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
|
@@ -43,6 +43,18 @@ import { execFileSync, spawnSync } from 'node:child_process';
|
|
|
43
43
|
let _execFileSync = execFileSync;
|
|
44
44
|
let _spawnSync = spawnSync;
|
|
45
45
|
|
|
46
|
+
/**
|
|
47
|
+
* Memoized cleaned env shared by every `gitSync` / `gitSpawn` /
|
|
48
|
+
* `createGitInterface` invocation in this process. Built lazily on first
|
|
49
|
+
* use so cold imports pay nothing. Call sites pass the object through to
|
|
50
|
+
* `child_process` only — none mutate `GIT_*` (or any other key) between
|
|
51
|
+
* git calls, so reuse is safe. Tests that mutate `process.env` and need
|
|
52
|
+
* a fresh snapshot must call {@link __resetCleanGitEnv}.
|
|
53
|
+
*
|
|
54
|
+
* @type {NodeJS.ProcessEnv | null}
|
|
55
|
+
*/
|
|
56
|
+
let _cleanGitEnv = null;
|
|
57
|
+
|
|
46
58
|
/**
|
|
47
59
|
* Build a child-process env that drops every `GIT_*` variable inherited from
|
|
48
60
|
* the parent. When this module's helpers run inside a git hook (e.g. husky
|
|
@@ -53,13 +65,28 @@ let _spawnSync = spawnSync;
|
|
|
53
65
|
* that spin up real git fixtures break reproducibly under that shape.
|
|
54
66
|
*
|
|
55
67
|
* Stripping every `GIT_*` is broader than strictly necessary but cheap and
|
|
56
|
-
* impossible to drift out of sync with future git releases.
|
|
57
|
-
*
|
|
68
|
+
* impossible to drift out of sync with future git releases. The result is
|
|
69
|
+
* memoized per process (see `_cleanGitEnv`); author/committer identity is
|
|
70
|
+
* restored via per-call `env:` overrides where required.
|
|
71
|
+
*
|
|
72
|
+
* @returns {NodeJS.ProcessEnv}
|
|
58
73
|
*/
|
|
59
74
|
function cleanGitEnv() {
|
|
60
|
-
return
|
|
61
|
-
|
|
75
|
+
if (_cleanGitEnv) return _cleanGitEnv;
|
|
76
|
+
_cleanGitEnv = Object.freeze(
|
|
77
|
+
Object.fromEntries(
|
|
78
|
+
Object.entries(process.env).filter(([k]) => !k.startsWith('GIT_')),
|
|
79
|
+
),
|
|
62
80
|
);
|
|
81
|
+
return _cleanGitEnv;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Drop the memoized cleaned env so the next git call rebuilds from
|
|
86
|
+
* `process.env`. Testing-only seam — not part of the stable API.
|
|
87
|
+
*/
|
|
88
|
+
export function __resetCleanGitEnv() {
|
|
89
|
+
_cleanGitEnv = null;
|
|
63
90
|
}
|
|
64
91
|
|
|
65
92
|
/**
|
|
@@ -288,20 +315,6 @@ export function gitPullWithRetry(cwd, ...args) {
|
|
|
288
315
|
return gitWithContentionRetry(cwd, ['pull', '--rebase'], args);
|
|
289
316
|
}
|
|
290
317
|
|
|
291
|
-
/**
|
|
292
|
-
* Resolves the canonical branch name for an Epic.
|
|
293
|
-
* v5 Standard: epic/[EPIC_ID]
|
|
294
|
-
* @param {string|number} epicId
|
|
295
|
-
* @returns {string}
|
|
296
|
-
*/
|
|
297
|
-
export function getEpicBranch(epicId) {
|
|
298
|
-
const id = typeof epicId === 'number' ? epicId : Number.parseInt(epicId, 10);
|
|
299
|
-
if (!Number.isFinite(id) || id <= 0) {
|
|
300
|
-
throw new Error(`getEpicBranch: invalid epicId: ${epicId}`);
|
|
301
|
-
}
|
|
302
|
-
return `epic/${id}`;
|
|
303
|
-
}
|
|
304
|
-
|
|
305
318
|
/**
|
|
306
319
|
* Sanitize a string into a URL/branch-safe slug.
|
|
307
320
|
* Lowercases, replaces non-alphanumeric characters with hyphens,
|
|
@@ -321,11 +334,10 @@ export function slugify(text) {
|
|
|
321
334
|
/**
|
|
322
335
|
* Resolves the canonical branch name for a Story.
|
|
323
336
|
* v5 Standard: story-[STORY_ID]
|
|
324
|
-
* @param {string|number} _epicId - Unused; retained for back-compat call sites.
|
|
325
337
|
* @param {string|number} storyId
|
|
326
338
|
* @returns {string}
|
|
327
339
|
*/
|
|
328
|
-
export function getStoryBranch(
|
|
340
|
+
export function getStoryBranch(storyId) {
|
|
329
341
|
const id =
|
|
330
342
|
typeof storyId === 'number' ? storyId : Number.parseInt(storyId, 10);
|
|
331
343
|
if (!Number.isFinite(id) || id <= 0) {
|
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
* json-utils.js — shared JSON-shape helpers.
|
|
3
3
|
*
|
|
4
4
|
* Hoisted out of five callers (`lib/baselines/writer.js`,
|
|
5
|
-
* `lib/config/defaults.js`, `lib/
|
|
6
|
-
* `lib/observability/perf-aggregator.js`, `lib/signals/schema.js`) which
|
|
5
|
+
* `lib/config/defaults.js`, `lib/signals/schema.js`) which
|
|
7
6
|
* shipped functionally-equivalent copies of these predicates. See Story
|
|
8
7
|
* #2464.
|
|
9
8
|
*
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Central source of truth for all GitHub label names used by the orchestrator.
|
|
3
3
|
*
|
|
4
|
-
* Every other module (label-taxonomy,
|
|
5
|
-
* etc.) should import from here rather than using string literals. Renames
|
|
4
|
+
* Every other module (label-taxonomy, single-story-close.js,
|
|
5
|
+
* stories-wave-tick.js, etc.) should import from here rather than using string literals. Renames
|
|
6
6
|
* land in one place.
|
|
7
7
|
*/
|
|
8
8
|
|
|
@@ -10,12 +10,12 @@ export const AGENT_LABELS = {
|
|
|
10
10
|
REVIEW_SPEC: 'agent::review-spec',
|
|
11
11
|
READY: 'agent::ready',
|
|
12
12
|
EXECUTING: 'agent::executing',
|
|
13
|
-
// Story #2144 — intermediate state owned by `story-close.js`. A Story
|
|
13
|
+
// Story #2144 — intermediate state owned by `single-story-close.js`. A Story
|
|
14
14
|
// flips to `agent::closing` after preflight validation succeeds and
|
|
15
|
-
//
|
|
16
|
-
// `agent::done` only after the
|
|
15
|
+
// the Story PR is opened against `main`. It flips to
|
|
16
|
+
// `agent::done` only after the close pipeline confirms the PR merge
|
|
17
17
|
// landed; if the close is killed mid-flight, the Story remains at
|
|
18
|
-
// `agent::closing` so
|
|
18
|
+
// `agent::closing` so `/deliver` can pick up at the
|
|
19
19
|
// post-merge phase rather than re-running preflight. The label is the
|
|
20
20
|
// distinguishing signal between "hung close" and "finished work".
|
|
21
21
|
CLOSING: 'agent::closing',
|
|
@@ -75,7 +75,6 @@ export function isValidTransition(fromState, toState) {
|
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
export const TYPE_LABELS = {
|
|
78
|
-
EPIC: 'type::epic',
|
|
79
78
|
STORY: 'type::story',
|
|
80
79
|
};
|
|
81
80
|
|
|
@@ -83,14 +82,6 @@ export const STATUS_LABELS = {
|
|
|
83
82
|
BLOCKED: 'status::blocked',
|
|
84
83
|
};
|
|
85
84
|
|
|
86
|
-
/**
|
|
87
|
-
* Persona labels are derived at bootstrap time from `.agents/personas/*.md`
|
|
88
|
-
* (see `label-taxonomy.js`), not hard-coded here — the persona file is the
|
|
89
|
-
* source of truth, and ticket hydration resolves the label value to the
|
|
90
|
-
* matching filename.
|
|
91
|
-
*/
|
|
92
|
-
export const PERSONA_LABEL_PREFIX = 'persona::';
|
|
93
|
-
|
|
94
85
|
/**
|
|
95
86
|
* Acceptance-axis labels for opt-out signalling on Epics that
|
|
96
87
|
* intentionally have no acceptance-table coverage. (Story #4324 retired
|
|
@@ -122,13 +113,10 @@ export const META_LABELS = {
|
|
|
122
113
|
|
|
123
114
|
/**
|
|
124
115
|
* Planning-axis labels (Epic #2880 F7). Currently scoped to the
|
|
125
|
-
* `planning::healthcheck-waived` operator-applied waiver
|
|
126
|
-
*
|
|
127
|
-
*
|
|
128
|
-
*
|
|
129
|
-
* when the healthcheck returned `ok: false` unless this label is
|
|
130
|
-
* present — see `.agents/docs/SDLC.md` § "`agent::ready` exit conditions"
|
|
131
|
-
* for the full handoff contract.
|
|
116
|
+
* `planning::healthcheck-waived` operator-applied waiver — a historical
|
|
117
|
+
* escape hatch for the retired post-plan readiness healthcheck. The
|
|
118
|
+
* label remains in the taxonomy for tickets that still carry it; the
|
|
119
|
+
* healthcheck CLI itself was deleted in the v2 epic-scripts sweep.
|
|
132
120
|
*
|
|
133
121
|
* Future planning-axis waivers (one per failing exit condition) extend
|
|
134
122
|
* this enum so consumers can reference them by symbol.
|
|
@@ -147,27 +135,11 @@ export const PLANNING_LABELS = {
|
|
|
147
135
|
*/
|
|
148
136
|
export const PLANNING_HEALTHCHECK_WAIVED = 'planning::healthcheck-waived';
|
|
149
137
|
|
|
150
|
-
/**
|
|
151
|
-
* Delivery-routing labels (Epic #4474 PR4 — design §2 mode matrix).
|
|
152
|
-
* `delivery::single` marks an Epic whose plan was persisted in the
|
|
153
|
-
* spec-only single-delivery mode: no Story tree exists and the Delivery
|
|
154
|
-
* Slicing table of the Epic body's Tech Spec is the audit trail.
|
|
155
|
-
* `plan-persist.js` applies it when the risk verdict declares
|
|
156
|
-
* `deliveryShape: "single"`; a fan-out re-persist over the same Epic
|
|
157
|
-
* removes it. The marker is **inert until #4475** lands the deliver-side
|
|
158
|
-
* reader — nothing in the deliver path consumes it yet.
|
|
159
|
-
*/
|
|
160
|
-
export const DELIVERY_LABELS = {
|
|
161
|
-
SINGLE: 'delivery::single',
|
|
162
|
-
};
|
|
163
|
-
|
|
164
138
|
/** Palette for the taxonomy; consumed by label-taxonomy.js. */
|
|
165
139
|
export const LABEL_COLORS = {
|
|
166
140
|
TYPE: '#7057FF',
|
|
167
141
|
AGENT: '#0E8A16',
|
|
168
142
|
STATUS_BLOCKED: '#D93F0B',
|
|
169
|
-
PERSONA: '#C5DEF5',
|
|
170
143
|
ACCEPTANCE: '#FBCA04',
|
|
171
144
|
PLANNING: '#FEF2C0',
|
|
172
|
-
DELIVERY: '#BFD4F2',
|
|
173
145
|
};
|
|
@@ -4,59 +4,29 @@
|
|
|
4
4
|
*
|
|
5
5
|
* All label names are sourced from `label-constants.js` so renames only need
|
|
6
6
|
* to happen in one place. Colors come from `LABEL_COLORS` in the same module.
|
|
7
|
+
*
|
|
8
|
+
* v2 deleted the behavioral persona concept (`.agents/personas/` +
|
|
9
|
+
* `persona::*` labels). Role framing for spawns lives in `.agents/agents/`
|
|
10
|
+
* via `delivery.routing.roleScopedAgents`; QA auth identities live in
|
|
11
|
+
* `qa.personas` — neither is a GitHub label axis.
|
|
7
12
|
*/
|
|
8
13
|
|
|
9
|
-
import fs from 'node:fs';
|
|
10
|
-
import path from 'node:path';
|
|
11
|
-
import { fileURLToPath } from 'node:url';
|
|
12
14
|
import {
|
|
13
15
|
ACCEPTANCE_LABELS,
|
|
14
16
|
AGENT_LABELS,
|
|
15
|
-
DELIVERY_LABELS,
|
|
16
17
|
LABEL_COLORS,
|
|
17
|
-
PERSONA_LABEL_PREFIX,
|
|
18
18
|
PLANNING_LABELS,
|
|
19
19
|
STATUS_LABELS,
|
|
20
20
|
TYPE_LABELS,
|
|
21
21
|
} from './label-constants.js';
|
|
22
22
|
|
|
23
|
-
const PERSONAS_DIR = path.resolve(
|
|
24
|
-
path.dirname(fileURLToPath(import.meta.url)),
|
|
25
|
-
'..',
|
|
26
|
-
'..',
|
|
27
|
-
'personas',
|
|
28
|
-
);
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Discover persona labels from `.agents/personas/*.md`. The filename
|
|
32
|
-
* (without extension) is the label suffix — this is the same value the
|
|
33
|
-
* context hydrator uses to resolve `persona::<name>` to its markdown file.
|
|
34
|
-
*/
|
|
35
|
-
function buildPersonaLabels() {
|
|
36
|
-
return fs
|
|
37
|
-
.readdirSync(PERSONAS_DIR)
|
|
38
|
-
.filter((f) => f.endsWith('.md'))
|
|
39
|
-
.map((f) => f.slice(0, -3))
|
|
40
|
-
.sort()
|
|
41
|
-
.map((name) => ({
|
|
42
|
-
name: `${PERSONA_LABEL_PREFIX}${name}`,
|
|
43
|
-
color: LABEL_COLORS.PERSONA,
|
|
44
|
-
description: `${name} persona`,
|
|
45
|
-
}));
|
|
46
|
-
}
|
|
47
|
-
|
|
48
23
|
/** @type {Array<{ name: string, color: string, description: string }>} */
|
|
49
24
|
export const LABEL_TAXONOMY = [
|
|
50
25
|
// Type
|
|
51
|
-
{
|
|
52
|
-
name: TYPE_LABELS.EPIC,
|
|
53
|
-
color: LABEL_COLORS.TYPE,
|
|
54
|
-
description: 'Epic-level work item',
|
|
55
|
-
},
|
|
56
26
|
{
|
|
57
27
|
name: TYPE_LABELS.STORY,
|
|
58
28
|
color: LABEL_COLORS.TYPE,
|
|
59
|
-
description: '
|
|
29
|
+
description: 'Story work item',
|
|
60
30
|
},
|
|
61
31
|
|
|
62
32
|
// Agent State
|
|
@@ -80,7 +50,7 @@ export const LABEL_TAXONOMY = [
|
|
|
80
50
|
{
|
|
81
51
|
name: AGENT_LABELS.CLOSING,
|
|
82
52
|
color: LABEL_COLORS.AGENT,
|
|
83
|
-
description: 'Close preflight passed; awaiting merge into the
|
|
53
|
+
description: 'Close preflight passed; awaiting merge into the base branch',
|
|
84
54
|
},
|
|
85
55
|
{
|
|
86
56
|
name: AGENT_LABELS.DONE,
|
|
@@ -95,9 +65,6 @@ export const LABEL_TAXONOMY = [
|
|
|
95
65
|
description: 'Blocked by a dependency',
|
|
96
66
|
},
|
|
97
67
|
|
|
98
|
-
// Persona — dynamically derived from .agents/personas/*.md
|
|
99
|
-
...buildPersonaLabels(),
|
|
100
|
-
|
|
101
68
|
// Acceptance axis — explicit opt-out signal for Epics that
|
|
102
69
|
// intentionally have no acceptance-table coverage (waives the Epic
|
|
103
70
|
// body's ## Acceptance Table section — Story #4324).
|
|
@@ -108,25 +75,13 @@ export const LABEL_TAXONOMY = [
|
|
|
108
75
|
},
|
|
109
76
|
|
|
110
77
|
// Planning axis — operator-applied waivers for the planning → delivery
|
|
111
|
-
// handoff gates.
|
|
112
|
-
//
|
|
113
|
-
// (`runPlanHealthcheck`) returned `ok: false` for a reason the
|
|
114
|
-
// operator has triaged and accepted.
|
|
78
|
+
// handoff gates. `healthcheck-waived` remains for tickets that still
|
|
79
|
+
// carry the historical label; the healthcheck CLI was retired.
|
|
115
80
|
{
|
|
116
81
|
name: PLANNING_LABELS.HEALTHCHECK_WAIVED,
|
|
117
82
|
color: LABEL_COLORS.PLANNING,
|
|
118
83
|
description:
|
|
119
|
-
'
|
|
120
|
-
},
|
|
121
|
-
|
|
122
|
-
// Delivery routing — applied by `plan-persist.js` when the risk verdict
|
|
123
|
-
// declares `deliveryShape: "single"` (Epic #4474 PR4). Inert until #4475
|
|
124
|
-
// lands the deliver-side reader.
|
|
125
|
-
{
|
|
126
|
-
name: DELIVERY_LABELS.SINGLE,
|
|
127
|
-
color: LABEL_COLORS.DELIVERY,
|
|
128
|
-
description:
|
|
129
|
-
'Single-delivery plan — no Story tree; the Delivery Slicing table is the audit trail (#4474/#4475)',
|
|
84
|
+
'Historical operator override for the retired post-plan healthcheck',
|
|
130
85
|
},
|
|
131
86
|
];
|
|
132
87
|
|
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
* Active-Story env-var propagation (Epic #1030 Story #1043 / Task #1061).
|
|
3
3
|
*
|
|
4
4
|
* The PreToolUse / PostToolUse trace hook in
|
|
5
|
-
* `lib/observability/tool-trace-hook.js` resolves the active
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* - `setActiveStoryEnv({
|
|
10
|
-
* `story-init.js` after the worktree is materialised. It sets the
|
|
11
|
-
*
|
|
12
|
-
* orchestrator spawns inherit
|
|
5
|
+
* `lib/observability/tool-trace-hook.js` resolves the active Story from
|
|
6
|
+
* `process.env.CC_STORY_ID`. This module is the single writer/clearer of
|
|
7
|
+
* that var:
|
|
8
|
+
*
|
|
9
|
+
* - `setActiveStoryEnv({ storyId, workCwd })` is called from
|
|
10
|
+
* `single-story-init.js` after the worktree is materialised. It sets the
|
|
11
|
+
* var on the current `process.env` (so any child commands the
|
|
12
|
+
* orchestrator spawns inherit it) and exports it to a sibling
|
|
13
13
|
* `.env.local` inside the worktree. The harness re-spawns the
|
|
14
14
|
* agent with that file's contents loaded, so the trace hook fires
|
|
15
15
|
* with the right ids on the *next* tool call after init returns.
|
|
@@ -37,96 +37,76 @@ const ENV_LOCAL_BASENAME = '.env.local';
|
|
|
37
37
|
/**
|
|
38
38
|
* Names of the env vars we own. Keeping the list central makes the
|
|
39
39
|
* round-trip (set on init, clear on close) trivially auditable —
|
|
40
|
-
* grep `
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
* hook
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
40
|
+
* grep `CC_STORY_ID` / `CC_EPIC_ID` to find every read site.
|
|
41
|
+
*
|
|
42
|
+
* `CC_STORY_ID` is the one var this module writes. `CC_EPIC_ID` is retained
|
|
43
|
+
* on the CLEAR path only: v2 has no Epics and nothing here sets it, but
|
|
44
|
+
* `tool-trace-hook.js`'s `resolveActiveStory` still reads it, so wiping it at
|
|
45
|
+
* close keeps the trace path's "no stale context past close" contract honest
|
|
46
|
+
* against a value that leaked in from outside (a pre-upgrade `.env.local` the
|
|
47
|
+
* harness already loaded, or an operator's shell).
|
|
48
|
+
*
|
|
49
|
+
* `CC_SLICE_ID` / `CC_OPERATOR` were removed with the heartbeat substrate:
|
|
50
|
+
* their only writer was the never-called `setActiveSliceEnv` and their only
|
|
51
|
+
* reader the deleted `hook-heartbeat.js`.
|
|
48
52
|
*/
|
|
49
|
-
export const ACTIVE_STORY_ENV_KEYS = [
|
|
50
|
-
'CC_EPIC_ID',
|
|
51
|
-
'CC_STORY_ID',
|
|
52
|
-
'CC_SLICE_ID',
|
|
53
|
-
'CC_OPERATOR',
|
|
54
|
-
];
|
|
53
|
+
export const ACTIVE_STORY_ENV_KEYS = ['CC_EPIC_ID', 'CC_STORY_ID'];
|
|
55
54
|
|
|
56
55
|
/**
|
|
57
56
|
* Render the `.env.local` body. One `KEY=value` line per var, LF
|
|
58
57
|
* line endings (the harness's dotenv parser tolerates CRLF too but LF
|
|
59
58
|
* keeps the file deterministic across Windows / macOS / Linux).
|
|
60
59
|
*
|
|
61
|
-
*
|
|
62
|
-
* Epic
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
* empty string and change the contract.
|
|
60
|
+
* Only `CC_STORY_ID` is emitted: v2 Stories are standalone, so there is no
|
|
61
|
+
* parent Epic to key. The trace hook's no-op contract reads "var absent from
|
|
62
|
+
* env" as the signal, so no `CC_EPIC_ID=` line is written at all — an empty
|
|
63
|
+
* one would set the var to the empty string and change the contract.
|
|
66
64
|
*
|
|
67
65
|
* Exported for testing.
|
|
68
66
|
*
|
|
69
|
-
* @param {{
|
|
67
|
+
* @param {{ storyId: number }} input
|
|
70
68
|
* @returns {string}
|
|
71
69
|
*/
|
|
72
|
-
export function renderActiveStoryEnvFile({
|
|
73
|
-
|
|
70
|
+
export function renderActiveStoryEnvFile({ storyId }) {
|
|
71
|
+
return [
|
|
74
72
|
'# Auto-managed by .agents/scripts/lib/observability/active-story-env.js',
|
|
75
73
|
'# Re-generated on every story-init; deleted on story-close.',
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
return lines.join('\n');
|
|
74
|
+
`CC_STORY_ID=${storyId}`,
|
|
75
|
+
'',
|
|
76
|
+
].join('\n');
|
|
80
77
|
}
|
|
81
78
|
|
|
82
79
|
/**
|
|
83
|
-
* Set `
|
|
84
|
-
*
|
|
80
|
+
* Set `CC_STORY_ID` on the current process and (when `workCwd` is provided)
|
|
81
|
+
* export it to `<workCwd>/.env.local`.
|
|
85
82
|
*
|
|
86
|
-
* Idempotent: re-running with the same
|
|
87
|
-
* different
|
|
83
|
+
* Idempotent: re-running with the same id is a no-op on disk; with a
|
|
84
|
+
* different id the `.env.local` is overwritten.
|
|
88
85
|
*
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
* no-op contract is keyed on the var's absence).
|
|
94
|
-
* - The rendered `.env.local` omits the `CC_EPIC_ID=` line.
|
|
95
|
-
* - `CC_STORY_ID` behaviour is unchanged.
|
|
96
|
-
* All other invalid `epicId` values (`0`, negative, NaN, non-integer)
|
|
97
|
-
* still throw — `null` is the only standalone signal.
|
|
86
|
+
* v2 Stories are standalone — there is no parent Epic — so `CC_EPIC_ID` is
|
|
87
|
+
* never set, and any pre-existing value is removed: the trace hook's
|
|
88
|
+
* `resolveActiveStory` no-op contract is keyed on the var's absence, and a
|
|
89
|
+
* stale epic id would key this Story's traces to a foreign Epic directory.
|
|
98
90
|
*
|
|
99
|
-
* @param {{
|
|
91
|
+
* @param {{ storyId: number, workCwd?: string,
|
|
100
92
|
* env?: NodeJS.ProcessEnv, fs?: typeof nodeFs,
|
|
101
93
|
* logger?: { warn?: (m: string) => void } }} args
|
|
102
94
|
* @returns {{ envSet: boolean, fileWritten: boolean, filePath: string|null }}
|
|
103
95
|
*/
|
|
104
96
|
export function setActiveStoryEnv({
|
|
105
|
-
epicId,
|
|
106
97
|
storyId,
|
|
107
98
|
workCwd,
|
|
108
99
|
env = process.env,
|
|
109
100
|
fs = nodeFs,
|
|
110
101
|
logger,
|
|
111
102
|
} = {}) {
|
|
112
|
-
if (epicId !== null && (!Number.isInteger(epicId) || epicId <= 0)) {
|
|
113
|
-
throw new Error(
|
|
114
|
-
`[active-story-env] epicId must be a positive integer or null; got ${epicId}`,
|
|
115
|
-
);
|
|
116
|
-
}
|
|
117
103
|
if (!Number.isInteger(storyId) || storyId <= 0) {
|
|
118
104
|
throw new Error(
|
|
119
105
|
`[active-story-env] storyId must be a positive integer; got ${storyId}`,
|
|
120
106
|
);
|
|
121
107
|
}
|
|
122
108
|
|
|
123
|
-
if (
|
|
124
|
-
// Standalone Story — ensure CC_EPIC_ID is absent so the trace
|
|
125
|
-
// hook's no-op contract sees "no epic" rather than "epic=''".
|
|
126
|
-
if ('CC_EPIC_ID' in env) delete env.CC_EPIC_ID;
|
|
127
|
-
} else {
|
|
128
|
-
env.CC_EPIC_ID = String(epicId);
|
|
129
|
-
}
|
|
109
|
+
if ('CC_EPIC_ID' in env) delete env.CC_EPIC_ID;
|
|
130
110
|
env.CC_STORY_ID = String(storyId);
|
|
131
111
|
|
|
132
112
|
let fileWritten = false;
|
|
@@ -134,13 +114,9 @@ export function setActiveStoryEnv({
|
|
|
134
114
|
if (typeof workCwd === 'string' && workCwd.length > 0) {
|
|
135
115
|
filePath = nodePath.join(workCwd, ENV_LOCAL_BASENAME);
|
|
136
116
|
try {
|
|
137
|
-
fs.writeFileSync(
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
{
|
|
141
|
-
encoding: 'utf8',
|
|
142
|
-
},
|
|
143
|
-
);
|
|
117
|
+
fs.writeFileSync(filePath, renderActiveStoryEnvFile({ storyId }), {
|
|
118
|
+
encoding: 'utf8',
|
|
119
|
+
});
|
|
144
120
|
fileWritten = true;
|
|
145
121
|
} catch (err) {
|
|
146
122
|
logger?.warn?.(
|
|
@@ -192,100 +168,3 @@ export function clearActiveStoryEnv({
|
|
|
192
168
|
}
|
|
193
169
|
return { envCleared: true, fileRemoved, filePath };
|
|
194
170
|
}
|
|
195
|
-
|
|
196
|
-
/**
|
|
197
|
-
* Render the single-delivery `.env.local` body. The single-delivery executor
|
|
198
|
-
* (`deliver-epic-single.md`) walks the Delivery Slicing table inside ONE long
|
|
199
|
-
* session; there is no Story fan-out and thus no `CC_STORY_ID`. Instead the
|
|
200
|
-
* "current slice" is exported as `CC_SLICE_ID` so the PostToolUse hook emits
|
|
201
|
-
* `slice.heartbeat` — the watchdog's forward-progress signal for the single
|
|
202
|
-
* session — as a free byproduct of tool activity.
|
|
203
|
-
*
|
|
204
|
-
* `CC_STORY_ID` MUST be absent (its presence would make the hook emit
|
|
205
|
-
* `story.heartbeat` and the trace path key off a non-existent Story). The
|
|
206
|
-
* optional `operator` handle is emitted as `CC_OPERATOR` only when supplied.
|
|
207
|
-
*
|
|
208
|
-
* Exported for testing.
|
|
209
|
-
*
|
|
210
|
-
* @param {{ epicId: number, sliceId: string, operator?: string }} input
|
|
211
|
-
* @returns {string}
|
|
212
|
-
*/
|
|
213
|
-
export function renderActiveSliceEnvFile({ epicId, sliceId, operator }) {
|
|
214
|
-
const lines = [
|
|
215
|
-
'# Auto-managed by .agents/scripts/lib/observability/active-story-env.js',
|
|
216
|
-
'# Re-generated on every slice-start; deleted on epic-close.',
|
|
217
|
-
`CC_EPIC_ID=${epicId}`,
|
|
218
|
-
`CC_SLICE_ID=${sliceId}`,
|
|
219
|
-
];
|
|
220
|
-
if (typeof operator === 'string' && operator.length > 0) {
|
|
221
|
-
lines.push(`CC_OPERATOR=${operator}`);
|
|
222
|
-
}
|
|
223
|
-
lines.push('');
|
|
224
|
-
return lines.join('\n');
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
/**
|
|
228
|
-
* Set `CC_EPIC_ID` / `CC_SLICE_ID` (+ optional `CC_OPERATOR`) on the current
|
|
229
|
-
* process and, when `workCwd` is provided, export them to
|
|
230
|
-
* `<workCwd>/.env.local` for the harness to reload on the next tool call. The
|
|
231
|
-
* single-delivery analogue of {@link setActiveStoryEnv}; called at each
|
|
232
|
-
* `slice.start` boundary so the hook's throttled `slice.heartbeat` is keyed to
|
|
233
|
-
* the slice currently being implemented.
|
|
234
|
-
*
|
|
235
|
-
* `CC_STORY_ID` is explicitly removed so a prior Story context (if any ever
|
|
236
|
-
* leaked in) cannot make the hook emit the wrong heartbeat shape.
|
|
237
|
-
*
|
|
238
|
-
* @param {{ epicId: number, sliceId: string, operator?: string|null,
|
|
239
|
-
* workCwd?: string, env?: NodeJS.ProcessEnv, fs?: typeof nodeFs,
|
|
240
|
-
* logger?: { warn?: (m: string) => void } }} args
|
|
241
|
-
* @returns {{ envSet: boolean, fileWritten: boolean, filePath: string|null }}
|
|
242
|
-
*/
|
|
243
|
-
export function setActiveSliceEnv({
|
|
244
|
-
epicId,
|
|
245
|
-
sliceId,
|
|
246
|
-
operator,
|
|
247
|
-
workCwd,
|
|
248
|
-
env = process.env,
|
|
249
|
-
fs = nodeFs,
|
|
250
|
-
logger,
|
|
251
|
-
} = {}) {
|
|
252
|
-
if (!Number.isInteger(epicId) || epicId <= 0) {
|
|
253
|
-
throw new Error(
|
|
254
|
-
`[active-story-env] epicId must be a positive integer; got ${epicId}`,
|
|
255
|
-
);
|
|
256
|
-
}
|
|
257
|
-
if (typeof sliceId !== 'string' || sliceId.length === 0) {
|
|
258
|
-
throw new Error(
|
|
259
|
-
`[active-story-env] sliceId must be a non-empty string; got ${sliceId}`,
|
|
260
|
-
);
|
|
261
|
-
}
|
|
262
|
-
const normOperator =
|
|
263
|
-
typeof operator === 'string' && operator.length > 0 ? operator : undefined;
|
|
264
|
-
|
|
265
|
-
if ('CC_STORY_ID' in env) delete env.CC_STORY_ID;
|
|
266
|
-
env.CC_EPIC_ID = String(epicId);
|
|
267
|
-
env.CC_SLICE_ID = sliceId;
|
|
268
|
-
if (normOperator) env.CC_OPERATOR = normOperator;
|
|
269
|
-
else if ('CC_OPERATOR' in env) delete env.CC_OPERATOR;
|
|
270
|
-
|
|
271
|
-
let fileWritten = false;
|
|
272
|
-
let filePath = null;
|
|
273
|
-
if (typeof workCwd === 'string' && workCwd.length > 0) {
|
|
274
|
-
filePath = nodePath.join(workCwd, ENV_LOCAL_BASENAME);
|
|
275
|
-
try {
|
|
276
|
-
fs.writeFileSync(
|
|
277
|
-
filePath,
|
|
278
|
-
renderActiveSliceEnvFile({ epicId, sliceId, operator: normOperator }),
|
|
279
|
-
{ encoding: 'utf8' },
|
|
280
|
-
);
|
|
281
|
-
fileWritten = true;
|
|
282
|
-
} catch (err) {
|
|
283
|
-
logger?.warn?.(
|
|
284
|
-
`[active-story-env] Failed to write ${filePath}: ${
|
|
285
|
-
err instanceof Error ? err.message : String(err)
|
|
286
|
-
}`,
|
|
287
|
-
);
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
return { envSet: true, fileWritten, filePath };
|
|
291
|
-
}
|