Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .claude/skills/mission-control/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -960,6 +960,18 @@ the PREVIOUS iteration's stamp — if the last iteration's own record is missing
stale copy, not a charter awaiting your entry. One command, and it is the difference between
appending history and erasing it.

**SPELL THE TELL IN THE CHARTER'S OWN CASE, AND PAIR IT WITH A CONTROL** (added 2026-08-03
iteration 134). Stamps are written `ITERATION 133` — **UPPERCASE** — while the sentence above says
"the previous iteration's stamp", so the natural transcription is `grep -c "Iteration 133"`, and
that returns **0** on a perfectly healthy charter. Iteration 134 ran exactly that and read `0` for
a charter that was byte-identical to origin. This is rule 3a's trap wearing THIS gate's clothes,
and it is the worst place for it: a broken tell and a genuinely stale charter produce the
identical output, so the failure routes a healthy iteration down the stale-copy path — or, in the
other direction, teaches you to distrust a tell you will need for real. Run it as
`grep -c "ITERATION <N-1>"` **alongside two controls in the same breath**: a known-present one
(`ITERATION <N-2>`, must be ≥1) and a known-absent one (`ITERATION 999`, must be 0). A `0` on the
known-present control means your instrument is broken, not that the charter is stale.

**THE STATUS ROTATION IS THE MOST DANGEROUS EDIT THIS LOOP MAKES — SCRIPT IT WITH A LINE-COUNT
ASSERTION, NEVER A BARE `## `-HEADER SCAN** (added 2026-08-01 iteration 127; third failure of this
same step — iter-83 hand-corrected an already-drifted N>4, iter-123 found the block drifted to 4
Expand Down
32 changes: 32 additions & 0 deletions design_docs/v1-mission-log.md
Original file line number Diff line number Diff line change
Expand Up @@ -7320,3 +7320,35 @@ The Fable designer specified the option-(c) bound as two budgets (`recordedDrain
**Next** — **execute S1** (`sprint_M-RECORDED-STREAM-API-S1.json`, validator rc=0, 5 milestones / 3.75 d): executor `codex:gpt-5.6-sol` in a worktree that is **not** under `/tmp`, evaluator `sonnet` (distinct provider → generator≠judge holds). Then `m-mcp-exact-tool-surface` Lane B (Mark's pick #2, and a release ask for Ailang World when it lands), then the two quota offloads.

**Parked for human — ONE decision, and it is the planner's ruling, not a request to re-litigate Mark's.** Dropping the sentinel means the drain budget bounds post-failure **work** (O(1)/chunk, zero retention) but not post-failure **wall-clock**; the call returns when the provider's stream ends, on a path unreachable for any `StreamChunk` constructible today. Accept? If no, the only remaining mechanism is a cancellable provider context — the already-rejected option (b) — which becomes a blocking dependency and makes this multi-sprint. `#558` (durable driver self-re-exec), `#554`'s root cause, `#561` and `#563` remain open.

---

## 139 — 2026-08-03 — Iteration 134: **dev CI was RED and the cause was a test helper whose own doc comment was false.** `cmd/ailang` re-linked the same 93 MB binary ~16× inside a 300s budget; on the Windows runner that package went **`FAIL 300.527s` → `ok 83.177s`**. PR **#564** → `3c28cc322`.

**Picked** — **NOT the queue head.** Gate 1's per-workflow CI read found `CI: completed/failure @ 773894d87`, i.e. dev HEAD itself, and a RED dev outranks the queue. The displaced pick (`m-recorded-stream-api` S1, plan-ready from iteration 133) is untouched and stays next.

**Reality check** — the red was **not** caused by the commit it landed on. `773894d87` is **docs-only** (`git show --stat`: one design doc, one sprint plan, one JSON — zero Go files), and `test-windows` was green on the previous **11 of 12** dev runs (job wall 337–617s). The failure was `panic: test timed out after 5m0s`, package `cmd/ailang`, stack parked in `buildAilang` → `exec.Cmd.CombinedOutput` → `go build`. Both CI jobs run `go test -timeout 300s ./...` (`ci.yml:74` linux, `:318` windows). So: a package that had been sitting just under its ceiling, tipped over by a slower runner. **The instrument nearly lied first** — a `grep -E "^\s*(--- FAIL|FAIL|panic:)"` over the 99 KB job log returned **nothing**; treated as a claim rather than a fact (rule 3a), a known-positive control (`grep -c "ok "` → 105) proved the log was intact and a widened case-insensitive search found the panic immediately.

**The find** — `cmd/ailang/main_test.go:430` carried the comment *"buildAilang builds the ailang binary once per test run"*. **The comment was false**: no memoization, every call ran a full `go build` into a fresh `t.TempDir()`. Measured warm (compile-cached) link cost on this Mac: **5–6 s** for a **93 MB** binary, 3/3 runs. **14 call sites**, one per top-level test, none in loops. And the same package linked the same binary twice more — `serve_api_mcp_surface_test.go:29` with its own `go build -o … "."`, and `budget_scoping_e2e_test.go`'s `budgetBin`, **which was already correct** (`sync.Once` + a persistent `os.MkdirTemp` dir, with a comment explaining that `t.TempDir` is torn down when the *first* caller returns and would delete the shared binary). So the right pattern already existed in the same file tree, twelve lines of it, unused by its sibling. That made this Principle 3 (systemic fix, audit before patching) rather than three patches: one `sync.Once` builder, all three paths routed through it, `TestMain` cleaning up after `m.Run()`, signature unchanged so **no call site moved**. The 300s timeout was deliberately **not** raised and nothing was skipped — it is a real hang-detector.

**Shipped** — PR **#564** → squash **`3c28cc322`**, 2 commits (fix + changelog). Evaluator **sonnet PASS 91/100 round 1, zero blocking**, one NB (missing `[Unreleased]` entry) **actioned** rather than waved through. Measurements, all first-party:

| | before | after |
|---|---|---|
| `cmd/ailang`, this Mac (controller, **outside** the codex sandbox) | `ok 110.833s` | `ok 15.487s` (**7.2×**) |
| `cmd/ailang`, **windows-latest runner** | `FAIL 300.527s` (timeout) | **`ok 83.177s`** |
| `test-windows` job wall | 536s | 337s |

86% of the package's runtime was redundant re-linking. The Windows row is the one that matters and it is a **measurement, not an extrapolation** — pulled from the PR's own job log, not scaled from the Mac.

**Ruled out** — three hypotheses, each refuted by measurement rather than argument. (1) *"The merge broke it"* — refuted: docs-only diff, and the two `go test ./...` failures in the worktree were both proven external. (2) *`internal/effects` `TestNetHttpPost` is a regression* — refuted: reproduces **identically on unmodified `origin/dev`** in the main checkout (httpbin.org **503**), i.e. `#561`, filed by iteration 133. (3) *`internal/smt` `TestSolve_HardTimeout_FakeSolverIgnoringT` is a regression* — refuted, and this one needed real work because it **passed** on the base and **failed** in my worktree, which is exactly the shape a genuine regression has. Isolated: **3/3 pass alone** in the *modified* worktree, and the diff touches **zero files outside `cmd/ailang`** (control: the changed-file list printed alongside). The evaluator then found the leg I had missed — the file carries **`//go:build !windows`** (verified first-party, control: its sibling `solver_test.go` has no tag), so it cannot run on the failing job at all. A load flake under `./...` parallelism, pre-existing.

**Also ruled out — two local "failures" that were the repo's own guards working.** CI's anti-silent-skip gate appeared to fail locally: 2 of its 3 required tests printed no `--- PASS:`. Not a regression — `TestRunSmokeInTempDir_Pass` skips without `bin/ailang` (absent in a fresh worktree; CI builds it first), and `TestPromptCommand_Piping` skips via `internal/testutil.RequireAilangOnPath`, which **skips when the on-PATH binary is older than the newest Go source** — and I had just edited `main_test.go`. Both PASS once the environment matches CI, proven with a PATH-scoped scratch binary rather than by overwriting the shared `~/go/bin/ailang` that the rig's evals use. That guard is Gate 2's verification-protocol step 1 in mechanical form, and it correctly fired on me.

**Routing evidence** — model=**claude-opus-5** (controller) task-class=**execute** round1-score=**91** rounds=**1** corrections=**1** (changelog NB actioned) provider=**codex** agent=**codex** cost=**quota-bucket:codex-chatgpt**. Executor **FIRED**: `codex:gpt-5.6-sol`, 1-token probe rc=0, bounded 30-min cap, `--sandbox workspace-write`, 60,751 tokens; `codex login status` → *"Logged in using ChatGPT"*, so the subscription bucket, **not** the metered key (`OPENAI_API_KEY` is set but does not win — checked with the safe `[ -n … ]` form, never the value-printing `${VAR:+…}` shape). Evaluator **FIRED**: `sonnet`, pinned — **generator≠judge holds** (codex/OpenAI executor vs Anthropic judge, different providers). Designer/planner **NOT fired** (a CI hotfix needs no doc or plan), so the designer rotation correctly did **not** advance, staying at `claude:claude-fable-5`. `metered=$0.00` of the `$5` ceiling. **Sandbox rule honoured**: codex reported its `go test ./cmd/ailang` as `UNINFORMATIVE UNDER SANDBOX` (an unrelated `httptest` loopback bind denial) and the controller re-ran every gate outside the sandbox — mandatory here, since the diff touches `cmd/*`.

**Gate hygiene** — Gate 0/1 clean: kill switch armed, billing **CLEAN**, gh account `sunholo-voight-kampff`, **ZERO** open `[nightly-eval]` alarms (control-verified: the same search returns hits under `--state all`, so the instrument sees positives), no new Mark comment (watermark `2026-08-03T07:04:45Z` already on his last), no rotation due (`#559` created 05:08:48Z = 07:08 CEST, *after* today's Monday 07:00 **local** boundary; 4 comments < 80). Inbox: 6 messages, all eval-suite telemetry plus mission-world's iteration-43 report (informational, no ask) and our own iter-133 report — no directive, no regression; acked. **Gate-1 trap did not fire, 3rd consecutive**: `dev` == `origin/dev` == `773894d87` and the running `SKILL.md` byte-identical to origin (`cmp` silent). **The cheap tell caught my own instrument**: `grep -c "Iteration 133"` on the charter returned **0**, which reads exactly like a stale copy — the charter writes stamps in **UPPERCASE**. Re-run case-correctly it is 1, with controls (`ITERATION 132` = 2, `ITERATION 999` = 0). A case-sensitive grep is an instrument, and this one would have sent a healthy iteration down the stale-charter path.

**Retro lane** — **skill-fix**, see below. Also: Gate-4 writes were made from a **worktree branched from `origin/dev`**, not in place, because merging #564 left local `dev` 1 behind — the routine post-merge state, not a divergence (zero local commits ahead).

**Next** — `m-recorded-stream-api` **S1** (`ailang#546`), plan-ready since iteration 133, sprint JSON validated rc=0: executor `codex:gpt-5.6-sol` in a worktree **not** under `/tmp`, evaluator `sonnet`. Unchanged by this iteration.
Loading
Loading