@fitlab-ai/agent-infra 0.9.8 → 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 (133) hide show
  1. package/README.md +1 -1
  2. package/README.zh-CN.md +1 -1
  3. package/dist/bin/internal-cli.js +6 -1
  4. package/dist/lib/agent-clients/adapters/codex-lifecycle/app-server.js +58 -21
  5. package/dist/lib/agent-clients/adapters/codex-lifecycle/build-identity.js +8 -1
  6. package/dist/lib/agent-clients/adapters/codex-lifecycle/capability-store.js +173 -10
  7. package/dist/lib/agent-clients/adapters/codex-lifecycle/controller-context.js +147 -0
  8. package/dist/lib/agent-clients/adapters/codex-lifecycle/evidence.js +14 -0
  9. package/dist/lib/agent-clients/adapters/codex-lifecycle/sandbox-controller.js +56 -67
  10. package/dist/lib/git/workflow.js +10 -1
  11. package/dist/lib/internal/codex-lifecycle.js +19 -5
  12. package/dist/lib/internal/codex-sandbox-controller.js +6 -13
  13. package/dist/lib/internal/git-workflow.js +5 -7
  14. package/dist/lib/internal/platform-pr.js +20 -7
  15. package/dist/lib/internal/release-workflow.js +2 -1
  16. package/dist/lib/internal/sandbox-control.js +79 -2
  17. package/dist/lib/internal/task-finalization.js +54 -0
  18. package/dist/lib/internal/task-orchestration.js +156 -291
  19. package/dist/lib/platform/pr-summary.js +48 -10
  20. package/dist/lib/platform/pull-requests.js +205 -41
  21. package/dist/lib/sandbox/commands/rm.js +316 -55
  22. package/dist/lib/sandbox/control/client.js +190 -6
  23. package/dist/lib/sandbox/control/controller-registration.js +273 -0
  24. package/dist/lib/sandbox/control/executor.js +137 -5
  25. package/dist/lib/sandbox/control/lifecycle.js +3 -1
  26. package/dist/lib/sandbox/control/protocol.js +67 -6
  27. package/dist/lib/sandbox/index.js +5 -3
  28. package/dist/lib/sandbox/managed-fs.js +5 -0
  29. package/dist/lib/sandbox/task-resolver.js +50 -6
  30. package/dist/lib/sandbox/workspace-identity.js +27 -0
  31. package/dist/lib/sandbox/worktree-safety.js +215 -2
  32. package/dist/lib/task/codex-orchestration.js +158 -33
  33. package/dist/lib/task/commands/status.js +59 -1
  34. package/dist/lib/task/commit-operation.js +335 -0
  35. package/dist/lib/task/commit-policy.js +18 -0
  36. package/dist/lib/task/delegation-receipts.js +243 -2
  37. package/dist/lib/task/finalization.js +567 -0
  38. package/dist/lib/task/operation-outcome.js +33 -0
  39. package/dist/lib/task/orchestration.js +187 -761
  40. package/dist/lib/task/short-id.js +59 -1
  41. package/dist/lib/task/task-execution-lock.js +6 -1
  42. package/dist/lib/task/verification-engine.js +113 -60
  43. package/dist/lib/task/verification.js +2 -1
  44. package/dist/lib/task/workflow-warning-intents.js +50 -1
  45. package/dist/lifecycle-build-manifest.json +3 -3
  46. package/lib/agent-clients/adapters/codex-lifecycle/app-server.ts +61 -19
  47. package/lib/agent-clients/adapters/codex-lifecycle/build-identity.ts +12 -0
  48. package/lib/agent-clients/adapters/codex-lifecycle/capability-store.ts +276 -12
  49. package/lib/agent-clients/adapters/codex-lifecycle/controller-context.ts +180 -0
  50. package/lib/agent-clients/adapters/codex-lifecycle/evidence.ts +19 -0
  51. package/lib/agent-clients/adapters/codex-lifecycle/manifest-files.json +9 -1
  52. package/lib/agent-clients/adapters/codex-lifecycle/sandbox-controller.ts +83 -91
  53. package/lib/git/workflow.ts +11 -2
  54. package/lib/internal/codex-lifecycle.ts +18 -5
  55. package/lib/internal/codex-sandbox-controller.ts +6 -12
  56. package/lib/internal/git-workflow.ts +5 -6
  57. package/lib/internal/platform-pr.ts +14 -7
  58. package/lib/internal/release-workflow.ts +2 -1
  59. package/lib/internal/sandbox-control.ts +92 -2
  60. package/lib/internal/task-finalization.ts +68 -0
  61. package/lib/internal/task-orchestration.ts +20 -103
  62. package/lib/platform/pr-summary.ts +55 -11
  63. package/lib/platform/pull-requests.ts +211 -41
  64. package/lib/sandbox/commands/rm.ts +413 -61
  65. package/lib/sandbox/control/client.ts +255 -6
  66. package/lib/sandbox/control/controller-registration.ts +347 -0
  67. package/lib/sandbox/control/executor.ts +163 -5
  68. package/lib/sandbox/control/lifecycle.ts +2 -1
  69. package/lib/sandbox/control/protocol.ts +80 -7
  70. package/lib/sandbox/index.ts +5 -3
  71. package/lib/sandbox/managed-fs.ts +5 -0
  72. package/lib/sandbox/task-resolver.ts +58 -7
  73. package/lib/sandbox/workspace-identity.ts +50 -2
  74. package/lib/sandbox/workspace-view.ts +3 -3
  75. package/lib/sandbox/worktree-safety.ts +236 -2
  76. package/lib/task/codex-orchestration.ts +167 -33
  77. package/lib/task/commands/status.ts +78 -1
  78. package/lib/task/commit-operation.ts +430 -0
  79. package/lib/task/commit-policy.ts +30 -0
  80. package/lib/task/delegation-receipts.ts +258 -1
  81. package/lib/task/finalization.ts +719 -0
  82. package/lib/task/operation-outcome.ts +48 -0
  83. package/lib/task/orchestration.ts +217 -982
  84. package/lib/task/short-id.ts +65 -1
  85. package/lib/task/task-execution-lock.ts +10 -1
  86. package/lib/task/verification-engine.ts +118 -63
  87. package/lib/task/verification.ts +3 -2
  88. package/lib/task/workflow-warning-intents.ts +57 -2
  89. package/package.json +2 -2
  90. package/templates/.agents/QUICKSTART.en.md +2 -2
  91. package/templates/.agents/QUICKSTART.zh-CN.md +2 -2
  92. package/templates/.agents/hooks/lifecycle-delegation.js +1 -21
  93. package/templates/.agents/rules/lifecycle-orchestration.en.md +1 -1
  94. package/templates/.agents/rules/lifecycle-orchestration.zh-CN.md +1 -1
  95. package/templates/.agents/rules/task-management.en.md +2 -2
  96. package/templates/.agents/rules/task-management.zh-CN.md +2 -2
  97. package/templates/.agents/skills/block-task/SKILL.en.md +2 -4
  98. package/templates/.agents/skills/block-task/SKILL.zh-CN.md +2 -4
  99. package/templates/.agents/skills/cancel-task/SKILL.en.md +3 -3
  100. package/templates/.agents/skills/cancel-task/SKILL.zh-CN.md +3 -3
  101. package/templates/.agents/skills/close-codescan/SKILL.en.md +6 -2
  102. package/templates/.agents/skills/close-codescan/SKILL.zh-CN.md +6 -2
  103. package/templates/.agents/skills/close-dependabot/SKILL.en.md +6 -2
  104. package/templates/.agents/skills/close-dependabot/SKILL.zh-CN.md +6 -2
  105. package/templates/.agents/skills/commit/SKILL.en.md +41 -125
  106. package/templates/.agents/skills/commit/SKILL.zh-CN.md +52 -123
  107. package/templates/.agents/skills/commit/reference/commit-message.en.md +1 -1
  108. package/templates/.agents/skills/commit/reference/commit-message.zh-CN.md +1 -1
  109. package/templates/.agents/skills/commit/reference/commit-orchestration.en.md +14 -43
  110. package/templates/.agents/skills/commit/reference/commit-orchestration.zh-CN.md +14 -49
  111. package/templates/.agents/skills/commit/reference/pr-summary-sync.en.md +1 -1
  112. package/templates/.agents/skills/commit/reference/pr-summary-sync.zh-CN.md +1 -1
  113. package/templates/.agents/skills/commit/reference/task-status-update.en.md +2 -35
  114. package/templates/.agents/skills/commit/reference/task-status-update.zh-CN.md +2 -35
  115. package/templates/.agents/skills/complete-task/SKILL.en.md +31 -38
  116. package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +31 -38
  117. package/templates/.agents/skills/complete-task/config/verify.en.json +1 -0
  118. package/templates/.agents/skills/complete-task/config/verify.zh-CN.json +1 -0
  119. package/templates/.agents/skills/complete-task/reference/external-delivery.en.md +1 -1
  120. package/templates/.agents/skills/complete-task/reference/external-delivery.zh-CN.md +1 -1
  121. package/templates/.agents/skills/create-pr/SKILL.en.md +6 -4
  122. package/templates/.agents/skills/create-pr/SKILL.zh-CN.md +6 -4
  123. package/templates/.agents/skills/create-pr/reference/comment-publish.en.md +2 -2
  124. package/templates/.agents/skills/create-pr/reference/comment-publish.zh-CN.md +2 -2
  125. package/templates/.agents/skills/run-task/SKILL.en.md +5 -5
  126. package/templates/.agents/skills/run-task/SKILL.zh-CN.md +5 -5
  127. package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.en.md +1 -1
  128. package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.zh-CN.md +1 -1
  129. package/templates/.codex/hooks.json +4 -4
  130. package/dist/lib/task/commit-finalization.js +0 -305
  131. package/dist/lib/task/commit-intent.js +0 -165
  132. package/lib/task/commit-finalization.ts +0 -419
  133. package/lib/task/commit-intent.ts +0 -230
@@ -1,5 +1,6 @@
1
1
  import { randomUUID } from 'node:crypto';
2
2
 
3
+ import { isAgentClientId } from '../agent-clients/types.ts';
3
4
  import type { AgentClientId } from '../agent-clients/types.ts';
4
5
  import { normalizeAgentToken } from '../agent-clients/tokens.ts';
5
6
 
@@ -87,6 +88,261 @@ type ReceiptFailure = Readonly<{ ok: false; code: string; message: string; recei
87
88
  type ReceiptSuccess = Readonly<{ ok: true; receipt: DelegationReceipt; code?: never; message?: never }>;
88
89
  type ReceiptResult = ReceiptSuccess | ReceiptFailure;
89
90
 
91
+ function isRecord(value: unknown): value is Record<string, unknown> {
92
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
93
+ }
94
+
95
+ function hasExactKeys(
96
+ value: unknown,
97
+ required: readonly string[],
98
+ optional: readonly string[] = []
99
+ ): value is Record<string, unknown> {
100
+ if (!isRecord(value)) return false;
101
+ const keys = Object.keys(value);
102
+ const allowed = new Set([...required, ...optional]);
103
+ return required.every((key) => Object.prototype.hasOwnProperty.call(value, key))
104
+ && keys.every((key) => allowed.has(key));
105
+ }
106
+
107
+ function exactText(value: unknown): value is string {
108
+ return typeof value === 'string' && value.length > 0 && value.trim() === value;
109
+ }
110
+
111
+ function nullableText(value: unknown): value is string | null {
112
+ return value === null || exactText(value);
113
+ }
114
+
115
+ function nullableSafeInteger(value: unknown): value is number | null {
116
+ return value === null || (Number.isSafeInteger(value) && (value as number) >= 0);
117
+ }
118
+
119
+ const LIFECYCLE_PROVENANCE_KEYS = [
120
+ 'protocolVersion', 'packageVersion', 'internalExecutableBuildHash', 'lifecycleContractHash',
121
+ 'hookDefinitionHash', 'hookSource', 'hookSourcePathDigest', 'hookSourceHash',
122
+ 'capabilitySessionId', 'capabilityTurnId', 'capabilityToolUseId',
123
+ 'controllerInstanceDigest', 'controlGeneration'
124
+ ] as const;
125
+
126
+ function isDelegationLifecycleProvenance(value: unknown): value is DelegationLifecycleProvenance {
127
+ if (!hasExactKeys(value, LIFECYCLE_PROVENANCE_KEYS)) return false;
128
+ return Number.isSafeInteger(value.protocolVersion)
129
+ && (value.protocolVersion as number) > 0
130
+ && exactText(value.packageVersion)
131
+ && exactText(value.internalExecutableBuildHash)
132
+ && exactText(value.lifecycleContractHash)
133
+ && exactText(value.hookDefinitionHash)
134
+ && ['project', 'managed', 'isolated-user'].includes(value.hookSource as string)
135
+ && exactText(value.hookSourcePathDigest)
136
+ && exactText(value.hookSourceHash)
137
+ && exactText(value.capabilitySessionId)
138
+ && exactText(value.capabilityTurnId)
139
+ && exactText(value.capabilityToolUseId)
140
+ && nullableText(value.controllerInstanceDigest)
141
+ && nullableText(value.controlGeneration);
142
+ }
143
+
144
+ const HOST_EVIDENCE_REQUIRED_KEYS = [
145
+ 'kind', 'hookDefinitionHash', 'startRevision', 'stopRevision', 'consumer', 'consumedAt'
146
+ ] as const;
147
+ const HOST_EVIDENCE_OPTIONAL_KEYS = [
148
+ 'protocolVersion', 'packageVersion', 'internalExecutableBuildHash', 'lifecycleContractHash',
149
+ 'hookSource', 'hookSourcePathDigest', 'hookSourceHash', 'capabilitySessionId',
150
+ 'capabilityTurnId', 'capabilityToolUseId', 'spawnToolUseId', 'spawnObservedAt',
151
+ 'controllerInstanceDigest', 'controlGeneration'
152
+ ] as const;
153
+
154
+ function isDelegationHostEvidence(value: unknown): value is DelegationHostEvidence {
155
+ if (!hasExactKeys(value, HOST_EVIDENCE_REQUIRED_KEYS, HOST_EVIDENCE_OPTIONAL_KEYS)) return false;
156
+ if (!['codex-lifecycle-v1', 'codex-lifecycle-v2'].includes(value.kind as string)) return false;
157
+ if (!exactText(value.hookDefinitionHash)
158
+ || !Number.isSafeInteger(value.startRevision) || (value.startRevision as number) < 1
159
+ || !nullableSafeInteger(value.stopRevision)
160
+ || !nullableText(value.consumer)
161
+ || !nullableText(value.consumedAt)) return false;
162
+ if (value.kind === 'codex-lifecycle-v1') return true;
163
+ return Number.isSafeInteger(value.protocolVersion)
164
+ && (value.protocolVersion as number) > 0
165
+ && exactText(value.packageVersion)
166
+ && exactText(value.internalExecutableBuildHash)
167
+ && exactText(value.lifecycleContractHash)
168
+ && ['project', 'managed', 'isolated-user'].includes(value.hookSource as string)
169
+ && exactText(value.hookSourcePathDigest)
170
+ && exactText(value.hookSourceHash)
171
+ && exactText(value.capabilitySessionId)
172
+ && exactText(value.capabilityTurnId)
173
+ && exactText(value.spawnToolUseId)
174
+ && exactText(value.spawnObservedAt)
175
+ && nullableText(value.controllerInstanceDigest)
176
+ && nullableText(value.controlGeneration);
177
+ }
178
+
179
+ function hasCurrentCodexEvidence(receipt: DelegationReceipt): boolean {
180
+ const provenance = receipt.lifecycleProvenance;
181
+ if (!provenance) return false;
182
+ const activated = ['activated', 'stage-completed', 'sealed', 'consumed'].includes(receipt.status);
183
+ if (!activated) return receipt.hostEvidence === null;
184
+ const host = receipt.hostEvidence;
185
+ if (
186
+ host?.kind !== 'codex-lifecycle-v2'
187
+ || host.protocolVersion !== provenance.protocolVersion
188
+ || host.packageVersion !== provenance.packageVersion
189
+ || host.internalExecutableBuildHash !== provenance.internalExecutableBuildHash
190
+ || host.lifecycleContractHash !== provenance.lifecycleContractHash
191
+ || host.hookDefinitionHash !== provenance.hookDefinitionHash
192
+ || host.hookSource !== provenance.hookSource
193
+ || host.hookSourcePathDigest !== provenance.hookSourcePathDigest
194
+ || host.hookSourceHash !== provenance.hookSourceHash
195
+ || host.capabilitySessionId !== provenance.capabilitySessionId
196
+ || host.capabilityTurnId !== provenance.capabilityTurnId
197
+ || host.controllerInstanceDigest !== provenance.controllerInstanceDigest
198
+ || host.controlGeneration !== provenance.controlGeneration
199
+ || receipt.parentId !== provenance.capabilitySessionId
200
+ || host.spawnToolUseId === provenance.capabilityToolUseId
201
+ ) return false;
202
+ const spawnObservedAt = Date.parse(host.spawnObservedAt ?? '');
203
+ const spawnDispatchedAt = Date.parse(receipt.spawnDispatchedAt ?? '');
204
+ const activationDeadlineAt = Date.parse(receipt.activationDeadlineAt ?? '');
205
+ if (
206
+ !Number.isFinite(spawnObservedAt)
207
+ || !Number.isFinite(spawnDispatchedAt)
208
+ || !Number.isFinite(activationDeadlineAt)
209
+ || spawnObservedAt < spawnDispatchedAt
210
+ || spawnObservedAt > activationDeadlineAt
211
+ ) return false;
212
+ if (['sealed', 'consumed'].includes(receipt.status)) {
213
+ return Number.isSafeInteger(host.stopRevision)
214
+ && (host.stopRevision as number) > host.startRevision
215
+ && host.consumer === receipt.id
216
+ && exactText(host.consumedAt);
217
+ }
218
+ return host.stopRevision === null && host.consumer === null && host.consumedAt === null;
219
+ }
220
+
221
+ const RECEIPT_KEYS = [
222
+ 'id', 'taskId', 'runId', 'role', 'stage', 'round', 'artifact', 'client',
223
+ 'requestedModel', 'requestedReasoningEffort', 'actualModel', 'actualReasoningEffort',
224
+ 'modelFallbackReason', 'reasoningEffortFallbackReason', 'parentId', 'childId',
225
+ 'spawnMode', 'agent', 'status', 'workspaceSnapshotScope', 'lifecycleProvenance',
226
+ 'hostEvidence', 'beforeFingerprint', 'afterFingerprint', 'changedPaths', 'createdAt',
227
+ 'preparedMonotonicMs', 'spawnDispatchMonotonicMs', 'activationDeadlineMonotonicMs',
228
+ 'spawnDispatchedAt', 'activationDeadlineAt', 'startEvidenceMonotonicMs',
229
+ 'activatedMonotonicMs', 'activatedAt', 'sealedAt', 'consumedAt'
230
+ ] as const;
231
+
232
+ function hasStatusBoundEvidence(receipt: DelegationReceipt): boolean {
233
+ const dispatchFields = [
234
+ receipt.spawnDispatchMonotonicMs,
235
+ receipt.activationDeadlineMonotonicMs,
236
+ receipt.spawnDispatchedAt,
237
+ receipt.activationDeadlineAt
238
+ ];
239
+ const dispatchEmpty = dispatchFields.every((field) => field === null);
240
+ const dispatchComplete = dispatchFields.every((field) => field !== null);
241
+ if (!dispatchEmpty && !dispatchComplete) return false;
242
+
243
+ const beforeActivation = ['prepared', 'aborted', 'expired'].includes(receipt.status);
244
+ if (beforeActivation) {
245
+ return receipt.parentId === null
246
+ && receipt.childId === null
247
+ && receipt.spawnMode === null
248
+ && receipt.actualModel === null
249
+ && receipt.actualReasoningEffort === null
250
+ && receipt.modelFallbackReason === null
251
+ && receipt.reasoningEffortFallbackReason === null
252
+ && receipt.agent === null
253
+ && receipt.hostEvidence === null
254
+ && receipt.startEvidenceMonotonicMs === null
255
+ && receipt.activatedMonotonicMs === null
256
+ && receipt.activatedAt === null
257
+ && receipt.afterFingerprint === null
258
+ && receipt.changedPaths.length === 0
259
+ && receipt.sealedAt === null
260
+ && receipt.consumedAt === null;
261
+ }
262
+
263
+ if (
264
+ !dispatchComplete
265
+ || !exactText(receipt.parentId)
266
+ || !exactText(receipt.childId)
267
+ || receipt.parentId === receipt.childId
268
+ || receipt.startEvidenceMonotonicMs === null
269
+ || receipt.activatedMonotonicMs === null
270
+ || !exactText(receipt.activatedAt)
271
+ ) return false;
272
+
273
+ if (receipt.status === 'activated') {
274
+ return receipt.agent === null
275
+ && receipt.afterFingerprint === null
276
+ && receipt.changedPaths.length === 0
277
+ && receipt.sealedAt === null
278
+ && receipt.consumedAt === null;
279
+ }
280
+
281
+ if (
282
+ !exactText(receipt.agent)
283
+ || normalizeAgentToken(receipt.agent) !== normalizeAgentToken(receipt.client)
284
+ ) return false;
285
+
286
+ if (receipt.status === 'stage-completed') {
287
+ return receipt.afterFingerprint === null
288
+ && receipt.changedPaths.length === 0
289
+ && receipt.sealedAt === null
290
+ && receipt.consumedAt === null;
291
+ }
292
+
293
+ if (!exactText(receipt.afterFingerprint) || !exactText(receipt.sealedAt)) return false;
294
+ return receipt.status === 'sealed'
295
+ ? receipt.consumedAt === null
296
+ : receipt.status === 'consumed' && exactText(receipt.consumedAt);
297
+ }
298
+
299
+ function isDelegationReceipt(value: unknown): value is DelegationReceipt {
300
+ if (!hasExactKeys(value, RECEIPT_KEYS)) return false;
301
+ const structurallyValid = exactText(value.id)
302
+ && exactText(value.taskId)
303
+ && exactText(value.runId)
304
+ && ['executor', 'reviewer'].includes(value.role as string)
305
+ && ['analysis', 'review-analysis', 'plan', 'review-plan', 'code', 'review-code', 'commit'].includes(value.stage as string)
306
+ && Number.isSafeInteger(value.round)
307
+ && (value.round as number) > 0
308
+ && exactText(value.artifact)
309
+ && isAgentClientId(value.client)
310
+ && exactText(value.requestedModel)
311
+ && exactText(value.requestedReasoningEffort)
312
+ && nullableText(value.actualModel)
313
+ && nullableText(value.actualReasoningEffort)
314
+ && nullableText(value.modelFallbackReason)
315
+ && nullableText(value.reasoningEffortFallbackReason)
316
+ && nullableText(value.parentId)
317
+ && nullableText(value.childId)
318
+ && nullableText(value.spawnMode)
319
+ && nullableText(value.agent)
320
+ && ['prepared', 'activated', 'stage-completed', 'sealed', 'consumed', 'aborted', 'expired'].includes(value.status as string)
321
+ && value.workspaceSnapshotScope === 'task'
322
+ && (value.lifecycleProvenance === null || isDelegationLifecycleProvenance(value.lifecycleProvenance))
323
+ && (value.hostEvidence === null || isDelegationHostEvidence(value.hostEvidence))
324
+ && exactText(value.beforeFingerprint)
325
+ && nullableText(value.afterFingerprint)
326
+ && Array.isArray(value.changedPaths)
327
+ && value.changedPaths.every(exactText)
328
+ && exactText(value.createdAt)
329
+ && nullableSafeInteger(value.preparedMonotonicMs)
330
+ && value.preparedMonotonicMs !== null
331
+ && nullableSafeInteger(value.spawnDispatchMonotonicMs)
332
+ && nullableSafeInteger(value.activationDeadlineMonotonicMs)
333
+ && nullableText(value.spawnDispatchedAt)
334
+ && nullableText(value.activationDeadlineAt)
335
+ && nullableSafeInteger(value.startEvidenceMonotonicMs)
336
+ && nullableSafeInteger(value.activatedMonotonicMs)
337
+ && nullableText(value.activatedAt)
338
+ && nullableText(value.sealedAt)
339
+ && nullableText(value.consumedAt);
340
+ if (!structurallyValid) return false;
341
+ const receipt = value as unknown as DelegationReceipt;
342
+ return hasStatusBoundEvidence(receipt)
343
+ && (receipt.client !== 'codex' || hasCurrentCodexEvidence(receipt));
344
+ }
345
+
90
346
  const MANAGED_AGENTS = {
91
347
  'agent-infra-lifecycle-executor': 'executor',
92
348
  'agent-infra-lifecycle-reviewer': 'reviewer'
@@ -151,7 +407,7 @@ function dispatchDelegation(
151
407
  }
152
408
  const monotonic = (options.monotonicNow ?? (() => Number(process.hrtime.bigint() / 1_000_000n)))();
153
409
  const dispatchedAt = (options.now ?? (() => new Date().toISOString()))();
154
- const window = options.activationWindowMs ?? 15_000;
410
+ const window = options.activationWindowMs ?? 60_000;
155
411
  return { ok: true, receipt: Object.freeze({
156
412
  ...receipt,
157
413
  spawnDispatchMonotonicMs: monotonic,
@@ -413,6 +669,7 @@ export {
413
669
  consumeDelegation,
414
670
  dispatchDelegation,
415
671
  foldBlankToNull,
672
+ isDelegationReceipt,
416
673
  managedDelegationRole,
417
674
  prepareDelegation,
418
675
  sealDelegation