mandrel 2.24.0 → 2.26.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 (189) hide show
  1. package/.agents/agents/acceptance-critic.md +19 -21
  2. package/.agents/agents/auditor.md +16 -19
  3. package/.agents/agents/story-worker.md +41 -54
  4. package/.agents/audit-checklists/architecture.md +5 -1
  5. package/.agents/audit-checklists/baselines.md +21 -0
  6. package/.agents/audit-checklists/quality.md +3 -0
  7. package/.agents/docs/agentrc-reference.json +2 -1
  8. package/.agents/docs/configuration.md +2 -1
  9. package/.agents/docs/quality-gates.md +80 -18
  10. package/.agents/docs/workflows.md +4 -2
  11. package/.agents/instructions.md +1 -1
  12. package/.agents/rules/ci-remediation.md +68 -3
  13. package/.agents/schemas/agentrc.schema.json +6 -1
  14. package/.agents/schemas/audit-rules.json +15 -0
  15. package/.agents/schemas/baselines/audit-baselines-envelope.schema.json +242 -0
  16. package/.agents/schemas/baselines/baseline-envelope.schema.json +8 -0
  17. package/.agents/schemas/baselines/crap.schema.json +13 -1
  18. package/.agents/schemas/crap-report.schema.json +37 -0
  19. package/.agents/schemas/model-attribution.schema.json +4 -0
  20. package/.agents/scripts/acceptance-eval.js +124 -15
  21. package/.agents/scripts/audit-baselines.js +136 -0
  22. package/.agents/scripts/audit-labels-bootstrap.js +16 -95
  23. package/.agents/scripts/audit-to-stories.js +33 -3
  24. package/.agents/scripts/check-arch-cycles.js +12 -93
  25. package/.agents/scripts/check-baseline-drift.js +16 -3
  26. package/.agents/scripts/check-baselines.js +19 -3
  27. package/.agents/scripts/check-context-budget.js +95 -14
  28. package/.agents/scripts/check-cyclomatic.js +214 -0
  29. package/.agents/scripts/check-schema-references.js +392 -0
  30. package/.agents/scripts/check-test-temp-hygiene.js +121 -1
  31. package/.agents/scripts/check-workflow-timeouts.js +291 -0
  32. package/.agents/scripts/cleanup-repo-test-temp.js +7 -5
  33. package/.agents/scripts/deliver-light.js +3 -4
  34. package/.agents/scripts/deliver-recover.js +13 -0
  35. package/.agents/scripts/diagnose-friction.js +85 -19
  36. package/.agents/scripts/lib/audit-baselines/engine.js +177 -0
  37. package/.agents/scripts/lib/audit-baselines/gate-surface.js +63 -0
  38. package/.agents/scripts/lib/audit-baselines/headroom.js +72 -0
  39. package/.agents/scripts/lib/audit-baselines/hotspots.js +69 -0
  40. package/.agents/scripts/lib/audit-baselines/kinds.js +313 -0
  41. package/.agents/scripts/lib/audit-baselines/outliers.js +100 -0
  42. package/.agents/scripts/lib/audit-baselines/read.js +87 -0
  43. package/.agents/scripts/lib/audit-baselines/staleness.js +123 -0
  44. package/.agents/scripts/lib/audit-baselines/surface-entry.js +106 -0
  45. package/.agents/scripts/lib/audit-baselines/trend.js +125 -0
  46. package/.agents/scripts/lib/audit-baselines/weights.js +193 -0
  47. package/.agents/scripts/lib/audit-suite/index.js +0 -5
  48. package/.agents/scripts/lib/audit-suite/selector.js +9 -62
  49. package/.agents/scripts/lib/audit-to-stories/audit-label-taxonomy.js +177 -0
  50. package/.agents/scripts/lib/audit-to-stories/audit-lenses.js +1 -0
  51. package/.agents/scripts/lib/audit-to-stories/build-story-body.js +35 -3
  52. package/.agents/scripts/lib/audit-to-stories/group-findings.js +20 -11
  53. package/.agents/scripts/lib/audit-to-stories/parse-audit-md.js +23 -9
  54. package/.agents/scripts/lib/audit-to-stories/seed-from-findings.js +9 -2
  55. package/.agents/scripts/lib/baseline-loader.js +0 -0
  56. package/.agents/scripts/lib/baseline-schema-registry.js +13 -1
  57. package/.agents/scripts/lib/baselines/diff-scope-cli.js +22 -160
  58. package/.agents/scripts/lib/baselines/duplication-scanner.js +27 -0
  59. package/.agents/scripts/lib/baselines/git-base.js +0 -0
  60. package/.agents/scripts/lib/baselines/kinds/crap.js +499 -57
  61. package/.agents/scripts/lib/baselines/preview-gates.js +58 -15
  62. package/.agents/scripts/lib/baselines/reader.js +10 -0
  63. package/.agents/scripts/lib/baselines/refresh-service.js +69 -11
  64. package/.agents/scripts/lib/baselines/scope.js +39 -90
  65. package/.agents/scripts/lib/baselines/writer.js +16 -7
  66. package/.agents/scripts/lib/changed-files.js +8 -1
  67. package/.agents/scripts/lib/cli-args.js +115 -1
  68. package/.agents/scripts/lib/close-validation/runner.js +70 -25
  69. package/.agents/scripts/lib/config-settings-schema-delivery.js +5 -0
  70. package/.agents/scripts/lib/crap-engine.js +124 -27
  71. package/.agents/scripts/lib/crap-method-identity.js +153 -0
  72. package/.agents/scripts/lib/crap-utils.js +86 -13
  73. package/.agents/scripts/lib/cyclomatic-ceiling.js +265 -0
  74. package/.agents/scripts/lib/env-loader.js +46 -16
  75. package/.agents/scripts/lib/feedback-loop/audit-results-graduator.js +0 -2
  76. package/.agents/scripts/lib/feedback-loop/prior-feedback-fetcher.js +0 -2
  77. package/.agents/scripts/lib/feedback-loop/retro-proposals-graduator.js +0 -2
  78. package/.agents/scripts/lib/findings/route-finding.js +123 -17
  79. package/.agents/scripts/lib/findings/severity.js +80 -2
  80. package/.agents/scripts/lib/git/cached-fetch.js +0 -0
  81. package/.agents/scripts/lib/git-utils.js +136 -80
  82. package/.agents/scripts/lib/import-graph.js +156 -0
  83. package/.agents/scripts/lib/label-constants.js +17 -0
  84. package/.agents/scripts/lib/observability/runtime-friction.js +17 -2
  85. package/.agents/scripts/lib/observability/source-classifier.js +175 -2
  86. package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +110 -17
  87. package/.agents/scripts/lib/orchestration/ceremony-routing.js +17 -12
  88. package/.agents/scripts/lib/orchestration/check-baselines/phases/compare.js +36 -6
  89. package/.agents/scripts/lib/orchestration/check-baselines/phases/evaluate.js +5 -0
  90. package/.agents/scripts/lib/orchestration/check-baselines/phases/floors.js +12 -1
  91. package/.agents/scripts/lib/orchestration/check-baselines/phases/report.js +8 -1
  92. package/.agents/scripts/lib/orchestration/ci-rerun-guard.js +548 -0
  93. package/.agents/scripts/lib/orchestration/deliver-recover.js +2 -2
  94. package/.agents/scripts/lib/orchestration/git-cleanup/phases/phase-drivers.js +10 -5
  95. package/.agents/scripts/lib/orchestration/git-cleanup/phases/render.js +39 -3
  96. package/.agents/scripts/lib/orchestration/lifecycle/listeners/watcher.js +71 -20
  97. package/.agents/scripts/lib/orchestration/light-backstop.js +20 -3
  98. package/.agents/scripts/lib/orchestration/light-escalation.js +82 -3
  99. package/.agents/scripts/lib/orchestration/light-suitability.js +103 -5
  100. package/.agents/scripts/lib/orchestration/plan-context.js +119 -66
  101. package/.agents/scripts/lib/orchestration/plan-persist/fan-out-gate.js +31 -5
  102. package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +216 -109
  103. package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +61 -13
  104. package/.agents/scripts/lib/orchestration/plan-persist/supersede-ops.js +79 -22
  105. package/.agents/scripts/lib/orchestration/plan-text-hygiene.js +51 -20
  106. package/.agents/scripts/lib/orchestration/planning/authoring-context.js +70 -74
  107. package/.agents/scripts/lib/orchestration/planning/memory-pool-advisory.js +231 -0
  108. package/.agents/scripts/lib/orchestration/resolve-stories.js +18 -17
  109. package/.agents/scripts/lib/orchestration/retro-proposals.js +0 -0
  110. package/.agents/scripts/lib/orchestration/run-epilogue.js +12 -0
  111. package/.agents/scripts/lib/orchestration/run-scoped-config.js +276 -0
  112. package/.agents/scripts/lib/orchestration/single-story-close/phases/base-sync.js +41 -10
  113. package/.agents/scripts/lib/orchestration/single-story-close/phases/confirm-merge.js +125 -37
  114. package/.agents/scripts/lib/orchestration/single-story-close/phases/normalize-pr-title.js +6 -6
  115. package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +42 -38
  116. package/.agents/scripts/lib/orchestration/single-story-close/phases/pull-request.js +129 -21
  117. package/.agents/scripts/lib/orchestration/single-story-close/phases/push.js +6 -1
  118. package/.agents/scripts/lib/orchestration/single-story-close/runner.js +267 -125
  119. package/.agents/scripts/lib/orchestration/spec-budget.js +16 -5
  120. package/.agents/scripts/lib/orchestration/story-follow-ups.js +182 -95
  121. package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +22 -0
  122. package/.agents/scripts/lib/orchestration/ticket-validator.js +5 -11
  123. package/.agents/scripts/lib/orchestration/ticketing/reads.js +4 -4
  124. package/.agents/scripts/lib/reserved-test-ids.js +77 -0
  125. package/.agents/scripts/lib/story-adjacency.js +3 -3
  126. package/.agents/scripts/lib/story-plan.js +137 -42
  127. package/.agents/scripts/lib/templates/decomposer-prompts.js +4 -4
  128. package/.agents/scripts/lib/test-runner-contract.js +134 -0
  129. package/.agents/scripts/lib/test-tiers.js +11 -2
  130. package/.agents/scripts/lib/ticket-body-sections.js +1 -1
  131. package/.agents/scripts/lib/util/concurrent-map.js +17 -0
  132. package/.agents/scripts/lib/util/parse-id-list.js +103 -0
  133. package/.agents/scripts/lib/util/poll-loop.js +18 -2
  134. package/.agents/scripts/lib/wave-runner/live-probe.js +29 -13
  135. package/.agents/scripts/lib/wave-runner/ready-set.js +254 -43
  136. package/.agents/scripts/lib/workers/combined-mi-crap-worker.js +10 -13
  137. package/.agents/scripts/lib/workers/crap-worker.js +8 -13
  138. package/.agents/scripts/lib/workers/maintainability-report-worker.js +4 -10
  139. package/.agents/scripts/lib/workers/maintainability-worker.js +4 -10
  140. package/.agents/scripts/lib/workers/serve-worker-messages.js +35 -0
  141. package/.agents/scripts/lib/worktree/git-hooks.js +206 -0
  142. package/.agents/scripts/lib/worktree/lifecycle/creation.js +6 -0
  143. package/.agents/scripts/lib/worktree-manager.js +14 -0
  144. package/.agents/scripts/plan-run-epilogue.js +17 -5
  145. package/.agents/scripts/pr-watch-with-update.js +568 -213
  146. package/.agents/scripts/providers/github/tickets.js +33 -10
  147. package/.agents/scripts/provision-git-hooks.js +85 -0
  148. package/.agents/scripts/quality-preview.js +137 -28
  149. package/.agents/scripts/resolve-stories.js +4 -1
  150. package/.agents/scripts/run-coverage.js +86 -35
  151. package/.agents/scripts/run-lint.js +20 -0
  152. package/.agents/scripts/run-tests.js +36 -36
  153. package/.agents/scripts/single-story-close.js +34 -2
  154. package/.agents/scripts/single-story-confirm-merge.js +22 -6
  155. package/.agents/scripts/single-story-init.js +7 -0
  156. package/.agents/scripts/stories-wave-tick.js +308 -47
  157. package/.agents/scripts/story-plan.js +65 -9
  158. package/.agents/scripts/update-coverage-baseline.js +34 -4
  159. package/.agents/scripts/update-crap-baseline.js +42 -4
  160. package/.agents/scripts/update-duplication-baseline.js +209 -83
  161. package/.agents/scripts/update-maintainability-baseline.js +31 -4
  162. package/.agents/scripts/validate-docs-freshness.js +1 -0
  163. package/.agents/skills/core/diagnose-friction/SKILL.md +4 -1
  164. package/.agents/skills/core/gates-and-baselines/SKILL.md +17 -11
  165. package/.agents/skills/skills.index.json +2 -2
  166. package/.agents/templates/single-story-body.md +16 -8
  167. package/.agents/workflows/audit-architecture.md +69 -13
  168. package/.agents/workflows/audit-baselines.md +289 -0
  169. package/.agents/workflows/audit-navigability.md +5 -4
  170. package/.agents/workflows/audit-quality.md +26 -0
  171. package/.agents/workflows/audit-to-stories.md +30 -4
  172. package/.agents/workflows/deliver.md +92 -97
  173. package/.agents/workflows/helpers/acceptance-self-eval.md +47 -10
  174. package/.agents/workflows/helpers/audit-lens-core.md +25 -4
  175. package/.agents/workflows/helpers/code-quality-guardrails.md +9 -2
  176. package/.agents/workflows/helpers/deliver-digest.md +41 -21
  177. package/.agents/workflows/helpers/deliver-reference.md +95 -4
  178. package/.agents/workflows/helpers/deliver-story-reference.md +174 -52
  179. package/.agents/workflows/helpers/deliver-story.md +104 -119
  180. package/.agents/workflows/helpers/plan-reference.md +49 -5
  181. package/.agents/workflows/memory-consolidate.md +116 -0
  182. package/.agents/workflows/plan.md +62 -75
  183. package/README.md +13 -6
  184. package/docs/CHANGELOG.md +93 -0
  185. package/lib/cli/update.js +14 -11
  186. package/lib/cli/version-check.js +9 -1
  187. package/package.json +9 -4
  188. package/.agents/schemas/friction-event.schema.json +0 -56
  189. package/.agents/scripts/lib/feedback-loop/memory-freshness.js +0 -707
@@ -62,17 +62,15 @@ turned in about it. Your only trusted inputs are:
62
62
  - the **change set** your caller hands you: the list of files this Story
63
63
  touched, computed **once** per delivery by the shared `computeChangeSet`
64
64
  enumerator (`.agents/scripts/lib/orchestration/change-set.js`) and threaded
65
- into your spawn context. Read those files and inspect their changes to see
66
- the work product. Do **not** re-derive the set yourself re-enumerating it
67
- can pick up commits that landed after your caller routed the ceremony, and
68
- then you would be scoring a different change than the one you were dispatched
69
- for (Story #4593). If no change set reached you, say so in your verdict
70
- rather than substituting your own enumeration.
65
+ into your spawn context. Do **not** re-derive the set yourself
66
+ re-enumerating it can pick up commits that landed after your caller routed
67
+ the ceremony, and then you would be scoring a different change than the one
68
+ you were dispatched for (Story #4593). If no change set reached you, say so
69
+ in your verdict rather than substituting your own enumeration.
71
70
  - the Story's inline `acceptance[]` and `verify[]` arrays, read from the
72
71
  **Story body itself** (`gh issue view <storyId> --json body`) — its `##
73
72
  Acceptance` / `## Verify` sections are the SSOT. The `story-init` structured
74
- comment does not carry them: it reports init state (`workCwd`,
75
- `dependenciesInstalled`, `remoteVerified`, …) and nothing else.
73
+ comment does not carry them it reports init state only.
76
74
  - the **actual output** of the `verify[]` commands you run yourself.
77
75
 
78
76
  Treat the implementation reasoning as untrusted. Score each criterion afresh
@@ -84,8 +82,7 @@ You are handed **one cluster** of acceptance criteria to score. You evaluate
84
82
  exactly the criteria in that cluster and emit one verdict record per criterion.
85
83
  You do **not** decide how many clusters exist, re-slice the criteria, or merge
86
84
  clusters — the caller owns clustering (`ceil(totalACs / clusterCeiling)` with
87
- its clamp). Your job is per-criterion scoring within the cluster you were
88
- given.
85
+ its clamp).
89
86
 
90
87
  ## Per-criterion evaluation
91
88
 
@@ -98,8 +95,7 @@ For each acceptance item in your cluster:
98
95
  supporting `verify[]` evidence where a `verify[]` command is relevant to it.
99
96
  `verify[]` is evidence, not optional advisory pre-flight.
100
97
  3. **Share `lint` / `typecheck` evidence with close** (Story #4250). When a
101
- `verify[]` command is **byte-identical** to a close-validation gate in
102
- practice only the command-identical `lint` and `typecheck` gates — run it
98
+ `verify[]` command is **byte-identical** to a close-validation gate, run it
103
99
  through `evidence-gate.js` in the **same Story worktree** close validates so
104
100
  a passing run records an evidence entry in the keyspace close consults:
105
101
 
@@ -115,15 +111,17 @@ For each acceptance item in your cluster:
115
111
 
116
112
  **Never** run the coverage / CRAP suite through `evidence-gate.js` to stamp
117
113
  it fresh — a false-fresh coverage record without `coverage-final.json`
118
- silently weakens the floor. Limit the evidence-share to `lint` and
119
- `typecheck`.
114
+ silently weakens the floor.
120
115
 
121
116
  ## Verdict schema (MUST)
122
117
 
123
- Emit a verdict file under `temp/` conforming to
118
+ Write a verdict file under `temp/` at a **cluster-unique path** (e.g.
119
+ `temp/acceptance-verdict-<storyId>-r<round>-c<clusterIndex>.json`) so parallel
120
+ sibling critics cannot overwrite each other, conforming to
124
121
  [`acceptance-eval-verdict.schema.json`](../schemas/acceptance-eval-verdict.schema.json):
125
122
  one `criteria[]` record per acceptance item in your cluster, in acceptance-array
126
- order.
123
+ order. Each `index` is the criterion's position in the Story's **full**
124
+ `acceptance[]` array, not within your cluster — the caller merges on it.
127
125
 
128
126
  ```json
129
127
  {
@@ -151,11 +149,11 @@ order.
151
149
  - `partial` — partially addressed, or addressed without the required evidence.
152
150
  - `unmet` — not addressed, or the evidence contradicts the claim.
153
151
 
154
- Write verdict files under `temp/` only they are scratch artifacts. Hand the
155
- verdict path to the caller's `acceptance-eval.js` gate, which applies the round
156
- cap and emits the per-criterion `acceptance-eval` signal; the **proceed /
157
- redraft / block** decision is the gate's, not yours. You score; the gate
158
- decides.
152
+ **Return the verdict file's absolute path to your caller never invoke
153
+ `acceptance-eval.js` yourself.** The caller merges every cluster's records into
154
+ one verdict and calls the gate **once** per round; a per-cluster call would burn
155
+ a Story-level round per cluster. The **proceed / redraft / block** decision is
156
+ the gate's, not yours. You score; the gate decides.
159
157
 
160
158
  ## Boundaries
161
159
 
@@ -50,9 +50,9 @@ the step-by-step. This shared core binds every role:
50
50
  You are an **audit lens worker**: you run one read-only audit lens over a
51
51
  scoped surface, filter your own findings, and return a report path plus an
52
52
  Executive Summary. Follow the `audit-<lens>.md` workflow your caller hands you
53
- for the lens-specific dimensions, detection batteries, applicability gates,
54
- and report additions; this delta governs what holds across every lens. The
55
- shared long-form contract is
53
+ for its dimensions, detection batteries, applicability gates and report
54
+ additions; this delta governs every lens. The shared long-form
55
+ contract is
56
56
  [`helpers/audit-lens-core.md`](../workflows/helpers/audit-lens-core.md) — this
57
57
  file is its standalone-agent form.
58
58
 
@@ -61,15 +61,14 @@ file is its standalone-agent form.
61
61
  - This is a **read-only** analysis. Do **not** modify application code, styles,
62
62
  configuration, dependencies, branches, or labels, and never open a PR.
63
63
  - The **only** write you perform is the report artifact at
64
- `{{auditOutputDir}}/audit-<lens>-results.md`, plus — where and only where the
65
- lens body explicitly declares it — a single measurement/baseline artifact it
66
- names (e.g. performance's `perf-baseline.json`).
64
+ `{{auditOutputDir}}/audit-<lens>-results.md`, plus — only where the lens body
65
+ explicitly declares it — a single measurement/baseline artifact it names
66
+ (e.g. `perf-baseline.json`).
67
67
  - Running **non-mutating** measurements/scanners the lens calls for (profilers,
68
- timers, `npm audit`, `actionlint`, read-only ORM status commands) is
69
- permitted; running anything that installs, mutates git/labels, edits source,
70
- or connects to a production database is forbidden. A lens that names a
71
- stricter carve-out (data-model's no-database rule, quality's "do not run the
72
- suite") tightens this for that lens.
68
+ timers, `npm audit`, read-only status commands) is permitted; running
69
+ anything that installs, mutates git/labels, edits source, or connects to a
70
+ production database is forbidden. A lens that names a stricter carve-out
71
+ tightens this for that lens.
73
72
 
74
73
  ## Scope
75
74
 
@@ -77,17 +76,13 @@ Your caller supplies the change-set file list (the lens's `{{changedFiles}}`
77
76
  fence). When it is a populated file list, restrict analysis to those files and
78
77
  their direct dependencies. When it is the literal `{{changedFiles}}` token,
79
78
  there is no scope filter — run the lens codebase-wide. A lens whose body
80
- declares a deviation (documentation's target-set intersection, navigability's
81
- whole-route-tree evaluation) follows its own Scope section instead. When a
82
- surface is absent or inapplicable, say so in the report and emit the lens's
83
- not-applicable / empty result rather than inventing findings.
79
+ declares a deviation follows its own Scope section instead.
84
80
 
85
81
  ## Findings schema — the finding-block skeleton (MUST stay parseable)
86
82
 
87
83
  Write the report with an `## Executive Summary` and a `## Detailed Findings`
88
84
  section. Every finding under Detailed Findings uses this shared skeleton; the
89
- lens may **add** fields (WCAG criterion, CWE ID, `Baseline MUST`, `Evidence`,
90
- `Route / Door` + `Persona(s)`) and may relabel `Severity` ↔ `Impact` and
85
+ lens may **add** fields and may relabel `Severity` `Impact` and
91
86
  `Dimension` ↔ `Category` ↔ `Type`, but never drops a shared field — the
92
87
  `audit-to-stories` parser depends on this shape:
93
88
 
@@ -95,7 +90,7 @@ lens may **add** fields (WCAG criterion, CWE ID, `Baseline MUST`, `Evidence`,
95
90
  ### `path/to/primary-file.ext` — [Short title of the issue]
96
91
 
97
92
  - **Dimension:** [the lens-specific dimension]
98
- - **Severity:** [Critical | High | Medium | Low]
93
+ - **Severity:** [Critical | High | Medium | Low | Info]
99
94
  - **Location:** `path/to/primary-file.ext:line`
100
95
  - **Current State:** [the specific file/line and why it is problematic]
101
96
  - **Recommendation & Rationale:** [how to remediate and why it matters]
@@ -113,10 +108,12 @@ and a surviving **Critical** halts the delivery gate:
113
108
  - **Critical** — an active, exploitable, or data-losing defect that must be
114
109
  fixed before the change ships.
115
110
  - **High** — a serious correctness/security/maintainability risk to fix
116
- promptly; does not by itself block the release.
111
+ promptly; does not block the release.
117
112
  - **Medium** — a real problem worth scheduling; contained blast radius or a
118
113
  workaround exists.
119
114
  - **Low** — minor or cosmetic; fix opportunistically.
115
+ - **Info** — the floor: a grounded observation asking for no scheduled work
116
+ (accepts `Informational`). Never a home for findings that fail the bar below.
120
117
 
121
118
  ## Self-cross-check bar (mandatory before you write the report)
122
119
 
@@ -46,10 +46,10 @@ the step-by-step. This shared core binds every role:
46
46
  # story-worker — Story delivery boot context
47
47
 
48
48
  You are a **Story delivery worker**: you take one Story from init through
49
- implementation to a landed PR, then return. Follow the
50
- `helpers/deliver-story` workflow prose your caller hands you for the
51
- step-by-step; this delta states the non-negotiable MUSTs that hold across
52
- every step. Treat a blocking tool-permission prompt as a harness condition —
49
+ implementation to a **pushed branch**, then return. You do **not** close it —
50
+ your caller owns the close-and-land tail. Follow the `helpers/deliver-story`
51
+ workflow prose your caller hands you; this delta states the non-negotiable
52
+ MUSTs. Treat a blocking tool-permission prompt as a harness condition —
53
53
  transition to `agent::blocked` rather than waiting on an approval that
54
54
  cannot come.
55
55
 
@@ -59,10 +59,9 @@ cannot come.
59
59
  `node .agents/scripts/single-story-init.js --story <storyId>` from the
60
60
  **main checkout**, synchronously with the Bash maximum timeout — a
61
61
  per-worktree install can take minutes; do not background it.
62
- 2. Capture `workCwd` and `dependenciesInstalled` from the flat init
63
- envelope. When worktree isolation is on, work only inside the absolute
64
- `workCwd`; the main checkout's HEAD is never moved by you. Because cwd
65
- may reset between calls, anchor every subsequent path at `workCwd`.
62
+ 2. Capture `workCwd` and `dependenciesInstalled` from the init envelope.
63
+ Work only inside the absolute `workCwd`; never move the main checkout's
64
+ HEAD. Because cwd may reset between calls, anchor every path at `workCwd`.
66
65
 
67
66
  ## Verify branch before every commit (MUST)
68
67
 
@@ -80,32 +79,29 @@ state) to restore the branch first.
80
79
 
81
80
  Author Conventional Commit subjects directly on `story-<storyId>` per
82
81
  [`git-conventions.md`](../rules/git-conventions.md): imperative mood,
83
- ≤100 chars, referencing the Story via `(refs #<storyId>)`. The `commit-msg`
84
- Husky hook runs commitlint — never bypass it with `--no-verify` /
85
- `--no-gpg-sign`. If a hook fails, fix the cause and add a follow-up commit;
86
- do not amend the rejected commit.
82
+ ≤100 chars, referencing the Story via `(refs #<storyId>)`. Never bypass the
83
+ `commit-msg` hook with `--no-verify` / `--no-gpg-sign`. If a hook fails, fix
84
+ the cause and add a follow-up commit; never amend the rejected one.
87
85
 
88
86
  ## Docs context — digest first
89
87
 
90
88
  Do **not** re-read every file in `project.docsContextFiles`. Read the
91
89
  `docsDigestPath` digest your caller passes, then pull full files on demand
92
- at the line numbers it names. A null `docsDigestPath` means no per-Story
93
- docs mandate — read a full doc only when the Story's own context points at
94
- one.
90
+ at the line numbers it names. A null `docsDigestPath` means no docs
91
+ mandate — read a full doc only when the Story's context points at one.
95
92
 
96
93
  ## Close gates — do not pre-run
97
94
 
98
95
  `single-story-close.js` runs the canonical close-validation chain
99
96
  (**typecheck, lint, test, format, maintainability, coverage, crap**) before
100
- it merges. Advisory pre-flight while iterating on a fix is fine, but the
101
- close pipeline is the authoritative gate. The acceptance self-eval loop may
102
- share `lint` / `typecheck` evidence with close via `evidence-gate.js`;
103
- never stamp coverage / CRAP fresh that way.
97
+ it merges. Advisory pre-flight is fine; the close pipeline is the
98
+ authoritative gate. The acceptance self-eval loop may share `lint` /
99
+ `typecheck` evidence with close via `evidence-gate.js`; never stamp
100
+ coverage / CRAP fresh that way.
104
101
 
105
102
  Before trusting a gate's output — or diagnosing a red one — read
106
103
  [`known-tooling-behavior.md`](../rules/known-tooling-behavior.md): measured
107
- cases where a command prints what it does not mean (lint exits 1 under a
108
- `0 error(s)` summary; a green `check-baselines.js` is not `baselines`).
104
+ cases where a command prints what it does not mean.
109
105
 
110
106
  ## Acceptance self-eval before close (MUST)
111
107
 
@@ -115,15 +111,14 @@ run the bounded acceptance self-eval loop
115
111
  It scores the change set you computed **once** and injected into the critic
116
112
  — never one the critic re-derives (Story #4593) — against each
117
113
  `acceptance[]` item, consuming `verify[]` output as required evidence. Gate
118
- outcomes: **proceed** → flip to `closing` and close; **redraft** → fix the
119
- flagged criteria, commit, re-eval; **block** → take the blocked path below.
120
- Never silently proceed to close.
114
+ outcomes: **proceed** → flip to `closing`, push, hand off; **redraft** → fix
115
+ the flagged criteria, commit, re-eval; **block** → take the blocked path
116
+ below. Never silently hand off an unscored branch.
121
117
 
122
118
  ## Lifecycle: progress & blocked (MUST)
123
119
 
124
120
  - **Progress.** Relay one terse line per phase transition (e.g.
125
- `Story #<id>: implementing → closing`); your commits on `story-<id>` and
126
- those lines are the progress surface.
121
+ `Story #<id>: implementing → closing`).
127
122
  - **Blocked.** When you genuinely cannot proceed, transition the Story to
128
123
  `agent::blocked`, post a `friction` comment naming the decision needed
129
124
  (or the unmet criteria and their evidence), and **exit non-zero**.
@@ -134,31 +129,23 @@ Never silently proceed to close.
134
129
 
135
130
  The Story's init envelope carries `remoteVerified` + `remoteProbe`. When
136
131
  `remoteVerified` is `false`, transition the Story to `agent::blocked`
137
- quoting `remoteProbe.detail` and stop. Implementing the Story inline
138
- outside the worktree / branch / PR path — or committing it to local `main`
139
- — is expressly **forbidden**; the close pipeline's push
140
- (`single-story-close.js`) is the only sanctioned landing.
141
-
142
- ## Hold the turn until the envelope arrives (MUST)
143
-
144
- Run close in the **foreground** and wait for it. Never background it,
145
- never delegate it to a child, and never end your turn while it is still
146
- running "close is running" is not a return value. Ending early strands
147
- the envelope in a turn nobody reads and costs your caller a recovery
148
- cycle plus a full resume of you. Close does persist a copy to
149
- `temp/orchestration/story-deliver-terminal-<id>.json`; that is your
150
- caller's fallback, not your licence to return before the verdict.
151
-
152
- ## Return schema
153
-
154
- The return contract is
155
- [`story-deliver-terminal.schema.json`](../schemas/story-deliver-terminal.schema.json)
156
- the SSOT for every field (Story #4543); do not restate them.
157
- `single-story-close.js` emits a validated envelope between its
158
- `--- STORY DELIVER TERMINAL ---` markers — **relay it**, never
159
- hand-compose one. Status ↔ exit code: `landed` → 0; `pending` → 3
160
- (**resumable, not a failure** — its `nextCommand` resumes it; the only
161
- sanctioned no-merge ending); `blocked` / `failed` → exit non-zero via the
162
- blocked path above. Stranded? Probe, don't guess:
163
- `node .agents/scripts/deliver-recover.js --story <id>` (read-only, prints
164
- one next command).
132
+ quoting `remoteProbe.detail` and stop. A PR opened by
133
+ `single-story-close.js` is the only sanctioned landing.
134
+
135
+ ## Your turn ends at a pushed branch (MUST)
136
+
137
+ You do **not** run close. Push `story-<storyId>` to `origin` — confirming
138
+ the remote ref moved — and return. The dispatching orchestrator runs
139
+ `single-story-close.js` in its own session, serialized against your
140
+ siblings. Do not open the PR, do not flip `agent::done`, and do not spawn
141
+ a child to close on your behalf.
142
+
143
+ ## Return contract the hand-off report
144
+
145
+ Return a short, literal hand-off your caller can act on: the Story id,
146
+ `workCwd`, the branch name, the pushed head SHA, the self-eval verdict,
147
+ and the `verify[]` evidence you gathered.
148
+ Say plainly that the branch is pushed and unclosed. Never hand-compose a
149
+ terminal envelope that document belongs to close, and inventing one
150
+ makes an unlanded Story look landed. If the push itself fails, take the
151
+ blocked path above rather than returning a hand-off you cannot back.
@@ -6,7 +6,7 @@
6
6
 
7
7
  # Architecture & Clean Code Audit — authoring checklist
8
8
 
9
- > Audit architectural boundaries, module coupling, and layering violations; emit a structured findings report keyed to High/Medium/Low severity.
9
+ > Audit architectural boundaries, module coupling, layering violations, and shipped-but-uncalled seams; emit a structured findings report keyed to the canonical severity scale.
10
10
 
11
11
  Self-check your change against this lens's concerns before you ship:
12
12
 
@@ -21,3 +21,7 @@ Self-check your change against this lens's concerns before you ship:
21
21
  - [ ] Medium
22
22
  - [ ] Low
23
23
  - [ ] Automated Architecture Guardrails
24
+ - [ ] Shipped-But-Never-Wired Seams (mandatory).
25
+ - [ ] A produced-but-never-consumed artifact.
26
+ - [ ] An optional field nothing populates.
27
+ - [ ] An exported seam with no in-tree caller
@@ -0,0 +1,21 @@
1
+ <!-- GENERATED FILE — do not edit by hand.
2
+ Source of truth: .agents/workflows/audit-baselines.md
3
+ Regenerate: node .agents/scripts/generate-lens-checklists.js
4
+ Drift is gated by: npm run docs:check
5
+ -->
6
+
7
+ # Baseline & Ratchet Audit — authoring checklist
8
+
9
+ > Audit the committed baseline surface — dead instruments, stale baselines, cross-gate hotspot clusters, trend drift, and floor-tightening headroom — and emit findings whose remediation burns the measured debt down and tightens the ratchet behind it.
10
+
11
+ Self-check your change against this lens's concerns before you ship:
12
+
13
+ - [ ] `configError` non-null.
14
+ - [ ] `degradations`.
15
+ - [ ] Dead Instruments.
16
+ - [ ] Staleness.
17
+ - [ ] Hotspot Clusters.
18
+ - [ ] Trend Drift.
19
+ - [ ] Tightening Headroom.
20
+ - [ ] Hotspot Cluster template
21
+ - [ ] Tightening Headroom template
@@ -18,3 +18,6 @@ Self-check your change against this lens's concerns before you ship:
18
18
  - [ ] Test Data Management
19
19
  - [ ] Performance & Execution
20
20
  - [ ] Requirement Alignment
21
+ - [ ] Unwired Seams — Coverage Without a Caller (mandatory).
22
+ - [ ] A produced-but-never-consumed artifact
23
+ - [ ] An optional field nothing populates
@@ -100,7 +100,8 @@
100
100
  "watch": {
101
101
  "pollIntervalMs": 10000,
102
102
  "maxPolls": 180,
103
- "maxResumes": 3
103
+ "maxResumes": 3,
104
+ "attachWindowMs": 1200000
104
105
  },
105
106
  "autoMerge": "trust-ci"
106
107
  },
@@ -278,10 +278,11 @@ top-level keys are validation errors.
278
278
  | `acceptanceEval.maxRounds` | No | `integer` | — | Maximum number of redraft rounds before escalation. Default 2; clamped into [1, hard ceiling] by lib/config/acceptance-eval.js so the cap can never be disabled (maxRounds: 0 clamps up to 1). |
279
279
  | `acceptanceEval.clusterCeiling` | No | `integer` | — | Epic #4475 (M4-B). Max acceptance criteria one single-delivery acceptance critic scores in a single fresh-context pass. Single delivery clusters the Epic ## Acceptance Table ACs into ceil(totalACs / clusterCeiling) groups and spawns one maker-blind critic per cluster, restoring the distributed acceptance coverage the per-Story critic fan-out gave for free. Default 4; clamped into [1, 8] by lib/config/acceptance-eval.js so a large value cannot collapse the fan-out to a single diluted critic. Ignored on the fan-out route. |
280
280
  | `ci` | No | `object` | — | Nested configuration block. |
281
- | `ci.watch` | No | `object` | — | Story #4356 (Epic #4355). Poll-loop tuning for the merge/CI watch. pollIntervalMs is the cadence between check probes; maxPolls caps total probes before the watcher gives up; maxResumes caps how many times the watcher may resume after a transient stall. |
281
+ | `ci.watch` | No | `object` | — | Story #4356 (Epic #4355). Poll-loop tuning for the merge/CI watch. pollIntervalMs is the cadence between check probes; maxPolls caps total probes before the watcher gives up; maxResumes caps how many times the watcher may resume after a transient stall; attachWindowMs bounds the wait for a required context to attach at all. |
282
282
  | `ci.watch.pollIntervalMs` | No | `integer` | — | — |
283
283
  | `ci.watch.maxPolls` | No | `integer` | — | — |
284
284
  | `ci.watch.maxResumes` | No | `integer` | — | — |
285
+ | `ci.watch.attachWindowMs` | No | `integer` | — | Story #4890. How long (ms) the watch keeps re-resolving an EMPTY `gh pr checks --required` set before it stops waiting for a required context to attach. A ruleset attaches its contexts asynchronously and the arrival latency is set by the slowest one, so a required context that is an aggregator job gated on every other tier is the last to appear — measured at 16m52s on this repository. Default 1200000 (20 minutes). Raise it for a repository whose contexts arrive later still; exhausting the window is never reported as a red check (the watch exits 2, not-yet-started). |
285
286
  | `ci.autoMerge` | No | `"trust-ci"` \| `"strict"` | — | Story #4356 (Epic #4355). Merge posture. 'trust-ci' (default) merges once required checks pass; 'strict' additionally requires a clean review gate. |
286
287
  | `routing` | No | `object` | — | v2 delivery-spawn routing: role-scoped boot contexts and maker-checker sampling. The v1 singleDelivery epic-route kill-switch was removed in Stage 6. |
287
288
  | `routing.roleScopedAgents` | No | `boolean` | — | Epic #4478 (M7-B). Kill-switch for the role-scoped boot contexts. When true (default), a converted delivery spawn (`story-worker`, `acceptance-critic`) boots on its own `.claude/agents/<role>.md` system prompt instead of re-paying the full CLAUDE.md @-import closure (≈50KB → ≈8KB per spawn — the payoff of the context diet). When false, every converted spawn falls back to `subagent_type: general-purpose` — the instant, code-rollback-free per-consumer revert, and the universal escape for hosts that ignore `.claude/agents/`. The fallback is the full-closure agent that ran before M7-B, so flipping it off never drops a gate. |
@@ -102,13 +102,18 @@ npm run coverage:update # writes baselines/coverage.json from the run
102
102
  runners that orchestrate coverage capture separately).
103
103
 
104
104
  The files-out-of-scope list is declared in [`.c8rc.cjs`](../../.c8rc.cjs) —
105
- thin CLI shells (e.g. `agents-bootstrap-github.js`, `plan-context.js`,
106
- `plan-persist.js`) plus the larger Story #1702 carve-out of
107
- top-level/orchestration/git CLIs and `lib/*` glue, each with a per-entry
108
- rationale in the `.c8rc.cjs` header comment (the authoritative list). Every
109
- excluded file also carries `/* node:coverage ignore file */` at the top of its
110
- source as a second line of defence; the header comment MUST be updated when the
111
- list changes.
105
+ thin CLI shells plus the larger Story #1702 carve-out of
106
+ top-level/orchestration/git CLIs and `lib/*` glue. The `exclude[]` array is
107
+ the **single** declaration: each entry carries its rationale as an inline
108
+ comment on the line above it. Story #4922 removed the prose inventory the
109
+ header used to duplicate two copies of one list in one file, 27 files
110
+ apart by the time it was measured. Do not reintroduce one. Every excluded
111
+ file also carries `/* node:coverage ignore file */` at the top of its source
112
+ as a second line of defence.
113
+
114
+ `.c8rc.cjs`'s `include` globs and `delivery.quality.gates.coverage.targetDirs`
115
+ in [`.agentrc.json`](../../.agentrc.json) MUST name the same roots — the gate
116
+ scores what c8 measures. `tests/c8rc-scope.test.js` asserts both invariants.
112
117
 
113
118
  ---
114
119
 
@@ -123,11 +128,30 @@ touched it:
123
128
 
124
129
  | Metric | Floor | Scope |
125
130
  | --- | --- | --- |
126
- | Coverage — lines | ≥ 90 % | per file |
127
- | Coverage — branches | ≥ 85 % | per file |
128
- | Coverage — functions | ≥ 90 % | per file |
129
- | Maintainability Index | ≥ 70 | per file |
130
- | CRAP | ≤ 20 | per method |
131
+ | Coverage — lines | ≥ 94 % | repo rollup |
132
+ | Coverage — branches | ≥ 85 % | repo rollup |
133
+ | Coverage — functions | ≥ 87 % | repo rollup |
134
+ | Maintainability Index | ≥ 70 | repo rollup |
135
+ | CRAP — methods above 20 | ≤ 13 | repo rollup |
136
+
137
+ Floors are enforced against the baseline's `rollup` components — the
138
+ `applyFloors` phase compares `rollup["*"]` (and any named component), never
139
+ individual rows. Story #4922 corrected this table, which previously read
140
+ "per file" and quoted 90/85/90 for coverage; those numbers came from the
141
+ example in `.agents/docs/agentrc-reference.json`, which is validated only
142
+ against itself, and the coverage gate was not configured at all.
143
+
144
+ The live coverage floors are derived from the measurement in
145
+ [`baselines/coverage.json`](../../baselines/coverage.json) — a full-tier run
146
+ scored 95.65 / 86.16 / 88.52, and each floor sits ~1–1.7 points under its
147
+ axis. Re-derive them, do not invent them, whenever the baseline is
148
+ regenerated wholesale.
149
+
150
+ The coverage gate deliberately declares **no `tolerance`**, so its
151
+ head-vs-base ratchet arm reports regressions without failing the build (the
152
+ same shape the `crap` gate uses). Story #4922's scope was making the
153
+ instrument honest; arming the ratchet belongs with the debt burn-down that
154
+ the widened measurement newly exposes.
131
155
 
132
156
  The floors are declared in [`.agentrc.json`](../../.agentrc.json) under
133
157
  `delivery.quality.gates.<gate>.floors.*` (defaults baked into the helper
@@ -173,11 +197,11 @@ The floor gate is only as strict as its scope, so the `exclude` list in
173
197
  [`.c8rc.cjs`](../../.c8rc.cjs) carries three hard requirements that are
174
198
  enforced by review (and partially by the audit suite):
175
199
 
176
- 1. **One-line rationale per entry.** Every file in `exclude[]` MUST have
177
- a bulleted justification in the `.c8rc.cjs` header comment naming
178
- *why* it is excluded — typically "thin CLI shell, meaningful logic
179
- lives in `lib/<X>` and is unit-tested there." A bare path with no
180
- rationale is a review-block.
200
+ 1. **One-line rationale per entry.** Every file in `exclude[]` MUST carry
201
+ an inline comment on the line(s) directly above it naming *why* it is
202
+ excluded — typically "thin CLI shell, meaningful logic lives in
203
+ `lib/<X>` and is unit-tested there." A bare path with no rationale is a
204
+ review-block, and `tests/c8rc-scope.test.js` fails on one.
181
205
  2. **`/* node:coverage ignore file */` pragma at source.** Every
182
206
  excluded file MUST carry the Node coverage pragma at the top of its
183
207
  own source. This is the second line of defence: when `c8 report` and
@@ -260,6 +284,42 @@ default and the deep-merge extender form).
260
284
 
261
285
  ---
262
286
 
287
+ ## Cyclomatic ceiling ratchet
288
+
289
+ `delivery.quality.codingGuardrails.cyclomaticMustFix` (default `12`) is the
290
+ per-function complexity ceiling, enforced by `check-cyclomatic.js`. It is a
291
+ **standalone ratchet** — the same slot as `check-arch-cycles.js`,
292
+ `check-dead-exports.js`, and `check-context-budget.js` — not a
293
+ `delivery.quality.gates` kind, so it needs no gate block and no floor.
294
+
295
+ ```bash
296
+ node .agents/scripts/check-cyclomatic.js # the gate
297
+ node .agents/scripts/check-cyclomatic.js --update # re-record the breaches
298
+ ```
299
+
300
+ `baselines/cyclomatic.json` records, per file, how many functions currently
301
+ sit above the ceiling and how bad the worst one is. The gate fails when a
302
+ file's over-ceiling count rises (including `0 → 1`, a brand-new breach) or
303
+ when its worst function gets worse than recorded. Shrinking and disappearing
304
+ are the success signals and never fail.
305
+
306
+ Recording existing breaches is what makes the ceiling adoptable: a repository
307
+ with dozens of over-ceiling functions can turn the gate on today and burn them
308
+ down on its own schedule, instead of disabling a gate that fails on the first
309
+ commit. Re-run `--update` after a deliberate refactor; that is the only motion
310
+ allowed to raise a recorded count, and it shows up in review as a baseline
311
+ diff.
312
+
313
+ The scan reuses `delivery.quality.gates.maintainability.targetDirs` /
314
+ `ignoreGlobs` — both instruments read the same coverage-free escomplex
315
+ surface, so a separate scope declaration could only ever restate it.
316
+
317
+ `cyclomaticFlag` (default `8`) is the softer half of the pair: it is not
318
+ gated, and names the ceiling `quality:preview` counts new methods against in
319
+ its `new-method count over c=<flag>` column.
320
+
321
+ ---
322
+
263
323
  ## CRAP gate — Consumer onboarding
264
324
 
265
325
  > Baseline envelope, axes, and component model: see the
@@ -436,7 +496,9 @@ are not comparable to rows scored by this one, and neither `kernelVersion` nor
436
496
  therefore carries a `scoringSemantics` stamp; `check-baselines` fails closed on
437
497
  a mismatch with the exact re-baseline command rather than comparing across the
438
498
  boundary. Bump the stamp whenever the coverage join, the line coordinate
439
- system, or the unresolved-method policy changes.
499
+ system, the unresolved-method policy, or the method identity rule changes
500
+ Story #4969 bumped it for the last of these, replacing escomplex's positional
501
+ `<anon method-N>` label with an enclosing-scope-path identity.
440
502
 
441
503
  ---
442
504
 
@@ -32,12 +32,13 @@ by `node .agents/scripts/generate-workflows-doc.js`; `npm run docs:check`
32
32
  fails when it drifts from the on-disk workflow set. To change a command’s
33
33
  description, edit the workflow file’s front-matter and regenerate.
34
34
 
35
- ## Commands (25)
35
+ ## Commands (27)
36
36
 
37
37
  | Command | Description |
38
38
  | --- | --- |
39
39
  | `/audit-accessibility` | Audit WCAG accessibility conformance (static-first) with an optional runtime verification pass, and produce a structured findings report |
40
- | `/audit-architecture` | Audit architectural boundaries, module coupling, and layering violations; emit a structured findings report keyed to High/Medium/Low severity. |
40
+ | `/audit-architecture` | Audit architectural boundaries, module coupling, layering violations, and shipped-but-uncalled seams; emit a structured findings report keyed to the canonical severity scale. |
41
+ | `/audit-baselines` | Audit the committed baseline surface — dead instruments, stale baselines, cross-gate hotspot clusters, trend drift, and floor-tightening headroom — and emit findings whose remediation burns the measured debt down and tightens the ratchet behind it. |
41
42
  | `/audit-clean-code` | Audit code smells, dead code, complexity hotspots, and maintainability-index outliers; emit a structured findings report. |
42
43
  | `/audit-data-model` | Audit the persistence layer as a first-class artifact — model↔migration↔seed drift, constraint completeness, migration hygiene, type fidelity, and access-pattern fit; gated by a persistence-layer applicability probe so DB-less repos skip cleanly. |
43
44
  | `/audit-dependencies` | Audit `package.json` for unused, outdated, and major-version-stale dependencies; surface Node-engine drift and propose upgrade batches. |
@@ -56,6 +57,7 @@ description, edit the workflow file’s front-matter and regenerate.
56
57
  | `/git-cleanup` | Tidy the local checkout in four phases: fast-forward `main`, prune stale remote-tracking refs, sweep merged branches (squash-aware), and triage `git stash` entries — each step gated by operator confirmation. |
57
58
  | `/git-deliver` | Single ad-hoc delivery command for working-tree changes. Detects the git setup and escalates to the right terminal step — commit only, commit + push, or commit + push + open a PR with native auto-merge — picking the default from observable state and letting flags pin any level explicitly. Replaces the retired git-commit-all, git-push, and git-pr-all trio. |
58
59
  | `/mandrel-update` | npm-era upgrade wraparound for a Mandrel consumer. Runs `npx mandrel update` (resolve newest published version → install → re-materialize `.agents/` → migrate → doctor → surface changelog) as the single mechanical step, then walks the operator through the judgment wraparound the CLI deliberately leaves unowned: reconcile `.agentrc.json`, install the stabilized quality-gate surface, refresh the harness permission allowlist, reconcile the consumer's `AGENTS.md` / runbooks against the surfaced changelog, and stage + commit the staged lockfile bump. |
60
+ | `/memory-consolidate` | Attended consolidation pass over this project's agent memory pool — merge duplicates, verify claims against the current tree, prune with operator confirmation, rewrite the index, and stamp the pool so the /plan advisory goes quiet. |
59
61
  | `/plan` | Unified planning entry point. Interrogate → author → persist. Emits one Story by default; splits into N>1 only under the default-single split policy. |
60
62
  | `/prototype` | Operator-invoked UI prototype pass. Discovers the consumer's design-system SSOT first, then — only after the operator confirms — writes exactly one self-contained HTML file under the gitignored workspace-root temp tree, so a layout can be reviewed before its UI acceptance criteria are authored. |
61
63
  | `/qa-assist` | Human-led QA assist loop — set up, then ride a rolling multi-observation intake session. The operator reports observations in any order; the agent enriches each (repro + root-cause file:line + coverage verdict for bugs; analysis + options + recommendation for enhancements), asks clarifying questions only when ambiguous, and appends a redacted ledger item — recording, never planning — to a persistent, resumable session under temp/qa/. Only when the operator says they are done does it review the full ledger and hand off to /plan. |
@@ -79,7 +79,7 @@ present, else the **Tech Stack** section of `docs/architecture.md`.
79
79
 
80
80
  You MUST log operational friction (repeated tool errors, unrecoverable
81
81
  command failures, self-corrected ambiguity, automatable boilerplate):
82
- `node .agents/scripts/diagnose-friction.js --story [STORY_ID] --cmd [FAILED_COMMAND]`
82
+ `node .agents/scripts/diagnose-friction.js --story [STORY_ID] --cmd <cmd> <args...>`
83
83
  — a **local NDJSON signal** (not posted to the ticket). Schema and the
84
84
  `AGENT_LOG_LEVEL` table:
85
85
  [`docs/execution-reference.md`](docs/execution-reference.md#friction-telemetry).