@ornexus/neocortex 4.60.46 → 4.60.47
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 +23 -23
- package/install.ps1 +1 -1
- package/install.sh +1 -1
- package/package.json +2 -2
- package/packages/client/dist/yoloop/yoloop-client-state-store.js +1 -1
- package/targets-stubs/antigravity/gemini.md +1 -1
- package/targets-stubs/antigravity/skill/SKILL.md +1 -1
- package/targets-stubs/claude-code/neocortex-root.agent.yaml +1 -1
- package/targets-stubs/claude-code/neocortex-root.md +2 -2
- package/targets-stubs/claude-code/neocortex.agent.yaml +1 -1
- package/targets-stubs/claude-code/neocortex.md +2 -2
- package/targets-stubs/codex/AGENTS.md +1 -1
- package/targets-stubs/cursor/agent.md +2 -2
- package/targets-stubs/gemini-cli/agent.md +2 -2
- package/targets-stubs/opencode/neocortex-root.md +1 -1
- package/targets-stubs/vscode/neocortex.agent.md +2 -2
package/dist/sbom.cdx.json
CHANGED
|
@@ -984,7 +984,7 @@
|
|
|
984
984
|
"version": "1.26.0"
|
|
985
985
|
},
|
|
986
986
|
{
|
|
987
|
-
"bom-ref": "@neocortex/client@4.60.
|
|
987
|
+
"bom-ref": "@neocortex/client@4.60.47",
|
|
988
988
|
"group": "@neocortex",
|
|
989
989
|
"name": "client",
|
|
990
990
|
"properties": [
|
|
@@ -993,9 +993,9 @@
|
|
|
993
993
|
"value": "node_modules/@neocortex/client"
|
|
994
994
|
}
|
|
995
995
|
],
|
|
996
|
-
"purl": "pkg:npm/%40neocortex/client@4.60.
|
|
996
|
+
"purl": "pkg:npm/%40neocortex/client@4.60.47",
|
|
997
997
|
"type": "library",
|
|
998
|
-
"version": "4.60.
|
|
998
|
+
"version": "4.60.47"
|
|
999
999
|
},
|
|
1000
1000
|
{
|
|
1001
1001
|
"bom-ref": "@neocortex/core@0.1.0",
|
|
@@ -1012,7 +1012,7 @@
|
|
|
1012
1012
|
"version": "0.1.0"
|
|
1013
1013
|
},
|
|
1014
1014
|
{
|
|
1015
|
-
"bom-ref": "@neocortex/server@4.60.
|
|
1015
|
+
"bom-ref": "@neocortex/server@4.60.47",
|
|
1016
1016
|
"group": "@neocortex",
|
|
1017
1017
|
"name": "server",
|
|
1018
1018
|
"properties": [
|
|
@@ -1021,12 +1021,12 @@
|
|
|
1021
1021
|
"value": "node_modules/@neocortex/server"
|
|
1022
1022
|
}
|
|
1023
1023
|
],
|
|
1024
|
-
"purl": "pkg:npm/%40neocortex/server@4.60.
|
|
1024
|
+
"purl": "pkg:npm/%40neocortex/server@4.60.47",
|
|
1025
1025
|
"type": "library",
|
|
1026
|
-
"version": "4.60.
|
|
1026
|
+
"version": "4.60.47"
|
|
1027
1027
|
},
|
|
1028
1028
|
{
|
|
1029
|
-
"bom-ref": "@neocortex/shared@4.60.
|
|
1029
|
+
"bom-ref": "@neocortex/shared@4.60.47",
|
|
1030
1030
|
"group": "@neocortex",
|
|
1031
1031
|
"name": "shared",
|
|
1032
1032
|
"properties": [
|
|
@@ -1035,9 +1035,9 @@
|
|
|
1035
1035
|
"value": "node_modules/@neocortex/shared"
|
|
1036
1036
|
}
|
|
1037
1037
|
],
|
|
1038
|
-
"purl": "pkg:npm/%40neocortex/shared@4.60.
|
|
1038
|
+
"purl": "pkg:npm/%40neocortex/shared@4.60.47",
|
|
1039
1039
|
"type": "library",
|
|
1040
|
-
"version": "4.60.
|
|
1040
|
+
"version": "4.60.47"
|
|
1041
1041
|
},
|
|
1042
1042
|
{
|
|
1043
1043
|
"bom-ref": "@opentelemetry/api-logs@0.214.0",
|
|
@@ -9405,17 +9405,17 @@
|
|
|
9405
9405
|
"dependsOn": [
|
|
9406
9406
|
"@clack/prompts@1.0.1",
|
|
9407
9407
|
"@modelcontextprotocol/sdk@1.26.0",
|
|
9408
|
-
"@neocortex/client@4.60.
|
|
9408
|
+
"@neocortex/client@4.60.47",
|
|
9409
9409
|
"@neocortex/core@0.1.0",
|
|
9410
|
-
"@neocortex/server@4.60.
|
|
9411
|
-
"@neocortex/shared@4.60.
|
|
9410
|
+
"@neocortex/server@4.60.47",
|
|
9411
|
+
"@neocortex/shared@4.60.47",
|
|
9412
9412
|
"better-sqlite3@12.11.1",
|
|
9413
9413
|
"execa@9.6.1",
|
|
9414
9414
|
"node-cache@5.1.2",
|
|
9415
9415
|
"picocolors@1.1.1",
|
|
9416
9416
|
"zod@4.4.3"
|
|
9417
9417
|
],
|
|
9418
|
-
"ref": "@ornexus/neocortex@4.60.
|
|
9418
|
+
"ref": "@ornexus/neocortex@4.60.47"
|
|
9419
9419
|
},
|
|
9420
9420
|
{
|
|
9421
9421
|
"dependsOn": [
|
|
@@ -9456,7 +9456,7 @@
|
|
|
9456
9456
|
"@fastify/jwt@10.2.2",
|
|
9457
9457
|
"@fastify/rate-limit@10.3.0",
|
|
9458
9458
|
"@fastify/static@10.1.3",
|
|
9459
|
-
"@neocortex/shared@4.60.
|
|
9459
|
+
"@neocortex/shared@4.60.47",
|
|
9460
9460
|
"@sentry/node@10.62.0",
|
|
9461
9461
|
"bcryptjs@3.0.3",
|
|
9462
9462
|
"drizzle-orm@0.45.2",
|
|
@@ -9469,7 +9469,7 @@
|
|
|
9469
9469
|
"stripe@20.4.1",
|
|
9470
9470
|
"yaml@2.9.0"
|
|
9471
9471
|
],
|
|
9472
|
-
"ref": "@neocortex/server@4.60.
|
|
9472
|
+
"ref": "@neocortex/server@4.60.47"
|
|
9473
9473
|
},
|
|
9474
9474
|
{
|
|
9475
9475
|
"dependsOn": [
|
|
@@ -9590,16 +9590,16 @@
|
|
|
9590
9590
|
},
|
|
9591
9591
|
{
|
|
9592
9592
|
"dependsOn": [
|
|
9593
|
-
"@neocortex/shared@4.60.
|
|
9593
|
+
"@neocortex/shared@4.60.47",
|
|
9594
9594
|
"better-sqlite3@12.11.1",
|
|
9595
9595
|
"jose@6.2.2",
|
|
9596
9596
|
"keytar@7.9.0"
|
|
9597
9597
|
],
|
|
9598
|
-
"ref": "@neocortex/client@4.60.
|
|
9598
|
+
"ref": "@neocortex/client@4.60.47"
|
|
9599
9599
|
},
|
|
9600
9600
|
{
|
|
9601
9601
|
"dependsOn": [
|
|
9602
|
-
"@neocortex/shared@4.60.
|
|
9602
|
+
"@neocortex/shared@4.60.47"
|
|
9603
9603
|
],
|
|
9604
9604
|
"ref": "@neocortex/core@0.1.0"
|
|
9605
9605
|
},
|
|
@@ -10653,7 +10653,7 @@
|
|
|
10653
10653
|
"ref": "@lukeed/ms@2.0.2"
|
|
10654
10654
|
},
|
|
10655
10655
|
{
|
|
10656
|
-
"ref": "@neocortex/shared@4.60.
|
|
10656
|
+
"ref": "@neocortex/shared@4.60.47"
|
|
10657
10657
|
},
|
|
10658
10658
|
{
|
|
10659
10659
|
"ref": "@opentelemetry/api@1.9.1"
|
|
@@ -11136,8 +11136,8 @@
|
|
|
11136
11136
|
"metadata": {
|
|
11137
11137
|
"component": {
|
|
11138
11138
|
"author": "OrNexus Team",
|
|
11139
|
-
"bom-ref": "@ornexus/neocortex@4.60.
|
|
11140
|
-
"description": "Neocortex v4.60.
|
|
11139
|
+
"bom-ref": "@ornexus/neocortex@4.60.47",
|
|
11140
|
+
"description": "Neocortex v4.60.47 - Orquestrador de Desenvolvimento de Epics & Stories para Claude Code",
|
|
11141
11141
|
"externalReferences": [
|
|
11142
11142
|
{
|
|
11143
11143
|
"comment": "as detected from PackageJson property \"bugs.url\"",
|
|
@@ -11170,9 +11170,9 @@
|
|
|
11170
11170
|
"value": ""
|
|
11171
11171
|
}
|
|
11172
11172
|
],
|
|
11173
|
-
"purl": "pkg:npm/%40ornexus/neocortex@4.60.
|
|
11173
|
+
"purl": "pkg:npm/%40ornexus/neocortex@4.60.47?vcs_url=git%2Bhttps%3A%2F%2Fgithub.com%2FOrNexus-AI%2Fneocortex.git",
|
|
11174
11174
|
"type": "application",
|
|
11175
|
-
"version": "4.60.
|
|
11175
|
+
"version": "4.60.47"
|
|
11176
11176
|
},
|
|
11177
11177
|
"tools": {
|
|
11178
11178
|
"components": [
|
package/install.ps1
CHANGED
package/install.sh
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ornexus/neocortex",
|
|
3
|
-
"version": "4.60.
|
|
4
|
-
"description": "Neocortex v4.60.
|
|
3
|
+
"version": "4.60.47",
|
|
4
|
+
"description": "Neocortex v4.60.47 - Orquestrador de Desenvolvimento de Epics & Stories para Claude Code",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"claude",
|
|
7
7
|
"claude-code",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{promises as u}from"node:fs";import{createHash as Y}from"node:crypto";import{join as _,dirname as U}from"node:path";import{hostname as I}from"node:os";import{setSecureFilePermissions as F,setSecureDirPermissions as K}from"../config/secure-config.js";import{RECOVERY_HISTORY_CAP as g}from"./shared-yoloop-types.js";const b=".neocortex",m="yoloop-state.json",V="yoloop.lock",M="yoloop-state.mutation.lock",T="yoloop-session-rollover.json",q=360*60*1e3,$=3e4,B=200,C=Object.freeze(["rollover-session-v1"]),J={warn:()=>{},info:()=>{},error:()=>{}};function S(t){const e=t.slice(0,10);return{version:"1.1",lastResetAt:t,storiesRunToday:0,iterationsToday:0,iterationsTodayDate:e,tokensUsedToday:0,lastRunAt:null,coolDownUntil:null,totalRunsAllTime:0,totalStoriesAllTime:0,currentSession:null,continuationPolicy:"p205-finite-resume-v2",pendingContinuationAuthorities:[],continuationReceipts:[],continuationRecoveryReceipts:[]}}function ue(t){return{lock:null,state:S(t),capabilities:C}}class he{stateDir;statePath;lockPath;mutationLockPath;rolloverManifestPath;logger;constructor(e,n=J){this.stateDir=_(e,b),this.statePath=_(this.stateDir,m),this.lockPath=_(this.stateDir,V),this.mutationLockPath=_(this.stateDir,M),this.rolloverManifestPath=_(this.stateDir,T),this.logger=n}async readAll(e){const n=e??new Date().toISOString();await this.cleanupOrphanTempFiles(),await this.recoverSessionRolloverIfPresent(n);const[s,o]=await Promise.all([this.readLock(),this.readState(n)]);return{lock:await this.prepareLockForSnapshot(s,n),state:o,capabilities:C}}async applyUpdate(e,n){const s=n??new Date().toISOString();await this.ensureDir(),await this.recoverSessionRolloverIfPresent(s);for(const o of e.operations)await this.applyOperation(o,s)}async requestRunTransition(e,n){const s=n??new Date().toISOString();return await this.ensureDir(),this.withMutationLock(()=>this.transitionRun(e,s))}async requestLifecycleAction(e,n={},s){const o=s??new Date().toISOString();return await this.ensureDir(),this.withMutationLock(async()=>{const i=(await this.readState(o)).runControl;if(!i)throw new Error("YOLOOP_RUN_TRANSITION_INVALID");const a=Date.parse(o).toString(36),c=n.operationId??`op-${e}-${a}`,l=n.idempotencyKey??`idem-${e}-${a}`,h=i.receipts.find(y=>y.operationId===c||y.idempotencyKey===l);if(h){if(h.operationId===c&&h.idempotencyKey===l)return h;throw new Error("YOLOOP_RUN_OPERATION_CONFLICT")}const O=Z(i.status,e);if(!O)throw new Error(R.has(i.status)?"YOLOOP_RUN_TERMINAL":"YOLOOP_RUN_TRANSITION_INVALID");return this.transitionRun(ee({current:i,action:e,target:O,operationId:c,idempotencyKey:l,occurredAt:o}),o)})}async applyOperation(e,n){switch(e.type){case"acquire_lock":await this.acquireLock(e.lock,n);return;case"release_lock":await this.releaseLock(e);return;case"write_state":await this.withMutationLock(async()=>{const s=await this.readState(n),{runControl:o,...r}=e.state;await this.writeState({...r,...s.runControl?{version:"1.2",runControl:s.runControl}:{}})});return;case"advance_epic":await this.advanceEpic(e.nextEpicIndex,e.nextEpicId,n);return;case"no_op":this.logger.info({event:"yoloop_noop"},"yoloop server sent no-op");return;case"reserve_continuation_authority":await this.reserveContinuationAuthority(e.authority,n);return;case"acknowledge_continuation_authority":await this.acknowledgeContinuationAuthority(e.idempotencyKey,e.receipt,n);return;case"repair_continuation_authority":await this.repairContinuationAuthority(e.beforeHash,e.authority,e.receipt,n);return;case"switch_continuation_policy":await this.switchContinuationPolicy(e.policy,e.session,n);return;case"transition_run":await this.requestRunTransition(e,n);return;case"start_successor_run":await this.withMutationLock(()=>this.startSuccessorRun(e,n));return;case"rollover_session":await this.withMutationLock(()=>this.rolloverSession(e,n));return;case"recovery_attempted":await this.appendRecoveryAttempt(e.attempt,n);return;case"recovery_resolved":await this.resolveRecoveryAttempt(e.attempt_id,e.outcome,n);return;default:{const s=e;throw this.logger.error({event:"yoloop_unknown_op",op:s},"unknown yoloop operation rejected"),new Error("YOLOOP_STATE_OPERATION_UNSUPPORTED")}}}async reserveContinuationAuthority(e,n){const s=await this.readState(n),o=s.pendingContinuationAuthorities??[],r=typeof e.idempotencyKey=="string"?e.idempotencyKey:"";if(!r)throw new Error("YOLOOP_CONTINUATION_AUTHORITY_INVALID");const i=o.find(a=>a.idempotencyKey===r);if(i){if(d(i)===d(e))return;throw new Error("YOLOOP_CONTINUATION_AUTHORITY_CONFLICT")}if(o.length>=64)throw new Error("YOLOOP_PENDING_AUTHORITY_CAPACITY_EXCEEDED");await this.writeState({...s,pendingContinuationAuthorities:[...o,e]})}async acknowledgeContinuationAuthority(e,n,s){const o=await this.readState(s),r=o.pendingContinuationAuthorities??[],i=r.findIndex(h=>h.idempotencyKey===e);if(i<0)throw new Error("YOLOOP_CONTINUATION_RECEIPT_ORPHAN");const a=r[i];if(n.idempotencyKey!==e||n.sessionId!==a.sessionId||JSON.stringify(n.storyIds)!==JSON.stringify(a.storyIds))throw new Error("YOLOOP_CONTINUATION_RECEIPT_MISMATCH");const c=r.filter((h,O)=>O!==i),l=o.continuationReceipts??[];await this.writeState({...o,pendingContinuationAuthorities:c,continuationReceipts:[...l.slice(-63),n]})}async repairContinuationAuthority(e,n,s,o){const r=await this.readState(o),i=r.pendingContinuationAuthorities??[],a=r.continuationRecoveryReceipts??[],c=typeof s.idempotencyKey=="string"?s.idempotencyKey:"",l=a.find(y=>y.idempotencyKey===c);if(l){if(d(l)===d(s))return;throw new Error("YOLOOP_CONTINUATION_RECOVERY_RECEIPT_CONFLICT")}if(i.length!==1||p("p208-legacy-authority-before-v1",i[0])!==e)throw new Error("YOLOOP_CONTINUATION_RECOVERY_BEFORE_MISMATCH");const h=p("p208-legacy-authority-after-v1",n);if(s.beforeHash!==e||s.afterHash!==h)throw new Error("YOLOOP_CONTINUATION_RECOVERY_HASH_MISMATCH");const O={...s};if(delete O.idempotencyKey,!c||p("p208-legacy-authority-recovery-receipt-v1",O)!==c)throw new Error("YOLOOP_CONTINUATION_RECOVERY_RECEIPT_INVALID");await this.writeState({...r,pendingContinuationAuthorities:[n],continuationRecoveryReceipts:[...a.slice(-63),s]})}async switchContinuationPolicy(e,n,s){const o=await this.readState(s);if(o.currentSession||(o.pendingContinuationAuthorities?.length??0)>0)throw new Error("YOLOOP_POLICY_SWITCH_ACTIVE");try{await u.copyFile(this.statePath,`${this.statePath}.policy-backup`)}catch(r){if(r.code!=="ENOENT")throw r}await this.writeState({...o,continuationPolicy:e,continuationSession:n})}async appendRecoveryAttempt(e,n){const s=await this.readState(n),o=s.recovery_history??[];if(o.some(c=>c.attempted_at===e.attempted_at&&c.story_id===e.story_id)){this.logger.warn({event:"recovery_attempted_duplicate",story_id:e.story_id},"duplicate recovery_attempted op; skipping");return}const i=H([...o,e]),a={...s,recovery_history:i};await this.writeState(a),this.logger.info({event:"recovery_attempted_persisted",story_id:e.story_id,history_size:i.length},"recovery attempt persisted")}async resolveRecoveryAttempt(e,n,s){const o=await this.readState(s),r=o.recovery_history??[],i=r.findIndex(h=>h.recovery_step_id_tokenized===e);if(i===-1){this.logger.warn({event:"recovery_resolve_orphan",attempt_id:e},"recovery_resolved op had no matching attempt; skipping");return}const a=r[i];if(a.outcome===n&&a.finished_at){this.logger.info({event:"recovery_resolved_duplicate",attempt_id:e,outcome:n},"duplicate recovery_resolved op; skipping");return}const c=r.slice();c[i]={...a,outcome:n,finished_at:s};const l={...o,recovery_history:c};await this.writeState(l),this.logger.info({event:"recovery_resolved_persisted",attempt_id:e,outcome:n},"recovery attempt resolved")}async acquireLock(e,n){const s={...e,pid:process.pid,hostname:I(),ownerKind:"client",startedAt:e.startedAt||n,leaseId:e.leaseId??ne(e.sessionId,n),leaseState:"active",leaseAcquiredAt:e.leaseAcquiredAt??n,leaseDurationMs:e.leaseDurationMs??q,leaseExpiresAt:e.leaseExpiresAt??e.ttlExpiresAt},o=JSON.stringify(s,null,2);try{const r=await u.open(this.lockPath,"wx");try{await r.writeFile(o,"utf8")}finally{await r.close()}this.trySetFilePerms(this.lockPath),this.logger.info({event:"yoloop_lock_acquired",pid:s.pid,sessionId:s.sessionId},"yoloop lock acquired");return}catch(r){const i=r;if(i.code!=="EEXIST")throw this.logger.error({event:"yoloop_lock_acquire_error",err:i.message},"failed to acquire yoloop lock"),r;const a=await this.readLock();if(a&&this.isSameClientSessionLock(a,s)){this.logger.info({event:"yoloop_lock_acquire_duplicate",sessionId:s.sessionId},"duplicate acquire_lock for current yoloop session; treating as no-op");return}if(!await this.maybeRecoverOrphanLock(n))throw this.logger.warn({event:"yoloop_lock_held"},"yoloop lock held by another live process"),r;const l=await u.open(this.lockPath,"wx");try{await l.writeFile(o,"utf8")}finally{await l.close()}this.trySetFilePerms(this.lockPath),this.logger.info({event:"yoloop_lock_acquired_after_recovery",pid:s.pid},"yoloop lock acquired after orphan recovery")}}async releaseLock(e){const n=await this.readState(new Date().toISOString()),s=await this.readLock();if(n.runControl){if(!e.expectedRunId||!e.expectedSessionId||!e.expectedLeaseId)throw new Error("YOLOOP_RUN_REVISION_CONFLICT");if(e.expectedRunId!==n.runControl.runId)throw new Error("YOLOOP_RUN_REVISION_CONFLICT");if(!s||e.expectedSessionId!==s.sessionId||e.expectedLeaseId!==s.leaseId)throw new Error("YOLOOP_RUN_OPERATION_CONFLICT")}try{await u.unlink(this.lockPath),this.logger.info({event:"yoloop_lock_released"},"yoloop lock released")}catch(o){const r=o;if(r.code==="ENOENT"){this.logger.info({event:"yoloop_lock_release_noop"},"yoloop lock release noop (file absent)");return}this.logger.warn({event:"yoloop_lock_release_error",err:r.message},"unexpected error releasing yoloop lock")}}async readLock(){try{const e=await u.readFile(this.lockPath,"utf8"),n=JSON.parse(e),s=n.currentEpicId??n.epicId??"";return{pid:n.pid??0,hostname:n.hostname??"",...n.ownerKind?{ownerKind:n.ownerKind}:{},...n.ownerPidState?{ownerPidState:n.ownerPidState}:{},...typeof n.leaseId=="string"?{leaseId:n.leaseId}:{},...n.leaseState?{leaseState:n.leaseState}:{},...typeof n.leaseAcquiredAt=="string"?{leaseAcquiredAt:n.leaseAcquiredAt}:{},...typeof n.leaseDurationMs=="number"?{leaseDurationMs:n.leaseDurationMs}:{},...typeof n.leaseExpiresAt=="string"?{leaseExpiresAt:n.leaseExpiresAt}:{},startedAt:n.startedAt??"",sessionId:n.sessionId??"",mode:n.mode??"epic-id",inputPath:n.inputPath??"",epicQueue:n.epicQueue??(s?[s]:[]),currentEpicIndex:n.currentEpicIndex??0,currentEpicId:s,ttlExpiresAt:n.ttlExpiresAt??"",epicId:n.epicId??s}}catch{return null}}async readState(e){try{const n=await u.readFile(this.statePath,"utf8"),s=JSON.parse(n);return se(s,e)}catch(n){const s=n;return s.code!=="ENOENT"&&this.logger.warn({event:"yoloop_state_read_error",err:s.message},"yoloop state file unreadable; using defaults"),S(e)}}async writeState(e){const n=`${this.statePath}.tmp.${process.pid}.${Date.now()}`,s=JSON.stringify(e,null,2);try{const o=await u.open(n,"w",384);try{await o.writeFile(s,"utf8"),await o.sync()}finally{await o.close()}this.trySetFilePerms(n),await u.rename(n,this.statePath),await this.syncStateDirectory()}catch(o){const r=o;this.logger.error({event:"yoloop_state_write_error",err:r.message},"failed to write yoloop state");try{await u.unlink(n)}catch{}throw o}}async rolloverSession(e,n){f(e);const s=await this.readRolloverManifest();if(s){if(G(s.operation,e)){if(s.operation.payloadHash!==e.payloadHash)throw new Error("YOLOOP_SESSION_ROLLOVER_CONFLICT");if(s.phase==="applied")return;await this.completePreparedSessionRollover(s.operation,n);return}else if(s.phase==="prepared")throw new Error("YOLOOP_SESSION_ROLLOVER_CONFLICT")}const o=await this.readState(n),r=await this.readLock();P(e,o,r),await this.writeRolloverManifest({schemaVersion:"YoloopSessionRolloverManifest/1.0",phase:"prepared",operation:e}),await this.completePreparedSessionRollover(e,n)}async completePreparedSessionRollover(e,n){const s=await this.readState(n);let o=d(s)===d(e.next);if(!o){const i=await this.readLock();P(e,s,i),await this.writeState(e.next),o=!0}const r=await this.readLock();if(e.expectedSessionId===null||e.expectedLeaseId===null){if(e.expectedSessionId!==null||e.expectedLeaseId!==null||r)throw new Error("YOLOOP_SESSION_ROLLOVER_LOCK_CONFLICT")}else if(r){if(r.sessionId!==e.expectedSessionId||r.leaseId!==e.expectedLeaseId)throw new Error("YOLOOP_SESSION_ROLLOVER_LOCK_CONFLICT");await u.unlink(this.lockPath),await this.syncStateDirectory()}else if(!o)throw new Error("YOLOOP_SESSION_ROLLOVER_LOCK_CONFLICT");await this.writeRolloverManifest({schemaVersion:"YoloopSessionRolloverManifest/1.0",phase:"applied",operation:e}),this.logger.info({event:"yoloop_session_rollover_applied",runId:e.runId,operationId:e.operationId,coolDownUntil:e.coolDownUntil},"yoloop per-run-cap session rollover applied")}async recoverSessionRolloverIfPresent(e){try{await u.access(this.rolloverManifestPath)}catch(n){if(n.code==="ENOENT")return;throw n}await this.ensureDir(),await this.withMutationLock(async()=>{const n=await this.readRolloverManifest();n?.phase==="prepared"&&await this.completePreparedSessionRollover(n.operation,e)})}async readRolloverManifest(){try{const e=JSON.parse(await u.readFile(this.rolloverManifestPath,"utf8"));if(e.schemaVersion!=="YoloopSessionRolloverManifest/1.0"||e.phase!=="prepared"&&e.phase!=="applied"||!e.operation||e.operation.type!=="rollover_session")throw new Error("YOLOOP_SESSION_ROLLOVER_MANIFEST_CORRUPT");return f(e.operation),e}catch(e){if(e.code==="ENOENT")return null;throw e.message==="YOLOOP_SESSION_ROLLOVER_MANIFEST_CORRUPT"?e:new Error("YOLOOP_SESSION_ROLLOVER_MANIFEST_CORRUPT")}}async writeRolloverManifest(e){const n=`${this.rolloverManifestPath}.tmp.${process.pid}.${Date.now()}`,s=await u.open(n,"w",384);try{await s.writeFile(JSON.stringify(e,null,2),"utf8"),await s.sync()}finally{await s.close()}this.trySetFilePerms(n),await u.rename(n,this.rolloverManifestPath),await this.syncStateDirectory()}async advanceEpic(e,n,s){const o=await this.readState(s);if(!o.currentSession){this.logger.warn({event:"yoloop_advance_no_session",nextEpicId:n},"advance_epic with no active session; skipping");return}const r={...o,currentSession:{...o.currentSession,currentEpicIndex:e}};await this.writeState(r),this.logger.info({event:"yoloop_epic_advance",nextEpicId:n,nextIndex:e},"yoloop advanced to next epic")}async ensureDir(){try{await u.mkdir(this.stateDir,{recursive:!0}),this.trySetDirPerms(this.stateDir)}catch(e){const n=e;throw this.logger.error({event:"yoloop_mkdir_error",err:n.message,path:this.stateDir},"failed to ensure .neocortex/ directory"),e}}async syncStateDirectory(){try{const e=await u.open(this.stateDir,"r");try{await e.sync()}finally{await e.close()}}catch(e){const n=e.code;if(n!=="EINVAL"&&n!=="EISDIR"&&n!=="ENOTSUP"&&n!=="EPERM")throw e}}async withMutationLock(e){let n=null;for(let s=0;s<B;s+=1)try{n=await u.open(this.mutationLockPath,"wx",384),await n.writeFile(JSON.stringify({pid:process.pid,acquiredAt:new Date().toISOString()})),await n.sync();break}catch(o){if(o.code!=="EEXIST")throw o;try{const r=await u.stat(this.mutationLockPath);if(Date.now()-r.mtimeMs>$){await u.unlink(this.mutationLockPath);continue}}catch{continue}await new Promise(r=>setTimeout(r,5))}if(!n)throw new Error("YOLOOP_RUN_REVISION_CONFLICT");try{return await e()}finally{await n.close().catch(()=>{}),await u.unlink(this.mutationLockPath).catch(()=>{})}}async transitionRun(e,n){v(e);const s=await this.readState(n),o=s.runControl,r=o?.receipts.find(l=>l.operationId===e.operationId||l.idempotencyKey===e.idempotencyKey);if(r){if(r.operationId===e.operationId&&r.idempotencyKey===e.idempotencyKey&&r.payloadHash===e.payloadHash)return r;throw new Error("YOLOOP_RUN_OPERATION_CONFLICT")}if(o&&o.runId!==e.runId)throw new Error("YOLOOP_RUN_REVISION_CONFLICT");if((o?.revision??0)!==e.expectedRevision)throw new Error("YOLOOP_RUN_REVISION_CONFLICT");if((o?.latestSnapshotHash??null)!==e.expectedSnapshotHash)throw new Error("YOLOOP_RUN_SNAPSHOT_CONFLICT");E(o,e);const c=e.next.receipts.at(-1);if(!c)throw new Error("YOLOOP_RUN_OPERATION_CONFLICT");return await this.writeState({...s,version:"1.2",runControl:e.next}),this.logger.info({event:"yoloop_run_transition_committed",runId:e.runId,operationId:e.operationId,revision:c.revision,status:c.status},"yoloop run transition committed"),c}async startSuccessorRun(e,n){X(e);const s=await this.readState(n),o=s.runControl,r={schemaVersion:"YoloopRunPredecessor/1.0",runId:e.previousRunId,revision:e.expectedRevision,snapshotHash:e.expectedSnapshotHash,successorOperationId:e.operationId,publicSafe:!0},i=o?.receipts.find(l=>l.operationId===e.operationId||l.idempotencyKey===e.idempotencyKey);if(i){if(i.operationId===e.operationId&&i.idempotencyKey===e.idempotencyKey&&e.next.receipts.at(-1)?.payloadHash===i.payloadHash&&d(o?.predecessor)===d(r))return i;throw new Error("YOLOOP_RUN_OPERATION_CONFLICT")}if(!o||o.runId!==e.previousRunId||o.status!=="exhausted"||o.revision!==e.expectedRevision||o.latestSnapshotHash!==e.expectedSnapshotHash||s.currentSession!==null||!s.coolDownUntil||Date.parse(s.coolDownUntil)>Date.parse(n))throw new Error("YOLOOP_RUN_SUCCESSOR_CONFLICT");const a=e.next.receipts.at(-1);if(!a||d(e.next.predecessor)!==d(r))throw new Error("YOLOOP_RUN_SUCCESSOR_CONFLICT");const c={type:"transition_run",runId:e.runId,operationId:e.operationId,idempotencyKey:e.idempotencyKey,expectedRevision:0,expectedSnapshotHash:null,payloadHash:a.payloadHash,next:e.next};return v(c),E(void 0,c),await this.writeState({...s,version:"1.2",runControl:e.next}),a}trySetFilePerms(e){try{F(e)}catch{}}trySetDirPerms(e){try{K(e)}catch{}}async prepareLockForSnapshot(e,n){if(!e)return null;if(e.ownerKind!=="client")return e;const s=k(e,n),o={...e,leaseState:s};if(s==="expired")return await this.deleteLockBestEffort(),this.logger.warn({event:"yoloop_client_lock_recovered",reason:"lease_expired"},"expired client-owned yoloop lock lease recovered before snapshot echo"),null;if(!o.pid||o.pid<=0)return await this.deleteLockBestEffort(),this.logger.warn({event:"yoloop_client_lock_recovered",reason:"invalid_pid"},"invalid PID in client-owned yoloop lock; recovered"),null;if(o.hostname&&o.hostname!==I())return{...o,ownerPidState:"unknown"};try{return process.kill(o.pid,0),{...o,ownerPidState:"live"}}catch{return await this.deleteLockBestEffort(),this.logger.warn({event:"yoloop_client_lock_recovered",reason:"dead_pid"},"stale client-owned yoloop lock recovered before snapshot echo"),null}}async maybeRecoverOrphanLock(e){const n=await this.readLock();if(!n)return!0;if(k(n,e)==="expired")return await this.deleteLockBestEffort(),this.logger.warn({event:"yoloop_orphan_lock_recovered",reason:"lease_expired"},"expired yoloop lock lease recovered"),!0;if(!n.pid||n.pid<=0)return await this.deleteLockBestEffort(),this.logger.warn({event:"yoloop_orphan_lock_recovered",reason:"invalid_pid"},"invalid PID in lock file; recovered"),!0;if(n.hostname&&n.hostname!==I())return this.logger.warn({event:"yoloop_lock_remote_host",ownerKind:n.ownerKind??"server",ownerPidState:"unknown"},"lock held by a remote host; honoring"),!1;try{return process.kill(n.pid,0),!1}catch{return await this.deleteLockBestEffort(),this.logger.warn({event:"yoloop_orphan_lock_recovered",reason:"dead_pid"},"orphan yoloop lock recovered"),!0}}async deleteLockBestEffort(){try{await u.unlink(this.lockPath)}catch{}}isSameClientSessionLock(e,n){return e.ownerKind==="client"&&e.sessionId===n.sessionId&&e.pid===process.pid&&e.hostname===I()}async cleanupOrphanTempFiles(){try{const e=U(this.statePath),n=await u.readdir(e),s=[`${m}.tmp.`,`${T}.tmp.`],o=n.filter(r=>s.some(i=>r.startsWith(i)));for(const r of o)try{await u.unlink(_(e,r))}catch{}}catch{}}}function d(t){return t===null||typeof t!="object"?JSON.stringify(t):Array.isArray(t)?`[${t.map(d).join(",")}]`:`{${Object.entries(t).filter(([,e])=>e!==void 0).sort(([e],[n])=>e.localeCompare(n)).map(([e,n])=>`${JSON.stringify(e)}:${d(n)}`).join(",")}}`}function p(t,e){return Y("sha256").update(`${t}\0${d(e)}`).digest("hex")}function j(t){return p("p9390812898200217364-yoloop-session-v1",t)}function z(t){return p("p9390812898200217364-yoloop-rollover-v1",t)}function W(t){return p("p9390812898200217364-yoloop-successor-run-v1",t)}function G(t,e){return t.operationId===e.operationId&&t.idempotencyKey===e.idempotencyKey}function f(t){const e=/^[A-Za-z0-9._:-]{1,128}$/,n={runId:t.runId,operationId:t.operationId,idempotencyKey:t.idempotencyKey,expectedRevision:t.expectedRevision,expectedSnapshotHash:t.expectedSnapshotHash,expectedSessionId:t.expectedSessionId,expectedSessionFingerprint:t.expectedSessionFingerprint,expectedLeaseId:t.expectedLeaseId,coolDownUntil:t.coolDownUntil,reason:t.reason,exhaustedRun:t.exhaustedRun,next:t.next};if(!e.test(t.runId)||!e.test(t.operationId)||!e.test(t.idempotencyKey)||!/^[a-f0-9]{64}$/.test(t.expectedSessionFingerprint)||!/^[a-f0-9]{64}$/.test(t.payloadHash)||!Number.isSafeInteger(t.expectedRevision)||t.expectedRevision<0||!Number.isFinite(Date.parse(t.coolDownUntil))||!["YOLOOP_PER_RUN_CAP_REACHED","YOLOOP_SESSION_TIMEOUT"].includes(t.reason)||t.payloadHash!==z(n)||t.receipt.schemaVersion!=="YoloopSessionRolloverReceipt/1.0"||t.receipt.runId!==t.runId||t.receipt.operationId!==t.operationId||t.receipt.idempotencyKey!==t.idempotencyKey||t.receipt.payloadHash!==t.payloadHash||t.receipt.coolDownUntil!==t.coolDownUntil||t.receipt.revision!==(t.exhaustedRun?.revision??0)||t.receipt.snapshotHash!==(t.exhaustedRun?.latestSnapshotHash??null)||t.receipt.status!=="exhausted"||t.receipt.publicSafe!==!0)throw new Error("YOLOOP_SESSION_ROLLOVER_CONFLICT");if(t.expectedSessionId===null!=(t.expectedLeaseId===null)||t.expectedSessionId!==null&&!e.test(t.expectedSessionId)||t.expectedLeaseId!==null&&!e.test(t.expectedLeaseId))throw new Error("YOLOOP_SESSION_ROLLOVER_LOCK_CONFLICT")}function X(t){const e=/^[A-Za-z0-9._:-]{1,128}$/,n={runId:t.runId,previousRunId:t.previousRunId,operationId:t.operationId,idempotencyKey:t.idempotencyKey,expectedRevision:t.expectedRevision,expectedSnapshotHash:t.expectedSnapshotHash,next:t.next};if(!e.test(t.runId)||!e.test(t.previousRunId)||t.runId===t.previousRunId||!e.test(t.operationId)||!e.test(t.idempotencyKey)||!/^[a-f0-9]{64}$/.test(t.payloadHash)||!Number.isSafeInteger(t.expectedRevision)||t.expectedRevision<1||t.payloadHash!==W(n))throw new Error("YOLOOP_RUN_SUCCESSOR_CONFLICT")}function P(t,e,n){f(t);const s=e.currentSession;if(!s||j(s)!==t.expectedSessionFingerprint)throw new Error("YOLOOP_SESSION_ROLLOVER_SESSION_CONFLICT");const o=e.runControl;if((o?.revision??0)!==t.expectedRevision||(o?.latestSnapshotHash??null)!==t.expectedSnapshotHash||o&&o.runId!==t.runId)throw new Error("YOLOOP_RUN_REVISION_CONFLICT");if(t.expectedSessionId===null||t.expectedLeaseId===null){if(n)throw new Error("YOLOOP_SESSION_ROLLOVER_LOCK_CONFLICT")}else if(!n||n.sessionId!==t.expectedSessionId||n.leaseId!==t.expectedLeaseId)throw new Error("YOLOOP_SESSION_ROLLOVER_LOCK_CONFLICT");const r=t.exhaustedRun;if(o)if(o.status==="exhausted"){if(d(r)!==d(o))throw new Error("YOLOOP_SESSION_ROLLOVER_STATE_CONFLICT")}else{if(!r||r.status!=="exhausted")throw new Error("YOLOOP_SESSION_ROLLOVER_STATE_CONFLICT");const a=r.receipts.at(-1);if(!a)throw new Error("YOLOOP_SESSION_ROLLOVER_STATE_CONFLICT");const c={type:"transition_run",runId:o.runId,operationId:a.operationId,idempotencyKey:a.idempotencyKey,expectedRevision:o.revision,expectedSnapshotHash:o.latestSnapshotHash,payloadHash:a.payloadHash,next:r};v(c),E(o,c)}else if(r)throw new Error("YOLOOP_SESSION_ROLLOVER_STATE_CONFLICT");const i={...e,version:"1.2",coolDownUntil:t.coolDownUntil,currentSession:null,...r?{runControl:r}:{}};if(d(i)!==d(t.next))throw new Error("YOLOOP_SESSION_ROLLOVER_STATE_CONFLICT")}function A(t){const{receipts:e,...n}=t.next;return p("p220-yoloop-run-transition-payload-v1",{runId:t.runId,operationId:t.operationId,idempotencyKey:t.idempotencyKey,expectedRevision:t.expectedRevision,expectedSnapshotHash:t.expectedSnapshotHash,next:n})}const R=new Set(["success","partial","blocked","failure","exhausted","cancelled"]),Q={created:["running","cancelling","exhausted"],running:["pausing","cancelling","success","partial","blocked","failure","exhausted"],pausing:["paused","cancelling","failure","exhausted"],paused:["resuming","cancelling","exhausted"],resuming:["running","cancelling","failure","exhausted"],cancelling:["cancelled","failure","exhausted"]};function Z(t,e){return e==="pause"?t==="running"?"pausing":null:e==="resume"?t==="paused"?"resuming":null:R.has(t)||t==="cancelling"?null:"cancelling"}function ee(t){const e=t.current.revision+1,n=t.action==="cancel"?["YOLOOP_RUN_CANCEL_REQUESTED"]:[],s={schemaVersion:"YoloopOperationalBudgetSummary/1.0",limits:t.current.operationalBudget.limits,usage:t.current.usage,exhaustedDimension:null},o={schemaVersion:"ProgressSnapshot/1.0",runId:t.current.runId,sequence:t.current.progressSnapshots.length+1,revision:e,operationId:t.operationId,boundary:t.action,phase:"before",status:t.current.status,occurredAt:t.occurredAt,parentSnapshotHash:t.current.latestSnapshotHash,budget:s,reasonCodes:n,publicSafe:!0},r=p("p220-yoloop-progress-snapshot-id-v1",{runId:o.runId,operationId:o.operationId,sequence:o.sequence,phase:o.phase}),i={...o,snapshotId:r,snapshotHash:p("p220-yoloop-progress-snapshot-v1",{...o,snapshotId:r})},a={...o,sequence:i.sequence+1,phase:"after",status:t.target,parentSnapshotHash:i.snapshotHash},c=p("p220-yoloop-progress-snapshot-id-v1",{runId:a.runId,operationId:a.operationId,sequence:a.sequence,phase:a.phase}),l={...a,snapshotId:c,snapshotHash:p("p220-yoloop-progress-snapshot-v1",{...a,snapshotId:c})},h={schemaVersion:"YoloopRunEvent/1.0",runId:t.current.runId,operationId:t.operationId,kind:"intent",sequence:t.current.events.length+1,revision:e,occurredAt:t.occurredAt,fromStatus:t.current.status,toStatus:t.target,reasonCodes:n,budgetDimension:null,parentEventHash:t.current.events.at(-1)?.eventHash??null,publicSafe:!0},O=p("p220-yoloop-run-event-id-v1",{runId:h.runId,operationId:h.operationId,sequence:h.sequence}),y={...h,eventId:O,eventHash:p("p220-yoloop-run-event-v1",{...h,eventId:O})},w={...t.current,revision:e,status:t.target,events:[...t.current.events,y],progressSnapshots:[...t.current.progressSnapshots,i,l],latestSnapshotHash:l.snapshotHash,receipts:[...t.current.receipts]},L={runId:t.current.runId,operationId:t.operationId,idempotencyKey:t.idempotencyKey,expectedRevision:t.current.revision,expectedSnapshotHash:t.current.latestSnapshotHash,next:w},N=A(L),D={schemaVersion:"YoloopRunTransitionReceipt/1.0",runId:t.current.runId,operationId:t.operationId,idempotencyKey:t.idempotencyKey,payloadHash:N,revision:e,snapshotHash:l.snapshotHash,status:t.target};return{type:"transition_run",...L,payloadHash:N,next:{...w,receipts:[...w.receipts,D]}}}function v(t){const e=/^[A-Za-z0-9._:-]{1,128}$/;if(!e.test(t.runId)||!e.test(t.operationId)||!e.test(t.idempotencyKey)||!/^[a-f0-9]{64}$/.test(t.payloadHash)||!Number.isSafeInteger(t.expectedRevision)||t.expectedRevision<0)throw new Error("YOLOOP_RUN_OPERATION_CONFLICT");if(t.payloadHash!==A(t))throw new Error("YOLOOP_RUN_OPERATION_CONFLICT")}function E(t,e){const n=e.next,s=t?.events??[],o=t?.progressSnapshots??[],r=t?.receipts??[];if(n.schemaVersion!=="YoloopRunControl/1.0"||n.runId!==e.runId||n.revision!==e.expectedRevision+1||n.events.length!==s.length+1||n.progressSnapshots.length!==o.length+2||n.receipts.length!==r.length+1||d(n.events.slice(0,s.length))!==d(s)||d(n.progressSnapshots.slice(0,o.length))!==d(o)||d(n.receipts.slice(0,r.length))!==d(r))throw new Error("YOLOOP_RUN_TRANSITION_INVALID");if(t){if(R.has(t.status))throw new Error("YOLOOP_RUN_TERMINAL");const h=n.progressSnapshots.at(-2)?.boundary,O=t.status===n.status&&(h==="budget"||h==="retry");if(!(Q[t.status]??[]).includes(n.status)&&!O)throw new Error("YOLOOP_RUN_TRANSITION_INVALID");if(t.startedAt!==n.startedAt||t.deadlineAt!==n.deadlineAt)throw new Error("YOLOOP_RUN_TRANSITION_INVALID");if(d(t.predecessor)!==d(n.predecessor))throw new Error("YOLOOP_RUN_TRANSITION_INVALID")}else if(n.status!=="created")throw new Error("YOLOOP_RUN_TRANSITION_INVALID");const i=n.progressSnapshots.at(-2),a=n.progressSnapshots.at(-1),c=n.events.at(-1),l=n.receipts.at(-1);if(!i||!a||!c||!l||i.phase!=="before"||a.phase!=="after"||i.operationId!==e.operationId||a.operationId!==e.operationId||c.operationId!==e.operationId||i.runId!==e.runId||a.runId!==e.runId||c.runId!==e.runId||i.revision!==n.revision||a.revision!==n.revision||c.revision!==n.revision||i.parentSnapshotHash!==(t?.latestSnapshotHash??null)||a.parentSnapshotHash!==i.snapshotHash||n.latestSnapshotHash!==a.snapshotHash||l.schemaVersion!=="YoloopRunTransitionReceipt/1.0"||l.runId!==e.runId||l.operationId!==e.operationId||l.idempotencyKey!==e.idempotencyKey||l.payloadHash!==e.payloadHash||l.revision!==n.revision||l.snapshotHash!==n.latestSnapshotHash||l.status!==n.status||Date.parse(n.deadlineAt)<=Date.parse(n.startedAt))throw new Error("YOLOOP_RUN_TRANSITION_INVALID");x(i),x(a),te(c,s.at(-1)?.eventHash??null)}function x(t){const{snapshotHash:e,...n}=t;if(e!==p("p220-yoloop-progress-snapshot-v1",n))throw new Error("YOLOOP_RUN_SNAPSHOT_CONFLICT")}function te(t,e){const{eventHash:n,...s}=t;if(t.parentEventHash!==e||n!==p("p220-yoloop-run-event-v1",s))throw new Error("YOLOOP_RUN_SNAPSHOT_CONFLICT")}function ne(t,e){return`lease-${oe(`${t}:${e}`)}`}function oe(t){let e=2166136261;for(let n=0;n<t.length;n+=1)e^=t.charCodeAt(n),e=Math.imul(e,16777619)>>>0;return e.toString(36).padStart(7,"0")}function k(t,e){const n=t.leaseExpiresAt??t.ttlExpiresAt,s=Date.parse(n),o=Date.parse(e);return!Number.isFinite(s)||!Number.isFinite(o)?"unknown":s<=o?"expired":"active"}function se(t,e){const n=S(e);return{...t,version:t.version==="1.2"?"1.2":"1.1",lastResetAt:t.lastResetAt??n.lastResetAt,storiesRunToday:t.storiesRunToday??0,iterationsToday:t.iterationsToday??0,iterationsTodayDate:t.iterationsTodayDate??n.iterationsTodayDate,tokensUsedToday:t.tokensUsedToday??0,lastRunAt:t.lastRunAt??null,coolDownUntil:t.coolDownUntil??null,totalRunsAllTime:t.totalRunsAllTime??0,totalStoriesAllTime:t.totalStoriesAllTime??0,currentSession:t.currentSession??null,...t.runControl!==void 0?{runControl:t.runControl}:{},...t.continuationPolicy!==void 0?{continuationPolicy:t.continuationPolicy}:{},...t.continuationSession!==void 0?{continuationSession:t.continuationSession}:{},...t.pendingContinuationAuthorities!==void 0?{pendingContinuationAuthorities:t.pendingContinuationAuthorities}:{},...t.continuationReceipts!==void 0?{continuationReceipts:t.continuationReceipts}:{},...t.continuationRecoveryReceipts!==void 0?{continuationRecoveryReceipts:t.continuationRecoveryReceipts}:{},recovery_history:Array.isArray(t.recovery_history)?H(t.recovery_history):[]}}function H(t){return t.length<=g?t:t.slice(t.length-g)}export{C as YOLOOP_PERSISTENCE_CAPABILITIES,he as YoloopClientStateStore,A as buildYoloopRunTransitionPayloadHash,z as buildYoloopSessionRolloverPayloadHash,W as buildYoloopSuccessorRunPayloadHash,H as capRecoveryHistory,S as createDefaultCounters,ue as createDefaultState,j as fingerprintYoloopSession};
|
|
1
|
+
import{promises as u}from"node:fs";import{createHash as D}from"node:crypto";import{join as _,dirname as U}from"node:path";import{hostname as I}from"node:os";import{setSecureFilePermissions as F,setSecureDirPermissions as K}from"../config/secure-config.js";import{RECOVERY_HISTORY_CAP as g}from"./shared-yoloop-types.js";const b=".neocortex",m="yoloop-state.json",V="yoloop.lock",M="yoloop-state.mutation.lock",T="yoloop-session-rollover.json",q=360*60*1e3,$=3e4,B=200,C=Object.freeze(["rollover-session-v1"]),J={warn:()=>{},info:()=>{},error:()=>{}};function S(t){const e=t.slice(0,10);return{version:"1.1",lastResetAt:t,storiesRunToday:0,iterationsToday:0,iterationsTodayDate:e,tokensUsedToday:0,lastRunAt:null,coolDownUntil:null,totalRunsAllTime:0,totalStoriesAllTime:0,currentSession:null,continuationPolicy:"p205-finite-resume-v2",pendingContinuationAuthorities:[],continuationReceipts:[],continuationRecoveryReceipts:[]}}function ue(t){return{lock:null,state:S(t),capabilities:C}}class he{stateDir;statePath;lockPath;mutationLockPath;rolloverManifestPath;logger;constructor(e,n=J){this.stateDir=_(e,b),this.statePath=_(this.stateDir,m),this.lockPath=_(this.stateDir,V),this.mutationLockPath=_(this.stateDir,M),this.rolloverManifestPath=_(this.stateDir,T),this.logger=n}async readAll(e){const n=e??new Date().toISOString();await this.cleanupOrphanTempFiles(),await this.recoverSessionRolloverIfPresent(n);const[r,s]=await Promise.all([this.readLock(),this.readState(n)]);return{lock:await this.prepareLockForSnapshot(r,n),state:s,capabilities:C}}async applyUpdate(e,n){const r=n??new Date().toISOString();await this.ensureDir(),await this.recoverSessionRolloverIfPresent(r);for(const s of e.operations)await this.applyOperation(s,r)}async requestRunTransition(e,n){const r=n??new Date().toISOString();return await this.ensureDir(),this.withMutationLock(()=>this.transitionRun(e,r))}async requestLifecycleAction(e,n={},r){const s=r??new Date().toISOString();return await this.ensureDir(),this.withMutationLock(async()=>{const i=(await this.readState(s)).runControl;if(!i)throw new Error("YOLOOP_RUN_TRANSITION_INVALID");const a=Date.parse(s).toString(36),c=n.operationId??`op-${e}-${a}`,l=n.idempotencyKey??`idem-${e}-${a}`,h=i.receipts.find(O=>O.operationId===c||O.idempotencyKey===l);if(h){if(h.operationId===c&&h.idempotencyKey===l)return h;throw new Error("YOLOOP_RUN_OPERATION_CONFLICT")}const y=Z(i.status,e);if(!y)throw new Error(R.has(i.status)?"YOLOOP_RUN_TERMINAL":"YOLOOP_RUN_TRANSITION_INVALID");return this.transitionRun(ee({current:i,action:e,target:y,operationId:c,idempotencyKey:l,occurredAt:s}),s)})}async applyOperation(e,n){switch(e.type){case"acquire_lock":await this.acquireLock(e.lock,n);return;case"release_lock":await this.releaseLock(e);return;case"write_state":await this.withMutationLock(async()=>{const r=await this.readState(n),{runControl:s,...o}=e.state;await this.writeState({...o,...r.runControl?{version:"1.2",runControl:r.runControl}:{}})});return;case"advance_epic":await this.advanceEpic(e.nextEpicIndex,e.nextEpicId,n);return;case"no_op":this.logger.info({event:"yoloop_noop"},"yoloop server sent no-op");return;case"reserve_continuation_authority":await this.reserveContinuationAuthority(e.authority,n);return;case"acknowledge_continuation_authority":await this.acknowledgeContinuationAuthority(e.idempotencyKey,e.receipt,n);return;case"repair_continuation_authority":await this.repairContinuationAuthority(e.beforeHash,e.authority,e.receipt,n);return;case"switch_continuation_policy":await this.switchContinuationPolicy(e.policy,e.session,n);return;case"transition_run":await this.requestRunTransition(e,n);return;case"start_successor_run":await this.withMutationLock(()=>this.startSuccessorRun(e,n));return;case"rollover_session":await this.withMutationLock(()=>this.rolloverSession(e,n));return;case"recovery_attempted":await this.appendRecoveryAttempt(e.attempt,n);return;case"recovery_resolved":await this.resolveRecoveryAttempt(e.attempt_id,e.outcome,n);return;default:{const r=e;throw this.logger.error({event:"yoloop_unknown_op",op:r},"unknown yoloop operation rejected"),new Error("YOLOOP_STATE_OPERATION_UNSUPPORTED")}}}async reserveContinuationAuthority(e,n){const r=await this.readState(n),s=r.pendingContinuationAuthorities??[],o=typeof e.idempotencyKey=="string"?e.idempotencyKey:"";if(!o)throw new Error("YOLOOP_CONTINUATION_AUTHORITY_INVALID");const i=s.find(a=>a.idempotencyKey===o);if(i){if(d(i)===d(e))return;throw new Error("YOLOOP_CONTINUATION_AUTHORITY_CONFLICT")}if(s.length>=64)throw new Error("YOLOOP_PENDING_AUTHORITY_CAPACITY_EXCEEDED");await this.writeState({...r,pendingContinuationAuthorities:[...s,e]})}async acknowledgeContinuationAuthority(e,n,r){const s=await this.readState(r),o=s.pendingContinuationAuthorities??[],i=o.findIndex(h=>h.idempotencyKey===e);if(i<0)throw new Error("YOLOOP_CONTINUATION_RECEIPT_ORPHAN");const a=o[i];if(n.idempotencyKey!==e||n.sessionId!==a.sessionId||JSON.stringify(n.storyIds)!==JSON.stringify(a.storyIds))throw new Error("YOLOOP_CONTINUATION_RECEIPT_MISMATCH");const c=o.filter((h,y)=>y!==i),l=s.continuationReceipts??[];await this.writeState({...s,pendingContinuationAuthorities:c,continuationReceipts:[...l.slice(-63),n]})}async repairContinuationAuthority(e,n,r,s){const o=await this.readState(s),i=o.pendingContinuationAuthorities??[],a=o.continuationRecoveryReceipts??[],c=typeof r.idempotencyKey=="string"?r.idempotencyKey:"",l=a.find(O=>O.idempotencyKey===c);if(l){if(d(l)===d(r))return;throw new Error("YOLOOP_CONTINUATION_RECOVERY_RECEIPT_CONFLICT")}if(i.length!==1||p("p208-legacy-authority-before-v1",i[0])!==e)throw new Error("YOLOOP_CONTINUATION_RECOVERY_BEFORE_MISMATCH");const h=p("p208-legacy-authority-after-v1",n);if(r.beforeHash!==e||r.afterHash!==h)throw new Error("YOLOOP_CONTINUATION_RECOVERY_HASH_MISMATCH");const y={...r};if(delete y.idempotencyKey,!c||p("p208-legacy-authority-recovery-receipt-v1",y)!==c)throw new Error("YOLOOP_CONTINUATION_RECOVERY_RECEIPT_INVALID");await this.writeState({...o,pendingContinuationAuthorities:[n],continuationRecoveryReceipts:[...a.slice(-63),r]})}async switchContinuationPolicy(e,n,r){const s=await this.readState(r);if(s.currentSession||(s.pendingContinuationAuthorities?.length??0)>0)throw new Error("YOLOOP_POLICY_SWITCH_ACTIVE");try{await u.copyFile(this.statePath,`${this.statePath}.policy-backup`)}catch(o){if(o.code!=="ENOENT")throw o}await this.writeState({...s,continuationPolicy:e,continuationSession:n})}async appendRecoveryAttempt(e,n){const r=await this.readState(n),s=r.recovery_history??[];if(s.some(c=>c.attempted_at===e.attempted_at&&c.story_id===e.story_id)){this.logger.warn({event:"recovery_attempted_duplicate",story_id:e.story_id},"duplicate recovery_attempted op; skipping");return}const i=H([...s,e]),a={...r,recovery_history:i};await this.writeState(a),this.logger.info({event:"recovery_attempted_persisted",story_id:e.story_id,history_size:i.length},"recovery attempt persisted")}async resolveRecoveryAttempt(e,n,r){const s=await this.readState(r),o=s.recovery_history??[],i=o.findIndex(h=>h.recovery_step_id_tokenized===e);if(i===-1){this.logger.warn({event:"recovery_resolve_orphan",attempt_id:e},"recovery_resolved op had no matching attempt; skipping");return}const a=o[i];if(a.outcome===n&&a.finished_at){this.logger.info({event:"recovery_resolved_duplicate",attempt_id:e,outcome:n},"duplicate recovery_resolved op; skipping");return}const c=o.slice();c[i]={...a,outcome:n,finished_at:r};const l={...s,recovery_history:c};await this.writeState(l),this.logger.info({event:"recovery_resolved_persisted",attempt_id:e,outcome:n},"recovery attempt resolved")}async acquireLock(e,n){const r={...e,pid:process.pid,hostname:I(),ownerKind:"client",startedAt:e.startedAt||n,leaseId:e.leaseId??ne(e.sessionId,n),leaseState:"active",leaseAcquiredAt:e.leaseAcquiredAt??n,leaseDurationMs:e.leaseDurationMs??q,leaseExpiresAt:e.leaseExpiresAt??e.ttlExpiresAt},s=JSON.stringify(r,null,2);try{const o=await u.open(this.lockPath,"wx");try{await o.writeFile(s,"utf8")}finally{await o.close()}this.trySetFilePerms(this.lockPath),this.logger.info({event:"yoloop_lock_acquired",pid:r.pid,sessionId:r.sessionId},"yoloop lock acquired");return}catch(o){const i=o;if(i.code!=="EEXIST")throw this.logger.error({event:"yoloop_lock_acquire_error",err:i.message},"failed to acquire yoloop lock"),o;const a=await this.readLock();if(a&&this.isSameClientSessionLock(a,r)){this.logger.info({event:"yoloop_lock_acquire_duplicate",sessionId:r.sessionId},"duplicate acquire_lock for current yoloop session; treating as no-op");return}if(!await this.maybeRecoverOrphanLock(n))throw this.logger.warn({event:"yoloop_lock_held"},"yoloop lock held by another live process"),o;const l=await u.open(this.lockPath,"wx");try{await l.writeFile(s,"utf8")}finally{await l.close()}this.trySetFilePerms(this.lockPath),this.logger.info({event:"yoloop_lock_acquired_after_recovery",pid:r.pid},"yoloop lock acquired after orphan recovery")}}async releaseLock(e){const n=await this.readState(new Date().toISOString()),r=await this.readLock();if(n.runControl){if(!e.expectedRunId||!e.expectedSessionId||!e.expectedLeaseId)throw new Error("YOLOOP_RUN_REVISION_CONFLICT");if(e.expectedRunId!==n.runControl.runId)throw new Error("YOLOOP_RUN_REVISION_CONFLICT");if(!r||e.expectedSessionId!==r.sessionId||e.expectedLeaseId!==r.leaseId)throw new Error("YOLOOP_RUN_OPERATION_CONFLICT")}try{await u.unlink(this.lockPath),this.logger.info({event:"yoloop_lock_released"},"yoloop lock released")}catch(s){const o=s;if(o.code==="ENOENT"){this.logger.info({event:"yoloop_lock_release_noop"},"yoloop lock release noop (file absent)");return}this.logger.warn({event:"yoloop_lock_release_error",err:o.message},"unexpected error releasing yoloop lock")}}async readLock(){try{const e=await u.readFile(this.lockPath,"utf8"),n=JSON.parse(e),r=n.currentEpicId??n.epicId??"";return{pid:n.pid??0,hostname:n.hostname??"",...n.ownerKind?{ownerKind:n.ownerKind}:{},...n.ownerPidState?{ownerPidState:n.ownerPidState}:{},...typeof n.leaseId=="string"?{leaseId:n.leaseId}:{},...n.leaseState?{leaseState:n.leaseState}:{},...typeof n.leaseAcquiredAt=="string"?{leaseAcquiredAt:n.leaseAcquiredAt}:{},...typeof n.leaseDurationMs=="number"?{leaseDurationMs:n.leaseDurationMs}:{},...typeof n.leaseExpiresAt=="string"?{leaseExpiresAt:n.leaseExpiresAt}:{},startedAt:n.startedAt??"",sessionId:n.sessionId??"",mode:n.mode??"epic-id",inputPath:n.inputPath??"",epicQueue:n.epicQueue??(r?[r]:[]),currentEpicIndex:n.currentEpicIndex??0,currentEpicId:r,ttlExpiresAt:n.ttlExpiresAt??"",epicId:n.epicId??r}}catch{return null}}async readState(e){try{const n=await u.readFile(this.statePath,"utf8"),r=JSON.parse(n);return re(r,e)}catch(n){const r=n;return r.code!=="ENOENT"&&this.logger.warn({event:"yoloop_state_read_error",err:r.message},"yoloop state file unreadable; using defaults"),S(e)}}async writeState(e){const n=`${this.statePath}.tmp.${process.pid}.${Date.now()}`,r=JSON.stringify(e,null,2);try{const s=await u.open(n,"w",384);try{await s.writeFile(r,"utf8"),await s.sync()}finally{await s.close()}this.trySetFilePerms(n),await u.rename(n,this.statePath),await this.syncStateDirectory()}catch(s){const o=s;this.logger.error({event:"yoloop_state_write_error",err:o.message},"failed to write yoloop state");try{await u.unlink(n)}catch{}throw s}}async rolloverSession(e,n){f(e);const r=await this.readRolloverManifest();if(r){if(G(r.operation,e)){if(r.operation.payloadHash!==e.payloadHash)throw new Error("YOLOOP_SESSION_ROLLOVER_CONFLICT");if(r.phase==="applied")return;await this.completePreparedSessionRollover(r.operation,n);return}else if(r.phase==="prepared")throw new Error("YOLOOP_SESSION_ROLLOVER_CONFLICT")}const s=await this.readState(n),o=await this.readLock();P(e,s,o),await this.writeRolloverManifest({schemaVersion:"YoloopSessionRolloverManifest/1.0",phase:"prepared",operation:e}),await this.completePreparedSessionRollover(e,n)}async completePreparedSessionRollover(e,n){const r=await this.readState(n);let s=d(r)===d(e.next);if(!s){const i=await this.readLock();P(e,r,i),await this.writeState(e.next),s=!0}const o=await this.readLock();if(e.expectedSessionId===null||e.expectedLeaseId===null){if(e.expectedSessionId!==null||e.expectedLeaseId!==null||o)throw new Error("YOLOOP_SESSION_ROLLOVER_LOCK_CONFLICT")}else if(o){if(o.sessionId!==e.expectedSessionId||o.leaseId!==e.expectedLeaseId)throw new Error("YOLOOP_SESSION_ROLLOVER_LOCK_CONFLICT");await u.unlink(this.lockPath),await this.syncStateDirectory()}else if(!s)throw new Error("YOLOOP_SESSION_ROLLOVER_LOCK_CONFLICT");await this.writeRolloverManifest({schemaVersion:"YoloopSessionRolloverManifest/1.0",phase:"applied",operation:e}),this.logger.info({event:"yoloop_session_rollover_applied",runId:e.runId,operationId:e.operationId,coolDownUntil:e.coolDownUntil},"yoloop per-run-cap session rollover applied")}async recoverSessionRolloverIfPresent(e){try{await u.access(this.rolloverManifestPath)}catch(n){if(n.code==="ENOENT")return;throw n}await this.ensureDir(),await this.withMutationLock(async()=>{const n=await this.readRolloverManifest();n?.phase==="prepared"&&await this.completePreparedSessionRollover(n.operation,e)})}async readRolloverManifest(){try{const e=JSON.parse(await u.readFile(this.rolloverManifestPath,"utf8"));if(e.schemaVersion!=="YoloopSessionRolloverManifest/1.0"||e.phase!=="prepared"&&e.phase!=="applied"||!e.operation||e.operation.type!=="rollover_session")throw new Error("YOLOOP_SESSION_ROLLOVER_MANIFEST_CORRUPT");return f(e.operation),e}catch(e){if(e.code==="ENOENT")return null;throw e.message==="YOLOOP_SESSION_ROLLOVER_MANIFEST_CORRUPT"?e:new Error("YOLOOP_SESSION_ROLLOVER_MANIFEST_CORRUPT")}}async writeRolloverManifest(e){const n=`${this.rolloverManifestPath}.tmp.${process.pid}.${Date.now()}`,r=await u.open(n,"w",384);try{await r.writeFile(JSON.stringify(e,null,2),"utf8"),await r.sync()}finally{await r.close()}this.trySetFilePerms(n),await u.rename(n,this.rolloverManifestPath),await this.syncStateDirectory()}async advanceEpic(e,n,r){const s=await this.readState(r);if(!s.currentSession){this.logger.warn({event:"yoloop_advance_no_session",nextEpicId:n},"advance_epic with no active session; skipping");return}const o={...s,currentSession:{...s.currentSession,currentEpicIndex:e}};await this.writeState(o),this.logger.info({event:"yoloop_epic_advance",nextEpicId:n,nextIndex:e},"yoloop advanced to next epic")}async ensureDir(){try{await u.mkdir(this.stateDir,{recursive:!0}),this.trySetDirPerms(this.stateDir)}catch(e){const n=e;throw this.logger.error({event:"yoloop_mkdir_error",err:n.message,path:this.stateDir},"failed to ensure .neocortex/ directory"),e}}async syncStateDirectory(){try{const e=await u.open(this.stateDir,"r");try{await e.sync()}finally{await e.close()}}catch(e){const n=e.code;if(n!=="EINVAL"&&n!=="EISDIR"&&n!=="ENOTSUP"&&n!=="EPERM")throw e}}async withMutationLock(e){let n=null;for(let r=0;r<B;r+=1)try{n=await u.open(this.mutationLockPath,"wx",384),await n.writeFile(JSON.stringify({pid:process.pid,acquiredAt:new Date().toISOString()})),await n.sync();break}catch(s){if(s.code!=="EEXIST")throw s;try{const o=await u.stat(this.mutationLockPath);if(Date.now()-o.mtimeMs>$){await u.unlink(this.mutationLockPath);continue}}catch{continue}await new Promise(o=>setTimeout(o,5))}if(!n)throw new Error("YOLOOP_RUN_REVISION_CONFLICT");try{return await e()}finally{await n.close().catch(()=>{}),await u.unlink(this.mutationLockPath).catch(()=>{})}}async transitionRun(e,n){v(e);const r=await this.readState(n),s=r.runControl,o=s?.receipts.find(l=>l.operationId===e.operationId||l.idempotencyKey===e.idempotencyKey);if(o){if(o.operationId===e.operationId&&o.idempotencyKey===e.idempotencyKey&&o.payloadHash===e.payloadHash)return o;throw new Error("YOLOOP_RUN_OPERATION_CONFLICT")}if(s&&s.runId!==e.runId)throw new Error("YOLOOP_RUN_REVISION_CONFLICT");if((s?.revision??0)!==e.expectedRevision)throw new Error("YOLOOP_RUN_REVISION_CONFLICT");if((s?.latestSnapshotHash??null)!==e.expectedSnapshotHash)throw new Error("YOLOOP_RUN_SNAPSHOT_CONFLICT");E(s,e);const c=e.next.receipts.at(-1);if(!c)throw new Error("YOLOOP_RUN_OPERATION_CONFLICT");return await this.writeState({...r,version:"1.2",runControl:e.next}),this.logger.info({event:"yoloop_run_transition_committed",runId:e.runId,operationId:e.operationId,revision:c.revision,status:c.status},"yoloop run transition committed"),c}async startSuccessorRun(e,n){X(e);const r=await this.readState(n),s=r.runControl,o={schemaVersion:"YoloopRunPredecessor/1.0",runId:e.previousRunId,revision:e.expectedRevision,snapshotHash:e.expectedSnapshotHash,successorOperationId:e.operationId,publicSafe:!0},i=s?.receipts.find(l=>l.operationId===e.operationId||l.idempotencyKey===e.idempotencyKey);if(i){if(i.operationId===e.operationId&&i.idempotencyKey===e.idempotencyKey&&e.next.receipts.at(-1)?.payloadHash===i.payloadHash&&d(s?.predecessor)===d(o))return i;throw new Error("YOLOOP_RUN_OPERATION_CONFLICT")}if(!s||s.runId!==e.previousRunId||s.status!=="exhausted"||s.revision!==e.expectedRevision||s.latestSnapshotHash!==e.expectedSnapshotHash||r.currentSession!==null)throw new Error("YOLOOP_RUN_SUCCESSOR_CONFLICT");const a=e.next.receipts.at(-1);if(!a||d(e.next.predecessor)!==d(o))throw new Error("YOLOOP_RUN_SUCCESSOR_CONFLICT");const c={type:"transition_run",runId:e.runId,operationId:e.operationId,idempotencyKey:e.idempotencyKey,expectedRevision:0,expectedSnapshotHash:null,payloadHash:a.payloadHash,next:e.next};return v(c),E(void 0,c),await this.writeState({...r,version:"1.2",runControl:e.next}),a}trySetFilePerms(e){try{F(e)}catch{}}trySetDirPerms(e){try{K(e)}catch{}}async prepareLockForSnapshot(e,n){if(!e)return null;if(e.ownerKind!=="client")return e;const r=k(e,n),s={...e,leaseState:r};if(r==="expired")return await this.deleteLockBestEffort(),this.logger.warn({event:"yoloop_client_lock_recovered",reason:"lease_expired"},"expired client-owned yoloop lock lease recovered before snapshot echo"),null;if(!s.pid||s.pid<=0)return await this.deleteLockBestEffort(),this.logger.warn({event:"yoloop_client_lock_recovered",reason:"invalid_pid"},"invalid PID in client-owned yoloop lock; recovered"),null;if(s.hostname&&s.hostname!==I())return{...s,ownerPidState:"unknown"};try{return process.kill(s.pid,0),{...s,ownerPidState:"live"}}catch{return await this.deleteLockBestEffort(),this.logger.warn({event:"yoloop_client_lock_recovered",reason:"dead_pid"},"stale client-owned yoloop lock recovered before snapshot echo"),null}}async maybeRecoverOrphanLock(e){const n=await this.readLock();if(!n)return!0;if(k(n,e)==="expired")return await this.deleteLockBestEffort(),this.logger.warn({event:"yoloop_orphan_lock_recovered",reason:"lease_expired"},"expired yoloop lock lease recovered"),!0;if(!n.pid||n.pid<=0)return await this.deleteLockBestEffort(),this.logger.warn({event:"yoloop_orphan_lock_recovered",reason:"invalid_pid"},"invalid PID in lock file; recovered"),!0;if(n.hostname&&n.hostname!==I())return this.logger.warn({event:"yoloop_lock_remote_host",ownerKind:n.ownerKind??"server",ownerPidState:"unknown"},"lock held by a remote host; honoring"),!1;try{return process.kill(n.pid,0),!1}catch{return await this.deleteLockBestEffort(),this.logger.warn({event:"yoloop_orphan_lock_recovered",reason:"dead_pid"},"orphan yoloop lock recovered"),!0}}async deleteLockBestEffort(){try{await u.unlink(this.lockPath)}catch{}}isSameClientSessionLock(e,n){return e.ownerKind==="client"&&e.sessionId===n.sessionId&&e.pid===process.pid&&e.hostname===I()}async cleanupOrphanTempFiles(){try{const e=U(this.statePath),n=await u.readdir(e),r=[`${m}.tmp.`,`${T}.tmp.`],s=n.filter(o=>r.some(i=>o.startsWith(i)));for(const o of s)try{await u.unlink(_(e,o))}catch{}}catch{}}}function d(t){return t===null||typeof t!="object"?JSON.stringify(t):Array.isArray(t)?`[${t.map(d).join(",")}]`:`{${Object.entries(t).filter(([,e])=>e!==void 0).sort(([e],[n])=>e.localeCompare(n)).map(([e,n])=>`${JSON.stringify(e)}:${d(n)}`).join(",")}}`}function p(t,e){return D("sha256").update(`${t}\0${d(e)}`).digest("hex")}function j(t){return p("p9390812898200217364-yoloop-session-v1",t)}function z(t){return p("p9390812898200217364-yoloop-rollover-v1",t)}function W(t){return p("p9390812898200217364-yoloop-successor-run-v1",t)}function G(t,e){return t.operationId===e.operationId&&t.idempotencyKey===e.idempotencyKey}function f(t){const e=/^[A-Za-z0-9._:-]{1,128}$/,n={runId:t.runId,operationId:t.operationId,idempotencyKey:t.idempotencyKey,expectedRevision:t.expectedRevision,expectedSnapshotHash:t.expectedSnapshotHash,expectedSessionId:t.expectedSessionId,expectedSessionFingerprint:t.expectedSessionFingerprint,expectedLeaseId:t.expectedLeaseId,coolDownUntil:t.coolDownUntil,reason:t.reason,exhaustedRun:t.exhaustedRun,next:t.next};if(!e.test(t.runId)||!e.test(t.operationId)||!e.test(t.idempotencyKey)||!/^[a-f0-9]{64}$/.test(t.expectedSessionFingerprint)||!/^[a-f0-9]{64}$/.test(t.payloadHash)||!Number.isSafeInteger(t.expectedRevision)||t.expectedRevision<0||!Number.isFinite(Date.parse(t.coolDownUntil))||!["YOLOOP_PER_RUN_CAP_REACHED","YOLOOP_SESSION_TIMEOUT"].includes(t.reason)||t.payloadHash!==z(n)||t.receipt.schemaVersion!=="YoloopSessionRolloverReceipt/1.0"||t.receipt.runId!==t.runId||t.receipt.operationId!==t.operationId||t.receipt.idempotencyKey!==t.idempotencyKey||t.receipt.payloadHash!==t.payloadHash||t.receipt.coolDownUntil!==t.coolDownUntil||t.receipt.revision!==(t.exhaustedRun?.revision??0)||t.receipt.snapshotHash!==(t.exhaustedRun?.latestSnapshotHash??null)||t.receipt.status!=="exhausted"||t.receipt.publicSafe!==!0)throw new Error("YOLOOP_SESSION_ROLLOVER_CONFLICT");if(t.expectedSessionId===null!=(t.expectedLeaseId===null)||t.expectedSessionId!==null&&!e.test(t.expectedSessionId)||t.expectedLeaseId!==null&&!e.test(t.expectedLeaseId))throw new Error("YOLOOP_SESSION_ROLLOVER_LOCK_CONFLICT")}function X(t){const e=/^[A-Za-z0-9._:-]{1,128}$/,n={runId:t.runId,previousRunId:t.previousRunId,operationId:t.operationId,idempotencyKey:t.idempotencyKey,expectedRevision:t.expectedRevision,expectedSnapshotHash:t.expectedSnapshotHash,next:t.next};if(!e.test(t.runId)||!e.test(t.previousRunId)||t.runId===t.previousRunId||!e.test(t.operationId)||!e.test(t.idempotencyKey)||!/^[a-f0-9]{64}$/.test(t.payloadHash)||!Number.isSafeInteger(t.expectedRevision)||t.expectedRevision<1||t.payloadHash!==W(n))throw new Error("YOLOOP_RUN_SUCCESSOR_CONFLICT")}function P(t,e,n){f(t);const r=e.currentSession;if(!r||j(r)!==t.expectedSessionFingerprint)throw new Error("YOLOOP_SESSION_ROLLOVER_SESSION_CONFLICT");const s=e.runControl;if((s?.revision??0)!==t.expectedRevision||(s?.latestSnapshotHash??null)!==t.expectedSnapshotHash||s&&s.runId!==t.runId)throw new Error("YOLOOP_RUN_REVISION_CONFLICT");if(t.expectedSessionId===null||t.expectedLeaseId===null){if(n)throw new Error("YOLOOP_SESSION_ROLLOVER_LOCK_CONFLICT")}else if(!n||n.sessionId!==t.expectedSessionId||n.leaseId!==t.expectedLeaseId)throw new Error("YOLOOP_SESSION_ROLLOVER_LOCK_CONFLICT");const o=t.exhaustedRun;if(s)if(s.status==="exhausted"){if(d(o)!==d(s))throw new Error("YOLOOP_SESSION_ROLLOVER_STATE_CONFLICT")}else{if(!o||o.status!=="exhausted")throw new Error("YOLOOP_SESSION_ROLLOVER_STATE_CONFLICT");const a=o.receipts.at(-1);if(!a)throw new Error("YOLOOP_SESSION_ROLLOVER_STATE_CONFLICT");const c={type:"transition_run",runId:s.runId,operationId:a.operationId,idempotencyKey:a.idempotencyKey,expectedRevision:s.revision,expectedSnapshotHash:s.latestSnapshotHash,payloadHash:a.payloadHash,next:o};v(c),E(s,c)}else{const a=o?.receipts[0],c=o?.receipts[1];if(o&&(o.runId!==t.runId||o.status!=="exhausted"||o.revision!==2||o.events.length!==2||o.progressSnapshots.length!==4||o.receipts.length!==2||a?.runId!==t.runId||a.revision!==1||a.status!=="created"||c?.runId!==t.runId||c.revision!==2||c.status!=="exhausted"||c.operationId!==`${t.operationId}:run`||c.idempotencyKey!==`${t.idempotencyKey}:run`||o.latestSnapshotHash!==c.snapshotHash||o.predecessor!==void 0))throw new Error("YOLOOP_SESSION_ROLLOVER_STATE_CONFLICT")}const i={...e,version:"1.2",coolDownUntil:t.coolDownUntil,currentSession:null,...o?{runControl:o}:{}};if(d(i)!==d(t.next))throw new Error("YOLOOP_SESSION_ROLLOVER_STATE_CONFLICT")}function x(t){const{receipts:e,...n}=t.next;return p("p220-yoloop-run-transition-payload-v1",{runId:t.runId,operationId:t.operationId,idempotencyKey:t.idempotencyKey,expectedRevision:t.expectedRevision,expectedSnapshotHash:t.expectedSnapshotHash,next:n})}const R=new Set(["success","partial","blocked","failure","exhausted","cancelled"]),Q={created:["running","cancelling","exhausted"],running:["pausing","cancelling","success","partial","blocked","failure","exhausted"],pausing:["paused","cancelling","failure","exhausted"],paused:["resuming","cancelling","exhausted"],resuming:["running","cancelling","failure","exhausted"],cancelling:["cancelled","failure","exhausted"]};function Z(t,e){return e==="pause"?t==="running"?"pausing":null:e==="resume"?t==="paused"?"resuming":null:R.has(t)||t==="cancelling"?null:"cancelling"}function ee(t){const e=t.current.revision+1,n=t.action==="cancel"?["YOLOOP_RUN_CANCEL_REQUESTED"]:[],r={schemaVersion:"YoloopOperationalBudgetSummary/1.0",limits:t.current.operationalBudget.limits,usage:t.current.usage,exhaustedDimension:null},s={schemaVersion:"ProgressSnapshot/1.0",runId:t.current.runId,sequence:t.current.progressSnapshots.length+1,revision:e,operationId:t.operationId,boundary:t.action,phase:"before",status:t.current.status,occurredAt:t.occurredAt,parentSnapshotHash:t.current.latestSnapshotHash,budget:r,reasonCodes:n,publicSafe:!0},o=p("p220-yoloop-progress-snapshot-id-v1",{runId:s.runId,operationId:s.operationId,sequence:s.sequence,phase:s.phase}),i={...s,snapshotId:o,snapshotHash:p("p220-yoloop-progress-snapshot-v1",{...s,snapshotId:o})},a={...s,sequence:i.sequence+1,phase:"after",status:t.target,parentSnapshotHash:i.snapshotHash},c=p("p220-yoloop-progress-snapshot-id-v1",{runId:a.runId,operationId:a.operationId,sequence:a.sequence,phase:a.phase}),l={...a,snapshotId:c,snapshotHash:p("p220-yoloop-progress-snapshot-v1",{...a,snapshotId:c})},h={schemaVersion:"YoloopRunEvent/1.0",runId:t.current.runId,operationId:t.operationId,kind:"intent",sequence:t.current.events.length+1,revision:e,occurredAt:t.occurredAt,fromStatus:t.current.status,toStatus:t.target,reasonCodes:n,budgetDimension:null,parentEventHash:t.current.events.at(-1)?.eventHash??null,publicSafe:!0},y=p("p220-yoloop-run-event-id-v1",{runId:h.runId,operationId:h.operationId,sequence:h.sequence}),O={...h,eventId:y,eventHash:p("p220-yoloop-run-event-v1",{...h,eventId:y})},w={...t.current,revision:e,status:t.target,events:[...t.current.events,O],progressSnapshots:[...t.current.progressSnapshots,i,l],latestSnapshotHash:l.snapshotHash,receipts:[...t.current.receipts]},L={runId:t.current.runId,operationId:t.operationId,idempotencyKey:t.idempotencyKey,expectedRevision:t.current.revision,expectedSnapshotHash:t.current.latestSnapshotHash,next:w},N=x(L),Y={schemaVersion:"YoloopRunTransitionReceipt/1.0",runId:t.current.runId,operationId:t.operationId,idempotencyKey:t.idempotencyKey,payloadHash:N,revision:e,snapshotHash:l.snapshotHash,status:t.target};return{type:"transition_run",...L,payloadHash:N,next:{...w,receipts:[...w.receipts,Y]}}}function v(t){const e=/^[A-Za-z0-9._:-]{1,128}$/;if(!e.test(t.runId)||!e.test(t.operationId)||!e.test(t.idempotencyKey)||!/^[a-f0-9]{64}$/.test(t.payloadHash)||!Number.isSafeInteger(t.expectedRevision)||t.expectedRevision<0)throw new Error("YOLOOP_RUN_OPERATION_CONFLICT");if(t.payloadHash!==x(t))throw new Error("YOLOOP_RUN_OPERATION_CONFLICT")}function E(t,e){const n=e.next,r=t?.events??[],s=t?.progressSnapshots??[],o=t?.receipts??[];if(n.schemaVersion!=="YoloopRunControl/1.0"||n.runId!==e.runId||n.revision!==e.expectedRevision+1||n.events.length!==r.length+1||n.progressSnapshots.length!==s.length+2||n.receipts.length!==o.length+1||d(n.events.slice(0,r.length))!==d(r)||d(n.progressSnapshots.slice(0,s.length))!==d(s)||d(n.receipts.slice(0,o.length))!==d(o))throw new Error("YOLOOP_RUN_TRANSITION_INVALID");if(t){if(R.has(t.status))throw new Error("YOLOOP_RUN_TERMINAL");const h=n.progressSnapshots.at(-2)?.boundary,y=t.status===n.status&&(h==="budget"||h==="retry");if(!(Q[t.status]??[]).includes(n.status)&&!y)throw new Error("YOLOOP_RUN_TRANSITION_INVALID");if(t.startedAt!==n.startedAt||t.deadlineAt!==n.deadlineAt)throw new Error("YOLOOP_RUN_TRANSITION_INVALID");if(d(t.predecessor)!==d(n.predecessor))throw new Error("YOLOOP_RUN_TRANSITION_INVALID")}else if(n.status!=="created")throw new Error("YOLOOP_RUN_TRANSITION_INVALID");const i=n.progressSnapshots.at(-2),a=n.progressSnapshots.at(-1),c=n.events.at(-1),l=n.receipts.at(-1);if(!i||!a||!c||!l||i.phase!=="before"||a.phase!=="after"||i.operationId!==e.operationId||a.operationId!==e.operationId||c.operationId!==e.operationId||i.runId!==e.runId||a.runId!==e.runId||c.runId!==e.runId||i.revision!==n.revision||a.revision!==n.revision||c.revision!==n.revision||i.parentSnapshotHash!==(t?.latestSnapshotHash??null)||a.parentSnapshotHash!==i.snapshotHash||n.latestSnapshotHash!==a.snapshotHash||l.schemaVersion!=="YoloopRunTransitionReceipt/1.0"||l.runId!==e.runId||l.operationId!==e.operationId||l.idempotencyKey!==e.idempotencyKey||l.payloadHash!==e.payloadHash||l.revision!==n.revision||l.snapshotHash!==n.latestSnapshotHash||l.status!==n.status||Date.parse(n.deadlineAt)<=Date.parse(n.startedAt))throw new Error("YOLOOP_RUN_TRANSITION_INVALID");A(i),A(a),te(c,r.at(-1)?.eventHash??null)}function A(t){const{snapshotHash:e,...n}=t;if(e!==p("p220-yoloop-progress-snapshot-v1",n))throw new Error("YOLOOP_RUN_SNAPSHOT_CONFLICT")}function te(t,e){const{eventHash:n,...r}=t;if(t.parentEventHash!==e||n!==p("p220-yoloop-run-event-v1",r))throw new Error("YOLOOP_RUN_SNAPSHOT_CONFLICT")}function ne(t,e){return`lease-${se(`${t}:${e}`)}`}function se(t){let e=2166136261;for(let n=0;n<t.length;n+=1)e^=t.charCodeAt(n),e=Math.imul(e,16777619)>>>0;return e.toString(36).padStart(7,"0")}function k(t,e){const n=t.leaseExpiresAt??t.ttlExpiresAt,r=Date.parse(n),s=Date.parse(e);return!Number.isFinite(r)||!Number.isFinite(s)?"unknown":r<=s?"expired":"active"}function re(t,e){const n=S(e);return{...t,version:t.version==="1.2"?"1.2":"1.1",lastResetAt:t.lastResetAt??n.lastResetAt,storiesRunToday:t.storiesRunToday??0,iterationsToday:t.iterationsToday??0,iterationsTodayDate:t.iterationsTodayDate??n.iterationsTodayDate,tokensUsedToday:t.tokensUsedToday??0,lastRunAt:t.lastRunAt??null,coolDownUntil:t.coolDownUntil??null,totalRunsAllTime:t.totalRunsAllTime??0,totalStoriesAllTime:t.totalStoriesAllTime??0,currentSession:t.currentSession??null,...t.runControl!==void 0?{runControl:t.runControl}:{},...t.continuationPolicy!==void 0?{continuationPolicy:t.continuationPolicy}:{},...t.continuationSession!==void 0?{continuationSession:t.continuationSession}:{},...t.pendingContinuationAuthorities!==void 0?{pendingContinuationAuthorities:t.pendingContinuationAuthorities}:{},...t.continuationReceipts!==void 0?{continuationReceipts:t.continuationReceipts}:{},...t.continuationRecoveryReceipts!==void 0?{continuationRecoveryReceipts:t.continuationRecoveryReceipts}:{},recovery_history:Array.isArray(t.recovery_history)?H(t.recovery_history):[]}}function H(t){return t.length<=g?t:t.slice(t.length-g)}export{C as YOLOOP_PERSISTENCE_CAPABILITIES,he as YoloopClientStateStore,x as buildYoloopRunTransitionPayloadHash,z as buildYoloopSessionRolloverPayloadHash,W as buildYoloopSuccessorRunPayloadHash,H as capRecoveryHistory,S as createDefaultCounters,ue as createDefaultState,j as fingerprintYoloopSession};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: neocortex-root
|
|
3
|
-
description: "🧠 Neocortex Root Agent v4.60.
|
|
3
|
+
description: "🧠 Neocortex Root Agent v4.60.47 | OrNexus Team"
|
|
4
4
|
model: opus
|
|
5
5
|
color: blue
|
|
6
6
|
tools:
|
|
@@ -108,7 +108,7 @@ SEMPRE que este agente for invocado, imprima o banner abaixo como PRIMEIRO outpu
|
|
|
108
108
|
┌────────────────────────────────────────────────────────────┐
|
|
109
109
|
│ │
|
|
110
110
|
│ ####### N E O C O R T E X │
|
|
111
|
-
│ ### ######## v4.60.
|
|
111
|
+
│ ### ######## v4.60.47 │
|
|
112
112
|
│ ######### ##### │
|
|
113
113
|
│ ## ############## Development Orchestrator │
|
|
114
114
|
│ ## ### ###### ## OrNexus Team │
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: neocortex
|
|
3
|
-
description: "🧠 Neocortex v4.60.
|
|
3
|
+
description: "🧠 Neocortex v4.60.47 | OrNexus Team"
|
|
4
4
|
model: opus
|
|
5
5
|
color: blue
|
|
6
6
|
permissionMode: bypassPermissions
|
|
@@ -104,7 +104,7 @@ SEMPRE que este agente for invocado, imprima o banner abaixo como PRIMEIRO outpu
|
|
|
104
104
|
┌────────────────────────────────────────────────────────────┐
|
|
105
105
|
│ │
|
|
106
106
|
│ ####### N E O C O R T E X │
|
|
107
|
-
│ ### ######## v4.60.
|
|
107
|
+
│ ### ######## v4.60.47 │
|
|
108
108
|
│ ######### ##### │
|
|
109
109
|
│ ## ############## Development Orchestrator │
|
|
110
110
|
│ ## ### ###### ## OrNexus Team │
|
|
@@ -28,7 +28,7 @@ Codex built-in commands or actions.
|
|
|
28
28
|
|
|
29
29
|
<!-- END: Plugin Conflict Prevention -->
|
|
30
30
|
|
|
31
|
-
# Neocortex v4.60.
|
|
31
|
+
# Neocortex v4.60.47 | OrNexus Team
|
|
32
32
|
|
|
33
33
|
You are a Development Orchestrator. All orchestration logic is delivered by the remote Neocortex server.
|
|
34
34
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: neocortex
|
|
3
|
-
description: "🧠 Neocortex v4.60.
|
|
3
|
+
description: "🧠 Neocortex v4.60.47 | OrNexus Team"
|
|
4
4
|
model: inherit
|
|
5
5
|
readonly: false
|
|
6
6
|
is_background: false
|
|
@@ -64,7 +64,7 @@ SEMPRE que este agente for invocado, imprima o banner abaixo como PRIMEIRO outpu
|
|
|
64
64
|
┌────────────────────────────────────────────────────────────┐
|
|
65
65
|
│ │
|
|
66
66
|
│ ####### N E O C O R T E X │
|
|
67
|
-
│ ### ######## v4.60.
|
|
67
|
+
│ ### ######## v4.60.47 │
|
|
68
68
|
│ ######### ##### │
|
|
69
69
|
│ ## ############## Development Orchestrator │
|
|
70
70
|
│ ## ### ###### ## OrNexus Team │
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: neocortex-root
|
|
3
|
-
description: "🧠 Neocortex v4.60.
|
|
3
|
+
description: "🧠 Neocortex v4.60.47 | OrNexus Team"
|
|
4
4
|
kind: local
|
|
5
5
|
tools:
|
|
6
6
|
# File operations (Gemini CLI built-ins)
|
|
@@ -62,7 +62,7 @@ SEMPRE que este agente for invocado, imprima o banner abaixo como PRIMEIRO outpu
|
|
|
62
62
|
┌────────────────────────────────────────────────────────────┐
|
|
63
63
|
│ │
|
|
64
64
|
│ ####### N E O C O R T E X │
|
|
65
|
-
│ ### ######## v4.60.
|
|
65
|
+
│ ### ######## v4.60.47 │
|
|
66
66
|
│ ######### ##### │
|
|
67
67
|
│ ## ############## Development Orchestrator │
|
|
68
68
|
│ ## ### ###### ## OrNexus Team │
|
|
@@ -58,7 +58,7 @@ explicit server opt-in rather than a local assumption.
|
|
|
58
58
|
┌────────────────────────────────────────────────────────────┐
|
|
59
59
|
│ │
|
|
60
60
|
│ ####### N E O C O R T E X │
|
|
61
|
-
│ ### ######## v4.60.
|
|
61
|
+
│ ### ######## v4.60.47 │
|
|
62
62
|
│ ######### ##### │
|
|
63
63
|
│ ## ############## Development Orchestrator │
|
|
64
64
|
│ ## ### ###### ## OrNexus Team │
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: "neocortex"
|
|
3
|
-
description: "Neocortex v4.60.
|
|
3
|
+
description: "Neocortex v4.60.47 | OrNexus Team"
|
|
4
4
|
tools:
|
|
5
5
|
# Read / Edit (built-in tool sets)
|
|
6
6
|
- read
|
|
@@ -68,7 +68,7 @@ SEMPRE que este agente for invocado, imprima o banner abaixo como PRIMEIRO outpu
|
|
|
68
68
|
┌────────────────────────────────────────────────────────────┐
|
|
69
69
|
│ │
|
|
70
70
|
│ ####### N E O C O R T E X │
|
|
71
|
-
│ ### ######## v4.60.
|
|
71
|
+
│ ### ######## v4.60.47 │
|
|
72
72
|
│ ######### ##### │
|
|
73
73
|
│ ## ############## Development Orchestrator │
|
|
74
74
|
│ ## ### ###### ## OrNexus Team │
|