@ornexus/neocortex 4.60.73 → 4.60.75

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 (269) 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.d.ts +27 -0
  22. package/packages/client/dist/cache/encrypted-cache.js +1 -108
  23. package/packages/client/dist/cache/in-memory-asset-cache.js +1 -73
  24. package/packages/client/dist/cache/index.js +1 -13
  25. package/packages/client/dist/cache/protected-pi-boundary.js +1 -44
  26. package/packages/client/dist/checkpoint/checkpoint-client-reader.js +2 -127
  27. package/packages/client/dist/checkpoint/index.js +1 -11
  28. package/packages/client/dist/checkpoint/shared-checkpoint-types.js +1 -32
  29. package/packages/client/dist/cli.js +5 -358
  30. package/packages/client/dist/commands/activate.js +8 -394
  31. package/packages/client/dist/commands/architecture-answers.js +7 -274
  32. package/packages/client/dist/commands/architecture-memory-terminal.js +4 -253
  33. package/packages/client/dist/commands/architecture-non-ui-continuation.js +1 -100
  34. package/packages/client/dist/commands/architecture-root-binding.js +1 -51
  35. package/packages/client/dist/commands/cache-status.js +2 -112
  36. package/packages/client/dist/commands/config.js +1 -88
  37. package/packages/client/dist/commands/doctor.js +2 -635
  38. package/packages/client/dist/commands/invoke.d.ts +38 -1
  39. package/packages/client/dist/commands/invoke.js +143 -7200
  40. package/packages/client/dist/commands/legacy-epic-terminal.js +1 -71
  41. package/packages/client/dist/commands/legacy-story-branch.js +1 -96
  42. package/packages/client/dist/commands/legacy-story-pr.js +1 -276
  43. package/packages/client/dist/commands/mutation-qa-checkpoint.js +5 -285
  44. package/packages/client/dist/commands/mutation-qa-gate.js +1 -54
  45. package/packages/client/dist/commands/mutation-qa-git.js +1 -41
  46. package/packages/client/dist/commands/mutation-qa-policy.js +1 -102
  47. package/packages/client/dist/commands/mutation-qa-run.js +3 -219
  48. package/packages/client/dist/commands/mutation-qa-verdict.js +1 -149
  49. package/packages/client/dist/commands/mutation-qa.js +1 -220
  50. package/packages/client/dist/commands/native-agent.js +2 -136
  51. package/packages/client/dist/commands/planning-diagnosis.js +1 -43
  52. package/packages/client/dist/commands/planning-generation.js +1 -53
  53. package/packages/client/dist/commands/planning-memory.js +1 -40
  54. package/packages/client/dist/commands/planning-research.js +1 -42
  55. package/packages/client/dist/commands/private-session.js +1 -75
  56. package/packages/client/dist/commands/property-qa.js +1 -139
  57. package/packages/client/dist/commands/qa-control.js +1 -16
  58. package/packages/client/dist/commands/qa-scan-browser-launch.js +1 -55
  59. package/packages/client/dist/commands/qa-scan-browser-route.js +1 -28
  60. package/packages/client/dist/commands/qa-scan-capture.js +5 -663
  61. package/packages/client/dist/commands/qa-scan-discovery.js +3 -376
  62. package/packages/client/dist/commands/qa-scan-review.js +5 -826
  63. package/packages/client/dist/commands/qa-synthetic-backend-capture.js +1 -266
  64. package/packages/client/dist/commands/qa-synthetic-backend-review.js +1 -297
  65. package/packages/client/dist/commands/qa-synthetic-backend.js +2 -340
  66. package/packages/client/dist/commands/qa-synthetic-broker-port.js +1 -85
  67. package/packages/client/dist/commands/qa-synthetic-browser.js +1 -39
  68. package/packages/client/dist/commands/refactor-characterization.js +21 -671
  69. package/packages/client/dist/commands/refactor-commit.js +13 -399
  70. package/packages/client/dist/commands/refactor-control.js +3 -142
  71. package/packages/client/dist/commands/refactor-cpp-assertions.js +3 -93
  72. package/packages/client/dist/commands/refactor-review.js +5 -283
  73. package/packages/client/dist/commands/refactor-root.js +7 -588
  74. package/packages/client/dist/commands/refresh-memory.js +3 -156
  75. package/packages/client/dist/commands/shared-architecture-non-ui.js +1 -24
  76. package/packages/client/dist/commands/story-checkpoint.js +1 -171
  77. package/packages/client/dist/config/host-auth-broker.d.ts +31 -0
  78. package/packages/client/dist/config/host-auth-broker.js +1 -0
  79. package/packages/client/dist/config/host-auth-reference.d.ts +32 -0
  80. package/packages/client/dist/config/host-auth-reference.js +1 -0
  81. package/packages/client/dist/config/profile-directory.js +1 -13
  82. package/packages/client/dist/config/resolver-selection.js +1 -278
  83. package/packages/client/dist/config/secure-config.js +12 -281
  84. package/packages/client/dist/config.js +2 -223
  85. package/packages/client/dist/constants.js +1 -25
  86. package/packages/client/dist/context/context-collector.js +2 -222
  87. package/packages/client/dist/context/context-sanitizer.js +1 -145
  88. package/packages/client/dist/continuity/autonomous-governance.js +1 -285
  89. package/packages/client/dist/continuity/continuity-client-state-store.js +1 -1587
  90. package/packages/client/dist/continuity/invoke-hooks.js +1 -129
  91. package/packages/client/dist/continuity/migrations/001-initial-schema.js +2 -12
  92. package/packages/client/dist/continuity/migrations/002-processing-output-summary-indexes.js +2 -12
  93. package/packages/client/dist/continuity/migrations/003-headless-execution-attempts.js +2 -12
  94. package/packages/client/dist/continuity/migrations/004-outbox-delivery-state.js +2 -12
  95. package/packages/client/dist/continuity/migrations/005-bounded-headless-queue.js +2 -12
  96. package/packages/client/dist/continuity/migrations/006-native-agent-dispatches.js +2 -10
  97. package/packages/client/dist/continuity/native-agent-store.js +1 -69
  98. package/packages/client/dist/continuity/native-agent-types.d.ts +11 -0
  99. package/packages/client/dist/continuity/native-agent-types.js +1 -90
  100. package/packages/client/dist/continuity/outbox.js +1 -117
  101. package/packages/client/dist/continuity/runner-bootstrap-policy.js +1 -172
  102. package/packages/client/dist/continuity/sqlite-store.js +81 -2612
  103. package/packages/client/dist/effects/invoke-effect-gateways.js +1 -62
  104. package/packages/client/dist/errors/error-messages.d.ts +3 -0
  105. package/packages/client/dist/errors/error-messages.js +2 -228
  106. package/packages/client/dist/errors/frontmatter-diagnostics.js +1 -125
  107. package/packages/client/dist/evidence/collector.js +1 -347
  108. package/packages/client/dist/evidence/index.js +1 -1
  109. package/packages/client/dist/evidence/types.js +0 -2
  110. package/packages/client/dist/fs/atomic-state-replace.js +1 -152
  111. package/packages/client/dist/generated/command-registry.generated.js +1 -4076
  112. package/packages/client/dist/generated/public-projections.generated.js +1 -149
  113. package/packages/client/dist/git/direct-yolo-c01-retry.js +4 -138
  114. package/packages/client/dist/git/direct-yolo-checkpoint.d.ts +11 -1
  115. package/packages/client/dist/git/direct-yolo-checkpoint.js +4 -1234
  116. package/packages/client/dist/git/epic-operational-state.js +2 -672
  117. package/packages/client/dist/git/git-lifecycle-step-ids.js +1 -14
  118. package/packages/client/dist/git/git-lifecycle-store.d.ts +23 -0
  119. package/packages/client/dist/git/git-lifecycle-store.js +10 -1981
  120. package/packages/client/dist/git/legacy-story-branch-checkpoint.js +9 -259
  121. package/packages/client/dist/git/legacy-story-branch-setup.js +4 -348
  122. package/packages/client/dist/git/legacy-story-pr.js +70 -3538
  123. package/packages/client/dist/git/secure-filesystem-boundary.js +5 -182
  124. package/packages/client/dist/graph-retrieval/pre-command-hook.js +1 -284
  125. package/packages/client/dist/graph-retrieval/shared-graph-retrieval-contract.js +1 -237
  126. package/packages/client/dist/i18n/first-run.js +2 -60
  127. package/packages/client/dist/index.d.ts +2 -0
  128. package/packages/client/dist/index.js +1 -47
  129. package/packages/client/dist/invocation/invoke-input.js +1 -24
  130. package/packages/client/dist/license/host-auth-recovery.d.ts +158 -0
  131. package/packages/client/dist/license/host-auth-recovery.js +1 -0
  132. package/packages/client/dist/license/index.js +1 -5
  133. package/packages/client/dist/license/license-client.d.ts +10 -1
  134. package/packages/client/dist/license/license-client.js +1 -304
  135. package/packages/client/dist/machine/fingerprint.js +2 -163
  136. package/packages/client/dist/machine/index.js +1 -5
  137. package/packages/client/dist/memory/project-memory-path-scope.js +1 -62
  138. package/packages/client/dist/memory/project-memory-writer.js +40 -1007
  139. package/packages/client/dist/memory/shared-project-memory-types.js +2 -253
  140. package/packages/client/dist/migrations/epic-lifecycle-backfill.js +3 -1060
  141. package/packages/client/dist/migrations/project-identity-capability.js +1 -50
  142. package/packages/client/dist/migrations/project-identity.js +7 -493
  143. package/packages/client/dist/migrations/state-json.js +4 -393
  144. package/packages/client/dist/policy/architecture-policy.js +2 -184
  145. package/packages/client/dist/policy/index.js +1 -7
  146. package/packages/client/dist/policy/shared-policy-types.js +0 -38
  147. package/packages/client/dist/policy/subagent-approval-policy.js +1 -55
  148. package/packages/client/dist/private-execution/clean-baseline.js +2 -279
  149. package/packages/client/dist/private-execution/codex-executor.js +4 -574
  150. package/packages/client/dist/private-execution/codex-host-runtime.js +1 -137
  151. package/packages/client/dist/private-execution/codex-lifecycle-guard.js +1 -97
  152. package/packages/client/dist/private-execution/codex-scoped-permissions.js +1 -128
  153. package/packages/client/dist/private-execution/delivery.js +13 -410
  154. package/packages/client/dist/private-execution/diagnosis-root-review.js +2 -294
  155. package/packages/client/dist/private-execution/frozen-handoff.js +6 -19
  156. package/packages/client/dist/private-execution/implementation-validation.js +2 -106
  157. package/packages/client/dist/private-execution/isolated-admission.js +23 -1432
  158. package/packages/client/dist/private-execution/isolated-session.js +5 -725
  159. package/packages/client/dist/private-execution/isolated-workspace.js +1 -122
  160. package/packages/client/dist/private-execution/pact-consumer-runtime.js +3 -409
  161. package/packages/client/dist/private-execution/pact-test-source.js +1 -258
  162. package/packages/client/dist/private-execution/pact-toolchain.js +3 -290
  163. package/packages/client/dist/private-execution/pact-write-set.js +1 -172
  164. package/packages/client/dist/private-execution/planning-diagnosis-checkpoint.js +5 -406
  165. package/packages/client/dist/private-execution/planning-generation-checkpoint.js +5 -462
  166. package/packages/client/dist/private-execution/planning-memory-checkpoint.js +3 -139
  167. package/packages/client/dist/private-execution/planning-research-checkpoint.js +4 -325
  168. package/packages/client/dist/private-execution/private-report-store.js +1 -42
  169. package/packages/client/dist/private-execution/property-test-candidate.js +1 -103
  170. package/packages/client/dist/private-execution/property-test-choices.js +3 -147
  171. package/packages/client/dist/private-execution/property-test-plan.js +7 -271
  172. package/packages/client/dist/private-execution/property-test-review.js +4 -258
  173. package/packages/client/dist/private-execution/property-test-runtime.js +9 -372
  174. package/packages/client/dist/private-execution/property-test-source.js +1 -139
  175. package/packages/client/dist/private-execution/root-checkpoint.js +1 -80
  176. package/packages/client/dist/private-execution/root-memory-git-evidence.js +3 -135
  177. package/packages/client/dist/private-execution/root-memory-recovery.js +1 -93
  178. package/packages/client/dist/private-execution/root-memory-request.js +1 -29
  179. package/packages/client/dist/private-execution/root-memory-scope.js +1 -178
  180. package/packages/client/dist/private-execution/root-memory-writer.js +1 -102
  181. package/packages/client/dist/private-execution/session-lease.js +1 -63
  182. package/packages/client/dist/private-execution/shared-private-admission-types.js +1 -50
  183. package/packages/client/dist/private-execution/shared-project-validation.js +1 -66
  184. package/packages/client/dist/private-execution/shared-root-memory-types.js +1 -61
  185. package/packages/client/dist/private-execution/ux-source-validation.js +1 -372
  186. package/packages/client/dist/private-execution/ux-write-set.js +2 -191
  187. package/packages/client/dist/registry/registry-reconciliation.js +1 -234
  188. package/packages/client/dist/resilience/circuit-breaker.js +1 -170
  189. package/packages/client/dist/resilience/degradation-manager.js +1 -164
  190. package/packages/client/dist/resilience/freshness-indicator.js +1 -100
  191. package/packages/client/dist/resilience/index.js +1 -8
  192. package/packages/client/dist/resilience/recovery-detector.js +1 -74
  193. package/packages/client/dist/resolvers/asset-resolver.js +0 -13
  194. package/packages/client/dist/resolvers/local-resolver.js +8 -255
  195. package/packages/client/dist/resolvers/remote-resolver.js +1 -233
  196. package/packages/client/dist/runner/binary.js +1 -404
  197. package/packages/client/dist/runner/cli.js +17 -1571
  198. package/packages/client/dist/runner/epic-background-dispatcher.d.ts +61 -0
  199. package/packages/client/dist/runner/epic-background-dispatcher.js +1 -0
  200. package/packages/client/dist/runner/headless/adapters.js +1 -49
  201. package/packages/client/dist/runner/headless/background-root.d.ts +65 -0
  202. package/packages/client/dist/runner/headless/background-root.js +1 -0
  203. package/packages/client/dist/runner/headless/claude-code-adapter.js +1 -79
  204. package/packages/client/dist/runner/headless/continuous-story-workspace.js +11 -1628
  205. package/packages/client/dist/runner/headless/epic-git-reconciliation-inventory.js +1 -69
  206. package/packages/client/dist/runner/headless/epic-merge-candidate-qa.d.ts +1 -1
  207. package/packages/client/dist/runner/headless/epic-merge-candidate-qa.js +2 -110
  208. package/packages/client/dist/runner/headless/epic-terminal-git-cli-adapter.d.ts +2 -0
  209. package/packages/client/dist/runner/headless/epic-terminal-git-cli-adapter.js +10 -1236
  210. package/packages/client/dist/runner/headless/epic-terminal-git-runner.d.ts +27 -2
  211. package/packages/client/dist/runner/headless/epic-terminal-git-runner.js +2 -318
  212. package/packages/client/dist/runner/headless/fake-adapter.js +1 -62
  213. package/packages/client/dist/runner/headless/managed-environment-cleanup.d.ts +95 -0
  214. package/packages/client/dist/runner/headless/managed-environment-cleanup.js +1 -0
  215. package/packages/client/dist/runner/headless/managed-profile.js +1 -132
  216. package/packages/client/dist/runner/headless/opencode-adapter.js +2 -145
  217. package/packages/client/dist/runner/headless/prepared-story-bundle.js +1 -43
  218. package/packages/client/dist/runner/headless/resolver.js +1 -231
  219. package/packages/client/dist/runner/headless/run-yolo.js +1 -885
  220. package/packages/client/dist/runner/headless/run-yoloop.d.ts +1 -0
  221. package/packages/client/dist/runner/headless/run-yoloop.js +2 -2574
  222. package/packages/client/dist/runner/headless/types.js +2 -574
  223. package/packages/client/dist/runner/local-console.js +13 -396
  224. package/packages/client/dist/runner/portal-sync-worker.js +1 -1487
  225. package/packages/client/dist/runner/project-identity.js +1 -106
  226. package/packages/client/dist/runner/scheduler.js +7 -995
  227. package/packages/client/dist/runner-cli.js +2 -18
  228. package/packages/client/dist/state/invocation-shape.js +1 -13
  229. package/packages/client/dist/state/project-state-snapshot.d.ts +7 -0
  230. package/packages/client/dist/state/project-state-snapshot.js +1 -1731
  231. package/packages/client/dist/state/state-json-repair.js +3 -785
  232. package/packages/client/dist/state/structural-dag-projection.js +1 -118
  233. package/packages/client/dist/telemetry/index.js +1 -5
  234. package/packages/client/dist/telemetry/offline-queue.js +1 -131
  235. package/packages/client/dist/tier/index.js +1 -5
  236. package/packages/client/dist/tier/tier-aware-client.js +1 -405
  237. package/packages/client/dist/types/index.js +1 -38
  238. package/packages/client/dist/version.js +1 -27
  239. package/packages/client/dist/yolo/change-evidence-collector.d.ts +21 -1
  240. package/packages/client/dist/yolo/change-evidence-collector.js +1 -126
  241. package/packages/client/dist/yolo/invoke-envelope-capability.js +1 -62
  242. package/packages/client/dist/yolo/spec-envelope-collector.js +5 -184
  243. package/packages/client/dist/yoloop/discovery-hook.js +2 -300
  244. package/packages/client/dist/yoloop/index.js +1 -8
  245. package/packages/client/dist/yoloop/invoke-hooks.js +12 -669
  246. package/packages/client/dist/yoloop/shared-discover-epics.js +1 -1007
  247. package/packages/client/dist/yoloop/shared-yoloop-types.js +1 -33
  248. package/packages/client/dist/yoloop/target-normalization.js +1 -180
  249. package/packages/client/dist/yoloop/yoloop-client-state-store.js +1 -1920
  250. package/packages/shared/dist/invocation/explicit-intent-recovery.d.ts +83 -0
  251. package/packages/shared/dist/invocation/explicit-intent-recovery.js +187 -0
  252. package/packages/shared/dist/invocation/index.d.ts +7 -0
  253. package/packages/shared/dist/invocation/index.js +22 -0
  254. package/packages/shared/dist/yolo/change-evidence.js +1 -1
  255. package/packages/shared/dist/yoloop/epic-terminal-git.js +144 -2
  256. package/targets-stubs/antigravity/gemini.md +1 -1
  257. package/targets-stubs/antigravity/skill/SKILL.md +1 -1
  258. package/targets-stubs/claude-code/neocortex-root.agent.yaml +1 -1
  259. package/targets-stubs/claude-code/neocortex-root.md +2 -2
  260. package/targets-stubs/claude-code/neocortex.agent.yaml +1 -1
  261. package/targets-stubs/claude-code/neocortex.md +2 -2
  262. package/targets-stubs/codex/AGENTS.md +24 -21
  263. package/targets-stubs/codex/README.md +6 -1
  264. package/targets-stubs/codex/neocortex.toml +7 -2
  265. package/targets-stubs/cursor/agent.md +2 -2
  266. package/targets-stubs/gemini-cli/agent.md +2 -2
  267. package/targets-stubs/opencode/neocortex-root.md +16 -1
  268. package/targets-stubs/opencode/neocortex.md +6 -0
  269. 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};