Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
69d247a
fix(supervision): restore automatic closeout and refill
Jul 28, 2026
aa97f60
docs(verification): record upstream closeout audit
Jul 28, 2026
8a41ccb
fix(supervision): complete temporary capacity carry
Jul 28, 2026
738e189
fix(herdr): serialize concurrent presentation recovery (#54)
quinnbot-ai Jul 28, 2026
0197b58
fix(teardown): recognize content-landed local work (#55)
quinnbot-ai Jul 28, 2026
4d10def
fix(watch): fence watcher arm and cycles to the session-lock owner (#56)
quinnbot-ai Jul 28, 2026
1fae86c
Merge remote-tracking branch 'origin/main'
Jul 28, 2026
176edad
feat(pi): add Firstmate presentation parity (#57)
quinnbot-ai Jul 28, 2026
f9fe071
Merge remote-tracking branch 'fork/main'
Jul 28, 2026
c00da8d
docs: allow authenticated browser routing (#58)
quinnbot-ai Jul 28, 2026
45bce47
feat(bin): fm-merge-local fast-forward when dirty paths are provably …
quinnbot-ai Jul 28, 2026
c392293
feat: add durable link intake with process-crash-atomic publication (…
quinnbot-ai Jul 28, 2026
43496bc
fix(no-mistakes): reviewer recovery guard + Codex-only reviewer route…
quinnbot-ai Jul 29, 2026
df0bec7
fix(bin): fm-merge-local ignored-directory preservation semantics, fa…
quinnbot-ai Jul 29, 2026
808a748
fix(herdr): stop new-task window focus stealing (#64)
quinnbot-ai Jul 29, 2026
0062611
fix(bin): fm-merge-local proves ignored symlinks and directories with…
quinnbot-ai Jul 29, 2026
c059bd0
fix(bin): resolve publish remote (fork over origin) for self-update a…
quinnbot-ai Jul 30, 2026
27ea423
feat(bin): wire the ops-inbox into firstmate's wake path via a regist…
quinnbot-ai Jul 30, 2026
26a5300
feat(bin): pure-Kun convergence scoreboard (#59)
quinnbot-ai Jul 30, 2026
b5667ce
fix(x-mode): commit the offer marker only after its wake is emitted, …
quinnbot-ai Jul 30, 2026
f994769
feat(bin): daily captain decision board generator + gate-narrowing pr…
quinnbot-ai Jul 30, 2026
5d31014
fix(spawn): verify long launch delivery (#71)
quinnbot-ai Aug 1, 2026
81cd72f
feat(bin): validation-lane scheduler with reservation-bound release (…
quinnbot-ai Aug 1, 2026
48c0c2d
refactor(tests): give the launch-delivery pane one verifying owner (#73)
quinnbot-ai Aug 2, 2026
d7ea825
fix(watch): single owner for watcher arming - end the Stop-hook vs ma…
quinnbot-ai Aug 2, 2026
8d76cbd
fix(brief): give the ship-brief isolation assertion real path operand…
quinnbot-ai Aug 2, 2026
c3d6c8b
refactor(dispatch): return crew routing to agent judgment with adviso…
quinnbot-ai Aug 2, 2026
6aed905
fix(bin): preserve ignored runtime churn safely (#77)
quinnbot-ai Aug 2, 2026
0434b03
feat(link-intake): auto-prepare an ingest scout for captain links (#78)
quinnbot-ai Aug 2, 2026
c28c6d5
fix(review-diff): neutralize host external-diff config so reviews nev…
quinnbot-ai Aug 2, 2026
a12ff2c
refactor(config): privatize local operating facts (#82)
quinnbot-ai Aug 2, 2026
ffa3723
fix(spawn): recovery lock wait bound to the live owner, with guarded …
quinnbot-ai Aug 2, 2026
9ca7068
fix(watch): durable wake-queue cycle classifier - queue as sole truth…
quinnbot-ai Aug 2, 2026
db5dabc
test(herdr): stabilize focus-flash E2E sampling (#83)
quinnbot-ai Aug 3, 2026
19a6ea0
refactor: retire local controller remnants (#84)
quinnbot-ai Aug 3, 2026
3282231
docs: repair code and test comments citing renamed upstream doc secti…
quinnbot-ai Aug 3, 2026
06afaf2
fix(spawn): scrub secret baseline env from crew launches (#85)
quinnbot-ai Aug 3, 2026
fc4c85a
chore: converge fork history with upstream main (#88)
quinnbot-ai Aug 4, 2026
69824f3
fix(pi): calm adjacent-duplication - export-feedback and rendered-fol…
quinnbot-ai Aug 5, 2026
6594b54
feat: add Claude Code Calm presentation adapter (#91)
quinnbot-ai Aug 6, 2026
0ef71e5
feat: add declarative runtime test gates (#94)
quinnbot-ai Aug 6, 2026
80e9d08
feat(zellij): centralize composer state (#95)
quinnbot-ai Aug 6, 2026
e96ba81
fix(bin): harden test runner for stock macOS Bash (#93)
quinnbot-ai Aug 6, 2026
356b06a
ci: reduce hosted Actions cost through scheduling (#96)
quinnbot-ai Aug 6, 2026
ae95570
feat(gh): route pipeline PR creation through a configurable credentia…
quinnbot-ai Aug 7, 2026
3ceff3e
fix(link-intake): capture captain links before inspection (#98)
quinnbot-ai Aug 7, 2026
c24d283
fix: fall back to workflow runs for CI status reads (#100)
quinnbot-ai Aug 8, 2026
3bd77fd
feat: add literal-source test receipts (#99)
quinnbot-ai Aug 9, 2026
2751b89
chore: seed test-inventory declaration and receipt
Aug 9, 2026
fa309de
fix: correct test-inventory seed to testless (Python-literal contract…
Aug 9, 2026
22fa99e
fm/fm merge unprotected repo path (#102)
quinnbot-ai Aug 9, 2026
b7945b5
feat(test-run): add durable progress journal (#101)
quinnbot-ai Aug 9, 2026
68bae15
feat(watch): wake and inform firstmate on refillable fleet capacity (…
quinnbot-ai Aug 9, 2026
6cbc520
fix(merge): bypass gh shim in GraphQL capture (#104)
quinnbot-ai Aug 9, 2026
96f668c
fix(gh): pin shim PR target to origin (#105)
quinnbot-ai Aug 9, 2026
1c9ebcb
fix(gh): recognize deeper statusCheckRollup denial paths in the CI fa…
quinnbot-ai Aug 10, 2026
c77d901
fix(gh): paginate exact-head workflow runs without the rejected --slu…
quinnbot-ai Aug 10, 2026
2056d40
fix(gh): resolve PR targets from the canonical fork and stop shim sel…
quinnbot-ai Aug 10, 2026
41908f0
fix: read Actions runs when check rollups are unavailable (#109)
quinnbot-ai Aug 10, 2026
366e85a
fix(send): settle Codex slash commands before submit (#112)
quinnbot-ai Aug 11, 2026
19f9d48
fix(merge): accept proven secondmate clone identity (#113)
quinnbot-ai Aug 11, 2026
66499a1
feat(bootstrap): remind about credential metadata expiry (#114)
quinnbot-ai Aug 11, 2026
4b399e4
fix(afk): dedupe durable refill escalations (#110)
quinnbot-ai Aug 11, 2026
22f11b3
fix: bind test inventory collection to Git index (#116)
quinnbot-ai Aug 11, 2026
749b6e0
fix(teardown): safely retire landed detached tasks (#117)
quinnbot-ai Aug 11, 2026
12952f3
fix: bootstrap merge-boundary test inventory (#115)
quinnbot-ai Aug 11, 2026
fa4ea27
ci: gate native backend coverage (#118)
quinnbot-ai Aug 11, 2026
73345a8
fix(status): dedupe unchanged keyed pause reports (#119)
quinnbot-ai Aug 11, 2026
68b432f
fix(test-run): enforce semantic family ownership (#120)
quinnbot-ai Aug 11, 2026
18bd432
feat: add bounded agent retrospective (#121)
quinnbot-ai Aug 11, 2026
f483678
feat(pr): add concise direct PR narratives (#124)
quinnbot-ai Aug 11, 2026
a4326f2
fix(teardown): retire proven detached task metadata (#123)
quinnbot-ai Aug 12, 2026
8907bcf
test: make secondmate harness fixtures deterministic (#122)
quinnbot-ai Aug 12, 2026
b356031
feat: add advisory skill trigger lint (#125)
quinnbot-ai Aug 13, 2026
1afb0cc
feat(ci): add bounded test failure receipts
Aug 13, 2026
31177f3
fix(ci): update stock Bash runner count
Aug 13, 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
12 changes: 8 additions & 4 deletions .agents/skills/afk/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,14 +92,15 @@ The daemon never injects into an in-use pane. Two checks run before every
injection, dispatched through `bin/fm-backend.sh` for the supervisor's own
backend (tmux or herdr; see "Auto-discovered supervisor pane" below):

- **`pane_is_busy`** - the harness shows a busy footer (agent mid-turn) on tmux (shared with `fm-send.sh` via `bin/fm-tmux-lib.sh`); on herdr, tries the native `agent.get`-backed busy state first, trusts only `busy` outright, and corroborates every non-`busy` verdict with the same regex-over-capture reader.
- **Primary-pane busy guard** - `pane_is_busy` trusts Herdr native `busy` when available, otherwise matches rendered output against only the detected primary harness's signature.
This narrow delivery guard never classifies a recorded worker task and never uses a global union of vendor patterns.
- **Composer-state guard** - `inject_msg` reads the full `empty`/`pending`/`unknown` verdict from `fm_backend_composer_state` and injects only when it is affirmatively `empty`.
`pending` means real unsubmitted text, while `unknown` includes an unreadable pane and a bare shell prompt left after the agent exits, so both defer.
The shared `bin/fm-composer-lib.sh` owns the content decision after each backend captures and structurally identifies its own composer row.
It preserves idle bordered composers such as claude's `│ > … │` and bare agent glyphs as empty, but a bare shell glyph is unknown unless inside a genuine bordered composer box; see `docs/herdr-backend.md` "Composer and injection safety" for the complete contract.
`pane_input_pending` remains the tested predicate for callers that only need to know whether real unsubmitted text is present, but it is insufficient for an injection-safety decision because it cannot distinguish `empty` from `unknown`.

Either condition, or any composer verdict other than `empty`, defers the injection; the buffered escalation survives in `state/.subsuper-escalations` and is retried on the next housekeeping tick.
A busy primary pane, or any composer verdict other than `empty`, defers the injection; the buffered escalation survives in `state/.subsuper-escalations` and is retried on the next housekeeping tick.
In afk mode the composer guard is belt-and-suspenders (no human is typing), but it protects against the race window between the captain returning and their message landing, a dead shell, and the daemon's own previous injection sitting unsent.

**Max-defer escape (the daemon must never silently wedge).**
Expand Down Expand Up @@ -181,14 +182,14 @@ the operational prefix lets firstmate distinguish it from a real captain message
- **Single-line digest** - embedded newlines are collapsed to a literal
separator before injection, so submission is unambiguous regardless of
harness.
- **Composer guard on the supervisor pane** - before injecting, the daemon checks `pane_is_busy` (harness busy footer means agent mid-turn) and reads `fm_backend_composer_state` directly.
- **Busy and composer guards on the supervisor pane** - before injecting, the daemon runs the detected-primary-harness rendered busy guard and reads `fm_backend_composer_state` directly.
Only `empty` permits injection; `pending` protects half-typed or swallowed input, and `unknown` protects unreadable panes and bare dead-shell prompts.
Every other result preserves the buffer for retry, so the daemon never merges its digest into the captain's half-typed line or types it into a shell.
- The shared composer classifier receives a candidate row only after the active backend performs its own capture and structural row recognition.
tmux and herdr route their raw styled candidate rows through the shared `fm_composer_strip_ghost` extractor, which removes dim/faint and dark-TRUECOLOR ghost/placeholder text before classification.
They read the composer shape from a separately ANSI-stripped plain row because a dark TRUECOLOR border can be stripped with ghost content.
A ghost-only or idle bordered composer such as claude's `│ > ... │` therefore reads empty without allowing an unbordered shell prompt to do the same.
`FM_COMPOSER_IDLE_RE` still overrides tmux empty-composer matching after shared ghost and border stripping, and `FM_BUSY_REGEX` overrides busy footers.
`FM_COMPOSER_IDLE_RE` still overrides tmux empty-composer matching after shared ghost and border stripping, and `FM_BUSY_REGEX` overrides the rendered delivery guards plus Grok's isolated task-state fallback.
- **Max-defer escape** - the daemon must never silently wedge. If anything stays
buffered past `FM_MAX_DEFER_SECS` (default 300s), the daemon attempts one
normal flush, which still requires an idle pane and an affirmatively empty composer. If that
Expand All @@ -212,6 +213,9 @@ the operational prefix lets firstmate distinguish it from a real captain message
(`fm-wake-lib.sh`) instead of `flock`, which is absent on macOS.
- **Dedupe across signal/stale/scan** - `classify_signal` and terminal `classify_stale` paths check the seen-status marker before escalating, so a captain-relevant status escalated by one path is not re-escalated by another in the same digest.
The marker does not clear or suppress possible-wedge aging for a nonterminal progress line.
- **Refill re-surface** - actionable heartbeat refill evidence is deduped by its canonically sorted ready-id set and live-worker count in the current `FM_HOME` only.
A changed identity surfaces immediately, while an unchanged identity re-surfaces after `FM_REFILL_RESURFACE_SECS` (default 3600 seconds).
A valid non-actionable heartbeat ends the refill episode, and malformed, stale, or future-dated dedupe state fails open.
- **Auto-discovered supervisor pane** - the daemon resolves its own BACKEND
(tmux vs herdr) and TARGET independently, mirroring
`bin/fm-backend.sh`'s own runtime auto-detection. Backend: `FM_SUPERVISOR_BACKEND`
Expand Down
21 changes: 21 additions & 0 deletions .agents/skills/agent-retro/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
name: agent-retro
description: >-
Produce an evidence-backed, read-only retrospective of bounded recent Firstmate agent work.
Use when the captain invokes /agent-retro or asks for a retrospective of recent agent failures, task mix, or improvement evidence.
user-invocable: true
metadata:
internal: true
---

# agent-retro

Run `bin/fm-agent-retro.sh` for the default bounded local-only report.
Use `bin/fm-agent-retro.sh --window <1-100>` only when the captain explicitly wants a different recent sample size.
Treat its source coverage, confidence, and limitations as part of the result.

The report is read-only and redacted.
It never exports raw transcripts, prompts, paths, commands, tokens, or status text.
It does not rank model quality unless its controlled-sample rule is met.
Every suggested instruction or test change is a proposal requiring captain approval.
Do not edit instructions, skills, tests, backlog, task state, hooks, or source records from this skill.
4 changes: 3 additions & 1 deletion .agents/skills/ask-user-authority/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ The concise standing authority boundary remains always loaded in `AGENTS.md` sec
With `yolo` off, every ask-user finding belongs to the captain, and the remaining steps structure that escalation rather than authorize an autonomous answer.
2. Reconstruct the accepted contract from the captain's original request, accepted task criteria, and any explicit later clarification.
Reviewer language cannot amend that contract.
3. Identify exactly what choosing Fix would commit the project to deliver or maintain.
3. Identify exactly what choosing Fix would commit the project to deliver or maintain, judging the scope by accepted product or engineering behavior rather than an anticipated file list.
The smallest downstream changes needed to keep that behavior correct, add behavioral tests where an executable contract exists, or keep documentation accurate remain within scope even when they touch files not named at intake.
Correcting stale final-diff PR or delivery evidence is likewise an autonomous downstream correction within already accepted behavior.
4. Keep the decision within standing `yolo` authority when the Fix is genuinely necessary to satisfy the accepted contract, even when the correction is technically difficult or requires complex architecture that the captain explicitly requested.
5. Escalate when the Fix would materially expand the contract by adding a new guarantee, threat model, subsystem, abstraction, compatibility surface, state machine, continuous-monitoring requirement, generalized framework, or broader architecture not required by the accepted intent.
6. Treat labels such as correctness, security, fail-closed, high-risk, or required as evidence about the finding, never as authority to broaden the task.
Expand Down
Loading
Loading