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
|
@@ -42,7 +42,8 @@
|
|
|
42
42
|
* @property {string} [summary]
|
|
43
43
|
*
|
|
44
44
|
* @typedef {Object} RoutedProposalsInput
|
|
45
|
-
* @property {number}
|
|
45
|
+
* @property {number} anchorId Story or run/Epic id in titles.
|
|
46
|
+
* @property {'story'|'run'} [anchorKind] Wording in titles/bodies (default `story`).
|
|
46
47
|
* @property {string} frameworkRepo `"<owner>/<repo>"`.
|
|
47
48
|
* @property {string} consumerRepo `"<owner>/<repo>"`.
|
|
48
49
|
* @property {FrictionSignal[]} [signals]
|
|
@@ -142,23 +143,53 @@ function dominantSource(entry) {
|
|
|
142
143
|
return entry.firstSource;
|
|
143
144
|
}
|
|
144
145
|
|
|
146
|
+
/**
|
|
147
|
+
* @param {'story'|'run'} kind
|
|
148
|
+
* @param {number} id
|
|
149
|
+
* @returns {string}
|
|
150
|
+
*/
|
|
151
|
+
function formatAnchor(kind, id) {
|
|
152
|
+
if (kind === 'story') return `Story #${id}`;
|
|
153
|
+
if (kind === 'run') return `plan-run ${id}`;
|
|
154
|
+
return `Epic #${id}`;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/** Story scope promotes single-occurrence friction; run keeps ≥2. */
|
|
158
|
+
function isActionableFriction(total, force, anchorKind) {
|
|
159
|
+
const threshold = anchorKind === 'story' ? 1 : 2;
|
|
160
|
+
return total >= threshold || Boolean(force);
|
|
161
|
+
}
|
|
162
|
+
|
|
145
163
|
/**
|
|
146
164
|
* Render the issue body. Plain text — no markdown headings — so the
|
|
147
165
|
* pre-drafted `gh issue create --body-file` heredoc remains a faithful
|
|
148
166
|
* representation of what the operator would paste.
|
|
149
167
|
*
|
|
150
|
-
* @param {{
|
|
168
|
+
* @param {{
|
|
169
|
+
* anchorId: number,
|
|
170
|
+
* anchorKind: 'story'|'run',
|
|
171
|
+
* category: string,
|
|
172
|
+
* occurrences: number,
|
|
173
|
+
* source: "framework"|"consumer",
|
|
174
|
+
* }} args
|
|
151
175
|
* @returns {string}
|
|
152
176
|
*/
|
|
153
|
-
function renderIssueBody({
|
|
177
|
+
function renderIssueBody({
|
|
178
|
+
anchorId,
|
|
179
|
+
anchorKind,
|
|
180
|
+
category,
|
|
181
|
+
occurrences,
|
|
182
|
+
source,
|
|
183
|
+
}) {
|
|
184
|
+
const anchor = formatAnchor(anchorKind, anchorId);
|
|
154
185
|
return [
|
|
155
|
-
`Recurring friction category "${category}" surfaced ${occurrences} times during
|
|
186
|
+
`Recurring friction category "${category}" surfaced ${occurrences} times during ${anchor}.`,
|
|
156
187
|
'',
|
|
157
188
|
`Source classification: ${source}.`,
|
|
158
189
|
'',
|
|
159
|
-
'Captured by the
|
|
190
|
+
'Captured by the follow-up composer. Triage and either:',
|
|
160
191
|
`- File a follow-on Story to address the underlying ${source} gap, or`,
|
|
161
|
-
|
|
192
|
+
`- Close with "wontfix" and document the rationale on ${anchor}.`,
|
|
162
193
|
].join('\n');
|
|
163
194
|
}
|
|
164
195
|
|
|
@@ -193,7 +224,8 @@ function renderIssueCommand({ repo, title, metaLabel, category, body }) {
|
|
|
193
224
|
* Build an actionable RoutedItem for a category.
|
|
194
225
|
*
|
|
195
226
|
* @param {{
|
|
196
|
-
*
|
|
227
|
+
* anchorId: number,
|
|
228
|
+
* anchorKind: 'story'|'run',
|
|
197
229
|
* category: string,
|
|
198
230
|
* occurrences: number,
|
|
199
231
|
* source: "framework"|"consumer",
|
|
@@ -203,15 +235,23 @@ function renderIssueCommand({ repo, title, metaLabel, category, body }) {
|
|
|
203
235
|
* @returns {RoutedItem}
|
|
204
236
|
*/
|
|
205
237
|
function buildRoutedItem({
|
|
206
|
-
|
|
238
|
+
anchorId,
|
|
239
|
+
anchorKind,
|
|
207
240
|
category,
|
|
208
241
|
occurrences,
|
|
209
242
|
source,
|
|
210
243
|
frameworkRepo,
|
|
211
244
|
consumerRepo,
|
|
212
245
|
}) {
|
|
213
|
-
const
|
|
214
|
-
const
|
|
246
|
+
const anchor = formatAnchor(anchorKind, anchorId);
|
|
247
|
+
const title = `Friction: ${category} recurred ${occurrences} times in ${anchor}`;
|
|
248
|
+
const body = renderIssueBody({
|
|
249
|
+
anchorId,
|
|
250
|
+
anchorKind,
|
|
251
|
+
category,
|
|
252
|
+
occurrences,
|
|
253
|
+
source,
|
|
254
|
+
});
|
|
215
255
|
const repo = source === 'framework' ? frameworkRepo : consumerRepo;
|
|
216
256
|
const metaLabel =
|
|
217
257
|
source === 'framework' ? 'framework-gap' : 'consumer-improvement';
|
|
@@ -231,23 +271,29 @@ function buildRoutedItem({
|
|
|
231
271
|
*
|
|
232
272
|
* @param {unknown} input
|
|
233
273
|
* @returns {{
|
|
234
|
-
*
|
|
274
|
+
* anchorId: number,
|
|
275
|
+
* anchorKind: 'story'|'run',
|
|
235
276
|
* frameworkRepo: string,
|
|
236
277
|
* consumerRepo: string,
|
|
237
278
|
* signals: FrictionSignal[],
|
|
238
279
|
* unresolvedBlockedEvents: BlockedEvent[],
|
|
239
280
|
* } | null}
|
|
240
281
|
*/
|
|
282
|
+
function normalizeAnchorKind(kind) {
|
|
283
|
+
return kind === 'story' || kind === 'run' ? kind : 'story';
|
|
284
|
+
}
|
|
285
|
+
|
|
241
286
|
function normaliseInput(input) {
|
|
242
287
|
if (input === null || typeof input !== 'object') return null;
|
|
243
288
|
const record = /** @type {RoutedProposalsInput} */ (input);
|
|
244
|
-
const
|
|
245
|
-
if (!Number.isInteger(
|
|
289
|
+
const anchorId = Number(record.anchorId);
|
|
290
|
+
if (!Number.isInteger(anchorId) || anchorId <= 0) return null;
|
|
246
291
|
const frameworkRepo = asString(record.frameworkRepo);
|
|
247
292
|
const consumerRepo = asString(record.consumerRepo);
|
|
248
|
-
if (frameworkRepo
|
|
293
|
+
if (!frameworkRepo || !consumerRepo) return null;
|
|
249
294
|
return {
|
|
250
|
-
|
|
295
|
+
anchorId,
|
|
296
|
+
anchorKind: normalizeAnchorKind(record.anchorKind),
|
|
251
297
|
frameworkRepo,
|
|
252
298
|
consumerRepo,
|
|
253
299
|
signals: Array.isArray(record.signals) ? record.signals : [],
|
|
@@ -257,35 +303,7 @@ function normaliseInput(input) {
|
|
|
257
303
|
};
|
|
258
304
|
}
|
|
259
305
|
|
|
260
|
-
|
|
261
|
-
* Compose the four routed proposal sections from aggregated source-tagged
|
|
262
|
-
* signals.
|
|
263
|
-
*
|
|
264
|
-
* Pure — no I/O, no time-dependent state, no provider calls. Returns an
|
|
265
|
-
* object with three arrays:
|
|
266
|
-
* - `framework`: actionable items routed to the framework repo.
|
|
267
|
-
* - `consumer`: actionable items routed to the consumer repo.
|
|
268
|
-
* - `discarded`: single-occurrence friction with no follow-on signal.
|
|
269
|
-
*
|
|
270
|
-
* @param {RoutedProposalsInput} input
|
|
271
|
-
* @returns {RoutedProposals}
|
|
272
|
-
*/
|
|
273
|
-
export function composeRoutedProposals(input) {
|
|
274
|
-
const normalised = normaliseInput(input);
|
|
275
|
-
if (normalised === null) return emptyResult();
|
|
276
|
-
const {
|
|
277
|
-
epicId,
|
|
278
|
-
frameworkRepo,
|
|
279
|
-
consumerRepo,
|
|
280
|
-
signals,
|
|
281
|
-
unresolvedBlockedEvents,
|
|
282
|
-
} = normalised;
|
|
283
|
-
|
|
284
|
-
const byCategory = aggregateByCategory(signals);
|
|
285
|
-
|
|
286
|
-
// Unresolved agent::blocked events always promote their category to
|
|
287
|
-
// actionable — even if the friction count is < 2. The event itself
|
|
288
|
-
// doesn't count as a friction occurrence; we treat it as a force-flag.
|
|
306
|
+
function blockedForceMap(unresolvedBlockedEvents) {
|
|
289
307
|
/** @type {Map<string, { source: "framework"|"consumer" }>} */
|
|
290
308
|
const blockedForceActionable = new Map();
|
|
291
309
|
for (const evt of unresolvedBlockedEvents) {
|
|
@@ -297,56 +315,99 @@ export function composeRoutedProposals(input) {
|
|
|
297
315
|
blockedForceActionable.set(category, { source });
|
|
298
316
|
}
|
|
299
317
|
}
|
|
318
|
+
return blockedForceActionable;
|
|
319
|
+
}
|
|
300
320
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
/** @type {DiscardedItem[]} */
|
|
306
|
-
const discarded = [];
|
|
321
|
+
function pushRouted(buckets, source, item) {
|
|
322
|
+
if (source === 'framework') buckets.framework.push(item);
|
|
323
|
+
else buckets.consumer.push(item);
|
|
324
|
+
}
|
|
307
325
|
|
|
308
|
-
|
|
326
|
+
function routeCategoryBuckets({
|
|
327
|
+
byCategory,
|
|
328
|
+
blockedForceActionable,
|
|
329
|
+
anchorId,
|
|
330
|
+
anchorKind,
|
|
331
|
+
frameworkRepo,
|
|
332
|
+
consumerRepo,
|
|
333
|
+
}) {
|
|
334
|
+
/** @type {RoutedProposals} */
|
|
335
|
+
const buckets = { framework: [], consumer: [], discarded: [] };
|
|
309
336
|
for (const entry of byCategory.values()) {
|
|
310
337
|
const { category, total } = entry;
|
|
311
338
|
const force = blockedForceActionable.get(category);
|
|
312
339
|
const source = force ? force.source : dominantSource(entry);
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
340
|
+
if (!isActionableFriction(total, force, anchorKind)) {
|
|
341
|
+
buckets.discarded.push({ category, occurrences: total, source });
|
|
342
|
+
continue;
|
|
343
|
+
}
|
|
344
|
+
pushRouted(
|
|
345
|
+
buckets,
|
|
346
|
+
source,
|
|
347
|
+
buildRoutedItem({
|
|
348
|
+
anchorId,
|
|
349
|
+
anchorKind,
|
|
317
350
|
category,
|
|
318
351
|
occurrences: total,
|
|
319
352
|
source,
|
|
320
353
|
frameworkRepo,
|
|
321
354
|
consumerRepo,
|
|
322
|
-
})
|
|
323
|
-
|
|
324
|
-
else consumer.push(item);
|
|
325
|
-
continue;
|
|
326
|
-
}
|
|
327
|
-
// total === 1 AND no force flag → discarded.
|
|
328
|
-
discarded.push({ category, occurrences: total, source });
|
|
355
|
+
}),
|
|
356
|
+
);
|
|
329
357
|
}
|
|
330
|
-
|
|
331
|
-
// Walk blocked-force categories that had NO friction signal at all —
|
|
332
|
-
// these still need an issue proposal (the blocker is the trigger).
|
|
333
358
|
for (const [category, info] of blockedForceActionable) {
|
|
334
359
|
if (byCategory.has(category)) continue;
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
360
|
+
pushRouted(
|
|
361
|
+
buckets,
|
|
362
|
+
info.source,
|
|
363
|
+
buildRoutedItem({
|
|
364
|
+
anchorId,
|
|
365
|
+
anchorKind,
|
|
366
|
+
category,
|
|
367
|
+
occurrences: 0,
|
|
368
|
+
source: info.source,
|
|
369
|
+
frameworkRepo,
|
|
370
|
+
consumerRepo,
|
|
371
|
+
}),
|
|
372
|
+
);
|
|
345
373
|
}
|
|
374
|
+
buckets.framework.sort((a, b) => a.category.localeCompare(b.category));
|
|
375
|
+
buckets.consumer.sort((a, b) => a.category.localeCompare(b.category));
|
|
376
|
+
buckets.discarded.sort((a, b) => a.category.localeCompare(b.category));
|
|
377
|
+
return buckets;
|
|
378
|
+
}
|
|
346
379
|
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
380
|
+
/**
|
|
381
|
+
* Compose the four routed proposal sections from aggregated source-tagged
|
|
382
|
+
* signals.
|
|
383
|
+
*
|
|
384
|
+
* Pure — no I/O, no time-dependent state, no provider calls. Returns an
|
|
385
|
+
* object with three arrays:
|
|
386
|
+
* - `framework`: actionable items routed to the framework repo.
|
|
387
|
+
* - `consumer`: actionable items routed to the consumer repo.
|
|
388
|
+
* - `discarded`: single-occurrence friction with no follow-on signal.
|
|
389
|
+
*
|
|
390
|
+
* @param {RoutedProposalsInput} input
|
|
391
|
+
* @returns {RoutedProposals}
|
|
392
|
+
*/
|
|
393
|
+
export function composeRoutedProposals(input) {
|
|
394
|
+
const normalised = normaliseInput(input);
|
|
395
|
+
if (normalised === null) return emptyResult();
|
|
396
|
+
const {
|
|
397
|
+
anchorId,
|
|
398
|
+
anchorKind,
|
|
399
|
+
frameworkRepo,
|
|
400
|
+
consumerRepo,
|
|
401
|
+
signals,
|
|
402
|
+
unresolvedBlockedEvents,
|
|
403
|
+
} = normalised;
|
|
350
404
|
|
|
351
|
-
return {
|
|
405
|
+
return routeCategoryBuckets({
|
|
406
|
+
byCategory: aggregateByCategory(signals),
|
|
407
|
+
blockedForceActionable: blockedForceMap(unresolvedBlockedEvents),
|
|
408
|
+
anchorId,
|
|
409
|
+
anchorKind,
|
|
410
|
+
frameworkRepo,
|
|
411
|
+
consumerRepo,
|
|
412
|
+
});
|
|
352
413
|
}
|
|
@@ -1,42 +1,117 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* lib/orchestration/review-depth.js —
|
|
3
|
-
*
|
|
2
|
+
* lib/orchestration/review-depth.js — the review-depth authority: derives a
|
|
3
|
+
* change level from observable facts and folds it with diff width into a tier
|
|
4
|
+
* (Story #3938, re-based on a derived signal by Story #4542).
|
|
4
5
|
*
|
|
5
|
-
*
|
|
6
|
-
* signals the framework already computes — the planner-judged risk
|
|
7
|
-
* (`planningRisk.overallLevel`) and the mechanical changed-file count of the
|
|
8
|
-
* diff under review — into one tier (`light` / `standard` / `deep`) without
|
|
9
|
-
* inventing a new complexity score or any new config knob.
|
|
6
|
+
* ## Why the level is derived, not authored
|
|
10
7
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* still resolves to `light` (preserves the #3937 producer
|
|
21
|
-
* contract where depth is resolved from risk before any diff
|
|
22
|
-
* is enumerated).
|
|
23
|
-
* - `standard` — everything else, including absent/malformed risk envelopes
|
|
24
|
-
* and a `medium` level. Fail toward the middle, never toward
|
|
25
|
-
* `light`: an Epic that skipped `/plan` has no risk
|
|
26
|
-
* verdict, and treating it as `light` would under-review
|
|
27
|
-
* unjudged work while `standard` preserves today's behaviour.
|
|
8
|
+
* This module used to consume `planningRisk.overallLevel` — a level the planner
|
|
9
|
+
* asserted about the plan it had just written. That signal was self-refereed and
|
|
10
|
+
* its fail-safe ran backwards: an *absent* verdict degraded toward MORE ceremony
|
|
11
|
+
* (standard depth), while a schema-valid all-low verdict bought `light`. Nothing
|
|
12
|
+
* cross-checked the claimed axes against the files actually touched, so the one
|
|
13
|
+
* input that could *reduce* review was exactly the one nobody verified. Story
|
|
14
|
+
* #4542 inverted that: the level is now derived at close time from the changed
|
|
15
|
+
* files themselves, which makes it a fact rather than a claim — and therefore
|
|
16
|
+
* trustworthy enough to reduce ceremony on.
|
|
28
17
|
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
18
|
+
* ## The two signals
|
|
19
|
+
*
|
|
20
|
+
* - **Sensitive paths** ({@link deriveChangeLevel}) — the changed-file set
|
|
21
|
+
* intersected with the `sensitivePaths` classes registered in
|
|
22
|
+
* `.agents/schemas/audit-rules.json` (auth, migrations, billing, destructive
|
|
23
|
+
* mutation, public API). Registered as **configuration**, matched with the
|
|
24
|
+
* audit-suite's existing picomatch machinery. This is what keeps a *narrow*
|
|
25
|
+
* high-stakes diff — a three-file auth fix, a small migration — at `deep`,
|
|
26
|
+
* the one thing a pure width heuristic would miss.
|
|
27
|
+
* - **Diff width** — the mechanical changed-file count, unchanged in role.
|
|
28
|
+
*
|
|
29
|
+
* ## Tier rules ({@link resolveDepth})
|
|
30
|
+
*
|
|
31
|
+
* - `deep` — `derivedLevel === 'high'` (a sensitive path was touched) OR
|
|
32
|
+
* the changed-file count exceeds the wide-change scale
|
|
33
|
+
* (`diffWidth.hardFiles`). A wide diff earns a deep pass on
|
|
34
|
+
* size alone even when it touches nothing sensitive.
|
|
35
|
+
* - `light` — `derivedLevel === 'low'` (the change set is known and touches
|
|
36
|
+
* no sensitive path) AND the count is at or below the
|
|
37
|
+
* small-change scale (`diffWidth.softFiles`). An *unknown*
|
|
38
|
+
* count does not block `light`: a missing width is treated as
|
|
39
|
+
* "not wide".
|
|
40
|
+
* - `standard` — everything else, including an absent/underivable level. Fail
|
|
41
|
+
* toward the middle, never toward `light`: when the diff cannot
|
|
42
|
+
* be enumerated there is no evidence the change is safe, and
|
|
43
|
+
* `standard` preserves today's behaviour.
|
|
44
|
+
*
|
|
45
|
+
* {@link resolveDepth} is pure and total: inputs in, tier out. No I/O, no
|
|
46
|
+
* throws. `null` / `undefined` / malformed inputs degrade to `standard` (or
|
|
47
|
+
* `deep`/`light` only when a signal unambiguously says so). {@link
|
|
48
|
+
* deriveChangeLevel} owns the one manifest read and is likewise total — any
|
|
49
|
+
* failure degrades to the `null` (fail-safe) level.
|
|
50
|
+
*
|
|
51
|
+
* v2 Stage 2: review depth is **decoupled** from the planning model-capacity
|
|
52
|
+
* advisory. Diff width is a mechanical review signal (files in the landed
|
|
53
|
+
* diff); planning capacity is an absolute authored-token session-mass signal.
|
|
54
|
+
* The two no longer share a constant.
|
|
35
55
|
*
|
|
36
56
|
* @typedef {'light'|'standard'|'deep'} ReviewDepth
|
|
57
|
+
* @typedef {'low'|'high'} ChangeLevel
|
|
37
58
|
*/
|
|
38
59
|
|
|
39
|
-
import {
|
|
60
|
+
import { selectSensitivePathClasses } from '../audit-suite/selector.js';
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Mechanical diff-width scales for review-depth tiering. These are **not**
|
|
64
|
+
* planning Story-sizing ceilings (those are gone in v2) — they only classify
|
|
65
|
+
* the changed-file count of a diff under review.
|
|
66
|
+
*/
|
|
67
|
+
export const DEFAULT_DIFF_WIDTH = Object.freeze({
|
|
68
|
+
softFiles: 15,
|
|
69
|
+
hardFiles: 30,
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Derive the change level for a change set from observable facts: does the
|
|
74
|
+
* changed-file set intersect any sensitive-path class registered in
|
|
75
|
+
* `audit-rules.json`?
|
|
76
|
+
*
|
|
77
|
+
* This is the **single source** of the derived level — both the review depth
|
|
78
|
+
* ({@link resolveDepth}) and the acceptance-critic fresh-vs-inline routing
|
|
79
|
+
* (`ceremony-routing.js#resolveCeremonyForRisk`) consume what this returns, so
|
|
80
|
+
* the two ceremony decisions can never disagree about how risky a change is.
|
|
81
|
+
*
|
|
82
|
+
* Returns `null` — the fail-safe "no derivable signal" level — when the change
|
|
83
|
+
* set is empty/unknown or the manifest cannot be read. Both downstream
|
|
84
|
+
* consumers treat `null` as the more thorough posture (`standard` depth, a
|
|
85
|
+
* `fresh` critic), so a derivation failure never buys a change less checking.
|
|
86
|
+
*
|
|
87
|
+
* Total: never throws.
|
|
88
|
+
*
|
|
89
|
+
* @param {{
|
|
90
|
+
* changedFiles?: string[]|null,
|
|
91
|
+
* injectedRules?: object,
|
|
92
|
+
* selectSensitivePathClassesFn?: typeof selectSensitivePathClasses,
|
|
93
|
+
* }} [input]
|
|
94
|
+
* @returns {{ level: ChangeLevel|null, classes: string[] }}
|
|
95
|
+
*/
|
|
96
|
+
export function deriveChangeLevel(input = {}) {
|
|
97
|
+
const changedFiles =
|
|
98
|
+
input && typeof input === 'object' ? input.changedFiles : null;
|
|
99
|
+
if (!Array.isArray(changedFiles) || changedFiles.length === 0) {
|
|
100
|
+
return { level: null, classes: [] };
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const select =
|
|
104
|
+
input.selectSensitivePathClassesFn ?? selectSensitivePathClasses;
|
|
105
|
+
let classes;
|
|
106
|
+
try {
|
|
107
|
+
classes = select({ changedFiles, injectedRules: input.injectedRules });
|
|
108
|
+
} catch {
|
|
109
|
+
// An unreadable/invalid manifest is not evidence the change is safe.
|
|
110
|
+
return { level: null, classes: [] };
|
|
111
|
+
}
|
|
112
|
+
const matched = Array.isArray(classes) ? classes : [];
|
|
113
|
+
return { level: matched.length > 0 ? 'high' : 'low', classes: matched };
|
|
114
|
+
}
|
|
40
115
|
|
|
41
116
|
/**
|
|
42
117
|
* Coerce an arbitrary input into a non-negative integer changed-file count, or
|
|
@@ -54,40 +129,44 @@ function normalizeChangedFileCount(value) {
|
|
|
54
129
|
}
|
|
55
130
|
|
|
56
131
|
/**
|
|
57
|
-
* Resolve the review depth for a change set from its
|
|
58
|
-
* width. See the module header for the tier
|
|
132
|
+
* Resolve the review depth for a change set from its derived level (see
|
|
133
|
+
* {@link deriveChangeLevel}) and diff width. See the module header for the tier
|
|
134
|
+
* rules.
|
|
59
135
|
*
|
|
60
136
|
* @param {{
|
|
61
|
-
*
|
|
137
|
+
* derivedLevel?: (ChangeLevel|string|null|undefined),
|
|
62
138
|
* changedFileCount?: (number|null|undefined),
|
|
63
|
-
*
|
|
139
|
+
* diffWidth?: { softFiles?: number, hardFiles?: number }|null,
|
|
64
140
|
* }} [input]
|
|
65
141
|
* @returns {ReviewDepth}
|
|
66
142
|
*/
|
|
67
143
|
export function resolveDepth(input = {}) {
|
|
68
|
-
const
|
|
69
|
-
input && typeof input === 'object' ? input.
|
|
144
|
+
const derivedLevel =
|
|
145
|
+
input && typeof input === 'object' ? input.derivedLevel : undefined;
|
|
70
146
|
const changedFileCount =
|
|
71
147
|
input && typeof input === 'object'
|
|
72
148
|
? normalizeChangedFileCount(input.changedFileCount)
|
|
73
149
|
: null;
|
|
74
150
|
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
|
|
151
|
+
const override =
|
|
152
|
+
input && typeof input === 'object' ? (input.diffWidth ?? {}) : {};
|
|
153
|
+
const mergedWidth = {
|
|
154
|
+
...DEFAULT_DIFF_WIDTH,
|
|
155
|
+
...override,
|
|
78
156
|
};
|
|
79
|
-
const { softFiles, hardFiles } =
|
|
157
|
+
const { softFiles, hardFiles } = mergedWidth;
|
|
80
158
|
|
|
81
159
|
// A known count strictly above the wide-change scale is wide.
|
|
82
160
|
const isWide = changedFileCount !== null && changedFileCount > hardFiles;
|
|
83
161
|
// An unknown count is treated as "not wide" — it does not block `light`.
|
|
84
162
|
const isSmall = changedFileCount === null || changedFileCount <= softFiles;
|
|
85
163
|
|
|
86
|
-
// deep —
|
|
87
|
-
if (
|
|
88
|
-
// light —
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
//
|
|
164
|
+
// deep — a sensitive path was touched OR the diff is wide.
|
|
165
|
+
if (derivedLevel === 'high' || isWide) return 'deep';
|
|
166
|
+
// light — nothing sensitive touched AND a (known-or-unknown-but-not-wide)
|
|
167
|
+
// small diff.
|
|
168
|
+
if (derivedLevel === 'low' && isSmall) return 'light';
|
|
169
|
+
// standard — everything else: an underivable level, or a non-sensitive diff
|
|
170
|
+
// whose width sits between softFiles and hardFiles.
|
|
92
171
|
return 'standard';
|
|
93
172
|
}
|
|
@@ -44,7 +44,7 @@ export const CODEX_REMEDIATIONS = Object.freeze({
|
|
|
44
44
|
'Install the Codex plugin (https://github.com/openai/codex-plugin-cc) ' +
|
|
45
45
|
'so the host registers the `/codex:review` slash command.',
|
|
46
46
|
fallback:
|
|
47
|
-
'Or set `codeReview.
|
|
47
|
+
'Or set `codeReview.providers` to [{ name: "native" }] in .agentrc.json to use the ' +
|
|
48
48
|
'in-process maintainability/lint provider instead.',
|
|
49
49
|
});
|
|
50
50
|
|
|
@@ -96,7 +96,7 @@ export function defaultProbeCodexCommand(opts = {}) {
|
|
|
96
96
|
*/
|
|
97
97
|
export function buildCodexUnavailableError() {
|
|
98
98
|
return new Error(
|
|
99
|
-
'[ReviewProviderFactory] codeReview.
|
|
99
|
+
'[ReviewProviderFactory] codeReview.providers includes "codex" but the ' +
|
|
100
100
|
'`/codex:review` slash command is not registered on this host. ' +
|
|
101
101
|
`${CODEX_REMEDIATIONS.install} ${CODEX_REMEDIATIONS.fallback}`,
|
|
102
102
|
);
|
|
@@ -13,7 +13,6 @@
|
|
|
13
13
|
*
|
|
14
14
|
* @typedef {import('./types.js').Finding} Finding
|
|
15
15
|
* @typedef {import('./types.js').Severity} Severity
|
|
16
|
-
* @typedef {import('./types.js').ReviewScope} ReviewScope
|
|
17
16
|
*/
|
|
18
17
|
|
|
19
18
|
/**
|
|
@@ -117,7 +116,6 @@ export function renderManualPromptsSection(messages) {
|
|
|
117
116
|
* non-empty.
|
|
118
117
|
*
|
|
119
118
|
* @param {{
|
|
120
|
-
* scope: ReviewScope,
|
|
121
119
|
* ticketId: number,
|
|
122
120
|
* baseRef: string,
|
|
123
121
|
* headRef: string,
|
|
@@ -128,26 +126,18 @@ export function renderManualPromptsSection(messages) {
|
|
|
128
126
|
* @returns {string}
|
|
129
127
|
*/
|
|
130
128
|
export function renderFindings(input) {
|
|
131
|
-
const {
|
|
132
|
-
|
|
133
|
-
ticketId,
|
|
134
|
-
baseRef,
|
|
135
|
-
headRef,
|
|
136
|
-
findings,
|
|
137
|
-
provider,
|
|
138
|
-
promptMessages,
|
|
139
|
-
} = input;
|
|
129
|
+
const { ticketId, baseRef, headRef, findings, provider, promptMessages } =
|
|
130
|
+
input;
|
|
140
131
|
const counts = countBySeverity(findings);
|
|
141
132
|
const totalKnown =
|
|
142
133
|
counts.critical + counts.high + counts.medium + counts.suggestion;
|
|
143
134
|
|
|
144
|
-
const scopeLabel = scope === 'epic' ? 'Epic' : 'Story';
|
|
145
135
|
const providerLine = provider
|
|
146
136
|
? `**Provider**: \`${provider}\``
|
|
147
137
|
: '**Provider**: _(unspecified)_';
|
|
148
138
|
|
|
149
139
|
const lines = [
|
|
150
|
-
`## 🔬 Code Review —
|
|
140
|
+
`## 🔬 Code Review — Story #${ticketId}`,
|
|
151
141
|
'',
|
|
152
142
|
`**Comparison**: \`${baseRef}\` … \`${headRef}\``,
|
|
153
143
|
providerLine,
|