Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
88 commits
Select commit Hold shift + click to select a range
9444a12
test: make sibling secondmate stall tests wait for watcher observatio…
kunchenguid Sep 23, 2026
1738c39
fix(bin): refuse a Herdr Claude submit that would send only a message…
tiago-peixoto Sep 23, 2026
38ad5cf
feat(bin): publish and watch Gerrit changes on forge-bound projects (…
slnkjthien Sep 23, 2026
500c8d3
feat(bin): opt-in per-home Claude and Pi worker account pin (#5358)
tiago-peixoto Sep 23, 2026
1fe31c0
fix(bin): keep Herdr lab session selection before passthrough argumen…
yasuhito Sep 23, 2026
f928e72
fix: enforce supervision guards across harnesses (#5471)
kunchenguid Sep 23, 2026
6a44587
feat(bin): make the ship-branch prefix configurable per project (#2648)
wesleymatosdev Sep 24, 2026
40c97f9
feat(bin): send dispatch router only the brief's task sections and ad…
zachlandes Sep 24, 2026
d3e1ce0
feat: add opt-in Claude away supervision host (#5488)
kunchenguid Sep 24, 2026
d18b1ea
docs: correct the Grok harness reference on folder trust, training op…
Courtneyezra Sep 24, 2026
93953aa
fix(bin): bound the startup-network worker's lock waits by its budget…
karotkriss Sep 24, 2026
c9fb9a0
fix(bin): make the ps-fallback watcher identity immune to terminal wi…
karotkriss Sep 24, 2026
f4b87ab
fix(bin): ignore fenced and indented Captain lines when extracting au…
karotkriss Sep 24, 2026
fe2e0ec
fix(bin): forbid administering the shared worktree pool in crewmate b…
karotkriss Sep 24, 2026
36608b0
fix(bin): refuse tasks-axi add/create --start so In flight always has…
karotkriss Sep 24, 2026
a73b419
feat: extend opt-in away supervision to non-Pi primaries (#5503)
kunchenguid Sep 24, 2026
a962762
fix: auto-relaunch dead secondmates during supervision (#5496)
kunchenguid Sep 24, 2026
8afeb12
fix(bin): start a successor when the Claude Stop-hook arm's attached …
karotkriss Sep 24, 2026
5edfb8e
fix(bin): report a Lavish source armed only after its listener is run…
tiago-peixoto Sep 24, 2026
ae9f742
fix(bin): stop repeating unknown-wake escalations that were already d…
tiago-peixoto Sep 25, 2026
1961dfc
fix(bin): keep a stated default-key retraction from cancelling a keyl…
tiago-peixoto Sep 25, 2026
3dc62f7
fix(bin): terminate a remote job worker that lost ownership on TERM (…
tiago-peixoto Sep 25, 2026
ccf2ce1
docs: make configuration settings easier to find and understand (#5589)
tmchow Sep 25, 2026
d774401
fix: limit project memory edits to factual corrections (#5636)
kunchenguid Sep 25, 2026
da54f62
feat: permit gate lifecycle calls against disposable lab homes (#5635)
kunchenguid Sep 25, 2026
6bd9a08
fix(bin): evict a watcher whose beacon stalls past a hard bound inste…
karotkriss Sep 25, 2026
d033b44
fix(pi): hide queued Firstmate inputs under Calm only when the sessio…
tiago-peixoto Sep 25, 2026
438c23b
fix(bin): refuse teardown when a required source disappears (#5548)
tiago-peixoto Sep 25, 2026
d8a0e71
docs: make supervision-host easier to read (#5605)
tmchow Sep 25, 2026
5d735c5
docs: make the Herdr backend guide easier to read (#5606)
tmchow Sep 25, 2026
a26ab99
docs: make pi-supervision-branch easier to read (#5607)
tmchow Sep 25, 2026
b07ae07
docs: make watcher-continuity easier to read (#5608)
tmchow Sep 25, 2026
8b15125
docs: make sessionstart-nudge easier to read (#5609)
tmchow Sep 25, 2026
cc4efd2
docs: make captain-hold-lifecycle easier to read (#5610)
tmchow Sep 25, 2026
178ea2a
docs: make remote-secondmates easier to read (#5612)
tmchow Sep 25, 2026
3dd5ed7
fix(bin): bound the away digest and log why a delivery failed (#5554)
Sophylax Sep 25, 2026
7988f96
test: add a gated harness seam and stabilize lifecycle fixtures (#5638)
kunchenguid Sep 25, 2026
57e8783
fix(bin): refuse watchers from disposable checkouts and exit when the…
karotkriss Sep 25, 2026
5ac374b
fix(bin): surface unrecognized status prefixes instead of reading the…
tiago-peixoto Sep 25, 2026
a891864
fix(bin): report the failing item when remote inheritance fails (#5658)
karotkriss Sep 25, 2026
eea6dc3
fix(bin): stand down the Claude Stop auto-arm on pi-code-delivered pa…
karotkriss Sep 25, 2026
f94d263
fix(bin): match whole multi-word project names in the registry lookup…
karotkriss Sep 25, 2026
ff31155
fix(bin): classify shell stdin payloads after -s operands (#5546)
coreldh Sep 25, 2026
52ffb24
fix(bin): strip AI co-author trailers from fleet-launched commits (#5…
tiago-peixoto Sep 25, 2026
f5e3853
fix(bin): treat Pi's dollar-first cost footer as furniture (#5683)
tiago-peixoto Sep 25, 2026
594e851
fix(bin): refuse merges with unreported required checks (#5534)
mremond Sep 25, 2026
2971f59
fix: keep persistent secondmates out of landed-work cleanup (#5696)
kunchenguid Sep 25, 2026
e19cecd
fix: reject invalid X reply and follow-up arguments before posting (#…
kunchenguid Sep 25, 2026
4f17cd3
fix: pause broken supervision-host sessions between engine probes (#5…
kunchenguid Sep 25, 2026
57b02d3
fix(bin): absorb routine secondmate working and paused status appends…
karotkriss Sep 25, 2026
0979800
fix(bin): use gh-axi for the ship DoD draft check (#5519)
karotkriss Sep 25, 2026
8175d80
fix(bin): bind inactive-outcome receipt identity to structured fields…
karotkriss Sep 25, 2026
a46a52e
feat: record the Claude and Cursor dialog for the supervision host (#…
kunchenguid Sep 25, 2026
366eb3b
fix(bin): retire check-row receipts on branch acknowledgement so away…
kunchenguid Sep 26, 2026
1d7edd2
fix(bin): deliver Claude-bound operational input as a record-backed d…
kunchenguid Sep 26, 2026
53c1fa0
test: isolate lint fixture from tracked suite (#5727)
kunchenguid Sep 26, 2026
40d7a5c
fix(bin): republish parent metadata after a remote secondmate relaunc…
tiago-peixoto Sep 26, 2026
dc9599c
fix(bin): give slow watcher suites headroom under the changed-suite b…
karotkriss Sep 26, 2026
2f78801
fix(bin): stop nested steal-lock recursion and mid-steal watcher TERM…
kunchenguid Sep 26, 2026
8a5dbc6
test: make supervision-host park-boundary tests deterministic (#5710)
kunchenguid Sep 26, 2026
99a556e
fix: stage remote home clones before publication (#5733)
kunchenguid Sep 26, 2026
f7175c5
fix: preserve Herdr status on Pi relaunch (#5161)
sdivanl Sep 26, 2026
75bd016
Seed the relaunch-ordering PR poll fixture without fm-pr-check.sh (#5…
kunchenguid Sep 26, 2026
ebac487
feat: add attended supervision for Claude and Cursor hosts (#5748)
kunchenguid Sep 26, 2026
c70953a
fix(bin): dedup directed source expansions in fm-pending-reply-lib (#…
kunchenguid Sep 26, 2026
ead489e
fix(bin): avoid bash 5.2 sibling $() in recovery mint and delivery lo…
Lakescape Sep 26, 2026
69bb434
fix(bin): name the recovery for a declined Claude imports dialog and …
karotkriss Sep 26, 2026
f727203
fix(bin): report the newest status event in the voice status reader (…
karotkriss Sep 26, 2026
a4340a9
fix(bin): gate a self-announcing tool's update-available report on a …
karotkriss Sep 26, 2026
8b4c170
fix(bin): pass the dispatch profile effort to OpenCode workers throug…
karotkriss Sep 26, 2026
2a3d61d
fix: stop cancelled validation runs from reporting false failures (#5…
mremond Sep 26, 2026
bfea4b8
fix: require declared waits for workers awaiting their own work (#5812)
mremond Sep 26, 2026
6b42126
fix: bound ShellCheck to one canonical root per process (#5770)
kunchenguid Sep 26, 2026
0f07efc
fix: bound watcher cleanup wait on the downtime-marker lock (#5732)
kunchenguid Sep 26, 2026
b6ccf2d
test: stop the remote secondmate e2e watcher before temp-root cleanup…
aminry Sep 26, 2026
de72ce6
fix(bin): stop reporting untouched shared-captain copies as drift (#4…
tiago-peixoto Sep 26, 2026
d34f1b4
docs: restructure calm.md for readability (#5604)
tmchow Sep 27, 2026
aacacdb
docs: restructure turnend-guard.md for readability (#5611)
tmchow Sep 27, 2026
8c40b6d
docs: move situational AGENTS.md sections into on-demand skills (#5872)
kunchenguid Sep 27, 2026
ae6b7e6
fix: route second-mate signal wakes by presented status span (#5879)
kunchenguid Sep 27, 2026
94aa321
fix(bin): take the source lock before the lifecycle lock in register-…
FocalFactotum Sep 27, 2026
6442875
fix: chain repository hooks under git -c overrides (#5877)
FocalFactotum Sep 27, 2026
0fcf6e9
fix(bin): withhold never-send values from dispatch resolver requests …
zachlandes Sep 27, 2026
35f954d
fix(bin): admit Pi's Codex usage-limit banner as a settled composer f…
mehulbhagwani Sep 25, 2026
6af89e3
no-mistakes(document): Document FM_COMPOSER_PI_TERMINAL_ERROR_RE over…
mehulbhagwani Sep 25, 2026
ba5b9ca
no-mistakes(ci): Root cause: pi 0.87.1 now renders a fixed "If this l…
mehulbhagwani Sep 26, 2026
4236dbe
no-mistakes(review): docs: document FM_COMPOSER_PI_ERROR_HINT_RE over…
mehulbhagwani Sep 26, 2026
56f7cfc
no-mistakes(test): Shrink live e2e tmux pane so pi renders the banner
mehulbhagwani Sep 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
53 changes: 34 additions & 19 deletions .agents/skills/afk/SKILL.md

Large diffs are not rendered by default.

28 changes: 28 additions & 0 deletions .agents/skills/agent-skill-trigger-index/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
name: agent-skill-trigger-index
description: Load only when auditing or maintaining the complete agent-only skill trigger index.
user-invocable: false
metadata:
internal: true
---

# Agent-only reference skills

These skills are not captain-invocable; load them only at their precise triggers.

- `bootstrap-diagnostics` - load whenever the session-start digest's bootstrap or network-checks section prints an actionable diagnostic line (`MISSING:`, `MISSING_MANUAL:`, `PRESENTATION_UNAVAILABLE:`, `BACKEND_INVALID:`, `NEEDS_GH_AUTH`, `TANGLE:`, `STARTUP_MEMORY_BUDGET:`, `CREW_DISPATCH: invalid`, `FLEET_SYNC:`, `NETWORK_CHECKS:`, `HOME_SUMMARY:`, `BACKLOG_RECONCILE:`, `SECONDMATE_SYNC:`, `SECONDMATE_LIVENESS:`, `SECONDMATE_HANDOFF:`, `NUDGE_SECONDMATES:`, or `FMX:`), or when `BOOTSTRAP_INFO:` says an interrupted backlog cleanup may have left an endpoint or local copy; silence and other `BOOTSTRAP_INFO:` facts need no load.
- `diagnostic-reasoning` - load before scoping a reported bug and before acting on a diagnostic report.
- `ask-user-authority` - load before deciding any ask-user finding.
- `quota-array-dispatch` - load before choosing among a matched crew-dispatch profile array from current quota-axi default TOON.
- `harness-adapters` - load before spawning or recovering a crewmate or secondmate, handling a trust dialog, sending a harness-specific skill invocation, interrupting or exiting an agent, resuming an exited agent, or verifying a new harness adapter.
- `firstmate-orca` - load before switching to Orca, spawning or supervising Orca-backed work, smoke-testing Orca backend behavior, debugging Orca task state, or reconciling Orca-backed task metadata.
- `project-management` - load before adding, creating, removing, or initializing a project.
Cloning or registering a project is add intake and uses the same trigger.
- `stuck-crewmate-recovery` - load when the session-start digest reports an ordinary direct report's endpoint dead or its metadata has no window, after a stale wake, looping pane, repeated confusion, an answered-by-brief question, an unresponsive crewmate, or a failed steer, and whenever a live worker reports its no-mistakes pipeline dead, unreachable, or timed out.
- `secondmate-provisioning` - load before creating, seeding, validating, launching, handing backlog to, recovering, pushing inherited local material into, or retiring a secondmate home, and before editing `data/secondmates.md`.
- `captain-hold-lifecycle` - load before treating an investigation or visual review as complete, before ending a visual review that exposed a captain decision, when recording or routing the captain's answer, and on any `RECORD DIVERGENCE` line from the wake drain.
- `process-event-sources` - load before arming a long-polling source, before registering a deterministic condition->action watch (do X as soon as Y is true), on any `procevent <adapter> <source-id> <sequence>` check wake, and on any `process-event source stranded` or `process-event source failed to start` check wake.
Never run a registered source's blocking command yourself in a conversational turn.
- `fmx-respond` - load on an `x-mention <request_id>` `check:` wake to handle the mention, on an `x-mode-error ...` `check:` wake to report the Relay configuration blocker, on a `public-followup ...` `check:` wake or a startup-surfaced public commitment, and on any milestone or terminal wake for a Relay-linked task before posting its completion follow-up; relevant only when Relay is on.
- `firstmate-codexapp` - load before coordinating a visible Codex Desktop thread, evaluating a Codex App backend request, or reconciling Codex Desktop host-tool smoke evidence for Firstmate work.
- `firstmate-coding-guidelines` - load before changing firstmate's shared, tracked material, as defined by section 1's list, whether editing directly or briefing a crewmate for a firstmate-repo task.
1 change: 1 addition & 0 deletions .agents/skills/ahoy/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Give the captain a concise session-only recap without gathering fresh state.
A captain boundary is an ordinary user-role message unless it matches one of the narrow operational exclusions below.
Exclude messages that begin with the current U+2063 `FIRSTMATE_OP:` injection prefix.
Exclude legacy bare-marker away-mode injections only when U+2063 is immediately followed by `Supervisor escalate (`.
Exclude a message that is exactly a record-backed operational doorbell that `bin/fm-operational-input.sh doorbell-kind` recognizes from its stdin; Claude Code, which strips U+2063, receives away-mode escalations this way.
Exclude the exact legacy unmarked session-start payload ``Run `bin/fm-session-start.sh` now, exactly once, before executing any other instructions.``
Custom-role messages such as Pi's `firstmate-sessionstart-nudge` are not captain messages.
System, developer, tool, watcher, guard, away-mode, and other injected operational messages are not captain messages.
Expand Down
22 changes: 22 additions & 0 deletions .agents/skills/away-quiet-supervision/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
name: away-quiet-supervision
description: Load whenever /afk or /quiet is invoked, an away or quiet record exists, or a marked away-supervisor message arrives.
user-invocable: false
metadata:
internal: true
---

# Away and quiet supervision safety

The `/afk` and `/quiet` skills each own their daemon procedure, which is otherwise identical; these safety facts apply to both:

- Every current daemon injection uses the `away-supervisor` kind from `bin/fm-operational-input.sh` after `FM_OPERATIONAL_PREFIX` (U+2063 INVISIBLE SEPARATOR followed by `FIRSTMATE_OP: `), except that a Claude Code primary, which strips U+2063, receives that owner's record-backed doorbell and it counts as marked only when `bin/fm-operational-input.sh open <path>` verifies its record; the `/afk` skill owns legacy bare-marker compatibility.
- `state/.afk-contract` is the away posture, written in the same turn as `/afk` before any other work, because `/afk` is itself the go: no read-back gates entry or waits for a go; entry announces hold-for-return only, and the away session acts on those words by its own judgment through the guarded scripts under standing authority, holding for the return on doubt.
- While `state/.afk` exists, the daemon owns supervision; do not arm a separate watcher.
The daemon is never launched on Pi, where the ordinary supervision session continues under the record with main parked: the branch takes every safe actionable wake it can, and only a declined wake (including a broken branch or unsafe scan) or a watcher failure wakes main.
Away mode on a non-Pi home with `config/supervision-host` works the same way with the supervision host as the branch; a wake it hands back arrives through that harness's own wake path and is never the captain's return.
- A marked message while away or quiet mode is active is internal escalation and does not exit that mode.
- A message beginning `/afk` refreshes away mode; a message beginning `/quiet` refreshes quiet mode.
- Any other unmarked message means the captain returned in away mode (load `/afk`, run the return owner, and do not process that message as ordinary work until its durable catch-up gate clears), or, in quiet mode, is simply answered as ordinary work with the flag and daemon left untouched until an explicit `/quiet off`.
- Away and quiet mode never expand approval authority for merges, ask-user findings, destructive actions, irreversible actions, or security-sensitive choices.
- Bias ambiguous input toward exit because a present captain takes precedence.
3 changes: 2 additions & 1 deletion .agents/skills/bootstrap-diagnostics/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ metadata:

Handle each printed line as below, before dispatching work that depends on it.
The line formats themselves are owned by `bin/fm-bootstrap.sh`'s header; this playbook owns the response to actionable lines.
The inline rules in `AGENTS.md` section 3 still bind: detect, then consent, then install - never install anything the captain has not approved in this session - and no work is dispatched until the tools it needs are present and GitHub auth is good.
The session-start rules in `session-start-recovery` still bind: detect, then consent, then install - never install anything the captain has not approved in this session - and no work is dispatched until the tools it needs are present and GitHub auth is good.
When any diagnostic needs captain attention, report the plain consequence and requested action using `AGENTS.md` section 9's captain-facing translation contract; do not name the diagnostic label unless the captain needs to paste it into a command or issue.

- `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...>`.
Expand All @@ -40,6 +40,7 @@ When any diagnostic needs captain attention, report the plain consequence and re
- `CREW_DISPATCH: invalid config/crew-dispatch.json - <reason>` - the optional dispatch profile file exists but failed low-cost bootstrap validation; stop profile-based dispatch, report the actionable error, and require correction of the malformed schema, unverified harness name, or invalid harness/effort pair rather than falling back around it or selecting a bad profile.
- `FLEET_SYNC: <repo>: skipped: <reason>` - a benign one-off skip (offline, no origin, local-only); bootstrap continued, investigate only if it blocks work.
A skip can also report the bounded fleet-refresh timeout (`FM_FLEET_SYNC_BOOTSTRAP_TIMEOUT`, or a fleet-size-aware default with a 20 second floor); a timeout never blocks startup.
`skipped: registry entry does not resolve to a delivery posture` is the one skip that is not one-off: the clone is left alone on every bootstrap until `data/projects.md` is corrected, so run the printed `bin/fm-project-mode.sh <repo>` to read the refusal and fix the entry.
- `FLEET_SYNC: <repo>: recovered: <detail>` - the clone had drifted onto a clean detached HEAD holding no unique commits and the sync self-healed it (re-attached the default branch and fast-forwarded); no action needed, it is reported only so the self-heal is visible.
- `FLEET_SYNC: <repo>: STUCK: on <state>, N commits behind <base> - needs attention` - the clone is dirty, on a non-default branch, detached with unique commits, or diverged, so the sync left it untouched (never forcing or discarding); it will keep falling behind until you look.
A loud STUCK, especially a growing N across bootstraps, means that clone needs hands-on attention; dispatch a crewmate or resolve it before it strands work.
Expand Down
2 changes: 1 addition & 1 deletion .agents/skills/captain-hold-lifecycle/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Only `answer` with the captain's words or an evidence-backed `reconcile close` m
Never close anything the captain owns without recording what he actually said: `bin/fm-captain-hold.sh answer` writes his exact words into the task and closes a question-shaped call, while `--release` frees a captain-gated work item to proceed.
A merge approval uses that existing release path because approval permits the merge to proceed; cleanup closes the work only after it lands and records what shipped.
Closing a held row at merge approval instead records completion before landing, so the backlog claims completion before the work actually ships.
When the answer changes what a task must build, follow `AGENTS.md` section 7's Validate contract to preserve the captain's words in the brief and steer the worker.
When the answer changes what a task must build, follow `AGENTS.md` section 7's mid-task ask rule to preserve the captain's words in the brief and steer the worker.
When the captain says "later", that is an answer too: re-hold with `bin/fm-captain-hold.sh hold <id> --reason "<reason>" --until <date>` so the item leaves the live Captain's Call and resurfaces on its date, instead of leaving a live-looking card or fabricating a closure.
"A keyed answer resolves its matching captain-held task" is one capability with one owner, `bin/fm-captain-hold.sh answers`, and every channel that carries a captain answer feeds it the same task id and answer; a channel never maps keys to tasks, records a decision, or resolves anything itself.
Chat already feeds it through `bin/fm-send.sh --resolve-key`, and a captured-answer source feeds it once bound with `bin/fm-captain-hold.sh bind <source-id>`; bind before arming the source, and key each structured question by the held task's id.
Expand Down
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.
Follow the task brief's status-reporting rule for declaring and resolving waits; bin/fm-brief.sh owns that rule.
Before doing substantive work, append "working: Codex Desktop thread started".
```

Expand Down
7 changes: 4 additions & 3 deletions .agents/skills/firstmate-coding-guidelines/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Before writing a new fact anywhere in this repo, ask where it belongs, in this o
1. Does the firstmate AGENT need this on every session or every turn to operate?
If yes: `AGENTS.md`, inline.
2. Does the agent need it only in a nameable situation - a spawn, a recovery, a specific wake type, a specific lifecycle step?
If yes: an agent-only skill under `.agents/skills/`, plus a one-line trigger pointer left inline in `AGENTS.md` (usually section 13).
If yes: an agent-only skill under `.agents/skills/`, whose description states its load trigger; leave a one-line inline pointer in `AGENTS.md` only when an always-loaded rule must name the skill.
3. Is it public product, setup, or user/operator reference?
If yes: the surface classified for that audience in [`docs/documentation-audiences.md`](../../../docs/documentation-audiences.md), limited to current behavior, setup, supported limits, stable invariants, concise rationale, and current verification entry points.
4. Is it contributor/maintainer architecture?
Expand Down Expand Up @@ -53,7 +53,7 @@ That is the trigger condition for loading the skill, plus any safety-critical fa
Everything else - the procedure, the mechanism, the surrounding detail - moves out completely.
Do not leave a partial restatement behind "just in case".
A partial copy is exactly the duplication the one-owner rule forbids.
The model to copy is `AGENTS.md` section 8's "Away-mode and quiet-mode stub": it keeps only the marker format, the ownership-transfer rule, and the exit condition inline, and points everything else at the `/afk` and `/quiet` skills.
The model to copy is `AGENTS.md` section 8's "Away-mode and quiet-mode stub": it keeps only the skill-invocation triggers inline and points everything else at the `/afk`, `/quiet`, and `away-quiet-supervision` skills.

## Size discipline

Expand All @@ -66,7 +66,7 @@ When in doubt, write the fact into the skill or doc first by patching that owner
## Trigger hygiene

A new skill is dead weight if nothing loads it.
Every new skill needs its load trigger declared inline: section 13 for agent-only reference skills, or the relevant operating section for anything else.
Every new skill needs its load trigger declared in its description, which is the always-loaded trigger index; add an inline `AGENTS.md` pointer only in the operating section whose always-loaded rule must name it.
State the trigger as a condition ("load before X", "load on Y wake"), never as a vague pointer.
Briefs for tasks that touch firstmate's own tracked material should tell the crewmate to load this skill.
`bin/fm-brief.sh`'s `REPO` argument is a caller-supplied string with no reliable signal that it names firstmate's own repo, unlike a project registered in `data/projects.md`, so there is no clean point inside the scaffold to detect this case automatically.
Expand Down Expand Up @@ -125,6 +125,7 @@ Firstmate PR #3644 demonstrated the cost: pinning a 75-162-script walk took 32.7
- Plain dash `-`, never an em dash.
- Never add an agent name as a commit co-author.
- `bin/*.sh` and `bin/backends/*.sh` must pass `shellcheck`.
- Run Firstmate production-library tests and commands that source `bin/` scripts under `bash` explicitly, never through the tool shell's default interpreter.
- Run `bin/fm-lint.sh` before treating a script change as done; it is the single owner of the lint definition that CI and the no-mistakes pre-push gate both invoke, its own header owns what that definition covers, and it refuses to run under any other version of either linter.
- When a task names a specific tool, implement the work with that tool, or explicitly flag the substitution and its new dependency footprint for review before shipping.
- Colocate tests with the existing pattern in `tests/`, name them `<subject>.test.sh`, and extend an existing script rather than inventing a new runner.
Expand Down
15 changes: 15 additions & 0 deletions .agents/skills/fmx-respond/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -311,3 +311,18 @@ Treat a public loop as closed only after `retire`.
- Never inline mention-influenced reply text into a shell command; always go through `--text-file` or stdin.
- The reply length authority is the relay (it trims), but a tight reply is on you.
- Never edit `bin/fm-x-poll.sh`, `bin/fm-x-reply.sh`, or the watcher to "answer faster"; the cadence is handled by the locked session-start bootstrap step.

## Relay activation and ownership contract

Relay is the public-mention integration older docs and some emitted lines still call "X mode"; its identifiers keep the `FMX_`, `x-`, and `fm-x-` spellings.
Relay ships inert and causes no behavior change until the home opts in by placing `FMX_PAIRING_TOKEN` in its gitignored `.env`.
That token is consent for public replies and normal reversible lifecycle actions from eligible mentions, not authority for destructive, irreversible, or security-sensitive action; those still require trusted-channel confirmation.
`docs/configuration.md` owns activation, generated state, cadence, wire protocol, and opt-out mechanics.

A Relay-only home still requires the live supervision cycle so mentions can wake it without fleet work.
On an `x-mention <request_id>` or `x-mode-error ...` check wake, load `fmx-respond`, which owns classification, public-safety policy, reply or dismissal, task linking, and follow-ups.
For every Relay-linked terminal outcome, load that owner and use the promised-final reconciliation when a typed public commitment exists, otherwise post the final completion follow-up before teardown.

A promised final public reply is durable state, never conversation memory.
Load `fmx-respond` before promising one, on a `public-followup ...` check wake, and whenever the session-start digest lists a public commitment awaiting delivery or an open public loop.
Only the home holding the relay consent and thread binding ever posts it, so never ask a secondmate or crewmate to find the thread or send the reply, and never recover a terminal result by reading a `done:` sentence.
Loading
Loading