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
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { LIMITS_DEFAULTS } from '../config/limits.js';
|
|
2
2
|
import {
|
|
3
3
|
AUTHORING_ALTITUDE_GUIDANCE,
|
|
4
|
-
|
|
4
|
+
DEFAULT_MODEL_CAPACITY,
|
|
5
5
|
DELIVERABLE_GRANULARITY_GUIDANCE,
|
|
6
|
+
resolveCapacityCeilings,
|
|
6
7
|
} from '../orchestration/ticket-validator-sizing.js';
|
|
7
8
|
|
|
8
9
|
/**
|
|
@@ -18,27 +19,16 @@ import {
|
|
|
18
19
|
* asks the planner to carry acceptance/verify as top-level ticket arrays.
|
|
19
20
|
*
|
|
20
21
|
* **Single source of the prompt body (Story #4162).** This module is the sole
|
|
21
|
-
* carrier of the full decomposer system-prompt body
|
|
22
|
-
* `
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
* `epic-plan-decompose/phases/context.js`) instead, so the two surfaces cannot
|
|
26
|
-
* drift. A guard test (`tests/ticket-decomposer.test.js`) fails if the SKILL
|
|
27
|
-
* re-grows a full copy of the prompt preamble.
|
|
28
|
-
*
|
|
29
|
-
* **Token-budget sizing input (Story #4162).** `maxTokenBudget` is the real
|
|
30
|
-
* one-pass delivery envelope (the task-prompt hydration cap surfaced into the
|
|
31
|
-
* authoring envelope by `context.js`, Story #3875). It is threaded into the
|
|
32
|
-
* rendered prompt as a sizing input so the planner sizes Stories against the
|
|
33
|
-
* envelope a single agent can actually deliver in one pass, rather than leading
|
|
34
|
-
* with the file-count proxy alone.
|
|
22
|
+
* carrier of the full decomposer system-prompt body, delivered to the host
|
|
23
|
+
* LLM in the `systemPrompts.decompose` field of the `/plan` context envelope
|
|
24
|
+
* (via `lib/orchestration/planning/decomposer-context.js`), so no second
|
|
25
|
+
* verbatim copy can drift.
|
|
35
26
|
*/
|
|
36
27
|
export function renderDecomposerSystemPrompt({
|
|
37
28
|
maxTickets = LIMITS_DEFAULTS.maxTickets,
|
|
38
|
-
maxTokenBudget = LIMITS_DEFAULTS.maxTokenBudget,
|
|
39
29
|
epicId = null,
|
|
40
30
|
} = {}) {
|
|
41
|
-
return render2TierPrompt({ maxTickets,
|
|
31
|
+
return render2TierPrompt({ maxTickets, epicId });
|
|
42
32
|
}
|
|
43
33
|
|
|
44
34
|
/**
|
|
@@ -47,12 +37,16 @@ export function renderDecomposerSystemPrompt({
|
|
|
47
37
|
* on the Story body so the executing agent has everything it needs in one
|
|
48
38
|
* ticket. Thematic grouping lives as prose in the Epic body / Tech Spec.
|
|
49
39
|
*/
|
|
50
|
-
function render2TierPrompt({ maxTickets,
|
|
51
|
-
//
|
|
52
|
-
//
|
|
53
|
-
|
|
40
|
+
function render2TierPrompt({ maxTickets, epicId = null }) {
|
|
41
|
+
// v2 Stage 3: default-single — emit one Story unless the split policy clears.
|
|
42
|
+
// Capacity thresholds are sourced from the single DEFAULT_MODEL_CAPACITY
|
|
43
|
+
// constant (ticket-validator-sizing.js) so the prompt and the validator
|
|
44
|
+
// cannot drift.
|
|
45
|
+
const { softSessionTokens, hardSessionTokens } = resolveCapacityCeilings(
|
|
46
|
+
DEFAULT_MODEL_CAPACITY,
|
|
47
|
+
);
|
|
54
48
|
// Deliverable-granularity definition + single-consumer merge rule + the
|
|
55
|
-
//
|
|
49
|
+
// thin-dependent merge heuristic are sourced from the single
|
|
56
50
|
// DELIVERABLE_GRANULARITY_GUIDANCE constant (ticket-validator-sizing.js) so
|
|
57
51
|
// the prompt and the authoring SKILL cannot drift (Story #3777; the
|
|
58
52
|
// envelope-floor sentence added by Story #4313).
|
|
@@ -78,17 +72,20 @@ function render2TierPrompt({ maxTickets, maxTokenBudget, epicId = null }) {
|
|
|
78
72
|
? `@epic-${epicId}-ac-1`
|
|
79
73
|
: '@epic-<id>-ac-N';
|
|
80
74
|
return `You are an expert Senior Project Manager and Orchestrator.
|
|
81
|
-
Your job is to
|
|
75
|
+
Your job is to turn a plan seed / Tech Spec into a Story ticket array for an AI Agent to execute.
|
|
82
76
|
|
|
83
|
-
### HIERARCHY RULES:
|
|
84
|
-
1. **
|
|
85
|
-
|
|
86
|
-
-
|
|
87
|
-
-
|
|
77
|
+
### HIERARCHY RULES (v2 default-single):
|
|
78
|
+
1. **Emit exactly one Story by default.** Split into N>1 only when pieces have near-zero overlap or sit across an architectural seam. Coupled work stays one Story — put intra-session checkpoints in \`## Slicing\` and fold the Tech Spec into \`## Spec\`.
|
|
79
|
+
2. **Stories**: Specific user-facing or architectural capabilities (e.g., "Implement JWT Token Exchange").
|
|
80
|
+
- There is NO Epic parent ticket, NO Feature tier, and NO Task layer.
|
|
81
|
+
- **Story-Level Execution**: Each Story is executed end-to-end on a single branch by a single agent. Acceptance criteria and verification commands live as top-level \`acceptance[]\` / \`verify[]\` arrays on the Story ticket (see STORY BODY SCHEMA below).
|
|
82
|
+
- Thematic grouping is prose in the Story's folded \`## Spec\` / \`## Slicing\`, never sibling tickets for coupled work.
|
|
88
83
|
|
|
89
84
|
### LABEL CONVENTIONS:
|
|
90
|
-
-
|
|
91
|
-
-
|
|
85
|
+
- \`type::story\` is applied automatically by persist — you do not need to emit it, and no other type label is allowed (the retired Feature and Task tiers have no labels under this hierarchy).
|
|
86
|
+
- \`labels[]\` is **optional**. Emit it only to request an *additional* label; persist sanitizes the list before applying it.
|
|
87
|
+
- Do **not** emit \`agent::*\` labels — lifecycle state is runtime-owned, and persist applies \`agent::ready\` itself once every checkpoint is on the ticket.
|
|
88
|
+
- Do **not** emit \`persona::*\` labels — the behavioral persona concept (and its label axis) was removed in v2.
|
|
92
89
|
|
|
93
90
|
### OUTPUT FORMAT:
|
|
94
91
|
You MUST respond ONLY with a valid JSON array of objects. No prose, no markdown blocks.
|
|
@@ -102,7 +99,7 @@ You MUST respond ONLY with a valid JSON array of objects. No prose, no markdown
|
|
|
102
99
|
"body": <string — see STORY BODY SCHEMA below>,
|
|
103
100
|
"acceptance": ["<testable, observable criterion>", ...],
|
|
104
101
|
"verify": ["<exact command or test path> (<tier>)", ...],
|
|
105
|
-
"labels": ["type::story
|
|
102
|
+
"labels": ["<extra-label>"] (optional — type::story is applied automatically; omit this field unless you need an additional label),
|
|
106
103
|
"depends_on": ["slug-of-blocking-dependency"] (optional array of Story slugs that block execution)
|
|
107
104
|
}
|
|
108
105
|
]
|
|
@@ -112,12 +109,20 @@ You MUST respond ONLY with a valid JSON array of objects. No prose, no markdown
|
|
|
112
109
|
### STORY BODY SCHEMA (REQUIRED FOR EVERY STORY):
|
|
113
110
|
\`body\` MUST be a **string** — the serialized markdown produced by \`serialize()\` from \`lib/story-body/story-body.js\`. Do NOT emit \`body\` as a JSON object: an object body throws \`StoryBodyParseError\` in the reconciler (Story #3302) and is discarded by the GitHub provider, producing an empty issue body. Stories are consumed by non-interactive sub-agents that must self-verify from the Story ticket alone — so the ticket must carry everything an agent needs to execute and self-verify.
|
|
114
111
|
|
|
115
|
-
The \`acceptance[]\` and \`verify[]\` arrays live at the **top level** of the Story ticket object
|
|
112
|
+
The \`acceptance[]\` and \`verify[]\` arrays live at the **top level** of the Story ticket object — that is the machine contract the validator reads. Author each list **once, at top level**, and **omit** the \`## Acceptance\` / \`## Verify\` sections from the authored \`body\` string: persist syncs the top-level arrays into those sections so the GitHub issue stays a complete executable document. The validator resolves both fields from the top level, so an omitted section is the expected shape, not a violation.
|
|
113
|
+
|
|
114
|
+
If you do write those sections into the \`body\` string anyway, they must mirror the top-level arrays **item for item** — persist fails closed on a disagreement rather than guessing which list is authoritative. Do **not** invent a second criteria list inside \`## Spec\`, and do not author a separate Acceptance Spec / PRD artifact.
|
|
116
115
|
|
|
117
116
|
The serialized \`body\` string renders these markdown sections (in order):
|
|
118
117
|
|
|
119
118
|
## Goal
|
|
120
|
-
<one sentence — why this Story exists
|
|
119
|
+
<one sentence — why this Story exists>
|
|
120
|
+
|
|
121
|
+
## Slicing
|
|
122
|
+
<optional ordered intra-session checkpoints — not a second Spec or AC table>
|
|
123
|
+
|
|
124
|
+
## Spec
|
|
125
|
+
<optional lean technical approach — do NOT restate Goal / Acceptance / Verify>
|
|
121
126
|
|
|
122
127
|
## Changes
|
|
123
128
|
- {"path": "<file path>", "assumption": "creates" | "refactors-existing" | "deletes"}
|
|
@@ -141,7 +146,9 @@ The serialized \`body\` string renders these markdown sections (in order):
|
|
|
141
146
|
|
|
142
147
|
#### STORY BODY RULES:
|
|
143
148
|
|
|
144
|
-
- **goal** (in body string): One sentence stating WHY this
|
|
149
|
+
- **goal** (in body string): One sentence stating WHY this Story exists.
|
|
150
|
+
- **spec** (optional, in body string as \`## Spec\`): Lean technical approach only. If the Spec is large enough to feel like its own document, the Story is probably too big — split it. Persist keeps Specs inline and rejects over-budget Specs (never writes them under \`docs/\`).
|
|
151
|
+
- **slicing** (optional): Ordered intra-session checkpoints for one Story. Not a fan-out table and not a duplicate of Acceptance.
|
|
145
152
|
- **changes** (in body string): Each entry is an object \`{ path, assumption }\` where \`assumption\` is one of \`creates | refactors-existing | deletes\`. Acceptable path shapes include explicit files (\`src/components/Foo.tsx\`), glob patterns (\`tests/e2e/*.spec.ts\`, \`**/*.astro\`), and module identifiers that resolve to files. Use \`refactors-existing\` for in-place edits to a file already on \`main\`; \`creates\` for net-new files; \`deletes\` for removals.
|
|
146
153
|
- **acceptance** (top-level array on the ticket object): Items MUST be observable from outside the agent. Acceptable shapes: a specific command exits 0, a file exists at a given path, a snapshot test matches, a \`data-testid\` resolves under a given selector, a row count in a fixture matches. UNACCEPTABLE: "verify by reading the diff", "looks good", "matches the spec" — push these down into a \`verify\` command instead.
|
|
147
154
|
- **verify** (top-level array on the ticket object): Each entry MUST name a testing tier in parentheses, drawn from \`unit\` / \`contract\` / \`e2e\` / \`validate\`. Example: \`npm run test -- src/x.test.ts (unit)\`, \`npm run validate (validate)\`. Stories with zero verify entries SHOULD fail validation; if a story is genuinely unverifiable in isolation (e.g., a copy edit auditor will eyeball), the literal entry \`manual:<reason>\` is allowed so the absence is intentional, not lazy. Manual entries without a reason are rejected.
|
|
@@ -157,37 +164,35 @@ ${newFileContract}
|
|
|
157
164
|
|
|
158
165
|
${advisoryCaveat}
|
|
159
166
|
|
|
160
|
-
#### STORY SIZING — COHESION FIRST (
|
|
167
|
+
#### STORY SIZING — COHESION FIRST (session capacity is only a backstop):
|
|
161
168
|
|
|
162
169
|
**Decompose at deliverable granularity, not module/task level.** ${granularityDefinition}
|
|
163
170
|
|
|
164
|
-
The primary question is **cohesion, not count**: *is this one coherent change with one reason to exist?* File count cannot tell a trivial
|
|
165
|
-
|
|
166
|
-
**Size against the real one-pass delivery envelope.** Each Story is delivered and self-verified by a single agent in one pass, whose context is capped by the delivery token budget \`maxTokenBudget = ${maxTokenBudget}\` tokens (the task-prompt hydration cap). Use that envelope — not the file count alone — as the leading sizing input: a Story is correctly sized when one agent can hold its full change, acceptance, and verification in a single pass within \`maxTokenBudget\`. The numeric file thresholds below are a coarse backstop on top of this envelope, not the primary signal.
|
|
171
|
+
The primary question is **cohesion, not count**: *is this one coherent change with one reason to exist?* File count cannot tell a trivial rename from a hard parser+caller+config change — so lead with the change's reason, not its size. Frontier models one-shot capability-sized work in a single pass — do not fragment a coherent capability into dependent slices just to stay "small."
|
|
167
172
|
|
|
168
173
|
${envelopeFloor}
|
|
169
174
|
|
|
170
175
|
- **One Story = one coherent change with one reason to exist.** If you cannot state that reason in a sentence, the Story is probably two Stories — or two Stories that should be one. State that sentence explicitly in the Story's \`reason_to_exist\` meta field (see STORY BODY RULES) so the consolidate critic can check it.
|
|
171
176
|
- ${singleConsumerRule}
|
|
172
177
|
- **Split independent, parallelizable work** into sibling Stories — but only when the pieces genuinely have separate reasons to exist.
|
|
173
|
-
- **Declare \`wide\` with a one-line reason when a change is legitimately broad** (a cohesive cutover
|
|
178
|
+
- **Declare \`wide\` with a one-line reason when a change is legitimately broad** (a cohesive cutover whose authored ticket mass is high for one reason). Declaring \`wide\` lifts the hard session-mass ceiling — see below.
|
|
174
179
|
|
|
175
|
-
**
|
|
180
|
+
**Capacity backstop (validator-enforced).** Absolute authored-token ceilings from the single \`DEFAULT_MODEL_CAPACITY\` constant in \`ticket-validator-sizing.js\` — not operator-tunable. They catch Spec novels, not capability-sized Stories:
|
|
176
181
|
|
|
177
|
-
-
|
|
178
|
-
-
|
|
179
|
-
-
|
|
182
|
+
- Soft advisory (**${softSessionTokens} tokens**): authored session mass above this emits a nudge to check cohesion or declare \`wide\`.
|
|
183
|
+
- Hard ceiling (**${hardSessionTokens} tokens**): authored session mass above this is **rejected** unless the Story declares \`wide\` with a reason.
|
|
184
|
+
- Session mass = **authored tokens only** (goal / reason / Spec / acceptance / verify / slicing / change-path text). File count and AC count do **not** inflate mass — a long binding contract or a broad file footprint is never by itself a reason to fragment one coherent capability into dependent slices.
|
|
180
185
|
|
|
181
186
|
#### DELIVERY-SCHEDULE SIMULATION — the story count must earn itself:
|
|
182
187
|
|
|
183
188
|
Before emitting, simulate the delivery schedule your plan implies, and judge the plan by its schedule — not by how tidy the taxonomy looks:
|
|
184
189
|
|
|
185
190
|
1. **Build the wave schedule.** A Story runs only after every \`depends_on\` completes, and two Stories that name the same file in \`changes[]\` cannot run in the same wave (the scheduler serializes file-overlapping Stories even when no \`depends_on\` edge links them).
|
|
186
|
-
2. **Compute the parallelism yield**: story count ÷ critical-path length in waves. A yield near 1.0 means the plan is a serial chain — N Stories that deliver no faster than one Story while paying N delivery sessions (
|
|
191
|
+
2. **Compute the parallelism yield**: story count ÷ critical-path length in waves. A yield near 1.0 means the plan is a serial chain — N Stories that deliver no faster than one Story while paying N delivery sessions (branch, PR, review, CI).
|
|
187
192
|
3. **Every Story must earn its slot** by at least one of:
|
|
188
193
|
- **(a) parallelism** — it actually runs concurrently with a sibling in the schedule you just built ("logically independent" does not count; *schedule*-independent does);
|
|
189
194
|
- **(b) risk isolation** — it isolates a consumer-facing behavior change or high-risk cutover into its own reviewable, revertable unit;
|
|
190
|
-
- **(c)
|
|
195
|
+
- **(c) cohesion break** — merged into its neighbor it would no longer be one coherent change with one reason to exist.
|
|
191
196
|
4. **A dependent link with none of those justifications merges into its consumer.** This generalizes the single-consumer merge rule from pairs to chains.
|
|
192
197
|
5. **Hot-file rule.** When one file appears in the \`changes[]\` of more than a third of your Stories, the slicing axis cuts across a shared seam — merge the Stories that co-edit it, or re-slice along the seam so each Story owns its files.
|
|
193
198
|
|
|
@@ -201,7 +206,7 @@ A Story whose footprint is legitimately broad declares \`wide\` carrying a one-l
|
|
|
201
206
|
"wide": { "reason": "hard contract cutover: migrate every <X> call site in one PR" }
|
|
202
207
|
\`\`\`
|
|
203
208
|
|
|
204
|
-
Declaring \`wide\` with a non-empty reason **lifts the
|
|
209
|
+
Declaring \`wide\` with a non-empty reason **lifts the hard session-mass rejection** — no Story is rejected for width when it states why it is broad. Omit \`wide\` for ordinary Stories; a wide footprint with no \`wide\` declaration emits only an advisory nudge (check cohesion or declare \`wide\`), never a rejection on its own.
|
|
205
210
|
|
|
206
211
|
**Glob entries** in \`changes[]\` (bullets containing \`*\`) mark the Story footprint as \`unknown-width\`: the numeric ceiling cannot bound a glob, so it is skipped. A Story carrying glob changes with no \`wide\` declaration emits an advisory nudge.
|
|
207
212
|
|
|
@@ -1,23 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* spec-author-prompts.js —
|
|
3
|
-
* Spec authoring system prompts (Epic #4474, M3 PR2).
|
|
2
|
+
* spec-author-prompts.js — Story-scoped Spec / Acceptance authoring prompts.
|
|
4
3
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* into `systemPrompts.spec` / `systemPrompts.acceptance` so the envelope
|
|
11
|
-
* is authoritative from day one, and M8 (#4479) then deletes the
|
|
12
|
-
* skill-side copies. This mirrors the Story #4162 pattern established by
|
|
13
|
-
* `decomposer-prompts.js` for the decompose prompt: one rendered carrier,
|
|
14
|
-
* no second verbatim copy to drift.
|
|
4
|
+
* v2 keeps a single executable document per Story. These prompts used to
|
|
5
|
+
* author a separate Epic Tech Spec + Acceptance Spec that were folded into
|
|
6
|
+
* the Epic body and then restated on Stories — a duplication source. They
|
|
7
|
+
* now author only Story `## Spec` approach prose and remind authors that
|
|
8
|
+
* acceptance lives once on the Story (`acceptance[]` / `## Acceptance`).
|
|
15
9
|
*/
|
|
16
10
|
|
|
17
11
|
/**
|
|
18
|
-
* The Tech Spec authoring system prompt (verbatim from the
|
|
19
|
-
* `epic-plan-spec-author` SKILL's authoritative block).
|
|
20
|
-
*
|
|
21
12
|
* @returns {string}
|
|
22
13
|
*/
|
|
23
14
|
export function renderTechSpecSystemPrompt() {
|
|
@@ -25,9 +16,6 @@ export function renderTechSpecSystemPrompt() {
|
|
|
25
16
|
}
|
|
26
17
|
|
|
27
18
|
/**
|
|
28
|
-
* The Acceptance Spec authoring system prompt (verbatim from the
|
|
29
|
-
* `epic-plan-spec-author` SKILL's authoritative block).
|
|
30
|
-
*
|
|
31
19
|
* @returns {string}
|
|
32
20
|
*/
|
|
33
21
|
export function renderAcceptanceSpecSystemPrompt() {
|
|
@@ -35,40 +23,54 @@ export function renderAcceptanceSpecSystemPrompt() {
|
|
|
35
23
|
}
|
|
36
24
|
|
|
37
25
|
const TECH_SPEC_SYSTEM_PROMPT = `You are an expert Engineering Architect.
|
|
38
|
-
Your job is to
|
|
26
|
+
Your job is to author the Story's \`## Spec\` approach section — the technical
|
|
27
|
+
how for one cohesive, executable Story. There is no separate Epic Tech Spec
|
|
28
|
+
document and no spill-to-docs path.
|
|
39
29
|
|
|
40
|
-
The
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
30
|
+
The Spec should outline only what an implementing agent needs beyond Goal /
|
|
31
|
+
Changes / Acceptance:
|
|
32
|
+
1. Architecture & Design (approach, seams, reuse)
|
|
33
|
+
2. Data Models (if any)
|
|
34
|
+
3. API Changes (if any)
|
|
35
|
+
4. Core Components
|
|
36
|
+
5. Security & Privacy Considerations
|
|
47
37
|
|
|
48
38
|
CRITICAL REQUIREMENTS:
|
|
49
|
-
- Respond ONLY with valid Markdown
|
|
50
|
-
- Do not use top-level <h1> (# ) tags.
|
|
51
|
-
- Do NOT restate the
|
|
39
|
+
- Respond ONLY with valid Markdown suitable to paste into a Story \`## Spec\`.
|
|
40
|
+
- Do not use top-level <h1> (# ) tags. Prefer \`##\` / \`###\` under Spec.
|
|
41
|
+
- Do NOT restate the Story's Goal, Acceptance, Verify, Changes, or Non-Goals —
|
|
42
|
+
those sections already live on the same Story body. Restatement is
|
|
43
|
+
duplication and a drift risk. If a brief orientation helps, keep a
|
|
44
|
+
\`## Technical Overview\` to 2–3 sentences naming the technical approach only.
|
|
45
|
+
- Do NOT author a Delivery Slicing / fan-out table. If the work needs multiple
|
|
46
|
+
independent Stories, say so in one short note and stop — oversized Specs
|
|
47
|
+
mean the Story should be split, not documented elsewhere.
|
|
52
48
|
- Format architectural decisions clearly with bullet points.
|
|
53
|
-
-
|
|
49
|
+
- Keep the Spec lean enough to stay inline on the Story (persist rejects
|
|
50
|
+
over-budget Specs; they are never written under docs/).`;
|
|
54
51
|
|
|
55
52
|
const ACCEPTANCE_SPEC_SYSTEM_PROMPT = `You are an expert Acceptance Engineer.
|
|
56
|
-
Your job is to
|
|
53
|
+
Your job is to help author the Story's binding acceptance contract — not a
|
|
54
|
+
separate Acceptance Spec document.
|
|
57
55
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
56
|
+
v2 rule: acceptance lives **once**, on the Story:
|
|
57
|
+
- Machine contract: top-level \`acceptance[]\` (and \`verify[]\`) on the ticket JSON
|
|
58
|
+
- Human document: the same items rendered under \`## Acceptance\` / \`## Verify\`
|
|
59
|
+
on the Story body (persist syncs top-level into the body)
|
|
62
60
|
|
|
63
|
-
|
|
61
|
+
Do **not** author an Epic Acceptance Table, PRD restatement, or a second
|
|
62
|
+
criteria list inside \`## Spec\`.
|
|
64
63
|
|
|
65
64
|
CRITICAL REQUIREMENTS:
|
|
66
|
-
- Respond ONLY with
|
|
67
|
-
|
|
68
|
-
- Every
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
-
|
|
72
|
-
|
|
73
|
-
-
|
|
74
|
-
|
|
65
|
+
- Respond ONLY with guidance or a draft \`acceptance[]\` / \`verify[]\` list for
|
|
66
|
+
one Story — never a parallel "Acceptance Spec" markdown artifact.
|
|
67
|
+
- Every acceptance item MUST be observable from outside the agent (command
|
|
68
|
+
exits 0, file exists, selector resolves, fixture count matches). Reject
|
|
69
|
+
vague "matches the spec" / "looks good" items.
|
|
70
|
+
- Every verify entry MUST name a tier in parentheses: unit | contract | e2e |
|
|
71
|
+
validate (or \`manual:<reason>\` when genuinely unverifiable in isolation).
|
|
72
|
+
- Do NOT re-elaborate Goal or Spec prose inside acceptance items — bind the
|
|
73
|
+
outcome, not the approach.
|
|
74
|
+
- Acceptance Outcomes MUST NOT prescribe a commit subject that begins with a
|
|
75
|
+
non-Conventional-Commits prefix (allowed leading types: feat|fix|chore|
|
|
76
|
+
refactor|perf|docs|style|test|build|ci|revert).`;
|
|
@@ -17,12 +17,25 @@
|
|
|
17
17
|
* the NODE_ENV band-aid was removed in Story #3342. Tests that need to
|
|
18
18
|
* exercise the webhook POST inject `opts.fetchImpl` instead, so the
|
|
19
19
|
* request never reaches the real network even if a URL resolves.)
|
|
20
|
+
* - Every `GIT_*` variable is dropped. When the suite runs inside a git
|
|
21
|
+
* hook (husky pre-push via the coverage-capture path), the parent git
|
|
22
|
+
* invocation exports `GIT_DIR` — from a linked worktree, the absolute
|
|
23
|
+
* `<main>/.git/worktrees/<name>` path. A test fixture's `git init`
|
|
24
|
+
* under that env re-initializes the shared gitdir and writes
|
|
25
|
+
* `core.bare=true` into the MAIN checkout's `.git/config`, breaking
|
|
26
|
+
* every worktree at once (#4580). Production git call sites are
|
|
27
|
+
* covered by `cleanGitEnv` in `git-utils.js`; this is the same scrub
|
|
28
|
+
* for test child processes, which may spawn git directly. Tests that
|
|
29
|
+
* need a `GIT_*` variable set it explicitly on their own spawn.
|
|
20
30
|
*
|
|
21
31
|
* @param {NodeJS.ProcessEnv} baseEnv
|
|
22
32
|
* @returns {NodeJS.ProcessEnv}
|
|
23
33
|
*/
|
|
24
34
|
export function buildWebhookSafeTestEnv(baseEnv = process.env) {
|
|
25
|
-
const env =
|
|
35
|
+
const env = Object.fromEntries(
|
|
36
|
+
Object.entries(baseEnv).filter(([k]) => !k.startsWith('GIT_')),
|
|
37
|
+
);
|
|
38
|
+
env.NODE_ENV = baseEnv.NODE_ENV ?? 'test';
|
|
26
39
|
if (env.MANDREL_ALLOW_TEST_WEBHOOKS !== '1') {
|
|
27
40
|
delete env.NOTIFICATION_WEBHOOK_URL;
|
|
28
41
|
}
|
|
@@ -12,13 +12,10 @@ import picomatch from 'picomatch';
|
|
|
12
12
|
*/
|
|
13
13
|
export const INTEGRATION_INCLUDE = [
|
|
14
14
|
'tests/**/*.integration.test.js',
|
|
15
|
-
'tests/epic-execute/epic-execute-record-wave.test.js',
|
|
16
15
|
'tests/hook-chain-reflog-invariant.test.js',
|
|
17
|
-
'tests/push-epic-retry.test.js',
|
|
18
16
|
'tests/contract/check-baselines-regression.test.js',
|
|
19
17
|
'tests/contract/check-baselines-kernel-mismatch.test.js',
|
|
20
18
|
'tests/integration-prime-after-sweep.test.js',
|
|
21
|
-
'tests/concurrency-wiring.test.js',
|
|
22
19
|
'tests/scripts/git-cleanup.test.js',
|
|
23
20
|
'tests/lib/checks/runner-integration.test.js',
|
|
24
21
|
'tests/single-story-close-sync.test.js',
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* ticket-body-sections.js — marker-delimited managed sections of a
|
|
3
|
+
* planning ticket body.
|
|
3
4
|
*
|
|
4
5
|
* Story #4324 retired the `context::tech-spec` / `context::acceptance-spec`
|
|
5
|
-
* ticket classes: the
|
|
6
|
-
* Tech Spec (opening with `## Delivery Slicing`, per #4316) and the
|
|
7
|
-
* Acceptance Spec's AC-ID table (`## Acceptance Table
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* *only its own region* without rewriting the rest of the body.
|
|
6
|
+
* ticket classes: the planning ticket body is the single planning document.
|
|
7
|
+
* The Tech Spec (opening with `## Delivery Slicing`, per #4316) and the
|
|
8
|
+
* Acceptance Spec's AC-ID table (`## Acceptance Table`) land as **managed
|
|
9
|
+
* sections**, delimited by invisible HTML comment markers so each writer
|
|
10
|
+
* can update *only its own region* without rewriting the rest of the body.
|
|
11
11
|
*
|
|
12
12
|
* Section-scoped writes are the load-bearing contract (extending the
|
|
13
13
|
* single-writer discipline #4303 established for the body trailer):
|
|
14
14
|
*
|
|
15
|
-
* - The
|
|
16
|
-
*
|
|
15
|
+
* - The `/plan` persist path upserts the `techSpec` and `acceptanceTable`
|
|
16
|
+
* regions.
|
|
17
17
|
* - The close-time acceptance reconciler
|
|
18
18
|
* (`acceptance-spec-reconciler.js`) reads and rewrites the
|
|
19
19
|
* `acceptanceTable` region only (verification dispositions).
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
*
|
|
33
33
|
* @type {Readonly<Record<'techSpec'|'acceptanceTable', { start: string, end: string, label: string }>>}
|
|
34
34
|
*/
|
|
35
|
-
export const
|
|
35
|
+
export const TICKET_BODY_SECTIONS = Object.freeze({
|
|
36
36
|
techSpec: Object.freeze({
|
|
37
37
|
start: '<!-- mandrel:tech-spec:start -->',
|
|
38
38
|
end: '<!-- mandrel:tech-spec:end -->',
|
|
@@ -47,7 +47,7 @@ export const EPIC_BODY_SECTIONS = Object.freeze({
|
|
|
47
47
|
|
|
48
48
|
/**
|
|
49
49
|
* Canonical heading the acceptance-table region opens with. Distinct from
|
|
50
|
-
* the
|
|
50
|
+
* the ticket's ideation `## Acceptance Criteria` bullets (which remain the
|
|
51
51
|
* SSOT for *what* the table verifies — the table anchors to those bullets).
|
|
52
52
|
*/
|
|
53
53
|
export const ACCEPTANCE_TABLE_HEADING = '## Acceptance Table';
|
|
@@ -56,7 +56,7 @@ export const ACCEPTANCE_TABLE_HEADING = '## Acceptance Table';
|
|
|
56
56
|
* Regex matching the Tech Spec's required opening heading (same variants
|
|
57
57
|
* `spec-section-validator.js` accepts). Exported so it is the single
|
|
58
58
|
* source of truth for this pattern — `spec-section-validator.js`,
|
|
59
|
-
* `
|
|
59
|
+
* `consolidation-precondition.js` all import
|
|
60
60
|
* it rather than each carrying their own copy.
|
|
61
61
|
*/
|
|
62
62
|
export const DELIVERY_SLICING_RE = /^##\s+(?:Delivery\s+)?Slicing\s*$/im;
|
|
@@ -66,10 +66,10 @@ export const DELIVERY_SLICING_RE = /^##\s+(?:Delivery\s+)?Slicing\s*$/im;
|
|
|
66
66
|
* @returns {{ start: string, end: string, label: string }}
|
|
67
67
|
*/
|
|
68
68
|
function descriptor(kind) {
|
|
69
|
-
const d =
|
|
69
|
+
const d = TICKET_BODY_SECTIONS[kind];
|
|
70
70
|
if (!d) {
|
|
71
71
|
throw new TypeError(
|
|
72
|
-
`
|
|
72
|
+
`ticket-body-sections: unknown section kind "${kind}" (expected ${Object.keys(TICKET_BODY_SECTIONS).join(' | ')})`,
|
|
73
73
|
);
|
|
74
74
|
}
|
|
75
75
|
return d;
|
|
@@ -103,24 +103,10 @@ function locate(body, kind) {
|
|
|
103
103
|
* @param {'techSpec'|'acceptanceTable'} kind
|
|
104
104
|
* @returns {boolean}
|
|
105
105
|
*/
|
|
106
|
-
export function
|
|
106
|
+
export function hasTicketSection(body, kind) {
|
|
107
107
|
return locate(body, kind) !== null;
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
-
/**
|
|
111
|
-
* Extract a managed region's content (between the markers, trimmed).
|
|
112
|
-
* Returns `null` when the region is absent.
|
|
113
|
-
*
|
|
114
|
-
* @param {string} body
|
|
115
|
-
* @param {'techSpec'|'acceptanceTable'} kind
|
|
116
|
-
* @returns {string|null}
|
|
117
|
-
*/
|
|
118
|
-
export function extractEpicSection(body, kind) {
|
|
119
|
-
const loc = locate(body, kind);
|
|
120
|
-
if (!loc) return null;
|
|
121
|
-
return body.slice(loc.contentStart, loc.contentEnd).trim();
|
|
122
|
-
}
|
|
123
|
-
|
|
124
110
|
/**
|
|
125
111
|
* Insert or replace a managed region, preserving every byte outside it.
|
|
126
112
|
*
|
|
@@ -136,7 +122,7 @@ export function extractEpicSection(body, kind) {
|
|
|
136
122
|
* @param {string} content Section content (headings included).
|
|
137
123
|
* @returns {string}
|
|
138
124
|
*/
|
|
139
|
-
export function
|
|
125
|
+
export function upsertTicketSection(body, kind, content) {
|
|
140
126
|
const { start, end } = descriptor(kind);
|
|
141
127
|
const safeBody = typeof body === 'string' ? body : '';
|
|
142
128
|
const trimmedContent = typeof content === 'string' ? content.trim() : '';
|
|
@@ -179,7 +165,7 @@ export function upsertEpicSection(body, kind, content) {
|
|
|
179
165
|
* @param {'techSpec'|'acceptanceTable'} kind
|
|
180
166
|
* @returns {string}
|
|
181
167
|
*/
|
|
182
|
-
export function
|
|
168
|
+
export function stripTicketSection(body, kind) {
|
|
183
169
|
const { end } = descriptor(kind);
|
|
184
170
|
const loc = locate(body, kind);
|
|
185
171
|
if (!loc) return typeof body === 'string' ? body : '';
|
|
@@ -189,7 +175,7 @@ export function stripEpicSection(body, kind) {
|
|
|
189
175
|
}
|
|
190
176
|
|
|
191
177
|
/**
|
|
192
|
-
* Re-plan / decompose detection: true when the
|
|
178
|
+
* Re-plan / decompose detection: true when the ticket body carries folded
|
|
193
179
|
* Tech Spec content — the managed region, or (defence in depth for a
|
|
194
180
|
* hand-authored body) a bare `## Delivery Slicing` heading.
|
|
195
181
|
*
|
|
@@ -197,7 +183,7 @@ export function stripEpicSection(body, kind) {
|
|
|
197
183
|
* @returns {boolean}
|
|
198
184
|
*/
|
|
199
185
|
export function hasTechSpecContent(body) {
|
|
200
|
-
if (
|
|
186
|
+
if (hasTicketSection(body, 'techSpec')) return true;
|
|
201
187
|
return typeof body === 'string' && DELIVERY_SLICING_RE.test(body);
|
|
202
188
|
}
|
|
203
189
|
|
|
@@ -217,9 +203,9 @@ const DELIVERY_DROP_HEADINGS = new Set([
|
|
|
217
203
|
]);
|
|
218
204
|
|
|
219
205
|
/**
|
|
220
|
-
* Slice
|
|
206
|
+
* Slice a planning ticket body down to the sections a delivery story agent acts on.
|
|
221
207
|
*
|
|
222
|
-
* KEEP: the
|
|
208
|
+
* KEEP: the ticket title / preamble before the first `##`, `## Goal`,
|
|
223
209
|
* `## Non-Goals`, `## User Stories`, the `techSpec` managed region, and —
|
|
224
210
|
* fail-open — any unknown / operator-authored `##` section not in the drop
|
|
225
211
|
* list. DROP: `## Context`, `## Scope`, `## Acceptance Criteria`, and the
|
|
@@ -236,12 +222,12 @@ const DELIVERY_DROP_HEADINGS = new Set([
|
|
|
236
222
|
* @param {string} body
|
|
237
223
|
* @returns {string}
|
|
238
224
|
*/
|
|
239
|
-
export function
|
|
225
|
+
export function sliceTicketBodyForDelivery(body) {
|
|
240
226
|
if (typeof body !== 'string' || body.length === 0) return '';
|
|
241
227
|
|
|
242
228
|
// 1. Drop the acceptance-table managed region outright (authoring/close
|
|
243
229
|
// machinery, never delivery context).
|
|
244
|
-
let working =
|
|
230
|
+
let working = stripTicketSection(body, 'acceptanceTable');
|
|
245
231
|
|
|
246
232
|
// 2. Protect the techSpec managed region from heading-boundary slicing by
|
|
247
233
|
// lifting it out behind an opaque placeholder, then restoring it after
|
|
@@ -261,7 +247,7 @@ export function sliceEpicBodyForDelivery(body) {
|
|
|
261
247
|
|
|
262
248
|
// 3. Slice plain `##` sections by heading boundaries, dropping only the
|
|
263
249
|
// known ideation/authoring headings. The preamble before the first
|
|
264
|
-
// `##` (
|
|
250
|
+
// `##` (ticket title / lede) is always kept.
|
|
265
251
|
const kept = [];
|
|
266
252
|
let dropping = false;
|
|
267
253
|
for (const line of working.split('\n')) {
|
|
@@ -291,7 +277,7 @@ export function sliceEpicBodyForDelivery(body) {
|
|
|
291
277
|
|
|
292
278
|
/**
|
|
293
279
|
* Strip the retired machine-managed `## Planning Artifacts` checklist from
|
|
294
|
-
*
|
|
280
|
+
* a planning ticket body (the section that linked the now-retired context tickets).
|
|
295
281
|
* The slice ends at the next `## ` heading, a managed-region marker, or
|
|
296
282
|
* EOF. Historical bodies without the section pass through untouched.
|
|
297
283
|
*
|