Repository navigation
Mission artifact gate: second, third and fourth review fixes (M9.9, M9.42) - #114
Merged
Merged
Conversation
…ership The artifact gate (gate-mission-artifact, _mission_roles.py, roles.json) after the second adversarial review, each finding a test in mission-roles.test.py: - A human's confirm, restore or veto-window apply during a role's run, and what its command changed (journeys frozen, a version superseded), is never the role's write and never blocks it; a status no record explains still blocks (effects() reads the records, with the status they set). - An overlapping run excuses a path only when it answers for it as it is now: an open run that will see the change at its stop, or a passed run whose `judged` holds those bytes; a released run owns nothing. A run is open while it is active (its newest tool call, from budget's per-agent state). - The ledger is append-only during a run: the start record keeps its byte length and sha256, and the stop requires that prefix. - Intents: no role rewrites an intent of the human's or intake's that existed at its start (intake's own `intent check` of it excuses its fill); a `source: mission` intent is the Mission Planner's. - Records (roles.json `records`): a judge run log and a usage report are the writing role's work, checked by their own contract and their area. - M9.42: the Product Tester writes research/, and a report belongs to the role its `role` field names. - A draft no harness id names may be removed; telemetry instrumentation is a `foreign` note; an area check blocking only on ledger problems that predate the run is a note; a timed-out check has a constant reason; a malformed intent field is an ordinary block. - OpenCode: a mission child continued for a new task starts a new run. - Personas name `baseline new --supersedes` (no `baseline propose`). ROADMAP: M9.42 done, M9.9 calls and counts, M9.41 note, M9.43 for the parts that need other tracks' files. CHANGELOG line under M9.9. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0197nSutKR1QAAqgJhFZ8fPj
…tifact-gate fixes Conflicts: CHANGELOG (master's lines, this track's M9.9 sub-bullet kept), ROADMAP (master's rows; this track's M9.41/M9.42; its follow-up row moves from M9.43, which master took, to M9.48). The track's new checks now get the human's typed line for an approval (grant(), and the OpenCode test types it through the UserPromptSubmit hook), and the ledger row that came through git cites the human's words, as M9.17 requires. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0197nSutKR1QAAqgJhFZ8fPj
…eir event - Intents: a human event, or intake's own intent.received/intent.normalized, of the run that names an intent makes its change, a new intent or its deletion theirs; a harness-named intent no event names (posed or deleted) blocks, and the source the run found decides whose an intent is. - Ledger: the supervisor's restore (HEAD's committed copy, or the rows before the first bad line of a ledger the run started broken) is a note, not a rewrite; a run that wrote nothing on a ledger broken before it started gets a note instead of "no artifact". - Liveness: an open run's last tool call is read from the transcript store (written by PostToolUse on every host, refused to roles), not from a budget file a role can touch; the backward read keeps a capped partial line, so it stays linear (a 200 MiB line: 30.7 s before, 0.95 s after). - Records: a judge run log or usage report counts only with its command's event of the run (judge.run, telemetry.report). - Snapshots belong to the roles whose reports cite them; deleting an artifact another run's pass accepted during this run blocks. - The Product Tester's eval suite names `baseline new --supersedes`; persona and eval verbs are checked against `mission <area> --help`. - mission-roles.test.py: 47 -> 57 checks; docs, ROADMAP M9.9/M9.41/M9.42/M9.48, TRACKING and CHANGELOG updated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0197nSutKR1QAAqgJhFZ8fPj
…-4 scope gate Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0197nSutKR1QAAqgJhFZ8fPj
…ir, merges) Each finding is now a check in scripts/test/mission-roles.test.py that failed before the fix, with its allow-control (58 -> 64 checks). Regressions of the third round, fixed: - Ledger restore: the start record now keeps each ledger row's bytes by event_id. A restore counts as the supervisor's repair only when it is HEAD's committed copy, or the good rows of a ledger the run started broken, followed only by rows the run started with (byte for byte) and rows a command of the run appended (its ledger event). A row edited in place, with its event_id kept and the chain hashed again, blocks again (after HEAD and after the bad line). - Wrote nothing on a ledger broken before the run: this is a note only for a role whose own commands decide from the ledger (roles.json `ledger_bound`: baseline new, assess, baseline measure, goal derive, ethics record). The test checks that each listed command refuses. The Scout and the Evaluator are blocked with "you wrote no artifact", as on the base. - docs/agents/intents/: every file there counts, not only *.json, so a rewrite of the human's raw-*.txt words blocks. - explained(): an event names an intent only through refs.intent or data.intent_id, never through refs.raw, which `intent new --raw-ref` lets the caller choose. Over-block fixed: an intent that a commit made during the run brought in or removed is the supervisor's (a `git merge` or `git pull`; mission roles cannot write git). The start record keeps HEAD, and the file must be HEAD's blob. The role is still blocked when it changes or deletes the file itself. Narrow items closed: a new file in intents/ whose name is not an intent id is no longer exempt (`aladdin run` picks the last *.json there). No role can flip a `source: mission` intent to another source to pose as the human, whether the intent existed before the run or intake's intent.received of the run recorded it as mission. Two existing intents checks (mp1, ev12) wrote the human's files with no event naming them. They now first assert the new block, then pass once the human's record 8000 is emitted. Deferred to ROADMAP M9.41 and M9.48, each with a reason: deleting an artifact that another open run created, the python channel into the transcript store (and a commit made from inside a program), merges into docs/agents/mission/, the 8 MiB liveness line cap, and the ledger-recovery advice over-block. M9.48 records the ALOOP_JUDGE_CMD part as done. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0197nSutKR1QAAqgJhFZ8fPj
…aluator ledger, intake source) Each finding is a check in scripts/test/mission-roles.test.py that failed before its fix, with its allow-control (64 -> 67 checks). Each fix was also reverted alone in a copy of the tree, and the test then fails at its check. Fixed: - A commit of the working tree during a role's run no longer hides the role's writes to docs/agents/intents/. Before, the human's `git commit -am` (or the supervisor's commit) made the Mission Planner's rewrite of the human's intent, and its own invalid `source: mission` intent, look like files a merge brought in. A file now counts as arrived only when a `git merge` or `git pull` brought it in. The start record keeps the size of HEAD's reflog. The reflog entries since then must chain from the start commit to HEAD, and the last entry that changed the file must be a merge or a pull. For a merge made here, the file must be the other side's blob, never a result merged with a local change. No commit made here during the run may have made the file as it is now, so a commit on a branch that is then merged is still a local commit. - Evaluator on a ledger broken before its run: `evaluate` and `goal close` decide from the ledger and refuse, so roles.json lists them as the Evaluator's `ledger_bound` commands. A run of it that wrote nothing is a note again, not a block every round until the stuck release. `mission evaluate` now refuses on a broken ledger before it writes a gap list. Before, it left a sealed gap list that no eval.completed record backs. The test now also shows that the Scout's commands (`research new|archive|claim`, `journeys new`) do not refuse on that ledger. - Intake's fill may change an intent's source to another of the human's kinds (`prompt` to `mixed` after a screenshot, with an `ask` question still open). Its intent.received of the run still names the intent. Before, the role was told to delete the human's request. A change to or from `source: mission` still blocks. Deferred, each to ROADMAP M9.41 or M9.48 with its reason: - A pull of another clone's mission artifacts, or of the human's `baseline confirm` made there. - The human's `rm` of an older request during a run, which leaves no event. - A squash merge, a conflicted merge concluded by `git commit`, or a plain `git rebase` during a run, which HEAD's reflog cannot tell from a local commit. - Still open from before: the 8 MiB liveness line cap, the ledger-recovery advice, eventless edits of an older intent (OB1/OB2), and the python channel. M9.41 now says that a branch made and merged from inside a program still passes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0197nSutKR1QAAqgJhFZ8fPj
…ledger note, the human's words) The Scout's `journeys retire` refuses on a broken ledger, so roles.json gives market-researcher `ledger_bound` and a Scout run that wrote nothing there is a note again. The words `aladdin` keeps beside an intent are judged only in the Mission Planner's run, the one role the scope gate lets write the dir, so the human editing or removing them while another role runs no longer blocks it. ROADMAP M9.41 records the over-blocks that are the same on master. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0197nSutKR1QAAqgJhFZ8fPj
… into the artifact gate fixes Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0197nSutKR1QAAqgJhFZ8fPj
…complete ledger_bound, no self-made excuse) - The words `aladdin` keeps beside an intent count in every role's run again: a program's write (`python3 -c`) is invisible to the scope gate, so af437a1's planner-only rule let an evaluator rewrite the human's request that `aladdin run` reads back. The test now writes them through a program. - l 8000 edger_bound is checked complete: every command a role's persona, eval suite or handout (the mission skill) names that refuses on a broken ledger is listed. It adds the planner's `goal retire` (M9.50), the Product Tester's `baseline measure`, and both measuring roles' `baseline apply`. - The wrote-nothing ledger note needs every ledger problem to be one the run started with: a ledger event a role appends to the run log with no row is no excuse. - macOS: the ledger path in the restore check is taken through realpath (/var is /private/var), which failed the macOS job. - Docs: the stale Scout claims in ROADMAP M9.9 and CHANGELOG, the gate docstring's ledger_bound list, M9.41's note on the human's own edits. mission-roles.test.py: 68 -> 69 checks. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0197nSutKR1QAAqgJhFZ8fPj
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0197nSutKR1QAAqgJhFZ8fPj
adeelahmad
marked this pull request as ready for review
October 20, 2026 18:26
adeelahmad
pushed a commit
that referenced
this pull request
Oct 20, 2026
…oop stop) into the M9.31 branch Conflicts: both sides' plugin constants and helpers kept (the door gate's timeout and read-only set beside master's NEEDS-HUMAN release), the dsh test's question helper renamed (master added a child named `ask`). This branch's open items move to M9.56–M9.65: master took M9.55 and #114 claims M9.48. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012rsDo9GYzNx8tXucywZHnA
adeelahmad
pushed a commit
that referenced
this pull request
Oct 20, 2026
…sh-clone stop) into the M9.31 branch ROADMAP: the M9 row keeps this branch's done/open lists and adds M9.42 (done in #114) and M9.48 (open); the M10 row takes master's fresh-clone stop and says the OpenCode plugin exports ALOOP_AGENT_SHELL since M9.31. aloop.js: the SubagentStart comment names both the core principles and the artifact gate's per-task start. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012rsDo9GYzNx8tXucywZHnA
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.
Requested by Adeel · project thread
Before: three adversarial reviews of the mission artifact gate (
gate-mission-artifact, M9.9) confirmed findings it judged wrong. Some let a role's bad write through:git commit -ammade during its run;zz-request.jsonindocs/agents/intents/(whichaladdin runpicks up) exempt because no intent id names it;source: missionintent flipped topromptto pose as the human.Others blocked a role for something it did not do:
git mergeorgit pullbringing in an intent;prompttomixed;research/, blocked as the Scout's (M9.42).After: every confirmed finding is a check in
mission-roles.test.pythat failed before its fix, with its allow-control. That makes 69 checks; master has 34.How:
_mission_roles.py,roles.json):rolefield names a role is that role's.judge.run,telemetry.report).ledger_bound). The test checks that each listed command refuses, and that the list holds every refusing command the role's persona, eval suite or handout names. The list includes the Scout'sjourneys retireand the planner'sgoal retirefrom M9.50.mission evaluatenow refuses before it writes a gap list.docs/agents/intents/:source: missionintent is the Mission Planner's, and no role flips it to another source.refs.intentorintent_id(never--raw-ref).git mergeorgit pullbrought it in.raw-*.txt) count in every role's run. A program's write (python3 -c) is invisible to the scope gate, andaladdin runreads the words back as the request.baseline new --supersedes, and the test checks each persona and eval verb againstmission <area> --help.Not in this PR (ROADMAP M9.41 and M9.48, each with its reason):
rmof an older intent, or their own edit of its words;git reset --hardto the upstream;git gcthat drops the run's reflog start;Evidence:
mission-roles.test.py: 69 checks (34 on master).journeys retireon a broken ledger is fixed and tested here. The human editing their own words during another role's run still blocks, because the gate cannot tell that edit from a role's write made by a program (M9.41).goal retiremissing from the list, and three stale doc lines. It refuted two./varis/private/var). The test passes with a symlinkedTMPDIR.make cipasses locally on 7adf6a4 (conformance 82/82).🤖 Generated with Claude Code
https://claude.ai/code/session_0197nSutKR1QAAqgJhFZ8fPj