@ornexus/neocortex 4.60.63 → 4.60.65
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/release-source.json +1 -1
- package/dist/sbom.cdx.json +31 -38
- package/install.js +1 -0
- package/install.ps1 +34 -3
- package/install.sh +35 -3
- package/package.json +5 -3
- package/packages/client/dist/cli.js +8 -3
- package/packages/client/dist/commands/activate.js +8 -8
- package/packages/client/dist/commands/architecture-memory-terminal.js +4 -2
- package/packages/client/dist/commands/architecture-non-ui-continuation.d.ts +3 -0
- package/packages/client/dist/commands/architecture-non-ui-continuation.js +1 -0
- package/packages/client/dist/commands/invoke.d.ts +19 -16
- package/packages/client/dist/commands/invoke.js +80 -75
- package/packages/client/dist/commands/mutation-qa-run.js +2 -2
- package/packages/client/dist/commands/planning-generation.js +1 -1
- package/packages/client/dist/commands/planning-memory.d.ts +1 -0
- package/packages/client/dist/commands/planning-memory.js +1 -0
- package/packages/client/dist/commands/private-session.d.ts +1 -0
- package/packages/client/dist/commands/private-session.js +1 -0
- package/packages/client/dist/commands/qa-control.d.ts +4 -0
- package/packages/client/dist/commands/qa-control.js +1 -0
- package/packages/client/dist/commands/qa-scan-browser-launch.d.ts +8 -0
- package/packages/client/dist/commands/qa-scan-browser-launch.js +1 -0
- package/packages/client/dist/commands/qa-scan-browser-route.d.ts +3 -0
- package/packages/client/dist/commands/qa-scan-browser-route.js +1 -0
- package/packages/client/dist/commands/qa-scan-capture.d.ts +43 -0
- package/packages/client/dist/commands/qa-scan-capture.js +5 -5
- package/packages/client/dist/commands/qa-scan-discovery.d.ts +7 -0
- package/packages/client/dist/commands/qa-scan-discovery.js +3 -3
- package/packages/client/dist/commands/qa-scan-review.d.ts +8 -1
- package/packages/client/dist/commands/qa-scan-review.js +5 -5
- package/packages/client/dist/commands/qa-synthetic-backend-capture.d.ts +62 -0
- package/packages/client/dist/commands/qa-synthetic-backend-capture.js +1 -0
- package/packages/client/dist/commands/qa-synthetic-backend-review.d.ts +104 -0
- package/packages/client/dist/commands/qa-synthetic-backend-review.js +1 -0
- package/packages/client/dist/commands/qa-synthetic-backend.d.ts +52 -0
- package/packages/client/dist/commands/qa-synthetic-backend.js +7 -0
- package/packages/client/dist/commands/qa-synthetic-broker-port.d.ts +30 -0
- package/packages/client/dist/commands/qa-synthetic-broker-port.js +1 -0
- package/packages/client/dist/commands/qa-synthetic-browser.d.ts +1 -0
- package/packages/client/dist/commands/qa-synthetic-browser.js +1 -0
- package/packages/client/dist/commands/refactor-characterization.d.ts +4 -2
- package/packages/client/dist/commands/refactor-characterization.js +21 -12
- package/packages/client/dist/commands/refactor-control.d.ts +9 -0
- package/packages/client/dist/commands/refactor-control.js +3 -0
- package/packages/client/dist/commands/refactor-cpp-assertions.d.ts +4 -0
- package/packages/client/dist/commands/refactor-cpp-assertions.js +3 -0
- package/packages/client/dist/commands/refactor-review.js +5 -5
- package/packages/client/dist/commands/refactor-root.d.ts +8 -1
- package/packages/client/dist/commands/refactor-root.js +7 -7
- package/packages/client/dist/commands/refresh-memory.d.ts +1 -0
- package/packages/client/dist/commands/refresh-memory.js +3 -3
- package/packages/client/dist/commands/shared-architecture-non-ui.d.ts +18 -0
- package/packages/client/dist/commands/shared-architecture-non-ui.js +1 -0
- package/packages/client/dist/errors/error-messages.js +1 -1
- package/packages/client/dist/git/direct-yolo-checkpoint.d.ts +5 -1
- package/packages/client/dist/git/direct-yolo-checkpoint.js +4 -4
- package/packages/client/dist/git/git-lifecycle-store.d.ts +2 -0
- package/packages/client/dist/git/git-lifecycle-store.js +9 -8
- package/packages/client/dist/license/license-client.d.ts +3 -1
- package/packages/client/dist/license/license-client.js +1 -1
- package/packages/client/dist/memory/project-memory-path-scope.d.ts +4 -0
- package/packages/client/dist/memory/project-memory-path-scope.js +1 -0
- package/packages/client/dist/memory/project-memory-writer.d.ts +4 -1
- package/packages/client/dist/memory/project-memory-writer.js +16 -16
- package/packages/client/dist/private-execution/codex-executor.d.ts +24 -4
- package/packages/client/dist/private-execution/codex-executor.js +4 -2
- package/packages/client/dist/private-execution/codex-host-runtime.d.ts +10 -0
- package/packages/client/dist/private-execution/codex-host-runtime.js +1 -0
- package/packages/client/dist/private-execution/codex-lifecycle-guard.d.ts +4 -0
- package/packages/client/dist/private-execution/codex-lifecycle-guard.js +1 -0
- package/packages/client/dist/private-execution/codex-scoped-permissions.d.ts +8 -0
- package/packages/client/dist/private-execution/codex-scoped-permissions.js +1 -0
- package/packages/client/dist/private-execution/delivery.d.ts +17 -1
- package/packages/client/dist/private-execution/delivery.js +11 -3
- package/packages/client/dist/private-execution/diagnosis-root-review.d.ts +112 -0
- package/packages/client/dist/private-execution/diagnosis-root-review.js +2 -0
- package/packages/client/dist/private-execution/frozen-handoff.d.ts +2 -0
- package/packages/client/dist/private-execution/frozen-handoff.js +6 -0
- package/packages/client/dist/private-execution/implementation-validation.d.ts +15 -0
- package/packages/client/dist/private-execution/implementation-validation.js +2 -0
- package/packages/client/dist/private-execution/isolated-admission.d.ts +11 -7
- package/packages/client/dist/private-execution/isolated-admission.js +17 -10
- package/packages/client/dist/private-execution/isolated-session.d.ts +68 -0
- package/packages/client/dist/private-execution/isolated-session.js +5 -2
- package/packages/client/dist/private-execution/pact-test-source.d.ts +1 -1
- package/packages/client/dist/private-execution/pact-test-source.js +1 -1
- package/packages/client/dist/private-execution/planning-diagnosis-checkpoint.d.ts +2 -0
- package/packages/client/dist/private-execution/planning-diagnosis-checkpoint.js +5 -5
- package/packages/client/dist/private-execution/planning-generation-checkpoint.d.ts +13 -0
- package/packages/client/dist/private-execution/planning-generation-checkpoint.js +4 -3
- package/packages/client/dist/private-execution/planning-memory-checkpoint.d.ts +32 -0
- package/packages/client/dist/private-execution/planning-memory-checkpoint.js +3 -0
- package/packages/client/dist/private-execution/planning-research-checkpoint.js +4 -4
- package/packages/client/dist/private-execution/root-checkpoint.js +1 -1
- package/packages/client/dist/private-execution/root-memory-git-evidence.d.ts +30 -0
- package/packages/client/dist/private-execution/root-memory-git-evidence.js +3 -0
- package/packages/client/dist/private-execution/root-memory-recovery.d.ts +16 -0
- package/packages/client/dist/private-execution/root-memory-recovery.js +1 -0
- package/packages/client/dist/private-execution/root-memory-request.d.ts +28 -0
- package/packages/client/dist/private-execution/root-memory-request.js +1 -0
- package/packages/client/dist/private-execution/root-memory-scope.d.ts +28 -0
- package/packages/client/dist/private-execution/root-memory-scope.js +1 -0
- package/packages/client/dist/private-execution/root-memory-writer.d.ts +22 -0
- package/packages/client/dist/private-execution/root-memory-writer.js +1 -0
- package/packages/client/dist/private-execution/session-lease.d.ts +19 -0
- package/packages/client/dist/private-execution/session-lease.js +1 -0
- package/packages/client/dist/private-execution/shared-private-admission-types.d.ts +34 -0
- package/packages/client/dist/private-execution/shared-private-admission-types.js +1 -0
- package/packages/client/dist/private-execution/shared-project-validation.d.ts +17 -0
- package/packages/client/dist/private-execution/shared-project-validation.js +1 -0
- package/packages/client/dist/private-execution/shared-root-memory-types.d.ts +37 -0
- package/packages/client/dist/private-execution/shared-root-memory-types.js +1 -0
- package/packages/client/dist/runner/binary.d.ts +1 -1
- package/packages/client/dist/runner/binary.js +1 -1
- package/packages/client/dist/runner/headless/opencode-adapter.js +2 -2
- package/packages/client/dist/yolo/change-evidence-collector.d.ts +2 -2
- package/packages/client/dist/yolo/change-evidence-collector.js +1 -1
- package/packages/client/dist/yolo/spec-envelope-collector.js +2 -2
- package/packages/shared/dist/planning/diagnosis-state.js +5 -2
- package/packages/shared/dist/project-memory-targets.js +243 -0
- package/packages/shared/dist/yolo/change-evidence.js +35 -0
- package/packages/shared/dist/yoloop/branch-unit.js +10 -1
- package/packages/shared/dist/yoloop/root-memory-effect.js +57 -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 +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/deepseek-harness/SKILL.md +64 -0
- package/targets-stubs/gemini-cli/agent.md +2 -2
- package/targets-stubs/opencode/neocortex-root.md +1 -1
- package/targets-stubs/vscode/neocortex.agent.md +2 -2
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import{createHash as
|
|
2
|
-
`)))throw new Error("refactor-root-admission-invalid");return
|
|
3
|
-
`);if(
|
|
4
|
-
`)}else if(o==="admit"&&
|
|
5
|
-
`)}else if(o==="verify"&&!
|
|
6
|
-
`)}else throw new Error("refactor-root-arguments-invalid");return 0}catch(
|
|
7
|
-
`),1}}export{
|
|
1
|
+
import{createHash as se}from"node:crypto";import{closeSync as q,constants as j,existsSync as ne,fstatSync as ae,fsyncSync as G,lstatSync as p,mkdirSync as ce,openSync as I,readFileSync as A,readSync as fe,realpathSync as v,writeFileSync as de}from"node:fs";import{dirname as U,isAbsolute as Q,join as b,resolve as L}from"node:path";import{mutationQaGit as E}from"./mutation-qa-git.js";const K=/^P[0-9]{1,12}(?:\.[0-9]{1,12}){1,3}$/,F=/^[a-f0-9]{64}$/,N=8*1024*1024,Y=256;function g(s){return se("sha256").update(s).digest("hex")}function Z(s){const o=E(s,["rev-parse","--git-common-dir"]).toString("utf8").trim(),t=Q(o)?L(o):L(s,o);if(v(t)!==t||p(t).isSymbolicLink()||p(t).uid!==process.getuid?.())throw new Error("refactor-root-store-unverified");const r=b(t,"neocortex-refactor");ce(r,{recursive:!0,mode:448});const i=p(r);if(!i.isDirectory()||i.isSymbolicLink()||i.uid!==process.getuid?.()||(i.mode&63)!==0)throw new Error("refactor-root-store-unverified");return r}function C(s){return!s||s.length>512||Q(s)||s.includes("\\")||/[\u0000-\u001f\u007f:*?\[\]]/.test(s)||s.normalize("NFC")!==s?!1:!s.split("/").some(t=>!t||t==="."||t===".."||[".git",".neocortex","node_modules"].includes(t.toLowerCase()))}function le(s,o){if(!C(o))throw new Error("refactor-root-write-set-invalid");const t=b(s,o),r=p(t);if(v(t)!==t||!r.isFile()||r.isSymbolicLink()||r.size===0||r.size>N)throw new Error("refactor-root-write-set-invalid");const i=A(t);if(i.length===0||i.length>N)throw new Error("refactor-root-write-set-invalid");if(new TextDecoder("utf-8",{fatal:!0}).decode(i),i.includes(0))throw new Error("refactor-root-write-set-invalid");const n=E(s,["show",`HEAD:${o}`]);if(!i.equals(n))throw new Error("refactor-root-source-dirty");return Object.freeze({sha256:g(i),mode:r.mode&511})}function ee(s,o){try{return E(s,["check-ignore","--no-index","-q","--",o]),!0}catch(t){if(t.status===1)return!1;throw t}}function P(s,o){if(!C(o))throw new Error("refactor-root-write-set-invalid");const t=b(s,o),r=U(t),i=p(r);if(!i.isDirectory()||i.isSymbolicLink()||v(r)!==r||E(s,["ls-files","--stage","-z","--",o]).length>0||ee(s,o))throw new Error("refactor-root-write-set-invalid");try{throw p(t),new Error("refactor-root-write-set-invalid")}catch(n){if(n.code!=="ENOENT")throw n}}function _(s){return g(E(s,["ls-files","--stage","-z"]))}function D(s,o){const t=E(s,o);return new TextDecoder("utf-8",{fatal:!0}).decode(t).split("\0").filter(Boolean)}function M(s){if(D(s,["ls-files","-v","-z"]).some(t=>!t.startsWith("H ")))throw new Error("refactor-root-index-unverified")}function W(s){const o=[],t=new Set;let r=0;const i=D(s,["status","--porcelain=v1","-z","--untracked-files=all"]);i.push(...D(s,["ls-files","--others","--ignored","--exclude-standard","-z","--",".neocortex/"]).map(n=>`!! ${n}`));for(const n of i){if(n.length<4||n[2]!==" ")throw new Error("refactor-root-sidecar-unverified");const e=n.slice(3);if(!e.startsWith(".neocortex/"))continue;if(t.has(e)||e.includes("\\")||/[\u0000-\u001f\u007f]/.test(e)||e.split("/").some(l=>!l||l==="."||l===".."))throw new Error("refactor-root-sidecar-unverified");t.add(e);const d=b(s,e),f=p(d);if(v(d)!==d||!f.isFile()||f.isSymbolicLink()||f.nlink!==1||f.size>64*1024*1024)throw new Error("refactor-root-sidecar-unverified");if(r+=f.size,r>128*1024*1024)throw new Error("refactor-root-sidecar-unverified");const w=I(d,j.O_RDONLY|j.O_NOFOLLOW);try{const l=Buffer.alloc(f.size+1);let h=0;for(;h<l.length;){const u=fe(w,l,h,l.length-h,h);if(!u)break;h+=u}const m=ae(w),c=p(d);if(h!==f.size||v(d)!==d||[m,c].some(u=>u.dev!==f.dev||u.ino!==f.ino||u.size!==f.size||u.mtimeMs!==f.mtimeMs||u.ctimeMs!==f.ctimeMs||u.mode!==f.mode||u.nlink!==1))throw new Error("refactor-root-sidecar-unverified");o.push({status:n.slice(0,2),path:e,sha256:g(l.subarray(0,h)),mode:f.mode&511})}finally{q(w)}}return o.sort((n,e)=>Buffer.from(n.path).compare(Buffer.from(e.path))),g(JSON.stringify(o))}function V(s){return[...s].sort((o,t)=>Buffer.from(o).compare(Buffer.from(t)))}function te(s){const o=s.files.map(t=>t.path);return g(JSON.stringify(s.schemaVersion===1?o:{files:o,newFiles:s.newFiles.map(t=>t.path)}))}function re(s,o){if(!F.test(o))throw new Error("refactor-root-admission-invalid");return b(Z(s),`admission-${o}.json`)}function X(s,o){const t=re(s,o),r=p(t);if(!r.isFile()||r.isSymbolicLink()||r.uid!==process.getuid?.()||(r.mode&63)!==0||r.size<100||r.size>512*1024)throw new Error("refactor-root-admission-invalid");const i=A(t);if(i.length>512*1024)throw new Error("refactor-root-admission-invalid");let n;try{n=JSON.parse(new TextDecoder("utf-8",{fatal:!0}).decode(i))}catch{throw new Error("refactor-root-admission-invalid")}if(!n||typeof n!="object"||Array.isArray(n))throw new Error("refactor-root-admission-invalid");const e=n,d=e.schemaVersion===2,f=["schemaVersion","kind","storyId","sourceHead","storySha256","planSha256","indexSha256","sidecarSha256","files","admissionSha256"];if(d&&f.push("newFiles"),Object.keys(e).sort().join("\0")!==f.sort().join("\0")||![1,2].includes(e.schemaVersion)||e.kind!=="private-root-refactor-admission"||typeof e.storyId!="string"||!K.test(e.storyId)||typeof e.sourceHead!="string"||!/^[a-f0-9]{40}(?:[a-f0-9]{24})?$/.test(e.sourceHead)||typeof e.storySha256!="string"||!F.test(e.storySha256)||typeof e.planSha256!="string"||!F.test(e.planSha256)||typeof e.indexSha256!="string"||!F.test(e.indexSha256)||typeof e.sidecarSha256!="string"||!F.test(e.sidecarSha256)||e.admissionSha256!==o||!Array.isArray(e.files)||e.files.length>Y||(d?!Array.isArray(e.newFiles)||e.newFiles.length<1||e.files.length+e.newFiles.length>Y:e.files.length<1))throw new Error("refactor-root-admission-invalid");if(g(`root-refactor-story-scope-v1\0${e.sourceHead}\0${e.storyId}\0${e.storySha256}`)!==e.planSha256)throw new Error("refactor-root-admission-invalid");const w=e.files;if(w.some(c=>!c||typeof c!="object"||Array.isArray(c)||Object.keys(c).sort().join("\0")!==["mode","path","sha256"].join("\0")||typeof c.path!="string"||!C(c.path)||typeof c.sha256!="string"||!F.test(c.sha256)||!Number.isSafeInteger(c.mode)||c.mode<0||c.mode>511))throw new Error("refactor-root-admission-invalid");const l=w.map(c=>c.path);if(new Set(l).size!==l.length||l.join("\0")!==V(l).join("\0"))throw new Error("refactor-root-admission-invalid");if(d){const c=e.newFiles;if(c.some(y=>!y||typeof y!="object"||Array.isArray(y)||Object.keys(y).join("\0")!=="path"||typeof y.path!="string"||!C(y.path)))throw new Error("refactor-root-admission-invalid");const u=c.map(y=>y.path);if(new Set([...l,...u]).size!==l.length+u.length||u.join("\0")!==V(u).join("\0")||[...l,...u].includes(`docs/stories/${e.storyId}.story.md`))throw new Error("refactor-root-admission-invalid")}const{admissionSha256:h,...m}=e;if(g(JSON.stringify(m))!==o||!i.equals(Buffer.from(`${JSON.stringify(e)}
|
|
2
|
+
`)))throw new Error("refactor-root-admission-invalid");return e}function he(s,o,t,r,i,n=[]){if(!i)throw new Error("refactor-root-authorization-required");if(!F.test(t)||r.length+n.length<1||r.length+n.length>Y)throw new Error("refactor-root-write-set-invalid");const e=L(s);try{const d=B(e,o);if(d.planSha256!==t)throw new Error("refactor-root-plan-stale");M(e);const f=_(e),w=W(e),l=V(r),h=V(n);if(new Set([...l,...h]).size!==l.length+h.length||[...l,...h].includes(`docs/stories/${o}.story.md`))throw new Error("refactor-root-write-set-invalid");const m=l.map(S=>Object.freeze({path:S,...le(e,S)})),c=h.map(S=>(P(e,S),Object.freeze({path:S})));if(_(e)!==f||W(e)!==w||B(e,o).planSha256!==t)throw new Error("refactor-root-source-dirty");for(const S of c)P(e,S.path);const u={kind:"private-root-refactor-admission",storyId:o,sourceHead:d.sourceHead,storySha256:d.storySha256,planSha256:t,indexSha256:f,sidecarSha256:w,files:m},y=c.length>0?{schemaVersion:2,...u,newFiles:c}:{schemaVersion:1,...u},k=g(JSON.stringify(y)),R={...y,admissionSha256:k},T=re(e,k),J=Buffer.from(`${JSON.stringify(R)}
|
|
3
|
+
`);if(ne(T))X(e,k);else{const S=I(T,j.O_WRONLY|j.O_CREAT|j.O_EXCL|(j.O_NOFOLLOW??0),384);try{de(S,J),G(S)}finally{q(S)}const a=I(Z(e),j.O_RDONLY|(j.O_DIRECTORY??0));try{G(a)}finally{q(a)}}if(X(e,k),_(e)!==f||W(e)!==w||B(e,o).planSha256!==t)throw new Error("refactor-root-source-dirty");for(const S of c)P(e,S.path);const $={kind:"root-refactor-write-set-admission",storyId:o,sourceHead:d.sourceHead,planSha256:t,writeSetSha256:te(R),admissionSha256:k,fileCount:m.length,rootEditPrepared:!0,privateChildAuthorized:!1,gitCommitAuthorized:!1,publicSafe:!0};return R.schemaVersion===2?Object.freeze({schemaVersion:2,...$,newFileCount:c.length}):Object.freeze({schemaVersion:1,...$})}catch(d){throw d instanceof Error&&d.message.startsWith("refactor-root-")?d:new Error("refactor-root-write-set-invalid")}}function oe(s,o){if(!C(o)||ee(s,o)||E(s,["ls-files","--stage","-z","--",o]).length>0)throw new Error("refactor-root-delta-outside-admission");const t=b(s,o),r=U(t);if(!p(r).isDirectory()||v(r)!==r)throw new Error("refactor-root-delta-outside-admission");const i=p(t);if(v(t)!==t||!i.isFile()||i.isSymbolicLink()||i.size===0||i.size>N||(i.mode&75)!==0)throw new Error("refactor-root-delta-outside-admission");const n=A(t);if(n.length===0||n.length>N||n.includes(0))throw new Error("refactor-root-delta-outside-admission");return new TextDecoder("utf-8",{fatal:!0}).decode(n),g(n)}function ue(s,o){return ie(s,o,!1).receipt}function ge(s,o){return ie(s,o,!0)}function ie(s,o,t){const r=L(s);try{const i=X(r,o),n=E(r,["rev-parse","--verify","HEAD"]).toString("utf8").trim();if(n!==i.sourceHead||_(r)!==i.indexSha256||W(r)!==i.sidecarSha256)throw new Error("refactor-root-baseline-stale");M(r);const e=b(r,"docs","stories",`${i.storyId}.story.md`),d=p(e);if(!d.isFile()||d.isSymbolicLink()||v(e)!==e||g(A(e))!==i.storySha256||g(E(r,["show",`HEAD:docs/stories/${i.storyId}.story.md`]))!==i.storySha256)throw new Error("refactor-root-baseline-stale");const f=D(r,["diff","--name-only","-z","--no-ext-diff","--no-textconv"]).filter(a=>!a.startsWith(".neocortex/")),w=D(r,["ls-files","--others","--exclude-standard","-z"]).filter(a=>!a.startsWith(".neocortex/")),l=new Set(i.files.map(a=>a.path)),h=i.schemaVersion===2?i.newFiles.map(a=>a.path):[],m=[];if(t){for(const a of h)if(a.endsWith(".md"))try{p(b(r,a))}catch(z){if(z.code!=="ENOENT")throw z;P(r,a),m.push(a)}}const c=h.filter(a=>!m.includes(a)),u=new Set(h);if(f.length+w.length===0||w.length!==c.length||f.some(a=>!l.has(a))||w.some(a=>!u.has(a)))throw new Error("refactor-root-delta-outside-admission");let y=0;const k=[];for(const a of i.files){const z=b(r,a.path);if(g(E(r,["show",`HEAD:${a.path}`]))!==a.sha256)throw new Error("refactor-root-admission-invalid");const x=p(z);if(v(z)!==z||!x.isFile()||x.isSymbolicLink()||x.size===0||x.size>N||(x.mode&511)!==a.mode)throw new Error("refactor-root-delta-outside-admission");const O=A(z);if(O.length===0||O.length>N)throw new Error("refactor-root-delta-outside-admission");if(new TextDecoder("utf-8",{fatal:!0}).decode(O),O.includes(0))throw new Error("refactor-root-delta-outside-admission");const H=g(O);k.push(H),H!==a.sha256&&y++}const R=c.map(a=>oe(r,a));y+=R.length;const T=D(r,["diff","--name-only","-z","--no-ext-diff","--no-textconv"]).filter(a=>!a.startsWith(".neocortex/")),J=D(r,["ls-files","--others","--exclude-standard","-z"]).filter(a=>!a.startsWith(".neocortex/"));if(M(r),y===0||y!==f.length+w.length||T.join("\0")!==f.join("\0")||J.join("\0")!==w.join("\0")||i.files.some((a,z)=>{const x=b(r,a.path),O=p(x);if(v(x)!==x||!O.isFile()||O.isSymbolicLink()||O.size>N||(O.mode&511)!==a.mode)return!0;const H=A(x);return H.length>N||g(H)!==k[z]})||c.some((a,z)=>oe(r,a)!==R[z])||_(r)!==i.indexSha256||W(r)!==i.sidecarSha256||E(r,["rev-parse","--verify","HEAD"]).toString("utf8").trim()!==n)throw new Error("refactor-root-baseline-stale");for(const a of m)P(r,a);const $={kind:"root-refactor-delta-containment",storyId:i.storyId,sourceHead:i.sourceHead,planSha256:i.planSha256,admissionSha256:o,writeSetSha256:te(i),changedFileCount:y,rootEditContained:!0,qaAccepted:!1,gitCommitAuthorized:!1,publicSafe:!0},S=i.schemaVersion===2?Object.freeze({schemaVersion:2,...$,newFileCount:c.length}):Object.freeze({schemaVersion:1,...$});return Object.freeze({receipt:S,pendingDocumentationPaths:Object.freeze(m)})}catch(i){throw i instanceof Error&&i.message.startsWith("refactor-root-")?i:new Error("refactor-root-delta-unverified")}}function B(s,o){if(!K.test(o))throw new Error("refactor-root-story-invalid");const t=L(s);try{if(v(t)!==t||!p(t).isDirectory())throw new Error("refactor-root-source-unverified");if(E(t,["rev-parse","--show-toplevel"]).toString("utf8").trim()!==t)throw new Error("refactor-root-source-unverified");if(E(t,["status","--porcelain=v1","-z","--untracked-files=all"]).toString("utf8").split("\0").filter(Boolean).some(c=>!/^.{2} \.neocortex\//.test(c)))throw new Error("refactor-root-source-dirty");const n=E(t,["rev-parse","--verify","HEAD"]).toString("utf8").trim();if(!/^[a-f0-9]{40}(?:[a-f0-9]{24})?$/.test(n))throw new Error("refactor-root-source-unverified");const e=`docs/stories/${o}.story.md`,d=b(t,e),f=p(d);if(v(d)!==d||!f.isFile()||f.isSymbolicLink()||f.size===0||f.size>1024*1024)throw new Error("refactor-root-story-unverified");const w=A(d),l=E(t,["show",`HEAD:${e}`]);if(!w.equals(l))throw new Error("refactor-root-story-unverified");const h=g(w),m=g(`root-refactor-story-scope-v1\0${n}\0${o}\0${h}`);return Object.freeze({schemaVersion:1,kind:"root-refactor-story-scope",storyId:o,sourceHead:n,storySha256:h,planSha256:m,candidateWriteSetRequired:!0,characterizationRequired:!0,executionAuthorized:!1,gitAuthority:"ROOT_ONLY",graphExecution:"NOT_RUN",publicSafe:!0})}catch(r){throw r instanceof Error&&r.message.startsWith("refactor-root-")?r:new Error("refactor-root-source-unverified")}}function Se(s){let o="",t="",r="",i="",n="",e=!1;const d=[],f=[];let w="plain";try{const l=[...s];o=l.shift()??"";for(let h=0;h<l.length;h++){const m=l[h],c=()=>{const u=l[++h];if(!u||u.startsWith("--"))throw new Error("refactor-root-arguments-invalid");return u};if(m==="--project-root")t=c();else if(m==="--story")r=c();else if(m==="--plan-sha")i=c();else if(m==="--admission-sha")n=c();else if(m==="--path")d.push(c());else if(m==="--new-path")f.push(c());else if(m==="--authorize-root-edit")e=!0;else if(m==="--format")w=c();else throw new Error("refactor-root-arguments-invalid")}if(!t||!["plain","json"].includes(w))throw new Error("refactor-root-arguments-invalid");if(o==="plan"&&r&&!i&&!n&&d.length===0&&f.length===0&&!e){const h=B(t,r);process.stdout.write(`${JSON.stringify({ok:!0,plan:h})}
|
|
4
|
+
`)}else if(o==="admit"&&r&&i&&!n&&d.length+f.length>0){const h=he(t,r,i,d,e,f);process.stdout.write(`${JSON.stringify({ok:!0,admission:h})}
|
|
5
|
+
`)}else if(o==="verify"&&!r&&!i&&n&&d.length===0&&f.length===0&&!e){const h=ue(t,n);process.stdout.write(`${JSON.stringify({ok:!0,containment:h})}
|
|
6
|
+
`)}else throw new Error("refactor-root-arguments-invalid");return 0}catch(l){const h=l instanceof Error&&/^refactor-root-[a-z-]+$/.test(l.message)?l.message:"refactor-root-source-unverified";return process.stdout.write(`${JSON.stringify({ok:!1,reasonCode:h})}
|
|
7
|
+
`),1}}export{he as admitRootRefactor,le as exactCommittedRefactorFile,B as planRootRefactor,Z as privateRefactorDirectory,X as readPrivateRefactorAdmission,Se as refactorRootCliHandler,W as refactorSidecarDigest,ue as verifyRootRefactor,ge as verifyRootRefactorForCharacterization};
|
|
@@ -5,6 +5,7 @@ export interface RefreshMemoryCliOptions {
|
|
|
5
5
|
readonly targetIds: readonly ProjectMemoryTargetId[];
|
|
6
6
|
readonly dryRun: boolean;
|
|
7
7
|
readonly verify?: boolean;
|
|
8
|
+
readonly backupDirectory?: string;
|
|
8
9
|
readonly memoryNotes?: readonly string[];
|
|
9
10
|
}
|
|
10
11
|
export interface ProjectMemoryVerification {
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{createHash as m}from"node:crypto";import{lstatSync as w,readFileSync as f}from"node:fs";import{join as
|
|
2
|
-
`).length>l.maxLines)throw new Error("Canonical project memory markers or budget are invalid.");const s=d(r).flatMap(n=>n.files);if(s.some(n=>n.changed||n.mode==="compatibility-materialized-fallback"||n.fallbackReason||n.remediationDebt))throw new Error("Project memory verification found stale or fallback targets.");let e;try{if(e=[...new Set(s.map(n=>n.relativeFile))].sort().map(n=>{const y=f(
|
|
3
|
-
`)).digest("hex"),fileCount:e.length,publicSafe:!0}}async function
|
|
1
|
+
import{createHash as m}from"node:crypto";import{lstatSync as w,readFileSync as f}from"node:fs";import{join as u,resolve as R}from"node:path";import{getProjectMemoryTarget as b,isProjectMemoryTargetId as E,listProjectMemoryTargets as g}from"../memory/shared-project-memory-types.js";import{writeProjectMemoryTargetFiles as v}from"../memory/project-memory-writer.js";function h(r){return(r??"").split(",").map(t=>t.trim()).filter(Boolean)}function M(r){let t=process.cwd(),c=!1,i=!1;const a=[],o=[];for(let s=0;s<r.length;s++){const e=r[s];if(e==="--dry-run"||e==="--preview")c=!0;else if(e==="--verify")i=!0,c=!0;else if(e==="--project-root")t=r[++s]??t;else if(e.startsWith("--project-root="))t=e.slice(15);else if(e==="--target"||e==="--targets")a.push(...h(r[++s]));else if(e.startsWith("--target="))a.push(...h(e.slice(9)));else if(e.startsWith("--targets="))a.push(...h(e.slice(10)));else if(e==="--note"||e==="--memory-note"||e==="--change"){const n=r[++s];n&&o.push(n)}else e.startsWith("--note=")?o.push(e.slice(7)):e.startsWith("--memory-note=")?o.push(e.slice(14)):e.startsWith("--change=")&&o.push(e.slice(9))}if(i&&(a.length>0||o.length>0))throw new Error("Project memory verification requires all targets and no update notes.");const l=a.length>0?a.map(s=>{if(!E(s))throw new Error(`Unknown project-memory target: ${s}`);return s}):["canonical",...g().map(s=>s.targetId)];return{projectRoot:R(t),targetIds:Array.from(new Set(l)),dryRun:c,verify:i,memoryNotes:o}}function d(r){return r.targetIds.map(t=>v({projectRoot:r.projectRoot,targetId:t,dryRun:r.dryRun,memoryNotes:r.memoryNotes??[],backupDirectory:r.backupDirectory}))}function P(r){if(!r.verify||!r.dryRun||r.memoryNotes?.length||r.targetIds.join(",")!==["canonical",...g().map(n=>n.targetId)].join(","))throw new Error("Project memory verification requires the complete read-only target set.");const t=u(r.projectRoot,"NEOCORTEX.md");let c;try{c=w(t)}catch{throw new Error("Canonical project memory is missing or unsafe.")}if(!c.isFile()||c.isSymbolicLink())throw new Error("Canonical project memory must be a regular file.");const i=f(t,"utf8"),a="<!-- NEOCORTEX-MEMORY-START -->",o="<!-- NEOCORTEX-MEMORY-END -->",l=b("canonical").budget;if(i.split(a).length!==2||i.split(o).length!==2||i.indexOf(a)>=i.indexOf(o)||Buffer.byteLength(i,"utf8")>l.maxBytes||i.split(`
|
|
2
|
+
`).length>l.maxLines)throw new Error("Canonical project memory markers or budget are invalid.");const s=d(r).flatMap(n=>n.files);if(s.some(n=>n.changed||n.mode==="compatibility-materialized-fallback"||n.fallbackReason||n.remediationDebt))throw new Error("Project memory verification found stale or fallback targets.");let e;try{if(e=[...new Set(s.map(n=>n.relativeFile))].sort().map(n=>{const y=f(u(r.projectRoot,n)),p=s.find(j=>j.relativeFile===n).mode;return`${n}:${p}:${m("sha256").update(y).digest("hex")}`}),f(t,"utf8")!==i||d(r).some(n=>n.changed))throw new Error("project-memory-verification-race")}catch{throw new Error("Project memory changed during verification.")}return{schemaVersion:"ProjectMemoryVerification/1",canonicalSha256:m("sha256").update(i).digest("hex"),projectionSha256:m("sha256").update(e.join(`
|
|
3
|
+
`)).digest("hex"),fileCount:e.length,publicSafe:!0}}async function k(r){try{const t=M(r);if(t.verify){const a=P(t);return console.log(`Project memory verified: files=${a.fileCount} canonical_sha256=${a.canonicalSha256} projection_sha256=${a.projectionSha256}`),0}const i=d(t).flatMap(a=>a.files.map(o=>[o.changed?t.dryRun?"would-change":"changed":"unchanged",o.mode,o.relativeFile,o.fallbackReason?`warning=${o.fallbackReason}`:void 0,o.remediationDebt?`debt=${o.remediationDebt}`:void 0,o.reasonCodes&&o.reasonCodes.length>0?`reasons=${o.reasonCodes.join(",")}`:void 0].filter(Boolean).join(" ")));console.log(`${t.dryRun?"Project memory preview":"Project memory refreshed"}: ${t.projectRoot}`);for(const a of i)console.log(a);return 0}catch(t){return console.error(t instanceof Error?t.message:String(t)),1}}export{M as parseRefreshMemoryArgs,k as refreshMemoryCliHandler,d as refreshProjectMemoryTargets,P as verifyProjectMemoryTargets};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** Standalone-client projection of the public non-UI architecture receipt syntax. */
|
|
2
|
+
export interface ArchitectureNonUiScopeReceipt {
|
|
3
|
+
readonly schemaVersion: 1;
|
|
4
|
+
readonly kind: 'ArchitectureNonUiScope/1';
|
|
5
|
+
readonly licenseHash: string;
|
|
6
|
+
readonly projectHash: string;
|
|
7
|
+
readonly targetEpicId: string;
|
|
8
|
+
readonly graphRevision: string;
|
|
9
|
+
readonly rootInputSha256: string;
|
|
10
|
+
readonly accountingId: string;
|
|
11
|
+
readonly applicability: 'non-ui';
|
|
12
|
+
readonly excludedStageCommands: readonly string[];
|
|
13
|
+
readonly macSha256: string;
|
|
14
|
+
readonly publicSafe: true;
|
|
15
|
+
}
|
|
16
|
+
export declare const ARCHITECTURE_PUBLIC_COMMANDS: readonly string[];
|
|
17
|
+
export declare const ARCHITECTURE_NON_UI_COMMANDS: readonly string[];
|
|
18
|
+
export declare function parseArchitectureNonUiScopeReceipt(value: unknown): ArchitectureNonUiScopeReceipt | undefined;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const i=Object.freeze(["arch-prd","arch-architecture","arch-fitness-functions","arch-api-contracts","generate-pacts","arch-api-integrations","arch-database","arch-security","arch-design-system","arch-ux-design","arch-performance","arch-testing","arch-infrastructure","arch-review","update-memory"]),n=Object.freeze(i.filter(t=>t!=="arch-design-system"&&t!=="arch-ux-design")),c=Object.freeze(["arch-design-system","arch-ux-design"]);function s(t){if(!t||typeof t!="object"||Array.isArray(t))return;const e=t;if(!(Object.keys(e).sort().join(",")!==["schemaVersion","kind","licenseHash","projectHash","targetEpicId","graphRevision","rootInputSha256","accountingId","applicability","excludedStageCommands","macSha256","publicSafe"].sort().join(",")||e.schemaVersion!==1||e.kind!=="ArchitectureNonUiScope/1"||e.publicSafe!==!0||e.applicability!=="non-ui"||typeof e.targetEpicId!="string"||!/^P[1-9][0-9]{0,11}$/.test(e.targetEpicId)||typeof e.accountingId!="string"||!/^arch-accounting-[a-f0-9]{32}$/.test(e.accountingId)||!["licenseHash","projectHash","graphRevision","rootInputSha256","macSha256"].every(r=>typeof e[r]=="string"&&/^[a-f0-9]{64}$/.test(e[r]))||!Array.isArray(e.excludedStageCommands)||e.excludedStageCommands.length!==c.length||!e.excludedStageCommands.every((r,a)=>r===c[a])))return Object.freeze({...e,excludedStageCommands:c})}export{n as ARCHITECTURE_NON_UI_COMMANDS,i as ARCHITECTURE_PUBLIC_COMMANDS,s as parseArchitectureNonUiScopeReceipt};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const t="support@neocortex.sh",u={AUTH_REFRESH_REQUIRED:{en:{summary:"Authentication must be refreshed.",whatHappened:"
|
|
1
|
+
const t="support@neocortex.sh",u={AUTH_REFRESH_REQUIRED:{en:{summary:"Authentication must be refreshed.",whatHappened:"Credentials are configured, but a valid authentication token is unavailable. The token may have expired or the authentication service may be unreachable. Strict read-only commands do not refresh tokens.",whatToDo:"Check the server connection and retry. If authentication remains unavailable, re-activate outside strict read-only mode.",command:"neocortex activate YOUR-LICENSE-KEY",url:"https://neocortex.sh/portal"},"pt-BR":{summary:"A autentica\xE7\xE3o precisa ser renovada.",whatHappened:"As credenciais est\xE3o configuradas, mas n\xE3o h\xE1 um token de autentica\xE7\xE3o v\xE1lido dispon\xEDvel. O token pode ter expirado ou o servi\xE7o de autentica\xE7\xE3o pode estar inacess\xEDvel. Comandos estritamente somente leitura n\xE3o renovam tokens.",whatToDo:"Verifique a conex\xE3o com o servidor e tente novamente. Se a autentica\xE7\xE3o continuar indispon\xEDvel, reative fora do modo estritamente somente leitura.",command:"neocortex activate SUA-LICENSE-KEY",url:"https://neocortex.sh/portal"}},AUTH_EXPIRED:{en:{summary:"Your session has expired.",whatHappened:"The token we use to authenticate your CLI has expired. This is normal and happens every few hours.",whatToDo:"Re-activate with the license key that was emailed to you.",command:"neocortex activate YOUR-LICENSE-KEY",url:"https://neocortex.sh/portal"},"pt-BR":{summary:"Sua sess\xE3o expirou.",whatHappened:"O token de autentica\xE7\xE3o do CLI expirou. Isso \xE9 normal e acontece a cada poucas horas.",whatToDo:"Reative o CLI com a license key que voc\xEA recebeu por email.",command:"neocortex activate SUA-LICENSE-KEY",url:"https://neocortex.sh/portal"}},UPGRADE_REQUIRED:{en:{summary:"Your CLI version is outdated.",whatHappened:"The server requires a newer CLI version. Older versions are not allowed for security and compatibility reasons.",whatToDo:"Install the latest CLI globally with npm.",command:"npm install -g @ornexus/neocortex@latest"},"pt-BR":{summary:"Sua vers\xE3o do CLI est\xE1 desatualizada.",whatHappened:"O servidor exige uma vers\xE3o mais recente do CLI. Vers\xF5es antigas n\xE3o s\xE3o permitidas por motivos de seguran\xE7a e compatibilidade.",whatToDo:"Instale a vers\xE3o mais recente globalmente via npm.",command:"npm install -g @ornexus/neocortex@latest"}},RATE_LIMITED:{en:{summary:"You sent too many requests in a short window.",whatHappened:"You hit the rate limit for your plan. This protects the service from abuse and keeps it fast for everyone.",whatToDo:"Wait a few seconds and try again. If you hit this often, upgrading your plan raises the limit.",url:"https://neocortex.sh/portal/plans"},"pt-BR":{summary:"Voc\xEA fez muitas requisi\xE7\xF5es em pouco tempo.",whatHappened:"O limite de taxa do seu plano foi atingido. Isso protege o servi\xE7o contra abuso e mant\xE9m a velocidade para todos.",whatToDo:"Espere alguns segundos e tente novamente. Se isso acontece com frequ\xEAncia, fazer upgrade do seu plano aumenta o limite.",url:"https://neocortex.sh/portal/plans"}},TRIGGER_NOT_ALLOWED:{en:{summary:"This command is not available on your current plan.",whatHappened:"You tried to use a trigger that requires a paid plan (Pro or Enterprise).",whatToDo:"See the full comparison and upgrade in the portal.",url:"https://neocortex.sh/portal/plans"},"pt-BR":{summary:"Este comando n\xE3o est\xE1 dispon\xEDvel no seu plano atual.",whatHappened:"Voc\xEA tentou usar um trigger que requer um plano pago (Pro ou Enterprise).",whatToDo:"Veja a compara\xE7\xE3o completa e fa\xE7a upgrade no portal.",url:"https://neocortex.sh/portal/plans"}},QUOTA_EXCEEDED:{en:{summary:"Daily quota reached.",whatHappened:"You have used all invocations allowed by your plan today. Quotas reset at midnight UTC.",whatToDo:"Wait for the daily reset, or upgrade your plan for a higher quota.",url:"https://neocortex.sh/portal/plans"},"pt-BR":{summary:"Quota di\xE1ria atingida.",whatHappened:"Voc\xEA usou todas as invoca\xE7\xF5es permitidas pelo seu plano hoje. As quotas s\xE3o resetadas \xE0 meia-noite UTC.",whatToDo:"Aguarde o reset di\xE1rio ou fa\xE7a upgrade do plano para uma quota maior.",url:"https://neocortex.sh/portal/plans"}},SERVER_ERROR:{en:{summary:"Server error.",whatHappened:"Something went wrong on our side. We have logged the error and will investigate.",whatToDo:`Try again in a minute. If the problem persists, please contact ${t} with the details.`},"pt-BR":{summary:"Erro do servidor.",whatHappened:"Algo deu errado no nosso lado. O erro foi registrado e vamos investigar.",whatToDo:`Tente novamente em um minuto. Se o problema persistir, entre em contato: ${t}.`}},ECONNREFUSED:{en:{summary:"Cannot reach the Neocortex server.",whatHappened:"We could not open a connection to the server. This is usually a network problem on your side.",whatToDo:"Check your internet connection, any VPN or corporate proxy, and try again."},"pt-BR":{summary:"N\xE3o foi poss\xEDvel alcan\xE7ar o servidor Neocortex.",whatHappened:"N\xE3o conseguimos abrir uma conex\xE3o com o servidor. Isso geralmente \xE9 um problema de rede do seu lado.",whatToDo:"Verifique sua conex\xE3o, qualquer VPN ou proxy corporativo, e tente novamente."}},MACHINE_LIMIT_EXCEEDED:{en:{summary:"Machine limit reached.",whatHappened:"Your plan allows a limited number of active machines, and this one would exceed it.",whatToDo:"Deactivate a machine you no longer use from the portal, then re-run activate here.",url:"https://neocortex.sh/portal/machines"},"pt-BR":{summary:"Limite de m\xE1quinas atingido.",whatHappened:"Seu plano permite um n\xFAmero limitado de m\xE1quinas ativas, e esta ultrapassaria o limite.",whatToDo:"Desative uma m\xE1quina que voc\xEA n\xE3o usa mais no portal e rode activate aqui de novo.",url:"https://neocortex.sh/portal/machines"}},NOT_CONFIGURED:{en:{summary:"Neocortex is not configured on this machine.",whatHappened:"No license key was found. You need to run `neocortex activate` once before using the CLI.",whatToDo:"Get a license key from the portal and activate.",command:"neocortex activate YOUR-LICENSE-KEY",url:"https://neocortex.sh/portal"},"pt-BR":{summary:"Neocortex n\xE3o est\xE1 configurado nesta m\xE1quina.",whatHappened:"Nenhuma license key encontrada. Voc\xEA precisa rodar `neocortex activate` uma vez antes de usar o CLI.",whatToDo:"Pegue uma license key no portal e ative.",command:"neocortex activate SUA-LICENSE-KEY",url:"https://neocortex.sh/portal"}}};function r(o=process.env){return(o.LC_ALL??o.LANG??"").toLowerCase().startsWith("pt")?"pt-BR":"en"}function p(o,a=r()){const e=u[o];return e?e[a]??e.en??null:null}function c(o,a=r()){const e=[];e.push(""),e.push(`[Neocortex] ${o.summary}`),e.push("");const n=a==="pt-BR"?"O que aconteceu":"What happened",s=a==="pt-BR"?"O que fazer":"What to do",i=a==="pt-BR"?`Precisa de ajuda? ${t}`:`Need help? ${t}`;return e.push(`${n}: ${o.whatHappened}`),e.push(`${s}: ${o.whatToDo}`),o.command&&(e.push(""),e.push(` ${o.command}`)),o.url&&(e.push(""),e.push(` ${o.url}`)),e.push(""),e.push(i),e.push(""),e.join(`
|
|
2
2
|
`)}function m(o){if(!o||typeof o!="object")return null;const a=o;return typeof a.code=="string"&&(a.code==="ECONNREFUSED"||a.code==="ENOTFOUND"||a.code==="ETIMEDOUT"||a.code==="ECONNRESET")||typeof a.message=="string"&&(/connect/i.test(a.message)&&/refus/i.test(a.message)||/fetch failed/i.test(a.message))?"ECONNREFUSED":null}export{r as detectErrorLocale,c as formatHumanizedError,p as humanizeError,m as inferErrorCodeFromException};
|
|
@@ -73,6 +73,10 @@ export interface DirectYoloCheckpointOptions {
|
|
|
73
73
|
readonly beforeCheckpointPersist?: () => Promise<void>;
|
|
74
74
|
/** Test seam for crash-window reproduction after durable CAS and before release. */
|
|
75
75
|
readonly afterCheckpointPersist?: () => Promise<void>;
|
|
76
|
+
/** Test-only timing seam; production callers use the fixed 30-minute lease. */
|
|
77
|
+
readonly writerLeaseDurationMs?: number;
|
|
78
|
+
/** Test-only timing seam; production callers renew every five minutes. */
|
|
79
|
+
readonly writerLeaseHeartbeatIntervalMs?: number;
|
|
76
80
|
}
|
|
77
81
|
/**
|
|
78
82
|
* Productive P207 setup boundary. It owns only the current checkout and the
|
|
@@ -87,7 +91,7 @@ export declare function acceptDirectYoloSetupCheckpoint(options: Pick<DirectYolo
|
|
|
87
91
|
* one-time token never crosses stdout; only a public receipt is returned.
|
|
88
92
|
*/
|
|
89
93
|
export declare function issueDirectYoloSetupLeaseHandoff(options: Pick<DirectYoloCheckpointOptions, 'projectRoot' | 'storyId' | 'nowIso'>): Promise<DirectYoloCheckpointResult<DirectYoloSetupHandoffReceipt>>;
|
|
90
|
-
export declare function beginDirectYoloStoryCommit(options: Pick<DirectYoloCheckpointOptions, 'projectRoot' | 'storyId' | 'nowIso' | 'setupLeaseHandoff' | 'setupHandoffFault'>): Promise<DirectYoloCheckpointResult<DirectYoloCommitPlan>>;
|
|
94
|
+
export declare function beginDirectYoloStoryCommit(options: Pick<DirectYoloCheckpointOptions, 'projectRoot' | 'storyId' | 'nowIso' | 'setupLeaseHandoff' | 'setupHandoffFault' | 'writerLeaseDurationMs'>): Promise<DirectYoloCheckpointResult<DirectYoloCommitPlan>>;
|
|
91
95
|
export declare function finalizeDirectYoloStoryCheckpoint(options: DirectYoloCheckpointOptions): Promise<DirectYoloCheckpointResult<StoryCommitCheckpoint>>;
|
|
92
96
|
export declare function recoverLegacyDirectYoloStoryCheckpoint(options: DirectYoloCheckpointOptions & {
|
|
93
97
|
readonly commitSha: string;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{execFile as Be}from"node:child_process";import{createHash as _e,randomBytes as le,timingSafeEqual as Le}from"node:crypto";import{readFile as M}from"node:fs/promises";import{join as te,resolve as Z}from"node:path";import{promisify as He}from"node:util";import{acquireGitLifecyclePhysicalIntegrationLock as G,applyGitLifecycleRuntimeOverlay as qe,computeImmutableStoryQaEvidenceDigest as Oe,computeGitLifecyclePhysicalIntegrationLockOwnerDigest as ye,computeP205StoryQaEvidenceDigest as Ce,computeLegacyDirectYoloRecoveryReceiptRef as $e,ensureRuntimeEpic as P,ensureRuntimeStory as ge,ensureGitLifecyclePrivateChildDirectory as ze,executeP205TransientAuthority as Pe,projectP205TransientExecutionEvidence as Ne,publicStoryReviewArtifactFromGit as Q,LEGACY_DIRECT_YOLO_RECOVERY_COMMITS as Ge,mutateGitLifecycleRuntime as $,P205_COMPLETE_COMMAND as Ke,readGitLifecycleRuntime as q,gitLifecycleRuntimeDirectory as Ve,assertGitLifecyclePrivateFile as we,releaseGitLifecyclePhysicalIntegrationLock as K,releaseGitLifecyclePhysicalIntegrationLockForCheckpoint as We,verifyGitLifecyclePhysicalIntegrationLock as U,verifyAcceptedGitLifecycleStoryCheckpoint as me}from"./git-lifecycle-store.js";import{anchoredAtomicWriteFile as Fe}from"./secure-filesystem-boundary.js";import{GIT_LIFECYCLE_COMMIT_PUSH_STEP_ID as Te,GIT_LIFECYCLE_REVIEW_PR_STEP_ID as Ie,GIT_LIFECYCLE_SETUP_BRANCH_STEP_ID as X}from"./git-lifecycle-step-ids.js";const re=He(Be);async function ct(e){try{const t=await ve(e.projectRoot,e.storyId),r=N(e.nowIso),o=Date.parse(r),i=await y(t.projectRoot,["symbolic-ref","--quiet","--short","HEAD"]),n=await y(t.projectRoot,["rev-parse","HEAD"]),p=await q(t.projectRoot,{required:!0}),h=w(p.epics[t.epicId]),d=w(h?.branch_lease),a=d&&Number.isFinite(Date.parse(String(d.expiresAt)))&&Date.parse(String(d.expiresAt))>o;if(a&&d?.ownerStoryId!==e.storyId)return s("direct-yolo-writer-active");let c=ue(h?.origin_binding,t.executionBranch,t.originBranch);if(i===t.executionBranch){if(!c)return s("direct-yolo-origin-binding-invalid")}else{if(i!==t.originBranch)return s("direct-yolo-current-branch-mismatch");if(c&&c.originHeadSha!==n)return s("direct-yolo-origin-binding-conflict");if(c??={schemaVersion:1,originBranch:t.originBranch,originHeadSha:n,executionBranch:t.executionBranch,capturedFromCurrentCheckout:!0,capturedAt:r},(await Ae(t.projectRoot)).some(f=>f.branch===t.executionBranch&&Z(f.path)!==t.projectRoot))return s("direct-yolo-execution-branch-checked-out-elsewhere");const m=await Y(t.projectRoot),j=`refs/heads/${t.executionBranch}`;if(await L(t.projectRoot,["show-ref","--verify","--quiet",j])){const f=await y(t.projectRoot,["rev-parse",j]);if(f!==n){if(!await L(t.projectRoot,["merge-base","--is-ancestor",f,n]))return s("direct-yolo-execution-branch-diverged");await y(t.projectRoot,["update-ref",j,n,f])}await y(t.projectRoot,["switch",t.executionBranch])}else await y(t.projectRoot,["switch","-c",t.executionBranch]);if(await Y(t.projectRoot)!==m)return s("direct-yolo-checkout-payload-raced")}const l=await y(t.projectRoot,["symbolic-ref","--quiet","--short","HEAD"]),u=await y(t.projectRoot,["rev-parse","HEAD"]);if(l!==t.executionBranch)return s("direct-yolo-current-branch-mismatch");if(a&&d?.ownerStoryId===e.storyId)return d.setupHeadSha!==u?s("direct-yolo-setup-lease-head-unbound"):{ok:!0,value:he(t,c,String(d.expiresAt),!0)};const v=r,x=new Date(o+3600*1e3).toISOString(),I=`setup-${le(32).toString("hex")}`,k=await q(t.projectRoot,{required:!0});return await $(t.projectRoot,S=>{const m=P(S,t.epicId),j=w(m.branch_lease);if(j&&Date.parse(String(j.expiresAt))>o&&j.ownerStoryId!==e.storyId)throw new Error("direct-yolo-writer-active");const f=ue(m.origin_binding,t.executionBranch,t.originBranch);if(m.origin_binding&&!f)throw new Error("direct-yolo-origin-binding-conflict");if(f&&JSON.stringify(f)!==JSON.stringify(c))throw new Error("direct-yolo-origin-binding-conflict");m.branch_mode="epic",m.execution_branch=t.executionBranch,m.origin_branch=t.originBranch,m.graph_revision=t.graphRevision,m.origin_binding=c,m.branch_lease={schemaVersion:1,ownerStoryId:e.storyId,sessionId:I,idempotencyKey:I,acquiredAt:v,expiresAt:x,setupHeadSha:u}},{expectedRevision:k.revision,preCommit:async()=>{if(await y(t.projectRoot,["symbolic-ref","--quiet","--short","HEAD"])!==t.executionBranch||await y(t.projectRoot,["rev-parse","HEAD"])!==u)throw new Error("direct-yolo-setup-physical-state-raced")}}),{ok:!0,value:he(t,c,x,!1)}}catch(t){return s(J(t,"direct-yolo-setup-failed"))}}async function dt(e){let t;try{const r=await W(e.projectRoot,e.storyId),o=N(e.nowIso),i=te(r.projectRoot,".neocortex/state.json"),n=await M(i,"utf8"),p=await Y(r.projectRoot),h=await y(r.projectRoot,["rev-parse","HEAD"]),d=`refs/heads/${r.executionBranch}`,a=await q(r.projectRoot,{required:!0}),c=w(a.epics[r.epicId]),l=ue(c?.origin_binding,r.executionBranch,r.originBranch),u=w(c?.branch_lease);if(!l)return s("direct-yolo-origin-binding-invalid");if(!u||!oe(u,e.storyId,o)||u?.sessionId!==u?.idempotencyKey)return s("direct-yolo-setup-lease-invalid");const v=await G(r.projectRoot,{kind:"direct",storyId:e.storyId,sessionId:String(u.sessionId),idempotencyKey:String(u.idempotencyKey),expiresAt:new Date(Date.now()+300*1e3).toISOString(),persistent:!1});if(!v.ok)return s(v.reasonCode);if(t=v,h!==u.setupHeadSha||!await L(r.projectRoot,["merge-base","--is-ancestor",l.originHeadSha,h])||await y(r.projectRoot,["rev-parse",d])!==h)return s("direct-yolo-setup-head-mismatch");if((await Ae(r.projectRoot)).some(f=>f.branch===r.executionBranch&&Z(f.path)!==r.projectRoot))return s("direct-yolo-execution-branch-checked-out-elsewhere");const I=w(JSON.parse(n)),k=w(w(I?.stories)?.[e.storyId]),S=w(a.stories[e.storyId]);if(!k||!["backlog","ready_to_start"].includes(String(k.status))||k.steps_completed!==void 0&&(!Array.isArray(k.steps_completed)||k.steps_completed.length>0)||k.branch_name||k.checkpoint)return s("direct-yolo-setup-story-progress-conflict");const m=S?.status==="branch-ready"&&S.last_step===X&&Array.isArray(S.steps_completed)&&S.steps_completed.length===1&&S.steps_completed[0]===X&&Object.keys(S).sort().join(",")==="last_step,status,steps_completed";if(S&&Object.keys(S).length>0&&!m)return s("direct-yolo-setup-story-progress-conflict");const j=async()=>{if(Date.parse(String(u.expiresAt))<=(e.nowIso?Date.parse(o):Date.now())||!t||!await U(t.path,t.owner)||await M(i,"utf8")!==n||await Y(r.projectRoot)!==p||await y(r.projectRoot,["symbolic-ref","--quiet","--short","HEAD"])!==r.executionBranch||await y(r.projectRoot,["rev-parse","HEAD"])!==h||!await L(r.projectRoot,["merge-base","--is-ancestor",l.originHeadSha,h])||await y(r.projectRoot,["rev-parse",d])!==h)throw new Error("direct-yolo-setup-physical-state-raced")};return m?await j():await $(r.projectRoot,f=>{const b=w(f.epics[r.epicId]),g=ge(f,e.storyId);if(JSON.stringify(b?.branch_lease)!==JSON.stringify(u)||JSON.stringify(b?.origin_binding)!==JSON.stringify(l)||b?.graph_revision!==r.graphRevision||Object.keys(g).length>0)throw new Error("direct-yolo-setup-runtime-raced");g.status="branch-ready",g.last_step=X,g.steps_completed=[X]},{expectedRevision:a.revision,preCommit:j}),{ok:!0,value:Object.freeze({...he(r,l,String(u.expiresAt),m),checkpointAccepted:!0,graphRevision:r.graphRevision,headSha:h})}}catch(r){return s(J(r,"direct-yolo-setup-acceptance-failed"))}finally{t&&await K(t.path,t.owner).catch(()=>{})}}async function ut(e){try{const t=await W(e.projectRoot,e.storyId),r=O(await A(t.projectRoot,["diff","--cached","--name-only","-z"])),o=F(r,t.authorizedWriteSet,e.storyId);if(!o.ok)return s(o.reasonCode);if(Q(t.projectRoot,e.storyId,":")?.verdict!=="approved")return s("direct-yolo-review-artifact-not-approved");if(O(await A(t.projectRoot,["diff","--name-only","-z"])).some(R=>r.includes(R)))return s("direct-yolo-user-overlap");const p=await A(t.projectRoot,["diff","--cached","--binary","--full-index"]);if(!p)return s("direct-yolo-staged-diff-empty");const h=D(p),d=D([...t.authorizedWriteSet].sort().join("\0")),a=N(e.nowIso),c=await q(t.projectRoot,{required:!0}),l=w(c.epics[t.epicId]?.branch_lease);if(!oe(l,e.storyId,a))return s("direct-yolo-setup-handoff-owner-invalid");const u=String(l.sessionId),v=String(l.expiresAt),x=new Date(Math.min(Date.parse(v),Date.parse(a)+300*1e3)).toISOString(),I=await V(t.projectRoot,e.storyId),k=I?.state==="issued"&&I.fromSessionId===u&&I.bundleDigest===h&&I.claimRevision===d&&Date.parse(I.expiresAt)>Date.parse(a),S=k?I.expiresAt:x,m=k?I.token:le(32).toString("base64url"),j=D(m),f=Object.freeze({schemaVersion:1,kind:"direct-yolo-setup-handoff",storyId:e.storyId,fromSessionId:u,tokenDigest:j,bundleDigest:h,claimRevision:d,expiresAt:S}),b=D(JSON.stringify(f)),g=await G(t.projectRoot,{kind:"direct",storyId:e.storyId,sessionId:u,idempotencyKey:u,expiresAt:S,persistent:!1,createdAt:a});if(!g.ok)return s(g.reasonCode==="git-lifecycle-integration-backpressure"?"direct-yolo-integration-backpressure":"direct-yolo-integration-lock-failed");try{await ie(t.projectRoot,{schemaVersion:1,kind:"direct-yolo-setup-handoff-token",state:"issued",storyId:e.storyId,fromSessionId:u,token:m,tokenDigest:j,bundleDigest:h,claimRevision:d,grantDigest:b,expiresAt:S}),await $(t.projectRoot,R=>{const E=w(P(R,t.epicId).branch_lease);if(!oe(E,e.storyId,a)||E?.sessionId!==u||E.idempotencyKey!==u)throw new Error("direct-yolo-setup-handoff-owner-raced");E.handoffGrant=f},{expectedRevision:c.revision,preCommit:async()=>{if(!await U(g.path,g.owner))throw new Error("direct-yolo-integration-lock-raced");const R=await V(t.projectRoot,e.storyId);if(!R||R.state!=="issued"||R.grantDigest!==b||R.tokenDigest!==j)throw new Error("direct-yolo-setup-handoff-token-raced")}})}finally{await K(g.path,g.owner).catch(()=>{})}return{ok:!0,value:Object.freeze({schemaVersion:1,kind:"direct-yolo-setup-handoff-receipt",storyId:e.storyId,sessionId:u,bundleDigest:h,claimRevision:d,grantDigest:b,expiresAt:S,reused:k,publicSafe:!0})}}catch(t){return s(t instanceof Error&&/^direct-yolo-/.test(t.message)?t.message:"direct-yolo-setup-handoff-failed")}}async function ht(e){try{const t=await W(e.projectRoot,e.storyId),r=await y(t.projectRoot,["rev-parse","HEAD"]),o=O(await A(t.projectRoot,["diff","--cached","--name-only","-z"])),i=F(o,t.authorizedWriteSet,e.storyId);if(!i.ok)return s(i.reasonCode);const n=Q(t.projectRoot,e.storyId,":");if(n?.verdict!=="approved")return s("direct-yolo-review-artifact-not-approved");if(O(await A(t.projectRoot,["diff","--name-only","-z"])).some(f=>o.includes(f)))return s("direct-yolo-user-overlap");const h=await A(t.projectRoot,["diff","--cached","--binary","--full-index"]);if(!h)return s("direct-yolo-staged-diff-empty");const d=D(h),a=D([...t.authorizedWriteSet].sort().join("\0")),c=D(["direct-yolo-commit-v1",e.storyId,t.epicId,t.executionBranch,r,d,t.graphRevision,a].join("\0")),l=N(e.nowIso);let u=e.setupLeaseHandoff??await Ye(t.projectRoot,e.storyId,d,a,l);const v=await q(t.projectRoot,{required:!0}),x=w(v.epics[t.epicId]?.branch_lease),I=x?.ownerStoryId===e.storyId&&x.sessionId===c&&x.idempotencyKey===c&&typeof x.expiresAt=="string"&&Date.parse(x.expiresAt)>Date.parse(l)?x:void 0;if(I&&e.setupLeaseHandoff)return s("direct-yolo-setup-handoff-replayed");const k=w(I?.handoffConsumption);if(k){const f=await V(t.projectRoot,e.storyId);if(!f||!["consuming","consumed"].includes(f.state)||f.fromSessionId!==k.fromSessionId||f.tokenDigest!==k.tokenDigest||f.bundleDigest!==d||f.claimRevision!==a||k.bundleDigest!==d||k.claimRevision!==a||f.consumedBySessionId!==c||k.consumedBySessionId!==c)return s("direct-yolo-setup-handoff-consume-invalid");if(f.state==="consuming"){if(!f.token||D(f.token)!==f.tokenDigest)return s("direct-yolo-setup-handoff-consume-invalid");u={sessionId:f.fromSessionId,token:f.token}}}const S=I?String(I.expiresAt):new Date(Date.parse(l)+1800*1e3).toISOString(),m=await G(t.projectRoot,{kind:"direct",storyId:e.storyId,sessionId:c,idempotencyKey:c,expiresAt:S,persistent:!0,createdAt:I&&typeof I.acquiredAt=="string"?I.acquiredAt:l});if(!m.ok)return s(m.reasonCode==="git-lifecycle-integration-backpressure"?"direct-yolo-integration-backpressure":"direct-yolo-integration-lock-failed");try{u&&e.setupLeaseHandoff===void 0&&(await Je(t.projectRoot,e.storyId,u.sessionId,u.token,c,l),await e.setupHandoffFault?.("after-consuming-persisted")),await $(t.projectRoot,f=>{const b=P(f,t.epicId),g=w(b.branch_lease),R=g&&Date.parse(String(g.expiresAt))>Date.parse(l),E=g?.ownerStoryId===e.storyId&&g.sessionId===c&&g.idempotencyKey===c,C=g?.ownerStoryId===e.storyId&&g.sessionId===g.idempotencyKey&&typeof g.idempotencyKey=="string"&&/^setup-[a-f0-9]{64}$/.test(g.idempotencyKey),B=R&&C&&Ze({current:g,handoff:u,storyId:e.storyId,bundleDigest:d,claimRevision:a,nowIso:l});if(u&&R&&!E&&!B)throw new Error("direct-yolo-setup-handoff-invalid");if(R&&!E&&!B)throw new Error("direct-yolo-writer-active");const _=B?w(g?.handoffGrant):void 0,H=_?{schemaVersion:1,kind:"direct-yolo-setup-handoff-consumption",state:"consumed",storyId:e.storyId,fromSessionId:String(g?.sessionId),tokenDigest:String(_.tokenDigest),bundleDigest:d,claimRevision:a,consumedBySessionId:c,consumedAt:l}:void 0;b.branch_mode="epic",b.execution_branch=t.executionBranch,b.origin_branch=t.originBranch,b.graph_revision=t.graphRevision,b.branch_lease=R&&E?g:{schemaVersion:1,ownerStoryId:e.storyId,sessionId:c,idempotencyKey:c,acquiredAt:l,expiresAt:S,...H?{handoffConsumption:H}:{}}},{expectedRevision:v.revision,preCommit:async()=>{if(!await U(m.path,m.owner))throw new Error("direct-yolo-integration-lock-raced")}})}catch(f){throw await K(m.path,m.owner).catch(()=>{}),f}u&&e.setupLeaseHandoff===void 0&&(await e.setupHandoffFault?.("before-consumed-persist"),await Me(t.projectRoot,t.epicId,e.storyId,u.sessionId,u.token,d,a,c,l));const j=Object.freeze([`Neocortex-Story: ${e.storyId}`,`Neocortex-Epic: ${t.epicId}`,`Neocortex-Execution-Branch: ${t.executionBranch}`,`Neocortex-Prepared-Base: ${r}`,`Neocortex-Bundle-Digest: ${d}`,`Neocortex-Review-Artifact-Digest: ${n.digest}`,`Neocortex-Graph-Revision: ${t.graphRevision}`,`Neocortex-Claim-Revision: ${a}`]);return{ok:!0,value:Object.freeze({schemaVersion:1,storyId:e.storyId,epicId:t.epicId,executionBranch:t.executionBranch,baseSha:r,bundleDigest:d,reviewArtifactDigest:n.digest,graphRevision:t.graphRevision,claimRevision:a,idempotencyKey:c,changedPaths:Object.freeze(o),trailers:j})}}catch(t){return s(J(t,"direct-yolo-begin-failed"))}}async function ft(e){let t,r,o;try{const i=await W(e.projectRoot,e.storyId);t=i;const n=await y(i.projectRoot,["rev-parse","HEAD"]);let p=await q(i.projectRoot,{required:!0});const h=w(p.stories[e.storyId]?.checkpoint);if(h){const B=typeof h.headSha=="string"?h.headSha:"",_=typeof h.graphRevision=="string"?h.graphRevision:"",H=/^[a-f0-9]{40,64}$/.test(B)?O(await A(i.projectRoot,["diff-tree","--no-commit-id","--name-only","-r","-z",B])):[],z=F(H,i.authorizedWriteSet,e.storyId);if(!(/^[a-f0-9]{40,64}$/.test(B)&&await L(i.projectRoot,["merge-base","--is-ancestor",B,n]))||!/^[a-f0-9]{64}$/.test(_)||!z.ok)return s("direct-yolo-replay-invalid");const Ee=await se(e,i.projectRoot,n,_);if(!await me(i.projectRoot,h,e.storyId,i.epicId,i.executionBranch,Ee.transientAuthority,i.authorizedWriteSet))return s("direct-yolo-replay-invalid");if(!await ce(i.projectRoot,i.executionBranch,n,H))return s("direct-yolo-replay-head-raced");if(e.push&&!await ke(i.projectRoot,e.remote??"origin",i.executionBranch,B))return s("direct-yolo-remote-head-mismatch");const fe=Array.isArray(h.receiptRefs)?h.receiptRefs.find(pe=>typeof pe=="string"&&/^physical-lock-owner:[a-f0-9]{64}$/.test(pe)):void 0;return fe&&typeof h.idempotencyKey=="string"&&await We(i.projectRoot,{storyId:e.storyId,idempotencyKey:h.idempotencyKey,ownerDigest:fe.slice(20)}),{ok:!0,value:h}}const d=n,a=await y(i.projectRoot,["rev-parse",`${d}^`]),c=await A(i.projectRoot,["show","--no-patch","--format=%B",d]),l=O(await A(i.projectRoot,["diff-tree","--no-commit-id","--name-only","-r","-z",d])),u=F(l,i.authorizedWriteSet,e.storyId);if(!u.ok)return s(u.reasonCode);const v=T(c,"Neocortex-Bundle-Digest"),x=T(c,"Neocortex-Graph-Revision"),I=T(c,"Neocortex-Claim-Revision"),k=new Map([["Neocortex-Story",e.storyId],["Neocortex-Epic",i.epicId],["Neocortex-Execution-Branch",i.executionBranch],["Neocortex-Prepared-Base",a],["Neocortex-Graph-Revision",i.graphRevision],["Neocortex-Claim-Revision",D([...i.authorizedWriteSet].sort().join("\0"))]]);if(!v||!/^[a-f0-9]{64}$/.test(v)||!x||!I||[...k].some(([B,_])=>T(c,B)!==_))return s("direct-yolo-trailers-invalid");const S=Q(i.projectRoot,e.storyId,d);if(S?.verdict!=="approved")return s("direct-yolo-review-artifact-not-approved");const m=T(c,"Neocortex-Review-Artifact-Digest");if(m!==void 0&&m!==S.digest)return s("direct-yolo-review-artifact-digest-mismatch");const j=D(await A(i.projectRoot,["diff","--binary","--full-index",`${a}..${d}`]));if(v!==j)return s("direct-yolo-bundle-digest-mismatch");const f=D(["direct-yolo-commit-v1",e.storyId,i.epicId,i.executionBranch,a,v,x,I].join("\0")),b=w(p.epics[i.epicId]?.branch_lease),g=N(e.nowIso),R=b?.ownerStoryId===e.storyId&&b.idempotencyKey===f&&b.sessionId===f&&Date.parse(String(b.expiresAt))>Date.now()?b:void 0;if(b&&Date.parse(String(b.expiresAt))>Date.now()&&!R)return s("direct-yolo-writer-active");const E=R??{schemaVersion:1,ownerStoryId:e.storyId,sessionId:f,idempotencyKey:f,acquiredAt:g,expiresAt:new Date(Date.parse(g)+1800*1e3).toISOString()},C=await G(i.projectRoot,{kind:"direct",storyId:e.storyId,sessionId:f,idempotencyKey:f,expiresAt:String(E.expiresAt),persistent:!0,createdAt:String(E.acquiredAt)});if(!C.ok)return s(C.reasonCode==="git-lifecycle-integration-backpressure"?"direct-yolo-integration-backpressure":"direct-yolo-integration-lock-failed");o=C,R||(p=(await $(i.projectRoot,_=>{const H=P(_,i.epicId),z=w(H.branch_lease);if(z&&Date.parse(String(z.expiresAt))>Date.parse(g))throw new Error("direct-yolo-writer-active");if(H.graph_revision!==i.graphRevision)throw new Error("direct-yolo-graph-revision-raced");H.branch_lease=E},{expectedRevision:p.revision})).document),r=E;{const B=await se(e,i.projectRoot,d,i.graphRevision);if(!await ce(i.projectRoot,i.executionBranch,d,l))return s("direct-yolo-head-raced");if(e.push){const z=ee(e.remote??"origin");if(await y(i.projectRoot,["push",z,i.executionBranch]),!await be(i.projectRoot,z,i.executionBranch,d))return s("direct-yolo-remote-head-mismatch")}const _=await Re({projectRoot:i.projectRoot,storyId:e.storyId,epicId:i.epicId,executionBranch:i.executionBranch,baseSha:a,headSha:d,bundleDigest:v,graphRevision:x,claimRevision:I,idempotencyKey:f,qaExecution:B,physicalLockOwnerDigest:ye(C.owner),nowIso:N(e.nowIso),legacyReceiptRef:void 0});return await e.beforeCheckpointPersist?.(),await Se({projectRoot:i.projectRoot,checkpoint:_,remote:e.push?e.remote??"origin":void 0,expectedRevision:p.revision,expectedLease:E,expectedGraphRevision:i.graphRevision,physicalLockPath:C.path,physicalLockOwner:C.owner,transientAuthority:B.transientAuthority,authorizedWriteSet:i.authorizedWriteSet})?(await e.afterCheckpointPersist?.(),{ok:!0,value:_}):s("direct-yolo-checkpoint-persist-failed")}}catch(i){return s(J(i,"direct-yolo-finalize-failed"))}finally{o&&await K(o.path,o.owner).catch(()=>{}),t&&r?await ae(t.projectRoot,t.epicId,r).catch(()=>{}):t&&await Ue(t,e.storyId).catch(()=>{})}}async function pt(e){try{const t=await W(e.projectRoot,e.storyId);if(!/^[a-f0-9]{40,64}$/.test(e.commitSha))return s("direct-yolo-recovery-commit-invalid");const r=await y(t.projectRoot,["rev-parse",e.commitSha]);if(Ge[e.storyId]!==r)return s("direct-yolo-recovery-not-allowlisted");if(await y(t.projectRoot,["rev-parse","HEAD"])!==r)return s("direct-yolo-recovery-head-mismatch");await y(t.projectRoot,["merge-base","--is-ancestor",r,`refs/heads/${t.executionBranch}`]);const o=await y(t.projectRoot,["rev-parse",`${r}^`]),i=await A(t.projectRoot,["diff","--binary","--full-index",`${o}..${r}`]),n=O(await A(t.projectRoot,["diff-tree","--no-commit-id","--name-only","-r","-z",r]));if(!F(n,t.authorizedWriteSet.length>0?t.authorizedWriteSet:n,e.storyId).ok)return s("direct-yolo-recovery-write-set-invalid");const h=D(i),d=D([...n].sort().join("\0")),a=D(["legacy-direct-yolo-recovery-v1",e.storyId,r].join("\0")),c=N(e.nowIso),l=new Date(Date.parse(c)+1800*1e3).toISOString(),u=await q(t.projectRoot,{required:!0}),v=await G(t.projectRoot,{kind:"direct",storyId:e.storyId,sessionId:a,idempotencyKey:a,expiresAt:l,persistent:!0,createdAt:c});if(!v.ok)return s(v.reasonCode==="git-lifecycle-integration-backpressure"?"direct-yolo-recovery-integration-backpressure":"direct-yolo-recovery-integration-lock-failed");const x={schemaVersion:1,ownerStoryId:e.storyId,sessionId:a,idempotencyKey:a,acquiredAt:c,expiresAt:l};let I=!1;try{const k=await $(t.projectRoot,g=>{const R=P(g,t.epicId),E=w(R.branch_lease);if(E&&Date.parse(String(E.expiresAt))>Date.parse(c)&&!ne(E,x))throw new Error("direct-yolo-recovery-writer-active");if(R.graph_revision!==t.graphRevision)throw new Error("direct-yolo-recovery-graph-raced");R.branch_mode="epic",R.execution_branch=t.executionBranch,R.origin_branch=t.originBranch,R.branch_lease=x},{expectedRevision:u.revision});I=!0;const S=await se(e,t.projectRoot,r,t.graphRevision);if(!await ce(t.projectRoot,t.executionBranch,r,n))return s("direct-yolo-recovery-head-raced");if(e.push){const g=ee(e.remote??"origin"),R=(await y(t.projectRoot,["ls-remote","--heads",g,`refs/heads/${t.executionBranch}`])).split(/\s+/)[0];if(!R||!await L(t.projectRoot,["merge-base","--is-ancestor",r,R]))return s("direct-yolo-recovery-remote-proof-missing")}const m=await Re({projectRoot:t.projectRoot,storyId:e.storyId,epicId:t.epicId,executionBranch:t.executionBranch,baseSha:o,headSha:r,bundleDigest:h,graphRevision:t.graphRevision,claimRevision:d,idempotencyKey:a,qaExecution:S,physicalLockOwnerDigest:ye(v.owner),nowIso:c,legacyReceiptRef:void 0}),j=await $e(t.projectRoot,{storyId:e.storyId,epicId:t.epicId,executionBranch:t.executionBranch,baseSha:o,headSha:r,bundleDigest:h,graphRevision:t.graphRevision});if(!j)return s("direct-yolo-recovery-evidence-invalid");const f=Object.freeze({...m,receiptRefs:Object.freeze([...m.receiptRefs,j])});return await Se({projectRoot:t.projectRoot,checkpoint:f,remote:e.push?e.remote??"origin":void 0,remotePolicy:"ancestor-recovery",expectedRevision:k.document.revision,expectedLease:x,expectedGraphRevision:t.graphRevision,physicalLockPath:v.path,physicalLockOwner:v.owner,transientAuthority:S.transientAuthority,authorizedWriteSet:t.authorizedWriteSet})?{ok:!0,value:f}:s("direct-yolo-recovery-persist-failed")}finally{await K(v.path,v.owner).catch(()=>{}),I&&await ae(t.projectRoot,t.epicId,x).catch(()=>{})}}catch(t){return s(J(t,"direct-yolo-recovery-failed"))}}async function ve(e,t){if(!/^[A-Za-z][A-Za-z0-9_-]*\.[A-Za-z0-9._-]+$/.test(t))throw new Error("direct-yolo-story-id-invalid");const r=Z(e),o=w(JSON.parse(await M(te(r,".neocortex/state.json"),"utf8"))),i=await q(r,{required:!0}),n=qe(o,i),p=w(n.stories),h=w(n.epics),d=w(p?.[t]),a=String(d?.epic_id??t.split(".")[0]),c=w(h?.[a]),l=String(c?.execution_branch??""),u=String(c?.origin_branch??""),v=String(c?.graph_revision??""),x=Array.isArray(d?.files_to_modify)?[...new Set(d.files_to_modify.filter(I=>typeof I=="string"&&de(I)))].sort():[];if(!d)throw new Error("direct-yolo-story-state-missing");if(c?.branch_mode!=="epic")throw new Error("direct-yolo-branch-mode-invalid");if(!je(l)||!await L(r,["check-ref-format","--branch",l]))throw new Error("direct-yolo-execution-branch-invalid");if(!je(u)||!await L(r,["check-ref-format","--branch",u]))throw new Error("direct-yolo-origin-branch-invalid");if(!/^[a-f0-9]{64}$/.test(v))throw new Error("direct-yolo-graph-revision-invalid");return{projectRoot:r,storyId:t,story:d,epicId:a,executionBranch:l,originBranch:u,graphRevision:v,authorizedWriteSet:x}}async function W(e,t){const r=await ve(e,t);if(await y(r.projectRoot,["symbolic-ref","--quiet","--short","HEAD"])!==r.executionBranch)throw new Error("direct-yolo-current-branch-mismatch");return r}async function Re(e){const t=e.nowIso,r=await A(e.projectRoot,["show","--no-patch","--format=%H%n%P%n%B",e.headSha]),o=O(await A(e.projectRoot,["diff-tree","--no-commit-id","--name-only","-r","-z",e.headSha])),i=Oe({storyId:e.storyId,baseSha:e.baseSha,headSha:e.headSha,bundleDigest:e.bundleDigest,graphRevision:e.graphRevision,commitBody:r,changedPaths:o}),n=Ce({gitEvidenceDigest:i,headSha:e.headSha,graphRevision:e.graphRevision,manifestDigest:e.qaExecution.manifestDigest,gateIds:e.qaExecution.gateIds,resultDigest:e.qaExecution.resultDigest}),p=`story-qa:${n}`,h=Object.freeze({schemaVersion:1,kind:"story_qa_evidence",producer:"local-yolo-tdd",evidenceVersion:"p205-execution-v2",storyId:e.storyId,epicId:e.epicId,baseSha:e.baseSha,headSha:e.headSha,bundleDigest:e.bundleDigest,graphRevision:e.graphRevision,contract:e.qaExecution.contract,command:e.qaExecution.command,manifestDigest:e.qaExecution.manifestDigest,gateIds:e.qaExecution.gateIds,resultDigest:e.qaExecution.resultDigest,sourceEvidenceDigest:n,verdict:"passed",checkedAt:t,receiptRef:p}),d=Q(e.projectRoot,e.storyId,e.headSha);if(d?.verdict!=="approved")throw new Error("direct-yolo-review-artifact-not-approved");const a=D(["root-commit-range-review-v2",e.storyId,e.baseSha,e.headSha,e.bundleDigest,e.graphRevision,p,D(r),[...o].sort().join(","),d.digest].join("\0")),c=`story-review:${a}`,l=Object.freeze({schemaVersion:1,kind:"story_review_evidence",producer:"root-commit-range-review",storyId:e.storyId,epicId:e.epicId,baseSha:e.baseSha,headSha:e.headSha,bundleDigest:e.bundleDigest,graphRevision:e.graphRevision,sourceEvidenceDigest:a,reviewArtifactDigest:d.digest,qaReceiptRef:p,verdict:"approved",reviewedAt:t,receiptRef:c}),u=[`.neocortex/stories/${e.storyId}/qa-gate-result.json`,`.neocortex/stories/${e.storyId}/validation-evidence.md`,p,c,...e.physicalLockOwnerDigest?[`physical-lock-owner:${e.physicalLockOwnerDigest}`]:[],...e.legacyReceiptRef?[e.legacyReceiptRef]:[]];return Object.freeze({schemaVersion:1,storyId:e.storyId,epicId:e.epicId,branch:e.executionBranch,baseSha:e.baseSha,headSha:e.headSha,commits:Object.freeze([e.headSha]),idempotencyKey:e.idempotencyKey,bundleDigest:e.bundleDigest,graphRevision:e.graphRevision,claimRevision:e.claimRevision,receiptRefs:Object.freeze(u),qaVerdict:"passed",reviewVerdict:"approved",qaReceipt:h,reviewReceipt:l,recordedAt:t})}async function Se(e){const{projectRoot:t,checkpoint:r,remote:o}=e;let i=!1;return await $(t,n=>{const p=P(n,r.epicId);if(e.expectedLease){const c=w(p.branch_lease);if(!ne(c,e.expectedLease))throw new Error("direct-yolo-runtime-revision-conflict");if(Date.parse(String(c?.expiresAt))<=Date.now())throw new Error("direct-yolo-writer-lease-expired");if(p.graph_revision!==e.expectedGraphRevision||r.graphRevision!==e.expectedGraphRevision)throw new Error("direct-yolo-graph-revision-raced")}const h=ge(n,r.storyId),d=w(h.checkpoint);if(d&&d.headSha!==r.headSha){i=!0;return}h.checkpoint=r,h.status="done",h.last_step=Ie;const a=Array.isArray(h.steps_completed)?h.steps_completed.filter(c=>typeof c=="string"):[];h.steps_completed=[...new Set([...a,Te,Ie])],p.branch_lease=null},{expectedRevision:e.expectedRevision,preCommit:async()=>{if(i)throw new Error("direct-yolo-checkpoint-conflict");if(await y(t,["symbolic-ref","--quiet","--short","HEAD"])!==r.branch||await y(t,["rev-parse","HEAD"])!==r.headSha)throw new Error("direct-yolo-checkpoint-head-raced");if(!await me(t,r,r.storyId,r.epicId,r.branch,e.transientAuthority,e.authorizedWriteSet))throw new Error("direct-yolo-checkpoint-physical-invalid");if(e.physicalLockPath&&e.physicalLockOwner&&!await U(e.physicalLockPath,e.physicalLockOwner))throw new Error("direct-yolo-integration-lock-raced");if(o&&!(e.remotePolicy==="ancestor-recovery"?await ke(t,o,r.branch,r.headSha):await be(t,o,r.branch,r.headSha)))throw new Error("direct-yolo-checkpoint-remote-raced")}}),!i}async function ke(e,t,r,o){const i=ee(t),n=(await y(e,["ls-remote","--heads",i,`refs/heads/${r}`])).split(/\s+/)[0];return!!(n&&await L(e,["merge-base","--is-ancestor",o,n]))}function oe(e,t,r){return!!(e?.ownerStoryId===t&&e.sessionId===e.idempotencyKey&&typeof e.idempotencyKey=="string"&&/^setup-[a-f0-9]{64}$/.test(e.idempotencyKey)&&typeof e.expiresAt=="string"&&Date.parse(e.expiresAt)>Date.parse(r))}async function xe(e,t){const r=await Ve(e),o=await ze(r,"handoffs"),i=`direct-${D(t)}.json`;return{parent:o,name:i,path:te(o,i)}}async function ie(e,t){const r=await xe(e,t.storyId);await Fe(r.parent,r.name,`${JSON.stringify(t,null,2)}
|
|
2
|
-
`),await
|
|
3
|
-
`).map(i=>i.trim()).filter(i=>i.startsWith(r)).map(i=>i.slice(r.length));return o.length===1?o[0]:void 0}function
|
|
4
|
-
`))o.startsWith("worktree ")?(r={path:o.slice(9)},t.push(r)):r&&o.startsWith("branch refs/heads/")&&(r.branch=o.slice(18));return t}function
|
|
1
|
+
import{execFile as $e}from"node:child_process";import{createHash as ze,randomBytes as Re,timingSafeEqual as Ne}from"node:crypto";import{readFile as oe}from"node:fs/promises";import{join as he,resolve as ie}from"node:path";import{promisify as Me}from"node:util";import{readRootMemoryEffectForCheckpoint as We}from"../private-execution/root-memory-scope.js";import{rootMemoryEffectDigest as Ge,verifyRootMemoryPhysicalWriteSet as fe}from"../private-execution/root-memory-git-evidence.js";import{acquireGitLifecyclePhysicalIntegrationLock as V,applyGitLifecycleRuntimeOverlay as Te,computeImmutableStoryQaEvidenceDigest as Ke,computeGitLifecyclePhysicalIntegrationLockOwnerDigest as Se,computeP205StoryQaEvidenceDigest as Ve,computeLegacyDirectYoloRecoveryReceiptRef as Fe,ensureRuntimeEpic as W,ensureRuntimeStory as xe,ensureGitLifecyclePrivateChildDirectory as Ye,executeP205TransientAuthority as Je,projectP205TransientExecutionEvidence as Ze,publicStoryReviewArtifactFromGit as ne,LEGACY_DIRECT_YOLO_RECOVERY_COMMITS as Qe,mutateGitLifecycleRuntime as P,P205_COMPLETE_COMMAND as Ue,readGitLifecycleRuntime as q,gitLifecycleRuntimeDirectory as Xe,assertGitLifecyclePrivateFile as De,releaseGitLifecyclePhysicalIntegrationLock as G,releaseGitLifecyclePhysicalIntegrationLockForCheckpoint as et,renewGitLifecyclePhysicalIntegrationLock as tt,verifyGitLifecyclePhysicalIntegrationLock as J,verifyAcceptedGitLifecycleStoryCheckpoint as be}from"./git-lifecycle-store.js";import{anchoredAtomicWriteFile as rt}from"./secure-filesystem-boundary.js";import{GIT_LIFECYCLE_COMMIT_PUSH_STEP_ID as ot,GIT_LIFECYCLE_REVIEW_PR_STEP_ID as ke,GIT_LIFECYCLE_SETUP_BRANCH_STEP_ID as ae}from"./git-lifecycle-step-ids.js";const le=Me($e),it=1800*1e3,nt=300*1e3;async function Dt(e){try{const t=await je(e.projectRoot,e.storyId),r=T(e.nowIso),o=Date.parse(r),i=await p(t.projectRoot,["symbolic-ref","--quiet","--short","HEAD"]),n=await p(t.projectRoot,["rev-parse","HEAD"]),l=await q(t.projectRoot,{required:!0}),c=w(l.epics[t.epicId]),d=w(c?.branch_lease),a=d&&Number.isFinite(Date.parse(String(d.expiresAt)))&&Date.parse(String(d.expiresAt))>o;if(a&&d?.ownerStoryId!==e.storyId)return s("direct-yolo-writer-active");let h=Ie(c?.origin_binding,t.executionBranch,t.originBranch);if(i===t.executionBranch){if(!h)return s("direct-yolo-origin-binding-invalid")}else{if(i!==t.originBranch)return s("direct-yolo-current-branch-mismatch");if(h&&h.originHeadSha!==n)return s("direct-yolo-origin-binding-conflict");if(h??={schemaVersion:1,originBranch:t.originBranch,originHeadSha:n,executionBranch:t.executionBranch,capturedFromCurrentCheckout:!0,capturedAt:r},(await Pe(t.projectRoot)).some(m=>m.branch===t.executionBranch&&ie(m.path)!==t.projectRoot))return s("direct-yolo-execution-branch-checked-out-elsewhere");const S=await X(t.projectRoot),x=`refs/heads/${t.executionBranch}`;if(await C(t.projectRoot,["show-ref","--verify","--quiet",x])){const m=await p(t.projectRoot,["rev-parse",x]);if(m!==n){if(!await C(t.projectRoot,["merge-base","--is-ancestor",m,n]))return s("direct-yolo-execution-branch-diverged");await p(t.projectRoot,["update-ref",x,n,m])}await p(t.projectRoot,["switch",t.executionBranch])}else await p(t.projectRoot,["switch","-c",t.executionBranch]);if(await X(t.projectRoot)!==S)return s("direct-yolo-checkout-payload-raced")}const u=await p(t.projectRoot,["symbolic-ref","--quiet","--short","HEAD"]),f=await p(t.projectRoot,["rev-parse","HEAD"]);if(u!==t.executionBranch)return s("direct-yolo-current-branch-mismatch");if(a&&d?.ownerStoryId===e.storyId)return d.setupHeadSha!==f?s("direct-yolo-setup-lease-head-unbound"):{ok:!0,value:ve(t,h,String(d.expiresAt),!0)};const v=r,b=new Date(o+3600*1e3).toISOString(),I=`setup-${Re(32).toString("hex")}`,R=await q(t.projectRoot,{required:!0});return await P(t.projectRoot,k=>{const S=W(k,t.epicId),x=w(S.branch_lease);if(x&&Date.parse(String(x.expiresAt))>o&&x.ownerStoryId!==e.storyId)throw new Error("direct-yolo-writer-active");const m=Ie(S.origin_binding,t.executionBranch,t.originBranch);if(S.origin_binding&&!m)throw new Error("direct-yolo-origin-binding-conflict");if(m&&JSON.stringify(m)!==JSON.stringify(h))throw new Error("direct-yolo-origin-binding-conflict");S.branch_mode="epic",S.execution_branch=t.executionBranch,S.origin_branch=t.originBranch,S.graph_revision=t.graphRevision,S.origin_binding=h,S.branch_lease={schemaVersion:1,ownerStoryId:e.storyId,sessionId:I,idempotencyKey:I,acquiredAt:v,expiresAt:b,setupHeadSha:f}},{expectedRevision:R.revision,preCommit:async()=>{if(await p(t.projectRoot,["symbolic-ref","--quiet","--short","HEAD"])!==t.executionBranch||await p(t.projectRoot,["rev-parse","HEAD"])!==f)throw new Error("direct-yolo-setup-physical-state-raced")}}),{ok:!0,value:ve(t,h,b,!1)}}catch(t){return s(ee(t,"direct-yolo-setup-failed"))}}async function bt(e){let t;try{const r=await Z(e.projectRoot,e.storyId),o=T(e.nowIso),i=he(r.projectRoot,".neocortex/state.json"),n=await oe(i,"utf8"),l=await X(r.projectRoot),c=await p(r.projectRoot,["rev-parse","HEAD"]),d=`refs/heads/${r.executionBranch}`,a=await q(r.projectRoot,{required:!0}),h=w(a.epics[r.epicId]),u=Ie(h?.origin_binding,r.executionBranch,r.originBranch),f=w(h?.branch_lease);if(!u)return s("direct-yolo-origin-binding-invalid");if(!f||!ue(f,e.storyId,o)||f?.sessionId!==f?.idempotencyKey)return s("direct-yolo-setup-lease-invalid");const v=await V(r.projectRoot,{kind:"direct",storyId:e.storyId,sessionId:String(f.sessionId),idempotencyKey:String(f.idempotencyKey),expiresAt:new Date(Date.now()+300*1e3).toISOString(),persistent:!1});if(!v.ok)return s(v.reasonCode);if(t=v,c!==f.setupHeadSha||!await C(r.projectRoot,["merge-base","--is-ancestor",u.originHeadSha,c])||await p(r.projectRoot,["rev-parse",d])!==c)return s("direct-yolo-setup-head-mismatch");if((await Pe(r.projectRoot)).some(m=>m.branch===r.executionBranch&&ie(m.path)!==r.projectRoot))return s("direct-yolo-execution-branch-checked-out-elsewhere");const I=w(JSON.parse(n)),R=w(w(I?.stories)?.[e.storyId]),k=w(a.stories[e.storyId]);if(!R||!["backlog","ready_to_start"].includes(String(R.status))||R.steps_completed!==void 0&&(!Array.isArray(R.steps_completed)||R.steps_completed.length>0)||R.branch_name||R.checkpoint)return s("direct-yolo-setup-story-progress-conflict");const S=k?.status==="branch-ready"&&k.last_step===ae&&Array.isArray(k.steps_completed)&&k.steps_completed.length===1&&k.steps_completed[0]===ae&&Object.keys(k).sort().join(",")==="last_step,status,steps_completed";if(k&&Object.keys(k).length>0&&!S)return s("direct-yolo-setup-story-progress-conflict");const x=async()=>{if(Date.parse(String(f.expiresAt))<=(e.nowIso?Date.parse(o):Date.now())||!t||!await J(t.path,t.owner)||await oe(i,"utf8")!==n||await X(r.projectRoot)!==l||await p(r.projectRoot,["symbolic-ref","--quiet","--short","HEAD"])!==r.executionBranch||await p(r.projectRoot,["rev-parse","HEAD"])!==c||!await C(r.projectRoot,["merge-base","--is-ancestor",u.originHeadSha,c])||await p(r.projectRoot,["rev-parse",d])!==c)throw new Error("direct-yolo-setup-physical-state-raced")};return S?await x():await P(r.projectRoot,m=>{const g=w(m.epics[r.epicId]),D=xe(m,e.storyId);if(JSON.stringify(g?.branch_lease)!==JSON.stringify(f)||JSON.stringify(g?.origin_binding)!==JSON.stringify(u)||g?.graph_revision!==r.graphRevision||Object.keys(D).length>0)throw new Error("direct-yolo-setup-runtime-raced");D.status="branch-ready",D.last_step=ae,D.steps_completed=[ae]},{expectedRevision:a.revision,preCommit:x}),{ok:!0,value:Object.freeze({...ve(r,u,String(f.expiresAt),S),checkpointAccepted:!0,graphRevision:r.graphRevision,headSha:c})}}catch(r){return s(ee(r,"direct-yolo-setup-acceptance-failed"))}finally{t&&await G(t.path,t.owner).catch(()=>{})}}async function kt(e){try{const t=await Z(e.projectRoot,e.storyId),r=$(await E(t.projectRoot,["diff","--cached","--name-only","-z"])),o=Q(r,t.authorizedWriteSet,e.storyId,t.rootMemoryEffect);if(!o.ok)return s(o.reasonCode);if(t.rootMemoryEffect&&fe(t.projectRoot,t.rootMemoryEffect,{storyId:e.storyId,executionBranch:t.executionBranch,baseSha:await p(t.projectRoot,["rev-parse","HEAD"]),headRef:":",childPaths:t.authorizedWriteSet}),ne(t.projectRoot,e.storyId,":")?.verdict!=="approved")return s("direct-yolo-review-artifact-not-approved");if($(await E(t.projectRoot,["diff","--name-only","-z"])).some(y=>r.includes(y)))return s("direct-yolo-user-overlap");const l=await E(t.projectRoot,["diff","--cached","--binary","--full-index"]);if(!l)return s("direct-yolo-staged-diff-empty");const c=j(l),d=j([...t.authorizedWriteSet].sort().join("\0")),a=T(e.nowIso),h=await q(t.projectRoot,{required:!0}),u=w(h.epics[t.epicId]?.branch_lease);if(!ue(u,e.storyId,a))return s("direct-yolo-setup-handoff-owner-invalid");const f=String(u.sessionId),v=String(u.expiresAt),b=new Date(Math.min(Date.parse(v),Date.parse(a)+300*1e3)).toISOString(),I=await F(t.projectRoot,e.storyId),R=I?.state==="issued"&&I.fromSessionId===f&&I.bundleDigest===c&&I.claimRevision===d&&Date.parse(I.expiresAt)>Date.parse(a),k=R?I.expiresAt:b,S=R?I.token:Re(32).toString("base64url"),x=j(S),m=Object.freeze({schemaVersion:1,kind:"direct-yolo-setup-handoff",storyId:e.storyId,fromSessionId:f,tokenDigest:x,bundleDigest:c,claimRevision:d,expiresAt:k}),g=j(JSON.stringify(m)),D=await V(t.projectRoot,{kind:"direct",storyId:e.storyId,sessionId:f,idempotencyKey:f,expiresAt:k,persistent:!1,createdAt:a});if(!D.ok)return s(D.reasonCode==="git-lifecycle-integration-backpressure"?"direct-yolo-integration-backpressure":"direct-yolo-integration-lock-failed");try{await ye(t.projectRoot,{schemaVersion:1,kind:"direct-yolo-setup-handoff-token",state:"issued",storyId:e.storyId,fromSessionId:f,token:S,tokenDigest:x,bundleDigest:c,claimRevision:d,grantDigest:g,expiresAt:k}),await P(t.projectRoot,y=>{const A=w(W(y,t.epicId).branch_lease);if(!ue(A,e.storyId,a)||A?.sessionId!==f||A.idempotencyKey!==f)throw new Error("direct-yolo-setup-handoff-owner-raced");A.handoffGrant=m},{expectedRevision:h.revision,preCommit:async()=>{if(!await J(D.path,D.owner))throw new Error("direct-yolo-integration-lock-raced");const y=await F(t.projectRoot,e.storyId);if(!y||y.state!=="issued"||y.grantDigest!==g||y.tokenDigest!==x)throw new Error("direct-yolo-setup-handoff-token-raced")}})}finally{await G(D.path,D.owner).catch(()=>{})}return{ok:!0,value:Object.freeze({schemaVersion:1,kind:"direct-yolo-setup-handoff-receipt",storyId:e.storyId,sessionId:f,bundleDigest:c,claimRevision:d,grantDigest:g,expiresAt:k,reused:R,publicSafe:!0})}}catch(t){return s(t instanceof Error&&/^direct-yolo-/.test(t.message)?t.message:"direct-yolo-setup-handoff-failed")}}async function jt(e){try{const t=await Z(e.projectRoot,e.storyId),r=await p(t.projectRoot,["rev-parse","HEAD"]),o=$(await E(t.projectRoot,["diff","--cached","--name-only","-z"])),i=Q(o,t.authorizedWriteSet,e.storyId,t.rootMemoryEffect);if(!i.ok)return s(i.reasonCode);t.rootMemoryEffect&&fe(t.projectRoot,t.rootMemoryEffect,{storyId:e.storyId,executionBranch:t.executionBranch,baseSha:r,headRef:":",childPaths:t.authorizedWriteSet});const n=ne(t.projectRoot,e.storyId,":");if(n?.verdict!=="approved")return s("direct-yolo-review-artifact-not-approved");if($(await E(t.projectRoot,["diff","--name-only","-z"])).some(g=>o.includes(g)))return s("direct-yolo-user-overlap");const c=await E(t.projectRoot,["diff","--cached","--binary","--full-index"]);if(!c)return s("direct-yolo-staged-diff-empty");const d=j(c),a=j([...t.authorizedWriteSet].sort().join("\0")),h=j(["direct-yolo-commit-v1",e.storyId,t.epicId,t.executionBranch,r,d,t.graphRevision,a].join("\0")),u=T(e.nowIso);let f=e.setupLeaseHandoff??await at(t.projectRoot,e.storyId,d,a,u);const v=await q(t.projectRoot,{required:!0}),b=w(v.epics[t.epicId]?.branch_lease),I=b?.ownerStoryId===e.storyId&&b.sessionId===h&&b.idempotencyKey===h&&typeof b.expiresAt=="string"&&Date.parse(b.expiresAt)>Date.parse(u)?b:void 0;if(I&&e.setupLeaseHandoff)return s("direct-yolo-setup-handoff-replayed");const R=w(I?.handoffConsumption);if(R){const g=await F(t.projectRoot,e.storyId);if(!g||!["consuming","consumed"].includes(g.state)||g.fromSessionId!==R.fromSessionId||g.tokenDigest!==R.tokenDigest||g.bundleDigest!==d||g.claimRevision!==a||R.bundleDigest!==d||R.claimRevision!==a||g.consumedBySessionId!==h||R.consumedBySessionId!==h)return s("direct-yolo-setup-handoff-consume-invalid");if(g.state==="consuming"){if(!g.token||j(g.token)!==g.tokenDigest)return s("direct-yolo-setup-handoff-consume-invalid");f={sessionId:g.fromSessionId,token:g.token}}}const k=Le(e.writerLeaseDurationMs),S=I?String(I.expiresAt):new Date(Date.parse(u)+k).toISOString(),x=await V(t.projectRoot,{kind:"direct",storyId:e.storyId,sessionId:h,idempotencyKey:h,expiresAt:S,persistent:!0,createdAt:I&&typeof I.acquiredAt=="string"?I.acquiredAt:u});if(!x.ok)return s(x.reasonCode==="git-lifecycle-integration-backpressure"?"direct-yolo-integration-backpressure":"direct-yolo-integration-lock-failed");try{f&&e.setupLeaseHandoff===void 0&&(await ct(t.projectRoot,e.storyId,f.sessionId,f.token,h,u),await e.setupHandoffFault?.("after-consuming-persisted")),await P(t.projectRoot,g=>{const D=W(g,t.epicId),y=w(D.branch_lease),A=y&&Date.parse(String(y.expiresAt))>Date.parse(u),Y=y?.ownerStoryId===e.storyId&&y.sessionId===h&&y.idempotencyKey===h,K=y?.ownerStoryId===e.storyId&&y.sessionId===y.idempotencyKey&&typeof y.idempotencyKey=="string"&&/^setup-[a-f0-9]{64}$/.test(y.idempotencyKey),z=A&&K&&dt({current:y,handoff:f,storyId:e.storyId,bundleDigest:d,claimRevision:a,nowIso:u});if(f&&A&&!Y&&!z)throw new Error("direct-yolo-setup-handoff-invalid");if(A&&!Y&&!z)throw new Error("direct-yolo-writer-active");const B=z?w(y?.handoffGrant):void 0,H=B?{schemaVersion:1,kind:"direct-yolo-setup-handoff-consumption",state:"consumed",storyId:e.storyId,fromSessionId:String(y?.sessionId),tokenDigest:String(B.tokenDigest),bundleDigest:d,claimRevision:a,consumedBySessionId:h,consumedAt:u}:void 0;D.branch_mode="epic",D.execution_branch=t.executionBranch,D.origin_branch=t.originBranch,D.graph_revision=t.graphRevision,D.branch_lease=A&&Y?y:{schemaVersion:1,ownerStoryId:e.storyId,sessionId:h,idempotencyKey:h,acquiredAt:u,expiresAt:S,...H?{handoffConsumption:H}:{}}},{expectedRevision:v.revision,preCommit:async()=>{if(!await J(x.path,x.owner))throw new Error("direct-yolo-integration-lock-raced")}})}catch(g){throw await G(x.path,x.owner).catch(()=>{}),g}f&&e.setupLeaseHandoff===void 0&&(await e.setupHandoffFault?.("before-consumed-persist"),await st(t.projectRoot,t.epicId,e.storyId,f.sessionId,f.token,d,a,h,u));const m=Object.freeze([`Neocortex-Story: ${e.storyId}`,`Neocortex-Epic: ${t.epicId}`,`Neocortex-Execution-Branch: ${t.executionBranch}`,`Neocortex-Prepared-Base: ${r}`,`Neocortex-Bundle-Digest: ${d}`,`Neocortex-Review-Artifact-Digest: ${n.digest}`,`Neocortex-Graph-Revision: ${t.graphRevision}`,`Neocortex-Claim-Revision: ${a}`,...t.rootMemoryEffect?[`Neocortex-Root-Memory-Effect: ${Ge(t.rootMemoryEffect)}`]:[]]);return{ok:!0,value:Object.freeze({schemaVersion:1,storyId:e.storyId,epicId:t.epicId,executionBranch:t.executionBranch,baseSha:r,bundleDigest:d,reviewArtifactDigest:n.digest,graphRevision:t.graphRevision,claimRevision:a,idempotencyKey:h,changedPaths:Object.freeze(o),trailers:m})}}catch(t){return s(ee(t,"direct-yolo-begin-failed"))}}async function Et(e){let t,r,o;try{const i=await Z(e.projectRoot,e.storyId);t=i;const n=await p(i.projectRoot,["rev-parse","HEAD"]);let l=await q(i.projectRoot,{required:!0});const c=w(l.stories[e.storyId]?.checkpoint);if(c){const L=typeof c.headSha=="string"?c.headSha:"",N=typeof c.graphRevision=="string"?c.graphRevision:"",O=/^[a-f0-9]{40,64}$/.test(L)?$(await E(i.projectRoot,["diff-tree","--no-commit-id","--name-only","-r","-z",L])):[],M=Q(O,i.authorizedWriteSet,e.storyId,i.rootMemoryEffect);if(!(/^[a-f0-9]{40,64}$/.test(L)&&await C(i.projectRoot,["merge-base","--is-ancestor",L,n]))||!/^[a-f0-9]{64}$/.test(N)||!M.ok)return s("direct-yolo-replay-invalid");const re=await ge(e,i.projectRoot,n,N);if(!await be(i.projectRoot,c,e.storyId,i.epicId,i.executionBranch,re.transientAuthority,i.authorizedWriteSet))return s("direct-yolo-replay-invalid");if(!await we(i.projectRoot,i.executionBranch,n,O))return s("direct-yolo-replay-head-raced");if(e.push&&!await Be(i.projectRoot,e.remote??"origin",i.executionBranch,L))return s("direct-yolo-remote-head-mismatch");const de=Array.isArray(c.receiptRefs)?c.receiptRefs.find(_=>typeof _=="string"&&/^physical-lock-owner:[a-f0-9]{64}$/.test(_)):void 0;return de&&typeof c.idempotencyKey=="string"&&await et(i.projectRoot,{storyId:e.storyId,idempotencyKey:c.idempotencyKey,ownerDigest:de.slice(20)}),{ok:!0,value:c}}const d=n,a=await p(i.projectRoot,["rev-parse",`${d}^`]),h=await E(i.projectRoot,["show","--no-patch","--format=%B",d]),u=$(await E(i.projectRoot,["diff-tree","--no-commit-id","--name-only","-r","-z",d])),f=Q(u,i.authorizedWriteSet,e.storyId,i.rootMemoryEffect);if(!f.ok)return s(f.reasonCode);i.rootMemoryEffect&&fe(i.projectRoot,i.rootMemoryEffect,{storyId:e.storyId,executionBranch:i.executionBranch,baseSha:a,headRef:d,childPaths:i.authorizedWriteSet});const v=U(h,"Neocortex-Bundle-Digest"),b=U(h,"Neocortex-Graph-Revision"),I=U(h,"Neocortex-Claim-Revision"),R=new Map([["Neocortex-Story",e.storyId],["Neocortex-Epic",i.epicId],["Neocortex-Execution-Branch",i.executionBranch],["Neocortex-Prepared-Base",a],["Neocortex-Graph-Revision",i.graphRevision],["Neocortex-Claim-Revision",j([...i.authorizedWriteSet].sort().join("\0"))]]);if(!v||!/^[a-f0-9]{64}$/.test(v)||!b||!I||[...R].some(([L,N])=>U(h,L)!==N))return s("direct-yolo-trailers-invalid");const k=ne(i.projectRoot,e.storyId,d);if(k?.verdict!=="approved")return s("direct-yolo-review-artifact-not-approved");const S=U(h,"Neocortex-Review-Artifact-Digest");if(S!==void 0&&S!==k.digest)return s("direct-yolo-review-artifact-digest-mismatch");const x=j(await E(i.projectRoot,["diff","--binary","--full-index",`${a}..${d}`]));if(v!==x)return s("direct-yolo-bundle-digest-mismatch");const m=j(["direct-yolo-commit-v1",e.storyId,i.epicId,i.executionBranch,a,v,b,I].join("\0")),g=w(l.epics[i.epicId]?.branch_lease),D=T(e.nowIso),y=g?.ownerStoryId===e.storyId&&g.idempotencyKey===m&&g.sessionId===m&&Date.parse(String(g.expiresAt))>Date.now()?g:void 0;if(g&&Date.parse(String(g.expiresAt))>Date.now()&&!y)return s("direct-yolo-writer-active");const A=Le(e.writerLeaseDurationMs),Y=ft(e.writerLeaseHeartbeatIntervalMs,A),K=y??{schemaVersion:1,ownerStoryId:e.storyId,sessionId:m,idempotencyKey:m,acquiredAt:D,expiresAt:new Date(Date.parse(D)+A).toISOString()},z=await V(i.projectRoot,{kind:"direct",storyId:e.storyId,sessionId:m,idempotencyKey:m,expiresAt:String(K.expiresAt),persistent:!0,createdAt:String(K.acquiredAt)});if(!z.ok)return s(z.reasonCode==="git-lifecycle-integration-backpressure"?"direct-yolo-integration-backpressure":"direct-yolo-integration-lock-failed");let B={path:z.path,owner:z.owner};o=B,y||(l=(await P(i.projectRoot,N=>{const O=W(N,i.epicId),M=w(O.branch_lease);if(M&&Date.parse(String(M.expiresAt))>Date.parse(D))throw new Error("direct-yolo-writer-active");if(O.graph_revision!==i.graphRevision)throw new Error("direct-yolo-graph-revision-raced");O.branch_lease=K},{expectedRevision:l.revision})).document);let H=K;r=H;{const L=await He({projectRoot:i.projectRoot,epicId:i.epicId,storyId:e.storyId,graphRevision:i.graphRevision,leaseDurationMs:A,state:{runtime:l,lease:H,physical:B}});l=L.runtime,H=L.lease,B=L.physical,r=H,o=B;const N=lt({projectRoot:i.projectRoot,epicId:i.epicId,storyId:e.storyId,graphRevision:i.graphRevision,leaseDurationMs:A,heartbeatIntervalMs:Y,state:{runtime:l,lease:H,physical:B},onRenewed:_=>{l=_.runtime,H=_.lease,B=_.physical,r=H,o=B}});let O,M;try{O=await ge(e,i.projectRoot,d,i.graphRevision)}catch(_){M=_}let te;try{await N.stop()}catch(_){te=_}if(M)throw M;if(te)throw te;if(!O)throw new Error("direct-yolo-qa-evidence-missing");if(!await we(i.projectRoot,i.executionBranch,d,u))return s("direct-yolo-head-raced");if(e.push){const _=se(e.remote??"origin");if(await p(i.projectRoot,["push",_,i.executionBranch]),!await Oe(i.projectRoot,_,i.executionBranch,d))return s("direct-yolo-remote-head-mismatch")}const re=await Ee({projectRoot:i.projectRoot,storyId:e.storyId,epicId:i.epicId,executionBranch:i.executionBranch,baseSha:a,headSha:d,bundleDigest:v,graphRevision:b,claimRevision:I,idempotencyKey:m,qaExecution:O,physicalLockOwnerDigest:Se(B.owner),nowIso:T(e.nowIso),legacyReceiptRef:void 0,rootMemoryEffect:i.rootMemoryEffect});return await e.beforeCheckpointPersist?.(),await Ae({projectRoot:i.projectRoot,checkpoint:re,remote:e.push?e.remote??"origin":void 0,expectedRevision:l.revision,expectedLease:H,expectedGraphRevision:i.graphRevision,physicalLockPath:B.path,physicalLockOwner:B.owner,transientAuthority:O.transientAuthority,authorizedWriteSet:i.authorizedWriteSet})?(await e.afterCheckpointPersist?.(),{ok:!0,value:re}):s("direct-yolo-checkpoint-persist-failed")}}catch(i){return s(ee(i,"direct-yolo-finalize-failed"))}finally{o&&await G(o.path,o.owner).catch(()=>{}),t&&r?await pe(t.projectRoot,t.epicId,r).catch(()=>{}):t&&await ut(t,e.storyId).catch(()=>{})}}async function At(e){try{const t=await Z(e.projectRoot,e.storyId);if(!/^[a-f0-9]{40,64}$/.test(e.commitSha))return s("direct-yolo-recovery-commit-invalid");const r=await p(t.projectRoot,["rev-parse",e.commitSha]);if(Qe[e.storyId]!==r)return s("direct-yolo-recovery-not-allowlisted");if(await p(t.projectRoot,["rev-parse","HEAD"])!==r)return s("direct-yolo-recovery-head-mismatch");await p(t.projectRoot,["merge-base","--is-ancestor",r,`refs/heads/${t.executionBranch}`]);const o=await p(t.projectRoot,["rev-parse",`${r}^`]),i=await E(t.projectRoot,["diff","--binary","--full-index",`${o}..${r}`]),n=$(await E(t.projectRoot,["diff-tree","--no-commit-id","--name-only","-r","-z",r]));if(!Q(n,t.authorizedWriteSet.length>0?t.authorizedWriteSet:n,e.storyId).ok)return s("direct-yolo-recovery-write-set-invalid");const c=j(i),d=j([...n].sort().join("\0")),a=j(["legacy-direct-yolo-recovery-v1",e.storyId,r].join("\0")),h=T(e.nowIso),u=new Date(Date.parse(h)+1800*1e3).toISOString(),f=await q(t.projectRoot,{required:!0}),v=await V(t.projectRoot,{kind:"direct",storyId:e.storyId,sessionId:a,idempotencyKey:a,expiresAt:u,persistent:!0,createdAt:h});if(!v.ok)return s(v.reasonCode==="git-lifecycle-integration-backpressure"?"direct-yolo-recovery-integration-backpressure":"direct-yolo-recovery-integration-lock-failed");const b={schemaVersion:1,ownerStoryId:e.storyId,sessionId:a,idempotencyKey:a,acquiredAt:h,expiresAt:u};let I=!1;try{const R=await P(t.projectRoot,D=>{const y=W(D,t.epicId),A=w(y.branch_lease);if(A&&Date.parse(String(A.expiresAt))>Date.parse(h)&&!ce(A,b))throw new Error("direct-yolo-recovery-writer-active");if(y.graph_revision!==t.graphRevision)throw new Error("direct-yolo-recovery-graph-raced");y.branch_mode="epic",y.execution_branch=t.executionBranch,y.origin_branch=t.originBranch,y.branch_lease=b},{expectedRevision:f.revision});I=!0;const k=await ge(e,t.projectRoot,r,t.graphRevision);if(!await we(t.projectRoot,t.executionBranch,r,n))return s("direct-yolo-recovery-head-raced");if(e.push){const D=se(e.remote??"origin"),y=(await p(t.projectRoot,["ls-remote","--heads",D,`refs/heads/${t.executionBranch}`])).split(/\s+/)[0];if(!y||!await C(t.projectRoot,["merge-base","--is-ancestor",r,y]))return s("direct-yolo-recovery-remote-proof-missing")}const S=await Ee({projectRoot:t.projectRoot,storyId:e.storyId,epicId:t.epicId,executionBranch:t.executionBranch,baseSha:o,headSha:r,bundleDigest:c,graphRevision:t.graphRevision,claimRevision:d,idempotencyKey:a,qaExecution:k,physicalLockOwnerDigest:Se(v.owner),nowIso:h,legacyReceiptRef:void 0}),x=await Fe(t.projectRoot,{storyId:e.storyId,epicId:t.epicId,executionBranch:t.executionBranch,baseSha:o,headSha:r,bundleDigest:c,graphRevision:t.graphRevision});if(!x)return s("direct-yolo-recovery-evidence-invalid");const m=Object.freeze({...S,receiptRefs:Object.freeze([...S.receiptRefs,x])});return await Ae({projectRoot:t.projectRoot,checkpoint:m,remote:e.push?e.remote??"origin":void 0,remotePolicy:"ancestor-recovery",expectedRevision:R.document.revision,expectedLease:b,expectedGraphRevision:t.graphRevision,physicalLockPath:v.path,physicalLockOwner:v.owner,transientAuthority:k.transientAuthority,authorizedWriteSet:t.authorizedWriteSet})?{ok:!0,value:m}:s("direct-yolo-recovery-persist-failed")}finally{await G(v.path,v.owner).catch(()=>{}),I&&await pe(t.projectRoot,t.epicId,b).catch(()=>{})}}catch(t){return s(ee(t,"direct-yolo-recovery-failed"))}}async function je(e,t){if(!/^[A-Za-z][A-Za-z0-9_-]*\.[A-Za-z0-9._-]+$/.test(t))throw new Error("direct-yolo-story-id-invalid");const r=ie(e),o=w(JSON.parse(await oe(he(r,".neocortex/state.json"),"utf8"))),i=await q(r,{required:!0}),n=Te(o,i),l=w(n.stories),c=w(n.epics),d=w(l?.[t]),a=String(d?.epic_id??t.split(".")[0]),h=w(c?.[a]),u=String(h?.execution_branch??""),f=String(h?.origin_branch??""),v=String(h?.graph_revision??""),b=Array.isArray(d?.files_to_modify)?[...new Set(d.files_to_modify.filter(R=>typeof R=="string"&&me(R)))].sort():[];if(!d)throw new Error("direct-yolo-story-state-missing");if(h?.branch_mode!=="epic")throw new Error("direct-yolo-branch-mode-invalid");if(!qe(u)||!await C(r,["check-ref-format","--branch",u]))throw new Error("direct-yolo-execution-branch-invalid");if(!qe(f)||!await C(r,["check-ref-format","--branch",f]))throw new Error("direct-yolo-origin-branch-invalid");if(!/^[a-f0-9]{64}$/.test(v))throw new Error("direct-yolo-graph-revision-invalid");const I=await We({projectRoot:r,storyId:t,graphRevision:v,executionBranch:u,childPaths:b});return{projectRoot:r,storyId:t,story:d,epicId:a,executionBranch:u,originBranch:f,graphRevision:v,authorizedWriteSet:b,rootMemoryEffect:I}}async function Z(e,t){const r=await je(e,t);if(await p(r.projectRoot,["symbolic-ref","--quiet","--short","HEAD"])!==r.executionBranch)throw new Error("direct-yolo-current-branch-mismatch");return r}async function Ee(e){const t=e.nowIso,r=await E(e.projectRoot,["show","--no-patch","--format=%H%n%P%n%B",e.headSha]),o=$(await E(e.projectRoot,["diff-tree","--no-commit-id","--name-only","-r","-z",e.headSha])),i=Ke({storyId:e.storyId,baseSha:e.baseSha,headSha:e.headSha,bundleDigest:e.bundleDigest,graphRevision:e.graphRevision,commitBody:r,changedPaths:o}),n=Ve({gitEvidenceDigest:i,headSha:e.headSha,graphRevision:e.graphRevision,manifestDigest:e.qaExecution.manifestDigest,gateIds:e.qaExecution.gateIds,resultDigest:e.qaExecution.resultDigest}),l=`story-qa:${n}`,c=Object.freeze({schemaVersion:1,kind:"story_qa_evidence",producer:"local-yolo-tdd",evidenceVersion:"p205-execution-v2",storyId:e.storyId,epicId:e.epicId,baseSha:e.baseSha,headSha:e.headSha,bundleDigest:e.bundleDigest,graphRevision:e.graphRevision,contract:e.qaExecution.contract,command:e.qaExecution.command,manifestDigest:e.qaExecution.manifestDigest,gateIds:e.qaExecution.gateIds,resultDigest:e.qaExecution.resultDigest,sourceEvidenceDigest:n,verdict:"passed",checkedAt:t,receiptRef:l}),d=ne(e.projectRoot,e.storyId,e.headSha);if(d?.verdict!=="approved")throw new Error("direct-yolo-review-artifact-not-approved");const a=j(["root-commit-range-review-v2",e.storyId,e.baseSha,e.headSha,e.bundleDigest,e.graphRevision,l,j(r),[...o].sort().join(","),d.digest].join("\0")),h=`story-review:${a}`,u=Object.freeze({schemaVersion:1,kind:"story_review_evidence",producer:"root-commit-range-review",storyId:e.storyId,epicId:e.epicId,baseSha:e.baseSha,headSha:e.headSha,bundleDigest:e.bundleDigest,graphRevision:e.graphRevision,sourceEvidenceDigest:a,reviewArtifactDigest:d.digest,qaReceiptRef:l,verdict:"approved",reviewedAt:t,receiptRef:h}),f=[`.neocortex/stories/${e.storyId}/qa-gate-result.json`,`.neocortex/stories/${e.storyId}/validation-evidence.md`,l,h,...e.physicalLockOwnerDigest?[`physical-lock-owner:${e.physicalLockOwnerDigest}`]:[],...e.legacyReceiptRef?[e.legacyReceiptRef]:[]];return Object.freeze({schemaVersion:1,storyId:e.storyId,epicId:e.epicId,branch:e.executionBranch,baseSha:e.baseSha,headSha:e.headSha,commits:Object.freeze([e.headSha]),idempotencyKey:e.idempotencyKey,bundleDigest:e.bundleDigest,graphRevision:e.graphRevision,claimRevision:e.claimRevision,receiptRefs:Object.freeze(f),qaVerdict:"passed",reviewVerdict:"approved",qaReceipt:c,reviewReceipt:u,recordedAt:t,...e.rootMemoryEffect?{rootMemoryEffect:e.rootMemoryEffect}:{}})}async function Ae(e){const{projectRoot:t,checkpoint:r,remote:o}=e;let i=!1;return await P(t,n=>{const l=W(n,r.epicId);if(e.expectedLease){const h=w(l.branch_lease);if(!ce(h,e.expectedLease))throw new Error("direct-yolo-runtime-revision-conflict");if(Date.parse(String(h?.expiresAt))<=Date.now())throw new Error("direct-yolo-writer-lease-expired");if(l.graph_revision!==e.expectedGraphRevision||r.graphRevision!==e.expectedGraphRevision)throw new Error("direct-yolo-graph-revision-raced")}const c=xe(n,r.storyId),d=w(c.checkpoint);if(d&&d.headSha!==r.headSha){i=!0;return}c.checkpoint=r,c.status="done",c.last_step=ke;const a=Array.isArray(c.steps_completed)?c.steps_completed.filter(h=>typeof h=="string"):[];c.steps_completed=[...new Set([...a,ot,ke])],l.branch_lease=null},{expectedRevision:e.expectedRevision,preCommit:async()=>{if(i)throw new Error("direct-yolo-checkpoint-conflict");if(await p(t,["symbolic-ref","--quiet","--short","HEAD"])!==r.branch||await p(t,["rev-parse","HEAD"])!==r.headSha)throw new Error("direct-yolo-checkpoint-head-raced");if(!await be(t,r,r.storyId,r.epicId,r.branch,e.transientAuthority,e.authorizedWriteSet))throw new Error("direct-yolo-checkpoint-physical-invalid");if(e.physicalLockPath&&e.physicalLockOwner&&!await J(e.physicalLockPath,e.physicalLockOwner))throw new Error("direct-yolo-integration-lock-raced");if(o&&!(e.remotePolicy==="ancestor-recovery"?await Be(t,o,r.branch,r.headSha):await Oe(t,o,r.branch,r.headSha)))throw new Error("direct-yolo-checkpoint-remote-raced")}}),!i}async function Be(e,t,r,o){const i=se(t),n=(await p(e,["ls-remote","--heads",i,`refs/heads/${r}`])).split(/\s+/)[0];return!!(n&&await C(e,["merge-base","--is-ancestor",o,n]))}function ue(e,t,r){return!!(e?.ownerStoryId===t&&e.sessionId===e.idempotencyKey&&typeof e.idempotencyKey=="string"&&/^setup-[a-f0-9]{64}$/.test(e.idempotencyKey)&&typeof e.expiresAt=="string"&&Date.parse(e.expiresAt)>Date.parse(r))}async function _e(e,t){const r=await Xe(e),o=await Ye(r,"handoffs"),i=`direct-${j(t)}.json`;return{parent:o,name:i,path:he(o,i)}}async function ye(e,t){const r=await _e(e,t.storyId);await rt(r.parent,r.name,`${JSON.stringify(t,null,2)}
|
|
2
|
+
`),await De(r.path,r.parent)}async function F(e,t){try{const r=await _e(e,t);await De(r.path,r.parent);const o=JSON.parse(await oe(r.path,"utf8")),i=o.state==="issued"?["schemaVersion","kind","state","storyId","fromSessionId","token","tokenDigest","bundleDigest","claimRevision","grantDigest","expiresAt"]:o.state==="consuming"?["schemaVersion","kind","state","storyId","fromSessionId","token","tokenDigest","bundleDigest","claimRevision","grantDigest","expiresAt","consumedBySessionId","consumeStartedAt"]:["schemaVersion","kind","state","storyId","fromSessionId","tokenDigest","bundleDigest","claimRevision","grantDigest","expiresAt","consumedBySessionId","consumedAt"];return Object.keys(o).sort().join("\0")!==[...i].sort().join("\0")||o.schemaVersion!==1||o.kind!=="direct-yolo-setup-handoff-token"||o.state!=="issued"&&o.state!=="consuming"&&o.state!=="consumed"||o.storyId!==t||typeof o.fromSessionId!="string"||!/^setup-[a-f0-9]{64}$/.test(o.fromSessionId)||![o.tokenDigest,o.bundleDigest,o.claimRevision,o.grantDigest].every(n=>typeof n=="string"&&/^[a-f0-9]{64}$/.test(n))||typeof o.expiresAt!="string"||!Number.isFinite(Date.parse(o.expiresAt))||(o.state==="issued"||o.state==="consuming")&&(typeof o.token!="string"||!/^[A-Za-z0-9_-]{32,256}$/.test(o.token))||o.state==="consuming"&&(typeof o.consumedBySessionId!="string"||!/^[a-f0-9]{64}$/.test(o.consumedBySessionId)||typeof o.consumeStartedAt!="string"||!Number.isFinite(Date.parse(o.consumeStartedAt)))||o.state==="consumed"&&(typeof o.consumedBySessionId!="string"||!/^[a-f0-9]{64}$/.test(o.consumedBySessionId)||typeof o.consumedAt!="string"||!Number.isFinite(Date.parse(o.consumedAt)))?void 0:o}catch{return}}async function at(e,t,r,o,i){const n=await F(e,t);if(!(!n||n.state==="consumed"||!n.token||n.bundleDigest!==r||n.claimRevision!==o||Date.parse(n.expiresAt)<=Date.parse(i)||j(n.token)!==n.tokenDigest))return{sessionId:n.fromSessionId,token:n.token}}async function ct(e,t,r,o,i,n){const l=await F(e,t);if(!l||l.state==="consumed"||l.fromSessionId!==r||l.token!==o||l.tokenDigest!==j(o))throw new Error("direct-yolo-setup-handoff-consume-invalid");if(l.state==="consuming"){if(l.consumedBySessionId!==i)throw new Error("direct-yolo-setup-handoff-consume-raced");return}await ye(e,{...l,state:"consuming",consumedBySessionId:i,consumeStartedAt:n})}async function st(e,t,r,o,i,n,l,c,d){const a=await F(e,r);if(a?.state==="consumed"&&a.fromSessionId===o&&a.consumedBySessionId===c)return;const h=await q(e,{required:!0}),u=w(h.epics[t]?.branch_lease),f=w(u?.handoffConsumption);if(!a||a.state!=="consuming"||a.fromSessionId!==o||a.token!==i||a.tokenDigest!==j(i)||a.bundleDigest!==n||a.claimRevision!==l||a.consumedBySessionId!==c||u?.ownerStoryId!==r||u.sessionId!==c||f?.kind!=="direct-yolo-setup-handoff-consumption"||f.state!=="consumed"||f.fromSessionId!==o||f.tokenDigest!==a.tokenDigest||f.bundleDigest!==n||f.claimRevision!==l||f.consumedBySessionId!==c)throw new Error("direct-yolo-setup-handoff-consume-invalid");try{await ye(e,{schemaVersion:1,kind:a.kind,state:"consumed",storyId:r,fromSessionId:o,tokenDigest:a.tokenDigest,bundleDigest:a.bundleDigest,claimRevision:a.claimRevision,grantDigest:a.grantDigest,expiresAt:a.expiresAt,consumedBySessionId:c,consumedAt:d})}catch{throw new Error("direct-yolo-setup-handoff-consume-persist-failed")}}function dt(e){const t=w(e.current?.handoffGrant),r=e.handoff?.token,o=typeof r=="string"&&/^[A-Za-z0-9_-]{32,256}$/.test(r)?j(r):void 0;return!!(t&&o&&e.handoff&&e.handoff.sessionId===e.current?.sessionId&&t.schemaVersion===1&&t.kind==="direct-yolo-setup-handoff"&&t.storyId===e.storyId&&t.fromSessionId===e.current?.sessionId&&t.bundleDigest===e.bundleDigest&&t.claimRevision===e.claimRevision&&typeof t.expiresAt=="string"&&Date.parse(t.expiresAt)>Date.parse(e.nowIso)&&typeof t.tokenDigest=="string"&&/^[a-f0-9]{64}$/.test(t.tokenDigest)&&ht(t.tokenDigest,o))}function ht(e,t){const r=Buffer.from(e,"hex"),o=Buffer.from(t,"hex");return r.length===32&&o.length===32&&Ne(r,o)}function ce(e,t){return!!(e&&["schemaVersion","ownerStoryId","sessionId","idempotencyKey","acquiredAt","expiresAt"].every(r=>e[r]===t[r]))}function Le(e){const t=e??it;if(!Number.isSafeInteger(t)||t<100||t>14400*1e3)throw new Error("direct-yolo-writer-lease-duration-invalid");return t}function ft(e,t){const r=e??nt;if(!Number.isSafeInteger(r)||r<10||r*2>=t)throw new Error("direct-yolo-writer-heartbeat-interval-invalid");return r}async function He(e){const t=Date.parse(String(e.state.lease.expiresAt)),r=new Date(Math.max(Date.now()+e.leaseDurationMs,t+1)).toISOString(),o=await tt(e.state.physical.path,e.state.physical.owner,r);if(!o)throw new Error("direct-yolo-integration-lock-raced");const i={...e.state.lease,expiresAt:r};try{return{runtime:(await P(e.projectRoot,l=>{const c=W(l,e.epicId),d=w(c.branch_lease);if(!ce(d,e.state.lease))throw new Error("direct-yolo-runtime-revision-conflict");if(Date.parse(String(d?.expiresAt))<=Date.now())throw new Error("direct-yolo-writer-lease-expired");if(c.graph_revision!==e.graphRevision)throw new Error("direct-yolo-graph-revision-raced");c.branch_lease=i},{expectedRevision:e.state.runtime.revision,preCommit:async()=>{if(!await J(e.state.physical.path,o))throw new Error("direct-yolo-integration-lock-raced")}})).document,lease:i,physical:{path:e.state.physical.path,owner:o}}}catch(n){throw await G(e.state.physical.path,o).catch(()=>{}),n instanceof Error&&n.message==="git-lifecycle-runtime-revision-conflict"?new Error("direct-yolo-runtime-revision-conflict"):n instanceof Error&&/^direct-yolo-/.test(n.message)?n:new Error("direct-yolo-writer-heartbeat-failed")}}function lt(e){let t=e.state,r=!1,o,i,n=Promise.resolve();const l=()=>{r||o||(i=setTimeout(()=>{n=He({projectRoot:e.projectRoot,epicId:e.epicId,storyId:e.storyId,graphRevision:e.graphRevision,leaseDurationMs:e.leaseDurationMs,state:t}).then(c=>{t=c,e.onRenewed(c)}).catch(c=>{o=c}).finally(l)},e.heartbeatIntervalMs),i.unref())};return l(),{stop:async()=>{if(r=!0,i&&clearTimeout(i),await n,o)throw o}}}async function pe(e,t,r){await P(e,o=>{const i=W(o,t),n=w(i.branch_lease);ce(n,r)&&(i.branch_lease=null)})}async function ut(e,t){const r=await q(e.projectRoot,{required:!0}),o=w(r.epics[e.epicId]?.branch_lease);if(!o||o.ownerStoryId!==t||!Ce(o.sessionId)||!Ce(o.idempotencyKey)||!Number.isFinite(Date.parse(String(o.acquiredAt)))||!Number.isFinite(Date.parse(String(o.expiresAt))))return;const i=await V(e.projectRoot,{kind:"direct",storyId:t,sessionId:String(o.sessionId),idempotencyKey:String(o.idempotencyKey),createdAt:String(o.acquiredAt),expiresAt:String(o.expiresAt),persistent:!0});if(!i.ok)return;await G(i.path,i.owner)&&await pe(e.projectRoot,e.epicId,o)}async function ge(e,t,r,o){const i=await Je(t,{headSha:r,graphRevision:o,nowIso:e.nowIso});await e.qaRunner?.({projectRoot:t,storyId:e.storyId,headSha:r});const n=Ze(i);if(!n)throw new Error("p205-transient-authority-invalid");return{contract:"P205-CI-02",command:Ue,manifestDigest:n.manifestDigest,gateIds:n.gateIds,resultDigest:n.resultDigest,transientAuthority:i}}async function we(e,t,r,o){return await p(e,["rev-parse","HEAD"])!==r||await p(e,["symbolic-ref","--quiet","--short","HEAD"])!==t||!await C(e,["diff","--cached","--quiet"])?!1:C(e,["diff","--quiet","HEAD","--",...o])}async function Oe(e,t,r,o){const i=se(t);return(await p(e,["ls-remote","--heads",i,`refs/heads/${r}`])).split(/\s+/)[0]===o}function Q(e,t,r,o){if(e.length===0||e.some(n=>!me(n)))return{ok:!1,reasonCode:"direct-yolo-write-set-invalid"};const i=[".neocortex/state.json",`docs/stories/${r}.story.md`,`.neocortex/stories/${r}/qa-gate-result.json`,`.neocortex/stories/${r}/validation-evidence.md`,`.neocortex/stories/${r}/review.md`];return!i.every(n=>e.includes(n))||!i.every(n=>t.includes(n))?{ok:!1,reasonCode:"direct-yolo-write-set-invalid"}:o&&(o.storyId!==r||o.childClaimRevision!==j([...t].sort().join("\0")))?{ok:!1,reasonCode:"direct-yolo-root-memory-claim-mismatch"}:e.some(n=>!t.includes(n)&&!o?.files.some(l=>l.path===n))?{ok:!1,reasonCode:"direct-yolo-write-set-unauthorized"}:{ok:!0}}function me(e){return e.length>0&&e.length<=1024&&!e.startsWith("/")&&!e.includes("\\")&&!e.split("/").includes("..")&&!e.startsWith(".git/")&&!e.includes("\0")}function Ce(e){return typeof e=="string"&&e.length>0&&e.length<=512&&/^[A-Za-z0-9._:@/+\-=]+$/.test(e)}function qe(e){return e.length>0&&e.length<=240&&!e.startsWith("-")&&!/[\s~^:?*[\\]/.test(e)&&!e.includes("..")}function se(e){if(!/^[A-Za-z0-9._-]{1,128}$/.test(e))throw new Error("direct-yolo-remote-invalid");return e}function U(e,t){const r=`${t}: `,o=e.split(`
|
|
3
|
+
`).map(i=>i.trim()).filter(i=>i.startsWith(r)).map(i=>i.slice(r.length));return o.length===1?o[0]:void 0}function j(e){return ze("sha256").update(e).digest("hex")}function $(e){return e.split("\0").filter(Boolean)}function T(e){return e&&Number.isFinite(Date.parse(e))?new Date(Date.parse(e)).toISOString():new Date().toISOString()}function w(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:void 0}function Ie(e,t,r){const o=w(e);if(!(!o||o.schemaVersion!==1||o.originBranch!==r||o.executionBranch!==t||o.capturedFromCurrentCheckout!==!0||typeof o.originHeadSha!="string"||!/^[a-f0-9]{40,64}$/.test(o.originHeadSha)||typeof o.capturedAt!="string"||!Number.isFinite(Date.parse(o.capturedAt))))return o}function ve(e,t,r,o){return Object.freeze({schemaVersion:1,kind:"direct-yolo-setup-receipt",storyId:e.storyId,epicId:e.epicId,executionBranch:e.executionBranch,originBranch:e.originBranch,originHeadSha:t.originHeadSha,leaseExpiresAt:r,reused:o,publicSafe:!0})}async function X(e){const t=$(await E(e,["ls-files","--others","--exclude-standard","-z"])).sort(),r=await Promise.all(t.map(async o=>{if(!me(o))throw new Error("direct-yolo-checkout-payload-invalid");return`${o}\0${await p(e,["hash-object","--no-filters","--",o])}`}));return j([await E(e,["diff","--cached","--binary","--full-index"]),await E(e,["diff","--binary","--full-index"]),await E(e,["status","--porcelain=v1","-z","--untracked-files=all"]),...r].join("\0"))}async function Bt(e){const t=ie(e),r=await p(t,["rev-parse","HEAD"]),o=await p(t,["symbolic-ref","--quiet","--short","HEAD"]),i=await X(t);if(await p(t,["rev-parse","HEAD"])!==r||await p(t,["symbolic-ref","--quiet","--short","HEAD"])!==o)throw new Error("direct-yolo-checkout-observation-raced");return Object.freeze({headSha:r,branch:o,payloadDigest:i})}async function Pe(e){const t=[];let r;for(const o of(await E(e,["worktree","list","--porcelain"])).split(`
|
|
4
|
+
`))o.startsWith("worktree ")?(r={path:o.slice(9)},t.push(r)):r&&o.startsWith("branch refs/heads/")&&(r.branch=o.slice(18));return t}function ee(e,t){return e instanceof Error&&e.message==="git-lifecycle-runtime-revision-conflict"?"direct-yolo-runtime-revision-conflict":e instanceof Error&&/^direct-yolo-[a-z0-9-]+$/.test(e.message)?e.message:t}function s(e){return{ok:!1,reasonCode:e}}async function p(e,t){return String((await le("git",[...t],{cwd:e,encoding:"utf8",maxBuffer:32*1024*1024})).stdout).trim()}async function E(e,t){return String((await le("git",[...t],{cwd:e,encoding:"utf8",maxBuffer:32*1024*1024})).stdout)}async function C(e,t){try{return await le("git",[...t],{cwd:e,maxBuffer:8*1024*1024}),!0}catch{return!1}}export{bt as acceptDirectYoloSetupCheckpoint,jt as beginDirectYoloStoryCommit,Bt as captureDirectYoloCheckoutEvidence,Et as finalizeDirectYoloStoryCheckpoint,kt as issueDirectYoloSetupLeaseHandoff,Dt as prepareDirectYoloSetup,At as recoverLegacyDirectYoloStoryCheckpoint};
|
|
@@ -277,6 +277,8 @@ export declare function acquireGitLifecyclePhysicalIntegrationLock(projectRoot:
|
|
|
277
277
|
readonly ownerNonce?: string;
|
|
278
278
|
}): Promise<GitLifecyclePhysicalIntegrationLockResult>;
|
|
279
279
|
export declare function verifyGitLifecyclePhysicalIntegrationLock(path: string, expected: GitLifecyclePhysicalIntegrationLockOwner): Promise<boolean>;
|
|
280
|
+
/** Extend only the exact live physical owner through an anchored file CAS. */
|
|
281
|
+
export declare function renewGitLifecyclePhysicalIntegrationLock(path: string, expected: GitLifecyclePhysicalIntegrationLockOwner, expiresAtInput: string): Promise<GitLifecyclePhysicalIntegrationLockOwner | undefined>;
|
|
280
282
|
export declare function releaseGitLifecyclePhysicalIntegrationLock(path: string, expected: GitLifecyclePhysicalIntegrationLockOwner): Promise<boolean>;
|
|
281
283
|
export declare function computeGitLifecyclePhysicalIntegrationLockOwnerDigest(owner: GitLifecyclePhysicalIntegrationLockOwner): string;
|
|
282
284
|
/** Recover only the exact persistent lock whose digest was bound to a checkpoint. */
|