mandrel 1.94.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/README.md +59 -73
- package/.agents/agents/story-worker.md +12 -13
- package/.agents/docs/SDLC.md +489 -1285
- package/.agents/docs/agentrc-reference.json +177 -67
- package/.agents/docs/configuration.md +104 -138
- package/.agents/docs/execution-reference.md +17 -20
- package/.agents/docs/quality-gates.md +13 -19
- package/.agents/docs/workflows.md +3 -3
- package/.agents/instructions.md +70 -81
- package/.agents/rules/ci-remediation.md +8 -12
- package/.agents/rules/git-conventions-reference.md +6 -7
- package/.agents/rules/git-conventions.md +16 -22
- package/.agents/schemas/acceptance-eval-verdict.schema.json +1 -1
- package/.agents/schemas/agentrc.schema.json +54 -214
- package/.agents/schemas/lifecycle/ledger-record.schema.json +1 -1
- package/.agents/schemas/lifecycle/retro.end.schema.json +1 -1
- package/.agents/schemas/risk-verdict.schema.json +0 -13
- package/.agents/scripts/analyze-execution.js +1 -1
- package/.agents/scripts/audit-to-stories.js +7 -7
- package/.agents/scripts/boot-sweep.js +1 -1
- package/.agents/scripts/check-lifecycle-lint.js +6 -9
- package/.agents/scripts/check-prepush-recovery.js +1 -1
- package/.agents/scripts/cleanup-repo-test-temp.js +6 -1
- 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 +5 -5
- 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 -4
- package/.agents/scripts/lib/baselines/reader.js +1 -6
- package/.agents/scripts/lib/bdd-runner-detect.js +5 -9
- package/.agents/scripts/lib/bootstrap/issue-forms-template.js +32 -33
- package/.agents/scripts/lib/checks/core-bare-clean.js +2 -2
- package/.agents/scripts/lib/checks/index.js +2 -1
- package/.agents/scripts/lib/checks/story-init-not-backgrounded.js +23 -21
- package/.agents/scripts/lib/cli/standard-args.js +13 -22
- package/.agents/scripts/lib/cli-args.js +16 -7
- package/.agents/scripts/lib/close-validation/gates.js +2 -2
- package/.agents/scripts/lib/config/ci.js +6 -31
- package/.agents/scripts/lib/config/delivery-routing.js +45 -29
- package/.agents/scripts/lib/config/explain.js +55 -36
- package/.agents/scripts/lib/config/limits.js +17 -58
- package/.agents/scripts/lib/config/paths.js +0 -2
- package/.agents/scripts/lib/config/quality.js +1 -1
- package/.agents/scripts/lib/config/runners.js +17 -50
- package/.agents/scripts/lib/config/temp-paths.js +19 -14
- 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 +24 -148
- package/.agents/scripts/lib/config-settings-schema-quality.js +8 -14
- package/.agents/scripts/lib/config-settings-schema.js +52 -38
- 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 +211 -41
- package/.agents/scripts/lib/feedback-loop/retro-proposals-graduator.js +1 -1
- package/.agents/scripts/lib/findings/promote-finding.js +5 -5
- package/.agents/scripts/lib/framework-version.js +2 -3
- package/.agents/scripts/lib/git-branch-cleanup.js +1 -10
- package/.agents/scripts/lib/git-branch-lifecycle.js +17 -22
- package/.agents/scripts/lib/git-utils.js +32 -6
- package/.agents/scripts/lib/github/framework-repo.js +6 -0
- package/.agents/scripts/lib/label-constants.js +10 -23
- package/.agents/scripts/lib/label-taxonomy.js +9 -43
- package/.agents/scripts/lib/observability/active-story-env.js +1 -1
- package/.agents/scripts/lib/observability/hook-heartbeat.js +20 -52
- package/.agents/scripts/lib/observability/source-classifier.js +3 -3
- package/.agents/scripts/lib/onboard/init-tail.js +1 -3
- package/.agents/scripts/lib/orchestration/audit-lens-routing.js +128 -0
- package/.agents/scripts/lib/orchestration/bookkeeping-outbox.js +8 -5
- package/.agents/scripts/lib/orchestration/ceremony-routing.js +83 -20
- package/.agents/scripts/lib/orchestration/code-review.js +20 -268
- package/.agents/scripts/lib/orchestration/column-sync.js +1 -1
- package/.agents/scripts/lib/orchestration/consolidation-precondition.js +1 -1
- package/.agents/scripts/lib/orchestration/context-envelope.js +2 -5
- 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/lifecycle/emit-loop-tick.js +8 -8
- package/.agents/scripts/lib/orchestration/lifecycle/emit-story-heartbeat.js +2 -2
- package/.agents/scripts/lib/orchestration/lifecycle/ledger-writer.js +6 -3
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/README.md +17 -43
- package/.agents/scripts/lib/orchestration/lint-baseline-service.js +4 -4
- package/.agents/scripts/lib/orchestration/merge-block-class.js +1 -1
- package/.agents/scripts/lib/orchestration/phase-runner.js +3 -2
- package/.agents/scripts/lib/orchestration/plan-context.js +248 -266
- package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +1 -1
- package/.agents/scripts/lib/orchestration/plan-navigation.js +92 -0
- package/.agents/scripts/lib/orchestration/plan-persist/fan-out-gate.js +61 -0
- package/.agents/scripts/lib/orchestration/plan-persist/persist-helpers.js +97 -0
- package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +223 -854
- package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +361 -0
- package/.agents/scripts/lib/orchestration/plan-persist/summary.js +35 -108
- 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 +13 -13
- package/.agents/scripts/lib/orchestration/planning/decomposer-context.js +27 -0
- package/.agents/scripts/lib/orchestration/{epic-plan-spec/phases → planning}/risk-verdict.js +3 -4
- package/.agents/scripts/lib/orchestration/post-merge/phases/branch-cleanup.js +2 -2
- package/.agents/scripts/lib/orchestration/post-merge/phases/dashboard-refresh.js +8 -20
- package/.agents/scripts/lib/orchestration/post-merge/phases/worktree-reap.js +3 -2
- package/.agents/scripts/lib/orchestration/pr-base-guard.js +18 -28
- package/.agents/scripts/lib/orchestration/preflight-cache.js +5 -5
- package/.agents/scripts/lib/orchestration/remote-verifier.js +1 -1
- package/.agents/scripts/lib/orchestration/resolve-plan-run.js +155 -0
- package/.agents/scripts/lib/orchestration/resolves-token.js +1 -1
- package/.agents/scripts/lib/orchestration/retro-perf-heuristics.js +8 -8
- package/.agents/scripts/lib/orchestration/retro-proposals.js +140 -79
- package/.agents/scripts/lib/orchestration/review-depth.js +26 -12
- package/.agents/scripts/lib/orchestration/review-providers/codex.js +2 -2
- package/.agents/scripts/lib/orchestration/review-providers/review-provider-factory.js +21 -56
- package/.agents/scripts/lib/orchestration/run-epilogue.js +426 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +1 -1
- package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +95 -41
- package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +16 -13
- package/.agents/scripts/lib/orchestration/single-story-close/phases/review-block.js +40 -0
- package/.agents/scripts/lib/orchestration/single-story-close/runner.js +11 -3
- 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/phases/code-review.js +15 -12
- package/.agents/scripts/lib/orchestration/story-follow-ups.js +237 -0
- package/.agents/scripts/lib/orchestration/story-init-remote.js +47 -0
- package/.agents/scripts/lib/orchestration/story-plan-state.js +48 -0
- package/.agents/scripts/lib/orchestration/{epic-runner → story-progress}/story-run-progress-writer.js +3 -3
- package/.agents/scripts/lib/orchestration/structured-comment-parser.js +1 -1
- package/.agents/scripts/lib/orchestration/task-body-validator.js +8 -18
- package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +11 -61
- package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +189 -373
- package/.agents/scripts/lib/orchestration/ticket-validator.js +2 -7
- package/.agents/scripts/lib/orchestration/ticketing/bulk.js +0 -25
- package/.agents/scripts/lib/orchestration/ticketing/reads.js +29 -26
- package/.agents/scripts/lib/orchestration/ticketing/transition.js +5 -5
- package/.agents/scripts/lib/planning-corpus.js +16 -11
- package/.agents/scripts/lib/preflight-runner.js +2 -2
- package/.agents/scripts/lib/qa/coverage-verdict.js +5 -5
- package/.agents/scripts/lib/single-story/confirm-merge-follow-ups.js +36 -0
- package/.agents/scripts/lib/single-story-sweep/protection-ctx.js +1 -1
- package/.agents/scripts/lib/story-adjacency.js +11 -14
- package/.agents/scripts/lib/story-body/story-body.js +124 -70
- package/.agents/scripts/lib/story-plan.js +2 -4
- package/.agents/scripts/lib/templates/decomposer-prompts.js +46 -45
- package/.agents/scripts/lib/templates/spec-author-prompts.js +47 -45
- package/.agents/scripts/lib/{epic-body-sections.js → ticket-body-sections.js} +26 -26
- package/.agents/scripts/lib/validation-evidence.js +1 -1
- package/.agents/scripts/lib/wave-runner/ready-set.js +6 -6
- package/.agents/scripts/lib/workspace-provisioner.js +1 -1
- package/.agents/scripts/lib/worktree/lifecycle/reap.js +5 -7
- 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 +64 -74
- package/.agents/scripts/plan-persist.js +121 -280
- package/.agents/scripts/plan-run-epilogue.js +97 -0
- package/.agents/scripts/providers/github/issues.js +17 -33
- package/.agents/scripts/providers/github/mappers.js +0 -12
- package/.agents/scripts/providers/github/tickets.js +2 -5
- package/.agents/scripts/resolve-plan-run.js +117 -0
- package/.agents/scripts/signals-view.js +24 -19
- package/.agents/scripts/single-story-close.js +11 -14
- package/.agents/scripts/single-story-confirm-merge.js +39 -23
- package/.agents/scripts/single-story-init.js +29 -20
- package/.agents/scripts/stories-wave-tick.js +6 -6
- package/.agents/scripts/story-plan.js +26 -47
- package/.agents/scripts/update-ticket-state.js +6 -15
- package/.agents/skills/core/analyze-execution/SKILL.md +21 -18
- package/.agents/skills/core/idea-refinement/SKILL.md +6 -6
- package/.agents/skills/core/scope-triage/SKILL.md +28 -172
- package/.agents/skills/skills.index.json +3 -43
- package/.agents/starter-agentrc.json +0 -5
- package/.agents/templates/agent-protocol.md +9 -10
- package/.agents/workflows/audit-architecture.md +3 -3
- package/.agents/workflows/audit-clean-code.md +3 -3
- package/.agents/workflows/audit-dependencies.md +3 -3
- package/.agents/workflows/audit-devops.md +3 -3
- package/.agents/workflows/audit-documentation.md +5 -5
- package/.agents/workflows/audit-lighthouse.md +3 -3
- package/.agents/workflows/audit-navigability.md +3 -2
- package/.agents/workflows/audit-performance.md +3 -3
- package/.agents/workflows/audit-privacy.md +3 -3
- package/.agents/workflows/audit-quality.md +3 -3
- package/.agents/workflows/audit-security.md +3 -3
- package/.agents/workflows/audit-seo.md +3 -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 +3 -3
- package/.agents/workflows/deliver.md +122 -174
- package/.agents/workflows/git-cleanup.md +3 -4
- package/.agents/workflows/helpers/_merge-conflict-template.md +1 -1
- package/.agents/workflows/helpers/acceptance-self-eval.md +16 -29
- package/.agents/workflows/helpers/code-review.md +70 -193
- package/.agents/workflows/helpers/{single-story-deliver-reference.md → deliver-story-reference.md} +12 -14
- package/.agents/workflows/helpers/{single-story-deliver.md → deliver-story.md} +113 -139
- package/.agents/workflows/helpers/diagnose.md +10 -10
- package/.agents/workflows/helpers/parallel-tooling.md +1 -1
- package/.agents/workflows/helpers/signals.md +16 -16
- package/.agents/workflows/helpers/worktree-lifecycle.md +48 -64
- package/.agents/workflows/mandrel-update.md +2 -1
- package/.agents/workflows/plan.md +112 -145
- package/.agents/workflows/qa-assist.md +24 -30
- package/.agents/workflows/qa-explore.md +29 -38
- package/.agents/workflows/qa-run.md +2 -2
- package/README.md +9 -8
- package/docs/CHANGELOG.md +30 -0
- package/lib/migrations/index.js +6 -5
- 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-spec.schema.json +0 -153
- 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/scripts/acceptance-spec-reconciler.js +0 -642
- package/.agents/scripts/bookkeeping-reconcile.js +0 -117
- 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/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/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/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/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/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/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/post-merge-pipeline.js +0 -205
- 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-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/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/scripts/lib/orchestration/{epic-plan-spec/phases → planning}/spec-authoring-grounding.js +0 -0
|
@@ -1,539 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* lib/orchestration/context-hydration-engine.js — Context Hydration Engine (SDK)
|
|
3
|
-
*
|
|
4
|
-
* Stateless, async logic for assembling the full execution prompt for an
|
|
5
|
-
* agent task. Extracted from the CLI entry point to enable reuse across
|
|
6
|
-
* consumers (CLI wrappers, tests).
|
|
7
|
-
*
|
|
8
|
-
* This module is the SDK layer — it has no knowledge of CLI arguments,
|
|
9
|
-
* file I/O decisions, or process.exit(). All I/O choices are delegated
|
|
10
|
-
* to the caller.
|
|
11
|
-
*
|
|
12
|
-
* Consumers import `hydrateContext` from this module directly — the former
|
|
13
|
-
* `hydrate-context.js` CLI wrapper was retired (#4482) with no live consumer.
|
|
14
|
-
*
|
|
15
|
-
* @see .agents/scripts/lib/ITicketingProvider.js
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
|
-
import crypto from 'node:crypto';
|
|
19
|
-
import fs from 'node:fs';
|
|
20
|
-
import path from 'node:path';
|
|
21
|
-
import { getCommands } from '../config/commands.js';
|
|
22
|
-
import {
|
|
23
|
-
getLimits,
|
|
24
|
-
getPaths,
|
|
25
|
-
PROJECT_ROOT,
|
|
26
|
-
resolveConfig,
|
|
27
|
-
} from '../config-resolver.js';
|
|
28
|
-
import { sliceEpicBodyForDelivery } from '../epic-body-sections.js';
|
|
29
|
-
import { resolveFrameworkVersion } from '../framework-version.js';
|
|
30
|
-
import { Logger } from '../Logger.js';
|
|
31
|
-
import {
|
|
32
|
-
buildEnvelope,
|
|
33
|
-
DEFAULT_ELIDE_POLICIES,
|
|
34
|
-
DEFAULT_SECTION_PRIORITIES,
|
|
35
|
-
elideEnvelope,
|
|
36
|
-
envelopeToPrompt,
|
|
37
|
-
} from './context-envelope.js';
|
|
38
|
-
|
|
39
|
-
// ---------------------------------------------------------------------------
|
|
40
|
-
// File-content cache — the agent-protocol template is read-only during a
|
|
41
|
-
// dispatch run.
|
|
42
|
-
// ---------------------------------------------------------------------------
|
|
43
|
-
|
|
44
|
-
const _fileCache = new Map();
|
|
45
|
-
|
|
46
|
-
function readFileCached(absPath) {
|
|
47
|
-
if (_fileCache.has(absPath)) return _fileCache.get(absPath);
|
|
48
|
-
const content = fs.readFileSync(absPath, 'utf8');
|
|
49
|
-
_fileCache.set(absPath, content);
|
|
50
|
-
return content;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
// ---------------------------------------------------------------------------
|
|
54
|
-
// Internal helpers
|
|
55
|
-
// ---------------------------------------------------------------------------
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Resolve the framework version. Delegates to the shared
|
|
59
|
-
* {@link resolveFrameworkVersion} helper (single owner of the root
|
|
60
|
-
* `package.json` read) so the hydrator and the ticket-body stamp read the same
|
|
61
|
-
* source. Retained as a thin named wrapper so the mismatch-warning call sites
|
|
62
|
-
* below read against a stable local name.
|
|
63
|
-
*
|
|
64
|
-
* @returns {string}
|
|
65
|
-
*/
|
|
66
|
-
function getVersion() {
|
|
67
|
-
return resolveFrameworkVersion();
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Parse the work-breakdown hierarchy from a Task ticket body.
|
|
72
|
-
*
|
|
73
|
-
* Looks for patterns like: `Epic: #1`, `Story: #3`.
|
|
74
|
-
*
|
|
75
|
-
* @param {string} body
|
|
76
|
-
* @returns {Record<string, number>}
|
|
77
|
-
*/
|
|
78
|
-
function parseHierarchy(body) {
|
|
79
|
-
const result = {};
|
|
80
|
-
if (!body) return result;
|
|
81
|
-
|
|
82
|
-
const matches = [...body.matchAll(/([A-Za-z\s]+):\s*#(\d+)/gi)];
|
|
83
|
-
for (const match of matches) {
|
|
84
|
-
const key = match[1].trim().toLowerCase().replace(/\s+/g, '');
|
|
85
|
-
const val = Number.parseInt(match[2], 10);
|
|
86
|
-
result[key] = val; // e.g. { epic: 1, story: 3 }
|
|
87
|
-
}
|
|
88
|
-
return result;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Extract the markdown list items under a `## <heading>` section of a
|
|
93
|
-
* Story body. Returns an empty array when the section is missing or has
|
|
94
|
-
* no list items. Recognises both `- ` (incl. `- [ ]` / `- [x]`) and
|
|
95
|
-
* `* ` bullet markers — matches the parser in `manifest-builder.js`
|
|
96
|
-
* so the inline-acceptance contract round-trips verbatim across the two
|
|
97
|
-
* call sites (manifest projection and context hydration).
|
|
98
|
-
*
|
|
99
|
-
* @param {string} body
|
|
100
|
-
* @param {string} heading
|
|
101
|
-
* @returns {string[]}
|
|
102
|
-
*/
|
|
103
|
-
function extractSectionList(body, heading) {
|
|
104
|
-
if (typeof body !== 'string' || body.length === 0) return [];
|
|
105
|
-
const pattern = new RegExp(
|
|
106
|
-
`^##\\s+${heading.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\s*$`,
|
|
107
|
-
'mi',
|
|
108
|
-
);
|
|
109
|
-
const startMatch = body.match(pattern);
|
|
110
|
-
if (!startMatch || startMatch.index == null) return [];
|
|
111
|
-
const startIdx = startMatch.index + startMatch[0].length;
|
|
112
|
-
const rest = body.slice(startIdx);
|
|
113
|
-
const nextHeading = rest.search(/^##\s+/m);
|
|
114
|
-
const block = nextHeading === -1 ? rest : rest.slice(0, nextHeading);
|
|
115
|
-
const items = [];
|
|
116
|
-
for (const rawLine of block.split(/\r?\n/)) {
|
|
117
|
-
const line = rawLine.trim();
|
|
118
|
-
const m = line.match(/^[-*]\s+(?:\[[ xX]\]\s+)?(.*)$/);
|
|
119
|
-
if (m && m[1].length > 0) items.push(m[1].trim());
|
|
120
|
-
}
|
|
121
|
-
return items;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* Extract the inline `## Acceptance` / `## Acceptance Criteria` and
|
|
126
|
-
* `## Verify` checklists from a Story body. Used by 2-tier hydration to
|
|
127
|
-
* populate the `acceptanceCriteria` and `verificationCommands` envelope
|
|
128
|
-
* sections directly from the dispatched Story ticket — under 2-tier the
|
|
129
|
-
* Story IS the unit of execution and carries acceptance/verify inline
|
|
130
|
-
* (no child tickets to walk).
|
|
131
|
-
*
|
|
132
|
-
* @param {string} body
|
|
133
|
-
* @returns {{ acceptance: string[], verify: string[] }}
|
|
134
|
-
*/
|
|
135
|
-
export function extractStorySections(body) {
|
|
136
|
-
const canonical = extractSectionList(body, 'Acceptance Criteria');
|
|
137
|
-
const acceptance =
|
|
138
|
-
canonical.length > 0 ? canonical : extractSectionList(body, 'Acceptance');
|
|
139
|
-
const verify = extractSectionList(body, 'Verify');
|
|
140
|
-
return { acceptance, verify };
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
* Remove one `## <heading>` section (heading line through the last line
|
|
145
|
-
* before the next `## ` heading, or EOF) from a Story body. Byte-preserving
|
|
146
|
-
* outside the removed span. No-op when the heading is absent. Case- and
|
|
147
|
-
* whitespace-tolerant to match `extractSectionList`.
|
|
148
|
-
*
|
|
149
|
-
* @param {string} body
|
|
150
|
-
* @param {string} heading
|
|
151
|
-
* @returns {string}
|
|
152
|
-
*/
|
|
153
|
-
function stripSection(body, heading) {
|
|
154
|
-
if (typeof body !== 'string' || body.length === 0) return body ?? '';
|
|
155
|
-
const pattern = new RegExp(
|
|
156
|
-
`^##\\s+${heading.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\s*$`,
|
|
157
|
-
'mi',
|
|
158
|
-
);
|
|
159
|
-
const startMatch = body.match(pattern);
|
|
160
|
-
if (!startMatch || startMatch.index == null) return body;
|
|
161
|
-
const start = startMatch.index;
|
|
162
|
-
const afterHeading = start + startMatch[0].length;
|
|
163
|
-
const rest = body.slice(afterHeading);
|
|
164
|
-
const nextHeading = rest.search(/^##\s+/m);
|
|
165
|
-
const end = nextHeading === -1 ? body.length : afterHeading + nextHeading;
|
|
166
|
-
const before = body.slice(0, start).replace(/\n+$/, '\n');
|
|
167
|
-
const after = body.slice(end).replace(/^\n+/, '');
|
|
168
|
-
return (before + after).replace(/\n{3,}/g, '\n\n').trimEnd();
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
/**
|
|
172
|
-
* Strip the inline `## Acceptance Criteria` / `## Acceptance` and `## Verify`
|
|
173
|
-
* sections from a Story body. Used to build the `taskInstructions` section
|
|
174
|
-
* when the dedicated `acceptanceCriteria` / `verificationCommands` envelope
|
|
175
|
-
* sections already carry those lists — so the binding acceptance/verify
|
|
176
|
-
* content appears exactly once in the hydrated envelope rather than being
|
|
177
|
-
* duplicated between the dedicated sections and the full task body.
|
|
178
|
-
*
|
|
179
|
-
* Each heading group is stripped only when its own dedicated section was
|
|
180
|
-
* emitted (`acceptance` gates `## Acceptance Criteria` + `## Acceptance`;
|
|
181
|
-
* `verify` gates `## Verify`). This keeps the strip symmetric with what was
|
|
182
|
-
* reproduced elsewhere in the envelope: a `## Verify` section that carried no
|
|
183
|
-
* bullets (so no dedicated `verificationCommands` section fired) is left
|
|
184
|
-
* intact in `taskInstructions` rather than being silently dropped. Both flags
|
|
185
|
-
* default to `true` so a no-argument call preserves the original
|
|
186
|
-
* strip-everything behaviour.
|
|
187
|
-
*
|
|
188
|
-
* @param {string} body
|
|
189
|
-
* @param {{ acceptance?: boolean, verify?: boolean }} [opts]
|
|
190
|
-
* @returns {string}
|
|
191
|
-
*/
|
|
192
|
-
export function stripStorySectionsForTaskInstructions(
|
|
193
|
-
body,
|
|
194
|
-
{ acceptance = true, verify = true } = {},
|
|
195
|
-
) {
|
|
196
|
-
if (typeof body !== 'string' || body.length === 0) return body ?? '';
|
|
197
|
-
let out = body;
|
|
198
|
-
if (acceptance) {
|
|
199
|
-
out = stripSection(out, 'Acceptance Criteria');
|
|
200
|
-
out = stripSection(out, 'Acceptance');
|
|
201
|
-
}
|
|
202
|
-
if (verify) {
|
|
203
|
-
out = stripSection(out, 'Verify');
|
|
204
|
-
}
|
|
205
|
-
return out;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
/**
|
|
209
|
-
* Detect whether the dispatched unit is a 2-tier Story (Story is the
|
|
210
|
-
* leaf, carries inline acceptance/verify) vs. a 4-tier Task (Task is
|
|
211
|
-
* the leaf, Story is one level up). The decision is made off the
|
|
212
|
-
* `type::*` label the dispatcher already stamps on every ticket; it
|
|
213
|
-
* does not depend on `planning.hierarchy`, so this engine
|
|
214
|
-
* stays correct even when a 4-tier Epic ships in a 2-tier-default repo
|
|
215
|
-
* (or vice versa) during the Epic #3078 dual-shape window.
|
|
216
|
-
*
|
|
217
|
-
* @param {object} task
|
|
218
|
-
* @returns {boolean}
|
|
219
|
-
*/
|
|
220
|
-
function isTwoTierStoryTask(task) {
|
|
221
|
-
const labels = task?.labels ?? [];
|
|
222
|
-
return labels.includes('type::story');
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
/**
|
|
226
|
-
* Load and substitute placeholders in the agent-protocol template. Extracted
|
|
227
|
-
* from {@link hydrateContext} to keep its complexity manageable.
|
|
228
|
-
*
|
|
229
|
-
* @param {object} args
|
|
230
|
-
* @param {{ templatesRoot: string }} args.paths
|
|
231
|
-
* @param {object} args.settings - resolved config (post-reshape `project.*` / `delivery.*` shape)
|
|
232
|
-
* @param {string} args.currentVersion
|
|
233
|
-
* @param {string} args.taskBranch
|
|
234
|
-
* @param {string} args.epicBranch
|
|
235
|
-
* @param {string|number} args.taskId
|
|
236
|
-
* @returns {string} hydrated template body, or '' on read failure
|
|
237
|
-
*/
|
|
238
|
-
function loadProtocolTemplate({
|
|
239
|
-
paths,
|
|
240
|
-
settings,
|
|
241
|
-
currentVersion,
|
|
242
|
-
taskBranch,
|
|
243
|
-
epicBranch,
|
|
244
|
-
taskId,
|
|
245
|
-
}) {
|
|
246
|
-
try {
|
|
247
|
-
const pTemplatePath = path.join(
|
|
248
|
-
PROJECT_ROOT,
|
|
249
|
-
paths.templatesRoot,
|
|
250
|
-
'agent-protocol.md',
|
|
251
|
-
);
|
|
252
|
-
const tpl = readFileCached(pTemplatePath);
|
|
253
|
-
const commands = getCommands(settings);
|
|
254
|
-
const baseBranch = settings?.baseBranch ?? 'main';
|
|
255
|
-
const protectedBranches = Array.isArray(settings?.git?.protectedBranches)
|
|
256
|
-
? settings.git.protectedBranches
|
|
257
|
-
: [baseBranch];
|
|
258
|
-
const protectedList = protectedBranches.map((b) => `\`${b}\``).join(', ');
|
|
259
|
-
return tpl
|
|
260
|
-
.replace(/\{\{PROTOCOL_VERSION\}\}/g, currentVersion)
|
|
261
|
-
.replace(/\{\{BRANCH_NAME\}\}/g, taskBranch)
|
|
262
|
-
.replace(/\{\{EPIC_BRANCH\}\}/g, epicBranch)
|
|
263
|
-
.replace(/\{\{TASK_ID\}\}/g, taskId)
|
|
264
|
-
.replace(/\{\{VALIDATE_CMD\}\}/g, commands.validate)
|
|
265
|
-
.replace(/\{\{TEST_CMD\}\}/g, commands.test)
|
|
266
|
-
.replace(/\{\{PROTECTED_BRANCHES\}\}/g, protectedList);
|
|
267
|
-
} catch (err) {
|
|
268
|
-
Logger.warn(`[Hydrator] Failed to load agent-protocol.md: ${err.message}`);
|
|
269
|
-
return '';
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
// ---------------------------------------------------------------------------
|
|
274
|
-
// Envelope assembly helpers
|
|
275
|
-
// ---------------------------------------------------------------------------
|
|
276
|
-
|
|
277
|
-
/**
|
|
278
|
-
* @param {object} ticket
|
|
279
|
-
* @param {string} retrievedAt
|
|
280
|
-
* @returns {import('./context-envelope.js').TicketSnapshot}
|
|
281
|
-
*/
|
|
282
|
-
function ticketSnapshot(ticket, retrievedAt) {
|
|
283
|
-
const body = ticket.body ?? '';
|
|
284
|
-
const id = ticket.id ?? ticket.number;
|
|
285
|
-
const version =
|
|
286
|
-
ticket.updatedAt ?? ticket.updated_at ?? ticket.updatedAtISO ?? retrievedAt;
|
|
287
|
-
const hash = crypto
|
|
288
|
-
.createHash('sha256')
|
|
289
|
-
.update(body)
|
|
290
|
-
.digest('hex')
|
|
291
|
-
.slice(0, 12);
|
|
292
|
-
return { id, version: String(version), hash, retrievedAt };
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
/**
|
|
296
|
-
* @param {object} task
|
|
297
|
-
* @returns {import('./context-envelope.js').ContextEnvelope['task']}
|
|
298
|
-
*/
|
|
299
|
-
function envelopeTaskFrom(task) {
|
|
300
|
-
return {
|
|
301
|
-
id: task.id,
|
|
302
|
-
title: task.title,
|
|
303
|
-
protocolVersion: task.protocolVersion,
|
|
304
|
-
};
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
/**
|
|
308
|
-
* @param {object} task
|
|
309
|
-
* @param {import('../ITicketingProvider.js').ITicketingProvider} provider
|
|
310
|
-
* @param {number} epicId
|
|
311
|
-
* @param {object} agentSettings - Legacy-shim settings bag or resolved config.
|
|
312
|
-
* @returns {Promise<{ content: string, provenance: import('./context-envelope.js').TicketSnapshot[] }>}
|
|
313
|
-
*/
|
|
314
|
-
async function buildHierarchySections(task, provider, epicId, agentSettings) {
|
|
315
|
-
const hierarchyKeys = parseHierarchy(task.body);
|
|
316
|
-
let hierarchyContext = '## Work Breakdown Hierarchy\n\n';
|
|
317
|
-
const provenance = [];
|
|
318
|
-
const retrievedAt = new Date().toISOString();
|
|
319
|
-
|
|
320
|
-
const depth = agentSettings?.contextDepth ?? 'standard';
|
|
321
|
-
const idsToFetch = [];
|
|
322
|
-
|
|
323
|
-
// Story #4324 — the context-ticket classes are retired: the Epic body IS
|
|
324
|
-
// the planning document (ideation sections + folded Tech Spec sections).
|
|
325
|
-
// `full` and `standard` fetch the identical Epic / Story pair; both
|
|
326
|
-
// branches are kept so the `contextDepth` setting stays a stable API
|
|
327
|
-
// surface.
|
|
328
|
-
if (depth === 'full') {
|
|
329
|
-
idsToFetch.push({ key: 'Epic', id: epicId || hierarchyKeys.epic });
|
|
330
|
-
idsToFetch.push({ key: 'Story', id: hierarchyKeys.story });
|
|
331
|
-
} else if (depth === 'standard') {
|
|
332
|
-
idsToFetch.push({ key: 'Epic', id: epicId || hierarchyKeys.epic });
|
|
333
|
-
idsToFetch.push({ key: 'Story', id: hierarchyKeys.story });
|
|
334
|
-
} else if (depth === 'minimal') {
|
|
335
|
-
idsToFetch.push({ key: 'Story', id: hierarchyKeys.story });
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
const fetchPromises = idsToFetch
|
|
339
|
-
.filter((item) => item.id)
|
|
340
|
-
.map(async (item) => {
|
|
341
|
-
try {
|
|
342
|
-
const t = await provider.getTicket(item.id);
|
|
343
|
-
provenance.push(ticketSnapshot(t, retrievedAt));
|
|
344
|
-
// Hydration section-slicing guardrail (Story #4340): the Epic body
|
|
345
|
-
// is sliced down to only the sections a delivery story agent acts
|
|
346
|
-
// on — Goal / Non-Goals / User Stories / Tech Spec (plus any
|
|
347
|
-
// operator-authored section, fail-open). Ideation / authoring /
|
|
348
|
-
// close machinery (## Context, ## Scope, ## Acceptance Criteria,
|
|
349
|
-
// and the ## Acceptance Table managed region) is dropped so
|
|
350
|
-
// per-story prompt size stays flat versus the pre-fold baseline.
|
|
351
|
-
const body =
|
|
352
|
-
item.key === 'Epic' ? sliceEpicBodyForDelivery(t.body ?? '') : t.body;
|
|
353
|
-
return `### ${item.key}: ${t.title} (#${t.id})\n\n${body}\n`;
|
|
354
|
-
} catch (err) {
|
|
355
|
-
const detail = err?.message ? `: ${err.message}` : '';
|
|
356
|
-
Logger.warn(
|
|
357
|
-
`[Hydrator] hierarchy fetch failed for ${item.key} #${item.id}${detail}`,
|
|
358
|
-
);
|
|
359
|
-
return `### ${item.key}: #${item.id} — ⚠️ unavailable (fetch failed${detail})\n`;
|
|
360
|
-
}
|
|
361
|
-
});
|
|
362
|
-
|
|
363
|
-
const fetchedHierarchy = await Promise.all(fetchPromises);
|
|
364
|
-
hierarchyContext += fetchedHierarchy.filter(Boolean).join('\n---\n\n');
|
|
365
|
-
return { content: hierarchyContext, provenance };
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
/**
|
|
369
|
-
* @param {object} task
|
|
370
|
-
* @param {{ templatesRoot: string }} paths
|
|
371
|
-
* @param {object} agentSettings - Legacy-shim settings bag or resolved config.
|
|
372
|
-
* @param {string} currentVersion
|
|
373
|
-
* @param {string} taskBranch
|
|
374
|
-
* @param {string} epicBranch
|
|
375
|
-
* @returns {{ warnings: string[], sections: import('./context-envelope.js').Section[] }}
|
|
376
|
-
*/
|
|
377
|
-
function buildStaticSections(
|
|
378
|
-
task,
|
|
379
|
-
paths,
|
|
380
|
-
agentSettings,
|
|
381
|
-
currentVersion,
|
|
382
|
-
taskBranch,
|
|
383
|
-
epicBranch,
|
|
384
|
-
) {
|
|
385
|
-
const warnings = [];
|
|
386
|
-
|
|
387
|
-
if (task.protocolVersion && task.protocolVersion !== currentVersion) {
|
|
388
|
-
warnings.push(
|
|
389
|
-
`⚠️ WARNING: Protocol version mismatch. Task was planned with v${task.protocolVersion}, but is executing with v${currentVersion}.`,
|
|
390
|
-
);
|
|
391
|
-
Logger.warn(
|
|
392
|
-
`[Hydrator] Protocol version mismatch on Task #${task.id}: planned with v${task.protocolVersion}, executing with v${currentVersion}`,
|
|
393
|
-
);
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
const sections = [];
|
|
397
|
-
const protocolTpl = loadProtocolTemplate({
|
|
398
|
-
paths,
|
|
399
|
-
settings: agentSettings,
|
|
400
|
-
currentVersion,
|
|
401
|
-
taskBranch,
|
|
402
|
-
epicBranch,
|
|
403
|
-
taskId: task.id,
|
|
404
|
-
});
|
|
405
|
-
if (protocolTpl) {
|
|
406
|
-
sections.push({
|
|
407
|
-
name: 'protocolPolicy',
|
|
408
|
-
priority: DEFAULT_SECTION_PRIORITIES.protocolPolicy,
|
|
409
|
-
elideWhenOverBudget: DEFAULT_ELIDE_POLICIES.protocolPolicy,
|
|
410
|
-
content: protocolTpl,
|
|
411
|
-
source: { kind: 'file', ref: 'templates/agent-protocol.md' },
|
|
412
|
-
});
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
// Track which dedicated section(s) were emitted so taskInstructions drops
|
|
416
|
-
// only the inline sections that were actually reproduced elsewhere in the
|
|
417
|
-
// envelope — keeping each binding acceptance/verify item present exactly
|
|
418
|
-
// once, without dropping a bulletless section that has no dedicated twin.
|
|
419
|
-
let acceptanceEmitted = false;
|
|
420
|
-
let verifyEmitted = false;
|
|
421
|
-
if (isTwoTierStoryTask(task)) {
|
|
422
|
-
const { acceptance, verify } = extractStorySections(task.body ?? '');
|
|
423
|
-
if (acceptance.length > 0) {
|
|
424
|
-
acceptanceEmitted = true;
|
|
425
|
-
sections.push({
|
|
426
|
-
name: 'acceptanceCriteria',
|
|
427
|
-
priority: DEFAULT_SECTION_PRIORITIES.acceptanceCriteria,
|
|
428
|
-
elideWhenOverBudget: DEFAULT_ELIDE_POLICIES.acceptanceCriteria,
|
|
429
|
-
content:
|
|
430
|
-
`## Acceptance Criteria (Story #${task.id})\n\n` +
|
|
431
|
-
acceptance.map((item) => `- ${item}`).join('\n'),
|
|
432
|
-
source: { kind: 'ticket', ref: String(task.id) },
|
|
433
|
-
});
|
|
434
|
-
}
|
|
435
|
-
if (verify.length > 0) {
|
|
436
|
-
verifyEmitted = true;
|
|
437
|
-
sections.push({
|
|
438
|
-
name: 'verificationCommands',
|
|
439
|
-
priority: DEFAULT_SECTION_PRIORITIES.verificationCommands,
|
|
440
|
-
elideWhenOverBudget: DEFAULT_ELIDE_POLICIES.verificationCommands,
|
|
441
|
-
content:
|
|
442
|
-
`## Verify (Story #${task.id})\n\n` +
|
|
443
|
-
verify.map((item) => `- ${item}`).join('\n'),
|
|
444
|
-
source: { kind: 'ticket', ref: String(task.id) },
|
|
445
|
-
});
|
|
446
|
-
}
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
// When a dedicated acceptance/verify section carries that list, strip the
|
|
450
|
-
// matching inline heading(s) from the task body so they are not duplicated
|
|
451
|
-
// in taskInstructions. Each group is gated on its own section: an inline
|
|
452
|
-
// section with no dedicated twin (e.g. a bulletless `## Verify`) is left
|
|
453
|
-
// intact. When neither fired, taskInstructions is byte-identical to the
|
|
454
|
-
// full body.
|
|
455
|
-
const taskBody =
|
|
456
|
-
acceptanceEmitted || verifyEmitted
|
|
457
|
-
? stripStorySectionsForTaskInstructions(task.body ?? '', {
|
|
458
|
-
acceptance: acceptanceEmitted,
|
|
459
|
-
verify: verifyEmitted,
|
|
460
|
-
})
|
|
461
|
-
: task.body;
|
|
462
|
-
sections.push({
|
|
463
|
-
name: 'taskInstructions',
|
|
464
|
-
priority: DEFAULT_SECTION_PRIORITIES.taskInstructions,
|
|
465
|
-
elideWhenOverBudget: DEFAULT_ELIDE_POLICIES.taskInstructions,
|
|
466
|
-
content: `## Task Instructions (Issue #${task.id}: ${task.title})\n\n${taskBody}`,
|
|
467
|
-
source: { kind: 'ticket', ref: String(task.id) },
|
|
468
|
-
});
|
|
469
|
-
|
|
470
|
-
return { warnings, sections };
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
// ---------------------------------------------------------------------------
|
|
474
|
-
// Public SDK export
|
|
475
|
-
// ---------------------------------------------------------------------------
|
|
476
|
-
|
|
477
|
-
/**
|
|
478
|
-
* Hydrate the execution context into a {@link ContextEnvelope}.
|
|
479
|
-
*
|
|
480
|
-
* @param {object} task - The normalized task object from the dispatcher
|
|
481
|
-
* @param {import('../ITicketingProvider.js').ITicketingProvider} provider
|
|
482
|
-
* @param {string} epicBranch - e.g. `epic/71`
|
|
483
|
-
* @param {string} taskBranch - e.g. `story/epic-71/my-story`
|
|
484
|
-
* @param {number} epicId
|
|
485
|
-
* @returns {Promise<import('./context-envelope.js').ContextEnvelope>}
|
|
486
|
-
*/
|
|
487
|
-
export async function hydrateContext(
|
|
488
|
-
task,
|
|
489
|
-
provider,
|
|
490
|
-
epicBranch,
|
|
491
|
-
taskBranch,
|
|
492
|
-
epicId,
|
|
493
|
-
) {
|
|
494
|
-
const { agentSettings } = resolveConfig();
|
|
495
|
-
const maxTokens = getLimits({
|
|
496
|
-
agentSettings: agentSettings ?? {},
|
|
497
|
-
}).maxTokenBudget;
|
|
498
|
-
|
|
499
|
-
const paths = getPaths({ agentSettings });
|
|
500
|
-
const currentVersion = getVersion();
|
|
501
|
-
const { warnings, sections: staticSections } = buildStaticSections(
|
|
502
|
-
task,
|
|
503
|
-
paths,
|
|
504
|
-
agentSettings,
|
|
505
|
-
currentVersion,
|
|
506
|
-
taskBranch,
|
|
507
|
-
epicBranch,
|
|
508
|
-
);
|
|
509
|
-
|
|
510
|
-
const { content: hierarchyContent, provenance } =
|
|
511
|
-
await buildHierarchySections(task, provider, epicId, agentSettings);
|
|
512
|
-
|
|
513
|
-
const sections = [...staticSections];
|
|
514
|
-
const hierarchySection = {
|
|
515
|
-
name: 'hierarchy',
|
|
516
|
-
priority: DEFAULT_SECTION_PRIORITIES.hierarchy,
|
|
517
|
-
elideWhenOverBudget: DEFAULT_ELIDE_POLICIES.hierarchy,
|
|
518
|
-
content: hierarchyContent,
|
|
519
|
-
source: { kind: 'derived', ref: 'work-breakdown-hierarchy' },
|
|
520
|
-
};
|
|
521
|
-
const taskIdx = sections.findIndex((s) => s.name === 'taskInstructions');
|
|
522
|
-
if (taskIdx >= 0) {
|
|
523
|
-
sections.splice(taskIdx, 0, hierarchySection);
|
|
524
|
-
} else {
|
|
525
|
-
sections.push(hierarchySection);
|
|
526
|
-
}
|
|
527
|
-
|
|
528
|
-
const envelope = buildEnvelope({
|
|
529
|
-
task: envelopeTaskFrom(task),
|
|
530
|
-
sections,
|
|
531
|
-
provenance,
|
|
532
|
-
warnings,
|
|
533
|
-
maxTokens,
|
|
534
|
-
});
|
|
535
|
-
|
|
536
|
-
return elideEnvelope(envelope, maxTokens);
|
|
537
|
-
}
|
|
538
|
-
|
|
539
|
-
export { envelopeToPrompt };
|