feat(org): adopt — put work already in flight onto a lane's plate - #277
feat(org): adopt — put work already in flight onto a lane's plate#277itsHabib wants to merge 2 commits into
Conversation
A session that never attached still produced a branch, a PR and a head SHA. Every one of those is observable from outside the session, and none of them could become ownership: registering the work needed the session's cooperation, which is exactly what is missing when a session never attached. Measured on 2026-08-31 in one live tenant: 31 open operator-authored PRs and 66 session directories against three chartered lanes, all of it unlinked, while every instrument the substrate owns reported ok. `org adopt` writes four records on an UNHELD lane: attach -> note -> assign -> release. No claim. The note is why this is a verb and not a documented recipe. `assign` takes no body and `attach` rejects one, so an adopter's identity has nowhere to live except a record of its own — and in a recipe that record is the optional step, which means it is the step missing from the tick where it mattered. An unattributed assign is indistinguishable from the lane's own coverage sweep, and that indistinguishability is the entire cost of adopting at all. `-by` is therefore required. Two properties come from the kernel rather than from this verb, and both are what make adoption safe to put in a watcher's hands: - It cannot displace. `attach` on a held lane is refused `already_held`, whose message already says "displacing a holder is a takeover". So granting adopt authority cannot leak into takeover authority — the kernel draws that line for free, and `checkTakeover` still gates the other side of it on `Terms.Supervisors`. - It never claims. Adoption writes Held, never Active. A lane holds many items and acts on exactly one (`claim_active`), so putting work on a plate and starting it are different acts, and adoption is only ever the first. That is what makes `held 31 · active 0` a truthful state rather than a broken one. Refuses `work_already_held` when another lane in the tenant already holds the work, rather than manufacturing the `assign_conflict` sweep reports: which of two lanes should own something is a routing question no mechanical verb gets to answer. An unreadable peer chain refuses too — it is not evidence of absence. Warns on scope drift and proceeds, matching `transfer`. Both refusals name frozen reasons, so the exit-code seam holds: 1 for the substrate declining, not 4 for the command failing. It manufactures no authority. `attach` carries no authorization check, so any process able to read the state directory could already write these four appends by hand; the composite adds only that the trace is not optional and the pin is not hand-assembled. WHO may invoke it is a charter question for the invoking role — for `/task-supervisor` specifically it is an open operator decision, recorded in cc-skills `docs/supervisor-as-manager.md` §4. The handoff is the assertion worth reading in the tests: adopted work is picked up with `org begin -work <uri>` and no pin, because the pin is already on the chain. Adoption is only worth anything if a successor can resume the work without knowing an adoption happened. Not exposed on org-mcp, matching begin/done/intake/transfer — that surface lags the CLI deliberately. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Claude finished @itsHabib's task in 3m 34s —— View job Review: feat(org): adopt —
|
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 327045af7b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
The otherHolder scan runs before the role lock is taken and appends lock one chain at a time, so two adoptions into two idle lanes can both pass and sweep reports the assign_conflict. Say so in the guide pair and the code, pointing at the FOLLOWUPS cross-chain-transaction entry, instead of implying the preflight is an admission law. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Summary
A session that never attached still produced a branch, a PR and a head SHA. All of that is observable from outside the session — and none of it could become ownership, because registering work needed the session's cooperation, which is exactly what is missing when a session never attached.
Measured in one live tenant on 2026-08-31: 31 open operator-authored PRs and 66 session directories against three chartered lanes, all unlinked, while
org sweepreported100% distilled session endsandliveness ok. The metric was not wrong — its denominator is the sessions that attached, which are the ones that were always going to be fine.org adoptwrites four records on an unheld lane:attach → note → assign → release. No claim.Why a verb and not a documented recipe
assigntakes no-bodyandattachrejects one, so an adopter's identity has nowhere to live except a record of its own. In a three-command recipe that record is the optional step — which means it is the step missing from the tick where it mattered. An unattributed assign is indistinguishable from the lane's own coverage sweep, and that indistinguishability is the entire cost of adopting at all. So-byis required, and the note is not skippable.Two properties that come from the kernel, not from this verb
Both are what make adoption safe to put in a watcher's hands:
attachon a held lane is refusedalready_held, whose message already says "displacing a holder is a takeover". Granting adopt authority therefore cannot leak into takeover authority — the kernel draws that line for free, andcheckTakeoverstill gates the other side onTerms.Supervisors.Held, neverActive. A lane holds many items and acts on exactly one (claim_active), so putting work on a plate and starting it are different acts. That is what makesheld 31 · active 0a truthful state rather than a broken one.Refusals
already_held, exit 1, naming the live holderwork_already_held, exit 1 — refuses rather than manufacturing theassign_conflictsweepreports. Which of two lanes should own something is a routing question no mechanical verb gets to answer.transfer)transferBoth refusals name frozen reasons, so the documented exit-code seam holds: 1 for the substrate declining, not 4 for the command failing.
It manufactures no authority
attachcarries no authorization check, so any process that can read the state directory could already write these four appends by hand — verified. The composite adds only that the trace is not optional and the pin is not hand-assembled. Who may invoke it is a charter question for the invoking role; for/task-supervisorspecifically it is an open operator decision, argued both ways in cc-skillsdocs/supervisor-as-manager.md§4.Validation
gofmt -lclean,go vetclean. Four new tests; the one worth reading is the handoff assertion — adopted work is picked up withorg begin -work <uri>and no pin, because the pin is already on the chain. Adoption is only worth anything if a successor can resume without knowing an adoption happened.End-to-end against a throwaway state root, three adoptions onto a released lane:
Not included
Not exposed on
org-mcp, matchingbegin/done/intake/transfer— that surface lags the CLI deliberately.