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,571 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* phases/compose-body.js — retro Phase 2: compose the retro markdown body.
|
|
3
|
-
*
|
|
4
|
-
* Pure: given an aggregated counts/signals input, produce the retro
|
|
5
|
-
* markdown body plus the compact/scorecard envelope. Selects the compact
|
|
6
|
-
* (clean-manifest) or full retro shape via `isCleanManifest`.
|
|
7
|
-
*
|
|
8
|
-
* `normalizeInterventionCount` is exported so the post-and-mirror phase
|
|
9
|
-
* can reuse the same clamping logic when forwarding the runtime's
|
|
10
|
-
* `manualInterventions` count into the body composer.
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
import { isCleanManifest } from '../../retro-heuristics.js';
|
|
14
|
-
import { classifyPerfSignals } from '../../retro-perf-heuristics.js';
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Pure: clamp a candidate count to a non-negative integer. Used to
|
|
18
|
-
* normalize the `manualInterventions` count plumbed in from the
|
|
19
|
-
* epic-run-state-store snapshot before it lands in the scorecard.
|
|
20
|
-
* Non-finite, negative, or non-numeric values collapse to 0.
|
|
21
|
-
*/
|
|
22
|
-
export function normalizeInterventionCount(value) {
|
|
23
|
-
if (typeof value !== 'number' || !Number.isFinite(value) || value < 0) {
|
|
24
|
-
return 0;
|
|
25
|
-
}
|
|
26
|
-
return Math.trunc(value);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Pure: does `routedProposals` carry at least one actionable item (a
|
|
31
|
-
* framework- or consumer-routed `gh issue create` proposal)? Story #4417 —
|
|
32
|
-
* the compact retro shape (and therefore the `automerge-verdict`
|
|
33
|
-
* `cleanSprint: true` flag it drives) MUST be suppressed whenever an
|
|
34
|
-
* actionable proposal exists, regardless of `forceFull` or the
|
|
35
|
-
* comment-derived counts: the clean-sprint verdict is an auto-merge input
|
|
36
|
-
* and must never read "clean" while actionable friction sits in the routed
|
|
37
|
-
* proposals. Discarded (single-occurrence) items do NOT count — they are
|
|
38
|
-
* the retro's explicit "nothing to file" bucket.
|
|
39
|
-
*
|
|
40
|
-
* @param {{ framework?: object[], consumer?: object[] } | null | undefined} routedProposals
|
|
41
|
-
* @returns {boolean}
|
|
42
|
-
*/
|
|
43
|
-
export function hasActionableProposals(routedProposals) {
|
|
44
|
-
if (
|
|
45
|
-
!routedProposals ||
|
|
46
|
-
typeof routedProposals !== 'object' ||
|
|
47
|
-
Array.isArray(routedProposals)
|
|
48
|
-
) {
|
|
49
|
-
return false;
|
|
50
|
-
}
|
|
51
|
-
const framework = Array.isArray(routedProposals.framework)
|
|
52
|
-
? routedProposals.framework
|
|
53
|
-
: [];
|
|
54
|
-
const consumer = Array.isArray(routedProposals.consumer)
|
|
55
|
-
? routedProposals.consumer
|
|
56
|
-
: [];
|
|
57
|
-
return framework.length > 0 || consumer.length > 0;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Pure: derive the recurring-defect-class signal from the routed-proposal
|
|
62
|
-
* sections (Story #4135 / Epic #4131, F11).
|
|
63
|
-
*
|
|
64
|
-
* The routed-proposals composer (`retro-proposals.js`) already split the
|
|
65
|
-
* Epic's source-tagged friction into `framework` / `consumer` actionable
|
|
66
|
-
* items — a category lands there only when it recurred ≥2 times across the
|
|
67
|
-
* Epic OR was force-flagged by an unresolved `agent::blocked` event. Those
|
|
68
|
-
* are exactly the **recurring classes** of review/deliver-caught issues F11
|
|
69
|
-
* tracks, so we lift them verbatim rather than re-deriving a parallel
|
|
70
|
-
* threshold. Each entry carries the `friction::<category>` label the
|
|
71
|
-
* composer stamps onto its `gh issue create` command — that label is the
|
|
72
|
-
* join key the `/plan` Phase 0 prior-feedback fetcher reads back to surface
|
|
73
|
-
* recurring classes to the planner.
|
|
74
|
-
*
|
|
75
|
-
* Determinism: the two actionable arrays are already sorted by `category`
|
|
76
|
-
* ASC by the composer; we concatenate framework-then-consumer and re-sort by
|
|
77
|
-
* `category` so the merged signal is stable regardless of which source
|
|
78
|
-
* contributed a class.
|
|
79
|
-
*
|
|
80
|
-
* No-op-safe: a null / non-object / shapeless `routedProposals` (or one with
|
|
81
|
-
* empty actionable arrays) yields `[]` — the common clean-sprint case.
|
|
82
|
-
*
|
|
83
|
-
* @param {{ framework?: object[], consumer?: object[] } | null | undefined} routedProposals
|
|
84
|
-
* @returns {Array<{ category: string, occurrences: number, source: 'framework'|'consumer', label: string }>}
|
|
85
|
-
*/
|
|
86
|
-
export function deriveDefectClasses(routedProposals) {
|
|
87
|
-
if (
|
|
88
|
-
!routedProposals ||
|
|
89
|
-
typeof routedProposals !== 'object' ||
|
|
90
|
-
Array.isArray(routedProposals)
|
|
91
|
-
) {
|
|
92
|
-
return [];
|
|
93
|
-
}
|
|
94
|
-
const framework = Array.isArray(routedProposals.framework)
|
|
95
|
-
? routedProposals.framework
|
|
96
|
-
: [];
|
|
97
|
-
const consumer = Array.isArray(routedProposals.consumer)
|
|
98
|
-
? routedProposals.consumer
|
|
99
|
-
: [];
|
|
100
|
-
|
|
101
|
-
const out = [];
|
|
102
|
-
for (const item of [...framework, ...consumer]) {
|
|
103
|
-
if (!item || typeof item !== 'object') continue;
|
|
104
|
-
const category =
|
|
105
|
-
typeof item.category === 'string' ? item.category.trim() : '';
|
|
106
|
-
if (category.length === 0) continue;
|
|
107
|
-
const occurrences =
|
|
108
|
-
typeof item.occurrences === 'number' && Number.isFinite(item.occurrences)
|
|
109
|
-
? item.occurrences
|
|
110
|
-
: 0;
|
|
111
|
-
const source = item.source === 'framework' ? 'framework' : 'consumer';
|
|
112
|
-
out.push({
|
|
113
|
-
category,
|
|
114
|
-
occurrences,
|
|
115
|
-
source,
|
|
116
|
-
label: `friction::${category}`,
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
out.sort((a, b) => a.category.localeCompare(b.category));
|
|
120
|
-
return out;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* Pure: compose the retro markdown body. Exported for tests so they can
|
|
125
|
-
* verify the body shape without round-tripping through a stub provider.
|
|
126
|
-
*
|
|
127
|
-
* Story #2289 adds `counts.interventions` — sourced from the
|
|
128
|
-
* `manualInterventions` array on the `epic-run-state` snapshot (the
|
|
129
|
-
* same list that disqualifies an Epic from auto-merge). Non-zero
|
|
130
|
-
* interventions route to the full retro shape via `isCleanManifest`.
|
|
131
|
-
*
|
|
132
|
-
* @param {{
|
|
133
|
-
* epicId: number,
|
|
134
|
-
* epicTitle?: string,
|
|
135
|
-
* counts: { friction: number, parked: number, recuts: number, hitl: number, interventions?: number },
|
|
136
|
-
* storyPerfSummaries?: object[],
|
|
137
|
-
* epicPerfReport?: object|null,
|
|
138
|
-
* parkedFollowOns?: { recuts: object[], parked: object[] },
|
|
139
|
-
* timestamp?: string,
|
|
140
|
-
* forceFull?: boolean,
|
|
141
|
-
* }} input
|
|
142
|
-
* @returns {{ body: string, compact: boolean, scorecard: object }}
|
|
143
|
-
*/
|
|
144
|
-
export function composeRetroBody(input) {
|
|
145
|
-
const {
|
|
146
|
-
epicId,
|
|
147
|
-
epicTitle = `Epic ${epicId}`,
|
|
148
|
-
counts,
|
|
149
|
-
storyPerfSummaries = [],
|
|
150
|
-
epicPerfReport = null,
|
|
151
|
-
parkedFollowOns = { recuts: [], parked: [] },
|
|
152
|
-
routedProposals = null,
|
|
153
|
-
timestamp = new Date().toISOString(),
|
|
154
|
-
forceFull = false,
|
|
155
|
-
perfThresholds = null,
|
|
156
|
-
} = input;
|
|
157
|
-
|
|
158
|
-
const interventions = normalizeInterventionCount(counts?.interventions);
|
|
159
|
-
// Story #4417 — the compact shape requires BOTH a clean manifest AND zero
|
|
160
|
-
// actionable routed proposals. The routed proposals and the counts are
|
|
161
|
-
// derived from the same unified signals scan (gather-signals.js), so this
|
|
162
|
-
// guard closes the window where the comment-derived counts read "clean"
|
|
163
|
-
// while the ndjson-derived routed proposals hold an actionable item.
|
|
164
|
-
const compact =
|
|
165
|
-
!forceFull &&
|
|
166
|
-
isCleanManifest({ ...counts, interventions }) &&
|
|
167
|
-
!hasActionableProposals(routedProposals);
|
|
168
|
-
const heading = `## 🪞 Sprint Retrospective — Epic #${epicId}: ${epicTitle}`;
|
|
169
|
-
const generatedLine = `_Generated ${timestamp}_`;
|
|
170
|
-
const scorecardRows = [
|
|
171
|
-
`| agent::blocked Events Raised | ${counts.hitl} |`,
|
|
172
|
-
`| Manual Interventions | ${interventions} |`,
|
|
173
|
-
`| Friction Events | ${counts.friction} |`,
|
|
174
|
-
];
|
|
175
|
-
const scorecard = {
|
|
176
|
-
hitl: counts.hitl,
|
|
177
|
-
friction: counts.friction,
|
|
178
|
-
parked: counts.parked,
|
|
179
|
-
recuts: counts.recuts,
|
|
180
|
-
interventions,
|
|
181
|
-
};
|
|
182
|
-
const completeMarker = `<!-- retro-complete: ${timestamp} -->`;
|
|
183
|
-
// Machine-readable auto-merge verdict trailer (Story #3901). The
|
|
184
|
-
// Phase 8.5 `AutomergePredicate` reads `cleanSprint` from THIS trailer
|
|
185
|
-
// — a parsed JSON boolean — rather than string-matching the human-facing
|
|
186
|
-
// "🟢 Clean sprint" prose, which was a brittle emoji `.includes()` that
|
|
187
|
-
// false-positived on any retro body that happened to quote the marker
|
|
188
|
-
// and false-negatived on any compact-body copy edit. `cleanSprint`
|
|
189
|
-
// tracks the compact shape exactly (a full/forced retro is never a
|
|
190
|
-
// clean sprint); the scorecard is mirrored so the predicate can surface
|
|
191
|
-
// the disqualifying counts without re-parsing the markdown table.
|
|
192
|
-
const automergeTrailer = `<!-- automerge-verdict: ${JSON.stringify({
|
|
193
|
-
cleanSprint: compact,
|
|
194
|
-
scorecard,
|
|
195
|
-
})} -->`;
|
|
196
|
-
|
|
197
|
-
if (compact) {
|
|
198
|
-
const body = [
|
|
199
|
-
heading,
|
|
200
|
-
'',
|
|
201
|
-
generatedLine,
|
|
202
|
-
'',
|
|
203
|
-
'🟢 Clean sprint — zero friction, zero parked follow-ons, zero recuts, zero agent::blocked events, zero manual interventions.',
|
|
204
|
-
'',
|
|
205
|
-
'### Sprint Scorecard',
|
|
206
|
-
'',
|
|
207
|
-
'| Metric | Value |',
|
|
208
|
-
'| ---------------------------- | ----- |',
|
|
209
|
-
...scorecardRows,
|
|
210
|
-
'',
|
|
211
|
-
'### Session Observations',
|
|
212
|
-
'',
|
|
213
|
-
'_Nothing notable beyond the scorecard._',
|
|
214
|
-
'',
|
|
215
|
-
'### Action Items for Next Epic',
|
|
216
|
-
'',
|
|
217
|
-
'_None._',
|
|
218
|
-
'',
|
|
219
|
-
completeMarker,
|
|
220
|
-
automergeTrailer,
|
|
221
|
-
].join('\n');
|
|
222
|
-
return { body, compact: true, scorecard };
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
// Full path — six sections.
|
|
226
|
-
const hotspotLines =
|
|
227
|
-
epicPerfReport &&
|
|
228
|
-
Array.isArray(epicPerfReport.topHotspots) &&
|
|
229
|
-
epicPerfReport.topHotspots.length > 0
|
|
230
|
-
? epicPerfReport.topHotspots.map(
|
|
231
|
-
(h) =>
|
|
232
|
-
`- \`${h.phase}\` — ${h.occurrences} occurrence(s), avg ratio ${
|
|
233
|
-
typeof h.avgRatio === 'number' ? h.avgRatio.toFixed(2) : 'n/a'
|
|
234
|
-
}`,
|
|
235
|
-
)
|
|
236
|
-
: ['_No epic-perf-report available._'];
|
|
237
|
-
|
|
238
|
-
const parkedLines =
|
|
239
|
-
parkedFollowOns.parked.length > 0
|
|
240
|
-
? parkedFollowOns.parked.map(
|
|
241
|
-
(p) =>
|
|
242
|
-
`- Adopt or close parked follow-on #${p.storyId ?? p.id ?? '?'}`,
|
|
243
|
-
)
|
|
244
|
-
: [];
|
|
245
|
-
const recutLines =
|
|
246
|
-
parkedFollowOns.recuts.length > 0
|
|
247
|
-
? parkedFollowOns.recuts.map(
|
|
248
|
-
(r) => `- Recut #${r.storyId ?? r.id ?? '?'} attributed to manifest`,
|
|
249
|
-
)
|
|
250
|
-
: [];
|
|
251
|
-
const legacyActionItems = [...parkedLines, ...recutLines];
|
|
252
|
-
const legacyActionItemsBody =
|
|
253
|
-
legacyActionItems.length > 0 ? legacyActionItems.join('\n') : '_None._';
|
|
254
|
-
|
|
255
|
-
// Story #2558 — routed-proposals mode. When routedProposals is supplied
|
|
256
|
-
// AND any of the three buckets is non-empty, render the three explicit
|
|
257
|
-
// sections in deterministic order ABOVE the retro-complete marker:
|
|
258
|
-
// 1. Proposed issues — consumer repo
|
|
259
|
-
// 2. Proposed issues — framework repo
|
|
260
|
-
// 3. One-off / discarded
|
|
261
|
-
// Otherwise the legacy "Action Items for Next Epic" section renders.
|
|
262
|
-
const routedSectionsBlock = renderRoutedSections(routedProposals);
|
|
263
|
-
|
|
264
|
-
const actionSection =
|
|
265
|
-
routedSectionsBlock === null
|
|
266
|
-
? ['### Action Items for Next Epic', '', legacyActionItemsBody]
|
|
267
|
-
: routedSectionsBlock;
|
|
268
|
-
|
|
269
|
-
// Story #3042 — Performance Signals + Recommended Follow-Ons. Both
|
|
270
|
-
// sections are emitted only when (1) the persisted epic-perf-report is
|
|
271
|
-
// present AND (2) `classifyPerfSignals` returns at least one signal.
|
|
272
|
-
// Otherwise the entire pair is suppressed so the retro stays compact.
|
|
273
|
-
const perfReportForHeuristics = epicPerfReport
|
|
274
|
-
? { ...epicPerfReport, storyPerfSummaries }
|
|
275
|
-
: null;
|
|
276
|
-
const perfSignals = perfReportForHeuristics
|
|
277
|
-
? classifyPerfSignals(perfReportForHeuristics, perfThresholds)
|
|
278
|
-
: [];
|
|
279
|
-
const perfSignalsSection = renderPerfSignalsSection(perfSignals);
|
|
280
|
-
const followOnsSection = renderFollowOnsSection(perfSignals);
|
|
281
|
-
|
|
282
|
-
const body = [
|
|
283
|
-
heading,
|
|
284
|
-
'',
|
|
285
|
-
generatedLine,
|
|
286
|
-
'',
|
|
287
|
-
'### Sprint Scorecard',
|
|
288
|
-
'',
|
|
289
|
-
'| Metric | Value |',
|
|
290
|
-
'| ---------------------------- | ----- |',
|
|
291
|
-
...scorecardRows,
|
|
292
|
-
'',
|
|
293
|
-
'### What Went Well',
|
|
294
|
-
'',
|
|
295
|
-
'_(populate from execution telemetry — extracted retro module emits a placeholder; deeper analysis is the operator follow-up.)_',
|
|
296
|
-
'',
|
|
297
|
-
'### What Could Be Improved',
|
|
298
|
-
'',
|
|
299
|
-
'#### Top hotspots',
|
|
300
|
-
'',
|
|
301
|
-
...hotspotLines,
|
|
302
|
-
'',
|
|
303
|
-
'### Architectural Debt',
|
|
304
|
-
'',
|
|
305
|
-
'_(no automated detection in v5.40.0 — operator review required.)_',
|
|
306
|
-
'',
|
|
307
|
-
'### Protocol Optimization Recommendations (Self-Healing)',
|
|
308
|
-
'',
|
|
309
|
-
'_(operator follow-up.)_',
|
|
310
|
-
'',
|
|
311
|
-
...actionSection,
|
|
312
|
-
'',
|
|
313
|
-
...perfSignalsSection,
|
|
314
|
-
...followOnsSection,
|
|
315
|
-
completeMarker,
|
|
316
|
-
automergeTrailer,
|
|
317
|
-
].join('\n');
|
|
318
|
-
return { body, compact: false, scorecard };
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
/**
|
|
322
|
-
* Pure: render the `## Performance Signals` section. Returns `[]` (so the
|
|
323
|
-
* caller can spread it conditionally) when no signal trips. The renderer
|
|
324
|
-
* emits one bullet per signal, naming the kind, the offending wave(s),
|
|
325
|
-
* the observed value, and the threshold that produced the signal.
|
|
326
|
-
*
|
|
327
|
-
* @param {Array<object>} signals
|
|
328
|
-
* @returns {string[]}
|
|
329
|
-
*/
|
|
330
|
-
function renderPerfSignalsSection(signals) {
|
|
331
|
-
if (!Array.isArray(signals) || signals.length === 0) return [];
|
|
332
|
-
const lines = ['## Performance Signals', ''];
|
|
333
|
-
for (const s of signals) {
|
|
334
|
-
lines.push(`- ${describeSignal(s)}`);
|
|
335
|
-
}
|
|
336
|
-
lines.push('');
|
|
337
|
-
return lines;
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
/**
|
|
341
|
-
* Pure: render the `## Recommended Follow-Ons` section. One stanza per
|
|
342
|
-
* signal, each carrying a Conventional-Commits-shaped title and a body
|
|
343
|
-
* including the suggested `meta::framework-gap` label.
|
|
344
|
-
*
|
|
345
|
-
* Each stanza is a `gh issue create` command operators can paste directly:
|
|
346
|
-
* the title is in Conventional-Commits form, and the body names the
|
|
347
|
-
* trigger metric so the planner has the context for triage.
|
|
348
|
-
*
|
|
349
|
-
* @param {Array<object>} signals
|
|
350
|
-
* @returns {string[]}
|
|
351
|
-
*/
|
|
352
|
-
function renderFollowOnsSection(signals) {
|
|
353
|
-
if (!Array.isArray(signals) || signals.length === 0) return [];
|
|
354
|
-
const lines = ['## Recommended Follow-Ons', ''];
|
|
355
|
-
for (const s of signals) {
|
|
356
|
-
const title = followOnTitle(s);
|
|
357
|
-
const body = followOnBody(s);
|
|
358
|
-
lines.push(`- **${title}**`);
|
|
359
|
-
lines.push('');
|
|
360
|
-
lines.push('```sh');
|
|
361
|
-
lines.push(
|
|
362
|
-
`gh issue create --title ${shellEscape(title)} --label meta::framework-gap --body ${shellEscape(body)}`,
|
|
363
|
-
);
|
|
364
|
-
lines.push('```');
|
|
365
|
-
lines.push('');
|
|
366
|
-
}
|
|
367
|
-
return lines;
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
/**
|
|
371
|
-
* Human-readable one-liner for a perf signal — used as the bullet text
|
|
372
|
-
* under `## Performance Signals`. Pure; signal kinds it doesn't know
|
|
373
|
-
* collapse to a generic shape so the renderer never produces empty
|
|
374
|
-
* strings for forward-compatible signal kinds.
|
|
375
|
-
*
|
|
376
|
-
* @param {object} s
|
|
377
|
-
* @returns {string}
|
|
378
|
-
*/
|
|
379
|
-
function describeSignal(s) {
|
|
380
|
-
if (!s || typeof s !== 'object') return 'unknown perf signal';
|
|
381
|
-
if (s.kind === 'low-utilisation') {
|
|
382
|
-
const pct = formatPercent(s.utilisation);
|
|
383
|
-
const thr = formatPercent(s.threshold);
|
|
384
|
-
return `low-utilisation: wave ${s.waveIndex} ran at ${pct} (threshold ${thr})`;
|
|
385
|
-
}
|
|
386
|
-
if (s.kind === 'high-bootstrap-share') {
|
|
387
|
-
const pct = formatPercent(s.share);
|
|
388
|
-
const thr = formatPercent(s.threshold);
|
|
389
|
-
return `high-bootstrap-share: story-init consumed ${pct} of Story execution time (threshold ${thr})`;
|
|
390
|
-
}
|
|
391
|
-
if (s.kind === 'cap-binding-run') {
|
|
392
|
-
return `cap-binding-run: waves ${s.fromWaveIndex}–${s.toWaveIndex} (${s.runLength} consecutive waves) saturated the concurrency cap`;
|
|
393
|
-
}
|
|
394
|
-
return `${s.kind ?? 'unknown'} perf signal`;
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
/**
|
|
398
|
-
* Conventional-Commits-shaped title for a perf signal's follow-on. Pure.
|
|
399
|
-
*
|
|
400
|
-
* @param {object} s
|
|
401
|
-
* @returns {string}
|
|
402
|
-
*/
|
|
403
|
-
function followOnTitle(s) {
|
|
404
|
-
if (!s || typeof s !== 'object')
|
|
405
|
-
return 'perf: investigate unknown perf signal';
|
|
406
|
-
if (s.kind === 'low-utilisation') {
|
|
407
|
-
return `perf(epic-deliver): investigate low utilisation in wave ${s.waveIndex}`;
|
|
408
|
-
}
|
|
409
|
-
if (s.kind === 'high-bootstrap-share') {
|
|
410
|
-
return 'perf(story-init): reduce bootstrap share of Story execution time';
|
|
411
|
-
}
|
|
412
|
-
if (s.kind === 'cap-binding-run') {
|
|
413
|
-
return `perf(deliver-runner): raise concurrency cap to break ${s.runLength}-wave cap-binding run`;
|
|
414
|
-
}
|
|
415
|
-
return `perf: investigate ${s.kind} signal`;
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
/**
|
|
419
|
-
* Body for the paste-ready follow-on stanza. Includes the trigger metric
|
|
420
|
-
* so the planner has the context for triage.
|
|
421
|
-
*
|
|
422
|
-
* @param {object} s
|
|
423
|
-
* @returns {string}
|
|
424
|
-
*/
|
|
425
|
-
function followOnBody(s) {
|
|
426
|
-
const trigger = describeSignal(s);
|
|
427
|
-
return [
|
|
428
|
-
`Auto-suggested by retro-perf-heuristics (Story #3042).`,
|
|
429
|
-
``,
|
|
430
|
-
`Trigger: ${trigger}.`,
|
|
431
|
-
``,
|
|
432
|
-
`Apply the meta::framework-gap label so /plan Phase 0 surfaces it on the next planning pass.`,
|
|
433
|
-
].join('\n');
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
function formatPercent(n) {
|
|
437
|
-
if (typeof n !== 'number' || !Number.isFinite(n)) return 'n/a';
|
|
438
|
-
return `${(n * 100).toFixed(1)}%`;
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
/**
|
|
442
|
-
* Minimal POSIX shell-quote for the `gh issue create` paste-ready
|
|
443
|
-
* command. We single-quote and escape embedded single quotes so the
|
|
444
|
-
* stanza works under bash/zsh/PowerShell-Core. The retro body is
|
|
445
|
-
* read-only documentation, so the quoting is a UX convenience, not a
|
|
446
|
-
* security boundary — but the helper is total nonetheless.
|
|
447
|
-
*
|
|
448
|
-
* @param {string} s
|
|
449
|
-
* @returns {string}
|
|
450
|
-
*/
|
|
451
|
-
function shellEscape(s) {
|
|
452
|
-
const str = String(s ?? '');
|
|
453
|
-
return `'${str.replace(/'/g, `'\\''`)}'`;
|
|
454
|
-
}
|
|
455
|
-
|
|
456
|
-
/**
|
|
457
|
-
* Render the body lines (everything below a section heading and its trailing
|
|
458
|
-
* blank) for a "proposed issues" bucket — the consumer and framework sections
|
|
459
|
-
* share this shape. Empty buckets collapse to a single `_None._`; populated
|
|
460
|
-
* buckets emit, per item, either the **filed issue reference** (when the
|
|
461
|
-
* retro auto-filer already filed it — Story #4418, stamped as
|
|
462
|
-
* `item.filedIssue`) or the paste-ready fenced `gh issue create` stanza (the
|
|
463
|
-
* toggle-OFF / filing-skipped fallback).
|
|
464
|
-
*
|
|
465
|
-
* @param {object[]} items
|
|
466
|
-
* @returns {string[]}
|
|
467
|
-
*/
|
|
468
|
-
function renderIssueBucket(items) {
|
|
469
|
-
if (items.length === 0) return ['_None._'];
|
|
470
|
-
const lines = [];
|
|
471
|
-
for (const item of items) {
|
|
472
|
-
lines.push(`- **${item.title ?? item.category}**`);
|
|
473
|
-
lines.push('');
|
|
474
|
-
if (item.filedIssue && item.filedIssue.url) {
|
|
475
|
-
const ref = Number.isInteger(item.filedIssue.number)
|
|
476
|
-
? `#${item.filedIssue.number}`
|
|
477
|
-
: 'issue';
|
|
478
|
-
lines.push(` Filed: [${ref}](${item.filedIssue.url})`);
|
|
479
|
-
} else {
|
|
480
|
-
lines.push('```sh');
|
|
481
|
-
lines.push(String(item.command ?? ''));
|
|
482
|
-
lines.push('```');
|
|
483
|
-
}
|
|
484
|
-
lines.push('');
|
|
485
|
-
}
|
|
486
|
-
return lines;
|
|
487
|
-
}
|
|
488
|
-
|
|
489
|
-
/**
|
|
490
|
-
* Render the body lines for the "one-off / discarded" bucket — one bullet per
|
|
491
|
-
* discarded class naming its occurrence count and source, or `_None._`.
|
|
492
|
-
*
|
|
493
|
-
* @param {object[]} items
|
|
494
|
-
* @returns {string[]}
|
|
495
|
-
*/
|
|
496
|
-
function renderDiscardedBucket(items) {
|
|
497
|
-
if (items.length === 0) return ['_None._'];
|
|
498
|
-
return items.map(
|
|
499
|
-
(d) =>
|
|
500
|
-
`- \`${d.category}\` (${d.occurrences ?? 1} occurrence, source: ${d.source ?? 'consumer'})`,
|
|
501
|
-
);
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
/**
|
|
505
|
-
* Descriptor table for the three routed-proposal sections, in deterministic
|
|
506
|
-
* emit order (consumer → framework → discarded). Each descriptor pairs a
|
|
507
|
-
* heading, the `routedProposals` field it reads, and a body renderer.
|
|
508
|
-
* {@link renderRoutedSections} walks the table once, so reordering or adding a
|
|
509
|
-
* section is a data edit here rather than another copy-pasted emit block.
|
|
510
|
-
*
|
|
511
|
-
* The former "Proposed memory updates" section was deleted in the Epic
|
|
512
|
-
* #4406 signal-contract cutover — no writer ever produced the memory-pane
|
|
513
|
-
* records it rendered.
|
|
514
|
-
*
|
|
515
|
-
* @type {Array<{ heading: string, field: string, renderBucket: (items: object[]) => string[] }>}
|
|
516
|
-
*/
|
|
517
|
-
const ROUTED_SECTIONS = [
|
|
518
|
-
{
|
|
519
|
-
heading: '### Proposed issues — consumer repo',
|
|
520
|
-
field: 'consumer',
|
|
521
|
-
renderBucket: renderIssueBucket,
|
|
522
|
-
},
|
|
523
|
-
{
|
|
524
|
-
heading: '### Proposed issues — framework repo',
|
|
525
|
-
field: 'framework',
|
|
526
|
-
renderBucket: renderIssueBucket,
|
|
527
|
-
},
|
|
528
|
-
{
|
|
529
|
-
heading: '### One-off / discarded',
|
|
530
|
-
field: 'discarded',
|
|
531
|
-
renderBucket: renderDiscardedBucket,
|
|
532
|
-
},
|
|
533
|
-
];
|
|
534
|
-
|
|
535
|
-
/**
|
|
536
|
-
* Pure: render the four routed-proposal sections in deterministic order.
|
|
537
|
-
* Returns `null` when `routedProposals` is absent or fully empty — the
|
|
538
|
-
* caller falls back to the legacy "Action Items for Next Epic" section so
|
|
539
|
-
* back-compat callers see no shape change.
|
|
540
|
-
*
|
|
541
|
-
* @param {{ framework: object[], consumer: object[], memory: object[], discarded: object[] } | null} routedProposals
|
|
542
|
-
* @returns {string[] | null}
|
|
543
|
-
*/
|
|
544
|
-
function renderRoutedSections(routedProposals) {
|
|
545
|
-
if (
|
|
546
|
-
!routedProposals ||
|
|
547
|
-
typeof routedProposals !== 'object' ||
|
|
548
|
-
Array.isArray(routedProposals)
|
|
549
|
-
) {
|
|
550
|
-
return null;
|
|
551
|
-
}
|
|
552
|
-
const buckets = ROUTED_SECTIONS.map((section) => {
|
|
553
|
-
const items = Array.isArray(routedProposals[section.field])
|
|
554
|
-
? routedProposals[section.field]
|
|
555
|
-
: [];
|
|
556
|
-
return { section, items };
|
|
557
|
-
});
|
|
558
|
-
if (buckets.every(({ items }) => items.length === 0)) {
|
|
559
|
-
return null;
|
|
560
|
-
}
|
|
561
|
-
|
|
562
|
-
// Each section renders as `[heading, '', ...body]`; a single blank-line
|
|
563
|
-
// separator sits between consecutive sections (no trailing separator after
|
|
564
|
-
// the last), reproducing the original hand-unrolled push sequence exactly.
|
|
565
|
-
const out = [];
|
|
566
|
-
for (const { section, items } of buckets) {
|
|
567
|
-
if (out.length > 0) out.push('');
|
|
568
|
-
out.push(section.heading, '', ...section.renderBucket(items));
|
|
569
|
-
}
|
|
570
|
-
return out;
|
|
571
|
-
}
|