mandrel 1.94.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/README.md +116 -99
- package/.agents/agents/acceptance-critic.md +9 -7
- package/.agents/agents/story-worker.md +45 -51
- package/.agents/audit-checklists/performance.md +1 -1
- package/.agents/docs/SDLC.md +498 -1287
- package/.agents/docs/agentrc-reference.json +185 -80
- package/.agents/docs/configuration.md +132 -190
- package/.agents/docs/execution-reference.md +51 -25
- package/.agents/docs/quality-gates.md +25 -33
- package/.agents/docs/workflows.md +8 -8
- package/.agents/instructions.md +113 -139
- package/.agents/rules/ci-remediation.md +11 -15
- package/.agents/rules/git-conventions-reference.md +48 -58
- package/.agents/rules/git-conventions.md +16 -22
- package/.agents/schemas/acceptance-eval-verdict.schema.json +1 -1
- package/.agents/schemas/agentrc.schema.json +83 -254
- package/.agents/schemas/audit-rules.json +59 -1
- package/.agents/schemas/audit-rules.schema.json +33 -1
- package/.agents/schemas/lifecycle/README.md +1 -2
- package/.agents/schemas/lifecycle/ledger-record.schema.json +1 -1
- package/.agents/schemas/lifecycle/merge.flip-failed.schema.json +33 -0
- package/.agents/schemas/lifecycle/merge.unlanded.schema.json +1 -0
- package/.agents/schemas/lifecycle/retro.end.schema.json +1 -1
- package/.agents/schemas/lifecycle/story.merged.schema.json +1 -1
- package/.agents/schemas/signal-event.schema.json +3 -3
- package/.agents/schemas/story-deliver-terminal.schema.json +152 -0
- package/.agents/schemas/validation-evidence.schema.json +1 -1
- package/.agents/scripts/acceptance-eval.js +22 -66
- package/.agents/scripts/agents-bootstrap-github.js +1 -1
- package/.agents/scripts/audit-to-stories.js +7 -7
- package/.agents/scripts/boot-sweep.js +1 -1
- package/.agents/scripts/bootstrap.js +3 -3
- package/.agents/scripts/check-dead-exports.js +43 -104
- package/.agents/scripts/check-doc-links.js +2 -2
- package/.agents/scripts/check-lifecycle-lint.js +7 -10
- package/.agents/scripts/check-workflow-cli-lint.js +91 -0
- package/.agents/scripts/cleanup-repo-test-temp.js +6 -1
- package/.agents/scripts/deliver-recover.js +122 -0
- package/.agents/scripts/drain-pending-cleanup.js +1 -1
- package/.agents/scripts/evidence-gate.js +20 -50
- package/.agents/scripts/generate-skills-index.js +17 -1
- package/.agents/scripts/generate-workflows-doc.js +4 -4
- package/.agents/scripts/lib/ITicketingProvider.js +1 -19
- package/.agents/scripts/lib/Logger.js +6 -10
- package/.agents/scripts/lib/audit-suite/runner.js +2 -2
- package/.agents/scripts/lib/audit-suite/selector.js +328 -28
- package/.agents/scripts/lib/audit-to-stories/{seed-epic-from-findings.js → seed-from-findings.js} +9 -9
- package/.agents/scripts/lib/baselines/kernel.js +206 -18
- package/.agents/scripts/lib/baselines/kinds/maintainability.js +0 -15
- package/.agents/scripts/lib/baselines/reader.js +1 -6
- package/.agents/scripts/lib/bdd-runner-detect.js +5 -9
- package/.agents/scripts/lib/bootstrap/ci-workflow-template.js +28 -33
- package/.agents/scripts/lib/bootstrap/issue-forms-template.js +32 -33
- package/.agents/scripts/lib/bootstrap/manifest.js +8 -11
- package/.agents/scripts/lib/bootstrap/project-bootstrap.js +30 -53
- package/.agents/scripts/lib/bootstrap/quality-bootstrap.js +0 -2
- package/.agents/scripts/lib/checks/core-bare-clean.js +6 -3
- package/.agents/scripts/lib/checks/index.js +3 -2
- package/.agents/scripts/lib/checks/loop-health.js +12 -11
- package/.agents/scripts/lib/checks/state.js +17 -248
- package/.agents/scripts/lib/checks/story-init-not-backgrounded.js +26 -24
- package/.agents/scripts/lib/checks/subagent-agent-tool-required.js +3 -4
- package/.agents/scripts/lib/checks/worktree-bootstrap-env.js +2 -2
- package/.agents/scripts/lib/checks/worktree-residue-biome.js +3 -3
- package/.agents/scripts/lib/cli/standard-args.js +13 -22
- package/.agents/scripts/lib/cli-args.js +39 -9
- package/.agents/scripts/lib/close-validation/gates.js +15 -15
- package/.agents/scripts/lib/close-validation/projections/inputs.js +7 -7
- package/.agents/scripts/lib/close-validation/projections/maintainability.js +12 -12
- package/.agents/scripts/lib/close-validation/runner.js +13 -21
- package/.agents/scripts/lib/close-validation/telemetry.js +17 -8
- package/.agents/scripts/lib/config/ci.js +6 -31
- package/.agents/scripts/lib/config/delivery-routing.js +52 -35
- package/.agents/scripts/lib/config/explain.js +61 -48
- package/.agents/scripts/lib/config/github.js +7 -5
- package/.agents/scripts/lib/config/limits.js +29 -80
- package/.agents/scripts/lib/config/paths.js +0 -2
- package/.agents/scripts/lib/config/quality.js +12 -15
- package/.agents/scripts/lib/config/runners.js +20 -66
- package/.agents/scripts/lib/config/temp-paths.js +30 -63
- package/.agents/scripts/lib/config/worktree-isolation.js +0 -5
- package/.agents/scripts/lib/config-resolver.js +2 -7
- package/.agents/scripts/lib/config-settings-schema-delivery.js +55 -161
- package/.agents/scripts/lib/config-settings-schema-quality.js +17 -16
- package/.agents/scripts/lib/config-settings-schema.js +100 -60
- package/.agents/scripts/lib/dead-exports-knip.js +105 -0
- package/.agents/scripts/lib/dead-exports-mode.js +51 -0
- package/.agents/scripts/lib/dependency-parser.js +3 -2
- package/.agents/scripts/lib/doc-tiers.js +2 -2
- package/.agents/scripts/lib/duplicate-search.js +242 -41
- package/.agents/scripts/lib/feedback-loop/retro-proposals-graduator.js +1 -1
- package/.agents/scripts/lib/findings/promote-finding.js +23 -14
- package/.agents/scripts/lib/format-generated-json.js +97 -0
- package/.agents/scripts/lib/framework-version.js +19 -190
- package/.agents/scripts/lib/gh-exec.js +8 -0
- package/.agents/scripts/lib/git-branch-cleanup.js +1 -10
- package/.agents/scripts/lib/git-branch-lifecycle.js +17 -180
- package/.agents/scripts/lib/git-utils.js +32 -20
- package/.agents/scripts/lib/github/framework-repo.js +6 -0
- package/.agents/scripts/lib/json-utils.js +1 -2
- package/.agents/scripts/lib/label-constants.js +10 -38
- package/.agents/scripts/lib/label-taxonomy.js +10 -55
- package/.agents/scripts/lib/observability/active-story-env.js +44 -165
- package/.agents/scripts/lib/observability/runtime-friction.js +243 -0
- package/.agents/scripts/lib/observability/signal-validator.js +4 -4
- package/.agents/scripts/lib/observability/signals-writer.js +6 -82
- package/.agents/scripts/lib/observability/source-classifier.js +5 -5
- package/.agents/scripts/lib/observability/tool-trace-hook.js +2 -12
- package/.agents/scripts/lib/onboard/init-tail.js +1 -3
- package/.agents/scripts/lib/orchestration/acceptance-clusters.js +1 -1
- package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +2 -2
- package/.agents/scripts/lib/orchestration/ceremony-routing.js +105 -44
- package/.agents/scripts/lib/orchestration/code-review.js +78 -436
- package/.agents/scripts/lib/orchestration/column-sync.js +1 -1
- package/.agents/scripts/lib/orchestration/consolidation-precondition.js +4 -4
- package/.agents/scripts/lib/orchestration/context-envelope.js +2 -5
- package/.agents/scripts/lib/orchestration/deliver-recover.js +328 -0
- package/.agents/scripts/lib/orchestration/detectors-phase.js +12 -6
- package/.agents/scripts/lib/orchestration/docs-digest.js +8 -8
- package/.agents/scripts/lib/orchestration/file-assumptions.js +7 -13
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/cli.js +1 -1
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/fast-forward.js +34 -0
- package/.agents/scripts/lib/orchestration/lease-guard-shared.js +3 -2
- package/.agents/scripts/lib/orchestration/lifecycle/emit-ledger-event.js +142 -0
- package/.agents/scripts/lib/orchestration/lifecycle/emit-loop-tick.js +17 -19
- package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-flip-failed.js +86 -0
- package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-unlanded.js +37 -103
- package/.agents/scripts/lib/orchestration/lifecycle/ledger-writer.js +6 -3
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/README.md +21 -43
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/watcher.js +50 -85
- package/.agents/scripts/lib/orchestration/lifecycle/trace-logger.js +3 -14
- package/.agents/scripts/lib/orchestration/lint-baseline-service.js +4 -4
- package/.agents/scripts/lib/orchestration/merge-block-class.js +77 -21
- package/.agents/scripts/lib/orchestration/merge-poll.js +104 -0
- package/.agents/scripts/lib/orchestration/phase-runner.js +3 -2
- package/.agents/scripts/lib/orchestration/plan-context.js +354 -282
- package/.agents/scripts/lib/orchestration/plan-critic-conditions.js +11 -22
- package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +4 -8
- package/.agents/scripts/lib/orchestration/plan-metrics.js +38 -6
- package/.agents/scripts/lib/orchestration/plan-navigation.js +92 -0
- package/.agents/scripts/lib/orchestration/plan-persist/fan-out-gate.js +71 -0
- package/.agents/scripts/lib/orchestration/plan-persist/persist-helpers.js +245 -0
- package/.agents/scripts/lib/orchestration/plan-persist/plan-context-source.js +116 -0
- package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +432 -858
- package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +778 -0
- package/.agents/scripts/lib/orchestration/plan-persist/summary.js +47 -115
- package/.agents/scripts/lib/orchestration/plan-persist/supersede-ops.js +509 -0
- package/.agents/scripts/lib/orchestration/plan-reachability.js +9 -14
- package/.agents/scripts/lib/orchestration/plan-runner/worktree-sweep.js +1 -1
- package/.agents/scripts/lib/orchestration/{epic-plan-spec/phases → planning}/authoring-context.js +52 -51
- package/.agents/scripts/lib/orchestration/planning/decomposer-context.js +27 -0
- package/.agents/scripts/lib/orchestration/{epic-plan-spec/phases → planning}/spec-authoring-grounding.js +1 -1
- package/.agents/scripts/lib/orchestration/pr-base-guard.js +18 -28
- package/.agents/scripts/lib/orchestration/remote-verifier.js +1 -1
- package/.agents/scripts/lib/orchestration/resolve-stories.js +344 -0
- package/.agents/scripts/lib/orchestration/resolves-token.js +1 -1
- package/.agents/scripts/lib/orchestration/retro-proposals.js +140 -79
- package/.agents/scripts/lib/orchestration/review-depth.js +126 -47
- package/.agents/scripts/lib/orchestration/review-providers/codex.js +2 -2
- package/.agents/scripts/lib/orchestration/review-providers/findings-renderer.js +3 -13
- package/.agents/scripts/lib/orchestration/review-providers/native.js +1 -154
- package/.agents/scripts/lib/orchestration/review-providers/review-depth.js +3 -2
- package/.agents/scripts/lib/orchestration/review-providers/review-provider-factory.js +21 -56
- package/.agents/scripts/lib/orchestration/review-providers/security-review.js +1 -1
- package/.agents/scripts/lib/orchestration/review-providers/types.js +5 -4
- package/.agents/scripts/lib/orchestration/review-providers/ultrareview.js +1 -1
- package/.agents/scripts/lib/orchestration/run-epilogue.js +784 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +25 -1
- package/.agents/scripts/lib/orchestration/single-story-close/phases/base-sync.js +11 -9
- package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +4 -4
- package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +86 -41
- package/.agents/scripts/lib/orchestration/single-story-close/phases/confirm-merge.js +608 -152
- package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +77 -32
- package/.agents/scripts/lib/orchestration/single-story-close/phases/post-land.js +305 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/pull-request.js +1 -1
- package/.agents/scripts/lib/orchestration/single-story-close/phases/review-block.js +44 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/worktree-reap.js +37 -4
- package/.agents/scripts/lib/orchestration/single-story-close/phases/wrong-tree-guard.js +2 -2
- package/.agents/scripts/lib/orchestration/single-story-close/runner.js +275 -46
- package/.agents/scripts/lib/orchestration/single-story-lease-guard.js +1 -1
- package/.agents/scripts/lib/orchestration/spec-freshness.js +14 -205
- package/.agents/scripts/lib/orchestration/spec-section-validator.js +4 -5
- package/.agents/scripts/lib/orchestration/spec-spill.js +60 -0
- package/.agents/scripts/lib/orchestration/split-policy-validator.js +188 -0
- package/.agents/scripts/lib/orchestration/story-close/emit-blocked.js +49 -0
- package/.agents/scripts/lib/orchestration/story-close/format-autofix.js +10 -10
- package/.agents/scripts/lib/orchestration/story-close/phases/code-review.js +28 -42
- package/.agents/scripts/lib/orchestration/story-deliver-terminal.js +360 -0
- package/.agents/scripts/lib/orchestration/story-follow-ups.js +298 -0
- package/.agents/scripts/lib/orchestration/story-init-remote.js +51 -0
- package/.agents/scripts/lib/orchestration/story-plan-state.js +33 -0
- package/.agents/scripts/lib/orchestration/structured-comment-parser.js +1 -1
- package/.agents/scripts/lib/orchestration/task-body-validator.js +60 -25
- package/.agents/scripts/lib/orchestration/ticket-lease.js +27 -74
- package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +130 -75
- package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +192 -377
- package/.agents/scripts/lib/orchestration/ticket-validator.js +123 -25
- package/.agents/scripts/lib/orchestration/ticketing/bulk.js +14 -72
- package/.agents/scripts/lib/orchestration/ticketing/reads.js +45 -55
- package/.agents/scripts/lib/orchestration/ticketing/transition.js +66 -6
- package/.agents/scripts/lib/orchestration/ticketing.js +0 -1
- package/.agents/scripts/lib/plan-phase-cleanup.js +12 -14
- package/.agents/scripts/lib/planning-corpus.js +12 -281
- package/.agents/scripts/lib/preflight-runner.js +4 -4
- package/.agents/scripts/lib/qa/coverage-verdict.js +5 -5
- package/.agents/scripts/lib/qa/qa-context-hydrator.js +5 -5
- package/.agents/scripts/lib/signals/index.js +4 -17
- package/.agents/scripts/lib/signals/read.js +35 -35
- package/.agents/scripts/lib/signals/schema.js +8 -11
- package/.agents/scripts/lib/signals/span-tree.js +7 -7
- package/.agents/scripts/lib/signals/write.js +0 -1
- package/.agents/scripts/lib/single-story/story-merged-notify.js +13 -2
- package/.agents/scripts/lib/single-story-sweep/protection-ctx.js +1 -1
- package/.agents/scripts/lib/skills/parse-skill.js +16 -3
- package/.agents/scripts/lib/story-adjacency.js +17 -19
- package/.agents/scripts/lib/story-body/story-body.js +130 -75
- package/.agents/scripts/lib/story-plan.js +2 -4
- package/.agents/scripts/lib/templates/decomposer-prompts.js +51 -46
- package/.agents/scripts/lib/templates/spec-author-prompts.js +47 -45
- package/.agents/scripts/lib/test-env.js +14 -1
- package/.agents/scripts/lib/test-tiers.js +0 -3
- package/.agents/scripts/lib/{epic-body-sections.js → ticket-body-sections.js} +25 -39
- package/.agents/scripts/lib/validation-evidence.js +32 -60
- package/.agents/scripts/lib/wave-runner/ready-set.js +38 -12
- package/.agents/scripts/lib/workspace-provisioner.js +1 -1
- package/.agents/scripts/lib/worktree/lifecycle/pending-cleanup.js +1 -1
- package/.agents/scripts/lib/worktree/lifecycle/reap.js +72 -25
- package/.agents/scripts/lib/worktree/lifecycle-manager.js +1 -2
- package/.agents/scripts/lint-issue-body.js +71 -40
- package/.agents/scripts/mandrel-update-preflight.js +1 -1
- package/.agents/scripts/notify.js +4 -3
- package/.agents/scripts/plan-context.js +102 -80
- package/.agents/scripts/plan-persist.js +230 -279
- package/.agents/scripts/plan-run-epilogue.js +142 -0
- package/.agents/scripts/post-structured-comment.js +0 -38
- package/.agents/scripts/pr-watch-with-update.js +43 -22
- package/.agents/scripts/providers/github/compose.js +0 -1
- package/.agents/scripts/providers/github/errors.js +0 -19
- package/.agents/scripts/providers/github/issues.js +13 -39
- package/.agents/scripts/providers/github/mappers.js +5 -12
- package/.agents/scripts/providers/github/sub-issues.js +0 -47
- package/.agents/scripts/providers/github/tickets.js +33 -156
- package/.agents/scripts/providers/github.js +17 -6
- package/.agents/scripts/resolve-stories.js +236 -0
- package/.agents/scripts/run-coverage.js +4 -1
- package/.agents/scripts/run-lint.js +2 -2
- package/.agents/scripts/run-verify.js +31 -2
- package/.agents/scripts/signals-view.js +25 -21
- package/.agents/scripts/single-story-close.js +178 -26
- package/.agents/scripts/single-story-confirm-merge.js +313 -24
- package/.agents/scripts/single-story-init.js +35 -30
- package/.agents/scripts/stories-wave-tick.js +85 -10
- package/.agents/scripts/story-plan.js +28 -49
- package/.agents/scripts/update-ticket-state.js +14 -65
- package/.agents/skills/core/code-review-and-quality/SKILL.md +28 -450
- package/.agents/skills/core/code-review-and-quality/reference.md +458 -0
- package/.agents/skills/core/debugging-and-error-recovery/SKILL.md +22 -315
- package/.agents/skills/core/debugging-and-error-recovery/reference.md +323 -0
- package/.agents/skills/core/diagnose-friction/SKILL.md +14 -18
- package/.agents/skills/core/documentation-and-adrs/SKILL.md +25 -397
- package/.agents/skills/core/documentation-and-adrs/reference.md +403 -0
- package/.agents/skills/core/gates-and-baselines/SKILL.md +12 -12
- package/.agents/skills/core/idea-refinement/SKILL.md +9 -9
- package/.agents/skills/core/scope-triage/SKILL.md +31 -172
- package/.agents/skills/core/security-and-hardening/SKILL.md +22 -367
- package/.agents/skills/core/security-and-hardening/reference.md +375 -0
- package/.agents/skills/skills.index.json +3 -53
- package/.agents/skills/stack/qa/playwright-bdd/SKILL.md +2 -4
- package/.agents/skills/stack/qa/qa-explore-driving/SKILL.md +1 -1
- package/.agents/skills/stack/qa/qa-harness/SKILL.md +1 -3
- package/.agents/starter-agentrc.json +0 -5
- package/.agents/templates/agent-protocol.md +9 -10
- package/.agents/workflows/audit-architecture.md +6 -7
- package/.agents/workflows/audit-clean-code.md +7 -7
- package/.agents/workflows/audit-dependencies.md +3 -3
- package/.agents/workflows/audit-devops.md +3 -3
- package/.agents/workflows/audit-documentation.md +9 -10
- package/.agents/workflows/audit-lighthouse.md +11 -3
- package/.agents/workflows/audit-navigability.md +13 -2
- package/.agents/workflows/audit-performance.md +5 -6
- package/.agents/workflows/audit-privacy.md +3 -3
- package/.agents/workflows/audit-quality.md +11 -12
- package/.agents/workflows/audit-security.md +4 -5
- package/.agents/workflows/audit-seo.md +13 -3
- package/.agents/workflows/audit-sre.md +3 -3
- package/.agents/workflows/audit-to-stories.md +20 -20
- package/.agents/workflows/audit-ux-ui.md +10 -3
- package/.agents/workflows/deliver.md +177 -176
- package/.agents/workflows/git-cleanup.md +5 -6
- package/.agents/workflows/git-deliver.md +1 -1
- package/.agents/workflows/helpers/_merge-conflict-template.md +1 -1
- package/.agents/workflows/helpers/acceptance-self-eval.md +35 -40
- package/.agents/workflows/helpers/code-quality-guardrails.md +7 -7
- package/.agents/workflows/helpers/code-review.md +75 -196
- package/.agents/workflows/helpers/{single-story-deliver-reference.md → deliver-story-reference.md} +83 -44
- package/.agents/workflows/helpers/deliver-story.md +606 -0
- package/.agents/workflows/helpers/diagnose.md +10 -10
- package/.agents/workflows/helpers/parallel-tooling.md +3 -3
- package/.agents/workflows/helpers/signals.md +16 -16
- package/.agents/workflows/helpers/worktree-lifecycle.md +66 -86
- package/.agents/workflows/mandrel-update.md +2 -1
- package/.agents/workflows/plan.md +277 -145
- package/.agents/workflows/qa-assist.md +27 -33
- package/.agents/workflows/qa-explore.md +29 -38
- package/.agents/workflows/qa-run.md +2 -6
- package/README.md +9 -8
- package/bin/mandrel.js +12 -1
- package/docs/CHANGELOG.md +70 -0
- package/lib/cli/registry.js +262 -19
- package/lib/cli/sync-agents.js +157 -0
- package/lib/cli/sync-commands.js +115 -6
- package/lib/cli/sync.js +168 -6
- package/lib/cli/update.js +105 -8
- package/lib/cli/version-helpers.js +131 -0
- package/lib/migrations/README.md +7 -5
- package/lib/migrations/index.js +12 -8
- package/lib/migrations/steps/2.1.0-retire-mi-drop-knobs.js +100 -0
- package/lib/migrations/steps/2.1.0-retire-verify-concurrency-cap.js +101 -0
- package/package.json +2 -2
- package/.agents/agents/retro.md +0 -42
- package/.agents/personas/architect.md +0 -113
- package/.agents/personas/devops-engineer.md +0 -38
- package/.agents/personas/engineer.md +0 -33
- package/.agents/personas/project-manager.md +0 -114
- package/.agents/personas/qa-engineer.md +0 -95
- package/.agents/personas/security-engineer.md +0 -111
- package/.agents/personas/technical-writer.md +0 -101
- package/.agents/schemas/dispatch-manifest.json +0 -232
- package/.agents/schemas/epic-perf-report.schema.json +0 -89
- package/.agents/schemas/epic-spec.schema.json +0 -153
- package/.agents/schemas/lifecycle/acceptance.reconcile.failed.schema.json +0 -13
- package/.agents/schemas/lifecycle/acceptance.reconcile.ok.schema.json +0 -13
- package/.agents/schemas/lifecycle/acceptance.reconcile.skipped.schema.json +0 -13
- package/.agents/schemas/lifecycle/acceptance.reconcile.start.schema.json +0 -12
- package/.agents/schemas/lifecycle/acceptance.reconcile.waived.schema.json +0 -13
- package/.agents/schemas/lifecycle/epic.automerge.end.schema.json +0 -15
- package/.agents/schemas/lifecycle/epic.automerge.start.schema.json +0 -13
- package/.agents/schemas/lifecycle/epic.blocked.schema.json +0 -13
- package/.agents/schemas/lifecycle/epic.cleanup.end.schema.json +0 -12
- package/.agents/schemas/lifecycle/epic.cleanup.start.schema.json +0 -12
- package/.agents/schemas/lifecycle/epic.close.end.schema.json +0 -12
- package/.agents/schemas/lifecycle/epic.complete.schema.json +0 -13
- package/.agents/schemas/lifecycle/epic.finalize.end.schema.json +0 -13
- package/.agents/schemas/lifecycle/epic.finalize.start.schema.json +0 -12
- package/.agents/schemas/lifecycle/epic.merge.armed.schema.json +0 -13
- package/.agents/schemas/lifecycle/epic.merge.blocked.schema.json +0 -14
- package/.agents/schemas/lifecycle/epic.merge.confirmed.schema.json +0 -17
- package/.agents/schemas/lifecycle/epic.merge.ready.schema.json +0 -15
- package/.agents/schemas/lifecycle/epic.plan.end.schema.json +0 -18
- package/.agents/schemas/lifecycle/epic.plan.start.schema.json +0 -12
- package/.agents/schemas/lifecycle/epic.snapshot.end.schema.json +0 -16
- package/.agents/schemas/lifecycle/epic.snapshot.start.schema.json +0 -12
- package/.agents/schemas/lifecycle/epic.watch.end.schema.json +0 -29
- package/.agents/schemas/lifecycle/epic.watch.start.schema.json +0 -16
- package/.agents/schemas/lifecycle/slice.end.schema.json +0 -21
- package/.agents/schemas/lifecycle/slice.heartbeat.schema.json +0 -20
- package/.agents/schemas/lifecycle/slice.start.schema.json +0 -17
- package/.agents/schemas/lifecycle/story.heartbeat.schema.json +0 -20
- package/.agents/schemas/risk-verdict.schema.json +0 -66
- package/.agents/schemas/story-perf-summary.schema.json +0 -73
- package/.agents/scripts/acceptance-spec-reconciler.js +0 -642
- package/.agents/scripts/analyze-execution.js +0 -444
- package/.agents/scripts/bookkeeping-reconcile.js +0 -117
- package/.agents/scripts/check-prepush-recovery.js +0 -90
- package/.agents/scripts/dispatcher.js +0 -295
- package/.agents/scripts/epic-audit-prepare.js +0 -497
- package/.agents/scripts/epic-audit-recheck.js +0 -274
- package/.agents/scripts/epic-deliver-note-intervention.js +0 -192
- package/.agents/scripts/epic-deliver-preflight.js +0 -462
- package/.agents/scripts/epic-deliver-prepare.js +0 -852
- package/.agents/scripts/epic-execute-record-wave.js +0 -449
- package/.agents/scripts/epic-plan-clarity.js +0 -211
- package/.agents/scripts/epic-plan-healthcheck.js +0 -581
- package/.agents/scripts/epic-reconcile.js +0 -625
- package/.agents/scripts/lib/baseline-snapshot.js +0 -979
- package/.agents/scripts/lib/checks/epic-merge-lock-stale.js +0 -54
- package/.agents/scripts/lib/checks/stale-origin-epic.js +0 -49
- package/.agents/scripts/lib/config/lifecycle.js +0 -40
- package/.agents/scripts/lib/config/preflight.js +0 -58
- package/.agents/scripts/lib/config/retro.js +0 -77
- package/.agents/scripts/lib/epic-merge-lock.js +0 -322
- package/.agents/scripts/lib/epic-plan-clarity.js +0 -181
- package/.agents/scripts/lib/epic-plan-ideation.js +0 -261
- package/.agents/scripts/lib/git-merge-orchestrator.js +0 -261
- package/.agents/scripts/lib/observability/baseline-refresh-rate.js +0 -221
- package/.agents/scripts/lib/observability/hook-heartbeat.js +0 -219
- package/.agents/scripts/lib/observability/perf-aggregator.js +0 -813
- package/.agents/scripts/lib/observability/perf-report-readers.js +0 -328
- package/.agents/scripts/lib/observability/perf-report-render.js +0 -182
- package/.agents/scripts/lib/orchestration/bookkeeping-outbox.js +0 -270
- package/.agents/scripts/lib/orchestration/context-hydration-engine.js +0 -539
- package/.agents/scripts/lib/orchestration/deliver-route.js +0 -173
- package/.agents/scripts/lib/orchestration/dispatch-engine.js +0 -134
- package/.agents/scripts/lib/orchestration/dispatch-pipeline.js +0 -183
- package/.agents/scripts/lib/orchestration/epic-cleanup.js +0 -801
- package/.agents/scripts/lib/orchestration/epic-deliver-lease-guard.js +0 -310
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/context.js +0 -163
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/creation.js +0 -140
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/dag.js +0 -64
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/diagnostics.js +0 -72
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/persist-helpers.js +0 -156
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/persist.js +0 -345
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/planning-artifacts.js +0 -41
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/reconcile-spawn.js +0 -86
- package/.agents/scripts/lib/orchestration/epic-plan-lease-guard.js +0 -391
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/drain.js +0 -94
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/plan-epic.js +0 -236
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/risk-verdict.js +0 -105
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/run-spec-phase.js +0 -307
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/spec-freshness.js +0 -117
- package/.agents/scripts/lib/orchestration/epic-plan-state-store.js +0 -117
- package/.agents/scripts/lib/orchestration/epic-run-state-store.js +0 -621
- package/.agents/scripts/lib/orchestration/epic-runner/concurrency-gate.js +0 -186
- package/.agents/scripts/lib/orchestration/epic-runner/deliver-phases.js +0 -50
- package/.agents/scripts/lib/orchestration/epic-runner/phases/build-wave-dag.js +0 -129
- package/.agents/scripts/lib/orchestration/epic-runner/phases/snapshot.js +0 -103
- package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/composition.js +0 -267
- package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/signals.js +0 -210
- package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/transport.js +0 -238
- package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/_bullet-format.js +0 -32
- package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/component-drift.js +0 -203
- package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/crap-drift.js +0 -227
- package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/maintainability-drift.js +0 -117
- package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/stalled-worktree.js +0 -37
- package/.agents/scripts/lib/orchestration/epic-runner/story-launcher.js +0 -127
- package/.agents/scripts/lib/orchestration/epic-runner/story-run-progress-writer.js +0 -400
- package/.agents/scripts/lib/orchestration/epic-runner/sub-agent-return.js +0 -276
- package/.agents/scripts/lib/orchestration/epic-runner/wave-scheduler.js +0 -66
- package/.agents/scripts/lib/orchestration/epic-spec-reconciler-apply.js +0 -789
- package/.agents/scripts/lib/orchestration/epic-spec-reconciler-diff.js +0 -676
- package/.agents/scripts/lib/orchestration/epic-spec-reconciler-discriminator.js +0 -389
- package/.agents/scripts/lib/orchestration/epic-spec-reconciler-format.js +0 -230
- package/.agents/scripts/lib/orchestration/epic-spec-reconciler-ops.js +0 -361
- package/.agents/scripts/lib/orchestration/error-journal.js +0 -139
- package/.agents/scripts/lib/orchestration/finalize/open-or-locate-pr.js +0 -306
- package/.agents/scripts/lib/orchestration/finalize/post-handoff-comment.js +0 -489
- package/.agents/scripts/lib/orchestration/finalize/sanitize-skip-ci.js +0 -88
- package/.agents/scripts/lib/orchestration/lifecycle/emit-slice-lifecycle.js +0 -270
- package/.agents/scripts/lib/orchestration/lifecycle/emit-story-dispatch-end.js +0 -147
- package/.agents/scripts/lib/orchestration/lifecycle/emit-story-heartbeat.js +0 -155
- package/.agents/scripts/lib/orchestration/lifecycle/ledger-diff.js +0 -140
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/acceptance-reconciler.js +0 -465
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-armer.js +0 -501
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-predicate.js +0 -984
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/branch-cleaner.js +0 -264
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/checkpoint-pointer-writer.js +0 -284
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/cleaner.js +0 -355
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/finalizer.js +0 -673
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/index.js +0 -378
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/intervention-recorder.js +0 -140
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/label-transitioner.js +0 -144
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/merge-watcher.js +0 -665
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/notify-dispatcher.js +0 -174
- package/.agents/scripts/lib/orchestration/manifest-builder.js +0 -222
- package/.agents/scripts/lib/orchestration/plan-persist/amend.js +0 -359
- package/.agents/scripts/lib/orchestration/plan-persist/delivery-mode.js +0 -127
- package/.agents/scripts/lib/orchestration/plan-review-routing.js +0 -63
- package/.agents/scripts/lib/orchestration/planning-context-budget.js +0 -213
- package/.agents/scripts/lib/orchestration/planning-risk.js +0 -194
- package/.agents/scripts/lib/orchestration/post-merge/phases/branch-cleanup.js +0 -56
- package/.agents/scripts/lib/orchestration/post-merge/phases/dashboard-refresh.js +0 -33
- package/.agents/scripts/lib/orchestration/post-merge/phases/notification.js +0 -78
- package/.agents/scripts/lib/orchestration/post-merge/phases/temp-cleanup.js +0 -68
- package/.agents/scripts/lib/orchestration/post-merge/phases/ticket-closure.js +0 -118
- package/.agents/scripts/lib/orchestration/post-merge/phases/worktree-reap.js +0 -396
- package/.agents/scripts/lib/orchestration/post-merge-pipeline.js +0 -205
- package/.agents/scripts/lib/orchestration/preflight-cache.js +0 -187
- package/.agents/scripts/lib/orchestration/recurring-failure-detector.js +0 -152
- package/.agents/scripts/lib/orchestration/retro/phases/checks.js +0 -94
- package/.agents/scripts/lib/orchestration/retro/phases/compose-body.js +0 -571
- package/.agents/scripts/lib/orchestration/retro/phases/gather-signals.js +0 -450
- package/.agents/scripts/lib/orchestration/retro/phases/post-and-mirror.js +0 -191
- package/.agents/scripts/lib/orchestration/retro-heuristics.js +0 -57
- package/.agents/scripts/lib/orchestration/retro-perf-heuristics.js +0 -275
- package/.agents/scripts/lib/orchestration/retro-runner.js +0 -197
- package/.agents/scripts/lib/orchestration/spec-renderer.js +0 -447
- package/.agents/scripts/lib/orchestration/story-close/auto-refresh-runner.js +0 -747
- package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/gate-failure.js +0 -211
- package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/pre-merge-attribution.js +0 -158
- package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/refresh-commit.js +0 -446
- package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/regression-projection.js +0 -297
- package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/scope-discovery.js +0 -48
- package/.agents/scripts/lib/orchestration/story-close/baseline-attribution-wiring.js +0 -67
- package/.agents/scripts/lib/orchestration/story-close/baseline-attribution.js +0 -161
- package/.agents/scripts/lib/orchestration/story-close/baseline-friction-body.js +0 -117
- package/.agents/scripts/lib/orchestration/story-close/cd-out-guard.js +0 -86
- package/.agents/scripts/lib/orchestration/story-close/cleanup-reconciler.js +0 -147
- package/.agents/scripts/lib/orchestration/story-close/close-inputs.js +0 -142
- package/.agents/scripts/lib/orchestration/story-close/comment-bodies.js +0 -62
- package/.agents/scripts/lib/orchestration/story-close/merge-runner.js +0 -658
- package/.agents/scripts/lib/orchestration/story-close/merge-subject.js +0 -198
- package/.agents/scripts/lib/orchestration/story-close/phases/branch-restore.js +0 -105
- package/.agents/scripts/lib/orchestration/story-close/phases/close.js +0 -222
- package/.agents/scripts/lib/orchestration/story-close/phases/gates.js +0 -292
- package/.agents/scripts/lib/orchestration/story-close/phases/locked-pipeline.js +0 -270
- package/.agents/scripts/lib/orchestration/story-close/phases/preflight.js +0 -110
- package/.agents/scripts/lib/orchestration/story-close/phases/refresh.js +0 -86
- package/.agents/scripts/lib/orchestration/story-close/phases/timeout-blocked-emitter.js +0 -112
- package/.agents/scripts/lib/orchestration/story-close/phases/timeout-blocked.js +0 -157
- package/.agents/scripts/lib/orchestration/story-close/post-merge-close.js +0 -421
- package/.agents/scripts/lib/orchestration/story-close/pre-merge-validation.js +0 -302
- package/.agents/scripts/lib/orchestration/story-close/shared-checkout-guard.js +0 -163
- package/.agents/scripts/lib/orchestration/story-close-recovery.js +0 -690
- package/.agents/scripts/lib/orchestration/wave-marker.js +0 -28
- package/.agents/scripts/lib/orchestration/wave-record-io.js +0 -218
- package/.agents/scripts/lib/orchestration/wave-record-notifications.js +0 -145
- package/.agents/scripts/lib/orchestration/wave-record-projection.js +0 -212
- package/.agents/scripts/lib/presentation/dispatch-manifest-render.js +0 -111
- package/.agents/scripts/lib/presentation/manifest-builder.js +0 -239
- package/.agents/scripts/lib/presentation/manifest-formatter.js +0 -242
- package/.agents/scripts/lib/presentation/manifest-helpers.js +0 -213
- package/.agents/scripts/lib/presentation/manifest-persistence.js +0 -261
- package/.agents/scripts/lib/presentation/manifest-procedures.js +0 -55
- package/.agents/scripts/lib/presentation/manifest-render-waves.js +0 -306
- package/.agents/scripts/lib/presentation/manifest-renderer.js +0 -188
- package/.agents/scripts/lib/presentation/manifest-story-views.js +0 -110
- package/.agents/scripts/lib/push-epic-retry.js +0 -209
- package/.agents/scripts/lib/spec/index.js +0 -36
- package/.agents/scripts/lib/spec/loader.js +0 -425
- package/.agents/scripts/lib/spec/state.js +0 -208
- package/.agents/scripts/lib/story-init/blocker-validator.js +0 -68
- package/.agents/scripts/lib/story-init/branch-initializer.js +0 -408
- package/.agents/scripts/lib/story-init/context-resolver.js +0 -92
- package/.agents/scripts/lib/story-init/donor-precheck.js +0 -207
- package/.agents/scripts/lib/story-init/state-transitioner.js +0 -80
- package/.agents/scripts/lib/story-init/task-graph-builder.js +0 -124
- package/.agents/scripts/lib/story-init/transition-summary.js +0 -34
- package/.agents/scripts/lib/test-reserved-epic-temp-ids.js +0 -35
- package/.agents/scripts/lib/wave-runner/tick.js +0 -754
- package/.agents/scripts/lib/wave-runner/wave-runner-error.js +0 -20
- package/.agents/scripts/lifecycle-emit-story-dispatch.js +0 -194
- package/.agents/scripts/lifecycle-emit.js +0 -510
- package/.agents/scripts/retro-run.js +0 -218
- package/.agents/scripts/slice-phase.js +0 -361
- package/.agents/scripts/standalone-feedback-rollup.js +0 -188
- package/.agents/scripts/story-close.js +0 -294
- package/.agents/scripts/story-init.js +0 -599
- package/.agents/scripts/story-phase.js +0 -369
- package/.agents/scripts/wave-tick.js +0 -464
- package/.agents/skills/core/analyze-execution/SKILL.md +0 -98
- package/.agents/skills/core/epic-plan-consolidate/SKILL.md +0 -172
- package/.agents/skills/core/epic-plan-consolidate/examples.md +0 -51
- package/.agents/skills/core/epic-plan-decompose-author/SKILL.md +0 -441
- package/.agents/skills/core/epic-plan-decompose-author/examples.md +0 -47
- package/.agents/skills/core/epic-plan-premortem/SKILL.md +0 -146
- package/.agents/skills/core/epic-plan-premortem/examples.md +0 -53
- package/.agents/skills/core/epic-plan-spec-author/SKILL.md +0 -383
- package/.agents/skills/core/epic-plan-spec-author/examples.md +0 -91
- package/.agents/workflows/helpers/deliver-epic-reference.md +0 -547
- package/.agents/workflows/helpers/deliver-epic-single.md +0 -331
- package/.agents/workflows/helpers/deliver-epic.md +0 -998
- package/.agents/workflows/helpers/deliver-stories.md +0 -450
- package/.agents/workflows/helpers/epic-audit.md +0 -189
- package/.agents/workflows/helpers/epic-deliver-story.md +0 -436
- package/.agents/workflows/helpers/epic-testing.md +0 -125
- package/.agents/workflows/helpers/plan-epic-reference.md +0 -160
- package/.agents/workflows/helpers/plan-epic.md +0 -353
- package/.agents/workflows/helpers/plan-story.md +0 -251
- package/.agents/workflows/helpers/scope-triage-gate.md +0 -108
- package/.agents/workflows/helpers/single-story-deliver.md +0 -557
|
@@ -11,19 +11,23 @@
|
|
|
11
11
|
* adapter's `runReview()` to collect a `Finding[]`, render the
|
|
12
12
|
* structured-comment body via `findings-renderer`, and post the
|
|
13
13
|
* comment through the GitHub provider here (the adapter is post-free
|
|
14
|
-
* by design).
|
|
15
|
-
*
|
|
16
|
-
*
|
|
14
|
+
* by design).
|
|
15
|
+
*
|
|
16
|
+
* v2.0.0 removed the Epic tier. The Epic-scope envelope and the
|
|
17
|
+
* Epic-scoped `code-review.start` / `.end` lifecycle emits (whose schema
|
|
18
|
+
* requires `epicId`) went with it; Story scope is the only scope and the
|
|
19
|
+
* module no longer touches the lifecycle bus.
|
|
17
20
|
*
|
|
18
21
|
* Public API:
|
|
19
|
-
* - `runCodeReview({
|
|
22
|
+
* - `runCodeReview({ ticketId, headRef, provider, logger, ... })` →
|
|
20
23
|
* `{ status, severity, posted, report, halted, blockerReason }`.
|
|
21
24
|
*
|
|
22
25
|
* Behaviour:
|
|
23
26
|
* - Loads the configured review adapter via the factory; defaults to
|
|
24
|
-
* `native` when `delivery.codeReview.
|
|
27
|
+
* a single `native` chain entry when `delivery.codeReview.providers`
|
|
28
|
+
* is unset or empty.
|
|
25
29
|
* - Always posts the unified `verification-results` structured comment on
|
|
26
|
-
* the
|
|
30
|
+
* the target issue/PR (the adapter never posts; the orchestrator owns
|
|
27
31
|
* persistence). Story #4411 (Epic #4405) unified the former
|
|
28
32
|
* `code-review` and `audit-results` findings contracts into this one
|
|
29
33
|
* `verification-results` marker.
|
|
@@ -36,12 +40,9 @@
|
|
|
36
40
|
*/
|
|
37
41
|
|
|
38
42
|
import { hasSurvivingCritical } from '../audit-suite/findings.js';
|
|
39
|
-
import { resolveLensTier } from '../audit-suite/selector.js';
|
|
40
43
|
import { resolveConfig } from '../config-resolver.js';
|
|
41
|
-
import { selectAuditStrategy } from '../dynamic-workflow/capability.js';
|
|
42
44
|
import { gitSpawn } from '../git-utils.js';
|
|
43
|
-
import {
|
|
44
|
-
import { resolveDepth } from './review-depth.js';
|
|
45
|
+
import { deriveChangeLevel, resolveDepth } from './review-depth.js';
|
|
45
46
|
import {
|
|
46
47
|
countBySeverity,
|
|
47
48
|
renderFindings,
|
|
@@ -51,29 +52,30 @@ import { upsertStructuredComment } from './ticketing.js';
|
|
|
51
52
|
|
|
52
53
|
/**
|
|
53
54
|
* Review depth tiers, ordered light → standard → deep. The depth is resolved
|
|
54
|
-
* by the shared {@link resolveDepth} resolver from
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
55
|
+
* by the shared {@link resolveDepth} resolver from two observable properties of
|
|
56
|
+
* the diff under review — whether its changed files touch a registered
|
|
57
|
+
* sensitive path ({@link deriveChangeLevel}) and their mechanical count — then
|
|
58
|
+
* threaded into the review provider's `runReview` input so a sensitive *or*
|
|
59
|
+
* wide-footprint change gets a deeper pass than a small, unremarkable one.
|
|
60
|
+
* Depth is an **input** signal only — it never changes the
|
|
59
61
|
* `{ status, severity, posted, report, halted, blockerReason }` output
|
|
60
|
-
* envelope nor the `
|
|
61
|
-
* extended by Story #3938).
|
|
62
|
+
* envelope nor the `verification-results` structured-comment body (Story #3876,
|
|
63
|
+
* extended by Story #3938; re-based off the diff by Story #4542).
|
|
62
64
|
*
|
|
63
65
|
* @typedef {import('./review-depth.js').ReviewDepth} ReviewDepth
|
|
64
66
|
*/
|
|
65
67
|
|
|
66
68
|
/**
|
|
67
|
-
*
|
|
68
|
-
* `git diff --name-only`. Returns the file
|
|
69
|
-
* cannot be enumerated (git failure, missing ref). A `null`
|
|
70
|
-
*
|
|
71
|
-
*
|
|
69
|
+
* Enumerate the files changed in the `baseRef...headRef` diff via
|
|
70
|
+
* `git diff --name-only`. Returns the file list, or `null` when the diff
|
|
71
|
+
* cannot be enumerated (git failure, missing ref). A `null` list is the neutral
|
|
72
|
+
* "diff unknown" signal both {@link deriveChangeLevel} and {@link resolveDepth}
|
|
73
|
+
* tolerate by failing safe to `standard`. Best-effort — never throws.
|
|
72
74
|
*
|
|
73
75
|
* @param {{ baseRef: string, headRef: string, gitSpawnFn?: typeof gitSpawn }} args
|
|
74
|
-
* @returns {
|
|
76
|
+
* @returns {string[]|null}
|
|
75
77
|
*/
|
|
76
|
-
function
|
|
78
|
+
function listChangedFiles({ baseRef, headRef, gitSpawnFn = gitSpawn }) {
|
|
77
79
|
try {
|
|
78
80
|
const result = gitSpawnFn(
|
|
79
81
|
process.cwd(),
|
|
@@ -85,300 +87,20 @@ function countChangedFiles({ baseRef, headRef, gitSpawnFn = gitSpawn }) {
|
|
|
85
87
|
return null;
|
|
86
88
|
}
|
|
87
89
|
return result.stdout
|
|
88
|
-
.trim()
|
|
89
90
|
.split('\n')
|
|
90
|
-
.
|
|
91
|
+
.map((line) => line.trim())
|
|
92
|
+
.filter((line) => line.length > 0);
|
|
91
93
|
} catch {
|
|
92
94
|
return null;
|
|
93
95
|
}
|
|
94
96
|
}
|
|
95
97
|
|
|
96
|
-
/**
|
|
97
|
-
* Resolve the `planning.taskSizing` operator override the same way the ticket
|
|
98
|
-
* validator does, so an operator who retunes sizing retunes the depth
|
|
99
|
-
* thresholds with it. Reads `config.planning.taskSizing` first, then the
|
|
100
|
-
* legacy `config.agentSettings.planning.taskSizing` nest; absent → `undefined`
|
|
101
|
-
* so {@link resolveDepth} falls back to `DEFAULT_TASK_SIZING`.
|
|
102
|
-
*
|
|
103
|
-
* @param {object|null|undefined} config
|
|
104
|
-
* @returns {object|undefined}
|
|
105
|
-
*/
|
|
106
|
-
function resolveTaskSizing(config) {
|
|
107
|
-
return (
|
|
108
|
-
config?.planning?.taskSizing ??
|
|
109
|
-
config?.agentSettings?.planning?.taskSizing ??
|
|
110
|
-
undefined
|
|
111
|
-
);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* Producer-side resolver (Story #3937, extended by Story #3938): read an
|
|
116
|
-
* Epic's judged `planningRisk` envelope off its `epic-plan-state` checkpoint
|
|
117
|
-
* and resolve the review depth via the shared {@link resolveDepth} resolver.
|
|
118
|
-
* This is the live epic-scope counterpart to `resolveRiskRoutedLenses` in
|
|
119
|
-
* `epic-audit-prepare.js` — it reuses the same best-effort `readPlanState`
|
|
120
|
-
* pattern so the producer never aborts the review on a risk-read failure.
|
|
121
|
-
*
|
|
122
|
-
* Best-effort and total: a missing/unparseable checkpoint, an absent
|
|
123
|
-
* `planningRisk` field, a read failure, or a malformed `overallLevel` all
|
|
124
|
-
* degrade to `standard` (never throws). So an Epic that skipped `/plan`
|
|
125
|
-
* (no checkpoint) still gets a passing `standard` review with no new failure
|
|
126
|
-
* mode. The producer resolves depth from the judged risk alone (the diff is
|
|
127
|
-
* not yet enumerated at this point); the full risk + diff-width combination is
|
|
128
|
-
* applied in `runCodeReview`, which knows the changed-file count. A high-risk
|
|
129
|
-
* Epic resolves to `deep` here; a low-risk one to `light` (the diff width can
|
|
130
|
-
* only escalate, never downgrade, that producer-side resolution).
|
|
131
|
-
*
|
|
132
|
-
* @param {{
|
|
133
|
-
* epicId: number,
|
|
134
|
-
* provider: object,
|
|
135
|
-
* readPlanState?: typeof readPlanState,
|
|
136
|
-
* }} params
|
|
137
|
-
* @returns {Promise<ReviewDepth>}
|
|
138
|
-
*/
|
|
139
|
-
export async function resolveReviewDepthForEpic({
|
|
140
|
-
epicId,
|
|
141
|
-
provider,
|
|
142
|
-
readPlanState: readPlanStateFn = readPlanState,
|
|
143
|
-
}) {
|
|
144
|
-
let state = null;
|
|
145
|
-
try {
|
|
146
|
-
state = await readPlanStateFn({ provider, epicId });
|
|
147
|
-
} catch {
|
|
148
|
-
// A read failure (provider error, malformed comment) must not abort the
|
|
149
|
-
// review. Degrade to the neutral `standard` depth.
|
|
150
|
-
return 'standard';
|
|
151
|
-
}
|
|
152
|
-
return resolveDepth({ overallLevel: state?.planningRisk?.overallLevel });
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
/**
|
|
156
|
-
* The axes whose presence (at `high` risk) routes a specific post-delivery
|
|
157
|
-
* audit lens. Mirrors the audit-workflow names under
|
|
158
|
-
* `.agents/workflows/audit-*.md`. Story #3939 broadened the routing so every
|
|
159
|
-
* high-risk REQUIRED axis maps to a lens rather than leaving three of them
|
|
160
|
-
* (`data-migration`, `destructive-mutation`, `billing`) routing nothing:
|
|
161
|
-
*
|
|
162
|
-
* - `security` → `audit-security` (auth/secret boundary)
|
|
163
|
-
* - `public-api` → `audit-architecture` (the canonical
|
|
164
|
-
* architectural axis; a breaking public surface)
|
|
165
|
-
* - `data-migration` → `audit-quality` (migration correctness +
|
|
166
|
-
* regression coverage)
|
|
167
|
-
* - `destructive-mutation` → `audit-security` (irreversible mutation is
|
|
168
|
-
* an auth/abuse boundary; co-routes with
|
|
169
|
-
* `security`, de-duplicated)
|
|
170
|
-
* - `billing` → `audit-privacy` (money + the PII/consent
|
|
171
|
-
* surface that travels with it)
|
|
172
|
-
* - `critical-workflow` → `audit-quality` (the load-bearing path
|
|
173
|
-
* warrants the deepest coverage pass)
|
|
174
|
-
*
|
|
175
|
-
* The `visible-behavior` axis intentionally routes NO lens: it forces the
|
|
176
|
-
* acceptance-spec disposition at plan time and no audit lens maps cleanly to
|
|
177
|
-
* it. Any other axis (or a low/medium-risk axis) contributes no lens.
|
|
178
|
-
*
|
|
179
|
-
* Every key here MUST be a value in the `axis` enum of
|
|
180
|
-
* `.agents/schemas/risk-verdict.schema.json` — the verdict-derived envelope
|
|
181
|
-
* can only ever carry schema-valid axes, so a key absent from that enum is
|
|
182
|
-
* unreachable dead routing (Story #3889 removed the unreachable
|
|
183
|
-
* `architecture` key; the architectural axis is `public-api`).
|
|
184
|
-
*/
|
|
185
|
-
const AXIS_TO_LENS = Object.freeze({
|
|
186
|
-
security: 'audit-security',
|
|
187
|
-
'public-api': 'audit-architecture',
|
|
188
|
-
'data-migration': 'audit-quality',
|
|
189
|
-
'destructive-mutation': 'audit-security',
|
|
190
|
-
billing: 'audit-privacy',
|
|
191
|
-
'critical-workflow': 'audit-quality',
|
|
192
|
-
});
|
|
193
|
-
|
|
194
|
-
/**
|
|
195
|
-
* Stable output order for routed lenses so the lens list is deterministic
|
|
196
|
-
* regardless of axis ordering in the verdict. Every lens any axis can route
|
|
197
|
-
* appears here exactly once; `resolveAuditLenses` filters this canonical
|
|
198
|
-
* order down to the matched set (Story #3939).
|
|
199
|
-
*/
|
|
200
|
-
const LENS_ORDER = Object.freeze([
|
|
201
|
-
'audit-security',
|
|
202
|
-
'audit-architecture',
|
|
203
|
-
'audit-quality',
|
|
204
|
-
'audit-privacy',
|
|
205
|
-
]);
|
|
206
|
-
|
|
207
|
-
/**
|
|
208
|
-
* Resolve the set of post-delivery audit lenses a judged risk envelope routes.
|
|
209
|
-
*
|
|
210
|
-
* High-risk axes map to their audit lens via {@link AXIS_TO_LENS}; only axes
|
|
211
|
-
* judged `high` contribute (a `low`/`medium` axis carries no lens). The result
|
|
212
|
-
* is de-duplicated and stably ordered by {@link LENS_ORDER} so an envelope
|
|
213
|
-
* listing the `public-api` axis more than once routes `['audit-architecture']`
|
|
214
|
-
* once, not twice — and two distinct axes routing the same lens (e.g.
|
|
215
|
-
* `security` + `destructive-mutation` both → `audit-security`) collapse to a
|
|
216
|
-
* single entry. A low-risk envelope — or any envelope with no high-risk routed
|
|
217
|
-
* axis — resolves to an empty array (no lens beyond the existing baseline
|
|
218
|
-
* gates).
|
|
219
|
-
*
|
|
220
|
-
* Pure function — no I/O, no side effects.
|
|
221
|
-
*
|
|
222
|
-
* @param {{ axes?: Array<{ axis?: string, level?: string }> }} [envelope]
|
|
223
|
-
* @returns {string[]} Ordered, de-duplicated audit-lens identifiers.
|
|
224
|
-
*/
|
|
225
|
-
export function resolveAuditLenses(envelope = {}) {
|
|
226
|
-
const axes = Array.isArray(envelope?.axes) ? envelope.axes : [];
|
|
227
|
-
const matched = new Set();
|
|
228
|
-
for (const entry of axes) {
|
|
229
|
-
if (!entry || entry.level !== 'high') continue;
|
|
230
|
-
const lens = AXIS_TO_LENS[entry.axis];
|
|
231
|
-
if (lens) matched.add(lens);
|
|
232
|
-
}
|
|
233
|
-
return LENS_ORDER.filter((lens) => matched.has(lens));
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
/**
|
|
237
|
-
* Compose the Epic-close (gate3) lens roster from the change-set selection
|
|
238
|
-
* plus every risk-routed lens.
|
|
239
|
-
*
|
|
240
|
-
* STOPGAP (post-#4405 review finding): Story #4412 excluded every
|
|
241
|
-
* `local`-tier change-set lens here on the premise that the Story-scope
|
|
242
|
-
* local-lens pass (Story #4409) verifies those concerns shift-left. That
|
|
243
|
-
* premise does not hold yet — `runLocalLensReview`
|
|
244
|
-
* (story-close/phases/code-review.js) materializes lens bodies with no
|
|
245
|
-
* `artifactPrefix` (so no content persists) and no consumer acts on its
|
|
246
|
-
* result, which left change-set lenses (security, privacy, performance,
|
|
247
|
-
* quality, …) executed by NO reviewer at ANY tier. Local-tier lenses are
|
|
248
|
-
* therefore KEPT at Epic close until the story-scope pass has a real
|
|
249
|
-
* consumer; re-enable the exclusion then (tracked as a follow-up issue).
|
|
250
|
-
* The write-time maker checklists (#4410) are advisory self-checks, not
|
|
251
|
-
* verification. The `resolveLensTierFn` seam is retained so the
|
|
252
|
-
* re-exclusion is a one-line revert.
|
|
253
|
-
*
|
|
254
|
-
* The two inputs mirror the `epic-audit-prepare.js` envelope:
|
|
255
|
-
* - `changeSetAudits` — the raw change-set gate3 selection, kept in full
|
|
256
|
-
* (see the stopgap note above).
|
|
257
|
-
* - `riskRoutedAudits` — the verdict-routed high-risk lenses plus the
|
|
258
|
-
* route-glob navigability lens. Kept in **full**, regardless of tier: a
|
|
259
|
-
* high-risk axis (or a route-adding change set) that demands a local-tier
|
|
260
|
-
* lens still runs it at Epic close, because that demand is the whole point
|
|
261
|
-
* of risk routing.
|
|
262
|
-
*
|
|
263
|
-
* De-duplicated and order-preserving (kept change-set lenses first, then the
|
|
264
|
-
* risk-routed extras). Pure over the injected `resolveLensTierFn` seam; the
|
|
265
|
-
* default resolver reads `audit-rules.json` from disk.
|
|
266
|
-
*
|
|
267
|
-
* @param {{
|
|
268
|
-
* changeSetAudits?: string[],
|
|
269
|
-
* riskRoutedAudits?: string[],
|
|
270
|
-
* resolveLensTierFn?: typeof resolveLensTier,
|
|
271
|
-
* }} [params]
|
|
272
|
-
* @returns {string[]} The Epic-close roster (all change-set tiers +
|
|
273
|
-
* risk-routed; local-tier exclusion suspended per the stopgap above).
|
|
274
|
-
*/
|
|
275
|
-
export function selectEpicCloseLenses({
|
|
276
|
-
changeSetAudits = [],
|
|
277
|
-
riskRoutedAudits = [],
|
|
278
|
-
resolveLensTierFn = resolveLensTier,
|
|
279
|
-
} = {}) {
|
|
280
|
-
const kept = [];
|
|
281
|
-
const seen = new Set();
|
|
282
|
-
const add = (lens) => {
|
|
283
|
-
if (typeof lens !== 'string' || lens.length === 0 || seen.has(lens)) return;
|
|
284
|
-
seen.add(lens);
|
|
285
|
-
kept.push(lens);
|
|
286
|
-
};
|
|
287
|
-
for (const lens of Array.isArray(changeSetAudits) ? changeSetAudits : []) {
|
|
288
|
-
if (typeof lens !== 'string' || lens.length === 0) continue;
|
|
289
|
-
// Stopgap: keep local-tier lenses (see docstring). The tier seam is
|
|
290
|
-
// deliberately untouched so restoring `=== 'local' → continue` is a
|
|
291
|
-
// one-line revert once the story-scope tier has a real consumer.
|
|
292
|
-
void resolveLensTierFn;
|
|
293
|
-
add(lens);
|
|
294
|
-
}
|
|
295
|
-
for (const lens of Array.isArray(riskRoutedAudits) ? riskRoutedAudits : []) {
|
|
296
|
-
add(lens);
|
|
297
|
-
}
|
|
298
|
-
return kept;
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
/**
|
|
302
|
-
* Build the post-delivery audit-lens execution plan for a judged risk
|
|
303
|
-
* envelope. Each routed lens (see {@link resolveAuditLenses}) is paired with a
|
|
304
|
-
* strategy decision from the **existing** `selectAuditStrategy` engine — no new
|
|
305
|
-
* audit machinery is introduced. A low-risk envelope resolves to an empty
|
|
306
|
-
* `lenses` array and runs no audit beyond the baseline gates (Story #3876).
|
|
307
|
-
*
|
|
308
|
-
* Pure with respect to the injected `selectAuditStrategyFn` (default is the
|
|
309
|
-
* shared dynamic-workflow engine, which is itself pure over its snapshot).
|
|
310
|
-
*
|
|
311
|
-
* @param {{ axes?: Array<{ axis?: string, level?: string }> }} [envelope]
|
|
312
|
-
* @param {{
|
|
313
|
-
* snapshot?: object,
|
|
314
|
-
* forceStrategy?: ('orchestrated'|'sequential'|null),
|
|
315
|
-
* selectAuditStrategyFn?: typeof selectAuditStrategy,
|
|
316
|
-
* }} [opts]
|
|
317
|
-
* @returns {{ lenses: string[], plan: Array<{ lens: string, strategy: string, reason: string, forced: boolean }> }}
|
|
318
|
-
*/
|
|
319
|
-
export function planAuditLenses(envelope = {}, opts = {}) {
|
|
320
|
-
const {
|
|
321
|
-
snapshot = {},
|
|
322
|
-
forceStrategy = null,
|
|
323
|
-
selectAuditStrategyFn = selectAuditStrategy,
|
|
324
|
-
} = opts;
|
|
325
|
-
const lenses = resolveAuditLenses(envelope);
|
|
326
|
-
const plan = lenses.map((lens) => {
|
|
327
|
-
const decision = selectAuditStrategyFn({ snapshot, forceStrategy });
|
|
328
|
-
return {
|
|
329
|
-
lens,
|
|
330
|
-
strategy: decision.strategy,
|
|
331
|
-
reason: decision.reason,
|
|
332
|
-
forced: decision.forced,
|
|
333
|
-
};
|
|
334
|
-
});
|
|
335
|
-
return { lenses, plan };
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
/**
|
|
339
|
-
* Build the `code-review.end` payload from the normalized result envelope.
|
|
340
|
-
* The runner result may carry a `report` field (full markdown body) which
|
|
341
|
-
* is NOT included in the lifecycle payload: the schema's
|
|
342
|
-
* `additionalProperties: false` forbids it, and the body can carry inline
|
|
343
|
-
* severity counts that drift from the structured `severity` field. The
|
|
344
|
-
* lifecycle ledger is the structured surface; the report is GitHub's
|
|
345
|
-
* surface (posted via the structured comment).
|
|
346
|
-
*
|
|
347
|
-
* Story #2839: `epicId` is preserved verbatim in the lifecycle payload so
|
|
348
|
-
* the `code-review.end` schema (additionalProperties: false, requires
|
|
349
|
-
* `epicId`) stays unchanged. Story-scope invocations never reach this
|
|
350
|
-
* helper — `runCodeReview` short-circuits the bus emit for `scope: 'story'`
|
|
351
|
-
* because story-scope review sits outside the Epic lifecycle ledger.
|
|
352
|
-
*/
|
|
353
|
-
function buildCodeReviewEndPayload({ epicId, result, durationMs }) {
|
|
354
|
-
const payload = {
|
|
355
|
-
epicId,
|
|
356
|
-
status: result.status,
|
|
357
|
-
};
|
|
358
|
-
if (result.severity && typeof result.severity === 'object') {
|
|
359
|
-
payload.severity = {
|
|
360
|
-
critical: result.severity.critical ?? 0,
|
|
361
|
-
high: result.severity.high ?? 0,
|
|
362
|
-
medium: result.severity.medium ?? 0,
|
|
363
|
-
suggestion: result.severity.suggestion ?? 0,
|
|
364
|
-
};
|
|
365
|
-
}
|
|
366
|
-
if (typeof result.halted === 'boolean') payload.halted = result.halted;
|
|
367
|
-
if (typeof result.posted === 'boolean') payload.posted = result.posted;
|
|
368
|
-
if (Number.isFinite(durationMs) && durationMs >= 0) {
|
|
369
|
-
payload.durationMs = Math.floor(durationMs);
|
|
370
|
-
}
|
|
371
|
-
return payload;
|
|
372
|
-
}
|
|
373
|
-
|
|
374
98
|
/**
|
|
375
99
|
* Resolve the project base branch fallback used when a caller omits
|
|
376
100
|
* `baseRef`.
|
|
377
101
|
*/
|
|
378
102
|
function resolveConfigBase(config) {
|
|
379
|
-
return
|
|
380
|
-
config?.project?.baseBranch ?? config?.agentSettings?.baseBranch ?? 'main'
|
|
381
|
-
);
|
|
103
|
+
return config?.project?.baseBranch ?? 'main';
|
|
382
104
|
}
|
|
383
105
|
|
|
384
106
|
/** Positive-integer override, else the supplied default. */
|
|
@@ -398,7 +120,6 @@ function resolveCommentTargetId(commentTargetId, fallback) {
|
|
|
398
120
|
* baseRef: string,
|
|
399
121
|
* headRef: string,
|
|
400
122
|
* commentTargetId: number,
|
|
401
|
-
* epicIdForLedger: null,
|
|
402
123
|
* }}
|
|
403
124
|
*/
|
|
404
125
|
function resolveStoryScope(opts, config) {
|
|
@@ -421,53 +142,16 @@ function resolveStoryScope(opts, config) {
|
|
|
421
142
|
opts.commentTargetId,
|
|
422
143
|
opts.ticketId,
|
|
423
144
|
),
|
|
424
|
-
epicIdForLedger: null,
|
|
425
145
|
};
|
|
426
146
|
}
|
|
427
147
|
|
|
428
148
|
/**
|
|
429
|
-
* Resolve the
|
|
430
|
-
* `{ scope
|
|
431
|
-
*
|
|
432
|
-
* base branch.
|
|
433
|
-
*
|
|
434
|
-
* @returns {{
|
|
435
|
-
* scope: 'epic',
|
|
436
|
-
* ticketId: number,
|
|
437
|
-
* baseRef: string,
|
|
438
|
-
* headRef: string,
|
|
439
|
-
* commentTargetId: number,
|
|
440
|
-
* epicIdForLedger: number,
|
|
441
|
-
* }}
|
|
442
|
-
*/
|
|
443
|
-
function resolveEpicScope(opts, config) {
|
|
444
|
-
if (!Number.isInteger(opts.ticketId) || opts.ticketId <= 0) {
|
|
445
|
-
throw new TypeError(
|
|
446
|
-
'runCodeReview: ticketId is required (positive integer) when scope="epic".',
|
|
447
|
-
);
|
|
448
|
-
}
|
|
449
|
-
return {
|
|
450
|
-
scope: 'epic',
|
|
451
|
-
ticketId: opts.ticketId,
|
|
452
|
-
baseRef: opts.baseRef ?? resolveConfigBase(config),
|
|
453
|
-
headRef: opts.headRef ?? `epic/${opts.ticketId}`,
|
|
454
|
-
commentTargetId: resolveCommentTargetId(
|
|
455
|
-
opts.commentTargetId,
|
|
456
|
-
opts.ticketId,
|
|
457
|
-
),
|
|
458
|
-
epicIdForLedger: opts.ticketId,
|
|
459
|
-
};
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
/**
|
|
463
|
-
* Dispatch the parameterized scope envelope
|
|
464
|
-
* (`{ scope, ticketId, baseRef, headRef, commentTargetId }`) to the
|
|
465
|
-
* matching pure resolver. `scope` defaults to `'epic'`.
|
|
149
|
+
* Resolve the scope envelope
|
|
150
|
+
* (`{ scope, ticketId, baseRef, headRef, commentTargetId }`). v2.0.0
|
|
151
|
+
* removed the Epic tier, so `'story'` is the only scope.
|
|
466
152
|
*/
|
|
467
153
|
function resolveScopeEnvelope(opts, config) {
|
|
468
|
-
return opts
|
|
469
|
-
? resolveStoryScope(opts, config)
|
|
470
|
-
: resolveEpicScope(opts, config);
|
|
154
|
+
return resolveStoryScope(opts, config);
|
|
471
155
|
}
|
|
472
156
|
|
|
473
157
|
/**
|
|
@@ -485,36 +169,28 @@ function resolveScopeEnvelope(opts, config) {
|
|
|
485
169
|
* derived from the `Finding[]` returned by the adapter (no separate
|
|
486
170
|
* severity field on the runner result).
|
|
487
171
|
*
|
|
488
|
-
* Story #2839 (Epic #2815) —
|
|
489
|
-
*
|
|
490
|
-
*
|
|
491
|
-
*
|
|
492
|
-
* caller as `halted: true`. Lifecycle bus emits are confined to
|
|
493
|
-
* `scope: 'epic'` because the `code-review.end` schema requires
|
|
494
|
-
* `epicId` and the ledger only spans Epic lifecycles.
|
|
172
|
+
* Story #2839 (Epic #2815) — the Story closer requests a Story-scope
|
|
173
|
+
* review against `main`, posts the structured findings comment to the PR
|
|
174
|
+
* (via `commentTargetId`), and surfaces critical findings to the caller
|
|
175
|
+
* as `halted: true`.
|
|
495
176
|
*
|
|
496
|
-
* Argument shape
|
|
497
|
-
* `{
|
|
498
|
-
*
|
|
499
|
-
* `
|
|
500
|
-
*
|
|
501
|
-
* For `scope === 'story'`, `commentTargetId` overrides the post
|
|
502
|
-
* target (e.g. PR number) while `ticketId` continues to label the
|
|
503
|
-
* rendered header ("Story #N").
|
|
177
|
+
* Argument shape:
|
|
178
|
+
* `{ ticketId, baseRef, headRef, [commentTargetId], provider }`
|
|
179
|
+
* `baseRef` defaults to the project base branch; `headRef` is required.
|
|
180
|
+
* `commentTargetId` overrides the post target (e.g. PR number) while
|
|
181
|
+
* `ticketId` continues to label the rendered header ("Story #N").
|
|
504
182
|
*
|
|
505
183
|
* @param {{
|
|
506
|
-
* scope?: '
|
|
184
|
+
* scope?: 'story',
|
|
507
185
|
* ticketId: number,
|
|
508
186
|
* baseRef?: string|null,
|
|
509
187
|
* headRef?: string|null,
|
|
510
188
|
* commentTargetId?: number|null,
|
|
511
189
|
* provider: object,
|
|
512
190
|
* logger?: { info?: Function, warn?: Function, error?: Function, fatal?: Function, createProgress?: Function },
|
|
513
|
-
*
|
|
191
|
+
* changedFiles?: string[]|null,
|
|
514
192
|
* changedFileCount?: number|null,
|
|
515
193
|
* storyId?: number|null,
|
|
516
|
-
* bus?: object|null,
|
|
517
|
-
* now?: () => number,
|
|
518
194
|
* reviewProvider?: { runReview: Function },
|
|
519
195
|
* gitSpawnFn?: typeof gitSpawn,
|
|
520
196
|
* resolveConfigFn?: typeof resolveConfig,
|
|
@@ -535,44 +211,47 @@ function resolveScopeEnvelope(opts, config) {
|
|
|
535
211
|
*/
|
|
536
212
|
/**
|
|
537
213
|
* Resolve the human-facing provider name from the resolved code-review
|
|
538
|
-
* config.
|
|
539
|
-
*
|
|
540
|
-
*
|
|
214
|
+
* config. Multi-entry chains render as `chain[a,b,...]`; a single-entry
|
|
215
|
+
* chain (including the unset/empty default) renders that entry's name;
|
|
216
|
+
* everything else falls back to `'native'`.
|
|
541
217
|
*/
|
|
542
218
|
function resolveProviderName(codeReviewConfig) {
|
|
543
|
-
const
|
|
544
|
-
codeReviewConfig &&
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
if (
|
|
548
|
-
return
|
|
549
|
-
.map((p) => p?.name ?? '?')
|
|
550
|
-
.join(',')}]`;
|
|
219
|
+
const providers =
|
|
220
|
+
codeReviewConfig && Array.isArray(codeReviewConfig.providers)
|
|
221
|
+
? codeReviewConfig.providers
|
|
222
|
+
: [];
|
|
223
|
+
if (providers.length === 1) {
|
|
224
|
+
return providers[0]?.name ?? 'native';
|
|
551
225
|
}
|
|
552
|
-
|
|
553
|
-
(
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
);
|
|
226
|
+
if (providers.length > 1) {
|
|
227
|
+
return `chain[${providers.map((p) => p?.name ?? '?').join(',')}]`;
|
|
228
|
+
}
|
|
229
|
+
return 'native';
|
|
557
230
|
}
|
|
558
231
|
|
|
559
232
|
/**
|
|
560
233
|
* Build the provider `runReview` input, resolving the review depth from the
|
|
561
|
-
*
|
|
562
|
-
*
|
|
563
|
-
* input-only signal (light → standard → deep) and never touches the
|
|
564
|
-
* envelope or the posted comment.
|
|
565
|
-
*
|
|
234
|
+
* diff under review: its changed files derive the change level (sensitive path
|
|
235
|
+
* touched or not — Story #4542) and their count supplies the width. The depth
|
|
236
|
+
* is an input-only signal (light → standard → deep) and never touches the
|
|
237
|
+
* output envelope or the posted comment. An unenumerable diff → `standard`.
|
|
238
|
+
* Story #4075 — extracted from `runCodeReview`.
|
|
566
239
|
*/
|
|
567
|
-
function buildReviewInput({ opts,
|
|
240
|
+
function buildReviewInput({ opts, scope, ticketId, baseRef, headRef }) {
|
|
241
|
+
const changedFiles = Array.isArray(opts.changedFiles)
|
|
242
|
+
? opts.changedFiles
|
|
243
|
+
: listChangedFiles({ baseRef, headRef, gitSpawnFn: opts.gitSpawnFn });
|
|
568
244
|
const changedFileCount =
|
|
569
245
|
typeof opts.changedFileCount === 'number'
|
|
570
246
|
? opts.changedFileCount
|
|
571
|
-
:
|
|
247
|
+
: (changedFiles?.length ?? null);
|
|
248
|
+
// v2 Stage 2: review depth uses DEFAULT_DIFF_WIDTH (mechanical file count
|
|
249
|
+
// of the diff under review). It is deliberately decoupled from the
|
|
250
|
+
// planning model-capacity advisory (`DEFAULT_MODEL_CAPACITY`).
|
|
251
|
+
const { level } = deriveChangeLevel({ changedFiles });
|
|
572
252
|
const depth = resolveDepth({
|
|
573
|
-
|
|
253
|
+
derivedLevel: level,
|
|
574
254
|
changedFileCount,
|
|
575
|
-
sizing: resolveTaskSizing(config),
|
|
576
255
|
});
|
|
577
256
|
return {
|
|
578
257
|
scope,
|
|
@@ -665,12 +344,11 @@ async function executeReviewPipeline({ opts, config, envelope }) {
|
|
|
665
344
|
injectedReviewProvider ?? createReviewProviderFn(codeReviewConfig);
|
|
666
345
|
|
|
667
346
|
logger?.info?.(
|
|
668
|
-
`[code-review] Running ${providerName} adapter for
|
|
347
|
+
`[code-review] Running ${providerName} adapter for Story #${ticketId} (${baseRef}...${headRef})...`,
|
|
669
348
|
);
|
|
670
349
|
|
|
671
350
|
const reviewInput = buildReviewInput({
|
|
672
351
|
opts,
|
|
673
|
-
config,
|
|
674
352
|
scope,
|
|
675
353
|
ticketId,
|
|
676
354
|
baseRef,
|
|
@@ -725,49 +403,13 @@ async function executeReviewPipeline({ opts, config, envelope }) {
|
|
|
725
403
|
}
|
|
726
404
|
|
|
727
405
|
export async function runCodeReview(opts = {}) {
|
|
728
|
-
const {
|
|
406
|
+
const { resolveConfigFn = resolveConfig } = opts;
|
|
729
407
|
|
|
730
408
|
const config = resolveConfigFn();
|
|
731
409
|
const envelope = resolveScopeEnvelope(opts, config);
|
|
732
|
-
const { scope } = envelope;
|
|
733
|
-
|
|
734
|
-
// Epic-scope lifecycle ledger requires `bus`; Story-scope sits outside
|
|
735
|
-
// the Epic lifecycle so the bus is optional there. A caller without a
|
|
736
|
-
// bus on the Story path still gets the full review semantics — only the
|
|
737
|
-
// `code-review.start`/`.end` events are suppressed.
|
|
738
|
-
if (scope === 'epic' && (!bus || typeof bus.emit !== 'function')) {
|
|
739
|
-
throw new TypeError('runCodeReview: bus is required (object with emit()).');
|
|
740
|
-
}
|
|
741
|
-
const ledgerEnabled =
|
|
742
|
-
scope === 'epic' && bus && typeof bus.emit === 'function';
|
|
743
|
-
|
|
744
|
-
const startedAt = typeof now === 'function' ? now() : Date.now();
|
|
745
|
-
// Emit the matched `code-review.end` boundary; the ledger must always
|
|
746
|
-
// show a start/end pair (even on adapter throw, where `result` is the
|
|
747
|
-
// canonical `{ status: 'invalid' }`).
|
|
748
|
-
const emitEnd = async (result) => {
|
|
749
|
-
if (!ledgerEnabled) return;
|
|
750
|
-
const endedAt = typeof now === 'function' ? now() : Date.now();
|
|
751
|
-
await bus.emit(
|
|
752
|
-
'code-review.end',
|
|
753
|
-
buildCodeReviewEndPayload({
|
|
754
|
-
epicId: envelope.epicIdForLedger,
|
|
755
|
-
result,
|
|
756
|
-
durationMs: Math.max(0, endedAt - startedAt),
|
|
757
|
-
}),
|
|
758
|
-
);
|
|
759
|
-
};
|
|
760
|
-
|
|
761
|
-
if (ledgerEnabled) {
|
|
762
|
-
await bus.emit('code-review.start', { epicId: envelope.epicIdForLedger });
|
|
763
|
-
}
|
|
764
410
|
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
} catch (err) {
|
|
770
|
-
await emitEnd({ status: 'invalid' });
|
|
771
|
-
throw err;
|
|
772
|
-
}
|
|
411
|
+
// No lifecycle-bus emit: the `code-review.start` / `.end` ledger pair was
|
|
412
|
+
// Epic-scoped (its schema requires `epicId`), and v2.0.0 removed the Epic
|
|
413
|
+
// tier. Story-scope review sits outside the lifecycle ledger entirely.
|
|
414
|
+
return executeReviewPipeline({ opts, config, envelope });
|
|
773
415
|
}
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
* Located at `lib/orchestration/column-sync.js` (Story #2548) so the
|
|
29
29
|
* canonical state mutator `transitionTicketState`
|
|
30
30
|
* (`lib/orchestration/ticketing/state.js`) can invoke it without an
|
|
31
|
-
* upward dependency into `epic-runner
|
|
31
|
+
* upward dependency into the deleted `epic-runner/` tree. Prior to #2548 this module
|
|
32
32
|
* lived under `epic-runner/` and was only wired against the Epic
|
|
33
33
|
* ticket — Stories and Tasks never updated their Projects v2 Status
|
|
34
34
|
* column on label flips.
|