@jaybeeuu/agent-cortex 2.0.0 → 2.2.0

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 (183) hide show
  1. package/CHANGELOG.md +437 -0
  2. package/README.md +46 -15
  3. package/agents/README.md +22 -10
  4. package/agents/plan/agent.md +2 -2
  5. package/agents/ralph/agent.md +128 -91
  6. package/agents/ralph/claude/frontmatter.json +3 -3
  7. package/agents/ralph/claude/wake.md +46 -0
  8. package/agents/ralph/pi/{polling.md → wake.md} +35 -20
  9. package/agents/ralph-plan/agent.md +23 -11
  10. package/bin/agent-cortex.mjs +66 -4
  11. package/bin/installers/claude.mjs +262 -77
  12. package/bin/installers/pi.mjs +200 -24
  13. package/extensions/agent-guardrails/README.md +1 -1
  14. package/extensions/agent-guardrails/guardrails.ts +1 -1
  15. package/extensions/agent-guardrails/index.ts +1 -1
  16. package/extensions/agent-modes/discover.test.ts +2 -2
  17. package/extensions/output-style/README.md +58 -0
  18. package/extensions/output-style/index.ts +23 -0
  19. package/extensions/output-style/output-style.md +43 -0
  20. package/extensions/output-style/output-style.test.ts +50 -0
  21. package/extensions/output-style/output-style.ts +32 -0
  22. package/extensions/output-style/package.json +19 -0
  23. package/hooks/claude/scripts/notify.mjs +8 -1
  24. package/lib/cli.mjs +91 -2
  25. package/package.json +29 -4
  26. package/scripts/check-changeset.mjs +4 -0
  27. package/scripts/check-no-sync.mjs +5 -1
  28. package/scripts/check-skill-frontmatter.mjs +21 -0
  29. package/scripts/lib/compose-agent.mjs +69 -9
  30. package/scripts/lib/fs.mjs +10 -2
  31. package/scripts/lib/migrate.mjs +736 -0
  32. package/scripts/lib/release-gates.mjs +21 -1
  33. package/scripts/lib/skill-frontmatter.mjs +152 -0
  34. package/scripts/lib/skill-links.mjs +52 -0
  35. package/scripts/lib/verify-worker-tree.mjs +25 -0
  36. package/scripts/resolve-publish-command.mjs +4 -0
  37. package/skills/engineering/design-an-interface/SKILL.md +3 -3
  38. package/skills/engineering/grill-with-docs/SKILL.md +3 -5
  39. package/skills/engineering/improve-codebase-architecture/SKILL.md +5 -4
  40. package/skills/engineering/tdd/SKILL.md +5 -7
  41. package/skills/engineering/technical-direction/SKILL.md +5 -5
  42. package/skills/planning/classify-bead/REFERENCE.md +3 -3
  43. package/skills/planning/classify-bead/SKILL.md +14 -9
  44. package/skills/planning/classify-bead/scripts/classify-bead.mjs +5 -4
  45. package/skills/planning/create-task/REFERENCE.md +52 -3
  46. package/skills/planning/create-task/SKILL.md +70 -26
  47. package/skills/planning/create-task/scripts/{create-chores.ts → create-chores.mjs} +48 -23
  48. package/skills/planning/flesh-out-idea/REFERENCE.md +116 -0
  49. package/skills/planning/flesh-out-idea/SKILL.md +146 -0
  50. package/skills/planning/prd-to-tasks/REFERENCE.md +54 -5
  51. package/skills/planning/prd-to-tasks/SKILL.md +22 -16
  52. package/skills/planning/record-idea/FORMAT.md +66 -17
  53. package/skills/planning/record-idea/SKILL.md +48 -24
  54. package/skills/planning/request-refactor-plan/SKILL.md +4 -4
  55. package/skills/planning/spec-to-tickets/SKILL.md +5 -5
  56. package/skills/planning/write-a-prd/SKILL.md +8 -9
  57. package/skills/planning/write-a-ticket/SKILL.md +4 -6
  58. package/skills/productivity/bd-tool/SKILL.md +15 -10
  59. package/skills/productivity/grill-me/SKILL.md +5 -0
  60. package/skills/productivity/init-beads/SKILL.md +3 -3
  61. package/skills/productivity/migration/REFERENCE.md +227 -0
  62. package/skills/productivity/migration/SKILL.md +188 -0
  63. package/skills/productivity/validate-agent-dir/scripts/{validate-agent-dir.ts → validate-agent-dir.mjs} +49 -28
  64. package/skills/productivity/write-a-skill/SKILL.md +5 -5
  65. package/skills/review/maintain-agent-docs/SKILL.md +5 -7
  66. package/skills/review/refactor-skill/SKILL.md +4 -3
  67. package/skills/review/review-security/SKILL.md +3 -5
  68. package/skills/style/style-code/SKILL.md +5 -10
  69. package/skills/style/style-comms/SKILL.md +5 -7
  70. package/skills/style/style-documentation/SKILL.md +5 -6
  71. package/skills/style/style-tests/SKILL.md +5 -7
  72. package/skills/workflow/git-workflow/SKILL.md +28 -4
  73. package/skills/workflow/hitl-collab/SKILL.md +4 -6
  74. package/skills/workflow/plan/SKILL.md +41 -30
  75. package/skills/workflow/ralph/REFERENCE.md +209 -55
  76. package/skills/workflow/ralph/SKILL.md +89 -50
  77. package/skills/workflow/ralph/scripts/pending-gates.mjs +134 -0
  78. package/skills/workflow/run-pipeline-stage/SKILL.md +72 -71
  79. package/skills/workflow/run-pipeline-stage/playbooks/code.md +11 -0
  80. package/skills/workflow/run-pipeline-stage/playbooks/document.md +12 -0
  81. package/skills/workflow/run-pipeline-stage/playbooks/fix.md +12 -0
  82. package/skills/workflow/run-pipeline-stage/playbooks/review.md +11 -0
  83. package/skills/workflow/run-pipeline-stage/playbooks/verify.md +13 -0
  84. package/skills/workflow/run-pipeline-stage/prompts/stage-runner.md +73 -1
  85. package/token-map.README.md +9 -4
  86. package/token-map.json +13 -6
  87. package/.agents/skills/style-versioning/SKILL.md +0 -172
  88. package/.changeset/README.md +0 -8
  89. package/.changeset/config.json +0 -11
  90. package/.github/workflows/ci.yml +0 -302
  91. package/.junie/guidelines.md +0 -87
  92. package/.junie/mcp/mcp.json +0 -10
  93. package/AGENTS.md +0 -151
  94. package/agents/ralph/claude/polling.md +0 -31
  95. package/agents-native/ralph.md +0 -193
  96. package/docs/claude-hooks.md +0 -128
  97. package/docs/commit-signing.md +0 -231
  98. package/docs/ideas/auto-model-selection.md +0 -75
  99. package/docs/ideas/ban-content-assertion-tests.md +0 -75
  100. package/docs/ideas/bead-progress-notes-for-session-resumption.md +0 -75
  101. package/docs/ideas/classify-beads-via-deterministic-script-with-agent-fallback.md +0 -70
  102. package/docs/ideas/ctx-alias-version-and-update-commands.md +0 -65
  103. package/docs/ideas/ctx-feedback-command-for-capturing-ideas-from-any-machine.md +0 -67
  104. package/docs/ideas/dedicated-review-tests-skill.md +0 -71
  105. package/docs/ideas/deployment-beads-for-post-merge-pipelines.md +0 -36
  106. package/docs/ideas/design-and-delivery-as-separate-bead-trees/design-and-delivery-as-separate-bead-trees.md +0 -99
  107. package/docs/ideas/enable-signed-commit-enforcement-changesets-bot-commits-must-be-signed.md +0 -42
  108. package/docs/ideas/extension-manifests.md +0 -121
  109. package/docs/ideas/improve-pi-system-prompt.md +0 -37
  110. package/docs/ideas/map-every-cortex-tool-to-a-real-pi-equivalent.md +0 -95
  111. package/docs/ideas/model-selector.md +0 -40
  112. package/docs/ideas/pi-task-memory.md +0 -34
  113. package/docs/ideas/qa-extension.md +0 -43
  114. package/docs/ideas/record-idea-implementation-questions.md +0 -68
  115. package/docs/ideas/record-ideas-as-beads.md +0 -115
  116. package/docs/ideas/self-flushing-session.md +0 -72
  117. package/docs/ideas/state-in-beads-not-md.md +0 -69
  118. package/docs/ideas/subagent-visibility.md +0 -72
  119. package/docs/ideas/task-session-context.local.md +0 -95
  120. package/docs/ideas/task-session-context.md +0 -89
  121. package/docs/ideas/test-data-creation-helpers.md +0 -92
  122. package/docs/ideas/test-planning-stage-bead-in-feature-planning.md +0 -68
  123. package/docs/ideas/unified-ci-pipeline.md +0 -28
  124. package/docs/ideas/unify-the-ticket-and-task-decomposition-workflows.md +0 -71
  125. package/docs/ideas/worktree-housekeeping-for-closed-beads.md +0 -39
  126. package/docs/inspirations.md +0 -33
  127. package/docs/research/disable-model-invocation.md +0 -82
  128. package/docs/research/gas-city-research.md +0 -256
  129. package/docs/research/skill-design-research.md +0 -286
  130. package/docs/research/skill-improvements-analysis.md +0 -117
  131. package/docs/research/skill-patterns-research.md +0 -24
  132. package/docs/skills/skill-anatomy.md +0 -197
  133. package/docs/technical-direction/harness-config.md +0 -177
  134. package/docs/technical-direction/migration-execution-labels.md +0 -177
  135. package/docs/user-preferences.md +0 -17
  136. package/extensions/agent-guardrails/tsconfig.json +0 -12
  137. package/extensions/agent-modes/tsconfig.json +0 -12
  138. package/extensions/session-start/tsconfig.json +0 -12
  139. package/extensions/skill-stats/pnpm-lock.yaml +0 -329
  140. package/extensions/skill-stats/tsconfig.json +0 -12
  141. package/extensions/subagent/agents/planner.md +0 -37
  142. package/extensions/subagent/agents/reviewer.md +0 -35
  143. package/extensions/subagent/agents/scout.md +0 -50
  144. package/extensions/subagent/agents/worker.md +0 -24
  145. package/extensions/subagent/prompts/implement-and-review.md +0 -10
  146. package/extensions/subagent/prompts/implement.md +0 -10
  147. package/extensions/subagent/prompts/scout-and-plan.md +0 -9
  148. package/extensions/subagent/tsconfig.json +0 -12
  149. package/pi/keybindings.json +0 -3
  150. package/pi/settings.json +0 -34
  151. package/pnpm-workspace.yaml +0 -14
  152. package/skills/planning/create-task/scripts/package.json +0 -14
  153. package/skills/planning/create-task/scripts/pnpm-lock.yaml +0 -342
  154. package/skills/planning/create-task/scripts/tsconfig.json +0 -12
  155. package/skills/planning/record-idea/scripts/new-idea.sh +0 -89
  156. package/skills/productivity/validate-agent-dir/scripts/package.json +0 -15
  157. package/skills/productivity/validate-agent-dir/scripts/pnpm-lock.yaml +0 -329
  158. package/skills/productivity/validate-agent-dir/scripts/pnpm-workspace.yaml +0 -2
  159. package/skills/productivity/validate-agent-dir/scripts/tsconfig.json +0 -19
  160. package/skills/productivity/validate-agent-dir/scripts/validate-agent-dir.test.ts +0 -317
  161. package/skills/workflow/run-pipeline-stage/REFERENCE.md +0 -22
  162. package/skills/workflow/run-pipeline-stage/scripts/generate-progress.test.ts +0 -682
  163. package/skills/workflow/run-pipeline-stage/scripts/generate-progress.ts +0 -588
  164. package/skills/workflow/run-pipeline-stage/scripts/package.json +0 -15
  165. package/skills/workflow/run-pipeline-stage/scripts/pnpm-lock.yaml +0 -342
  166. package/skills/workflow/run-pipeline-stage/scripts/pnpm-workspace.yaml +0 -2
  167. package/skills/workflow/run-pipeline-stage/scripts/tsconfig.json +0 -12
  168. package/test/classify-bead.test.mjs +0 -277
  169. package/test/claude-installer.test.mjs +0 -308
  170. package/test/cli.test.mjs +0 -314
  171. package/test/create-chores.test.mjs +0 -85
  172. package/test/fake-bd.test.mjs +0 -72
  173. package/test/fs.test.mjs +0 -76
  174. package/test/helpers/fake-bd.mjs +0 -87
  175. package/test/helpers/fake-claude.mjs +0 -152
  176. package/test/helpers/fake-pi.mjs +0 -132
  177. package/test/installer.test.mjs +0 -664
  178. package/test/notify-hook.test.mjs +0 -63
  179. package/test/pi-installer.test.mjs +0 -785
  180. package/test/pi-register.test.mjs +0 -342
  181. package/test/pi-sweep.test.mjs +0 -619
  182. package/test/release-gates.test.mjs +0 -190
  183. package/test/verify-worker-tree.test.mjs +0 -120
@@ -0,0 +1,227 @@
1
+ # Migration reference
2
+
3
+ Contracts, step details, and recovery recipes for the `migration` skill. `SKILL.md` holds the
4
+ workflow and the gate; this file holds the detail you reach for while running it.
5
+
6
+ ## Command interface the skill relies on
7
+
8
+ The command is shipped by the `agent-cortex` CLI (`bin/agent-cortex.mjs` + `lib/cli.mjs`), which
9
+ exposes exactly one executable name — `agent-cortex`. From a checkout that is not installed, run
10
+ it as `node bin/agent-cortex.mjs migrate`. There is no shorter alias. This skill depends on the
11
+ following behaviour — nothing wider:
12
+
13
+ | Contract | Guarantee the skill assumes |
14
+ |---|---|
15
+ | `agent-cortex migrate` | **Dry run is the default**: plans the first pending step only, zero writes, exit 0. With `--apply` it runs every step the repo still needs. |
16
+ | `--apply` | Performs the writes. Same plan, executed. |
17
+ | `--dry-run` | Explicit form of the default; identical output, still zero writes. |
18
+ | `--help` | Lists the commands and flags this build accepts, including whether `migrate` itself is present. |
19
+ | `--dir <path>` | Points step v2 at a workspace that keeps its idea files somewhere other than `docs/ideas`. Omitted, the default applies; a missing value is a usage error, not a silent fallback. |
20
+ | Idea source | Step v2 reads `*.md` under the idea directory (`docs/ideas/` unless `--dir` says otherwise), one level of nesting included, and never writes or deletes one. |
21
+ | Registry detection | Reports the repo's current version and the first step with pending work — the only step a dry run plans — derived from workspace state, not from a flag or a stored marker the agent has to keep. |
22
+ | Step ordering | Applies steps in version order, oldest first. The final summary is one line per step: its name and description, that step's pending bead total, and a `verified` line. It carries no per-group breakdown — derive group sizes from the step-v1 export counts. |
23
+ | Idempotence | A converged repo plans zero targets and exits 0; a re-run after a partial failure resumes rather than repeating writes. |
24
+ | Failure mode | Fails loudly (non-zero exit) when `bd` is missing or a `bd` subcommand errors; never silently skips a group. A v1 label value outside `afk\|hitl` is a blocking error that names each offending bead and label and stops before any write — both the dry run and `--apply` refuse. |
25
+
26
+ Read `agent-cortex migrate --help` in the target workspace before relying on any flag beyond the
27
+ above. The registry grows over time; treat the flags in this table as the floor, and the installed
28
+ build's help output as the truth. If `migrate` is not listed at all, the installed package predates
29
+ the command — upgrade rather than reconstructing the steps by hand.
30
+
31
+ Scope note: the command touches beads only. Skills, hooks, docs, and agent prompts that mention
32
+ the old labels are follow-up edits in the repo, not command output. Step v2 reads idea files and
33
+ never writes or deletes one — retiring the files is the repo's cutover, not the migration.
34
+
35
+ ## Detection source and its cost
36
+
37
+ Detection and verification read `bd export --all`, cross-checked against `bd label list-all
38
+ --json`. A label-filtered `bd list` is not in the path: on bd 1.3.1 that query can omit closed
39
+ beads, which is how a half-migrated workspace once verified clean. The cross-check keeps the
40
+ export from becoming the new silent weak link — an export that cannot attribute a legacy label
41
+ the index still lists fails the run rather than shrinking the count.
42
+
43
+ The cost is operational. One `--apply` reads the whole export about three times — initial
44
+ detection, verification after the step, then re-detection for the next step — so a large workspace
45
+ pays for a full export per call rather than a label-filtered page. Each call is capped at 32 MB of
46
+ stdout (roughly 12k issues at typical record sizes); past the cap the run fails loudly instead of
47
+ truncating. Near the ceiling, expect that explicit failure and do not read a short result as a
48
+ clean workspace.
49
+
50
+ Step v2 adds two reads of its own, both cheap: the idea files on disk, and one `bd list -l
51
+ kind:idea --all --json --limit 0` for the records that already exist. It never runs the full
52
+ export.
53
+
54
+ ## Snapshot scope (SKILL step 2)
55
+
56
+ `bd export --all` is the pre-migration snapshot. It includes infrastructure beads (agents, roles,
57
+ messages), templates, gates, and `bd remember` memories as well as regular issues — so treat the
58
+ file as sensitive and keep it out of the repo (a path outside the workspace, or one you have
59
+ gitignored; `bd export --all -o <path>.jsonl` writes it directly). It is an issue export, not a
60
+ full database backup: Dolt branches, commit history, and working-set state are not captured. For
61
+ undoing a migration that is enough — steps change labels and dependencies, both of which the
62
+ export records.
63
+
64
+ ## Step v1 — label rename
65
+
66
+ Purpose: `implementation-type:afk|hitl` → `execution:afk|hitl`, strictly renamed and
67
+ agent-agnostic. Only those two values are mapped: any other value (`wip`, a typo, a value from a
68
+ future axis) is a blocking error naming the bead and the label, raised before any write, so the
69
+ run can never invent a label such as `execution:wip` that nothing queries.
70
+
71
+ Mechanics the plan reflects:
72
+
73
+ 1. Enumerate every bead carrying an `implementation-type:*` label by reading the whole workspace —
74
+ `bd export --all` (JSONL) — closed beads included, because a clean label space is the goal and
75
+ bd tolerates label history on closed issues. There is no label filter and no page limit in this
76
+ path, so the count is the workspace's rather than a query's.
77
+ 2. Group bead ids by label value. A bead carrying both `afk` and `hitl` appears in both groups;
78
+ that is a data problem worth inspecting, not a conflict the tool resolves for you.
79
+ 3. Per group, on `--apply`: `bd label add <ids…> execution:<value>` then
80
+ `bd label remove <ids…> implementation-type:<value>`. Add-then-remove keeps the routing label
81
+ present at every instant, so nothing is unroutable mid-flight.
82
+ 4. Re-running after convergence finds zero targets — the no-op that proves idempotence.
83
+
84
+ Verification commands:
85
+
86
+ ```bash
87
+ bd label list-all # no implementation-type:* entries
88
+ bd export --all | grep '"implementation-type:' # empty, closed beads included
89
+ bd label list <bead-id> # spot-check: execution:<value> present
90
+ bd ready -l execution:afk # the routing query still works
91
+ ```
92
+
93
+ ## Step v2 — ideas to beads
94
+
95
+ Purpose: loose idea files (`docs/ideas/*.md`) become `kind:idea` + `execution:hitl` beads, one
96
+ bead per file. The files are read and left in place; deleting them is the repo's own cutover step.
97
+ The step is repo-agnostic — it assumes an idea directory (`docs/ideas/` by default, `--dir`
98
+ overridable) and nothing else: no skill, no install path, no agent-cortex-specific label.
99
+
100
+ Mechanics the plan reflects:
101
+
102
+ - **Discovery.** Top-level `*.md` under the idea directory, plus one level of nesting (a multi-part
103
+ idea can live in its own folder). A missing directory is not an error — a workspace that never
104
+ used idea files has nothing pending. The plan prints one line per file: path, title, priority.
105
+ - **Field mapping.** The files predate a single template, so a `##` heading is matched by normalised
106
+ name (case-folded, trailing parenthetical ignored) rather than exact text. Every field keeps its
107
+ `##` marker, because the marker is the contract `flesh-out-idea` reads a bead by.
108
+
109
+ | Bead field | Sections |
110
+ |---|---|
111
+ | title | the `#` heading, `Idea: ` prefixed (a leading `Idea:`/`Design:` is not doubled) |
112
+ | `--description` | `## Problem`, legacy `## Why it might be useful`, `## Who benefits`, `## Proposed outcome` |
113
+ | `--design` | `## How we might do it`, `## Fleshed-out design (…)`, `## Design so far / provenance` |
114
+ | `--notes` | `## Status`, `## Created`, `## Validity check`, `## Constraints`, `## Next validation step`, `## Priority`, `## When to think about it`, `## Open questions`, `## Notes`, and every unlisted `##` section in file order |
115
+ | `--context` | unused — no idea file in the wild carries a referential section; do not invent one |
116
+ | `--acceptance` | fixed promotion criterion: a scoped epic/feature is spawned from the bead, or it is explicitly rejected (a `task` bead needs acceptance criteria to lint clean) |
117
+ | `-p` | first `P0`–`P4` token anywhere in the file, `P4` when the file states none |
118
+
119
+ The invariant that makes the mapping checkable: **no content loss** — the heading becomes the
120
+ title and every other line of the file appears in exactly one of the three fields.
121
+
122
+ - **Priority caveat.** The first `P<n>` token wins, so a file that only mentions a `P0-P4` *scale*
123
+ reads as `P0`. Read the priority column of the plan before applying.
124
+
125
+ - **Labels.** `kind:idea` marks the record as an unscoped idea; `execution:hitl` is always applied
126
+ because an idea is human-owned until promoted, and it stays out of the agent queue by *not*
127
+ carrying `execution:afk`.
128
+
129
+ - **Idempotence.** Before creating anything the step reads `bd list -l kind:idea --all --json
130
+ --limit 0` and skips a file when an idea bead already records it: either a bead names the file
131
+ under a `## Provenance` heading, or a bead carrying no provenance has a matching title (after
132
+ dropping the `Idea: ` / `Design: ` prefix and all punctuation). Every bead the step creates
133
+ cites its source file under `## Provenance`, so the provenance rule is what makes a re-run, or
134
+ an `--apply` that died part-way, a no-op — and what keeps two files that share a title
135
+ (`task-session-context.md` and `task-session-context.local.md` do) separately attributable. The
136
+ title rule is the fallback for records migrated by hand before the step existed, which cite no
137
+ source; a title match is therefore also the one case where a summary bead can stand in for a
138
+ file's content. A passing cross-reference outside a provenance section is not a record — the
139
+ step still creates that bead.
140
+
141
+ - **Write order.** One `bd create --silent` per file, in path order, so a partial failure leaves
142
+ only the unmigrated files behind; the verification pass re-detects and must find nothing.
143
+
144
+ Verify with `bd list -l kind:idea --json --limit 0`, then compare one bead's fields against its
145
+ source file before the files are retired ("files present but already migrated" is a normal state:
146
+ the plan simply has nothing to say about them).
147
+
148
+ ## Rollback recipes
149
+
150
+ The pre-migration `bd export --all` snapshot plus the recorded dry-run plan is enough to undo any
151
+ step. Work per label group, oldest rename last, and re-verify with the v1 checks after each
152
+ inversion.
153
+
154
+ Every `bd label` call in this skill passes issue ids first and the label last, matching the CLI's
155
+ `bd label add [issue-id...] [label[,label...]]`. Reversing that order fails: the ids are resolved
156
+ before the trailing argument is read as a label.
157
+
158
+ ```bash
159
+ # Invert the v1 rename for a specific group
160
+ bd label add <ids…> implementation-type:afk
161
+ bd label remove <ids…> execution:afk
162
+
163
+ # Confirm the inversion landed before touching the next group
164
+ bd list -l execution:afk --all
165
+ ```
166
+
167
+ Rules that keep recovery safe:
168
+
169
+ - Drive every change through `bd`; editing `.beads/` files bypasses Dolt bookkeeping and produces
170
+ a workspace that disagrees with its own history.
171
+ - Invert one group at a time and re-check. Whole-step inversion in one shot makes a partial
172
+ mistake indistinguishable from a partial success.
173
+ - If the workspace is shared or synced (`bd dolt push` in use), say so in your report and pause
174
+ for the human owner before inverting — other clones may already have observed the rename.
175
+
176
+ ## Manual fallback (pinned version, no `migrate`)
177
+
178
+ Use only when the installed package genuinely lacks the command and an upgrade is out of scope.
179
+ Run exactly what v1 would run, with the same gate:
180
+ ```bash
181
+ # Read the plan; confirm the group counts match what you expect
182
+ bd export --all | grep '"implementation-type:' # every bead, closed included
183
+ bd label add <ids…> execution:afk
184
+ bd label remove <ids…> implementation-type:afk
185
+ bd label add <ids…> execution:hitl
186
+ bd label remove <ids…> implementation-type:hitl
187
+ bd label list-all # verify: nothing left
188
+ ```
189
+
190
+ Then record in the handoff that the run did not go through the registry, so the repo still needs
191
+ a `migrate` dry run once the command is available (it will simply find nothing to do).
192
+
193
+ For step v2 by hand, follow the field table under _Step v2 — ideas to beads_ and create one bead
194
+ per file:
195
+
196
+ ```bash
197
+ bd create "Idea: <file title>" --silent -l kind:idea,execution:hitl -p P<n> \
198
+ -d "<## Problem, ## Who benefits, ## Proposed outcome>" \
199
+ --design "<## How we might do it>" \
200
+ --notes "<## Status, ## Validity check, ## Constraints, ## Next validation step, …>" \
201
+ --acceptance "<promotion criterion>"
202
+ ```
203
+
204
+ Keep every `##` marker inside its field, check the title against `bd list -l kind:idea` before
205
+ creating — a hand-run has no collision skip — and leave the source files in place unless the repo
206
+ has already retired the file flow.
207
+
208
+ ## Stale-reference sweep
209
+
210
+ The rename is not done while text still teaches the old label. Search the workspace for the old
211
+ name and route each hit to its owner:
212
+
213
+ ```bash
214
+ grep -rn "implementation-type" . --exclude-dir=node_modules --exclude-dir=.git --exclude-dir=.beads
215
+ ```
216
+
217
+ Classify each hit before editing: skill instructions and classifier logic (they apply labels),
218
+ routing queries in orchestration docs (they filter on labels), and historical records such as
219
+ changelogs, ADRs, or closed-bead notes (leave them — rewriting history removes the trail).
220
+
221
+ ## Reporting a run
222
+
223
+ Record, in order: the detected version and steps planned, the snapshot location, the dry-run
224
+ plan with the group sizes reconciled from the export (or, at v2, the per-file title and priority
225
+ lines), the `--apply` summary, the four post-check results, the idempotence re-run outcome, and the
226
+ stale-reference list with owning files. That sequence is also the evidence trail if a later
227
+ post-check fails.
@@ -0,0 +1,188 @@
1
+ ---
2
+ name: migration
3
+ description: "Migrate a beads workspace to the two-axis model via the versioned `agent-cortex migrate` command: dry-run, apply, verify, recover. Use when asked to \"run the migration\" or \"rename the labels\"."
4
+ disable-model-invocation: true
5
+ ---
6
+
7
+ # Migration
8
+
9
+ Bring a beads workspace up to the current workflow model by running the versioned
10
+ `agent-cortex migrate` command in that workspace. From a checkout that is not installed, the same
11
+ command is `node bin/agent-cortex.mjs migrate` — those are the only two invocations. The command
12
+ keeps an ordered registry of steps, detects the version a repo is at, and applies each step in
13
+ order until the repo is current — the same command migrates every workspace, whenever it joins.
14
+
15
+ Steps are **dry-run by default**, **idempotent**, and **verified per step**. Your job is to
16
+ plan, gate, and prove the run — never to hand-edit `.beads/` or a label list.
17
+
18
+ Steps in the registry (full contract in `REFERENCE.md`):
19
+
20
+ | Version | Step | Effect |
21
+ |---|---|---|
22
+ | v1 | Label rename | `implementation-type:afk\|hitl` → `execution:afk\|hitl`, all beads including closed |
23
+ | v2 | Ideas → beads | `docs/ideas/*.md` (default; `--dir` overrides, one level of nesting included) become `kind:idea` + `execution:hitl` beads — the command reads the files and never deletes them |
24
+
25
+ ## When to use
26
+
27
+ - A workspace's beads still carry `implementation-type:afk|hitl` and must move to `execution:*`.
28
+ - The user says "run the migration", "rename the labels", "migrate this repo", or asks why
29
+ `bd ready -l execution:afk` returns nothing in a project that clearly has AFK work.
30
+ - A repo adopts agent-cortex (or a newer version) and its existing beads predate the model.
31
+ - Loose idea markdown still lives under `docs/ideas/` in a workspace and those records belong in
32
+ the backlog as beads (step v2).
33
+
34
+ ## When NOT to use
35
+
36
+ - No `.beads/` in the workspace — initialise it first with the `init-beads` skill; there is
37
+ nothing to migrate.
38
+ - The migration command is absent from the installed `agent-cortex` — upgrade the package
39
+ instead of hand-running steps. The only exception is the documented manual fallback in
40
+ `REFERENCE.md`, used when a fix is needed on a pinned version.
41
+ - The repo's skills and routing queries still create and filter the *old* labels. Land those
42
+ updates first: renaming under a ralph that queries `implementation-type:afk` leaves the
43
+ workspace unroutable. Order the sequence; do not race it.
44
+
45
+ ## Workflow
46
+
47
+ 1. **Preflight.** Run `bd version`, `bd label list-all`, and `agent-cortex --help` (upgrade the
48
+ package if `migrate` is not listed). The command is `agent-cortex migrate`; if the CLI is not
49
+ on PATH, run it from the package checkout as `node bin/agent-cortex.mjs migrate`. Read
50
+ `agent-cortex migrate --help` for the flags this build accepts. Act on the version the registry
51
+ detects — do not infer it yourself.
52
+
53
+ 2. **Snapshot before touching anything.** `bd export --all -o <path>.jsonl` (JSONL of every issue
54
+ including closed, with labels and dependencies). `--all` also exports infrastructure beads,
55
+ templates, gates, and `bd remember` memories, so keep the file outside the repo or gitignored —
56
+ see _Snapshot scope_ in `REFERENCE.md`. This is the rollback source of truth; keep it until the
57
+ post-checks pass.
58
+
59
+ 3. **Dry run.** Run the command with no apply flag — dry-run is the default, and an explicit
60
+ `--dry-run` is equivalent. It writes nothing and exits 0. Read the plan it prints: the
61
+ workspace version against the latest, then the **first pending step** only — its name, one
62
+ line per pending item, the pending count, and the no-writes notice. A v1 line is a bead and the
63
+ labels it would gain and lose; a v2 line is an idea file and the title plus priority it becomes.
64
+ Steps behind a pending one are not named, and the plan does not group beads by label value —
65
+ take group sizes from the export counts in step 4.
66
+
67
+ 4. **Gate on the plan.** Apply only when all of these hold:
68
+ - The detected version and the steps to run match what you expect for this repo.
69
+ - Every `implementation-type:<value>` group maps to exactly one `execution:<value>` group.
70
+ - Group sizes reconcile with the legacy-label counts in `bd export --all` — the source the
71
+ command itself reads. A bead carrying both labels appears in both groups — expected, not a
72
+ conflict. Do not reconcile with `bd list --label-pattern` (see `REFERENCE.md`).
73
+ - No unmapped or novel label value: the rename is strict and only `afk|hitl` are mapped, so
74
+ the command refuses the whole run — dry run and `--apply` alike, nothing written — naming
75
+ each offending bead and label. Treat that error as a signal to inspect, not to work around.
76
+ - For a v2 plan, each line names the file, the title, and the priority it will carry. A file
77
+ missing from the plan is one the command considers already recorded (a bead citing the file
78
+ under `## Provenance` — which every bead the step creates does — or a source-less bead with
79
+ that title); confirm the record exists before accepting the skip, and do not hand-create a
80
+ replacement.
81
+
82
+ 5. **Apply.** Run the same command with `--apply`. Step v1 writes in batches per label value —
83
+ add the `execution:<value>` label, then remove the `implementation-type:<value>` label — so a
84
+ partial failure never loses the routing label. Step v2 creates one bead per idea file, one file
85
+ at a time, so a run that dies part-way leaves only the unmigrated files behind and the retry
86
+ resumes exactly there. Record the summary verbatim in your report.
87
+
88
+ 6. **Post-check.** Treat the migration as unproven until all of these hold:
89
+
90
+ ```bash
91
+ bd label list-all # no implementation-type:* remains
92
+ bd export --all | grep '"implementation-type:' # empty, closed beads included
93
+ bd ready -l execution:afk # same beads as the pre-migration AFK set
94
+ ```
95
+
96
+ Then grep the repo for stale `implementation-type` references (skills, docs, hooks, configs).
97
+ List the files still to update — they are follow-up work, not part of the rename.
98
+
99
+ For v2, check a migrated bead against its source file with `bd show <id>` before the files are
100
+ retired: `--description`, `--design`, and `--notes` carry the file's sections with their `##`
101
+ markers, and the priority matches what the file stated.
102
+
103
+ 7. **Prove idempotence.** Re-run the dry run. A converged repo plans zero targets, performs no
104
+ writes, and exits 0. A non-empty plan after `--apply` means the write step did not converge:
105
+ investigate before applying again.
106
+
107
+ 8. **Recover if needed.** A dry run that wrote nothing is the normal failure mode. For a
108
+ half-applied step, an inverted rename, or a bad plan, follow _Rollback and recovery_.
109
+
110
+ 9. **Continue the sequence.** The label rename is one step, not the migration. Idea files become
111
+ beads at a later step, and any skill, hook, or doc that creates or queries the old labels
112
+ must be updated before the workspace is truly current. Hand those edits to their owners; the
113
+ migration command does not rewrite prose — and it does not delete the idea files either. Retire
114
+ them (and any scaffold script that writes them) only after the skills that used the file flow
115
+ have stopped, or the repo recreates what you just deleted.
116
+
117
+ Workflow at a glance:
118
+
119
+ ```text
120
+ [Preflight: bd + command]
121
+ |
122
+ v
123
+ [Snapshot: bd export --all]
124
+ |
125
+ v
126
+ [Dry run: read plan] --(plan unexpected)--> [Stop: no writes]
127
+ |
128
+ (plan matches)
129
+ v
130
+ [Apply --apply]
131
+ |
132
+ v
133
+ [Post-check 4 gates] --(fail)--> [Invert per group]
134
+ |
135
+ (pass)
136
+ v
137
+ [Re-run dry run: no-op] --> [Hand off stale refs + later steps]
138
+ ```
139
+
140
+ ## Rollback and recovery
141
+
142
+ - **Nothing applied yet** — the dry run wrote nothing, so discard the plan; the workspace is
143
+ untouched; the snapshot is not even needed.
144
+ - **A step died mid-batch** — dry-run, then re-run `--apply`: steps are idempotent, so
145
+ already-renamed beads no longer match and an already-created idea bead cites its source file, so
146
+ the retry resumes instead of repeating writes — even when two files share one title.
147
+ - **A completed step was wrong** — invert it per group from the recorded plan or pre-migration
148
+ export: `bd label add <ids…> implementation-type:<value>` then
149
+ `bd label remove <ids…> execution:<value>` (issue ids first, label last), through `bd`, never
150
+ by editing `.beads/` files.
151
+ - **Unsure which groups moved** — diff the pre-migration export's label sets against
152
+ `bd export --all` now. Recipes and shared-workspace cautions are in `REFERENCE.md`.
153
+
154
+ ## Rationale: why the rename exists
155
+
156
+ The workspace runs on two independent axes: **bead type** (`idea → epic → feature → chore`,
157
+ what shape the work has) and **execution** (`execution:afk` = agent-routable, `execution:hitl` =
158
+ human required). Hierarchy is ownership via `--parent`; ordering is `depends-on`, which alone
159
+ gates readiness. `implementation-type:` collapsed the two axes and named one particular executor,
160
+ which is why routing broke when the executor changed; `execution:` is agent-agnostic and is the
161
+ exact value ralph queries (`bd ready -l execution:afk`). That is also why the rename is strict:
162
+ the label *is* the query, so a half-migrated workspace does not error — it silently starves, and
163
+ the queue looks empty instead of broken. Hence snapshot → dry run → gated apply → post-check.
164
+
165
+ ## See Also
166
+
167
+ - [bd-tool](../bd-tool/SKILL.md) — bead query and label conventions the post-checks assume.
168
+ - [classify-bead](../../planning/classify-bead/SKILL.md) — the classifier that applies `execution:*` labels to new beads after the rename.
169
+ - [ralph](../../workflow/ralph/SKILL.md) — the consumer whose `execution:afk` query is the migration's smoke test.
170
+ - [init-beads](../init-beads/SKILL.md) — load when the project has no `.beads/` workspace to migrate yet.
171
+
172
+ ## Verification checklist
173
+
174
+ - [ ] `bd version` and `agent-cortex migrate --help` both ran; the flags this build accepts are known.
175
+ - [ ] A pre-migration `bd export --all` snapshot exists and is readable.
176
+ - [ ] The dry run reported a plan and wrote nothing (no label changes in `bd label list-all`).
177
+ - [ ] The plan reconciles with the legacy-label counts in `bd export --all`.
178
+ - [ ] The `--apply` summary is recorded verbatim: one line per step with its pending bead total
179
+ and a `verified` line. It reports no per-group counts — reconcile group sizes against the
180
+ step-4 export counts.
181
+ - [ ] `bd label list-all` and the export grep in step 6 both show nothing left.
182
+ - [ ] `bd ready -l execution:afk` returns the same beads as the pre-migration AFK set.
183
+ - [ ] A repeat dry run is a no-op (zero targets, exit 0).
184
+ - [ ] Stale `implementation-type` references are listed with their owning files, and later steps
185
+ (idea files → beads) plus skill/doc updates are handed off explicitly.
186
+ - [ ] For v2: one `kind:idea` + `execution:hitl` bead exists per idea file, a spot-checked bead
187
+ carries its source sections in `--description`/`--design`/`--notes` with the original
188
+ priority, and the source files were left in place for the repo's own cutover to retire.
@@ -1,43 +1,59 @@
1
+ // @ts-check
2
+ // Validator for the composable agent directory layout: `agent.md` plus at
3
+ // least one harness subdirectory with a valid `frontmatter.json`.
4
+ //
5
+ // Zero dependencies: import the pure functions, or run the test suite at
6
+ // `test/validate-agent-dir.test.mjs`.
7
+
1
8
  import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
2
9
  import { join } from "node:path";
3
10
 
4
11
  // ─── Types ────────────────────────────────────────────────────────────────────
5
12
 
6
- export interface Frontmatter {
7
- name: string;
8
- description: string;
9
- tools: string[];
10
- model?: string;
11
- argumentHint?: string;
12
- [key: string]: unknown;
13
- }
14
-
15
- export interface AgentDir {
16
- name: string;
17
- agentMdPath: string;
18
- harnesses: Map<string, { frontmatter: Frontmatter; sections: string[] }>;
19
- }
20
-
21
- export interface ValidationResult {
22
- ok: boolean;
23
- errors: string[];
24
- }
13
+ /**
14
+ * @typedef {object} Frontmatter
15
+ * @property {string} name
16
+ * @property {string} description
17
+ * @property {string[]} tools
18
+ * @property {string} [model]
19
+ * @property {string} [argumentHint]
20
+ */
21
+
22
+ /**
23
+ * @typedef {object} AgentDir
24
+ * @property {string} name
25
+ * @property {string} agentMdPath
26
+ * @property {Map<string, { frontmatter: Frontmatter, sections: string[] }>} harnesses
27
+ */
28
+
29
+ /**
30
+ * @typedef {object} ValidationResult
31
+ * @property {boolean} ok
32
+ * @property {string[]} errors
33
+ */
25
34
 
26
35
  // ─── Constants ────────────────────────────────────────────────────────────────
27
36
 
28
- const REQUIRED_FIELDS = ["name", "description", "tools"] as const;
29
- const KNOWN_OPTIONAL_FIELDS = ["model", "argumentHint"] as const;
37
+ /** @type {readonly string[]} */
38
+ const REQUIRED_FIELDS = ["name", "description", "tools"];
39
+ /** @type {readonly string[]} */
40
+ const KNOWN_OPTIONAL_FIELDS = ["model", "argumentHint"];
30
41
 
31
42
  // ─── Validation ───────────────────────────────────────────────────────────────
32
43
 
33
- export function validateFrontmatter(fm: unknown): ValidationResult {
34
- const errors: string[] = [];
44
+ /**
45
+ * @param {unknown} fm
46
+ * @returns {ValidationResult}
47
+ */
48
+ export function validateFrontmatter(fm) {
49
+ /** @type {string[]} */
50
+ const errors = [];
35
51
 
36
52
  if (typeof fm !== "object" || fm === null) {
37
53
  return { ok: false, errors: ["frontmatter must be an object"] };
38
54
  }
39
55
 
40
- const record = fm as Record<string, unknown>;
56
+ const record = /** @type {Record<string, unknown>} */ (fm);
41
57
 
42
58
  // Check required fields
43
59
  for (const field of REQUIRED_FIELDS) {
@@ -70,7 +86,7 @@ export function validateFrontmatter(fm: unknown): ValidationResult {
70
86
  // Check for unknown fields
71
87
  const knownFields = new Set([...REQUIRED_FIELDS, ...KNOWN_OPTIONAL_FIELDS]);
72
88
  for (const key of Object.keys(record)) {
73
- if (!knownFields.has(key as any)) {
89
+ if (!knownFields.has(/** @type {any} */ (key))) {
74
90
  errors.push(`unknown field: ${key}`);
75
91
  }
76
92
  }
@@ -78,8 +94,13 @@ export function validateFrontmatter(fm: unknown): ValidationResult {
78
94
  return { ok: errors.length === 0, errors };
79
95
  }
80
96
 
81
- export function validateAgentDir(agentDirPath: string): ValidationResult {
82
- const errors: string[] = [];
97
+ /**
98
+ * @param {string} agentDirPath
99
+ * @returns {ValidationResult}
100
+ */
101
+ export function validateAgentDir(agentDirPath) {
102
+ /** @type {string[]} */
103
+ const errors = [];
83
104
 
84
105
  // Check agent.md exists
85
106
  const agentMdPath = join(agentDirPath, "agent.md");
@@ -118,7 +139,7 @@ export function validateAgentDir(agentDirPath: string): ValidationResult {
118
139
  errors.push(`${harnessDir}/frontmatter.json: ${err}`);
119
140
  }
120
141
  }
121
- } catch (e) {
142
+ } catch {
122
143
  errors.push(`${harnessDir}/frontmatter.json: invalid JSON`);
123
144
  }
124
145
  }
@@ -49,11 +49,11 @@ Verify the final document against the verification checklist below before finish
49
49
  - **Padding sections with generic content** — Every section must earn its place with content specific to the skill's purpose. Copying generic filler from the template placeholder text produces a weak skill.
50
50
  - **Skipping the trigger-phrase interview** — The description's trigger phrases are the main routing signal for the skill. Guessing what users say rather than asking produces a skill that is hard to invoke.
51
51
 
52
- ## Cross-skill references
52
+ ## See Also
53
53
 
54
- - Use `refactor-skill` when the task is upgrading an existing skill rather than creating a new one.
55
- - Run `style-code` after writing to check that code conventions in any example snippets or bundled scripts are consistent.
56
- - Run `review-security` before committing to check for leaked secrets in examples or documentation.
54
+ - [refactor-skill](../../review/refactor-skill/SKILL.md) — load when upgrading an existing skill rather than authoring a new one.
55
+ - [style-code](../../style/style-code/SKILL.md) — load when the skill ships code examples or bundled scripts.
56
+ - [review-security](../../review/review-security/SKILL.md) — run before committing, so examples carry no leaked credentials.
57
57
 
58
58
  ## Examples
59
59
 
@@ -72,4 +72,4 @@ Output: A new `skills/review-security/SKILL.md` with front matter, When to use,
72
72
  - [ ] No ALL-CAPS emphasis
73
73
  - [ ] `SKILL.md` ≤ 150 lines (`wc -l skills/<name>/SKILL.md`)
74
74
  - [ ] Supporting docs split by purpose when `SKILL.md` exceeds ~150 lines
75
- - [ ] Cross-skill references point to `refactor-skill` for upgrades where relevant
75
+ - [ ] `See Also` entries link the target `SKILL.md` relatively, state why to load it, and point to `refactor-skill` for upgrades where relevant
@@ -74,14 +74,12 @@ See [REFERENCE.md](REFERENCE.md) for templates, examples, and detailed section g
74
74
  - [ ] Phase 1 complete: audit findings presented as a numbered list; nothing fixed yet.
75
75
  - [ ] Phase 2 complete: every proposal reviewed and approved before applying.
76
76
 
77
- ## Cross-skill references
77
+ ## See Also
78
78
 
79
- | When you need… | Use this skill |
80
- |---|---|
81
- | What and whether to document | `style-documentation` |
82
- | Tone, structure, and concision for the writing | `style-comms` |
83
- | Creating or refactoring a skill | `write-a-skill`, `refactor-skill` |
84
- | Scanning changes for leaked secrets | `review-security` |
79
+ - [style-documentation](../../style/style-documentation/SKILL.md) — what and whether to document, applied to the pages being audited.
80
+ - [style-comms](../../style/style-comms/SKILL.md) — tone and concision for the prose being edited.
81
+ - [refactor-skill](../refactor-skill/SKILL.md) — load when the drift is inside a SKILL.md instead of docs/.
82
+ - [review-security](../review-security/SKILL.md) — run before committing, so audited examples carry no leaked credentials.
85
83
 
86
84
  ## Examples
87
85
 
@@ -14,7 +14,8 @@ description: Refactor an existing SKILL.md to the canonical anatomy template thr
14
14
 
15
15
  ## When NOT to use
16
16
 
17
- - Creating a brand-new skill from scratch — use `write-a-skill` instead.
17
+ - Creating a brand-new skill from scratch — use [write-a-skill](../../productivity/write-a-skill/SKILL.md) instead.
18
+ - Drift in `AGENTS.md` or `docs/` rather than in a `SKILL.md` — use [maintain-agent-docs](../maintain-agent-docs/SKILL.md).
18
19
  - Minor copy-editing or typo fixes that don't need anatomy alignment.
19
20
  - Skills that are already verified against the anatomy template.
20
21
 
@@ -42,7 +43,7 @@ Run through each dimension of the anatomy template and record how the target cur
42
43
  - **Red Flags**: present? Only include for discipline-enforcement skills (security, TDD, review).
43
44
  - **Common Rationalizations**: present? Only include for process-critical skills where shortcut pressure is common.
44
45
  - **Phase-gate checklists**: present? Only include for multi-phase workflows (3+ distinct phases).
45
- - **Cross-skill references**: present? Only include when another skill owns a sub-domain better than restating.
46
+ - **See Also**: present? Only include when another skill owns a sub-domain better than restating — as a relative `SKILL.md` link plus the reason to load it.
46
47
  - **Examples**: present? Only include for non-trivial output contracts.
47
48
  - **Verification checklist**: present? Concrete, machine-checkable items?
48
49
  - **Voice/tone**: imperative second-person? Positive framing? Rationale sentences for non-obvious rules?
@@ -68,7 +69,7 @@ Present the comparison and discuss optional sections using the inclusion criteri
68
69
  | `Red Flags` | The skill enforces process discipline (security, TDD, review) |
69
70
  | `Common Rationalizations` | The skill is process-critical where shortcut pressure is common |
70
71
  | `Phase-gate checklists` | The workflow has 3+ distinct phases |
71
- | `Cross-skill references` | Another skill owns a sub-domain the workflow delegates to |
72
+ | `See Also` | Another skill owns a sub-domain the workflow delegates to |
72
73
  | `Examples` | The output contract is non-trivial (formats, schemas, templates) |
73
74
  | `Philosophy / rationale` | The skill defends an opinionated method with trade-offs |
74
75
 
@@ -71,12 +71,10 @@ When running within a ralph review pipeline, the outcome is communicated through
71
71
  | "I will scan before pushing, not before committing" | The earlier you catch it, the cheaper it is. Pre-commit scan costs two seconds. |
72
72
  | "This is a false positive" | It might be. Verify the context before dismissing it. |
73
73
 
74
- ## Cross-skill references
74
+ ## See Also
75
75
 
76
- | When you need… | Use this skill |
77
- |---|---|
78
- | Code conventions that help avoid embedding secrets | `style-code` |
79
- | Documentation conventions that keep examples secret-free | `style-documentation` |
76
+ - [style-code](../../style/style-code/SKILL.md) — the conventions that keep secrets out of the code in the first place.
77
+ - [style-documentation](../../style/style-documentation/SKILL.md) — the conventions that keep examples in docs secret-free.
80
78
 
81
79
  ## Examples
82
80
 
@@ -68,17 +68,12 @@ description: Defines this project's coding style, conventions, and architectural
68
68
  | "A factory closure is more functional/pure" | State is state — a class names it. A closure over mutable state is an object with extra steps: the state is still there, the API is less discoverable, and nothing is gained. Use `#private` fields and public methods. |
69
69
  | "It's convenient to return the saved row / new count from the write" | That return turns a command into a query mid-flight: the caller now depends on data the mutation happens to produce. Return a typed result for the outcome, and let a separate query read the state if the caller needs it. |
70
70
 
71
- ## Cross-skill references
71
+ ## See Also
72
72
 
73
- | When you need… | Use this skill |
74
- |---|---|
75
- | Test-first development loop | `tdd` |
76
- | Test writing conventions | `style-tests` |
77
- | Building or hardening the project's ubiquitous language | `grill-with-docs` |
78
- | Communication tone and document structure | `style-comms` |
79
- | What and whether to document | `style-documentation` |
80
- | Surfacing architectural friction and deepening shallow modules | `improve-codebase-architecture` |
81
- | Secrets and credential scanning | `review-security` |
73
+ - [tdd](../../engineering/tdd/SKILL.md) — the red-green loop that drives the code being named.
74
+ - [style-tests](../style-tests/SKILL.md) — assertion, mock, and test-data conventions, which these rules leave out.
75
+ - [grill-with-docs](../../engineering/grill-with-docs/SKILL.md) — the ubiquitous language that names and boundaries should follow.
76
+ - [review-security](../../review/review-security/SKILL.md) — run before committing, for leaked secrets these rules cannot catch.
82
77
 
83
78
  ## Examples
84
79