@ornexus/neocortex 4.60.58 → 4.60.60
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/sbom.cdx.json +241 -82
- package/install.ps1 +1 -1
- package/install.sh +1 -1
- package/package.json +6 -2
- package/packages/client/dist/cli.js +37 -4
- package/packages/client/dist/commands/architecture-answers.d.ts +26 -0
- package/packages/client/dist/commands/architecture-answers.js +7 -0
- package/packages/client/dist/commands/architecture-memory-terminal.d.ts +21 -0
- package/packages/client/dist/commands/architecture-memory-terminal.js +2 -0
- package/packages/client/dist/commands/architecture-root-binding.d.ts +2 -0
- package/packages/client/dist/commands/architecture-root-binding.js +1 -0
- package/packages/client/dist/commands/invoke.d.ts +43 -2
- package/packages/client/dist/commands/invoke.js +98 -70
- package/packages/client/dist/commands/legacy-story-branch.d.ts +10 -0
- package/packages/client/dist/commands/legacy-story-branch.js +1 -0
- package/packages/client/dist/commands/legacy-story-pr.d.ts +18 -0
- package/packages/client/dist/commands/legacy-story-pr.js +1 -0
- package/packages/client/dist/commands/planning-diagnosis.d.ts +4 -0
- package/packages/client/dist/commands/planning-diagnosis.js +1 -0
- package/packages/client/dist/commands/planning-generation.d.ts +2 -0
- package/packages/client/dist/commands/planning-generation.js +1 -0
- package/packages/client/dist/commands/planning-research.d.ts +3 -0
- package/packages/client/dist/commands/planning-research.js +1 -0
- package/packages/client/dist/commands/refresh-memory.d.ts +10 -0
- package/packages/client/dist/commands/refresh-memory.js +3 -1
- package/packages/client/dist/commands/story-checkpoint.d.ts +1 -1
- package/packages/client/dist/commands/story-checkpoint.js +1 -1
- package/packages/client/dist/config/profile-directory.d.ts +2 -0
- package/packages/client/dist/config/profile-directory.js +1 -0
- package/packages/client/dist/config/secure-config.js +5 -5
- package/packages/client/dist/continuity/runner-bootstrap-policy.d.ts +1 -1
- package/packages/client/dist/continuity/runner-bootstrap-policy.js +1 -1
- package/packages/client/dist/generated/command-registry.generated.d.ts +11 -11
- package/packages/client/dist/generated/command-registry.generated.js +1 -1
- package/packages/client/dist/generated/public-projections.generated.d.ts +20 -20
- package/packages/client/dist/generated/public-projections.generated.js +1 -1
- package/packages/client/dist/git/direct-yolo-checkpoint.d.ts +9 -0
- package/packages/client/dist/git/direct-yolo-checkpoint.js +4 -4
- package/packages/client/dist/git/git-lifecycle-step-ids.d.ts +5 -0
- package/packages/client/dist/git/git-lifecycle-step-ids.js +1 -1
- package/packages/client/dist/git/git-lifecycle-store.d.ts +16 -0
- package/packages/client/dist/git/git-lifecycle-store.js +9 -4
- package/packages/client/dist/git/legacy-story-branch-checkpoint.d.ts +38 -0
- package/packages/client/dist/git/legacy-story-branch-checkpoint.js +9 -0
- package/packages/client/dist/git/legacy-story-branch-setup.d.ts +56 -0
- package/packages/client/dist/git/legacy-story-branch-setup.js +4 -0
- package/packages/client/dist/git/legacy-story-pr.d.ts +514 -0
- package/packages/client/dist/git/legacy-story-pr.js +62 -0
- package/packages/client/dist/git/secure-filesystem-boundary.d.ts +2 -0
- package/packages/client/dist/git/secure-filesystem-boundary.js +34 -7
- package/packages/client/dist/machine/fingerprint.js +2 -2
- package/packages/client/dist/memory/project-memory-writer.js +17 -17
- package/packages/client/dist/memory/shared-project-memory-types.d.ts +23 -13
- package/packages/client/dist/memory/shared-project-memory-types.js +2 -2
- package/packages/client/dist/migrations/state-json.d.ts +23 -1
- package/packages/client/dist/migrations/state-json.js +4 -4
- package/packages/client/dist/private-execution/delivery.d.ts +131 -3
- package/packages/client/dist/private-execution/delivery.js +2 -2
- package/packages/client/dist/private-execution/isolated-admission.d.ts +28 -1
- package/packages/client/dist/private-execution/isolated-admission.js +11 -2
- package/packages/client/dist/private-execution/isolated-session.js +2 -2
- package/packages/client/dist/private-execution/isolated-workspace.d.ts +8 -0
- package/packages/client/dist/private-execution/isolated-workspace.js +1 -1
- package/packages/client/dist/private-execution/pact-consumer-runtime.d.ts +19 -0
- package/packages/client/dist/private-execution/pact-consumer-runtime.js +3 -0
- package/packages/client/dist/private-execution/pact-test-source.d.ts +9 -0
- package/packages/client/dist/private-execution/pact-test-source.js +1 -0
- package/packages/client/dist/private-execution/pact-toolchain.d.ts +37 -0
- package/packages/client/dist/private-execution/pact-toolchain.js +3 -0
- package/packages/client/dist/private-execution/pact-write-set.d.ts +24 -0
- package/packages/client/dist/private-execution/pact-write-set.js +1 -0
- package/packages/client/dist/private-execution/planning-diagnosis-checkpoint.d.ts +38 -0
- package/packages/client/dist/private-execution/planning-diagnosis-checkpoint.js +5 -0
- package/packages/client/dist/private-execution/planning-generation-checkpoint.d.ts +34 -0
- package/packages/client/dist/private-execution/planning-generation-checkpoint.js +4 -0
- package/packages/client/dist/private-execution/planning-research-checkpoint.d.ts +38 -0
- package/packages/client/dist/private-execution/planning-research-checkpoint.js +4 -0
- package/packages/client/dist/private-execution/ux-source-validation.d.ts +2 -0
- package/packages/client/dist/private-execution/ux-source-validation.js +1 -0
- package/packages/client/dist/private-execution/ux-write-set.d.ts +30 -0
- package/packages/client/dist/private-execution/ux-write-set.js +2 -0
- package/packages/client/dist/resolvers/remote-resolver.d.ts +5 -22
- package/packages/client/dist/resolvers/remote-resolver.js +1 -1
- package/packages/client/dist/runner/project-identity.js +1 -1
- package/packages/client/dist/runner/scheduler.d.ts +20 -0
- package/packages/client/dist/runner/scheduler.js +7 -7
- package/packages/client/dist/state/project-state-snapshot.js +1 -1
- package/packages/client/dist/yolo/change-evidence-collector.d.ts +8 -0
- package/packages/client/dist/yolo/change-evidence-collector.js +1 -1
- package/packages/client/dist/yolo/spec-envelope-collector.d.ts +2 -0
- package/packages/client/dist/yolo/spec-envelope-collector.js +3 -3
- package/packages/client/dist/yoloop/invoke-hooks.js +7 -7
- package/packages/client/dist/yoloop/shared-yoloop-types.d.ts +15 -1
- package/packages/client/dist/yoloop/yoloop-client-state-store.d.ts +5 -1
- package/packages/client/dist/yoloop/yoloop-client-state-store.js +1 -1
- package/packages/shared/dist/generated/command-registry.generated.js +12 -10
- package/packages/shared/dist/generated/invocation-schema.generated.js +14 -6
- package/packages/shared/dist/generated/public-projections.generated.js +18 -18
- package/packages/shared/dist/invocation/index.d.ts +1 -1
- package/packages/shared/dist/merge-readiness/c12-remote-observation.js +80 -0
- package/packages/shared/dist/planning/diagnosis-state.js +143 -0
- package/packages/shared/dist/yoloop/branch-unit.js +23 -1
- package/targets-stubs/antigravity/gemini.md +1 -1
- package/targets-stubs/antigravity/skill/SKILL.md +1 -1
- package/targets-stubs/claude-code/neocortex-root.agent.yaml +1 -1
- package/targets-stubs/claude-code/neocortex-root.md +2 -2
- package/targets-stubs/claude-code/neocortex.agent.yaml +1 -1
- package/targets-stubs/claude-code/neocortex.md +2 -2
- package/targets-stubs/codex/AGENTS.md +1 -1
- package/targets-stubs/cursor/agent.md +2 -2
- package/targets-stubs/gemini-cli/agent.md +2 -2
- package/targets-stubs/opencode/neocortex-root.md +1 -1
- package/targets-stubs/vscode/neocortex.agent.md +2 -2
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import{execFileSync as K}from"node:child_process";import{createHash as Pe,randomBytes as U}from"node:crypto";import{closeSync as rt,constants as Re,existsSync as D,fstatSync as at,lstatSync as Z,mkdirSync as st,mkdtempSync as ot,openSync as nt,readFileSync as it,realpathSync as E,rmdirSync as ct,unlinkSync as yt,writeFileSync as dt}from"node:fs";import{tmpdir as lt}from"node:os";import{isAbsolute as Ce,join as N}from"node:path";import{parseDocument as X}from"yaml";import{summarizeC12RemoteRollup as qe}from"../../../shared/dist/merge-readiness/c12-remote-observation.js";import{resolveBranchUnit as je}from"../../../shared/dist/yoloop/branch-unit.js";import{acquireGitLifecyclePhysicalIntegrationLock as ee,assertGitLifecyclePrivateDirectory as ze,assertGitLifecyclePrivateFile as J,ensureGitLifecyclePrivateChildDirectory as W,gitLifecycleRuntimeDirectory as F,releaseGitLifecyclePhysicalIntegrationLock as te}from"./git-lifecycle-store.js";import{anchoredAtomicWriteFile as z,anchoredCompareAndSwapFile as G}from"./secure-filesystem-boundary.js";import{GIT_LIFECYCLE_CREATE_PR_STEP_ID as Q,GIT_LIFECYCLE_MERGE_PR_STEP_ID as ge,GIT_LIFECYCLE_REVIEW_PR_STEP_ID as Y,GIT_LIFECYCLE_COMMIT_PUSH_STEP_ID as T,GIT_LIFECYCLE_SYNC_MAIN_STEP_ID as V,GIT_LIFECYCLE_UPDATE_PROJECT_MEMORY_STEP_ID as ye}from"./git-lifecycle-step-ids.js";import{executeP205TransientAuthority as Le,projectP205TransientExecutionEvidence as Ve}from"./git-lifecycle-store.js";import{readCompletedLegacyStoryBranchPlan as ht}from"./legacy-story-branch-setup.js";function i(t){return{ok:!1,reasonCode:t}}function m(t){return t&&typeof t=="object"&&!Array.isArray(t)?t:null}function u(t,...r){return K("git",r,{cwd:t,encoding:"utf8",timeout:15e3,stdio:["ignore","pipe","pipe"],maxBuffer:2*1024*1024}).trim()}function w(t,...r){return K("git",r,{cwd:t,encoding:"utf8",timeout:15e3,stdio:["ignore","pipe","pipe"],maxBuffer:2*1024*1024})}function B(t,r){const a=nt(t,Re.O_RDONLY|(Re.O_NOFOLLOW??0));try{const e=at(a);if(!e.isFile()||e.size>r)throw new Error("legacy-story-pr-file-unsafe");return it(a,"utf8")}finally{rt(a)}}function R(t,r){const a=u(t,"ls-remote","--heads","origin",`refs/heads/${r}`).split(`
|
|
2
|
+
`).filter(Boolean);if(a.length!==1)throw new Error("legacy-story-pr-remote-ref-missing");const e=a[0].match(/^([a-f0-9]{40})\s+refs\/heads\/(.+)$/);if(!e||e[2]!==r)throw new Error("legacy-story-pr-remote-ref-invalid");return e[1]}function re(t){const a=u(t,"config","--get","remote.origin.url").match(/^(?:https:\/\/github\.com\/|git@github\.com:)([A-Za-z0-9_.-]+)\/([A-Za-z0-9_.-]+?)(?:\.git)?$/);if(!a||a[1].includes("..")||a[2].includes(".."))throw new Error("legacy-story-pr-repository-invalid");return`${a[1]}/${a[2]}`}function Ie(t){const r=u(t,"rev-parse","--git-common-dir");return E(Ce(r)?r:N(t,r))}function de(t,r){if(!Array.isArray(r)||r.length>=100)throw new Error("legacy-story-pr-list-incomplete");const a=r.filter(o=>o.headRefName===t.branch);if(a.length>1||a.some(o=>o.state!=="OPEN"||o.baseRefName!==t.baseBranch||o.headRefOid!==t.headSha))throw new Error("legacy-story-pr-provider-conflict");const e=a[0];if(!e)return null;if(!Number.isSafeInteger(e.number)||e.number<=0||e.url.toLowerCase()!==`https://github.com/${t.repository}/pull/${e.number}`.toLowerCase())throw new Error("legacy-story-pr-provider-invalid");return e}async function ft(t,r){const a=await W(await F(t),"legacy-story-pr-intents"),e=`${Pe("sha256").update(r.storyId).digest("hex")}.json`,o=N(a,e),c={schemaVersion:1,kind:"legacy-story-pr-create-attempt",storyId:r.storyId,epicId:r.epicId,repository:r.repository,branch:r.branch,baseBranch:r.baseBranch,headSha:r.headSha};if(D(o)){if(await J(o,a),B(o,4096)!==`${JSON.stringify(c)}
|
|
3
|
+
`)throw new Error("legacy-story-pr-attempt-conflict");return!1}return await z(a,e,`${JSON.stringify(c)}
|
|
4
|
+
`),await J(o,a),!0}function pt(t){if(!/^[A-Za-z0-9][A-Za-z0-9_-]*\.[A-Za-z0-9._-]+$/.test(t.storyId))return i("legacy-story-commit-target-invalid");try{const r=E(t.projectRoot);if(E(u(r,"rev-parse","--show-toplevel"))!==r||w(r,"diff","--name-only","-z")!==""||w(r,"ls-files","--others","--exclude-standard","-z")!=="")return i("legacy-story-commit-checkout-invalid");const a=w(r,"diff","--cached","--name-only","-z").split("\0").filter(Boolean);if(a.length===0||new Set(a).size!==a.length||a.some(_=>_.length>1024||_.startsWith("/")||_.includes("\\")||_.includes("\0")||_.split("/").includes("..")||_===".git"||_.startsWith(".git/")))return i("legacy-story-commit-write-set-invalid");if(w(r,"ls-files","-u","-z")!==""||a.some(_=>{const M=w(r,"ls-files","-s","-z","--",_).split("\0").filter(Boolean);return M.length>1||M.some(ce=>{const ue=ce.match(/^(100644|100755) [a-f0-9]{40} 0\t(.+)$/);return!ue||ue[2]!==_})}))return i("legacy-story-commit-index-unsafe");u(r,"diff","--cached","--check");const e=w(r,"show",":.neocortex/state.json"),o=`docs/stories/${t.storyId}.story.md`,c=w(r,"show",`:${o}`);if(B(N(r,".neocortex/state.json"),2*1024*1024)!==e||B(N(r,o),2*1024*1024)!==c)return i("legacy-story-commit-preimage-drift");const h=m(JSON.parse(e)),l=m(h?.stories),y=m(l?.[t.storyId]),s=y?.epic_id,d=typeof s=="string"?m(m(h?.epics)?.[s]):null,n=d?.stories;if(!y||y.id!==t.storyId||typeof s!="string"||!d||d.id!==s||d.branch_mode==="epic"||y.status!=="memory-updated"||y.last_step!==ye||!Array.isArray(y.steps_completed)||!y.steps_completed.includes(ye)||y.steps_completed.includes(T)||!Number.isSafeInteger(y.issue_number)||y.issue_number<=0||!Array.isArray(n)||n.length===0||new Set(n).size!==n.length||!n.includes(t.storyId)||n.some(_=>typeof _!="string"||m(l?.[_])?.epic_id!==s)||Object.entries(l??{}).some(([_,M])=>m(M)?.epic_id===s&&!n.includes(_)))return i("legacy-story-commit-state-invalid");const I=je(d,n.map(_=>({...m(l?.[_]),id:_}))),b=`story/${s}/${t.storyId}`,f=m(h?.config)?.default_branch;if(I.mode!=="story"||y.branch_name!==b||u(r,"branch","--show-current")!==b||typeof f!="string"||f===b||u(r,"check-ref-format","--branch",f)!==f)return i("legacy-story-commit-branch-invalid");const k=m(JSON.parse(w(r,"show","HEAD:.neocortex/state.json"))),g=m(m(k?.stories)?.[t.storyId]),$=Array.isArray(g?.files_to_modify)?g.files_to_modify:null;if(!$||$.length===0||new Set($).size!==$.length||g?.epic_id!==s||JSON.stringify(y.files_to_modify)!==JSON.stringify($)||$.some(_=>typeof _!="string"||_.length>1024||_.startsWith("/")||_.includes("\\")||_.split("/").includes("..")||_===".git"||_.startsWith(".git/"))||!a.every(_=>$.includes(_))||!a.includes(".neocortex/state.json")||!a.includes(o)||!$.includes(".neocortex/state.json")||!$.includes(o))return i("legacy-story-commit-write-set-unauthorized");const A=c.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n/);if(!A)return i("legacy-story-commit-frontmatter-invalid");const v=X(A[1],{strict:!0,uniqueKeys:!0}),C=m(v.toJS()),S=["stepsCompleted","steps_completed"].filter(_=>v.has(_)),O=["lastStep","last_step"].filter(_=>v.has(_)),j=["branchName","branch_name"].filter(_=>v.has(_)),H=["issueNumber","issue_number"].filter(_=>v.has(_));if(v.errors.length>0||v.get("id")!==t.storyId||(v.get("epic_id")??v.get("epic"))!==s||v.get("status")!=="memory-updated"||v.has("currentStatus")&&v.get("currentStatus")!=="memory-updated"||S.length!==1||O.length!==1||j.length!==1||H.length!==1||JSON.stringify(C?.[S[0]])!==JSON.stringify(y.steps_completed)||C?.[O[0]]!==ye||C?.[j[0]]!==b||C?.[H[0]]!==y.issue_number)return i("legacy-story-commit-frontmatter-invalid");const x=u(r,"rev-parse","HEAD"),q=u(r,"ls-remote","--heads","origin",`refs/heads/${b}`).split(`
|
|
5
|
+
`).filter(Boolean),L=R(r,f);return!/^[a-f0-9]{40}$/.test(x)||q.length!==0||u(r,"rev-parse",`refs/remotes/origin/${f}`)!==L?i("legacy-story-commit-remote-drift"):{ok:!0,value:Object.freeze({schemaVersion:1,kind:"legacy-story-c08-commit-plan",storyId:t.storyId,epicId:s,repository:re(r),branch:b,baseBranch:f,headSha:x,remoteHeadSha:null,baseSha:L,indexDigestSha256:p(w(r,"ls-files","-s","-z")),stagedPatchSha256:p(w(r,"diff","--cached","--binary","--full-index")),changedPaths:Object.freeze(a),stateSha256:p(e),storySha256:p(c),stateIndexBlobSha:u(r,"rev-parse",":.neocortex/state.json"),storyIndexBlobSha:u(r,"rev-parse",`:${o}`),physicalCommit:!1,checkpointAccepted:!1,localOnly:!0})}}catch{return i("legacy-story-commit-physical-unavailable")}}function Me(t,r){const a=w(t,"show",r.stateIndexBlobSha),e=w(t,"show",r.storyIndexBlobSha);if(u(t,"cat-file","-t",r.stateIndexBlobSha)!=="blob"||u(t,"cat-file","-t",r.storyIndexBlobSha)!=="blob"||p(a)!==r.stateSha256||p(e)!==r.storySha256)throw new Error("legacy-story-commit-preimage-invalid");const o=m(JSON.parse(a)),c=m(m(o?.stories)?.[r.storyId]);if(!c||c.epic_id!==r.epicId||c.status!=="memory-updated"||c.last_step!==ye||!Array.isArray(c.steps_completed)||!c.steps_completed.includes(ye)||c.steps_completed.includes(T))throw new Error("legacy-story-commit-projection-state-invalid");const h=c.steps_completed;c.status="committed",c.last_step=T,c.steps_completed=[...h,T];const l=`${JSON.stringify(o,null,2)}
|
|
6
|
+
`,y=e.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n/);if(!y)throw new Error("legacy-story-commit-projection-frontmatter-invalid");const s=X(y[1],{strict:!0,uniqueKeys:!0}),d=m(s.toJS()),n=["stepsCompleted","steps_completed"].filter(f=>s.has(f)),I=["lastStep","last_step"].filter(f=>s.has(f));if(s.errors.length>0||s.get("id")!==r.storyId||(s.get("epic_id")??s.get("epic"))!==r.epicId||s.get("status")!=="memory-updated"||n.length!==1||I.length!==1||JSON.stringify(d?.[n[0]])!==JSON.stringify(h)||d?.[I[0]]!==ye)throw new Error("legacy-story-commit-projection-frontmatter-invalid");s.set("status","committed"),s.has("currentStatus")&&s.set("currentStatus","committed"),s.set(n[0],c.steps_completed),s.set(I[0],T);const b=`---
|
|
7
|
+
${s.toString({lineWidth:0})}---
|
|
8
|
+
${e.slice(y[0].length)}`;return{stateBefore:a,storyBefore:e,stateAfter:l,storyAfter:b}}async function Ke(t,r,a){if(a)return a();const e=await ht({projectRoot:t,storyId:r.storyId});if(!e.ok||e.value.epicId!==r.epicId||e.value.branch!==r.branch||e.value.baseBranch!==r.baseBranch||e.value.worktreePath!==t)return!1;try{u(t,"merge-base","--is-ancestor",e.value.baseHeadSha,r.headSha)}catch{return!1}const o=await W(await F(t),"legacy-story-branch-intents"),c=N(o,`${p(r.storyId)}.c01.accepted.json`);if(!D(c))return!1;await J(c,o);const h=m(JSON.parse(B(c,4096))),l=m(JSON.parse(w(t,"show",r.stateIndexBlobSha))),y=m(m(l?.stories)?.[r.storyId]);return!!h&&h.schemaVersion===1&&h.kind==="legacy-story-c01-acceptance-intent"&&h.storyId===r.storyId&&h.planDigest===p(JSON.stringify(e.value))&&h.repository===r.repository&&h.issueNumber===y?.issue_number}function Be(t,r){return r.changedPaths.filter(a=>a!==".neocortex/state.json"&&a!==`docs/stories/${r.storyId}.story.md`).map(a=>{const e=w(t,"ls-files","-s","-z","--",a).split("\0").filter(Boolean);if(e.length>1)throw new Error("legacy-story-commit-index-invalid");return{path:a,entry:e[0]??null}})}async function qt(t){if(!t.authorize)return i("legacy-story-commit-authorization-required");if(!/^[A-Za-z0-9][A-Za-z0-9_-]*\.[A-Za-z0-9._-]+$/.test(t.storyId))return i("legacy-story-commit-target-invalid");const r=`legacy-c08-${U(16).toString("hex")}`,a=await ee(t.projectRoot,{kind:"direct",storyId:t.storyId,sessionId:r,idempotencyKey:r,expiresAt:new Date(Date.now()+60*6e4).toISOString(),persistent:!1});if(!a.ok)return i(a.reasonCode);try{const e=E(t.projectRoot);if(E(u(e,"rev-parse","--show-toplevel"))!==e)return i("legacy-story-commit-checkout-invalid");const o=await W(await F(e),"legacy-story-pr-intents"),c=p(t.storyId),h=`${c}.c08.commit.json`,l=`${c}.c08.commit.accepted.json`;let y=await me(o,h,64*1024);if(!y){const S=pt(t);if(!S.ok)return S;const O=S.value;if(!await Ke(e,O,t.verifyC01))return i("legacy-story-commit-c01-unverified");const j=Me(e,O),H={schemaVersion:1,kind:"legacy-story-c08-commit-intent",plan:O,stateAfterSha256:p(j.stateAfter),storyAfterSha256:p(j.storyAfter),otherIndex:Be(e,O)};await z(o,h,`${JSON.stringify(H)}
|
|
9
|
+
`),await J(N(o,h),o),y=H}const s=m(y.plan);if(y.schemaVersion!==1||y.kind!=="legacy-story-c08-commit-intent"||!s||s.schemaVersion!==1||s.kind!=="legacy-story-c08-commit-plan"||s.storyId!==t.storyId||typeof s.epicId!="string"||s.branch!==`story/${s.epicId}/${t.storyId}`||typeof s.repository!="string"||typeof s.baseBranch!="string"||typeof s.headSha!="string"||!/^[a-f0-9]{40}$/.test(s.headSha)||typeof s.stateIndexBlobSha!="string"||!/^[a-f0-9]{40}$/.test(s.stateIndexBlobSha)||typeof s.storyIndexBlobSha!="string"||!/^[a-f0-9]{40}$/.test(s.storyIndexBlobSha)||!Array.isArray(s.changedPaths)||!s.changedPaths.includes(".neocortex/state.json")||!s.changedPaths.includes(`docs/stories/${t.storyId}.story.md`)||s.remoteHeadSha!==null||s.physicalCommit!==!1||s.checkpointAccepted!==!1||typeof y.stateAfterSha256!="string"||!/^[a-f0-9]{64}$/.test(y.stateAfterSha256)||typeof y.storyAfterSha256!="string"||!/^[a-f0-9]{64}$/.test(y.storyAfterSha256)||!Array.isArray(y.otherIndex)||y.otherIndex.length!==s.changedPaths.length-2||y.otherIndex.some(S=>{const O=m(S);return!O||typeof O.path!="string"||!s.changedPaths.includes(O.path)||O.path===".neocortex/state.json"||O.path===`docs/stories/${t.storyId}.story.md`||O.entry!==null&&(typeof O.entry!="string"||!/^(100644|100755) [a-f0-9]{40} 0\t/.test(O.entry)||!O.entry.endsWith(` ${O.path}`))})||!/^[a-f0-9]{64}$/.test(String(s.indexDigestSha256))||!/^[a-f0-9]{64}$/.test(String(s.stagedPatchSha256))||!/^[a-f0-9]{64}$/.test(String(s.stateSha256))||!/^[a-f0-9]{64}$/.test(String(s.storySha256))||new Set(s.changedPaths).size!==s.changedPaths.length||s.changedPaths.some(S=>typeof S!="string"||S.length>1024||S.startsWith("/")||S.includes("\\")||S.split("/").includes("..")||S===".git"||S.startsWith(".git/"))||re(e)!==s.repository||u(e,"branch","--show-current")!==s.branch)return i("legacy-story-commit-intent-invalid");const d=s;if(!await Ke(e,d,t.verifyC01))return i("legacy-story-commit-c01-unverified");const n=Me(e,d);if(p(n.stateAfter)!==y.stateAfterSha256||p(n.storyAfter)!==y.storyAfterSha256||JSON.stringify(Be(e,d))!==JSON.stringify(y.otherIndex))return i("legacy-story-commit-intent-drift");const I=p(JSON.stringify(y)),f=await me(o,l,4096);if(f&&(f.schemaVersion!==1||f.kind!=="legacy-story-c08-commit-accepted"||f.intentSha256!==I||!/^[a-f0-9]{40}$/.test(f.checkpointHeadSha)||!/^[a-f0-9]{64}$/.test(f.qaSha256)))return i("legacy-story-commit-accepted-invalid");let k=u(e,"rev-parse","HEAD");if(k===d.headSha){if(f)return i("legacy-story-commit-accepted-physical-drift");const S=w(e,"diff","--cached","--name-only","-z").split("\0").filter(Boolean),O=w(e,"diff","--name-only","-z").split("\0").filter(Boolean);if(JSON.stringify(S)!==JSON.stringify(d.changedPaths)||O.some(L=>L!==".neocortex/state.json"&&L!==`docs/stories/${d.storyId}.story.md`)||w(e,"ls-files","--others","--exclude-standard","-z")!==""||u(e,"ls-remote","--heads","origin",`refs/heads/${d.branch}`)!==""||R(e,d.baseBranch)!==d.baseSha)return i("legacy-story-commit-precommit-drift");const j=B(N(e,".neocortex/state.json"),2*1024*1024),H=B(N(e,`docs/stories/${d.storyId}.story.md`),2*1024*1024),x=w(e,"show",":.neocortex/state.json"),q=w(e,"show",`:docs/stories/${d.storyId}.story.md`);if(![n.stateBefore,n.stateAfter].includes(j)||![n.storyBefore,n.storyAfter].includes(H)||![n.stateBefore,n.stateAfter].includes(x)||![n.storyBefore,n.storyAfter].includes(q)||x===n.stateAfter&&j!==n.stateAfter||q===n.storyAfter&&H!==n.storyAfter)return i("legacy-story-commit-preimage-drift");if(j===n.stateBefore&&(await G(N(e,".neocortex"),"state.json",n.stateAfter,p(n.stateBefore)),await t.afterStateWrite?.()),H===n.storyBefore&&await G(N(e,"docs/stories"),`${d.storyId}.story.md`,n.storyAfter,p(n.storyBefore)),B(N(e,".neocortex/state.json"),2*1024*1024)!==n.stateAfter||B(N(e,`docs/stories/${d.storyId}.story.md`),2*1024*1024)!==n.storyAfter)return i("legacy-story-commit-projection-drift");if(u(e,"add","--",".neocortex/state.json",`docs/stories/${d.storyId}.story.md`),u(e,"diff","--cached","--check"),w(e,"diff","--name-only","-z")!==""||w(e,"ls-files","--others","--exclude-standard","-z")!==""||JSON.stringify(Be(e,d))!==JSON.stringify(y.otherIndex)||p(w(e,"show",":.neocortex/state.json"))!==y.stateAfterSha256||p(w(e,"show",`:docs/stories/${d.storyId}.story.md`))!==y.storyAfterSha256)return i("legacy-story-commit-index-drift");u(e,"commit","-m",`chore(story): checkpoint ${d.storyId} C08`,"-m",`Neocortex-Legacy-Commit: ${d.storyId}`),k=u(e,"rev-parse","HEAD"),await t.afterCommit?.()}const g=u(e,"rev-list","--parents","-n","1",k).split(" "),$=w(e,"diff-tree","--no-commit-id","--name-only","-r","-z",k).split("\0").filter(Boolean);if(JSON.stringify(g)!==JSON.stringify([k,d.headSha])||JSON.stringify($)!==JSON.stringify(d.changedPaths)||y.otherIndex.some(({path:S,entry:O})=>{const j=w(e,"ls-tree","-z",k,"--",S).split("\0").filter(Boolean);return O===null?j.length!==0:j.length!==1||j[0]!==O.replace(/^(100644|100755) ([a-f0-9]{40}) 0\t/,"$1 blob $2 ")})||p(w(e,"show",`${k}:.neocortex/state.json`))!==y.stateAfterSha256||p(w(e,"show",`${k}:docs/stories/${d.storyId}.story.md`))!==y.storyAfterSha256||!w(e,"log","-1","--format=%B",k).split(`
|
|
10
|
+
`).map(S=>S.trim()).includes(`Neocortex-Legacy-Commit: ${d.storyId}`)||w(e,"status","--porcelain=v1","-uall")!=="")return i("legacy-story-commit-checkpoint-invalid");const A=u(e,"ls-remote","--heads","origin",`refs/heads/${d.branch}`);if(A!==""&&A!==`${k} refs/heads/${d.branch}`)return i("legacy-story-commit-remote-drift");let v=f?.qaSha256;if(!v){try{v=t.verifyQa?await t.verifyQa(k):await(async()=>{const S=await Le(e,{headSha:k,graphRevision:p(`legacy-story-c08\0${I}`)}),O=Ve(S);if(!O||O.executionHeadSha!==k)throw new Error("qa-invalid");return O.executionEvidenceDigest})()}catch{return i("legacy-story-commit-qa-failed")}if(!/^[a-f0-9]{64}$/.test(v))return i("legacy-story-commit-qa-failed")}if(u(e,"rev-parse","HEAD")!==k||w(e,"status","--porcelain=v1","-uall")!=="")return i("legacy-story-commit-final-drift");if(A===""&&u(e,"push","--porcelain","origin",`${k}:refs/heads/${d.branch}`),u(e,"ls-remote","--heads","origin",`refs/heads/${d.branch}`)!==`${k} refs/heads/${d.branch}`)return i("legacy-story-commit-push-unverified");await t.afterPush?.();const C={schemaVersion:1,kind:"legacy-story-c08-commit-accepted",intentSha256:I,checkpointHeadSha:k,qaSha256:v};return f&&JSON.stringify(f)!==JSON.stringify(C)?i("legacy-story-commit-accepted-conflict"):(f||(await z(o,l,`${JSON.stringify(C)}
|
|
11
|
+
`),await J(N(o,l),o)),{ok:!0,value:Object.freeze({schemaVersion:1,kind:"legacy-story-c08-commit-accepted",storyId:d.storyId,epicId:d.epicId,branch:d.branch,checkpointHeadSha:k,qaSha256:v,reused:!!f,physicalCommit:!0,checkpointAccepted:!0,publicSafe:!0})})}catch(e){const o=e instanceof Error?e.message:"";return i(o.startsWith("legacy-story-commit-")?o:"legacy-story-commit-effect-uncertain")}finally{await te(a.path,a.owner).catch(()=>{})}}function ut(t){if(!/^[A-Za-z0-9][A-Za-z0-9_-]*\.[A-Za-z0-9._-]+$/.test(t.storyId))return i("legacy-story-sync-target-invalid");try{const r=E(t.projectRoot);if(E(u(r,"rev-parse","--show-toplevel"))!==r||w(r,"status","--porcelain=v1","-uall")!=="")return i("legacy-story-sync-checkout-invalid");const a=w(r,"show","HEAD:.neocortex/state.json"),e=`docs/stories/${t.storyId}.story.md`,o=w(r,"show",`HEAD:${e}`);if(B(N(r,".neocortex/state.json"),2*1024*1024)!==a||B(N(r,e),2*1024*1024)!==o)return i("legacy-story-sync-committed-content-drift");const c=m(JSON.parse(a)),h=m(c?.stories),l=m(c?.epics),y=m(h?.[t.storyId]),s=y?.epic_id,d=typeof s=="string"?m(l?.[s]):null;if(!y||y.id!==t.storyId||typeof s!="string"||!d||d.id!==s||d.branch_mode==="epic"||y.status!=="committed"||y.last_step!==T||!Array.isArray(y.steps_completed)||!y.steps_completed.includes(T)||y.steps_completed.includes(V)||!Number.isSafeInteger(y.issue_number)||y.issue_number<=0)return i("legacy-story-sync-state-invalid");const n=Array.isArray(d.stories)?d.stories:null;if(!n||n.length===0||new Set(n).size!==n.length||!n.includes(t.storyId)||n.some(x=>typeof x!="string"||m(h?.[x])?.epic_id!==s)||Object.entries(h??{}).some(([x,q])=>m(q)?.epic_id===s&&!n.includes(x)))return i("legacy-story-sync-topology-invalid");const I=je(d,n.map(x=>({...m(h?.[x]),id:x}))),b=`story/${s}/${t.storyId}`,k=m(c?.config)?.default_branch;if(I.mode!=="story"||y.branch_name!==b||u(r,"branch","--show-current")!==b||typeof k!="string"||k===b||u(r,"check-ref-format","--branch",k)!==k)return i("legacy-story-sync-branch-invalid");const g=o.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n/);if(!g)return i("legacy-story-sync-frontmatter-invalid");const $=X(g[1],{strict:!0,uniqueKeys:!0}),A=m($.toJS()),v=["stepsCompleted","steps_completed"].filter(x=>$.has(x)),C=["lastStep","last_step"].filter(x=>$.has(x)),S=["branchName","branch_name"].filter(x=>$.has(x));if($.errors.length>0||$.get("id")!==t.storyId||($.get("epic_id")??$.get("epic"))!==s||$.get("status")!=="committed"||$.has("currentStatus")&&$.get("currentStatus")!=="committed"||v.length>1||C.length>1||S.length>1||v.length===1&&JSON.stringify(A?.[v[0]])!==JSON.stringify(y.steps_completed)||C.length===1&&A?.[C[0]]!==T||S.length===1&&A?.[S[0]]!==b)return i("legacy-story-sync-frontmatter-invalid");const O=u(r,"rev-parse","HEAD"),j=R(r,k);if(!/^[a-f0-9]{40}$/.test(O)||R(r,b)!==O||u(r,"rev-parse",`refs/remotes/origin/${k}`)!==j)return i("legacy-story-sync-remote-drift");const H=u(r,"merge-base",O,j);return/^[a-f0-9]{40}$/.test(H)?{ok:!0,value:Object.freeze({schemaVersion:1,kind:"legacy-story-c09-sync-plan",storyId:t.storyId,epicId:s,repository:re(r),branch:b,baseBranch:k,headSha:O,baseSha:j,mergeBaseSha:H,stateSha256:p(a),storySha256:p(o),baseAlreadyAncestor:H===j,physicalSync:!1,checkpointAccepted:!1,localOnly:!0})}:i("legacy-story-sync-ancestry-invalid")}catch{return i("legacy-story-sync-physical-unavailable")}}function gt(t,r){const a=B(N(t,".neocortex/state.json"),2097152),e=`docs/stories/${r.storyId}.story.md`,o=B(N(t,e),2*1024*1024),c=w(t,"show",`${r.headSha}:.neocortex/state.json`),h=w(t,"show",`${r.headSha}:${e}`);if(p(c)!==r.stateSha256||p(h)!==r.storySha256||o!==h)throw new Error("legacy-story-sync-preimage-drift");const l=m(JSON.parse(a)),y=m(JSON.parse(c)),s=m(l?.stories),d=m(m(y?.stories)?.[r.storyId]),n=m(s?.[r.storyId]),I=m(m(l?.epics)?.[r.epicId]),b=I?.stories;if(!n||!d||JSON.stringify(n)!==JSON.stringify(d)||n.status!=="committed"||n.last_step!==T||n.branch_name!==r.branch||!Array.isArray(n.steps_completed)||!n.steps_completed.includes(T)||n.steps_completed.includes(V)||!I||I.id!==r.epicId||I.branch_mode==="epic"||!Array.isArray(b)||!b.includes(r.storyId)||new Set(b).size!==b.length||b.some(S=>typeof S!="string"||m(s?.[S])?.epic_id!==r.epicId)||m(l?.config)?.default_branch!==r.baseBranch)throw new Error("legacy-story-sync-merged-state-invalid");n.status="synced",n.last_step=V,n.steps_completed=[...n.steps_completed,V],n.sync_base_sha=r.baseSha;const f=`${JSON.stringify(l,null,2)}
|
|
12
|
+
`,k=o.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n/);if(!k)throw new Error("legacy-story-sync-frontmatter-invalid");const g=X(k[1],{strict:!0,uniqueKeys:!0}),$=m(g.toJS()),A=["stepsCompleted","steps_completed"].filter(S=>g.has(S)),v=["lastStep","last_step"].filter(S=>g.has(S));if(g.errors.length>0||g.get("id")!==r.storyId||(g.get("epic_id")??g.get("epic"))!==r.epicId||g.get("status")!=="committed"||A.length!==1||v.length!==1||JSON.stringify($?.[A[0]])!==JSON.stringify(d.steps_completed)||$?.[v[0]]!==T)throw new Error("legacy-story-sync-frontmatter-invalid");g.set("status","synced"),g.has("currentStatus")&&g.set("currentStatus","synced"),g.set(A[0],[...d.steps_completed,V]),g.set(v[0],V),g.set("syncBaseSha",r.baseSha);const C=`---
|
|
13
|
+
${g.toString({lineWidth:0})}---
|
|
14
|
+
${o.slice(k[0].length)}`;return{stateBefore:a,stateAfter:f,storyBefore:o,storyAfter:C}}async function me(t,r,a){const e=N(t,r);if(!D(e))return null;await J(e,t);const o=m(JSON.parse(B(e,a)));if(!o)throw new Error("legacy-story-sync-journal-invalid");return o}async function zt(t){if(!t.authorize)return i("legacy-story-sync-authorization-required");if(!/^[A-Za-z0-9][A-Za-z0-9_-]*\.[A-Za-z0-9._-]+$/.test(t.storyId))return i("legacy-story-sync-target-invalid");const r=`legacy-c09-sync-${U(16).toString("hex")}`,a=await ee(t.projectRoot,{kind:"direct",storyId:t.storyId,sessionId:r,idempotencyKey:r,expiresAt:new Date(Date.now()+60*6e4).toISOString(),persistent:!1});if(!a.ok)return i(a.reasonCode);try{const e=E(t.projectRoot);if(E(u(e,"rev-parse","--show-toplevel"))!==e)return i("legacy-story-sync-checkout-invalid");const o=await W(await F(e),"legacy-story-pr-intents"),c=p(t.storyId),h=`${c}.c09.sync.json`,l=`${c}.c09.sync.prepared.json`,y=`${c}.c09.sync.accepted.json`;let s=await me(o,h,8192);if(!s){const _=ut(t);if(!_.ok)return _;const M={schemaVersion:1,kind:"legacy-story-c09-sync-intent",plan:_.value};await z(o,h,`${JSON.stringify(M)}
|
|
15
|
+
`),s=M}const d=m(s.plan);if(s.schemaVersion!==1||s.kind!=="legacy-story-c09-sync-intent"||!d||d.schemaVersion!==1||d.kind!=="legacy-story-c09-sync-plan"||d.storyId!==t.storyId||typeof d.epicId!="string"||d.branch!==`story/${d.epicId}/${t.storyId}`||typeof d.baseBranch!="string"||typeof d.repository!="string"||typeof d.headSha!="string"||!/^[a-f0-9]{40}$/.test(d.headSha)||typeof d.baseSha!="string"||!/^[a-f0-9]{40}$/.test(d.baseSha)||typeof d.stateSha256!="string"||!/^[a-f0-9]{64}$/.test(d.stateSha256)||typeof d.storySha256!="string"||!/^[a-f0-9]{64}$/.test(d.storySha256)||typeof d.baseAlreadyAncestor!="boolean"||d.physicalSync!==!1||d.checkpointAccepted!==!1||u(e,"branch","--show-current")!==d.branch||re(e)!==d.repository)return i("legacy-story-sync-intent-invalid");const n=d,I=p(JSON.stringify(s));let f=await me(o,l,4096);if(f&&(f.schemaVersion!==1||f.kind!=="legacy-story-c09-sync-prepared"||f.intentSha256!==I||!/^[a-f0-9]{40}$/.test(f.treeSha)||!/^[a-f0-9]{64}$/.test(f.stateSha256)||!/^[a-f0-9]{64}$/.test(f.storySha256)))return i("legacy-story-sync-prepared-invalid");const g=await me(o,y,4096);if(g&&(g.schemaVersion!==1||g.kind!=="legacy-story-c09-sync-accepted"||g.intentSha256!==I||!/^[a-f0-9]{40}$/.test(g.checkpointHeadSha)||!/^[a-f0-9]{64}$/.test(g.qaSha256)))return i("legacy-story-sync-accepted-invalid");const $=u(e,"rev-parse","HEAD");if(w(e,"status","--porcelain=v1","-uall")!==""||R(e,n.baseBranch)!==n.baseSha||p(w(e,"show",`${n.headSha}:.neocortex/state.json`))!==n.stateSha256||p(w(e,"show",`${n.headSha}:docs/stories/${n.storyId}.story.md`))!==n.storySha256)return i("legacy-story-sync-physical-drift");const A=N(o,`${c}.c09.sync.checkout`);if(D(A)||K("git",["worktree","add","--detach",A,g?.checkpointHeadSha??n.headSha],{cwd:e,encoding:"utf8",timeout:6e4,stdio:["ignore","pipe","pipe"],maxBuffer:32*1024}),!Z(A).isDirectory()||E(A)!==A||E(u(A,"rev-parse","--show-toplevel"))!==A||Ie(A)!==Ie(e)||u(A,"branch","--show-current")!=="")return i("legacy-story-sync-candidate-invalid");let v=u(A,"rev-parse","HEAD");if(v===n.headSha){if(f)return i("legacy-story-sync-prepared-uncommitted");if($!==n.headSha||R(e,n.branch)!==n.headSha||w(A,"status","--porcelain=v1","-uall")!=="")return i("legacy-story-sync-preparation-drift");if(!n.baseAlreadyAncestor){try{u(A,"merge","--no-ff","--no-commit",n.baseSha)}catch{return i("legacy-story-sync-merge-conflict")}if(w(A,"ls-files","-u")!=="")return i("legacy-story-sync-merge-conflict")}const _=gt(A,n);await G(N(A,".neocortex"),"state.json",_.stateAfter,p(_.stateBefore)),await G(N(A,"docs/stories"),`${n.storyId}.story.md`,_.storyAfter,p(_.storyBefore)),u(A,"add","--",".neocortex/state.json",`docs/stories/${n.storyId}.story.md`),u(A,"diff","--cached","--check"),f={schemaVersion:1,kind:"legacy-story-c09-sync-prepared",intentSha256:I,treeSha:u(A,"write-tree"),stateSha256:p(_.stateAfter),storySha256:p(_.storyAfter)},await z(o,l,`${JSON.stringify(f)}
|
|
16
|
+
`),await J(N(o,l),o),u(A,"commit","-m",`chore(story): sync ${n.storyId} with ${n.baseBranch}`,"-m",`Neocortex-Legacy-Sync: ${n.storyId}`),v=u(A,"rev-parse","HEAD"),await t.afterCommit?.()}const C=u(A,"rev-list","--parents","-n","1",v).split(" "),S=n.baseAlreadyAncestor?[v,n.headSha]:[v,n.headSha,n.baseSha],O=m(JSON.parse(w(A,"show",`${v}:.neocortex/state.json`))),j=m(m(O?.stories)?.[n.storyId]),H=w(A,"show",`${v}:docs/stories/${n.storyId}.story.md`);if(!f||u(A,"rev-parse",`${v}^{tree}`)!==f.treeSha||p(w(A,"show",`${v}:.neocortex/state.json`))!==f.stateSha256||p(H)!==f.storySha256||JSON.stringify(C)!==JSON.stringify(S)||!j||j.status!=="synced"||j.last_step!==V||j.sync_base_sha!==n.baseSha||!Array.isArray(j.steps_completed)||!j.steps_completed.includes(V)||!H.startsWith(`---
|
|
17
|
+
`)||!w(A,"log","-1","--format=%B",v).split(`
|
|
18
|
+
`).map(_=>_.trim()).includes(`Neocortex-Legacy-Sync: ${n.storyId}`)||w(A,"status","--porcelain=v1","-uall")!=="")return i("legacy-story-sync-checkpoint-invalid");if(g&&g.checkpointHeadSha!==v)return i("legacy-story-sync-accepted-conflict");const x=R(e,n.branch);if(![n.headSha,v].includes($)||![n.headSha,v].includes(x)||g&&($!==v||x!==v))return i("legacy-story-sync-remote-drift");let q=g?.qaSha256;if(!q){if(!t.verifyQa)try{Ze(A)}catch{return i("legacy-story-sync-dependencies-failed")}const _={schemaVersion:1,kind:"legacy-story-pr-plan",storyId:n.storyId,epicId:n.epicId,repository:n.repository,branch:n.branch,baseBranch:n.baseBranch,headSha:v,baseSha:n.baseSha,qaAuthority:"root-review-required",localOnly:!0};try{q=await se(_,A,t.verifyQa)}catch{return i("legacy-story-sync-qa-failed")}}if(u(A,"rev-parse","HEAD")!==v||w(A,"status","--porcelain=v1","-uall")!==""||u(e,"rev-parse","HEAD")!==$||w(e,"status","--porcelain=v1","-uall")!==""||R(e,n.baseBranch)!==n.baseSha)return i("legacy-story-sync-final-drift");if(x===n.headSha&&u(e,"push","--porcelain","origin",`${v}:refs/heads/${n.branch}`),R(e,n.branch)!==v)return i("legacy-story-sync-push-unverified");if(await t.afterPush?.(),u(e,"rev-parse","HEAD")===n.headSha&&u(e,"merge","--ff-only",v),u(e,"rev-parse","HEAD")!==v||w(e,"status","--porcelain=v1","-uall")!==""||B(N(e,".neocortex/state.json"),2*1024*1024)!==w(e,"show",`${v}:.neocortex/state.json`)||B(N(e,`docs/stories/${n.storyId}.story.md`),2*1024*1024)!==H)return i("legacy-story-sync-local-readback-invalid");const L={schemaVersion:1,kind:"legacy-story-c09-sync-accepted",intentSha256:I,checkpointHeadSha:v,qaSha256:q};return g&&JSON.stringify(g)!==JSON.stringify(L)?i("legacy-story-sync-accepted-conflict"):(g||(await z(o,y,`${JSON.stringify(L)}
|
|
19
|
+
`),await J(N(o,y),o)),{ok:!0,value:Object.freeze({schemaVersion:1,kind:"legacy-story-c09-sync-accepted",storyId:n.storyId,epicId:n.epicId,branch:n.branch,baseSha:n.baseSha,checkpointHeadSha:v,qaSha256:q,reused:!!g,physicalSync:!0,checkpointAccepted:!0,publicSafe:!0})})}catch(e){const o=e instanceof Error?e.message:"";return i(o.startsWith("legacy-story-sync-")?o:"legacy-story-sync-effect-uncertain")}finally{await te(a.path,a.owner).catch(()=>{})}}function le(t,r){try{const a=E(t.projectRoot);if(!/^[A-Za-z0-9][A-Za-z0-9_-]*\.[A-Za-z0-9._-]+$/.test(t.storyId)||E(u(a,"rev-parse","--show-toplevel"))!==a||!r&&u(a,"status","--porcelain=v1","-uall")!=="")return i("legacy-story-pr-checkout-invalid");const e=w(a,"show","HEAD:.neocortex/state.json");if(!r&&e!==B(N(a,".neocortex/state.json"),2*1024*1024))return i("legacy-story-pr-state-not-committed");const o=m(JSON.parse(e)),c=m(o?.stories),h=m(o?.epics),l=m(c?.[t.storyId]),y=l?.epic_id,s=typeof y=="string"?m(h?.[y]):null;if(!l||l.id!==t.storyId||typeof y!="string"||!s||s.id!==y||s.branch_mode==="epic"||l.status!=="synced"||l.last_step!==V||!Array.isArray(l.steps_completed)||!l.steps_completed.includes(V)||l.steps_completed.includes(Q))return i("legacy-story-pr-state-invalid");const d=Array.isArray(s.stories)?s.stories:null;if(!d||d.length===0||new Set(d).size!==d.length||!d.includes(t.storyId)||d.some(C=>typeof C!="string"||m(c?.[C])?.epic_id!==y)||Object.entries(c??{}).some(([C,S])=>m(S)?.epic_id===y&&!d.includes(C)))return i("legacy-story-pr-topology-invalid");const n=je(s,d.map(C=>({...m(c?.[C]),id:C}))),I=`story/${y}/${t.storyId}`,f=m(o?.config)?.default_branch;if(n.mode!=="story"||l.branch_name!==I||u(a,"branch","--show-current")!==I||typeof f!="string"||f===I||u(a,"check-ref-format","--branch",f)!==f)return i("legacy-story-pr-branch-invalid");const g=u(a,"show",`HEAD:docs/stories/${t.storyId}.story.md`).match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n/);if(!g)return i("legacy-story-pr-frontmatter-invalid");const $=X(g[1],{strict:!0,uniqueKeys:!0});if($.errors.length>0||$.get("id")!==t.storyId||($.get("epic_id")??$.get("epic"))!==y||$.get("status")!=="synced")return i("legacy-story-pr-frontmatter-invalid");const A=u(a,"rev-parse","HEAD"),v=R(a,f);return!/^[a-f0-9]{40}$/.test(A)||R(a,I)!==A||u(a,"rev-parse",`refs/remotes/origin/${f}`)!==v?i("legacy-story-pr-remote-drift"):(u(a,"merge-base","--is-ancestor",v,A),{ok:!0,value:Object.freeze({schemaVersion:1,kind:"legacy-story-pr-plan",storyId:t.storyId,epicId:y,repository:re(a),branch:I,baseBranch:f,headSha:A,baseSha:v,qaAuthority:"root-review-required",localOnly:!0})})}catch{return i("legacy-story-pr-physical-unavailable")}}function he(t){return le(t,!1)}async function se(t,r,a){const e=a?await a(t):await(async()=>{const o=await Le(r,{headSha:t.headSha,graphRevision:p(`legacy-story-pr-c10\0${JSON.stringify(t)}`)}),c=Ve(o);if(!c||c.executionHeadSha!==t.headSha)throw new Error("legacy-story-pr-checkpoint-qa-invalid");return c.executionEvidenceDigest})();if(!/^[a-f0-9]{64}$/.test(e))throw new Error("legacy-story-pr-checkpoint-qa-invalid");return e}function Ze(t){for(const r of[".","packages/server","portal","admin","landing"]){const a=N(t,r),e=N(a,"package.json"),o=N(a,"package-lock.json");if(!D(a)||!Z(a).isDirectory()||E(a)!==a||!D(e)||!Z(e).isFile()||!D(o)||!Z(o).isFile())throw new Error("legacy-story-pr-candidate-dependencies-missing");try{K("npm",["ci","--include=dev","--no-audit","--no-fund"],{cwd:a,encoding:"utf8",timeout:10*6e4,stdio:["ignore","pipe","pipe"],maxBuffer:1024*1024})}catch{throw new Error("legacy-story-pr-candidate-dependencies-failed")}}}const oe={async list(t,r,a){const e=K("gh",["pr","list","--repo",t,"--state","all","--head",r,"--json","number,state,headRefName,headRefOid,baseRefName,url","--limit","100"],{encoding:"utf8",timeout:15e3,stdio:["ignore","pipe","pipe"],maxBuffer:262144});return JSON.parse(e)},async create(t,r,a,e,o){K("gh",["pr","create","--repo",t,"--head",r,"--base",a,"--title",e,"--body-file",o],{encoding:"utf8",timeout:3e4,stdio:["ignore","pipe","pipe"],maxBuffer:16*1024})}},Se={async view(t,r){const a=K("gh",["pr","view",String(r),"--repo",t,"--json","number,state,headRefName,headRefOid,baseRefName,baseRefOid,isDraft,mergeable,mergeCommit,statusCheckRollup,url"],{encoding:"utf8",timeout:15e3,stdio:["ignore","pipe","pipe"],maxBuffer:262144});return JSON.parse(a)},async merge(t,r,a){K("gh",["api","--method","PUT",`repos/${t}/pulls/${r}/merge`,"-f",`sha=${a}`,"-f","merge_method=merge"],{encoding:"utf8",timeout:3e4,stdio:["ignore","pipe","pipe"],maxBuffer:16*1024})}};async function Lt(t){if(!t.authorize)return i("legacy-story-pr-authorization-required");let r;try{if(Z(t.bodyFile).isSymbolicLink())return i("legacy-story-pr-body-unsafe");const h=B(t.bodyFile,32*1024);if(!h.trim()||h.includes("\0"))return i("legacy-story-pr-body-unsafe");r=h}catch{return i("legacy-story-pr-body-unsafe")}const a=he(t);if(!a.ok)return a;try{await se(a.value,t.projectRoot,t.verifyQa)}catch{return i("legacy-story-pr-checkpoint-qa-failed")}const e=t.provider??oe,o=`legacy-c10-${U(16).toString("hex")}`,c=await ee(t.projectRoot,{kind:"direct",storyId:t.storyId,sessionId:o,idempotencyKey:o,expiresAt:new Date(Date.now()+5*6e4).toISOString(),persistent:!1});if(!c.ok)return i(c.reasonCode);try{const h=he(t);if(!h.ok||JSON.stringify(h.value)!==JSON.stringify(a.value))return i("legacy-story-pr-pre-effect-race");const l=await e.list(a.value.repository,a.value.branch,a.value.baseBranch);let y=de(a.value,l);const s=y!==null;if(!y){const n=he(t);if(!n.ok||JSON.stringify(n.value)!==JSON.stringify(a.value))return i("legacy-story-pr-pre-effect-race");if(!await ft(t.projectRoot,a.value))return i("legacy-story-pr-create-attempt-unresolved");const I=ot(N(lt(),"legacy-story-pr-body-")),b=N(I,"body.md");try{dt(b,r,{flag:"wx",mode:384}),await e.create(a.value.repository,a.value.branch,a.value.baseBranch,`[YOLO] Story ${a.value.storyId}`,b)}finally{try{yt(b)}catch{}ct(I)}const f=he(t);if(!f.ok||JSON.stringify(f.value)!==JSON.stringify(a.value))return i("legacy-story-pr-post-effect-race");if(y=de(a.value,await e.list(a.value.repository,a.value.branch,a.value.baseBranch)),!y)return i("legacy-story-pr-readback-unavailable")}const d=he(t);return!d.ok||JSON.stringify(d.value)!==JSON.stringify(a.value)?i("legacy-story-pr-post-effect-race"):{ok:!0,value:Object.freeze({schemaVersion:1,kind:"legacy-story-pr-provider-receipt",storyId:a.value.storyId,epicId:a.value.epicId,repository:a.value.repository,branch:a.value.branch,baseBranch:a.value.baseBranch,headSha:a.value.headSha,number:y.number,url:y.url,reused:s,checkpointAccepted:!1,publicSafe:!0})}}catch(h){const l=h instanceof Error?h.message:"";return i(l.startsWith("legacy-story-pr-")?l:"legacy-story-pr-provider-unavailable")}finally{await te(c.path,c.owner).catch(()=>{})}}function p(t){return Pe("sha256").update(t).digest("hex")}function Ee(t,r,a){const e=w(t,"show","HEAD:.neocortex/state.json"),o=m(JSON.parse(e)),c=m(m(o?.stories)?.[r.storyId]);if(!c||c.status!=="synced"||c.last_step!==V||!Array.isArray(c.steps_completed)||!c.steps_completed.includes(V)||c.steps_completed.includes(Q)||c.pr_number!=null)throw new Error("legacy-story-pr-checkpoint-state-conflict");const h=c.steps_completed;c.status="pr-created",c.last_step=Q,c.steps_completed=[...h,Q],c.pr_number=a;const l=`${JSON.stringify(o,null,2)}
|
|
20
|
+
`,y=`docs/stories/${r.storyId}.story.md`,s=w(t,"show",`HEAD:${y}`),d=s.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n/);if(!d)throw new Error("legacy-story-pr-checkpoint-frontmatter-invalid");const n=X(d[1],{strict:!0,uniqueKeys:!0}),I=m(n.toJS()),b=["stepsCompleted","steps_completed"].filter(A=>n.has(A)),f=["lastStep","last_step"].filter(A=>n.has(A)),k=["prNumber","pr_number"].filter(A=>n.has(A)),g=["branchName","branch_name"].filter(A=>n.has(A));if(n.errors.length>0||n.get("id")!==r.storyId||(n.get("epic_id")??n.get("epic"))!==r.epicId||n.get("status")!=="synced"||b.length>1||f.length>1||k.length>1||g.length>1||n.has("currentStatus")&&n.get("currentStatus")!=="synced"||b.length===1&&(!Array.isArray(I?.[b[0]])||JSON.stringify(I?.[b[0]])!==JSON.stringify(h))||f.length===1&&I?.[f[0]]!==V||g.length===1&&I?.[g[0]]!==r.branch||k.length===1&&I?.[k[0]]!=null)throw new Error("legacy-story-pr-checkpoint-frontmatter-conflict");n.set("status","pr-created"),n.has("currentStatus")&&n.set("currentStatus","pr-created"),n.set(b[0]??"stepsCompleted",[...b.length===1?I[b[0]]:h,Q]),n.set(f[0]??"lastStep",Q),n.set(k[0]??"prNumber",a);const $=`---
|
|
21
|
+
${n.toString({lineWidth:0})}---
|
|
22
|
+
${s.slice(d[0].length)}`;return{stateBefore:e,stateAfter:l,storyBefore:s,storyAfter:$,storyPath:y}}function we(t,r,a){const e=le({projectRoot:t,storyId:r.storyId},!0);if(!e.ok||JSON.stringify(e.value)!==JSON.stringify(r))throw new Error("legacy-story-pr-checkpoint-physical-drift");const o=B(N(t,".neocortex/state.json"),2*1024*1024),c=B(N(t,a.storyPath),2*1024*1024);if(![a.stateBefore,a.stateAfter].includes(o)||![a.storyBefore,a.storyAfter].includes(c))throw new Error("legacy-story-pr-checkpoint-preimage-conflict");if(w(t,"status","--porcelain=v1","-uall").split(`
|
|
23
|
+
`).filter(Boolean).some(l=>!l.startsWith(" M ")||![".neocortex/state.json",a.storyPath].includes(l.slice(3))))throw new Error("legacy-story-pr-checkpoint-worktree-dirty");return{stateCurrent:o,storyCurrent:c}}async function fe(t,r){const a=N(t,r);if(!D(a))return null;await J(a,t);const e=B(a,4096),o=m(JSON.parse(e));if(!o||o.schemaVersion!==1||o.kind!=="legacy-story-c10-acceptance-intent"||typeof o.qaDigest!="string"||!/^[a-f0-9]{64}$/.test(o.qaDigest))throw new Error("legacy-story-pr-checkpoint-journal-invalid");return o}async function We(t,r,a){await z(t,r,`${JSON.stringify(a)}
|
|
24
|
+
`),await J(N(t,r),t)}async function Vt(t){if(!Number.isSafeInteger(t.prNumber)||t.prNumber<=0)return i("legacy-story-pr-checkpoint-number-invalid");const r=he(t);let a=null;if(r.ok)try{a=await se(r.value,t.projectRoot,t.verifyQa)}catch{return i("legacy-story-pr-checkpoint-qa-failed")}const e=`legacy-c10-accept-${U(16).toString("hex")}`,o=await ee(t.projectRoot,{kind:"direct",storyId:t.storyId,sessionId:e,idempotencyKey:e,expiresAt:new Date(Date.now()+5*6e4).toISOString(),persistent:!1});if(!o.ok)return i(o.reasonCode);try{const c=E(t.projectRoot),h=le(t,!0);if(!h.ok||r.ok&&JSON.stringify(h.value)!==JSON.stringify(r.value))return i("legacy-story-pr-checkpoint-plan-drift");const l=h.value,y=Ee(c,l,t.prNumber),s=we(c,l,y),d=await W(await F(c),"legacy-story-pr-intents"),n=p(l.storyId),I=`${n}.c10.json`,b=`${n}.c10.accepted.json`,f=await fe(d,I),k=await fe(d,b);if(!f&&(!r.ok||!a||s.stateCurrent!==y.stateBefore||s.storyCurrent!==y.storyBefore))return i("legacy-story-pr-checkpoint-unjournaled-drift");if(k&&(!f||JSON.stringify(k)!==JSON.stringify(f)))return i("legacy-story-pr-checkpoint-accepted-conflict");const g=de(l,await(t.provider??oe).list(l.repository,l.branch,l.baseBranch));if(!g||g.number!==t.prNumber)return i("legacy-story-pr-checkpoint-provider-mismatch");const $={schemaVersion:1,kind:"legacy-story-c10-acceptance-intent",storyId:l.storyId,planDigest:p(JSON.stringify(l)),repository:l.repository,number:g.number,url:g.url,qaDigest:f?.qaDigest??a,stateBefore:p(y.stateBefore),stateAfter:p(y.stateAfter),storyBefore:p(y.storyBefore),storyAfter:p(y.storyAfter)};if(f&&JSON.stringify(f)!==JSON.stringify($))return i("legacy-story-pr-checkpoint-journal-conflict");f||await We(d,I,$);const A=we(c,l,y);if(k&&(A.stateCurrent!==y.stateAfter||A.storyCurrent!==y.storyAfter))return i("legacy-story-pr-checkpoint-accepted-physical-mismatch");A.stateCurrent===y.stateBefore&&(await G(N(c,".neocortex"),"state.json",y.stateAfter,$.stateBefore),await t.afterStatePersist?.()),we(c,l,y).storyCurrent===y.storyBefore&&(await G(N(c,"docs/stories"),`${l.storyId}.story.md`,y.storyAfter,$.storyBefore),await t.afterStoryPersist?.());const C=we(c,l,y);return C.stateCurrent!==y.stateAfter||C.storyCurrent!==y.storyAfter?i("legacy-story-pr-checkpoint-post-write-mismatch"):(k||await We(d,b,$),{ok:!0,value:Object.freeze({schemaVersion:1,kind:"legacy-story-c10-checkpoint",storyId:l.storyId,epicId:l.epicId,branch:l.branch,repository:l.repository,number:g.number,url:g.url,headSha:l.headSha,stateSha256:$.stateAfter,storySha256:$.storyAfter,reused:!!k,checkpointAccepted:!0,localOnly:!0})})}catch(c){const h=c instanceof Error?c.message:"";return i(h.startsWith("legacy-story-pr-")?h:h.includes("secure-filesystem-cas-conflict")?"legacy-story-pr-checkpoint-write-raced":"legacy-story-pr-checkpoint-failed")}finally{await te(o.path,o.owner).catch(()=>{})}}async function Mt(t){if(!Number.isSafeInteger(t.prNumber)||t.prNumber<=0)return i("legacy-story-pr-checkpoint-number-invalid");try{const r=E(t.projectRoot),a=le(t,!0);if(!a.ok)return a;const e=a.value,o=Ee(r,e,t.prNumber),c=we(r,e,o);if(c.stateCurrent!==o.stateAfter||c.storyCurrent!==o.storyAfter)return i("legacy-story-pr-checkpoint-not-accepted");const h=await W(await F(r),"legacy-story-pr-intents"),l=p(e.storyId),y=await fe(h,`${l}.c10.json`),s=await fe(h,`${l}.c10.accepted.json`);if(!y||!s||JSON.stringify(y)!==JSON.stringify(s))return i("legacy-story-pr-checkpoint-not-accepted");const d=de(e,await(t.provider??oe).list(e.repository,e.branch,e.baseBranch));if(!d||d.number!==t.prNumber)return i("legacy-story-pr-checkpoint-provider-mismatch");const n={schemaVersion:1,kind:"legacy-story-c10-acceptance-intent",storyId:e.storyId,planDigest:p(JSON.stringify(e)),repository:e.repository,number:d.number,url:d.url,qaDigest:s.qaDigest,stateBefore:p(o.stateBefore),stateAfter:p(o.stateAfter),storyBefore:p(o.storyBefore),storyAfter:p(o.storyAfter)};return JSON.stringify(s)!==JSON.stringify(n)?i("legacy-story-pr-checkpoint-journal-conflict"):{ok:!0,value:Object.freeze({plan:e,receipt:Object.freeze({schemaVersion:1,kind:"legacy-story-c10-checkpoint",storyId:e.storyId,epicId:e.epicId,branch:e.branch,repository:e.repository,number:d.number,url:d.url,headSha:e.headSha,stateSha256:s.stateAfter,storySha256:s.storyAfter,reused:!0,checkpointAccepted:!0,localOnly:!0})})}}catch(r){const a=r instanceof Error?r.message:"";return i(a.startsWith("legacy-story-pr-")?a:"legacy-story-pr-checkpoint-read-failed")}}function mt(t,r){const a=w(t,"diff","--raw","-z",r.baseSha,r.headSha),e=w(t,"diff","--name-only","-z",r.baseSha,r.headSha).split("\0").filter(Boolean);if(e.length===0||e.length>256||e.some(o=>!Fe(o)))throw new Error("legacy-story-pr-review-diff-invalid");return{diffSha256:p(a),changedPaths:Object.freeze(e)}}function Fe(t){return t.length>0&&t.length<=240&&/^[A-Za-z0-9_.-]+(?:\/[A-Za-z0-9_.-]+)*$/.test(t)&&t.split("/").every(r=>r!=="."&&r!=="..")}function Ae(t,r,a,e){const o=m(JSON.parse(r.stateAfter)),c=m(m(o?.stories)?.[t.storyId]);if(!c||c.status!=="pr-created"||c.last_step!==Q||c.pr_number!==a||c.review_request!=null||!Array.isArray(c.steps_completed)||!c.steps_completed.includes(Q)||c.steps_completed.includes(Y))throw new Error("legacy-story-pr-review-state-conflict");c.status="pr-reviewed",c.last_step=Y,c.steps_completed=[...c.steps_completed,Y],c.review_request={schemaVersion:1,kind:"git-pull-request",gitPullRequest:!0,prNumber:a,headSha:t.headSha,reviewEvidenceDigest:e};const h=`${JSON.stringify(o,null,2)}
|
|
25
|
+
`,l=r.storyAfter.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n/);if(!l)throw new Error("legacy-story-pr-review-frontmatter-invalid");const y=X(l[1],{strict:!0,uniqueKeys:!0}),s=m(y.toJS()),d=["stepsCompleted","steps_completed"].filter(f=>y.has(f)),n=["lastStep","last_step"].filter(f=>y.has(f)),I=s?.[d[0]];if(y.errors.length>0||y.get("id")!==t.storyId||(y.get("epic_id")??y.get("epic"))!==t.epicId||y.get("status")!=="pr-created"||d.length!==1||n.length!==1||y.has("currentStatus")&&y.get("currentStatus")!=="pr-created"||s?.[n[0]]!==Q||!Array.isArray(I)||!I.includes(Q))throw new Error("legacy-story-pr-review-frontmatter-conflict");y.set("status","pr-reviewed"),y.has("currentStatus")&&y.set("currentStatus","pr-reviewed"),y.set(d[0],[...I,Y]),y.set(n[0],Y);const b=`---
|
|
26
|
+
${y.toString({lineWidth:0})}---
|
|
27
|
+
${r.storyAfter.slice(l[0].length)}`;return{stateBefore:r.stateAfter,stateAfter:h,storyBefore:r.storyAfter,storyAfter:b,storyPath:r.storyPath}}async function pe(t){const r=E(t.projectRoot),a=le(t,!0);if(!a.ok)throw new Error(a.reasonCode);const e=a.value;if(!Number.isSafeInteger(t.prNumber)||t.prNumber<=0)throw new Error("legacy-story-pr-review-number-invalid");const o=Ee(r,e,t.prNumber),c=await W(await F(r),"legacy-story-pr-intents"),h=p(e.storyId),l=await fe(c,`${h}.c10.json`),y=await fe(c,`${h}.c10.accepted.json`);if(!l||!y||JSON.stringify(l)!==JSON.stringify(y))throw new Error("legacy-story-pr-review-c10-unaccepted");const s=de(e,await(t.provider??oe).list(e.repository,e.branch,e.baseBranch));if(!s||s.number!==t.prNumber)throw new Error("legacy-story-pr-review-provider-mismatch");const d={schemaVersion:1,kind:"legacy-story-c10-acceptance-intent",storyId:e.storyId,planDigest:p(JSON.stringify(e)),repository:e.repository,number:s.number,url:s.url,qaDigest:y.qaDigest,stateBefore:p(o.stateBefore),stateAfter:p(o.stateAfter),storyBefore:p(o.storyBefore),storyAfter:p(o.storyAfter)};if(JSON.stringify(y)!==JSON.stringify(d))throw new Error("legacy-story-pr-review-c10-journal-conflict");const n=mt(r,e),I=Object.freeze({schemaVersion:1,kind:"legacy-story-pr-review-plan",storyId:e.storyId,epicId:e.epicId,repository:e.repository,branch:e.branch,baseBranch:e.baseBranch,baseSha:e.baseSha,headSha:e.headSha,prNumber:t.prNumber,diffSha256:n.diffSha256,changedPaths:n.changedPaths,checkpointAccepted:!1,localOnly:!0});return{cwd:r,plan:e,c10:o,directory:c,reviewPlan:I}}function ne(t,r,a){const e=le({projectRoot:t,storyId:r.storyId},!0);if(!e.ok||JSON.stringify(e.value)!==JSON.stringify(r))throw new Error("legacy-story-pr-review-physical-drift");const o=B(N(t,".neocortex/state.json"),2*1024*1024),c=B(N(t,a.storyPath),2*1024*1024);if(![a.stateBefore,a.stateAfter].includes(o)||![a.storyBefore,a.storyAfter].includes(c))throw new Error("legacy-story-pr-review-preimage-conflict");if(w(t,"status","--porcelain=v1","-uall").split(`
|
|
28
|
+
`).filter(Boolean).some(l=>!l.startsWith(" M ")||![".neocortex/state.json",a.storyPath].includes(l.slice(3))))throw new Error("legacy-story-pr-review-worktree-dirty");return{stateCurrent:o,storyCurrent:c}}function Te(t,r,a){if(!Array.isArray(a)||a.length<1||a.length>64)return!1;const e=new Set;return a.every(o=>{const c=m(o);if(!c||Object.keys(c).sort().join(",")!=="disposition,id,path,sha256"||typeof c.id!="string"||!/^[A-Za-z0-9][A-Za-z0-9_.-]{0,63}$/.test(c.id)||e.has(c.id)||typeof c.path!="string"||!Fe(c.path)||typeof c.sha256!="string"||!/^[a-f0-9]{64}$/.test(c.sha256)||c.disposition!=="passed"&&c.disposition!=="not-applicable")return!1;e.add(c.id);try{return p(w(t,"show",`${r}:${c.path}`))===c.sha256}catch{return!1}})}function Ne(t,r){if(Buffer.byteLength(t)>32*1024)throw new Error("legacy-story-pr-review-report-unsafe");const a=m(JSON.parse(t)),e=r.reviewPlan;if(!a||Object.keys(a).sort().join(",")!==["acceptanceEvidence","baseSha","blockingFindings","diffSha256","epicId","headSha","kind","nonBlockingFindings","prNumber","remoteObservations","schemaVersion","sddEvidence","storyId","verdict"].sort().join(",")||a.schemaVersion!==1||a.kind!=="legacy-story-pr-review"||a.storyId!==e.storyId||a.epicId!==e.epicId||a.prNumber!==e.prNumber||a.headSha!==e.headSha||a.baseSha!==e.baseSha||a.diffSha256!==e.diffSha256||a.verdict!=="approved"||!Array.isArray(a.blockingFindings)||a.blockingFindings.length!==0||!Array.isArray(a.nonBlockingFindings)||a.nonBlockingFindings.length!==0||!Array.isArray(a.remoteObservations)||a.remoteObservations.length!==0||!Te(r.cwd,e.headSha,a.acceptanceEvidence)||!Te(r.cwd,e.headSha,a.sddEvidence))throw new Error("legacy-story-pr-review-report-invalid");return{report:a,raw:t,sha256:p(t)}}function Ge(t,r){if(Z(t).isSymbolicLink())throw new Error("legacy-story-pr-review-report-unsafe");return Ne(B(t,32*1024),r)}async function ae(t,r){const a=N(t,r);if(!D(a))return null;await J(a,t);const e=m(JSON.parse(B(a,64*1024)));if(!e||e.schemaVersion!==1||e.kind!=="legacy-story-c11-acceptance-intent"||typeof e.reviewSha256!="string"||!/^[a-f0-9]{64}$/.test(e.reviewSha256)||typeof e.qaSha256!="string"||!/^[a-f0-9]{64}$/.test(e.qaSha256)||typeof e.reviewRaw!="string"||p(e.reviewRaw)!==e.reviewSha256)throw new Error("legacy-story-pr-review-journal-invalid");return e}async function Qe(t,r,a){await z(t,r,`${JSON.stringify(a)}
|
|
29
|
+
`),await J(N(t,r),t)}async function Kt(t){try{const r=await pe(t),a=ne(r.cwd,r.plan,Ae(r.plan,r.c10,t.prNumber,"0".repeat(64)));return a.stateCurrent!==r.c10.stateAfter||a.storyCurrent!==r.c10.storyAfter?i("legacy-story-pr-review-already-transitioned"):{ok:!0,value:r.reviewPlan}}catch(r){const a=r instanceof Error?r.message:"";return i(a.startsWith("legacy-story-pr-")?a:"legacy-story-pr-review-plan-failed")}}async function Zt(t){if(!t.authorize)return i("legacy-story-pr-review-authorization-required");let r,a,e=null;try{r=await pe(t),a=Ge(t.reportFile,r);const h=Ae(r.plan,r.c10,t.prNumber,a.sha256),l=ne(r.cwd,r.plan,h);if(l.stateCurrent===r.c10.stateAfter&&l.storyCurrent===r.c10.storyAfter)try{e=await se(r.plan,r.cwd,t.verifyQa)}catch{throw new Error("legacy-story-pr-review-qa-failed")}}catch(h){const l=h instanceof Error?h.message:"";return i(l.startsWith("legacy-story-pr-")?l:"legacy-story-pr-review-preflight-failed")}const o=`legacy-c11-accept-${U(16).toString("hex")}`,c=await ee(t.projectRoot,{kind:"direct",storyId:t.storyId,sessionId:o,idempotencyKey:o,expiresAt:new Date(Date.now()+5*6e4).toISOString(),persistent:!1});if(!c.ok)return i(c.reasonCode);try{const h=await pe(t);if(JSON.stringify(h.reviewPlan)!==JSON.stringify(r.reviewPlan))return i("legacy-story-pr-review-plan-drift");const l=Ge(t.reportFile,h);if(l.sha256!==a.sha256)return i("legacy-story-pr-review-report-drift");const y=Ae(h.plan,h.c10,t.prNumber,l.sha256),s=ne(h.cwd,h.plan,y),d=p(h.plan.storyId),n=`${d}.c11.json`,I=`${d}.c11.accepted.json`,b=await ae(h.directory,n),f=await ae(h.directory,I);if(!b&&(!e||s.stateCurrent!==y.stateBefore||s.storyCurrent!==y.storyBefore))return i("legacy-story-pr-review-unjournaled-drift");if(f&&(!b||JSON.stringify(f)!==JSON.stringify(b)))return i("legacy-story-pr-review-accepted-conflict");const k={schemaVersion:1,kind:"legacy-story-c11-acceptance-intent",storyId:h.plan.storyId,planDigest:p(JSON.stringify(h.reviewPlan)),prNumber:t.prNumber,reviewSha256:l.sha256,qaSha256:b?.qaSha256??e,reviewRaw:l.raw,stateBefore:p(y.stateBefore),stateAfter:p(y.stateAfter),storyBefore:p(y.storyBefore),storyAfter:p(y.storyAfter)};if(b&&JSON.stringify(b)!==JSON.stringify(k))return i("legacy-story-pr-review-journal-conflict");b||await Qe(h.directory,n,k);const g=ne(h.cwd,h.plan,y);if(f&&(g.stateCurrent!==y.stateAfter||g.storyCurrent!==y.storyAfter))return i("legacy-story-pr-review-accepted-physical-mismatch");g.stateCurrent===y.stateBefore&&(await G(N(h.cwd,".neocortex"),"state.json",y.stateAfter,k.stateBefore),await t.afterStatePersist?.()),ne(h.cwd,h.plan,y).storyCurrent===y.storyBefore&&(await G(N(h.cwd,"docs/stories"),`${h.plan.storyId}.story.md`,y.storyAfter,k.storyBefore),await t.afterStoryPersist?.());const A=ne(h.cwd,h.plan,y);return A.stateCurrent!==y.stateAfter||A.storyCurrent!==y.storyAfter?i("legacy-story-pr-review-post-write-mismatch"):(f||await Qe(h.directory,I,k),{ok:!0,value:Object.freeze({schemaVersion:1,kind:"legacy-story-c11-checkpoint",storyId:h.plan.storyId,epicId:h.plan.epicId,branch:h.plan.branch,prNumber:t.prNumber,headSha:h.plan.headSha,reviewSha256:k.reviewSha256,qaSha256:k.qaSha256,stateSha256:k.stateAfter,storySha256:k.storyAfter,reused:!!f,checkpointAccepted:!0,localOnly:!0})})}catch(h){const l=h instanceof Error?h.message:"";return i(l.startsWith("legacy-story-pr-")?l:l.includes("secure-filesystem-cas-conflict")?"legacy-story-pr-review-write-raced":"legacy-story-pr-review-accept-failed")}finally{await te(c.path,c.owner).catch(()=>{})}}async function St(t){try{const r=await pe(t),a=p(r.plan.storyId),e=await ae(r.directory,`${a}.c11.json`),o=await ae(r.directory,`${a}.c11.accepted.json`);if(!e||!o||JSON.stringify(e)!==JSON.stringify(o))return i("legacy-story-pr-review-not-accepted");const c=Ne(o.reviewRaw,r),h=Ae(r.plan,r.c10,t.prNumber,c.sha256),l={schemaVersion:1,kind:"legacy-story-c11-acceptance-intent",storyId:r.plan.storyId,planDigest:p(JSON.stringify(r.reviewPlan)),prNumber:t.prNumber,reviewSha256:c.sha256,qaSha256:o.qaSha256,reviewRaw:c.raw,stateBefore:p(h.stateBefore),stateAfter:p(h.stateAfter),storyBefore:p(h.storyBefore),storyAfter:p(h.storyAfter)};if(JSON.stringify(o)!==JSON.stringify(l))return i("legacy-story-pr-review-journal-conflict");const y=ne(r.cwd,r.plan,h);return y.stateCurrent!==h.stateAfter||y.storyCurrent!==h.storyAfter?i("legacy-story-pr-review-physical-not-accepted"):{ok:!0,value:Object.freeze({plan:r.reviewPlan,receipt:Object.freeze({schemaVersion:1,kind:"legacy-story-c11-checkpoint",storyId:r.plan.storyId,epicId:r.plan.epicId,branch:r.plan.branch,prNumber:t.prNumber,headSha:r.plan.headSha,reviewSha256:o.reviewSha256,qaSha256:o.qaSha256,stateSha256:o.stateAfter,storySha256:o.storyAfter,reused:!0,checkpointAccepted:!0,localOnly:!0})})}}catch(r){const a=r instanceof Error?r.message:"";return i(a.startsWith("legacy-story-pr-")?a:"legacy-story-pr-review-read-failed")}}function Ye(t,r,a){const e=o=>o.map(c=>`- ${c.id}: ${c.disposition}; ${c.path}; sha256:${c.sha256}`).join(`
|
|
30
|
+
`);return`# ${t.storyId} \u2014 PR review
|
|
31
|
+
|
|
32
|
+
Verdict: approved
|
|
33
|
+
|
|
34
|
+
PR: ${t.prNumber}
|
|
35
|
+
Reviewed HEAD: ${t.headSha}
|
|
36
|
+
Base HEAD: ${t.baseSha}
|
|
37
|
+
Diff SHA-256: ${t.diffSha256}
|
|
38
|
+
Root review SHA-256: ${r}
|
|
39
|
+
Local QA SHA-256: ${a}
|
|
40
|
+
|
|
41
|
+
## Acceptance evidence
|
|
42
|
+
|
|
43
|
+
${e(t.acceptanceEvidence)}
|
|
44
|
+
|
|
45
|
+
## SDD evidence
|
|
46
|
+
|
|
47
|
+
${e(t.sddEvidence)}
|
|
48
|
+
`}async function wt(t){try{const r=await St(t);if(!r.ok)return r;const a=await pe(t),e=p(a.plan.storyId),o=await ae(a.directory,`${e}.c11.accepted.json`);if(!o||o.reviewSha256!==r.value.receipt.reviewSha256||o.qaSha256!==r.value.receipt.qaSha256)return i("legacy-story-pr-merge-review-drift");const c=Ne(o.reviewRaw,a),h=`.neocortex/stories/${a.plan.storyId}/review.md`;if(D(N(a.cwd,h)))return i("legacy-story-pr-merge-review-artifact-conflict");try{return u(a.cwd,"cat-file","-e",`${a.plan.headSha}:${h}`),i("legacy-story-pr-merge-review-artifact-conflict")}catch{}const l=Ye(c.report,o.reviewSha256,o.qaSha256);return{ok:!0,value:Object.freeze({schemaVersion:1,kind:"legacy-story-pr-merge-plan",storyId:a.plan.storyId,epicId:a.plan.epicId,repository:a.plan.repository,branch:a.plan.branch,baseBranch:a.plan.baseBranch,baseSha:a.plan.baseSha,originalHeadSha:a.plan.headSha,prNumber:t.prNumber,reviewArtifactPath:h,reviewArtifactSha256:p(l),reviewSha256:o.reviewSha256,qaSha256:o.qaSha256,stateSha256:o.stateAfter,storySha256:o.storyAfter,nextAuthority:"root-review-commit-and-new-head-qa-required",physicalMerge:!1,localOnly:!0})}}catch(r){const a=r instanceof Error?r.message:"";return i(a.startsWith("legacy-story-pr-")?a:"legacy-story-pr-merge-plan-failed")}}async function be(t,r){const a=N(t,r);if(!D(a))return null;await J(a,t);const e=m(JSON.parse(B(a,64*1024))),o=m(e?.plan);if(!e||e.schemaVersion!==1||e.kind!=="legacy-story-c12-review-commit-intent"||!o||o.kind!=="legacy-story-pr-merge-plan"||typeof o.reviewArtifactSha256!="string"||typeof e.reviewArtifact!="string"||p(e.reviewArtifact)!==o.reviewArtifactSha256)throw new Error("legacy-story-pr-merge-intent-invalid");return e}async function ve(t,r){const a=N(t,r);if(!D(a))return null;await J(a,t);const e=m(JSON.parse(B(a,4096)));if(!e||e.schemaVersion!==1||e.kind!=="legacy-story-c12-prepared"||typeof e.intentSha256!="string"||!/^[a-f0-9]{64}$/.test(e.intentSha256)||typeof e.candidateHeadSha!="string"||!/^[a-f0-9]{40}$/.test(e.candidateHeadSha)||typeof e.qaSha256!="string"||!/^[a-f0-9]{64}$/.test(e.qaSha256))throw new Error("legacy-story-pr-merge-prepared-journal-invalid");return e}function bt(t,r){const a=[N(t,".neocortex"),N(t,".neocortex/stories"),N(t,".neocortex/stories",r)];for(const e of a)if(D(e)||st(e,{mode:448}),!Z(e).isDirectory()||E(e)!==e)throw new Error("legacy-story-pr-merge-review-directory-unsafe");return a[2]}function $e(t){return[".neocortex/state.json",`docs/stories/${t.storyId}.story.md`,t.reviewArtifactPath].sort()}function ke(t,r,a){const e=r.plan;if(u(t,"rev-parse",`${a}^`)!==e.originalHeadSha||u(t,"rev-list","--count",`${e.originalHeadSha}..${a}`)!=="1")throw new Error("legacy-story-pr-merge-candidate-parent-invalid");const o=w(t,"diff-tree","--no-commit-id","--name-only","-r","-z",a).split("\0").filter(Boolean).sort();if(JSON.stringify(o)!==JSON.stringify($e(e))||p(w(t,"show",`${a}:.neocortex/state.json`))!==e.stateSha256||p(w(t,"show",`${a}:docs/stories/${e.storyId}.story.md`))!==e.storySha256||p(w(t,"show",`${a}:${e.reviewArtifactPath}`))!==e.reviewArtifactSha256||!w(t,"log","-1","--format=%B",a).split(`
|
|
49
|
+
`).map(c=>c.trim()).includes(`Neocortex-Legacy-Review: ${e.storyId}`))throw new Error("legacy-story-pr-merge-candidate-invalid")}function Oe(t,r,a,e){const o=r.plan;if(re(t)!==o.repository||u(t,"branch","--show-current")!==o.branch||R(t,o.baseBranch)!==o.baseSha||a.storyId!==o.storyId||a.reviewSha256!==o.reviewSha256||a.qaSha256!==o.qaSha256||a.stateAfter!==o.stateSha256||a.storyAfter!==o.storySha256)throw new Error("legacy-story-pr-merge-intent-drift");const c=u(t,"rev-parse","HEAD"),h=R(t,o.branch);if(c!==o.originalHeadSha&&ke(t,r,c),h!==o.originalHeadSha&&h!==c)throw new Error("legacy-story-pr-merge-remote-drift");const l={schemaVersion:1,kind:"legacy-story-pr-plan",storyId:o.storyId,epicId:o.epicId,repository:o.repository,branch:o.branch,baseBranch:o.baseBranch,baseSha:o.baseSha,headSha:h,qaAuthority:"root-review-required",localOnly:!0},y=de(l,e);if(!y||y.number!==o.prNumber)throw new Error("legacy-story-pr-merge-provider-drift");const s=B(N(t,".neocortex/state.json"),2*1024*1024),d=B(N(t,`docs/stories/${o.storyId}.story.md`),2*1024*1024);if(p(s)!==o.stateSha256||p(d)!==o.storySha256)throw new Error("legacy-story-pr-merge-checkpoint-drift");const n=w(t,"status","--porcelain=v1","-uall").split(`
|
|
50
|
+
`).filter(Boolean);if(c===o.originalHeadSha){const I=new Set($e(o));if(n.some(b=>!I.has(b.slice(3))||![" M","M ","MM","??","A "].includes(b.slice(0,2))))throw new Error("legacy-story-pr-merge-worktree-dirty")}else if(n.length>0)throw new Error("legacy-story-pr-merge-worktree-dirty");return{headSha:c,remoteSha:h}}async function Wt(t){if(!t.authorize)return i("legacy-story-pr-merge-authorization-required");if(!Number.isSafeInteger(t.prNumber)||t.prNumber<=0||!/^[A-Za-z0-9][A-Za-z0-9_-]*\.[A-Za-z0-9._-]+$/.test(t.storyId))return i("legacy-story-pr-merge-target-invalid");const r=`legacy-c12-prepare-${U(16).toString("hex")}`,a=await ee(t.projectRoot,{kind:"direct",storyId:t.storyId,sessionId:r,idempotencyKey:r,expiresAt:new Date(Date.now()+60*6e4).toISOString(),persistent:!1});if(!a.ok)return i(a.reasonCode);try{const e=E(t.projectRoot),o=await W(await F(e),"legacy-story-pr-intents"),c=p(t.storyId),h=await ae(o,`${c}.c11.json`),l=await ae(o,`${c}.c11.accepted.json`);if(!h||!l||JSON.stringify(h)!==JSON.stringify(l))return i("legacy-story-pr-merge-review-unaccepted");const y=`${c}.c12.json`,s=`${c}.c12.prepared.json`;let d=await be(o,y);if(!d){const C=await wt(t);if(!C.ok)return C;const S=await pe(t),O=Ne(l.reviewRaw,S),j=Ye(O.report,l.reviewSha256,l.qaSha256);d={schemaVersion:1,kind:"legacy-story-c12-review-commit-intent",plan:C.value,reviewArtifact:j},await z(o,y,`${JSON.stringify(d)}
|
|
51
|
+
`),await J(N(o,y),o)}const n=d.plan;if(n.storyId!==t.storyId||n.prNumber!==t.prNumber||p(d.reviewArtifact)!==n.reviewArtifactSha256)return i("legacy-story-pr-merge-intent-conflict");const I=t.provider??oe,b=async()=>Oe(e,d,l,await I.list(n.repository,n.branch,n.baseBranch));let f=await b();const k=p(JSON.stringify(d)),g=await ve(o,s);if(g)return g.intentSha256!==k||g.candidateHeadSha!==f.headSha||f.remoteSha!==f.headSha?i("legacy-story-pr-merge-prepared-conflict"):{ok:!0,value:Object.freeze({schemaVersion:1,kind:"legacy-story-c12-prepared",storyId:n.storyId,epicId:n.epicId,branch:n.branch,prNumber:n.prNumber,originalHeadSha:n.originalHeadSha,candidateHeadSha:g.candidateHeadSha,qaSha256:g.qaSha256,reused:!0,physicalMerge:!1,localOnly:!0})};if(f.headSha===n.originalHeadSha){if(f.remoteSha!==n.originalHeadSha)return i("legacy-story-pr-merge-remote-drift");const C=bt(e,n.storyId),S=N(C,"review.md");if(D(S)){if(Z(S).isSymbolicLink()||B(S,32*1024)!==d.reviewArtifact)return i("legacy-story-pr-merge-review-artifact-conflict")}else await z(C,"review.md",d.reviewArtifact);f=await b(),u(e,"add","--",...$e(n));const O=w(e,"diff","--cached","--name-only","-z").split("\0").filter(Boolean).sort();if(JSON.stringify(O)!==JSON.stringify($e(n))||p(w(e,"show",":.neocortex/state.json"))!==n.stateSha256||p(w(e,"show",`:docs/stories/${n.storyId}.story.md`))!==n.storySha256||p(w(e,"show",`:${n.reviewArtifactPath}`))!==n.reviewArtifactSha256||w(e,"diff","--name-only","-z")!=="")return i("legacy-story-pr-merge-staged-scope-invalid");u(e,"diff","--cached","--check"),u(e,"commit","-m",`chore(story): record reviewed PR ${n.storyId}`,"-m",`Neocortex-Legacy-Review: ${n.storyId}`),f=await b(),await t.afterCommit?.()}if(f.headSha===n.originalHeadSha)return i("legacy-story-pr-merge-commit-missing");const $={schemaVersion:1,kind:"legacy-story-pr-plan",storyId:n.storyId,epicId:n.epicId,repository:n.repository,branch:n.branch,baseBranch:n.baseBranch,headSha:f.headSha,baseSha:n.baseSha,qaAuthority:"root-review-required",localOnly:!0};let A;try{A=await se($,e,t.verifyQa)}catch{return i("legacy-story-pr-merge-new-head-qa-failed")}if(f=await b(),f.headSha===n.originalHeadSha)return i("legacy-story-pr-merge-candidate-raced");if(f.remoteSha===n.originalHeadSha&&u(e,"push","--porcelain","origin",`${f.headSha}:refs/heads/${n.branch}`),f=await b(),f.remoteSha!==f.headSha)return i("legacy-story-pr-merge-push-unverified");await t.afterPush?.();const v={schemaVersion:1,kind:"legacy-story-c12-prepared",intentSha256:k,candidateHeadSha:f.headSha,qaSha256:A};return await z(o,s,`${JSON.stringify(v)}
|
|
52
|
+
`),await J(N(o,s),o),{ok:!0,value:Object.freeze({schemaVersion:1,kind:"legacy-story-c12-prepared",storyId:n.storyId,epicId:n.epicId,branch:n.branch,prNumber:n.prNumber,originalHeadSha:n.originalHeadSha,candidateHeadSha:f.headSha,qaSha256:A,reused:!1,physicalMerge:!1,localOnly:!0})}}catch(e){const o=e instanceof Error?e.message:"";return i(o.startsWith("legacy-story-pr-")?o:"legacy-story-pr-merge-prepare-failed")}finally{await te(a.path,a.owner).catch(()=>{})}}function vt(t,r,a){const e=m(t);return!e||JSON.stringify(Object.keys(e).sort())!==JSON.stringify(["baseSha","blockingChecks","canMerge","candidateHeadSha","epicId","followUpDebt","kind","nonBlockingChecks","prNumber","remoteObservationDigest","reviewSha256","schemaVersion","storyId"].sort())?!1:e.schemaVersion===1&&e.kind==="legacy-story-c12-root-merge-decision"&&e.storyId===r.storyId&&e.epicId===r.epicId&&e.prNumber===r.prNumber&&e.candidateHeadSha===a&&e.baseSha===r.baseSha&&e.reviewSha256===r.reviewSha256&&typeof e.remoteObservationDigest=="string"&&/^[a-f0-9]{64}$/.test(e.remoteObservationDigest)&&e.canMerge===!0&&Array.isArray(e.blockingChecks)&&e.blockingChecks.length===0&&Array.isArray(e.nonBlockingChecks)&&e.nonBlockingChecks.length===0&&Array.isArray(e.followUpDebt)&&e.followUpDebt.length===0}async function _e(t,r){const a=N(t,r);if(!D(a))return null;await J(a,t);const e=m(JSON.parse(B(a,4096)));if(!e||e.schemaVersion!==1||e.kind!=="legacy-story-c12-merge-attempt"||typeof e.intentSha256!="string"||!/^[a-f0-9]{64}$/.test(e.intentSha256)||typeof e.candidateHeadSha!="string"||!/^[a-f0-9]{40}$/.test(e.candidateHeadSha)||typeof e.qaSha256!="string"||!/^[a-f0-9]{64}$/.test(e.qaSha256)||typeof e.remoteObservationDigest!="string"||!/^[a-f0-9]{64}$/.test(e.remoteObservationDigest))throw new Error("legacy-story-pr-merge-attempt-invalid");return e}async function xe(t,r){const a=N(t,r);if(!D(a))return null;await J(a,t);const e=m(JSON.parse(B(a,4096)));if(!e||e.schemaVersion!==1||e.kind!=="legacy-story-c12-merged"||typeof e.intentSha256!="string"||!/^[a-f0-9]{64}$/.test(e.intentSha256)||typeof e.candidateHeadSha!="string"||!/^[a-f0-9]{40}$/.test(e.candidateHeadSha)||typeof e.qaSha256!="string"||!/^[a-f0-9]{64}$/.test(e.qaSha256)||typeof e.remoteObservationDigest!="string"||!/^[a-f0-9]{64}$/.test(e.remoteObservationDigest)||typeof e.mergeCommitSha!="string"||!/^[a-f0-9]{40}$/.test(e.mergeCommitSha)||typeof e.baseHeadSha!="string"||!/^[a-f0-9]{40}$/.test(e.baseHeadSha))throw new Error("legacy-story-pr-merge-journal-invalid");return e}function ie(t,r,a,e){if(a.number!==t.prNumber||a.state!==e||a.headRefName!==t.branch||a.headRefOid!==r||a.baseRefName!==t.baseBranch||a.url.toLowerCase()!==`https://github.com/${t.repository}/pull/${t.prNumber}`.toLowerCase())throw new Error("legacy-story-pr-merge-provider-drift");if(e==="OPEN"&&(a.baseRefOid!==t.baseSha||a.isDraft!==!1||a.mergeable!=="MERGEABLE"))throw new Error("legacy-story-pr-merge-provider-not-ready")}function Ue(t){const r=qe(t.statusCheckRollup);if(!r.ok||r.value.reasonCodes.length>0)throw new Error("legacy-story-pr-merge-remote-observation-unclassified");return r.value}function It(t,r,a,e){const o=r.plan;ie(o,a.candidateHeadSha,e,"MERGED");const c=e.mergeCommit?.oid;if(!c||!/^[a-f0-9]{40}$/.test(c)||u(t,"rev-parse","HEAD")!==a.candidateHeadSha||w(t,"status","--porcelain=v1","-uall")!=="")throw new Error("legacy-story-pr-merge-physical-invalid");ke(t,r,a.candidateHeadSha),u(t,"fetch","--no-tags","origin",`refs/heads/${o.baseBranch}`);const h=u(t,"rev-parse","FETCH_HEAD");if(R(t,o.baseBranch)!==h||!/^[a-f0-9]{40}$/.test(h))throw new Error("legacy-story-pr-merge-base-readback-drift");const l=u(t,"rev-list","--parents","-n","1",c).split(" ");if(l.length!==3||l[0]!==c||l[1]!==o.baseSha||l[2]!==a.candidateHeadSha)throw new Error("legacy-story-pr-merge-commit-parent-invalid");return u(t,"merge-base","--is-ancestor",c,h),{mergeCommitSha:c,baseHeadSha:h}}async function Xe(t){if(!Number.isSafeInteger(t.prNumber)||t.prNumber<=0||!/^[A-Za-z0-9][A-Za-z0-9_-]*\.[A-Za-z0-9._-]+$/.test(t.storyId))return i("legacy-story-pr-merge-target-invalid");try{const r=E(t.projectRoot),a=u(r,"rev-parse","--git-common-dir"),e=E(Ce(a)?a:N(r,a)),o=N(e,"neocortex-yoloop"),c=N(o,"legacy-story-pr-intents");if(!D(o)||!D(c))return i("legacy-story-pr-merge-not-prepared");if(!Z(o).isDirectory()||E(o)!==o)return i("legacy-story-pr-merge-runtime-unsafe");await ze(c,o);const h=p(t.storyId),l=await be(c,`${h}.c12.json`),y=await ve(c,`${h}.c12.prepared.json`),s=await ae(c,`${h}.c11.accepted.json`);if(!l||!y||!s)return i("legacy-story-pr-merge-not-prepared");const d=l.plan;if(d.storyId!==t.storyId||d.prNumber!==t.prNumber||y.intentSha256!==p(JSON.stringify(l))||s.reviewSha256!==d.reviewSha256||s.qaSha256!==d.qaSha256)return i("legacy-story-pr-merge-prepared-drift");const n=Oe(r,l,s,await(t.provider??oe).list(d.repository,d.branch,d.baseBranch));if(n.headSha!==y.candidateHeadSha||n.remoteSha!==y.candidateHeadSha)return i("legacy-story-pr-merge-remote-drift");ke(r,l,y.candidateHeadSha);const I=await(t.mergeProvider??Se).view(d.repository,d.prNumber);ie(d,y.candidateHeadSha,I,"OPEN");const b=qe(I.statusCheckRollup);if(!b.ok)return i("legacy-story-pr-merge-remote-observation-unclassified");const f=b.value;return f.reasonCodes.length>0?{ok:!0,value:Object.freeze({schemaVersion:1,kind:"legacy-story-c12-remote-debt-required",storyId:d.storyId,epicId:d.epicId,prNumber:d.prNumber,candidateHeadSha:y.candidateHeadSha,baseSha:d.baseSha,reviewSha256:d.reviewSha256,remoteObservationDigest:f.digest,reasonCodes:f.reasonCodes,reasonCounts:f.reasonCounts,canMerge:!1,publicSafe:!0})}:{ok:!0,value:Object.freeze({schemaVersion:1,kind:"legacy-story-c12-root-merge-decision",storyId:d.storyId,epicId:d.epicId,prNumber:d.prNumber,candidateHeadSha:y.candidateHeadSha,baseSha:d.baseSha,reviewSha256:d.reviewSha256,remoteObservationDigest:f.digest,canMerge:!0,blockingChecks:[],nonBlockingChecks:[],followUpDebt:[]})}}catch(r){const a=r instanceof Error?r.message:"";return i(a.startsWith("legacy-story-pr-")?a:"legacy-story-pr-merge-decision-uncertain")}}async function Ft(t){if(!Number.isSafeInteger(t.prNumber)||t.prNumber<=0||!/^[A-Za-z0-9][A-Za-z0-9_-]*\.[A-Za-z0-9._-]+$/.test(t.storyId))return i("legacy-story-pr-merge-target-invalid");const r=await Xe(t);if(!r.ok)return i(r.reasonCode);if(r.value.canMerge)return i("legacy-story-pr-merge-remote-debt-not-required");const a=`legacy-c12-remote-debt-${U(16).toString("hex")}`,e=await ee(t.projectRoot,{kind:"direct",storyId:t.storyId,sessionId:a,idempotencyKey:a,expiresAt:new Date(Date.now()+5*6e4).toISOString(),persistent:!1});if(!e.ok)return i(e.reasonCode);try{const o=await Xe(t);if(!o.ok)return i(o.reasonCode);if(o.value.canMerge)return i("legacy-story-pr-merge-remote-debt-not-required");if(JSON.stringify(o.value)!==JSON.stringify(r.value))return i("legacy-story-pr-merge-remote-debt-observation-drift");const c=o.value,h=E(t.projectRoot),l=await W(await F(h),"legacy-story-pr-intents"),y={schemaVersion:1,kind:"legacy-story-c12-remote-debt-observation",planSha256:p(JSON.stringify(c)),storyId:c.storyId,epicId:c.epicId,prNumber:c.prNumber,candidateHeadSha:c.candidateHeadSha,remoteObservationDigest:c.remoteObservationDigest,reasonCodes:c.reasonCodes,reasonCounts:c.reasonCounts},s=`${p(c.storyId)}.${c.candidateHeadSha}.${c.remoteObservationDigest}.c12.remote-debt.json`,d=N(l,s),n=D(d);if(n){await J(d,l);const I=m(JSON.parse(B(d,4096)));if(!I||JSON.stringify(I)!==JSON.stringify(y))return i("legacy-story-pr-merge-remote-debt-journal-conflict")}else await z(l,s,`${JSON.stringify(y)}
|
|
53
|
+
`),await J(d,l);return{ok:!0,value:Object.freeze({schemaVersion:1,kind:"legacy-story-c12-remote-debt-journaled",storyId:c.storyId,epicId:c.epicId,prNumber:c.prNumber,candidateHeadSha:c.candidateHeadSha,remoteObservationDigest:c.remoteObservationDigest,reasonCodes:c.reasonCodes,reasonCounts:c.reasonCounts,reused:n,durableObservation:!0,registryRecorded:!1,canMerge:!1,publicSafe:!0})}}catch(o){const c=o instanceof Error?o.message:"";return i(c.startsWith("legacy-story-pr-")?c:"legacy-story-pr-merge-remote-debt-uncertain")}finally{await te(e.path,e.owner).catch(()=>{})}}async function Tt(t){if(!t.authorize)return i("legacy-story-pr-merge-authorization-required");if(!Number.isSafeInteger(t.prNumber)||t.prNumber<=0||!/^[A-Za-z0-9][A-Za-z0-9_-]*\.[A-Za-z0-9._-]+$/.test(t.storyId))return i("legacy-story-pr-merge-target-invalid");const r=`legacy-c12-merge-${U(16).toString("hex")}`,a=await ee(t.projectRoot,{kind:"direct",storyId:t.storyId,sessionId:r,idempotencyKey:r,expiresAt:new Date(Date.now()+60*6e4).toISOString(),persistent:!1});if(!a.ok)return i(a.reasonCode);try{const e=E(t.projectRoot),o=await W(await F(e),"legacy-story-pr-intents"),c=p(t.storyId),h=await be(o,`${c}.c12.json`),l=await ve(o,`${c}.c12.prepared.json`),y=await ae(o,`${c}.c11.accepted.json`);if(!h||!l||!y)return i("legacy-story-pr-merge-not-prepared");const s=h.plan,d=p(JSON.stringify(h));if(s.storyId!==t.storyId||s.prNumber!==t.prNumber||l.intentSha256!==d||re(e)!==s.repository||u(e,"branch","--show-current")!==s.branch||u(e,"rev-parse","HEAD")!==l.candidateHeadSha||y.reviewSha256!==s.reviewSha256||y.qaSha256!==s.qaSha256||y.stateAfter!==s.stateSha256||y.storyAfter!==s.storySha256||p(B(N(e,".neocortex/state.json"),2*1024*1024))!==s.stateSha256||p(B(N(e,`docs/stories/${s.storyId}.story.md`),2*1024*1024))!==s.storySha256||w(e,"status","--porcelain=v1","-uall")!=="")return i("legacy-story-pr-merge-prepared-drift");ke(e,h,l.candidateHeadSha);const n=`${c}.c12.merge-attempt.json`,I=`${c}.c12.merged.json`,b=await _e(o,n),f=await xe(o,I),k=t.mergeProvider??Se,g=t.rootDecision;if((!b||g)&&!vt(g,s,l.candidateHeadSha))return i("legacy-story-pr-merge-root-decision-required");if(b&&(b.intentSha256!==d||b.candidateHeadSha!==l.candidateHeadSha||g&&b.remoteObservationDigest!==g.remoteObservationDigest))return i("legacy-story-pr-merge-attempt-conflict");if(f&&(!b||f.intentSha256!==d||f.candidateHeadSha!==l.candidateHeadSha||f.qaSha256!==b.qaSha256||f.remoteObservationDigest!==b.remoteObservationDigest))return i("legacy-story-pr-merge-journal-conflict");if(!b){if(!g)return i("legacy-story-pr-merge-root-decision-required");const C=t.provider??oe,S=Oe(e,h,y,await C.list(s.repository,s.branch,s.baseBranch));if(S.headSha!==l.candidateHeadSha||S.remoteSha!==l.candidateHeadSha)return i("legacy-story-pr-merge-remote-drift");const O=await k.view(s.repository,s.prNumber);if(ie(s,l.candidateHeadSha,O,"OPEN"),Ue(O).digest!==g.remoteObservationDigest)return i("legacy-story-pr-merge-remote-observation-drift");const H={schemaVersion:1,kind:"legacy-story-pr-plan",storyId:s.storyId,epicId:s.epicId,repository:s.repository,branch:s.branch,baseBranch:s.baseBranch,headSha:l.candidateHeadSha,baseSha:s.baseSha,qaAuthority:"root-review-required",localOnly:!0};let x;try{x=await se(H,e,t.verifyQa)}catch{return i("legacy-story-pr-merge-final-qa-failed")}const q=Oe(e,h,y,await C.list(s.repository,s.branch,s.baseBranch));if(q.headSha!==l.candidateHeadSha||q.remoteSha!==l.candidateHeadSha)return i("legacy-story-pr-merge-remote-drift");const L=await k.view(s.repository,s.prNumber);ie(s,l.candidateHeadSha,L,"OPEN");const _=Ue(L);if(_.digest!==g.remoteObservationDigest)return i("legacy-story-pr-merge-remote-observation-drift");const M={schemaVersion:1,kind:"legacy-story-c12-merge-attempt",intentSha256:d,candidateHeadSha:l.candidateHeadSha,qaSha256:x,remoteObservationDigest:_.digest};await z(o,n,`${JSON.stringify(M)}
|
|
54
|
+
`),await J(N(o,n),o);try{await k.merge(s.repository,s.prNumber,l.candidateHeadSha)}catch{}await t.afterMerge?.()}const $=b??await _e(o,n);if(!$)return i("legacy-story-pr-merge-attempt-missing");const A=await k.view(s.repository,s.prNumber);if(A.state!=="MERGED")return i("legacy-story-pr-merge-effect-not-confirmed");const v=It(e,h,l,A);if(f){if(f.mergeCommitSha!==v.mergeCommitSha)return i("legacy-story-pr-merge-journal-conflict");u(e,"merge-base","--is-ancestor",f.baseHeadSha,v.baseHeadSha)}else{const C={...$,kind:"legacy-story-c12-merged",mergeCommitSha:v.mergeCommitSha,baseHeadSha:v.baseHeadSha};await z(o,I,`${JSON.stringify(C)}
|
|
55
|
+
`),await J(N(o,I),o)}return{ok:!0,value:Object.freeze({schemaVersion:1,kind:"legacy-story-c12-merged",storyId:s.storyId,epicId:s.epicId,prNumber:s.prNumber,branch:s.branch,candidateHeadSha:l.candidateHeadSha,mergeCommitSha:v.mergeCommitSha,baseHeadSha:v.baseHeadSha,qaSha256:$.qaSha256,remoteObservationDigest:$.remoteObservationDigest,reused:!!f,physicalMerge:!0,checkpointAccepted:!1,localOnly:!0})}}catch(e){const o=e instanceof Error?e.message:"";return i(o.startsWith("legacy-story-pr-")?o:"legacy-story-pr-merge-effect-uncertain")}finally{await te(a.path,a.owner).catch(()=>{})}}const et={async view(t,r){const a=K("gh",["issue","view",String(r),"--repo",t,"--json","number,title,state,url"],{encoding:"utf8",timeout:15e3,stdio:["ignore","pipe","pipe"],maxBuffer:16384});return JSON.parse(a)},async close(t,r){K("gh",["issue","close",String(r),"--repo",t,"--reason","completed"],{encoding:"utf8",timeout:3e4,stdio:["ignore","pipe","pipe"],maxBuffer:16*1024})}};function tt(t,r,a){const e=w(t,"show",`${r.mergeCommitSha}:.neocortex/state.json`),o=`docs/stories/${r.storyId}.story.md`,c=w(t,"show",`${r.mergeCommitSha}:${o}`);if(p(e)!==r.stateSha256||p(c)!==r.storySha256)throw new Error("legacy-story-pr-post-merge-preimage-drift");const h=m(JSON.parse(e)),l=m(h?.stories),y=m(h?.epics),s=m(l?.[r.storyId]),d=m(y?.[r.epicId]),n=s?.steps_completed,I=d?.stories;if(!s||!d||d.id!==r.epicId||s.id!==r.storyId||s.epic_id!==r.epicId||s.status!=="pr-reviewed"||s.last_step!==Y||s.pr_number!==r.prNumber||s.issue_number!==r.issueNumber||s.branch_name!==`story/${r.epicId}/${r.storyId}`||!Array.isArray(n)||!n.includes(Y)||n.includes(ge)||!Array.isArray(I)||!I.includes(r.storyId)||new Set(I).size!==I.length||I.some(j=>typeof j!="string"||m(l?.[j])?.epic_id!==r.epicId))throw new Error("legacy-story-pr-post-merge-state-conflict");s.status="done",s.last_step=ge,s.steps_completed=[...n,ge],s.merged=!0,s.physicalMergeStatus="merged",s.merge_commit_sha=r.mergeCommitSha,s.issue_state="closed";const b=I.filter(j=>m(l?.[j])?.status==="done").length;if(d.total_stories=I.length,d.completed_stories=b,b===I.length)d.status="done",d.completed_at==null&&(d.completed_at=a);else if(d.status==="done")throw new Error("legacy-story-pr-post-merge-epic-conflict");const f=`${JSON.stringify(h,null,2)}
|
|
56
|
+
`,k=c.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n/);if(!k)throw new Error("legacy-story-pr-post-merge-frontmatter-invalid");const g=X(k[1],{strict:!0,uniqueKeys:!0}),$=m(g.toJS()),A=["stepsCompleted","steps_completed"].filter(j=>g.has(j)),v=["lastStep","last_step"].filter(j=>g.has(j)),C=["issueNumber","issue_number"].filter(j=>g.has(j)),S=["prNumber","pr_number"].filter(j=>g.has(j));if(g.errors.length>0||g.get("id")!==r.storyId||(g.get("epic_id")??g.get("epic"))!==r.epicId||g.get("status")!=="pr-reviewed"||g.has("currentStatus")&&g.get("currentStatus")!=="pr-reviewed"||A.length!==1||v.length!==1||C.length>1||S.length>1||JSON.stringify($?.[A[0]])!==JSON.stringify(n)||$?.[v[0]]!==Y||C.length===1&&$?.[C[0]]!==r.issueNumber||S.length===1&&$?.[S[0]]!==r.prNumber)throw new Error("legacy-story-pr-post-merge-frontmatter-conflict");g.set("status","done"),g.has("currentStatus")&&g.set("currentStatus","done"),g.set(A[0],[...n,ge]),g.set(v[0],ge),g.set("mergeCommitSha",r.mergeCommitSha),g.set("issueState","closed");const O=`---
|
|
57
|
+
${g.toString({lineWidth:0})}---
|
|
58
|
+
${c.slice(k[0].length)}`;return{stateBefore:e,stateAfter:f,storyBefore:c,storyAfter:O}}async function At(t){if(!Number.isSafeInteger(t.prNumber)||t.prNumber<=0||!/^[A-Za-z0-9][A-Za-z0-9_-]*\.[A-Za-z0-9._-]+$/.test(t.storyId))return i("legacy-story-pr-post-merge-target-invalid");try{const r=E(t.projectRoot);if(E(u(r,"rev-parse","--show-toplevel"))!==r||w(r,"status","--porcelain=v1","-uall")!=="")return i("legacy-story-pr-post-merge-checkout-invalid");const a=u(r,"rev-parse","--git-common-dir"),e=E(Ce(a)?a:N(r,a)),o=N(e,"neocortex-yoloop"),c=N(o,"legacy-story-pr-intents");if(!D(o)||!D(c))return i("legacy-story-pr-post-merge-not-journaled");if(!Z(o).isDirectory()||E(o)!==o)return i("legacy-story-pr-post-merge-runtime-unsafe");await ze(c,o);const h=p(t.storyId),l=await be(c,`${h}.c12.json`),y=await ve(c,`${h}.c12.prepared.json`),s=await _e(c,`${h}.c12.merge-attempt.json`),d=await xe(c,`${h}.c12.merged.json`);if(!l||!y||!s||!d)return i("legacy-story-pr-post-merge-not-journaled");const n=l.plan;if(n.storyId!==t.storyId||n.prNumber!==t.prNumber||y.intentSha256!==p(JSON.stringify(l))||s.intentSha256!==y.intentSha256||d.intentSha256!==s.intentSha256||s.candidateHeadSha!==y.candidateHeadSha||d.candidateHeadSha!==s.candidateHeadSha||d.qaSha256!==s.qaSha256||d.remoteObservationDigest!==s.remoteObservationDigest||re(r)!==n.repository||u(r,"branch","--show-current")!==n.baseBranch)return i("legacy-story-pr-post-merge-journal-drift");const I=u(r,"rev-parse","HEAD");if(I!==d.mergeCommitSha||R(r,n.baseBranch)!==I)return i("legacy-story-pr-post-merge-base-drift");const b=await(t.mergeProvider??Se).view(n.repository,n.prNumber);if(ie(n,y.candidateHeadSha,b,"MERGED"),b.mergeCommit?.oid!==d.mergeCommitSha)return i("legacy-story-pr-post-merge-provider-drift");const f=u(r,"rev-list","--parents","-n","1",I).split(" ");if(f.length!==3||f[0]!==I||f[1]!==n.baseSha||f[2]!==y.candidateHeadSha)return i("legacy-story-pr-post-merge-parents-invalid");const k=w(r,"show","HEAD:.neocortex/state.json"),g=`docs/stories/${n.storyId}.story.md`,$=w(r,"show",`HEAD:${g}`);if(p(k)!==n.stateSha256||p($)!==n.storySha256||B(N(r,".neocortex/state.json"),2*1024*1024)!==k||B(N(r,g),2*1024*1024)!==$)return i("legacy-story-pr-post-merge-content-drift");const A=m(JSON.parse(k)),v=m(m(A?.stories)?.[n.storyId]),C=v?.issue_number;if(!v||v.id!==n.storyId||v.epic_id!==n.epicId||v.status!=="pr-reviewed"||v.last_step!==Y||v.pr_number!==n.prNumber||v.branch_name!==n.branch||!Array.isArray(v.steps_completed)||!v.steps_completed.includes(Y)||!Number.isSafeInteger(C)||C<=0)return i("legacy-story-pr-post-merge-state-invalid");const S=$.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n/);if(!S)return i("legacy-story-pr-post-merge-frontmatter-invalid");const O=X(S[1],{strict:!0,uniqueKeys:!0});if(O.errors.length>0||O.get("id")!==n.storyId||(O.get("epic_id")??O.get("epic"))!==n.epicId||O.get("status")!=="pr-reviewed")return i("legacy-story-pr-post-merge-frontmatter-invalid");const j=await(t.issueProvider??et).view(n.repository,C);return j.number!==C||j.state!=="OPEN"||j.title!==`[YOLO] Story ${n.storyId} - Workflow Run`||j.url.toLowerCase()!==`https://github.com/${n.repository}/issues/${C}`.toLowerCase()?i("legacy-story-pr-post-merge-issue-invalid"):{ok:!0,value:Object.freeze({schemaVersion:1,kind:"legacy-story-c12-post-merge-plan",storyId:n.storyId,epicId:n.epicId,repository:n.repository,baseBranch:n.baseBranch,prNumber:n.prNumber,issueNumber:C,candidateHeadSha:y.candidateHeadSha,mergeCommitSha:d.mergeCommitSha,stateSha256:n.stateSha256,storySha256:n.storySha256,nextAuthority:"root-state-checkpoint-and-issue-closure-required",checkpointAccepted:!1,localOnly:!0})}}catch(r){const a=r instanceof Error?r.message:"";return i(a.startsWith("legacy-story-pr-")?a:"legacy-story-pr-post-merge-physical-unavailable")}}async function Nt(t,r){const a=N(t,r);if(!D(a))return null;await J(a,t);const e=m(JSON.parse(B(a,8192))),o=m(e?.plan);if(!e||e.schemaVersion!==1||e.kind!=="legacy-story-c12-post-merge-intent"||!o||o.schemaVersion!==1||o.kind!=="legacy-story-c12-post-merge-plan"||typeof e.nowIso!="string"||!Number.isFinite(Date.parse(e.nowIso))||typeof e.stateAfterSha256!="string"||!/^[a-f0-9]{64}$/.test(e.stateAfterSha256)||typeof e.storyAfterSha256!="string"||!/^[a-f0-9]{64}$/.test(e.storyAfterSha256))throw new Error("legacy-story-pr-post-merge-intent-invalid");return e}async function $t(t,r){const a=N(t,r);if(!D(a))return null;await J(a,t);const e=m(JSON.parse(B(a,4096)));if(!e||e.schemaVersion!==1||e.kind!=="legacy-story-c12-post-merge-accepted"||typeof e.intentSha256!="string"||!/^[a-f0-9]{64}$/.test(e.intentSha256)||typeof e.checkpointHeadSha!="string"||!/^[a-f0-9]{40}$/.test(e.checkpointHeadSha)||typeof e.qaSha256!="string"||!/^[a-f0-9]{64}$/.test(e.qaSha256))throw new Error("legacy-story-pr-post-merge-accepted-invalid");return e}async function Gt(t){if(!t.authorize)return i("legacy-story-pr-post-merge-authorization-required");if(!Number.isSafeInteger(t.prNumber)||t.prNumber<=0||!/^[A-Za-z0-9][A-Za-z0-9_-]*\.[A-Za-z0-9._-]+$/.test(t.storyId))return i("legacy-story-pr-post-merge-target-invalid");const r=`legacy-c12-post-merge-${U(16).toString("hex")}`,a=await ee(t.projectRoot,{kind:"direct",storyId:t.storyId,sessionId:r,idempotencyKey:r,expiresAt:new Date(Date.now()+60*6e4).toISOString(),persistent:!1});if(!a.ok)return i(a.reasonCode);try{const e=E(t.projectRoot);if(E(u(e,"rev-parse","--show-toplevel"))!==e)return i("legacy-story-pr-post-merge-checkout-invalid");const o=await W(await F(e),"legacy-story-pr-intents"),c=p(t.storyId),h=`${c}.c12.post-merge.json`,l=`${c}.c12.post-merge.accepted.json`;let y=await Nt(o,h);if(!y){const P=await At(t);if(!P.ok)return P;const De=new Date().toISOString(),He=tt(e,P.value,De);y={schemaVersion:1,kind:"legacy-story-c12-post-merge-intent",plan:P.value,nowIso:De,stateAfterSha256:p(He.stateAfter),storyAfterSha256:p(He.storyAfter)},await z(o,h,`${JSON.stringify(y)}
|
|
59
|
+
`),await J(N(o,h),o)}const s=y.plan,d=await be(o,`${c}.c12.json`),n=await ve(o,`${c}.c12.prepared.json`),I=await _e(o,`${c}.c12.merge-attempt.json`),b=await xe(o,`${c}.c12.merged.json`);if(!d||!n||!I||!b||s.storyId!==t.storyId||s.prNumber!==t.prNumber||s.repository!==d.plan.repository||s.epicId!==d.plan.epicId||s.baseBranch!==d.plan.baseBranch||s.candidateHeadSha!==n.candidateHeadSha||s.mergeCommitSha!==b.mergeCommitSha||s.stateSha256!==d.plan.stateSha256||s.storySha256!==d.plan.storySha256||n.intentSha256!==p(JSON.stringify(d))||I.intentSha256!==n.intentSha256||b.intentSha256!==I.intentSha256||b.qaSha256!==I.qaSha256||b.remoteObservationDigest!==I.remoteObservationDigest||re(e)!==s.repository||u(e,"branch","--show-current")!==s.baseBranch)return i("legacy-story-pr-post-merge-intent-drift");const f=tt(e,s,y.nowIso);if(p(f.stateAfter)!==y.stateAfterSha256||p(f.storyAfter)!==y.storyAfterSha256)return i("legacy-story-pr-post-merge-projection-drift");const k=await(t.mergeProvider??Se).view(s.repository,s.prNumber);if(ie(d.plan,n.candidateHeadSha,k,"MERGED"),k.mergeCommit?.oid!==s.mergeCommitSha)return i("legacy-story-pr-post-merge-provider-drift");const g=u(e,"rev-list","--parents","-n","1",s.mergeCommitSha).split(" ");if(g.length!==3||g[0]!==s.mergeCommitSha||g[1]!==d.plan.baseSha||g[2]!==s.candidateHeadSha)return i("legacy-story-pr-post-merge-parents-invalid");const $=await $t(o,l),A=p(JSON.stringify(y));if($&&$.intentSha256!==A)return i("legacy-story-pr-post-merge-accepted-conflict");const v=u(e,"rev-parse","HEAD");let C=R(e,s.baseBranch);if(w(e,"status","--porcelain=v1","-uall")!=="")return i("legacy-story-pr-post-merge-base-worktree-dirty");const S=N(o,`${c}.c12.post-merge.checkout`);if(D(S)||K("git",["worktree","add","--detach",S,$?.checkpointHeadSha??s.mergeCommitSha],{cwd:e,encoding:"utf8",timeout:6e4,stdio:["ignore","pipe","pipe"],maxBuffer:32*1024}),!Z(S).isDirectory()||E(S)!==S||E(u(S,"rev-parse","--show-toplevel"))!==S||Ie(S)!==Ie(e)||u(S,"branch","--show-current")!=="")return i("legacy-story-pr-post-merge-candidate-checkout-invalid");let O=u(S,"rev-parse","HEAD");if(O!==s.mergeCommitSha&&(u(S,"rev-parse",`${O}^`)!==s.mergeCommitSha||JSON.stringify(w(S,"diff-tree","--no-commit-id","--name-only","-r","-z",O).split("\0").filter(Boolean).sort())!==JSON.stringify([".neocortex/state.json",`docs/stories/${s.storyId}.story.md`].sort())||p(w(S,"show",`${O}:.neocortex/state.json`))!==y.stateAfterSha256||p(w(S,"show",`${O}:docs/stories/${s.storyId}.story.md`))!==y.storyAfterSha256||!w(S,"log","-1","--format=%B",O).split(`
|
|
60
|
+
`).map(P=>P.trim()).includes(`Neocortex-Legacy-Merge: ${s.storyId}`)))return i("legacy-story-pr-post-merge-checkpoint-commit-invalid");if(![s.mergeCommitSha,O].includes(v)||![s.mergeCommitSha,O].includes(C)||$&&($.checkpointHeadSha!==O||C!==O))return i("legacy-story-pr-post-merge-base-drift");const j=w(S,"status","--porcelain=v1","-uall").split(`
|
|
61
|
+
`).filter(Boolean),H=new Set([".neocortex/state.json",`docs/stories/${s.storyId}.story.md`]);if(O!==s.mergeCommitSha&&j.length>0||j.some(P=>!H.has(P.slice(3))||![" M","M ","MM"].includes(P.slice(0,2))))return i("legacy-story-pr-post-merge-worktree-dirty");const x=B(N(S,".neocortex/state.json"),2*1024*1024),q=B(N(S,`docs/stories/${s.storyId}.story.md`),2*1024*1024);if(![f.stateBefore,f.stateAfter].includes(x)||![f.storyBefore,f.storyAfter].includes(q)||O!==s.mergeCommitSha&&(x!==f.stateAfter||q!==f.storyAfter))return i("legacy-story-pr-post-merge-content-drift");const L=t.issueProvider??et,_=async()=>{const P=await L.view(s.repository,s.issueNumber);if(P.number!==s.issueNumber||P.title!==`[YOLO] Story ${s.storyId} - Workflow Run`||P.url.toLowerCase()!==`https://github.com/${s.repository}/issues/${s.issueNumber}`.toLowerCase()||!["OPEN","CLOSED"].includes(P.state))throw new Error("legacy-story-pr-post-merge-issue-invalid");return P.state};if($&&await _()!=="CLOSED")return i("legacy-story-pr-post-merge-accepted-issue-drift");if(!$&&v===s.mergeCommitSha&&C===s.mergeCommitSha){if(j.length>0)return i("legacy-story-pr-post-merge-pre-issue-drift");const P={schemaVersion:1,kind:"legacy-story-pr-plan",storyId:s.storyId,epicId:s.epicId,repository:s.repository,branch:s.baseBranch,baseBranch:s.baseBranch,headSha:s.mergeCommitSha,baseSha:d.plan.baseSha,qaAuthority:"root-review-required",localOnly:!0};try{await se(P,e,t.verifyQa)}catch{return i("legacy-story-pr-post-merge-pre-issue-qa-failed")}if(u(e,"rev-parse","HEAD")!==s.mergeCommitSha||R(e,s.baseBranch)!==s.mergeCommitSha||w(e,"status","--porcelain=v1","-uall")!=="")return i("legacy-story-pr-post-merge-pre-issue-drift")}if(O===s.mergeCommitSha){if(x===f.stateBefore&&await G(N(S,".neocortex"),"state.json",f.stateAfter,p(f.stateBefore)),q===f.storyBefore&&await G(N(S,"docs/stories"),`${s.storyId}.story.md`,f.storyAfter,p(f.storyBefore)),B(N(S,".neocortex/state.json"),2*1024*1024)!==f.stateAfter||B(N(S,`docs/stories/${s.storyId}.story.md`),2*1024*1024)!==f.storyAfter)return i("legacy-story-pr-post-merge-write-drift");u(S,"add","--",".neocortex/state.json",`docs/stories/${s.storyId}.story.md`);const P=w(S,"diff","--cached","--name-only","-z").split("\0").filter(Boolean).sort();if(JSON.stringify(P)!==JSON.stringify([...H].sort())||w(S,"diff","--name-only","-z")!=="")return i("legacy-story-pr-post-merge-staged-scope-invalid");u(S,"diff","--cached","--check"),u(S,"commit","-m",`chore(story): accept merged PR ${s.storyId}`,"-m",`Neocortex-Legacy-Merge: ${s.storyId}`),O=u(S,"rev-parse","HEAD"),await t.afterCommit?.()}if(w(S,"status","--porcelain=v1","-uall")!=="")return i("legacy-story-pr-post-merge-worktree-dirty");const M={schemaVersion:1,kind:"legacy-story-pr-plan",storyId:s.storyId,epicId:s.epicId,repository:s.repository,branch:s.baseBranch,baseBranch:s.baseBranch,headSha:O,baseSha:s.mergeCommitSha,qaAuthority:"root-review-required",localOnly:!0};let ce=$?.qaSha256;if(!ce){if(!t.verifyQa)try{Ze(S)}catch(P){return i(P instanceof Error&&P.message.endsWith("-missing")?"legacy-story-pr-post-merge-dependencies-missing":"legacy-story-pr-post-merge-dependencies-failed")}try{ce=await se(M,S,t.verifyQa)}catch{return i("legacy-story-pr-post-merge-qa-failed")}}if(u(S,"rev-parse","HEAD")!==O||w(S,"status","--porcelain=v1","-uall")!==""||u(e,"rev-parse","HEAD")!==v||w(e,"status","--porcelain=v1","-uall")!=="")return i("legacy-story-pr-post-merge-final-drift");if(await _()==="OPEN"){if(R(e,s.baseBranch)!==s.mergeCommitSha)return i("legacy-story-pr-post-merge-pre-issue-drift");await L.close(s.repository,s.issueNumber),await t.afterIssueClose?.()}if(await _()!=="CLOSED")return i("legacy-story-pr-post-merge-issue-not-closed");const ue=await(t.mergeProvider??Se).view(s.repository,s.prNumber);if(ie(d.plan,n.candidateHeadSha,ue,"MERGED"),ue.mergeCommit?.oid!==s.mergeCommitSha)return i("legacy-story-pr-post-merge-provider-drift");if(C=R(e,s.baseBranch),C===s.mergeCommitSha&&u(e,"push","--porcelain","origin",`${O}:refs/heads/${s.baseBranch}`),R(e,s.baseBranch)!==O)return i("legacy-story-pr-post-merge-push-unverified");if(await t.afterPush?.(),u(e,"rev-parse","HEAD")===s.mergeCommitSha&&u(e,"merge","--ff-only",O),u(e,"rev-parse","HEAD")!==O||w(e,"status","--porcelain=v1","-uall")!==""||B(N(e,".neocortex/state.json"),2*1024*1024)!==f.stateAfter||B(N(e,`docs/stories/${s.storyId}.story.md`),2*1024*1024)!==f.storyAfter)return i("legacy-story-pr-post-merge-base-readback-invalid");const Je={schemaVersion:1,kind:"legacy-story-c12-post-merge-accepted",intentSha256:A,checkpointHeadSha:O,qaSha256:ce};return $&&JSON.stringify($)!==JSON.stringify(Je)?i("legacy-story-pr-post-merge-accepted-conflict"):($||(await z(o,l,`${JSON.stringify(Je)}
|
|
62
|
+
`),await J(N(o,l),o)),{ok:!0,value:Object.freeze({schemaVersion:1,kind:"legacy-story-c12-post-merge-accepted",storyId:s.storyId,epicId:s.epicId,prNumber:s.prNumber,issueNumber:s.issueNumber,mergeCommitSha:s.mergeCommitSha,checkpointHeadSha:O,qaSha256:ce,reused:!!$,physicalMerge:!0,issueClosed:!0,checkpointAccepted:!0,publicSafe:!0})})}catch(e){const o=e instanceof Error?e.message:"";return i(o.startsWith("legacy-story-pr-")?o:o.includes("secure-filesystem-cas-conflict")?"legacy-story-pr-post-merge-write-raced":"legacy-story-pr-post-merge-effect-uncertain")}finally{await te(a.path,a.owner).catch(()=>{})}}export{qt as acceptLegacyStoryCommitC08,Vt as acceptLegacyStoryPrC10,Gt as acceptLegacyStoryPrPostMergeC12,Zt as acceptLegacyStoryPrReviewC11,zt as acceptLegacyStorySyncC09,Lt as createLegacyStoryPr,Tt as mergeLegacyStoryPrC12,pt as planLegacyStoryCommitC08,he as planLegacyStoryPr,wt as planLegacyStoryPrMergeC12,Xe as planLegacyStoryPrMergeDecisionC12,At as planLegacyStoryPrPostMergeC12,Kt as planLegacyStoryPrReview,ut as planLegacyStorySyncC09,Wt as prepareLegacyStoryPrMergeC12,Mt as readAcceptedLegacyStoryPrC10,St as readAcceptedLegacyStoryPrReviewC11,Ft as recordLegacyStoryPrRemoteDebtC12};
|
|
@@ -12,6 +12,8 @@ export interface AnchoredDirectoryIdentity {
|
|
|
12
12
|
}
|
|
13
13
|
export declare function secureFilesystemBoundaryAvailable(platform?: NodeJS.Platform): boolean;
|
|
14
14
|
export declare function anchoredAtomicWriteFile(parent: string, name: string, content: Buffer | string, options?: AnchoredFilesystemTestOptions): Promise<void>;
|
|
15
|
+
/** Replace a regular tracked file only while its exact preimage still matches. */
|
|
16
|
+
export declare function anchoredCompareAndSwapFile(parent: string, name: string, content: Buffer | string, expectedSha256: string, options?: AnchoredFilesystemTestOptions): Promise<void>;
|
|
15
17
|
export declare function anchoredRemoveFile(parent: string, name: string, options?: AnchoredFilesystemTestOptions): Promise<void>;
|
|
16
18
|
export declare function anchoredEnsureDirectory(parent: string, name: string, options?: AnchoredFilesystemTestOptions): Promise<void>;
|
|
17
19
|
export declare function anchoredCreateDirectory(parent: string, name: string): Promise<AnchoredDirectoryIdentity>;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import{spawn as b}from"node:child_process";import{randomBytes as
|
|
1
|
+
import{spawn as b}from"node:child_process";import{randomBytes as B}from"node:crypto";import{lstat as w,stat as x}from"node:fs/promises";const T=String.raw`
|
|
2
2
|
const fs = require('node:fs');
|
|
3
|
-
const
|
|
3
|
+
const crypto = require('node:crypto');
|
|
4
|
+
const [op, expectedDev, expectedIno, name, temporary, expectedSha] = process.argv.slice(1);
|
|
4
5
|
const fail = (code) => { process.stderr.write(code); process.exit(73); };
|
|
5
6
|
process.on('uncaughtException', (error) => fail('secure-filesystem-os:' + String(error && error.code || 'UNKNOWN')));
|
|
6
7
|
const safe = (value) => typeof value === 'string' && value.length > 0 && value.length <= 255
|
|
@@ -52,6 +53,32 @@ if (op === 'mkdir' || op === 'mkdir-exclusive') {
|
|
|
52
53
|
safeExisting(name, 'file');
|
|
53
54
|
fs.renameSync(temporary, name);
|
|
54
55
|
safeExisting(name, 'file') || fail('secure-filesystem-destination-missing');
|
|
56
|
+
} else if (op === 'write-cas') {
|
|
57
|
+
if (!/^[0-9a-f]{64}$/.test(expectedSha || '')) fail('secure-filesystem-digest-invalid');
|
|
58
|
+
const original = safeExisting(name, 'file') || fail('secure-filesystem-entry-missing');
|
|
59
|
+
const originalMode = Number(original.mode & 0o777n);
|
|
60
|
+
const digest = () => {
|
|
61
|
+
const fd = fs.openSync(name, fs.constants.O_RDONLY | noFollow);
|
|
62
|
+
try {
|
|
63
|
+
const stat = fs.fstatSync(fd, { bigint: true });
|
|
64
|
+
if (!stat.isFile()) fail('secure-filesystem-entry-unsafe');
|
|
65
|
+
return crypto.createHash('sha256').update(fs.readFileSync(fd)).digest('hex');
|
|
66
|
+
} finally { fs.closeSync(fd); }
|
|
67
|
+
};
|
|
68
|
+
if (digest() !== expectedSha) fail('secure-filesystem-cas-conflict');
|
|
69
|
+
const fd = fs.openSync(temporary, fs.constants.O_CREAT | fs.constants.O_EXCL | fs.constants.O_WRONLY | noFollow, 0o600);
|
|
70
|
+
try {
|
|
71
|
+
fs.writeFileSync(fd, readStdin());
|
|
72
|
+
fs.fchmodSync(fd, originalMode);
|
|
73
|
+
fs.fsyncSync(fd);
|
|
74
|
+
} finally { fs.closeSync(fd); }
|
|
75
|
+
safeExisting(temporary, 'file') || fail('secure-filesystem-temporary-missing');
|
|
76
|
+
if (digest() !== expectedSha) {
|
|
77
|
+
fs.unlinkSync(temporary);
|
|
78
|
+
fail('secure-filesystem-cas-conflict');
|
|
79
|
+
}
|
|
80
|
+
fs.renameSync(temporary, name);
|
|
81
|
+
safeExisting(name, 'file') || fail('secure-filesystem-destination-missing');
|
|
55
82
|
} else if (op === 'remove') {
|
|
56
83
|
const item = safeExisting(name, 'file');
|
|
57
84
|
if (item) fs.unlinkSync(name);
|
|
@@ -66,7 +93,7 @@ if (op === 'mkdir' || op === 'mkdir-exclusive') {
|
|
|
66
93
|
if (safeExisting(name, 'directory')) fail('secure-filesystem-directory-remained');
|
|
67
94
|
} else fail('secure-filesystem-operation-invalid');
|
|
68
95
|
try { const parent = fs.openSync('.', fs.constants.O_RDONLY); fs.fsyncSync(parent); fs.closeSync(parent); } catch {}
|
|
69
|
-
`,
|
|
96
|
+
`,k=String.raw`
|
|
70
97
|
const fs = require('node:fs');
|
|
71
98
|
const cp = require('node:child_process');
|
|
72
99
|
const [expectedParentDev, expectedParentIno, name, expectedChildDev, expectedChildIno, encodedArgs, handshake, binary] = process.argv.slice(1);
|
|
@@ -104,7 +131,7 @@ const gitEnv = { ...process.env, GIT_OPTIONAL_LOCKS: '1' };
|
|
|
104
131
|
for (const key of ['GIT_DIR', 'GIT_WORK_TREE', 'GIT_INDEX_FILE', 'GIT_OBJECT_DIRECTORY',
|
|
105
132
|
'GIT_ALTERNATE_OBJECT_DIRECTORIES', 'GIT_COMMON_DIR', 'GIT_NAMESPACE', 'GIT_CEILING_DIRECTORIES']) delete gitEnv[key];
|
|
106
133
|
if (binary !== 'git') {
|
|
107
|
-
for (const key of ['NODE_OPTIONS', 'NODE_PATH', 'NEOCORTEX_RELEASE_GATE_MANIFEST']) delete gitEnv[key];
|
|
134
|
+
for (const key of ['NODE_OPTIONS', 'NODE_PATH', 'NEOCORTEX_RELEASE_GATE_MANIFEST', 'NEOCORTEX_PROFILE_DIR']) delete gitEnv[key];
|
|
108
135
|
gitEnv.npm_config_global = 'false';
|
|
109
136
|
}
|
|
110
137
|
const result = cp.spawnSync(binary === 'node' ? process.execPath : binary, args, {
|
|
@@ -118,6 +145,6 @@ if (result.error) fail('secure-git-command-error:' + String(result.error.code ||
|
|
|
118
145
|
if (result.status !== 0) fail('secure-git-command-failed:' + String(Number.isInteger(result.status) ? result.status : 1));
|
|
119
146
|
if (result.stdout && result.stdout.length > maxOutputBytes) fail('secure-git-output-too-large');
|
|
120
147
|
if (result.stdout) process.stdout.write(result.stdout);
|
|
121
|
-
`;function
|
|
122
|
-
`))&&N()}),
|
|
123
|
-
`).find(D=>D.startsWith("secure-git-")&&D!=="secure-git-handoff-ready")??(S>
|
|
148
|
+
`;function v(r=process.platform){return r!=="win32"}async function G(r,t,e,i={}){const s=`.${t}.${process.pid}.${B(8).toString("hex")}.tmp`;await y(r,["write",t,s],Buffer.isBuffer(e)?e:Buffer.from(e),i)}async function P(r,t,e,i,s={}){const n=`.${t}.${process.pid}.${B(8).toString("hex")}.tmp`;await y(r,["write-cas",t,n,i],Buffer.isBuffer(e)?e:Buffer.from(e),s)}async function H(r,t,e={}){await y(r,["remove",t],void 0,e)}async function W(r,t,e={}){await y(r,["mkdir",t],void 0,e)}async function $(r,t){const i=(await y(r,["mkdir-exclusive",t])).toString("utf8").match(/^secure-filesystem-identity:([0-9]+):([0-9]+)$/);if(!i)throw new Error("secure-filesystem-created-identity-missing");return Object.freeze({dev:i[1],ino:i[2]})}async function X(r){if(!v())throw new Error("secure-filesystem-platform-unsupported");const t=await w(r,{bigint:!0}),e=await x(r,{bigint:!0});if(t.isSymbolicLink()||!t.isDirectory()||!e.isDirectory()||t.dev!==e.dev||t.ino!==e.ino)throw new Error("secure-filesystem-directory-unsafe");return Object.freeze({dev:String(e.dev),ino:String(e.ino)})}async function Y(r,t,e,i,s,n={}){return O("git",r,t,e,i,s,n)}async function M(r,t,e,i,s,n={}){return O("node",r,t,e,i,s,n)}async function K(r,t,e,i){return O("npm",r,t,e,i)}async function O(r,t,e,i,s,n,f={}){if(!v(f.platform??process.platform))throw new Error("secure-filesystem-platform-unsupported");if(s.length===0||s.length>512||s.some(a=>typeof a!="string"||a.length>4096||a.includes("\0")))throw new Error("secure-git-args-invalid");const d=await x(t,{bigint:!0}),o=await w(t,{bigint:!0});if(!d.isDirectory()||o.isSymbolicLink()||!o.isDirectory()||d.dev!==o.dev||d.ino!==o.ino)throw new Error("secure-filesystem-parent-invalid");await f.beforeHandoff?.();const m=r==="git"?16*1024*1024:64*1024*1024;return await new Promise((a,p)=>{const l=f.afterHandoff?"1":"0",g=Buffer.from(JSON.stringify([...s])).toString("base64url"),c=b(process.execPath,["-e",k,String(d.dev),String(d.ino),e,i.dev,i.ino,g,l,r],{cwd:t,stdio:["pipe","pipe","pipe"]}),h=[],E=[];let S=0,_=!f.afterHandoff,I=!1;const N=async()=>{if(!I){I=!0;try{await f.afterHandoff?.(),_=!0,c.stdin.end(n===void 0?void 0:Buffer.isBuffer(n)?n:Buffer.from(n))}catch(u){c.kill(),p(u)}}};c.stdout.on("data",u=>{S+=u.length,S>m?c.kill():h.push(u)}),c.stderr.on("data",u=>{E.push(u),!_&&Buffer.concat(E).includes(Buffer.from(`secure-git-handoff-ready
|
|
149
|
+
`))&&N()}),c.once("error",p),c.once("close",u=>{if(u===0&&S<=m)return a(Buffer.concat(h));const R=Buffer.concat(E).toString("utf8").split(`
|
|
150
|
+
`).find(D=>D.startsWith("secure-git-")&&D!=="secure-git-handoff-ready")??(S>m?"secure-git-output-too-large":"secure-git-helper-failed");p(new Error(R))}),f.afterHandoff||N()})}async function q(r,t,e){await y(r,["create-owned-directory",t],Buffer.isBuffer(e)?e:Buffer.from(e))}async function J(r,t,e,i={}){await y(r,["rename-directory",t,e],void 0,i)}async function U(r,t,e={}){await y(r,["remove-directory",t],void 0,e)}async function y(r,t,e,i={}){if(!v(i.platform??process.platform))throw new Error("secure-filesystem-platform-unsupported");const s=await x(r,{bigint:!0});if(!s.isDirectory())throw new Error("secure-filesystem-parent-invalid");if((await w(r,{bigint:!0})).isSymbolicLink())throw new Error("secure-filesystem-parent-symlink");return await i.beforeHandoff?.(),await new Promise((f,d)=>{const o=b(process.execPath,["-e",T,...t.slice(0,1),String(s.dev),String(s.ino),...t.slice(1)],{cwd:r,stdio:["pipe","pipe","pipe"]}),m=[];let a=0;const p=[];o.stdout.on("data",l=>{a+=l.length,a>1024?o.kill():m.push(l)}),o.stderr.on("data",l=>p.push(l)),o.once("error",d),o.once("close",l=>{if(l===0&&a<=1024)return f(Buffer.concat(m));const g=Buffer.concat(p).toString("utf8")||"secure-filesystem-helper-failed",c=new Error(g),h=g.match(/^secure-filesystem-os:(E[A-Z0-9]+)$/)?.[1];h&&(c.code=h),g==="secure-filesystem-entry-exists"&&(c.code="EEXIST"),d(c)}),o.stdin.end(e)})}export{G as anchoredAtomicWriteFile,P as anchoredCompareAndSwapFile,$ as anchoredCreateDirectory,q as anchoredCreateOwnedDirectory,X as anchoredDirectoryIdentity,W as anchoredEnsureDirectory,Y as anchoredExecuteGit,M as anchoredExecuteNode,K as anchoredExecuteNpm,U as anchoredRemoveDirectory,H as anchoredRemoveFile,J as anchoredRenameDirectory,v as secureFilesystemBoundaryAvailable};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{createHash as p}from"node:crypto";import{existsSync as
|
|
2
|
-
`,"utf-8"),x(c)}catch{}}function R(){try{const t=o
|
|
1
|
+
import{createHash as p}from"node:crypto";import{existsSync as i,readFileSync as s,writeFileSync as d,mkdirSync as h,chmodSync as y}from"node:fs";import{join as f}from"node:path";import{arch as g,cpus as F,hostname as I,networkInterfaces as M,platform as S}from"node:os";import{neocortexProfileDirectory as w}from"../config/profile-directory.js";const O="00:00:00:00:00:00",o=w(),c=f(o,".machine-id");function $(){const t=M(),r=[];for(const e of Object.values(t))if(e)for(const n of e)!n.internal&&n.mac!==O&&r.push(n.mac);return[...new Set(r)].sort()}function E(){const t=I(),r=S(),e=g(),n=F(),u=n.length>0?n[0].model:"",l=$(),m=`${t}|${r}|${e}|${u}|${l.join(",")}`;return p("sha256").update(m).digest("hex")}function x(t){try{process.platform!=="win32"&&y(t,384)}catch{}}function C(){try{if(!i(c))return null;const t=s(c,"utf-8").trim();return/^[a-f0-9]{64}$/.test(t)?t:null}catch{return null}}function a(t){try{h(o,{recursive:!0}),d(c,t+`
|
|
2
|
+
`,"utf-8"),x(c)}catch{}}function R(){try{const t=f(o,"config.json");if(!i(t))return null;const r=s(t,"utf-8"),n=JSON.parse(r.replace(/^\uFEFF/,"")).machineId;return typeof n=="string"&&/^[a-f0-9]{64}$/.test(n)?n:null}catch{return null}}function D(t={}){const r=C();if(r)return r;const e=R();if(e)return t.strictReadOnly||a(e),e;const n=E();return t.strictReadOnly||a(n),n}export{E as computeHardwareFingerprint,D as getMachineFingerprint};
|