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
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* plan-run-epilogue.js — execute the real per-run closeout for a
|
|
4
|
+
* multi-Story `/deliver`.
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* node .agents/scripts/plan-run-epilogue.js --stories 1,2,3
|
|
8
|
+
*
|
|
9
|
+
* Keyed on the delivered id set: an `adhoc-<sorted-ids>` run id is
|
|
10
|
+
* synthesized from `--stories`. Story #4540 retired the `--run <planRunId>`
|
|
11
|
+
* label-resolution branch along with the `plan-run::<id>` label itself.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import './lib/runtime-deps/ensure-installed.js';
|
|
15
|
+
import { parseArgs } from 'node:util';
|
|
16
|
+
|
|
17
|
+
import { runAsCli } from './lib/cli-utils.js';
|
|
18
|
+
import { resolveConfig } from './lib/config-resolver.js';
|
|
19
|
+
import { Logger } from './lib/Logger.js';
|
|
20
|
+
import { runPlanRunEpilogue } from './lib/orchestration/run-epilogue.js';
|
|
21
|
+
import { createProvider } from './lib/provider-factory.js';
|
|
22
|
+
|
|
23
|
+
const CLI_OPTIONS = {
|
|
24
|
+
stories: { type: 'string' },
|
|
25
|
+
cwd: { type: 'string' },
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @param {string[]} [argv]
|
|
30
|
+
* @returns {Promise<object>}
|
|
31
|
+
*/
|
|
32
|
+
export async function main(argv = process.argv.slice(2)) {
|
|
33
|
+
const { values } = parseArgs({
|
|
34
|
+
args: argv,
|
|
35
|
+
options: CLI_OPTIONS,
|
|
36
|
+
strict: false,
|
|
37
|
+
});
|
|
38
|
+
const hasStoriesFlag =
|
|
39
|
+
typeof values.stories === 'string' && values.stories.trim().length > 0;
|
|
40
|
+
if (!hasStoriesFlag) {
|
|
41
|
+
throw new Error('Usage: node plan-run-epilogue.js --stories 1,2,3');
|
|
42
|
+
}
|
|
43
|
+
const cwd =
|
|
44
|
+
typeof values.cwd === 'string' && values.cwd.trim()
|
|
45
|
+
? values.cwd.trim()
|
|
46
|
+
: process.cwd();
|
|
47
|
+
const config = resolveConfig({ cwd });
|
|
48
|
+
const provider = createProvider(config);
|
|
49
|
+
|
|
50
|
+
// Story #4540 retired the `--run <planRunId>` label-resolution branch
|
|
51
|
+
// along with the label itself. The epilogue is keyed on the delivered id
|
|
52
|
+
// set, and the synthesized `adhoc-<ids>` id it already used for positional
|
|
53
|
+
// runs is now the only id it needs.
|
|
54
|
+
const stories = values.stories
|
|
55
|
+
.split(',')
|
|
56
|
+
.map((s) => Number(s.trim()))
|
|
57
|
+
.filter((n) => Number.isInteger(n) && n > 0);
|
|
58
|
+
|
|
59
|
+
const planRunId = `adhoc-${[...stories].sort((a, b) => a - b).join('-')}`;
|
|
60
|
+
|
|
61
|
+
const result = await runPlanRunEpilogue({
|
|
62
|
+
planRunId,
|
|
63
|
+
stories,
|
|
64
|
+
provider,
|
|
65
|
+
config,
|
|
66
|
+
cwd,
|
|
67
|
+
});
|
|
68
|
+
warnOnUnresolvedBase(result);
|
|
69
|
+
warnOnEmptyRollup(result);
|
|
70
|
+
Logger.info(JSON.stringify(result, null, 2));
|
|
71
|
+
if (result.errors?.length) {
|
|
72
|
+
process.exitCode = 1;
|
|
73
|
+
}
|
|
74
|
+
return result;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Surface an unresolvable combined landed diff as a loud operator warning.
|
|
79
|
+
*
|
|
80
|
+
* The roster's changed-file set is the input the host walks its audit lenses
|
|
81
|
+
* against; a silent absence would read as "nothing changed" and the lens walk
|
|
82
|
+
* would look complete while covering nothing. Not fatal — with no diff the
|
|
83
|
+
* selector degrades to keyword-only lens selection, so the rest of the
|
|
84
|
+
* roster is still useful.
|
|
85
|
+
*
|
|
86
|
+
* @param {object} result - `runPlanRunEpilogue` envelope.
|
|
87
|
+
* @returns {void}
|
|
88
|
+
*/
|
|
89
|
+
function warnOnUnresolvedBase(result) {
|
|
90
|
+
const roster = (result?.results ?? []).find(
|
|
91
|
+
(r) => r?.kind === 'audit-roster',
|
|
92
|
+
);
|
|
93
|
+
const base = roster?.baseResolution;
|
|
94
|
+
if (base?.resolved !== false) return;
|
|
95
|
+
Logger.warn(
|
|
96
|
+
`⚠️ Combined landed diff unavailable — the pre-run base sha could not be ` +
|
|
97
|
+
`resolved against \`${base.baseRef}\`: ${base.reason}\n` +
|
|
98
|
+
` changedFiles is null (NOT an empty set). Determine the run diff by ` +
|
|
99
|
+
`hand before walking the selected lenses.`,
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Surface a zero-signal roll-up over a multi-Story run as a loud operator
|
|
105
|
+
* warning (Story #4578).
|
|
106
|
+
*
|
|
107
|
+
* The failure this exists to prevent is a *reassuring* one. The roll-up read
|
|
108
|
+
* "No friction signals — nothing to follow up" for a 7-Story run that
|
|
109
|
+
* contained a mid-run git outage, a parked worker needing an operator
|
|
110
|
+
* resume, and an acceptance critic that needed four rounds. Nothing was
|
|
111
|
+
* broken in the roll-up — the stream really was empty — but the report was
|
|
112
|
+
* indistinguishable from a clean run, so the retro loop that exists to learn
|
|
113
|
+
* from a run was silently blind to that run's pain.
|
|
114
|
+
*
|
|
115
|
+
* Not fatal: a genuinely friction-free multi-Story run is possible, and this
|
|
116
|
+
* cannot tell the two apart — which is precisely why it asks the operator
|
|
117
|
+
* rather than asserting either reading.
|
|
118
|
+
*
|
|
119
|
+
* @param {object} result - `runPlanRunEpilogue` envelope.
|
|
120
|
+
* @returns {void}
|
|
121
|
+
*/
|
|
122
|
+
function warnOnEmptyRollup(result) {
|
|
123
|
+
const rollup = (result?.results ?? []).find(
|
|
124
|
+
(r) => r?.kind === 'follow-up-rollup',
|
|
125
|
+
);
|
|
126
|
+
if (!rollup?.emptyRollupSuspect) return;
|
|
127
|
+
Logger.warn(
|
|
128
|
+
`⚠️ 0 friction signals across ${rollup.storyCount} Stories — telemetry may not ` +
|
|
129
|
+
`have fired.\n` +
|
|
130
|
+
` An empty roll-up is NOT evidence of a clean run: it is the same output a ` +
|
|
131
|
+
`run with\n` +
|
|
132
|
+
` heavy friction produces when nothing recorded it. The runtime emits ` +
|
|
133
|
+
`friction from its\n` +
|
|
134
|
+
` own observables (agent::blocked transitions, failed closes, exhausted ` +
|
|
135
|
+
`merge waits), so\n` +
|
|
136
|
+
` zero here also means none of those fired. If this run had friction you ` +
|
|
137
|
+
`can name, that\n` +
|
|
138
|
+
` telemetry gap is itself worth filing.`,
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
await runAsCli(import.meta.url, main);
|
|
@@ -22,10 +22,6 @@ import fs from 'node:fs/promises';
|
|
|
22
22
|
import { parseArgs } from 'node:util';
|
|
23
23
|
import { runAsCli } from './lib/cli-utils.js';
|
|
24
24
|
import { resolveConfig } from './lib/config-resolver.js';
|
|
25
|
-
import {
|
|
26
|
-
outboxPathFor,
|
|
27
|
-
postCommentOrBuffer,
|
|
28
|
-
} from './lib/orchestration/bookkeeping-outbox.js';
|
|
29
25
|
import {
|
|
30
26
|
assertValidStructuredCommentType,
|
|
31
27
|
upsertStructuredComment,
|
|
@@ -41,11 +37,6 @@ Flags:
|
|
|
41
37
|
retro, epic-run-state, wave-0-start) (required).
|
|
42
38
|
--body-file Path to a file containing the markdown body (required).
|
|
43
39
|
--provider Provider name (default: inferred from .agentrc.json github block).
|
|
44
|
-
--buffer Headless mode: buffer this upsert to the per-Epic bookkeeping
|
|
45
|
-
outbox instead of posting live. Requires --epic. Drained to
|
|
46
|
-
GitHub once at finalize by bookkeeping-reconcile.js (Epic
|
|
47
|
-
#4476). Omit for attended runs (posts live, unchanged).
|
|
48
|
-
--epic <id> Epic id owning the outbox (required with --buffer).
|
|
49
40
|
--help Show this message.
|
|
50
41
|
`;
|
|
51
42
|
|
|
@@ -73,8 +64,6 @@ export function parseArgv(argv) {
|
|
|
73
64
|
marker: { type: 'string' },
|
|
74
65
|
'body-file': { type: 'string' },
|
|
75
66
|
provider: { type: 'string' },
|
|
76
|
-
buffer: { type: 'boolean' },
|
|
77
|
-
epic: { type: 'string' },
|
|
78
67
|
help: { type: 'boolean' },
|
|
79
68
|
},
|
|
80
69
|
strict: false,
|
|
@@ -126,33 +115,6 @@ export async function main(argv = process.argv.slice(2)) {
|
|
|
126
115
|
: config;
|
|
127
116
|
const provider = createProvider(effectiveConfig);
|
|
128
117
|
|
|
129
|
-
// Headless buffering (Epic #4476 M5): route the upsert to the per-Epic
|
|
130
|
-
// outbox instead of a live GitHub round-trip. Requires --epic to locate the
|
|
131
|
-
// outbox; finalize's bookkeeping-reconcile.js drains it once. Attended runs
|
|
132
|
-
// (no --buffer) are unchanged.
|
|
133
|
-
if (values.buffer) {
|
|
134
|
-
const epicId = Number.parseInt(values.epic ?? '', 10);
|
|
135
|
-
if (!Number.isInteger(epicId) || epicId <= 0) {
|
|
136
|
-
process.stderr.write(
|
|
137
|
-
'[post-structured-comment] --buffer requires --epic <id>.\n',
|
|
138
|
-
);
|
|
139
|
-
process.exit(2);
|
|
140
|
-
}
|
|
141
|
-
assertValidStructuredCommentType(values.marker);
|
|
142
|
-
const { buffered } = await postCommentOrBuffer({
|
|
143
|
-
provider,
|
|
144
|
-
ticketId,
|
|
145
|
-
marker: values.marker,
|
|
146
|
-
body,
|
|
147
|
-
headless: true,
|
|
148
|
-
outboxPath: outboxPathFor(epicId, config),
|
|
149
|
-
});
|
|
150
|
-
process.stdout.write(
|
|
151
|
-
`${JSON.stringify({ success: true, ticketId, type: values.marker, buffered })}\n`,
|
|
152
|
-
);
|
|
153
|
-
return;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
118
|
const envelope = await runPostStructuredComment({
|
|
157
119
|
ticketId,
|
|
158
120
|
type: values.marker,
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* pr-watch-with-update.js — the single CI-watch mechanism for
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* `gh pr checks --watch` from the single-Story path so both drive this
|
|
7
|
-
* one CLI.
|
|
3
|
+
* pr-watch-with-update.js — the single CI-watch mechanism for the Story
|
|
4
|
+
* delivery path (`helpers/deliver-story.md` Step 4). Story #4358 retired
|
|
5
|
+
* the bare `gh pr checks --watch` so every caller drives this one CLI.
|
|
8
6
|
*
|
|
9
7
|
* Polls the PR's required checks to a terminal state and auto-recovers
|
|
10
8
|
* from `mergeStateStatus: BEHIND` (via bounded `gh pr update-branch`
|
|
@@ -17,10 +15,13 @@
|
|
|
17
15
|
* - GREEN — every required check terminal + green → exit 0.
|
|
18
16
|
* - RED — one or more required checks genuinely failed → exit 1
|
|
19
17
|
* IMMEDIATELY, consuming no resume budget. On red the CLI
|
|
20
|
-
* writes `temp/
|
|
18
|
+
* writes `temp/story-<id>-ci-digest.{json,md}` (failing check
|
|
21
19
|
* name, run id, a `gh run view --log-failed` tail, and a
|
|
22
20
|
* coarse classification) and prints the red-green
|
|
23
|
-
* remediation handoff.
|
|
21
|
+
* remediation handoff. The digest is scoped by filename, so
|
|
22
|
+
* it requires `--story` (Story #4539: the digest was
|
|
23
|
+
* Epic-scoped and therefore never written on the only
|
|
24
|
+
* delivery path v2 has).
|
|
24
25
|
* - STILL-RUNNING — the poll cap fired with checks still pending and
|
|
25
26
|
* none failed; the watcher re-armed up to
|
|
26
27
|
* `delivery.ci.watch.maxResumes` times, then returned a
|
|
@@ -35,8 +36,8 @@
|
|
|
35
36
|
* CLI flags override config; config overrides the framework fallback.
|
|
36
37
|
*
|
|
37
38
|
* Usage:
|
|
38
|
-
* node .agents/scripts/pr-watch-with-update.js --pr <n>
|
|
39
|
-
* [--
|
|
39
|
+
* node .agents/scripts/pr-watch-with-update.js --pr <n> --story <id>
|
|
40
|
+
* [--repo owner/repo] [--max-updates N] [--poll-interval-ms MS]
|
|
40
41
|
* [--max-polls N] [--max-resumes N]
|
|
41
42
|
*/
|
|
42
43
|
import { spawnSync } from 'node:child_process';
|
|
@@ -161,13 +162,33 @@ function resolveRunId({ prRef, checkName, cwd, spawnFn = spawnSync }) {
|
|
|
161
162
|
}
|
|
162
163
|
}
|
|
163
164
|
|
|
165
|
+
/**
|
|
166
|
+
* Resolve which ticket the digest is keyed to. Story #4539: the digest used
|
|
167
|
+
* to be Epic-scoped by filename and returned `null` without an epic id — so
|
|
168
|
+
* on the v2 Story path (which has no Epic and invokes the watch with `--pr`
|
|
169
|
+
* alone) a red check wrote no digest at all, despite the module header
|
|
170
|
+
* advertising one. v2.0.0 removed the Epic tier; Story scope is the only
|
|
171
|
+
* scope.
|
|
172
|
+
*
|
|
173
|
+
* @param {{ storyId?: number|string|null }} opts
|
|
174
|
+
* @returns {{ kind: 'story', id: number } | null}
|
|
175
|
+
*/
|
|
176
|
+
export function resolveDigestScope({ storyId = null } = {}) {
|
|
177
|
+
if (storyId == null || String(storyId).length === 0) return null;
|
|
178
|
+
const parsed = Number.parseInt(String(storyId), 10);
|
|
179
|
+
return Number.isInteger(parsed) && parsed > 0
|
|
180
|
+
? { kind: 'story', id: parsed }
|
|
181
|
+
: null;
|
|
182
|
+
}
|
|
183
|
+
|
|
164
184
|
/**
|
|
165
185
|
* Write the CI failure digest (`.json` + `.md`) for a red watch. Returns
|
|
166
|
-
* the two paths written
|
|
167
|
-
* digest is
|
|
186
|
+
* the two paths written, or `null` when no story id was supplied (the
|
|
187
|
+
* digest is scoped by filename and has nothing to key on). Exported for
|
|
188
|
+
* tests.
|
|
168
189
|
*
|
|
169
190
|
* @param {object} opts
|
|
170
|
-
* @param {number|string|null} opts.
|
|
191
|
+
* @param {number|string|null} [opts.storyId] The v2 delivery scope.
|
|
171
192
|
* @param {number} opts.prNumber
|
|
172
193
|
* @param {Array<{name:string, outcome:string}>} opts.failures
|
|
173
194
|
* @param {string} opts.tempRoot
|
|
@@ -178,7 +199,7 @@ function resolveRunId({ prRef, checkName, cwd, spawnFn = spawnSync }) {
|
|
|
178
199
|
* @returns {{ jsonPath: string, mdPath: string } | null}
|
|
179
200
|
*/
|
|
180
201
|
export function writeCiDigest({
|
|
181
|
-
|
|
202
|
+
storyId = null,
|
|
182
203
|
prNumber,
|
|
183
204
|
failures,
|
|
184
205
|
tempRoot,
|
|
@@ -187,13 +208,14 @@ export function writeCiDigest({
|
|
|
187
208
|
runIdFn = resolveRunId,
|
|
188
209
|
logTailFn = ghRunLogTail,
|
|
189
210
|
}) {
|
|
190
|
-
|
|
211
|
+
const scope = resolveDigestScope({ storyId });
|
|
212
|
+
if (!scope) return null;
|
|
191
213
|
const primary = failures[0] ?? { name: 'unknown', outcome: 'failure' };
|
|
192
214
|
const runId = runIdFn({ prRef, checkName: primary.name, cwd });
|
|
193
215
|
const logTail = logTailFn({ runId, cwd });
|
|
194
216
|
const classification = classifyFailure(primary.name);
|
|
195
217
|
const digest = {
|
|
196
|
-
|
|
218
|
+
storyId: scope.id,
|
|
197
219
|
prNumber,
|
|
198
220
|
failingCheck: primary.name,
|
|
199
221
|
failingOutcome: primary.outcome,
|
|
@@ -205,12 +227,12 @@ export function writeCiDigest({
|
|
|
205
227
|
};
|
|
206
228
|
const dir = path.isAbsolute(tempRoot) ? tempRoot : path.join(cwd, tempRoot);
|
|
207
229
|
mkdirSync(dir, { recursive: true });
|
|
208
|
-
const base =
|
|
230
|
+
const base = `${scope.kind}-${scope.id}-ci-digest`;
|
|
209
231
|
const jsonPath = path.join(dir, `${base}.json`);
|
|
210
232
|
const mdPath = path.join(dir, `${base}.md`);
|
|
211
233
|
writeFileSync(jsonPath, `${JSON.stringify(digest, null, 2)}\n`);
|
|
212
234
|
const md = [
|
|
213
|
-
`# CI failure digest —
|
|
235
|
+
`# CI failure digest — Story #${scope.id} (PR #${prNumber})`,
|
|
214
236
|
'',
|
|
215
237
|
`- **Failing check:** \`${digest.failingCheck}\` (${digest.failingOutcome})`,
|
|
216
238
|
`- **Run id:** ${runId ?? 'unresolved'}`,
|
|
@@ -247,7 +269,6 @@ export function writeCiDigest({
|
|
|
247
269
|
* @param {object} opts
|
|
248
270
|
* @param {number} opts.prNumber
|
|
249
271
|
* @param {string|null} [opts.repo]
|
|
250
|
-
* @param {number|string|null} [opts.epicId] Epic id for the red-path digest.
|
|
251
272
|
* @param {number|string} [opts.maxUpdates]
|
|
252
273
|
* @param {number|string} [opts.pollIntervalMs]
|
|
253
274
|
* @param {number|string} [opts.maxPolls]
|
|
@@ -266,7 +287,7 @@ export function writeCiDigest({
|
|
|
266
287
|
export async function runPrWatch({
|
|
267
288
|
prNumber,
|
|
268
289
|
repo = null,
|
|
269
|
-
|
|
290
|
+
storyId = null,
|
|
270
291
|
maxUpdates,
|
|
271
292
|
pollIntervalMs,
|
|
272
293
|
maxPolls,
|
|
@@ -377,7 +398,7 @@ export async function runPrWatch({
|
|
|
377
398
|
let digestPaths = null;
|
|
378
399
|
try {
|
|
379
400
|
digestPaths = writeDigestFn({
|
|
380
|
-
|
|
401
|
+
storyId,
|
|
381
402
|
prNumber,
|
|
382
403
|
failures,
|
|
383
404
|
tempRoot: effectiveTempRoot,
|
|
@@ -415,7 +436,7 @@ async function main() {
|
|
|
415
436
|
options: {
|
|
416
437
|
pr: { type: 'string' },
|
|
417
438
|
repo: { type: 'string' },
|
|
418
|
-
|
|
439
|
+
story: { type: 'string' },
|
|
419
440
|
'max-updates': { type: 'string' },
|
|
420
441
|
'poll-interval-ms': { type: 'string' },
|
|
421
442
|
'max-polls': { type: 'string' },
|
|
@@ -426,7 +447,7 @@ async function main() {
|
|
|
426
447
|
return runPrWatch({
|
|
427
448
|
prNumber: Number.parseInt(values.pr ?? '', 10),
|
|
428
449
|
repo: values.repo ?? null,
|
|
429
|
-
|
|
450
|
+
storyId: values.story ?? null,
|
|
430
451
|
maxUpdates: values['max-updates'],
|
|
431
452
|
pollIntervalMs: values['poll-interval-ms'],
|
|
432
453
|
maxPolls: values['max-polls'],
|
|
@@ -272,22 +272,3 @@ export const REMOVE_SUB_ISSUE_MUTATION = `
|
|
|
272
272
|
subIssue { number }
|
|
273
273
|
}
|
|
274
274
|
}`;
|
|
275
|
-
|
|
276
|
-
// Story #2982 — native parent lookup for the cascade upward walk. The
|
|
277
|
-
// inverse of `SUB_ISSUES_QUERY`: given a child Issue node, fetch the
|
|
278
|
-
// `parent` field exposed by the Sub-Issues feature so `cascadeCompletion`
|
|
279
|
-
// can resolve a parent even when the child body lacks the `parent: #N`
|
|
280
|
-
// orchestrator footer.
|
|
281
|
-
export const PARENT_ISSUE_QUERY = `query($id: ID!) {
|
|
282
|
-
node(id: $id) {
|
|
283
|
-
... on Issue {
|
|
284
|
-
parent {
|
|
285
|
-
number
|
|
286
|
-
databaseId
|
|
287
|
-
id
|
|
288
|
-
title
|
|
289
|
-
state
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
}`;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Owns the remaining read-side surface that did not belong to any of the
|
|
5
5
|
* earlier six gateways: the raw GraphQL shim (`graphql` / `_ghGraphql`),
|
|
6
|
-
* epic
|
|
6
|
+
* epic reads (`getEpic`), repository-wide label scans
|
|
7
7
|
* (`listIssuesByLabel`), branch existence probes (`branchExists`), and the
|
|
8
8
|
* three-strategy sub-ticket aggregator (`getSubTickets`).
|
|
9
9
|
*
|
|
@@ -16,11 +16,10 @@
|
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
18
|
import { Logger } from '../../lib/Logger.js';
|
|
19
|
-
import { TYPE_LABELS } from '../../lib/label-constants.js';
|
|
20
19
|
import { concurrentMap } from '../../lib/util/concurrent-map.js';
|
|
21
20
|
import { isNotFoundError } from './branch-protection.js';
|
|
22
21
|
import { withTransientRetry } from './errors.js';
|
|
23
|
-
import { issueToEpic
|
|
22
|
+
import { issueToEpic } from './mappers.js';
|
|
24
23
|
import {
|
|
25
24
|
defaultRetryWarn,
|
|
26
25
|
paginateRest,
|
|
@@ -114,13 +113,15 @@ export class IssuesGateway {
|
|
|
114
113
|
* are returned (no `state:` qualifier is appended) so a closed-fingerprint
|
|
115
114
|
* match can surface as `regression-of-closed`.
|
|
116
115
|
*
|
|
117
|
-
* Returns the trimmed `[{ number, state, body }]`
|
|
118
|
-
*
|
|
119
|
-
*
|
|
116
|
+
* Returns the trimmed `[{ number, state, body, title, html_url }]`
|
|
117
|
+
* projection. Dedup callers use `{ number, state, body }`; duplicate-
|
|
118
|
+
* search also needs `title` / `html_url`. `state` is normalised to the
|
|
119
|
+
* REST lowercase form (`open` / `closed`). Results are capped at one
|
|
120
|
+
* Search API page (`per_page=100`).
|
|
120
121
|
*
|
|
121
122
|
* @param {{ query: string, owner?: string, repo?: string }} params
|
|
122
|
-
* @returns {Promise<Array<{ number: number, state: string, body: string }>>}
|
|
123
|
-
* @field-manifest GET /search/issues: total_count, items[number, state, body]
|
|
123
|
+
* @returns {Promise<Array<{ number: number, state: string, body: string, title: string, html_url?: string }>>}
|
|
124
|
+
* @field-manifest GET /search/issues: total_count, items[number, state, body, title, html_url]
|
|
124
125
|
*/
|
|
125
126
|
async searchIssues({ query, owner, repo } = {}) {
|
|
126
127
|
if (typeof query !== 'string' || query.trim().length === 0) {
|
|
@@ -133,7 +134,8 @@ export class IssuesGateway {
|
|
|
133
134
|
// issue body where the `<!-- audit-fingerprints: ... -->` footer lives.
|
|
134
135
|
const qualifiers = [`repo:${scopeOwner}/${scopeRepo}`, 'type:issue'];
|
|
135
136
|
const q = `${query.trim()} ${qualifiers.join(' ')}`;
|
|
136
|
-
const
|
|
137
|
+
const params = new URLSearchParams({ q, per_page: '100' });
|
|
138
|
+
const endpoint = `/search/issues?${params}`;
|
|
137
139
|
const result = await withTransientRetry(
|
|
138
140
|
() => this._gh.api({ method: 'GET', endpoint }),
|
|
139
141
|
{ label: `searchIssues ${query}`, onRetry: defaultRetryWarn },
|
|
@@ -144,39 +146,11 @@ export class IssuesGateway {
|
|
|
144
146
|
number: item.number,
|
|
145
147
|
state: item.state ?? 'open',
|
|
146
148
|
body: item.body ?? '',
|
|
149
|
+
title: item.title ?? '',
|
|
150
|
+
html_url: item.html_url ?? undefined,
|
|
147
151
|
}));
|
|
148
152
|
}
|
|
149
153
|
|
|
150
|
-
/**
|
|
151
|
-
* List Epic-typed issues. Filter shape preserved from the old code.
|
|
152
|
-
*
|
|
153
|
-
* `filters.pageCap` / `filters.perPage` pass through to `paginateRest`
|
|
154
|
-
* so a caller that only needs a bounded shortlist (e.g. the
|
|
155
|
-
* standalone-Story corpus lookup in `planning-corpus.js`, which ranks
|
|
156
|
-
* candidates down to a top-5 shortlist) can cap the scan instead of
|
|
157
|
-
* inheriting the default 50-page / 5000-item ceiling. Omitted, both
|
|
158
|
-
* fall back to `paginateRest`'s own defaults — unchanged behavior for
|
|
159
|
-
* existing callers (e.g. `duplicate-search.js`).
|
|
160
|
-
*
|
|
161
|
-
* @field-manifest /repos/{owner}/{repo}/issues?labels=type::epic: number,
|
|
162
|
-
* title, labels, state, state_reason, pull_request
|
|
163
|
-
*/
|
|
164
|
-
/* node:coverage ignore next */
|
|
165
|
-
async getEpics(filters = {}) {
|
|
166
|
-
const params = new URLSearchParams({
|
|
167
|
-
state: filters.state ?? 'all',
|
|
168
|
-
labels: TYPE_LABELS.EPIC,
|
|
169
|
-
});
|
|
170
|
-
const endpoint = `/repos/${this.owner}/${this.repo}/issues?${params}`;
|
|
171
|
-
const issues = await paginateRest(this._gh, endpoint, {
|
|
172
|
-
pageCap: filters.pageCap,
|
|
173
|
-
perPage: filters.perPage,
|
|
174
|
-
});
|
|
175
|
-
return issues
|
|
176
|
-
.filter((issue) => !issue.pull_request)
|
|
177
|
-
.map(issueToEpicListItem);
|
|
178
|
-
}
|
|
179
|
-
|
|
180
154
|
/**
|
|
181
155
|
* @field-manifest /repos/{owner}/{repo}/issues/{n}: number, id, node_id,
|
|
182
156
|
* title, body, labels, state
|
|
@@ -35,6 +35,11 @@ export function issueToTicket(issue) {
|
|
|
35
35
|
labelSet: new Set(labels),
|
|
36
36
|
assignees: (issue.assignees ?? []).map((a) => a.login),
|
|
37
37
|
state: issue.state,
|
|
38
|
+
// `completed` | `not_planned` | `reopened` | null. `state` alone cannot
|
|
39
|
+
// tell a Story that landed from one closed as superseded — both read
|
|
40
|
+
// `closed` — so the close path needs this to avoid reporting a
|
|
41
|
+
// never-merged Story as landed.
|
|
42
|
+
stateReason: issue.state_reason ?? null,
|
|
38
43
|
};
|
|
39
44
|
}
|
|
40
45
|
|
|
@@ -109,15 +114,3 @@ export function issueToListItem(issue) {
|
|
|
109
114
|
state: issue.state,
|
|
110
115
|
};
|
|
111
116
|
}
|
|
112
|
-
|
|
113
|
-
export function issueToEpicListItem(issue) {
|
|
114
|
-
const labels = normalizeLabels(issue);
|
|
115
|
-
return {
|
|
116
|
-
id: issue.number,
|
|
117
|
-
title: issue.title,
|
|
118
|
-
labels,
|
|
119
|
-
labelSet: new Set(labels),
|
|
120
|
-
state: issue.state,
|
|
121
|
-
state_reason: issue.state_reason,
|
|
122
|
-
};
|
|
123
|
-
}
|
|
@@ -30,7 +30,6 @@ import { concurrentMap } from '../../lib/util/concurrent-map.js';
|
|
|
30
30
|
import {
|
|
31
31
|
ADD_SUB_ISSUE_MUTATION,
|
|
32
32
|
classifyGithubError as defaultClassifyGithubError,
|
|
33
|
-
PARENT_ISSUE_QUERY,
|
|
34
33
|
REMOVE_SUB_ISSUE_MUTATION,
|
|
35
34
|
SUB_ISSUES_QUERY,
|
|
36
35
|
withTransientRetry,
|
|
@@ -134,52 +133,6 @@ export class SubIssueGateway {
|
|
|
134
133
|
return childIds;
|
|
135
134
|
}
|
|
136
135
|
|
|
137
|
-
/**
|
|
138
|
-
* Strategy 2 — native GitHub Sub-Issues, inverse direction. Given a
|
|
139
|
-
* child Issue node, return the parent's issue number (or `null` when
|
|
140
|
-
* the child has no native parent link, or the feature is disabled on
|
|
141
|
-
* this repo). Story #2982: used by `cascadeCompletion` as a third
|
|
142
|
-
* fallback so a Story whose body lost the `parent: #N` orchestrator
|
|
143
|
-
* footer still cascades upward to its true Sub-Issue parent.
|
|
144
|
-
*
|
|
145
|
-
* @param {string} childNodeId GraphQL node ID of the child Issue.
|
|
146
|
-
* @param {number} childNumber Issue number, for log context only.
|
|
147
|
-
* @returns {Promise<number|null>}
|
|
148
|
-
*/
|
|
149
|
-
async getNativeParent(childNodeId, childNumber) {
|
|
150
|
-
if (!childNodeId) return null;
|
|
151
|
-
try {
|
|
152
|
-
const data = await withTransientRetry(
|
|
153
|
-
() =>
|
|
154
|
-
this._ghGraphql(
|
|
155
|
-
PARENT_ISSUE_QUERY,
|
|
156
|
-
{ id: childNodeId },
|
|
157
|
-
{ headers: { 'GraphQL-Features': 'sub_issues' } },
|
|
158
|
-
),
|
|
159
|
-
{
|
|
160
|
-
label: `getNativeParent child=#${childNumber}`,
|
|
161
|
-
classify: this._classify,
|
|
162
|
-
onRetry: defaultRetryWarn,
|
|
163
|
-
},
|
|
164
|
-
);
|
|
165
|
-
const parent = data?.node?.parent;
|
|
166
|
-
if (!parent || typeof parent.number !== 'number') return null;
|
|
167
|
-
return parent.number;
|
|
168
|
-
} catch (err) {
|
|
169
|
-
const category = this._classify(err);
|
|
170
|
-
if (category === 'feature-disabled') {
|
|
171
|
-
Logger.warn(
|
|
172
|
-
`[GitHubProvider] sub-issues parent lookup unavailable (child #${childNumber})`,
|
|
173
|
-
);
|
|
174
|
-
return null;
|
|
175
|
-
}
|
|
176
|
-
Logger.error(
|
|
177
|
-
`[GitHubProvider] native parent lookup failed (child #${childNumber}, category=${category}): ${err.message}`,
|
|
178
|
-
);
|
|
179
|
-
throw err;
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
|
|
183
136
|
/**
|
|
184
137
|
* Establish the native sub-issue link between `parentNumber` and the
|
|
185
138
|
* child identified by `childNodeId`. Retries on transient errors with
|