Repository navigation
The mission loop hands out a goal's commands only when the gate takes them (M9.53) - #111
Draft
adeelahmad wants to merge 8 commits into
Draft
adeelahmad wants to merge 8 commits into
adeelahmad wants to merge 8 commits into
Conversation
Before PLAN_INTENTS and SPRINT, `mission tick` runs `goal check`, the check `goal intents` and
`goal next` run; before a met goal's close it runs `goal.close_problems`, now the rule `goal close`
runs. A refusal is BLOCKED naming the gate's reason (keyed on it), where the loop used to hand out
the same command 3 times and then block with no cause named.
`goal close` records goal.met before it sets the status, and repairs a bare `met` status.
The tick test's goals are now real: `Project.goal` runs `assess`, `evaluate` and `goal derive`
in-process on the project's clock (`Project.at_clock`), so every section's goal passes `goal check`.
New check 34: a raised budget voids a goal (BLOCKED, as `goal intents`/`next` refuse), a stray
status blocks the close with `goal close`'s reason, and a bare met status closes. It fails on
master's code ("expected BLOCKED, got PLAN_INTENTS" and "got EVALUATE").
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Aw6CiQcdpzdzZZXKf8WbUM
… first - goal.next_intent is `goal next`'s whole rule (check, a goal.met record, the status, the next intent's `intent check`); tick's SPRINT asks it, so a goal next refuses is BLOCKED with its reason, not SPRINT 3 times. - `goal next` refuses a goal with a goal.met record. - `goal close` checks the goal's content before it trusts a goal.met record, then repairs a bare status. - The close BLOCKED is keyed on its problems, so a new reason is told. - Tick check 13 sprints real intents; docs say which goals are real. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Aw6CiQcdpzdzZZXKf8WbUM
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Aw6CiQcdpzdzZZXKf8WbUM
…fusal - intent: `verdict` is `intent check` without its event; `cmd_check` adds intent.normalized. goal.next_intent asks it in process, so `tick --peek` and `due` no longer emit the intake event `ids freeze` links plans to. - A crash of the check (a contract of the wrong shape) is its refusal, never "every intent has a plan". - `goal next` with nothing to hand out names why (no intent recorded, or every intent planned), and tick says BLOCKED with it, not SPRINT x3. - `goal close` checks the ledger before the goal's content. - Tests: section 13 sprints real intents from the start; section 33 adds the no-intent, no-emit and crash cases; goal check 8 covers a met goal with an unplanned intent and a ledger that lost goal.derived. - ROADMAP M9.70: `ids freeze` should link the handed-off intent. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Aw6CiQcdpzdzZZXKf8WbUM
An active goal with no recorded intent now gets BLOCKED (`goal next` has nothing to hand out), so the lifecycle, spoon-fed, cadence and same-second sections run `goal intents` and sprint each intent, as the planner does. Co-Authored-By: Claude Opus 5.5 <noreply@a 8000 nthropic.com> Claude-Session: https://claude.ai/code/session_01Aw6CiQcdpzdzZZXKf8WbUM
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Aw6CiQcdpzdzZZXKf8WbUM
adeelahmad
pushed a commit
that referenced
this pull request
Oct 20, 2026
…t once, ids M9.80-87 An adversarial review of the live-run fixes confirmed 9 findings: - seed_test_kept accepted an added def that rebinds the seed's test name (replacing it), an import or class shadowing TodoList, and code run at import through a decorator, default, annotation, base or class body. Added statements must now rebind none of the seed's names and run no code at import (pytest's own decorators with plain arguments). - No test pinned check_product's wiring: it now has one on the stub run's repo (an append passes, a redefinition fails). - journeys new returned on a runner problem before the other problems and the "nothing written" footer; it now names every problem at once. Its usage offers --from as the one form. - ROADMAP ids M9.63-70 clash with #105 and #111: now M9.80-87. - Docs: 39 checks, the M9.87 block count, run 1's three stop causes, and a test that pins the rival constraint's new wording. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018RxETAY6S1gcmdctBK8a8Z
…ntent Round 3 of the M9.53 review: with real intents in sections 13 and 18, nothing tested goal_sprints' no-intent branch (a SPRINT an older tick handed out). A legacy case now does: an older sprint is not the goal's, one planned in the second of the handout is. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Aw6CiQcdpzdzZZXKf8WbUM
This branch has not been deployed
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:
mission tickhanded outPLAN_INTENTS,SPRINTor a met goal's close without asking whether the command would accept the goal. A goal the mission had outgrown (for example after a raised budget cap) gotPLAN_INTENTSwhilegoal intentsrefused it. After 3 handouts the repeat guard saidBLOCKEDwith no cause named. A broken next intent, or a stray status on a met goal, looped the same way ongoal nextandgoal close.After: tick asks the gate first. If the gate refuses, tick says
BLOCKEDwith the gate's own reason, for example "the mission changed since the goal was derived" or "the human answers it", so the human sees why at once. The check records nothing, sotick --peekandduestill write no events.goal closenow checks the ledger and the goal's content before it trusts agoal.metrecord, writes that record before the status, and repairs a baremetstatus left by a crash.How:
next_intentis all ofgoal next's rule:goal check, agoal.metrecord, the status, a next intent at all, and that intent'sintent check.cmd_nextprints from it, so the command and the loop share one rule.intent.verdict(intent checkwithout itsintent.normalized). Onlygoal nextitself, when it hands an intent out, runsintent checkand emits the event. A check that crashes on a contract of the wrong shape is a refusal that names it.goal nextsays why: no intent of the goal is recorded, or every intent has a plan.goal nextrefuses a goal that has agoal.metrecord.close_problemsiscmd_close's rule, extracted so the loop and the command share it.cmd_closechecks the ledger, then the content, then a matchinggoal.metrecord (repairing a bare status), then recordsgoal.metand sets the status.verdictisintent check's rule without its event;cmd_checkadds the event.PLAN_INTENTS,goal_refusedrunsgoal.check, the checkgoal intentsruns. BeforeSPRINTit runsgoal.next_intent.goal.close_problems.BLOCKED, keyed on its problems, so a new problem is told again.goal nextexiting 1 (nothing to hand out) counts as a refusal.BLOCKEDrow in the docstring and in SKILL.md names this case.goal check.Project.at_clockrunsaloop missionin-process with the clock frozen at a chosen project hour.Project.goalruns realassess,evaluateandgoal deriveat the hours the sections used.BLOCKEDfor the edited pick. The gate refuses an edited goal, and the result still tells the two fold orders apart.goal intentsand sprint each one, since an active goal with no recorded intent is nowBLOCKED.Calls I made:
BLOCKED, notDERIVE_GOAL, for a goal the mission outgrew. A second goal in flight is M9.55's to rule out, and M9.43 decides which mission changes void a goal.BLOCKED, notPLAN_INTENTS, for an active goal with no recorded intent. That happens on a fresh checkout (the run log is gone) or after a hand-set status, and re-runninggoal intentsthere would duplicate intents whose files still exist. Sprint history as run data is M9.26.ids freezelinks a plan to the newestintent.normalizedanywhere, so a human's intake betweengoal nextand the freeze can link the wrong intent.Review rounds
Round 1 ran on 0da88a6. Its 6 confirmed findings are fixed in 4cabc54, each with a test:
SPRINTchecked onlygoal check, so a goalgoal nextrefused (an unanswered ask in the next intent, a gone intent file, a status no record says) gotSPRINTuntilBLOCKED.goal nexthanded out intents for a goal with agoal.metrecord.goal closetrusted agoal.metrecord before checking the goal's content.BLOCKEDwas keyed on the eval alone, so a second reason for the same eval was never told.goal nextand tick using different events, the M9.43 remedy for an outgrown goal, and an unused spoon-fed path inProject.goal.Round 2 ran on 4cabc54 (3 lenses, each finding re-verified). It confirmed 5 findings, all fixed in 368d912 with tests:
goal nextcheck ranintent check, which emitsintent.normalized. Sotick --peekandduewrote an intake event, andids freezecould link a human's sprint to the goal's intent.goal nextexiting 1 still gotSPRINT, then the causelessBLOCKED.intent checkexited 1, which read as "every intent has a plan".goal closeread a ledger that lostgoal.derivedas a goal never derived.Evidence
scripts/test/mission-tick.test.py(34 checks), check 34:goal intentsandgoal nextrefuse it, and tick saysBLOCKEDwith their reason for bothPLAN_INTENTSandSPRINT.retiredstatus, an unanswered ask in the next intent and a gone intent file each makegoal nextrefuse, and tick saysBLOCKEDwith that reason.retiredstatus on a met goal isBLOCKEDwithgoal close's reason, keyed on it.metstatus gets the close, andgoal closerecords it.BLOCKEDnaming that. A recorded tick, a--peekanddueatSPRINTemit nointent.normalized. A crashing check isBLOCKEDwith "the planner fixes it".scripts/test/mission-goal.test.py(14 checks), check 8:goal nextrefuses a goal with agoal.metrecord even with an unplanned intent left, a second close repairs the status, an edited goal's close is refused despite its record, and a ledger that lostgoal.derivedis named as the ledger's problem.tick.pyandgoal.py, check 34 fails twice: "expected BLOCKED, got PLAN_INTENTS", and in the close part "expected BLOCKED, got EVALUATE".goal nexthands out an intent for a met goal.goal.metcheck moved last) turns its test red.mission-tick34 checks,mission-goal14,mission-roles34,intent-contract15,make pycheck,scripts/check-tracking.py(98 requirements) andmake test-hosts(46 checks; the live dsh run skips without the binary) all pass locally.🤖 Generated with Claude Code
https://claude.ai/code/session_01Aw6CiQcdpzdzZZXKf8WbUM