Skip to content

fix: remove startup memory budget while preserving archival - #72

Merged
ashkonmousavi merged 5 commits into
mainfrom
fm/fm-main700-remove-startup-word-budget-v2
Oct 6, 2026
Merged

ashkonmousavi merged 5 commits into
mainfrom
fm/fm-main700-remove-startup-word-budget-v2

Conversation

@ashkonmousavi

@ashkonmousavi ashkonmousavi commented Oct 6, 2026 •

Copy link
Copy Markdown
Owner

Intent

Remove the startup word budget; archive old rulings instead.

Accepted specification from the preparation record (not the captain's words):

Expected outcomes and how to check each

Outcome Exact observable result Where and how to check Expected value
O1 No budget created A fresh primary bootstrap writes no config/startup-memory-budget and prints no STARTUP_MEMORY_BUDGET line bash tests/fm-bootstrap.test.sh fixture home file absent, no such line
O2 No budget inherited Secondmate propagation lists no startup-memory-budget item bash tests/fm-secondmate-harness.test.sh passes with the item gone
O3 Cascade still resolves transport Each stanza carries secondmate, placement, home and transport, with no budget_report key bash tests/fm-stow-cascade.test.sh passes; no budget_report= in output
O4 Old rulings still archived /stow keeps date-decay and consolidation archival to data/memory-archive.md and has no budget step reviewer read of .agents/skills/stow/SKILL.md plus git grep -n -i budget .agents/skills/stow/SKILL.md cold-tier section present; grep output empty
O5 Nothing references the removed owner No tracked file names the script, library, setting or diagnostic git grep -n -e startup-memory-budget -e STARTUP_MEMORY_BUDGET -e fm_startup_memory no output, exit 1
O6 Docs and lint consistent Configuration, layout, diagnostics and trigger index no longer describe the budget bin/fm-doc-audience-check.sh; bin/fm-lint.sh both exit 0

2. Behaviour spec

States: before the change a primary home's bootstrap materializes config/startup-memory-budget, /stow measures and evicts to it and may open captain decisions to raise it; after the change bootstrap is silent about it, an existing file is ignored, /stow never measures against a budget, never evicts for size and never opens a budget decision.
Controls: the captain loses the config/startup-memory-budget setting; no control is added.
Actions and results: /stow still reinforces, decays, consolidates and archives stale or superseded entries to data/memory-archive.md, offloads conditional material to an existing live owner when step 3's retention plan prefers it, and still cascades to secondmates by transport.
Copy: the /stow receipt drops the "effective startup-memory budget and total estimated tokens" line and the over-budget wording; the reset-safe rule keeps its unresolved-exception condition without the budget clause.
Restart and reopen: a home updated to this change and restarted reads no budget; a not-yet-updated remote secondmate still has its old script, which the updated cascade no longer calls.

11. Definition of done

  • O1-O6 observed in the worker's report with commands and outputs.
  • Only this removal ships, as its own Firstmate PR through the publication route in the six-cuts report, green on current-head CI, merged by Firstmate through bin/fm-pr-merge.sh under MAIN700 authority.
  • No FINALIZE-AFTER marker for this id exists.
  • Main then updates every home; merged but not on every home is not done.

What Changed

  • Remove startup-memory budget helpers, bootstrap defaults and diagnostics, config inheritance, and related documentation and tests.
  • Remove /stow size accounting, budget eviction, and budget decisions while retaining decay, consolidation, archival to data/memory-archive.md, planned offload, and secondmate transport routing.
  • Order inherited-config reread generations by durable sequence rather than timestamp, add backward-clock regression coverage, and move backlog fault injection off the removed budget path.

Risk Assessment

✅ Low: The bounded removal preserves archival, ownership rules, and cascade routing, and the prior fix matches its authorized scope.

Testing

Focused acceptance tests and live CLI/native-Claude scenarios passed, with receipts and persisted memory retained as evidence. The backward-clock regression failed on the base and passed on the target; full live retry delivery remained blocked by the gate guard. No graphical UI changed. Lint, CI, publication, merge and home rollout remain with the outer executor.

  • Live validation: ✅ go - 8 of 9 scenarios driven live against the product
Scenario Result Live Evidence
Bootstrap a fresh primary without creating a budget setting or diagnostic ✅ pass live r2-fresh-bootstrap.txt; r2-live-product.log
Restart a home with an invalid legacy setting and leave that file untouched ✅ pass live r2-legacy-bootstrap.txt; r2-legacy-session-start.txt
Push inherited configuration without listing or creating the retired setting ✅ pass live r2-config-push.txt; r2-live-product.log
Resolve direct, live-agent and deferred cascade routes with complete routing fields and no budget report ✅ pass live r2-local-cascade.txt; r2-deferred-cascade.txt; r2-agent-cascade.txt
Run stow to archive stale rulings with provenance and consolidate duplicates while retaining current memory despite a legacy limit of one ✅ pass live r2-stow-native-transcript.txt; r2-stow-after-primary/memory-archive.md; r2-behavior-checks.json
Offload current conditional knowledge to its existing private owner before removing it from startup memory ✅ pass live r2-stow-after-primary/lab-calibration.md; r2-behavior-checks.json
Cascade stow to a local secondmate, archive its old ruling and preserve its shared input byte-for-byte ✅ pass live r2-stow-native-transcript.txt; r2-stow-after-secondary/memory-archive.md; r2-behavior-checks.json
Receive a stow receipt without budget accounting or decisions that withholds reset safety while a remote exception remains ✅ pass live r2-stow-receipt.md; r2-native-receipt-checks.json; r2-stow-state-files.json
Retry a failed configuration instruction before delivering a newer generation when the clock moves backward ⏸️ untested no Attempted the real configuration-push executable against marked disposable homes and a private tmux endpoint, injecting an instruction-write failure and clock rollback. Its nested fm-send call supplie…
Evidence: Live bootstrap, inheritance and cascade transcript

Source: Live bootstrap, inheritance and cascade transcript

$ bin/fm-lab-home.sh create ~/.no-mistakes/evidence/01M49EBAM259QST2W72QEEJVGG/.lp
~/.no-mistakes/evidence/01M49EBAM259QST2W72QEEJVGG/.lp

exit=0
$ bin/fm-lab-home.sh create ~/.no-mistakes/evidence/01M49EBAM259QST2W72QEEJVGG/.ls
~/.no-mistakes/evidence/01M49EBAM259QST2W72QEEJVGG/.ls

exit=0
$ bin/fm-lab-home.sh create ~/.no-mistakes/evidence/01M49EBAM259QST2W72QEEJVGG/.lt
~/.no-mistakes/evidence/01M49EBAM259QST2W72QEEJVGG/.lt

exit=0
$ bin/fm-bootstrap.sh
BOOTSTRAP_INFO: lavish-axi >=0.1.80 enables confirmed board replies; this older compatible version retains the legacy reply path, but upgrade to prevent handing back a board before its reply is accepted

exit=0
PASS Fresh primary creates no retired setting and emits no retired diagnostic
$ bin/fm-bootstrap.sh
BOOTSTRAP_INFO: lavish-axi >=0.1.80 enables confirmed board replies; this older compatible version retains the legacy reply path, but upgrade to prevent handing back a board before its reply is accepted

exit=0
PASS Invalid legacy setting is ignored and preserved
$ bin/fm-session-start.sh

================================================================================
SESSION START - ~/.no-mistakes/evidence/01M49EBAM259QST2W72QEEJVGG/.lp
================================================================================

LOCK
--------------------------------------------------------------------------------
lock acquired: harness pid 9748

BOOTSTRAP
--------------------------------------------------------------------------------
BOOTSTRAP_INFO: lavish-axi >=0.1.80 enables confirmed board replies; this older compatible version retains the legacy reply path, but upgrade to prevent handing back a board before its reply is accepted

WAKE QUEUE
--------------------------------------------------------------------------------
(no queued wakes)
================================================================================
SUPERVISION OPERATING INSTRUCTIONS - primary harness: codex
================================================================================
Current state:
- Lock: held by this session; this session owns normal supervision unless away mode says otherwise.
- Away/quiet mode: inactive.
- X mode: inactive; use the default watcher cadence.
- Ordinary wake: take the next foreground bin/fm-watch-checkpoint.sh checkpoint as directed below.

Mode: Codex foreground checkpoint.

Whenever this session owns supervision, including while the away-posture record exists:
1. Drain first with `bin/fm-wake-drain.sh`.
   After handling all emitted wakes and reconciling open decisions and unread status lines, run the exact `--ack-through` command printed as `WAKE_ACK_REQUIRED`; until then the work remains durable for idempotent re-handling after interruption.
2. Source `~/.no-mistakes/evidence/01M49EBAM259QST2W72QEEJVGG/.lp/config/x-mode.env` first when Relay is active.
3. First cycle: run one foreground watcher checkpoint with `bin/fm-watch-checkpoint.sh --seconds "${FM_CODEX_WATCH_CHECKPOINT:-180}"`.
4. Ordinary wake: if the command prints `signal:`, `stale:`, `check:`, or `heartbeat`, drain queued wakes, handle that wake, then start the next checkpoint.
5. If the command prints `checkpoint:` or exits 124 with no wake, drain queued wakes anyway, process any queued user message now visible to Codex, then start the next checkpoint.
6. Never use shell `&` or Codex background tasks for firstmate watcher supervision.
7. Do not run `bin/fm-watch-arm.sh` as Codex's normal supervision command.
   If it is ever shelled anyway, a backgrounded, piped, or bundled anti-pattern is denied automatically by the PreToolUse seatbelt (`bin/fm-arm-pretool-check.sh`) registered in `.codex/hooks.json`.
8. Failure or missing cycle only: drain queued wakes, inspect the failure, then start a fresh foreground checkpoint.

Away mode changes notification and decision handling, not this ownership loop.
Do not launch `bin/fm-afk-launch.sh start` except when the repair line identifies a live legacy away daemon for its guarded handoff, and do not finalize to an idle prompt while supervision is needed.
The foreground checkpoint returns durable watcher output directly to Codex without typing into or submitting the composer, so pending user text remains untouched.

Codex cannot reason while a foreground tool call is running.
The bounded checkpoint returns control regularly so user messages and queued wakes can be handled without relying on background-task wake semantics.


================================================================================
READ-ONCE CONTRACT
================================================================================
Everything below is printed in full for this session start: every state/*.meta,
a compact data/backlog.md listing, a bounded tail of every state/*.status,
data/projects.md, data/secondmates.md, data/captain.md, data/captain-shared.md,
and data/learnings.md.
Do NOT re-read any of them after reading this digest, and do NOT bulk-read
data/backlog.md or state/*.status: re-reading everything defeats the entire
point of this command.

Go to a source directly only when:
  - this digest flagged it ABSENT (then rebuild or create it per AGENTS.md),
  - its contents looked unparseable or corrupt,
  - an individual full status log is needed for older wake-event history, or a
    status line was capped and its tail matters (each task's full log path is
    printed with its tail),
  - a full task body is needed (bin/fm-tasks-axi.sh show <id> --full, or data/backlog.md),
  - the backlog listing disclosed omitted queued items and this turn needs them,
  - the NETWORK CHECKS section reported its checks still IN PROGRESS and this
    turn needs their verdict (bin/fm-startup-network.sh report),
  - or a STARTUP TRUNCATED banner named the stage that would have printed it, in
    which case that stage's sources were never emitted and must be reconciled.

================================================================================
FLEET STATE
================================================================================

data/backlog.md
--------------------------------------------------------------------------------
ABSENT

Work under way (state/*.meta)
--------------------------------------------------------------------------------
(none)

Orphan status logs (state/*.status without matching .meta)
--------------------------------------------------------------------------------
(none)

AFK
--------------------------------------------------------------------------------
absent

================================================================================
NETWORK CHECKS
================================================================================
IN PROGRESS - the deferred network checks have not finished yet.
NOT yet confirmed: GitHub authentication, dead-secondmate relaunch, secondmate convergence, pending handoff delivery, project clone refresh with its drift reporting, and inactive terminal-outcome reconciliation.
Started 3s ago, bounded at 120s.
Only a FAILED or otherwise actionable result arrives as a `check: startup-network` wake; a clean success stays silent.
The durable result is readable on demand with ~/.no-mistakes/worktrees/892c8faf04fc/01M49EBAM259QST2W72QEEJVGG/bin/fm-startup-network.sh report; until it finishes, treat none of it as confirmed.

================================================================================
CONTEXT
================================================================================

data/projects.md
--------------------------------------------------------------------------------
ABSENT

data/secondmates.md
--------------------------------------------------------------------------------
ABSENT

data/captain.md
--------------------------------------------------------------------------------
ABSENT

data/captain-shared.md (shared, main-authoritative, read-only in secondmate homes)
--------------------------------------------------------------------------------
ABSENT

data/learnings.md
--------------------------------------------------------------------------------
ABSENT

================================================================================
NEXT STEP
================================================================================
Follow the supervision operating instructions block above for harness 'codex'.
This script never starts supervision itself.

The digest above is complete for this session start. The READ-ONCE CONTRACT
section near the top of it governs what may still be read from disk.

exit=0
PASS Restart digest has no retired diagnostic and preserves invalid legacy file
$ bin/fm-config-push.sh
●━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
●  WATCHER DOWN - SUPERVISION IS OFF
●  2 task(s) in flight, but no watcher has a fresh beacon (last beat: never, grace 300s).
●  Trust the emitted supervision protocol for this harness; do not use shell & for watcher repair.
●  This is a supervision warning only; the guarded operation WILL still run.
●  repair missing watcher supervision with a foreground checkpoint: bin/fm-watch-checkpoint.sh --seconds 180.
●━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
config-push: ~/.no-mistakes/evidence/01M49EBAM259QST2W72QEEJVGG/.lp -> live secondmate homes
secondmate local-fresh (~/.no-mistakes/evidence/01M49EBAM259QST2W72QEEJVGG/.lt):
  crew-dispatch.json: unchanged
  dispatch-never-send: unchanged
  crew-harness: unchanged
  backlog-backend: unchanged
  backend: unchanged
  herdr-presentation-spaces: unchanged
  trace-context: unchanged - session-scoped
  launch-env-allowlist: unchanged
  claude-permission-mode: unchanged
  claude-worker-settings.json: unchanged
  lavish-axi-host: unchanged
  keep-ai-trailers: unchanged
  supervision-host-off: unchanged
  data/captain-shared.md: unchanged
secondmate local-old (~/.no-mistakes/evidence/01M49EBAM259QST2W72QEEJVGG/.ls):
  crew-dispatch.json: unchanged
  dispatch-never-send: unchanged
  crew-harness: unchanged
  backlog-backend: unchanged
  backend: unchanged
  herdr-presentation-spaces: unchanged
  trace-context: unchanged - session-scoped
  launch-env-allowlist: unchanged
  claude-permission-mode: unchanged
  claude-worker-settings.json: unchanged
  lavish-axi-host: unchanged
  keep-ai-trailers: unchanged
  supervision-host-off: unchanged
  data/captain-shared.md: unchanged

exit=0
PASS Config push neither lists nor creates the retired item; old secondary file untouched
$ bin/fm-stow-cascade.sh
role=primary

secondmate=local-old
placement=local
home=~/.no-mistakes/evidence/01M49EBAM259QST2W72QEEJVGG/.ls
transport=direct
reason=recorded endpoint has no target

secondmate=local-fresh
placement=local
home=~/.no-mistakes/evidence/01M49EBAM259QST2W72QEEJVGG/.lt
transport=direct
reason=recorded endpoint has no target

secondmates=2
exceptions=0

exit=0
PASS Local cascade reports both homes and direct transports without budget_report
$ bin/fm-stow-cascade.sh
role=primary

secondmate=local-old
placement=local
home=~/.no-mistakes/evidence/01M49EBAM259QST2W72QEEJVGG/.ls
transport=direct
reason=recorded endpoint has no target

secondmate=local-fresh
placement=local
home=~/.no-mistakes/evidence/01M49EBAM259QST2W72QEEJVGG/.lt
transport=direct
reason=recorded endpoint has no target

secondmate=remote-old
placement=remote
host=fm-lab-uncontacted
home=/disposable/old
transport=deferred
reason=no recorded endpoint and no remote memory write path

secondmates=3
exceptions=1

exit=3
PASS Unupdated remote without endpoint is deferred and does not prevent local resolution
$ tmux -L fm-lab new-session -d -s primary -x 120 -y 40 -c ~/.no-mistakes/worktrees/892c8faf04fc/01M49EBAM259QST2W72QEEJVGG -e FM_HOME=~/.no-mistakes/evidence/01M49EBAM259QST2W72QEEJVGG/.lp 'claude -p --permission-mode auto --no-session-persistence --setting-sources project --strict-mcp-config --disallowedTools Agent,Task,TaskCreate,TaskUpdate,TaskList,TaskGet --add-dir ~/.no-mistakes/evidence/01M49EBAM259QST2W72QEEJVGG/.lp --add-dir ~/.no-mistakes/evidence/01M49EBAM259QST2W72QEEJVGG/.ls --verbose --output-format stream-json '"'"'/stow This is a disposable lab primary with FM_HOME=~/.no-mistakes/evidence/01M49EBAM259QST2W72QEEJVGG/.lp. Curate only this home and its registered disposable local secondmate ~/.no-mistakes/evidence/01M49EBAM259QST2W72QEEJVGG/.ls. Use the tracked internal stow skill and its normal cascade. The existing private note data/lab-calibration.md already owns the LAB-CALIBRATION batch-trace investigation trigger; consider that live owner in your retention plan. LAB-OLD is closed. No independent current-session evidence confirms the completed old primary release or secondary incident. There are no open work records or uncaptured durable findings. Do not modify tracked source, any other home, credential stores, or tool configuration. Do not create/control pipelines, launch workers, or contact external services other than this harness model call. The registered remote has no endpoint and must stay untouched. All primary data lives under FM_HOME, not cwd data. Produce the normal completion receipt and finish.'"'"' > ~/.no-mistakes/evidence/01M49EBAM259QST2W72QEEJVGG/r2-stow-native.jsonl 2> ~/.no-mistakes/evidence/01M49EBAM259QST2W72QEEJVGG/r2-stow-native.stderr'

exit=0
PASS Normal signed-in Claude primary completes stow
PASS Stale aging and expired perishable entries recoverable with provenance
PASS Current fleet rule survives and duplicate is consolidated despite size limit 1
PASS Current conditional material relocates to existing private triggered owner
PASS Direct secondary cascade archives old ruling in its own cold tier
PASS Secondary shared input remains byte-identical
PASS Stow ignores legacy settings without changing either file
Disposable homes and private tmux server removed.
Evidence: Real Claude secondmate resolves to agent transport

Source: Real Claude secondmate resolves to agent transport

$ FM_HOME=<lab-primary> bin/fm-stow-cascade.sh
role=primary

secondmate=agent
placement=local
home=~/.no-mistakes/evidence/01M49EBAM259QST2W72QEEJVGG/.as
transport=agent

secondmates=1
exceptions=0

exit=0
Evidence: Native stow execution transcript

Source: Native stow execution transcript

Bash {"command": "cd ~/.no-mistakes/evidence/01M49EBAM259QST2W72QEEJVGG; for h in .lp .ls; do echo \"=== $h\"; find $h -maxdepth 3 -not -path '*/.git/*' | head -50; done; for f in .lp/data/*.md .ls/data/*.md; do echo \"----- $f\"; cat \"$f\"; done; ls .lp/config .ls/config 2>&1", "description": "Inspect lab primary and secondmate homes and memory files"}

=== .lp
.lp
.lp/state
.lp/tmux
.lp/.fm-lab-home
.lp/config
.lp/projects
.lp/data
.lp/state/.trace-context-effective
.lp/state/.lock
.lp/state/.inactive-outcome-reconcile
.lp/state/.startup-network.status
.lp/state/.startup-network.report
.lp/state/.lock-session
.lp/state/terminal-outcomes
.lp/state/.startup-network.timings
.lp/state/.session-start-complete
.lp/state/.guard-watcher-stale-banner
.lp/state/home-summary.json
.lp/state/.wake-queue
.lp/tmux/tmux-1000
.lp/config/supervision-host-off
.lp/config/startup-memory-budget
.lp/data/secondmates.md
.lp/data/captain-shared.md
.lp/data/captain.md
.lp/data/lab-calibration.md
.lp/data/learnings.md
.lp/tmux/tmux-1000/fm-lab
=== .ls
.ls
.ls/state
.ls/.fm-secondmate-home
.ls/.fm-lab-home
.ls/AGENTS.md
.ls/bin
.ls/config
.ls/projects
.ls/data
.ls/config/startup-memory-budget
.ls/data/captain-shared.md
.ls/data/learnings.md
----- .lp/data/captain-shared.md
# Shared captain
<!-- memory tiers: see the stow skill -->
- Report observed outcomes faithfully and disclose remaining gaps.
----- .lp/data/captain.md
# Captain
<!-- memory tiers: see the stow skill -->
- Never discard unlanded work without explicit authority.
----- .lp/data/lab-calibration.md
# Lab calibration owner
Read only when debugging LAB-CALIBRATION batch traces.
----- .lp/data/learnings.md
# Learnings
<!-- memory tiers: see the stow skill -->
- Fleet-wide dispatch must resolve the registered home before selecting its transport. <!--a:2026-10-06-->
- Fleet-wide dispatch must resolve the registered home before selecting its transport. <!--a:2026-10-06-->
- Completed lab release 0.0.1 used the superseded path /disposable/obsolete. <!--a:2026-01-01-->
- Temporary compatibility workaround for closed lab ticket LAB-OLD was retired when that ticket closed. <!--p:2026-01-01-->
- When debugging LAB-CALIBRATION batch traces, preserve the local batch identifier before replay, compare the stored sampling interval with the trace header, and inspect the recorded sequence before deciding whether to rebuild the lab sample. These checks belong to the calibration investigation only and are irrelevant to dispatch, session recovery, and every other fleet task. <!--a:2026-10-06-->
----- .lp/data/secondmates.md
- local-old - lab (home: ~/.no-mistakes/evidence/01M49EBAM259QST2W72QEEJVGG/.ls; scope: testing; projects: alpha; added 2026-10-06)
- remote-old - lab (host: fm-lab-uncontacted; root: /disposable/root; home: /disposable/old; scope: testing; projects: alpha; added 2026-10-06)
----- .ls/data/captain-shared.md
# Shared captain
<!-- memory tiers: see the stow skill -->
- Keep unresolved authority boundaries explicit.
----- .ls/data/learnings.md
# Learnings
<!-- memory tiers: see the stow skill -->
- Finished secondary incident used the superseded lab path /disposable/old-secondary. <!--a:2026-01-01-->
.lp/config:
startup-memory-budget
supervision-host-off

.ls/config:
startup-memory-budget
Shell cwd was reset to ~/.no-mistakes/worktrees/892c8faf04fc/01M49EBAM259QST2W72QEEJVGG

Bash {"command": "sed -n 1,80p bin/fm-stow-cascade.sh; cd ~/.no-mistakes/evidence/01M49EBAM259QST2W72QEEJVGG/.lp && git rev-parse --show-toplevel 2>&1; ls -la data; cat .fm-lab-home", "description": "Read cascade script header and check lab home git status"}

#!/usr/bin/env bash
# Enumerate this home's registered secondmates for an internal /stow cascade.
# Usage: fm-stow-cascade.sh [--help]
#
# The internal /stow skill owns curation judgement; this command owns only the
# mechanical inputs a cascade needs: which homes exist and how the sweep can
# reach each one.
#
# Enumeration comes from data/secondmates.md, the registry that already refuses
# a duplicate id, a duplicate home, and an overlapping home, so each registered
# secondmate is emitted exactly once.
#
# Each home is reported as one blank-line-separated key=value stanza:
#   secondmate=<id>
#   placement=local|remote            (host=<alias> on a remote route)
#   home=<path>
#   transport=agent|direct|deferred|unavailable
#   reason=<one line>                 (whenever a step did not complete)
#
# transport says how the sweep reaches that home:
#   agent     - a live secondmate agent owns the home; steer it with
#               bin/fm-send.sh so it sweeps its own uncaptured session
#               knowledge and replies through its marked return channel.
#   direct    - a local home with no live agent; curate its editable memory
#               files in place.
#   deferred  - a remote home with no live agent. There is deliberately no
#               generic remote write path (bin/fm-remote-file.sh put reaches
#               only the handoff outbox), so that home is curated by its next
#               cascade once its agent is back.
#   unavailable - the local home failed validation or the remote endpoint probe
#               failed, so no transport conclusion is safe.
#
# Every step that crosses a host runs under one hard bound (FM_STOW_CASCADE_TIMEOUT seconds, default 60), so a slow or
# unreachable home reports an exception and the sweep continues instead of
# blocking the primary's own /stow. A local endpoint probe reads this host's
# recorded backend in process, like every other caller of that contract.
#
# A secondmate home never cascades: secondmates do not own secondmates, so this
# command reports the empty cascade there rather than reaching for a registry.
#
# Exit status: 0 every home reported cleanly (or there were none); 3 at least
# one home reported an exception and every home was still reported; 1 the
# cascade input itself is unusable; 2 invalid use.
set -u

usage() {
  sed -n '2,43{s/^# \{0,1\}//;p;}' "$0"
}

case "${1:-}" in
  -h|--help) usage; exit 0 ;;
  "") ;;
  *) usage >&2; exit 2 ;;
esac
[ "$#" -le 1 ] || { usage >&2; exit 2; }

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
FM_ROOT="${FM_ROOT_OVERRIDE:-$(cd "$SCRIPT_DIR/.." && pwd)}"
FM_HOME="${FM_HOME:-${FM_ROOT_OVERRIDE:-$FM_ROOT}}"
DATA="${FM_DATA_OVERRIDE:-$FM_HOME/data}"
STATE="${FM_STATE_OVERRIDE:-$FM_HOME/state}"
REGISTRY="$DATA/secondmates.md"
SUB_HOME_MARKER="${SUB_HOME_MARKER:-.fm-secondmate-home}"

# shellcheck source=bin/fm-ff-lib.sh
. "$SCRIPT_DIR/fm-ff-lib.sh"
# shellcheck source=bin/fm-backend.sh
. "$SCRIPT_DIR/fm-backend.sh"
# shellcheck source=bin/fm-timeout-lib.sh
. "$SCRIPT_DIR/fm-timeout-lib.sh"

BOUND=${FM_STOW_CASCADE_TIMEOUT:-60}
case "$BOUND" in
  ''|*[!0-9]*) printf 'error: FM_STOW_CASCADE_TIMEOUT must be a positive integer: %s\n' "$BOUND" >&2; exit 2 ;;
esac
[ "$BOUND" -gt 0 ] \
  || { printf 'error: FM_STOW_CASCADE_TIMEOUT must be a positive integer: %s\n' "$BOUND" >&2; exit 2; }

die() { printf 'error: %s\n' "$1" >&2; exit 1; }
emit() { printf '%s\n' "$1"; }
fatal: not a git repository (or any of the parent directories): .git
total 28
drwxr-xr-x 2 tegris tegris 4096 Oct  6 14:02 .
drwxr-xr-x 7 tegris tegris 4096 Oct  6 14:02 ..
-rw-r--r-- 1 tegris tegris  126 Oct  6 14:02 captain-shared.md
-rw-r--r-- 1 tegris tegris  110 Oct  6 14:02 captain.md
-rw-r--r-- 1 tegris tegris   79 Oct  6 14:02 lab-calibration.md
-rw-r--r-- 1 tegris tegris  888 Oct  6 14:02 learnings.md
-rw-r--r-- 1 tegris tegris  287 Oct  6 14:02 secondmates.md
fm-lab-home v1

Bash {"command": "sed -n 80,260p ~/.no-mistakes/worktrees/892c8faf04fc/01M49EBAM259QST2W72QEEJVGG/bin/fm-stow-cascade.sh", "description": "Read remainder of cascade script"}

emit() { printf '%s\n' "$1"; }

TMP=$(mktemp -d "${TMPDIR:-/tmp}/fm-stow-cascade.XXXXXX") || exit 1
# shellcheck disable=SC2317,SC2329 # Invoked by the EXIT trap.
cleanup() { rm -rf -- "$TMP"; }
trap cleanup EXIT
STEP_OUT="$TMP/step.out"

# Run one bounded external step, capturing its stdout for the caller.
# Returns the step's own status, or 124 when the bound was hit.
run_step() {
  local rc

... [5913 bytes truncated] ...

ngs
<!-- memory tiers: see the stow skill -->
- Fleet-wide dispatch must resolve the registered home before selecting its transport. <!--a:2026-10-06-->
# Lab calibration owner
Read only when debugging LAB-CALIBRATION batch traces.
- When debugging LAB-CALIBRATION batch traces, preserve the local batch identifier before replay, compare the stored sampling interval with the trace header, and inspect the recorded sequence before deciding whether to rebuild the lab sample. These checks belong to the calibration investigation only and are irrelevant to dispatch, session recovery, and every other fleet task.

role=primary

secondmate=local-old
placement=local
home=~/.no-mistakes/evidence/01M49EBAM259QST2W72QEEJVGG/.ls
transport=direct
reason=no recorded endpoint for this home

secondmate=remote-old
placement=remote
host=fm-lab-uncontacted
home=/disposable/old
transport=deferred
reason=no recorded endpoint and no remote memory write path

secondmates=2
exceptions=1
exit=3

Local secondmate is curated directly; the remote one was deferred without any contact. Curating the secondmate's own learnings (its shared-captain file stays read-only):

Bash {"command": "cd ~/.no-mistakes/evidence/01M49EBAM259QST2W72QEEJVGG/.ls/data && ls; cat > memory-archive.md <<'EOF'\n# Memory archive\n\n## 2026-10-06 stow\n- (from learnings.md, tier: aging, reinforced: 2026-01-01) Finished secondary incident used the superseded lab path /disposable/old-secondary. [archived: unreinforced 278d]\nEOF\ncat > learnings.md <<'EOF'\n# Learnings\n<!-- memory tiers: see the stow skill -->\nEOF\ncat learnings.md memory-archive.md captain-shared.md", "description": "Archive stale secondmate learning entry"}

captain-shared.md
learnings.md
# Learnings
<!-- memory tiers: see the stow skill -->
# Memory archive

## 2026-10-06 stow
- (from learnings.md, tier: aging, reinforced: 2026-01-01) Finished secondary incident used the superseded lab path /disposable/old-secondary. [archived: unreinforced 278d]
# Shared captain
<!-- memory tiers: see the stow skill -->
- Keep unresolved authority boundaries explicit.

Captain, the memory cleanup is done for the lab main home and its local second mate. One exception is still open: the remote second mate could not be cleaned up from here, so the session is **not** safe to reset yet.

**Main home**
- **Captain preferences:** unchanged. The single entry is a standing preference and the header pointer is correct.
- **Shared captain preferences:** unchanged. The single entry is a standing preference and the header pointer is correct.
- **Learnings:** pruned, archived and offloaded. It went from five entries to one.
  - **Pruned:** a duplicate "resolve the registered home before selecting its transport" line. The identical copy stays, still current as of today.
  - **Archived:** "Completed lab release 0.0.1 used /disposable/obsolete". It had not been confirmed in 278 days and nothing this session confirmed it.
  - **Archived:** the retired LAB-OLD workaround. It had not been confirmed in 278 days and its expiry condition is met because LAB-OLD is closed.
  - **Offloaded:** the LAB-CALIBRATION batch-trace debugging procedure.
    - It only matters when debugging calibration traces, and it was the largest entry.
    - It now lives in the existing private calibration note `data/lab-calibration.md`.
    - That note is untracked because the home is not a git repository. I confirmed the full text is there before removing it from memory.
- **Archive file:** `data/memory-archive.md` was created, with the source, tier, last-confirmed date and reason for each archived entry.

**Local second mate (cleaned up from here, since no worker was attached to it)**
- **Captain preferences:** absent. Nothing was created.
- **Shared captain preferences:** unchanged. This copy is owned by the main home, the second mate cannot edit it, and its header pointer is already correct.
- **Learnings:** archived. "Finished secondary incident used /disposable/old-secondary" had not been confirmed in 278 days and nothing this session confirmed it. The file now holds only its header.
- **Archive file:** created in the second mate's own home.

**Open exception: the remote second mate**
- It has no recorded connection point, so it was skipped without being contacted.
- There is no remote way to edit its memory files. It will be cleaned up the next time this runs while its worker is reachable.
- Relaunching it would be a separate decision.

**Other results**
- No new durable findings, no proposed moves for permanent entries, and no work records changed. You said there were no open records, and I held none.
- Nothing outside these two homes was touched. That includes tracked code, other homes, credentials and tool settings, and no pipelines or workers were started.

**Reset safety:** nothing this session knew has been lost, but the session is not safe to reset while the remote second mate is still waiting for its cleanup. This only means nothing from this session was lost; it does not check whether the home's records are correct.

lanes working: 0 (this lab home has no task records)

FINAL RECEIPT
Captain, the memory cleanup is done for the lab main home and its local second mate. One exception is still open: the remote second mate could not be cleaned up from here, so the session is **not** safe to reset yet.

**Main home**
- **Captain preferences:** unchanged. The single entry is a standing preference and the header pointer is correct.
- **Shared captain preferences:** unchanged. The single entry is a standing preference and the header pointer is correct.
- **Learnings:** pruned, archived and offloaded. It went from five entries to one.
  - **Pruned:** a duplicate "resolve the registered home before selecting its transport" line. The identical copy stays, still current as of today.
  - **Archived:** "Completed lab release 0.0.1 used /disposable/obsolete". It had not been confirmed in 278 days and nothing this session confirmed it.
  - **Archived:** the retired LAB-OLD workaround. It had not been confirmed in 278 days and its expiry condition is met because LAB-OLD is closed.
  - **Offloaded:** the LAB-CALIBRATION batch-trace debugging procedure.
    - It only matters when debugging calibration traces, and it was the largest entry.
    - It now lives in the existing private calibration note `data/lab-calibration.md`.
    - That note is untracked because the home is not a git repository. I confirmed the full text is there before removing it from memory.
- **Archive file:** `data/memory-archive.md` was created, with the source, tier, last-confirmed date and reason for each archived entry.

**Local second mate (cleaned up from here, since no worker was attached to it)**
- **Captain preferences:** absent. Nothing was created.
- **Shared captain preferences:** unchanged. This copy is owned by the main home, the second mate cannot edit it, and its header pointer is already correct.
- **Learnings:** archived. "Finished secondary incident used /disposable/old-secondary" had not been confirmed in 278 days and nothing this session confirmed it. The file now holds only its header.
- **Archive file:** created in the second mate's own home.

**Open exception: the remote second mate**
- It has no recorded connection point, so it was skipped without being contacted.
- There is no remote way to edit its memory files. It will be cleaned up the next time this runs while its worker is reachable.
- Relaunching it would be a separate decision.

**Other results**
- No new durable findings, no proposed moves for permanent entries, and no work records changed. You said there were no open records, and I held none.
- Nothing outside these two homes was touched. That includes tracked code, other homes, credentials and tool settings, and no pipelines or workers were started.

**Reset safety:** nothing this session knew has been lost, but the session is not safe to reset while the remote second mate is still waiting for its cleanup. This only means nothing from this session was lost; it does not check whether the home's records are correct.

lanes working: 0 (this lab home has no task records)
Evidence: Persisted cold archive with provenance

Source: Persisted cold archive with provenance

# Memory archive

## 2026-10-06 stow
- (from learnings.md, tier: aging, reinforced: 2026-01-01) Completed lab release 0.0.1 used the superseded path /disposable/obsolete. [archived: unreinforced 278d]
- (from learnings.md, tier: perishable, reinforced: 2026-01-01) Temporary compatibility workaround for closed lab ticket LAB-OLD was retired when that ticket closed. [archived: unreinforced 278d; condition resolved - LAB-OLD closed]
Evidence: Persisted conditional knowledge in its existing owner

Source: Persisted conditional knowledge in its existing owner

# Lab calibration owner
Read only when debugging LAB-CALIBRATION batch traces.
- When debugging LAB-CALIBRATION batch traces, preserve the local batch identifier before replay, compare the stored sampling interval with the trace header, and inspect the recorded sequence before deciding whether to rebuild the lab sample. These checks belong to the calibration investigation only and are irrelevant to dispatch, session recovery, and every other fleet task.

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

🔧 **Review** - 1 issue found → auto-fixed ✅
  • ⚠️ .agents/skills/bootstrap-diagnostics/SKILL.md:38 - Spec: O6 requires diagnostics to "no longer describe the budget." The diff deletes the STARTUP_MEMORY_BUDGET bullet but leaves "Correct the local primary file, then rerun session start ... deliver the validated value to secondmate homes." This former budget remediation now belongs to the TANGLE bullet, incorrectly instructing agents handling a stranded branch to correct and propagate an unspecified file. Remove this orphaned sentence to complete the diagnostic removal.

🔧 Fix applied.
✅ Re-checked - no issues remain.

🔧 **Test** - 2 issues found → auto-fixed ✅
  • ⚠️ tests/fm-secondmate-harness.test.sh:2227 - The required secondmate test file failed intermittently: the initial target run reported incorrect original retry bytes, while its full rerun and six isolated retry runs passed. The base-commit test file also failed in a retry-generation assertion. This prevents reliable repeatable test acceptance; isolate the intermittent failure before approving the step. Root cause remains unconfirmed, so no speculative fix was applied.
  • 🚨 live validation verdict: no-go (7 of 7 scenarios were driven live against the product)
  • Live validation: ❌ no-go - 7 of 7 scenarios driven live against the product
Scenario Result Live Evidence
Bootstrap a fresh primary home without creating a budget setting or diagnostic ✅ pass live live-product.log: fresh-bootstrap
Restart a primary containing an invalid legacy setting and receive its digest without budget errors or setting changes ✅ pass live live-product.log: legacy-bootstrap and legacy-session-start
Propagate configuration to fresh and existing secondmates without inheriting or changing retired budget settings ✅ pass live live-product.log: config-push
Enumerate local and unavailable remote secondmates with routing facts, without budget reports ✅ pass live direct-cascade.txt and remote-deferred-cascade.txt
Invoke stow to archive stale aging and expired perishable rulings with provenance while retaining current memory ✅ pass live stow-native-receipt.md and stow-after/memory-archive.md
Invoke stow with a legacy budget of one to consolidate duplicates and curate a local secondmate while preserving shared-file ownership and the unresolved-exception guard ✅ pass live cascade-stow-native-transcript.txt and cascade-stow-native-receipt.md
Invoke stow to move current conditional knowledge into an existing private triggered owner without budget accounting ✅ pass live offload-stow-native-receipt.md and offload-stow-after-primary/lab-calibration.md
  • bash tests/fm-bootstrap.test.sh
  • bash tests/fm-stow-cascade.test.sh
  • bash tests/fm-secondmate-harness.test.sh twice: initial failure, full rerun exit 0
  • Six isolated executions of test_config_reread_write_failure_retains_exact_retry_generation
  • Focused execution of test_bootstrap_stops_when_data_disappears_before_reconciliation
  • Base-commit snapshot execution of tests/fm-secondmate-harness.test.sh: exit 1
  • python3 ~/.no-mistakes/evidence/01M49EBAM259QST2W72QEEJVGG/live-product.py
  • python3 ~/.no-mistakes/evidence/01M49EBAM259QST2W72QEEJVGG/cascade-stow-live.py
  • python3 ~/.no-mistakes/evidence/01M49EBAM259QST2W72QEEJVGG/offload-stow-live.py
  • Verified native receipts, persisted archives, retained current memory, shared-file byte preservation, and existing-owner offload
  • Manual removal-reference checks and confirmation that the recorded orphan sentence is absent
  • Verified disposable homes, private tmux servers, temporary test copies, and base snapshot were removed; worktree clean

🔧 Fix applied.
✅ Re-checked - no issues remain.

  • Live validation: ✅ go - 8 of 9 scenarios driven live against the product
Scenario Result Live Evidence
Bootstrap a fresh primary without creating a budget setting or diagnostic ✅ pass live r2-fresh-bootstrap.txt; r2-live-product.log
Restart a home with an invalid legacy setting and leave that file untouched ✅ pass live r2-legacy-bootstrap.txt; r2-legacy-session-start.txt
Push inherited configuration without listing or creating the retired setting ✅ pass live r2-config-push.txt; r2-live-product.log
Resolve direct, live-agent and deferred cascade routes with complete routing fields and no budget report ✅ pass live r2-local-cascade.txt; r2-deferred-cascade.txt; r2-agent-cascade.txt
Run stow to archive stale rulings with provenance and consolidate duplicates while retaining current memory despite a legacy limit of one ✅ pass live r2-stow-native-transcript.txt; r2-stow-after-primary/memory-archive.md; r2-behavior-checks.json
Offload current conditional knowledge to its existing private owner before removing it from startup memory ✅ pass live r2-stow-after-primary/lab-calibration.md; r2-behavior-checks.json
Cascade stow to a local secondmate, archive its old ruling and preserve its shared input byte-for-byte ✅ pass live r2-stow-native-transcript.txt; r2-stow-after-secondary/memory-archive.md; r2-behavior-checks.json
Receive a stow receipt without budget accounting or decisions that withholds reset safety while a remote exception remains ✅ pass live r2-stow-receipt.md; r2-native-receipt-checks.json; r2-stow-state-files.json
Retry a failed configuration instruction before delivering a newer generation when the clock moves backward ⏸️ untested no Attempted the real configuration-push executable against marked disposable homes and a private tmux endpoint, injecting an instruction-write failure and clock rollback. Its nested fm-send call supplie…
  • bash tests/fm-bootstrap.test.sh - passed.
  • bash tests/fm-secondmate-harness.test.sh - passed, including normal and backward-clock retry cases.
  • bash tests/fm-stow-cascade.test.sh - passed.
  • test_bootstrap_stops_when_data_disappears_before_reconciliation via a temporary focused runner - passed.
  • test_config_reread_write_failure_retains_exact_retry_generation backwards against a disposable base snapshot and the target - base failed on original-byte delivery; target passed.
  • python3 ~/.no-mistakes/evidence/01M49EBAM259QST2W72QEEJVGG/r2-live-product.py - drove real bootstrap, session start, configuration push, cascade and native Claude stow.
  • python3 ~/.no-mistakes/evidence/01M49EBAM259QST2W72QEEJVGG/r2-agent-cascade.py - verified cascade transport against a running Claude secondmate.
  • python3 ~/.no-mistakes/evidence/01M49EBAM259QST2W72QEEJVGG/r2-retry-live.py - attempted live retry delivery; nested lifecycle guard blocked it.
  • git grep -n -e startup-memory-budget -e STARTUP_MEMORY_BUDGET -e fm_startup_memory and git grep -n -i budget .agents/skills/stow/SKILL.md - both returned no matches, exit 1.
  • Inspected native receipts, executed commands, persisted archives, offload destination, shared-file preservation and absence of budget decisions.
  • Verified disposable homes, private tmux servers and temporary runners were removed; git status --short --untracked-files=all was empty.
✅ **Document** - passed

✅ No issues found.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

Test User added 5 commits October 6, 2026 13:26
Delete the startup-memory budget setting, its library and report command,
its bootstrap materialization and diagnostic, its secondmate inheritance,
and the stow cascade's per-home accounting. /stow keeps date-decay and
consolidation archival to data/memory-archive.md and no longer measures,
evicts, or opens decisions against a size budget.
…ide command substitution in tests/fm-secondmate-harness.test.sh with an equivalent suffix check. The behavior suite, focused ShellCheck, 474-file Bash 5.2 parse sweep, and diff check passed. Cursor coverage skipped because unavailable; native macOS Bash 3.2 verification remains outstanding
@ashkonmousavi
ashkonmousavi merged commit 197ec28 into main Oct 6, 2026
19 checks passed
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.

1 participant