Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
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 atelier` 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 atelier 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 atelier 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
2 changes: 1 addition & 1 deletion .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`, `atelier-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
Loading
Loading