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
package/lib/cli/update.js
CHANGED
|
@@ -136,8 +136,12 @@ import { fileURLToPath } from 'node:url';
|
|
|
136
136
|
import { detectPackageManagerWithWorkspace } from '../../.agents/scripts/lib/detect-package-manager.js';
|
|
137
137
|
import { runInstallCommand } from '../../.agents/scripts/lib/install-cmd-parser.js';
|
|
138
138
|
import { runAgentsDrift } from './registry.js';
|
|
139
|
+
import { defaultResolvePackageRoot } from './sync.js';
|
|
139
140
|
import { isStale } from './version-check.js';
|
|
140
|
-
import {
|
|
141
|
+
import {
|
|
142
|
+
compareVersions,
|
|
143
|
+
resolveConsumerPinVersion,
|
|
144
|
+
} from './version-helpers.js';
|
|
141
145
|
|
|
142
146
|
/** The published package whose newest version `mandrel update` advances to. */
|
|
143
147
|
const PACKAGE_NAME = 'mandrel';
|
|
@@ -163,6 +167,15 @@ const DEFAULT_CACHE_FILENAME = 'version-check.json';
|
|
|
163
167
|
* `package.json`. The module lives at `<root>/lib/cli/update.js`, so the
|
|
164
168
|
* manifest is two directories up.
|
|
165
169
|
*
|
|
170
|
+
* Pre-Story-#4525 this was the update decision's `current` — the exact
|
|
171
|
+
* self-referential confusion #4525 filed: "the version of the mandrel that
|
|
172
|
+
* is executing" is tautologically `>= target` whenever the installed
|
|
173
|
+
* package is newest, which made the `npm-update` step unreachable whenever
|
|
174
|
+
* a consumer's declared pin had fallen behind what happened to be resolved
|
|
175
|
+
* in `node_modules`. It survives here only as the last-resort fallback
|
|
176
|
+
* inside {@link resolveCurrentVersionForUpdate}, for the case where even
|
|
177
|
+
* `node_modules` resolution from the consumer root fails.
|
|
178
|
+
*
|
|
166
179
|
* @param {typeof nodeFs} [fs]
|
|
167
180
|
* @returns {string}
|
|
168
181
|
*/
|
|
@@ -173,6 +186,48 @@ function defaultCurrentVersion(fs = nodeFs) {
|
|
|
173
186
|
return String(parsed.version);
|
|
174
187
|
}
|
|
175
188
|
|
|
189
|
+
/**
|
|
190
|
+
* Resolve the "current" version for the `mandrel update` decision
|
|
191
|
+
* (Story #4525 / #4530): the consumer's declared `mandrel` dependency pin
|
|
192
|
+
* when it resolves to a plain semver, falling back — in order — to the
|
|
193
|
+
* version actually resolvable in the consumer's `node_modules` (anchored at
|
|
194
|
+
* `consumerRoot` via the same resolution `mandrel sync` uses, unlike the
|
|
195
|
+
* pre-#4525 self-referential `defaultCurrentVersion`), and finally to
|
|
196
|
+
* `defaultCurrentVersion` itself when neither resolves (a corrupted or
|
|
197
|
+
* highly unusual install — keeps `mandrel update` from throwing outright
|
|
198
|
+
* rather than silently misreporting "already current").
|
|
199
|
+
*
|
|
200
|
+
* The declared pin is preferred because it is exactly what the `npm-update`
|
|
201
|
+
* step moves: a consumer whose `package.json` pin lags an inflated
|
|
202
|
+
* `node_modules` resolution (e.g. an out-of-band symlink or manual
|
|
203
|
+
* `npm install mandrel@latest --no-save`) must still see `planUpdate`
|
|
204
|
+
* choose `updated`, not `resynced` — the bug #4525 reported.
|
|
205
|
+
*
|
|
206
|
+
* @param {string} consumerRoot
|
|
207
|
+
* @param {typeof nodeFs} [fs]
|
|
208
|
+
* @param {{ resolvePackageRoot?: (fromDir: string) => string }} [opts] - test
|
|
209
|
+
* seam for the `node_modules` resolution tier; defaults to the real
|
|
210
|
+
* `defaultResolvePackageRoot` from `sync.js`.
|
|
211
|
+
* @returns {string}
|
|
212
|
+
*/
|
|
213
|
+
export function resolveCurrentVersionForUpdate(
|
|
214
|
+
consumerRoot,
|
|
215
|
+
fs = nodeFs,
|
|
216
|
+
{ resolvePackageRoot = defaultResolvePackageRoot } = {},
|
|
217
|
+
) {
|
|
218
|
+
const pinned = resolveConsumerPinVersion(consumerRoot, fs);
|
|
219
|
+
if (pinned) return pinned;
|
|
220
|
+
try {
|
|
221
|
+
const packageRoot = resolvePackageRoot(consumerRoot);
|
|
222
|
+
const parsed = JSON.parse(
|
|
223
|
+
fs.readFileSync(path.join(packageRoot, 'package.json'), 'utf8'),
|
|
224
|
+
);
|
|
225
|
+
return String(parsed.version);
|
|
226
|
+
} catch {
|
|
227
|
+
return defaultCurrentVersion(fs);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
176
231
|
/**
|
|
177
232
|
* Resolve the project root — the directory two levels up from this module
|
|
178
233
|
* (`<root>/lib/cli/update.js`). Mirrors `lib/cli/registry.js#resolveProjectRoot`.
|
|
@@ -685,18 +740,20 @@ export function defaultSpawnPhase(
|
|
|
685
740
|
* The ordered step names the orchestrator drives on an update. Shared
|
|
686
741
|
* by the live path and the `--dry-run` plan printout so the two never drift.
|
|
687
742
|
*
|
|
688
|
-
* Step ordering (Story #4046 A1c):
|
|
743
|
+
* Step ordering (Story #4046 A1c; sync-agents added by Story #4528/#4530):
|
|
689
744
|
* 1. npm-update — install the new version
|
|
690
745
|
* 2. runSync — re-materialize .agents/ from the new payload
|
|
691
746
|
* 3. sync-commands — regenerate .claude/commands/ from the new payload
|
|
692
|
-
* 4.
|
|
693
|
-
* 5.
|
|
694
|
-
* 6.
|
|
747
|
+
* 4. sync-agents — regenerate .claude/agents/ from the new payload
|
|
748
|
+
* 5. runMigrations — apply version-keyed migrations
|
|
749
|
+
* 6. doctor — validate the post-upgrade state
|
|
750
|
+
* 7. surface changelog — print the changelog (always last, best-effort)
|
|
695
751
|
*/
|
|
696
752
|
const STEP_PLAN = [
|
|
697
753
|
'npm-update',
|
|
698
754
|
'runSync',
|
|
699
755
|
'sync-commands',
|
|
756
|
+
'sync-agents',
|
|
700
757
|
'runMigrations',
|
|
701
758
|
'doctor',
|
|
702
759
|
'surface changelog',
|
|
@@ -744,6 +801,20 @@ function fullUpgradeSteps(current, target) {
|
|
|
744
801
|
'the .claude/commands/ tree may be out of sync. ' +
|
|
745
802
|
'Run `npm run sync:commands` manually to restore.',
|
|
746
803
|
},
|
|
804
|
+
{
|
|
805
|
+
// Story #4528/#4530: the CLI update path previously never projected the
|
|
806
|
+
// role-agent tree at all — only the bootstrap path did. Added alongside
|
|
807
|
+
// sync-commands so `.claude/agents/` materializes here too, which is
|
|
808
|
+
// what makes the tightened `agents-in-sync` doctor check satisfiable.
|
|
809
|
+
kind: 'spawn',
|
|
810
|
+
phase: 'sync-agents',
|
|
811
|
+
args: [],
|
|
812
|
+
label: 'sync-agents',
|
|
813
|
+
failMessage:
|
|
814
|
+
'mandrel update: `mandrel sync-agents` from new binary exited non-zero — ' +
|
|
815
|
+
'the .claude/agents/ tree may be out of sync. ' +
|
|
816
|
+
'Run `mandrel sync-agents` manually to restore.',
|
|
817
|
+
},
|
|
747
818
|
{
|
|
748
819
|
kind: 'spawn',
|
|
749
820
|
phase: 'migrate',
|
|
@@ -760,8 +831,9 @@ function fullUpgradeSteps(current, target) {
|
|
|
760
831
|
|
|
761
832
|
/**
|
|
762
833
|
* The ordered phase descriptors for a drift-heal (version already current, but
|
|
763
|
-
* `.agents/` is stale). No npm-update, no migrations, no doctor — only the
|
|
764
|
-
* sync phases re-materialize the payload from the already-installed
|
|
834
|
+
* `.agents/` is stale). No npm-update, no migrations, no doctor — only the
|
|
835
|
+
* three sync phases re-materialize the payload from the already-installed
|
|
836
|
+
* binary.
|
|
765
837
|
*
|
|
766
838
|
* @returns {Array<{ kind: 'spawn', phase: string, args: string[], label: string, failMessage: string }>}
|
|
767
839
|
*/
|
|
@@ -787,6 +859,17 @@ function driftHealSteps() {
|
|
|
787
859
|
'the .claude/commands/ tree may be out of sync. ' +
|
|
788
860
|
'Run `npm run sync:commands` manually to restore.',
|
|
789
861
|
},
|
|
862
|
+
{
|
|
863
|
+
// Story #4528/#4530: see the matching entry in fullUpgradeSteps().
|
|
864
|
+
kind: 'spawn',
|
|
865
|
+
phase: 'sync-agents',
|
|
866
|
+
args: [],
|
|
867
|
+
label: 'sync-agents',
|
|
868
|
+
failMessage:
|
|
869
|
+
'mandrel update: `mandrel sync-agents` from installed binary exited non-zero — ' +
|
|
870
|
+
'the .claude/agents/ tree may be out of sync. ' +
|
|
871
|
+
'Run `mandrel sync-agents` manually to restore.',
|
|
872
|
+
},
|
|
790
873
|
];
|
|
791
874
|
}
|
|
792
875
|
|
|
@@ -1070,6 +1153,9 @@ export async function runUpdate({
|
|
|
1070
1153
|
write(
|
|
1071
1154
|
' 2. sync-commands — regenerate .claude/commands/ from .agents/workflows/\n',
|
|
1072
1155
|
);
|
|
1156
|
+
write(
|
|
1157
|
+
' 3. sync-agents — regenerate .claude/agents/ from .agents/agents/\n',
|
|
1158
|
+
);
|
|
1073
1159
|
write('Dry run: no files written.\n');
|
|
1074
1160
|
} else {
|
|
1075
1161
|
write(`mandrel update — planned upgrade v${current} → v${target}\n`);
|
|
@@ -1202,6 +1288,8 @@ export async function runUpdate({
|
|
|
1202
1288
|
* changelogPath?: string,
|
|
1203
1289
|
* fetchChangelog?: (version: string) => Promise<string>,
|
|
1204
1290
|
* runUpdate?: typeof runUpdate,
|
|
1291
|
+
* cwd?: () => string,
|
|
1292
|
+
* checkDrift?: () => (boolean | Promise<boolean>),
|
|
1205
1293
|
* write?: (s: string) => void,
|
|
1206
1294
|
* writeErr?: (s: string) => void,
|
|
1207
1295
|
* exit?: (code: number) => void,
|
|
@@ -1224,9 +1312,16 @@ export default async function run(argv = [], deps = {}) {
|
|
|
1224
1312
|
writeErr = (s) => process.stderr.write(s),
|
|
1225
1313
|
exit = (code) => process.exit(code),
|
|
1226
1314
|
log,
|
|
1315
|
+
cwd,
|
|
1316
|
+
checkDrift,
|
|
1227
1317
|
} = deps;
|
|
1228
1318
|
|
|
1229
|
-
const
|
|
1319
|
+
const cwdFn = typeof cwd === 'function' ? cwd : () => process.cwd();
|
|
1320
|
+
|
|
1321
|
+
// Story #4525/#4530: prefer the consumer's declared dependency pin over
|
|
1322
|
+
// the pre-#4525 self-referential read — see resolveCurrentVersionForUpdate.
|
|
1323
|
+
const current =
|
|
1324
|
+
deps.currentVersion ?? resolveCurrentVersionForUpdate(cwdFn(), fs);
|
|
1230
1325
|
|
|
1231
1326
|
// The production spawnPhase: spawn each post-install phase from
|
|
1232
1327
|
// node_modules/.bin/mandrel (the newly-installed binary). This is the sole
|
|
@@ -1260,6 +1355,7 @@ export default async function run(argv = [], deps = {}) {
|
|
|
1260
1355
|
runInstall: runInstall ?? runInstallCommand,
|
|
1261
1356
|
fs,
|
|
1262
1357
|
}),
|
|
1358
|
+
...(checkDrift ? { checkDrift } : {}),
|
|
1263
1359
|
spawnPhase: productionSpawnPhase,
|
|
1264
1360
|
surfaceChangelog: (target) =>
|
|
1265
1361
|
defaultSurfaceChangelog(target, {
|
|
@@ -1273,5 +1369,6 @@ export default async function run(argv = [], deps = {}) {
|
|
|
1273
1369
|
write,
|
|
1274
1370
|
writeErr,
|
|
1275
1371
|
exit,
|
|
1372
|
+
cwd: cwdFn,
|
|
1276
1373
|
});
|
|
1277
1374
|
}
|
|
@@ -7,11 +7,23 @@
|
|
|
7
7
|
* `compareVersions`; this module is the single authoritative
|
|
8
8
|
* implementation (Story #4048 B3 — multiplied helpers).
|
|
9
9
|
*
|
|
10
|
+
* `resolveConsumerPinVersion` (Story #4530) lives here for the same
|
|
11
|
+
* no-mirror-copies reason rather than in either file directly: `update.js`
|
|
12
|
+
* already imports `registry.js` (for the drift-check fallback), so a
|
|
13
|
+
* function needed by both would otherwise force a two-way circular import
|
|
14
|
+
* between them. This module is a dependency-free leaf both already import.
|
|
15
|
+
*
|
|
10
16
|
* Builtins only — this module is imported from both the CLI surface
|
|
11
17
|
* (`lib/cli/`) and the doctor registry which runs before third-party
|
|
12
18
|
* packages are guaranteed to be present.
|
|
13
19
|
*/
|
|
14
20
|
|
|
21
|
+
import nodeFs from 'node:fs';
|
|
22
|
+
import path from 'node:path';
|
|
23
|
+
|
|
24
|
+
/** The published package whose consumer pin is resolved below. */
|
|
25
|
+
const PACKAGE_NAME = 'mandrel';
|
|
26
|
+
|
|
15
27
|
/**
|
|
16
28
|
* Parse a dotted semver-ish string into a numeric tuple. Non-numeric or
|
|
17
29
|
* missing segments coerce to 0 so a partial version still compares sanely.
|
|
@@ -57,3 +69,122 @@ export function compareVersions(a, b) {
|
|
|
57
69
|
export function crossesMajor(current, target) {
|
|
58
70
|
return parseVersion(target)[0] > parseVersion(current)[0];
|
|
59
71
|
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Does `version` satisfy the range described by `spec` — a
|
|
75
|
+
* `{ operator, version }` pin spec as returned by
|
|
76
|
+
* {@link resolveConsumerPinSpec}?
|
|
77
|
+
*
|
|
78
|
+
* A deliberately minimal caret/tilde/exact implementation rather than a
|
|
79
|
+
* `semver` dependency: `version-helpers.js` is builtins-only (it is imported
|
|
80
|
+
* by the doctor registry, which runs before third-party packages are
|
|
81
|
+
* guaranteed to be present), and the only ranges
|
|
82
|
+
* {@link resolveConsumerPinSpec} ever yields are `^`, `~`, and exact.
|
|
83
|
+
*
|
|
84
|
+
* Semantics match npm's:
|
|
85
|
+
* - `''` (exact) → `version === spec.version`
|
|
86
|
+
* - `~1.2.3` → `>=1.2.3 <1.3.0`
|
|
87
|
+
* - `^1.2.3` → `>=1.2.3 <2.0.0`
|
|
88
|
+
* - `^0.2.3` → `>=0.2.3 <0.3.0` (0.x: the minor axis is the API axis)
|
|
89
|
+
* - `^0.0.3` → `>=0.0.3 <0.0.4`
|
|
90
|
+
*
|
|
91
|
+
* Prerelease tags are ignored on both sides, consistent with
|
|
92
|
+
* {@link parseVersion}'s numeric-tuple contract.
|
|
93
|
+
*
|
|
94
|
+
* @param {string} version
|
|
95
|
+
* @param {{ operator: '^' | '~' | '', version: string }} spec
|
|
96
|
+
* @returns {boolean}
|
|
97
|
+
*/
|
|
98
|
+
export function satisfiesPinSpec(version, spec) {
|
|
99
|
+
if (compareVersions(version, spec.version) < 0) return false;
|
|
100
|
+
const [vMajor, vMinor] = parseVersion(version);
|
|
101
|
+
const [pMajor, pMinor, pPatch] = parseVersion(spec.version);
|
|
102
|
+
|
|
103
|
+
if (spec.operator === '~') {
|
|
104
|
+
return vMajor === pMajor && vMinor === pMinor;
|
|
105
|
+
}
|
|
106
|
+
if (spec.operator === '^') {
|
|
107
|
+
if (pMajor > 0) return vMajor === pMajor;
|
|
108
|
+
if (pMinor > 0) return vMajor === 0 && vMinor === pMinor;
|
|
109
|
+
// ^0.0.x pins the patch axis exactly.
|
|
110
|
+
return compareVersions(version, `0.0.${pPatch}`) === 0;
|
|
111
|
+
}
|
|
112
|
+
return compareVersions(version, spec.version) === 0;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Read the consumer's declared `mandrel` dependency pin from
|
|
117
|
+
* `<consumerRoot>/package.json` (checking `dependencies` then
|
|
118
|
+
* `devDependencies`), returning both the range `operator` and the base
|
|
119
|
+
* `version` it decorates.
|
|
120
|
+
*
|
|
121
|
+
* Callers that only need to decide whether `npm install mandrel@<target>`
|
|
122
|
+
* would move the declared pin want {@link resolveConsumerPinVersion} (the
|
|
123
|
+
* base version alone). Callers that need to ask whether an installed
|
|
124
|
+
* version is *in range* — `mandrel doctor`'s `pin-current` check — need the
|
|
125
|
+
* operator too, because `^2.1.0` and `2.1.0` make very different claims
|
|
126
|
+
* about an installed 2.4.0.
|
|
127
|
+
*
|
|
128
|
+
* Returns `null` under exactly the same conditions as
|
|
129
|
+
* {@link resolveConsumerPinVersion} — see its contract.
|
|
130
|
+
*
|
|
131
|
+
* @param {string} consumerRoot
|
|
132
|
+
* @param {typeof nodeFs} [fsImpl]
|
|
133
|
+
* @returns {{ operator: '^' | '~' | '', version: string } | null}
|
|
134
|
+
*/
|
|
135
|
+
export function resolveConsumerPinSpec(consumerRoot, fsImpl = nodeFs) {
|
|
136
|
+
let parsed;
|
|
137
|
+
try {
|
|
138
|
+
const raw = fsImpl.readFileSync(
|
|
139
|
+
path.join(consumerRoot, 'package.json'),
|
|
140
|
+
'utf8',
|
|
141
|
+
);
|
|
142
|
+
parsed = JSON.parse(raw);
|
|
143
|
+
} catch {
|
|
144
|
+
return null;
|
|
145
|
+
}
|
|
146
|
+
const declared =
|
|
147
|
+
parsed?.dependencies?.[PACKAGE_NAME] ??
|
|
148
|
+
parsed?.devDependencies?.[PACKAGE_NAME];
|
|
149
|
+
if (typeof declared !== 'string') return null;
|
|
150
|
+
const match = /^([\^~]?)(\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?)$/.exec(
|
|
151
|
+
declared.trim(),
|
|
152
|
+
);
|
|
153
|
+
if (!match) return null;
|
|
154
|
+
return {
|
|
155
|
+
operator: /** @type {'^' | '~' | ''} */ (match[1]),
|
|
156
|
+
version: match[2],
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Read the consumer's declared `mandrel` dependency pin from
|
|
162
|
+
* `<consumerRoot>/package.json` (checking `dependencies` then
|
|
163
|
+
* `devDependencies`), stripping a leading `^`/`~` range operator to
|
|
164
|
+
* recover a base semver for comparison against the registry's newest
|
|
165
|
+
* published version.
|
|
166
|
+
*
|
|
167
|
+
* A base-version compare against the target is the right question here
|
|
168
|
+
* regardless of what the full range technically already matches: the
|
|
169
|
+
* declared pin is exactly what `npm install mandrel@<target>` (the
|
|
170
|
+
* `mandrel update` `npm-update` step) moves, so comparing its base version
|
|
171
|
+
* decides whether that step needs to run.
|
|
172
|
+
*
|
|
173
|
+
* Returns `null` — never throws — when there is no readable `package.json`,
|
|
174
|
+
* no `mandrel` entry in either dependency block, or the declared value
|
|
175
|
+
* isn't a plain exact/caret/tilde semver (a `workspace:`/`file:`/`git+`
|
|
176
|
+
* specifier, `latest`, `*`, or a comparator range). Callers fall back to
|
|
177
|
+
* resolving the actually-installed version in that case — see
|
|
178
|
+
* `lib/cli/update.js#resolveCurrentVersionForUpdate` and
|
|
179
|
+
* `lib/cli/registry.js`'s `pin-current` doctor check (both Story #4530),
|
|
180
|
+
* which is also how a project with no `mandrel` dependency at all —
|
|
181
|
+
* including mandrel's own repo, which carries no self-dependency —
|
|
182
|
+
* degrades to a clean skip rather than a false failure.
|
|
183
|
+
*
|
|
184
|
+
* @param {string} consumerRoot
|
|
185
|
+
* @param {typeof nodeFs} [fsImpl]
|
|
186
|
+
* @returns {string | null}
|
|
187
|
+
*/
|
|
188
|
+
export function resolveConsumerPinVersion(consumerRoot, fsImpl = nodeFs) {
|
|
189
|
+
return resolveConsumerPinSpec(consumerRoot, fsImpl)?.version ?? null;
|
|
190
|
+
}
|
package/lib/migrations/README.md
CHANGED
|
@@ -9,11 +9,13 @@ filtering, idempotency enforcement, and the actionable per-step log line. The
|
|
|
9
9
|
`migrations` array is the single source of truth for which steps exist and in
|
|
10
10
|
what order they run.
|
|
11
11
|
|
|
12
|
-
>
|
|
13
|
-
>
|
|
14
|
-
>
|
|
15
|
-
>
|
|
16
|
-
>
|
|
12
|
+
> Story #4531 registered the first real step —
|
|
13
|
+
> [`steps/2.1.0-retire-mi-drop-knobs.js`](./steps/2.1.0-retire-mi-drop-knobs.js),
|
|
14
|
+
> which strips the retired `codingGuardrails.miDropMustRefactor` and
|
|
15
|
+
> `autoRefresh.miDropCap` keys from a consumer's `.agentrc.json`. The
|
|
16
|
+
> machinery itself is still exercised independently by fixture steps in
|
|
17
|
+
> [`__tests__/index.test.js`](./__tests__/index.test.js). Add the next real
|
|
18
|
+
> step here (ascending by version) when the next contract cutover lands.
|
|
17
19
|
|
|
18
20
|
## Step shape
|
|
19
21
|
|
package/lib/migrations/index.js
CHANGED
|
@@ -43,17 +43,21 @@
|
|
|
43
43
|
* already in the tree (the consumer was on that version) and is skipped; a
|
|
44
44
|
* step at exactly `toVersion` is the target and runs.
|
|
45
45
|
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
* `
|
|
50
|
-
*
|
|
46
|
+
* v2.0.0's Story-collapse cutover did not register a config migration step
|
|
47
|
+
* (consumers wipe/re-sync `.agents/` and re-seed `.agentrc.json` from the
|
|
48
|
+
* starter). Story #4531 registered the first real step — see
|
|
49
|
+
* `steps/2.1.0-retire-mi-drop-knobs.js` — alongside the fixture steps in
|
|
50
|
+
* `__tests__/index.test.js` that prove the machinery independent of any
|
|
51
|
+
* real step. When the next contract cutover lands, add its step here
|
|
52
|
+
* (ascending by version) with an idempotent `detect`/`apply`.
|
|
51
53
|
*/
|
|
52
54
|
|
|
55
|
+
import { retireMiDropKnobs } from './steps/2.1.0-retire-mi-drop-knobs.js';
|
|
56
|
+
import { retireVerifyConcurrencyCap } from './steps/2.1.0-retire-verify-concurrency-cap.js';
|
|
57
|
+
|
|
53
58
|
/**
|
|
54
59
|
* Ordered registry of migration steps. MUST stay sorted ascending by
|
|
55
|
-
* `version`.
|
|
56
|
-
* here.
|
|
60
|
+
* `version`.
|
|
57
61
|
*
|
|
58
62
|
* @type {Array<{
|
|
59
63
|
* version: string,
|
|
@@ -62,7 +66,7 @@
|
|
|
62
66
|
* apply: (ctx: unknown) => void,
|
|
63
67
|
* }>}
|
|
64
68
|
*/
|
|
65
|
-
export const migrations = [];
|
|
69
|
+
export const migrations = [retireMiDropKnobs, retireVerifyConcurrencyCap];
|
|
66
70
|
|
|
67
71
|
/**
|
|
68
72
|
* Parse a dotted semver-ish string into a numeric tuple for comparison.
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
// lib/migrations/steps/2.1.0-retire-mi-drop-knobs.js
|
|
2
|
+
/**
|
|
3
|
+
* Story #4531 — the first real step in the migration registry.
|
|
4
|
+
*
|
|
5
|
+
* `delivery.quality.codingGuardrails.miDropMustRefactor` and
|
|
6
|
+
* `delivery.quality.autoRefresh.miDropCap` were schema-validated, defaulted,
|
|
7
|
+
* and seeded by `apply-quality-bootstrap.js` into a consumer's
|
|
8
|
+
* `.agentrc.json` — but never consumed by the gate they were named for
|
|
9
|
+
* (`maintainability.tolerance` is the knob actually in force; see the
|
|
10
|
+
* Story body for the full diagnosis). Both retired keys lived under
|
|
11
|
+
* sub-schemas with `additionalProperties: false`, so a consumer whose
|
|
12
|
+
* config still carries either key hits a hard AJV validation failure on
|
|
13
|
+
* upgrade, not a warning. This step strips them before that check runs.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import nodeFs from 'node:fs';
|
|
17
|
+
import path from 'node:path';
|
|
18
|
+
|
|
19
|
+
const AGENTRC_FILENAME = '.agentrc.json';
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @param {unknown} ctx
|
|
23
|
+
* @returns {string}
|
|
24
|
+
*/
|
|
25
|
+
function resolveAgentrcPath(ctx) {
|
|
26
|
+
const projectRoot = ctx?.projectRoot ?? process.cwd();
|
|
27
|
+
return path.join(projectRoot, AGENTRC_FILENAME);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* @param {unknown} ctx
|
|
32
|
+
* @param {typeof nodeFs} fsImpl
|
|
33
|
+
* @returns {object | null}
|
|
34
|
+
*/
|
|
35
|
+
function readAgentrcConfig(ctx, fsImpl) {
|
|
36
|
+
try {
|
|
37
|
+
const raw = fsImpl.readFileSync(resolveAgentrcPath(ctx), 'utf8');
|
|
38
|
+
return JSON.parse(raw);
|
|
39
|
+
} catch {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* @param {object | null} config
|
|
46
|
+
* @returns {boolean}
|
|
47
|
+
*/
|
|
48
|
+
function hasRetiredKey(config) {
|
|
49
|
+
const guardrails = config?.delivery?.quality?.codingGuardrails;
|
|
50
|
+
const autoRefresh = config?.delivery?.quality?.autoRefresh;
|
|
51
|
+
return (
|
|
52
|
+
(Boolean(guardrails) && Object.hasOwn(guardrails, 'miDropMustRefactor')) ||
|
|
53
|
+
(Boolean(autoRefresh) && Object.hasOwn(autoRefresh, 'miDropCap'))
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export const retireMiDropKnobs = {
|
|
58
|
+
version: '2.1.0',
|
|
59
|
+
description:
|
|
60
|
+
'strip retired delivery.quality.codingGuardrails.miDropMustRefactor ' +
|
|
61
|
+
'and delivery.quality.autoRefresh.miDropCap from .agentrc.json',
|
|
62
|
+
/**
|
|
63
|
+
* @param {{ projectRoot?: string, fs?: typeof nodeFs }} [ctx]
|
|
64
|
+
* @returns {boolean}
|
|
65
|
+
*/
|
|
66
|
+
detect(ctx) {
|
|
67
|
+
const fsImpl = ctx?.fs ?? nodeFs;
|
|
68
|
+
return hasRetiredKey(readAgentrcConfig(ctx, fsImpl));
|
|
69
|
+
},
|
|
70
|
+
/**
|
|
71
|
+
* @param {{ projectRoot?: string, fs?: typeof nodeFs }} [ctx]
|
|
72
|
+
* @returns {void}
|
|
73
|
+
*/
|
|
74
|
+
apply(ctx) {
|
|
75
|
+
const fsImpl = ctx?.fs ?? nodeFs;
|
|
76
|
+
const config = readAgentrcConfig(ctx, fsImpl);
|
|
77
|
+
if (!config) return;
|
|
78
|
+
|
|
79
|
+
const guardrails = config.delivery?.quality?.codingGuardrails;
|
|
80
|
+
if (guardrails && Object.hasOwn(guardrails, 'miDropMustRefactor')) {
|
|
81
|
+
delete guardrails.miDropMustRefactor;
|
|
82
|
+
if (Object.keys(guardrails).length === 0) {
|
|
83
|
+
delete config.delivery.quality.codingGuardrails;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const autoRefresh = config.delivery?.quality?.autoRefresh;
|
|
88
|
+
if (autoRefresh && Object.hasOwn(autoRefresh, 'miDropCap')) {
|
|
89
|
+
delete autoRefresh.miDropCap;
|
|
90
|
+
if (Object.keys(autoRefresh).length === 0) {
|
|
91
|
+
delete config.delivery.quality.autoRefresh;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
fsImpl.writeFileSync(
|
|
96
|
+
resolveAgentrcPath(ctx),
|
|
97
|
+
`${JSON.stringify(config, null, 2)}\n`,
|
|
98
|
+
);
|
|
99
|
+
},
|
|
100
|
+
};
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
// lib/migrations/steps/2.1.0-retire-verify-concurrency-cap.js
|
|
2
|
+
/**
|
|
3
|
+
* Story #4545 — retire `delivery.deliverRunner.verifyConcurrencyCap`.
|
|
4
|
+
*
|
|
5
|
+
* The knob was schema-validated, defaulted to 4, resolved by `getRunners`,
|
|
6
|
+
* and documented as bounding "the per-wave verifyWaveResults loop" — a loop
|
|
7
|
+
* that does not exist anywhere in the tree. Its only reader was
|
|
8
|
+
* `analyze-execution.js`, which echoed the number into a perf report rather
|
|
9
|
+
* than bounding anything; that CLI is deleted in the same Story. Setting the
|
|
10
|
+
* knob to any value only ever changed a number printed in a report.
|
|
11
|
+
*
|
|
12
|
+
* `delivery.deliverRunner` declares `additionalProperties: false`, so a
|
|
13
|
+
* consumer whose config still carries the key hits a hard AJV validation
|
|
14
|
+
* failure on upgrade — every script that resolves config, not just the one
|
|
15
|
+
* that read it. This step strips it before that check runs.
|
|
16
|
+
*
|
|
17
|
+
* Unlike the 2.1.0 mi-drop step, this one also sweeps `.agentrc.local.json`:
|
|
18
|
+
* the resolver deep-merges the local override over `.agentrc.json` and
|
|
19
|
+
* validates the *merged* result, so a key left in the local file fails the
|
|
20
|
+
* same way a key in the committed file does.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
import nodeFs from 'node:fs';
|
|
24
|
+
import path from 'node:path';
|
|
25
|
+
|
|
26
|
+
const AGENTRC_FILENAMES = ['.agentrc.json', '.agentrc.local.json'];
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @param {unknown} ctx
|
|
30
|
+
* @param {string} filename
|
|
31
|
+
* @returns {string}
|
|
32
|
+
*/
|
|
33
|
+
function resolveAgentrcPath(ctx, filename) {
|
|
34
|
+
const projectRoot = ctx?.projectRoot ?? process.cwd();
|
|
35
|
+
return path.join(projectRoot, filename);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* @param {unknown} ctx
|
|
40
|
+
* @param {string} filename
|
|
41
|
+
* @param {typeof nodeFs} fsImpl
|
|
42
|
+
* @returns {object | null}
|
|
43
|
+
*/
|
|
44
|
+
function readAgentrcConfig(ctx, filename, fsImpl) {
|
|
45
|
+
try {
|
|
46
|
+
const raw = fsImpl.readFileSync(resolveAgentrcPath(ctx, filename), 'utf8');
|
|
47
|
+
return JSON.parse(raw);
|
|
48
|
+
} catch {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* @param {object | null} config
|
|
55
|
+
* @returns {boolean}
|
|
56
|
+
*/
|
|
57
|
+
function hasRetiredKey(config) {
|
|
58
|
+
const deliverRunner = config?.delivery?.deliverRunner;
|
|
59
|
+
return (
|
|
60
|
+
Boolean(deliverRunner) &&
|
|
61
|
+
Object.hasOwn(deliverRunner, 'verifyConcurrencyCap')
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export const retireVerifyConcurrencyCap = {
|
|
66
|
+
version: '2.1.0',
|
|
67
|
+
description:
|
|
68
|
+
'strip retired delivery.deliverRunner.verifyConcurrencyCap from ' +
|
|
69
|
+
'.agentrc.json and .agentrc.local.json',
|
|
70
|
+
/**
|
|
71
|
+
* @param {{ projectRoot?: string, fs?: typeof nodeFs }} [ctx]
|
|
72
|
+
* @returns {boolean}
|
|
73
|
+
*/
|
|
74
|
+
detect(ctx) {
|
|
75
|
+
const fsImpl = ctx?.fs ?? nodeFs;
|
|
76
|
+
return AGENTRC_FILENAMES.some((filename) =>
|
|
77
|
+
hasRetiredKey(readAgentrcConfig(ctx, filename, fsImpl)),
|
|
78
|
+
);
|
|
79
|
+
},
|
|
80
|
+
/**
|
|
81
|
+
* @param {{ projectRoot?: string, fs?: typeof nodeFs }} [ctx]
|
|
82
|
+
* @returns {void}
|
|
83
|
+
*/
|
|
84
|
+
apply(ctx) {
|
|
85
|
+
const fsImpl = ctx?.fs ?? nodeFs;
|
|
86
|
+
for (const filename of AGENTRC_FILENAMES) {
|
|
87
|
+
const config = readAgentrcConfig(ctx, filename, fsImpl);
|
|
88
|
+
if (!hasRetiredKey(config)) continue;
|
|
89
|
+
|
|
90
|
+
delete config.delivery.deliverRunner.verifyConcurrencyCap;
|
|
91
|
+
if (Object.keys(config.delivery.deliverRunner).length === 0) {
|
|
92
|
+
delete config.delivery.deliverRunner;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
fsImpl.writeFileSync(
|
|
96
|
+
resolveAgentrcPath(ctx, filename),
|
|
97
|
+
`${JSON.stringify(config, null, 2)}\n`,
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mandrel",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "Claude Code-first opinionated workflow framework: instructions,
|
|
3
|
+
"version": "2.1.0",
|
|
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/",
|
|
7
7
|
"bin/",
|
package/.agents/agents/retro.md
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: retro
|
|
3
|
-
description: >-
|
|
4
|
-
Role-scoped boot context for a minimal reference-gathering retro pass. Booted
|
|
5
|
-
on its own system prompt (no CLAUDE.md / instructions.md closure). Gathers and
|
|
6
|
-
summarizes retrospective signals; it does not deliver code or judge
|
|
7
|
-
acceptance. INERT under M7-A — no workflow references this agent type yet
|
|
8
|
-
(that is M7-B).
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
# retro — reference-gathering boot context
|
|
12
|
-
|
|
13
|
-
<!--
|
|
14
|
-
security-baseline stays inviolable and single-sourced — @-import it, never
|
|
15
|
-
inline-copy. The path resolves to the repo root from BOTH the payload source
|
|
16
|
-
(.agents/agents/) and the materialized destination (.claude/agents/) because
|
|
17
|
-
each is exactly two levels below the repo root.
|
|
18
|
-
-->
|
|
19
|
-
|
|
20
|
-
@../../.agents/rules/security-baseline.md
|
|
21
|
-
|
|
22
|
-
You are a **reference-gathering retro** agent. You collect and summarize
|
|
23
|
-
retrospective signals for the caller; you do not implement changes, open PRs,
|
|
24
|
-
or score acceptance.
|
|
25
|
-
|
|
26
|
-
## What you do
|
|
27
|
-
|
|
28
|
-
- Read the friction / acceptance-eval signals from the per-Epic (or standalone)
|
|
29
|
-
`signals.ndjson` streams the retro roll-up points you at, plus any open
|
|
30
|
-
feedback issues the caller threads in.
|
|
31
|
-
- Cluster and summarize them into a compact, de-duplicated set of observations
|
|
32
|
-
the caller can route into proposals. Report signal provenance (which stream /
|
|
33
|
-
issue each observation came from); do not fabricate signals.
|
|
34
|
-
|
|
35
|
-
## Boundaries
|
|
36
|
-
|
|
37
|
-
- **Read-only.** Do not modify code, commit, change ticket labels, or open PRs.
|
|
38
|
-
You gather and report; the caller decides what to route.
|
|
39
|
-
- **No acceptance judgment.** Scoring a diff against acceptance criteria is the
|
|
40
|
-
acceptance-critic's job, not yours.
|
|
41
|
-
- Emit only paths, counts, and signal summaries — never secrets or raw
|
|
42
|
-
credential values (security-baseline § Data Leakage & Logging).
|