@ornexus/neocortex 4.60.63 → 4.60.64
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/release-source.json +1 -1
- package/dist/sbom.cdx.json +23 -23
- package/install.ps1 +1 -1
- package/install.sh +1 -1
- package/package.json +7 -2
- package/packages/client/dist/cli.js +8 -3
- package/packages/client/dist/commands/activate.js +8 -8
- package/packages/client/dist/commands/architecture-memory-terminal.js +4 -2
- package/packages/client/dist/commands/architecture-non-ui-continuation.d.ts +3 -0
- package/packages/client/dist/commands/architecture-non-ui-continuation.js +1 -0
- package/packages/client/dist/commands/invoke.d.ts +19 -16
- package/packages/client/dist/commands/invoke.js +85 -80
- package/packages/client/dist/commands/planning-generation.js +1 -1
- package/packages/client/dist/commands/planning-memory.d.ts +1 -0
- package/packages/client/dist/commands/planning-memory.js +1 -0
- package/packages/client/dist/commands/private-session.d.ts +1 -0
- package/packages/client/dist/commands/private-session.js +1 -0
- package/packages/client/dist/commands/qa-control.d.ts +4 -0
- package/packages/client/dist/commands/qa-control.js +1 -0
- package/packages/client/dist/commands/qa-scan-browser-launch.d.ts +8 -0
- package/packages/client/dist/commands/qa-scan-browser-launch.js +1 -0
- package/packages/client/dist/commands/qa-scan-browser-route.d.ts +3 -0
- package/packages/client/dist/commands/qa-scan-browser-route.js +1 -0
- package/packages/client/dist/commands/qa-scan-capture.d.ts +43 -0
- package/packages/client/dist/commands/qa-scan-capture.js +5 -5
- package/packages/client/dist/commands/qa-scan-discovery.d.ts +7 -0
- package/packages/client/dist/commands/qa-scan-discovery.js +3 -3
- package/packages/client/dist/commands/qa-scan-review.d.ts +8 -1
- package/packages/client/dist/commands/qa-scan-review.js +5 -5
- package/packages/client/dist/commands/qa-synthetic-backend-capture.d.ts +62 -0
- package/packages/client/dist/commands/qa-synthetic-backend-capture.js +1 -0
- package/packages/client/dist/commands/qa-synthetic-backend-review.d.ts +104 -0
- package/packages/client/dist/commands/qa-synthetic-backend-review.js +1 -0
- package/packages/client/dist/commands/qa-synthetic-backend.d.ts +52 -0
- package/packages/client/dist/commands/qa-synthetic-backend.js +7 -0
- package/packages/client/dist/commands/qa-synthetic-broker-port.d.ts +30 -0
- package/packages/client/dist/commands/qa-synthetic-broker-port.js +1 -0
- package/packages/client/dist/commands/qa-synthetic-browser.d.ts +1 -0
- package/packages/client/dist/commands/qa-synthetic-browser.js +1 -0
- package/packages/client/dist/commands/refactor-characterization.d.ts +12 -3
- package/packages/client/dist/commands/refactor-characterization.js +21 -12
- package/packages/client/dist/commands/refactor-control.d.ts +17 -0
- package/packages/client/dist/commands/refactor-control.js +3 -0
- package/packages/client/dist/commands/refactor-cpp-assertions.d.ts +4 -0
- package/packages/client/dist/commands/refactor-cpp-assertions.js +3 -0
- package/packages/client/dist/commands/refactor-review.d.ts +13 -0
- package/packages/client/dist/commands/refactor-review.js +6 -5
- package/packages/client/dist/commands/refactor-root.d.ts +165 -1
- package/packages/client/dist/commands/refactor-root.js +12 -7
- package/packages/client/dist/commands/refresh-memory.d.ts +1 -0
- package/packages/client/dist/commands/refresh-memory.js +3 -3
- package/packages/client/dist/commands/shared-architecture-non-ui-contract.d.ts +19 -0
- package/packages/client/dist/commands/shared-architecture-non-ui-contract.js +1 -0
- package/packages/client/dist/errors/error-messages.js +1 -1
- package/packages/client/dist/git/direct-yolo-checkpoint.js +4 -4
- package/packages/client/dist/git/git-lifecycle-store.js +7 -7
- package/packages/client/dist/license/license-client.d.ts +3 -1
- package/packages/client/dist/license/license-client.js +1 -1
- package/packages/client/dist/memory/project-memory-path-scope.d.ts +4 -0
- package/packages/client/dist/memory/project-memory-path-scope.js +1 -0
- package/packages/client/dist/memory/project-memory-writer.d.ts +4 -1
- package/packages/client/dist/memory/project-memory-writer.js +16 -16
- package/packages/client/dist/private-execution/clean-baseline.d.ts +6 -0
- package/packages/client/dist/private-execution/clean-baseline.js +2 -2
- package/packages/client/dist/private-execution/codex-executor.d.ts +48 -4
- package/packages/client/dist/private-execution/codex-executor.js +9 -2
- package/packages/client/dist/private-execution/codex-host-runtime.d.ts +10 -0
- package/packages/client/dist/private-execution/codex-host-runtime.js +1 -0
- package/packages/client/dist/private-execution/codex-lifecycle-guard.d.ts +4 -0
- package/packages/client/dist/private-execution/codex-lifecycle-guard.js +1 -0
- package/packages/client/dist/private-execution/codex-scoped-permissions.d.ts +8 -0
- package/packages/client/dist/private-execution/codex-scoped-permissions.js +1 -0
- package/packages/client/dist/private-execution/delivery.d.ts +18 -1
- package/packages/client/dist/private-execution/delivery.js +11 -3
- package/packages/client/dist/private-execution/diagnosis-root-review.d.ts +112 -0
- package/packages/client/dist/private-execution/diagnosis-root-review.js +2 -0
- package/packages/client/dist/private-execution/frozen-handoff.d.ts +2 -0
- package/packages/client/dist/private-execution/frozen-handoff.js +7 -0
- package/packages/client/dist/private-execution/implementation-validation.d.ts +24 -0
- package/packages/client/dist/private-execution/implementation-validation.js +2 -0
- package/packages/client/dist/private-execution/isolated-admission.d.ts +11 -7
- package/packages/client/dist/private-execution/isolated-admission.js +17 -10
- package/packages/client/dist/private-execution/isolated-session.d.ts +68 -0
- package/packages/client/dist/private-execution/isolated-session.js +5 -2
- package/packages/client/dist/private-execution/pact-test-source.d.ts +1 -1
- package/packages/client/dist/private-execution/pact-test-source.js +1 -1
- package/packages/client/dist/private-execution/planning-diagnosis-checkpoint.d.ts +2 -0
- package/packages/client/dist/private-execution/planning-diagnosis-checkpoint.js +5 -5
- package/packages/client/dist/private-execution/planning-generation-checkpoint.d.ts +13 -0
- package/packages/client/dist/private-execution/planning-generation-checkpoint.js +4 -3
- package/packages/client/dist/private-execution/planning-memory-checkpoint.d.ts +32 -0
- package/packages/client/dist/private-execution/planning-memory-checkpoint.js +3 -0
- package/packages/client/dist/private-execution/planning-research-checkpoint.js +4 -4
- package/packages/client/dist/private-execution/root-checkpoint.js +1 -1
- package/packages/client/dist/private-execution/root-memory-git-evidence.d.ts +30 -0
- package/packages/client/dist/private-execution/root-memory-git-evidence.js +3 -0
- package/packages/client/dist/private-execution/root-memory-recovery.d.ts +16 -0
- package/packages/client/dist/private-execution/root-memory-recovery.js +1 -0
- package/packages/client/dist/private-execution/root-memory-request.d.ts +28 -0
- package/packages/client/dist/private-execution/root-memory-request.js +1 -0
- package/packages/client/dist/private-execution/root-memory-scope.d.ts +28 -0
- package/packages/client/dist/private-execution/root-memory-scope.js +1 -0
- package/packages/client/dist/private-execution/root-memory-writer.d.ts +22 -0
- package/packages/client/dist/private-execution/root-memory-writer.js +1 -0
- package/packages/client/dist/private-execution/session-lease.d.ts +19 -0
- package/packages/client/dist/private-execution/session-lease.js +1 -0
- package/packages/client/dist/private-execution/ux-source-validation.js +1 -1
- package/packages/client/dist/runner-cli.js +0 -0
- package/packages/client/dist/yolo/change-evidence-collector.d.ts +2 -2
- package/packages/client/dist/yolo/change-evidence-collector.js +1 -1
- package/packages/client/dist/yolo/spec-envelope-collector.js +2 -2
- package/packages/shared/dist/invocation/index.js +4 -2
- package/packages/shared/dist/invocation/packed-invoke.d.ts +12 -0
- package/packages/shared/dist/invocation/packed-invoke.js +58 -0
- package/packages/shared/dist/invocation/packed-invoke.test.d.ts +1 -0
- package/packages/shared/dist/invocation/packed-invoke.test.js +21 -0
- package/packages/shared/dist/planning/diagnosis-state.js +5 -2
- package/packages/shared/dist/private-qa-structural-admission.js +14 -0
- package/packages/shared/dist/private-yolo-predecessor-decision.js +32 -0
- package/packages/shared/dist/project-memory-targets.js +243 -0
- package/packages/shared/dist/project-validation-commands.js +96 -0
- package/packages/shared/dist/yolo/change-evidence.js +35 -0
- package/packages/shared/dist/yoloop/branch-unit.js +10 -1
- package/packages/shared/dist/yoloop/root-memory-effect.js +57 -0
- package/targets-stubs/antigravity/gemini.md +1 -1
- package/targets-stubs/antigravity/skill/SKILL.md +1 -1
- package/targets-stubs/claude-code/neocortex-root.agent.yaml +1 -1
- package/targets-stubs/claude-code/neocortex-root.md +2 -2
- package/targets-stubs/claude-code/neocortex.agent.yaml +1 -1
- package/targets-stubs/claude-code/neocortex.md +2 -2
- package/targets-stubs/codex/AGENTS.md +1 -1
- package/targets-stubs/cursor/agent.md +2 -2
- package/targets-stubs/gemini-cli/agent.md +2 -2
- package/targets-stubs/opencode/neocortex-root.md +1 -1
- package/targets-stubs/vscode/neocortex.agent.md +2 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import{execFileSync as q,spawnSync as
|
|
2
|
-
`))?.[1];if(!
|
|
3
|
-
`),
|
|
4
|
-
`)]))))}function oi(i){if(!o(i)||Object.keys(i).sort().join("|")!==["schemaVersion","verdict","claimId","epicId","logicalFingerprint","sourceHead","sourceBranch","sourceStateSha256","admission","artifactDigests","qaEvidenceId","intake","artifactSummary"].sort().join("|")||i.schemaVersion!=="PlanningDiagnosisRootReview/1"||i.verdict!=="accepted"||typeof i.claimId!="string"||!ci.test(i.claimId)||typeof i.epicId!="string"||!si.test(i.epicId)||typeof i.logicalFingerprint!="string"||!
|
|
5
|
-
`),_(
|
|
1
|
+
import{execFileSync as q,spawnSync as Y}from"node:child_process";import{createHash as v,randomUUID as ii}from"node:crypto";import{closeSync as D,fsyncSync as _,lstatSync as w,mkdirSync as ni,openSync as j,readFileSync as V,realpathSync as J,renameSync as ei,unlinkSync as L,writeFileSync as T}from"node:fs";import{isAbsolute as ti,join as m,resolve as B}from"node:path";import{isDeepStrictEqual as b}from"node:util";import{canonicalPlanningIntake as H,createPlanningReceiptV1 as N,planningIntakeRevision as F,projectDiagnosedEpicState as M}from"../../../shared/dist/planning/diagnosis-state.js";const x=/^[a-f0-9]{64}$/,si=/^P[1-9][0-9]{0,11}$/,ci=/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/,A=["idea","diagnosis","enrichment","index"],G="acd455ed0e39d98b90fb57391db75e366e4c5604db043e03a89a20e33d643c3c",ai="81f50aaa801c1660eabe46e645501acbfb3e9873410c991e1496c014ca75c369";function o(i){return i!==null&&typeof i=="object"&&!Array.isArray(i)}function S(i){return v("sha256").update(i).digest("hex")}function O(i,n){return q("git",[...n],{cwd:i,encoding:"utf8",stdio:["ignore","pipe","ignore"],maxBuffer:65536}).trim()}function I(i,n,e){const t=m(i,n),c=w(t);if(!c.isFile()||c.isSymbolicLink()||c.size<1||c.size>e)throw new Error("planning-diagnosis-physical-artifact-invalid");return V(t)}function U(i,n){return typeof i=="string"&&i.length<=128&&S(i)===n}function Z(i,n,e){const t=/^---\n([\s\S]{1,8192}?)\n---\n/.exec(i.replace(/\r\n/g,`
|
|
2
|
+
`))?.[1];if(!t)return!1;const c=t.split(`
|
|
3
|
+
`),a=d=>{const g=c.filter(r=>r.startsWith(`${d}:`));return g.length===1?g[0].slice(d.length+1).trim().replace(/^(?:"(.*)"|'(.*)')$/,"$1$2"):void 0};return a("epic_id")===n&&a("status")==="completed"&&U(a("step"),e)}function mi(i){const n=m(i,".neocortex/pending-epic-claims.json");let e;try{e=w(n)}catch(a){if(a.code==="ENOENT")return;throw a}const t=w(m(i,".neocortex"));if(!t.isDirectory()||t.isSymbolicLink()||t.uid!==process.getuid?.()||(t.mode&18)!==0||!e.isFile()||e.isSymbolicLink()||e.uid!==process.getuid?.()||(e.mode&63)!==0||e.size<1||e.size>128*1024)throw new Error("planning-pending-sidecar-invalid");const c=V(n);if(c.length!==e.size)throw new Error("planning-pending-sidecar-invalid");return S(c)}function ri(i,n,e,t=!0){const c=new Set(Object.values(n)),a=new Set([".neocortex/state.json.planning.lock",...e?[e]:[]]),d=q("git",["status","--porcelain=v1","-z","--untracked-files=all"],{cwd:i,stdio:["ignore","pipe","ignore"],maxBuffer:128*1024}).toString("utf8").split("\0").filter(Boolean),g=[],r=new Set;for(const l of d){const h=l.slice(0,2),s=l.slice(3);if(!(a.has(s)&&h==="??")){if(l[2]!==" "||!c.has(s)&&(!t||s!==".neocortex/pending-epic-claims.json")||s===".neocortex/pending-epic-claims.json"&&h!=="??"||s!==".neocortex/pending-epic-claims.json"&&h!=="??"&&h!==" M"||r.has(s))throw new Error("planning-diagnosis-write-scope-conflict");r.add(s),h==="??"&&c.has(s)&&g.push(s)}}if([...c].some(l=>!r.has(l)))throw new Error("planning-diagnosis-write-scope-conflict");const p=[q("git",["diff","--binary","--no-ext-diff","--no-textconv","HEAD","--"],{cwd:i,stdio:["ignore","pipe","ignore"],maxBuffer:2*1024*1024})];for(const l of g.sort()){const h=Y("git",["diff","--no-index","--binary","--no-ext-diff","--","/dev/null",l],{cwd:i,encoding:"buffer",maxBuffer:2097152});if(h.status!==1||!Buffer.isBuffer(h.stdout))throw new Error("planning-diagnosis-patch-invalid");p.push(h.stdout)}return S(Buffer.concat(p.map(l=>Buffer.concat([l,Buffer.from(`
|
|
4
|
+
`)]))))}function oi(i){if(!o(i)||Object.keys(i).sort().join("|")!==["schemaVersion","verdict","claimId","epicId","logicalFingerprint","sourceHead","sourceBranch","sourceStateSha256","admission","artifactDigests","qaEvidenceId","intake","artifactSummary"].sort().join("|")||i.schemaVersion!=="PlanningDiagnosisRootReview/1"||i.verdict!=="accepted"||typeof i.claimId!="string"||!ci.test(i.claimId)||typeof i.epicId!="string"||!si.test(i.epicId)||typeof i.logicalFingerprint!="string"||!x.test(i.logicalFingerprint)||typeof i.sourceHead!="string"||!/^[a-f0-9]{40}$/.test(i.sourceHead)||typeof i.sourceBranch!="string"||!/^[a-zA-Z0-9][a-zA-Z0-9._/-]{0,127}$/.test(i.sourceBranch)||typeof i.sourceStateSha256!="string"||!x.test(i.sourceStateSha256)||!o(i.admission)||i.admission.schemaVersion!==1||i.admission.outcome!=="admitted-unverified"||i.admission.baseSha!==i.sourceHead||i.admission.executionBranch!==i.sourceBranch||typeof i.admission.patchSha256!="string"||!x.test(i.admission.patchSha256)||typeof i.qaEvidenceId!="string"||!/^qa-[a-z0-9-]{8,80}$/.test(i.qaEvidenceId)||!o(i.artifactDigests)||Object.keys(i.artifactDigests).sort().join("|")!==[...A].sort().join("|")||A.some(n=>typeof i.artifactDigests[n]!="string"||!x.test(i.artifactDigests[n])))throw new Error("planning-diagnosis-review-invalid");H(i.intake),N({kind:"diagnosis",epicId:i.epicId,intakeRevision:F(i.intake),artifactSummary:i.artifactSummary,accepted:!0})}function W(i,n,e,t){if(O(i,["rev-parse","HEAD"])!==n.sourceHead||O(i,["symbolic-ref","--quiet","--short","HEAD"])!==n.sourceBranch)throw new Error("planning-diagnosis-head-conflict");const c=w(m(i,".neocortex")),a=w(m(i,".neocortex/pending-epic-claims.json"));if(!c.isDirectory()||c.isSymbolicLink()||(c.mode&18)!==0||!a.isFile()||a.isSymbolicLink()||a.uid!==process.getuid?.()||(a.mode&63)!==0)throw new Error("planning-diagnosis-claim-boundary-invalid");const d=JSON.parse(I(i,".neocortex/pending-epic-claims.json",128*1024).toString("utf8")),g=o(d)&&o(d.operations)?d.operations[n.logicalFingerprint]:void 0;if(!o(g)||g.claimId!==n.claimId||g.epicId!==n.epicId)throw new Error("planning-diagnosis-claim-conflict");const r=`.neocortex/planning/epic-${n.epicId}`,f={idea:`${r}/idea.json`,diagnosis:`${r}/diagnosis.md`,enrichment:`${r}/enriched-prompt.md`,index:".neocortex/planning/planning.json"};if(!Array.isArray(n.admission.changedPaths)||[...n.admission.changedPaths].sort().join("|")!==Object.values(f).sort().join("|")||e&&ri(i,f,t)!==n.admission.patchSha256)throw new Error("planning-diagnosis-admission-patch-conflict");const p={idea:I(i,f.idea,32*1024),diagnosis:I(i,f.diagnosis,256*1024),enrichment:I(i,f.enrichment,256*1024),index:I(i,f.index,128*1024)};for(const P of A)if(S(p[P])!==n.artifactDigests[P])throw new Error("planning-diagnosis-artifact-conflict");const l=JSON.parse(p.idea.toString("utf8")),h=JSON.parse(p.index.toString("utf8")),s=H(n.intake),u=o(h)&&o(h.epics)?h.epics[n.epicId]:void 0,y=o(u)?u.output_files:void 0;if(!o(l)||l.epic_id!==n.epicId||l.status!=="diagnosed"||l.raw_input!==s.rawIntent||!o(u)||u.id!==n.epicId||u.idea!==s.rawIntent||u.status!=="diagnosed"||!Z(p.diagnosis.toString("utf8"),n.epicId,G)||!Z(p.enrichment.toString("utf8"),n.epicId,ai)||!Array.isArray(u.steps_completed)||u.steps_completed.length!==1||!U(u.steps_completed[0],G)||!o(y)||!b(y,{diagnosis:f.diagnosis})||typeof u.created_at!="string"||!Number.isFinite(Date.parse(u.created_at))||u.completed_at!==null)throw new Error("planning-diagnosis-artifact-identity-conflict");if(typeof s.goal!="string"||!s.goal.trim()||typeof s.desiredOutcome!="string"||!s.desiredOutcome.trim()||!Array.isArray(s.users)||s.users.length===0||!Array.isArray(s.surfaces)||s.surfaces.length===0)throw new Error("planning-diagnosis-critical-intake-missing");const E=F(s),k=N({kind:"diagnosis",epicId:n.epicId,intakeRevision:E,artifactSummary:n.artifactSummary,accepted:!0});return{checkpoint:{schemaVersion:1,epicId:n.epicId,intake:s,intakeRevision:E,diagnosisReceipt:k},receiptId:k.receiptId}}function X(i,n,e){const t=W(i,n,!0,e),c=I(i,".neocortex/state.json",8*1024*1024);if(S(c)!==n.sourceStateSha256)throw new Error("planning-diagnosis-state-conflict");const a=JSON.parse(c.toString("utf8"));if(!o(a)||o(a.scope)&&a.scope.kind==="projected")throw new Error("planning-diagnosis-state-invalid");return M(a,{claimId:n.claimId,epicId:n.epicId,checkpoint:t.checkpoint}),{stateRaw:c,state:a,...t}}function K(i,n){const e={schemaVersion:"PlanningDiagnosisPhysicalAcceptance/1",claimId:i.claimId,epicId:i.epicId,diagnosisReceiptId:n,qaEvidenceId:i.qaEvidenceId,sourceHead:i.sourceHead,sourceStateSha256:i.sourceStateSha256,admissionPatchSha256:i.admission.patchSha256,artifactDigests:i.artifactDigests};return{...e,receiptId:S(JSON.stringify(e)),publicSafe:!0}}function yi(i,n,e,t=!1){const c=o(i)?i:void 0,d=(c&&o(c.epics)?c.epics:void 0)?.[e];if(!o(d)||d.id!==e||d.source!=="create-epic"||d.status!=="diagnosed"&&!(t&&d.status==="researched")||!o(d.createEpicPlanningClaim)||d.createEpicPlanningClaim.claimId!==n||d.createEpicPlanningClaim.epicId!==e||!o(d.createEpicPlanning)||!o(d.createEpicPlanningPhysical))throw new Error("planning-research-predecessor-invalid");const g=d.createEpicPlanning,r=d.createEpicPlanningPhysical,f=o(r.artifactDigests)?r.artifactDigests:void 0,p=H(g.intake),l=F(p),h=c&&o(c.epic_id_ledger)?c.epic_id_ledger:void 0,s=o(g.diagnosisReceipt)?g.diagnosisReceipt:void 0;if(g.schemaVersion!==1||g.epicId!==e||g.intakeRevision!==l||!t&&g.researchReceipt!==void 0||typeof p.goal!="string"||!p.goal.trim()||typeof p.desiredOutcome!="string"||!p.desiredOutcome.trim()||typeof p.rawIntent!="string"||!p.rawIntent.trim()||!Array.isArray(p.users)||p.users.length===0||!Array.isArray(p.surfaces)||p.surfaces.length===0||!Array.isArray(h?.reserved_ids)||!h.reserved_ids.includes(e)||!s||s.kind!=="diagnosis"||s.epicId!==e||s.intakeRevision!==l||s.accepted!==!0||typeof s.artifactSummary!="string"||!b(s,N({kind:"diagnosis",epicId:e,intakeRevision:l,artifactSummary:s.artifactSummary,accepted:!0}))||r.schemaVersion!=="PlanningDiagnosisPhysicalAcceptance/1"||r.claimId!==n||r.epicId!==e||r.diagnosisReceiptId!==s.receiptId||typeof r.qaEvidenceId!="string"||!/^qa-[a-z0-9-]{8,80}$/.test(r.qaEvidenceId)||typeof r.sourceHead!="string"||!/^[a-f0-9]{40}$/.test(r.sourceHead)||typeof r.sourceStateSha256!="string"||!x.test(r.sourceStateSha256)||typeof r.admissionPatchSha256!="string"||!x.test(r.admissionPatchSha256)||!f||Object.keys(f).sort().join("|")!==[...A].sort().join("|")||A.some(y=>typeof f[y]!="string"||!x.test(f[y])))throw new Error("planning-research-predecessor-invalid");const u={schemaVersion:r.schemaVersion,claimId:n,epicId:e,diagnosisReceiptId:s.receiptId,qaEvidenceId:r.qaEvidenceId,sourceHead:r.sourceHead,sourceStateSha256:r.sourceStateSha256,admissionPatchSha256:r.admissionPatchSha256,artifactDigests:f};if(!b(r,{...u,receiptId:S(JSON.stringify(u)),publicSafe:!0}))throw new Error("planning-research-predecessor-invalid");return{intakeRevision:l,diagnosisReceiptId:s.receiptId,rawIntent:p.rawIntent}}function di(i,n){const e=W(i,n,!1),t=JSON.parse(I(i,".neocortex/state.json",8*1024*1024).toString("utf8")),a=(o(t)&&o(t.epics)?t.epics:void 0)?.[n.epicId],d=o(t)&&o(t.epic_id_ledger)?t.epic_id_ledger:void 0;if(!o(a)||!o(a.createEpicPlanning)||!o(a.createEpicPlanningClaim)||a.createEpicPlanningClaim.claimId!==n.claimId||a.createEpicPlanningClaim.epicId!==n.epicId||a.createEpicPlanning.epicId!==n.epicId||a.createEpicPlanning.intakeRevision!==e.checkpoint.intakeRevision||!b(a.createEpicPlanning.intake,e.checkpoint.intake)||!b(a.createEpicPlanning.diagnosisReceipt,e.checkpoint.diagnosisReceipt)||!b(a.createEpicPlanningPhysical,K(n,e.receiptId))||!Array.isArray(d?.reserved_ids)||!d.reserved_ids.includes(n.epicId))throw new Error("planning-diagnosis-replay-conflict");return e.receiptId}function Si(i,n){oi(n);const e=n,t=B(i);if(J(t)!==t||O(t,["rev-parse","--show-toplevel"])!==t)throw new Error("planning-diagnosis-root-invalid");const c=m(t,".neocortex"),a=m(c,"state.json.planning.lock"),d=j(a,"wx",384);let g;try{const r=I(t,".neocortex/state.json",8388608);if(S(r)!==e.sourceStateSha256){const Q=di(t,e);return{epicId:e.epicId,diagnosisReceiptId:Q,qaEvidenceId:e.qaEvidenceId}}const f=X(t,e),p=M(f.state,{claimId:e.claimId,epicId:e.epicId,checkpoint:f.checkpoint});if(p===f.state)throw new Error("planning-diagnosis-already-sealed");const l=K(e,f.receiptId),h=p.epics,s={...p,epics:{...h,[e.epicId]:{...h[e.epicId],createEpicPlanningPhysical:l}}},u=O(t,["rev-parse","--git-common-dir"]),y=ti(u)?B(u):B(t,u);if(J(y)!==y||w(y).isSymbolicLink())throw new Error("planning-diagnosis-backup-dir-invalid");const E=m(y,"neocortex-planning");ni(E,{recursive:!0,mode:448});const k=w(E);if(!k.isDirectory()||k.isSymbolicLink()||k.uid!==process.getuid?.()||(k.mode&63)!==0)throw new Error("planning-diagnosis-backup-dir-invalid");const R=ii(),P=j(m(E,`state-backup-${R}.json`),"wx",384);try{T(P,f.stateRaw),_(P)}finally{D(P)}const C=j(E,"r");try{_(C)}finally{D(C)}g=m(c,`state.json.planning-tmp-${R}`);const $=j(g,"wx",384);try{T($,`${JSON.stringify(s,null,2)}
|
|
5
|
+
`),_($)}finally{D($)}if(!X(t,e,`.neocortex/state.json.planning-tmp-${R}`).stateRaw.equals(f.stateRaw))throw new Error("planning-diagnosis-state-conflict");ei(g,m(c,"state.json")),g=void 0;const z=j(c,"r");try{_(z)}finally{D(z)}return{epicId:e.epicId,diagnosisReceiptId:f.receiptId,qaEvidenceId:e.qaEvidenceId}}finally{if(g)try{L(g)}catch{}D(d),L(a)}}export{yi as acceptedPlanningDiagnosisPredecessor,mi as planningPendingSidecarDigest,ri as planningPhysicalPatchDigest,Si as sealPlanningDiagnosis};
|
|
@@ -25,6 +25,19 @@ export interface PlanningGenerationRootReviewV1 {
|
|
|
25
25
|
readonly qaEvidenceId: string;
|
|
26
26
|
readonly artifactSummary: string;
|
|
27
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* Reopen an already sealed and committed P03 before root memory work. This is
|
|
30
|
+
* physical consistency verification, not new QA, a claim or terminal authority.
|
|
31
|
+
* The sealer intentionally stays bound to its original pre-commit HEAD.
|
|
32
|
+
*/
|
|
33
|
+
export declare function verifyCommittedPlanningGeneration(projectRoot: string, claimId: string, epicId: string): {
|
|
34
|
+
readonly epicId: string;
|
|
35
|
+
readonly physicalAcceptanceReceiptId: string;
|
|
36
|
+
readonly storyIds: readonly string[];
|
|
37
|
+
readonly verifiedHead: string;
|
|
38
|
+
readonly stateSha256: string;
|
|
39
|
+
readonly publicSafe: true;
|
|
40
|
+
};
|
|
28
41
|
/** The root supplies independent QA; this CAS persists the accepted P03 checkpoint. */
|
|
29
42
|
export declare function sealPlanningGeneration(projectRoot: string, reviewInput: unknown): {
|
|
30
43
|
readonly epicId: string;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import{execFileSync as
|
|
1
|
+
import{execFileSync as lt,spawnSync as st}from"node:child_process";import{createHash as ht,randomUUID as mt}from"node:crypto";import{closeSync as U,fsyncSync as Z,lstatSync as X,mkdirSync as yt,openSync as W,readFileSync as ut,realpathSync as Y,renameSync as St,unlinkSync as it,writeFileSync as nt}from"node:fs";import{isAbsolute as It,join as N,resolve as K}from"node:path";import{isDeepStrictEqual as G}from"node:util";import{planningPendingSidecarDigest as ct,planningPhysicalPatchDigest as Dt}from"./planning-diagnosis-checkpoint.js";import{acceptedPlanningResearchPredecessor as rt}from"./planning-research-checkpoint.js";const _=/^[a-f0-9]{64}$/,ot=/^P[1-9][0-9]{0,11}$/,at=/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/,pt="acd455ed0e39d98b90fb57391db75e366e4c5604db043e03a89a20e33d643c3c",dt="fa2194f89c01f07e225fd6f39e98e679f628e072239b6cd0af3ee527f0722518",gt="8636f22ec5950410902448ee1e9cb4947359ac98df518742bddbbb367468e3ae";function r(t){return t!==null&&typeof t=="object"&&!Array.isArray(t)}function l(t){return ht("sha256").update(t).digest("hex")}function V(t,e,s=128*1024){return lt("git",[...e],{cwd:t,encoding:"utf8",stdio:["ignore","pipe","ignore"],maxBuffer:s}).trim()}function q(t,e,s){const i=X(N(t,e));if(!i.isFile()||i.isSymbolicLink()||i.size<1||i.size>s)throw new Error("planning-generation-physical-artifact-invalid");return ut(N(t,e))}function J(t,e,s,i="HEAD"){const c=st("git",["show",`${i}:${e}`],{cwd:t,encoding:"buffer",maxBuffer:s});if(c.status!==0||!Buffer.isBuffer(c.stdout)||c.stdout.length<1||c.stdout.length>s)throw new Error("planning-generation-predecessor-uncommitted");return c.stdout}function v(t,e){for(const s of[".neocortex",".neocortex/planning",`.neocortex/planning/epic-${e}`,"docs","docs/epics","docs/stories"]){const i=X(N(t,s));if(!i.isDirectory()||i.isSymbolicLink()||i.uid!==process.getuid?.()||s===".neocortex"&&(i.mode&18)!==0)throw new Error("planning-generation-directory-boundary-invalid")}}function H(t,e){const i=/^---\n([\s\S]{1,8192}?)\n---\n/.exec(t.replace(/\r\n/g,`
|
|
2
2
|
`))?.[1]?.split(`
|
|
3
|
-
`).filter(
|
|
4
|
-
`),
|
|
3
|
+
`).filter(c=>c.startsWith(`${e}:`))??[];return i.length===1?i[0].slice(e.length+1).trim().replace(/^(?:"(.*)"|'(.*)')$/,"$1$2"):void 0}function L(t,e){return typeof t=="string"&&t.length<=128&&l(t)===e}function Q(t,e){return Array.from({length:e},(s,i)=>`docs/stories/${t}.${String(i+1).padStart(2,"0")}.story.md`)}function bt(t){if(!r(t)||Object.keys(t).sort().join("|")!==["schemaVersion","verdict","claimId","epicId","diagnosisReceiptId","researchReceiptId","intakeRevision","sourceHead","sourceBranch","sourceStateSha256","admission","artifactDigests","qaEvidenceId","artifactSummary"].sort().join("|")||t.schemaVersion!=="PlanningGenerationRootReview/1"||t.verdict!=="accepted"||typeof t.claimId!="string"||!at.test(t.claimId)||typeof t.epicId!="string"||!ot.test(t.epicId)||typeof t.diagnosisReceiptId!="string"||!_.test(t.diagnosisReceiptId)||typeof t.researchReceiptId!="string"||!_.test(t.researchReceiptId)||typeof t.intakeRevision!="string"||!_.test(t.intakeRevision)||typeof t.sourceHead!="string"||!/^[a-f0-9]{40}$/.test(t.sourceHead)||typeof t.sourceBranch!="string"||!/^[a-zA-Z0-9][a-zA-Z0-9._/-]{0,127}$/.test(t.sourceBranch)||typeof t.sourceStateSha256!="string"||!_.test(t.sourceStateSha256)||!r(t.admission)||Object.keys(t.admission).sort().join("|")!==["schemaVersion","outcome","baseSha","executionBranch","changedPaths","patchSha256"].sort().join("|")||t.admission.schemaVersion!==1||t.admission.outcome!=="admitted-unverified"||t.admission.baseSha!==t.sourceHead||t.admission.executionBranch!==t.sourceBranch||typeof t.admission.patchSha256!="string"||!_.test(t.admission.patchSha256)||!r(t.artifactDigests)||Object.keys(t.artifactDigests).sort().join("|")!=="epic|index|stories"||typeof t.artifactDigests.epic!="string"||!_.test(t.artifactDigests.epic)||typeof t.artifactDigests.index!="string"||!_.test(t.artifactDigests.index)||!r(t.artifactDigests.stories)||Object.keys(t.artifactDigests.stories).length<1||Object.keys(t.artifactDigests.stories).length>24||Object.values(t.artifactDigests.stories).some(s=>typeof s!="string"||!_.test(s))||typeof t.qaEvidenceId!="string"||!/^qa-[a-z0-9-]{8,80}$/.test(t.qaEvidenceId)||typeof t.artifactSummary!="string"||t.artifactSummary.length<16||t.artifactSummary.length>2048)throw new Error("planning-generation-review-invalid");const e=Q(t.epicId,Object.keys(t.artifactDigests.stories).length);if(!G(Object.keys(t.artifactDigests.stories).sort(),[...e].sort()))throw new Error("planning-generation-review-invalid")}function Et(t){const e={schemaVersion:"PlanningGenerationPhysicalAcceptance/1",claimId:t.claimId,epicId:t.epicId,diagnosisReceiptId:t.diagnosisReceiptId,researchReceiptId:t.researchReceiptId,intakeRevision:t.intakeRevision,qaEvidenceId:t.qaEvidenceId,sourceHead:t.sourceHead,sourceStateSha256:t.sourceStateSha256,admissionPatchSha256:t.admission.patchSha256,artifactDigests:t.artifactDigests};return{...e,receiptId:l(JSON.stringify(e)),publicSafe:!0}}function tt(t,e,s,i,c){if(v(t,e.epicId),V(t,["rev-parse","HEAD"])!==e.sourceHead||V(t,["symbolic-ref","--quiet","--short","HEAD"])!==e.sourceBranch)throw new Error("planning-generation-head-conflict");const y=`.neocortex/planning/epic-${e.epicId}`,u=`docs/epics/epic-${e.epicId}.md`,o=".neocortex/planning/planning.json",h=Q(e.epicId,Object.keys(e.artifactDigests.stories).length),n={index:o,epic:u,...Object.fromEntries(h.map((m,f)=>[`story${f}`,m]))};if(!Array.isArray(e.admission.changedPaths)||!G([...e.admission.changedPaths].sort(),Object.values(n).sort())||s&&Dt(t,n,i,!0)!==e.admission.patchSha256)throw new Error("planning-generation-admission-patch-conflict");const B=q(t,o,128*1024),R=q(t,u,512*1024),S=h.map(m=>q(t,m,128*1024));if(l(B)!==e.artifactDigests.index||l(R)!==e.artifactDigests.epic||h.some((m,f)=>l(S[f])!==e.artifactDigests.stories[m]))throw new Error("planning-generation-artifact-conflict");const $=R.toString("utf8"),T=H($,"title");if(H($,"id")!==e.epicId||H($,"stories_count")!==String(h.length)||!T||T.length>200||!$.includes("## Stories"))throw new Error("planning-generation-epic-invalid");for(const[m,f]of S.entries()){const d=f.toString("utf8"),D=/^---\n([\s\S]{1,8192}?)\n---\n/.exec(d.replace(/\r\n/g,`
|
|
4
|
+
`))?.[1]??"",C=H(d,"epic_id"),g=C===e.epicId&&!/^\s*epic\s*:/m.test(D)||!s&&C===void 0&&!/^\s*epic_id\s*:/m.test(D)&&H(d,"epic")===e.epicId;if(H(d,"id")!==`${e.epicId}.${String(m+1).padStart(2,"0")}`||!g||H(d,"status")!=="backlog"||!H(d,"title")||!d.includes("## Acceptance Criteria")||!/\bGiven\b[\s\S]*\bWhen\b[\s\S]*\bThen\b/.test(d))throw new Error("planning-generation-story-invalid")}const b=c??q(t,".neocortex/state.json",8*1024*1024),a=JSON.parse(b.toString("utf8"));if(!r(a)||!r(a.epics)||!r(a.stories))throw new Error("planning-generation-state-invalid");const E=rt(a,e.claimId,e.epicId);if(E.diagnosisReceiptId!==e.diagnosisReceiptId||E.researchReceiptId!==e.researchReceiptId||E.intakeRevision!==e.intakeRevision||s&&l(b)!==e.sourceStateSha256)throw new Error("planning-generation-state-conflict");const k=a.epics[e.epicId];if(!r(k)||h.some((m,f)=>Object.hasOwn(a.stories,`${e.epicId}.${String(f+1).padStart(2,"0")}`)))throw new Error("planning-generation-story-collision");const P=k.createEpicPlanningPhysical,x=k.createEpicPlanningResearchPhysical;if(!r(P)||!r(x)||!r(P.artifactDigests)||!r(x.artifactDigests))throw new Error("planning-generation-predecessor-invalid");for(const[m,f]of Object.entries({idea:`${y}/idea.json`,diagnosis:`${y}/diagnosis.md`,enrichment:`${y}/enriched-prompt.md`,research:`${y}/research.md`})){const d=m==="research"?x.artifactDigests.research:P.artifactDigests[m],D=q(t,f,m==="idea"?32*1024:256*1024);if(l(D)!==d||!D.equals(J(t,f,512*1024)))throw new Error("planning-generation-predecessor-artifact-drift")}const j=J(t,o,128*1024);if(l(j)!==x.artifactDigests.index)throw new Error("planning-generation-predecessor-index-drift");const A=JSON.parse(j.toString("utf8")),w=JSON.parse(B.toString("utf8"));if(!r(A)||!r(A.epics)||!r(w)||!r(w.epics))throw new Error("planning-generation-index-invalid");const p=A.epics[e.epicId],I=w.epics[e.epicId];if(!r(p)||p.id!==e.epicId||p.status!=="researched"||!Array.isArray(p.steps_completed)||p.steps_completed.length!==2||!L(p.steps_completed[0],pt)||!L(p.steps_completed[1],dt)||!G(p.output_files,{diagnosis:`${y}/diagnosis.md`,research:`${y}/research.md`})||!r(I)||!Array.isArray(I.steps_completed)||!L(I.steps_completed[2],gt))throw new Error("planning-generation-index-predecessor-invalid");const O={...A,last_scan:w.last_scan,epics:{...A.epics,[e.epicId]:{...p,status:"generated",steps_completed:[...p.steps_completed,I.steps_completed[2]],completed_at:I.completed_at,output_files:{...p.output_files,epic:u,stories:h}}}};if(typeof w.last_scan!="string"||!Number.isFinite(Date.parse(w.last_scan))||typeof I.completed_at!="string"||!Number.isFinite(Date.parse(I.completed_at))||!G(w,O))throw new Error("planning-generation-index-transition-invalid");return{stateRaw:b,state:a,title:T,stories:h,storyBytes:S,completedAt:I.completed_at}}function et(t,e,s){const i=t.state,c=t.stories.map(o=>o.slice(13,-9)),y=i.epics[e.epicId],u={...i.stories};for(const[o,h]of c.entries())u[h]={id:h,epic_id:e.epicId,title:H(t.storyBytes[o].toString("utf8"),"title"),status:"backlog"};return{...i,epics:{...i.epics,[e.epicId]:{...y,title:t.title,status:"generated",stories:c,total_stories:c.length,completed_stories:0,createEpicPlanningGenerationPhysical:s}},stories:u,last_updated:t.completedAt}}function kt(t,e,s){const i=()=>new Error("planning-generation-committed-evidence-invalid"),c=K(t);if(!at.test(e)||!ot.test(s)||Y(c)!==c||V(c,["rev-parse","--show-toplevel"])!==c)throw i();v(c,s);const y=V(c,["rev-parse","HEAD"]),u=q(c,".neocortex/state.json",8*1024*1024);if(!u.equals(J(c,".neocortex/state.json",8*1024*1024)))throw i();const o=JSON.parse(u.toString("utf8")),h=r(o)&&r(o.epics)?o.epics[s]:void 0,n=r(h)?h.createEpicPlanningGenerationPhysical:void 0;if(!r(n)||n.schemaVersion!=="PlanningGenerationPhysicalAcceptance/1"||n.claimId!==e||n.epicId!==s||typeof n.sourceHead!="string"||!/^[a-f0-9]{40}$/.test(n.sourceHead)||typeof n.qaEvidenceId!="string"||!/^qa-[a-z0-9-]{8,80}$/.test(n.qaEvidenceId)||["diagnosisReceiptId","researchReceiptId","intakeRevision","sourceStateSha256","admissionPatchSha256"].some(g=>typeof n[g]!="string"||!_.test(n[g]))||!r(n.artifactDigests)||Object.keys(n.artifactDigests).sort().join("|")!=="epic|index|stories"||typeof n.artifactDigests.epic!="string"||!_.test(n.artifactDigests.epic)||typeof n.artifactDigests.index!="string"||!_.test(n.artifactDigests.index)||!r(n.artifactDigests.stories))throw i();const B=Object.keys(n.artifactDigests.stories).length,R=Q(s,B);if(B<1||B>24||!G(Object.keys(n.artifactDigests.stories).sort(),[...R].sort())||Object.values(n.artifactDigests.stories).some(g=>typeof g!="string"||!_.test(g)))throw i();const S={schemaVersion:"PlanningGenerationPhysicalAcceptance/1",claimId:e,epicId:s,diagnosisReceiptId:n.diagnosisReceiptId,researchReceiptId:n.researchReceiptId,intakeRevision:n.intakeRevision,qaEvidenceId:n.qaEvidenceId,sourceHead:n.sourceHead,sourceStateSha256:n.sourceStateSha256,admissionPatchSha256:n.admissionPatchSha256,artifactDigests:n.artifactDigests},$={...S,receiptId:l(JSON.stringify(S)),publicSafe:!0};if(!G(n,$)||st("git",["merge-base","--is-ancestor",n.sourceHead,"HEAD"],{cwd:c,stdio:"ignore"}).status!==0)throw i();const b=J(c,".neocortex/state.json",8*1024*1024,n.sourceHead);if(l(b)!==n.sourceStateSha256)throw i();const a=JSON.parse(b.toString("utf8")),E=rt(a,e,s);if(E.diagnosisReceiptId!==n.diagnosisReceiptId||E.researchReceiptId!==n.researchReceiptId||E.intakeRevision!==n.intakeRevision||!r(a)||!r(a.epics)||!r(a.epics[s]))throw i();const k=a.epics[s],P=k.createEpicPlanningPhysical,x=k.createEpicPlanningResearchPhysical;if(!r(P)||!r(P.artifactDigests)||!r(x)||!r(x.artifactDigests))throw i();const j=`.neocortex/planning/epic-${s}`;for(const[g,M,z]of[["idea",`${j}/idea.json`,32*1024],["diagnosis",`${j}/diagnosis.md`,256*1024],["enrichment",`${j}/enriched-prompt.md`,256*1024],["research",`${j}/research.md`,256*1024]]){const F=q(c,M,z),ft=g==="research"?x.artifactDigests.research:P.artifactDigests[g];if(l(F)!==ft||!F.equals(J(c,M,z))||!F.equals(J(c,M,z,n.sourceHead)))throw i()}const A=(g,M,z)=>{const F=q(c,g,z);if(l(F)!==M||!F.equals(J(c,g,z)))throw i();return F},w=A(`docs/epics/epic-${s}.md`,S.artifactDigests.epic,512*1024),p=R.map(g=>A(g,S.artifactDigests.stories[g],128*1024)),I=".neocortex/planning/planning.json",O=JSON.parse(A(I,S.artifactDigests.index,128*1024).toString("utf8")),m=J(c,I,128*1024,n.sourceHead);if(l(m)!==x.artifactDigests.index)throw i();const f=JSON.parse(m.toString("utf8"));if(!r(O)||!r(O.epics)||!r(O.epics[s])||!r(f)||!r(f.epics)||!r(f.epics[s]))throw i();const d=O.epics[s],D=f.epics[s];if(!Array.isArray(D.steps_completed)||D.steps_completed.length!==2||!L(D.steps_completed[0],pt)||!L(D.steps_completed[1],dt)||!Array.isArray(d.steps_completed)||!L(d.steps_completed[2],gt)||typeof d.completed_at!="string"||!Number.isFinite(Date.parse(d.completed_at))||typeof O.last_scan!="string"||!Number.isFinite(Date.parse(O.last_scan))||!G(O,{...f,last_scan:O.last_scan,epics:{...f.epics,[s]:{...D,status:"generated",steps_completed:[...D.steps_completed,d.steps_completed[2]],completed_at:d.completed_at,output_files:{...D.output_files,epic:`docs/epics/epic-${s}.md`,stories:R}}}}))throw i();const C=H(w.toString("utf8"),"title");if(!C||!G(o,et({stateRaw:b,state:a,title:C,stories:R,storyBytes:p,completedAt:d.completed_at},{epicId:s},$))||V(c,["rev-parse","HEAD"])!==y||!q(c,".neocortex/state.json",8*1024*1024).equals(u))throw i();return{epicId:s,physicalAcceptanceReceiptId:$.receiptId,storyIds:R.map(g=>g.slice(13,-9)),verifiedHead:y,stateSha256:l(u),publicSafe:!0}}function At(t,e){bt(e);const s=e,i=K(t);if(Y(i)!==i||V(i,["rev-parse","--show-toplevel"])!==i)throw new Error("planning-generation-root-invalid");v(i,s.epicId);const c=N(i,".neocortex"),y=N(c,"state.json.planning.lock"),u=W(y,"wx",384);let o;try{const h=ct(i),n=Et(s),B=Q(s.epicId,Object.keys(s.artifactDigests.stories).length).map(p=>p.slice(13,-9)),R=q(i,".neocortex/state.json",8*1024*1024);if(l(R)!==s.sourceStateSha256){const p=J(i,".neocortex/state.json",8388608);if(l(p)!==s.sourceStateSha256)throw new Error("planning-generation-replay-conflict");const I=tt(i,s,!1,void 0,p);if(!G(JSON.parse(R.toString("utf8")),et(I,s,n)))throw new Error("planning-generation-replay-conflict");return{epicId:s.epicId,physicalAcceptanceReceiptId:n.receiptId,qaEvidenceId:s.qaEvidenceId,storyIds:B}}const S=tt(i,s,!0),$=et(S,s,n),T=V(i,["rev-parse","--git-common-dir"]),b=It(T)?K(T):K(i,T);if(Y(b)!==b||X(b).isSymbolicLink())throw new Error("planning-generation-backup-dir-invalid");const a=N(b,"neocortex-planning");yt(a,{recursive:!0,mode:448});const E=X(a);if(!E.isDirectory()||E.isSymbolicLink()||E.uid!==process.getuid?.()||(E.mode&63)!==0)throw new Error("planning-generation-backup-dir-invalid");const k=mt(),P=W(N(a,`state-backup-${k}.json`),"wx",384);try{nt(P,S.stateRaw),Z(P)}finally{U(P)}const x=W(a,"r");try{Z(x)}finally{U(x)}o=N(c,`state.json.planning-tmp-${k}`);const j=W(o,"wx",384);try{nt(j,`${JSON.stringify($,null,2)}
|
|
5
|
+
`),Z(j)}finally{U(j)}if(!tt(i,s,!0,`.neocortex/state.json.planning-tmp-${k}`).stateRaw.equals(S.stateRaw))throw new Error("planning-generation-state-conflict");if(ct(i)!==h)throw new Error("planning-generation-pending-conflict");St(o,N(c,"state.json")),o=void 0;const w=W(c,"r");try{Z(w)}finally{U(w)}return{epicId:s.epicId,physicalAcceptanceReceiptId:n.receiptId,qaEvidenceId:s.qaEvidenceId,storyIds:B}}finally{if(o)try{it(o)}catch{}U(u),it(y)}}export{At as sealPlanningGeneration,kt as verifyCommittedPlanningGeneration};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export interface PlanningMemoryRootReviewV1 {
|
|
2
|
+
readonly schemaVersion: 'PlanningMemoryRootReview/1';
|
|
3
|
+
readonly verdict: 'accepted';
|
|
4
|
+
readonly claimId: string;
|
|
5
|
+
readonly epicId: string;
|
|
6
|
+
readonly sourceHead: string;
|
|
7
|
+
readonly generationReceiptId: string;
|
|
8
|
+
readonly canonicalSha256: string;
|
|
9
|
+
readonly projectionSha256: string;
|
|
10
|
+
readonly fileCount: number;
|
|
11
|
+
readonly qaEvidenceId: string;
|
|
12
|
+
readonly artifactSummary: string;
|
|
13
|
+
}
|
|
14
|
+
export interface PlanningMemoryPhysicalAcceptanceV1 {
|
|
15
|
+
readonly schemaVersion: 'PlanningMemoryPhysicalAcceptance/1';
|
|
16
|
+
readonly claimId: string;
|
|
17
|
+
readonly epicId: string;
|
|
18
|
+
readonly sourceHead: string;
|
|
19
|
+
readonly generationReceiptId: string;
|
|
20
|
+
readonly stateSha256: string;
|
|
21
|
+
readonly canonicalSha256: string;
|
|
22
|
+
readonly projectionSha256: string;
|
|
23
|
+
readonly fileCount: number;
|
|
24
|
+
readonly qaEvidenceId: string;
|
|
25
|
+
readonly artifactSummary: string;
|
|
26
|
+
readonly receiptId: string;
|
|
27
|
+
readonly publicSafe: true;
|
|
28
|
+
}
|
|
29
|
+
/** Only a typed independent root review can create this receipt. No canonical state is rewritten. */
|
|
30
|
+
export declare function sealPlanningMemory(projectRoot: string, input: unknown): PlanningMemoryPhysicalAcceptanceV1;
|
|
31
|
+
/** Fresh read-only physical verification; metadata, a digest or an old receipt is insufficient. */
|
|
32
|
+
export declare function verifyCommittedPlanningMemory(projectRoot: string, claimId: string, epicId: string): PlanningMemoryPhysicalAcceptanceV1;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import{execFileSync as q,spawnSync as x}from"node:child_process";import{createHash as A}from"node:crypto";import{closeSync as h,existsSync as $,fsyncSync as H,lstatSync as g,openSync as S,readFileSync as I,readlinkSync as M,realpathSync as D,unlinkSync as F,writeFileSync as N}from"node:fs";import{join as d,resolve as b}from"node:path";import{isDeepStrictEqual as w}from"node:util";import{canonicalPlanningIntake as B}from"../../../shared/dist/planning/diagnosis-state.js";import{parseRefreshMemoryArgs as O,refreshProjectMemoryTargets as v,verifyProjectMemoryTargets as J}from"../commands/refresh-memory.js";import{planningPendingSidecarDigest as P}from"./planning-diagnosis-checkpoint.js";import{verifyCommittedPlanningGeneration as k}from"./planning-generation-checkpoint.js";const L=e=>A("sha256").update(e).digest("hex"),r=()=>new Error("planning-memory-physical-evidence-invalid"),E=e=>!!e&&typeof e=="object"&&!Array.isArray(e),y=(e,...t)=>q("git",t,{cwd:e,encoding:"utf8",stdio:["ignore","pipe","ignore"],maxBuffer:1024*1024}).trim(),R=e=>`.neocortex/planning/epic-${e}/memory-acceptance.json`;function C(e,t){const i=x("git",["show",`HEAD:${t}`],{cwd:e,encoding:"buffer",maxBuffer:1048576});if(i.status!==0||!Buffer.isBuffer(i.stdout))throw r();return i.stdout}function V(e,t,i){if(D(e)!==e||y(e,"rev-parse","--show-toplevel")!==e)throw r();const o=k(e,t,i),c=O(["--project-root",e,"--verify"]),m=J(c),l=[...new Set(v(c).flatMap(n=>n.files.map(s=>s.relativeFile)))].sort();for(const n of l){const s=d(e,n),a=g(s);if(!(a.isSymbolicLink()?Buffer.from(M(s)):I(s)).equals(C(e,n)))throw r();const f=y(e,"ls-tree","HEAD","--",n).split(" ")[0];if(a.isSymbolicLink()?f!=="120000":!a.isFile()||!["100644","100755"].includes(f))throw r()}if(y(e,"rev-parse","HEAD")!==o.verifiedHead)throw r();return{generation:o,memory:m,files:l}}function u(e){if(!E(e)||Object.keys(e).sort().join("|")!==["schemaVersion","verdict","claimId","epicId","sourceHead","generationReceiptId","canonicalSha256","projectionSha256","fileCount","qaEvidenceId","artifactSummary"].sort().join("|")||e.schemaVersion!=="PlanningMemoryRootReview/1"||e.verdict!=="accepted"||typeof e.claimId!="string"||!/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/.test(e.claimId)||typeof e.epicId!="string"||!/^P[1-9][0-9]{0,11}$/.test(e.epicId)||typeof e.sourceHead!="string"||!/^[a-f0-9]{40}$/.test(e.sourceHead)||[e.generationReceiptId,e.canonicalSha256,e.projectionSha256].some(t=>typeof t!="string"||!/^[a-f0-9]{64}$/.test(t))||!Number.isInteger(e.fileCount)||Number(e.fileCount)<1||Number(e.fileCount)>64||typeof e.qaEvidenceId!="string"||!/^qa-[a-z0-9-]{8,80}$/.test(e.qaEvidenceId)||typeof e.artifactSummary!="string"||!e.artifactSummary.trim())throw r();B({goal:e.artifactSummary})}function j(e,t){u(t);const{generation:i,memory:o}=V(e,t.claimId,t.epicId);if(i.physicalAcceptanceReceiptId!==t.generationReceiptId||o.canonicalSha256!==t.canonicalSha256||o.projectionSha256!==t.projectionSha256||o.fileCount!==t.fileCount||x("git",["merge-base","--is-ancestor",t.sourceHead,"HEAD"],{cwd:e,stdio:"ignore"}).status!==0)throw r();const c={schemaVersion:"PlanningMemoryPhysicalAcceptance/1",claimId:t.claimId,epicId:t.epicId,sourceHead:t.sourceHead,generationReceiptId:t.generationReceiptId,stateSha256:i.stateSha256,canonicalSha256:t.canonicalSha256,projectionSha256:t.projectionSha256,fileCount:t.fileCount,qaEvidenceId:t.qaEvidenceId,artifactSummary:t.artifactSummary};return{...c,receiptId:L(JSON.stringify(c)),publicSafe:!0}}function Z(e,t){u(t);const i=b(e),o=R(t.epicId);k(i,t.claimId,t.epicId);const c=d(i,".neocortex/state.json.planning.lock"),m=S(c,"wx",384);try{const l=P(i),n=j(i,t);if($(d(i,o))){const f=g(d(i,o));if(!f.isFile()||f.isSymbolicLink()||f.size>16384||!w(JSON.parse(I(d(i,o),"utf8")),n))throw r();return n}if(y(i,"rev-parse","HEAD")!==t.sourceHead||y(i,"diff","--name-only")||y(i,"diff","--cached","--name-only")||y(i,"ls-files","--others","--exclude-standard").split(`
|
|
2
|
+
`).filter(Boolean).some(f=>f!==".neocortex/pending-epic-claims.json"&&f!==".neocortex/state.json.planning.lock")||P(i)!==l||!w(j(i,t),n))throw r();const a=S(d(i,o),"wx",384);try{N(a,`${JSON.stringify(n,null,2)}
|
|
3
|
+
`),H(a)}finally{h(a)}const p=S(d(i,".neocortex/planning",`epic-${t.epicId}`),"r");try{H(p)}finally{h(p)}return n}finally{h(m),F(c)}}function _(e,t,i){if(!/^P[1-9][0-9]{0,11}$/.test(i))throw r();const o=b(e),c=R(i),m=g(d(o,c));if(!m.isFile()||m.isSymbolicLink()||m.size>16384)throw r();const l=I(d(o,c));if(!l.equals(C(o,c)))throw r();const n=JSON.parse(l.toString("utf8"));if(!E(n)||n.claimId!==t||n.epicId!==i)throw r();const s={schemaVersion:"PlanningMemoryRootReview/1",verdict:"accepted",claimId:t,epicId:i,sourceHead:n.sourceHead,generationReceiptId:n.generationReceiptId,canonicalSha256:n.canonicalSha256,projectionSha256:n.projectionSha256,fileCount:n.fileCount,qaEvidenceId:n.qaEvidenceId,artifactSummary:n.artifactSummary};u(s);const a=j(o,s);if(!w(n,a))throw r();return a}export{Z as sealPlanningMemory,_ as verifyCommittedPlanningMemory};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{execFileSync as
|
|
2
|
-
`),n=/^---\n([\s\S]{1,8192}?)\n---\n/.exec(i)?.[1];if(!n)return;const
|
|
3
|
-
`),
|
|
4
|
-
`),q(
|
|
1
|
+
import{execFileSync as W,spawnSync as X}from"node:child_process";import{createHash as K,randomUUID as Q}from"node:crypto";import{closeSync as D,fsyncSync as q,lstatSync as A,mkdirSync as Y,openSync as b,readFileSync as v,realpathSync as J,renameSync as ee,unlinkSync as F,writeFileSync as L}from"node:fs";import{isAbsolute as te,join as y,resolve as B}from"node:path";import{isDeepStrictEqual as P}from"node:util";import{createPlanningReceiptV1 as V}from"../../../shared/dist/planning/diagnosis-state.js";import{acceptedPlanningDiagnosisPredecessor as T,planningPendingSidecarDigest as C,planningPhysicalPatchDigest as ie}from"./planning-diagnosis-checkpoint.js";const l=/^[a-f0-9]{64}$/,ne=/^P[1-9][0-9]{0,11}$/,se=/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/,ce="acd455ed0e39d98b90fb57391db75e366e4c5604db043e03a89a20e33d643c3c",re="fa2194f89c01f07e225fd6f39e98e679f628e072239b6cd0af3ee527f0722518";function p(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function u(e){return K("sha256").update(e).digest("hex")}function _(e,t,i=128*1024){return W("git",[...t],{cwd:e,encoding:"utf8",stdio:["ignore","pipe","ignore"],maxBuffer:i}).trim()}function w(e,t,i){const n=A(y(e,t));if(!n.isFile()||n.isSymbolicLink()||n.size<1||n.size>i)throw new Error("planning-research-physical-artifact-invalid");return v(y(e,t))}function G(e,t){for(const i of[".neocortex",".neocortex/planning",`.neocortex/planning/epic-${t}`]){const n=A(y(e,i));if(!n.isDirectory()||n.isSymbolicLink()||n.uid!==process.getuid?.()||i===".neocortex"&&(n.mode&18)!==0)throw new Error("planning-research-directory-boundary-invalid")}}function M(e,t){return typeof e=="string"&&e.length<=128&&u(e)===t}function ae(e,t){const i=e.replace(/\r\n/g,`
|
|
2
|
+
`),n=/^---\n([\s\S]{1,8192}?)\n---\n/.exec(i)?.[1];if(!n)return;const a=n.split(`
|
|
3
|
+
`),r=c=>{const s=a.filter(o=>o.startsWith(`${c}:`));return s.length===1?s[0].slice(c.length+1).trim().replace(/^(?:"(.*)"|'(.*)')$/,"$1$2"):void 0},g=r("step");return r("epic_id")===t&&r("status")==="completed"&&M(g,re)&&i.slice(n.length+9).trim().length>0?g:void 0}function oe(e){if(!p(e)||Object.keys(e).sort().join("|")!==["schemaVersion","verdict","claimId","epicId","diagnosisReceiptId","intakeRevision","sourceHead","sourceBranch","sourceStateSha256","admission","artifactDigests","qaEvidenceId","artifactSummary"].sort().join("|")||e.schemaVersion!=="PlanningResearchRootReview/1"||e.verdict!=="accepted"||typeof e.claimId!="string"||!se.test(e.claimId)||typeof e.epicId!="string"||!ne.test(e.epicId)||typeof e.diagnosisReceiptId!="string"||!l.test(e.diagnosisReceiptId)||typeof e.intakeRevision!="string"||!l.test(e.intakeRevision)||typeof e.sourceHead!="string"||!/^[a-f0-9]{40}$/.test(e.sourceHead)||typeof e.sourceBranch!="string"||!/^[a-zA-Z0-9][a-zA-Z0-9._/-]{0,127}$/.test(e.sourceBranch)||typeof e.sourceStateSha256!="string"||!l.test(e.sourceStateSha256)||!p(e.admission)||Object.keys(e.admission).sort().join("|")!==["schemaVersion","outcome","baseSha","executionBranch","changedPaths","patchSha256"].sort().join("|")||e.admission.schemaVersion!==1||e.admission.outcome!=="admitted-unverified"||e.admission.baseSha!==e.sourceHead||e.admission.executionBranch!==e.sourceBranch||typeof e.admission.patchSha256!="string"||!l.test(e.admission.patchSha256)||!p(e.artifactDigests)||Object.keys(e.artifactDigests).sort().join("|")!=="index|research"||typeof e.artifactDigests.index!="string"||!l.test(e.artifactDigests.index)||typeof e.artifactDigests.research!="string"||!l.test(e.artifactDigests.research)||typeof e.qaEvidenceId!="string"||!/^qa-[a-z0-9-]{8,80}$/.test(e.qaEvidenceId)||typeof e.artifactSummary!="string")throw new Error("planning-research-review-invalid");V({kind:"research",epicId:e.epicId,intakeRevision:e.intakeRevision,predecessorReceiptId:e.diagnosisReceiptId,artifactSummary:e.artifactSummary,accepted:!0})}function U(e,t){const i={schemaVersion:"PlanningResearchPhysicalAcceptance/1",claimId:e.claimId,epicId:e.epicId,diagnosisReceiptId:e.diagnosisReceiptId,researchReceiptId:t,intakeRevision:e.intakeRevision,qaEvidenceId:e.qaEvidenceId,sourceHead:e.sourceHead,sourceStateSha256:e.sourceStateSha256,admissionPatchSha256:e.admission.patchSha256,artifactDigests:e.artifactDigests};return{...i,receiptId:u(JSON.stringify(i)),publicSafe:!0}}function z(e,t,i,n){if(G(e,t.epicId),_(e,["rev-parse","HEAD"])!==t.sourceHead||_(e,["symbolic-ref","--quiet","--short","HEAD"])!==t.sourceBranch)throw new Error("planning-research-head-conflict");const a={research:`.neocortex/planning/epic-${t.epicId}/research.md`,index:".neocortex/planning/planning.json"};if(!Array.isArray(t.admission.changedPaths)||[...t.admission.changedPaths].sort().join("|")!==Object.values(a).sort().join("|")||i&&ie(e,a,n,!0)!==t.admission.patchSha256)throw new Error("planning-research-admission-patch-conflict");const r={research:w(e,a.research,256*1024),index:w(e,a.index,128*1024)},g=ae(r.research.toString("utf8"),t.epicId);if(u(r.research)!==t.artifactDigests.research||u(r.index)!==t.artifactDigests.index||!g)throw new Error("planning-research-artifact-conflict");const c=w(e,".neocortex/state.json",8*1024*1024),s=JSON.parse(c.toString("utf8")),o=T(s,t.claimId,t.epicId,!i);if(o.diagnosisReceiptId!==t.diagnosisReceiptId||o.intakeRevision!==t.intakeRevision||i&&u(c)!==t.sourceStateSha256)throw new Error("planning-research-state-conflict");const j=s.epics[t.epicId].createEpicPlanningPhysical.artifactDigests,I=`.neocortex/planning/epic-${t.epicId}`;for(const[x,$]of Object.entries({idea:`${I}/idea.json`,diagnosis:`${I}/diagnosis.md`,enrichment:`${I}/enriched-prompt.md`}))if(u(w(e,$,x==="idea"?32*1024:256*1024))!==j[x])throw new Error("planning-research-predecessor-artifact-drift");const R=X("git",["show",`HEAD:${a.index}`],{cwd:e,encoding:"buffer",maxBuffer:128*1024});if(R.status!==0||!Buffer.isBuffer(R.stdout)||u(R.stdout)!==j.index)throw new Error("planning-research-predecessor-index-drift");const m=JSON.parse(R.stdout.toString("utf8")),f=JSON.parse(r.index.toString("utf8"));if(!p(m)||!p(m.epics)||!p(f)||!p(f.epics))throw new Error("planning-research-index-invalid");const d=m.epics[t.epicId];if(!p(d)||d.id!==t.epicId||d.idea!==o.rawIntent||d.status!=="diagnosed"||!Array.isArray(d.steps_completed)||d.steps_completed.length!==1||!M(d.steps_completed[0],ce)||!P(d.output_files,{diagnosis:`${I}/diagnosis.md`}))throw new Error("planning-research-index-predecessor-invalid");const E={...m,last_scan:f.last_scan,epics:{...m.epics,[t.epicId]:{...d,status:"researched",steps_completed:[...d.steps_completed,g],output_files:{diagnosis:`${I}/diagnosis.md`,research:a.research}}}};if(typeof f.last_scan!="string"||!Number.isFinite(Date.parse(f.last_scan))||!P(f,E))throw new Error("planning-research-index-transition-invalid");const k=V({kind:"research",epicId:t.epicId,intakeRevision:t.intakeRevision,predecessorReceiptId:t.diagnosisReceiptId,artifactSummary:t.artifactSummary,accepted:!0});return{stateRaw:c,state:s,receipt:k}}function de(e,t){const i=z(e,t,!1),a=i.state.epics[t.epicId],r=a.createEpicPlanning;if(a.status!=="researched"||!P(r.researchReceipt,i.receipt)||!P(a.createEpicPlanningResearchPhysical,U(t,i.receipt.receiptId)))throw new Error("planning-research-replay-conflict");return i.receipt.receiptId}function Ie(e,t,i){const n=T(e,t,i,!0),r=e.epics[i],g=p(r?.createEpicPlanning)?r.createEpicPlanning:void 0,c=p(g?.researchReceipt)?g.researchReceipt:void 0,s=p(r?.createEpicPlanningResearchPhysical)?r.createEpicPlanningResearchPhysical:void 0,o=p(s?.artifactDigests)?s.artifactDigests:void 0;if(r?.status!=="researched"||!c||!s||!o||typeof c.artifactSummary!="string"||!P(c,V({kind:"research",epicId:i,intakeRevision:n.intakeRevision,predecessorReceiptId:n.diagnosisReceiptId,artifactSummary:c.artifactSummary,accepted:!0}))||s.schemaVersion!=="PlanningResearchPhysicalAcceptance/1"||s.claimId!==t||s.epicId!==i||s.diagnosisReceiptId!==n.diagnosisReceiptId||s.researchReceiptId!==c.receiptId||s.intakeRevision!==n.intakeRevision||typeof s.qaEvidenceId!="string"||!/^qa-[a-z0-9-]{8,80}$/.test(s.qaEvidenceId)||typeof s.sourceHead!="string"||!/^[a-f0-9]{40}$/.test(s.sourceHead)||typeof s.sourceStateSha256!="string"||!l.test(s.sourceStateSha256)||typeof s.admissionPatchSha256!="string"||!l.test(s.admissionPatchSha256)||Object.keys(o).sort().join("|")!=="index|research"||typeof o.index!="string"||!l.test(o.index)||typeof o.research!="string"||!l.test(o.research))throw new Error("planning-generation-predecessor-invalid");const h={schemaVersion:s.schemaVersion,claimId:t,epicId:i,diagnosisReceiptId:n.diagnosisReceiptId,researchReceiptId:c.receiptId,intakeRevision:n.intakeRevision,qaEvidenceId:s.qaEvidenceId,sourceHead:s.sourceHead,sourceStateSha256:s.sourceStateSha256,admissionPatchSha256:s.admissionPatchSha256,artifactDigests:o},S={...h,receiptId:u(JSON.stringify(h)),publicSafe:!0};if(!P(s,S))throw new Error("planning-generation-predecessor-invalid");return{intakeRevision:n.intakeRevision,diagnosisReceiptId:n.diagnosisReceiptId,researchReceiptId:c.receiptId,physicalAcceptanceReceiptId:S.receiptId}}function Se(e,t){oe(t);const i=t,n=B(e);if(J(n)!==n||_(n,["rev-parse","--show-toplevel"])!==n)throw new Error("planning-research-root-invalid");G(n,i.epicId);const a=y(n,".neocortex"),r=y(a,"state.json.planning.lock"),g=b(r,"wx",384);let c;try{const s=C(n),o=w(n,".neocortex/state.json",8*1024*1024);if(u(o)!==i.sourceStateSha256){const Z=de(n,i);return{epicId:i.epicId,researchReceiptId:Z,qaEvidenceId:i.qaEvidenceId}}const h=z(n,i,!0),S=h.state.epics,H=S[i.epicId],j=H.createEpicPlanning,I=U(i,h.receipt.receiptId),R={...h.state,epics:{...S,[i.epicId]:{...H,status:"researched",createEpicPlanning:{...j,researchReceipt:h.receipt},createEpicPlanningResearchPhysical:I}}},m=_(n,["rev-parse","--git-common-dir"]),f=te(m)?B(m):B(n,m);if(J(f)!==f||A(f).isSymbolicLink())throw new Error("planning-research-backup-dir-invalid");const d=y(f,"neocortex-planning");Y(d,{recursive:!0,mode:448});const E=A(d);if(!E.isDirectory()||E.isSymbolicLink()||E.uid!==process.getuid?.()||(E.mode&63)!==0)throw new Error("planning-research-backup-dir-invalid");const k=Q(),x=b(y(d,`state-backup-${k}.json`),"wx",384);try{L(x,h.stateRaw),q(x)}finally{D(x)}const $=b(d,"r");try{q($)}finally{D($)}c=y(a,`state.json.planning-tmp-${k}`);const O=b(c,"wx",384);try{L(O,`${JSON.stringify(R,null,2)}
|
|
4
|
+
`),q(O)}finally{D(O)}if(!z(n,i,!0,`.neocortex/state.json.planning-tmp-${k}`).stateRaw.equals(h.stateRaw))throw new Error("planning-research-state-conflict");if(C(n)!==s)throw new Error("planning-research-pending-conflict");ee(c,y(a,"state.json")),c=void 0;const N=b(a,"r");try{q(N)}finally{D(N)}return{epicId:i.epicId,researchReceiptId:h.receipt.receiptId,qaEvidenceId:i.qaEvidenceId}}finally{if(c)try{F(c)}catch{}D(g),F(r)}}export{Ie as acceptedPlanningResearchPredecessor,Se as sealPlanningResearch};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{execFileSync as f}from"node:child_process";import{createHash as l}from"node:crypto";import{resolve as I}from"node:path";import{beginDirectYoloStoryCommit as v,finalizeDirectYoloStoryCheckpoint as m,issueDirectYoloSetupLeaseHandoff as E}from"../git/direct-yolo-checkpoint.js";import{verifyPrivateYoloCleanBaseline as y}from"./clean-baseline.js";import{stagePrivateYoloIsolatedSessionBundle as g}from"./isolated-session.js";const
|
|
1
|
+
import{execFileSync as f}from"node:child_process";import{createHash as l}from"node:crypto";import{resolve as I}from"node:path";import{beginDirectYoloStoryCommit as v,finalizeDirectYoloStoryCheckpoint as m,issueDirectYoloSetupLeaseHandoff as E}from"../git/direct-yolo-checkpoint.js";import{verifyPrivateYoloCleanBaseline as y}from"./clean-baseline.js";import{stagePrivateYoloIsolatedSessionBundle as g}from"./isolated-session.js";const w="step-5ce2a8c7";function a(c,e){const o={...process.env};for(const i of["GIT_DIR","GIT_WORK_TREE","GIT_INDEX_FILE","GIT_OBJECT_DIRECTORY","GIT_ALTERNATE_OBJECT_DIRECTORIES","GIT_COMMON_DIR","GIT_NAMESPACE","GIT_CEILING_DIRECTORIES"])delete o[i];return f("git",[...e],{cwd:c,env:o,stdio:["ignore","pipe","pipe"],timeout:3e4,maxBuffer:16*1024*1024})}async function b(c,e){const o=I(c);if(e.schemaVersion!==1||e.action!=="checkpoint-epic-story"||!/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/.test(e.storyId)||!/^[a-f0-9]{64}$/.test(e.graphRevision)||e.stepId!==w||!/^[A-Za-z0-9][A-Za-z0-9._/-]{0,127}$/.test(e.executionBranch)||e.executionBranch.includes("..")||e.publicSafe!==!0)throw new Error("private-execution-root-checkpoint-invalid");await y(o,e.storyId,e.executionBranch,e.graphRevision);const i=await g(o,e.storyId,e.graphRevision),n=await E({projectRoot:o,storyId:e.storyId});if(!n.ok||n.value.bundleDigest!==i.bundleSha256)throw new Error("private-execution-root-checkpoint-handoff-denied",{cause:new Error(n.ok?"private-execution-root-checkpoint-handoff-bundle-mismatch":n.reasonCode)});const t=await v({projectRoot:o,storyId:e.storyId});if(!t.ok)throw new Error("private-execution-root-checkpoint-begin-denied");if(t.value.graphRevision!==e.graphRevision||t.value.executionBranch!==e.executionBranch)throw new Error("private-execution-root-checkpoint-authority-drift");try{const r=a(o,["rev-parse","HEAD"]).toString("utf8").trim(),h=a(o,["symbolic-ref","--quiet","--short","HEAD"]).toString("utf8").trim(),u=a(o,["diff","--cached","--binary","--full-index"]),d=l("sha256").update(u).digest("hex");if(r!==t.value.baseSha||h!==t.value.executionBranch||d!==t.value.bundleDigest||d!==i.bundleSha256)throw new Error("private-execution-root-checkpoint-bundle-drift");a(o,["commit","-m",`fix(${e.storyId}): checkpoint direct yolo`,...t.value.trailers.flatMap(p=>["-m",p])])}catch(r){throw r instanceof Error&&r.message==="private-execution-root-checkpoint-bundle-drift"?r:new Error("private-execution-root-checkpoint-commit-failed")}const s=await m({projectRoot:o,storyId:e.storyId,push:!0});if(!s.ok)throw new Error("private-execution-root-checkpoint-finalize-denied");return Object.freeze({schemaVersion:1,outcome:"checkpoint-validated",storyId:e.storyId,headSha:s.value.headSha,publicSafe:!0})}export{b as runPrivateYoloRootCheckpoint};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { type RootMemoryFileState, type RootProjectMemoryEffect } from '../../../shared/dist/yoloop/root-memory-effect.js';
|
|
2
|
+
/** Hash Git blobs without following links, using the same link-byte hash as the writer. */
|
|
3
|
+
export declare function rootMemoryGitFileState(root: string, sha: string, path: string): RootMemoryFileState;
|
|
4
|
+
export interface RootMemoryGitBinding {
|
|
5
|
+
readonly storyId: string;
|
|
6
|
+
readonly graphRevision: string;
|
|
7
|
+
readonly childClaimRevision: string;
|
|
8
|
+
readonly setupSessionId: string;
|
|
9
|
+
readonly sourceHeadSha: string;
|
|
10
|
+
readonly executionBranch: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Prove that the recorded root range contains exactly the registered memory delta.
|
|
14
|
+
* The caller must separately verify the private producer receipt and live session.
|
|
15
|
+
* A JSON effect plus this inspection alone is never an execution authority.
|
|
16
|
+
*/
|
|
17
|
+
export declare function verifyRootMemoryEffectGitEvidence(root: string, effect: unknown, binding: RootMemoryGitBinding): RootProjectMemoryEffect;
|
|
18
|
+
export declare function rootMemoryEffectDigest(effect: RootProjectMemoryEffect): string;
|
|
19
|
+
/**
|
|
20
|
+
* Verify only physical ownership and bytes in the staged/committed C08 bundle.
|
|
21
|
+
* Selection must come from private producer custody or an already accepted typed
|
|
22
|
+
* checkpoint. This inspector alone does not grant QA, review or commit authority.
|
|
23
|
+
*/
|
|
24
|
+
export declare function verifyRootMemoryPhysicalWriteSet(root: string, candidate: unknown, binding: {
|
|
25
|
+
readonly storyId: string;
|
|
26
|
+
readonly executionBranch: string;
|
|
27
|
+
readonly baseSha: string;
|
|
28
|
+
readonly headRef: string;
|
|
29
|
+
readonly childPaths: readonly string[];
|
|
30
|
+
}): RootProjectMemoryEffect;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import{execFileSync as S}from"node:child_process";import{createHash as R}from"node:crypto";import{isDeepStrictEqual as f}from"node:util";import{canonicalRootMemoryEffectJson as x,isRootProjectMemoryEffect as p,rootProjectMemoryPaths as d}from"../../../shared/dist/yoloop/root-memory-effect.js";import{getProjectMemoryTarget as E,listProjectMemoryTargets as P}from"../../../shared/dist/project-memory-targets.js";import{shouldUseManagedWrapper as g}from"../memory/project-memory-writer.js";const u=o=>R("sha256").update(o).digest("hex"),i=()=>{throw new Error("private-root-memory-git-evidence-unverified")};function l(o,t){return S("git",[...t],{cwd:o,stdio:["ignore","pipe","ignore"],env:{...Object.fromEntries(Object.entries(process.env).filter(([e])=>!e.startsWith("GIT_"))),GIT_NO_REPLACE_OBJECTS:"1"},timeout:3e4,maxBuffer:2*1024*1024})}function m(o,t,e){if(t!==":"&&!/^[a-f0-9]{40,64}$/.test(t)||!d().includes(e))return i();const h=l(o,t===":"?["ls-files","--stage","-z","--",e]:["ls-tree","-z",t,"--",e]).toString("utf8");if(!h)return{kind:"absent",sha256:null};const s=(t===":"?/^(100644|120000) ([a-f0-9]{40,64}) 0\t([^\0]+)\0$/:/^(100644|120000) blob ([a-f0-9]{40,64})\t([^\0]+)\0$/).exec(h);if(!s||s[3]!==e)return i();const c=l(o,["cat-file","blob",s[2]]);return c.byteLength>512*1024?i():s[1]==="120000"?{kind:"symlink",sha256:u(c),linkTarget:c.toString("utf8")}:{kind:"regular",sha256:u(c)}}function C(o,t,e){try{if(!p(t)||!e||["storyId","graphRevision","childClaimRevision","setupSessionId","sourceHeadSha","executionBranch"].some(s=>t[s]!==e[s]))return i();l(o,["merge-base","--is-ancestor",t.sourceHeadSha,t.sourceSnapshotSha]),l(o,["merge-base","--is-ancestor",t.sourceSnapshotSha,t.memorySnapshotSha]);const h=l(o,["diff","--name-only","--no-renames","--no-ext-diff","--no-textconv","-z",t.sourceSnapshotSha,t.memorySnapshotSha]).toString("utf8").split("\0").filter(Boolean).sort();if(!f(h,t.files.map(s=>s.path).sort()))return i();for(const s of t.files){const c=m(o,t.sourceSnapshotSha,s.path),r=m(o,t.memorySnapshotSha,s.path);if(!f(c,s.before)||!f(r,s.after)||f(c,r))return i()}return y(o,t.memorySnapshotSha,t),t}catch{return i()}}function y(o,t,e){const h=m(o,t,"NEOCORTEX.md");if(h.kind!=="regular"||h.sha256!==e.canonicalSha256)return i();const s=new Map;for(const r of[E("canonical"),...P()])for(const a of[r.primaryFile,...r.targetId==="canonical"?[]:r.secondaryFiles.filter(n=>n.scope==="project").map(n=>n.path)])s.has(a)||s.set(a,r.targetId==="canonical"?"canonical":g(r,a)?"managed-wrapper":"semantic-symlink");const c=[...s].sort(([r],[a])=>r<a?-1:r>a?1:0).map(([r,a])=>{const n=m(o,t,r);return n.kind==="absent"||a!=="semantic-symlink"&&n.kind!=="regular"||a==="semantic-symlink"&&(n.kind!=="symlink"||n.linkTarget!=="../".repeat(r.split("/").length-1)+"NEOCORTEX.md")?i():`${r}:${a}:${n.kind==="symlink"?h.sha256:n.sha256}`});if(e.projectionFileCount!==c.length||e.projectionSha256!==u(Buffer.from(c.join(`
|
|
2
|
+
`))))return i()}function k(o){return u(Buffer.from(x(o)))}function I(o,t,e){try{if(!p(t)||!e||t.storyId!==e.storyId||t.executionBranch!==e.executionBranch||t.sourceHeadSha!==e.baseSha||!/^[a-f0-9]{40,64}$/.test(e.baseSha)||e.headRef!==":"&&!/^[a-f0-9]{40,64}$/.test(e.headRef)||!Array.isArray(e.childPaths)||e.childPaths.length<1||e.childPaths.length>1024||e.childPaths.some(r=>typeof r!="string"||!r||r.startsWith("/")||/[\\\x00-\x1f\x7f]/.test(r)||r.split("/").includes("..")||r.split("/").includes(".git"))||new Set(e.childPaths).size!==e.childPaths.length||t.childClaimRevision!==u(Buffer.from([...e.childPaths].sort().join("\0"))))return i();const h=r=>e.childPaths.some(a=>a===r||a.endsWith("/")&&r.startsWith(a)),s=l(o,["diff",...e.headRef===":"?["--cached"]:[],"--name-only","--no-renames","--no-ext-diff","--no-textconv","-z",e.baseSha,...e.headRef===":"?[]:[e.headRef]]).toString("utf8").split("\0").filter(Boolean),c=t.files.map(r=>r.path).sort();if(!f(s.filter(r=>!h(r)).sort(),c)||t.files.some(r=>h(r.path)))return i();for(const r of t.files){const a=m(o,e.baseSha,r.path),n=m(o,e.headRef,r.path);if(!f(a,r.before)||!f(n,r.after)||f(a,n))return i()}if(y(o,e.headRef,t),e.headRef!==":"){const a=l(o,["show","--no-patch","--format=%B",e.headRef]).toString("utf8").split(`
|
|
3
|
+
`).filter(n=>n.startsWith("Neocortex-Root-Memory-Effect:"));if(a.length!==1||a[0]!==`Neocortex-Root-Memory-Effect: ${k(t)}`)return i()}return t}catch{return i()}}export{k as rootMemoryEffectDigest,m as rootMemoryGitFileState,C as verifyRootMemoryEffectGitEvidence,I as verifyRootMemoryPhysicalWriteSet};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { PrivateYoloIsolatedSessionV1 } from './isolated-session.js';
|
|
2
|
+
import type { PrivateRootMemoryRequest } from './root-memory-request.js';
|
|
3
|
+
export declare function rootMemoryOperationJournalName(current: PrivateYoloIsolatedSessionV1, request: PrivateRootMemoryRequest): string;
|
|
4
|
+
export declare function readVerifiedPreparedRootMemory(input: {
|
|
5
|
+
readonly projectRoot: string;
|
|
6
|
+
readonly parent: string;
|
|
7
|
+
readonly current: PrivateYoloIsolatedSessionV1;
|
|
8
|
+
readonly request: PrivateRootMemoryRequest;
|
|
9
|
+
readonly childPaths: readonly string[];
|
|
10
|
+
}): Promise<{
|
|
11
|
+
receipt: any;
|
|
12
|
+
effect: import("../../../shared/dist/yoloop/root-memory-effect.js").RootProjectMemoryEffect;
|
|
13
|
+
patch: Buffer<ArrayBufferLike>;
|
|
14
|
+
sourceAlreadyApplied: boolean;
|
|
15
|
+
journalPath: string;
|
|
16
|
+
}>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createHash as x}from"node:crypto";import{execFileSync as M}from"node:child_process";import{existsSync as O,lstatSync as m,readFileSync as P,realpathSync as A}from"node:fs";import{join as l}from"node:path";import{isDeepStrictEqual as d}from"node:util";import{isRootProjectMemoryEffect as D,rootProjectMemoryPaths as H}from"../../../shared/dist/yoloop/root-memory-effect.js";import{assertGitLifecyclePrivateFile as B}from"../git/git-lifecycle-store.js";import{privateYoloSourceFileMatchesSnapshot as F}from"./isolated-admission.js";import{rootMemoryGitFileState as I,verifyRootMemoryEffectGitEvidence as J}from"./root-memory-git-evidence.js";import{rootMemoryFileState as N}from"./root-memory-writer.js";const S=s=>x("sha256").update(s).digest("hex"),n=()=>{throw new Error("private-root-memory-prepared-recovery-unverified")},b=(s,e)=>Object.keys(s).sort().join("|")===[...e].sort().join("|");function c(s,e){return M("git",[...e],{cwd:s,stdio:["ignore","pipe","ignore"],env:{...Object.fromEntries(Object.entries(process.env).filter(([t])=>!t.startsWith("GIT_"))),GIT_NO_REPLACE_OBJECTS:"1"},timeout:3e4,maxBuffer:16*1024*1024})}function G(s,e){return`memory-operation-${S(JSON.stringify([s.storyId,s.setupSessionId,s.graphRevision,e.review.snapshotSha,e.review.proposalSha256,e.review.sourceStateSha256,e.review.rootQaReceiptId,S(JSON.stringify(e.review.notes))]))}.json`}async function U(s){try{const{projectRoot:e,current:t,request:g,childPaths:f}=s,{review:h,directive:u}=g,y=l(s.parent,G(t,g));await B(y,s.parent);const w=P(y);if(w.length>256*1024)return n();const p=JSON.parse(w.toString("utf8"));if(!p||!b(p,["schemaVersion","kind","previousSession","receipt","patchSha256"])||p.schemaVersion!==1||p.kind!=="prepared-root-memory-effect"||!d(p.previousSession,t)||t.rootMemoryEffect!==void 0)return n();const r=p.receipt,a=r?.rootMemoryEffect;if(!r||!b(r,["schemaVersion","kind","storyId","graphRevision","sourceHeadSha","snapshotSha","proposalSha256","notesSha256","sourceStateSha256","checks","reviewedAt","rootMemoryEffect","independentStoryQaAccepted","terminalAccepted"])||!D(a)||r.schemaVersion!==1||r.kind!=="private-project-memory-root-review"||r.storyId!==t.storyId||r.graphRevision!==t.graphRevision||r.sourceHeadSha!==t.workspace.baseSha||r.snapshotSha!==a.memorySnapshotSha||r.proposalSha256!==h.proposalSha256||r.sourceStateSha256!==h.sourceStateSha256||r.notesSha256!==S(JSON.stringify(h.notes))||r.notesSha256!==a.proposalSha256||!d(r.checks,h.checks)||r.reviewedAt!==a.recordedAt||a.sourceSnapshotSha!==t.snapshotSha||a.rootQaReceiptId!==h.rootQaReceiptId||r.independentStoryQaAccepted!==!1||r.terminalAccepted!==!1)return n();const o=t.workspace.workspacePath;if(A(e)!==e||A(o)!==o||!m(o).isDirectory()||m(o).uid!==process.getuid?.()||(m(o).mode&63)!==0||!m(l(o,".git")).isDirectory()||m(l(o,".git")).isSymbolicLink()||O(l(o,".git/objects/info/alternates"))||c(o,["rev-parse","--show-toplevel"]).toString().trim()!==o||c(e,["rev-parse","--show-toplevel"]).toString().trim()!==e||c(e,["rev-parse","HEAD"]).toString().trim()!==t.workspace.baseSha||c(e,["symbolic-ref","--short","HEAD"]).toString().trim()!==u.executionBranch||c(o,["rev-parse","HEAD"]).toString().trim()!==a.memorySnapshotSha||c(o,["symbolic-ref","--short","HEAD"]).toString().trim()!==u.executionBranch||c(o,["status","--porcelain=v1","-z","--untracked-files=all","--ignored=matching"]).length!==0||c(e,["diff","--cached","--name-only","-z"]).length!==0||(J(o,a,{storyId:t.storyId,graphRevision:t.graphRevision,childClaimRevision:S([...f].sort().join("\0")),setupSessionId:t.setupSessionId,sourceHeadSha:t.workspace.baseSha,executionBranch:u.executionBranch}),f.some(i=>!F(e,o,t.snapshotSha,i))))return n();const k=a.files.map(i=>i.path);if(c(e,["status","--porcelain=v1","-z","--untracked-files=all"]).toString("utf8").split("\0").filter(Boolean).some(i=>![" M"," D","??"," T"].includes(i.slice(0,2))||!f.includes(i.slice(3))&&!k.includes(i.slice(3))||i.slice(0,2)===" T"&&!k.includes(i.slice(3))))return n();let E=!0,v=!0;for(const i of H()){if(f.includes(i))return n();const R=N(e,i);E&&=d(R,I(o,t.snapshotSha,i)),v&&=d(R,I(o,a.memorySnapshotSha,i))}if(!E&&!v)return n();const j=c(o,["diff","--binary","--full-index",t.snapshotSha,a.memorySnapshotSha]);return S(j)!==p.patchSha256?n():{receipt:r,effect:a,patch:j,sourceAlreadyApplied:v,journalPath:y}}catch{return n()}}export{U as readVerifiedPreparedRootMemory,G as rootMemoryOperationJournalName};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export declare const ROOT_MEMORY_STEP_DIGEST = "638cc25234b6a507841c889ad7f5c8c1e33bd38aa20ca7818b0f21c4a3e9030e";
|
|
2
|
+
export declare const ROOT_MEMORY_REVIEW_CHECKS: string[];
|
|
3
|
+
export interface PrivateRootMemoryRequest {
|
|
4
|
+
readonly schemaVersion: 'PrivateYoloProjectMemoryAcceptance/1';
|
|
5
|
+
readonly executorStopped: true;
|
|
6
|
+
readonly directive: {
|
|
7
|
+
readonly schemaVersion: 1;
|
|
8
|
+
readonly action: 'review-project-memory-candidate';
|
|
9
|
+
readonly storyId: string;
|
|
10
|
+
readonly executionBranch: string;
|
|
11
|
+
readonly graphRevision: string;
|
|
12
|
+
readonly stepId: 'step-638cc252';
|
|
13
|
+
readonly publicSafe: true;
|
|
14
|
+
};
|
|
15
|
+
readonly review: {
|
|
16
|
+
readonly reviewer: 'root';
|
|
17
|
+
readonly decision: 'approve-project-memory';
|
|
18
|
+
readonly snapshotSha: string;
|
|
19
|
+
readonly proposalSha256: string;
|
|
20
|
+
readonly sourceStateSha256: string;
|
|
21
|
+
readonly rootQaReceiptId: string;
|
|
22
|
+
readonly rawStepId: string;
|
|
23
|
+
readonly reviewedAt: string;
|
|
24
|
+
readonly notes: readonly string[];
|
|
25
|
+
readonly checks: Readonly<Record<string, true>>;
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
export declare function parsePrivateRootMemoryRequest(value: unknown): PrivateRootMemoryRequest;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createHash as h}from"node:crypto";const v="638cc25234b6a507841c889ad7f5c8c1e33bd38aa20ca7818b0f21c4a3e9030e",c=["canonicalUpdateReviewed","acceptedQaReviewed","scopeReviewed","unresolvedGatesPreserved","platformTargetsReviewed","wrapperPreservationReviewed","mandatoryRequirementsResolved","noImplementationChange"];function u(n){const p=()=>{throw new Error("private-root-memory-review-unverified")},s=t=>t!==null&&typeof t=="object"&&!Array.isArray(t)?t:void 0,a=(t,d)=>Object.keys(t).sort().join("|")===d.sort().join("|"),o=s(n),r=s(o?.directive),e=s(o?.review),i=s(e?.checks);return!o||!r||!e||!i||!a(o,["schemaVersion","executorStopped","directive","review"])||o.schemaVersion!=="PrivateYoloProjectMemoryAcceptance/1"||o.executorStopped!==!0||!a(r,["schemaVersion","action","storyId","executionBranch","graphRevision","stepId","publicSafe"])||r.schemaVersion!==1||r.action!=="review-project-memory-candidate"||r.stepId!=="step-638cc252"||r.publicSafe!==!0||typeof r.storyId!="string"||!/^P[1-9][0-9]*\.[0-9]+$/.test(r.storyId)||r.executionBranch!==`epic/${r.storyId.split(".")[0]}`||typeof r.graphRevision!="string"||!/^[a-f0-9]{64}$/.test(r.graphRevision)||!a(e,["reviewer","decision","snapshotSha","proposalSha256","sourceStateSha256","rootQaReceiptId","rawStepId","reviewedAt","notes","checks"])||e.reviewer!=="root"||e.decision!=="approve-project-memory"||typeof e.snapshotSha!="string"||!/^[a-f0-9]{40,64}$/.test(e.snapshotSha)||["proposalSha256","sourceStateSha256","rootQaReceiptId"].some(t=>typeof e[t]!="string"||!/^[a-f0-9]{64}$/.test(e[t]))||typeof e.rawStepId!="string"||h("sha256").update(e.rawStepId).digest("hex")!==v||typeof e.reviewedAt!="string"||!Number.isFinite(Date.parse(e.reviewedAt))||Date.parse(e.reviewedAt)>Date.now()||Date.now()-Date.parse(e.reviewedAt)>10*6e4||!Array.isArray(e.notes)||e.notes.length<1||e.notes.length>8||e.notes.some(t=>typeof t!="string"||Buffer.byteLength(t)<1||Buffer.byteLength(t)>512)||!a(i,[...c])||c.some(t=>i[t]!==!0)?p():structuredClone(n)}export{c as ROOT_MEMORY_REVIEW_CHECKS,v as ROOT_MEMORY_STEP_DIGEST,u as parsePrivateRootMemoryRequest};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type RootProjectMemoryEffect } from '../../../shared/dist/yoloop/root-memory-effect.js';
|
|
2
|
+
export interface PrivateRootMemoryScope {
|
|
3
|
+
readonly __rootMemoryScope: never;
|
|
4
|
+
}
|
|
5
|
+
/** Absence means no extra scope; malformed or mismatched existing evidence fails closed. */
|
|
6
|
+
export declare function readPrivateRootMemoryScope(input: {
|
|
7
|
+
readonly projectRoot: string;
|
|
8
|
+
readonly storyId: string;
|
|
9
|
+
readonly snapshotRoot: string;
|
|
10
|
+
readonly snapshotSha: string;
|
|
11
|
+
readonly sourceHeadSha: string;
|
|
12
|
+
readonly executionBranch: string;
|
|
13
|
+
readonly graphRevision: string;
|
|
14
|
+
readonly setupSessionId: string;
|
|
15
|
+
readonly childPaths: readonly string[];
|
|
16
|
+
}): Promise<PrivateRootMemoryScope | undefined>;
|
|
17
|
+
/** A caller-provided object never supplies extra source or agent permissions. */
|
|
18
|
+
export declare function privateRootMemoryEffect(scope: PrivateRootMemoryScope): RootProjectMemoryEffect;
|
|
19
|
+
export declare function privateRootMemorySourceMatches(scope: PrivateRootMemoryScope, root: string, snapshotRoot?: string, snapshotSha?: string): boolean;
|
|
20
|
+
export declare function privateRootMemorySourceMatchReason(scope: PrivateRootMemoryScope, root: string, snapshotRoot?: string, snapshotSha?: string): string;
|
|
21
|
+
/** C08 selection comes from actual private custody, never caller-supplied JSON. */
|
|
22
|
+
export declare function readRootMemoryEffectForCheckpoint(input: {
|
|
23
|
+
readonly projectRoot: string;
|
|
24
|
+
readonly storyId: string;
|
|
25
|
+
readonly graphRevision: string;
|
|
26
|
+
readonly executionBranch: string;
|
|
27
|
+
readonly childPaths: readonly string[];
|
|
28
|
+
}): Promise<RootProjectMemoryEffect | undefined>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createHash as S}from"node:crypto";import{execFileSync as A}from"node:child_process";import{existsSync as B,readFileSync as l}from"node:fs";import{join as g,resolve as w}from"node:path";import{isDeepStrictEqual as u}from"node:util";import{isRootProjectMemoryEffect as _}from"../../../shared/dist/yoloop/root-memory-effect.js";import{assertGitLifecyclePrivateFile as R,ensureGitLifecyclePrivateChildDirectory as k,gitLifecycleRuntimeDirectory as P,readGitLifecycleRuntime as H}from"../git/git-lifecycle-store.js";import{rootMemoryGitFileState as I,verifyRootMemoryEffectGitEvidence as C,verifyRootMemoryPhysicalWriteSet as $}from"./root-memory-git-evidence.js";import{rootMemoryFileState as G}from"./root-memory-writer.js";import{ROOT_MEMORY_REVIEW_CHECKS as b,ROOT_MEMORY_STEP_DIGEST as T}from"./root-memory-request.js";import{parseRefreshMemoryArgs as q,verifyProjectMemoryTargets as F}from"../commands/refresh-memory.js";const j=new WeakMap,n=()=>{throw new Error("private-root-memory-scope-unverified")};function m(e,o){return A("git",[...o],{cwd:e,encoding:"utf8",stdio:["ignore","pipe","ignore"],env:{...Object.fromEntries(Object.entries(process.env).filter(([h])=>!h.startsWith("GIT_"))),GIT_NO_REPLACE_OBJECTS:"1"},timeout:3e4,maxBuffer:2*1024*1024})}async function J(e){let o="pin";try{const h=w(e.projectRoot);if(!/^P[1-9][0-9]*\.[0-9]+$/.test(e.storyId))return n();const r=await k(await P(h),"private-execution"),a=g(r,`session-${S("sha256").update(e.storyId).digest("hex")}.json`);await R(a,r);const i=l(a);if(i.length>128*1024)return n();const s=JSON.parse(i.toString("utf8"));if(o="binding",s.storyId!==e.storyId||s.graphRevision!==e.graphRevision||s.setupSessionId!==e.setupSessionId||s.snapshotSha!==e.snapshotSha||s.workspace?.sourceRoot!==h||s.workspace?.workspacePath!==e.snapshotRoot||s.workspace?.baseSha!==e.sourceHeadSha||s.workspace?.executionBranch!==e.executionBranch)return n();if(s.rootMemoryEffect===void 0)return;const t=s.rootMemoryEffect;if(!_(t)||!Array.isArray(s.graphHistory)||!s.graphHistory.includes(t.graphRevision))return n();o="producer-receipt";const d=f=>S("sha256").update(f).digest("hex"),y=g(r,`memory-review-${d(JSON.stringify(t))}.json`);await R(y,r);const x=l(y);if(x.length>128*1024)return n();const c=JSON.parse(x.toString("utf8"));if(Object.keys(c).sort().join("|")!==["schemaVersion","kind","storyId","graphRevision","sourceHeadSha","snapshotSha","proposalSha256","notesSha256","sourceStateSha256","checks","reviewedAt","rootMemoryEffect","independentStoryQaAccepted","terminalAccepted"].sort().join("|")||c.schemaVersion!==1||c.kind!=="private-project-memory-root-review"||c.storyId!==e.storyId||c.graphRevision!==t.graphRevision||c.sourceHeadSha!==e.sourceHeadSha||c.snapshotSha!==t.memorySnapshotSha||c.notesSha256!==t.proposalSha256||c.reviewedAt!==t.recordedAt||c.independentStoryQaAccepted!==!1||c.terminalAccepted!==!1||!u(c.rootMemoryEffect,t)||!c.checks||Object.keys(c.checks).sort().join("|")!==[...b].sort().join("|")||b.some(f=>c.checks[f]!==!0)||c.proposalSha256!==d(Buffer.from(m(e.snapshotRoot,["show",`${t.sourceSnapshotSha}:.neocortex/stories/${e.storyId}/validation-evidence.md`])))||c.sourceStateSha256!==d(Buffer.from(m(e.snapshotRoot,["show",`${t.sourceSnapshotSha}:.neocortex/state.json`]))))return n();const E=g(r,`qa-review-${t.rootQaReceiptId}.json`);await R(E,r);const v=l(E);if(v.length>16384||d(v)!==t.rootQaReceiptId)return n();const p=JSON.parse(v.toString("utf8"));if(p.kind!=="private-qa-root-review"||p.storyId!==e.storyId||p.sourceHeadSha!==e.sourceHeadSha||p.precommitQaAccepted!==!0||p.independentStoryQaAccepted!==!1||p.terminalAccepted!==!1||(m(e.snapshotRoot,["merge-base","--is-ancestor",p.snapshotSha,t.sourceSnapshotSha]),o="git-evidence",C(e.snapshotRoot,t,{storyId:e.storyId,executionBranch:e.executionBranch,sourceHeadSha:e.sourceHeadSha,graphRevision:t.graphRevision,setupSessionId:e.setupSessionId,childClaimRevision:S("sha256").update([...e.childPaths].sort().join("\0")).digest("hex")}),o="range",m(e.snapshotRoot,["merge-base","--is-ancestor",t.memorySnapshotSha,e.snapshotSha]),m(e.snapshotRoot,["diff","--name-only","--no-renames","--no-ext-diff","--no-textconv","-z",e.sourceHeadSha,e.snapshotSha]).split("\0").filter(Boolean).some(f=>!e.childPaths.includes(f)&&!t.files.some(O=>O.path===f))))return n();o="files";for(const f of t.files)if(e.childPaths.includes(f.path)||!u(I(e.snapshotRoot,e.sourceHeadSha,f.path),f.before)||!u(I(e.snapshotRoot,e.snapshotSha,f.path),f.after))return n();const M=Object.freeze(Object.create(null));return j.set(M,Object.freeze({effect:structuredClone(t),root:h,snapshotRoot:e.snapshotRoot})),M}catch{throw new Error(`private-root-memory-scope-${o}-unverified`)}}function N(e){const o=j.get(e);return o?structuredClone(o.effect):n()}function Q(e,o,h,r){return L(e,o,h,r)==="matched"}function L(e,o,h,r){const a=j.get(e);if(!a||a.root!==w(o)||h!==void 0&&h!==a.snapshotRoot)return"scope-binding";let i="snapshot-ancestry";try{if(r&&(m(a.snapshotRoot,["merge-base","--is-ancestor",a.effect.memorySnapshotSha,r]),i="snapshot-content",a.effect.files.some(t=>!u(I(a.snapshotRoot,r,t.path),t.after)))||(i="source-content",!a.effect.files.every(t=>u(G(o,t.path),t.after))))return i;i="source-projection";const s=F(q(["--project-root",o,"--verify"]));return s.canonicalSha256===a.effect.canonicalSha256&&s.projectionSha256===a.effect.projectionSha256&&s.fileCount===a.effect.projectionFileCount?"matched":i}catch{return i+"-unsafe"}}async function re(e){try{const o=w(e.projectRoot),h=await H(o,{required:!0}),r=h.stories[e.storyId]?.checkpoint;if(r?.rootMemoryEffect!==void 0)return r.storyId!==e.storyId||r.branch!==e.executionBranch||typeof r.baseSha!="string"||typeof r.headSha!="string"?n():structuredClone($(o,r.rootMemoryEffect,{storyId:e.storyId,executionBranch:e.executionBranch,baseSha:r.baseSha,headRef:r.headSha,childPaths:e.childPaths}));if(!/^P[1-9][0-9]*\.[0-9]+$/.test(e.storyId))return;const a=await k(await P(o),"private-execution"),i=g(a,`session-${S("sha256").update(e.storyId).digest("hex")}.json`);if(!B(i))return;await R(i,a);const s=l(i);if(s.length>128*1024)return n();const t=JSON.parse(s.toString("utf8"));if(t.rootMemoryEffect===void 0)return;const d=h.stories[e.storyId];if(d?.status!=="memory-updated"||typeof d.last_step!="string"||S("sha256").update(d.last_step).digest("hex")!==T||!Array.isArray(d.steps_completed)||d.steps_completed.at(-1)!==d.last_step)return n();const y=await J({projectRoot:o,storyId:e.storyId,snapshotRoot:t.workspace?.workspacePath,snapshotSha:t.snapshotSha,sourceHeadSha:t.workspace?.baseSha,executionBranch:e.executionBranch,graphRevision:e.graphRevision,setupSessionId:t.setupSessionId,childPaths:e.childPaths});return!y||!Q(y,o,t.workspace?.workspacePath,t.snapshotSha)?n():N(y)}catch{return n()}}export{N as privateRootMemoryEffect,L as privateRootMemorySourceMatchReason,Q as privateRootMemorySourceMatches,J as readPrivateRootMemoryScope,re as readRootMemoryEffectForCheckpoint};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type RootMemoryFileEffect, type RootMemoryFileState } from '../../../shared/dist/yoloop/root-memory-effect.js';
|
|
2
|
+
import { type ProjectMemoryVerification } from '../commands/refresh-memory.js';
|
|
3
|
+
export interface RootMemoryWriterAuthority {
|
|
4
|
+
readonly __rootMemoryWriter?: never;
|
|
5
|
+
}
|
|
6
|
+
export interface RootMemoryWriterExecution {
|
|
7
|
+
readonly snapshotRoot: string;
|
|
8
|
+
readonly sourceSnapshotSha: string;
|
|
9
|
+
readonly notesSha256: string;
|
|
10
|
+
readonly files: readonly RootMemoryFileEffect[];
|
|
11
|
+
readonly verification: ProjectMemoryVerification;
|
|
12
|
+
}
|
|
13
|
+
export declare function rootMemoryFileState(root: string, path: string): RootMemoryFileState;
|
|
14
|
+
export declare function executeRootMemoryWriter(input: {
|
|
15
|
+
readonly snapshotRoot: string;
|
|
16
|
+
readonly expectedSnapshotSha: string;
|
|
17
|
+
readonly notes: readonly string[];
|
|
18
|
+
readonly backupDirectory: string;
|
|
19
|
+
}): RootMemoryWriterAuthority;
|
|
20
|
+
export declare function projectRootMemoryWriterExecution(authority: RootMemoryWriterAuthority): RootMemoryWriterExecution | undefined;
|
|
21
|
+
/** Recheck the actual writer output immediately before source admission. */
|
|
22
|
+
export declare function verifyRootMemoryWriterExecution(authority: RootMemoryWriterAuthority): RootMemoryWriterExecution;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{execFileSync as z}from"node:child_process";import{createHash as N}from"node:crypto";import{lstatSync as y,readFileSync as E,readlinkSync as D,realpathSync as v}from"node:fs";import{join as O,resolve as l}from"node:path";import{rootProjectMemoryPaths as j}from"../../../shared/dist/yoloop/root-memory-effect.js";import{parseRefreshMemoryArgs as x,refreshProjectMemoryTargets as M,verifyProjectMemoryTargets as J}from"../commands/refresh-memory.js";import{assertProjectMemoryPaths as w}from"../memory/project-memory-path-scope.js";import{classifyProjectMemoryUpdate as P}from"../memory/project-memory-writer.js";const d=r=>N("sha256").update(r).digest("hex"),h=new WeakMap,n=()=>{throw new Error("private-root-memory-writer-unverified")};function c(r,...e){return z("git",e,{cwd:r,encoding:"utf8",stdio:["ignore","pipe","ignore"],env:Object.fromEntries(Object.entries(process.env).filter(([i])=>!i.startsWith("GIT_"))),timeout:3e4,maxBuffer:2*1024*1024})}function m(r,e){if(!j().includes(e))return n();w(r,[e]);const i=O(r,e);let o;try{o=y(i)}catch(a){return a.code==="ENOENT"?{kind:"absent",sha256:null}:n()}if(o.uid!==process.getuid?.()||o.nlink!==1||(o.mode&18)!==0&&!o.isSymbolicLink())return n();if(o.isSymbolicLink()){const a=D(i);return l(r,e,"..",a)!==O(l(r),"NEOCORTEX.md")?n():{kind:"symlink",sha256:d(a),linkTarget:a}}return!o.isFile()||o.size>512*1024?n():{kind:"regular",sha256:d(E(i))}}function G(r){const e=l(r.snapshotRoot),i=l(r.backupDirectory),o=y(e),a=y(i);if(!o.isDirectory()||o.uid!==process.getuid?.()||(o.mode&63)!==0||v(e)!==e||!a.isDirectory()||a.isSymbolicLink()||a.uid!==process.getuid?.()||(a.mode&63)!==0||v(i)!==i||i===e||i.startsWith(e+"/")||!/^[a-f0-9]{40,64}$/.test(r.expectedSnapshotSha)||!Array.isArray(r.notes)||r.notes.length<1||r.notes.length>8||r.notes.some(t=>typeof t!="string"||Buffer.byteLength(t)<1||Buffer.byteLength(t)>512)||c(e,"rev-parse","HEAD").trim()!==r.expectedSnapshotSha||c(e,"status","--porcelain=v1","--untracked-files=all").length!==0)return n();for(const t of r.notes)P(t);const f=j(),g=new Map(f.map(t=>[t,m(e,t)])),S=x(["--project-root",e,...r.notes.flatMap(t=>["--note",t])]);if(M({...S,dryRun:!0}).some(t=>t.files.some(s=>s.fallbackReason||s.remediationDebt||s.mode==="compatibility-materialized-fallback"||!f.includes(s.relativeFile))))return n();for(const[t,s]of g)if(JSON.stringify(m(e,t))!==JSON.stringify(s))return n();if(M({...S,backupDirectory:i}).some(t=>t.files.some(s=>s.fallbackReason||s.remediationDebt||s.mode==="compatibility-materialized-fallback"||!f.includes(s.relativeFile))))return n();const R=J(x(["--project-root",e,"--verify"])),u=c(e,"status","--porcelain=v1","-z","--untracked-files=all").split("\0").filter(Boolean).map(t=>t.slice(3));if(u.some(t=>!f.includes(t))||c(e,"rev-parse","HEAD").trim()!==r.expectedSnapshotSha)return n();const p=f.flatMap(t=>{const s=g.get(t),k=m(e,t);return JSON.stringify(s)===JSON.stringify(k)?[]:[Object.freeze({path:t,before:Object.freeze(s),after:Object.freeze(k)})]});if(p.some(t=>!u.includes(t.path))||u.some(t=>!p.some(s=>s.path===t)))return n();const b=Object.freeze(Object.create(null));return h.set(b,Object.freeze({snapshotRoot:e,sourceSnapshotSha:r.expectedSnapshotSha,notesSha256:d(JSON.stringify(r.notes)),files:Object.freeze(p),verification:Object.freeze(R)})),b}function U(r){return h.get(r)}function X(r){const e=h.get(r);if(!e||c(e.snapshotRoot,"rev-parse","HEAD").trim()!==e.sourceSnapshotSha)return n();const i=c(e.snapshotRoot,"status","--porcelain=v1","-z","--untracked-files=all").split("\0").filter(Boolean).map(o=>o.slice(3)).sort();return JSON.stringify(i)!==JSON.stringify(e.files.map(o=>o.path).sort())||e.files.some(o=>JSON.stringify(m(e.snapshotRoot,o.path))!==JSON.stringify(o.after))?n():e}export{G as executeRootMemoryWriter,U as projectRootMemoryWriterExecution,m as rootMemoryFileState,X as verifyRootMemoryWriterExecution};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export declare function renewPrivateYoloSessionLease(projectRoot: string, storyId: string, graphRevision: string, input: {
|
|
2
|
+
readonly executorStopped: true;
|
|
3
|
+
readonly expectedSnapshotSha: string;
|
|
4
|
+
readonly expiresAt: string;
|
|
5
|
+
}): Promise<{
|
|
6
|
+
schemaVersion: "PrivateYoloSessionLeaseRenewal/1";
|
|
7
|
+
storyId: string;
|
|
8
|
+
graphRevision: string;
|
|
9
|
+
snapshotSha: string;
|
|
10
|
+
sourceHead: string;
|
|
11
|
+
previousExpiresAt: string;
|
|
12
|
+
expiresAt: string;
|
|
13
|
+
revision: number;
|
|
14
|
+
reused: boolean;
|
|
15
|
+
sessionPinPreserved: true;
|
|
16
|
+
originPreserved: true;
|
|
17
|
+
checkpointAccepted: false;
|
|
18
|
+
publicSafe: true;
|
|
19
|
+
}>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{resolve as g}from"node:path";import{acquireGitLifecyclePhysicalIntegrationLock as b,mutateGitLifecycleRuntime as A,readGitLifecycleRuntime as D,releaseGitLifecyclePhysicalIntegrationLock as k}from"../git/git-lifecycle-store.js";import{resumePrivateYoloIsolatedSession as m}from"./isolated-session.js";async function P(y,r,s,t){const n=g(y),c=Date.now(),i=Date.parse(t.expiresAt);if(t.executorStopped!==!0||!/^[a-f0-9]{40,64}$/.test(t.expectedSnapshotSha)||!Number.isFinite(i)||i<=c||i>c+3600*1e3)throw new Error("private-execution-session-renewal-input-invalid");const h=await D(n,{required:!0}),S=r.split(".")[0],p=h.epics[S],w=p?.branch_lease,e=w&&typeof w=="object"&&!Array.isArray(w)?w:void 0;if(!e||e.schemaVersion!==1||e.ownerStoryId!==r||e.sessionId!==e.idempotencyKey||typeof e.sessionId!="string"||p?.graph_revision!==s||typeof e.expiresAt!="string"||!Number.isFinite(Date.parse(e.expiresAt))||Date.parse(e.expiresAt)<=c||i<Date.parse(e.expiresAt)||!p.origin_binding)throw new Error("private-execution-session-renewal-authority-invalid");const l=e.sessionId,u=e.expiresAt,f=await b(n,{kind:"direct",storyId:r,sessionId:l,idempotencyKey:l,expiresAt:new Date(c+5*6e4).toISOString(),persistent:!1});if(!f.ok)throw new Error("private-execution-session-renewal-backpressure");try{const o=await m(n,r,s);if(o.snapshotSha!==t.expectedSnapshotSha||o.setupSessionId!==l||o.workspace.baseSha!==e.setupHeadSha)throw new Error("private-execution-session-renewal-pin-invalid");const x=new Date(i).toISOString();let v=h.revision;return Date.parse(u)!==i&&(v=(await A(n,d=>{const a=d.epics[S];if(!a||JSON.stringify(a.origin_binding)!==JSON.stringify(p.origin_binding)||JSON.stringify(a.branch_lease)!==JSON.stringify(e)||a.graph_revision!==s)throw new Error("private-execution-session-renewal-raced");a.branch_lease={...e,expiresAt:x}},{expectedRevision:h.revision,preCommit:async()=>{if(Date.parse(u)<=Date.now())throw new Error("private-execution-session-renewal-expired");const d=await m(n,r,s);if(d.snapshotSha!==t.expectedSnapshotSha||d.setupSessionId!==l)throw new Error("private-execution-session-renewal-raced")}})).document.revision),{schemaVersion:"PrivateYoloSessionLeaseRenewal/1",storyId:r,graphRevision:s,snapshotSha:o.snapshotSha,sourceHead:o.workspace.baseSha,previousExpiresAt:u,expiresAt:x,revision:v,reused:Date.parse(u)===i,sessionPinPreserved:!0,originPreserved:!0,checkpointAccepted:!1,publicSafe:!0}}finally{if(!await k(f.path,f.owner))throw new Error("private-execution-session-renewal-lock-unverified")}}export{P as renewPrivateYoloSessionLease};
|