factory: a clean verdict clears the needs:human it applied, and only that one - #64
Merged
Merged
Conversation
…that one Propagates toon-meta#353 + toon-meta#354 into this repo. The reviewer's BLOCKING verdict applies `needs:human` as a side effect (toon-meta#282) and nothing ever removed it. So a PR that went blocking -> fixed -> clean ended APPROVED *and* still carrying the label, and auto-merge.yml refuses on exactly that label. Once blocked, gated forever. It stranded connector#923 and connector#935, both cleared by hand. The clear is ownership-gated, not presence-gated. `needs:human` is a HUMAN control point (FACTORY.md), so clearing it unconditionally would let a machine overrule a person who applied it deliberately. It fires only when the most recent application of the label was by the approver identity itself — which needs the TIMELINE, not the label list, because the label list says only that the label is present, never who applied it. Fails closed everywhere. - .sandcastle/needs-human-evaluator.mjs: new, the pure ownership rule, copied verbatim from toon-meta. It sits beside its only caller because scripts/factory/ exists only in toon-meta, so the original import path resolved nowhere else (toon-meta#354). - .sandcastle/review-verdict.ts: additive only (+75 lines) — the import, the clearsNeedsHuman() I/O helper, and an else-if branch on the existing if (blocking). Nothing in this repo's copy was rewritten. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
ALLiDoizCode
force-pushed
the
factory/clear-machine-applied-needs-human
branch
from
August 12, 2026 21:02
617f6c4 to
119dcdd
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Propagation of toon-meta#353 and toon-meta#354 into this repo. No behaviour of this repo's own product changes — only the two
.sandcastle/files that carry the factory fix.The wedge
The reviewer's BLOCKING verdict applies
needs:humanas a side effect (toon-meta#282). Nothing ever removed it.So a PR that went blocking → fixed → clean ended up
APPROVEDand still carrying the label — andauto-merge.ymlrefuses on exactly that label (needs-human: PR carries needs:human). Once blocked, gated forever. Structurally the same defect as the dead-agent:implementwedge: a label applied by an automated step that no automated step ever clears.It stranded connector#923 and connector#935, both of which had to be cleared by hand. The clear could not fire there because connector still carries the old
review-verdict.ts— which is the whole reason this propagation exists.Why ownership-gated and not presence-gated
The naive fix — "a clean verdict clears the label" — trades this bug for a worse one.
needs:humanis a HUMAN control point (FACTORY.md), so clearing it unconditionally would let a machine overrule a person who applied it deliberately.So the clear fires only when the most recent application of the label was by the approver identity itself. A human's label is never touched, and a human who re-applies it after a clean verdict keeps it.
That distinction needs the timeline, not the label list: the label list says only that the label is present, never who applied it.
labeled/unlabeledevents carry the actor and arrive oldest-first, so the last event for the label is the live state.It fails closed everywhere — an unreadable timeline, an unknown applier, a missing approver identity or a malformed event all leave the label alone. A label that should have been cleared costs a manual edit; one cleared wrongly overrules a person.
What changed
.sandcastle/needs-human-evaluator.mjs— new file, the pure ownership rule, copied verbatim from toon-meta. It sits beside its only caller (that was the point of toon-meta#354):scripts/factory/exists only in toon-meta, so the original import path resolved nowhere else and the fix was correct but unshippable..sandcastle/review-verdict.ts— the import, aclearsNeedsHuman()helper that fetches the timeline, and anelse ifbranch on the existingif (blocking). Additive only: 75 inserted lines, nothing removed or reordered.This repo's
review-verdict.tswas byte-identical to toon-meta's pre-fix version, so the upstream patch applied cleanly and both files now match toon-metamainbyte for byte.Verification
Gate green. Import resolution confirmed with
npx tsx -e "import('./.sandcastle/review-verdict.ts')"→OK, which is the check that would have caught toon-meta#354's unresolvable path.🤖 Generated with Claude Code