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
13 changes: 8 additions & 5 deletions .agents/skills/secondmate-provisioning/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,15 @@ Keep the always-inline routing rules in `AGENTS.md` authoritative: route by natu

## Routing table

`data/secondmates.md` has one line per persistent domain supervisor:
`data/secondmates.md` has one parser-compatible line per persistent domain supervisor:

```markdown
- <id> - <charter summary> (home: <absolute-home-path>; scope: <natural-language responsibility>; projects: <project-a>, <project-b>; added <date>)
- <id> - <one-sentence charter summary> (home: <absolute-home-path>; scope: <natural-language responsibility>; projects: <project-a>, <project-b>; added <date>)
```

Each registry entry stays concise and single-line: the summary is one sentence naming the durable charter, `scope:` is the natural-language intake responsibility, `projects:` is the non-exclusive clone list, and any extra prose is limited to genuinely domain-specific hard rules that change routing or safety for that secondmate.
The `home:` path points to the seeded home containing `data/charter.md`; no extra registry pointer field is needed.
The home-seeded `data/charter.md` is the sole owner of boilerplate idle-by-default behavior, the normal delegation lifecycle, and standard escalation contracts, so point to that charter rather than restating those contracts in the registry entry.
The `scope:` field is used during intake.
The `projects:` field is a non-exclusive clone list, not ownership.

Expand All @@ -41,9 +44,9 @@ Pass `--no-projects` instead of a project list to scaffold a project-less charte
`--no-projects` is mutually exclusive with a project list, and omitting both still fails loudly, so an accidental omission is never mistaken for a deliberate project-less seed.
Re-seeding a populated home as project-less is refused non-destructively when the home contains project clones or `data/projects.md` entries.
Retire or clean that home first, and re-scaffold a stale project-bearing charter with `--no-projects` before seeding.
Keep the charter focused on the persistent responsibility, available project clones, escalation back to the main firstmate status file, and the requests-from-main-firstmate contract.
The scaffold's definition of done encodes the idle-by-default contract: on startup the secondmate reconciles only its own in-flight work and then waits for routed tasks, never self-initiating a survey or audit.
Preserve that wording when filling the charter, including the marker rule that marked supervisor requests return through status or a doc pointer while unmarked captain messages stay conversational.
Keep custom charter text focused on the persistent responsibility, available project clones, and genuinely domain-specific hard rules.
The scaffolded charter, later copied to `data/charter.md`, owns the standard lifecycle and escalation wording.
Preserve the generated charter sections unless the domain genuinely needs a hard rule.

Provision the persistent home and registry entry after the charter is filled:

Expand Down
2 changes: 1 addition & 1 deletion docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ An explicit per-spawn harness or raw launch command does not inherit model or ef
`config/crew-dispatch.json` is inherited too; secondmates use the same natural-language dispatch profiles when spawning their own crewmates.
`config/backlog-backend` is inherited too; absent or `tasks-axi` selects the default tasks-axi backlog backend, while `manual` forces routine backlog updates to hand-editing across the fleet without disabling validated handoff delegation.

The `data/secondmates.md` line schema and the secondmate environment variables are documented in [configuration.md](configuration.md).
The `data/secondmates.md` line contract is owned by the [`secondmate-provisioning` skill](../.agents/skills/secondmate-provisioning/SKILL.md#routing-table), and the secondmate environment variables are documented in [configuration.md](configuration.md).

## Project modes are explicit

Expand Down
4 changes: 3 additions & 1 deletion docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,8 @@ The file is created lazily on first learning and follows the same dated, evidenc
## Secondmate routes (data/secondmates.md)

Persistent secondmate routes live locally in `data/secondmates.md`.
Each line records the secondmate id, charter summary, absolute home path, natural-language scope, project clone list, and added date; `fm-home-seed.sh validate` refuses duplicate ids, duplicate homes, and nested or overlapping homes.
The concise single-line route contract is owned by the [`secondmate-provisioning` skill](../.agents/skills/secondmate-provisioning/SKILL.md#routing-table), including the parser-compatible fields, one-sentence summary requirement, `home:` pointer to the seeded charter, and limit on extra registry prose.
`fm-home-seed.sh validate` refuses duplicate ids, duplicate homes, and nested or overlapping homes.
The main first mate routes by reading those scopes with judgment; the project list is provisioning data, not exclusive ownership.
Use `fm-home-seed.sh <id> - {<project>...|--no-projects}` to lease a fresh firstmate worktree for the secondmate home.
Use the deliberate `--no-projects` signal only for a firstmate-repo domain that needs no separate project clones.
Expand All @@ -134,6 +135,7 @@ Secondmate routes cover `no-mistakes` and `direct-PR` projects; `local-only` pro
For `no-mistakes` projects, seeding initializes only projects newly cloned into a secondmate home and refuses to mutate a preexisting clone that is not already initialized.
After creating a secondmate, move existing main-backlog queued items that you have judged in-scope with `fm-backlog-handoff.sh <secondmate-id> <item-key>...`; it is idempotent and refuses In flight, Done, or non-secondmate homes.
Set `FM_SECONDMATE_CHARTER` to seed from inline charter text when no filled charter brief exists; set `FM_SECONDMATE_SCOPE` when the routing scope should differ from the charter text.
The seeded home's `data/charter.md` owns the standard secondmate lifecycle and escalation contract; the route file points to it through the existing `home:` field instead of adding another pointer.
Each seed writes an `.fm-secondmate-home` identity marker at the home root.
The tracked root `.gitignore` ignores that marker, so validation can read it without making a freshly seeded home appear dirty to porcelain-based safety checks.
This does not relax protection for any other untracked file.
Expand Down
42 changes: 42 additions & 0 deletions tests/fm-instruction-owners.test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ PROJECT="$ROOT/.agents/skills/project-management/SKILL.md"
HARNESS="$ROOT/.agents/skills/harness-adapters/SKILL.md"
CODING="$ROOT/.agents/skills/firstmate-coding-guidelines/SKILL.md"
RECOVERY="$ROOT/.agents/skills/stuck-crewmate-recovery/SKILL.md"
SECONDMATE="$ROOT/.agents/skills/secondmate-provisioning/SKILL.md"
CONFIG="$ROOT/docs/configuration.md"
AGENTS="$ROOT/AGENTS.md"
BRIEF="$ROOT/bin/fm-brief.sh"
Expand Down Expand Up @@ -111,6 +112,46 @@ test_shared_authoring_requirements_are_owned() {
pass "firstmate-coding-guidelines owns compatibility review and deterministic enforcement"
}

test_secondmate_registry_contract_stays_concise() {
local guidance routing_section schema_line
routing_section=$(awk '
/^## Routing table$/ { found = 1 }
found && /^## Charter and seed$/ { exit }
found { print }
' "$SECONDMATE")
guidance=$(awk '
/^## Routing table$/ { found = 1 }
found && /^## Backlog handoff$/ { exit }
found { print }
' "$SECONDMATE")
schema_line="- <id> - <one-sentence charter summary> (home: <absolute-home-path>; scope: <natural-language responsibility>; projects: <project-a>, <project-b>; added <date>)"
assert_contains "$routing_section" "$schema_line" \
"secondmate routing table lost the parser-compatible single-line schema"
assert_contains "$routing_section" "Each registry entry stays concise and single-line" \
"secondmate routing table no longer requires concise single-line entries"
assert_contains "$routing_section" "genuinely domain-specific hard rules" \
"secondmate routing table no longer limits extra prose to domain-specific hard rules"
assert_contains "$routing_section" "The home-seeded \`data/charter.md\` is the sole owner of boilerplate idle-by-default behavior, the normal delegation lifecycle, and standard escalation contracts" \
"secondmate routing table lost the explicit charter ownership pointer"
assert_contains "$routing_section" "no extra registry pointer field is needed" \
"secondmate routing table no longer explains why the existing home field is the charter pointer"
for phrase in \
"go idle and wait silently" \
"Act only on tasks" \
"never spawn a survey" \
"run normal firstmate bootstrap" \
"escalation back to the main firstmate status file" \
"requests-from-main-firstmate contract" \
"waits for routed tasks, never self-initiating a survey or audit" \
"marked supervisor requests return through status" \
"unmarked captain messages stay conversational"; do
if printf '%s\n' "$guidance" | grep -F "$phrase" >/dev/null; then
fail "secondmate provisioning guidance restated charter boilerplate: $phrase"
fi
done
pass "secondmate registry guidance keeps concise routes and points to the charter"
}

test_state_startup_and_ordinary_recovery_placement() {
assert_grep "single owner of the top-level operational-home layout" "$CONFIG" \
"configuration docs do not own the operational state layout"
Expand Down Expand Up @@ -185,6 +226,7 @@ test_diagnostic_owner_covers_causal_procedure
test_project_management_owner_covers_guarded_operations
test_generic_effort_fallback_respects_precedence
test_shared_authoring_requirements_are_owned
test_secondmate_registry_contract_stays_concise
test_state_startup_and_ordinary_recovery_placement
test_compressed_agents_owner_map
test_compressed_agents_retains_authority_and_supervision_safety