@ornexus/neocortex 4.60.23 → 4.60.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/sbom.cdx.json +23 -23
- package/install.js +67 -10
- package/install.ps1 +39 -8
- package/install.sh +18 -6
- package/package.json +5 -2
- package/packages/client/dist/adapters/adapter-registry.d.ts +2 -2
- package/packages/client/dist/adapters/adapter-registry.js +1 -1
- package/packages/client/dist/adapters/grok-adapter.d.ts +11 -0
- package/packages/client/dist/adapters/grok-adapter.js +2 -0
- package/packages/client/dist/adapters/index.d.ts +1 -0
- package/packages/client/dist/adapters/index.js +1 -1
- package/packages/client/dist/adapters/platform-detector.d.ts +1 -1
- package/packages/client/dist/adapters/platform-detector.js +1 -1
- package/packages/client/dist/agent/refresh-stubs.js +2 -2
- package/packages/client/dist/cli.js +21 -2
- package/packages/client/dist/commands/invoke.d.ts +20 -21
- package/packages/client/dist/commands/invoke.js +59 -55
- package/packages/client/dist/commands/story-checkpoint.d.ts +15 -0
- package/packages/client/dist/commands/story-checkpoint.js +1 -0
- package/packages/client/dist/config.js +1 -1
- package/packages/client/dist/generated/command-registry.generated.d.ts +18 -52
- package/packages/client/dist/generated/command-registry.generated.js +1 -1
- package/packages/client/dist/git/direct-yolo-checkpoint.d.ts +67 -0
- package/packages/client/dist/git/direct-yolo-checkpoint.js +3 -0
- package/packages/client/dist/git/git-lifecycle-step-ids.d.ts +2 -0
- package/packages/client/dist/git/git-lifecycle-step-ids.js +1 -0
- package/packages/client/dist/git/git-lifecycle-store.d.ts +198 -0
- package/packages/client/dist/git/git-lifecycle-store.js +4 -0
- package/packages/client/dist/git/secure-filesystem-boundary.d.ts +26 -0
- package/packages/client/dist/git/secure-filesystem-boundary.js +123 -0
- package/packages/client/dist/graph-retrieval/shared-graph-retrieval-contract.js +1 -1
- package/packages/client/dist/index.d.ts +2 -0
- package/packages/client/dist/index.js +1 -1
- package/packages/client/dist/memory/shared-project-memory-types.d.ts +29 -2
- package/packages/client/dist/memory/shared-project-memory-types.js +2 -2
- package/packages/client/dist/policy/subagent-approval-policy.js +1 -1
- package/packages/client/dist/runner/headless/continuous-story-workspace.d.ts +131 -0
- package/packages/client/dist/runner/headless/continuous-story-workspace.js +58 -0
- package/packages/client/dist/runner/headless/epic-git-reconciliation-inventory.d.ts +23 -0
- package/packages/client/dist/runner/headless/epic-git-reconciliation-inventory.js +1 -0
- package/packages/client/dist/runner/headless/epic-merge-candidate-qa.d.ts +15 -0
- package/packages/client/dist/runner/headless/epic-merge-candidate-qa.js +28 -0
- package/packages/client/dist/runner/headless/epic-terminal-git-cli-adapter.d.ts +12 -0
- package/packages/client/dist/runner/headless/epic-terminal-git-cli-adapter.js +8 -0
- package/packages/client/dist/runner/headless/epic-terminal-git-runner.d.ts +134 -0
- package/packages/client/dist/runner/headless/epic-terminal-git-runner.js +2 -0
- package/packages/client/dist/runner/headless/prepared-story-bundle.js +1 -1
- package/packages/client/dist/runner/headless/run-yolo.js +1 -1
- package/packages/client/dist/runner/headless/run-yoloop.d.ts +7 -2
- package/packages/client/dist/runner/headless/run-yoloop.js +8 -1
- package/packages/client/dist/runner/headless/types.d.ts +1 -1
- package/packages/client/dist/runner/headless/types.js +2 -2
- package/packages/client/dist/runner-cli.js +0 -0
- package/packages/client/dist/state/project-state-snapshot.js +1 -1
- package/packages/client/dist/state/state-json-repair.d.ts +9 -0
- package/packages/client/dist/state/state-json-repair.js +3 -3
- package/packages/client/dist/tier/tier-aware-client.js +1 -1
- package/packages/client/dist/yoloop/invoke-hooks.d.ts +13 -10
- package/packages/client/dist/yoloop/invoke-hooks.js +8 -5
- package/packages/client/dist/yoloop/shared-discover-epics.js +1 -1
- package/packages/shared/dist/generated/command-registry.generated.js +18 -66
- package/packages/shared/dist/generated/invocation-schema.generated.js +5 -25
- package/packages/shared/dist/invocation/index.d.ts +1 -1
- package/packages/shared/dist/yoloop/epic-terminal-git.js +227 -0
- package/packages/shared/dist/yoloop/planning-graph.js +119 -0
- package/packages/shared/dist/yoloop/public-story-write-set.js +27 -0
- package/packages/shared/dist/yoloop/wave-decision-receipt.js +19 -0
- package/targets-stubs/antigravity/gemini.md +1 -1
- package/targets-stubs/antigravity/neocortex.md +18 -0
- package/targets-stubs/antigravity/skill/SKILL.md +1 -1
- package/targets-stubs/claude-code/neocortex-root.agent.yaml +1 -1
- package/targets-stubs/claude-code/neocortex-root.md +21 -2
- package/targets-stubs/claude-code/neocortex.agent.yaml +1 -1
- package/targets-stubs/claude-code/neocortex.md +2 -2
- package/targets-stubs/codex/AGENTS.md +20 -1
- package/targets-stubs/cursor/agent.md +20 -2
- package/targets-stubs/gemini-cli/agent.md +2 -2
- package/targets-stubs/gemini-cli/gemini.md +18 -0
- package/targets-stubs/grok/README.md +13 -0
- package/targets-stubs/grok/SKILL.md +50 -0
- package/targets-stubs/grok/config-mcp.toml +22 -0
- package/targets-stubs/grok/install-grok.sh +31 -0
- package/targets-stubs/kimi/neocortex.md +18 -0
- package/targets-stubs/openclaw/SKILL.md +18 -0
- package/targets-stubs/opencode/neocortex-root.md +20 -1
- 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 we}from"node:child_process";import{createHash as Ie,randomBytes as Re,timingSafeEqual as ve}from"node:crypto";import{readFile as re}from"node:fs/promises";import{join as oe,resolve as Se}from"node:path";import{promisify as ke}from"node:util";import{acquireGitLifecyclePhysicalIntegrationLock as H,applyGitLifecycleRuntimeOverlay as De,computeImmutableStoryQaEvidenceDigest as xe,computeGitLifecyclePhysicalIntegrationLockOwnerDigest as ie,computeP205StoryQaEvidenceDigest as be,computeLegacyDirectYoloRecoveryReceiptRef as Ae,ensureRuntimeEpic as C,ensureRuntimeStory as je,ensureGitLifecyclePrivateChildDirectory as Ee,executeP205TransientAuthority as Le,projectP205TransientExecutionEvidence as _e,LEGACY_DIRECT_YOLO_RECOVERY_COMMITS as Be,mutateGitLifecycleRuntime as O,P205_COMPLETE_COMMAND as $e,readGitLifecycleRuntime as q,gitLifecycleRuntimeDirectory as qe,assertGitLifecyclePrivateFile as ne,releaseGitLifecyclePhysicalIntegrationLock as N,releaseGitLifecyclePhysicalIntegrationLockForCheckpoint as ze,verifyGitLifecyclePhysicalIntegrationLock as F,verifyAcceptedGitLifecycleStoryCheckpoint as se}from"./git-lifecycle-store.js";import{anchoredAtomicWriteFile as Ce}from"./secure-filesystem-boundary.js";import{GIT_LIFECYCLE_COMMIT_PUSH_STEP_ID as Oe,GIT_LIFECYCLE_REVIEW_PR_STEP_ID as ae}from"./git-lifecycle-step-ids.js";const Y=ke(we);async function Xe(e){try{const t=await K(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=W(e.nowIso),n=await q(t.projectRoot,{required:!0}),d=I(n.epics[t.epicId]?.branch_lease);if(!ye(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:Re(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 O(t.projectRoot,w=>{const g=I(C(w,t.epicId).branch_lease);if(!ye(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 F(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 et(e){try{const t=await K(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=W(e.nowIso);let h=e.setupLeaseHandoff??await Pe(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 He(t.projectRoot,e.storyId,h.sessionId,h.token,n,d),await e.setupHandoffFault?.("after-consuming-persisted")),await O(t.projectRoot,u=>{const k=C(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),L=w&&D&&Ge({current:p,handoff:h,storyId:e.storyId,bundleDigest:a,claimRevision:c,nowIso:d});if(h&&w&&!g&&!L)throw new Error("direct-yolo-setup-handoff-invalid");if(w&&!g&&!L)throw new Error("direct-yolo-writer-active");const _=L?I(p?.handoffGrant):void 0,B=_?{schemaVersion:1,kind:"direct-yolo-setup-handoff-consumption",state:"consumed",storyId:e.storyId,fromSessionId:String(p?.sessionId),tokenDigest:String(_.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,...B?{handoffConsumption:B}:{}}},{expectedRevision:R.revision,preCommit:async()=>{if(!await F(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 Ne(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 tt(e){let t,i,r;try{const o=await K(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:"",L=typeof a.graphRevision=="string"?a.graphRevision:"",_=/^[a-f0-9]{40,64}$/.test(D)?$(await E(o.projectRoot,["diff-tree","--no-commit-id","--name-only","-r","-z",D])):[],B=G(_,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(L)||!B.ok)return y("direct-yolo-replay-invalid");const ge=await Q(e,o.projectRoot,s,L);if(!await se(o.projectRoot,a,e.storyId,o.epicId,o.executionBranch,ge.transientAuthority,o.authorizedWriteSet))return y("direct-yolo-replay-invalid");if(!await U(o.projectRoot,o.executionBranch,s,_))return y("direct-yolo-replay-head-raced");if(e.push&&!await fe(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 ze(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=T(d,"Neocortex-Bundle-Digest"),l=T(d,"Neocortex-Graph-Revision"),S=T(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,L])=>T(d,D)!==L))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=W(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 O(o.projectRoot,L=>{const _=C(L,o.epicId),B=I(_.branch_lease);if(B&&Date.parse(String(B.expiresAt))>Date.parse(k))throw new Error("direct-yolo-writer-active");if(_.graph_revision!==o.graphRevision)throw new Error("direct-yolo-graph-revision-raced");_.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 B=V(e.remote??"origin");if(await b(o.projectRoot,["push",B,o.executionBranch]),!await ue(o.projectRoot,B,o.executionBranch,c))return y("direct-yolo-remote-head-mismatch")}const L=await ce({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:W(e.nowIso),legacyReceiptRef:void 0});return await e.beforeCheckpointPersist?.(),await de({projectRoot:o.projectRoot,checkpoint:L,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:L}):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 Ke(t,e.storyId).catch(()=>{})}}async function rt(e){try{const t=await K(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(Be[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=W(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 O(t.projectRoot,w=>{const g=C(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 ce({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 Ae(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 de({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 K(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=Se(e),r=I(JSON.parse(await re(oe(i,".neocortex/state.json"),"utf8"))),o=await q(i,{required:!0}),s=De(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"&&le(A)))].sort():[],S=await b(i,["symbolic-ref","--quiet","--short","HEAD"]);if(!c||d?.branch_mode!=="epic"||!me(h)||!me(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 ce(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=xe({storyId:e.storyId,baseSha:e.baseSha,headSha:e.headSha,bundleDigest:e.bundleDigest,graphRevision:e.graphRevision,commitBody:i,changedPaths:r}),s=be({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 de(e){const{projectRoot:t,checkpoint:i,remote:r}=e;let o=!1;return await O(t,s=>{const f=C(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=je(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=ae;const n=Array.isArray(a.steps_completed)?a.steps_completed.filter(d=>typeof d=="string"):[];a.steps_completed=[...new Set([...n,Oe,ae])],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 F(e.physicalLockPath,e.physicalLockOwner))throw new Error("direct-yolo-integration-lock-raced");if(r&&!(e.remotePolicy==="ancestor-recovery"?await fe(t,r,i.branch,i.headSha):await ue(t,r,i.branch,i.headSha)))throw new Error("direct-yolo-checkpoint-remote-raced")}}),!o}async function fe(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 ye(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 he(e,t){const i=await qe(e),r=await Ee(i,"handoffs"),o=`direct-${v(t)}.json`;return{parent:r,name:o,path:oe(r,o)}}async function M(e,t){const i=await he(e,t.storyId);await Ce(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 he(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 Pe(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 He(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 Ne(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 Ge(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)&&We(t.tokenDigest,r))}function We(e,t){const i=Buffer.from(e,"hex"),r=Buffer.from(t,"hex");return i.length===32&&r.length===32&&ve(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 O(e,r=>{const o=C(r,t),s=I(o.branch_lease);Z(s,i)&&(o.branch_lease=null)})}async function Ke(e,t){const i=await q(e.projectRoot,{required:!0}),r=I(i.epics[e.epicId]?.branch_lease);if(!r||r.ownerStoryId!==t||!pe(r.sessionId)||!pe(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 Le(t,{headSha:i,graphRevision:r,nowIso:e.nowIso});await e.qaRunner?.({projectRoot:t,storyId:e.storyId,headSha:i});const s=_e(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 ue(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=>!le(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 le(e){return e.length>0&&e.length<=1024&&!e.startsWith("/")&&!e.includes("\\")&&!e.split("/").includes("..")&&!e.startsWith(".git/")&&!e.includes("\0")}function pe(e){return typeof e=="string"&&e.length>0&&e.length<=512&&/^[A-Za-z0-9._:@/+\-=]+$/.test(e)}function me(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 T(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 Ie("sha256").update(e).digest("hex")}function $(e){return e.split("\0").filter(Boolean)}function W(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{et as beginDirectYoloStoryCommit,tt as finalizeDirectYoloStoryCheckpoint,Xe as issueDirectYoloSetupLeaseHandoff,rt as recoverLegacyDirectYoloStoryCheckpoint};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function _(e,t,I){return["step",e,t,...I].join("-")}const c=_("c","08",["commit","push"]),E=_("c","11",["review","pr"]);export{c as GIT_LIFECYCLE_COMMIT_PUSH_STEP_ID,E as GIT_LIFECYCLE_REVIEW_PR_STEP_ID};
|
|
@@ -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 X}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 M,stat as rt}from"node:fs/promises";import{existsSync as B,lstatSync as ke,readFileSync as Oe,realpathSync as we}from"node:fs";import{basename as _,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";import{GIT_LIFECYCLE_COMMIT_PUSH_STEP_ID as ft,GIT_LIFECYCLE_REVIEW_PR_STEP_ID as ut}from"./git-lifecycle-step-ids.js";const k=at(tt),ce="neocortex-yoloop",oe="runtime.json",O="node scripts/test-root.mjs --gate complete",Ve=Object.freeze({"P174.03.029264":"339141be7339a0edf55710cbccb6e6558f514792"}),gt=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",lt="runtime.lock",Be=new WeakMap;async function oi(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 k("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 k(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 si(t,e={}){const i=await Et(t);return Me(i,e)}function ht(t,e={}){let i;try{const r=X("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");Ot(o);const s=p(o,ce),u=p(s,oe);if(B(s)&&(Ke(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 _e()}if(!B(i)){if(e.required)throw new Error("git-lifecycle-runtime-missing");return _e()}return Ke(i,"file"),xe(JSON.parse(Oe(i,"utf8")))}async function di(t,e,i={}){const r=await De(t),n=await Fe(r),a=p(n,lt),o=await Jt(a);try{const s=p(n,oe),u=p(r,Se),c=await Me(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 q(n,"directory"),await Ct(s),await ot(n,oe,`${JSON.stringify(l,null,2)}
|
|
2
|
+
`),await q(s,"file"),await mt(n),{document:l,value:S}}finally{await Qt(a,o).catch(()=>{})}}async function mt(t){let e;try{e=await it(t,"r")}catch(i){if(process.platform==="win32"&&(I(i,"EPERM")||I(i,"EISDIR")||I(i,"EINVAL")))return;throw i}try{await e.sync()}finally{await e.close()}}function fi(t,e){const i=structuredClone(t),r=Le(i,"epics"),n=Le(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 Le(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 ui(t,e){return t.epics[e]??(t.epics[e]={})}function gi(t,e){return t.stories[e]??(t.stories[e]={})}function qe(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 li(t,e,i,r,n,a,o=[]){return pt(t,e,i,r,n,a,o).verdict==="verified"}function pt(t,e,i,r,n,a,o=[],s=new Date().toISOString()){const u=()=>_t({storyId:i,epicId:r,executionBranch:n,value:e,verifiedAt:s,verdict:"rejected",reasonCode:"checkpoint-git-physical-invalid"});try{if(!qe(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=L(t,["rev-parse",`refs/heads/${n}`]).trim();X("git",["merge-base","--is-ancestor",l,v],{cwd:t,stdio:"ignore"});const N=L(t,["show","--no-patch","--format=%H%n%P%n%B",l]),G=L(t,["rev-parse",`${l}^`]).trim(),$=L(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 Ce=[...Y].find(et=>et.startsWith("Neocortex-Prepared-Base: "))?.slice(25)??"";if(!/^[a-f0-9]{40,64}$/i.test(Ce))return u();X("git",["merge-base","--is-ancestor",Ce,l],{cwd:t,stdio:"ignore"})}const A=L(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"),C=je({checkpoint:c,storyId:i,epicId:r,executionBranch:n,baseSha:y,headSha:l,commitBodyDigest:le,changedPathsDigest:he,changedPaths:A,authorizedWriteSet:o.length>0?o:wt(t,i)});if(!C||d.receiptRef!==`story-qa:${String(d.sourceEvidenceDigest)}`)return u();const Ie=Dt({storyId:i,baseSha:y,headSha:l,bundleDigest:String(c.bundleDigest),graphRevision:String(c.graphRevision),commitBody:N,changedPaths:A}),Re=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===xt({gitEvidenceDigest:Ie,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===Ie,Ue=d.evidenceVersion===void 0&&C.mode==="legacy-migration"&&C.binding?.qaDigest===d.sourceEvidenceDigest,me=yt(a,v,String(c.graphRevision))&&(Re||C.mode==="legacy-migration"&&(Ze||Ue)),pe=a===void 0&ℜ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}`||C.mode==="legacy-migration"&&C.binding?.reviewDigest!==void 0&&C.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 Xe=m("sha256").update(["checkpoint-p205-transient-v1",i,r,n,y,l,String(c.bundleDigest),le,he,C.mode,C.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:C.mode,effectiveClaimRevision:C.effectiveClaimRevision,sourceEvidenceDigest:Xe,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",...C.mode==="legacy-migration"?["checkpoint-legacy-migration-verified"]:[]]),publicSafe:!0})}catch{return u()}}function yt(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 hi(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 mi(t,e,i){const r=te(t);return!!(r&&r.executionHeadSha===e&&r.graphRevision===i&&r.command===O)}function je(t){const e=gt[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=bt(t.authorizedWriteSet),a=n.length>0&&n.length===t.authorizedWriteSet.length&&t.changedPaths.every(o=>n.some(s=>vt(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 bt(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 wt(t,e){try{const i=JSON.parse(Oe(p(t,".neocortex","state.json"),"utf8")),r=f(i.stories),n=f(r?.[e]),a=ht(t),o=f(a.stories[e]?.checkpoint)??f(n?.checkpoint);return St(e,n,o)}catch{return[]}}function St(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 vt(t,e){return t===e||t.endsWith("/")&&e.startsWith(t)}function pi(t,e,i,r,n,a){try{if(!qe(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=L(t,["rev-parse",`refs/heads/${n}`]).trim();if(X("git",["merge-base","--is-ancestor",c,S],{cwd:t,stdio:"ignore"}),L(t,["rev-parse",`${c}^`]).trim()!==d||L(t,["rev-list","--count",`${d}..${c}`]).trim()!=="1")return!1;const l=L(t,["show","--no-patch","--format=%H%n%P%n%B",c]),y=L(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 Dt(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 xt(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 _t(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 L(t,e){return X("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 yi(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 k("git",["rev-parse",`refs/heads/${e.executionBranch}`],{cwd:t,encoding:"utf8",maxBuffer:1048576})).stdout.trim();if(await k("git",["merge-base","--is-ancestor",e.headSha,r],{cwd:t}),(await k("git",["rev-parse",`${e.headSha}^`],{cwd:t,encoding:"utf8",maxBuffer:1024*1024})).stdout.trim()!==e.baseSha)return;const a=String((await k("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 k("git",["show","--no-patch","--format=%H%n%P%n%B",e.headSha],{cwd:t,encoding:"utf8",maxBuffer:4*1024*1024})).stdout);if(!String((await k("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 k("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 k("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(ft)||!G.includes(ut)||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 Et(t){const e=await De(t),i=p(e,ce),r=p(i,oe);if(B(i)&&(await q(i,"directory"),await M(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 It(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 bi(t,e){await T(t,e)}async function K(t,e,i){const r=h(e),n=h(t);Z(r,n);try{await b(n,r)}catch(o){if(I(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,_(n),_(a)),await b(a,r),i&&!await i(a)?(await re(a,n,r).catch(()=>{}),!1):(await dt(r,_(a)),!0)}async function re(t,e,i){await b(t,i);try{await be(e);return}catch(r){if(!I(r,"ENOENT"))throw r}await Q(i,_(t),_(e)),await b(e,i)}async function R(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 wi(t,e){const i=await He(t),r=await It(i,"leases"),n=p(r,"integration"),a=`${n}.recovery`;if(B(a)){await b(a,r);const c=await Te(a),d=await R(a);if(c===void 0||ue(c))return{ok:!1,reasonCode:"git-lifecycle-integration-backpressure"};if(!d||!await K(a,r,async S=>await R(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,_(n),`${JSON.stringify(s)}
|
|
4
|
+
`),await b(n,r),await T(p(n,"owner.json"),n),!0}catch(c){throw I(c,"EEXIST")||await K(n,r).catch(()=>{}),c}};try{return await u(),{ok:!0,owner:s,path:n}}catch(c){if(!I(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 R(n);if(!l)return{ok:!1,reasonCode:"git-lifecycle-integration-lock-failed"};const y=`${n}.stale.${process.pid}.${Date.now()}`;await Q(r,_(n),_(y));try{if(await b(y,r),await R(y)!==l)return await re(y,n,r).catch(()=>{}),{ok:!1,reasonCode:"git-lifecycle-integration-backpressure"};await u()}finally{await K(y,r,async v=>await R(v)===l).catch(()=>{})}return{ok:!0,owner:s,path:n}}catch(c){return{ok:!1,reasonCode:I(c,"EEXIST")||I(c,"ENOENT")?"git-lifecycle-integration-backpressure":"git-lifecycle-integration-lock-failed"}}}async function Si(t,e){const i=await ne(t);return!!(i&&ve(i,e)&&Date.parse(i.expiresAt)>Date.now())}async function Rt(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 R(t);if(!n)return!1;const a=`${t}.release.${process.pid}.${Date.now()}`;await Q(i,_(t),_(a)),await b(a,i);const o=await ne(a);return!o||!ve(o,e)||await R(a)!==n?(await re(a,t,i).catch(()=>{}),!1):K(a,i,async s=>await R(s)===n)}catch(i){if(I(i,"ENOENT"))return!1;throw i}}function At(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 vi(t,e){if(!U(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||At(a)!==e.ownerDigest?"foreign":await Rt(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"||!U(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 M(t),r=(await k("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 M(n);if(a!==n)throw new Error("git-lifecycle-common-dir-symlink");await kt(a);const s=(await k("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 q(e,"directory"),await M(e)!==e)throw new Error("git-lifecycle-runtime-directory-symlink");return e}async function Me(t,e={}){try{return await q(t,"file"),xe(JSON.parse(await F(t,"utf8")))}catch(i){if(I(i,"ENOENT")){if(e.required)throw new Error("git-lifecycle-runtime-missing");return _e()}throw i}}async function Ct(t){try{await q(t,"file")}catch(e){if(I(e,"ENOENT"))return;throw e}}async function q(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 q(i,"directory"),h(await M(i))!==i)throw new Error("git-lifecycle-directory-substituted");if(e){const r=h(e);if(await q(r,"directory"),h(await M(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 q(i,"file"),h(await M(i))!==i)throw new Error("git-lifecycle-file-substituted")}function Ke(t,e){const i=ke(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 kt(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 Ot(t){const e=ke(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(!U(n)||!$t(a))throw new Error("git-lifecycle-runtime-epic-invalid");for(const[n,a]of Object.entries(r))if(!U(n)||!n.includes(".")||!Vt(a,n))throw new Error("git-lifecycle-runtime-story-invalid");return e}const Pt=["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"],Nt=["checkpoint","status","last_step","steps_completed"];function $t(t){return D(t,Pt,"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||Bt(t.branch_lease))&&(t.origin_binding===void 0||t.origin_binding===null||jt(t.origin_binding))&&(t.graph_revision===void 0||g(t.graph_revision))&&(t.aggregate_qa_receipt===void 0||t.aggregate_qa_receipt===null||zt(t.aggregate_qa_receipt))&&(t.terminal_git_receipt===void 0||t.terminal_git_receipt===null||Ht(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||Kt(t.git_reconciliation_receipts))&&(t.git_reconciliation_debt===void 0||Wt(t.git_reconciliation_debt))}function Vt(t,e){return D(t,Nt,"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 Bt(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&&U(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||Lt(e.handoffGrant,e))&&(e.handoffConsumption===void 0||qt(e.handoffConsumption,e))):!1}function Lt(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 qt(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 jt(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 zt(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 Ht(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&&U(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||Gt(e.candidateQa,e))&&(e.providerGuard===void 0||Tt(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 Tt(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 Gt(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&&Yt(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))&&Ft(i.qaReceipt,i)&&(i.reviewVerdict==="pending"?i.reviewReceipt===void 0:Mt(i.reviewReceipt,i))&&x(i.recordedAt)}function Ft(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 Mt(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 Kt(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 Wt(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 U(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 Yt(t){return Array.isArray(t)&&t.length>0&&t.length<=256&&t.every(w)}function _e(){return{schemaVersion:1,revision:0,epics:{},stories:{}}}async function Jt(t){const e=z(t),i={pid:process.pid,nonce:ye(16).toString("hex")},r=async()=>{await H(e),await Pe(e,_(t),JSON.stringify(i));try{await b(t,e),await T(p(t,"owner.json"),t)}catch(n){throw await K(t,e).catch(()=>{}),n}};try{await r()}catch(n){if(!I(n,"EEXIST"))throw n;await q(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 R(t);if(!o)throw new Error("git-lifecycle-runtime-lock-owner-invalid");const s=`${t}.stale.${process.pid}.${Date.now()}`;await Q(e,_(t),_(s));try{if(await b(s,e),await R(s)!==o)throw await re(s,t,e).catch(()=>{}),new Error("git-lifecycle-runtime-lock-owner-replaced");await r()}finally{await K(s,e,async u=>await R(u)===o).catch(()=>{})}}return i}async function Qt(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 R(t);if(!n)return!1;const a=`${t}.release.${process.pid}.${Date.now()}`;await Q(i,_(t),_(a)),await b(a,i);const o=await Ee(a);return!o||!Qe(o,e)||await R(a)!==n?(await re(a,t,i).catch(()=>{}),!1):K(a,i,async s=>await R(s)===n)}catch(r){if(I(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 I(e,"EPERM")}}function f(t){return t&&typeof t=="object"&&!Array.isArray(t)?t:void 0}function I(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,gt as LEGACY_P174_CHECKPOINT_MIGRATIONS,O as P205_COMPLETE_COMMAND,wi as acquireGitLifecyclePhysicalIntegrationLock,fi as applyGitLifecycleRuntimeOverlay,b as assertGitLifecyclePrivateDirectory,bi as assertGitLifecyclePrivateFile,At as computeGitLifecyclePhysicalIntegrationLockOwnerDigest,Dt as computeImmutableStoryQaEvidenceDigest,yi as computeLegacyDirectYoloRecoveryReceiptRef,xt as computeP205StoryQaEvidenceDigest,It as ensureGitLifecyclePrivateChildDirectory,ui as ensureRuntimeEpic,gi as ensureRuntimeStory,oi as executeP205TransientAuthority,He as gitLifecycleRuntimeDirectory,St as gitLifecycleStoryWriteSet,qe as isAcceptedGitLifecycleStoryCheckpoint,di as mutateGitLifecycleRuntime,mi as p205TransientAuthorityMatchesAggregate,se as posixSecurityAvailable,hi as projectP205TransientExecutionEvidence,si as readGitLifecycleRuntime,ht as readGitLifecycleRuntimeSync,Rt as releaseGitLifecyclePhysicalIntegrationLock,vi as releaseGitLifecyclePhysicalIntegrationLockForCheckpoint,K as removeGitLifecyclePrivateDirectory,li as verifyAcceptedGitLifecycleStoryCheckpoint,pt as verifyAcceptedGitLifecycleStoryCheckpointSync,Si as verifyGitLifecyclePhysicalIntegrationLock,pi 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>;
|