Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
b96dba1
fix(bearings): restore decision options and add close controls (#2707)
kunchenguid Aug 21, 2026
a0cec26
ci: require no-mistakes pipeline step attestation (#2710)
kunchenguid Aug 21, 2026
99b21d8
feat: collapse decisions into tasks held for the captain (#2728)
kunchenguid Aug 21, 2026
3f03533
fix: bound recovery announcements and preserve supervision (#2733)
kunchenguid Aug 21, 2026
d3342dc
fix(bin): surface captain-call record divergence (#2744)
mremond Aug 21, 2026
4d2cb0c
fix(bin): re-arm after an abandoned auto-arm claim and defer a wedge …
Inthuson Aug 21, 2026
3d125ad
fix(bin): give a captain hold the same bounded pause cadence as a dec…
Inthuson Aug 21, 2026
738460d
fix(bin): make lint prerequisites and harness tests reliable (#2758)
kunchenguid Aug 21, 2026
59e7393
feat(bin): report watched tooling updates that are available or insta…
Inthuson Aug 21, 2026
52d20f1
fix: decouple ask-user decisions from yolo (#2764)
kunchenguid Aug 22, 2026
fbe37e9
feat(bin): add a spoken interface that answers from records and hands…
Inthuson Aug 22, 2026
dc0172c
fix(bin): preserve Relay follow-up loops until explicit disposition (…
kunchenguid Aug 22, 2026
5b6d0fb
feat(bin): merge GitLab merge requests through the guarded PR merge p…
Inthuson Aug 22, 2026
1231b6a
fix(bin): record a lost relay connection instead of an unanswered tur…
Inthuson Aug 22, 2026
8714c9a
fix(composer): stop a blocked pi pane from proving an empty composer …
karotkriss Aug 23, 2026
801c083
fix(bin): require project clone roots during fleet sync (#2849)
karotkriss Aug 23, 2026
505c819
fix(bin): retry transient Lavish poll interruptions (#2846)
karotkriss Aug 23, 2026
86dd2f6
fix(brief): stop the documented {TASK} fill from corrupting the Herdr…
karotkriss Aug 23, 2026
266fdb9
fix(bin): resolve the busy-state lock mtime with the platform's own s…
karotkriss Aug 23, 2026
f170ced
fix(stow): add opt-in pass horizon for memory decay (#2850)
karotkriss Aug 23, 2026
2f250c7
test(watcher): stop fixture confirmation budgets racing real child st…
karotkriss Aug 23, 2026
197afbb
fix(bin): deterministically order remote tool paths (#2870)
karotkriss Aug 23, 2026
52f62ab
fix(bin): prevent routed secondmate work from stranding (#2848)
kunchenguid Aug 23, 2026
822a990
fix: make macOS inbox test path portable (#2857)
kunchenguid Aug 23, 2026
e46df1a
feat(bin): deliver local steers through durable task inboxes (#2856)
kunchenguid Aug 23, 2026
8d8362c
feat(bin): add fast local lint mode (#2891)
kunchenguid Aug 23, 2026
ddf74ef
feat(bin): deliver remote steers through durable inboxes (#2901)
kunchenguid Aug 23, 2026
7b88520
feat: add persistent Pi supervision branch (#2858)
kunchenguid Aug 23, 2026
fb2ce5b
fix(bin): parallelize startup network sweeps (#2927)
kunchenguid Aug 24, 2026
8b21c99
test: handle absent watcher wake queues (#2845)
karotkriss Aug 24, 2026
52ff62e
style(pi): distinguish routine and captain supervision merge notes by…
kunchenguid Aug 24, 2026
d55e00a
docs(pi): add the approved multi-brain architecture poster (#2938)
kunchenguid Aug 24, 2026
8fa0505
feat(pi): default branch supervision and route heartbeats (#2939)
kunchenguid Aug 24, 2026
038d0f7
fix(bin): bound remote job worker supervisor restarts (#2942)
stanzhang Aug 24, 2026
85d6c72
fix: safely split supervision wake handling by actor (#2953)
kunchenguid Aug 25, 2026
6a2cd6c
fix(pi): hide branch outcomes tool rows in Calm (#3024)
kunchenguid Aug 25, 2026
3e5577b
fix: bind no-mistakes attestations to PR head (#3027)
kunchenguid Aug 25, 2026
9a01dea
feat(pi): add persistent supervision branch model selection (#3028)
kunchenguid Aug 25, 2026
f7a387f
feat(pi): let /supervision-model pick branch reasoning effort (#3079)
kunchenguid Aug 26, 2026
07bf0c8
fix: keep routine supervision noise out of captain chat (#3093)
kunchenguid Aug 26, 2026
9ce69ac
fix(bin): stop a correlation token from hiding and stranding decision…
mremond Aug 26, 2026
b0ca8f5
fix(bin): Cursor-Park unter Pi-Host ohne Cursor-Identität stilllegen …
thelad-dev Aug 26, 2026
5aed873
fix(pi): make supervision model picker searchable and scrollable (#3099)
kunchenguid Aug 26, 2026
662a8c7
fix(bin): durably report merged pull requests (#3104)
kunchenguid Aug 26, 2026
60bedde
fix(bearings): preserve projections through inventory mismatches (#3129)
kunchenguid Aug 26, 2026
22fa6ed
fix(bin): reconcile markerless remote secondmates safely (#3140)
kunchenguid Aug 27, 2026
99c1a0d
fix(bin): hand a busy declared pause to the away-mode daemon once, un…
3264studios Aug 27, 2026
524994c
fix(bin): name the stale submodule pin behind a pooled slot refusal (…
mkurt Aug 27, 2026
d63b0e2
fix(pi): prevent stale captain outcome re-emissions (#3154)
kunchenguid Aug 27, 2026
aa35fc4
fix(watch): hold the declared-wait cadence across pane churn (#67)
withally Aug 22, 2026
f90dccc
fix(remote): complete already-retired secondmate teardown (#68)
withally Aug 24, 2026
8bb308f
fix(teardown): keep remote retirement working with unrelated pending …
withally Aug 24, 2026
855c482
feat(bin): add durable host resource telemetry recorder (#70)
withally Aug 24, 2026
f52247f
fix(lock): bound stale lock recovery with a non-recursive steal mutex…
withally Aug 24, 2026
1619c1a
fix(bin): keep remote home seeding portable on Bash 3.2 and fail clos…
withally Aug 24, 2026
48d062a
feat(bin): add fseventsd footprint early warning to the fleet watcher…
withally Aug 24, 2026
2bdedae
fix(spawn): set PI_CLEAR_ON_SHRINK=1 for Firstmate-launched Pi sessio…
withally Aug 25, 2026
570f7b5
docs: record upstream sync procedure and cutover
withally Aug 27, 2026
161a5ad
fix: harden upstream cutover validation
withally Aug 27, 2026
f4ab005
chore: record origin/main as reconciled by the 2026-08-27 upstream cu…
withally Aug 27, 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
4 changes: 1 addition & 3 deletions .agents/skills/afk/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,7 @@ For tmux that confirmation is normally a proven cleared composer from the shared
Without that baseline, busy state never converts an `unknown` composer into confirmation.
For herdr, idle-baseline submits first seek native agent-state showing a real turn started, then use the shared classifier when native state remains idle: a cleared composer confirms delivery, while pending text retries Enter and reaches the shared busy-queue verdict only after the retry budget.
A bordered-empty or ghost-only composer is recognized as empty where that backend uses composer confirmation, rather than mistaken for a swallowed Enter.
`fm-send.sh` uses the same primitive and exits non-zero
when a steer's Enter is positively swallowed, so firstmate learns an instruction
did not land instead of leaving it unsubmitted.
`fm-send.sh` uses the same primitive only on its typed plane and exits non-zero when that plane's Enter is positively swallowed; ordinary local text steers use the durable inbox and do not treat doorbell submission as delivery proof.

**Busy-queued Enter exception (opencode 1.18.4).** OpenCode keeps queued text visible while it is mid-turn, so tmux and herdr delegate the final delivery decision to `fm_composer_queued_enter_verdict` in `bin/fm-composer-lib.sh` rather than treating visible text alone as a swallowed Enter.
The daemon still clears its buffer only on the backend's `empty` success verdict; [`docs/tmux-backend.md`](../../../docs/tmux-backend.md) and [`docs/herdr-backend.md`](../../../docs/herdr-backend.md) own the backend-specific confirmation signals.
Expand Down
29 changes: 20 additions & 9 deletions .agents/skills/bearings/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ Generate a complete current snapshot from the fleet's current state, so the capt
Plain `/bearings` returns only the concise four-section chat digest.
Only `/bearings file` writes the dated markdown report artifact and then returns the concise four-section chat digest linked to that report.
Only `/bearings lavish` builds the interactive fleet board beside that digest, through `bin/fm-bearings-board.sh` (its header owns every board mechanic and the fm-bearings-board.v1 payload contract).
A digest/build invocation is operationally read-only apart from those explicit per-mode artifacts: the dated report in file mode, and in lavish mode the board file plus the answer binding and source registration that `bin/fm-bearings-board.sh build` records through their own owners.
During that invocation it never tears down a task, merges a PR, dispatches new work, steers a worker, answers a decision, cleans up work, or mutates backlog or task state.
A digest/build invocation is operationally read-only apart from the cooldown-limited reconcile instruction and its `state/<id>.reconcile-nudged` record, plus the explicit per-mode artifacts: the dated report in file mode, and in lavish mode the board file plus the answer binding and source registration that `bin/fm-bearings-board.sh build` records through their own owners.
During that invocation it never tears down a task, merges a PR, dispatches new work, steers a worker except through that reconcile hook, answers a decision, cleans up work, or mutates backlog or task state beyond the reconcile record.
Board answers are acted on later under the normal authority rules; this skill's board-wake section explicitly owns the guarded routing at that time.

## Invocation modes
Expand All @@ -34,8 +34,8 @@ Board answers are acted on later under the normal authority rules; this skill's
## What it does

1. **Gather live fleet state with one deterministic command.**
Run `bin/fm-bearings-snapshot.sh` at invocation time and read its compact output.
It is the single bounded, deterministic fleet-state source for Bearings and renders TOON by default.
Run `snapshot=$(bin/fm-bearings-snapshot.sh --json)` at invocation time and read that compact output.
It is the single bounded, deterministic fleet-state source for Bearings.
Do not create or consult a second fleet-state reader, parser contract, status-event-tail interpretation, visible-session recap, ad-hoc project probe, or ad-hoc `gh-axi`/`gh` query.
The command's header and `--help` output own its exact fields, bounds, opt-ins, and output contract.
Keep the default local-only read unless the captain asks to include PRs.
Expand All @@ -48,13 +48,22 @@ Board answers are acted on later under the normal authority rules; this skill's
Until then it stays queued with the reason.
The `(main-inventory)` gate is an action-free integrity warning rather than queued work.
Render it under Charted Next with the related `omitted` disclosure, never invent an Underway row from backlog-only state, and never move it into Captain's Call.
The same holds for a secondmate home whose current state is unavailable, and for a readable home whose `invalidity` reports a backlog-vs-metadata mismatch: the mismatch is a repair notice about that home's own books, not a reason to drop its separately projected decisions, queued, landed, or live work.

2. **Compose the four-section chat digest from the fresh snapshot.**
2. **Ask any home whose own books disagree to reconcile them.**
When the snapshot reports a secondmate home whose `invalidity` is `orphan_in_flight`, `unowned_current`, or `terminal_in_flight`, that home's backlog and its own task metadata disagree and only that home may fix it.
Run `printf '%s\n' "$snapshot" | bin/fm-secondmate-reconcile.sh notify --snapshot -` inline immediately after gathering the snapshot, so the durable fire-and-forget enqueue finishes before digest composition without spawning any child or second snapshot.
The script header owns the cooldown window, non-blocking lock skips, stale-endpoint checks, retry, and fire-and-forget delivery contract; this hook arms no reply recovery or inbox escalation.
If the hook reports a skip or failure, continue composing the digest from the captured snapshot; a lock skip or known-undelivered send leaves the cooldown unset for a later recap.
A home is asked at most once per four-hour window, so running this on every recap costs nothing and cannot nag, while a mismatch still sitting there after the window earns one gentle re-nudge.
Never edit another home's backlog or metadata from here, and never expect or wait on a reply: the mate acts asynchronously from its durable inbox while the digest is composed from the snapshot already in hand.

3. **Compose the four-section chat digest from the fresh snapshot.**
The gather step is deterministic; your judgment is scoped to ranking the command's facts by what matters right now and writing scannable captain-facing prose.
The chat response uses the four complete sections in the chat-response contract below, in the same order, each always present.
Plain mode stops here and writes no report artifact.

3. **In explicit file mode only, compose and replace the detailed report file.**
4. **In explicit file mode only, compose and replace the detailed report file.**
The report uses the same four complete sections as the chat, in the same order, and adds the detail the chat omits.
Never read an earlier `data/status-report-*.md` to decide what to omit, include, describe as changed, or call current.
Write the full report to `data/status-report-<YYYY-MM-DD>.md` using today's date.
Expand All @@ -81,6 +90,8 @@ Compose the payload from the same snapshot with the same ranking judgment as the
- Decision cards carry agent-authored copy: a short noun-phrase title, one-line `about` and `decide` context rows, and option labels with hints, with the recommended option marked.
- Card `type` (decision, merge, credential) is your composing judgment from the row's content; no backlog field types a card for you.
- When the card's task is a captain-gated WORK item (the answer should free it to proceed rather than complete it), set the card's `close: "release"` so the answer lifts the hold instead of closing the task; question-shaped items omit it.
- A Charted Next row's optional `kind` separates work from alarms: omit it (or set `"queued"`) for real queued work, and set `"warning"` on every action-free fleet-integrity notice - the `(main-inventory)` gate, an unavailable secondmate home, and an inventory-mismatch repair notice. The board badges a warning row `needs repair` instead of `waiting` and leaves it out of the Charted Next count, so those rows never read as dispatchable queued work.
- `charted_more` counts omitted queued rows only, while `charted_warning_more` counts omitted warning rows only; keep both counts separate whenever the board payload truncates Charted Next.
- Every Captain's Call item and every Underway, Recently Landed, and Charted Next row carries an explicit `repo` field. Fill it from the snapshot and task records wherever known; use null or an empty string only as the deliberate genuinely-no-repo marker, in which case the template may show the internal id. Ids otherwise stay in the payload only as the routing channel, and composed reasons name blockers in plain words.

Run `build` once after composing the payload.
Expand Down Expand Up @@ -127,7 +138,7 @@ Rules that keep the contract unambiguous:
- The four buckets are mutually exclusive, so every item is forced into exactly one: needs-your-action is Captain's Call, done is Recently Landed, self-progressing is Underway, and not-yet-started work or an action-free fleet-integrity warning is Charted Next.
- The strict boundary keeps action-free items OUT of Captain's Call: a working or validating task, a queued item blocked on another task or a date, landed work, a completed scout's report pointer, a declared `paused:` external wait, and a bare recorded PR with no merge-ready signal each belong to one of the other three sections, never Captain's Call.
- A secondmate's own row appears Underway only for `active_child_work`; `externally_held` belongs in Charted Next, and `unknown` belongs there as an unavailable-state gate unless its reason requires the captain's action.
- Do not suppress separately projected decisions, landed records, or gates from a `partial-structured` home merely because that secondmate's own row is `unknown`.
- Do not suppress separately projected decisions, landed records, or gates from a `partial-structured` home merely because that secondmate's own row is `unknown` or its `invalidity` reports an inventory mismatch.
- Include the required direct address to the captain inside one item or empty-state sentence.
- Every PR appears as the full `https://...` URL; a shorthand `#number` is fine only as a back-reference after the full URL has already appeared in the same digest.
- The chat follows `AGENTS.md` section 9 and carries one scannable line per item.
Expand All @@ -144,7 +155,7 @@ Rules that keep the contract unambiguous:

## Supervision discipline

During a digest/build invocation, this skill changes no fleet state beyond its explicit report or board artifacts, binding, and source registration.
Do not tear down a task, merge a PR, dispatch queued work, steer a worker, answer a queued decision, clean up work, or mutate any other `state/` or `data/` file during that invocation.
During a digest/build invocation, this skill changes no fleet state beyond its reconcile instruction and cooldown record, explicit report or board artifacts, binding, and source registration.
Do not tear down a task, merge a PR, dispatch queued work, steer a worker except through the reconcile hook, answer a queued decision, clean up work, or mutate any other `state/` or `data/` file during that invocation.
If the state gathered for the digest suggests an action, name it in its section and leave it to the normal lifecycle and configured authority.
On a later board wake, this read-only invocation rule yields to "Handling a board wake" and its guarded authority for captain-selected dispatches and merges.
29 changes: 21 additions & 8 deletions .agents/skills/bearings/assets/board-template.html
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,12 @@
return n;
}
function badge(tone, text) { return el("span", "fm-badge fm-badge--" + tone, text); }
/* Warnings ride the charted feed for layout only; they are alarms, not work,
so every count of queued work excludes them. */
function isWarning(t) { return t && t.kind === "warning"; }
function chartedQueued(rows) { return (rows || []).filter(function (t) { return !isWarning(t); }); }
var chartedMoreQueued = data.charted_more || 0;
var chartedMoreWarnings = data.charted_warning_more || 0;
function utf8ByteLength(text) { return new TextEncoder().encode(text).length; }
var CHECK_SVG = '<svg class="fm-ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg>';

Expand All @@ -446,7 +452,7 @@
{ n: callTotal, l: "need you", call: true },
{ n: data.underway.length, l: "underway" },
{ n: data.landed.length, l: "landed recently" },
{ n: data.charted.length + (data.charted_more || 0), l: "charted next" }
{ n: chartedQueued(data.charted).length + chartedMoreQueued, l: "charted next" }
];
var strip = document.getElementById("bb-stats");
stats.forEach(function (s) {
Expand Down Expand Up @@ -651,10 +657,12 @@
barBtn.disabled = !n;
}

if (!data.charted.length) ch.appendChild(el("div", "bb-empty", "Nothing is queued."));
if (!chartedQueued(data.charted).length && !chartedMoreQueued) {
ch.appendChild(el("div", "bb-empty", "Nothing is queued."));
}
data.charted.forEach(function (t) {
var row = el("div", "bb-row");
if (t.dispatchable) {
if (t.dispatchable && !isWarning(t)) {
anyPickable = true;
var pick = document.createElement("input");
pick.type = "checkbox"; pick.className = "bb-pick"; pick.value = t.id;
Expand All @@ -677,14 +685,19 @@
var chSub = t.repo || t.id;
main.appendChild(el("div", "bb-row__sub", t.reason ? t.reason + " · " + chSub : chSub));
row.appendChild(main);
if (t.reason) row.appendChild(badge("warn", "waiting"));
if (isWarning(t)) row.appendChild(badge("danger", "needs repair"));
else if (t.reason) row.appendChild(badge("warn", "waiting"));
ch.appendChild(row);
});
var chartedTotal = data.charted.length + (data.charted_more || 0);
var chartedShown = chartedQueued(data.charted).length;
var chartedTotal = chartedShown + chartedMoreQueued;
document.getElementById("bb-charted-sub").textContent =
data.charted_more ? "showing " + data.charted.length + " of " + chartedTotal : "";
if (data.charted_more) {
ch.appendChild(el("span", "bb-morechip", "+" + data.charted_more + " more queued - ask firstmate for the full chart"));
chartedMoreQueued ? "showing " + chartedShown + " of " + chartedTotal : "";
if (chartedMoreQueued) {
ch.appendChild(el("span", "bb-morechip", "+" + chartedMoreQueued + " more queued - ask firstmate for the full chart"));
}
if (chartedMoreWarnings) {
ch.appendChild(el("span", "bb-morechip", "+" + chartedMoreWarnings + " more repair warning" + (chartedMoreWarnings === 1 ? "" : "s") + " - ask firstmate for the full chart"));
}

if (anyPickable) {
Expand Down
6 changes: 3 additions & 3 deletions .agents/skills/bootstrap-diagnostics/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ When any diagnostic needs captain attention, report the plain consequence and re

- `MISSING: <tool> (install: <command>)` - list the missing tools to the captain with a one-line purpose each plus the printed install commands, wait for consent (one approval may cover the list), then run `bin/fm-bootstrap.sh install <approved tools...>`.
For `treehouse`, this also covers an installed version whose `treehouse get` lacks `--lease`; treat it as an upgrade request.
For `no-mistakes`, this also covers an installed version older than 1.31.2, because crewmate validation briefs delegate gate mechanics to no-mistakes' version-matched guidance.
For `no-mistakes`, this also covers an installed version older than 1.46.0, because this repo's PR gate requires structured pipeline attestation that older builds do not write.
For any axi-family tool - `gh-axi`, `lavish-axi`, `tasks-axi`, `quota-axi` - an installed version below its floor is a plain upgrade request; [`bin/fm-bootstrap.sh`](../../../bin/fm-bootstrap.sh) owns the floor policy, and never argue the floor down to whatever the home happens to have installed.
For `tasks-axi`, this additionally covers an installed build that fails the separate feature probe (`bin/fm-tasks-axi-lib.sh` owns the definition); `config/backlog-backend=manual` only suppresses the verbose `BOOTSTRAP_INFO: tasks-axi available` fact, not this missing-tool report.
For `quota-axi`, bootstrap requires it because firstmate reads its current output directly before resolving every crew-dispatch profile array; without it, report the missing requirement and do not choose around an unexamined candidate.
Expand Down Expand Up @@ -53,8 +53,8 @@ When any diagnostic needs captain attention, report the plain consequence and re
- `SECONDMATE_SYNC: secondmate <id>: skipped: <reason>` - secondmate convergence left a live home on its existing checkout because the home was dirty, diverged, unsafe, on the wrong branch, missing its placement-specific target commit, unreachable, or otherwise not fast-forwardable, or because inherited local-material propagation failed; bootstrap continued, but inspect the reason because the secondmate's tracked instructions, inherited settings, or shared captain preferences may be stale after a primary update.
- `SECONDMATE_LIVENESS: secondmate <id>: skipped: <reason>|respawn failed after <cause>: <reason>` - the session-start liveness sweep could not guarantee that the registered secondmate is running a real agent process.
Investigate the reason because that secondmate is not guaranteed live.
- `SECONDMATE_HANDOFF: secondmate <id>: pending delivery: <n> item(s)` - queued work has already left the main dispatchable backlog and remains safe in the named remote route's backlog-format outbox.
Preserve that outbox and rerun `bin/fm-backlog-handoff.sh --resume-pending` after same-host connectivity returns; never re-add or dispatch the items from the main backlog.
- `SECONDMATE_HANDOFF: secondmate <id>: pending delivery: <n> item(s)` - queued work has already left the main dispatchable backlog and remains safe in the named remote route's backlog-format outbox, pending backlog receipt or receiver-wake confirmation.
Preserve that outbox and rerun `bin/fm-backlog-handoff.sh --resume-pending` after the route or endpoint problem is resolved; never re-add or dispatch the items from the main backlog.
An unsafe-outbox variant requires path and file-type inspection before any retry.
- `NUDGE_SECONDMATES: secondmate <id>: send failed: <reason>` - secondmate convergence changed a running home's loaded instructions or inherited config, but the deterministic `fm-send.sh fm-<id>` re-read nudge failed.
Inspect the reason, keep the pending marker under `state/.secondmate-nudge-pending/` intact, and rerun session start after the endpoint or metadata issue is fixed so bootstrap can retry the exact same marked send on the same local or remote route.
Expand Down
Loading
Loading