mandrel 2.30.0 → 2.32.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.
- package/.agents/README.md +13 -17
- package/.agents/agents/acceptance-critic.md +1 -2
- package/.agents/docs/SDLC.md +4 -4
- package/.agents/docs/agentrc-reference.json +61 -57
- package/.agents/docs/configuration.md +274 -227
- package/.agents/docs/execution-reference.md +13 -14
- package/.agents/docs/quality-gates.md +195 -23
- package/.agents/instructions.md +2 -5
- package/.agents/rules/ci-remediation.md +44 -1
- package/.agents/rules/git-conventions-reference.md +27 -27
- package/.agents/rules/git-conventions.md +4 -2
- package/.agents/rules/known-tooling-behavior.md +66 -30
- package/.agents/rules/testing-standards.md +35 -71
- package/.agents/runtime-deps.json +0 -1
- package/.agents/schemas/agentrc.schema.json +1939 -1400
- package/.agents/schemas/lifecycle/README.md +21 -14
- package/.agents/schemas/lifecycle/ledger-record.schema.json +76 -22
- package/.agents/schemas/story-deliver-terminal.schema.json +2 -2
- package/.agents/scripts/README.md +7 -29
- package/.agents/scripts/apply-quality-bootstrap.js +27 -34
- package/.agents/scripts/bootstrap.js +28 -26
- package/.agents/scripts/check-baseline-drift.js +73 -13
- package/.agents/scripts/check-baseline-scope.js +362 -0
- package/.agents/scripts/check-dead-exports.js +9 -1
- package/.agents/scripts/check-gherkin-corpus.js +508 -0
- package/.agents/scripts/check-knip-entries.js +136 -0
- package/.agents/scripts/check-lifecycle-lint.js +36 -112
- package/.agents/scripts/check-schema-references.js +1 -1
- package/.agents/scripts/diagnose-friction.js +7 -4
- package/.agents/scripts/generate-config-docs.js +263 -171
- package/.agents/scripts/install-matrix-assert.js +0 -1
- package/.agents/scripts/lib/ITicketingProvider.js +0 -58
- package/.agents/scripts/lib/audit-baselines/staleness.js +6 -6
- package/.agents/scripts/lib/audit-baselines/trend.js +7 -8
- package/.agents/scripts/lib/audit-baselines/weights.js +4 -5
- package/.agents/scripts/lib/audit-suite/checklist-threading.js +1 -1
- package/.agents/scripts/lib/audit-to-stories/build-story-body.js +0 -1
- package/.agents/scripts/lib/baselines/envelope.js +41 -60
- package/.agents/scripts/lib/baselines/git-base.js +30 -37
- package/.agents/scripts/lib/baselines/kinds/_crap-new-method-gate.js +103 -0
- package/.agents/scripts/lib/baselines/kinds/_crap-read.js +150 -0
- package/.agents/scripts/lib/baselines/kinds/crap.js +25 -65
- package/.agents/scripts/lib/baselines/orphan-pruner.js +233 -0
- package/.agents/scripts/lib/baselines/refresh-service.js +6 -8
- package/.agents/scripts/lib/baselines/scope-assert.js +223 -0
- package/.agents/scripts/lib/baselines/scope-inventory.js +314 -0
- package/.agents/scripts/lib/bdd-step-index.js +326 -0
- package/.agents/scripts/lib/bootstrap/install-ledger.js +5 -3
- package/.agents/scripts/lib/bootstrap/issue-forms-template.js +4 -6
- package/.agents/scripts/lib/bootstrap/manifest.js +17 -40
- package/.agents/scripts/lib/bootstrap/project-bootstrap.js +12 -59
- package/.agents/scripts/lib/bootstrap/quality-bootstrap.js +62 -2
- package/.agents/scripts/lib/checks/loop-health.js +9 -37
- package/.agents/scripts/lib/child-exec.js +193 -0
- package/.agents/scripts/lib/cli/standard-args.js +1 -1
- package/.agents/scripts/lib/cli-args.js +64 -0
- package/.agents/scripts/lib/close-validation/gates.js +2 -2
- package/.agents/scripts/lib/close-validation/runner.js +3 -3
- package/.agents/scripts/lib/config/acceptance-eval.js +5 -52
- package/.agents/scripts/lib/config/commands.js +3 -5
- package/.agents/scripts/lib/config/explain.js +5 -7
- package/.agents/scripts/lib/config/gates/bundle-size.schema.js +32 -6
- package/.agents/scripts/lib/config/gates/coverage.schema.js +25 -5
- package/.agents/scripts/lib/config/gates/crap-incremental-coverage.schema.js +12 -2
- package/.agents/scripts/lib/config/gates/crap.schema.js +68 -23
- package/.agents/scripts/lib/config/gates/duplication.schema.js +29 -17
- package/.agents/scripts/lib/config/gates/index.js +5 -2
- package/.agents/scripts/lib/config/gates/lighthouse.schema.js +34 -6
- package/.agents/scripts/lib/config/gates/lint.schema.js +11 -2
- package/.agents/scripts/lib/config/gates/maintainability.schema.js +37 -15
- package/.agents/scripts/lib/config/gates/mutation.schema.js +15 -3
- package/.agents/scripts/lib/config/gates/shared.js +58 -9
- package/.agents/scripts/lib/config/github.js +0 -1
- package/.agents/scripts/lib/config/limits.js +3 -48
- package/.agents/scripts/lib/config/qa.js +105 -0
- package/.agents/scripts/lib/config/temp-paths.js +6 -5
- package/.agents/scripts/lib/config-settings-schema-delivery.js +237 -56
- package/.agents/scripts/lib/config-settings-schema-quality.js +209 -29
- package/.agents/scripts/lib/config-settings-schema.js +386 -39
- package/.agents/scripts/lib/crap-baseline-join.js +126 -9
- package/.agents/scripts/lib/crap-utils.js +84 -520
- package/.agents/scripts/lib/dead-exports-knip.js +79 -10
- package/.agents/scripts/lib/degraded-mode.js +2 -2
- package/.agents/scripts/lib/doc-tiers.js +3 -3
- package/.agents/scripts/lib/feedback-loop/graduator-core.js +46 -104
- package/.agents/scripts/lib/feedback-loop/retro-proposals-graduator.js +10 -8
- package/.agents/scripts/lib/fs-walk.js +52 -0
- package/.agents/scripts/lib/git-branch-lifecycle.js +2 -2
- package/.agents/scripts/lib/git-utils.js +16 -36
- package/.agents/scripts/lib/knip-entry-sync.js +469 -0
- package/.agents/scripts/lib/observability/metrics-ledger.js +1 -1
- package/.agents/scripts/lib/observability/runtime-friction.js +10 -0
- package/.agents/scripts/lib/observability/signal-validator.js +5 -85
- package/.agents/scripts/lib/observability/signals-writer.js +19 -62
- package/.agents/scripts/lib/observability/source-classifier.js +5 -7
- package/.agents/scripts/lib/observability/terse-result.js +3 -3
- package/.agents/scripts/lib/orchestration/behind-recovery.js +114 -0
- package/.agents/scripts/lib/orchestration/ceremony-routing.js +7 -8
- package/.agents/scripts/lib/orchestration/ci-rerun-guard.js +34 -33
- package/.agents/scripts/lib/orchestration/code-review.js +2 -2
- package/.agents/scripts/lib/orchestration/complexity-gate.js +43 -161
- package/.agents/scripts/lib/orchestration/diff-magnitude.js +4 -4
- package/.agents/scripts/lib/orchestration/label-transitions.js +3 -2
- package/.agents/scripts/lib/orchestration/lease-guard-shared.js +12 -38
- package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-unlanded.js +5 -6
- package/.agents/scripts/lib/orchestration/plan-metrics.js +2 -3
- package/.agents/scripts/lib/orchestration/plan-persist/persist-helpers.js +6 -0
- package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +0 -1
- package/.agents/scripts/lib/orchestration/{lifecycle/listeners/watcher.js → pr-watch.js} +58 -208
- package/.agents/scripts/lib/orchestration/resolve-stories.js +5 -15
- package/.agents/scripts/lib/orchestration/review-providers/codex.js +1 -1
- package/.agents/scripts/lib/orchestration/review-providers/mi-exemptions.js +130 -0
- package/.agents/scripts/lib/orchestration/review-providers/native.js +30 -16
- package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +1 -1
- package/.agents/scripts/lib/orchestration/single-story-close/phases/confirm-merge.js +37 -26
- package/.agents/scripts/lib/orchestration/single-story-close/phases/conventional-subject.js +376 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/normalize-pr-title.js +161 -151
- package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +15 -3
- package/.agents/scripts/lib/orchestration/single-story-close/phases/pull-request.js +10 -15
- package/.agents/scripts/lib/orchestration/single-story-close/phases/push.js +17 -2
- package/.agents/scripts/lib/orchestration/single-story-close/phases/review-block.js +5 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/review-override.js +157 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/worktree-reap.js +0 -14
- package/.agents/scripts/lib/orchestration/single-story-close/runner.js +65 -25
- package/.agents/scripts/lib/orchestration/single-story-lease-guard.js +20 -31
- package/.agents/scripts/lib/orchestration/spec-spill.js +17 -3
- package/.agents/scripts/lib/orchestration/story-close/phases/review-core.js +7 -6
- package/.agents/scripts/lib/orchestration/story-deliver-terminal.js +2 -1
- package/.agents/scripts/lib/orchestration/task-body-validator.js +4 -1
- package/.agents/scripts/lib/orchestration/ticket-lease.js +28 -127
- package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +1 -1
- package/.agents/scripts/lib/orchestration/ticketing/reads.js +5 -5
- package/.agents/scripts/lib/orchestration/ticketing/transition.js +5 -4
- package/.agents/scripts/lib/orchestration/verify-tier-repair.js +107 -0
- package/.agents/scripts/lib/qa/coverage-verdict.js +5 -87
- package/.agents/scripts/lib/signals/detectors/common.js +1 -1
- package/.agents/scripts/lib/signals/index.js +8 -6
- package/.agents/scripts/lib/signals/schema.js +20 -25
- package/.agents/scripts/lib/signals/write.js +8 -8
- package/.agents/scripts/lib/story-body/story-body.js +12 -59
- package/.agents/scripts/lib/temp-retention.js +1 -1
- package/.agents/scripts/lib/templates/decomposer-prompts.js +16 -14
- package/.agents/scripts/lib/ticket-body-sections.js +4 -5
- package/.agents/scripts/lib/worktree/lifecycle/merge-reachability.js +13 -45
- package/.agents/scripts/lib/worktree/lifecycle/reap.js +4 -5
- package/.agents/scripts/lib/worktree-manager.js +2 -3
- package/.agents/scripts/lint-label-vocabulary.js +2 -24
- package/.agents/scripts/pr-watch-with-update.js +7 -5
- package/.agents/scripts/providers/github/cache.js +2 -2
- package/.agents/scripts/providers/github/comments.js +6 -28
- package/.agents/scripts/providers/github/compose.js +0 -15
- package/.agents/scripts/providers/github/errors.js +10 -27
- package/.agents/scripts/providers/github/request-helpers.js +1 -2
- package/.agents/scripts/providers/github/sub-issues.js +10 -218
- package/.agents/scripts/providers/github.js +4 -7
- package/.agents/scripts/prune-baseline-orphans.js +181 -0
- package/.agents/scripts/resolve-stories.js +0 -2
- package/.agents/scripts/run-lint.js +61 -61
- package/.agents/scripts/run-test-profile.js +6 -6
- package/.agents/scripts/run-verify.js +48 -30
- package/.agents/scripts/single-story-close.js +20 -0
- package/.agents/scripts/single-story-init.js +12 -35
- package/.agents/scripts/update-dead-exports-baseline.js +321 -0
- package/.agents/skills/core/gates-and-baselines/SKILL.md +2 -2
- package/.agents/skills/skills.index.json +2 -12
- package/.agents/skills/stack/qa/playwright/SKILL.md +48 -0
- package/.agents/workflows/audit-documentation.md +5 -6
- package/.agents/workflows/audit-to-stories.md +2 -2
- package/.agents/workflows/helpers/audit-lens-core.md +11 -12
- package/.agents/workflows/helpers/code-quality-guardrails.md +15 -14
- package/.agents/workflows/helpers/code-review.md +3 -8
- package/.agents/workflows/helpers/deliver-reference.md +2 -1
- package/.agents/workflows/helpers/deliver-story-reference.md +27 -16
- package/.agents/workflows/helpers/worktree-lifecycle.md +1 -2
- package/.agents/workflows/mandrel-update.md +10 -10
- package/.agents/workflows/qa-assist.md +15 -20
- package/.agents/workflows/qa-explore.md +9 -8
- package/README.md +1 -1
- package/docs/CHANGELOG.md +49 -0
- package/lib/migrations/index.js +2 -0
- package/lib/migrations/steps/2.32.0-retire-lint-baseline-command.js +127 -0
- package/package.json +12 -3
- package/.agents/schemas/lifecycle/checkpoint.written.schema.json +0 -13
- package/.agents/schemas/lifecycle/close-validate.end.schema.json +0 -18
- package/.agents/schemas/lifecycle/close-validate.start.schema.json +0 -13
- package/.agents/schemas/lifecycle/code-review.end.schema.json +0 -30
- package/.agents/schemas/lifecycle/code-review.start.schema.json +0 -12
- package/.agents/schemas/lifecycle/intervention.recorded.schema.json +0 -15
- package/.agents/schemas/lifecycle/loop.tick.schema.json +0 -20
- package/.agents/schemas/lifecycle/notification.emitted.schema.json +0 -18
- package/.agents/schemas/lifecycle/pr.created.schema.json +0 -14
- package/.agents/schemas/lifecycle/retro.end.schema.json +0 -16
- package/.agents/schemas/lifecycle/retro.start.schema.json +0 -12
- package/.agents/schemas/lifecycle/story.blocked.schema.json +0 -13
- package/.agents/schemas/lifecycle/story.dispatch.end.schema.json +0 -17
- package/.agents/schemas/lifecycle/story.dispatch.start.schema.json +0 -15
- package/.agents/schemas/lifecycle/story.merged.schema.json +0 -13
- package/.agents/scripts/check-gherkin-placeholders.js +0 -663
- package/.agents/scripts/check-lifecycle-doc-drift.js +0 -411
- package/.agents/scripts/lib/audit-suite/cli.js +0 -64
- package/.agents/scripts/lib/bootstrap/baselines-layout-migration.js +0 -202
- package/.agents/scripts/lib/bootstrap/ci-workflow-template.js +0 -212
- package/.agents/scripts/lib/checks/baseline-drift-main-checkout.js +0 -104
- package/.agents/scripts/lib/checks/push-hook-parity.js +0 -106
- package/.agents/scripts/lib/checks/windows-coverage-noise-floor.js +0 -92
- package/.agents/scripts/lib/checks/worktree-bootstrap-env.js +0 -81
- package/.agents/scripts/lib/checks/worktree-residue-biome.js +0 -55
- package/.agents/scripts/lib/crap-baseline-index.js +0 -46
- package/.agents/scripts/lib/crap-utils-incremental.js +0 -113
- package/.agents/scripts/lib/dynamic-workflow/capability.js +0 -396
- package/.agents/scripts/lib/feedback-loop/audit-results-graduator.js +0 -335
- package/.agents/scripts/lib/mutation/baseline-snapshot.js +0 -239
- package/.agents/scripts/lib/mutation/config-detector.js +0 -119
- package/.agents/scripts/lib/mutation/stryker-runner.js +0 -306
- package/.agents/scripts/lib/mutation/survivor-report.js +0 -160
- package/.agents/scripts/lib/observability/active-story-env.js +0 -170
- package/.agents/scripts/lib/observability/tool-trace-hook.js +0 -456
- package/.agents/scripts/lib/orchestration/acceptance-clusters.js +0 -111
- package/.agents/scripts/lib/orchestration/context-envelope.js +0 -277
- package/.agents/scripts/lib/orchestration/detectors-phase.js +0 -194
- package/.agents/scripts/lib/orchestration/lifecycle/bus.js +0 -309
- package/.agents/scripts/lib/orchestration/lifecycle/emit-loop-tick.js +0 -181
- package/.agents/scripts/lib/orchestration/lifecycle/ledger-writer.js +0 -229
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/README.md +0 -54
- package/.agents/scripts/lib/orchestration/lifecycle/trace-logger.js +0 -344
- package/.agents/scripts/lib/orchestration/lint-baseline-service.js +0 -114
- package/.agents/scripts/lib/orchestration/pr-base-guard.js +0 -37
- package/.agents/scripts/lib/orchestration/resolves-token.js +0 -127
- package/.agents/scripts/lib/orchestration/spec-section-validator.js +0 -130
- package/.agents/scripts/lib/orchestration/story-close/emit-blocked.js +0 -55
- package/.agents/scripts/lib/orchestration/story-close/phases/code-review.js +0 -211
- package/.agents/scripts/lib/planning-corpus.js +0 -37
- package/.agents/scripts/lib/qa/coverage-report.js +0 -181
- package/.agents/scripts/lib/qa/propose-missing-test.js +0 -95
- package/.agents/scripts/lib/qa/qa-context-hydrator.js +0 -217
- package/.agents/scripts/lib/signals/detectors/index.js +0 -14
- package/.agents/scripts/lib/signals/detectors/retry.js +0 -253
- package/.agents/scripts/lib/signals/detectors/rework.js +0 -167
- package/.agents/scripts/lib/signals/read.js +0 -268
- package/.agents/scripts/lib/signals/span-tree.js +0 -291
- package/.agents/scripts/lib/story-lifecycle.js +0 -194
- package/.agents/scripts/lib/story-plan.js +0 -379
- package/.agents/scripts/lib/util/phase-timer-state.js +0 -72
- package/.agents/scripts/lib/util/phase-timer.js +0 -163
- package/.agents/scripts/lib/workers/combined-mi-crap-worker.js +0 -169
- package/.agents/scripts/lint-baseline.js +0 -507
- package/.agents/scripts/providers/github/prs.js +0 -103
- package/.agents/scripts/signals-view.js +0 -309
- package/.agents/scripts/story-plan.js +0 -370
- package/.agents/scripts/sync-branch-from-base.js +0 -149
- package/.agents/scripts/validate-docs-freshness.js +0 -314
- package/.agents/skills/core/diagnose-friction/SKILL.md +0 -78
- package/.agents/workflows/helpers/signals.md +0 -112
|
@@ -116,8 +116,7 @@ PowerShell `Get-CimInstance Win32_Process`, terminating them with
|
|
|
116
116
|
- The close output reports `pending-cleanup persistent-lock: story-N, ...`.
|
|
117
117
|
- `git worktree list` shows `.worktrees/story-N/` for a closed Story.
|
|
118
118
|
- `npm run lint` fails because of a nested `biome.json` in a half-reaped
|
|
119
|
-
worktree.
|
|
120
|
-
failure mode.
|
|
119
|
+
worktree.
|
|
121
120
|
|
|
122
121
|
### Manual usage
|
|
123
122
|
|
|
@@ -150,22 +150,22 @@ in Step 5). Full procedure:
|
|
|
150
150
|
node .agents/scripts/apply-quality-bootstrap.js
|
|
151
151
|
```
|
|
152
152
|
|
|
153
|
-
Runs the same idempotent
|
|
154
|
-
[`bootstrap.js`](../scripts/bootstrap.js) uses — `applyQualityBootstrap`
|
|
155
|
-
|
|
156
|
-
|
|
153
|
+
Runs the same idempotent install the quality-gates phase of
|
|
154
|
+
[`bootstrap.js`](../scripts/bootstrap.js) uses — `applyQualityBootstrap` —
|
|
155
|
+
and prints a `{ quality }` JSON envelope. The five quality-bootstrap
|
|
156
|
+
outcomes: **helper** (materialize
|
|
157
157
|
[`code-quality-guardrails.md`](helpers/code-quality-guardrails.md)),
|
|
158
158
|
**hook** (install the `.husky/pre-commit` diff-scoped `quality:preview`
|
|
159
159
|
invocation — a pre-existing **custom hook is never overwritten silently**;
|
|
160
160
|
the action is `custom-hook-skip` and the helper returns the snippet to
|
|
161
161
|
append by hand), **scripts** (backfill `quality:preview` /
|
|
162
162
|
`quality:watch` only when absent), **config** (seed missing
|
|
163
|
-
`delivery.quality.*` defaults — operator overrides survive)
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
main-tracked root baselines are never touched. A second run reports
|
|
167
|
-
`no-change` on every path — the idempotence
|
|
168
|
-
requires.
|
|
163
|
+
`delivery.quality.*` defaults — operator overrides survive), and
|
|
164
|
+
**legacyBaselines** (`git rm` a committed pre-v2 `baselines/epic/` tree —
|
|
165
|
+
the Story-only v2 model retired every reader of those per-Epic snapshots;
|
|
166
|
+
the main-tracked root baselines are never touched). A second run reports
|
|
167
|
+
`no-change` / `already-present` / `absent` on every path — the idempotence
|
|
168
|
+
contract this workflow requires.
|
|
169
169
|
|
|
170
170
|
## Step 3.6 — Refresh the harness permission allowlist
|
|
171
171
|
|
|
@@ -172,27 +172,21 @@ every decision to the shared helpers; never re-derive them in prose.
|
|
|
172
172
|
surfaces it touches, the **options**, and a brief **recommendation** with
|
|
173
173
|
trade-offs. Still pin the relevant `file:line` anchor(s) where the change
|
|
174
174
|
would land.
|
|
175
|
-
3. **
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
```js
|
|
181
|
-
import { hydrateQaContext } from '../scripts/lib/qa/qa-context-hydrator.js';
|
|
182
|
-
const context = await hydrateQaContext({ ticketNumber, githubPort, gitPort, surfaceMap });
|
|
183
|
-
```
|
|
184
|
-
|
|
175
|
+
3. **Locate the code.** Read the source ticket with
|
|
176
|
+
`gh issue view <ticketNumber> --json title,body,labels`, and verify each
|
|
177
|
+
surface-map path resolves with `git cat-file -e HEAD:<path>` — flag every
|
|
178
|
+
miss rather than citing a path that does not exist.
|
|
185
179
|
4. **Compute the coverage verdict** for the surface the observation points at,
|
|
186
180
|
via [`coverage-verdict.js`](../scripts/lib/qa/coverage-verdict.js) — the
|
|
187
181
|
deterministic seam behind the
|
|
188
182
|
[`core/qa-coverage-mapping`](../skills/core/qa-coverage-mapping/SKILL.md)
|
|
189
183
|
skill. Read that skill for how to assemble the `surface` input and read the
|
|
190
|
-
per-tier `{present|absent}` verdict.
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
184
|
+
per-tier `{present|absent}` verdict.
|
|
185
|
+
5. **Name the missing test** (if any) from that verdict: take the lowest tier
|
|
186
|
+
the verdict marks `absent` (unit → contract → acceptance) and write one
|
|
187
|
+
concrete sentence describing the test that would close it. Every tier
|
|
188
|
+
`present` means no missing test. Record that sentence as the ledger item's
|
|
189
|
+
`missingTest`.
|
|
196
190
|
6. **Classify** the finding via
|
|
197
191
|
[`classify-finding.js`](../scripts/lib/findings/classify-finding.js) so the
|
|
198
192
|
tentative `class` resolves to the correct focus/meta label set. The helper
|
|
@@ -273,10 +267,11 @@ the `/qa-assist`-specific deltas are:
|
|
|
273
267
|
- **Persistent, resumable rolling session** — `/qa-assist` defaults to resuming
|
|
274
268
|
the same session and appending; a reused session carries the untriaged backlog
|
|
275
269
|
forward and never overwrites a prior ledger.
|
|
276
|
-
- **Enrichment
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
270
|
+
- **Enrichment delegates where a helper exists** — the coverage verdict and
|
|
271
|
+
the finding classification come from their deterministic helpers, never from
|
|
272
|
+
prose. Context lookup and the missing-test sentence are the model's own work:
|
|
273
|
+
they are judgments, not computations, and routing them through a module only
|
|
274
|
+
bought a round-trip.
|
|
280
275
|
|
|
281
276
|
## See also
|
|
282
277
|
|
|
@@ -176,10 +176,11 @@ For each observation the agent makes while driving:
|
|
|
176
176
|
[`core/qa-coverage-mapping`](../skills/core/qa-coverage-mapping/SKILL.md)
|
|
177
177
|
skill. Read that skill for how to assemble the `surface` input and read the
|
|
178
178
|
per-tier `{present|absent}` verdict.
|
|
179
|
-
3. **
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
Record
|
|
179
|
+
3. **Name the missing test** (if any) from that verdict: take the lowest tier
|
|
180
|
+
the verdict marks `absent` (unit → contract → acceptance) and write one
|
|
181
|
+
concrete sentence describing the test that would close it. Every tier
|
|
182
|
+
`present` means no missing test. Record that sentence as the ledger item's
|
|
183
|
+
`missingTest` (or `null`).
|
|
183
184
|
4. **Append a `QaLedgerItem`** to the ledger (shape per
|
|
184
185
|
[`helpers/qa-core.md`](helpers/qa-core.md)): a stable `id`, the redacted
|
|
185
186
|
`evidence`, the `coverage` label (the `surface`, or `unknown`), a tentative
|
|
@@ -230,10 +231,10 @@ the `/qa-explore`-specific deltas are:
|
|
|
230
231
|
and fall back to static.
|
|
231
232
|
- **Broken navigation is a finding, not a workaround** — never URL-jump around a
|
|
232
233
|
missing affordance, a nav 404, or a guard redirect loop.
|
|
233
|
-
- **Delegate coverage
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
234
|
+
- **Delegate the coverage verdict to the helper.** Tier placement comes from
|
|
235
|
+
[`coverage-verdict.js`](../scripts/lib/qa/coverage-verdict.js) — deterministic,
|
|
236
|
+
never re-derived in prose. The missing-test sentence is yours to write from
|
|
237
|
+
that verdict's lowest `absent` tier.
|
|
237
238
|
|
|
238
239
|
## See also
|
|
239
240
|
|
package/README.md
CHANGED
|
@@ -87,7 +87,7 @@ time to confirm the install is healthy.
|
|
|
87
87
|
> Prefer a surgical alternative? Replace `shamefully-hoist` with a scoped
|
|
88
88
|
> `public-hoist-pattern[]=` line per package listed in
|
|
89
89
|
> `.agents/runtime-deps.json` (`ajv`, `ajv-formats`, `js-yaml`, `minimatch`,
|
|
90
|
-
> `picomatch`, `
|
|
90
|
+
> `picomatch`, `typhonjs-escomplex`). If `mandrel doctor`
|
|
91
91
|
> reports `runtime-deps missing: …`, this is the fix.
|
|
92
92
|
|
|
93
93
|
`bootstrap.js` is interactive on a TTY and auto-accepts the
|
package/docs/CHANGELOG.md
CHANGED
|
@@ -15,6 +15,55 @@ All notable changes to this project will be documented in this file.
|
|
|
15
15
|
-->
|
|
16
16
|
<!-- markdownlint-disable-file MD004 MD012 MD037 -->
|
|
17
17
|
|
|
18
|
+
## [2.32.0](https://github.com/dsj1984/mandrel/compare/mandrel-v2.31.0...mandrel-v2.32.0) (2026-08-06)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
### ⚠ BREAKING CHANGES
|
|
22
|
+
|
|
23
|
+
* `.agents/scripts/validate-docs-freshness.js` is removed from the published payload. It had no invoker in `package.json` scripts, Husky hooks, CI workflows, or any workflow markdown, so no shipped flow loses a step. A consumer calling it by hand should drop the call; the `delivery.docsFreshness.paths` key it read is unchanged and is still consumed by the audit-documentation lens.
|
|
24
|
+
* `project.commands.lintBaseline` is removed from the `.agentrc.json` schema. The `project.commands` block is `additionalProperties: false`, so a config still carrying the key now fails validation instead of being ignored. `npx mandrel update` deletes it for you; delete it by hand otherwise. Nothing replaces it — the framework no longer ships a lint-baseline capture CLI, and a consumer that wants the `lint` baseline kind writes `baselines/lint.json` from its own linter.
|
|
25
|
+
* `ITicketingProvider` no longer declares `getRecentComments`, `addSubIssue`, `removeSubIssue` or `createPullRequest`, and `GitHubProvider` no longer installs them. A consumer implementing or calling those members must drop them: open pull requests with `gh pr create` (as `single-story-close.js` does) and read a ticket's comments through `getTicketComments`.
|
|
26
|
+
* `apply-quality-bootstrap.js` no longer prints a `baselines` key. Its stdout envelope is now `{ quality }`, and the retired baselines migration is reported as `quality.legacyBaselines` instead. A consumer parsing `.baselines.action` from `/mandrel-update` Step 3.5 must read `.quality.legacyBaselines.action` (`absent` | `pruned`); the pre-v2 snapshot relocation into `temp/epic/<id>/baselines/` no longer happens at all.
|
|
27
|
+
* the delivery.lease config block (delivery.lease.ttlMs) is removed from .agentrc.json. The schema now rejects it as an unknown key, so a consumer carrying it must delete the block. Nothing replaces it: the lease has no TTL, and a stranded claim is cleared with --steal.
|
|
28
|
+
* `delivery.acceptanceEval.clusterCeiling` is removed from the agentrc schema. The block is `additionalProperties: false`, so a consumer `.agentrc.json` still carrying the key now fails AJV validation — delete the key; nothing read it.
|
|
29
|
+
|
|
30
|
+
### Added
|
|
31
|
+
|
|
32
|
+
* baseline honesty surface: framework-owned scope/staleness gate + measurement-free orphan pruner ([#5012](https://github.com/dsj1984/mandrel/issues/5012)) ([#5016](https://github.com/dsj1984/mandrel/issues/5016)) ([71f7134](https://github.com/dsj1984/mandrel/commit/71f713419bba8523ab6bbca60fb962d5919f18b1))
|
|
33
|
+
* **baselines:** baseline-refresh: schedule the full-scope re-score ([#5028](https://github.com/dsj1984/mandrel/issues/5028)) ([eee9005](https://github.com/dsj1984/mandrel/commit/eee9005933a572f69ac3faa94bfc1d7193dfd7d4))
|
|
34
|
+
* **gates:** make the dead-exports ratchet detect whole-file death (refs [#5001](https://github.com/dsj1984/mandrel/issues/5001)) ([#5014](https://github.com/dsj1984/mandrel/issues/5014)) ([38dfc3c](https://github.com/dsj1984/mandrel/commit/38dfc3c690c14c80b0fd2dc97dd7cbd599a19322))
|
|
35
|
+
* one child-process exec wrapper: single maxBuffer SSOT, normalized errors, lint-banned raw spawns ([#5009](https://github.com/dsj1984/mandrel/issues/5009)) ([#5029](https://github.com/dsj1984/mandrel/issues/5029)) ([956dcfc](https://github.com/dsj1984/mandrel/commit/956dcfc777fe74b2c35e208ee1a44ee7a47a3fd1))
|
|
36
|
+
* planning surface diet: delete the parallel authoring pipeline and stop rejecting output the validator can already fix ([#5005](https://github.com/dsj1984/mandrel/issues/5005)) ([#5020](https://github.com/dsj1984/mandrel/issues/5020)) ([a62efd5](https://github.com/dsj1984/mandrel/commit/a62efd5d27f9d82761f150a5edd0388eb0370493))
|
|
37
|
+
* **quality:** derive knip's CLI entry list instead of trusting memory ([#5026](https://github.com/dsj1984/mandrel/issues/5026)) ([7554851](https://github.com/dsj1984/mandrel/commit/7554851979de86622baf58f2467b5198d3202ed9))
|
|
38
|
+
* ship a fail-closed dead-exports baseline producer so the ratchet has an updater, not a hand-edit ([#5011](https://github.com/dsj1984/mandrel/issues/5011)) ([#5033](https://github.com/dsj1984/mandrel/issues/5033)) ([eede007](https://github.com/dsj1984/mandrel/commit/eede007c502fab485de480c2517516f8e015491d))
|
|
39
|
+
* ship a static gherkin corpus gate: must-compile with the real parser, must-bind scoped per step root ([#5013](https://github.com/dsj1984/mandrel/issues/5013)) ([#5034](https://github.com/dsj1984/mandrel/issues/5034)) ([9f4e83e](https://github.com/dsj1984/mandrel/commit/9f4e83ede2c7a55a6dd94e2d8b162e54fb4de217))
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
### Fixed
|
|
43
|
+
|
|
44
|
+
* close six defects found reviewing the v2.32.0 release diff ([#5035](https://github.com/dsj1984/mandrel/issues/5035)) ([625004c](https://github.com/dsj1984/mandrel/commit/625004ccc65a65508ef99b239ddd09fafb13c56f))
|
|
45
|
+
* **close:** review lens must honour maintainability ignoreGlobs; add a logged override ([#5030](https://github.com/dsj1984/mandrel/issues/5030)) ([e21ff82](https://github.com/dsj1984/mandrel/commit/e21ff82b8ee80c80a9d3ff7803247c992f0a3abc))
|
|
46
|
+
* derive the squash subject from release impact, keep acronyms, propagate breaking changes ([#5027](https://github.com/dsj1984/mandrel/issues/5027)) ([a7bb9af](https://github.com/dsj1984/mandrel/commit/a7bb9af0353853c60ac6a2b59ea04b7c66695dbc))
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
### Changed
|
|
50
|
+
|
|
51
|
+
* cRAP surface diet: delete the dead combined scan, unify the baseline read path, stop the c≈5 cap on untestable CLI wiring ([#5002](https://github.com/dsj1984/mandrel/issues/5002)) ([#5017](https://github.com/dsj1984/mandrel/issues/5017)) ([7624c12](https://github.com/dsj1984/mandrel/commit/7624c125f974cce0820d494b63efad6e56b9beae))
|
|
52
|
+
* delivery/orchestration sweep: retire Epic-era close residue and collapse self-documented-unreachable machinery ([#5006](https://github.com/dsj1984/mandrel/issues/5006)) ([#5021](https://github.com/dsj1984/mandrel/issues/5021)) ([7c19dc5](https://github.com/dsj1984/mandrel/commit/7c19dc5d449f4a9926a7b59c9c9f0dbadf92e091))
|
|
53
|
+
* **orchestration:** delete production-dead story-lifecycle module ([#5025](https://github.com/dsj1984/mandrel/issues/5025)) ([811966c](https://github.com/dsj1984/mandrel/commit/811966c0e1d0f2a746261e342f64acfe1b6f6bd5))
|
|
54
|
+
* providers/QA/misc sweep: prune Epic-era provider surface, dead subsystems, and QA round-trip ceremony ([#5008](https://github.com/dsj1984/mandrel/issues/5008)) ([#5023](https://github.com/dsj1984/mandrel/issues/5023)) ([a019c14](https://github.com/dsj1984/mandrel/commit/a019c144149b23b7102fcd39e466842a3880cfa2))
|
|
55
|
+
* remove the write-only observability surface: tool-trace hooks, dead signals viewer, Epic-era graduator ([#5003](https://github.com/dsj1984/mandrel/issues/5003)) ([#5018](https://github.com/dsj1984/mandrel/issues/5018)) ([3a6273f](https://github.com/dsj1984/mandrel/commit/3a6273f3dc78796ac89a62c1fefa0d95200bac8e))
|
|
56
|
+
* retire the orphaned lifecycle-bus stratum: bus, both observers, the emitter-less schemas, and the doc-drift guard behind them ([#5024](https://github.com/dsj1984/mandrel/issues/5024)) ([#5032](https://github.com/dsj1984/mandrel/issues/5032)) ([caed250](https://github.com/dsj1984/mandrel/commit/caed2501520ce292832b99f12a5478350954c8b9))
|
|
57
|
+
* rules refresh: retire the phantom docs-freshness gate, demote §1.H, condense testing pedagogy ([#5010](https://github.com/dsj1984/mandrel/issues/5010)) ([#5031](https://github.com/dsj1984/mandrel/issues/5031)) ([18715c4](https://github.com/dsj1984/mandrel/commit/18715c4a13448b0992ad8b005193414a0fcf493f))
|
|
58
|
+
* single-source the config surface and finish the bootstrap vestige cleanup ([#5007](https://github.com/dsj1984/mandrel/issues/5007)) ([#5022](https://github.com/dsj1984/mandrel/issues/5022)) ([073415e](https://github.com/dsj1984/mandrel/commit/073415ebbefb2b5d4df05e3e52bbd4b11cf73120))
|
|
59
|
+
|
|
60
|
+
## [2.31.0](https://github.com/dsj1984/mandrel/compare/mandrel-v2.30.0...mandrel-v2.31.0) (2026-08-05)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
### Added
|
|
64
|
+
|
|
65
|
+
* **qa:** add an attach-don't-boot seam and an unreproducible-tier verdict (refs [#4994](https://github.com/dsj1984/mandrel/issues/4994)) ([#4995](https://github.com/dsj1984/mandrel/issues/4995)) ([dac7986](https://github.com/dsj1984/mandrel/commit/dac79868a305e34db01005f06f638fc384c21c17)), closes [#4993](https://github.com/dsj1984/mandrel/issues/4993)
|
|
66
|
+
|
|
18
67
|
## [2.30.0](https://github.com/dsj1984/mandrel/compare/mandrel-v2.29.0...mandrel-v2.30.0) (2026-08-04)
|
|
19
68
|
|
|
20
69
|
|
package/lib/migrations/index.js
CHANGED
|
@@ -57,6 +57,7 @@ import { retireVerifyConcurrencyCap } from './steps/2.1.0-retire-verify-concurre
|
|
|
57
57
|
import { retireEpicAcTags } from './steps/2.2.0-retire-epic-ac-tags.js';
|
|
58
58
|
import { retireMaxSeedWords } from './steps/2.11.0-retire-max-seed-words.js';
|
|
59
59
|
import { retireCodebaseSnapshot } from './steps/2.20.0-retire-codebase-snapshot.js';
|
|
60
|
+
import { retireLintBaselineCommand } from './steps/2.32.0-retire-lint-baseline-command.js';
|
|
60
61
|
|
|
61
62
|
/**
|
|
62
63
|
* Ordered registry of migration steps. MUST stay sorted ascending by
|
|
@@ -75,6 +76,7 @@ export const migrations = [
|
|
|
75
76
|
retireEpicAcTags,
|
|
76
77
|
retireMaxSeedWords,
|
|
77
78
|
retireCodebaseSnapshot,
|
|
79
|
+
retireLintBaselineCommand,
|
|
78
80
|
];
|
|
79
81
|
|
|
80
82
|
/**
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
// lib/migrations/steps/2.32.0-retire-lint-baseline-command.js
|
|
2
|
+
/**
|
|
3
|
+
* Story #5004 follow-up — strip the retired `project.commands.lintBaseline`
|
|
4
|
+
* key from a consumer's `.agentrc.json`.
|
|
5
|
+
*
|
|
6
|
+
* #5004 (PR #5019) deleted `lint-baseline.js` and
|
|
7
|
+
* `lib/orchestration/lint-baseline-service.js`: the CLI spawned the configured
|
|
8
|
+
* command and parsed ESLint-shaped JSON, a shape this repo's own `npm run
|
|
9
|
+
* lint` (Biome + markdownlint fan-out) never produced, and nothing invoked the
|
|
10
|
+
* service. The key left the runtime AJV schema, the published mirror,
|
|
11
|
+
* `.agentrc.json` and `agentrc-reference.json` in the same change.
|
|
12
|
+
*
|
|
13
|
+
* `project.commands` carries `additionalProperties: false`, so a consumer
|
|
14
|
+
* whose config still sets `lintBaseline` hits a hard validation failure on
|
|
15
|
+
* upgrade, not a warning. This step strips the key before that check runs —
|
|
16
|
+
* the same contract-cutover pattern as `2.11.0-retire-max-seed-words.js`.
|
|
17
|
+
*
|
|
18
|
+
* It sweeps **both** config surfaces. `config-resolver.js` deep-merges
|
|
19
|
+
* `.agentrc.local.json` over `.agentrc.json` and validates the result, so a
|
|
20
|
+
* key surviving in the operator's overlay fails exactly as a base one would.
|
|
21
|
+
* Sweeping only the base would report "nothing to migrate" and leave that
|
|
22
|
+
* consumer hard-broken with no self-service remedy — re-running
|
|
23
|
+
* `mandrel update` would keep reporting clean — while this commit's
|
|
24
|
+
* `BREAKING CHANGE:` footer promises the upgrade deletes the key for them.
|
|
25
|
+
*
|
|
26
|
+
* The `lint` baseline KIND survives for consumers whose own linter writes
|
|
27
|
+
* `baselines/lint.json`; only the framework-owned capture shell is gone, so
|
|
28
|
+
* nothing here touches the baseline file or the gate config.
|
|
29
|
+
*
|
|
30
|
+
* This step is also the carrier for the release note #5004 never emitted: its
|
|
31
|
+
* commit ships the `BREAKING CHANGE:` footer that the squash subject on `main`
|
|
32
|
+
* (`227e1af4`) lacks, and which release-please therefore could not surface.
|
|
33
|
+
* See `single-story-close/phases/conventional-subject.js` for the close-side
|
|
34
|
+
* fix that stops the next one being lost.
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
import nodeFs from 'node:fs';
|
|
38
|
+
import path from 'node:path';
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Both config surfaces the resolver reads. `.agentrc.local.json` is deep-merged
|
|
42
|
+
* over the base *before* the AJV gate runs
|
|
43
|
+
* (`.agents/scripts/lib/config-resolver.js`), so a `lintBaseline` surviving in
|
|
44
|
+
* the overlay fails validation exactly as one in the base would — and a step
|
|
45
|
+
* that swept only the base would leave that consumer hard-broken with no
|
|
46
|
+
* self-service remedy, since re-running `mandrel update` would keep reporting
|
|
47
|
+
* clean. The overlay is operator-owned and gitignored, which is why it is easy
|
|
48
|
+
* to forget and why the sweep has to name it explicitly.
|
|
49
|
+
*/
|
|
50
|
+
const AGENTRC_FILENAMES = Object.freeze([
|
|
51
|
+
'.agentrc.json',
|
|
52
|
+
'.agentrc.local.json',
|
|
53
|
+
]);
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* @param {unknown} ctx
|
|
57
|
+
* @param {string} filename
|
|
58
|
+
* @returns {string}
|
|
59
|
+
*/
|
|
60
|
+
function resolveAgentrcPath(ctx, filename) {
|
|
61
|
+
const projectRoot = ctx?.projectRoot ?? process.cwd();
|
|
62
|
+
return path.join(projectRoot, filename);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* @param {unknown} ctx
|
|
67
|
+
* @param {typeof nodeFs} fsImpl
|
|
68
|
+
* @param {string} filename
|
|
69
|
+
* @returns {object | null}
|
|
70
|
+
*/
|
|
71
|
+
function readAgentrcConfig(ctx, fsImpl, filename) {
|
|
72
|
+
try {
|
|
73
|
+
const raw = fsImpl.readFileSync(resolveAgentrcPath(ctx, filename), 'utf8');
|
|
74
|
+
return JSON.parse(raw);
|
|
75
|
+
} catch {
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* @param {object | null} config
|
|
82
|
+
* @returns {boolean}
|
|
83
|
+
*/
|
|
84
|
+
function hasRetiredKey(config) {
|
|
85
|
+
const commands = config?.project?.commands;
|
|
86
|
+
return Boolean(commands) && Object.hasOwn(commands, 'lintBaseline');
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export const retireLintBaselineCommand = {
|
|
90
|
+
version: '2.32.0',
|
|
91
|
+
description:
|
|
92
|
+
'strip retired project.commands.lintBaseline from .agentrc.json ' +
|
|
93
|
+
'(the framework lint-baseline capture CLI is gone — Story #5004)',
|
|
94
|
+
/**
|
|
95
|
+
* @param {{ projectRoot?: string, fs?: typeof nodeFs }} [ctx]
|
|
96
|
+
* @returns {boolean}
|
|
97
|
+
*/
|
|
98
|
+
detect(ctx) {
|
|
99
|
+
const fsImpl = ctx?.fs ?? nodeFs;
|
|
100
|
+
return AGENTRC_FILENAMES.some((filename) =>
|
|
101
|
+
hasRetiredKey(readAgentrcConfig(ctx, fsImpl, filename)),
|
|
102
|
+
);
|
|
103
|
+
},
|
|
104
|
+
/**
|
|
105
|
+
* @param {{ projectRoot?: string, fs?: typeof nodeFs }} [ctx]
|
|
106
|
+
* @returns {void}
|
|
107
|
+
*/
|
|
108
|
+
apply(ctx) {
|
|
109
|
+
const fsImpl = ctx?.fs ?? nodeFs;
|
|
110
|
+
for (const filename of AGENTRC_FILENAMES) {
|
|
111
|
+
const config = readAgentrcConfig(ctx, fsImpl, filename);
|
|
112
|
+
// An absent overlay is the common case, not an error.
|
|
113
|
+
if (!config || !hasRetiredKey(config)) continue;
|
|
114
|
+
|
|
115
|
+
delete config.project.commands.lintBaseline;
|
|
116
|
+
// An emptied `commands` block is left in place: unlike
|
|
117
|
+
// `planning.complexityGate`, `project` is a required block and an empty
|
|
118
|
+
// `commands` object is valid against the schema, so pruning it would be
|
|
119
|
+
// a cosmetic edit to a config the consumer owns.
|
|
120
|
+
|
|
121
|
+
fsImpl.writeFileSync(
|
|
122
|
+
resolveAgentrcPath(ctx, filename),
|
|
123
|
+
`${JSON.stringify(config, null, 2)}\n`,
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mandrel",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.32.0",
|
|
4
4
|
"description": "Claude Code-first opinionated workflow framework: instructions, skills, rules, and SDLC workflows that govern AI coding assistants.",
|
|
5
5
|
"files": [
|
|
6
6
|
".agents/",
|
|
@@ -28,10 +28,12 @@
|
|
|
28
28
|
"coverage:update": "node .agents/scripts/update-coverage-baseline.js",
|
|
29
29
|
"coverage:reanchor": "node .agents/scripts/update-coverage-baseline.js --full-scope",
|
|
30
30
|
"baseline:agents-loc": "node baselines/agents-loc-baseline.mjs",
|
|
31
|
+
"baselines:scope": "node .agents/scripts/check-baseline-scope.js",
|
|
32
|
+
"baselines:prune": "node .agents/scripts/prune-baseline-orphans.js",
|
|
31
33
|
"lint:md": "markdownlint-cli2 \".agents/**/*.md\" \"*.md\" \"!node_modules/**\" \"!.worktrees/**\"",
|
|
32
34
|
"lint": "node .agents/scripts/run-lint.js && npm run docs:check",
|
|
33
35
|
"docs:gen": "node .agents/scripts/generate-config-docs.js && node .agents/scripts/generate-lifecycle-docs.js && node .agents/scripts/generate-workflows-doc.js && node .agents/scripts/generate-lens-checklists.js",
|
|
34
|
-
"docs:check": "node .agents/scripts/generate-config-docs.js --check && node .agents/scripts/generate-lifecycle-docs.js --check && node .agents/scripts/generate-workflows-doc.js --check && node .agents/scripts/generate-lens-checklists.js --check && node .agents/scripts/check-
|
|
36
|
+
"docs:check": "node .agents/scripts/generate-config-docs.js --check && node .agents/scripts/generate-lifecycle-docs.js --check && node .agents/scripts/generate-workflows-doc.js --check && node .agents/scripts/generate-lens-checklists.js --check && node .agents/scripts/check-doc-links.js && npm run skills:check",
|
|
35
37
|
"skills:index": "node .agents/scripts/generate-skills-index.js",
|
|
36
38
|
"skills:check": "node .agents/scripts/generate-skills-index.js --check",
|
|
37
39
|
"format": "biome format --write .",
|
|
@@ -43,6 +45,8 @@
|
|
|
43
45
|
"check:context-budget": "node .agents/scripts/check-context-budget.js",
|
|
44
46
|
"check:cyclomatic": "node .agents/scripts/check-cyclomatic.js",
|
|
45
47
|
"cyclomatic:update": "node .agents/scripts/check-cyclomatic.js --update",
|
|
48
|
+
"dead-exports:update": "node .agents/scripts/update-dead-exports-baseline.js && node .agents/scripts/update-dead-exports-baseline.js --production",
|
|
49
|
+
"check:knip-entries": "node .agents/scripts/check-knip-entries.js",
|
|
46
50
|
"check:schema-refs": "node .agents/scripts/check-schema-references.js",
|
|
47
51
|
"check:workflow-citations": "node .agents/scripts/check-workflow-citations.js",
|
|
48
52
|
"crap:check": "node .agents/scripts/check-baselines.js --gate crap",
|
|
@@ -87,6 +91,7 @@
|
|
|
87
91
|
"@biomejs/biome": "^2.5.0",
|
|
88
92
|
"@commitlint/cli": "^21.0.2",
|
|
89
93
|
"@commitlint/config-conventional": "^21.0.2",
|
|
94
|
+
"@cucumber/gherkin": "^42.0.1",
|
|
90
95
|
"c8": "^11.0.0",
|
|
91
96
|
"chokidar": "^5.0.0",
|
|
92
97
|
"husky": "^9.1.7",
|
|
@@ -104,18 +109,22 @@
|
|
|
104
109
|
"js-yaml": "^4.2.0",
|
|
105
110
|
"minimatch": "^10.0.0",
|
|
106
111
|
"picomatch": "^4.0.4",
|
|
107
|
-
"string-argv": "^0.3.2",
|
|
108
112
|
"typhonjs-escomplex": "^0.1.0"
|
|
109
113
|
},
|
|
110
114
|
"peerDependencies": {
|
|
115
|
+
"@cucumber/gherkin": ">=32.0.0",
|
|
111
116
|
"typescript": ">=5.0.0"
|
|
112
117
|
},
|
|
113
118
|
"peerDependenciesMeta": {
|
|
119
|
+
"@cucumber/gherkin": {
|
|
120
|
+
"optional": true
|
|
121
|
+
},
|
|
114
122
|
"typescript": {
|
|
115
123
|
"optional": true
|
|
116
124
|
}
|
|
117
125
|
},
|
|
118
126
|
"//": {
|
|
127
|
+
"peerDependencies.@cucumber/gherkin": "OPTIONAL peer, mirroring the `typescript` precedent, and deliberately NOT a runtime dependency. `check-gherkin-corpus.js` is the only consumer and it is opt-in behind `qa.gherkinLint`, so a consumer with no BDD tier must gain nothing from an upgrade. The devDependency alongside it is what lets this repository's own suite drive the real parser. The gate resolves it through a require path anchored at the consumer project — `.agents/` reaches a consumer by plain file copy, so a bare specifier would resolve against the consumer's module chain, which under a non-hoisting linker need not hold it.",
|
|
119
128
|
"overrides.js-yaml": "COUPLED to devDependencies.markdownlint-cli2 — do not bump either alone, and do NOT drop this override. It is load-bearing: markdownlint-cli2 0.22.x pulls js-yaml 4.1.1, which carries GHSA-52cp-r559-cp3m (high) and GHSA-h67p-54hq-rp68 (moderate); removing the override was measured to reintroduce both (1 high + 1 moderate), while with it in place `npm audit` is clean. An npm override also wins over a transitive package's own pin, so this tree-wide ^4.2.0 is imposed on every js-yaml consumer regardless of what they declare — and markdownlint-cli2 0.23.x declares an exact js-yaml 5.2.1. A dry-run bump confirmed the trap: markdownlint-cli2 0.23.1 resolves against js-yaml 4.3.0, two majors off what it declares, silently. The only safe move is to raise this override and bump markdownlint-cli2 in ONE reviewed commit (first confirming cosmiconfig, under @commitlint/cli, tolerates the same major). renovate.json excludes markdownlint-cli2 from devDependency auto-merge so that pair cannot drift apart unattended.",
|
|
120
129
|
"dependencies.js-yaml": "States the SAME range as overrides.js-yaml above. The two are deliberate duplicates — npm has no way to reference the direct range from the overrides block — so they MUST move in lockstep; changing one without the other silently splits the direct and transitive resolutions."
|
|
121
130
|
},
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
-
"$id": "https://github.com/dsj1984/mandrel/blob/main/.agents/schemas/lifecycle/checkpoint.written.schema.json",
|
|
4
|
-
"title": "checkpoint.written",
|
|
5
|
-
"description": "Self-emitted by CheckpointPointerWriter after the pointer file is updated. Carries the phase header for tracing and the last-completed seqId for the resume contract.",
|
|
6
|
-
"type": "object",
|
|
7
|
-
"required": ["phase", "lastCompletedSeqId"],
|
|
8
|
-
"properties": {
|
|
9
|
-
"phase": { "type": "string", "minLength": 1 },
|
|
10
|
-
"lastCompletedSeqId": { "type": "integer", "minimum": 0 }
|
|
11
|
-
},
|
|
12
|
-
"additionalProperties": false
|
|
13
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
-
"$id": "https://github.com/dsj1984/mandrel/blob/main/.agents/schemas/lifecycle/close-validate.end.schema.json",
|
|
4
|
-
"title": "close-validate.end",
|
|
5
|
-
"description": "Emitted at the end of the close-validate sub-phase. ok=true => every gate passed; ok=false => failedGate identifies the first failed gate. durationMs is wall-clock time spent in the gate chain. Story #2250.",
|
|
6
|
-
"type": "object",
|
|
7
|
-
"required": ["epicId", "storyId", "ok"],
|
|
8
|
-
"properties": {
|
|
9
|
-
"epicId": { "type": "integer", "minimum": 1 },
|
|
10
|
-
"storyId": { "type": "integer", "minimum": 1 },
|
|
11
|
-
"ok": { "type": "boolean" },
|
|
12
|
-
"gateCount": { "type": "integer", "minimum": 0 },
|
|
13
|
-
"failedGate": { "type": "string", "minLength": 1 },
|
|
14
|
-
"exitCode": { "type": "integer" },
|
|
15
|
-
"durationMs": { "type": "integer", "minimum": 0 }
|
|
16
|
-
},
|
|
17
|
-
"additionalProperties": false
|
|
18
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
-
"$id": "https://github.com/dsj1984/mandrel/blob/main/.agents/schemas/lifecycle/close-validate.start.schema.json",
|
|
4
|
-
"title": "close-validate.start",
|
|
5
|
-
"description": "Emitted at the start of the close-validate sub-phase (pre-merge gate chain typecheck/lint/test/format/maintainability/crap). Story #2250.",
|
|
6
|
-
"type": "object",
|
|
7
|
-
"required": ["epicId", "storyId"],
|
|
8
|
-
"properties": {
|
|
9
|
-
"epicId": { "type": "integer", "minimum": 1 },
|
|
10
|
-
"storyId": { "type": "integer", "minimum": 1 }
|
|
11
|
-
},
|
|
12
|
-
"additionalProperties": false
|
|
13
|
-
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
-
"$id": "https://github.com/dsj1984/mandrel/blob/main/.agents/schemas/lifecycle/code-review.end.schema.json",
|
|
4
|
-
"title": "code-review.end",
|
|
5
|
-
"description": "Emitted at the end of the code-review sub-phase. Carries a review-finding severity summary so the lifecycle ledger surfaces critical/high/medium/suggestion counts directly. The payload MUST NOT carry any secret-key-denylist fields (token, password, secret, apiKey, webhookUrl) — the LedgerWriter enforces this, but the schema's `additionalProperties: false` keeps the surface tight. Story #2252.",
|
|
6
|
-
"type": "object",
|
|
7
|
-
"required": ["epicId", "status"],
|
|
8
|
-
"properties": {
|
|
9
|
-
"epicId": { "type": "integer", "minimum": 1 },
|
|
10
|
-
"status": {
|
|
11
|
-
"type": "string",
|
|
12
|
-
"enum": ["ok", "no-changes", "invalid"]
|
|
13
|
-
},
|
|
14
|
-
"severity": {
|
|
15
|
-
"type": "object",
|
|
16
|
-
"required": ["critical", "high", "medium", "suggestion"],
|
|
17
|
-
"properties": {
|
|
18
|
-
"critical": { "type": "integer", "minimum": 0 },
|
|
19
|
-
"high": { "type": "integer", "minimum": 0 },
|
|
20
|
-
"medium": { "type": "integer", "minimum": 0 },
|
|
21
|
-
"suggestion": { "type": "integer", "minimum": 0 }
|
|
22
|
-
},
|
|
23
|
-
"additionalProperties": false
|
|
24
|
-
},
|
|
25
|
-
"halted": { "type": "boolean" },
|
|
26
|
-
"posted": { "type": "boolean" },
|
|
27
|
-
"durationMs": { "type": "integer", "minimum": 0 }
|
|
28
|
-
},
|
|
29
|
-
"additionalProperties": false
|
|
30
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
-
"$id": "https://github.com/dsj1984/mandrel/blob/main/.agents/schemas/lifecycle/code-review.start.schema.json",
|
|
4
|
-
"title": "code-review.start",
|
|
5
|
-
"description": "Emitted at the start of the code-review sub-phase (Phase D of the close-tail). Story #2252.",
|
|
6
|
-
"type": "object",
|
|
7
|
-
"required": ["epicId"],
|
|
8
|
-
"properties": {
|
|
9
|
-
"epicId": { "type": "integer", "minimum": 1 }
|
|
10
|
-
},
|
|
11
|
-
"additionalProperties": false
|
|
12
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
-
"$id": "https://github.com/dsj1984/mandrel/blob/main/.agents/schemas/lifecycle/intervention.recorded.schema.json",
|
|
4
|
-
"title": "intervention.recorded",
|
|
5
|
-
"description": "Emitted whenever the host LLM performs an out-of-band manual intervention during an Epic delivery (e.g., AskUserQuestion, manual git restore/reset, --no-ff recovery merge, story-close --skipValidation). The InterventionRecorder listener appends the payload to the epic-run-state-store's manualInterventions array; a non-empty array disqualifies the Epic from auto-merge.",
|
|
6
|
-
"type": "object",
|
|
7
|
-
"required": ["epicId", "reason"],
|
|
8
|
-
"properties": {
|
|
9
|
-
"epicId": { "type": "integer", "minimum": 1 },
|
|
10
|
-
"reason": { "type": "string", "minLength": 1 },
|
|
11
|
-
"source": { "type": "string", "minLength": 1, "default": "host-llm" },
|
|
12
|
-
"ts": { "type": "string", "format": "date-time" }
|
|
13
|
-
},
|
|
14
|
-
"additionalProperties": false
|
|
15
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
-
"$id": "https://github.com/dsj1984/mandrel/blob/main/.agents/schemas/lifecycle/loop.tick.schema.json",
|
|
4
|
-
"title": "loop.tick",
|
|
5
|
-
"description": "Emitted once per pass of a host-driven loop (e.g. a recurring loop command or a long-running poll) so each round lands an inspectable ledger record. Surfaces the loop as forward-progress evidence the /deliver idle watchdog already scans — distinct from story.heartbeat, which carries Story-phase info for a single in-flight Story. A loop is not tied to a Story tier: loop.tick carries a free-form loopName, a monotonic round counter, the configured cadence, and a status so a host loop never runs silently. cadence is the loop's configured interval label (e.g. '5m', 'self-paced'); status is the per-round verdict (running while the loop continues, done when it terminates normally, blocked when it stalls).",
|
|
6
|
-
"type": "object",
|
|
7
|
-
"required": ["event", "loopName", "round", "cadence", "status", "timestamp"],
|
|
8
|
-
"properties": {
|
|
9
|
-
"event": { "type": "string", "const": "loop.tick" },
|
|
10
|
-
"loopName": { "type": "string", "minLength": 1 },
|
|
11
|
-
"round": { "type": "integer", "minimum": 0 },
|
|
12
|
-
"cadence": { "type": "string", "minLength": 1 },
|
|
13
|
-
"status": {
|
|
14
|
-
"type": "string",
|
|
15
|
-
"enum": ["running", "done", "blocked"]
|
|
16
|
-
},
|
|
17
|
-
"timestamp": { "type": "string", "format": "date-time" }
|
|
18
|
-
},
|
|
19
|
-
"additionalProperties": false
|
|
20
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
-
"$id": "https://github.com/dsj1984/mandrel/blob/main/.agents/schemas/lifecycle/notification.emitted.schema.json",
|
|
4
|
-
"title": "notification.emitted",
|
|
5
|
-
"description": "Self-emitted by NotifyDispatcher after each webhook/comment dispatch. Carries the upstream event name, the channel, the severity, and the ok flag for trace fidelity.",
|
|
6
|
-
"type": "object",
|
|
7
|
-
"required": ["event", "channel", "severity", "ok"],
|
|
8
|
-
"properties": {
|
|
9
|
-
"event": { "type": "string", "minLength": 1 },
|
|
10
|
-
"channel": { "type": "string", "enum": ["webhook", "comment"] },
|
|
11
|
-
"severity": {
|
|
12
|
-
"type": "string",
|
|
13
|
-
"enum": ["info", "warn", "error", "critical"]
|
|
14
|
-
},
|
|
15
|
-
"ok": { "type": "boolean" }
|
|
16
|
-
},
|
|
17
|
-
"additionalProperties": false
|
|
18
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
-
"$id": "https://github.com/dsj1984/mandrel/blob/main/.agents/schemas/lifecycle/pr.created.schema.json",
|
|
4
|
-
"title": "pr.created",
|
|
5
|
-
"description": "Emitted by Finalizer immediately after gh pr create (or short-circuit). Must be preceded by acceptance.reconcile.ok from the same run.",
|
|
6
|
-
"type": "object",
|
|
7
|
-
"required": ["prUrl", "head", "base"],
|
|
8
|
-
"properties": {
|
|
9
|
-
"prUrl": { "type": "string", "format": "uri", "minLength": 1 },
|
|
10
|
-
"head": { "type": "string", "minLength": 1 },
|
|
11
|
-
"base": { "type": "string", "minLength": 1 }
|
|
12
|
-
},
|
|
13
|
-
"additionalProperties": false
|
|
14
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
-
"$id": "https://github.com/dsj1984/mandrel/blob/main/.agents/schemas/lifecycle/retro.end.schema.json",
|
|
4
|
-
"title": "retro.end",
|
|
5
|
-
"description": "Emitted at the end of the retro sub-phase. `posted` indicates whether the retro structured comment was upserted onto the Epic; `retroPath` is the local mirror path under temp/run-<id>/ when written. Story #2252.",
|
|
6
|
-
"type": "object",
|
|
7
|
-
"required": ["epicId", "posted"],
|
|
8
|
-
"properties": {
|
|
9
|
-
"epicId": { "type": "integer", "minimum": 1 },
|
|
10
|
-
"posted": { "type": "boolean" },
|
|
11
|
-
"compact": { "type": "boolean" },
|
|
12
|
-
"retroPath": { "type": "string", "minLength": 1 },
|
|
13
|
-
"durationMs": { "type": "integer", "minimum": 0 }
|
|
14
|
-
},
|
|
15
|
-
"additionalProperties": false
|
|
16
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
-
"$id": "https://github.com/dsj1984/mandrel/blob/main/.agents/schemas/lifecycle/retro.start.schema.json",
|
|
4
|
-
"title": "retro.start",
|
|
5
|
-
"description": "Emitted at the start of the retro sub-phase (Phase E of the close-tail). Story #2252.",
|
|
6
|
-
"type": "object",
|
|
7
|
-
"required": ["epicId"],
|
|
8
|
-
"properties": {
|
|
9
|
-
"epicId": { "type": "integer", "minimum": 1 }
|
|
10
|
-
},
|
|
11
|
-
"additionalProperties": false
|
|
12
|
-
}
|