mandrel 1.94.0 → 2.1.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 +116 -99
- package/.agents/agents/acceptance-critic.md +9 -7
- package/.agents/agents/story-worker.md +45 -51
- package/.agents/audit-checklists/performance.md +1 -1
- package/.agents/docs/SDLC.md +498 -1287
- package/.agents/docs/agentrc-reference.json +185 -80
- package/.agents/docs/configuration.md +132 -190
- package/.agents/docs/execution-reference.md +51 -25
- package/.agents/docs/quality-gates.md +25 -33
- package/.agents/docs/workflows.md +8 -8
- package/.agents/instructions.md +113 -139
- package/.agents/rules/ci-remediation.md +11 -15
- package/.agents/rules/git-conventions-reference.md +48 -58
- package/.agents/rules/git-conventions.md +16 -22
- package/.agents/schemas/acceptance-eval-verdict.schema.json +1 -1
- package/.agents/schemas/agentrc.schema.json +83 -254
- package/.agents/schemas/audit-rules.json +59 -1
- package/.agents/schemas/audit-rules.schema.json +33 -1
- package/.agents/schemas/lifecycle/README.md +1 -2
- package/.agents/schemas/lifecycle/ledger-record.schema.json +1 -1
- package/.agents/schemas/lifecycle/merge.flip-failed.schema.json +33 -0
- package/.agents/schemas/lifecycle/merge.unlanded.schema.json +1 -0
- package/.agents/schemas/lifecycle/retro.end.schema.json +1 -1
- package/.agents/schemas/lifecycle/story.merged.schema.json +1 -1
- package/.agents/schemas/signal-event.schema.json +3 -3
- package/.agents/schemas/story-deliver-terminal.schema.json +152 -0
- package/.agents/schemas/validation-evidence.schema.json +1 -1
- package/.agents/scripts/acceptance-eval.js +22 -66
- package/.agents/scripts/agents-bootstrap-github.js +1 -1
- package/.agents/scripts/audit-to-stories.js +7 -7
- package/.agents/scripts/boot-sweep.js +1 -1
- package/.agents/scripts/bootstrap.js +3 -3
- package/.agents/scripts/check-dead-exports.js +43 -104
- package/.agents/scripts/check-doc-links.js +2 -2
- package/.agents/scripts/check-lifecycle-lint.js +7 -10
- package/.agents/scripts/check-workflow-cli-lint.js +91 -0
- package/.agents/scripts/cleanup-repo-test-temp.js +6 -1
- package/.agents/scripts/deliver-recover.js +122 -0
- package/.agents/scripts/drain-pending-cleanup.js +1 -1
- package/.agents/scripts/evidence-gate.js +20 -50
- package/.agents/scripts/generate-skills-index.js +17 -1
- package/.agents/scripts/generate-workflows-doc.js +4 -4
- package/.agents/scripts/lib/ITicketingProvider.js +1 -19
- package/.agents/scripts/lib/Logger.js +6 -10
- package/.agents/scripts/lib/audit-suite/runner.js +2 -2
- package/.agents/scripts/lib/audit-suite/selector.js +328 -28
- package/.agents/scripts/lib/audit-to-stories/{seed-epic-from-findings.js → seed-from-findings.js} +9 -9
- package/.agents/scripts/lib/baselines/kernel.js +206 -18
- package/.agents/scripts/lib/baselines/kinds/maintainability.js +0 -15
- package/.agents/scripts/lib/baselines/reader.js +1 -6
- package/.agents/scripts/lib/bdd-runner-detect.js +5 -9
- package/.agents/scripts/lib/bootstrap/ci-workflow-template.js +28 -33
- package/.agents/scripts/lib/bootstrap/issue-forms-template.js +32 -33
- package/.agents/scripts/lib/bootstrap/manifest.js +8 -11
- package/.agents/scripts/lib/bootstrap/project-bootstrap.js +30 -53
- package/.agents/scripts/lib/bootstrap/quality-bootstrap.js +0 -2
- package/.agents/scripts/lib/checks/core-bare-clean.js +6 -3
- package/.agents/scripts/lib/checks/index.js +3 -2
- package/.agents/scripts/lib/checks/loop-health.js +12 -11
- package/.agents/scripts/lib/checks/state.js +17 -248
- package/.agents/scripts/lib/checks/story-init-not-backgrounded.js +26 -24
- package/.agents/scripts/lib/checks/subagent-agent-tool-required.js +3 -4
- package/.agents/scripts/lib/checks/worktree-bootstrap-env.js +2 -2
- package/.agents/scripts/lib/checks/worktree-residue-biome.js +3 -3
- package/.agents/scripts/lib/cli/standard-args.js +13 -22
- package/.agents/scripts/lib/cli-args.js +39 -9
- package/.agents/scripts/lib/close-validation/gates.js +15 -15
- package/.agents/scripts/lib/close-validation/projections/inputs.js +7 -7
- package/.agents/scripts/lib/close-validation/projections/maintainability.js +12 -12
- package/.agents/scripts/lib/close-validation/runner.js +13 -21
- package/.agents/scripts/lib/close-validation/telemetry.js +17 -8
- package/.agents/scripts/lib/config/ci.js +6 -31
- package/.agents/scripts/lib/config/delivery-routing.js +52 -35
- package/.agents/scripts/lib/config/explain.js +61 -48
- package/.agents/scripts/lib/config/github.js +7 -5
- package/.agents/scripts/lib/config/limits.js +29 -80
- package/.agents/scripts/lib/config/paths.js +0 -2
- package/.agents/scripts/lib/config/quality.js +12 -15
- package/.agents/scripts/lib/config/runners.js +20 -66
- package/.agents/scripts/lib/config/temp-paths.js +30 -63
- package/.agents/scripts/lib/config/worktree-isolation.js +0 -5
- package/.agents/scripts/lib/config-resolver.js +2 -7
- package/.agents/scripts/lib/config-settings-schema-delivery.js +55 -161
- package/.agents/scripts/lib/config-settings-schema-quality.js +17 -16
- package/.agents/scripts/lib/config-settings-schema.js +100 -60
- package/.agents/scripts/lib/dead-exports-knip.js +105 -0
- package/.agents/scripts/lib/dead-exports-mode.js +51 -0
- package/.agents/scripts/lib/dependency-parser.js +3 -2
- package/.agents/scripts/lib/doc-tiers.js +2 -2
- package/.agents/scripts/lib/duplicate-search.js +242 -41
- package/.agents/scripts/lib/feedback-loop/retro-proposals-graduator.js +1 -1
- package/.agents/scripts/lib/findings/promote-finding.js +23 -14
- package/.agents/scripts/lib/format-generated-json.js +97 -0
- package/.agents/scripts/lib/framework-version.js +19 -190
- package/.agents/scripts/lib/gh-exec.js +8 -0
- package/.agents/scripts/lib/git-branch-cleanup.js +1 -10
- package/.agents/scripts/lib/git-branch-lifecycle.js +17 -180
- package/.agents/scripts/lib/git-utils.js +32 -20
- package/.agents/scripts/lib/github/framework-repo.js +6 -0
- package/.agents/scripts/lib/json-utils.js +1 -2
- package/.agents/scripts/lib/label-constants.js +10 -38
- package/.agents/scripts/lib/label-taxonomy.js +10 -55
- package/.agents/scripts/lib/observability/active-story-env.js +44 -165
- package/.agents/scripts/lib/observability/runtime-friction.js +243 -0
- package/.agents/scripts/lib/observability/signal-validator.js +4 -4
- package/.agents/scripts/lib/observability/signals-writer.js +6 -82
- package/.agents/scripts/lib/observability/source-classifier.js +5 -5
- package/.agents/scripts/lib/observability/tool-trace-hook.js +2 -12
- package/.agents/scripts/lib/onboard/init-tail.js +1 -3
- package/.agents/scripts/lib/orchestration/acceptance-clusters.js +1 -1
- package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +2 -2
- package/.agents/scripts/lib/orchestration/ceremony-routing.js +105 -44
- package/.agents/scripts/lib/orchestration/code-review.js +78 -436
- package/.agents/scripts/lib/orchestration/column-sync.js +1 -1
- package/.agents/scripts/lib/orchestration/consolidation-precondition.js +4 -4
- package/.agents/scripts/lib/orchestration/context-envelope.js +2 -5
- package/.agents/scripts/lib/orchestration/deliver-recover.js +328 -0
- package/.agents/scripts/lib/orchestration/detectors-phase.js +12 -6
- package/.agents/scripts/lib/orchestration/docs-digest.js +8 -8
- package/.agents/scripts/lib/orchestration/file-assumptions.js +7 -13
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/cli.js +1 -1
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/fast-forward.js +34 -0
- package/.agents/scripts/lib/orchestration/lease-guard-shared.js +3 -2
- package/.agents/scripts/lib/orchestration/lifecycle/emit-ledger-event.js +142 -0
- package/.agents/scripts/lib/orchestration/lifecycle/emit-loop-tick.js +17 -19
- package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-flip-failed.js +86 -0
- package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-unlanded.js +37 -103
- package/.agents/scripts/lib/orchestration/lifecycle/ledger-writer.js +6 -3
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/README.md +21 -43
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/watcher.js +50 -85
- package/.agents/scripts/lib/orchestration/lifecycle/trace-logger.js +3 -14
- package/.agents/scripts/lib/orchestration/lint-baseline-service.js +4 -4
- package/.agents/scripts/lib/orchestration/merge-block-class.js +77 -21
- package/.agents/scripts/lib/orchestration/merge-poll.js +104 -0
- package/.agents/scripts/lib/orchestration/phase-runner.js +3 -2
- package/.agents/scripts/lib/orchestration/plan-context.js +354 -282
- package/.agents/scripts/lib/orchestration/plan-critic-conditions.js +11 -22
- package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +4 -8
- package/.agents/scripts/lib/orchestration/plan-metrics.js +38 -6
- package/.agents/scripts/lib/orchestration/plan-navigation.js +92 -0
- package/.agents/scripts/lib/orchestration/plan-persist/fan-out-gate.js +71 -0
- package/.agents/scripts/lib/orchestration/plan-persist/persist-helpers.js +245 -0
- package/.agents/scripts/lib/orchestration/plan-persist/plan-context-source.js +116 -0
- package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +432 -858
- package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +778 -0
- package/.agents/scripts/lib/orchestration/plan-persist/summary.js +47 -115
- package/.agents/scripts/lib/orchestration/plan-persist/supersede-ops.js +509 -0
- package/.agents/scripts/lib/orchestration/plan-reachability.js +9 -14
- package/.agents/scripts/lib/orchestration/plan-runner/worktree-sweep.js +1 -1
- package/.agents/scripts/lib/orchestration/{epic-plan-spec/phases → planning}/authoring-context.js +52 -51
- package/.agents/scripts/lib/orchestration/planning/decomposer-context.js +27 -0
- package/.agents/scripts/lib/orchestration/{epic-plan-spec/phases → planning}/spec-authoring-grounding.js +1 -1
- package/.agents/scripts/lib/orchestration/pr-base-guard.js +18 -28
- package/.agents/scripts/lib/orchestration/remote-verifier.js +1 -1
- package/.agents/scripts/lib/orchestration/resolve-stories.js +344 -0
- package/.agents/scripts/lib/orchestration/resolves-token.js +1 -1
- package/.agents/scripts/lib/orchestration/retro-proposals.js +140 -79
- package/.agents/scripts/lib/orchestration/review-depth.js +126 -47
- package/.agents/scripts/lib/orchestration/review-providers/codex.js +2 -2
- package/.agents/scripts/lib/orchestration/review-providers/findings-renderer.js +3 -13
- package/.agents/scripts/lib/orchestration/review-providers/native.js +1 -154
- package/.agents/scripts/lib/orchestration/review-providers/review-depth.js +3 -2
- package/.agents/scripts/lib/orchestration/review-providers/review-provider-factory.js +21 -56
- package/.agents/scripts/lib/orchestration/review-providers/security-review.js +1 -1
- package/.agents/scripts/lib/orchestration/review-providers/types.js +5 -4
- package/.agents/scripts/lib/orchestration/review-providers/ultrareview.js +1 -1
- package/.agents/scripts/lib/orchestration/run-epilogue.js +784 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +25 -1
- package/.agents/scripts/lib/orchestration/single-story-close/phases/base-sync.js +11 -9
- package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +4 -4
- package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +86 -41
- package/.agents/scripts/lib/orchestration/single-story-close/phases/confirm-merge.js +608 -152
- package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +77 -32
- package/.agents/scripts/lib/orchestration/single-story-close/phases/post-land.js +305 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/pull-request.js +1 -1
- package/.agents/scripts/lib/orchestration/single-story-close/phases/review-block.js +44 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/worktree-reap.js +37 -4
- package/.agents/scripts/lib/orchestration/single-story-close/phases/wrong-tree-guard.js +2 -2
- package/.agents/scripts/lib/orchestration/single-story-close/runner.js +275 -46
- package/.agents/scripts/lib/orchestration/single-story-lease-guard.js +1 -1
- package/.agents/scripts/lib/orchestration/spec-freshness.js +14 -205
- package/.agents/scripts/lib/orchestration/spec-section-validator.js +4 -5
- package/.agents/scripts/lib/orchestration/spec-spill.js +60 -0
- package/.agents/scripts/lib/orchestration/split-policy-validator.js +188 -0
- package/.agents/scripts/lib/orchestration/story-close/emit-blocked.js +49 -0
- package/.agents/scripts/lib/orchestration/story-close/format-autofix.js +10 -10
- package/.agents/scripts/lib/orchestration/story-close/phases/code-review.js +28 -42
- package/.agents/scripts/lib/orchestration/story-deliver-terminal.js +360 -0
- package/.agents/scripts/lib/orchestration/story-follow-ups.js +298 -0
- package/.agents/scripts/lib/orchestration/story-init-remote.js +51 -0
- package/.agents/scripts/lib/orchestration/story-plan-state.js +33 -0
- package/.agents/scripts/lib/orchestration/structured-comment-parser.js +1 -1
- package/.agents/scripts/lib/orchestration/task-body-validator.js +60 -25
- package/.agents/scripts/lib/orchestration/ticket-lease.js +27 -74
- package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +130 -75
- package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +192 -377
- package/.agents/scripts/lib/orchestration/ticket-validator.js +123 -25
- package/.agents/scripts/lib/orchestration/ticketing/bulk.js +14 -72
- package/.agents/scripts/lib/orchestration/ticketing/reads.js +45 -55
- package/.agents/scripts/lib/orchestration/ticketing/transition.js +66 -6
- package/.agents/scripts/lib/orchestration/ticketing.js +0 -1
- package/.agents/scripts/lib/plan-phase-cleanup.js +12 -14
- package/.agents/scripts/lib/planning-corpus.js +12 -281
- package/.agents/scripts/lib/preflight-runner.js +4 -4
- package/.agents/scripts/lib/qa/coverage-verdict.js +5 -5
- package/.agents/scripts/lib/qa/qa-context-hydrator.js +5 -5
- package/.agents/scripts/lib/signals/index.js +4 -17
- package/.agents/scripts/lib/signals/read.js +35 -35
- package/.agents/scripts/lib/signals/schema.js +8 -11
- package/.agents/scripts/lib/signals/span-tree.js +7 -7
- package/.agents/scripts/lib/signals/write.js +0 -1
- package/.agents/scripts/lib/single-story/story-merged-notify.js +13 -2
- package/.agents/scripts/lib/single-story-sweep/protection-ctx.js +1 -1
- package/.agents/scripts/lib/skills/parse-skill.js +16 -3
- package/.agents/scripts/lib/story-adjacency.js +17 -19
- package/.agents/scripts/lib/story-body/story-body.js +130 -75
- package/.agents/scripts/lib/story-plan.js +2 -4
- package/.agents/scripts/lib/templates/decomposer-prompts.js +51 -46
- package/.agents/scripts/lib/templates/spec-author-prompts.js +47 -45
- package/.agents/scripts/lib/test-env.js +14 -1
- package/.agents/scripts/lib/test-tiers.js +0 -3
- package/.agents/scripts/lib/{epic-body-sections.js → ticket-body-sections.js} +25 -39
- package/.agents/scripts/lib/validation-evidence.js +32 -60
- package/.agents/scripts/lib/wave-runner/ready-set.js +38 -12
- package/.agents/scripts/lib/workspace-provisioner.js +1 -1
- package/.agents/scripts/lib/worktree/lifecycle/pending-cleanup.js +1 -1
- package/.agents/scripts/lib/worktree/lifecycle/reap.js +72 -25
- package/.agents/scripts/lib/worktree/lifecycle-manager.js +1 -2
- package/.agents/scripts/lint-issue-body.js +71 -40
- package/.agents/scripts/mandrel-update-preflight.js +1 -1
- package/.agents/scripts/notify.js +4 -3
- package/.agents/scripts/plan-context.js +102 -80
- package/.agents/scripts/plan-persist.js +230 -279
- package/.agents/scripts/plan-run-epilogue.js +142 -0
- package/.agents/scripts/post-structured-comment.js +0 -38
- package/.agents/scripts/pr-watch-with-update.js +43 -22
- package/.agents/scripts/providers/github/compose.js +0 -1
- package/.agents/scripts/providers/github/errors.js +0 -19
- package/.agents/scripts/providers/github/issues.js +13 -39
- package/.agents/scripts/providers/github/mappers.js +5 -12
- package/.agents/scripts/providers/github/sub-issues.js +0 -47
- package/.agents/scripts/providers/github/tickets.js +33 -156
- package/.agents/scripts/providers/github.js +17 -6
- package/.agents/scripts/resolve-stories.js +236 -0
- package/.agents/scripts/run-coverage.js +4 -1
- package/.agents/scripts/run-lint.js +2 -2
- package/.agents/scripts/run-verify.js +31 -2
- package/.agents/scripts/signals-view.js +25 -21
- package/.agents/scripts/single-story-close.js +178 -26
- package/.agents/scripts/single-story-confirm-merge.js +313 -24
- package/.agents/scripts/single-story-init.js +35 -30
- package/.agents/scripts/stories-wave-tick.js +85 -10
- package/.agents/scripts/story-plan.js +28 -49
- package/.agents/scripts/update-ticket-state.js +14 -65
- package/.agents/skills/core/code-review-and-quality/SKILL.md +28 -450
- package/.agents/skills/core/code-review-and-quality/reference.md +458 -0
- package/.agents/skills/core/debugging-and-error-recovery/SKILL.md +22 -315
- package/.agents/skills/core/debugging-and-error-recovery/reference.md +323 -0
- package/.agents/skills/core/diagnose-friction/SKILL.md +14 -18
- package/.agents/skills/core/documentation-and-adrs/SKILL.md +25 -397
- package/.agents/skills/core/documentation-and-adrs/reference.md +403 -0
- package/.agents/skills/core/gates-and-baselines/SKILL.md +12 -12
- package/.agents/skills/core/idea-refinement/SKILL.md +9 -9
- package/.agents/skills/core/scope-triage/SKILL.md +31 -172
- package/.agents/skills/core/security-and-hardening/SKILL.md +22 -367
- package/.agents/skills/core/security-and-hardening/reference.md +375 -0
- package/.agents/skills/skills.index.json +3 -53
- package/.agents/skills/stack/qa/playwright-bdd/SKILL.md +2 -4
- package/.agents/skills/stack/qa/qa-explore-driving/SKILL.md +1 -1
- package/.agents/skills/stack/qa/qa-harness/SKILL.md +1 -3
- package/.agents/starter-agentrc.json +0 -5
- package/.agents/templates/agent-protocol.md +9 -10
- package/.agents/workflows/audit-architecture.md +6 -7
- package/.agents/workflows/audit-clean-code.md +7 -7
- package/.agents/workflows/audit-dependencies.md +3 -3
- package/.agents/workflows/audit-devops.md +3 -3
- package/.agents/workflows/audit-documentation.md +9 -10
- package/.agents/workflows/audit-lighthouse.md +11 -3
- package/.agents/workflows/audit-navigability.md +13 -2
- package/.agents/workflows/audit-performance.md +5 -6
- package/.agents/workflows/audit-privacy.md +3 -3
- package/.agents/workflows/audit-quality.md +11 -12
- package/.agents/workflows/audit-security.md +4 -5
- package/.agents/workflows/audit-seo.md +13 -3
- package/.agents/workflows/audit-sre.md +3 -3
- package/.agents/workflows/audit-to-stories.md +20 -20
- package/.agents/workflows/audit-ux-ui.md +10 -3
- package/.agents/workflows/deliver.md +177 -176
- package/.agents/workflows/git-cleanup.md +5 -6
- package/.agents/workflows/git-deliver.md +1 -1
- package/.agents/workflows/helpers/_merge-conflict-template.md +1 -1
- package/.agents/workflows/helpers/acceptance-self-eval.md +35 -40
- package/.agents/workflows/helpers/code-quality-guardrails.md +7 -7
- package/.agents/workflows/helpers/code-review.md +75 -196
- package/.agents/workflows/helpers/{single-story-deliver-reference.md → deliver-story-reference.md} +83 -44
- package/.agents/workflows/helpers/deliver-story.md +606 -0
- package/.agents/workflows/helpers/diagnose.md +10 -10
- package/.agents/workflows/helpers/parallel-tooling.md +3 -3
- package/.agents/workflows/helpers/signals.md +16 -16
- package/.agents/workflows/helpers/worktree-lifecycle.md +66 -86
- package/.agents/workflows/mandrel-update.md +2 -1
- package/.agents/workflows/plan.md +277 -145
- package/.agents/workflows/qa-assist.md +27 -33
- package/.agents/workflows/qa-explore.md +29 -38
- package/.agents/workflows/qa-run.md +2 -6
- package/README.md +9 -8
- package/bin/mandrel.js +12 -1
- package/docs/CHANGELOG.md +70 -0
- package/lib/cli/registry.js +262 -19
- package/lib/cli/sync-agents.js +157 -0
- package/lib/cli/sync-commands.js +115 -6
- package/lib/cli/sync.js +168 -6
- package/lib/cli/update.js +105 -8
- package/lib/cli/version-helpers.js +131 -0
- package/lib/migrations/README.md +7 -5
- package/lib/migrations/index.js +12 -8
- package/lib/migrations/steps/2.1.0-retire-mi-drop-knobs.js +100 -0
- package/lib/migrations/steps/2.1.0-retire-verify-concurrency-cap.js +101 -0
- package/package.json +2 -2
- package/.agents/agents/retro.md +0 -42
- package/.agents/personas/architect.md +0 -113
- package/.agents/personas/devops-engineer.md +0 -38
- package/.agents/personas/engineer.md +0 -33
- package/.agents/personas/project-manager.md +0 -114
- package/.agents/personas/qa-engineer.md +0 -95
- package/.agents/personas/security-engineer.md +0 -111
- package/.agents/personas/technical-writer.md +0 -101
- package/.agents/schemas/dispatch-manifest.json +0 -232
- package/.agents/schemas/epic-perf-report.schema.json +0 -89
- package/.agents/schemas/epic-spec.schema.json +0 -153
- package/.agents/schemas/lifecycle/acceptance.reconcile.failed.schema.json +0 -13
- package/.agents/schemas/lifecycle/acceptance.reconcile.ok.schema.json +0 -13
- package/.agents/schemas/lifecycle/acceptance.reconcile.skipped.schema.json +0 -13
- package/.agents/schemas/lifecycle/acceptance.reconcile.start.schema.json +0 -12
- package/.agents/schemas/lifecycle/acceptance.reconcile.waived.schema.json +0 -13
- package/.agents/schemas/lifecycle/epic.automerge.end.schema.json +0 -15
- package/.agents/schemas/lifecycle/epic.automerge.start.schema.json +0 -13
- package/.agents/schemas/lifecycle/epic.blocked.schema.json +0 -13
- package/.agents/schemas/lifecycle/epic.cleanup.end.schema.json +0 -12
- package/.agents/schemas/lifecycle/epic.cleanup.start.schema.json +0 -12
- package/.agents/schemas/lifecycle/epic.close.end.schema.json +0 -12
- package/.agents/schemas/lifecycle/epic.complete.schema.json +0 -13
- package/.agents/schemas/lifecycle/epic.finalize.end.schema.json +0 -13
- package/.agents/schemas/lifecycle/epic.finalize.start.schema.json +0 -12
- package/.agents/schemas/lifecycle/epic.merge.armed.schema.json +0 -13
- package/.agents/schemas/lifecycle/epic.merge.blocked.schema.json +0 -14
- package/.agents/schemas/lifecycle/epic.merge.confirmed.schema.json +0 -17
- package/.agents/schemas/lifecycle/epic.merge.ready.schema.json +0 -15
- package/.agents/schemas/lifecycle/epic.plan.end.schema.json +0 -18
- package/.agents/schemas/lifecycle/epic.plan.start.schema.json +0 -12
- package/.agents/schemas/lifecycle/epic.snapshot.end.schema.json +0 -16
- package/.agents/schemas/lifecycle/epic.snapshot.start.schema.json +0 -12
- package/.agents/schemas/lifecycle/epic.watch.end.schema.json +0 -29
- package/.agents/schemas/lifecycle/epic.watch.start.schema.json +0 -16
- package/.agents/schemas/lifecycle/slice.end.schema.json +0 -21
- package/.agents/schemas/lifecycle/slice.heartbeat.schema.json +0 -20
- package/.agents/schemas/lifecycle/slice.start.schema.json +0 -17
- package/.agents/schemas/lifecycle/story.heartbeat.schema.json +0 -20
- package/.agents/schemas/risk-verdict.schema.json +0 -66
- package/.agents/schemas/story-perf-summary.schema.json +0 -73
- package/.agents/scripts/acceptance-spec-reconciler.js +0 -642
- package/.agents/scripts/analyze-execution.js +0 -444
- package/.agents/scripts/bookkeeping-reconcile.js +0 -117
- package/.agents/scripts/check-prepush-recovery.js +0 -90
- package/.agents/scripts/dispatcher.js +0 -295
- package/.agents/scripts/epic-audit-prepare.js +0 -497
- package/.agents/scripts/epic-audit-recheck.js +0 -274
- package/.agents/scripts/epic-deliver-note-intervention.js +0 -192
- package/.agents/scripts/epic-deliver-preflight.js +0 -462
- package/.agents/scripts/epic-deliver-prepare.js +0 -852
- package/.agents/scripts/epic-execute-record-wave.js +0 -449
- package/.agents/scripts/epic-plan-clarity.js +0 -211
- package/.agents/scripts/epic-plan-healthcheck.js +0 -581
- package/.agents/scripts/epic-reconcile.js +0 -625
- package/.agents/scripts/lib/baseline-snapshot.js +0 -979
- package/.agents/scripts/lib/checks/epic-merge-lock-stale.js +0 -54
- package/.agents/scripts/lib/checks/stale-origin-epic.js +0 -49
- package/.agents/scripts/lib/config/lifecycle.js +0 -40
- package/.agents/scripts/lib/config/preflight.js +0 -58
- package/.agents/scripts/lib/config/retro.js +0 -77
- package/.agents/scripts/lib/epic-merge-lock.js +0 -322
- package/.agents/scripts/lib/epic-plan-clarity.js +0 -181
- package/.agents/scripts/lib/epic-plan-ideation.js +0 -261
- package/.agents/scripts/lib/git-merge-orchestrator.js +0 -261
- package/.agents/scripts/lib/observability/baseline-refresh-rate.js +0 -221
- package/.agents/scripts/lib/observability/hook-heartbeat.js +0 -219
- package/.agents/scripts/lib/observability/perf-aggregator.js +0 -813
- package/.agents/scripts/lib/observability/perf-report-readers.js +0 -328
- package/.agents/scripts/lib/observability/perf-report-render.js +0 -182
- package/.agents/scripts/lib/orchestration/bookkeeping-outbox.js +0 -270
- package/.agents/scripts/lib/orchestration/context-hydration-engine.js +0 -539
- package/.agents/scripts/lib/orchestration/deliver-route.js +0 -173
- package/.agents/scripts/lib/orchestration/dispatch-engine.js +0 -134
- package/.agents/scripts/lib/orchestration/dispatch-pipeline.js +0 -183
- package/.agents/scripts/lib/orchestration/epic-cleanup.js +0 -801
- package/.agents/scripts/lib/orchestration/epic-deliver-lease-guard.js +0 -310
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/context.js +0 -163
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/creation.js +0 -140
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/dag.js +0 -64
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/diagnostics.js +0 -72
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/persist-helpers.js +0 -156
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/persist.js +0 -345
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/planning-artifacts.js +0 -41
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/reconcile-spawn.js +0 -86
- package/.agents/scripts/lib/orchestration/epic-plan-lease-guard.js +0 -391
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/drain.js +0 -94
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/plan-epic.js +0 -236
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/risk-verdict.js +0 -105
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/run-spec-phase.js +0 -307
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/spec-freshness.js +0 -117
- package/.agents/scripts/lib/orchestration/epic-plan-state-store.js +0 -117
- package/.agents/scripts/lib/orchestration/epic-run-state-store.js +0 -621
- package/.agents/scripts/lib/orchestration/epic-runner/concurrency-gate.js +0 -186
- package/.agents/scripts/lib/orchestration/epic-runner/deliver-phases.js +0 -50
- package/.agents/scripts/lib/orchestration/epic-runner/phases/build-wave-dag.js +0 -129
- package/.agents/scripts/lib/orchestration/epic-runner/phases/snapshot.js +0 -103
- package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/composition.js +0 -267
- package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/signals.js +0 -210
- package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/transport.js +0 -238
- package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/_bullet-format.js +0 -32
- package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/component-drift.js +0 -203
- package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/crap-drift.js +0 -227
- package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/maintainability-drift.js +0 -117
- package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/stalled-worktree.js +0 -37
- package/.agents/scripts/lib/orchestration/epic-runner/story-launcher.js +0 -127
- package/.agents/scripts/lib/orchestration/epic-runner/story-run-progress-writer.js +0 -400
- package/.agents/scripts/lib/orchestration/epic-runner/sub-agent-return.js +0 -276
- package/.agents/scripts/lib/orchestration/epic-runner/wave-scheduler.js +0 -66
- package/.agents/scripts/lib/orchestration/epic-spec-reconciler-apply.js +0 -789
- package/.agents/scripts/lib/orchestration/epic-spec-reconciler-diff.js +0 -676
- package/.agents/scripts/lib/orchestration/epic-spec-reconciler-discriminator.js +0 -389
- package/.agents/scripts/lib/orchestration/epic-spec-reconciler-format.js +0 -230
- package/.agents/scripts/lib/orchestration/epic-spec-reconciler-ops.js +0 -361
- package/.agents/scripts/lib/orchestration/error-journal.js +0 -139
- package/.agents/scripts/lib/orchestration/finalize/open-or-locate-pr.js +0 -306
- package/.agents/scripts/lib/orchestration/finalize/post-handoff-comment.js +0 -489
- package/.agents/scripts/lib/orchestration/finalize/sanitize-skip-ci.js +0 -88
- package/.agents/scripts/lib/orchestration/lifecycle/emit-slice-lifecycle.js +0 -270
- package/.agents/scripts/lib/orchestration/lifecycle/emit-story-dispatch-end.js +0 -147
- package/.agents/scripts/lib/orchestration/lifecycle/emit-story-heartbeat.js +0 -155
- package/.agents/scripts/lib/orchestration/lifecycle/ledger-diff.js +0 -140
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/acceptance-reconciler.js +0 -465
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-armer.js +0 -501
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-predicate.js +0 -984
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/branch-cleaner.js +0 -264
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/checkpoint-pointer-writer.js +0 -284
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/cleaner.js +0 -355
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/finalizer.js +0 -673
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/index.js +0 -378
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/intervention-recorder.js +0 -140
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/label-transitioner.js +0 -144
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/merge-watcher.js +0 -665
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/notify-dispatcher.js +0 -174
- package/.agents/scripts/lib/orchestration/manifest-builder.js +0 -222
- package/.agents/scripts/lib/orchestration/plan-persist/amend.js +0 -359
- package/.agents/scripts/lib/orchestration/plan-persist/delivery-mode.js +0 -127
- package/.agents/scripts/lib/orchestration/plan-review-routing.js +0 -63
- package/.agents/scripts/lib/orchestration/planning-context-budget.js +0 -213
- package/.agents/scripts/lib/orchestration/planning-risk.js +0 -194
- package/.agents/scripts/lib/orchestration/post-merge/phases/branch-cleanup.js +0 -56
- package/.agents/scripts/lib/orchestration/post-merge/phases/dashboard-refresh.js +0 -33
- package/.agents/scripts/lib/orchestration/post-merge/phases/notification.js +0 -78
- package/.agents/scripts/lib/orchestration/post-merge/phases/temp-cleanup.js +0 -68
- package/.agents/scripts/lib/orchestration/post-merge/phases/ticket-closure.js +0 -118
- package/.agents/scripts/lib/orchestration/post-merge/phases/worktree-reap.js +0 -396
- package/.agents/scripts/lib/orchestration/post-merge-pipeline.js +0 -205
- package/.agents/scripts/lib/orchestration/preflight-cache.js +0 -187
- package/.agents/scripts/lib/orchestration/recurring-failure-detector.js +0 -152
- package/.agents/scripts/lib/orchestration/retro/phases/checks.js +0 -94
- package/.agents/scripts/lib/orchestration/retro/phases/compose-body.js +0 -571
- package/.agents/scripts/lib/orchestration/retro/phases/gather-signals.js +0 -450
- package/.agents/scripts/lib/orchestration/retro/phases/post-and-mirror.js +0 -191
- package/.agents/scripts/lib/orchestration/retro-heuristics.js +0 -57
- package/.agents/scripts/lib/orchestration/retro-perf-heuristics.js +0 -275
- package/.agents/scripts/lib/orchestration/retro-runner.js +0 -197
- package/.agents/scripts/lib/orchestration/spec-renderer.js +0 -447
- package/.agents/scripts/lib/orchestration/story-close/auto-refresh-runner.js +0 -747
- package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/gate-failure.js +0 -211
- package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/pre-merge-attribution.js +0 -158
- package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/refresh-commit.js +0 -446
- package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/regression-projection.js +0 -297
- package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/scope-discovery.js +0 -48
- package/.agents/scripts/lib/orchestration/story-close/baseline-attribution-wiring.js +0 -67
- package/.agents/scripts/lib/orchestration/story-close/baseline-attribution.js +0 -161
- package/.agents/scripts/lib/orchestration/story-close/baseline-friction-body.js +0 -117
- package/.agents/scripts/lib/orchestration/story-close/cd-out-guard.js +0 -86
- package/.agents/scripts/lib/orchestration/story-close/cleanup-reconciler.js +0 -147
- package/.agents/scripts/lib/orchestration/story-close/close-inputs.js +0 -142
- package/.agents/scripts/lib/orchestration/story-close/comment-bodies.js +0 -62
- package/.agents/scripts/lib/orchestration/story-close/merge-runner.js +0 -658
- package/.agents/scripts/lib/orchestration/story-close/merge-subject.js +0 -198
- package/.agents/scripts/lib/orchestration/story-close/phases/branch-restore.js +0 -105
- package/.agents/scripts/lib/orchestration/story-close/phases/close.js +0 -222
- package/.agents/scripts/lib/orchestration/story-close/phases/gates.js +0 -292
- package/.agents/scripts/lib/orchestration/story-close/phases/locked-pipeline.js +0 -270
- package/.agents/scripts/lib/orchestration/story-close/phases/preflight.js +0 -110
- package/.agents/scripts/lib/orchestration/story-close/phases/refresh.js +0 -86
- package/.agents/scripts/lib/orchestration/story-close/phases/timeout-blocked-emitter.js +0 -112
- package/.agents/scripts/lib/orchestration/story-close/phases/timeout-blocked.js +0 -157
- package/.agents/scripts/lib/orchestration/story-close/post-merge-close.js +0 -421
- package/.agents/scripts/lib/orchestration/story-close/pre-merge-validation.js +0 -302
- package/.agents/scripts/lib/orchestration/story-close/shared-checkout-guard.js +0 -163
- package/.agents/scripts/lib/orchestration/story-close-recovery.js +0 -690
- package/.agents/scripts/lib/orchestration/wave-marker.js +0 -28
- package/.agents/scripts/lib/orchestration/wave-record-io.js +0 -218
- package/.agents/scripts/lib/orchestration/wave-record-notifications.js +0 -145
- package/.agents/scripts/lib/orchestration/wave-record-projection.js +0 -212
- package/.agents/scripts/lib/presentation/dispatch-manifest-render.js +0 -111
- package/.agents/scripts/lib/presentation/manifest-builder.js +0 -239
- package/.agents/scripts/lib/presentation/manifest-formatter.js +0 -242
- package/.agents/scripts/lib/presentation/manifest-helpers.js +0 -213
- package/.agents/scripts/lib/presentation/manifest-persistence.js +0 -261
- package/.agents/scripts/lib/presentation/manifest-procedures.js +0 -55
- package/.agents/scripts/lib/presentation/manifest-render-waves.js +0 -306
- package/.agents/scripts/lib/presentation/manifest-renderer.js +0 -188
- package/.agents/scripts/lib/presentation/manifest-story-views.js +0 -110
- package/.agents/scripts/lib/push-epic-retry.js +0 -209
- package/.agents/scripts/lib/spec/index.js +0 -36
- package/.agents/scripts/lib/spec/loader.js +0 -425
- package/.agents/scripts/lib/spec/state.js +0 -208
- package/.agents/scripts/lib/story-init/blocker-validator.js +0 -68
- package/.agents/scripts/lib/story-init/branch-initializer.js +0 -408
- package/.agents/scripts/lib/story-init/context-resolver.js +0 -92
- package/.agents/scripts/lib/story-init/donor-precheck.js +0 -207
- package/.agents/scripts/lib/story-init/state-transitioner.js +0 -80
- package/.agents/scripts/lib/story-init/task-graph-builder.js +0 -124
- package/.agents/scripts/lib/story-init/transition-summary.js +0 -34
- package/.agents/scripts/lib/test-reserved-epic-temp-ids.js +0 -35
- package/.agents/scripts/lib/wave-runner/tick.js +0 -754
- package/.agents/scripts/lib/wave-runner/wave-runner-error.js +0 -20
- package/.agents/scripts/lifecycle-emit-story-dispatch.js +0 -194
- package/.agents/scripts/lifecycle-emit.js +0 -510
- package/.agents/scripts/retro-run.js +0 -218
- package/.agents/scripts/slice-phase.js +0 -361
- package/.agents/scripts/standalone-feedback-rollup.js +0 -188
- package/.agents/scripts/story-close.js +0 -294
- package/.agents/scripts/story-init.js +0 -599
- package/.agents/scripts/story-phase.js +0 -369
- package/.agents/scripts/wave-tick.js +0 -464
- package/.agents/skills/core/analyze-execution/SKILL.md +0 -98
- package/.agents/skills/core/epic-plan-consolidate/SKILL.md +0 -172
- package/.agents/skills/core/epic-plan-consolidate/examples.md +0 -51
- package/.agents/skills/core/epic-plan-decompose-author/SKILL.md +0 -441
- package/.agents/skills/core/epic-plan-decompose-author/examples.md +0 -47
- package/.agents/skills/core/epic-plan-premortem/SKILL.md +0 -146
- package/.agents/skills/core/epic-plan-premortem/examples.md +0 -53
- package/.agents/skills/core/epic-plan-spec-author/SKILL.md +0 -383
- package/.agents/skills/core/epic-plan-spec-author/examples.md +0 -91
- package/.agents/workflows/helpers/deliver-epic-reference.md +0 -547
- package/.agents/workflows/helpers/deliver-epic-single.md +0 -331
- package/.agents/workflows/helpers/deliver-epic.md +0 -998
- package/.agents/workflows/helpers/deliver-stories.md +0 -450
- package/.agents/workflows/helpers/epic-audit.md +0 -189
- package/.agents/workflows/helpers/epic-deliver-story.md +0 -436
- package/.agents/workflows/helpers/epic-testing.md +0 -125
- package/.agents/workflows/helpers/plan-epic-reference.md +0 -160
- package/.agents/workflows/helpers/plan-epic.md +0 -353
- package/.agents/workflows/helpers/plan-story.md +0 -251
- package/.agents/workflows/helpers/scope-triage-gate.md +0 -108
- package/.agents/workflows/helpers/single-story-deliver.md +0 -557
|
@@ -37,16 +37,14 @@ and dedup/route decisions. The agent never invents those decisions in prose.
|
|
|
37
37
|
> a structured agent-driven bug-hunt the operator wants captured into a
|
|
38
38
|
> triageable ledger.
|
|
39
39
|
>
|
|
40
|
-
> **
|
|
41
|
-
> `stack/qa/qa-explore-driving`
|
|
40
|
+
> **Skills**: `core/qa-coverage-mapping`, `stack/qa/qa-explore-driving`
|
|
42
41
|
|
|
43
|
-
##
|
|
42
|
+
## Role framing
|
|
44
43
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
first action so the Plan/Capture/Triage loop is governed by it.
|
|
44
|
+
You are the quality gatekeeper for this run: value coverage, hermetic
|
|
45
|
+
environments, and deterministic results. Do **not** invent signal — capture
|
|
46
|
+
what the surface shows. Apply the QA skills below; there is no separate
|
|
47
|
+
persona pack.
|
|
50
48
|
|
|
51
49
|
## Driving conventions skill
|
|
52
50
|
|
|
@@ -89,10 +87,10 @@ ledger**; do not switch methods mid-surface without a new Plan note.
|
|
|
89
87
|
| --------- | -------- | ---------------------------------- | -------------------------------------------------------------------------------------- |
|
|
90
88
|
| `surface` | yes | `feature:login`, `area:onboarding` | A human label for the single surface to explore. Recorded as each ledger item's `coverage`. |
|
|
91
89
|
|
|
92
|
-
If no `surface` is supplied, **stop and ask** the operator to name one —
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
90
|
+
If no `surface` is supplied, **stop and ask** the operator to name one — do
|
|
91
|
+
not invent scope. `/qa-explore` is **bounded to one surface per session**:
|
|
92
|
+
explore exactly the named surface, do not wander into adjacent surfaces, and
|
|
93
|
+
start a fresh session for a different surface.
|
|
96
94
|
|
|
97
95
|
## Project contract
|
|
98
96
|
|
|
@@ -161,7 +159,7 @@ advances phases autonomously. If the operator does not confirm, stop and hold.
|
|
|
161
159
|
Goal: agree on **what** will be explored and **how the agent will drive it**
|
|
162
160
|
before touching the surface.
|
|
163
161
|
|
|
164
|
-
1. Re-read the
|
|
162
|
+
1. Re-read the
|
|
165
163
|
[`stack/qa/qa-explore-driving`](../skills/stack/qa/qa-explore-driving/SKILL.md)
|
|
166
164
|
skill, and resolve the `qa` contract and session (above).
|
|
167
165
|
2. **Resolve the target environment** via
|
|
@@ -339,33 +337,26 @@ For each untriaged ledger item:
|
|
|
339
337
|
import { promoteFindings } from '../scripts/lib/findings/promote-finding.js';
|
|
340
338
|
const { promotions } = await promoteFindings(ledgerItems, {
|
|
341
339
|
searchIssues, // GitHub provider, open + closed
|
|
342
|
-
createStory, // tight cluster (≤2 surfaces):
|
|
343
|
-
|
|
340
|
+
createStory, // tight cluster (≤2 surfaces): seed → /plan --seed-file
|
|
341
|
+
createPlanSeed, // broad cluster (>2 surfaces): same /plan --seed-file path (may N>1)
|
|
344
342
|
});
|
|
345
343
|
```
|
|
346
344
|
|
|
347
345
|
- **Sizing is delegated, not decided in prose.** `promoteFindings` runs
|
|
348
346
|
`clusterLedgerItems` + `targetForCluster`: a cluster spanning **≤2**
|
|
349
347
|
distinct coverage surfaces routes to `createStory`; **>2** routes to
|
|
350
|
-
`
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
348
|
+
`createPlanSeed`. Neither port opens an Epic ticket — both chain
|
|
349
|
+
`/plan --seed-file`. The workflow introduces no new sizing, clustering,
|
|
350
|
+
or dedup logic — `route-finding.js` / `promote-finding.js` remain the
|
|
351
|
+
single implementation.
|
|
352
|
+
- **`createStory` / `createPlanSeed` (`/plan --seed-file`)** — render a
|
|
353
|
+
**redacted** plan seed from the cluster (reuse the `/audit-to-stories`
|
|
354
|
+
Phase 5a seed shape; redaction already ran in Capture), **stamp the
|
|
356
355
|
cluster's `fingerprintFooter(sha)` verbatim into the seed body**, then
|
|
357
|
-
chain `/plan --
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
dedups the same finding instead of re-filing it.
|
|
362
|
-
- **`createEpic` (`/plan --idea`)** — carry the cluster's
|
|
363
|
-
`fingerprintFooter(sha)` into the `/plan --idea` seed, then chain
|
|
364
|
-
`/plan --idea <seed>`. **Known limitation (not solved here):**
|
|
365
|
-
per-child-Story fingerprint propagation through full Epic decomposition is
|
|
366
|
-
*not* guaranteed — the fingerprint is carried in the Epic seed only; the
|
|
367
|
-
child Stories `/plan` spawns from that seed are not individually
|
|
368
|
-
footer-stamped.
|
|
356
|
+
chain `/plan --seed-file <seed>`. Prefer one Story; split only under
|
|
357
|
+
the default-single policy. The footer must survive into the issue body
|
|
358
|
+
so a later `routeFinding` dedups the same finding instead of re-filing
|
|
359
|
+
it.
|
|
369
360
|
- **A `file` disposition never opens a raw GitHub Issue.** Every `file`
|
|
370
361
|
finding flows through `promoteFindings` → `/plan`; only `defer` and
|
|
371
362
|
`dismiss` skip the `/plan` handoff.
|
|
@@ -379,8 +370,8 @@ For each untriaged ledger item:
|
|
|
379
370
|
After triage, write the updated dispositions back to the ledger (still under
|
|
380
371
|
`temp/qa/`), and summarize: items captured, the driving method used, classes,
|
|
381
372
|
routes (`new`/`update-existing`/`duplicate`/`regression-of-closed`), the
|
|
382
|
-
Stories (`/plan --
|
|
383
|
-
|
|
373
|
+
Stories (`/plan --seed-file`) promoted, and the deferred rolling backlog
|
|
374
|
+
that a resumed session will pick up.
|
|
384
375
|
|
|
385
376
|
---
|
|
386
377
|
|
|
@@ -423,7 +414,7 @@ deferred rolling backlog that a resumed session will pick up.
|
|
|
423
414
|
deterministic — never re-derive them in prose.
|
|
424
415
|
- **Promote through `/plan`, never a raw Issue.** A `file`-dispositioned
|
|
425
416
|
finding is promoted via `promoteFindings`, which chains into
|
|
426
|
-
[`/plan`](plan.md) (`--
|
|
417
|
+
[`/plan`](plan.md) (`--seed-file` for a tight cluster, `--seed` for a broad
|
|
427
418
|
one) — mirroring [`/audit-to-stories`](audit-to-stories.md). `/qa-explore`
|
|
428
419
|
never opens a bare GitHub Issue for a `file` finding. The cluster's
|
|
429
420
|
`fingerprintFooter(sha)` is stamped verbatim into the seed so a future
|
|
@@ -435,8 +426,8 @@ deferred rolling backlog that a resumed session will pick up.
|
|
|
435
426
|
## See also
|
|
436
427
|
|
|
437
428
|
- [`/plan`](plan.md) — the planning pipeline `/qa-explore` Triage chains into
|
|
438
|
-
for a `file`-dispositioned finding (`--
|
|
439
|
-
|
|
429
|
+
for a `file`-dispositioned finding (`--seed-file` / `--seed`). The
|
|
430
|
+
plan→deliver hard stop is preserved across the handoff.
|
|
440
431
|
- [`/qa-assist`](qa-assist.md) — the human-led sibling that enriches a single
|
|
441
432
|
operator observation and triages through the same `/plan` handoff.
|
|
442
433
|
- [`/audit-to-stories`](audit-to-stories.md) — the precedent for the
|
|
@@ -381,17 +381,13 @@ For each untriaged ledger item:
|
|
|
381
381
|
[`promote-finding.js`](../scripts/lib/findings/promote-finding.js) — the
|
|
382
382
|
same cluster/size/route/file path `/qa-explore` and `/audit-to-stories`
|
|
383
383
|
consume (`clusterLedgerItems` + `targetForCluster`: a cluster spanning ≤2
|
|
384
|
-
coverage surfaces routes to `createStory` via `/plan --
|
|
385
|
-
`
|
|
384
|
+
coverage surfaces routes to `createStory` via `/plan --seed-file`, >2 to
|
|
385
|
+
`createPlanSeed` via `/plan --seed`, with the cluster's `fingerprintFooter(sha)`
|
|
386
386
|
stamped verbatim into the seed). A `file` disposition never opens a raw
|
|
387
387
|
GitHub Issue; only `defer` and `dismiss` skip the `/plan` handoff.
|
|
388
388
|
5. **Gate:** any ticket-filing, seed write, `/plan` invocation, or label
|
|
389
389
|
mutation is a write — confirm each with the operator before it happens.
|
|
390
390
|
|
|
391
|
-
If the run was triggered from an Epic-testing context, hand the approved,
|
|
392
|
-
promoted findings to the Epic-testing helper for attachment to the Epic's QA
|
|
393
|
-
evidence ticket.
|
|
394
|
-
|
|
395
391
|
## Step 6 — Report
|
|
396
392
|
|
|
397
393
|
Summarize the sweep in chat with:
|
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
[](https://github.com/dsj1984/mandrel/actions/workflows/ci.yml)
|
|
4
4
|
|
|
5
5
|
An opinionated workflow framework for AI coding assistants built on
|
|
6
|
-
|
|
6
|
+
Story-centric GitHub orchestration. Planning, execution, and state all live
|
|
7
7
|
natively in GitHub Issues, Labels, and Projects V2.
|
|
8
8
|
|
|
9
9
|
## Prerequisites
|
|
@@ -35,7 +35,8 @@ npx mandrel init # install mandrel → sync → prompt → bootstrap →
|
|
|
35
35
|
|
|
36
36
|
```text
|
|
37
37
|
# then, inside Claude Code (commands load from .claude/commands/):
|
|
38
|
-
/plan
|
|
38
|
+
/plan --seed "…" # interrogate → author one Story (default) → persist
|
|
39
|
+
/deliver <id> # story-<id> → PR → main
|
|
39
40
|
```
|
|
40
41
|
|
|
41
42
|
`npx mandrel init` installs `mandrel` (when `./.agents/` is absent),
|
|
@@ -47,9 +48,9 @@ any time to configure). Pass `--assume-yes` for a non-interactive run that
|
|
|
47
48
|
proceeds straight to configure (and forwards the flag to bootstrap). When
|
|
48
49
|
`./.agents/` is already present (you ran `npm install mandrel` first), `init`
|
|
49
50
|
skips the install/sync and goes straight to the prompt. Once `mandrel init`
|
|
50
|
-
completes, you land at the `/plan` handoff — run `/plan --
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
completes, you land at the `/plan` handoff — run `/plan --seed "<idea>"` to
|
|
52
|
+
author your first Story, then deliver it with `/deliver <storyId>`
|
|
53
|
+
(`story-<id>` → PR → `main`).
|
|
53
54
|
|
|
54
55
|
### Manual equivalent
|
|
55
56
|
|
|
@@ -217,9 +218,9 @@ against malicious lifecycle scripts in compromised transitive packages
|
|
|
217
218
|
install scripts for a specific install, run
|
|
218
219
|
`npm install --ignore-scripts=false` for that invocation only.
|
|
219
220
|
|
|
220
|
-
CRAP and Maintainability gates fire at
|
|
221
|
-
|
|
222
|
-
thresholds from `delivery.quality.*` in `.agentrc.json`.
|
|
221
|
+
CRAP and Maintainability gates fire at three sites — close-validation
|
|
222
|
+
(story close), `.husky/pre-push`, and CI (`ci.yml`, push + PR) — against
|
|
223
|
+
the same thresholds from `delivery.quality.*` in `.agentrc.json`.
|
|
223
224
|
|
|
224
225
|
## License
|
|
225
226
|
|
package/bin/mandrel.js
CHANGED
|
@@ -57,7 +57,18 @@ const SUBCOMMANDS = new Map([
|
|
|
57
57
|
'sync-commands',
|
|
58
58
|
{
|
|
59
59
|
description: 'regenerate .claude/commands/ from .agents/workflows/',
|
|
60
|
-
|
|
60
|
+
// No --dry-run: the projection scripts have no preview mode, and
|
|
61
|
+
// accepting the flag while syncing for real overwrote .claude/ on an
|
|
62
|
+
// operator who asked for a preview. Reject it at the dispatcher.
|
|
63
|
+
knownFlags: new Set([]),
|
|
64
|
+
},
|
|
65
|
+
],
|
|
66
|
+
[
|
|
67
|
+
'sync-agents',
|
|
68
|
+
{
|
|
69
|
+
description: 'regenerate .claude/agents/ from .agents/agents/',
|
|
70
|
+
// Same contract as sync-commands: no preview mode, so no --dry-run.
|
|
71
|
+
knownFlags: new Set([]),
|
|
61
72
|
},
|
|
62
73
|
],
|
|
63
74
|
[
|
package/docs/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,76 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [2.1.0](https://github.com/dsj1984/mandrel/compare/mandrel-v2.0.0...mandrel-v2.1.0) (2026-07-17)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### ⚠ BREAKING CHANGES
|
|
9
|
+
|
|
10
|
+
* **plan:** plan-persist.js no longer accepts --risk-verdict and no plan-time step authors a risk verdict; review depth and the acceptance critic mode are derived from the diff at close time.
|
|
11
|
+
* /deliver no longer accepts --run <planRunId> or --dep, and /plan no longer applies a plan-run::<id> label. Deliver Story ids; the graph resolves itself from live state.
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
* /deliver takes only Story ids and resolves dependencies dynamically (retire plan-run) ([#4540](https://github.com/dsj1984/mandrel/issues/4540)) ([#4560](https://github.com/dsj1984/mandrel/issues/4560)) ([e9935cc](https://github.com/dsj1984/mandrel/commit/e9935cc332b43862d79dca9979691077327e1882))
|
|
16
|
+
* **dead-exports:** add a production-mode pass that discounts test-only importers (refs [#4575](https://github.com/dsj1984/mandrel/issues/4575)) ([#4582](https://github.com/dsj1984/mandrel/issues/4582)) ([0a77ca9](https://github.com/dsj1984/mandrel/commit/0a77ca91bdd67a294b66cc076e45c43bc4d691c8))
|
|
17
|
+
* **deliver:** script-owned land tail, resumable pending status, terminal envelope, and deliver-recover ([#4543](https://github.com/dsj1984/mandrel/issues/4543)) ([#4566](https://github.com/dsj1984/mandrel/issues/4566)) ([f234306](https://github.com/dsj1984/mandrel/commit/f234306d1465fe96d19d361f1501ad8edf055cc3))
|
|
18
|
+
* **plan:** close --tickets source issues as superseded by default ([#4535](https://github.com/dsj1984/mandrel/issues/4535)) ([#4553](https://github.com/dsj1984/mandrel/issues/4553)) ([c35e298](https://github.com/dsj1984/mandrel/commit/c35e29880edba4fec0c45687071fbea242236370))
|
|
19
|
+
* **plan:** mirror sibling depends_on into native blocked_by edges (refs [#4544](https://github.com/dsj1984/mandrel/issues/4544)) ([#4570](https://github.com/dsj1984/mandrel/issues/4570)) ([6b94968](https://github.com/dsj1984/mandrel/commit/6b949688e4fd487c979044f2473e3837a4637e1a))
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
|
|
24
|
+
* **bootstrap:** honor command:false in the workflow/command parity check ([#4588](https://github.com/dsj1984/mandrel/issues/4588)) ([493b3eb](https://github.com/dsj1984/mandrel/commit/493b3eb039eefabbd2e33af6a08933d43876c052))
|
|
25
|
+
* **cli:** resolve versions from the consumer, not the running CLI — and make the sync surface fail loudly on skew ([#4530](https://github.com/dsj1984/mandrel/issues/4530)) ([#4536](https://github.com/dsj1984/mandrel/issues/4536)) ([5f20563](https://github.com/dsj1984/mandrel/commit/5f20563eca79203096b49e8fa3dfaa64e2487e12))
|
|
26
|
+
* **cli:** stop sync pruning generated .agents/ files — declare a never-pruned registry so the install ledger survives ([#4534](https://github.com/dsj1984/mandrel/issues/4534)) ([#4552](https://github.com/dsj1984/mandrel/issues/4552)) ([ceccd57](https://github.com/dsj1984/mandrel/commit/ceccd572614a7d8c5226bdd9f1a3b793381be4dd))
|
|
27
|
+
* **column-sync:** stop two more test suites leaking into the shared meta cache ([#4561](https://github.com/dsj1984/mandrel/issues/4561)) ([757e509](https://github.com/dsj1984/mandrel/commit/757e509ff4aa95a091fe9a5de053396a78a26793)), closes [#4555](https://github.com/dsj1984/mandrel/issues/4555)
|
|
28
|
+
* **deliver:** diff the plan-run epilogue against the pre-run base, not origin/main...HEAD (refs [#4550](https://github.com/dsj1984/mandrel/issues/4550)) ([#4558](https://github.com/dsj1984/mandrel/issues/4558)) ([79ddbf6](https://github.com/dsj1984/mandrel/commit/79ddbf61d19bdf256a06aabb860651be6bdce94b))
|
|
29
|
+
* **deliver:** ground the audit roster's lens selection in the landed diff (refs [#4571](https://github.com/dsj1984/mandrel/issues/4571)) ([#4573](https://github.com/dsj1984/mandrel/issues/4573)) ([fa06aca](https://github.com/dsj1984/mandrel/commit/fa06acaedc0c3070516ec32d447f0755a06ea0eb))
|
|
30
|
+
* **deliver:** repair the close-and-land default path (config, operator-merge, follow-ups, reap, reporting) ([#4539](https://github.com/dsj1984/mandrel/issues/4539)) ([#4551](https://github.com/dsj1984/mandrel/issues/4551)) ([9b5c3ee](https://github.com/dsj1984/mandrel/commit/9b5c3ee61b2030e96ff88091761b258eb43fdf43))
|
|
31
|
+
* make `npm run verify` a true CI mirror: include dead-exports + arch-cycles (or catalogue them as CI-only) ([#4549](https://github.com/dsj1984/mandrel/issues/4549)) ([#4557](https://github.com/dsj1984/mandrel/issues/4557)) ([70d088a](https://github.com/dsj1984/mandrel/commit/70d088a646fd1867f3d536c541f89c1c49b0b866))
|
|
32
|
+
* **plan:** make persist resumable and align its gates with the authoring contract ([#4541](https://github.com/dsj1984/mandrel/issues/4541)) ([#4565](https://github.com/dsj1984/mandrel/issues/4565)) ([1cbe974](https://github.com/dsj1984/mandrel/commit/1cbe974154403edab14e006e83f42a5c414150d1))
|
|
33
|
+
* **plan:** make the fan-out deletion gate count importers, not basename word matches ([#4547](https://github.com/dsj1984/mandrel/issues/4547)) ([#4567](https://github.com/dsj1984/mandrel/issues/4567)) ([4c5c724](https://github.com/dsj1984/mandrel/commit/4c5c7248e88136bac83cd91db38658390139c588))
|
|
34
|
+
* **plan:** thread sourceTickets through the envelope so --tickets superseding cannot silently no-op ([#4554](https://github.com/dsj1984/mandrel/issues/4554)) ([#4559](https://github.com/dsj1984/mandrel/issues/4559)) ([4546c40](https://github.com/dsj1984/mandrel/commit/4546c405b2131f6c5afd3ccf40bccb357f4223a0))
|
|
35
|
+
* **quality:** retire the unconsumed miDropMustRefactor/miDropCap knobs and make maintainability.tolerance the single MI-drop control ([#4531](https://github.com/dsj1984/mandrel/issues/4531)) ([#4548](https://github.com/dsj1984/mandrel/issues/4548)) ([fe0c7ce](https://github.com/dsj1984/mandrel/commit/fe0c7ce3ad40e21b957cd6d0a916efbc5e75f634))
|
|
36
|
+
* **skills-index:** emit biome-formatted JSON so regeneration leaves no drift (refs [#4546](https://github.com/dsj1984/mandrel/issues/4546)) ([#4568](https://github.com/dsj1984/mandrel/issues/4568)) ([bdb223e](https://github.com/dsj1984/mandrel/commit/bdb223e2979c0d386ca260b6743cdf2062dbff09))
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
### Changed
|
|
40
|
+
|
|
41
|
+
* **checks:** drop the dead epic merge-lock and epic-branch probes ([#4581](https://github.com/dsj1984/mandrel/issues/4581)) ([28cb4ab](https://github.com/dsj1984/mandrel/commit/28cb4abf4aa9c0c0120598c26dd5b7220b195678))
|
|
42
|
+
* **docs:** move weight out of always-loaded prompts and skill essays into on-demand references ([#4546](https://github.com/dsj1984/mandrel/issues/4546)) ([#4564](https://github.com/dsj1984/mandrel/issues/4564)) ([14381b3](https://github.com/dsj1984/mandrel/commit/14381b3efd7ce774e39dd47f535bb55991387617))
|
|
43
|
+
* **plan:** derive review depth from the diff and retire the authored risk verdict (refs [#4542](https://github.com/dsj1984/mandrel/issues/4542)) ([#4569](https://github.com/dsj1984/mandrel/issues/4569)) ([7a7fb50](https://github.com/dsj1984/mandrel/commit/7a7fb50f7ec0e33d616fa54618fc0b93c2e310a6))
|
|
44
|
+
|
|
45
|
+
## [2.0.0](https://github.com/dsj1984/mandrel/compare/mandrel-v1.94.0...mandrel-v2.0.0) (2026-07-14)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
### ⚠ BREAKING CHANGES
|
|
49
|
+
|
|
50
|
+
* **v2 Story collapse:** one ticket type (`type::story`), one delivery
|
|
51
|
+
path (`/deliver` → `helpers/deliver-story`), one branch model
|
|
52
|
+
(`story-<id>` → PR → `main`). `type::epic`, the epic integration
|
|
53
|
+
branch, wave/dispatch fan-out, and `delivery.routing.singleDelivery`
|
|
54
|
+
are removed. Per-Story file/AC ceilings are replaced by
|
|
55
|
+
`planning.modelCapacity` session-mass thresholds. In-flight v1 Epics
|
|
56
|
+
must land before upgrading.
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
### Features
|
|
60
|
+
|
|
61
|
+
* collapse `/plan` to a single flat-Story path and retire epic/story routers
|
|
62
|
+
* collapse delivery onto `helpers/deliver-story` with plan-run sequencing
|
|
63
|
+
* deletion sweep for wave/dispatch, epic-runner, and epic lifecycle strata
|
|
64
|
+
* re-key run temp to `temp/run-<id>/`; slim personas and drop `type::epic`
|
|
65
|
+
* drop `delivery.routing.singleDelivery`; land Story-only docs freshness
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
### Documentation
|
|
69
|
+
|
|
70
|
+
* refresh always-loaded hierarchy prose (`AGENTS.md`, `CLAUDE.md`,
|
|
71
|
+
`instructions.md` §5, `SDLC.md`, `architecture.md`, consumer README)
|
|
72
|
+
* regenerate `.agents/docs/configuration.md` without the inert
|
|
73
|
+
`singleDelivery` cell
|
|
74
|
+
|
|
5
75
|
## [1.94.0](https://github.com/dsj1984/mandrel/compare/mandrel-v1.93.0...mandrel-v1.94.0) (2026-07-13)
|
|
6
76
|
|
|
7
77
|
|
package/lib/cli/registry.js
CHANGED
|
@@ -31,12 +31,17 @@ import {
|
|
|
31
31
|
satisfiesNodeEngine,
|
|
32
32
|
} from '../../.agents/scripts/lib/bootstrap/project-bootstrap.js';
|
|
33
33
|
import { isCommandExcluded } from '../../.agents/scripts/lib/command-header.js';
|
|
34
|
+
import { getDeliveryRouting } from '../../.agents/scripts/lib/config/delivery-routing.js';
|
|
34
35
|
import {
|
|
35
36
|
defaultResolvePackageRoot,
|
|
36
37
|
listFiles as listPayloadFiles,
|
|
37
38
|
} from './sync.js';
|
|
38
39
|
import { readCache } from './version-check.js';
|
|
39
|
-
import {
|
|
40
|
+
import {
|
|
41
|
+
compareVersions as compareSemver,
|
|
42
|
+
resolveConsumerPinSpec,
|
|
43
|
+
satisfiesPinSpec,
|
|
44
|
+
} from './version-helpers.js';
|
|
40
45
|
|
|
41
46
|
// ---------------------------------------------------------------------------
|
|
42
47
|
// Internal helpers
|
|
@@ -309,6 +314,60 @@ function runCommandsInSync({ projectRoot, cwd, readDir, readFile } = {}) {
|
|
|
309
314
|
// check: agents-in-sync
|
|
310
315
|
// ---------------------------------------------------------------------------
|
|
311
316
|
|
|
317
|
+
/**
|
|
318
|
+
* Best-effort raw JSON read — no AJV, no merge validation. Absent, unreadable,
|
|
319
|
+
* or malformed files degrade to `null` so a config problem never crashes a
|
|
320
|
+
* doctor check; the caller applies framework defaults on `null`.
|
|
321
|
+
*
|
|
322
|
+
* @param {string} absPath
|
|
323
|
+
* @param {typeof fs} fsImpl
|
|
324
|
+
* @returns {object | null}
|
|
325
|
+
*/
|
|
326
|
+
function readJsonSafe(absPath, fsImpl) {
|
|
327
|
+
try {
|
|
328
|
+
return JSON.parse(fsImpl.readFileSync(absPath, 'utf8'));
|
|
329
|
+
} catch {
|
|
330
|
+
return null;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* Resolve `delivery.routing.roleScopedAgents` (default `true`) for
|
|
336
|
+
* `agents-in-sync`'s fatal/advisory branch below, WITHOUT importing the full
|
|
337
|
+
* `resolveConfig()` chain — that chain pulls in AJV (`config-schema.js`),
|
|
338
|
+
* which would violate this module's own "Node built-ins only" contract (see
|
|
339
|
+
* the module doc: registry.js must load inside the preflight guard, before
|
|
340
|
+
* any third-party package is guaranteed present).
|
|
341
|
+
*
|
|
342
|
+
* Reads `.agentrc.json` and `.agentrc.local.json` directly and shallow-merges
|
|
343
|
+
* only the `delivery.routing` block (local wins per-key) — narrower than the
|
|
344
|
+
* resolver's full deep-merge, but sufficient for this one boolean, and it
|
|
345
|
+
* still honours a local override rather than silently ignoring it. Delegates
|
|
346
|
+
* the actual default/coercion to `getDeliveryRouting` (`config/delivery-
|
|
347
|
+
* routing.js`), which has zero imports of its own and is already the single
|
|
348
|
+
* source of truth for this default elsewhere in the framework.
|
|
349
|
+
*
|
|
350
|
+
* @param {string} projectRoot
|
|
351
|
+
* @param {typeof fs} fsImpl
|
|
352
|
+
* @returns {boolean}
|
|
353
|
+
*/
|
|
354
|
+
function resolveRoleScopedAgentsFlag(projectRoot, fsImpl) {
|
|
355
|
+
const base = readJsonSafe(path.join(projectRoot, '.agentrc.json'), fsImpl);
|
|
356
|
+
const local = readJsonSafe(
|
|
357
|
+
path.join(projectRoot, '.agentrc.local.json'),
|
|
358
|
+
fsImpl,
|
|
359
|
+
);
|
|
360
|
+
const merged = {
|
|
361
|
+
delivery: {
|
|
362
|
+
routing: {
|
|
363
|
+
...(base?.delivery?.routing ?? {}),
|
|
364
|
+
...(local?.delivery?.routing ?? {}),
|
|
365
|
+
},
|
|
366
|
+
},
|
|
367
|
+
};
|
|
368
|
+
return getDeliveryRouting(merged).roleScopedAgents;
|
|
369
|
+
}
|
|
370
|
+
|
|
312
371
|
/**
|
|
313
372
|
* Dry-run the sync-claude-agents logic: compare `.agents/agents/*.md` sources
|
|
314
373
|
* to the generated `.claude/agents/*.md` role-agent tree and report parity.
|
|
@@ -326,30 +385,52 @@ function runCommandsInSync({ projectRoot, cwd, readDir, readFile } = {}) {
|
|
|
326
385
|
* A repo with no `.agents/agents/` sources and no `.claude/agents/` tree is a
|
|
327
386
|
* clean no-op (0 sources, 0 dests → "up to date").
|
|
328
387
|
*
|
|
329
|
-
* **
|
|
330
|
-
*
|
|
331
|
-
*
|
|
332
|
-
*
|
|
333
|
-
*
|
|
334
|
-
*
|
|
335
|
-
*
|
|
336
|
-
*
|
|
388
|
+
* **Tightened from advisory to fatal (Story #4530, M7-B).** Prior to this
|
|
389
|
+
* Story, a **never materialized** agent tree (sources present, `.claude/
|
|
390
|
+
* agents/` empty) was reported as advisory — "inert", because no workflow
|
|
391
|
+
* spawned the role agents yet. M7-B has landed: `helpers/deliver-story` Step
|
|
392
|
+
* 1a dispatches `subagent_type: acceptance-critic` on the **default** path
|
|
393
|
+
* (`roleScopedAgents` defaults `true`). An unmaterialized tree under that
|
|
394
|
+
* default is no longer a benign scaffolding gap — it is the acceptance
|
|
395
|
+
* ceremony's fresh-context critic silently failing to spawn and falling back
|
|
396
|
+
* to a weaker inline critic, with doctor reporting green throughout. This
|
|
397
|
+
* check now fails in exactly that case. When `roleScopedAgents` is `false`
|
|
398
|
+
* (the operator kill-switch), an unmaterialized tree is expected — the check
|
|
399
|
+
* stays advisory. Once the tree HAS been materialized, drift (a source
|
|
400
|
+
* missing from the dest, or a stale dest file) fails the check exactly like
|
|
401
|
+
* `commands-in-sync`, unconditionally, exactly as before this Story.
|
|
337
402
|
*
|
|
338
403
|
* Injectable seams (used by tests so no real filesystem is touched):
|
|
339
404
|
* - `cwd()` replaces `process.cwd` so tests can pin the consumer root.
|
|
340
405
|
* - `readDir` replaces `fs.readdirSync`.
|
|
406
|
+
* - `fsImpl` replaces the `node:fs` surface used for the `.agentrc.json` /
|
|
407
|
+
* `.agentrc.local.json` reads.
|
|
408
|
+
* - `roleScopedAgents` overrides the resolved flag directly, bypassing the
|
|
409
|
+
* config reads entirely.
|
|
341
410
|
*
|
|
342
|
-
* @param {{
|
|
411
|
+
* @param {{
|
|
412
|
+
* projectRoot?: string,
|
|
413
|
+
* cwd?: () => string,
|
|
414
|
+
* readDir?: (dir: string) => string[],
|
|
415
|
+
* fsImpl?: typeof fs,
|
|
416
|
+
* roleScopedAgents?: boolean,
|
|
417
|
+
* }} [opts]
|
|
343
418
|
* @returns {{ ok: boolean, detail: string, remedy?: string }}
|
|
344
419
|
*/
|
|
345
|
-
function runAgentsInSync({
|
|
420
|
+
function runAgentsInSync({
|
|
421
|
+
projectRoot,
|
|
422
|
+
cwd,
|
|
423
|
+
readDir,
|
|
424
|
+
fsImpl = fs,
|
|
425
|
+
roleScopedAgents,
|
|
426
|
+
} = {}) {
|
|
346
427
|
const getCwd = cwd ?? (() => process.cwd());
|
|
347
428
|
const root = projectRoot ?? getCwd();
|
|
348
429
|
const listDir =
|
|
349
430
|
readDir ??
|
|
350
431
|
((dir) => {
|
|
351
432
|
try {
|
|
352
|
-
return
|
|
433
|
+
return fsImpl.readdirSync(dir).filter((f) => f.endsWith('.md'));
|
|
353
434
|
} catch {
|
|
354
435
|
return [];
|
|
355
436
|
}
|
|
@@ -365,14 +446,26 @@ function runAgentsInSync({ projectRoot, cwd, readDir } = {}) {
|
|
|
365
446
|
.filter((f) => !f.startsWith('.'))
|
|
366
447
|
.sort();
|
|
367
448
|
|
|
368
|
-
// Never-materialized agent tree: inert, so advisory (ok:true), not fatal.
|
|
369
449
|
if (dests.length === 0) {
|
|
450
|
+
if (sources.length === 0) {
|
|
451
|
+
return { ok: true, detail: '0 agents up to date' };
|
|
452
|
+
}
|
|
453
|
+
const resolvedFlag =
|
|
454
|
+
typeof roleScopedAgents === 'boolean'
|
|
455
|
+
? roleScopedAgents
|
|
456
|
+
: resolveRoleScopedAgentsFlag(root, fsImpl);
|
|
457
|
+
if (!resolvedFlag) {
|
|
458
|
+
// Kill-switch off: an unmaterialized tree is expected, not a defect.
|
|
459
|
+
return {
|
|
460
|
+
ok: true,
|
|
461
|
+
detail: `${sources.length} agent def(s) not materialized (roleScopedAgents is disabled)`,
|
|
462
|
+
};
|
|
463
|
+
}
|
|
370
464
|
return {
|
|
371
|
-
ok:
|
|
372
|
-
detail:
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
: `${sources.length} agent def(s) not yet materialized (inert)`,
|
|
465
|
+
ok: false,
|
|
466
|
+
detail: `${sources.length} agent def(s) not yet materialized in .claude/agents/`,
|
|
467
|
+
remedy:
|
|
468
|
+
'Run `mandrel sync-agents` to regenerate the `.claude/agents/` tree.',
|
|
376
469
|
};
|
|
377
470
|
}
|
|
378
471
|
|
|
@@ -392,7 +485,7 @@ function runAgentsInSync({ projectRoot, cwd, readDir } = {}) {
|
|
|
392
485
|
ok: false,
|
|
393
486
|
detail: parts.join(', '),
|
|
394
487
|
remedy:
|
|
395
|
-
'Run `
|
|
488
|
+
'Run `mandrel sync-agents` to regenerate the `.claude/agents/` tree.',
|
|
396
489
|
};
|
|
397
490
|
}
|
|
398
491
|
|
|
@@ -705,6 +798,149 @@ export function runAgentsDrift({ cwd, fsImpl = fs, resolvePackageRoot } = {}) {
|
|
|
705
798
|
};
|
|
706
799
|
}
|
|
707
800
|
|
|
801
|
+
// ---------------------------------------------------------------------------
|
|
802
|
+
// check: pin-current
|
|
803
|
+
// ---------------------------------------------------------------------------
|
|
804
|
+
|
|
805
|
+
/**
|
|
806
|
+
* Fatal doctor check (Story #4525 / #4530): is the version actually
|
|
807
|
+
* resolvable in `node_modules` **consistent with** the consumer's declared
|
|
808
|
+
* `mandrel` dependency range (`package.json`)?
|
|
809
|
+
*
|
|
810
|
+
* This is a **different** signal from `agents-drift` (are the materialized
|
|
811
|
+
* `.agents/` file *contents* byte-identical to the installed payload) and
|
|
812
|
+
* from `version-current` below (is a *newer* version *published*). Neither
|
|
813
|
+
* of those catches the shape of bug #4525 reported: a `package.json` pin
|
|
814
|
+
* that has fallen out of agreement with what `node_modules` actually
|
|
815
|
+
* resolves to — e.g. an out-of-band symlink, or `npm install mandrel@latest
|
|
816
|
+
* --no-save` — which `mandrel doctor` graded as fully green before this
|
|
817
|
+
* check existed, because the only version `defaultCurrentVersion` ever read
|
|
818
|
+
* WAS the inflated `node_modules` one.
|
|
819
|
+
*
|
|
820
|
+
* **Range-aware.** The declared pin is a *range*, not an equality, so the
|
|
821
|
+
* question this check asks is satisfaction, not identity. A consumer who
|
|
822
|
+
* declares `^2.1.0` and runs a routine `npm update` gets 2.4.0 in
|
|
823
|
+
* `node_modules` with `package.json` untouched — that is npm behaving
|
|
824
|
+
* exactly as documented, and under this project's `always-bump-minor`
|
|
825
|
+
* release cadence it is the *normal* steady state, not a defect. Grading it
|
|
826
|
+
* fatal (as this check originally did, comparing only the pin's base
|
|
827
|
+
* version) made `mandrel doctor` cry wolf on healthy installs.
|
|
828
|
+
*
|
|
829
|
+
* The graded contract:
|
|
830
|
+
* - installed **satisfies** the declared range and equals its base version
|
|
831
|
+
* → pass, quietly.
|
|
832
|
+
* - installed **satisfies** the declared range but is newer than its base
|
|
833
|
+
* (`^2.1.0` + 2.4.0) → pass with an **advisory** `detail`. Re-pinning via
|
|
834
|
+
* `mandrel update` is tidier, but nothing is broken. This mirrors how
|
|
835
|
+
* `version-current` stays non-fatal: `ok: true` with the advisory carried
|
|
836
|
+
* in `detail` (the registry's `advisory: true` flag documents an entry
|
|
837
|
+
* whose `run()` *never* fails, which is not true of this check).
|
|
838
|
+
* - installed does **not** satisfy the declared range (`^2.1.0` + 3.0.0, or
|
|
839
|
+
* an exact `2.1.0` pin + 2.4.0) → **fail**. The declared dependency does
|
|
840
|
+
* not describe the code that is running.
|
|
841
|
+
* - installed is **behind** the pin's base version (`^2.4.0` + 2.1.0) →
|
|
842
|
+
* **fail**, and note that `<` the base never satisfies any of the ranges
|
|
843
|
+
* `resolveConsumerPinSpec` yields, so this is a sub-case of the above
|
|
844
|
+
* given a distinct, more actionable message.
|
|
845
|
+
*
|
|
846
|
+
* Skips cleanly (not a failure) when there is no resolvable pin at all — no
|
|
847
|
+
* `package.json`, no `mandrel` entry in `dependencies`/`devDependencies`, or
|
|
848
|
+
* a non-semver specifier (`workspace:`, `git+`, `latest`, a comparator
|
|
849
|
+
* range) — via {@link resolveConsumerPinSpec}'s own `null` contract. This
|
|
850
|
+
* is also how mandrel's own repo (no self-dependency) and workspace/npx
|
|
851
|
+
* consumers degrade to a clean pass rather than a false failure.
|
|
852
|
+
*
|
|
853
|
+
* Injectable seams (used by tests so no real filesystem or package is
|
|
854
|
+
* needed):
|
|
855
|
+
* - `cwd()` — replaces `process.cwd`, anchoring both the pin read and the
|
|
856
|
+
* `node_modules` resolution at the same consumer root (mirrors
|
|
857
|
+
* `agents-drift` / `agents-in-sync`).
|
|
858
|
+
* - `fsImpl` — replaces the `node:fs` surface.
|
|
859
|
+
* - `resolvePackageRoot(fromDir)` — replaces `mandrel` resolution; throws
|
|
860
|
+
* when the package is not installed.
|
|
861
|
+
*
|
|
862
|
+
* @param {{
|
|
863
|
+
* cwd?: () => string,
|
|
864
|
+
* fsImpl?: typeof fs,
|
|
865
|
+
* resolvePackageRoot?: (fromDir: string) => string,
|
|
866
|
+
* }} [opts]
|
|
867
|
+
* @returns {{ ok: boolean, detail: string, remedy?: string }}
|
|
868
|
+
*/
|
|
869
|
+
export function runPinCurrent({ cwd, fsImpl = fs, resolvePackageRoot } = {}) {
|
|
870
|
+
const getCwd = cwd ?? (() => process.cwd());
|
|
871
|
+
const resolveRoot = resolvePackageRoot ?? defaultResolvePackageRoot;
|
|
872
|
+
const projectRoot = getCwd();
|
|
873
|
+
|
|
874
|
+
const spec = resolveConsumerPinSpec(projectRoot, fsImpl);
|
|
875
|
+
if (!spec) {
|
|
876
|
+
return {
|
|
877
|
+
ok: true,
|
|
878
|
+
detail: 'no resolvable mandrel dependency pin — skipped',
|
|
879
|
+
};
|
|
880
|
+
}
|
|
881
|
+
|
|
882
|
+
let installedRoot;
|
|
883
|
+
try {
|
|
884
|
+
installedRoot = resolveRoot(projectRoot);
|
|
885
|
+
} catch {
|
|
886
|
+
// No baseline to compare the pin against; agents-materialized /
|
|
887
|
+
// runtime-deps own the "not installed" remedy.
|
|
888
|
+
return {
|
|
889
|
+
ok: true,
|
|
890
|
+
detail: 'mandrel not installed — pin check skipped',
|
|
891
|
+
};
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
let installed;
|
|
895
|
+
try {
|
|
896
|
+
const parsed = JSON.parse(
|
|
897
|
+
fsImpl.readFileSync(path.join(installedRoot, 'package.json'), 'utf8'),
|
|
898
|
+
);
|
|
899
|
+
installed = String(parsed.version);
|
|
900
|
+
} catch {
|
|
901
|
+
return {
|
|
902
|
+
ok: true,
|
|
903
|
+
detail: 'installed version unreadable — pin check skipped',
|
|
904
|
+
};
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
const declared = `${spec.operator}${spec.version}`;
|
|
908
|
+
|
|
909
|
+
if (compareSemver(installed, spec.version) < 0) {
|
|
910
|
+
return {
|
|
911
|
+
ok: false,
|
|
912
|
+
detail: `package.json pins ${declared} but an older v${installed} is installed`,
|
|
913
|
+
remedy:
|
|
914
|
+
'Run `npm install` to install a version satisfying the package.json pin.',
|
|
915
|
+
};
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
if (!satisfiesPinSpec(installed, spec)) {
|
|
919
|
+
return {
|
|
920
|
+
ok: false,
|
|
921
|
+
detail: `package.json pins ${declared} but v${installed} is installed — outside the declared range`,
|
|
922
|
+
remedy:
|
|
923
|
+
'Run `mandrel update` to reconcile the package.json pin with the installed version.',
|
|
924
|
+
};
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
if (compareSemver(installed, spec.version) > 0) {
|
|
928
|
+
// In range, just newer than the declared base — the ordinary result of an
|
|
929
|
+
// `npm update` under a caret/tilde pin. Healthy, so `ok: true`; the
|
|
930
|
+
// advisory rides in `detail` (the doctor runner only prints `remedy` for
|
|
931
|
+
// failures).
|
|
932
|
+
return {
|
|
933
|
+
ok: true,
|
|
934
|
+
detail: `v${installed} satisfies the ${declared} pin but is newer than it — run \`mandrel update\` to re-pin (advisory)`,
|
|
935
|
+
};
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
return {
|
|
939
|
+
ok: true,
|
|
940
|
+
detail: `pin ${declared} matches the installed version`,
|
|
941
|
+
};
|
|
942
|
+
}
|
|
943
|
+
|
|
708
944
|
// ---------------------------------------------------------------------------
|
|
709
945
|
// check: version-current
|
|
710
946
|
// ---------------------------------------------------------------------------
|
|
@@ -870,6 +1106,13 @@ export const registry = [
|
|
|
870
1106
|
name: 'agents-drift',
|
|
871
1107
|
run: (opts) => runAgentsDrift(opts),
|
|
872
1108
|
},
|
|
1109
|
+
{
|
|
1110
|
+
name: 'pin-current',
|
|
1111
|
+
// Fatal, unlike version-current below (Story #4525/#4530): a pin/install
|
|
1112
|
+
// disagreement means the declared dependency does not describe the code
|
|
1113
|
+
// that is running.
|
|
1114
|
+
run: (opts) => runPinCurrent(opts),
|
|
1115
|
+
},
|
|
873
1116
|
{
|
|
874
1117
|
name: 'version-current',
|
|
875
1118
|
// Non-fatal: surfaces a cache-only stale-version advisory. `run()` always
|