8000 A mission's gap list counts only as `mission evaluate` computed it (M9.27) by adeelahmad · Pull Request #101 · adeelahmad/aloop · GitHub
[go: up one dir, main page]

Skip to content

A mission's gap list counts only as mission evaluate computed it (M9.27) - #101

Merged
adeelahmad merged 3 commits into
masterfrom
claude/m9-loop-skill-zkmelo
Oct 20, 2026
Merged

adeelahmad merged 3 commits into
masterfrom
claude/m9-loop-skill-zkmelo

Conversation

@adeelahmad
Copy link
Copy Markdown
Owner

Requested by Adeel · project thread

Before: aloop mission tick read every eval file in docs/agents/mission/eval/. A file nobody computed, or one edited after it was written, could say goal_met: true, and the loop would then hand out RESEARCH ("raise the bar") instead of DERIVE_GOAL. The goal commands trusted an eval only through a run-log event, which a fresh clone does not have, so on a clone tick handed out DERIVE_GOAL while goal derive refused. The readers also picked "the latest eval" by three different clocks.

After: mission evaluate records eval.completed in the committed, hash-chained ledger. mission tick, evaluate check and goal all take the newest intact eval from one function, evaluate.evaluated, in the ledger's order. Intact means three things: the ledger record covers this exact content, the schema is valid, and the seal matches. An eval that was forged, edited or re-stamped (its status or sha256 field changed) says nothing to any reader. A machine whose clock is behind cannot reorder evals. A fresh checkout derives and closes goals from the evals it committed. An eval or state cited as journey or baseline evidence also needs its record.

How:

  • Ledger: eval.completed joins LEDGER_EVENTS.
  • evaluate.py: evaluate writes the record with M.record. intact() checks the record, the schema and the seal, and problems() adds the existing recomputation. evaluated() and latest() list and order evals by ledger position.
  • goal.py: eval_record reads the ledger record. latest_eval is EV.latest. goal close orders "derived before evaluated" by ledger position, where it used to use the run log.
  • tick.py: the eval list is EV.evaluated. The goal_met fallback to the run log is gone.
  • journeys.py: evidence that names an evl_/sta_ needs its eval.completed/state.assessed record.

Calls I made:

  • The recomputation stays in evaluate check/goal, not in tick, for now. The tick test's synthetic sections use evals that cannot recompute, so tick reads only the record, schema and seal. That remaining gap is a new ROADMAP item, M9.52.
  • Tick checking a goal's own problems (goal check) is a new item, M9.53. It came up in the review.
  • No migration. The mission layer is unreleased, so an eval written before this change has no record and is simply evaluated again.

Evidence

  • scripts/test/mission-tick.test.py section 31 (check 32): each part below failed on the code before it was fixed.
    • A sealed, well-formed eval nobody computed gives EVALUATE ("no eval yet"), not RESEARCH, and evaluate check exits 2 on it.
    • Editing the newer of two evals, or only its status or sha256 field, makes tick, evaluate check and goal options all fall back to the older one.
    • A second machine with its clock behind records a newer eval whose id and created_at sort earlier. Tick and evaluate check still pick it.
    • After rm -rf .aladdin, tick says DERIVE_GOAL, and goal derive succeeds.
    • Then intents, a passing assess and an eval narrowed to the goal, then another rm -rf .aladdin. Tick says close, and goal close succeeds.
  • scripts/test/mission-evaluate.test.py: the eval.completed row is in the ledger with role evaluator.
  • scripts/test/mission-journeys.test.py: retiring a journey on a fake evl_ as evidence is refused. Before the fix, the old code retired it.
  • An adversarial review of the first commit found 4 real gaps, and the second commit fixes them. They were: goal took an edited newest eval that tick skipped; a re-stamp was trusted; the three readers ordered evals differently; and fake evidence was accepted.
  • Locally all 17 mission suites pass (tick 32, goal 13, evaluate 8, e2e 8, journeys 11, …), and so do make pycheck, scripts/check-tracking.py (86 requirements) and make test-hosts on the first commit.

Generated by Claude Code

…9.27)

`mission evaluate` now records eval.completed in the committed ledger.
`evaluate check`, `goal derive`/`close` and `mission tick` count an eval
only with that record of its content, so a hand-written or edited eval
no longer reads as "goal met", and a fresh checkout derives and closes
goals from the evals it committed (goal close orders by the ledger).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Aw6CiQcdpzdzZZXKf8WbUM
…7 review)

Review findings, each a test that failed before this:
- goal derive/options took the newest recorded eval even when its file
  was edited, while tick and evaluate check skipped it; now all three read
  evaluate.evaluated (record of the content, schema, a seal that matches).
- a re-stamped eval (status or sha256 field, outside the digest) was
  still trusted by tick; the seal must now match the content.
- tick ordered evals by the id's clock, goal by the ledger and evaluate
  check by created_at; all now use the ledger's order.
- journey and baseline evidence accepted an eval or state nobody computed.
The recomputation half and tick checking a goal's own problems are new
ROADMAP items M9.52 and M9.53.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Aw6CiQcdpzdzZZXKf8WbUM
# Conflicts:
#	docs/TRACKING.md
#	plugin/bin/_mission.py
@adeelahmad
adeelahmad marked this pull request as ready for review October 20, 2026 11:06
@adeelahmad
adeelahmad merged commit 6140f19 into master Oct 20, 2026
5 checks passed
adeelahmad pushed a commit that referenced this pull request Oct 20, 2026
adeelahmad pushed a commit that referenced this pull request Oct 20, 2026
adeelahmad pushed a commit that referenced this pull request Oct 20, 2026
…er and rule fixes

The merge follows the #86 thread's recipe for _shellread.py (Word.body ours,
Cmd keeps end plus loop/pipe, their heredoc registration, `for NAME do`),
and doors.py skips the reader's compound markers and keeps a pipeline
element's cd in the element.

Round 4 (the verifiers of round 3): the scope gate walks every state a
command may leave the shell in. A cd inside an if/case/loop body, group or
function, or after && / ||, may or may not have run, so the rest is judged
from each dir (a compound's own `} > f` from where it started); a loop body
once per item; unquoted $VAR splits; eval and source /dev/stdin run in the
calling shell; a background job's cd stays in it; nesting past 8 levels,
more than 1024 walks or 50 000 judged commands blocks. find's -name tests
bound a removal through -o alternatives and negations; -fprint/-fls write;
wget --spider -O, npm -g --prefix, --global=false, os.environ.__setitem__/
update, xargs -i/-I{}, runuser options and `command -p export` are read.
Residuals are ROADMAP M9.54. mission-scope-bash.test.py: 718 commands.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0197nSutKR1QAAqgJhFZ8fPj
adeelahmad pushed a commit that referenced this pull request Oct 20, 2026
…ch; docs for M9.31

Conflicts: the OpenCode plugin's header comment (gate-dispatch on task from
master, the door gate last from this branch) and codex-hooks.test.py (both
blocks kept). ROADMAP: M9.31 done, new items M9.48, M9.49, M9.54-M9.59, and
the M9 row of section 0 brought up to date; TRACKING, CHANGELOG, OVERVIEW.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012rsDo9GYzNx8tXucywZHnA
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

0