@yemi33/minions 0.1.2424 → 0.1.2425

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 (182) hide show
  1. package/bin/install-internal-minions.js +1209 -0
  2. package/bin/minions.js +75 -9
  3. package/dashboard/docs/typography.md +27 -12
  4. package/dashboard/js/command-center.js +13 -11
  5. package/dashboard/js/live-stream.js +1 -1
  6. package/dashboard/js/memory-search.js +388 -43
  7. package/dashboard/js/modal-qa.js +5 -5
  8. package/dashboard/js/qa.js +39 -26
  9. package/dashboard/js/refresh.js +37 -18
  10. package/dashboard/js/render-agents.js +14 -18
  11. package/dashboard/js/render-dispatch.js +14 -74
  12. package/dashboard/js/render-inbox.js +3 -3
  13. package/dashboard/js/render-meetings.js +8 -8
  14. package/dashboard/js/render-other.js +45 -20
  15. package/dashboard/js/render-pipelines.js +6 -6
  16. package/dashboard/js/render-plans.js +14 -14
  17. package/dashboard/js/render-prd.js +46 -46
  18. package/dashboard/js/render-prs.js +9 -65
  19. package/dashboard/js/render-schedules.js +5 -5
  20. package/dashboard/js/render-skills.js +6 -6
  21. package/dashboard/js/render-utils.js +4 -4
  22. package/dashboard/js/render-watches.js +4 -16
  23. package/dashboard/js/render-work-items.js +95 -107
  24. package/dashboard/js/settings.js +175 -74
  25. package/dashboard/layout.html +3 -2
  26. package/dashboard/pages/inbox.html +1 -1
  27. package/dashboard/pages/work.html +1 -1
  28. package/dashboard/shared/model-display.js +9 -0
  29. package/dashboard/shared/watches-source.js +43 -0
  30. package/dashboard/shared/welcome-popup.js +259 -0
  31. package/dashboard/slim/body.html +6 -6
  32. package/dashboard/slim/js/chat.js +4 -2
  33. package/dashboard/slim/js/history.js +10 -3
  34. package/dashboard/slim/js/modals-tiles.js +85 -16
  35. package/dashboard/slim/js/status.js +12 -16
  36. package/dashboard/slim/styles.css +24 -4
  37. package/dashboard/styles.css +62 -27
  38. package/dashboard-build.js +8 -2
  39. package/dashboard.js +3854 -2514
  40. package/docs/README.md +6 -4
  41. package/docs/api-errors.md +144 -0
  42. package/docs/auto-discovery.md +83 -61
  43. package/docs/capture-demos.js +173 -30
  44. package/docs/command-center.md +5 -1
  45. package/docs/completion-reports.md +127 -11
  46. package/docs/constants.md +15 -3
  47. package/docs/constellation-style-telemetry.md +2 -2
  48. package/docs/copilot-cli-schema.md +32 -22
  49. package/docs/cross-repo-plans.md +30 -30
  50. package/docs/demo/memory-system.html +1 -1
  51. package/docs/deprecated.json +132 -18
  52. package/docs/diagnostics-memory.md +8 -4
  53. package/docs/human-vs-automated.md +2 -2
  54. package/docs/internal-install.md +190 -0
  55. package/docs/kb-pr3223-cascade-archiving.md +16 -0
  56. package/docs/kb-pr696-merge-conflict-docs.md +23 -0
  57. package/docs/kb-sweep.md +2 -2
  58. package/docs/keep-processes.md +8 -1
  59. package/docs/live-checkout-mode.md +1 -1
  60. package/docs/managed-spawn.md +21 -3
  61. package/docs/named-agents.md +3 -2
  62. package/docs/plan-lifecycle.md +32 -32
  63. package/docs/pr-screenshots/pr-899/worker-pool-worktrees-AFTER.png +0 -0
  64. package/docs/pr-screenshots/pr-899/worker-pool-worktrees-BEFORE.png +0 -0
  65. package/docs/pr-screenshots/pr-979/auto-fix-pane-AFTER.png +0 -0
  66. package/docs/pr-screenshots/pr-979/auto-fix-pane-BEFORE.png +0 -0
  67. package/docs/pr-screenshots/pr-985/pr-column-em-dash-AFTER.png +0 -0
  68. package/docs/pr-screenshots/pr-985/pr-column-em-dash-BEFORE.png +0 -0
  69. package/docs/qa-runbook-lifecycle.md +67 -51
  70. package/docs/qa-runbooks.md +2 -2
  71. package/docs/runtime-adapters.md +101 -50
  72. package/docs/security.md +28 -0
  73. package/docs/self-improvement.md +47 -13
  74. package/docs/skills.md +29 -0
  75. package/docs/slim-ux/concepts.md +2 -2
  76. package/docs/specs/agent-configurability.md +43 -41
  77. package/docs/specs/agent-rename.md +13 -13
  78. package/docs/team-memory.md +283 -14
  79. package/docs/tutorials/03-plan-driven-feature.md +3 -3
  80. package/docs/tutorials/04-runtimes-and-harness.md +18 -21
  81. package/docs/tutorials/08-operations-and-recovery.md +3 -2
  82. package/docs/tutorials/README.md +4 -3
  83. package/docs/visual-evidence-ci.md +103 -0
  84. package/docs/watches.md +35 -30
  85. package/docs/worktree-lifecycle.md +151 -13
  86. package/engine/acp-transport.js +1 -0
  87. package/engine/ado.js +80 -33
  88. package/engine/agent-api-validation.js +571 -0
  89. package/engine/agent-worker-pool.js +7 -6
  90. package/engine/api-contracts/agent-content.js +761 -0
  91. package/engine/api-contracts/cc-ops.js +219 -0
  92. package/engine/api-contracts/config-runtime.js +419 -0
  93. package/engine/api-contracts/core.js +138 -0
  94. package/engine/api-contracts/index.js +506 -0
  95. package/engine/api-contracts/orchestration.js +602 -0
  96. package/engine/api-contracts/pull-requests.js +323 -0
  97. package/engine/api-contracts/qa-process.js +764 -0
  98. package/engine/api-contracts/work-plan-prd.js +494 -0
  99. package/engine/api-validation.js +543 -0
  100. package/engine/cc-api-validation.js +586 -0
  101. package/engine/cc-worker-pool.js +9 -1
  102. package/engine/cleanup.js +393 -271
  103. package/engine/cli.js +65 -7
  104. package/engine/comment-classifier.js +70 -5
  105. package/engine/consolidation.js +123 -5
  106. package/engine/content-api-validation.js +606 -0
  107. package/engine/create-pr-worktree.js +22 -1
  108. package/engine/db/migrations/027-review-learning-lifecycle.js +162 -0
  109. package/engine/dispatch.js +33 -0
  110. package/engine/distribution.js +189 -0
  111. package/engine/execution-model.js +59 -0
  112. package/engine/features.js +12 -0
  113. package/engine/github.js +67 -25
  114. package/engine/harness-context.js +313 -0
  115. package/engine/inbox-store.js +1 -1
  116. package/engine/kb-sweep.js +161 -38
  117. package/engine/keep-process-sweep.js +43 -3
  118. package/engine/lifecycle.js +1066 -165
  119. package/engine/llm.js +4 -0
  120. package/engine/managed-spawn.js +463 -48
  121. package/engine/meeting.js +197 -34
  122. package/engine/memory-retrieval.js +280 -0
  123. package/engine/memory-store.js +821 -38
  124. package/engine/model-discovery.js +17 -3
  125. package/engine/pipeline.js +802 -14
  126. package/engine/plan-prd-validation.js +745 -0
  127. package/engine/playbook.js +206 -17
  128. package/engine/pooled-agent-process.js +6 -1
  129. package/engine/pr-action.js +1 -1
  130. package/engine/pr-issue-validation.js +653 -0
  131. package/engine/pr-resolve.js +75 -13
  132. package/engine/prd-store.js +39 -6
  133. package/engine/preflight.js +7 -2
  134. package/engine/process-utils.js +79 -31
  135. package/engine/projects.js +198 -12
  136. package/engine/promotion.js +371 -0
  137. package/engine/qa-from-prd.js +3 -0
  138. package/engine/qa-process-validation.js +572 -0
  139. package/engine/qa-runbooks.js +41 -37
  140. package/engine/qa-runners/maestro.js +11 -7
  141. package/engine/qa-runners/playwright.js +37 -14
  142. package/engine/qa-runners.js +9 -10
  143. package/engine/qa-runs.js +124 -11
  144. package/engine/qa-sessions.js +139 -40
  145. package/engine/quarantine-refs.js +81 -11
  146. package/engine/queries.js +163 -9
  147. package/engine/review-learning-backfill.js +482 -0
  148. package/engine/review-learning.js +1236 -0
  149. package/engine/runtimes/claude.js +60 -2
  150. package/engine/runtimes/codex.js +57 -16
  151. package/engine/runtimes/contract.js +21 -0
  152. package/engine/runtimes/copilot.js +51 -3
  153. package/engine/runtimes/index.js +1 -0
  154. package/engine/scheduler.js +201 -32
  155. package/engine/settings-validation.js +909 -0
  156. package/engine/shared.js +705 -208
  157. package/engine/spawn-agent.js +48 -21
  158. package/engine/steering-constraints.js +31 -0
  159. package/engine/steering-store.js +10 -2
  160. package/engine/steering.js +14 -2
  161. package/engine/timeout.js +404 -111
  162. package/engine/untrusted-fence.js +24 -10
  163. package/engine/watch-actions.js +7 -2
  164. package/engine/watches.js +353 -51
  165. package/engine/work-item-validation.js +561 -0
  166. package/engine/work-items-store.js +61 -1
  167. package/engine/worktree-gc.js +656 -37
  168. package/engine/worktree-preflight.js +154 -0
  169. package/engine.js +2068 -342
  170. package/package.json +1 -1
  171. package/playbooks/_pr-description-audit.md +88 -41
  172. package/playbooks/build-fix-complex.md +3 -3
  173. package/playbooks/docs.md +2 -2
  174. package/playbooks/fix.md +18 -18
  175. package/playbooks/implement.md +18 -18
  176. package/playbooks/qa-session-draft.md +10 -12
  177. package/playbooks/qa-session-execute.md +16 -12
  178. package/playbooks/qa-validate.md +8 -7
  179. package/playbooks/shared-rules.md +45 -0
  180. package/playbooks/test.md +4 -0
  181. package/prompts/cc-system.md +1 -1
  182. package/skills/check-self-authored-review-comment/SKILL.md +2 -2
@@ -92,16 +92,16 @@ When `notes.md` exceeds 50KB, the engine trims it to the cap (keeping the header
92
92
 
93
93
  ## 2. Per-Agent History
94
94
 
95
- Each agent maintains a `history.md` file that tracks its last 20 tasks. This is injected into the agent's system prompt so it knows what it did recently.
95
+ Each agent's `history.md` retains its last 20 tasks. To bound prompt size, `engine/playbook.js` injects only the five most recent retained entries into the next dispatch.
96
96
 
97
97
  ### Flow
98
98
 
99
99
  ```
100
100
  Agent finishes task
101
101
  → engine calls updateAgentHistory()
102
- → prepends entry to agents/<name>/history.md
102
+ → prepends entry to agents/<id>/history.md
103
103
  → trims to 20 entries
104
- → next time agent spawns: history.md injected into system prompt
104
+ → next time agent spawns: 5 retained entries injected into the prompt
105
105
  ```
106
106
 
107
107
  ### What's tracked per entry
@@ -161,6 +161,40 @@ in the future, avoid the patterns flagged here.
161
161
 
162
162
  Without this, review findings only exist in the inbox file under the reviewer's name. The author never explicitly sees them unless they happen to read the consolidated notes.md. The feedback loop ensures the author gets a direct, targeted learning from every review.
163
163
 
164
+ ### 3a. Structured review learning (durable, opt-in)
165
+
166
+ The narrative feedback file above is per-PR and consolidated into free-text notes.
167
+ **Review learning** is its durable, structured evolution: a verified reviewer
168
+ finding becomes a bounded, project-scoped procedural *lesson* that a later,
169
+ lexically unrelated dispatch touching the same file or symbol recalls
170
+ deterministically. It is fully specified in
171
+ [team-memory.md](team-memory.md#review-learning-lifecycle-storage); the essentials:
172
+
173
+ - **Trust & taxonomy.** Lessons carry `source_type: review-learning`, system trust,
174
+ and a stable finding key `<project>|<canonical-pr-id>|<host-namespaced-source-key>`.
175
+ They are globally excluded from generic FTS recall and only surface through the
176
+ dedicated project-scoped path.
177
+ - **Capture.** With `review-learning-capture` on, only a completed Minions
178
+ `changes-requested` verdict creates an unresolved *candidate*; a verified
179
+ `accepted-fixed` / `satisfied-elsewhere` disposition promotes it to one active
180
+ lesson. Invalid/stale/deferred close or hold the candidate.
181
+ - **Recall.** With `review-learning-recall` on, a dispatch with a resolved project
182
+ recalls up to 4 records / 4 KiB as a separately fenced `## Applicable Prior Review
183
+ Lessons` section, ranked by exact symbol → file → tag overlap.
184
+ - **Application, correction, supersession.** Agents report `applied` /
185
+ `considered-not-applicable` / `contradicted` outcomes for lessons their trusted
186
+ retrieval trace showed them; an evidence-backed contradiction quarantines the
187
+ lesson. Changed rule content supersedes the prior active version, leaving at most
188
+ one active lesson per finding key.
189
+ - **Promotion.** A high-confidence, repeatedly observed lesson can be human-promoted
190
+ into repository guidance (`CLAUDE.md` / `AGENTS.md` / Copilot instructions or a
191
+ project skill) via a normal PR — never by editing a checkout.
192
+ - **Diagnostics, retention & rollback.** Retrieval decisions, a lifecycle timeline,
193
+ rollout aggregates, and the staged-rollout comparison are exposed under
194
+ `/api/memory-records/*`. Both flags default off and expire 2027-01-31; disabling
195
+ recall is a complete prompt rollback (see
196
+ [team-memory.md → Staged rollout and acceptance](team-memory.md#staged-rollout-and-acceptance)).
197
+
164
198
  ## 4. Human Feedback on PRs
165
199
 
166
200
  Humans can leave actionable comments on ADO or GitHub PRs to trigger fix tasks;
@@ -196,8 +230,9 @@ The engine tracks per-agent performance metrics in the SQL metrics store. It upd
196
230
 
197
231
  | Metric | Updated when |
198
232
  |--------|-------------|
199
- | `tasksCompleted` | Agent exits with code 0 |
200
- | `tasksErrored` | Agent exits with non-zero code |
233
+ | `tasksCompleted` | Lifecycle records a final `DISPATCH_RESULT.SUCCESS` |
234
+ | `tasksRetried` | A non-terminal failure is auto-requeued |
235
+ | `tasksErrored` | Lifecycle records a terminal non-success result |
201
236
  | `prsCreated` | Agent completes an implement task |
202
237
  | `prsApproved` | Reviewer approves the agent's PR |
203
238
  | `prsRejected` | Reviewer requests changes on the agent's PR |
@@ -223,10 +258,9 @@ Metrics:
223
258
  lambert 2 0 0 0 (-) 0 4
224
259
  ```
225
260
 
226
- ### Future use
261
+ ### Current and future use
227
262
 
228
- Metrics are currently informational — displayed in status and dashboard. Planned uses:
229
- - **Routing adaptation:** If an agent's approval rate drops below a threshold, deprioritize them for implementation tasks
263
+ Metrics are displayed in status and the dashboard, and task error rate already affects routing: `_any_` and any-idle fallback/reservation paths choose the eligible agent with the lowest `tasksErrored / (tasksCompleted + tasksErrored)` rate. Approval-rate routing is not implemented. Potential future uses:
230
264
  - **Auto-escalation:** If an agent errors 3 times in a row, pause their dispatch and alert
231
265
  - **Capacity planning:** Track throughput per agent to optimize `maxConcurrent`
232
266
 
@@ -247,10 +281,10 @@ Metrics are currently informational — displayed in status and dashboard. Plann
247
281
  │ tasks) │ │ │
248
282
  └──────────┘ │ on completion │ consolidateInbox()
249
283
  ▲ ▼ ▼
250
- │ ┌──────────────────┐ ┌──────────┐
251
- └─updateHistory───│ Engine │─prune──→│decisions
252
- │ post-hooks │ │ .md │
253
- └────────┬─────────┘ └──────────┘
284
+ │ ┌──────────────────┐
285
+ └─updateHistory───│ Engine │
286
+ │ post-hooks │
287
+ └────────┬─────────┘
254
288
 
255
289
  ┌───────────┼───────────┐
256
290
  ▼ ▼ ▼
@@ -324,6 +358,6 @@ The canonical block format, fields, and eligibility threshold live in
324
358
  | `notes/inbox/*.md` | Agent findings drop-box | Agents |
325
359
  | `notes/archive/*.md` | Archived inbox files | Engine (consolidation) |
326
360
  | `notes.md` | Accumulated team knowledge | Engine (consolidation) |
327
- | `agents/<name>/history.md` | Per-agent task history | Engine (post-completion) |
361
+ | `agents/<id>/history.md` | Per-agent task history | Engine (post-completion) |
328
362
  | `engine/state.db` `metrics` | Quality metrics per agent | Engine (post-completion + review) |
329
363
  | `notes/inbox/feedback-*.md` | Review feedback for authors | Engine (post-review) |
package/docs/skills.md CHANGED
@@ -43,3 +43,32 @@ Plain Markdown. Include the steps, commands, file paths, and notes another agent
43
43
  ## When not to emit a skill
44
44
 
45
45
  See [`playbooks/shared-rules.md`](../playbooks/shared-rules.md) for the full threshold. In short: do not emit a skill for one-off bug fixes, isolated command output, obvious repo facts, or anything already covered by existing docs, playbooks, or skills.
46
+
47
+ ## Human-approved promotion of review lessons (P-192d3660)
48
+
49
+ Verified **review lessons** captured in structured memory (`sourceType: review-learning`,
50
+ `memoryType: procedural`) can be promoted into durable repository guidance so vanilla
51
+ Copilot/Claude pick them up through native instruction/skill discovery. Promotion is an
52
+ **operator-only** action in the dashboard **Structured Memory** modal — it never edits a
53
+ checkout. It queues a normal project-bound work item that follows the usual branch → PR →
54
+ review → merge lifecycle.
55
+
56
+ - **Eligibility** (`engine/promotion.js#evaluateLessonPromotionEligibility`): the lesson must be
57
+ `active`, high-confidence (`confidence >= 0.8`), and backed by **at least two distinct valid
58
+ findings** (its own finding plus repeated-finding recurrences, counted by
59
+ `memory-store.js#getReviewLearningFindingSupport`). The search API annotates eligible lessons
60
+ with a `repoPromotion` object; the modal shows a **Promote to repo** button only for those.
61
+ - **Targets**: the operator confirms a project and either
62
+ - `project-skill` — a lowercase kebab-case slug queued as an `implement` work item that creates
63
+ `<slug>/SKILL.md` (the runtime's native skill root); or
64
+ - `repository-instruction` — an allowlisted file (`CLAUDE.md`, `AGENTS.md` at any depth, or
65
+ `.github/copilot-instructions.md`) queued as a `docs` work item.
66
+ - **Queueing** goes through `engine/promotion.js#queuePromotion`, which reuses the same
67
+ project-bound work-item queueing extracted from `lifecycle.js#extractSkillsFromOutput`
68
+ (`queueProjectSkillWorkItem`). The queued work item cites the stable originating memory IDs, the
69
+ bounded proposed rule(s), and the target project/path in `meta.promotion`.
70
+ - **API**: `POST /api/memory-records/<id>/promote` with `{ targetKind, project, path }`. Repeated
71
+ clicks are deduplicated on `meta.promotion.dedupeKey`; the endpoint returns the existing
72
+ work-item id (`duplicate: true`) instead of queueing a second item. A `promotion-requested`
73
+ lifecycle event links the memory → target → work item (and, via the work item's normal PR
74
+ linkage, the eventual PR).
@@ -681,7 +681,7 @@ work sources.
681
681
  `checkoutMode: "worktree"` is the default isolated execution model.
682
682
  `checkoutMode: "live"` opts a project into guarded in-place execution.
683
683
 
684
- **Existing dashboard.** `dashboard/pages/settings.html` owns project onboarding and removal.
684
+ **Existing dashboard.** `dashboard/js/settings.js` owns project onboarding and removal.
685
685
 
686
686
  **Endpoints.**
687
687
 
@@ -828,7 +828,7 @@ MCP/skill configuration remain owned and discovered by the selected CLI.
828
828
  - Settings handlers: `dashboard.js#handleSettingsRead`, `#handleSettingsUpdate`,
829
829
  `#handleSettingsReset`, and `#handleSettingsRouting`
830
830
 
831
- **Existing dashboard.** `dashboard/pages/settings.html` is the canonical settings surface.
831
+ **Existing dashboard.** `dashboard/js/settings.js` is the canonical settings surface.
832
832
 
833
833
  **Endpoints.**
834
834
 
@@ -1,15 +1,17 @@
1
1
  # Spec: Agent & Role Configurability
2
2
 
3
- **Status:** Draft
3
+ **Status:** Draft (Phase 0b shipped; remaining phases unimplemented)
4
4
  **Owner:** @calebt
5
5
  **Audience:** Minions contributors working on the dashboard, engine config surface, and playbook/system-prompt rendering.
6
6
  **Depends on:** [`agent-rename.md`](agent-rename.md) — a **hard prerequisite**. That spec delivers the "names aren't load-bearing" foundation (stable opaque agent **id**, name-agnostic charters, and the agent rename capability) that this Library builds on. The decoupling sections below (§2.8, §4.1a, §4.3c, §5.4) are **summaries that defer to `agent-rename.md`** for the full treatment.
7
7
 
8
8
  > Companion reading: [`.github/copilot-instructions.md`](../../.github/copilot-instructions.md) and [`CLAUDE.md`](../../CLAUDE.md) for the engine/dashboard split, config conventions, and the feature-flag registry.
9
+ >
10
+ > **Implementation status (2026-07-19):** Phase 0b (`skills` → `expertise`) has shipped. `expertise` is canonical and `skills` remains a read-compat alias tracked in [`docs/deprecated.json`](../deprecated.json). The Role / Agent Library, role model, CRUD, and `agent-library` feature flag remain unimplemented.
9
11
 
10
12
  ## 1. Motivation
11
13
 
12
- Today a Minions "team" is a fixed roster of five hard-coded agents (`ripley`, `dallas`, `lambert`, `rebecca`, `ralph`) whose personas live in a mix of places: a free-text `role` string in `config.json`, a loosely-related `skills` string array, and a per-agent `charter.md` file. The charter — the real persona — is **per-agent**, so there is no reusable notion of "what it means to be an Engineer." There is **no way to**:
14
+ Today a Minions "team" is a fixed roster of five hard-coded agents (`ripley`, `dallas`, `lambert`, `rebecca`, `ralph`) whose personas live in a mix of places: a free-text `role` string in `config.json`, an `expertise` string array, and a per-agent `charter.md` file. The charter — the real persona — is **per-agent**, so there is no reusable notion of "what it means to be an Engineer." There is **no way to**:
13
15
 
14
16
  - See an agent's full definition (role charter + expertise + runtime) in one place.
15
17
  - Treat a "role" as a reusable, editable unit (a durable charter shared across agents) — it is just a label string today.
@@ -23,7 +25,7 @@ The goal is to make the fleet **user-configurable** through a **Role / Agent Lib
23
25
 
24
26
  Phases:
25
27
 
26
- - **Phase 0 — Prerequisite migrations.** Establish the feature flag and rename the misnamed `skills` field to `expertise`. (The stable-id formalization and name-agnostic charters are delivered by the **[`agent-rename.md`](agent-rename.md) prerequisite**, which must land first.) All additive + flag-aware.
28
+ - **Phase 0 — Prerequisite migrations.** Phase 0b (`skills` `expertise`) is shipped; Phase 0a still establishes the feature flag. (The stable-id formalization and name-agnostic charters are delivered by the **[`agent-rename.md`](agent-rename.md) prerequisite**, which must land first.) All additive + flag-aware.
27
29
  - **Phase 1 — Expose & edit.** Surface each role's durable charter + each agent's variable expertise in one editable library view; the agent **rename** capability comes from the prerequisite and is surfaced inline here. No new roles or agents yet.
28
30
  - **Phase 2 — Create & assign.** Add new roles, and stand up new named agents bound to a role.
29
31
 
@@ -33,16 +35,16 @@ This section is the factual baseline the design must respect. Citations are `fil
33
35
 
34
36
  ### 2.1 Agent object — already id-keyed
35
37
 
36
- Agents live under `config.agents` keyed by a **stable lowercase id** (the object key). `name` is a **separate display field** — there is no explicit `id` field inside the object; the key *is* the id, and `getAgents()` materializes it as `{ id, ...info }` (`engine/queries.js:681-687`). Defaults are hard-coded:
38
+ Agents live under `config.agents` keyed by a **stable lowercase id** (the object key). `name` is a **separate display field** — there is no explicit `id` field inside the object; the key *is* the id, and `getAgents()` materializes it as `{ id, ...info }` (`engine/queries.js:764-845`). Defaults are hard-coded:
37
39
 
38
40
  ```js
39
- // engine/shared.js:4398-4404
41
+ // engine/shared.js:4728-4734
40
42
  const DEFAULT_AGENTS = {
41
- ripley: { name: 'Ripley', emoji: '🏗️', role: 'Lead / Explorer', skills: ['architecture', 'codebase-exploration', 'design-review'] },
42
- dallas: { name: 'Dallas', emoji: '🔧', role: 'Engineer', skills: ['implementation', 'typescript', 'docker', 'testing'] },
43
- lambert: { name: 'Lambert', emoji: '📊', role: 'Analyst', skills: ['gap-analysis', 'requirements', 'documentation'] },
44
- rebecca: { name: 'Rebecca', emoji: '🧠', role: 'Architect', skills: ['system-design', 'api-design', 'scalability', 'implementation'] },
45
- ralph: { name: 'Ralph', emoji: '⚙️', role: 'Engineer', skills: ['implementation', 'bug-fixes', 'testing', 'scaffolding'] },
43
+ ripley: { name: 'Ripley', emoji: '🏗️', role: 'Lead / Explorer', expertise: ['architecture', 'codebase-exploration', 'design-review'] },
44
+ dallas: { name: 'Dallas', emoji: '🔧', role: 'Engineer', expertise: ['implementation', 'typescript', 'docker', 'testing'] },
45
+ lambert: { name: 'Lambert', emoji: '📊', role: 'Analyst', expertise: ['gap-analysis', 'requirements', 'documentation'] },
46
+ rebecca: { name: 'Rebecca', emoji: '🧠', role: 'Architect', expertise: ['system-design', 'api-design', 'scalability', 'implementation'] },
47
+ ralph: { name: 'Ralph', emoji: '⚙️', role: 'Engineer', expertise: ['implementation', 'bug-fixes', 'testing', 'scaffolding'] },
46
48
  };
47
49
  ```
48
50
 
@@ -52,29 +54,29 @@ Runtime / budget fields are **optional per-agent overrides** resolved against `e
52
54
 
53
55
  | Field | Resolver | Falls back to |
54
56
  |-------|----------|---------------|
55
- | `cli` | `resolveAgentCli` (shared.js:3142) | `engine.defaultCli` → `'copilot'` |
56
- | `model` | `resolveAgentModel` (shared.js:3202) | `engine.defaultModel` → undefined |
57
- | `maxBudgetUsd` / `monthlyBudgetUsd` | `resolveAgentMaxBudget` (shared.js:3231) | `engine.maxBudgetUsd` |
58
- | `bareMode` | `resolveAgentBareMode` (shared.js:3254) | `engine.claudeBareMode` → false |
57
+ | `cli` | `resolveAgentCli` (shared.js:3561) | `engine.defaultCli` → `'copilot'` |
58
+ | `model` | `resolveAgentModel` (shared.js:3672) | `engine.defaultModel` → undefined |
59
+ | `maxBudgetUsd` / `monthlyBudgetUsd` | `resolveAgentMaxBudget` (shared.js:3711) | `engine.maxBudgetUsd` |
60
+ | `bareMode` | `resolveAgentBareMode` (shared.js:3734) | `engine.claudeBareMode` → false |
59
61
 
60
62
  ### 2.2 "Role" is a label, not an entity
61
63
 
62
- `role` is a **free-text string** on the agent. There is no role registry, no role schema, and routing does **not** reference roles — it references agent ids. The dashboard edits role as a plain text input (`dashboard/js/settings.js:72`) and persists it verbatim (`dashboard.js:10684`).
64
+ `role` is a **free-text string** on the agent. There is no role registry, no role schema, and routing does **not** reference roles — it references agent ids. The dashboard edits role as a plain text input (`dashboard/js/settings.js:72`) and persists it verbatim (`dashboard.js:11242-11244`).
63
65
 
64
- ### 2.3 `skills` is *expertise*, not real skills
66
+ ### 2.3 `expertise` metadata is distinct from executable skills
65
67
 
66
- Two unrelated things share the word "skill" today, and the `agent.skills` field is the **misnamed** one:
68
+ Two unrelated concepts previously shared the word "skill"; Phase 0b made `agent.expertise` canonical while retaining `agent.skills` as a compatibility alias:
67
69
 
68
- 1. **`agent.skills`** — a string array of **expertise tags**. It is *not* linked to any executable capability or on-disk skill file. It has exactly two readers:
69
- - **Display:** rendered as the `Expertise: …` line in the system prompt (`engine/playbook.js:950`).
70
- - **Soft routing:** `pickReReviewAgentHints()` (`engine/lifecycle.js:4613-4624`) scans `agent.skills` for the tags `code-review` / `design-review` to *prefer* (not require) that agent for re-review. This is the one functional consumer — a rename must update it too, not just the display line.
71
- 2. **Real `SKILL.md` files** — discovered from disk (`.claude/skills/`, `~/.claude/skills`, project harness dirs) by `collectSkillFiles()` / `getSkills()` (`engine/queries.js:1263-1400`), scoped global/project/plugin. These are **not** bound to a specific agent or role; every agent sees the same discovered catalog, and `agent.skills` has **no relationship** to them.
70
+ 1. **`agent.expertise`** — a string array of descriptive expertise tags. It is *not* linked to any executable capability or on-disk skill file. Readers tolerate legacy configs with `agent.expertise ?? agent.skills`:
71
+ - **Display:** the `Expertise: …` line in the system prompt (`engine/playbook.js:1094`).
72
+ - **Soft routing:** `pickReReviewAgentHints()` (`engine/lifecycle.js:5311-5321`) prefers agents tagged `code-review` / `design-review`.
73
+ 2. **Real `SKILL.md` files** — discovered from disk by `collectSkillFiles()` / `getSkills()` (`engine/queries.js:1363-1498`), scoped global/project/plugin. These are **not** bound to a specific agent or role; every agent sees the same discovered catalog, and expertise metadata has **no relationship** to them.
72
74
 
73
- Because `agent.skills` is purely expertise metadata (plus a soft reviewer hint), the field is misnamed. **Phase 0b renames it `expertise`** to remove the overload and free the word "skills" for any future real-skill binding (§8).
75
+ The canonical rename has shipped. The legacy alias remains only for compatible reads until the removal gate in `docs/deprecated.json` clears.
74
76
 
75
77
  ### 2.4 Charter = the real "agent definition"
76
78
 
77
- The substantive persona/instructions for an agent is `agents/<id>/charter.md`, read by `getAgentCharter()` (`engine/queries.js:677-678`) and injected into the system prompt as `## Your Charter` (`engine/playbook.js:942-954`). The system prompt assembled in `buildSystemPrompt()` is:
79
+ The substantive persona/instructions for an agent is `agents/<id>/charter.md`, served by `getAgentDetail()` (`engine/queries.js:847-850`) and read directly by `buildSystemPrompt()` before injection as `## Your Charter` (`engine/playbook.js:1084-1099`). The system prompt is:
78
80
 
79
81
  ```
80
82
  # You are {name} ({role})
@@ -84,7 +86,7 @@ Expertise: {expertise joined}
84
86
  ## Your Charter
85
87
  {charter.md contents}
86
88
  ```
87
- (`engine/playbook.js:940-955`)
89
+ (`engine/playbook.js:1084-1099`)
88
90
 
89
91
  Charter is already editable today, but only from the **agent detail panel → Charter tab** (`dashboard/js/detail-panel.js:115-126`) via `POST /api/agents/charter` (`dashboard.js:13205-13211`). It is disconnected from the Settings → Agents table.
90
92
 
@@ -97,9 +99,9 @@ Charter is already editable today, but only from the **agent detail panel → Ch
97
99
  ### 2.6 Config read / write surface
98
100
 
99
101
  - **Read:** `queries.getConfig()` (`engine/queries.js:181-225`); Settings read endpoint returns `{ engine, claude, agents, projects, routing }` (`dashboard.js:10362-10391`).
100
- - **Write:** `POST /api/settings` edits `engine`, `claude`, **existing** `agents[id]` (role, skills, cli, model, budget — `dashboard.js:10682-10705`; **note: `name` is NOT editable today**), and projects, then saves `config.json`. **There is no agent create/delete/rename path** — the loop `for (const [id, updates] of Object.entries(body.agents))` skips unknown ids (`dashboard.js:10683`).
101
- - **Reset:** restores `engine` defaults + `shared.DEFAULT_AGENTS` (`dashboard.js:10808-10815`).
102
- - **UI:** Settings → Runtime pane has an **edit-only** Agents table (Role, Skills, CLI, Model, Budget) — `dashboard/js/settings.js:152-157`. No add/remove/rename.
102
+ - **Write:** `POST /api/settings` edits `engine`, `claude`, **existing** `agents[id]` (role, expertise, cli, model, budget — `dashboard.js:11242-11262`; **note: `name` is NOT editable today**), and projects, then saves `config.json`. Legacy `skills` input is normalized to `expertise`; unknown ids are skipped.
103
+ - **Reset:** restores `engine` defaults + `shared.DEFAULT_AGENTS` (`dashboard.js:11434-11440`).
104
+ - **UI:** Settings → Runtime pane has an **edit-only** Agents table (Role, Expertise, CLI, Model, Budget). No add/remove/rename.
103
105
 
104
106
  ### 2.7 Gaps summary
105
107
 
@@ -110,7 +112,7 @@ Charter is already editable today, but only from the **agent detail panel → Ch
110
112
  | Reuse one charter across many agents | ✗ (each agent has its own `charter.md`) |
111
113
  | Edit a role's charter from the library/settings | ✗ (only the per-agent detail panel) |
112
114
  | Rename an agent's display name (+ emoji) | ✗ |
113
- | `expertise` field named for what it is | (called `skills`, overloaded) |
115
+ | `expertise` field named for what it is | (`skills` retained only as a read-compat alias) |
114
116
  | Add a new role | ✗ |
115
117
  | Add a new named agent | ✗ |
116
118
  | Delete an agent | ✗ |
@@ -119,7 +121,7 @@ Charter is already editable today, but only from the **agent detail panel → Ch
119
121
 
120
122
  > **Summary — full treatment in [`agent-rename.md`](agent-rename.md) §2.**
121
123
 
122
- Agents are **already id-keyed**: every piece of agent-scoped state (charter file, per-agent memory, metrics, dispatch/PR records, inbox prefixes, routing) is keyed by the immutable `config.agents` **key**, never the display `name`. The only consumers of `name` are `buildSystemPrompt`'s `# You are {name}` line and dashboard display text. So the id is the stable handle the role model relies on (an agent can be renamed or reassigned to a different role without touching any id-keyed state), and it must never be mutated. The rename prerequisite formalizes this invariant with a guard + tests.
124
+ Agents are **already id-keyed**: every piece of agent-scoped state (charter file, per-agent memory, metrics, dispatch/PR records, inbox prefixes, routing) is keyed by the immutable `config.agents` **key**, never the display `name`. The name is used for prompt/dashboard display and soft free-text matching in `resolveTaskContext()`, but never as a persistent key. So the id is the stable handle the role model relies on (an agent can be renamed or reassigned to a different role without touching any id-keyed state), and it must never be mutated. The rename prerequisite formalizes this invariant with a guard + tests.
123
125
 
124
126
  ## 3. Target model: the Role / Agent Library
125
127
 
@@ -227,7 +229,7 @@ Why this matters:
227
229
  - **Rename touches only the per-agent identity** (`name`/`emoji`); neither expertise nor the role charter is affected (§5.4).
228
230
  - **Two agents of one role share the durable charter but differ in the variable expertise.** Dallas and Ralph both resolve the Engineer charter, yet Dallas carries `typescript/docker` and Ralph `bug-fixes/scaffolding` — the payoff of the durable/variable split (§3).
229
231
 
230
- This formalizes what `buildSystemPrompt` already does loosely today (the `# You are {name}` / `Agent ID` / `Expertise` lines are a proto short-form; `engine/playbook.js:947-955`); the spec elevates it to named dimensions. Whether the short-form is rendered as prose lines or an explicit JSON card is an open question (§9).
232
+ This formalizes what `buildSystemPrompt` already does loosely today (the `# You are {name}` / `Agent ID` / `Expertise` lines are a proto short-form; `engine/playbook.js:1092-1099`); the spec elevates it to named dimensions. Whether the short-form is rendered as prose lines or an explicit JSON card is an open question (§9).
231
233
 
232
234
  ## 4. Phase 0 — Prerequisite migrations
233
235
 
@@ -243,17 +245,17 @@ Register `agent-library` (§3.1). No behavior change yet — just the gate other
243
245
 
244
246
  The stable-id invariant (id = immutable key, name = display-only) and its guard + regression tests land in the rename prerequisite. The role model below assumes it: an agent can be reassigned to a different role or renamed without touching any id-keyed state (§2.8).
245
247
 
246
- ### 4.2b Rename `skills` → `expertise`
248
+ ### 4.2b Rename `skills` → `expertise` — shipped
247
249
 
248
250
  `agent.skills` is expertise, not skills (§2.3). Rename the field across the stack, with an **unconditional** back-compat reader:
249
251
 
250
252
  - **Read shim (always on):** everywhere that reads agent expertise resolves `agent.expertise ?? agent.skills`. Old configs with `skills` keep working untouched — no disk rewrite forced. (Expertise is the per-agent **variable** layer, §3.3 — it lives on the agent, not the role.)
251
- - **Writers / defaults:** `DEFAULT_AGENTS` use `expertise`. The Settings write path persists `expertise`; if it sees a legacy `skills` key it may migrate it in-memory (mirroring `applyLegacyCcModelMigration`'s no-rewrite pattern).
252
- - **Update the two readers** named in §2.3: the `Expertise:` line (`engine/playbook.js:950`) and `pickReReviewAgentHints` (`engine/lifecycle.js:4613-4624`) both read the resolved expertise, so the soft reviewer-preference heuristic keeps matching `code-review`/`design-review`.
253
- - **Dashboard:** the Agents table column header and its read/write (`dashboard/js/settings.js:73`, `dashboard.js:10685`) move to `expertise`, accepting `skills` on read for compatibility.
254
- - **Deprecation:** add a `docs/deprecated.json` entry for the `skills` alias with a cleanup path.
253
+ - **Writers / defaults:** `DEFAULT_AGENTS` use `expertise`. The Settings write path accepts legacy `skills`, persists the value as `expertise`, and deletes the old key.
254
+ - **Readers:** the `Expertise:` line (`engine/playbook.js:1094`), `pickReReviewAgentHints` (`engine/lifecycle.js:5311-5321`), and `getAgents` (`engine/queries.js:830-832`) all prefer `expertise` and tolerate `skills`.
255
+ - **Dashboard:** the Agents table uses `expertise` (`dashboard/js/settings.js:73`); settings writes normalize legacy `skills` input to `expertise` (`dashboard.js:11245-11252`).
256
+ - **Deprecation:** `docs/deprecated.json` tracks the compatibility alias and its removal gate.
255
257
 
256
- This rename is independent of the role model and can ship first; it is pure renaming + a back-compat alias, so it is safe even with the feature flag OFF (the alias is unconditional).
258
+ This rename shipped independently of the role model. Cleanup remains gated by the deprecation tracker; the alias is unconditional while it exists.
257
259
 
258
260
  ### 4.3c Name-agnostic charters — *delivered by the prerequisite*
259
261
 
@@ -276,7 +278,7 @@ All UI/API in this phase is gated by `agent-library` (§3.1). The **rename** cap
276
278
 
277
279
  ### 5.2 Data model (Phase 1)
278
280
 
279
- - Add `DEFAULT_ROLES` to `engine/shared.js`, one per distinct `role` label in `DEFAULT_AGENTS` (`Lead / Explorer`, `Engineer`, `Analyst`, `Architect`). Author each role's **durable `charter`** name-agnostic (§4.3c), seeded from the sanitized union of the corresponding agents' existing `charter.md` files. Each agent's current per-agent skills become its **`expertise`** (the variable layer), so two Engineers keep distinct specializations while sharing one role charter. (Where two agents of the same label have materially different *personas* today, split them into two roles instead — but the default four collapse cleanly.)
281
+ - Add `DEFAULT_ROLES` to `engine/shared.js`, one per distinct `role` label in `DEFAULT_AGENTS` (`Lead / Explorer`, `Engineer`, `Analyst`, `Architect`). Author each role's **durable `charter`** name-agnostic (§4.3c), seeded from the sanitized union of the corresponding agents' existing `charter.md` files. Each agent keeps its current per-agent **`expertise`** (the variable layer), so two Engineers retain distinct specializations while sharing one role charter. (Where two agents of the same label have materially different *personas* today, split them into two roles instead — but the default four collapse cleanly.)
280
282
  - Migrate `agent.role` free-text → role key on first load (in-memory, mirroring `applyLegacyCcModelMigration`'s no-disk-rewrite pattern) by slugifying the label and matching against `roles{}`. Unmatched strings remain legacy free text rendered as an ad-hoc role.
281
283
  - Resolution rules (§3) sit behind the existing resolver helpers and the feature flag so engine behavior is unchanged when `roles` is absent or the flag is OFF.
282
284
 
@@ -319,7 +321,7 @@ The agent **rename** capability (`POST /api/agents/rename` → `{ id, name, emoj
319
321
  ## 6. Migration & backward compatibility
320
322
 
321
323
  - **Feature-flagged & dark by default.** New surfaces are OFF until `agent-library` is enabled (§3.1). Back-compat readers are unconditional so toggling the flag off after edits never breaks a fleet.
322
- - **Additive config.** `roles` (with `charter`) and agent `expertise` are new and optional. Absent ⇒ legacy path (free-text role, `skills`, per-agent `charter.md`). No forced disk rewrite — migration is in-memory at load, matching `applyLegacyCcModelMigration`.
324
+ - **Additive config.** `roles` (with `charter`) is new and optional. Absent ⇒ legacy path (free-text role, per-agent `expertise` with the `skills` read alias, per-agent `charter.md`). No forced role-model disk rewrite — migration is in-memory at load, matching `applyLegacyCcModelMigration`.
323
325
  - **`skills` alias preserved.** Reads resolve `agent.expertise ?? agent.skills`; legacy configs are untouched (§4.2b).
324
326
  - **Charters preserved.** `agents/<id>/charter.md` remains readable as the **lowest-priority** charter source (used only when an agent's role has no charter). `minions init`/upgrade already preserves charter files (`bin/minions.js:1361-1368`) — do not regress that.
325
327
  - **Name decoupling via the prerequisite.** Name-agnostic charters and the stable-id invariant ship in [`agent-rename.md`](agent-rename.md) (§4.1a, §4.3c). This Library assumes them: role charters are shared name-agnostic prose, and agents are reassigned/renamed without re-keying any state. Legacy user charters with names render verbatim (non-breaking).
@@ -383,7 +385,7 @@ Flag-gated like Phase 1.
383
385
  3. **"Charter" terminology** — the spec uses **`charter`** as the durable role-level field name (matching today's `charter.md` and the existing Charter tab). Confirm we keep "charter" user-facing everywhere rather than introducing "definition" as a competing term. *(Tentatively resolved: yes, `charter` on the role; "definition" used only as the generic English word.)*
384
386
  4. **Expertise→skill enrichment (§5.3)** — ship the "tag matches discovered SKILL.md → inline description" behavior in P1, or keep expertise purely as the `Expertise:` line until later?
385
387
  5. **Default role charters** — author fresh name-agnostic role charters, or mechanically sanitize + merge the existing per-agent `charter.md` files? And how to handle two builtin agents sharing a label but differing in persona today (split into two roles vs. unify)?
386
- 6. **`skills`→`expertise` rollout** — ship the §4.2b rename as its own standalone PR (pure rename + alias, flag-independent) ahead of the Library, to de-risk the bigger change?
388
+ 6. **`skills`→`expertise` rollout** — resolved: shipped independently with an unconditional compatibility alias tracked in `docs/deprecated.json`.
387
389
  7. **Identity rendering (§3.3)** — render the per-agent short-form as the existing prose lines (`# You are …` / `Agent ID` / `Expertise`), or also emit a compact machine-readable JSON identity card the agent can parse to reason about itself? (Prose is the lowest-risk default; JSON is additive.)
388
390
 
389
391
  ## 10. Work breakdown (suggested PRD seeds)
@@ -393,7 +395,7 @@ Flag-gated like Phase 1.
393
395
 
394
396
  **Phase 0 — prerequisites (owned here)**
395
397
  - P0-a: Register `agent-library` feature flag (`engine/features.js`) + Settings toggle.
396
- - P0-b: Rename `skills`→`expertise` with unconditional back-compat alias; update `playbook.js:950`, `lifecycle.js:4613-4624`, `dashboard.js`/`settings.js`, `DEFAULT_AGENTS`; `docs/deprecated.json` entry.
398
+ - P0-b: **Shipped** `skills`→`expertise` with an unconditional back-compat alias across playbook, lifecycle, queries, Settings, defaults, and `docs/deprecated.json`.
397
399
 
398
400
  **Phase 1 — expose & edit**
399
401
  - P1-a: `DEFAULT_ROLES` (durable charter per role) + per-agent `expertise` (variable) + in-memory legacy role migration + role-tier resolver (engine/shared.js, playbook.js), flag-gated. Seeds role charters from the prerequisite's sanitized `agents/<id>/charter.md`.
@@ -409,4 +411,4 @@ Flag-gated like Phase 1.
409
411
 
410
412
  ---
411
413
 
412
- _Every new `engine.*`/config surface introduced here must also get a dashboard control and be documented in CLAUDE.md — config without UI is incomplete (see CLAUDE.md "Best Practices" #15). New feature flags follow the FEATURES-registry lifecycle: register with `addedIn`/`expires`, gate, then delete the entry + gates on graduation._
414
+ _Every new `engine.*`/config surface introduced here must also get a dashboard control and be documented in CLAUDE.md — config without UI is incomplete (see CLAUDE.md "Best Practices" #9). New feature flags follow the FEATURES-registry lifecycle: register with `addedIn`/`expires`, gate, then delete the entry + gates on graduation._
@@ -25,13 +25,13 @@ Citations are `file:line` against the repo at spec-authoring time.
25
25
 
26
26
  ### 2.1 Agents are already id-keyed
27
27
 
28
- Agents live under `config.agents` keyed by a **stable lowercase id** (the object key). `name` is a **separate display field** — there is no explicit `id` field inside the object; the key *is* the id, and `getAgents()` materializes it as `{ id, ...info }` (`engine/queries.js:681-687`).
28
+ Agents live under `config.agents` keyed by a **stable lowercase id** (the object key). `name` is a **separate display field** — there is no explicit `id` field inside the object; the key *is* the id, and `getAgents()` materializes it as `{ id, ...info }` (`engine/queries.js:764`).
29
29
 
30
30
  ```js
31
- // engine/shared.js:4398-4404
31
+ // engine/shared.js:4728-4734
32
32
  const DEFAULT_AGENTS = {
33
- ripley: { name: 'Ripley', emoji: '🏗️', role: 'Lead / Explorer', skills: [...] },
34
- dallas: { name: 'Dallas', emoji: '🔧', role: 'Engineer', skills: [...] },
33
+ ripley: { name: 'Ripley', emoji: '🏗️', role: 'Lead / Explorer', expertise: [...] },
34
+ dallas: { name: 'Dallas', emoji: '🔧', role: 'Engineer', expertise: [...] },
35
35
  // …
36
36
  };
37
37
  ```
@@ -42,7 +42,7 @@ Crucially, **nothing derives the id from the name** — `id === lowercase(name)`
42
42
 
43
43
  | State | Keyed by id at |
44
44
  |-------|----------------|
45
- | Charter file | `agents/<id>/charter.md` (`engine/queries.js:677-679`) |
45
+ | Charter file | `agents/<id>/charter.md` (`engine/queries.js:847-850`) |
46
46
  | Per-agent memory | `knowledge/agents/<id>.md`; inbox routes by `agent:` frontmatter → filename prefix (`engine/consolidation.js:106-129,159-182`) |
47
47
  | Metrics / spend / error rate | `metrics[id]`, `perAgent[id]` (`engine/routing.js:66-92`) |
48
48
  | Dispatch records | `dispatch.active[].agent` (`engine/queries.js:587-605`) |
@@ -50,12 +50,12 @@ Crucially, **nothing derives the id from the name** — `id === lowercase(name)`
50
50
  | Inbox files | `notes/inbox/<id>-…` filename prefix (`engine/queries.js:700-713`) |
51
51
  | Routing | preferred/fallback agent ids (`routing.md`, `engine/routing.js:31-52`) |
52
52
 
53
- The **only** consumers of the display `name` are `buildSystemPrompt`'s `# You are {name}` line (`engine/playbook.js:947-950`) and dashboard display text. So renaming the display name is safe and needs no state migration **as long as the id key is never mutated**. Changing the id key would orphan every row above — the id must be immutable.
53
+ The display `name` is consumed by `buildSystemPrompt`, dashboard text, and the soft free-text matcher in `resolveTaskContext()` (§2.3), but no persistent state is keyed by it. So renaming the display name is safe and needs no state migration **as long as the id key is never mutated**. Changing the id key would orphan every row above — the id must be immutable.
54
54
 
55
55
  ### 2.3 Names are load-bearing in two places (the part that must change)
56
56
 
57
57
  1. **Charters hardcode names.** The shipped charters bake the agent's own name and peers' names into the prose — e.g. `agents/ripley/charter.md` opens `# Ripley — Lead / Explorer`, `**Name:** Ripley`, and says "Handing off structured findings to **Dallas** (Engineer) and **Lambert** (Analyst)". A rename would strew the old name through the prompt.
58
- 2. **Playbook context-resolution matches by name.** `engine/playbook.js:163-240` matches referenced plans/notes by **both** agent `id` **and** `name` (e.g. "Ripley's plan"). After a rename, artifacts that referenced the old *name* stop auto-linking (id-based matches still resolve).
58
+ 2. **Playbook context-resolution matches by name.** `resolveTaskContext()` (`engine/playbook.js:171-256`) matches referenced plans/notes by agent `id` and display `name` (e.g. "Ripley's plan"). After a rename, artifacts that referenced the old *name* stop auto-linking (id-based matches still resolve).
59
59
 
60
60
  These are the two reasons "names are load-bearing" — §4.2 and §4.3 neutralize them.
61
61
 
@@ -83,7 +83,7 @@ Agents are **already** id-keyed (§2.1–2.2); this step makes the invariant exp
83
83
 
84
84
  A charter that hardcodes a proper name (§2.3) breaks the moment an agent is renamed (and later blocks a role-level charter being shared across agents — the configurability payoff). Make the charter body **name-agnostic** so the identity line is the single source of the name:
85
85
 
86
- - **Single source of name.** The agent's name appears *only* in the engine-injected `# You are {name} ({label})` block (`engine/playbook.js:947-950`). The charter prose must use the **second person** ("you", "your") and **never** restate its own proper name (no `# Ripley`, no `**Name:** Ripley`). The agent still knows its name — it reads it from the identity block — so **name-agnostic ≠ name-blind**.
86
+ - **Single source of prompt identity.** The agent's name appears in the engine-injected `# You are {name} ({label})` block (`engine/playbook.js:1092-1094`). The charter prose must use the **second person** ("you", "your") and **never** restate its own proper name (no `# Ripley`, no `**Name:** Ripley`). The agent still knows its name — it reads it from the identity block — so **name-agnostic ≠ name-blind**.
87
87
  - **Refer to peers by role, not name.** "hand off to **Dallas** (Engineer)" becomes "hand off to the **Engineer** role" — roles are stable; names are mutable. This keeps a charter valid when *any* agent is renamed.
88
88
  - **Rewrite the shipped defaults.** Sanitize the repo's `agents/<id>/charter.md` files name-agnostic. (The configurability spec later seeds role charters from these — but the sanitization lands here, unconditionally.)
89
89
  - **Legacy user charters are not auto-rewritten.** A user-authored `charter.md` that still contains a name renders verbatim (back-compat, non-breaking) — it just reads stale after a rename. A **soft, dismissible warning** flags a name embedded in an editable charter, nudging toward second person / role references. No hard block, no silent rewrite of user content.
@@ -100,7 +100,7 @@ A rename changes the agent's **display identity** (`name`, and optionally `emoji
100
100
  - **Concurrency & audit:** writes through `mutateJsonFileLocked` on `config.json` (never `safeWrite`); logs `old → new`.
101
101
 
102
102
  **What updates (display only, picked up live)**
103
- - The system-prompt identity line `# You are {name} ({label})` on the **next** dispatch (`engine/playbook.js:947-950`).
103
+ - The system-prompt identity line `# You are {name} ({label})` on the **next** dispatch (`engine/playbook.js:1092-1094`).
104
104
  - Dashboard display: team cards, agent detail panel, history attribution, Command Center state preamble — all read `name` live on next render.
105
105
  - The rename invalidates the system-prompt / status / CC-preamble caches so the new name surfaces promptly.
106
106
 
@@ -113,7 +113,7 @@ A rename changes the agent's **display identity** (`name`, and optionally `emoji
113
113
 
114
114
  **Stale name references in historical free-text (known, accepted, non-breaking)**
115
115
  - Rename does **not** cascade into pre-existing free-text: `notes.md`, `pinned.md`, the knowledge base, per-agent memory, and plan/PRD prose keep the old name (non-breaking — just stale).
116
- - Concrete engine consequence (§2.3): playbook context-resolution matches referenced plans/notes by both `id` and `name` (`engine/playbook.js:163-240`); after a rename, old-name artifacts stop auto-linking to the agent (id matches still resolve). §4.2's guidance minimizes future name-baking.
116
+ - Concrete engine consequence (§2.3): playbook context-resolution matches referenced plans/notes by both `id` and `name` (`engine/playbook.js:171-256`); after a rename, old-name artifacts stop auto-linking to the agent (id matches still resolve). §4.2's guidance minimizes future name-baking.
117
117
  - A **soft, non-blocking** "old name still appears in N place(s)" hint may follow a rename; it **never** auto-rewrites user/historical content.
118
118
 
119
119
  **UI**
@@ -126,7 +126,7 @@ A rename changes the agent's **display identity** (`name`, and optionally `emoji
126
126
  - **Stable id.** The id key is immutable; rename touches `name`/`emoji` only. No agent state is re-keyed.
127
127
  - **Charters preserved.** `agents/<id>/charter.md` remains the charter source. `minions init`/upgrade already preserves charter files (`bin/minions.js:1361-1368`) — do not regress that. Legacy user charters with names render verbatim and only earn a soft warning.
128
128
  - **Routing unaffected.** Routing targets agent ids; rename is invisible to it.
129
- - **No `name` writer today is broken.** `POST /api/settings` does not edit `name` (`dashboard.js:10672-10758`); the new rename endpoint is the sole `name` writer.
129
+ - **No `name` writer today is broken.** `POST /api/settings` edits existing agent fields but not `name` (`dashboard.js:11242-11268`); the new rename endpoint is the sole `name` writer.
130
130
 
131
131
  ## 6. Acceptance criteria
132
132
 
@@ -142,7 +142,7 @@ A rename changes the agent's **display identity** (`name`, and optionally `emoji
142
142
 
143
143
  - **Re-keying an agent id.** Rename changes `name`/`emoji` only; there is no change-id path (§4.1).
144
144
  - **The Role / Agent Library** itself (roles, durable charters, expertise field, CRUD) — see [`agent-configurability.md`](agent-configurability.md), which depends on this spec.
145
- - **`skills`→`expertise` field rename** — a separate cleanup owned by the configurability spec.
145
+ - **`skills`→`expertise` field rename** — shipped separately under the configurability spec; it is not part of the rename feature.
146
146
  - **Cascading a rename into historical free-text** (notes/KB/memory/plans). Non-goal; only a soft hint is offered.
147
147
 
148
148
  ## 8. Work breakdown (suggested PRD seeds)
@@ -160,4 +160,4 @@ This spec is a **hard prerequisite** for [`agent-configurability.md`](agent-conf
160
160
 
161
161
  ---
162
162
 
163
- _Every new config surface here must also get a dashboard control and be documented in CLAUDE.md — config without UI is incomplete (CLAUDE.md "Best Practices" #15). The `agent-rename` flag follows the FEATURES-registry lifecycle: register with `addedIn`/`expires`, gate, then delete the entry + gate on graduation._
163
+ _Every new config surface here must also get a dashboard control and be documented in CLAUDE.md — config without UI is incomplete (CLAUDE.md "Best Practices" #9). The `agent-rename` flag follows the FEATURES-registry lifecycle: register with `addedIn`/`expires`, gate, then delete the entry + gate on graduation._