@ornexus/neocortex 4.60.61 → 4.60.63

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.
Files changed (91) hide show
  1. package/dist/release-source.json +1 -0
  2. package/dist/sbom.cdx.json +196 -66
  3. package/install.ps1 +1 -1
  4. package/install.sh +1 -1
  5. package/package.json +13 -6
  6. package/packages/client/dist/cli.js +52 -2
  7. package/packages/client/dist/commands/invoke.d.ts +1 -0
  8. package/packages/client/dist/commands/invoke.js +81 -72
  9. package/packages/client/dist/commands/legacy-epic-terminal.d.ts +9 -0
  10. package/packages/client/dist/commands/legacy-epic-terminal.js +1 -0
  11. package/packages/client/dist/commands/legacy-story-pr.d.ts +2 -1
  12. package/packages/client/dist/commands/legacy-story-pr.js +1 -1
  13. package/packages/client/dist/commands/mutation-qa-checkpoint.d.ts +39 -0
  14. package/packages/client/dist/commands/mutation-qa-checkpoint.js +5 -0
  15. package/packages/client/dist/commands/mutation-qa-gate.d.ts +35 -0
  16. package/packages/client/dist/commands/mutation-qa-gate.js +1 -0
  17. package/packages/client/dist/commands/mutation-qa-git.d.ts +2 -0
  18. package/packages/client/dist/commands/mutation-qa-git.js +1 -0
  19. package/packages/client/dist/commands/mutation-qa-policy.d.ts +15 -0
  20. package/packages/client/dist/commands/mutation-qa-policy.js +1 -0
  21. package/packages/client/dist/commands/mutation-qa-run.d.ts +14 -0
  22. package/packages/client/dist/commands/mutation-qa-run.js +3 -0
  23. package/packages/client/dist/commands/mutation-qa-verdict.d.ts +21 -0
  24. package/packages/client/dist/commands/mutation-qa-verdict.js +1 -0
  25. package/packages/client/dist/commands/mutation-qa.d.ts +22 -0
  26. package/packages/client/dist/commands/mutation-qa.js +1 -0
  27. package/packages/client/dist/commands/property-qa.d.ts +1 -0
  28. package/packages/client/dist/commands/property-qa.js +1 -0
  29. package/packages/client/dist/commands/qa-scan-capture.d.ts +52 -0
  30. package/packages/client/dist/commands/qa-scan-capture.js +11 -0
  31. package/packages/client/dist/commands/qa-scan-discovery.d.ts +36 -0
  32. package/packages/client/dist/commands/qa-scan-discovery.js +3 -0
  33. package/packages/client/dist/commands/qa-scan-review.d.ts +119 -0
  34. package/packages/client/dist/commands/qa-scan-review.js +5 -0
  35. package/packages/client/dist/commands/refactor-characterization.d.ts +47 -0
  36. package/packages/client/dist/commands/refactor-characterization.js +12 -0
  37. package/packages/client/dist/commands/refactor-commit.d.ts +45 -0
  38. package/packages/client/dist/commands/refactor-commit.js +13 -0
  39. package/packages/client/dist/commands/refactor-review.d.ts +37 -0
  40. package/packages/client/dist/commands/refactor-review.js +5 -0
  41. package/packages/client/dist/commands/refactor-root.d.ts +85 -0
  42. package/packages/client/dist/commands/refactor-root.js +7 -0
  43. package/packages/client/dist/generated/command-registry.generated.d.ts +9 -9
  44. package/packages/client/dist/generated/command-registry.generated.js +1 -1
  45. package/packages/client/dist/generated/public-projections.generated.d.ts +20 -20
  46. package/packages/client/dist/generated/public-projections.generated.js +1 -1
  47. package/packages/client/dist/git/legacy-story-pr.d.ts +137 -6
  48. package/packages/client/dist/git/legacy-story-pr.js +51 -43
  49. package/packages/client/dist/license/license-client.js +1 -1
  50. package/packages/client/dist/package.json +1 -0
  51. package/packages/client/dist/private-execution/clean-baseline.d.ts +1 -0
  52. package/packages/client/dist/private-execution/clean-baseline.js +2 -2
  53. package/packages/client/dist/private-execution/delivery.d.ts +49 -4
  54. package/packages/client/dist/private-execution/delivery.js +4 -2
  55. package/packages/client/dist/private-execution/isolated-admission.d.ts +7 -0
  56. package/packages/client/dist/private-execution/isolated-admission.js +10 -10
  57. package/packages/client/dist/private-execution/isolated-session.js +2 -2
  58. package/packages/client/dist/private-execution/private-report-store.d.ts +17 -0
  59. package/packages/client/dist/private-execution/private-report-store.js +1 -0
  60. package/packages/client/dist/private-execution/property-test-candidate.d.ts +14 -0
  61. package/packages/client/dist/private-execution/property-test-candidate.js +1 -0
  62. package/packages/client/dist/private-execution/property-test-choices.d.ts +15 -0
  63. package/packages/client/dist/private-execution/property-test-choices.js +3 -0
  64. package/packages/client/dist/private-execution/property-test-plan.d.ts +65 -0
  65. package/packages/client/dist/private-execution/property-test-plan.js +7 -0
  66. package/packages/client/dist/private-execution/property-test-review.d.ts +58 -0
  67. package/packages/client/dist/private-execution/property-test-review.js +4 -0
  68. package/packages/client/dist/private-execution/property-test-runtime.d.ts +18 -0
  69. package/packages/client/dist/private-execution/property-test-runtime.js +9 -0
  70. package/packages/client/dist/private-execution/property-test-source.d.ts +8 -0
  71. package/packages/client/dist/private-execution/property-test-source.js +1 -0
  72. package/packages/client/dist/state/project-state-snapshot.js +1 -1
  73. package/packages/shared/dist/generated/command-registry.generated.js +9 -9
  74. package/packages/shared/dist/generated/invocation-schema.generated.js +2 -2
  75. package/packages/shared/dist/generated/public-projections.generated.js +18 -18
  76. package/packages/shared/dist/invocation/index.d.ts +1 -1
  77. package/packages/shared/dist/invocation/index.js +13 -0
  78. package/packages/shared/dist/merge-readiness/c12-registry-projection.js +111 -0
  79. package/packages/shared/dist/merge-readiness/c12-remote-observation.js +60 -0
  80. package/packages/shared/dist/package.json +1 -0
  81. package/targets-stubs/antigravity/gemini.md +1 -1
  82. package/targets-stubs/antigravity/skill/SKILL.md +1 -1
  83. package/targets-stubs/claude-code/neocortex-root.agent.yaml +1 -1
  84. package/targets-stubs/claude-code/neocortex-root.md +2 -2
  85. package/targets-stubs/claude-code/neocortex.agent.yaml +1 -1
  86. package/targets-stubs/claude-code/neocortex.md +2 -2
  87. package/targets-stubs/codex/AGENTS.md +1 -1
  88. package/targets-stubs/cursor/agent.md +2 -2
  89. package/targets-stubs/gemini-cli/agent.md +2 -2
  90. package/targets-stubs/opencode/neocortex-root.md +1 -1
  91. package/targets-stubs/vscode/neocortex.agent.md +2 -2
@@ -1,2 +1,2 @@
1
- import{execFileSync as k,spawnSync as A}from"node:child_process";import{createHash as x}from"node:crypto";import{existsSync as q,mkdirSync as C,readFileSync as D}from"node:fs";import{homedir as z}from"node:os";import{join as T,resolve as p}from"node:path";import{acquireGitLifecyclePhysicalIntegrationLock as N,assertGitLifecyclePrivateFile as B,ensureGitLifecyclePrivateChildDirectory as j,gitLifecycleRuntimeDirectory as H,readGitLifecycleRuntimeSync as L,releaseGitLifecyclePhysicalIntegrationLock as $}from"../git/git-lifecycle-store.js";import{anchoredAtomicWriteFile as Y}from"../git/secure-filesystem-boundary.js";import{readPrivateYoloFrozenWriteSet as d,readPrivateYoloFrozenWriteSetForTransition as F}from"./clean-baseline.js";import{admitPrivateYoloFrozenWorkspace as M,verifyPrivateYoloSnapshotBoundary as m}from"./isolated-admission.js";import{preparePrivateYoloIsolatedWorkspace as J}from"./isolated-workspace.js";function l(n,t){const e={...process.env};for(const s 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 e[s];return k("git",[...t],{cwd:n,env:e,encoding:"utf8",stdio:["ignore","pipe","pipe"],timeout:3e4,maxBuffer:16*1024*1024}).trim()}function y(n,t){const e={...process.env};for(const s 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 e[s];return k("git",[...t],{cwd:n,env:e,stdio:["ignore","pipe","pipe"],timeout:3e4,maxBuffer:16*1024*1024})}function b(n,t){const e={...process.env};for(const o 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 e[o];const s=A("git",[...t],{cwd:n,env:e,stdio:"ignore",timeout:3e4});if(s.error||s.signal)throw new Error("git-unverified");return s.status===0}async function P(n,t){const e=await H(n),s=await j(e,"private-execution"),o=`session-${x("sha256").update(t).digest("hex")}.json`;return{parent:s,name:o,path:T(s,o)}}function h(n,t){const e=t.split(".")[0],o=L(n,{required:!0}).epics[e]?.branch_lease,i=o&&typeof o=="object"&&!Array.isArray(o)?o:void 0,r=i?.sessionId;if(i?.ownerStoryId!==t||typeof r!="string"||!/^setup-[a-f0-9]{64}$/.test(r)||r!==i.idempotencyKey)throw new Error("session-lease-invalid");return r}function W(n){const t=JSON.parse(n);if(!t||typeof t!="object"||Array.isArray(t))throw new Error("session-invalid");const e=t,s=e.workspace;if(Object.keys(e).sort().join(",")!==["schemaVersion","kind","storyId","initialGraphRevision","graphRevision","graphHistory","setupSessionId","workspace","snapshotSha","sequence","lastPatchSha256"].sort().join(",")||e.schemaVersion!==1||e.kind!=="private-yolo-isolated-session"||typeof e.storyId!="string"||!/^[A-Za-z][A-Za-z0-9_-]*\.[A-Za-z0-9._-]+$/.test(e.storyId)||typeof e.initialGraphRevision!="string"||!/^[a-f0-9]{64}$/.test(e.initialGraphRevision)||typeof e.graphRevision!="string"||!/^[a-f0-9]{64}$/.test(e.graphRevision)||!Array.isArray(e.graphHistory)||e.graphHistory.length<1||e.graphHistory.length>65||e.graphHistory.some(i=>typeof i!="string"||!/^[a-f0-9]{64}$/.test(i))||new Set(e.graphHistory).size!==e.graphHistory.length||e.graphHistory[0]!==e.initialGraphRevision||e.graphHistory[e.graphHistory.length-1]!==e.graphRevision||typeof e.setupSessionId!="string"||!/^setup-[a-f0-9]{64}$/.test(e.setupSessionId)||typeof e.snapshotSha!="string"||!/^[a-f0-9]{40,64}$/.test(e.snapshotSha)||!Number.isSafeInteger(e.sequence)||Number(e.sequence)<0||Number(e.sequence)>64||Number(e.sequence)===0&&e.initialGraphRevision!==e.graphRevision||Number(e.sequence)===0&&e.lastPatchSha256!==null||Number(e.sequence)>0&&e.lastPatchSha256===null||e.lastPatchSha256!==null&&(typeof e.lastPatchSha256!="string"||!/^[a-f0-9]{64}$/.test(e.lastPatchSha256))||!s||typeof s!="object"||Array.isArray(s))throw new Error("session-invalid");const o=s;if(Object.keys(o).sort().join(",")!==["schemaVersion","sourceRoot","workspacePath","baseSha","executionBranch"].sort().join(",")||o.schemaVersion!==1||typeof o.sourceRoot!="string"||typeof o.workspacePath!="string"||typeof o.baseSha!="string"||!/^[a-f0-9]{40,64}$/.test(o.baseSha)||typeof o.executionBranch!="string"||!o.executionBranch)throw new Error("session-invalid");return e}async function f(n,t){const e=await P(n,t);if(q(e.path))return await B(e.path,e.parent),W(D(e.path,"utf8"))}async function v(n,t){const e=await P(n,t.storyId);await Y(e.parent,e.name,`${JSON.stringify(t)}
2
- `)}async function E(n,t,e,s){const o=await N(n,{kind:"direct",storyId:t,sessionId:e,idempotencyKey:e,expiresAt:new Date(Date.now()+3e5).toISOString(),persistent:!1});if(!o.ok)throw new Error("private-execution-isolated-session-backpressure");try{return await s()}finally{if(!await $(o.path,o.owner))throw new Error("private-execution-isolated-session-lock-unverified")}}async function g(n,t,e,s){G(n,t,e,s);const o=await d(t,e,n.workspace.executionBranch,s);m(n.workspace,o,n.snapshotSha)}function G(n,t,e,s){if(n.storyId!==e||n.graphRevision!==s||n.workspace.sourceRoot!==t||n.setupSessionId!==h(t,e)||n.sequence===0&&n.snapshotSha!==n.workspace.baseSha||n.sequence>0&&n.snapshotSha===n.workspace.baseSha)throw new Error("session-binding-invalid")}async function ie(n,t,e){const s=p(n.sourceRoot);try{const o=h(s,t);return await E(s,t,o,async()=>{const i=await f(s,t);if(i){if(await g(i,s,t,e),i.workspace.workspacePath!==n.workspacePath)throw new Error("session-replacement-denied");return i}const r=await d(s,t,n.executionBranch,e);m(n,r,n.baseSha);const c=Object.freeze({schemaVersion:1,kind:"private-yolo-isolated-session",storyId:t,initialGraphRevision:e,graphRevision:e,graphHistory:[e],setupSessionId:o,workspace:n,snapshotSha:n.baseSha,sequence:0,lastPatchSha256:null});return await v(s,c),c})}catch{throw new Error("private-execution-isolated-session-unverified")}}async function R(n,t,e,s){if(n.graphRevision===s)return await g(n,t,e,s),n;if(n.storyId!==e||n.workspace.sourceRoot!==t||n.setupSessionId!==h(t,e)||n.sequence===0||n.lastPatchSha256===null||n.graphHistory.includes(s)||n.graphHistory.length>=65)throw new Error("session-graph-transition-invalid");const o=await F(t,e,n.workspace.executionBranch,n.initialGraphRevision,s);m(n.workspace,o,n.snapshotSha);const i=Object.freeze({...n,graphRevision:s,graphHistory:Object.freeze([...n.graphHistory,s])});return await v(t,i),await g(i,t,e,s),i}async function oe(n,t,e){const s=p(n);try{const o=h(s,t);return await E(s,t,o,async()=>{const i=await f(s,t);if(!i)throw new Error("session-missing");return R(i,s,t,e)})}catch{throw new Error("private-execution-isolated-session-unverified")}}async function ae(n,t,e,s){const o=p(n);try{const i=h(o,t);return await E(o,t,i,async()=>{const r=await f(o,t);if(r)return R(r,o,t,e);const c=s??T(z(),".local","share","neocortex","private-yolo-workspaces");s===void 0&&C(c,{recursive:!0,mode:448});const a=J(o,c),u=await d(o,t,a.executionBranch,e);m(a,u,a.baseSha);const w=Object.freeze({schemaVersion:1,kind:"private-yolo-isolated-session",storyId:t,initialGraphRevision:e,graphRevision:e,graphHistory:[e],setupSessionId:i,workspace:a,snapshotSha:a.baseSha,sequence:0,lastPatchSha256:null});return await v(o,w),w})}catch{throw new Error("private-execution-isolated-session-unverified")}}async function re(n,t,e){const s=p(n);try{const o=await f(s,t);if(!o)throw new Error("session-missing");return await g(o,s,t,e),o}catch{throw new Error("private-execution-isolated-session-unverified")}}async function ce(n,t,e){const s=p(n);try{const o=h(s,t);return await E(s,t,o,async()=>{const i=await f(s,t);if(!i)throw new Error("session-missing");G(i,s,t,e);const r=await M(i.workspace,t,e,i.snapshotSha,i.sequence===0);l(i.workspace.workspacePath,["add","-A","--",...r.changedPaths]),l(i.workspace.workspacePath,["-c","core.hooksPath=/dev/null","-c","commit.gpgsign=false","-c","user.name=Neocortex Private Session","-c","user.email=private-session@neocortex.invalid","commit","-q","-m",`private snapshot ${t} ${i.sequence+1}`]);const c=l(i.workspace.workspacePath,["rev-parse","HEAD"]),a=await d(s,t,i.workspace.executionBranch,e);m(i.workspace,a,c);const u=Object.freeze({...i,snapshotSha:c,sequence:i.sequence+1,lastPatchSha256:r.patchSha256});return await v(s,u),{session:u,admission:r}})}catch{throw new Error("private-execution-isolated-session-unverified")}}async function he(n,t,e){const s=p(n);try{const o=h(s,t);return await E(s,t,o,async()=>{const i=await f(s,t);if(!i||i.sequence<1)throw new Error("session-incomplete");await g(i,s,t,e);const r=await d(s,t,i.workspace.executionBranch,e),c=i.workspace.workspacePath,a=y(c,["diff","--name-only","-z",i.workspace.baseSha,i.snapshotSha]).toString("utf8").split("\0").filter(Boolean).sort(),u=[".neocortex/state.json",`docs/stories/${t}.story.md`,`.neocortex/stories/${t}/qa-gate-result.json`,`.neocortex/stories/${t}/validation-evidence.md`,`.neocortex/stories/${t}/review.md`];if(a.length===0||a.length>1024||new Set(a).size!==a.length||a.some(S=>!r.includes(S))||u.some(S=>!a.includes(S)))throw new Error("bundle-incomplete");if(!b(s,["diff","--cached","--quiet"])||y(s,["ls-files","-u","-z"]).byteLength!==0)throw new Error("index-not-clean");const w=y(c,["diff","--binary","--full-index",i.workspace.baseSha,i.snapshotSha]);if(w.byteLength===0)throw new Error("bundle-empty");l(s,["add","-A","--",...a]);const I=y(s,["diff","--cached","--binary","--full-index"]),_=y(s,["diff","--cached","--name-only","-z"]).toString("utf8").split("\0").filter(Boolean).sort();if(!I.equals(w)||_.length!==a.length||_.some((S,O)=>S!==a[O])||!b(s,["diff","--quiet"])||l(s,["rev-parse","HEAD"])!==i.workspace.baseSha||l(s,["symbolic-ref","--quiet","--short","HEAD"])!==i.workspace.executionBranch)throw new Error("bundle-raced");return Object.freeze({schemaVersion:1,outcome:"staged-unverified",snapshotSha:i.snapshotSha,bundleSha256:x("sha256").update(I).digest("hex"),changedPaths:Object.freeze(a)})})}catch{throw new Error("private-execution-root-stage-unverified")}}export{ce as admitPrivateYoloIsolatedSessionStep,ie as beginPrivateYoloIsolatedSession,ae as ensurePrivateYoloIsolatedSession,oe as reconcilePrivateYoloIsolatedSession,re as resumePrivateYoloIsolatedSession,he as stagePrivateYoloIsolatedSessionBundle};
1
+ import{execFileSync as k,spawnSync as C}from"node:child_process";import{createHash as x}from"node:crypto";import{existsSync as D,mkdirSync as z,readFileSync as N}from"node:fs";import{homedir as B}from"node:os";import{join as T,resolve as p}from"node:path";import{acquireGitLifecyclePhysicalIntegrationLock as H,assertGitLifecyclePrivateFile as j,ensureGitLifecyclePrivateChildDirectory as L,gitLifecycleRuntimeDirectory as $,readGitLifecycleRuntimeSync as b,releaseGitLifecyclePhysicalIntegrationLock as Y}from"../git/git-lifecycle-store.js";import{anchoredAtomicWriteFile as F}from"../git/secure-filesystem-boundary.js";import{privateYoloRootOnlySetupReady as M,readPrivateYoloFrozenWriteSet as y,readPrivateYoloFrozenWriteSetForTransition as J}from"./clean-baseline.js";import{admitPrivateYoloFrozenWorkspace as W,verifyPrivateYoloSnapshotBoundary as m}from"./isolated-admission.js";import{preparePrivateYoloIsolatedWorkspace as V}from"./isolated-workspace.js";function l(s,t){const e={...process.env};for(const n 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 e[n];return k("git",[...t],{cwd:s,env:e,encoding:"utf8",stdio:["ignore","pipe","pipe"],timeout:3e4,maxBuffer:16*1024*1024}).trim()}function d(s,t){const e={...process.env};for(const n 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 e[n];return k("git",[...t],{cwd:s,env:e,stdio:["ignore","pipe","pipe"],timeout:3e4,maxBuffer:16*1024*1024})}function P(s,t){const e={...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 e[i];const n=C("git",[...t],{cwd:s,env:e,stdio:"ignore",timeout:3e4});if(n.error||n.signal)throw new Error("git-unverified");return n.status===0}async function G(s,t){const e=await $(s),n=await L(e,"private-execution"),i=`session-${x("sha256").update(t).digest("hex")}.json`;return{parent:n,name:i,path:T(n,i)}}function h(s,t){const e=t.split(".")[0],i=b(s,{required:!0}).epics[e]?.branch_lease,a=i&&typeof i=="object"&&!Array.isArray(i)?i:void 0,r=a?.sessionId;if(a?.ownerStoryId!==t||typeof r!="string"||!/^setup-[a-f0-9]{64}$/.test(r)||r!==a.idempotencyKey)throw new Error("session-lease-invalid");return r}function R(s,t){const e=b(s,{required:!0}).stories[t];return M(e)}function K(s){const t=JSON.parse(s);if(!t||typeof t!="object"||Array.isArray(t))throw new Error("session-invalid");const e=t,n=e.workspace;if(Object.keys(e).sort().join(",")!==["schemaVersion","kind","storyId","initialGraphRevision","graphRevision","graphHistory","setupSessionId","workspace","snapshotSha","sequence","lastPatchSha256"].sort().join(",")||e.schemaVersion!==1||e.kind!=="private-yolo-isolated-session"||typeof e.storyId!="string"||!/^[A-Za-z][A-Za-z0-9_-]*\.[A-Za-z0-9._-]+$/.test(e.storyId)||typeof e.initialGraphRevision!="string"||!/^[a-f0-9]{64}$/.test(e.initialGraphRevision)||typeof e.graphRevision!="string"||!/^[a-f0-9]{64}$/.test(e.graphRevision)||!Array.isArray(e.graphHistory)||e.graphHistory.length<1||e.graphHistory.length>65||e.graphHistory.some(a=>typeof a!="string"||!/^[a-f0-9]{64}$/.test(a))||new Set(e.graphHistory).size!==e.graphHistory.length||e.graphHistory[0]!==e.initialGraphRevision||e.graphHistory[e.graphHistory.length-1]!==e.graphRevision||typeof e.setupSessionId!="string"||!/^setup-[a-f0-9]{64}$/.test(e.setupSessionId)||typeof e.snapshotSha!="string"||!/^[a-f0-9]{40,64}$/.test(e.snapshotSha)||!Number.isSafeInteger(e.sequence)||Number(e.sequence)<0||Number(e.sequence)>64||Number(e.sequence)===0&&e.initialGraphRevision!==e.graphRevision&&e.graphHistory.length!==2||Number(e.sequence)===0&&e.lastPatchSha256!==null||Number(e.sequence)>0&&e.lastPatchSha256===null||e.lastPatchSha256!==null&&(typeof e.lastPatchSha256!="string"||!/^[a-f0-9]{64}$/.test(e.lastPatchSha256))||!n||typeof n!="object"||Array.isArray(n))throw new Error("session-invalid");const i=n;if(Object.keys(i).sort().join(",")!==["schemaVersion","sourceRoot","workspacePath","baseSha","executionBranch"].sort().join(",")||i.schemaVersion!==1||typeof i.sourceRoot!="string"||typeof i.workspacePath!="string"||typeof i.baseSha!="string"||!/^[a-f0-9]{40,64}$/.test(i.baseSha)||typeof i.executionBranch!="string"||!i.executionBranch)throw new Error("session-invalid");return e}async function f(s,t){const e=await G(s,t);if(D(e.path))return await j(e.path,e.parent),K(N(e.path,"utf8"))}async function v(s,t){const e=await G(s,t.storyId);await F(e.parent,e.name,`${JSON.stringify(t)}
2
+ `)}async function g(s,t,e,n){const i=await H(s,{kind:"direct",storyId:t,sessionId:e,idempotencyKey:e,expiresAt:new Date(Date.now()+3e5).toISOString(),persistent:!1});if(!i.ok)throw new Error("private-execution-isolated-session-backpressure");try{return await n()}finally{if(!await Y(i.path,i.owner))throw new Error("private-execution-isolated-session-lock-unverified")}}async function E(s,t,e,n){O(s,t,e,n);const i=await y(t,e,s.workspace.executionBranch,n);m(s.workspace,i,s.snapshotSha)}function O(s,t,e,n){if(s.storyId!==e||s.graphRevision!==n||s.workspace.sourceRoot!==t||s.setupSessionId!==h(t,e)||s.sequence===0&&s.snapshotSha!==s.workspace.baseSha||s.sequence===0&&s.graphHistory.length>1&&!R(t,e)||s.sequence>0&&s.snapshotSha===s.workspace.baseSha)throw new Error("session-binding-invalid")}async function oe(s,t,e){const n=p(s.sourceRoot);try{const i=h(n,t);return await g(n,t,i,async()=>{const a=await f(n,t);if(a){if(await E(a,n,t,e),a.workspace.workspacePath!==s.workspacePath)throw new Error("session-replacement-denied");return a}const r=await y(n,t,s.executionBranch,e);m(s,r,s.baseSha);const c=Object.freeze({schemaVersion:1,kind:"private-yolo-isolated-session",storyId:t,initialGraphRevision:e,graphRevision:e,graphHistory:[e],setupSessionId:i,workspace:s,snapshotSha:s.baseSha,sequence:0,lastPatchSha256:null});return await v(n,c),c})}catch{throw new Error("private-execution-isolated-session-unverified")}}async function A(s,t,e,n){if(s.graphRevision===n)return await E(s,t,e,n),s;if(s.storyId!==e||s.workspace.sourceRoot!==t||s.setupSessionId!==h(t,e)||s.sequence===0&&(s.graphHistory.length!==1||s.lastPatchSha256!==null||!R(t,e))||s.sequence>0&&s.lastPatchSha256===null||s.graphHistory.includes(n)||s.graphHistory.length>=65)throw new Error("session-graph-transition-invalid");const i=await J(t,e,s.workspace.executionBranch,s.initialGraphRevision,n);m(s.workspace,i,s.snapshotSha);const a=Object.freeze({...s,graphRevision:n,graphHistory:Object.freeze([...s.graphHistory,n])});return await v(t,a),await E(a,t,e,n),a}async function re(s,t,e){const n=p(s);try{const i=h(n,t);return await g(n,t,i,async()=>{const a=await f(n,t);if(!a)throw new Error("session-missing");return A(a,n,t,e)})}catch{throw new Error("private-execution-isolated-session-unverified")}}async function ce(s,t,e,n){const i=p(s);try{const a=h(i,t);return await g(i,t,a,async()=>{const r=await f(i,t);if(r)return A(r,i,t,e);const c=n??T(B(),".local","share","neocortex","private-yolo-workspaces");n===void 0&&z(c,{recursive:!0,mode:448});const o=V(i,c),u=await y(i,t,o.executionBranch,e);m(o,u,o.baseSha);const w=Object.freeze({schemaVersion:1,kind:"private-yolo-isolated-session",storyId:t,initialGraphRevision:e,graphRevision:e,graphHistory:[e],setupSessionId:a,workspace:o,snapshotSha:o.baseSha,sequence:0,lastPatchSha256:null});return await v(i,w),w})}catch{throw new Error("private-execution-isolated-session-unverified")}}async function he(s,t,e){const n=p(s);try{const i=await f(n,t);if(!i)throw new Error("session-missing");return await E(i,n,t,e),i}catch{throw new Error("private-execution-isolated-session-unverified")}}async function ue(s,t,e){const n=p(s);try{const i=h(n,t);return await g(n,t,i,async()=>{const a=await f(n,t);if(!a)throw new Error("session-missing");O(a,n,t,e);const r=await W(a.workspace,t,e,a.snapshotSha);l(a.workspace.workspacePath,["add","-A","--",...r.changedPaths]),l(a.workspace.workspacePath,["-c","core.hooksPath=/dev/null","-c","commit.gpgsign=false","-c","user.name=Neocortex Private Session","-c","user.email=private-session@neocortex.invalid","commit","-q","-m",`private snapshot ${t} ${a.sequence+1}`]);const c=l(a.workspace.workspacePath,["rev-parse","HEAD"]),o=await y(n,t,a.workspace.executionBranch,e);m(a.workspace,o,c);const u=Object.freeze({...a,snapshotSha:c,sequence:a.sequence+1,lastPatchSha256:r.patchSha256});return await v(n,u),{session:u,admission:r}})}catch{throw new Error("private-execution-isolated-session-unverified")}}async function pe(s,t,e){const n=p(s);try{const i=h(n,t);return await g(n,t,i,async()=>{const a=await f(n,t);if(!a||a.sequence<1)throw new Error("session-incomplete");await E(a,n,t,e);const r=await y(n,t,a.workspace.executionBranch,e),c=a.workspace.workspacePath,o=d(c,["diff","--name-only","-z",a.workspace.baseSha,a.snapshotSha]).toString("utf8").split("\0").filter(Boolean).sort(),u=[".neocortex/state.json",`docs/stories/${t}.story.md`,`.neocortex/stories/${t}/qa-gate-result.json`,`.neocortex/stories/${t}/validation-evidence.md`,`.neocortex/stories/${t}/review.md`];if(o.length===0||o.length>1024||new Set(o).size!==o.length||o.some(S=>!r.includes(S))||u.some(S=>!o.includes(S)))throw new Error("bundle-incomplete");if(!P(n,["diff","--cached","--quiet"])||d(n,["ls-files","-u","-z"]).byteLength!==0)throw new Error("index-not-clean");const w=d(c,["diff","--binary","--full-index",a.workspace.baseSha,a.snapshotSha]);if(w.byteLength===0)throw new Error("bundle-empty");l(n,["add","-A","--",...o]);const I=d(n,["diff","--cached","--binary","--full-index"]),_=d(n,["diff","--cached","--name-only","-z"]).toString("utf8").split("\0").filter(Boolean).sort();if(!I.equals(w)||_.length!==o.length||_.some((S,q)=>S!==o[q])||!P(n,["diff","--quiet"])||l(n,["rev-parse","HEAD"])!==a.workspace.baseSha||l(n,["symbolic-ref","--quiet","--short","HEAD"])!==a.workspace.executionBranch)throw new Error("bundle-raced");return Object.freeze({schemaVersion:1,outcome:"staged-unverified",snapshotSha:a.snapshotSha,bundleSha256:x("sha256").update(I).digest("hex"),changedPaths:Object.freeze(o)})})}catch{throw new Error("private-execution-root-stage-unverified")}}export{ue as admitPrivateYoloIsolatedSessionStep,oe as beginPrivateYoloIsolatedSession,ce as ensurePrivateYoloIsolatedSession,re as reconcilePrivateYoloIsolatedSession,he as resumePrivateYoloIsolatedSession,pe as stagePrivateYoloIsolatedSessionBundle};
@@ -0,0 +1,17 @@
1
+ export interface PrivateReportReceiptV1 {
2
+ readonly schemaVersion: 1;
3
+ readonly kind: 'private-ui-ux-review-report';
4
+ readonly format: 'markdown' | 'json';
5
+ readonly sha256: string;
6
+ readonly byteLength: number;
7
+ readonly path: string;
8
+ readonly reused: boolean;
9
+ readonly publicSafe: true;
10
+ }
11
+ /** The returned path is local-only; callers must never place report bytes in public metadata. */
12
+ export declare function storePrivateUiUxReviewReport(options: {
13
+ readonly projectRoot: string;
14
+ readonly material: string;
15
+ readonly format: 'markdown' | 'json';
16
+ readonly sha256: string;
17
+ }): Promise<PrivateReportReceiptV1>;
@@ -0,0 +1 @@
1
+ import{createHash as f}from"node:crypto";import{existsSync as m,readFileSync as s}from"node:fs";import{join as h}from"node:path";import{assertGitLifecyclePrivateFile as l,ensureGitLifecyclePrivateChildDirectory as u,gitLifecycleRuntimeDirectory as p}from"../git/git-lifecycle-store.js";import{anchoredAtomicWriteFile as v}from"../git/secure-filesystem-boundary.js";async function x(r){try{if(r.format!=="markdown"&&r.format!=="json"||typeof r.material!="string"||!/^[a-f0-9]{64}$/.test(r.sha256))throw new Error("private-report-input-invalid");const e=Buffer.from(r.material,"utf8");if(e.length===0||e.length>1024*1024||f("sha256").update(e).digest("hex")!==r.sha256)throw new Error("private-report-digest-invalid");if(r.format==="json"){const i=JSON.parse(r.material);if(!i||typeof i!="object"||Array.isArray(i))throw new Error("private-report-json-invalid")}const c=await p(r.projectRoot),a=await u(c,"private-ui-ux-reports"),o=`${r.sha256}.${r.format==="json"?"json":"md"}`,t=h(a,o),n=m(t);if(n||await v(a,o,e),await l(t,a),!s(t).equals(e))throw new Error("private-report-readback-invalid");return Object.freeze({schemaVersion:1,kind:"private-ui-ux-review-report",format:r.format,sha256:r.sha256,byteLength:e.length,path:t,reused:n,publicSafe:!0})}catch{throw new Error("private-execution-report-store-unverified")}}export{x as storePrivateUiUxReviewReport};
@@ -0,0 +1,14 @@
1
+ export interface PropertyTestCandidateReceiptV1 {
2
+ readonly schemaVersion: 1;
3
+ readonly kind: 'property-test-candidate-inspection';
4
+ readonly sourceHead: string;
5
+ readonly planSha256: string;
6
+ readonly artifactSha256: string;
7
+ readonly testFileCount: number;
8
+ readonly sourceSyntaxChecked: boolean;
9
+ readonly executionVerified: false;
10
+ readonly qaAccepted: false;
11
+ readonly publicSafe: true;
12
+ }
13
+ /** No test execution, state write or semantic QA; only exact physical candidate bytes. */
14
+ export declare function inspectPropertyTestCandidate(projectRoot: string): PropertyTestCandidateReceiptV1;
@@ -0,0 +1 @@
1
+ import{createHash as F}from"node:crypto";import{lstatSync as T,readFileSync as x}from"node:fs";import{join as b}from"node:path";import{isDeepStrictEqual as d}from"node:util";import{mutationQaGit as m}from"../commands/mutation-qa-git.js";import{loadPropertyTestCandidatePlan as k}from"./property-test-choices.js";import{inspectPropertyTestCatalog as A,renderPropertyTestConfiguration as _}from"./property-test-plan.js";import{validatePropertyTestTypeScriptSource as D}from"./property-test-source.js";function s(n){return F("sha256").update(n).digest("hex")}function l(n,r){let i=n;const a=r.split("/");if(a.some(t=>!/^[A-Za-z0-9_.-]+$/.test(t)||t==="."||t===".."))throw new Error("property-test-candidate-path-invalid");for(const[t,g]of a.entries()){i=b(i,g);const p=T(i);if(p.isSymbolicLink()||(t===a.length-1?!p.isFile()||p.size<1||p.size>2e6:!p.isDirectory()))throw new Error("property-test-candidate-path-invalid")}return x(i)}function P(n){return m(n,["status","--porcelain=v1","-z","--untracked-files=all"]).toString("utf8").split("\0").filter(Boolean).sort()}function q(n){try{const{root:r,head:i,choices:a,plan:t}=k(n);if(t.schemaVersion!==1||!["prd.md","docs/architecture/prd.md"].includes(t.prdPath)||t.planSha256.length!==64||t.writeSet.length<1||t.writeSet.length!==t.aggregates.length||t.checkpointAccepted!==!1||t.publicSafe!==!0||t.prdSha256!==a.prdSha256||t.language!==a.language||t.numRuns!==a.numRuns||t.aggregates.some(e=>a.mappings[e.name]!==e.implementationFile||!Number.isSafeInteger(e.invariantCount)||e.invariantCount<1)||!d(t.writeSet,t.aggregates.map(e=>e.testFile).sort()))throw new Error("property-test-candidate-plan-invalid");const{planSha256:g,checkpointAccepted:p,publicSafe:z,...E}=t;if(s(JSON.stringify(E))!==t.planSha256)throw new Error("property-test-candidate-plan-invalid");const y=A(r);if(y.prdPath!==t.prdPath||!d(y.aggregates.map(({name:e,invariantCount:o})=>({name:e,invariantCount:o})),t.aggregates.map(({name:e,invariantCount:o})=>({name:e,invariantCount:o}))))throw new Error("property-test-candidate-plan-invalid");const w=m(r,["show",`HEAD:${t.prdPath}`]);if(s(w)!==t.prdSha256)throw new Error("property-test-candidate-preimage-drift");const S=l(r,t.prdPath),u=new TextDecoder("utf-8",{fatal:!0}).decode(S),v=[...u.matchAll(/^- Generated at: (\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z)$/gm)];if(v.length!==1||u.split("## Property Test Configuration").length!==2||u!==_(new TextDecoder("utf-8",{fatal:!0}).decode(w),t,v[0][1]))throw new Error("property-test-candidate-prd-invalid");const C=[t.prdPath,...t.writeSet].sort(),f=P(r);if(!d(f.map(e=>e.slice(3)).sort(),C)||f.some(e=>![" M ","?? "].includes(e.slice(0,3))))throw new Error("property-test-candidate-scope-invalid");const h=[[t.prdPath,s(S)]];for(const e of t.aggregates){const o=l(r,e.implementationFile);if(s(o)!==e.implementationSha256)throw new Error("property-test-candidate-preimage-drift");const c=new TextDecoder("utf-8",{fatal:!0}).decode(l(r,e.testFile));if(t.language==="typescript")D({source:c,testFile:e.testFile,implementationFile:e.implementationFile,invariantCount:e.invariantCount,numRuns:t.numRuns});else if((c.match(/^def\s+test_[A-Za-z0-9_]+\s*\(/gm)??[]).length<e.invariantCount||!c.includes(String(t.numRuns)))throw new Error("property-test-candidate-source-invalid");h.push([e.testFile,s(c)])}if(m(r,["rev-parse","--verify","HEAD"]).toString("utf8").trim()!==i||!d(P(r),f)||h.some(([e,o])=>s(l(r,e))!==o))throw new Error("property-test-candidate-physical-drift");return Object.freeze({schemaVersion:1,kind:"property-test-candidate-inspection",sourceHead:i,planSha256:t.planSha256,artifactSha256:s(`property-test-candidate-v1\0${JSON.stringify(h)}`),testFileCount:t.writeSet.length,sourceSyntaxChecked:t.language==="typescript",executionVerified:!1,qaAccepted:!1,publicSafe:!0})}catch{throw new Error("property-test-candidate-unverified")}}export{q as inspectPropertyTestCandidate};
@@ -0,0 +1,15 @@
1
+ import { type PropertyTestChoices, type PropertyTestPlan } from './property-test-plan.js';
2
+ /** Save an explicit local choice, replacing only this private record. No tracked file is touched. */
3
+ export declare function savePropertyTestChoices(projectRoot: string, choices: PropertyTestChoices): PropertyTestPlan;
4
+ /** Load only a plan still bound to the current physical HEAD and file preimages. */
5
+ export declare function loadPropertyTestChoices(projectRoot: string): {
6
+ readonly choices: PropertyTestChoices;
7
+ readonly plan: PropertyTestPlan;
8
+ } | undefined;
9
+ /** A v2 plan remains readable after its authorized PRD/test patch; no acceptance is inferred. */
10
+ export declare function loadPropertyTestCandidatePlan(projectRoot: string): {
11
+ readonly root: string;
12
+ readonly head: string;
13
+ readonly choices: PropertyTestChoices;
14
+ readonly plan: PropertyTestPlan;
15
+ };
@@ -0,0 +1,3 @@
1
+ import{createHash as O,randomUUID as k}from"node:crypto";import{closeSync as w,existsSync as p,fsyncSync as v,lstatSync as l,mkdirSync as b,openSync as E,readFileSync as P,realpathSync as j,renameSync as $,unlinkSync as A,writeFileSync as J}from"node:fs";import{isAbsolute as N,join as y,resolve as f}from"node:path";import{confirmPropertyTestPlan as m}from"./property-test-plan.js";import{mutationQaGit as x}from"../commands/mutation-qa-git.js";function H(n){return O("sha256").update(n).digest("hex")}function d(n,t){return x(n,t).toString("utf8").trim()}function S(n,t){const o=f(n),s=d(o,["rev-parse","--show-toplevel"]),r=d(o,["rev-parse","--verify","HEAD"]),e=d(o,["rev-parse","--git-common-dir"]),i=N(e)?f(e):f(o,e);if(j(o)!==o||f(s)!==o||!/^[a-f0-9]{40,64}$/.test(r)||j(i)!==i||l(i).isSymbolicLink()||l(i).uid!==process.getuid?.())throw new Error("property-test-private-store-invalid");const a=y(i,"neocortex-property-test");if(t&&b(a,{recursive:!0,mode:448}),p(a)){const c=l(a);if(!c.isDirectory()||c.isSymbolicLink()||c.uid!==process.getuid?.()||(c.mode&63)!==0)throw new Error("property-test-private-store-invalid")}return{root:o,directory:a,head:r}}function C(n,t,o){const s={prdSha256:t.prdSha256,language:t.language,numRuns:t.numRuns,mappings:Object.fromEntries(Object.entries(t.mappings).sort(([e],[i])=>e.localeCompare(i)))},r={schemaVersion:"PropertyTestChoices/2",sourceHead:n,choices:s,planSha256:o.planSha256,plan:o};return{...r,checksumSha256:H(`property-test-choices-v2\0${JSON.stringify(r)}`)}}function g(n){const t=l(n);if(!t.isFile()||t.isSymbolicLink()||t.uid!==process.getuid?.()||(t.mode&63)!==0||t.size<1||t.size>32768)throw new Error("property-test-private-store-invalid");const o=P(n,"utf8"),s=JSON.parse(o);if(!s||typeof s!="object"||Array.isArray(s))throw new Error("property-test-private-store-invalid");const r=s,e=r.schemaVersion==="PropertyTestChoices/2";if(Object.keys(r).sort().join(",")!==["schemaVersion","sourceHead","choices","planSha256",...e?["plan"]:[],"checksumSha256"].sort().join(",")||!["PropertyTestChoices/1","PropertyTestChoices/2"].includes(String(r.schemaVersion))||typeof r.sourceHead!="string"||!/^[a-f0-9]{40,64}$/.test(r.sourceHead)||typeof r.planSha256!="string"||!/^[a-f0-9]{64}$/.test(r.planSha256)||typeof r.checksumSha256!="string"||!/^[a-f0-9]{64}$/.test(r.checksumSha256)||!r.choices||typeof r.choices!="object"||Array.isArray(r.choices)||e&&(!r.plan||typeof r.plan!="object"||Array.isArray(r.plan)||r.plan.planSha256!==r.planSha256))throw new Error("property-test-private-store-invalid");const i={schemaVersion:r.schemaVersion,sourceHead:r.sourceHead,choices:r.choices,planSha256:r.planSha256,...e?{plan:r.plan}:{}};if(r.checksumSha256!==H(`property-test-choices-v${e?"2":"1"}\0${JSON.stringify(i)}`)||o!==`${JSON.stringify(r)}
2
+ `)throw new Error("property-test-private-store-invalid");return r}function z(n,t){const{root:o,directory:s,head:r}=S(n,!0),e=m(o,t),i=C(r,t,e),a=y(s,"choices.json");if(p(a)){const h=g(a);if(JSON.stringify(h)===JSON.stringify(i))return e}const c=y(s,`choices-${k()}.tmp`),u=E(c,"wx",384);try{J(u,`${JSON.stringify(i)}
3
+ `),v(u)}finally{w(u)}try{if(d(o,["rev-parse","--verify","HEAD"])!==r||m(o,t).planSha256!==e.planSha256)throw new Error("property-test-choices-stale");$(c,a);const h=E(s,"r");try{v(h)}finally{w(h)}}finally{p(c)&&A(c)}return e}function L(n){const{root:t,directory:o,head:s}=S(n,!1);if(!p(o))return;const r=y(o,"choices.json");if(!p(r))return;const e=g(r);if(e.sourceHead!==s)throw new Error("property-test-choices-stale");const i=m(t,e.choices);if(i.planSha256!==e.planSha256)throw new Error("property-test-choices-stale");if(e.plan&&JSON.stringify(e.plan)!==JSON.stringify(i))throw new Error("property-test-choices-stale");return{choices:e.choices,plan:i}}function U(n){const{root:t,directory:o,head:s}=S(n,!1),r=y(o,"choices.json");if(!p(r))throw new Error("property-test-choices-missing");const e=g(r);if(e.sourceHead!==s||!e.plan)throw new Error("property-test-choices-stale");return{root:t,head:s,choices:e.choices,plan:e.plan}}export{U as loadPropertyTestCandidatePlan,L as loadPropertyTestChoices,z as savePropertyTestChoices};
@@ -0,0 +1,65 @@
1
+ export interface PropertyTestCatalog {
2
+ readonly schemaVersion: 1;
3
+ readonly prdPath: string;
4
+ readonly prdSha256: string;
5
+ readonly aggregates: readonly {
6
+ readonly name: string;
7
+ readonly invariantCount: number;
8
+ readonly suggestedFiles: readonly string[];
9
+ }[];
10
+ readonly invariantCount: number;
11
+ readonly publicSafe: true;
12
+ }
13
+ export interface PropertyTestChoices {
14
+ readonly prdSha256: string;
15
+ readonly language: 'typescript' | 'python';
16
+ readonly numRuns: 100 | 1000 | 10000;
17
+ /** Explicit operator-confirmed aggregate-to-file mapping; no implicit default. */
18
+ readonly mappings: Readonly<Record<string, string>>;
19
+ }
20
+ export interface PropertyTestPlan {
21
+ readonly schemaVersion: 1;
22
+ readonly prdPath: string;
23
+ readonly prdSha256: string;
24
+ readonly language: PropertyTestChoices['language'];
25
+ readonly numRuns: PropertyTestChoices['numRuns'];
26
+ readonly aggregates: readonly {
27
+ readonly name: string;
28
+ readonly invariantCount: number;
29
+ readonly implementationFile: string;
30
+ readonly implementationSha256: string;
31
+ readonly testFile: string;
32
+ readonly testPreimageSha256: string | null;
33
+ }[];
34
+ readonly writeSet: readonly string[];
35
+ readonly planSha256: string;
36
+ readonly checkpointAccepted: false;
37
+ readonly publicSafe: true;
38
+ }
39
+ /** Closed request projection: the PRD expressions, mappings and test bodies stay local. */
40
+ export interface PropertyTestExecutionInput {
41
+ readonly schemaVersion: 1;
42
+ readonly prdPath: 'prd.md' | 'docs/architecture/prd.md';
43
+ readonly prdSha256: string;
44
+ readonly planSha256: string;
45
+ readonly pathsSha256: string;
46
+ readonly aggregateCount: number;
47
+ readonly invariantCount: number;
48
+ readonly pathCount: number;
49
+ readonly language: PropertyTestChoices['language'];
50
+ readonly numRuns: PropertyTestChoices['numRuns'];
51
+ readonly publicSafe: true;
52
+ }
53
+ export interface PropertyTestInvariantRef {
54
+ readonly aggregate: string;
55
+ readonly ordinal: number;
56
+ /** Hash of the exact PRD row and its position; never an expression body. */
57
+ readonly invariantSha256: string;
58
+ }
59
+ /** Closed identifiers for root semantic review; the PRD text stays local. */
60
+ export declare function propertyTestInvariantRefs(markdown: string): readonly PropertyTestInvariantRef[];
61
+ export declare function inspectPropertyTestCatalog(projectRoot: string): PropertyTestCatalog;
62
+ export declare function confirmPropertyTestPlan(projectRoot: string, choices: PropertyTestChoices): PropertyTestPlan;
63
+ export declare function propertyTestExecutionInput(plan: PropertyTestPlan): PropertyTestExecutionInput;
64
+ /** Build root-owned PRD configuration bytes; no invariant expression leaves the local PRD. */
65
+ export declare function renderPropertyTestConfiguration(currentPrd: string, plan: PropertyTestPlan, generatedAt: string): string;
@@ -0,0 +1,7 @@
1
+ import{createHash as x}from"node:crypto";import{lstatSync as m,readFileSync as w,realpathSync as P}from"node:fs";import{join as S,relative as F,resolve as R,sep as j}from"node:path";const E=["prd.md","docs/architecture/prd.md"],k=new Set(["Range","Cardinality","SumEquality","Format","Temporal"]),v=/^[A-Z][A-Za-z0-9]{0,79}$/,d=/^[a-f0-9]{64}$/;function l(t){return x("sha256").update(t).digest("hex")}function $(t,e){if(!/^[A-Za-z0-9][A-Za-z0-9._/-]{0,255}$/.test(e)||e.split("/").some(o=>o==="."||o===".."||o.length===0))throw new Error("property-test-invalid-path");const r=R(t,e),n=F(t,r);if(n.startsWith(`..${j}`)||n===".."||n==="")throw new Error("property-test-path-escape");let s=t;for(const o of e.split("/"))if(s=S(s,o),m(s).isSymbolicLink())throw new Error("property-test-symlink");if(!m(r).isFile())throw new Error("property-test-not-regular");return r}function A(t){return t.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase()}function _(t){const e=[];let r="";for(let n=1;n<t.length-1;n++){const s=t[n];s==="\\"&&t[n+1]==="|"?(r+="|",n++):s==="|"?(e.push(r.trim()),r=""):r+=s}return e.push(r.trim()),e}function O(t,e){let r=t;for(const n of e.split("/")){r=S(r,n);try{const s=m(r);if(s.isSymbolicLink())throw new Error("property-test-symlink");if(r===S(t,e)&&!s.isFile())throw new Error("property-test-invalid-destination")}catch(s){if(s.code==="ENOENT")return null;throw s}}return l(w(r))}function C(t){const e=t.split(/\r?\n/),r=e.findIndex(a=>/^## Aggregate Invariants\s*$/.test(a));if(r<0)throw new Error("property-test-no-invariants-section");const n=new Map,s=[];let o,p;for(const a of e.slice(r+1)){if(/^##\s/.test(a))break;const u=/^###\s+(.+?)\s*$/.exec(a);if(u){if(o=u[1],!v.test(o))throw new Error("property-test-invalid-aggregate");p=void 0;continue}if(!a.startsWith("|")||!a.endsWith("|"))continue;const i=_(a);if(i.every(h=>/^:?-{3,}:?$/.test(h)))continue;if(i.includes("Expression")&&i.includes("Type")){p=i;continue}if(!p||i.length!==p.length)throw new Error("property-test-invalid-table");const y=p,g=h=>i[y.indexOf(h)]??"",c=o??g("Aggregate");if(!v.test(c)||!g("Expression")||!k.has(g("Type"))||!g("Description")||o&&g("Aggregate")&&g("Aggregate")!==o)throw new Error("property-test-invalid-invariant");const f=(n.get(c)??0)+1;if(n.set(c,f),s.push(Object.freeze({aggregate:c,ordinal:f,invariantSha256:l(`property-test-invariant-v1\0${JSON.stringify({aggregate:c,ordinal:f,expression:g("Expression"),type:g("Type"),description:g("Description")})}`)})),n.size>64||[...n.values()].reduce((h,b)=>h+b,0)>1024)throw new Error("property-test-catalog-too-large")}if(n.size===0)throw new Error("property-test-no-aggregates");return{counts:n,rows:s}}function D(t){return C(t).rows}function T(t){const e=P(t),r=[];for(const n of E){let s,o;try{o=w($(e,n)),s=new TextDecoder("utf-8",{fatal:!0}).decode(o)}catch(p){if(p.code==="ENOENT")continue;throw p}if(o.length>2e6)throw new Error("property-test-prd-too-large");/^## Aggregate Invariants\s*$/m.test(s)&&r.push({path:n,sha:l(o),counts:C(s).counts})}if(r.length!==1)throw new Error(r.length?"property-test-ambiguous-prd":"property-test-no-invariants-section");return{root:e,...r[0]}}function z(t,e){const r=A(e);return[`src/domain/${r}.ts`,`src/aggregates/${r}.ts`,`src/${r}.ts`,`src/domain/${r.replaceAll("-","_")}.py`,`aggregates/${r.replaceAll("-","_")}.py`].filter(s=>{try{return $(t,s),!0}catch{return!1}})}function W(t){const e=T(t),r=[...e.counts].sort(([n],[s])=>n.localeCompare(s)).map(([n,s])=>({name:n,invariantCount:s,suggestedFiles:z(e.root,n)}));return{schemaVersion:1,prdPath:e.path,prdSha256:e.sha,aggregates:r,invariantCount:r.reduce((n,s)=>n+s.invariantCount,0),publicSafe:!0}}function G(t,e){const r=T(t);if(!e||!d.test(e.prdSha256)||e.prdSha256!==r.sha||!["typescript","python"].includes(e.language)||![100,1e3,1e4].includes(e.numRuns)||!e.mappings||typeof e.mappings!="object"||Array.isArray(e.mappings)||Object.keys(e).sort().join("\0")!==["language","mappings","numRuns","prdSha256"].join("\0")||Object.keys(e.mappings).sort().join("\0")!==[...r.counts.keys()].sort().join("\0"))throw new Error("property-test-choices-mismatch");const n=new Set,s=[...r.counts].sort(([a],[u])=>a.localeCompare(u)).map(([a,u])=>{const i=e.mappings[a];if(typeof i!="string"||!/^(?:src|aggregates)\/[A-Za-z0-9_./-]+\.(?:ts|py)$/.test(i)||(e.language==="typescript"?!i.endsWith(".ts"):!i.endsWith(".py")))throw new Error("property-test-invalid-mapping");const y=l(w($(r.root,i))),g=A(a),c=e.language==="typescript"?`tests/property/${g}.property.test.ts`:`tests/property/test_${g.replaceAll("-","_")}_properties.py`;if(n.has(c))throw new Error("property-test-write-collision");const f=O(r.root,c);return n.add(c),{name:a,invariantCount:u,implementationFile:i,implementationSha256:y,testFile:c,testPreimageSha256:f}}),o=[...n].sort(),p={schemaVersion:1,prdPath:r.path,prdSha256:r.sha,language:e.language,numRuns:e.numRuns,aggregates:s,writeSet:o};return{...p,planSha256:l(JSON.stringify(p)),checkpointAccepted:!1,publicSafe:!0}}function H(t){if(!E.includes(t.prdPath)||!d.test(t.planSha256)||!d.test(t.prdSha256)||t.aggregates.length<1||t.aggregates.length>64||t.writeSet.length!==t.aggregates.length||t.aggregates.reduce((e,r)=>e+r.invariantCount,0)>1024)throw new Error("property-test-plan-invalid");return{schemaVersion:1,prdPath:t.prdPath,prdSha256:t.prdSha256,planSha256:t.planSha256,pathsSha256:l(JSON.stringify(t.writeSet)),aggregateCount:t.aggregates.length,invariantCount:t.aggregates.reduce((e,r)=>e+r.invariantCount,0),pathCount:t.writeSet.length,language:t.language,numRuns:t.numRuns,publicSafe:!0}}function L(t,e,r){if(!/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/.test(r)||!Number.isFinite(Date.parse(r))||!d.test(e.planSha256)||l(t)!==e.prdSha256||/^## Property Test Configuration\s*$/m.test(t)||t.includes("\0"))throw new Error("property-test-configuration-conflict");const n=t.includes(`\r
2
+ `)?`\r
3
+ `:`
4
+ `;if(n===`\r
5
+ `&&t.replaceAll(`\r
6
+ `,"").includes(`
7
+ `))throw new Error("property-test-configuration-conflict");const s=["## Property Test Configuration","",`- Language: ${e.language}`,`- numRuns: ${e.numRuns}`,`- Generated at: ${r}`,"- Step: property-test (P112.03)",`- Confirmed plan SHA-256: ${e.planSha256}`,"","| Aggregate | Implementation File | Invariants |","|---|---|---|",...e.aggregates.map(o=>`| ${o.name} | ${o.implementationFile} | ${o.invariantCount} |`),""];return`${t.replace(/(?:\r?\n)*$/,"")}${n}${n}${s.join(n)}`}export{G as confirmPropertyTestPlan,W as inspectPropertyTestCatalog,H as propertyTestExecutionInput,D as propertyTestInvariantRefs,L as renderPropertyTestConfiguration};
@@ -0,0 +1,58 @@
1
+ export interface PropertyTestReviewPlanV1 {
2
+ readonly schemaVersion: 1;
3
+ readonly kind: 'property-test-review-plan';
4
+ readonly sourceHead: string;
5
+ readonly planSha256: string;
6
+ readonly candidateSha256: string;
7
+ readonly invariants: readonly {
8
+ readonly aggregate: string;
9
+ readonly ordinal: number;
10
+ readonly invariantSha256: string;
11
+ readonly testFile: string;
12
+ readonly testSha256: string;
13
+ readonly lineCount: number;
14
+ }[];
15
+ readonly executionVerified: false;
16
+ readonly qaAccepted: false;
17
+ readonly publicSafe: true;
18
+ }
19
+ export interface PropertyTestSemanticReviewV1 {
20
+ readonly schemaVersion: 1;
21
+ readonly kind: 'property-test-semantic-review';
22
+ readonly sourceHead: string;
23
+ readonly planSha256: string;
24
+ readonly candidateSha256: string;
25
+ readonly verdict: 'approved';
26
+ readonly coverage: readonly {
27
+ readonly invariantSha256: string;
28
+ readonly testFile: string;
29
+ readonly assertionLine: number;
30
+ /** Root-authored explanation of why this assertion proves this PRD invariant. */
31
+ readonly rationale: string;
32
+ }[];
33
+ }
34
+ export interface PropertyTestReviewReceiptV1 {
35
+ readonly schemaVersion: 1;
36
+ readonly kind: 'property-test-review-acceptance';
37
+ readonly sourceHead: string;
38
+ readonly planSha256: string;
39
+ readonly candidateSha256: string;
40
+ readonly reviewSha256: string;
41
+ readonly invariantCount: number;
42
+ readonly passedTests: number;
43
+ readonly causalFailedTests: number;
44
+ readonly executionVerified: true;
45
+ readonly qaAccepted: true;
46
+ readonly publicSafe: true;
47
+ }
48
+ /** Only hashes, counts and planned paths leave this local planning function. */
49
+ export declare function inspectPropertyTestReviewPlan(projectRoot: string): PropertyTestReviewPlanV1;
50
+ /** Exact-root report shape and complete per-invariant review are mandatory. */
51
+ export declare function validatePropertyTestSemanticReview(projectRoot: string, report: unknown): {
52
+ readonly plan: PropertyTestReviewPlanV1;
53
+ readonly reviewSha256: string;
54
+ };
55
+ /** Explicit root acceptance re-runs physical + causal QA before an immutable private receipt. */
56
+ export declare function acceptPropertyTestSemanticReview(projectRoot: string, report: unknown): PropertyTestReviewReceiptV1;
57
+ /** Revalidate the immutable root decision against the current physical candidate. */
58
+ export declare function readPropertyTestReviewReceipt(projectRoot: string): PropertyTestReviewReceiptV1;
@@ -0,0 +1,4 @@
1
+ import{createHash as $,randomUUID as L}from"node:crypto";import{closeSync as k,existsSync as T,fsyncSync as x,linkSync as P,lstatSync as h,mkdirSync as j,openSync as F,readFileSync as g,realpathSync as H,unlinkSync as C,writeFileSync as D}from"node:fs";import{isAbsolute as J,join as w,resolve as S}from"node:path";import{mutationQaGit as E}from"../commands/mutation-qa-git.js";import{inspectPropertyTestCandidate as z}from"./property-test-candidate.js";import{loadPropertyTestCandidatePlan as R}from"./property-test-choices.js";import{propertyTestInvariantRefs as q}from"./property-test-plan.js";import{verifyPropertyTestRuntime as B}from"./property-test-runtime.js";const A=/^[a-f0-9]{64}$/,b=256*1024;function v(n){return $("sha256").update(n).digest("hex")}function m(n,r){return n!==null&&typeof n=="object"&&!Array.isArray(n)&&Object.keys(n).sort().join("\0")===[...r].sort().join("\0")}function V(n,r){if(!/^tests\/property\/[a-z0-9-]+\.property\.test\.ts$/.test(r))throw new Error("property-test-review-unverified");let i=n;for(const[a,e]of r.split("/").entries()){i=w(i,e);const s=h(i);if(s.isSymbolicLink()||(a===r.split("/").length-1?!s.isFile()||s.size<1||s.size>256*1024:!s.isDirectory()))throw new Error("property-test-review-unverified")}return g(i)}function l(n){try{const r=z(n),{root:i,head:a,plan:e}=R(n);if(a!==r.sourceHead||e.planSha256!==r.planSha256)throw new Error("property-test-review-unverified");const s=E(i,["show",`HEAD:${e.prdPath}`]);if(v(s)!==e.prdSha256)throw new Error("property-test-review-unverified");const o=new TextDecoder("utf-8",{fatal:!0}).decode(s),t=q(o);if(t.length!==e.aggregates.reduce((d,p)=>d+p.invariantCount,0)||new Set(t.map(d=>d.invariantSha256)).size!==t.length)throw new Error("property-test-review-unverified");const u=new Map(e.aggregates.map(d=>[d.name,d])),c=new Map(e.aggregates.map(d=>{const p=V(i,d.testFile),y=new TextDecoder("utf-8",{fatal:!0}).decode(p).split(/\r?\n/);return[d.name,{testFile:d.testFile,testSha256:v(p),lineCount:y.length}]})),f=t.map(d=>{const p=u.get(d.aggregate),y=c.get(d.aggregate);if(!p||!y||d.ordinal>p.invariantCount)throw new Error("property-test-review-unverified");return Object.freeze({...d,...y})});if(z(i).artifactSha256!==r.artifactSha256)throw new Error("property-test-review-unverified");return Object.freeze({schemaVersion:1,kind:"property-test-review-plan",sourceHead:a,planSha256:e.planSha256,candidateSha256:r.artifactSha256,invariants:f,executionVerified:!1,qaAccepted:!1,publicSafe:!0})}catch{throw new Error("property-test-review-unverified")}}function N(n,r){try{const i=l(n);if(!m(r,["schemaVersion","kind","sourceHead","planSha256","candidateSha256","verdict","coverage"])||r.schemaVersion!==1||r.kind!=="property-test-semantic-review"||r.verdict!=="approved"||r.sourceHead!==i.sourceHead||r.planSha256!==i.planSha256||r.candidateSha256!==i.candidateSha256||!Array.isArray(r.coverage)||r.coverage.length!==i.invariants.length||Buffer.byteLength(JSON.stringify(r))>b)throw new Error("property-test-review-unverified");const a=new Map(i.invariants.map(t=>[t.invariantSha256,t])),e=new Set,s=new Set,o=new Map([...new Set(i.invariants.map(t=>t.testFile))].map(t=>[t,new TextDecoder("utf-8",{fatal:!0}).decode(V(n,t)).split(/\r?\n/)]));for(const t of r.coverage){if(!m(t,["invariantSha256","testFile","assertionLine","rationale"])||typeof t.invariantSha256!="string"||!A.test(t.invariantSha256)||e.has(t.invariantSha256))throw new Error("property-test-review-unverified");e.add(t.invariantSha256);const u=a.get(t.invariantSha256),c=`${t.testFile}:${t.assertionLine}`;if(!u||t.testFile!==u.testFile||s.has(c)||!Number.isSafeInteger(t.assertionLine)||Number(t.assertionLine)<1||Number(t.assertionLine)>u.lineCount||typeof t.rationale!="string"||t.rationale.length<30||t.rationale.length>500||/[\x00-\x1f\x7f]/.test(t.rationale))throw new Error("property-test-review-unverified");s.add(c);const f=o.get(u.testFile)?.[Number(t.assertionLine)-1]??"";if(!/\b(?:expect|assert|throw)\s*\(/.test(f.split("//")[0]??""))throw new Error("property-test-review-unverified")}if(e.size!==a.size||l(n).candidateSha256!==i.candidateSha256)throw new Error("property-test-review-unverified");return Object.freeze({plan:i,reviewSha256:v(`property-test-semantic-review-v1\0${JSON.stringify(r)}`)})}catch{throw new Error("property-test-review-unverified")}}function O(n,r){const i=E(n,["rev-parse","--show-toplevel"]).toString("utf8").trim(),a=E(n,["rev-parse","--git-common-dir"]).toString("utf8").trim(),e=J(a)?S(a):S(n,a);if(H(n)!==n||i!==n||H(e)!==e||h(e).isSymbolicLink()||h(e).uid!==process.getuid?.())throw new Error("property-test-review-unverified");const s=w(e,"neocortex-property-test");r&&j(s,{recursive:!0,mode:448});const o=h(s);if(!o.isDirectory()||o.isSymbolicLink()||o.uid!==process.getuid?.()||(o.mode&63)!==0)throw new Error("property-test-review-unverified");return s}function X(n,r){try{const i=S(n),a=N(i,r),e=B(i);if(!e.executionVerified||e.qaAccepted||e.outcome!=="execution-proven"||e.sourceHead!==a.plan.sourceHead||e.candidateSha256!==a.plan.candidateSha256||e.passedTests<a.plan.invariants.length||e.causalFailedTests!==e.passedTests||l(i).candidateSha256!==a.plan.candidateSha256)throw new Error("property-test-review-unverified");const s=Object.freeze({schemaVersion:1,kind:"property-test-review-acceptance",sourceHead:a.plan.sourceHead,planSha256:a.plan.planSha256,candidateSha256:a.plan.candidateSha256,reviewSha256:a.reviewSha256,invariantCount:a.plan.invariants.length,passedTests:e.passedTests,causalFailedTests:e.causalFailedTests,executionVerified:!0,qaAccepted:!0,publicSafe:!0}),o=O(i,!0),t=w(o,`review-${s.candidateSha256}.json`),u={report:r,receipt:s},c={schemaVersion:1,kind:"property-test-review-record",...u,checksumSha256:v(`property-test-review-record-v1\0${JSON.stringify(u)}`)};if(T(t)){const p=h(t);if(!p.isFile()||p.isSymbolicLink()||p.uid!==process.getuid?.()||(p.mode&63)!==0||p.size<1||p.size>b+4096||g(t,"utf8")!==`${JSON.stringify(c)}
2
+ `)throw new Error("property-test-review-unverified");return s}const f=w(o,`review-${L()}.tmp`),d=F(f,"wx",384);try{D(d,`${JSON.stringify(c)}
3
+ `),x(d)}finally{k(d)}try{if(l(i).candidateSha256!==s.candidateSha256)throw new Error("property-test-review-unverified");P(f,t);const p=F(o,"r");try{x(p)}finally{k(p)}}finally{T(f)&&C(f)}return s}catch{throw new Error("property-test-review-unverified")}}function Y(n){try{const r=S(n),i=l(r),a=w(O(r,!1),`review-${i.candidateSha256}.json`),e=h(a);if(!e.isFile()||e.isSymbolicLink()||e.uid!==process.getuid?.()||(e.mode&63)!==0||e.size<1||e.size>b+4096)throw new Error("property-test-review-unverified");const s=g(a,"utf8"),o=JSON.parse(s);if(!m(o,["schemaVersion","kind","report","receipt","checksumSha256"])||o.schemaVersion!==1||o.kind!=="property-test-review-record"||typeof o.checksumSha256!="string"||!A.test(o.checksumSha256)||s!==`${JSON.stringify(o)}
4
+ `)throw new Error("property-test-review-unverified");const t={report:o.report,receipt:o.receipt};if(o.checksumSha256!==v(`property-test-review-record-v1\0${JSON.stringify(t)}`))throw new Error("property-test-review-unverified");const u=N(r,o.report),c=o.receipt;if(!m(c,["schemaVersion","kind","sourceHead","planSha256","candidateSha256","reviewSha256","invariantCount","passedTests","causalFailedTests","executionVerified","qaAccepted","publicSafe"])||c.schemaVersion!==1||c.kind!=="property-test-review-acceptance"||c.sourceHead!==i.sourceHead||c.planSha256!==i.planSha256||c.candidateSha256!==i.candidateSha256||c.reviewSha256!==u.reviewSha256||c.invariantCount!==i.invariants.length||!Number.isSafeInteger(c.passedTests)||Number(c.passedTests)<i.invariants.length||c.causalFailedTests!==c.passedTests||c.executionVerified!==!0||c.qaAccepted!==!0||c.publicSafe!==!0||l(r).candidateSha256!==i.candidateSha256)throw new Error("property-test-review-unverified");return Object.freeze(c)}catch{throw new Error("property-test-review-unverified")}}export{X as acceptPropertyTestSemanticReview,l as inspectPropertyTestReviewPlan,Y as readPropertyTestReviewReceipt,N as validatePropertyTestSemanticReview};
@@ -0,0 +1,18 @@
1
+ type Reason = 'tests-passed' | 'toolchain-unavailable' | 'source-unsupported' | 'install-failed' | 'sandbox-unavailable' | 'tests-failed' | 'mutation-not-causal';
2
+ export interface PropertyTestRuntimeReceiptV1 {
3
+ readonly schemaVersion: 1;
4
+ readonly kind: 'property-test-runtime';
5
+ readonly outcome: 'execution-proven' | 'unverified';
6
+ readonly reasonCode: Reason;
7
+ readonly sourceHead: string | null;
8
+ readonly candidateSha256: string | null;
9
+ readonly testFileCount: number;
10
+ readonly passedTests: number;
11
+ readonly causalFailedTests: number;
12
+ readonly executionVerified: boolean;
13
+ readonly qaAccepted: false;
14
+ readonly publicSafe: true;
15
+ }
16
+ /** An unavailable host or toolchain yields no verdict; only positive + causal runs prove execution. */
17
+ export declare function verifyPropertyTestRuntime(projectRoot: string): PropertyTestRuntimeReceiptV1;
18
+ export {};
@@ -0,0 +1,9 @@
1
+ import{spawnSync as Z}from"node:child_process";import{createHash as $}from"node:crypto";import{existsSync as b,lstatSync as y,mkdirSync as L,mkdtempSync as O,readFileSync as te,realpathSync as F,rmSync as V,writeFileSync as x}from"node:fs";import{homedir as se,tmpdir as M}from"node:os";import{dirname as ne,join as u,posix as I,resolve as oe}from"node:path";import{parse as re}from"@babel/parser";import{parseDocument as ie}from"yaml";import{mutationQaGit as ae}from"../commands/mutation-qa-git.js";import{loadPropertyTestCandidatePlan as ce}from"./property-test-choices.js";import{inspectPropertyTestCandidate as X}from"./property-test-candidate.js";const z="P222_PROPERTY_CAUSAL_CANARY",ue=512,le=16*1024*1024,pe=256*1024;class q extends Error{reason;constructor(o){super(o),this.reason=o}}function c(n){throw new q(n)}function g(n){return n!==null&&typeof n=="object"&&!Array.isArray(n)}function J(n,o,t,r,e=0,s=0){const a=n==="tests-passed";return Object.freeze({schemaVersion:1,kind:"property-test-runtime",outcome:a?"execution-proven":"unverified",reasonCode:n,sourceHead:o,candidateSha256:t,testFileCount:r,passedTests:e,causalFailedTests:s,executionVerified:a,qaAccepted:!1,publicSafe:!0})}function v(n,o,t){(!/^[A-Za-z0-9_.-]+(?:\/[A-Za-z0-9_.-]+)*$/.test(o)||o.split("/").some(s=>s==="."||s===".."))&&c("source-unsupported");let r=n;const e=o.split("/");for(const[s,a]of e.entries()){r=u(r,a);const p=y(r);(p.isSymbolicLink()||(s===e.length-1?!p.isFile()||p.size<1||p.size>t:!p.isDirectory()))&&c("source-unsupported")}return te(r)}function H(n){try{const o=new TextDecoder("utf-8",{fatal:!0}).decode(n),t=ie(o,{strict:!0,uniqueKeys:!0,schema:"core",customTags:[]});if(t.errors.length||t.warnings.length)return null;const r=JSON.parse(o);return g(r)?r:null}catch{return null}}function de(n,o){const t=H(n),r=H(o);if(!t||!r||t.workspaces!==void 0||![2,3].includes(Number(r.lockfileVersion))||!g(r.packages)||!g(r.packages[""])||Object.keys(r.packages).length>1e4)return!1;const e=/^(?:\^|~)?[0-9]+\.[0-9]+\.[0-9]+$/;for(const l of["dependencies","devDependencies","optionalDependencies","peerDependencies"])if(t[l]!==void 0&&(!g(t[l])||Object.values(t[l]).some(h=>typeof h!="string"||!e.test(h))))return!1;const s={...g(t.dependencies)?t.dependencies:{},...g(t.devDependencies)?t.devDependencies:{}},a=r.packages[""],p=g(a)?{...g(a.dependencies)?a.dependencies:{},...g(a.devDependencies)?a.devDependencies:{}}:{};if(typeof s.vitest!="string"||typeof s["fast-check"]!="string"||p.vitest!==s.vitest||p["fast-check"]!==s["fast-check"])return!1;for(const[l,h]of Object.entries(r.packages)){if(!g(h)||h.link===!0)return!1;if(l!==""){if(!/^node_modules\/(?:@[^/]+\/)?[^/]+(?:\/node_modules\/(?:@[^/]+\/)?[^/]+)*$/.test(l)||h.resolved===void 0||typeof h.resolved!="string"||typeof h.integrity!="string"||!/^sha512-[A-Za-z0-9+/]+={0,2}$/.test(h.integrity))return!1;try{const d=new URL(h.resolved);if(d.protocol!=="https:"||d.hostname!=="registry.npmjs.org"||d.port||d.username||d.password||d.search||d.hash||!d.pathname.startsWith("/")||d.pathname.includes(".."))return!1}catch{return!1}}}return!0}function fe(){for(const n of(process.env.PATH??"").split(":")){if(!n.startsWith("/"))continue;const o=u(n,"npm");if(b(o))try{const t=F(o);return(t.startsWith("/usr/")||t.startsWith("/home/linuxbrew/.linuxbrew/"))&&t.endsWith(".js")&&y(t).isFile()?t:null}catch{return null}}return null}function me(n,o,t){const r=re(o,{sourceType:"module",plugins:["typescript"]}),e=new Set;for(const s of r.program.body)if(!(s.type!=="ImportDeclaration"||s.importKind==="type"||!s.source.value.startsWith(".")||I.normalize(I.join(I.dirname(n),s.source.value)).replace(/\.(?:ts|js)$/,"")!==t.replace(/\.ts$/,"")))for(const p of s.specifiers){p.type==="ImportNamespaceSpecifier"&&c("source-unsupported");const l=p.type==="ImportDefaultSpecifier"?"default":p.imported.type==="Identifier"?p.imported.name:p.imported.value;/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(l)||c("source-unsupported"),e.add(l)}return e.size||c("source-unsupported"),e}function he(n,o,t,r){const e=["--die-with-parent","--new-session","--unshare-all","--clearenv","--setenv","HOME","/tmp","--setenv","TMPDIR","/tmp","--setenv","PATH","/home/linuxbrew/.linuxbrew/bin:/usr/bin:/bin","--setenv","CI","true","--setenv","NODE_ENV","test","--ro-bind","/usr","/usr"];for(const s of["/lib","/lib64","/bin"])b(s)&&e.push("--ro-bind",s,s);b("/home/linuxbrew/.linuxbrew")&&e.push("--ro-bind","/home/linuxbrew/.linuxbrew","/home/linuxbrew/.linuxbrew"),e.push("--dir","/etc");for(const s of["passwd","group","hosts","nsswitch.conf"])e.push("--ro-bind",u(n,".sandbox-etc",s),`/etc/${s}`);return[...e,"--dev","/dev","--proc","/proc","--tmpfs","/tmp","--ro-bind",n,"/work","--bind",o,"/results","--chdir","/work","--",r,"node_modules/vitest/vitest.mjs","run","--maxWorkers=1",...t,"--reporter=json","--outputFile=/results/report.json"]}function be(n,o,t,r){const e=["--die-with-parent","--new-session","--unshare-all","--clearenv","--setenv","HOME","/tmp","--setenv","TMPDIR","/tmp","--setenv","PATH","/home/linuxbrew/.linuxbrew/bin:/usr/bin:/bin","--setenv","CI","true","--setenv","NO_UPDATE_NOTIFIER","1","--setenv","npm_config_cache","/npm-cache","--setenv","npm_config_userconfig","/dev/null","--setenv","npm_config_globalconfig","/tmp/npm-global.npmrc","--ro-bind","/usr","/usr"];for(const s of["/lib","/lib64","/bin"])b(s)&&e.push("--ro-bind",s,s);b("/home/linuxbrew/.linuxbrew")&&e.push("--ro-bind","/home/linuxbrew/.linuxbrew","/home/linuxbrew/.linuxbrew"),e.push("--dir","/etc");for(const s of["passwd","group","hosts","nsswitch.conf"])e.push("--ro-bind",u(n,".sandbox-etc",s),`/etc/${s}`);return[...e,"--dev","/dev","--proc","/proc","--tmpfs","/tmp","--ro-bind",o,"/npm-cache","--bind",n,"/work","--chdir","/work","--",t,r,"ci","--offline","--ignore-scripts","--no-audit","--no-fund"]}function K(n,o,t,r){const e=Z("/usr/bin/bwrap",he(n,o,t,r),{env:{PATH:"/usr/bin:/bin"},timeout:18e4,stdio:"ignore"});return(e.error||e.signal||e.status===null)&&c("sandbox-unavailable"),e.status}function G(n,o){b(u(n,"report.json"))||c("sandbox-unavailable");const t=H(v(n,"report.json",2*1024*1024));(!t||!Array.isArray(t.testResults)||t.testResults.length!==o.length)&&c("tests-failed");const r=new Map;for(const e of t.testResults)(!g(e)||typeof e.name!="string"||!o.some(s=>e.name===`/work/${s}`)||r.has(e.name)||!Array.isArray(e.assertionResults))&&c("tests-failed"),r.set(e.name,e.assertionResults);return o.flatMap(e=>r.get(`/work/${e}`))}function Fe(n){let o=null,t=null,r=0,e=0,s=0,a;const p=[];try{const l=F(process.execPath);(process.platform!=="linux"||!b("/usr/bin/bwrap")||!(l.startsWith("/usr/")||l.startsWith("/home/linuxbrew/.linuxbrew/"))||!y("/usr/bin/bwrap").isFile())&&c("sandbox-unavailable");const h=fe();h||c("toolchain-unavailable");const d=u(se(),".npm");(!b(d)||F(d)!==d||!y(d).isDirectory()||y(d).uid!==process.getuid?.())&&c("toolchain-unavailable");const f=oe(n);(F(f)!==f||!y(f).isDirectory())&&c("source-unsupported");const N=X(f);o=N.sourceHead,t=N.artifactSha256;const{plan:w}=ce(f);r=w.writeSet.length,w.language!=="typescript"&&c("toolchain-unavailable");for(const i of[".npmrc","npm-shrinkwrap.json","pnpm-lock.yaml","yarn.lock","bun.lock","bun.lockb"])b(u(f,i))&&c("toolchain-unavailable");(!b(u(f,"package.json"))||!b(u(f,"package-lock.json")))&&c("toolchain-unavailable");const k=v(f,"package.json",1024*1024),j=v(f,"package-lock.json",8*1024*1024);de(k,j)||c("toolchain-unavailable");const W=ae(f,["ls-files","-z","--","src","app","lib","packages","clients"]).toString("utf8").split("\0").filter(Boolean).filter(i=>/^(?:src|app|lib|packages|clients)\//.test(i)&&/\.(?:ts|tsx|js|jsx|mjs|cjs|json)$/.test(i));W.length>ue&&c("source-unsupported");const S=new Map([["package.json",k],["package-lock.json",j]]);for(const i of W)S.set(i,v(f,i,1024*1024));const P=new Map;for(const i of w.aggregates){const m=v(f,i.testFile,pe),E=new TextDecoder("utf-8",{fatal:!0}).decode(m),D=me(i.testFile,E,i.implementationFile),Y=P.get(i.implementationFile)??new Set;for(const ee of D)Y.add(ee);P.set(i.implementationFile,Y),S.set(i.testFile,m)}[...S.values()].reduce((i,m)=>i+m.length,0)>le&&c("source-unsupported"),a=O(u(M(),"p222-property-runtime-")),L(u(a,".sandbox-etc"),{mode:448});const Q=process.getuid?.()??1e3,B=process.getgid?.()??1e3;for(const[i,m]of Object.entries({passwd:`sandbox:x:${Q}:${B}:Sandbox:/work:/bin/sh
2
+ `,group:`sandbox:x:${B}:
3
+ `,hosts:`127.0.0.1 localhost
4
+ `,"nsswitch.conf":`passwd: files
5
+ group: files
6
+ hosts: files
7
+ `}))x(u(a,".sandbox-etc",i),m,{mode:384});x(u(a,"package.json"),k,{mode:384}),x(u(a,"package-lock.json"),j,{mode:384});const R=Z("/usr/bin/bwrap",be(a,d,l,h),{cwd:a,env:{PATH:"/usr/bin:/bin"},timeout:18e4,stdio:"ignore"});(R.error||R.signal||R.status!==0)&&c("install-failed");for(const[i,m]of S)i==="package.json"||i==="package-lock.json"||(L(u(a,ne(i)),{recursive:!0,mode:448}),x(u(a,i),m,{mode:384}));const A=O(u(M(),"p222-property-report-"));p.push(A),K(a,A,w.writeSet,l)!==0&&c(b(u(A,"report.json"))?"tests-failed":"sandbox-unavailable");const _=G(A,w.writeSet);(_.length<w.aggregates.reduce((i,m)=>i+m.invariantCount,0)||_.some(i=>i.status!=="passed"))&&c("tests-failed"),e=_.length;for(const[i,m]of P){const E=[...m].map(D=>D==="default"?`export default function(){throw new Error('${z}')}`:`export const ${D}=function(){throw new Error('${z}')}`).join(`
8
+ `);x(u(a,i),`${E}
9
+ `,{mode:384})}const T=O(u(M(),"p222-property-report-"));p.push(T),(K(a,T,w.writeSet,l)===0||!b(u(T,"report.json")))&&c("mutation-not-causal");const C=G(T,w.writeSet);(C.length!==_.length||C.some(i=>i.status!=="failed"||!Array.isArray(i.failureMessages)||!i.failureMessages.some(m=>typeof m=="string"&&m.includes(z))))&&c("mutation-not-causal"),s=C.length;const U=X(f);return(U.sourceHead!==o||U.artifactSha256!==t||$("sha256").update(k).digest("hex")!==$("sha256").update(v(f,"package.json",1024*1024)).digest("hex")||$("sha256").update(j).digest("hex")!==$("sha256").update(v(f,"package-lock.json",8*1024*1024)).digest("hex"))&&c("source-unsupported"),J("tests-passed",o,t,r,e,s)}catch(l){return J(l instanceof q?l.reason:"source-unsupported",o,t,r,e,s)}finally{for(const l of p)V(l,{recursive:!0,force:!0});a&&V(a,{recursive:!0,force:!0})}}export{Fe as verifyPropertyTestRuntime};
@@ -0,0 +1,8 @@
1
+ /** Require direct Vitest cases with real fast-check calls and a value import from the mapped module. */
2
+ export declare function validatePropertyTestTypeScriptSource(input: {
3
+ source: string;
4
+ testFile: string;
5
+ implementationFile: string;
6
+ invariantCount: number;
7
+ numRuns: number;
8
+ }): void;
@@ -0,0 +1 @@
1
+ import{parse as h}from"@babel/parser";import{posix as f}from"node:path";const g=1e5;function o(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function u(e,n){return o(e)&&e.type==="Identifier"&&e.name===n}function y(e,n,l){return o(e)&&e.type==="MemberExpression"&&e.computed===!1&&u(e.object,n)&&u(e.property,l)}function w(e,n,l){if(!o(e)||e.type!=="CallExpression"||!y(e.callee,n,"assert")||!Array.isArray(e.arguments)||e.arguments.length!==2)return!1;const i=e.arguments[0],p=e.arguments[1];if(!o(i)||i.type!=="CallExpression"||!(y(i.callee,n,"property")||y(i.callee,n,"asyncProperty"))||!Array.isArray(i.arguments)||i.arguments.length<2||!o(i.arguments[i.arguments.length-1])||!["ArrowFunctionExpression","FunctionExpression"].includes(String(i.arguments[i.arguments.length-1].type))||!o(p)||p.type!=="ObjectExpression"||!Array.isArray(p.properties))return!1;const c=p.properties.filter(t=>o(t)&&t.type==="ObjectProperty"&&t.computed===!1&&(u(t.key,"numRuns")||o(t.key)&&t.key.type==="StringLiteral"&&t.key.value==="numRuns"));return c.length===1&&o(c[0])&&o(c[0].value)&&c[0].value.type==="NumericLiteral"&&c[0].value.value===l&&p.properties.every(t=>o(t)&&t.type==="ObjectProperty"&&t.computed===!1)}function A(e,n,l){const i=[e];let p=0;for(;i.length;){const c=i.pop();if(o(c)){if(++p>g)throw new Error("property-test-source-invalid");if(w(c,n,l))return!0;for(const[t,m]of Object.entries(c))t==="loc"||t==="extra"||t==="comments"||t==="leadingComments"||t==="trailingComments"||(Array.isArray(m)?i.push(...m):o(m)&&i.push(m))}}return!1}function v(e){let n;try{n=h(e.source,{sourceType:"module",plugins:["typescript"]})}catch{throw new Error("property-test-source-invalid")}const l=e.implementationFile.replace(/\.ts$/,"");let i;const p=new Set;let c=!1;for(const s of n.program.body)if(!(s.type!=="ImportDeclaration"||s.importKind==="type"))if(s.source.value==="fast-check"){if(i||s.specifiers.length!==1||!["ImportDefaultSpecifier","ImportNamespaceSpecifier"].includes(s.specifiers[0].type))throw new Error("property-test-source-invalid");i=s.specifiers[0].local.name}else if(s.source.value==="vitest")for(const r of s.specifiers)r.type==="ImportSpecifier"&&r.importKind!=="type"&&r.imported.type==="Identifier"&&["it","test"].includes(r.imported.name)&&p.add(r.local.name);else s.source.value.startsWith(".")&&f.normalize(f.join(f.dirname(e.testFile),s.source.value)).replace(/\.(?:ts|js)$/,"")===l&&s.specifiers.some(a=>a.type!=="ImportSpecifier"||a.importKind!=="type")&&(c=!0);if(!i||p.size===0||!c)throw new Error("property-test-source-invalid");const t=[n.program];let m=0,d=0;for(;t.length;){const s=t.pop();if(o(s)){if(++m>g)throw new Error("property-test-source-invalid");if(s.type==="CallExpression"){const r=s.callee;if(o(r)&&r.type==="MemberExpression"&&o(r.object)&&r.object.type==="Identifier"&&(p.has(String(r.object.name))||r.object.name==="describe")&&o(r.property)&&["skip","todo","only"].includes(String(r.property.name)))throw new Error("property-test-source-invalid");if(o(r)&&r.type==="Identifier"&&p.has(String(r.name))){const a=s.arguments;if(!Array.isArray(a)||a.length<2||!A(a[1],i,e.numRuns))throw new Error("property-test-source-invalid");d++}}for(const[r,a]of Object.entries(s))r==="loc"||r==="extra"||r==="comments"||r==="leadingComments"||r==="trailingComments"||(Array.isArray(a)?t.push(...a):o(a)&&t.push(a))}}if(d<e.invariantCount)throw new Error("property-test-source-invalid")}export{v as validatePropertyTestTypeScriptSource};