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
|
@@ -8,13 +8,16 @@
|
|
|
8
8
|
*
|
|
9
9
|
* The gateway is constructed with a `{ gh, owner, repo, hooks }` object so
|
|
10
10
|
* cross-gateway concerns can be threaded in without bloating the constructor
|
|
11
|
-
* signature.
|
|
12
|
-
*
|
|
13
|
-
* link a freshly-created child as a native sub-issue) and `addItemToProject`
|
|
14
|
-
* (from the projects-v2 shim, used by `createTicket` to add the new issue
|
|
15
|
-
* to the configured Project V2).
|
|
11
|
+
* signature. The `addItemToProject` hook (from the projects-v2 shim) adds a
|
|
12
|
+
* newly-created issue to the configured Project V2.
|
|
16
13
|
*
|
|
17
|
-
*
|
|
14
|
+
* Story #4545 deleted `createTicket` and its `composeStoryBody` helper — the
|
|
15
|
+
* Epic-hierarchy write surface. It composed the exact `Epic: #N` footer that
|
|
16
|
+
* `pr-base-guard.js` hard-refuses at delivery, so the framework retained the
|
|
17
|
+
* ability to generate work it would then reject; it had no production caller
|
|
18
|
+
* (`/plan` persists through the bare `createIssue` below).
|
|
19
|
+
*
|
|
20
|
+
* Public surface: `GitHubProvider.createIssue / getTicket /
|
|
18
21
|
* getTickets / updateTicket / getTicketDependencies / primeTicketCache /
|
|
19
22
|
* invalidateTicket` all delegate to the same-named methods on this class.
|
|
20
23
|
*
|
|
@@ -22,9 +25,7 @@
|
|
|
22
25
|
*/
|
|
23
26
|
|
|
24
27
|
import { parseBlockedBy, parseBlocks } from '../../lib/dependency-parser.js';
|
|
25
|
-
import { stampFrameworkVersion } from '../../lib/framework-version.js';
|
|
26
28
|
import { Logger } from '../../lib/Logger.js';
|
|
27
|
-
import { TYPE_LABELS } from '../../lib/label-constants.js';
|
|
28
29
|
import { addIssueToBoard } from './board-add.js';
|
|
29
30
|
import { createInlineTicketCache } from './cache.js';
|
|
30
31
|
import { withTransientRetry } from './errors.js';
|
|
@@ -43,70 +44,6 @@ import {
|
|
|
43
44
|
*/
|
|
44
45
|
const SEARCH_PAGE_CAP = 10;
|
|
45
46
|
|
|
46
|
-
/**
|
|
47
|
-
* Compose the final markdown body for a created ticket. Under the 2-tier
|
|
48
|
-
* hierarchy (Epic → Story), `body` is always a string supplied
|
|
49
|
-
* by the caller (the decomposer, the spec planner, or the reconciler-apply
|
|
50
|
-
* engine). This helper appends the canonical orchestrator footer
|
|
51
|
-
* (`parent: #<n>` / `Epic: #<m>` / `blocked by #<x>`) byte-stable with the
|
|
52
|
-
* format consumers (manifest, close-gate, dispatcher) parse.
|
|
53
|
-
*
|
|
54
|
-
* Story #3186 — inlined here when the Task-tier body-renderer helpers
|
|
55
|
-
* were retired. The structured-body (object) path is gone: Stories carry
|
|
56
|
-
* inline `acceptance[]` / `verify[]`
|
|
57
|
-
* arrays on the Story body authored by the decomposer; there is no
|
|
58
|
-
* server-side rendering of a four-section payload at create time.
|
|
59
|
-
*
|
|
60
|
-
* Story #4382 — this is also where a Story body is stamped, once, with the
|
|
61
|
-
* running Mandrel framework version and authoring date (hidden `mandrel_version`
|
|
62
|
-
* / `authored_at` meta field + a visible `> 🏷️ Authored with Mandrel …`
|
|
63
|
-
* marker) via {@link stampFrameworkVersion}. The stamp is immutable: a body
|
|
64
|
-
* that already carries a version (e.g. a reconciler re-create) is preserved
|
|
65
|
-
* verbatim. The `stamp` override exists for deterministic tests; production
|
|
66
|
-
* callers omit it so the running version and today's date are used.
|
|
67
|
-
*
|
|
68
|
-
* @param {{
|
|
69
|
-
* body: string,
|
|
70
|
-
* parentId: number,
|
|
71
|
-
* epicId?: number,
|
|
72
|
-
* dependencies?: number[],
|
|
73
|
-
* stamp?: { version?: string, authoredAt?: string } | false,
|
|
74
|
-
* }} opts
|
|
75
|
-
* @returns {string}
|
|
76
|
-
*
|
|
77
|
-
* Story #3958 — this is the single owner of the `blocked by #N` footer.
|
|
78
|
-
* Callers (the reconciler-apply create path, the spec planner) pass
|
|
79
|
-
* resolved dependency issue numbers via `dependencies` and supply a body
|
|
80
|
-
* WITHOUT any pre-appended footer. A caller that also appends a
|
|
81
|
-
* `blocked by` block to `body` would double every dependency line.
|
|
82
|
-
*/
|
|
83
|
-
export function composeStoryBody({
|
|
84
|
-
body,
|
|
85
|
-
parentId,
|
|
86
|
-
epicId,
|
|
87
|
-
dependencies = [],
|
|
88
|
-
stamp,
|
|
89
|
-
}) {
|
|
90
|
-
const rawHead = typeof body === 'string' ? body : '';
|
|
91
|
-
// `stamp === false` → footer-only recomposition: the caller (the reconciler
|
|
92
|
-
// UPDATE/diff path) owns stamp preservation itself and must NOT introduce a
|
|
93
|
-
// fresh authoring stamp, which would churn or bump the version on every
|
|
94
|
-
// reconcile. Every other call is a create — stamp once (immutably).
|
|
95
|
-
const head =
|
|
96
|
-
stamp === false ? rawHead : stampFrameworkVersion(rawHead, stamp ?? {});
|
|
97
|
-
const lines = ['---', `parent: #${parentId}`];
|
|
98
|
-
if (epicId !== undefined && epicId !== null) {
|
|
99
|
-
lines.push(`Epic: #${epicId}`);
|
|
100
|
-
}
|
|
101
|
-
if (dependencies.length > 0) {
|
|
102
|
-
lines.push('');
|
|
103
|
-
for (const dep of dependencies) {
|
|
104
|
-
lines.push(`blocked by #${dep}`);
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
return `${head}\n\n${lines.join('\n')}`;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
47
|
export class TicketGateway {
|
|
111
48
|
/**
|
|
112
49
|
* @param {{
|
|
@@ -114,7 +51,6 @@ export class TicketGateway {
|
|
|
114
51
|
* owner: string,
|
|
115
52
|
* repo: string,
|
|
116
53
|
* hooks?: {
|
|
117
|
-
* addSubIssue?: (parentNumber: number, childNodeId: string) => Promise<unknown>,
|
|
118
54
|
* addItemToProject?: (nodeId: string) => Promise<unknown>,
|
|
119
55
|
* getProjectNumber?: () => number|null,
|
|
120
56
|
* },
|
|
@@ -314,84 +250,10 @@ export class TicketGateway {
|
|
|
314
250
|
// ---------------------------------------------------------------------------
|
|
315
251
|
|
|
316
252
|
/**
|
|
317
|
-
* Create a
|
|
318
|
-
*
|
|
319
|
-
*
|
|
320
|
-
*
|
|
321
|
-
* After the POST, opportunistically link the child as a native sub-issue
|
|
322
|
-
* (via the `addSubIssue` hook — retried internally on the sub-issue
|
|
323
|
-
* gateway) and add it to the configured Project V2 (best-effort —
|
|
324
|
-
* failures warn but do not fail the create).
|
|
325
|
-
*
|
|
326
|
-
* @field-manifest POST /repos/{owner}/{repo}/issues: number, id, node_id,
|
|
327
|
-
* html_url
|
|
328
|
-
*/
|
|
329
|
-
/* node:coverage ignore next */
|
|
330
|
-
async createTicket(parentId, ticketData) {
|
|
331
|
-
const epicId = ticketData.epicId || parentId;
|
|
332
|
-
const renderedBody = composeStoryBody({
|
|
333
|
-
body: ticketData.body ?? '',
|
|
334
|
-
parentId,
|
|
335
|
-
epicId,
|
|
336
|
-
dependencies: ticketData.dependencies ?? [],
|
|
337
|
-
});
|
|
338
|
-
|
|
339
|
-
// Mirror the Epic create path (issues.js:160 → `labels: TYPE_LABELS.EPIC`):
|
|
340
|
-
// inject TYPE_LABELS.STORY so a spec that omits the labels array cannot
|
|
341
|
-
// produce an unlabeled, undispatchable Story. Dedupe to avoid duplicates
|
|
342
|
-
// when the caller already carries the label. (Story #4324 retired the
|
|
343
|
-
// `context::*` ticket classes, so every ticket created through this
|
|
344
|
-
// factory is a Story.)
|
|
345
|
-
const callerLabels = ticketData.labels ?? [];
|
|
346
|
-
const labels = callerLabels.includes(TYPE_LABELS.STORY)
|
|
347
|
-
? callerLabels
|
|
348
|
-
: [TYPE_LABELS.STORY, ...callerLabels];
|
|
349
|
-
const result = await this._gh.api({
|
|
350
|
-
method: 'POST',
|
|
351
|
-
endpoint: `/repos/${this.owner}/${this.repo}/issues`,
|
|
352
|
-
body: {
|
|
353
|
-
title: ticketData.title,
|
|
354
|
-
body: renderedBody,
|
|
355
|
-
labels,
|
|
356
|
-
},
|
|
357
|
-
});
|
|
358
|
-
const issue = parseApiJson(result);
|
|
359
|
-
this._listCache.clear();
|
|
360
|
-
|
|
361
|
-
let subIssueLinked = false;
|
|
362
|
-
let subIssueError = null;
|
|
363
|
-
try {
|
|
364
|
-
if (typeof this._hooks.addSubIssue === 'function') {
|
|
365
|
-
await this._hooks.addSubIssue(parentId, issue.node_id);
|
|
366
|
-
subIssueLinked = true;
|
|
367
|
-
}
|
|
368
|
-
} catch (err) {
|
|
369
|
-
subIssueError = err;
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
await addIssueToBoard({
|
|
373
|
-
nodeId: issue.node_id,
|
|
374
|
-
issueNumber: issue.number,
|
|
375
|
-
getProjectNumber: this._hooks.getProjectNumber,
|
|
376
|
-
addItemToProject: this._hooks.addItemToProject,
|
|
377
|
-
});
|
|
378
|
-
|
|
379
|
-
return {
|
|
380
|
-
id: issue.number,
|
|
381
|
-
internalId: issue.id,
|
|
382
|
-
nodeId: issue.node_id,
|
|
383
|
-
url: issue.html_url,
|
|
384
|
-
subIssueLinked,
|
|
385
|
-
subIssueError,
|
|
386
|
-
};
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
/**
|
|
390
|
-
* Create a **bare** issue — no `parent: #N` footer composition and no
|
|
391
|
-
* sub-issue link. Serves the standalone create paths that bypass
|
|
392
|
-
* `createTicket`'s Story-shaped body rendering: the `/plan`
|
|
393
|
-
* persist step and the `/plan` Phase 4 Epic open
|
|
394
|
-
* (`openEpicFromOnePager`'s `createIssue` port).
|
|
253
|
+
* Create a **bare** issue — no footer composition and no sub-issue link.
|
|
254
|
+
* Since Story #4545 this is the *only* create path: `/plan` persist and the
|
|
255
|
+
* `/plan` Phase 4 Epic open (`openEpicFromOnePager`'s `createIssue` port)
|
|
256
|
+
* both route through it.
|
|
395
257
|
*
|
|
396
258
|
* After the POST, the new issue is added to the configured Project V2
|
|
397
259
|
* board via the shared `addIssueToBoard` helper (Story #3822) —
|
|
@@ -399,6 +261,17 @@ export class TicketGateway {
|
|
|
399
261
|
* so board membership never depends on GitHub's "Auto-add to project"
|
|
400
262
|
* built-in workflow.
|
|
401
263
|
*
|
|
264
|
+
* The POST is wrapped in `withTransientRetry` (Story #4541) so it absorbs
|
|
265
|
+
* the same 502/429/ECONNRESET blips the read surfaces already do. It used
|
|
266
|
+
* to post bare, which made a single transient failure at story *k* of *N*
|
|
267
|
+
* abort `/plan` persist with `1..k-1` already live on the tracker.
|
|
268
|
+
*
|
|
269
|
+
* Retry alone is not sufficient for that failure mode — a POST whose
|
|
270
|
+
* response is lost would double-create on the retry — so the caller
|
|
271
|
+
* (`plan-persist`'s `createStoryIssues`) carries the idempotency half via
|
|
272
|
+
* a plan fingerprint it looks up before creating. Retry narrows the
|
|
273
|
+
* window; the fingerprint closes it.
|
|
274
|
+
*
|
|
402
275
|
* @field-manifest POST /repos/{owner}/{repo}/issues: number, id, node_id,
|
|
403
276
|
* html_url
|
|
404
277
|
*
|
|
@@ -413,11 +286,15 @@ export class TicketGateway {
|
|
|
413
286
|
* }>}
|
|
414
287
|
*/
|
|
415
288
|
async createIssue({ title, body, labels = [] }) {
|
|
416
|
-
const result = await
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
289
|
+
const result = await withTransientRetry(
|
|
290
|
+
() =>
|
|
291
|
+
this._gh.api({
|
|
292
|
+
method: 'POST',
|
|
293
|
+
endpoint: `/repos/${this.owner}/${this.repo}/issues`,
|
|
294
|
+
body: { title, body, labels },
|
|
295
|
+
}),
|
|
296
|
+
{ label: `createIssue "${title}"`, onRetry: defaultRetryWarn },
|
|
297
|
+
);
|
|
421
298
|
const issue = parseApiJson(result);
|
|
422
299
|
this._listCache.clear();
|
|
423
300
|
|
|
@@ -80,9 +80,23 @@ export class GitHubProvider extends ITicketingProvider {
|
|
|
80
80
|
return this._memoizedToken;
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
83
|
+
/**
|
|
84
|
+
* The identifiers a native dependency-edge writer needs, handed over as an
|
|
85
|
+
* explicit interface (Story #4544).
|
|
86
|
+
*
|
|
87
|
+
* `providers/github/blocked-by-add.js` talks to the dependencies REST API
|
|
88
|
+
* directly, so it needs the `gh` facade plus `owner`/`repo` — none of which
|
|
89
|
+
* the `ITicketingProvider` surface exposes. Its caller lives in the
|
|
90
|
+
* orchestration layer (`plan-persist/story-ops.js`), and the alternative was
|
|
91
|
+
* for that caller to reach through `provider._gh` — a private-by-convention
|
|
92
|
+
* field — from outside this module. Naming the hand-off here keeps the
|
|
93
|
+
* coupling declared and greppable instead of incidental: the provider
|
|
94
|
+
* decides what it lends out, and the field stays private.
|
|
95
|
+
*
|
|
96
|
+
* @returns {{ gh: object, owner: string, repo: string }}
|
|
97
|
+
*/
|
|
98
|
+
getDependencyWriteContext() {
|
|
99
|
+
return { gh: this._gh, owner: this.owner, repo: this.repo };
|
|
86
100
|
}
|
|
87
101
|
|
|
88
102
|
static isInsufficientScopes(err) {
|
|
@@ -100,7 +114,6 @@ const DELEGATIONS = [
|
|
|
100
114
|
['graphql', 'issues.ghGraphql'],
|
|
101
115
|
['searchIssues', 'issues.searchIssues'],
|
|
102
116
|
['listIssuesByLabel', 'issues.listIssuesByLabel'],
|
|
103
|
-
['getEpics', 'issues.getEpics'],
|
|
104
117
|
['getEpic', 'issues.getEpic'],
|
|
105
118
|
['branchExists', 'issues.branchExists'],
|
|
106
119
|
['getSubTickets', 'issues.getSubTickets'],
|
|
@@ -108,12 +121,10 @@ const DELEGATIONS = [
|
|
|
108
121
|
['getTickets', 'tickets.getTickets'],
|
|
109
122
|
['getTicket', 'tickets.getTicket'],
|
|
110
123
|
['getTicketDependencies', 'tickets.getTicketDependencies'],
|
|
111
|
-
['createTicket', 'tickets.createTicket'],
|
|
112
124
|
['createIssue', 'tickets.createIssue'],
|
|
113
125
|
['updateTicket', 'tickets.updateTicket'],
|
|
114
126
|
['_applyLabelMutations', 'tickets._applyLabelMutations'],
|
|
115
127
|
['_getNativeSubIssues', 'subIssues.getNativeSubIssues'],
|
|
116
|
-
['_getNativeParent', 'subIssues.getNativeParent'],
|
|
117
128
|
['addSubIssue', 'subIssues.addSubIssue'],
|
|
118
129
|
['removeSubIssue', 'subIssues.removeSubIssue'],
|
|
119
130
|
['reconcileSubIssueLinks', 'subIssues.reconcileSubIssueLinks'],
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* resolve-stories.js — resolve a list of Story ids into the
|
|
5
|
+
* `{ stories, dag, done }` envelope `/deliver` sequences from.
|
|
6
|
+
*
|
|
7
|
+
* This is the ONE resolution step for multi-Story delivery. `/deliver` takes
|
|
8
|
+
* only Story ids; the graph is discovered here, from live state, rather than
|
|
9
|
+
* hand-transcribed by the host or implied by a batch label.
|
|
10
|
+
*
|
|
11
|
+
* What it resolves, per Story:
|
|
12
|
+
* - the issue itself, fetched with **state=all** so an already-landed
|
|
13
|
+
* sibling is present rather than silently dropped;
|
|
14
|
+
* - its dependency edges: the union of body-parsed `blocked by #N` /
|
|
15
|
+
* `depends on #N` and native GitHub `blocked_by` edges;
|
|
16
|
+
* - its declared file footprint, as plain path strings, so the scheduler's
|
|
17
|
+
* co-dispatch overlap guard has something to work with.
|
|
18
|
+
*
|
|
19
|
+
* And across the set: every dependency id — inside the requested set or
|
|
20
|
+
* foreign to it — is checked against live issue state, and a blocker that is
|
|
21
|
+
* closed or `agent::done` lands in `done[]`. That is what makes "deliver
|
|
22
|
+
* Stories across plan runs and over time" work: a Story whose blocker merged
|
|
23
|
+
* weeks ago in a different run is simply ready.
|
|
24
|
+
*
|
|
25
|
+
* Usage:
|
|
26
|
+
* node .agents/scripts/resolve-stories.js --ids 101,102
|
|
27
|
+
* node .agents/scripts/resolve-stories.js --ids 101,102 --pretty
|
|
28
|
+
* node .agents/scripts/resolve-stories.js --ids 101 --no-native # skip the dependencies API
|
|
29
|
+
*
|
|
30
|
+
* Exit codes: 0 ok, 1 usage/resolution error.
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
import { parseArgs } from 'node:util';
|
|
34
|
+
|
|
35
|
+
import { runAsCli } from './lib/cli-utils.js';
|
|
36
|
+
import { resolveConfig } from './lib/config-resolver.js';
|
|
37
|
+
import { Logger, routeAllOutputToStderr } from './lib/Logger.js';
|
|
38
|
+
import {
|
|
39
|
+
buildStoriesEnvelope,
|
|
40
|
+
isSatisfiedBlocker,
|
|
41
|
+
parseIds,
|
|
42
|
+
readNativeBlockedBy,
|
|
43
|
+
toStoryRecord,
|
|
44
|
+
} from './lib/orchestration/resolve-stories.js';
|
|
45
|
+
import { createProvider } from './lib/provider-factory.js';
|
|
46
|
+
import { concurrentMap } from './lib/util/concurrent-map.js';
|
|
47
|
+
import { parseApiJson } from './providers/github/request-helpers.js';
|
|
48
|
+
|
|
49
|
+
export { buildStoriesEnvelope, parseIds, readNativeBlockedBy, toStoryRecord };
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Bounded concurrency for the per-issue round-trips. Matches the edge-writer's
|
|
53
|
+
* cap: modest enough for GitHub's secondary rate limits, while collapsing
|
|
54
|
+
* wall-clock from sum(round-trips) toward sum/concurrency.
|
|
55
|
+
*/
|
|
56
|
+
const FETCH_CONCURRENCY = 5;
|
|
57
|
+
|
|
58
|
+
const HELP = `\
|
|
59
|
+
Usage:
|
|
60
|
+
resolve-stories.js --ids <n,n,...> [--pretty] [--no-native]
|
|
61
|
+
|
|
62
|
+
Resolve Story ids into the { stories, dag, done } envelope /deliver sequences
|
|
63
|
+
from. Dependencies are discovered from live state: body edges union native
|
|
64
|
+
blocked_by edges, with every blocker (in-set or foreign) resolved against its
|
|
65
|
+
real issue state.
|
|
66
|
+
|
|
67
|
+
Options:
|
|
68
|
+
--ids <csv> Comma-separated Story issue numbers. Required.
|
|
69
|
+
--pretty Pretty-print the JSON envelope.
|
|
70
|
+
--no-native Skip the native blocked_by read (body edges only).
|
|
71
|
+
--help Show this help.
|
|
72
|
+
`;
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* @param {object} [deps]
|
|
76
|
+
* @returns {{ provider: object, config: object }}
|
|
77
|
+
*/
|
|
78
|
+
export function resolveStoriesProvider({
|
|
79
|
+
resolveConfigFn = resolveConfig,
|
|
80
|
+
createProviderFn = createProvider,
|
|
81
|
+
} = {}) {
|
|
82
|
+
const config = resolveConfigFn();
|
|
83
|
+
return { provider: createProviderFn(config), config };
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Fetch every requested id and map it to a Story record, failing on the first
|
|
88
|
+
* id that is not a deliverable Story.
|
|
89
|
+
*
|
|
90
|
+
* @param {object} provider
|
|
91
|
+
* @param {number[]} ids
|
|
92
|
+
* @returns {Promise<object[]>}
|
|
93
|
+
*/
|
|
94
|
+
export async function fetchStories(provider, ids) {
|
|
95
|
+
return concurrentMap(
|
|
96
|
+
ids,
|
|
97
|
+
async (id) => {
|
|
98
|
+
const issue = await provider.getTicket(id);
|
|
99
|
+
if (!issue) {
|
|
100
|
+
throw new Error(`[resolve-stories] Issue #${id} was not found.`);
|
|
101
|
+
}
|
|
102
|
+
return toStoryRecord(issue, id);
|
|
103
|
+
},
|
|
104
|
+
{ concurrency: FETCH_CONCURRENCY },
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Read native blocked_by edges for every Story in the set.
|
|
110
|
+
*
|
|
111
|
+
* @returns {Promise<Map<number, number[]>>}
|
|
112
|
+
*/
|
|
113
|
+
export async function readNativeEdges({ provider, stories, owner, repo }) {
|
|
114
|
+
const entries = await concurrentMap(
|
|
115
|
+
stories,
|
|
116
|
+
async (story) => [
|
|
117
|
+
story.id,
|
|
118
|
+
await readNativeBlockedBy({
|
|
119
|
+
gh: provider._gh,
|
|
120
|
+
owner,
|
|
121
|
+
repo,
|
|
122
|
+
issueNumber: story.id,
|
|
123
|
+
parseJson: parseApiJson,
|
|
124
|
+
}),
|
|
125
|
+
],
|
|
126
|
+
{ concurrency: FETCH_CONCURRENCY },
|
|
127
|
+
);
|
|
128
|
+
return new Map(entries);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Resolve dependency ids that are NOT in the requested set against live issue
|
|
133
|
+
* state. A foreign blocker that already landed must enter `done[]`, or the
|
|
134
|
+
* scheduler withholds its dependent forever — the exact wedge that made
|
|
135
|
+
* cross-run delivery impossible.
|
|
136
|
+
*
|
|
137
|
+
* A foreign id that cannot be read is left OUT of `done[]`: unknown means
|
|
138
|
+
* "still gating", which withholds the dependent rather than dispatching it
|
|
139
|
+
* against a possibly-unlanded blocker.
|
|
140
|
+
*
|
|
141
|
+
* @returns {Promise<number[]>}
|
|
142
|
+
*/
|
|
143
|
+
export async function resolveForeignDone({ provider, dag, inSetIds }) {
|
|
144
|
+
const foreign = [
|
|
145
|
+
...new Set(
|
|
146
|
+
dag.flatMap((node) => node.dependsOn).filter((dep) => !inSetIds.has(dep)),
|
|
147
|
+
),
|
|
148
|
+
];
|
|
149
|
+
if (foreign.length === 0) return [];
|
|
150
|
+
const resolved = await concurrentMap(
|
|
151
|
+
foreign,
|
|
152
|
+
async (id) => {
|
|
153
|
+
try {
|
|
154
|
+
const issue = await provider.getTicket(id);
|
|
155
|
+
return isSatisfiedBlocker(issue) ? id : null;
|
|
156
|
+
} catch (err) {
|
|
157
|
+
Logger.warn(
|
|
158
|
+
`[resolve-stories] Could not read foreign blocker #${id} (${err?.message ?? err}) — ` +
|
|
159
|
+
`treating it as still gating.`,
|
|
160
|
+
);
|
|
161
|
+
return null;
|
|
162
|
+
}
|
|
163
|
+
},
|
|
164
|
+
{ concurrency: FETCH_CONCURRENCY },
|
|
165
|
+
);
|
|
166
|
+
return resolved.filter((id) => id !== null);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
async function main() {
|
|
170
|
+
const { values } = parseArgs({
|
|
171
|
+
options: {
|
|
172
|
+
ids: { type: 'string' },
|
|
173
|
+
pretty: { type: 'boolean', default: false },
|
|
174
|
+
native: { type: 'boolean', default: true },
|
|
175
|
+
help: { type: 'boolean', default: false },
|
|
176
|
+
},
|
|
177
|
+
// The documented opt-out is `--no-native`; without allowNegative,
|
|
178
|
+
// parseArgs rejects it as an unknown option and the CLI has no working
|
|
179
|
+
// way to skip the dependencies API.
|
|
180
|
+
allowNegative: true,
|
|
181
|
+
allowPositionals: false,
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
if (values.help) {
|
|
185
|
+
process.stdout.write(HELP);
|
|
186
|
+
return 0;
|
|
187
|
+
}
|
|
188
|
+
if (!values.ids) {
|
|
189
|
+
process.stderr.write(HELP);
|
|
190
|
+
throw new Error('[resolve-stories] --ids <n,n,...> is required');
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// stdout is a JSON stream — keep human-readable output on stderr so a
|
|
194
|
+
// headless caller can pipe this straight into stories-wave-tick.js.
|
|
195
|
+
routeAllOutputToStderr();
|
|
196
|
+
|
|
197
|
+
const ids = parseIds(values.ids);
|
|
198
|
+
const { provider, config } = resolveStoriesProvider();
|
|
199
|
+
const owner = config.github?.owner;
|
|
200
|
+
const repo = config.github?.repo;
|
|
201
|
+
|
|
202
|
+
const stories = await fetchStories(provider, ids);
|
|
203
|
+
const nativeEdges = values.native
|
|
204
|
+
? await readNativeEdges({ provider, stories, owner, repo })
|
|
205
|
+
: new Map();
|
|
206
|
+
|
|
207
|
+
const inSetIds = new Set(stories.map((s) => s.id));
|
|
208
|
+
const provisional = buildStoriesEnvelope({
|
|
209
|
+
stories,
|
|
210
|
+
nativeEdges,
|
|
211
|
+
warn: (m) => Logger.warn(m),
|
|
212
|
+
});
|
|
213
|
+
const foreignDone = await resolveForeignDone({
|
|
214
|
+
provider,
|
|
215
|
+
dag: provisional.dag,
|
|
216
|
+
inSetIds,
|
|
217
|
+
});
|
|
218
|
+
const envelope = buildStoriesEnvelope({
|
|
219
|
+
stories,
|
|
220
|
+
nativeEdges,
|
|
221
|
+
foreignDone,
|
|
222
|
+
warn: () => {},
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
process.stdout.write(
|
|
226
|
+
values.pretty
|
|
227
|
+
? `${JSON.stringify(envelope, null, 2)}\n`
|
|
228
|
+
: `${JSON.stringify(envelope)}\n`,
|
|
229
|
+
);
|
|
230
|
+
return 0;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
runAsCli(import.meta.url, main, {
|
|
234
|
+
source: 'resolve-stories',
|
|
235
|
+
propagateExitCode: true,
|
|
236
|
+
});
|
|
@@ -45,6 +45,7 @@ import { fileURLToPath } from 'node:url';
|
|
|
45
45
|
|
|
46
46
|
import { cleanupRepoTestTempArtifacts } from './cleanup-repo-test-temp.js';
|
|
47
47
|
import { C8_CLI } from './lib/c8-cli-path.js';
|
|
48
|
+
import { buildWebhookSafeTestEnv } from './lib/test-env.js';
|
|
48
49
|
import { TEST_RUNNER_FLAGS } from './run-tests.js';
|
|
49
50
|
|
|
50
51
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
@@ -89,7 +90,9 @@ function runCoveragePipeline() {
|
|
|
89
90
|
const testRun = spawnSync(process.execPath, buildCoverageTestArgs(), {
|
|
90
91
|
cwd: ROOT,
|
|
91
92
|
stdio: 'inherit',
|
|
92
|
-
|
|
93
|
+
// GIT_*-scrubbed: under a husky pre-push from a linked worktree the
|
|
94
|
+
// inherited GIT_DIR poisons fixture `git init` runs (#4580).
|
|
95
|
+
env: { ...buildWebhookSafeTestEnv(process.env), NODE_V8_COVERAGE: V8_TMP },
|
|
93
96
|
});
|
|
94
97
|
|
|
95
98
|
cleanupRepoTestTempArtifacts({ repoRoot: ROOT });
|
|
@@ -73,8 +73,8 @@ const tasks = [
|
|
|
73
73
|
// spans for axis-shaped tokens (`type/epic`, etc.) and asserts
|
|
74
74
|
// only the canonical `<axis>::<value>` separator from
|
|
75
75
|
// `lib/label-constants.js` appears. Closes the drift gap that
|
|
76
|
-
// let the original `type/epic` typo land
|
|
77
|
-
//
|
|
76
|
+
// let the original `type/epic` typo land in a since-retired
|
|
77
|
+
// planning workflow helper.
|
|
78
78
|
name: 'label-vocabulary',
|
|
79
79
|
cmd: 'node',
|
|
80
80
|
args: ['.agents/scripts/lint-label-vocabulary.js'],
|
|
@@ -5,14 +5,28 @@
|
|
|
5
5
|
* Local full verification — a true CI mirror for the gates that CAN be proven
|
|
6
6
|
* locally, without epic-scoped MI projection or push semantics.
|
|
7
7
|
*
|
|
8
|
-
* Order: audit (SCA) → lint (includes docs:check
|
|
9
|
-
* unified baselines
|
|
8
|
+
* Order: audit (SCA) → lint (includes docs:check + the arch-cycles ratchet) →
|
|
9
|
+
* full test suite → unified baselines → the dead-exports and context-budget
|
|
10
|
+
* ratchets.
|
|
10
11
|
*
|
|
11
12
|
* The `audit` step runs `npm audit --audit-level=high`, matching CI's
|
|
12
13
|
* "Dependency Vulnerability Audit (SCA)" gate so a local green no longer hides
|
|
13
14
|
* a high-severity advisory that CI would fail on. It is independent of the
|
|
14
15
|
* pre-push `PREPUSH_AUDIT` opt-in, which stays unchanged.
|
|
15
16
|
*
|
|
17
|
+
* The trailing ratchets complete the mirror of CI's "Architecture Cycle Check"
|
|
18
|
+
* step in the `baselines` job (Story #4549). That step runs three checks;
|
|
19
|
+
* `check-arch-cycles.js` is deliberately absent from STEPS because the `lint`
|
|
20
|
+
* step above already runs it (see run-lint.js) — re-running it here would
|
|
21
|
+
* double-pay a gate verify already covers. `check-dead-exports.js` and
|
|
22
|
+
* `check-context-budget.js` had no such cover: they were reachable locally only
|
|
23
|
+
* via the diff-scoped `npm run quality:preview` or a direct invocation, so a
|
|
24
|
+
* clean `verify` could still hide a CI-red — the failure Story #4531 / PR #4548
|
|
25
|
+
* paid for with a full push → CI → fix → push round-trip. Both are pure-Node
|
|
26
|
+
* and baseline-aware, adding ~15s on a cold cache (dominated by knip's
|
|
27
|
+
* full-tree scan in check-dead-exports.js) to a command that already carries
|
|
28
|
+
* the full test suite.
|
|
29
|
+
*
|
|
16
30
|
* A handful of CI gates cannot be reproduced by this command (action pinning,
|
|
17
31
|
* TruffleHog secret scan, the BASELINE_SCOPE=full push-scoped maintainability
|
|
18
32
|
* run) — those are catalogued in docs/ci-contract.md.
|
|
@@ -34,6 +48,21 @@ const STEPS = [
|
|
|
34
48
|
cmd: 'node',
|
|
35
49
|
args: ['.agents/scripts/check-baselines.js'],
|
|
36
50
|
},
|
|
51
|
+
{
|
|
52
|
+
label: 'dead-exports',
|
|
53
|
+
cmd: 'node',
|
|
54
|
+
args: ['.agents/scripts/check-dead-exports.js'],
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
label: 'dead-exports-production',
|
|
58
|
+
cmd: 'node',
|
|
59
|
+
args: ['.agents/scripts/check-dead-exports.js', '--production'],
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
label: 'context-budget',
|
|
63
|
+
cmd: 'node',
|
|
64
|
+
args: ['.agents/scripts/check-context-budget.js'],
|
|
65
|
+
},
|
|
37
66
|
];
|
|
38
67
|
|
|
39
68
|
export function runVerifySteps({
|