@ornexus/neocortex 4.60.73 → 4.60.74

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.
Files changed (241) hide show
  1. package/dist/release-source.json +1 -1
  2. package/dist/sbom.cdx.json +1216 -1210
  3. package/install.ps1 +1 -1
  4. package/install.sh +1 -1
  5. package/package.json +2 -2
  6. package/packages/client/dist/adapters/adapter-registry.js +1 -108
  7. package/packages/client/dist/adapters/antigravity-adapter.js +2 -77
  8. package/packages/client/dist/adapters/claude-code-adapter.js +3 -79
  9. package/packages/client/dist/adapters/codex-adapter.js +2 -80
  10. package/packages/client/dist/adapters/cursor-adapter.js +4 -115
  11. package/packages/client/dist/adapters/gemini-adapter.js +2 -71
  12. package/packages/client/dist/adapters/grok-adapter.js +2 -42
  13. package/packages/client/dist/adapters/index.js +1 -22
  14. package/packages/client/dist/adapters/platform-detector.js +1 -212
  15. package/packages/client/dist/adapters/target-adapter.js +0 -12
  16. package/packages/client/dist/adapters/vscode-adapter.js +2 -72
  17. package/packages/client/dist/agent/refresh-stubs.js +2 -417
  18. package/packages/client/dist/agent/update-agent-yaml.js +1 -102
  19. package/packages/client/dist/agent/update-description.js +1 -251
  20. package/packages/client/dist/cache/crypto-utils.js +1 -78
  21. package/packages/client/dist/cache/encrypted-cache.js +1 -108
  22. package/packages/client/dist/cache/in-memory-asset-cache.js +1 -73
  23. package/packages/client/dist/cache/index.js +1 -13
  24. package/packages/client/dist/cache/protected-pi-boundary.js +1 -44
  25. package/packages/client/dist/checkpoint/checkpoint-client-reader.js +2 -127
  26. package/packages/client/dist/checkpoint/index.js +1 -11
  27. package/packages/client/dist/checkpoint/shared-checkpoint-types.js +1 -32
  28. package/packages/client/dist/cli.js +5 -358
  29. package/packages/client/dist/commands/activate.js +8 -394
  30. package/packages/client/dist/commands/architecture-answers.js +7 -274
  31. package/packages/client/dist/commands/architecture-memory-terminal.js +4 -253
  32. package/packages/client/dist/commands/architecture-non-ui-continuation.js +1 -100
  33. package/packages/client/dist/commands/architecture-root-binding.js +1 -51
  34. package/packages/client/dist/commands/cache-status.js +2 -112
  35. package/packages/client/dist/commands/config.js +1 -88
  36. package/packages/client/dist/commands/doctor.js +2 -635
  37. package/packages/client/dist/commands/invoke.js +143 -7200
  38. package/packages/client/dist/commands/legacy-epic-terminal.js +1 -71
  39. package/packages/client/dist/commands/legacy-story-branch.js +1 -96
  40. package/packages/client/dist/commands/legacy-story-pr.js +1 -276
  41. package/packages/client/dist/commands/mutation-qa-checkpoint.js +5 -285
  42. package/packages/client/dist/commands/mutation-qa-gate.js +1 -54
  43. package/packages/client/dist/commands/mutation-qa-git.js +1 -41
  44. package/packages/client/dist/commands/mutation-qa-policy.js +1 -102
  45. package/packages/client/dist/commands/mutation-qa-run.js +3 -219
  46. package/packages/client/dist/commands/mutation-qa-verdict.js +1 -149
  47. package/packages/client/dist/commands/mutation-qa.js +1 -220
  48. package/packages/client/dist/commands/native-agent.js +2 -136
  49. package/packages/client/dist/commands/planning-diagnosis.js +1 -43
  50. package/packages/client/dist/commands/planning-generation.js +1 -53
  51. package/packages/client/dist/commands/planning-memory.js +1 -40
  52. package/packages/client/dist/commands/planning-research.js +1 -42
  53. package/packages/client/dist/commands/private-session.js +1 -75
  54. package/packages/client/dist/commands/property-qa.js +1 -139
  55. package/packages/client/dist/commands/qa-control.js +1 -16
  56. package/packages/client/dist/commands/qa-scan-browser-launch.js +1 -55
  57. package/packages/client/dist/commands/qa-scan-browser-route.js +1 -28
  58. package/packages/client/dist/commands/qa-scan-capture.js +5 -663
  59. package/packages/client/dist/commands/qa-scan-discovery.js +3 -376
  60. package/packages/client/dist/commands/qa-scan-review.js +5 -826
  61. package/packages/client/dist/commands/qa-synthetic-backend-capture.js +1 -266
  62. package/packages/client/dist/commands/qa-synthetic-backend-review.js +1 -297
  63. package/packages/client/dist/commands/qa-synthetic-backend.js +2 -340
  64. package/packages/client/dist/commands/qa-synthetic-broker-port.js +1 -85
  65. package/packages/client/dist/commands/qa-synthetic-browser.js +1 -39
  66. package/packages/client/dist/commands/refactor-characterization.js +21 -671
  67. package/packages/client/dist/commands/refactor-commit.js +13 -399
  68. package/packages/client/dist/commands/refactor-control.js +3 -142
  69. package/packages/client/dist/commands/refactor-cpp-assertions.js +3 -93
  70. package/packages/client/dist/commands/refactor-review.js +5 -283
  71. package/packages/client/dist/commands/refactor-root.js +7 -588
  72. package/packages/client/dist/commands/refresh-memory.js +3 -156
  73. package/packages/client/dist/commands/shared-architecture-non-ui.js +1 -24
  74. package/packages/client/dist/commands/story-checkpoint.js +1 -171
  75. package/packages/client/dist/config/profile-directory.js +1 -13
  76. package/packages/client/dist/config/resolver-selection.js +1 -278
  77. package/packages/client/dist/config/secure-config.js +12 -281
  78. package/packages/client/dist/config.js +2 -223
  79. package/packages/client/dist/constants.js +1 -25
  80. package/packages/client/dist/context/context-collector.js +2 -222
  81. package/packages/client/dist/context/context-sanitizer.js +1 -145
  82. package/packages/client/dist/continuity/autonomous-governance.js +1 -285
  83. package/packages/client/dist/continuity/continuity-client-state-store.js +1 -1587
  84. package/packages/client/dist/continuity/invoke-hooks.js +1 -129
  85. package/packages/client/dist/continuity/migrations/001-initial-schema.js +2 -12
  86. package/packages/client/dist/continuity/migrations/002-processing-output-summary-indexes.js +2 -12
  87. package/packages/client/dist/continuity/migrations/003-headless-execution-attempts.js +2 -12
  88. package/packages/client/dist/continuity/migrations/004-outbox-delivery-state.js +2 -12
  89. package/packages/client/dist/continuity/migrations/005-bounded-headless-queue.js +2 -12
  90. package/packages/client/dist/continuity/migrations/006-native-agent-dispatches.js +2 -10
  91. package/packages/client/dist/continuity/native-agent-store.js +1 -69
  92. package/packages/client/dist/continuity/native-agent-types.js +1 -90
  93. package/packages/client/dist/continuity/outbox.js +1 -117
  94. package/packages/client/dist/continuity/runner-bootstrap-policy.js +1 -172
  95. package/packages/client/dist/continuity/sqlite-store.js +81 -2612
  96. package/packages/client/dist/effects/invoke-effect-gateways.js +1 -62
  97. package/packages/client/dist/errors/error-messages.js +2 -228
  98. package/packages/client/dist/errors/frontmatter-diagnostics.js +1 -125
  99. package/packages/client/dist/evidence/collector.js +1 -347
  100. package/packages/client/dist/evidence/index.js +1 -1
  101. package/packages/client/dist/evidence/types.js +0 -2
  102. package/packages/client/dist/fs/atomic-state-replace.js +1 -152
  103. package/packages/client/dist/generated/command-registry.generated.js +1 -4076
  104. package/packages/client/dist/generated/public-projections.generated.js +1 -149
  105. package/packages/client/dist/git/direct-yolo-c01-retry.js +4 -138
  106. package/packages/client/dist/git/direct-yolo-checkpoint.js +4 -1234
  107. package/packages/client/dist/git/epic-operational-state.js +2 -672
  108. package/packages/client/dist/git/git-lifecycle-step-ids.js +1 -14
  109. package/packages/client/dist/git/git-lifecycle-store.d.ts +23 -0
  110. package/packages/client/dist/git/git-lifecycle-store.js +10 -1981
  111. package/packages/client/dist/git/legacy-story-branch-checkpoint.js +9 -259
  112. package/packages/client/dist/git/legacy-story-branch-setup.js +4 -348
  113. package/packages/client/dist/git/legacy-story-pr.js +70 -3538
  114. package/packages/client/dist/git/secure-filesystem-boundary.js +5 -182
  115. package/packages/client/dist/graph-retrieval/pre-command-hook.js +1 -284
  116. package/packages/client/dist/graph-retrieval/shared-graph-retrieval-contract.js +1 -237
  117. package/packages/client/dist/i18n/first-run.js +2 -60
  118. package/packages/client/dist/index.js +1 -47
  119. package/packages/client/dist/invocation/invoke-input.js +1 -24
  120. package/packages/client/dist/license/index.js +1 -5
  121. package/packages/client/dist/license/license-client.js +1 -304
  122. package/packages/client/dist/machine/fingerprint.js +2 -163
  123. package/packages/client/dist/machine/index.js +1 -5
  124. package/packages/client/dist/memory/project-memory-path-scope.js +1 -62
  125. package/packages/client/dist/memory/project-memory-writer.js +40 -1007
  126. package/packages/client/dist/memory/shared-project-memory-types.js +2 -253
  127. package/packages/client/dist/migrations/epic-lifecycle-backfill.js +3 -1060
  128. package/packages/client/dist/migrations/project-identity-capability.js +1 -50
  129. package/packages/client/dist/migrations/project-identity.js +7 -493
  130. package/packages/client/dist/migrations/state-json.js +4 -393
  131. package/packages/client/dist/policy/architecture-policy.js +2 -184
  132. package/packages/client/dist/policy/index.js +1 -7
  133. package/packages/client/dist/policy/shared-policy-types.js +0 -38
  134. package/packages/client/dist/policy/subagent-approval-policy.js +1 -55
  135. package/packages/client/dist/private-execution/clean-baseline.js +2 -279
  136. package/packages/client/dist/private-execution/codex-executor.js +4 -574
  137. package/packages/client/dist/private-execution/codex-host-runtime.js +1 -137
  138. package/packages/client/dist/private-execution/codex-lifecycle-guard.js +1 -97
  139. package/packages/client/dist/private-execution/codex-scoped-permissions.js +1 -128
  140. package/packages/client/dist/private-execution/delivery.js +13 -410
  141. package/packages/client/dist/private-execution/diagnosis-root-review.js +2 -294
  142. package/packages/client/dist/private-execution/frozen-handoff.js +6 -19
  143. package/packages/client/dist/private-execution/implementation-validation.js +2 -106
  144. package/packages/client/dist/private-execution/isolated-admission.js +23 -1432
  145. package/packages/client/dist/private-execution/isolated-session.js +5 -725
  146. package/packages/client/dist/private-execution/isolated-workspace.js +1 -122
  147. package/packages/client/dist/private-execution/pact-consumer-runtime.js +3 -409
  148. package/packages/client/dist/private-execution/pact-test-source.js +1 -258
  149. package/packages/client/dist/private-execution/pact-toolchain.js +3 -290
  150. package/packages/client/dist/private-execution/pact-write-set.js +1 -172
  151. package/packages/client/dist/private-execution/planning-diagnosis-checkpoint.js +5 -406
  152. package/packages/client/dist/private-execution/planning-generation-checkpoint.js +5 -462
  153. package/packages/client/dist/private-execution/planning-memory-checkpoint.js +3 -139
  154. package/packages/client/dist/private-execution/planning-research-checkpoint.js +4 -325
  155. package/packages/client/dist/private-execution/private-report-store.js +1 -42
  156. package/packages/client/dist/private-execution/property-test-candidate.js +1 -103
  157. package/packages/client/dist/private-execution/property-test-choices.js +3 -147
  158. package/packages/client/dist/private-execution/property-test-plan.js +7 -271
  159. package/packages/client/dist/private-execution/property-test-review.js +4 -258
  160. package/packages/client/dist/private-execution/property-test-runtime.js +9 -372
  161. package/packages/client/dist/private-execution/property-test-source.js +1 -139
  162. package/packages/client/dist/private-execution/root-checkpoint.js +1 -80
  163. package/packages/client/dist/private-execution/root-memory-git-evidence.js +3 -135
  164. package/packages/client/dist/private-execution/root-memory-recovery.js +1 -93
  165. package/packages/client/dist/private-execution/root-memory-request.js +1 -29
  166. package/packages/client/dist/private-execution/root-memory-scope.js +1 -178
  167. package/packages/client/dist/private-execution/root-memory-writer.js +1 -102
  168. package/packages/client/dist/private-execution/session-lease.js +1 -63
  169. package/packages/client/dist/private-execution/shared-private-admission-types.js +1 -50
  170. package/packages/client/dist/private-execution/shared-project-validation.js +1 -66
  171. package/packages/client/dist/private-execution/shared-root-memory-types.js +1 -61
  172. package/packages/client/dist/private-execution/ux-source-validation.js +1 -372
  173. package/packages/client/dist/private-execution/ux-write-set.js +2 -191
  174. package/packages/client/dist/registry/registry-reconciliation.js +1 -234
  175. package/packages/client/dist/resilience/circuit-breaker.js +1 -170
  176. package/packages/client/dist/resilience/degradation-manager.js +1 -164
  177. package/packages/client/dist/resilience/freshness-indicator.js +1 -100
  178. package/packages/client/dist/resilience/index.js +1 -8
  179. package/packages/client/dist/resilience/recovery-detector.js +1 -74
  180. package/packages/client/dist/resolvers/asset-resolver.js +0 -13
  181. package/packages/client/dist/resolvers/local-resolver.js +8 -255
  182. package/packages/client/dist/resolvers/remote-resolver.js +1 -233
  183. package/packages/client/dist/runner/binary.js +1 -404
  184. package/packages/client/dist/runner/cli.js +17 -1571
  185. package/packages/client/dist/runner/headless/adapters.js +1 -49
  186. package/packages/client/dist/runner/headless/claude-code-adapter.js +1 -79
  187. package/packages/client/dist/runner/headless/continuous-story-workspace.js +11 -1628
  188. package/packages/client/dist/runner/headless/epic-git-reconciliation-inventory.js +1 -69
  189. package/packages/client/dist/runner/headless/epic-merge-candidate-qa.d.ts +1 -1
  190. package/packages/client/dist/runner/headless/epic-merge-candidate-qa.js +2 -110
  191. package/packages/client/dist/runner/headless/epic-terminal-git-cli-adapter.d.ts +2 -0
  192. package/packages/client/dist/runner/headless/epic-terminal-git-cli-adapter.js +10 -1236
  193. package/packages/client/dist/runner/headless/epic-terminal-git-runner.d.ts +18 -2
  194. package/packages/client/dist/runner/headless/epic-terminal-git-runner.js +2 -318
  195. package/packages/client/dist/runner/headless/fake-adapter.js +1 -62
  196. package/packages/client/dist/runner/headless/managed-profile.js +1 -132
  197. package/packages/client/dist/runner/headless/opencode-adapter.js +2 -145
  198. package/packages/client/dist/runner/headless/prepared-story-bundle.js +1 -43
  199. package/packages/client/dist/runner/headless/resolver.js +1 -231
  200. package/packages/client/dist/runner/headless/run-yolo.js +1 -885
  201. package/packages/client/dist/runner/headless/run-yoloop.d.ts +1 -0
  202. package/packages/client/dist/runner/headless/run-yoloop.js +2 -2574
  203. package/packages/client/dist/runner/headless/types.js +2 -574
  204. package/packages/client/dist/runner/local-console.js +13 -396
  205. package/packages/client/dist/runner/portal-sync-worker.js +1 -1487
  206. package/packages/client/dist/runner/project-identity.js +1 -106
  207. package/packages/client/dist/runner/scheduler.js +7 -995
  208. package/packages/client/dist/runner-cli.js +2 -18
  209. package/packages/client/dist/state/invocation-shape.js +1 -13
  210. package/packages/client/dist/state/project-state-snapshot.js +1 -1731
  211. package/packages/client/dist/state/state-json-repair.js +3 -785
  212. package/packages/client/dist/state/structural-dag-projection.js +1 -118
  213. package/packages/client/dist/telemetry/index.js +1 -5
  214. package/packages/client/dist/telemetry/offline-queue.js +1 -131
  215. package/packages/client/dist/tier/index.js +1 -5
  216. package/packages/client/dist/tier/tier-aware-client.js +1 -405
  217. package/packages/client/dist/types/index.js +1 -38
  218. package/packages/client/dist/version.js +1 -27
  219. package/packages/client/dist/yolo/change-evidence-collector.js +1 -126
  220. package/packages/client/dist/yolo/invoke-envelope-capability.js +1 -62
  221. package/packages/client/dist/yolo/spec-envelope-collector.js +5 -184
  222. package/packages/client/dist/yoloop/discovery-hook.js +2 -300
  223. package/packages/client/dist/yoloop/index.js +1 -8
  224. package/packages/client/dist/yoloop/invoke-hooks.js +12 -669
  225. package/packages/client/dist/yoloop/shared-discover-epics.js +1 -1007
  226. package/packages/client/dist/yoloop/shared-yoloop-types.js +1 -33
  227. package/packages/client/dist/yoloop/target-normalization.js +1 -180
  228. package/packages/client/dist/yoloop/yoloop-client-state-store.js +1 -1920
  229. package/packages/shared/dist/yolo/change-evidence.js +1 -1
  230. package/packages/shared/dist/yoloop/epic-terminal-git.js +144 -2
  231. package/targets-stubs/antigravity/gemini.md +1 -1
  232. package/targets-stubs/antigravity/skill/SKILL.md +1 -1
  233. package/targets-stubs/claude-code/neocortex-root.agent.yaml +1 -1
  234. package/targets-stubs/claude-code/neocortex-root.md +2 -2
  235. package/targets-stubs/claude-code/neocortex.agent.yaml +1 -1
  236. package/targets-stubs/claude-code/neocortex.md +2 -2
  237. package/targets-stubs/codex/AGENTS.md +1 -1
  238. package/targets-stubs/cursor/agent.md +2 -2
  239. package/targets-stubs/gemini-cli/agent.md +2 -2
  240. package/targets-stubs/opencode/neocortex-root.md +1 -1
  241. package/targets-stubs/vscode/neocortex.agent.md +2 -2
@@ -1,146 +1,4 @@
1
- /**
2
- * @license FSL-1.1
3
- * Copyright (c) 2026 OrNexus AI
4
- *
5
- * P190.06 -- runner root-owned execution plane for run_yoloop directives.
6
- */
7
- import { createHash, randomBytes } from 'node:crypto';
8
- import { spawn } from 'node:child_process';
9
- import { existsSync } from 'node:fs';
10
- import * as os from 'node:os';
11
- import { dirname, join } from 'node:path';
12
- import { fileURLToPath } from 'node:url';
13
- import { AUTONOMOUS_GOVERNANCE_EVIDENCE_TAG, AUTONOMOUS_GOVERNANCE_REASON_CODES, autonomousGovernanceMetadata, buildAutonomousGovernanceEnvelope, readAutonomousGovernanceEnvelopeFromMetadata, recordAutonomousGovernance, } from '../../continuity/autonomous-governance.js';
14
- import { createDefaultHeadlessAdapterRegistry } from './adapters.js';
15
- import { loadHeadlessRuntimeDefaults, resolveHeadlessRuntime } from './resolver.js';
16
- import { DEFAULT_HEADLESS_EXECUTION_BACKOFF_MS, DEFAULT_HEADLESS_EXECUTION_LEASE_MS, DEFAULT_HEADLESS_EXECUTION_LIMIT, DEFAULT_HEADLESS_EXECUTION_MAX_ATTEMPTS, DEFAULT_HEADLESS_EXECUTION_STALE_LEASE_AFTER_MS, DEFAULT_HEADLESS_EXECUTION_TIMEOUT_MS, headlessExecutionEntityId, runYoloExecutionPhase, } from './run-yolo.js';
17
- import { HEADLESS_REASON_CODES, boundPublicSummary, hashPublicValue, redaction, } from './types.js';
18
- import { validatePhasedYoloopPlan } from './prepared-story-bundle.js';
19
- import { createAnchoredContinuousStoryCommandRunner, createBranchlessContinuousStoryWorkspaceManager, } from './continuous-story-workspace.js';
20
- import { executeEpicGitReconciliation, executeEpicTerminalGit } from './epic-terminal-git-runner.js';
21
- import { createCliEpicTerminalGitAdapter } from './epic-terminal-git-cli-adapter.js';
22
- import { acquireGitLifecyclePhysicalIntegrationLock, releaseGitLifecyclePhysicalIntegrationLock, } from '../../git/git-lifecycle-store.js';
23
- import { normalizeContinuousWriteRef } from '../../../../shared/dist/yoloop/wave-decision-receipt.js';
24
- import { parseReleaseBlockedResult, } from '../../../../shared/dist/yoloop/release-blocked.js';
25
- export const DEFAULT_HEADLESS_YOLOOP_MAX_ITERATIONS = 20;
26
- export const DEFAULT_HEADLESS_YOLOOP_MAX_DURATION_MS = 30 * 60 * 1000;
27
- export const DEFAULT_HEADLESS_YOLOOP_LOCAL_CONCURRENCY_CAP = 1;
28
- export const MAX_HEADLESS_YOLOOP_LOCAL_CONCURRENCY_CAP = 10;
29
- /**
30
- * Resolve the absent-override default from physical capacity. The explicit CLI
31
- * option remains authoritative; this resolver is injectable for deterministic
32
- * Node 18 fallback tests.
33
- */
34
- export function resolveDefaultHeadlessYoloopLocalConcurrencyCap(input = {}) {
35
- let reported = input.availableParallelism;
36
- if (reported === undefined) {
37
- const available = os.availableParallelism;
38
- if (typeof available === 'function') {
39
- try {
40
- reported = available();
41
- }
42
- catch {
43
- reported = undefined;
44
- }
45
- }
46
- }
47
- if (!Number.isFinite(reported) || (reported ?? 0) < 1) {
48
- const cpuCount = input.cpuCount ?? (() => {
49
- try {
50
- return os.cpus().length;
51
- }
52
- catch {
53
- return DEFAULT_HEADLESS_YOLOOP_LOCAL_CONCURRENCY_CAP;
54
- }
55
- })();
56
- reported = Number.isFinite(cpuCount) && cpuCount > 0
57
- ? cpuCount
58
- : DEFAULT_HEADLESS_YOLOOP_LOCAL_CONCURRENCY_CAP;
59
- }
60
- return boundedInteger(reported ?? DEFAULT_HEADLESS_YOLOOP_LOCAL_CONCURRENCY_CAP, 1, MAX_HEADLESS_YOLOOP_LOCAL_CONCURRENCY_CAP);
61
- }
62
- export const RUN_YOLOOP_DRIVER_STATES = Object.freeze([
63
- 'start',
64
- 'lifecycle_evidence',
65
- 'metadata_parse',
66
- 'child_story_delegation',
67
- 'reinvoke',
68
- 'git_reconciliation',
69
- 'terminal_git',
70
- 'complete',
71
- 'aborted',
72
- 'release_blocked',
73
- 'backoff',
74
- ]);
75
- const EPIC_TARGET_PATTERN = /^docs\/epics\/epic-[A-Za-z0-9._-]+\.md$/;
76
- const CHILD_STORY_TARGET_PATTERN = /^docs\/stories\/[A-Za-z0-9._-]+\.story\.md$/;
77
- const CHILD_PROMPT_PATTERN = /^\*yolo @docs\/stories\/[A-Za-z0-9._-]+\.story\.md(?: branchless-preparation)?$/;
78
- const BRANCHLESS_PREPARATION_PROMPT_PATTERN = /^\*yolo @docs\/stories\/[A-Za-z0-9._-]+\.story\.md branchless-preparation$/;
79
- const FRONTMATTER_ENVELOPE_PATTERN = /^(?:\uFEFF)?---(?:\r?\n)/;
80
- const SAFE_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,159}$/;
81
- const SHELL_FRAGMENT_PATTERN = /(?:[;&|`$<>]|\$\(|\n|\r|\0)/;
82
- const UNSAFE_KEY_PATTERN = /(raw[_-]?(?:logs?|payloads?)|std(?:out|err)|stack(?:[_-]?trace)?|transcript|objective(?:[_-]?(?:text|body|prompt))|prompt(?:[_-]?(?:body|text))?|private[_-]?(?:urls?|prompts?)|secret|token|password|protected(?:[_-]?(?:field|body|bodies|internals))?|workflow(?:[_-]?body)?|step(?:[_-]?body)?|customer(?:[_-]?(?:pii|data))?|\bpii\b|authorization|api[_-]?key|license[_-]?key|argv|args|executable(?:[_-]?path)?|binary(?:[_-]?path)?|shell|cwd|command[_-]?path|vendor(?:[_-]?(?:payload|corpus|response|output)))/i;
83
- const UNSAFE_VALUE_PATTERN = /(https?:\/\/\S+|(?:^|\s)(?:\/(?:home|Users|media|mnt|tmp|var|etc|private)\/\S+|[A-Za-z]:\\\S+)|ghp_[A-Za-z0-9_]+|sk-[A-Za-z0-9_-]+|-----BEGIN [A-Z ]*PRIVATE KEY-----|authorization\s*:|password\s*=|token\s*=|api[_-]?key\s*=|license[_-]?key\s*=|raw[_-]?(?:logs?)\s*[:=]|transcript|stack\s*trace|stderr:|stdout:|system prompt|workflow body|step body|PROTECTED_|PRIVATE_INTERNALS|CUSTOMER_PII|\bPII\b|VENDOR_CORPUS|P190[_-]?SYNTHETIC[_-]?(?:HEADLESS|CONTINUITY))/i;
84
- const PUBLIC_CHILD_DEBT_CONSTRAINTS = new Set([
85
- 'no_private_prompt_or_history',
86
- 'no_raw_vendor_corpus',
87
- 'no_unrelated_story_context',
88
- ]);
89
- function hasDelegatedPromptIsolationViolation(prompt) {
90
- return FRONTMATTER_ENVELOPE_PATTERN.test(prompt) ||
91
- prompt.includes('@neocortex') ||
92
- prompt.includes('*yoloop') ||
93
- SHELL_FRAGMENT_PATTERN.test(prompt) ||
94
- UNSAFE_VALUE_PATTERN.test(prompt);
95
- }
96
- export function isCanonicalDelegatedStoryPrompt(prompt) {
97
- return !hasDelegatedPromptIsolationViolation(prompt) && CHILD_PROMPT_PATTERN.test(prompt);
98
- }
99
- const EXECUTION_DIRECTIVE_ALLOWED_KEYS = new Set([
100
- 'schemaVersion',
101
- 'contractVersion',
102
- 'kind',
103
- 'commandClass',
104
- 'jobId',
105
- 'operationId',
106
- 'idempotencyKey',
107
- 'targetKind',
108
- 'targetRef',
109
- 'commandRef',
110
- 'epicId',
111
- 'runtime',
112
- 'publicSummary',
113
- 'reasonCode',
114
- 'attempts',
115
- 'metadata',
116
- 'redactionSummary',
117
- 'publicSafe',
118
- ]);
119
- const RUNTIME_ALLOWED_KEYS = new Set(['runtimeId', 'modelId', 'source', 'reasonCode', 'publicSafe']);
120
- const JOB_ABORTED_REASON_CODE = 'job-aborted';
121
- const MAX_ITERATIONS_REASON_CODE = 'max-iterations-reached';
122
- const MAX_DURATION_REASON_CODE = 'max-duration-reached';
123
- const PUBLIC_TERMINAL_LOCK_RETRY_REASONS = new Set([
124
- 'git-lifecycle-integration-backpressure',
125
- 'git-lifecycle-integration-lock-failed',
126
- 'git-lifecycle-integration-lock-release-failed',
127
- ]);
128
- const RESUMABLE_YOLOOP_BOUNDARY_REASONS = new Set([
129
- 'yoloop-per-run-cap-resumable',
130
- 'yoloop-session-timeout-resumable',
131
- ]);
132
- async function defaultIsolatedYoloopRootInvokeTransport(options, boundary) {
133
- // The thin client's lock belongs to its invocation PID. Keeping invoke in
134
- // the long-lived runner made the next iteration see its own PID as another
135
- // live owner forever. Use the normal short-lived client lifetime; only the
136
- // existing local liveness reconciler may recover its lock after process exit.
137
- // Loop scheduling and all Git effects remain in this root, not in the child.
138
- const moduleDirectory = dirname(fileURLToPath(import.meta.url));
139
- const installedModule = join(moduleDirectory, '../../commands/invoke.js');
140
- const modulePath = existsSync(installedModule) ? installedModule
141
- : join(moduleDirectory, '../../../dist/commands/invoke.js');
142
- return new Promise((resolveResult) => {
143
- const child = spawn(process.execPath, ['--input-type=module', '-e', `
1
+ import{createHash as Ke,randomBytes as Ue}from"node:crypto";import{spawn as ze}from"node:child_process";import{existsSync as $e}from"node:fs";import*as ke from"node:os";import{dirname as Ye,join as Oe}from"node:path";import{fileURLToPath as Fe}from"node:url";import{AUTONOMOUS_GOVERNANCE_EVIDENCE_TAG as Ve,AUTONOMOUS_GOVERNANCE_REASON_CODES as Ee,autonomousGovernanceMetadata as Re,buildAutonomousGovernanceEnvelope as qe,readAutonomousGovernanceEnvelopeFromMetadata as ve,recordAutonomousGovernance as We}from"../../continuity/autonomous-governance.js";import{createDefaultHeadlessAdapterRegistry as Ge}from"./adapters.js";import{loadHeadlessRuntimeDefaults as Xe,resolveHeadlessRuntime as Ze}from"./resolver.js";import{DEFAULT_HEADLESS_EXECUTION_BACKOFF_MS as Je,DEFAULT_HEADLESS_EXECUTION_LIMIT as Qe,DEFAULT_HEADLESS_EXECUTION_MAX_ATTEMPTS as et,DEFAULT_HEADLESS_EXECUTION_STALE_LEASE_AFTER_MS as tt,DEFAULT_HEADLESS_EXECUTION_TIMEOUT_MS as rt,headlessExecutionEntityId as q,runYoloExecutionPhase as ot}from"./run-yolo.js";import{HEADLESS_REASON_CODES as p,boundPublicSummary as me,hashPublicValue as x,redaction as h}from"./types.js";import{validatePhasedYoloopPlan as at}from"./prepared-story-bundle.js";import{createAnchoredContinuousStoryCommandRunner as nt,createBranchlessContinuousStoryWorkspaceManager as st}from"./continuous-story-workspace.js";import{P205_RELEASE_GATE_BUDGETS as oe}from"../../../../shared/dist/yoloop/epic-terminal-git.js";import{executeEpicGitReconciliation as it,executeEpicTerminalGit as dt}from"./epic-terminal-git-runner.js";import{createCliEpicTerminalGitAdapter as ct}from"./epic-terminal-git-cli-adapter.js";import{acquireGitLifecyclePhysicalIntegrationLock as lt,releaseGitLifecyclePhysicalIntegrationLock as ut}from"../../git/git-lifecycle-store.js";import{normalizeContinuousWriteRef as pt}from"../../../../shared/dist/yoloop/wave-decision-receipt.js";import{parseReleaseBlockedResult as mt}from"../../../../shared/dist/yoloop/release-blocked.js";const ft=20,yt=oe.terminalWorkflowMaxDurationMs,ht=oe.terminalWorkflowMaxDurationMs,fe=1,Pe=10;function Te(e={}){let r=e.availableParallelism;if(r===void 0){const t=ke.availableParallelism;if(typeof t=="function")try{r=t()}catch{r=void 0}}if(!Number.isFinite(r)||(r??0)<1){const t=e.cpuCount??(()=>{try{return ke.cpus().length}catch{return fe}})();r=Number.isFinite(t)&&t>0?t:fe}return F(r??fe,1,Pe)}const Or=Object.freeze(["start","lifecycle_evidence","metadata_parse","child_story_delegation","reinvoke","git_reconciliation","terminal_git","complete","aborted","release_blocked","backoff"]),ye=/^docs\/epics\/epic-[A-Za-z0-9._-]+\.md$/,_t=/^docs\/stories\/[A-Za-z0-9._-]+\.story\.md$/,he=/^\*yolo @docs\/stories\/[A-Za-z0-9._-]+\.story\.md(?: branchless-preparation)?$/,Ct=/^\*yolo @docs\/stories\/[A-Za-z0-9._-]+\.story\.md branchless-preparation$/,It=/^(?:\uFEFF)?---(?:\r?\n)/,bt=/^[A-Za-z0-9][A-Za-z0-9._:-]{0,159}$/,W=/(?:[;&|`$<>]|\$\(|\n|\r|\0)/,ae=/(raw[_-]?(?:logs?|payloads?)|std(?:out|err)|stack(?:[_-]?trace)?|transcript|objective(?:[_-]?(?:text|body|prompt))|prompt(?:[_-]?(?:body|text))?|private[_-]?(?:urls?|prompts?)|secret|token|password|protected(?:[_-]?(?:field|body|bodies|internals))?|workflow(?:[_-]?body)?|step(?:[_-]?body)?|customer(?:[_-]?(?:pii|data))?|\bpii\b|authorization|api[_-]?key|license[_-]?key|argv|args|executable(?:[_-]?path)?|binary(?:[_-]?path)?|shell|cwd|command[_-]?path|vendor(?:[_-]?(?:payload|corpus|response|output)))/i,D=/(https?:\/\/\S+|(?:^|\s)(?:\/(?:home|Users|media|mnt|tmp|var|etc|private)\/\S+|[A-Za-z]:\\\S+)|ghp_[A-Za-z0-9_]+|sk-[A-Za-z0-9_-]+|-----BEGIN [A-Z ]*PRIVATE KEY-----|authorization\s*:|password\s*=|token\s*=|api[_-]?key\s*=|license[_-]?key\s*=|raw[_-]?(?:logs?)\s*[:=]|transcript|stack\s*trace|stderr:|stdout:|system prompt|workflow body|step body|PROTECTED_|PRIVATE_INTERNALS|CUSTOMER_PII|\bPII\b|VENDOR_CORPUS|P190[_-]?SYNTHETIC[_-]?(?:HEADLESS|CONTINUITY))/i,St=new Set(["no_private_prompt_or_history","no_raw_vendor_corpus","no_unrelated_story_context"]);function we(e){return It.test(e)||e.includes("@neocortex")||e.includes("*yoloop")||W.test(e)||D.test(e)}function Er(e){return!we(e)&&he.test(e)}const gt=new Set(["schemaVersion","contractVersion","kind","commandClass","jobId","operationId","idempotencyKey","targetKind","targetRef","commandRef","epicId","runtime","publicSummary","reasonCode","attempts","metadata","redactionSummary","publicSafe"]),At=new Set(["runtimeId","modelId","source","reasonCode","publicSafe"]),kt="job-aborted",Ot="max-iterations-reached",Et="max-duration-reached",Rt=new Set(["git-lifecycle-integration-backpressure","git-lifecycle-integration-lock-failed","git-lifecycle-integration-lock-release-failed"]),xe=new Set(["yoloop-per-run-cap-resumable","yoloop-session-timeout-resumable"]);async function vt(e,r){const t=Ye(Fe(import.meta.url)),a=Oe(t,"../../commands/invoke.js"),o=$e(a)?a:Oe(t,"../../../dist/commands/invoke.js");return new Promise(s=>{const n=ze(process.execPath,["--input-type=module","-e",`
144
2
  import { pathToFileURL } from 'node:url';
145
3
  process.once('message', async ({ modulePath, options }) => {
146
4
  try {
@@ -149,2434 +7,4 @@ async function defaultIsolatedYoloopRootInvokeTransport(options, boundary) {
149
7
  process.send(result, () => process.exit(0));
150
8
  } catch { process.exit(1); }
151
9
  });
152
- `], { cwd: boundary.projectRoot, stdio: ['ignore', 'pipe', 'pipe', 'ipc'], windowsHide: true });
153
- let received;
154
- let bytes = 0;
155
- let invalid = false;
156
- const timer = setTimeout(() => { invalid = true; child.kill(); }, boundary.timeoutMs);
157
- const countOutput = (chunk) => {
158
- bytes += chunk.length;
159
- if (bytes > 32 * 1024 * 1024) {
160
- invalid = true;
161
- child.kill();
162
- }
163
- };
164
- child.stdout?.on('data', countOutput);
165
- child.stderr?.on('data', countOutput);
166
- child.on('message', (value) => {
167
- if (received || !isRecord(value) || typeof value.success !== 'boolean'
168
- || Buffer.byteLength(JSON.stringify(value)) > 32 * 1024 * 1024) {
169
- invalid = true;
170
- child.kill();
171
- return;
172
- }
173
- received = value;
174
- });
175
- const failed = { success: false, errorCode: 'headless-root-invoke-failed',
176
- error: 'The isolated root metadata invocation did not complete.', exitCode: 1 };
177
- child.on('error', () => { invalid = true; });
178
- child.on('close', (code) => {
179
- clearTimeout(timer);
180
- resolveResult(code === 0 && !invalid && received ? received : failed);
181
- });
182
- child.send({ modulePath, options }, (error) => { if (error) {
183
- invalid = true;
184
- child.kill();
185
- } });
186
- });
187
- }
188
- export async function defaultYoloopRootInvoker(input, invokeTransport = defaultIsolatedYoloopRootInvokeTransport) {
189
- const startedAt = Date.now();
190
- const options = {
191
- args: input.args,
192
- projectRoot: input.projectRoot,
193
- format: 'json',
194
- platformTarget: 'runner',
195
- serverUrl: input.serverUrl,
196
- strictReadOnly: input.strictReadOnly,
197
- };
198
- const result = await invokeTransport(options, {
199
- projectRoot: input.projectRoot,
200
- timeoutMs: input.timeoutMs,
201
- });
202
- return {
203
- success: result.success,
204
- instructions: result.instructions,
205
- metadata: result.metadata,
206
- error: result.error,
207
- errorCode: result.errorCode,
208
- exitCode: result.exitCode,
209
- durationMs: Date.now() - startedAt,
210
- publicSafe: true,
211
- };
212
- }
213
- export async function runYoloopExecutionPhase(options) {
214
- const registry = options.adapterRegistry ?? createDefaultHeadlessAdapterRegistry();
215
- const limit = boundedInteger(options.limit ?? DEFAULT_HEADLESS_EXECUTION_LIMIT, 1, 10);
216
- const leaseMs = boundedInteger(options.leaseMs ?? DEFAULT_HEADLESS_EXECUTION_LEASE_MS, 1_000, 60 * 60 * 1000);
217
- const staleLeaseAfterMs = boundedInteger(options.staleLeaseAfterMs ?? DEFAULT_HEADLESS_EXECUTION_STALE_LEASE_AFTER_MS, 0, 24 * 60 * 60 * 1000);
218
- const maxAttempts = boundedInteger(options.maxAttempts ?? DEFAULT_HEADLESS_EXECUTION_MAX_ATTEMPTS, 1, 10);
219
- const localConcurrencyCap = boundedInteger(options.localConcurrencyCap ?? resolveDefaultHeadlessYoloopLocalConcurrencyCap(), 1, MAX_HEADLESS_YOLOOP_LOCAL_CONCURRENCY_CAP);
220
- const reasonCodes = [];
221
- const receipts = [];
222
- const nowIso = options.now();
223
- const enqueueResult = enqueueRunYoloopExecutionDirectives({
224
- store: options.store,
225
- metadata: options.metadata,
226
- nowIso,
227
- maxAttempts,
228
- queueCap: options.queueCap,
229
- });
230
- reasonCodes.push(...enqueueResult.reasonCodes);
231
- const recovered = options.store.recoverStaleHeadlessExecutionAttempts({
232
- nowIso,
233
- staleAfterMs: staleLeaseAfterMs,
234
- limit: limit * 2,
235
- });
236
- if (recovered.recoveredAttemptIds.length > 0) {
237
- reasonCodes.push(HEADLESS_REASON_CODES.EXECUTION_BACKOFF);
238
- if (recovered.failedAttemptIds.length > 0)
239
- reasonCodes.push(HEADLESS_REASON_CODES.EXECUTION_TIMEOUT);
240
- }
241
- const dueAttempts = options.store
242
- .listDueHeadlessExecutionAttempts({ nowIso: options.now(), limit: Math.max(limit * 5, 10) })
243
- .filter((attempt) => attempt.directive_kind === 'run_yoloop')
244
- .slice(0, limit);
245
- for (const attempt of dueAttempts) {
246
- const receipt = await processRunYoloopAttempt({
247
- store: options.store,
248
- projectRoot: options.projectRoot,
249
- runnerId: options.runnerId,
250
- attempt,
251
- registry,
252
- now: options.now,
253
- leaseMs,
254
- timeoutMs: boundedInteger(options.timeoutMs ?? DEFAULT_HEADLESS_EXECUTION_TIMEOUT_MS, 1_000, 30 * 60 * 1000),
255
- backoffMs: boundedInteger(options.backoffMs ?? DEFAULT_HEADLESS_EXECUTION_BACKOFF_MS, 1_000, 60 * 60 * 1000),
256
- maxAttempts,
257
- maxIterations: boundedInteger(options.maxIterations ?? DEFAULT_HEADLESS_YOLOOP_MAX_ITERATIONS, 1, 100),
258
- maxDurationMs: boundedInteger(options.maxDurationMs ?? DEFAULT_HEADLESS_YOLOOP_MAX_DURATION_MS, 1_000, 2 * 60 * 60 * 1000),
259
- localConcurrencyCap,
260
- queueCap: options.queueCap,
261
- adapterOptions: options.adapterOptions,
262
- runtimeDefaults: options.runtimeDefaults,
263
- runtimeFallback: options.runtimeFallback,
264
- yoloopInvoker: options.yoloopInvoker ?? defaultYoloopRootInvoker,
265
- serverUrl: options.serverUrl,
266
- idFactory: options.idFactory ?? defaultHeadlessIdFactory,
267
- continuousWorkspaceManager: options.continuousWorkspaceManager ?? createBranchlessContinuousStoryWorkspaceManager(),
268
- terminalGitAdapter: options.terminalGitAdapter ?? createCliEpicTerminalGitAdapter(options.projectRoot),
269
- });
270
- receipts.push(receipt);
271
- reasonCodes.push(receipt.reasonCode, ...receipt.workerPoolSummary.reasonCodes);
272
- }
273
- return {
274
- ok: receipts.every((receipt) => receipt.outcome !== 'failed') && enqueueResult.rejectedCount === 0,
275
- enqueuedAttemptCount: enqueueResult.enqueuedCount,
276
- dueAttemptCount: dueAttempts.length,
277
- processedAttemptCount: receipts.filter((receipt) => receipt.outcome !== 'ignored').length,
278
- recoveredAttemptIds: recovered.recoveredAttemptIds,
279
- receipts,
280
- reasonCodes: unique(reasonCodes.length > 0 ? reasonCodes : [HEADLESS_REASON_CODES.OK]),
281
- publicSafe: true,
282
- };
283
- }
284
- function enqueueRunYoloopExecutionDirectives(input) {
285
- let enqueuedCount = 0;
286
- let rejectedCount = 0;
287
- const reasonCodes = [];
288
- for (const candidate of extractExecutionDirectiveCandidates(input.metadata)) {
289
- if (!isRecord(candidate) || candidate.kind !== 'run_yoloop')
290
- continue;
291
- const validation = validateRunYoloopExecutionDirective(candidate);
292
- if (!validation.ok) {
293
- rejectedCount += 1;
294
- reasonCodes.push(validation.reasonCode);
295
- continue;
296
- }
297
- const directive = validation.directive;
298
- if (!input.store.jobExists(directive.jobId)) {
299
- rejectedCount += 1;
300
- reasonCodes.push(AUTONOMOUS_GOVERNANCE_REASON_CODES.BYPASS_BLOCKED);
301
- continue;
302
- }
303
- const directiveHash = hashDirective(directive);
304
- if (input.store.hasCompletedHeadlessExecutionDirectiveHash(directiveHash)) {
305
- reasonCodes.push(HEADLESS_REASON_CODES.EXECUTION_COMPLETED);
306
- continue;
307
- }
308
- const governanceEnvelope = buildAutonomousGovernanceEnvelope({
309
- autonomousKind: 'run_yoloop',
310
- source: 'headless-run-yoloop',
311
- targetKind: 'epic',
312
- targetRef: directive.targetRef,
313
- epicId: directive.epicId ?? epicIdFromTargetRef(directive.targetRef),
314
- jobId: directive.jobId,
315
- operationSeed: directive.operationId,
316
- commandHash: hashPublicValue(directive.commandRef),
317
- });
318
- const governance = recordAutonomousGovernance(input.store, governanceEnvelope, input.nowIso, { requireExistingJob: true });
319
- if (!governance.ok) {
320
- rejectedCount += 1;
321
- reasonCodes.push(governance.reasonCode);
322
- continue;
323
- }
324
- const attemptId = headlessExecutionEntityId('attempt', directive.idempotencyKey);
325
- const executionId = headlessExecutionEntityId('exec', directive.operationId);
326
- const result = input.store.enqueueHeadlessExecutionAttempt({
327
- attemptId,
328
- executionId,
329
- jobId: directive.jobId,
330
- directiveHash,
331
- directiveKind: 'run_yoloop',
332
- commandClass: directive.commandClass,
333
- targetKind: 'epic',
334
- targetRef: directive.targetRef,
335
- epicId: directive.epicId ?? epicIdFromTargetRef(directive.targetRef),
336
- runtimeId: directive.runtime?.runtimeId,
337
- modelId: directive.runtime?.modelId,
338
- runtimeSource: normalizeStoredRuntimeSource(directive.runtime?.source),
339
- reasonCode: directive.reasonCode,
340
- publicSummary: directive.publicSummary,
341
- enqueuedAt: input.nowIso,
342
- notBeforeAt: input.nowIso,
343
- maxAttempts: input.maxAttempts,
344
- queueCap: input.queueCap,
345
- operationId: `${directive.operationId}:enqueue`,
346
- idempotencyKey: directive.idempotencyKey,
347
- counts: { directives: 1 },
348
- hashes: { directive: directiveHash },
349
- redactionSummary: directive.redactionSummary,
350
- relativePaths: [directive.targetRef],
351
- metadata: autonomousGovernanceMetadata(governanceEnvelope, {
352
- schemaVersion: 1,
353
- contractVersion: 'continuity-v1',
354
- jobId: directive.jobId,
355
- operationId: directive.operationId,
356
- reasonCode: directive.reasonCode ?? HEADLESS_REASON_CODES.OK,
357
- targetRef: directive.targetRef,
358
- directiveHash,
359
- }),
360
- });
361
- if (!result.accepted) {
362
- rejectedCount += 1;
363
- reasonCodes.push(result.reasonCode ?? 'queue-cap-reached');
364
- continue;
365
- }
366
- if (result.inserted)
367
- enqueuedCount += 1;
368
- reasonCodes.push(HEADLESS_REASON_CODES.OK);
369
- }
370
- return { enqueuedCount, rejectedCount, reasonCodes: unique(reasonCodes) };
371
- }
372
- async function processRunYoloopAttempt(input) {
373
- const claimedAt = input.now();
374
- const leaseId = input.idFactory('lease', input.attempt.attempt_id);
375
- const leaseExpiresAt = addMilliseconds(claimedAt, input.leaseMs);
376
- const claim = input.store.claimHeadlessExecutionAttempt({
377
- attemptId: input.attempt.attempt_id,
378
- leaseId,
379
- runnerId: input.runnerId,
380
- claimedAt,
381
- leaseExpiresAt,
382
- reasonCode: HEADLESS_REASON_CODES.OK,
383
- });
384
- if (!claim.inserted) {
385
- return emptyYoloopReceipt(input.attempt, {
386
- status: input.attempt.status,
387
- receiptStatus: 'ignored',
388
- reasonCode: 'lease-conflict',
389
- timestamp: claimedAt,
390
- });
391
- }
392
- const duplicateCompletion = input.store.hasCompletedHeadlessExecutionDirectiveHash(input.attempt.directive_hash, input.attempt.attempt_id);
393
- if (duplicateCompletion) {
394
- return persistYoloopAttemptOutcome(input.store, input.attempt, {
395
- leaseId,
396
- runnerId: input.runnerId,
397
- status: 'skipped',
398
- receiptStatus: 'ignored',
399
- reasonCode: HEADLESS_REASON_CODES.EXECUTION_COMPLETED,
400
- publicSummary: 'Skipped duplicate run_yoloop directive because the directive hash is already completed.',
401
- completedAt: input.now(),
402
- counts: emptyAggregateCounts(),
403
- hashes: { directive: input.attempt.directive_hash },
404
- redactionSummary: [],
405
- relativePaths: [input.attempt.target_ref],
406
- childStoryIds: [],
407
- stateTransitions: ['start', 'complete'],
408
- });
409
- }
410
- const preparation = prepareYoloopAttemptInput(input);
411
- if (!preparation.ok) {
412
- return persistYoloopAttemptOutcome(input.store, input.attempt, {
413
- leaseId,
414
- runnerId: input.runnerId,
415
- status: preparation.status,
416
- receiptStatus: preparation.receiptStatus,
417
- reasonCode: preparation.reasonCode,
418
- publicSummary: preparation.publicSummary,
419
- completedAt: input.now(),
420
- counts: emptyAggregateCounts(),
421
- hashes: { directive: input.attempt.directive_hash },
422
- redactionSummary: preparation.redactionSummary,
423
- relativePaths: safeAttemptRelativePaths(input.attempt),
424
- childStoryIds: [],
425
- stateTransitions: ['start'],
426
- });
427
- }
428
- const driverResult = await executeRootOwnedYoloop({
429
- ...input,
430
- prepared: preparation.input,
431
- });
432
- const retry = retryDecision(input.attempt, driverResult, input.maxAttempts, input.backoffMs, input.now());
433
- const status = retry.retry ? 'backoff' : driverResult.status;
434
- const receiptStatus = retry.retry ? 'deferred' : driverResult.receiptStatus;
435
- const reasonCode = retry.retry
436
- ? (PUBLIC_TERMINAL_LOCK_RETRY_REASONS.has(driverResult.reasonCode)
437
- || RESUMABLE_YOLOOP_BOUNDARY_REASONS.has(driverResult.reasonCode)
438
- ? driverResult.reasonCode : HEADLESS_REASON_CODES.EXECUTION_BACKOFF)
439
- : driverResult.reasonCode;
440
- const publicSummary = retry.retry
441
- ? 'Headless run_yoloop execution scheduled bounded retry after transient metadata/runtime outcome.'
442
- : driverResult.publicSummary;
443
- return persistYoloopAttemptOutcome(input.store, input.attempt, {
444
- leaseId,
445
- runnerId: input.runnerId,
446
- status,
447
- receiptStatus,
448
- reasonCode,
449
- publicSummary,
450
- completedAt: input.now(),
451
- durationMs: driverResult.durationMs,
452
- notBeforeAt: retry.notBeforeAt,
453
- retryCount: retry.retryCount,
454
- counts: driverResult.counts,
455
- workerPoolSummary: driverResult.workerPoolSummary,
456
- hashes: { ...driverResult.hashes, directive: input.attempt.directive_hash },
457
- redactionSummary: driverResult.redactionSummary,
458
- relativePaths: driverResult.relativePaths,
459
- childStoryIds: driverResult.childStoryIds,
460
- runtimeId: preparation.input.runtimeId,
461
- modelId: preparation.input.modelId,
462
- runtimeSource: preparation.input.runtimeSource,
463
- stateTransitions: driverResult.stateTransitions,
464
- terminalClass: driverResult.terminalClass,
465
- releaseBlocked: driverResult.releaseBlocked,
466
- });
467
- }
468
- async function executeRootOwnedYoloop(input) {
469
- const startedAt = Date.now();
470
- const stateTransitions = ['start'];
471
- const processedStoryIds = new Set();
472
- const childStoryIds = [];
473
- const childTargetRefs = [];
474
- const hashes = { root: hashPublicValue(input.prepared.rootPrompt) };
475
- const redactions = [redaction('rootPrompt', 'prompt_body', hashes.root)];
476
- let iterations = 0;
477
- let succeededChildCount = 0;
478
- let failedChildCount = 0;
479
- let skippedChildCount = 0;
480
- let metadataCompleteCount = 0;
481
- let metadataAbortedCount = 0;
482
- let terminalP205Authority;
483
- let lifecycleEvidencePrepared = false;
484
- const workerPool = createMutableWorkerPoolSummary(input.localConcurrencyCap);
485
- const continuousInFlight = new Map();
486
- let continuousModeObserved = false;
487
- const continuousDeferredReasons = new Map();
488
- const continuousFailureReasons = new Map();
489
- const recordContinuousChild = (result) => {
490
- const child = result.child;
491
- hashes[`child-${child.storyId.replace(/[^A-Za-z0-9_.:-]/g, '-')}`] = result.commandHash;
492
- redactions.push(result.promptRedaction);
493
- const receipt = result.receipt;
494
- if (result.terminalFailure) {
495
- if (result.deferredFailure) {
496
- continuousDeferredReasons.set(child.storyId, result.terminalFailure);
497
- workerPool.backpressurePauseCount += 1;
498
- return;
499
- }
500
- continuousDeferredReasons.delete(child.storyId);
501
- continuousFailureReasons.set(child.storyId, result.terminalFailure);
502
- if (!processedStoryIds.has(child.storyId)) {
503
- processedStoryIds.add(child.storyId);
504
- childStoryIds.push(child.storyId);
505
- childTargetRefs.push(child.targetRef);
506
- failedChildCount += 1;
507
- }
508
- return;
509
- }
510
- if (!receipt || receipt.outcome === 'deferred') {
511
- continuousDeferredReasons.set(child.storyId, result.reasonCodes.includes('queue-cap-reached')
512
- ? HEADLESS_REASON_CODES.WORKER_POOL_BACKPRESSURE_PAUSED
513
- : receipt?.reasonCode || HEADLESS_REASON_CODES.EXECUTION_BACKOFF);
514
- if (result.reasonCodes.includes('queue-cap-reached'))
515
- workerPool.backpressurePauseCount += 1;
516
- return;
517
- }
518
- continuousDeferredReasons.delete(child.storyId);
519
- if (processedStoryIds.has(child.storyId))
520
- return;
521
- processedStoryIds.add(child.storyId);
522
- childStoryIds.push(child.storyId);
523
- childTargetRefs.push(child.targetRef);
524
- if (receipt.outcome === 'failed') {
525
- failedChildCount += 1;
526
- continuousFailureReasons.set(child.storyId, receipt.reasonCode || HEADLESS_REASON_CODES.EXECUTION_FAILED);
527
- }
528
- else if (receipt.outcome === 'ignored')
529
- skippedChildCount += 1;
530
- else
531
- succeededChildCount += 1;
532
- };
533
- const settleOneContinuousChild = async () => {
534
- const settled = await Promise.race([...continuousInFlight.entries()].map(([storyId, entry]) => entry.promise.then((result) => ({ storyId, result }))));
535
- continuousInFlight.delete(settled.storyId);
536
- workerPool.completedChildCount += 1;
537
- workerPool.pendingChildCount = continuousInFlight.size;
538
- recordContinuousChild(settled.result);
539
- };
540
- while (true) {
541
- if (iterations >= input.maxIterations) {
542
- stateTransitions.push('backoff');
543
- return driverResult({
544
- status: 'failed',
545
- receiptStatus: 'failed',
546
- reasonCode: MAX_ITERATIONS_REASON_CODE,
547
- publicSummary: 'Headless yoloop reached the bounded iteration limit before completion metadata.',
548
- retryable: false,
549
- startedAt,
550
- counts: aggregateCounts(iterations, childStoryIds.length, succeededChildCount, failedChildCount, skippedChildCount, metadataCompleteCount, metadataAbortedCount),
551
- workerPoolSummary: publicWorkerPoolSummary(workerPool),
552
- hashes,
553
- redactions,
554
- relativePaths: [input.prepared.targetRef, ...childTargetRefs],
555
- childStoryIds,
556
- stateTransitions,
557
- });
558
- }
559
- if (Date.now() - startedAt > input.maxDurationMs) {
560
- stateTransitions.push('backoff');
561
- return driverResult({
562
- status: 'failed',
563
- receiptStatus: 'failed',
564
- reasonCode: MAX_DURATION_REASON_CODE,
565
- publicSummary: 'Headless yoloop reached the bounded duration limit before completion metadata.',
566
- retryable: false,
567
- startedAt,
568
- counts: aggregateCounts(iterations, childStoryIds.length, succeededChildCount, failedChildCount, skippedChildCount, metadataCompleteCount, metadataAbortedCount),
569
- workerPoolSummary: publicWorkerPoolSummary(workerPool),
570
- hashes,
571
- redactions,
572
- relativePaths: [input.prepared.targetRef, ...childTargetRefs],
573
- childStoryIds,
574
- stateTransitions,
575
- });
576
- }
577
- stateTransitions.push('metadata_parse');
578
- const rootResult = await input.yoloopInvoker({
579
- projectRoot: input.projectRoot,
580
- args: input.prepared.rootPrompt,
581
- attemptId: input.attempt.attempt_id,
582
- executionId: input.attempt.execution_id,
583
- jobId: input.attempt.job_id,
584
- runnerId: input.runnerId,
585
- iteration: iterations,
586
- runtimeId: input.prepared.runtimeId,
587
- ...(input.prepared.modelId ? { modelId: input.prepared.modelId } : {}),
588
- timeoutMs: input.timeoutMs,
589
- serverUrl: input.serverUrl,
590
- });
591
- if (rootResult.durationMs !== undefined)
592
- hashes[`iter-${iterations}`] = hashPublicValue(String(rootResult.durationMs));
593
- const metadata = rootResult.metadata;
594
- const releaseBlockedTransport = rootResult.errorCode === 'YOLOOP_RELEASE_BLOCKED'
595
- || metadata?.yoloopReleaseBlocked === true
596
- || metadata?.terminalClass === 'release-blocked'
597
- || metadata?.releaseBlocked !== undefined;
598
- if (!rootResult.success && !releaseBlockedTransport) {
599
- stateTransitions.push('backoff');
600
- return driverResult({
601
- status: 'backoff',
602
- receiptStatus: 'deferred',
603
- reasonCode: HEADLESS_REASON_CODES.EXECUTION_FAILED,
604
- publicSummary: 'Headless yoloop root metadata invocation failed with bounded public evidence.',
605
- retryable: true,
606
- startedAt,
607
- counts: aggregateCounts(iterations, childStoryIds.length, succeededChildCount, failedChildCount, skippedChildCount, metadataCompleteCount, metadataAbortedCount),
608
- workerPoolSummary: publicWorkerPoolSummary(workerPool),
609
- hashes,
610
- redactions,
611
- relativePaths: [input.prepared.targetRef, ...childTargetRefs],
612
- childStoryIds,
613
- stateTransitions,
614
- });
615
- }
616
- const terminal = classifyYoloopTerminalMetadata(metadata);
617
- if (!terminal.ok) {
618
- stateTransitions.push('backoff');
619
- return driverResult({
620
- status: 'failed',
621
- receiptStatus: 'failed',
622
- reasonCode: terminal.reasonCode,
623
- publicSummary: terminal.publicSummary,
624
- retryable: false,
625
- startedAt,
626
- counts: aggregateCounts(iterations, childStoryIds.length, succeededChildCount, failedChildCount, skippedChildCount, metadataCompleteCount, metadataAbortedCount),
627
- workerPoolSummary: publicWorkerPoolSummary(workerPool),
628
- hashes,
629
- redactions: [...redactions, ...terminal.redactionSummary],
630
- relativePaths: [input.prepared.targetRef, ...childTargetRefs],
631
- childStoryIds,
632
- stateTransitions,
633
- });
634
- }
635
- const resumableBoundary = extractResumableExhaustionBoundary(metadata);
636
- if (terminal.aborted && resumableBoundary) {
637
- while (continuousInFlight.size > 0)
638
- await settleOneContinuousChild();
639
- metadataAbortedCount += 1;
640
- stateTransitions.push('backoff');
641
- return driverResult({
642
- status: 'backoff',
643
- receiptStatus: 'deferred',
644
- reasonCode: resumableBoundary.reason === 'YOLOOP_SESSION_TIMEOUT'
645
- ? 'yoloop-session-timeout-resumable'
646
- : 'yoloop-per-run-cap-resumable',
647
- publicSummary: 'Headless yoloop reached a finite run boundary and scheduled the same queue after cool-down.',
648
- retryable: true,
649
- retryNotBeforeAt: resumableBoundary.coolDownUntil,
650
- startedAt,
651
- counts: aggregateCounts(iterations + 1, childStoryIds.length, succeededChildCount, failedChildCount, skippedChildCount, metadataCompleteCount, metadataAbortedCount),
652
- workerPoolSummary: publicWorkerPoolSummary(workerPool),
653
- hashes,
654
- redactions,
655
- relativePaths: [input.prepared.targetRef, ...childTargetRefs],
656
- childStoryIds,
657
- stateTransitions,
658
- });
659
- }
660
- if ((terminal.releaseBlocked || terminal.aborted || terminal.complete || terminal.replay || (terminal.outcome && terminal.outcome !== 'selected' && terminal.outcome !== 'queue_exhausted'))
661
- && continuousModeObserved && continuousInFlight.size > 0) {
662
- await settleOneContinuousChild();
663
- iterations += 1;
664
- stateTransitions.push('reinvoke');
665
- continue;
666
- }
667
- if (terminal.releaseBlocked) {
668
- stateTransitions.push('release_blocked');
669
- return driverResult({
670
- status: 'failed',
671
- receiptStatus: 'failed',
672
- reasonCode: 'yoloop-release-blocked',
673
- publicSummary: 'Headless yoloop stopped at a terminal release-blocked boundary without declaring success.',
674
- retryable: false,
675
- startedAt,
676
- counts: aggregateCounts(iterations + 1, childStoryIds.length, succeededChildCount, failedChildCount, skippedChildCount, metadataCompleteCount, metadataAbortedCount),
677
- workerPoolSummary: publicWorkerPoolSummary(workerPool),
678
- hashes: { ...hashes, releaseBlocked: hashPublicValue(terminal.releaseBlocked.resultId) },
679
- redactions,
680
- relativePaths: [input.prepared.targetRef, ...childTargetRefs],
681
- childStoryIds,
682
- stateTransitions,
683
- terminalClass: 'release-blocked',
684
- releaseBlocked: terminal.releaseBlocked,
685
- });
686
- }
687
- const epicIntegration = isRecord(metadata?.epicIntegration) ? metadata.epicIntegration : undefined;
688
- const integrationReasonCodes = Array.isArray(epicIntegration?.reasonCodes)
689
- ? epicIntegration.reasonCodes.filter((value) => typeof value === 'string')
690
- : [];
691
- const lifecycleEvidenceCanRepair = terminal.aborted
692
- && metadata?.abortReason === 'epic-integration-checkpoints-incomplete'
693
- && epicIntegration?.required === true
694
- && epicIntegration.ready === false
695
- && integrationReasonCodes.length > 0
696
- && integrationReasonCodes.every((reasonCode) => reasonCode === 'epic-aggregate-qa-receipt-required'
697
- || reasonCode === 'epic-origin-binding-required');
698
- // P223 release admission has already completed for this root invocation.
699
- // Only now may the client produce the physical aggregate/origin evidence
700
- // needed for the server to emit the terminal Git directive. This avoids a
701
- // release-blocked request causing Git effects while preserving the
702
- // pre-P223 terminal-integration convergence path.
703
- if (lifecycleEvidenceCanRepair && input.terminalGitAdapter.prepareLifecycleEvidence) {
704
- stateTransitions.push('lifecycle_evidence');
705
- const evidence = await input.terminalGitAdapter.prepareLifecycleEvidence({
706
- epicId: input.prepared.epicId,
707
- nowIso: input.now(),
708
- });
709
- if (!evidence.ok) {
710
- stateTransitions.push('backoff');
711
- return driverResult({
712
- status: evidence.retryEligible ? 'backoff' : 'failed',
713
- receiptStatus: evidence.retryEligible ? 'deferred' : 'failed',
714
- reasonCode: evidence.reasonCode,
715
- publicSummary: 'Headless yoloop stopped because physical Git lifecycle evidence could not be produced safely.',
716
- retryable: evidence.retryEligible,
717
- startedAt,
718
- counts: aggregateCounts(iterations + 1, childStoryIds.length, succeededChildCount, failedChildCount, skippedChildCount, metadataCompleteCount, metadataAbortedCount),
719
- workerPoolSummary: publicWorkerPoolSummary(workerPool),
720
- hashes,
721
- redactions,
722
- relativePaths: [input.prepared.targetRef, ...childTargetRefs],
723
- childStoryIds,
724
- stateTransitions,
725
- });
726
- }
727
- terminalP205Authority = evidence.p205Authority;
728
- lifecycleEvidencePrepared = true;
729
- iterations += 1;
730
- stateTransitions.push('reinvoke');
731
- continue;
732
- }
733
- if (terminal.aborted) {
734
- metadataAbortedCount += 1;
735
- stateTransitions.push('aborted');
736
- return driverResult({
737
- status: 'failed',
738
- receiptStatus: 'failed',
739
- reasonCode: JOB_ABORTED_REASON_CODE,
740
- publicSummary: 'Headless yoloop stopped because public metadata reported an aborted loop.',
741
- retryable: false,
742
- startedAt,
743
- counts: aggregateCounts(iterations + 1, childStoryIds.length, succeededChildCount, failedChildCount, skippedChildCount, metadataCompleteCount, metadataAbortedCount),
744
- workerPoolSummary: publicWorkerPoolSummary(workerPool),
745
- hashes,
746
- redactions,
747
- relativePaths: [input.prepared.targetRef, ...childTargetRefs],
748
- childStoryIds,
749
- stateTransitions,
750
- });
751
- }
752
- if (terminal.outcome && terminal.outcome !== 'selected' && terminal.outcome !== 'queue_exhausted') {
753
- stateTransitions.push('backoff');
754
- return driverResult({
755
- status: 'failed', receiptStatus: 'failed', reasonCode: `yoloop-${terminal.outcome}`,
756
- publicSummary: 'Headless yoloop stopped on a non-executable graph-first continuation outcome.',
757
- retryable: false, startedAt,
758
- counts: aggregateCounts(iterations + 1, childStoryIds.length, succeededChildCount, failedChildCount, skippedChildCount, metadataCompleteCount, metadataAbortedCount),
759
- workerPoolSummary: publicWorkerPoolSummary(workerPool), hashes, redactions,
760
- relativePaths: [input.prepared.targetRef, ...childTargetRefs], childStoryIds, stateTransitions,
761
- });
762
- }
763
- if (terminal.replay) {
764
- stateTransitions.push('backoff');
765
- return driverResult({
766
- status: 'backoff', receiptStatus: 'deferred', reasonCode: 'yoloop-replay-pending',
767
- publicSummary: 'Headless yoloop observed pending replay authority and did not delegate a second child.',
768
- retryable: true, startedAt,
769
- counts: aggregateCounts(iterations + 1, childStoryIds.length, succeededChildCount, failedChildCount, skippedChildCount, metadataCompleteCount, metadataAbortedCount),
770
- workerPoolSummary: publicWorkerPoolSummary(workerPool), hashes, redactions,
771
- relativePaths: [input.prepared.targetRef, ...childTargetRefs], childStoryIds, stateTransitions,
772
- });
773
- }
774
- if (terminal.complete && continuousModeObserved
775
- && continuousDeferredReasons.size > 0 && continuousFailureReasons.size === 0) {
776
- stateTransitions.push('backoff');
777
- return driverResult({
778
- status: 'backoff', receiptStatus: 'deferred',
779
- reasonCode: [...continuousDeferredReasons.values()].sort()[0],
780
- publicSummary: 'Headless yoloop rejected terminal completion while previously runnable work remained undispatched.',
781
- retryable: true, startedAt,
782
- counts: aggregateCounts(iterations + 1, childStoryIds.length, succeededChildCount, failedChildCount, skippedChildCount, metadataCompleteCount, metadataAbortedCount),
783
- workerPoolSummary: publicWorkerPoolSummary(workerPool), hashes, redactions,
784
- relativePaths: [input.prepared.targetRef, ...childTargetRefs], childStoryIds, stateTransitions,
785
- });
786
- }
787
- if (terminal.complete && continuousModeObserved && continuousFailureReasons.size > 0) {
788
- stateTransitions.push('backoff');
789
- return driverResult({
790
- status: 'failed', receiptStatus: 'failed',
791
- reasonCode: [...continuousFailureReasons.values()].sort()[0],
792
- publicSummary: 'Headless yoloop rejected terminal completion because runnable work failed before an accepted dispatch receipt.',
793
- retryable: false, startedAt,
794
- counts: aggregateCounts(iterations + 1, childStoryIds.length, succeededChildCount, failedChildCount, skippedChildCount, metadataCompleteCount, metadataAbortedCount),
795
- workerPoolSummary: publicWorkerPoolSummary(workerPool), hashes, redactions,
796
- relativePaths: [input.prepared.targetRef, ...childTargetRefs], childStoryIds, stateTransitions,
797
- });
798
- }
799
- // A terminal response can truthfully report queue exhaustion while also
800
- // carrying the still-required physical Git integration directive. The
801
- // effect must run before accepting yoloopComplete; the persisted receipt
802
- // makes the next invocation converge to terminal success.
803
- const terminalGitDirective = extractEpicTerminalGitDirective(metadata);
804
- if (terminalGitDirective) {
805
- if (!lifecycleEvidencePrepared && input.terminalGitAdapter.prepareLifecycleEvidence) {
806
- stateTransitions.push('lifecycle_evidence');
807
- const evidence = await input.terminalGitAdapter.prepareLifecycleEvidence({
808
- epicId: input.prepared.epicId,
809
- nowIso: input.now(),
810
- });
811
- if (!evidence.ok) {
812
- stateTransitions.push('backoff');
813
- return driverResult({
814
- status: evidence.retryEligible ? 'backoff' : 'failed',
815
- receiptStatus: evidence.retryEligible ? 'deferred' : 'failed',
816
- reasonCode: evidence.reasonCode,
817
- publicSummary: 'Headless yoloop stopped because physical Git lifecycle evidence could not be produced safely.',
818
- retryable: evidence.retryEligible,
819
- startedAt,
820
- counts: aggregateCounts(iterations, childStoryIds.length, succeededChildCount, failedChildCount, skippedChildCount, metadataCompleteCount, metadataAbortedCount),
821
- workerPoolSummary: publicWorkerPoolSummary(workerPool),
822
- hashes,
823
- redactions,
824
- relativePaths: [input.prepared.targetRef, ...childTargetRefs],
825
- childStoryIds,
826
- stateTransitions,
827
- });
828
- }
829
- terminalP205Authority = evidence.p205Authority;
830
- lifecycleEvidencePrepared = true;
831
- }
832
- stateTransitions.push('terminal_git');
833
- const lockStartedAt = new Date();
834
- const physicalLock = await acquireGitLifecyclePhysicalIntegrationLock(input.projectRoot, {
835
- kind: 'continuous', storyId: terminalGitDirective.epicId,
836
- sessionId: `${input.runnerId}:${input.attempt.attempt_id}`,
837
- idempotencyKey: terminalGitDirective.idempotencyKey,
838
- persistent: false,
839
- expiresAt: new Date(lockStartedAt.getTime() + Math.max(input.timeoutMs, input.maxDurationMs) + 60_000).toISOString(),
840
- });
841
- if (!physicalLock.ok) {
842
- stateTransitions.push('backoff');
843
- return driverResult({
844
- status: 'backoff', receiptStatus: 'deferred', reasonCode: physicalLock.reasonCode,
845
- publicSummary: 'Headless yoloop deferred terminal Git while another physical writer retained authority.',
846
- retryable: true, startedAt,
847
- counts: aggregateCounts(iterations + 1, childStoryIds.length, succeededChildCount, failedChildCount, skippedChildCount, metadataCompleteCount, metadataAbortedCount),
848
- workerPoolSummary: publicWorkerPoolSummary(workerPool), hashes, redactions,
849
- relativePaths: [input.prepared.targetRef, ...childTargetRefs], childStoryIds, stateTransitions,
850
- });
851
- }
852
- let integration;
853
- let released = false;
854
- try {
855
- integration = await executeEpicTerminalGit(terminalGitDirective, input.terminalGitAdapter, input.now, terminalP205Authority);
856
- }
857
- finally {
858
- released = await releaseGitLifecyclePhysicalIntegrationLock(physicalLock.path, physicalLock.owner)
859
- .catch(() => false);
860
- }
861
- if (!released) {
862
- stateTransitions.push('backoff');
863
- return driverResult({
864
- status: 'backoff', receiptStatus: 'deferred', reasonCode: 'git-lifecycle-integration-lock-release-failed',
865
- publicSummary: 'Headless yoloop stopped because terminal Git writer ownership could not be released safely.',
866
- retryable: true, startedAt,
867
- counts: aggregateCounts(iterations + 1, childStoryIds.length, succeededChildCount, failedChildCount, skippedChildCount, metadataCompleteCount, metadataAbortedCount),
868
- workerPoolSummary: publicWorkerPoolSummary(workerPool), hashes, redactions,
869
- relativePaths: [input.prepared.targetRef, ...childTargetRefs], childStoryIds, stateTransitions,
870
- });
871
- }
872
- hashes[`terminal-git-${iterations}`] = hashPublicValue(`${integration.receipt.idempotencyKey}:${integration.receipt.physicalStatus}`);
873
- if (!integration.ok) {
874
- const retryable = integration.receipt.retryEligible;
875
- stateTransitions.push('backoff');
876
- return driverResult({
877
- status: retryable ? 'backoff' : 'failed',
878
- receiptStatus: retryable ? 'deferred' : 'failed',
879
- reasonCode: integration.reasonCodes[0] ?? 'epic-terminal-git-failed',
880
- publicSummary: 'Headless yoloop stopped at the epic terminal Git boundary with public-safe retry evidence.',
881
- retryable,
882
- startedAt,
883
- counts: aggregateCounts(iterations + 1, childStoryIds.length, succeededChildCount, failedChildCount, skippedChildCount, metadataCompleteCount, metadataAbortedCount),
884
- workerPoolSummary: publicWorkerPoolSummary(workerPool), hashes, redactions,
885
- relativePaths: [input.prepared.targetRef, ...childTargetRefs], childStoryIds, stateTransitions,
886
- });
887
- }
888
- // A persisted pushed receipt may let the server render queue exhaustion,
889
- // but it never lets the root accept completion without this invocation's
890
- // fresh physical ancestry/provider verification. The same directive is
891
- // therefore emitted on replay and this successful verification is the
892
- // terminal authority for the current root run.
893
- if (terminal.complete) {
894
- metadataCompleteCount += 1;
895
- stateTransitions.push('complete');
896
- return driverResult({
897
- status: 'completed', receiptStatus: 'applied',
898
- reasonCode: HEADLESS_REASON_CODES.EXECUTION_COMPLETED,
899
- publicSummary: 'Headless yoloop completed only after fresh root-owned physical Git verification.',
900
- retryable: false, startedAt,
901
- counts: aggregateCounts(iterations + 1, childStoryIds.length, succeededChildCount, failedChildCount, skippedChildCount, metadataCompleteCount, metadataAbortedCount),
902
- workerPoolSummary: publicWorkerPoolSummary(workerPool), hashes, redactions,
903
- relativePaths: [input.prepared.targetRef, ...childTargetRefs], childStoryIds, stateTransitions,
904
- });
905
- }
906
- iterations += 1;
907
- stateTransitions.push('reinvoke');
908
- continue;
909
- }
910
- if (terminal.complete) {
911
- metadataCompleteCount += 1;
912
- stateTransitions.push('complete');
913
- return driverResult({
914
- status: 'completed',
915
- receiptStatus: 'applied',
916
- reasonCode: HEADLESS_REASON_CODES.EXECUTION_COMPLETED,
917
- publicSummary: 'Headless yoloop completed after public metadata reported yoloopComplete.',
918
- retryable: false,
919
- startedAt,
920
- counts: aggregateCounts(iterations + 1, childStoryIds.length, succeededChildCount, failedChildCount, skippedChildCount, metadataCompleteCount, metadataAbortedCount),
921
- workerPoolSummary: publicWorkerPoolSummary(workerPool),
922
- hashes,
923
- redactions,
924
- relativePaths: [input.prepared.targetRef, ...childTargetRefs],
925
- childStoryIds,
926
- stateTransitions,
927
- });
928
- }
929
- const reconciliationDirective = extractEpicGitReconciliationDirective(metadata);
930
- if (reconciliationDirective) {
931
- stateTransitions.push('git_reconciliation');
932
- const reconciliation = await executeEpicGitReconciliation(reconciliationDirective, input.terminalGitAdapter, input.now);
933
- hashes[`git-reconciliation-${iterations}`] = hashPublicValue(`${reconciliationDirective.idempotencyKey}:${reconciliation.reasonCodes.join(',')}`);
934
- if (!reconciliation.ok) {
935
- stateTransitions.push('backoff');
936
- return driverResult({
937
- status: 'backoff', receiptStatus: 'deferred',
938
- reasonCode: reconciliation.reasonCodes[0] ?? 'git-reconciliation-failed',
939
- publicSummary: 'Headless yoloop paused at a fail-closed Git reconciliation boundary.',
940
- retryable: true, startedAt,
941
- counts: aggregateCounts(iterations + 1, childStoryIds.length, succeededChildCount, failedChildCount, skippedChildCount, metadataCompleteCount, metadataAbortedCount),
942
- workerPoolSummary: publicWorkerPoolSummary(workerPool), hashes, redactions,
943
- relativePaths: [input.prepared.targetRef, ...childTargetRefs], childStoryIds, stateTransitions,
944
- });
945
- }
946
- }
947
- const extraction = extractAuthorizedChildPrompts(metadata, input.prepared.epicId);
948
- if (!extraction.ok) {
949
- stateTransitions.push('backoff');
950
- return driverResult({
951
- status: 'failed',
952
- receiptStatus: 'failed',
953
- reasonCode: extraction.reasonCode,
954
- publicSummary: extraction.publicSummary,
955
- retryable: false,
956
- startedAt,
957
- counts: aggregateCounts(iterations + 1, childStoryIds.length, succeededChildCount, failedChildCount, skippedChildCount, metadataCompleteCount, metadataAbortedCount),
958
- workerPoolSummary: publicWorkerPoolSummary(workerPool),
959
- hashes,
960
- redactions: [...redactions, ...extraction.redactionSummary],
961
- relativePaths: [input.prepared.targetRef, ...childTargetRefs],
962
- childStoryIds,
963
- stateTransitions,
964
- });
965
- }
966
- const repeatedChild = extraction.continuous
967
- ? undefined
968
- : extraction.prompts.find((child) => processedStoryIds.has(child.storyId));
969
- if (repeatedChild) {
970
- stateTransitions.push('backoff');
971
- return driverResult({
972
- status: 'failed',
973
- receiptStatus: 'failed',
974
- reasonCode: HEADLESS_REASON_CODES.YOLOOP_ISOLATION_VIOLATION,
975
- publicSummary: 'Headless yoloop rejected cyclic child story delegation evidence.',
976
- retryable: false,
977
- startedAt,
978
- counts: aggregateCounts(iterations + 1, childStoryIds.length, succeededChildCount, failedChildCount, skippedChildCount, metadataCompleteCount, metadataAbortedCount),
979
- workerPoolSummary: publicWorkerPoolSummary(workerPool),
980
- hashes,
981
- redactions: [...redactions, redaction('storyId', 'prompt_body', hashPublicValue(repeatedChild.storyId))],
982
- relativePaths: [input.prepared.targetRef, ...childTargetRefs],
983
- childStoryIds,
984
- stateTransitions,
985
- });
986
- }
987
- workerPool.mode = extraction.mode === 'continuous_dag'
988
- ? 'continuous_dag'
989
- : extraction.parallelAuthorized ? 'parallel_wave' : 'serial';
990
- workerPool.serverMaxConcurrency = extraction.serverMaxConcurrency;
991
- if (extraction.continuous) {
992
- continuousModeObserved = true;
993
- const eligible = extraction.prompts.filter((child) => !processedStoryIds.has(child.storyId) && !continuousInFlight.has(child.storyId));
994
- workerPool.pendingChildCount = eligible.length + continuousInFlight.size;
995
- if (eligible.length > 0) {
996
- const capacity = resolveWorkerPoolCapacity({
997
- store: input.store,
998
- nowIso: input.now(),
999
- localCap: input.localConcurrencyCap,
1000
- serverMaxConcurrency: extraction.serverMaxConcurrency,
1001
- parallelAuthorized: true,
1002
- continuous: true,
1003
- eligibleCount: eligible.length,
1004
- });
1005
- workerPool.queueCap = capacity.queueCap;
1006
- workerPool.availableLeases = capacity.availableLeases;
1007
- workerPool.effectiveConcurrency = capacity.effectiveConcurrency;
1008
- workerPool.reasonCodes.push(capacity.reasonCode);
1009
- if (capacity.effectiveConcurrency === 0 && continuousInFlight.size === 0) {
1010
- workerPool.backpressurePauseCount += 1;
1011
- stateTransitions.push('backoff');
1012
- return driverResult({
1013
- status: 'backoff', receiptStatus: 'deferred', reasonCode: HEADLESS_REASON_CODES.WORKER_POOL_BACKPRESSURE_PAUSED,
1014
- publicSummary: 'Headless yoloop retained its eligible frontier while physical worker capacity was unavailable.',
1015
- retryable: true, startedAt,
1016
- counts: aggregateCounts(iterations + 1, childStoryIds.length, succeededChildCount, failedChildCount, skippedChildCount, metadataCompleteCount, metadataAbortedCount),
1017
- workerPoolSummary: publicWorkerPoolSummary(workerPool), hashes, redactions,
1018
- relativePaths: [input.prepared.targetRef, ...childTargetRefs], childStoryIds, stateTransitions,
1019
- });
1020
- }
1021
- const launchable = eligible.slice(0, capacity.effectiveConcurrency);
1022
- stateTransitions.push('child_story_delegation');
1023
- for (const child of launchable) {
1024
- continuousInFlight.set(child.storyId, {
1025
- child,
1026
- promise: executeYoloopChild({ ...input, child, iteration: iterations }),
1027
- });
1028
- }
1029
- workerPool.startedChildCount += launchable.length;
1030
- workerPool.peakConcurrency = Math.max(workerPool.peakConcurrency, continuousInFlight.size);
1031
- workerPool.pendingChildCount = eligible.length - launchable.length + continuousInFlight.size;
1032
- }
1033
- if (continuousInFlight.size > 0) {
1034
- await settleOneContinuousChild();
1035
- }
1036
- else if (continuousDeferredReasons.size > 0) {
1037
- stateTransitions.push('backoff');
1038
- return driverResult({
1039
- status: 'backoff', receiptStatus: 'deferred', reasonCode: [...continuousDeferredReasons.values()].sort()[0],
1040
- publicSummary: 'Headless yoloop retained deferred continuous work for a bounded retry.',
1041
- retryable: true, startedAt,
1042
- counts: aggregateCounts(iterations + 1, childStoryIds.length, succeededChildCount, failedChildCount, skippedChildCount, metadataCompleteCount, metadataAbortedCount),
1043
- workerPoolSummary: publicWorkerPoolSummary(workerPool), hashes, redactions,
1044
- relativePaths: [input.prepared.targetRef, ...childTargetRefs], childStoryIds, stateTransitions,
1045
- });
1046
- }
1047
- else if (continuousFailureReasons.size > 0) {
1048
- stateTransitions.push('backoff');
1049
- return driverResult({
1050
- status: 'failed', receiptStatus: 'failed', reasonCode: [...continuousFailureReasons.values()].sort()[0],
1051
- publicSummary: 'Headless yoloop completed independent work and stopped on the remaining failed dependency closure.',
1052
- retryable: false, startedAt,
1053
- counts: aggregateCounts(iterations + 1, childStoryIds.length, succeededChildCount, failedChildCount, skippedChildCount, metadataCompleteCount, metadataAbortedCount),
1054
- workerPoolSummary: publicWorkerPoolSummary(workerPool), hashes, redactions,
1055
- relativePaths: [input.prepared.targetRef, ...childTargetRefs], childStoryIds, stateTransitions,
1056
- });
1057
- }
1058
- iterations += 1;
1059
- stateTransitions.push('reinvoke');
1060
- continue;
1061
- }
1062
- workerPool.pendingChildCount = extraction.prompts.length;
1063
- const pending = [...extraction.prompts];
1064
- while (pending.length > 0) {
1065
- const capacity = resolveWorkerPoolCapacity({
1066
- store: input.store,
1067
- nowIso: input.now(),
1068
- localCap: input.localConcurrencyCap,
1069
- serverMaxConcurrency: extraction.serverMaxConcurrency,
1070
- parallelAuthorized: extraction.parallelAuthorized,
1071
- continuous: false,
1072
- eligibleCount: pending.length,
1073
- });
1074
- workerPool.queueCap = capacity.queueCap;
1075
- workerPool.availableLeases = capacity.availableLeases;
1076
- workerPool.effectiveConcurrency = capacity.effectiveConcurrency;
1077
- workerPool.reasonCodes.push(capacity.reasonCode);
1078
- if (capacity.effectiveConcurrency === 0) {
1079
- workerPool.backpressurePauseCount += 1;
1080
- workerPool.pendingChildCount = pending.length;
1081
- stateTransitions.push('backoff');
1082
- return driverResult({
1083
- status: 'backoff',
1084
- receiptStatus: 'deferred',
1085
- reasonCode: HEADLESS_REASON_CODES.WORKER_POOL_BACKPRESSURE_PAUSED,
1086
- publicSummary: 'Headless yoloop paused child workers because bounded queue or lease capacity was unavailable.',
1087
- retryable: true,
1088
- startedAt,
1089
- counts: aggregateCounts(iterations + 1, childStoryIds.length, succeededChildCount, failedChildCount, skippedChildCount, metadataCompleteCount, metadataAbortedCount),
1090
- workerPoolSummary: publicWorkerPoolSummary(workerPool),
1091
- hashes,
1092
- redactions,
1093
- relativePaths: [input.prepared.targetRef, ...childTargetRefs],
1094
- childStoryIds,
1095
- stateTransitions,
1096
- });
1097
- }
1098
- const batch = pending.splice(0, capacity.effectiveConcurrency);
1099
- workerPool.startedChildCount += batch.length;
1100
- workerPool.peakConcurrency = Math.max(workerPool.peakConcurrency, batch.length);
1101
- workerPool.pendingChildCount = pending.length;
1102
- stateTransitions.push('child_story_delegation');
1103
- const settled = await Promise.all(batch.map((child) => executeYoloopChild({
1104
- ...input,
1105
- child,
1106
- iteration: iterations,
1107
- })));
1108
- workerPool.completedChildCount += settled.length;
1109
- let terminalChild;
1110
- for (const result of settled) {
1111
- const child = result.child;
1112
- hashes[`child-${child.storyId.replace(/[^A-Za-z0-9_.:-]/g, '-')}`] = result.commandHash;
1113
- redactions.push(result.promptRedaction);
1114
- childStoryIds.push(child.storyId);
1115
- childTargetRefs.push(child.targetRef);
1116
- processedStoryIds.add(child.storyId);
1117
- const receipt = result.receipt;
1118
- if (!receipt) {
1119
- if (result.reasonCodes.includes('queue-cap-reached')) {
1120
- workerPool.backpressurePauseCount += 1;
1121
- workerPool.pendingChildCount += 1;
1122
- workerPool.reasonCodes.push(HEADLESS_REASON_CODES.WORKER_POOL_BACKPRESSURE_PAUSED);
1123
- terminalChild ??= { kind: 'deferred', reasonCode: HEADLESS_REASON_CODES.WORKER_POOL_BACKPRESSURE_PAUSED };
1124
- }
1125
- else {
1126
- failedChildCount += 1;
1127
- terminalChild ??= { kind: 'missing', reasonCode: HEADLESS_REASON_CODES.EXECUTION_FAILED };
1128
- }
1129
- continue;
1130
- }
1131
- if (receipt.outcome === 'deferred') {
1132
- terminalChild ??= { kind: 'deferred', reasonCode: HEADLESS_REASON_CODES.EXECUTION_BACKOFF };
1133
- continue;
1134
- }
1135
- if (receipt.outcome === 'failed') {
1136
- failedChildCount += 1;
1137
- terminalChild ??= { kind: 'failed', reasonCode: receipt.reasonCode || HEADLESS_REASON_CODES.EXECUTION_FAILED };
1138
- continue;
1139
- }
1140
- if (receipt.outcome === 'ignored')
1141
- skippedChildCount += 1;
1142
- else
1143
- succeededChildCount += 1;
1144
- }
1145
- if (terminalChild) {
1146
- const deferred = terminalChild.kind === 'deferred';
1147
- return driverResult({
1148
- status: deferred ? 'backoff' : 'failed',
1149
- receiptStatus: deferred ? 'deferred' : 'failed',
1150
- reasonCode: terminalChild.reasonCode,
1151
- publicSummary: terminalChild.kind === 'missing'
1152
- ? 'Headless yoloop child story delegation did not produce a public receipt.'
1153
- : deferred
1154
- ? 'Headless yoloop child story delegated bounded backoff to the root attempt.'
1155
- : 'Headless yoloop child story execution failed with public receipt evidence.',
1156
- retryable: deferred,
1157
- startedAt,
1158
- counts: aggregateCounts(iterations + 1, childStoryIds.length, succeededChildCount, failedChildCount, skippedChildCount, metadataCompleteCount, metadataAbortedCount),
1159
- workerPoolSummary: publicWorkerPoolSummary(workerPool),
1160
- hashes,
1161
- redactions,
1162
- relativePaths: [input.prepared.targetRef, ...childTargetRefs],
1163
- childStoryIds,
1164
- stateTransitions,
1165
- });
1166
- }
1167
- }
1168
- iterations += 1;
1169
- stateTransitions.push('reinvoke');
1170
- }
1171
- }
1172
- async function executeYoloopChild(input) {
1173
- const workspace = input.child.dispatchId
1174
- ? await input.continuousWorkspaceManager.prepare({
1175
- projectRoot: input.projectRoot,
1176
- epicId: input.prepared.epicId,
1177
- storyId: input.child.storyId,
1178
- targetRef: input.child.targetRef,
1179
- dispatchId: input.child.dispatchId,
1180
- executionBranch: input.child.executionBranch ?? '',
1181
- graphRevision: input.child.graphRevision ?? '',
1182
- authorizedWriteSet: input.child.writeSet ?? [],
1183
- })
1184
- : undefined;
1185
- if (workspace && !workspace.ok) {
1186
- return {
1187
- child: input.child,
1188
- reasonCodes: [workspace.reasonCode],
1189
- commandHash: hashPublicValue(input.child.commandRef),
1190
- promptRedaction: redaction(`child.${input.child.storyId}`, 'prompt_body', hashPublicValue(input.child.commandRef)),
1191
- terminalFailure: workspace.reasonCode,
1192
- deferredFailure: /backpressure|lease-active/.test(workspace.reasonCode),
1193
- };
1194
- }
1195
- const childProjectRoot = input.projectRoot;
1196
- const childCommandRunner = workspace?.ok
1197
- ? createAnchoredContinuousStoryCommandRunner(workspace.value)
1198
- : input.adapterOptions?.commandRunner;
1199
- const childDirective = buildChildRunYoloDirective({
1200
- rootAttempt: input.attempt,
1201
- child: input.child,
1202
- iteration: input.iteration,
1203
- runtimeId: input.prepared.runtimeId,
1204
- modelId: input.prepared.modelId,
1205
- runtimeSource: input.prepared.runtimeSource,
1206
- });
1207
- const childAttemptId = headlessExecutionEntityId('attempt', childDirective.idempotencyKey);
1208
- let preserveWorkspace = Boolean(workspace);
1209
- try {
1210
- const childResult = await runYoloExecutionPhase({
1211
- store: input.store,
1212
- projectRoot: childProjectRoot,
1213
- runnerId: input.runnerId,
1214
- now: input.now,
1215
- metadata: { continuityExecutionDirectives: [childDirective] },
1216
- adapterRegistry: input.registry,
1217
- adapterOptions: {
1218
- ...input.adapterOptions,
1219
- cwd: childProjectRoot,
1220
- env: {
1221
- ...input.adapterOptions?.env,
1222
- ...(workspace?.ok ? {
1223
- NEOCORTEX_BRANCHLESS_PROJECT_ROOT: workspace.value.workspacePath,
1224
- NEOCORTEX_BRANCHLESS_ROOT_AUTHORITY: JSON.stringify(input.child.rootAuthority),
1225
- } : {}),
1226
- },
1227
- ...(childCommandRunner ? { commandRunner: childCommandRunner, versionRunner: childCommandRunner } : {}),
1228
- },
1229
- runtimeDefaults: input.runtimeDefaults,
1230
- runtimeFallback: input.runtimeFallback,
1231
- timeoutMs: input.timeoutMs,
1232
- maxAttempts: 1,
1233
- limit: 1,
1234
- queueCap: input.queueCap,
1235
- attemptIds: [childAttemptId],
1236
- idFactory: input.idFactory,
1237
- });
1238
- const receipt = childResult.receipts.find((item) => item.attemptId === childAttemptId) ?? childResult.receipts[0];
1239
- if (workspace?.ok && receipt && receipt.outcome !== 'failed' && receipt.outcome !== 'deferred') {
1240
- const integration = await input.continuousWorkspaceManager.integrate(workspace.value, {
1241
- receiptRefs: [`continuity:${receipt.attemptId}`],
1242
- nowIso: receipt.timestamp,
1243
- });
1244
- if (!integration.ok) {
1245
- return {
1246
- child: input.child,
1247
- receipt,
1248
- reasonCodes: [...childResult.reasonCodes, integration.reasonCode],
1249
- commandHash: hashPublicValue(input.child.commandRef),
1250
- promptRedaction: redaction(`child.${input.child.storyId}`, 'prompt_body', hashPublicValue(input.child.commandRef)),
1251
- terminalFailure: integration.reasonCode,
1252
- deferredFailure: /backpressure|graph-revision-stale/.test(integration.reasonCode),
1253
- };
1254
- }
1255
- preserveWorkspace = false;
1256
- }
1257
- return {
1258
- child: input.child,
1259
- receipt,
1260
- reasonCodes: childResult.reasonCodes,
1261
- commandHash: hashPublicValue(input.child.commandRef),
1262
- promptRedaction: redaction(`child.${input.child.storyId}`, 'prompt_body', hashPublicValue(input.child.commandRef)),
1263
- };
1264
- }
1265
- finally {
1266
- if (workspace?.ok)
1267
- await input.continuousWorkspaceManager.release(workspace.value, preserveWorkspace);
1268
- }
1269
- }
1270
- function resolveWorkerPoolCapacity(input) {
1271
- const snapshot = input.store.collectSnapshotRows({
1272
- nowIso: input.nowIso,
1273
- jobLimit: 1,
1274
- staleLeaseLimit: 1,
1275
- receiptLimit: 1,
1276
- eventLimit: 1,
1277
- snapshotLimit: 1,
1278
- });
1279
- const queueCap = Math.max(1, Math.floor(snapshot.queue.capacity));
1280
- // The current run_yoloop parent owns one active queue lease. Only other active
1281
- // headless workers reduce the local child-lease budget.
1282
- const activeOtherLeases = Math.max(0, Math.floor(snapshot.queue.running) - 1);
1283
- const availableLeases = input.continuous
1284
- ? Math.max(0, Math.floor(snapshot.queue.available))
1285
- : Math.max(0, Math.min(Math.max(0, input.localCap - activeOtherLeases), Math.floor(snapshot.queue.available)));
1286
- const serverMaxConcurrency = input.parallelAuthorized
1287
- ? Math.max(1, Math.floor(input.serverMaxConcurrency))
1288
- : 1;
1289
- const effectiveConcurrency = Math.max(0, Math.min(input.eligibleCount, serverMaxConcurrency, input.localCap, queueCap, availableLeases));
1290
- return {
1291
- queueCap,
1292
- availableLeases,
1293
- effectiveConcurrency,
1294
- reasonCode: effectiveConcurrency === 0
1295
- ? HEADLESS_REASON_CODES.WORKER_POOL_BACKPRESSURE_PAUSED
1296
- : (input.parallelAuthorized || input.continuous) && effectiveConcurrency > 1
1297
- ? HEADLESS_REASON_CODES.WORKER_POOL_PARALLEL_ACTIVE
1298
- : HEADLESS_REASON_CODES.WORKER_POOL_SERIAL_FALLBACK,
1299
- };
1300
- }
1301
- function createMutableWorkerPoolSummary(localCap) {
1302
- return {
1303
- mode: 'serial',
1304
- serverMaxConcurrency: 1,
1305
- localCap,
1306
- queueCap: 1,
1307
- availableLeases: 1,
1308
- effectiveConcurrency: 1,
1309
- peakConcurrency: 0,
1310
- pendingChildCount: 0,
1311
- startedChildCount: 0,
1312
- completedChildCount: 0,
1313
- backpressurePauseCount: 0,
1314
- reasonCodes: [],
1315
- };
1316
- }
1317
- function publicWorkerPoolSummary(summary) {
1318
- return {
1319
- mode: summary.mode,
1320
- serverMaxConcurrency: boundedCount(summary.serverMaxConcurrency),
1321
- localCap: boundedCount(summary.localCap),
1322
- queueCap: boundedCount(summary.queueCap),
1323
- availableLeases: boundedCount(summary.availableLeases),
1324
- effectiveConcurrency: boundedCount(summary.effectiveConcurrency),
1325
- peakConcurrency: boundedCount(summary.peakConcurrency),
1326
- pendingChildCount: boundedCount(summary.pendingChildCount),
1327
- startedChildCount: boundedCount(summary.startedChildCount),
1328
- completedChildCount: boundedCount(summary.completedChildCount),
1329
- backpressurePauseCount: boundedCount(summary.backpressurePauseCount),
1330
- reasonCodes: unique(summary.reasonCodes.length > 0
1331
- ? summary.reasonCodes
1332
- : [HEADLESS_REASON_CODES.WORKER_POOL_SERIAL_FALLBACK]).slice(0, 10),
1333
- publicSafe: true,
1334
- };
1335
- }
1336
- function defaultWorkerPoolSummary(localCap = resolveDefaultHeadlessYoloopLocalConcurrencyCap()) {
1337
- return publicWorkerPoolSummary(createMutableWorkerPoolSummary(localCap));
1338
- }
1339
- function boundedCount(value) {
1340
- if (!Number.isFinite(value))
1341
- return 0;
1342
- return Math.max(0, Math.min(10_000, Math.floor(value)));
1343
- }
1344
- function prepareYoloopAttemptInput(input) {
1345
- const governance = readAutonomousGovernanceEnvelopeFromMetadata(input.attempt.metadata_json, {
1346
- autonomousKind: 'run_yoloop',
1347
- jobId: input.attempt.job_id,
1348
- targetKind: 'epic',
1349
- targetRef: input.attempt.target_ref,
1350
- });
1351
- if (!governance.ok) {
1352
- return {
1353
- ok: false,
1354
- status: 'failed',
1355
- receiptStatus: 'failed',
1356
- reasonCode: governance.reasonCode,
1357
- publicSummary: governance.publicSummary,
1358
- redactionSummary: governance.redactionSummary,
1359
- };
1360
- }
1361
- const promptValidation = validateRunYoloopAttemptShape(input.attempt);
1362
- if (!promptValidation.ok)
1363
- return promptValidation;
1364
- const runtime = resolveAttemptRuntime(input);
1365
- if (!runtime.ok) {
1366
- return {
1367
- ok: false,
1368
- status: 'failed',
1369
- receiptStatus: 'failed',
1370
- reasonCode: runtime.reasonCode,
1371
- publicSummary: runtime.publicSummary,
1372
- redactionSummary: runtime.redactionSummary,
1373
- };
1374
- }
1375
- const epicId = input.attempt.epic_id ?? epicIdFromTargetRef(input.attempt.target_ref);
1376
- return {
1377
- ok: true,
1378
- input: {
1379
- rootPrompt: `*yoloop @${input.attempt.target_ref}`,
1380
- targetRef: input.attempt.target_ref,
1381
- epicId,
1382
- runtimeId: runtime.runtimeId,
1383
- ...(runtime.modelId ? { modelId: runtime.modelId } : {}),
1384
- runtimeSource: runtime.runtimeSource,
1385
- publicSafe: true,
1386
- },
1387
- };
1388
- }
1389
- function validateRunYoloopAttemptShape(attempt) {
1390
- const redactions = [];
1391
- if (attempt.directive_kind !== 'run_yoloop')
1392
- redactions.push(redaction('directiveKind', 'unsafe_key', 'value-denied'));
1393
- if (attempt.target_kind !== 'epic')
1394
- redactions.push(redaction('targetKind', 'prompt_body', 'value-denied'));
1395
- if (!EPIC_TARGET_PATTERN.test(attempt.target_ref) || SHELL_FRAGMENT_PATTERN.test(attempt.target_ref) || UNSAFE_VALUE_PATTERN.test(attempt.target_ref)) {
1396
- redactions.push(redaction('targetRef', 'prompt_body', 'value-denied'));
1397
- }
1398
- const epicId = epicIdFromTargetRef(attempt.target_ref);
1399
- if (attempt.epic_id && attempt.epic_id !== epicId)
1400
- redactions.push(redaction('epicId', 'prompt_body', 'value-denied'));
1401
- if (redactions.length > 0) {
1402
- return {
1403
- ok: false,
1404
- status: 'failed',
1405
- receiptStatus: 'failed',
1406
- reasonCode: HEADLESS_REASON_CODES.PROMPT_REJECTED,
1407
- publicSummary: 'Headless run_yoloop attempt did not match the canonical public epic prompt shape.',
1408
- redactionSummary: redactions,
1409
- };
1410
- }
1411
- return {
1412
- ok: true,
1413
- input: {
1414
- rootPrompt: `*yoloop @${attempt.target_ref}`,
1415
- targetRef: attempt.target_ref,
1416
- epicId,
1417
- runtimeId: 'fake',
1418
- publicSafe: true,
1419
- },
1420
- };
1421
- }
1422
- function resolveAttemptRuntime(input) {
1423
- const defaults = input.runtimeDefaults !== undefined
1424
- ? input.runtimeDefaults
1425
- : loadHeadlessRuntimeDefaults({ projectRoot: input.projectRoot });
1426
- if (isRecord(defaults) && defaults.ok === false) {
1427
- return {
1428
- ok: false,
1429
- reasonCode: HEADLESS_REASON_CODES.RUNTIME_UNTRUSTED,
1430
- publicSummary: typeof defaults.publicSummary === 'string' ? defaults.publicSummary : 'Headless runtime defaults failed public-safety validation.',
1431
- redactionSummary: Array.isArray(defaults.redactionSummary) ? defaults.redactionSummary : [],
1432
- };
1433
- }
1434
- const source = normalizeRuntimeSource(input.attempt.runtime_source) ?? 'explicit';
1435
- const hint = (input.attempt.runtime_id || input.attempt.model_id)
1436
- ? {
1437
- ...(input.attempt.runtime_id ? { runtimeId: input.attempt.runtime_id } : {}),
1438
- ...(input.attempt.model_id ? { modelId: input.attempt.model_id } : {}),
1439
- source,
1440
- publicSafe: true,
1441
- }
1442
- : undefined;
1443
- const resolutionInput = {
1444
- registry: input.registry,
1445
- defaults,
1446
- fallback: input.runtimeFallback,
1447
- };
1448
- if (hint) {
1449
- if (source === 'origin')
1450
- resolutionInput.origin = hint;
1451
- else if (source === 'default')
1452
- resolutionInput.projectDefault = hint;
1453
- else if (source === 'fallback')
1454
- resolutionInput.fallback = hint;
1455
- else
1456
- resolutionInput.explicit = hint;
1457
- }
1458
- const resolution = resolveHeadlessRuntime(resolutionInput);
1459
- if (!resolution.ok) {
1460
- return {
1461
- ok: false,
1462
- reasonCode: resolution.reasonCode,
1463
- publicSummary: resolution.publicSummary,
1464
- redactionSummary: resolution.redactionSummary,
1465
- };
1466
- }
1467
- return {
1468
- ok: true,
1469
- runtimeId: resolution.runtimeId,
1470
- ...(resolution.modelId ? { modelId: resolution.modelId } : {}),
1471
- runtimeSource: resolution.runtimeSource,
1472
- };
1473
- }
1474
- function validateRunYoloopExecutionDirective(input) {
1475
- const redactions = [];
1476
- for (const key of Object.keys(input)) {
1477
- if (!EXECUTION_DIRECTIVE_ALLOWED_KEYS.has(key) || UNSAFE_KEY_PATTERN.test(key)) {
1478
- redactions.push(redaction(key, unsafeKeyReason(key), 'key-denied'));
1479
- }
1480
- }
1481
- if (input.publicSafe !== true)
1482
- redactions.push(redaction('publicSafe', 'unsafe_key', 'value-denied'));
1483
- const kind = stringField(input, 'kind');
1484
- const commandClass = stringField(input, 'commandClass');
1485
- const jobId = stringField(input, 'jobId');
1486
- const operationId = stringField(input, 'operationId');
1487
- const idempotencyKey = stringField(input, 'idempotencyKey');
1488
- const targetKind = stringField(input, 'targetKind');
1489
- const targetRef = stringField(input, 'targetRef');
1490
- const commandRef = stringField(input, 'commandRef');
1491
- const publicSummary = stringField(input, 'publicSummary');
1492
- const epicId = stringField(input, 'epicId');
1493
- if (kind !== 'run_yoloop')
1494
- redactions.push(redaction('kind', 'unsafe_key', 'value-denied'));
1495
- if (commandClass !== 'goal-tick' && commandClass !== 'loop-tick')
1496
- redactions.push(redaction('commandClass', 'unsafe_key', 'value-denied'));
1497
- if (!isSafeIdentifier(jobId))
1498
- redactions.push(redaction('jobId', 'unsafe_key', 'value-denied'));
1499
- if (!isSafeIdentifier(operationId))
1500
- redactions.push(redaction('operationId', 'unsafe_key', 'value-denied'));
1501
- if (!isSafeIdentifier(idempotencyKey))
1502
- redactions.push(redaction('idempotencyKey', 'unsafe_key', 'value-denied'));
1503
- if (targetKind !== 'epic' || !targetRef || !EPIC_TARGET_PATTERN.test(targetRef) || UNSAFE_VALUE_PATTERN.test(targetRef)) {
1504
- redactions.push(redaction('targetRef', 'prompt_body', 'value-denied'));
1505
- }
1506
- const expectedCommandRef = targetRef ? `*yoloop @${targetRef}` : undefined;
1507
- if (!commandRef || commandRef !== expectedCommandRef || commandRef.includes('@neocortex') || SHELL_FRAGMENT_PATTERN.test(commandRef) || UNSAFE_VALUE_PATTERN.test(commandRef)) {
1508
- redactions.push(redaction('commandRef', 'prompt_body', 'value-denied'));
1509
- }
1510
- if (epicId && targetRef && epicId !== epicIdFromTargetRef(targetRef))
1511
- redactions.push(redaction('epicId', 'prompt_body', 'value-denied'));
1512
- if (!publicSummary || publicSummary.length > 240 || UNSAFE_VALUE_PATTERN.test(publicSummary)) {
1513
- redactions.push(redaction('publicSummary', 'unbounded_text', 'value-denied'));
1514
- }
1515
- if (input.reasonCode !== undefined && (typeof input.reasonCode !== 'string' || UNSAFE_VALUE_PATTERN.test(input.reasonCode))) {
1516
- redactions.push(redaction('reasonCode', 'unsafe_key', 'value-denied'));
1517
- }
1518
- const runtime = validateDirectiveRuntime(input.runtime, redactions);
1519
- if (input.attempts !== undefined)
1520
- assertPublicSafeCandidate(input.attempts, 'attempts', redactions);
1521
- if (input.metadata !== undefined)
1522
- assertPublicSafeCandidate(input.metadata, 'metadata', redactions);
1523
- const metadata = isRecord(input.metadata) ? input.metadata : undefined;
1524
- const redactionSummary = validateDirectiveRedactions(input.redactionSummary, redactions);
1525
- if (redactions.length > 0 || kind !== 'run_yoloop' || !commandClass || !jobId || !operationId || !idempotencyKey || !targetRef || !commandRef || !publicSummary) {
1526
- const promptRejected = redactions.some((item) => item.reason === 'prompt_body');
1527
- return {
1528
- ok: false,
1529
- reasonCode: promptRejected ? HEADLESS_REASON_CODES.PROMPT_REJECTED : HEADLESS_REASON_CODES.DIRECTIVE_REJECTED,
1530
- redactionSummary: redactions,
1531
- };
1532
- }
1533
- return {
1534
- ok: true,
1535
- directive: {
1536
- kind: 'run_yoloop',
1537
- commandClass: commandClass,
1538
- jobId: jobId,
1539
- operationId: operationId,
1540
- idempotencyKey: idempotencyKey,
1541
- targetKind: 'epic',
1542
- targetRef: targetRef,
1543
- commandRef: commandRef,
1544
- ...(epicId ? { epicId } : {}),
1545
- ...(runtime ? { runtime } : {}),
1546
- publicSummary: publicSummary,
1547
- ...(typeof input.reasonCode === 'string' ? { reasonCode: input.reasonCode } : {}),
1548
- ...(metadata ? { metadata } : {}),
1549
- ...(redactionSummary.length > 0 ? { redactionSummary } : {}),
1550
- publicSafe: true,
1551
- },
1552
- };
1553
- }
1554
- function extractAuthorizedChildPrompts(metadata, epicId) {
1555
- if (!metadata) {
1556
- return rejectPromptExtraction(HEADLESS_REASON_CODES.YOLOOP_METADATA_INVALID, 'Headless yoloop metadata was missing.', []);
1557
- }
1558
- const publicSafety = validateYoloopMetadataPublicSubset(metadata);
1559
- if (!publicSafety.ok)
1560
- return publicSafety;
1561
- const prompts = [];
1562
- const plan = isRecord(metadata.yoloopExecutionPlan) ? metadata.yoloopExecutionPlan : undefined;
1563
- const planStoryIds = plan ? safeStringArray(plan.storyIds).filter(isStoryId) : [];
1564
- const continuousNodes = plan?.version === 3 && isRecord(plan.scheduler) && Array.isArray(plan.scheduler.nodes)
1565
- ? new Map(plan.scheduler.nodes.filter(isRecord).map((node) => [String(node.storyId ?? ''), node]))
1566
- : new Map();
1567
- const continuousGraphRevision = plan?.version === 3 && isRecord(plan.scheduler) && typeof plan.scheduler.graphRevision === 'string'
1568
- ? plan.scheduler.graphRevision
1569
- : undefined;
1570
- const continuousExecutionBranch = plan?.version === 3 && typeof plan.executionBranch === 'string'
1571
- ? plan.executionBranch
1572
- : undefined;
1573
- let planValidation;
1574
- if (plan) {
1575
- const validation = validateExecutionPlan(plan);
1576
- if (!validation.ok)
1577
- return validation;
1578
- planValidation = validation;
1579
- for (const prompt of extractPlanPrompts(plan)) {
1580
- const normalized = normalizeChildPrompt(prompt, epicId, 'execution-plan');
1581
- if (!normalized.ok)
1582
- return normalized;
1583
- prompts.push(enrichContinuousPrompt(normalized.prompt, continuousNodes.get(normalized.prompt.storyId), continuousGraphRevision, continuousExecutionBranch));
1584
- }
1585
- if (prompts.length === 0) {
1586
- for (const storyId of planStoryIds) {
1587
- const normalized = normalizeChildPrompt(`*yolo @docs/stories/${storyId}.story.md`, epicId, 'execution-plan');
1588
- if (!normalized.ok)
1589
- return normalized;
1590
- prompts.push(enrichContinuousPrompt(normalized.prompt, continuousNodes.get(normalized.prompt.storyId), continuousGraphRevision, continuousExecutionBranch));
1591
- }
1592
- }
1593
- const directiveCompatibility = validatePlanTaskDirectives(metadata.skillDirectives, prompts);
1594
- if (!directiveCompatibility.ok)
1595
- return directiveCompatibility;
1596
- }
1597
- const nextStoryId = typeof metadata.nextStoryId === 'string' && isStoryId(metadata.nextStoryId)
1598
- ? metadata.nextStoryId
1599
- : undefined;
1600
- // A validated execution plan is the sole child-dispatch authority. Compatible
1601
- // duplicate task directives were checked above but never become a second
1602
- // dispatch source.
1603
- for (const directive of plan ? [] : Array.isArray(metadata.skillDirectives) ? metadata.skillDirectives : []) {
1604
- if (!isRecord(directive) || directive.kind !== 'task')
1605
- continue;
1606
- const explicitPrompts = safeStringArray(directive.promptTemplates);
1607
- if (explicitPrompts.length > 0) {
1608
- for (const prompt of explicitPrompts) {
1609
- const normalized = normalizeChildPrompt(prompt, epicId, 'task-directive');
1610
- if (!normalized.ok)
1611
- return normalized;
1612
- prompts.push(normalized.prompt);
1613
- }
1614
- continue;
1615
- }
1616
- const template = typeof directive.promptTemplate === 'string' ? directive.promptTemplate : undefined;
1617
- if (!template)
1618
- continue;
1619
- const storyIds = safeStringArray(directive.storyIds).filter(isStoryId);
1620
- const ids = storyIds.length > 0 ? storyIds : nextStoryId ? [nextStoryId] : [];
1621
- if (ids.length === 0 && CHILD_PROMPT_PATTERN.test(template)) {
1622
- const normalized = normalizeChildPrompt(template, epicId, 'task-directive');
1623
- if (!normalized.ok)
1624
- return normalized;
1625
- prompts.push(normalized.prompt);
1626
- continue;
1627
- }
1628
- for (const storyId of ids) {
1629
- const prompt = template.includes('{storyId}') ? template.replaceAll('{storyId}', storyId) : template;
1630
- const normalized = normalizeChildPrompt(prompt, epicId, 'task-directive');
1631
- if (!normalized.ok)
1632
- return normalized;
1633
- prompts.push(normalized.prompt);
1634
- }
1635
- }
1636
- if (prompts.length === 0 && nextStoryId) {
1637
- const normalized = normalizeChildPrompt(`*yolo @docs/stories/${nextStoryId}.story.md`, epicId, 'next-story');
1638
- if (!normalized.ok)
1639
- return normalized;
1640
- prompts.push(normalized.prompt);
1641
- }
1642
- const uniquePrompts = uniqueBy(prompts, (item) => item.commandRef);
1643
- if (planValidation?.continuous) {
1644
- if (uniquePrompts.length !== planStoryIds.length
1645
- || uniquePrompts.some((prompt) => prompt.preparationOnly !== true || prompt.source !== 'execution-plan')) {
1646
- return rejectPromptExtraction(HEADLESS_REASON_CODES.YOLOOP_ISOLATION_VIOLATION, 'Headless continuous yoloop rejected an ambiguous or non-preparation child prompt.', [redaction('promptTemplates', 'prompt_body', 'operation-denied')]);
1647
- }
1648
- }
1649
- else if (uniquePrompts.some((prompt) => prompt.preparationOnly === true)) {
1650
- return rejectPromptExtraction(HEADLESS_REASON_CODES.YOLOOP_ISOLATION_VIOLATION, 'Headless yoloop rejected branchless preparation outside a validated continuous plan.', [redaction('promptTemplates', 'prompt_body', 'operation-denied')]);
1651
- }
1652
- if (planStoryIds.length > 0) {
1653
- const authorized = new Set(planStoryIds);
1654
- for (const prompt of uniquePrompts) {
1655
- if (!authorized.has(prompt.storyId)) {
1656
- return rejectPromptExtraction(HEADLESS_REASON_CODES.YOLOOP_ISOLATION_VIOLATION, 'Headless yoloop rejected a child prompt outside the server-authorized execution plan.', [redaction('storyId', 'prompt_body', hashPublicValue(prompt.storyId))]);
1657
- }
1658
- }
1659
- }
1660
- if (planValidation?.parallelAuthorized && !sameStringSet(uniquePrompts.map((item) => item.storyId), planStoryIds)) {
1661
- return rejectPromptExtraction(HEADLESS_REASON_CODES.YOLOOP_METADATA_INVALID, 'Headless yoloop rejected a parallel plan whose executable prompts did not match the selected wave.', []);
1662
- }
1663
- if (uniquePrompts.length === 0 && !planValidation?.continuous) {
1664
- return rejectPromptExtraction(HEADLESS_REASON_CODES.YOLOOP_METADATA_INVALID, 'Headless yoloop metadata did not include an authorized per-story child prompt.', []);
1665
- }
1666
- return {
1667
- ok: true,
1668
- prompts: uniquePrompts,
1669
- mode: planValidation?.mode ?? 'legacy',
1670
- serverMaxConcurrency: planValidation?.serverMaxConcurrency ?? 1,
1671
- parallelAuthorized: planValidation?.parallelAuthorized ?? false,
1672
- continuous: planValidation?.continuous ?? false,
1673
- reasonCodes: [
1674
- HEADLESS_REASON_CODES.OK,
1675
- planValidation?.parallelAuthorized
1676
- ? HEADLESS_REASON_CODES.WORKER_POOL_PARALLEL_ACTIVE
1677
- : HEADLESS_REASON_CODES.WORKER_POOL_SERIAL_FALLBACK,
1678
- ],
1679
- };
1680
- }
1681
- function enrichContinuousPrompt(prompt, node, graphRevision, executionBranch) {
1682
- if (!node || !graphRevision || !executionBranch)
1683
- return prompt;
1684
- const writeSet = Array.isArray(node.writeSet) ? safeStringArray(node.writeSet) : [];
1685
- const rootAuthority = parseBranchlessRootAuthority(node.childExecutionAuthority, {
1686
- storyId: prompt.storyId,
1687
- invocationPrompt: prompt.commandRef,
1688
- authorizedWriteSet: writeSet,
1689
- });
1690
- return {
1691
- ...prompt,
1692
- ...(typeof node.dispatchId === 'string' ? { dispatchId: node.dispatchId } : {}),
1693
- ...(typeof node.idempotencyKey === 'string' ? { idempotencyKey: node.idempotencyKey } : {}),
1694
- graphRevision,
1695
- executionBranch,
1696
- ...(writeSet.length > 0 ? { writeSet } : {}),
1697
- ...(rootAuthority ? { rootAuthority } : {}),
1698
- };
1699
- }
1700
- function validateYoloopMetadataPublicSubset(metadata) {
1701
- const redactions = [];
1702
- if (metadata.nextStoryId !== undefined)
1703
- validatePublicMetadataValue(metadata.nextStoryId, 'nextStoryId', redactions);
1704
- if (metadata.yoloopExecutionPlan !== undefined)
1705
- validatePublicMetadataValue(metadata.yoloopExecutionPlan, 'yoloopExecutionPlan', redactions);
1706
- if (Array.isArray(metadata.skillDirectives)) {
1707
- metadata.skillDirectives.forEach((directive, index) => {
1708
- if (isRecord(directive) && directive.kind === 'task')
1709
- validatePublicMetadataValue(directive, `skillDirectives.${index}`, redactions);
1710
- });
1711
- }
1712
- if (redactions.length > 0) {
1713
- return rejectPromptExtraction(HEADLESS_REASON_CODES.YOLOOP_METADATA_INVALID, 'Headless yoloop rejected unsafe public metadata before child delegation.', redactions);
1714
- }
1715
- return { ok: true };
1716
- }
1717
- function validatePlanTaskDirectives(value, planPrompts) {
1718
- if (!Array.isArray(value))
1719
- return { ok: true };
1720
- const authorized = new Set(planPrompts.map((prompt) => prompt.commandRef));
1721
- for (const [index, directive] of value.entries()) {
1722
- if (!isRecord(directive) || directive.kind !== 'task')
1723
- continue;
1724
- const promptTemplate = typeof directive.promptTemplate === 'string' ? directive.promptTemplate : undefined;
1725
- const promptTemplates = safeStringArray(directive.promptTemplates);
1726
- const redactedDuplicate = promptTemplate === '[REDACTED]'
1727
- && directive.subagentType === 'neocortex'
1728
- && typeof directive.reasonCode === 'string'
1729
- && directive.reasonCode.startsWith('directive-prompt-')
1730
- && promptTemplates.length === 0;
1731
- if (redactedDuplicate)
1732
- continue;
1733
- const candidates = [...(promptTemplate ? [promptTemplate] : []), ...promptTemplates];
1734
- if (directive.subagentType !== 'neocortex'
1735
- || candidates.length === 0
1736
- || candidates.some((candidate) => !authorized.has(candidate))) {
1737
- return rejectPromptExtraction(HEADLESS_REASON_CODES.YOLOOP_ISOLATION_VIOLATION, 'Headless yoloop rejected a task directive that conflicted with the server-authorized execution plan.', [redaction(`skillDirectives.${index}`, 'prompt_body', 'operation-denied')]);
1738
- }
1739
- }
1740
- return { ok: true };
1741
- }
1742
- function validatePublicMetadataValue(value, path, redactions) {
1743
- if (typeof value === 'string') {
1744
- if (/\.allowedDebt\.constraints\.\d+$/.test(path) && PUBLIC_CHILD_DEBT_CONSTRAINTS.has(value))
1745
- return;
1746
- if (UNSAFE_VALUE_PATTERN.test(value) || /\0/.test(value))
1747
- redactions.push(redaction(path, unsafeKeyReason(path), 'value-denied'));
1748
- return;
1749
- }
1750
- if (value === undefined || value === null || typeof value === 'number' || typeof value === 'boolean')
1751
- return;
1752
- if (Array.isArray(value)) {
1753
- value.forEach((item, index) => validatePublicMetadataValue(item, `${path}.${index}`, redactions));
1754
- return;
1755
- }
1756
- if (isRecord(value)) {
1757
- for (const [key, child] of Object.entries(value)) {
1758
- const childPath = `${path}.${key}`;
1759
- const promptTemplateKey = key === 'promptTemplate'
1760
- || key === 'promptTemplates'
1761
- || key === 'invocationPrompt'
1762
- || key === 'childPromptKind'
1763
- || key === 'allowMetaTaskPromptInChild'
1764
- || key === 'authorization';
1765
- if (!promptTemplateKey && UNSAFE_KEY_PATTERN.test(key))
1766
- redactions.push(redaction(childPath, unsafeKeyReason(key), 'key-denied'));
1767
- validatePublicMetadataValue(child, childPath, redactions);
1768
- }
1769
- return;
1770
- }
1771
- redactions.push(redaction(path, 'unsafe_key', 'value-denied'));
1772
- }
1773
- function validateExecutionPlan(plan) {
1774
- const mode = typeof plan.mode === 'string' ? plan.mode : '';
1775
- const isolationPolicy = isRecord(plan.isolationPolicy) ? plan.isolationPolicy : undefined;
1776
- const storyIds = safeStringArray(plan.storyIds);
1777
- if (plan.authorization !== 'server_authorized') {
1778
- return rejectPromptExtraction(HEADLESS_REASON_CODES.YOLOOP_METADATA_INVALID, 'Headless yoloop execution plan was not server-authorized.', []);
1779
- }
1780
- if (plan.executor !== 'root_agent' && plan.executor !== 'root_agent_with_child_tasks') {
1781
- return rejectPromptExtraction(HEADLESS_REASON_CODES.YOLOOP_METADATA_INVALID, 'Headless yoloop execution plan executor was not root-owned.', []);
1782
- }
1783
- if (mode !== 'serial' && mode !== 'parallel_wave' && mode !== 'continuous_dag' && mode !== 'manual') {
1784
- return rejectPromptExtraction(HEADLESS_REASON_CODES.YOLOOP_METADATA_INVALID, 'Headless yoloop execution plan mode was invalid.', []);
1785
- }
1786
- const continuousMode = plan.version === 3 && mode === 'continuous_dag';
1787
- if (!Array.isArray(plan.storyIds) ||
1788
- (!continuousMode && storyIds.length === 0) ||
1789
- storyIds.length !== plan.storyIds.length ||
1790
- storyIds.some((storyId) => !isStoryId(storyId)) ||
1791
- new Set(storyIds).size !== storyIds.length) {
1792
- return rejectPromptExtraction(HEADLESS_REASON_CODES.YOLOOP_METADATA_INVALID, 'Headless yoloop execution plan story selection was invalid or ambiguous.', []);
1793
- }
1794
- if (!isolationPolicy ||
1795
- isolationPolicy.rootOwnsLoop !== true ||
1796
- (isolationPolicy.childPromptKind === 'per_story_branchless_preparation_only' && !continuousMode) ||
1797
- (Object.prototype.hasOwnProperty.call(isolationPolicy, 'childExecutionBoundary') && !continuousMode) ||
1798
- (isolationPolicy.childPromptKind !== 'per_story_yolo_only' &&
1799
- isolationPolicy.childPromptKind !== 'per_story_branchless_preparation_only' &&
1800
- !(isolationPolicy.childPromptKind === 'none' &&
1801
- ((mode === 'serial' && isolationPolicy.childTaskDelegation === 'not_required') ||
1802
- (mode === 'parallel_wave' && plan.executor === 'root_agent' && isolationPolicy.childTaskDelegation === 'forbidden')))) ||
1803
- isolationPolicy.allowOuterYoloopInChild !== false ||
1804
- isolationPolicy.allowMetaTaskPromptInChild !== false) {
1805
- return rejectPromptExtraction(HEADLESS_REASON_CODES.YOLOOP_ISOLATION_VIOLATION, 'Headless yoloop rejected an execution plan that did not preserve root-owned child isolation.', [redaction('isolationPolicy', 'prompt_body', 'value-denied')]);
1806
- }
1807
- const skippedStories = Array.isArray(plan.skippedStories) ? plan.skippedStories : [];
1808
- for (const skipped of skippedStories) {
1809
- if (!isRecord(skipped) || typeof skipped.storyId !== 'string' || !isStoryId(skipped.storyId) || typeof skipped.reason !== 'string') {
1810
- return rejectPromptExtraction(HEADLESS_REASON_CODES.YOLOOP_METADATA_INVALID, 'Headless yoloop skipped-story evidence was malformed.', []);
1811
- }
1812
- if (storyIds.includes(skipped.storyId)) {
1813
- return rejectPromptExtraction(HEADLESS_REASON_CODES.YOLOOP_METADATA_INVALID, 'Headless yoloop selected a story that server evidence marked skipped.', []);
1814
- }
1815
- }
1816
- if (continuousMode) {
1817
- const scheduler = isRecord(plan.scheduler) ? plan.scheduler : undefined;
1818
- const nodes = Array.isArray(scheduler?.nodes) ? scheduler.nodes.filter(isRecord) : [];
1819
- const schedulerReady = safeStringArray(scheduler?.readyStoryIds);
1820
- const schedulerRunning = safeStringArray(scheduler?.runningStoryIds);
1821
- const promptTemplates = safeStringArray(plan.promptTemplates);
1822
- const dependencyBasis = isRecord(plan.dependencyBasis) ? plan.dependencyBasis : undefined;
1823
- const readinessBasis = isRecord(plan.readinessBasis) ? plan.readinessBasis : undefined;
1824
- const graphRevision = typeof scheduler?.graphRevision === 'string' ? scheduler.graphRevision : '';
1825
- const executionBranch = typeof plan.executionBranch === 'string' ? plan.executionBranch : '';
1826
- const nodeIds = nodes.map((node) => typeof node.storyId === 'string' ? node.storyId : '');
1827
- const unsafeNode = nodes.find((node) => {
1828
- const storyId = typeof node.storyId === 'string' ? node.storyId : '';
1829
- const prompt = typeof node.promptTemplate === 'string' ? node.promptTemplate : '';
1830
- const writeSet = Array.isArray(node.writeSet) ? safeStringArray(node.writeSet) : [];
1831
- return !isStoryId(storyId) || prompt !== `*yolo @docs/stories/${storyId}.story.md branchless-preparation`
1832
- || typeof node.dispatchId !== 'string' || !/^[a-f0-9]{64}$/.test(node.dispatchId)
1833
- || typeof node.idempotencyKey !== 'string' || !/^[a-f0-9]{64}$/.test(node.idempotencyKey)
1834
- || node.dependencyBasis !== 'verified'
1835
- || !Array.isArray(node.dependencies) || safeStringArray(node.dependencies).length !== node.dependencies.length
1836
- || !Array.isArray(node.writeSet) || writeSet.length === 0 || writeSet.length !== node.writeSet.length
1837
- || !parseBranchlessRootAuthority(node.childExecutionAuthority, {
1838
- storyId, invocationPrompt: prompt, authorizedWriteSet: writeSet,
1839
- });
1840
- });
1841
- if (plan.executor !== 'root_agent_with_child_tasks'
1842
- || plan.legacyConcurrencyIgnored !== true
1843
- || Object.prototype.hasOwnProperty.call(plan, 'maxConcurrency')
1844
- || Object.prototype.hasOwnProperty.call(plan, 'maxParallel')
1845
- || isolationPolicy?.rootOwnedScheduling !== 'continuous_dag_allowed'
1846
- || isolationPolicy?.childPromptKind !== 'per_story_branchless_preparation_only'
1847
- || isolationPolicy?.childExecutionBoundary !== 'filesystem_only'
1848
- || isolationPolicy?.childTaskDelegation !== 'allowed'
1849
- || isolationPolicy?.maxDepth !== 1
1850
- || isolationPolicy?.childWorkspace !== 'branchless_sandbox'
1851
- || isolationPolicy?.epicCheckout !== 'current_checkout'
1852
- || isolationPolicy?.workspaceLifecycle !== 'user_managed'
1853
- || isolationPolicy?.integrationOwner !== 'root_agent'
1854
- || !scheduler
1855
- || scheduler.schemaVersion !== 1
1856
- || scheduler.strategy !== 'continuous-event-driven-dag'
1857
- || scheduler.logicalConcurrency !== 'ready-set'
1858
- || scheduler.capacityPolicy !== 'backpressure-only'
1859
- || scheduler.rootOwnsLoop !== true
1860
- || scheduler.maxDepth !== 1
1861
- || !/^[a-f0-9]{64}$/.test(graphRevision)
1862
- || !isSafeExecutionBranch(executionBranch)
1863
- || new Set(nodeIds).size !== nodeIds.length
1864
- || nodeIds.some((storyId) => !isStoryId(storyId))
1865
- || schedulerReady.some((storyId) => !nodeIds.includes(storyId))
1866
- || schedulerRunning.some((storyId) => !nodeIds.includes(storyId) || schedulerReady.includes(storyId))
1867
- || !sameStringSet(storyIds, schedulerReady)
1868
- || promptTemplates.length !== storyIds.length
1869
- || promptTemplates.some((prompt, index) => prompt !== `*yolo @docs/stories/${storyIds[index]}.story.md branchless-preparation`)
1870
- || !dependencyBasis || dependencyBasis.source !== 'state_snapshot'
1871
- || !readinessBasis || readinessBasis.source !== 'ready_wave'
1872
- || !sameStringSet(safeStringArray(readinessBasis.selectedStoryIds), storyIds)
1873
- || unsafeNode) {
1874
- return rejectPromptExtraction(HEADLESS_REASON_CODES.YOLOOP_METADATA_INVALID, 'Headless yoloop rejected an invalid continuous DAG execution plan.', []);
1875
- }
1876
- return {
1877
- ok: true,
1878
- mode: 'continuous_dag',
1879
- serverMaxConcurrency: storyIds.length,
1880
- parallelAuthorized: true,
1881
- continuous: true,
1882
- };
1883
- }
1884
- if (plan.version === 2) {
1885
- const phased = validatePhasedYoloopPlan(plan);
1886
- if (!phased.ok) {
1887
- return rejectPromptExtraction(HEADLESS_REASON_CODES.YOLOOP_METADATA_INVALID, 'Headless yoloop rejected an unsafe phased execution plan.', []);
1888
- }
1889
- // A child *yolo performs the complete story lifecycle and may write. Until
1890
- // preparation-only child directives exist, full child execution is pinned
1891
- // to the P207 single writer even when preparation phases allow parallelism.
1892
- return { ok: true, mode: 'parallel_wave', serverMaxConcurrency: phased.childExecutionConcurrency, parallelAuthorized: false, continuous: false };
1893
- }
1894
- if (mode !== 'parallel_wave') {
1895
- return {
1896
- ok: true,
1897
- mode: mode,
1898
- serverMaxConcurrency: 1,
1899
- parallelAuthorized: false,
1900
- continuous: false,
1901
- };
1902
- }
1903
- const maxConcurrency = plan.maxConcurrency;
1904
- const maxParallel = plan.maxParallel;
1905
- const dependencyBasis = isRecord(plan.dependencyBasis) ? plan.dependencyBasis : undefined;
1906
- const readinessBasis = isRecord(plan.readinessBasis) ? plan.readinessBasis : undefined;
1907
- const parallelWaves = Array.isArray(plan.parallelWaves) ? plan.parallelWaves : [];
1908
- const wave = parallelWaves.length === 1 && isRecord(parallelWaves[0]) ? parallelWaves[0] : undefined;
1909
- if (isolationPolicy.rootOwnedScheduling !== 'parallel_wave_allowed' ||
1910
- !Number.isInteger(maxConcurrency) || typeof maxConcurrency !== 'number' || maxConcurrency < 2 || maxConcurrency > storyIds.length ||
1911
- !Number.isInteger(maxParallel) || maxParallel !== maxConcurrency ||
1912
- !dependencyBasis || dependencyBasis.source !== 'state_snapshot' || !sameStringSet(safeStringArray(dependencyBasis.storyIds), storyIds) ||
1913
- !readinessBasis || readinessBasis.source !== 'ready_wave' || !sameStringSet(safeStringArray(readinessBasis.selectedStoryIds), storyIds) ||
1914
- !wave || !sameStringSet(safeStringArray(wave.storyIds), storyIds) || wave.maxConcurrency !== maxConcurrency) {
1915
- return rejectPromptExtraction(HEADLESS_REASON_CODES.YOLOOP_METADATA_INVALID, 'Headless yoloop parallel plan lacked consistent bounded authorization and readiness evidence.', []);
1916
- }
1917
- const wavePrompts = safeStringArray(wave.promptTemplates);
1918
- if (wavePrompts.length !== storyIds.length || new Set(wavePrompts).size !== wavePrompts.length) {
1919
- return rejectPromptExtraction(HEADLESS_REASON_CODES.YOLOOP_METADATA_INVALID, 'Headless yoloop parallel wave prompts were incomplete or ambiguous.', []);
1920
- }
1921
- const proofs = Array.isArray(wave.proofSummaries)
1922
- ? wave.proofSummaries
1923
- : Array.isArray(plan.proofSummaries) ? plan.proofSummaries : [];
1924
- const waveProof = proofs.find((proof) => isRecord(proof) && sameStringSet(safeStringArray(proof.storyIds), storyIds));
1925
- if (!isRecord(waveProof) ||
1926
- waveProof.dependencyClosure !== 'resolved' ||
1927
- waveProof.contractOwnership !== 'non_overlapping' ||
1928
- waveProof.validationSurfaces !== 'compatible') {
1929
- return rejectPromptExtraction(HEADLESS_REASON_CODES.YOLOOP_METADATA_INVALID, 'Headless yoloop parallel plan lacked resolved independence proof.', []);
1930
- }
1931
- const unsafeSkipped = skippedStories.find((skipped) => isRecord(skipped) && typeof skipped.reason === 'string' && /(cycle|unresolved|ambiguous)/i.test(skipped.reason));
1932
- if (unsafeSkipped) {
1933
- return rejectPromptExtraction(HEADLESS_REASON_CODES.YOLOOP_METADATA_INVALID, 'Headless yoloop parallel plan contained unresolved dependency evidence.', []);
1934
- }
1935
- return {
1936
- ok: true,
1937
- mode: 'parallel_wave',
1938
- serverMaxConcurrency: maxConcurrency,
1939
- parallelAuthorized: true,
1940
- continuous: false,
1941
- };
1942
- }
1943
- function parseBranchlessRootAuthority(value, expected) {
1944
- if (!isRecord(value) || !isRecord(value.artifact))
1945
- return undefined;
1946
- const artifact = value.artifact;
1947
- const writeSet = Array.isArray(value.authorizedWriteSet) ? safeStringArray(value.authorizedWriteSet) : [];
1948
- if (Object.keys(value).sort().join('\0') !== [
1949
- 'artifact', 'authorizedWriteSet', 'effectScope', 'invocationPrompt', 'kind',
1950
- 'lifecycleAuthority', 'publicSafe', 'schemaVersion', 'storyId',
1951
- ].sort().join('\0')
1952
- || Object.keys(artifact).sort().join('\0') !== [
1953
- 'content', 'contentBinding', 'kind', 'path', 'schemaVersion',
1954
- ].sort().join('\0')
1955
- || value.schemaVersion !== 1 || value.kind !== 'branchless_story_preparation'
1956
- || value.storyId !== expected.storyId || value.invocationPrompt !== expected.invocationPrompt
1957
- || !Array.isArray(value.authorizedWriteSet)
1958
- || writeSet.length !== value.authorizedWriteSet.length
1959
- || writeSet.some((ref) => normalizeContinuousWriteRef(ref) !== ref)
1960
- || !sameOrderedStrings(writeSet, expected.authorizedWriteSet)
1961
- || value.effectScope !== 'filesystem_only' || value.lifecycleAuthority !== 'root_only'
1962
- || value.publicSafe !== true || artifact.schemaVersion !== 1
1963
- || artifact.kind !== 'branchless_root_bound_artifact'
1964
- || typeof artifact.path !== 'string' || !writeSet.includes(artifact.path)
1965
- || typeof artifact.content !== 'string' || artifact.content.length === 0 || artifact.content.length > 4096
1966
- || typeof artifact.contentBinding !== 'string' || !/^[a-f0-9]{64}$/.test(artifact.contentBinding)) {
1967
- return undefined;
1968
- }
1969
- const expectedBinding = createHash('sha256').update([
1970
- 'branchless-root-bound-artifact-v1', expected.storyId, expected.invocationPrompt,
1971
- ...writeSet, 'filesystem_only', 'root_only', artifact.path, artifact.content,
1972
- ].join('\0')).digest('hex');
1973
- if (artifact.contentBinding !== expectedBinding)
1974
- return undefined;
1975
- return value;
1976
- }
1977
- function sameOrderedStrings(left, right) {
1978
- return left.length === right.length && left.every((value, index) => value === right[index]);
1979
- }
1980
- function extractPlanPrompts(plan) {
1981
- const prompts = [];
1982
- prompts.push(...safeStringArray(plan.promptTemplates));
1983
- for (const step of Array.isArray(plan.serialSteps) ? plan.serialSteps : []) {
1984
- if (isRecord(step) && typeof step.promptTemplate === 'string')
1985
- prompts.push(step.promptTemplate);
1986
- }
1987
- for (const wave of Array.isArray(plan.parallelWaves) ? plan.parallelWaves : []) {
1988
- if (isRecord(wave))
1989
- prompts.push(...safeStringArray(wave.promptTemplates));
1990
- }
1991
- return prompts;
1992
- }
1993
- function normalizeChildPrompt(prompt, epicId, source) {
1994
- if (hasDelegatedPromptIsolationViolation(prompt)) {
1995
- return rejectPromptExtraction(HEADLESS_REASON_CODES.YOLOOP_ISOLATION_VIOLATION, 'Headless yoloop rejected an unsafe child prompt shape.', [redaction('promptTemplate', 'prompt_body', hashPublicValue(prompt))]);
1996
- }
1997
- if (!CHILD_PROMPT_PATTERN.test(prompt)) {
1998
- return rejectPromptExtraction(HEADLESS_REASON_CODES.YOLOOP_METADATA_INVALID, 'Headless yoloop child prompt did not match the canonical per-story yolo shape.', [redaction('promptTemplate', 'prompt_body', hashPublicValue(prompt))]);
1999
- }
2000
- const preparationOnly = BRANCHLESS_PREPARATION_PROMPT_PATTERN.test(prompt);
2001
- const targetRef = prompt.replace(/^\*yolo @/, '').replace(/ branchless-preparation$/, '');
2002
- const storyId = storyIdFromTargetRef(targetRef);
2003
- if (!CHILD_STORY_TARGET_PATTERN.test(targetRef) || !isStoryId(storyId) || !storyId.startsWith(`${epicId}.`)) {
2004
- return rejectPromptExtraction(HEADLESS_REASON_CODES.YOLOOP_ISOLATION_VIOLATION, 'Headless yoloop rejected a child prompt outside the targeted public epic.', [redaction('storyId', 'prompt_body', hashPublicValue(storyId))]);
2005
- }
2006
- return {
2007
- ok: true,
2008
- prompt: { storyId, targetRef, commandRef: prompt, source, ...(preparationOnly ? { preparationOnly: true } : {}) },
2009
- };
2010
- }
2011
- function extractEpicTerminalGitDirective(metadata) {
2012
- const value = metadata?.epicTerminalGitDirective;
2013
- if (!isRecord(value)
2014
- || value.schemaVersion !== 1
2015
- || value.kind !== 'epic_terminal_git'
2016
- || typeof value.epicId !== 'string'
2017
- || typeof value.executionBranch !== 'string'
2018
- || typeof value.originBranch !== 'string'
2019
- || typeof value.expectedExecutionHeadSha !== 'string'
2020
- || !Array.isArray(value.storyCheckpointIds)
2021
- || !isRecord(value.localGates)
2022
- || value.localGates.passed !== true
2023
- || !Array.isArray(value.localGates.receiptRefs)
2024
- || !isRecord(value.reconcile)
2025
- || typeof value.idempotencyKey !== 'string'
2026
- || value.publicSafe !== true)
2027
- return undefined;
2028
- return value;
2029
- }
2030
- function extractEpicGitReconciliationDirective(metadata) {
2031
- const value = metadata?.epicGitReconciliationDirective;
2032
- if (!isRecord(value)
2033
- || value.schemaVersion !== 1
2034
- || value.kind !== 'epic_git_reconciliation'
2035
- || typeof value.epicId !== 'string'
2036
- || typeof value.executionBranch !== 'string'
2037
- || typeof value.originBranch !== 'string'
2038
- || !['start', 'resume', 'audit'].includes(String(value.lifecycleBoundary))
2039
- || typeof value.dryRun !== 'boolean'
2040
- || typeof value.idempotencyKey !== 'string'
2041
- || value.publicSafe !== true)
2042
- return undefined;
2043
- return value;
2044
- }
2045
- function classifyYoloopTerminalMetadata(metadata) {
2046
- if (!metadata || !isRecord(metadata)) {
2047
- return {
2048
- ok: false,
2049
- reasonCode: HEADLESS_REASON_CODES.YOLOOP_METADATA_INVALID,
2050
- publicSummary: 'Headless yoloop root invocation did not return public metadata.',
2051
- redactionSummary: [],
2052
- };
2053
- }
2054
- const decision = isRecord(metadata.yoloopContinuationDecision) ? metadata.yoloopContinuationDecision : undefined;
2055
- const outcome = typeof decision?.outcome === 'string' ? decision.outcome : undefined;
2056
- const complete = outcome === 'queue_exhausted' || metadata.yoloopComplete === true;
2057
- const aborted = metadata.yoloopAborted === true;
2058
- const releaseBlocked = parseReleaseBlockedResult(metadata.releaseBlocked);
2059
- const replay = outcome === 'selected' && decision?.replay === true;
2060
- if (outcome && !['selected', 'queue_exhausted', 'blocked', 'cycle', 'invalid', 'no_progress'].includes(outcome)) {
2061
- return { ok: false, reasonCode: HEADLESS_REASON_CODES.YOLOOP_METADATA_INVALID, publicSummary: 'Headless yoloop rejected an unknown continuation outcome.', redactionSummary: [] };
2062
- }
2063
- if (outcome === 'queue_exhausted' && decision?.terminalSuccess !== true) {
2064
- return { ok: false, reasonCode: HEADLESS_REASON_CODES.YOLOOP_METADATA_INVALID, publicSummary: 'Headless yoloop rejected inconsistent queue exhaustion metadata.', redactionSummary: [] };
2065
- }
2066
- if (complete && aborted) {
2067
- return {
2068
- ok: false,
2069
- reasonCode: HEADLESS_REASON_CODES.YOLOOP_METADATA_INVALID,
2070
- publicSummary: 'Headless yoloop metadata reported mutually exclusive terminal states.',
2071
- redactionSummary: [redaction('yoloopTerminal', 'unsafe_key', 'value-denied')],
2072
- };
2073
- }
2074
- const releaseBlockedSignalled = metadata.yoloopReleaseBlocked === true
2075
- || metadata.terminalClass === 'release-blocked'
2076
- || metadata.releaseBlocked !== undefined;
2077
- if (releaseBlockedSignalled && (!releaseBlocked || metadata.yoloopReleaseBlocked !== true
2078
- || metadata.terminalClass !== 'release-blocked' || complete || aborted || outcome !== undefined)) {
2079
- return {
2080
- ok: false,
2081
- reasonCode: HEADLESS_REASON_CODES.YOLOOP_METADATA_INVALID,
2082
- publicSummary: 'Headless yoloop rejected inconsistent release-blocked terminal metadata.',
2083
- redactionSummary: [],
2084
- };
2085
- }
2086
- return { ok: true, complete, aborted, ...(releaseBlocked ? { releaseBlocked } : {}), outcome, replay };
2087
- }
2088
- function extractResumableExhaustionBoundary(metadata) {
2089
- if (!metadata)
2090
- return undefined;
2091
- const reason = metadata.abortReason;
2092
- if (reason !== 'YOLOOP_PER_RUN_CAP_REACHED' && reason !== 'YOLOOP_SESSION_TIMEOUT')
2093
- return undefined;
2094
- const boundary = metadata.yoloopResumableBoundary;
2095
- const boundedId = /^[A-Za-z0-9._:-]{1,128}$/;
2096
- if (!isRecord(boundary)
2097
- || boundary.schemaVersion !== 'YoloopResumableBoundary/1.0'
2098
- || boundary.resumable !== true
2099
- || boundary.reason !== reason
2100
- || boundary.publicSafe !== true
2101
- || typeof boundary.coolDownUntil !== 'string'
2102
- || !Number.isFinite(Date.parse(boundary.coolDownUntil))
2103
- || !Number.isSafeInteger(boundary.retryAfterMs)
2104
- || boundary.retryAfterMs < 0
2105
- || typeof boundary.operationId !== 'string'
2106
- || !boundedId.test(boundary.operationId)
2107
- || !isRecord(boundary.receipt)
2108
- || boundary.receipt.schemaVersion !== 'YoloopSessionRolloverReceipt/1.0'
2109
- || typeof boundary.receipt.runId !== 'string'
2110
- || !boundedId.test(boundary.receipt.runId)
2111
- || boundary.receipt.operationId !== boundary.operationId
2112
- || typeof boundary.receipt.idempotencyKey !== 'string'
2113
- || !boundedId.test(boundary.receipt.idempotencyKey)
2114
- || typeof boundary.receipt.payloadHash !== 'string'
2115
- || !/^[a-f0-9]{64}$/.test(boundary.receipt.payloadHash)
2116
- || boundary.receipt.coolDownUntil !== boundary.coolDownUntil
2117
- || !Number.isSafeInteger(boundary.receipt.revision)
2118
- || boundary.receipt.revision < 0
2119
- || (boundary.receipt.snapshotHash !== null
2120
- && (typeof boundary.receipt.snapshotHash !== 'string'
2121
- || !/^[a-f0-9]{64}$/.test(boundary.receipt.snapshotHash)))
2122
- || boundary.receipt.status !== 'exhausted'
2123
- || boundary.receipt.publicSafe !== true)
2124
- return undefined;
2125
- return { coolDownUntil: boundary.coolDownUntil, reason };
2126
- }
2127
- function buildChildRunYoloDirective(input) {
2128
- const stableBasis = `${input.rootAttempt.execution_id}:${input.child.graphRevision ?? 'legacy'}:${input.child.storyId}`;
2129
- const operationId = input.child.dispatchId ?? headlessExecutionEntityId('child-op', `${stableBasis}:${input.iteration}`);
2130
- const idempotencyKey = input.child.idempotencyKey ?? headlessExecutionEntityId('child-idem', `${stableBasis}:${input.iteration}`);
2131
- return {
2132
- schemaVersion: 1,
2133
- contractVersion: 'continuity-v1',
2134
- kind: 'run_yolo',
2135
- commandClass: input.rootAttempt.command_class === 'goal-tick' ? 'goal-tick' : 'loop-tick',
2136
- jobId: input.rootAttempt.job_id,
2137
- operationId,
2138
- idempotencyKey,
2139
- targetKind: 'story',
2140
- targetRef: input.child.targetRef,
2141
- commandRef: input.child.commandRef,
2142
- ...(input.child.preparationOnly ? { executionMode: 'branchless_child_preparation' } : {}),
2143
- storyId: input.child.storyId,
2144
- runtime: {
2145
- runtimeId: input.runtimeId,
2146
- ...(input.modelId ? { modelId: input.modelId } : {}),
2147
- source: input.runtimeSource ?? 'explicit',
2148
- reasonCode: input.runtimeSource === 'fallback' ? HEADLESS_REASON_CODES.RUNTIME_FALLBACK : HEADLESS_REASON_CODES.RUNTIME_EXPLICIT,
2149
- publicSafe: true,
2150
- },
2151
- publicSummary: `Root-owned yoloop delegated public story ${input.child.storyId}.`,
2152
- reasonCode: HEADLESS_REASON_CODES.OK,
2153
- metadata: {
2154
- governanceSource: 'delegated-subagent',
2155
- parentAttemptId: input.rootAttempt.attempt_id,
2156
- parentExecutionId: input.rootAttempt.execution_id,
2157
- iteration: input.iteration,
2158
- ...(input.child.dispatchId ? { dispatchId: input.child.dispatchId } : {}),
2159
- ...(input.child.graphRevision ? { graphRevision: input.child.graphRevision } : {}),
2160
- ...(input.child.writeSet ? { writeSet: input.child.writeSet } : {}),
2161
- ...(input.child.executionBranch ? { executionBranch: input.child.executionBranch } : {}),
2162
- ...(input.child.graphRevision ? {
2163
- childWorkspace: 'branchless_sandbox',
2164
- epicCheckout: 'current_checkout',
2165
- workspaceLifecycle: 'user_managed',
2166
- integrationOwner: 'root_agent',
2167
- maxDepth: 1,
2168
- } : {}),
2169
- publicSafe: true,
2170
- },
2171
- attempts: [],
2172
- redactionSummary: [redaction('prompt', 'prompt_body', hashPublicValue(input.child.commandRef))],
2173
- publicSafe: true,
2174
- };
2175
- }
2176
- function persistYoloopAttemptOutcome(store, attempt, outcome) {
2177
- const hashes = sanitizePublicRecord(outcome.hashes);
2178
- const workerPoolSummary = outcome.workerPoolSummary ?? defaultWorkerPoolSummary();
2179
- const counts = sanitizePublicRecord({
2180
- iterations: outcome.counts.iterations,
2181
- childCount: outcome.counts.childCount,
2182
- succeededChildCount: outcome.counts.succeededChildCount,
2183
- failedChildCount: outcome.counts.failedChildCount,
2184
- skippedChildCount: outcome.counts.skippedChildCount,
2185
- metadataCompleteCount: outcome.counts.metadataCompleteCount,
2186
- metadataAbortedCount: outcome.counts.metadataAbortedCount,
2187
- serverMaxConcurrency: workerPoolSummary.serverMaxConcurrency,
2188
- localCap: workerPoolSummary.localCap,
2189
- queueCap: workerPoolSummary.queueCap,
2190
- availableLeases: workerPoolSummary.availableLeases,
2191
- effectiveConcurrency: workerPoolSummary.effectiveConcurrency,
2192
- peakConcurrency: workerPoolSummary.peakConcurrency,
2193
- pendingChildCount: workerPoolSummary.pendingChildCount,
2194
- startedChildCount: workerPoolSummary.startedChildCount,
2195
- completedChildCount: workerPoolSummary.completedChildCount,
2196
- backpressurePauseCount: workerPoolSummary.backpressurePauseCount,
2197
- });
2198
- const outcomeMetadata = {
2199
- schemaVersion: 1,
2200
- contractVersion: 'continuity-v1',
2201
- attemptId: attempt.attempt_id,
2202
- executionId: attempt.execution_id,
2203
- jobId: attempt.job_id,
2204
- directiveHash: attempt.directive_hash,
2205
- status: outcome.status,
2206
- reasonCode: outcome.reasonCode,
2207
- storyIds: outcome.childStoryIds.slice(0, 50),
2208
- counts,
2209
- hashes,
2210
- ...(outcome.reasonCode === AUTONOMOUS_GOVERNANCE_REASON_CODES.BYPASS_BLOCKED ? { governanceEvidence: AUTONOMOUS_GOVERNANCE_EVIDENCE_TAG } : {}),
2211
- reasonCodes: unique([outcome.reasonCode, ...workerPoolSummary.reasonCodes, ...outcome.stateTransitions]),
2212
- publicSummary: boundPublicSummary(outcome.publicSummary),
2213
- ...(outcome.terminalClass ? { terminalClass: outcome.terminalClass } : {}),
2214
- ...(outcome.releaseBlocked ? { releaseBlocked: outcome.releaseBlocked } : {}),
2215
- };
2216
- const governance = readAutonomousGovernanceEnvelopeFromMetadata(attempt.metadata_json, {
2217
- autonomousKind: 'run_yoloop',
2218
- jobId: attempt.job_id,
2219
- targetKind: 'epic',
2220
- targetRef: attempt.target_ref,
2221
- });
2222
- // Backoff reuses the same attempt row. Preserve only its already-validated,
2223
- // public-safe authority envelope so the next tick cannot lose authorization
2224
- // when completion metadata replaces the queued metadata.
2225
- const metadata = governance.ok
2226
- ? autonomousGovernanceMetadata(governance.envelope, outcomeMetadata)
2227
- : outcomeMetadata;
2228
- store.completeHeadlessExecutionAttempt({
2229
- attemptId: attempt.attempt_id,
2230
- executionId: attempt.execution_id,
2231
- jobId: attempt.job_id,
2232
- leaseId: outcome.leaseId,
2233
- runnerId: outcome.runnerId,
2234
- status: outcome.status,
2235
- completedAt: outcome.completedAt,
2236
- durationMs: outcome.durationMs,
2237
- reasonCode: outcome.reasonCode,
2238
- publicSummary: boundPublicSummary(outcome.publicSummary),
2239
- notBeforeAt: outcome.notBeforeAt,
2240
- retryCount: outcome.retryCount,
2241
- counts,
2242
- hashes,
2243
- redactionSummary: outcome.redactionSummary,
2244
- relativePaths: unique([attempt.target_ref, ...outcome.relativePaths]),
2245
- metadata,
2246
- });
2247
- store.recordHeadlessExecutionReceipt({
2248
- receiptId: `receipt-${headlessExecutionEntityId('headless-yoloop', `${attempt.attempt_id}-${outcome.status}`)}`,
2249
- attemptId: attempt.attempt_id,
2250
- executionId: attempt.execution_id,
2251
- jobId: attempt.job_id,
2252
- status: outcome.receiptStatus,
2253
- reasonCode: outcome.reasonCode,
2254
- createdAt: outcome.completedAt,
2255
- operationId: `${attempt.execution_id}:${outcome.status}:receipt`,
2256
- idempotencyKey: `${attempt.directive_hash}:${outcome.status}:receipt`,
2257
- counts,
2258
- hashes,
2259
- redactionSummary: outcome.redactionSummary,
2260
- relativePaths: unique([attempt.target_ref, ...outcome.relativePaths]),
2261
- metadata,
2262
- });
2263
- store.recordHeadlessExecutionSummary({
2264
- eventId: `event-${headlessExecutionEntityId('headless-yoloop-summary', `${attempt.attempt_id}-${outcome.status}`)}`,
2265
- attemptId: attempt.attempt_id,
2266
- executionId: attempt.execution_id,
2267
- jobId: attempt.job_id,
2268
- status: outcome.status,
2269
- runtimeId: outcome.runtimeId,
2270
- modelId: outcome.modelId,
2271
- publicSummary: boundPublicSummary(outcome.publicSummary),
2272
- reasonCode: outcome.reasonCode,
2273
- createdAt: outcome.completedAt,
2274
- durationMs: outcome.durationMs,
2275
- counts,
2276
- hashes,
2277
- redactionSummary: outcome.redactionSummary,
2278
- relativePaths: unique([attempt.target_ref, ...outcome.relativePaths]),
2279
- metadata,
2280
- });
2281
- return {
2282
- attemptId: attempt.attempt_id,
2283
- executionId: attempt.execution_id,
2284
- jobId: attempt.job_id,
2285
- status: outcome.status,
2286
- outcome: outcome.receiptStatus,
2287
- reasonCode: outcome.reasonCode,
2288
- timestamp: outcome.completedAt,
2289
- childStoryIds: outcome.childStoryIds,
2290
- aggregateCounts: outcome.counts,
2291
- workerPoolSummary,
2292
- redactionSummary: outcome.redactionSummary,
2293
- ...(outcome.terminalClass ? { terminalClass: outcome.terminalClass } : {}),
2294
- ...(outcome.releaseBlocked ? { releaseBlocked: outcome.releaseBlocked } : {}),
2295
- publicSafe: true,
2296
- };
2297
- }
2298
- function emptyYoloopReceipt(attempt, input) {
2299
- return {
2300
- attemptId: attempt.attempt_id,
2301
- executionId: attempt.execution_id,
2302
- jobId: attempt.job_id,
2303
- status: input.status,
2304
- outcome: input.receiptStatus,
2305
- reasonCode: input.reasonCode,
2306
- timestamp: input.timestamp,
2307
- childStoryIds: [],
2308
- aggregateCounts: emptyAggregateCounts(),
2309
- workerPoolSummary: defaultWorkerPoolSummary(),
2310
- redactionSummary: [],
2311
- publicSafe: true,
2312
- };
2313
- }
2314
- function retryDecision(attempt, result, maxAttempts, backoffMs, nowIso) {
2315
- if (!result.retryable)
2316
- return { retry: false };
2317
- if (RESUMABLE_YOLOOP_BOUNDARY_REASONS.has(result.reasonCode)) {
2318
- return {
2319
- retry: true,
2320
- // A valid operational boundary is a resumable checkpoint, not a failed
2321
- // attempt. Preserve the generic failure budget across any number of
2322
- // server-authorized timeout/per-run successor boundaries.
2323
- retryCount: attempt.retry_count,
2324
- notBeforeAt: laterIsoTimestamp(addMilliseconds(nowIso, backoffMs), result.retryNotBeforeAt),
2325
- };
2326
- }
2327
- const retryCount = attempt.retry_count + 1;
2328
- if (retryCount >= Math.max(1, attempt.max_attempts || maxAttempts))
2329
- return { retry: false, retryCount };
2330
- const multiplier = Math.min(8, 2 ** Math.max(0, attempt.retry_count));
2331
- return {
2332
- retry: true,
2333
- retryCount,
2334
- notBeforeAt: laterIsoTimestamp(addMilliseconds(nowIso, backoffMs * multiplier), result.retryNotBeforeAt),
2335
- };
2336
- }
2337
- function driverResult(input) {
2338
- return {
2339
- status: input.status,
2340
- receiptStatus: input.receiptStatus,
2341
- reasonCode: input.reasonCode,
2342
- publicSummary: input.publicSummary,
2343
- retryable: input.retryable,
2344
- ...(input.retryNotBeforeAt ? { retryNotBeforeAt: input.retryNotBeforeAt } : {}),
2345
- durationMs: Math.max(0, Date.now() - input.startedAt),
2346
- counts: input.counts,
2347
- workerPoolSummary: input.workerPoolSummary ?? defaultWorkerPoolSummary(),
2348
- hashes: input.hashes,
2349
- redactionSummary: input.redactions.slice(0, 50),
2350
- relativePaths: unique(input.relativePaths).slice(0, 50),
2351
- childStoryIds: unique(input.childStoryIds).slice(0, 50),
2352
- stateTransitions: unique(input.stateTransitions),
2353
- ...(input.terminalClass ? { terminalClass: input.terminalClass } : {}),
2354
- ...(input.releaseBlocked ? { releaseBlocked: input.releaseBlocked } : {}),
2355
- };
2356
- }
2357
- function validateDirectiveRuntime(value, redactions) {
2358
- if (value === undefined)
2359
- return undefined;
2360
- if (!isRecord(value)) {
2361
- redactions.push(redaction('runtime', 'unsafe_key', 'value-denied'));
2362
- return undefined;
2363
- }
2364
- for (const key of Object.keys(value)) {
2365
- if (!RUNTIME_ALLOWED_KEYS.has(key) || UNSAFE_KEY_PATTERN.test(key))
2366
- redactions.push(redaction(`runtime.${key}`, unsafeKeyReason(key), 'key-denied'));
2367
- }
2368
- if (value.publicSafe !== true)
2369
- redactions.push(redaction('runtime.publicSafe', 'unsafe_key', 'value-denied'));
2370
- const runtimeId = stringField(value, 'runtimeId');
2371
- const modelId = stringField(value, 'modelId');
2372
- const source = stringField(value, 'source');
2373
- if (runtimeId && (!/^[A-Za-z0-9][A-Za-z0-9._:-]{0,79}$/.test(runtimeId) || UNSAFE_VALUE_PATTERN.test(runtimeId) || SHELL_FRAGMENT_PATTERN.test(runtimeId))) {
2374
- redactions.push(redaction('runtime.runtimeId', 'unsafe_key', 'value-denied'));
2375
- }
2376
- if (modelId && (!/^[A-Za-z0-9][A-Za-z0-9._:+/-]{0,119}$/.test(modelId) || UNSAFE_VALUE_PATTERN.test(modelId) || SHELL_FRAGMENT_PATTERN.test(modelId))) {
2377
- redactions.push(redaction('runtime.modelId', 'unsafe_key', 'value-denied'));
2378
- }
2379
- if (source !== undefined && source !== 'explicit' && source !== 'origin' && source !== 'default' && source !== 'fallback' && source !== 'unspecified') {
2380
- redactions.push(redaction('runtime.source', 'unsafe_key', 'value-denied'));
2381
- }
2382
- if (value.reasonCode !== undefined && (typeof value.reasonCode !== 'string' || UNSAFE_VALUE_PATTERN.test(value.reasonCode))) {
2383
- redactions.push(redaction('runtime.reasonCode', 'unsafe_key', 'value-denied'));
2384
- }
2385
- if (value.publicSafe !== true)
2386
- return undefined;
2387
- return {
2388
- ...(runtimeId ? { runtimeId } : {}),
2389
- ...(modelId ? { modelId } : {}),
2390
- ...(source === 'explicit' || source === 'origin' || source === 'default' || source === 'fallback' || source === 'unspecified' ? { source } : {}),
2391
- ...(typeof value.reasonCode === 'string' ? { reasonCode: value.reasonCode } : {}),
2392
- publicSafe: true,
2393
- };
2394
- }
2395
- function extractExecutionDirectiveCandidates(metadata) {
2396
- const records = Array.isArray(metadata) ? metadata : metadata ? [metadata] : [];
2397
- const directives = [];
2398
- for (const record of records) {
2399
- const value = record.continuityExecutionDirectives;
2400
- if (Array.isArray(value))
2401
- directives.push(...value);
2402
- }
2403
- return directives;
2404
- }
2405
- function hashDirective(directive) {
2406
- return hashPublicValue(stableJson({
2407
- kind: directive.kind,
2408
- commandClass: directive.commandClass,
2409
- jobId: directive.jobId,
2410
- targetRef: directive.targetRef,
2411
- commandRef: directive.commandRef,
2412
- epicId: directive.epicId,
2413
- runtime: directive.runtime,
2414
- }));
2415
- }
2416
- function stableJson(value) {
2417
- if (Array.isArray(value))
2418
- return `[${value.map(stableJson).join(',')}]`;
2419
- if (isRecord(value)) {
2420
- return `{${Object.keys(value).sort().map((key) => `${JSON.stringify(key)}:${stableJson(value[key])}`).join(',')}}`;
2421
- }
2422
- return JSON.stringify(value);
2423
- }
2424
- function assertPublicSafeCandidate(value, path, redactions) {
2425
- if (typeof value === 'string') {
2426
- if (UNSAFE_VALUE_PATTERN.test(value) || SHELL_FRAGMENT_PATTERN.test(value))
2427
- redactions.push(redaction(path, unsafeKeyReason(path), 'value-denied'));
2428
- return;
2429
- }
2430
- if (value === undefined || value === null || typeof value === 'number' || typeof value === 'boolean')
2431
- return;
2432
- if (Array.isArray(value)) {
2433
- value.forEach((item, index) => assertPublicSafeCandidate(item, `${path}.${index}`, redactions));
2434
- return;
2435
- }
2436
- if (isRecord(value)) {
2437
- for (const [key, child] of Object.entries(value)) {
2438
- const field = `${path}.${key}`;
2439
- if (UNSAFE_KEY_PATTERN.test(key))
2440
- redactions.push(redaction(field, unsafeKeyReason(key), 'key-denied'));
2441
- assertPublicSafeCandidate(child, field, redactions);
2442
- }
2443
- return;
2444
- }
2445
- redactions.push(redaction(path, 'unsafe_key', 'value-denied'));
2446
- }
2447
- function validateDirectiveRedactions(value, redactions) {
2448
- if (value === undefined)
2449
- return [];
2450
- if (!Array.isArray(value)) {
2451
- redactions.push(redaction('redactionSummary', 'unsafe_key', 'value-denied'));
2452
- return [];
2453
- }
2454
- const safe = [];
2455
- for (const [index, item] of value.entries()) {
2456
- if (!isRecord(item) || item.publicSafe !== true) {
2457
- redactions.push(redaction(`redactionSummary.${index}`, 'unsafe_key', 'value-denied'));
2458
- continue;
2459
- }
2460
- const field = stringField(item, 'field');
2461
- const reason = stringField(item, 'reason');
2462
- const evidence = stringField(item, 'evidence');
2463
- if (!field || !reason || !evidence || UNSAFE_VALUE_PATTERN.test(field) || UNSAFE_VALUE_PATTERN.test(reason) || UNSAFE_VALUE_PATTERN.test(evidence)) {
2464
- redactions.push(redaction(`redactionSummary.${index}`, 'unsafe_key', 'value-denied'));
2465
- continue;
2466
- }
2467
- safe.push({ field, reason, evidence, publicSafe: true });
2468
- }
2469
- return safe;
2470
- }
2471
- function rejectPromptExtraction(reasonCode, publicSummary, redactionSummary) {
2472
- return { ok: false, reasonCode, publicSummary, redactionSummary };
2473
- }
2474
- function safeStringArray(value) {
2475
- return Array.isArray(value) ? value.filter((item) => typeof item === 'string') : [];
2476
- }
2477
- function isSafeExecutionBranch(value) {
2478
- return value.length > 0 && value.length <= 240 && !value.startsWith('-') && !value.includes('..')
2479
- && !value.includes('\\') && /^[A-Za-z0-9._/-]+$/.test(value);
2480
- }
2481
- function sameStringSet(left, right) {
2482
- return left.length === right.length && new Set(left).size === left.length && left.every((item) => right.includes(item));
2483
- }
2484
- function safeAttemptRelativePaths(attempt) {
2485
- return EPIC_TARGET_PATTERN.test(attempt.target_ref) ? [attempt.target_ref] : [];
2486
- }
2487
- function sanitizePublicRecord(record) {
2488
- if (!record)
2489
- return undefined;
2490
- const output = {};
2491
- for (const [key, value] of Object.entries(record)) {
2492
- if (!/^[A-Za-z0-9_.:-]{1,80}$/.test(key) || UNSAFE_KEY_PATTERN.test(key) || UNSAFE_VALUE_PATTERN.test(key))
2493
- continue;
2494
- if (typeof value === 'string' && UNSAFE_VALUE_PATTERN.test(value))
2495
- continue;
2496
- output[key] = value;
2497
- }
2498
- return Object.keys(output).length > 0 ? output : undefined;
2499
- }
2500
- function emptyAggregateCounts() {
2501
- return aggregateCounts(0, 0, 0, 0, 0, 0, 0);
2502
- }
2503
- function aggregateCounts(iterations, childCount, succeededChildCount, failedChildCount, skippedChildCount, metadataCompleteCount, metadataAbortedCount) {
2504
- return { iterations, childCount, succeededChildCount, failedChildCount, skippedChildCount, metadataCompleteCount, metadataAbortedCount };
2505
- }
2506
- function storyIdFromTargetRef(targetRef) {
2507
- return targetRef.replace(/^docs\/stories\//, '').replace(/\.story\.md$/, '');
2508
- }
2509
- function epicIdFromTargetRef(targetRef) {
2510
- return targetRef.replace(/^docs\/epics\/epic-/, '').replace(/\.md$/, '');
2511
- }
2512
- function isStoryId(value) {
2513
- return /^[A-Za-z0-9][A-Za-z0-9_-]*\.\d+[A-Za-z0-9_-]*$/.test(value) && !UNSAFE_VALUE_PATTERN.test(value) && !SHELL_FRAGMENT_PATTERN.test(value);
2514
- }
2515
- function normalizeRuntimeSource(value) {
2516
- if (value === 'explicit' || value === 'origin' || value === 'default' || value === 'fallback')
2517
- return value;
2518
- return undefined;
2519
- }
2520
- function normalizeStoredRuntimeSource(value) {
2521
- if (value === 'explicit' || value === 'origin' || value === 'default' || value === 'fallback' || value === 'unspecified')
2522
- return value;
2523
- return undefined;
2524
- }
2525
- function unsafeKeyReason(key) {
2526
- if (/prompt|commandRef/i.test(key))
2527
- return 'prompt_body';
2528
- if (/std(?:out|err)|raw|log|transcript|stack/i.test(key))
2529
- return 'raw_log';
2530
- if (/url/i.test(key))
2531
- return 'private_url';
2532
- if (/path|cwd|argv|args|shell|command|binary|executable/i.test(key))
2533
- return 'executable_path';
2534
- if (/secret|token|password|authorization|api[_-]?key|license/i.test(key))
2535
- return 'secret_or_pii';
2536
- return 'unsafe_key';
2537
- }
2538
- function stringField(record, key) {
2539
- return typeof record[key] === 'string' ? record[key] : undefined;
2540
- }
2541
- function isSafeIdentifier(value) {
2542
- return Boolean(value && SAFE_ID_PATTERN.test(value) && !UNSAFE_VALUE_PATTERN.test(value) && !SHELL_FRAGMENT_PATTERN.test(value));
2543
- }
2544
- function isRecord(value) {
2545
- return typeof value === 'object' && value !== null && !Array.isArray(value);
2546
- }
2547
- function defaultHeadlessIdFactory(prefix, attemptId) {
2548
- return headlessExecutionEntityId(prefix, `${attemptId}-${Date.now()}-${randomBytes(4).toString('hex')}`);
2549
- }
2550
- function addMilliseconds(iso, ms) {
2551
- const base = Date.parse(iso);
2552
- return new Date((Number.isFinite(base) ? base : Date.now()) + ms).toISOString();
2553
- }
2554
- function laterIsoTimestamp(left, right) {
2555
- const leftMs = Date.parse(left);
2556
- const rightMs = right ? Date.parse(right) : Number.NaN;
2557
- if (!Number.isFinite(rightMs))
2558
- return left;
2559
- if (!Number.isFinite(leftMs))
2560
- return right;
2561
- return rightMs > leftMs ? right : left;
2562
- }
2563
- function boundedInteger(value, min, max) {
2564
- if (!Number.isFinite(value))
2565
- return min;
2566
- return Math.max(min, Math.min(max, Math.floor(value)));
2567
- }
2568
- function unique(values) {
2569
- return Array.from(new Set(values));
2570
- }
2571
- function uniqueBy(values, key) {
2572
- const seen = new Set();
2573
- const output = [];
2574
- for (const value of values) {
2575
- const itemKey = key(value);
2576
- if (seen.has(itemKey))
2577
- continue;
2578
- seen.add(itemKey);
2579
- output.push(value);
2580
- }
2581
- return output;
2582
- }
10
+ `],{cwd:r.projectRoot,stdio:["ignore","pipe","pipe","ipc"],windowsHide:!0});let c,d=0,l=!1;const y=setTimeout(()=>{l=!0,n.kill()},r.timeoutMs),f=m=>{d+=m.length,d>32*1024*1024&&(l=!0,n.kill())};n.stdout?.on("data",f),n.stderr?.on("data",f),n.on("message",m=>{if(c||!_(m)||typeof m.success!="boolean"||Buffer.byteLength(JSON.stringify(m))>32*1024*1024){l=!0,n.kill();return}c=m});const u={success:!1,errorCode:"headless-root-invoke-failed",error:"The isolated root metadata invocation did not complete.",exitCode:1};n.on("error",()=>{l=!0}),n.on("close",m=>{clearTimeout(y),s(m===0&&!l&&c?c:u)}),n.send({modulePath:o,options:e},m=>{m&&(l=!0,n.kill())})})}async function Pt(e,r=vt){const t=Date.now(),a={args:e.args,projectRoot:e.projectRoot,format:"json",platformTarget:"runner",serverUrl:e.serverUrl,strictReadOnly:e.strictReadOnly},o=await r(a,{projectRoot:e.projectRoot,timeoutMs:e.timeoutMs});return{success:o.success,instructions:o.instructions,metadata:o.metadata,error:o.error,errorCode:o.errorCode,exitCode:o.exitCode,durationMs:Date.now()-t,publicSafe:!0}}async function Rr(e){const r=e.adapterRegistry??Ge(),t=F(e.limit??Qe,1,10),a=F(e.leaseMs??ht,1e3,oe.terminalWorkflowMaxDurationMs),o=F(e.staleLeaseAfterMs??tt,0,1440*60*1e3),s=F(e.maxAttempts??et,1,10),n=F(e.localConcurrencyCap??Te(),1,Pe),c=[],d=[],l=e.now(),y=Tt({store:e.store,metadata:e.metadata,nowIso:l,maxAttempts:s,queueCap:e.queueCap});c.push(...y.reasonCodes);const f=e.store.recoverStaleHeadlessExecutionAttempts({nowIso:l,staleAfterMs:o,limit:t*2});f.recoveredAttemptIds.length>0&&(c.push(p.EXECUTION_BACKOFF),f.failedAttemptIds.length>0&&c.push(p.EXECUTION_TIMEOUT));const u=e.store.listDueHeadlessExecutionAttempts({nowIso:e.now(),limit:Math.max(t*5,10)}).filter(m=>m.directive_kind==="run_yoloop").slice(0,t);for(const m of u){const g=await wt({store:e.store,projectRoot:e.projectRoot,runnerId:e.runnerId,attempt:m,registry:r,now:e.now,leaseMs:a,timeoutMs:F(e.timeoutMs??rt,1e3,oe.terminalWorkflowMaxDurationMs),backoffMs:F(e.backoffMs??Je,1e3,36e5),maxAttempts:s,maxIterations:F(e.maxIterations??ft,1,100),maxDurationMs:F(e.maxDurationMs??yt,1e3,oe.terminalWorkflowMaxDurationMs),localConcurrencyCap:n,queueCap:e.queueCap,adapterOptions:e.adapterOptions,runtimeDefaults:e.runtimeDefaults,runtimeFallback:e.runtimeFallback,yoloopInvoker:e.yoloopInvoker??Pt,serverUrl:e.serverUrl,idFactory:e.idFactory??nr,continuousWorkspaceManager:e.continuousWorkspaceManager??st(),terminalGitAdapter:e.terminalGitAdapter??ct(e.projectRoot)});d.push(g),c.push(g.reasonCode,...g.workerPoolSummary.reasonCodes)}return{ok:d.every(m=>m.outcome!=="failed")&&y.rejectedCount===0,enqueuedAttemptCount:y.enqueuedCount,dueAttemptCount:u.length,processedAttemptCount:d.filter(m=>m.outcome!=="ignored").length,recoveredAttemptIds:f.recoveredAttemptIds,receipts:d,reasonCodes:V(c.length>0?c:[p.OK]),publicSafe:!0}}function Tt(e){let r=0,t=0;const a=[];for(const o of Zt(e.metadata)){if(!_(o)||o.kind!=="run_yoloop")continue;const s=Nt(o);if(!s.ok){t+=1,a.push(s.reasonCode);continue}const n=s.directive;if(!e.store.jobExists(n.jobId)){t+=1,a.push(Ee.BYPASS_BLOCKED);continue}const c=Jt(n);if(e.store.hasCompletedHeadlessExecutionDirectiveHash(c)){a.push(p.EXECUTION_COMPLETED);continue}const d=qe({autonomousKind:"run_yoloop",source:"headless-run-yoloop",targetKind:"epic",targetRef:n.targetRef,epicId:n.epicId??se(n.targetRef),jobId:n.jobId,operationSeed:n.operationId,commandHash:x(n.commandRef)}),l=We(e.store,d,e.nowIso,{requireExistingJob:!0});if(!l.ok){t+=1,a.push(l.reasonCode);continue}const y=q("attempt",n.idempotencyKey),f=q("exec",n.operationId),u=e.store.enqueueHeadlessExecutionAttempt({attemptId:y,executionId:f,jobId:n.jobId,directiveHash:c,directiveKind:"run_yoloop",commandClass:n.commandClass,targetKind:"epic",targetRef:n.targetRef,epicId:n.epicId??se(n.targetRef),runtimeId:n.runtime?.runtimeId,modelId:n.runtime?.modelId,runtimeSource:ar(n.runtime?.source),reasonCode:n.reasonCode,publicSummary:n.publicSummary,enqueuedAt:e.nowIso,notBeforeAt:e.nowIso,maxAttempts:e.maxAttempts,queueCap:e.queueCap,operationId:`${n.operationId}:enqueue`,idempotencyKey:n.idempotencyKey,counts:{directives:1},hashes:{directive:c},redactionSummary:n.redactionSummary,relativePaths:[n.targetRef],metadata:Re(d,{schemaVersion:1,contractVersion:"continuity-v1",jobId:n.jobId,operationId:n.operationId,reasonCode:n.reasonCode??p.OK,targetRef:n.targetRef,directiveHash:c})});if(!u.accepted){t+=1,a.push(u.reasonCode??"queue-cap-reached");continue}u.inserted&&(r+=1),a.push(p.OK)}return{enqueuedCount:r,rejectedCount:t,reasonCodes:V(a)}}async function wt(e){const r=e.now(),t=e.idFactory("lease",e.attempt.attempt_id),a=ge(r,e.leaseMs);if(!e.store.claimHeadlessExecutionAttempt({attemptId:e.attempt.attempt_id,leaseId:t,runnerId:e.runnerId,claimedAt:r,leaseExpiresAt:a,reasonCode:p.OK}).inserted)return Wt(e.attempt,{status:e.attempt.status,receiptStatus:"ignored",reasonCode:"lease-conflict",timestamp:r});if(e.store.hasCompletedHeadlessExecutionDirectiveHash(e.attempt.directive_hash,e.attempt.attempt_id))return Ce(e.store,e.attempt,{leaseId:t,runnerId:e.runnerId,status:"skipped",receiptStatus:"ignored",reasonCode:p.EXECUTION_COMPLETED,publicSummary:"Skipped duplicate run_yoloop directive because the directive hash is already completed.",completedAt:e.now(),counts:be(),hashes:{directive:e.attempt.directive_hash},redactionSummary:[],relativePaths:[e.attempt.target_ref],childStoryIds:[],stateTransitions:["start","complete"]});const n=Lt(e);if(!n.ok)return Ce(e.store,e.attempt,{leaseId:t,runnerId:e.runnerId,status:n.status,receiptStatus:n.receiptStatus,reasonCode:n.reasonCode,publicSummary:n.publicSummary,completedAt:e.now(),counts:be(),hashes:{directive:e.attempt.directive_hash},redactionSummary:n.redactionSummary,relativePaths:tr(e.attempt),childStoryIds:[],stateTransitions:["start"]});const c=await xt({...e,prepared:n.input}),d=Gt(e.attempt,c,e.maxAttempts,e.backoffMs,e.now()),l=d.retry?"backoff":c.status,y=d.retry?"deferred":c.receiptStatus,f=d.retry?Rt.has(c.reasonCode)||xe.has(c.reasonCode)?c.reasonCode:p.EXECUTION_BACKOFF:c.reasonCode,u=d.retry?"Headless run_yoloop execution scheduled bounded retry after transient metadata/runtime outcome.":c.publicSummary;return Ce(e.store,e.attempt,{leaseId:t,runnerId:e.runnerId,status:l,receiptStatus:y,reasonCode:f,publicSummary:u,completedAt:e.now(),durationMs:c.durationMs,notBeforeAt:d.notBeforeAt,retryCount:d.retryCount,counts:c.counts,workerPoolSummary:c.workerPoolSummary,hashes:{...c.hashes,directive:e.attempt.directive_hash},redactionSummary:c.redactionSummary,relativePaths:c.relativePaths,childStoryIds:c.childStoryIds,runtimeId:n.input.runtimeId,modelId:n.input.modelId,runtimeSource:n.input.runtimeSource,stateTransitions:c.stateTransitions,terminalClass:c.terminalClass,releaseBlocked:c.releaseBlocked})}async function xt(e){const r=Date.now(),t=["start"],a=new Set,o=[],s=[],n={root:x(e.prepared.rootPrompt)},c=[h("rootPrompt","prompt_body",n.root)];let d=0,l=0,y=0,f=0,u=0,m=0,g,P=!1;const i=Me(e.localConcurrencyCap),E=new Map;let j=!1;const K=new Map,z=new Map,ie=T=>{const b=T.child;n[`child-${b.storyId.replace(/[^A-Za-z0-9_.:-]/g,"-")}`]=T.commandHash,c.push(T.promptRedaction);const M=T.receipt;if(T.terminalFailure){if(T.deferredFailure){K.set(b.storyId,T.terminalFailure),i.backpressurePauseCount+=1;return}K.delete(b.storyId),z.set(b.storyId,T.terminalFailure),a.has(b.storyId)||(a.add(b.storyId),o.push(b.storyId),s.push(b.targetRef),y+=1);return}if(!M||M.outcome==="deferred"){K.set(b.storyId,T.reasonCodes.includes("queue-cap-reached")?p.WORKER_POOL_BACKPRESSURE_PAUSED:M?.reasonCode||p.EXECUTION_BACKOFF),T.reasonCodes.includes("queue-cap-reached")&&(i.backpressurePauseCount+=1);return}K.delete(b.storyId),!a.has(b.storyId)&&(a.add(b.storyId),o.push(b.storyId),s.push(b.targetRef),M.outcome==="failed"?(y+=1,z.set(b.storyId,M.reasonCode||p.EXECUTION_FAILED)):M.outcome==="ignored"?f+=1:l+=1)},X=async()=>{const T=await Promise.race([...E.entries()].map(([b,M])=>M.promise.then(S=>({storyId:b,result:S}))));E.delete(T.storyId),i.completedChildCount+=1,i.pendingChildCount=E.size,ie(T.result)};for(;;){if(d>=e.maxIterations)return t.push("backoff"),O({status:"failed",receiptStatus:"failed",reasonCode:Ot,publicSummary:"Headless yoloop reached the bounded iteration limit before completion metadata.",retryable:!1,startedAt:r,counts:k(d,o.length,l,y,f,u,m),workerPoolSummary:A(i),hashes:n,redactions:c,relativePaths:[e.prepared.targetRef,...s],childStoryIds:o,stateTransitions:t});if(Date.now()-r>e.maxDurationMs)return t.push("backoff"),O({status:"failed",receiptStatus:"failed",reasonCode:Et,publicSummary:"Headless yoloop reached the bounded duration limit before completion metadata.",retryable:!1,startedAt:r,counts:k(d,o.length,l,y,f,u,m),workerPoolSummary:A(i),hashes:n,redactions:c,relativePaths:[e.prepared.targetRef,...s],childStoryIds:o,stateTransitions:t});t.push("metadata_parse");const T=await e.yoloopInvoker({projectRoot:e.projectRoot,args:e.prepared.rootPrompt,attemptId:e.attempt.attempt_id,executionId:e.attempt.execution_id,jobId:e.attempt.job_id,runnerId:e.runnerId,iteration:d,runtimeId:e.prepared.runtimeId,...e.prepared.modelId?{modelId:e.prepared.modelId}:{},timeoutMs:e.timeoutMs,serverUrl:e.serverUrl});T.durationMs!==void 0&&(n[`iter-${d}`]=x(String(T.durationMs)));const b=T.metadata,M=T.errorCode==="YOLOOP_RELEASE_BLOCKED"||b?.yoloopReleaseBlocked===!0||b?.terminalClass==="release-blocked"||b?.releaseBlocked!==void 0;if(!T.success&&!M)return t.push("backoff"),O({status:"backoff",receiptStatus:"deferred",reasonCode:p.EXECUTION_FAILED,publicSummary:"Headless yoloop root metadata invocation failed with bounded public evidence.",retryable:!0,startedAt:r,counts:k(d,o.length,l,y,f,u,m),workerPoolSummary:A(i),hashes:n,redactions:c,relativePaths:[e.prepared.targetRef,...s],childStoryIds:o,stateTransitions:t});const S=Ft(b);if(!S.ok)return t.push("backoff"),O({status:"failed",receiptStatus:"failed",reasonCode:S.reasonCode,publicSummary:S.publicSummary,retryable:!1,startedAt:r,counts:k(d,o.length,l,y,f,u,m),workerPoolSummary:A(i),hashes:n,redactions:[...c,...S.redactionSummary],relativePaths:[e.prepared.targetRef,...s],childStoryIds:o,stateTransitions:t});const I=Vt(b);if(S.aborted&&I){for(;E.size>0;)await X();return m+=1,t.push("backoff"),O({status:"backoff",receiptStatus:"deferred",reasonCode:I.reason==="YOLOOP_SESSION_TIMEOUT"?"yoloop-session-timeout-resumable":"yoloop-per-run-cap-resumable",publicSummary:"Headless yoloop reached a finite run boundary and scheduled the same queue after cool-down.",retryable:!0,retryNotBeforeAt:I.coolDownUntil,startedAt:r,counts:k(d+1,o.length,l,y,f,u,m),workerPoolSummary:A(i),hashes:n,redactions:c,relativePaths:[e.prepared.targetRef,...s],childStoryIds:o,stateTransitions:t})}if((S.releaseBlocked||S.aborted||S.complete||S.replay||S.outcome&&S.outcome!=="selected"&&S.outcome!=="queue_exhausted")&&j&&E.size>0){await X(),d+=1,t.push("reinvoke");continue}if(S.releaseBlocked)return t.push("release_blocked"),O({status:"failed",receiptStatus:"failed",reasonCode:"yoloop-release-blocked",publicSummary:"Headless yoloop stopped at a terminal release-blocked boundary without declaring success.",retryable:!1,startedAt:r,counts:k(d+1,o.length,l,y,f,u,m),workerPoolSummary:A(i),hashes:{...n,releaseBlocked:x(S.releaseBlocked.resultId)},redactions:c,relativePaths:[e.prepared.targetRef,...s],childStoryIds:o,stateTransitions:t,terminalClass:"release-blocked",releaseBlocked:S.releaseBlocked});const $=_(b?.epicIntegration)?b.epicIntegration:void 0,ee=Array.isArray($?.reasonCodes)?$.reasonCodes.filter(C=>typeof C=="string"):[];if(S.aborted&&b?.abortReason==="epic-integration-checkpoints-incomplete"&&$?.required===!0&&$.ready===!1&&ee.length>0&&ee.every(C=>C==="epic-aggregate-qa-receipt-required"||C==="epic-origin-binding-required"||/^missing-story-checkpoint:[A-Za-z0-9._-]+$/.test(C))&&e.terminalGitAdapter.prepareLifecycleEvidence){t.push("lifecycle_evidence");const C=await e.terminalGitAdapter.prepareLifecycleEvidence({epicId:e.prepared.epicId,nowIso:e.now()});if(!C.ok)return t.push("backoff"),O({status:C.retryEligible?"backoff":"failed",receiptStatus:C.retryEligible?"deferred":"failed",reasonCode:C.reasonCode,publicSummary:"Headless yoloop stopped because physical Git lifecycle evidence could not be produced safely.",retryable:C.retryEligible,startedAt:r,counts:k(d+1,o.length,l,y,f,u,m),workerPoolSummary:A(i),hashes:n,redactions:c,relativePaths:[e.prepared.targetRef,...s],childStoryIds:o,stateTransitions:t});g=C.terminalAuthority??C.p205Authority,P=!0,d+=1,t.push("reinvoke");continue}if(S.aborted)return m+=1,t.push("aborted"),O({status:"failed",receiptStatus:"failed",reasonCode:kt,publicSummary:"Headless yoloop stopped because public metadata reported an aborted loop.",retryable:!1,startedAt:r,counts:k(d+1,o.length,l,y,f,u,m),workerPoolSummary:A(i),hashes:n,redactions:c,relativePaths:[e.prepared.targetRef,...s],childStoryIds:o,stateTransitions:t});if(S.outcome&&S.outcome!=="selected"&&S.outcome!=="queue_exhausted")return t.push("backoff"),O({status:"failed",receiptStatus:"failed",reasonCode:`yoloop-${S.outcome}`,publicSummary:"Headless yoloop stopped on a non-executable graph-first continuation outcome.",retryable:!1,startedAt:r,counts:k(d+1,o.length,l,y,f,u,m),workerPoolSummary:A(i),hashes:n,redactions:c,relativePaths:[e.prepared.targetRef,...s],childStoryIds:o,stateTransitions:t});if(S.replay)return t.push("backoff"),O({status:"backoff",receiptStatus:"deferred",reasonCode:"yoloop-replay-pending",publicSummary:"Headless yoloop observed pending replay authority and did not delegate a second child.",retryable:!0,startedAt:r,counts:k(d+1,o.length,l,y,f,u,m),workerPoolSummary:A(i),hashes:n,redactions:c,relativePaths:[e.prepared.targetRef,...s],childStoryIds:o,stateTransitions:t});if(S.complete&&j&&K.size>0&&z.size===0)return t.push("backoff"),O({status:"backoff",receiptStatus:"deferred",reasonCode:[...K.values()].sort()[0],publicSummary:"Headless yoloop rejected terminal completion while previously runnable work remained undispatched.",retryable:!0,startedAt:r,counts:k(d+1,o.length,l,y,f,u,m),workerPoolSummary:A(i),hashes:n,redactions:c,relativePaths:[e.prepared.targetRef,...s],childStoryIds:o,stateTransitions:t});if(S.complete&&j&&z.size>0)return t.push("backoff"),O({status:"failed",receiptStatus:"failed",reasonCode:[...z.values()].sort()[0],publicSummary:"Headless yoloop rejected terminal completion because runnable work failed before an accepted dispatch receipt.",retryable:!1,startedAt:r,counts:k(d+1,o.length,l,y,f,u,m),workerPoolSummary:A(i),hashes:n,redactions:c,relativePaths:[e.prepared.targetRef,...s],childStoryIds:o,stateTransitions:t});const ce=$t(b);if(ce){if(!P&&e.terminalGitAdapter.prepareLifecycleEvidence){t.push("lifecycle_evidence");const R=await e.terminalGitAdapter.prepareLifecycleEvidence({epicId:e.prepared.epicId,nowIso:e.now()});if(!R.ok)return t.push("backoff"),O({status:R.retryEligible?"backoff":"failed",receiptStatus:R.retryEligible?"deferred":"failed",reasonCode:R.reasonCode,publicSummary:"Headless yoloop stopped because physical Git lifecycle evidence could not be produced safely.",retryable:R.retryEligible,startedAt:r,counts:k(d,o.length,l,y,f,u,m),workerPoolSummary:A(i),hashes:n,redactions:c,relativePaths:[e.prepared.targetRef,...s],childStoryIds:o,stateTransitions:t});g=R.terminalAuthority??R.p205Authority,P=!0}t.push("terminal_git");const C=new Date,L=await lt(e.projectRoot,{kind:"continuous",storyId:ce.epicId,sessionId:`${e.runnerId}:${e.attempt.attempt_id}`,idempotencyKey:ce.idempotencyKey,persistent:!1,expiresAt:new Date(C.getTime()+Math.max(e.timeoutMs,e.maxDurationMs)+6e4).toISOString()});if(!L.ok)return t.push("backoff"),O({status:"backoff",receiptStatus:"deferred",reasonCode:L.reasonCode,publicSummary:"Headless yoloop deferred terminal Git while another physical writer retained authority.",retryable:!0,startedAt:r,counts:k(d+1,o.length,l,y,f,u,m),workerPoolSummary:A(i),hashes:n,redactions:c,relativePaths:[e.prepared.targetRef,...s],childStoryIds:o,stateTransitions:t});let U,H=!1;try{U=await dt(ce,e.terminalGitAdapter,e.now,g)}finally{H=await ut(L.path,L.owner).catch(()=>!1)}if(!H)return t.push("backoff"),O({status:"backoff",receiptStatus:"deferred",reasonCode:"git-lifecycle-integration-lock-release-failed",publicSummary:"Headless yoloop stopped because terminal Git writer ownership could not be released safely.",retryable:!0,startedAt:r,counts:k(d+1,o.length,l,y,f,u,m),workerPoolSummary:A(i),hashes:n,redactions:c,relativePaths:[e.prepared.targetRef,...s],childStoryIds:o,stateTransitions:t});if(n[`terminal-git-${d}`]=x(`${U.receipt.idempotencyKey}:${U.receipt.physicalStatus}`),!U.ok){const R=U.receipt.retryEligible;return t.push("backoff"),O({status:R?"backoff":"failed",receiptStatus:R?"deferred":"failed",reasonCode:U.reasonCodes[0]??"epic-terminal-git-failed",publicSummary:"Headless yoloop stopped at the epic terminal Git boundary with public-safe retry evidence.",retryable:R,startedAt:r,counts:k(d+1,o.length,l,y,f,u,m),workerPoolSummary:A(i),hashes:n,redactions:c,relativePaths:[e.prepared.targetRef,...s],childStoryIds:o,stateTransitions:t})}if(g=void 0,P=!1,S.complete)return u+=1,t.push("complete"),O({status:"completed",receiptStatus:"applied",reasonCode:p.EXECUTION_COMPLETED,publicSummary:"Headless yoloop completed only after fresh root-owned physical Git verification.",retryable:!1,startedAt:r,counts:k(d+1,o.length,l,y,f,u,m),workerPoolSummary:A(i),hashes:n,redactions:c,relativePaths:[e.prepared.targetRef,...s],childStoryIds:o,stateTransitions:t});d+=1,t.push("reinvoke");continue}if(S.complete)return u+=1,t.push("complete"),O({status:"completed",receiptStatus:"applied",reasonCode:p.EXECUTION_COMPLETED,publicSummary:"Headless yoloop completed after public metadata reported yoloopComplete.",retryable:!1,startedAt:r,counts:k(d+1,o.length,l,y,f,u,m),workerPoolSummary:A(i),hashes:n,redactions:c,relativePaths:[e.prepared.targetRef,...s],childStoryIds:o,stateTransitions:t});const pe=Yt(b);if(pe){t.push("git_reconciliation");const C=await it(pe,e.terminalGitAdapter,e.now);if(n[`git-reconciliation-${d}`]=x(`${pe.idempotencyKey}:${C.reasonCodes.join(",")}`),!C.ok)return t.push("backoff"),O({status:"backoff",receiptStatus:"deferred",reasonCode:C.reasonCodes[0]??"git-reconciliation-failed",publicSummary:"Headless yoloop paused at a fail-closed Git reconciliation boundary.",retryable:!0,startedAt:r,counts:k(d+1,o.length,l,y,f,u,m),workerPoolSummary:A(i),hashes:n,redactions:c,relativePaths:[e.prepared.targetRef,...s],childStoryIds:o,stateTransitions:t})}const N=Bt(b,e.prepared.epicId);if(!N.ok)return t.push("backoff"),O({status:"failed",receiptStatus:"failed",reasonCode:N.reasonCode,publicSummary:N.publicSummary,retryable:!1,startedAt:r,counts:k(d+1,o.length,l,y,f,u,m),workerPoolSummary:A(i),hashes:n,redactions:[...c,...N.redactionSummary],relativePaths:[e.prepared.targetRef,...s],childStoryIds:o,stateTransitions:t});const Ae=N.continuous?void 0:N.prompts.find(C=>a.has(C.storyId));if(Ae)return t.push("backoff"),O({status:"failed",receiptStatus:"failed",reasonCode:p.YOLOOP_ISOLATION_VIOLATION,publicSummary:"Headless yoloop rejected cyclic child story delegation evidence.",retryable:!1,startedAt:r,counts:k(d+1,o.length,l,y,f,u,m),workerPoolSummary:A(i),hashes:n,redactions:[...c,h("storyId","prompt_body",x(Ae.storyId))],relativePaths:[e.prepared.targetRef,...s],childStoryIds:o,stateTransitions:t});if(i.mode=N.mode==="continuous_dag"?"continuous_dag":N.parallelAuthorized?"parallel_wave":"serial",i.serverMaxConcurrency=N.serverMaxConcurrency,N.continuous){j=!0;const C=N.prompts.filter(L=>!a.has(L.storyId)&&!E.has(L.storyId));if(i.pendingChildCount=C.length+E.size,C.length>0){const L=De({store:e.store,nowIso:e.now(),localCap:e.localConcurrencyCap,serverMaxConcurrency:N.serverMaxConcurrency,parallelAuthorized:!0,continuous:!0,eligibleCount:C.length});if(i.queueCap=L.queueCap,i.availableLeases=L.availableLeases,i.effectiveConcurrency=L.effectiveConcurrency,i.reasonCodes.push(L.reasonCode),L.effectiveConcurrency===0&&E.size===0)return i.backpressurePauseCount+=1,t.push("backoff"),O({status:"backoff",receiptStatus:"deferred",reasonCode:p.WORKER_POOL_BACKPRESSURE_PAUSED,publicSummary:"Headless yoloop retained its eligible frontier while physical worker capacity was unavailable.",retryable:!0,startedAt:r,counts:k(d+1,o.length,l,y,f,u,m),workerPoolSummary:A(i),hashes:n,redactions:c,relativePaths:[e.prepared.targetRef,...s],childStoryIds:o,stateTransitions:t});const U=C.slice(0,L.effectiveConcurrency);t.push("child_story_delegation");for(const H of U)E.set(H.storyId,{child:H,promise:Le({...e,child:H,iteration:d})});i.startedChildCount+=U.length,i.peakConcurrency=Math.max(i.peakConcurrency,E.size),i.pendingChildCount=C.length-U.length+E.size}if(E.size>0)await X();else{if(K.size>0)return t.push("backoff"),O({status:"backoff",receiptStatus:"deferred",reasonCode:[...K.values()].sort()[0],publicSummary:"Headless yoloop retained deferred continuous work for a bounded retry.",retryable:!0,startedAt:r,counts:k(d+1,o.length,l,y,f,u,m),workerPoolSummary:A(i),hashes:n,redactions:c,relativePaths:[e.prepared.targetRef,...s],childStoryIds:o,stateTransitions:t});if(z.size>0)return t.push("backoff"),O({status:"failed",receiptStatus:"failed",reasonCode:[...z.values()].sort()[0],publicSummary:"Headless yoloop completed independent work and stopped on the remaining failed dependency closure.",retryable:!1,startedAt:r,counts:k(d+1,o.length,l,y,f,u,m),workerPoolSummary:A(i),hashes:n,redactions:c,relativePaths:[e.prepared.targetRef,...s],childStoryIds:o,stateTransitions:t})}d+=1,t.push("reinvoke");continue}i.pendingChildCount=N.prompts.length;const te=[...N.prompts];for(;te.length>0;){const C=De({store:e.store,nowIso:e.now(),localCap:e.localConcurrencyCap,serverMaxConcurrency:N.serverMaxConcurrency,parallelAuthorized:N.parallelAuthorized,continuous:!1,eligibleCount:te.length});if(i.queueCap=C.queueCap,i.availableLeases=C.availableLeases,i.effectiveConcurrency=C.effectiveConcurrency,i.reasonCodes.push(C.reasonCode),C.effectiveConcurrency===0)return i.backpressurePauseCount+=1,i.pendingChildCount=te.length,t.push("backoff"),O({status:"backoff",receiptStatus:"deferred",reasonCode:p.WORKER_POOL_BACKPRESSURE_PAUSED,publicSummary:"Headless yoloop paused child workers because bounded queue or lease capacity was unavailable.",retryable:!0,startedAt:r,counts:k(d+1,o.length,l,y,f,u,m),workerPoolSummary:A(i),hashes:n,redactions:c,relativePaths:[e.prepared.targetRef,...s],childStoryIds:o,stateTransitions:t});const L=te.splice(0,C.effectiveConcurrency);i.startedChildCount+=L.length,i.peakConcurrency=Math.max(i.peakConcurrency,L.length),i.pendingChildCount=te.length,t.push("child_story_delegation");const U=await Promise.all(L.map(R=>Le({...e,child:R,iteration:d})));i.completedChildCount+=U.length;let H;for(const R of U){const le=R.child;n[`child-${le.storyId.replace(/[^A-Za-z0-9_.:-]/g,"-")}`]=R.commandHash,c.push(R.promptRedaction),o.push(le.storyId),s.push(le.targetRef),a.add(le.storyId);const re=R.receipt;if(!re){R.reasonCodes.includes("queue-cap-reached")?(i.backpressurePauseCount+=1,i.pendingChildCount+=1,i.reasonCodes.push(p.WORKER_POOL_BACKPRESSURE_PAUSED),H??={kind:"deferred",reasonCode:p.WORKER_POOL_BACKPRESSURE_PAUSED}):(y+=1,H??={kind:"missing",reasonCode:p.EXECUTION_FAILED});continue}if(re.outcome==="deferred"){H??={kind:"deferred",reasonCode:p.EXECUTION_BACKOFF};continue}if(re.outcome==="failed"){y+=1,H??={kind:"failed",reasonCode:re.reasonCode||p.EXECUTION_FAILED};continue}re.outcome==="ignored"?f+=1:l+=1}if(H){const R=H.kind==="deferred";return O({status:R?"backoff":"failed",receiptStatus:R?"deferred":"failed",reasonCode:H.reasonCode,publicSummary:H.kind==="missing"?"Headless yoloop child story delegation did not produce a public receipt.":R?"Headless yoloop child story delegated bounded backoff to the root attempt.":"Headless yoloop child story execution failed with public receipt evidence.",retryable:R,startedAt:r,counts:k(d+1,o.length,l,y,f,u,m),workerPoolSummary:A(i),hashes:n,redactions:c,relativePaths:[e.prepared.targetRef,...s],childStoryIds:o,stateTransitions:t})}}d+=1,t.push("reinvoke")}}async function Le(e){const r=e.child.dispatchId?await e.continuousWorkspaceManager.prepare({projectRoot:e.projectRoot,epicId:e.prepared.epicId,storyId:e.child.storyId,targetRef:e.child.targetRef,dispatchId:e.child.dispatchId,executionBranch:e.child.executionBranch??"",graphRevision:e.child.graphRevision??"",authorizedWriteSet:e.child.writeSet??[]}):void 0;if(r&&!r.ok)return{child:e.child,reasonCodes:[r.reasonCode],commandHash:x(e.child.commandRef),promptRedaction:h(`child.${e.child.storyId}`,"prompt_body",x(e.child.commandRef)),terminalFailure:r.reasonCode,deferredFailure:/backpressure|lease-active/.test(r.reasonCode)};const t=e.projectRoot,a=r?.ok?nt(r.value):e.adapterOptions?.commandRunner,o=qt({rootAttempt:e.attempt,child:e.child,iteration:e.iteration,runtimeId:e.prepared.runtimeId,modelId:e.prepared.modelId,runtimeSource:e.prepared.runtimeSource}),s=q("attempt",o.idempotencyKey);let n=!!r;try{const c=await ot({store:e.store,projectRoot:t,runnerId:e.runnerId,now:e.now,metadata:{continuityExecutionDirectives:[o]},adapterRegistry:e.registry,adapterOptions:{...e.adapterOptions,cwd:t,env:{...e.adapterOptions?.env,...r?.ok?{NEOCORTEX_BRANCHLESS_PROJECT_ROOT:r.value.workspacePath,NEOCORTEX_BRANCHLESS_ROOT_AUTHORITY:JSON.stringify(e.child.rootAuthority)}:{}},...a?{commandRunner:a,versionRunner:a}:{}},runtimeDefaults:e.runtimeDefaults,runtimeFallback:e.runtimeFallback,timeoutMs:e.timeoutMs,maxAttempts:1,limit:1,queueCap:e.queueCap,attemptIds:[s],idFactory:e.idFactory}),d=c.receipts.find(l=>l.attemptId===s)??c.receipts[0];if(r?.ok&&d&&d.outcome!=="failed"&&d.outcome!=="deferred"){const l=await e.continuousWorkspaceManager.integrate(r.value,{receiptRefs:[`continuity:${d.attemptId}`],nowIso:d.timestamp});if(!l.ok)return{child:e.child,receipt:d,reasonCodes:[...c.reasonCodes,l.reasonCode],commandHash:x(e.child.commandRef),promptRedaction:h(`child.${e.child.storyId}`,"prompt_body",x(e.child.commandRef)),terminalFailure:l.reasonCode,deferredFailure:/backpressure|graph-revision-stale/.test(l.reasonCode)};n=!1}return{child:e.child,receipt:d,reasonCodes:c.reasonCodes,commandHash:x(e.child.commandRef),promptRedaction:h(`child.${e.child.storyId}`,"prompt_body",x(e.child.commandRef))}}finally{r?.ok&&await e.continuousWorkspaceManager.release(r.value,n)}}function De(e){const r=e.store.collectSnapshotRows({nowIso:e.nowIso,jobLimit:1,staleLeaseLimit:1,receiptLimit:1,eventLimit:1,snapshotLimit:1}),t=Math.max(1,Math.floor(r.queue.capacity)),a=Math.max(0,Math.floor(r.queue.running)-1),o=e.continuous?Math.max(0,Math.floor(r.queue.available)):Math.max(0,Math.min(Math.max(0,e.localCap-a),Math.floor(r.queue.available))),s=e.parallelAuthorized?Math.max(1,Math.floor(e.serverMaxConcurrency)):1,n=Math.max(0,Math.min(e.eligibleCount,s,e.localCap,t,o));return{queueCap:t,availableLeases:o,effectiveConcurrency:n,reasonCode:n===0?p.WORKER_POOL_BACKPRESSURE_PAUSED:(e.parallelAuthorized||e.continuous)&&n>1?p.WORKER_POOL_PARALLEL_ACTIVE:p.WORKER_POOL_SERIAL_FALLBACK}}function Me(e){return{mode:"serial",serverMaxConcurrency:1,localCap:e,queueCap:1,availableLeases:1,effectiveConcurrency:1,peakConcurrency:0,pendingChildCount:0,startedChildCount:0,completedChildCount:0,backpressurePauseCount:0,reasonCodes:[]}}function A(e){return{mode:e.mode,serverMaxConcurrency:Y(e.serverMaxConcurrency),localCap:Y(e.localCap),queueCap:Y(e.queueCap),availableLeases:Y(e.availableLeases),effectiveConcurrency:Y(e.effectiveConcurrency),peakConcurrency:Y(e.peakConcurrency),pendingChildCount:Y(e.pendingChildCount),startedChildCount:Y(e.startedChildCount),completedChildCount:Y(e.completedChildCount),backpressurePauseCount:Y(e.backpressurePauseCount),reasonCodes:V(e.reasonCodes.length>0?e.reasonCodes:[p.WORKER_POOL_SERIAL_FALLBACK]).slice(0,10),publicSafe:!0}}function _e(e=Te()){return A(Me(e))}function Y(e){return Number.isFinite(e)?Math.max(0,Math.min(1e4,Math.floor(e))):0}function Lt(e){const r=ve(e.attempt.metadata_json,{autonomousKind:"run_yoloop",jobId:e.attempt.job_id,targetKind:"epic",targetRef:e.attempt.target_ref});if(!r.ok)return{ok:!1,status:"failed",receiptStatus:"failed",reasonCode:r.reasonCode,publicSummary:r.publicSummary,redactionSummary:r.redactionSummary};const t=Dt(e.attempt);if(!t.ok)return t;const a=Mt(e);if(!a.ok)return{ok:!1,status:"failed",receiptStatus:"failed",reasonCode:a.reasonCode,publicSummary:a.publicSummary,redactionSummary:a.redactionSummary};const o=e.attempt.epic_id??se(e.attempt.target_ref);return{ok:!0,input:{rootPrompt:`*yoloop @${e.attempt.target_ref}`,targetRef:e.attempt.target_ref,epicId:o,runtimeId:a.runtimeId,...a.modelId?{modelId:a.modelId}:{},runtimeSource:a.runtimeSource,publicSafe:!0}}}function Dt(e){const r=[];e.directive_kind!=="run_yoloop"&&r.push(h("directiveKind","unsafe_key","value-denied")),e.target_kind!=="epic"&&r.push(h("targetKind","prompt_body","value-denied")),(!ye.test(e.target_ref)||W.test(e.target_ref)||D.test(e.target_ref))&&r.push(h("targetRef","prompt_body","value-denied"));const t=se(e.target_ref);return e.epic_id&&e.epic_id!==t&&r.push(h("epicId","prompt_body","value-denied")),r.length>0?{ok:!1,status:"failed",receiptStatus:"failed",reasonCode:p.PROMPT_REJECTED,publicSummary:"Headless run_yoloop attempt did not match the canonical public epic prompt shape.",redactionSummary:r}:{ok:!0,input:{rootPrompt:`*yoloop @${e.target_ref}`,targetRef:e.target_ref,epicId:t,runtimeId:"fake",publicSafe:!0}}}function Mt(e){const r=e.runtimeDefaults!==void 0?e.runtimeDefaults:Xe({projectRoot:e.projectRoot});if(_(r)&&r.ok===!1)return{ok:!1,reasonCode:p.RUNTIME_UNTRUSTED,publicSummary:typeof r.publicSummary=="string"?r.publicSummary:"Headless runtime defaults failed public-safety validation.",redactionSummary:Array.isArray(r.redactionSummary)?r.redactionSummary:[]};const t=or(e.attempt.runtime_source)??"explicit",a=e.attempt.runtime_id||e.attempt.model_id?{...e.attempt.runtime_id?{runtimeId:e.attempt.runtime_id}:{},...e.attempt.model_id?{modelId:e.attempt.model_id}:{},source:t,publicSafe:!0}:void 0,o={registry:e.registry,defaults:r,fallback:e.runtimeFallback};a&&(t==="origin"?o.origin=a:t==="default"?o.projectDefault=a:t==="fallback"?o.fallback=a:o.explicit=a);const s=Ze(o);return s.ok?{ok:!0,runtimeId:s.runtimeId,...s.modelId?{modelId:s.modelId}:{},runtimeSource:s.runtimeSource}:{ok:!1,reasonCode:s.reasonCode,publicSummary:s.publicSummary,redactionSummary:s.redactionSummary}}function Nt(e){const r=[];for(const i of Object.keys(e))(!gt.has(i)||ae.test(i))&&r.push(h(i,Q(i),"key-denied"));e.publicSafe!==!0&&r.push(h("publicSafe","unsafe_key","value-denied"));const t=B(e,"kind"),a=B(e,"commandClass"),o=B(e,"jobId"),s=B(e,"operationId"),n=B(e,"idempotencyKey"),c=B(e,"targetKind"),d=B(e,"targetRef"),l=B(e,"commandRef"),y=B(e,"publicSummary"),f=B(e,"epicId");t!=="run_yoloop"&&r.push(h("kind","unsafe_key","value-denied")),a!=="goal-tick"&&a!=="loop-tick"&&r.push(h("commandClass","unsafe_key","value-denied")),Se(o)||r.push(h("jobId","unsafe_key","value-denied")),Se(s)||r.push(h("operationId","unsafe_key","value-denied")),Se(n)||r.push(h("idempotencyKey","unsafe_key","value-denied")),(c!=="epic"||!d||!ye.test(d)||D.test(d))&&r.push(h("targetRef","prompt_body","value-denied"));const u=d?`*yoloop @${d}`:void 0;(!l||l!==u||l.includes("@neocortex")||W.test(l)||D.test(l))&&r.push(h("commandRef","prompt_body","value-denied")),f&&d&&f!==se(d)&&r.push(h("epicId","prompt_body","value-denied")),(!y||y.length>240||D.test(y))&&r.push(h("publicSummary","unbounded_text","value-denied")),e.reasonCode!==void 0&&(typeof e.reasonCode!="string"||D.test(e.reasonCode))&&r.push(h("reasonCode","unsafe_key","value-denied"));const m=Xt(e.runtime,r);e.attempts!==void 0&&ue(e.attempts,"attempts",r),e.metadata!==void 0&&ue(e.metadata,"metadata",r);const g=_(e.metadata)?e.metadata:void 0,P=Qt(e.redactionSummary,r);return r.length>0||t!=="run_yoloop"||!a||!o||!s||!n||!d||!l||!y?{ok:!1,reasonCode:r.some(E=>E.reason==="prompt_body")?p.PROMPT_REJECTED:p.DIRECTIVE_REJECTED,redactionSummary:r}:{ok:!0,directive:{kind:"run_yoloop",commandClass:a,jobId:o,operationId:s,idempotencyKey:n,targetKind:"epic",targetRef:d,commandRef:l,...f?{epicId:f}:{},...m?{runtime:m}:{},publicSummary:y,...typeof e.reasonCode=="string"?{reasonCode:e.reasonCode}:{},...g?{metadata:g}:{},...P.length>0?{redactionSummary:P}:{},publicSafe:!0}}}function Bt(e,r){if(!e)return v(p.YOLOOP_METADATA_INVALID,"Headless yoloop metadata was missing.",[]);const t=Ht(e);if(!t.ok)return t;const a=[],o=_(e.yoloopExecutionPlan)?e.yoloopExecutionPlan:void 0,s=o?w(o.storyIds).filter(G):[],n=o?.version===3&&_(o.scheduler)&&Array.isArray(o.scheduler.nodes)?new Map(o.scheduler.nodes.filter(_).map(u=>[String(u.storyId??""),u])):new Map,c=o?.version===3&&_(o.scheduler)&&typeof o.scheduler.graphRevision=="string"?o.scheduler.graphRevision:void 0,d=o?.version===3&&typeof o.executionBranch=="string"?o.executionBranch:void 0;let l;if(o){const u=Kt(o);if(!u.ok)return u;l=u;for(const g of zt(o)){const P=J(g,r,"execution-plan");if(!P.ok)return P;a.push(Ne(P.prompt,n.get(P.prompt.storyId),c,d))}if(a.length===0)for(const g of s){const P=J(`*yolo @docs/stories/${g}.story.md`,r,"execution-plan");if(!P.ok)return P;a.push(Ne(P.prompt,n.get(P.prompt.storyId),c,d))}const m=jt(e.skillDirectives,a);if(!m.ok)return m}const y=typeof e.nextStoryId=="string"&&G(e.nextStoryId)?e.nextStoryId:void 0;for(const u of o?[]:Array.isArray(e.skillDirectives)?e.skillDirectives:[]){if(!_(u)||u.kind!=="task")continue;const m=w(u.promptTemplates);if(m.length>0){for(const E of m){const j=J(E,r,"task-directive");if(!j.ok)return j;a.push(j.prompt)}continue}const g=typeof u.promptTemplate=="string"?u.promptTemplate:void 0;if(!g)continue;const P=w(u.storyIds).filter(G),i=P.length>0?P:y?[y]:[];if(i.length===0&&he.test(g)){const E=J(g,r,"task-directive");if(!E.ok)return E;a.push(E.prompt);continue}for(const E of i){const j=g.includes("{storyId}")?g.replaceAll("{storyId}",E):g,K=J(j,r,"task-directive");if(!K.ok)return K;a.push(K.prompt)}}if(a.length===0&&y){const u=J(`*yolo @docs/stories/${y}.story.md`,r,"next-story");if(!u.ok)return u;a.push(u.prompt)}const f=sr(a,u=>u.commandRef);if(l?.continuous){if(f.length!==s.length||f.some(u=>u.preparationOnly!==!0||u.source!=="execution-plan"))return v(p.YOLOOP_ISOLATION_VIOLATION,"Headless continuous yoloop rejected an ambiguous or non-preparation child prompt.",[h("promptTemplates","prompt_body","operation-denied")])}else if(f.some(u=>u.preparationOnly===!0))return v(p.YOLOOP_ISOLATION_VIOLATION,"Headless yoloop rejected branchless preparation outside a validated continuous plan.",[h("promptTemplates","prompt_body","operation-denied")]);if(s.length>0){const u=new Set(s);for(const m of f)if(!u.has(m.storyId))return v(p.YOLOOP_ISOLATION_VIOLATION,"Headless yoloop rejected a child prompt outside the server-authorized execution plan.",[h("storyId","prompt_body",x(m.storyId))])}return l?.parallelAuthorized&&!Z(f.map(u=>u.storyId),s)?v(p.YOLOOP_METADATA_INVALID,"Headless yoloop rejected a parallel plan whose executable prompts did not match the selected wave.",[]):f.length===0&&!l?.continuous?v(p.YOLOOP_METADATA_INVALID,"Headless yoloop metadata did not include an authorized per-story child prompt.",[]):{ok:!0,prompts:f,mode:l?.mode??"legacy",serverMaxConcurrency:l?.serverMaxConcurrency??1,parallelAuthorized:l?.parallelAuthorized??!1,continuous:l?.continuous??!1,reasonCodes:[p.OK,l?.parallelAuthorized?p.WORKER_POOL_PARALLEL_ACTIVE:p.WORKER_POOL_SERIAL_FALLBACK]}}function Ne(e,r,t,a){if(!r||!t||!a)return e;const o=Array.isArray(r.writeSet)?w(r.writeSet):[],s=Be(r.childExecutionAuthority,{storyId:e.storyId,invocationPrompt:e.commandRef,authorizedWriteSet:o});return{...e,...typeof r.dispatchId=="string"?{dispatchId:r.dispatchId}:{},...typeof r.idempotencyKey=="string"?{idempotencyKey:r.idempotencyKey}:{},graphRevision:t,executionBranch:a,...o.length>0?{writeSet:o}:{},...s?{rootAuthority:s}:{}}}function Ht(e){const r=[];return e.nextStoryId!==void 0&&ne(e.nextStoryId,"nextStoryId",r),e.yoloopExecutionPlan!==void 0&&ne(e.yoloopExecutionPlan,"yoloopExecutionPlan",r),Array.isArray(e.skillDirectives)&&e.skillDirectives.forEach((t,a)=>{_(t)&&t.kind==="task"&&ne(t,`skillDirectives.${a}`,r)}),r.length>0?v(p.YOLOOP_METADATA_INVALID,"Headless yoloop rejected unsafe public metadata before child delegation.",r):{ok:!0}}function jt(e,r){if(!Array.isArray(e))return{ok:!0};const t=new Set(r.map(a=>a.commandRef));for(const[a,o]of e.entries()){if(!_(o)||o.kind!=="task")continue;const s=typeof o.promptTemplate=="string"?o.promptTemplate:void 0,n=w(o.promptTemplates);if(s==="[REDACTED]"&&o.subagentType==="neocortex"&&typeof o.reasonCode=="string"&&o.reasonCode.startsWith("directive-prompt-")&&n.length===0)continue;const d=[...s?[s]:[],...n];if(o.subagentType!=="neocortex"||d.length===0||d.some(l=>!t.has(l)))return v(p.YOLOOP_ISOLATION_VIOLATION,"Headless yoloop rejected a task directive that conflicted with the server-authorized execution plan.",[h(`skillDirectives.${a}`,"prompt_body","operation-denied")])}return{ok:!0}}function ne(e,r,t){if(typeof e=="string"){if(/\.allowedDebt\.constraints\.\d+$/.test(r)&&St.has(e))return;(D.test(e)||/\0/.test(e))&&t.push(h(r,Q(r),"value-denied"));return}if(!(e==null||typeof e=="number"||typeof e=="boolean")){if(Array.isArray(e)){e.forEach((a,o)=>ne(a,`${r}.${o}`,t));return}if(_(e)){for(const[a,o]of Object.entries(e)){const s=`${r}.${a}`;!(a==="promptTemplate"||a==="promptTemplates"||a==="invocationPrompt"||a==="childPromptKind"||a==="allowMetaTaskPromptInChild"||a==="authorization")&&ae.test(a)&&t.push(h(s,Q(a),"key-denied")),ne(o,s,t)}return}t.push(h(r,"unsafe_key","value-denied"))}}function Kt(e){const r=typeof e.mode=="string"?e.mode:"",t=_(e.isolationPolicy)?e.isolationPolicy:void 0,a=w(e.storyIds);if(e.authorization!=="server_authorized")return v(p.YOLOOP_METADATA_INVALID,"Headless yoloop execution plan was not server-authorized.",[]);if(e.executor!=="root_agent"&&e.executor!=="root_agent_with_child_tasks")return v(p.YOLOOP_METADATA_INVALID,"Headless yoloop execution plan executor was not root-owned.",[]);if(r!=="serial"&&r!=="parallel_wave"&&r!=="continuous_dag"&&r!=="manual")return v(p.YOLOOP_METADATA_INVALID,"Headless yoloop execution plan mode was invalid.",[]);const o=e.version===3&&r==="continuous_dag";if(!Array.isArray(e.storyIds)||!o&&a.length===0||a.length!==e.storyIds.length||a.some(i=>!G(i))||new Set(a).size!==a.length)return v(p.YOLOOP_METADATA_INVALID,"Headless yoloop execution plan story selection was invalid or ambiguous.",[]);if(!t||t.rootOwnsLoop!==!0||t.childPromptKind==="per_story_branchless_preparation_only"&&!o||Object.prototype.hasOwnProperty.call(t,"childExecutionBoundary")&&!o||t.childPromptKind!=="per_story_yolo_only"&&t.childPromptKind!=="per_story_branchless_preparation_only"&&!(t.childPromptKind==="none"&&(r==="serial"&&t.childTaskDelegation==="not_required"||r==="parallel_wave"&&e.executor==="root_agent"&&t.childTaskDelegation==="forbidden"))||t.allowOuterYoloopInChild!==!1||t.allowMetaTaskPromptInChild!==!1)return v(p.YOLOOP_ISOLATION_VIOLATION,"Headless yoloop rejected an execution plan that did not preserve root-owned child isolation.",[h("isolationPolicy","prompt_body","value-denied")]);const s=Array.isArray(e.skippedStories)?e.skippedStories:[];for(const i of s){if(!_(i)||typeof i.storyId!="string"||!G(i.storyId)||typeof i.reason!="string")return v(p.YOLOOP_METADATA_INVALID,"Headless yoloop skipped-story evidence was malformed.",[]);if(a.includes(i.storyId))return v(p.YOLOOP_METADATA_INVALID,"Headless yoloop selected a story that server evidence marked skipped.",[])}if(o){const i=_(e.scheduler)?e.scheduler:void 0,E=Array.isArray(i?.nodes)?i.nodes.filter(_):[],j=w(i?.readyStoryIds),K=w(i?.runningStoryIds),z=w(e.promptTemplates),ie=_(e.dependencyBasis)?e.dependencyBasis:void 0,X=_(e.readinessBasis)?e.readinessBasis:void 0,T=typeof i?.graphRevision=="string"?i.graphRevision:"",b=typeof e.executionBranch=="string"?e.executionBranch:"",M=E.map(I=>typeof I.storyId=="string"?I.storyId:""),S=E.find(I=>{const $=typeof I.storyId=="string"?I.storyId:"",ee=typeof I.promptTemplate=="string"?I.promptTemplate:"",de=Array.isArray(I.writeSet)?w(I.writeSet):[];return!G($)||ee!==`*yolo @docs/stories/${$}.story.md branchless-preparation`||typeof I.dispatchId!="string"||!/^[a-f0-9]{64}$/.test(I.dispatchId)||typeof I.idempotencyKey!="string"||!/^[a-f0-9]{64}$/.test(I.idempotencyKey)||I.dependencyBasis!=="verified"||!Array.isArray(I.dependencies)||w(I.dependencies).length!==I.dependencies.length||!Array.isArray(I.writeSet)||de.length===0||de.length!==I.writeSet.length||!Be(I.childExecutionAuthority,{storyId:$,invocationPrompt:ee,authorizedWriteSet:de})});return e.executor!=="root_agent_with_child_tasks"||e.legacyConcurrencyIgnored!==!0||Object.prototype.hasOwnProperty.call(e,"maxConcurrency")||Object.prototype.hasOwnProperty.call(e,"maxParallel")||t?.rootOwnedScheduling!=="continuous_dag_allowed"||t?.childPromptKind!=="per_story_branchless_preparation_only"||t?.childExecutionBoundary!=="filesystem_only"||t?.childTaskDelegation!=="allowed"||t?.maxDepth!==1||t?.childWorkspace!=="branchless_sandbox"||t?.epicCheckout!=="current_checkout"||t?.workspaceLifecycle!=="user_managed"||t?.integrationOwner!=="root_agent"||!i||i.schemaVersion!==1||i.strategy!=="continuous-event-driven-dag"||i.logicalConcurrency!=="ready-set"||i.capacityPolicy!=="backpressure-only"||i.rootOwnsLoop!==!0||i.maxDepth!==1||!/^[a-f0-9]{64}$/.test(T)||!er(b)||new Set(M).size!==M.length||M.some(I=>!G(I))||j.some(I=>!M.includes(I))||K.some(I=>!M.includes(I)||j.includes(I))||!Z(a,j)||z.length!==a.length||z.some((I,$)=>I!==`*yolo @docs/stories/${a[$]}.story.md branchless-preparation`)||!ie||ie.source!=="state_snapshot"||!X||X.source!=="ready_wave"||!Z(w(X.selectedStoryIds),a)||S?v(p.YOLOOP_METADATA_INVALID,"Headless yoloop rejected an invalid continuous DAG execution plan.",[]):{ok:!0,mode:"continuous_dag",serverMaxConcurrency:a.length,parallelAuthorized:!0,continuous:!0}}if(e.version===2){const i=at(e);return i.ok?{ok:!0,mode:"parallel_wave",serverMaxConcurrency:i.childExecutionConcurrency,parallelAuthorized:!1,continuous:!1}:v(p.YOLOOP_METADATA_INVALID,"Headless yoloop rejected an unsafe phased execution plan.",[])}if(r!=="parallel_wave")return{ok:!0,mode:r,serverMaxConcurrency:1,parallelAuthorized:!1,continuous:!1};const n=e.maxConcurrency,c=e.maxParallel,d=_(e.dependencyBasis)?e.dependencyBasis:void 0,l=_(e.readinessBasis)?e.readinessBasis:void 0,y=Array.isArray(e.parallelWaves)?e.parallelWaves:[],f=y.length===1&&_(y[0])?y[0]:void 0;if(t.rootOwnedScheduling!=="parallel_wave_allowed"||!Number.isInteger(n)||typeof n!="number"||n<2||n>a.length||!Number.isInteger(c)||c!==n||!d||d.source!=="state_snapshot"||!Z(w(d.storyIds),a)||!l||l.source!=="ready_wave"||!Z(w(l.selectedStoryIds),a)||!f||!Z(w(f.storyIds),a)||f.maxConcurrency!==n)return v(p.YOLOOP_METADATA_INVALID,"Headless yoloop parallel plan lacked consistent bounded authorization and readiness evidence.",[]);const u=w(f.promptTemplates);if(u.length!==a.length||new Set(u).size!==u.length)return v(p.YOLOOP_METADATA_INVALID,"Headless yoloop parallel wave prompts were incomplete or ambiguous.",[]);const g=(Array.isArray(f.proofSummaries)?f.proofSummaries:Array.isArray(e.proofSummaries)?e.proofSummaries:[]).find(i=>_(i)&&Z(w(i.storyIds),a));return!_(g)||g.dependencyClosure!=="resolved"||g.contractOwnership!=="non_overlapping"||g.validationSurfaces!=="compatible"?v(p.YOLOOP_METADATA_INVALID,"Headless yoloop parallel plan lacked resolved independence proof.",[]):s.find(i=>_(i)&&typeof i.reason=="string"&&/(cycle|unresolved|ambiguous)/i.test(i.reason))?v(p.YOLOOP_METADATA_INVALID,"Headless yoloop parallel plan contained unresolved dependency evidence.",[]):{ok:!0,mode:"parallel_wave",serverMaxConcurrency:n,parallelAuthorized:!0,continuous:!1}}function Be(e,r){if(!_(e)||!_(e.artifact))return;const t=e.artifact,a=Array.isArray(e.authorizedWriteSet)?w(e.authorizedWriteSet):[];if(Object.keys(e).sort().join("\0")!==["artifact","authorizedWriteSet","effectScope","invocationPrompt","kind","lifecycleAuthority","publicSafe","schemaVersion","storyId"].sort().join("\0")||Object.keys(t).sort().join("\0")!==["content","contentBinding","kind","path","schemaVersion"].sort().join("\0")||e.schemaVersion!==1||e.kind!=="branchless_story_preparation"||e.storyId!==r.storyId||e.invocationPrompt!==r.invocationPrompt||!Array.isArray(e.authorizedWriteSet)||a.length!==e.authorizedWriteSet.length||a.some(s=>pt(s)!==s)||!Ut(a,r.authorizedWriteSet)||e.effectScope!=="filesystem_only"||e.lifecycleAuthority!=="root_only"||e.publicSafe!==!0||t.schemaVersion!==1||t.kind!=="branchless_root_bound_artifact"||typeof t.path!="string"||!a.includes(t.path)||typeof t.content!="string"||t.content.length===0||t.content.length>4096||typeof t.contentBinding!="string"||!/^[a-f0-9]{64}$/.test(t.contentBinding))return;const o=Ke("sha256").update(["branchless-root-bound-artifact-v1",r.storyId,r.invocationPrompt,...a,"filesystem_only","root_only",t.path,t.content].join("\0")).digest("hex");if(t.contentBinding===o)return e}function Ut(e,r){return e.length===r.length&&e.every((t,a)=>t===r[a])}function zt(e){const r=[];r.push(...w(e.promptTemplates));for(const t of Array.isArray(e.serialSteps)?e.serialSteps:[])_(t)&&typeof t.promptTemplate=="string"&&r.push(t.promptTemplate);for(const t of Array.isArray(e.parallelWaves)?e.parallelWaves:[])_(t)&&r.push(...w(t.promptTemplates));return r}function J(e,r,t){if(we(e))return v(p.YOLOOP_ISOLATION_VIOLATION,"Headless yoloop rejected an unsafe child prompt shape.",[h("promptTemplate","prompt_body",x(e))]);if(!he.test(e))return v(p.YOLOOP_METADATA_INVALID,"Headless yoloop child prompt did not match the canonical per-story yolo shape.",[h("promptTemplate","prompt_body",x(e))]);const a=Ct.test(e),o=e.replace(/^\*yolo @/,"").replace(/ branchless-preparation$/,""),s=rr(o);return!_t.test(o)||!G(s)||!s.startsWith(`${r}.`)?v(p.YOLOOP_ISOLATION_VIOLATION,"Headless yoloop rejected a child prompt outside the targeted public epic.",[h("storyId","prompt_body",x(s))]):{ok:!0,prompt:{storyId:s,targetRef:o,commandRef:e,source:t,...a?{preparationOnly:!0}:{}}}}function $t(e){const r=e?.epicTerminalGitDirective;if(!(!_(r)||r.schemaVersion!==1||r.kind!=="epic_terminal_git"||typeof r.epicId!="string"||typeof r.executionBranch!="string"||typeof r.originBranch!="string"||typeof r.expectedExecutionHeadSha!="string"||!Array.isArray(r.storyCheckpointIds)||!_(r.localGates)||r.localGates.passed!==!0||!Array.isArray(r.localGates.receiptRefs)||!_(r.reconcile)||typeof r.idempotencyKey!="string"||r.publicSafe!==!0))return r}function Yt(e){const r=e?.epicGitReconciliationDirective;if(!(!_(r)||r.schemaVersion!==1||r.kind!=="epic_git_reconciliation"||typeof r.epicId!="string"||typeof r.executionBranch!="string"||typeof r.originBranch!="string"||!["start","resume","audit"].includes(String(r.lifecycleBoundary))||typeof r.dryRun!="boolean"||typeof r.idempotencyKey!="string"||r.publicSafe!==!0))return r}function Ft(e){if(!e||!_(e))return{ok:!1,reasonCode:p.YOLOOP_METADATA_INVALID,publicSummary:"Headless yoloop root invocation did not return public metadata.",redactionSummary:[]};const r=_(e.yoloopContinuationDecision)?e.yoloopContinuationDecision:void 0,t=typeof r?.outcome=="string"?r.outcome:void 0,a=t==="queue_exhausted"||e.yoloopComplete===!0,o=e.yoloopAborted===!0,s=mt(e.releaseBlocked),n=t==="selected"&&r?.replay===!0;return t&&!["selected","queue_exhausted","blocked","cycle","invalid","no_progress"].includes(t)?{ok:!1,reasonCode:p.YOLOOP_METADATA_INVALID,publicSummary:"Headless yoloop rejected an unknown continuation outcome.",redactionSummary:[]}:t==="queue_exhausted"&&r?.terminalSuccess!==!0?{ok:!1,reasonCode:p.YOLOOP_METADATA_INVALID,publicSummary:"Headless yoloop rejected inconsistent queue exhaustion metadata.",redactionSummary:[]}:a&&o?{ok:!1,reasonCode:p.YOLOOP_METADATA_INVALID,publicSummary:"Headless yoloop metadata reported mutually exclusive terminal states.",redactionSummary:[h("yoloopTerminal","unsafe_key","value-denied")]}:(e.yoloopReleaseBlocked===!0||e.terminalClass==="release-blocked"||e.releaseBlocked!==void 0)&&(!s||e.yoloopReleaseBlocked!==!0||e.terminalClass!=="release-blocked"||a||o||t!==void 0)?{ok:!1,reasonCode:p.YOLOOP_METADATA_INVALID,publicSummary:"Headless yoloop rejected inconsistent release-blocked terminal metadata.",redactionSummary:[]}:{ok:!0,complete:a,aborted:o,...s?{releaseBlocked:s}:{},outcome:t,replay:n}}function Vt(e){if(!e)return;const r=e.abortReason;if(r!=="YOLOOP_PER_RUN_CAP_REACHED"&&r!=="YOLOOP_SESSION_TIMEOUT")return;const t=e.yoloopResumableBoundary,a=/^[A-Za-z0-9._:-]{1,128}$/;if(!(!_(t)||t.schemaVersion!=="YoloopResumableBoundary/1.0"||t.resumable!==!0||t.reason!==r||t.publicSafe!==!0||typeof t.coolDownUntil!="string"||!Number.isFinite(Date.parse(t.coolDownUntil))||!Number.isSafeInteger(t.retryAfterMs)||t.retryAfterMs<0||typeof t.operationId!="string"||!a.test(t.operationId)||!_(t.receipt)||t.receipt.schemaVersion!=="YoloopSessionRolloverReceipt/1.0"||typeof t.receipt.runId!="string"||!a.test(t.receipt.runId)||t.receipt.operationId!==t.operationId||typeof t.receipt.idempotencyKey!="string"||!a.test(t.receipt.idempotencyKey)||typeof t.receipt.payloadHash!="string"||!/^[a-f0-9]{64}$/.test(t.receipt.payloadHash)||t.receipt.coolDownUntil!==t.coolDownUntil||!Number.isSafeInteger(t.receipt.revision)||t.receipt.revision<0||t.receipt.snapshotHash!==null&&(typeof t.receipt.snapshotHash!="string"||!/^[a-f0-9]{64}$/.test(t.receipt.snapshotHash))||t.receipt.status!=="exhausted"||t.receipt.publicSafe!==!0))return{coolDownUntil:t.coolDownUntil,reason:r}}function qt(e){const r=`${e.rootAttempt.execution_id}:${e.child.graphRevision??"legacy"}:${e.child.storyId}`,t=e.child.dispatchId??q("child-op",`${r}:${e.iteration}`),a=e.child.idempotencyKey??q("child-idem",`${r}:${e.iteration}`);return{schemaVersion:1,contractVersion:"continuity-v1",kind:"run_yolo",commandClass:e.rootAttempt.command_class==="goal-tick"?"goal-tick":"loop-tick",jobId:e.rootAttempt.job_id,operationId:t,idempotencyKey:a,targetKind:"story",targetRef:e.child.targetRef,commandRef:e.child.commandRef,...e.child.preparationOnly?{executionMode:"branchless_child_preparation"}:{},storyId:e.child.storyId,runtime:{runtimeId:e.runtimeId,...e.modelId?{modelId:e.modelId}:{},source:e.runtimeSource??"explicit",reasonCode:e.runtimeSource==="fallback"?p.RUNTIME_FALLBACK:p.RUNTIME_EXPLICIT,publicSafe:!0},publicSummary:`Root-owned yoloop delegated public story ${e.child.storyId}.`,reasonCode:p.OK,metadata:{governanceSource:"delegated-subagent",parentAttemptId:e.rootAttempt.attempt_id,parentExecutionId:e.rootAttempt.execution_id,iteration:e.iteration,...e.child.dispatchId?{dispatchId:e.child.dispatchId}:{},...e.child.graphRevision?{graphRevision:e.child.graphRevision}:{},...e.child.writeSet?{writeSet:e.child.writeSet}:{},...e.child.executionBranch?{executionBranch:e.child.executionBranch}:{},...e.child.graphRevision?{childWorkspace:"branchless_sandbox",epicCheckout:"current_checkout",workspaceLifecycle:"user_managed",integrationOwner:"root_agent",maxDepth:1}:{},publicSafe:!0},attempts:[],redactionSummary:[h("prompt","prompt_body",x(e.child.commandRef))],publicSafe:!0}}function Ce(e,r,t){const a=He(t.hashes),o=t.workerPoolSummary??_e(),s=He({iterations:t.counts.iterations,childCount:t.counts.childCount,succeededChildCount:t.counts.succeededChildCount,failedChildCount:t.counts.failedChildCount,skippedChildCount:t.counts.skippedChildCount,metadataCompleteCount:t.counts.metadataCompleteCount,metadataAbortedCount:t.counts.metadataAbortedCount,serverMaxConcurrency:o.serverMaxConcurrency,localCap:o.localCap,queueCap:o.queueCap,availableLeases:o.availableLeases,effectiveConcurrency:o.effectiveConcurrency,peakConcurrency:o.peakConcurrency,pendingChildCount:o.pendingChildCount,startedChildCount:o.startedChildCount,completedChildCount:o.completedChildCount,backpressurePauseCount:o.backpressurePauseCount}),n={schemaVersion:1,contractVersion:"continuity-v1",attemptId:r.attempt_id,executionId:r.execution_id,jobId:r.job_id,directiveHash:r.directive_hash,status:t.status,reasonCode:t.reasonCode,storyIds:t.childStoryIds.slice(0,50),counts:s,hashes:a,...t.reasonCode===Ee.BYPASS_BLOCKED?{governanceEvidence:Ve}:{},reasonCodes:V([t.reasonCode,...o.reasonCodes,...t.stateTransitions]),publicSummary:me(t.publicSummary),...t.terminalClass?{terminalClass:t.terminalClass}:{},...t.releaseBlocked?{releaseBlocked:t.releaseBlocked}:{}},c=ve(r.metadata_json,{autonomousKind:"run_yoloop",jobId:r.job_id,targetKind:"epic",targetRef:r.target_ref}),d=c.ok?Re(c.envelope,n):n;return e.completeHeadlessExecutionAttempt({attemptId:r.attempt_id,executionId:r.execution_id,jobId:r.job_id,leaseId:t.leaseId,runnerId:t.runnerId,status:t.status,completedAt:t.completedAt,durationMs:t.durationMs,reasonCode:t.reasonCode,publicSummary:me(t.publicSummary),notBeforeAt:t.notBeforeAt,retryCount:t.retryCount,counts:s,hashes:a,redactionSummary:t.redactionSummary,relativePaths:V([r.target_ref,...t.relativePaths]),metadata:d}),e.recordHeadlessExecutionReceipt({receiptId:`receipt-${q("headless-yoloop",`${r.attempt_id}-${t.status}`)}`,attemptId:r.attempt_id,executionId:r.execution_id,jobId:r.job_id,status:t.receiptStatus,reasonCode:t.reasonCode,createdAt:t.completedAt,operationId:`${r.execution_id}:${t.status}:receipt`,idempotencyKey:`${r.directive_hash}:${t.status}:receipt`,counts:s,hashes:a,redactionSummary:t.redactionSummary,relativePaths:V([r.target_ref,...t.relativePaths]),metadata:d}),e.recordHeadlessExecutionSummary({eventId:`event-${q("headless-yoloop-summary",`${r.attempt_id}-${t.status}`)}`,attemptId:r.attempt_id,executionId:r.execution_id,jobId:r.job_id,status:t.status,runtimeId:t.runtimeId,modelId:t.modelId,publicSummary:me(t.publicSummary),reasonCode:t.reasonCode,createdAt:t.completedAt,durationMs:t.durationMs,counts:s,hashes:a,redactionSummary:t.redactionSummary,relativePaths:V([r.target_ref,...t.relativePaths]),metadata:d}),{attemptId:r.attempt_id,executionId:r.execution_id,jobId:r.job_id,status:t.status,outcome:t.receiptStatus,reasonCode:t.reasonCode,timestamp:t.completedAt,childStoryIds:t.childStoryIds,aggregateCounts:t.counts,workerPoolSummary:o,redactionSummary:t.redactionSummary,...t.terminalClass?{terminalClass:t.terminalClass}:{},...t.releaseBlocked?{releaseBlocked:t.releaseBlocked}:{},publicSafe:!0}}function Wt(e,r){return{attemptId:e.attempt_id,executionId:e.execution_id,jobId:e.job_id,status:r.status,outcome:r.receiptStatus,reasonCode:r.reasonCode,timestamp:r.timestamp,childStoryIds:[],aggregateCounts:be(),workerPoolSummary:_e(),redactionSummary:[],publicSafe:!0}}function Gt(e,r,t,a,o){if(!r.retryable)return{retry:!1};if(xe.has(r.reasonCode))return{retry:!0,retryCount:e.retry_count,notBeforeAt:je(ge(o,a),r.retryNotBeforeAt)};const s=e.retry_count+1;if(s>=Math.max(1,e.max_attempts||t))return{retry:!1,retryCount:s};const n=Math.min(8,2**Math.max(0,e.retry_count));return{retry:!0,retryCount:s,notBeforeAt:je(ge(o,a*n),r.retryNotBeforeAt)}}function O(e){return{status:e.status,receiptStatus:e.receiptStatus,reasonCode:e.reasonCode,publicSummary:e.publicSummary,retryable:e.retryable,...e.retryNotBeforeAt?{retryNotBeforeAt:e.retryNotBeforeAt}:{},durationMs:Math.max(0,Date.now()-e.startedAt),counts:e.counts,workerPoolSummary:e.workerPoolSummary??_e(),hashes:e.hashes,redactionSummary:e.redactions.slice(0,50),relativePaths:V(e.relativePaths).slice(0,50),childStoryIds:V(e.childStoryIds).slice(0,50),stateTransitions:V(e.stateTransitions),...e.terminalClass?{terminalClass:e.terminalClass}:{},...e.releaseBlocked?{releaseBlocked:e.releaseBlocked}:{}}}function Xt(e,r){if(e===void 0)return;if(!_(e)){r.push(h("runtime","unsafe_key","value-denied"));return}for(const s of Object.keys(e))(!At.has(s)||ae.test(s))&&r.push(h(`runtime.${s}`,Q(s),"key-denied"));e.publicSafe!==!0&&r.push(h("runtime.publicSafe","unsafe_key","value-denied"));const t=B(e,"runtimeId"),a=B(e,"modelId"),o=B(e,"source");if(t&&(!/^[A-Za-z0-9][A-Za-z0-9._:-]{0,79}$/.test(t)||D.test(t)||W.test(t))&&r.push(h("runtime.runtimeId","unsafe_key","value-denied")),a&&(!/^[A-Za-z0-9][A-Za-z0-9._:+/-]{0,119}$/.test(a)||D.test(a)||W.test(a))&&r.push(h("runtime.modelId","unsafe_key","value-denied")),o!==void 0&&o!=="explicit"&&o!=="origin"&&o!=="default"&&o!=="fallback"&&o!=="unspecified"&&r.push(h("runtime.source","unsafe_key","value-denied")),e.reasonCode!==void 0&&(typeof e.reasonCode!="string"||D.test(e.reasonCode))&&r.push(h("runtime.reasonCode","unsafe_key","value-denied")),e.publicSafe===!0)return{...t?{runtimeId:t}:{},...a?{modelId:a}:{},...o==="explicit"||o==="origin"||o==="default"||o==="fallback"||o==="unspecified"?{source:o}:{},...typeof e.reasonCode=="string"?{reasonCode:e.reasonCode}:{},publicSafe:!0}}function Zt(e){const r=Array.isArray(e)?e:e?[e]:[],t=[];for(const a of r){const o=a.continuityExecutionDirectives;Array.isArray(o)&&t.push(...o)}return t}function Jt(e){return x(Ie({kind:e.kind,commandClass:e.commandClass,jobId:e.jobId,targetRef:e.targetRef,commandRef:e.commandRef,epicId:e.epicId,runtime:e.runtime}))}function Ie(e){return Array.isArray(e)?`[${e.map(Ie).join(",")}]`:_(e)?`{${Object.keys(e).sort().map(r=>`${JSON.stringify(r)}:${Ie(e[r])}`).join(",")}}`:JSON.stringify(e)}function ue(e,r,t){if(typeof e=="string"){(D.test(e)||W.test(e))&&t.push(h(r,Q(r),"value-denied"));return}if(!(e==null||typeof e=="number"||typeof e=="boolean")){if(Array.isArray(e)){e.forEach((a,o)=>ue(a,`${r}.${o}`,t));return}if(_(e)){for(const[a,o]of Object.entries(e)){const s=`${r}.${a}`;ae.test(a)&&t.push(h(s,Q(a),"key-denied")),ue(o,s,t)}return}t.push(h(r,"unsafe_key","value-denied"))}}function Qt(e,r){if(e===void 0)return[];if(!Array.isArray(e))return r.push(h("redactionSummary","unsafe_key","value-denied")),[];const t=[];for(const[a,o]of e.entries()){if(!_(o)||o.publicSafe!==!0){r.push(h(`redactionSummary.${a}`,"unsafe_key","value-denied"));continue}const s=B(o,"field"),n=B(o,"reason"),c=B(o,"evidence");if(!s||!n||!c||D.test(s)||D.test(n)||D.test(c)){r.push(h(`redactionSummary.${a}`,"unsafe_key","value-denied"));continue}t.push({field:s,reason:n,evidence:c,publicSafe:!0})}return t}function v(e,r,t){return{ok:!1,reasonCode:e,publicSummary:r,redactionSummary:t}}function w(e){return Array.isArray(e)?e.filter(r=>typeof r=="string"):[]}function er(e){return e.length>0&&e.length<=240&&!e.startsWith("-")&&!e.includes("..")&&!e.includes("\\")&&/^[A-Za-z0-9._/-]+$/.test(e)}function Z(e,r){return e.length===r.length&&new Set(e).size===e.length&&e.every(t=>r.includes(t))}function tr(e){return ye.test(e.target_ref)?[e.target_ref]:[]}function He(e){if(!e)return;const r={};for(const[t,a]of Object.entries(e))!/^[A-Za-z0-9_.:-]{1,80}$/.test(t)||ae.test(t)||D.test(t)||typeof a=="string"&&D.test(a)||(r[t]=a);return Object.keys(r).length>0?r:void 0}function be(){return k(0,0,0,0,0,0,0)}function k(e,r,t,a,o,s,n){return{iterations:e,childCount:r,succeededChildCount:t,failedChildCount:a,skippedChildCount:o,metadataCompleteCount:s,metadataAbortedCount:n}}function rr(e){return e.replace(/^docs\/stories\//,"").replace(/\.story\.md$/,"")}function se(e){return e.replace(/^docs\/epics\/epic-/,"").replace(/\.md$/,"")}function G(e){return/^[A-Za-z0-9][A-Za-z0-9_-]*\.\d+[A-Za-z0-9_-]*$/.test(e)&&!D.test(e)&&!W.test(e)}function or(e){if(e==="explicit"||e==="origin"||e==="default"||e==="fallback")return e}function ar(e){if(e==="explicit"||e==="origin"||e==="default"||e==="fallback"||e==="unspecified")return e}function Q(e){return/prompt|commandRef/i.test(e)?"prompt_body":/std(?:out|err)|raw|log|transcript|stack/i.test(e)?"raw_log":/url/i.test(e)?"private_url":/path|cwd|argv|args|shell|command|binary|executable/i.test(e)?"executable_path":/secret|token|password|authorization|api[_-]?key|license/i.test(e)?"secret_or_pii":"unsafe_key"}function B(e,r){return typeof e[r]=="string"?e[r]:void 0}function Se(e){return!!(e&&bt.test(e)&&!D.test(e)&&!W.test(e))}function _(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function nr(e,r){return q(e,`${r}-${Date.now()}-${Ue(4).toString("hex")}`)}function ge(e,r){const t=Date.parse(e);return new Date((Number.isFinite(t)?t:Date.now())+r).toISOString()}function je(e,r){const t=Date.parse(e),a=r?Date.parse(r):Number.NaN;return Number.isFinite(a)?Number.isFinite(t)?a>t?r:e:r:e}function F(e,r,t){return Number.isFinite(e)?Math.max(r,Math.min(t,Math.floor(e))):r}function V(e){return Array.from(new Set(e))}function sr(e,r){const t=new Set,a=[];for(const o of e){const s=r(o);t.has(s)||(t.add(s),a.push(o))}return a}export{ht as DEFAULT_HEADLESS_YOLOOP_LEASE_MS,fe as DEFAULT_HEADLESS_YOLOOP_LOCAL_CONCURRENCY_CAP,yt as DEFAULT_HEADLESS_YOLOOP_MAX_DURATION_MS,ft as DEFAULT_HEADLESS_YOLOOP_MAX_ITERATIONS,Pe as MAX_HEADLESS_YOLOOP_LOCAL_CONCURRENCY_CAP,Or as RUN_YOLOOP_DRIVER_STATES,Pt as defaultYoloopRootInvoker,Er as isCanonicalDelegatedStoryPrompt,Te as resolveDefaultHeadlessYoloopLocalConcurrencyCap,Rr as runYoloopExecutionPhase};