@zerwiz/ymir 0.1.16 → 0.1.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (171) hide show
  1. package/.agents/config/app-repos.yaml +38 -0
  2. package/.claude/settings.json +31 -0
  3. package/.codex/hooks.json +43 -0
  4. package/.cursor/hooks.json +33 -0
  5. package/.pi/extensions/README.md +39 -0
  6. package/.pi/extensions/gna-pi-watch.ts +15 -0
  7. package/.pi/extensions/lib/ro-assistant-layout.ts +96 -0
  8. package/.pi/extensions/lib/ro-operational-user-layout.ts +145 -0
  9. package/.pi/extensions/lib/ro-visibility.ts +99 -0
  10. package/.pi/extensions/lib/ro-working-ship.ts +243 -0
  11. package/.pi/extensions/lib/rodd-operational-input.ts +62 -0
  12. package/.pi/extensions/lib/skuld-branch-dispatch.ts +252 -0
  13. package/.pi/extensions/lib/skuld-branch-model-picker.ts +77 -0
  14. package/.pi/extensions/lib/vordr-sessionstart-supervisor.mjs +48 -0
  15. package/.pi/extensions/ro.ts +11 -0
  16. package/.pi/extensions/skuld-branch-supervision.ts +11 -0
  17. package/.pi/extensions/syn-turnend-guard.ts +11 -0
  18. package/.pi/mcp.json +16 -0
  19. package/.pi/mcp.json.example +11 -0
  20. package/.pi/npm/.gitignore +2 -0
  21. package/.pi/settings.json +8 -0
  22. package/.pi/shared/extensions/gna-pi-watch.ts +750 -0
  23. package/.pi/shared/extensions/herdr-agent-state.ts +257 -0
  24. package/.pi/shared/extensions/open-editor.ts +509 -0
  25. package/.pi/shared/extensions/ro.ts +504 -0
  26. package/.pi/shared/extensions/skuld-branch-supervision.ts +1535 -0
  27. package/.pi/shared/extensions/syn-turnend-guard.ts +683 -0
  28. package/.pi/shared/extensions/todo.ts +133 -0
  29. package/.pi/shared/extensions/ymir-subagents.ts +287 -0
  30. package/.pi/shared/extensions/ymir-well.ts +130 -0
  31. package/CHANGELOG.md +23 -0
  32. package/assets/Ymir.md +4654 -0
  33. package/assets/healer.html +717 -0
  34. package/assets/icon-family/family-sheet.png +0 -0
  35. package/assets/icon-family/hlidskjalf.svg +1 -0
  36. package/assets/icon-family/sessrumnir.svg +1 -0
  37. package/assets/icon-family/smidja.svg +1 -0
  38. package/assets/icon-family/ymir.svg +1 -0
  39. package/assets/mimirswell.html +880 -0
  40. package/assets/mock/README.md +16 -0
  41. package/assets/mock/feeds.ts +175 -0
  42. package/assets/mock/mock.ts +408 -0
  43. package/assets/reference/docs/agent-control.md +122 -0
  44. package/assets/reference/docs/apodex/Appdex_as_Orchestrator_Planner_Reviewer_Assessment.md +176 -0
  45. package/assets/reference/docs/apodex/Final Report(1).md +198 -0
  46. package/assets/reference/docs/apodex/Final Report(2).md +54 -0
  47. package/assets/reference/docs/apodex/Final Report(3).md +40 -0
  48. package/assets/reference/docs/apodex/Final Report(4).md +234 -0
  49. package/assets/reference/docs/apodex/Final Report(5).md +13 -0
  50. package/assets/reference/docs/apodex/Final Report.md +82 -0
  51. package/assets/reference/docs/architecture.md +392 -0
  52. package/assets/reference/docs/arm-pretool-check.md +247 -0
  53. package/assets/reference/docs/calm-mode-feasibility.md +541 -0
  54. package/assets/reference/docs/calm.md +59 -0
  55. package/assets/reference/docs/captain-hold-lifecycle.md +96 -0
  56. package/assets/reference/docs/cd-guard.md +165 -0
  57. package/assets/reference/docs/cmux-backend.md +133 -0
  58. package/assets/reference/docs/codex-app-backend.md +57 -0
  59. package/assets/reference/docs/configuration.md +924 -0
  60. package/assets/reference/docs/documentation-audiences.json +468 -0
  61. package/assets/reference/docs/documentation-audiences.md +28 -0
  62. package/assets/reference/docs/examples/crew-dispatch.json +26 -0
  63. package/assets/reference/docs/examples/process-event-extension/file-signal.mjs +96 -0
  64. package/assets/reference/docs/examples/process-event-extension/firstmate-extension.json +15 -0
  65. package/assets/reference/docs/examples/watched-tools.json +24 -0
  66. package/assets/reference/docs/examples/wedge-alarm +22 -0
  67. package/assets/reference/docs/extension-bindings.md +237 -0
  68. package/assets/reference/docs/fm-test-isolation-proof.json +37 -0
  69. package/assets/reference/docs/fm-test-isolation-proof.md +149 -0
  70. package/assets/reference/docs/fm-test-portable-shards.md +118 -0
  71. package/assets/reference/docs/gitlab-merge-watch.md +275 -0
  72. package/assets/reference/docs/herdr-backend.md +346 -0
  73. package/assets/reference/docs/orca-backend.md +84 -0
  74. package/assets/reference/docs/pi-supervision-branch-poster.svg +125 -0
  75. package/assets/reference/docs/pi-supervision-branch.md +96 -0
  76. package/assets/reference/docs/plans/agentic-engineering-workflow.md +395 -0
  77. package/assets/reference/docs/plans/agentic-factory-implementation-plan.md +615 -0
  78. package/assets/reference/docs/plans/command-factory-enhancement-plan.md +420 -0
  79. package/assets/reference/docs/plans/phase-1-layer3-program-design.md +134 -0
  80. package/assets/reference/docs/plans/phase-2-vertical-slices.md +100 -0
  81. package/assets/reference/docs/plans/phase-3-measurable-goals.md +106 -0
  82. package/assets/reference/docs/plans/phase-4-context-budget.md +106 -0
  83. package/assets/reference/docs/plans/phase-5-pre-mortem-confidence.md +100 -0
  84. package/assets/reference/docs/plans/phase-6-incident-to-agent.md +109 -0
  85. package/assets/reference/docs/remote-secondmates.md +268 -0
  86. package/assets/reference/docs/scripts.md +146 -0
  87. package/assets/reference/docs/sessionstart-nudge.md +115 -0
  88. package/assets/reference/docs/subagent-guard.md +383 -0
  89. package/assets/reference/docs/supervision-protocols/claude.md +27 -0
  90. package/assets/reference/docs/supervision-protocols/codex.md +16 -0
  91. package/assets/reference/docs/supervision-protocols/cursor.md +31 -0
  92. package/assets/reference/docs/supervision-protocols/grok.md +39 -0
  93. package/assets/reference/docs/supervision-protocols/opencode.md +17 -0
  94. package/assets/reference/docs/supervision-protocols/pi.md +33 -0
  95. package/assets/reference/docs/supervision-protocols/unknown.md +13 -0
  96. package/assets/reference/docs/tmux-backend.md +115 -0
  97. package/assets/reference/docs/trace-context.md +117 -0
  98. package/assets/reference/docs/turnend-guard.md +170 -0
  99. package/assets/reference/docs/verification/dispatch-auth.md +204 -0
  100. package/assets/reference/docs/verification/muse.md +221 -0
  101. package/assets/reference/docs/verification/process-event-sources.md +208 -0
  102. package/assets/reference/docs/verification/public-followup.md +119 -0
  103. package/assets/reference/docs/verification/runtime-backends.md +1022 -0
  104. package/assets/reference/docs/verification/stow-memory.md +53 -0
  105. package/assets/reference/docs/verification/supervision.md +534 -0
  106. package/assets/reference/docs/verification/trace-context.md +31 -0
  107. package/assets/reference/docs/voice-relay.md +295 -0
  108. package/assets/reference/docs/watcher-continuity.md +119 -0
  109. package/assets/reference/docs/wedge-alarm.md +39 -0
  110. package/assets/reference/docs/zellij-backend.md +114 -0
  111. package/assets/reference/index.html +1172 -0
  112. package/assets/reference/skills/afk/SKILL.md +241 -0
  113. package/assets/reference/skills/ahoy/SKILL.md +56 -0
  114. package/assets/reference/skills/ask-user-authority/SKILL.md +56 -0
  115. package/assets/reference/skills/bearings/SKILL.md +161 -0
  116. package/assets/reference/skills/bearings/assets/board-template.html +731 -0
  117. package/assets/reference/skills/bootstrap-diagnostics/SKILL.md +68 -0
  118. package/assets/reference/skills/captain-hold-lifecycle/SKILL.md +54 -0
  119. package/assets/reference/skills/decision-hold-lifecycle/SKILL.md +15 -0
  120. package/assets/reference/skills/diagnostic-reasoning/SKILL.md +53 -0
  121. package/assets/reference/skills/firstmate-codexapp/SKILL.md +110 -0
  122. package/assets/reference/skills/firstmate-codexapp/agents/openai.yaml +4 -0
  123. package/assets/reference/skills/firstmate-coding-guidelines/SKILL.md +127 -0
  124. package/assets/reference/skills/firstmate-orca/SKILL.md +92 -0
  125. package/assets/reference/skills/fmx-respond/SKILL.md +283 -0
  126. package/assets/reference/skills/harness-adapters/SKILL.md +95 -0
  127. package/assets/reference/skills/harness-adapters/references/common/control-and-recovery.md +37 -0
  128. package/assets/reference/skills/harness-adapters/references/common/dispatch.md +32 -0
  129. package/assets/reference/skills/harness-adapters/references/common/model-and-effort.md +42 -0
  130. package/assets/reference/skills/harness-adapters/references/common/primary-hooks.md +40 -0
  131. package/assets/reference/skills/harness-adapters/references/harness/claude.md +55 -0
  132. package/assets/reference/skills/harness-adapters/references/harness/codex.md +43 -0
  133. package/assets/reference/skills/harness-adapters/references/harness/cursor.md +75 -0
  134. package/assets/reference/skills/harness-adapters/references/harness/grok.md +69 -0
  135. package/assets/reference/skills/harness-adapters/references/harness/kimi.md +51 -0
  136. package/assets/reference/skills/harness-adapters/references/harness/muse.md +70 -0
  137. package/assets/reference/skills/harness-adapters/references/harness/opencode.md +42 -0
  138. package/assets/reference/skills/harness-adapters/references/harness/pi.md +56 -0
  139. package/assets/reference/skills/process-event-sources/SKILL.md +137 -0
  140. package/assets/reference/skills/project-management/SKILL.md +92 -0
  141. package/assets/reference/skills/quota-array-dispatch/SKILL.md +131 -0
  142. package/assets/reference/skills/secondmate-provisioning/SKILL.md +254 -0
  143. package/assets/reference/skills/stow/SKILL.md +309 -0
  144. package/assets/reference/skills/stuck-crewmate-recovery/SKILL.md +54 -0
  145. package/assets/reference/skills/updatefirstmate/SKILL.md +64 -0
  146. package/assets/skills/README.md +5 -0
  147. package/assets/yggdrasil.html +649 -0
  148. package/assets/ymir-banner-01.png +0 -0
  149. package/assets/ymir-banner-02.png +0 -0
  150. package/assets/ymir-banner-03.png +0 -0
  151. package/assets/ymir-banner-04.png +0 -0
  152. package/assets/ymir-banner-05.png +0 -0
  153. package/assets/ymir-banner-06.png +0 -0
  154. package/assets/ymir-emblem-darksteel.svg +63 -0
  155. package/assets/ymir-emblem-forged.svg +55 -0
  156. package/assets/ymir-emblem-slate.svg +55 -0
  157. package/assets/ymir-mark-algiz-anvil.svg +9 -0
  158. package/assets/ymir-stave.svg +53 -0
  159. package/assets/ymir.html +563 -0
  160. package/bin/ymir-install.sh +6 -1
  161. package/data/learnings.md +33 -0
  162. package/data/local-models.md +34 -0
  163. package/data/operator.md +15 -0
  164. package/data/projects.md +28 -0
  165. package/data/realm.md +1 -0
  166. package/deploy/Containerfile +27 -0
  167. package/deploy/README.md +104 -0
  168. package/deploy/compose/compose.yaml +45 -0
  169. package/deploy/env.example +30 -0
  170. package/deploy/quadlet/ymir.container +57 -0
  171. package/package.json +10 -8
@@ -0,0 +1,92 @@
1
+ ---
2
+ name: project-management
3
+ description: >-
4
+ Agent-only procedure for Firstmate project management.
5
+ Use before adding, creating, removing, or initializing a project.
6
+ Cloning or registering a project is add intake and uses the same trigger.
7
+ Owns project add, create, clone, remove, initialization, registry, delivery-mode, autonomy, and outward-consent decisions.
8
+ user-invocable: false
9
+ metadata:
10
+ internal: true
11
+ ---
12
+
13
+ # project-management
14
+
15
+ Use this procedure before adding, creating, removing, or initializing a project.
16
+ Cloning or registering a project is add intake and uses the same trigger.
17
+ This skill is the single owner of Firstmate's project-management procedure.
18
+ It does not replace `secondmate-provisioning`, which owns project clones inside persistent secondmate homes.
19
+
20
+ ## Preconditions and registry
21
+
22
+ Projects live flat under `projects/`, and `data/projects.md` is the private fleet registry.
23
+ Use the registry format and parser contract owned by the header of `bin/fm-project-mode.sh`.
24
+ Keep each registry description useful for identifying the project, but keep delivery posture, captain-private state, and detailed project knowledge in their existing designated homes.
25
+ Do not turn the registry into project documentation.
26
+
27
+ Before adding, cloning, creating, or registering any project in the main home, inspect the authoritative `data/secondmates.md` routing table and judge every existing natural-language `scope:` against the proposed project or domain.
28
+ Apply `AGENTS.md` section 7's authoritative secondmate routing rules; if an existing scope owns that domain, route the new-project operation or work there instead of creating or registering a duplicate main-home clone.
29
+ Absence from the main `data/projects.md` registry is never evidence that no second mate owns the domain.
30
+ If the owning second mate cannot accept the route, report that concrete blocker or obtain an explicit captain redirection rather than silently duplicating the project in the main home.
31
+
32
+ Resolve the project name, destination, delivery posture, and autonomy posture before changing local or remote state.
33
+ Keep a newly added clone and its registry entry consistent, and roll back only artifacts created by the incomplete operation when a later initialization step fails and that rollback is safe.
34
+ Do not overwrite or repurpose an existing path.
35
+
36
+ ## Delivery posture
37
+
38
+ The registry records the project's standing posture, which is the captain's default for the work rather than any task's answer; `AGENTS.md` section 7 owns how each task's concrete mode and yolo are resolved at intake and passed explicitly to the brief, the spawn, and any promotion.
39
+ Choose that posture when adding or creating the project:
40
+
41
+ - `no-mistakes` runs the full validation pipeline before a PR.
42
+ - `direct-PR` pushes and opens a PR without the no-mistakes pipeline.
43
+ - `local-only` has no required remote or PR and lands only through the approved local fast-forward path.
44
+ - `no-mistakes-prod-only` is a conditional policy rather than one flat mode: genuinely internal-only tooling, automation, contributor or operator process, and release or submission work ships `direct-PR`, while product-facing, mixed, and uncertain work ships `no-mistakes`.
45
+
46
+ `no-mistakes-prod-only` is the default for a newly added or created remote-backed project when the captain specifies nothing, and a project with no remote defaults to `local-only`.
47
+ State that resolved default while confirming the source, local name, and posture instead of asking the captain to choose from scratch, and record a flat mode instead whenever they ask for one.
48
+ Existing registry entries keep the meaning they already have and are never migrated or reinterpreted, so a legacy entry with no bracket stays `no-mistakes`.
49
+ Registering a conditional policy is a one-time choice and never requires classifying any change; the per-task surface classification happens at each task's intake, and internal-only is never inferred from file location or project name.
50
+
51
+ The optional `+yolo` posture changes merge authority only and does not change the delivery mode.
52
+ Default it off for every project and every posture, and enable it only on the captain's explicit instruction.
53
+ `AGENTS.md` section 7 owns the merge-authority contract.
54
+
55
+ ## Add or clone an existing project
56
+
57
+ Confirm the source URL, local project name, delivery posture, and autonomy posture, stating the resolved default for each rather than asking the captain to invent one.
58
+ Clone into `projects/<name>` and add the registry entry only after the destination is known to be unused.
59
+ A `no-mistakes` or `no-mistakes-prod-only` project must have an `origin` remote and must complete the initialization procedure below, because a conditional policy's product-facing work runs the pipeline while its internal-only work still takes the direct PR.
60
+ A `direct-PR` project needs an `origin` remote but skips no-mistakes initialization.
61
+ A `local-only` project may have no remote and skips no-mistakes initialization.
62
+
63
+ ## Create a project
64
+
65
+ Creating a GitHub repository is outward-facing.
66
+ Before making that remote change, propose the repository name, owner or organization, visibility, and delivery posture, defaulting visibility to private and the posture to `no-mistakes-prod-only`, then obtain the captain's explicit consent for those exact values; a stated default never replaces that consent.
67
+ Use `gh-axi` for the approved GitHub operation and consult its current help rather than relying on remembered flags.
68
+ After remote creation succeeds, clone it locally, add the registry entry, and initialize it according to its delivery posture.
69
+
70
+ For a purely `local-only` project, create a local Git repository under its unused `projects/<name>` path, add the registry entry, and make no GitHub call.
71
+ The captain's request to create that local project authorizes this local initialization, but it does not authorize an unmentioned remote repository.
72
+
73
+ ## Initialize
74
+
75
+ Run no-mistakes initialization only for `no-mistakes` and `no-mistakes-prod-only` projects:
76
+
77
+ ```sh
78
+ cd projects/<name> && no-mistakes init && no-mistakes doctor
79
+ ```
80
+
81
+ Initialization configures the local gate and does not vendor a no-mistakes skill into the project.
82
+ Do not create a commit merely because initialization ran.
83
+ If doctor reports an environment, authentication, or daemon problem, resolve that blocker before dispatching work and never restart the shared daemon from a project operation.
84
+
85
+ ## Remove
86
+
87
+ Project removal is destructive.
88
+ First obtain the captain's explicit removal decision, then inspect the current digest and authoritative repositories for in-flight or queued work, registered secondmate clones, linked worktrees, dirty files, unpushed commits, and any other unlanded work.
89
+ If any dependency or unlanded work exists, stop and report it before changing anything.
90
+ Never issue a raw removal command from Firstmate.
91
+ Once that preflight confirms none of the above and the captain's approval is concrete, AGENTS.md hard rule 1's captain-approved project operation exception authorizes firstmate to remove the clone directly and update its registry entry to match.
92
+ When a clone has already been removed through an approved removal, or the registry is provably stale because no clone exists, remove its registry line so navigation matches reality.
@@ -0,0 +1,131 @@
1
+ ---
2
+ name: quota-array-dispatch
3
+ description: >-
4
+ Agent-only decision procedure for resolving a matched crew-dispatch profile
5
+ array from quota-axi's default TOON, ranking by spendPriority after three
6
+ orthogonal gates.
7
+ Load when a dispatch rule or default resolves to more than one profile candidate.
8
+ user-invocable: false
9
+ metadata:
10
+ internal: true
11
+ ---
12
+
13
+ # quota-array-dispatch
14
+
15
+ This skill is the single owner of the completion-aware profile-array selection procedure.
16
+ `AGENTS.md` section 4 owns the always-loaded intake boundary, load trigger, malformed-config refusal, every-candidate accounting, and strongest-reasoning/tie safety rules.
17
+ `harness-adapters` owns harness verification, model/provider discovery, and effort fallback.
18
+ `quota-axi` remains data-only: it publishes `spendPriority` as a comparable scalar and never recommends, selects, ranks, or infers a route.
19
+ Do not add a daemon, opaque composite score, routing wrapper, hard-coded model-specific policy, or producer-side route recommendation.
20
+ Deterministic shell owns only schema, configuration, and version validation plus concrete spawn safeguards; every model-to-provider, provider-to-credential, and quota-applicability relation is yours to establish transparently and to show your evidence for.
21
+
22
+ ## Worker-side quota helper
23
+
24
+ The canonical shell helper for a worker that has already performed its model-selection reasoning and now needs to pick the first viable candidate is `bin/fm-quota-choose.sh`.
25
+ Pass it the intake's already-captured default TOON or permitted JSON fallback through stdin or `--snapshot`; it never takes another quota snapshot, so it selects from the same quota state as the intake.
26
+ Pass each candidate as `harness:model`, with earlier candidates preferred.
27
+ The helper maps each harness to its primary provider family and applies the provider-wide scopes plus the exact model or product scopes for the model.
28
+ An `exhausted_now` runway vetoes the candidate.
29
+ The helper selects a candidate only when its applicable quota has a known `effectivePercentRemaining` greater than zero.
30
+ This is an optional narrow helper with a known limitation: it maps each harness to one primary provider family only, so a candidate whose established provider differs from that primary family is checked against the wrong quota row.
31
+ Authoritative multi-provider routing - including provider discovery from the harness catalog and quota matching by that explicit provider - stays owned by this skill's intake procedure above and AGENTS.md section 4, not by the helper.
32
+ Use it only when the brief already fixed the candidate order and every candidate's provider is the harness's primary family.
33
+ It does not replace the reasoning-class, runway-feasibility, or authentication gates above.
34
+ Firstmate can optionally arm `bin/fm-procevent-quota.sh` for a recurring mid-task check that wakes when the tracked provider drops below its configured threshold or its runway becomes `exhausted_now`.
35
+
36
+ ## Read the default TOON
37
+
38
+ Start each intake by running `quota-axi` once with no `--json`, and reuse that TOON for every candidate.
39
+ Post-consolidation quota-axi (the floor owned by `bin/fm-quota-axi-lib.sh`) puts `spendPriority` in the default `quota[]` block beside `effectivePercentRemaining`, `runway`, `confidence`, `limitedBy`, and `resetsAt`.
40
+ Sparse `exhaustion[]` carries finite-runway seconds only for `projected_exhaustion` and `exhausted_now`.
41
+ Sparse `attention[]` names auth, stale, and unmeasurable facts.
42
+ `spendPriority` is THE quota-perspective ranker.
43
+ It already computes the economics that older instructions reconstructed by hand from headroom, pace, reserve, and window-id lists; do not recompute those.
44
+ Do not read `--json` on the normal path, and do not reach for `--full` to rebuild that economics.
45
+
46
+ After reading the TOON, fall back to one `quota-axi --json` call only when that TOON is genuinely ambiguous for the decision, or when the installed quota-axi is somehow below the floor so its TOON lacks `spendPriority`.
47
+ Ambiguous means a candidate's `spendPriority` is the literal `unknown` or unmeasurable, a real tie still needs extra evidence, or a candidate's eligibility is unclear from `quota[]` plus `attention[]`.
48
+ The fallback therefore has an explicit TOON-then-JSON call sequence; reuse its JSON result and do not take any further quota snapshots.
49
+ Below-floor is rare: bootstrap enforces `FM_QUOTA_AXI_MIN` and normally reports `MISSING` before dispatch; if an intake somehow reaches an older build whose TOON lacks `spendPriority`, use the defensive `--json` fallback rather than treating the missing scalar as healthy.
50
+ `--json` is a defensive belt, not a habit; never reach for it because it feels more complete.
51
+ Read `quota-axi auth --json` only when a candidate's credential surface is in question.
52
+
53
+ For each candidate, preserve explicit `harness`, `model`, and `provider`; `harness-adapters` owns identity, and model/provider never infer harness.
54
+
55
+ ## Three gates, then spendPriority
56
+
57
+ Apply the three cheap orthogonal gates first.
58
+ `spendPriority` ranks only among candidates that pass all three.
59
+ It cannot override a hard-gate failure, and it is never hidden inside a new composite score.
60
+
61
+ ### 1. Eligibility
62
+
63
+ Deterministic shell must never map a model to a provider, a provider to a credential store, or a name prefix to a family.
64
+ You establish those relations yourself, in the open, from the candidate's own authoritative catalog (`harness-adapters` owns the per-harness discovery surface) plus the one intake snapshot.
65
+
66
+ Confirm the catalog lists the candidate's model and record the provider family it reports.
67
+ A model the catalog does not list is concrete contradictory evidence: block that candidate and quote the catalog result.
68
+ Apply quota at the granularity the vendor actually supplies.
69
+ A provider-level or `all_models`/`all_products` scope bounds every model you established in that family, including one with no window of its own.
70
+ A named-model or named-product scope is an additional bound for that model alone.
71
+ Match the candidate to its `quota[]` row by that established provider and scope; a stale, auth-required, or unmeasurable scope is named in `attention[]` instead of a fabricated number.
72
+
73
+ A candidate authenticates through its own tuple's surface; another harness's CLI can never gate it, and `harness=pi` with `model=xai/grok-*` is Pi using xAI rather than the standalone Grok CLI.
74
+ `quota-axi auth --json` lists each provider's credential sources independently, so read the one source the candidate actually uses rather than collapsing a provider to a single status.
75
+ A provider can carry a healthy source beside a missing or expired one; the unused source's state is not the candidate's state.
76
+ A Pi-hosted family may authenticate through the vendor's own store with no `pi:`-prefixed source at all, which is normal and never evidence against the candidate.
77
+
78
+ Uncertainty and ineligibility are different findings:
79
+
80
+ - No model-level window, no matching auth source, an unmeasurable or `unknown` scope, or a surface quota-axi does not model at all is disclosed uncertainty.
81
+ Keep the candidate eligible, state the unknown, and prefer known viable evidence when otherwise comparable.
82
+ - An expired credential is a short-lived session token the owning vendor renews on next use, not a sign-out.
83
+ - Only concrete contradictory evidence blocks: an authoritative catalog proving the model unsupported, or proof that the credential the candidate actually selects is unusable.
84
+ - Reserve login wording for that proven-unusable case, and name the harness, model, surface, and evidence.
85
+
86
+ When a credential's local classification is the only thing standing between a candidate and a block, get ground truth before blocking.
87
+ `bin/fm-vendor-auth-probe.sh` is the only approved vendor-credential probe; its `--help` owns the registered probes and mechanics.
88
+ It takes no harness, model, or provider and returns a fact, not a route: only `authenticated` and `unauthenticated` are ground truth, while `indeterminate`, `timeout`, and `unavailable` establish nothing and must never be read as either outcome.
89
+ Never launch a vendor CLI yourself, and never probe a credential store the candidate does not use.
90
+ Grok prepaid `credits` are unrelated to paid-window headroom; never read them as exhaustion.
91
+
92
+ Malformed configuration is an actionable error, not a candidate to rank around.
93
+
94
+ ### 2. Reasoning-class fit
95
+
96
+ Keep only candidates that meet the required reasoning class for this task (a simple bug fix versus very-difficult design).
97
+ Never use `spendPriority` or remaining quota to silently replace that class.
98
+ When every remaining candidate is tight, dispatch inside the strongest-reasoning class if one of those candidates can proceed, or stop and report that the strongest-class choice cannot proceed rather than downgrading it to spend or conserve quota.
99
+
100
+ ### 3. Runway feasibility floor
101
+
102
+ Known runway that will not last until the inspectable likely-completion horizon fails this gate, even when that candidate has the highest `spendPriority`.
103
+ Read `runway` from the `quota[]` row: `through_reset` passes this generic feasibility floor because the window reaches its refill without exhausting; never compare its `resetsAt` with the completion horizon as though reset were an exhaustion deadline.
104
+ `exhausted_now` is zero, and `projected_exhaustion` uses the matching `exhaustion[]` row's `usableRunwaySeconds`.
105
+ A high `spendPriority` on a nearly empty window that will exhaust soon must not route into a mid-task stall.
106
+ Unknown or unmeasurable runway stays eligible with disclosed uncertainty and is never assumed to pass.
107
+ Do not invent a generic percentage floor, and honor an explicit captain floor for a candidate when one exists.
108
+
109
+ ## Rank by spendPriority
110
+
111
+ Among candidates that pass all three gates, pick the highest known `spendPriority`.
112
+ A higher known scalar is better: positive means paid allowance is on track to reach reset unused, `0` is exact utilization, and negative means overdrawn against the reset clock.
113
+ Rank only from comparable known scalars.
114
+ Never treat absent, `unknown`, or unmeasurable `spendPriority` as zero or as healthy; `0` means exact utilization, a different claim from unknown.
115
+ An unknown `spendPriority` keeps the candidate eligible with disclosed uncertainty.
116
+ Prefer known viable evidence when otherwise comparable.
117
+ After the permitted TOON-to-JSON fallback, escalate to Firstmate instead of routing if no candidate can be ranked or runway uncertainty prevents proving the feasibility floor for any candidate that could be selected.
118
+ Never resolve that terminal uncertainty by treating unknown as healthy or by choosing arbitrarily.
119
+ Show the scalar or the literal `unknown` in the rationale; do not hide it in a score.
120
+
121
+ Do not compare headroom against runway by hand.
122
+ Do not use pace or signed reserve as a later tie-break layer.
123
+ Do not read `aheadWindowIds`, `behindWindowIds`, `onPaceWindowIds`, `limitingWindowIds`, or other window-id lists to reconstruct what `spendPriority` already computed.
124
+
125
+ Genuine ties: stop and report every tied candidate for captain choice.
126
+ Do not select by array order, harness name, or another arbitrary identity ordering.
127
+ Report duplicate concrete profiles as a configuration error.
128
+
129
+ Account for every candidate visibly before selecting or escalating, naming its catalog evidence, provider relation, applicable quota and authentication facts, remaining uncertainty, fit and reasoning class, `spendPriority`, and runway-versus-horizon result.
130
+ A blocked credential report must name `harness`, `model`, authentication surface, and concrete failure evidence; never emit a bare `Grok unauthenticated` statement.
131
+ Never conclude with an unexplained "best quota" label.
@@ -0,0 +1,254 @@
1
+ ---
2
+ name: secondmate-provisioning
3
+ description: >-
4
+ Agent-only reference for persistent secondmate setup and retirement.
5
+ Use when creating, seeding, validating, launching, recovering, handing backlog to, pushing inherited local material into, or retiring a secondmate home, or when editing data/secondmates.md.
6
+ Covers local leases, whole-home remote routes, transactional seeding, record intake for an existing or inherited domain, project clone restrictions, secondmate harness pins, inherited local-material push, idle charter, handoff helper, and teardown safety.
7
+ user-invocable: false
8
+ metadata:
9
+ internal: true
10
+ ---
11
+
12
+ # secondmate-provisioning
13
+
14
+ Use this reference before creating, seeding, validating, launching, handing backlog to, recovering, pushing inherited local material into, or retiring a persistent secondmate, and before editing `data/secondmates.md`.
15
+
16
+ Keep the always-inline routing rules in `AGENTS.md` authoritative: route by natural-language `scope:`, local-only projects stay with the main firstmate, and secondmates are idle by default.
17
+
18
+ ## Routing table
19
+
20
+ `data/secondmates.md` has one parser-compatible line per persistent second mate.
21
+ A local route uses:
22
+
23
+ ```markdown
24
+ - <id> - <one-sentence charter summary> (home: <absolute-home-path>; scope: <natural-language responsibility>; projects: <project-a>, <project-b>; added <date>)
25
+ ```
26
+
27
+ A whole-home remote route uses:
28
+
29
+ ```markdown
30
+ - <id> - <one-sentence charter summary> (host: <ssh-alias>; root: <absolute-remote-code-root>; home: <absolute-remote-home>; scope: <natural-language responsibility>; projects: <project-a>, <project-b>; added <date>)
31
+ ```
32
+
33
+ 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.
34
+ Natural-language summary and `scope:` text may contain parentheses and semicolons; keep the generated `(home: ...; scope: ...; projects: ...; added ...)` suffix intact so operational consumers resolve its explicit field markers.
35
+ The `home:` path points to the seeded home containing `data/charter.md`; no extra registry pointer field is needed.
36
+ For a remote route, `host:` is an OpenSSH config alias and `root:` is that host's separate tracked Firstmate code root.
37
+ A remote second-mate agent always runs on the Herdr backend and every seed, launch, and liveness relaunch first gates its host on `bin/fm-remote-doctor.sh` readiness, so an unready host refuses with that doctor's own gap text rather than half-creating a route; the workers that second mate supervises keep the home's ordinary backend selection.
38
+ This release places whole secondmate homes remotely and never individual workers.
39
+ [`docs/remote-secondmates.md`](../../../docs/remote-secondmates.md) owns current operator setup and transport behavior.
40
+ 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.
41
+ The `scope:` field is used during intake.
42
+ The `projects:` field is a non-exclusive clone list, not ownership.
43
+
44
+ ## Charter and seed
45
+
46
+ Scaffold a secondmate charter with:
47
+
48
+ ```sh
49
+ bin/fm-brief.sh <id> --secondmate {<project>...|--no-projects}
50
+ ```
51
+
52
+ The scaffold writes a charter brief instead of a task brief.
53
+ Set `FM_SECONDMATE_CHARTER='<charter>'` to fill the charter text and `FM_SECONDMATE_SCOPE='<scope>'` when the routing scope differs.
54
+ If you scaffold without `FM_SECONDMATE_CHARTER`, replace the `{TASK}` placeholder before seeding.
55
+ Pass `--no-projects` instead of a project list to scaffold a project-less charter for a domain whose subject is the firstmate repo itself, whose home is a firstmate worktree and whose crews take pooled worktrees of the same repo.
56
+ `--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.
57
+ Re-seeding a populated home as project-less is refused non-destructively when the home contains project clones or `data/projects.md` entries.
58
+ Retire or clean that home first, and re-scaffold a stale project-bearing charter with `--no-projects` before seeding.
59
+ Keep custom charter text focused on the persistent responsibility, available project clones, and genuinely domain-specific hard rules.
60
+ The scaffolded charter, later copied to `data/charter.md`, owns the standard lifecycle and escalation wording.
61
+ Preserve the generated charter sections unless the domain genuinely needs a hard rule.
62
+
63
+ Provision a local persistent home and registry entry after the charter is filled:
64
+
65
+ ```sh
66
+ bin/fm-home-seed.sh <id> <home|-> {<project>...|--no-projects}
67
+ ```
68
+
69
+ Provision a whole remote home through its configured SSH host with:
70
+
71
+ ```sh
72
+ bin/fm-remote-home-seed.sh <id> <ssh-alias> <remote-root> <remote-home> {<project>[=<origin-url>]...|--no-projects}
73
+ ```
74
+
75
+ You resolve each project's origin yourself - from the captain, the project registry, a clone that exists elsewhere, `gh-axi`, or an explicit paste - and name it as `<project>=<origin-url>`; the seed validates and transports what you supply.
76
+ A remote seed therefore creates nothing in this home beyond the route, the charter brief, and a launch record once it is launched: never clone a project into `projects/`, initialize no-mistakes here, or run a fleet sync just to seed a remote secondmate.
77
+ A bare `<project>` remains a convenience for a project this home already has cloned, whose configured origin is read instead.
78
+ [`docs/remote-secondmates.md`](../../../docs/remote-secondmates.md#provision-a-route) owns the rest of the operator contract, and [`bin/fm-project-origin-lib.sh`](../../../bin/fm-project-origin-lib.sh) owns the accepted origin forms.
79
+ Pass `--no-projects` in the project position to seed the project-less home described above; the same mutual-exclusion and fail-loud-on-omission rules apply.
80
+ It may only seed a home with no project clones or project-registry entries, and refuses conversion of populated homes without changing them.
81
+ `-` durably leases a fresh firstmate worktree via `treehouse get --lease` under the secondmate id.
82
+ The lease survives with no live process and is never recycled by later `treehouse get` or `prune`.
83
+ The slot stays reserved across restarts until the lease is released.
84
+ Release happens only on explicit retirement or seed rollback, never on routine restart or recovery.
85
+
86
+ `bin/fm-home-seed.sh` copies the charter into the secondmate home as `data/charter.md`.
87
+ It also writes the gitignored `.fm-secondmate-parent` durable binding before the required `.fm-secondmate-home` identity marker; the parser header in [`bin/fm-secondmate-parent-lib.sh`](../../../bin/fm-secondmate-parent-lib.sh) owns the record contract, and both files must remain in place.
88
+ `bin/fm-spawn.sh --secondmate` launches it through the secondmate harness path, resolving `config/secondmate-harness` -> `config/crew-harness` -> the primary's own harness unless an explicit per-spawn harness override is passed.
89
+
90
+ `config/secondmate-harness` may also pin a concrete model and effort for the secondmate agent, in the SAME file rather than a new one: the format is a single whitespace-separated line `<harness> [<model>] [<effort>]`, with only the first non-empty, non-comment line parsed.
91
+ A bare `<harness>` (today's format, e.g. `claude`) behaves exactly as before - harness only, no model/effort flag - so this is fully backward-compatible.
92
+ `bin/fm-harness.sh secondmate-model` and `bin/fm-harness.sh secondmate-effort` print the optional 2nd/3rd tokens (empty when absent, or when the file is absent/`default`/harness-only); they read only `config/secondmate-harness`, never `config/crew-harness`, which stays a bare adapter name.
93
+ For a `--secondmate` spawn, `bin/fm-spawn.sh` populates `MODEL`/`EFFORT` from those tokens only when the harness itself came from the secondmate config path for that spawn.
94
+ For a local route, an explicit per-spawn `--harness` flag, positional harness arg, or raw launch command starts clean on model and effort too, unless the caller also passes explicit `--model` or `--effort`.
95
+ A remote route accepts only a verified harness adapter and refuses a raw launch command at the host boundary.
96
+ When the file's tokens do apply, an explicit per-spawn `--model` or `--effort` flag always wins over the file's token for that axis.
97
+ Because this resolves from the file on every spawn, the pin is durable across every respawn (recovery, `/updatefirstmate`, restart) exactly like the harness axis itself - e.g. `config/secondmate-harness` containing `claude opus` keeps a secondmate pinned to Opus even if the primary's own default model later changes.
98
+ This is secondmate-only: crewmate/scout model resolution is untouched by this file.
99
+
100
+ This section is the single owner of the secondmate sync and inherited-local-material propagation contract; `AGENTS.md` sections 3 and 4 point here.
101
+ Before a local launch, `fm-spawn.sh --secondmate` locally fast-forwards the home to the primary firstmate checkout's current default-branch commit when it is safe; dirty, diverged, or in-flight homes launch unchanged with a warning.
102
+ The locked session-start deferred network stage runs the same bootstrap sweep for every live local secondmate home, discovered from `state/<id>.meta` records with `kind=secondmate` (`data/secondmates.md` only backfills `home=` for older records).
103
+ That no-fetch path is a purely local fast-forward of tracked files, never an origin fetch, and it never touches the gitignored operational dirs, so a secondmate's backlog, projects, and in-flight work are never disturbed; a linked worktree advances immediately, while a standalone clone that lacks the target receives firstmate updates through `/updatefirstmate`'s origin refresh.
104
+ A remote launch and the deferred bootstrap sweep ask the configured host to fast-forward its persistent home to that host's code-root commit under the same clean and ancestry guards.
105
+ `/updatefirstmate` first updates the remote code root from its own origin, then runs that guarded home sync.
106
+ SSH exit 255 preserves the route and reports unknown completion; it never triggers local respawn or failover.
107
+ The same placement-specific launch and deferred bootstrap sweep also propagate the primary's declared inherited local material: `config/crew-dispatch.json`, `config/crew-harness`, `config/backlog-backend`, `config/backend`, `config/herdr-presentation-spaces`, `config/startup-memory-budget`, and the one shared captain-preference file `data/captain-shared.md`.
108
+ Because these paths are gitignored, that propagation is a separate, primary-authoritative copy independent of the tracked-files fast-forward: it re-converges every live home whether or not its tracked files advanced, and it touches only the declared items.
109
+ Propagation failures warn without blocking secondmate launch or session-start continuation, and the destination keeps whatever safely validated state the helper left behind.
110
+ Inheritance copies the literal `config/crew-harness` file, so a secondmate's own crewmates use the primary's crewmate harness only when it names a concrete adapter such as `codex`; an unset or `default` value has nothing concrete to inherit, and the secondmate's own crewmates fall back to the secondmate's own or detected harness instead.
111
+ Inherited `config/backend` becomes that secondmate home's local runtime-backend default for future spawns only; it never retargets, rewrites, migrates, stops, or restarts an already-live worker endpoint.
112
+ A present primary value always converges byte-exact into validated secondmate homes, and primary absence removes the destination so those homes keep runtime auto-detection.
113
+ Explicit per-spawn `--backend` and `FM_BACKEND` remain stronger than every home's local `config/backend`, including an inherited default.
114
+ `config/secondmate-harness` is not inherited because it is only the primary's knob for launching secondmate agents.
115
+ `data/captain-shared.md` is main-authoritative in the primary home and read-only in secondmate homes.
116
+ Its primary file header must state that the file is main-authoritative, read-only in secondmate homes, must not be edited there, and that new captain-preference discoveries are routed to the main firstmate through marked status or a document pointer.
117
+ Every propagation point converges the secondmate copy to the primary bytes; when the primary file is absent, any existing secondmate copy is quarantined and removed so absence converges too.
118
+ The helper rejects unsafe directories, symlinked or nonordinary source or destination artifacts, and hardlinked destination files.
119
+ Between propagation runs, the secondmate copy is filesystem read-only; the helper may make its owned destination writable only around a guarded update and restores read-only mode on success, unchanged bytes, and recoverable failure paths.
120
+ Before replacing divergent secondmate bytes, the helper hash-compares source and destination, quarantines the secondmate-local version to a collision-safe private dated sibling file, and emits a `SECONDMATE_SYNC:` diagnostic naming the home and quarantine artifact.
121
+ Never copy any secondmate `data/captain-shared.md` back into the primary.
122
+ Keep each home's `data/captain.md` domain-local.
123
+ After first propagation to an existing home, trim that home's local `data/captain.md` by hand to domain-specific content plus pointers to `data/captain-shared.md`; do not automate or silently delete private content.
124
+ Keep every `data/learnings.md` fully local by captain decision; route fleet-general machinery facts into tracked documentation through the normal firstmate repo path rather than inventing shared learnings propagation.
125
+ No AGENTS.md reread nudge is needed at spawn or respawn because the agent reads instructions fresh on launch; only the bootstrap sweep's running-home instruction-surface advance needs that AGENTS.md re-read.
126
+ Bootstrap reports successful AGENTS.md re-read sends as `BOOTSTRAP_INFO:` and only emits `NUDGE_SECONDMATES:` when that send fails and needs retry.
127
+ A separate, literal-content config reread is required whenever inherited `config/*` material changes under an already-running secondmate.
128
+ For a local home, after each successful allowlisted config write, both the locked bootstrap convergence path and mid-session `bin/fm-config-push.sh` use the shared propagation report to build one per-home generation-specific private instruction file from the validated destination post-write bytes for only the allowlisted config items that actually changed for that home (`config/crew-dispatch.json`, `config/crew-harness`, `config/backlog-backend`, `config/backend`, `config/herdr-presentation-spaces`, `config/startup-memory-budget`), in deterministic allowlist order.
129
+ Each changed path is printed with clear begin/end delimiters and the destination file's full exact new bytes unparsed, or the explicit token `ABSENT` when propagation removed the destination copy.
130
+ The instruction uses only minimal framing that these are defaults/rules and do not remove judgment; it never includes SHA values, selected profiles, parsed summaries, or any other generated interpretation.
131
+ `data/captain-shared.md` is not a config file and is never inlined into this instruction file or message.
132
+ Homes whose allowlisted config files were all unchanged receive no config-reread message when no retry is pending.
133
+ Different homes may receive different changed-file sets based on their pre-push destination bytes.
134
+ Delivery uses the existing routed secondmate path (`fm-send`) with only a single-line `CONFIG_REREAD: <absolute generation-specific instruction path>` pointer; a failed instruction publication retains the generated exact bytes in a bounded private retry queue when possible, legacy retry reports remain recoverable, a failed publication or retry-marker write retains the exact generation until it can be delivered, a failed send records a per-generation durable retry marker when possible, and all failures surface a concrete `CONFIG_REREAD:` diagnostic without claiming the live agent already re-read the values.
135
+ The propagation, generation publication, and pointer-delivery sequence holds one per-home inheritance lock, so concurrent mid-session pushes cannot deliver an older generation after a newer one.
136
+ A newly launched or relaunched secondmate already reads its files at launch, so its pending config-reread generations are discarded or quarantined after cleanup failure and it needs no redundant live-agent config nudge unless propagation changes files after launch.
137
+ Quarantined pre-relaunch generations are retained in bounded private history, and cleanup skips creating an empty quarantine generation.
138
+ Successfully delivered generations are retained only within a bounded per-home state history, while pending generations remain until delivery succeeds or a launch supersedes them.
139
+ A remote home receives the same allowlisted bytes through `fm-remote-inherit.sh` and gets one marked re-read instruction after a changed transfer.
140
+ The parent records that nudge before delivery, retains it after a failed send, and retries the exact same route during locked bootstrap convergence.
141
+ It does not receive a pointer to a primary-local generation path that cannot exist on that host.
142
+ These config values remain defaults and rules only; they must not harden `fm-spawn` to reject a deliberate runtime choice that differs from the configured defaults.
143
+ For already-live secondmates, use `bin/fm-config-push.sh` to push a mid-session inherited local-material change without running the tracked-file fast-forward.
144
+ It uses the same live-home discovery and propagation helper as bootstrap, reports each item as `pushed`, `unchanged`, `skipped`, or `error`, and follows the config-reread contract above for changed or pending generations.
145
+ `bin/fm-home-seed.sh` refuses to copy a missing or placeholder charter.
146
+
147
+ Direct seed without a preexisting brief requires `FM_SECONDMATE_CHARTER`.
148
+ Run `bin/fm-home-seed.sh validate` when checking registry integrity; its header owns the complete validation and refusal mechanics.
149
+
150
+ Seeding is transactional.
151
+ If validation, cloning, no-mistakes initialization, or registry update fails, generated briefs, new homes, new project clones, and registry edits are rolled back.
152
+
153
+ Secondmate project lists may include `no-mistakes` and `direct-PR` projects only.
154
+ `local-only` projects stay with the main firstmate.
155
+ 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.
156
+
157
+ ## Record intake for an existing or inherited domain
158
+
159
+ Classify the domain before seeding, because this step applies to only one of the two cases.
160
+ A greenfield domain has no delivered domain work yet: nothing already shipped in its projects, no live deployment, and no predecessor records to import.
161
+ Seed a greenfield domain normally; there is nothing to reconcile and this section adds no work to it.
162
+ An existing or inherited domain is any domain whose product is already in development, and any predecessor's domain a new mate takes over, including a consolidation after a retirement.
163
+ Both of those cases require record intake before the new mate acts on any inherited plan.
164
+
165
+ For an existing or inherited domain, the creating agent must:
166
+
167
+ 1. Reconcile every inherited plan against the domain's authoritative shipped state, which is `origin/main` for each relevant project plus the live deployment.
168
+ A fetched clone of each relevant project is a precondition of that reconciliation, so wire the home to its projects before reconciling rather than on first task.
169
+ The imported backlog, the predecessor's own notes, instruction-surface prose, and an absent or unfetched local view are all inadmissible as shipped-state evidence.
170
+ 2. Seed the new home with only genuinely open work plus the domain's durable knowledge, meaning the learnings, decisions, and delivery posture that are still live.
171
+ 3. Never inherit a plan backlog blind.
172
+ A plan row whose work is already shipped is dropped, or recorded as done with the merged evidence that settles it, and is never carried forward as open.
173
+
174
+ A live backlog keeps only the configured recent Done entries by design, so an inherited queue structurally over-represents plans and under-represents deliveries.
175
+ Treat an inherited queue that carries plans with no matching delivery record as unreconciled rather than as open work, and record whatever could not be reconciled as an explicit residual-uncertainty list in the new home rather than leaving that gap silent.
176
+
177
+ ## Backlog handoff
178
+
179
+ Apply `AGENTS.md` section 10's work-items-only backlog contract before creation or handoff.
180
+ When a secondmate is created for a domain, existing main-backlog items that fall under its scope should become its work instead of staying stranded in the main backlog.
181
+ Scope-matching is firstmate's judgment against the secondmate's natural-language scope, not a keyword rule.
182
+ Read `data/backlog.md`, pick queued items that fit the new scope, and move them with:
183
+
184
+ ```sh
185
+ bin/fm-backlog-handoff.sh <secondmate-id> <item-key>...
186
+ ```
187
+
188
+ After seeding, run this handoff for the new secondmate's in-scope queued items.
189
+ For an existing or inherited domain, complete record intake first so no already-shipped plan row is handed off as open work.
190
+ For a local route, the helper resolves and validates the secondmate home from `data/secondmates.md`, then delegates the item move to `tasks-axi mv` (the single owner of the backlog format), which moves each named item - and a whole connected set, blocker plus dependents, atomically - from the main `data/backlog.md` into the secondmate home's `data/backlog.md`.
191
+ For a remote route, the same helper first moves the dependency-closed set atomically from the main backlog into `data/handoff/<id>.outbox.md`, then transfers that backlog-format outbox through `fm-on.sh` and lets the remote home's `fm-backlog-receive.sh` move every not-already-present key under the destination lock.
192
+ After a new local placement or a remote outbox receipt becomes durable, the helper sends one marked routed-work instruction through the receiving secondmate's recorded endpoint; missing or failed delivery makes the command fail loudly with the moved work intact, and the same handoff command retries known-undelivered wake intent without moving an already-present item again.
193
+ An unresolved delivery attempt is never blindly resent.
194
+ For a remote route, the outbox remains until both backlog receipt and receiver wake are confirmed; `--resume-pending` retries unfinished outboxes, while the script header owns its stable wake-correlation recovery state.
195
+ There is no two-phase handoff journal and no tasks-axi release beyond the already-required atomic `mv` capability.
196
+ Bootstrap retries pending outboxes when mutation is authorized and emits `SECONDMATE_HANDOFF:` for any that remain.
197
+ This delegated route remains required when `config/backlog-backend=manual`, which controls only routine firstmate backlog edits.
198
+ It moves each queued item's whole block - the `- [ ] <id> ...` header plus every following two-or-more-space-indented body line and blank separator, up to the next item or column-0 section heading - byte-exact under the same section, treating an indented `## ...` line as body rather than a section boundary, so neither the header nor its body is duplicated or orphaned.
199
+ It refuses a selected item with a single-space or tab-indented continuation rather than risk leaving content orphaned in the main backlog.
200
+ It accepts in-scope `## Queued` entries only and refuses `## In flight` and historical `## Done` entries.
201
+ Done records stay with their home for pruning or archiving.
202
+ It is idempotent; an item already in the secondmate backlog is skipped.
203
+ After a successful move it warns for any moved key that still owes a public relay reply bound to `main/<key>`, because that binding no longer names the home owning the work; rebind the commitment to `secondmate:<id>` through the `fmx-respond` promised-final procedure, which owns those commands.
204
+ That same rule governs routing generally: a Relay-linked request whose work goes to a secondmate cannot use the home-local mention link at all and needs a promised-final commitment bound to that secondmate's home.
205
+ It refuses any destination that is not a genuine seeded firstmate home with safe operational directories and a matching `.fm-secondmate-home` marker, so a move can never land in a project.
206
+ Do not hand off `local-only` items.
207
+
208
+ ## Recovery
209
+
210
+ For local `kind=secondmate` meta with no window, treat the secondmate as a dead persistent direct report and respawn it with:
211
+
212
+ ```sh
213
+ bin/fm-spawn.sh <id> --secondmate
214
+ ```
215
+
216
+ Use the recorded `home=` in meta.
217
+ If meta is missing but `data/secondmates.md` still registers the secondmate, respawn from the registry entry and its persistent home.
218
+ For a remote route, the same command probes and relaunches only on the configured host.
219
+ An SSH transport failure or unreadable remote endpoint remains unknown and must be reconciled on that host; never launch a local replacement.
220
+ `stuck-crewmate-recovery`'s remote-secondmate note owns why the endpoint-dead and send-failed verdicts that seem to justify this are themselves unreliable.
221
+ Respawn re-resolves the secondmate harness from current config, uses the same guarded pre-launch sync, and re-propagates inherited local material, so recovered secondmates converge inherited config items and shared captain preferences whenever their home validates; tracked-file sync remains guarded separately.
222
+ If the secondmate is already running and only inherited local material changed, prefer `bin/fm-config-push.sh` over respawning.
223
+ To move a live LOCAL secondmate onto a newly pinned harness, model, or effort without a full recovery, set `config/secondmate-harness` and then relaunch it with `bin/fm-control.sh <id> relaunch`, which re-resolves that pin, stops the agent, and launches the replacement in the same home ([`.agents/skills/eindri-homes/assets/control-plane.md`](../../../.agents/skills/eindri-homes/assets/control-plane.md)).
224
+ That plane refuses a remotely placed secondmate by name, because its agent runs on another host where none of the plane's postconditions can be read; use the remote route's own relaunch path for those.
225
+
226
+ Do not reconstruct a secondmate's whole tree from the main home.
227
+ The main firstmate reconciles only direct reports.
228
+ Each secondmate is a firstmate in its own home, so it runs recovery on startup and reconciles its own crewmates.
229
+ A secondmate's recovery reconciles only work that is already its own and then idles.
230
+ It never initiates a survey or audit during recovery.
231
+
232
+ ## Retirement and teardown
233
+
234
+ A secondmate is persistent by default.
235
+ An empty queue is healthy and does not trigger teardown.
236
+ Run `bin/fm-teardown.sh <id>` for `kind=secondmate` only when the captain or main firstmate explicitly decides to retire that persistent second mate.
237
+
238
+ The safety check is the secondmate's own home.
239
+ Teardown refuses while its `state/*.meta` contains in-flight work.
240
+ A remote route delegates the same guard to its configured host and additionally refuses while the primary has a pending handoff outbox or unresolved routed reply.
241
+ SSH exit 255 preserves the route and local records because remote completion is unknown.
242
+ When safe, teardown kills the direct endpoint, removes the `data/secondmates.md` route, clears the main home metadata, and removes the retired secondmate home.
243
+ Removing a leased home releases its durable treehouse lease via `treehouse return`, so the pool slot is freed for reuse rather than left leased forever.
244
+ A plain-clone home with no pool slot is simply removed.
245
+ If `treehouse return` fails for a leased home, teardown stops with state intact rather than raw-removing the directory and hiding a held lease.
246
+ Before either return or direct removal, teardown asks the target home's process-event runner to retire its registrations and physically owned machine-wide claims through the safe generation-bound path.
247
+ It refuses retirement while that cleanup is uncertain or unavailable, preserving the home and retirement records for a later retry.
248
+ Raw deletion is unsupported because a blocking process-event child can outlive its home.
249
+
250
+ With `--force`, teardown is the explicit discard path.
251
+ It kills child windows, discards child work and state inside the secondmate home, removes the route, releases the lease, and removes the retired secondmate home.
252
+ If forced teardown contends with a fresh task publication in any affected home, one command refuses without publishing or removing task state; treat that refusal as terminal and inspect the other operation before retrying.
253
+ Relaunch and non-forced teardown remain outside that serialization.
254
+ Never use `--force` unless the captain explicitly said to discard the work.