mandrel 1.93.0 → 2.0.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 +59 -73
- package/.agents/agents/acceptance-critic.md +129 -0
- package/.agents/agents/story-worker.md +161 -0
- package/.agents/docs/SDLC.md +489 -1285
- package/.agents/docs/agentrc-reference.json +177 -67
- package/.agents/docs/configuration.md +108 -136
- package/.agents/docs/execution-reference.md +44 -22
- package/.agents/docs/quality-gates.md +13 -19
- package/.agents/docs/workflows.md +3 -3
- package/.agents/instructions.md +107 -108
- package/.agents/rules/ci-remediation.md +8 -12
- package/.agents/rules/git-conventions-reference.md +224 -0
- package/.agents/rules/git-conventions.md +42 -223
- package/.agents/rules/security-baseline.md +5 -0
- package/.agents/rules/testing-standards.md +106 -13
- package/.agents/schemas/acceptance-eval-verdict.schema.json +1 -1
- package/.agents/schemas/agentrc.schema.json +71 -201
- package/.agents/schemas/lifecycle/ledger-record.schema.json +1 -1
- package/.agents/schemas/lifecycle/retro.end.schema.json +1 -1
- package/.agents/schemas/risk-verdict.schema.json +0 -13
- package/.agents/scripts/acceptance-eval.js +62 -18
- package/.agents/scripts/agents-bootstrap-github.js +1 -1
- package/.agents/scripts/analyze-execution.js +1 -1
- package/.agents/scripts/audit-to-stories.js +7 -7
- package/.agents/scripts/boot-sweep.js +1 -1
- package/.agents/scripts/check-context-budget.js +62 -5
- package/.agents/scripts/check-lifecycle-lint.js +6 -9
- package/.agents/scripts/check-prepush-recovery.js +1 -1
- package/.agents/scripts/cleanup-repo-test-temp.js +6 -1
- package/.agents/scripts/diagnose-friction.js +0 -6
- 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 +5 -5
- 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 -4
- package/.agents/scripts/lib/baselines/reader.js +1 -6
- package/.agents/scripts/lib/bdd-runner-detect.js +5 -9
- package/.agents/scripts/lib/bootstrap/issue-forms-template.js +32 -33
- package/.agents/scripts/lib/bootstrap/project-bootstrap.js +56 -18
- package/.agents/scripts/lib/checks/core-bare-clean.js +2 -2
- package/.agents/scripts/lib/checks/index.js +2 -1
- package/.agents/scripts/lib/checks/story-init-not-backgrounded.js +23 -21
- package/.agents/scripts/lib/cli/standard-args.js +13 -22
- package/.agents/scripts/lib/cli-args.js +16 -7
- package/.agents/scripts/lib/close-validation/gates.js +160 -22
- package/.agents/scripts/lib/config/acceptance-eval.js +52 -5
- package/.agents/scripts/lib/config/ci.js +6 -31
- package/.agents/scripts/lib/config/delivery-routing.js +103 -0
- package/.agents/scripts/lib/config/explain.js +57 -36
- package/.agents/scripts/lib/config/limits.js +17 -58
- package/.agents/scripts/lib/config/paths.js +0 -2
- package/.agents/scripts/lib/config/quality.js +1 -1
- package/.agents/scripts/lib/config/runners.js +17 -50
- package/.agents/scripts/lib/config/temp-paths.js +19 -14
- package/.agents/scripts/lib/config/worktree-isolation.js +0 -5
- package/.agents/scripts/lib/config-resolver.js +3 -8
- package/.agents/scripts/lib/config-settings-schema-delivery.js +46 -136
- package/.agents/scripts/lib/config-settings-schema-quality.js +17 -14
- package/.agents/scripts/lib/config-settings-schema.js +52 -38
- package/.agents/scripts/lib/dependency-parser.js +3 -2
- package/.agents/scripts/lib/doc-tiers.js +39 -4
- package/.agents/scripts/lib/duplicate-search.js +211 -41
- package/.agents/scripts/lib/feedback-loop/retro-proposals-graduator.js +1 -1
- package/.agents/scripts/lib/findings/promote-finding.js +5 -5
- package/.agents/scripts/lib/framework-version.js +2 -3
- package/.agents/scripts/lib/git-branch-cleanup.js +1 -10
- package/.agents/scripts/lib/git-branch-lifecycle.js +17 -22
- package/.agents/scripts/lib/git-utils.js +32 -6
- package/.agents/scripts/lib/github/framework-repo.js +6 -0
- package/.agents/scripts/lib/label-constants.js +10 -23
- package/.agents/scripts/lib/label-taxonomy.js +9 -43
- package/.agents/scripts/lib/observability/active-story-env.js +112 -3
- package/.agents/scripts/lib/observability/hook-heartbeat.js +187 -0
- package/.agents/scripts/lib/observability/source-classifier.js +3 -3
- package/.agents/scripts/lib/observability/tool-trace-hook.js +15 -4
- package/.agents/scripts/lib/onboard/init-tail.js +1 -3
- package/.agents/scripts/lib/orchestration/acceptance-clusters.js +111 -0
- package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +32 -4
- package/.agents/scripts/lib/orchestration/audit-lens-routing.js +128 -0
- package/.agents/scripts/lib/orchestration/bookkeeping-outbox.js +273 -0
- package/.agents/scripts/lib/orchestration/ceremony-routing.js +204 -0
- package/.agents/scripts/lib/orchestration/code-review.js +20 -268
- package/.agents/scripts/lib/orchestration/column-sync.js +1 -1
- package/.agents/scripts/lib/orchestration/consolidation-precondition.js +1 -1
- package/.agents/scripts/lib/orchestration/context-envelope.js +2 -5
- 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/lifecycle/emit-loop-tick.js +8 -8
- package/.agents/scripts/lib/orchestration/lifecycle/emit-story-heartbeat.js +2 -2
- package/.agents/scripts/lib/orchestration/lifecycle/ledger-writer.js +6 -3
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/README.md +17 -43
- package/.agents/scripts/lib/orchestration/lint-baseline-service.js +4 -4
- package/.agents/scripts/lib/orchestration/merge-block-class.js +1 -1
- package/.agents/scripts/lib/orchestration/phase-runner.js +3 -2
- package/.agents/scripts/lib/orchestration/plan-context.js +248 -266
- package/.agents/scripts/lib/orchestration/plan-critic-conditions.js +3 -2
- package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +1 -1
- package/.agents/scripts/lib/orchestration/plan-navigation.js +92 -0
- package/.agents/scripts/lib/orchestration/plan-persist/fan-out-gate.js +61 -0
- package/.agents/scripts/lib/orchestration/plan-persist/persist-helpers.js +97 -0
- package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +223 -854
- package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +361 -0
- package/.agents/scripts/lib/orchestration/plan-persist/summary.js +35 -108
- 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 +14 -14
- package/.agents/scripts/lib/orchestration/planning/decomposer-context.js +27 -0
- package/.agents/scripts/lib/orchestration/{epic-plan-spec/phases → planning}/risk-verdict.js +3 -4
- package/.agents/scripts/lib/orchestration/post-merge/phases/branch-cleanup.js +2 -2
- package/.agents/scripts/lib/orchestration/post-merge/phases/dashboard-refresh.js +8 -20
- package/.agents/scripts/lib/orchestration/post-merge/phases/worktree-reap.js +3 -2
- package/.agents/scripts/lib/orchestration/pr-base-guard.js +18 -28
- package/.agents/scripts/lib/orchestration/preflight-cache.js +5 -5
- package/.agents/scripts/lib/orchestration/remote-verifier.js +1 -1
- package/.agents/scripts/lib/orchestration/resolve-plan-run.js +155 -0
- package/.agents/scripts/lib/orchestration/resolves-token.js +1 -1
- package/.agents/scripts/lib/orchestration/retro-perf-heuristics.js +8 -8
- package/.agents/scripts/lib/orchestration/retro-proposals.js +140 -79
- package/.agents/scripts/lib/orchestration/review-depth.js +26 -12
- package/.agents/scripts/lib/orchestration/review-providers/codex.js +2 -2
- package/.agents/scripts/lib/orchestration/review-providers/review-provider-factory.js +21 -56
- package/.agents/scripts/lib/orchestration/run-epilogue.js +426 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +1 -1
- package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +1 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +95 -41
- package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +16 -13
- package/.agents/scripts/lib/orchestration/single-story-close/phases/review-block.js +40 -0
- package/.agents/scripts/lib/orchestration/single-story-close/runner.js +11 -3
- 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/phases/code-review.js +15 -12
- package/.agents/scripts/lib/orchestration/story-follow-ups.js +237 -0
- package/.agents/scripts/lib/orchestration/story-init-remote.js +47 -0
- package/.agents/scripts/lib/orchestration/story-plan-state.js +48 -0
- package/.agents/scripts/lib/orchestration/{epic-runner → story-progress}/story-run-progress-writer.js +3 -3
- package/.agents/scripts/lib/orchestration/structured-comment-parser.js +1 -1
- package/.agents/scripts/lib/orchestration/task-body-validator.js +8 -18
- package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +11 -61
- package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +189 -373
- package/.agents/scripts/lib/orchestration/ticket-validator.js +3 -8
- package/.agents/scripts/lib/orchestration/ticketing/bulk.js +0 -25
- package/.agents/scripts/lib/orchestration/ticketing/reads.js +29 -26
- package/.agents/scripts/lib/orchestration/ticketing/transition.js +5 -5
- package/.agents/scripts/lib/planning-corpus.js +16 -11
- package/.agents/scripts/lib/preflight-runner.js +2 -2
- package/.agents/scripts/lib/provider-factory.js +1 -1
- package/.agents/scripts/lib/qa/coverage-verdict.js +5 -5
- package/.agents/scripts/lib/single-story/confirm-merge-follow-ups.js +36 -0
- package/.agents/scripts/lib/single-story-sweep/protection-ctx.js +1 -1
- package/.agents/scripts/lib/story-adjacency.js +11 -14
- package/.agents/scripts/lib/story-body/story-body.js +124 -70
- package/.agents/scripts/lib/story-plan.js +2 -4
- package/.agents/scripts/lib/templates/decomposer-prompts.js +46 -45
- package/.agents/scripts/lib/templates/spec-author-prompts.js +47 -45
- package/.agents/scripts/lib/{epic-body-sections.js → ticket-body-sections.js} +26 -26
- package/.agents/scripts/lib/validation-evidence.js +1 -1
- package/.agents/scripts/lib/wave-runner/ready-set.js +6 -6
- package/.agents/scripts/lib/workspace-provisioner.js +1 -1
- package/.agents/scripts/lib/worktree/lifecycle/reap.js +5 -7
- 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 +64 -74
- package/.agents/scripts/plan-persist.js +121 -280
- package/.agents/scripts/plan-run-epilogue.js +97 -0
- package/.agents/scripts/post-structured-comment.js +38 -0
- package/.agents/scripts/providers/github/issues.js +17 -33
- package/.agents/scripts/providers/github/mappers.js +0 -12
- package/.agents/scripts/providers/github/tickets.js +2 -5
- package/.agents/scripts/resolve-plan-run.js +117 -0
- package/.agents/scripts/signals-view.js +24 -19
- package/.agents/scripts/single-story-close.js +11 -14
- package/.agents/scripts/single-story-confirm-merge.js +39 -23
- package/.agents/scripts/single-story-init.js +29 -20
- package/.agents/scripts/stories-wave-tick.js +6 -6
- package/.agents/scripts/story-plan.js +26 -47
- package/.agents/scripts/sync-claude-agents.js +165 -0
- package/.agents/scripts/update-ticket-state.js +37 -15
- package/.agents/skills/core/analyze-execution/SKILL.md +21 -18
- package/.agents/skills/core/api-and-interface-design/SKILL.md +5 -3
- package/.agents/skills/core/code-review-and-quality/SKILL.md +63 -7
- package/.agents/skills/core/debugging-and-error-recovery/SKILL.md +1 -1
- package/.agents/skills/core/gates-and-baselines/SKILL.md +149 -0
- package/.agents/skills/core/idea-refinement/SKILL.md +8 -14
- package/.agents/skills/core/qa-coverage-mapping/SKILL.md +7 -7
- package/.agents/skills/core/scope-triage/SKILL.md +28 -172
- package/.agents/skills/skills.index.json +8 -418
- package/.agents/starter-agentrc.json +0 -5
- package/.agents/templates/agent-protocol.md +9 -10
- package/.agents/workflows/audit-architecture.md +3 -3
- package/.agents/workflows/audit-clean-code.md +3 -3
- package/.agents/workflows/audit-dependencies.md +3 -3
- package/.agents/workflows/audit-devops.md +3 -3
- package/.agents/workflows/audit-documentation.md +5 -5
- package/.agents/workflows/audit-lighthouse.md +3 -3
- package/.agents/workflows/audit-navigability.md +3 -2
- package/.agents/workflows/audit-performance.md +3 -3
- package/.agents/workflows/audit-privacy.md +3 -3
- package/.agents/workflows/audit-quality.md +3 -3
- package/.agents/workflows/audit-security.md +3 -3
- package/.agents/workflows/audit-seo.md +3 -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 +3 -3
- package/.agents/workflows/deliver.md +122 -131
- package/.agents/workflows/git-cleanup.md +3 -4
- package/.agents/workflows/helpers/_merge-conflict-template.md +1 -1
- package/.agents/workflows/helpers/acceptance-self-eval.md +52 -40
- package/.agents/workflows/helpers/code-review.md +70 -193
- package/.agents/workflows/helpers/{single-story-deliver-reference.md → deliver-story-reference.md} +12 -14
- package/.agents/workflows/helpers/{single-story-deliver.md → deliver-story.md} +113 -139
- package/.agents/workflows/helpers/diagnose.md +10 -10
- package/.agents/workflows/helpers/mandrel-sync-config.md +1 -1
- package/.agents/workflows/helpers/parallel-tooling.md +1 -1
- package/.agents/workflows/helpers/signals.md +16 -16
- package/.agents/workflows/helpers/worktree-lifecycle.md +48 -64
- package/.agents/workflows/mandrel-update.md +3 -2
- package/.agents/workflows/plan.md +112 -145
- package/.agents/workflows/qa-assist.md +24 -30
- package/.agents/workflows/qa-explore.md +29 -38
- package/.agents/workflows/qa-run.md +2 -2
- package/README.md +9 -8
- package/docs/CHANGELOG.md +46 -0
- package/lib/cli/registry.js +95 -0
- package/lib/migrations/index.js +6 -5
- package/package.json +5 -3
- package/.agents/personas/architect.md +0 -113
- package/.agents/personas/devops-engineer.md +0 -38
- package/.agents/personas/engineer-mobile.md +0 -120
- package/.agents/personas/engineer-web.md +0 -111
- package/.agents/personas/engineer.md +0 -119
- package/.agents/personas/product.md +0 -94
- package/.agents/personas/project-manager.md +0 -114
- package/.agents/personas/qa-engineer.md +0 -95
- package/.agents/personas/refactorer.md +0 -113
- package/.agents/personas/security-engineer.md +0 -112
- package/.agents/personas/sre.md +0 -86
- package/.agents/personas/technical-writer.md +0 -101
- package/.agents/personas/ux-designer.md +0 -95
- package/.agents/schemas/dispatch-manifest.json +0 -232
- package/.agents/schemas/epic-spec.schema.json +0 -153
- package/.agents/scripts/acceptance-spec-reconciler.js +0 -642
- 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 -590
- package/.agents/scripts/epic-execute-record-wave.js +0 -449
- package/.agents/scripts/epic-plan-clarity.js +0 -211
- package/.agents/scripts/epic-plan-decompose.js +0 -54
- package/.agents/scripts/epic-plan-healthcheck.js +0 -581
- package/.agents/scripts/epic-plan-spec.js +0 -64
- 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/orchestration/context-hydration-engine.js +0 -660
- 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/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 -388
- 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/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/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-story-dispatch-end.js +0 -147
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/acceptance-reconciler.js +0 -384
- 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 -278
- 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/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/post-merge-pipeline.js +0 -205
- 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-runner.js +0 -197
- package/.agents/scripts/lib/orchestration/skill-capsule-loader.js +0 -109
- 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 -301
- 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/plan-critics.js +0 -199
- package/.agents/scripts/retro-run.js +0 -218
- 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 -335
- package/.agents/skills/core/baseline-refresh/SKILL.md +0 -181
- package/.agents/skills/core/ci-cd-and-automation/SKILL.md +0 -274
- package/.agents/skills/core/ci-cd-and-automation/examples.md +0 -211
- package/.agents/skills/core/code-simplification/SKILL.md +0 -389
- package/.agents/skills/core/context-engineering/SKILL.md +0 -309
- package/.agents/skills/core/context-engineering/examples.md +0 -58
- package/.agents/skills/core/deprecation-and-migration/SKILL.md +0 -250
- 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 -413
- package/.agents/skills/core/epic-plan-spec-author/examples.md +0 -91
- package/.agents/skills/core/frontend-ui-engineering/SKILL.md +0 -357
- package/.agents/skills/core/hydrate-context/SKILL.md +0 -123
- package/.agents/skills/core/idea-refinement/examples.md +0 -437
- package/.agents/skills/core/idea-refinement/frameworks.md +0 -135
- package/.agents/skills/core/incremental-implementation/SKILL.md +0 -271
- package/.agents/skills/core/introducing-a-baseline-gate/SKILL.md +0 -213
- package/.agents/skills/core/knowledge-transfer/SKILL.md +0 -180
- package/.agents/skills/core/mutation-survivor-remediation/SKILL.md +0 -117
- package/.agents/skills/core/performance-optimization/SKILL.md +0 -314
- package/.agents/skills/core/planning-and-task-breakdown/SKILL.md +0 -277
- package/.agents/skills/core/property-based-testing/SKILL.md +0 -148
- package/.agents/skills/core/refactoring-discipline/SKILL.md +0 -111
- package/.agents/skills/core/shipping-and-launch/SKILL.md +0 -328
- package/.agents/skills/core/spec-driven-development/SKILL.md +0 -252
- package/.agents/skills/core/test-driven-development/SKILL.md +0 -475
- package/.agents/skills/core/using-agent-skills/SKILL.md +0 -232
- package/.agents/skills/stack/architecture/monorepo-path-strategist/SKILL.md +0 -31
- package/.agents/skills/stack/architecture/structured-output-zod/SKILL.md +0 -51
- package/.agents/skills/stack/architecture/subagent-orchestration/SKILL.md +0 -76
- package/.agents/skills/stack/backend/cloudflare-hono-architect/SKILL.md +0 -31
- package/.agents/skills/stack/backend/cloudflare-hono-architect/examples/route-template.ts +0 -33
- package/.agents/skills/stack/backend/cloudflare-queue-manager/SKILL.md +0 -31
- package/.agents/skills/stack/backend/cloudflare-workers/SKILL.md +0 -51
- package/.agents/skills/stack/backend/highlevel-crm/SKILL.md +0 -54
- package/.agents/skills/stack/backend/sqlite-drizzle-expert/SKILL.md +0 -29
- package/.agents/skills/stack/backend/sqlite-drizzle-expert/examples/schema-template.ts +0 -30
- package/.agents/skills/stack/backend/stripe-integration/SKILL.md +0 -57
- package/.agents/skills/stack/backend/stripe-integration/scripts/listen-stripe.sh +0 -9
- package/.agents/skills/stack/backend/turso-sqlite/SKILL.md +0 -48
- package/.agents/skills/stack/frontend/astro/SKILL.md +0 -62
- package/.agents/skills/stack/frontend/astro-react-island-strategist/SKILL.md +0 -30
- package/.agents/skills/stack/frontend/expo-react-native-developer/SKILL.md +0 -29
- package/.agents/skills/stack/frontend/google-analytics-v4/SKILL.md +0 -50
- package/.agents/skills/stack/frontend/tailwind-v4/SKILL.md +0 -58
- package/.agents/skills/stack/frontend/ui-accessibility-engineer/SKILL.md +0 -34
- package/.agents/skills/stack/qa/audit-accessibility/SKILL.md +0 -51
- package/.agents/skills/stack/qa/lighthouse-baseline/SKILL.md +0 -199
- package/.agents/skills/stack/security/backend-security-patterns/SKILL.md +0 -68
- package/.agents/workflows/helpers/deliver-epic-reference.md +0 -534
- package/.agents/workflows/helpers/deliver-epic.md +0 -955
- package/.agents/workflows/helpers/deliver-stories.md +0 -440
- package/.agents/workflows/helpers/epic-audit.md +0 -189
- package/.agents/workflows/helpers/epic-deliver-story.md +0 -427
- 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 -351
- package/.agents/workflows/helpers/plan-story.md +0 -251
- package/.agents/workflows/helpers/scope-triage-gate.md +0 -108
- /package/.agents/scripts/lib/orchestration/{epic-plan-spec/phases → planning}/spec-authoring-grounding.js +0 -0
|
@@ -1,227 +0,0 @@
|
|
|
1
|
-
import nodeFs from 'node:fs';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
import { loadCoverage as defaultLoadCoverage } from '../../../coverage-utils.js';
|
|
4
|
-
import { calculateCrapForSource } from '../../../crap-engine.js';
|
|
5
|
-
import { formatNumber } from './_bullet-format.js';
|
|
6
|
-
import {
|
|
7
|
-
createDriftDetector,
|
|
8
|
-
walkComponentRegressions,
|
|
9
|
-
} from './component-drift.js';
|
|
10
|
-
|
|
11
|
-
const DEFAULT_THRESHOLD = 5.0;
|
|
12
|
-
const DEFAULT_CEILING = 30;
|
|
13
|
-
// Distinct from the canonical ratchet baseline at `baselines/crap.json`
|
|
14
|
-
// (Epic #730 Story 5.5) — this is a per-wave drift SNAPSHOT, not the
|
|
15
|
-
// committed score baseline. Filename intentionally differs so a repo-wide
|
|
16
|
-
// grep for the canonical baseline no longer hits the snapshot.
|
|
17
|
-
const BASELINE_FILENAME = 'wave-crap-snapshot.json';
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Normalise a repo-relative path for coverage-key lookup. Pure; exported
|
|
21
|
-
* for unit tests so the underlying branches don't have to be exercised
|
|
22
|
-
* through the closure-bound `findCoverageEntry`.
|
|
23
|
-
*/
|
|
24
|
-
export function normaliseCoveragePath(relPath) {
|
|
25
|
-
return String(relPath)
|
|
26
|
-
.replace(/\\/g, '/')
|
|
27
|
-
.replace(/^\.\/+/, '');
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* True when a coverage map key matches a (normalised) relative path,
|
|
32
|
-
* either by full equality or by suffix-with-slash. Pure.
|
|
33
|
-
*/
|
|
34
|
-
export function coverageKeyMatches(key, suffix) {
|
|
35
|
-
const norm = String(key).replace(/\\/g, '/');
|
|
36
|
-
return norm === suffix || norm.endsWith(`/${suffix}`);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Detect per-component CRAP regressions from a baseline rollup against the
|
|
41
|
-
* gate's configured floors. Pure — the caller loads the baseline via
|
|
42
|
-
* `lib/baselines/reader.js#load('crap')` and passes the resulting
|
|
43
|
-
* `{ rollup }` plus the gate config block.
|
|
44
|
-
*
|
|
45
|
-
* Bullet shape (Task #1919, Epic #1786):
|
|
46
|
-
*
|
|
47
|
-
* 🧨 crap: <component> <axis> <value> > floor <floor>
|
|
48
|
-
*
|
|
49
|
-
* CRAP is a "lower is better" gate — every axis breach reports when
|
|
50
|
-
* `value > floor`. Component-scoped breaches do NOT trigger a `*` bullet
|
|
51
|
-
* unless `*` itself breaches. The walk itself is the shared
|
|
52
|
-
* `component-drift.js` helper (Story #3984).
|
|
53
|
-
*
|
|
54
|
-
* @param {{
|
|
55
|
-
* rollup?: Record<string, Record<string, number>>,
|
|
56
|
-
* gateConfig?: { floors?: Record<string, Record<string, number>> } & object,
|
|
57
|
-
* }} params
|
|
58
|
-
* @returns {string[]}
|
|
59
|
-
*/
|
|
60
|
-
export function detectComponentRegressions(params = {}) {
|
|
61
|
-
return walkComponentRegressions(params, {
|
|
62
|
-
isBreach: (value, cap) => value > cap,
|
|
63
|
-
formatBullet: (name, axis, value, cap) =>
|
|
64
|
-
`🧨 crap: ${name} ${axis} ${formatNumber(value)} > floor ${formatNumber(cap)}`,
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Detects per-method CRAP drift versus a wave-start baseline.
|
|
70
|
-
*
|
|
71
|
-
* Mirrors the `maintainability-drift.js` contract but at per-method
|
|
72
|
-
* granularity: baseline snapshots are `{ "<file>::<method>@<startLine>": crap }`
|
|
73
|
-
* rather than a single score per file. A method surfaces as a Notable bullet
|
|
74
|
-
* when either condition holds:
|
|
75
|
-
*
|
|
76
|
-
* - **Crossed the ceiling** — current CRAP ≥ `ceiling` and baseline was
|
|
77
|
-
* either absent or below `ceiling`. Captures newly introduced hotspots
|
|
78
|
-
* and methods that tipped over the budget.
|
|
79
|
-
* - **Rose by ≥ threshold** — baseline present and `current - baseline ≥
|
|
80
|
-
* threshold`. Captures silent regressions that stay under the ceiling
|
|
81
|
-
* but are trending badly.
|
|
82
|
-
*
|
|
83
|
-
* Bullet shape:
|
|
84
|
-
*
|
|
85
|
-
* 🧨 CRAP drift: <file>::<method> <score> (ceiling <N>)
|
|
86
|
-
*
|
|
87
|
-
* Persistence: baseline is written to `<cwd>/<baselineDir>/wave-crap-snapshot.json`
|
|
88
|
-
* so a resumed epic run can reuse the wave-start anchor rather than lose it.
|
|
89
|
-
*
|
|
90
|
-
* Resilience: read / scoring errors for an individual file are swallowed (and
|
|
91
|
-
* optionally logged) so a single unscorable file cannot take the progress
|
|
92
|
-
* reporter down.
|
|
93
|
-
*
|
|
94
|
-
* @param {{
|
|
95
|
-
* cwd?: string,
|
|
96
|
-
* files?: string[],
|
|
97
|
-
* fs?: { readFileSync: Function, writeFileSync?: Function, mkdirSync?: Function, existsSync?: Function },
|
|
98
|
-
* calculate?: (source: string, coverageForFile: object|null) => Array<{ method: string, startLine: number, crap: number|null }>,
|
|
99
|
-
* loadCoverage?: (coveragePath: string) => object|null,
|
|
100
|
-
* coveragePath?: string | null,
|
|
101
|
-
* threshold?: number,
|
|
102
|
-
* ceiling?: number,
|
|
103
|
-
* baselineDir?: string,
|
|
104
|
-
* logger?: { warn?: Function },
|
|
105
|
-
* }} [opts]
|
|
106
|
-
*/
|
|
107
|
-
export function createCrapDriftDetector(opts = {}) {
|
|
108
|
-
const fs = opts.fs ?? nodeFs;
|
|
109
|
-
const cwd = opts.cwd ?? process.cwd();
|
|
110
|
-
const files = Array.isArray(opts.files) ? [...opts.files] : [];
|
|
111
|
-
const calculate = opts.calculate ?? calculateCrapForSource;
|
|
112
|
-
const loadCoverage = opts.loadCoverage ?? defaultLoadCoverage;
|
|
113
|
-
const coveragePath = opts.coveragePath ?? null;
|
|
114
|
-
const threshold = Number.isFinite(opts.threshold)
|
|
115
|
-
? opts.threshold
|
|
116
|
-
: DEFAULT_THRESHOLD;
|
|
117
|
-
const ceiling = Number.isFinite(opts.ceiling)
|
|
118
|
-
? opts.ceiling
|
|
119
|
-
: DEFAULT_CEILING;
|
|
120
|
-
const logger = opts.logger ?? null;
|
|
121
|
-
|
|
122
|
-
function methodKey(method, startLine) {
|
|
123
|
-
return `${method}@${startLine}`;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
// Hoisted helpers — exported via `_internal` for unit coverage on each
|
|
127
|
-
// branch. Keeping them outside the closure keeps the orchestration
|
|
128
|
-
// method's complexity low.
|
|
129
|
-
// (see normaliseCoveragePath / coverageKeyMatches at module top.)
|
|
130
|
-
function findCoverageEntry(coverageMap, relPath) {
|
|
131
|
-
if (!coverageMap || typeof coverageMap !== 'object') return null;
|
|
132
|
-
const suffix = normaliseCoveragePath(relPath);
|
|
133
|
-
if (!suffix) return null;
|
|
134
|
-
for (const key of Object.keys(coverageMap)) {
|
|
135
|
-
if (coverageKeyMatches(key, suffix)) {
|
|
136
|
-
return coverageMap[key] ?? null;
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
return null;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
function scoreFile(relPath, coverageMap) {
|
|
143
|
-
try {
|
|
144
|
-
const abs = path.join(cwd, relPath);
|
|
145
|
-
const src = fs.readFileSync(abs, 'utf-8');
|
|
146
|
-
const entry = findCoverageEntry(coverageMap, relPath);
|
|
147
|
-
const rows = calculate(src, entry) ?? [];
|
|
148
|
-
const methods = {};
|
|
149
|
-
for (const row of rows) {
|
|
150
|
-
if (!row || typeof row.method !== 'string') continue;
|
|
151
|
-
if (typeof row.startLine !== 'number') continue;
|
|
152
|
-
if (typeof row.crap !== 'number' || !Number.isFinite(row.crap))
|
|
153
|
-
continue;
|
|
154
|
-
methods[methodKey(row.method, row.startLine)] = {
|
|
155
|
-
method: row.method,
|
|
156
|
-
startLine: row.startLine,
|
|
157
|
-
crap: row.crap,
|
|
158
|
-
};
|
|
159
|
-
}
|
|
160
|
-
return methods;
|
|
161
|
-
} catch (err) {
|
|
162
|
-
logger?.warn?.(
|
|
163
|
-
`[crap-drift] scoring failed for ${relPath}: ${err?.message ?? err}`,
|
|
164
|
-
);
|
|
165
|
-
return null;
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
function readCoverageMap() {
|
|
170
|
-
if (!coveragePath) return null;
|
|
171
|
-
try {
|
|
172
|
-
return loadCoverage(coveragePath);
|
|
173
|
-
} catch (err) {
|
|
174
|
-
logger?.warn?.(
|
|
175
|
-
`[crap-drift] coverage load failed (${coveragePath}): ${err?.message ?? err}`,
|
|
176
|
-
);
|
|
177
|
-
return null;
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
return createDriftDetector({
|
|
182
|
-
fs,
|
|
183
|
-
cwd,
|
|
184
|
-
files: opts.files,
|
|
185
|
-
baselineDir: opts.baselineDir,
|
|
186
|
-
baselineFilename: BASELINE_FILENAME,
|
|
187
|
-
metadata: { ceiling, threshold },
|
|
188
|
-
beforeScore: readCoverageMap,
|
|
189
|
-
scoreFile,
|
|
190
|
-
captureScore: (methods) => {
|
|
191
|
-
const persisted = {};
|
|
192
|
-
for (const [key, row] of Object.entries(methods)) {
|
|
193
|
-
persisted[key] = row.crap;
|
|
194
|
-
}
|
|
195
|
-
return persisted;
|
|
196
|
-
},
|
|
197
|
-
async detect({ baseline, scoreFile: score }) {
|
|
198
|
-
const bullets = [];
|
|
199
|
-
// Union of files watched and files present in baseline, so methods that
|
|
200
|
-
// appeared since the snapshot (new files) are still checked, and methods
|
|
201
|
-
// that disappeared from baseline-only files don't get us stuck iterating
|
|
202
|
-
// anything spurious.
|
|
203
|
-
const fileSet = new Set([...files, ...Object.keys(baseline)]);
|
|
204
|
-
for (const relPath of fileSet) {
|
|
205
|
-
const currentMethods = score(relPath);
|
|
206
|
-
if (!currentMethods) continue;
|
|
207
|
-
const fileBaseline = baseline[relPath] ?? {};
|
|
208
|
-
for (const [key, row] of Object.entries(currentMethods)) {
|
|
209
|
-
const prev = fileBaseline[key];
|
|
210
|
-
const crossed =
|
|
211
|
-
row.crap >= ceiling &&
|
|
212
|
-
(prev === undefined || prev === null || prev < ceiling);
|
|
213
|
-
const rose =
|
|
214
|
-
typeof prev === 'number' &&
|
|
215
|
-
Number.isFinite(prev) &&
|
|
216
|
-
row.crap - prev >= threshold;
|
|
217
|
-
if (crossed || rose) {
|
|
218
|
-
bullets.push(
|
|
219
|
-
`🧨 CRAP drift: ${relPath}::${row.method} ${row.crap.toFixed(2)} (ceiling ${ceiling})`,
|
|
220
|
-
);
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
return bullets;
|
|
225
|
-
},
|
|
226
|
-
});
|
|
227
|
-
}
|
package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/maintainability-drift.js
DELETED
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
import nodeFs from 'node:fs';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
|
|
4
|
-
import { calculateForSource } from '../../../maintainability-engine.js';
|
|
5
|
-
import { formatNumber } from './_bullet-format.js';
|
|
6
|
-
import {
|
|
7
|
-
createDriftDetector,
|
|
8
|
-
walkComponentRegressions,
|
|
9
|
-
} from './component-drift.js';
|
|
10
|
-
|
|
11
|
-
const DEFAULT_THRESHOLD = 2.0;
|
|
12
|
-
// Distinct from the canonical ratchet baseline at `baselines/maintainability.json`
|
|
13
|
-
// (Epic #730 Story 5.5) — this file is a per-wave drift SNAPSHOT, not the
|
|
14
|
-
// committed score baseline. Filename intentionally differs so a repo-wide
|
|
15
|
-
// grep for the canonical baseline no longer hits the snapshot.
|
|
16
|
-
const BASELINE_FILENAME = 'wave-mi-snapshot.json';
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Detect per-component maintainability regressions from a baseline rollup
|
|
20
|
-
* against the gate's configured floors. Pure — the caller loads the
|
|
21
|
-
* baseline via `lib/baselines/reader.js#load('maintainability')` and passes
|
|
22
|
-
* the resulting `{ rollup }` plus the gate config block.
|
|
23
|
-
*
|
|
24
|
-
* Bullet shape (Task #1919, Epic #1786):
|
|
25
|
-
*
|
|
26
|
-
* 📉 maintainability: <component> <axis> <value> < floor <floor>
|
|
27
|
-
*
|
|
28
|
-
* Maintainability is "higher is better" — every axis breach reports when
|
|
29
|
-
* `value < floor`. Component-scoped breaches do NOT trigger a `*` bullet
|
|
30
|
-
* unless `*` itself breaches. The walk itself is the shared
|
|
31
|
-
* `component-drift.js` helper (Story #3984).
|
|
32
|
-
*
|
|
33
|
-
* @param {{
|
|
34
|
-
* rollup?: Record<string, Record<string, number>>,
|
|
35
|
-
* gateConfig?: { floors?: Record<string, Record<string, number>> } & object,
|
|
36
|
-
* }} params
|
|
37
|
-
* @returns {string[]}
|
|
38
|
-
*/
|
|
39
|
-
export function detectComponentRegressions(params = {}) {
|
|
40
|
-
return walkComponentRegressions(params, {
|
|
41
|
-
isBreach: (value, target) => value < target,
|
|
42
|
-
formatBullet: (name, axis, value, target) =>
|
|
43
|
-
`📉 maintainability: ${name} ${axis} ${formatNumber(value)} < floor ${formatNumber(target)}`,
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Detects per-file maintainability drop versus a wave-start baseline.
|
|
49
|
-
*
|
|
50
|
-
* Usage:
|
|
51
|
-
* const detector = createMaintainabilityDriftDetector({ cwd, files });
|
|
52
|
-
* detector.captureBaseline(); // call once at wave-start
|
|
53
|
-
* await detector.detect(rows); // call each progress fire
|
|
54
|
-
*
|
|
55
|
-
* A baseline is a map of file -> score, persisted to
|
|
56
|
-
* `<cwd>/<baselineDir>/wave-mi-snapshot.json` so that a resumed epic
|
|
57
|
-
* run can re-read the snapshot from the previous wave rather than lose the
|
|
58
|
-
* anchor. Any file whose score has dropped by >= `threshold` since baseline
|
|
59
|
-
* is surfaced as a bullet:
|
|
60
|
-
*
|
|
61
|
-
* 📉 Maintainability drift: <file> -<n.nn> vs wave-start baseline
|
|
62
|
-
*
|
|
63
|
-
* Errors while reading/scoring individual files are swallowed — a single
|
|
64
|
-
* bad file must not take the progress reporter down.
|
|
65
|
-
*
|
|
66
|
-
* @param {{
|
|
67
|
-
* cwd?: string,
|
|
68
|
-
* files?: string[], // files to watch; repo-relative paths
|
|
69
|
-
* fs?: { readFileSync: Function, writeFileSync?: Function, mkdirSync?: Function, existsSync?: Function },
|
|
70
|
-
* calculate?: (source: string) => number,
|
|
71
|
-
* threshold?: number, // drop (baseline - current) that trips a bullet
|
|
72
|
-
* baselineDir?: string, // directory (under cwd) to persist snapshot
|
|
73
|
-
* }} [opts]
|
|
74
|
-
*/
|
|
75
|
-
export function createMaintainabilityDriftDetector(opts = {}) {
|
|
76
|
-
const fs = opts.fs ?? nodeFs;
|
|
77
|
-
const cwd = opts.cwd ?? process.cwd();
|
|
78
|
-
const calculate = opts.calculate ?? calculateForSource;
|
|
79
|
-
const threshold = Number.isFinite(opts.threshold)
|
|
80
|
-
? opts.threshold
|
|
81
|
-
: DEFAULT_THRESHOLD;
|
|
82
|
-
|
|
83
|
-
function scoreFile(relPath) {
|
|
84
|
-
try {
|
|
85
|
-
const abs = path.join(cwd, relPath);
|
|
86
|
-
const src = fs.readFileSync(abs, 'utf-8');
|
|
87
|
-
const score = calculate(src);
|
|
88
|
-
return Number.isFinite(score) ? score : null;
|
|
89
|
-
} catch {
|
|
90
|
-
return null;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
return createDriftDetector({
|
|
95
|
-
fs,
|
|
96
|
-
cwd,
|
|
97
|
-
files: opts.files,
|
|
98
|
-
baselineDir: opts.baselineDir,
|
|
99
|
-
baselineFilename: BASELINE_FILENAME,
|
|
100
|
-
scoreFile,
|
|
101
|
-
captureScore: (score) => score,
|
|
102
|
-
async detect({ baseline, scoreFile: score }) {
|
|
103
|
-
const bullets = [];
|
|
104
|
-
for (const [relPath, baseScore] of Object.entries(baseline)) {
|
|
105
|
-
const current = score(relPath);
|
|
106
|
-
if (current == null) continue;
|
|
107
|
-
const drop = baseScore - current;
|
|
108
|
-
if (drop >= threshold) {
|
|
109
|
-
bullets.push(
|
|
110
|
-
`📉 Maintainability drift: ${relPath} -${drop.toFixed(2)} vs wave-start baseline`,
|
|
111
|
-
);
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
return bullets;
|
|
115
|
-
},
|
|
116
|
-
});
|
|
117
|
-
}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import nodeFs from 'node:fs';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Detects "worktree residue" — stories that the ticket graph reports as done,
|
|
6
|
-
* but whose `.worktrees/story-<id>/` directory is still on disk. This usually
|
|
7
|
-
* means story-close failed to reap the worktree (see the Windows
|
|
8
|
-
* partial-reap failure mode in friction memory), and a future run of the
|
|
9
|
-
* same story id would collide with the stale directory.
|
|
10
|
-
*
|
|
11
|
-
* The detector is pure (aside from fs reads) and accepts an fs adapter so the
|
|
12
|
-
* unit test can drive present/absent cases without touching disk.
|
|
13
|
-
*
|
|
14
|
-
* @param {{
|
|
15
|
-
* fs?: { existsSync: (p: string) => boolean },
|
|
16
|
-
* cwd?: string,
|
|
17
|
-
* }} [opts]
|
|
18
|
-
* @returns {(rows: Array<{id:number|string, state:string}>) => Promise<string[]>}
|
|
19
|
-
*/
|
|
20
|
-
export function createStalledWorktreeDetector(opts = {}) {
|
|
21
|
-
const fs = opts.fs ?? nodeFs;
|
|
22
|
-
const cwd = opts.cwd ?? process.cwd();
|
|
23
|
-
return async function detect(rows = []) {
|
|
24
|
-
const bullets = [];
|
|
25
|
-
for (const row of rows) {
|
|
26
|
-
if (row?.state !== 'done') continue;
|
|
27
|
-
const relPath = `.worktrees/story-${row.id}`;
|
|
28
|
-
const absPath = path.join(cwd, relPath);
|
|
29
|
-
if (fs.existsSync(absPath)) {
|
|
30
|
-
bullets.push(
|
|
31
|
-
`⚠️ Worktree residue: #${row.id} marked done but .worktrees/story-${row.id}/ still present`,
|
|
32
|
-
);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
return bullets;
|
|
36
|
-
};
|
|
37
|
-
}
|
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* StoryLauncher — produces the per-wave dispatch plan and (optionally)
|
|
3
|
-
* delegates execution to an injected `dispatch` adapter.
|
|
4
|
-
*
|
|
5
|
-
* After Story #908, in-session Agent-tool fan-out replaces the subprocess
|
|
6
|
-
* spawn pipeline. The launcher's primary responsibility is `planWave(stories)`:
|
|
7
|
-
* given a wave's Story tickets it returns a stable list of
|
|
8
|
-
* `{ storyId, worktree }` entries. The `/deliver` skill consumes that
|
|
9
|
-
* list (one wave at a time) to format one assistant turn containing N
|
|
10
|
-
* parallel `Agent` tool calls (subagent_type `general-purpose`), each of
|
|
11
|
-
* which drives `/deliver <storyId>` for one Story.
|
|
12
|
-
*
|
|
13
|
-
* `launchWave(stories)` is a convenience for callers that already hold a
|
|
14
|
-
* concrete dispatch adapter (tests, future programmatic harnesses). It calls
|
|
15
|
-
* `planWave` and forwards the plan to `dispatch({ plan, concurrencyCap, signal })`,
|
|
16
|
-
* returning the adapter's result list. The CLI does not provide a default
|
|
17
|
-
* dispatch adapter — invoking the engine without one is an explicit error.
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
const DEFAULT_TIMEOUT_MS = 6 * 60 * 60 * 1000;
|
|
21
|
-
|
|
22
|
-
export class StoryLauncher {
|
|
23
|
-
/**
|
|
24
|
-
* @param {{
|
|
25
|
-
* ctx?: { dispatch?: Function, concurrencyCap?: number, worktreeResolver?: (storyId: number) => string, logger?: object },
|
|
26
|
-
* concurrencyCap?: number,
|
|
27
|
-
* dispatch?: (args: { plan: Array<{ storyId: number, worktree?: string }>, concurrencyCap: number, signal?: AbortSignal }) => Promise<Array<{ storyId: number, status: string, detail?: string }>>,
|
|
28
|
-
* worktreeResolver?: (storyId: number) => string,
|
|
29
|
-
* timeoutMs?: number,
|
|
30
|
-
* logger?: { info: Function, warn: Function, error: Function }
|
|
31
|
-
* }} opts
|
|
32
|
-
*/
|
|
33
|
-
constructor(opts = {}) {
|
|
34
|
-
const ctx = opts?.ctx;
|
|
35
|
-
const dispatch = opts?.dispatch ?? ctx?.dispatch ?? null;
|
|
36
|
-
const concurrencyCap = opts?.concurrencyCap ?? ctx?.concurrencyCap;
|
|
37
|
-
if (!Number.isInteger(concurrencyCap) || concurrencyCap < 1) {
|
|
38
|
-
throw new RangeError('concurrencyCap must be a positive integer');
|
|
39
|
-
}
|
|
40
|
-
this.concurrencyCap = concurrencyCap;
|
|
41
|
-
this.dispatch = dispatch;
|
|
42
|
-
this.worktreeResolver = opts?.worktreeResolver ?? ctx?.worktreeResolver;
|
|
43
|
-
this.timeoutMs = opts?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
44
|
-
this.logger = opts?.logger ?? ctx?.logger ?? console;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Produce the dispatch plan for a wave. Pure: no side effects, no IO. The
|
|
49
|
-
* caller (the `/deliver` skill's wave loop, or `launchWave` below)
|
|
50
|
-
* decides what to do with the plan.
|
|
51
|
-
*
|
|
52
|
-
* @param {Array<number|{id?:number,storyId?:number,number?:number}>} stories
|
|
53
|
-
* @returns {Array<{ storyId: number, worktree?: string }>}
|
|
54
|
-
*/
|
|
55
|
-
planWave(stories) {
|
|
56
|
-
return (stories ?? []).map((s) => {
|
|
57
|
-
const storyId =
|
|
58
|
-
typeof s === 'object' && s !== null
|
|
59
|
-
? (s.id ?? s.storyId ?? s.number)
|
|
60
|
-
: s;
|
|
61
|
-
const id = Number(storyId);
|
|
62
|
-
return {
|
|
63
|
-
storyId: id,
|
|
64
|
-
worktree: this.worktreeResolver?.(id),
|
|
65
|
-
};
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* Plan + dispatch the wave through the injected adapter. Returns one result
|
|
71
|
-
* entry per input Story preserving input order. Throws when no dispatch
|
|
72
|
-
* adapter was injected — the engine is no longer callable without one.
|
|
73
|
-
*
|
|
74
|
-
* @param {object[]} stories
|
|
75
|
-
* @param {AbortSignal} [signal]
|
|
76
|
-
* @returns {Promise<Array<{ storyId: number, status: string, detail?: string }>>}
|
|
77
|
-
*/
|
|
78
|
-
async launchWave(stories, signal) {
|
|
79
|
-
if (typeof this.dispatch !== 'function') {
|
|
80
|
-
throw new TypeError(
|
|
81
|
-
'StoryLauncher.launchWave requires a dispatch adapter (in-session Agent-tool fan-out is the responsibility of the /deliver skill).',
|
|
82
|
-
);
|
|
83
|
-
}
|
|
84
|
-
const plan = this.planWave(stories);
|
|
85
|
-
if (plan.length === 0) return [];
|
|
86
|
-
|
|
87
|
-
const controller = new AbortController();
|
|
88
|
-
const timer = setTimeout(
|
|
89
|
-
() =>
|
|
90
|
-
controller.abort(new Error(`wave timed out after ${this.timeoutMs}ms`)),
|
|
91
|
-
this.timeoutMs,
|
|
92
|
-
);
|
|
93
|
-
const onParentAbort = () => controller.abort(signal?.reason);
|
|
94
|
-
signal?.addEventListener?.('abort', onParentAbort, { once: true });
|
|
95
|
-
try {
|
|
96
|
-
const results = await this.dispatch({
|
|
97
|
-
plan,
|
|
98
|
-
concurrencyCap: this.concurrencyCap,
|
|
99
|
-
signal: controller.signal,
|
|
100
|
-
});
|
|
101
|
-
return this.#alignResults(plan, results);
|
|
102
|
-
} catch (err) {
|
|
103
|
-
return plan.map((p) => ({
|
|
104
|
-
storyId: p.storyId,
|
|
105
|
-
status: 'failed',
|
|
106
|
-
detail: err?.message ?? String(err),
|
|
107
|
-
}));
|
|
108
|
-
} finally {
|
|
109
|
-
clearTimeout(timer);
|
|
110
|
-
signal?.removeEventListener?.('abort', onParentAbort);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
#alignResults(plan, results) {
|
|
115
|
-
const list = Array.isArray(results) ? results : [];
|
|
116
|
-
const byId = new Map(list.map((r) => [Number(r.storyId), r]));
|
|
117
|
-
return plan.map((p) => {
|
|
118
|
-
const r = byId.get(p.storyId);
|
|
119
|
-
if (r) return { storyId: p.storyId, ...r };
|
|
120
|
-
return {
|
|
121
|
-
storyId: p.storyId,
|
|
122
|
-
status: 'failed',
|
|
123
|
-
detail: 'dispatch returned no result for this story',
|
|
124
|
-
};
|
|
125
|
-
});
|
|
126
|
-
}
|
|
127
|
-
}
|