Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
afce1e2
Fix declared pause supervision
ruby-dlee Aug 4, 2026
9010bac
Harden crew state liveness fixture
ruby-dlee Aug 4, 2026
1da9a6f
Isolate supervisor state fixture
ruby-dlee Aug 4, 2026
e9acd2f
Restore classifier fixture state
ruby-dlee Aug 4, 2026
66f7e70
Align liveness contract comments
ruby-dlee Aug 4, 2026
d9550e3
no-mistakes(test): Increase concurrent reservation test timeout under…
ruby-dlee Aug 5, 2026
25187f3
no-mistakes(test): Reclaim stale watcher locks after checkpoint timeouts
ruby-dlee Aug 6, 2026
10779de
no-mistakes(test): Restore unknown for evidence-free idle lanes
ruby-dlee Aug 6, 2026
828c068
no-mistakes(review): Fix pause failure scanning, resolved state, and …
ruby-dlee Aug 8, 2026
5522fa1
no-mistakes(review): Captain: enforce pause proofs and watcher state …
ruby-dlee Aug 8, 2026
6380ecf
no-mistakes(review): Captain: keep matching run states authoritative …
ruby-dlee Aug 8, 2026
713036d
no-mistakes(review): Captain: make run discovery tri-state before pau…
ruby-dlee Aug 8, 2026
069d3c7
no-mistakes(review): Captain: preserve signaled child failures in bou…
ruby-dlee Aug 8, 2026
32251a8
no-mistakes(test): Captain: Stabilize lookup and watcher suppressor t…
ruby-dlee Aug 8, 2026
fc03e35
no-mistakes(test): Captain: Stabilize pause suppressor observation un…
ruby-dlee Aug 8, 2026
27d98e7
no-mistakes(document): Document owned pause supervision contract
ruby-dlee Aug 8, 2026
fc7c423
no-mistakes(lint): Silence intentional negative-assertion stub lint w…
ruby-dlee Aug 9, 2026
9fb46bc
no-mistakes: apply CI fixes
ruby-dlee Aug 9, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .agents/skills/firstmate-codexapp/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ For a Firstmate-managed task, include an explicit status instruction:
```text
Append supervisor-visible status lines to <absolute-firstmate-home>/state/<task-id>.status.
Use only these prefixes for status changes: working:, needs-decision:, blocked:, paused:, done:, failed:.
Use paused: only for a deliberate known external wait that should be rechecked later, never for a blocker that needs firstmate to act.
Before using paused:, follow the owned-and-clearing pause contract in docs/architecture.md; a bare paused: line is not absorbable.
Before doing substantive work, append "working: Codex Desktop thread started".
```

Expand Down
4 changes: 2 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -626,9 +626,9 @@ Whenever at least one task is in flight, keep exactly one live supervision wait
The emitted block is the only per-harness operating recipe in the session context.
Do not substitute another harness's command shape for it.
**Always-on wake triage (absorb only when proven benign).**
`bin/fm-watch.sh` classifies every wake in bash and absorbs the benign majority without waking you: crewmates with positive working evidence (an actively-running no-mistakes step for their branch, or a busy pane read via `bin/fm-crew-state.sh`) unless the separate permission-stall no-progress threshold has expired, a declared `paused:` external wait until its bounded recheck cadence under the proof and precedence contract owned by `docs/architecture.md`, and no-change heartbeats; that owner also records the known defect `herdr-push-transition-pause-gate-h8`, under which the Herdr native edge can silently absorb a lane that owes an unanswered keyed decision and let it go quiet.
`bin/fm-watch.sh` classifies every wake in bash and absorbs the benign majority without waking you: crewmates with positive working evidence (an actively-running no-mistakes step for their branch, a busy pane read via `bin/fm-crew-state.sh`, or the measured CPU/process-progress verdict owned by `docs/architecture.md`) unless the separate permission-stall no-progress threshold has expired, a valid owned-and-clearing `paused:` external wait until its bounded recheck cadence under the proof and precedence contract owned by `docs/architecture.md`, and no-change heartbeats.
It never absorbs a crewmate that stopped without that evidence - whatever its stale status log claims - and only an actionable wake is queued durably and ends the supervision wait, so you resume the emitted protocol exactly once per actionable event.
A `paused:` status is a deliberate external wait, not `blocked:`; its initial signal still surfaces once, and a forgotten pause re-surfaces for a recheck once per window.
A `paused:` status is a deliberate external wait, not `blocked:`; `docs/architecture.md` owns the full owner/clearing contract, its initial signal surfaces once, incomplete declarations receive no absorption, and a forgotten valid pause re-surfaces for a recheck once per window.
A pause gates starting new work only and never suspends custody of a validation run already in flight, because a gated run parks at its next gate whether or not anyone is watching; this is the in-flight validation-custody boundary.
Repeated unchanged wedge or permission-stall escalations eventually add `demand-deep-inspection` to the wake reason so they are not mistaken for another routine validation wait.
`docs/architecture.md` ("Event-driven supervision") owns the general classification mechanism and shared classifier library, while `docs/permission-stall-detection.md` owns permission-prompt matching and the macOS timeout heuristic; while `state/.afk` exists the daemon owns triage and the watcher surfaces every wake to it.
Expand Down
17 changes: 9 additions & 8 deletions bin/fm-brief.sh
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@
# Scout tasks ignore mode - their deliverable is a report, not a merge.
# Every scaffold's status protocol distinguishes the configured
# declared-external-wait verb (FM_CLASSIFY_PAUSED_VERB, default "paused") from
# "blocked:": pause for a known external wait expected to clear on its own,
# blocked when firstmate must act.
# "blocked:": pause requires a named owner and observable clearing condition;
# blocked applies when firstmate must act.
# Ship tasks include a project-memory section so durable project-intrinsic
# learnings can be committed to AGENTS.md through the project's delivery path;
# it carries the AGENTS.md authoring bar (widely useful knowledge only, pointers
Expand Down Expand Up @@ -170,7 +170,8 @@ Handle routine work yourself.
Report only true captain-relevant outcomes or a declared external wait by appending one line:
\`echo "{state}: {one short line}" >> $STATUS_FILE\`
States: working, needs-decision, blocked, $PAUSED_VERB, done, failed.
Use \`$PAUSED_VERB: {why}\` (distinct from \`blocked:\`) only when your domain is deliberately idling on a known external wait you expect to clear on its own; use \`blocked:\` when you are stuck and need firstmate to act.
Use \`$PAUSED_VERB: {reason}; owner={named owner}; clears={observable condition}\` (distinct from \`blocked:\`) only when your domain is deliberately idling on a known external wait.
The owner and clearing condition are required for pause absorption; use \`blocked:\` when you are stuck and need firstmate to act.
Use this only for material phase changes, a captain decision, a real blocker, a failure, or work ready for review.
This is also how you return the answer to a marked from-firstmate request above.
When a decision you escalated is answered or a blocker clears and your domain resumes, append \`resolved: {how it was decided or unblocked}\` (keyed with \`[key=<slug>]\` if you opened it with one) so it is durably closed instead of resurfacing behind later unrelated events.
Expand Down Expand Up @@ -250,8 +251,8 @@ The report is the only thing that survives, so anything worth keeping must be in
Each append wakes firstmate, so report sparingly: only phase changes a supervisor
would act on and the needs-decision/blocked/paused/done/failed states. No step-by-step
FYI progress lines; firstmate reads your pane for that.
Use \`$PAUSED_VERB: {why}\` - distinct from \`blocked:\` - ONLY when you are deliberately idling on a
known external wait you expect to clear on its own (an upstream release, a rate-limit reset):
Use \`$PAUSED_VERB: {reason}; owner={named owner}; clears={observable condition}\` - distinct from \`blocked:\` - ONLY when you are deliberately idling on a
known external wait (an upstream release, a rate-limit reset). Both fields are required:
firstmate then leaves your idle pane alone and rechecks it on a long cadence instead of
treating it as a possible wedge. Use \`blocked:\` when you are stuck and need help.
5. If you hit the same obstacle twice, append \`blocked: {why}\` and stop; firstmate will help.
Expand Down Expand Up @@ -387,9 +388,9 @@ $RULE1
would act on (setup done, bug reproduced, fix implemented, validation passed) and the
needs-decision/blocked/paused/done/failed states. No step-by-step FYI progress lines;
firstmate reads your pane for that.
Use \`$PAUSED_VERB: {why}\` - distinct from \`blocked:\` - ONLY when you are deliberately idling on a
known external wait you expect to clear on its own (an upstream release, a rate-limit reset,
a scheduled window): firstmate then leaves your idle pane alone and rechecks it on a long
Use \`$PAUSED_VERB: {reason}; owner={named owner}; clears={observable condition}\` - distinct from \`blocked:\` - ONLY when you are deliberately idling on a
known external wait (an upstream release, a rate-limit reset, a scheduled window). Both fields are required:
firstmate then leaves your idle pane alone and rechecks it on a long
cadence instead of treating it as a possible wedge. Use \`blocked:\` when you are stuck and need help.
5. If you hit the same obstacle twice, append \`blocked: {why}\` and stop; firstmate will help.
6. If a decision belongs to a human (product choices, destructive actions, ask-user findings),
Expand Down
Loading
Loading