@fitlab-ai/agent-infra 0.9.7 → 0.9.9

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 (195) hide show
  1. package/README.md +1 -1
  2. package/README.zh-CN.md +1 -1
  3. package/dist/bin/internal-cli.js +11 -1
  4. package/dist/lib/agent-clients/adapters/claude-code.js +3 -3
  5. package/dist/lib/agent-clients/adapters/codex-lifecycle/app-server.js +60 -22
  6. package/dist/lib/agent-clients/adapters/codex-lifecycle/build-identity.js +8 -1
  7. package/dist/lib/agent-clients/adapters/codex-lifecycle/capability-store.js +175 -11
  8. package/dist/lib/agent-clients/adapters/codex-lifecycle/controller-context.js +147 -0
  9. package/dist/lib/agent-clients/adapters/codex-lifecycle/evidence.js +14 -0
  10. package/dist/lib/agent-clients/adapters/codex-lifecycle/sandbox-controller.js +86 -69
  11. package/dist/lib/agent-clients/adapters/codex-lifecycle/store.js +2 -1
  12. package/dist/lib/decide.js +68 -14
  13. package/dist/lib/git/workflow.js +10 -1
  14. package/dist/lib/init.js +1 -1
  15. package/dist/lib/internal/codex-lifecycle.js +19 -5
  16. package/dist/lib/internal/codex-sandbox-controller.js +6 -13
  17. package/dist/lib/internal/git-workflow.js +5 -7
  18. package/dist/lib/internal/platform-pr.js +20 -7
  19. package/dist/lib/internal/release-workflow.js +3 -4
  20. package/dist/lib/internal/sandbox-control.js +79 -2
  21. package/dist/lib/internal/task-activity.js +57 -7
  22. package/dist/lib/internal/task-event.js +57 -4
  23. package/dist/lib/internal/task-finalization.js +54 -0
  24. package/dist/lib/internal/task-ledger.js +59 -5
  25. package/dist/lib/internal/task-lifecycle.js +59 -8
  26. package/dist/lib/internal/task-orchestration.js +161 -288
  27. package/dist/lib/internal/task-override.js +131 -0
  28. package/dist/lib/internal/task-review.js +64 -6
  29. package/dist/lib/internal/task-verify.js +65 -3
  30. package/dist/lib/internal/task-warning.js +57 -4
  31. package/dist/lib/platform/pr-summary.js +53 -13
  32. package/dist/lib/platform/pull-requests.js +205 -41
  33. package/dist/lib/runtime/agent-runtime.js +56 -0
  34. package/dist/lib/sandbox/commands/create.js +389 -311
  35. package/dist/lib/sandbox/commands/rm.js +316 -55
  36. package/dist/lib/sandbox/control/client.js +190 -6
  37. package/dist/lib/sandbox/control/container-identity.js +1 -1
  38. package/dist/lib/sandbox/control/controller-registration.js +273 -0
  39. package/dist/lib/sandbox/control/executor.js +145 -5
  40. package/dist/lib/sandbox/control/lifecycle.js +395 -73
  41. package/dist/lib/sandbox/control/protocol.js +67 -6
  42. package/dist/lib/sandbox/control/state.js +27 -11
  43. package/dist/lib/sandbox/engine.js +14 -7
  44. package/dist/lib/sandbox/index.js +5 -3
  45. package/dist/lib/sandbox/managed-fs.js +5 -0
  46. package/dist/lib/sandbox/mounts.js +20 -5
  47. package/dist/lib/sandbox/recovery.js +78 -10
  48. package/dist/lib/sandbox/task-resolver.js +50 -6
  49. package/dist/lib/sandbox/workspace-identity.js +27 -0
  50. package/dist/lib/sandbox/workspace-view.js +62 -40
  51. package/dist/lib/sandbox/worktree-safety.js +215 -2
  52. package/dist/lib/server/process-state.js +51 -1
  53. package/dist/lib/task/activity-intent.js +4 -1
  54. package/dist/lib/task/codex-orchestration.js +158 -33
  55. package/dist/lib/task/commands/status.js +59 -1
  56. package/dist/lib/task/commit-operation.js +335 -0
  57. package/dist/lib/task/commit-policy.js +18 -0
  58. package/dist/lib/task/decision-intents.js +4 -2
  59. package/dist/lib/task/delegation-receipts.js +279 -17
  60. package/dist/lib/task/events.js +9 -5
  61. package/dist/lib/task/finalization.js +567 -0
  62. package/dist/lib/task/guard-override.js +31 -0
  63. package/dist/lib/task/human-override.js +1240 -0
  64. package/dist/lib/task/ledger-intents.js +6 -3
  65. package/dist/lib/task/lifecycle.js +69 -14
  66. package/dist/lib/task/operation-outcome.js +33 -0
  67. package/dist/lib/task/orchestration.js +199 -719
  68. package/dist/lib/task/review-finalization.js +3 -2
  69. package/dist/lib/task/short-id.js +59 -1
  70. package/dist/lib/task/task-execution-lock.js +6 -1
  71. package/dist/lib/task/verification-engine.js +138 -59
  72. package/dist/lib/task/verification.js +15 -2
  73. package/dist/lib/task/workflow-warning-intents.js +54 -3
  74. package/dist/lib/task/write.js +2 -1
  75. package/dist/lifecycle-build-manifest.json +3 -3
  76. package/lib/agent-clients/adapters/claude-code.ts +3 -3
  77. package/lib/agent-clients/adapters/codex-lifecycle/app-server.ts +63 -20
  78. package/lib/agent-clients/adapters/codex-lifecycle/build-identity.ts +12 -0
  79. package/lib/agent-clients/adapters/codex-lifecycle/capability-store.ts +278 -13
  80. package/lib/agent-clients/adapters/codex-lifecycle/controller-context.ts +180 -0
  81. package/lib/agent-clients/adapters/codex-lifecycle/evidence.ts +19 -0
  82. package/lib/agent-clients/adapters/codex-lifecycle/manifest-files.json +9 -1
  83. package/lib/agent-clients/adapters/codex-lifecycle/sandbox-controller.ts +112 -93
  84. package/lib/agent-clients/adapters/codex-lifecycle/store.ts +2 -1
  85. package/lib/decide.ts +59 -14
  86. package/lib/git/workflow.ts +11 -2
  87. package/lib/init.ts +1 -1
  88. package/lib/internal/codex-lifecycle.ts +18 -5
  89. package/lib/internal/codex-sandbox-controller.ts +6 -12
  90. package/lib/internal/git-workflow.ts +5 -6
  91. package/lib/internal/platform-pr.ts +14 -7
  92. package/lib/internal/release-workflow.ts +3 -4
  93. package/lib/internal/sandbox-control.ts +92 -2
  94. package/lib/internal/task-activity.ts +46 -6
  95. package/lib/internal/task-event.ts +53 -4
  96. package/lib/internal/task-finalization.ts +68 -0
  97. package/lib/internal/task-ledger.ts +48 -4
  98. package/lib/internal/task-lifecycle.ts +56 -12
  99. package/lib/internal/task-orchestration.ts +32 -107
  100. package/lib/internal/task-override.ts +138 -0
  101. package/lib/internal/task-review.ts +51 -6
  102. package/lib/internal/task-verify.ts +52 -3
  103. package/lib/internal/task-warning.ts +44 -3
  104. package/lib/platform/pr-summary.ts +65 -14
  105. package/lib/platform/pull-requests.ts +211 -41
  106. package/lib/runtime/agent-runtime.ts +76 -0
  107. package/lib/sandbox/commands/create.ts +88 -4
  108. package/lib/sandbox/commands/rm.ts +413 -61
  109. package/lib/sandbox/config.ts +2 -1
  110. package/lib/sandbox/control/client.ts +255 -6
  111. package/lib/sandbox/control/container-identity.ts +3 -3
  112. package/lib/sandbox/control/controller-registration.ts +347 -0
  113. package/lib/sandbox/control/executor.ts +172 -6
  114. package/lib/sandbox/control/lifecycle.ts +465 -77
  115. package/lib/sandbox/control/protocol.ts +85 -9
  116. package/lib/sandbox/control/state.ts +35 -18
  117. package/lib/sandbox/engine.ts +20 -9
  118. package/lib/sandbox/index.ts +5 -3
  119. package/lib/sandbox/managed-fs.ts +5 -0
  120. package/lib/sandbox/mounts.ts +23 -5
  121. package/lib/sandbox/recovery.ts +90 -9
  122. package/lib/sandbox/task-resolver.ts +58 -7
  123. package/lib/sandbox/workspace-identity.ts +50 -2
  124. package/lib/sandbox/workspace-view.ts +73 -43
  125. package/lib/sandbox/worktree-safety.ts +236 -2
  126. package/lib/server/process-state.ts +48 -1
  127. package/lib/task/activity-intent.ts +4 -2
  128. package/lib/task/codex-orchestration.ts +167 -33
  129. package/lib/task/commands/status.ts +78 -1
  130. package/lib/task/commit-operation.ts +430 -0
  131. package/lib/task/commit-policy.ts +30 -0
  132. package/lib/task/decision-intents.ts +4 -2
  133. package/lib/task/delegation-receipts.ts +304 -19
  134. package/lib/task/events.ts +10 -5
  135. package/lib/task/finalization.ts +719 -0
  136. package/lib/task/guard-override.ts +50 -0
  137. package/lib/task/human-override.ts +1503 -0
  138. package/lib/task/ledger-intents.ts +6 -3
  139. package/lib/task/lifecycle.ts +71 -14
  140. package/lib/task/operation-outcome.ts +48 -0
  141. package/lib/task/orchestration.ts +239 -922
  142. package/lib/task/review-finalization.ts +6 -2
  143. package/lib/task/short-id.ts +65 -1
  144. package/lib/task/task-execution-lock.ts +10 -1
  145. package/lib/task/verification-engine.ts +145 -64
  146. package/lib/task/verification.ts +18 -3
  147. package/lib/task/workflow-warning-intents.ts +61 -4
  148. package/lib/task/write.ts +4 -1
  149. package/package.json +2 -2
  150. package/templates/.agents/QUICKSTART.en.md +2 -2
  151. package/templates/.agents/QUICKSTART.zh-CN.md +2 -2
  152. package/templates/.agents/hooks/lifecycle-delegation.js +9 -24
  153. package/templates/.agents/rules/lifecycle-orchestration.en.md +4 -3
  154. package/templates/.agents/rules/lifecycle-orchestration.zh-CN.md +4 -3
  155. package/templates/.agents/rules/task-management.en.md +2 -2
  156. package/templates/.agents/rules/task-management.zh-CN.md +2 -2
  157. package/templates/.agents/skills/block-task/SKILL.en.md +2 -4
  158. package/templates/.agents/skills/block-task/SKILL.zh-CN.md +2 -4
  159. package/templates/.agents/skills/cancel-task/SKILL.en.md +3 -3
  160. package/templates/.agents/skills/cancel-task/SKILL.zh-CN.md +3 -3
  161. package/templates/.agents/skills/close-codescan/SKILL.en.md +6 -2
  162. package/templates/.agents/skills/close-codescan/SKILL.zh-CN.md +6 -2
  163. package/templates/.agents/skills/close-dependabot/SKILL.en.md +6 -2
  164. package/templates/.agents/skills/close-dependabot/SKILL.zh-CN.md +6 -2
  165. package/templates/.agents/skills/commit/SKILL.en.md +41 -125
  166. package/templates/.agents/skills/commit/SKILL.zh-CN.md +52 -123
  167. package/templates/.agents/skills/commit/reference/commit-message.en.md +1 -1
  168. package/templates/.agents/skills/commit/reference/commit-message.zh-CN.md +1 -1
  169. package/templates/.agents/skills/commit/reference/commit-orchestration.en.md +14 -43
  170. package/templates/.agents/skills/commit/reference/commit-orchestration.zh-CN.md +14 -49
  171. package/templates/.agents/skills/commit/reference/pr-summary-sync.en.md +1 -1
  172. package/templates/.agents/skills/commit/reference/pr-summary-sync.zh-CN.md +1 -1
  173. package/templates/.agents/skills/commit/reference/task-status-update.en.md +2 -35
  174. package/templates/.agents/skills/commit/reference/task-status-update.zh-CN.md +2 -35
  175. package/templates/.agents/skills/complete-task/SKILL.en.md +31 -38
  176. package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +31 -38
  177. package/templates/.agents/skills/complete-task/config/verify.en.json +1 -0
  178. package/templates/.agents/skills/complete-task/config/verify.zh-CN.json +1 -0
  179. package/templates/.agents/skills/complete-task/reference/external-delivery.en.md +1 -1
  180. package/templates/.agents/skills/complete-task/reference/external-delivery.zh-CN.md +1 -1
  181. package/templates/.agents/skills/create-pr/SKILL.en.md +6 -4
  182. package/templates/.agents/skills/create-pr/SKILL.zh-CN.md +6 -4
  183. package/templates/.agents/skills/create-pr/reference/comment-publish.en.md +2 -2
  184. package/templates/.agents/skills/create-pr/reference/comment-publish.zh-CN.md +2 -2
  185. package/templates/.agents/skills/run-task/SKILL.en.md +5 -5
  186. package/templates/.agents/skills/run-task/SKILL.zh-CN.md +5 -5
  187. package/templates/.agents/skills/run-task/reference/host-validation.en.md +3 -1
  188. package/templates/.agents/skills/run-task/reference/host-validation.zh-CN.md +3 -1
  189. package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.en.md +1 -1
  190. package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.zh-CN.md +1 -1
  191. package/templates/.codex/hooks.json +4 -4
  192. package/dist/lib/task/commit-finalization.js +0 -305
  193. package/dist/lib/task/commit-intent.js +0 -165
  194. package/lib/task/commit-finalization.ts +0 -419
  195. package/lib/task/commit-intent.ts +0 -230
@@ -1,18 +1,34 @@
1
- import fs from 'node:fs';
2
1
  import { preflightCodexLifecycleEvidence, resolveCodexSpawnedChild, resolveCodexTerminal, resolveCodexThread } from '../agent-clients/adapters/codex-lifecycle/app-server.js';
3
2
  import { createCodexLifecycleStore } from '../agent-clients/adapters/codex-lifecycle/store.js';
4
- import { createCodexCapabilityStore } from '../agent-clients/adapters/codex-lifecycle/capability-store.js';
3
+ import { createCodexCapabilityStore, isCodexCapabilityProvenanceDetail } from '../agent-clients/adapters/codex-lifecycle/capability-store.js';
5
4
  import { computeLifecycleBuildIdentity } from '../agent-clients/adapters/codex-lifecycle/build-identity.js';
6
5
  import { verifyCodexSandboxControllerContext } from '../agent-clients/adapters/codex-lifecycle/sandbox-controller.js';
6
+ import { verifyCodexSandboxControllerContext as verifyControllerContextFile } from '../agent-clients/adapters/codex-lifecycle/controller-context.js';
7
7
  import { resolveTaskRef } from './resolve-ref.js';
8
- import { activateMatchingOrchestrationDelegation, hasActivatableOrchestrationDelegation, hasSealableOrchestrationDelegation, pauseMatchingOrchestrationDelegation, prepareOrchestrationDelegation, reconcileMatchingOrchestrationDelegation, sealMatchingOrchestrationDelegationWithHostEvidence } from './orchestration.js';
8
+ import { activateMatchingOrchestrationDelegation, hasActivatableOrchestrationDelegation, hasSealableOrchestrationDelegation, OrchestrationStateError, pauseMatchingOrchestrationDelegation, prepareOrchestrationDelegation, reconcileMatchingOrchestrationDelegation, sealMatchingOrchestrationDelegationWithHostEvidence } from './orchestration.js';
9
9
  function coreOptions(options) {
10
10
  return { ...options.orchestrationOptions, repoRoot: options.repoRoot ?? options.orchestrationOptions?.repoRoot };
11
11
  }
12
- function bridgeFailure(code, message) {
12
+ function bridgeFailure(code, message, detail) {
13
13
  return {
14
14
  status: 'failed', changed: false, taskId: null, run: null, next: null,
15
- error: { code, message }
15
+ error: { code, message, ...(detail ? { detail } : {}) }
16
+ };
17
+ }
18
+ function capabilityFailure(error) {
19
+ const detailValue = error instanceof Error
20
+ ? error.detail
21
+ : undefined;
22
+ return {
23
+ code: error instanceof Error && error.name.startsWith('CODEX_CAPABILITY_')
24
+ ? error.name
25
+ : 'ORCHESTRATION_CLIENT_PREFLIGHT_FAILED',
26
+ message: error instanceof Error ? error.message : String(error),
27
+ ...(error instanceof Error
28
+ && error.name === 'CODEX_CAPABILITY_PROVENANCE_MISMATCH'
29
+ && isCodexCapabilityProvenanceDetail(detailValue)
30
+ ? { detail: detailValue }
31
+ : {})
16
32
  };
17
33
  }
18
34
  function pauseBridge(code, message, options) {
@@ -26,11 +42,50 @@ function requiredStore(options) {
26
42
  throw new Error('Codex lifecycle store is required for orchestration bridge events');
27
43
  return options.store;
28
44
  }
29
- function controllerContext(taskId, repoRoot) {
45
+ function controllerContext(repoRoot, brokerController) {
30
46
  const contextPath = process.env.AGENT_INFRA_CODEX_CONTROLLER_CONTEXT;
31
- return contextPath
32
- ? verifyCodexSandboxControllerContext(contextPath, taskId, { repoRoot })
33
- : null;
47
+ if (!contextPath)
48
+ return null;
49
+ if (brokerController) {
50
+ return verifyControllerContextFile(contextPath, {
51
+ repoRoot,
52
+ generation: process.env.AGENT_INFRA_CONTROL_GENERATION ?? brokerController.controlGeneration
53
+ });
54
+ }
55
+ return verifyCodexSandboxControllerContext(contextPath, { repoRoot });
56
+ }
57
+ function brokerBindingConflictsWithContext(repoRoot, brokerController) {
58
+ const contextPath = process.env.AGENT_INFRA_CODEX_CONTROLLER_CONTEXT;
59
+ if (!contextPath || !brokerController)
60
+ return false;
61
+ const context = verifyControllerContextFile(contextPath, {
62
+ repoRoot,
63
+ generation: process.env.AGENT_INFRA_CONTROL_GENERATION ?? brokerController.controlGeneration
64
+ });
65
+ return context.controllerInstanceDigest !== brokerController.instanceDigest
66
+ || context.controlGeneration !== brokerController.controlGeneration;
67
+ }
68
+ function brokerControllerBinding() {
69
+ const raw = process.env.AGENT_INFRA_CONTROL_CONTROLLER_BINDING;
70
+ if (!raw)
71
+ return null;
72
+ let value;
73
+ try {
74
+ value = JSON.parse(raw);
75
+ }
76
+ catch {
77
+ throw new Error('CODEX_SANDBOX_CONTROLLER_BINDING_INVALID');
78
+ }
79
+ if (!value || typeof value !== 'object' || Array.isArray(value)) {
80
+ throw new Error('CODEX_SANDBOX_CONTROLLER_BINDING_INVALID');
81
+ }
82
+ const binding = value;
83
+ if (Object.keys(binding).sort().join(',') !== 'controlGeneration,instanceDigest'
84
+ || typeof binding.instanceDigest !== 'string' || !/^[a-f0-9]{64}$/u.test(binding.instanceDigest)
85
+ || typeof binding.controlGeneration !== 'string' || binding.controlGeneration.length === 0) {
86
+ throw new Error('CODEX_SANDBOX_CONTROLLER_BINDING_INVALID');
87
+ }
88
+ return binding;
34
89
  }
35
90
  async function prepareCodexOrchestrationDelegation(taskRef, input, options = {}) {
36
91
  if (input.client !== 'codex')
@@ -45,35 +100,96 @@ async function prepareCodexOrchestrationDelegation(taskRef, input, options = {})
45
100
  return bridgeFailure('ORCHESTRATION_CODEX_CAPABILITY_REQUIRED', 'Codex prepare requires a current-session capability token');
46
101
  }
47
102
  const buildIdentity = options.buildIdentity ?? computeLifecycleBuildIdentity(repoRoot);
48
- const controller = controllerContext(resolved.taskId, repoRoot);
103
+ const brokerController = brokerControllerBinding();
104
+ if (brokerBindingConflictsWithContext(repoRoot, brokerController)) {
105
+ return bridgeFailure('CODEX_SANDBOX_CONTROLLER_BINDING_MISMATCH', 'broker and local controller bindings do not match');
106
+ }
107
+ const localController = controllerContext(repoRoot, brokerController);
108
+ if (localController && brokerController
109
+ && (localController.controllerInstanceDigest !== brokerController.instanceDigest
110
+ || localController.controlGeneration !== brokerController.controlGeneration)) {
111
+ return bridgeFailure('CODEX_SANDBOX_CONTROLLER_BINDING_MISMATCH', 'broker and local controller bindings do not match');
112
+ }
113
+ const controller = brokerController ?? (localController ? {
114
+ instanceDigest: localController.controllerInstanceDigest,
115
+ controlGeneration: localController.controlGeneration
116
+ } : null);
49
117
  const capabilityStore = options.capabilityStore ?? createCodexCapabilityStore();
50
- const consumed = capabilityStore.consume(input.capabilityToken, {
118
+ const attested = capabilityStore.inspect(input.capabilityToken);
119
+ const lifecycleProvenance = {
120
+ ...attested.buildIdentity,
121
+ hookDefinitionHash: preflight.hookDefinitionHash,
122
+ ...preflight.hookProvenance,
123
+ capabilitySessionId: attested.sessionId,
124
+ capabilityTurnId: attested.turnId,
125
+ capabilityToolUseId: attested.toolUseId,
126
+ controllerInstanceDigest: controller?.instanceDigest ?? null,
127
+ controlGeneration: controller?.controlGeneration ?? null
128
+ };
129
+ const capabilityExpected = {
51
130
  taskId: resolved.taskId,
52
131
  hookDefinitionHash: preflight.hookDefinitionHash,
53
132
  buildIdentity,
54
133
  ...(controller ? { controller: {
55
- instanceDigest: controller.controllerInstanceDigest,
134
+ instanceDigest: controller.instanceDigest,
56
135
  controlGeneration: controller.controlGeneration
57
136
  } } : {})
58
- });
137
+ };
59
138
  return prepareOrchestrationDelegation(taskRef, {
60
139
  ...input,
61
- lifecycleProvenance: {
62
- ...consumed.buildIdentity,
63
- hookDefinitionHash: preflight.hookDefinitionHash,
64
- ...preflight.hookProvenance,
65
- capabilitySessionId: consumed.sessionId,
66
- capabilityTurnId: consumed.turnId,
67
- capabilityToolUseId: consumed.toolUseId,
68
- controllerInstanceDigest: controller?.controllerInstanceDigest ?? null,
69
- controlGeneration: controller?.controlGeneration ?? null
140
+ lifecycleProvenance
141
+ }, {
142
+ ...coreOptions(options),
143
+ validateLifecycleCapability: () => {
144
+ try {
145
+ const validated = capabilityStore.validate(input.capabilityToken, capabilityExpected);
146
+ if (validated.sessionId !== attested.sessionId
147
+ || validated.turnId !== attested.turnId
148
+ || validated.toolUseId !== attested.toolUseId) {
149
+ return {
150
+ code: 'CODEX_CAPABILITY_IDENTITY_CHANGED',
151
+ message: 'capability identity changed during validation'
152
+ };
153
+ }
154
+ return null;
155
+ }
156
+ catch (error) {
157
+ return capabilityFailure(error);
158
+ }
159
+ },
160
+ consumeLifecycleCapability: () => {
161
+ try {
162
+ const consumed = capabilityStore.consume(input.capabilityToken, capabilityExpected);
163
+ if (consumed.sessionId !== attested.sessionId
164
+ || consumed.turnId !== attested.turnId
165
+ || consumed.toolUseId !== attested.toolUseId) {
166
+ return {
167
+ code: 'CODEX_CAPABILITY_IDENTITY_CHANGED',
168
+ message: 'capability identity changed during consumption'
169
+ };
170
+ }
171
+ return null;
172
+ }
173
+ catch (error) {
174
+ return capabilityFailure(error);
175
+ }
70
176
  }
71
- }, coreOptions(options));
177
+ });
72
178
  }
73
179
  catch (error) {
180
+ if (error instanceof OrchestrationStateError)
181
+ return bridgeFailure(error.code, error.message);
182
+ const detailValue = error instanceof Error
183
+ ? error.detail
184
+ : undefined;
185
+ const detail = error instanceof Error
186
+ && error.name === 'CODEX_CAPABILITY_PROVENANCE_MISMATCH'
187
+ && isCodexCapabilityProvenanceDetail(detailValue)
188
+ ? detailValue
189
+ : undefined;
74
190
  return bridgeFailure(error instanceof Error && error.name.startsWith('CODEX_CAPABILITY_')
75
191
  ? error.name
76
- : 'ORCHESTRATION_CLIENT_PREFLIGHT_FAILED', error instanceof Error ? error.message : String(error));
192
+ : 'ORCHESTRATION_CLIENT_PREFLIGHT_FAILED', error instanceof Error ? error.message : String(error), detail);
77
193
  }
78
194
  }
79
195
  async function activateCodexOrchestrationDelegation(childThreadId, options = {}) {
@@ -100,14 +216,8 @@ async function activateCodexOrchestrationDelegation(childThreadId, options = {})
100
216
  });
101
217
  const buildIdentity = options.buildIdentity ?? computeLifecycleBuildIdentity(repoRoot);
102
218
  const contextPath = process.env.AGENT_INFRA_CODEX_CONTROLLER_CONTEXT;
103
- const contextTaskId = contextPath
104
- ? JSON.parse(fs.readFileSync(contextPath, 'utf8')).taskId
105
- : null;
106
- if (contextPath && typeof contextTaskId !== 'string') {
107
- throw new Error('CODEX_SANDBOX_CONTROLLER_CONTEXT_INVALID');
108
- }
109
219
  const controller = contextPath
110
- ? verifyCodexSandboxControllerContext(contextPath, contextTaskId, { repoRoot })
220
+ ? verifyCodexSandboxControllerContext(contextPath, { repoRoot })
111
221
  : null;
112
222
  return activateMatchingOrchestrationDelegation('codex', {
113
223
  nativeAgent: evidence.nativeAgent,
@@ -136,6 +246,8 @@ async function activateCodexOrchestrationDelegation(childThreadId, options = {})
136
246
  }, coreOptions(options));
137
247
  }
138
248
  catch (error) {
249
+ if (error instanceof OrchestrationStateError)
250
+ return bridgeFailure(error.code, error.message);
139
251
  return pauseBridge('ORCHESTRATION_CODEX_START_FAILED', error instanceof Error ? error.message : String(error), options);
140
252
  }
141
253
  }
@@ -160,6 +272,8 @@ async function activateCodexSpawnDelegation(spawn, options = {}) {
160
272
  });
161
273
  }
162
274
  catch (error) {
275
+ if (error instanceof OrchestrationStateError)
276
+ return bridgeFailure(error.code, error.message);
163
277
  return pauseBridge('ORCHESTRATION_CODEX_START_FAILED', error instanceof Error ? error.message : String(error), options);
164
278
  }
165
279
  }
@@ -171,7 +285,11 @@ async function sealCodexOrchestrationDelegation(childThreadId, options = {}) {
171
285
  const store = requiredStore(options);
172
286
  const existing = store.read(childThreadId);
173
287
  if (!existing.consumer) {
174
- store.apply(await (options.resolveTerminal ?? resolveCodexTerminal)(childThreadId));
288
+ const stopTurnId = existing.state.stop?.turnId;
289
+ if (!stopTurnId) {
290
+ return pauseBridge('ORCHESTRATION_CODEX_STOP_EVIDENCE_INVALID', 'Codex lifecycle stop hook is not available', options);
291
+ }
292
+ store.apply(await (options.resolveTerminal ?? resolveCodexTerminal)(childThreadId, stopTurnId));
175
293
  }
176
294
  const record = store.read(childThreadId);
177
295
  const evidence = record.state.stopEvidence;
@@ -188,6 +306,8 @@ async function sealCodexOrchestrationDelegation(childThreadId, options = {}) {
188
306
  }, coreOptions(options));
189
307
  }
190
308
  catch (error) {
309
+ if (error instanceof OrchestrationStateError)
310
+ return bridgeFailure(error.code, error.message);
191
311
  return pauseBridge('ORCHESTRATION_CODEX_STOP_FAILED', error instanceof Error ? error.message : String(error), options);
192
312
  }
193
313
  }
@@ -208,7 +328,10 @@ async function sealCodexParentDelegation(parentThreadId, options = {}) {
208
328
  const start = active.state.startEvidence;
209
329
  const child = active.state.child;
210
330
  if (!active.state.terminal) {
211
- store.apply(await (options.resolveTerminal ?? resolveCodexTerminal)(start.childThreadId));
331
+ const resolveTerminal = options.resolveTerminal ?? resolveCodexTerminal;
332
+ store.apply(active.state.stop
333
+ ? await resolveTerminal(start.childThreadId, active.state.stop.turnId)
334
+ : await resolveTerminal(start.childThreadId));
212
335
  }
213
336
  if (!store.read(start.childThreadId).state.stop) {
214
337
  store.apply({
@@ -223,6 +346,8 @@ async function sealCodexParentDelegation(parentThreadId, options = {}) {
223
346
  return sealCodexOrchestrationDelegation(start.childThreadId, options);
224
347
  }
225
348
  catch (error) {
349
+ if (error instanceof OrchestrationStateError)
350
+ return bridgeFailure(error.code, error.message);
226
351
  if (error instanceof Error && error.message === 'CODEX_TURN_NOT_TERMINAL') {
227
352
  return bridgeFailure('ORCHESTRATION_DELEGATION_MISSING', 'The matching Codex child has not completed');
228
353
  }
@@ -9,6 +9,7 @@ import { parseTaskFrontmatter, extractTitle } from '../frontmatter.js';
9
9
  import { loadShortIdByTaskId } from '../short-id.js';
10
10
  import { getOpenWorkflowWarnings, formatWorkflowWarningSummary } from '../workflow-warnings.js';
11
11
  import { parseActivityLog, pairEntries } from '../activity-log.js';
12
+ import { readRun } from '../orchestration.js';
12
13
  import { statusCard } from '../../server/display.js';
13
14
  const USAGE = `Usage: ai task status [<N | TASK-id> | --task <ref> | -t <ref>]
14
15
 
@@ -262,6 +263,38 @@ function collectRuntime(taskDir, workflow, run) {
262
263
  log: record.log_file
263
264
  };
264
265
  }
266
+ function pendingDelegationInfo(receipt) {
267
+ if (!receipt)
268
+ return null;
269
+ return {
270
+ id: receipt.id,
271
+ role: receipt.role,
272
+ stage: receipt.stage,
273
+ round: receipt.round,
274
+ artifact: receipt.artifact,
275
+ client: receipt.client,
276
+ status: receipt.status
277
+ };
278
+ }
279
+ function collectOrchestration(taskDir) {
280
+ const run = readRun(taskDir);
281
+ if (!run) {
282
+ return {
283
+ status: 'absent',
284
+ runId: DASH,
285
+ nextStage: DASH,
286
+ pause: null,
287
+ pendingDelegation: null
288
+ };
289
+ }
290
+ return {
291
+ status: run.status,
292
+ runId: run.runId,
293
+ nextStage: run.nextStage ?? DASH,
294
+ pause: run.pause,
295
+ pendingDelegation: pendingDelegationInfo(run.pendingDelegation)
296
+ };
297
+ }
265
298
  // Indent each label/value pair by two spaces and pad labels to a common width so
266
299
  // every section reads as an aligned "key value" block.
267
300
  function renderPairs(rows) {
@@ -284,6 +317,21 @@ function renderStatus(model) {
284
317
  else {
285
318
  lines.push(...renderPairs(model.artifacts.groups.map((group) => [group.stage, group.files.join(', ')])));
286
319
  }
320
+ lines.push('', 'Orchestration', ...renderPairs([
321
+ ['status', model.orchestration.status],
322
+ ['run_id', model.orchestration.runId],
323
+ ['next_stage', model.orchestration.nextStage],
324
+ ['pause_code', model.orchestration.pause?.code ?? DASH],
325
+ ['pause_message', model.orchestration.pause?.message ?? DASH],
326
+ ['recoverable', model.orchestration.pause ? String(model.orchestration.pause.recoverable) : DASH],
327
+ ['pending_id', model.orchestration.pendingDelegation?.id ?? DASH],
328
+ ['pending_role', model.orchestration.pendingDelegation?.role ?? DASH],
329
+ ['pending_stage', model.orchestration.pendingDelegation?.stage ?? DASH],
330
+ ['pending_round', model.orchestration.pendingDelegation ? String(model.orchestration.pendingDelegation.round) : DASH],
331
+ ['pending_artifact', model.orchestration.pendingDelegation?.artifact ?? DASH],
332
+ ['pending_client', model.orchestration.pendingDelegation?.client ?? DASH],
333
+ ['pending_status', model.orchestration.pendingDelegation?.status ?? DASH]
334
+ ]));
287
335
  lines.push('', 'Workflow', ...renderPairs([
288
336
  ['state', model.workflow.state],
289
337
  ['step', model.workflow.step],
@@ -313,6 +361,12 @@ function renderStatus(model) {
313
361
  return lines;
314
362
  }
315
363
  function modelTone(model) {
364
+ if (model.orchestration.status === 'paused')
365
+ return 'warning';
366
+ if (model.orchestration.status === 'running')
367
+ return 'running';
368
+ if (model.orchestration.status === 'completed')
369
+ return 'success';
316
370
  if (model.workflow.state === 'in-progress')
317
371
  return model.workflow.stale === 'yes' ? 'warning' : 'running';
318
372
  if (model.metadata.some(([key, value]) => key === 'status' && value === 'completed'))
@@ -337,6 +391,7 @@ function buildFromResolved(input) {
337
391
  artifacts: { count: artifacts.length, groups: groupArtifacts(artifacts) },
338
392
  workflow,
339
393
  runtime: collectRuntime(input.taskDir, workflow, run),
394
+ orchestration: collectOrchestration(input.taskDir),
340
395
  git: collectGit(fm.branch ?? '', run)
341
396
  };
342
397
  }
@@ -359,6 +414,9 @@ function buildStatusModel(refOrInput, options = {}) {
359
414
  }
360
415
  function statusModelToDisplay(model) {
361
416
  return statusCard(`Task ${model.taskId} (${model.shortId})`, modelTone(model), [
417
+ ['orchestration', model.orchestration.status],
418
+ ['run', model.orchestration.runId],
419
+ ['next', model.orchestration.nextStage],
362
420
  ['workflow', model.workflow.state],
363
421
  ['step', model.workflow.step],
364
422
  ['runtime', model.runtime.status],
@@ -393,5 +451,5 @@ function status(args = []) {
393
451
  process.stdout.write(`${line}\n`);
394
452
  }
395
453
  }
396
- export { status, makeRunner, buildStatusModel, collectMetadata, groupArtifacts, collectGit, collectWorkflow, collectRuntime, renderStatus, statusModelToDisplay, METADATA_KEYS };
454
+ export { status, makeRunner, buildStatusModel, collectMetadata, groupArtifacts, collectGit, collectWorkflow, collectRuntime, collectOrchestration, renderStatus, statusModelToDisplay, METADATA_KEYS };
397
455
  //# sourceMappingURL=status.js.map