@ornexus/neocortex 4.60.23 → 4.60.24

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 (84) hide show
  1. package/dist/sbom.cdx.json +23 -23
  2. package/install.js +67 -10
  3. package/install.ps1 +39 -8
  4. package/install.sh +18 -6
  5. package/package.json +5 -2
  6. package/packages/client/dist/adapters/adapter-registry.d.ts +2 -2
  7. package/packages/client/dist/adapters/adapter-registry.js +1 -1
  8. package/packages/client/dist/adapters/grok-adapter.d.ts +11 -0
  9. package/packages/client/dist/adapters/grok-adapter.js +2 -0
  10. package/packages/client/dist/adapters/index.d.ts +1 -0
  11. package/packages/client/dist/adapters/index.js +1 -1
  12. package/packages/client/dist/adapters/platform-detector.d.ts +1 -1
  13. package/packages/client/dist/adapters/platform-detector.js +1 -1
  14. package/packages/client/dist/agent/refresh-stubs.js +2 -2
  15. package/packages/client/dist/cli.js +21 -2
  16. package/packages/client/dist/commands/invoke.d.ts +20 -21
  17. package/packages/client/dist/commands/invoke.js +59 -55
  18. package/packages/client/dist/commands/story-checkpoint.d.ts +15 -0
  19. package/packages/client/dist/commands/story-checkpoint.js +1 -0
  20. package/packages/client/dist/config.js +1 -1
  21. package/packages/client/dist/generated/command-registry.generated.d.ts +18 -52
  22. package/packages/client/dist/generated/command-registry.generated.js +1 -1
  23. package/packages/client/dist/git/direct-yolo-checkpoint.d.ts +67 -0
  24. package/packages/client/dist/git/direct-yolo-checkpoint.js +3 -0
  25. package/packages/client/dist/git/git-lifecycle-store.d.ts +198 -0
  26. package/packages/client/dist/git/git-lifecycle-store.js +4 -0
  27. package/packages/client/dist/git/secure-filesystem-boundary.d.ts +26 -0
  28. package/packages/client/dist/git/secure-filesystem-boundary.js +123 -0
  29. package/packages/client/dist/graph-retrieval/shared-graph-retrieval-contract.js +1 -1
  30. package/packages/client/dist/index.d.ts +2 -0
  31. package/packages/client/dist/index.js +1 -1
  32. package/packages/client/dist/memory/shared-project-memory-types.d.ts +29 -2
  33. package/packages/client/dist/memory/shared-project-memory-types.js +2 -2
  34. package/packages/client/dist/policy/subagent-approval-policy.js +1 -1
  35. package/packages/client/dist/runner/headless/continuous-story-workspace.d.ts +131 -0
  36. package/packages/client/dist/runner/headless/continuous-story-workspace.js +58 -0
  37. package/packages/client/dist/runner/headless/epic-git-reconciliation-inventory.d.ts +23 -0
  38. package/packages/client/dist/runner/headless/epic-git-reconciliation-inventory.js +1 -0
  39. package/packages/client/dist/runner/headless/epic-merge-candidate-qa.d.ts +15 -0
  40. package/packages/client/dist/runner/headless/epic-merge-candidate-qa.js +28 -0
  41. package/packages/client/dist/runner/headless/epic-terminal-git-cli-adapter.d.ts +12 -0
  42. package/packages/client/dist/runner/headless/epic-terminal-git-cli-adapter.js +8 -0
  43. package/packages/client/dist/runner/headless/epic-terminal-git-runner.d.ts +134 -0
  44. package/packages/client/dist/runner/headless/epic-terminal-git-runner.js +2 -0
  45. package/packages/client/dist/runner/headless/prepared-story-bundle.js +1 -1
  46. package/packages/client/dist/runner/headless/run-yolo.js +1 -1
  47. package/packages/client/dist/runner/headless/run-yoloop.d.ts +7 -2
  48. package/packages/client/dist/runner/headless/run-yoloop.js +8 -1
  49. package/packages/client/dist/runner/headless/types.d.ts +1 -1
  50. package/packages/client/dist/runner/headless/types.js +2 -2
  51. package/packages/client/dist/runner-cli.js +0 -0
  52. package/packages/client/dist/state/project-state-snapshot.js +1 -1
  53. package/packages/client/dist/state/state-json-repair.d.ts +9 -0
  54. package/packages/client/dist/state/state-json-repair.js +3 -3
  55. package/packages/client/dist/tier/tier-aware-client.js +1 -1
  56. package/packages/client/dist/yoloop/invoke-hooks.d.ts +13 -10
  57. package/packages/client/dist/yoloop/invoke-hooks.js +8 -5
  58. package/packages/client/dist/yoloop/shared-discover-epics.js +1 -1
  59. package/packages/shared/dist/generated/command-registry.generated.js +18 -66
  60. package/packages/shared/dist/generated/invocation-schema.generated.js +5 -25
  61. package/packages/shared/dist/invocation/index.d.ts +1 -1
  62. package/packages/shared/dist/yoloop/epic-terminal-git.js +227 -0
  63. package/packages/shared/dist/yoloop/planning-graph.js +119 -0
  64. package/packages/shared/dist/yoloop/public-story-write-set.js +27 -0
  65. package/packages/shared/dist/yoloop/wave-decision-receipt.js +19 -0
  66. package/targets-stubs/antigravity/gemini.md +1 -1
  67. package/targets-stubs/antigravity/neocortex.md +18 -0
  68. package/targets-stubs/antigravity/skill/SKILL.md +1 -1
  69. package/targets-stubs/claude-code/neocortex-root.agent.yaml +1 -1
  70. package/targets-stubs/claude-code/neocortex-root.md +21 -2
  71. package/targets-stubs/claude-code/neocortex.agent.yaml +1 -1
  72. package/targets-stubs/claude-code/neocortex.md +2 -2
  73. package/targets-stubs/codex/AGENTS.md +20 -1
  74. package/targets-stubs/cursor/agent.md +20 -2
  75. package/targets-stubs/gemini-cli/agent.md +2 -2
  76. package/targets-stubs/gemini-cli/gemini.md +18 -0
  77. package/targets-stubs/grok/README.md +13 -0
  78. package/targets-stubs/grok/SKILL.md +50 -0
  79. package/targets-stubs/grok/config-mcp.toml +22 -0
  80. package/targets-stubs/grok/install-grok.sh +31 -0
  81. package/targets-stubs/kimi/neocortex.md +18 -0
  82. package/targets-stubs/openclaw/SKILL.md +18 -0
  83. package/targets-stubs/opencode/neocortex-root.md +20 -1
  84. package/targets-stubs/vscode/neocortex.agent.md +20 -2
@@ -0,0 +1,67 @@
1
+ import type { StoryCommitCheckpoint } from '../../../shared/dist/yoloop/branch-unit.js';
2
+ export type DirectYoloCheckpointResult<T> = {
3
+ readonly ok: true;
4
+ readonly value: T;
5
+ } | {
6
+ readonly ok: false;
7
+ readonly reasonCode: string;
8
+ };
9
+ export interface DirectYoloCommitPlan {
10
+ readonly schemaVersion: 1;
11
+ readonly storyId: string;
12
+ readonly epicId: string;
13
+ readonly executionBranch: string;
14
+ readonly baseSha: string;
15
+ readonly bundleDigest: string;
16
+ readonly graphRevision: string;
17
+ readonly claimRevision: string;
18
+ readonly idempotencyKey: string;
19
+ readonly changedPaths: readonly string[];
20
+ readonly trailers: readonly string[];
21
+ }
22
+ export interface DirectYoloSetupHandoffReceipt {
23
+ readonly schemaVersion: 1;
24
+ readonly kind: 'direct-yolo-setup-handoff-receipt';
25
+ readonly storyId: string;
26
+ readonly sessionId: string;
27
+ readonly bundleDigest: string;
28
+ readonly claimRevision: string;
29
+ readonly grantDigest: string;
30
+ readonly expiresAt: string;
31
+ readonly reused: boolean;
32
+ readonly publicSafe: true;
33
+ }
34
+ export interface DirectYoloCheckpointOptions {
35
+ readonly projectRoot: string;
36
+ readonly storyId: string;
37
+ readonly push?: boolean;
38
+ readonly remote?: string;
39
+ readonly nowIso?: string;
40
+ /** One-time setup-owner grant required to transfer a still-live setup lease. */
41
+ readonly setupLeaseHandoff?: {
42
+ readonly sessionId: string;
43
+ readonly token: string;
44
+ };
45
+ /** Fault-only seam around the private handoff consumption transaction. */
46
+ readonly setupHandoffFault?: (phase: 'after-consuming-persisted' | 'before-consumed-persist') => Promise<void>;
47
+ /** Test observer after canonical P205; cannot supply or replace its result. */
48
+ readonly qaRunner?: (input: {
49
+ readonly projectRoot: string;
50
+ readonly storyId: string;
51
+ readonly headSha: string;
52
+ }) => Promise<unknown>;
53
+ /** Test seam executed after push and before the final locked checkpoint CAS. */
54
+ readonly beforeCheckpointPersist?: () => Promise<void>;
55
+ /** Test seam for crash-window reproduction after durable CAS and before release. */
56
+ readonly afterCheckpointPersist?: () => Promise<void>;
57
+ }
58
+ /**
59
+ * Productive setup-owner handoff emitter used immediately before C08. The
60
+ * one-time token never crosses stdout; only a public receipt is returned.
61
+ */
62
+ export declare function issueDirectYoloSetupLeaseHandoff(options: Pick<DirectYoloCheckpointOptions, 'projectRoot' | 'storyId' | 'nowIso'>): Promise<DirectYoloCheckpointResult<DirectYoloSetupHandoffReceipt>>;
63
+ export declare function beginDirectYoloStoryCommit(options: Pick<DirectYoloCheckpointOptions, 'projectRoot' | 'storyId' | 'nowIso' | 'setupLeaseHandoff' | 'setupHandoffFault'>): Promise<DirectYoloCheckpointResult<DirectYoloCommitPlan>>;
64
+ export declare function finalizeDirectYoloStoryCheckpoint(options: DirectYoloCheckpointOptions): Promise<DirectYoloCheckpointResult<StoryCommitCheckpoint>>;
65
+ export declare function recoverLegacyDirectYoloStoryCheckpoint(options: DirectYoloCheckpointOptions & {
66
+ readonly commitSha: string;
67
+ }): Promise<DirectYoloCheckpointResult<StoryCommitCheckpoint>>;
@@ -0,0 +1,3 @@
1
+ import{execFile as ge}from"node:child_process";import{createHash as we,randomBytes as Ie,timingSafeEqual as Re}from"node:crypto";import{readFile as re}from"node:fs/promises";import{join as oe,resolve as ve}from"node:path";import{promisify as Se}from"node:util";import{acquireGitLifecyclePhysicalIntegrationLock as H,applyGitLifecycleRuntimeOverlay as ke,computeImmutableStoryQaEvidenceDigest as De,computeGitLifecyclePhysicalIntegrationLockOwnerDigest as ie,computeP205StoryQaEvidenceDigest as xe,computeLegacyDirectYoloRecoveryReceiptRef as be,ensureRuntimeEpic as O,ensureRuntimeStory as Ae,ensureGitLifecyclePrivateChildDirectory as je,executeP205TransientAuthority as Ee,projectP205TransientExecutionEvidence as Be,LEGACY_DIRECT_YOLO_RECOVERY_COMMITS as Le,mutateGitLifecycleRuntime as C,P205_COMPLETE_COMMAND as _e,readGitLifecycleRuntime as q,gitLifecycleRuntimeDirectory as $e,assertGitLifecyclePrivateFile as ne,releaseGitLifecyclePhysicalIntegrationLock as N,releaseGitLifecyclePhysicalIntegrationLockForCheckpoint as qe,verifyGitLifecyclePhysicalIntegrationLock as T,verifyAcceptedGitLifecycleStoryCheckpoint as se}from"./git-lifecycle-store.js";import{anchoredAtomicWriteFile as ze}from"./secure-filesystem-boundary.js";const Y=Se(ge);async function Je(e){try{const t=await W(e.projectRoot,e.storyId),i=$(await E(t.projectRoot,["diff","--cached","--name-only","-z"])),r=G(i,t.authorizedWriteSet,e.storyId);if(!r.ok)return y(r.reasonCode);if($(await E(t.projectRoot,["diff","--name-only","-z"])).some(w=>i.includes(w)))return y("direct-yolo-user-overlap");const s=await E(t.projectRoot,["diff","--cached","--binary","--full-index"]);if(!s)return y("direct-yolo-staged-diff-empty");const f=v(s),a=v([...t.authorizedWriteSet].sort().join("\0")),c=K(e.nowIso),n=await q(t.projectRoot,{required:!0}),d=I(n.epics[t.epicId]?.branch_lease);if(!fe(d,e.storyId,c))return y("direct-yolo-setup-handoff-owner-invalid");const h=String(d.sessionId),R=String(d.expiresAt),m=new Date(Math.min(Date.parse(R),Date.parse(c)+300*1e3)).toISOString(),l=await P(t.projectRoot,e.storyId),S=l?.state==="issued"&&l.fromSessionId===h&&l.bundleDigest===f&&l.claimRevision===a&&Date.parse(l.expiresAt)>Date.parse(c),A=S?l.expiresAt:m,j=S?l.token:Ie(32).toString("base64url"),x=v(j),u=Object.freeze({schemaVersion:1,kind:"direct-yolo-setup-handoff",storyId:e.storyId,fromSessionId:h,tokenDigest:x,bundleDigest:f,claimRevision:a,expiresAt:A}),k=v(JSON.stringify(u)),p=await H(t.projectRoot,{kind:"direct",storyId:e.storyId,sessionId:h,idempotencyKey:h,expiresAt:A,persistent:!1,createdAt:c});if(!p.ok)return y(p.reasonCode==="git-lifecycle-integration-backpressure"?"direct-yolo-integration-backpressure":"direct-yolo-integration-lock-failed");try{await M(t.projectRoot,{schemaVersion:1,kind:"direct-yolo-setup-handoff-token",state:"issued",storyId:e.storyId,fromSessionId:h,token:j,tokenDigest:x,bundleDigest:f,claimRevision:a,grantDigest:k,expiresAt:A}),await C(t.projectRoot,w=>{const g=I(O(w,t.epicId).branch_lease);if(!fe(g,e.storyId,c)||g?.sessionId!==h||g.idempotencyKey!==h)throw new Error("direct-yolo-setup-handoff-owner-raced");g.handoffGrant=u},{expectedRevision:n.revision,preCommit:async()=>{if(!await T(p.path,p.owner))throw new Error("direct-yolo-integration-lock-raced");const w=await P(t.projectRoot,e.storyId);if(!w||w.state!=="issued"||w.grantDigest!==k||w.tokenDigest!==x)throw new Error("direct-yolo-setup-handoff-token-raced")}})}finally{await N(p.path,p.owner).catch(()=>{})}return{ok:!0,value:Object.freeze({schemaVersion:1,kind:"direct-yolo-setup-handoff-receipt",storyId:e.storyId,sessionId:h,bundleDigest:f,claimRevision:a,grantDigest:k,expiresAt:A,reused:S,publicSafe:!0})}}catch(t){return y(t instanceof Error&&/^direct-yolo-/.test(t.message)?t.message:"direct-yolo-setup-handoff-failed")}}async function Qe(e){try{const t=await W(e.projectRoot,e.storyId),i=await b(t.projectRoot,["rev-parse","HEAD"]),r=$(await E(t.projectRoot,["diff","--cached","--name-only","-z"])),o=G(r,t.authorizedWriteSet,e.storyId);if(!o.ok)return y(o.reasonCode);if($(await E(t.projectRoot,["diff","--name-only","-z"])).some(u=>r.includes(u)))return y("direct-yolo-user-overlap");const f=await E(t.projectRoot,["diff","--cached","--binary","--full-index"]);if(!f)return y("direct-yolo-staged-diff-empty");const a=v(f),c=v([...t.authorizedWriteSet].sort().join("\0")),n=v(["direct-yolo-commit-v1",e.storyId,t.epicId,t.executionBranch,i,a,t.graphRevision,c].join("\0")),d=K(e.nowIso);let h=e.setupLeaseHandoff??await Oe(t.projectRoot,e.storyId,a,c,d);const R=await q(t.projectRoot,{required:!0}),m=I(R.epics[t.epicId]?.branch_lease),l=m?.ownerStoryId===e.storyId&&m.sessionId===n&&m.idempotencyKey===n&&typeof m.expiresAt=="string"&&Date.parse(m.expiresAt)>Date.parse(d)?m:void 0;if(l&&e.setupLeaseHandoff)return y("direct-yolo-setup-handoff-replayed");const S=I(l?.handoffConsumption);if(S){const u=await P(t.projectRoot,e.storyId);if(!u||!["consuming","consumed"].includes(u.state)||u.fromSessionId!==S.fromSessionId||u.tokenDigest!==S.tokenDigest||u.bundleDigest!==a||u.claimRevision!==c||S.bundleDigest!==a||S.claimRevision!==c||u.consumedBySessionId!==n||S.consumedBySessionId!==n)return y("direct-yolo-setup-handoff-consume-invalid");if(u.state==="consuming"){if(!u.token||v(u.token)!==u.tokenDigest)return y("direct-yolo-setup-handoff-consume-invalid");h={sessionId:u.fromSessionId,token:u.token}}}const A=l?String(l.expiresAt):new Date(Date.parse(d)+1800*1e3).toISOString(),j=await H(t.projectRoot,{kind:"direct",storyId:e.storyId,sessionId:n,idempotencyKey:n,expiresAt:A,persistent:!0,createdAt:l&&typeof l.acquiredAt=="string"?l.acquiredAt:d});if(!j.ok)return y(j.reasonCode==="git-lifecycle-integration-backpressure"?"direct-yolo-integration-backpressure":"direct-yolo-integration-lock-failed");try{h&&e.setupLeaseHandoff===void 0&&(await Ce(t.projectRoot,e.storyId,h.sessionId,h.token,n,d),await e.setupHandoffFault?.("after-consuming-persisted")),await C(t.projectRoot,u=>{const k=O(u,t.epicId),p=I(k.branch_lease),w=p&&Date.parse(String(p.expiresAt))>Date.parse(d),g=p?.ownerStoryId===e.storyId&&p.sessionId===n&&p.idempotencyKey===n,D=p?.ownerStoryId===e.storyId&&p.sessionId===p.idempotencyKey&&typeof p.idempotencyKey=="string"&&/^setup-[a-f0-9]{64}$/.test(p.idempotencyKey),B=w&&D&&He({current:p,handoff:h,storyId:e.storyId,bundleDigest:a,claimRevision:c,nowIso:d});if(h&&w&&!g&&!B)throw new Error("direct-yolo-setup-handoff-invalid");if(w&&!g&&!B)throw new Error("direct-yolo-writer-active");const L=B?I(p?.handoffGrant):void 0,_=L?{schemaVersion:1,kind:"direct-yolo-setup-handoff-consumption",state:"consumed",storyId:e.storyId,fromSessionId:String(p?.sessionId),tokenDigest:String(L.tokenDigest),bundleDigest:a,claimRevision:c,consumedBySessionId:n,consumedAt:d}:void 0;k.branch_mode="epic",k.execution_branch=t.executionBranch,k.origin_branch=t.originBranch,k.graph_revision=t.graphRevision,k.branch_lease=w&&g?p:{schemaVersion:1,ownerStoryId:e.storyId,sessionId:n,idempotencyKey:n,acquiredAt:d,expiresAt:A,..._?{handoffConsumption:_}:{}}},{expectedRevision:R.revision,preCommit:async()=>{if(!await T(j.path,j.owner))throw new Error("direct-yolo-integration-lock-raced")}})}catch(u){throw await N(j.path,j.owner).catch(()=>{}),u}h&&e.setupLeaseHandoff===void 0&&(await e.setupHandoffFault?.("before-consumed-persist"),await Pe(t.projectRoot,t.epicId,e.storyId,h.sessionId,h.token,a,c,n,d));const x=Object.freeze([`Neocortex-Story: ${e.storyId}`,`Neocortex-Epic: ${t.epicId}`,`Neocortex-Execution-Branch: ${t.executionBranch}`,`Neocortex-Prepared-Base: ${i}`,`Neocortex-Bundle-Digest: ${a}`,`Neocortex-Graph-Revision: ${t.graphRevision}`,`Neocortex-Claim-Revision: ${c}`]);return{ok:!0,value:Object.freeze({schemaVersion:1,storyId:e.storyId,epicId:t.epicId,executionBranch:t.executionBranch,baseSha:i,bundleDigest:a,graphRevision:t.graphRevision,claimRevision:c,idempotencyKey:n,changedPaths:Object.freeze(r),trailers:x})}}catch(t){return y(X(t,"direct-yolo-begin-failed"))}}async function Ue(e){let t,i,r;try{const o=await W(e.projectRoot,e.storyId);t=o;const s=await b(o.projectRoot,["rev-parse","HEAD"]);let f=await q(o.projectRoot,{required:!0});const a=I(f.stories[e.storyId]?.checkpoint);if(a){const D=typeof a.headSha=="string"?a.headSha:"",B=typeof a.graphRevision=="string"?a.graphRevision:"",L=/^[a-f0-9]{40,64}$/.test(D)?$(await E(o.projectRoot,["diff-tree","--no-commit-id","--name-only","-r","-z",D])):[],_=G(L,o.authorizedWriteSet,e.storyId);if(!(/^[a-f0-9]{40,64}$/.test(D)&&await z(o.projectRoot,["merge-base","--is-ancestor",D,s]))||!/^[a-f0-9]{64}$/.test(B)||!_.ok)return y("direct-yolo-replay-invalid");const me=await Q(e,o.projectRoot,s,B);if(!await se(o.projectRoot,a,e.storyId,o.epicId,o.executionBranch,me.transientAuthority,o.authorizedWriteSet))return y("direct-yolo-replay-invalid");if(!await U(o.projectRoot,o.executionBranch,s,L))return y("direct-yolo-replay-head-raced");if(e.push&&!await de(o.projectRoot,e.remote??"origin",o.executionBranch,D))return y("direct-yolo-remote-head-mismatch");const ee=Array.isArray(a.receiptRefs)?a.receiptRefs.find(te=>typeof te=="string"&&/^physical-lock-owner:[a-f0-9]{64}$/.test(te)):void 0;return ee&&typeof a.idempotencyKey=="string"&&await qe(o.projectRoot,{storyId:e.storyId,idempotencyKey:a.idempotencyKey,ownerDigest:ee.slice(20)}),{ok:!0,value:a}}const c=s,n=await b(o.projectRoot,["rev-parse",`${c}^`]),d=await E(o.projectRoot,["show","--no-patch","--format=%B",c]),h=$(await E(o.projectRoot,["diff-tree","--no-commit-id","--name-only","-r","-z",c])),R=G(h,o.authorizedWriteSet,e.storyId);if(!R.ok)return y(R.reasonCode);const m=F(d,"Neocortex-Bundle-Digest"),l=F(d,"Neocortex-Graph-Revision"),S=F(d,"Neocortex-Claim-Revision"),A=new Map([["Neocortex-Story",e.storyId],["Neocortex-Epic",o.epicId],["Neocortex-Execution-Branch",o.executionBranch],["Neocortex-Prepared-Base",n],["Neocortex-Graph-Revision",o.graphRevision],["Neocortex-Claim-Revision",v([...o.authorizedWriteSet].sort().join("\0"))]]);if(!m||!/^[a-f0-9]{64}$/.test(m)||!l||!S||[...A].some(([D,B])=>F(d,D)!==B))return y("direct-yolo-trailers-invalid");const j=v(await E(o.projectRoot,["diff","--binary","--full-index",`${n}..${c}`]));if(m!==j)return y("direct-yolo-bundle-digest-mismatch");const x=v(["direct-yolo-commit-v1",e.storyId,o.epicId,o.executionBranch,n,m,l,S].join("\0")),u=I(f.epics[o.epicId]?.branch_lease),k=K(e.nowIso),p=u?.ownerStoryId===e.storyId&&u.idempotencyKey===x&&u.sessionId===x&&Date.parse(String(u.expiresAt))>Date.now()?u:void 0;if(u&&Date.parse(String(u.expiresAt))>Date.now()&&!p)return y("direct-yolo-writer-active");const w=p??{schemaVersion:1,ownerStoryId:e.storyId,sessionId:x,idempotencyKey:x,acquiredAt:k,expiresAt:new Date(Date.parse(k)+1800*1e3).toISOString()},g=await H(o.projectRoot,{kind:"direct",storyId:e.storyId,sessionId:x,idempotencyKey:x,expiresAt:String(w.expiresAt),persistent:!0,createdAt:String(w.acquiredAt)});if(!g.ok)return y(g.reasonCode==="git-lifecycle-integration-backpressure"?"direct-yolo-integration-backpressure":"direct-yolo-integration-lock-failed");r=g,p||(f=(await C(o.projectRoot,B=>{const L=O(B,o.epicId),_=I(L.branch_lease);if(_&&Date.parse(String(_.expiresAt))>Date.parse(k))throw new Error("direct-yolo-writer-active");if(L.graph_revision!==o.graphRevision)throw new Error("direct-yolo-graph-revision-raced");L.branch_lease=w},{expectedRevision:f.revision})).document),i=w;{const D=await Q(e,o.projectRoot,c,o.graphRevision);if(!await U(o.projectRoot,o.executionBranch,c,h))return y("direct-yolo-head-raced");if(e.push){const _=V(e.remote??"origin");if(await b(o.projectRoot,["push",_,o.executionBranch]),!await he(o.projectRoot,_,o.executionBranch,c))return y("direct-yolo-remote-head-mismatch")}const B=await ae({projectRoot:o.projectRoot,storyId:e.storyId,epicId:o.epicId,executionBranch:o.executionBranch,baseSha:n,headSha:c,bundleDigest:m,graphRevision:l,claimRevision:S,idempotencyKey:x,qaExecution:D,physicalLockOwnerDigest:ie(g.owner),nowIso:K(e.nowIso),legacyReceiptRef:void 0});return await e.beforeCheckpointPersist?.(),await ce({projectRoot:o.projectRoot,checkpoint:B,remote:e.push?e.remote??"origin":void 0,expectedRevision:f.revision,expectedLease:w,expectedGraphRevision:o.graphRevision,physicalLockPath:g.path,physicalLockOwner:g.owner,transientAuthority:D.transientAuthority,authorizedWriteSet:o.authorizedWriteSet})?(await e.afterCheckpointPersist?.(),{ok:!0,value:B}):y("direct-yolo-checkpoint-persist-failed")}}catch(o){return y(X(o,"direct-yolo-finalize-failed"))}finally{r&&await N(r.path,r.owner).catch(()=>{}),t&&i?await J(t.projectRoot,t.epicId,i).catch(()=>{}):t&&await Ge(t,e.storyId).catch(()=>{})}}async function Xe(e){try{const t=await W(e.projectRoot,e.storyId);if(!/^[a-f0-9]{40,64}$/.test(e.commitSha))return y("direct-yolo-recovery-commit-invalid");const i=await b(t.projectRoot,["rev-parse",e.commitSha]);if(Le[e.storyId]!==i)return y("direct-yolo-recovery-not-allowlisted");if(await b(t.projectRoot,["rev-parse","HEAD"])!==i)return y("direct-yolo-recovery-head-mismatch");await b(t.projectRoot,["merge-base","--is-ancestor",i,`refs/heads/${t.executionBranch}`]);const r=await b(t.projectRoot,["rev-parse",`${i}^`]),o=await E(t.projectRoot,["diff","--binary","--full-index",`${r}..${i}`]),s=$(await E(t.projectRoot,["diff-tree","--no-commit-id","--name-only","-r","-z",i]));if(!G(s,t.authorizedWriteSet.length>0?t.authorizedWriteSet:s,e.storyId).ok)return y("direct-yolo-recovery-write-set-invalid");const a=v(o),c=v([...s].sort().join("\0")),n=v(["legacy-direct-yolo-recovery-v1",e.storyId,i].join("\0")),d=K(e.nowIso),h=new Date(Date.parse(d)+1800*1e3).toISOString(),R=await q(t.projectRoot,{required:!0}),m=await H(t.projectRoot,{kind:"direct",storyId:e.storyId,sessionId:n,idempotencyKey:n,expiresAt:h,persistent:!0,createdAt:d});if(!m.ok)return y(m.reasonCode==="git-lifecycle-integration-backpressure"?"direct-yolo-recovery-integration-backpressure":"direct-yolo-recovery-integration-lock-failed");const l={schemaVersion:1,ownerStoryId:e.storyId,sessionId:n,idempotencyKey:n,acquiredAt:d,expiresAt:h};let S=!1;try{const A=await C(t.projectRoot,w=>{const g=O(w,t.epicId),D=I(g.branch_lease);if(D&&Date.parse(String(D.expiresAt))>Date.parse(d)&&!Z(D,l))throw new Error("direct-yolo-recovery-writer-active");if(g.graph_revision!==t.graphRevision)throw new Error("direct-yolo-recovery-graph-raced");g.branch_mode="epic",g.execution_branch=t.executionBranch,g.origin_branch=t.originBranch,g.branch_lease=l},{expectedRevision:R.revision});S=!0;const j=await Q(e,t.projectRoot,i,t.graphRevision);if(!await U(t.projectRoot,t.executionBranch,i,s))return y("direct-yolo-recovery-head-raced");if(e.push){const w=V(e.remote??"origin"),g=(await b(t.projectRoot,["ls-remote","--heads",w,`refs/heads/${t.executionBranch}`])).split(/\s+/)[0];if(!g||!await z(t.projectRoot,["merge-base","--is-ancestor",i,g]))return y("direct-yolo-recovery-remote-proof-missing")}const x=await ae({projectRoot:t.projectRoot,storyId:e.storyId,epicId:t.epicId,executionBranch:t.executionBranch,baseSha:r,headSha:i,bundleDigest:a,graphRevision:t.graphRevision,claimRevision:c,idempotencyKey:n,qaExecution:j,physicalLockOwnerDigest:ie(m.owner),nowIso:d,legacyReceiptRef:void 0}),u=await be(t.projectRoot,{storyId:e.storyId,epicId:t.epicId,executionBranch:t.executionBranch,baseSha:r,headSha:i,bundleDigest:a,graphRevision:t.graphRevision});if(!u)return y("direct-yolo-recovery-evidence-invalid");const k=Object.freeze({...x,receiptRefs:Object.freeze([...x.receiptRefs,u])});return await ce({projectRoot:t.projectRoot,checkpoint:k,remote:e.push?e.remote??"origin":void 0,remotePolicy:"ancestor-recovery",expectedRevision:A.document.revision,expectedLease:l,expectedGraphRevision:t.graphRevision,physicalLockPath:m.path,physicalLockOwner:m.owner,transientAuthority:j.transientAuthority,authorizedWriteSet:t.authorizedWriteSet})?{ok:!0,value:k}:y("direct-yolo-recovery-persist-failed")}finally{await N(m.path,m.owner).catch(()=>{}),S&&await J(t.projectRoot,t.epicId,l).catch(()=>{})}}catch(t){return y(X(t,"direct-yolo-recovery-failed"))}}async function W(e,t){if(!/^[A-Za-z][A-Za-z0-9_-]*\.[A-Za-z0-9._-]+$/.test(t))throw new Error("direct-yolo-story-id-invalid");const i=ve(e),r=I(JSON.parse(await re(oe(i,".neocortex/state.json"),"utf8"))),o=await q(i,{required:!0}),s=ke(r,o),f=I(s.stories),a=I(s.epics),c=I(f?.[t]),n=String(c?.epic_id??t.split(".")[0]),d=I(a?.[n]),h=String(d?.execution_branch??""),R=String(d?.origin_branch??""),m=String(d?.graph_revision??""),l=Array.isArray(c?.files_to_modify)?[...new Set(c.files_to_modify.filter(A=>typeof A=="string"&&ue(A)))].sort():[],S=await b(i,["symbolic-ref","--quiet","--short","HEAD"]);if(!c||d?.branch_mode!=="epic"||!pe(h)||!pe(R)||!await z(i,["check-ref-format","--branch",h])||!await z(i,["check-ref-format","--branch",R])||!/^[a-f0-9]{64}$/.test(m)||S!==h)throw new Error("direct-yolo-epic-authority-invalid");return{projectRoot:i,story:c,epicId:n,executionBranch:h,originBranch:R,graphRevision:m,authorizedWriteSet:l}}async function ae(e){const t=e.nowIso,i=await E(e.projectRoot,["show","--no-patch","--format=%H%n%P%n%B",e.headSha]),r=$(await E(e.projectRoot,["diff-tree","--no-commit-id","--name-only","-r","-z",e.headSha])),o=De({storyId:e.storyId,baseSha:e.baseSha,headSha:e.headSha,bundleDigest:e.bundleDigest,graphRevision:e.graphRevision,commitBody:i,changedPaths:r}),s=xe({gitEvidenceDigest:o,headSha:e.headSha,graphRevision:e.graphRevision,manifestDigest:e.qaExecution.manifestDigest,gateIds:e.qaExecution.gateIds,resultDigest:e.qaExecution.resultDigest}),f=`story-qa:${s}`,a=Object.freeze({schemaVersion:1,kind:"story_qa_evidence",producer:"local-yolo-tdd",evidenceVersion:"p205-execution-v2",storyId:e.storyId,epicId:e.epicId,baseSha:e.baseSha,headSha:e.headSha,bundleDigest:e.bundleDigest,graphRevision:e.graphRevision,contract:e.qaExecution.contract,command:e.qaExecution.command,manifestDigest:e.qaExecution.manifestDigest,gateIds:e.qaExecution.gateIds,resultDigest:e.qaExecution.resultDigest,sourceEvidenceDigest:s,verdict:"passed",checkedAt:t,receiptRef:f}),c=v(["root-commit-range-review-v1",e.storyId,e.baseSha,e.headSha,e.bundleDigest,e.graphRevision,f,v(i),[...r].sort().join(",")].join("\0")),n=`story-review:${c}`,d=Object.freeze({schemaVersion:1,kind:"story_review_evidence",producer:"root-commit-range-review",storyId:e.storyId,epicId:e.epicId,baseSha:e.baseSha,headSha:e.headSha,bundleDigest:e.bundleDigest,graphRevision:e.graphRevision,sourceEvidenceDigest:c,qaReceiptRef:f,verdict:"approved",reviewedAt:t,receiptRef:n}),h=[`.neocortex/stories/${e.storyId}/qa-gate-result.json`,`.neocortex/stories/${e.storyId}/validation-evidence.md`,f,n,...e.physicalLockOwnerDigest?[`physical-lock-owner:${e.physicalLockOwnerDigest}`]:[],...e.legacyReceiptRef?[e.legacyReceiptRef]:[]];return Object.freeze({schemaVersion:1,storyId:e.storyId,epicId:e.epicId,branch:e.executionBranch,baseSha:e.baseSha,headSha:e.headSha,commits:Object.freeze([e.headSha]),idempotencyKey:e.idempotencyKey,bundleDigest:e.bundleDigest,graphRevision:e.graphRevision,claimRevision:e.claimRevision,receiptRefs:Object.freeze(h),qaVerdict:"passed",reviewVerdict:"approved",qaReceipt:a,reviewReceipt:d,recordedAt:t})}async function ce(e){const{projectRoot:t,checkpoint:i,remote:r}=e;let o=!1;return await C(t,s=>{const f=O(s,i.epicId);if(e.expectedLease){const d=I(f.branch_lease);if(!Z(d,e.expectedLease))throw new Error("direct-yolo-runtime-revision-conflict");if(Date.parse(String(d?.expiresAt))<=Date.now())throw new Error("direct-yolo-writer-lease-expired");if(f.graph_revision!==e.expectedGraphRevision||i.graphRevision!==e.expectedGraphRevision)throw new Error("direct-yolo-graph-revision-raced")}const a=Ae(s,i.storyId),c=I(a.checkpoint);if(c&&c.headSha!==i.headSha){o=!0;return}a.checkpoint=i,a.status="done",a.last_step="step-c-11-review-pr";const n=Array.isArray(a.steps_completed)?a.steps_completed.filter(d=>typeof d=="string"):[];a.steps_completed=[...new Set([...n,"step-c-08-commit-push","step-c-11-review-pr"])],f.branch_lease=null},{expectedRevision:e.expectedRevision,preCommit:async()=>{if(o)throw new Error("direct-yolo-checkpoint-conflict");if(await b(t,["symbolic-ref","--quiet","--short","HEAD"])!==i.branch||await b(t,["rev-parse","HEAD"])!==i.headSha)throw new Error("direct-yolo-checkpoint-head-raced");if(!await se(t,i,i.storyId,i.epicId,i.branch,e.transientAuthority,e.authorizedWriteSet))throw new Error("direct-yolo-checkpoint-physical-invalid");if(e.physicalLockPath&&e.physicalLockOwner&&!await T(e.physicalLockPath,e.physicalLockOwner))throw new Error("direct-yolo-integration-lock-raced");if(r&&!(e.remotePolicy==="ancestor-recovery"?await de(t,r,i.branch,i.headSha):await he(t,r,i.branch,i.headSha)))throw new Error("direct-yolo-checkpoint-remote-raced")}}),!o}async function de(e,t,i,r){const o=V(t),s=(await b(e,["ls-remote","--heads",o,`refs/heads/${i}`])).split(/\s+/)[0];return!!(s&&await z(e,["merge-base","--is-ancestor",r,s]))}function fe(e,t,i){return!!(e?.ownerStoryId===t&&e.sessionId===e.idempotencyKey&&typeof e.idempotencyKey=="string"&&/^setup-[a-f0-9]{64}$/.test(e.idempotencyKey)&&typeof e.expiresAt=="string"&&Date.parse(e.expiresAt)>Date.parse(i))}async function ye(e,t){const i=await $e(e),r=await je(i,"handoffs"),o=`direct-${v(t)}.json`;return{parent:r,name:o,path:oe(r,o)}}async function M(e,t){const i=await ye(e,t.storyId);await ze(i.parent,i.name,`${JSON.stringify(t,null,2)}
2
+ `),await ne(i.path,i.parent)}async function P(e,t){try{const i=await ye(e,t);await ne(i.path,i.parent);const r=JSON.parse(await re(i.path,"utf8")),o=r.state==="issued"?["schemaVersion","kind","state","storyId","fromSessionId","token","tokenDigest","bundleDigest","claimRevision","grantDigest","expiresAt"]:r.state==="consuming"?["schemaVersion","kind","state","storyId","fromSessionId","token","tokenDigest","bundleDigest","claimRevision","grantDigest","expiresAt","consumedBySessionId","consumeStartedAt"]:["schemaVersion","kind","state","storyId","fromSessionId","tokenDigest","bundleDigest","claimRevision","grantDigest","expiresAt","consumedBySessionId","consumedAt"];return Object.keys(r).sort().join("\0")!==[...o].sort().join("\0")||r.schemaVersion!==1||r.kind!=="direct-yolo-setup-handoff-token"||r.state!=="issued"&&r.state!=="consuming"&&r.state!=="consumed"||r.storyId!==t||typeof r.fromSessionId!="string"||!/^setup-[a-f0-9]{64}$/.test(r.fromSessionId)||![r.tokenDigest,r.bundleDigest,r.claimRevision,r.grantDigest].every(s=>typeof s=="string"&&/^[a-f0-9]{64}$/.test(s))||typeof r.expiresAt!="string"||!Number.isFinite(Date.parse(r.expiresAt))||(r.state==="issued"||r.state==="consuming")&&(typeof r.token!="string"||!/^[A-Za-z0-9_-]{32,256}$/.test(r.token))||r.state==="consuming"&&(typeof r.consumedBySessionId!="string"||!/^[a-f0-9]{64}$/.test(r.consumedBySessionId)||typeof r.consumeStartedAt!="string"||!Number.isFinite(Date.parse(r.consumeStartedAt)))||r.state==="consumed"&&(typeof r.consumedBySessionId!="string"||!/^[a-f0-9]{64}$/.test(r.consumedBySessionId)||typeof r.consumedAt!="string"||!Number.isFinite(Date.parse(r.consumedAt)))?void 0:r}catch{return}}async function Oe(e,t,i,r,o){const s=await P(e,t);if(!(!s||s.state==="consumed"||!s.token||s.bundleDigest!==i||s.claimRevision!==r||Date.parse(s.expiresAt)<=Date.parse(o)||v(s.token)!==s.tokenDigest))return{sessionId:s.fromSessionId,token:s.token}}async function Ce(e,t,i,r,o,s){const f=await P(e,t);if(!f||f.state==="consumed"||f.fromSessionId!==i||f.token!==r||f.tokenDigest!==v(r))throw new Error("direct-yolo-setup-handoff-consume-invalid");if(f.state==="consuming"){if(f.consumedBySessionId!==o)throw new Error("direct-yolo-setup-handoff-consume-raced");return}await M(e,{...f,state:"consuming",consumedBySessionId:o,consumeStartedAt:s})}async function Pe(e,t,i,r,o,s,f,a,c){const n=await P(e,i);if(n?.state==="consumed"&&n.fromSessionId===r&&n.consumedBySessionId===a)return;const d=await q(e,{required:!0}),h=I(d.epics[t]?.branch_lease),R=I(h?.handoffConsumption);if(!n||n.state!=="consuming"||n.fromSessionId!==r||n.token!==o||n.tokenDigest!==v(o)||n.bundleDigest!==s||n.claimRevision!==f||n.consumedBySessionId!==a||h?.ownerStoryId!==i||h.sessionId!==a||R?.kind!=="direct-yolo-setup-handoff-consumption"||R.state!=="consumed"||R.fromSessionId!==r||R.tokenDigest!==n.tokenDigest||R.bundleDigest!==s||R.claimRevision!==f||R.consumedBySessionId!==a)throw new Error("direct-yolo-setup-handoff-consume-invalid");try{await M(e,{schemaVersion:1,kind:n.kind,state:"consumed",storyId:i,fromSessionId:r,tokenDigest:n.tokenDigest,bundleDigest:n.bundleDigest,claimRevision:n.claimRevision,grantDigest:n.grantDigest,expiresAt:n.expiresAt,consumedBySessionId:a,consumedAt:c})}catch{throw new Error("direct-yolo-setup-handoff-consume-persist-failed")}}function He(e){const t=I(e.current?.handoffGrant),i=e.handoff?.token,r=typeof i=="string"&&/^[A-Za-z0-9_-]{32,256}$/.test(i)?v(i):void 0;return!!(t&&r&&e.handoff&&e.handoff.sessionId===e.current?.sessionId&&t.schemaVersion===1&&t.kind==="direct-yolo-setup-handoff"&&t.storyId===e.storyId&&t.fromSessionId===e.current?.sessionId&&t.bundleDigest===e.bundleDigest&&t.claimRevision===e.claimRevision&&typeof t.expiresAt=="string"&&Date.parse(t.expiresAt)>Date.parse(e.nowIso)&&typeof t.tokenDigest=="string"&&/^[a-f0-9]{64}$/.test(t.tokenDigest)&&Ne(t.tokenDigest,r))}function Ne(e,t){const i=Buffer.from(e,"hex"),r=Buffer.from(t,"hex");return i.length===32&&r.length===32&&Re(i,r)}function Z(e,t){return!!(e&&["schemaVersion","ownerStoryId","sessionId","idempotencyKey","acquiredAt","expiresAt"].every(i=>e[i]===t[i]))}async function J(e,t,i){await C(e,r=>{const o=O(r,t),s=I(o.branch_lease);Z(s,i)&&(o.branch_lease=null)})}async function Ge(e,t){const i=await q(e.projectRoot,{required:!0}),r=I(i.epics[e.epicId]?.branch_lease);if(!r||r.ownerStoryId!==t||!le(r.sessionId)||!le(r.idempotencyKey)||!Number.isFinite(Date.parse(String(r.acquiredAt)))||!Number.isFinite(Date.parse(String(r.expiresAt))))return;const o=await H(e.projectRoot,{kind:"direct",storyId:t,sessionId:String(r.sessionId),idempotencyKey:String(r.idempotencyKey),createdAt:String(r.acquiredAt),expiresAt:String(r.expiresAt),persistent:!0});if(!o.ok)return;await N(o.path,o.owner)&&await J(e.projectRoot,e.epicId,r)}async function Q(e,t,i,r){const o=await Ee(t,{headSha:i,graphRevision:r,nowIso:e.nowIso});await e.qaRunner?.({projectRoot:t,storyId:e.storyId,headSha:i});const s=Be(o);if(!s)throw new Error("p205-transient-authority-invalid");return{contract:"P205-CI-02",command:_e,manifestDigest:s.manifestDigest,gateIds:s.gateIds,resultDigest:s.resultDigest,transientAuthority:o}}async function U(e,t,i,r){return await b(e,["rev-parse","HEAD"])!==i||await b(e,["symbolic-ref","--quiet","--short","HEAD"])!==t||!await z(e,["diff","--cached","--quiet"])?!1:z(e,["diff","--quiet","HEAD","--",...r])}async function he(e,t,i,r){const o=V(t);return(await b(e,["ls-remote","--heads",o,`refs/heads/${i}`])).split(/\s+/)[0]===r}function G(e,t,i){if(e.length===0||e.some(o=>!ue(o)))return{ok:!1,reasonCode:"direct-yolo-write-set-invalid"};const r=[".neocortex/state.json",`docs/stories/${i}.story.md`,`.neocortex/stories/${i}/qa-gate-result.json`,`.neocortex/stories/${i}/validation-evidence.md`,`.neocortex/stories/${i}/review.md`];return!r.every(o=>e.includes(o))||!r.every(o=>t.includes(o))?{ok:!1,reasonCode:"direct-yolo-write-set-invalid"}:e.some(o=>!t.includes(o))?{ok:!1,reasonCode:"direct-yolo-write-set-unauthorized"}:{ok:!0}}function ue(e){return e.length>0&&e.length<=1024&&!e.startsWith("/")&&!e.includes("\\")&&!e.split("/").includes("..")&&!e.startsWith(".git/")&&!e.includes("\0")}function le(e){return typeof e=="string"&&e.length>0&&e.length<=512&&/^[A-Za-z0-9._:@/+\-=]+$/.test(e)}function pe(e){return e.length>0&&e.length<=240&&!e.startsWith("-")&&!/[\s~^:?*[\\]/.test(e)&&!e.includes("..")}function V(e){if(!/^[A-Za-z0-9._-]{1,128}$/.test(e))throw new Error("direct-yolo-remote-invalid");return e}function F(e,t){const i=`${t}: `,r=e.split(`
3
+ `).map(o=>o.trim()).filter(o=>o.startsWith(i)).map(o=>o.slice(i.length));return r.length===1?r[0]:void 0}function v(e){return we("sha256").update(e).digest("hex")}function $(e){return e.split("\0").filter(Boolean)}function K(e){return e&&Number.isFinite(Date.parse(e))?new Date(Date.parse(e)).toISOString():new Date().toISOString()}function I(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:void 0}function X(e,t){return e instanceof Error&&e.message==="git-lifecycle-runtime-revision-conflict"?"direct-yolo-runtime-revision-conflict":e instanceof Error&&/^direct-yolo-[a-z0-9-]+$/.test(e.message)?e.message:t}function y(e){return{ok:!1,reasonCode:e}}async function b(e,t){return String((await Y("git",[...t],{cwd:e,encoding:"utf8",maxBuffer:32*1024*1024})).stdout).trim()}async function E(e,t){return String((await Y("git",[...t],{cwd:e,encoding:"utf8",maxBuffer:32*1024*1024})).stdout)}async function z(e,t){try{return await Y("git",[...t],{cwd:e,maxBuffer:8*1024*1024}),!0}catch{return!1}}export{Qe as beginDirectYoloStoryCommit,Ue as finalizeDirectYoloStoryCheckpoint,Je as issueDirectYoloSetupLeaseHandoff,Xe as recoverLegacyDirectYoloStoryCheckpoint};
@@ -0,0 +1,198 @@
1
+ import { type AnchoredDirectoryIdentity } from './secure-filesystem-boundary.js';
2
+ export declare const GIT_LIFECYCLE_RUNTIME_DIRECTORY = "neocortex-yoloop";
3
+ export declare const GIT_LIFECYCLE_RUNTIME_FILE = "runtime.json";
4
+ export declare const P205_COMPLETE_COMMAND: "node scripts/test-root.mjs --gate complete";
5
+ export declare const LEGACY_DIRECT_YOLO_RECOVERY_COMMITS: Readonly<Record<string, string>>;
6
+ interface LegacyCheckpointMigrationBinding {
7
+ readonly baseSha: string;
8
+ readonly headSha: string;
9
+ readonly graphRevision: string;
10
+ readonly effectiveClaimRevision: string;
11
+ readonly commitBodyDigest: string;
12
+ readonly changedPathsDigest: string;
13
+ readonly qaDigest: string;
14
+ readonly reviewDigest: string;
15
+ }
16
+ /**
17
+ * Exact immutable bindings for the seven P174 checkpoints predating P205-v2.
18
+ * This table is only an allowlist: every value is recomputed from Git and the
19
+ * independent QA/review receipts before a fresh aggregate P205 may migrate it.
20
+ */
21
+ export declare const LEGACY_P174_CHECKPOINT_MIGRATIONS: Readonly<Record<string, Readonly<LegacyCheckpointMigrationBinding>>>;
22
+ export interface GitLifecycleRuntimeDocument {
23
+ readonly schemaVersion: 1;
24
+ readonly revision: number;
25
+ readonly epics: Record<string, Record<string, unknown>>;
26
+ readonly stories: Record<string, Record<string, unknown>>;
27
+ }
28
+ export interface GitLifecycleMutationResult<T> {
29
+ readonly document: GitLifecycleRuntimeDocument;
30
+ readonly value: T;
31
+ }
32
+ export interface GitLifecycleMutationOptions {
33
+ /** Optional compare-and-swap guard for callers resuming a prior projection. */
34
+ readonly expectedRevision?: number;
35
+ /** Final async physical guard executed while the lifecycle lock is held. */
36
+ readonly preCommit?: (document: GitLifecycleRuntimeDocument) => Promise<void>;
37
+ }
38
+ export interface GitLifecycleReadOptions {
39
+ /** Epic-aware calls require the initialized sidecar; projectless calls opt out explicitly. */
40
+ readonly required?: boolean;
41
+ }
42
+ export interface GitLifecycleCheckpointVerification {
43
+ readonly schemaVersion: 1;
44
+ readonly kind: 'story_checkpoint_physical_verification';
45
+ readonly producer: 'client-p205-transient-v1';
46
+ readonly storyId: string;
47
+ readonly epicId: string;
48
+ readonly branch: string;
49
+ readonly baseSha: string;
50
+ readonly headSha: string;
51
+ readonly aggregateHeadSha: string;
52
+ readonly commitBodyDigest: string;
53
+ readonly changedPathsDigest: string;
54
+ readonly claimVerification: 'canonical' | 'legacy-migration';
55
+ readonly effectiveClaimRevision: string;
56
+ readonly command: typeof P205_COMPLETE_COMMAND;
57
+ readonly manifestDigest: string;
58
+ readonly gateIds: readonly string[];
59
+ readonly resultDigest: string;
60
+ readonly graphRevision: string;
61
+ readonly executionEvidenceDigest: string;
62
+ readonly sourceEvidenceDigest: string;
63
+ readonly verifiedAt: string;
64
+ readonly verdict: 'verified' | 'rejected';
65
+ readonly reasonCodes: readonly string[];
66
+ readonly publicSafe: true;
67
+ }
68
+ /**
69
+ * Process-local authority created only by a successful canonical P205 run.
70
+ * Its runtime object has no enumerable payload. Bindings live only in a private
71
+ * WeakMap so JSON, object spread and structural mocks cannot recreate authority.
72
+ */
73
+ export interface P205TransientExecutionAuthority {
74
+ readonly __p205OpaqueAuthority: never;
75
+ }
76
+ export declare function executeP205TransientAuthority(projectRoot: string, input: {
77
+ readonly headSha: string;
78
+ readonly graphRevision: string;
79
+ readonly nowIso?: string;
80
+ /** Internal detached QA sandbox; no replaceable command/executor seam. */
81
+ readonly anchoredWorkspace?: {
82
+ readonly parent: string;
83
+ readonly name: string;
84
+ readonly identity: AnchoredDirectoryIdentity;
85
+ };
86
+ }): Promise<P205TransientExecutionAuthority>;
87
+ export declare function readGitLifecycleRuntime(projectRoot: string, options?: GitLifecycleReadOptions): Promise<GitLifecycleRuntimeDocument>;
88
+ export declare function readGitLifecycleRuntimeSync(projectRoot: string, options?: GitLifecycleReadOptions): GitLifecycleRuntimeDocument;
89
+ export declare function mutateGitLifecycleRuntime<T>(projectRoot: string, mutate: (document: GitLifecycleRuntimeDocument) => T, options?: GitLifecycleMutationOptions): Promise<GitLifecycleMutationResult<T>>;
90
+ /** Merge the runtime overlay over tracked state without mutating either input. */
91
+ export declare function applyGitLifecycleRuntimeOverlay(tracked: Record<string, unknown>, runtime: GitLifecycleRuntimeDocument): Record<string, unknown>;
92
+ export declare function ensureRuntimeEpic(document: GitLifecycleRuntimeDocument, epicId: string): Record<string, unknown>;
93
+ export declare function ensureRuntimeStory(document: GitLifecycleRuntimeDocument, storyId: string): Record<string, unknown>;
94
+ /** Runtime-safe accepted-checkpoint predicate kept in the published client closure. */
95
+ export declare function isAcceptedGitLifecycleStoryCheckpoint(value: unknown, storyId: string, epicId: string, executionBranch: string): boolean;
96
+ /**
97
+ * Structural JSON is untrusted under a same-UID threat model. Recompute the
98
+ * commit-range/review authority from Git before a checkpoint can authorize
99
+ * aggregate QA or terminal integration.
100
+ */
101
+ export declare function verifyAcceptedGitLifecycleStoryCheckpoint(projectRoot: string, value: unknown, storyId: string, epicId: string, executionBranch: string, transientAuthority?: P205TransientExecutionAuthority | null, authorizedWriteSet?: readonly string[]): Promise<boolean>;
102
+ /**
103
+ * Synchronous variant used at the state-snapshot boundary, before any runtime
104
+ * overlay is sent to the server. It returns a fresh, public, Git-derived receipt.
105
+ */
106
+ export declare function verifyAcceptedGitLifecycleStoryCheckpointSync(projectRoot: string, value: unknown, storyId: string, epicId: string, executionBranch: string, transientAuthority?: P205TransientExecutionAuthority | null, authorizedWriteSet?: readonly string[], nowIso?: string): GitLifecycleCheckpointVerification;
107
+ /** Read-only projection for persistence/audit; it never recreates authority. */
108
+ export declare function projectP205TransientExecutionEvidence(authority: P205TransientExecutionAuthority | null | undefined): Readonly<{
109
+ readonly executionHeadSha: string;
110
+ readonly graphRevision: string;
111
+ readonly manifestDigest: string;
112
+ readonly gateIds: readonly string[];
113
+ readonly resultDigest: string;
114
+ readonly executedAt: string;
115
+ readonly executionEvidenceDigest: string;
116
+ }> | undefined;
117
+ export declare function p205TransientAuthorityMatchesAggregate(authority: P205TransientExecutionAuthority | null | undefined, headSha: string, graphRevision: string): boolean;
118
+ /** Reconstruct the same closed claim used by the direct or continuous planner. */
119
+ export declare function gitLifecycleStoryWriteSet(storyId: string, story: Record<string, unknown> | undefined, checkpoint: Record<string, unknown> | undefined): readonly string[];
120
+ /** Pre-P205 admission for only the exact seven immutable P174 migrations. */
121
+ export declare function verifyLegacyCheckpointMigrationCandidateSync(projectRoot: string, value: unknown, storyId: string, epicId: string, executionBranch: string, authorizedWriteSet: readonly string[]): boolean;
122
+ export declare function computeImmutableStoryQaEvidenceDigest(input: {
123
+ readonly storyId: string;
124
+ readonly baseSha: string;
125
+ readonly headSha: string;
126
+ readonly bundleDigest: string;
127
+ readonly graphRevision: string;
128
+ readonly commitBody: string;
129
+ readonly changedPaths: readonly string[];
130
+ }): string;
131
+ /** Bind an actual successful P205 execution to immutable Git authority. */
132
+ export declare function computeP205StoryQaEvidenceDigest(input: {
133
+ readonly gitEvidenceDigest: string;
134
+ readonly headSha: string;
135
+ readonly graphRevision: string;
136
+ readonly manifestDigest: string;
137
+ readonly gateIds: readonly string[];
138
+ readonly resultDigest: string;
139
+ }): string;
140
+ /**
141
+ * Bounded migration evidence for direct-*yolo commits created before canonical
142
+ * trailers were mandatory. The receipt is derived only from immutable commit
143
+ * data and story-owned evidence blobs; JSON sidecar shape alone is never enough.
144
+ */
145
+ export declare function computeLegacyDirectYoloRecoveryReceiptRef(projectRoot: string, input: {
146
+ readonly storyId: string;
147
+ readonly epicId: string;
148
+ readonly executionBranch: string;
149
+ readonly baseSha: string;
150
+ readonly headSha: string;
151
+ readonly bundleDigest: string;
152
+ readonly graphRevision: string;
153
+ }): Promise<string | undefined>;
154
+ /** Resolve/create the private root used by lifecycle state, locks and sandboxes. */
155
+ export declare function gitLifecycleRuntimeDirectory(projectRoot: string): Promise<string>;
156
+ /** Create or validate one private direct child without following substitutions. */
157
+ export declare function ensureGitLifecyclePrivateChildDirectory(parent: string, childName: string): Promise<string>;
158
+ /** Validate a private directory and every direct parent binding before use. */
159
+ export declare function assertGitLifecyclePrivateDirectory(path: string, parent: string): Promise<void>;
160
+ export declare function assertGitLifecyclePrivateFile(path: string, parent: string): Promise<void>;
161
+ /** Remove only the validated directory object renamed inside its validated parent. */
162
+ export declare function removeGitLifecyclePrivateDirectory(path: string, parent: string, verifyRenamed?: (quarantinePath: string) => Promise<boolean>): Promise<boolean>;
163
+ export interface GitLifecyclePhysicalIntegrationLockOwner {
164
+ readonly schemaVersion: 1;
165
+ readonly kind: 'direct' | 'continuous';
166
+ readonly storyId: string;
167
+ readonly sessionId: string;
168
+ readonly idempotencyKey: string;
169
+ readonly pid: number;
170
+ readonly createdAt: string;
171
+ readonly expiresAt: string;
172
+ readonly persistent: boolean;
173
+ readonly ownerNonce: string;
174
+ }
175
+ export type GitLifecyclePhysicalIntegrationLockResult = {
176
+ readonly ok: true;
177
+ readonly owner: GitLifecyclePhysicalIntegrationLockOwner;
178
+ readonly path: string;
179
+ } | {
180
+ readonly ok: false;
181
+ readonly reasonCode: 'git-lifecycle-integration-backpressure' | 'git-lifecycle-integration-lock-failed';
182
+ };
183
+ /** One physical writer lock shared by direct `*yolo` and continuous DAG integration. */
184
+ export declare function acquireGitLifecyclePhysicalIntegrationLock(projectRoot: string, requested: Omit<GitLifecyclePhysicalIntegrationLockOwner, 'schemaVersion' | 'pid' | 'createdAt' | 'ownerNonce'> & {
185
+ readonly createdAt?: string;
186
+ readonly ownerNonce?: string;
187
+ }): Promise<GitLifecyclePhysicalIntegrationLockResult>;
188
+ export declare function verifyGitLifecyclePhysicalIntegrationLock(path: string, expected: GitLifecyclePhysicalIntegrationLockOwner): Promise<boolean>;
189
+ export declare function releaseGitLifecyclePhysicalIntegrationLock(path: string, expected: GitLifecyclePhysicalIntegrationLockOwner): Promise<boolean>;
190
+ export declare function computeGitLifecyclePhysicalIntegrationLockOwnerDigest(owner: GitLifecyclePhysicalIntegrationLockOwner): string;
191
+ /** Recover only the exact persistent lock whose digest was bound to a checkpoint. */
192
+ export declare function releaseGitLifecyclePhysicalIntegrationLockForCheckpoint(projectRoot: string, input: {
193
+ readonly storyId: string;
194
+ readonly idempotencyKey: string;
195
+ readonly ownerDigest: string;
196
+ }): Promise<'absent' | 'released' | 'foreign'>;
197
+ export declare function posixSecurityAvailable(platform?: NodeJS.Platform): boolean;
198
+ export {};
@@ -0,0 +1,4 @@
1
+ import{execFile as tt,execFileSync as U}from"node:child_process";import{createHash as m,randomBytes as ye}from"node:crypto";import{lstat as be,open as it,readFile as F,realpath as K,stat as rt}from"node:fs/promises";import{existsSync as B,lstatSync as Ce,readFileSync as Oe,realpathSync as we}from"node:fs";import{basename as R,dirname as z,isAbsolute as ee,join as p,relative as nt,resolve as h}from"node:path";import{promisify as at}from"node:util";import{publicWriteSet as ct}from"../../../shared/dist/yoloop/public-story-write-set.js";import{anchoredAtomicWriteFile as ot,anchoredCreateOwnedDirectory as Pe,anchoredEnsureDirectory as Ne,anchoredExecuteGit as st,anchoredExecuteNode as $e,anchoredRemoveDirectory as dt,anchoredRenameDirectory as Q}from"./secure-filesystem-boundary.js";const C=at(tt),ce="neocortex-yoloop",oe="runtime.json",O="node scripts/test-root.mjs --gate complete",Ve=Object.freeze({"P174.03.029264":"339141be7339a0edf55710cbccb6e6558f514792"}),ft=Object.freeze({"P174.03.811759":Object.freeze({baseSha:"749c8fc732deaf26c81a8e08cc94b83c8cf0f5ba",headSha:"84162456d9cbe5000ffd0ed3eb3d0e88cfeba499",graphRevision:"60b343b4b810e6d5abc3159275012b9ab9ab517f9d780e7550fa5b49be740445",effectiveClaimRevision:"11f54704f5007f6139159419cfd7781f908b1502e117365c6d84011384579ed2",commitBodyDigest:"b4fc759a49765fd8c0b3d0f5d1c333c2a4bf28d324e83eedabb12f9530df3738",changedPathsDigest:"11f54704f5007f6139159419cfd7781f908b1502e117365c6d84011384579ed2",qaDigest:"f1100775e21f5d0d990f77303a2a06d936908f016983e32a63316d81aee6b9fc",reviewDigest:"50400bbcddb6f02408837cf99077de5d3af8c84822ab23a8b5499c338af7103a"}),"P174.03.685003":Object.freeze({baseSha:"84162456d9cbe5000ffd0ed3eb3d0e88cfeba499",headSha:"272a7fee89e4b9324d35701df1c83b671fa96299",graphRevision:"60b343b4b810e6d5abc3159275012b9ab9ab517f9d780e7550fa5b49be740445",effectiveClaimRevision:"6cc3c9033f1c4711dcbe3c676d1d7f9906614c7d6e95228e843d1c63cefbc641",commitBodyDigest:"e97966e26ce3ba31d5951b9fdac67808c88c1fd8be7ec1e73982f3f1cc7ffd81",changedPathsDigest:"6cc3c9033f1c4711dcbe3c676d1d7f9906614c7d6e95228e843d1c63cefbc641",qaDigest:"7439329a93321f39fb6b0de0a41c22e58373a399f9048e362dff4ffa6f1a7d89",reviewDigest:"1b2d12262e84acf9da7d06149a0effb11274ebdc986affbfd47635b855ec7135"}),"P174.03.029264":Object.freeze({baseSha:"272a7fee89e4b9324d35701df1c83b671fa96299",headSha:"339141be7339a0edf55710cbccb6e6558f514792",graphRevision:"60b343b4b810e6d5abc3159275012b9ab9ab517f9d780e7550fa5b49be740445",effectiveClaimRevision:"1053bb2baf487e38fa28d7e8cfb872c5c4da66802534ee226bbc2c7455a6a5ab",commitBodyDigest:"0f269a00dcd168a6f548ff10dfa667b193c948ac9c7211f5cb11a0561757c371",changedPathsDigest:"1053bb2baf487e38fa28d7e8cfb872c5c4da66802534ee226bbc2c7455a6a5ab",qaDigest:"ef0fd2c6e216557825cd8521ccb2f9960a3af48f18e7a5ada441bee8bfda400b",reviewDigest:"372d0f4a2f32978c8b39f20167637b3917187edb75d49875e93200c4c5a19d0d"}),"P174.03.913359":Object.freeze({baseSha:"339141be7339a0edf55710cbccb6e6558f514792",headSha:"4ccc90b85c49b27f718090bf25bc452f1b84e5e3",graphRevision:"60b343b4b810e6d5abc3159275012b9ab9ab517f9d780e7550fa5b49be740445",effectiveClaimRevision:"12b5cfba2667e8064309807776c1b323561dc8d853f9afe5f676007b8494b2b5",commitBodyDigest:"89a6653197509e75246a758d2706876b337770571a1cac47d9d85ec96c196459",changedPathsDigest:"12b5cfba2667e8064309807776c1b323561dc8d853f9afe5f676007b8494b2b5",qaDigest:"c7d3762ad30e4f9356243df17a1dd7123cbf1b660808d68176f44d1cd5da6449",reviewDigest:"e4ecf577e174fd66f31aa4a0113ab672ced16b12ee531f6831aa533795145ba1"}),"P174.03.724350":Object.freeze({baseSha:"4ccc90b85c49b27f718090bf25bc452f1b84e5e3",headSha:"568e9464fb086304146b9eb4594281f91302aef1",graphRevision:"60b343b4b810e6d5abc3159275012b9ab9ab517f9d780e7550fa5b49be740445",effectiveClaimRevision:"c8b8b6b96edf9cea78925e2f961bd74069d77af03783a5368b8ac8025bf1fefe",commitBodyDigest:"b3032338bfcd6c9dc460e9426220a1966dedeff9968c4064fdd36a315560721b",changedPathsDigest:"c8b8b6b96edf9cea78925e2f961bd74069d77af03783a5368b8ac8025bf1fefe",qaDigest:"91f2f5b00935b1b04bb5d400df500cbc97c412072078b713c6e5ba8fda669bd0",reviewDigest:"9bc92069d3b3a76cc8b02d339d432690258be1376464b69e152ed8fd3d682f05"}),"P174.03.011976":Object.freeze({baseSha:"568e9464fb086304146b9eb4594281f91302aef1",headSha:"195599b1a99a99a8416c4c26c9ab9990847338a4",graphRevision:"60b343b4b810e6d5abc3159275012b9ab9ab517f9d780e7550fa5b49be740445",effectiveClaimRevision:"49b7f2a0a967b2ba4249615c6d08834445a60df95045352838808eb4d6743b21",commitBodyDigest:"b8a28392fac663dd614b695a49c894b7cab116d45722a42850e3b24e2aaf36f4",changedPathsDigest:"49b7f2a0a967b2ba4249615c6d08834445a60df95045352838808eb4d6743b21",qaDigest:"6eb4459a7d80c4a268fc931297e8156ed2a320584f8775f0787d91b42c0929d4",reviewDigest:"98b21de29f7cceeec73da19000c6c144395cce6eb699c6a82dfab505d4ab7b44"}),"P174.03.686659":Object.freeze({baseSha:"195599b1a99a99a8416c4c26c9ab9990847338a4",headSha:"0db3681a5dad4e25ce37d967c636eb9d54915556",graphRevision:"60b343b4b810e6d5abc3159275012b9ab9ab517f9d780e7550fa5b49be740445",effectiveClaimRevision:"5c0fdbf820d677c288981b6f73f7d2d9a04ce7f4713687f12a2e984705244b8e",commitBodyDigest:"143257f4018ad773afc0c7280bd8aab8786851a9c20b65f8110881ff54656839",changedPathsDigest:"5c0fdbf820d677c288981b6f73f7d2d9a04ce7f4713687f12a2e984705244b8e",qaDigest:"6303dbf473e2815a3671aeb2c25528d8daba484b92a5a40d1eea5215e1f6763e",reviewDigest:"1bd6695846ed9340c8677cfa9b573880532187aeee487efaaa70577a0c94e7f2"})}),Se="neocortex-yoloop-runtime.json",ut="runtime.lock",Be=new WeakMap;async function ni(t,e){if(!w(e.headSha)||!g(e.graphRevision))throw new Error("p205-transient-binding-invalid");const i=e.anchoredWorkspace;if(i&&h(t)!==p(h(i.parent),i.name))throw new Error("p205-transient-anchor-binding-invalid");const r=async A=>i?(await st(i.parent,i.name,i.identity,A)).toString("utf8"):String((await C("git",[...A],{cwd:t,encoding:"utf8",maxBuffer:8*1024*1024})).stdout),n=async()=>i?JSON.parse((await $e(i.parent,i.name,i.identity,["-e","const fs=require('node:fs');process.stdout.write(JSON.stringify({manifest:fs.readFileSync('config/release-gates.v2.json','utf8'),runner:fs.readFileSync('scripts/test-root.mjs','utf8')}));"])).toString("utf8")):{manifest:await F(p(t,"config","release-gates.v2.json"),"utf8"),runner:await F(p(t,"scripts","test-root.mjs"),"utf8")};if((await r(["rev-parse","HEAD"])).trim()!==e.headSha)throw new Error("p205-transient-head-mismatch");const{manifest:o,runner:s}=await n(),[u,c]=await Promise.all([r(["show",`${e.headSha}:config/release-gates.v2.json`]),r(["show",`${e.headSha}:scripts/test-root.mjs`])]);if(o!==u||s!==c)throw new Error("p205-transient-producer-dirty");const d=JSON.parse(o),S=Array.isArray(d.requiredCompleteClasses)?d.requiredCompleteClasses.filter(A=>typeof A=="string"&&/^[a-z0-9-]+$/.test(A)):[];if(d.contract!=="P205-CI-02"||S.length===0)throw new Error("p205-transient-manifest-invalid");const l=i?(await $e(i.parent,i.name,i.identity,["scripts/test-root.mjs","--gate","complete"])).toString("utf8"):String((await C(process.execPath,["scripts/test-root.mjs","--gate","complete"],{cwd:t,encoding:"utf8",maxBuffer:64*1024*1024})).stdout),{manifest:y,runner:v}=await n();if(y!==o||v!==s)throw new Error("p205-transient-producer-raced");if((await r(["rev-parse","HEAD"])).trim()!==e.headSha)throw new Error("p205-transient-head-raced");const G=m("sha256").update(o).digest("hex"),$=m("sha256").update(l).digest("hex"),Y=ie(e.nowIso??new Date().toISOString()),V=m("sha256").update(["p205-transient-execution-v1",O,e.headSha,e.graphRevision,G,S.join(","),$,Y].join("\0")).digest("hex"),ae=Object.freeze({schemaVersion:1,kind:"p205_transient_execution_authority",contract:"P205-CI-02",command:O,executionHeadSha:e.headSha,graphRevision:e.graphRevision,manifestDigest:G,gateIds:Object.freeze(S),resultDigest:$,executedAt:Y,executionEvidenceDigest:V}),ge=Object.freeze(Object.create(null));return Be.set(ge,ae),ge}async function ai(t,e={}){const i=await xt(t);return Ke(i,e)}function gt(t,e={}){let i;try{const r=U("git",["rev-parse","--git-common-dir"],{cwd:t,encoding:"utf8",stdio:["ignore","pipe","ignore"]}).trim(),n=we(t),a=ee(r)?h(r):h(n,r),o=we(a);if(o!==a)throw new Error("git-lifecycle-common-dir-symlink");kt(o);const s=p(o,ce),u=p(s,oe);if(B(s)&&(Me(s,"directory"),we(s)!==s))throw new Error("git-lifecycle-runtime-directory-symlink");i=B(u)?u:p(o,Se)}catch{if(e.required)throw new Error("git-lifecycle-common-dir-invalid");return Re()}if(!B(i)){if(e.required)throw new Error("git-lifecycle-runtime-missing");return Re()}return Me(i,"file"),xe(JSON.parse(Oe(i,"utf8")))}async function ci(t,e,i={}){const r=await De(t),n=await Fe(r),a=p(n,ut),o=await Wt(a);try{const s=p(n,oe),u=p(r,Se),c=await Ke(B(s)?s:u);if(i.expectedRevision!==void 0&&i.expectedRevision!==c.revision)throw new Error("git-lifecycle-runtime-revision-conflict");const d=structuredClone(c),S=e(d),l=xe({...d,schemaVersion:1,revision:c.revision+1});return await i.preCommit?.(l),await L(n,"directory"),await It(s),await ot(n,oe,`${JSON.stringify(l,null,2)}
2
+ `),await L(s,"file"),await lt(n),{document:l,value:S}}finally{await Yt(a,o).catch(()=>{})}}async function lt(t){let e;try{e=await it(t,"r")}catch(i){if(process.platform==="win32"&&(_(i,"EPERM")||_(i,"EISDIR")||_(i,"EINVAL")))return;throw i}try{await e.sync()}finally{await e.close()}}function oi(t,e){const i=structuredClone(t),r=qe(i,"epics"),n=qe(i,"stories");for(const[a,o]of Object.entries(e.epics))r[a]={...f(r[a])??{},...structuredClone(o)};for(const[a,o]of Object.entries(e.stories))n[a]={...f(n[a])??{},...structuredClone(o)};return i}function qe(t,e){const i=t[e];if(i===void 0){const a={};return t[e]=a,a}const r=f(i);if(r)return r;if(!Array.isArray(i))throw new Error(`git-lifecycle-tracked-${e}-invalid`);const n={};for(const a of i){const o=f(a),s=typeof o?.id=="string"?o.id.trim():"";if(!s||n[s]!==void 0)throw new Error(`git-lifecycle-tracked-${e}-ambiguous`);n[s]=o}return t[e]=n,n}function si(t,e){return t.epics[e]??(t.epics[e]={})}function di(t,e){return t.stories[e]??(t.stories[e]={})}function Le(t,e,i,r){const n=f(t);return!!(n&&n.epicId===i&&n.branch===r&&n.qaVerdict==="passed"&&n.reviewVerdict==="approved"&&We(n,e))}async function fi(t,e,i,r,n,a,o=[]){return ht(t,e,i,r,n,a,o).verdict==="verified"}function ht(t,e,i,r,n,a,o=[],s=new Date().toISOString()){const u=()=>Dt({storyId:i,epicId:r,executionBranch:n,value:e,verifiedAt:s,verdict:"rejected",reasonCode:"checkpoint-git-physical-invalid"});try{if(!Le(e,i,r,n))return u();const c=f(e),d=f(c.qaReceipt),S=f(c.reviewReceipt),l=String(c.headSha),y=String(c.baseSha),v=q(t,["rev-parse",`refs/heads/${n}`]).trim();U("git",["merge-base","--is-ancestor",l,v],{cwd:t,stdio:"ignore"});const N=q(t,["show","--no-patch","--format=%H%n%P%n%B",l]),G=q(t,["rev-parse",`${l}^`]).trim(),$=q(t,["rev-list","--count",`${y}..${l}`]).trim();if(G!==y||$!=="1")return u();const Y=new Set(N.split(`
3
+ `).map(j=>j.trim())),ae=[`Neocortex-Story: ${i}`,`Neocortex-Epic: ${r}`,`Neocortex-Execution-Branch: ${n}`,`Neocortex-Bundle-Digest: ${String(c.bundleDigest)}`,`Neocortex-Graph-Revision: ${String(c.graphRevision)}`,...c.dispatchId?[`Neocortex-Dispatch: ${String(c.dispatchId)}`]:[],...c.bundleId?[`Neocortex-Bundle: ${String(c.bundleId)}`]:[],...c.claimRevision?[`Neocortex-Claim-Revision: ${String(c.claimRevision)}`]:[]].every(j=>Y.has(j));if(ae){const ke=[...Y].find(et=>et.startsWith("Neocortex-Prepared-Base: "))?.slice(25)??"";if(!/^[a-f0-9]{40,64}$/i.test(ke))return u();U("git",["merge-base","--is-ancestor",ke,l],{cwd:t,stdio:"ignore"})}const A=q(t,["diff-tree","--no-commit-id","--name-only","-r","-z",l]).split("\0").filter(Boolean);if(A.length===0||A.some(j=>!de(j)))return u();const le=m("sha256").update(N).digest("hex"),he=m("sha256").update([...A].sort().join("\0")).digest("hex"),k=je({checkpoint:c,storyId:i,epicId:r,executionBranch:n,baseSha:y,headSha:l,commitBodyDigest:le,changedPathsDigest:he,changedPaths:A,authorizedWriteSet:o.length>0?o:yt(t,i)});if(!k||d.receiptRef!==`story-qa:${String(d.sourceEvidenceDigest)}`)return u();const _e=St({storyId:i,baseSha:y,headSha:l,bundleDigest:String(c.bundleDigest),graphRevision:String(c.graphRevision),commitBody:N,changedPaths:A}),Ie=d.evidenceVersion==="p205-execution-v2"&&d.contract==="P205-CI-02"&&d.command===O&&g(d.manifestDigest)&&P(d.gateIds,32,!0)&&g(d.resultDigest)&&d.sourceEvidenceDigest===vt({gitEvidenceDigest:_e,headSha:l,graphRevision:String(c.graphRevision),manifestDigest:String(d.manifestDigest),gateIds:d.gateIds,resultDigest:String(d.resultDigest)}),Ze=d.evidenceVersion==="git-immutable-v1"&&d.sourceEvidenceDigest===_e,Xe=d.evidenceVersion===void 0&&k.mode==="legacy-migration"&&k.binding?.qaDigest===d.sourceEvidenceDigest,me=mt(a,v,String(c.graphRevision))&&(Ie||k.mode==="legacy-migration"&&(Ze||Xe)),pe=a===void 0&&Ie;if(!me&&!pe)return u();const Ae=m("sha256").update(["root-commit-range-review-v1",i,y,l,String(c.bundleDigest),String(c.graphRevision),String(d.receiptRef),m("sha256").update(N).digest("hex"),[...A].sort().join(",")].join("\0")).digest("hex");if(S.sourceEvidenceDigest!==Ae||S.receiptRef!==`story-review:${Ae}`||k.mode==="legacy-migration"&&k.binding?.reviewDigest!==void 0&&k.binding.reviewDigest!==S.sourceEvidenceDigest||!ae&&(Ve[i]!==l||!Array.isArray(c.receiptRefs)||!c.receiptRefs.some(j=>typeof j=="string"&&j.startsWith("legacy-direct-yolo:"))))return u();const Ue=m("sha256").update(["checkpoint-p205-transient-v1",i,r,n,y,l,String(c.bundleDigest),le,he,k.mode,k.effectiveClaimRevision,String(d.sourceEvidenceDigest),String(S.sourceEvidenceDigest),te(a)?.executionEvidenceDigest??(pe?"maintenance-git-verification":"legacy-bounded-authority")].join("\0")).digest("hex"),J=me?te(a):void 0;return Object.freeze({schemaVersion:1,kind:"story_checkpoint_physical_verification",producer:"client-p205-transient-v1",storyId:i,epicId:r,branch:n,baseSha:y,headSha:l,aggregateHeadSha:J?.executionHeadSha??l,commitBodyDigest:le,changedPathsDigest:he,claimVerification:k.mode,effectiveClaimRevision:k.effectiveClaimRevision,sourceEvidenceDigest:Ue,command:O,manifestDigest:J?.manifestDigest??"0".repeat(64),gateIds:J?.gateIds??Object.freeze(["legacy-bounded"]),resultDigest:J?.resultDigest??"0".repeat(64),graphRevision:String(c.graphRevision),executionEvidenceDigest:J?.executionEvidenceDigest??"0".repeat(64),verifiedAt:J?.executedAt??ie(s),verdict:"verified",reasonCodes:Object.freeze([me?"checkpoint-p205-transient-verified":pe?"checkpoint-git-maintenance-verified":"checkpoint-legacy-bounded-verified",...k.mode==="legacy-migration"?["checkpoint-legacy-migration-verified"]:[]]),publicSafe:!0})}catch{return u()}}function mt(t,e,i){const r=te(t);return!!(r&&r.schemaVersion===1&&r.kind==="p205_transient_execution_authority"&&r.contract==="P205-CI-02"&&r.command===O&&r.graphRevision===i&&g(r.resultDigest)&&g(r.executionEvidenceDigest)&&r.executionHeadSha===e&&w(e))}function te(t){return t&&typeof t=="object"?Be.get(t):void 0}function ui(t){const e=te(t);return e?Object.freeze({executionHeadSha:e.executionHeadSha,graphRevision:e.graphRevision,manifestDigest:e.manifestDigest,gateIds:Object.freeze([...e.gateIds]),resultDigest:e.resultDigest,executedAt:e.executedAt,executionEvidenceDigest:e.executionEvidenceDigest}):void 0}function gi(t,e,i){const r=te(t);return!!(r&&r.executionHeadSha===e&&r.graphRevision===i&&r.command===O)}function je(t){const e=ft[t.storyId],i=typeof t.checkpoint.claimRevision=="string"?t.checkpoint.claimRevision:void 0,r=t.storyId==="P174.03.811759"||t.storyId==="P174.03.685003",n=pt(t.authorizedWriteSet),a=n.length>0&&n.length===t.authorizedWriteSet.length&&t.changedPaths.every(o=>n.some(s=>wt(s,o)));if(e&&t.epicId==="P174"&&t.executionBranch==="epic/P174"&&t.baseSha===e.baseSha&&t.headSha===e.headSha&&t.checkpoint.graphRevision===e.graphRevision&&t.commitBodyDigest===e.commitBodyDigest&&t.changedPathsDigest===e.changedPathsDigest&&(r?i===void 0:i===e.effectiveClaimRevision))return t.authorizedWriteSet.length>0&&(!a||!ze(e.effectiveClaimRevision,n))?void 0:Object.freeze({mode:"legacy-migration",effectiveClaimRevision:e.effectiveClaimRevision,binding:e});if(i!==void 0&&!(!i||!g(i))&&!(!a||!ze(i,n)))return Object.freeze({mode:"canonical",effectiveClaimRevision:i})}function pt(t){const e=t.map(i=>i.replaceAll("\\","/").replace(/^\.\//,"").replace(/\/{2,}/g,"/"));return e.some(i=>!de(i))?Object.freeze([]):Object.freeze([...new Set(e)].sort())}function yt(t,e){try{const i=JSON.parse(Oe(p(t,".neocortex","state.json"),"utf8")),r=f(i.stories),n=f(r?.[e]),a=gt(t),o=f(a.stories[e]?.checkpoint)??f(n?.checkpoint);return bt(e,n,o)}catch{return[]}}function bt(t,e,i){const r=Array.isArray(e?.files_to_modify)?e.files_to_modify.filter(n=>typeof n=="string"):[];if(!i?.dispatchId||!i.bundleId)return r;try{return ct({...e,id:t,files_to_modify:r})}catch{return[]}}function ze(t,e){return t===m("sha256").update(e.join("\0")).digest("hex")||t===m("sha256").update(JSON.stringify(e)).digest("hex")}function wt(t,e){return t===e||t.endsWith("/")&&e.startsWith(t)}function li(t,e,i,r,n,a){try{if(!Le(e,i,r,n))return!1;const o=f(e),s=f(o.qaReceipt),u=f(o.reviewReceipt),c=String(o.headSha),d=String(o.baseSha),S=q(t,["rev-parse",`refs/heads/${n}`]).trim();if(U("git",["merge-base","--is-ancestor",c,S],{cwd:t,stdio:"ignore"}),q(t,["rev-parse",`${c}^`]).trim()!==d||q(t,["rev-list","--count",`${d}..${c}`]).trim()!=="1")return!1;const l=q(t,["show","--no-patch","--format=%H%n%P%n%B",c]),y=q(t,["diff-tree","--no-commit-id","--name-only","-r","-z",c]).split("\0").filter(Boolean);if(y.length===0||y.some(N=>!de(N)))return!1;const v=je({checkpoint:o,storyId:i,epicId:r,executionBranch:n,baseSha:d,headSha:c,changedPaths:y,authorizedWriteSet:a,commitBodyDigest:m("sha256").update(l).digest("hex"),changedPathsDigest:m("sha256").update([...y].sort().join("\0")).digest("hex")});return!(v?.mode!=="legacy-migration"||!v.binding||s.sourceEvidenceDigest!==v.binding.qaDigest||s.receiptRef!==`story-qa:${v.binding.qaDigest}`||u.sourceEvidenceDigest!==v.binding.reviewDigest||u.receiptRef!==`story-review:${v.binding.reviewDigest}`||u.qaReceiptRef!==s.receiptRef)}catch{return!1}}function St(t){return m("sha256").update(["local-yolo-tdd-git-immutable-v1",t.storyId,t.baseSha,t.headSha,t.bundleDigest,t.graphRevision,m("sha256").update(t.commitBody).digest("hex"),m("sha256").update([...t.changedPaths].sort().join("\0")).digest("hex")].join("\0")).digest("hex")}function vt(t){return m("sha256").update(["local-yolo-tdd-p205-execution-v2",O,t.gitEvidenceDigest,t.headSha,t.graphRevision,t.manifestDigest,t.gateIds.join(","),t.resultDigest].join("\0")).digest("hex")}function Dt(t){const e=f(t.value);return Object.freeze({schemaVersion:1,kind:"story_checkpoint_physical_verification",producer:"client-p205-transient-v1",storyId:t.storyId,epicId:t.epicId,branch:t.executionBranch,baseSha:w(e?.baseSha)?String(e?.baseSha):"0".repeat(40),headSha:w(e?.headSha)?String(e?.headSha):"0".repeat(40),aggregateHeadSha:"0".repeat(40),commitBodyDigest:"0".repeat(64),changedPathsDigest:"0".repeat(64),claimVerification:"canonical",effectiveClaimRevision:"0".repeat(64),command:O,manifestDigest:"0".repeat(64),gateIds:Object.freeze([]),resultDigest:"0".repeat(64),graphRevision:"0".repeat(64),executionEvidenceDigest:"0".repeat(64),sourceEvidenceDigest:"0".repeat(64),verifiedAt:ie(t.verifiedAt),verdict:t.verdict,reasonCodes:Object.freeze([t.reasonCode]),publicSafe:!0})}function q(t,e){return U("git",[...e],{cwd:t,encoding:"utf8",maxBuffer:32*1024*1024})}function ie(t){return Number.isFinite(Date.parse(t))?new Date(Date.parse(t)).toISOString():new Date().toISOString()}async function hi(t,e){if(Ve[e.storyId]!==e.headSha)return;const i=[".neocortex/state.json",`.neocortex/stories/${e.storyId}/qa-gate-result.json`,`.neocortex/stories/${e.storyId}/validation-evidence.md`,`.neocortex/stories/${e.storyId}/review.md`,`docs/stories/${e.storyId}.story.md`];try{const r=(await C("git",["rev-parse",`refs/heads/${e.executionBranch}`],{cwd:t,encoding:"utf8",maxBuffer:1048576})).stdout.trim();if(await C("git",["merge-base","--is-ancestor",e.headSha,r],{cwd:t}),(await C("git",["rev-parse",`${e.headSha}^`],{cwd:t,encoding:"utf8",maxBuffer:1024*1024})).stdout.trim()!==e.baseSha)return;const a=String((await C("git",["diff","--binary","--full-index",`${e.baseSha}..${e.headSha}`],{cwd:t,encoding:"utf8",maxBuffer:32*1024*1024})).stdout);if(m("sha256").update(a).digest("hex")!==e.bundleDigest)return;const o=String((await C("git",["show","--no-patch","--format=%H%n%P%n%B",e.headSha],{cwd:t,encoding:"utf8",maxBuffer:4*1024*1024})).stdout);if(!String((await C("git",["show","--no-patch","--format=%s",e.headSha],{cwd:t,encoding:"utf8",maxBuffer:1024*1024})).stdout).trim().includes(e.storyId))return;const c=String((await C("git",["diff-tree","--no-commit-id","--name-only","-r","-z",e.headSha],{cwd:t,encoding:"utf8",maxBuffer:8*1024*1024})).stdout).split("\0").filter(Boolean);if(!i.every(V=>c.includes(V))||c.some(V=>!de(V)))return;const d=await Promise.all(i.map(async V=>String((await C("git",["show",`${e.headSha}:${V}`],{cwd:t,encoding:"utf8",maxBuffer:16*1024*1024})).stdout))),S=JSON.parse(d[0]),l=f(S.stories),y=f(S.epics),v=f(l?.[e.storyId]),N=f(y?.[e.epicId]),G=Array.isArray(v?.steps_completed)?v.steps_completed:[],$=JSON.parse(d[1]);return v?.status!=="done"||!G.includes("step-c-08-commit-push")||!G.includes("step-c-11-review-pr")||N?.branch_mode!=="epic"||N.execution_branch!==e.executionBranch||$.storyId!==e.storyId||$.status!=="qa-passed"||$.safeToContinueYoloop!==!0||!Array.isArray($.blockingChecks)||$.blockingChecks.length!==0||!d[2].includes(e.storyId)||!/P205[\s\S]{0,80}(pass|aprov)/i.test(d[2])||!d[3].includes(e.storyId)||!/approved|aprovado/i.test(d[3])||!d[4].includes(e.storyId)?void 0:`legacy-direct-yolo:${m("sha256").update(["legacy-direct-yolo-recovery-v1",e.storyId,e.epicId,e.executionBranch,e.baseSha,e.headSha,e.bundleDigest,e.graphRevision,m("sha256").update(o).digest("hex"),m("sha256").update([...c].sort().join("\0")).digest("hex"),...d.map(V=>m("sha256").update(V).digest("hex"))].join("\0")).digest("hex")}`}catch{return}}async function xt(t){const e=await De(t),i=p(e,ce),r=p(i,oe);if(B(i)&&(await L(i,"directory"),await K(i)!==i))throw new Error("git-lifecycle-runtime-directory-symlink");return B(r)?r:p(e,Se)}async function He(t){return Fe(await De(t))}async function Rt(t,e){if(!/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/.test(e)||e.includes(".."))throw new Error("git-lifecycle-private-child-invalid");const i=h(t);await H(i);const r=h(i,e);return Z(i,r),B(r)||await Ne(i,e),await H(r,i),await H(i),r}async function b(t,e){const i=h(e),r=h(t);Z(i,r),await H(i),await H(r,i)}async function mi(t,e){await T(t,e)}async function M(t,e,i){const r=h(e),n=h(t);Z(r,n);try{await b(n,r)}catch(o){if(_(o,"ENOENT"))return!1;throw o}const a=h(r,`${n.slice(r.length+1)}.remove.${process.pid}.${Date.now()}.${ye(4).toString("hex")}`);return Z(r,a),await Q(r,R(n),R(a)),await b(a,r),i&&!await i(a)?(await re(a,n,r).catch(()=>{}),!1):(await dt(r,R(a)),!0)}async function re(t,e,i){await b(t,i);try{await be(e);return}catch(r){if(!_(r,"ENOENT"))throw r}await Q(i,R(t),R(e)),await b(e,i)}async function I(t){try{await b(t,z(t));const e=p(t,"owner.json");await T(e,t);const i=await F(e);return await T(e,t),m("sha256").update(i).digest("hex")}catch{return}}async function pi(t,e){const i=await He(t),r=await Rt(i,"leases"),n=p(r,"integration"),a=`${n}.recovery`;if(B(a)){await b(a,r);const c=await Te(a),d=await I(a);if(c===void 0||ue(c))return{ok:!1,reasonCode:"git-lifecycle-integration-backpressure"};if(!d||!await M(a,r,async S=>await I(S)===d))return{ok:!1,reasonCode:"git-lifecycle-integration-backpressure"}}const o=ie(e.createdAt??new Date().toISOString()),s=Object.freeze({schemaVersion:1,kind:e.kind,storyId:e.storyId,sessionId:e.sessionId,idempotencyKey:e.idempotencyKey,pid:process.pid,createdAt:o,expiresAt:ie(e.expiresAt),persistent:e.persistent,ownerNonce:e.ownerNonce??ye(16).toString("hex")});if(Date.parse(s.expiresAt)<=Date.parse(s.createdAt))return{ok:!1,reasonCode:"git-lifecycle-integration-lock-failed"};const u=async()=>{await H(r,i);try{return await Pe(r,R(n),`${JSON.stringify(s)}
4
+ `),await b(n,r),await T(p(n,"owner.json"),n),!0}catch(c){throw _(c,"EEXIST")||await M(n,r).catch(()=>{}),c}};try{return await u(),{ok:!0,owner:s,path:n}}catch(c){if(!_(c,"EEXIST"))return{ok:!1,reasonCode:"git-lifecycle-integration-lock-failed"}}try{const c=await ne(n),d=c?void 0:await Te(n);if(c&&Ge(c,s))return{ok:!0,owner:c,path:n};if(c&&Date.parse(c.expiresAt)>Date.now()&&(c.persistent||ue(c.pid))||d!==void 0&&ue(d)||!c&&d===void 0&&await Je(n))return{ok:!1,reasonCode:"git-lifecycle-integration-backpressure"};const l=await I(n);if(!l)return{ok:!1,reasonCode:"git-lifecycle-integration-lock-failed"};const y=`${n}.stale.${process.pid}.${Date.now()}`;await Q(r,R(n),R(y));try{if(await b(y,r),await I(y)!==l)return await re(y,n,r).catch(()=>{}),{ok:!1,reasonCode:"git-lifecycle-integration-backpressure"};await u()}finally{await M(y,r,async v=>await I(v)===l).catch(()=>{})}return{ok:!0,owner:s,path:n}}catch(c){return{ok:!1,reasonCode:_(c,"EEXIST")||_(c,"ENOENT")?"git-lifecycle-integration-backpressure":"git-lifecycle-integration-lock-failed"}}}async function yi(t,e){const i=await ne(t);return!!(i&&ve(i,e)&&Date.parse(i.expiresAt)>Date.now())}async function Et(t,e){try{const i=z(t);await b(t,i);const r=await ne(t);if(!r||!ve(r,e))return!1;const n=await I(t);if(!n)return!1;const a=`${t}.release.${process.pid}.${Date.now()}`;await Q(i,R(t),R(a)),await b(a,i);const o=await ne(a);return!o||!ve(o,e)||await I(a)!==n?(await re(a,t,i).catch(()=>{}),!1):M(a,i,async s=>await I(s)===n)}catch(i){if(_(i,"ENOENT"))return!1;throw i}}function _t(t){return m("sha256").update(["git-lifecycle-physical-owner-v1",t.kind,t.storyId,t.sessionId,t.idempotencyKey,String(t.pid),t.createdAt,t.expiresAt,t.persistent?"persistent":"ephemeral",t.ownerNonce].join("\0")).digest("hex")}async function bi(t,e){if(!X(e.storyId)||!E(e.idempotencyKey)||!g(e.ownerDigest))return"foreign";const i=await He(t),r=p(i,"leases"),n=p(r,"integration");if(!B(n))return"absent";try{await b(r,i),await b(n,r);const a=await ne(n);return!a||a.kind!=="direct"||a.storyId!==e.storyId||a.sessionId!==e.idempotencyKey||a.idempotencyKey!==e.idempotencyKey||a.persistent!==!0||_t(a)!==e.ownerDigest?"foreign":await Et(n,a)?"released":"foreign"}catch{return"foreign"}}async function ne(t){try{await b(t,z(t));const e=p(t,"owner.json");await T(e,t);const i=JSON.parse(await F(e,"utf8"));return i.schemaVersion!==1||i.kind!=="direct"&&i.kind!=="continuous"||!X(i.storyId)||!E(i.sessionId)||!E(i.idempotencyKey)||!Number.isSafeInteger(i.pid)||Number(i.pid)<=0||!x(i.createdAt)||!x(i.expiresAt)||typeof i.persistent!="boolean"||typeof i.ownerNonce!="string"||!/^[a-f0-9]{32}$/.test(i.ownerNonce)?void 0:i}catch{return}}async function Te(t){try{await b(t,z(t));const e=p(t,"owner.json");await T(e,t);const i=JSON.parse(await F(e,"utf8"));return Number.isSafeInteger(i.pid)&&Number(i.pid)>0?Number(i.pid):void 0}catch{return}}function Ge(t,e){return t.kind===e.kind&&t.storyId===e.storyId&&t.sessionId===e.sessionId&&t.idempotencyKey===e.idempotencyKey&&t.expiresAt===e.expiresAt&&t.persistent===e.persistent}function ve(t,e){return Ge(t,e)&&t.schemaVersion===e.schemaVersion&&t.pid===e.pid&&t.createdAt===e.createdAt&&t.ownerNonce===e.ownerNonce}async function De(t){const e=await K(t),r=(await C("git",["rev-parse","--git-common-dir"],{cwd:e,encoding:"utf8",maxBuffer:1024*1024})).stdout.trim(),n=ee(r)?h(r):h(e,r),a=await K(n);if(a!==n)throw new Error("git-lifecycle-common-dir-symlink");await At(a);const s=(await C("git",["rev-parse","--git-common-dir"],{cwd:e,encoding:"utf8",maxBuffer:1024*1024})).stdout.trim();if((ee(s)?h(s):h(e,s))!==n)throw new Error("git-lifecycle-common-dir-raced");return a}async function Fe(t){const e=p(t,ce);if(B(e)||await Ne(t,ce),await L(e,"directory"),await K(e)!==e)throw new Error("git-lifecycle-runtime-directory-symlink");return e}async function Ke(t,e={}){try{return await L(t,"file"),xe(JSON.parse(await F(t,"utf8")))}catch(i){if(_(i,"ENOENT")){if(e.required)throw new Error("git-lifecycle-runtime-missing");return Re()}throw i}}async function It(t){try{await L(t,"file")}catch(e){if(_(e,"ENOENT"))return;throw e}}async function L(t,e){const i=await be(t);if(i.isSymbolicLink())throw new Error(`git-lifecycle-${e}-symlink`);if(e==="file"?!i.isFile():!i.isDirectory())throw new Error(`git-lifecycle-${e}-invalid`);if(se()&&i.uid!==process.getuid())throw new Error(`git-lifecycle-${e}-ownership-mismatch`);if(se()&&(i.mode&63)!==0)throw new Error(`git-lifecycle-${e}-permissions-unsafe`)}function Z(t,e){const i=h(t),r=h(e),n=nt(i,r);if(!n||n.startsWith("..")||ee(n)||z(r)!==i)throw new Error("git-lifecycle-private-path-escape")}async function H(t,e){const i=h(t);if(e&&Z(h(e),i),await L(i,"directory"),h(await K(i))!==i)throw new Error("git-lifecycle-directory-substituted");if(e){const r=h(e);if(await L(r,"directory"),h(await K(r))!==r)throw new Error("git-lifecycle-directory-parent-substituted")}}async function T(t,e){const i=h(t);if(Z(h(e),i),await H(h(e)),await L(i,"file"),h(await K(i))!==i)throw new Error("git-lifecycle-file-substituted")}function Me(t,e){const i=Ce(t);if(i.isSymbolicLink())throw new Error(`git-lifecycle-${e}-symlink`);if(e==="file"?!i.isFile():!i.isDirectory())throw new Error(`git-lifecycle-${e}-invalid`);if(se()&&i.uid!==process.getuid())throw new Error(`git-lifecycle-${e}-ownership-mismatch`);if(se()&&(i.mode&63)!==0)throw new Error(`git-lifecycle-${e}-permissions-unsafe`)}async function At(t){const e=await be(t);if(e.isSymbolicLink())throw new Error("git-lifecycle-common-dir-symlink");if(!e.isDirectory())throw new Error("git-lifecycle-common-dir-invalid")}function kt(t){const e=Ce(t);if(e.isSymbolicLink())throw new Error("git-lifecycle-common-dir-symlink");if(!e.isDirectory())throw new Error("git-lifecycle-common-dir-invalid")}function se(t=process.platform){return t!=="win32"&&typeof process.getuid=="function"}function xe(t){if(!t||typeof t!="object"||Array.isArray(t))throw new Error("git-lifecycle-runtime-invalid");const e=t;D(e,["schemaVersion","revision","epics","stories"],"git-lifecycle-runtime-unknown-field");const i=f(e.epics),r=f(e.stories);if(e.schemaVersion!==1||!Number.isSafeInteger(e.revision)||Number(e.revision)<0||!i||!r||Object.values(i).some(n=>!f(n))||Object.values(r).some(n=>!f(n)))throw new Error("git-lifecycle-runtime-invalid");for(const[n,a]of Object.entries(i))if(!X(n)||!Pt(a))throw new Error("git-lifecycle-runtime-epic-invalid");for(const[n,a]of Object.entries(r))if(!X(n)||!n.includes(".")||!Nt(a,n))throw new Error("git-lifecycle-runtime-story-invalid");return e}const Ct=["branch_mode","execution_branch","origin_branch","branch_lease","origin_binding","graph_revision","aggregate_qa_receipt","terminal_git_receipt","physicalMergeStatus","pr_number","git_reconciliation_receipts","git_reconciliation_debt"],Ot=["checkpoint","status","last_step","steps_completed"];function Pt(t){return D(t,Ct,"git-lifecycle-runtime-epic-unknown-field"),(t.branch_mode===void 0||t.branch_mode==="epic")&&(t.execution_branch===void 0||W(t.execution_branch))&&(t.origin_branch===void 0||W(t.origin_branch))&&(t.branch_lease===void 0||t.branch_lease===null||$t(t.branch_lease))&&(t.origin_binding===void 0||t.origin_binding===null||qt(t.origin_binding))&&(t.graph_revision===void 0||g(t.graph_revision))&&(t.aggregate_qa_receipt===void 0||t.aggregate_qa_receipt===null||Lt(t.aggregate_qa_receipt))&&(t.terminal_git_receipt===void 0||t.terminal_git_receipt===null||jt(t.terminal_git_receipt))&&(t.physicalMergeStatus===void 0||["merged","pushed","denied_external_gate","blocked_local_or_repo","not_attempted"].includes(String(t.physicalMergeStatus)))&&(t.pr_number===void 0||t.pr_number===null||Number.isSafeInteger(t.pr_number)&&Number(t.pr_number)>0)&&(t.git_reconciliation_receipts===void 0||Ft(t.git_reconciliation_receipts))&&(t.git_reconciliation_debt===void 0||Kt(t.git_reconciliation_debt))}function Nt(t,e){return D(t,Ot,"git-lifecycle-runtime-story-unknown-field"),(t.checkpoint===void 0||t.checkpoint===null||We(t.checkpoint,e))&&(t.status===void 0||E(t.status))&&(t.last_step===void 0||t.last_step===null||E(t.last_step))&&(t.steps_completed===void 0||P(t.steps_completed,128))}function $t(t){const e=f(t);return e?(D(e,["schemaVersion","ownerStoryId","sessionId","idempotencyKey","acquiredAt","expiresAt","handoffGrant","handoffConsumption"],"git-lifecycle-runtime-lease-unknown-field"),e.schemaVersion===1&&X(e.ownerStoryId)&&E(e.sessionId)&&E(e.idempotencyKey)&&x(e.acquiredAt)&&x(e.expiresAt)&&Date.parse(String(e.expiresAt))>Date.parse(String(e.acquiredAt))&&(e.handoffGrant===void 0||Vt(e.handoffGrant,e))&&(e.handoffConsumption===void 0||Bt(e.handoffConsumption,e))):!1}function Vt(t,e){const i=f(t);return i?(D(i,["schemaVersion","kind","storyId","fromSessionId","tokenDigest","bundleDigest","claimRevision","expiresAt"],"git-lifecycle-runtime-handoff-grant-unknown-field"),i.schemaVersion===1&&i.kind==="direct-yolo-setup-handoff"&&i.storyId===e.ownerStoryId&&i.fromSessionId===e.sessionId&&g(i.tokenDigest)&&g(i.bundleDigest)&&g(i.claimRevision)&&x(i.expiresAt)&&Date.parse(String(i.expiresAt))<=Date.parse(String(e.expiresAt))):!1}function Bt(t,e){const i=f(t);return i?(D(i,["schemaVersion","kind","state","storyId","fromSessionId","tokenDigest","bundleDigest","claimRevision","consumedBySessionId","consumedAt"],"git-lifecycle-runtime-handoff-consumption-unknown-field"),i.schemaVersion===1&&i.kind==="direct-yolo-setup-handoff-consumption"&&i.state==="consumed"&&i.storyId===e.ownerStoryId&&E(i.fromSessionId)&&g(i.tokenDigest)&&g(i.bundleDigest)&&g(i.claimRevision)&&i.consumedBySessionId===e.sessionId&&x(i.consumedAt)):!1}function qt(t){const e=f(t);return e?(D(e,["schemaVersion","originBranch","originHeadSha","executionBranch","capturedFromCurrentCheckout","capturedAt"],"git-lifecycle-runtime-origin-unknown-field"),e.schemaVersion===1&&W(e.originBranch)&&W(e.executionBranch)&&e.originBranch!==e.executionBranch&&w(e.originHeadSha)&&e.capturedFromCurrentCheckout===!0&&x(e.capturedAt)):!1}function Lt(t){const e=f(t);if(!e)return!1;D(e,["schemaVersion","evidenceVersion","producer","contract","command","verdict","executionHeadSha","graphRevision","manifestDigest","resultDigest","checkedAt","receiptRef","gateIds"],"git-lifecycle-runtime-aggregate-qa-unknown-field");const i=e.evidenceVersion==="p205-execution-v2"&&e.producer==="local-yolo-tdd"&&e.contract==="P205-CI-02"&&e.command===O&&g(e.manifestDigest)&&g(e.resultDigest),r=e.evidenceVersion===void 0&&e.producer===void 0&&e.contract===void 0&&e.command===void 0&&e.manifestDigest===void 0&&e.resultDigest===void 0;return e.schemaVersion===1&&(i||r)&&e.verdict==="passed"&&w(e.executionHeadSha)&&g(e.graphRevision)&&x(e.checkedAt)&&fe(e.receiptRef)&&P(e.gateIds,128,!0)}function jt(t){const e=f(t);return e?(D(e,["schemaVersion","epicId","executionBranch","originBranch","baseSha","executionHeadSha","mergeSha","pushedSha","strategy","prNumber","physicalStatus","localGateReceiptRefs","idempotencyKey","attemptStartedAt","completedAt","retryEligible","reasonCodes","publicSafe","candidateQa","providerGuard"],"git-lifecycle-runtime-terminal-receipt-unknown-field"),e.schemaVersion===1&&X(e.epicId)&&W(e.executionBranch)&&W(e.originBranch)&&w(e.baseSha)&&w(e.executionHeadSha)&&(e.mergeSha===void 0||w(e.mergeSha))&&(e.pushedSha===void 0||w(e.pushedSha))&&(e.strategy==="direct"||e.strategy==="single_pr")&&(e.candidateQa===void 0||Ht(e.candidateQa,e))&&(e.providerGuard===void 0||zt(e.providerGuard,e))&&(e.prNumber===void 0||Number.isSafeInteger(e.prNumber)&&Number(e.prNumber)>0)&&["prepared","merged","pushed","denied_external_gate","blocked_local_or_repo"].includes(String(e.physicalStatus))&&P(e.localGateReceiptRefs,128,!0)&&E(e.idempotencyKey)&&x(e.attemptStartedAt)&&(e.completedAt===void 0||x(e.completedAt))&&typeof e.retryEligible=="boolean"&&P(e.reasonCodes,128)&&e.publicSafe===!0):!1}function zt(t,e){const i=f(t);if(!i)return!1;D(i,["schemaVersion","provider","mode","source","prHeadSha","originHeadSha","checkedAt","publicSafe"],"git-lifecycle-runtime-provider-guard-unknown-field");const r=i.mode==="recovered_exact_tree"?i.source==="physical_recovery":i.mode==="strict_up_to_date_expected_head"&&["branch_protection","ruleset","branch_protection_and_ruleset"].includes(String(i.source));return i.schemaVersion===1&&i.provider==="github"&&r&&e.strategy==="single_pr"&&e.physicalStatus==="pushed"&&Number.isSafeInteger(e.prNumber)&&Number(e.prNumber)>0&&w(i.prHeadSha)&&i.prHeadSha===e.mergeSha&&w(i.originHeadSha)&&i.originHeadSha===e.baseSha&&x(i.checkedAt)&&i.publicSafe===!0}function Ht(t,e){const i=f(t);return i?(D(i,["schemaVersion","kind","contract","command","originHeadSha","executionHeadSha","mergeSha","treeSha","graphRevision","manifestDigest","resultDigest","gateIds","checkedAt","receiptRef"],"git-lifecycle-runtime-merge-candidate-unknown-field"),i.schemaVersion===1&&i.kind==="epic_merge_candidate_qa"&&i.contract==="P205-CI-02"&&i.command===O&&w(i.originHeadSha)&&i.originHeadSha===e.baseSha&&w(i.executionHeadSha)&&i.executionHeadSha===e.executionHeadSha&&w(i.mergeSha)&&i.mergeSha===e.mergeSha&&w(i.treeSha)&&g(i.graphRevision)&&g(i.manifestDigest)&&g(i.resultDigest)&&P(i.gateIds,128,!0)&&x(i.checkedAt)&&fe(i.receiptRef)):!1}function We(t,e){const i=f(t);if(!i)return!1;D(i,["schemaVersion","storyId","epicId","branch","baseSha","headSha","commits","idempotencyKey","dispatchId","bundleId","bundleDigest","graphRevision","claimRevision","receiptRefs","qaVerdict","reviewVerdict","qaReceipt","reviewReceipt","recordedAt"],"git-lifecycle-runtime-checkpoint-unknown-field");const r=String(e).split(".")[0];return i.schemaVersion===1&&i.storyId===e&&i.epicId===r&&W(i.branch)&&w(i.baseSha)&&w(i.headSha)&&i.baseSha!==i.headSha&&Mt(i.commits)&&i.commits.length===1&&i.commits[0]===i.headSha&&E(i.idempotencyKey)&&(i.dispatchId===void 0||g(i.dispatchId))&&(i.bundleId===void 0||g(i.bundleId))&&g(i.bundleDigest)&&g(i.graphRevision)&&(i.claimRevision===void 0||g(i.claimRevision))&&P(i.receiptRefs,256,!0)&&(i.qaVerdict==="passed"||i.qaVerdict==="blocked")&&["approved","changes-requested","pending"].includes(String(i.reviewVerdict))&&Tt(i.qaReceipt,i)&&(i.reviewVerdict==="pending"?i.reviewReceipt===void 0:Gt(i.reviewReceipt,i))&&x(i.recordedAt)}function Tt(t,e){const i=f(t);return i?(D(i,["schemaVersion","kind","producer","evidenceVersion","storyId","epicId","baseSha","headSha","bundleDigest","graphRevision","contract","command","manifestDigest","gateIds","resultDigest","sourceEvidenceDigest","verdict","checkedAt","receiptRef"],"git-lifecycle-runtime-story-qa-unknown-field"),i.schemaVersion===1&&i.kind==="story_qa_evidence"&&i.producer==="local-yolo-tdd"&&(i.evidenceVersion===void 0||i.evidenceVersion==="git-immutable-v1"||i.evidenceVersion==="p205-execution-v2"&&i.contract==="P205-CI-02"&&i.command===O&&g(i.manifestDigest)&&P(i.gateIds,32,!0)&&g(i.resultDigest))&&Ye(i,e)&&g(i.sourceEvidenceDigest)&&i.verdict===e.qaVerdict&&(i.verdict==="passed"||i.verdict==="blocked")&&x(i.checkedAt)&&fe(i.receiptRef)&&e.receiptRefs.includes(i.receiptRef)):!1}function Gt(t,e){const i=f(t),r=f(e.qaReceipt);return!i||!r?!1:(D(i,["schemaVersion","kind","producer","storyId","epicId","baseSha","headSha","bundleDigest","graphRevision","sourceEvidenceDigest","qaReceiptRef","verdict","reviewedAt","receiptRef"],"git-lifecycle-runtime-story-review-unknown-field"),i.schemaVersion===1&&i.kind==="story_review_evidence"&&i.producer==="root-commit-range-review"&&Ye(i,e)&&g(i.sourceEvidenceDigest)&&i.qaReceiptRef===r.receiptRef&&i.receiptRef!==r.receiptRef&&(i.verdict==="approved"||i.verdict==="changes-requested")&&(i.verdict==="approved"?e.reviewVerdict==="approved":e.reviewVerdict==="changes-requested")&&x(i.reviewedAt)&&Date.parse(String(i.reviewedAt))>=Date.parse(String(r.checkedAt))&&fe(i.receiptRef)&&e.receiptRefs.includes(i.receiptRef))}function Ye(t,e){return["storyId","epicId","baseSha","headSha","bundleDigest","graphRevision"].every(i=>t[i]===e[i])}function Ft(t){return!Array.isArray(t)||t.length>1024?!1:t.every(e=>{const i=f(e);return i?(D(i,["schemaVersion","resourceId","action","outcome","idempotencyKey","reasonCodes","recordedAt","publicSafe"],"git-lifecycle-runtime-reconciliation-receipt-unknown-field"),i.schemaVersion===1&&E(i.resourceId)&&["no_op","delete_local_branch","delete_remote_branch","close_pull_request"].includes(String(i.action))&&["applied","already_absent","dry_run","failed"].includes(String(i.outcome))&&E(i.idempotencyKey)&&P(i.reasonCodes,128)&&x(i.recordedAt)&&i.publicSafe===!0):!1})}function Kt(t){return!Array.isArray(t)||t.length>1024?!1:t.every(e=>{const i=f(e);return i?(D(i,["schemaVersion","resourceId","action","managed","reasonCodes","evidence","publicSafe"],"git-lifecycle-runtime-reconciliation-debt-unknown-field"),i.schemaVersion===1&&E(i.resourceId)&&i.action==="preserve"&&typeof i.managed=="boolean"&&P(i.reasonCodes,128)&&P(i.evidence,16)&&i.publicSafe===!0):!1})}function D(t,e,i){const r=new Set(e);if(Object.keys(t).some(n=>!r.has(n)))throw new Error(i)}function X(t){return typeof t=="string"&&/^P[1-9][0-9]*(?:\.[0-9]+)*$/.test(t)}function W(t){return typeof t=="string"&&/^[A-Za-z0-9][A-Za-z0-9._/-]{0,239}$/.test(t)&&!t.includes("..")&&!t.includes("//")&&!t.includes("@{")&&!t.endsWith("/")&&!t.endsWith(".")&&!t.split("/").some(e=>!e||e.startsWith(".")||e.endsWith(".lock"))}function de(t){return t.length>0&&t.length<=1024&&!ee(t)&&!t.includes("\0")&&!t.replaceAll("\\","/").split("/").includes("..")}function E(t){return typeof t=="string"&&t.length>0&&t.length<=240&&/^[A-Za-z0-9._:/#\-[\]]+$/.test(t)&&!t.includes("..")}function fe(t){return E(t)}function w(t){return typeof t=="string"&&/^[a-f0-9]{40,64}$/i.test(t)}function g(t){return typeof t=="string"&&/^[a-f0-9]{64}$/i.test(t)}function x(t){return typeof t=="string"&&t.length<=64&&Number.isFinite(Date.parse(t))}function P(t,e,i=!1){return Array.isArray(t)&&t.length<=e&&(!i||t.length>0)&&t.every(E)}function Mt(t){return Array.isArray(t)&&t.length>0&&t.length<=256&&t.every(w)}function Re(){return{schemaVersion:1,revision:0,epics:{},stories:{}}}async function Wt(t){const e=z(t),i={pid:process.pid,nonce:ye(16).toString("hex")},r=async()=>{await H(e),await Pe(e,R(t),JSON.stringify(i));try{await b(t,e),await T(p(t,"owner.json"),t)}catch(n){throw await M(t,e).catch(()=>{}),n}};try{await r()}catch(n){if(!_(n,"EEXIST"))throw n;await L(t,"directory");const a=await Ee(t);if(a!==void 0&&ue(a.pid))throw new Error("git-lifecycle-runtime-lock-active");if(a===void 0&&await Je(t))throw new Error("git-lifecycle-runtime-lock-active");const o=await I(t);if(!o)throw new Error("git-lifecycle-runtime-lock-owner-invalid");const s=`${t}.stale.${process.pid}.${Date.now()}`;await Q(e,R(t),R(s));try{if(await b(s,e),await I(s)!==o)throw await re(s,t,e).catch(()=>{}),new Error("git-lifecycle-runtime-lock-owner-replaced");await r()}finally{await M(s,e,async u=>await I(u)===o).catch(()=>{})}}return i}async function Yt(t,e){const i=z(t);try{await b(t,i);const r=await Ee(t);if(!r||!Qe(r,e))return!1;const n=await I(t);if(!n)return!1;const a=`${t}.release.${process.pid}.${Date.now()}`;await Q(i,R(t),R(a)),await b(a,i);const o=await Ee(a);return!o||!Qe(o,e)||await I(a)!==n?(await re(a,t,i).catch(()=>{}),!1):M(a,i,async s=>await I(s)===n)}catch(r){if(_(r,"ENOENT"))return!1;throw r}}async function Je(t){try{return Date.now()-(await rt(t)).mtimeMs<3e4}catch{return!0}}async function Ee(t){try{await b(t,z(t));const e=p(t,"owner.json");await T(e,t);const i=JSON.parse(await F(e,"utf8"));return Number.isSafeInteger(i.pid)&&Number(i.pid)>0&&(i.nonce===void 0||typeof i.nonce=="string"&&/^[a-f0-9]{32}$/.test(i.nonce))?{pid:Number(i.pid),...typeof i.nonce=="string"?{nonce:i.nonce}:{}}:void 0}catch{return}}function Qe(t,e){return t.pid===e.pid&&t.nonce!==void 0&&t.nonce===e.nonce}function ue(t){try{return process.kill(t,0),!0}catch(e){return _(e,"EPERM")}}function f(t){return t&&typeof t=="object"&&!Array.isArray(t)?t:void 0}function _(t,e){return t instanceof Error&&"code"in t&&t.code===e}export{ce as GIT_LIFECYCLE_RUNTIME_DIRECTORY,oe as GIT_LIFECYCLE_RUNTIME_FILE,Ve as LEGACY_DIRECT_YOLO_RECOVERY_COMMITS,ft as LEGACY_P174_CHECKPOINT_MIGRATIONS,O as P205_COMPLETE_COMMAND,pi as acquireGitLifecyclePhysicalIntegrationLock,oi as applyGitLifecycleRuntimeOverlay,b as assertGitLifecyclePrivateDirectory,mi as assertGitLifecyclePrivateFile,_t as computeGitLifecyclePhysicalIntegrationLockOwnerDigest,St as computeImmutableStoryQaEvidenceDigest,hi as computeLegacyDirectYoloRecoveryReceiptRef,vt as computeP205StoryQaEvidenceDigest,Rt as ensureGitLifecyclePrivateChildDirectory,si as ensureRuntimeEpic,di as ensureRuntimeStory,ni as executeP205TransientAuthority,He as gitLifecycleRuntimeDirectory,bt as gitLifecycleStoryWriteSet,Le as isAcceptedGitLifecycleStoryCheckpoint,ci as mutateGitLifecycleRuntime,gi as p205TransientAuthorityMatchesAggregate,se as posixSecurityAvailable,ui as projectP205TransientExecutionEvidence,ai as readGitLifecycleRuntime,gt as readGitLifecycleRuntimeSync,Et as releaseGitLifecyclePhysicalIntegrationLock,bi as releaseGitLifecyclePhysicalIntegrationLockForCheckpoint,M as removeGitLifecyclePrivateDirectory,fi as verifyAcceptedGitLifecycleStoryCheckpoint,ht as verifyAcceptedGitLifecycleStoryCheckpointSync,yi as verifyGitLifecyclePhysicalIntegrationLock,li as verifyLegacyCheckpointMigrationCandidateSync};
@@ -0,0 +1,26 @@
1
+ export interface AnchoredFilesystemTestOptions {
2
+ /** Deterministic race hook after identity capture and before cwd handoff. */
3
+ readonly beforeHandoff?: () => Promise<void> | void;
4
+ /** Deterministic observer after the helper owns the validated child cwd. */
5
+ readonly afterHandoff?: () => Promise<void> | void;
6
+ /** Test-only platform seam; production always uses process.platform. */
7
+ readonly platform?: NodeJS.Platform;
8
+ }
9
+ export interface AnchoredDirectoryIdentity {
10
+ readonly dev: string;
11
+ readonly ino: string;
12
+ }
13
+ export declare function secureFilesystemBoundaryAvailable(platform?: NodeJS.Platform): boolean;
14
+ export declare function anchoredAtomicWriteFile(parent: string, name: string, content: Buffer | string, options?: AnchoredFilesystemTestOptions): Promise<void>;
15
+ export declare function anchoredRemoveFile(parent: string, name: string, options?: AnchoredFilesystemTestOptions): Promise<void>;
16
+ export declare function anchoredEnsureDirectory(parent: string, name: string, options?: AnchoredFilesystemTestOptions): Promise<void>;
17
+ export declare function anchoredCreateDirectory(parent: string, name: string): Promise<AnchoredDirectoryIdentity>;
18
+ export declare function anchoredDirectoryIdentity(path: string): Promise<AnchoredDirectoryIdentity>;
19
+ /** Execute Git only after a helper owns and revalidates the sandbox directory cwd. */
20
+ export declare function anchoredExecuteGit(parent: string, name: string, expectedChild: AnchoredDirectoryIdentity, args: readonly string[], input?: Buffer | string, options?: AnchoredFilesystemTestOptions): Promise<Buffer>;
21
+ /** Gate commands inherit a pinned cwd, never a mutable sandbox pathname. */
22
+ export declare function anchoredExecuteNode(parent: string, name: string, expectedChild: AnchoredDirectoryIdentity, args: readonly string[], input?: Buffer | string, options?: AnchoredFilesystemTestOptions): Promise<Buffer>;
23
+ export declare function anchoredExecuteNpm(parent: string, name: string, expectedChild: AnchoredDirectoryIdentity, args: readonly string[]): Promise<Buffer>;
24
+ export declare function anchoredCreateOwnedDirectory(parent: string, name: string, owner: Buffer | string): Promise<void>;
25
+ export declare function anchoredRenameDirectory(parent: string, sourceName: string, destinationName: string, options?: AnchoredFilesystemTestOptions): Promise<void>;
26
+ export declare function anchoredRemoveDirectory(parent: string, name: string, options?: AnchoredFilesystemTestOptions): Promise<void>;