Kuickr

03 · Anchors — subjects that are not rows

Some things you want a procedure for are not ActiveRecord records: a node in a JSON tree, a file path, a DNS zone, a cron schedule.

An anchor gives such a subject a stable relational identity, so a runbook can attach to it like anything else.

Jazari::AnchorTarget.new(
  scope_type: "Tree", scope_id: workspace.id, key: "node-x",
  public_reference: { kind: "node" }, recipe_id: "node.v1"
)

scope_type + scope_id say which container; key says which thing inside it.

Register the scope

Unregistered scopes fail closed:

Jazari.configure { |c| c.anchor_scopes = { "Tree" => nil } }

nil means "use the gem's own anchors table" — fine when the subject has no existence of its own.

Supplying your own resolver

Supply a lambda when the anchor lives somewhere jazari cannot see, or your table has columns the gem knows nothing about:

c.anchor_scopes = {
  "Tree" => lambda do |target, create|
    workspace = Workspace.find_by(id: target.scope_id)
    raise Jazari::TargetNotFound, "unknown workspace" unless workspace
    raise Jazari::TargetNotFound, "unknown node" unless node_in?(workspace, target.key)

    if create
      MyAnchor.create_or_find_by!(workspace: workspace, node_id: target.key)
    else
      MyAnchor.find_by(workspace: workspace, node_id: target.key)
    end
  end
}

The contract, and why each part exists

create tells you whether you may materialise. It is false on every read. A resolver that always creates will materialise an anchor on resolve — which breaks the rule that reading a default writes nothing, and quietly fills your table with rows for subjects nobody ever customised.

Return a persisted record, or nil, or raise. Anything else fails closed. A nil on a write raises target_not_found rather than proceeding.

Distinguish "invalid" from "absent" — they are not the same.

Situation Do
the container or key is invalid raise Jazari::TargetNotFound
valid, but no anchor yet return nil

Collapsing these is the subtlest mistake available here. If an unknown node returns nil, it resolves to a default and looks like a perfectly ordinary uncustomised subject — so a typo'd id silently succeeds instead of failing.

Validate against the authority, not a projection. If you keep a search index or cache of your tree, do not consult it here. A rebuildable projection must not decide whether durable user intent may exist.

Lifecycle

An anchor is created only when a customisation is materialised, and destroyed with it on reset — including anchors of your own class. Nothing here assumes the gem owns the anchor model.

K 03 · Anchors — subjects that are not rows
3 / 7