Chain: once you have PROVEN the lease (
forge issue owns <id>exits 0), continue todevto work the issue (smithproceeds into plan/dev after this proof). Usable standalone whenever ownership is in question.
Claiming is not owning. The Forge kernel keys a claim's idempotency on
claim.create:<issue_id>:<actor>, so a same-key duplicate replay returns
ok:true echoing the current call's claim_id. A genuine cross-actor
conflict returns ok:false (the partial-UNIQUE active-lease index guarantees one
lease) — but ok:true alone does not prove sole ownership. A live lease can
also be reclaimed on expiry (an expired lease is superseded by the next
claimant). Therefore every worker MUST verify ownership before mutating a claimed
issue, and RE-verify before close/release.
This is a reusable, standalone procedure: any skill or agent that mutates a claimed issue embeds it (it is NOT folded into one orchestrator).
The verification primitive
forge issue owns <id> # exit 0 iff YOU hold the live lease; non-zero otherwise
forge issue owns <id> --json # { ok:true, data:{ owned, claimed_by, expired, actor, expires_at } }
owns resolves your actor the same way the kernel does — FORGE_ACTOR →
FORGE_SESSION_ID → default forge — then reports owned:true iff you hold the
single active claim AND that lease has not expired. It exits 0 when you
own it and non-zero (conflict, code 4) when you do not, with a clear "you do not
own the lease for <id> (held by <actor>)" message. It is a strict READ — it
never mutates kernel state. (data.claimed_by is lease-derived; there is no
claims command.)
Procedure
- Select work —
forge issue ready --json(see thetriage-readyskill). Never claim epics/decisions or defer-windowed items. - Claim —
FORGE_ACTOR=<your-actor> forge claim <id>. Always run under a distinct actor so a losing claim reaches the conflict guard instead of collapsing to a shared-actor duplicate. - Prove ownership BEFORE working —
forge issue owns <id>.- exit 0 (OWNED) → the lease is yours; proceed to work.
- non-zero (NOT OWNED) → you lost the race, or your claim collapsed to a
foreign/duplicate-collapsed claim. Do NOT work the issue. Reselect via
forge issue ready --jsonand start over at step 1.
- Work the issue (
dev/edit/etc.). - RE-verify before
close/release— a live lease can be reclaimed on expiry while you worked. Runforge issue owns <id>again:- OWNED →
forge release check --target <release-ref> --json(release-readiness; omit--targetto use the project default), thenforge close <id> --reason "…"orforge release <id>. - NOT OWNED → the lease was reclaimed (likely expired). Do NOT close/ release someone else's lease; reselect and, if the work is still needed, re-claim and reconcile.
- OWNED →
Contract (what each result means)
forge claim result |
Meaning | Action |
|---|---|---|
ok:false (conflict, code 4) |
A live lease is held by another actor | Reselect (ready) |
ok:true |
Provisionally yours — not proof (duplicate replays also return ok:true) | Run forge issue owns <id> |
forge issue owns |
Meaning | Action |
|---|---|---|
exit 0, owned:true |
You hold the live, unexpired lease | Work / close / release |
non-zero, owned:false |
Someone else holds it, or your lease expired | Reselect; never mutate |
Fork points
- Actor source — how
<your-actor>is derived (FORGE_ACTORexplicit id →FORGE_SESSION_ID→ defaultforge). Use a distinct per-agent actor so contending claims reach the conflict guard rather than collapsing to a duplicate. - Expiry / lease TTL — whether claims carry an
expires_atand how long;ownstreats an expired lease as NOT owned (it can be reclaimed). - Re-verify cadence — verify after claim and again before
close/release; a longer task may re-verify more often (e.g. before each irreversible step). - Reselection policy — on NOT-OWNED, how the next item is chosen (ranking /
filters live in the
triage-readyskill). - Fail-closed posture — with no usable clock/state, treat ownership as NOT proven (mirror the readiness model's "no usable clock ⇒ not workable").
Reliability notes
- A genuine cross-actor conflict returns
ok:false— there is no phantomok:true-on-conflict. The real hazards are (a) a duplicate replay'sok:trueand (b) expiry-driven reclaim.ownscloses both. - Full multi-agent safety depends on the actor-identity kernel fix (distinct
actors per agent, kernel
d71a824b): without distinct actors, two agents share one idempotency key andownscannot tell them apart.