@ornexus/neocortex 4.60.72 → 4.60.74
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/release-source.json +1 -1
- package/dist/sbom.cdx.json +1217 -1211
- package/install.ps1 +1 -1
- package/install.sh +1 -1
- package/package.json +2 -2
- package/packages/client/dist/commands/invoke.js +66 -66
- package/packages/client/dist/continuity/sqlite-store.d.ts +22 -1
- package/packages/client/dist/continuity/sqlite-store.js +60 -60
- package/packages/client/dist/git/epic-operational-state.d.ts +198 -0
- package/packages/client/dist/git/epic-operational-state.js +2 -0
- package/packages/client/dist/git/git-lifecycle-store.d.ts +32 -1
- package/packages/client/dist/git/git-lifecycle-store.js +9 -8
- package/packages/client/dist/migrations/epic-lifecycle-backfill.d.ts +97 -0
- package/packages/client/dist/migrations/epic-lifecycle-backfill.js +3 -0
- package/packages/client/dist/migrations/state-json.d.ts +22 -0
- package/packages/client/dist/migrations/state-json.js +4 -4
- package/packages/client/dist/runner/headless/epic-merge-candidate-qa.d.ts +1 -1
- package/packages/client/dist/runner/headless/epic-merge-candidate-qa.js +2 -2
- package/packages/client/dist/runner/headless/epic-terminal-git-cli-adapter.d.ts +2 -0
- package/packages/client/dist/runner/headless/epic-terminal-git-cli-adapter.js +10 -8
- package/packages/client/dist/runner/headless/epic-terminal-git-runner.d.ts +18 -2
- package/packages/client/dist/runner/headless/epic-terminal-git-runner.js +2 -2
- package/packages/client/dist/runner/headless/run-yolo.js +1 -1
- package/packages/client/dist/runner/headless/run-yoloop.d.ts +1 -0
- package/packages/client/dist/runner/headless/run-yoloop.js +2 -2
- package/packages/client/dist/runner/headless/types.js +2 -2
- package/packages/client/dist/state/project-state-snapshot.d.ts +8 -0
- package/packages/client/dist/state/project-state-snapshot.js +1 -1
- package/packages/client/dist/yolo/spec-envelope-collector.js +3 -3
- package/packages/client/dist/yoloop/shared-yoloop-types.d.ts +65 -1
- package/packages/client/dist/yoloop/yoloop-client-state-store.d.ts +8 -0
- package/packages/client/dist/yoloop/yoloop-client-state-store.js +1 -1
- package/packages/shared/dist/yolo/change-evidence.js +1 -1
- package/packages/shared/dist/yolo/spec-envelope.js +3 -6
- package/packages/shared/dist/yoloop/epic-terminal-git.js +144 -2
- package/targets-stubs/antigravity/gemini.md +1 -1
- package/targets-stubs/antigravity/skill/SKILL.md +1 -1
- package/targets-stubs/claude-code/neocortex-root.agent.yaml +1 -1
- package/targets-stubs/claude-code/neocortex-root.md +2 -2
- package/targets-stubs/claude-code/neocortex.agent.yaml +1 -1
- package/targets-stubs/claude-code/neocortex.md +2 -2
- package/targets-stubs/codex/AGENTS.md +1 -1
- package/targets-stubs/cursor/agent.md +2 -2
- package/targets-stubs/gemini-cli/agent.md +2 -2
- package/targets-stubs/opencode/neocortex-root.md +1 -1
- package/targets-stubs/vscode/neocortex.agent.md +2 -2
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import{Buffer as J}from"node:buffer";import{createHash as M}from"node:crypto";import{chmodSync as z,closeSync as ge,existsSync as te,mkdirSync as ae,openSync as Ae,readSync as xe}from"node:fs";import{dirname as re,join as se}from"node:path";import{INITIAL_CONTINUITY_SQLITE_MIGRATION as Re}from"./migrations/001-initial-schema.js";import{PROCESSING_OUTPUT_SUMMARY_SQLITE_MIGRATION as Oe}from"./migrations/002-processing-output-summary-indexes.js";import{HEADLESS_EXECUTION_ATTEMPTS_SQLITE_MIGRATION as Ne}from"./migrations/003-headless-execution-attempts.js";import{OUTBOX_DELIVERY_STATE_SQLITE_MIGRATION as Te}from"./migrations/004-outbox-delivery-state.js";import{BOUNDED_HEADLESS_QUEUE_SQLITE_MIGRATION as Le}from"./migrations/005-bounded-headless-queue.js";import{NATIVE_AGENT_DISPATCHES_SQLITE_MIGRATION as ve}from"./migrations/006-native-agent-dispatches.js";import{NATIVE_AGENT_TERMINAL_STATES as oe,isNativeAgentDispatchReceiptV1 as X,isNativeAgentStateTransitionAllowed as je,isNativeDispatchBindingV1 as Me,isNativeHostAttestationV1 as ke}from"./native-agent-types.js";import{CONTINUITY_QUEUE_REASON_CODES as k,CONTINUITY_RECEIPT_COMPACTION_EVENT_TYPE as W,CONTINUITY_RECEIPT_RETENTION_REASON_CODES as F,DEFAULT_CONTINUITY_QUEUE_POLICY as De,computeContinuityQueueRetryAt as Ue,computeContinuityOutboxFailureDecision as we,normalizeContinuityQueuePolicy as B,normalizeContinuityQueuePriority as qe,normalizeContinuityQueueScope as Pe,normalizeContinuityRetentionPolicy as He}from"./outbox.js";const ne=".neocortex/continuity",We="continuity.sqlite",kt=6,Fe=5e3,O="processing_output_summary",Be=2e3,de=20,$e=100,ie="Install the optional Enterprise continuity SQLite adapter with `npm install --workspace packages/client better-sqlite3 --include=optional` or reinstall Neocortex with optional dependencies enabled.",Ye=Object.freeze(["discover_more","create_epic","run_yoloop","run_yolo","run_verifier","run_review_gate","compact_context","wait_external","backoff","waiting_human","complete","abort","scheduled","running","overlap_skipped","missed_run_catchup","completed","aborted","cancelled","blocked","draft","planned"]),ce=20,Ke=new Set(Ye),Ve=/^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}(?::\d{2}(?:\.\d{1,6})?)?(?:Z|[+-]\d{2}:?\d{2})?$/;function le(a){return typeof a=="string"&&Ke.has(a)}function ue(a){if(typeof a!="string")return;const e=a.trim();if(!(e.length===0||e.length>40)&&Ve.test(e))return e}function Ge(a){if(!Array.isArray(a))return[];const e=[];for(const t of a){if(!E(t)||!le(t.stage))continue;const r=ue(t.at);r&&e.push({stage:t.stage,at:r})}return e.slice(-ce)}function Qe(a){if(!(typeof a!="number"||!Number.isFinite(a)||a<0))return Math.floor(a)}class i extends Error{code;reasonCode;guidance;mutationBlocked;cause;constructor(e,t,r={}){super(t),this.name="ContinuitySqliteStoreError",this.code=e,this.reasonCode=e,this.guidance=r.guidance,this.cause=r.cause,this.mutationBlocked=r.mutationBlocked??e==="sqlite-integrity-failed"}}function $(a){const e=Object.freeze({schemaVersion:1,storyId:a.story_id,graphRevision:a.graph_revision,dispatchKey:a.dispatch_key,profile:a.profile,parentHandle:a.parent_handle,handle:a.handle,topology:a.topology,state:a.state,requestedAt:a.requested_at,observedAt:a.observed_at,terminalAt:a.terminal_at,freshness:a.freshness,observationSource:a.observation_source,reasonCode:a.reason_code,revision:a.revision,publicSafe:!0});if(!X(e))throw new i("sqlite-integrity-failed","Native-agent receipt failed its closed public contract.",{mutationBlocked:!0});return e}const Je=[Re,Oe,Ne,Te,Le,ve],ze=Object.freeze(["continuity_migrations","jobs","job_leases","job_events","job_receipts","goal_campaigns","goal_ledger_items","goal_verifiers","goal_review_gates","loop_jobs","artifacts","state_snapshots","headless_execution_attempts","runner_config","outbox","native_agent_dispatches","native_agent_observations"]),_e=/(raw[_-]?(?:logs?|payloads?)|std(?:out|err)|stack(?:[_-]?trace)?|transcript|objective(?:[_-]?(?:text|body|prompt))|prompt(?:[_-]?(?:body|text))?|private[_-]?(?:urls?|prompts?)|secret|token|password|protected(?:[_-]?(?:field|body|bodies|internals))?|workflow(?:[_-]?body)?|step(?:[_-]?body)?|customer(?:[_-]?(?:pii|data))?|\bpii\b|authorization|api[_-]?key|license[_-]?key|argv|args|executable(?:[_-]?path)?|binary(?:[_-]?path)?|shell|cwd|command[_-]?path|vendor(?:[_-]?(?:payload|corpus|response|output)))/i,me=/(https?:\/\/\S+|(?:^|\s)(?:\/(?:home|Users|media|mnt|tmp|var|etc|private)\/\S+|[A-Za-z]:\\\S+)|ghp_[A-Za-z0-9_]+|sk-[A-Za-z0-9_-]+|-----BEGIN [A-Z ]*PRIVATE KEY-----|authorization\s*:|password\s*=|token\s*=|api[_-]?key\s*=|license[_-]?key\s*=|raw[_ -]?(?:logs?|outputs?)\s*[:=]|transcript|stack\s*trace|stderr:|stdout:|system prompt|prompt[_ -]?(?:body|text)|workflow body|step body|\bargv\b|(?:bash|sh|zsh|powershell|pwsh)\s+-c\b|(?:\.{0,2}\/|[A-Za-z]:\\|\/)[^\s]*(?:\.exe|\.bat|\.cmd|\.ps1|\.sh|\/bin\/[^\s]+)|\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b|PROTECTED_|PRIVATE_INTERNALS|CUSTOMER_PII|\bPII\b|VENDOR_CORPUS|P180[_-]?SYNTHETIC[_-]?CONTINUITY|P185[_-]?SYNTHETIC[_-]?CONTINUITY|P187[_-]?SYNTHETIC[_-]?(?:CONTINUITY|RUNNER|WATCH)|P190[_-]?SYNTHETIC[_-]?(?:HEADLESS|CONTINUITY)|P192[_-]?SYNTHETIC[_-]?(?:PORTAL|RUNNER|SYNC))/i,Xe=new Set(["unsafe_key","raw_log","prompt_body","private_url","local_absolute_path","secret","protected_field","unbounded_text","unbounded_number","unknown_required_operation","missing"]),Ze=/(corrupt|malformed|not a database|file is not a database|database disk image is malformed)/i,et=/(foreign key constraint failed|SQLITE_CONSTRAINT_FOREIGNKEY)/i,Z="p185:v1:",tt=new Set(["schemaVersion","contractVersion","eventType","executionId","jobId","operationId","idempotencyKey","goalId","loopId","campaignId","itemId","ledgerItemIds","verifierId","verifierIds","gateId","reviewGateIds","runnerId","leaseId","status","reasonCode","reasonCodes","runtimeId","modelId","runtimeSource","headlessRuntime","headlessModel","headlessRuntimeReasonCode","originRuntime","originModel","targetRef","attemptId","attemptStatus","terminalClass","releaseBlocked","directiveHash","timeoutMs","leaseExpiresAt","heartbeatAt","notBeforeAt","maxAttempts","counts","hashes","relativePaths","artifactRefs","evidenceRefs","validationRefs","registryRefs","storyIds","epicIds","debtIds","iteration","currentStage","stageHistory","durationMs","retryCount","attemptCount","queuePriority","queueScope","queueCap","queueDepth","queueAvailable","queueBackpressure","nextTickAt","nextAttemptAt","nextRetryAt","deadLetterReasonCode","deliveryCursor","lastAttemptAt","sentAt","ackedAt","lastErrorReason","lastErrorSummary","deadLetterSummary","deadLetteredAt","processingOutputSource","publicSummary","redactionEvidence","selectorKind","targetId","targetJobId","relatedJobIds","serverAccessToLocalhost","serverHeldStream","initialCursor","targetResolutionState","targetKind","relatedJobCount","snapshotStatus","snapshotGeneratedAt","renderedSummaryCount","cursorState","currentCursor","nextCursor","cursorAdvanced","eventId","latestEventId","watchStatus","stopReason","syncVersion","transportKind","envelopeId","workspaceId","workspaceLabel","projectId","projectLabel","snapshotId","syncCursor","previousSyncCursor","nextSyncCursor","commandId","receiptId","acknowledgedAt","observedAt","generatedAt","syncStatus","commandStatus","receiptStatus","actorType","actorId","tenantId","commandKind","auditStatus","redactionCount","autonomousGovernance","governanceVersion","governanceEvidence","governanceSource","publicSafe"]),at=new Set(["foreground_invoke","scheduled_tick","runner_tick","manual_tick","headless_execution","jobs_command","invoke_watch","portal_render"]);function rt(a){return import(a)}function st(a){return`sha256:${M("sha256").update(a).digest("hex")}`}function E(a){return typeof a=="object"&&a!==null&&!Array.isArray(a)}function ot(a){return a instanceof Error?a.message:String(a)}function nt(a){return E(a)&&typeof a.code=="string"?a.code:void 0}function m(a,e){if(a instanceof i)return a;const t=ot(a),r=nt(a);return r==="SQLITE_CORRUPT"||r==="SQLITE_NOTADB"||Ze.test(t)?new i("sqlite-integrity-failed","Continuity SQLite integrity check failed; durable mutation is blocked until the store is repaired or rebuilt.",{cause:a,mutationBlocked:!0}):r==="SQLITE_CONSTRAINT_FOREIGNKEY"||et.test(t)?new i("sqlite-foreign-key-failed","Continuity SQLite foreign-key validation failed; mutation was rejected.",{cause:a}):new i(e,t,{cause:a})}function g(a,e){if(typeof a=="string"){if(/\.(?:redactionEvidence|redactionSummary)\[\d+\]\.field$/.test(e)&&/^[A-Za-z0-9_.:[\]-]{1,120}$/.test(a)||/\.(?:redactionEvidence|redactionSummary)\[\d+\]\.reason$/.test(e)&&Xe.has(a))return;if(me.test(a))throw new i("sqlite-public-safety-rejected",`Continuity SQLite metadata rejected unsafe value at ${e}.`);return}if(!(a===null||typeof a=="number"||typeof a=="boolean")){if(Array.isArray(a)){a.forEach((t,r)=>g(t,`${e}[${r}]`));return}if(E(a)){for(const[t,r]of Object.entries(a)){const s=t==="terminationToken"&&e.endsWith(".releaseBlocked")&&r==="[YOLOOP_RELEASE_BLOCKED]";if(_e.test(t)&&!s)throw new i("sqlite-public-safety-rejected",`Continuity SQLite metadata rejected unsafe key at ${e}.${t}.`);g(r,`${e}.${t}`)}return}throw new i("sqlite-public-safety-rejected",`Continuity SQLite metadata rejected unsupported value at ${e}.`)}}function b(a,e){if(a!==void 0&&me.test(a))throw new i("sqlite-public-safety-rejected",`Continuity SQLite text rejected unsafe value at ${e}.`)}function Y(a,e,t=240){if(a.trim().length===0)throw new i("sqlite-public-safety-rejected",`Continuity SQLite processing summary text is required at ${e}.`);if(b(a,e),a.length>t)throw new i("sqlite-public-safety-rejected",`Continuity SQLite processing summary text exceeded the public bound at ${e}.`)}function K(a){const e={};if(!a)return e;for(const[t,r]of Object.entries(a))if(tt.has(t)&&!_e.test(t))try{g(r,`metadata.${t}`),e[t]=r}catch{}return e}function dt(a){const e={...K(a.metadata),schemaVersion:1,contractVersion:"continuity-v1",eventType:O,executionId:a.executionId,jobId:a.jobId,operationId:a.executionId,publicSummary:a.publicSummary};return a.idempotencyKey&&(e.idempotencyKey=a.idempotencyKey),a.goalId&&(e.goalId=a.goalId),a.loopId&&(e.loopId=a.loopId),a.reasonCode&&(e.reasonCode=a.reasonCode),a.source&&at.has(a.source)&&(e.processingOutputSource=a.source),K(e)}function ye(a){const e=Math.floor(a??de);return Number.isFinite(e)?Math.max(1,Math.min($e,e)):de}function it(a){if(a.eventId&&a.eventId.trim().length>0)return a.eventId;const e=a.executionId.replace(/[^a-z0-9_.:-]+/gi,"-").replace(/^-+|-+$/g,"");return e.length>0?`event-processing-summary-${e.slice(0,160)}`:`event-processing-summary-${M("sha256").update(a.executionId).digest("hex").slice(0,32)}`}function ct(a){return`${Z}${J.from(JSON.stringify([a.created_at,a.event_id]),"utf8").toString("base64url")}`}function lt(a){if(a?.startsWith(Z))try{const e=a.slice(Z.length),t=JSON.parse(J.from(e,"base64url").toString("utf8"));if(!Array.isArray(t)||t.length!==2)return;const[r,s]=t;return typeof r!="string"||typeof s!="string"?void 0:{createdAt:r,eventId:s}}catch{return}}function D(a,e){if(!e)return;const t=e.trim().replace(/^@/,"");if(a==="job"&&/^job-J\d{3,}$/i.test(t))return`job-J${t.match(/\d+$/)?.[0]??""}`;if(a==="goal"&&/^goal-G\d{3,}$/i.test(t))return`goal-G${t.match(/\d+$/)?.[0]??""}`;if(a==="loop"&&/^loop-L\d{3,}$/i.test(t))return`loop-L${t.match(/\d+$/)?.[0]??""}`}function he(a){return a?q(a.map(e=>D("job",e)).filter(e=>!!e)):[]}function pe(a){const e=a.target;if(!e){const r=D("job",a.jobId);return r?{sql:" AND job_id = ?",params:[r]}:{sql:"",params:[]}}const t=e.selectorKind;if(t==="job"){const r=D("job",e.jobId??e.targetId??a.jobId);return r?{sql:" AND job_id = ?",params:[r]}:{sql:" AND 1 = 0",params:[]}}if(t==="goal"){const r=D("goal",e.goalId??e.targetId);if(!r)return{sql:" AND 1 = 0",params:[]};const s=he(e.relatedJobIds);return{sql:` AND (job_id = ? OR json_extract(metadata_json, '$.goalId') = ?${s.length>0?` OR job_id IN (${s.map(()=>"?").join(", ")})`:""})`,params:[r,r,...s]}}if(t==="loop"){const r=D("loop",e.loopId??e.targetId);if(!r)return{sql:" AND 1 = 0",params:[]};const s=he(e.relatedJobIds);return{sql:` AND (job_id = ? OR json_extract(metadata_json, '$.loopId') = ?${s.length>0?` OR job_id IN (${s.map(()=>"?").join(", ")})`:""})`,params:[r,r,...s]}}return{sql:" AND 1 = 0",params:[]}}function be(a){const e={event_id:a.event_id,job_id:a.job_id,execution_id:a.operation_id,public_summary:a.summary,reason_code:a.reason_code,created_at:a.created_at,metadata_json:a.metadata_json};return{...e,cursor:ct(e)}}function S(a){return a?(g(a,"metadata"),JSON.stringify(a)):null}function ut(a,e,t){const r=d=>`sha256:${M("sha256").update(d.map(o=>[o.id,o.status,o.reasonCode].join(":")).sort().join(`
|
|
2
|
-
`)).digest("hex")}`,s=r(e),n=r(t);return{receipts:s,outputs:n,aggregate:`sha256:${M("sha256").update(`${a}:${s}:${n}`).digest("hex")}`}}function _t(a){if(!a)return{};try{const e=JSON.parse(a);return E(e)?{...e}:{}}catch{return{}}}function c(a,e,t,r=!1){if(a===void 0){if(r)throw new i("sqlite-public-safety-rejected",`Continuity SQLite text is required at ${e}.`);return}if(b(a,e),a.trim().length===0||a.length>t)throw new i("sqlite-public-safety-rejected",`Continuity SQLite text exceeded the public bound at ${e}.`)}function N(a,e){if(a!==void 0&&(!Number.isFinite(a)||a<0||Math.floor(a)!==a))throw new i("sqlite-public-safety-rejected",`Continuity SQLite numeric value rejected at ${e}.`)}function v(a){c(a.outboxId,"outbox.outboxId",160,!0),c(a.jobId,"outbox.jobId",160),c(a.operationId,"outbox.operationId",160),c(a.idempotencyKey,"outbox.idempotencyKey",160),c(a.type,"outbox.type",80),c(a.status,"outbox.status",40),c(a.deliveryCursor,"outbox.deliveryCursor",200),c(a.timestamp,"outbox.timestamp",80),c(a.reasonCode,"outbox.reasonCode",100),c(a.summary,"outbox.summary",240)}function Ie(a){return a==="pending"||a==="sent"||a==="acked"||a==="failed"||a==="dead_letter"}function mt(a){return typeof a=="string"&&Ie(a)?a:"failed"}function h(a){return typeof a=="string"&&a.length>0?a:void 0}function yt(a){if(typeof a!="string"||a.trim().length===0)return{};try{const e=JSON.parse(a);return E(e)?(g(e,"outbox.payload"),e):{}}catch{return{}}}function ht(a){return{outboxId:String(a.outbox_id??""),...h(a.job_id)?{jobId:h(a.job_id)}:{},operationId:String(a.operation_id??""),...h(a.idempotency_key)?{idempotencyKey:h(a.idempotency_key)}:{},type:String(a.type??""),status:mt(a.status),payload:yt(a.payload_json),retryCount:typeof a.retry_count=="number"?a.retry_count:0,attemptCount:typeof a.attempt_count=="number"?a.attempt_count:0,...h(a.delivery_cursor)?{deliveryCursor:h(a.delivery_cursor)}:{},...h(a.next_attempt_at)?{nextAttemptAt:h(a.next_attempt_at)}:{},...h(a.last_attempt_at)?{lastAttemptAt:h(a.last_attempt_at)}:{},...h(a.sent_at)?{sentAt:h(a.sent_at)}:{},...h(a.acked_at)?{ackedAt:h(a.acked_at)}:{},...h(a.last_error_code)?{lastErrorCode:h(a.last_error_code)}:{},...h(a.last_error_reason)?{lastErrorReason:h(a.last_error_reason)}:{},...h(a.last_error_summary)?{lastErrorSummary:h(a.last_error_summary)}:{},...h(a.dead_letter_summary)?{deadLetterSummary:h(a.dead_letter_summary)}:{},...h(a.dead_lettered_at)?{deadLetteredAt:h(a.dead_lettered_at)}:{},createdAt:String(a.created_at??""),updatedAt:String(a.updated_at??""),publicSafe:!0}}function C(a){return{...a,publicSafe:!0}}function T(a,e){return a===void 0?null:(g(a,e),JSON.stringify(a))}function U(a){if(!a)return;const e=q(a.map(t=>t.replace(/\\/g,"/"))).filter(t=>t.length>0).slice(0,50);for(const[t,r]of e.entries()){c(r,`relativePaths[${t}]`,240,!0);const s=r.split("/").filter(Boolean);if(r.startsWith("/")||r.startsWith("~")||r.includes("://")||/^[A-Za-z]:\//.test(r)||s.includes(".."))throw new i("sqlite-public-safety-rejected",`Continuity SQLite rejected non-relative path at relativePaths[${t}].`)}return e}function V(a){const e={...K(a.metadata),schemaVersion:1,contractVersion:"continuity-v1",attemptId:a.attemptId,executionId:a.executionId,jobId:a.jobId};return a.directiveHash&&(e.directiveHash=a.directiveHash),a.runtimeId&&(e.runtimeId=a.runtimeId),a.modelId&&(e.modelId=a.modelId),a.runtimeSource&&(e.runtimeSource=a.runtimeSource),a.status&&(e.attemptStatus=a.status),a.reasonCode&&(e.reasonCode=a.reasonCode),a.durationMs!==void 0&&(e.durationMs=a.durationMs),a.retryCount!==void 0&&(e.retryCount=a.retryCount),a.attemptCount!==void 0&&(e.attemptCount=a.attemptCount),a.maxAttempts!==void 0&&(e.maxAttempts=a.maxAttempts),a.queuePriority!==void 0&&(e.queuePriority=a.queuePriority),a.queueScope&&(e.queueScope=a.queueScope),a.nextRetryAt&&(e.nextRetryAt=a.nextRetryAt),a.deadLetterReasonCode&&(e.deadLetterReasonCode=a.deadLetterReasonCode),a.counts&&(e.counts=a.counts),a.hashes&&(e.hashes=a.hashes),a.redactionSummary&&(e.redactionEvidence=a.redactionSummary),a.relativePaths&&(e.relativePaths=U(a.relativePaths)),K(e)}function L(a){c(a.attemptId,"headless_execution.attemptId",160,!0),c(a.executionId,"headless_execution.executionId",160,!0),c(a.jobId,"headless_execution.jobId",160,!0),c(a.directiveHash,"headless_execution.directiveHash",160),c(a.targetRef,"headless_execution.targetRef",240),c(a.storyId,"headless_execution.storyId",120),c(a.epicId,"headless_execution.epicId",120),c(a.runtimeId,"headless_execution.runtimeId",80),c(a.modelId,"headless_execution.modelId",120),c(a.runtimeSource,"headless_execution.runtimeSource",40),c(a.reasonCode,"headless_execution.reasonCode",100),c(a.publicSummary,"headless_execution.publicSummary",240),c(a.leaseId,"headless_execution.leaseId",160),c(a.runnerId,"headless_execution.runnerId",160),c(a.timestamp,"headless_execution.timestamp",80)}function w(a){if(Array.isArray(a)){const e=a[0];return E(e)?Object.values(e)[0]:e}return E(a)?Object.values(a)[0]:a}function pt(a){return ze.includes(a)}function q(a){return Array.from(new Set(a))}function bt(a){const e=E(a)&&"default"in a?a.default:a;if(typeof e!="function")throw new i("sqlite-adapter-unavailable","Optional better-sqlite3 adapter did not export a database constructor.",{guidance:ie});const t=e;return{adapterName:"better-sqlite3",open(r,s){return new t(r,s)}}}async function It(a=rt){try{const e=await a("better-sqlite3");return{ok:!0,adapter:bt(e)}}catch(e){return e instanceof i?{ok:!1,error:e}:{ok:!1,error:new i("sqlite-adapter-unavailable","Optional Enterprise continuity SQLite adapter better-sqlite3 is unavailable.",{cause:e,guidance:ie})}}}function Ee(a){return se(a,ne,We)}function Et(a){const e=se(a,ne);ae(e,{recursive:!0,mode:448});try{z(e,448)}catch{}return e}async function Dt(a){const e=a.adapter??await Ce(a.adapterLoader),t=a.filePath??Ee(a.projectRoot);if(a.strictReadOnly)fe(t);else if(a.filePath){ae(re(t),{recursive:!0,mode:448});try{z(re(t),448)}catch{}}else Et(a.projectRoot);let r;try{r=e.open(t,a.strictReadOnly?{fileMustExist:!0,readonly:!0}:void 0)}catch(n){throw m(n,"sqlite-integrity-failed")}const s=new ft({db:r,filePath:t,adapterName:e.adapterName,busyTimeoutMs:a.busyTimeoutMs??Fe,integrityCheck:a.integrityCheck??!0,now:a.now??(()=>new Date().toISOString())});try{if(a.strictReadOnly)return s.runIntegrityCheck(),s.getSchemaVersion(),s;if(s.initialize(),te(t))try{z(t,384)}catch{}return s}catch(n){try{r.close()}catch{}throw n}}function fe(a){if(!te(a))throw new i("sqlite-integrity-failed","Continuity database is unavailable for physical read-only inspection.",{mutationBlocked:!0});let e;try{const t=Ae(a,"r");try{if(e=J.alloc(20),xe(t,e,0,e.length,0)<e.length)throw new Error("short-header")}finally{ge(t)}}catch(t){throw new i("sqlite-integrity-failed","Continuity database header could not be inspected read-only.",{cause:t,mutationBlocked:!0})}if(e.subarray(0,16).toString("ascii")!=="SQLite format 3\0"||e[18]===2||e[19]===2)throw new i("sqlite-integrity-failed","Continuity database requires an unsafe WAL read profile.",{mutationBlocked:!0})}async function Ut(a){const e=Ee(a.projectRoot);fe(e);const t=a.adapter??await Ce(a.adapterLoader);let r;try{r=t.open(e,{fileMustExist:!0,readonly:!0});const n=w(r.pragma("integrity_check",{simple:!0}));if(String(n).toLowerCase()!=="ok")throw new Error("integrity")}catch(n){throw new i("sqlite-integrity-failed","Continuity database failed physical read-only inspection.",{cause:n,mutationBlocked:!0})}const s=n=>{const d=n.trim().replace(/^\(+/u,"").toLowerCase();if(!/^(select|with\s)/u.test(d)||/\b(insert|update|delete|replace|create|alter|drop|pragma|attach|detach|vacuum|reindex)\b/u.test(d))throw new i("sqlite-mutation-blocked","Statement is not in the physical read-only query profile.",{mutationBlocked:!0})};return Object.freeze({filePath:e,adapterName:t.adapterName,all(n,...d){return s(n),r.prepare(n).all(...d)},get(n,...d){return s(n),r.prepare(n).get(...d)},close(){r.close()}})}async function Ce(a){const e=a?await a():await It();if(!e.ok)throw e.error;return e.adapter}class ft{filePath;adapterName;db;busyTimeoutMs;integrityCheck;now;mutationBlocked=!1;constructor(e){this.db=e.db,this.filePath=e.filePath,this.adapterName=e.adapterName,this.busyTimeoutMs=e.busyTimeoutMs,this.integrityCheck=e.integrityCheck,this.now=e.now}initialize(){try{this.configureConnection(),this.integrityCheck&&this.runIntegrityCheck(),this.ensureMigrationTable(),this.applyMigrations(),this.integrityCheck&&this.runIntegrityCheck()}catch(e){throw m(e,"sqlite-migration-failed")}}close(){this.db.close()}pragmaValue(e){return w(this.db.pragma(e,{simple:!0}))}runIntegrityCheck(){try{if(String(w(this.db.pragma("integrity_check",{simple:!0}))??"").toLowerCase()!=="ok")throw this.mutationBlocked=!0,new i("sqlite-integrity-failed","Continuity SQLite integrity check failed; durable mutation is blocked until the store is repaired or rebuilt.",{mutationBlocked:!0})}catch(e){throw this.mutationBlocked=!0,m(e,"sqlite-integrity-failed")}}getSchemaVersion(){const e=this.db.prepare("SELECT COALESCE(MAX(version), 0) AS version FROM continuity_migrations").get();return E(e)&&typeof e.version=="number"?e.version:0}countRows(e){if(!pt(e))throw new i("sqlite-public-safety-rejected","Unknown continuity table name.");const t=this.db.prepare(`SELECT COUNT(*) AS count FROM ${e}`).get();return E(t)&&typeof t.count=="number"?t.count:0}reserveNativeAgentDispatch(e){if(this.assertCanMutate(),!Me(e.binding)||!ke(e.hostAttestation))throw new i("sqlite-public-safety-rejected","Native-agent reservation rejected invalid binding or host evidence.");const t={schemaVersion:1,storyId:e.binding.storyId,graphRevision:e.binding.graphRevision.replace(/^sha256:/,"").toLowerCase(),dispatchKey:e.binding.dispatchKey.toLowerCase(),profile:"neocortex",parentHandle:null,handle:null,topology:e.topology??"native-agent",state:"requested",requestedAt:e.requestedAt,observedAt:null,terminalAt:null,freshness:"unknown",observationSource:"local-reservation",reasonCode:e.reasonCode??"native-agent-dispatch-reserved",revision:0,publicSafe:!0};if(!X(t))throw new i("sqlite-public-safety-rejected","Native-agent reservation rejected unsafe public fields.");try{return this.runInTransaction(()=>{const r=this.db.prepare(`
|
|
1
|
+
import{Buffer as J}from"node:buffer";import{createHash as M}from"node:crypto";import{chmodSync as z,closeSync as ge,existsSync as te,mkdirSync as ae,openSync as Ae,readSync as xe}from"node:fs";import{dirname as re,join as se}from"node:path";import{INITIAL_CONTINUITY_SQLITE_MIGRATION as Re}from"./migrations/001-initial-schema.js";import{PROCESSING_OUTPUT_SUMMARY_SQLITE_MIGRATION as Oe}from"./migrations/002-processing-output-summary-indexes.js";import{HEADLESS_EXECUTION_ATTEMPTS_SQLITE_MIGRATION as Ne}from"./migrations/003-headless-execution-attempts.js";import{OUTBOX_DELIVERY_STATE_SQLITE_MIGRATION as Te}from"./migrations/004-outbox-delivery-state.js";import{BOUNDED_HEADLESS_QUEUE_SQLITE_MIGRATION as Le}from"./migrations/005-bounded-headless-queue.js";import{NATIVE_AGENT_DISPATCHES_SQLITE_MIGRATION as ve}from"./migrations/006-native-agent-dispatches.js";import{NATIVE_AGENT_TERMINAL_STATES as oe,isNativeAgentDispatchReceiptV1 as X,isNativeAgentStateTransitionAllowed as je,isNativeDispatchBindingV1 as Me,isNativeHostAttestationV1 as ke}from"./native-agent-types.js";import{CONTINUITY_QUEUE_REASON_CODES as k,CONTINUITY_RECEIPT_COMPACTION_EVENT_TYPE as W,CONTINUITY_RECEIPT_RETENTION_REASON_CODES as F,DEFAULT_CONTINUITY_QUEUE_POLICY as De,computeContinuityQueueRetryAt as we,computeContinuityOutboxFailureDecision as Ue,normalizeContinuityQueuePolicy as B,normalizeContinuityQueuePriority as qe,normalizeContinuityQueueScope as Pe,normalizeContinuityRetentionPolicy as He}from"./outbox.js";const ne=".neocortex/continuity",We="continuity.sqlite",Dt=6,Fe=5e3,O="processing_output_summary",Be=2e3,de=20,$e=100,ie="Install the optional Enterprise continuity SQLite adapter with `npm install --workspace packages/client better-sqlite3 --include=optional` or reinstall Neocortex with optional dependencies enabled.",Ye=Object.freeze(["discover_more","create_epic","run_yoloop","run_yolo","run_verifier","run_review_gate","compact_context","wait_external","backoff","waiting_human","complete","abort","scheduled","running","overlap_skipped","missed_run_catchup","completed","aborted","cancelled","blocked","draft","planned"]),ce=20,Ke=new Set(Ye),Ve=/^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}(?::\d{2}(?:\.\d{1,6})?)?(?:Z|[+-]\d{2}:?\d{2})?$/;function le(t){return typeof t=="string"&&Ke.has(t)}function ue(t){if(typeof t!="string")return;const e=t.trim();if(!(e.length===0||e.length>40)&&Ve.test(e))return e}function Qe(t){if(!Array.isArray(t))return[];const e=[];for(const a of t){if(!E(a)||!le(a.stage))continue;const r=ue(a.at);r&&e.push({stage:a.stage,at:r})}return e.slice(-ce)}function Ge(t){if(!(typeof t!="number"||!Number.isFinite(t)||t<0))return Math.floor(t)}class i extends Error{code;reasonCode;guidance;mutationBlocked;cause;constructor(e,a,r={}){super(a),this.name="ContinuitySqliteStoreError",this.code=e,this.reasonCode=e,this.guidance=r.guidance,this.cause=r.cause,this.mutationBlocked=r.mutationBlocked??e==="sqlite-integrity-failed"}}function $(t){const e=Object.freeze({schemaVersion:1,storyId:t.story_id,graphRevision:t.graph_revision,dispatchKey:t.dispatch_key,profile:t.profile,parentHandle:t.parent_handle,handle:t.handle,topology:t.topology,state:t.state,requestedAt:t.requested_at,observedAt:t.observed_at,terminalAt:t.terminal_at,freshness:t.freshness,observationSource:t.observation_source,reasonCode:t.reason_code,revision:t.revision,publicSafe:!0});if(!X(e))throw new i("sqlite-integrity-failed","Native-agent receipt failed its closed public contract.",{mutationBlocked:!0});return e}const Je=[Re,Oe,Ne,Te,Le,ve],ze=Object.freeze(["continuity_migrations","jobs","job_leases","job_events","job_receipts","goal_campaigns","goal_ledger_items","goal_verifiers","goal_review_gates","loop_jobs","artifacts","state_snapshots","headless_execution_attempts","runner_config","outbox","native_agent_dispatches","native_agent_observations"]),_e=/(raw[_-]?(?:logs?|payloads?)|std(?:out|err)|stack(?:[_-]?trace)?|transcript|objective(?:[_-]?(?:text|body|prompt))|prompt(?:[_-]?(?:body|text))?|private[_-]?(?:urls?|prompts?)|secret|token|password|protected(?:[_-]?(?:field|body|bodies|internals))?|workflow(?:[_-]?body)?|step(?:[_-]?body)?|customer(?:[_-]?(?:pii|data))?|\bpii\b|authorization|api[_-]?key|license[_-]?key|argv|args|executable(?:[_-]?path)?|binary(?:[_-]?path)?|shell|cwd|command[_-]?path|vendor(?:[_-]?(?:payload|corpus|response|output)))/i,me=/(https?:\/\/\S+|(?:^|\s)(?:\/(?:home|Users|media|mnt|tmp|var|etc|private)\/\S+|[A-Za-z]:\\\S+)|ghp_[A-Za-z0-9_]+|sk-[A-Za-z0-9_-]+|-----BEGIN [A-Z ]*PRIVATE KEY-----|authorization\s*:|password\s*=|token\s*=|api[_-]?key\s*=|license[_-]?key\s*=|raw[_ -]?(?:logs?|outputs?)\s*[:=]|transcript|stack\s*trace|stderr:|stdout:|system prompt|prompt[_ -]?(?:body|text)|workflow body|step body|\bargv\b|(?:bash|sh|zsh|powershell|pwsh)\s+-c\b|(?:\.{0,2}\/|[A-Za-z]:\\|\/)[^\s]*(?:\.exe|\.bat|\.cmd|\.ps1|\.sh|\/bin\/[^\s]+)|\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b|PROTECTED_|PRIVATE_INTERNALS|CUSTOMER_PII|\bPII\b|VENDOR_CORPUS|P180[_-]?SYNTHETIC[_-]?CONTINUITY|P185[_-]?SYNTHETIC[_-]?CONTINUITY|P187[_-]?SYNTHETIC[_-]?(?:CONTINUITY|RUNNER|WATCH)|P190[_-]?SYNTHETIC[_-]?(?:HEADLESS|CONTINUITY)|P192[_-]?SYNTHETIC[_-]?(?:PORTAL|RUNNER|SYNC))/i,Xe=new Set(["unsafe_key","raw_log","prompt_body","private_url","local_absolute_path","secret","protected_field","unbounded_text","unbounded_number","unknown_required_operation","missing"]),Ze=/(corrupt|malformed|not a database|file is not a database|database disk image is malformed)/i,et=/(foreign key constraint failed|SQLITE_CONSTRAINT_FOREIGNKEY)/i,Z="p185:v1:",tt=new Set(["schemaVersion","contractVersion","eventType","executionId","jobId","operationId","idempotencyKey","goalId","loopId","campaignId","itemId","ledgerItemIds","verifierId","verifierIds","gateId","reviewGateIds","runnerId","leaseId","status","reasonCode","reasonCodes","runtimeId","modelId","runtimeSource","headlessRuntime","headlessModel","headlessRuntimeReasonCode","originRuntime","originModel","targetRef","attemptId","attemptStatus","terminalClass","releaseBlocked","directiveHash","timeoutMs","leaseExpiresAt","heartbeatAt","notBeforeAt","maxAttempts","counts","hashes","relativePaths","artifactRefs","evidenceRefs","validationRefs","registryRefs","storyIds","epicIds","debtIds","iteration","currentStage","stageHistory","durationMs","retryCount","attemptCount","queuePriority","queueScope","queueCap","queueDepth","queueAvailable","queueBackpressure","nextTickAt","nextAttemptAt","nextRetryAt","deadLetterReasonCode","deliveryCursor","lastAttemptAt","sentAt","ackedAt","lastErrorReason","lastErrorSummary","deadLetterSummary","deadLetteredAt","processingOutputSource","publicSummary","redactionEvidence","selectorKind","targetId","targetJobId","relatedJobIds","serverAccessToLocalhost","serverHeldStream","initialCursor","targetResolutionState","targetKind","relatedJobCount","snapshotStatus","snapshotGeneratedAt","renderedSummaryCount","cursorState","currentCursor","nextCursor","cursorAdvanced","eventId","latestEventId","watchStatus","stopReason","syncVersion","transportKind","envelopeId","workspaceId","workspaceLabel","projectId","projectLabel","snapshotId","syncCursor","previousSyncCursor","nextSyncCursor","commandId","receiptId","acknowledgedAt","observedAt","generatedAt","syncStatus","commandStatus","receiptStatus","actorType","actorId","tenantId","commandKind","auditStatus","redactionCount","autonomousGovernance","governanceVersion","governanceEvidence","governanceSource","publicSafe"]),at=new Set(["foreground_invoke","scheduled_tick","runner_tick","manual_tick","headless_execution","jobs_command","invoke_watch","portal_render"]);function rt(t){return import(t)}function st(t){return`sha256:${M("sha256").update(t).digest("hex")}`}function E(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}function ot(t){return t instanceof Error?t.message:String(t)}function nt(t){return E(t)&&typeof t.code=="string"?t.code:void 0}function m(t,e){if(t instanceof i)return t;const a=ot(t),r=nt(t);return r==="SQLITE_CORRUPT"||r==="SQLITE_NOTADB"||Ze.test(a)?new i("sqlite-integrity-failed","Continuity SQLite integrity check failed; durable mutation is blocked until the store is repaired or rebuilt.",{cause:t,mutationBlocked:!0}):r==="SQLITE_CONSTRAINT_FOREIGNKEY"||et.test(a)?new i("sqlite-foreign-key-failed","Continuity SQLite foreign-key validation failed; mutation was rejected.",{cause:t}):new i(e,a,{cause:t})}function g(t,e){if(typeof t=="string"){if(/\.(?:redactionEvidence|redactionSummary)\[\d+\]\.field$/.test(e)&&/^[A-Za-z0-9_.:[\]-]{1,120}$/.test(t)||/\.(?:redactionEvidence|redactionSummary)\[\d+\]\.reason$/.test(e)&&Xe.has(t))return;if(me.test(t))throw new i("sqlite-public-safety-rejected",`Continuity SQLite metadata rejected unsafe value at ${e}.`);return}if(!(t===null||typeof t=="number"||typeof t=="boolean")){if(Array.isArray(t)){t.forEach((a,r)=>g(a,`${e}[${r}]`));return}if(E(t)){for(const[a,r]of Object.entries(t)){const s=a==="terminationToken"&&e.endsWith(".releaseBlocked")&&r==="[YOLOOP_RELEASE_BLOCKED]";if(_e.test(a)&&!s)throw new i("sqlite-public-safety-rejected",`Continuity SQLite metadata rejected unsafe key at ${e}.${a}.`);g(r,`${e}.${a}`)}return}throw new i("sqlite-public-safety-rejected",`Continuity SQLite metadata rejected unsupported value at ${e}.`)}}function b(t,e){if(t!==void 0&&me.test(t))throw new i("sqlite-public-safety-rejected",`Continuity SQLite text rejected unsafe value at ${e}.`)}function Y(t,e,a=240){if(t.trim().length===0)throw new i("sqlite-public-safety-rejected",`Continuity SQLite processing summary text is required at ${e}.`);if(b(t,e),t.length>a)throw new i("sqlite-public-safety-rejected",`Continuity SQLite processing summary text exceeded the public bound at ${e}.`)}function K(t){const e={};if(!t)return e;for(const[a,r]of Object.entries(t))if(tt.has(a)&&!_e.test(a))try{g(r,`metadata.${a}`),e[a]=r}catch{}return e}function dt(t){const e={...K(t.metadata),schemaVersion:1,contractVersion:"continuity-v1",eventType:O,executionId:t.executionId,jobId:t.jobId,operationId:t.executionId,publicSummary:t.publicSummary};return t.idempotencyKey&&(e.idempotencyKey=t.idempotencyKey),t.goalId&&(e.goalId=t.goalId),t.loopId&&(e.loopId=t.loopId),t.reasonCode&&(e.reasonCode=t.reasonCode),t.source&&at.has(t.source)&&(e.processingOutputSource=t.source),K(e)}function he(t){const e=Math.floor(t??de);return Number.isFinite(e)?Math.max(1,Math.min($e,e)):de}function it(t){if(t.eventId&&t.eventId.trim().length>0)return t.eventId;const e=t.executionId.replace(/[^a-z0-9_.:-]+/gi,"-").replace(/^-+|-+$/g,"");return e.length>0?`event-processing-summary-${e.slice(0,160)}`:`event-processing-summary-${M("sha256").update(t.executionId).digest("hex").slice(0,32)}`}function ct(t){return`${Z}${J.from(JSON.stringify([t.created_at,t.event_id]),"utf8").toString("base64url")}`}function lt(t){if(t?.startsWith(Z))try{const e=t.slice(Z.length),a=JSON.parse(J.from(e,"base64url").toString("utf8"));if(!Array.isArray(a)||a.length!==2)return;const[r,s]=a;return typeof r!="string"||typeof s!="string"?void 0:{createdAt:r,eventId:s}}catch{return}}function D(t,e){if(!e)return;const a=e.trim().replace(/^@/,"");if(t==="job"&&/^job-J\d{3,}$/i.test(a))return`job-J${a.match(/\d+$/)?.[0]??""}`;if(t==="goal"&&/^goal-G\d{3,}$/i.test(a))return`goal-G${a.match(/\d+$/)?.[0]??""}`;if(t==="loop"&&/^loop-L\d{3,}$/i.test(a))return`loop-L${a.match(/\d+$/)?.[0]??""}`}function ye(t){return t?q(t.map(e=>D("job",e)).filter(e=>!!e)):[]}function pe(t){const e=t.target;if(!e){const r=D("job",t.jobId);return r?{sql:" AND job_id = ?",params:[r]}:{sql:"",params:[]}}const a=e.selectorKind;if(a==="job"){const r=D("job",e.jobId??e.targetId??t.jobId);return r?{sql:" AND job_id = ?",params:[r]}:{sql:" AND 1 = 0",params:[]}}if(a==="goal"){const r=D("goal",e.goalId??e.targetId);if(!r)return{sql:" AND 1 = 0",params:[]};const s=ye(e.relatedJobIds);return{sql:` AND (job_id = ? OR json_extract(metadata_json, '$.goalId') = ?${s.length>0?` OR job_id IN (${s.map(()=>"?").join(", ")})`:""})`,params:[r,r,...s]}}if(a==="loop"){const r=D("loop",e.loopId??e.targetId);if(!r)return{sql:" AND 1 = 0",params:[]};const s=ye(e.relatedJobIds);return{sql:` AND (job_id = ? OR json_extract(metadata_json, '$.loopId') = ?${s.length>0?` OR job_id IN (${s.map(()=>"?").join(", ")})`:""})`,params:[r,r,...s]}}return{sql:" AND 1 = 0",params:[]}}function be(t){const e={event_id:t.event_id,job_id:t.job_id,execution_id:t.operation_id,public_summary:t.summary,reason_code:t.reason_code,created_at:t.created_at,metadata_json:t.metadata_json};return{...e,cursor:ct(e)}}function S(t){return t?(g(t,"metadata"),JSON.stringify(t)):null}function ut(t,e,a){const r=d=>`sha256:${M("sha256").update(d.map(o=>[o.id,o.status,o.reasonCode].join(":")).sort().join(`
|
|
2
|
+
`)).digest("hex")}`,s=r(e),n=r(a);return{receipts:s,outputs:n,aggregate:`sha256:${M("sha256").update(`${t}:${s}:${n}`).digest("hex")}`}}function _t(t){if(!t)return{};try{const e=JSON.parse(t);return E(e)?{...e}:{}}catch{return{}}}function c(t,e,a,r=!1){if(t===void 0){if(r)throw new i("sqlite-public-safety-rejected",`Continuity SQLite text is required at ${e}.`);return}if(b(t,e),t.trim().length===0||t.length>a)throw new i("sqlite-public-safety-rejected",`Continuity SQLite text exceeded the public bound at ${e}.`)}function N(t,e){if(t!==void 0&&(!Number.isFinite(t)||t<0||Math.floor(t)!==t))throw new i("sqlite-public-safety-rejected",`Continuity SQLite numeric value rejected at ${e}.`)}function v(t){c(t.outboxId,"outbox.outboxId",160,!0),c(t.jobId,"outbox.jobId",160),c(t.operationId,"outbox.operationId",160),c(t.idempotencyKey,"outbox.idempotencyKey",160),c(t.type,"outbox.type",80),c(t.status,"outbox.status",40),c(t.deliveryCursor,"outbox.deliveryCursor",200),c(t.timestamp,"outbox.timestamp",80),c(t.reasonCode,"outbox.reasonCode",100),c(t.summary,"outbox.summary",240)}function Ee(t){return t==="pending"||t==="sent"||t==="acked"||t==="failed"||t==="dead_letter"}function mt(t){return typeof t=="string"&&Ee(t)?t:"failed"}function y(t){return typeof t=="string"&&t.length>0?t:void 0}function ht(t){if(typeof t!="string"||t.trim().length===0)return{};try{const e=JSON.parse(t);return E(e)?(g(e,"outbox.payload"),e):{}}catch{return{}}}function yt(t){return{outboxId:String(t.outbox_id??""),...y(t.job_id)?{jobId:y(t.job_id)}:{},operationId:String(t.operation_id??""),...y(t.idempotency_key)?{idempotencyKey:y(t.idempotency_key)}:{},type:String(t.type??""),status:mt(t.status),payload:ht(t.payload_json),retryCount:typeof t.retry_count=="number"?t.retry_count:0,attemptCount:typeof t.attempt_count=="number"?t.attempt_count:0,...y(t.delivery_cursor)?{deliveryCursor:y(t.delivery_cursor)}:{},...y(t.next_attempt_at)?{nextAttemptAt:y(t.next_attempt_at)}:{},...y(t.last_attempt_at)?{lastAttemptAt:y(t.last_attempt_at)}:{},...y(t.sent_at)?{sentAt:y(t.sent_at)}:{},...y(t.acked_at)?{ackedAt:y(t.acked_at)}:{},...y(t.last_error_code)?{lastErrorCode:y(t.last_error_code)}:{},...y(t.last_error_reason)?{lastErrorReason:y(t.last_error_reason)}:{},...y(t.last_error_summary)?{lastErrorSummary:y(t.last_error_summary)}:{},...y(t.dead_letter_summary)?{deadLetterSummary:y(t.dead_letter_summary)}:{},...y(t.dead_lettered_at)?{deadLetteredAt:y(t.dead_lettered_at)}:{},createdAt:String(t.created_at??""),updatedAt:String(t.updated_at??""),publicSafe:!0}}function C(t){return{...t,publicSafe:!0}}function T(t,e){return t===void 0?null:(g(t,e),JSON.stringify(t))}function w(t){if(!t)return;const e=q(t.map(a=>a.replace(/\\/g,"/"))).filter(a=>a.length>0).slice(0,50);for(const[a,r]of e.entries()){c(r,`relativePaths[${a}]`,240,!0);const s=r.split("/").filter(Boolean);if(r.startsWith("/")||r.startsWith("~")||r.includes("://")||/^[A-Za-z]:\//.test(r)||s.includes(".."))throw new i("sqlite-public-safety-rejected",`Continuity SQLite rejected non-relative path at relativePaths[${a}].`)}return e}function V(t){const e={...K(t.metadata),schemaVersion:1,contractVersion:"continuity-v1",attemptId:t.attemptId,executionId:t.executionId,jobId:t.jobId};return t.directiveHash&&(e.directiveHash=t.directiveHash),t.runtimeId&&(e.runtimeId=t.runtimeId),t.modelId&&(e.modelId=t.modelId),t.runtimeSource&&(e.runtimeSource=t.runtimeSource),t.status&&(e.attemptStatus=t.status),t.reasonCode&&(e.reasonCode=t.reasonCode),t.durationMs!==void 0&&(e.durationMs=t.durationMs),t.retryCount!==void 0&&(e.retryCount=t.retryCount),t.attemptCount!==void 0&&(e.attemptCount=t.attemptCount),t.maxAttempts!==void 0&&(e.maxAttempts=t.maxAttempts),t.queuePriority!==void 0&&(e.queuePriority=t.queuePriority),t.queueScope&&(e.queueScope=t.queueScope),t.nextRetryAt&&(e.nextRetryAt=t.nextRetryAt),t.deadLetterReasonCode&&(e.deadLetterReasonCode=t.deadLetterReasonCode),t.counts&&(e.counts=t.counts),t.hashes&&(e.hashes=t.hashes),t.redactionSummary&&(e.redactionEvidence=t.redactionSummary),t.relativePaths&&(e.relativePaths=w(t.relativePaths)),K(e)}function L(t){c(t.attemptId,"headless_execution.attemptId",160,!0),c(t.executionId,"headless_execution.executionId",160,!0),c(t.jobId,"headless_execution.jobId",160,!0),c(t.directiveHash,"headless_execution.directiveHash",160),c(t.targetRef,"headless_execution.targetRef",240),c(t.storyId,"headless_execution.storyId",120),c(t.epicId,"headless_execution.epicId",120),c(t.runtimeId,"headless_execution.runtimeId",80),c(t.modelId,"headless_execution.modelId",120),c(t.runtimeSource,"headless_execution.runtimeSource",40),c(t.reasonCode,"headless_execution.reasonCode",100),c(t.publicSummary,"headless_execution.publicSummary",240),c(t.leaseId,"headless_execution.leaseId",160),c(t.runnerId,"headless_execution.runnerId",160),c(t.timestamp,"headless_execution.timestamp",80)}function U(t){if(Array.isArray(t)){const e=t[0];return E(e)?Object.values(e)[0]:e}return E(t)?Object.values(t)[0]:t}function pt(t){return ze.includes(t)}function q(t){return Array.from(new Set(t))}function bt(t){const e=E(t)&&"default"in t?t.default:t;if(typeof e!="function")throw new i("sqlite-adapter-unavailable","Optional better-sqlite3 adapter did not export a database constructor.",{guidance:ie});const a=e;return{adapterName:"better-sqlite3",open(r,s){return new a(r,s)}}}async function Et(t=rt){try{const e=await t("better-sqlite3");return{ok:!0,adapter:bt(e)}}catch(e){return e instanceof i?{ok:!1,error:e}:{ok:!1,error:new i("sqlite-adapter-unavailable","Optional Enterprise continuity SQLite adapter better-sqlite3 is unavailable.",{cause:e,guidance:ie})}}}function Ie(t){return se(t,ne,We)}function It(t){const e=se(t,ne);ae(e,{recursive:!0,mode:448});try{z(e,448)}catch{}return e}async function wt(t){const e=t.adapter??await Ce(t.adapterLoader),a=t.filePath??Ie(t.projectRoot);if(t.strictReadOnly)fe(a);else if(t.filePath){ae(re(a),{recursive:!0,mode:448});try{z(re(a),448)}catch{}}else It(t.projectRoot);let r;try{r=e.open(a,t.strictReadOnly?{fileMustExist:!0,readonly:!0}:void 0)}catch(n){throw m(n,"sqlite-integrity-failed")}const s=new Ct({db:r,filePath:a,adapterName:e.adapterName,busyTimeoutMs:t.busyTimeoutMs??Fe,integrityCheck:t.integrityCheck??!0,now:t.now??(()=>new Date().toISOString())});try{if(t.strictReadOnly)return s.runIntegrityCheck(),s.getSchemaVersion(),s;if(s.initialize(),te(a))try{z(a,384)}catch{}return s}catch(n){try{r.close()}catch{}throw n}}function fe(t){if(!te(t))throw new i("sqlite-projection-missing","Continuity database is unavailable for physical read-only inspection.",{mutationBlocked:!0});let e;try{const a=Ae(t,"r");try{if(e=J.alloc(20),xe(a,e,0,e.length,0)<e.length)throw new Error("short-header")}finally{ge(a)}}catch(a){throw new i("sqlite-integrity-failed","Continuity database header could not be inspected read-only.",{cause:a,mutationBlocked:!0})}if(e.subarray(0,16).toString("ascii")!=="SQLite format 3\0")throw new i("sqlite-integrity-failed","Continuity database header is not a recognized SQLite database.",{mutationBlocked:!0});if(e[18]===2||e[19]===2)throw new i("sqlite-projection-wal-unsafe","Continuity database requires an unsafe WAL read profile.",{mutationBlocked:!0})}async function ft(t){const e=Ie(t.projectRoot);fe(e);const a=t.adapter??await Ce(t.adapterLoader);let r,s=!1;try{r=a.open(e,{fileMustExist:!0,readonly:!0}),s=!0;const d=U(r.pragma("integrity_check",{simple:!0}));if(String(d).toLowerCase()!=="ok")throw new Error("integrity")}catch(d){throw new i(s?"sqlite-integrity-failed":"sqlite-projection-adapter-incompatible","Continuity database failed physical read-only inspection.",{cause:d,mutationBlocked:!0})}const n=d=>{const o=d.trim().replace(/^\(+/u,"").toLowerCase();if(!/^(select|with\s)/u.test(o)||/\b(insert|update|delete|replace|create|alter|drop|pragma|attach|detach|vacuum|reindex)\b/u.test(o))throw new i("sqlite-mutation-blocked","Statement is not in the physical read-only query profile.",{mutationBlocked:!0})};return Object.freeze({filePath:e,adapterName:a.adapterName,all(d,...o){return n(d),r.prepare(d).all(...o)},get(d,...o){return n(d),r.prepare(d).get(...o)},close(){r.close()}})}async function Ut(t){if(!Number.isSafeInteger(t.authorityRevision)||t.authorityRevision<0||!/^[a-f0-9]{64}$/.test(t.sourceDigest))throw new i("sqlite-integrity-failed","Epic operational SQLite binding input is invalid.",{mutationBlocked:!0});let e;try{e=await ft(t);let a;try{a=e.all("SELECT sha256, metadata_json FROM state_snapshots WHERE kind = ? ORDER BY captured_at DESC LIMIT 2","epic-operational-state")}catch{return Object.freeze({schemaVersion:"EpicOperationalSqliteBindingInspection/1.0",status:"unavailable",authorityRevision:t.authorityRevision,sourceDigest:null,adapterName:e.adapterName,reasonCodes:["sqlite-projection-schema-unsupported"],publicSafe:!0})}const r=a.filter(s=>{if(!E(s)||s.sha256!==t.sourceDigest||typeof s.metadata_json!="string")return!1;try{const n=JSON.parse(s.metadata_json);return E(n)&&n.authorityRevision===t.authorityRevision}catch{return!1}});return Object.freeze({schemaVersion:"EpicOperationalSqliteBindingInspection/1.0",status:r.length===1?"bound":"unbound",authorityRevision:t.authorityRevision,sourceDigest:r.length===1?t.sourceDigest:null,adapterName:e.adapterName,reasonCodes:r.length===1?["epic-operational-sqlite-binding-verified"]:["epic-operational-projection-unbound"],publicSafe:!0})}catch(a){const r=a instanceof i?a.reasonCode:"sqlite-integrity-failed";return Object.freeze({schemaVersion:"EpicOperationalSqliteBindingInspection/1.0",status:"unavailable",authorityRevision:t.authorityRevision,sourceDigest:null,adapterName:null,reasonCodes:[r],publicSafe:!0})}finally{e?.close()}}async function Ce(t){const e=t?await t():await Et();if(!e.ok)throw e.error;return e.adapter}class Ct{filePath;adapterName;db;busyTimeoutMs;integrityCheck;now;mutationBlocked=!1;constructor(e){this.db=e.db,this.filePath=e.filePath,this.adapterName=e.adapterName,this.busyTimeoutMs=e.busyTimeoutMs,this.integrityCheck=e.integrityCheck,this.now=e.now}initialize(){try{this.configureConnection(),this.integrityCheck&&this.runIntegrityCheck(),this.ensureMigrationTable(),this.applyMigrations(),this.integrityCheck&&this.runIntegrityCheck()}catch(e){throw m(e,"sqlite-migration-failed")}}close(){this.db.close()}pragmaValue(e){return U(this.db.pragma(e,{simple:!0}))}runIntegrityCheck(){try{if(String(U(this.db.pragma("integrity_check",{simple:!0}))??"").toLowerCase()!=="ok")throw this.mutationBlocked=!0,new i("sqlite-integrity-failed","Continuity SQLite integrity check failed; durable mutation is blocked until the store is repaired or rebuilt.",{mutationBlocked:!0})}catch(e){throw this.mutationBlocked=!0,m(e,"sqlite-integrity-failed")}}getSchemaVersion(){const e=this.db.prepare("SELECT COALESCE(MAX(version), 0) AS version FROM continuity_migrations").get();return E(e)&&typeof e.version=="number"?e.version:0}countRows(e){if(!pt(e))throw new i("sqlite-public-safety-rejected","Unknown continuity table name.");const a=this.db.prepare(`SELECT COUNT(*) AS count FROM ${e}`).get();return E(a)&&typeof a.count=="number"?a.count:0}reserveNativeAgentDispatch(e){if(this.assertCanMutate(),!Me(e.binding)||!ke(e.hostAttestation))throw new i("sqlite-public-safety-rejected","Native-agent reservation rejected invalid binding or host evidence.");const a={schemaVersion:1,storyId:e.binding.storyId,graphRevision:e.binding.graphRevision.replace(/^sha256:/,"").toLowerCase(),dispatchKey:e.binding.dispatchKey.toLowerCase(),profile:"neocortex",parentHandle:null,handle:null,topology:e.topology??"native-agent",state:"requested",requestedAt:e.requestedAt,observedAt:null,terminalAt:null,freshness:"unknown",observationSource:"local-reservation",reasonCode:e.reasonCode??"native-agent-dispatch-reserved",revision:0,publicSafe:!0};if(!X(a))throw new i("sqlite-public-safety-rejected","Native-agent reservation rejected unsafe public fields.");try{return this.runInTransaction(()=>{const r=this.db.prepare(`
|
|
3
3
|
INSERT OR IGNORE INTO native_agent_dispatches (
|
|
4
4
|
dispatch_key, story_id, graph_revision, profile,
|
|
5
5
|
host_kind, host_version, host_origin, host_confidence,
|
|
6
6
|
parent_handle, handle, topology, state, requested_at, observed_at,
|
|
7
7
|
terminal_at, freshness, observation_source, reason_code, revision
|
|
8
8
|
) VALUES (?, ?, ?, 'neocortex', ?, ?, ?, ?, NULL, NULL, ?, 'requested', ?, NULL, NULL, 'unknown', 'local-reservation', ?, 0)
|
|
9
|
-
`).run(
|
|
9
|
+
`).run(a.dispatchKey,a.storyId,a.graphRevision,e.hostAttestation.hostKind,e.hostAttestation.hostVersion,e.hostAttestation.origin,e.hostAttestation.confidence,a.topology,a.requestedAt,a.reasonCode),s=this.findNativeAgentDispatchRow(a.dispatchKey,a.storyId,a.graphRevision);if(!s)throw new Error("native-agent-reservation-readback-missing");if(s.dispatch_key!==a.dispatchKey||s.story_id!==a.storyId||s.graph_revision!==a.graphRevision)throw new i("sqlite-mutation-failed","Native-agent reservation conflicts with an existing story graph binding.");return Object.freeze({receipt:$(s),reserved:r.changes===1,replay:r.changes===0})})}catch(r){throw m(r,"sqlite-mutation-failed")}}observeNativeAgentDispatch(e){this.assertCanMutate();try{return this.runInTransaction(()=>{const a=this.db.prepare("SELECT * FROM native_agent_dispatches WHERE dispatch_key = ?").get(e.dispatchKey);if(!a)throw new i("sqlite-mutation-failed","Native-agent dispatch reservation is missing.");const r=$(a),s=oe.has(e.state)?e.terminalAt??e.observedAt:null,n=e.handle??r.handle,d=e.parentHandle===void 0?r.parentHandle:e.parentHandle,o={...r,handle:n,parentHandle:d,topology:e.topology,state:e.state,observedAt:e.observedAt,terminalAt:s,freshness:e.freshness,observationSource:e.observationSource,reasonCode:e.reasonCode,revision:r.revision+1};if(!X(o))throw new i("sqlite-public-safety-rejected","Native-agent observation rejected unsafe or inconsistent fields.");if(r.handle&&e.handle&&r.handle!==e.handle)throw new i("sqlite-mutation-failed","Native-agent observation handle conflicts with the reserved dispatch.");if(!je(r.state,e.state))throw new i("sqlite-mutation-failed","Native-agent observation attempted a terminal or non-monotonic regression.");if(r.state===o.state&&r.handle===o.handle&&r.parentHandle===o.parentHandle&&r.topology===o.topology&&r.observedAt===o.observedAt&&r.terminalAt===o.terminalAt&&r.freshness===o.freshness&&r.observationSource===o.observationSource&&r.reasonCode===o.reasonCode)return Object.freeze({receipt:r,applied:!1,replay:!0});if(e.expectedRevision!==r.revision)throw new i("sqlite-mutation-failed","Native-agent observation CAS revision conflict.");if(r.observedAt&&Date.parse(e.observedAt)<Date.parse(r.observedAt))throw new i("sqlite-mutation-failed","Native-agent observation timestamp regressed.");if(this.db.prepare(`
|
|
10
10
|
UPDATE native_agent_dispatches
|
|
11
11
|
SET parent_handle = ?, handle = ?, topology = ?, state = ?, observed_at = ?,
|
|
12
12
|
terminal_at = ?, freshness = ?, observation_source = ?, reason_code = ?, revision = revision + 1
|
|
@@ -16,16 +16,16 @@ import{Buffer as J}from"node:buffer";import{createHash as M}from"node:crypto";im
|
|
|
16
16
|
dispatch_key, sequence, state, handle, parent_handle, topology,
|
|
17
17
|
observed_at, terminal_at, freshness, observation_source, reason_code
|
|
18
18
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
19
|
-
`).run(o.dispatchKey,o.revision,o.state,o.handle,o.parentHandle,o.topology,o.observedAt,o.terminalAt,o.freshness,o.observationSource,o.reasonCode),Object.freeze({receipt:o,applied:!0,replay:!1})})}catch(
|
|
19
|
+
`).run(o.dispatchKey,o.revision,o.state,o.handle,o.parentHandle,o.topology,o.observedAt,o.terminalAt,o.freshness,o.observationSource,o.reasonCode),Object.freeze({receipt:o,applied:!0,replay:!1})})}catch(a){throw m(a,"sqlite-mutation-failed")}}getNativeAgentDispatchStatus(e,a={}){const r=this.db.prepare("SELECT * FROM native_agent_dispatches WHERE dispatch_key = ?").get(e);if(!r)return null;const s=$(r),n=Math.max(1e3,a.staleAfterMs??3e4),d=Date.parse(a.nowIso??this.now()),o=s.observedAt?Date.parse(s.observedAt):NaN;return!oe.has(s.state)&&Number.isFinite(d)&&(!Number.isFinite(o)||d-o>n)?Object.freeze({...s,state:"unknown",freshness:s.observedAt?"stale":"unknown",reasonCode:s.observedAt?"native-agent-observation-stale":"native-agent-awaiting-host-evidence"}):s}listRecentNativeAgentDispatches(e=20){const a=Math.max(1,Math.min(50,Math.floor(e))),r=this.db.prepare(`
|
|
20
20
|
SELECT * FROM native_agent_dispatches
|
|
21
21
|
ORDER BY COALESCE(observed_at, requested_at) DESC, dispatch_key DESC
|
|
22
22
|
LIMIT ?
|
|
23
|
-
`).all(
|
|
23
|
+
`).all(a);return Object.freeze(r.map($))}findNativeAgentDispatchRow(e,a,r){return this.db.prepare(`
|
|
24
24
|
SELECT * FROM native_agent_dispatches
|
|
25
25
|
WHERE dispatch_key = ? OR (story_id = ? AND graph_revision = ?)
|
|
26
26
|
ORDER BY CASE WHEN dispatch_key = ? THEN 0 ELSE 1 END
|
|
27
27
|
LIMIT 1
|
|
28
|
-
`).get(e,
|
|
28
|
+
`).get(e,a,r,e)}getLocalConsoleAttachmentState(e){c(e,"local_console.jobId",160,!0);const a=this.db.prepare(`
|
|
29
29
|
SELECT j.job_id AS job_id,
|
|
30
30
|
j.kind AS kind,
|
|
31
31
|
j.status AS status,
|
|
@@ -34,23 +34,23 @@ import{Buffer as J}from"node:buffer";import{createHash as M}from"node:crypto";im
|
|
|
34
34
|
FROM jobs j
|
|
35
35
|
WHERE j.job_id = ?
|
|
36
36
|
LIMIT 1
|
|
37
|
-
`).get(e);return!E(
|
|
37
|
+
`).get(e);return!E(a)||typeof a.job_id!="string"?null:{jobId:a.job_id,kind:typeof a.kind=="string"?a.kind:"unknown",status:typeof a.status=="string"?a.status:"unknown",activeLeaseCount:typeof a.active_lease_count=="number"?a.active_lease_count:0,runningHeadlessAttemptCount:typeof a.running_headless_attempt_count=="number"?a.running_headless_attempt_count:0,publicSafe:!0}}recordJob(e){this.assertCanMutate(),b(e.summary,"jobs.summary");const a=S(e.metadata);try{const r=this.db.prepare(`
|
|
38
38
|
INSERT OR IGNORE INTO jobs (
|
|
39
39
|
job_id, kind, status, summary, reason_code, created_at, updated_at,
|
|
40
40
|
next_run_at, goal_id, loop_id, campaign_id, operation_id,
|
|
41
41
|
idempotency_key, metadata_json
|
|
42
42
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
43
|
-
`).run(e.jobId,e.kind,e.status,e.summary??null,e.reasonCode??null,e.createdAt,e.updatedAt,e.nextRunAt??null,e.goalId??null,e.loopId??null,e.campaignId??null,e.operationId??null,e.idempotencyKey??null,
|
|
43
|
+
`).run(e.jobId,e.kind,e.status,e.summary??null,e.reasonCode??null,e.createdAt,e.updatedAt,e.nextRunAt??null,e.goalId??null,e.loopId??null,e.campaignId??null,e.operationId??null,e.idempotencyKey??null,a);return this.toWriteResult(r)}catch(r){throw m(r,"sqlite-mutation-failed")}}appendEvent(e){this.assertCanMutate(),b(e.summary,"job_events.summary");const a=S(e.metadata);try{const r=this.db.prepare(`
|
|
44
44
|
INSERT OR IGNORE INTO job_events (
|
|
45
45
|
event_id, job_id, operation_id, idempotency_key, event_sequence,
|
|
46
46
|
type, summary, reason_code, created_at, metadata_json
|
|
47
47
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
48
|
-
`).run(e.eventId,e.jobId,e.operationId,e.idempotencyKey??null,e.sequence??null,e.type,e.summary,e.reasonCode??null,e.createdAt,
|
|
48
|
+
`).run(e.eventId,e.jobId,e.operationId,e.idempotencyKey??null,e.sequence??null,e.type,e.summary,e.reasonCode??null,e.createdAt,a);return this.toWriteResult(r)}catch(r){throw m(r,"sqlite-mutation-failed")}}recordProcessingOutputSummary(e){Y(e.executionId,"processing_output_summary.executionId",160),Y(e.jobId,"processing_output_summary.jobId",160),Y(e.publicSummary,"processing_output_summary.publicSummary",Be),Y(e.createdAt,"processing_output_summary.createdAt",80),b(e.eventId,"processing_output_summary.eventId"),b(e.idempotencyKey,"processing_output_summary.idempotencyKey"),b(e.goalId,"processing_output_summary.goalId"),b(e.loopId,"processing_output_summary.loopId"),b(e.reasonCode,"processing_output_summary.reasonCode"),b(e.source,"processing_output_summary.source");const a=this.appendEvent({eventId:it(e),jobId:e.jobId,operationId:e.executionId,idempotencyKey:e.idempotencyKey??e.executionId,type:O,summary:e.publicSummary,reasonCode:e.reasonCode,createdAt:e.createdAt,metadata:dt(e)});return a.inserted&&this.recordJobStageProgress({jobId:e.jobId,currentStage:e.metadata?.currentStage,iteration:e.metadata?.iteration,at:e.createdAt}),a}enqueueHeadlessExecutionAttempt(e){if(this.assertCanMutate(),L({attemptId:e.attemptId,executionId:e.executionId,jobId:e.jobId,directiveHash:e.directiveHash,targetRef:e.targetRef,storyId:e.storyId,epicId:e.epicId,runtimeId:e.runtimeId,modelId:e.modelId,runtimeSource:e.runtimeSource,reasonCode:e.reasonCode,publicSummary:e.publicSummary,timestamp:e.enqueuedAt}),c(e.notBeforeAt,"headless_execution.notBeforeAt",80),c(e.operationId,"headless_execution.operationId",160),c(e.idempotencyKey,"headless_execution.idempotencyKey",160),N(e.retryCount,"headless_execution.retryCount"),N(e.maxAttempts,"headless_execution.maxAttempts"),e.maxAttempts!==void 0&&e.maxAttempts<1)throw new i("sqlite-public-safety-rejected","Continuity SQLite maxAttempts must be greater than zero.");e.metadata&&g(e.metadata,"headless_execution.metadata");const a=B({maxItems:e.queueCap,maxAttempts:e.maxAttempts}),r=qe(e.queuePriority),s=Pe(e.queueScope),n=w(e.relativePaths),d=V({attemptId:e.attemptId,executionId:e.executionId,jobId:e.jobId,directiveHash:e.directiveHash,runtimeId:e.runtimeId,modelId:e.modelId,runtimeSource:e.runtimeSource,status:e.status??"queued",reasonCode:e.reasonCode,retryCount:e.retryCount??0,attemptCount:0,maxAttempts:a.maxAttempts,queuePriority:r,queueScope:s,counts:e.counts,hashes:e.hashes,redactionSummary:e.redactionSummary,relativePaths:n,metadata:e.metadata});return this.runInTransaction(()=>{const o=this.db.prepare(`
|
|
49
49
|
SELECT value_json
|
|
50
50
|
FROM runner_config
|
|
51
51
|
WHERE key = 'headless_queue_policy'
|
|
52
52
|
LIMIT 1
|
|
53
|
-
`).get();let l=
|
|
53
|
+
`).get();let l=a.maxItems;if(e.queueCap===void 0&&E(o)&&typeof o.value_json=="string")try{const u=JSON.parse(o.value_json);E(u)&&typeof u.maxItems=="number"&&(l=B({maxItems:u.maxItems}).maxItems)}catch{}this.db.prepare(`
|
|
54
54
|
INSERT INTO runner_config (key, value_json, updated_at)
|
|
55
55
|
VALUES ('headless_queue_policy', ?, ?)
|
|
56
56
|
ON CONFLICT(key) DO UPDATE SET
|
|
@@ -63,12 +63,12 @@ import{Buffer as J}from"node:buffer";import{createHash as M}from"node:crypto";im
|
|
|
63
63
|
OR (? IS NOT NULL AND operation_id = ?)
|
|
64
64
|
OR (? IS NOT NULL AND idempotency_key = ?)
|
|
65
65
|
LIMIT 1
|
|
66
|
-
`).get(e.attemptId,e.operationId??null,e.operationId??null,e.idempotencyKey??null,e.idempotencyKey??null),
|
|
66
|
+
`).get(e.attemptId,e.operationId??null,e.operationId??null,e.idempotencyKey??null,e.idempotencyKey??null),h=this.db.prepare(`
|
|
67
67
|
SELECT COUNT(*) AS count
|
|
68
68
|
FROM headless_execution_attempts
|
|
69
69
|
WHERE status IN ('queued', 'backoff', 'running')
|
|
70
70
|
AND dead_lettered_at IS NULL
|
|
71
|
-
`).get(),f=E(
|
|
71
|
+
`).get(),f=E(h)&&typeof h.count=="number"?h.count:0;if(I)return{inserted:!1,replay:!0,changes:0,accepted:!0,backpressure:f>=l,queueDepth:f,queueCap:l,publicSafe:!0};if(f>=l)return{inserted:!1,replay:!1,changes:0,accepted:!1,backpressure:!0,queueDepth:f,queueCap:l,reasonCode:k.CAP_REACHED,publicSafe:!0};const _=this.db.prepare(`
|
|
72
72
|
INSERT INTO headless_execution_attempts (
|
|
73
73
|
attempt_id, execution_id, job_id, directive_hash, directive_kind,
|
|
74
74
|
command_class, target_kind, target_ref, story_id, epic_id, runtime_id,
|
|
@@ -78,7 +78,7 @@ import{Buffer as J}from"node:buffer";import{createHash as M}from"node:crypto";im
|
|
|
78
78
|
relative_paths_json, metadata_json, queue_priority, queue_scope,
|
|
79
79
|
attempt_count, next_retry_at
|
|
80
80
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 0, ?)
|
|
81
|
-
`).run(e.attemptId,e.executionId,e.jobId,e.directiveHash,e.directiveKind,e.commandClass,e.targetKind,e.targetRef,e.storyId??null,e.epicId??null,e.runtimeId??null,e.modelId??null,e.runtimeSource??null,e.status??"queued",e.reasonCode??null,e.publicSummary??null,e.enqueuedAt,e.status==="backoff"?e.notBeforeAt??e.enqueuedAt:null,e.retryCount??0,
|
|
81
|
+
`).run(e.attemptId,e.executionId,e.jobId,e.directiveHash,e.directiveKind,e.commandClass,e.targetKind,e.targetRef,e.storyId??null,e.epicId??null,e.runtimeId??null,e.modelId??null,e.runtimeSource??null,e.status??"queued",e.reasonCode??null,e.publicSummary??null,e.enqueuedAt,e.status==="backoff"?e.notBeforeAt??e.enqueuedAt:null,e.retryCount??0,a.maxAttempts,e.operationId??null,e.idempotencyKey??null,T(e.counts,"headless_execution.counts"),T(e.hashes,"headless_execution.hashes"),T(e.redactionSummary,"headless_execution.redactionSummary"),T(n,"headless_execution.relativePaths"),S(d),r,s,e.notBeforeAt??e.enqueuedAt);return{inserted:_.changes>0,replay:!1,changes:_.changes,accepted:_.changes>0,backpressure:f+_.changes>=l,queueDepth:f+_.changes,queueCap:l,publicSafe:!0}})}listDueHeadlessExecutionAttempts(e){const a=Math.max(1,Math.min(50,Math.floor(e.limit)));return c(e.nowIso,"headless_execution.nowIso",80,!0),this.db.prepare(`
|
|
82
82
|
SELECT attempt_id, execution_id, job_id, directive_hash, directive_kind,
|
|
83
83
|
command_class, target_kind, target_ref, story_id, epic_id,
|
|
84
84
|
runtime_id, model_id, runtime_source, status, reason_code,
|
|
@@ -97,13 +97,13 @@ import{Buffer as J}from"node:buffer";import{createHash as M}from"node:crypto";im
|
|
|
97
97
|
ORDER BY queue_priority DESC, COALESCE(next_retry_at, not_before_at, enqueued_at) ASC,
|
|
98
98
|
enqueued_at ASC, attempt_id ASC
|
|
99
99
|
LIMIT ?
|
|
100
|
-
`).all(e.nowIso,e.nowIso,
|
|
100
|
+
`).all(e.nowIso,e.nowIso,a)}hasCompletedHeadlessExecutionDirectiveHash(e,a){c(e,"headless_execution.directiveHash",160,!0),c(a,"headless_execution.attemptId",160);const r=a?" AND attempt_id != ?":"",s=a?[e,a]:[e];return this.db.prepare(`
|
|
101
101
|
SELECT 1 AS found
|
|
102
102
|
FROM headless_execution_attempts
|
|
103
103
|
WHERE directive_hash = ?
|
|
104
104
|
AND status = 'completed'${r}
|
|
105
105
|
LIMIT 1
|
|
106
|
-
`).get(...s)?.found===1}claimHeadlessExecutionAttempt(e){this.assertCanMutate(),L({attemptId:e.attemptId,executionId:e.attemptId,jobId:e.attemptId,leaseId:e.leaseId,runnerId:e.runnerId,reasonCode:e.reasonCode,timestamp:e.claimedAt}),c(e.leaseExpiresAt,"headless_execution.leaseExpiresAt",80,!0);try{const
|
|
106
|
+
`).get(...s)?.found===1}claimHeadlessExecutionAttempt(e){this.assertCanMutate(),L({attemptId:e.attemptId,executionId:e.attemptId,jobId:e.attemptId,leaseId:e.leaseId,runnerId:e.runnerId,reasonCode:e.reasonCode,timestamp:e.claimedAt}),c(e.leaseExpiresAt,"headless_execution.leaseExpiresAt",80,!0);try{const a=this.db.prepare(`
|
|
107
107
|
UPDATE headless_execution_attempts
|
|
108
108
|
SET status = 'running',
|
|
109
109
|
lease_id = ?,
|
|
@@ -119,7 +119,7 @@ import{Buffer as J}from"node:buffer";import{createHash as M}from"node:crypto";im
|
|
|
119
119
|
AND dead_lettered_at IS NULL
|
|
120
120
|
AND (COALESCE(next_retry_at, not_before_at) IS NULL OR COALESCE(next_retry_at, not_before_at) <= ?)
|
|
121
121
|
AND (lease_id IS NULL OR lease_released_at IS NOT NULL OR lease_expires_at <= ?)
|
|
122
|
-
`).run(e.leaseId,e.runnerId,e.claimedAt,e.claimedAt,e.leaseExpiresAt,e.reasonCode??null,e.attemptId,e.claimedAt,e.claimedAt);return this.toWriteResult(
|
|
122
|
+
`).run(e.leaseId,e.runnerId,e.claimedAt,e.claimedAt,e.leaseExpiresAt,e.reasonCode??null,e.attemptId,e.claimedAt,e.claimedAt);return this.toWriteResult(a)}catch(a){throw m(a,"sqlite-mutation-failed")}}acquireNextHeadlessExecutionAttempt(e){return this.assertCanMutate(),L({attemptId:e.leaseId,executionId:e.leaseId,jobId:e.leaseId,leaseId:e.leaseId,runnerId:e.runnerId,reasonCode:e.reasonCode,timestamp:e.claimedAt}),c(e.leaseExpiresAt,"headless_execution.leaseExpiresAt",80,!0),this.runInTransaction(()=>{const a=this.db.prepare(`
|
|
123
123
|
SELECT attempt_id
|
|
124
124
|
FROM headless_execution_attempts
|
|
125
125
|
WHERE status IN ('queued', 'backoff')
|
|
@@ -132,7 +132,7 @@ import{Buffer as J}from"node:buffer";import{createHash as M}from"node:crypto";im
|
|
|
132
132
|
enqueued_at ASC,
|
|
133
133
|
attempt_id ASC
|
|
134
134
|
LIMIT 1
|
|
135
|
-
`).get(e.directiveKind??null,e.directiveKind??null,e.claimedAt,e.claimedAt);if(typeof
|
|
135
|
+
`).get(e.directiveKind??null,e.directiveKind??null,e.claimedAt,e.claimedAt);if(typeof a?.attempt_id!="string")return{acquired:!1,reasonCode:"continuity-ok",publicSafe:!0};if(this.db.prepare(`
|
|
136
136
|
UPDATE headless_execution_attempts
|
|
137
137
|
SET status = 'running',
|
|
138
138
|
lease_id = ?,
|
|
@@ -148,7 +148,7 @@ import{Buffer as J}from"node:buffer";import{createHash as M}from"node:crypto";im
|
|
|
148
148
|
AND dead_lettered_at IS NULL
|
|
149
149
|
AND (COALESCE(next_retry_at, not_before_at) IS NULL OR COALESCE(next_retry_at, not_before_at) <= ?)
|
|
150
150
|
AND (lease_id IS NULL OR lease_released_at IS NOT NULL OR lease_expires_at <= ?)
|
|
151
|
-
`).run(e.leaseId,e.runnerId,e.claimedAt,e.claimedAt,e.leaseExpiresAt,e.reasonCode??null,
|
|
151
|
+
`).run(e.leaseId,e.runnerId,e.claimedAt,e.claimedAt,e.leaseExpiresAt,e.reasonCode??null,a.attempt_id,e.claimedAt,e.claimedAt).changes===0)return{acquired:!1,reasonCode:"lease-conflict",publicSafe:!0};const s=this.getHeadlessExecutionAttempt(a.attempt_id);return s?{acquired:!0,attempt:s,reasonCode:e.reasonCode??"continuity-ok",publicSafe:!0}:{acquired:!1,reasonCode:"lease-conflict",publicSafe:!0}})}heartbeatHeadlessExecutionAttempt(e){this.assertCanMutate(),L({attemptId:e.attemptId,executionId:e.attemptId,jobId:e.attemptId,leaseId:e.leaseId,runnerId:e.runnerId,timestamp:e.heartbeatAt}),c(e.leaseExpiresAt,"headless_execution.leaseExpiresAt",80);try{const a=this.db.prepare(`
|
|
152
152
|
UPDATE headless_execution_attempts
|
|
153
153
|
SET heartbeat_at = ?,
|
|
154
154
|
lease_expires_at = COALESCE(?, lease_expires_at)
|
|
@@ -158,7 +158,7 @@ import{Buffer as J}from"node:buffer";import{createHash as M}from"node:crypto";im
|
|
|
158
158
|
AND status = 'running'
|
|
159
159
|
AND lease_released_at IS NULL
|
|
160
160
|
AND lease_expires_at > ?
|
|
161
|
-
`).run(e.heartbeatAt,e.leaseExpiresAt??null,e.attemptId,e.leaseId,e.runnerId,e.heartbeatAt);return this.toWriteResult(
|
|
161
|
+
`).run(e.heartbeatAt,e.leaseExpiresAt??null,e.attemptId,e.leaseId,e.runnerId,e.heartbeatAt);return this.toWriteResult(a)}catch(a){throw m(a,"sqlite-mutation-failed")}}releaseHeadlessExecutionAttempt(e){this.assertCanMutate(),L({attemptId:e.attemptId,executionId:e.attemptId,jobId:e.attemptId,leaseId:e.leaseId,reasonCode:e.reasonCode,timestamp:e.releasedAt}),c(e.notBeforeAt,"headless_execution.notBeforeAt",80),N(e.retryCount,"headless_execution.retryCount");try{const a=this.db.prepare(`
|
|
162
162
|
UPDATE headless_execution_attempts
|
|
163
163
|
SET status = COALESCE(?, status),
|
|
164
164
|
reason_code = COALESCE(?, reason_code),
|
|
@@ -174,8 +174,8 @@ import{Buffer as J}from"node:buffer";import{createHash as M}from"node:crypto";im
|
|
|
174
174
|
AND lease_id = ?
|
|
175
175
|
AND status = 'running'
|
|
176
176
|
AND lease_released_at IS NULL
|
|
177
|
-
`).run(e.status??null,e.reasonCode??null,e.notBeforeAt??null,e.retryCount??null,e.status??null,e.notBeforeAt??null,e.status??null,e.releasedAt,e.attemptId,e.leaseId);return this.toWriteResult(
|
|
178
|
-
AND lease_released_at IS NULL${e.runnerId?" AND runner_id = ?":""}`:"",n=e.leaseId?"status = 'running'":"status NOT IN ('completed', 'failed', 'timed_out', 'skipped')",d=[e.status,e.completedAt,e.durationMs??null,e.reasonCode??null,e.publicSummary??null,e.notBeforeAt??null,e.retryCount??null,e.status,e.notBeforeAt??null,e.counts?T(e.counts,"headless_execution.counts"):null,e.hashes?T(e.hashes,"headless_execution.hashes"):null,e.redactionSummary?T(e.redactionSummary,"headless_execution.redactionSummary"):null,
|
|
177
|
+
`).run(e.status??null,e.reasonCode??null,e.notBeforeAt??null,e.retryCount??null,e.status??null,e.notBeforeAt??null,e.status??null,e.releasedAt,e.attemptId,e.leaseId);return this.toWriteResult(a)}catch(a){throw m(a,"sqlite-mutation-failed")}}completeHeadlessExecutionAttempt(e){this.assertCanMutate(),L({attemptId:e.attemptId,executionId:e.attemptId,jobId:e.attemptId,leaseId:e.leaseId,runnerId:e.runnerId,reasonCode:e.reasonCode,publicSummary:e.publicSummary,timestamp:e.completedAt}),c(e.notBeforeAt,"headless_execution.notBeforeAt",80),N(e.durationMs,"headless_execution.durationMs"),N(e.retryCount,"headless_execution.retryCount"),e.metadata&&g(e.metadata,"headless_execution.metadata");const a=w(e.relativePaths),r=V({attemptId:e.attemptId,executionId:e.executionId??e.attemptId,jobId:e.jobId??e.attemptId,status:e.status,reasonCode:e.reasonCode,durationMs:e.durationMs,retryCount:e.retryCount,counts:e.counts,hashes:e.hashes,redactionSummary:e.redactionSummary,relativePaths:a,metadata:e.metadata}),s=e.leaseId?` AND lease_id = ?
|
|
178
|
+
AND lease_released_at IS NULL${e.runnerId?" AND runner_id = ?":""}`:"",n=e.leaseId?"status = 'running'":"status NOT IN ('completed', 'failed', 'timed_out', 'skipped')",d=[e.status,e.completedAt,e.durationMs??null,e.reasonCode??null,e.publicSummary??null,e.notBeforeAt??null,e.retryCount??null,e.status,e.notBeforeAt??null,e.counts?T(e.counts,"headless_execution.counts"):null,e.hashes?T(e.hashes,"headless_execution.hashes"):null,e.redactionSummary?T(e.redactionSummary,"headless_execution.redactionSummary"):null,a?T(a,"headless_execution.relativePaths"):null,S(r),e.completedAt,e.attemptId];e.leaseId&&d.push(e.leaseId),e.leaseId&&e.runnerId&&d.push(e.runnerId);try{const o=this.db.prepare(`
|
|
179
179
|
UPDATE headless_execution_attempts
|
|
180
180
|
SET status = ?,
|
|
181
181
|
completed_at = ?,
|
|
@@ -196,51 +196,51 @@ import{Buffer as J}from"node:buffer";import{createHash as M}from"node:crypto";im
|
|
|
196
196
|
lease_released_at = COALESCE(lease_released_at, ?)
|
|
197
197
|
WHERE attempt_id = ?${s}
|
|
198
198
|
AND ${n}
|
|
199
|
-
`).run(...d);return this.toWriteResult(o)}catch(o){throw m(o,"sqlite-mutation-failed")}}recordHeadlessExecutionReceipt(e){L({attemptId:e.attemptId,executionId:e.executionId,jobId:e.jobId,reasonCode:e.reasonCode,timestamp:e.createdAt}),e.metadata&&g(e.metadata,"headless_execution.metadata");const
|
|
199
|
+
`).run(...d);return this.toWriteResult(o)}catch(o){throw m(o,"sqlite-mutation-failed")}}recordHeadlessExecutionReceipt(e){L({attemptId:e.attemptId,executionId:e.executionId,jobId:e.jobId,reasonCode:e.reasonCode,timestamp:e.createdAt}),e.metadata&&g(e.metadata,"headless_execution.metadata");const a=w(e.relativePaths),r=V({attemptId:e.attemptId,executionId:e.executionId,jobId:e.jobId,status:e.status,reasonCode:e.reasonCode,counts:e.counts,hashes:e.hashes,redactionSummary:e.redactionSummary,relativePaths:a,metadata:e.metadata});return this.appendReceipt({receiptId:e.receiptId,jobId:e.jobId,operationId:e.operationId??e.executionId,idempotencyKey:e.idempotencyKey??e.executionId,status:e.status,reasonCode:e.reasonCode,appliedOperationIds:e.status==="applied"?[e.executionId]:void 0,ignoredOperationIds:e.status==="ignored"?[e.executionId]:void 0,createdAt:e.createdAt,metadata:r})}recordHeadlessExecutionSummary(e){L({attemptId:e.attemptId,executionId:e.executionId,jobId:e.jobId,runtimeId:e.runtimeId,modelId:e.modelId,reasonCode:e.reasonCode,publicSummary:e.publicSummary,timestamp:e.createdAt}),N(e.durationMs,"headless_execution.durationMs"),e.metadata&&g(e.metadata,"headless_execution.metadata");const a=w(e.relativePaths),r=V({attemptId:e.attemptId,executionId:e.executionId,jobId:e.jobId,runtimeId:e.runtimeId,modelId:e.modelId,status:e.status??"completed",reasonCode:e.reasonCode,durationMs:e.durationMs,counts:e.counts,hashes:e.hashes,redactionSummary:e.redactionSummary,relativePaths:a,metadata:e.metadata});return this.recordProcessingOutputSummary({eventId:e.eventId,executionId:e.executionId,jobId:e.jobId,idempotencyKey:e.executionId,publicSummary:e.publicSummary,reasonCode:e.reasonCode,createdAt:e.createdAt,source:"headless_execution",metadata:r})}appendReceipt(e){this.assertCanMutate();const a=S(e.metadata);try{const r=this.db.prepare(`
|
|
200
200
|
INSERT OR IGNORE INTO job_receipts (
|
|
201
201
|
receipt_id, job_id, operation_id, idempotency_key, status, reason_code,
|
|
202
202
|
applied_operation_ids_json, ignored_operation_ids_json, created_at, metadata_json
|
|
203
203
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
204
|
-
`).run(e.receiptId,e.jobId,e.operationId??null,e.idempotencyKey??null,e.status,e.reasonCode??null,e.appliedOperationIds?JSON.stringify(e.appliedOperationIds):null,e.ignoredOperationIds?JSON.stringify(e.ignoredOperationIds):null,e.createdAt,
|
|
204
|
+
`).run(e.receiptId,e.jobId,e.operationId??null,e.idempotencyKey??null,e.status,e.reasonCode??null,e.appliedOperationIds?JSON.stringify(e.appliedOperationIds):null,e.ignoredOperationIds?JSON.stringify(e.ignoredOperationIds):null,e.createdAt,a);return this.toWriteResult(r)}catch(r){throw m(r,"sqlite-mutation-failed")}}compactPublicReceiptsAndOutputs(e){this.assertCanMutate();const a=Date.parse(e.nowIso);if(!Number.isFinite(a))throw new i("sqlite-public-safety-rejected","Continuity receipt compaction requires a valid public timestamp.");const r=He(e.policy),s=new Date(a-r.receipts.maxAgeMs).toISOString(),n=new Date(a-r.processingOutputs.maxAgeMs).toISOString();try{return this.runInTransaction(()=>{const d=this.selectReceiptRetentionCandidates({cutoff:s,maxItems:r.receipts.maxItems,maxBytes:r.receipts.maxBytes,limit:r.maxDeleteRowsPerRun}),o=this.selectOutputRetentionCandidates({cutoff:n,maxItems:r.processingOutputs.maxItems,maxBytes:r.processingOutputs.maxBytes,limit:r.maxDeleteRowsPerRun}),l=[...d,...o].sort((u,p)=>u.createdAt.localeCompare(p.createdAt)||u.id.localeCompare(p.id)).slice(0,r.maxDeleteRowsPerRun);if(l.length===0)return{status:"noop",summaries:[],counts:{receiptsRemoved:0,outputsRemoved:0,bytesRemoved:0,summariesCreated:0},reasonCode:F.NOOP,publicSafe:!0};const I=l.filter(u=>u.kind==="receipt"),h=l.filter(u=>u.kind==="output");for(const u of q(I.map(p=>p.jobId)))this.preserveReceiptDerivedIteration(u,e.nowIso);this.deleteRetentionCandidates("job_receipts","receipt_id",I.map(u=>u.id)),this.deleteRetentionCandidates("job_events","event_id",h.map(u=>u.id));const f=new Map;for(const u of l)f.set(u.jobId,[...f.get(u.jobId)??[],u]);const _=[];for(const[u,p]of[...f.entries()].sort(([x],[A])=>x.localeCompare(A))){const x=p.filter(j=>j.kind==="receipt"),A=p.filter(j=>j.kind==="output"),Q=this.retainedReceiptOutputCounts(u),G=ut(u,x,A),R={receiptsRemoved:x.length,receiptsRetained:Q.receipts,outputsRemoved:A.length,outputsRetained:Q.outputs,bytesRemoved:p.reduce((j,Se)=>j+Se.approxBytes,0),bytesRetained:Q.bytes,redactions:0},P=`Compacted public receipt and processing evidence: receipts removed ${R.receiptsRemoved}, retained ${R.receiptsRetained}; summaries removed ${R.outputsRemoved}, retained ${R.outputsRetained}; bytes removed ${R.bytesRemoved}, retained ${R.bytesRetained}.`;c(P,"receipt_compaction.publicSummary",500,!0);const H=`receipt-compaction-${M("sha256").update(`${u}:${e.nowIso}:${G.aggregate}`).digest("hex").slice(0,32)}`,ee={schemaVersion:1,contractVersion:"continuity-v1",policyVersion:1,type:W,summaryId:H,jobId:u,scope:"local_sqlite",status:"compacted",createdAt:e.nowIso,reasonCodes:[F.COMPACTED],counts:R,hashes:G,publicSummary:P,publicSafe:!0};this.appendEvent({eventId:H,jobId:u,operationId:`op-${H}`,idempotencyKey:`idem-${H}`,type:W,summary:P,reasonCode:F.COMPACTED,createdAt:e.nowIso,metadata:{schemaVersion:1,contractVersion:"continuity-v1",eventType:W,jobId:u,reasonCodes:ee.reasonCodes,counts:R,hashes:G,publicSummary:P}}),this.pruneReceiptCompactionSummaries(u,r.maxCompactionSummariesPerJob),_.push(ee)}return{status:"compacted",summaries:_,counts:{receiptsRemoved:I.length,outputsRemoved:h.length,bytesRemoved:l.reduce((u,p)=>u+p.approxBytes,0),summariesCreated:_.length},reasonCode:F.COMPACTED,publicSafe:!0}})}catch(d){throw m(d,"sqlite-mutation-failed")}}updateJobStatus(e){this.assertCanMutate();try{const a=this.db.prepare(`
|
|
205
205
|
UPDATE jobs
|
|
206
206
|
SET status = ?,
|
|
207
207
|
reason_code = COALESCE(?, reason_code),
|
|
208
208
|
updated_at = ?,
|
|
209
209
|
next_run_at = COALESCE(?, next_run_at)
|
|
210
210
|
WHERE job_id = ?
|
|
211
|
-
`).run(e.status,e.reasonCode??null,e.updatedAt,e.nextRunAt??null,e.jobId);if(
|
|
211
|
+
`).run(e.status,e.reasonCode??null,e.updatedAt,e.nextRunAt??null,e.jobId);if(a.changes===0)throw new i("sqlite-foreign-key-failed",`Continuity SQLite job ${e.jobId} was not found for status update.`);return this.toWriteResult(a)}catch(a){throw m(a,"sqlite-mutation-failed")}}recordJobStageProgress(e){this.assertCanMutate(),c(e.jobId,"job_stage.jobId",160,!0);const a=le(e.currentStage)?e.currentStage:void 0,r=Ge(e.iteration);if(!a&&r===void 0)return{inserted:!1,replay:!1,changes:0};const s=ue(e.at);try{const n=this.db.prepare("SELECT metadata_json FROM jobs WHERE job_id = ?").get(e.jobId);if(!n)return{inserted:!1,replay:!1,changes:0};const d=_t(typeof n.metadata_json=="string"?n.metadata_json:null);if(a&&(d.currentStage=a),r!==void 0&&(d.iteration=r),a&&s&&e.appendHistory!==!1){const l=Qe(d.stageHistory);l.push({stage:a,at:s}),d.stageHistory=l.slice(-ce)}const o=this.db.prepare("UPDATE jobs SET metadata_json = ? WHERE job_id = ?").run(S(d),e.jobId);return this.toWriteResult(o)}catch(n){throw m(n,"sqlite-mutation-failed")}}updateJobAndExistingGoalCampaignStatus(e){return this.runInTransaction(()=>{const a=this.db.prepare(`
|
|
212
212
|
UPDATE jobs
|
|
213
213
|
SET status = ?,
|
|
214
214
|
reason_code = COALESCE(?, reason_code),
|
|
215
215
|
updated_at = ?,
|
|
216
216
|
next_run_at = COALESCE(?, next_run_at)
|
|
217
217
|
WHERE job_id = ?
|
|
218
|
-
`).run(e.status,e.reasonCode??null,e.updatedAt,e.nextRunAt??null,e.jobId);if(
|
|
218
|
+
`).run(e.status,e.reasonCode??null,e.updatedAt,e.nextRunAt??null,e.jobId);if(a.changes===0)throw new i("sqlite-foreign-key-failed",`Continuity SQLite job ${e.jobId} was not found for status parity update.`);const r=this.db.prepare(`
|
|
219
219
|
UPDATE goal_campaigns
|
|
220
220
|
SET status = ?,
|
|
221
221
|
reason_code = COALESCE(?, reason_code),
|
|
222
222
|
updated_at = ?
|
|
223
223
|
WHERE job_id = ?
|
|
224
|
-
`).run(e.status,e.reasonCode??null,e.updatedAt,e.jobId);return this.toWriteResult({changes:
|
|
224
|
+
`).run(e.status,e.reasonCode??null,e.updatedAt,e.jobId);return this.toWriteResult({changes:a.changes+r.changes})})}scheduleNextTick(e){return this.updateJobStatus({jobId:e.jobId,status:"active",updatedAt:e.updatedAt,reasonCode:e.reasonCode,nextRunAt:e.scheduledAt})}acquireLease(e){this.assertCanMutate();const a=S(e.metadata);try{const r=this.db.prepare(`
|
|
225
225
|
INSERT OR IGNORE INTO job_leases (
|
|
226
226
|
lease_id, job_id, runner_id, status, acquired_at, expires_at,
|
|
227
227
|
operation_id, idempotency_key, metadata_json
|
|
228
228
|
) VALUES (?, ?, ?, 'acquired', ?, ?, ?, ?, ?)
|
|
229
|
-
`).run(e.leaseId,e.jobId,e.runnerId,e.acquiredAt,e.expiresAt,e.operationId??null,e.idempotencyKey??null,
|
|
229
|
+
`).run(e.leaseId,e.jobId,e.runnerId,e.acquiredAt,e.expiresAt,e.operationId??null,e.idempotencyKey??null,a);return this.toWriteResult(r)}catch(r){throw m(r,"sqlite-mutation-failed")}}releaseLease(e){this.assertCanMutate();try{const a=this.db.prepare(`
|
|
230
230
|
UPDATE job_leases
|
|
231
231
|
SET status = 'released', released_at = ?
|
|
232
232
|
WHERE lease_id = ? AND released_at IS NULL
|
|
233
|
-
`).run(e.releasedAt,e.leaseId);if(
|
|
233
|
+
`).run(e.releasedAt,e.leaseId);if(a.changes===0)throw new i("sqlite-foreign-key-failed",`Continuity SQLite lease ${e.leaseId} was not found for release.`);return this.toWriteResult(a)}catch(a){throw m(a,"sqlite-mutation-failed")}}recordStateSnapshot(e){this.assertCanMutate(),b(e.summary,"state_snapshots.summary"),b(e.relativePath,"state_snapshots.relative_path");const a=S(e.metadata);try{const r=this.db.prepare(`
|
|
234
234
|
INSERT OR IGNORE INTO state_snapshots (
|
|
235
235
|
snapshot_id, job_id, kind, relative_path, sha256, summary, captured_at,
|
|
236
236
|
operation_id, idempotency_key, metadata_json
|
|
237
237
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
238
|
-
`).run(e.snapshotId,e.jobId??null,e.kind,e.relativePath??null,e.sha256??null,e.summary??null,e.capturedAt,e.operationId??null,e.idempotencyKey??null,
|
|
238
|
+
`).run(e.snapshotId,e.jobId??null,e.kind,e.relativePath??null,e.sha256??null,e.summary??null,e.capturedAt,e.operationId??null,e.idempotencyKey??null,a);return this.toWriteResult(r)}catch(r){throw m(r,"sqlite-mutation-failed")}}recordArtifact(e){this.assertCanMutate(),b(e.kind,"artifacts.kind"),b(e.relativePath,"artifacts.relative_path"),b(e.summary,"artifacts.summary");const a=S(e.metadata);try{const r=this.db.prepare(`
|
|
239
239
|
INSERT OR IGNORE INTO artifacts (
|
|
240
240
|
artifact_id, job_id, kind, relative_path, sha256, summary,
|
|
241
241
|
operation_id, idempotency_key, created_at, metadata_json
|
|
242
242
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
243
|
-
`).run(e.artifactId,e.jobId??null,e.kind,e.relativePath,e.sha256??null,e.summary??null,e.operationId??null,e.idempotencyKey??null,e.createdAt,
|
|
243
|
+
`).run(e.artifactId,e.jobId??null,e.kind,e.relativePath,e.sha256??null,e.summary??null,e.operationId??null,e.idempotencyKey??null,e.createdAt,a);return this.toWriteResult(r)}catch(r){throw m(r,"sqlite-mutation-failed")}}enqueueOutbox(e){this.assertCanMutate(),v({outboxId:e.outboxId,jobId:e.jobId,operationId:e.operationId,idempotencyKey:e.idempotencyKey,type:e.type,status:e.status,deliveryCursor:e.deliveryCursor,timestamp:e.createdAt,reasonCode:e.lastErrorReason??e.lastErrorCode,summary:e.lastErrorSummary??e.deadLetterSummary}),v({outboxId:e.outboxId,timestamp:e.updatedAt}),c(e.nextAttemptAt,"outbox.nextAttemptAt",80),c(e.lastAttemptAt,"outbox.lastAttemptAt",80),c(e.sentAt,"outbox.sentAt",80),c(e.ackedAt,"outbox.ackedAt",80),c(e.deadLetteredAt,"outbox.deadLetteredAt",80),N(e.retryCount,"outbox.retryCount"),N(e.attemptCount,"outbox.attemptCount");const a=S(e.payload);try{const r=this.db.prepare(`
|
|
244
244
|
INSERT OR IGNORE INTO outbox (
|
|
245
245
|
outbox_id, job_id, operation_id, idempotency_key, type, status,
|
|
246
246
|
payload_json, retry_count, attempt_count, delivery_cursor,
|
|
@@ -248,7 +248,7 @@ import{Buffer as J}from"node:buffer";import{createHash as M}from"node:crypto";im
|
|
|
248
248
|
last_error_reason, last_error_summary, dead_letter_summary,
|
|
249
249
|
dead_lettered_at, created_at, updated_at
|
|
250
250
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
251
|
-
`).run(e.outboxId,e.jobId??null,e.operationId,e.idempotencyKey??null,e.type,e.status??"pending",
|
|
251
|
+
`).run(e.outboxId,e.jobId??null,e.operationId,e.idempotencyKey??null,e.type,e.status??"pending",a??"{}",e.retryCount??0,e.attemptCount??0,e.deliveryCursor??null,e.nextAttemptAt??null,e.lastAttemptAt??null,e.sentAt??null,e.ackedAt??null,e.lastErrorCode??null,e.lastErrorReason??e.lastErrorCode??null,e.lastErrorSummary??null,e.deadLetterSummary??null,e.deadLetteredAt??null,e.createdAt,e.updatedAt);return this.toWriteResult(r)}catch(r){throw m(r,"sqlite-mutation-failed")}}selectOutboxBatch(e){v({outboxId:"outbox-query",timestamp:e.nowIso});const a=Math.max(1,Math.min(100,Math.floor(e.limit))),r=q(e.statuses?.length?e.statuses:["pending","failed"]);for(const d of r)if(!Ee(d))throw new i("sqlite-public-safety-rejected","Continuity SQLite outbox batch query rejected an unknown status.");const s=r.map(()=>"?").join(", ");return this.db.prepare(`
|
|
252
252
|
SELECT outbox_id, job_id, operation_id, idempotency_key, type, status,
|
|
253
253
|
payload_json, retry_count, attempt_count, delivery_cursor,
|
|
254
254
|
next_attempt_at, last_attempt_at, sent_at, acked_at, last_error_code,
|
|
@@ -259,7 +259,7 @@ import{Buffer as J}from"node:buffer";import{createHash as M}from"node:crypto";im
|
|
|
259
259
|
AND (status NOT IN ('pending', 'failed') OR next_attempt_at IS NULL OR next_attempt_at <= ?)
|
|
260
260
|
ORDER BY COALESCE(next_attempt_at, created_at) ASC, created_at ASC, outbox_id ASC
|
|
261
261
|
LIMIT ?
|
|
262
|
-
`).all(...r,e.nowIso,
|
|
262
|
+
`).all(...r,e.nowIso,a).map(yt)}markOutboxSent(e){this.assertCanMutate(),v({outboxId:e.outboxId,deliveryCursor:e.deliveryCursor,timestamp:e.sentAt,reasonCode:e.reasonCode});try{return this.runInTransaction(()=>{const a=this.getOutboxTransitionRow(e.outboxId);if(!a)return C({outboxId:e.outboxId,status:"missing",changes:0,replay:!1,reasonCode:"outbox-missing"});if((a.status==="sent"||a.status==="acked")&&a.delivery_cursor===e.deliveryCursor)return C({outboxId:e.outboxId,status:a.status,changes:0,replay:!0,deliveryCursor:e.deliveryCursor,reasonCode:e.reasonCode??"outbox-delivery-replay"});if(a.status==="sent"||a.status==="acked"||a.status==="dead_letter")return C({outboxId:e.outboxId,status:"conflict",changes:0,replay:!1,deliveryCursor:a.delivery_cursor??void 0,reasonCode:"outbox-delivery-conflict"});const r=this.db.prepare(`
|
|
263
263
|
UPDATE outbox
|
|
264
264
|
SET status = 'sent',
|
|
265
265
|
delivery_cursor = ?,
|
|
@@ -270,7 +270,7 @@ import{Buffer as J}from"node:buffer";import{createHash as M}from"node:crypto";im
|
|
|
270
270
|
updated_at = ?
|
|
271
271
|
WHERE outbox_id = ?
|
|
272
272
|
AND status IN ('pending', 'failed')
|
|
273
|
-
`).run(e.deliveryCursor,e.sentAt,e.sentAt,e.sentAt,e.outboxId);return C({outboxId:e.outboxId,status:"sent",changes:r.changes,replay:!1,deliveryCursor:e.deliveryCursor,reasonCode:e.reasonCode??"outbox-sent"})})}catch(
|
|
273
|
+
`).run(e.deliveryCursor,e.sentAt,e.sentAt,e.sentAt,e.outboxId);return C({outboxId:e.outboxId,status:"sent",changes:r.changes,replay:!1,deliveryCursor:e.deliveryCursor,reasonCode:e.reasonCode??"outbox-sent"})})}catch(a){throw m(a,"sqlite-mutation-failed")}}ackOutbox(e){this.assertCanMutate(),v({outboxId:e.outboxId,deliveryCursor:e.deliveryCursor,timestamp:e.ackedAt,reasonCode:e.reasonCode});try{return this.runInTransaction(()=>{const a=this.getOutboxTransitionRow(e.outboxId);if(!a)return C({outboxId:e.outboxId,status:"missing",changes:0,replay:!1,reasonCode:"outbox-missing"});if(a.status==="acked"&&(!e.deliveryCursor||a.delivery_cursor===e.deliveryCursor))return C({outboxId:e.outboxId,status:"acked",changes:0,replay:!0,deliveryCursor:a.delivery_cursor??void 0,reasonCode:e.reasonCode??"outbox-ack-replay"});if(a.status!=="sent"||e.deliveryCursor&&a.delivery_cursor!==e.deliveryCursor)return C({outboxId:e.outboxId,status:"conflict",changes:0,replay:!1,deliveryCursor:a.delivery_cursor??void 0,reasonCode:"outbox-ack-conflict"});const r=this.db.prepare(`
|
|
274
274
|
UPDATE outbox
|
|
275
275
|
SET status = 'acked',
|
|
276
276
|
acked_at = ?,
|
|
@@ -280,7 +280,7 @@ import{Buffer as J}from"node:buffer";import{createHash as M}from"node:crypto";im
|
|
|
280
280
|
last_error_reason = NULL
|
|
281
281
|
WHERE outbox_id = ?
|
|
282
282
|
AND status = 'sent'
|
|
283
|
-
`).run(e.ackedAt,e.ackedAt,e.outboxId);return C({outboxId:e.outboxId,status:"acked",changes:r.changes,replay:!1,deliveryCursor:
|
|
283
|
+
`).run(e.ackedAt,e.ackedAt,e.outboxId);return C({outboxId:e.outboxId,status:"acked",changes:r.changes,replay:!1,deliveryCursor:a.delivery_cursor??void 0,reasonCode:e.reasonCode??"outbox-acked"})})}catch(a){throw m(a,"sqlite-mutation-failed")}}failOutboxDelivery(e){this.assertCanMutate(),v({outboxId:e.outboxId,deliveryCursor:e.deliveryCursor,timestamp:e.failedAt,reasonCode:e.reasonCode,summary:e.summary}),c(e.nextRetryAt,"outbox.nextRetryAt",80);try{return this.runInTransaction(()=>{const a=this.getOutboxTransitionRow(e.outboxId);if(!a)return C({outboxId:e.outboxId,status:"missing",changes:0,replay:!1,reasonCode:"outbox-missing"});if(a.status==="acked")return C({outboxId:e.outboxId,status:"acked",changes:0,replay:!0,deliveryCursor:a.delivery_cursor??void 0,reasonCode:"outbox-already-acked"});if(a.status==="dead_letter")return C({outboxId:e.outboxId,status:"dead_letter",changes:0,replay:!0,deliveryCursor:a.delivery_cursor??void 0,deadLetteredAt:a.dead_lettered_at??void 0,reasonCode:a.last_error_reason??a.last_error_code??e.reasonCode});if(e.deliveryCursor&&a.delivery_cursor&&a.delivery_cursor!==e.deliveryCursor)return C({outboxId:e.outboxId,status:"conflict",changes:0,replay:!1,deliveryCursor:a.delivery_cursor,reasonCode:"outbox-fail-conflict"});const r=Math.max(1,a.attempt_count??0,a.retry_count??0),s=Ue({nowIso:e.failedAt,attemptCount:r,reasonCode:e.reasonCode,summary:e.summary,nextRetryAt:e.nextRetryAt,policy:e.policy}),n=this.db.prepare(`
|
|
284
284
|
UPDATE outbox
|
|
285
285
|
SET status = ?,
|
|
286
286
|
retry_count = MAX(retry_count, ?),
|
|
@@ -293,7 +293,7 @@ import{Buffer as J}from"node:buffer";import{createHash as M}from"node:crypto";im
|
|
|
293
293
|
updated_at = ?
|
|
294
294
|
WHERE outbox_id = ?
|
|
295
295
|
AND status IN ('pending', 'sent', 'failed')
|
|
296
|
-
`).run(s.status,r,s.status==="failed"?s.nextRetryAt??e.failedAt:null,e.reasonCode,e.reasonCode,e.summary??null,s.status==="dead_letter"?e.summary??e.reasonCode:null,s.deadLetteredAt??null,e.failedAt,e.outboxId);return C({outboxId:e.outboxId,status:s.status,changes:n.changes,replay:!1,deliveryCursor:
|
|
296
|
+
`).run(s.status,r,s.status==="failed"?s.nextRetryAt??e.failedAt:null,e.reasonCode,e.reasonCode,e.summary??null,s.status==="dead_letter"?e.summary??e.reasonCode:null,s.deadLetteredAt??null,e.failedAt,e.outboxId);return C({outboxId:e.outboxId,status:s.status,changes:n.changes,replay:!1,deliveryCursor:a.delivery_cursor??e.deliveryCursor,reasonCode:s.reasonCode,...s.nextRetryAt?{nextRetryAt:s.nextRetryAt}:{},...s.deadLetteredAt?{deadLetteredAt:s.deadLetteredAt}:{}})})}catch(a){throw m(a,"sqlite-mutation-failed")}}deadLetterOutbox(e){this.assertCanMutate(),v({outboxId:e.outboxId,timestamp:e.deadLetteredAt,reasonCode:e.reasonCode,summary:e.summary});try{return this.runInTransaction(()=>{const a=this.getOutboxTransitionRow(e.outboxId);if(!a)return C({outboxId:e.outboxId,status:"missing",changes:0,replay:!1,reasonCode:"outbox-missing"});if(a.status==="dead_letter")return C({outboxId:e.outboxId,status:"dead_letter",changes:0,replay:!0,deliveryCursor:a.delivery_cursor??void 0,deadLetteredAt:a.dead_lettered_at??void 0,reasonCode:a.last_error_reason??a.last_error_code??e.reasonCode});const r=this.db.prepare(`
|
|
297
297
|
UPDATE outbox
|
|
298
298
|
SET status = 'dead_letter',
|
|
299
299
|
next_attempt_at = NULL,
|
|
@@ -305,13 +305,13 @@ import{Buffer as J}from"node:buffer";import{createHash as M}from"node:crypto";im
|
|
|
305
305
|
updated_at = ?
|
|
306
306
|
WHERE outbox_id = ?
|
|
307
307
|
AND status <> 'acked'
|
|
308
|
-
`).run(e.reasonCode,e.reasonCode,e.summary,e.summary,e.deadLetteredAt,e.deadLetteredAt,e.outboxId);return C({outboxId:e.outboxId,status:"dead_letter",changes:r.changes,replay:!1,deliveryCursor:
|
|
308
|
+
`).run(e.reasonCode,e.reasonCode,e.summary,e.summary,e.deadLetteredAt,e.deadLetteredAt,e.outboxId);return C({outboxId:e.outboxId,status:"dead_letter",changes:r.changes,replay:!1,deliveryCursor:a.delivery_cursor??void 0,deadLetteredAt:e.deadLetteredAt,reasonCode:e.reasonCode})})}catch(a){throw m(a,"sqlite-mutation-failed")}}retryOutboxEntries(e){this.assertCanMutate();const a=Math.max(1,Math.min(100,Math.floor(e.limit))),r=q(e.statuses?.length?e.statuses:["failed","dead_letter"]),s=e.reasonCode??"backoff-scheduled";b(s,"outbox.last_error_code"),b(e.nextAttemptAt,"outbox.next_attempt_at");try{return this.runInTransaction(()=>{const n=r.map(()=>"?").join(", "),o=this.db.prepare(`
|
|
309
309
|
SELECT outbox_id
|
|
310
310
|
FROM outbox
|
|
311
311
|
WHERE status IN (${n})
|
|
312
312
|
ORDER BY updated_at ASC, outbox_id ASC
|
|
313
313
|
LIMIT ?
|
|
314
|
-
`).all(...r,
|
|
314
|
+
`).all(...r,a).map(h=>h.outbox_id).filter(h=>typeof h=="string"&&h.length>0);if(o.length===0)return{retriedOutboxIds:[],changes:0,reasonCode:s,publicSafe:!0};const l=o.map(()=>"?").join(", "),I=this.db.prepare(`
|
|
315
315
|
UPDATE outbox
|
|
316
316
|
SET status = 'pending',
|
|
317
317
|
retry_count = retry_count + 1,
|
|
@@ -325,7 +325,7 @@ import{Buffer as J}from"node:buffer";import{createHash as M}from"node:crypto";im
|
|
|
325
325
|
dead_lettered_at = NULL,
|
|
326
326
|
updated_at = ?
|
|
327
327
|
WHERE outbox_id IN (${l})
|
|
328
|
-
`).run(e.nextAttemptAt??e.nowIso,s,s,e.nowIso,...o);return{retriedOutboxIds:o,changes:I.changes,reasonCode:s,publicSafe:!0}})}catch(n){throw m(n,"sqlite-mutation-failed")}}upsertGoalCampaign(e){this.assertCanMutate(),b(e.title,"goal_campaigns.title"),b(e.publicSummary,"goal_campaigns.public_summary");const
|
|
328
|
+
`).run(e.nextAttemptAt??e.nowIso,s,s,e.nowIso,...o);return{retriedOutboxIds:o,changes:I.changes,reasonCode:s,publicSafe:!0}})}catch(n){throw m(n,"sqlite-mutation-failed")}}upsertGoalCampaign(e){this.assertCanMutate(),b(e.title,"goal_campaigns.title"),b(e.publicSummary,"goal_campaigns.public_summary");const a=S(e.metadata);try{const r=this.db.prepare(`
|
|
329
329
|
INSERT INTO goal_campaigns (
|
|
330
330
|
campaign_id, job_id, status, title, public_summary, reason_code,
|
|
331
331
|
created_at, updated_at, operation_id, idempotency_key, metadata_json
|
|
@@ -339,7 +339,7 @@ import{Buffer as J}from"node:buffer";import{createHash as M}from"node:crypto";im
|
|
|
339
339
|
operation_id = excluded.operation_id,
|
|
340
340
|
idempotency_key = excluded.idempotency_key,
|
|
341
341
|
metadata_json = excluded.metadata_json
|
|
342
|
-
`).run(e.campaignId,e.jobId,e.status,e.title??null,e.publicSummary??null,e.reasonCode??null,e.createdAt,e.updatedAt,e.operationId??null,e.idempotencyKey??null,
|
|
342
|
+
`).run(e.campaignId,e.jobId,e.status,e.title??null,e.publicSummary??null,e.reasonCode??null,e.createdAt,e.updatedAt,e.operationId??null,e.idempotencyKey??null,a);return this.toWriteResult(r)}catch(r){throw m(r,"sqlite-mutation-failed")}}upsertGoalLedgerItem(e){this.assertCanMutate(),b(e.summary,"goal_ledger_items.summary");const a=S(e.metadata);try{this.ensureGoalCampaign(e.campaignId,e.jobId,e.createdAt,e.updatedAt);const r=this.db.prepare(`
|
|
343
343
|
INSERT INTO goal_ledger_items (
|
|
344
344
|
item_id, campaign_id, operation_id, idempotency_key, item_type, status,
|
|
345
345
|
summary, reason_code, created_at, updated_at, metadata_json
|
|
@@ -350,7 +350,7 @@ import{Buffer as J}from"node:buffer";import{createHash as M}from"node:crypto";im
|
|
|
350
350
|
reason_code = excluded.reason_code,
|
|
351
351
|
updated_at = excluded.updated_at,
|
|
352
352
|
metadata_json = excluded.metadata_json
|
|
353
|
-
`).run(e.itemId,e.campaignId,e.operationId??null,e.idempotencyKey??null,e.itemType,e.status,e.summary,e.reasonCode??null,e.createdAt,e.updatedAt,
|
|
353
|
+
`).run(e.itemId,e.campaignId,e.operationId??null,e.idempotencyKey??null,e.itemType,e.status,e.summary,e.reasonCode??null,e.createdAt,e.updatedAt,a);return this.toWriteResult(r)}catch(r){throw m(r,"sqlite-mutation-failed")}}upsertGoalVerifier(e){this.assertCanMutate(),b(e.summary,"goal_verifiers.summary");const a=S(e.metadata);try{const r=e.lastCheckedAt??this.now();this.ensureGoalCampaign(e.campaignId,e.jobId,r,r);const s=this.db.prepare(`
|
|
354
354
|
INSERT INTO goal_verifiers (
|
|
355
355
|
verifier_id, campaign_id, kind, status, summary, reason_code,
|
|
356
356
|
last_checked_at, operation_id, idempotency_key, metadata_json
|
|
@@ -361,7 +361,7 @@ import{Buffer as J}from"node:buffer";import{createHash as M}from"node:crypto";im
|
|
|
361
361
|
reason_code = excluded.reason_code,
|
|
362
362
|
last_checked_at = excluded.last_checked_at,
|
|
363
363
|
metadata_json = excluded.metadata_json
|
|
364
|
-
`).run(e.verifierId,e.campaignId,e.kind,e.status,e.summary??null,e.reasonCode??null,e.lastCheckedAt??null,e.operationId??null,e.idempotencyKey??null,
|
|
364
|
+
`).run(e.verifierId,e.campaignId,e.kind,e.status,e.summary??null,e.reasonCode??null,e.lastCheckedAt??null,e.operationId??null,e.idempotencyKey??null,a);return this.toWriteResult(s)}catch(r){throw m(r,"sqlite-mutation-failed")}}upsertGoalReviewGate(e){this.assertCanMutate(),b(e.summary,"goal_review_gates.summary");const a=S(e.metadata);try{const r=this.now();this.ensureGoalCampaign(e.campaignId,e.jobId,r,r);const s=this.db.prepare(`
|
|
365
365
|
INSERT INTO goal_review_gates (
|
|
366
366
|
gate_id, campaign_id, status, summary, required, reason_code,
|
|
367
367
|
operation_id, idempotency_key, metadata_json
|
|
@@ -372,7 +372,7 @@ import{Buffer as J}from"node:buffer";import{createHash as M}from"node:crypto";im
|
|
|
372
372
|
required = excluded.required,
|
|
373
373
|
reason_code = excluded.reason_code,
|
|
374
374
|
metadata_json = excluded.metadata_json
|
|
375
|
-
`).run(e.gateId,e.campaignId,e.status,e.summary??null,e.required?1:0,e.reasonCode??null,e.operationId??null,e.idempotencyKey??null,
|
|
375
|
+
`).run(e.gateId,e.campaignId,e.status,e.summary??null,e.required?1:0,e.reasonCode??null,e.operationId??null,e.idempotencyKey??null,a);return this.toWriteResult(s)}catch(r){throw m(r,"sqlite-mutation-failed")}}recordOperationAudit(e){return this.appendReceipt(e)}hasOperationRef(e,a){this.assertCanMutate();const r=["jobs","job_leases","job_events","job_receipts","goal_campaigns","goal_ledger_items","goal_verifiers","goal_review_gates","loop_jobs","artifacts","state_snapshots","headless_execution_attempts","runner_config","outbox"],s=r.map(o=>`SELECT 1 AS found FROM ${o} WHERE operation_id = ?${a?" OR idempotency_key = ?":""}`),n=r.flatMap(()=>a?[e,a]:[e]);return!!this.db.prepare(`${s.join(" UNION ALL ")} LIMIT 1`).get(...n)}jobExists(e){return!!this.db.prepare("SELECT 1 AS found FROM jobs WHERE job_id = ? LIMIT 1").get(e)}getHeadlessExecutionAttempt(e){return this.db.prepare(`
|
|
376
376
|
SELECT attempt_id, execution_id, job_id, directive_hash, directive_kind,
|
|
377
377
|
command_class, target_kind, target_ref, story_id, epic_id,
|
|
378
378
|
runtime_id, model_id, runtime_source, status, reason_code,
|
|
@@ -386,13 +386,13 @@ import{Buffer as J}from"node:buffer";import{createHash as M}from"node:crypto";im
|
|
|
386
386
|
FROM headless_execution_attempts
|
|
387
387
|
WHERE attempt_id = ?
|
|
388
388
|
LIMIT 1
|
|
389
|
-
`).get(e)}getOutboxTransitionRow(e){const
|
|
389
|
+
`).get(e)}getOutboxTransitionRow(e){const a=this.db.prepare(`
|
|
390
390
|
SELECT outbox_id, status, delivery_cursor, retry_count, attempt_count,
|
|
391
391
|
last_error_code, last_error_reason, dead_lettered_at
|
|
392
392
|
FROM outbox
|
|
393
393
|
WHERE outbox_id = ?
|
|
394
394
|
LIMIT 1
|
|
395
|
-
`).get(e);if(!(!
|
|
395
|
+
`).get(e);if(!(!a||!E(a)))return a}selectReceiptRetentionCandidates(e){return this.db.prepare(`
|
|
396
396
|
WITH sized AS (
|
|
397
397
|
SELECT receipt_id, job_id, status, reason_code, created_at,
|
|
398
398
|
length(receipt_id) + length(job_id) + length(status) + length(created_at)
|
|
@@ -430,13 +430,13 @@ import{Buffer as J}from"node:buffer";import{createHash as M}from"node:crypto";im
|
|
|
430
430
|
WHERE created_at < ? OR retain_rank > ? OR cumulative_bytes > ?
|
|
431
431
|
ORDER BY created_at ASC, event_id ASC
|
|
432
432
|
LIMIT ?
|
|
433
|
-
`).all(O,e.cutoff,e.maxItems,e.maxBytes,e.limit).flatMap(r=>typeof r.event_id!="string"||typeof r.job_id!="string"?[]:[{kind:"output",id:r.event_id,jobId:r.job_id,status:typeof r.type=="string"?r.type:O,reasonCode:typeof r.reason_code=="string"?r.reason_code:"continuity-ok",createdAt:typeof r.created_at=="string"?r.created_at:e.cutoff,approxBytes:typeof r.approx_bytes=="number"&&r.approx_bytes>=0?Math.floor(r.approx_bytes):0}])}deleteRetentionCandidates(e,
|
|
433
|
+
`).all(O,e.cutoff,e.maxItems,e.maxBytes,e.limit).flatMap(r=>typeof r.event_id!="string"||typeof r.job_id!="string"?[]:[{kind:"output",id:r.event_id,jobId:r.job_id,status:typeof r.type=="string"?r.type:O,reasonCode:typeof r.reason_code=="string"?r.reason_code:"continuity-ok",createdAt:typeof r.created_at=="string"?r.created_at:e.cutoff,approxBytes:typeof r.approx_bytes=="number"&&r.approx_bytes>=0?Math.floor(r.approx_bytes):0}])}deleteRetentionCandidates(e,a,r){if(r.length===0)return;const s=r.map(()=>"?").join(", ");this.db.prepare(`DELETE FROM ${e} WHERE ${a} IN (${s})`).run(...r)}preserveReceiptDerivedIteration(e,a){const r=this.db.prepare(`
|
|
434
434
|
SELECT COUNT(*) AS iteration
|
|
435
435
|
FROM job_receipts
|
|
436
436
|
WHERE job_id = ?
|
|
437
437
|
AND (operation_id LIKE 'tick-%' OR operation_id LIKE 'loop-tick-%')
|
|
438
438
|
AND status IN ('accepted', 'applied')
|
|
439
|
-
`).get(e),s=typeof r?.iteration=="number"?r.iteration:0;s>0&&this.recordJobStageProgress({jobId:e,iteration:s,at:
|
|
439
|
+
`).get(e),s=typeof r?.iteration=="number"?r.iteration:0;s>0&&this.recordJobStageProgress({jobId:e,iteration:s,at:a,appendHistory:!1})}retainedReceiptOutputCounts(e){const a=this.db.prepare(`
|
|
440
440
|
SELECT COUNT(*) AS count,
|
|
441
441
|
COALESCE(SUM(length(receipt_id) + length(job_id) + length(status) + length(created_at)
|
|
442
442
|
+ COALESCE(length(operation_id), 0) + COALESCE(length(idempotency_key), 0)
|
|
@@ -451,7 +451,7 @@ import{Buffer as J}from"node:buffer";import{createHash as M}from"node:crypto";im
|
|
|
451
451
|
+ COALESCE(length(reason_code), 0) + COALESCE(length(metadata_json), 0)), 0) AS bytes
|
|
452
452
|
FROM job_events
|
|
453
453
|
WHERE job_id = ? AND type = ?
|
|
454
|
-
`).get(e,O);return{receipts:typeof
|
|
454
|
+
`).get(e,O);return{receipts:typeof a?.count=="number"?a.count:0,outputs:typeof r?.count=="number"?r.count:0,bytes:(typeof a?.bytes=="number"?a.bytes:0)+(typeof r?.bytes=="number"?r.bytes:0)}}pruneReceiptCompactionSummaries(e,a){this.db.prepare(`
|
|
455
455
|
DELETE FROM job_events
|
|
456
456
|
WHERE event_id IN (
|
|
457
457
|
SELECT event_id
|
|
@@ -460,14 +460,14 @@ import{Buffer as J}from"node:buffer";import{createHash as M}from"node:crypto";im
|
|
|
460
460
|
ORDER BY created_at DESC, event_id DESC
|
|
461
461
|
LIMIT -1 OFFSET ?
|
|
462
462
|
)
|
|
463
|
-
`).run(e,W,
|
|
463
|
+
`).run(e,W,a)}runInTransaction(e){this.assertCanMutate();const a=this.db.transaction(e);try{return typeof a.immediate=="function"?a.immediate():a()}catch(r){throw m(r,"sqlite-mutation-failed")}}collectSnapshotRows(e){const a=(p,...x)=>{const A=this.db.prepare(p).get(...x);return E(A)&&typeof A.count=="number"?A.count:0},r=this.db.prepare(`
|
|
464
464
|
SELECT status, COUNT(*) AS count FROM outbox GROUP BY status
|
|
465
465
|
`).all(),s={};for(const p of r)typeof p.status=="string"&&typeof p.count=="number"&&(s[p.status]=p.count);const n=this.db.prepare(`
|
|
466
466
|
SELECT value_json
|
|
467
467
|
FROM runner_config
|
|
468
468
|
WHERE key = 'headless_queue_policy'
|
|
469
469
|
LIMIT 1
|
|
470
|
-
`).get();let d=De;if(E(n)&&typeof n.value_json=="string")try{const p=JSON.parse(n.value_json);E(p)&&typeof p.maxItems=="number"&&(d=B({maxItems:p.maxItems}))}catch{}const o=
|
|
470
|
+
`).get();let d=De;if(E(n)&&typeof n.value_json=="string")try{const p=JSON.parse(n.value_json);E(p)&&typeof p.maxItems=="number"&&(d=B({maxItems:p.maxItems}))}catch{}const o=a("SELECT COUNT(*) AS count FROM headless_execution_attempts WHERE status = 'queued' AND dead_lettered_at IS NULL"),l=a("SELECT COUNT(*) AS count FROM headless_execution_attempts WHERE status = 'backoff' AND dead_lettered_at IS NULL"),I=a("SELECT COUNT(*) AS count FROM headless_execution_attempts WHERE status = 'running' AND dead_lettered_at IS NULL"),h=a("SELECT COUNT(*) AS count FROM headless_execution_attempts WHERE dead_lettered_at IS NOT NULL"),f=o+l+I,_=this.db.prepare(`
|
|
471
471
|
SELECT MIN(next_retry_at) AS next_retry_at
|
|
472
472
|
FROM headless_execution_attempts
|
|
473
473
|
WHERE status = 'backoff'
|
|
@@ -557,19 +557,19 @@ import{Buffer as J}from"node:buffer";import{createHash as M}from"node:crypto";im
|
|
|
557
557
|
FROM headless_execution_attempts
|
|
558
558
|
ORDER BY enqueued_at DESC, attempt_id ASC
|
|
559
559
|
LIMIT ?
|
|
560
|
-
`).all(e.jobLimit),counts:{jobs:
|
|
560
|
+
`).all(e.jobLimit),counts:{jobs:a("SELECT COUNT(*) AS count FROM jobs"),activeJobs:a("SELECT COUNT(*) AS count FROM jobs WHERE status IN ('planned', 'active', 'running', 'waiting_external', 'waiting_human', 'backoff', 'paused', 'blocked')"),activeLeases:a("SELECT COUNT(*) AS count FROM job_leases WHERE released_at IS NULL"),dueJobs:a("SELECT COUNT(*) AS count FROM jobs WHERE next_run_at IS NOT NULL AND next_run_at <= ? AND status NOT IN ('completed', 'aborted', 'cancelled')",e.nowIso),staleLeases:a("SELECT COUNT(*) AS count FROM job_leases WHERE released_at IS NULL AND expires_at <= ?",e.nowIso),receipts:a("SELECT COUNT(*) AS count FROM job_receipts"),events:a("SELECT COUNT(*) AS count FROM job_events"),processingOutputSummaries:a("SELECT COUNT(*) AS count FROM job_events WHERE type = ?",O),goalLedgerItems:a("SELECT COUNT(*) AS count FROM goal_ledger_items"),goalVerifiers:a("SELECT COUNT(*) AS count FROM goal_verifiers"),goalReviewGates:a("SELECT COUNT(*) AS count FROM goal_review_gates"),stateSnapshots:a("SELECT COUNT(*) AS count FROM state_snapshots"),headlessExecutionAttempts:a("SELECT COUNT(*) AS count FROM headless_execution_attempts"),headlessQueuedAttempts:a("SELECT COUNT(*) AS count FROM headless_execution_attempts WHERE status IN ('queued', 'backoff')"),headlessRunningAttempts:a("SELECT COUNT(*) AS count FROM headless_execution_attempts WHERE status = 'running'"),headlessRetryingAttempts:l,headlessDeadLetterAttempts:h,staleHeadlessExecutionAttempts:a("SELECT COUNT(*) AS count FROM headless_execution_attempts WHERE status = 'running' AND lease_released_at IS NULL AND lease_expires_at <= ?",e.nowIso),outbox:a("SELECT COUNT(*) AS count FROM outbox")},outboxCounts:s,queue:{depth:f,queued:o,running:I,retrying:l,deadLetter:h,capacity:d.maxItems,available:Math.max(0,d.maxItems-f),backpressure:f>=d.maxItems,generatedAt:e.nowIso,...u?{nextRetryAt:u}:{},...f>=d.maxItems?{reasonCode:k.CAP_REACHED}:{},publicSafe:!0}}}listProcessingOutputSummaries(e={}){const a=he(e.limit),r=pe(e),s=`
|
|
561
561
|
SELECT event_id, job_id, operation_id, summary, reason_code, created_at, metadata_json
|
|
562
562
|
FROM job_events
|
|
563
563
|
WHERE type = ?${r.sql}
|
|
564
564
|
ORDER BY created_at DESC, event_id DESC
|
|
565
565
|
LIMIT ?
|
|
566
|
-
`;return this.db.prepare(`SELECT * FROM (${s}) ORDER BY created_at ASC, event_id ASC`).all(O,...r.params,
|
|
566
|
+
`;return this.db.prepare(`SELECT * FROM (${s}) ORDER BY created_at ASC, event_id ASC`).all(O,...r.params,a).map(be)}pollProcessingOutputSummaries(e={}){const a=he(e.limit),r=lt(e.cursor),s=pe(e),n=r?" AND (created_at > ? OR (created_at = ? AND event_id > ?))":"",d=`
|
|
567
567
|
SELECT event_id, job_id, operation_id, summary, reason_code, created_at, metadata_json
|
|
568
568
|
FROM job_events
|
|
569
569
|
WHERE type = ?${s.sql}${n}
|
|
570
570
|
ORDER BY created_at ASC, event_id ASC
|
|
571
571
|
LIMIT ?
|
|
572
|
-
`,o=[O];o.push(...s.params),r&&o.push(r.createdAt,r.createdAt,r.eventId),o.push(
|
|
572
|
+
`,o=[O];o.push(...s.params),r&&o.push(r.createdAt,r.createdAt,r.eventId),o.push(a+1);const l=this.db.prepare(d).all(...o),I=l.slice(0,a).map(be),h=I[I.length-1];return{summaries:I,...h?{nextCursor:h.cursor}:e.cursor?{nextCursor:e.cursor}:{},hasMore:l.length>a,publicSafe:!0}}listDueJobs(e){const a=Math.max(1,Math.min(50,Math.floor(e.limit)));return this.db.prepare(`
|
|
573
573
|
SELECT j.job_id, j.kind, j.status, j.summary, j.reason_code, j.created_at,
|
|
574
574
|
j.updated_at, j.next_run_at, j.metadata_json,
|
|
575
575
|
(SELECT COUNT(*)
|
|
@@ -587,19 +587,19 @@ import{Buffer as J}from"node:buffer";import{createHash as M}from"node:crypto";im
|
|
|
587
587
|
AND j.status NOT IN ('waiting_external', 'waiting_human', 'paused', 'blocked', 'completed', 'aborted', 'cancelled')
|
|
588
588
|
ORDER BY j.next_run_at ASC, j.job_id ASC
|
|
589
589
|
LIMIT ?
|
|
590
|
-
`).all(e.nowIso,
|
|
590
|
+
`).all(e.nowIso,a)}recoverStaleLeases(e){this.assertCanMutate();const a=Date.parse(e.nowIso);if(!Number.isFinite(a))throw new i("sqlite-public-safety-rejected","Continuity SQLite stale lease recovery received an invalid timestamp.");const r=Math.max(0,Math.floor(e.staleAfterMs)),s=Math.max(1,Math.min(100,Math.floor(e.limit))),n=new Date(a-r).toISOString();try{return this.runInTransaction(()=>{const o=this.db.prepare(`
|
|
591
591
|
SELECT lease_id
|
|
592
592
|
FROM job_leases
|
|
593
593
|
WHERE released_at IS NULL
|
|
594
594
|
AND expires_at <= ?
|
|
595
595
|
ORDER BY expires_at ASC, lease_id ASC
|
|
596
596
|
LIMIT ?
|
|
597
|
-
`).all(n,s).map(
|
|
597
|
+
`).all(n,s).map(h=>h.lease_id).filter(h=>typeof h=="string"&&h.length>0);if(o.length===0)return{recoveredLeaseIds:[],safeExpiredAtOrBefore:n,changes:0};const l=o.map(()=>"?").join(", "),I=this.db.prepare(`
|
|
598
598
|
UPDATE job_leases
|
|
599
599
|
SET status = 'expired', released_at = ?
|
|
600
600
|
WHERE released_at IS NULL
|
|
601
601
|
AND lease_id IN (${l})
|
|
602
|
-
`).run(e.nowIso,...o);return{recoveredLeaseIds:o,safeExpiredAtOrBefore:n,changes:I.changes}})}catch(d){throw m(d,"sqlite-mutation-failed")}}recoverStaleHeadlessExecutionAttempts(e){this.assertCanMutate();const
|
|
602
|
+
`).run(e.nowIso,...o);return{recoveredLeaseIds:o,safeExpiredAtOrBefore:n,changes:I.changes}})}catch(d){throw m(d,"sqlite-mutation-failed")}}recoverStaleHeadlessExecutionAttempts(e){this.assertCanMutate();const a=Date.parse(e.nowIso);if(!Number.isFinite(a))throw new i("sqlite-public-safety-rejected","Continuity SQLite headless stale recovery received an invalid timestamp.");const r=Math.max(0,Math.floor(e.staleAfterMs)),s=Math.max(1,Math.min(100,Math.floor(e.limit))),n=new Date(a-r).toISOString();try{return this.runInTransaction(()=>{const d=this.db.prepare(`
|
|
603
603
|
SELECT attempt_id, retry_count, max_attempts, attempt_count
|
|
604
604
|
FROM headless_execution_attempts
|
|
605
605
|
WHERE status = 'running'
|
|
@@ -607,7 +607,7 @@ import{Buffer as J}from"node:buffer";import{createHash as M}from"node:crypto";im
|
|
|
607
607
|
AND lease_expires_at <= ?
|
|
608
608
|
ORDER BY lease_expires_at ASC, attempt_id ASC
|
|
609
609
|
LIMIT ?
|
|
610
|
-
`).all(n,s),o=[],l=[],I=B(e.policy);for(const _ of d){if(typeof _.attempt_id!="string"||_.attempt_id.length===0)continue;const u=typeof _.retry_count=="number"?_.retry_count:0,p=typeof _.max_attempts=="number"?_.max_attempts:1,x=typeof _.attempt_count=="number"?_.attempt_count:0;Math.max(x,u+1)>=p?l.push(_.attempt_id):o.push({attemptId:_.attempt_id,nextRetryAt:
|
|
610
|
+
`).all(n,s),o=[],l=[],I=B(e.policy);for(const _ of d){if(typeof _.attempt_id!="string"||_.attempt_id.length===0)continue;const u=typeof _.retry_count=="number"?_.retry_count:0,p=typeof _.max_attempts=="number"?_.max_attempts:1,x=typeof _.attempt_count=="number"?_.attempt_count:0;Math.max(x,u+1)>=p?l.push(_.attempt_id):o.push({attemptId:_.attempt_id,nextRetryAt:we(e.nowIso,u+1,I)})}let h=0;for(const _ of o)h+=this.db.prepare(`
|
|
611
611
|
UPDATE headless_execution_attempts
|
|
612
612
|
SET status = 'backoff',
|
|
613
613
|
retry_count = retry_count + 1,
|
|
@@ -618,7 +618,7 @@ import{Buffer as J}from"node:buffer";import{createHash as M}from"node:crypto";im
|
|
|
618
618
|
WHERE attempt_id = ?
|
|
619
619
|
AND status = 'running'
|
|
620
620
|
AND lease_released_at IS NULL
|
|
621
|
-
`).run(k.LEASE_TIMEOUT_RETRY,e.nowIso,_.nextRetryAt,_.nextRetryAt,_.attemptId).changes;if(l.length>0){const _=l.map(()=>"?").join(", ");
|
|
621
|
+
`).run(k.LEASE_TIMEOUT_RETRY,e.nowIso,_.nextRetryAt,_.nextRetryAt,_.attemptId).changes;if(l.length>0){const _=l.map(()=>"?").join(", ");h+=this.db.prepare(`
|
|
622
622
|
UPDATE headless_execution_attempts
|
|
623
623
|
SET status = 'failed',
|
|
624
624
|
retry_count = retry_count + 1,
|
|
@@ -631,15 +631,15 @@ import{Buffer as J}from"node:buffer";import{createHash as M}from"node:crypto";im
|
|
|
631
631
|
WHERE attempt_id IN (${_})
|
|
632
632
|
AND status = 'running'
|
|
633
633
|
AND lease_released_at IS NULL
|
|
634
|
-
`).run(k.ATTEMPTS_EXHAUSTED,e.nowIso,e.nowIso,e.nowIso,k.ATTEMPTS_EXHAUSTED,...l).changes}const f=o.map(_=>_.attemptId);return{recoveredAttemptIds:[...f,...l],failedAttemptIds:l,retryingAttemptIds:f,deadLetteredAttemptIds:l,safeExpiredAtOrBefore:n,changes:
|
|
634
|
+
`).run(k.ATTEMPTS_EXHAUSTED,e.nowIso,e.nowIso,e.nowIso,k.ATTEMPTS_EXHAUSTED,...l).changes}const f=o.map(_=>_.attemptId);return{recoveredAttemptIds:[...f,...l],failedAttemptIds:l,retryingAttemptIds:f,deadLetteredAttemptIds:l,safeExpiredAtOrBefore:n,changes:h,publicSafe:!0}})}catch(d){throw m(d,"sqlite-mutation-failed")}}ensureGoalCampaign(e,a,r,s){this.db.prepare(`
|
|
635
635
|
INSERT OR IGNORE INTO goal_campaigns (
|
|
636
636
|
campaign_id, job_id, status, public_summary, created_at, updated_at
|
|
637
637
|
) VALUES (?, ?, 'active', 'Public goal campaign summary unavailable', ?, ?)
|
|
638
|
-
`).run(e,
|
|
638
|
+
`).run(e,a,r,s)}configureConnection(){const e=String(U(this.db.pragma("journal_mode = WAL",{simple:!0}))??"").toLowerCase();if(e!=="wal")throw new i("sqlite-migration-failed",`Continuity SQLite journal_mode did not switch to WAL (observed ${e||"unknown"}).`);if(this.db.pragma("foreign_keys = ON"),this.db.pragma(`busy_timeout = ${this.busyTimeoutMs}`),Number(U(this.db.pragma("foreign_keys",{simple:!0}))??0)!==1)throw new i("sqlite-migration-failed","Continuity SQLite foreign_keys pragma is not enabled.")}ensureMigrationTable(){this.db.exec(`
|
|
639
639
|
CREATE TABLE IF NOT EXISTS continuity_migrations (
|
|
640
640
|
version INTEGER PRIMARY KEY,
|
|
641
641
|
name TEXT NOT NULL,
|
|
642
642
|
checksum TEXT NOT NULL,
|
|
643
643
|
applied_at TEXT NOT NULL
|
|
644
644
|
);
|
|
645
|
-
`)}applyMigrations(){this.db.transaction(()=>{for(const
|
|
645
|
+
`)}applyMigrations(){this.db.transaction(()=>{for(const a of Je){const r=st(a.sql),s=this.db.prepare("SELECT version, name, checksum FROM continuity_migrations WHERE version = ?").get(a.version);if(s){if(s.checksum!==r||s.name!==a.name)throw new i("sqlite-migration-conflict",`Continuity SQLite migration ${a.version} checksum conflict.`);continue}this.db.exec(a.sql),this.db.prepare("INSERT INTO continuity_migrations (version, name, checksum, applied_at) VALUES (?, ?, ?, ?)").run(a.version,a.name,r,this.now()),this.db.pragma(`user_version = ${a.version}`)}})()}assertCanMutate(){if(this.mutationBlocked)throw new i("sqlite-mutation-blocked","Continuity SQLite mutation is blocked after integrity failure.",{mutationBlocked:!0})}toWriteResult(e){const a=e.changes>0;return{inserted:a,replay:!a,changes:e.changes}}}export{O as CONTINUITY_PROCESSING_OUTPUT_SUMMARY_EVENT_TYPE,Be as CONTINUITY_PROCESSING_OUTPUT_SUMMARY_MAX_CHARS,Ye as CONTINUITY_PUBLIC_STAGES,We as CONTINUITY_SQLITE_FILENAME,ne as CONTINUITY_SQLITE_RELATIVE_DIR,Dt as CONTINUITY_SQLITE_SCHEMA_VERSION,ce as CONTINUITY_STAGE_HISTORY_MAX,Ct as ContinuitySqliteStore,i as ContinuitySqliteStoreError,de as DEFAULT_CONTINUITY_PROCESSING_SUMMARY_LIMIT,Fe as DEFAULT_CONTINUITY_SQLITE_BUSY_TIMEOUT_MS,$e as MAX_CONTINUITY_PROCESSING_SUMMARY_LIMIT,ie as SQLITE_ADAPTER_INSTALL_GUIDANCE,Ie as continuitySqliteStorePath,Ut as inspectEpicOperationalSqliteBinding,le as isContinuityPublicStage,Et as loadBetterSqlite3Adapter,Ge as normalizeContinuityStageIteration,ft as openContinuitySqliteReadOnly,wt as openContinuitySqliteStore,Qe as sanitizeContinuityStageHistory,ue as sanitizeContinuityStageTimestamp};
|