fix(skills): give the stow sweep and the ceiling wakes their missing next steps - #62
Merged
Conversation
added 4 commits
August 3, 2026 20:15
…ision surface Records the captain's 2026-08-02 decision: past 300k of context, stow durable knowledge and clear at the next quiet boundary, rebuilding from durable records rather than compacting the transcript. The stow skill owns the cadence in full; the rendered supervision block and the heartbeat item carry only the trigger, so there is no second copy of the rule and no per-harness duplicate. No hook, daemon, or transcript probe is added - that variant was explicitly rejected. Committed on a base that predates docs/context-reset.md; reconciliation against the current default branch follows.
…ed mechanism The reset mechanism landed while this branch was blocked, so most of the original change is superseded and is removed here rather than kept as a second copy: the supervision block no longer restates a threshold the watcher measures, and the heartbeat item no longer duplicates section 8 item 3. Two gaps remain, and this is what stays: The stow skill said nothing about being a step inside a verified reset. It now states what belongs to the sweep rather than to the mechanism - that the receipt attests to the sweep and cannot verify it, that captain input between sweep and receipt correctly voids it, and that a resumable clear is a safety net rather than a licence to sweep thinly - and points the mechanism itself at docs/context-reset.md. Section 8 item 3 described every context-ceiling wake as carrying its own next step. The reset and ask branches do; the unenforced and blocked branches carry a diagnosis instead, so a model meeting those had nothing to act on. It now says to repair the named condition or report it as unrepaired.
…clarify ceiling wording
… ceiling wake branches
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.
Intent
Implement the captain's 2026-08-02 decision to hold firstmate's session context to a 300k ceiling using the fleet's existing stow-then-clear instrument (NOT compaction - compaction is explicitly forbidden here and must never be added, enabled, configured, or recommended).
History matters for reading this branch, because it has two commits that partly undo each other and that is deliberate, not an accident:
Commit 1 (29609e4) was written against a base that is now 43 commits stale. At that time no reset mechanism existed, so it stated the ceiling in three places: a shared line in the rendered supervision block (bin/fm-supervision-instructions.sh), a heartbeat checklist item in AGENTS.md section 8, and a full cadence section in the stow skill as the one owner. Work was then blocked: the captain correctly pointed out that firstmate cannot clear its own context, so an instruction to run /stow then /clear was one the model was structurally unable to follow - an instruction that cannot execute and cannot visibly fail. That commit was made purely to preserve the work before rebasing, on explicit instruction, and is intentionally kept in history rather than squashed away.
Commit 2 (8d05a1b) reconciles that work against the mechanism that landed in the meantime (docs/context-reset.md, bin/fm-context-lib.sh, bin/fm-context-reset.sh, bin/fm-stow-receipt.sh, and the watcher's context_ceiling_surface). Most of commit 1 is deliberately REMOVED there as superseded, not because it was wrong to write but because the landed mechanism now owns it and a second copy would drift. Specifically: the supervision-block lines are gone (bin/fm-supervision-instructions.sh and docs/supervision-protocols/ are now byte-identical to origin/main), and the AGENTS.md heartbeat item is gone because section 8 item 3 already states it better - item 3 names the receipt and reset commands, which my heartbeat line omitted. A conflict in docs/architecture.md was resolved wholly in favour of the landed text because my paragraph ended with 'no hook or daemon measures it', which the watcher had just made false.
The net change against origin/main is therefore only 79 lines in four files, and is exactly the two gaps that survived that reconciliation:
.agents/skills/stow/SKILL.md - the /stow skill said nothing about now being a load-bearing step inside an automated, verified reset. It is the only step in an otherwise all-code path that requires judgement. The new section states what belongs to the sweep rather than to the mechanism: the receipt attests to the sweep and cannot verify it (so a thin sweep yields a structurally valid but substantively false receipt), captain input between sweep and receipt correctly invalidates it (so the two belong in one turn), and a cleared conversation stays resumable so a missed finding is misplaced rather than lost - which is a safety net, not licence to sweep thinly. The mechanism itself is pointed at docs/context-reset.md rather than restated, under the repo's one-owner rule. The frontmatter description trigger was updated to name the context-ceiling wake as a second caller.
AGENTS.md section 8 item 3 - it described every context-ceiling wake as one 'whose payload carries its own next step'. That is true of the reset and ask branches, whose payloads name exact commands, but NOT of the unenforced and blocked branches, whose payloads carry a diagnosis with no command (for example 'the ceiling is unenforced until that is repaired'). A model meeting those two branches had nothing to act on. One added line says to repair the named condition or say plainly that it stands unrepaired.
Deliberate choices a reviewer should not flag as mistakes:
Verification already run locally: bin/fm-test-run.sh --changed passed 31 tests with 0 failures, including tests/fm-context-reset.test.sh (54 assertions covering the landed mechanism), tests/fm-instruction-owners.test.sh, and tests/fm-captain-translation-contract.test.sh. shellcheck -x is clean on both touched test files; no non-test script is modified.
Constraint from the captain: stop at the pull request, do not merge.
What Changed
.agents/skills/stow/SKILL.mdgains a "When the context ceiling calls this sweep" section and a frontmatter trigger that now fires on a context-ceiling wake (and on a compaction the harness performs anyway, which is explicitly not the instrument that holds the ceiling). The section states only what belongs to the sweep - the receipt attests to it but cannot verify it, captain input after the receipt correctly invalidates it so both belong in one turn, and a cleared conversation stays resumable as a safety net rather than licence to sweep thinly - and points atdocs/context-reset.mdas the owner of the mechanism itself.AGENTS.mdsection 8 item 3 previously described every context-ceiling wake as carrying its own next step, which holds for the reset and ask branches but not for the unenforced and blocked branches; an added line says to repair the named condition or state plainly that it stands unrepaired.docs/architecture.mdnow describes all three wake branches, anddocs/context-reset.mdnames the stow skill as owner of the sweep's obligations.tests/fm-stow-contract.test.shadds three cases covering the new section, the dispatch trigger, and the AGENTS.md line;tests/fm-supervision-instructions.test.shadds a case asserting the ceiling is deliberately absent from every rendered harness block and fromdocs/supervision-protocols/*.md, with a glob-expansion guard (added during review) so that absence check cannot pass vacuously. No non-test script is modified.Risk Assessment
✅ Low: The follow-up commit resolves all three prior findings using existing repo conventions and touches nothing executable, leaving a well-bounded 86-line documentation and test change whose every factual claim is verified against the landed mechanism in bin/fm-context-lib.sh, bin/fm-stow-receipt.sh, and bin/fm-context-reset.sh.
Testing
Ran the repo's changed-file selection (31 tests, 0 failures) plus the two touched test files and the three doc-contract/mechanism suites named in the intent, then demonstrated the change at the surface a firstmate model actually meets: I drove the real
context_ceiling_surfaceto emit all four context-ceiling wake payloads, showing that the blocked and unenforced branches end in a condition with no command and that the new AGENTS.md line is what now tells the model to repair it or report it unrepaired, and captured the /stow skill's new sweep section and updated trigger alongside proof that no rendered supervision block or protocol snippet carries a second copy of the 300k value. I added one focused assertion on the skill's frontmatter dispatch trigger, which no test had guarded, and mutation-checked that it fails when that line is reverted. There is no UI surface to screenshot: the change is agent-instruction Markdown and shell tests, so the reviewer-visible artifacts are CLI transcripts of the wake payloads and rendered instruction text. Worktree is clean apart from that intentional test addition.Evidence: Real context-ceiling wake payloads (all four branches) vs the new AGENTS.md guidance
=== context-ceiling wake payloads a firstmate session actually receives === source: bin/fm-watch.sh context_ceiling_surface -> bin/fm-context-lib.sh fm_context_ceiling_reason --- branch: reset (payload names its own next step) --- check: context-ceiling: 900000 tokens is over the 300000 ceiling, the fleet is quiet and the captain is not present - run /stow now, then in the SAME turn run: <root>/bin/fm-stow-receipt.sh && <root>/bin/fm-context-reset.sh --- branch: ask (payload names its own next step) --- check: context-ceiling: 900000 tokens is over the 300000 ceiling and the fleet is quiet, but the captain has been active - ASK the captain before resetting; never reset autonomously during a live conversation --- branch: blocked (payload names a CONDITION, no command) --- check: context-ceiling: 900000 tokens is over the 300000 ceiling, but a reset cannot run safely: the session-start hook in <home>/.claude/settings.json no longer runs fm-sessionstart-nudge.sh on a clear --- branch: unenforced (payload names a CONDITION, no command) --- check: context-ceiling: a firstmate session is running here but its context cannot be measured (no session transcript recorded at <state>/.primary-transcript); the 300000 ceiling is unenforced until that is repaired === what AGENTS.md section 8 item 3 now tells the model for each branch === 3. Forcheck:, act on the named poll result, including merges, Bridge inbox traffic, X-mode events, certsync health, and a context-ceiling wake whose payload carries its own next step: either run/stowand then, in that same turn, the receipt and reset commands it names, or ask the captain first because a reset must never happen during a live conversation. A ceiling wake that instead reports the ceiling unenforced, or a reset blocked, names a condition rather than a next step: repair the named condition, or say plainly that it stands unrepaired, because a ceiling nobody can measure is one nobody is holding.Evidence: Deliberate absence: no rendered supervision block or protocol snippet restates the ceiling
=== deliberate absence: no rendered supervision block carries a second copy of the ceiling === claude block: 31 lines | grep -c "300k"=0 | grep -c "Context ceiling"=0 codex block: 30 lines | grep -c "300k"=0 | grep -c "Context ceiling"=0 grok block: 51 lines | grep -c "300k"=0 | grep -c "Context ceiling"=0 opencode block: 31 lines | grep -c "300k"=0 | grep -c "Context ceiling"=0 pi block: 40 lines | grep -c "300k"=0 | grep -c "Context ceiling"=0 not-real block: 21 lines | grep -c "300k"=0 | grep -c "Context ceiling"=0 per-harness protocol snippets under docs/supervision-protocols/: all six files grep -c "300k"=0 and the files commit 1 touched are byte-identical to origin/main: (empty diff = identical)Evidence: /stow skill surface: frontmatter trigger, new sweep section, compaction ruled out
--- forbidden-instrument check: compaction is never offered as the ceiling instrument --- 3:description: ... before a compaction the harness is about to perform anyway (file ahead of one; a compaction is never the instrument that holds the context ceiling), and on a context-ceiling wake that asks for this sweep before the receipt and reset commands it names. 32:The instrument here is stow-then-clear, never compaction: durable knowledge goes to disk and the next session rebuilds from it ... 33:Nothing in this skill adds, enables, or recommends compaction as a way to hold the ceiling. changed non-doc/test files in this branch (must be none): (no lines = only Markdown and tests changed)Evidence: Evidence harness used to emit the four real wake payloads
Pipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
🔧 **Review** - 3 issues found → auto-fixed ✅
tests/fm-supervision-instructions.test.sh:246- The per-snippet loopfor snippet in "$ROOT"/docs/supervision-protocols/*.mdhas no guard that the glob expanded. If that directory is renamed, moved, or emptied, bash leaves the pattern literal,assert_no_greprunsgrep -F -- '300k' '<literal-glob-path>', grep exits 2 on the missing file, and! greptherefore succeeds - so the test reports the ceiling-absence invariant as held while checking nothing (it only leaks a 'No such file' line on stderr, which the runner does not fail on). This is the same silent-staleness failure mode tests/lib.sh's own helper comments call out. Add a presence guard inside the loop (e.g.assert_present "$snippet" "...", already used in tests/fm-instruction-owners.test.sh) or fail when the expansion is the literal pattern..agents/skills/stow/SKILL.md:19- "the watcher measures the primary session against it and, when the session is over and the fleet is quiet, queues a wake" - "the session is over" parses first as "the session has ended", which is the opposite of the condition (over the ceiling) and is a state in which no sweep could run. In a model-facing instruction file this ambiguity is load-bearing; "when the session is over that ceiling and the fleet is quiet" removes it without changing intent..agents/skills/stow/SKILL.md:3- The frontmatter trigger changed from "before a session reset or context compaction" to "before a session or context reset", so the compaction moment is no longer a documented trigger for the sweep. The intent says the description "was updated to name the context-ceiling wake as a second caller" and forbids adding, enabling, configuring, or recommending compaction - naming compaction as a moment to stow BEFORE is none of those, and harnesses still auto-compact independently of fleet policy (.agents/skills/stuck-crewmate-recovery/SKILL.md:47 states this, and nothing in the repo disables auto-compact). Confirm the trigger removal is intended rather than collateral to the ceiling-caller edit; if not, the clause can be restored alongside the new caller.🔧 Fix: guard snippet glob; restore compaction trigger; clarify ceiling wording
✅ Re-checked - no issues remain.
✅ **Test** - passed
✅ No issues found.
bash tests/fm-stow-contract.test.shbash tests/fm-supervision-instructions.test.shbash tests/fm-context-reset.test.shbash tests/fm-instruction-owners.test.shbash tests/fm-captain-translation-contract.test.shbin/fm-test-run.sh --changed(31 tests, 0 failures, 1 gate-skip)Manual end-to-end: sourcedbin/fm-watch.shand calledcontext_ceiling_surfaceagainst four fixture homes to print the real reset / ask / blocked / unenforced wake payloads next to AGENTS.md section 8 item 3Manual: renderedbin/fm-supervision-instructions.sh --harness <claude|codex|grok|opencode|pi|not-real>and grepped every block plusdocs/supervision-protocols/*.mdfor300kandContext ceiling(0 hits), and confirmedgit diff origin/main...HEAD -- bin/fm-supervision-instructions.sh docs/supervision-protocols/is emptyAdded and mutation-checkedtest_stow_skill_trigger_names_the_context_ceiling_callerintests/fm-stow-contract.test.sh: reverting the SKILL.md frontmatter description to origin/main's makes it fail, restoring makes it pass.agents/skills/stow/SKILL.md:21- The three bullets in the new "When the context ceiling calls this sweep" section are near-restatements of facts docs/context-reset.md already owns: the receipt is an attestation not a proof (context-reset.md:57-59), captain input after the receipt invalidates it (context-reset.md:67), and a cleared conversation stays resumable (context-reset.md:70-72). I left them as authored because the user intent states this framing is deliberate - the skill is meant to carry the sweep-side judgement the mechanism cannot perform for itself, and it does point at docs/context-reset.md as the mechanism owner rather than restating the loop or the refusals. Flagging it only as a drift risk: if either copy is later revised, the two will disagree about what the receipt proves. A follow-up could reduce the bullets to their sweep-side imperative alone (sweep in one turn with the receipt, sweep as though the conversation were lost) and let the rationale live solely in the owner doc.✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.