mission-control
Skill38 starsChanged 8 days agoApache-2.0View on GitHub
Run ONE outer-loop iteration of a long-running mission (default: the V1 mission) — observe mission state, pick the top backlog item, route it through design-doc-creator → sprint-planner → sprint-executor → sprint-evaluator with the mission''s model routing policy, record a log entry, and run the retro. Use when user says "run mission control", "mission iteration", "work the v1 backlog", or when fired nightly by the dev.ailang.mission-control launchd job.
11 other projects use a version of this.
Adopted by
Most recently taken up by
- inkatze/planwrighttheir own version, first seen Nov 8, 2026
- DMNENGINE/apolotheir own version, first seen Nov 1, 2026
- evelan-de/claude-code-pluginstheir own version, first seen Oct 17, 2026
- ryotaroh180105/claude-skillstheir own version, first seen Oct 15, 2026
- chinmaireddy09/fleet-commandtheir own version, first seen Oct 13, 2026
- profbernardoj/everclawtheir own version, first seen Oct 8, 2026
Other versions11 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 11
- builderz-labs/mission-control★ 6.4ksame name
- profbernardoj/everclaw★ 112same name
- DMNENGINE/apolo★ 5same name
- inkatze/planwright★ 4same name
- evelan-de/claude-code-plugins★ 3same name
- alexanderpino/skills★ 1same name
- corygabrielsen/skills★ 1same name
- chinmaireddy09/fleet-command★ 0same name
- G-HunterAi/openclaw-skills★ 0same name
- McCavity/claude-code-dashboard★ 0same name
1 more not listed
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository85 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- docs/llms.txtllms.txt
- llms.txtllms.txt
- agent-inboxSkill
- ailang-core-triageSkill
- ailang-packagesSkill
- benchmark-managerSkill
- benchmark-runnerSkill
- builtin-developerSkill
- cli-doc-maintainerSkill
- cloud-cascade-debugSkill
- cloud-setupSkill
- codebase-organizerSkill
- collaboration-hubSkill
- coordinator-helperSkill
- design-doc-creatorSkill
- design-spec-auditorSkill
- docs-syncSkill
- eval-analyzerSkill
- eval-gap-finderSkill
- gemini-cli-helperSkill
- github-issue-triageSkill
- headless-runnerSkill
- local-model-onboardingSkill
- local-ollama-evalSkill
- mission-briefSkill
- mission-loop-changeSkill
- model-managerSkill
- motoko-analyzerSkill
- parser-developerSkill
- post-releaseSkill
- pr-monitorSkill
- prompt-managerSkill
- release-managerSkill
- sonarcloud-triageSkill
- sprint-evaluatorSkill
- sprint-executorSkill
- sprint-plannerSkill
- test-coverage-guardianSkill
- trace-debuggerSkill
- use-ailangSkill
- wasm-debuggerSkill
- agent-inboxSkill
- ailang-core-triageSkill
- ailang-packagesSkill
- benchmark-managerSkill
- benchmark-runnerSkill
- builtin-developerSkill
- cli-doc-maintainerSkill
- cloud-cascade-debugSkill
- cloud-setupSkill
- codebase-organizerSkill
- collaboration-hubSkill
- coordinator-helperSkill
- design-doc-creatorSkill
- design-spec-auditorSkill
- docs-syncSkill
- eval-analyzerSkill
- eval-gap-finderSkill
- The first 60 shown.
The file
We split this skill into the rules it gives an agent
9 rules. 0 are common, 4 are distinctive, and 5 are very specific to this project.
0
Common
Most of the 9 edited versions we read keep these.
4
Distinctive
This author's own choices. Worth a look.
5
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 8
Run ONE iteration of the mission defined in design_docs/v1-mission.md (or the mission doc passed as argument).
- Distinctive: line 229
When Mark states a ruling in an attended session and asks for it to be recorded, record it with the script — do not refuse, and do not …
- Very specific: line 241
⚠ THE FULL RULES FOR THIS GATE ARE NOT IN THIS FILE: Read .claude/skills/mission-control/resources/gate-0-preflight.md NOW, before doing …
- Very specific: line 269
INSTEAD. That loop runs no inner loop.
- Distinctive: line 311
NEVER release — stop at ready-to-release and report.
- Very specific: line 476
Rules. (a): DELETE the artifact before the run that is supposed to produce it, and assert it EXISTS afterwards — rm -f out.
- Distinctive: line 491
NOT A FILE DESCRIPTOR, SO A POLLER YOU THOUGHT WAS FINISHED RE-CREATES THE PATH AND ITS VERDICT LANDS IN YOUR NEW LOG AS IF IT WERE ABOUT …
- Distinctive: line 509
Rules. (a-bis): Before reusing an artifact path, prove the previous writer is DEAD — not that the file is gone.
- Very specific: line 545
Rule: Every spawn directive for a role that may background work carries the operative half of rule 7 in its own words: *poll the artifact …
“Common” is measured: kept by at least 6 in 10 of the 9 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Mission Control — one outer-loop iteration
Run ONE iteration of the mission defined in design_docs/v1-mission.md
(or the mission doc passed as argument). The gates run in order and are not skippable; earlier
gates are cheap and prevent expensive mistakes. This is the outer loop around the four honed
inner-loop skills — it does not duplicate them.
Read the environment by NAME, never by value — before anything else in this file (fleet iterations 51 and 52 printed CLAUDE_CODE_OAUTH_TOKEN; World iteration 332 did it again while reading the sections below, before Gate 0's copy of this rule was in view; fleet iteration 78's first command read values too). List names with env | cut -d= -f1 | grep -E '^(MISSION_|AILANG_)' | sort, then echo only the specific non-secret variables you need. A CLAUDE_CODE_ prefix matches CLAUDE_CODE_OAUTH_TOKEN, and a key-only filter misses *_TOKEN, *_SECRET and *_AUTH*.
Repo Profile (M-MISSION-PORTABILITY M2)
One skill runs EVERY mission — never fork it per mission (a fork undoes the Gate-5 self- improvement loop, since retro fixes must benefit all missions). What differs per mission is a small profile, read from two places:
⚠ A SKILL EDIT IS LIVE FOR EVERY MISSION THE INSTANT YOU SAVE IT — there is no sync step, and no "the sibling is insulated" grace period (added 2026-07-31 iteration 125; instances: iter-123 filed
#544after finding.claude/skills/vs.agents/skills/duplicated with 31 of 38 diverged, and iter-125's planner refuted the controller's own cross-mission blast-radius claim). Measured on the rig, and the measurement corrected the first draft of this very note:~/.claude/skills/mission-controlis a SYMLINK to<repo>/.claude/skills/mission-control(readlinkconfirms; both paths report the same inode). So the "global copy" and the "repo copy" are ONE FILE, not two —ls -laon the file hides this, because the symlink is on the directory. Editing the repo copy is instantly live for every mission on the rig, andailang-worldhas no repo-local.claude/skills/directory at all, so it resolves through that same symlink. A third, genuinely separate, git-tracked and already-drifted copy sits at<repo>/.agents/skills/mission-control/SKILL.md(44,067 B vs 72,254 B) — that one is a real divergence and is what#544tracks. Two consequences: (a) a Gate-5 skill edit needs no copy-sync, but it DOES take effect for the sibling mission's next fire with no review gate of its own, so write it to be true for every mission, not just this one; (b) never infer cross-mission blast radius from the DRIVER alone — the drivers really are two byte-identical files (diff -qsilent), and iter-125 cited that true fact for a broader "blast radius = zero until synced" claim that is FALSE, because the skill is shared by symlink. That is a Gate-2 rule-3b scope error: a green check quoted for a sentence wider than it supports. Check the skill path separately from the driver —readlinkbefore concluding anything about copies — or say "driver-only" and mean it. (c) "The instant you save it" holds only for an edit SAVED IN THE MAIN CHECKOUT — a Gate-5 edit COMMITTED FROM A WORKTREE reaches origin and never reaches the running skill (added 2026-08-01 iteration 128; instance 2 of the diverged-checkout class after iter-127 surfaced the divergence, and the first time the harm was measured). The symlink resolves to the MAIN CHECKOUT's working tree, so what the loop executes is that checkout's file at its own HEAD — not origin's. Iteration 128 measured its own rulebook: of the last 8 commits touching this file the newest TWO (858b067d4,c7fc3b954) wereNOT-in-local-HEAD, while every older one was — the older ones had been saved in place, the new ones committed from worktrees. So the loop was executing a copy missing iter-127's own Gate-4 STATUS-rotation mass-deletion guard, a rule added because that step had already destroyed the charter's 1,571-line queue once. The drift is one-way and unbounded: every sprint lands from a worktree, so every Gate-5 edit made that way widens the gap — silently, while this very note promises the opposite. At Gate 1, after the origin fetch, diff the RUNNING skill against origin:git show origin/dev:.claude/skills/mission-control/SKILL.md | cmp -s - "$(readlink -f ~/.claude/skills/mission-control)/SKILL.md"— and the second path MUST be the RESOLVED symlink target, never the relative.claude/skills/..., because the loop does not run from the checkout the symlink points at (added 2026-08-21 V1 iteration 241; instance 1 is iteration 240, which caught it by hand and recorded the correction in its STATUS stamp without fixing the prescription, instance 2 is this iteration, which ran the command as written and got a green from the wrong file). The relative path resolves against the CWD — and the V1 driver executes from a pinned worktree (~/.ailang-driver-pin/v1), whose own.claude/skills/mission-control/SKILL.mdis a DIFFERENT FILE from the one~/.claude/skills/mission-controlresolves to. Measured: inodes45326796(pin worktree) vs45241676(main checkout). So the check silently compares origin against a copy nothing executes, and — this is what makes it worse than useless — it reads GREEN in exactly the situation the whole rule exists to detect, because the pin worktree is checked out atorigin/devby construction while the main checkout is the one that drifts. A stale running skill is therefore guaranteed to pass the prescribed form. Rule 3a's trap aimed at this gate's own instrument: pair it withreadlinkand assert the two paths are the same file before trusting either answer. Mission-independent — any mission whose driver runs from a worktree, a pinned checkout, or any CWD other than the symlink's target has the same hole, and the generalisation is this file's own recurring shape: a relative path is a claim about where you are standing, not about which file runs. — if it DIFFERS, read the delta (git diff origin/dev -- <skill>) BEFORE proceeding and say so in the report, because the rules you are about to follow are not the rules the mission agreed on. Prefer saving Gate-5 edits in the MAIN checkout when that tree is clean enough to commit from; when Principle 0 forbids that, land via the worktree AND escalate the reconcile as a human decision — the loop cannot fix its own rulebook by writing only to a tree nobody executes.⚠ AND THAT
cmpCOVERSSKILL.mdAND NOTHING ELSE, WHILE ALMOST EVERY OPERATIVE RULE NOW LIVES IN Aresources/*.mdFILE THAT EACH GATE STUB TELLS YOU TO READ BY RELATIVE PATH — SO THE STALENESS CHECK GREENS ON THE ONE FILE THAT IS FRESH WHILE YOU READ ELEVEN THAT MAY NOT BE (added 2026-09-08 V1 iteration 349; instance 1 is iteration 241'sreadlinkrule immediately above, which closed exactly this hole forSKILL.md— and was written before the gates were split out under the progressive-disclosure gate, so the remedy stayed pointed at the file that shrank while the rules moved into files it does not cover). Every gate stub in this file says "Read.claude/skills/mission-control/resources/gate-N-….mdNOW … this stub is an index entry, not a summary you may act on." That path is relative, the loop executes from a pin worktree, and so the file you obediently read is the pin's copy — which is exactly the tree the rule above has already established is NOT the tree the skill runs from. The two halves are now inconsistent by construction:SKILL.mdarrives through the symlink (the main checkout) and its own resources arrive through the CWD (the pin), so a single invocation can execute a current rulebook whose rules are a different vintage. Measured first-party this iteration, and note which way it fails:SKILL.mdcmps byte-identical toorigin/dev, so the prescribed check reads green — whileresources/gate-3-route.mdis 75,448 B in the pin against 78,390 B running andresources/gate-3b-ci-green.md30,155 B against 33,494 B. Ten of the twelve resource files matched, which is what makes this quiet rather than obvious: a spot check almost anywhere agrees, and the two that differ are the routing and CI-verdict gates — i.e. the two whose rules decide what gets spawned and what counts as LANDED. Under a SHA-pinnedAILANG_DRIVER_REF(which is how this fleet currently deploys) the gap does not close on its own and grows with every merge. Rules. (a) Diff the resource DIRECTORY, not justSKILL.md, and do it in the same Gate-1 breath — for eachresources/*.md,git show origin/dev:.claude/skills/mission-control/resources/<f>against"$(readlink -f ~/.claude/skills/mission-control)"/resources/<f>, and print the per-file verdict rather than an aggregate (an aggregate over twelve files reads green when two differ and ten do not). (b) READ every resource file from the resolved symlink target, never from the relative path the stubs are written with — the stub's path is prose about where the file lives, not a claim about which copy you are standing next to. (c) Where the two disagree, the resolved copy WINS, because it is the oneSKILL.mditself came from; say in the report which files differed and which vintage you followed. (d) Do not "fix" this by editing the pin's copy — the pin is a throwaway worktree, so an edit there reaches nothing and is destroyed on the next re-pin. Mission-independent: every mission on this rig is pinned this way and shares these twelve files. The tell: a gate told you to read a file "NOW", you typed the path exactly as written, and you have not asked which checkout that path resolved against.
- Driver env (exported by
tools/launchd/mission-control.sh):MISSION_NAME(defaultv1),MISSION_REPO(defaultsunholo-data/ailang),MISSION_DOC(defaultdesign_docs/v1-mission.md); the bookkeeping-issue number lives in~/.ailang/state/mission-${MISSION_NAME}-gh-issue(V1 falls back to329). ⚠ NAMESPACE THAT PATH — the bare~/.ailang/state/mission-gh-issuethis profile used to prescribe is ONE FILE SHARED BY EVERY MISSION ON THE RIG, and Gate 5's rotation step WRITES to it, so a sibling's rotation week silently overwrites another mission's live inbound human channel with an issue number that does not exist in that mission's repo (fixed 2026-08-21 V1 iteration 246; proposed bymission-worlditer-106 and corroborated first-party in V1's own running copy before adoption — sibling-claim ghost discipline). This is the THIRD instance of a class this file has already fixed twice and told itself to sweep: the roles table's designer-rotation note (2026-08-13, iter-188) closes with "any~/.ailang/state/key this skill names as a literal is shared by all missions — audit the whole path list before adding another", and Gate 4's dashboard note (2026-08-17, iter-216) closes with "one namespacing fix landed, the neighbouring literal did not." Neither audit was run; this is what it would have found. It is worse than the dashboard collision, which is a read-then-overwrite a careful controller notices: this is a write onto a path the writer never reads, so the damage lands entirely on the mission that did nothing wrong, and its only symptom is a Gate-0 read pointing at nothing. Measured on the rig:mission-gh-issue=745and-prev=635, both V1's (control —745does not resolve insunholo-data/ailang-world), whilemission-world-gh-issue,mission-world-gh-issue-prev,mission-motoko-gh-issueandmission-motoko-gh-issue-prevall exist as files hand-created by careful sibling controllers that this skill's literal never read — the same signature the rotation key showed. The bare literal appeared 4 times in the running copy (Repo Profile, Gate 5's report step, and both halves of Gate 5 rotation step 4); positive controls, the two keys already namespaced, read 2 and 1, and a fresh invented literal read 0. Migration, one line and safe in both directions: on first read, if the namespaced file is absent but the bare one exists AND its number resolves in$MISSION_REPO, seed from it; otherwise treat the bare file as another mission's and never write it again. The resolves-in-my-own-repo predicate is the load-bearing half — it is what makes the migration safe for whichever mission currently owns the bare path. And run the audit rather than fixing one key: whenever this skill names a~/.ailang/state/path or adesign_docs/filename a mission writes to, ask what the sibling writes there first. The tell: you are about to write to a path whose name contains no mission identifier. - The mission doc's charter header — a
## Repo Profileblock (single source of truth, versioned with the mission): repo slug, bookkeeping-issue state key, the CI workflow names Gate 3b polls, and the verify profile name. - ⚠
MISSION_WORKDIRMEANS TWO DIFFERENT DIRECTORIES BEFORE AND AFTER THE PIN RE-EXEC, AND EVERY GATE THAT READS IT RUNS AFTER — SO THE ENV FILE'S LITERAL IS NEVER WHAT EXECUTES (added 2026-08-23 motoko iteration 20; instance 1 is V1 iteration 241'sreadlinkrule immediately above, which is this same "which copy runs?" question aimed at the SKILL path, instance 2 is this iteration's own$REPOdefect one layer down).tools/launchd/lib/pin-root.shre-execs each driver out of a worktree pinned toorigin/devand, deliberately, exportsMISSION_WORKDIR=<pin worktree>before theexecso the charter and skill move with the script. The mission env file'sMISSION_WORKDIR=<source clone>is therefore a pre-pin default, read once and overwritten — while the charter's Repo Profile, the plists and every human's mental model still say "working checkout". Measured from a live pinned session:MISSION_WORKDIR=~/.ailang-driver-pin/motokobesideAILANG_DRIVER_SRC=~/dev/sunholo-data/ailang-motoko, the latter 170 commits behind with aSKILL.md1,063 lines short. Two consequences. (a) Any notice, log line or record you build from$MISSION_WORKDIR(or from a$0-relativeREPOderived from it) on the post-exec pass names the throwaway worktree, whose drift is0by construction — so a staleness report built that way is not merely wrong, it is self-refuting, and it reads as a clean bill of health. UseAILANG_DRIVER_SRCfor the clone andMISSION_WORKDIRfor what ran. (b) A checkout the charter names but nothing executes drifts without bound and without symptom: the pin succeeds every fire, so the failure path that reports staleness never fires, and the growth sits on the success path in a log nobody reads (measured: 119 → 132 → 144 → 159 → 170 over five fires before anyone looked). Mission-independent — every mission on this rig is pinned this way — and the generalisation is the one iteration 241 already earned, aimed at a variable instead of a symlink: a path is a claim about where you were standing when it was set, not about which tree is running. The tell: you are about to name a checkout in a record or a notice, and the variable you are interpolating was set by something other than the code that is executing now.
Wherever a gate below shows a literal sunholo-data/ailang, design_docs/v1-mission.md, or 329,
that literal is the V1 default — use $MISSION_REPO / $MISSION_DOC /
${MISSION_GH_ISSUE:-<the mission's default>} so the same gate serves any mission. (War-story prose
below keeps its literal SHAs/issue numbers — only OPERATIVE commands parameterize.)
Verify profiles — the mission doc names exactly ONE
Gates 1–3b run its commands instead of make literals:
| Profile | Rebuild-before-check | Full test suite | Binary staleness | Used by |
go-compiler | make quick-install && make build (BOTH binaries) | make test | ~/go/bin/ailang (PATH) + bin/ailang go stale independently — confirm --version == git describe before trusting output | V1 (this repo compiles the toolchain) |
ailang-code | ailang install (binary ships prebuilt — nothing to compile) | ailang check (types) · ailang test (tests) · ailang ai-check (unified check+verify) | binary is a released artifact, pinned in the mission's lockfile — no -dirty staleness class | Ailang World (an AILANG-code repo) |
docs-site | nothing to rebuild — the site is the artifact | make docs-build (Docusaurus production build; the deploy workflow runs the same thing, so a green local build is the cheap pre-image of Gate 3b) · make verify-examples · ailang check <file> for any .ail touched | no dual-binary class — but the binary running verify-examples can be stale, so confirm ailang --version before quoting its output | Docs (the website upkeep loop) |
godot-game | nothing to compile — Godot and ailang are pinned releases (.github/workflows/ci.yml); make deps fetches the locked AILANG packages | make test (headless: physics reference, sim vs closed form, VM/interpreter parity, strict pure core) — what CI runs · GPU gates on the rig only: make golden, make capture, make bench, make export-smoke | ailang --version and godot --version must match the CI pins before quoting output; the mission's AILANG package pins live in sim/ailang.lock | Stapledon (sunholo-data/stapledons-godot) |
Under ailang-code, verification IS the binary's own gates: ailang check (types), ailang test
(tests), and ailang ai-check — the UNIFIED check+verify (types + Z3 in one JSON; do not
reinvent a split gate). Gate 2's Go-only steps (make quick-install, bin/ailang staleness,
t.Skip un-skip) apply to go-compiler only; under ailang-code the shipped binary is the gate.
Under docs-site there is no compile step and no dual-binary staleness class, so the go-compiler
rules about ~/go/bin/ailang and bin/ailang drifting apart do not apply. Two things replace them.
(a) The gate is the site build, and it is path-filtered in CI (docs/**, prompts/**,
llms.txt, CHANGELOG.md) while CI itself has no push paths filter — so a docs-only commit still
runs full CI, and Gate 3b must wait for it rather than reading a path-filtered skip as "not
applicable". (b) The staleness class moves rather than vanishing: make verify-examples is only
as current as the ailang binary running it, which is exactly the trap go-compiler warns about,
wearing different clothes.
Under godot-game the CI job runs only what needs no GPU. The visual gates (make golden
sub-pixel GPU-vs-CPU checks, make capture reference renders, make bench frame times, make
export-smoke on the exported app) need the rig's Metal device and a GUI session, so a green CI
is necessary but not sufficient: an item that changes anything visible is LANDED only when those
gates' output (logs + renders) is attached to the sprint JSON notes, and renders are shown to Mark
before a milestone closes. Physics maths lands in the sunholo/relativity package first (its own
ailang pkg quality gate), and the game pins the published version.
Everything else in this skill is already repo-agnostic and ports UNCHANGED: the directive-author
allowlist (MarkEdmondson1234), quorum-at-pick, the billing tripwire, the pidfile/overlap guard,
the rotation designer, and the weekly issue rotation. Namespaced state keys (M1) keep two missions
on one rig from colliding.
MARK ANSWERS DECISIONS THROUGH TWO CHANNELS, EQUAL IN RANK — AND AN ATTENDED SESSION MUST USE THE
SECOND WHEN MARK RULES IN IT (made prominent 2026-09-28; the rule itself dates from 2026-09-01 and
lives in resources/gate-0-preflight.md § "ATTENDED LEDGER EDITS", where an attended session setting
up a NEW mission never looked). (1) An allowlisted comment on the bookkeeping issue. (2) An
attended ruling written straight into the charter's decision ledger:
<ailang-checkout>/scripts/mission_answer.sh --id D-n --answer "…" --file design_docs/<name>-mission.md --commit
(one line, no leading "ANSWERED —"), then scripts/mission_decisions.sh --check --file … and push.
When Mark states a ruling in an attended session and asks for it to be recorded, record it with
the script — do not refuse, and do not bounce him to the issue because your git identity is the
fleet bot: that exact over-application cost an hour on 2026-09-02 and happened again on
2026-09-28 (stapledon D-1..D-4, bootstrapping a mission from outside this repo). Only the
UNATTENDED loop is barred from resolving rows. If the mission's loop is mid-iteration in the work
checkout, write from a separate worktree on origin/<branch> and push; the loop rebases onto it
(rule (e)).
Gate 0 — PREFLIGHT (deterministic; abort = exit silently with a controlplane message)
Deterministic preflight. Kill switch, git/gh identity, billing tripwire, dev CI, directives. Abort = exit silently.
⚠ THE FULL RULES FOR THIS GATE ARE NOT IN THIS FILE. Read
.claude/skills/mission-control/resources/gate-0-preflight.md NOW, before doing anything in
Gate 0. It is the authoritative text; this stub is an index entry, not a summary you may
act on. Skipping the read is how a gate's rules silently stop applying.
Gate 1 — OBSERVE (cheap, read-only)
Cheap read-only observation. Charter head, last log entry, inbox, parked evaluations. Spends nothing.
⚠ THE FULL RULES FOR THIS GATE ARE NOT IN THIS FILE. Read
.claude/skills/mission-control/resources/gate-1-observe.md NOW, before doing anything in
Gate 1. It is the authoritative text; this stub is an index entry, not a summary you may
act on. Skipping the read is how a gate's rules silently stop applying.
Gate 2 — PICK + REALITY-CHECK
Map the bar (which clauses are UNMET, which rows move them), then pick and REALITY-CHECK first-party. The judgement gate: most bad iterations start with an unchecked premise here, and a run of good ones can still drift off the bar.
⚠ THE FULL RULES FOR THIS GATE ARE NOT IN THIS FILE. Read
.claude/skills/mission-control/resources/gate-2-pick.md NOW, before doing anything in
Gate 2. It is the authoritative text; this stub is an index entry, not a summary you may
act on. Skipping the read is how a gate's rules silently stop applying.
Gate 3 — ROUTE + EXECUTE (the inner loop, with the routing policy)
Route and execute: designer -> planner -> executor -> evaluator, with the routing policy and the cross-provider spawn recipes.
Triage mission (MISSION_NAME=triage): read .claude/skills/mission-control/resources/gate-3-triage.md
INSTEAD. That loop runs no inner loop. It runs read-only verifiers, a different-vendor judge,
attestations and the shadow ledger, and it never approves, rejects or merges. Its Gate 2 is the
triage branch in gate-2-pick.md.
⚠ THE FULL RULES FOR THIS GATE ARE NOT IN THIS FILE. Read
.claude/skills/mission-control/resources/gate-3-route.md NOW, before doing anything in
Gate 3. It is the authoritative text; this stub is an index entry, not a summary you may
act on. Skipping the read is how a gate's rules silently stop applying.
Gate 3b — CI GREEN (an item is not LANDED until remote CI passes on its merge)
An item is not LANDED until remote CI passes on its merge. Poll pinned to the SHA you pushed.
⚠ THE FULL RULES FOR THIS GATE ARE NOT IN THIS FILE. Read
.claude/skills/mission-control/resources/gate-3b-ci-green.md NOW, before doing anything in
Gate 3b. It is the authoritative text; this stub is an index entry, not a summary you may
act on. Skipping the read is how a gate's rules silently stop applying.
Gate 4 — RECORD (append-only; the log is the mission's memory)
Append the log entry, refresh the dashboard, record the routing evidence row.
⚠ THE FULL RULES FOR THIS GATE ARE NOT IN THIS FILE. Read
.claude/skills/mission-control/resources/gate-4-record.md NOW, before doing anything in
Gate 4. It is the authoritative text; this stub is an index entry, not a summary you may
act on. Skipping the read is how a gate's rules silently stop applying.
Gate 5 — RETRO + REPORT
Retro, report on both channels. The directive watermark moves only via mission_directives.sh
--mark, after routing (Gate 0 step 8) — never by hand.
⚠ THE FULL RULES FOR THIS GATE ARE NOT IN THIS FILE. Read
.claude/skills/mission-control/resources/gate-5-retro.md NOW, before doing anything in
Gate 5. It is the authoritative text; this stub is an index entry, not a summary you may
act on. Skipping the read is how a gate's rules silently stop applying.
Standing rules
- One backlog item per iteration (a bookkeeping-only pick allows taking a second).
- Never force through a guardrail — park and report; the queue always has a next item.
- Commit per milestone on
dev(or the worktree branch); no pushes on the wrong gh account; NEVER release — stop at ready-to-release and report. - The inner-loop skills are the contract — improve them via Gate 5, don't bypass them mid-iteration because one is annoying. If a skill blocks you, that IS the retro finding.
- Data before conclusions (PROGRAM.md invariant): no fix without a measured/reproduced failure; record refuted hypotheses in the log's Ruled out field.
- Every wait is bounded (added 2026-07-12 after iteration 13 hung 4h in an unbounded
until COND; do sleep 30; done— no worktree, no commit, claude idle at 0% CPU with a livesleepgrandchild, until the 6h driver watchdog reclaimed the slot). ANY poll/wait you issue — CI (Gate 3b), a coordinator task, a background agent, an eval, amakestep — MUST carry a hard ceiling: adate +%sdeadline OR a max-iteration counter. On expiry, FAIL LOUDLY and park/report — never keep sleeping. Forbidden: a baregh run watch,while true, oruntil COND; do sleep …; donewith no cutoff. A headless iteration has no human to notice, so one unbounded wait burns the entire 6h slot. Default cap ≤30 min; treat expiry as a parkable failure, not an error to retry in place. Every wait is ACTIVE — NEVER END YOUR TURN WHILE A BACKGROUND AGENT OR BACKGROUND
BashIS STILL RUNNING (added 2026-08-08 V1 iteration 167; proposed bymission-worlditer-65, which shares this skill but cannot edit it, and corroborated first-party in V1's own driver log before adoption — sibling-claim ghost discipline). This is rule 6's mirror, and the two collide in a way that is lethal precisely because rule 6 is correct: rule 6 tells you to bound your waits, and the most natural way to "wait" for a background agent is to stop making tool calls and let the harness hold the slot for you. That is the fatal move.claude -pterminates still-running background tasks 600 s after the assistant's last turn ends, printsBackground tasks still running after 600s; terminating.— and exits rc=0. The driver then logsiteration complete (rc=0)and neither watchdog fires, because a clean exit code is exactly what they are built to ignore. So the slot ends with a plausible transcript, zero commits, zero charter rows, zero log entries: the vacuous-pass class this loop keeps closing elsewhere — success reported for work that never happened — now aimed at the loop itself. It is invisible afterwards to every check except Gate 2's died-mid-flight traces. Attribution, measured, both missions, zero misses and zero false positives:grep -c 'Background tasks still running after 600s'returns 2 in/tmp/ailang-mission-control.log(V1, lines 3193 / 3420 = the 2026-08-07 12:26 fire → iteration 159, and the 2026-08-08 09:09 fire → iteration 167 attempt 1, which died holding six freshly-measured verification rows) and 2 in/tmp/ailang-mission-world.log— World's only two orphaned slots in 67 iterations. Both V1 hits sit immediately above a transcript reading "Gates 0–2 complete; sprint-planner running", i.e. the controller had just spawned a background role and stopped. The per-gatemission-heartbeat.shstamps above are the durable attribution contract for this failure class; never skip or defer a gate's first-action stamp. The rule: while any background work you spawned is outstanding, keep the turn alive with chained bounded waits — aMonitor, a boundeddate +%spoll, or repeated short status reads — so the harness never sees you stop. Rule 6 still binds each individual wait; what changes is that expiry must be handled by you, in-turn (park, kill, report), never by going quiet and hoping. Two corollaries: (a) prefer a FOREGROUND spawn (run_in_background: false) whenever the work fits inside the tool's own limit — a synchronous call cannot be reaped this way at all; (b) the driver-side safety net isexport CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS=0, landed in V1'stools/launchd/mission-control.shat iteration 167 —0means "wait indefinitely", which is not an unbounded wait in rule 6's sense: it hands the bound to the driver'sHARD_TIMEOUTand stall watchdog, both of which fail LOUDLY, replacing a silent 10-minute rc=0. Any mission whose driver lacks that export is still exposed; check it rather than assume it. The tell: you are about to write "the planner is running; I will report back", or to end a turn whose last tool call started something you have not yet read the result of. ⚠ THE CEILING=0 SAFETY NET DOES NOT HOLD THE SLOT, AND INSTALLING IT DELETED THE ONLY WAY TO SEE THAT IT DIDN'T (added 2026-08-11 V1 iteration 176; instance 3 of this gap, and the first under the post-fix regime). Everything above treats (b) as the belt behind (a)'s braces. It is not. Measured on V1: the 11:23:12 fire ran withbg-wait-ceiling=0ms— confirmed in its own driver banner — spawned a background executor, and its controller reasoned, in the transcript, "bg-wait ceiling is0(indefinite) — the 600s reaper is disabled, so waiting on the Monitor is safe … I'll wait for the next event". The slot then loggediteration complete (rc=0)nine minutes later while the executor kept writing for a further twelve. Zero commits, zero charter rows, zero log entries — the same vacuous pass as before, arriving faster and quieter. So read (b) narrowly: it removes the harness's 600-second reap, it does not make ending your turn safe, and nothing in aclaude -prun will re-invoke you when aMonitorfires. AMonitoris an event stream, not a wait. Chain bounded in-turn polls, or spawn withrun_in_background: false, exactly as (a) says — (b) never relaxes (a). And fix your instrument before you use it to look for this.grep -c 'Background tasks still running after 600s'is the attribution tell this rule prescribes, and it is now wrong in both directions. It is blind by construction to every post-fix instance, because the ceiling suppresses the very line it greps for — so a mission with the fix installed reads clean while dying exactly as before. And it over-counts: on V1 it returns 3 against 2 real reap lines, the third being iteration 167's own log record quoting the count. This file already warns that a self-describing file poisons a known-ABSENT control; this is the same trap sprung on a known-PRESENT one, which is worse — an absent control that fires announces itself, while a present one that over-counts just looks like more evidence. Attribute a dead slot by the shape instead: aniteration complete (rc=0)whose elapsed time is far below the work it claims, sitting above a transcript that ends by announcing a wait. Then confirm with Gate 2's died-mid-flight traces (a stale worktree, an orphaned output file still growing after the exit) — those are mechanism-independent, which is the whole reason they outlive each fix.⚠ AND
pgrepIS NOT AN AUTHORITATIVE LIVENESS SIGNAL ON THIS RIG — IT FAILS IN BOTH DIRECTIONS, AND ITS FALSE NEGATIVE IS THE ONE THAT ENDS YOUR TURN (added 2026-08-20 V1 iteration 235; instance 1 is iteration 234's worktree rule, which prescribespgrepand then read its output backwards, instance 2 is this iteration's own executor poll). Rule 7 tells you to chain bounded waits rather than go quiet. It does not say what to POLL, so the natural choice is "is the process still alive?" — and that question is answered by an instrument this loop has now mis-read three times. False negative: apgrep -f 'codex exec --model …'liveness loop reported "codex process gone" while codex was demonstrably still working — its output file grew from 70 KB to 693 KB afterwards, and the worktree diff was still empty at the moment the poll declared completion. Had the turn ended there, the run would have been abandoned mid-flight and the slot would have exited rc=0, i.e. exactly the vacuous pass rule 7 exists to prevent, reached through rule 7's own remedy. False positive:pgrep -fl codexreturns fourChatGPT.apphelper processes on this rig, andpgrep -f 'claude-fable-5'matches every long-lived interactive session — so a non-empty result is not evidence either. The pattern is doing the work, and a pattern that must match a process's full argv is fragile by construction: the argv may be truncated, the process may be wrapped bysh/exec, and a substring you chose can match something unrelated. Rules. (a) Poll the artifact, not the process — the output file's size, the final-message file's existence, the worktree diff, the task's own notification. An artifact is produced by the work; a process name is produced by the shell. (b) The harness's own completion notification is authoritative andpgrepis not: never conclude "done" frompgrepwhile the notification for that task has not arrived. (c) When you do usepgrep, pair it with a known-positive control in the same call (rule 3a aimed at a process table) — a pattern that matches nothing anywhere is broken, not informative — and treat an EMPTY result as unknown, never as dead. (d) This NARROWS the worktree rule's "runpgrepand believe the output": believe a PID it returns (that direction is safe — something matched), never believe its silence. The tell: you are about to act on "the process is gone" and the only thing that told you so printed nothing.⚠ CLAUSE (b) IS TRUE OF THE TASK AND FALSE OF THE WORK — A COMPLETION NOTIFICATION REPORTS THE COMMAND YOU HANDED THE HARNESS, AND IF THAT COMMAND BACKGROUNDED ITS OWN CHILD, IT REPORTS
exit code 0THE INSTANT THE LAUNCHER RETURNS (added 2026-08-22 V1 iteration 249; three first-party instances in one iteration). Clause (b) says the notification "is authoritative", and for a foreground command it is. But this file's own recipes hand you the counter-example: the codex and pi recipes both wrap the real work in( … ) &plus adate +%sdeadline loop, and the worktree rule tells you to create a 23k-file checkout withrun_in_background: true. A launcher script whose last statement is&has finished — sorc=0is a true statement about a shell that did nothing but fork. Note it is the same shape as Gate 0'sgh issue close --comment: an exit code describes the request, not the delivery — arriving here at the one signal clause (b) elevates above every other. Measured this iteration, three times, all benign only because the polls caught them: ago buildlauncher notifiedcompleted (exit code 0)while the 96 MB binary was still being written — atest -fmoments later printedINSTRUMENT FAILURE — no binary, and the artifact was present shortly after withrc=0in its own file; agit worktree addnotified complete whilegitwas still at "Updating files: 1% (345/23852)"; and a five-gate baseline sweep notified complete before its first gate had run. Read strictly, clause (b) authorises acting on all three — and acting on the second is precisely iteration 234's half-built-worktree trap, whosegit statusreports 23,835 files as deleted. Rules. (a) A notification for a command that contains&means launched, not done — have the backgrounded body write its own terminal marker (echo DONE > …,echo "rc=$?" > …) and poll for THAT, per clause (a)'s artifact discipline aimed at the notification rather than atpgrep. (b) Prefer not backgrounding twice: if you passrun_in_background: true, let the command run in the foreground inside it, so the harness's notification and the work's completion are the same event. Double-backgrounding is what breaks (b), and it is easy to do by accident when copying a recipe that already backgrounds. (c) Keep the rc-file convention the codex recipe already uses — the code you want is the work's, and it must be captured without a pipe (step 3) inside the backgrounded body. (d) Atest -fimmediately after a notification is not a refutation either: treat an absent artifact as not yet, and let the bounded poll decide. Mission-independent, and it generalises past this harness: wherever a launcher and its work are different processes, a status from the launcher is a claim about the fork. The tell: you got a completion notification, and the command you launched ended in&.⚠ AND THE ARTIFACT THAT REMEDY SENDS YOU TO IS AN INSTRUMENT TOO — ASSERT IT IS FRESH, NOT MERELY PRESENT, BECAUSE A PATH YOU WRITE TO TWICE HOLDS THE PREVIOUS RUN'S ANSWER AND READS AS A RESULT (added 2026-08-22 V1 iteration 247; instance 1 is iteration 244's worktree-readiness poll, instance 2 is this iteration's probe harness). Clause (a) immediately above is correct and it points the whole loop at artifacts — output-file size, a final-message file, a worktree diff, a built binary — precisely because processes lie. That is a good trade and it hands you a new failure mode with no guard: a process cannot be stale, and an artifact can.
pgrepat worst tells you nothing; a leftover file tells you something specific and wrong, in the voice of a measurement. Note where this loop's existing remedy sits, because the shape is this file's own named one. The codex recipe already says to give the directive file a per-iteration name — "a fixed name collides with the previous iteration's leftover" — which is exactly this defect, guarded for one file in one recipe while every other probe artifact you write to a fixed path is unguarded: guard the helper, miss the call site. Two shapes, and they fail in opposite directions. (a) Present but not yet COMPLETE. Iteration 244's readiness poll greened ongrep -q .against a loggitwas still writing progress into, so work that had not started read as work that had finished. (b) Present but from a PREVIOUS run. Iteration 247 built a compiled-vs-interpreted harness around a hardcoded generated-package subdirectory; when codegen emitted a different directory name thego buildsilently failed, and the harness executed the binary left over from the previous round. It then reported three byte-identical runs and zero heap addresses — a green, for a determinism property, from a binary that no longer corresponded to the tree under test. Nothing in the output said "stale"; it was caught only because the paired interpreted-vs-compiled comparison came back rc=1 with content that did not match either arm, and the natural reading of that is "the fix regressed", not "my instrument is lying". Rules. (a) DELETE the artifact before the run that is supposed to produce it, and assert it EXISTS afterwards —rm -f out; cmd; test -f out || echo "INSTRUMENT FAILURE — not a verdict". Absence after a real run is loud; a leftover is silent. (b) Prefer a per-invocation path (/tmp/x_iter<N>_round<K>) over a fixed one, generalising the codex recipe's rule from its one file to every artifact you read back. (c) Assert the artifact is NEWER than the input that produced it, not merely non-empty —[ out -nt input ]— which catches (b) even when the path is reused. (d) Never let a build's exit code go unread on the way to running its output:go build ... ; rc=$?then refuse to execute on non-zero, since "the binary is missing" and "the binary is old" are the same command line away. (e) When a paired comparison disagrees with a same-run single reading, suspect the INSTRUMENT before the code — that disagreement is the only tell either shape produces. Mission-independent, and it generalises past files to any reused sink: a scratch directory, a database row, a fixed branch name, an--outtarget. The tell: you are about to read a path that a previous invocation also wrote, and nothing between the two runs removed it. ⚠ AND REMEDY (a) IS VOID WHILE THE PREVIOUS WRITER IS STILL ALIVE —rm -fDELETES A FILE, NOT A FILE DESCRIPTOR, SO A POLLER YOU THOUGHT WAS FINISHED RE-CREATES THE PATH AND ITS VERDICT LANDS IN YOUR NEW LOG AS IF IT WERE ABOUT YOUR NEW SUBJECT (added 2026-09-02 V1 iteration 320; instance 1 is iteration 247's rule immediately above, whose remedy (a) I followed to the letter, instance 2 is this iteration, where following it produced the failure). Clause (a) is written about a previous run — one that has ENDED, leaving a corpse. It says nothing about a concurrent one, and standing rule 7 is what manufactures those: it tells you to bound every wait with adate +%sdeadline, so a 30-minute CI poller keeps running long after the thing it watched has been superseded. Delete its log and it simply appends again. Note the two failure surfaces differ in kind: the.donemarker is written by whichever writer finishes FIRST, so it can be the stale one; and the log ends up INTERLEAVED, which is worse than stale, because the two verdicts are individually true and their juxtaposition is not. Measured here, at the gate that decides LANDED vs parked: a first poller was watching a pre-rebase head; I force-pushed,rm -f'd both artifacts and launched a second poller on the new head; the first then wroteALL COMPLETEinto the fresh log — a correct verdict about a commit that no longer existed — and created.done. AtailshowedALL COMPLETEat the top andpending=3at the bottom of the same file. Read as prescribed, that is a green for a run still in flight. It was caught only because the two lines contradicted each other, i.e. by rule (e), not by rule (a). Rules. (a-bis) Before reusing an artifact path, prove the previous writer is DEAD — not that the file is gone. In this harness a background task's completion notification is that proof;pgrepis not (standing rule 7's own amendment: believe a PID it returns, never its silence). (b-bis) Better, obey (b) rather than (a): give every poller a per-invocation path (/tmp/ci_iter<N>_head<sha7>.log), which makes the question moot and, unlike (a), cannot be defeated by a writer you forgot about. (c-bis) Put the SUBJECT in the verdict —ALL COMPLETE for <sha>rather thanALL COMPLETE— so a stale line identifies itself the moment it is read; that one change turns this whole class from silent into loud. (d-bis) When a superseding event happens (a force-push, a rebase, a re-run), KILL the poller watching the old subject rather than letting its deadline expire; a bounded wait is bounded in time, not in relevance. Mission-independent, and the generalisation is this file's own recurring shape aimed at the intersection of two of its own rules: rule 7 tells you to spawn bounded background watchers, and the stale-artifact rule assumes writers stop when you stop caring — the two are only jointly safe if the artifact path names its subject. The tell: you deleted a file to get a clean reading, and something that was writing to it before you deleted it has not notified you that it finished. ⚠ AND EVERY WORD OF RULE 7 IS ADDRESSED TO THE CONTROLLER, SO THE SUB-AGENTS THIS SKILL SPAWNS INHERIT NONE OF IT — A ROLE THAT ENDS ITS TURN ON A WAIT COSTS YOU A WHOLE RESUME CYCLE, AND ITS REPORT IS SIMPLY ABSENT (added 2026-09-01 motoko iteration 32; instance 1 is iteration 176's controller, which read this very rule and then reasoned "I'll wait for the next event", instance 2 is this iteration's EVALUATOR, which ended its turn with "I'll pause here and wait for the Monitor notification to arrive before compiling the report"). Rule 7 and its four amendments are complete on the question "what must I not do while background work runs?" — and every one of them is written in the second person to the loop's own session. The designer, planner, executor and evaluator never read this file. For a cross-provider role that is obvious; the trap is the Agent-tool roles, which run on the same harness, hit the sameMonitor-is-not-a-wait semantics, and are the ones you are most likely to assume already know. Guard the helper, miss the call site — this file's own named shape, aimed at the directives it tells you to write. Note the failure is quiet in the direction that matters: the sub-agent does not crash and does not report an error, it returns a plausible closing sentence announcing an intention. Iteration 32's evaluator returned exactly one line of output after 37 minutes and 93 tool calls; the score, the findings and the mutation drills existed nowhere. Recovering it cost aSendMessageresume, and the resumed run then produced the single most valuable result of the iteration (the T3 drill neither the executor nor the controller had run). Had the controller banked that one-line return as the evaluation, the iteration would have landed with no judge — standing rule 7's vacuous pass, arriving through a role rather than through the slot. Rule. Every spawn directive for a role that may background work carries the operative half of rule 7 in its own words: poll the artifact inside a boundeddate +%sloop; aMonitoris an event stream, not a wait; nothing will re-invoke you when it fires, so do not end your turn announcing one. Two corollaries. (a) When a role returns a suspiciously short result — a single sentence, no deliverable, a stated intention — treat it as not finished rather than as a verdict, and resume it by name (SendMessagekeeps its transcript, so nothing is re-run). (b) A resumed role must be told what to do about the thing it was waiting for: recover the result from disk, or declare it UNMEASURED — otherwise it waits again. Mission-independent: every mission on this rig spawns the same four roles through the same harness. The tell: a sub-agent's last sentence contains the words "wait", "pause" or "once it completes", and there is no deliverable attached to it.- THERE ARE TWO KINDS OF PARK AND THIS SKILL ONLY NAMES ONE — A DOC WAITING ON A QUOTA BUCKET IS
NOT
needs-human-review, AND FILING IT AS ONE MANUFACTURES A DECISION THE HUMAN DOES NOT HAVE (added 2026-08-19 V1 iteration 229; two consecutive first-party frictions, 228 and 229). Every park in this file resolves to one state: Gate 2's quorum flow parksneeds-human-review, Gate 3's round-3 evaluator failure parksneeds-human-review, Gate 3b's timeout parksneeds-human-review. That is correct whenever the blocker is judgment — a contested design direction, a red nobody can attribute, an objection needing a call only the human can make. It is wrong, and expensively wrong, whenever the blocker is capacity: a model lane that is quota-exhausted, a rotation entry that is structurally incapable of the role, a provider outage. The two are indistinguishable once written down, and they have opposite resume conditions — a judgment park waits indefinitely and must appear in Gate 5'sDECISIONS FOR MARK; a capacity park unblocks on a clock, needs no ask, and must NOT appear there at all. The failure mode is not merely cosmetic. Gate 0 unparks by looking for an allowlisted directive, so a capacity park filed as a judgment park can only be cleared by a human answering a question that was never real — and the human's queue is this loop's scarcest channel, which Gate 5 already protects with a hard digest cap. In the other direction the next iteration inherits a park with no machine-checkable resume predicate and must reconstruct the entire routing story from prose to learn that it could simply have re-run. Measured, both iterations, same rotation and same shape:codex:gpt-5.6-solprobed rc=1 ("usage limit … try again at Aug 20th, 2026 5:34 AM"), the next rotation entry (gemini/managed_agents) is read-only underCapRemoteSandboxand cannot author a file at all, so the designer resolved to Fable as a fallback — where the Fable diet allows one bounded run per iteration. Iteration 228 spent two (create + revision) and FLAGGED the diet violation; iteration 229 hit the identical wall on a round-1 block and declined to repeat it, at which point there was no state in this skill that says "a revision is owed, nothing is being asked of anyone, and the lane returns at 05:34." Rule. Classify every park before writing it. (a) Judgment →needs-human-review, and it carries a one-word-answerable ask into the Gate-5 DECISIONS row, as today. (b) Capacity →PARKED-ON-LANE, and it MUST name three things: the role that could not run, the lane that refused with the command and its rc, and the time or condition the lane returns. (c) APARKED-ON-LANEitem never enters DECISIONS and never counts as a decision in the ledger — if you find yourself writing an ask whose answer is "wait", you have misclassified it. (d) Its resume is a predicate, not a narrative: the next iteration re-probes the named lane and proceeds on rc=0, exactly as the blocked-external-row rule requires the predicate be run as a command rather than transcribed. (e) When a lane park recurs for the same role in consecutive iterations, that is a routing-policy signal, not a fact about the item — surface it in the report, because the loop cannot widen its own rotation but the human can. Mission-independent by construction: every mission on this rig shares one rotation file and the same quota buckets, so all three hit this the same way. The tell: you are about to fileneeds-human-reviewand the sentence explaining why contains a reset time, a quota, or the phrase "no other route".
Current State
⚠ POSITION IS DELIBERATE — THIS BLOCK IS LAST BECAUSE IT IS VOLATILE. Every line below runs a command at load time, so its output differs on every fire. Prompt caching keys on a byte-identical PREFIX, so anything placed AFTER volatile content can never be served from cache. Keeping the ~12k-token stable body above this block is what lets it cache between fires; moving this section up would silently forfeit that for everything below it.
⚠ EVERY LINE BELOW IS A V1-SHAPED DEFAULT — namespace it per the ACTUAL mission before trusting
it (added 2026-08-28, docs-mission iteration 0; instance 5 of the "bare ~/.ailang/state/
literal in this shared skill is fleet-shared, not per-mission" class this file has already fixed
four times over — designer-rotation, mission-gh-issue, mission-dashboard.md — and each time
called for auditing "the whole path list", which this is). tools/launchd/mission-control.sh
itself resolves the kill switch to mission-control.disabled for V1 only (bit-for-bit legacy
compat) and to mission-${MISSION_NAME}.disabled for every other mission — so the bare literal
below is CORRECT for V1 and WRONG for docs/world/motoko, and a controller who runs it as-written
for a non-V1 mission gets a confident "armed" reading from a file that mission never writes to.
Measured first-party: docs-mission's own charter STATUS names ~/.ailang/state/mission-docs.disabled
as ITS kill switch; checking the bare path instead would have silently missed a real disable. The
"Queue head" and "Last log entry" lines have the identical defect one file over — v1-mission.md/
v1-mission-log.md are V1's own filenames, not this skill's.
- Kill switch: !'K="$HOME/.ailang/state/mission-control.disabled"; [ "${MISSION_NAME:-v1}" = "v1" ] || K="$HOME/.ailang/state/mission-${MISSION_NAME}.disabled"; test -f "$K" && echo "DISABLED — STOP ($K)" || echo "armed ($K)"'
- Branch / tree: !'git branch --show-current && git status --porcelain | head -5'
- gh account: !'gh auth status 2>&1 | grep -E "Active account|Logged in" | head -2'
- Queue head: !'grep -A2 "^## Queue" "${MISSION_DOC:-design_docs/v1-mission.md}" | tail -2'
- Last log entry: !'grep "^## " "design_docs/${MISSION_NAME:-v1}-mission-log.md" | tail -1'
- Unread inbox: !'ailang messages list --unread 2>/dev/null | head -8 || echo "none"'
- Parked evaluations: !'ls .ailang/state/evaluations/ 2>/dev/null | tail -3 || echo "none"'
Use the injected data above first; re-run only if empty or stale.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

