@zaip-ai/cli 1.3.1 → 1.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +6 -3
- package/README.md +11 -4
- package/dist/services/codex-pre-tool-hook-template.js +1 -1
- package/dist/services/runtime-template.test.js +9 -8
- package/dist/services/runtime-template.test.js.map +1 -1
- package/package.json +2 -2
- package/templates/.agents/dashboard/.zaip-managed.json +403 -383
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{CostCalculationGuidePage-ovxurkIk.js → CostCalculationGuidePage-BZWjXQB-.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{DashboardHelpDialog-BgVgrfhQ.js → DashboardHelpDialog-D8qqeIPE.js} +58 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{PricingSettingsDialog-vSvvOHQp.js → PricingSettingsDialog-Cm12_A0v.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{ProjectSettingsPage-zH758vfs.js → ProjectSettingsPage-DxO9F8B4.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{TraceabilityWorkspace-DLn-Mz2M.js → TraceabilityWorkspace-_x0twOcS.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-Cpp8xFij.js +68 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{icons-vendor-B_lDDHn1.js → icons-vendor-CR4Fbf3g.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/index-ncC1rxap.js +2 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{react-vendor-B3TJrD4O.js → react-vendor-DRJQbKnp.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{traceability-7f1j5wx3.js → traceability-CMrDYqjR.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/index.html +5 -5
- package/templates/.agents/dashboard/apps/frontend/src/App.tsx +48 -3
- package/templates/.agents/dashboard/apps/frontend/src/AppRequestGuards.tsx +44 -0
- package/templates/.agents/dashboard/apps/frontend/src/cost-period-refresh.test.ts +92 -1
- package/templates/.agents/dashboard/apps/frontend/src/snapshot-coherence.test.ts +2 -2
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostDeveloperAttributionPanel.test.ts +60 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostDeveloperAttributionPanel.tsx +26 -9
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorNavigation.tsx +189 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorPage.test.ts +122 -2
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorPage.tsx +70 -155
- package/templates/.agents/dashboard/modules/operations/src/react/export/ExcelExportAction.test.ts +59 -0
- package/templates/.agents/dashboard/modules/operations/src/react/export/ExcelExportAction.tsx +55 -2
- package/templates/.agents/dashboard/packages/local-runtime/dist/server.cjs +274 -246
- package/templates/.agents/dashboard/packages/local-runtime/dist/sqlite-read-model.cjs +255 -227
- package/templates/.agents/dashboard/packages/local-runtime/server.mjs +263 -235
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-dimension-facts.test.ts +282 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-dimension-facts.ts +71 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-operations-work-list.test.ts +70 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-operations-work-list.ts +74 -7
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-launch-progress.ts +18 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-stale-seed.ts +50 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model.test.ts +9 -6
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model.ts +45 -73
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-snapshot-seed.test.ts +79 -2
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-work-item-index.test.ts +56 -0
- package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-launch-page.mjs +26 -8
- package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-launch-page.test.mjs +45 -4
- package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-lifecycle.mjs +58 -0
- package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-lifecycle.test.mjs +81 -0
- package/templates/.agents/dashboard/packages/local-runtime/start-dashboard.mjs +171 -71
- package/templates/.agents/dashboard/packages/local-runtime/start-dashboard.test.mjs +152 -11
- package/templates/.agents/dashboard/packages/windows-launcher/Program.cs +4 -9
- package/templates/.agents/dashboard/tests/e2e/playwright.config.ts +9 -1
- package/templates/.agents/dashboard/tests/e2e/specs/cost-monitor-period-transition.spec.ts +232 -0
- package/templates/.agents/dashboard/tests/e2e/specs/dashboard.spec.ts +26 -5
- package/templates/.agents/requirements/autonomous-assurance.md +1 -1
- package/templates/.agents/requirements/comparative-audit.md +1 -1
- package/templates/.agents/requirements/context-engine.md +1 -1
- package/templates/.agents/requirements/cost-observability.md +1 -1
- package/templates/.agents/requirements/dashboard-launch.md +1 -1
- package/templates/.agents/requirements/data-export.md +1 -1
- package/templates/.agents/requirements/design-system.md +1 -1
- package/templates/.agents/requirements/execution-engine.md +1 -1
- package/templates/.agents/requirements/kanban-dashboard.md +1 -1
- package/templates/.agents/requirements/model-orchestration.md +1 -1
- package/templates/.agents/requirements/public-distribution.md +1 -1
- package/templates/.agents/requirements/software-architecture.md +1 -1
- package/templates/.agents/requirements/strategic-improvements.md +1 -1
- package/templates/.agents/requirements/work-lifecycle.md +1 -1
- package/templates/.agents/requirements/zaip-strategic-95.md +1 -1
- package/templates/.agents/runtime/bin/zaip.mjs +7 -7
- package/templates/.agents/runtime/checksums.sha256 +3 -3
- package/templates/.agents/runtime/provenance.json +3 -3
- package/templates/.agents/runtime/sbom.cdx.json +1595 -3491
- package/templates/.agents/skills/zaip-skill-lifecycle-closure/SKILL.md +16 -0
- package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-local-telemetry.mjs +19 -20
- package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-local-telemetry.test.mjs +143 -0
- package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-lib.mjs +14 -0
- package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-remeasurement.mjs +3 -1
- package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-remeasurement.test.mjs +21 -0
- package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/source-size-telemetry/model-identity-reconciliation.mjs +3 -0
- package/templates/.agents/zaip-aios/guides/26-qualidade-e-release.md +44 -0
- package/templates/template-manifest.json +536 -932
- package/templates/.agents/dashboard/.tmp-run-list.json +0 -254
- package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-DKwP1stV.js +0 -68
- package/templates/.agents/dashboard/apps/frontend/dist/assets/index-CZQlsLV9.js +0 -2
|
@@ -75,7 +75,7 @@ const allowedExplicitNetworkHosts = new Set([
|
|
|
75
75
|
]);
|
|
76
76
|
const networkClientPattern = /\b(?:curl|wget|Invoke-WebRequest|Invoke-RestMethod|iwr|irm)\b/i;
|
|
77
77
|
const homeReferencePattern = /(?:\$HOME\b|\$env:(?:USERPROFILE|HOMEDRIVE|HOMEPATH)\b|%(?:USERPROFILE|HOMEDRIVE|HOMEPATH)%|(?:^|[\s"'=])~[\\/])/i;
|
|
78
|
-
const credentialReferencePattern = /(?:^|[\\/\s"'=])(?:\.ssh|\.aws|\.azure|\.kube|\.docker|\.gnupg|\.git-credentials|\.npmrc|\.pypirc|id_(?:rsa|ed25519)|[^\\/\s"']+\.(?:pem|key|p12|pfx))(?:[\\/\s"'=]|$)|(?:^|[\\/\s"'=])\.env(?:[\\/\s"']|$)/i;
|
|
78
|
+
const credentialReferencePattern = /(?:^|[\\/\s"'=])(?:\.ssh|\.aws|\.azure|\.kube|\.docker|\.gnupg|\.git-credentials|\.npmrc|\.pypirc|id_(?:rsa|ed25519)|[^\\/\s"']+\.(?:pem|key|p12|pfx))(?:[\\/\s"'=]|$)|(?:^|[\\/\s"'=])\.env(?:\.[A-Za-z0-9_-]+)*(?:[\\/\s"']|$)/i;
|
|
79
79
|
const sensitiveEnvironmentPattern = /(?:\$env:|%|\$)[A-Z0-9_]*(?:TOKEN|SECRET|PASSWORD|API_KEY|PRIVATE_KEY|CREDENTIAL)[A-Z0-9_]*%?/i;
|
|
80
80
|
const destructivePatterns = [
|
|
81
81
|
{
|
|
@@ -1293,9 +1293,9 @@ ${consequences}`}function isNodeError3(error51){return error51 instanceof Error&
|
|
|
1293
1293
|
`);return validated}function developerIdentityNeedsRevalidation(identity,now=new Date){if(identity.expires_at===null||identity.expires_at===void 0)return true;const expiresAt=Date.parse(identity.expires_at);return!Number.isFinite(expiresAt)||expiresAt<=now.getTime()}function verifiedDeveloperIdentity(account,now=new Date){const verifiedAt=now.toISOString();return developerIdentityV1Schema.parse({schema_version:1,provider:"github",account_id:account.id,login_snapshot:account.login,attribution_source:"verified_local_account",verified_at:verifiedAt,last_verified_at:verifiedAt,expires_at:new Date(now.getTime()+DEVELOPER_IDENTITY_CACHE_TTL_MS).toISOString()})}function cachedFallbackDeveloperIdentity(identity){return developerIdentityV1Schema.parse({...identity,attribution_source:"cached_fallback",last_verified_at:identity.last_verified_at??identity.verified_at})}function isMissing(error51){return typeof error51==="object"&&error51!==null&&"code"in error51&&error51.code==="ENOENT"}import{createHash as createHash10,randomUUID as randomUUID2}from"node:crypto";import{createHash as createHash8}from"node:crypto";var ROOT=".local/codex-telemetry-spool/v1";var LIST_READ_CONCURRENCY=32;var MAX_ENVELOPE_BYTES=64*1024;var digest3=value=>createHash8("sha256").update(value).digest("hex");function codexTelemetryCorrelationFromRun(run){if(!["codex","codex-desktop","codex-subagent"].includes(run.client)||run.agent_invocation_id===void 0||run.root_agent_invocation_id===void 0||run.parent_agent_invocation_id===void 0||run.invocation_kind===void 0||run.delegation_depth===void 0)return null;const isSubagent=run.client==="codex-subagent";const clientThreadId=run.client_thread_id??null;const clientTurnId=run.client_turn_id??null;if(clientThreadId===null&&clientTurnId===null)return null;return codexTelemetryCorrelationV1Schema.parse({schema_version:1,run_id:run.run_id,execution_id:run.execution_id,task_id:run.task_id,spec_id:run.spec_id,prd_id:run.prd_id,change_id:run.change_id,developer_identity:run.developer_identity??null,zaip_agent:run.agent,phase:run.phase,purpose:run.run_purpose??null,agent_invocation_id:run.agent_invocation_id,root_agent_invocation_id:run.root_agent_invocation_id,parent_agent_invocation_id:run.parent_agent_invocation_id,invocation_kind:run.invocation_kind,delegation_depth:run.delegation_depth,client:run.client,thread_id:isSubagent?null:clientThreadId,turn_id:clientTurnId,agent_path:isSubagent?clientThreadId:null})}async function persistCodexTelemetryCorrelation(filesystem,correlation){const validated=codexTelemetryCorrelationV1Schema.parse(correlation);const identity=JSON.stringify([validated.client==="codex-desktop"?"codex":validated.client,validated.thread_id,validated.turn_id,validated.agent_path,validated.turn_id===null?validated.run_id:null]);const path=`${ROOT}/correlations/${digest3(identity)}.json`;try{await filesystem.writeTextAtomicExclusive(path,`${JSON.stringify(validated)}
|
|
1294
1294
|
`);return validated}catch(error51){if(!isNodeError4(error51)||error51.code!=="EEXIST")throw error51}const existing=codexTelemetryCorrelationV1Schema.parse(JSON.parse(await filesystem.readText(path)));if(isCompatibleCorrelationEnrichment(existing,validated)){await filesystem.writeTextAtomic(path,`${JSON.stringify(validated)}
|
|
1295
1295
|
`);return validated}if(JSON.stringify(existing)!==JSON.stringify(validated))throw new Error(`Codex telemetry correlation is already owned by ${existing.agent_invocation_id}`);return existing}function isCompatibleCorrelationEnrichment(existing,candidate){const stableKeys=["run_id","agent_invocation_id","root_agent_invocation_id","parent_agent_invocation_id","invocation_kind","delegation_depth","client","thread_id","turn_id","agent_path"];if(stableKeys.some(key=>existing[key]!==candidate[key]))return false;const enrichableKeys=["execution_id","task_id","spec_id","prd_id","change_id","zaip_agent","phase","purpose"];return enrichableKeys.every(key=>existing[key]===null||existing[key]===candidate[key])}async function listCodexTelemetryCorrelations(filesystem){const paths=await filesystem.listFiles(`${ROOT}/correlations`,".json");const correlations=await mapInBatches(paths,path=>readListedJson(filesystem,path));return correlations.filter(value=>value!==null).map(value=>codexTelemetryCorrelationV1Schema.parse(value)).sort((left,right)=>left.agent_invocation_id.localeCompare(right.agent_invocation_id)||left.run_id.localeCompare(right.run_id))}async function appendCodexTelemetrySpoolEvent(filesystem,input){const event=codexTelemetrySpoolEventInputV1Schema.parse(input);await persistCodexTelemetryCorrelation(filesystem,event.correlation);const sourceDigest=digest3(event.source_event_key);const path=`${ROOT}/events/${sourceDigest.slice(0,2)}/${sourceDigest}.json`;const unsigned={schema_version:1,event_id:`CEVT-${sourceDigest}`,compaction:{status:"pending",compacted_at:null},event};const envelope=codexTelemetrySpoolEnvelopeV1Schema.parse({...unsigned,checksum_sha256:digest3(JSON.stringify(unsigned))});const serialized=`${JSON.stringify(envelope)}
|
|
1296
|
-
`;if(Buffer.byteLength(serialized,"utf8")>MAX_ENVELOPE_BYTES)throw new Error("Codex telemetry spool envelope exceeds the 64 KiB sanitized limit");try{await filesystem.writeTextAtomicExclusive(path,serialized);return{...envelope,spool_path:path}}catch(error51){if(!isNodeError4(error51)||error51.code!=="EEXIST")throw error51}const existing=await readCodexTelemetrySpoolEvent(filesystem,path);if(JSON.stringify({...existing.event,captured_at:event.captured_at})!==JSON.stringify(event))throw new Error(`Codex telemetry source event is already owned by ${existing.event.correlation.agent_invocation_id}`);return existing}async function readCodexTelemetrySpoolEvent(filesystem,path){if(!path.startsWith(`${ROOT}/events/`)||!path.endsWith(".json"))throw new Error(`Invalid Codex telemetry spool event path: ${path}`);const envelope=codexTelemetrySpoolEnvelopeV1Schema.parse(JSON.parse(await filesystem.readText(path)));const{checksum_sha256:checksum,...unsigned}=envelope;if(digest3(JSON.stringify(unsigned))!==checksum)throw new Error(`Codex telemetry spool checksum mismatch: ${envelope.event_id}`);return{...envelope,spool_path:path}}async function listCodexTelemetrySpoolEvents(filesystem,status){const paths=await filesystem.listFiles(`${ROOT}/events`,".json");const events=await mapInBatches(paths,async path=>{try{return await readCodexTelemetrySpoolEvent(filesystem,path)}catch(error51){if(isNodeError4(error51)&&error51.code==="ENOENT")return null;throw error51}});return events.filter(event=>event!==null).filter(event=>status===void 0||event.compaction.status===status).sort(compareCodexTelemetrySpoolEvents)}async function mapInBatches(values,transform2){const results=[];for(let offset=0;offset<values.length;offset+=LIST_READ_CONCURRENCY){results.push(...await Promise.all(values.slice(offset,offset+LIST_READ_CONCURRENCY).map(transform2)))}return results}function compareCodexTelemetrySpoolEvents(left,right){const leftOccurredAt=left.event.source_occurred_at;const rightOccurredAt=right.event.source_occurred_at;if(leftOccurredAt===null&&rightOccurredAt!==null)return 1;if(leftOccurredAt!==null&&rightOccurredAt===null)return-1;if(leftOccurredAt!==null&&rightOccurredAt!==null){const order2=leftOccurredAt.localeCompare(rightOccurredAt);if(order2!==0)return order2}return left.event_id.localeCompare(right.event_id)}async function readListedJson(filesystem,path){try{return JSON.parse(await filesystem.readText(path))}catch(error51){if(isNodeError4(error51)&&error51.code==="ENOENT")return null;throw error51}}function isNodeError4(error51){return error51 instanceof Error&&"code"in error51}import{createHash as createHash9,randomUUID}from"node:crypto";var PURPOSE="usage-attribution";var RECOVERY_PURPOSE="usage-attribution-recovery";var LEASE_MS=3e4;async function withUsageAttributionLock(filesystem,lockPath,operation){const deadline=Date.now()+12e4;const ownerNonce=randomUUID();let lastRetryError=null;while(true){if(lastRetryError!==null&&Date.now()>=deadline)throw lastRetryError;try{await filesystem.writeTextExclusive(lockPath,`${JSON.stringify(lock(ownerNonce))}
|
|
1297
|
-
`);if(Date.now()>=deadline){await removeIfOwned(filesystem,lockPath,ownerNonce);throw new Error("Usage attribution lock acquisition exceeded deadline")}break}catch(error51){if((!isNodeError5(error51)||error51.code!=="EEXIST")&&!isTransient(error51))throw error51;lastRetryError=error51;if(isNodeError5(error51)&&error51.code==="EEXIST"){const incumbent=await
|
|
1298
|
-
`);return recovery}catch(error51){if(!isNodeError5(error51)||error51.code!=="EEXIST")throw error51;const existing=await readLock(fs,recovery);if(existing!==null&&existing.purpose===RECOVERY_PURPOSE&&existing.target_nonce===target&&Date.parse(existing.lease_expires_at)<=Date.now()&&!alive(existing.pid)){await removeRecovery(fs,recovery,existing.owner_nonce)}return null}}async function removeIfOwned(fs,path,owner){const current=await readLock(fs,path);if(current?.purpose===PURPOSE&¤t.owner_nonce===owner)await fs.removeFileIfContentMatches(path,current.content)}async function removeRecovery(fs,path,owner){const current=await readLock(fs,path);if(current?.purpose===RECOVERY_PURPOSE&¤t.owner_nonce===owner)await fs.removeFileIfContentMatches(path,current.content)}async function retry(error51,deadline){if(Date.now()>=deadline)throw error51;await new Promise(resolve10=>setTimeout(resolve10,25))}function isNodeError5(error51){return error51 instanceof Error&&"code"in error51}function isTransient(error51){return isNodeError5(error51)&&(error51.code==="ENOENT"||error51.code==="EBADF")||error51 instanceof WorkspacePathError&&(isNodeError5(error51.cause)&&(error51.cause.code==="ENOENT"||error51.cause.code==="EBADF")||error51.message.startsWith("Physical path escapes workspace root:"))}var RunV2Repository=class{constructor(filesystem,storage){this.filesystem=filesystem;this.storage=storage;if(storage.storageMode==="tracked_sanitized"&&storage.layout.version===1){throw new Error("tracked_sanitized Run V2 storage requires a modern WorkspaceLayout")}if(storage.storageMode==="local_only")assertCanonicalBasePath(storage.localBasePath)}filesystem;storage;activeWriters=new Set;async start(input){const clock=input.clock??new SystemClock;const id=input.id??createId("RUN",input.shortName,{clock,...input.collisionCode===void 0?{}:{collisionCode:input.collisionCode},...input.timeZone===void 0?{}:{timeZone:input.timeZone}});const parent=input.parentRunId===void 0||input.parentRunId===null?null:await this.read(input.parentRunId).catch(()=>null);const agentInvocationId=`AINV-${id.slice("RUN-".length)}`;const parentAgentInvocationId=parent===null?input.parentRunId===void 0||input.parentRunId===null?null:`AINV-${input.parentRunId.slice("RUN-".length)}`:parent.run.agent_invocation_id??`AINV-${parent.run.run_id.slice("RUN-".length)}`;const rootAgentInvocationId=parent===null?parentAgentInvocationId??agentInvocationId:parent.run.root_agent_invocation_id??parentAgentInvocationId;const delegationDepth=parentAgentInvocationId===null?0:(parent?.run.delegation_depth??0)+1;const developerIdentity=parent!==null?parent.run.developer_identity:input.developerIdentity??(this.storage.storageMode==="local_only"?null:await requireDeveloperIdentityCache(this.filesystem));const started=runStartedV2Schema.parse({schema_version:2,event_id:eventId(id,1),run_id:id,sequence:1,occurred_at:clock.now().toISOString(),type:"run.started",attribution_status:"attributed",developer_identity:developerIdentity,phase:input.phase,run_role:input.runRole??(input.phase!=="execution"?"intake":input.parentRunId!==void 0&&input.parentRunId!==null?"subagent":"orchestrator"),run_purpose:input.runPurpose??(input.phase!=="execution"?"intake":input.agent==="agent-finalizer"?"finalization":input.agent==="agent-reviewer"?"review":input.agent==="agent-auditor"?"audit":input.parentRunId===void 0||input.parentRunId===null?"orchestration":"execution"),requires_finalizer:input.requiresFinalizer??(input.phase==="execution"&&(input.parentRunId===void 0||input.parentRunId===null)&&input.executionId!==void 0&&input.executionId!==null),execution_kind:input.executionKind,execution_eligibility:[...input.executionEligibility??[]],entrypoint:input.entrypoint,work_type:input.workType,storage_mode:this.storage.storageMode,client:input.client,agent:input.agent,agent_name:input.agentName??null,...input.agentIdentityWarning===void 0?{}:{agent_identity_warning:input.agentIdentityWarning},provider:input.provider,model:input.model,reasoning_effort:input.reasoningEffort??null,client_thread_id:input.clientThreadId??null,client_turn_id:input.clientTurnId??null,conversation_id:input.conversationId,execution_id:input.executionId??null,task_id:input.taskId??null,spec_id:input.specId??null,prd_id:input.prdId??null,change_id:input.changeId??null,parent_run_id:input.parentRunId??null,...input.agentInvocationId===void 0?{}:{agent_invocation_id:input.agentInvocationId,root_agent_invocation_id:input.rootAgentInvocationId,parent_agent_invocation_id:input.parentAgentInvocationId,invocation_kind:input.invocationKind,delegation_depth:input.delegationDepth},continuation_of_run_id:input.continuationOfRunId??null,retry_of_run_id:input.retryOfRunId??null,agent_invocation_id:agentInvocationId,root_agent_invocation_id:rootAgentInvocationId,parent_agent_invocation_id:parentAgentInvocationId,invocation_kind:parentAgentInvocationId===null?"orchestrator":"delegated",delegation_depth:delegationDepth,intake:input.intake??null});const path=this.path(id);if(this.activeWriters.has(id)){throw new Error(`Run V2 already has a writer or persisted stream: ${id}`)}try{await this.filesystem.writeTextExclusive(path,serializeRecord(started))}catch(error51){if(!isNodeError6(error51)||error51.code!=="EEXIST")throw error51;throw new Error(`Run V2 already has a writer or persisted stream: ${id}`)}try{const correlation=codexTelemetryCorrelationFromRun(started);if(correlation!==null){await persistCodexTelemetryCorrelation(this.filesystem,correlation)}}catch(error51){await this.filesystem.removeFile(path);throw error51}this.activeWriters.add(id);return new RunV2Writer(this.filesystem,path,started,clock,()=>{this.activeWriters.delete(id)})}async read(id){const path=await this.readPath(id);if(path===null)throw new Error(`Run V2 not found: ${id}`);return foldRunV2Records(parseRunV2JsonLines(await this.filesystem.readText(path)))}async list(){const paths=await this.filesystem.listFiles(this.basePath(),".jsonl");const entries=await Promise.all(paths.map(async path=>{const run=foldRunV2Records(parseRunV2JsonLines(await this.filesystem.readText(path)));if(!this.candidatePaths(run.run.run_id).includes(path)){throw new Error(`Run V2 id does not match storage path: ${path}`)}return{path,run}}));const byId2=new Map;for(const entry of entries){const existing=byId2.get(entry.run.run.run_id);if(existing===void 0){byId2.set(entry.run.run.run_id,entry);continue}if(JSON.stringify(existing.run.records)!==JSON.stringify(entry.run.records)){throw new Error(`Run V2 has divergent monthly and legacy streams: ${entry.run.run.run_id}`)}if(entry.path===this.path(entry.run.run.run_id)){byId2.set(entry.run.run.run_id,entry)}}const runs=[...byId2.values()].map(entry=>entry.run);return runs.sort((left,right)=>right.run.occurred_at.localeCompare(left.run.occurred_at)||right.run.run_id.localeCompare(left.run.run_id))}async appendRecord(record3){const validated=runV2RecordSchema.parse(record3);const path=this.path(validated.run_id);const lockPath=`${path}.lock`;try{await this.filesystem.writeTextExclusive(lockPath,`${JSON.stringify({run_id:validated.run_id,pid:process.pid})}
|
|
1296
|
+
`;if(Buffer.byteLength(serialized,"utf8")>MAX_ENVELOPE_BYTES)throw new Error("Codex telemetry spool envelope exceeds the 64 KiB sanitized limit");try{await filesystem.writeTextAtomicExclusive(path,serialized);return{...envelope,spool_path:path}}catch(error51){if(!isNodeError4(error51)||error51.code!=="EEXIST")throw error51}const existing=await readCodexTelemetrySpoolEvent(filesystem,path);if(JSON.stringify({...existing.event,captured_at:event.captured_at})!==JSON.stringify(event))throw new Error(`Codex telemetry source event is already owned by ${existing.event.correlation.agent_invocation_id}`);return existing}async function readCodexTelemetrySpoolEvent(filesystem,path){if(!path.startsWith(`${ROOT}/events/`)||!path.endsWith(".json"))throw new Error(`Invalid Codex telemetry spool event path: ${path}`);const envelope=codexTelemetrySpoolEnvelopeV1Schema.parse(JSON.parse(await filesystem.readText(path)));const{checksum_sha256:checksum,...unsigned}=envelope;if(digest3(JSON.stringify(unsigned))!==checksum)throw new Error(`Codex telemetry spool checksum mismatch: ${envelope.event_id}`);return{...envelope,spool_path:path}}async function listCodexTelemetrySpoolEvents(filesystem,status){const paths=await filesystem.listFiles(`${ROOT}/events`,".json");const events=await mapInBatches(paths,async path=>{try{return await readCodexTelemetrySpoolEvent(filesystem,path)}catch(error51){if(isNodeError4(error51)&&error51.code==="ENOENT")return null;throw error51}});return events.filter(event=>event!==null).filter(event=>status===void 0||event.compaction.status===status).sort(compareCodexTelemetrySpoolEvents)}async function mapInBatches(values,transform2){const results=[];for(let offset=0;offset<values.length;offset+=LIST_READ_CONCURRENCY){results.push(...await Promise.all(values.slice(offset,offset+LIST_READ_CONCURRENCY).map(transform2)))}return results}function compareCodexTelemetrySpoolEvents(left,right){const leftOccurredAt=left.event.source_occurred_at;const rightOccurredAt=right.event.source_occurred_at;if(leftOccurredAt===null&&rightOccurredAt!==null)return 1;if(leftOccurredAt!==null&&rightOccurredAt===null)return-1;if(leftOccurredAt!==null&&rightOccurredAt!==null){const order2=leftOccurredAt.localeCompare(rightOccurredAt);if(order2!==0)return order2}return left.event_id.localeCompare(right.event_id)}async function readListedJson(filesystem,path){try{return JSON.parse(await filesystem.readText(path))}catch(error51){if(isNodeError4(error51)&&error51.code==="ENOENT")return null;throw error51}}function isNodeError4(error51){return error51 instanceof Error&&"code"in error51}import{createHash as createHash9,randomUUID}from"node:crypto";var PURPOSE="usage-attribution";var RECOVERY_PURPOSE="usage-attribution-recovery";var LEASE_MS=3e4;var MAX_TRANSIENT_READ_ATTEMPTS=3;async function withUsageAttributionLock(filesystem,lockPath,operation){const deadline=Date.now()+12e4;const ownerNonce=randomUUID();let lastRetryError=null;while(true){if(lastRetryError!==null&&Date.now()>=deadline)throw lastRetryError;try{await filesystem.writeTextExclusive(lockPath,`${JSON.stringify(lock(ownerNonce))}
|
|
1297
|
+
`);if(Date.now()>=deadline){await removeIfOwned(filesystem,lockPath,ownerNonce);throw new Error("Usage attribution lock acquisition exceeded deadline")}break}catch(error51){if((!isNodeError5(error51)||error51.code!=="EEXIST")&&!isTransient(error51))throw error51;lastRetryError=error51;if(isNodeError5(error51)&&error51.code==="EEXIST"){const incumbent=await readLockAfterTransientFailure(filesystem,lockPath,deadline);if(incumbent===null){await retry(error51,deadline);continue}if(incumbent.purpose!==PURPOSE)throw new Error("Usage attribution lock has an incompatible purpose");if(!recoverable(incumbent)){await retry(error51,deadline);continue}if(Date.now()>=deadline)throw error51;const recoveryPath=await acquireRecovery(filesystem,lockPath,incumbent.owner_nonce,ownerNonce);if(recoveryPath!==null)try{if(Date.now()>=deadline)throw error51;const current=await readLock(filesystem,lockPath);if(current!==null&¤t.owner_nonce===incumbent.owner_nonce&&recoverable(current)){if(Date.now()>=deadline)throw error51;await filesystem.removeFileIfContentMatches(lockPath,current.content)}}finally{await removeRecovery(filesystem,recoveryPath,ownerNonce)}}await retry(error51,deadline)}}try{return await operation()}finally{await removeIfOwned(filesystem,lockPath,ownerNonce)}}function lock(owner_nonce){const now=Date.now();return{schema_version:1,purpose:PURPOSE,pid:process.pid,owner_nonce,acquired_at:new Date(now).toISOString(),lease_expires_at:new Date(now+LEASE_MS).toISOString()}}async function readLock(fs,path){try{const content=await fs.readText(path);const value=JSON.parse(content);if(valid(value))return{...value,content};if(legacy(value))return{schema_version:1,purpose:PURPOSE,pid:value.pid,owner_nonce:`legacy-${createHash9("sha256").update(content).digest("hex")}`,acquired_at:new Date(0).toISOString(),lease_expires_at:new Date(0).toISOString(),legacy:true,content};throw new Error(`Usage attribution lock is malformed: ${path}`)}catch(error51){if(isNodeError5(error51)&&error51.code==="ENOENT")return null;throw error51}}async function readLockAfterTransientFailure(fs,path,deadline){let attempts=0;while(true){try{return await readLock(fs,path)}catch(error51){if(!isTransientReadFailure(error51))throw error51;attempts+=1;if(attempts>=MAX_TRANSIENT_READ_ATTEMPTS||Date.now()>=deadline)throw error51;await retry(error51,deadline);if(Date.now()>=deadline)throw error51}}}function legacy(value){return typeof value==="object"&&value!==null&&value.purpose===PURPOSE&&Number.isSafeInteger(value.pid)&&value.pid>0}function valid(value){if(typeof value!=="object"||value===null)return false;const x=value;return x.schema_version===1&&(x.purpose===PURPOSE||x.purpose===RECOVERY_PURPOSE)&&Number.isSafeInteger(x.pid)&&(x.pid??0)>0&&typeof x.owner_nonce==="string"&&x.owner_nonce.length>=16&&typeof x.acquired_at==="string"&&Number.isFinite(Date.parse(x.acquired_at))&&typeof x.lease_expires_at==="string"&&Number.isFinite(Date.parse(x.lease_expires_at))&&(x.target_nonce===void 0||typeof x.target_nonce==="string")}function recoverable(value){return value!==null&&value.purpose===PURPOSE&&(value.legacy===true||Date.parse(value.lease_expires_at)<=Date.now())&&!alive(value.pid)}function alive(pid){try{process.kill(pid,0);return true}catch(error51){return!(isNodeError5(error51)&&error51.code==="ESRCH")}}async function acquireRecovery(fs,path,target,owner){const recovery=`${path}.recovery-${target}`;try{await fs.writeTextExclusive(recovery,`${JSON.stringify({...lock(owner),purpose:RECOVERY_PURPOSE,target_nonce:target})}
|
|
1298
|
+
`);return recovery}catch(error51){if(!isNodeError5(error51)||error51.code!=="EEXIST")throw error51;const existing=await readLock(fs,recovery);if(existing!==null&&existing.purpose===RECOVERY_PURPOSE&&existing.target_nonce===target&&Date.parse(existing.lease_expires_at)<=Date.now()&&!alive(existing.pid)){await removeRecovery(fs,recovery,existing.owner_nonce)}return null}}async function removeIfOwned(fs,path,owner){const current=await readLock(fs,path);if(current?.purpose===PURPOSE&¤t.owner_nonce===owner)await fs.removeFileIfContentMatches(path,current.content)}async function removeRecovery(fs,path,owner){const current=await readLock(fs,path);if(current?.purpose===RECOVERY_PURPOSE&¤t.owner_nonce===owner)await fs.removeFileIfContentMatches(path,current.content)}async function retry(error51,deadline){if(Date.now()>=deadline)throw error51;await new Promise(resolve10=>setTimeout(resolve10,25))}function isNodeError5(error51){return error51 instanceof Error&&"code"in error51}function isTransient(error51){return isNodeError5(error51)&&(error51.code==="ENOENT"||error51.code==="EBADF")||error51 instanceof WorkspacePathError&&(isNodeError5(error51.cause)&&(error51.cause.code==="ENOENT"||error51.cause.code==="EBADF")||error51.message.startsWith("Physical path escapes workspace root:"))}function isTransientReadFailure(error51){return isNodeError5(error51)&&error51.code==="EBADF"||error51 instanceof WorkspacePathError&&isNodeError5(error51.cause)&&error51.cause.code==="EBADF"}var RunV2Repository=class{constructor(filesystem,storage){this.filesystem=filesystem;this.storage=storage;if(storage.storageMode==="tracked_sanitized"&&storage.layout.version===1){throw new Error("tracked_sanitized Run V2 storage requires a modern WorkspaceLayout")}if(storage.storageMode==="local_only")assertCanonicalBasePath(storage.localBasePath)}filesystem;storage;activeWriters=new Set;async start(input){const clock=input.clock??new SystemClock;const id=input.id??createId("RUN",input.shortName,{clock,...input.collisionCode===void 0?{}:{collisionCode:input.collisionCode},...input.timeZone===void 0?{}:{timeZone:input.timeZone}});const parent=input.parentRunId===void 0||input.parentRunId===null?null:await this.read(input.parentRunId).catch(()=>null);const agentInvocationId=`AINV-${id.slice("RUN-".length)}`;const parentAgentInvocationId=parent===null?input.parentRunId===void 0||input.parentRunId===null?null:`AINV-${input.parentRunId.slice("RUN-".length)}`:parent.run.agent_invocation_id??`AINV-${parent.run.run_id.slice("RUN-".length)}`;const rootAgentInvocationId=parent===null?parentAgentInvocationId??agentInvocationId:parent.run.root_agent_invocation_id??parentAgentInvocationId;const delegationDepth=parentAgentInvocationId===null?0:(parent?.run.delegation_depth??0)+1;const developerIdentity=parent!==null?parent.run.developer_identity:input.developerIdentity??(this.storage.storageMode==="local_only"?null:await requireDeveloperIdentityCache(this.filesystem));const started=runStartedV2Schema.parse({schema_version:2,event_id:eventId(id,1),run_id:id,sequence:1,occurred_at:clock.now().toISOString(),type:"run.started",attribution_status:"attributed",developer_identity:developerIdentity,phase:input.phase,run_role:input.runRole??(input.phase!=="execution"?"intake":input.parentRunId!==void 0&&input.parentRunId!==null?"subagent":"orchestrator"),run_purpose:input.runPurpose??(input.phase!=="execution"?"intake":input.agent==="agent-finalizer"?"finalization":input.agent==="agent-reviewer"?"review":input.agent==="agent-auditor"?"audit":input.parentRunId===void 0||input.parentRunId===null?"orchestration":"execution"),requires_finalizer:input.requiresFinalizer??(input.phase==="execution"&&(input.parentRunId===void 0||input.parentRunId===null)&&input.executionId!==void 0&&input.executionId!==null),execution_kind:input.executionKind,execution_eligibility:[...input.executionEligibility??[]],entrypoint:input.entrypoint,work_type:input.workType,storage_mode:this.storage.storageMode,client:input.client,agent:input.agent,agent_name:input.agentName??null,...input.agentIdentityWarning===void 0?{}:{agent_identity_warning:input.agentIdentityWarning},provider:input.provider,model:input.model,reasoning_effort:input.reasoningEffort??null,client_thread_id:input.clientThreadId??null,client_turn_id:input.clientTurnId??null,conversation_id:input.conversationId,execution_id:input.executionId??null,task_id:input.taskId??null,spec_id:input.specId??null,prd_id:input.prdId??null,change_id:input.changeId??null,parent_run_id:input.parentRunId??null,...input.agentInvocationId===void 0?{}:{agent_invocation_id:input.agentInvocationId,root_agent_invocation_id:input.rootAgentInvocationId,parent_agent_invocation_id:input.parentAgentInvocationId,invocation_kind:input.invocationKind,delegation_depth:input.delegationDepth},continuation_of_run_id:input.continuationOfRunId??null,retry_of_run_id:input.retryOfRunId??null,agent_invocation_id:agentInvocationId,root_agent_invocation_id:rootAgentInvocationId,parent_agent_invocation_id:parentAgentInvocationId,invocation_kind:parentAgentInvocationId===null?"orchestrator":"delegated",delegation_depth:delegationDepth,intake:input.intake??null});const path=this.path(id);if(this.activeWriters.has(id)){throw new Error(`Run V2 already has a writer or persisted stream: ${id}`)}try{await this.filesystem.writeTextExclusive(path,serializeRecord(started))}catch(error51){if(!isNodeError6(error51)||error51.code!=="EEXIST")throw error51;throw new Error(`Run V2 already has a writer or persisted stream: ${id}`)}try{const correlation=codexTelemetryCorrelationFromRun(started);if(correlation!==null){await persistCodexTelemetryCorrelation(this.filesystem,correlation)}}catch(error51){await this.filesystem.removeFile(path);throw error51}this.activeWriters.add(id);return new RunV2Writer(this.filesystem,path,started,clock,()=>{this.activeWriters.delete(id)})}async read(id){const path=await this.readPath(id);if(path===null)throw new Error(`Run V2 not found: ${id}`);return foldRunV2Records(parseRunV2JsonLines(await this.filesystem.readText(path)))}async list(){const paths=await this.filesystem.listFiles(this.basePath(),".jsonl");const entries=await Promise.all(paths.map(async path=>{const run=foldRunV2Records(parseRunV2JsonLines(await this.filesystem.readText(path)));if(!this.candidatePaths(run.run.run_id).includes(path)){throw new Error(`Run V2 id does not match storage path: ${path}`)}return{path,run}}));const byId2=new Map;for(const entry of entries){const existing=byId2.get(entry.run.run.run_id);if(existing===void 0){byId2.set(entry.run.run.run_id,entry);continue}if(JSON.stringify(existing.run.records)!==JSON.stringify(entry.run.records)){throw new Error(`Run V2 has divergent monthly and legacy streams: ${entry.run.run.run_id}`)}if(entry.path===this.path(entry.run.run.run_id)){byId2.set(entry.run.run.run_id,entry)}}const runs=[...byId2.values()].map(entry=>entry.run);return runs.sort((left,right)=>right.run.occurred_at.localeCompare(left.run.occurred_at)||right.run.run_id.localeCompare(left.run.run_id))}async appendRecord(record3){const validated=runV2RecordSchema.parse(record3);const path=this.path(validated.run_id);const lockPath=`${path}.lock`;try{await this.filesystem.writeTextExclusive(lockPath,`${JSON.stringify({run_id:validated.run_id,pid:process.pid})}
|
|
1299
1299
|
`)}catch(error51){if(isNodeError6(error51)&&error51.code==="EEXIST"){throw new Error(`Run V2 is being updated concurrently: ${validated.run_id}`)}throw error51}try{const persistedPath=await this.readPath(validated.run_id);if(persistedPath!==path){throw new Error(`Run V2 ${validated.run_id} is stored in a legacy daily path; migrate it before append`)}const current=await this.read(validated.run_id);const expectedSequence=current.records.length+1;if(validated.sequence!==expectedSequence){throw new Error(`Run V2 compare-and-append failed: expected sequence ${expectedSequence}, received ${validated.sequence}`)}foldRunV2Records([...current.records,validated]);await this.filesystem.appendText(path,serializeRecord(validated))}finally{await this.filesystem.removeFile(lockPath)}}async withUsageAttributionLock(operation){return withUsageAttributionLock(this.filesystem,`${this.basePath()}/.usage-attribution.lock`,operation)}async withSubagentInvocationClaim(identity,resolveExisting,create,findExisting){const digest6=createHash10("sha256").update(identity).digest("hex");const claimPath=this.subagentInvocationClaimPath(digest6);await this.migrateLegacySubagentInvocationClaim(claimPath,digest6,identity);const ownerNonce=randomUUID2();const pending=invocationClaim(identity,ownerNonce);let ownsClaim=false;try{await this.filesystem.writeTextExclusive(claimPath,`${JSON.stringify(pending)}
|
|
1300
1300
|
`);ownsClaim=true}catch(error51){if(!isNodeError6(error51)||error51.code!=="EEXIST")throw error51}const deadline=Date.now()+5e3;while(!ownsClaim){const claim=await readInvocationClaim(this.filesystem,claimPath,identity,digest6);if(typeof claim.run_id==="string")return resolveExisting(claim.run_id);if(!claimIsStale(claim)){if(Date.now()>=deadline){throw new Error(`Subagent invocation claim remained pending: ${digest6}`)}await delay2(25);continue}const recoveryPath=await acquireRecoveryLease(this.filesystem,claimPath,claim.owner_nonce,ownerNonce);if(recoveryPath===null){if(Date.now()>=deadline){throw new Error(`Subagent invocation claim recovery timed out: ${digest6}`)}await delay2(25);continue}try{const current=await readInvocationClaim(this.filesystem,claimPath,identity,digest6);if(typeof current.run_id==="string")return resolveExisting(current.run_id);if(!claimIsStale(current))continue;await this.filesystem.writeTextAtomic(claimPath,`${JSON.stringify(pending)}
|
|
1301
1301
|
`);ownsClaim=true}finally{await this.filesystem.removeFile(recoveryPath)}}try{const adopted=await findExisting?.();if(adopted!==void 0&&adopted!==null){await commitInvocationClaim(this.filesystem,claimPath,identity,digest6,ownerNonce,adopted.runId);return adopted.value}const created=await create();await commitInvocationClaim(this.filesystem,claimPath,identity,digest6,ownerNonce,created.runId);return created.value}catch(error51){const claim=await readInvocationClaim(this.filesystem,claimPath,identity,digest6);if(claim.owner_nonce===ownerNonce&&claim.run_id===null){await this.filesystem.removeFile(claimPath)}throw error51}}path(id){if(this.storage.storageMode==="tracked_sanitized"){return this.storage.layout.activePath("run",id)}const{year,month}=datedIdParts(id);return`${this.storage.localBasePath}/${year}/${month}/${id}.jsonl`}candidatePaths(id){if(this.storage.storageMode==="tracked_sanitized"){return[this.path(id),...this.storage.layout.legacyReadCandidates("run",id).map(candidate=>candidate.path)]}const{year,month,day}=datedIdPartsWithDay(id);return[this.path(id),`${this.storage.localBasePath}/${year}/${month}/${day}/${id}.jsonl`]}async readPath(id){if(this.storage.storageMode==="tracked_sanitized"){return resolveArtifactReadPath(this.filesystem,this.storage.layout,"run",id)}for(const path of this.candidatePaths(id)){if(await this.filesystem.exists(path))return path}return null}basePath(){return this.storage.storageMode==="tracked_sanitized"?this.storage.layout.entityRoot("run"):this.storage.localBasePath}subagentInvocationClaimPath(digest6){return this.storage.storageMode==="tracked_sanitized"?lifecycleClaimPath("subagent-invocation",digest6):`${this.basePath()}/.claims/subagent-invocation/${digest6}.json`}async migrateLegacySubagentInvocationClaim(claimPath,digest6,identity){const legacyPath=`${this.basePath()}/.subagent-invocation-claims/${digest6}.json`;if(!await this.filesystem.exists(legacyPath))return;const legacy2=await readInvocationClaim(this.filesystem,legacyPath,identity,digest6);try{await this.filesystem.writeTextExclusive(claimPath,`${JSON.stringify(legacy2)}
|
|
@@ -1558,7 +1558,7 @@ ${statement}
|
|
|
1558
1558
|
- \`${acceptanceId}\`: setup and doctor validate this contract deterministically.
|
|
1559
1559
|
`}var V3_LIFECYCLE_MANIFEST_FILES=[{path:".agents/records/lifecycle/.gitkeep",content:""}];var V3_CONTEXT_CONFIG={canonical_roots:["packages",".agents/dashboard",".agents/design"],projection_roots:["public-cli","release"]};var DATA_DIRECTORIES=["prds","specs","changes","tasks","executions","runs"];var PUBLIC_ROOTS=new Set("config runtime rules requirements skills zaip-aios tools records data dashboard design architecture branding growth marketing sales .env.example .gitignore".split(" "));var LEGACY_RULE_RELOCATIONS=new Map(["core","workflow","architecture","security","context"].map(name=>[`.agents/rules/zaip/${name}.md`,`.agents/rules/${name}.md`]));var OBSOLETE_RULE_MARKER=".agents/rules/.gitkeep";var LEGACY_ROOTS=[".agents/manifest.yaml",".agents/constitution.md",".agents/specs",".agents/changes",".agents/tasks",".agents/decisions",".agents/runs",".agents/generated",".agents/managed",".agents/project",".agents/telemetry",".agents/local",".agents/state"];var DEFAULT_V2_MANAGED_FILES=[{path:".agents/rules/core.md",content:ruleTemplate("RULE-CORE","always","critical",500,[],"Read only relevant Rules and Requirements. Preserve project-owned files and record Evidence before completion.")},{path:".agents/rules/workflow.md",content:ruleTemplate("RULE-WORKFLOW","always","critical",800,["RULE-CORE"],"PRD and SPEC are optional. Task-first assurance is proportional, SPEC/PRD add parent assurance, and executable work materializes Change, Task and Execution before mutation.")},{path:".agents/rules/architecture.md",content:ruleTemplate("RULE-ARCHITECTURE","auto","critical",1e3,["RULE-CORE"],"Preserve module boundaries, dependency direction and explicit integration boundaries.")},{path:".agents/rules/security.md",content:ruleTemplate("RULE-SECURITY","auto","critical",800,["RULE-CORE"],"Do not expose secrets. Validate trust boundaries and prefer deterministic offline verification.")},{path:".agents/rules/context.md",content:ruleTemplate("RULE-CONTEXT","auto","high",650,["RULE-CORE"],"Load only relevant Rules, Requirements, source files and tests. Exclude raw Run events from common context packs.")},{path:".agents/requirements/work-lifecycle.md",content:requirementTemplate("WORK-LIFECYCLE","work-lifecycle","Work lifecycle","REQ-WORK-001","AC-WORK-001-01","Task-first, SPEC and PRD entries remain optional and distinguishable.")},{path:".agents/requirements/execution-engine.md",content:requirementTemplate("EXECUTION-ENGINE","execution-engine","Execution engine","REQ-EXEC-002","AC-EXEC-002-02","Execution materializes a validated DAG idempotently before delivery mutation.")},{path:".agents/requirements/cost-observability.md",content:requirementTemplate("COST-OBSERVABILITY","cost-observability","Cost observability","REQ-COST-001","AC-COST-001-01","Tokens and costs preserve phase, coverage and macro attribution without inventing zeroes.")},{path:".agents/requirements/kanban-dashboard.md",content:requirementTemplate("KANBAN-DASHBOARD","kanban-dashboard","Kanban and dashboard","REQ-DASH-001","AC-DASH-001-01","Operational views expose the complete V2 lifecycle and macro ancestry.")},{path:".agents/requirements/context-engine.md",content:requirementTemplate("CONTEXT-ENGINE","context-engine","Context engine","REQ-CONTEXT-001","AC-CONTEXT-001-01","Context starts from project config and relevant governance without legacy global state.")},{path:".agents/requirements/autonomous-assurance.md",content:requirementTemplate("AUTONOMOUS-ASSURANCE","autonomous-assurance","Adaptive assurance and autonomous execution","REQ-ASSURE-001","AC-ASSURE-001-01","Task assurance uses risk-scaled minimum evidence without artifact quotas; critical controls are enabled by declared risk signals, while SPEC/PRD add parent assurance.")}];async function setupProjectV2(filesystem,options){const hasProject=await filesystem.exists(PROJECT_CONFIG_PATH);const hasLock=await filesystem.exists(FRAMEWORK_LOCK_PATH);if(hasProject!==hasLock){const conflict=hasProject?PROJECT_CONFIG_PATH:FRAMEWORK_LOCK_PATH;return setupResult([],[],[],[conflict],[conflict],{},options.dryRun??false,false)}const fresh=!hasProject;const projectConfig=hasProject?parseProjectConfig(parseYaml(await filesystem.readText(PROJECT_CONFIG_PATH))):desiredProjectConfig(options);const existingLock=hasLock?parseFrameworkLock(parseYaml(await filesystem.readText(FRAMEWORK_LOCK_PATH))):null;const managedCandidates=managedSetupCandidates(options.templateFiles??[]);const managedFiles=Object.fromEntries(managedCandidates.filter(({managed})=>managed).map(candidate=>[candidate.path,managedFileHash(candidate.path,new TextEncoder().encode(candidate.content))]));const frameworkLock=desiredFrameworkLock(options,projectConfig,existingLock,managedFiles);const candidates=[...fresh?[{path:PROJECT_CONFIG_PATH,content:serializeYaml(projectConfig),managed:false}]:[],...managedCandidates,...fresh&&options.bootstrapTask===true?bootstrapCandidates(projectConfig,frameworkLock,options):[]];const created=[];const updated=[];const existing=[];const preserved=hasProject?[PROJECT_CONFIG_PATH]:[];const conflicts=[];const writes=[];const deletes=[];for(const candidate of candidates){if(!await filesystem.exists(candidate.path)){created.push(candidate.path);writes.push({...candidate,operation:"create",previous:null});continue}const actual=await filesystem.readText(candidate.path);if(actual===candidate.content){existing.push(candidate.path);continue}if(!candidate.managed){conflicts.push(candidate.path);continue}const recorded=existingLock?.managed_files[candidate.path];if(recorded===void 0||sha256(actual)!==recorded){conflicts.push(candidate.path);continue}updated.push(candidate.path);writes.push({...candidate,operation:"update",previous:actual})}for(const path of[...LEGACY_RULE_RELOCATIONS.keys(),OBSOLETE_RULE_MARKER]){if(!await filesystem.exists(path))continue;const actual=await filesystem.readText(path);const recorded=existingLock?.managed_files[path];if(recorded===void 0||sha256(actual)!==recorded){conflicts.push(path);continue}updated.push(path);deletes.push({path,previous:actual})}const lockContent=serializeYaml(frameworkLock);if(!hasLock){created.push(FRAMEWORK_LOCK_PATH);writes.push({path:FRAMEWORK_LOCK_PATH,content:lockContent,managed:false,operation:"create",previous:null})}else{const actualLock=await filesystem.readText(FRAMEWORK_LOCK_PATH);if(actualLock===lockContent)existing.push(FRAMEWORK_LOCK_PATH);else{updated.push(FRAMEWORK_LOCK_PATH);writes.push({path:FRAMEWORK_LOCK_PATH,content:lockContent,managed:false,operation:"update",previous:actualLock})}}const dryRun=options.dryRun??false;if(dryRun||conflicts.length>0){return setupResult(created,updated,existing,preserved,conflicts,managedFiles,dryRun,false)}const applied=[];const removed=[];try{for(const write of writes){if(write.operation==="create"){await filesystem.writeTextExclusive(write.path,write.content)}else{await filesystem.writeTextAtomic(write.path,write.content)}applied.push(write)}for(const deletion of deletes){await filesystem.removeFile(deletion.path);removed.push(deletion)}}catch(error51){for(const deletion of removed.reverse()){await filesystem.writeTextAtomic(deletion.path,deletion.previous)}for(const write of applied.reverse()){if(write.previous===null)await filesystem.removeFile(write.path);else await filesystem.writeTextAtomic(write.path,write.previous)}throw error51}return setupResult(created,updated,existing,preserved,conflicts,managedFiles,dryRun,true)}async function doctorProjectV2(filesystem){const findings=[];const[hasProject,hasLock]=await Promise.all([filesystem.exists(PROJECT_CONFIG_PATH),filesystem.exists(FRAMEWORK_LOCK_PATH)]);let project=null;let lock2=null;if(!hasProject)addFinding(findings,"error","missing-config",PROJECT_CONFIG_PATH,"V2 project config is missing","inactive");if(!hasLock)addFinding(findings,"error","missing-config",FRAMEWORK_LOCK_PATH,"V2 framework lock is missing","inactive");if(hasProject){try{project=parseProjectConfig(parseYaml(await filesystem.readText(PROJECT_CONFIG_PATH)))}catch(error51){addFinding(findings,"error","invalid-config",PROJECT_CONFIG_PATH,errorMessage2(error51),"inactive")}}if(hasLock){try{lock2=parseFrameworkLock(parseYaml(await filesystem.readText(FRAMEWORK_LOCK_PATH)))}catch(error51){addFinding(findings,"error","invalid-config",FRAMEWORK_LOCK_PATH,errorMessage2(error51),"inactive")}}if(project!==null&&lock2!==null){const layout=createV2WorkspaceLayout(project,lock2);for(const[kind]of DATA_DIRECTORIES.entries()){const entityKind=["prd","spec","change","task","execution","run"][kind];const expected=layout.entityRoot(entityKind);if(layout.entityRoot(entityKind)!==expected){addFinding(findings,"error","invalid-layout",expected,"WorkspaceLayout V2 root mismatch","inactive")}if(!await filesystem.exists(expected)){addFinding(findings,"error","missing-data-root",expected,"V2 data root is missing","inactive")}}for(const file2 of DEFAULT_V2_MANAGED_FILES){if(!await filesystem.exists(file2.path)){addFinding(findings,"error","missing-required-managed-file",file2.path,"Required V2 Rule or Requirement is missing","inactive");continue}try{const content=await filesystem.readText(file2.path);if(!file2.path.startsWith(".agents/rules/"))parseRequirementDocument(content)}catch(error51){addFinding(findings,"error","invalid-governance-document",file2.path,errorMessage2(error51),"inactive")}}const ruleIds=new Map;const rulePaths=[...await filesystem.listFiles(".agents/rules")].sort();for(const path of rulePaths){const isRootFile=/^\.agents\/rules\/[^/]+$/.test(path);if(!isRootFile){addFinding(findings,"error","invalid-rule-path",path,"Rules must live directly under .agents/rules","inactive");continue}if(!path.endsWith(".md")){addFinding(findings,"error","invalid-rule-file",path,"Rules must be Markdown files","inactive");continue}try{const rule=parseRuleDocument(await filesystem.readText(path));const previous=ruleIds.get(rule.metadata.id);if(previous!==void 0){addFinding(findings,"error","duplicate-rule-id",path,`Rule id ${rule.metadata.id} is already declared by ${previous}`,"inactive")}else{ruleIds.set(rule.metadata.id,path)}}catch(error51){addFinding(findings,"error","invalid-governance-document",path,errorMessage2(error51),"inactive")}}for(const[path,recordedHash]of Object.entries(lock2.managed_files)){if(!isManagedPath(path)){addFinding(findings,"error","invalid-managed-path",path,"Lock owns a file outside V2 managed namespaces","inactive");continue}if(!await filesystem.exists(path)){addFinding(findings,"error","missing-managed-file",path,"Managed file is missing","inactive");continue}if(managedFileHash(path,await filesystem.readBytes(path))!==recordedHash){addFinding(findings,"error","managed-hash-mismatch",path,"Managed file differs from framework.lock.yaml","inactive")}}}for(const path of LEGACY_ROOTS){if(await filesystem.exists(path)){addFinding(findings,"error","legacy-layout",path,"Legacy public state is inactive under V2","legacy")}}for(const path of await filesystem.listDirectories(".agents")){const root=path.split("/")[1];if(root!==void 0&&!PUBLIC_ROOTS.has(root)){addFinding(findings,"error","inactive-public-root",path,"Path is outside the public V2 layout","inactive")}}for(const path of await filesystem.listFiles(".agents")){const root=path.split("/")[1];if(root!==void 0&&!PUBLIC_ROOTS.has(root)){addFinding(findings,"error","inactive-public-root",path,"Path is outside the public V2 layout","inactive")}}return findings.sort((left,right)=>left.path.localeCompare(right.path)||left.code.localeCompare(right.code))}function desiredProjectConfig(options){return parseProjectConfig({schema_version:1,zaip:{enabled:true},project:{id:options.projectId??normalizeProjectId(options.projectName),name:options.projectName,timezone:options.timezone??"America/Sao_Paulo"},stack:{id:options.profileId??"zaip-aios-stack",language:"typescript",api:"hono",query_builder:"kysely",extensions:[".ts",".tsx"],layout:{frontend:"apps/frontend",backend:"apps/backend",site:"apps/site",modules:"modules",packages:"packages",e2e:"tests/e2e"},source_limits:{warning_lines:400,error_lines:800},invariants:["clean-architecture","cqrs","module-storage-private"],commands:{test:"corepack pnpm test",typecheck:"corepack pnpm typecheck"},overrides:{}},clients:options.clients??{codex:true,claude:true},tracking:{enabled:options.tracking?.enabled??true,currency:options.tracking?.currency??"BRL",storage_mode:options.tracking?.storageMode??"tracked_sanitized"},model_orchestration:{mode:"manual",default_model:"manual",default_effort:"manual",default_velocity:"manual",notice:"always"},execution:{runtime:"manual"},assurance:{version:1,standard_depth:"auto",require_final_commit:true},context:V3_CONTEXT_CONFIG})}function desiredFrameworkLock(options,project,existing,managedFiles){return parseFrameworkLock({lock_version:2,framework:{version:options.frameworkVersion??existing?.framework.version??"0.2.0",distribution_sha256:options.distributionSha256===void 0?existing?.framework.distribution_sha256??null:options.distributionSha256},layout:{version:3},resolved_profile:{id:project.stack.id,sha256:options.profileSha256===void 0?existing?.resolved_profile.sha256??null:options.profileSha256},managed_files:managedFiles})}function managedSetupCandidates(templateFiles){const files=new Map;for(const file2 of DEFAULT_V2_MANAGED_FILES){files.set(file2.path,{...file2,managed:true})}for(const directory of DATA_DIRECTORIES){const path=`.agents/records/${directory}/.gitkeep`;files.set(path,{path,content:"",managed:true})}for(const file2 of V3_LIFECYCLE_MANIFEST_FILES)files.set(file2.path,{...file2,managed:true});files.set(".agents/skills/.gitkeep",{path:".agents/skills/.gitkeep",content:"",managed:true});for(const file2 of templateFiles){const managed=file2.path!==".agents/config/agents/catalog.yaml";if(managed&&!isTemplatePath(file2.path)){throw new TypeError(`V2 template path must target the agent catalog, rules, requirements or skills: ${file2.path}`)}files.set(file2.path,{...file2,managed})}return[...files.values()].sort((left,right)=>left.path.localeCompare(right.path))}function bootstrapCandidates(project,lock2,options){const clock=options.clock??new SystemClock;const now=clock.now().toISOString();const idOptions={clock,timeZone:project.project.timezone,...options.collisionCode===void 0?{}:{collisionCode:options.collisionCode}};const changeId=createId("CHG","bootstrap zaip",idOptions);const taskId=createId("TASK","bootstrap zaip",idOptions);const executionId=createId("RUN","bootstrap zaip",idOptions).replace(/^RUN-/,"EXEC-");const planHash=sha256(JSON.stringify({changeId,taskId,executionId,revision:1}));const layout=createV2WorkspaceLayout(project,lock2);const change={schema_version:2,id:changeId,revision:1,title:"Validate ZAIP-AIOS V2 bootstrap",status:"planned",risk:"lite",source:{type:"task",task_id:taskId},requirement_ids:["REQ-EXEC-002"],acceptance_ids:["AC-EXEC-002-02"],requirement_impact:{type:"none",reason:"Bootstrap validates existing requirements."},task_ids:[taskId],plan_revision:1,plan_hash:planHash,created_at:now,updated_at:now,started_at:null,finished_at:null,result:null};const task={schema_version:2,id:taskId,revision:1,change_id:changeId,title:"Validate ZAIP-AIOS V2 bootstrap",short_name:"bootstrap zaip",objective:"Verify the fresh V2 installation before delivery work begins.",status:"planned",risk:"lite",priority:"high",owner:"zaip-skill-setup",requirement_ids:["REQ-EXEC-002"],acceptance_ids:["AC-EXEC-002-02"],depends_on:[],write_scopes:[],plan_revision:1,plan_hash:planHash,created_at:now,updated_at:now,started_at:null,finished_at:null,result:null};const execution={schema_version:2,id:executionId,revision:1,kind:"delivery",client_turn_id:null,origin:{type:"task",task_id:taskId},status:"planned",plan_revision:1,plan_hash:planHash,policy:{failure_policy:"stop_on_terminal_failure",max_parallelism:1,max_operational_retries:1,max_repair_cycles_per_task:2},dag:{nodes:[{task_id:taskId,change_id:changeId,depends_on:[]}],topological_order:[taskId]},created_at:now,updated_at:now,started_at:null,finished_at:null,result:null};return[{path:layout.activePath("change",changeId),content:serializeMarkdown({metadata:change,body:"# Bootstrap Change\n\nPlanned validation of the fresh V2 workspace."}),managed:false},{path:layout.activePath("task",taskId),content:serializeMarkdown({metadata:task,body:"# Bootstrap Task\n\nTask-first validation without a synthetic SPEC."}),managed:false},{path:layout.activePath("execution",executionId),content:serializeMarkdown({metadata:execution,body:`# Bootstrap Execution ${executionId}
|
|
1560
1560
|
|
|
1561
|
-
The persisted DAG owns ${taskId} and ${changeId}.`}),managed:false}]}function setupResult(created,updated,existing,preserved,conflicts,managedFiles,dryRun,applied){const sorted=values=>[...new Set(values)].sort();return{created:sorted(created),updated:sorted(updated),existing:sorted(existing),preserved:sorted(preserved),conflicts:sorted(conflicts),managedFiles,dryRun,applied}}function isTemplatePath(path){return isCanonicalPath(path)&&(/^\.agents\/rules\/[^/]+\.md$/.test(path)||/^\.agents\/(?:(?:requirements|skills|design|zaip-aios|tools)\/.+|config\/(?:clients\.yaml|src\/icon_zaip\.png|pricing\/.+)|runtime\/.+)$/.test(path))}function isManagedPath(path){return isTemplatePath(path)||isCanonicalPath(path)&&/^\.agents\/(?:records|data)\/(?:prds|specs|changes|tasks|executions|runs|lifecycle)\/\.gitkeep$/.test(path)}function isCanonicalPath(path){return path.length>0&&!path.includes("\\")&&!path.includes("\0")&&!path.startsWith("/")&&!path.startsWith("./")&&!/^[A-Za-z]:/.test(path)&&path.split("/").every(segment2=>segment2.length>0&&segment2!=="."&&segment2!=="..")}function normalizeProjectId(name){const id=name.normalize("NFKD").replace(/[\u0300-\u036f]/g,"").toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"");if(id.length===0)throw new TypeError("projectName must contain at least one letter or number");return id}function sha256(content){return createHash18("sha256").update(content).digest("hex")}function managedFileHash(path,content){if(/\.(?:avif|gif|ico|jpe?g|png|webp)$/i.test(path))return sha256(content);return sha256(Buffer.from(content).toString("utf8").replace(/\r\n/g,"\n"))}function addFinding(findings,severity,code,path,message,state){if(!findings.some(finding2=>finding2.code===code&&finding2.path===path)){findings.push({severity,code,path,message,state})}}function errorMessage2(error51){return error51 instanceof Error?error51.message:String(error51)}var MigrationPlanHashError=class extends Error{name="MigrationPlanHashError"};var MigrationSourceDivergenceError=class extends Error{name="MigrationSourceDivergenceError"};var MigrationCollisionError=class extends Error{name="MigrationCollisionError"};async function planV1ToV2Migration(filesystem,options={}){const fingerprint=await fingerprintV1Source(filesystem);const manifestFile=fingerprint.files.find(file2=>file2.path===".agents/manifest.yaml");if(manifestFile===void 0)throw new Error("V1 manifest is required for migration");const manifest=asRecord2(parseYaml(await filesystem.readText(manifestFile.path)),"manifest");if(manifest.schema_version!==1)throw new Error("Only a schema_version 1 manifest is supported");const promotions=[...options.promotions??[]].sort((left,right)=>left.legacy_spec_id.localeCompare(right.legacy_spec_id));assertPromotionMappings(promotions);const promotedSpecIds=new Map(promotions.map(promotion=>[promotion.legacy_spec_id,promotion.delivery_spec_id]));const findings=[];const operations=[];const changes=await loadMarkdownDocuments(filesystem,fingerprint,".agents/changes/","/proposal.md");const tasks=await loadMarkdownDocuments(filesystem,fingerprint,".agents/tasks/",".md");const capabilities=await loadMarkdownDocuments(filesystem,fingerprint,".agents/specs/capabilities/","/spec.md");const decisions=await loadMarkdownDocuments(filesystem,fingerprint,".agents/decisions/",".md");assertPromotionAuthorizations(promotions,decisions);const evidence=await loadBinarySources(filesystem,fingerprint,".agents/evidence/",".md");const runs=await loadMarkdownDocuments(filesystem,fingerprint,".agents/runs/",".md");const telemetryRunSources=await loadJsonLineSources(filesystem,fingerprint,".agents/telemetry/","runs.jsonl");const telemetryCycleSources=await loadJsonLineSources(filesystem,fingerprint,".agents/telemetry/","cycles.jsonl");const taskIdsByChange=new Map;const changeByTaskId=new Map;const specByTaskId=new Map;for(const task of tasks){const taskId=requiredString2(task.metadata.id,`${task.path}:id`);const changeId=requiredString2(task.metadata.change,`${task.path}:change`);taskIdsByChange.set(changeId,[...taskIdsByChange.get(changeId)??[],taskId].sort());changeByTaskId.set(taskId,changeId);specByTaskId.set(taskId,typeof task.metadata.spec==="string"&&task.metadata.spec.startsWith("SPEC-")?task.metadata.spec:null)}const changeIds=new Set(changes.map(change=>requiredString2(change.metadata.id,change.path)).filter(changeId=>(taskIdsByChange.get(changeId)?.length??0)>0));const runIdsByTask=new Map;for(const run of runs){const taskId=typeof run.metadata.task==="string"?run.metadata.task:null;const runId=typeof run.metadata.id==="string"?run.metadata.id:null;if(taskId!==null&&runId!==null){runIdsByTask.set(taskId,[...runIdsByTask.get(taskId)??[],runId].sort())}}const migrationTimestamp=sourceTimestamp([...changes,...tasks]);const date5=migrationTimestamp.slice(0,16).replace(/[-T:]/g,"-");const suffix=fingerprint.sha256.slice(0,8).toUpperCase();const migrationId=`MIG-${suffix}`;const migrationExecutionId=`EXEC-${date5}-MIGRATE-V1-V2-${suffix}`;const migrationTaskId=`TASK-${date5}-MIGRATE-V1-V2-${suffix}`;const migrationChangeId=`CHG-${date5}-MIGRATE-V1-V2-${suffix}`;const migrationRunId=`RUN-${date5}-MIGRATE-V1-V2-${suffix}`;let convertedChangeCount=0;for(const change of changes){const id=requiredString2(change.metadata.id,`${change.path}:id`);const taskIds=taskIdsByChange.get(id)??[];if(taskIds.length===0){findings.push({severity:"warning",code:"change-without-task-archived",path:change.path,message:`${id} has no Task and will remain legacy evidence.`});continue}const requirements=legacyIds(change.metadata.requirements,"REQ",change.sha256);const acceptanceIds=acceptanceIdsFor(requirements,change.sha256);const status=workStatus(change.metadata.status);const createdAt=timestamp10(change.metadata.created_at,migrationTimestamp);const updatedAt=timestamp10(change.metadata.updated_at,createdAt);const terminal=["completed","failed","cancelled"].includes(status);const promotedChangeSpecs=stringArray(change.metadata.capabilities).map(legacyId=>promotedSpecIds.get(legacyId)).filter(id2=>id2!==void 0).sort();if(promotedChangeSpecs.length>1){findings.push({severity:"warning",code:"multiple-promoted-specs-on-change",path:change.path,message:`Change references multiple promoted Specs; ${promotedChangeSpecs[0]} is the canonical source.`})}const source=promotedChangeSpecs[0]===void 0?{type:"task",task_id:taskIds[0]}:{type:"spec",spec_id:promotedChangeSpecs[0]};const startedAt=["executing","verifying","completed","failed"].includes(status)?timestamp10(change.metadata.started_at,createdAt):null;const converted={schema_version:2,id,revision:1,title:stringOr(change.metadata.title,id),status,risk:risk(change.metadata.risk),source,requirement_ids:requirements,acceptance_ids:acceptanceIds,requirement_impact:{type:"none",reason:"Migrated from V1 without semantic promotion."},task_ids:taskIds,plan_revision:1,plan_hash:change.sha256,created_at:createdAt,updated_at:updatedAt,started_at:startedAt,finished_at:terminal?timestamp10(change.metadata.completed_at??change.metadata.finished_at,updatedAt):null,result:terminal?"Migrated from the terminal V1 Change record.":null};operations.push(textOperation("convert","change",change.path,change.sha256,v2EntityPath2("changes",id,"change.md"),serializeMarkdown({metadata:converted,body:provenanceBody(change.body,change.path,change.sha256)})));convertedChangeCount+=1}const convertibleTaskIds=new Set(tasks.filter(task=>changeIds.has(requiredString2(task.metadata.change,`${task.path}:change`))).map(task=>requiredString2(task.metadata.id,`${task.path}:id`)));const convertedTaskIds=new Set;for(const task of tasks){const id=requiredString2(task.metadata.id,`${task.path}:id`);const changeId=requiredString2(task.metadata.change,`${task.path}:change`);if(!changeIds.has(changeId)){findings.push({severity:"warning",code:"task-without-change-archived",path:task.path,message:`${id} has no converted Change and will remain legacy evidence.`});continue}const requirements=legacyIds(task.metadata.requirements,"REQ",task.sha256);const status=workStatus(task.metadata.status);const createdAt=timestamp10(task.metadata.created_at,migrationTimestamp);const terminal=["completed","failed","cancelled"].includes(status);const changedFiles=changedFilesFromLegacyTask(task.body);const legacyDependencies=legacyIds(task.metadata.depends_on,"TASK",task.sha256,true);const dependencies=legacyDependencies.filter(dependency=>convertibleTaskIds.has(dependency));if(dependencies.length!==legacyDependencies.length){findings.push({severity:"warning",code:"missing-task-dependency-removed",path:task.path,message:`${id} referenced a Task dependency that cannot be converted.`})}const converted={schema_version:2,id,revision:1,change_id:changeId,title:stringOr(task.metadata.title,id),short_name:stringOr(task.metadata.short_name,"legacy-task"),objective:bodySection(task.body,"Objetivo")||stringOr(task.metadata.title,id),status,risk:risk(task.metadata.risk),priority:priority(task.metadata.priority),owner:typeof task.metadata.owner==="string"&&task.metadata.owner.length>0?task.metadata.owner:null,requirement_ids:requirements,acceptance_ids:acceptanceIdsFor(requirements,task.sha256),depends_on:dependencies,write_scopes:changedFiles,plan_revision:1,plan_hash:task.sha256,created_at:createdAt,updated_at:timestamp10(task.metadata.finished_at??task.metadata.started_at,createdAt),started_at:["executing","verifying","completed","failed"].includes(status)?timestamp10(task.metadata.started_at,createdAt):null,finished_at:terminal?timestamp10(task.metadata.finished_at,createdAt):null,result:terminal?{summary:"Migrated from the terminal V1 Task record.",changed_files:changedFiles,evidence_ids:[`EVD-LEGACY-${task.sha256.slice(0,12).toUpperCase()}`],completed_run_id:runIdsByTask.get(id)?.[0]??migrationRunId}:null};operations.push(textOperation("convert","task",task.path,task.sha256,v2EntityPath2("tasks",id,`${id}.md`),serializeMarkdown({metadata:converted,body:provenanceBody(task.body,task.path,task.sha256)})));convertedTaskIds.add(id)}let convertedDecisions=0;for(const decision of decisions){const id=requiredString2(decision.metadata.id,`${decision.path}:id`);const directChange=typeof decision.metadata.change==="string"?decision.metadata.change:null;const taskId=typeof decision.metadata.task==="string"?decision.metadata.task:null;const changeId=directChange!==null&&changeIds.has(directChange)?directChange:taskId===null?null:changeByTaskId.get(taskId)??null;if(changeId===null||!changeIds.has(changeId)){findings.push({severity:"warning",code:"orphan-decision-archived",path:decision.path,message:`${id} has no resolvable Change and will remain only as legacy evidence.`});continue}const origin=decision.metadata.origin==="human"?"human":"agent";const createdAt=timestamp10(decision.metadata.created_at,migrationTimestamp);if(origin==="human"&&nullableTimestamp(decision.metadata.confirmed_at)===null){findings.push({severity:"warning",code:"unconfirmed-human-decision-archived",path:decision.path,message:`${id} has no explicit confirmation provenance and will remain legacy evidence.`});continue}const converted={schema_version:2,id,title:stringOr(decision.metadata.title,id),scope_type:"change",scope_id:changeId,origin,category:decisionCategory(decision.metadata.category),context:stringOr(decision.metadata.context,"Context preserved from the V1 Decision."),decision:stringOr(decision.metadata.decision,decision.body.trim()||"See the preserved V1 Decision body."),reason:stringOr(decision.metadata.reason,"Reason preserved in the V1 provenance."),alternatives:stringArray(decision.metadata.alternatives),consequences:stringArray(decision.metadata.consequences),reversible:decision.metadata.reversible===true,rollback:stringOr(decision.metadata.rollback,"Restore the V1 source from the migration journal backup."),confidence:origin==="human"?null:typeof decision.metadata.confidence==="number"?decision.metadata.confidence:.5,created_at:createdAt,confirmed_at:nullableTimestamp(decision.metadata.confirmed_at)};const target=`${v2EntityDirectory("changes",changeId)}/${changeId}/decisions/${id}.md`;operations.push(textOperation("convert","decision",decision.path,decision.sha256,target,serializeMarkdown({metadata:converted,body:decisionProvenanceBody(decision.body,decision.metadata,decision.path,decision.sha256)})));convertedDecisions+=1}let relocatedEvidence=0;for(const artifact of evidence){const taskId=artifact.path.match(/\/((?:TASK)-[^/]+)\.md$/)?.[1]??null;const changeId=taskId===null?null:changeByTaskId.get(taskId)??null;if(taskId===null||!convertedTaskIds.has(taskId)||changeId===null||!changeIds.has(changeId)){findings.push({severity:"warning",code:"orphan-evidence-archived",path:artifact.path,message:"Evidence filename does not resolve through Task to a migrated Change."});continue}operations.push(bytesOperation("convert","evidence",artifact.path,artifact.sha256,`${v2EntityDirectory("changes",changeId)}/${changeId}/artifacts/evidence/${taskId}.md`,artifact.bytes));relocatedEvidence+=1}const telemetryRuns=telemetryRunSources.flatMap(source=>source.rows.map(row=>({...row,source_path:source.path})));const telemetryCycles=telemetryCycleSources.flatMap(source=>source.rows.map(row=>({...row,source_path:source.path})));const consumedTelemetryPaths=new Set;let convertedRuns=0;let usageRecords=0;for(const run of runs){const id=requiredString2(run.metadata.id,`${run.path}:id`);const taskId=typeof run.metadata.task==="string"&&run.metadata.task.startsWith("TASK-")?run.metadata.task:null;const changeId=taskId===null?null:changeByTaskId.get(taskId)??null;if(taskId===null||!convertedTaskIds.has(taskId)||changeId===null||!changeIds.has(changeId)){findings.push({severity:"warning",code:"orphan-run-archived",path:run.path,message:`${id} cannot be attributed to a migrated Task and Change.`});continue}const aggregateCandidates=telemetryRuns.filter(row=>row.run_id===id).sort((left,right)=>stringOr(left.recorded_at,"").localeCompare(stringOr(right.recorded_at,"")));const aggregate=aggregateCandidates.at(-1)??null;const cycles=telemetryCycles.filter(row=>row.run_id===id).sort((left,right)=>numberOr(left.cycle_index,0)-numberOr(right.cycle_index,0)||stringOr(left.timestamp,"").localeCompare(stringOr(right.timestamp,"")));const startedAt=timestamp10(run.metadata.started_at,migrationTimestamp);const provider=nullableString2(aggregate?.provider??run.metadata.provider);const model=stringOr(aggregate?.model??run.metadata.model,"legacy-unknown");const client=stringOr(aggregate?.client??run.metadata.client,"legacy");const agent=stringOr(aggregate?.agent??run.metadata.agent,"legacy");const records=[{schema_version:2,event_id:runEventId(id,1),run_id:id,sequence:1,occurred_at:startedAt,type:"run.started",phase:"execution",entrypoint:"task",work_type:"new",storage_mode:"tracked_sanitized",attribution_status:"legacy_unattributed",client,agent,provider,model,conversation_id:`CONV-LEGACY-${sha2562(id).slice(0,24).toUpperCase()}`,execution_id:null,task_id:taskId,spec_id:specByTaskId.get(taskId)===null?null:promotedSpecIds.get(specByTaskId.get(taskId))??null,prd_id:null,change_id:changeId,parent_run_id:null,continuation_of_run_id:null,retry_of_run_id:null}];const selectedUsage=cycles.length>0?cycles.map((cycle,index)=>({usage:cycle.token_usage,cost:cycle.estimated_cost,occurredAt:timestamp10(cycle.timestamp,startedAt),provider:nullableString2(cycle.provider)??provider,model:nullableString2(cycle.model)??model,activityKind:"legacy_cycle",sourceKey:`${stringOr(cycle.source_segment_key,`legacy:${id}`)}#cycle-${numberOr(cycle.cycle_index,index+1)}-${sha2562(JSON.stringify(cycle)).slice(0,8)}`,sourcePath:requiredString2(cycle.source_path,"cycle source path")})):aggregate!==null?[{usage:aggregate.token_usage,cost:aggregate.estimated_cost,occurredAt:timestamp10(aggregate.finished_at??aggregate.recorded_at,startedAt),provider,model,activityKind:"legacy_run_aggregate",sourceKey:stringOr(aggregate.source_segment_key,`legacy:${id}:aggregate`),sourcePath:requiredString2(aggregate.source_path,"run telemetry source path")}]:run.metadata.token_usage!==void 0?[{usage:run.metadata.token_usage,cost:run.metadata.cost,occurredAt:timestamp10(run.metadata.finished_at,startedAt),provider,model,activityKind:"legacy_markdown_run",sourceKey:`legacy:${id}:markdown`,sourcePath:run.path}]:[];for(const selected of selectedUsage){consumedTelemetryPaths.add(selected.sourcePath);const sequence=records.length+1;records.push({schema_version:2,event_id:runEventId(id,sequence),run_id:id,sequence,occurred_at:selected.occurredAt,type:"usage.recorded",phase:"execution",activity_kind:selected.activityKind,classification_source:"legacy_inferred",tokens:legacyTokenUsage(selected.usage),cost:legacyCost(selected.cost),provider:selected.provider,model:selected.model,source_segment_key:selected.sourceKey,supersedes_event_id:null});usageRecords+=1}const status=run.metadata.status;if(status==="completed"||status==="failed"||status==="cancelled"){const sequence=records.length+1;records.push({schema_version:2,event_id:runEventId(id,sequence),run_id:id,sequence,occurred_at:timestamp10(run.metadata.finished_at,startedAt),type:"run.finished",phase:"execution",status})}operations.push(textOperation("convert","run",run.path,run.sha256,v2EntityPath2("runs",id,`${id}.jsonl`),`${records.map(record3=>JSON.stringify(record3)).join("\n")}
|
|
1561
|
+
The persisted DAG owns ${taskId} and ${changeId}.`}),managed:false}]}function setupResult(created,updated,existing,preserved,conflicts,managedFiles,dryRun,applied){const sorted=values=>[...new Set(values)].sort();return{created:sorted(created),updated:sorted(updated),existing:sorted(existing),preserved:sorted(preserved),conflicts:sorted(conflicts),managedFiles,dryRun,applied}}function isTemplatePath(path){return isCanonicalPath(path)&&(path===".local/.gitignore"||/^\.agents\/rules\/[^/]+\.md$/.test(path)||/^\.agents\/(?:(?:architecture|branding|dashboard|design|growth|marketing|requirements|sales|skills|tools|zaip-aios)\/.+|config\/(?:(?:agents|clients|pricing)\/.+|clients\.yaml|src\/icon_zaip\.png)|runtime\/.+)$/.test(path))}function isManagedPath(path){return isTemplatePath(path)||isCanonicalPath(path)&&/^\.agents\/(?:records|data)\/(?:prds|specs|changes|tasks|executions|runs|lifecycle)\/\.gitkeep$/.test(path)}function isCanonicalPath(path){return path.length>0&&!path.includes("\\")&&!path.includes("\0")&&!path.startsWith("/")&&!path.startsWith("./")&&!/^[A-Za-z]:/.test(path)&&path.split("/").every(segment2=>segment2.length>0&&segment2!=="."&&segment2!=="..")}function normalizeProjectId(name){const id=name.normalize("NFKD").replace(/[\u0300-\u036f]/g,"").toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"");if(id.length===0)throw new TypeError("projectName must contain at least one letter or number");return id}function sha256(content){return createHash18("sha256").update(content).digest("hex")}function managedFileHash(path,content){if(/\.(?:avif|cmd|docx|exe|gif|ico|jpe?g|png|webp|woff2)$/i.test(path))return sha256(content);return sha256(Buffer.from(content).toString("utf8").replace(/\r\n/g,"\n"))}function addFinding(findings,severity,code,path,message,state){if(!findings.some(finding2=>finding2.code===code&&finding2.path===path)){findings.push({severity,code,path,message,state})}}function errorMessage2(error51){return error51 instanceof Error?error51.message:String(error51)}var MigrationPlanHashError=class extends Error{name="MigrationPlanHashError"};var MigrationSourceDivergenceError=class extends Error{name="MigrationSourceDivergenceError"};var MigrationCollisionError=class extends Error{name="MigrationCollisionError"};async function planV1ToV2Migration(filesystem,options={}){const fingerprint=await fingerprintV1Source(filesystem);const manifestFile=fingerprint.files.find(file2=>file2.path===".agents/manifest.yaml");if(manifestFile===void 0)throw new Error("V1 manifest is required for migration");const manifest=asRecord2(parseYaml(await filesystem.readText(manifestFile.path)),"manifest");if(manifest.schema_version!==1)throw new Error("Only a schema_version 1 manifest is supported");const promotions=[...options.promotions??[]].sort((left,right)=>left.legacy_spec_id.localeCompare(right.legacy_spec_id));assertPromotionMappings(promotions);const promotedSpecIds=new Map(promotions.map(promotion=>[promotion.legacy_spec_id,promotion.delivery_spec_id]));const findings=[];const operations=[];const changes=await loadMarkdownDocuments(filesystem,fingerprint,".agents/changes/","/proposal.md");const tasks=await loadMarkdownDocuments(filesystem,fingerprint,".agents/tasks/",".md");const capabilities=await loadMarkdownDocuments(filesystem,fingerprint,".agents/specs/capabilities/","/spec.md");const decisions=await loadMarkdownDocuments(filesystem,fingerprint,".agents/decisions/",".md");assertPromotionAuthorizations(promotions,decisions);const evidence=await loadBinarySources(filesystem,fingerprint,".agents/evidence/",".md");const runs=await loadMarkdownDocuments(filesystem,fingerprint,".agents/runs/",".md");const telemetryRunSources=await loadJsonLineSources(filesystem,fingerprint,".agents/telemetry/","runs.jsonl");const telemetryCycleSources=await loadJsonLineSources(filesystem,fingerprint,".agents/telemetry/","cycles.jsonl");const taskIdsByChange=new Map;const changeByTaskId=new Map;const specByTaskId=new Map;for(const task of tasks){const taskId=requiredString2(task.metadata.id,`${task.path}:id`);const changeId=requiredString2(task.metadata.change,`${task.path}:change`);taskIdsByChange.set(changeId,[...taskIdsByChange.get(changeId)??[],taskId].sort());changeByTaskId.set(taskId,changeId);specByTaskId.set(taskId,typeof task.metadata.spec==="string"&&task.metadata.spec.startsWith("SPEC-")?task.metadata.spec:null)}const changeIds=new Set(changes.map(change=>requiredString2(change.metadata.id,change.path)).filter(changeId=>(taskIdsByChange.get(changeId)?.length??0)>0));const runIdsByTask=new Map;for(const run of runs){const taskId=typeof run.metadata.task==="string"?run.metadata.task:null;const runId=typeof run.metadata.id==="string"?run.metadata.id:null;if(taskId!==null&&runId!==null){runIdsByTask.set(taskId,[...runIdsByTask.get(taskId)??[],runId].sort())}}const migrationTimestamp=sourceTimestamp([...changes,...tasks]);const date5=migrationTimestamp.slice(0,16).replace(/[-T:]/g,"-");const suffix=fingerprint.sha256.slice(0,8).toUpperCase();const migrationId=`MIG-${suffix}`;const migrationExecutionId=`EXEC-${date5}-MIGRATE-V1-V2-${suffix}`;const migrationTaskId=`TASK-${date5}-MIGRATE-V1-V2-${suffix}`;const migrationChangeId=`CHG-${date5}-MIGRATE-V1-V2-${suffix}`;const migrationRunId=`RUN-${date5}-MIGRATE-V1-V2-${suffix}`;let convertedChangeCount=0;for(const change of changes){const id=requiredString2(change.metadata.id,`${change.path}:id`);const taskIds=taskIdsByChange.get(id)??[];if(taskIds.length===0){findings.push({severity:"warning",code:"change-without-task-archived",path:change.path,message:`${id} has no Task and will remain legacy evidence.`});continue}const requirements=legacyIds(change.metadata.requirements,"REQ",change.sha256);const acceptanceIds=acceptanceIdsFor(requirements,change.sha256);const status=workStatus(change.metadata.status);const createdAt=timestamp10(change.metadata.created_at,migrationTimestamp);const updatedAt=timestamp10(change.metadata.updated_at,createdAt);const terminal=["completed","failed","cancelled"].includes(status);const promotedChangeSpecs=stringArray(change.metadata.capabilities).map(legacyId=>promotedSpecIds.get(legacyId)).filter(id2=>id2!==void 0).sort();if(promotedChangeSpecs.length>1){findings.push({severity:"warning",code:"multiple-promoted-specs-on-change",path:change.path,message:`Change references multiple promoted Specs; ${promotedChangeSpecs[0]} is the canonical source.`})}const source=promotedChangeSpecs[0]===void 0?{type:"task",task_id:taskIds[0]}:{type:"spec",spec_id:promotedChangeSpecs[0]};const startedAt=["executing","verifying","completed","failed"].includes(status)?timestamp10(change.metadata.started_at,createdAt):null;const converted={schema_version:2,id,revision:1,title:stringOr(change.metadata.title,id),status,risk:risk(change.metadata.risk),source,requirement_ids:requirements,acceptance_ids:acceptanceIds,requirement_impact:{type:"none",reason:"Migrated from V1 without semantic promotion."},task_ids:taskIds,plan_revision:1,plan_hash:change.sha256,created_at:createdAt,updated_at:updatedAt,started_at:startedAt,finished_at:terminal?timestamp10(change.metadata.completed_at??change.metadata.finished_at,updatedAt):null,result:terminal?"Migrated from the terminal V1 Change record.":null};operations.push(textOperation("convert","change",change.path,change.sha256,v2EntityPath2("changes",id,"change.md"),serializeMarkdown({metadata:converted,body:provenanceBody(change.body,change.path,change.sha256)})));convertedChangeCount+=1}const convertibleTaskIds=new Set(tasks.filter(task=>changeIds.has(requiredString2(task.metadata.change,`${task.path}:change`))).map(task=>requiredString2(task.metadata.id,`${task.path}:id`)));const convertedTaskIds=new Set;for(const task of tasks){const id=requiredString2(task.metadata.id,`${task.path}:id`);const changeId=requiredString2(task.metadata.change,`${task.path}:change`);if(!changeIds.has(changeId)){findings.push({severity:"warning",code:"task-without-change-archived",path:task.path,message:`${id} has no converted Change and will remain legacy evidence.`});continue}const requirements=legacyIds(task.metadata.requirements,"REQ",task.sha256);const status=workStatus(task.metadata.status);const createdAt=timestamp10(task.metadata.created_at,migrationTimestamp);const terminal=["completed","failed","cancelled"].includes(status);const changedFiles=changedFilesFromLegacyTask(task.body);const legacyDependencies=legacyIds(task.metadata.depends_on,"TASK",task.sha256,true);const dependencies=legacyDependencies.filter(dependency=>convertibleTaskIds.has(dependency));if(dependencies.length!==legacyDependencies.length){findings.push({severity:"warning",code:"missing-task-dependency-removed",path:task.path,message:`${id} referenced a Task dependency that cannot be converted.`})}const converted={schema_version:2,id,revision:1,change_id:changeId,title:stringOr(task.metadata.title,id),short_name:stringOr(task.metadata.short_name,"legacy-task"),objective:bodySection(task.body,"Objetivo")||stringOr(task.metadata.title,id),status,risk:risk(task.metadata.risk),priority:priority(task.metadata.priority),owner:typeof task.metadata.owner==="string"&&task.metadata.owner.length>0?task.metadata.owner:null,requirement_ids:requirements,acceptance_ids:acceptanceIdsFor(requirements,task.sha256),depends_on:dependencies,write_scopes:changedFiles,plan_revision:1,plan_hash:task.sha256,created_at:createdAt,updated_at:timestamp10(task.metadata.finished_at??task.metadata.started_at,createdAt),started_at:["executing","verifying","completed","failed"].includes(status)?timestamp10(task.metadata.started_at,createdAt):null,finished_at:terminal?timestamp10(task.metadata.finished_at,createdAt):null,result:terminal?{summary:"Migrated from the terminal V1 Task record.",changed_files:changedFiles,evidence_ids:[`EVD-LEGACY-${task.sha256.slice(0,12).toUpperCase()}`],completed_run_id:runIdsByTask.get(id)?.[0]??migrationRunId}:null};operations.push(textOperation("convert","task",task.path,task.sha256,v2EntityPath2("tasks",id,`${id}.md`),serializeMarkdown({metadata:converted,body:provenanceBody(task.body,task.path,task.sha256)})));convertedTaskIds.add(id)}let convertedDecisions=0;for(const decision of decisions){const id=requiredString2(decision.metadata.id,`${decision.path}:id`);const directChange=typeof decision.metadata.change==="string"?decision.metadata.change:null;const taskId=typeof decision.metadata.task==="string"?decision.metadata.task:null;const changeId=directChange!==null&&changeIds.has(directChange)?directChange:taskId===null?null:changeByTaskId.get(taskId)??null;if(changeId===null||!changeIds.has(changeId)){findings.push({severity:"warning",code:"orphan-decision-archived",path:decision.path,message:`${id} has no resolvable Change and will remain only as legacy evidence.`});continue}const origin=decision.metadata.origin==="human"?"human":"agent";const createdAt=timestamp10(decision.metadata.created_at,migrationTimestamp);if(origin==="human"&&nullableTimestamp(decision.metadata.confirmed_at)===null){findings.push({severity:"warning",code:"unconfirmed-human-decision-archived",path:decision.path,message:`${id} has no explicit confirmation provenance and will remain legacy evidence.`});continue}const converted={schema_version:2,id,title:stringOr(decision.metadata.title,id),scope_type:"change",scope_id:changeId,origin,category:decisionCategory(decision.metadata.category),context:stringOr(decision.metadata.context,"Context preserved from the V1 Decision."),decision:stringOr(decision.metadata.decision,decision.body.trim()||"See the preserved V1 Decision body."),reason:stringOr(decision.metadata.reason,"Reason preserved in the V1 provenance."),alternatives:stringArray(decision.metadata.alternatives),consequences:stringArray(decision.metadata.consequences),reversible:decision.metadata.reversible===true,rollback:stringOr(decision.metadata.rollback,"Restore the V1 source from the migration journal backup."),confidence:origin==="human"?null:typeof decision.metadata.confidence==="number"?decision.metadata.confidence:.5,created_at:createdAt,confirmed_at:nullableTimestamp(decision.metadata.confirmed_at)};const target=`${v2EntityDirectory("changes",changeId)}/${changeId}/decisions/${id}.md`;operations.push(textOperation("convert","decision",decision.path,decision.sha256,target,serializeMarkdown({metadata:converted,body:decisionProvenanceBody(decision.body,decision.metadata,decision.path,decision.sha256)})));convertedDecisions+=1}let relocatedEvidence=0;for(const artifact of evidence){const taskId=artifact.path.match(/\/((?:TASK)-[^/]+)\.md$/)?.[1]??null;const changeId=taskId===null?null:changeByTaskId.get(taskId)??null;if(taskId===null||!convertedTaskIds.has(taskId)||changeId===null||!changeIds.has(changeId)){findings.push({severity:"warning",code:"orphan-evidence-archived",path:artifact.path,message:"Evidence filename does not resolve through Task to a migrated Change."});continue}operations.push(bytesOperation("convert","evidence",artifact.path,artifact.sha256,`${v2EntityDirectory("changes",changeId)}/${changeId}/artifacts/evidence/${taskId}.md`,artifact.bytes));relocatedEvidence+=1}const telemetryRuns=telemetryRunSources.flatMap(source=>source.rows.map(row=>({...row,source_path:source.path})));const telemetryCycles=telemetryCycleSources.flatMap(source=>source.rows.map(row=>({...row,source_path:source.path})));const consumedTelemetryPaths=new Set;let convertedRuns=0;let usageRecords=0;for(const run of runs){const id=requiredString2(run.metadata.id,`${run.path}:id`);const taskId=typeof run.metadata.task==="string"&&run.metadata.task.startsWith("TASK-")?run.metadata.task:null;const changeId=taskId===null?null:changeByTaskId.get(taskId)??null;if(taskId===null||!convertedTaskIds.has(taskId)||changeId===null||!changeIds.has(changeId)){findings.push({severity:"warning",code:"orphan-run-archived",path:run.path,message:`${id} cannot be attributed to a migrated Task and Change.`});continue}const aggregateCandidates=telemetryRuns.filter(row=>row.run_id===id).sort((left,right)=>stringOr(left.recorded_at,"").localeCompare(stringOr(right.recorded_at,"")));const aggregate=aggregateCandidates.at(-1)??null;const cycles=telemetryCycles.filter(row=>row.run_id===id).sort((left,right)=>numberOr(left.cycle_index,0)-numberOr(right.cycle_index,0)||stringOr(left.timestamp,"").localeCompare(stringOr(right.timestamp,"")));const startedAt=timestamp10(run.metadata.started_at,migrationTimestamp);const provider=nullableString2(aggregate?.provider??run.metadata.provider);const model=stringOr(aggregate?.model??run.metadata.model,"legacy-unknown");const client=stringOr(aggregate?.client??run.metadata.client,"legacy");const agent=stringOr(aggregate?.agent??run.metadata.agent,"legacy");const records=[{schema_version:2,event_id:runEventId(id,1),run_id:id,sequence:1,occurred_at:startedAt,type:"run.started",phase:"execution",entrypoint:"task",work_type:"new",storage_mode:"tracked_sanitized",attribution_status:"legacy_unattributed",client,agent,provider,model,conversation_id:`CONV-LEGACY-${sha2562(id).slice(0,24).toUpperCase()}`,execution_id:null,task_id:taskId,spec_id:specByTaskId.get(taskId)===null?null:promotedSpecIds.get(specByTaskId.get(taskId))??null,prd_id:null,change_id:changeId,parent_run_id:null,continuation_of_run_id:null,retry_of_run_id:null}];const selectedUsage=cycles.length>0?cycles.map((cycle,index)=>({usage:cycle.token_usage,cost:cycle.estimated_cost,occurredAt:timestamp10(cycle.timestamp,startedAt),provider:nullableString2(cycle.provider)??provider,model:nullableString2(cycle.model)??model,activityKind:"legacy_cycle",sourceKey:`${stringOr(cycle.source_segment_key,`legacy:${id}`)}#cycle-${numberOr(cycle.cycle_index,index+1)}-${sha2562(JSON.stringify(cycle)).slice(0,8)}`,sourcePath:requiredString2(cycle.source_path,"cycle source path")})):aggregate!==null?[{usage:aggregate.token_usage,cost:aggregate.estimated_cost,occurredAt:timestamp10(aggregate.finished_at??aggregate.recorded_at,startedAt),provider,model,activityKind:"legacy_run_aggregate",sourceKey:stringOr(aggregate.source_segment_key,`legacy:${id}:aggregate`),sourcePath:requiredString2(aggregate.source_path,"run telemetry source path")}]:run.metadata.token_usage!==void 0?[{usage:run.metadata.token_usage,cost:run.metadata.cost,occurredAt:timestamp10(run.metadata.finished_at,startedAt),provider,model,activityKind:"legacy_markdown_run",sourceKey:`legacy:${id}:markdown`,sourcePath:run.path}]:[];for(const selected of selectedUsage){consumedTelemetryPaths.add(selected.sourcePath);const sequence=records.length+1;records.push({schema_version:2,event_id:runEventId(id,sequence),run_id:id,sequence,occurred_at:selected.occurredAt,type:"usage.recorded",phase:"execution",activity_kind:selected.activityKind,classification_source:"legacy_inferred",tokens:legacyTokenUsage(selected.usage),cost:legacyCost(selected.cost),provider:selected.provider,model:selected.model,source_segment_key:selected.sourceKey,supersedes_event_id:null});usageRecords+=1}const status=run.metadata.status;if(status==="completed"||status==="failed"||status==="cancelled"){const sequence=records.length+1;records.push({schema_version:2,event_id:runEventId(id,sequence),run_id:id,sequence,occurred_at:timestamp10(run.metadata.finished_at,startedAt),type:"run.finished",phase:"execution",status})}operations.push(textOperation("convert","run",run.path,run.sha256,v2EntityPath2("runs",id,`${id}.jsonl`),`${records.map(record3=>JSON.stringify(record3)).join("\n")}
|
|
1562
1562
|
`));convertedRuns+=1}const executionDirectory=v2EntityDirectory("executions",migrationExecutionId);if(changeIds.has(migrationChangeId)||tasks.some(task=>task.metadata.id===migrationTaskId)||runs.some(run=>run.metadata.id===migrationRunId)){throw new Error("Deterministic migration entity id collides with a V1 entity")}const migrationRequirementId="REQ-ZAIP-MIGRATION-001";const migrationAcceptanceId="AC-ZAIP-MIGRATION-001";const migrationChange={schema_version:2,id:migrationChangeId,revision:1,title:`Migrate ZAIP-AIOS V1 state with ${migrationId}`,status:"completed",risk:"critical",source:{type:"task",task_id:migrationTaskId},requirement_ids:[migrationRequirementId],acceptance_ids:[migrationAcceptanceId],requirement_impact:{type:"none",reason:"Migration preserves existing V1 truth."},task_ids:[migrationTaskId],plan_revision:1,plan_hash:fingerprint.sha256,created_at:migrationTimestamp,updated_at:migrationTimestamp,started_at:migrationTimestamp,finished_at:migrationTimestamp,result:`Applied ${migrationId}.`};const migrationTask={schema_version:2,id:migrationTaskId,revision:1,change_id:migrationChangeId,title:`Apply migration ${migrationId}`,short_name:"migrate-v1-v2",objective:"Apply the signed V1 to V2 migration plan and preserve rollback evidence.",status:"completed",risk:"critical",priority:"urgent",owner:"zaip-migrator",requirement_ids:[migrationRequirementId],acceptance_ids:[migrationAcceptanceId],depends_on:[],write_scopes:[".agents/**",".local/migrations/**"],plan_revision:1,plan_hash:fingerprint.sha256,created_at:migrationTimestamp,updated_at:migrationTimestamp,started_at:migrationTimestamp,finished_at:migrationTimestamp,result:{summary:`Applied ${migrationId} with verified backup and journal.`,changed_files:[],evidence_ids:[`EVD-${migrationId}`],completed_run_id:migrationRunId}};const execution={schema_version:2,id:migrationExecutionId,revision:1,origin:{type:"task",task_id:migrationTaskId},status:"completed",plan_revision:1,plan_hash:fingerprint.sha256,policy:{failure_policy:"stop_on_terminal_failure",max_parallelism:1,max_operational_retries:0,max_repair_cycles_per_task:0},dag:{nodes:[{task_id:migrationTaskId,change_id:migrationChangeId,depends_on:[]}],topological_order:[migrationTaskId]},created_at:migrationTimestamp,updated_at:migrationTimestamp,started_at:migrationTimestamp,finished_at:migrationTimestamp,result:`Applied ${migrationId}.`};const migrationRunRecords=[{schema_version:2,event_id:runEventId(migrationRunId,1),run_id:migrationRunId,sequence:1,occurred_at:migrationTimestamp,type:"run.started",attribution_status:"attributed",phase:"execution",entrypoint:"task",work_type:"new",storage_mode:"tracked_sanitized",client:"zaip-cli",agent:"zaip-migrator",provider:null,model:"zaip-migrator-v2",conversation_id:`CONV-${date5}-MIGRATE-V1-V2-${suffix}`,execution_id:migrationExecutionId,task_id:migrationTaskId,spec_id:null,prd_id:null,change_id:migrationChangeId,parent_run_id:null,continuation_of_run_id:null,retry_of_run_id:null},{schema_version:2,event_id:runEventId(migrationRunId,2),run_id:migrationRunId,sequence:2,occurred_at:migrationTimestamp,type:"run.finished",phase:"execution",status:"completed"}];operations.push(textOperation("convert","change",null,null,v2EntityPath2("changes",migrationChangeId,"change.md"),serializeMarkdown({metadata:migrationChange,body:`# Migration ${migrationId}
|
|
1563
1563
|
|
|
1564
1564
|
The signed migration plan created this Change as its own auditable delivery envelope.`})),textOperation("convert","task",null,null,v2EntityPath2("tasks",migrationTaskId,`${migrationTaskId}.md`),serializeMarkdown({metadata:migrationTask,body:`# Apply migration ${migrationId}
|
|
@@ -1598,7 +1598,7 @@ ${await context.filesystem.readText(path)}`)}const resolved=candidates.find(docu
|
|
|
1598
1598
|
`;await filesystem.writeTextExclusive(path,participantText);try{const participants=await bakeryParticipants(filesystem);const ticket=Math.max(0,...participants.map(entry=>entry.ticket))+1;participantText=`${JSON.stringify({...owner,choosing:false,ticket})}
|
|
1599
1599
|
`;await filesystem.writeTextAtomic(path,participantText);while(true){const others=await bakeryParticipants(filesystem);const blocked=others.some(entry=>entry.owner_nonce!==owner.owner_nonce&&(entry.choosing||entry.ticket>0&&(entry.ticket<ticket||entry.ticket===ticket&&entry.owner_nonce<owner.owner_nonce)));if(!blocked)break;if(Date.now()>=deadline)throw new Error(`Telemetry compaction bakery lock remained held: ${COMPACTION_LOCK_ROOT}. Verify participant files before manual removal.`);await delay5(COMPACTION_LOCK_WAIT_MS)}return await operation()}finally{await releaseCompactionParticipant(filesystem,path,participantText)}}async function bakeryParticipants(filesystem){const paths=await filesystem.listFiles(COMPACTION_LOCK_ROOT,".json");const values=[];for(const path of paths){const text=await readCompactionParticipant(filesystem,path);if(text===null)continue;try{const value=JSON.parse(text);if(isCompactionParticipant(value,path))values.push(value);else values.push(invalidParticipant(path))}catch{values.push(invalidParticipant(path))}}return values}async function readCompactionParticipant(filesystem,path){for(let attempt=0;attempt<2;attempt+=1){try{return await filesystem.readText(path)}catch(error51){if(isNodeError9(error51)&&error51.code==="ENOENT")return null;if(isConcurrentParticipantRemoval(error51))return null;if(isNodeError9(error51)&&error51.code==="EPERM"&&attempt===0){await delay5(COMPACTION_LOCK_WAIT_MS);if(!await filesystem.exists(path))return null;continue}throw error51}}return null}function isConcurrentParticipantRemoval(error51){return error51 instanceof WorkspacePathError&&isNodeError9(error51.cause)&&error51.cause.code==="ENOENT"}function isCompactionParticipant(value,path){if(typeof value!=="object"||value===null)return false;const participant=value;return participant.schema_version===1&&participant.purpose==="telemetry-compaction"&&Number.isSafeInteger(participant.pid)&&participant.pid>=1&&typeof participant.owner_nonce==="string"&&participant.owner_nonce.length>0&&participant.path===path&&participant.path===`${COMPACTION_LOCK_ROOT}/${participant.owner_nonce}.json`&&typeof participant.acquired_at==="string"&&!Number.isNaN(Date.parse(participant.acquired_at))&&typeof participant.choosing==="boolean"&&Number.isSafeInteger(participant.ticket)&&participant.ticket>=0}function invalidParticipant(path){return{...compactionLock(`invalid-${path}`,path),choosing:true,ticket:1}}async function releaseCompactionParticipant(filesystem,path,expected){try{if(await filesystem.readText(path)!==expected)return}catch(error51){if(isNodeError9(error51)&&error51.code==="ENOENT")return;throw error51}await filesystem.removeFile(path)}function compactionLock(owner_nonce,path){return{schema_version:1,purpose:"telemetry-compaction",pid:process.pid,owner_nonce,path,acquired_at:new Date().toISOString()}}async function resolveWriterId(filesystem){const existing=workspaceWriterIds.get(filesystem.root);if(existing!==void 0)return existing;const created=(async()=>{const path=".local/telemetry-writer-id.json";const writerId=`writer-${randomUUID4()}`;try{await filesystem.writeTextAtomicExclusive(path,`${JSON.stringify({schema_version:1,writer_id:writerId})}
|
|
1600
1600
|
`);return writerId}catch(error51){if(!isNodeError9(error51)||error51.code!=="EEXIST")throw error51;const marker=JSON.parse(await filesystem.readText(path));if(typeof marker!=="object"||marker===null||!("writer_id"in marker)||typeof marker.writer_id!=="string"||!/^writer-[0-9a-f-]{36}$/.test(marker.writer_id)){throw new Error("Invalid local telemetry writer marker")}return marker.writer_id}})();workspaceWriterIds.set(filesystem.root,created);try{return await created}catch(error51){if(workspaceWriterIds.get(filesystem.root)===created)workspaceWriterIds.delete(filesystem.root);throw error51}}function isNodeError9(error51){return typeof error51==="object"&&error51!==null&&"code"in error51}function unique(values){return[...new Set(values)].sort()}function digest4(value){return createHash26("sha256").update(value).digest("hex")}async function delay5(milliseconds){await new Promise(resolveDelay=>setTimeout(resolveDelay,milliseconds))}import{createHash as createHash27}from"node:crypto";function isCodexTelemetryClient(client){return["codex","codex-desktop","codex-subagent"].includes(client)}function telemetrySourceThreadId(current,allRuns){const runsById=new Map(allRuns.map(fold=>[fold.run.run_id,fold]));let run=current.run;const visited=new Set;while(run.parent_run_id!==null&&!visited.has(run.run_id)){visited.add(run.run_id);const parent=runsById.get(run.parent_run_id);if(parent===void 0)break;run=parent.run}return run.client_thread_id??current.run.client_thread_id??null}function telemetrySource(current,allRuns){const rootThreadId=telemetrySourceThreadId(current,allRuns);if(current.run.client==="codex-subagent"){return{agentPath:current.run.client_thread_id??null,parentThreadId:null,threadId:null,turnId:current.run.client_turn_id??null}}return{agentPath:null,parentThreadId:null,threadId:rootThreadId,turnId:current.run.client_turn_id??null}}async function recordUnavailableCodexTelemetryToSpool(current,filesystem,status,capturedAt=new Date().toISOString()){if(!isCodexTelemetryClient(current.run.client))return null;const correlation=codexTelemetryCorrelationFromRun(current.run);if(correlation===null)return null;return appendCodexTelemetrySpoolEvent(filesystem,{correlation,event_kind:"terminal",source:"unavailable",source_event_key:`run:${current.run.run_id}:terminal:unavailable`,source_occurred_at:null,captured_at:capturedAt,coverage:"unavailable",tokens:{input:null,cached_input:null,output:null,reasoning:null,total:null,source:"unavailable"},provider:null,model:null,runtime:{reasoning_effort:null,service_tier:null},status,latency_ms:null,context_stats:null,discarded_counts:{prompt:0,response_text:0,reasoning:0,secrets:0}})}function sumObservedUsage(values){const observed=values.filter(value=>value!==null);const sum=component=>{let total=0;for(const usage of observed){const value=usage[component];if(value===null)return null;total+=value}return total};return{input:sum("input"),cached_input:sum("cached_input"),output:sum("output"),reasoning:sum("reasoning"),total:sum("total"),source:"provider_reported"}}function commonObservedValue(values){const observed=[...new Set(values.filter(value=>value!==null))];return observed.length===1?observed[0]??null:null}function latestSourceTimestamp(events){return events.map(event=>event.event.source_occurred_at).filter(value=>value!==null).sort().at(-1)??null}function modelCallId(sourceCallKey){return`MCALL-${digest5(sourceCallKey)}`}function providerInvocationId(sourceCallKey){return`INV-CODEX-${digest5(sourceCallKey)}`}function elapsedMilliseconds(startedAt,finishedAt){const started=Date.parse(startedAt??"");const finished=Date.parse(finishedAt??"");return Number.isFinite(started)&&Number.isFinite(finished)?Math.max(0,finished-started):null}function hasObservedUsage(current){return current.effective_usage_records.some(record3=>record3.tokens.source!=="unavailable")}function unavailableUsageEventId(current){return current.effective_usage_records.findLast(record3=>record3.tokens.source==="unavailable")?.event_id??null}function observedUsageDelta(cumulative,previous){const previousTotal=component=>{let total=0;for(const usage of previous){const value=usage[component];if(value===null)return null;total+=value}return total};const delta=component=>{const observed=cumulative[component];if(observed===null)return null;const attributed=previousTotal(component);return attributed===null?null:Math.max(0,observed-attributed)};return{input:delta("input"),cached_input:delta("cached_input"),output:delta("output"),reasoning:delta("reasoning"),total:delta("total"),source:cumulative.source}}function latestPhase(current){const latest=current.records.findLast(record3=>"phase"in record3);return latest?.phase??"conversation"}function digest5(sourceCallKey){return createHash27("sha256").update(sourceCallKey).digest("hex").slice(0,32)}function shouldAppendFallbackModelCall(records,sourceCallKey){const callId=modelCallId(sourceCallKey);return!records.some(record3=>record3.source_call_key===sourceCallKey||record3.call_id===callId)}function fallbackCallIdentity(sourceCallKey){return[sourceCallKey,modelCallId(sourceCallKey)]}async function recordCodexTelemetryIfAvailable(current,composition,filesystem,sourceOverride=null,appServerNotifications=[],fallbackSegmentFinder=findLatestCodexSegment){if(!isCodexTelemetryClient(current.run.client)||current.run.client_thread_id===null&¤t.run.client_turn_id===null){return current}return composition.runs.withUsageAttributionLock(async()=>{const freshCurrent=await composition.runs.read(current.run.run_id);if(appServerNotifications.length>0){await ingestCodexAppServerNotifications(filesystem,appServerNotifications)}if(freshCurrent.finished!==null){return freshCurrent}const allRuns=await composition.runs.list();const nativeEvents=(await listCodexTelemetrySpoolEvents(filesystem)).filter(event=>event.event.source==="codex_app_server"&&event.event.correlation.run_id===freshCurrent.run.run_id);if(nativeEvents.some(event=>["response_completed","usage_updated","error","turn_completed"].includes(event.event.stream_boundary??""))){const recorded=await recordNativeCodexUsage(freshCurrent,composition,nativeEvents);await compactPendingCodexTelemetry(filesystem);return recorded}if(hasObservedUsage(freshCurrent))return freshCurrent;const source=sourceOverride??telemetrySource(freshCurrent,allRuns);const exactTurn=source.turnId;if(exactTurn===null)return freshCurrent;const existingSegmentKeys=new Set(allRuns.flatMap(fold=>fold.effective_usage_records.flatMap(record3=>record3.source_segment_key?[record3.source_segment_key]:[])));const candidate=await fallbackSegmentFinder(filesystem.root,exactTurn===null?existingSegmentKeys:new Set,{startedAfter:freshCurrent.run.occurred_at,agentPath:source.agentPath,parentThreadId:source.parentThreadId,threadId:source.threadId,turnId:exactTurn});const timestamp11=Date.parse(candidate?.finishedAt??candidate?.startedAt??"");if(candidate===null||!Number.isFinite(timestamp11)||!(candidate.turnId===exactTurn)){return freshCurrent}const candidateLoops=Array.from(new Map(candidate.loops.map(loop=>[`${candidate.segmentKey}:loop:${loop.cycleIndex}`,loop])).values());const existingOwner=allRuns.find(fold=>fold.run.run_id!==freshCurrent.run.run_id&&fold.effective_usage_records.some(record3=>record3.source_segment_key===candidate.segmentKey||record3.source_segment_key?.startsWith(`${candidate.segmentKey}@`)===true));if(existingOwner!==void 0)return freshCurrent;const model=candidate.model??freshCurrent.run.model;const provider=inferProvider(model,freshCurrent.run.provider??freshCurrent.run.client,freshCurrent.run.agent);const correlation=codexTelemetryCorrelationFromRun(freshCurrent.run);if(correlation===null)return freshCurrent;const capturedAt=new Date().toISOString();const pricing=new PricingRepository(filesystem);const catalog=await pricing.readCatalog();const fxRate=await pricing.readLatestFxRate();const spooledLoops=[];for(const loop of candidateLoops){const loopModel=loop.model??model;const loopProvider=inferProvider(loopModel,freshCurrent.run.provider??freshCurrent.run.client,freshCurrent.run.agent);const historical_cost=estimateUsageCost({provider:loopProvider,model:loopModel,usage:loop.usage,catalog,fxRate});spooledLoops.push(await appendCodexTelemetrySpoolEvent(filesystem,{correlation,event_kind:"usage",source:"codex_session_fallback",source_event_key:`${candidate.segmentKey}:loop:${loop.cycleIndex}`,source_occurred_at:loop.timestamp,captured_at:capturedAt,coverage:"partial",tokens:loop.usage,provider:loopProvider,model:loopModel,runtime:{reasoning_effort:candidate.reasoningEffort??null,service_tier:candidate.serviceTier??null},status:null,latency_ms:null,historical_cost,context_stats:null,discarded_counts:{prompt:0,response_text:0,reasoning:0,secrets:0}}))}await appendCodexTelemetrySpoolEvent(filesystem,{correlation,event_kind:"terminal",source:"codex_session_fallback",source_event_key:`${candidate.segmentKey}:terminal`,source_occurred_at:candidate.finishedAt??candidate.startedAt,captured_at:capturedAt,coverage:"partial",tokens:null,provider,model,runtime:{reasoning_effort:candidate.reasoningEffort??null,service_tier:candidate.serviceTier??null},status:"completed",latency_ms:elapsedMilliseconds(candidate.startedAt,candidate.finishedAt),context_stats:null,discarded_counts:{prompt:0,response_text:0,reasoning:0,secrets:0}});const cumulative=aggregateSegmentUsage({...candidate,loops:candidateLoops});const previous=allRuns.filter(fold=>fold.run.run_id!==freshCurrent.run.run_id&&exactTurn!==null&&fold.run.client_turn_id===exactTurn).flatMap(fold=>fold.effective_usage_records).filter(record3=>record3.source_segment_key===candidate.segmentKey||record3.source_segment_key?.startsWith(`${candidate.segmentKey}@`)===true);const tokens=observedUsageDelta(cumulative,previous.map(record3=>record3.tokens));if(tokens.input===0&&tokens.cached_input===0&&tokens.output===0&&tokens.reasoning===0&&tokens.total===0){return freshCurrent}const estimated=estimateUsageCost({provider,model,usage:tokens,catalog,fxRate});const agentInvocationId=freshCurrent.run.agent_invocation_id??`AINV-${freshCurrent.run.run_id.slice("RUN-".length)}`;let sequence=freshCurrent.records.length+1;const fallbackCallIdentities=new Set(freshCurrent.model_call_records.flatMap(record3=>[record3.source_call_key,record3.call_id].filter(value=>typeof value==="string")));for(const spooled of spooledLoops){const loop=spooled.event;if(loop.tokens===null)continue;const loopModel=loop.model??freshCurrent.run.model;const loopProvider=inferProvider(loopModel,loop.provider??freshCurrent.run.provider??freshCurrent.run.client,freshCurrent.run.agent);const loopEstimated=estimateUsageCost({provider:loopProvider,model:loopModel,usage:loop.tokens,catalog,fxRate});const sourceCallKey=loop.source_event_key;const identities=fallbackCallIdentity(sourceCallKey);if(!shouldAppendFallbackModelCall(freshCurrent.model_call_records,sourceCallKey)||identities.some(identity=>fallbackCallIdentities.has(identity))){continue}await composition.runs.appendRecord(modelCallObservedV3Schema.parse({schema_version:2,event_id:`${freshCurrent.run.run_id}:${String(sequence).padStart(6,"0")}`,run_id:freshCurrent.run.run_id,sequence:sequence++,occurred_at:new Date().toISOString(),type:"model.call.observed",call_id:modelCallId(sourceCallKey),agent_invocation_id:agentInvocationId,coverage:"partial",tokens:loop.tokens,cost:{usd:loopEstimated.estimated_usd,brl:loopEstimated.estimated_brl,fx_rate:loopEstimated.fx_rate},provider:loopProvider,model:loopModel,source_call_key:sourceCallKey,...loop.source_occurred_at===null?{}:{source_occurred_at:loop.source_occurred_at},runtime:loop.runtime}));for(const identity of identities)fallbackCallIdentities.add(identity)}const usage=usageRecordedV2Schema.parse({schema_version:2,event_id:`${freshCurrent.run.run_id}:${String(sequence).padStart(6,"0")}`,run_id:freshCurrent.run.run_id,sequence,occurred_at:new Date().toISOString(),type:"usage.recorded",phase:latestPhase(freshCurrent),activity_kind:"implementation",classification_source:"current_context",tokens,cost:{usd:estimated.estimated_usd,brl:estimated.estimated_brl,fx_rate:estimated.fx_rate},provider,model,source_segment_key:candidate.segmentKey,runtime:{reasoning_effort:candidate.reasoningEffort??null,service_tier:candidate.serviceTier??null},supersedes_event_id:unavailableUsageEventId(freshCurrent),source_occurred_at:candidate.finishedAt??candidate.startedAt??void 0,source_started_at:candidate.startedAt??void 0,source_finished_at:candidate.finishedAt??void 0});await composition.runs.appendRecord(usage);await compactPendingCodexTelemetry(filesystem);return composition.runs.read(freshCurrent.run.run_id)})}async function ingestCodexAppServerNotifications(filesystem,notifications,capturedAt=new Date().toISOString()){const persisted=[];for(const notification of notifications){const event=await ingestCodexAppServerNotification(filesystem,notification,capturedAt);if(event!==null)persisted.push(event)}await compactPendingCodexTelemetry(filesystem);return persisted}async function ingestCodexAppServerNotification(filesystem,notification,capturedAt=new Date().toISOString()){const sanitized=sanitizeAppServerNotification(notification,capturedAt);if(sanitized===null)return null;const correlations=await listCodexTelemetryCorrelations(filesystem);const sameTurn=correlations.filter(item=>item.turn_id===sanitized.turnId);const candidates=sanitized.agentPath===null?rootCorrelationCandidates(sameTurn,sanitized.threadId):sameTurn.filter(item=>item.client==="codex-subagent"&&item.agent_path===sanitized.agentPath);if(candidates.length>1){throw new Error(`Ambiguous Codex app-server correlation for turn ${sanitized.turnId}`)}if(candidates[0]===void 0){await quarantineCodexAppServerNotification(filesystem,sanitized);return null}return appendCodexTelemetrySpoolEvent(filesystem,{correlation:candidates[0],...sanitized.event})}function rootCorrelationCandidates(correlations,threadId){const roots=correlations.filter(item=>item.client!=="codex-subagent");const exact=roots.filter(item=>item.thread_id===threadId);return exact.length>0?exact:roots.filter(item=>item.thread_id===null)}async function quarantineCodexAppServerNotification(filesystem,input){const digest6=hostDigest(input.event.source_event_key);const unsigned={schema_version:1,event_id:`QEVT-${digest6}`,thread_id:input.threadId,turn_id:input.turnId,agent_path:input.agentPath,event:input.event};const serialized=`${JSON.stringify({...unsigned,checksum_sha256:hostDigest(JSON.stringify(unsigned))})}
|
|
1601
|
-
`;if(Buffer.byteLength(serialized,"utf8")>64*1024)throw new Error("Unmatched Codex telemetry envelope exceeds the 64 KiB sanitized limit");try{await filesystem.writeTextAtomicExclusive(`.local/codex-telemetry-spool/v1/unmatched/${digest6.slice(0,2)}/${digest6}.json`,serialized)}catch(error51){if(!(error51 instanceof Error&&"code"in error51&&error51.code==="EEXIST"))throw error51}}function sanitizeAppServerNotification(input,capturedAt){const notification=hostObject(input,"Codex app-server notification");const method=String(notification.method);if(!["item/completed","rawResponse/completed","thread/tokenUsage/updated","error","turn/completed"].includes(method))return null;const params=hostObject(notification.params,`${method} params`);const threadId=hostString(params.threadId,`${method} threadId`);const rawAgentPath=params.agentPath??params.agent_path;const agentPath=rawAgentPath===void 0?null:hostString(rawAgentPath,`${method} agentPath`);const occurredAt=hostTimestamp(notification.emittedAtMs);const wrap=(turnId2,event)=>({threadId,turnId:turnId2,agentPath,event:{source:"codex_app_server",source_occurred_at:occurredAt,captured_at:capturedAt,coverage:"complete",provider:null,model:null,runtime:{reasoning_effort:null,service_tier:null},latency_ms:null,context_stats:null,...event}});if(method==="item/completed"){const turnId2=hostString(params.turnId,`${method} turnId`);const item=hostObject(params.item,`${method} item`);return wrap(turnId2,{event_kind:"response",source_method:method,stream_boundary:"item_completed",source_event_key:hostSourceKey(`${threadId}:${turnId2}:item:${hostString(item.id,`${method} item id`)}`,"item"),source_occurred_at:hostTimestamp(params.completedAtMs)??occurredAt,tokens:null,status:null,discarded_counts:discardedItem(String(item.type??""),item)})}if(method==="rawResponse/completed"){const turnId2=hostString(params.turnId,`${method} turnId`);return wrap(turnId2,{event_kind:"response",source_method:method,stream_boundary:"response_completed",source_event_key:hostSourceKey(`${threadId}:${turnId2}:raw-response:${hostString(params.responseId,`${method} responseId`)}`,"response"),tokens:params.usage===null?null:hostTokens(params.usage,method),status:null,discarded_counts:{...emptyDiscarded(),response_text:Number(typeof params.output==="string")}})}if(method==="thread/tokenUsage/updated"){const turnId2=hostString(params.turnId,`${method} turnId`);const tokens=hostTokens(hostObject(params.tokenUsage,`${method} tokenUsage`).total,method);const suffix=notification.emittedAtMs===void 0?hostDigest(JSON.stringify(tokens)).slice(0,24):String(notification.emittedAtMs);return wrap(turnId2,{event_kind:"usage",source_method:method,stream_boundary:"usage_updated",source_event_key:hostSourceKey(`${threadId}:${turnId2}:token-usage:${suffix}`,"usage"),tokens,status:null,discarded_counts:emptyDiscarded()})}if(method==="error"){const turnId2=hostString(params.turnId,`${method} turnId`);const error52=isHostObject(params.error)?params.error:{};const suffix=notification.emittedAtMs===void 0?hostDigest(JSON.stringify([params.willRetry===true,error52.codexErrorInfo??null])).slice(0,24):String(notification.emittedAtMs);return wrap(turnId2,{event_kind:"error",source_method:method,stream_boundary:"error",source_event_key:hostSourceKey(`${threadId}:${turnId2}:error:${suffix}`,"error"),tokens:null,status:params.willRetry===true?null:"failed",will_retry:params.willRetry===true,discarded_counts:{...emptyDiscarded(),secrets:Number(typeof error52.message==="string")+Number(typeof error52.additionalDetails==="string")}})}const turn=hostObject(params.turn,"turn/completed turn");const turnId=hostString(turn.id,"turn/completed turn id");if(!["completed","failed","interrupted"].includes(String(turn.status)))throw new Error(`turn/completed has non-terminal status: ${String(turn.status)}`);const discarded=(Array.isArray(turn.items)?turn.items.filter(isHostObject):[]).map(item=>discardedItem(String(item.type??""),item)).reduce(addDiscarded,emptyDiscarded());const error51=isHostObject(turn.error)?turn.error:{};return wrap(turnId,{event_kind:"terminal",source_method:"turn/completed",stream_boundary:"turn_completed",source_event_key:hostSourceKey(`${threadId}:${turnId}:terminal`,"terminal"),source_occurred_at:hostTimestamp(typeof turn.completedAt==="number"?turn.completedAt*1e3:turn.completedAt)??occurredAt,tokens:null,status:turn.status==="interrupted"?"cancelled":turn.status,latency_ms:Number.isSafeInteger(turn.durationMs)&&Number(turn.durationMs)>=0?Number(turn.durationMs):null,discarded_counts:{...discarded,secrets:discarded.secrets+Number(typeof error51.message==="string")+Number(typeof error51.additionalDetails==="string")}})}var emptyDiscarded=()=>({prompt:0,response_text:0,reasoning:0,secrets:0});var addDiscarded=(left,right)=>({prompt:left.prompt+right.prompt,response_text:left.response_text+right.response_text,reasoning:left.reasoning+right.reasoning,secrets:left.secrets+right.secrets});var discardedItem=(type,item)=>({prompt:Number(["userMessage","hookPrompt","function_call","custom_tool_call"].includes(type)),response_text:Number(["agentMessage","plan","message","agent_message"].includes(type)),reasoning:Number(type==="reasoning"),secrets:Number(typeof item.encrypted_content==="string")+Number(item.internal_chat_message_metadata_passthrough!==void 0)});var isHostObject=value=>typeof value==="object"&&value!==null&&!Array.isArray(value);function hostObject(value,label){if(!isHostObject(value))throw new Error(`${label} must be an object`);return value}function hostString(value,label){if(typeof value!=="string"||value.length===0)throw new Error(`${label} must be a non-empty string`);return value}function hostCount(value,label){if(!Number.isSafeInteger(value)||Number(value)<0)throw new Error(`${label} must be a non-negative safe integer`);return Number(value)}var hostTimestamp=value=>typeof value==="number"&&Number.isFinite(value)&&value>=0?new Date(value).toISOString():null;var hostDigest=value=>createHash28("sha256").update(value).digest("hex");var hostSourceKey=(value,prefix)=>value.length<=500?value:`${prefix}:${hostDigest(value)}`;function hostTokens(value,label){const usage=hostObject(value,`${label} usage`);return{input:hostCount(usage.inputTokens,`${label} inputTokens`),cached_input:hostCount(usage.cachedInputTokens,`${label} cachedInputTokens`),output:hostCount(usage.outputTokens,`${label} outputTokens`),reasoning:hostCount(usage.reasoningOutputTokens,`${label} reasoningOutputTokens`),total:hostCount(usage.totalTokens,`${label} totalTokens`),source:"provider_reported"}}function parseCodexAppServerNotificationStream(content){const normalized=content.trim();if(normalized.length===0)return[];if(normalized.startsWith("[")){const parsed=JSON.parse(normalized);if(!Array.isArray(parsed))throw new Error("Codex app-server event stream must be an array");return parsed}return normalized.split(/\r?\n/).map(line=>line.trim()).filter(Boolean).map(line=>JSON.parse(line))}async function recordNativeCodexUsage(current,composition,events){const exactCalls=events.filter(event=>event.event.stream_boundary==="response_completed"&&event.event.tokens!==null);const latestCumulative=events.findLast(event=>event.event.stream_boundary==="usage_updated"&&event.event.tokens!==null);const terminal=events.findLast(event=>event.event.stream_boundary==="turn_completed"||event.event.stream_boundary==="error"&&event.event.will_retry!==true);const usageEvents=exactCalls.length>0?exactCalls:latestCumulative?[latestCumulative]:[];if(usageEvents.length===0&&terminal===void 0)return current;let fresh=current;let sequence=current.records.length+1;const agentInvocationId=current.run.agent_invocation_id??`AINV-${current.run.run_id.slice("RUN-".length)}`;for(const call of exactCalls){const event=call.event;if(event.tokens===null)continue;const coverage2=terminal===void 0?"partial":"complete";const existing=fresh.model_call_records.find(record3=>record3.source_call_key===event.source_event_key);if(existing===void 0||existing.coverage==="partial"&&coverage2==="complete"){await composition.runs.appendRecord(modelCallObservedV3Schema.parse({schema_version:2,event_id:`${current.run.run_id}:${String(sequence).padStart(6,"0")}`,run_id:current.run.run_id,sequence:sequence++,occurred_at:event.captured_at,type:"model.call.observed",call_id:modelCallId(event.source_event_key),agent_invocation_id:agentInvocationId,coverage:coverage2,tokens:event.tokens,cost:{usd:null,brl:null},provider:event.provider,model:event.model,source_call_key:event.source_event_key,...event.source_occurred_at===null?{}:{source_occurred_at:event.source_occurred_at},runtime:event.runtime}));fresh=await composition.runs.read(current.run.run_id)}}const sourceSegmentKey=`codex-app-server:${current.run.run_id}`;if(usageEvents.length>0&&!fresh.effective_usage_records.some(record3=>record3.source_segment_key===sourceSegmentKey)){const tokens=sumObservedUsage(usageEvents.map(event=>event.event.tokens));await composition.runs.appendRecord(usageRecordedV2Schema.parse({schema_version:2,event_id:`${current.run.run_id}:${String(sequence).padStart(6,"0")}`,run_id:current.run.run_id,sequence:sequence++,occurred_at:new Date().toISOString(),type:"usage.recorded",phase:latestPhase(current),activity_kind:"implementation",classification_source:"current_context",tokens,cost:{usd:null,brl:null},provider:commonObservedValue(usageEvents.map(event=>event.event.provider)),model:commonObservedValue(usageEvents.map(event=>event.event.model)),source_segment_key:sourceSegmentKey,runtime:{reasoning_effort:commonObservedValue(usageEvents.map(event=>event.event.runtime.reasoning_effort)),service_tier:commonObservedValue(usageEvents.map(event=>event.event.runtime.service_tier))},supersedes_event_id:unavailableUsageEventId(current),...latestSourceTimestamp(usageEvents)===null?{}:{source_occurred_at:latestSourceTimestamp(usageEvents)}}));fresh=await composition.runs.read(current.run.run_id)}if(terminal===void 0||terminal.event.status===null)return fresh;const callKeys=exactCalls.length>0?exactCalls.map(call=>call.event.source_event_key):[terminal.event.source_event_key];for(const callKey of callKeys){const invocationId2=providerInvocationId(callKey);if(!fresh.model_selection_records.some(record3=>record3.invocation_id===invocationId2)){await composition.runs.appendRecord(modelSelectionRecordedV2Schema.parse({schema_version:2,event_id:`${current.run.run_id}:${String(sequence).padStart(6,"0")}`,run_id:current.run.run_id,sequence:sequence++,occurred_at:terminal.event.captured_at,type:"model.selection.recorded",invocation_id:invocationId2,requested:{model:current.run.model,reasoning_effort:current.run.reasoning_effort??null,velocity:"standard"},selection:{source:"execution-override",policy_version:1,reasons:["host-run-header"]}}));fresh=await composition.runs.read(current.run.run_id)}if(!fresh.provider_invocation_records.some(record3=>record3.invocation_id===invocationId2)){await composition.runs.appendRecord(providerInvocationFinishedV2Schema.parse({schema_version:2,event_id:`${current.run.run_id}:${String(sequence).padStart(6,"0")}`,run_id:current.run.run_id,sequence:sequence++,occurred_at:terminal.event.captured_at,type:"provider.invocation.finished",invocation_id:invocationId2,status:terminal.event.status,effective:{provider:terminal.event.provider,model:terminal.event.model,reasoning_effort:terminal.event.runtime.reasoning_effort,service_tier:terminal.event.runtime.service_tier},latency_ms:terminal.event.latency_ms}));fresh=await composition.runs.read(current.run.run_id)}}return fresh}async function resolveRunClientInvocation(filesystem,client,options={}){if(!new Set(["codex","codex-desktop"]).has(client)){return{clientThreadId:null,clientTurnId:null,userMessage:null,observedModel:null,observedReasoningEffort:null,observedServiceTier:null}}const threadId=normalizedId(options.threadId??process.env.CODEX_THREAD_ID);const turnId=normalizedId(options.turnId??process.env.CODEX_TURN_ID);const active=await findActiveCodexInvocation(filesystem.root,{threadId,...options.sessionsRoot===void 0?{}:{sessionsRoot:options.sessionsRoot},...options.now===void 0?{}:{now:options.now}});return{clientThreadId:threadId??active?.sessionId??null,clientTurnId:turnId??active?.turnId??null,userMessage:active?.userMessage??null,observedModel:active?.model??null,observedReasoningEffort:active?.reasoningEffort??null,observedServiceTier:active?.serviceTier??null}}function normalizedId(value){const normalized=value?.trim();return normalized===void 0||normalized.length===0?null:normalized}function activeDescendantRuns(rootRunId,candidates){return descendantRuns(rootRunId,candidates).filter(candidate=>candidate.finished===null)}function descendantRuns(rootRunId,candidates){const descendants=[];const parentIds=new Set([rootRunId]);let discovered=true;while(discovered){discovered=false;for(const candidate of candidates){if(candidate.run.parent_run_id!==null&&parentIds.has(candidate.run.parent_run_id)&&!parentIds.has(candidate.run.run_id)){parentIds.add(candidate.run.run_id);descendants.push(candidate);discovered=true}}}return descendants}function finalizationBarrierBlockReason(barrier){if(barrier.required&&barrier.status==="evidence_missing"){return"Finalization barrier evidence_missing; resume after passed typed Evidence linked to the same Task, Change, Execution, and Run"}return barrier.required&&!barrier.satisfied?`Finalization barrier ${barrier.status}; resume after a completed zaip-agent-finalizer Sub-Run with authoritative metadata`:null}function assessRunFinalizationBarrier(parent,candidates,evidenceSatisfied=false){const required2=runV2RequiresFinalizer(parent.run)||descendantRuns(parent.run.run_id,candidates).length>0;const evidenceRequired=parent.run.execution_kind==="delivery";if(!required2){return{required:false,evidence_required:false,evidence_satisfied:true,status:"not_required",finalizer_run_id:null,satisfied:true}}const finalizer=directFinalizers(parent.run.run_id,candidates).at(-1);if(finalizer===void 0){return{required:true,evidence_required:evidenceRequired,evidence_satisfied:!evidenceRequired||evidenceSatisfied,status:"missing",finalizer_run_id:null,satisfied:false}}const evidenceAccepted=!evidenceRequired||evidenceSatisfied;const status=finalizer.status==="completed"&&!evidenceAccepted?"evidence_missing":finalizer.status;return{required:true,evidence_required:evidenceRequired,evidence_satisfied:evidenceAccepted,status,finalizer_run_id:finalizer.run.run_id,satisfied:status==="completed"&&evidenceAccepted}}function assertChildRunMayStart(parent,purpose,agent,candidates,executionEligibility=[],options={}){if(parent.finished!==null)throw new Error(`Parent Run is already finished: ${parent.run.run_id}`);const crossedBarrier=ancestorLineage(parent,candidates).find(ancestor=>directFinalizers(ancestor.run.run_id,candidates).length>0);if(crossedBarrier!==void 0){throw new Error(`Run ${crossedBarrier.run.run_id} crossed its finalization barrier; no new Sub-Run may start`)}const executionKind=parent.run.execution_kind;if(purpose==="execution"&&options.allowObservedIneligibleInvocation!==true&&(executionKind===void 0||!executionEligibility.includes(executionKind))){throw new Error(`Agent ${agent} lacks an execution capability for Run ${parent.run.run_id}`)}if(purpose==="finalization"&&agent!=="agent-finalizer"){throw new Error(`Finalizer for Run ${parent.run.run_id} requires agent-finalizer`)}if(purpose!=="finalization")return;if(effectiveRunV2Role(parent.run)==="orchestrator"&&directExecutors(parent.run.run_id,executionKind,candidates).length===0){throw new Error(`Finalizer for Execution Run ${parent.run.run_id} requires a prior capable executor Sub-Run`)}const active=activeDescendantRuns(parent.run.run_id,candidates);if(active.length>0){throw new Error(`Finalizer for Run ${parent.run.run_id} must be the last Sub-Run; active descendants: ${active.map(run=>run.run.run_id).join(", ")}`)}}function directExecutors(parentRunId,executionKind,candidates){return candidates.filter(candidate=>candidate.run.parent_run_id===parentRunId&&effectiveRunV2Purpose(candidate.run)==="execution"&&(executionKind!==void 0&&candidate.run.execution_eligibility?.includes(executionKind)===true||executionKind===void 0&&candidate.run.execution_eligibility===void 0&&candidate.run.agent==="agent-task-executor")&&candidate.run.agent!=="agent-finalizer")}function ancestorLineage(parent,candidates){const byId2=new Map(candidates.map(candidate=>[candidate.run.run_id,candidate]));const lineage=[];const visited=new Set;let current=parent;while(current!==void 0&&!visited.has(current.run.run_id)){lineage.push(current);visited.add(current.run.run_id);current=current.run.parent_run_id===null?void 0:byId2.get(current.run.parent_run_id)}return lineage}function directFinalizers(parentRunId,candidates){return candidates.filter(candidate=>candidate.run.parent_run_id===parentRunId&&effectiveRunV2Purpose(candidate.run)==="finalization"&&(candidate.run.agent==="agent-finalizer"||candidate.run.agent==="agent-task-finalizer")).sort((left,right)=>left.run.occurred_at.localeCompare(right.run.occurred_at))}async function hasPassedTypedEvidenceForRun(run,evidenceIds,composition){if(run.run.execution_kind!=="delivery")return true;if(run.run.execution_id===null||evidenceIds.length===0){return false}const tasks=await evidenceTasks(run,composition);if(tasks.length===0)return false;const requested=new Set(evidenceIds);const bundle=await readAssuranceBundle(composition.filesystem,composition.layout,tasks,[...requested]);const eligible=await Promise.all(bundle.evidences.map(async evidence=>{const task=tasks.find(candidate=>evidence.task_id===candidate.id&&evidence.change_id===candidate.change_id);return requested.has(evidence.id)&&evidence.status==="passed"&&task!==void 0&&evidence.execution_id===run.run.execution_id&&completedEvidenceRun(evidence.run_id,run,task,composition)}));return bundle.evidences.length===requested.size&&eligible.every(Boolean)}async function passedTypedEvidenceIdsForRun(run,composition){if(run.run.execution_kind!=="delivery"||run.run.execution_id===null){return[]}const tasks=await evidenceTasks(run,composition);if(tasks.length===0)return[];const bundle=await readAssuranceBundle(composition.filesystem,composition.layout,tasks);const eligible=await Promise.all(bundle.evidences.map(async evidence=>{const task=tasks.find(candidate=>evidence.task_id===candidate.id&&evidence.change_id===candidate.change_id);return evidence.status==="passed"&&task!==void 0&&evidence.execution_id===run.run.execution_id&&await completedEvidenceRun(evidence.run_id,run,task,composition)?evidence.id:null}));return eligible.filter(id=>id!==null).sort()}async function evidenceTasks(run,composition){if(run.run.task_id!==null)return[(await composition.tasks.read(run.run.task_id)).task];if(run.run.execution_id===null||run.run.spec_id===null&&run.run.prd_id===null)return[];const execution=(await composition.executions.read(run.run.execution_id)).execution;const scopeMatches2=run.run.prd_id!==null?execution.origin.type==="prd"&&execution.origin.prd_id===run.run.prd_id:execution.origin.type==="spec"&&execution.origin.spec_id===run.run.spec_id;if(execution.status!=="completed"||!scopeMatches2)return[];return Promise.all(execution.dag.nodes.map(async node=>(await composition.tasks.read(node.task_id)).task))}async function completedEvidenceRun(id,root,task,composition){if(root.run.task_id!==null)return id===root.run.run_id;if(task.status!=="completed"||task.result?.completed_run_id!==id)return false;try{const run=await composition.runs.read(id);return run.status==="completed"&&run.run.execution_id===root.run.execution_id&&run.run.task_id===task.id&&run.run.change_id===task.change_id&&run.run.conversation_id===root.run.conversation_id}catch{return false}}async function assessRunLifecycleClosure(current,composition,candidateRuns){const role=effectiveRunV2Role(current.run);if(role==="intake"||role==="subagent"){return emptyClosure(current.run.run_id)}const subjects=(await Promise.all(current.run.entrypoint==="task"?[subject("task",current.run.task_id,composition,role,current)]:[subject("spec",current.run.spec_id,composition,role,current),subject("prd",current.run.prd_id,composition,role,current)])).filter(item=>item!==null);void candidateRuns;const openSubjectIds=subjects.filter(item=>!item.settled).map(item=>item.id);const status=subjects.length===0?"not_applicable":openSubjectIds.length===0?"closed":"action_required";return{status,run_id:current.run.run_id,continuation_run_id:null,subjects,open_subject_ids:openSubjectIds,default_inconclusive_outcome:"blocked",allowed_terminal_outcomes:["completed","blocked","failed","cancelled"],guidance:status==="action_required"?"Start an attributed continuation Run or settle every related work item; use blocked by default, failed only for an execution-preventing error, and cancelled only after an explicit user cancellation.":"Run lifecycle closure is satisfied."}}async function subject(kind,id,composition,role,current){if(id===null)return null;try{const status=kind==="task"?(await composition.tasks.read(id)).task.status:kind==="spec"?(await composition.specs.read(id)).spec.status:(await composition.prds.read(id)).prd.status;return{kind,id,status,settled:isSettled(kind,status,role,current)}}catch{return{kind,id,status:"missing",settled:false}}}function isSettled(kind,status,role,current){if(kind==="task")return["completed","blocked","failed","cancelled"].includes(status);if(role==="orchestrator"&¤t.finished?.status==="completed")return status!=="missing";return["delivered","blocked","failed","cancelled"].includes(status)}function emptyClosure(runId){return{status:"not_applicable",run_id:runId,continuation_run_id:null,subjects:[],open_subject_ids:[],default_inconclusive_outcome:"blocked",allowed_terminal_outcomes:["completed","blocked","failed","cancelled"],guidance:"Run lifecycle closure is satisfied."}}function lifecycleReconciliationOutcome(value){if(value===void 0)return void 0;if(value==="completed"||value==="blocked"||value==="failed"||value==="cancelled"){return value}throw new Error("--task-outcome must be completed, blocked, failed, or cancelled")}function lifecycleOutcomeOption(options){if(options["owner-outcome"]!==void 0){throw new Error("Legacy lifecycle outcome option is no longer supported; use --task-outcome")}return lifecycleReconciliationOutcome(options["task-outcome"])}var SETTLEABLE_TASK=new Set(["draft","planned","executing","verifying"]);var SETTLEABLE_CHANGE=new Set(["draft","planned","executing","verifying"]);var SETTLEABLE_EXECUTION=new Set(["planned","running","paused","verifying"]);var MISSING_GUI_FINALIZATION_REASON="Finalization barrier missing; resume after a completed zaip-agent-finalizer Sub-Run with authoritative metadata";var MISSING_GUI_DECISION_REASON="Orchestrator stopped without a persisted Gui finalization decision; lifecycle was fail-closed as blocked.";function isTaskAttemptRun(current){return effectiveRunV2Role(current.run)==="orchestrator"&¤t.run.parent_run_id===null&&(current.run.entrypoint==="task"||current.run.work_type==="rework"&¤t.run.task_id!==null)}async function reconcileFinishedRunLifecycle(current,composition,lifecycle,options={}){if(current.finished===null)throw new Error(`Run is still running: ${current.run.run_id}`);const role=effectiveRunV2Role(current.run);if(role==="intake"||role==="subagent"){return emptyResult(current.run.run_id,"not_applicable")}if(current.run.execution_id!==null){const execution=await composition.executions.read(current.run.execution_id).catch(()=>null);if(execution?.execution.kind==="interaction"){return emptyResult(current.run.run_id,"not_applicable")}}if(options.defer===true){throw new Error(`Orchestrator Run closure cannot be deferred for Run ${current.run.run_id}`)}const closure=await assessRunLifecycleClosure(current,composition,options.candidateRuns);if(closure.status==="not_applicable")return emptyResult(current.run.run_id,"not_applicable");const catalog=options.catalog??await loadCatalog(composition);const graph=relatedGraph(current,catalog);const requested=resolveOutcome(current,graph.tasks,options.requestedOutcome,options.forceRequestedOutcome);if(requested==="completed"){try{const resumable=await resumeOwnCompletionGateBlocks(current,graph,composition,lifecycle,options.candidateRuns);const completed=await completeGraph(current,resumable,composition,lifecycle,options);return{...completed,status:"closed",outcome:"completed"}}catch(error51){const message=error51 instanceof Error?error51.message:String(error51);const blocked=await settleGraph(current,await refreshGraph(graph,composition),composition,lifecycle,"blocked",`Completion gates did not close Run ${current.run.run_id}: ${message}`);return{...blocked,status:"closed",outcome:"blocked",fallback_from:"completed",error:message}}}const settled=await settleGraph(current,graph,composition,lifecycle,requested,options.summary===void 0?defaultReason(current.run.run_id,requested):`${options.summary} (Run ${current.run.run_id}).`);return{...settled,status:"closed",outcome:requested}}async function snapshotRunLifecycle(current,composition,catalog){const role=effectiveRunV2Role(current.run);if(role==="intake"||role==="subagent"){return emptyResult(current.run.run_id,"not_applicable")}const graph=relatedGraph(current,catalog??await loadCatalog(composition));return currentGraphResult(current.run.run_id,await refreshGraph(graph,composition))}async function resumeOwnCompletionGateBlocks(current,graph,composition,lifecycle,candidateRuns){if(current.finalization_decision?.outcome!=="completed")return graph;const eligiblePredecessors=new Set(await completionGatePredecessorIds(current,graph,candidateRuns??await composition.runs.list()));if(current.finalization_decision?.outcome==="completed"){eligiblePredecessors.add(current.run.run_id)}const isOwnBlock=reason=>[...eligiblePredecessors].some(runId=>reason===`${MISSING_GUI_DECISION_REASON} (Run ${runId}).`||reason===`${MISSING_GUI_FINALIZATION_REASON} (Run ${runId}).`||reason?.startsWith(`Completion gates did not close Run ${runId}:`)===true);for(const task of graph.tasks){const latest=(await composition.tasks.read(task.id)).task;if(latest.status==="blocked"&&isOwnBlock(latest.status_reason??null)){await lifecycle.startTask(task.id,"resume")}}for(const change of graph.changes){const latest=(await composition.changes.read(change.id)).change;if(latest.status==="blocked"&&isOwnBlock(latest.status_reason??null)){await composition.changes.transition(latest.id,"executing")}}for(const execution of graph.executions){const latest=(await composition.executions.read(execution.id)).execution;if(latest.status!=="blocked"||!isOwnBlock(latest.status_reason??null))continue;if(latest.dag.nodes.length===0){await composition.executions.transition(latest.id,"cancelled","Superseded empty continuation intake")}else{await composition.executions.transition(latest.id,"running")}}return refreshGraph(graph,composition)}async function completionGatePredecessorIds(current,graph,candidates){const threadId=current.run.client_thread_id;if(current.run.task_id===null||current.run.change_id===null||current.run.execution_id===null){return new Set}const executionIds=new Set(graph.executions.map(execution=>execution.id));const eligible=new Set;for(const predecessor of candidates){if(predecessor.run.run_id===current.run.run_id||predecessor.finished===null||!isTaskAttemptRun(predecessor)||predecessor.run.occurred_at>=current.run.occurred_at||threadId!==null&&predecessor.run.client_thread_id!==threadId||predecessor.run.task_id!==current.run.task_id||predecessor.run.change_id!==current.run.change_id||predecessor.run.execution_id===null||!executionIds.has(predecessor.run.execution_id)){continue}eligible.add(predecessor.run.run_id)}return eligible}function resolveOutcome(current,tasks,requested,forceRequested){if(forceRequested===true&&requested!==void 0)return requested;if(current.finished?.status==="failed")return"failed";if(current.finished?.status==="cancelled")return"cancelled";if(requested!==void 0)return requested;if(!isTaskAttemptRun(current))return"completed";const terminal=tasks.find(task=>["completed","blocked","failed","cancelled"].includes(task.status))?.status;return terminal==="completed"||terminal==="blocked"||terminal==="failed"||terminal==="cancelled"?terminal:"blocked"}async function completeGraph(current,graph,composition,lifecycle,options){const summary=options.summary??`Run ${current.run.run_id} completed.`;const result2={summary,changed_files:[...options.changedFiles??[]],evidence_ids:[...options.evidenceIds??[]],completed_run_id:current.run.run_id};const taskAttempt=isTaskAttemptRun(current);if(taskAttempt){for(const task of graph.tasks){let latest=(await composition.tasks.read(task.id)).task;if(latest.status==="executing")latest=await composition.tasks.transition(task.id,"verifying");if(latest.status==="verifying")await lifecycle.completeTask(task.id,result2)}}else{const unfinished=graph.tasks.filter(task=>task.status!=="completed");if(unfinished.some(task=>["draft","planned","executing","verifying"].includes(task.status))){await keepMacroParentsActive(graph,composition);return currentGraphResult(current.run.run_id,await refreshGraph(graph,composition))}if(unfinished.length>0){throw new Error(`Macro Tasks did not complete: ${unfinished.map(task=>task.id).join(", ")}`)}}for(const change of graph.changes){let latest=(await composition.changes.read(change.id)).change;const relatedTasks=await Promise.all(latest.task_ids.map(async id=>(await composition.tasks.read(id)).task));if(relatedTasks.some(task=>task.status!=="completed"))continue;if(latest.status==="executing"){await lifecycle.verifyChange(change.id);latest=(await composition.changes.read(change.id)).change}if(latest.status==="verifying")await lifecycle.completeChange(change.id,summary)}for(const execution of graph.executions){let latest=(await composition.executions.read(execution.id)).execution;const relatedTasks=await Promise.all(latest.dag.nodes.map(async node=>(await composition.tasks.read(node.task_id)).task));if(relatedTasks.some(task=>task.status!=="completed"))continue;if(latest.status==="planned"&&latest.dag.nodes.length===0){await composition.executions.transition(execution.id,"cancelled","Superseded empty continuation intake");continue}if(latest.status==="planned"){latest=await composition.executions.transition(execution.id,"running")}if(latest.status==="blocked"&&taskAttempt){latest=await composition.executions.transition(execution.id,"running")}if(latest.status==="running"){await lifecycle.verifyExecution(execution.id);latest=(await composition.executions.read(execution.id)).execution}if(latest.status==="verifying")await lifecycle.completeExecution(execution.id,summary)}if(!taskAttempt){for(const spec of graph.specs.filter(item=>graph.directSpecIds.has(item.id))){if((await composition.specs.read(spec.id)).spec.status==="active")await lifecycle.deliverSpec(spec.id)}for(const prd of graph.prds.filter(item=>graph.directPrdIds.has(item.id))){if((await composition.prds.read(prd.id)).prd.status==="active")await lifecycle.deliverPrd(prd.id)}}else{await aggregateMacroAncestors(graph,composition)}const refreshed=await refreshGraph(graph,composition);assertGraphCompleted(refreshed,taskAttempt);return currentGraphResult(current.run.run_id,refreshed)}function assertGraphCompleted(graph,taskAttempt){const incomplete=[...graph.tasks.filter(item=>item.status!=="completed").map(item=>item.id),...!taskAttempt?graph.changes.filter(item=>item.status!=="completed").map(item=>item.id):[],...graph.executions.filter(item=>item.status!=="completed"&&!(item.dag.nodes.length===0&&item.status==="cancelled")).map(item=>item.id),...graph.specs.filter(item=>!taskAttempt&&graph.directSpecIds.has(item.id)&&item.status!=="delivered").map(item=>item.id),...graph.prds.filter(item=>!taskAttempt&&graph.directPrdIds.has(item.id)&&item.status!=="delivered").map(item=>item.id)];if(incomplete.length>0){throw new Error(`Completion left related work non-terminal: ${incomplete.join(", ")}`)}}async function settleGraph(current,graph,composition,lifecycle,outcome,reason){const clock=new SystemClock;const taskAttempt=isTaskAttemptRun(current);const taskResult=outcome==="blocked"?null:{summary:reason,changed_files:[],evidence_ids:[],completed_run_id:current.run.run_id};for(const task of graph.tasks){if(SETTLEABLE_TASK.has((await composition.tasks.read(task.id)).task.status)){await composition.tasks.transition(task.id,outcome,taskResult,clock,reason)}}const standalone=graph.executions.some(execution=>execution.origin.type==="task");for(const change of taskAttempt&&!standalone?[]:graph.changes){if(SETTLEABLE_CHANGE.has((await composition.changes.read(change.id)).change.status)){await composition.changes.transition(change.id,outcome,outcome==="blocked"?null:reason,clock,reason)}}for(const execution of taskAttempt&&!standalone?[]:graph.executions){if(SETTLEABLE_EXECUTION.has((await composition.executions.read(execution.id)).execution.status)){await composition.executions.transition(execution.id,outcome,outcome==="blocked"?null:reason,clock,reason)}}const specIdsToSettle=new Set(taskAttempt?[]:specIdsForLifecycleSettlement(graph.specs.map(item=>item.id),graph.directSpecIds,graph.directPrdIds));const specsToSettle=graph.specs.filter(item=>specIdsToSettle.has(item.id));for(const spec of specsToSettle){if(outcome==="cancelled"&&graph.directPrdIds.size>0)break;if((await composition.specs.read(spec.id)).spec.status==="active"){if(outcome==="cancelled")await lifecycle.cancelSpec(spec.id);else await composition.specs.transition(spec.id,outcome,reason)}}for(const prd of graph.prds.filter(item=>!taskAttempt&&graph.directPrdIds.has(item.id))){if((await composition.prds.read(prd.id)).prd.status==="active"){if(outcome==="cancelled")await lifecycle.cancelPrd(prd.id);else await composition.prds.transition(prd.id,outcome,reason)}}if(taskAttempt&&!standalone)await aggregateMacroAncestors(graph,composition);return currentGraphResult(current.run.run_id,await refreshGraph(graph,composition))}function relatedGraph(current,catalog){const{tasks,changes,executions,specs,prds}=catalog;const taskIds=new Set(current.run.task_id===null?[]:[current.run.task_id]);const changeIds=new Set(current.run.change_id===null?[]:[current.run.change_id]);const executionIds=new Set(current.run.execution_id===null?[]:[current.run.execution_id]);const specIds=new Set(current.run.spec_id===null?[]:[current.run.spec_id]);const prdIds=new Set(current.run.prd_id===null?[]:[current.run.prd_id]);const taskAttempt=isTaskAttemptRun(current);if(!taskAttempt){for(const spec of specs)if(spec.prd_id!==null&&prdIds.has(spec.prd_id))specIds.add(spec.id)}for(const change of changes){const source=change.source;if(changeIds.has(change.id)||source.type==="task"&&taskIds.has(source.task_id)||!taskAttempt&&source.type==="spec"&&specIds.has(source.spec_id)||!taskAttempt&&source.type==="prd"&&prdIds.has(source.prd_id))changeIds.add(change.id)}for(const task of tasks){if(taskIds.has(task.id)||!taskAttempt&&changeIds.has(task.change_id)){taskIds.add(task.id);const canonicalExecutionId=task.plan_ref?.execution_id??task.prepared_plan?.execution_id;if(canonicalExecutionId!==void 0&&canonicalExecutionId!==null)executionIds.add(canonicalExecutionId)}}for(const execution of executions){if(executionIds.has(execution.id)||execution.origin.type==="task"&&taskIds.has(execution.origin.task_id)||execution.dag.nodes.some(node=>taskIds.has(node.task_id))){executionIds.add(execution.id)}}return{tasks:tasks.filter(item=>taskIds.has(item.id)),changes:changes.filter(item=>changeIds.has(item.id)),executions:executions.filter(item=>executionIds.has(item.id)),specs:specs.filter(item=>specIds.has(item.id)),prds:prds.filter(item=>prdIds.has(item.id)),directSpecIds:new Set(current.run.spec_id===null?[]:[current.run.spec_id]),directPrdIds:new Set(current.run.prd_id===null?[]:[current.run.prd_id])}}async function keepMacroParentsActive(graph,composition){for(const spec of graph.specs){const latest=(await composition.specs.read(spec.id)).spec;if(latest.status==="ready"||latest.status==="blocked"){await composition.specs.transition(latest.id,"active")}}for(const prd of graph.prds){const latest=(await composition.prds.read(prd.id)).prd;if(latest.status==="ready"||latest.status==="blocked"){await composition.prds.transition(latest.id,"active")}}}async function aggregateMacroAncestors(graph,composition){await keepMacroParentsActive(graph,composition)}async function loadCatalog(composition){const[tasks,changes,executions,specs,prds]=await Promise.all([composition.tasks.list(),composition.changes.list(),composition.executions.list(),composition.specs.list(),composition.prds.list()]);return{tasks,changes,executions,specs,prds}}async function refreshGraph(graph,composition){const[tasks,changes,executions,specs,prds]=await Promise.all([Promise.all(graph.tasks.map(async item=>(await composition.tasks.read(item.id)).task)),Promise.all(graph.changes.map(async item=>(await composition.changes.read(item.id)).change)),Promise.all(graph.executions.map(async item=>(await composition.executions.read(item.id)).execution)),Promise.all(graph.specs.map(async item=>(await composition.specs.read(item.id)).spec)),Promise.all(graph.prds.map(async item=>(await composition.prds.read(item.id)).prd))]);return{...graph,tasks,changes,executions,specs,prds}}function currentGraphResult(runId,graph){return{run_id:runId,status:"closed",outcome:null,fallback_from:null,error:null,tasks:graph.tasks,changes:graph.changes,executions:graph.executions,specs:graph.specs,prds:graph.prds}}function emptyResult(runId,status){return{run_id:runId,status,outcome:null,fallback_from:null,error:null,tasks:[],changes:[],executions:[],specs:[],prds:[]}}function specIdsForLifecycleSettlement(specIds,directSpecIds,directPrdIds){return directPrdIds.size>0?[...specIds]:specIds.filter(id=>directSpecIds.has(id))}function defaultReason(runId,outcome){if(outcome==="failed")return`Run ${runId} failed and closed its operational lifecycle.`;if(outcome==="cancelled")return`Run ${runId} was explicitly cancelled.`;return`Run ${runId} completed without sufficient closure gates and has no concrete continuation.`}function compactRunAggregate(aggregate){const bucket=value=>({usage_event_count:value.usage_event_count,tokens:value.tokens,cost:value.cost,coverage:value.coverage});return{scope_id:aggregate.scope_id,run_count:aggregate.run_count,run_coverage:aggregate.run_coverage,attribution:aggregate.attribution,conversation:bucket(aggregate.conversation),planning:bucket(aggregate.planning),execution:bucket(aggregate.execution),total:bucket(aggregate.total),work_types:{new:bucket(aggregate.work_types.new),rework:bucket(aggregate.work_types.rework)}}}async function runConversationV2Command(action,parsed,composition,filesystem,lifecycle){if(action==="start"){const client=parsed.options.client??"codex";const clientInvocation=await resolveRunClientInvocation(filesystem,client);const requestedIntent=resolveConversationIntent(parsed,clientInvocation.userMessage);assertDefinitionConversationIntake(parsed,requestedIntent);if(requestedIntent==="git_only"||isImplicitConversationCapture(parsed)&&isGitOnlyPublicationRequest(clientInvocation.userMessage)){return{skipped:true,reason:"git-only-publication",message:"Explicit deploy, push, and publication requests do not create ZAIP lifecycle records"}}const existing=await findIntakeForExactTurn(composition,client,clientInvocation);if(existing!==null){const task2=existing.run.task_id===null?null:(await composition.tasks.read(existing.run.task_id)).task;return{task:task2,run:existing.run,task_path:task2===null?null:composition.tasks.path(task2.id),run_path:composition.runs.path(existing.run.run_id),reused:true}}const request=conversationRequestOptions(clientInvocation.userMessage);const threadContext=await latestThreadContext(composition,client,clientInvocation.clientThreadId);let intent=requestedIntent;const newWorkMetadata=intent==="new_work"?requireSemanticNewWorkMetadata(parsed):null;let target=intent==="continue"||intent==="refine"||intent==="rework"?explicitIntakeTarget(parsed)??threadContext.implicitTarget:null;let decision=intakeDecision(parsed,intent);if(intent==="new_work"&&newWorkMetadata!==null&&decision.classification_source!=="explicit"&&threadContext.implicitTarget?.taskId!==void 0){const focusedTask=(await composition.tasks.read(threadContext.implicitTarget.taskId)).task;if((focusedTask.status==="draft"||focusedTask.status==="planned")&&focusedTask.started_at===null&&describesEquivalentWork(newWorkMetadata,focusedTask)){intent="continue";target=threadContext.implicitTarget;decision={intent:"continue",classification_source:"fallback",confidence:1,reason_codes:["equivalent-thread-work-reused"]}}}if((intent==="continue"||intent==="refine"||intent==="rework")&&target===null){intent="conversation";target=null;decision={intent:"conversation",classification_source:"fallback",confidence:0,reason_codes:["target-not-resolved"]}}const model=resolveConversationModel(parsed.options.model,clientInvocation.observedModel);const reasoningEffort=resolveConversationReasoningEffort(parsed.options["reasoning-effort"],clientInvocation.observedReasoningEffort);const timeZone=composition.layout.project.timezone;const conversationId2=parsed.options.conversation??threadContext.conversationId??createConversationId(intent==="new_work"?"new-work":"conversation");const clientTurnId=clientInvocation.clientTurnId??`local-${Date.now()}-${createCollisionCode(16)}`;const executionPolicy={failure_policy:"stop_on_terminal_failure",max_parallelism:1,max_operational_retries:1,max_repair_cycles_per_task:0,verification_mode:"scoped"};const commonInput=(executionId,executionKind)=>({...parsed.options.run===void 0?{}:{id:parsed.options.run},phase:conversationCapturePhase(intent),workType:runV2WorkTypeOption(intent==="rework"?"rework":parsed.options["work-type"]??"new"),client,runRole:"orchestrator",runPurpose:"orchestration",requiresFinalizer:executionKind==="delivery",executionKind,executionEligibility:[],agent:"agent-orchestrator",agentName:"zaip-agent-orchestrator",provider:parsed.options.provider??null,model,reasoningEffort,clientThreadId:clientInvocation.clientThreadId,clientTurnId,conversationId:conversationId2,executionId,intake:decision});const rootDeveloperIdentity=await resolveDeveloperIdentityForRoot(filesystem);const openIntakes=await openThreadIntakes(composition,client,clientInvocation.clientThreadId,clientInvocation.clientTurnId);const continuationOfRunId=target===null?null:openIntakes.find(fold=>runMatchesTarget(fold,target))?.run.run_id??null;if(intent!=="new_work"){const canonicalTaskExecution=target?.taskId===void 0?null:await activeCanonicalTaskExecution(target.taskId,composition);const execution=target===null?await composition.executions.createInteraction({id:parsed.options.execution??createId("EXEC",`interaction-${intent}`,{timeZone}),clientTurnId,conversationId:conversationId2,policy:executionPolicy}):canonicalTaskExecution??await composition.executions.createDeliveryIntake({id:parsed.options.execution??createId("EXEC",`delivery-${intent}`,{timeZone}),clientTurnId,origin:target.taskId!==void 0?{type:"task",task_id:target.taskId}:target.specId!==void 0?{type:"spec",spec_id:target.specId}:{type:"prd",prd_id:target.prdId},policy:executionPolicy});const targetTask=target?.taskId===void 0?null:(await composition.tasks.read(target.taskId)).task;const input={...commonInput(execution.id,execution.kind??"delivery"),developerIdentity:rootDeveloperIdentity,shortName:parsed.options["short-name"]??intent.replaceAll("_","-"),entrypoint:target?.entrypoint??"conversation",...target?.taskId===void 0?{}:{taskId:target.taskId},...targetTask===null?{}:{changeId:targetTask.change_id},...target?.specId===void 0?{}:{specId:target.specId},...target?.prdId===void 0?{}:{prdId:target.prdId},continuationOfRunId};await validateRunV2Attribution(input,composition);const writer=await composition.runs.start(input);const settledIntakes=await finishOpenThreadIntakes(openIntakes,composition,filesystem,parsed,lifecycle);const task2=input.taskId==null?null:(await composition.tasks.read(input.taskId)).task;return{task:task2,run:writer.started,settled_intakes:settledIntakes,task_path:task2===null?null:composition.tasks.path(task2.id),run_path:composition.runs.path(writer.started.run_id)}}const metadata=newWorkMetadata??requireSemanticNewWorkMetadata(parsed);const taskId=parsed.options.task??createId("TASK",metadata.shortName,{timeZone});const changeId=parsed.options.change??createId("CHG",metadata.shortName,{timeZone});const task=await composition.tasks.createDraft({id:taskId,changeId,title:metadata.title,shortName:metadata.shortName,objective:metadata.objective,risk:riskOption(parsed.options.risk??request.risk),priority:priorityOption(parsed.options.priority),owner:parsed.options.owner??null,requirementIds:csvOption(parsed.options.requirements??"REQ-WORK-001"),acceptanceIds:csvOption(parsed.options.acceptance??"AC-WORK-001-09"),dependsOn:[],writeScopes:csvOption(parsed.options["write-scopes"])});await composition.changes.createDraft({id:changeId,title:task.title,risk:task.risk,taskId:task.id,requirementIds:task.requirement_ids,acceptanceIds:task.acceptance_ids});const deliveryExecution=await composition.executions.createDeliveryIntake({id:parsed.options.execution??createId("EXEC",`delivery-${intent}`,{timeZone}),clientTurnId,origin:{type:"task",task_id:task.id},policy:executionPolicy});try{const plan=createTaskFirstPreparedPlan({task,executionId:deliveryExecution.id,preparedAt:new Date().toISOString(),policy:executionPolicy});await composition.tasks.setPreparedPlan(task.id,plan);await composition.materializer.execute(plan);await composition.executions.transition(deliveryExecution.id,"running");await composition.changes.transition(changeId,"executing");const activeTask=await lifecycle.startTask(task.id);const input={...commonInput(deliveryExecution.id,"delivery"),developerIdentity:rootDeveloperIdentity,shortName:metadata.shortName,entrypoint:"task",taskId,changeId};await validateRunV2Attribution(input,composition);const writer=await composition.runs.start(input);const settledIntakes=await finishOpenThreadIntakes(openIntakes,composition,filesystem,parsed,lifecycle);return{task:activeTask,run:writer.started,settled_intakes:settledIntakes,task_path:composition.tasks.path(task.id),run_path:composition.runs.path(writer.started.run_id)}}catch(error51){const message=error51 instanceof Error?error51.message:String(error51);await composition.tasks.transition(taskId,"cancelled",{summary:`Conversation Run was not created: ${message}`,changed_files:[],evidence_ids:[],completed_run_id:null});await composition.changes.transition(changeId,"cancelled",`Conversation Run was not created: ${message}`);const currentExecution=(await composition.executions.read(deliveryExecution.id)).execution;if(currentExecution.status==="planned"||currentExecution.status==="running"){await composition.executions.transition(deliveryExecution.id,"cancelled",`Conversation Run was not created: ${message}`)}throw error51}}if(action==="finish"){requireOptions(parsed.options,["run","summary"]);const runId=parsed.options.run;let current=await composition.runs.read(runId);if(parsed.options.task!==void 0&¤t.run.task_id!==parsed.options.task){throw new UsageError(`Run ${runId} is not attributed to Task ${parsed.options.task}`)}const candidateRuns=await composition.runs.list();const evidenceIds=csvOption(parsed.options.evidence);const finalizationBarrier=assessRunFinalizationBarrier(current,candidateRuns,await hasPassedTypedEvidenceForRun(current,evidenceIds,composition));const finalizationBlockReason=finalizationBarrierBlockReason(finalizationBarrier);if(current.finished===null&&finalizationBarrier.status==="evidence_missing"){throw new UsageError(finalizationBlockReason)}const activeChildren=activeDescendantRuns(runId,candidateRuns);if(activeChildren.length>0){throw new UsageError(`Run ${runId} cannot finish while descendant Runs are active: ${activeChildren.map(child=>child.run.run_id).join(", ")}`)}const executionAtFinish=current.run.execution_id===null?null:(await composition.executions.read(current.run.execution_id)).execution;if(current.finished===null){current=await recordCodexTelemetryIfAvailable(current,composition,filesystem,null,await codexAppServerNotifications(parsed,filesystem))}if(current.finished===null&¤t.effective_usage_records.length===0){await recordUnavailableCodexTelemetryToSpool(current,filesystem,runV2FinishStatusOption(parsed.options.status));const usage=unavailableUsageRecord(current,parsed,current.records.length+1);await composition.runs.appendRecord(usage);current=foldRunV2Records([...current.records,usage])}if(current.finished===null){await composition.runs.appendRecord(runFinishedV2Schema.parse({schema_version:2,event_id:runV2EventId(runId,current.records.length+1),run_id:runId,sequence:current.records.length+1,occurred_at:new Date().toISOString(),type:"run.finished",phase:latestRunV2Phase(current.records),status:runV2FinishStatusOption(parsed.options.status)}))}let task=current.run.task_id===null?null:(await composition.tasks.read(current.run.task_id)).task;if(parsed.flags.has("cancel-task")){throw new UsageError("--cancel-task cannot bypass Gui; finish the delivery Run after Gui finalization")}const run=await composition.runs.read(runId);let interactionExecution=null;if(executionAtFinish?.kind==="interaction"){interactionExecution=finalizationBlockReason===null?await completeInteractionExecution(executionAtFinish.id,composition):await blockInteractionExecution(executionAtFinish.id,finalizationBlockReason,composition)}const reconciliation=await reconcileFinishedRunLifecycle(run,composition,lifecycle,{requestedOutcome:finalizationBlockReason===null?lifecycleOutcomeOption(parsed.options):"blocked",forceRequestedOutcome:finalizationBlockReason!==null,summary:finalizationBlockReason??parsed.options.summary,changedFiles:csvOption(parsed.options["changed-files"]),evidenceIds,defer:finalizationBlockReason===null&&parsed.flags.has("defer-orchestrator-closure"),candidateRuns});task=current.run.task_id===null?null:(await composition.tasks.read(current.run.task_id)).task;return{task,summary:parsed.options.summary,run:runV2Summary(run,composition),reconciliation,execution:interactionExecution,finalization_barrier:finalizationBarrier,task_path:task===null?null:composition.tasks.path(task.id),run_path:composition.runs.path(runId)}}throw new UsageError(`Unknown Conversation action: ${action??""}`)}async function activeCanonicalTaskExecution(taskId,composition){const task=(await composition.tasks.read(taskId)).task;const executionId=task.plan_ref?.execution_id??task.prepared_plan?.execution_id??null;if(executionId===null)return null;const execution=(await composition.executions.read(executionId)).execution;const terminal=new Set(["completed","failed","cancelled"]);return!terminal.has(execution.status)&&execution.dag.nodes.some(node=>node.task_id===task.id&&node.change_id===task.change_id)?execution:null}async function completeInteractionExecution(executionId,composition){let execution=(await composition.executions.read(executionId)).execution;if(execution.status==="running"){execution=await composition.executions.transition(executionId,"verifying")}return execution.status==="verifying"?composition.executions.transition(executionId,"completed","Interaction finalized"):execution}async function blockInteractionExecution(executionId,reason,composition){const execution=(await composition.executions.read(executionId)).execution;return execution.status==="running"||execution.status==="paused"||execution.status==="verifying"?composition.executions.transition(executionId,"blocked",null,void 0,reason):execution}function conversationCapturePhase(intent){if(intent==="new_work")return"execution";return intent==="refine"||intent==="rework"?"planning":"conversation"}function resolveConversationModel(explicitModel,observedModel=null){return explicitModel??observedModel??"unknown"}function resolveConversationReasoningEffort(explicitEffort,observedEffort){if(explicitEffort!==void 0)return runV2ReasoningEffortSchema.parse(explicitEffort);const observed=runV2ReasoningEffortSchema.safeParse(observedEffort);return observed.success?observed.data:null}async function openThreadIntakes(composition,client,clientThreadId,currentTurnId){if(clientThreadId===null)return[];const candidates=await composition.runs.list();return candidates.filter(fold=>fold.finished===null&&fold.run.client===client&&fold.run.client_thread_id===clientThreadId&&fold.run.parent_run_id===null&&fold.run.intake!=null&&!runV2RequiresFinalizer(fold.run)&&descendantRuns(fold.run.run_id,candidates).length===0&&fold.run.client_turn_id!==currentTurnId)}async function finishOpenThreadIntakes(openIntakes,composition,filesystem,parsed,lifecycle){const settled=[];for(const intake of openIntakes){const candidateRuns=await composition.runs.list();if(descendantRuns(intake.run.run_id,candidateRuns).length>0||activeDescendantRuns(intake.run.run_id,candidateRuns).length>0){continue}let current=intake;current=await recordCodexTelemetryIfAvailable(current,composition,filesystem,null,await codexAppServerNotifications(parsed,filesystem));if(current.effective_usage_records.length===0){await recordUnavailableCodexTelemetryToSpool(current,filesystem,"completed");await composition.runs.appendRecord(unavailableUsageRecord(current,parsed,current.records.length+1));current=await composition.runs.read(current.run.run_id)}await composition.runs.appendRecord(runFinishedV2Schema.parse({schema_version:2,event_id:runV2EventId(current.run.run_id,current.records.length+1),run_id:current.run.run_id,sequence:current.records.length+1,occurred_at:new Date().toISOString(),type:"run.finished",phase:latestRunV2Phase(current.records),status:"completed"}));const run=await composition.runs.read(current.run.run_id);settled.push({run,reconciliation:await reconcileFinishedRunLifecycle(run,composition,lifecycle,{candidateRuns})})}return settled}async function codexAppServerNotifications(parsed,filesystem){const path=parsed.options["codex-app-server-events"];return path===void 0?[]:parseCodexAppServerNotificationStream(await filesystem.readText(path))}function runMatchesTarget(fold,target){return target.taskId!==void 0&&fold.run.task_id===target.taskId||target.specId!==void 0&&fold.run.spec_id===target.specId||target.prdId!==void 0&&fold.run.prd_id===target.prdId}async function recordContextPackUsage(runId,initialPackTokens,composition){const current=await composition.runs.read(runId);if(current.finished!==null)throw new UsageError(`Run V2 is already finished: ${runId}`);const sequence=current.records.length+1;await composition.runs.appendRecord(usageRecordedV2Schema.parse({schema_version:2,event_id:runV2EventId(runId,sequence),run_id:runId,sequence,occurred_at:new Date().toISOString(),type:"usage.recorded",phase:latestRunV2Phase(current.records),activity_kind:"context_build",classification_source:"current_context",tokens:{input:null,cached_input:null,output:null,reasoning:null,total:null,source:"unavailable"},cost:{usd:null,brl:null},provider:current.run.provider,model:current.run.model,source_segment_key:`context-pack:${runId}:${sequence}`,supersedes_event_id:null,source_occurred_at:new Date().toISOString(),context_stats:{initial_pack_tokens:initialPackTokens,tool_output_tokens:null,files_opened:null,snippets_opened:null}}))}function unavailableUsageRecord(current,parsed,sequence){const occurredAt=new Date().toISOString();return usageRecordedV2Schema.parse({schema_version:2,event_id:runV2EventId(current.run.run_id,sequence),run_id:current.run.run_id,sequence,occurred_at:occurredAt,type:"usage.recorded",phase:latestRunV2Phase(current.records),activity_kind:"run_finalize",classification_source:"current_context",tokens:{input:null,cached_input:null,output:null,reasoning:null,total:null,source:"unavailable"},cost:{usd:null,brl:null},provider:current.run.provider,model:current.run.model,source_segment_key:null,supersedes_event_id:null,...runUsageMetadataOptions(parsed.options,occurredAt)})}function latestRunV2Phase(records){const latest=records.findLast(record3=>"phase"in record3);return latest?.phase??"conversation"}function runV2EventId(runId,sequence){return`${runId}:${String(sequence).padStart(6,"0")}`}function runV2CostInput(fold){return{run:{run_id:fold.run.run_id,attribution_status:fold.run.attribution_status,conversation_id:fold.run.conversation_id,execution_id:fold.run.execution_id,task_id:fold.run.task_id,spec_id:fold.run.spec_id,prd_id:fold.run.prd_id,change_id:fold.run.change_id,work_type:fold.run.work_type},records:fold.records,effective_usage_records:fold.effective_usage_records}}function runV2Summary(fold,composition){const usage=aggregateRunV2Usage([runV2CostInput(fold)],fold.run.run_id).total;const callIds=new Set([...fold.model_selection_records.map(record3=>record3.invocation_id),...fold.provider_invocation_records.map(record3=>record3.invocation_id)]);return{id:fold.run.run_id,status:fold.status,created_at:fold.run.occurred_at,finished_at:fold.finished?.occurred_at??null,phase:latestRunV2Phase(fold.records),run_role:effectiveRunV2Role(fold.run),parent_run_id:fold.run.parent_run_id,entrypoint:fold.run.entrypoint,work_type:fold.run.work_type,intake:fold.run.intake??null,agent:fold.run.agent,agent_name:fold.run.agent_name??(fold.run.agent.startsWith("agent-")?`zaip-agent-${fold.run.agent.slice("agent-".length)}`:fold.run.agent),model:fold.run.model,reasoning_effort:fold.run.reasoning_effort??fold.model_selection_records[0]?.requested.reasoning_effort??null,call_count:callIds.size===0?null:callIds.size,client_thread_id:fold.run.client_thread_id??null,client_turn_id:fold.run.client_turn_id??null,conversation_id:fold.run.conversation_id,execution_id:fold.run.execution_id,task_id:fold.run.task_id,spec_id:fold.run.spec_id,prd_id:fold.run.prd_id,change_id:fold.run.change_id,usage:{event_count:usage.usage_event_count,tokens:usage.tokens,cost:usage.cost,coverage:usage.coverage},artifact_path:composition.runs.path(fold.run.run_id)}}async function reconcileTerminalOrchestratorRoot(root,candidates,composition,lifecycle){const evidenceIds=await passedTypedEvidenceIdsForRun(root,composition);const evidenceSatisfied=await hasPassedTypedEvidenceForRun(root,evidenceIds,composition);const barrier=assessRunFinalizationBarrier(root,candidates,evidenceSatisfied);const blockReason=finalizationBarrierBlockReason(barrier);const decision=root.finalization_decision??null;const decisionEligible=decision!==null&&(decision.outcome!=="completed"||barrier.satisfied);const reconciliation=await reconcileFinishedRunLifecycle(root,composition,lifecycle,{requestedOutcome:decisionEligible?decision.outcome:"blocked",forceRequestedOutcome:!decisionEligible,summary:decisionEligible?decision.summary:blockReason??"Orchestrator stopped without a persisted Gui finalization decision; lifecycle was fail-closed as blocked.",evidenceIds:decision?.evidence_ids??evidenceIds,changedFiles:decision?.changed_files??[],candidateRuns:candidates});return{status:"closed",parent_run_id:root.run.run_id,finalization_barrier:barrier,finalization_decision:decision,reconciliation}}async function runSubagentV2Command(action,parsed,composition,filesystem,lifecycle,onTerminalMutationCommitted){parsed=normalizeSubagentSessionOption(parsed);if(action==="reconcile-local"){requireOptions(parsed.options,["parent-run-id"]);const parentRunId=optionValue(parsed,"parent-run-id");const root=(await composition.runs.list()).find(fold=>fold.finished===null&&fold.run.parent_run_id===null&&fold.run.run_id===parentRunId);if(root===void 0)throw new UsageError(`Active root Run not found: ${parentRunId}`);return reconcileLocalSubagentSessions(root,composition,filesystem,lifecycle)}if(action==="capture-terminal"){return captureTerminalFallback(parsed,composition,filesystem,lifecycle,onTerminalMutationCommitted)}if(action!=="capture")throw new UsageError(`Unknown subagent action: ${action??""}`);requireOptions(parsed.options,["event","session","turn","agent-id","agent-type"]);const event=parsed.options.event;if(event!=="start"&&event!=="stop"){throw new UsageError("--event must be start or stop")}if(event==="start")requireOptions(parsed.options,["model"]);const identity=await subagentIdentity(filesystem,parsed.options["agent-type"]??"");return event==="start"?captureStart(parsed,composition,identity):captureStop(parsed,composition,filesystem,lifecycle,identity)}async function captureTerminalFallback(parsed,composition,filesystem,lifecycle,onTerminalMutationCommitted){requireOptions(parsed.options,["parent-run-id","agent-id","agent-type","status"]);const parentAgentId=parsed.options["parent-agent-id"]?.trim();const parentRunId=optionValue(parsed,"parent-run-id");const agentPath=optionValue(parsed,"agent-id");const status=terminalStatus(parsed.options.status);const identity=await subagentIdentity(filesystem,optionValue(parsed,"agent-type"));const finalizer=identity.agent==="agent-finalizer"||identity.role==="execution-finalizer";const finalization=terminalFinalizationRequest(parsed,finalizer);const eligibleExecutor=identity.cataloged&&identity.executionEligibility.includes("delivery")&&identity.capabilities.includes("task-delivery");if(!identity.cataloged||!finalizer&&!eligibleExecutor)throw new UsageError("capture-terminal requires the cataloged zaip-agent-finalizer or an eligible delivery executor");const agentPathTaskName=agentPath.split(/[\\/]/u).filter(Boolean).at(-1)??"";if(identity.codexTaskName===null||agentPathTaskName!==identity.codexTaskName){throw new UsageError("capture-terminal agent-id must end with the selected catalog identity codex_task_name")}const initialRuns=await composition.runs.list();const root=initialRuns.find(fold=>fold.run.run_id===parentRunId&&fold.run.parent_run_id===null&&(parentAgentId===void 0?fold.run.client_thread_id===null:fold.run.client_thread_id===parentAgentId));if(root===void 0){throw new UsageError(`Cannot capture terminal Sub-Run without exact active root Run ${parentRunId}`)}if(root.finished!==null){const existing=terminalFallbackExisting(initialRuns,root.run.run_id,agentPath,identity.agent);if(existing===void 0||existing.status!==status){throw new UsageError(`Cannot capture terminal Sub-Run without exact active root Run ${parentRunId}`)}if(finalization!==null){const decision=root.finalization_decision??null;if(decision===null||decision.finalizer_run_id!==existing.run.run_id||decision.outcome!==finalization.outcome||decision.summary!==finalization.summary||!sameStringSet(decision.evidence_ids,finalization.evidenceIds)||!sameStringSet(decision.changed_files,finalization.changedFiles)){throw new UsageError(`capture-terminal decision conflicts with the persisted Gui finalization for Run ${root.run.run_id}`)}}return captureResult(existing,true)}const capture=await withLifecycleCanonicalMutationLock(filesystem,async()=>{const capture2=await composition.runs.withUsageAttributionLock(async()=>{const invocationIdentity=["codex-subagent-terminal-fallback-v1",root.run.run_id,agentPath,identity.agent].join("");const captured2=await composition.runs.withSubagentInvocationClaim(invocationIdentity,async runId=>{const existing=await composition.runs.read(runId);if(existing.status!==status){throw new UsageError(`capture-terminal status conflicts with existing Sub-Run ${existing.run.run_id}`)}return captureResult(existing,true)},async()=>{const runs=await composition.runs.list();const parent=runs.find(fold=>fold.status==="running"&&fold.run.run_id===root.run.run_id);if(parent===void 0){throw new Error(`Root Run is no longer active: ${root.run.run_id}`)}const existing=terminalFallbackExisting(runs,parent.run.run_id,agentPath,identity.agent);if(existing!==void 0){if(existing.status!==status){throw new UsageError(`capture-terminal status conflicts with existing Sub-Run ${existing.run.run_id}`)}return{runId:existing.run.run_id,value:captureResult(existing,true)}}const executionKind=parent.run.execution_kind??(parent.run.entrypoint!=="conversation"?"delivery":parent.run.execution_id===null?void 0:await composition.executions.read(parent.run.execution_id).then(({execution})=>execution.kind??"delivery").catch(()=>void 0));const runPurpose=finalizer?"finalization":"execution";const effectiveParent=executionKind===void 0?parent:{...parent,run:{...parent.run,execution_kind:executionKind}};assertChildRunMayStart(effectiveParent,runPurpose,identity.agent,runs,identity.executionEligibility);const input={shortName:`subagent-${slug(identity.agent)}-fallback`,phase:latestRunV2Phase(parent.records),runRole:"subagent",runPurpose,...executionKind===void 0?{}:{executionKind},executionEligibility:identity.executionEligibility,entrypoint:parent.run.entrypoint,workType:parent.run.work_type,client:"codex-subagent",agent:identity.agent,agentName:identity.agentName,provider:null,model:"unavailable",reasoningEffort:null,clientThreadId:agentPath,clientTurnId:null,conversationId:parent.run.conversation_id,executionId:parent.run.execution_id,taskId:parent.run.task_id,specId:parent.run.spec_id,prdId:parent.run.prd_id,changeId:parent.run.change_id,parentRunId:parent.run.run_id};await validateRunV2Attribution(input,composition);const writer=await composition.runs.start(input);const started=writer.started;const current=await composition.runs.read(started.run_id);await composition.runs.appendRecord(unavailableUsageRecord(current,parsed,current.records.length+1));const withUsage=await composition.runs.read(started.run_id);const sequence=withUsage.records.length+1;await composition.runs.appendRecord(runFinishedV2Schema.parse({schema_version:2,event_id:runV2EventId(started.run_id,sequence),run_id:started.run_id,sequence,occurred_at:new Date().toISOString(),type:"run.finished",phase:latestRunV2Phase(withUsage.records),status}));const finished=await composition.runs.read(started.run_id);return{runId:started.run_id,value:{...captureResult(finished,false),fallback:"terminal-agent-path",usage_source:"unavailable"}}},async()=>{const existing=terminalFallbackExisting(await composition.runs.list(),root.run.run_id,agentPath,identity.agent);if(existing===void 0)return null;if(existing.status!==status){throw new UsageError(`capture-terminal status conflicts with existing Sub-Run ${existing.run.run_id}`)}return{runId:existing.run.run_id,value:captureResult(existing,true)}});const terminalDecision2=finalizer?await persistTerminalFallbackDecision(root.run.run_id,captured2,finalization,composition):null;return{captured:captured2,terminalDecision:terminalDecision2}});return capture2});const{captured,terminalDecision}=capture;const result2=finalizer?{...captured,...terminalDecision===null?{}:{finalization:terminalDecision},parent_closure:await reconcileOrchestratorStop(await composition.runs.read(root.run.run_id),composition,lifecycle)}:captured;await onTerminalMutationCommitted?.(result2);return result2}function terminalFallbackExisting(runs,parentRunId,agentPath,agent){const matches=runs.filter(fold=>fold.run.parent_run_id===parentRunId&&fold.run.client_thread_id===agentPath&&fold.run.agent===agent);if(matches.length>1){throw new UsageError(`capture-terminal is ambiguous for ${agentPath}; capture the exact child session and turn`)}return matches[0]}function terminalFinalizationRequest(parsed,finalizer){const outcome=parsed.options["task-outcome"];const requested=outcome!==void 0||parsed.options.summary!==void 0||parsed.options.evidence!==void 0||parsed.options["changed-files"]!==void 0;if(!requested)return null;if(!finalizer){throw new UsageError("capture-terminal finalization decision is restricted to zaip-agent-finalizer")}if(outcome!=="completed"&&outcome!=="blocked"&&outcome!=="failed"&&outcome!=="cancelled"){throw new UsageError("capture-terminal --task-outcome must be completed, blocked, failed, or cancelled")}const summary=parsed.options.summary?.trim();if(summary===void 0||summary.length===0){throw new UsageError("capture-terminal finalization requires --summary")}return{outcome,summary,evidenceIds:csvOption2(parsed.options.evidence),changedFiles:csvOption2(parsed.options["changed-files"])}}async function persistTerminalFallbackDecision(rootRunId,captured,request,composition){if(request===null)return null;const finalizerRunId=captured.run?.run_id;if(typeof finalizerRunId!=="string"){throw new Error("capture-terminal did not return its authenticated Gui Sub-Run")}const root=await composition.runs.read(rootRunId);const finalizer=await composition.runs.read(finalizerRunId);if(root.finished!==null||finalizer.run.parent_run_id!==root.run.run_id||finalizer.run.agent!=="agent-finalizer"||effectiveRunV2Purpose(finalizer.run)!=="finalization"||finalizer.finished===null){throw new UsageError("capture-terminal finalization requires its exact terminal Gui Sub-Run")}const existing=root.finalization_decision??null;if(existing!==null){if(existing.finalizer_run_id!==finalizerRunId||existing.outcome!==request.outcome||existing.summary!==request.summary||!sameStringSet(existing.evidence_ids,request.evidenceIds)||!sameStringSet(existing.changed_files,request.changedFiles)){throw new UsageError(`Run ${root.run.run_id} already has a different Gui finalization decision`)}return existing}const record3=runFinalizationDecidedV2Schema.parse({schema_version:2,event_id:runV2EventId(root.run.run_id,root.records.length+1),run_id:root.run.run_id,sequence:root.records.length+1,occurred_at:new Date().toISOString(),type:"run.finalization.decided",finalizer_run_id:finalizerRunId,outcome:request.outcome,summary:request.summary,evidence_ids:request.evidenceIds,changed_files:request.changedFiles});await composition.runs.appendRecord(record3);return record3}function csvOption2(value){return value===void 0?[]:value.split(",").map(item=>item.trim()).filter(item=>item.length>0)}function sameStringSet(left,right){return left.length===right.length&&left.every(value=>right.includes(value))}async function captureStart(parsed,composition,identity){const[sessionId,turnId,agentId2,,model]=startValues(parsed);return composition.runs.withUsageAttributionLock(async()=>{const invocationIdentity=["codex-subagent-v1",sessionId,parsed.options["parent-agent-id"]??"",agentId2,turnId,identity.agent].join("");return composition.runs.withSubagentInvocationClaim(invocationIdentity,async runId=>captureResult(await composition.runs.read(runId),true),async()=>{const runs=await composition.runs.list();const existing=runs.find(fold=>fold.run.client_thread_id===agentId2&&fold.run.client_turn_id===turnId&&fold.run.agent===identity.agent&&(parsed.options["parent-run-id"]===void 0||fold.run.parent_run_id===parsed.options["parent-run-id"]));if(existing!==void 0){assertCapturedSubagentIdentity(existing,runs,sessionId,parsed.options["parent-agent-id"],true);return{runId:existing.run.run_id,value:captureResult(existing,true)}}const parent=selectParent(runs,sessionId,turnId,parsed.options["parent-agent-id"],parsed.options["parent-run-id"]);if(parent===void 0){throw new Error(`Cannot claim Sub-Run without parent Run for ${agentId2}`)}if(identity.role==="orchestrator"&&parent.run.parent_run_id===null&&parent.run.agent==="agent-orchestrator"){return{runId:parent.run.run_id,value:{...captureResult(parent,true),bound_to_root:true}}}const source=parent.run;const executionKind=source.execution_kind??(source.entrypoint!=="conversation"?"delivery":source.execution_id===null?void 0:await composition.executions.read(source.execution_id).then(({execution})=>execution.kind??"delivery").catch(()=>void 0));const effectiveParent=executionKind===void 0?parent:{...parent,run:{...parent.run,execution_kind:executionKind}};const runPurpose=identity.role==="execution-finalizer"?"finalization":identity.role==="reviewer"?"review":identity.role==="auditor"?"audit":"execution";assertChildRunMayStart(effectiveParent,runPurpose,identity.agent,runs,identity.executionEligibility,{allowObservedIneligibleInvocation:parsed.options["observed-local-recovery"]==="true"});const input={shortName:`subagent-${slug(identity.agent)}`,phase:latestRunV2Phase(parent.records),runRole:"subagent",runPurpose,...executionKind===void 0?{}:{executionKind},executionEligibility:identity.executionEligibility,entrypoint:source.entrypoint,workType:source.work_type,client:"codex-subagent",agent:identity.agent,agentName:identity.agentName,provider:source.provider??"openai",model,reasoningEffort:parsed.options["reasoning-effort"]===void 0?null:runV2ReasoningEffortSchema.parse(parsed.options["reasoning-effort"]),clientThreadId:agentId2,clientTurnId:turnId,conversationId:source.conversation_id,executionId:source.execution_id,taskId:source.task_id,specId:source.spec_id,prdId:source.prd_id,changeId:source.change_id,parentRunId:source.run_id};await validateRunV2Attribution(input,composition);const writer=await composition.runs.start(input);return{runId:writer.started.run_id,value:{captured:true,reused:false,run:writer.started,artifact_path:composition.runs.path(writer.started.run_id),cataloged:identity.cataloged}}},async()=>{const existing=(await composition.runs.list()).find(fold=>fold.run.client_thread_id===agentId2&&fold.run.client_turn_id===turnId&&fold.run.agent===identity.agent);if(existing===void 0)return null;assertCapturedSubagentIdentity(existing,await composition.runs.list(),sessionId,parsed.options["parent-agent-id"],true);return{runId:existing.run.run_id,value:captureResult(existing,true)}})})}async function reconcileLocalSubagentSessions(root,composition,filesystem,lifecycle,sourceOptions={},stopOnConcurrentRootAmbiguity=false){const parentThreadId=root.run.client_thread_id;const turnId=root.run.client_turn_id;if(parentThreadId==null||turnId==null){return{captured:[],skipped:[{reason:"root-correlation-unavailable"}],parent_run_id:root.run.run_id}}const concurrentRoots=(await composition.runs.list()).filter(fold=>fold.finished===null&&fold.run.parent_run_id===null&&fold.run.client_thread_id===parentThreadId);if(concurrentRoots.length>1){if(stopOnConcurrentRootAmbiguity){return{captured:[],skipped:[{reason:"local-discovery-skipped-concurrent-roots"}],parent_run_id:root.run.run_id}}throw new UsageError(`Multiple active root Runs share ${parentThreadId}; local Sub-Run discovery is ambiguous`)}const catalog=await loadAgentCatalog(filesystem);const rootStartedAt=Date.parse(root.run.occurred_at);const rootFinishedAt=root.finished===null?null:Date.parse(root.finished.occurred_at);const lifecycles=(await listCodexInvocationLifecycles(filesystem.root,{...sourceOptions,parentThreadId})).filter(item=>{const startedAt=item.startedAt===null?Number.NaN:Date.parse(item.startedAt);return Number.isFinite(startedAt)&&startedAt>=rootStartedAt&&(rootFinishedAt===null||startedAt<=rootFinishedAt)});const unique2=new Map(lifecycles.map(item=>[`${item.sessionId}${item.turnId}${item.agentPath}`,item]));const ordered=[...unique2.values()].sort((left,right)=>{const leftFinalizer=left.agentRole==="zaip-agent-finalizer"?1:0;const rightFinalizer=right.agentRole==="zaip-agent-finalizer"?1:0;return leftFinalizer-rightFinalizer||(left.startedAt??"").localeCompare(right.startedAt??"")});const captured=[];const skipped=[];for(const observed of ordered){if(observed.status==="active"||observed.status==="interrupted"){skipped.push({agent_type:observed.agentRole,agent_path:observed.agentPath,reason:observed.status==="active"?"subagent-still-active":"terminal-status-inconclusive"});continue}const taskName=observed.agentPath?.split(/[\\/]/u).filter(Boolean).at(-1)??null;const catalogAgent=catalog.agents.find(candidate=>candidate.codex_name===observed.agentRole&&candidate.codex_task_name===taskName);if(catalogAgent===void 0||observed.agentPath===null){skipped.push({agent_type:observed.agentRole,agent_path:observed.agentPath,reason:"catalog-identity-mismatch"});continue}const existingTerminal=(await composition.runs.list()).find(fold=>fold.finished!==null&&fold.run.parent_run_id===root.run.run_id&&fold.run.client_thread_id===observed.agentPath&&fold.run.client_turn_id===observed.turnId&&fold.run.agent===catalogAgent.id);if(existingTerminal!==void 0){if(existingTerminal.status!==observed.status||!hasObservedUsage(existingTerminal)){skipped.push({agent_type:observed.agentRole,agent_path:observed.agentPath,reason:"existing-terminal-subrun-conflict"});continue}captured.push({agent_type:catalogAgent.codex_name,agent_path:observed.agentPath,status:observed.status});continue}const segment2=await findLatestCodexSegment(filesystem.root,new Set,{...sourceOptions,agentPath:observed.agentPath,parentThreadId,turnId:observed.turnId});if(segment2===null||segment2.model===null){skipped.push({agent_type:observed.agentRole,agent_path:observed.agentPath,reason:"observed-model-or-segment-unavailable"});continue}const baseOptions={session:observed.sessionId,turn:observed.turnId,"agent-id":observed.agentPath,"agent-type":catalogAgent.codex_name,"parent-agent-id":parentThreadId,"parent-run-id":root.run.run_id,"observed-local-recovery":"true"};await captureStart({positionals:["subagent","capture"],flags:new Set,options:{...baseOptions,event:"start",model:segment2.model,...segment2.reasoningEffort===null?{}:{"reasoning-effort":segment2.reasoningEffort}}},composition,await subagentIdentity(filesystem,catalogAgent.codex_name));const startedChild=(await composition.runs.list()).find(fold=>fold.run.parent_run_id===root.run.run_id&&fold.run.client_thread_id===observed.agentPath&&fold.run.client_turn_id===observed.turnId&&fold.run.agent===catalogAgent.id);if(startedChild===void 0){throw new Error(`Reconciled Sub-Run was not materialized for ${observed.agentPath}`)}if(startedChild.finished!==null){if(startedChild.status!==observed.status||!hasObservedUsage(startedChild)){skipped.push({agent_type:observed.agentRole,agent_path:observed.agentPath,reason:"existing-terminal-subrun-conflict"});continue}captured.push({agent_type:catalogAgent.codex_name,agent_path:observed.agentPath,status:observed.status});continue}await recordCodexTelemetryIfAvailable(startedChild,composition,filesystem,{agentPath:observed.agentPath,parentThreadId,threadId:null,turnId:observed.turnId},[],async()=>segment2);await captureStop({positionals:["subagent","capture"],flags:new Set,options:{...baseOptions,event:"stop",status:observed.status}},composition,filesystem,lifecycle,await subagentIdentity(filesystem,catalogAgent.codex_name));captured.push({agent_type:catalogAgent.codex_name,agent_path:observed.agentPath,status:observed.status})}return{captured,skipped,parent_run_id:root.run.run_id}}async function captureStop(parsed,composition,filesystem,lifecycle,identity){const[sessionId,turnId,agentId2]=baseValues(parsed);const runs=await composition.runs.list();if(identity.role==="orchestrator"){if(lifecycle===void 0){throw new UsageError("Orchestrator reconciliation requires lifecycle services")}const root=selectParent(runs,sessionId,turnId,parsed.options["parent-agent-id"],parsed.options["parent-run-id"])??runs.find(candidate=>candidate.finished!==null&&candidate.run.parent_run_id===null&&candidate.run.agent==="agent-orchestrator"&&candidate.run.client_thread_id===sessionId&&candidate.run.client_turn_id===turnId);if(root===void 0||root.run.parent_run_id!==null||root.run.agent!=="agent-orchestrator"){return{captured:false,reason:"root-run-not-found",agent_id:agentId2}}const current2=await recordCodexTelemetryIfAvailable(root,composition,filesystem,{agentPath:agentId2,parentThreadId:sessionId,threadId:null,turnId:null});const closure=await reconcileOrchestratorStop(current2,composition,lifecycle);const settled=closure===null?current2:await composition.runs.read(current2.run.run_id);return{...captureResult(settled,true),bound_to_root:true,closure}}const status=terminalStatus(parsed.options.status??"completed");const child=runs.find(fold=>fold.run.client_thread_id===agentId2&&fold.run.client_turn_id===turnId&&fold.run.agent===identity.agent&&(parsed.options["parent-run-id"]===void 0||fold.run.parent_run_id===parsed.options["parent-run-id"]));if(child===void 0){if(parsed.options["parent-run-id"]!==void 0&&runs.some(fold=>fold.run.client_thread_id===agentId2&&fold.run.client_turn_id===turnId&&fold.run.agent===identity.agent)){throw new UsageError("Sub-Run identity conflicts with explicit --parent-run-id")}return{captured:false,reused:true,status,reason:"pending-subagent-start",agent_id:agentId2,recovery:"replay-stop-after-start"}}assertCapturedSubagentIdentity(child,runs,sessionId,parsed.options["parent-agent-id"]);if(child.finished!==null){if(child.status!==status){throw new UsageError(`subagent stop status conflicts with existing Sub-Run ${child.run.run_id}`)}return captureResult(child,true)}let current=await recordCodexTelemetryIfAvailable(child,composition,filesystem);for(let attempt=0;attempt<4&&!hasObservedUsage(current);attempt+=1){await new Promise(resolve10=>setTimeout(resolve10,100*2**attempt));current=await recordCodexTelemetryIfAvailable(current,composition,filesystem)}const captured=await composition.runs.withUsageAttributionLock(async()=>{current=await composition.runs.read(child.run.run_id);if(current.finished!==null){if(current.status!==status){throw new UsageError(`subagent stop status conflicts with existing Sub-Run ${current.run.run_id}`)}return captureResult(current,true)}if(current.effective_usage_records.length===0){const usage=unavailableUsageRecord(current,parsed,current.records.length+1);await composition.runs.appendRecord(usage);current=foldRunV2Records([...current.records,usage])}const sequence=current.records.length+1;await composition.runs.appendRecord(runFinishedV2Schema.parse({schema_version:2,event_id:runV2EventId(current.run.run_id,sequence),run_id:current.run.run_id,sequence,occurred_at:new Date().toISOString(),type:"run.finished",phase:latestRunV2Phase(current.records),status}));return captureResult(await composition.runs.read(current.run.run_id),false)});if(identity.agent==="agent-finalizer"){const parent=(await composition.runs.list()).find(candidate=>candidate.run.run_id===child.run.parent_run_id);if(parent!==void 0&&lifecycle!==void 0){const closure=await reconcileOrchestratorStop(parent,composition,lifecycle);return{...captured,parent_closure:closure}}}return captured}async function reconcileOrchestratorStop(current,composition,lifecycle){return composition.runs.withUsageAttributionLock(async()=>{const fresh=await composition.runs.read(current.run.run_id);const candidates=await composition.runs.list();const active=activeDescendantRuns(fresh.run.run_id,candidates);if(active.length>0){return{status:"pending_descendants",parent_run_id:fresh.run.run_id,active_run_ids:active.map(candidate=>candidate.run.run_id)}}if(fresh.finished!==null)return reconcileTerminalOrchestratorRoot(fresh,candidates,composition,lifecycle);const sequence=fresh.records.length+1;await composition.runs.appendRecord(runFinishedV2Schema.parse({schema_version:2,event_id:runV2EventId(fresh.run.run_id,sequence),run_id:fresh.run.run_id,sequence,occurred_at:new Date().toISOString(),type:"run.finished",phase:latestRunV2Phase(fresh.records),status:"completed"}));const finishedRoot=await composition.runs.read(fresh.run.run_id);return reconcileTerminalOrchestratorRoot(finishedRoot,await composition.runs.list(),composition,lifecycle)})}async function subagentIdentity(filesystem,rawAgentType){const agentType=rawAgentType.trim();const catalog=await loadAgentCatalog(filesystem);const agent=catalog.agents.find(candidate=>candidate.codex_name===agentType||candidate.id===agentType);return agent===void 0?{agent:`unrecognized-subagent:${slug(agentType)}`,agentName:agentType,codexTaskName:null,role:null,capabilities:[],executionEligibility:[],cataloged:false}:{agent:agent.id,agentName:agent.codex_name,codexTaskName:agent.codex_task_name,role:agent.role,capabilities:agent.capabilities,executionEligibility:agent.execution_eligibility,cataloged:true}}function selectParent(runs,sessionId,turnId,parentAgentId,parentRunId){const explicitParent=parentAgentId?.trim();const explicitRun=parentRunId?.trim();if(explicitRun!==void 0&&explicitRun.length>0){if(explicitParent===void 0||explicitParent.length===0){throw new UsageError("--parent-run-id requires --parent-agent-id")}return runs.find(fold=>fold.status==="running"&&fold.run.run_id===explicitRun&&fold.run.client_thread_id===explicitParent)}if(explicitParent!==void 0&&explicitParent.length>0){const candidates=runs.filter(fold=>fold.status==="running"&&fold.run.client_thread_id===explicitParent);if(candidates.length>1){throw new UsageError(`Multiple active root Runs share ${explicitParent}; pass --parent-run-id for exact attribution`)}return candidates[0]}return runs.filter(fold=>fold.status==="running"&&fold.run.parent_run_id===null&&fold.run.client_thread_id===sessionId&&fold.run.client_turn_id===turnId).sort((left,right)=>right.run.occurred_at.localeCompare(left.run.occurred_at))[0]}function assertCapturedSubagentIdentity(child,runs,sessionId,rawParentAgentId,requireRootSession=false){const parent=child.run.parent_run_id===null?void 0:runs.find(candidate=>candidate.run.run_id===child.run.parent_run_id);const declaredParent=rawParentAgentId?.trim();if(parent===void 0||declaredParent!==void 0&&declaredParent.length>0&&parent.run.client_thread_id!==declaredParent){throw new UsageError(`Sub-Run identity conflicts with existing Run ${child.run.run_id}`)}if(declaredParent!==void 0&&declaredParent.length>0&&!requireRootSession)return;let root=parent;while(root.run.parent_run_id!==null){const next=runs.find(candidate=>candidate.run.run_id===root.run.parent_run_id);if(next===void 0){throw new UsageError(`Sub-Run identity conflicts with existing Run ${child.run.run_id}`)}root=next}if(root.run.client_thread_id!==sessionId){throw new UsageError(`Sub-Run identity conflicts with existing Run ${child.run.run_id}`)}}function normalizeSubagentSessionOption(parsed){const alias=parsed.options["session-id"];const session=parsed.options.session;if(alias!==void 0&&session!==void 0&&alias!==session){throw new UsageError("--session and --session-id must match when both are provided")}if(session!==void 0||alias===void 0)return parsed;return{...parsed,options:{...parsed.options,session:alias}}}function baseValues(parsed){return["session","turn","agent-id","agent-type"].map(name=>{const value=parsed.options[name]?.trim();if(value===void 0||value.length===0||value.length>200){throw new UsageError(`--${name} must contain 1 to 200 characters`)}return value})}function optionValue(parsed,name){const value=parsed.options[name]?.trim();if(value===void 0||value.length===0||value.length>200){throw new UsageError(`--${name} must contain 1 to 200 characters`)}return value}function terminalStatus(value){if(value==="completed"||value==="failed"||value==="cancelled")return value;throw new UsageError("--status must be completed, failed, or cancelled")}function startValues(parsed){const model=parsed.options.model?.trim();if(model===void 0||model.length===0||model.length>200){throw new UsageError("--model must contain 1 to 200 characters")}return[...baseValues(parsed),model]}function captureResult(fold,reused){return{captured:true,reused,run:fold.run,status:fold.status}}function slug(value){return value.normalize("NFKD").replace(/[\u0300-\u036f]/g,"").toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,60)||"worker"}async function runValidationV2Command(action,parsed,filesystem,composition){if(action==="observe")return recordEvidenceObservation(parsed,filesystem,composition);if(action!=="record")throw new UsageError(`Unknown V2 Validation action: ${action??""}`);assertSafeRecordContent(parsed.options);requireOptions(parsed.options,["id","task","acceptance","command","outcome","locators","run"]);const outcome=parsed.options.outcome;if(outcome!=="passed"&&outcome!=="failed"&&outcome!=="not_applicable")throw new UsageError("validation record requires --outcome passed, failed, or not_applicable");const kindResult=assuranceValidationKindSchema.safeParse(parsed.options.kind??"test");if(!kindResult.success)throw new UsageError(`Invalid Validation kind: ${parsed.options.kind}`);const kind=kindResult.data;const id=parsed.options.id;const prefix=validationPrefix(kind);if(!id.startsWith(prefix))throw new UsageError(`Invalid ${kind} Validation id: ${id}`);const taskId=parsed.options.task;const mutation=kind==="mutation"?await mutationDiscrimination(parsed.options,filesystem):null;const{task}=await composition.tasks.read(taskId);const acceptanceIds=String(parsed.options.acceptance).split(",").filter(Boolean);if(acceptanceIds.length===0||acceptanceIds.some(id2=>!task.acceptance_ids.includes(id2))){throw new UsageError("Validation Acceptance Criteria must belong to the Task")}const executionId=resolveTaskExecutionIdV2(task,await composition.executions.list(),parsed.options.execution);const runId=parsed.options.run;const{run}=await composition.runs.read(runId);if(run.task_id!==taskId||run.change_id!==task.change_id||run.execution_id!==executionId){throw new UsageError(`Run does not link Task, Change, and Execution: ${runId}`)}const artifact=validationArtifactV2Schema.parse({schema_version:2,id,kind,task_id:taskId,change_id:task.change_id,execution_id:executionId,run_id:runId,acceptance_ids:acceptanceIds,executed_at:parsed.options["executed-at"]??new Date().toISOString(),command:parsed.options.command,status:outcome,asserted_outcomes:String(parsed.options["asserted-outcome"]??parsed.options.asserted??`validation ${outcome}`).split(",").filter(Boolean),locators:String(parsed.options.locators).split(",").filter(Boolean),author_id:parsed.options.author??"cli",commit_sha:parsed.options.commit??null,not_applicable_reason:outcome==="not_applicable"?parsed.options.reason??null:null});const directory=composition.changes.path(task.change_id).replace(/\/change\.md$/,"");const path=`${directory}/artifacts/tests/${id}.md`;await filesystem.writeTextAtomicExclusive(path,serializeMarkdown({metadata:artifact,body:`# Validation ${id}
|
|
1601
|
+
`;if(Buffer.byteLength(serialized,"utf8")>64*1024)throw new Error("Unmatched Codex telemetry envelope exceeds the 64 KiB sanitized limit");try{await filesystem.writeTextAtomicExclusive(`.local/codex-telemetry-spool/v1/unmatched/${digest6.slice(0,2)}/${digest6}.json`,serialized)}catch(error51){if(!(error51 instanceof Error&&"code"in error51&&error51.code==="EEXIST"))throw error51}}function sanitizeAppServerNotification(input,capturedAt){const notification=hostObject(input,"Codex app-server notification");const method=String(notification.method);if(!["item/completed","rawResponse/completed","thread/tokenUsage/updated","error","turn/completed"].includes(method))return null;const params=hostObject(notification.params,`${method} params`);const threadId=hostString(params.threadId,`${method} threadId`);const rawAgentPath=params.agentPath??params.agent_path;const agentPath=rawAgentPath===void 0?null:hostString(rawAgentPath,`${method} agentPath`);const occurredAt=hostTimestamp(notification.emittedAtMs);const wrap=(turnId2,event)=>({threadId,turnId:turnId2,agentPath,event:{source:"codex_app_server",source_occurred_at:occurredAt,captured_at:capturedAt,coverage:"complete",provider:null,model:null,runtime:{reasoning_effort:null,service_tier:null},latency_ms:null,context_stats:null,...event}});if(method==="item/completed"){const turnId2=hostString(params.turnId,`${method} turnId`);const item=hostObject(params.item,`${method} item`);return wrap(turnId2,{event_kind:"response",source_method:method,stream_boundary:"item_completed",source_event_key:hostSourceKey(`${threadId}:${turnId2}:item:${hostString(item.id,`${method} item id`)}`,"item"),source_occurred_at:hostTimestamp(params.completedAtMs)??occurredAt,tokens:null,status:null,discarded_counts:discardedItem(String(item.type??""),item)})}if(method==="rawResponse/completed"){const turnId2=hostString(params.turnId,`${method} turnId`);return wrap(turnId2,{event_kind:"response",source_method:method,stream_boundary:"response_completed",source_event_key:hostSourceKey(`${threadId}:${turnId2}:raw-response:${hostString(params.responseId,`${method} responseId`)}`,"response"),tokens:params.usage===null?null:hostTokens(params.usage,method),status:null,discarded_counts:{...emptyDiscarded(),response_text:Number(typeof params.output==="string")}})}if(method==="thread/tokenUsage/updated"){const turnId2=hostString(params.turnId,`${method} turnId`);const tokens=hostTokens(hostObject(params.tokenUsage,`${method} tokenUsage`).total,method);const suffix=notification.emittedAtMs===void 0?hostDigest(JSON.stringify(tokens)).slice(0,24):String(notification.emittedAtMs);return wrap(turnId2,{event_kind:"usage",source_method:method,stream_boundary:"usage_updated",source_event_key:hostSourceKey(`${threadId}:${turnId2}:token-usage:${suffix}`,"usage"),tokens,status:null,discarded_counts:emptyDiscarded()})}if(method==="error"){const turnId2=hostString(params.turnId,`${method} turnId`);const error52=isHostObject(params.error)?params.error:{};const suffix=notification.emittedAtMs===void 0?hostDigest(JSON.stringify([params.willRetry===true,error52.codexErrorInfo??null])).slice(0,24):String(notification.emittedAtMs);return wrap(turnId2,{event_kind:"error",source_method:method,stream_boundary:"error",source_event_key:hostSourceKey(`${threadId}:${turnId2}:error:${suffix}`,"error"),tokens:null,status:params.willRetry===true?null:"failed",will_retry:params.willRetry===true,discarded_counts:{...emptyDiscarded(),secrets:Number(typeof error52.message==="string")+Number(typeof error52.additionalDetails==="string")}})}const turn=hostObject(params.turn,"turn/completed turn");const turnId=hostString(turn.id,"turn/completed turn id");if(!["completed","failed","interrupted"].includes(String(turn.status)))throw new Error(`turn/completed has non-terminal status: ${String(turn.status)}`);const discarded=(Array.isArray(turn.items)?turn.items.filter(isHostObject):[]).map(item=>discardedItem(String(item.type??""),item)).reduce(addDiscarded,emptyDiscarded());const error51=isHostObject(turn.error)?turn.error:{};return wrap(turnId,{event_kind:"terminal",source_method:"turn/completed",stream_boundary:"turn_completed",source_event_key:hostSourceKey(`${threadId}:${turnId}:terminal`,"terminal"),source_occurred_at:hostTimestamp(typeof turn.completedAt==="number"?turn.completedAt*1e3:turn.completedAt)??occurredAt,tokens:null,status:turn.status==="interrupted"?"cancelled":turn.status,latency_ms:Number.isSafeInteger(turn.durationMs)&&Number(turn.durationMs)>=0?Number(turn.durationMs):null,discarded_counts:{...discarded,secrets:discarded.secrets+Number(typeof error51.message==="string")+Number(typeof error51.additionalDetails==="string")}})}var emptyDiscarded=()=>({prompt:0,response_text:0,reasoning:0,secrets:0});var addDiscarded=(left,right)=>({prompt:left.prompt+right.prompt,response_text:left.response_text+right.response_text,reasoning:left.reasoning+right.reasoning,secrets:left.secrets+right.secrets});var discardedItem=(type,item)=>({prompt:Number(["userMessage","hookPrompt","function_call","custom_tool_call"].includes(type)),response_text:Number(["agentMessage","plan","message","agent_message"].includes(type)),reasoning:Number(type==="reasoning"),secrets:Number(typeof item.encrypted_content==="string")+Number(item.internal_chat_message_metadata_passthrough!==void 0)});var isHostObject=value=>typeof value==="object"&&value!==null&&!Array.isArray(value);function hostObject(value,label){if(!isHostObject(value))throw new Error(`${label} must be an object`);return value}function hostString(value,label){if(typeof value!=="string"||value.length===0)throw new Error(`${label} must be a non-empty string`);return value}function hostCount(value,label){if(!Number.isSafeInteger(value)||Number(value)<0)throw new Error(`${label} must be a non-negative safe integer`);return Number(value)}var hostTimestamp=value=>typeof value==="number"&&Number.isFinite(value)&&value>=0?new Date(value).toISOString():null;var hostDigest=value=>createHash28("sha256").update(value).digest("hex");var hostSourceKey=(value,prefix)=>value.length<=500?value:`${prefix}:${hostDigest(value)}`;function hostTokens(value,label){const usage=hostObject(value,`${label} usage`);return{input:hostCount(usage.inputTokens,`${label} inputTokens`),cached_input:hostCount(usage.cachedInputTokens,`${label} cachedInputTokens`),output:hostCount(usage.outputTokens,`${label} outputTokens`),reasoning:hostCount(usage.reasoningOutputTokens,`${label} reasoningOutputTokens`),total:hostCount(usage.totalTokens,`${label} totalTokens`),source:"provider_reported"}}function parseCodexAppServerNotificationStream(content){const normalized=content.trim();if(normalized.length===0)return[];if(normalized.startsWith("[")){const parsed=JSON.parse(normalized);if(!Array.isArray(parsed))throw new Error("Codex app-server event stream must be an array");return parsed}return normalized.split(/\r?\n/).map(line=>line.trim()).filter(Boolean).map(line=>JSON.parse(line))}async function recordNativeCodexUsage(current,composition,events){const exactCalls=events.filter(event=>event.event.stream_boundary==="response_completed"&&event.event.tokens!==null);const latestCumulative=events.findLast(event=>event.event.stream_boundary==="usage_updated"&&event.event.tokens!==null);const terminal=events.findLast(event=>event.event.stream_boundary==="turn_completed"||event.event.stream_boundary==="error"&&event.event.will_retry!==true);const usageEvents=exactCalls.length>0?exactCalls:latestCumulative?[latestCumulative]:[];if(usageEvents.length===0&&terminal===void 0)return current;let fresh=current;let sequence=current.records.length+1;const agentInvocationId=current.run.agent_invocation_id??`AINV-${current.run.run_id.slice("RUN-".length)}`;for(const call of exactCalls){const event=call.event;if(event.tokens===null)continue;const coverage2=terminal===void 0?"partial":"complete";const existing=fresh.model_call_records.find(record3=>record3.source_call_key===event.source_event_key);if(existing===void 0||existing.coverage==="partial"&&coverage2==="complete"){await composition.runs.appendRecord(modelCallObservedV3Schema.parse({schema_version:2,event_id:`${current.run.run_id}:${String(sequence).padStart(6,"0")}`,run_id:current.run.run_id,sequence:sequence++,occurred_at:event.captured_at,type:"model.call.observed",call_id:modelCallId(event.source_event_key),agent_invocation_id:agentInvocationId,coverage:coverage2,tokens:event.tokens,cost:{usd:null,brl:null},provider:event.provider,model:event.model,source_call_key:event.source_event_key,...event.source_occurred_at===null?{}:{source_occurred_at:event.source_occurred_at},runtime:event.runtime}));fresh=await composition.runs.read(current.run.run_id)}}const sourceSegmentKey=`codex-app-server:${current.run.run_id}`;if(usageEvents.length>0&&!fresh.effective_usage_records.some(record3=>record3.source_segment_key===sourceSegmentKey)){const tokens=sumObservedUsage(usageEvents.map(event=>event.event.tokens));await composition.runs.appendRecord(usageRecordedV2Schema.parse({schema_version:2,event_id:`${current.run.run_id}:${String(sequence).padStart(6,"0")}`,run_id:current.run.run_id,sequence:sequence++,occurred_at:new Date().toISOString(),type:"usage.recorded",phase:latestPhase(current),activity_kind:"implementation",classification_source:"current_context",tokens,cost:{usd:null,brl:null},provider:commonObservedValue(usageEvents.map(event=>event.event.provider)),model:commonObservedValue(usageEvents.map(event=>event.event.model)),source_segment_key:sourceSegmentKey,runtime:{reasoning_effort:commonObservedValue(usageEvents.map(event=>event.event.runtime.reasoning_effort)),service_tier:commonObservedValue(usageEvents.map(event=>event.event.runtime.service_tier))},supersedes_event_id:unavailableUsageEventId(current),...latestSourceTimestamp(usageEvents)===null?{}:{source_occurred_at:latestSourceTimestamp(usageEvents)}}));fresh=await composition.runs.read(current.run.run_id)}if(terminal===void 0||terminal.event.status===null)return fresh;const callKeys=exactCalls.length>0?exactCalls.map(call=>call.event.source_event_key):[terminal.event.source_event_key];for(const callKey of callKeys){const invocationId2=providerInvocationId(callKey);if(!fresh.model_selection_records.some(record3=>record3.invocation_id===invocationId2)){await composition.runs.appendRecord(modelSelectionRecordedV2Schema.parse({schema_version:2,event_id:`${current.run.run_id}:${String(sequence).padStart(6,"0")}`,run_id:current.run.run_id,sequence:sequence++,occurred_at:terminal.event.captured_at,type:"model.selection.recorded",invocation_id:invocationId2,requested:{model:current.run.model,reasoning_effort:current.run.reasoning_effort??null,velocity:"standard"},selection:{source:"execution-override",policy_version:1,reasons:["host-run-header"]}}));fresh=await composition.runs.read(current.run.run_id)}if(!fresh.provider_invocation_records.some(record3=>record3.invocation_id===invocationId2)){await composition.runs.appendRecord(providerInvocationFinishedV2Schema.parse({schema_version:2,event_id:`${current.run.run_id}:${String(sequence).padStart(6,"0")}`,run_id:current.run.run_id,sequence:sequence++,occurred_at:terminal.event.captured_at,type:"provider.invocation.finished",invocation_id:invocationId2,status:terminal.event.status,effective:{provider:terminal.event.provider,model:terminal.event.model,reasoning_effort:terminal.event.runtime.reasoning_effort,service_tier:terminal.event.runtime.service_tier},latency_ms:terminal.event.latency_ms}));fresh=await composition.runs.read(current.run.run_id)}}return fresh}async function resolveRunClientInvocation(filesystem,client,options={}){if(!new Set(["codex","codex-desktop"]).has(client)){return{clientThreadId:null,clientTurnId:null,userMessage:null,observedModel:null,observedReasoningEffort:null,observedServiceTier:null}}const threadId=normalizedId(options.threadId??process.env.CODEX_THREAD_ID);const turnId=normalizedId(options.turnId??process.env.CODEX_TURN_ID);const active=await findActiveCodexInvocation(filesystem.root,{threadId,...options.sessionsRoot===void 0?{}:{sessionsRoot:options.sessionsRoot},...options.now===void 0?{}:{now:options.now}});return{clientThreadId:threadId??active?.sessionId??null,clientTurnId:turnId??active?.turnId??null,userMessage:active?.userMessage??null,observedModel:active?.model??null,observedReasoningEffort:active?.reasoningEffort??null,observedServiceTier:active?.serviceTier??null}}function normalizedId(value){const normalized=value?.trim();return normalized===void 0||normalized.length===0?null:normalized}function activeDescendantRuns(rootRunId,candidates){return descendantRuns(rootRunId,candidates).filter(candidate=>candidate.finished===null)}function descendantRuns(rootRunId,candidates){const descendants=[];const parentIds=new Set([rootRunId]);let discovered=true;while(discovered){discovered=false;for(const candidate of candidates){if(candidate.run.parent_run_id!==null&&parentIds.has(candidate.run.parent_run_id)&&!parentIds.has(candidate.run.run_id)){parentIds.add(candidate.run.run_id);descendants.push(candidate);discovered=true}}}return descendants}function finalizationBarrierBlockReason(barrier){if(barrier.required&&barrier.status==="evidence_missing"){return"Finalization barrier evidence_missing; resume after passed typed Evidence linked to the same Task, Change, Execution, and Run"}return barrier.required&&!barrier.satisfied?`Finalization barrier ${barrier.status}; resume after a completed zaip-agent-finalizer Sub-Run with authoritative metadata`:null}function assessRunFinalizationBarrier(parent,candidates,evidenceSatisfied=false){const required2=runV2RequiresFinalizer(parent.run)||descendantRuns(parent.run.run_id,candidates).length>0;const evidenceRequired=parent.run.execution_kind==="delivery";if(!required2){return{required:false,evidence_required:false,evidence_satisfied:true,status:"not_required",finalizer_run_id:null,satisfied:true}}const finalizer=directFinalizers(parent.run.run_id,candidates).at(-1);if(finalizer===void 0){return{required:true,evidence_required:evidenceRequired,evidence_satisfied:!evidenceRequired||evidenceSatisfied,status:"missing",finalizer_run_id:null,satisfied:false}}const evidenceAccepted=!evidenceRequired||evidenceSatisfied;const status=finalizer.status==="completed"&&!evidenceAccepted?"evidence_missing":finalizer.status;return{required:true,evidence_required:evidenceRequired,evidence_satisfied:evidenceAccepted,status,finalizer_run_id:finalizer.run.run_id,satisfied:status==="completed"&&evidenceAccepted}}function assertChildRunMayStart(parent,purpose,agent,candidates,executionEligibility=[],options={}){if(parent.finished!==null)throw new Error(`Parent Run is already finished: ${parent.run.run_id}`);const crossedBarrier=ancestorLineage(parent,candidates).find(ancestor=>directFinalizers(ancestor.run.run_id,candidates).length>0);if(crossedBarrier!==void 0){throw new Error(`Run ${crossedBarrier.run.run_id} crossed its finalization barrier; no new Sub-Run may start`)}const executionKind=parent.run.execution_kind;if(purpose==="execution"&&options.allowObservedIneligibleInvocation!==true&&(executionKind===void 0||!executionEligibility.includes(executionKind))){throw new Error(`Agent ${agent} lacks an execution capability for Run ${parent.run.run_id}`)}if(purpose==="finalization"&&agent!=="agent-finalizer"){throw new Error(`Finalizer for Run ${parent.run.run_id} requires agent-finalizer`)}if(purpose!=="finalization")return;if(effectiveRunV2Role(parent.run)==="orchestrator"&&directExecutors(parent.run.run_id,executionKind,candidates).length===0){throw new Error(`Finalizer for Execution Run ${parent.run.run_id} requires a prior capable executor Sub-Run`)}const active=activeDescendantRuns(parent.run.run_id,candidates);if(active.length>0){throw new Error(`Finalizer for Run ${parent.run.run_id} must be the last Sub-Run; active descendants: ${active.map(run=>run.run.run_id).join(", ")}`)}}function directExecutors(parentRunId,executionKind,candidates){return candidates.filter(candidate=>candidate.run.parent_run_id===parentRunId&&effectiveRunV2Purpose(candidate.run)==="execution"&&(executionKind!==void 0&&candidate.run.execution_eligibility?.includes(executionKind)===true||executionKind===void 0&&candidate.run.execution_eligibility===void 0&&candidate.run.agent==="agent-task-executor")&&candidate.run.agent!=="agent-finalizer")}function ancestorLineage(parent,candidates){const byId2=new Map(candidates.map(candidate=>[candidate.run.run_id,candidate]));const lineage=[];const visited=new Set;let current=parent;while(current!==void 0&&!visited.has(current.run.run_id)){lineage.push(current);visited.add(current.run.run_id);current=current.run.parent_run_id===null?void 0:byId2.get(current.run.parent_run_id)}return lineage}function directFinalizers(parentRunId,candidates){return candidates.filter(candidate=>candidate.run.parent_run_id===parentRunId&&effectiveRunV2Purpose(candidate.run)==="finalization"&&(candidate.run.agent==="agent-finalizer"||candidate.run.agent==="agent-task-finalizer")).sort((left,right)=>left.run.occurred_at.localeCompare(right.run.occurred_at))}async function hasPassedTypedEvidenceForRun(run,evidenceIds,composition,candidates=[]){if(run.run.execution_kind!=="delivery")return true;if(run.run.execution_id===null||evidenceIds.length===0){return false}const tasks=await evidenceTasks(run,composition);if(tasks.length===0)return false;const requested=new Set(evidenceIds);const bundle=await readAssuranceBundle(composition.filesystem,composition.layout,tasks,[...requested]);const eligible=await Promise.all(bundle.evidences.map(async evidence=>{const task=tasks.find(candidate=>evidence.task_id===candidate.id&&evidence.change_id===candidate.change_id);return requested.has(evidence.id)&&evidence.status==="passed"&&task!==void 0&&evidence.execution_id===run.run.execution_id&&completedEvidenceRun(evidence.run_id,run,task,composition,candidates)}));return bundle.evidences.length===requested.size&&eligible.every(Boolean)&&(run.run.task_id===null||sharesCandidate(bundle.evidences))}async function passedTypedEvidenceIdsForRun(run,composition,candidates=[]){if(run.run.execution_kind!=="delivery"||run.run.execution_id===null){return[]}const tasks=await evidenceTasks(run,composition);if(tasks.length===0)return[];const bundle=await readAssuranceBundle(composition.filesystem,composition.layout,tasks);const eligible=await Promise.all(bundle.evidences.map(async evidence=>{const task=tasks.find(candidate=>evidence.task_id===candidate.id&&evidence.change_id===candidate.change_id);return evidence.status==="passed"&&task!==void 0&&evidence.execution_id===run.run.execution_id&&await completedEvidenceRun(evidence.run_id,run,task,composition,candidates)?evidence.id:null}));return eligible.filter(id=>id!==null).sort()}async function evidenceTasks(run,composition){if(run.run.task_id!==null)return[(await composition.tasks.read(run.run.task_id)).task];if(run.run.execution_id===null||run.run.spec_id===null&&run.run.prd_id===null)return[];const execution=(await composition.executions.read(run.run.execution_id)).execution;const scopeMatches2=run.run.prd_id!==null?execution.origin.type==="prd"&&execution.origin.prd_id===run.run.prd_id:execution.origin.type==="spec"&&execution.origin.spec_id===run.run.spec_id;if(execution.status!=="completed"||!scopeMatches2)return[];return Promise.all(execution.dag.nodes.map(async node=>(await composition.tasks.read(node.task_id)).task))}async function completedEvidenceRun(id,root,task,composition,candidates){if(root.run.task_id===null&&(task.status!=="completed"||task.result?.completed_run_id!==id)){return false}try{const run=await composition.runs.read(id);return(id===root.run.run_id||run.status==="completed")&&run.run.execution_id===root.run.execution_id&&run.run.task_id===task.id&&run.run.change_id===task.change_id&&run.run.conversation_id===root.run.conversation_id&&(root.run.task_id===null||belongsToRoot(id,root.run.run_id,candidates))}catch{return false}}function belongsToRoot(evidenceRunId,rootRunId,candidates){return evidenceRunId===rootRunId||descendantRuns(rootRunId,candidates).some(candidate=>candidate.run.run_id===evidenceRunId)}function sharesCandidate(evidences){const identities=new Set(evidences.map(evidence=>evidence.commit_sha));if(identities.size>1)return false;return identities.has(null)?evidences.length===1:true}async function assessRunLifecycleClosure(current,composition,candidateRuns){const role=effectiveRunV2Role(current.run);if(role==="intake"||role==="subagent"){return emptyClosure(current.run.run_id)}const subjects=(await Promise.all(current.run.entrypoint==="task"?[subject("task",current.run.task_id,composition,role,current)]:[subject("spec",current.run.spec_id,composition,role,current),subject("prd",current.run.prd_id,composition,role,current)])).filter(item=>item!==null);void candidateRuns;const openSubjectIds=subjects.filter(item=>!item.settled).map(item=>item.id);const status=subjects.length===0?"not_applicable":openSubjectIds.length===0?"closed":"action_required";return{status,run_id:current.run.run_id,continuation_run_id:null,subjects,open_subject_ids:openSubjectIds,default_inconclusive_outcome:"blocked",allowed_terminal_outcomes:["completed","blocked","failed","cancelled"],guidance:status==="action_required"?"Start an attributed continuation Run or settle every related work item; use blocked by default, failed only for an execution-preventing error, and cancelled only after an explicit user cancellation.":"Run lifecycle closure is satisfied."}}async function subject(kind,id,composition,role,current){if(id===null)return null;try{const status=kind==="task"?(await composition.tasks.read(id)).task.status:kind==="spec"?(await composition.specs.read(id)).spec.status:(await composition.prds.read(id)).prd.status;return{kind,id,status,settled:isSettled(kind,status,role,current)}}catch{return{kind,id,status:"missing",settled:false}}}function isSettled(kind,status,role,current){if(kind==="task")return["completed","blocked","failed","cancelled"].includes(status);if(role==="orchestrator"&¤t.finished?.status==="completed")return status!=="missing";return["delivered","blocked","failed","cancelled"].includes(status)}function emptyClosure(runId){return{status:"not_applicable",run_id:runId,continuation_run_id:null,subjects:[],open_subject_ids:[],default_inconclusive_outcome:"blocked",allowed_terminal_outcomes:["completed","blocked","failed","cancelled"],guidance:"Run lifecycle closure is satisfied."}}function lifecycleReconciliationOutcome(value){if(value===void 0)return void 0;if(value==="completed"||value==="blocked"||value==="failed"||value==="cancelled"){return value}throw new Error("--task-outcome must be completed, blocked, failed, or cancelled")}function lifecycleOutcomeOption(options){if(options["owner-outcome"]!==void 0){throw new Error("Legacy lifecycle outcome option is no longer supported; use --task-outcome")}return lifecycleReconciliationOutcome(options["task-outcome"])}var SETTLEABLE_TASK=new Set(["draft","planned","executing","verifying"]);var SETTLEABLE_CHANGE=new Set(["draft","planned","executing","verifying"]);var SETTLEABLE_EXECUTION=new Set(["planned","running","paused","verifying"]);var MISSING_GUI_FINALIZATION_REASON="Finalization barrier missing; resume after a completed zaip-agent-finalizer Sub-Run with authoritative metadata";var MISSING_GUI_DECISION_REASON="Orchestrator stopped without a persisted Gui finalization decision; lifecycle was fail-closed as blocked.";function isTaskAttemptRun(current){return effectiveRunV2Role(current.run)==="orchestrator"&¤t.run.parent_run_id===null&&(current.run.entrypoint==="task"||current.run.work_type==="rework"&¤t.run.task_id!==null)}async function reconcileFinishedRunLifecycle(current,composition,lifecycle,options={}){if(current.finished===null)throw new Error(`Run is still running: ${current.run.run_id}`);const role=effectiveRunV2Role(current.run);if(role==="intake"||role==="subagent"){return emptyResult(current.run.run_id,"not_applicable")}if(current.run.execution_id!==null){const execution=await composition.executions.read(current.run.execution_id).catch(()=>null);if(execution?.execution.kind==="interaction"){return emptyResult(current.run.run_id,"not_applicable")}}if(options.defer===true){throw new Error(`Orchestrator Run closure cannot be deferred for Run ${current.run.run_id}`)}const closure=await assessRunLifecycleClosure(current,composition,options.candidateRuns);if(closure.status==="not_applicable")return emptyResult(current.run.run_id,"not_applicable");const catalog=options.catalog??await loadCatalog(composition);const graph=relatedGraph(current,catalog);const requested=resolveOutcome(current,graph.tasks,options.requestedOutcome,options.forceRequestedOutcome);if(requested==="completed"){try{const resumable=await resumeOwnCompletionGateBlocks(current,graph,composition,lifecycle,options.candidateRuns);const completed=await completeGraph(current,resumable,composition,lifecycle,options);return{...completed,status:"closed",outcome:"completed"}}catch(error51){const message=error51 instanceof Error?error51.message:String(error51);const blocked=await settleGraph(current,await refreshGraph(graph,composition),composition,lifecycle,"blocked",`Completion gates did not close Run ${current.run.run_id}: ${message}`);return{...blocked,status:"closed",outcome:"blocked",fallback_from:"completed",error:message}}}const settled=await settleGraph(current,graph,composition,lifecycle,requested,options.summary===void 0?defaultReason(current.run.run_id,requested):`${options.summary} (Run ${current.run.run_id}).`);return{...settled,status:"closed",outcome:requested}}async function snapshotRunLifecycle(current,composition,catalog){const role=effectiveRunV2Role(current.run);if(role==="intake"||role==="subagent"){return emptyResult(current.run.run_id,"not_applicable")}const graph=relatedGraph(current,catalog??await loadCatalog(composition));return currentGraphResult(current.run.run_id,await refreshGraph(graph,composition))}async function resumeOwnCompletionGateBlocks(current,graph,composition,lifecycle,candidateRuns){if(current.finalization_decision?.outcome!=="completed")return graph;const eligiblePredecessors=new Set(await completionGatePredecessorIds(current,graph,candidateRuns??await composition.runs.list()));if(current.finalization_decision?.outcome==="completed"){eligiblePredecessors.add(current.run.run_id)}const isOwnBlock=reason=>[...eligiblePredecessors].some(runId=>reason===`${MISSING_GUI_DECISION_REASON} (Run ${runId}).`||reason===`${MISSING_GUI_FINALIZATION_REASON} (Run ${runId}).`||reason?.startsWith(`Completion gates did not close Run ${runId}:`)===true);for(const task of graph.tasks){const latest=(await composition.tasks.read(task.id)).task;if(latest.status==="blocked"&&isOwnBlock(latest.status_reason??null)){await lifecycle.startTask(task.id,"resume")}}for(const change of graph.changes){const latest=(await composition.changes.read(change.id)).change;if(latest.status==="blocked"&&isOwnBlock(latest.status_reason??null)){await composition.changes.transition(latest.id,"executing")}}for(const execution of graph.executions){const latest=(await composition.executions.read(execution.id)).execution;if(latest.status!=="blocked"||!isOwnBlock(latest.status_reason??null))continue;if(latest.dag.nodes.length===0){await composition.executions.transition(latest.id,"cancelled","Superseded empty continuation intake")}else{await composition.executions.transition(latest.id,"running")}}return refreshGraph(graph,composition)}async function completionGatePredecessorIds(current,graph,candidates){const threadId=current.run.client_thread_id;if(current.run.task_id===null||current.run.change_id===null||current.run.execution_id===null){return new Set}const executionIds=new Set(graph.executions.map(execution=>execution.id));const eligible=new Set;for(const predecessor of candidates){if(predecessor.run.run_id===current.run.run_id||predecessor.finished===null||!isTaskAttemptRun(predecessor)||predecessor.run.occurred_at>=current.run.occurred_at||threadId!==null&&predecessor.run.client_thread_id!==threadId||predecessor.run.task_id!==current.run.task_id||predecessor.run.change_id!==current.run.change_id||predecessor.run.execution_id===null||!executionIds.has(predecessor.run.execution_id)){continue}eligible.add(predecessor.run.run_id)}return eligible}function resolveOutcome(current,tasks,requested,forceRequested){if(forceRequested===true&&requested!==void 0)return requested;if(current.finished?.status==="failed")return"failed";if(current.finished?.status==="cancelled")return"cancelled";if(requested!==void 0)return requested;if(!isTaskAttemptRun(current))return"completed";const terminal=tasks.find(task=>["completed","blocked","failed","cancelled"].includes(task.status))?.status;return terminal==="completed"||terminal==="blocked"||terminal==="failed"||terminal==="cancelled"?terminal:"blocked"}async function completeGraph(current,graph,composition,lifecycle,options){const summary=options.summary??`Run ${current.run.run_id} completed.`;const result2={summary,changed_files:[...options.changedFiles??[]],evidence_ids:[...options.evidenceIds??[]],completed_run_id:current.run.run_id};const taskAttempt=isTaskAttemptRun(current);if(taskAttempt){for(const task of graph.tasks){let latest=(await composition.tasks.read(task.id)).task;if(latest.status==="executing")latest=await composition.tasks.transition(task.id,"verifying");if(latest.status==="verifying")await lifecycle.completeTask(task.id,result2)}}else{const unfinished=graph.tasks.filter(task=>task.status!=="completed");if(unfinished.some(task=>["draft","planned","executing","verifying"].includes(task.status))){await keepMacroParentsActive(graph,composition);return currentGraphResult(current.run.run_id,await refreshGraph(graph,composition))}if(unfinished.length>0){throw new Error(`Macro Tasks did not complete: ${unfinished.map(task=>task.id).join(", ")}`)}}for(const change of graph.changes){let latest=(await composition.changes.read(change.id)).change;const relatedTasks=await Promise.all(latest.task_ids.map(async id=>(await composition.tasks.read(id)).task));if(relatedTasks.some(task=>task.status!=="completed"))continue;if(latest.status==="executing"){await lifecycle.verifyChange(change.id);latest=(await composition.changes.read(change.id)).change}if(latest.status==="verifying")await lifecycle.completeChange(change.id,summary)}for(const execution of graph.executions){let latest=(await composition.executions.read(execution.id)).execution;const relatedTasks=await Promise.all(latest.dag.nodes.map(async node=>(await composition.tasks.read(node.task_id)).task));if(relatedTasks.some(task=>task.status!=="completed"))continue;if(latest.status==="planned"&&latest.dag.nodes.length===0){await composition.executions.transition(execution.id,"cancelled","Superseded empty continuation intake");continue}if(latest.status==="planned"){latest=await composition.executions.transition(execution.id,"running")}if(latest.status==="blocked"&&taskAttempt){latest=await composition.executions.transition(execution.id,"running")}if(latest.status==="running"){await lifecycle.verifyExecution(execution.id);latest=(await composition.executions.read(execution.id)).execution}if(latest.status==="verifying")await lifecycle.completeExecution(execution.id,summary)}if(!taskAttempt){for(const spec of graph.specs.filter(item=>graph.directSpecIds.has(item.id))){if((await composition.specs.read(spec.id)).spec.status==="active")await lifecycle.deliverSpec(spec.id)}for(const prd of graph.prds.filter(item=>graph.directPrdIds.has(item.id))){if((await composition.prds.read(prd.id)).prd.status==="active")await lifecycle.deliverPrd(prd.id)}}else{await aggregateMacroAncestors(graph,composition)}const refreshed=await refreshGraph(graph,composition);assertGraphCompleted(refreshed,taskAttempt);return currentGraphResult(current.run.run_id,refreshed)}function assertGraphCompleted(graph,taskAttempt){const incomplete=[...graph.tasks.filter(item=>item.status!=="completed").map(item=>item.id),...!taskAttempt?graph.changes.filter(item=>item.status!=="completed").map(item=>item.id):[],...graph.executions.filter(item=>item.status!=="completed"&&!(item.dag.nodes.length===0&&item.status==="cancelled")).map(item=>item.id),...graph.specs.filter(item=>!taskAttempt&&graph.directSpecIds.has(item.id)&&item.status!=="delivered").map(item=>item.id),...graph.prds.filter(item=>!taskAttempt&&graph.directPrdIds.has(item.id)&&item.status!=="delivered").map(item=>item.id)];if(incomplete.length>0){throw new Error(`Completion left related work non-terminal: ${incomplete.join(", ")}`)}}async function settleGraph(current,graph,composition,lifecycle,outcome,reason){const clock=new SystemClock;const taskAttempt=isTaskAttemptRun(current);const taskResult=outcome==="blocked"?null:{summary:reason,changed_files:[],evidence_ids:[],completed_run_id:current.run.run_id};for(const task of graph.tasks){if(SETTLEABLE_TASK.has((await composition.tasks.read(task.id)).task.status)){await composition.tasks.transition(task.id,outcome,taskResult,clock,reason)}}const standalone=graph.executions.some(execution=>execution.origin.type==="task");for(const change of taskAttempt&&!standalone?[]:graph.changes){if(SETTLEABLE_CHANGE.has((await composition.changes.read(change.id)).change.status)){await composition.changes.transition(change.id,outcome,outcome==="blocked"?null:reason,clock,reason)}}for(const execution of taskAttempt&&!standalone?[]:graph.executions){if(SETTLEABLE_EXECUTION.has((await composition.executions.read(execution.id)).execution.status)){await composition.executions.transition(execution.id,outcome,outcome==="blocked"?null:reason,clock,reason)}}const specIdsToSettle=new Set(taskAttempt?[]:specIdsForLifecycleSettlement(graph.specs.map(item=>item.id),graph.directSpecIds,graph.directPrdIds));const specsToSettle=graph.specs.filter(item=>specIdsToSettle.has(item.id));for(const spec of specsToSettle){if(outcome==="cancelled"&&graph.directPrdIds.size>0)break;if((await composition.specs.read(spec.id)).spec.status==="active"){if(outcome==="cancelled")await lifecycle.cancelSpec(spec.id);else await composition.specs.transition(spec.id,outcome,reason)}}for(const prd of graph.prds.filter(item=>!taskAttempt&&graph.directPrdIds.has(item.id))){if((await composition.prds.read(prd.id)).prd.status==="active"){if(outcome==="cancelled")await lifecycle.cancelPrd(prd.id);else await composition.prds.transition(prd.id,outcome,reason)}}if(taskAttempt&&!standalone)await aggregateMacroAncestors(graph,composition);return currentGraphResult(current.run.run_id,await refreshGraph(graph,composition))}function relatedGraph(current,catalog){const{tasks,changes,executions,specs,prds}=catalog;const taskIds=new Set(current.run.task_id===null?[]:[current.run.task_id]);const changeIds=new Set(current.run.change_id===null?[]:[current.run.change_id]);const executionIds=new Set(current.run.execution_id===null?[]:[current.run.execution_id]);const specIds=new Set(current.run.spec_id===null?[]:[current.run.spec_id]);const prdIds=new Set(current.run.prd_id===null?[]:[current.run.prd_id]);const taskAttempt=isTaskAttemptRun(current);if(!taskAttempt){for(const spec of specs)if(spec.prd_id!==null&&prdIds.has(spec.prd_id))specIds.add(spec.id)}for(const change of changes){const source=change.source;if(changeIds.has(change.id)||source.type==="task"&&taskIds.has(source.task_id)||!taskAttempt&&source.type==="spec"&&specIds.has(source.spec_id)||!taskAttempt&&source.type==="prd"&&prdIds.has(source.prd_id))changeIds.add(change.id)}for(const task of tasks){if(taskIds.has(task.id)||!taskAttempt&&changeIds.has(task.change_id)){taskIds.add(task.id);const canonicalExecutionId=task.plan_ref?.execution_id??task.prepared_plan?.execution_id;if(canonicalExecutionId!==void 0&&canonicalExecutionId!==null)executionIds.add(canonicalExecutionId)}}for(const execution of executions){if(executionIds.has(execution.id)||execution.origin.type==="task"&&taskIds.has(execution.origin.task_id)||execution.dag.nodes.some(node=>taskIds.has(node.task_id))){executionIds.add(execution.id)}}return{tasks:tasks.filter(item=>taskIds.has(item.id)),changes:changes.filter(item=>changeIds.has(item.id)),executions:executions.filter(item=>executionIds.has(item.id)),specs:specs.filter(item=>specIds.has(item.id)),prds:prds.filter(item=>prdIds.has(item.id)),directSpecIds:new Set(current.run.spec_id===null?[]:[current.run.spec_id]),directPrdIds:new Set(current.run.prd_id===null?[]:[current.run.prd_id])}}async function keepMacroParentsActive(graph,composition){for(const spec of graph.specs){const latest=(await composition.specs.read(spec.id)).spec;if(latest.status==="ready"||latest.status==="blocked"){await composition.specs.transition(latest.id,"active")}}for(const prd of graph.prds){const latest=(await composition.prds.read(prd.id)).prd;if(latest.status==="ready"||latest.status==="blocked"){await composition.prds.transition(latest.id,"active")}}}async function aggregateMacroAncestors(graph,composition){await keepMacroParentsActive(graph,composition)}async function loadCatalog(composition){const[tasks,changes,executions,specs,prds]=await Promise.all([composition.tasks.list(),composition.changes.list(),composition.executions.list(),composition.specs.list(),composition.prds.list()]);return{tasks,changes,executions,specs,prds}}async function refreshGraph(graph,composition){const[tasks,changes,executions,specs,prds]=await Promise.all([Promise.all(graph.tasks.map(async item=>(await composition.tasks.read(item.id)).task)),Promise.all(graph.changes.map(async item=>(await composition.changes.read(item.id)).change)),Promise.all(graph.executions.map(async item=>(await composition.executions.read(item.id)).execution)),Promise.all(graph.specs.map(async item=>(await composition.specs.read(item.id)).spec)),Promise.all(graph.prds.map(async item=>(await composition.prds.read(item.id)).prd))]);return{...graph,tasks,changes,executions,specs,prds}}function currentGraphResult(runId,graph){return{run_id:runId,status:"closed",outcome:null,fallback_from:null,error:null,tasks:graph.tasks,changes:graph.changes,executions:graph.executions,specs:graph.specs,prds:graph.prds}}function emptyResult(runId,status){return{run_id:runId,status,outcome:null,fallback_from:null,error:null,tasks:[],changes:[],executions:[],specs:[],prds:[]}}function specIdsForLifecycleSettlement(specIds,directSpecIds,directPrdIds){return directPrdIds.size>0?[...specIds]:specIds.filter(id=>directSpecIds.has(id))}function defaultReason(runId,outcome){if(outcome==="failed")return`Run ${runId} failed and closed its operational lifecycle.`;if(outcome==="cancelled")return`Run ${runId} was explicitly cancelled.`;return`Run ${runId} completed without sufficient closure gates and has no concrete continuation.`}async function createTaskAndChangeAtomically(filesystem,composition,taskInput){const created=new Map;try{const task=await composition.tasks.createDraft(taskInput);created.set(composition.tasks.path(task.id),composition.tasks.serialize(task));const change=await composition.changes.createDraft({id:task.change_id,title:task.title,risk:task.risk,taskId:task.id,requirementIds:task.requirement_ids,acceptanceIds:task.acceptance_ids});return{task,change}}catch(error51){await rollbackTaskChangeCreation(filesystem,created);throw error51}}async function rollbackTaskChangeCreation(filesystem,created){for(const[path,content]of[...created].reverse()){await filesystem.removeFileIfContentMatches(path,content)}}function compactRunAggregate(aggregate){const bucket=value=>({usage_event_count:value.usage_event_count,tokens:value.tokens,cost:value.cost,coverage:value.coverage});return{scope_id:aggregate.scope_id,run_count:aggregate.run_count,run_coverage:aggregate.run_coverage,attribution:aggregate.attribution,conversation:bucket(aggregate.conversation),planning:bucket(aggregate.planning),execution:bucket(aggregate.execution),total:bucket(aggregate.total),work_types:{new:bucket(aggregate.work_types.new),rework:bucket(aggregate.work_types.rework)}}}async function runConversationV2Command(action,parsed,composition,filesystem,lifecycle){if(action==="start"){const client=parsed.options.client??"codex";const clientInvocation=await resolveRunClientInvocation(filesystem,client);const requestedIntent=resolveConversationIntent(parsed,clientInvocation.userMessage);assertDefinitionConversationIntake(parsed,requestedIntent);if(requestedIntent==="git_only"||isImplicitConversationCapture(parsed)&&isGitOnlyPublicationRequest(clientInvocation.userMessage)){return{skipped:true,reason:"git-only-publication",message:"Explicit deploy, push, and publication requests do not create ZAIP lifecycle records"}}const existing=await findIntakeForExactTurn(composition,client,clientInvocation);if(existing!==null){const task2=existing.run.task_id===null?null:(await composition.tasks.read(existing.run.task_id)).task;return{task:task2,run:existing.run,task_path:task2===null?null:composition.tasks.path(task2.id),run_path:composition.runs.path(existing.run.run_id),reused:true}}const request=conversationRequestOptions(clientInvocation.userMessage);const threadContext=await latestThreadContext(composition,client,clientInvocation.clientThreadId);let intent=requestedIntent;const newWorkMetadata=intent==="new_work"?requireSemanticNewWorkMetadata(parsed):null;let target=intent==="continue"||intent==="refine"||intent==="rework"?explicitIntakeTarget(parsed)??threadContext.implicitTarget:null;let decision=intakeDecision(parsed,intent);if(intent==="new_work"&&newWorkMetadata!==null&&decision.classification_source!=="explicit"&&threadContext.implicitTarget?.taskId!==void 0){const focusedTask=(await composition.tasks.read(threadContext.implicitTarget.taskId)).task;if((focusedTask.status==="draft"||focusedTask.status==="planned")&&focusedTask.started_at===null&&describesEquivalentWork(newWorkMetadata,focusedTask)){intent="continue";target=threadContext.implicitTarget;decision={intent:"continue",classification_source:"fallback",confidence:1,reason_codes:["equivalent-thread-work-reused"]}}}if((intent==="continue"||intent==="refine"||intent==="rework")&&target===null){intent="conversation";target=null;decision={intent:"conversation",classification_source:"fallback",confidence:0,reason_codes:["target-not-resolved"]}}const model=resolveConversationModel(parsed.options.model,clientInvocation.observedModel);const reasoningEffort=resolveConversationReasoningEffort(parsed.options["reasoning-effort"],clientInvocation.observedReasoningEffort);const timeZone=composition.layout.project.timezone;const conversationId2=parsed.options.conversation??threadContext.conversationId??createConversationId(intent==="new_work"?"new-work":"conversation");const clientTurnId=clientInvocation.clientTurnId??`local-${Date.now()}-${createCollisionCode(16)}`;const executionPolicy={failure_policy:"stop_on_terminal_failure",max_parallelism:1,max_operational_retries:1,max_repair_cycles_per_task:0,verification_mode:"scoped"};const commonInput=(executionId,executionKind)=>({...parsed.options.run===void 0?{}:{id:parsed.options.run},phase:conversationCapturePhase(intent),workType:runV2WorkTypeOption(intent==="rework"?"rework":parsed.options["work-type"]??"new"),client,runRole:"orchestrator",runPurpose:"orchestration",requiresFinalizer:executionKind==="delivery",executionKind,executionEligibility:[],agent:"agent-orchestrator",agentName:"zaip-agent-orchestrator",provider:parsed.options.provider??null,model,reasoningEffort,clientThreadId:clientInvocation.clientThreadId,clientTurnId,conversationId:conversationId2,executionId,intake:decision});const rootDeveloperIdentity=await resolveDeveloperIdentityForRoot(filesystem);const openIntakes=await openThreadIntakes(composition,client,clientInvocation.clientThreadId,clientInvocation.clientTurnId);const continuationOfRunId=target===null?null:openIntakes.find(fold=>runMatchesTarget(fold,target))?.run.run_id??null;if(intent!=="new_work"){const canonicalTaskExecution=target?.taskId===void 0?null:await activeCanonicalTaskExecution(target.taskId,composition);const execution=target===null?await composition.executions.createInteraction({id:parsed.options.execution??createId("EXEC",`interaction-${intent}`,{timeZone}),clientTurnId,conversationId:conversationId2,policy:executionPolicy}):canonicalTaskExecution??await composition.executions.createDeliveryIntake({id:parsed.options.execution??createId("EXEC",`delivery-${intent}`,{timeZone}),clientTurnId,origin:target.taskId!==void 0?{type:"task",task_id:target.taskId}:target.specId!==void 0?{type:"spec",spec_id:target.specId}:{type:"prd",prd_id:target.prdId},policy:executionPolicy});const targetTask=target?.taskId===void 0?null:(await composition.tasks.read(target.taskId)).task;const input={...commonInput(execution.id,execution.kind??"delivery"),developerIdentity:rootDeveloperIdentity,shortName:parsed.options["short-name"]??intent.replaceAll("_","-"),entrypoint:target?.entrypoint??"conversation",...target?.taskId===void 0?{}:{taskId:target.taskId},...targetTask===null?{}:{changeId:targetTask.change_id},...target?.specId===void 0?{}:{specId:target.specId},...target?.prdId===void 0?{}:{prdId:target.prdId},continuationOfRunId};await validateRunV2Attribution(input,composition);const writer=await composition.runs.start(input);const settledIntakes=await finishOpenThreadIntakes(openIntakes,composition,filesystem,parsed,lifecycle);const task2=input.taskId==null?null:(await composition.tasks.read(input.taskId)).task;return{task:task2,run:writer.started,settled_intakes:settledIntakes,task_path:task2===null?null:composition.tasks.path(task2.id),run_path:composition.runs.path(writer.started.run_id)}}const metadata=newWorkMetadata??requireSemanticNewWorkMetadata(parsed);const taskId=parsed.options.task??createId("TASK",metadata.shortName,{timeZone});const changeId=parsed.options.change??createId("CHG",metadata.shortName,{timeZone});const{task,change}=await createTaskAndChangeAtomically(filesystem,composition,{id:taskId,changeId,title:metadata.title,shortName:metadata.shortName,objective:metadata.objective,risk:riskOption(parsed.options.risk??request.risk),priority:priorityOption(parsed.options.priority),owner:parsed.options.owner??null,requirementIds:csvOption(parsed.options.requirements??"REQ-WORK-001"),acceptanceIds:csvOption(parsed.options.acceptance??"AC-WORK-001-09"),dependsOn:[],writeScopes:csvOption(parsed.options["write-scopes"])});const createdArtifacts=new Map([[composition.tasks.path(task.id),composition.tasks.serialize(task)],[composition.changes.path(change.id),composition.changes.serialize(change)]]);let deliveryExecution;try{deliveryExecution=await composition.executions.createDeliveryIntake({id:parsed.options.execution??createId("EXEC",`delivery-${intent}`,{timeZone}),clientTurnId,origin:{type:"task",task_id:task.id},policy:executionPolicy})}catch(error51){await rollbackTaskChangeCreation(filesystem,createdArtifacts);throw error51}try{const plan=createTaskFirstPreparedPlan({task,executionId:deliveryExecution.id,preparedAt:new Date().toISOString(),policy:executionPolicy});await composition.tasks.setPreparedPlan(task.id,plan);await composition.materializer.execute(plan);await composition.executions.transition(deliveryExecution.id,"running");await composition.changes.transition(changeId,"executing");const activeTask=await lifecycle.startTask(task.id);const input={...commonInput(deliveryExecution.id,"delivery"),developerIdentity:rootDeveloperIdentity,shortName:metadata.shortName,entrypoint:"task",taskId,changeId};await validateRunV2Attribution(input,composition);const writer=await composition.runs.start(input);const settledIntakes=await finishOpenThreadIntakes(openIntakes,composition,filesystem,parsed,lifecycle);return{task:activeTask,run:writer.started,settled_intakes:settledIntakes,task_path:composition.tasks.path(task.id),run_path:composition.runs.path(writer.started.run_id)}}catch(error51){const message=error51 instanceof Error?error51.message:String(error51);await composition.tasks.transition(taskId,"cancelled",{summary:`Conversation Run was not created: ${message}`,changed_files:[],evidence_ids:[],completed_run_id:null});await composition.changes.transition(changeId,"cancelled",`Conversation Run was not created: ${message}`);const currentExecution=(await composition.executions.read(deliveryExecution.id)).execution;if(currentExecution.status==="planned"||currentExecution.status==="running"){await composition.executions.transition(deliveryExecution.id,"cancelled",`Conversation Run was not created: ${message}`)}throw error51}}if(action==="finish"){requireOptions(parsed.options,["run","summary"]);const runId=parsed.options.run;let current=await composition.runs.read(runId);if(parsed.options.task!==void 0&¤t.run.task_id!==parsed.options.task){throw new UsageError(`Run ${runId} is not attributed to Task ${parsed.options.task}`)}const candidateRuns=await composition.runs.list();const evidenceIds=csvOption(parsed.options.evidence);const finalizationBarrier=assessRunFinalizationBarrier(current,candidateRuns,await hasPassedTypedEvidenceForRun(current,evidenceIds,composition));const finalizationBlockReason=finalizationBarrierBlockReason(finalizationBarrier);if(current.finished===null&&finalizationBarrier.status==="evidence_missing"){throw new UsageError(finalizationBlockReason)}const activeChildren=activeDescendantRuns(runId,candidateRuns);if(activeChildren.length>0){throw new UsageError(`Run ${runId} cannot finish while descendant Runs are active: ${activeChildren.map(child=>child.run.run_id).join(", ")}`)}const executionAtFinish=current.run.execution_id===null?null:(await composition.executions.read(current.run.execution_id)).execution;if(current.finished===null){current=await recordCodexTelemetryIfAvailable(current,composition,filesystem,null,await codexAppServerNotifications(parsed,filesystem))}if(current.finished===null&¤t.effective_usage_records.length===0){await recordUnavailableCodexTelemetryToSpool(current,filesystem,runV2FinishStatusOption(parsed.options.status));const usage=unavailableUsageRecord(current,parsed,current.records.length+1);await composition.runs.appendRecord(usage);current=foldRunV2Records([...current.records,usage])}if(current.finished===null){await composition.runs.appendRecord(runFinishedV2Schema.parse({schema_version:2,event_id:runV2EventId(runId,current.records.length+1),run_id:runId,sequence:current.records.length+1,occurred_at:new Date().toISOString(),type:"run.finished",phase:latestRunV2Phase(current.records),status:runV2FinishStatusOption(parsed.options.status)}))}let task=current.run.task_id===null?null:(await composition.tasks.read(current.run.task_id)).task;if(parsed.flags.has("cancel-task")){throw new UsageError("--cancel-task cannot bypass Gui; finish the delivery Run after Gui finalization")}const run=await composition.runs.read(runId);let interactionExecution=null;if(executionAtFinish?.kind==="interaction"){interactionExecution=finalizationBlockReason===null?await completeInteractionExecution(executionAtFinish.id,composition):await blockInteractionExecution(executionAtFinish.id,finalizationBlockReason,composition)}const reconciliation=await reconcileFinishedRunLifecycle(run,composition,lifecycle,{requestedOutcome:finalizationBlockReason===null?lifecycleOutcomeOption(parsed.options):"blocked",forceRequestedOutcome:finalizationBlockReason!==null,summary:finalizationBlockReason??parsed.options.summary,changedFiles:csvOption(parsed.options["changed-files"]),evidenceIds,defer:finalizationBlockReason===null&&parsed.flags.has("defer-orchestrator-closure"),candidateRuns});task=current.run.task_id===null?null:(await composition.tasks.read(current.run.task_id)).task;return{task,summary:parsed.options.summary,run:runV2Summary(run,composition),reconciliation,execution:interactionExecution,finalization_barrier:finalizationBarrier,task_path:task===null?null:composition.tasks.path(task.id),run_path:composition.runs.path(runId)}}throw new UsageError(`Unknown Conversation action: ${action??""}`)}async function activeCanonicalTaskExecution(taskId,composition){const task=(await composition.tasks.read(taskId)).task;const executionId=task.plan_ref?.execution_id??task.prepared_plan?.execution_id??null;if(executionId===null)return null;const execution=(await composition.executions.read(executionId)).execution;const terminal=new Set(["completed","failed","cancelled"]);return!terminal.has(execution.status)&&execution.dag.nodes.some(node=>node.task_id===task.id&&node.change_id===task.change_id)?execution:null}async function completeInteractionExecution(executionId,composition){let execution=(await composition.executions.read(executionId)).execution;if(execution.status==="running"){execution=await composition.executions.transition(executionId,"verifying")}return execution.status==="verifying"?composition.executions.transition(executionId,"completed","Interaction finalized"):execution}async function blockInteractionExecution(executionId,reason,composition){const execution=(await composition.executions.read(executionId)).execution;return execution.status==="running"||execution.status==="paused"||execution.status==="verifying"?composition.executions.transition(executionId,"blocked",null,void 0,reason):execution}function conversationCapturePhase(intent){if(intent==="new_work")return"execution";return intent==="refine"||intent==="rework"?"planning":"conversation"}function resolveConversationModel(explicitModel,observedModel=null){return explicitModel??observedModel??"unknown"}function resolveConversationReasoningEffort(explicitEffort,observedEffort){if(explicitEffort!==void 0)return runV2ReasoningEffortSchema.parse(explicitEffort);const observed=runV2ReasoningEffortSchema.safeParse(observedEffort);return observed.success?observed.data:null}async function openThreadIntakes(composition,client,clientThreadId,currentTurnId){if(clientThreadId===null)return[];const candidates=await composition.runs.list();return candidates.filter(fold=>fold.finished===null&&fold.run.client===client&&fold.run.client_thread_id===clientThreadId&&fold.run.parent_run_id===null&&fold.run.intake!=null&&!runV2RequiresFinalizer(fold.run)&&descendantRuns(fold.run.run_id,candidates).length===0&&fold.run.client_turn_id!==currentTurnId)}async function finishOpenThreadIntakes(openIntakes,composition,filesystem,parsed,lifecycle){const settled=[];for(const intake of openIntakes){const candidateRuns=await composition.runs.list();if(descendantRuns(intake.run.run_id,candidateRuns).length>0||activeDescendantRuns(intake.run.run_id,candidateRuns).length>0){continue}let current=intake;current=await recordCodexTelemetryIfAvailable(current,composition,filesystem,null,await codexAppServerNotifications(parsed,filesystem));if(current.effective_usage_records.length===0){await recordUnavailableCodexTelemetryToSpool(current,filesystem,"completed");await composition.runs.appendRecord(unavailableUsageRecord(current,parsed,current.records.length+1));current=await composition.runs.read(current.run.run_id)}await composition.runs.appendRecord(runFinishedV2Schema.parse({schema_version:2,event_id:runV2EventId(current.run.run_id,current.records.length+1),run_id:current.run.run_id,sequence:current.records.length+1,occurred_at:new Date().toISOString(),type:"run.finished",phase:latestRunV2Phase(current.records),status:"completed"}));const run=await composition.runs.read(current.run.run_id);settled.push({run,reconciliation:await reconcileFinishedRunLifecycle(run,composition,lifecycle,{candidateRuns})})}return settled}async function codexAppServerNotifications(parsed,filesystem){const path=parsed.options["codex-app-server-events"];return path===void 0?[]:parseCodexAppServerNotificationStream(await filesystem.readText(path))}function runMatchesTarget(fold,target){return target.taskId!==void 0&&fold.run.task_id===target.taskId||target.specId!==void 0&&fold.run.spec_id===target.specId||target.prdId!==void 0&&fold.run.prd_id===target.prdId}async function recordContextPackUsage(runId,initialPackTokens,composition){const current=await composition.runs.read(runId);if(current.finished!==null)throw new UsageError(`Run V2 is already finished: ${runId}`);const sequence=current.records.length+1;await composition.runs.appendRecord(usageRecordedV2Schema.parse({schema_version:2,event_id:runV2EventId(runId,sequence),run_id:runId,sequence,occurred_at:new Date().toISOString(),type:"usage.recorded",phase:latestRunV2Phase(current.records),activity_kind:"context_build",classification_source:"current_context",tokens:{input:null,cached_input:null,output:null,reasoning:null,total:null,source:"unavailable"},cost:{usd:null,brl:null},provider:current.run.provider,model:current.run.model,source_segment_key:`context-pack:${runId}:${sequence}`,supersedes_event_id:null,source_occurred_at:new Date().toISOString(),context_stats:{initial_pack_tokens:initialPackTokens,tool_output_tokens:null,files_opened:null,snippets_opened:null}}))}function unavailableUsageRecord(current,parsed,sequence){const occurredAt=new Date().toISOString();return usageRecordedV2Schema.parse({schema_version:2,event_id:runV2EventId(current.run.run_id,sequence),run_id:current.run.run_id,sequence,occurred_at:occurredAt,type:"usage.recorded",phase:latestRunV2Phase(current.records),activity_kind:"run_finalize",classification_source:"current_context",tokens:{input:null,cached_input:null,output:null,reasoning:null,total:null,source:"unavailable"},cost:{usd:null,brl:null},provider:current.run.provider,model:current.run.model,source_segment_key:null,supersedes_event_id:null,...runUsageMetadataOptions(parsed.options,occurredAt)})}function latestRunV2Phase(records){const latest=records.findLast(record3=>"phase"in record3);return latest?.phase??"conversation"}function runV2EventId(runId,sequence){return`${runId}:${String(sequence).padStart(6,"0")}`}function runV2CostInput(fold){return{run:{run_id:fold.run.run_id,attribution_status:fold.run.attribution_status,conversation_id:fold.run.conversation_id,execution_id:fold.run.execution_id,task_id:fold.run.task_id,spec_id:fold.run.spec_id,prd_id:fold.run.prd_id,change_id:fold.run.change_id,work_type:fold.run.work_type},records:fold.records,effective_usage_records:fold.effective_usage_records}}function runV2Summary(fold,composition){const usage=aggregateRunV2Usage([runV2CostInput(fold)],fold.run.run_id).total;const callIds=new Set([...fold.model_selection_records.map(record3=>record3.invocation_id),...fold.provider_invocation_records.map(record3=>record3.invocation_id)]);return{id:fold.run.run_id,status:fold.status,created_at:fold.run.occurred_at,finished_at:fold.finished?.occurred_at??null,phase:latestRunV2Phase(fold.records),run_role:effectiveRunV2Role(fold.run),parent_run_id:fold.run.parent_run_id,entrypoint:fold.run.entrypoint,work_type:fold.run.work_type,intake:fold.run.intake??null,agent:fold.run.agent,agent_name:fold.run.agent_name??(fold.run.agent.startsWith("agent-")?`zaip-agent-${fold.run.agent.slice("agent-".length)}`:fold.run.agent),model:fold.run.model,reasoning_effort:fold.run.reasoning_effort??fold.model_selection_records[0]?.requested.reasoning_effort??null,call_count:callIds.size===0?null:callIds.size,client_thread_id:fold.run.client_thread_id??null,client_turn_id:fold.run.client_turn_id??null,conversation_id:fold.run.conversation_id,execution_id:fold.run.execution_id,task_id:fold.run.task_id,spec_id:fold.run.spec_id,prd_id:fold.run.prd_id,change_id:fold.run.change_id,usage:{event_count:usage.usage_event_count,tokens:usage.tokens,cost:usage.cost,coverage:usage.coverage},artifact_path:composition.runs.path(fold.run.run_id)}}async function reconcileTerminalOrchestratorRoot(root,candidates,composition,lifecycle){const evidenceIds=await passedTypedEvidenceIdsForRun(root,composition,candidates);const evidenceSatisfied=await hasPassedTypedEvidenceForRun(root,evidenceIds,composition,candidates);const barrier=assessRunFinalizationBarrier(root,candidates,evidenceSatisfied);const blockReason=finalizationBarrierBlockReason(barrier);const decision=root.finalization_decision??null;const decisionEligible=decision!==null&&(decision.outcome!=="completed"||barrier.satisfied);const reconciliation=await reconcileFinishedRunLifecycle(root,composition,lifecycle,{requestedOutcome:decisionEligible?decision.outcome:"blocked",forceRequestedOutcome:!decisionEligible,summary:decisionEligible?decision.summary:blockReason??"Orchestrator stopped without a persisted Gui finalization decision; lifecycle was fail-closed as blocked.",evidenceIds:decision?.evidence_ids??evidenceIds,changedFiles:decision?.changed_files??[],candidateRuns:candidates});return{status:"closed",parent_run_id:root.run.run_id,finalization_barrier:barrier,finalization_decision:decision,reconciliation}}async function runSubagentV2Command(action,parsed,composition,filesystem,lifecycle,onTerminalMutationCommitted){parsed=normalizeSubagentSessionOption(parsed);if(action==="reconcile-local"){requireOptions(parsed.options,["parent-run-id"]);const parentRunId=optionValue(parsed,"parent-run-id");const root=(await composition.runs.list()).find(fold=>fold.finished===null&&fold.run.parent_run_id===null&&fold.run.run_id===parentRunId);if(root===void 0)throw new UsageError(`Active root Run not found: ${parentRunId}`);return reconcileLocalSubagentSessions(root,composition,filesystem,lifecycle)}if(action==="capture-terminal"){return captureTerminalFallback(parsed,composition,filesystem,lifecycle,onTerminalMutationCommitted)}if(action!=="capture")throw new UsageError(`Unknown subagent action: ${action??""}`);requireOptions(parsed.options,["event","session","turn","agent-id","agent-type"]);const event=parsed.options.event;if(event!=="start"&&event!=="stop"){throw new UsageError("--event must be start or stop")}if(event==="start")requireOptions(parsed.options,["model"]);const identity=await subagentIdentity(filesystem,parsed.options["agent-type"]??"");return event==="start"?captureStart(parsed,composition,identity):captureStop(parsed,composition,filesystem,lifecycle,identity)}async function captureTerminalFallback(parsed,composition,filesystem,lifecycle,onTerminalMutationCommitted){requireOptions(parsed.options,["parent-run-id","agent-id","agent-type","status"]);const parentAgentId=parsed.options["parent-agent-id"]?.trim();const parentRunId=optionValue(parsed,"parent-run-id");const agentPath=optionValue(parsed,"agent-id");const status=terminalStatus(parsed.options.status);const identity=await subagentIdentity(filesystem,optionValue(parsed,"agent-type"));const finalizer=identity.agent==="agent-finalizer"||identity.role==="execution-finalizer";const finalization=terminalFinalizationRequest(parsed,finalizer);const eligibleExecutor=identity.cataloged&&identity.executionEligibility.includes("delivery")&&identity.capabilities.includes("task-delivery");if(!identity.cataloged||!finalizer&&!eligibleExecutor)throw new UsageError("capture-terminal requires the cataloged zaip-agent-finalizer or an eligible delivery executor");const agentPathTaskName=agentPath.split(/[\\/]/u).filter(Boolean).at(-1)??"";if(identity.codexTaskName===null||agentPathTaskName!==identity.codexTaskName){throw new UsageError("capture-terminal agent-id must end with the selected catalog identity codex_task_name")}const initialRuns=await composition.runs.list();const root=initialRuns.find(fold=>fold.run.run_id===parentRunId&&fold.run.parent_run_id===null&&(parentAgentId===void 0?fold.run.client_thread_id===null:fold.run.client_thread_id===parentAgentId));if(root===void 0){throw new UsageError(`Cannot capture terminal Sub-Run without exact active root Run ${parentRunId}`)}if(root.finished!==null){const existing=terminalFallbackExisting(initialRuns,root.run.run_id,agentPath,identity.agent);if(existing===void 0||existing.status!==status){throw new UsageError(`Cannot capture terminal Sub-Run without exact active root Run ${parentRunId}`)}if(finalization!==null){const decision=root.finalization_decision??null;if(decision===null||decision.finalizer_run_id!==existing.run.run_id||decision.outcome!==finalization.outcome||decision.summary!==finalization.summary||!sameStringSet(decision.evidence_ids,finalization.evidenceIds)||!sameStringSet(decision.changed_files,finalization.changedFiles)){throw new UsageError(`capture-terminal decision conflicts with the persisted Gui finalization for Run ${root.run.run_id}`)}}return captureResult(existing,true)}const capture=await withLifecycleCanonicalMutationLock(filesystem,async()=>{const capture2=await composition.runs.withUsageAttributionLock(async()=>{const invocationIdentity=["codex-subagent-terminal-fallback-v1",root.run.run_id,agentPath,identity.agent].join("");const captured2=await composition.runs.withSubagentInvocationClaim(invocationIdentity,async runId=>{const existing=await composition.runs.read(runId);if(existing.status!==status){throw new UsageError(`capture-terminal status conflicts with existing Sub-Run ${existing.run.run_id}`)}return captureResult(existing,true)},async()=>{const runs=await composition.runs.list();const parent=runs.find(fold=>fold.status==="running"&&fold.run.run_id===root.run.run_id);if(parent===void 0){throw new Error(`Root Run is no longer active: ${root.run.run_id}`)}const existing=terminalFallbackExisting(runs,parent.run.run_id,agentPath,identity.agent);if(existing!==void 0){if(existing.status!==status){throw new UsageError(`capture-terminal status conflicts with existing Sub-Run ${existing.run.run_id}`)}return{runId:existing.run.run_id,value:captureResult(existing,true)}}const executionKind=parent.run.execution_kind??(parent.run.entrypoint!=="conversation"?"delivery":parent.run.execution_id===null?void 0:await composition.executions.read(parent.run.execution_id).then(({execution})=>execution.kind??"delivery").catch(()=>void 0));const runPurpose=finalizer?"finalization":"execution";const effectiveParent=executionKind===void 0?parent:{...parent,run:{...parent.run,execution_kind:executionKind}};assertChildRunMayStart(effectiveParent,runPurpose,identity.agent,runs,identity.executionEligibility);const input={shortName:`subagent-${slug(identity.agent)}-fallback`,phase:latestRunV2Phase(parent.records),runRole:"subagent",runPurpose,...executionKind===void 0?{}:{executionKind},executionEligibility:identity.executionEligibility,entrypoint:parent.run.entrypoint,workType:parent.run.work_type,client:"codex-subagent",agent:identity.agent,agentName:identity.agentName,provider:null,model:"unavailable",reasoningEffort:null,clientThreadId:agentPath,clientTurnId:null,conversationId:parent.run.conversation_id,executionId:parent.run.execution_id,taskId:parent.run.task_id,specId:parent.run.spec_id,prdId:parent.run.prd_id,changeId:parent.run.change_id,parentRunId:parent.run.run_id};await validateRunV2Attribution(input,composition);const writer=await composition.runs.start(input);const started=writer.started;const current=await composition.runs.read(started.run_id);await composition.runs.appendRecord(unavailableUsageRecord(current,parsed,current.records.length+1));const withUsage=await composition.runs.read(started.run_id);const sequence=withUsage.records.length+1;await composition.runs.appendRecord(runFinishedV2Schema.parse({schema_version:2,event_id:runV2EventId(started.run_id,sequence),run_id:started.run_id,sequence,occurred_at:new Date().toISOString(),type:"run.finished",phase:latestRunV2Phase(withUsage.records),status}));const finished=await composition.runs.read(started.run_id);return{runId:started.run_id,value:{...captureResult(finished,false),fallback:"terminal-agent-path",usage_source:"unavailable"}}},async()=>{const existing=terminalFallbackExisting(await composition.runs.list(),root.run.run_id,agentPath,identity.agent);if(existing===void 0)return null;if(existing.status!==status){throw new UsageError(`capture-terminal status conflicts with existing Sub-Run ${existing.run.run_id}`)}return{runId:existing.run.run_id,value:captureResult(existing,true)}});const terminalDecision2=finalizer?await persistTerminalFallbackDecision(root.run.run_id,captured2,finalization,composition):null;return{captured:captured2,terminalDecision:terminalDecision2}});return capture2});const{captured,terminalDecision}=capture;const result2=finalizer?{...captured,...terminalDecision===null?{}:{finalization:terminalDecision},parent_closure:await reconcileOrchestratorStop(await composition.runs.read(root.run.run_id),composition,lifecycle)}:captured;await onTerminalMutationCommitted?.(result2);return result2}function terminalFallbackExisting(runs,parentRunId,agentPath,agent){const matches=runs.filter(fold=>fold.run.parent_run_id===parentRunId&&fold.run.client_thread_id===agentPath&&fold.run.agent===agent);if(matches.length>1){throw new UsageError(`capture-terminal is ambiguous for ${agentPath}; capture the exact child session and turn`)}return matches[0]}function terminalFinalizationRequest(parsed,finalizer){const outcome=parsed.options["task-outcome"];const requested=outcome!==void 0||parsed.options.summary!==void 0||parsed.options.evidence!==void 0||parsed.options["changed-files"]!==void 0;if(!requested)return null;if(!finalizer){throw new UsageError("capture-terminal finalization decision is restricted to zaip-agent-finalizer")}if(outcome!=="completed"&&outcome!=="blocked"&&outcome!=="failed"&&outcome!=="cancelled"){throw new UsageError("capture-terminal --task-outcome must be completed, blocked, failed, or cancelled")}const summary=parsed.options.summary?.trim();if(summary===void 0||summary.length===0){throw new UsageError("capture-terminal finalization requires --summary")}return{outcome,summary,evidenceIds:csvOption2(parsed.options.evidence),changedFiles:csvOption2(parsed.options["changed-files"])}}async function persistTerminalFallbackDecision(rootRunId,captured,request,composition){if(request===null)return null;const finalizerRunId=captured.run?.run_id;if(typeof finalizerRunId!=="string"){throw new Error("capture-terminal did not return its authenticated Gui Sub-Run")}const root=await composition.runs.read(rootRunId);const finalizer=await composition.runs.read(finalizerRunId);if(root.finished!==null||finalizer.run.parent_run_id!==root.run.run_id||finalizer.run.agent!=="agent-finalizer"||effectiveRunV2Purpose(finalizer.run)!=="finalization"||finalizer.finished===null){throw new UsageError("capture-terminal finalization requires its exact terminal Gui Sub-Run")}const existing=root.finalization_decision??null;if(existing!==null){if(existing.finalizer_run_id!==finalizerRunId||existing.outcome!==request.outcome||existing.summary!==request.summary||!sameStringSet(existing.evidence_ids,request.evidenceIds)||!sameStringSet(existing.changed_files,request.changedFiles)){throw new UsageError(`Run ${root.run.run_id} already has a different Gui finalization decision`)}return existing}const record3=runFinalizationDecidedV2Schema.parse({schema_version:2,event_id:runV2EventId(root.run.run_id,root.records.length+1),run_id:root.run.run_id,sequence:root.records.length+1,occurred_at:new Date().toISOString(),type:"run.finalization.decided",finalizer_run_id:finalizerRunId,outcome:request.outcome,summary:request.summary,evidence_ids:request.evidenceIds,changed_files:request.changedFiles});await composition.runs.appendRecord(record3);return record3}function csvOption2(value){return value===void 0?[]:value.split(",").map(item=>item.trim()).filter(item=>item.length>0)}function sameStringSet(left,right){return left.length===right.length&&left.every(value=>right.includes(value))}async function captureStart(parsed,composition,identity){const[sessionId,turnId,agentId2,,model]=startValues(parsed);return composition.runs.withUsageAttributionLock(async()=>{const invocationIdentity=["codex-subagent-v1",sessionId,parsed.options["parent-agent-id"]??"",agentId2,turnId,identity.agent].join("");return composition.runs.withSubagentInvocationClaim(invocationIdentity,async runId=>captureResult(await composition.runs.read(runId),true),async()=>{const runs=await composition.runs.list();const existing=runs.find(fold=>fold.run.client_thread_id===agentId2&&fold.run.client_turn_id===turnId&&fold.run.agent===identity.agent&&(parsed.options["parent-run-id"]===void 0||fold.run.parent_run_id===parsed.options["parent-run-id"]));if(existing!==void 0){assertCapturedSubagentIdentity(existing,runs,sessionId,parsed.options["parent-agent-id"],true);return{runId:existing.run.run_id,value:captureResult(existing,true)}}const parent=selectParent(runs,sessionId,turnId,parsed.options["parent-agent-id"],parsed.options["parent-run-id"]);if(parent===void 0){throw new Error(`Cannot claim Sub-Run without parent Run for ${agentId2}`)}if(identity.role==="orchestrator"&&parent.run.parent_run_id===null&&parent.run.agent==="agent-orchestrator"){return{runId:parent.run.run_id,value:{...captureResult(parent,true),bound_to_root:true}}}const source=parent.run;const executionKind=source.execution_kind??(source.entrypoint!=="conversation"?"delivery":source.execution_id===null?void 0:await composition.executions.read(source.execution_id).then(({execution})=>execution.kind??"delivery").catch(()=>void 0));const effectiveParent=executionKind===void 0?parent:{...parent,run:{...parent.run,execution_kind:executionKind}};const runPurpose=identity.role==="execution-finalizer"?"finalization":identity.role==="reviewer"?"review":identity.role==="auditor"?"audit":"execution";assertChildRunMayStart(effectiveParent,runPurpose,identity.agent,runs,identity.executionEligibility,{allowObservedIneligibleInvocation:parsed.options["observed-local-recovery"]==="true"});const input={shortName:`subagent-${slug(identity.agent)}`,phase:latestRunV2Phase(parent.records),runRole:"subagent",runPurpose,...executionKind===void 0?{}:{executionKind},executionEligibility:identity.executionEligibility,entrypoint:source.entrypoint,workType:source.work_type,client:"codex-subagent",agent:identity.agent,agentName:identity.agentName,provider:source.provider??"openai",model,reasoningEffort:parsed.options["reasoning-effort"]===void 0?null:runV2ReasoningEffortSchema.parse(parsed.options["reasoning-effort"]),clientThreadId:agentId2,clientTurnId:turnId,conversationId:source.conversation_id,executionId:source.execution_id,taskId:source.task_id,specId:source.spec_id,prdId:source.prd_id,changeId:source.change_id,parentRunId:source.run_id};await validateRunV2Attribution(input,composition);const writer=await composition.runs.start(input);return{runId:writer.started.run_id,value:{captured:true,reused:false,run:writer.started,artifact_path:composition.runs.path(writer.started.run_id),cataloged:identity.cataloged}}},async()=>{const existing=(await composition.runs.list()).find(fold=>fold.run.client_thread_id===agentId2&&fold.run.client_turn_id===turnId&&fold.run.agent===identity.agent);if(existing===void 0)return null;assertCapturedSubagentIdentity(existing,await composition.runs.list(),sessionId,parsed.options["parent-agent-id"],true);return{runId:existing.run.run_id,value:captureResult(existing,true)}})})}async function reconcileLocalSubagentSessions(root,composition,filesystem,lifecycle,sourceOptions={},stopOnConcurrentRootAmbiguity=false){const parentThreadId=root.run.client_thread_id;const turnId=root.run.client_turn_id;if(parentThreadId==null||turnId==null){return{captured:[],skipped:[{reason:"root-correlation-unavailable"}],parent_run_id:root.run.run_id}}const concurrentRoots=(await composition.runs.list()).filter(fold=>fold.finished===null&&fold.run.parent_run_id===null&&fold.run.client_thread_id===parentThreadId);if(concurrentRoots.length>1){if(stopOnConcurrentRootAmbiguity){return{captured:[],skipped:[{reason:"local-discovery-skipped-concurrent-roots"}],parent_run_id:root.run.run_id}}throw new UsageError(`Multiple active root Runs share ${parentThreadId}; local Sub-Run discovery is ambiguous`)}const catalog=await loadAgentCatalog(filesystem);const rootStartedAt=Date.parse(root.run.occurred_at);const rootFinishedAt=root.finished===null?null:Date.parse(root.finished.occurred_at);const lifecycles=(await listCodexInvocationLifecycles(filesystem.root,{...sourceOptions,parentThreadId})).filter(item=>{const startedAt=item.startedAt===null?Number.NaN:Date.parse(item.startedAt);return Number.isFinite(startedAt)&&startedAt>=rootStartedAt&&(rootFinishedAt===null||startedAt<=rootFinishedAt)});const unique2=new Map(lifecycles.map(item=>[`${item.sessionId}${item.turnId}${item.agentPath}`,item]));const ordered=[...unique2.values()].sort((left,right)=>{const leftFinalizer=left.agentRole==="zaip-agent-finalizer"?1:0;const rightFinalizer=right.agentRole==="zaip-agent-finalizer"?1:0;return leftFinalizer-rightFinalizer||(left.startedAt??"").localeCompare(right.startedAt??"")});const captured=[];const skipped=[];for(const observed of ordered){if(observed.status==="active"||observed.status==="interrupted"){skipped.push({agent_type:observed.agentRole,agent_path:observed.agentPath,reason:observed.status==="active"?"subagent-still-active":"terminal-status-inconclusive"});continue}const taskName=observed.agentPath?.split(/[\\/]/u).filter(Boolean).at(-1)??null;const catalogAgent=catalog.agents.find(candidate=>candidate.codex_name===observed.agentRole&&candidate.codex_task_name===taskName);if(catalogAgent===void 0||observed.agentPath===null){skipped.push({agent_type:observed.agentRole,agent_path:observed.agentPath,reason:"catalog-identity-mismatch"});continue}const existingTerminal=(await composition.runs.list()).find(fold=>fold.finished!==null&&fold.run.parent_run_id===root.run.run_id&&fold.run.client_thread_id===observed.agentPath&&fold.run.client_turn_id===observed.turnId&&fold.run.agent===catalogAgent.id);if(existingTerminal!==void 0){if(existingTerminal.status!==observed.status||!hasObservedUsage(existingTerminal)){skipped.push({agent_type:observed.agentRole,agent_path:observed.agentPath,reason:"existing-terminal-subrun-conflict"});continue}captured.push({agent_type:catalogAgent.codex_name,agent_path:observed.agentPath,status:observed.status});continue}const segment2=await findLatestCodexSegment(filesystem.root,new Set,{...sourceOptions,agentPath:observed.agentPath,parentThreadId,turnId:observed.turnId});if(segment2===null||segment2.model===null){skipped.push({agent_type:observed.agentRole,agent_path:observed.agentPath,reason:"observed-model-or-segment-unavailable"});continue}const baseOptions={session:observed.sessionId,turn:observed.turnId,"agent-id":observed.agentPath,"agent-type":catalogAgent.codex_name,"parent-agent-id":parentThreadId,"parent-run-id":root.run.run_id,"observed-local-recovery":"true"};await captureStart({positionals:["subagent","capture"],flags:new Set,options:{...baseOptions,event:"start",model:segment2.model,...segment2.reasoningEffort===null?{}:{"reasoning-effort":segment2.reasoningEffort}}},composition,await subagentIdentity(filesystem,catalogAgent.codex_name));const startedChild=(await composition.runs.list()).find(fold=>fold.run.parent_run_id===root.run.run_id&&fold.run.client_thread_id===observed.agentPath&&fold.run.client_turn_id===observed.turnId&&fold.run.agent===catalogAgent.id);if(startedChild===void 0){throw new Error(`Reconciled Sub-Run was not materialized for ${observed.agentPath}`)}if(startedChild.finished!==null){if(startedChild.status!==observed.status||!hasObservedUsage(startedChild)){skipped.push({agent_type:observed.agentRole,agent_path:observed.agentPath,reason:"existing-terminal-subrun-conflict"});continue}captured.push({agent_type:catalogAgent.codex_name,agent_path:observed.agentPath,status:observed.status});continue}await recordCodexTelemetryIfAvailable(startedChild,composition,filesystem,{agentPath:observed.agentPath,parentThreadId,threadId:null,turnId:observed.turnId},[],async()=>segment2);await captureStop({positionals:["subagent","capture"],flags:new Set,options:{...baseOptions,event:"stop",status:observed.status}},composition,filesystem,lifecycle,await subagentIdentity(filesystem,catalogAgent.codex_name));captured.push({agent_type:catalogAgent.codex_name,agent_path:observed.agentPath,status:observed.status})}return{captured,skipped,parent_run_id:root.run.run_id}}async function captureStop(parsed,composition,filesystem,lifecycle,identity){const[sessionId,turnId,agentId2]=baseValues(parsed);const runs=await composition.runs.list();if(identity.role==="orchestrator"){if(lifecycle===void 0){throw new UsageError("Orchestrator reconciliation requires lifecycle services")}const root=selectParent(runs,sessionId,turnId,parsed.options["parent-agent-id"],parsed.options["parent-run-id"])??runs.find(candidate=>candidate.finished!==null&&candidate.run.parent_run_id===null&&candidate.run.agent==="agent-orchestrator"&&candidate.run.client_thread_id===sessionId&&candidate.run.client_turn_id===turnId);if(root===void 0||root.run.parent_run_id!==null||root.run.agent!=="agent-orchestrator"){return{captured:false,reason:"root-run-not-found",agent_id:agentId2}}const current2=await recordCodexTelemetryIfAvailable(root,composition,filesystem,{agentPath:agentId2,parentThreadId:sessionId,threadId:null,turnId:null});const closure=await reconcileOrchestratorStop(current2,composition,lifecycle);const settled=closure===null?current2:await composition.runs.read(current2.run.run_id);return{...captureResult(settled,true),bound_to_root:true,closure}}const status=terminalStatus(parsed.options.status??"completed");const child=runs.find(fold=>fold.run.client_thread_id===agentId2&&fold.run.client_turn_id===turnId&&fold.run.agent===identity.agent&&(parsed.options["parent-run-id"]===void 0||fold.run.parent_run_id===parsed.options["parent-run-id"]));if(child===void 0){if(parsed.options["parent-run-id"]!==void 0&&runs.some(fold=>fold.run.client_thread_id===agentId2&&fold.run.client_turn_id===turnId&&fold.run.agent===identity.agent)){throw new UsageError("Sub-Run identity conflicts with explicit --parent-run-id")}return{captured:false,reused:true,status,reason:"pending-subagent-start",agent_id:agentId2,recovery:"replay-stop-after-start"}}assertCapturedSubagentIdentity(child,runs,sessionId,parsed.options["parent-agent-id"]);if(child.finished!==null){if(child.status!==status){throw new UsageError(`subagent stop status conflicts with existing Sub-Run ${child.run.run_id}`)}return captureResult(child,true)}let current=await recordCodexTelemetryIfAvailable(child,composition,filesystem);for(let attempt=0;attempt<4&&!hasObservedUsage(current);attempt+=1){await new Promise(resolve10=>setTimeout(resolve10,100*2**attempt));current=await recordCodexTelemetryIfAvailable(current,composition,filesystem)}const captured=await composition.runs.withUsageAttributionLock(async()=>{current=await composition.runs.read(child.run.run_id);if(current.finished!==null){if(current.status!==status){throw new UsageError(`subagent stop status conflicts with existing Sub-Run ${current.run.run_id}`)}return captureResult(current,true)}if(current.effective_usage_records.length===0){const usage=unavailableUsageRecord(current,parsed,current.records.length+1);await composition.runs.appendRecord(usage);current=foldRunV2Records([...current.records,usage])}const sequence=current.records.length+1;await composition.runs.appendRecord(runFinishedV2Schema.parse({schema_version:2,event_id:runV2EventId(current.run.run_id,sequence),run_id:current.run.run_id,sequence,occurred_at:new Date().toISOString(),type:"run.finished",phase:latestRunV2Phase(current.records),status}));return captureResult(await composition.runs.read(current.run.run_id),false)});if(identity.agent==="agent-finalizer"){const parent=(await composition.runs.list()).find(candidate=>candidate.run.run_id===child.run.parent_run_id);if(parent!==void 0&&lifecycle!==void 0){const closure=await reconcileOrchestratorStop(parent,composition,lifecycle);return{...captured,parent_closure:closure}}}return captured}async function reconcileOrchestratorStop(current,composition,lifecycle){return composition.runs.withUsageAttributionLock(async()=>{const fresh=await composition.runs.read(current.run.run_id);const candidates=await composition.runs.list();const active=activeDescendantRuns(fresh.run.run_id,candidates);if(active.length>0){return{status:"pending_descendants",parent_run_id:fresh.run.run_id,active_run_ids:active.map(candidate=>candidate.run.run_id)}}if(fresh.finished!==null)return reconcileTerminalOrchestratorRoot(fresh,candidates,composition,lifecycle);const sequence=fresh.records.length+1;await composition.runs.appendRecord(runFinishedV2Schema.parse({schema_version:2,event_id:runV2EventId(fresh.run.run_id,sequence),run_id:fresh.run.run_id,sequence,occurred_at:new Date().toISOString(),type:"run.finished",phase:latestRunV2Phase(fresh.records),status:"completed"}));const finishedRoot=await composition.runs.read(fresh.run.run_id);return reconcileTerminalOrchestratorRoot(finishedRoot,await composition.runs.list(),composition,lifecycle)})}async function subagentIdentity(filesystem,rawAgentType){const agentType=rawAgentType.trim();const catalog=await loadAgentCatalog(filesystem);const agent=catalog.agents.find(candidate=>candidate.codex_name===agentType||candidate.id===agentType);return agent===void 0?{agent:`unrecognized-subagent:${slug(agentType)}`,agentName:agentType,codexTaskName:null,role:null,capabilities:[],executionEligibility:[],cataloged:false}:{agent:agent.id,agentName:agent.codex_name,codexTaskName:agent.codex_task_name,role:agent.role,capabilities:agent.capabilities,executionEligibility:agent.execution_eligibility,cataloged:true}}function selectParent(runs,sessionId,turnId,parentAgentId,parentRunId){const explicitParent=parentAgentId?.trim();const explicitRun=parentRunId?.trim();if(explicitRun!==void 0&&explicitRun.length>0){if(explicitParent===void 0||explicitParent.length===0){throw new UsageError("--parent-run-id requires --parent-agent-id")}return runs.find(fold=>fold.status==="running"&&fold.run.run_id===explicitRun&&fold.run.client_thread_id===explicitParent)}if(explicitParent!==void 0&&explicitParent.length>0){const candidates=runs.filter(fold=>fold.status==="running"&&fold.run.client_thread_id===explicitParent);if(candidates.length>1){throw new UsageError(`Multiple active root Runs share ${explicitParent}; pass --parent-run-id for exact attribution`)}return candidates[0]}return runs.filter(fold=>fold.status==="running"&&fold.run.parent_run_id===null&&fold.run.client_thread_id===sessionId&&fold.run.client_turn_id===turnId).sort((left,right)=>right.run.occurred_at.localeCompare(left.run.occurred_at))[0]}function assertCapturedSubagentIdentity(child,runs,sessionId,rawParentAgentId,requireRootSession=false){const parent=child.run.parent_run_id===null?void 0:runs.find(candidate=>candidate.run.run_id===child.run.parent_run_id);const declaredParent=rawParentAgentId?.trim();if(parent===void 0||declaredParent!==void 0&&declaredParent.length>0&&parent.run.client_thread_id!==declaredParent){throw new UsageError(`Sub-Run identity conflicts with existing Run ${child.run.run_id}`)}if(declaredParent!==void 0&&declaredParent.length>0&&!requireRootSession)return;let root=parent;while(root.run.parent_run_id!==null){const next=runs.find(candidate=>candidate.run.run_id===root.run.parent_run_id);if(next===void 0){throw new UsageError(`Sub-Run identity conflicts with existing Run ${child.run.run_id}`)}root=next}if(root.run.client_thread_id!==sessionId){throw new UsageError(`Sub-Run identity conflicts with existing Run ${child.run.run_id}`)}}function normalizeSubagentSessionOption(parsed){const alias=parsed.options["session-id"];const session=parsed.options.session;if(alias!==void 0&&session!==void 0&&alias!==session){throw new UsageError("--session and --session-id must match when both are provided")}if(session!==void 0||alias===void 0)return parsed;return{...parsed,options:{...parsed.options,session:alias}}}function baseValues(parsed){return["session","turn","agent-id","agent-type"].map(name=>{const value=parsed.options[name]?.trim();if(value===void 0||value.length===0||value.length>200){throw new UsageError(`--${name} must contain 1 to 200 characters`)}return value})}function optionValue(parsed,name){const value=parsed.options[name]?.trim();if(value===void 0||value.length===0||value.length>200){throw new UsageError(`--${name} must contain 1 to 200 characters`)}return value}function terminalStatus(value){if(value==="completed"||value==="failed"||value==="cancelled")return value;throw new UsageError("--status must be completed, failed, or cancelled")}function startValues(parsed){const model=parsed.options.model?.trim();if(model===void 0||model.length===0||model.length>200){throw new UsageError("--model must contain 1 to 200 characters")}return[...baseValues(parsed),model]}function captureResult(fold,reused){return{captured:true,reused,run:fold.run,status:fold.status}}function slug(value){return value.normalize("NFKD").replace(/[\u0300-\u036f]/g,"").toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,60)||"worker"}async function runValidationV2Command(action,parsed,filesystem,composition){if(action==="observe")return recordEvidenceObservation(parsed,filesystem,composition);if(action!=="record")throw new UsageError(`Unknown V2 Validation action: ${action??""}`);assertSafeRecordContent(parsed.options);requireOptions(parsed.options,["id","task","acceptance","command","outcome","locators","run"]);const outcome=parsed.options.outcome;if(outcome!=="passed"&&outcome!=="failed"&&outcome!=="not_applicable")throw new UsageError("validation record requires --outcome passed, failed, or not_applicable");const kindResult=assuranceValidationKindSchema.safeParse(parsed.options.kind??"test");if(!kindResult.success)throw new UsageError(`Invalid Validation kind: ${parsed.options.kind}`);const kind=kindResult.data;const id=parsed.options.id;const prefix=validationPrefix(kind);if(!id.startsWith(prefix))throw new UsageError(`Invalid ${kind} Validation id: ${id}`);const taskId=parsed.options.task;const mutation=kind==="mutation"?await mutationDiscrimination(parsed.options,filesystem):null;const{task}=await composition.tasks.read(taskId);const acceptanceIds=String(parsed.options.acceptance).split(",").filter(Boolean);if(acceptanceIds.length===0||acceptanceIds.some(id2=>!task.acceptance_ids.includes(id2))){throw new UsageError("Validation Acceptance Criteria must belong to the Task")}const executionId=resolveTaskExecutionIdV2(task,await composition.executions.list(),parsed.options.execution);const runId=parsed.options.run;const{run}=await composition.runs.read(runId);if(run.task_id!==taskId||run.change_id!==task.change_id||run.execution_id!==executionId){throw new UsageError(`Run does not link Task, Change, and Execution: ${runId}`)}const artifact=validationArtifactV2Schema.parse({schema_version:2,id,kind,task_id:taskId,change_id:task.change_id,execution_id:executionId,run_id:runId,acceptance_ids:acceptanceIds,executed_at:parsed.options["executed-at"]??new Date().toISOString(),command:parsed.options.command,status:outcome,asserted_outcomes:String(parsed.options["asserted-outcome"]??parsed.options.asserted??`validation ${outcome}`).split(",").filter(Boolean),locators:String(parsed.options.locators).split(",").filter(Boolean),author_id:parsed.options.author??"cli",commit_sha:parsed.options.commit??null,not_applicable_reason:outcome==="not_applicable"?parsed.options.reason??null:null});const directory=composition.changes.path(task.change_id).replace(/\/change\.md$/,"");const path=`${directory}/artifacts/tests/${id}.md`;await filesystem.writeTextAtomicExclusive(path,serializeMarkdown({metadata:artifact,body:`# Validation ${id}
|
|
1602
1602
|
|
|
1603
1603
|
${artifact.command}
|
|
1604
1604
|
`}));let mutationArtifactPath=null;if(mutation!==null){mutationArtifactPath=`${directory}/artifacts/checks/${id}-discrimination.md`;await filesystem.writeTextAtomicExclusive(mutationArtifactPath,serializeMarkdown({metadata:{kind:"mutation_discrimination",task_id:taskId,validation_artifact_id:id,executed_at:artifact.executed_at,commit_sha:artifact.commit_sha,baseline_passed:true,total_mutants:mutation.total,killed_mutants:mutation.killed,kill_ratio:mutation.killed/mutation.total,mutation_report:mutation.reportPath,acceptance_ids:acceptanceIds},body:`# Mutation discrimination ${id}
|
|
@@ -1608,7 +1608,7 @@ ${mutation.killed}/${mutation.total} mutants killed.
|
|
|
1608
1608
|
|
|
1609
1609
|
${observation.data.observed??"pending"}
|
|
1610
1610
|
`}));return{observation:observation.data,artifact_path:path}}async function mutationDiscrimination(options,filesystem){requireOptions(options,["mutation-report"]);const reportPath=options["mutation-report"];let report;try{report=JSON.parse(await filesystem.readText(reportPath))}catch{throw new UsageError("--mutation-report must reference readable runner JSON")}if(!isMutationReport(report)||report.baseline?.passed!==true||report.passed!==true||report.killed_mutants!==report.total_mutants||report.mutants.some(mutant=>mutant.killed!==true)){throw new UsageError("--mutation-report must prove a passed baseline and every mutant killed")}return{total:report.total_mutants,killed:report.killed_mutants,reportPath}}function isMutationReport(value){if(value===null||typeof value!=="object")return false;const report=value;return report.kind==="mutation_discrimination"&&Number.isSafeInteger(report.total_mutants)&&Number(report.total_mutants)>0&&Number.isSafeInteger(report.killed_mutants)&&Array.isArray(report.mutants)&&report.baseline!==null&&typeof report.baseline==="object"}function validationPrefix(kind){return{test:"TEST-",eval:"EVAL-",check:"CHECK-",review:"REVIEW-",spec_review:"REVIEW-SPEC-",quality_review:"REVIEW-QUALITY-",mutation:"MUT-",integration:"INT-",cross_spec_e2e:"E2E-"}[kind]}async function assertActiveDefinitionRun(input){const{area,runId,filesystem,composition}=input;const catalog=await loadAgentCatalog(filesystem);const expected=selectAgent(catalog,{role:area==="prd"?"analyst":"builder",capability:area==="prd"?"prd-creation":"spec-creation"}).agent;if(runId===null){throw new UsageError(`${area.toUpperCase()} definition requires an observed --run or exact-turn Run`)}const observed=await composition.runs.read(runId);const parent=observed.run.parent_run_id===null?null:await composition.runs.read(observed.run.parent_run_id);const invocation=await resolveRunClientInvocation(filesystem,"codex");const isStandaloneAuthoring=parent===null;const reworkAuthoring=input.reworkAuthoring===true||input.reworkSuccessorPrdId!==void 0;const authorizationRun=parent?.run??observed.run;const definitionAuthorized=authorizationRun.intake?.reason_codes.includes(`definition-${area}-authorized`)??false;if(!reworkAuthoring&&!definitionAuthorized){throw new UsageError(`${area.toUpperCase()} definition requires root intake authorization --definition ${area}`)}if(!reworkAuthoring&&authorizationRun.execution_kind!=="interaction"){throw new UsageError(`${area.toUpperCase()} definition requires a root interaction, not a delivery execution`)}if(!reworkAuthoring&&(authorizationRun.intake?.intent!=="conversation"||authorizationRun.intake.classification_source!=="explicit")){throw new UsageError(`${area.toUpperCase()} definition requires an explicit conversation root intake`)}const expectedAgent=reworkAuthoring&&area==="prd"?[expected.id,"agent-builder"]:[expected.id];const currentInvocationMatches=invocation.clientThreadId!==null&&invocation.clientTurnId!==null&&[observed.run,...parent===null?[]:[parent.run]].some(run=>run.client_thread_id===invocation.clientThreadId&&run.client_turn_id===invocation.clientTurnId);if(!expectedAgent.includes(observed.run.agent)||observed.run.agent===expected.id&&observed.run.agent_name!==expected.codex_name||observed.run.agent==="agent-builder"&&observed.run.agent_name!=="zaip-agent-builder"||observed.status!=="running"||observed.run.client!=="codex-subagent"||reworkAuthoring&&observed.run.work_type!=="rework"||input.reworkSuccessorPrdId!==void 0&&observed.run.prd_id!==input.reworkSuccessorPrdId||!isStandaloneAuthoring&&(observed.run.invocation_kind!=="delegated"||observed.run.run_purpose!=="execution")||!isStandaloneAuthoring&&(parent.status!=="running"||parent.run.parent_run_id!==null||parent.run.invocation_kind!=="orchestrator"||parent.run.agent!=="agent-orchestrator"||parent.run.agent_name!=="zaip-agent-orchestrator"||parent.run.execution_id!==observed.run.execution_id||parent.run.conversation_id!==observed.run.conversation_id||!currentInvocationMatches)){throw new UsageError(`${area.toUpperCase()} definition requires an active delegated ${expected.codex_name} Run linked to the root orchestration`)}return observed.run.run_id}function defaultExecutionPolicy(risk2,signals={}){const independentBranches=signals.independent_branches===true;return{failure_policy:"stop_on_terminal_failure",max_parallelism:risk2==="lite"?1:independentBranches?risk2==="critical"?3:2:1,max_operational_retries:risk2==="lite"?0:1,max_repair_cycles_per_task:risk2==="lite"?0:2,soft_model_cycle_budget:risk2==="lite"?4:risk2==="standard"?24:40,context_refresh_after_cycles:risk2==="lite"?4:8,verification_mode:risk2==="critical"?"full":"scoped",max_cost_usd:signals.max_cost_usd??null}}function completeObservedCostUsd(costs){if(costs.length===0||costs.some(cost2=>cost2===null))return null;return costs.reduce((sum,cost2)=>sum+cost2,0)}async function evaluateRunBudget(run,composition,filesystem){if(run.run.execution_id===null)return null;const execution=(await composition.executions.read(run.run.execution_id)).execution;const cycles=run.effective_usage_records.length;const providerInputTokens=run.effective_usage_records.reduce((sum,event)=>sum+Math.max(0,(event.tokens.input??0)-(event.tokens.cached_input??0)),0);const observedContextTokens=run.effective_usage_records.reduce((sum,event)=>sum+(event.context_stats?.initial_pack_tokens??0)+(event.context_stats?.tool_output_tokens??0),0);const measuredInputTokens=providerInputTokens>0?providerInputTokens:observedContextTokens;const cycleBudget=execution.policy.soft_model_cycle_budget??null;const refreshAfter=execution.policy.context_refresh_after_cycles??null;const checkpointRequired=cycleBudget!==null&&cycles>=cycleBudget;const contextRefreshRequired=refreshAfter!==null&&cycles>0&&cycles%refreshAfter===0;const costCapUsd=execution.policy.max_cost_usd??null;const observedCostUsd=completeObservedCostUsd(run.effective_usage_records.map(event=>event.cost.usd));const hasCompleteObservedCost=observedCostUsd!==null;const budget={schema_version:1,run_id:run.run.run_id,execution_id:execution.id,measured_at:new Date().toISOString(),cycles,provider_uncached_input_tokens:providerInputTokens,observed_context_tokens:observedContextTokens,measured_input_tokens:measuredInputTokens,measurement_source:providerInputTokens>0?"provider_uncached":"context_stats",soft_model_cycle_budget:cycleBudget,context_refresh_after_cycles:refreshAfter,max_cost_usd:costCapUsd,observed_cost_usd:observedCostUsd,cost_measurement_source:hasCompleteObservedCost?"observed":"unavailable",cost_checkpoint_required:costCapUsd!==null&&observedCostUsd!==null&&observedCostUsd>=costCapUsd,checkpoint_required:checkpointRequired,context_refresh_required:contextRefreshRequired};if(checkpointRequired||contextRefreshRequired||budget.cost_checkpoint_required){await filesystem.writeTextAtomic(`.local/checkpoints/${run.run.run_id}.json`,`${JSON.stringify(budget,null,2)}
|
|
1611
|
-
`)}return budget}async function cancelTaskRunsForHuman(taskId,composition,parsed){return composition.runs.withUsageAttributionLock(async()=>{const candidates=await composition.runs.list();const roots=candidates.filter(fold=>fold.finished===null&&fold.run.parent_run_id===null&&fold.run.task_id===taskId);for(const root of roots){await cancelActiveDescendantRuns(activeDescendantRuns(root.run.run_id,candidates),composition,parsed);await cancelActiveDescendantRuns([root],composition,parsed)}return roots.map(root=>root.run.run_id)})}async function cancelActiveDescendantRuns(descendants,composition,parsed){for(const descendant of[...descendants].reverse()){let current=await composition.runs.read(descendant.run.run_id);if(current.finished!==null)continue;if(current.effective_usage_records.length===0){const usage=unavailableUsageRecord(current,parsed,current.records.length+1);await composition.runs.appendRecord(usage);current=foldRunV2Records([...current.records,usage])}const record3=runFinishedV2Schema.parse({schema_version:2,event_id:runV2EventId(current.run.run_id,current.records.length+1),run_id:current.run.run_id,sequence:current.records.length+1,occurred_at:new Date().toISOString(),type:"run.finished",phase:latestRunV2Phase(current.records),status:"cancelled"});foldRunV2Records([...current.records,record3]);await composition.runs.appendRecord(record3)}}function aggregateRunsByAgent(runs,runCostInput2){const groups=new Map;for(const run of runs){const key=run.run.agent_name??run.run.agent;groups.set(key,[...groups.get(key)??[],run])}return[...groups.entries()].sort(([left],[right])=>left.localeCompare(right)).map(([agentName2,agentRuns])=>{const aggregate=aggregateRunV2Usage(agentRuns.map(runCostInput2),agentName2);const durations=agentRuns.flatMap(run=>{if(run.finished===null)return[];const duration3=Date.parse(run.finished.occurred_at)-Date.parse(run.run.occurred_at);return Number.isFinite(duration3)&&duration3>=0?[duration3]:[]});const cycles=agentRuns.map(run=>run.effective_usage_records.length);return{agent:agentRuns[0]?.run.agent??agentName2,agent_name:agentName2,run_count:agentRuns.length,rework_runs:agentRuns.filter(run=>run.run.work_type==="rework").length,duration:{known_runs:durations.length,unknown_runs:agentRuns.length-durations.length,total_ms:durations.reduce((sum,value)=>sum+value,0),average_ms:durations.length===0?null:Math.round(durations.reduce((sum,value)=>sum+value,0)/durations.length)},observed_usage_cycles:{total:cycles.reduce((sum,value)=>sum+value,0),average:cycles.length===0?null:Number((cycles.reduce((sum,value)=>sum+value,0)/cycles.length).toFixed(2))},tokens:aggregate.total.tokens,cost:aggregate.total.cost,coverage:aggregate.run_coverage}})}import{createHash as createHash29,randomBytes as randomBytes2}from"node:crypto";function lifecycleActionAlias(area,action){if(action===void 0)return action;const normalized=action.normalize("NFKD").replace(/[\u0300-\u036f]/g,"").toLocaleLowerCase();if(area==="prd"||area==="spec"){if(["pronto","pronto-para-executar","ready-to-execute"].includes(normalized))return"ready";if(["finalizar","finalize","concluir","conclude"].includes(normalized))return"finalize"}return normalized}function resolveMacroFinalizeAction(status){if(status==="draft"||status==="ready")return"ready";if(status==="active"||status==="verifying")return"continue";return null}function maxCostUsdOption(value){if(value===void 0)return null;const parsed=Number(value);if(!Number.isFinite(parsed)||parsed<0){throw new UsageError("--max-cost-usd must be a non-negative number")}return parsed}async function finalizeMacro(area,parsed,composition,makeReady){const id=requiredEntityId(parsed,2,`${area.toUpperCase()} id`);const entity=area==="prd"?(await composition.prds.read(id)).prd:(await composition.specs.read(id)).spec;const resolution=resolveMacroFinalizeAction(entity.status);if(resolution==="ready")return makeReady();if(resolution==="continue"){return{[area]:entity,next_action:"continue",message:`${area.toUpperCase()} ${id} remains active; finish its Tasks and parent gates before deliver`}}throw new UsageError(`${area.toUpperCase()} ${id} cannot finalize from status ${entity.status}`)}async function createPrdWithOptionalPlan(input){const{parsed,filesystem,composition,creationRunId}=input;requireOptions(parsed.options,["title","short-name","problem"]);const plan=parsed.options.plan===void 0?null:await readPreparedPlan(filesystem,parsed);if(plan!==null&&plan.blueprints.specs===void 0){throw new UsageError("Composite PRD creation requires technical SPEC blueprints; create canonical SPECs first, then use prd prepare for legacy plans")}if(plan!==null&&parsed.options.id===void 0){throw new UsageError("Composite PRD creation requires --id matching the PreparedPlan source")}if(plan!==null&&(plan.source.type!=="prd"||plan.source.prd_id!==parsed.options.id)){throw new UsageError(`Composite PRD plan must have source prd ${parsed.options.id}`)}const specIds=plan===null?[]:specIdsForPrdPlanV2(plan,parsed.options.id);const specCreationRunId=plan===null?null:await assertActiveDefinitionRun({area:"spec",runId:parsed.options["spec-run"]??null,filesystem,composition});if(plan!==null){await assertPreparedPlanReferences(filesystem,plan);await Promise.all((plan.blueprints.specs??[]).map(blueprint=>assertSpecImplementationMatchesProject(blueprint.implementation,filesystem,composition.layout)));const occupied=await Promise.all([filesystem.exists(composition.prds.path(parsed.options.id)),...specIds.map(id=>filesystem.exists(composition.specs.path(id)))]);if(occupied.some(Boolean)){throw new UsageError("Composite PRD creation requires unused PRD and SPEC artifact ids")}}const prd=await composition.prds.create({...parsed.options.id===void 0?{}:{id:parsed.options.id},title:parsed.options.title,shortName:parsed.options["short-name"],problem:parsed.options.problem,audiences:csvOption(parsed.options.audiences),outcomes:csvOption(parsed.options.outcomes),constraints:csvOption(parsed.options.constraints),nonGoals:csvOption(parsed.options["non-goals"]),creationRunId});if(plan===null)return{prd,artifact_path:composition.prds.path(prd.id)};const createdFiles=new Map([[composition.prds.path(prd.id),await filesystem.readText(composition.prds.path(prd.id))]]);const specBlueprints=new Map((plan.blueprints.specs??[]).map(blueprint=>[blueprint.id,blueprint]));try{const specs=[];for(const specId of specIds){const blueprint=specBlueprints.get(specId);if(blueprint===void 0){throw new UsageError(`Composite PRD plan lacks technical SPEC blueprint ${specId}`)}const spec=await composition.specs.create({id:specId,prdId:prd.id,title:blueprint.title,shortName:blueprint.short_name,objective:blueprint.objective,includedScope:blueprint.included_scope,excludedScope:blueprint.excluded_scope,requirementIds:blueprint.requirement_ids,acceptanceIds:blueprint.acceptance_ids,implementation:blueprint.implementation,creationRunId:specCreationRunId});specs.push(spec);const path=composition.specs.path(spec.id);createdFiles.set(path,await filesystem.readText(path))}const prepared=await composition.prds.setPreparedPlan(prd.id,plan);return{prd:prepared,specs,artifact_path:composition.prds.path(prepared.id),plan_hash:plan.hash,spec_blueprints:plan.blueprints.specs,materialized:false}}catch(error51){const recovered=await rollbackCompositeCreation(filesystem,createdFiles);if(recovered.length>0){throw new AggregateError([error51],`Composite PRD creation rolled back; concurrent edits were preserved at ${recovered.join(", ")}`)}throw error51}}async function createPrdRework(input){const{parsed,composition,creationRunId}=input;requireOptions(parsed.options,["title","short-name","problem"]);const sourceId=requiredPosition(parsed.positionals,2,"Cancelled PRD id");const prd=await composition.prds.createReworkSuccessor(sourceId,{...parsed.options.id===void 0?{}:{id:parsed.options.id},title:parsed.options.title,shortName:parsed.options["short-name"],problem:parsed.options.problem,audiences:csvOption(parsed.options.audiences),outcomes:csvOption(parsed.options.outcomes),constraints:csvOption(parsed.options.constraints),nonGoals:csvOption(parsed.options["non-goals"]),creationRunId});return{prd,artifact_path:composition.prds.path(prd.id),rework_of_prd_id:sourceId}}async function createSpecWithOptionalPlan(input){const{parsed,filesystem,composition,creationRunId}=input;requireOptions(parsed.options,["title","short-name","objective"]);const plan=parsed.options.plan===void 0?null:await readPreparedPlan(filesystem,parsed);if(plan!==null&&parsed.options.id===void 0){throw new UsageError("Composite SPEC creation requires --id matching the PreparedPlan source")}if(plan!==null&&(plan.source.type!=="spec"||plan.source.spec_id!==parsed.options.id)){throw new UsageError(`Composite SPEC plan must have source spec ${parsed.options.id}`)}const sourceSpecId=plan?.source.type==="spec"?plan.source.spec_id:null;const blueprint=plan===null||sourceSpecId===null?null:(plan.blueprints.specs??[]).find(candidate=>candidate.id===sourceSpecId);if(plan!==null){if(blueprint===void 0||blueprint===null){throw new UsageError(`Composite SPEC plan lacks technical SPEC blueprint ${sourceSpecId}`)}await assertPreparedPlanReferences(filesystem,plan);await assertSpecImplementationMatchesProject(blueprint.implementation,filesystem,composition.layout);if(await filesystem.exists(composition.specs.path(parsed.options.id))){throw new UsageError("Composite SPEC creation requires an unused SPEC artifact id")}}const spec=await composition.specs.create({...parsed.options.id===void 0?{}:{id:parsed.options.id},...parsed.options.prd===void 0?{}:{prdId:parsed.options.prd},title:blueprint?.title??parsed.options.title,shortName:blueprint?.short_name??parsed.options["short-name"],objective:blueprint?.objective??parsed.options.objective,includedScope:blueprint?.included_scope??csvOption(parsed.options.scope),excludedScope:blueprint?.excluded_scope??csvOption(parsed.options["out-of-scope"]),requirementIds:blueprint?.requirement_ids??csvOption(parsed.options.requirements),acceptanceIds:blueprint?.acceptance_ids??csvOption(parsed.options.acceptance),...blueprint===null||blueprint===void 0?{}:{implementation:blueprint.implementation},creationRunId});if(plan===null)return{spec,artifact_path:composition.specs.path(spec.id)};const path=composition.specs.path(spec.id);const original=await filesystem.readText(path);try{const prepared=await composition.specs.setPreparedPlan(spec.id,plan);return{spec:prepared,artifact_path:composition.specs.path(prepared.id),plan_hash:plan.hash,materialized:false}}catch(error51){const recovered=await rollbackCompositeCreation(filesystem,new Map([[path,original]]));if(recovered.length>0){throw new AggregateError([error51],`Composite SPEC creation rolled back; concurrent edits were preserved at ${recovered.join(", ")}`)}throw error51}}async function rollbackCompositeCreation(filesystem,createdFiles){const recovered=[];for(const[path,original]of createdFiles){if(!await filesystem.exists(path))continue;const digest6=createHash29("sha256").update(`${path}\0${randomBytes2(16).toString("hex")}`).digest("hex").slice(0,24);const recoveryPath=`.local/recovery/composite-create/${digest6}.md`;await filesystem.moveFileAtomic(path,recoveryPath);if(await filesystem.readText(recoveryPath)===original){await filesystem.removeFile(recoveryPath)}else recovered.push(recoveryPath)}return recovered}async function runLifecycleV2Command(area,action,parsed,filesystem,composition,lifecycle){action=lifecycleActionAlias(area,action);if(area==="prd")return runPrdV2Command(action,parsed,filesystem,composition,lifecycle);if(area==="spec")return runSpecV2Command(action,parsed,filesystem,composition,lifecycle);return runTaskV2Command(action,parsed,filesystem,composition,lifecycle)}async function runPrdV2Command(action,parsed,filesystem,composition,lifecycle){if(action==="finalize"){return finalizeMacro("prd",parsed,composition,()=>runLifecycleV2Command("prd","ready",parsed,filesystem,composition,lifecycle))}if(action==="create"){const creationRunId=await creationRunIdForCurrentTurn(parsed,filesystem,composition);return createPrdWithOptionalPlan({parsed,filesystem,composition,creationRunId})}if(action==="rework"){return createPrdRework({parsed,composition,creationRunId:await creationRunIdForCurrentTurn(parsed,filesystem,composition)})}if(action==="list"){return listLifecyclePage(await composition.prds.list(),parsed).map(prd=>({prd:compactPreparedEntity(prd),artifact_path:composition.prds.path(prd.id)}))}const id=requiredEntityId(parsed,2,"PRD id");if(action==="show"){return{...await composition.prds.read(id),artifact_path:composition.prds.path(id)}}if(action==="prepare"){const plan=await readPreparedPlan(filesystem,parsed);await assertPreparedPlanReferences(filesystem,plan);const prd=await composition.prds.setPreparedPlan(id,plan);const specs=await Promise.all(specIdsForPrdPlanV2(plan,id).map(async specId=>(await composition.specs.read(specId)).spec));return{prd,specs,artifact_path:composition.prds.path(id),plan_hash:plan.hash}}if(action==="ready"){const current=await composition.prds.read(id);const plan=await preparedPlanForReadyOrExecute(current.prd,"PRD",id,composition.materializer);await assertPreparedPlanReferences(filesystem,plan);if(!new Set(["draft","ready"]).has(current.prd.status)){throw new UsageError(`PRD cannot move to ready from status ${current.prd.status}: ${id}`)}const selectedSpecs=await Promise.all(specIdsForPrdPlanV2(plan,id).map(async specId=>(await composition.specs.read(specId)).spec));for(const spec of selectedSpecs){if(!new Set(["draft","ready"]).has(spec.status)){throw new UsageError(`SPEC cannot move to ready from status ${spec.status}: ${spec.id}`)}}const materialized=materializationOutput(await composition.materializer.execute(plan),composition);const prd=current.prd.status==="draft"?await composition.prds.transition(id,"ready"):current.prd;const specs=await Promise.all(selectedSpecs.map(spec=>spec.status==="draft"?composition.specs.transition(spec.id,"ready"):spec));return{...materialized,prd,specs,artifact_path:composition.prds.path(id)}}if(action==="execute"){const current=await composition.prds.read(id);const plan=await preparedPlanForReadyOrExecute(current.prd,"PRD",id,composition.materializer);await assertPreparedPlanReferences(filesystem,plan);if(!new Set(["draft","ready"]).has(current.prd.status)){throw new UsageError(`PRD cannot execute from status ${current.prd.status}: ${id}`)}const selectedSpecs=await Promise.all(specIdsForPrdPlanV2(plan,id).map(async specId=>(await composition.specs.read(specId)).spec));for(const spec of selectedSpecs){if(!new Set(["draft","ready"]).has(spec.status)){throw new UsageError(`SPEC cannot execute from status ${spec.status}: ${spec.id}`)}}const output2=materializationOutput(await composition.materializer.execute(plan),composition);const specs=await Promise.all(selectedSpecs.map(async selectedSpec=>{let spec=selectedSpec;if(spec.status==="draft")spec=await composition.specs.transition(spec.id,"ready");return spec.status==="ready"?composition.specs.transition(spec.id,"active"):spec}));if(current.prd.status==="draft")await composition.prds.transition(id,"ready");const preparedPrd=(await composition.prds.read(id)).prd;if(preparedPrd.status==="ready")await composition.prds.transition(id,"active");return{...output2,specs}}if(action==="deliver"){throw new UsageError("PRD terminal status is applied only by Gui through run finish")}if(action==="block"||action==="fail"){throw new UsageError("PRD terminal status is applied only by Gui through run finish")}if(action==="cancel"){throw new UsageError("PRD terminal status is applied only by Gui through run finish")}if(action==="activate"){const prd=await composition.prds.transition(id,"active");return{prd,artifact_path:composition.prds.path(id)}}throw new UsageError(`Unknown V2 PRD action: ${action??""}`)}async function runSpecV2Command(action,parsed,filesystem,composition,lifecycle){if(action==="finalize"){return finalizeMacro("spec",parsed,composition,()=>runLifecycleV2Command("spec","ready",parsed,filesystem,composition,lifecycle))}if(action==="create"){const creationRunId=await creationRunIdForCurrentTurn(parsed,filesystem,composition);return createSpecWithOptionalPlan({parsed,filesystem,composition,creationRunId})}if(action==="list"){const specs=(await composition.specs.list()).filter(spec=>parsed.options.prd===void 0||spec.prd_id===parsed.options.prd);return listLifecyclePage(specs,parsed).map(spec=>({spec:compactPreparedEntity(spec),artifact_path:composition.specs.path(spec.id)}))}const id=requiredEntityId(parsed,2,"SPEC id");if(action==="show"){return{...await composition.specs.read(id),artifact_path:composition.specs.path(id)}}if(action==="prepare"){const plan=await readPreparedPlan(filesystem,parsed);await assertPreparedPlanReferences(filesystem,plan);const spec=await composition.specs.setPreparedPlan(id,plan);return{spec,artifact_path:composition.specs.path(id),plan_hash:plan.hash}}if(action==="ready"){const current=await composition.specs.read(id);const plan=await preparedPlanForReadyOrExecute(current.spec,"SPEC",id,composition.materializer);await assertPreparedPlanReferences(filesystem,plan);if(!new Set(["draft","ready"]).has(current.spec.status)){throw new UsageError(`SPEC cannot move to ready from status ${current.spec.status}: ${id}`)}const materialized=materializationOutput(await composition.materializer.execute(plan),composition);const spec=current.spec.status==="draft"?await composition.specs.transition(id,"ready"):current.spec;return{...materialized,spec,artifact_path:composition.specs.path(id)}}if(action==="execute"){const current=await composition.specs.read(id);const plan=await preparedPlanForReadyOrExecute(current.spec,"SPEC",id,composition.materializer);await assertPreparedPlanReferences(filesystem,plan);if(!new Set(["draft","ready"]).has(current.spec.status)){throw new UsageError(`SPEC cannot execute from status ${current.spec.status}: ${id}`)}const output2=materializationOutput(await composition.materializer.execute(plan),composition);if(current.spec.status==="draft")await composition.specs.transition(id,"ready");const preparedSpec=(await composition.specs.read(id)).spec;if(preparedSpec.status==="ready")await composition.specs.transition(id,"active");return output2}if(action==="deliver"){throw new UsageError("SPEC terminal status is applied only by Gui through run finish")}if(action==="block"||action==="fail"){throw new UsageError("SPEC terminal status is applied only by Gui through run finish")}if(action==="cancel"){const changes=(await composition.changes.list()).filter(change=>change.source.type==="spec"&&change.source.spec_id===id||change.source.type==="prd"&&change.source.spec_id===id);const executions=(await composition.executions.list()).filter(execution=>execution.origin.type==="spec"&&execution.origin.spec_id===id);const taskIds=new Set([...changes.flatMap(change=>change.task_ids),...executions.flatMap(execution=>execution.dag.nodes.map(node=>node.task_id))]);const cancelled_run_ids=(await Promise.all([...taskIds].map(taskId=>cancelTaskRunsForHuman(taskId,composition,parsed)))).flat();const result2=await lifecycle.cancelSpec(id);return{...result2,cancelled_run_ids,artifact_path:composition.specs.path(id)}}if(action==="activate"){const spec=await composition.specs.transition(id,"active");return{spec,artifact_path:composition.specs.path(id)}}throw new UsageError(`Unknown V2 SPEC action: ${action??""}`)}async function creationRunIdForCurrentTurn(parsed,filesystem,composition){if(parsed.options.run!==void 0){return(await composition.runs.read(parsed.options.run)).run.run_id}const invocation=await resolveRunClientInvocation(filesystem,"codex");const intake=await findIntakeForExactTurn(composition,"codex",invocation);return intake?.run.run_id??null}async function runTaskV2Command(action,parsed,filesystem,composition,lifecycle){if(action==="create"){requireOptions(parsed.options,["title","short-name","objective","requirements","acceptance"]);const timeZone=composition.layout.project.timezone;const taskId=parsed.options.id??createId("TASK",parsed.options["short-name"],{timeZone});const changeId=parsed.options.change??createId("CHG",parsed.options["short-name"],{timeZone});const requirementIds=csvOption(parsed.options.requirements);const acceptanceIds=csvOption(parsed.options.acceptance);const risk2=riskOption(parsed.options.risk);const shortName=parsed.options["short-name"];const task=await composition.tasks.createDraft({id:taskId,changeId,title:parsed.options.title,shortName,objective:parsed.options.objective,risk:risk2,priority:priorityOption(parsed.options.priority),owner:parsed.options.owner??null,requirementIds,acceptanceIds,dependsOn:csvOption(parsed.options["depends-on"]),writeScopes:csvOption(parsed.options["write-scopes"])});const change=await composition.changes.createDraft({id:changeId,title:task.title,risk:task.risk,taskId:task.id,requirementIds,acceptanceIds});return{task,change,artifact_path:composition.tasks.path(task.id),change_path:composition.changes.path(change.id)}}if(action==="prepare"){const id2=requiredEntityId(parsed,2,"Task id");const current=await composition.tasks.read(id2);if(current.task.status==="planned"&¤t.task.prepared_plan!==void 0){await assertPreparedPlanReferences(filesystem,current.task.prepared_plan);return{task:current.task,artifact_path:composition.tasks.path(id2),plan_hash:current.task.prepared_plan.hash}}if(parsed.options.plan===void 0&¤t.task.depends_on.length>0){throw new UsageError("task prepare with dependencies requires --plan containing the complete DAG")}const timeZone=composition.layout.project.timezone;const executionId=await resolveTaskFirstExecutionId(parsed.options.execution,current.task.id,()=>composition.executions.list());const plan=parsed.options.plan===void 0?createTaskFirstPreparedPlan({task:current.task,executionId:executionId??createId("RUN",current.task.short_name,{timeZone}).replace(/^RUN-/,"EXEC-"),preparedAt:new Date().toISOString(),policy:defaultExecutionPolicy(current.task.risk,{independent_branches:parsed.flags.has("independent-branches"),max_cost_usd:maxCostUsdOption(parsed.options["max-cost-usd"])}),...parsed.options["requirement-impact"]===void 0?{}:{requirementImpactReason:parsed.options["requirement-impact"]}}):await readPreparedPlan(filesystem,parsed);await assertPreparedPlanReferences(filesystem,plan);const task=await composition.tasks.setPreparedPlan(id2,plan);const change=plan.blueprints.changes.find(candidate=>candidate.id===task.change_id);if(change===void 0)throw new UsageError(`Prepared plan does not contain Change ${task.change_id}`);await ensureTaskDraftChange(composition,task);await composition.changes.promoteDraft(task.change_id,plannedChangeFromBlueprint(change,plan,task.id));return{task,artifact_path:composition.tasks.path(id2),plan_hash:plan.hash}}if(action==="recover-intake"){requireOptions(parsed.options,["execution"]);const taskId=requiredEntityId(parsed,2,"Task id");const{task}=await composition.tasks.read(taskId);if(task.status!=="executing"||task.plan_ref===void 0)throw new UsageError(`Task has no active canonical plan reference: ${taskId}`);const plan=await composition.materializer.readPreparedPlan(task.plan_ref.execution_id);if(plan.hash!==task.plan_ref.hash||plan.source.type!=="task"||plan.source.task_id!==task.id)throw new UsageError(`Task plan reference cannot be resolved canonically: ${taskId}`);const intake=(await composition.executions.read(parsed.options.execution)).execution;if(intake.kind!=="delivery"||intake.origin.type!=="task"||intake.origin.task_id!==task.id)throw new UsageError(`Delivery intake does not belong to Task: ${intake.id}`);const current=intake;const nodes=plan.dag.nodes.map(node=>{const blueprint=plan.blueprints.tasks.find(candidate=>candidate.id===node.task_id);if(blueprint===void 0)throw new UsageError(`Prepared plan DAG lacks Task blueprint: ${node.task_id}`);return{task_id:node.task_id,change_id:blueprint.change_id,depends_on:node.depends_on}});const planned={...current,kind:"delivery",status:"planned",status_reason:null,plan_revision:plan.revision,plan_hash:plan.hash,policy:plan.policy,dag:{nodes,topological_order:plan.dag.topological_order}};const execution=await composition.executions.promoteDeliveryIntake(current.id,planned);return{task,execution,artifact_path:composition.executions.path(execution.id),recovered:true}}if(action==="execute"){const plan=parsed.options.plan!==void 0?await readPreparedPlan(filesystem,parsed):await preparedTaskPlan(composition.tasks,composition.materializer,requiredEntityId(parsed,2,"Task id"));await assertPreparedPlanReferences(filesystem,plan);if(plan.source.type!=="task"){throw new UsageError("task execute requires a task-first prepared plan")}const materialized=await existingTaskFirstMaterialization(plan,composition)??await composition.materializer.execute(plan);const taskId=plan.source.task_id;const task=materialized.tasks.find(candidate=>candidate.id===taskId);if(task===void 0){throw new UsageError(`Task-first plan did not materialize its source Task ${taskId}`)}const change=materialized.changes.find(candidate=>candidate.id===task.change_id);if(change===void 0){throw new UsageError(`Task-first plan did not materialize Change ${task.change_id}`)}assertTaskFirstExecutable(task.status,"Task",task.id);assertTaskFirstExecutable(materialized.execution.status,"Execution",materialized.execution.id);assertTaskFirstExecutable(change.status,"Change",change.id);const run=await ensureTaskOrchestratorRun(task,change.id,materialized.execution.id,parsed,filesystem,composition);let execution=(await composition.executions.read(materialized.execution.id)).execution;if(execution.status==="planned"){execution=await composition.executions.transition(execution.id,"running")}let activeChange=(await composition.changes.read(change.id)).change;if(activeChange.status==="planned"){activeChange=await composition.changes.transition(activeChange.id,"executing")}let activeTask=(await composition.tasks.read(task.id)).task;if(activeTask.status==="planned"){activeTask=await lifecycle.startTask(activeTask.id)}return{...materializationOutput(materialized,composition),execution,changes:[activeChange],tasks:[activeTask],run,run_path:composition.runs.path(run.run_id)}}if(action==="list"){const[tasks,changes]=await Promise.all([composition.tasks.list(),parsed.options.prd===void 0&&parsed.options.spec===void 0?Promise.resolve([]):composition.changes.list()]);const relatedChangeIds=new Set(changes.filter(change=>(parsed.options.prd===void 0||change.source.type==="prd"&&change.source.prd_id===parsed.options.prd)&&(parsed.options.spec===void 0||change.source.type==="spec"&&change.source.spec_id===parsed.options.spec||change.source.type==="prd"&&change.source.spec_id===parsed.options.spec)).map(change=>change.id));const filtered=tasks.filter(task=>parsed.options.prd===void 0&&parsed.options.spec===void 0||relatedChangeIds.has(task.change_id));return listLifecyclePage(filtered,parsed).map(task=>({task:compactPreparedEntity(task),artifact_path:composition.tasks.path(task.id)}))}if(action==="next"){const[tasks,executions]=await Promise.all([composition.tasks.list(),composition.executions.list()]);const completed=new Set(tasks.filter(task=>task.status==="completed").map(task=>task.id));const materialized=new Set(executions.flatMap(execution=>execution.dag.nodes.map(node=>node.task_id)));return tasks.filter(task=>task.status==="planned"&&materialized.has(task.id)&&task.depends_on.every(dependency=>completed.has(dependency))).map(task=>({task,artifact_path:composition.tasks.path(task.id)}))}const id=requiredEntityId(parsed,2,"Task id");if(action==="show"){return{...await composition.tasks.read(id),artifact_path:composition.tasks.path(id)}}if(action==="start"||action==="resume"||action==="rework"){const task=await lifecycle.startTask(id,action);return{task,artifact_path:composition.tasks.path(id)}}if(action==="verify"){const task=await lifecycle.verifyTask(id,csvOption(parsed.options.evidence));return{task,artifact_path:composition.tasks.path(id)}}if(action==="block"){throw new UsageError("Task terminal status is applied only by Gui through run finish")}if(action==="complete"){throw new UsageError("Task terminal status is applied only by Gui through run finish")}if(action==="fail"){throw new UsageError("Task terminal status is applied only by Gui through run finish")}if(action==="cancel"){const cancelled_run_ids=await cancelTaskRunsForHuman(id,composition,parsed);const result2=await lifecycle.cancelTask(id,"Explicit human cancellation",null);return{...result2,cancelled_run_ids,artifact_path:composition.tasks.path(id)}}throw new UsageError(`Unknown V2 Task action: ${action??""}`)}async function resolveTaskFirstExecutionId(explicitExecutionId,taskId,listExecutions){if(explicitExecutionId!==void 0)return explicitExecutionId;const deliveryIntake=(await listExecutions()).find(execution=>execution.kind==="delivery"&&execution.plan_hash===null&&execution.origin.type==="task"&&execution.origin.task_id===taskId);return deliveryIntake?.id}function assertTaskFirstExecutable(status,kind,id){if(status==="planned"||status==="executing"||status==="running")return;const guidance=status==="blocked"?"resume the Task before starting a new orchestrator agent call":status==="failed"?"rework the Task before starting a new orchestrator agent call":"terminal work is immutable";throw new UsageError(`${kind} ${id} cannot execute from status ${status}; ${guidance}`)}async function existingTaskFirstMaterialization(plan,composition){if(plan.source.type!=="task")return null;const existing=await Promise.all([composition.tasks.read(plan.source.task_id).catch(()=>null),composition.executions.read(plan.execution_id).catch(()=>null)]);const task=existing[0]?.task;const execution=existing[1]?.execution;if(task===void 0||execution===void 0||task.plan_hash!==plan.hash||execution.plan_hash!==plan.hash||!execution.dag.nodes.some(node=>node.task_id===task.id&&node.change_id===task.change_id)){return null}const change=await composition.changes.read(task.change_id).catch(()=>null);if(change===null||change.change.plan_hash!==plan.hash)return null;const reusedPaths=[composition.executions.path(execution.id),composition.changes.path(change.change.id),composition.tasks.path(task.id)];return{execution,changes:[change.change],tasks:[task],created_paths:[],reused_paths:reusedPaths}}async function ensureTaskOrchestratorRun(task,changeId,executionId,parsed,filesystem,composition){const runs=await composition.runs.list();const existing=runs.filter(candidate=>candidate.finished===null&&effectiveRunV2Role(candidate.run)==="orchestrator"&&candidate.run.parent_run_id===null&&candidate.run.task_id===task.id&&candidate.run.execution_id===executionId).sort((left,right)=>right.run.occurred_at.localeCompare(left.run.occurred_at))[0];if(existing!==void 0)return existing.run;const invocation=await resolveRunClientInvocation(filesystem,"codex");if(invocation.clientTurnId!==null){await composition.executions.claimClientTurn(executionId,invocation.clientTurnId)}const intake=await findIntakeForExactTurn(composition,"codex",invocation);const source=intake?.run;const developerIdentity=await resolveDeveloperIdentityForRoot(filesystem);const writer=await composition.runs.start({...parsed.options.run===void 0?{}:{id:parsed.options.run},shortName:task.short_name,phase:"execution",runRole:"orchestrator",runPurpose:"orchestration",requiresFinalizer:true,executionKind:"delivery",executionEligibility:[],entrypoint:"task",workType:source?.work_type??"new",client:"codex",agent:"agent-orchestrator",agentName:"zaip-agent-orchestrator",provider:source?.provider??null,model:parsed.options.model??source?.model??"unknown",reasoningEffort:source?.reasoning_effort??null,...invocation,conversationId:source?.conversation_id??createConversationId(task.short_name),executionId,taskId:task.id,changeId,developerIdentity});return writer.started}async function ensureTaskDraftChange(composition,task){const existing=await composition.changes.read(task.change_id).catch(()=>null);if(existing!==null)return existing.change;return composition.changes.createDraft({id:task.change_id,title:task.title,risk:task.risk,taskId:task.id,requirementIds:task.requirement_ids,acceptanceIds:task.acceptance_ids})}function plannedChangeFromBlueprint(blueprint,plan,taskId){return{schema_version:2,id:blueprint.id,revision:1,title:blueprint.title,status:"planned",risk:blueprint.risk,source:blueprint.source,requirement_ids:[...blueprint.requirement_ids],acceptance_ids:[...blueprint.acceptance_ids],requirement_impact:blueprint.requirement_impact,task_ids:[taskId],plan_revision:plan.revision,plan_hash:plan.hash,created_at:plan.prepared_at,updated_at:plan.prepared_at,started_at:null,finished_at:null,result:null}}function materializationOutput(result2,composition){return{execution:result2.execution,changes:result2.changes,tasks:result2.tasks,artifact_path:composition.executions.path(result2.execution.id),change_paths:result2.changes.map(change=>composition.changes.path(change.id)),task_paths:result2.tasks.map(task=>composition.tasks.path(task.id)),created_paths:result2.created_paths,reused_paths:result2.reused_paths}}async function preparedPlanForReadyOrExecute(entity,kind,id,materializer){if(entity.prepared_plan!==null)return entity.prepared_plan;if(entity.plan_ref!==null)return materializer.readPreparedPlan(entity.plan_ref.execution_id);throw new UsageError(`${kind} is not prepared: ${id}`)}var ORPHANED_RUN_GRACE_MS=10*60*1e3;var ORPHANED_EXECUTION_GRACE_MS=10*60*1e3;var ACTIVE_INVOCATION_START_TOLERANCE_MS=2*60*1e3;async function reconcileOpenWork(parsed,composition,lifecycle,filesystem){let runs=await composition.runs.list();const runningCodex=runs.filter(fold=>[fold.finished===null,isCodexTelemetryClient(fold.run.client),fold.run.client_thread_id!==null].every(Boolean));const threadIds=runningCodex.flatMap(fold=>typeof fold.run.client_thread_id==="string"?[fold.run.client_thread_id]:[]);const invocations=runningCodex.flatMap(fold=>{const threadId=fold.run.client_thread_id;const turnId=fold.run.client_turn_id;return typeof threadId==="string"&&typeof turnId==="string"?[{threadId,turnId}]:[]});const[localLifecycles,activeInvocations]=await Promise.all([listCodexInvocationLifecycles(filesystem.root,{threadIds,invocations}),listActiveCodexInvocations(filesystem.root,{threadIds})]);const localByInvocation=new Map(localLifecycles.map(item=>[`${item.sessionId}:${item.turnId}`,item]));const closedRuns=[];const reconciliationStartedAt=new Date;for(const fold of runningCodex){if((await composition.runs.read(fold.run.run_id)).finished!==null)continue;const local=localByInvocation.get(`${fold.run.client_thread_id??""}:${fold.run.client_turn_id??""}`);const completedLocally=(local?.status==="completed"||local?.status==="cancelled"||local?.status==="interrupted")&&local.finishedAt!==null;const orphaned=isOrphanedCodexRun(fold,activeInvocations,reconciliationStartedAt);if(!completedLocally&&!orphaned)continue;const role=effectiveRunV2Role(fold.run);const activeChildren=activeDescendantRuns(fold.run.run_id,runs);if(role==="orchestrator"&&activeChildren.length>0){if(local?.status!=="cancelled")continue;await cancelActiveDescendantRuns2(activeChildren,composition,parsed);runs=await composition.runs.list()}let current=completedLocally?await recordCodexTelemetryIfAvailable(fold,composition,filesystem):fold;if(current.effective_usage_records.length===0){await composition.runs.appendRecord(unavailableUsageRecord(current,parsed,current.records.length+1));current=await composition.runs.read(current.run.run_id)}const finished=runFinishedV2Schema.parse({schema_version:2,event_id:`${current.run.run_id}:${String(current.records.length+1).padStart(6,"0")}`,run_id:current.run.run_id,sequence:current.records.length+1,occurred_at:completedLocally?local.finishedAt:new Date().toISOString(),type:"run.finished",phase:latestRunV2Phase(current.records),status:completedLocally&&local?.status==="cancelled"?"cancelled":completedLocally?"completed":"failed"});foldRunV2Records([...current.records,finished]);await composition.runs.appendRecord(finished);closedRuns.push(await composition.runs.read(current.run.run_id))}if(closedRuns.length>0)runs=await composition.runs.list();let[tasks,changes,executions,specs,prds]=await Promise.all([composition.tasks.list(),composition.changes.list(),composition.executions.list(),composition.specs.list(),composition.prds.list()]);let catalog={tasks,changes,executions,specs,prds};const explicitlyCancelled=await closeExplicitlyCancelledTaskRoots(runs,catalog,composition,parsed);if(explicitlyCancelled.length>0){closedRuns.push(...explicitlyCancelled);runs=await composition.runs.list()}const activeSubjectIds=activeLifecycleSubjectIds(runs.filter(item=>item.finished===null),catalog);const operationalSubjectIds=terminalReconciliationSubjectIds(catalog);const reconciliations=[];const reconciliationErrors=[];const reconciledSubjectIds=new Set;const terminal=runs.filter(fold=>fold.finished!==null&&terminalSubjectIds(fold).some(id=>operationalSubjectIds.has(id))).sort((left,right)=>(right.finished?.occurred_at??right.run.occurred_at).localeCompare(left.finished?.occurred_at??left.run.occurred_at));for(const fold of terminal){const subjects=terminalSubjectIds(fold);if(subjects.length===0||subjects.some(id=>activeSubjectIds.has(id))||subjects.every(id=>reconciledSubjectIds.has(id))){continue}try{reconciliations.push(await reconcileFinishedRunLifecycle(fold,composition,lifecycle,{catalog,candidateRuns:runs}))}catch(error51){const message=error51 instanceof Error?error51.message:String(error51);reconciliations.push({...await snapshotRunLifecycle(fold,composition,catalog),status:"deferred",error:message});reconciliationErrors.push({run_id:fold.run.run_id,error:message})}subjects.forEach(id=>{reconciledSubjectIds.add(id)})}[tasks,changes,executions,specs,prds]=await Promise.all([composition.tasks.list(),composition.changes.list(),composition.executions.list(),composition.specs.list(),composition.prds.list()]);catalog={tasks,changes,executions,specs,prds};const orphanedExecutions=await blockOrphanedStandaloneExecutions(catalog,runs,composition,reconciliationStartedAt);const orphanedInteractionExecutions=await blockOrphanedInteractionExecutions(catalog,runs,composition,reconciliationStartedAt);return{runs:closedRuns,orphaned_executions:orphanedExecutions.map(execution=>execution.id),orphaned_interaction_executions:orphanedInteractionExecutions.map(execution=>execution.id),orphaned_execution_entities:[...orphanedExecutions,...orphanedInteractionExecutions],reconciliations,reconciliation_errors:reconciliationErrors,unresolved_running_run_ids:runs.filter(fold=>fold.finished===null).map(fold=>fold.run.run_id)}}async function closeExplicitlyCancelledTaskRoots(runs,catalog,composition,parsed){const cancelledTaskIds=new Set(catalog.tasks.filter(task=>task.status==="cancelled").map(task=>task.id));const closed=[];for(const fold of runs){if(fold.finished!==null||effectiveRunV2Role(fold.run)!=="orchestrator"||fold.run.parent_run_id!==null||fold.run.entrypoint!=="task"||fold.run.task_id===null||!cancelledTaskIds.has(fold.run.task_id)){continue}const current=await composition.runs.read(fold.run.run_id);if(current.finished!==null)continue;const activeChildren=activeDescendantRuns(current.run.run_id,runs);if(activeChildren.length>0)await cancelActiveDescendantRuns2(activeChildren,composition,parsed);let attributable=await composition.runs.read(current.run.run_id);if(attributable.effective_usage_records.length===0){await composition.runs.appendRecord(unavailableUsageRecord(attributable,parsed,attributable.records.length+1));attributable=await composition.runs.read(current.run.run_id)}await composition.runs.appendRecord(runFinishedV2Schema.parse({schema_version:2,event_id:`${attributable.run.run_id}:${String(attributable.records.length+1).padStart(6,"0")}`,run_id:attributable.run.run_id,sequence:attributable.records.length+1,occurred_at:new Date().toISOString(),type:"run.finished",phase:latestRunV2Phase(attributable.records),status:"cancelled"}));closed.push(await composition.runs.read(current.run.run_id))}return closed}async function cancelActiveDescendantRuns2(descendants,composition,parsed){for(const descendant of[...descendants].reverse()){let current=await composition.runs.read(descendant.run.run_id);if(current.finished!==null)continue;if(current.effective_usage_records.length===0){await composition.runs.appendRecord(unavailableUsageRecord(current,parsed,current.records.length+1));current=await composition.runs.read(current.run.run_id)}await composition.runs.appendRecord(runFinishedV2Schema.parse({schema_version:2,event_id:`${current.run.run_id}:${String(current.records.length+1).padStart(6,"0")}`,run_id:current.run.run_id,sequence:current.records.length+1,occurred_at:new Date().toISOString(),type:"run.finished",phase:latestRunV2Phase(current.records),status:"cancelled"}))}}async function blockOrphanedStandaloneExecutions(catalog,runs,composition,now){const ids=orphanedStandaloneExecutionIds(catalog,runs,now);if(ids.length===0)return[];const clock=new SystemClock;const taskById=new Map(catalog.tasks.map(task=>[task.id,task]));const changeById=new Map(catalog.changes.map(change=>[change.id,change]));const blocked=[];for(const id of ids){const execution=catalog.executions.find(item=>item.id===id);if(execution===void 0)continue;const reason=`Execution ${id} has no active orchestrator agent call after the reconciliation grace period.`;for(const node of execution.dag.nodes){const task=taskById.get(node.task_id);if(task!==void 0&&["executing","verifying"].includes(task.status)){await composition.tasks.transition(task.id,"blocked",null,clock,reason)}const change=changeById.get(node.change_id);if(change!==void 0&&["executing","verifying"].includes(change.status)){await composition.changes.transition(change.id,"blocked",null,clock,reason)}}await composition.executions.transition(id,"blocked",null,clock,reason);blocked.push((await composition.executions.read(id)).execution)}return blocked}async function blockOrphanedInteractionExecutions(catalog,runs,composition,now){const ids=orphanedInteractionExecutionIds(catalog,runs,now);if(ids.length===0)return[];const clock=new SystemClock;const blocked=[];for(const id of ids){await composition.executions.transition(id,"blocked",null,clock,`Interaction Execution ${id} has no active orchestrator Run after the reconciliation grace period.`);blocked.push((await composition.executions.read(id)).execution)}return blocked}function orphanedStandaloneExecutionIds(catalog,runs,now=new Date){return catalog.executions.flatMap(execution=>{if(execution.origin.type!=="task"||!["running","verifying"].includes(execution.status)){return[]}const startedAt=Date.parse(execution.started_at??execution.updated_at??execution.created_at);if(!Number.isFinite(startedAt)||now.getTime()-startedAt<ORPHANED_EXECUTION_GRACE_MS){return[]}const taskIds=new Set(execution.dag.nodes.map(node=>node.task_id));const hasActiveOrchestratorRun=runs.some(run=>{const required2=[run.finished===null,effectiveRunV2Role(run.run)==="orchestrator",run.run.parent_run_id===null,run.run.entrypoint==="task"];if(!required2.every(Boolean))return false;return run.run.execution_id===execution.id||run.run.task_id!==null&&taskIds.has(run.run.task_id)});return hasActiveOrchestratorRun?[]:[execution.id]})}function orphanedInteractionExecutionIds(catalog,runs,now=new Date){return catalog.executions.flatMap(execution=>{if(execution.kind!=="interaction"||!["running","verifying"].includes(execution.status)){return[]}const startedAt=Date.parse(execution.started_at??execution.updated_at??execution.created_at);if(!Number.isFinite(startedAt)||now.getTime()-startedAt<ORPHANED_EXECUTION_GRACE_MS){return[]}const hasActiveRoot=runs.some(run=>run.finished===null&&effectiveRunV2Role(run.run)==="orchestrator"&&run.run.parent_run_id===null&&run.run.execution_id===execution.id);return hasActiveRoot?[]:[execution.id]})}function terminalReconciliationSubjectIds(catalog){const ids=new Set;const unsettledTaskIds=new Set(catalog.tasks.filter(task=>["executing","verifying"].includes(task.status)).map(task=>task.id));unsettledTaskIds.forEach(id=>{ids.add(id)});for(const change of catalog.changes){const unsettled=["planned","executing","verifying"].includes(change.status);const hasUnsettledTask=change.task_ids.some(id=>unsettledTaskIds.has(id));if(!unsettled&&!hasUnsettledTask)continue;change.task_ids.forEach(id=>{ids.add(id)});if(change.source.type==="spec")ids.add(change.source.spec_id);if(change.source.type==="prd"){ids.add(change.source.prd_id);if(change.source.spec_id!==null)ids.add(change.source.spec_id)}}for(const execution of catalog.executions){if(!["planned","running","paused","verifying"].includes(execution.status))continue;execution.dag.nodes.forEach(node=>{ids.add(node.task_id)})}catalog.specs.filter(spec=>spec.status==="active").forEach(spec=>{ids.add(spec.id)});catalog.prds.filter(prd=>prd.status==="active").forEach(prd=>{ids.add(prd.id)});return ids}function isOrphanedCodexRun(fold,activeInvocations,now=new Date){if(fold.finished!==null||!isCodexTelemetryClient(fold.run.client))return false;const startedAt=Date.parse(fold.run.occurred_at);if(!Number.isFinite(startedAt)||now.getTime()-startedAt<ORPHANED_RUN_GRACE_MS){return false}return!activeInvocations.some(active=>{if(active.sessionId!==fold.run.client_thread_id)return false;const activeObservedAt=Date.parse(active.observedAt??active.startedAt??"");if(!Number.isFinite(activeObservedAt)||now.getTime()-activeObservedAt>ORPHANED_RUN_GRACE_MS){return false}if(active.turnId===fold.run.client_turn_id)return true;const activeStartedAt=active.startedAt===null?Number.NaN:Date.parse(active.startedAt);return Number.isFinite(activeStartedAt)&&Math.abs(activeStartedAt-startedAt)<=ACTIVE_INVOCATION_START_TOLERANCE_MS})}function activeLifecycleSubjectIds(activeRuns,catalog){const ids=new Set;const taskById=new Map(catalog.tasks.map(task=>[task.id,task]));const changeById=new Map(catalog.changes.map(change=>[change.id,change]));const specById=new Map(catalog.specs.map(spec=>[spec.id,spec]));for(const fold of activeRuns){relatedWorkIds(fold).forEach(id=>{ids.add(id)});const task=fold.run.task_id===null?void 0:taskById.get(fold.run.task_id);const change=task===void 0?void 0:changeById.get(task.change_id);const specId=fold.run.spec_id??(change?.source.type==="spec"||change?.source.type==="prd"?change.source.spec_id:null);const prdId=fold.run.prd_id??(change?.source.type==="prd"?change.source.prd_id:null)??(specId===null?null:specById.get(specId)?.prd_id??null);if(change!==void 0)ids.add(change.id);if(specId!==null)ids.add(specId);if(prdId!==null)ids.add(prdId);for(const candidate of catalog.changes){const belongsToSpec=specId!==null&&candidate.source.type!=="task"&&candidate.source.spec_id===specId;const belongsToPrd=candidate.source.type==="prd"&&candidate.source.prd_id===prdId;if(!belongsToSpec&&!belongsToPrd)continue;ids.add(candidate.id);candidate.task_ids.forEach(id=>{ids.add(id)})}for(const execution of catalog.executions){if(execution.origin.type==="prd"&&execution.origin.prd_id===prdId||execution.origin.type==="spec"&&execution.origin.spec_id===specId){ids.add(execution.id);execution.dag.nodes.forEach(node=>{ids.add(node.task_id)})}}}return ids}function relatedWorkIds(fold){return[fold.run.task_id,fold.run.spec_id,fold.run.prd_id].filter(id=>id!==null)}function terminalSubjectIds(fold){const role=effectiveRunV2Role(fold.run);if(role==="orchestrator"&&fold.run.entrypoint==="task"){return fold.run.task_id===null?[]:[fold.run.task_id]}if(role==="orchestrator"){return[fold.run.spec_id,fold.run.prd_id].filter(id=>id!==null)}return[]}async function reconcileHistoricalCodexTiming(parsed,composition,filesystem){requireOptions(parsed.options,["id","session","turn"]);const id=parsed.options.id;const turnId=parsed.options.turn;const sessionPath=parsed.options.session;const current=await composition.runs.read(id);if(current.run.client_turn_id!==turnId){throw new UsageError(`Run ${id} is not correlated with the requested turn`)}const candidate=await findLatestCodexSegment(filesystem.root,new Set,{turnId,sessionPaths:[sessionPath],...current.run.client_thread_id==null?{}:{threadId:current.run.client_thread_id}});if(candidate===null||candidate.startedAt===null||candidate.finishedAt===null||candidate.turnId!==turnId){throw new UsageError("No completed observed interval exists for the requested Run/session/turn")}const sourceSegmentKey=candidate.segmentKey;const sourceUsage=current.effective_usage_records.find(record3=>record3.source_segment_key===sourceSegmentKey);if(sourceUsage===void 0){throw new UsageError("No existing usage segment matches the requested observed session turn")}const existing=current.records.find(record3=>record3.type==="usage.recorded"&&record3.supersedes_event_id===sourceUsage.event_id&&"source_started_at"in record3&&record3.source_started_at===candidate.startedAt&&"source_finished_at"in record3&&record3.source_finished_at===candidate.finishedAt);const timing={run_id:id,session:sessionPath,turn_id:turnId,source_started_at:candidate.startedAt,source_finished_at:candidate.finishedAt,source_duration_ms:Date.parse(candidate.finishedAt)-Date.parse(candidate.startedAt),source_segment_key:sourceSegmentKey,supersedes_event_id:sourceUsage.event_id};if(parsed.flags.has("dry-run")||existing!==void 0){return{applied:false,reason:existing===void 0?"dry-run":"already-reconciled",timing}}const sequence=current.records.length+1;await composition.runs.appendRecord(usageRecordedV2Schema.parse({schema_version:2,event_id:runV2EventId(id,sequence),run_id:id,sequence,occurred_at:new Date().toISOString(),type:"usage.recorded",phase:latestRunV2Phase(current.records),activity_kind:"retrospective_local_remeasurement",classification_source:sourceUsage.classification_source,tokens:sourceUsage.tokens,cost:sourceUsage.cost,provider:sourceUsage.provider,model:sourceUsage.model,source_segment_key:sourceSegmentKey,supersedes_event_id:sourceUsage.event_id,retrospective_correction:true,source_occurred_at:candidate.finishedAt,source_started_at:candidate.startedAt,source_finished_at:candidate.finishedAt}));return{applied:true,timing,artifact_path:composition.runs.path(id)}}function sameStringSet2(left,right){return left.length===right.length&&left.every(value=>right.includes(value))}function runV2CostInput2(fold){return{run:{run_id:fold.run.run_id,attribution_status:fold.run.attribution_status,conversation_id:fold.run.conversation_id,execution_id:fold.run.execution_id,task_id:fold.run.task_id,spec_id:fold.run.spec_id,prd_id:fold.run.prd_id,change_id:fold.run.change_id,work_type:fold.run.work_type},records:fold.records,effective_usage_records:fold.effective_usage_records}}function runV2ScopeOption(parsed){return parsed.positionals[2]??parsed.options.id??parsed.options.conversation??parsed.options.execution??parsed.options.task??parsed.options.spec??parsed.options.prd??parsed.options.change??null}async function runRunV2Command(action,parsed,composition,filesystem,lifecycle){if(action==="start"){requireOptions(parsed.options,["short-name","phase","entrypoint","work-type","client","model"]);const client=parsed.options.client;const phase=runV2PhaseOption(parsed.options.phase);const parentRunId=parsed.options.parent??null;const clientInvocation=await resolveRunClientInvocation(filesystem,client);const agentResolution=await resolveRunAgentIdentityResult(filesystem,{agent:parsed.options.agent,client});const agent=agentResolution.agent_id;const runPurpose=parsed.options["run-purpose"]===void 0?phase!=="execution"?"intake":agent==="agent-finalizer"?"finalization":agent==="agent-reviewer"?"review":agent==="agent-auditor"?"audit":parentRunId===null?"orchestration":"execution":runV2PurposeSchema.parse(parsed.options["run-purpose"]);const catalog=await loadAgentCatalog(filesystem).catch(()=>null);const catalogAgent=catalog?.agents.find(candidate=>candidate.id===agent);const parent=parentRunId===null?null:await composition.runs.read(parentRunId);const execution=parent===null&&parsed.options.execution!==void 0?await composition.executions.read(parsed.options.execution).catch(()=>null):null;const executionKind=parent?.run.execution_kind??execution?.execution.kind??void 0;const rootDeveloperIdentity=parentRunId===null?await resolveDeveloperIdentityForRoot(filesystem):void 0;const input={...parsed.options.id===void 0?{}:{id:parsed.options.id},shortName:parsed.options["short-name"],phase,...parsed.options["run-role"]===void 0?{}:{runRole:runV2RoleSchema.parse(parsed.options["run-role"])},runPurpose,...executionKind===void 0?{}:{executionKind},executionEligibility:catalogAgent?.execution_eligibility??[],entrypoint:runV2EntrypointOption(parsed.options.entrypoint),workType:runV2WorkTypeOption(parsed.options["work-type"]),client,agent,agentName:await resolveRunAgentName(filesystem,agent),...agentResolution.warning===null?{}:{agentIdentityWarning:agentResolution.warning},provider:parsed.options.provider??null,model:parsed.options.model,reasoningEffort:parsed.options["reasoning-effort"]===void 0?null:runV2ReasoningEffortSchema.parse(parsed.options["reasoning-effort"]),...clientInvocation,conversationId:parsed.options.conversation??createConversationId(parsed.options["short-name"]),executionId:parsed.options.execution??null,taskId:parsed.options.task??null,specId:parsed.options.spec??null,prdId:parsed.options.prd??null,changeId:parsed.options.change??null,parentRunId,continuationOfRunId:parsed.options.continuation??null,retryOfRunId:parsed.options.retry??null,...rootDeveloperIdentity===void 0?{}:{developerIdentity:rootDeveloperIdentity}};await validateRunV2Attribution(input,composition);const start=async()=>{if(parentRunId!==null){const freshParent=await composition.runs.read(parentRunId);const candidates=await composition.runs.list();assertChildRunMayStart(freshParent,runPurpose,agent,candidates,catalogAgent?.execution_eligibility??[])}const writer=await composition.runs.start(input);return{run:writer.started,artifact_path:composition.runs.path(writer.started.run_id),warnings:agentResolution.warning===null?[]:[agentResolution.warning]}};return parentRunId===null?start():composition.runs.withUsageAttributionLock(start)}if(action==="list"||action==="aggregate"){const runs=filterRunV2Folds(await composition.runs.list(),parsed);if(action==="aggregate"){const aggregate=aggregateRunV2Usage(runs.map(runV2CostInput2),runV2ScopeOption(parsed));const agents=aggregateRunsByAgent(runs,runV2CostInput2);return parsed.options.view==="full"?{...aggregate,agents}:{...compactRunAggregate(aggregate),agents}}const summaries=runs.map(run=>runV2Summary(run,composition));return listLifecyclePage(summaries,parsed)}if(action==="reconcile"){if(parsed.flags.has("open"))return reconcileOpenWork(parsed,composition,lifecycle,filesystem);return reconcileHistoricalCodexTiming(parsed,composition,filesystem)}const id=requiredEntityId(parsed,2,"Run V2 id");if(action==="show"){const run=await composition.runs.read(id);const includeEvents=parsed.flags.has("events")||parsed.options["event-id"]!==void 0||parsed.options["from-sequence"]!==void 0;return includeEvents?{run:{...run,records:run.records.filter(record3=>(parsed.options["event-id"]===void 0||record3.event_id===parsed.options["event-id"])&&(parsed.options["from-sequence"]===void 0||record3.sequence>=numberOption(parsed.options["from-sequence"],1)))},artifact_path:composition.runs.path(id)}:runV2Summary(run,composition)}if(action==="recover-attribution"){return composition.runs.withUsageAttributionLock(async()=>{const current=await composition.runs.read(id);const started=current.records[0];if(current.finished!==null)throw new UsageError(`Run V2 is already finished: ${id}`);if(started?.type!=="run.started")throw new UsageError(`Run V2 has no start record: ${id}`);if(current.attribution_recovery!==null){throw new UsageError(`Run V2 already has an attribution recovery: ${id}`)}if(current.run.entrypoint!=="task"||current.run.execution_id===null||current.run.task_id===null||current.run.change_id!==null){throw new UsageError(`Run ${id} is not an active task Run with an unclaimed Change attribution`)}const task=await composition.tasks.read(current.run.task_id);const changeId=task.task.change_id;if(changeId===null)throw new UsageError(`Task ${task.task.id} has no materialized Change`);await validateRunV2Attribution({shortName:current.run.run_id,phase:"execution",entrypoint:"task",workType:current.run.work_type,client:current.run.client,agent:current.run.agent,provider:current.run.provider,model:current.run.model,conversationId:current.run.conversation_id,executionId:current.run.execution_id,taskId:current.run.task_id,changeId,parentRunId:current.run.parent_run_id,continuationOfRunId:current.run.continuation_of_run_id,retryOfRunId:current.run.retry_of_run_id},composition);const record3=runAttributionRecoveredV2Schema.parse({schema_version:2,event_id:runV2EventId(id,current.records.length+1),run_id:id,sequence:current.records.length+1,occurred_at:new Date().toISOString(),type:"run.attribution.recovered",phase:"execution",execution_id:current.run.execution_id,task_id:current.run.task_id,change_id:changeId});await composition.runs.appendRecord(record3);return{recovery:record3,run:runV2Summary(await composition.runs.read(id),composition),artifact_path:composition.runs.path(id)}})}if(action==="closure"){const current=await composition.runs.read(id);if(current.finished===null)throw new UsageError(`Run V2 is still running: ${id}`);const closure=await assessRunLifecycleClosure(current,composition);if(closure.status==="action_required"){throw new UsageError(`Run ${id} left related work open: ${closure.open_subject_ids.join(", ")}. ${closure.guidance}`)}return{closure,artifact_path:composition.runs.path(id)}}if(action==="usage"){let current=await composition.runs.read(id);if(current.finished!==null)throw new UsageError(`Run V2 is already finished: ${id}`);const appServerEventsPath=parsed.options["codex-app-server-events"];const rawCaptureDisabled=parsed.flags.has("disable-codex-raw");if(appServerEventsPath!==void 0&&!rawCaptureDisabled){const notifications=parseCodexAppServerNotificationStream(await filesystem.readText(appServerEventsPath));const persisted=await ingestCodexAppServerNotifications(filesystem,notifications);current=await recordCodexTelemetryIfAvailable(current,composition,filesystem);return{telemetry:{received_notifications:notifications.length,persisted_event_ids:persisted.map(event=>event.event_id)},run:runV2Summary(current,composition),artifact_path:composition.runs.path(id)}}if(rawCaptureDisabled){current=await recordCodexTelemetryIfAvailable(current,composition,filesystem);return{telemetry:{raw_capture:"disabled",fallback:"codex_session_fallback"},run:runV2Summary(current,composition),artifact_path:composition.runs.path(id)}}const sequence=current.records.length+1;const input=nullableNumberOption(parsed.options["input-tokens"]);const cachedInput=nullableNumberOption(parsed.options["cached-input-tokens"]);const outputTokens=nullableNumberOption(parsed.options["output-tokens"]);const reasoning=nullableNumberOption(parsed.options["reasoning-tokens"]);const explicitTotal=nullableNumberOption(parsed.options["total-tokens"]);const occurredAt=new Date().toISOString();const tokens={input,cached_input:cachedInput,output:outputTokens,reasoning,total:explicitTotal??(input===null||outputTokens===null?null:input+outputTokens),source:tokenSourceOption(parsed.options["token-source"])};const provider=inferProvider(parsed.options.model??current.run.model,parsed.options.provider??current.run.provider??current.run.client,current.run.agent);const pricing=new PricingRepository(filesystem);const estimated=estimateUsageCost({provider,model:parsed.options.model??current.run.model,usage:tokens,catalog:await pricing.readCatalog(),fxRate:await pricing.readLatestFxRate()});const record3=usageRecordedV2Schema.parse({schema_version:2,event_id:parsed.options["event-id"]??runV2EventId(id,sequence),run_id:id,sequence,occurred_at:occurredAt,type:"usage.recorded",phase:runV2PhaseOption(parsed.options.phase??latestRunV2Phase(current.records)),activity_kind:parsed.options.activity??"implementation",classification_source:runV2ClassificationOption(parsed.options.classification),tokens,cost:{usd:nullableCurrencyOption(parsed.options["cost-usd"])??estimated.estimated_usd,brl:nullableCurrencyOption(parsed.options["cost-brl"])??estimated.estimated_brl,fx_rate:parsed.options["cost-brl"]===void 0?estimated.fx_rate:null},provider,model:parsed.options.model??current.run.model,source_segment_key:parsed.options["source-segment"]??null,supersedes_event_id:parsed.options.supersedes??null,...runUsageMetadataOptions(parsed.options,occurredAt)});const folded=foldRunV2Records([...current.records,record3]);await composition.runs.appendRecord(record3);const budget=await evaluateRunBudget(folded,composition,filesystem);return{usage:record3,budget,artifact_path:composition.runs.path(id)}}if(action==="finish"){const telemetryCandidate=await composition.runs.read(id);if(telemetryCandidate.finished===null){await recordCodexTelemetryIfAvailable(telemetryCandidate,composition,filesystem)}return composition.runs.withUsageAttributionLock(async()=>{let current=await composition.runs.read(id);const status=runV2FinishStatusOption(parsed.options.status);const candidateRuns=await composition.runs.list();const role=effectiveRunV2Role(current.run);const suppliedEvidenceIds=csvOption(parsed.options.evidence);const finalizationDecision=current.finalization_decision??null;if(finalizationDecision!==null&&suppliedEvidenceIds.length>0&&!sameStringSet2(suppliedEvidenceIds,finalizationDecision.evidence_ids)){throw new UsageError("--evidence must match the persisted Gui finalization decision")}const evidenceIds=finalizationDecision?.evidence_ids??suppliedEvidenceIds;const suppliedChangedFiles=csvOption(parsed.options["changed-files"]);if(finalizationDecision!==null&&suppliedChangedFiles.length>0&&!sameStringSet2(suppliedChangedFiles,finalizationDecision.changed_files)){throw new UsageError("--changed-files must match the persisted Gui finalization decision")}const changedFiles=finalizationDecision?.changed_files??suppliedChangedFiles;const finalizationBarrier=assessRunFinalizationBarrier(current,candidateRuns,await hasPassedTypedEvidenceForRun(current,evidenceIds,composition));const barrierBlockReason=finalizationBarrierBlockReason(finalizationBarrier);const finalizationBlockReason=finalizationDecision!==null&&finalizationDecision.outcome!=="completed"?null:barrierBlockReason;if(current.finished===null&&finalizationBarrier.status==="evidence_missing"&&finalizationBlockReason!==null){throw new UsageError(finalizationBlockReason)}const suppliedOutcome=lifecycleOutcomeOption(parsed.options);if(current.finished===null&&role==="orchestrator"&&finalizationBarrier.required&&finalizationDecision===null&&finalizationBlockReason===null){throw new UsageError(`Run ${id} requires a persisted Gui finalization decision before lifecycle closure`)}if(finalizationDecision!==null&&suppliedOutcome!==void 0&&suppliedOutcome!==finalizationDecision.outcome){throw new UsageError(`--task-outcome must match the persisted Gui decision (${finalizationDecision.outcome})`)}if(finalizationDecision!==null&&parsed.options.summary!==void 0&&parsed.options.summary!==finalizationDecision.summary){throw new UsageError("--summary must match the persisted Gui finalization decision")}const requestedOutcome=finalizationBlockReason===null?finalizationDecision?.outcome??suppliedOutcome:"blocked";const reconciliationSummary=finalizationBlockReason??finalizationDecision?.summary??parsed.options.summary;if(current.finished===null&&role==="orchestrator"){const activeChildren=activeDescendantRuns(id,candidateRuns);if(activeChildren.length>0){throw new UsageError(`Run ${id} cannot finish while descendant Runs are active: ${activeChildren.map(child=>child.run.run_id).join(", ")}`)}}if(finalizationBlockReason===null&&parsed.flags.has("defer-orchestrator-closure")&&role==="orchestrator"){throw new UsageError(`Orchestrator Run closure cannot be deferred for Run ${id}`)}const deferClosure=finalizationBlockReason===null&&parsed.flags.has("defer-orchestrator-closure");if(current.finished!==null){if(current.finished.status!==status){throw new UsageError(`Run V2 is already ${current.finished.status}: ${id}`)}const reconciliation2=await reconcileFinishedRunLifecycle(current,composition,lifecycle,{requestedOutcome,forceRequestedOutcome:finalizationBlockReason!==null,summary:reconciliationSummary,changedFiles,evidenceIds,defer:deferClosure,candidateRuns});const interactionExecution2=await settleInteractionExecutionForRun(current,composition,finalizationBlockReason);return{run:parsed.flags.has("events")||parsed.options.view==="full"?current:runV2Summary(current,composition),reconciliation:reconciliation2,execution:interactionExecution2,finalization_barrier:finalizationBarrier,closure:await assessRunLifecycleClosure(current,composition,candidateRuns),artifact_path:composition.runs.path(id)}}if(current.effective_usage_records.length===0){const usage=unavailableUsageRecord(current,parsed,current.records.length+1);await composition.runs.appendRecord(usage);current=foldRunV2Records([...current.records,usage])}const sequence=current.records.length+1;const record3=runFinishedV2Schema.parse({schema_version:2,event_id:runV2EventId(id,sequence),run_id:id,sequence,occurred_at:new Date().toISOString(),type:"run.finished",phase:latestRunV2Phase(current.records),status});foldRunV2Records([...current.records,record3]);await composition.runs.appendRecord(record3);const run=await composition.runs.read(id);const reconciliation=await reconcileFinishedRunLifecycle(run,composition,lifecycle,{requestedOutcome,forceRequestedOutcome:finalizationBlockReason!==null,summary:reconciliationSummary,changedFiles,evidenceIds,defer:deferClosure,candidateRuns});const interactionExecution=await settleInteractionExecutionForRun(run,composition,finalizationBlockReason);const closure=await assessRunLifecycleClosure(run,composition,candidateRuns);return{run:parsed.flags.has("events")||parsed.options.view==="full"?run:runV2Summary(run,composition),reconciliation,execution:interactionExecution,finalization_barrier:finalizationBarrier,closure,artifact_path:composition.runs.path(id)}})}if(action==="finalization"){const current=await composition.runs.read(id);if(effectiveRunV2Role(current.run)!=="orchestrator"){throw new UsageError(`Run ${id} is not an orchestrator Run`)}const outcome=lifecycleOutcomeOption(parsed.options);if(outcome===void 0)throw new UsageError("Missing options: --task-outcome");const summary=parsed.options.summary?.trim();if(summary===void 0||summary.length===0)throw new UsageError("Missing options: --summary");const evidenceIds=csvOption(parsed.options.evidence);const changedFiles=csvOption(parsed.options["changed-files"]);const requestedFinalizerRunId=parsed.options["finalizer-run-id"]?.trim();return composition.runs.withUsageAttributionLock(async()=>{const fresh=await composition.runs.read(id);const existing=fresh.finalization_decision??null;if(existing!==null){if(requestedFinalizerRunId!==void 0&&requestedFinalizerRunId.length>0&&existing.finalizer_run_id!==requestedFinalizerRunId||existing.outcome!==outcome||existing.summary!==summary||!sameStringSet2(existing.evidence_ids,evidenceIds)||!sameStringSet2(existing.changed_files,changedFiles)){throw new UsageError(`Run ${id} already has a different Gui finalization decision`)}return{finalization:existing,reused:true,artifact_path:composition.runs.path(id)}}const lockedCandidates=await composition.runs.list();const finalizers=lockedCandidates.filter(candidate=>candidate.run.parent_run_id===id&&effectiveRunV2Purpose(candidate.run)==="finalization"&&candidate.run.agent==="agent-finalizer");const activeFinalizers=finalizers.filter(candidate=>candidate.finished===null);const terminalFallbackFinalizers=finalizers.filter(candidate=>candidate.finished!==null&&candidate.run.client==="codex-subagent"&&candidate.run.client_turn_id===null&&candidate.run.provider===null&&candidate.run.model==="unavailable");const candidatesForDecision=fresh.finished===null?activeFinalizers:terminalFallbackFinalizers;const lockedFinalizer=requestedFinalizerRunId===void 0||requestedFinalizerRunId.length===0?candidatesForDecision.length===1?candidatesForDecision[0]:void 0:candidatesForDecision.find(candidate=>candidate.run.run_id===requestedFinalizerRunId);if(lockedFinalizer===void 0){if(fresh.finished!==null){throw new UsageError(`Run ${id} requires its exact terminal fallback Gui finalizer to record a post-close decision`)}throw new UsageError(`Run ${id} requires an active Gui finalizer to record its decision`)}if(fresh.finished!==null&&fresh.finished.status!=="completed"){throw new UsageError(`Run V2 is already ${fresh.finished.status}: ${id}`)}const lockedActiveElsewhere=activeDescendantRuns(id,lockedCandidates).filter(candidate=>candidate.run.run_id!==lockedFinalizer.run.run_id);if(lockedActiveElsewhere.length>0){throw new UsageError(`Gui finalization for Run ${id} requires every other descendant to be terminal: ${lockedActiveElsewhere.map(run=>run.run.run_id).join(", ")}`)}const record3=runFinalizationDecidedV2Schema.parse({schema_version:2,event_id:runV2EventId(id,fresh.records.length+1),run_id:id,sequence:fresh.records.length+1,occurred_at:new Date().toISOString(),type:"run.finalization.decided",finalizer_run_id:lockedFinalizer.run.run_id,outcome,summary,evidence_ids:evidenceIds,changed_files:changedFiles});await composition.runs.appendRecord(record3);return{finalization:record3,reused:false,artifact_path:composition.runs.path(id)}})}throw new UsageError(`Unknown Run V2 action: ${action??""}`)}async function settleInteractionExecutionForRun(run,composition,finalizationBlockReason){if(run.run.execution_id===null)return null;let execution=(await composition.executions.read(run.run.execution_id)).execution;if(execution.kind!=="interaction")return null;if(run.finished?.status==="cancelled"){return["running","paused","verifying"].includes(execution.status)?composition.executions.transition(execution.id,"cancelled","Run explicitly cancelled"):execution}if(finalizationBlockReason!==null){return["running","paused","verifying"].includes(execution.status)?composition.executions.transition(execution.id,"blocked",null,void 0,finalizationBlockReason):execution}if(execution.status==="running"){execution=await composition.executions.transition(execution.id,"verifying")}return execution.status==="verifying"?composition.executions.transition(execution.id,"completed","Interaction finalized"):execution}function filterRunV2Folds(runs,parsed){const statuses=new Set(csvOption(parsed.options.status));const from=dateBoundary(parsed.options.from,false);const to=dateBoundary(parsed.options.to,true);const positionalRunId=parsed.positionals[2];const phase=parsed.options.phase===void 0?void 0:runV2PhaseOption(parsed.options.phase);const entrypoint=parsed.options.entrypoint===void 0?void 0:runV2EntrypointOption(parsed.options.entrypoint);const workType=parsed.options["work-type"]===void 0?void 0:runV2WorkTypeOption(parsed.options["work-type"]);return runs.filter(fold=>{const run=fold.run;if(statuses.size>0&&!statuses.has(fold.status))return false;const occurredAt=Date.parse(run.occurred_at);if(from!==null&&occurredAt<from||to!==null&&occurredAt>to)return false;const requestedAgent=parsed.options.agent;if(requestedAgent!==void 0&&run.agent!==requestedAgent&&run.agent_name!==requestedAgent){return false}const criteria=[[positionalRunId,run.run_id],[parsed.options.id,run.run_id],[phase,phase===void 0?void 0:latestRunV2Phase(fold.records)],[entrypoint,run.entrypoint],[workType,run.work_type],[parsed.options.conversation,run.conversation_id],[parsed.options.execution,run.execution_id],[parsed.options.task,run.task_id],[parsed.options.spec,run.spec_id],[parsed.options.prd,run.prd_id],[parsed.options.change,run.change_id]];return criteria.every(([expected,actual])=>expected===void 0||actual===expected)})}var V2_COMMAND_AREAS=new Set(["plan","prd","spec","change","task","execution","decision","evidence","validation","run","run-v2","conversation","developer","subagent"]);function createV2Composition(filesystem,layout){const storageMode=layout.projectConfig?.tracking.storage_mode??"tracked_sanitized";return{filesystem,layout,prds:new PrdV2Repository(filesystem,layout),specs:new DeliverySpecV2Repository(filesystem,layout),changes:new ChangeV2Repository(filesystem,layout),tasks:new TaskV2Repository(filesystem,layout),executions:new ExecutionV2Repository(filesystem,layout),materializer:new PreparedPlanV2Materializer(filesystem,layout),decisions:new DecisionV2Repository(filesystem,layout),runs:new RunV2Repository(filesystem,storageMode==="local_only"?{storageMode:"local_only",localBasePath:".local/runs"}:{storageMode:"tracked_sanitized",layout})}}async function runV2Command(area,action,parsed,filesystem,layout){if(!isLifecycleManifestMutation(action)||isNarrowSubagentTerminalCapture(area,action)||isNarrowRunFinish(area,action)){return runV2CommandUnlocked(area,action,parsed,filesystem,layout)}return withLifecycleCanonicalMutationLock(filesystem,()=>runV2CommandUnlocked(area,action,parsed,filesystem,layout))}async function runV2CommandUnlocked(area,action,parsed,filesystem,layout){const composition=createV2Composition(filesystem,layout);if(action==="list"&&parsed.options.view!=="full"){return manifestList(area==="run-v2"?"run":area,parsed,filesystem)}const lifecycle=new LifecycleV2Gate(filesystem,layout,composition);let result2;let manifestSyncedDuringMutation=false;if(area==="plan")return runPlanV2Command(action,parsed,filesystem,layout);if(area==="developer")return runDeveloperIdentityCommand(action,parsed,filesystem);if(area==="prd")result2=await runDefinitionLifecycleCommand(area,action,parsed,filesystem,composition,lifecycle);else if(area==="spec")result2=await runDefinitionLifecycleCommand(area,action,parsed,filesystem,composition,lifecycle);else if(area==="change")result2=await runChangeV2Command(action,parsed,composition,lifecycle);if(area==="conversation"){result2=await runConversationV2Command(action,parsed,composition,filesystem,lifecycle)}else if(area==="subagent"){result2=await runSubagentV2Command(action,parsed,composition,filesystem,lifecycle,async captured=>{await syncLifecycleManifestResult(captured,"subagent",parsed,composition,filesystem);manifestSyncedDuringMutation=true})}else if(area==="task"){result2=await runLifecycleV2Command(area,action,parsed,filesystem,composition,lifecycle)}else if(area==="execution")result2=await runExecutionV2Command(action,parsed,composition,lifecycle,async(id,options)=>runAutonomousExecutionCommand(id,options,composition,layout.projectConfig?.execution?.runtime==="autonomous"&&layout.projectConfig!==null?createAutonomousProductionDriver(filesystem,layout.projectConfig):void 0,await loadAgentCatalog(filesystem)));else if(area==="decision")result2=await runDecisionV2Command(action,parsed,filesystem,composition);else if(area==="evidence")result2=await runEvidenceV2Command(action,parsed,filesystem,composition);else if(area==="validation")result2=await runValidationV2Command(action,parsed,filesystem,composition);else if(area==="run"||area==="run-v2"){result2=await runRunV2Command(action,parsed,composition,filesystem,lifecycle)}else if(!["prd","spec","change","task","conversation","subagent","evidence","validation"].includes(area)){throw new UsageError(`Unknown V2 command: ${area} ${action??""}`.trim())}if(isLifecycleManifestMutation(action)&&!manifestSyncedDuringMutation){await syncLifecycleManifestResult(result2,area==="run-v2"?"run":area,parsed,composition,filesystem)}return result2}function isNarrowSubagentTerminalCapture(area,action){return area==="subagent"&&action==="capture-terminal"}function isNarrowRunFinish(area,action){return(area==="run"||area==="run-v2")&&action==="finish"}async function runDefinitionLifecycleCommand(area,action,parsed,filesystem,composition,lifecycle){const definitionActions=new Set(["create","rework","prepare"]);if(!definitionActions.has(action??"")){return runLifecycleV2Command(area,action,parsed,filesystem,composition,lifecycle)}const runId=await creationRunIdForCurrentTurn(parsed,filesystem,composition);await assertActiveDefinitionRun({area,runId,filesystem,composition,reworkAuthoring:action==="rework"});return runLifecycleV2Command(area,action,parsed,filesystem,composition,lifecycle)}async function readCostCohortInput(filesystem,path){let decoded;try{decoded=JSON.parse(await filesystem.readText(path))}catch(error51){throw new UsageError(`Unable to read cost cohort input: ${error51 instanceof Error?error51.message:String(error51)}`)}try{return collectCompletedTaskCostCohortV2(parseCompletedTaskCostCohortCollectionInputV2(decoded))}catch(error51){throw new UsageError(`Invalid cost cohort input: ${error51 instanceof Error?error51.message:String(error51)}`)}}async function buildContextForCommand(filesystem,parsed,query,budget){return buildContextPack(filesystem,query,budget,contextBuildOptions(parsed))}function contextBuildOptions(parsed){const role=enumOption(parsed.options.role,CONTEXT_ROLES,"role");const phase=enumOption(parsed.options.phase,CONTEXT_PHASES,"phase");return{...role===void 0?{}:{role},...phase===void 0?{}:{phase},failClosed:true}}function enumOption(value,allowed,name){if(value===void 0)return void 0;if(allowed.includes(value))return value;throw new UsageError(`--${name} must be one of: ${allowed.join(", ")}`)}function helpText(version2){return`ZAIP-AIOS ${version2}
|
|
1611
|
+
`)}return budget}async function cancelTaskRunsForHuman(taskId,composition,parsed){return composition.runs.withUsageAttributionLock(async()=>{const candidates=await composition.runs.list();const roots=candidates.filter(fold=>fold.finished===null&&fold.run.parent_run_id===null&&fold.run.task_id===taskId);for(const root of roots){await cancelActiveDescendantRuns(activeDescendantRuns(root.run.run_id,candidates),composition,parsed);await cancelActiveDescendantRuns([root],composition,parsed)}return roots.map(root=>root.run.run_id)})}async function cancelActiveDescendantRuns(descendants,composition,parsed){for(const descendant of[...descendants].reverse()){let current=await composition.runs.read(descendant.run.run_id);if(current.finished!==null)continue;if(current.effective_usage_records.length===0){const usage=unavailableUsageRecord(current,parsed,current.records.length+1);await composition.runs.appendRecord(usage);current=foldRunV2Records([...current.records,usage])}const record3=runFinishedV2Schema.parse({schema_version:2,event_id:runV2EventId(current.run.run_id,current.records.length+1),run_id:current.run.run_id,sequence:current.records.length+1,occurred_at:new Date().toISOString(),type:"run.finished",phase:latestRunV2Phase(current.records),status:"cancelled"});foldRunV2Records([...current.records,record3]);await composition.runs.appendRecord(record3)}}function aggregateRunsByAgent(runs,runCostInput2){const groups=new Map;for(const run of runs){const key=run.run.agent_name??run.run.agent;groups.set(key,[...groups.get(key)??[],run])}return[...groups.entries()].sort(([left],[right])=>left.localeCompare(right)).map(([agentName2,agentRuns])=>{const aggregate=aggregateRunV2Usage(agentRuns.map(runCostInput2),agentName2);const durations=agentRuns.flatMap(run=>{if(run.finished===null)return[];const duration3=Date.parse(run.finished.occurred_at)-Date.parse(run.run.occurred_at);return Number.isFinite(duration3)&&duration3>=0?[duration3]:[]});const cycles=agentRuns.map(run=>run.effective_usage_records.length);return{agent:agentRuns[0]?.run.agent??agentName2,agent_name:agentName2,run_count:agentRuns.length,rework_runs:agentRuns.filter(run=>run.run.work_type==="rework").length,duration:{known_runs:durations.length,unknown_runs:agentRuns.length-durations.length,total_ms:durations.reduce((sum,value)=>sum+value,0),average_ms:durations.length===0?null:Math.round(durations.reduce((sum,value)=>sum+value,0)/durations.length)},observed_usage_cycles:{total:cycles.reduce((sum,value)=>sum+value,0),average:cycles.length===0?null:Number((cycles.reduce((sum,value)=>sum+value,0)/cycles.length).toFixed(2))},tokens:aggregate.total.tokens,cost:aggregate.total.cost,coverage:aggregate.run_coverage}})}import{createHash as createHash29,randomBytes as randomBytes2}from"node:crypto";function lifecycleActionAlias(area,action){if(action===void 0)return action;const normalized=action.normalize("NFKD").replace(/[\u0300-\u036f]/g,"").toLocaleLowerCase();if(area==="prd"||area==="spec"){if(["pronto","pronto-para-executar","ready-to-execute"].includes(normalized))return"ready";if(["finalizar","finalize","concluir","conclude"].includes(normalized))return"finalize"}return normalized}function resolveMacroFinalizeAction(status){if(status==="draft"||status==="ready")return"ready";if(status==="active"||status==="verifying")return"continue";return null}function maxCostUsdOption(value){if(value===void 0)return null;const parsed=Number(value);if(!Number.isFinite(parsed)||parsed<0){throw new UsageError("--max-cost-usd must be a non-negative number")}return parsed}async function finalizeMacro(area,parsed,composition,makeReady){const id=requiredEntityId(parsed,2,`${area.toUpperCase()} id`);const entity=area==="prd"?(await composition.prds.read(id)).prd:(await composition.specs.read(id)).spec;const resolution=resolveMacroFinalizeAction(entity.status);if(resolution==="ready")return makeReady();if(resolution==="continue"){return{[area]:entity,next_action:"continue",message:`${area.toUpperCase()} ${id} remains active; finish its Tasks and parent gates before deliver`}}throw new UsageError(`${area.toUpperCase()} ${id} cannot finalize from status ${entity.status}`)}async function createPrdWithOptionalPlan(input){const{parsed,filesystem,composition,creationRunId}=input;requireOptions(parsed.options,["title","short-name","problem"]);const plan=parsed.options.plan===void 0?null:await readPreparedPlan(filesystem,parsed);if(plan!==null&&plan.blueprints.specs===void 0){throw new UsageError("Composite PRD creation requires technical SPEC blueprints; create canonical SPECs first, then use prd prepare for legacy plans")}if(plan!==null&&parsed.options.id===void 0){throw new UsageError("Composite PRD creation requires --id matching the PreparedPlan source")}if(plan!==null&&(plan.source.type!=="prd"||plan.source.prd_id!==parsed.options.id)){throw new UsageError(`Composite PRD plan must have source prd ${parsed.options.id}`)}const specIds=plan===null?[]:specIdsForPrdPlanV2(plan,parsed.options.id);const specCreationRunId=plan===null?null:await assertActiveDefinitionRun({area:"spec",runId:parsed.options["spec-run"]??null,filesystem,composition});if(plan!==null){await assertPreparedPlanReferences(filesystem,plan);await Promise.all((plan.blueprints.specs??[]).map(blueprint=>assertSpecImplementationMatchesProject(blueprint.implementation,filesystem,composition.layout)));const occupied=await Promise.all([filesystem.exists(composition.prds.path(parsed.options.id)),...specIds.map(id=>filesystem.exists(composition.specs.path(id)))]);if(occupied.some(Boolean)){throw new UsageError("Composite PRD creation requires unused PRD and SPEC artifact ids")}}const prd=await composition.prds.create({...parsed.options.id===void 0?{}:{id:parsed.options.id},title:parsed.options.title,shortName:parsed.options["short-name"],problem:parsed.options.problem,audiences:csvOption(parsed.options.audiences),outcomes:csvOption(parsed.options.outcomes),constraints:csvOption(parsed.options.constraints),nonGoals:csvOption(parsed.options["non-goals"]),creationRunId});if(plan===null)return{prd,artifact_path:composition.prds.path(prd.id)};const createdFiles=new Map([[composition.prds.path(prd.id),await filesystem.readText(composition.prds.path(prd.id))]]);const specBlueprints=new Map((plan.blueprints.specs??[]).map(blueprint=>[blueprint.id,blueprint]));try{const specs=[];for(const specId of specIds){const blueprint=specBlueprints.get(specId);if(blueprint===void 0){throw new UsageError(`Composite PRD plan lacks technical SPEC blueprint ${specId}`)}const spec=await composition.specs.create({id:specId,prdId:prd.id,title:blueprint.title,shortName:blueprint.short_name,objective:blueprint.objective,includedScope:blueprint.included_scope,excludedScope:blueprint.excluded_scope,requirementIds:blueprint.requirement_ids,acceptanceIds:blueprint.acceptance_ids,implementation:blueprint.implementation,creationRunId:specCreationRunId});specs.push(spec);const path=composition.specs.path(spec.id);createdFiles.set(path,await filesystem.readText(path))}const prepared=await composition.prds.setPreparedPlan(prd.id,plan);return{prd:prepared,specs,artifact_path:composition.prds.path(prepared.id),plan_hash:plan.hash,spec_blueprints:plan.blueprints.specs,materialized:false}}catch(error51){const recovered=await rollbackCompositeCreation(filesystem,createdFiles);if(recovered.length>0){throw new AggregateError([error51],`Composite PRD creation rolled back; concurrent edits were preserved at ${recovered.join(", ")}`)}throw error51}}async function createPrdRework(input){const{parsed,composition,creationRunId}=input;requireOptions(parsed.options,["title","short-name","problem"]);const sourceId=requiredPosition(parsed.positionals,2,"Cancelled PRD id");const prd=await composition.prds.createReworkSuccessor(sourceId,{...parsed.options.id===void 0?{}:{id:parsed.options.id},title:parsed.options.title,shortName:parsed.options["short-name"],problem:parsed.options.problem,audiences:csvOption(parsed.options.audiences),outcomes:csvOption(parsed.options.outcomes),constraints:csvOption(parsed.options.constraints),nonGoals:csvOption(parsed.options["non-goals"]),creationRunId});return{prd,artifact_path:composition.prds.path(prd.id),rework_of_prd_id:sourceId}}async function createSpecWithOptionalPlan(input){const{parsed,filesystem,composition,creationRunId}=input;requireOptions(parsed.options,["title","short-name","objective"]);const plan=parsed.options.plan===void 0?null:await readPreparedPlan(filesystem,parsed);if(plan!==null&&parsed.options.id===void 0){throw new UsageError("Composite SPEC creation requires --id matching the PreparedPlan source")}if(plan!==null&&(plan.source.type!=="spec"||plan.source.spec_id!==parsed.options.id)){throw new UsageError(`Composite SPEC plan must have source spec ${parsed.options.id}`)}const sourceSpecId=plan?.source.type==="spec"?plan.source.spec_id:null;const blueprint=plan===null||sourceSpecId===null?null:(plan.blueprints.specs??[]).find(candidate=>candidate.id===sourceSpecId);if(plan!==null){if(blueprint===void 0||blueprint===null){throw new UsageError(`Composite SPEC plan lacks technical SPEC blueprint ${sourceSpecId}`)}await assertPreparedPlanReferences(filesystem,plan);await assertSpecImplementationMatchesProject(blueprint.implementation,filesystem,composition.layout);if(await filesystem.exists(composition.specs.path(parsed.options.id))){throw new UsageError("Composite SPEC creation requires an unused SPEC artifact id")}}const spec=await composition.specs.create({...parsed.options.id===void 0?{}:{id:parsed.options.id},...parsed.options.prd===void 0?{}:{prdId:parsed.options.prd},title:blueprint?.title??parsed.options.title,shortName:blueprint?.short_name??parsed.options["short-name"],objective:blueprint?.objective??parsed.options.objective,includedScope:blueprint?.included_scope??csvOption(parsed.options.scope),excludedScope:blueprint?.excluded_scope??csvOption(parsed.options["out-of-scope"]),requirementIds:blueprint?.requirement_ids??csvOption(parsed.options.requirements),acceptanceIds:blueprint?.acceptance_ids??csvOption(parsed.options.acceptance),...blueprint===null||blueprint===void 0?{}:{implementation:blueprint.implementation},creationRunId});if(plan===null)return{spec,artifact_path:composition.specs.path(spec.id)};const path=composition.specs.path(spec.id);const original=await filesystem.readText(path);try{const prepared=await composition.specs.setPreparedPlan(spec.id,plan);return{spec:prepared,artifact_path:composition.specs.path(prepared.id),plan_hash:plan.hash,materialized:false}}catch(error51){const recovered=await rollbackCompositeCreation(filesystem,new Map([[path,original]]));if(recovered.length>0){throw new AggregateError([error51],`Composite SPEC creation rolled back; concurrent edits were preserved at ${recovered.join(", ")}`)}throw error51}}async function rollbackCompositeCreation(filesystem,createdFiles){const recovered=[];for(const[path,original]of createdFiles){if(!await filesystem.exists(path))continue;const digest6=createHash29("sha256").update(`${path}\0${randomBytes2(16).toString("hex")}`).digest("hex").slice(0,24);const recoveryPath=`.local/recovery/composite-create/${digest6}.md`;await filesystem.moveFileAtomic(path,recoveryPath);if(await filesystem.readText(recoveryPath)===original){await filesystem.removeFile(recoveryPath)}else recovered.push(recoveryPath)}return recovered}async function runLifecycleV2Command(area,action,parsed,filesystem,composition,lifecycle){action=lifecycleActionAlias(area,action);if(area==="prd")return runPrdV2Command(action,parsed,filesystem,composition,lifecycle);if(area==="spec")return runSpecV2Command(action,parsed,filesystem,composition,lifecycle);return runTaskV2Command(action,parsed,filesystem,composition,lifecycle)}async function runPrdV2Command(action,parsed,filesystem,composition,lifecycle){if(action==="finalize"){return finalizeMacro("prd",parsed,composition,()=>runLifecycleV2Command("prd","ready",parsed,filesystem,composition,lifecycle))}if(action==="create"){const creationRunId=await creationRunIdForCurrentTurn(parsed,filesystem,composition);return createPrdWithOptionalPlan({parsed,filesystem,composition,creationRunId})}if(action==="rework"){return createPrdRework({parsed,composition,creationRunId:await creationRunIdForCurrentTurn(parsed,filesystem,composition)})}if(action==="list"){return listLifecyclePage(await composition.prds.list(),parsed).map(prd=>({prd:compactPreparedEntity(prd),artifact_path:composition.prds.path(prd.id)}))}const id=requiredEntityId(parsed,2,"PRD id");if(action==="show"){return{...await composition.prds.read(id),artifact_path:composition.prds.path(id)}}if(action==="prepare"){const plan=await readPreparedPlan(filesystem,parsed);await assertPreparedPlanReferences(filesystem,plan);const prd=await composition.prds.setPreparedPlan(id,plan);const specs=await Promise.all(specIdsForPrdPlanV2(plan,id).map(async specId=>(await composition.specs.read(specId)).spec));return{prd,specs,artifact_path:composition.prds.path(id),plan_hash:plan.hash}}if(action==="ready"){const current=await composition.prds.read(id);const plan=await preparedPlanForReadyOrExecute(current.prd,"PRD",id,composition.materializer);await assertPreparedPlanReferences(filesystem,plan);if(!new Set(["draft","ready"]).has(current.prd.status)){throw new UsageError(`PRD cannot move to ready from status ${current.prd.status}: ${id}`)}const selectedSpecs=await Promise.all(specIdsForPrdPlanV2(plan,id).map(async specId=>(await composition.specs.read(specId)).spec));for(const spec of selectedSpecs){if(!new Set(["draft","ready"]).has(spec.status)){throw new UsageError(`SPEC cannot move to ready from status ${spec.status}: ${spec.id}`)}}const materialized=materializationOutput(await composition.materializer.execute(plan),composition);const prd=current.prd.status==="draft"?await composition.prds.transition(id,"ready"):current.prd;const specs=await Promise.all(selectedSpecs.map(spec=>spec.status==="draft"?composition.specs.transition(spec.id,"ready"):spec));return{...materialized,prd,specs,artifact_path:composition.prds.path(id)}}if(action==="execute"){const current=await composition.prds.read(id);const plan=await preparedPlanForReadyOrExecute(current.prd,"PRD",id,composition.materializer);await assertPreparedPlanReferences(filesystem,plan);if(!new Set(["draft","ready"]).has(current.prd.status)){throw new UsageError(`PRD cannot execute from status ${current.prd.status}: ${id}`)}const selectedSpecs=await Promise.all(specIdsForPrdPlanV2(plan,id).map(async specId=>(await composition.specs.read(specId)).spec));for(const spec of selectedSpecs){if(!new Set(["draft","ready"]).has(spec.status)){throw new UsageError(`SPEC cannot execute from status ${spec.status}: ${spec.id}`)}}const output2=materializationOutput(await composition.materializer.execute(plan),composition);const specs=await Promise.all(selectedSpecs.map(async selectedSpec=>{let spec=selectedSpec;if(spec.status==="draft")spec=await composition.specs.transition(spec.id,"ready");return spec.status==="ready"?composition.specs.transition(spec.id,"active"):spec}));if(current.prd.status==="draft")await composition.prds.transition(id,"ready");const preparedPrd=(await composition.prds.read(id)).prd;if(preparedPrd.status==="ready")await composition.prds.transition(id,"active");return{...output2,specs}}if(action==="deliver"){throw new UsageError("PRD terminal status is applied only by Gui through run finish")}if(action==="block"||action==="fail"){throw new UsageError("PRD terminal status is applied only by Gui through run finish")}if(action==="cancel"){throw new UsageError("PRD terminal status is applied only by Gui through run finish")}if(action==="activate"){const prd=await composition.prds.transition(id,"active");return{prd,artifact_path:composition.prds.path(id)}}throw new UsageError(`Unknown V2 PRD action: ${action??""}`)}async function runSpecV2Command(action,parsed,filesystem,composition,lifecycle){if(action==="finalize"){return finalizeMacro("spec",parsed,composition,()=>runLifecycleV2Command("spec","ready",parsed,filesystem,composition,lifecycle))}if(action==="create"){const creationRunId=await creationRunIdForCurrentTurn(parsed,filesystem,composition);return createSpecWithOptionalPlan({parsed,filesystem,composition,creationRunId})}if(action==="list"){const specs=(await composition.specs.list()).filter(spec=>parsed.options.prd===void 0||spec.prd_id===parsed.options.prd);return listLifecyclePage(specs,parsed).map(spec=>({spec:compactPreparedEntity(spec),artifact_path:composition.specs.path(spec.id)}))}const id=requiredEntityId(parsed,2,"SPEC id");if(action==="show"){return{...await composition.specs.read(id),artifact_path:composition.specs.path(id)}}if(action==="prepare"){const plan=await readPreparedPlan(filesystem,parsed);await assertPreparedPlanReferences(filesystem,plan);const spec=await composition.specs.setPreparedPlan(id,plan);return{spec,artifact_path:composition.specs.path(id),plan_hash:plan.hash}}if(action==="ready"){const current=await composition.specs.read(id);const plan=await preparedPlanForReadyOrExecute(current.spec,"SPEC",id,composition.materializer);await assertPreparedPlanReferences(filesystem,plan);if(!new Set(["draft","ready"]).has(current.spec.status)){throw new UsageError(`SPEC cannot move to ready from status ${current.spec.status}: ${id}`)}const materialized=materializationOutput(await composition.materializer.execute(plan),composition);const spec=current.spec.status==="draft"?await composition.specs.transition(id,"ready"):current.spec;return{...materialized,spec,artifact_path:composition.specs.path(id)}}if(action==="execute"){const current=await composition.specs.read(id);const plan=await preparedPlanForReadyOrExecute(current.spec,"SPEC",id,composition.materializer);await assertPreparedPlanReferences(filesystem,plan);if(!new Set(["draft","ready"]).has(current.spec.status)){throw new UsageError(`SPEC cannot execute from status ${current.spec.status}: ${id}`)}const output2=materializationOutput(await composition.materializer.execute(plan),composition);if(current.spec.status==="draft")await composition.specs.transition(id,"ready");const preparedSpec=(await composition.specs.read(id)).spec;if(preparedSpec.status==="ready")await composition.specs.transition(id,"active");return output2}if(action==="deliver"){throw new UsageError("SPEC terminal status is applied only by Gui through run finish")}if(action==="block"||action==="fail"){throw new UsageError("SPEC terminal status is applied only by Gui through run finish")}if(action==="cancel"){const changes=(await composition.changes.list()).filter(change=>change.source.type==="spec"&&change.source.spec_id===id||change.source.type==="prd"&&change.source.spec_id===id);const executions=(await composition.executions.list()).filter(execution=>execution.origin.type==="spec"&&execution.origin.spec_id===id);const taskIds=new Set([...changes.flatMap(change=>change.task_ids),...executions.flatMap(execution=>execution.dag.nodes.map(node=>node.task_id))]);const cancelled_run_ids=(await Promise.all([...taskIds].map(taskId=>cancelTaskRunsForHuman(taskId,composition,parsed)))).flat();const result2=await lifecycle.cancelSpec(id);return{...result2,cancelled_run_ids,artifact_path:composition.specs.path(id)}}if(action==="activate"){const spec=await composition.specs.transition(id,"active");return{spec,artifact_path:composition.specs.path(id)}}throw new UsageError(`Unknown V2 SPEC action: ${action??""}`)}async function creationRunIdForCurrentTurn(parsed,filesystem,composition){if(parsed.options.run!==void 0){return(await composition.runs.read(parsed.options.run)).run.run_id}const invocation=await resolveRunClientInvocation(filesystem,"codex");const intake=await findIntakeForExactTurn(composition,"codex",invocation);return intake?.run.run_id??null}async function runTaskV2Command(action,parsed,filesystem,composition,lifecycle){if(action==="create"){requireOptions(parsed.options,["title","short-name","objective","requirements","acceptance"]);const timeZone=composition.layout.project.timezone;const taskId=parsed.options.id??createId("TASK",parsed.options["short-name"],{timeZone});const changeId=parsed.options.change??createId("CHG",parsed.options["short-name"],{timeZone});const requirementIds=csvOption(parsed.options.requirements);const acceptanceIds=csvOption(parsed.options.acceptance);const risk2=riskOption(parsed.options.risk);const shortName=parsed.options["short-name"];const{task,change}=await createTaskAndChangeAtomically(filesystem,composition,{id:taskId,changeId,title:parsed.options.title,shortName,objective:parsed.options.objective,risk:risk2,priority:priorityOption(parsed.options.priority),owner:parsed.options.owner??null,requirementIds,acceptanceIds,dependsOn:csvOption(parsed.options["depends-on"]),writeScopes:csvOption(parsed.options["write-scopes"])});return{task,change,artifact_path:composition.tasks.path(task.id),change_path:composition.changes.path(change.id)}}if(action==="prepare"){const id2=requiredEntityId(parsed,2,"Task id");const current=await composition.tasks.read(id2);if(current.task.status==="planned"&¤t.task.prepared_plan!==void 0){await assertPreparedPlanReferences(filesystem,current.task.prepared_plan);return{task:current.task,artifact_path:composition.tasks.path(id2),plan_hash:current.task.prepared_plan.hash}}if(parsed.options.plan===void 0&¤t.task.depends_on.length>0){throw new UsageError("task prepare with dependencies requires --plan containing the complete DAG")}const timeZone=composition.layout.project.timezone;const executionId=await resolveTaskFirstExecutionId(parsed.options.execution,current.task.id,()=>composition.executions.list());const plan=parsed.options.plan===void 0?createTaskFirstPreparedPlan({task:current.task,executionId:executionId??createId("RUN",current.task.short_name,{timeZone}).replace(/^RUN-/,"EXEC-"),preparedAt:new Date().toISOString(),policy:defaultExecutionPolicy(current.task.risk,{independent_branches:parsed.flags.has("independent-branches"),max_cost_usd:maxCostUsdOption(parsed.options["max-cost-usd"])}),...parsed.options["requirement-impact"]===void 0?{}:{requirementImpactReason:parsed.options["requirement-impact"]}}):await readPreparedPlan(filesystem,parsed);await assertPreparedPlanReferences(filesystem,plan);const task=await composition.tasks.setPreparedPlan(id2,plan);const change=plan.blueprints.changes.find(candidate=>candidate.id===task.change_id);if(change===void 0)throw new UsageError(`Prepared plan does not contain Change ${task.change_id}`);await ensureTaskDraftChange(composition,task);await composition.changes.promoteDraft(task.change_id,plannedChangeFromBlueprint(change,plan,task.id));return{task,artifact_path:composition.tasks.path(id2),plan_hash:plan.hash}}if(action==="recover-intake"){requireOptions(parsed.options,["execution"]);const taskId=requiredEntityId(parsed,2,"Task id");const{task}=await composition.tasks.read(taskId);if(task.status!=="executing"||task.plan_ref===void 0)throw new UsageError(`Task has no active canonical plan reference: ${taskId}`);const plan=await composition.materializer.readPreparedPlan(task.plan_ref.execution_id);if(plan.hash!==task.plan_ref.hash||plan.source.type!=="task"||plan.source.task_id!==task.id)throw new UsageError(`Task plan reference cannot be resolved canonically: ${taskId}`);const intake=(await composition.executions.read(parsed.options.execution)).execution;if(intake.kind!=="delivery"||intake.origin.type!=="task"||intake.origin.task_id!==task.id)throw new UsageError(`Delivery intake does not belong to Task: ${intake.id}`);const current=intake;const nodes=plan.dag.nodes.map(node=>{const blueprint=plan.blueprints.tasks.find(candidate=>candidate.id===node.task_id);if(blueprint===void 0)throw new UsageError(`Prepared plan DAG lacks Task blueprint: ${node.task_id}`);return{task_id:node.task_id,change_id:blueprint.change_id,depends_on:node.depends_on}});const planned={...current,kind:"delivery",status:"planned",status_reason:null,plan_revision:plan.revision,plan_hash:plan.hash,policy:plan.policy,dag:{nodes,topological_order:plan.dag.topological_order}};const execution=await composition.executions.promoteDeliveryIntake(current.id,planned);return{task,execution,artifact_path:composition.executions.path(execution.id),recovered:true}}if(action==="execute"){const plan=parsed.options.plan!==void 0?await readPreparedPlan(filesystem,parsed):await preparedTaskPlan(composition.tasks,composition.materializer,requiredEntityId(parsed,2,"Task id"));await assertPreparedPlanReferences(filesystem,plan);if(plan.source.type!=="task"){throw new UsageError("task execute requires a task-first prepared plan")}const materialized=await existingTaskFirstMaterialization(plan,composition)??await composition.materializer.execute(plan);const taskId=plan.source.task_id;const task=materialized.tasks.find(candidate=>candidate.id===taskId);if(task===void 0){throw new UsageError(`Task-first plan did not materialize its source Task ${taskId}`)}const change=materialized.changes.find(candidate=>candidate.id===task.change_id);if(change===void 0){throw new UsageError(`Task-first plan did not materialize Change ${task.change_id}`)}assertTaskFirstExecutable(task.status,"Task",task.id);assertTaskFirstExecutable(materialized.execution.status,"Execution",materialized.execution.id);assertTaskFirstExecutable(change.status,"Change",change.id);const run=await ensureTaskOrchestratorRun(task,change.id,materialized.execution.id,parsed,filesystem,composition);let execution=(await composition.executions.read(materialized.execution.id)).execution;if(execution.status==="planned"){execution=await composition.executions.transition(execution.id,"running")}let activeChange=(await composition.changes.read(change.id)).change;if(activeChange.status==="planned"){activeChange=await composition.changes.transition(activeChange.id,"executing")}let activeTask=(await composition.tasks.read(task.id)).task;if(activeTask.status==="planned"){activeTask=await lifecycle.startTask(activeTask.id)}return{...materializationOutput(materialized,composition),execution,changes:[activeChange],tasks:[activeTask],run,run_path:composition.runs.path(run.run_id)}}if(action==="list"){const[tasks,changes]=await Promise.all([composition.tasks.list(),parsed.options.prd===void 0&&parsed.options.spec===void 0?Promise.resolve([]):composition.changes.list()]);const relatedChangeIds=new Set(changes.filter(change=>(parsed.options.prd===void 0||change.source.type==="prd"&&change.source.prd_id===parsed.options.prd)&&(parsed.options.spec===void 0||change.source.type==="spec"&&change.source.spec_id===parsed.options.spec||change.source.type==="prd"&&change.source.spec_id===parsed.options.spec)).map(change=>change.id));const filtered=tasks.filter(task=>parsed.options.prd===void 0&&parsed.options.spec===void 0||relatedChangeIds.has(task.change_id));return listLifecyclePage(filtered,parsed).map(task=>({task:compactPreparedEntity(task),artifact_path:composition.tasks.path(task.id)}))}if(action==="next"){const[tasks,executions]=await Promise.all([composition.tasks.list(),composition.executions.list()]);const completed=new Set(tasks.filter(task=>task.status==="completed").map(task=>task.id));const materialized=new Set(executions.flatMap(execution=>execution.dag.nodes.map(node=>node.task_id)));return tasks.filter(task=>task.status==="planned"&&materialized.has(task.id)&&task.depends_on.every(dependency=>completed.has(dependency))).map(task=>({task,artifact_path:composition.tasks.path(task.id)}))}const id=requiredEntityId(parsed,2,"Task id");if(action==="show"){return{...await composition.tasks.read(id),artifact_path:composition.tasks.path(id)}}if(action==="start"||action==="resume"||action==="rework"){const task=await lifecycle.startTask(id,action);return{task,artifact_path:composition.tasks.path(id)}}if(action==="verify"){const task=await lifecycle.verifyTask(id,csvOption(parsed.options.evidence));return{task,artifact_path:composition.tasks.path(id)}}if(action==="block"){throw new UsageError("Task terminal status is applied only by Gui through run finish")}if(action==="complete"){throw new UsageError("Task terminal status is applied only by Gui through run finish")}if(action==="fail"){throw new UsageError("Task terminal status is applied only by Gui through run finish")}if(action==="cancel"){const cancelled_run_ids=await cancelTaskRunsForHuman(id,composition,parsed);const result2=await lifecycle.cancelTask(id,"Explicit human cancellation",null);return{...result2,cancelled_run_ids,artifact_path:composition.tasks.path(id)}}throw new UsageError(`Unknown V2 Task action: ${action??""}`)}async function resolveTaskFirstExecutionId(explicitExecutionId,taskId,listExecutions){if(explicitExecutionId!==void 0)return explicitExecutionId;const deliveryIntake=(await listExecutions()).find(execution=>execution.kind==="delivery"&&execution.plan_hash===null&&execution.origin.type==="task"&&execution.origin.task_id===taskId);return deliveryIntake?.id}function assertTaskFirstExecutable(status,kind,id){if(status==="planned"||status==="executing"||status==="running")return;const guidance=status==="blocked"?"resume the Task before starting a new orchestrator agent call":status==="failed"?"rework the Task before starting a new orchestrator agent call":"terminal work is immutable";throw new UsageError(`${kind} ${id} cannot execute from status ${status}; ${guidance}`)}async function existingTaskFirstMaterialization(plan,composition){if(plan.source.type!=="task")return null;const existing=await Promise.all([composition.tasks.read(plan.source.task_id).catch(()=>null),composition.executions.read(plan.execution_id).catch(()=>null)]);const task=existing[0]?.task;const execution=existing[1]?.execution;if(task===void 0||execution===void 0||task.plan_hash!==plan.hash||execution.plan_hash!==plan.hash||!execution.dag.nodes.some(node=>node.task_id===task.id&&node.change_id===task.change_id)){return null}const change=await composition.changes.read(task.change_id).catch(()=>null);if(change===null||change.change.plan_hash!==plan.hash)return null;const reusedPaths=[composition.executions.path(execution.id),composition.changes.path(change.change.id),composition.tasks.path(task.id)];return{execution,changes:[change.change],tasks:[task],created_paths:[],reused_paths:reusedPaths}}async function ensureTaskOrchestratorRun(task,changeId,executionId,parsed,filesystem,composition){const runs=await composition.runs.list();const existing=runs.filter(candidate=>candidate.finished===null&&effectiveRunV2Role(candidate.run)==="orchestrator"&&candidate.run.parent_run_id===null&&candidate.run.task_id===task.id&&candidate.run.execution_id===executionId).sort((left,right)=>right.run.occurred_at.localeCompare(left.run.occurred_at))[0];if(existing!==void 0)return existing.run;const invocation=await resolveRunClientInvocation(filesystem,"codex");if(invocation.clientTurnId!==null){await composition.executions.claimClientTurn(executionId,invocation.clientTurnId)}const intake=await findIntakeForExactTurn(composition,"codex",invocation);const source=intake?.run;const developerIdentity=await resolveDeveloperIdentityForRoot(filesystem);const writer=await composition.runs.start({...parsed.options.run===void 0?{}:{id:parsed.options.run},shortName:task.short_name,phase:"execution",runRole:"orchestrator",runPurpose:"orchestration",requiresFinalizer:true,executionKind:"delivery",executionEligibility:[],entrypoint:"task",workType:source?.work_type??"new",client:"codex",agent:"agent-orchestrator",agentName:"zaip-agent-orchestrator",provider:source?.provider??null,model:parsed.options.model??source?.model??"unknown",reasoningEffort:source?.reasoning_effort??null,...invocation,conversationId:source?.conversation_id??createConversationId(task.short_name),executionId,taskId:task.id,changeId,developerIdentity});return writer.started}async function ensureTaskDraftChange(composition,task){const existing=await composition.changes.read(task.change_id).catch(()=>null);if(existing!==null)return existing.change;return composition.changes.createDraft({id:task.change_id,title:task.title,risk:task.risk,taskId:task.id,requirementIds:task.requirement_ids,acceptanceIds:task.acceptance_ids})}function plannedChangeFromBlueprint(blueprint,plan,taskId){return{schema_version:2,id:blueprint.id,revision:1,title:blueprint.title,status:"planned",risk:blueprint.risk,source:blueprint.source,requirement_ids:[...blueprint.requirement_ids],acceptance_ids:[...blueprint.acceptance_ids],requirement_impact:blueprint.requirement_impact,task_ids:[taskId],plan_revision:plan.revision,plan_hash:plan.hash,created_at:plan.prepared_at,updated_at:plan.prepared_at,started_at:null,finished_at:null,result:null}}function materializationOutput(result2,composition){return{execution:result2.execution,changes:result2.changes,tasks:result2.tasks,artifact_path:composition.executions.path(result2.execution.id),change_paths:result2.changes.map(change=>composition.changes.path(change.id)),task_paths:result2.tasks.map(task=>composition.tasks.path(task.id)),created_paths:result2.created_paths,reused_paths:result2.reused_paths}}async function preparedPlanForReadyOrExecute(entity,kind,id,materializer){if(entity.prepared_plan!==null)return entity.prepared_plan;if(entity.plan_ref!==null)return materializer.readPreparedPlan(entity.plan_ref.execution_id);throw new UsageError(`${kind} is not prepared: ${id}`)}function inferredOrphanFailureTask(fold,tasks){if(fold.finished?.status!=="failed"||fold.run.client_thread_id!==null||fold.run.client_turn_id!==null||fold.finalization_decision!=null||effectiveRunV2Role(fold.run)!=="orchestrator")return void 0;return tasks.find(task=>{const result2=task.result;return task.id===fold.run.task_id&&task.status==="failed"&&result2!=null&&result2.completed_run_id===fold.run.run_id&&result2.changed_files.length===0&&result2.evidence_ids.length===0&&task.status_reason===`Run ${fold.run.run_id} failed and closed its operational lifecycle.`})}var terminalTaskStatuses=new Set(["blocked","completed","cancelled","failed"]);var openChangeStatuses=new Set(["draft","planned","executing","verifying"]);async function blockExplicitlySelectedUnmaterializedTasks(catalog,runs,composition,scope){const clock=new SystemClock;const blocked=[];for(const task of catalog.tasks){if(!scope.matchesTask(task.id)||!["draft","planned","blocked"].includes(task.status))continue;const linkedRun=runs.some(run=>run.run.task_id===task.id);const linkedExecution=catalog.executions.some(execution=>execution.origin.type==="task"&&execution.origin.task_id===task.id||execution.dag.nodes.some(node=>node.task_id===task.id));if(linkedRun||linkedExecution)continue;const change=catalog.changes.find(candidate=>candidate.id===task.change_id);const reason=`Explicit orphan reconciliation selected Task ${task.id}; no linked Run or Execution was found${change===void 0?"; linked Change absent.":"."}`;let changed=false;if(task.status!=="blocked"){await composition.tasks.transition(task.id,"blocked",null,clock,reason);changed=true}const otherOpenTask=change?.task_ids.some(id=>id!==task.id&&!terminalTaskStatuses.has(catalog.tasks.find(candidate=>candidate.id===id)?.status??"unknown"));const activeChangeRun=change!==void 0&&runs.some(run=>run.finished===null&&(run.run.change_id===change.id||run.run.task_id!==null&&change.task_ids.includes(run.run.task_id)));if(change!==void 0&&openChangeStatuses.has(change.status)&&!otherOpenTask&&!activeChangeRun){await composition.changes.transition(change.id,"blocked",null,clock,reason);changed=true}if(changed)blocked.push((await composition.tasks.read(task.id)).task)}return blocked}var ORPHANED_RUN_GRACE_MS=10*60*1e3;var ORPHANED_EXECUTION_GRACE_MS=10*60*1e3;var ACTIVE_INVOCATION_START_TOLERANCE_MS=2*60*1e3;var EXPLICIT_LEGACY_CODEX_CLIENTS=new Set(["codex-prd-authoring","codex-prd-composite-authoring"]);async function reconcileOpenWork(parsed,composition,lifecycle,filesystem){let runs=await composition.runs.list();const orphanScope=authorizedOrphanScope(parsed);const runningCodex=runs.filter(fold=>[fold.finished===null,isReconcilableCodexClient(fold.run.client,orphanScope!==void 0),orphanScope===void 0?fold.run.client_thread_id!==null:orphanScope.matchesRun(fold)].every(Boolean)).sort((left,right)=>runDepth(right,runs)-runDepth(left,runs));const threadIds=runningCodex.flatMap(fold=>typeof fold.run.client_thread_id==="string"?[fold.run.client_thread_id]:[]);const invocations=runningCodex.flatMap(fold=>{const threadId=fold.run.client_thread_id;const turnId=fold.run.client_turn_id;return typeof threadId==="string"&&typeof turnId==="string"?[{threadId,turnId}]:[]});const[localLifecycles,activeInvocations]=threadIds.length===0?[[],[]]:await Promise.all([listCodexInvocationLifecycles(filesystem.root,{threadIds,invocations}),listActiveCodexInvocations(filesystem.root,{threadIds})]);const localByInvocation=new Map(localLifecycles.map(item=>[`${item.sessionId}:${item.turnId}`,item]));const closedRuns=[];const orphanedRootRunIds=new Set;const reconciliationStartedAt=new Date;for(const fold of runningCodex){if((await composition.runs.read(fold.run.run_id)).finished!==null)continue;const local=localByInvocation.get(`${fold.run.client_thread_id??""}:${fold.run.client_turn_id??""}`);const completedLocally=(local?.status==="completed"||local?.status==="cancelled"||local?.status==="interrupted")&&local.finishedAt!==null;const orphaned=isOrphanedCodexRun(fold,activeInvocations,reconciliationStartedAt)||orphanScope!==void 0&&isExplicitLegacyNoHostOrphan(fold,reconciliationStartedAt);if(!completedLocally&&!orphaned)continue;if(orphaned)orphanedRootRunIds.add(fold.run.run_id);const role=effectiveRunV2Role(fold.run);const activeChildren=activeDescendantRuns(fold.run.run_id,runs);if(role==="orchestrator"&&activeChildren.length>0){if(local?.status!=="cancelled")continue;await cancelActiveDescendantRuns2(activeChildren,composition,parsed);runs=await composition.runs.list()}let current=completedLocally?await recordCodexTelemetryIfAvailable(fold,composition,filesystem):fold;if(current.effective_usage_records.length===0){await composition.runs.appendRecord(unavailableUsageRecord(current,parsed,current.records.length+1));current=await composition.runs.read(current.run.run_id)}const finished=runFinishedV2Schema.parse({schema_version:2,event_id:`${current.run.run_id}:${String(current.records.length+1).padStart(6,"0")}`,run_id:current.run.run_id,sequence:current.records.length+1,occurred_at:completedLocally?local.finishedAt:new Date().toISOString(),type:"run.finished",phase:latestRunV2Phase(current.records),status:completedLocally&&local?.status==="cancelled"?"cancelled":completedLocally?"completed":"failed"});foldRunV2Records([...current.records,finished]);await composition.runs.appendRecord(finished);closedRuns.push(await composition.runs.read(current.run.run_id));runs=await composition.runs.list()}if(closedRuns.length>0)runs=await composition.runs.list();let[tasks,changes,executions,specs,prds]=await Promise.all([composition.tasks.list(),composition.changes.list(),composition.executions.list(),composition.specs.list(),composition.prds.list()]);let catalog={tasks,changes,executions,specs,prds};const explicitlyCancelled=await closeExplicitlyCancelledTaskRoots(runs,catalog,composition,parsed,orphanScope);if(explicitlyCancelled.length>0){closedRuns.push(...explicitlyCancelled);runs=await composition.runs.list()}const activeSubjectIds=activeLifecycleSubjectIds(runs.filter(item=>item.finished===null&&!(orphanScope?.matchesRun(item)&&isOrphanedCodexRun(item,activeInvocations,reconciliationStartedAt))),catalog);const operationalSubjectIds=terminalReconciliationSubjectIds(catalog,orphanScope!==void 0);const inferredRepairIds=new Set;if(orphanScope!==void 0){for(const fold of runs){const task=inferredOrphanFailureTask(fold,catalog.tasks);if(task===void 0||!orphanScope.matchesRun(fold)||activeSubjectIds.has(task.id)||activeDescendantRuns(fold.run.run_id,runs).length>0)continue;inferredRepairIds.add(fold.run.run_id);orphanedRootRunIds.add(fold.run.run_id);operationalSubjectIds.add(task.id)}}const reconciliations=[];const reconciliationErrors=[];const reconciledSubjectIds=new Set;const terminal=runs.filter(fold=>fold.finished!==null&&terminalSubjectIds(fold).some(id=>operationalSubjectIds.has(id))&&(orphanScope===void 0||orphanScope.matchesRun(fold))).sort((left,right)=>(right.finished?.occurred_at??right.run.occurred_at).localeCompare(left.finished?.occurred_at??left.run.occurred_at));for(const fold of terminal){const subjects=terminalSubjectIds(fold);if(subjects.length===0||subjects.some(id=>activeSubjectIds.has(id))||subjects.every(id=>reconciledSubjectIds.has(id))){continue}try{if(inferredRepairIds.has(fold.run.run_id)){const task=inferredOrphanFailureTask(fold,catalog.tasks);if(task!==void 0)await lifecycle.startTask(task.id,"rework")}reconciliations.push(await reconcileFinishedRunLifecycle(fold,composition,lifecycle,{...inferredRepairIds.has(fold.run.run_id)?{}:{catalog},candidateRuns:runs,...orphanedRootRunIds.has(fold.run.run_id)?{requestedOutcome:"blocked",forceRequestedOutcome:true,summary:"Explicit orphan reconciliation found no active host invocation or terminal work outcome; repair is required before resuming"}:{}}))}catch(error51){const message=error51 instanceof Error?error51.message:String(error51);reconciliations.push({...await snapshotRunLifecycle(fold,composition,catalog),status:"deferred",error:message});reconciliationErrors.push({run_id:fold.run.run_id,error:message})}subjects.forEach(id=>{reconciledSubjectIds.add(id)})}[tasks,changes,executions,specs,prds]=await Promise.all([composition.tasks.list(),composition.changes.list(),composition.executions.list(),composition.specs.list(),composition.prds.list()]);catalog={tasks,changes,executions,specs,prds};const orphanedExecutions=await blockOrphanedStandaloneExecutions(catalog,runs,composition,reconciliationStartedAt,orphanScope);const orphanedInteractionExecutions=await blockOrphanedInteractionExecutions(catalog,runs,composition,reconciliationStartedAt,orphanScope);const orphanedTasks=orphanScope===void 0?[]:await blockExplicitlySelectedUnmaterializedTasks(catalog,runs,composition,orphanScope);return{runs:closedRuns,orphaned_executions:orphanedExecutions.map(execution=>execution.id),orphaned_interaction_executions:orphanedInteractionExecutions.map(execution=>execution.id),orphaned_tasks:orphanedTasks.map(task=>task.id),orphaned_execution_entities:[...orphanedExecutions,...orphanedInteractionExecutions],reconciliations,reconciliation_errors:reconciliationErrors,unresolved_running_run_ids:runs.filter(fold=>fold.finished===null).map(fold=>fold.run.run_id)}}async function closeExplicitlyCancelledTaskRoots(runs,catalog,composition,parsed,scope){const cancelledTaskIds=new Set(catalog.tasks.filter(task=>task.status==="cancelled").map(task=>task.id));const closed=[];for(const fold of runs){if(fold.finished!==null||effectiveRunV2Role(fold.run)!=="orchestrator"||fold.run.parent_run_id!==null||fold.run.entrypoint!=="task"||fold.run.task_id===null||!cancelledTaskIds.has(fold.run.task_id)||scope!==void 0&&!scope.matchesRun(fold)){continue}const current=await composition.runs.read(fold.run.run_id);if(current.finished!==null)continue;const activeChildren=activeDescendantRuns(current.run.run_id,runs);if(activeChildren.length>0)await cancelActiveDescendantRuns2(activeChildren,composition,parsed);let attributable=await composition.runs.read(current.run.run_id);if(attributable.effective_usage_records.length===0){await composition.runs.appendRecord(unavailableUsageRecord(attributable,parsed,attributable.records.length+1));attributable=await composition.runs.read(current.run.run_id)}await composition.runs.appendRecord(runFinishedV2Schema.parse({schema_version:2,event_id:`${attributable.run.run_id}:${String(attributable.records.length+1).padStart(6,"0")}`,run_id:attributable.run.run_id,sequence:attributable.records.length+1,occurred_at:new Date().toISOString(),type:"run.finished",phase:latestRunV2Phase(attributable.records),status:"cancelled"}));closed.push(await composition.runs.read(current.run.run_id))}return closed}async function cancelActiveDescendantRuns2(descendants,composition,parsed){for(const descendant of[...descendants].reverse()){let current=await composition.runs.read(descendant.run.run_id);if(current.finished!==null)continue;if(current.effective_usage_records.length===0){await composition.runs.appendRecord(unavailableUsageRecord(current,parsed,current.records.length+1));current=await composition.runs.read(current.run.run_id)}await composition.runs.appendRecord(runFinishedV2Schema.parse({schema_version:2,event_id:`${current.run.run_id}:${String(current.records.length+1).padStart(6,"0")}`,run_id:current.run.run_id,sequence:current.records.length+1,occurred_at:new Date().toISOString(),type:"run.finished",phase:latestRunV2Phase(current.records),status:"cancelled"}))}}async function blockOrphanedStandaloneExecutions(catalog,runs,composition,now,scope){const ids=orphanedStandaloneExecutionIds(catalog,runs,now,scope!==void 0).filter(id=>{const execution=catalog.executions.find(candidate=>candidate.id===id);return execution!==void 0&&(scope===void 0||scope.matchesExecution(execution))});if(ids.length===0)return[];const clock=new SystemClock;const taskById=new Map(catalog.tasks.map(task=>[task.id,task]));const changeById=new Map(catalog.changes.map(change=>[change.id,change]));const blocked=[];for(const id of ids){const execution=catalog.executions.find(item=>item.id===id);if(execution===void 0)continue;const reason=`Execution ${id} has no active orchestrator agent call after the reconciliation grace period.`;for(const node of execution.dag.nodes){const task=taskById.get(node.task_id);if(task!==void 0&&["executing","verifying"].includes(task.status)){await composition.tasks.transition(task.id,"blocked",null,clock,reason)}const change=changeById.get(node.change_id);if(change!==void 0&&["executing","verifying"].includes(change.status)){await composition.changes.transition(change.id,"blocked",null,clock,reason)}}await composition.executions.transition(id,"blocked",null,clock,reason);blocked.push((await composition.executions.read(id)).execution)}return blocked}async function blockOrphanedInteractionExecutions(catalog,runs,composition,now,scope){const ids=orphanedInteractionExecutionIds(catalog,runs,now).filter(id=>{const execution=catalog.executions.find(candidate=>candidate.id===id);return execution!==void 0&&(scope===void 0||scope.matchesExecution(execution))});if(ids.length===0)return[];const clock=new SystemClock;const blocked=[];for(const id of ids){await composition.executions.transition(id,"blocked",null,clock,`Interaction Execution ${id} has no active orchestrator Run after the reconciliation grace period.`);blocked.push((await composition.executions.read(id)).execution)}return blocked}function orphanedStandaloneExecutionIds(catalog,runs,now=new Date,includePlanned=false){return catalog.executions.flatMap(execution=>{if(execution.origin.type!=="task"||!["running","verifying",...includePlanned?["planned"]:[]].includes(execution.status)){return[]}const startedAt=Date.parse(execution.started_at??execution.updated_at??execution.created_at);if(!Number.isFinite(startedAt)||now.getTime()-startedAt<ORPHANED_EXECUTION_GRACE_MS){return[]}const taskIds=new Set(execution.dag.nodes.map(node=>node.task_id));const hasActiveOrchestratorRun=runs.some(run=>{const required2=[run.finished===null,effectiveRunV2Role(run.run)==="orchestrator",run.run.parent_run_id===null,run.run.entrypoint==="task"];if(!required2.every(Boolean))return false;return run.run.execution_id===execution.id||run.run.task_id!==null&&taskIds.has(run.run.task_id)});return hasActiveOrchestratorRun?[]:[execution.id]})}function orphanedInteractionExecutionIds(catalog,runs,now=new Date){return catalog.executions.flatMap(execution=>{if(execution.kind!=="interaction"||!["running","verifying"].includes(execution.status)){return[]}const startedAt=Date.parse(execution.started_at??execution.updated_at??execution.created_at);if(!Number.isFinite(startedAt)||now.getTime()-startedAt<ORPHANED_EXECUTION_GRACE_MS){return[]}const hasActiveRoot=runs.some(run=>run.finished===null&&effectiveRunV2Role(run.run)==="orchestrator"&&run.run.parent_run_id===null&&run.run.execution_id===execution.id);return hasActiveRoot?[]:[execution.id]})}function terminalReconciliationSubjectIds(catalog,includePrepared=false){const ids=new Set;const unsettledTaskIds=new Set(catalog.tasks.filter(task=>["executing","verifying",...includePrepared?["planned"]:[]].includes(task.status)).map(task=>task.id));unsettledTaskIds.forEach(id=>{ids.add(id)});for(const change of catalog.changes){const unsettled=["planned","executing","verifying"].includes(change.status);const hasUnsettledTask=change.task_ids.some(id=>unsettledTaskIds.has(id));if(!unsettled&&!hasUnsettledTask)continue;change.task_ids.forEach(id=>{ids.add(id)});if(change.source.type==="spec")ids.add(change.source.spec_id);if(change.source.type==="prd"){ids.add(change.source.prd_id);if(change.source.spec_id!==null)ids.add(change.source.spec_id)}}for(const execution of catalog.executions){if(!["planned","running","paused","verifying"].includes(execution.status))continue;execution.dag.nodes.forEach(node=>{ids.add(node.task_id)})}catalog.specs.filter(spec=>spec.status==="active").forEach(spec=>{ids.add(spec.id)});catalog.prds.filter(prd=>prd.status==="active").forEach(prd=>{ids.add(prd.id)});return ids}function authorizedOrphanScope(parsed){const reason=parsed.options["orphan-reason"];const scope=parsed.options["orphan-scope"];if(reason===void 0&&scope===void 0)return void 0;if(reason!=="inactive_terminal_without_host_identity"){throw new Error("--orphan-reason must be inactive_terminal_without_host_identity for explicit orphan reconciliation")}if(scope===void 0||scope.trim().length===0){throw new Error("Explicit orphan reconciliation requires --orphan-scope all or comma-separated Run/Task/Execution IDs")}const ids=new Set(scope.split(",").map(value=>value.trim()).filter(Boolean));if(ids.size===0)throw new Error("--orphan-scope must name all or at least one canonical ID");return{matchesRun(fold){return ids.has("all")||ids.has(fold.run.run_id)||fold.run.task_id!==null&&ids.has(fold.run.task_id)||fold.run.execution_id!==null&&ids.has(fold.run.execution_id)},matchesTask(taskId){return ids.has("all")||ids.has(taskId)},matchesExecution(execution){return ids.has("all")||ids.has(execution.id)||execution.origin.type==="task"&&ids.has(execution.origin.task_id)||execution.dag.nodes.some(node=>ids.has(node.task_id))}}}function isOrphanedCodexRun(fold,activeInvocations,now=new Date){if(fold.finished!==null||!isCodexTelemetryClient(fold.run.client))return false;const startedAt=Date.parse(fold.run.occurred_at);if(!Number.isFinite(startedAt)||now.getTime()-startedAt<ORPHANED_RUN_GRACE_MS){return false}return!activeInvocations.some(active=>{if(active.sessionId!==fold.run.client_thread_id)return false;const activeObservedAt=Date.parse(active.observedAt??active.startedAt??"");if(!Number.isFinite(activeObservedAt)||now.getTime()-activeObservedAt>ORPHANED_RUN_GRACE_MS){return false}if(active.turnId===fold.run.client_turn_id)return true;const activeStartedAt=active.startedAt===null?Number.NaN:Date.parse(active.startedAt);return Number.isFinite(activeStartedAt)&&Math.abs(activeStartedAt-startedAt)<=ACTIVE_INVOCATION_START_TOLERANCE_MS})}function isReconcilableCodexClient(client,explicitScope){return isCodexTelemetryClient(client)||explicitScope&&EXPLICIT_LEGACY_CODEX_CLIENTS.has(client)}function isExplicitLegacyNoHostOrphan(fold,now){if(fold.finished!==null||!EXPLICIT_LEGACY_CODEX_CLIENTS.has(fold.run.client)||fold.run.client_thread_id!==null){return false}const startedAt=Date.parse(fold.run.occurred_at);return Number.isFinite(startedAt)&&now.getTime()-startedAt>=ORPHANED_RUN_GRACE_MS}function activeLifecycleSubjectIds(activeRuns,catalog){const ids=new Set;const taskById=new Map(catalog.tasks.map(task=>[task.id,task]));const changeById=new Map(catalog.changes.map(change=>[change.id,change]));const specById=new Map(catalog.specs.map(spec=>[spec.id,spec]));for(const fold of activeRuns){relatedWorkIds(fold).forEach(id=>{ids.add(id)});const task=fold.run.task_id===null?void 0:taskById.get(fold.run.task_id);const change=task===void 0?void 0:changeById.get(task.change_id);const specId=fold.run.spec_id??(change?.source.type==="spec"||change?.source.type==="prd"?change.source.spec_id:null);const prdId=fold.run.prd_id??(change?.source.type==="prd"?change.source.prd_id:null)??(specId===null?null:specById.get(specId)?.prd_id??null);if(change!==void 0)ids.add(change.id);if(specId!==null)ids.add(specId);if(prdId!==null)ids.add(prdId);for(const candidate of catalog.changes){const belongsToSpec=specId!==null&&candidate.source.type!=="task"&&candidate.source.spec_id===specId;const belongsToPrd=candidate.source.type==="prd"&&candidate.source.prd_id===prdId;if(!belongsToSpec&&!belongsToPrd)continue;ids.add(candidate.id);candidate.task_ids.forEach(id=>{ids.add(id)})}for(const execution of catalog.executions){if(execution.origin.type==="prd"&&execution.origin.prd_id===prdId||execution.origin.type==="spec"&&execution.origin.spec_id===specId){ids.add(execution.id);execution.dag.nodes.forEach(node=>{ids.add(node.task_id)})}}}return ids}function relatedWorkIds(fold){return[fold.run.task_id,fold.run.spec_id,fold.run.prd_id].filter(id=>id!==null)}function runDepth(fold,runs){const parentById=new Map(runs.map(candidate=>[candidate.run.run_id,candidate.run.parent_run_id]));let depth=0;let parent=fold.run.parent_run_id;const seen=new Set([fold.run.run_id]);while(parent!==null&&!seen.has(parent)){seen.add(parent);depth+=1;parent=parentById.get(parent)??null}return depth}function terminalSubjectIds(fold){const role=effectiveRunV2Role(fold.run);if(role==="orchestrator"&&fold.run.entrypoint==="task"){return fold.run.task_id===null?[]:[fold.run.task_id]}if(role==="orchestrator"){return[fold.run.spec_id,fold.run.prd_id].filter(id=>id!==null)}return[]}async function reconcileHistoricalCodexTiming(parsed,composition,filesystem){requireOptions(parsed.options,["id","session","turn"]);const id=parsed.options.id;const turnId=parsed.options.turn;const sessionPath=parsed.options.session;const current=await composition.runs.read(id);if(current.run.client_turn_id!==turnId){throw new UsageError(`Run ${id} is not correlated with the requested turn`)}const candidate=await findLatestCodexSegment(filesystem.root,new Set,{turnId,sessionPaths:[sessionPath],...current.run.client_thread_id==null?{}:{threadId:current.run.client_thread_id}});if(candidate===null||candidate.startedAt===null||candidate.finishedAt===null||candidate.turnId!==turnId){throw new UsageError("No completed observed interval exists for the requested Run/session/turn")}const sourceSegmentKey=candidate.segmentKey;const sourceUsage=current.effective_usage_records.find(record3=>record3.source_segment_key===sourceSegmentKey);if(sourceUsage===void 0){throw new UsageError("No existing usage segment matches the requested observed session turn")}const existing=current.records.find(record3=>record3.type==="usage.recorded"&&record3.supersedes_event_id===sourceUsage.event_id&&"source_started_at"in record3&&record3.source_started_at===candidate.startedAt&&"source_finished_at"in record3&&record3.source_finished_at===candidate.finishedAt);const timing={run_id:id,session:sessionPath,turn_id:turnId,source_started_at:candidate.startedAt,source_finished_at:candidate.finishedAt,source_duration_ms:Date.parse(candidate.finishedAt)-Date.parse(candidate.startedAt),source_segment_key:sourceSegmentKey,supersedes_event_id:sourceUsage.event_id};if(parsed.flags.has("dry-run")||existing!==void 0){return{applied:false,reason:existing===void 0?"dry-run":"already-reconciled",timing}}const sequence=current.records.length+1;await composition.runs.appendRecord(usageRecordedV2Schema.parse({schema_version:2,event_id:runV2EventId(id,sequence),run_id:id,sequence,occurred_at:new Date().toISOString(),type:"usage.recorded",phase:latestRunV2Phase(current.records),activity_kind:"retrospective_local_remeasurement",classification_source:sourceUsage.classification_source,tokens:sourceUsage.tokens,cost:sourceUsage.cost,provider:sourceUsage.provider,model:sourceUsage.model,source_segment_key:sourceSegmentKey,supersedes_event_id:sourceUsage.event_id,retrospective_correction:true,source_occurred_at:candidate.finishedAt,source_started_at:candidate.startedAt,source_finished_at:candidate.finishedAt}));return{applied:true,timing,artifact_path:composition.runs.path(id)}}function sameStringSet2(left,right){return left.length===right.length&&left.every(value=>right.includes(value))}function runV2CostInput2(fold){return{run:{run_id:fold.run.run_id,attribution_status:fold.run.attribution_status,conversation_id:fold.run.conversation_id,execution_id:fold.run.execution_id,task_id:fold.run.task_id,spec_id:fold.run.spec_id,prd_id:fold.run.prd_id,change_id:fold.run.change_id,work_type:fold.run.work_type},records:fold.records,effective_usage_records:fold.effective_usage_records}}function runV2ScopeOption(parsed){return parsed.positionals[2]??parsed.options.id??parsed.options.conversation??parsed.options.execution??parsed.options.task??parsed.options.spec??parsed.options.prd??parsed.options.change??null}async function runRunV2Command(action,parsed,composition,filesystem,lifecycle){if(action==="start"){requireOptions(parsed.options,["short-name","phase","entrypoint","work-type","client","model"]);const client=parsed.options.client;const phase=runV2PhaseOption(parsed.options.phase);const parentRunId=parsed.options.parent??null;const clientInvocation=await resolveRunClientInvocation(filesystem,client);const agentResolution=await resolveRunAgentIdentityResult(filesystem,{agent:parsed.options.agent,client});const agent=agentResolution.agent_id;const runPurpose=parsed.options["run-purpose"]===void 0?phase!=="execution"?"intake":agent==="agent-finalizer"?"finalization":agent==="agent-reviewer"?"review":agent==="agent-auditor"?"audit":parentRunId===null?"orchestration":"execution":runV2PurposeSchema.parse(parsed.options["run-purpose"]);const catalog=await loadAgentCatalog(filesystem).catch(()=>null);const catalogAgent=catalog?.agents.find(candidate=>candidate.id===agent);const parent=parentRunId===null?null:await composition.runs.read(parentRunId);const execution=parent===null&&parsed.options.execution!==void 0?await composition.executions.read(parsed.options.execution).catch(()=>null):null;const executionKind=parent?.run.execution_kind??execution?.execution.kind??void 0;const rootDeveloperIdentity=parentRunId===null?await resolveDeveloperIdentityForRoot(filesystem):void 0;const input={...parsed.options.id===void 0?{}:{id:parsed.options.id},shortName:parsed.options["short-name"],phase,...parsed.options["run-role"]===void 0?{}:{runRole:runV2RoleSchema.parse(parsed.options["run-role"])},runPurpose,...executionKind===void 0?{}:{executionKind},executionEligibility:catalogAgent?.execution_eligibility??[],entrypoint:runV2EntrypointOption(parsed.options.entrypoint),workType:runV2WorkTypeOption(parsed.options["work-type"]),client,agent,agentName:await resolveRunAgentName(filesystem,agent),...agentResolution.warning===null?{}:{agentIdentityWarning:agentResolution.warning},provider:parsed.options.provider??null,model:parsed.options.model,reasoningEffort:parsed.options["reasoning-effort"]===void 0?null:runV2ReasoningEffortSchema.parse(parsed.options["reasoning-effort"]),...clientInvocation,conversationId:parsed.options.conversation??createConversationId(parsed.options["short-name"]),executionId:parsed.options.execution??null,taskId:parsed.options.task??null,specId:parsed.options.spec??null,prdId:parsed.options.prd??null,changeId:parsed.options.change??null,parentRunId,continuationOfRunId:parsed.options.continuation??null,retryOfRunId:parsed.options.retry??null,...rootDeveloperIdentity===void 0?{}:{developerIdentity:rootDeveloperIdentity}};await validateRunV2Attribution(input,composition);const start=async()=>{if(parentRunId!==null){const freshParent=await composition.runs.read(parentRunId);const candidates=await composition.runs.list();assertChildRunMayStart(freshParent,runPurpose,agent,candidates,catalogAgent?.execution_eligibility??[])}const writer=await composition.runs.start(input);return{run:writer.started,artifact_path:composition.runs.path(writer.started.run_id),warnings:agentResolution.warning===null?[]:[agentResolution.warning]}};return parentRunId===null?start():composition.runs.withUsageAttributionLock(start)}if(action==="list"||action==="aggregate"){const runs=filterRunV2Folds(await composition.runs.list(),parsed);if(action==="aggregate"){const aggregate=aggregateRunV2Usage(runs.map(runV2CostInput2),runV2ScopeOption(parsed));const agents=aggregateRunsByAgent(runs,runV2CostInput2);return parsed.options.view==="full"?{...aggregate,agents}:{...compactRunAggregate(aggregate),agents}}const summaries=runs.map(run=>runV2Summary(run,composition));return listLifecyclePage(summaries,parsed)}if(action==="reconcile"){if(parsed.flags.has("open"))return reconcileOpenWork(parsed,composition,lifecycle,filesystem);return reconcileHistoricalCodexTiming(parsed,composition,filesystem)}const id=requiredEntityId(parsed,2,"Run V2 id");if(action==="show"){const run=await composition.runs.read(id);const includeEvents=parsed.flags.has("events")||parsed.options["event-id"]!==void 0||parsed.options["from-sequence"]!==void 0;return includeEvents?{run:{...run,records:run.records.filter(record3=>(parsed.options["event-id"]===void 0||record3.event_id===parsed.options["event-id"])&&(parsed.options["from-sequence"]===void 0||record3.sequence>=numberOption(parsed.options["from-sequence"],1)))},artifact_path:composition.runs.path(id)}:runV2Summary(run,composition)}if(action==="recover-attribution"){return composition.runs.withUsageAttributionLock(async()=>{const current=await composition.runs.read(id);const started=current.records[0];if(current.finished!==null)throw new UsageError(`Run V2 is already finished: ${id}`);if(started?.type!=="run.started")throw new UsageError(`Run V2 has no start record: ${id}`);if(current.attribution_recovery!==null){throw new UsageError(`Run V2 already has an attribution recovery: ${id}`)}if(current.run.entrypoint!=="task"||current.run.execution_id===null||current.run.task_id===null||current.run.change_id!==null){throw new UsageError(`Run ${id} is not an active task Run with an unclaimed Change attribution`)}const task=await composition.tasks.read(current.run.task_id);const changeId=task.task.change_id;if(changeId===null)throw new UsageError(`Task ${task.task.id} has no materialized Change`);await validateRunV2Attribution({shortName:current.run.run_id,phase:"execution",entrypoint:"task",workType:current.run.work_type,client:current.run.client,agent:current.run.agent,provider:current.run.provider,model:current.run.model,conversationId:current.run.conversation_id,executionId:current.run.execution_id,taskId:current.run.task_id,changeId,parentRunId:current.run.parent_run_id,continuationOfRunId:current.run.continuation_of_run_id,retryOfRunId:current.run.retry_of_run_id},composition);const record3=runAttributionRecoveredV2Schema.parse({schema_version:2,event_id:runV2EventId(id,current.records.length+1),run_id:id,sequence:current.records.length+1,occurred_at:new Date().toISOString(),type:"run.attribution.recovered",phase:"execution",execution_id:current.run.execution_id,task_id:current.run.task_id,change_id:changeId});await composition.runs.appendRecord(record3);return{recovery:record3,run:runV2Summary(await composition.runs.read(id),composition),artifact_path:composition.runs.path(id)}})}if(action==="closure"){const current=await composition.runs.read(id);if(current.finished===null)throw new UsageError(`Run V2 is still running: ${id}`);const closure=await assessRunLifecycleClosure(current,composition);if(closure.status==="action_required"){throw new UsageError(`Run ${id} left related work open: ${closure.open_subject_ids.join(", ")}. ${closure.guidance}`)}return{closure,artifact_path:composition.runs.path(id)}}if(action==="usage"){let current=await composition.runs.read(id);if(current.finished!==null)throw new UsageError(`Run V2 is already finished: ${id}`);const appServerEventsPath=parsed.options["codex-app-server-events"];const rawCaptureDisabled=parsed.flags.has("disable-codex-raw");if(appServerEventsPath!==void 0&&!rawCaptureDisabled){const notifications=parseCodexAppServerNotificationStream(await filesystem.readText(appServerEventsPath));const persisted=await ingestCodexAppServerNotifications(filesystem,notifications);current=await recordCodexTelemetryIfAvailable(current,composition,filesystem);return{telemetry:{received_notifications:notifications.length,persisted_event_ids:persisted.map(event=>event.event_id)},run:runV2Summary(current,composition),artifact_path:composition.runs.path(id)}}if(rawCaptureDisabled){current=await recordCodexTelemetryIfAvailable(current,composition,filesystem);return{telemetry:{raw_capture:"disabled",fallback:"codex_session_fallback"},run:runV2Summary(current,composition),artifact_path:composition.runs.path(id)}}const sequence=current.records.length+1;const input=nullableNumberOption(parsed.options["input-tokens"]);const cachedInput=nullableNumberOption(parsed.options["cached-input-tokens"]);const outputTokens=nullableNumberOption(parsed.options["output-tokens"]);const reasoning=nullableNumberOption(parsed.options["reasoning-tokens"]);const explicitTotal=nullableNumberOption(parsed.options["total-tokens"]);const occurredAt=new Date().toISOString();const tokens={input,cached_input:cachedInput,output:outputTokens,reasoning,total:explicitTotal??(input===null||outputTokens===null?null:input+outputTokens),source:tokenSourceOption(parsed.options["token-source"])};const provider=inferProvider(parsed.options.model??current.run.model,parsed.options.provider??current.run.provider??current.run.client,current.run.agent);const pricing=new PricingRepository(filesystem);const estimated=estimateUsageCost({provider,model:parsed.options.model??current.run.model,usage:tokens,catalog:await pricing.readCatalog(),fxRate:await pricing.readLatestFxRate()});const record3=usageRecordedV2Schema.parse({schema_version:2,event_id:parsed.options["event-id"]??runV2EventId(id,sequence),run_id:id,sequence,occurred_at:occurredAt,type:"usage.recorded",phase:runV2PhaseOption(parsed.options.phase??latestRunV2Phase(current.records)),activity_kind:parsed.options.activity??"implementation",classification_source:runV2ClassificationOption(parsed.options.classification),tokens,cost:{usd:nullableCurrencyOption(parsed.options["cost-usd"])??estimated.estimated_usd,brl:nullableCurrencyOption(parsed.options["cost-brl"])??estimated.estimated_brl,fx_rate:parsed.options["cost-brl"]===void 0?estimated.fx_rate:null},provider,model:parsed.options.model??current.run.model,source_segment_key:parsed.options["source-segment"]??null,supersedes_event_id:parsed.options.supersedes??null,...runUsageMetadataOptions(parsed.options,occurredAt)});const folded=foldRunV2Records([...current.records,record3]);await composition.runs.appendRecord(record3);const budget=await evaluateRunBudget(folded,composition,filesystem);return{usage:record3,budget,artifact_path:composition.runs.path(id)}}if(action==="finish"){const telemetryCandidate=await composition.runs.read(id);if(telemetryCandidate.finished===null){await recordCodexTelemetryIfAvailable(telemetryCandidate,composition,filesystem)}return composition.runs.withUsageAttributionLock(async()=>{let current=await composition.runs.read(id);const status=runV2FinishStatusOption(parsed.options.status);const candidateRuns=await composition.runs.list();const role=effectiveRunV2Role(current.run);const suppliedEvidenceIds=csvOption(parsed.options.evidence);const finalizationDecision=current.finalization_decision??null;if(finalizationDecision!==null&&suppliedEvidenceIds.length>0&&!sameStringSet2(suppliedEvidenceIds,finalizationDecision.evidence_ids)){throw new UsageError("--evidence must match the persisted Gui finalization decision")}const evidenceIds=finalizationDecision?.evidence_ids??suppliedEvidenceIds;const suppliedChangedFiles=csvOption(parsed.options["changed-files"]);if(finalizationDecision!==null&&suppliedChangedFiles.length>0&&!sameStringSet2(suppliedChangedFiles,finalizationDecision.changed_files)){throw new UsageError("--changed-files must match the persisted Gui finalization decision")}const changedFiles=finalizationDecision?.changed_files??suppliedChangedFiles;const finalizationBarrier=assessRunFinalizationBarrier(current,candidateRuns,await hasPassedTypedEvidenceForRun(current,evidenceIds,composition,candidateRuns));const barrierBlockReason=finalizationBarrierBlockReason(finalizationBarrier);const finalizationBlockReason=finalizationDecision!==null&&finalizationDecision.outcome!=="completed"?null:barrierBlockReason;if(current.finished===null&&finalizationBarrier.status==="evidence_missing"&&finalizationBlockReason!==null){throw new UsageError(finalizationBlockReason)}const suppliedOutcome=lifecycleOutcomeOption(parsed.options);if(current.finished===null&&role==="orchestrator"&&finalizationBarrier.required&&finalizationDecision===null&&finalizationBlockReason===null){throw new UsageError(`Run ${id} requires a persisted Gui finalization decision before lifecycle closure`)}if(finalizationDecision!==null&&suppliedOutcome!==void 0&&suppliedOutcome!==finalizationDecision.outcome){throw new UsageError(`--task-outcome must match the persisted Gui decision (${finalizationDecision.outcome})`)}if(finalizationDecision!==null&&parsed.options.summary!==void 0&&parsed.options.summary!==finalizationDecision.summary){throw new UsageError("--summary must match the persisted Gui finalization decision")}const requestedOutcome=finalizationBlockReason===null?finalizationDecision?.outcome??suppliedOutcome:"blocked";const reconciliationSummary=finalizationBlockReason??finalizationDecision?.summary??parsed.options.summary;if(current.finished===null&&role==="orchestrator"){const activeChildren=activeDescendantRuns(id,candidateRuns);if(activeChildren.length>0){throw new UsageError(`Run ${id} cannot finish while descendant Runs are active: ${activeChildren.map(child=>child.run.run_id).join(", ")}`)}}if(finalizationBlockReason===null&&parsed.flags.has("defer-orchestrator-closure")&&role==="orchestrator"){throw new UsageError(`Orchestrator Run closure cannot be deferred for Run ${id}`)}const deferClosure=finalizationBlockReason===null&&parsed.flags.has("defer-orchestrator-closure");if(current.finished!==null){if(current.finished.status!==status){throw new UsageError(`Run V2 is already ${current.finished.status}: ${id}`)}const reconciliation2=await reconcileFinishedRunLifecycle(current,composition,lifecycle,{requestedOutcome,forceRequestedOutcome:finalizationBlockReason!==null,summary:reconciliationSummary,changedFiles,evidenceIds,defer:deferClosure,candidateRuns});const interactionExecution2=await settleInteractionExecutionForRun(current,composition,finalizationBlockReason);return{run:parsed.flags.has("events")||parsed.options.view==="full"?current:runV2Summary(current,composition),reconciliation:reconciliation2,execution:interactionExecution2,finalization_barrier:finalizationBarrier,closure:await assessRunLifecycleClosure(current,composition,candidateRuns),artifact_path:composition.runs.path(id)}}if(current.effective_usage_records.length===0){const usage=unavailableUsageRecord(current,parsed,current.records.length+1);await composition.runs.appendRecord(usage);current=foldRunV2Records([...current.records,usage])}const sequence=current.records.length+1;const record3=runFinishedV2Schema.parse({schema_version:2,event_id:runV2EventId(id,sequence),run_id:id,sequence,occurred_at:new Date().toISOString(),type:"run.finished",phase:latestRunV2Phase(current.records),status});foldRunV2Records([...current.records,record3]);await composition.runs.appendRecord(record3);const run=await composition.runs.read(id);const reconciliation=await reconcileFinishedRunLifecycle(run,composition,lifecycle,{requestedOutcome,forceRequestedOutcome:finalizationBlockReason!==null,summary:reconciliationSummary,changedFiles,evidenceIds,defer:deferClosure,candidateRuns});const interactionExecution=await settleInteractionExecutionForRun(run,composition,finalizationBlockReason);const closure=await assessRunLifecycleClosure(run,composition,candidateRuns);return{run:parsed.flags.has("events")||parsed.options.view==="full"?run:runV2Summary(run,composition),reconciliation,execution:interactionExecution,finalization_barrier:finalizationBarrier,closure,artifact_path:composition.runs.path(id)}})}if(action==="finalization"){const current=await composition.runs.read(id);if(effectiveRunV2Role(current.run)!=="orchestrator"){throw new UsageError(`Run ${id} is not an orchestrator Run`)}const outcome=lifecycleOutcomeOption(parsed.options);if(outcome===void 0)throw new UsageError("Missing options: --task-outcome");const summary=parsed.options.summary?.trim();if(summary===void 0||summary.length===0)throw new UsageError("Missing options: --summary");const evidenceIds=csvOption(parsed.options.evidence);const changedFiles=csvOption(parsed.options["changed-files"]);const requestedFinalizerRunId=parsed.options["finalizer-run-id"]?.trim();return composition.runs.withUsageAttributionLock(async()=>{const fresh=await composition.runs.read(id);const existing=fresh.finalization_decision??null;if(existing!==null){if(requestedFinalizerRunId!==void 0&&requestedFinalizerRunId.length>0&&existing.finalizer_run_id!==requestedFinalizerRunId||existing.outcome!==outcome||existing.summary!==summary||!sameStringSet2(existing.evidence_ids,evidenceIds)||!sameStringSet2(existing.changed_files,changedFiles)){throw new UsageError(`Run ${id} already has a different Gui finalization decision`)}return{finalization:existing,reused:true,artifact_path:composition.runs.path(id)}}const lockedCandidates=await composition.runs.list();const finalizers=lockedCandidates.filter(candidate=>candidate.run.parent_run_id===id&&effectiveRunV2Purpose(candidate.run)==="finalization"&&candidate.run.agent==="agent-finalizer");const activeFinalizers=finalizers.filter(candidate=>candidate.finished===null);const terminalFallbackFinalizers=finalizers.filter(candidate=>candidate.finished!==null&&candidate.run.client==="codex-subagent"&&candidate.run.client_turn_id===null&&candidate.run.provider===null&&candidate.run.model==="unavailable");const candidatesForDecision=fresh.finished===null?activeFinalizers:terminalFallbackFinalizers;const lockedFinalizer=requestedFinalizerRunId===void 0||requestedFinalizerRunId.length===0?candidatesForDecision.length===1?candidatesForDecision[0]:void 0:candidatesForDecision.find(candidate=>candidate.run.run_id===requestedFinalizerRunId);if(lockedFinalizer===void 0){if(fresh.finished!==null){throw new UsageError(`Run ${id} requires its exact terminal fallback Gui finalizer to record a post-close decision`)}throw new UsageError(`Run ${id} requires an active Gui finalizer to record its decision`)}if(fresh.finished!==null&&fresh.finished.status!=="completed"){throw new UsageError(`Run V2 is already ${fresh.finished.status}: ${id}`)}const lockedActiveElsewhere=activeDescendantRuns(id,lockedCandidates).filter(candidate=>candidate.run.run_id!==lockedFinalizer.run.run_id);if(lockedActiveElsewhere.length>0){throw new UsageError(`Gui finalization for Run ${id} requires every other descendant to be terminal: ${lockedActiveElsewhere.map(run=>run.run.run_id).join(", ")}`)}const record3=runFinalizationDecidedV2Schema.parse({schema_version:2,event_id:runV2EventId(id,fresh.records.length+1),run_id:id,sequence:fresh.records.length+1,occurred_at:new Date().toISOString(),type:"run.finalization.decided",finalizer_run_id:lockedFinalizer.run.run_id,outcome,summary,evidence_ids:evidenceIds,changed_files:changedFiles});await composition.runs.appendRecord(record3);return{finalization:record3,reused:false,artifact_path:composition.runs.path(id)}})}throw new UsageError(`Unknown Run V2 action: ${action??""}`)}async function settleInteractionExecutionForRun(run,composition,finalizationBlockReason){if(run.run.execution_id===null)return null;let execution=(await composition.executions.read(run.run.execution_id)).execution;if(execution.kind!=="interaction")return null;if(run.finished?.status==="cancelled"){return["running","paused","verifying"].includes(execution.status)?composition.executions.transition(execution.id,"cancelled","Run explicitly cancelled"):execution}if(finalizationBlockReason!==null){return["running","paused","verifying"].includes(execution.status)?composition.executions.transition(execution.id,"blocked",null,void 0,finalizationBlockReason):execution}if(execution.status==="running"){execution=await composition.executions.transition(execution.id,"verifying")}return execution.status==="verifying"?composition.executions.transition(execution.id,"completed","Interaction finalized"):execution}function filterRunV2Folds(runs,parsed){const statuses=new Set(csvOption(parsed.options.status));const from=dateBoundary(parsed.options.from,false);const to=dateBoundary(parsed.options.to,true);const positionalRunId=parsed.positionals[2];const phase=parsed.options.phase===void 0?void 0:runV2PhaseOption(parsed.options.phase);const entrypoint=parsed.options.entrypoint===void 0?void 0:runV2EntrypointOption(parsed.options.entrypoint);const workType=parsed.options["work-type"]===void 0?void 0:runV2WorkTypeOption(parsed.options["work-type"]);return runs.filter(fold=>{const run=fold.run;if(statuses.size>0&&!statuses.has(fold.status))return false;const occurredAt=Date.parse(run.occurred_at);if(from!==null&&occurredAt<from||to!==null&&occurredAt>to)return false;const requestedAgent=parsed.options.agent;if(requestedAgent!==void 0&&run.agent!==requestedAgent&&run.agent_name!==requestedAgent){return false}const criteria=[[positionalRunId,run.run_id],[parsed.options.id,run.run_id],[phase,phase===void 0?void 0:latestRunV2Phase(fold.records)],[entrypoint,run.entrypoint],[workType,run.work_type],[parsed.options.conversation,run.conversation_id],[parsed.options.execution,run.execution_id],[parsed.options.task,run.task_id],[parsed.options.spec,run.spec_id],[parsed.options.prd,run.prd_id],[parsed.options.change,run.change_id]];return criteria.every(([expected,actual])=>expected===void 0||actual===expected)})}var V2_COMMAND_AREAS=new Set(["plan","prd","spec","change","task","execution","decision","evidence","validation","run","run-v2","conversation","developer","subagent"]);function createV2Composition(filesystem,layout){const storageMode=layout.projectConfig?.tracking.storage_mode??"tracked_sanitized";return{filesystem,layout,prds:new PrdV2Repository(filesystem,layout),specs:new DeliverySpecV2Repository(filesystem,layout),changes:new ChangeV2Repository(filesystem,layout),tasks:new TaskV2Repository(filesystem,layout),executions:new ExecutionV2Repository(filesystem,layout),materializer:new PreparedPlanV2Materializer(filesystem,layout),decisions:new DecisionV2Repository(filesystem,layout),runs:new RunV2Repository(filesystem,storageMode==="local_only"?{storageMode:"local_only",localBasePath:".local/runs"}:{storageMode:"tracked_sanitized",layout})}}async function runV2Command(area,action,parsed,filesystem,layout){if(!isLifecycleManifestMutation(action)||isNarrowSubagentTerminalCapture(area,action)||isNarrowRunFinish(area,action)){return runV2CommandUnlocked(area,action,parsed,filesystem,layout)}return withLifecycleCanonicalMutationLock(filesystem,()=>runV2CommandUnlocked(area,action,parsed,filesystem,layout))}async function runV2CommandUnlocked(area,action,parsed,filesystem,layout){const composition=createV2Composition(filesystem,layout);if(action==="list"&&parsed.options.view!=="full"){return manifestList(area==="run-v2"?"run":area,parsed,filesystem)}const lifecycle=new LifecycleV2Gate(filesystem,layout,composition);let result2;let manifestSyncedDuringMutation=false;if(area==="plan")return runPlanV2Command(action,parsed,filesystem,layout);if(area==="developer")return runDeveloperIdentityCommand(action,parsed,filesystem);if(area==="prd")result2=await runDefinitionLifecycleCommand(area,action,parsed,filesystem,composition,lifecycle);else if(area==="spec")result2=await runDefinitionLifecycleCommand(area,action,parsed,filesystem,composition,lifecycle);else if(area==="change")result2=await runChangeV2Command(action,parsed,composition,lifecycle);if(area==="conversation"){result2=await runConversationV2Command(action,parsed,composition,filesystem,lifecycle)}else if(area==="subagent"){result2=await runSubagentV2Command(action,parsed,composition,filesystem,lifecycle,async captured=>{await syncLifecycleManifestResult(captured,"subagent",parsed,composition,filesystem);manifestSyncedDuringMutation=true})}else if(area==="task"){result2=await runLifecycleV2Command(area,action,parsed,filesystem,composition,lifecycle)}else if(area==="execution")result2=await runExecutionV2Command(action,parsed,composition,lifecycle,async(id,options)=>runAutonomousExecutionCommand(id,options,composition,layout.projectConfig?.execution?.runtime==="autonomous"&&layout.projectConfig!==null?createAutonomousProductionDriver(filesystem,layout.projectConfig):void 0,await loadAgentCatalog(filesystem)));else if(area==="decision")result2=await runDecisionV2Command(action,parsed,filesystem,composition);else if(area==="evidence")result2=await runEvidenceV2Command(action,parsed,filesystem,composition);else if(area==="validation")result2=await runValidationV2Command(action,parsed,filesystem,composition);else if(area==="run"||area==="run-v2"){result2=await runRunV2Command(action,parsed,composition,filesystem,lifecycle)}else if(!["prd","spec","change","task","conversation","subagent","evidence","validation"].includes(area)){throw new UsageError(`Unknown V2 command: ${area} ${action??""}`.trim())}if(isLifecycleManifestMutation(action)&&!manifestSyncedDuringMutation){await syncLifecycleManifestResult(result2,area==="run-v2"?"run":area,parsed,composition,filesystem)}return result2}function isNarrowSubagentTerminalCapture(area,action){return area==="subagent"&&action==="capture-terminal"}function isNarrowRunFinish(area,action){return(area==="run"||area==="run-v2")&&action==="finish"}async function runDefinitionLifecycleCommand(area,action,parsed,filesystem,composition,lifecycle){const definitionActions=new Set(["create","rework","prepare"]);if(!definitionActions.has(action??"")){return runLifecycleV2Command(area,action,parsed,filesystem,composition,lifecycle)}const runId=await creationRunIdForCurrentTurn(parsed,filesystem,composition);await assertActiveDefinitionRun({area,runId,filesystem,composition,reworkAuthoring:action==="rework"});return runLifecycleV2Command(area,action,parsed,filesystem,composition,lifecycle)}async function readCostCohortInput(filesystem,path){let decoded;try{decoded=JSON.parse(await filesystem.readText(path))}catch(error51){throw new UsageError(`Unable to read cost cohort input: ${error51 instanceof Error?error51.message:String(error51)}`)}try{return collectCompletedTaskCostCohortV2(parseCompletedTaskCostCohortCollectionInputV2(decoded))}catch(error51){throw new UsageError(`Invalid cost cohort input: ${error51 instanceof Error?error51.message:String(error51)}`)}}async function buildContextForCommand(filesystem,parsed,query,budget){return buildContextPack(filesystem,query,budget,contextBuildOptions(parsed))}function contextBuildOptions(parsed){const role=enumOption(parsed.options.role,CONTEXT_ROLES,"role");const phase=enumOption(parsed.options.phase,CONTEXT_PHASES,"phase");return{...role===void 0?{}:{role},...phase===void 0?{}:{phase},failClosed:true}}function enumOption(value,allowed,name){if(value===void 0)return void 0;if(allowed.includes(value))return value;throw new UsageError(`--${name} must be one of: ${allowed.join(", ")}`)}function helpText(version2){return`ZAIP-AIOS ${version2}
|
|
1612
1612
|
|
|
1613
1613
|
Usage: zaip <command> [action] [--json] [--workspace PATH]
|
|
1614
1614
|
|