@ornexus/neocortex 4.60.18 → 4.60.19
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/sbom.cdx.json +6504 -6410
- package/docs/install/installer-diagnostics.md +52 -0
- package/install.ps1 +1 -1
- package/install.sh +1 -1
- package/package.json +27 -4
- package/packages/client/dist/agent/refresh-stubs.d.ts +7 -0
- package/packages/client/dist/agent/refresh-stubs.js +2 -2
- package/packages/client/dist/cache/encrypted-cache.d.ts +3 -0
- package/packages/client/dist/cache/encrypted-cache.js +1 -1
- package/packages/client/dist/checkpoint/checkpoint-client-reader.js +2 -2
- package/packages/client/dist/cli.js +3 -3
- package/packages/client/dist/commands/activate.js +7 -7
- package/packages/client/dist/commands/config.js +1 -1
- package/packages/client/dist/commands/invoke.d.ts +64 -0
- package/packages/client/dist/commands/invoke.js +54 -47
- package/packages/client/dist/config/secure-config.d.ts +9 -3
- package/packages/client/dist/config/secure-config.js +8 -8
- package/packages/client/dist/config.d.ts +1 -1
- package/packages/client/dist/config.js +1 -1
- package/packages/client/dist/continuity/continuity-client-state-store.d.ts +1 -0
- package/packages/client/dist/continuity/continuity-client-state-store.js +1 -1
- package/packages/client/dist/continuity/invoke-hooks.d.ts +2 -1
- package/packages/client/dist/continuity/invoke-hooks.js +1 -1
- package/packages/client/dist/continuity/sqlite-store.d.ts +21 -0
- package/packages/client/dist/continuity/sqlite-store.js +49 -49
- package/packages/client/dist/effects/invoke-effect-gateways.d.ts +22 -0
- package/packages/client/dist/effects/invoke-effect-gateways.js +1 -0
- package/packages/client/dist/errors/frontmatter-diagnostics.d.ts +20 -0
- package/packages/client/dist/errors/frontmatter-diagnostics.js +1 -0
- package/packages/client/dist/generated/command-registry.generated.d.ts +2836 -0
- package/packages/client/dist/generated/command-registry.generated.js +1 -0
- package/packages/client/dist/graph-retrieval/pre-command-hook.d.ts +2 -0
- package/packages/client/dist/graph-retrieval/pre-command-hook.js +1 -1
- package/packages/client/dist/index.d.ts +1 -0
- package/packages/client/dist/index.js +1 -1
- package/packages/client/dist/license/license-client.d.ts +3 -0
- package/packages/client/dist/license/license-client.js +1 -1
- package/packages/client/dist/machine/fingerprint.d.ts +3 -1
- package/packages/client/dist/machine/fingerprint.js +2 -2
- package/packages/client/dist/memory/project-memory-writer.js +19 -15
- package/packages/client/dist/{subagent-approval-policy.d.ts → policy/subagent-approval-policy.d.ts} +8 -3
- package/packages/client/dist/policy/subagent-approval-policy.js +1 -0
- package/packages/client/dist/resolvers/local-resolver.d.ts +3 -0
- package/packages/client/dist/resolvers/local-resolver.js +4 -4
- package/packages/client/dist/runner/cli.d.ts +1 -0
- package/packages/client/dist/runner/cli.js +1 -1
- package/packages/client/dist/runner/headless/prepared-story-bundle.d.ts +20 -0
- package/packages/client/dist/runner/headless/prepared-story-bundle.js +1 -0
- package/packages/client/dist/runner/headless/run-yoloop.d.ts +2 -0
- package/packages/client/dist/runner/headless/run-yoloop.js +1 -1
- package/packages/client/dist/runner/portal-sync-worker.js +1 -1
- package/packages/client/dist/runner/scheduler.d.ts +3 -0
- package/packages/client/dist/runner/scheduler.js +7 -7
- package/packages/client/dist/state/project-state-snapshot.js +1 -1
- package/packages/client/dist/tier/tier-aware-client.js +1 -1
- package/packages/client/dist/version.d.ts +3 -0
- package/packages/client/dist/version.js +1 -0
- package/packages/client/dist/yoloop/discovery-hook.js +2 -2
- package/packages/client/dist/yoloop/invoke-hooks.js +4 -4
- package/packages/client/dist/yoloop/shared-discover-epics.d.ts +9 -3
- package/packages/client/dist/yoloop/shared-discover-epics.js +1 -1
- package/packages/client/dist/yoloop/shared-yoloop-types.d.ts +24 -0
- package/packages/client/dist/yoloop/target-normalization.d.ts +24 -0
- package/packages/client/dist/yoloop/target-normalization.js +1 -0
- package/packages/client/dist/yoloop/yoloop-client-state-store.d.ts +4 -0
- package/packages/client/dist/yoloop/yoloop-client-state-store.js +1 -1
- package/packages/shared/dist/command-registry-contract.js +382 -0
- package/packages/shared/dist/generated/command-registry.generated.js +4216 -0
- package/packages/shared/dist/generated/invocation-schema.generated.js +1850 -0
- package/packages/shared/dist/invocation/index.d.ts +175 -0
- package/packages/shared/dist/invocation/index.js +587 -0
- package/packages/shared/dist/nx-invoke-signature.js +233 -0
- package/packages/shared/dist/strict-readonly.js +381 -0
- package/packages/shared/dist/yoloop/wave-decision-receipt.js +77 -0
- 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 +5 -2
- package/targets-stubs/claude-code/neocortex.agent.yaml +1 -1
- package/targets-stubs/claude-code/neocortex.md +7 -2
- package/targets-stubs/codex/AGENTS.md +4 -1
- package/targets-stubs/codex/neocortex.toml +4 -0
- package/targets-stubs/cursor/agent.md +2 -2
- package/targets-stubs/gemini-cli/agent.md +2 -2
- package/targets-stubs/opencode/neocortex-root.md +4 -1
- package/targets-stubs/opencode/neocortex.md +3 -0
- package/targets-stubs/vscode/neocortex.agent.md +2 -2
- package/packages/client/dist/subagent-approval-policy.js +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import{Buffer as z}from"node:buffer";import{createHash as M}from"node:crypto";import{chmodSync as X,existsSync as ye,mkdirSync as Ie}from"node:fs";import{join as Z}from"node:path";import{INITIAL_CONTINUITY_SQLITE_MIGRATION as Ee}from"./migrations/001-initial-schema.js";import{PROCESSING_OUTPUT_SUMMARY_SQLITE_MIGRATION as be}from"./migrations/002-processing-output-summary-indexes.js";import{HEADLESS_EXECUTION_ATTEMPTS_SQLITE_MIGRATION as he}from"./migrations/003-headless-execution-attempts.js";import{OUTBOX_DELIVERY_STATE_SQLITE_MIGRATION as pe}from"./migrations/004-outbox-delivery-state.js";import{BOUNDED_HEADLESS_QUEUE_SQLITE_MIGRATION as Ce}from"./migrations/005-bounded-headless-queue.js";import{CONTINUITY_QUEUE_REASON_CODES as U,CONTINUITY_RECEIPT_COMPACTION_EVENT_TYPE as H,CONTINUITY_RECEIPT_RETENTION_REASON_CODES as W,DEFAULT_CONTINUITY_QUEUE_POLICY as fe,computeContinuityQueueRetryAt as Se,computeContinuityOutboxFailureDecision as Ae,normalizeContinuityQueuePolicy as F,normalizeContinuityQueuePriority as ge,normalizeContinuityQueueScope as xe,normalizeContinuityRetentionPolicy as Re}from"./outbox.js";const ee=".neocortex/continuity",Oe="continuity.sqlite",Ct=5,Te=5e3,O="processing_output_summary",Ne=2e3,te=20,Le=100,ae="Install the optional Enterprise continuity SQLite adapter with `npm install --workspace packages/client better-sqlite3 --include=optional` or reinstall Neocortex with optional dependencies enabled.",je=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"]),re=20,ve=new Set(je),Me=/^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}(?::\d{2}(?:\.\d{1,6})?)?(?:Z|[+-]\d{2}:?\d{2})?$/;function se(t){return typeof t=="string"&&ve.has(t)}function oe(t){if(typeof t!="string")return;const e=t.trim();if(!(e.length===0||e.length>40)&&Me.test(e))return e}function Ue(t){if(!Array.isArray(t))return[];const e=[];for(const a of t){if(!h(a)||!se(a.stage))continue;const r=oe(a.at);r&&e.push({stage:a.stage,at:r})}return e.slice(-re)}function De(t){if(!(typeof t!="number"||!Number.isFinite(t)||t<0))return Math.floor(t)}class _ 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"}}const ke=[Ee,be,he,pe,Ce],qe=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"]),de=/(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,ne=/(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,we=new Set(["unsafe_key","raw_log","prompt_body","private_url","local_absolute_path","secret","protected_field","unbounded_text","unbounded_number","unknown_required_operation","missing"]),Pe=/(corrupt|malformed|not a database|file is not a database|database disk image is malformed)/i,He=/(foreign key constraint failed|SQLITE_CONSTRAINT_FOREIGNKEY)/i,V="p185:v1:",We=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","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"]),Fe=new Set(["foreground_invoke","scheduled_tick","runner_tick","manual_tick","headless_execution","jobs_command","invoke_watch","portal_render"]);function $e(t){return new Function("specifier","return import(specifier)")(t)}function Be(t){return`sha256:${M("sha256").update(t).digest("hex")}`}function h(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}function Ye(t){return t instanceof Error?t.message:String(t)}function Ke(t){return h(t)&&typeof t.code=="string"?t.code:void 0}function m(t,e){if(t instanceof _)return t;const a=Ye(t),r=Ke(t);return r==="SQLITE_CORRUPT"||r==="SQLITE_NOTADB"||Pe.test(a)?new _("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"||He.test(a)?new _("sqlite-foreign-key-failed","Continuity SQLite foreign-key validation failed; mutation was rejected.",{cause:t}):new _(e,a,{cause:t})}function A(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)&&we.has(t))return;if(ne.test(t))throw new _("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)=>A(a,`${e}[${r}]`));return}if(h(t)){for(const[a,r]of Object.entries(t)){if(de.test(a))throw new _("sqlite-public-safety-rejected",`Continuity SQLite metadata rejected unsafe key at ${e}.${a}.`);A(r,`${e}.${a}`)}return}throw new _("sqlite-public-safety-rejected",`Continuity SQLite metadata rejected unsupported value at ${e}.`)}}function b(t,e){if(t!==void 0&&ne.test(t))throw new _("sqlite-public-safety-rejected",`Continuity SQLite text rejected unsafe value at ${e}.`)}function $(t,e,a=240){if(t.trim().length===0)throw new _("sqlite-public-safety-rejected",`Continuity SQLite processing summary text is required at ${e}.`);if(b(t,e),t.length>a)throw new _("sqlite-public-safety-rejected",`Continuity SQLite processing summary text exceeded the public bound at ${e}.`)}function B(t){const e={};if(!t)return e;for(const[a,r]of Object.entries(t))if(We.has(a)&&!de.test(a))try{A(r,`metadata.${a}`),e[a]=r}catch{}return e}function Je(t){const e={...B(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&&Fe.has(t.source)&&(e.processingOutputSource=t.source),B(e)}function ie(t){const e=Math.floor(t??te);return Number.isFinite(e)?Math.max(1,Math.min(Le,e)):te}function Qe(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 Ve(t){return`${V}${z.from(JSON.stringify([t.created_at,t.event_id]),"utf8").toString("base64url")}`}function Ge(t){if(t?.startsWith(V))try{const e=t.slice(V.length),a=JSON.parse(z.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 ce(t){return t?q(t.map(e=>D("job",e)).filter(e=>!!e)):[]}function ue(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=ce(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=ce(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 le(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:Ve(e)}}function S(t){return t?(A(t,"metadata"),JSON.stringify(t)):null}function ze(t,e,a){const r=i=>`sha256:${M("sha256").update(i.map(n=>[n.id,n.status,n.reasonCode].join(":")).sort().join(`
|
|
2
|
-
`)).digest("hex")}`,s=r(e),
|
|
1
|
+
import{Buffer as V}from"node:buffer";import{createHash as M}from"node:crypto";import{chmodSync as X,closeSync as Ee,existsSync as Z,mkdirSync as pe,openSync as fe,readSync as Ce}from"node:fs";import{join as ee}from"node:path";import{INITIAL_CONTINUITY_SQLITE_MIGRATION as Se}from"./migrations/001-initial-schema.js";import{PROCESSING_OUTPUT_SUMMARY_SQLITE_MIGRATION as Ae}from"./migrations/002-processing-output-summary-indexes.js";import{HEADLESS_EXECUTION_ATTEMPTS_SQLITE_MIGRATION as ge}from"./migrations/003-headless-execution-attempts.js";import{OUTBOX_DELIVERY_STATE_SQLITE_MIGRATION as xe}from"./migrations/004-outbox-delivery-state.js";import{BOUNDED_HEADLESS_QUEUE_SQLITE_MIGRATION as Re}from"./migrations/005-bounded-headless-queue.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 Oe,computeContinuityQueueRetryAt as Te,computeContinuityOutboxFailureDecision as Ne,normalizeContinuityQueuePolicy as B,normalizeContinuityQueuePriority as Le,normalizeContinuityQueueScope as je,normalizeContinuityRetentionPolicy as ve}from"./outbox.js";const te=".neocortex/continuity",Me="continuity.sqlite",gt=5,ke=5e3,O="processing_output_summary",Ue=2e3,ae=20,De=100,re="Install the optional Enterprise continuity SQLite adapter with `npm install --workspace packages/client better-sqlite3 --include=optional` or reinstall Neocortex with optional dependencies enabled.",we=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"]),se=20,qe=new Set(we),Pe=/^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}(?::\d{2}(?:\.\d{1,6})?)?(?:Z|[+-]\d{2}:?\d{2})?$/;function oe(t){return typeof t=="string"&&qe.has(t)}function de(t){if(typeof t!="string")return;const e=t.trim();if(!(e.length===0||e.length>40)&&Pe.test(e))return e}function He(t){if(!Array.isArray(t))return[];const e=[];for(const a of t){if(!E(a)||!oe(a.stage))continue;const r=de(a.at);r&&e.push({stage:a.stage,at:r})}return e.slice(-se)}function We(t){if(!(typeof t!="number"||!Number.isFinite(t)||t<0))return Math.floor(t)}class l 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"}}const Fe=[Se,Ae,ge,xe,Re],Be=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"]),ne=/(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,ie=/(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,$e=new Set(["unsafe_key","raw_log","prompt_body","private_url","local_absolute_path","secret","protected_field","unbounded_text","unbounded_number","unknown_required_operation","missing"]),Ye=/(corrupt|malformed|not a database|file is not a database|database disk image is malformed)/i,Ke=/(foreign key constraint failed|SQLITE_CONSTRAINT_FOREIGNKEY)/i,G="p185:v1:",Qe=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","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"]),Je=new Set(["foreground_invoke","scheduled_tick","runner_tick","manual_tick","headless_execution","jobs_command","invoke_watch","portal_render"]);function Ve(t){return import(t)}function Ge(t){return`sha256:${M("sha256").update(t).digest("hex")}`}function E(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}function ze(t){return t instanceof Error?t.message:String(t)}function Xe(t){return E(t)&&typeof t.code=="string"?t.code:void 0}function m(t,e){if(t instanceof l)return t;const a=ze(t),r=Xe(t);return r==="SQLITE_CORRUPT"||r==="SQLITE_NOTADB"||Ye.test(a)?new l("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"||Ke.test(a)?new l("sqlite-foreign-key-failed","Continuity SQLite foreign-key validation failed; mutation was rejected.",{cause:t}):new l(e,a,{cause:t})}function A(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)&&$e.has(t))return;if(ie.test(t))throw new l("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)=>A(a,`${e}[${r}]`));return}if(E(t)){for(const[a,r]of Object.entries(t)){if(ne.test(a))throw new l("sqlite-public-safety-rejected",`Continuity SQLite metadata rejected unsafe key at ${e}.${a}.`);A(r,`${e}.${a}`)}return}throw new l("sqlite-public-safety-rejected",`Continuity SQLite metadata rejected unsupported value at ${e}.`)}}function b(t,e){if(t!==void 0&&ie.test(t))throw new l("sqlite-public-safety-rejected",`Continuity SQLite text rejected unsafe value at ${e}.`)}function $(t,e,a=240){if(t.trim().length===0)throw new l("sqlite-public-safety-rejected",`Continuity SQLite processing summary text is required at ${e}.`);if(b(t,e),t.length>a)throw new l("sqlite-public-safety-rejected",`Continuity SQLite processing summary text exceeded the public bound at ${e}.`)}function Y(t){const e={};if(!t)return e;for(const[a,r]of Object.entries(t))if(Qe.has(a)&&!ne.test(a))try{A(r,`metadata.${a}`),e[a]=r}catch{}return e}function Ze(t){const e={...Y(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&&Je.has(t.source)&&(e.processingOutputSource=t.source),Y(e)}function ce(t){const e=Math.floor(t??ae);return Number.isFinite(e)?Math.max(1,Math.min(De,e)):ae}function et(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 tt(t){return`${G}${V.from(JSON.stringify([t.created_at,t.event_id]),"utf8").toString("base64url")}`}function at(t){if(t?.startsWith(G))try{const e=t.slice(G.length),a=JSON.parse(V.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 U(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 ue(t){return t?q(t.map(e=>U("job",e)).filter(e=>!!e)):[]}function le(t){const e=t.target;if(!e){const r=U("job",t.jobId);return r?{sql:" AND job_id = ?",params:[r]}:{sql:"",params:[]}}const a=e.selectorKind;if(a==="job"){const r=U("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=U("goal",e.goalId??e.targetId);if(!r)return{sql:" AND 1 = 0",params:[]};const s=ue(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=U("loop",e.loopId??e.targetId);if(!r)return{sql:" AND 1 = 0",params:[]};const s=ue(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 _e(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:tt(e)}}function S(t){return t?(A(t,"metadata"),JSON.stringify(t)):null}function rt(t,e,a){const r=n=>`sha256:${M("sha256").update(n.map(i=>[i.id,i.status,i.reasonCode].join(":")).sort().join(`
|
|
2
|
+
`)).digest("hex")}`,s=r(e),o=r(a);return{receipts:s,outputs:o,aggregate:`sha256:${M("sha256").update(`${t}:${s}:${o}`).digest("hex")}`}}function st(t){if(!t)return{};try{const e=JSON.parse(t);return E(e)?{...e}:{}}catch{return{}}}function d(t,e,a,r=!1){if(t===void 0){if(r)throw new l("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 l("sqlite-public-safety-rejected",`Continuity SQLite text exceeded the public bound at ${e}.`)}function T(t,e){if(t!==void 0&&(!Number.isFinite(t)||t<0||Math.floor(t)!==t))throw new l("sqlite-public-safety-rejected",`Continuity SQLite numeric value rejected at ${e}.`)}function j(t){d(t.outboxId,"outbox.outboxId",160,!0),d(t.jobId,"outbox.jobId",160),d(t.operationId,"outbox.operationId",160),d(t.idempotencyKey,"outbox.idempotencyKey",160),d(t.type,"outbox.type",80),d(t.status,"outbox.status",40),d(t.deliveryCursor,"outbox.deliveryCursor",200),d(t.timestamp,"outbox.timestamp",80),d(t.reasonCode,"outbox.reasonCode",100),d(t.summary,"outbox.summary",240)}function me(t){return t==="pending"||t==="sent"||t==="acked"||t==="failed"||t==="dead_letter"}function ot(t){return typeof t=="string"&&me(t)?t:"failed"}function I(t){return typeof t=="string"&&t.length>0?t:void 0}function dt(t){if(typeof t!="string"||t.trim().length===0)return{};try{const e=JSON.parse(t);return E(e)?(A(e,"outbox.payload"),e):{}}catch{return{}}}function nt(t){return{outboxId:String(t.outbox_id??""),...I(t.job_id)?{jobId:I(t.job_id)}:{},operationId:String(t.operation_id??""),...I(t.idempotency_key)?{idempotencyKey:I(t.idempotency_key)}:{},type:String(t.type??""),status:ot(t.status),payload:dt(t.payload_json),retryCount:typeof t.retry_count=="number"?t.retry_count:0,attemptCount:typeof t.attempt_count=="number"?t.attempt_count:0,...I(t.delivery_cursor)?{deliveryCursor:I(t.delivery_cursor)}:{},...I(t.next_attempt_at)?{nextAttemptAt:I(t.next_attempt_at)}:{},...I(t.last_attempt_at)?{lastAttemptAt:I(t.last_attempt_at)}:{},...I(t.sent_at)?{sentAt:I(t.sent_at)}:{},...I(t.acked_at)?{ackedAt:I(t.acked_at)}:{},...I(t.last_error_code)?{lastErrorCode:I(t.last_error_code)}:{},...I(t.last_error_reason)?{lastErrorReason:I(t.last_error_reason)}:{},...I(t.last_error_summary)?{lastErrorSummary:I(t.last_error_summary)}:{},...I(t.dead_letter_summary)?{deadLetterSummary:I(t.dead_letter_summary)}:{},...I(t.dead_lettered_at)?{deadLetteredAt:I(t.dead_lettered_at)}:{},createdAt:String(t.created_at??""),updatedAt:String(t.updated_at??""),publicSafe:!0}}function C(t){return{...t,publicSafe:!0}}function N(t,e){return t===void 0?null:(A(t,e),JSON.stringify(t))}function D(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()){d(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 l("sqlite-public-safety-rejected",`Continuity SQLite rejected non-relative path at relativePaths[${a}].`)}return e}function K(t){const e={...Y(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=D(t.relativePaths)),Y(e)}function L(t){d(t.attemptId,"headless_execution.attemptId",160,!0),d(t.executionId,"headless_execution.executionId",160,!0),d(t.jobId,"headless_execution.jobId",160,!0),d(t.directiveHash,"headless_execution.directiveHash",160),d(t.targetRef,"headless_execution.targetRef",240),d(t.storyId,"headless_execution.storyId",120),d(t.epicId,"headless_execution.epicId",120),d(t.runtimeId,"headless_execution.runtimeId",80),d(t.modelId,"headless_execution.modelId",120),d(t.runtimeSource,"headless_execution.runtimeSource",40),d(t.reasonCode,"headless_execution.reasonCode",100),d(t.publicSummary,"headless_execution.publicSummary",240),d(t.leaseId,"headless_execution.leaseId",160),d(t.runnerId,"headless_execution.runnerId",160),d(t.timestamp,"headless_execution.timestamp",80)}function w(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 it(t){return Be.includes(t)}function q(t){return Array.from(new Set(t))}function ct(t){const e=E(t)&&"default"in t?t.default:t;if(typeof e!="function")throw new l("sqlite-adapter-unavailable","Optional better-sqlite3 adapter did not export a database constructor.",{guidance:re});const a=e;return{adapterName:"better-sqlite3",open(r,s){return new a(r,s)}}}async function ut(t=Ve){try{const e=await t("better-sqlite3");return{ok:!0,adapter:ct(e)}}catch(e){return e instanceof l?{ok:!1,error:e}:{ok:!1,error:new l("sqlite-adapter-unavailable","Optional Enterprise continuity SQLite adapter better-sqlite3 is unavailable.",{cause:e,guidance:re})}}}function ye(t){return ee(t,te,Me)}function lt(t){const e=ee(t,te);pe(e,{recursive:!0,mode:448});try{X(e,448)}catch{}return e}async function xt(t){const e=t.adapter??await he(t.adapterLoader),a=ye(t.projectRoot);t.strictReadOnly?Ie(a):lt(t.projectRoot);let r;try{r=e.open(a,t.strictReadOnly?{fileMustExist:!0,readonly:!0}:void 0)}catch(o){throw m(o,"sqlite-integrity-failed")}const s=new _t({db:r,filePath:a,adapterName:e.adapterName,busyTimeoutMs:t.busyTimeoutMs??ke,integrityCheck:t.integrityCheck??!0,now:t.now??(()=>new Date().toISOString())});try{if(t.strictReadOnly)return s.runIntegrityCheck(),s.getSchemaVersion(),s;if(s.initialize(),Z(a))try{X(a,384)}catch{}return s}catch(o){try{r.close()}catch{}throw o}}function Ie(t){if(!Z(t))throw new l("sqlite-integrity-failed","Continuity database is unavailable for physical read-only inspection.",{mutationBlocked:!0});let e;try{const a=fe(t,"r");try{if(e=V.alloc(20),Ce(a,e,0,e.length,0)<e.length)throw new Error("short-header")}finally{Ee(a)}}catch(a){throw new l("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"||e[18]===2||e[19]===2)throw new l("sqlite-integrity-failed","Continuity database requires an unsafe WAL read profile.",{mutationBlocked:!0})}async function Rt(t){const e=ye(t.projectRoot);Ie(e);const a=t.adapter??await he(t.adapterLoader);let r;try{r=a.open(e,{fileMustExist:!0,readonly:!0});const o=w(r.pragma("integrity_check",{simple:!0}));if(String(o).toLowerCase()!=="ok")throw new Error("integrity")}catch(o){throw new l("sqlite-integrity-failed","Continuity database failed physical read-only inspection.",{cause:o,mutationBlocked:!0})}const s=o=>{const n=o.trim().replace(/^\(+/u,"").toLowerCase();if(!/^(select|with\s)/u.test(n)||/\b(insert|update|delete|replace|create|alter|drop|pragma|attach|detach|vacuum|reindex)\b/u.test(n))throw new l("sqlite-mutation-blocked","Statement is not in the physical read-only query profile.",{mutationBlocked:!0})};return Object.freeze({filePath:e,adapterName:a.adapterName,all(o,...n){return s(o),r.prepare(o).all(...n)},get(o,...n){return s(o),r.prepare(o).get(...n)},close(){r.close()}})}async function he(t){const e=t?await t():await ut();if(!e.ok)throw e.error;return e.adapter}class _t{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 l("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(!it(e))throw new l("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}getLocalConsoleAttachmentState(e){d(e,"local_console.jobId",160,!0);const a=this.db.prepare(`
|
|
3
3
|
SELECT j.job_id AS job_id,
|
|
4
4
|
j.kind AS kind,
|
|
5
5
|
j.status AS status,
|
|
@@ -8,7 +8,7 @@ import{Buffer as z}from"node:buffer";import{createHash as M}from"node:crypto";im
|
|
|
8
8
|
FROM jobs j
|
|
9
9
|
WHERE j.job_id = ?
|
|
10
10
|
LIMIT 1
|
|
11
|
-
`).get(e);return!
|
|
11
|
+
`).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(`
|
|
12
12
|
INSERT OR IGNORE INTO jobs (
|
|
13
13
|
job_id, kind, status, summary, reason_code, created_at, updated_at,
|
|
14
14
|
next_run_at, goal_id, loop_id, campaign_id, operation_id,
|
|
@@ -19,12 +19,12 @@ import{Buffer as z}from"node:buffer";import{createHash as M}from"node:crypto";im
|
|
|
19
19
|
event_id, job_id, operation_id, idempotency_key, event_sequence,
|
|
20
20
|
type, summary, reason_code, created_at, metadata_json
|
|
21
21
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
22
|
-
`).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){$(e.executionId,"processing_output_summary.executionId",160),$(e.jobId,"processing_output_summary.jobId",160),$(e.publicSummary,"processing_output_summary.publicSummary",
|
|
22
|
+
`).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){$(e.executionId,"processing_output_summary.executionId",160),$(e.jobId,"processing_output_summary.jobId",160),$(e.publicSummary,"processing_output_summary.publicSummary",Ue),$(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:et(e),jobId:e.jobId,operationId:e.executionId,idempotencyKey:e.idempotencyKey??e.executionId,type:O,summary:e.publicSummary,reasonCode:e.reasonCode,createdAt:e.createdAt,metadata:Ze(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}),d(e.notBeforeAt,"headless_execution.notBeforeAt",80),d(e.operationId,"headless_execution.operationId",160),d(e.idempotencyKey,"headless_execution.idempotencyKey",160),T(e.retryCount,"headless_execution.retryCount"),T(e.maxAttempts,"headless_execution.maxAttempts"),e.maxAttempts!==void 0&&e.maxAttempts<1)throw new l("sqlite-public-safety-rejected","Continuity SQLite maxAttempts must be greater than zero.");e.metadata&&A(e.metadata,"headless_execution.metadata");const a=B({maxItems:e.queueCap,maxAttempts:e.maxAttempts}),r=Le(e.queuePriority),s=je(e.queueScope),o=D(e.relativePaths),n=K({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:o,metadata:e.metadata});return this.runInTransaction(()=>{const i=this.db.prepare(`
|
|
23
23
|
SELECT value_json
|
|
24
24
|
FROM runner_config
|
|
25
25
|
WHERE key = 'headless_queue_policy'
|
|
26
26
|
LIMIT 1
|
|
27
|
-
`).get();let c=a.maxItems;if(e.queueCap===void 0&&
|
|
27
|
+
`).get();let c=a.maxItems;if(e.queueCap===void 0&&E(i)&&typeof i.value_json=="string")try{const u=JSON.parse(i.value_json);E(u)&&typeof u.maxItems=="number"&&(c=B({maxItems:u.maxItems}).maxItems)}catch{}this.db.prepare(`
|
|
28
28
|
INSERT INTO runner_config (key, value_json, updated_at)
|
|
29
29
|
VALUES ('headless_queue_policy', ?, ?)
|
|
30
30
|
ON CONFLICT(key) DO UPDATE SET
|
|
@@ -42,7 +42,7 @@ import{Buffer as z}from"node:buffer";import{createHash as M}from"node:crypto";im
|
|
|
42
42
|
FROM headless_execution_attempts
|
|
43
43
|
WHERE status IN ('queued', 'backoff', 'running')
|
|
44
44
|
AND dead_lettered_at IS NULL
|
|
45
|
-
`).get(),
|
|
45
|
+
`).get(),f=E(y)&&typeof y.count=="number"?y.count:0;if(p)return{inserted:!1,replay:!0,changes:0,accepted:!0,backpressure:f>=c,queueDepth:f,queueCap:c,publicSafe:!0};if(f>=c)return{inserted:!1,replay:!1,changes:0,accepted:!1,backpressure:!0,queueDepth:f,queueCap:c,reasonCode:k.CAP_REACHED,publicSafe:!0};const _=this.db.prepare(`
|
|
46
46
|
INSERT INTO headless_execution_attempts (
|
|
47
47
|
attempt_id, execution_id, job_id, directive_hash, directive_kind,
|
|
48
48
|
command_class, target_kind, target_ref, story_id, epic_id, runtime_id,
|
|
@@ -52,7 +52,7 @@ import{Buffer as z}from"node:buffer";import{createHash as M}from"node:crypto";im
|
|
|
52
52
|
relative_paths_json, metadata_json, queue_priority, queue_scope,
|
|
53
53
|
attempt_count, next_retry_at
|
|
54
54
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 0, ?)
|
|
55
|
-
`).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,N(e.counts,"headless_execution.counts"),N(e.hashes,"headless_execution.hashes"),N(e.redactionSummary,"headless_execution.redactionSummary"),N(
|
|
55
|
+
`).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,N(e.counts,"headless_execution.counts"),N(e.hashes,"headless_execution.hashes"),N(e.redactionSummary,"headless_execution.redactionSummary"),N(o,"headless_execution.relativePaths"),S(n),r,s,e.notBeforeAt??e.enqueuedAt);return{inserted:_.changes>0,replay:!1,changes:_.changes,accepted:_.changes>0,backpressure:f+_.changes>=c,queueDepth:f+_.changes,queueCap:c,publicSafe:!0}})}listDueHeadlessExecutionAttempts(e){const a=Math.max(1,Math.min(50,Math.floor(e.limit)));return d(e.nowIso,"headless_execution.nowIso",80,!0),this.db.prepare(`
|
|
56
56
|
SELECT attempt_id, execution_id, job_id, directive_hash, directive_kind,
|
|
57
57
|
command_class, target_kind, target_ref, story_id, epic_id,
|
|
58
58
|
runtime_id, model_id, runtime_source, status, reason_code,
|
|
@@ -71,13 +71,13 @@ import{Buffer as z}from"node:buffer";import{createHash as M}from"node:crypto";im
|
|
|
71
71
|
ORDER BY queue_priority DESC, COALESCE(next_retry_at, not_before_at, enqueued_at) ASC,
|
|
72
72
|
enqueued_at ASC, attempt_id ASC
|
|
73
73
|
LIMIT ?
|
|
74
|
-
`).all(e.nowIso,e.nowIso,a)}hasCompletedHeadlessExecutionDirectiveHash(e,a){
|
|
74
|
+
`).all(e.nowIso,e.nowIso,a)}hasCompletedHeadlessExecutionDirectiveHash(e,a){d(e,"headless_execution.directiveHash",160,!0),d(a,"headless_execution.attemptId",160);const r=a?" AND attempt_id != ?":"",s=a?[e,a]:[e];return this.db.prepare(`
|
|
75
75
|
SELECT 1 AS found
|
|
76
76
|
FROM headless_execution_attempts
|
|
77
77
|
WHERE directive_hash = ?
|
|
78
78
|
AND status = 'completed'${r}
|
|
79
79
|
LIMIT 1
|
|
80
|
-
`).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}),
|
|
80
|
+
`).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}),d(e.leaseExpiresAt,"headless_execution.leaseExpiresAt",80,!0);try{const a=this.db.prepare(`
|
|
81
81
|
UPDATE headless_execution_attempts
|
|
82
82
|
SET status = 'running',
|
|
83
83
|
lease_id = ?,
|
|
@@ -93,7 +93,7 @@ import{Buffer as z}from"node:buffer";import{createHash as M}from"node:crypto";im
|
|
|
93
93
|
AND dead_lettered_at IS NULL
|
|
94
94
|
AND (COALESCE(next_retry_at, not_before_at) IS NULL OR COALESCE(next_retry_at, not_before_at) <= ?)
|
|
95
95
|
AND (lease_id IS NULL OR lease_released_at IS NOT NULL OR lease_expires_at <= ?)
|
|
96
|
-
`).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}),
|
|
96
|
+
`).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}),d(e.leaseExpiresAt,"headless_execution.leaseExpiresAt",80,!0),this.runInTransaction(()=>{const a=this.db.prepare(`
|
|
97
97
|
SELECT attempt_id
|
|
98
98
|
FROM headless_execution_attempts
|
|
99
99
|
WHERE status IN ('queued', 'backoff')
|
|
@@ -122,7 +122,7 @@ import{Buffer as z}from"node:buffer";import{createHash as M}from"node:crypto";im
|
|
|
122
122
|
AND dead_lettered_at IS NULL
|
|
123
123
|
AND (COALESCE(next_retry_at, not_before_at) IS NULL OR COALESCE(next_retry_at, not_before_at) <= ?)
|
|
124
124
|
AND (lease_id IS NULL OR lease_released_at IS NOT NULL OR lease_expires_at <= ?)
|
|
125
|
-
`).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}),
|
|
125
|
+
`).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}),d(e.leaseExpiresAt,"headless_execution.leaseExpiresAt",80);try{const a=this.db.prepare(`
|
|
126
126
|
UPDATE headless_execution_attempts
|
|
127
127
|
SET heartbeat_at = ?,
|
|
128
128
|
lease_expires_at = COALESCE(?, lease_expires_at)
|
|
@@ -132,7 +132,7 @@ import{Buffer as z}from"node:buffer";import{createHash as M}from"node:crypto";im
|
|
|
132
132
|
AND status = 'running'
|
|
133
133
|
AND lease_released_at IS NULL
|
|
134
134
|
AND lease_expires_at > ?
|
|
135
|
-
`).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}),
|
|
135
|
+
`).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}),d(e.notBeforeAt,"headless_execution.notBeforeAt",80),T(e.retryCount,"headless_execution.retryCount");try{const a=this.db.prepare(`
|
|
136
136
|
UPDATE headless_execution_attempts
|
|
137
137
|
SET status = COALESCE(?, status),
|
|
138
138
|
reason_code = COALESCE(?, reason_code),
|
|
@@ -148,8 +148,8 @@ import{Buffer as z}from"node:buffer";import{createHash as M}from"node:crypto";im
|
|
|
148
148
|
AND lease_id = ?
|
|
149
149
|
AND status = 'running'
|
|
150
150
|
AND lease_released_at IS NULL
|
|
151
|
-
`).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}),
|
|
152
|
-
AND lease_released_at IS NULL${e.runnerId?" AND runner_id = ?":""}`:"",
|
|
151
|
+
`).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}),d(e.notBeforeAt,"headless_execution.notBeforeAt",80),T(e.durationMs,"headless_execution.durationMs"),T(e.retryCount,"headless_execution.retryCount"),e.metadata&&A(e.metadata,"headless_execution.metadata");const a=D(e.relativePaths),r=K({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 = ?
|
|
152
|
+
AND lease_released_at IS NULL${e.runnerId?" AND runner_id = ?":""}`:"",o=e.leaseId?"status = 'running'":"status NOT IN ('completed', 'failed', 'timed_out', 'skipped')",n=[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?N(e.counts,"headless_execution.counts"):null,e.hashes?N(e.hashes,"headless_execution.hashes"):null,e.redactionSummary?N(e.redactionSummary,"headless_execution.redactionSummary"):null,a?N(a,"headless_execution.relativePaths"):null,S(r),e.completedAt,e.attemptId];e.leaseId&&n.push(e.leaseId),e.leaseId&&e.runnerId&&n.push(e.runnerId);try{const i=this.db.prepare(`
|
|
153
153
|
UPDATE headless_execution_attempts
|
|
154
154
|
SET status = ?,
|
|
155
155
|
completed_at = ?,
|
|
@@ -169,27 +169,27 @@ import{Buffer as z}from"node:buffer";import{createHash as M}from"node:crypto";im
|
|
|
169
169
|
metadata_json = COALESCE(?, metadata_json),
|
|
170
170
|
lease_released_at = COALESCE(lease_released_at, ?)
|
|
171
171
|
WHERE attempt_id = ?${s}
|
|
172
|
-
AND ${
|
|
173
|
-
`).run(...
|
|
172
|
+
AND ${o}
|
|
173
|
+
`).run(...n);return this.toWriteResult(i)}catch(i){throw m(i,"sqlite-mutation-failed")}}recordHeadlessExecutionReceipt(e){L({attemptId:e.attemptId,executionId:e.executionId,jobId:e.jobId,reasonCode:e.reasonCode,timestamp:e.createdAt}),e.metadata&&A(e.metadata,"headless_execution.metadata");const a=D(e.relativePaths),r=K({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}),T(e.durationMs,"headless_execution.durationMs"),e.metadata&&A(e.metadata,"headless_execution.metadata");const a=D(e.relativePaths),r=K({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(`
|
|
174
174
|
INSERT OR IGNORE INTO job_receipts (
|
|
175
175
|
receipt_id, job_id, operation_id, idempotency_key, status, reason_code,
|
|
176
176
|
applied_operation_ids_json, ignored_operation_ids_json, created_at, metadata_json
|
|
177
177
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
178
|
-
`).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
|
|
178
|
+
`).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 l("sqlite-public-safety-rejected","Continuity receipt compaction requires a valid public timestamp.");const r=ve(e.policy),s=new Date(a-r.receipts.maxAgeMs).toISOString(),o=new Date(a-r.processingOutputs.maxAgeMs).toISOString();try{return this.runInTransaction(()=>{const n=this.selectReceiptRetentionCandidates({cutoff:s,maxItems:r.receipts.maxItems,maxBytes:r.receipts.maxBytes,limit:r.maxDeleteRowsPerRun}),i=this.selectOutputRetentionCandidates({cutoff:o,maxItems:r.processingOutputs.maxItems,maxBytes:r.processingOutputs.maxBytes,limit:r.maxDeleteRowsPerRun}),c=[...n,...i].sort((u,h)=>u.createdAt.localeCompare(h.createdAt)||u.id.localeCompare(h.id)).slice(0,r.maxDeleteRowsPerRun);if(c.length===0)return{status:"noop",summaries:[],counts:{receiptsRemoved:0,outputsRemoved:0,bytesRemoved:0,summariesCreated:0},reasonCode:F.NOOP,publicSafe:!0};const p=c.filter(u=>u.kind==="receipt"),y=c.filter(u=>u.kind==="output");for(const u of q(p.map(h=>h.jobId)))this.preserveReceiptDerivedIteration(u,e.nowIso);this.deleteRetentionCandidates("job_receipts","receipt_id",p.map(u=>u.id)),this.deleteRetentionCandidates("job_events","event_id",y.map(u=>u.id));const f=new Map;for(const u of c)f.set(u.jobId,[...f.get(u.jobId)??[],u]);const _=[];for(const[u,h]of[...f.entries()].sort(([x],[g])=>x.localeCompare(g))){const x=h.filter(v=>v.kind==="receipt"),g=h.filter(v=>v.kind==="output"),Q=this.retainedReceiptOutputCounts(u),J=rt(u,x,g),R={receiptsRemoved:x.length,receiptsRetained:Q.receipts,outputsRemoved:g.length,outputsRetained:Q.outputs,bytesRemoved:h.reduce((v,be)=>v+be.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}.`;d(P,"receipt_compaction.publicSummary",500,!0);const H=`receipt-compaction-${M("sha256").update(`${u}:${e.nowIso}:${J.aggregate}`).digest("hex").slice(0,32)}`,z={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:J,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:z.reasonCodes,counts:R,hashes:J,publicSummary:P}}),this.pruneReceiptCompactionSummaries(u,r.maxCompactionSummariesPerJob),_.push(z)}return{status:"compacted",summaries:_,counts:{receiptsRemoved:p.length,outputsRemoved:y.length,bytesRemoved:c.reduce((u,h)=>u+h.approxBytes,0),summariesCreated:_.length},reasonCode:F.COMPACTED,publicSafe:!0}})}catch(n){throw m(n,"sqlite-mutation-failed")}}updateJobStatus(e){this.assertCanMutate();try{const a=this.db.prepare(`
|
|
179
179
|
UPDATE jobs
|
|
180
180
|
SET status = ?,
|
|
181
181
|
reason_code = COALESCE(?, reason_code),
|
|
182
182
|
updated_at = ?,
|
|
183
183
|
next_run_at = COALESCE(?, next_run_at)
|
|
184
184
|
WHERE job_id = ?
|
|
185
|
-
`).run(e.status,e.reasonCode??null,e.updatedAt,e.nextRunAt??null,e.jobId);if(a.changes===0)throw new
|
|
185
|
+
`).run(e.status,e.reasonCode??null,e.updatedAt,e.nextRunAt??null,e.jobId);if(a.changes===0)throw new l("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(),d(e.jobId,"job_stage.jobId",160,!0);const a=oe(e.currentStage)?e.currentStage:void 0,r=We(e.iteration);if(!a&&r===void 0)return{inserted:!1,replay:!1,changes:0};const s=de(e.at);try{const o=this.db.prepare("SELECT metadata_json FROM jobs WHERE job_id = ?").get(e.jobId);if(!o)return{inserted:!1,replay:!1,changes:0};const n=st(typeof o.metadata_json=="string"?o.metadata_json:null);if(a&&(n.currentStage=a),r!==void 0&&(n.iteration=r),a&&s&&e.appendHistory!==!1){const c=He(n.stageHistory);c.push({stage:a,at:s}),n.stageHistory=c.slice(-se)}const i=this.db.prepare("UPDATE jobs SET metadata_json = ? WHERE job_id = ?").run(S(n),e.jobId);return this.toWriteResult(i)}catch(o){throw m(o,"sqlite-mutation-failed")}}updateJobAndExistingGoalCampaignStatus(e){return this.runInTransaction(()=>{const a=this.db.prepare(`
|
|
186
186
|
UPDATE jobs
|
|
187
187
|
SET status = ?,
|
|
188
188
|
reason_code = COALESCE(?, reason_code),
|
|
189
189
|
updated_at = ?,
|
|
190
190
|
next_run_at = COALESCE(?, next_run_at)
|
|
191
191
|
WHERE job_id = ?
|
|
192
|
-
`).run(e.status,e.reasonCode??null,e.updatedAt,e.nextRunAt??null,e.jobId);if(a.changes===0)throw new
|
|
192
|
+
`).run(e.status,e.reasonCode??null,e.updatedAt,e.nextRunAt??null,e.jobId);if(a.changes===0)throw new l("sqlite-foreign-key-failed",`Continuity SQLite job ${e.jobId} was not found for status parity update.`);const r=this.db.prepare(`
|
|
193
193
|
UPDATE goal_campaigns
|
|
194
194
|
SET status = ?,
|
|
195
195
|
reason_code = COALESCE(?, reason_code),
|
|
@@ -204,7 +204,7 @@ import{Buffer as z}from"node:buffer";import{createHash as M}from"node:crypto";im
|
|
|
204
204
|
UPDATE job_leases
|
|
205
205
|
SET status = 'released', released_at = ?
|
|
206
206
|
WHERE lease_id = ? AND released_at IS NULL
|
|
207
|
-
`).run(e.releasedAt,e.leaseId);if(a.changes===0)throw new
|
|
207
|
+
`).run(e.releasedAt,e.leaseId);if(a.changes===0)throw new l("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(`
|
|
208
208
|
INSERT OR IGNORE INTO state_snapshots (
|
|
209
209
|
snapshot_id, job_id, kind, relative_path, sha256, summary, captured_at,
|
|
210
210
|
operation_id, idempotency_key, metadata_json
|
|
@@ -214,7 +214,7 @@ import{Buffer as z}from"node:buffer";import{createHash as M}from"node:crypto";im
|
|
|
214
214
|
artifact_id, job_id, kind, relative_path, sha256, summary,
|
|
215
215
|
operation_id, idempotency_key, created_at, metadata_json
|
|
216
216
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
217
|
-
`).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(),j({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}),j({outboxId:e.outboxId,timestamp:e.updatedAt}),
|
|
217
|
+
`).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(),j({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}),j({outboxId:e.outboxId,timestamp:e.updatedAt}),d(e.nextAttemptAt,"outbox.nextAttemptAt",80),d(e.lastAttemptAt,"outbox.lastAttemptAt",80),d(e.sentAt,"outbox.sentAt",80),d(e.ackedAt,"outbox.ackedAt",80),d(e.deadLetteredAt,"outbox.deadLetteredAt",80),T(e.retryCount,"outbox.retryCount"),T(e.attemptCount,"outbox.attemptCount");const a=S(e.payload);try{const r=this.db.prepare(`
|
|
218
218
|
INSERT OR IGNORE INTO outbox (
|
|
219
219
|
outbox_id, job_id, operation_id, idempotency_key, type, status,
|
|
220
220
|
payload_json, retry_count, attempt_count, delivery_cursor,
|
|
@@ -222,7 +222,7 @@ import{Buffer as z}from"node:buffer";import{createHash as M}from"node:crypto";im
|
|
|
222
222
|
last_error_reason, last_error_summary, dead_letter_summary,
|
|
223
223
|
dead_lettered_at, created_at, updated_at
|
|
224
224
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
225
|
-
`).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){j({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
|
|
225
|
+
`).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){j({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 n of r)if(!me(n))throw new l("sqlite-public-safety-rejected","Continuity SQLite outbox batch query rejected an unknown status.");const s=r.map(()=>"?").join(", ");return this.db.prepare(`
|
|
226
226
|
SELECT outbox_id, job_id, operation_id, idempotency_key, type, status,
|
|
227
227
|
payload_json, retry_count, attempt_count, delivery_cursor,
|
|
228
228
|
next_attempt_at, last_attempt_at, sent_at, acked_at, last_error_code,
|
|
@@ -233,7 +233,7 @@ import{Buffer as z}from"node:buffer";import{createHash as M}from"node:crypto";im
|
|
|
233
233
|
AND (status NOT IN ('pending', 'failed') OR next_attempt_at IS NULL OR next_attempt_at <= ?)
|
|
234
234
|
ORDER BY COALESCE(next_attempt_at, created_at) ASC, created_at ASC, outbox_id ASC
|
|
235
235
|
LIMIT ?
|
|
236
|
-
`).all(...r,e.nowIso,a).map(
|
|
236
|
+
`).all(...r,e.nowIso,a).map(nt)}markOutboxSent(e){this.assertCanMutate(),j({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(`
|
|
237
237
|
UPDATE outbox
|
|
238
238
|
SET status = 'sent',
|
|
239
239
|
delivery_cursor = ?,
|
|
@@ -244,7 +244,7 @@ import{Buffer as z}from"node:buffer";import{createHash as M}from"node:crypto";im
|
|
|
244
244
|
updated_at = ?
|
|
245
245
|
WHERE outbox_id = ?
|
|
246
246
|
AND status IN ('pending', 'failed')
|
|
247
|
-
`).run(e.deliveryCursor,e.sentAt,e.sentAt,e.sentAt,e.outboxId);return
|
|
247
|
+
`).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(),j({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(`
|
|
248
248
|
UPDATE outbox
|
|
249
249
|
SET status = 'acked',
|
|
250
250
|
acked_at = ?,
|
|
@@ -254,7 +254,7 @@ import{Buffer as z}from"node:buffer";import{createHash as M}from"node:crypto";im
|
|
|
254
254
|
last_error_reason = NULL
|
|
255
255
|
WHERE outbox_id = ?
|
|
256
256
|
AND status = 'sent'
|
|
257
|
-
`).run(e.ackedAt,e.ackedAt,e.outboxId);return
|
|
257
|
+
`).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(),j({outboxId:e.outboxId,deliveryCursor:e.deliveryCursor,timestamp:e.failedAt,reasonCode:e.reasonCode,summary:e.summary}),d(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=Ne({nowIso:e.failedAt,attemptCount:r,reasonCode:e.reasonCode,summary:e.summary,nextRetryAt:e.nextRetryAt,policy:e.policy}),o=this.db.prepare(`
|
|
258
258
|
UPDATE outbox
|
|
259
259
|
SET status = ?,
|
|
260
260
|
retry_count = MAX(retry_count, ?),
|
|
@@ -267,7 +267,7 @@ import{Buffer as z}from"node:buffer";import{createHash as M}from"node:crypto";im
|
|
|
267
267
|
updated_at = ?
|
|
268
268
|
WHERE outbox_id = ?
|
|
269
269
|
AND status IN ('pending', 'sent', 'failed')
|
|
270
|
-
`).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
|
|
270
|
+
`).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:o.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(),j({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(`
|
|
271
271
|
UPDATE outbox
|
|
272
272
|
SET status = 'dead_letter',
|
|
273
273
|
next_attempt_at = NULL,
|
|
@@ -279,13 +279,13 @@ import{Buffer as z}from"node:buffer";import{createHash as M}from"node:crypto";im
|
|
|
279
279
|
updated_at = ?
|
|
280
280
|
WHERE outbox_id = ?
|
|
281
281
|
AND status <> 'acked'
|
|
282
|
-
`).run(e.reasonCode,e.reasonCode,e.summary,e.summary,e.deadLetteredAt,e.deadLetteredAt,e.outboxId);return
|
|
282
|
+
`).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 o=r.map(()=>"?").join(", "),i=this.db.prepare(`
|
|
283
283
|
SELECT outbox_id
|
|
284
284
|
FROM outbox
|
|
285
|
-
WHERE status IN (${
|
|
285
|
+
WHERE status IN (${o})
|
|
286
286
|
ORDER BY updated_at ASC, outbox_id ASC
|
|
287
287
|
LIMIT ?
|
|
288
|
-
`).all(...r,a).map(y=>y.outbox_id).filter(y=>typeof y=="string"&&y.length>0);if(
|
|
288
|
+
`).all(...r,a).map(y=>y.outbox_id).filter(y=>typeof y=="string"&&y.length>0);if(i.length===0)return{retriedOutboxIds:[],changes:0,reasonCode:s,publicSafe:!0};const c=i.map(()=>"?").join(", "),p=this.db.prepare(`
|
|
289
289
|
UPDATE outbox
|
|
290
290
|
SET status = 'pending',
|
|
291
291
|
retry_count = retry_count + 1,
|
|
@@ -299,7 +299,7 @@ import{Buffer as z}from"node:buffer";import{createHash as M}from"node:crypto";im
|
|
|
299
299
|
dead_lettered_at = NULL,
|
|
300
300
|
updated_at = ?
|
|
301
301
|
WHERE outbox_id IN (${c})
|
|
302
|
-
`).run(e.nextAttemptAt??e.nowIso,s,s,e.nowIso,...
|
|
302
|
+
`).run(e.nextAttemptAt??e.nowIso,s,s,e.nowIso,...i);return{retriedOutboxIds:i,changes:p.changes,reasonCode:s,publicSafe:!0}})}catch(o){throw m(o,"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(`
|
|
303
303
|
INSERT INTO goal_campaigns (
|
|
304
304
|
campaign_id, job_id, status, title, public_summary, reason_code,
|
|
305
305
|
created_at, updated_at, operation_id, idempotency_key, metadata_json
|
|
@@ -346,7 +346,7 @@ import{Buffer as z}from"node:buffer";import{createHash as M}from"node:crypto";im
|
|
|
346
346
|
required = excluded.required,
|
|
347
347
|
reason_code = excluded.reason_code,
|
|
348
348
|
metadata_json = excluded.metadata_json
|
|
349
|
-
`).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(
|
|
349
|
+
`).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(i=>`SELECT 1 AS found FROM ${i} WHERE operation_id = ?${a?" OR idempotency_key = ?":""}`),o=r.flatMap(()=>a?[e,a]:[e]);return!!this.db.prepare(`${s.join(" UNION ALL ")} LIMIT 1`).get(...o)}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(`
|
|
350
350
|
SELECT attempt_id, execution_id, job_id, directive_hash, directive_kind,
|
|
351
351
|
command_class, target_kind, target_ref, story_id, epic_id,
|
|
352
352
|
runtime_id, model_id, runtime_source, status, reason_code,
|
|
@@ -366,7 +366,7 @@ import{Buffer as z}from"node:buffer";import{createHash as M}from"node:crypto";im
|
|
|
366
366
|
FROM outbox
|
|
367
367
|
WHERE outbox_id = ?
|
|
368
368
|
LIMIT 1
|
|
369
|
-
`).get(e);if(!(!a||!
|
|
369
|
+
`).get(e);if(!(!a||!E(a)))return a}selectReceiptRetentionCandidates(e){return this.db.prepare(`
|
|
370
370
|
WITH sized AS (
|
|
371
371
|
SELECT receipt_id, job_id, status, reason_code, created_at,
|
|
372
372
|
length(receipt_id) + length(job_id) + length(status) + length(created_at)
|
|
@@ -434,20 +434,20 @@ import{Buffer as z}from"node:buffer";import{createHash as M}from"node:crypto";im
|
|
|
434
434
|
ORDER BY created_at DESC, event_id DESC
|
|
435
435
|
LIMIT -1 OFFSET ?
|
|
436
436
|
)
|
|
437
|
-
`).run(e,
|
|
437
|
+
`).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=(h,...x)=>{const g=this.db.prepare(h).get(...x);return E(g)&&typeof g.count=="number"?g.count:0},r=this.db.prepare(`
|
|
438
438
|
SELECT status, COUNT(*) AS count FROM outbox GROUP BY status
|
|
439
|
-
`).all(),s={};for(const
|
|
439
|
+
`).all(),s={};for(const h of r)typeof h.status=="string"&&typeof h.count=="number"&&(s[h.status]=h.count);const o=this.db.prepare(`
|
|
440
440
|
SELECT value_json
|
|
441
441
|
FROM runner_config
|
|
442
442
|
WHERE key = 'headless_queue_policy'
|
|
443
443
|
LIMIT 1
|
|
444
|
-
`).get();let
|
|
444
|
+
`).get();let n=Oe;if(E(o)&&typeof o.value_json=="string")try{const h=JSON.parse(o.value_json);E(h)&&typeof h.maxItems=="number"&&(n=B({maxItems:h.maxItems}))}catch{}const i=a("SELECT COUNT(*) AS count FROM headless_execution_attempts WHERE status = 'queued' AND dead_lettered_at IS NULL"),c=a("SELECT COUNT(*) AS count FROM headless_execution_attempts WHERE status = 'backoff' AND dead_lettered_at IS NULL"),p=a("SELECT COUNT(*) AS count FROM headless_execution_attempts WHERE status = 'running' AND dead_lettered_at IS NULL"),y=a("SELECT COUNT(*) AS count FROM headless_execution_attempts WHERE dead_lettered_at IS NOT NULL"),f=i+c+p,_=this.db.prepare(`
|
|
445
445
|
SELECT MIN(next_retry_at) AS next_retry_at
|
|
446
446
|
FROM headless_execution_attempts
|
|
447
447
|
WHERE status = 'backoff'
|
|
448
448
|
AND dead_lettered_at IS NULL
|
|
449
449
|
AND next_retry_at IS NOT NULL
|
|
450
|
-
`).get(),u=
|
|
450
|
+
`).get(),u=E(_)&&typeof _.next_retry_at=="string"?_.next_retry_at:void 0;return{schemaVersion:this.getSchemaVersion(),jobs:this.db.prepare(`
|
|
451
451
|
SELECT job_id, kind, status, summary, reason_code, created_at, updated_at,
|
|
452
452
|
next_run_at, metadata_json,
|
|
453
453
|
(SELECT COUNT(*)
|
|
@@ -531,19 +531,19 @@ import{Buffer as z}from"node:buffer";import{createHash as M}from"node:crypto";im
|
|
|
531
531
|
FROM headless_execution_attempts
|
|
532
532
|
ORDER BY enqueued_at DESC, attempt_id ASC
|
|
533
533
|
LIMIT ?
|
|
534
|
-
`).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:c,headlessDeadLetterAttempts:y,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:
|
|
534
|
+
`).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:c,headlessDeadLetterAttempts:y,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:i,running:p,retrying:c,deadLetter:y,capacity:n.maxItems,available:Math.max(0,n.maxItems-f),backpressure:f>=n.maxItems,generatedAt:e.nowIso,...u?{nextRetryAt:u}:{},...f>=n.maxItems?{reasonCode:k.CAP_REACHED}:{},publicSafe:!0}}}listProcessingOutputSummaries(e={}){const a=ce(e.limit),r=le(e),s=`
|
|
535
535
|
SELECT event_id, job_id, operation_id, summary, reason_code, created_at, metadata_json
|
|
536
536
|
FROM job_events
|
|
537
537
|
WHERE type = ?${r.sql}
|
|
538
538
|
ORDER BY created_at DESC, event_id DESC
|
|
539
539
|
LIMIT ?
|
|
540
|
-
`;return this.db.prepare(`SELECT * FROM (${s}) ORDER BY created_at ASC, event_id ASC`).all(O,...r.params,a).map(
|
|
540
|
+
`;return this.db.prepare(`SELECT * FROM (${s}) ORDER BY created_at ASC, event_id ASC`).all(O,...r.params,a).map(_e)}pollProcessingOutputSummaries(e={}){const a=ce(e.limit),r=at(e.cursor),s=le(e),o=r?" AND (created_at > ? OR (created_at = ? AND event_id > ?))":"",n=`
|
|
541
541
|
SELECT event_id, job_id, operation_id, summary, reason_code, created_at, metadata_json
|
|
542
542
|
FROM job_events
|
|
543
|
-
WHERE type = ?${s.sql}${
|
|
543
|
+
WHERE type = ?${s.sql}${o}
|
|
544
544
|
ORDER BY created_at ASC, event_id ASC
|
|
545
545
|
LIMIT ?
|
|
546
|
-
`,
|
|
546
|
+
`,i=[O];i.push(...s.params),r&&i.push(r.createdAt,r.createdAt,r.eventId),i.push(a+1);const c=this.db.prepare(n).all(...i),p=c.slice(0,a).map(_e),y=p[p.length-1];return{summaries:p,...y?{nextCursor:y.cursor}:e.cursor?{nextCursor:e.cursor}:{},hasMore:c.length>a,publicSafe:!0}}listDueJobs(e){const a=Math.max(1,Math.min(50,Math.floor(e.limit)));return this.db.prepare(`
|
|
547
547
|
SELECT j.job_id, j.kind, j.status, j.summary, j.reason_code, j.created_at,
|
|
548
548
|
j.updated_at, j.next_run_at, j.metadata_json,
|
|
549
549
|
(SELECT COUNT(*)
|
|
@@ -561,19 +561,19 @@ import{Buffer as z}from"node:buffer";import{createHash as M}from"node:crypto";im
|
|
|
561
561
|
AND j.status NOT IN ('waiting_external', 'waiting_human', 'paused', 'blocked', 'completed', 'aborted', 'cancelled')
|
|
562
562
|
ORDER BY j.next_run_at ASC, j.job_id ASC
|
|
563
563
|
LIMIT ?
|
|
564
|
-
`).all(e.nowIso,a)}recoverStaleLeases(e){this.assertCanMutate();const a=Date.parse(e.nowIso);if(!Number.isFinite(a))throw new
|
|
564
|
+
`).all(e.nowIso,a)}recoverStaleLeases(e){this.assertCanMutate();const a=Date.parse(e.nowIso);if(!Number.isFinite(a))throw new l("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))),o=new Date(a-r).toISOString();try{return this.runInTransaction(()=>{const i=this.db.prepare(`
|
|
565
565
|
SELECT lease_id
|
|
566
566
|
FROM job_leases
|
|
567
567
|
WHERE released_at IS NULL
|
|
568
568
|
AND expires_at <= ?
|
|
569
569
|
ORDER BY expires_at ASC, lease_id ASC
|
|
570
570
|
LIMIT ?
|
|
571
|
-
`).all(
|
|
571
|
+
`).all(o,s).map(y=>y.lease_id).filter(y=>typeof y=="string"&&y.length>0);if(i.length===0)return{recoveredLeaseIds:[],safeExpiredAtOrBefore:o,changes:0};const c=i.map(()=>"?").join(", "),p=this.db.prepare(`
|
|
572
572
|
UPDATE job_leases
|
|
573
573
|
SET status = 'expired', released_at = ?
|
|
574
574
|
WHERE released_at IS NULL
|
|
575
575
|
AND lease_id IN (${c})
|
|
576
|
-
`).run(e.nowIso,...
|
|
576
|
+
`).run(e.nowIso,...i);return{recoveredLeaseIds:i,safeExpiredAtOrBefore:o,changes:p.changes}})}catch(n){throw m(n,"sqlite-mutation-failed")}}recoverStaleHeadlessExecutionAttempts(e){this.assertCanMutate();const a=Date.parse(e.nowIso);if(!Number.isFinite(a))throw new l("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))),o=new Date(a-r).toISOString();try{return this.runInTransaction(()=>{const n=this.db.prepare(`
|
|
577
577
|
SELECT attempt_id, retry_count, max_attempts, attempt_count
|
|
578
578
|
FROM headless_execution_attempts
|
|
579
579
|
WHERE status = 'running'
|
|
@@ -581,7 +581,7 @@ import{Buffer as z}from"node:buffer";import{createHash as M}from"node:crypto";im
|
|
|
581
581
|
AND lease_expires_at <= ?
|
|
582
582
|
ORDER BY lease_expires_at ASC, attempt_id ASC
|
|
583
583
|
LIMIT ?
|
|
584
|
-
`).all(
|
|
584
|
+
`).all(o,s),i=[],c=[],p=B(e.policy);for(const _ of n){if(typeof _.attempt_id!="string"||_.attempt_id.length===0)continue;const u=typeof _.retry_count=="number"?_.retry_count:0,h=typeof _.max_attempts=="number"?_.max_attempts:1,x=typeof _.attempt_count=="number"?_.attempt_count:0;Math.max(x,u+1)>=h?c.push(_.attempt_id):i.push({attemptId:_.attempt_id,nextRetryAt:Te(e.nowIso,u+1,p)})}let y=0;for(const _ of i)y+=this.db.prepare(`
|
|
585
585
|
UPDATE headless_execution_attempts
|
|
586
586
|
SET status = 'backoff',
|
|
587
587
|
retry_count = retry_count + 1,
|
|
@@ -592,7 +592,7 @@ import{Buffer as z}from"node:buffer";import{createHash as M}from"node:crypto";im
|
|
|
592
592
|
WHERE attempt_id = ?
|
|
593
593
|
AND status = 'running'
|
|
594
594
|
AND lease_released_at IS NULL
|
|
595
|
-
`).run(
|
|
595
|
+
`).run(k.LEASE_TIMEOUT_RETRY,e.nowIso,_.nextRetryAt,_.nextRetryAt,_.attemptId).changes;if(c.length>0){const _=c.map(()=>"?").join(", ");y+=this.db.prepare(`
|
|
596
596
|
UPDATE headless_execution_attempts
|
|
597
597
|
SET status = 'failed',
|
|
598
598
|
retry_count = retry_count + 1,
|
|
@@ -602,18 +602,18 @@ import{Buffer as z}from"node:buffer";import{createHash as M}from"node:crypto";im
|
|
|
602
602
|
dead_lettered_at = ?,
|
|
603
603
|
dead_letter_reason_code = ?,
|
|
604
604
|
next_retry_at = NULL
|
|
605
|
-
WHERE attempt_id IN (${
|
|
605
|
+
WHERE attempt_id IN (${_})
|
|
606
606
|
AND status = 'running'
|
|
607
607
|
AND lease_released_at IS NULL
|
|
608
|
-
`).run(
|
|
608
|
+
`).run(k.ATTEMPTS_EXHAUSTED,e.nowIso,e.nowIso,e.nowIso,k.ATTEMPTS_EXHAUSTED,...c).changes}const f=i.map(_=>_.attemptId);return{recoveredAttemptIds:[...f,...c],failedAttemptIds:c,retryingAttemptIds:f,deadLetteredAttemptIds:c,safeExpiredAtOrBefore:o,changes:y,publicSafe:!0}})}catch(n){throw m(n,"sqlite-mutation-failed")}}ensureGoalCampaign(e,a,r,s){this.db.prepare(`
|
|
609
609
|
INSERT OR IGNORE INTO goal_campaigns (
|
|
610
610
|
campaign_id, job_id, status, public_summary, created_at, updated_at
|
|
611
611
|
) VALUES (?, ?, 'active', 'Public goal campaign summary unavailable', ?, ?)
|
|
612
|
-
`).run(e,a,r,s)}configureConnection(){const e=String(
|
|
612
|
+
`).run(e,a,r,s)}configureConnection(){const e=String(w(this.db.pragma("journal_mode = WAL",{simple:!0}))??"").toLowerCase();if(e!=="wal")throw new l("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(w(this.db.pragma("foreign_keys",{simple:!0}))??0)!==1)throw new l("sqlite-migration-failed","Continuity SQLite foreign_keys pragma is not enabled.")}ensureMigrationTable(){this.db.exec(`
|
|
613
613
|
CREATE TABLE IF NOT EXISTS continuity_migrations (
|
|
614
614
|
version INTEGER PRIMARY KEY,
|
|
615
615
|
name TEXT NOT NULL,
|
|
616
616
|
checksum TEXT NOT NULL,
|
|
617
617
|
applied_at TEXT NOT NULL
|
|
618
618
|
);
|
|
619
|
-
`)}applyMigrations(){this.db.transaction(()=>{for(const a of
|
|
619
|
+
`)}applyMigrations(){this.db.transaction(()=>{for(const a of Fe){const r=Ge(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 l("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 l("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,Ue as CONTINUITY_PROCESSING_OUTPUT_SUMMARY_MAX_CHARS,we as CONTINUITY_PUBLIC_STAGES,Me as CONTINUITY_SQLITE_FILENAME,te as CONTINUITY_SQLITE_RELATIVE_DIR,gt as CONTINUITY_SQLITE_SCHEMA_VERSION,se as CONTINUITY_STAGE_HISTORY_MAX,_t as ContinuitySqliteStore,l as ContinuitySqliteStoreError,ae as DEFAULT_CONTINUITY_PROCESSING_SUMMARY_LIMIT,ke as DEFAULT_CONTINUITY_SQLITE_BUSY_TIMEOUT_MS,De as MAX_CONTINUITY_PROCESSING_SUMMARY_LIMIT,re as SQLITE_ADAPTER_INSTALL_GUIDANCE,ye as continuitySqliteStorePath,oe as isContinuityPublicStage,ut as loadBetterSqlite3Adapter,We as normalizeContinuityStageIteration,Rt as openContinuitySqliteReadOnly,xt as openContinuitySqliteStore,He as sanitizeContinuityStageHistory,de as sanitizeContinuityStageTimestamp};
|