mandrel 2.0.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 +59 -28
- package/.agents/agents/acceptance-critic.md +9 -7
- package/.agents/agents/story-worker.md +41 -46
- package/.agents/audit-checklists/performance.md +1 -1
- package/.agents/docs/SDLC.md +51 -44
- package/.agents/docs/agentrc-reference.json +8 -13
- package/.agents/docs/configuration.md +32 -56
- package/.agents/docs/execution-reference.md +39 -10
- package/.agents/docs/quality-gates.md +14 -16
- package/.agents/docs/workflows.md +6 -6
- package/.agents/instructions.md +64 -79
- package/.agents/rules/ci-remediation.md +3 -3
- package/.agents/rules/git-conventions-reference.md +42 -51
- package/.agents/schemas/agentrc.schema.json +34 -45
- 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/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/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 +1 -1
- package/.agents/scripts/check-workflow-cli-lint.js +91 -0
- 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/audit-suite/selector.js +323 -23
- package/.agents/scripts/lib/baselines/kinds/maintainability.js +0 -11
- package/.agents/scripts/lib/bootstrap/ci-workflow-template.js +28 -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 +4 -1
- package/.agents/scripts/lib/checks/index.js +1 -1
- 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 +3 -3
- 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-args.js +23 -2
- package/.agents/scripts/lib/close-validation/gates.js +13 -13
- 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/delivery-routing.js +7 -6
- package/.agents/scripts/lib/config/explain.js +10 -16
- package/.agents/scripts/lib/config/github.js +7 -5
- package/.agents/scripts/lib/config/limits.js +15 -25
- package/.agents/scripts/lib/config/quality.js +11 -14
- package/.agents/scripts/lib/config/runners.js +8 -21
- package/.agents/scripts/lib/config/temp-paths.js +18 -56
- package/.agents/scripts/lib/config-settings-schema-delivery.js +31 -13
- package/.agents/scripts/lib/config-settings-schema-quality.js +9 -2
- package/.agents/scripts/lib/config-settings-schema.js +48 -22
- package/.agents/scripts/lib/dead-exports-knip.js +105 -0
- package/.agents/scripts/lib/dead-exports-mode.js +51 -0
- package/.agents/scripts/lib/duplicate-search.js +38 -7
- 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 -189
- package/.agents/scripts/lib/gh-exec.js +8 -0
- package/.agents/scripts/lib/git-branch-lifecycle.js +0 -158
- package/.agents/scripts/lib/git-utils.js +0 -14
- package/.agents/scripts/lib/json-utils.js +1 -2
- package/.agents/scripts/lib/label-constants.js +0 -15
- package/.agents/scripts/lib/label-taxonomy.js +1 -12
- package/.agents/scripts/lib/observability/active-story-env.js +42 -163
- 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 +2 -2
- package/.agents/scripts/lib/observability/tool-trace-hook.js +2 -12
- 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 +43 -45
- package/.agents/scripts/lib/orchestration/code-review.js +58 -168
- package/.agents/scripts/lib/orchestration/consolidation-precondition.js +3 -3
- 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/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 +9 -11
- 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/listeners/README.md +7 -3
- 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/merge-block-class.js +76 -20
- package/.agents/scripts/lib/orchestration/merge-poll.js +104 -0
- package/.agents/scripts/lib/orchestration/plan-context.js +114 -24
- package/.agents/scripts/lib/orchestration/plan-critic-conditions.js +11 -22
- package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +3 -7
- package/.agents/scripts/lib/orchestration/plan-metrics.js +38 -6
- package/.agents/scripts/lib/orchestration/plan-persist/fan-out-gate.js +16 -6
- package/.agents/scripts/lib/orchestration/plan-persist/persist-helpers.js +173 -25
- package/.agents/scripts/lib/orchestration/plan-persist/plan-context-source.js +116 -0
- package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +280 -75
- package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +472 -55
- package/.agents/scripts/lib/orchestration/plan-persist/summary.js +21 -16
- package/.agents/scripts/lib/orchestration/plan-persist/supersede-ops.js +509 -0
- package/.agents/scripts/lib/orchestration/planning/authoring-context.js +41 -40
- package/.agents/scripts/lib/orchestration/planning/spec-authoring-grounding.js +1 -1
- package/.agents/scripts/lib/orchestration/resolve-stories.js +344 -0
- package/.agents/scripts/lib/orchestration/retro-proposals.js +7 -7
- package/.agents/scripts/lib/orchestration/review-depth.js +105 -40
- 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/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 +374 -16
- package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +24 -0
- 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 +3 -12
- 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 +72 -30
- 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 +12 -8
- 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 +264 -43
- package/.agents/scripts/lib/orchestration/single-story-lease-guard.js +1 -1
- package/.agents/scripts/lib/orchestration/story-close/format-autofix.js +10 -10
- package/.agents/scripts/lib/orchestration/story-close/phases/code-review.js +15 -32
- package/.agents/scripts/lib/orchestration/story-deliver-terminal.js +360 -0
- package/.agents/scripts/lib/orchestration/story-follow-ups.js +75 -14
- package/.agents/scripts/lib/orchestration/story-init-remote.js +12 -8
- package/.agents/scripts/lib/orchestration/story-plan-state.js +14 -29
- package/.agents/scripts/lib/orchestration/task-body-validator.js +52 -7
- package/.agents/scripts/lib/orchestration/ticket-lease.js +27 -74
- package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +119 -14
- package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +3 -4
- package/.agents/scripts/lib/orchestration/ticket-validator.js +121 -18
- package/.agents/scripts/lib/orchestration/ticketing/bulk.js +14 -47
- package/.agents/scripts/lib/orchestration/ticketing/reads.js +19 -32
- package/.agents/scripts/lib/orchestration/ticketing/transition.js +61 -1
- 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 -286
- package/.agents/scripts/lib/preflight-runner.js +2 -2
- 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/skills/parse-skill.js +16 -3
- package/.agents/scripts/lib/story-adjacency.js +8 -7
- package/.agents/scripts/lib/story-body/story-body.js +6 -5
- package/.agents/scripts/lib/templates/decomposer-prompts.js +7 -3
- package/.agents/scripts/lib/test-env.js +14 -1
- package/.agents/scripts/lib/test-tiers.js +0 -3
- package/.agents/scripts/lib/ticket-body-sections.js +0 -14
- package/.agents/scripts/lib/validation-evidence.js +31 -59
- package/.agents/scripts/lib/wave-runner/ready-set.js +32 -6
- package/.agents/scripts/lib/worktree/lifecycle/pending-cleanup.js +1 -1
- package/.agents/scripts/lib/worktree/lifecycle/reap.js +68 -19
- package/.agents/scripts/lib/worktree/lifecycle-manager.js +1 -2
- package/.agents/scripts/plan-context.js +38 -6
- package/.agents/scripts/plan-persist.js +145 -35
- package/.agents/scripts/plan-run-epilogue.js +83 -38
- 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 +1 -11
- package/.agents/scripts/providers/github/mappers.js +5 -0
- package/.agents/scripts/providers/github/sub-issues.js +0 -47
- package/.agents/scripts/providers/github/tickets.js +33 -153
- 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 +9 -10
- package/.agents/scripts/single-story-close.js +173 -18
- package/.agents/scripts/single-story-confirm-merge.js +288 -15
- package/.agents/scripts/single-story-init.js +6 -10
- package/.agents/scripts/stories-wave-tick.js +79 -4
- package/.agents/scripts/story-plan.js +3 -3
- package/.agents/scripts/update-ticket-state.js +8 -50
- 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 +3 -3
- package/.agents/skills/core/scope-triage/SKILL.md +3 -0
- 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 +2 -12
- 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/workflows/audit-architecture.md +3 -4
- package/.agents/workflows/audit-clean-code.md +4 -4
- package/.agents/workflows/audit-documentation.md +4 -5
- package/.agents/workflows/audit-lighthouse.md +8 -0
- package/.agents/workflows/audit-navigability.md +10 -0
- package/.agents/workflows/audit-performance.md +2 -3
- package/.agents/workflows/audit-quality.md +8 -9
- package/.agents/workflows/audit-security.md +1 -2
- package/.agents/workflows/audit-seo.md +10 -0
- package/.agents/workflows/audit-ux-ui.md +7 -0
- package/.agents/workflows/deliver.md +98 -45
- package/.agents/workflows/git-cleanup.md +2 -2
- package/.agents/workflows/git-deliver.md +1 -1
- package/.agents/workflows/helpers/acceptance-self-eval.md +21 -13
- package/.agents/workflows/helpers/code-quality-guardrails.md +7 -7
- package/.agents/workflows/helpers/code-review.md +12 -10
- package/.agents/workflows/helpers/deliver-story-reference.md +73 -32
- package/.agents/workflows/helpers/deliver-story.md +193 -118
- package/.agents/workflows/helpers/parallel-tooling.md +2 -2
- package/.agents/workflows/helpers/worktree-lifecycle.md +28 -32
- package/.agents/workflows/plan.md +184 -19
- package/.agents/workflows/qa-assist.md +6 -6
- package/.agents/workflows/qa-explore.md +3 -3
- package/.agents/workflows/qa-run.md +1 -5
- package/bin/mandrel.js +12 -1
- package/docs/CHANGELOG.md +40 -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 -9
- 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 +1 -1
- package/.agents/schemas/epic-perf-report.schema.json +0 -89
- 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/story.heartbeat.schema.json +0 -20
- package/.agents/schemas/risk-verdict.schema.json +0 -53
- package/.agents/schemas/story-perf-summary.schema.json +0 -73
- package/.agents/scripts/analyze-execution.js +0 -444
- package/.agents/scripts/check-prepush-recovery.js +0 -90
- 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 -187
- 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/audit-lens-routing.js +0 -128
- package/.agents/scripts/lib/orchestration/bookkeeping-outbox.js +0 -273
- package/.agents/scripts/lib/orchestration/error-journal.js +0 -139
- 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/merge-watcher.js +0 -665
- package/.agents/scripts/lib/orchestration/plan-review-routing.js +0 -63
- package/.agents/scripts/lib/orchestration/planning/risk-verdict.js +0 -104
- 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 -21
- 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 -397
- package/.agents/scripts/lib/orchestration/preflight-cache.js +0 -187
- package/.agents/scripts/lib/orchestration/resolve-plan-run.js +0 -155
- package/.agents/scripts/lib/orchestration/retro-perf-heuristics.js +0 -275
- package/.agents/scripts/lib/orchestration/story-progress/story-run-progress-writer.js +0 -400
- package/.agents/scripts/lib/single-story/confirm-merge-follow-ups.js +0 -36
- package/.agents/scripts/resolve-plan-run.js +0 -117
- package/.agents/skills/core/analyze-execution/SKILL.md +0 -101
|
@@ -11,12 +11,15 @@
|
|
|
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:
|
|
@@ -24,7 +27,7 @@
|
|
|
24
27
|
* a single `native` chain entry when `delivery.codeReview.providers`
|
|
25
28
|
* is unset or empty.
|
|
26
29
|
* - Always posts the unified `verification-results` structured comment on
|
|
27
|
-
* the
|
|
30
|
+
* the target issue/PR (the adapter never posts; the orchestrator owns
|
|
28
31
|
* persistence). Story #4411 (Epic #4405) unified the former
|
|
29
32
|
* `code-review` and `audit-results` findings contracts into this one
|
|
30
33
|
* `verification-results` marker.
|
|
@@ -39,7 +42,7 @@
|
|
|
39
42
|
import { hasSurvivingCritical } from '../audit-suite/findings.js';
|
|
40
43
|
import { resolveConfig } from '../config-resolver.js';
|
|
41
44
|
import { gitSpawn } from '../git-utils.js';
|
|
42
|
-
import { resolveDepth } from './review-depth.js';
|
|
45
|
+
import { deriveChangeLevel, resolveDepth } from './review-depth.js';
|
|
43
46
|
import {
|
|
44
47
|
countBySeverity,
|
|
45
48
|
renderFindings,
|
|
@@ -49,29 +52,30 @@ import { upsertStructuredComment } from './ticketing.js';
|
|
|
49
52
|
|
|
50
53
|
/**
|
|
51
54
|
* Review depth tiers, ordered light → standard → deep. The depth is resolved
|
|
52
|
-
* by the shared {@link resolveDepth} resolver from
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
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
|
|
57
61
|
* `{ status, severity, posted, report, halted, blockerReason }` output
|
|
58
|
-
* envelope nor the `
|
|
59
|
-
* 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).
|
|
60
64
|
*
|
|
61
65
|
* @typedef {import('./review-depth.js').ReviewDepth} ReviewDepth
|
|
62
66
|
*/
|
|
63
67
|
|
|
64
68
|
/**
|
|
65
|
-
*
|
|
66
|
-
* `git diff --name-only`. Returns the file
|
|
67
|
-
* cannot be enumerated (git failure, missing ref). A `null`
|
|
68
|
-
*
|
|
69
|
-
*
|
|
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.
|
|
70
74
|
*
|
|
71
75
|
* @param {{ baseRef: string, headRef: string, gitSpawnFn?: typeof gitSpawn }} args
|
|
72
|
-
* @returns {
|
|
76
|
+
* @returns {string[]|null}
|
|
73
77
|
*/
|
|
74
|
-
function
|
|
78
|
+
function listChangedFiles({ baseRef, headRef, gitSpawnFn = gitSpawn }) {
|
|
75
79
|
try {
|
|
76
80
|
const result = gitSpawnFn(
|
|
77
81
|
process.cwd(),
|
|
@@ -83,50 +87,14 @@ function countChangedFiles({ baseRef, headRef, gitSpawnFn = gitSpawn }) {
|
|
|
83
87
|
return null;
|
|
84
88
|
}
|
|
85
89
|
return result.stdout
|
|
86
|
-
.trim()
|
|
87
90
|
.split('\n')
|
|
88
|
-
.
|
|
91
|
+
.map((line) => line.trim())
|
|
92
|
+
.filter((line) => line.length > 0);
|
|
89
93
|
} catch {
|
|
90
94
|
return null;
|
|
91
95
|
}
|
|
92
96
|
}
|
|
93
97
|
|
|
94
|
-
/**
|
|
95
|
-
* Build the `code-review.end` payload from the normalized result envelope.
|
|
96
|
-
* The runner result may carry a `report` field (full markdown body) which
|
|
97
|
-
* is NOT included in the lifecycle payload: the schema's
|
|
98
|
-
* `additionalProperties: false` forbids it, and the body can carry inline
|
|
99
|
-
* severity counts that drift from the structured `severity` field. The
|
|
100
|
-
* lifecycle ledger is the structured surface; the report is GitHub's
|
|
101
|
-
* surface (posted via the structured comment).
|
|
102
|
-
*
|
|
103
|
-
* Story #2839: `epicId` is preserved verbatim in the lifecycle payload so
|
|
104
|
-
* the `code-review.end` schema (additionalProperties: false, requires
|
|
105
|
-
* `epicId`) stays unchanged. Story-scope invocations never reach this
|
|
106
|
-
* helper — `runCodeReview` short-circuits the bus emit for `scope: 'story'`
|
|
107
|
-
* because story-scope review sits outside the Epic lifecycle ledger.
|
|
108
|
-
*/
|
|
109
|
-
function buildCodeReviewEndPayload({ epicId, result, durationMs }) {
|
|
110
|
-
const payload = {
|
|
111
|
-
epicId,
|
|
112
|
-
status: result.status,
|
|
113
|
-
};
|
|
114
|
-
if (result.severity && typeof result.severity === 'object') {
|
|
115
|
-
payload.severity = {
|
|
116
|
-
critical: result.severity.critical ?? 0,
|
|
117
|
-
high: result.severity.high ?? 0,
|
|
118
|
-
medium: result.severity.medium ?? 0,
|
|
119
|
-
suggestion: result.severity.suggestion ?? 0,
|
|
120
|
-
};
|
|
121
|
-
}
|
|
122
|
-
if (typeof result.halted === 'boolean') payload.halted = result.halted;
|
|
123
|
-
if (typeof result.posted === 'boolean') payload.posted = result.posted;
|
|
124
|
-
if (Number.isFinite(durationMs) && durationMs >= 0) {
|
|
125
|
-
payload.durationMs = Math.floor(durationMs);
|
|
126
|
-
}
|
|
127
|
-
return payload;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
98
|
/**
|
|
131
99
|
* Resolve the project base branch fallback used when a caller omits
|
|
132
100
|
* `baseRef`.
|
|
@@ -152,7 +120,6 @@ function resolveCommentTargetId(commentTargetId, fallback) {
|
|
|
152
120
|
* baseRef: string,
|
|
153
121
|
* headRef: string,
|
|
154
122
|
* commentTargetId: number,
|
|
155
|
-
* epicIdForLedger: null,
|
|
156
123
|
* }}
|
|
157
124
|
*/
|
|
158
125
|
function resolveStoryScope(opts, config) {
|
|
@@ -175,53 +142,16 @@ function resolveStoryScope(opts, config) {
|
|
|
175
142
|
opts.commentTargetId,
|
|
176
143
|
opts.ticketId,
|
|
177
144
|
),
|
|
178
|
-
epicIdForLedger: null,
|
|
179
|
-
};
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
/**
|
|
183
|
-
* Resolve the Epic-scope envelope from the parameterized
|
|
184
|
-
* `{ scope: 'epic', ticketId, baseRef, headRef, commentTargetId }` shape.
|
|
185
|
-
* `headRef` defaults to `epic/<ticketId>` and `baseRef` to the project
|
|
186
|
-
* base branch.
|
|
187
|
-
*
|
|
188
|
-
* @returns {{
|
|
189
|
-
* scope: 'epic',
|
|
190
|
-
* ticketId: number,
|
|
191
|
-
* baseRef: string,
|
|
192
|
-
* headRef: string,
|
|
193
|
-
* commentTargetId: number,
|
|
194
|
-
* epicIdForLedger: number,
|
|
195
|
-
* }}
|
|
196
|
-
*/
|
|
197
|
-
function resolveEpicScope(opts, config) {
|
|
198
|
-
if (!Number.isInteger(opts.ticketId) || opts.ticketId <= 0) {
|
|
199
|
-
throw new TypeError(
|
|
200
|
-
'runCodeReview: ticketId is required (positive integer) when scope="epic".',
|
|
201
|
-
);
|
|
202
|
-
}
|
|
203
|
-
return {
|
|
204
|
-
scope: 'epic',
|
|
205
|
-
ticketId: opts.ticketId,
|
|
206
|
-
baseRef: opts.baseRef ?? resolveConfigBase(config),
|
|
207
|
-
headRef: opts.headRef ?? `epic/${opts.ticketId}`,
|
|
208
|
-
commentTargetId: resolveCommentTargetId(
|
|
209
|
-
opts.commentTargetId,
|
|
210
|
-
opts.ticketId,
|
|
211
|
-
),
|
|
212
|
-
epicIdForLedger: opts.ticketId,
|
|
213
145
|
};
|
|
214
146
|
}
|
|
215
147
|
|
|
216
148
|
/**
|
|
217
|
-
*
|
|
218
|
-
* (`{ scope, ticketId, baseRef, headRef, commentTargetId }`)
|
|
219
|
-
*
|
|
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.
|
|
220
152
|
*/
|
|
221
153
|
function resolveScopeEnvelope(opts, config) {
|
|
222
|
-
return opts
|
|
223
|
-
? resolveStoryScope(opts, config)
|
|
224
|
-
: resolveEpicScope(opts, config);
|
|
154
|
+
return resolveStoryScope(opts, config);
|
|
225
155
|
}
|
|
226
156
|
|
|
227
157
|
/**
|
|
@@ -239,36 +169,28 @@ function resolveScopeEnvelope(opts, config) {
|
|
|
239
169
|
* derived from the `Finding[]` returned by the adapter (no separate
|
|
240
170
|
* severity field on the runner result).
|
|
241
171
|
*
|
|
242
|
-
* Story #2839 (Epic #2815) —
|
|
243
|
-
*
|
|
244
|
-
*
|
|
245
|
-
*
|
|
246
|
-
* caller as `halted: true`. Lifecycle bus emits are confined to
|
|
247
|
-
* `scope: 'epic'` because the `code-review.end` schema requires
|
|
248
|
-
* `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`.
|
|
249
176
|
*
|
|
250
|
-
* Argument shape
|
|
251
|
-
* `{
|
|
252
|
-
*
|
|
253
|
-
* `
|
|
254
|
-
*
|
|
255
|
-
* For `scope === 'story'`, `commentTargetId` overrides the post
|
|
256
|
-
* target (e.g. PR number) while `ticketId` continues to label the
|
|
257
|
-
* 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").
|
|
258
182
|
*
|
|
259
183
|
* @param {{
|
|
260
|
-
* scope?: '
|
|
184
|
+
* scope?: 'story',
|
|
261
185
|
* ticketId: number,
|
|
262
186
|
* baseRef?: string|null,
|
|
263
187
|
* headRef?: string|null,
|
|
264
188
|
* commentTargetId?: number|null,
|
|
265
189
|
* provider: object,
|
|
266
190
|
* logger?: { info?: Function, warn?: Function, error?: Function, fatal?: Function, createProgress?: Function },
|
|
267
|
-
*
|
|
191
|
+
* changedFiles?: string[]|null,
|
|
268
192
|
* changedFileCount?: number|null,
|
|
269
193
|
* storyId?: number|null,
|
|
270
|
-
* bus?: object|null,
|
|
271
|
-
* now?: () => number,
|
|
272
194
|
* reviewProvider?: { runReview: Function },
|
|
273
195
|
* gitSpawnFn?: typeof gitSpawn,
|
|
274
196
|
* resolveConfigFn?: typeof resolveConfig,
|
|
@@ -309,22 +231,26 @@ function resolveProviderName(codeReviewConfig) {
|
|
|
309
231
|
|
|
310
232
|
/**
|
|
311
233
|
* Build the provider `runReview` input, resolving the review depth from the
|
|
312
|
-
*
|
|
313
|
-
*
|
|
314
|
-
* input-only signal (light → standard → deep) and never touches the
|
|
315
|
-
* envelope or the posted comment.
|
|
316
|
-
*
|
|
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`.
|
|
317
239
|
*/
|
|
318
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 });
|
|
319
244
|
const changedFileCount =
|
|
320
245
|
typeof opts.changedFileCount === 'number'
|
|
321
246
|
? opts.changedFileCount
|
|
322
|
-
:
|
|
247
|
+
: (changedFiles?.length ?? null);
|
|
323
248
|
// v2 Stage 2: review depth uses DEFAULT_DIFF_WIDTH (mechanical file count
|
|
324
249
|
// of the diff under review). It is deliberately decoupled from the
|
|
325
250
|
// planning model-capacity advisory (`DEFAULT_MODEL_CAPACITY`).
|
|
251
|
+
const { level } = deriveChangeLevel({ changedFiles });
|
|
326
252
|
const depth = resolveDepth({
|
|
327
|
-
|
|
253
|
+
derivedLevel: level,
|
|
328
254
|
changedFileCount,
|
|
329
255
|
});
|
|
330
256
|
return {
|
|
@@ -418,7 +344,7 @@ async function executeReviewPipeline({ opts, config, envelope }) {
|
|
|
418
344
|
injectedReviewProvider ?? createReviewProviderFn(codeReviewConfig);
|
|
419
345
|
|
|
420
346
|
logger?.info?.(
|
|
421
|
-
`[code-review] Running ${providerName} adapter for
|
|
347
|
+
`[code-review] Running ${providerName} adapter for Story #${ticketId} (${baseRef}...${headRef})...`,
|
|
422
348
|
);
|
|
423
349
|
|
|
424
350
|
const reviewInput = buildReviewInput({
|
|
@@ -477,49 +403,13 @@ async function executeReviewPipeline({ opts, config, envelope }) {
|
|
|
477
403
|
}
|
|
478
404
|
|
|
479
405
|
export async function runCodeReview(opts = {}) {
|
|
480
|
-
const {
|
|
406
|
+
const { resolveConfigFn = resolveConfig } = opts;
|
|
481
407
|
|
|
482
408
|
const config = resolveConfigFn();
|
|
483
409
|
const envelope = resolveScopeEnvelope(opts, config);
|
|
484
|
-
const { scope } = envelope;
|
|
485
410
|
|
|
486
|
-
//
|
|
487
|
-
//
|
|
488
|
-
//
|
|
489
|
-
|
|
490
|
-
if (scope === 'epic' && (!bus || typeof bus.emit !== 'function')) {
|
|
491
|
-
throw new TypeError('runCodeReview: bus is required (object with emit()).');
|
|
492
|
-
}
|
|
493
|
-
const ledgerEnabled =
|
|
494
|
-
scope === 'epic' && bus && typeof bus.emit === 'function';
|
|
495
|
-
|
|
496
|
-
const startedAt = typeof now === 'function' ? now() : Date.now();
|
|
497
|
-
// Emit the matched `code-review.end` boundary; the ledger must always
|
|
498
|
-
// show a start/end pair (even on adapter throw, where `result` is the
|
|
499
|
-
// canonical `{ status: 'invalid' }`).
|
|
500
|
-
const emitEnd = async (result) => {
|
|
501
|
-
if (!ledgerEnabled) return;
|
|
502
|
-
const endedAt = typeof now === 'function' ? now() : Date.now();
|
|
503
|
-
await bus.emit(
|
|
504
|
-
'code-review.end',
|
|
505
|
-
buildCodeReviewEndPayload({
|
|
506
|
-
epicId: envelope.epicIdForLedger,
|
|
507
|
-
result,
|
|
508
|
-
durationMs: Math.max(0, endedAt - startedAt),
|
|
509
|
-
}),
|
|
510
|
-
);
|
|
511
|
-
};
|
|
512
|
-
|
|
513
|
-
if (ledgerEnabled) {
|
|
514
|
-
await bus.emit('code-review.start', { epicId: envelope.epicIdForLedger });
|
|
515
|
-
}
|
|
516
|
-
|
|
517
|
-
try {
|
|
518
|
-
const result = await executeReviewPipeline({ opts, config, envelope });
|
|
519
|
-
await emitEnd(result);
|
|
520
|
-
return result;
|
|
521
|
-
} catch (err) {
|
|
522
|
-
await emitEnd({ status: 'invalid' });
|
|
523
|
-
throw err;
|
|
524
|
-
}
|
|
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 });
|
|
525
415
|
}
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* reconcile — dispatching it is pure token spend for a no-op. This module
|
|
13
13
|
* computes that decision **deterministically**, off the same two inputs the
|
|
14
14
|
* critic itself reads (the draft array and the Epic body's Delivery Slicing
|
|
15
|
-
* table), so
|
|
15
|
+
* table), so the planning workflow can skip the sub-agent
|
|
16
16
|
* dispatch when it is provably safe to.
|
|
17
17
|
*
|
|
18
18
|
* **Fail-open by design.** Every ambiguous case — a missing or unparseable
|
|
@@ -123,7 +123,7 @@ export function parseDeliverySlicingTable(epicBody) {
|
|
|
123
123
|
|
|
124
124
|
/**
|
|
125
125
|
* True when `story` is the recognized wave-0 BDD scaffold Story — identified
|
|
126
|
-
* by the literal `bdd-scaffold` goal token the
|
|
126
|
+
* by the literal `bdd-scaffold` goal token the decomposer prompt
|
|
127
127
|
* skill's WAVE-0 BDD SCAFFOLD STORY section requires. Scaffold Stories are
|
|
128
128
|
* not a Delivery Slicing slice, so they are excluded from the count
|
|
129
129
|
* comparison — BDD-adopting consumer repos still benefit from the
|
|
@@ -145,7 +145,7 @@ function isBddScaffoldStory(story) {
|
|
|
145
145
|
*
|
|
146
146
|
* @param {object} input
|
|
147
147
|
* @param {object[]} input.draftStories - The draft `tickets.json` array
|
|
148
|
-
* (
|
|
148
|
+
* (the decomposer's output) — raw Story ticket objects with
|
|
149
149
|
* top-level `slug` / `depends_on` / `body` (serialized string).
|
|
150
150
|
* @param {string} input.epicBody - The Epic body carrying the folded Tech
|
|
151
151
|
* Spec sections (`## Delivery Slicing` onward).
|