@ornexus/neocortex 4.60.22 → 4.60.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. package/dist/sbom.cdx.json +24 -24
  2. package/install.js +67 -10
  3. package/install.ps1 +39 -8
  4. package/install.sh +18 -6
  5. package/package.json +9 -3
  6. package/packages/client/dist/adapters/adapter-registry.d.ts +2 -2
  7. package/packages/client/dist/adapters/adapter-registry.js +1 -1
  8. package/packages/client/dist/adapters/grok-adapter.d.ts +11 -0
  9. package/packages/client/dist/adapters/grok-adapter.js +2 -0
  10. package/packages/client/dist/adapters/index.d.ts +1 -0
  11. package/packages/client/dist/adapters/index.js +1 -1
  12. package/packages/client/dist/adapters/platform-detector.d.ts +1 -1
  13. package/packages/client/dist/adapters/platform-detector.js +1 -1
  14. package/packages/client/dist/agent/refresh-stubs.js +2 -2
  15. package/packages/client/dist/cli.js +21 -2
  16. package/packages/client/dist/commands/invoke.d.ts +39 -26
  17. package/packages/client/dist/commands/invoke.js +56 -50
  18. package/packages/client/dist/commands/story-checkpoint.d.ts +15 -0
  19. package/packages/client/dist/commands/story-checkpoint.js +1 -0
  20. package/packages/client/dist/config.js +1 -1
  21. package/packages/client/dist/continuity/invoke-hooks.js +1 -1
  22. package/packages/client/dist/fs/atomic-state-replace.d.ts +16 -0
  23. package/packages/client/dist/fs/atomic-state-replace.js +1 -0
  24. package/packages/client/dist/generated/command-registry.generated.d.ts +51 -51
  25. package/packages/client/dist/generated/command-registry.generated.js +1 -1
  26. package/packages/client/dist/git/direct-yolo-checkpoint.d.ts +67 -0
  27. package/packages/client/dist/git/direct-yolo-checkpoint.js +3 -0
  28. package/packages/client/dist/git/git-lifecycle-store.d.ts +198 -0
  29. package/packages/client/dist/git/git-lifecycle-store.js +4 -0
  30. package/packages/client/dist/git/secure-filesystem-boundary.d.ts +26 -0
  31. package/packages/client/dist/git/secure-filesystem-boundary.js +123 -0
  32. package/packages/client/dist/graph-retrieval/pre-command-hook.d.ts +11 -0
  33. package/packages/client/dist/graph-retrieval/pre-command-hook.js +1 -1
  34. package/packages/client/dist/graph-retrieval/shared-graph-retrieval-contract.js +1 -1
  35. package/packages/client/dist/index.d.ts +2 -0
  36. package/packages/client/dist/index.js +1 -1
  37. package/packages/client/dist/invocation/invoke-input.d.ts +9 -0
  38. package/packages/client/dist/invocation/invoke-input.js +1 -0
  39. package/packages/client/dist/memory/shared-project-memory-types.d.ts +29 -2
  40. package/packages/client/dist/memory/shared-project-memory-types.js +2 -2
  41. package/packages/client/dist/migrations/project-identity-capability.d.ts +13 -0
  42. package/packages/client/dist/migrations/project-identity-capability.js +1 -0
  43. package/packages/client/dist/migrations/project-identity.d.ts +41 -0
  44. package/packages/client/dist/migrations/project-identity.js +7 -0
  45. package/packages/client/dist/policy/subagent-approval-policy.js +1 -1
  46. package/packages/client/dist/runner/headless/continuous-story-workspace.d.ts +131 -0
  47. package/packages/client/dist/runner/headless/continuous-story-workspace.js +58 -0
  48. package/packages/client/dist/runner/headless/epic-git-reconciliation-inventory.d.ts +23 -0
  49. package/packages/client/dist/runner/headless/epic-git-reconciliation-inventory.js +1 -0
  50. package/packages/client/dist/runner/headless/epic-merge-candidate-qa.d.ts +15 -0
  51. package/packages/client/dist/runner/headless/epic-merge-candidate-qa.js +28 -0
  52. package/packages/client/dist/runner/headless/epic-terminal-git-cli-adapter.d.ts +12 -0
  53. package/packages/client/dist/runner/headless/epic-terminal-git-cli-adapter.js +8 -0
  54. package/packages/client/dist/runner/headless/epic-terminal-git-runner.d.ts +134 -0
  55. package/packages/client/dist/runner/headless/epic-terminal-git-runner.js +2 -0
  56. package/packages/client/dist/runner/headless/prepared-story-bundle.js +1 -1
  57. package/packages/client/dist/runner/headless/run-yolo.js +1 -1
  58. package/packages/client/dist/runner/headless/run-yoloop.d.ts +7 -2
  59. package/packages/client/dist/runner/headless/run-yoloop.js +8 -1
  60. package/packages/client/dist/runner/headless/types.d.ts +1 -1
  61. package/packages/client/dist/runner/headless/types.js +2 -2
  62. package/packages/client/dist/state/invocation-shape.d.ts +9 -0
  63. package/packages/client/dist/state/invocation-shape.js +1 -0
  64. package/packages/client/dist/state/project-state-snapshot.d.ts +9 -3
  65. package/packages/client/dist/state/project-state-snapshot.js +1 -1
  66. package/packages/client/dist/state/state-json-repair.d.ts +9 -0
  67. package/packages/client/dist/state/state-json-repair.js +3 -3
  68. package/packages/client/dist/state/structural-dag-projection.d.ts +24 -0
  69. package/packages/client/dist/state/structural-dag-projection.js +1 -0
  70. package/packages/client/dist/tier/tier-aware-client.js +1 -1
  71. package/packages/client/dist/yoloop/invoke-hooks.d.ts +13 -10
  72. package/packages/client/dist/yoloop/invoke-hooks.js +8 -5
  73. package/packages/client/dist/yoloop/shared-discover-epics.js +1 -1
  74. package/packages/shared/dist/generated/command-registry.generated.js +64 -65
  75. package/packages/shared/dist/generated/invocation-schema.generated.js +16 -24
  76. package/packages/shared/dist/invocation/index.d.ts +6 -2
  77. package/packages/shared/dist/invocation/index.js +5 -0
  78. package/packages/shared/dist/invocation/input-envelope.d.ts +37 -0
  79. package/packages/shared/dist/invocation/input-envelope.js +98 -0
  80. package/packages/shared/dist/invocation/project-identity-migration.d.ts +28 -0
  81. package/packages/shared/dist/invocation/project-identity-migration.js +83 -0
  82. package/packages/shared/dist/invocation/public-diagnostics.d.ts +87 -0
  83. package/packages/shared/dist/invocation/public-diagnostics.js +181 -0
  84. package/packages/shared/dist/invocation/state-projection.d.ts +21 -0
  85. package/packages/shared/dist/invocation/state-projection.js +1 -0
  86. package/packages/shared/dist/invocation/strict-effect-receipt.d.ts +12 -0
  87. package/packages/shared/dist/invocation/strict-effect-receipt.js +43 -0
  88. package/packages/shared/dist/yoloop/epic-terminal-git.js +227 -0
  89. package/packages/shared/dist/yoloop/planning-graph.js +119 -0
  90. package/packages/shared/dist/yoloop/public-story-write-set.js +27 -0
  91. package/packages/shared/dist/yoloop/wave-decision-receipt.js +19 -0
  92. package/targets-stubs/antigravity/gemini.md +1 -1
  93. package/targets-stubs/antigravity/neocortex.md +18 -0
  94. package/targets-stubs/antigravity/skill/SKILL.md +1 -1
  95. package/targets-stubs/claude-code/neocortex-root.agent.yaml +1 -1
  96. package/targets-stubs/claude-code/neocortex-root.md +21 -2
  97. package/targets-stubs/claude-code/neocortex.agent.yaml +1 -1
  98. package/targets-stubs/claude-code/neocortex.md +2 -2
  99. package/targets-stubs/codex/AGENTS.md +20 -1
  100. package/targets-stubs/cursor/agent.md +20 -2
  101. package/targets-stubs/gemini-cli/agent.md +2 -2
  102. package/targets-stubs/gemini-cli/gemini.md +18 -0
  103. package/targets-stubs/grok/README.md +13 -0
  104. package/targets-stubs/grok/SKILL.md +50 -0
  105. package/targets-stubs/grok/config-mcp.toml +22 -0
  106. package/targets-stubs/grok/install-grok.sh +31 -0
  107. package/targets-stubs/kimi/neocortex.md +18 -0
  108. package/targets-stubs/openclaw/SKILL.md +18 -0
  109. package/targets-stubs/opencode/neocortex-root.md +20 -1
  110. package/targets-stubs/vscode/neocortex.agent.md +20 -2
@@ -0,0 +1,198 @@
1
+ import { type AnchoredDirectoryIdentity } from './secure-filesystem-boundary.js';
2
+ export declare const GIT_LIFECYCLE_RUNTIME_DIRECTORY = "neocortex-yoloop";
3
+ export declare const GIT_LIFECYCLE_RUNTIME_FILE = "runtime.json";
4
+ export declare const P205_COMPLETE_COMMAND: "node scripts/test-root.mjs --gate complete";
5
+ export declare const LEGACY_DIRECT_YOLO_RECOVERY_COMMITS: Readonly<Record<string, string>>;
6
+ interface LegacyCheckpointMigrationBinding {
7
+ readonly baseSha: string;
8
+ readonly headSha: string;
9
+ readonly graphRevision: string;
10
+ readonly effectiveClaimRevision: string;
11
+ readonly commitBodyDigest: string;
12
+ readonly changedPathsDigest: string;
13
+ readonly qaDigest: string;
14
+ readonly reviewDigest: string;
15
+ }
16
+ /**
17
+ * Exact immutable bindings for the seven P174 checkpoints predating P205-v2.
18
+ * This table is only an allowlist: every value is recomputed from Git and the
19
+ * independent QA/review receipts before a fresh aggregate P205 may migrate it.
20
+ */
21
+ export declare const LEGACY_P174_CHECKPOINT_MIGRATIONS: Readonly<Record<string, Readonly<LegacyCheckpointMigrationBinding>>>;
22
+ export interface GitLifecycleRuntimeDocument {
23
+ readonly schemaVersion: 1;
24
+ readonly revision: number;
25
+ readonly epics: Record<string, Record<string, unknown>>;
26
+ readonly stories: Record<string, Record<string, unknown>>;
27
+ }
28
+ export interface GitLifecycleMutationResult<T> {
29
+ readonly document: GitLifecycleRuntimeDocument;
30
+ readonly value: T;
31
+ }
32
+ export interface GitLifecycleMutationOptions {
33
+ /** Optional compare-and-swap guard for callers resuming a prior projection. */
34
+ readonly expectedRevision?: number;
35
+ /** Final async physical guard executed while the lifecycle lock is held. */
36
+ readonly preCommit?: (document: GitLifecycleRuntimeDocument) => Promise<void>;
37
+ }
38
+ export interface GitLifecycleReadOptions {
39
+ /** Epic-aware calls require the initialized sidecar; projectless calls opt out explicitly. */
40
+ readonly required?: boolean;
41
+ }
42
+ export interface GitLifecycleCheckpointVerification {
43
+ readonly schemaVersion: 1;
44
+ readonly kind: 'story_checkpoint_physical_verification';
45
+ readonly producer: 'client-p205-transient-v1';
46
+ readonly storyId: string;
47
+ readonly epicId: string;
48
+ readonly branch: string;
49
+ readonly baseSha: string;
50
+ readonly headSha: string;
51
+ readonly aggregateHeadSha: string;
52
+ readonly commitBodyDigest: string;
53
+ readonly changedPathsDigest: string;
54
+ readonly claimVerification: 'canonical' | 'legacy-migration';
55
+ readonly effectiveClaimRevision: string;
56
+ readonly command: typeof P205_COMPLETE_COMMAND;
57
+ readonly manifestDigest: string;
58
+ readonly gateIds: readonly string[];
59
+ readonly resultDigest: string;
60
+ readonly graphRevision: string;
61
+ readonly executionEvidenceDigest: string;
62
+ readonly sourceEvidenceDigest: string;
63
+ readonly verifiedAt: string;
64
+ readonly verdict: 'verified' | 'rejected';
65
+ readonly reasonCodes: readonly string[];
66
+ readonly publicSafe: true;
67
+ }
68
+ /**
69
+ * Process-local authority created only by a successful canonical P205 run.
70
+ * Its runtime object has no enumerable payload. Bindings live only in a private
71
+ * WeakMap so JSON, object spread and structural mocks cannot recreate authority.
72
+ */
73
+ export interface P205TransientExecutionAuthority {
74
+ readonly __p205OpaqueAuthority: never;
75
+ }
76
+ export declare function executeP205TransientAuthority(projectRoot: string, input: {
77
+ readonly headSha: string;
78
+ readonly graphRevision: string;
79
+ readonly nowIso?: string;
80
+ /** Internal detached QA sandbox; no replaceable command/executor seam. */
81
+ readonly anchoredWorkspace?: {
82
+ readonly parent: string;
83
+ readonly name: string;
84
+ readonly identity: AnchoredDirectoryIdentity;
85
+ };
86
+ }): Promise<P205TransientExecutionAuthority>;
87
+ export declare function readGitLifecycleRuntime(projectRoot: string, options?: GitLifecycleReadOptions): Promise<GitLifecycleRuntimeDocument>;
88
+ export declare function readGitLifecycleRuntimeSync(projectRoot: string, options?: GitLifecycleReadOptions): GitLifecycleRuntimeDocument;
89
+ export declare function mutateGitLifecycleRuntime<T>(projectRoot: string, mutate: (document: GitLifecycleRuntimeDocument) => T, options?: GitLifecycleMutationOptions): Promise<GitLifecycleMutationResult<T>>;
90
+ /** Merge the runtime overlay over tracked state without mutating either input. */
91
+ export declare function applyGitLifecycleRuntimeOverlay(tracked: Record<string, unknown>, runtime: GitLifecycleRuntimeDocument): Record<string, unknown>;
92
+ export declare function ensureRuntimeEpic(document: GitLifecycleRuntimeDocument, epicId: string): Record<string, unknown>;
93
+ export declare function ensureRuntimeStory(document: GitLifecycleRuntimeDocument, storyId: string): Record<string, unknown>;
94
+ /** Runtime-safe accepted-checkpoint predicate kept in the published client closure. */
95
+ export declare function isAcceptedGitLifecycleStoryCheckpoint(value: unknown, storyId: string, epicId: string, executionBranch: string): boolean;
96
+ /**
97
+ * Structural JSON is untrusted under a same-UID threat model. Recompute the
98
+ * commit-range/review authority from Git before a checkpoint can authorize
99
+ * aggregate QA or terminal integration.
100
+ */
101
+ export declare function verifyAcceptedGitLifecycleStoryCheckpoint(projectRoot: string, value: unknown, storyId: string, epicId: string, executionBranch: string, transientAuthority?: P205TransientExecutionAuthority | null, authorizedWriteSet?: readonly string[]): Promise<boolean>;
102
+ /**
103
+ * Synchronous variant used at the state-snapshot boundary, before any runtime
104
+ * overlay is sent to the server. It returns a fresh, public, Git-derived receipt.
105
+ */
106
+ export declare function verifyAcceptedGitLifecycleStoryCheckpointSync(projectRoot: string, value: unknown, storyId: string, epicId: string, executionBranch: string, transientAuthority?: P205TransientExecutionAuthority | null, authorizedWriteSet?: readonly string[], nowIso?: string): GitLifecycleCheckpointVerification;
107
+ /** Read-only projection for persistence/audit; it never recreates authority. */
108
+ export declare function projectP205TransientExecutionEvidence(authority: P205TransientExecutionAuthority | null | undefined): Readonly<{
109
+ readonly executionHeadSha: string;
110
+ readonly graphRevision: string;
111
+ readonly manifestDigest: string;
112
+ readonly gateIds: readonly string[];
113
+ readonly resultDigest: string;
114
+ readonly executedAt: string;
115
+ readonly executionEvidenceDigest: string;
116
+ }> | undefined;
117
+ export declare function p205TransientAuthorityMatchesAggregate(authority: P205TransientExecutionAuthority | null | undefined, headSha: string, graphRevision: string): boolean;
118
+ /** Reconstruct the same closed claim used by the direct or continuous planner. */
119
+ export declare function gitLifecycleStoryWriteSet(storyId: string, story: Record<string, unknown> | undefined, checkpoint: Record<string, unknown> | undefined): readonly string[];
120
+ /** Pre-P205 admission for only the exact seven immutable P174 migrations. */
121
+ export declare function verifyLegacyCheckpointMigrationCandidateSync(projectRoot: string, value: unknown, storyId: string, epicId: string, executionBranch: string, authorizedWriteSet: readonly string[]): boolean;
122
+ export declare function computeImmutableStoryQaEvidenceDigest(input: {
123
+ readonly storyId: string;
124
+ readonly baseSha: string;
125
+ readonly headSha: string;
126
+ readonly bundleDigest: string;
127
+ readonly graphRevision: string;
128
+ readonly commitBody: string;
129
+ readonly changedPaths: readonly string[];
130
+ }): string;
131
+ /** Bind an actual successful P205 execution to immutable Git authority. */
132
+ export declare function computeP205StoryQaEvidenceDigest(input: {
133
+ readonly gitEvidenceDigest: string;
134
+ readonly headSha: string;
135
+ readonly graphRevision: string;
136
+ readonly manifestDigest: string;
137
+ readonly gateIds: readonly string[];
138
+ readonly resultDigest: string;
139
+ }): string;
140
+ /**
141
+ * Bounded migration evidence for direct-*yolo commits created before canonical
142
+ * trailers were mandatory. The receipt is derived only from immutable commit
143
+ * data and story-owned evidence blobs; JSON sidecar shape alone is never enough.
144
+ */
145
+ export declare function computeLegacyDirectYoloRecoveryReceiptRef(projectRoot: string, input: {
146
+ readonly storyId: string;
147
+ readonly epicId: string;
148
+ readonly executionBranch: string;
149
+ readonly baseSha: string;
150
+ readonly headSha: string;
151
+ readonly bundleDigest: string;
152
+ readonly graphRevision: string;
153
+ }): Promise<string | undefined>;
154
+ /** Resolve/create the private root used by lifecycle state, locks and sandboxes. */
155
+ export declare function gitLifecycleRuntimeDirectory(projectRoot: string): Promise<string>;
156
+ /** Create or validate one private direct child without following substitutions. */
157
+ export declare function ensureGitLifecyclePrivateChildDirectory(parent: string, childName: string): Promise<string>;
158
+ /** Validate a private directory and every direct parent binding before use. */
159
+ export declare function assertGitLifecyclePrivateDirectory(path: string, parent: string): Promise<void>;
160
+ export declare function assertGitLifecyclePrivateFile(path: string, parent: string): Promise<void>;
161
+ /** Remove only the validated directory object renamed inside its validated parent. */
162
+ export declare function removeGitLifecyclePrivateDirectory(path: string, parent: string, verifyRenamed?: (quarantinePath: string) => Promise<boolean>): Promise<boolean>;
163
+ export interface GitLifecyclePhysicalIntegrationLockOwner {
164
+ readonly schemaVersion: 1;
165
+ readonly kind: 'direct' | 'continuous';
166
+ readonly storyId: string;
167
+ readonly sessionId: string;
168
+ readonly idempotencyKey: string;
169
+ readonly pid: number;
170
+ readonly createdAt: string;
171
+ readonly expiresAt: string;
172
+ readonly persistent: boolean;
173
+ readonly ownerNonce: string;
174
+ }
175
+ export type GitLifecyclePhysicalIntegrationLockResult = {
176
+ readonly ok: true;
177
+ readonly owner: GitLifecyclePhysicalIntegrationLockOwner;
178
+ readonly path: string;
179
+ } | {
180
+ readonly ok: false;
181
+ readonly reasonCode: 'git-lifecycle-integration-backpressure' | 'git-lifecycle-integration-lock-failed';
182
+ };
183
+ /** One physical writer lock shared by direct `*yolo` and continuous DAG integration. */
184
+ export declare function acquireGitLifecyclePhysicalIntegrationLock(projectRoot: string, requested: Omit<GitLifecyclePhysicalIntegrationLockOwner, 'schemaVersion' | 'pid' | 'createdAt' | 'ownerNonce'> & {
185
+ readonly createdAt?: string;
186
+ readonly ownerNonce?: string;
187
+ }): Promise<GitLifecyclePhysicalIntegrationLockResult>;
188
+ export declare function verifyGitLifecyclePhysicalIntegrationLock(path: string, expected: GitLifecyclePhysicalIntegrationLockOwner): Promise<boolean>;
189
+ export declare function releaseGitLifecyclePhysicalIntegrationLock(path: string, expected: GitLifecyclePhysicalIntegrationLockOwner): Promise<boolean>;
190
+ export declare function computeGitLifecyclePhysicalIntegrationLockOwnerDigest(owner: GitLifecyclePhysicalIntegrationLockOwner): string;
191
+ /** Recover only the exact persistent lock whose digest was bound to a checkpoint. */
192
+ export declare function releaseGitLifecyclePhysicalIntegrationLockForCheckpoint(projectRoot: string, input: {
193
+ readonly storyId: string;
194
+ readonly idempotencyKey: string;
195
+ readonly ownerDigest: string;
196
+ }): Promise<'absent' | 'released' | 'foreign'>;
197
+ export declare function posixSecurityAvailable(platform?: NodeJS.Platform): boolean;
198
+ export {};
@@ -0,0 +1,4 @@
1
+ import{execFile as tt,execFileSync as U}from"node:child_process";import{createHash as m,randomBytes as ye}from"node:crypto";import{lstat as be,open as it,readFile as F,realpath as K,stat as rt}from"node:fs/promises";import{existsSync as B,lstatSync as Ce,readFileSync as Oe,realpathSync as we}from"node:fs";import{basename as R,dirname as z,isAbsolute as ee,join as p,relative as nt,resolve as h}from"node:path";import{promisify as at}from"node:util";import{publicWriteSet as ct}from"../../../shared/dist/yoloop/public-story-write-set.js";import{anchoredAtomicWriteFile as ot,anchoredCreateOwnedDirectory as Pe,anchoredEnsureDirectory as Ne,anchoredExecuteGit as st,anchoredExecuteNode as $e,anchoredRemoveDirectory as dt,anchoredRenameDirectory as Q}from"./secure-filesystem-boundary.js";const C=at(tt),ce="neocortex-yoloop",oe="runtime.json",O="node scripts/test-root.mjs --gate complete",Ve=Object.freeze({"P174.03.029264":"339141be7339a0edf55710cbccb6e6558f514792"}),ft=Object.freeze({"P174.03.811759":Object.freeze({baseSha:"749c8fc732deaf26c81a8e08cc94b83c8cf0f5ba",headSha:"84162456d9cbe5000ffd0ed3eb3d0e88cfeba499",graphRevision:"60b343b4b810e6d5abc3159275012b9ab9ab517f9d780e7550fa5b49be740445",effectiveClaimRevision:"11f54704f5007f6139159419cfd7781f908b1502e117365c6d84011384579ed2",commitBodyDigest:"b4fc759a49765fd8c0b3d0f5d1c333c2a4bf28d324e83eedabb12f9530df3738",changedPathsDigest:"11f54704f5007f6139159419cfd7781f908b1502e117365c6d84011384579ed2",qaDigest:"f1100775e21f5d0d990f77303a2a06d936908f016983e32a63316d81aee6b9fc",reviewDigest:"50400bbcddb6f02408837cf99077de5d3af8c84822ab23a8b5499c338af7103a"}),"P174.03.685003":Object.freeze({baseSha:"84162456d9cbe5000ffd0ed3eb3d0e88cfeba499",headSha:"272a7fee89e4b9324d35701df1c83b671fa96299",graphRevision:"60b343b4b810e6d5abc3159275012b9ab9ab517f9d780e7550fa5b49be740445",effectiveClaimRevision:"6cc3c9033f1c4711dcbe3c676d1d7f9906614c7d6e95228e843d1c63cefbc641",commitBodyDigest:"e97966e26ce3ba31d5951b9fdac67808c88c1fd8be7ec1e73982f3f1cc7ffd81",changedPathsDigest:"6cc3c9033f1c4711dcbe3c676d1d7f9906614c7d6e95228e843d1c63cefbc641",qaDigest:"7439329a93321f39fb6b0de0a41c22e58373a399f9048e362dff4ffa6f1a7d89",reviewDigest:"1b2d12262e84acf9da7d06149a0effb11274ebdc986affbfd47635b855ec7135"}),"P174.03.029264":Object.freeze({baseSha:"272a7fee89e4b9324d35701df1c83b671fa96299",headSha:"339141be7339a0edf55710cbccb6e6558f514792",graphRevision:"60b343b4b810e6d5abc3159275012b9ab9ab517f9d780e7550fa5b49be740445",effectiveClaimRevision:"1053bb2baf487e38fa28d7e8cfb872c5c4da66802534ee226bbc2c7455a6a5ab",commitBodyDigest:"0f269a00dcd168a6f548ff10dfa667b193c948ac9c7211f5cb11a0561757c371",changedPathsDigest:"1053bb2baf487e38fa28d7e8cfb872c5c4da66802534ee226bbc2c7455a6a5ab",qaDigest:"ef0fd2c6e216557825cd8521ccb2f9960a3af48f18e7a5ada441bee8bfda400b",reviewDigest:"372d0f4a2f32978c8b39f20167637b3917187edb75d49875e93200c4c5a19d0d"}),"P174.03.913359":Object.freeze({baseSha:"339141be7339a0edf55710cbccb6e6558f514792",headSha:"4ccc90b85c49b27f718090bf25bc452f1b84e5e3",graphRevision:"60b343b4b810e6d5abc3159275012b9ab9ab517f9d780e7550fa5b49be740445",effectiveClaimRevision:"12b5cfba2667e8064309807776c1b323561dc8d853f9afe5f676007b8494b2b5",commitBodyDigest:"89a6653197509e75246a758d2706876b337770571a1cac47d9d85ec96c196459",changedPathsDigest:"12b5cfba2667e8064309807776c1b323561dc8d853f9afe5f676007b8494b2b5",qaDigest:"c7d3762ad30e4f9356243df17a1dd7123cbf1b660808d68176f44d1cd5da6449",reviewDigest:"e4ecf577e174fd66f31aa4a0113ab672ced16b12ee531f6831aa533795145ba1"}),"P174.03.724350":Object.freeze({baseSha:"4ccc90b85c49b27f718090bf25bc452f1b84e5e3",headSha:"568e9464fb086304146b9eb4594281f91302aef1",graphRevision:"60b343b4b810e6d5abc3159275012b9ab9ab517f9d780e7550fa5b49be740445",effectiveClaimRevision:"c8b8b6b96edf9cea78925e2f961bd74069d77af03783a5368b8ac8025bf1fefe",commitBodyDigest:"b3032338bfcd6c9dc460e9426220a1966dedeff9968c4064fdd36a315560721b",changedPathsDigest:"c8b8b6b96edf9cea78925e2f961bd74069d77af03783a5368b8ac8025bf1fefe",qaDigest:"91f2f5b00935b1b04bb5d400df500cbc97c412072078b713c6e5ba8fda669bd0",reviewDigest:"9bc92069d3b3a76cc8b02d339d432690258be1376464b69e152ed8fd3d682f05"}),"P174.03.011976":Object.freeze({baseSha:"568e9464fb086304146b9eb4594281f91302aef1",headSha:"195599b1a99a99a8416c4c26c9ab9990847338a4",graphRevision:"60b343b4b810e6d5abc3159275012b9ab9ab517f9d780e7550fa5b49be740445",effectiveClaimRevision:"49b7f2a0a967b2ba4249615c6d08834445a60df95045352838808eb4d6743b21",commitBodyDigest:"b8a28392fac663dd614b695a49c894b7cab116d45722a42850e3b24e2aaf36f4",changedPathsDigest:"49b7f2a0a967b2ba4249615c6d08834445a60df95045352838808eb4d6743b21",qaDigest:"6eb4459a7d80c4a268fc931297e8156ed2a320584f8775f0787d91b42c0929d4",reviewDigest:"98b21de29f7cceeec73da19000c6c144395cce6eb699c6a82dfab505d4ab7b44"}),"P174.03.686659":Object.freeze({baseSha:"195599b1a99a99a8416c4c26c9ab9990847338a4",headSha:"0db3681a5dad4e25ce37d967c636eb9d54915556",graphRevision:"60b343b4b810e6d5abc3159275012b9ab9ab517f9d780e7550fa5b49be740445",effectiveClaimRevision:"5c0fdbf820d677c288981b6f73f7d2d9a04ce7f4713687f12a2e984705244b8e",commitBodyDigest:"143257f4018ad773afc0c7280bd8aab8786851a9c20b65f8110881ff54656839",changedPathsDigest:"5c0fdbf820d677c288981b6f73f7d2d9a04ce7f4713687f12a2e984705244b8e",qaDigest:"6303dbf473e2815a3671aeb2c25528d8daba484b92a5a40d1eea5215e1f6763e",reviewDigest:"1bd6695846ed9340c8677cfa9b573880532187aeee487efaaa70577a0c94e7f2"})}),Se="neocortex-yoloop-runtime.json",ut="runtime.lock",Be=new WeakMap;async function ni(t,e){if(!w(e.headSha)||!g(e.graphRevision))throw new Error("p205-transient-binding-invalid");const i=e.anchoredWorkspace;if(i&&h(t)!==p(h(i.parent),i.name))throw new Error("p205-transient-anchor-binding-invalid");const r=async A=>i?(await st(i.parent,i.name,i.identity,A)).toString("utf8"):String((await C("git",[...A],{cwd:t,encoding:"utf8",maxBuffer:8*1024*1024})).stdout),n=async()=>i?JSON.parse((await $e(i.parent,i.name,i.identity,["-e","const fs=require('node:fs');process.stdout.write(JSON.stringify({manifest:fs.readFileSync('config/release-gates.v2.json','utf8'),runner:fs.readFileSync('scripts/test-root.mjs','utf8')}));"])).toString("utf8")):{manifest:await F(p(t,"config","release-gates.v2.json"),"utf8"),runner:await F(p(t,"scripts","test-root.mjs"),"utf8")};if((await r(["rev-parse","HEAD"])).trim()!==e.headSha)throw new Error("p205-transient-head-mismatch");const{manifest:o,runner:s}=await n(),[u,c]=await Promise.all([r(["show",`${e.headSha}:config/release-gates.v2.json`]),r(["show",`${e.headSha}:scripts/test-root.mjs`])]);if(o!==u||s!==c)throw new Error("p205-transient-producer-dirty");const d=JSON.parse(o),S=Array.isArray(d.requiredCompleteClasses)?d.requiredCompleteClasses.filter(A=>typeof A=="string"&&/^[a-z0-9-]+$/.test(A)):[];if(d.contract!=="P205-CI-02"||S.length===0)throw new Error("p205-transient-manifest-invalid");const l=i?(await $e(i.parent,i.name,i.identity,["scripts/test-root.mjs","--gate","complete"])).toString("utf8"):String((await C(process.execPath,["scripts/test-root.mjs","--gate","complete"],{cwd:t,encoding:"utf8",maxBuffer:64*1024*1024})).stdout),{manifest:y,runner:v}=await n();if(y!==o||v!==s)throw new Error("p205-transient-producer-raced");if((await r(["rev-parse","HEAD"])).trim()!==e.headSha)throw new Error("p205-transient-head-raced");const G=m("sha256").update(o).digest("hex"),$=m("sha256").update(l).digest("hex"),Y=ie(e.nowIso??new Date().toISOString()),V=m("sha256").update(["p205-transient-execution-v1",O,e.headSha,e.graphRevision,G,S.join(","),$,Y].join("\0")).digest("hex"),ae=Object.freeze({schemaVersion:1,kind:"p205_transient_execution_authority",contract:"P205-CI-02",command:O,executionHeadSha:e.headSha,graphRevision:e.graphRevision,manifestDigest:G,gateIds:Object.freeze(S),resultDigest:$,executedAt:Y,executionEvidenceDigest:V}),ge=Object.freeze(Object.create(null));return Be.set(ge,ae),ge}async function ai(t,e={}){const i=await xt(t);return Ke(i,e)}function gt(t,e={}){let i;try{const r=U("git",["rev-parse","--git-common-dir"],{cwd:t,encoding:"utf8",stdio:["ignore","pipe","ignore"]}).trim(),n=we(t),a=ee(r)?h(r):h(n,r),o=we(a);if(o!==a)throw new Error("git-lifecycle-common-dir-symlink");kt(o);const s=p(o,ce),u=p(s,oe);if(B(s)&&(Me(s,"directory"),we(s)!==s))throw new Error("git-lifecycle-runtime-directory-symlink");i=B(u)?u:p(o,Se)}catch{if(e.required)throw new Error("git-lifecycle-common-dir-invalid");return Re()}if(!B(i)){if(e.required)throw new Error("git-lifecycle-runtime-missing");return Re()}return Me(i,"file"),xe(JSON.parse(Oe(i,"utf8")))}async function ci(t,e,i={}){const r=await De(t),n=await Fe(r),a=p(n,ut),o=await Wt(a);try{const s=p(n,oe),u=p(r,Se),c=await Ke(B(s)?s:u);if(i.expectedRevision!==void 0&&i.expectedRevision!==c.revision)throw new Error("git-lifecycle-runtime-revision-conflict");const d=structuredClone(c),S=e(d),l=xe({...d,schemaVersion:1,revision:c.revision+1});return await i.preCommit?.(l),await L(n,"directory"),await It(s),await ot(n,oe,`${JSON.stringify(l,null,2)}
2
+ `),await L(s,"file"),await lt(n),{document:l,value:S}}finally{await Yt(a,o).catch(()=>{})}}async function lt(t){let e;try{e=await it(t,"r")}catch(i){if(process.platform==="win32"&&(_(i,"EPERM")||_(i,"EISDIR")||_(i,"EINVAL")))return;throw i}try{await e.sync()}finally{await e.close()}}function oi(t,e){const i=structuredClone(t),r=qe(i,"epics"),n=qe(i,"stories");for(const[a,o]of Object.entries(e.epics))r[a]={...f(r[a])??{},...structuredClone(o)};for(const[a,o]of Object.entries(e.stories))n[a]={...f(n[a])??{},...structuredClone(o)};return i}function qe(t,e){const i=t[e];if(i===void 0){const a={};return t[e]=a,a}const r=f(i);if(r)return r;if(!Array.isArray(i))throw new Error(`git-lifecycle-tracked-${e}-invalid`);const n={};for(const a of i){const o=f(a),s=typeof o?.id=="string"?o.id.trim():"";if(!s||n[s]!==void 0)throw new Error(`git-lifecycle-tracked-${e}-ambiguous`);n[s]=o}return t[e]=n,n}function si(t,e){return t.epics[e]??(t.epics[e]={})}function di(t,e){return t.stories[e]??(t.stories[e]={})}function Le(t,e,i,r){const n=f(t);return!!(n&&n.epicId===i&&n.branch===r&&n.qaVerdict==="passed"&&n.reviewVerdict==="approved"&&We(n,e))}async function fi(t,e,i,r,n,a,o=[]){return ht(t,e,i,r,n,a,o).verdict==="verified"}function ht(t,e,i,r,n,a,o=[],s=new Date().toISOString()){const u=()=>Dt({storyId:i,epicId:r,executionBranch:n,value:e,verifiedAt:s,verdict:"rejected",reasonCode:"checkpoint-git-physical-invalid"});try{if(!Le(e,i,r,n))return u();const c=f(e),d=f(c.qaReceipt),S=f(c.reviewReceipt),l=String(c.headSha),y=String(c.baseSha),v=q(t,["rev-parse",`refs/heads/${n}`]).trim();U("git",["merge-base","--is-ancestor",l,v],{cwd:t,stdio:"ignore"});const N=q(t,["show","--no-patch","--format=%H%n%P%n%B",l]),G=q(t,["rev-parse",`${l}^`]).trim(),$=q(t,["rev-list","--count",`${y}..${l}`]).trim();if(G!==y||$!=="1")return u();const Y=new Set(N.split(`
3
+ `).map(j=>j.trim())),ae=[`Neocortex-Story: ${i}`,`Neocortex-Epic: ${r}`,`Neocortex-Execution-Branch: ${n}`,`Neocortex-Bundle-Digest: ${String(c.bundleDigest)}`,`Neocortex-Graph-Revision: ${String(c.graphRevision)}`,...c.dispatchId?[`Neocortex-Dispatch: ${String(c.dispatchId)}`]:[],...c.bundleId?[`Neocortex-Bundle: ${String(c.bundleId)}`]:[],...c.claimRevision?[`Neocortex-Claim-Revision: ${String(c.claimRevision)}`]:[]].every(j=>Y.has(j));if(ae){const ke=[...Y].find(et=>et.startsWith("Neocortex-Prepared-Base: "))?.slice(25)??"";if(!/^[a-f0-9]{40,64}$/i.test(ke))return u();U("git",["merge-base","--is-ancestor",ke,l],{cwd:t,stdio:"ignore"})}const A=q(t,["diff-tree","--no-commit-id","--name-only","-r","-z",l]).split("\0").filter(Boolean);if(A.length===0||A.some(j=>!de(j)))return u();const le=m("sha256").update(N).digest("hex"),he=m("sha256").update([...A].sort().join("\0")).digest("hex"),k=je({checkpoint:c,storyId:i,epicId:r,executionBranch:n,baseSha:y,headSha:l,commitBodyDigest:le,changedPathsDigest:he,changedPaths:A,authorizedWriteSet:o.length>0?o:yt(t,i)});if(!k||d.receiptRef!==`story-qa:${String(d.sourceEvidenceDigest)}`)return u();const _e=St({storyId:i,baseSha:y,headSha:l,bundleDigest:String(c.bundleDigest),graphRevision:String(c.graphRevision),commitBody:N,changedPaths:A}),Ie=d.evidenceVersion==="p205-execution-v2"&&d.contract==="P205-CI-02"&&d.command===O&&g(d.manifestDigest)&&P(d.gateIds,32,!0)&&g(d.resultDigest)&&d.sourceEvidenceDigest===vt({gitEvidenceDigest:_e,headSha:l,graphRevision:String(c.graphRevision),manifestDigest:String(d.manifestDigest),gateIds:d.gateIds,resultDigest:String(d.resultDigest)}),Ze=d.evidenceVersion==="git-immutable-v1"&&d.sourceEvidenceDigest===_e,Xe=d.evidenceVersion===void 0&&k.mode==="legacy-migration"&&k.binding?.qaDigest===d.sourceEvidenceDigest,me=mt(a,v,String(c.graphRevision))&&(Ie||k.mode==="legacy-migration"&&(Ze||Xe)),pe=a===void 0&&Ie;if(!me&&!pe)return u();const Ae=m("sha256").update(["root-commit-range-review-v1",i,y,l,String(c.bundleDigest),String(c.graphRevision),String(d.receiptRef),m("sha256").update(N).digest("hex"),[...A].sort().join(",")].join("\0")).digest("hex");if(S.sourceEvidenceDigest!==Ae||S.receiptRef!==`story-review:${Ae}`||k.mode==="legacy-migration"&&k.binding?.reviewDigest!==void 0&&k.binding.reviewDigest!==S.sourceEvidenceDigest||!ae&&(Ve[i]!==l||!Array.isArray(c.receiptRefs)||!c.receiptRefs.some(j=>typeof j=="string"&&j.startsWith("legacy-direct-yolo:"))))return u();const Ue=m("sha256").update(["checkpoint-p205-transient-v1",i,r,n,y,l,String(c.bundleDigest),le,he,k.mode,k.effectiveClaimRevision,String(d.sourceEvidenceDigest),String(S.sourceEvidenceDigest),te(a)?.executionEvidenceDigest??(pe?"maintenance-git-verification":"legacy-bounded-authority")].join("\0")).digest("hex"),J=me?te(a):void 0;return Object.freeze({schemaVersion:1,kind:"story_checkpoint_physical_verification",producer:"client-p205-transient-v1",storyId:i,epicId:r,branch:n,baseSha:y,headSha:l,aggregateHeadSha:J?.executionHeadSha??l,commitBodyDigest:le,changedPathsDigest:he,claimVerification:k.mode,effectiveClaimRevision:k.effectiveClaimRevision,sourceEvidenceDigest:Ue,command:O,manifestDigest:J?.manifestDigest??"0".repeat(64),gateIds:J?.gateIds??Object.freeze(["legacy-bounded"]),resultDigest:J?.resultDigest??"0".repeat(64),graphRevision:String(c.graphRevision),executionEvidenceDigest:J?.executionEvidenceDigest??"0".repeat(64),verifiedAt:J?.executedAt??ie(s),verdict:"verified",reasonCodes:Object.freeze([me?"checkpoint-p205-transient-verified":pe?"checkpoint-git-maintenance-verified":"checkpoint-legacy-bounded-verified",...k.mode==="legacy-migration"?["checkpoint-legacy-migration-verified"]:[]]),publicSafe:!0})}catch{return u()}}function mt(t,e,i){const r=te(t);return!!(r&&r.schemaVersion===1&&r.kind==="p205_transient_execution_authority"&&r.contract==="P205-CI-02"&&r.command===O&&r.graphRevision===i&&g(r.resultDigest)&&g(r.executionEvidenceDigest)&&r.executionHeadSha===e&&w(e))}function te(t){return t&&typeof t=="object"?Be.get(t):void 0}function ui(t){const e=te(t);return e?Object.freeze({executionHeadSha:e.executionHeadSha,graphRevision:e.graphRevision,manifestDigest:e.manifestDigest,gateIds:Object.freeze([...e.gateIds]),resultDigest:e.resultDigest,executedAt:e.executedAt,executionEvidenceDigest:e.executionEvidenceDigest}):void 0}function gi(t,e,i){const r=te(t);return!!(r&&r.executionHeadSha===e&&r.graphRevision===i&&r.command===O)}function je(t){const e=ft[t.storyId],i=typeof t.checkpoint.claimRevision=="string"?t.checkpoint.claimRevision:void 0,r=t.storyId==="P174.03.811759"||t.storyId==="P174.03.685003",n=pt(t.authorizedWriteSet),a=n.length>0&&n.length===t.authorizedWriteSet.length&&t.changedPaths.every(o=>n.some(s=>wt(s,o)));if(e&&t.epicId==="P174"&&t.executionBranch==="epic/P174"&&t.baseSha===e.baseSha&&t.headSha===e.headSha&&t.checkpoint.graphRevision===e.graphRevision&&t.commitBodyDigest===e.commitBodyDigest&&t.changedPathsDigest===e.changedPathsDigest&&(r?i===void 0:i===e.effectiveClaimRevision))return t.authorizedWriteSet.length>0&&(!a||!ze(e.effectiveClaimRevision,n))?void 0:Object.freeze({mode:"legacy-migration",effectiveClaimRevision:e.effectiveClaimRevision,binding:e});if(i!==void 0&&!(!i||!g(i))&&!(!a||!ze(i,n)))return Object.freeze({mode:"canonical",effectiveClaimRevision:i})}function pt(t){const e=t.map(i=>i.replaceAll("\\","/").replace(/^\.\//,"").replace(/\/{2,}/g,"/"));return e.some(i=>!de(i))?Object.freeze([]):Object.freeze([...new Set(e)].sort())}function yt(t,e){try{const i=JSON.parse(Oe(p(t,".neocortex","state.json"),"utf8")),r=f(i.stories),n=f(r?.[e]),a=gt(t),o=f(a.stories[e]?.checkpoint)??f(n?.checkpoint);return bt(e,n,o)}catch{return[]}}function bt(t,e,i){const r=Array.isArray(e?.files_to_modify)?e.files_to_modify.filter(n=>typeof n=="string"):[];if(!i?.dispatchId||!i.bundleId)return r;try{return ct({...e,id:t,files_to_modify:r})}catch{return[]}}function ze(t,e){return t===m("sha256").update(e.join("\0")).digest("hex")||t===m("sha256").update(JSON.stringify(e)).digest("hex")}function wt(t,e){return t===e||t.endsWith("/")&&e.startsWith(t)}function li(t,e,i,r,n,a){try{if(!Le(e,i,r,n))return!1;const o=f(e),s=f(o.qaReceipt),u=f(o.reviewReceipt),c=String(o.headSha),d=String(o.baseSha),S=q(t,["rev-parse",`refs/heads/${n}`]).trim();if(U("git",["merge-base","--is-ancestor",c,S],{cwd:t,stdio:"ignore"}),q(t,["rev-parse",`${c}^`]).trim()!==d||q(t,["rev-list","--count",`${d}..${c}`]).trim()!=="1")return!1;const l=q(t,["show","--no-patch","--format=%H%n%P%n%B",c]),y=q(t,["diff-tree","--no-commit-id","--name-only","-r","-z",c]).split("\0").filter(Boolean);if(y.length===0||y.some(N=>!de(N)))return!1;const v=je({checkpoint:o,storyId:i,epicId:r,executionBranch:n,baseSha:d,headSha:c,changedPaths:y,authorizedWriteSet:a,commitBodyDigest:m("sha256").update(l).digest("hex"),changedPathsDigest:m("sha256").update([...y].sort().join("\0")).digest("hex")});return!(v?.mode!=="legacy-migration"||!v.binding||s.sourceEvidenceDigest!==v.binding.qaDigest||s.receiptRef!==`story-qa:${v.binding.qaDigest}`||u.sourceEvidenceDigest!==v.binding.reviewDigest||u.receiptRef!==`story-review:${v.binding.reviewDigest}`||u.qaReceiptRef!==s.receiptRef)}catch{return!1}}function St(t){return m("sha256").update(["local-yolo-tdd-git-immutable-v1",t.storyId,t.baseSha,t.headSha,t.bundleDigest,t.graphRevision,m("sha256").update(t.commitBody).digest("hex"),m("sha256").update([...t.changedPaths].sort().join("\0")).digest("hex")].join("\0")).digest("hex")}function vt(t){return m("sha256").update(["local-yolo-tdd-p205-execution-v2",O,t.gitEvidenceDigest,t.headSha,t.graphRevision,t.manifestDigest,t.gateIds.join(","),t.resultDigest].join("\0")).digest("hex")}function Dt(t){const e=f(t.value);return Object.freeze({schemaVersion:1,kind:"story_checkpoint_physical_verification",producer:"client-p205-transient-v1",storyId:t.storyId,epicId:t.epicId,branch:t.executionBranch,baseSha:w(e?.baseSha)?String(e?.baseSha):"0".repeat(40),headSha:w(e?.headSha)?String(e?.headSha):"0".repeat(40),aggregateHeadSha:"0".repeat(40),commitBodyDigest:"0".repeat(64),changedPathsDigest:"0".repeat(64),claimVerification:"canonical",effectiveClaimRevision:"0".repeat(64),command:O,manifestDigest:"0".repeat(64),gateIds:Object.freeze([]),resultDigest:"0".repeat(64),graphRevision:"0".repeat(64),executionEvidenceDigest:"0".repeat(64),sourceEvidenceDigest:"0".repeat(64),verifiedAt:ie(t.verifiedAt),verdict:t.verdict,reasonCodes:Object.freeze([t.reasonCode]),publicSafe:!0})}function q(t,e){return U("git",[...e],{cwd:t,encoding:"utf8",maxBuffer:32*1024*1024})}function ie(t){return Number.isFinite(Date.parse(t))?new Date(Date.parse(t)).toISOString():new Date().toISOString()}async function hi(t,e){if(Ve[e.storyId]!==e.headSha)return;const i=[".neocortex/state.json",`.neocortex/stories/${e.storyId}/qa-gate-result.json`,`.neocortex/stories/${e.storyId}/validation-evidence.md`,`.neocortex/stories/${e.storyId}/review.md`,`docs/stories/${e.storyId}.story.md`];try{const r=(await C("git",["rev-parse",`refs/heads/${e.executionBranch}`],{cwd:t,encoding:"utf8",maxBuffer:1048576})).stdout.trim();if(await C("git",["merge-base","--is-ancestor",e.headSha,r],{cwd:t}),(await C("git",["rev-parse",`${e.headSha}^`],{cwd:t,encoding:"utf8",maxBuffer:1024*1024})).stdout.trim()!==e.baseSha)return;const a=String((await C("git",["diff","--binary","--full-index",`${e.baseSha}..${e.headSha}`],{cwd:t,encoding:"utf8",maxBuffer:32*1024*1024})).stdout);if(m("sha256").update(a).digest("hex")!==e.bundleDigest)return;const o=String((await C("git",["show","--no-patch","--format=%H%n%P%n%B",e.headSha],{cwd:t,encoding:"utf8",maxBuffer:4*1024*1024})).stdout);if(!String((await C("git",["show","--no-patch","--format=%s",e.headSha],{cwd:t,encoding:"utf8",maxBuffer:1024*1024})).stdout).trim().includes(e.storyId))return;const c=String((await C("git",["diff-tree","--no-commit-id","--name-only","-r","-z",e.headSha],{cwd:t,encoding:"utf8",maxBuffer:8*1024*1024})).stdout).split("\0").filter(Boolean);if(!i.every(V=>c.includes(V))||c.some(V=>!de(V)))return;const d=await Promise.all(i.map(async V=>String((await C("git",["show",`${e.headSha}:${V}`],{cwd:t,encoding:"utf8",maxBuffer:16*1024*1024})).stdout))),S=JSON.parse(d[0]),l=f(S.stories),y=f(S.epics),v=f(l?.[e.storyId]),N=f(y?.[e.epicId]),G=Array.isArray(v?.steps_completed)?v.steps_completed:[],$=JSON.parse(d[1]);return v?.status!=="done"||!G.includes("step-c-08-commit-push")||!G.includes("step-c-11-review-pr")||N?.branch_mode!=="epic"||N.execution_branch!==e.executionBranch||$.storyId!==e.storyId||$.status!=="qa-passed"||$.safeToContinueYoloop!==!0||!Array.isArray($.blockingChecks)||$.blockingChecks.length!==0||!d[2].includes(e.storyId)||!/P205[\s\S]{0,80}(pass|aprov)/i.test(d[2])||!d[3].includes(e.storyId)||!/approved|aprovado/i.test(d[3])||!d[4].includes(e.storyId)?void 0:`legacy-direct-yolo:${m("sha256").update(["legacy-direct-yolo-recovery-v1",e.storyId,e.epicId,e.executionBranch,e.baseSha,e.headSha,e.bundleDigest,e.graphRevision,m("sha256").update(o).digest("hex"),m("sha256").update([...c].sort().join("\0")).digest("hex"),...d.map(V=>m("sha256").update(V).digest("hex"))].join("\0")).digest("hex")}`}catch{return}}async function xt(t){const e=await De(t),i=p(e,ce),r=p(i,oe);if(B(i)&&(await L(i,"directory"),await K(i)!==i))throw new Error("git-lifecycle-runtime-directory-symlink");return B(r)?r:p(e,Se)}async function He(t){return Fe(await De(t))}async function Rt(t,e){if(!/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/.test(e)||e.includes(".."))throw new Error("git-lifecycle-private-child-invalid");const i=h(t);await H(i);const r=h(i,e);return Z(i,r),B(r)||await Ne(i,e),await H(r,i),await H(i),r}async function b(t,e){const i=h(e),r=h(t);Z(i,r),await H(i),await H(r,i)}async function mi(t,e){await T(t,e)}async function M(t,e,i){const r=h(e),n=h(t);Z(r,n);try{await b(n,r)}catch(o){if(_(o,"ENOENT"))return!1;throw o}const a=h(r,`${n.slice(r.length+1)}.remove.${process.pid}.${Date.now()}.${ye(4).toString("hex")}`);return Z(r,a),await Q(r,R(n),R(a)),await b(a,r),i&&!await i(a)?(await re(a,n,r).catch(()=>{}),!1):(await dt(r,R(a)),!0)}async function re(t,e,i){await b(t,i);try{await be(e);return}catch(r){if(!_(r,"ENOENT"))throw r}await Q(i,R(t),R(e)),await b(e,i)}async function I(t){try{await b(t,z(t));const e=p(t,"owner.json");await T(e,t);const i=await F(e);return await T(e,t),m("sha256").update(i).digest("hex")}catch{return}}async function pi(t,e){const i=await He(t),r=await Rt(i,"leases"),n=p(r,"integration"),a=`${n}.recovery`;if(B(a)){await b(a,r);const c=await Te(a),d=await I(a);if(c===void 0||ue(c))return{ok:!1,reasonCode:"git-lifecycle-integration-backpressure"};if(!d||!await M(a,r,async S=>await I(S)===d))return{ok:!1,reasonCode:"git-lifecycle-integration-backpressure"}}const o=ie(e.createdAt??new Date().toISOString()),s=Object.freeze({schemaVersion:1,kind:e.kind,storyId:e.storyId,sessionId:e.sessionId,idempotencyKey:e.idempotencyKey,pid:process.pid,createdAt:o,expiresAt:ie(e.expiresAt),persistent:e.persistent,ownerNonce:e.ownerNonce??ye(16).toString("hex")});if(Date.parse(s.expiresAt)<=Date.parse(s.createdAt))return{ok:!1,reasonCode:"git-lifecycle-integration-lock-failed"};const u=async()=>{await H(r,i);try{return await Pe(r,R(n),`${JSON.stringify(s)}
4
+ `),await b(n,r),await T(p(n,"owner.json"),n),!0}catch(c){throw _(c,"EEXIST")||await M(n,r).catch(()=>{}),c}};try{return await u(),{ok:!0,owner:s,path:n}}catch(c){if(!_(c,"EEXIST"))return{ok:!1,reasonCode:"git-lifecycle-integration-lock-failed"}}try{const c=await ne(n),d=c?void 0:await Te(n);if(c&&Ge(c,s))return{ok:!0,owner:c,path:n};if(c&&Date.parse(c.expiresAt)>Date.now()&&(c.persistent||ue(c.pid))||d!==void 0&&ue(d)||!c&&d===void 0&&await Je(n))return{ok:!1,reasonCode:"git-lifecycle-integration-backpressure"};const l=await I(n);if(!l)return{ok:!1,reasonCode:"git-lifecycle-integration-lock-failed"};const y=`${n}.stale.${process.pid}.${Date.now()}`;await Q(r,R(n),R(y));try{if(await b(y,r),await I(y)!==l)return await re(y,n,r).catch(()=>{}),{ok:!1,reasonCode:"git-lifecycle-integration-backpressure"};await u()}finally{await M(y,r,async v=>await I(v)===l).catch(()=>{})}return{ok:!0,owner:s,path:n}}catch(c){return{ok:!1,reasonCode:_(c,"EEXIST")||_(c,"ENOENT")?"git-lifecycle-integration-backpressure":"git-lifecycle-integration-lock-failed"}}}async function yi(t,e){const i=await ne(t);return!!(i&&ve(i,e)&&Date.parse(i.expiresAt)>Date.now())}async function Et(t,e){try{const i=z(t);await b(t,i);const r=await ne(t);if(!r||!ve(r,e))return!1;const n=await I(t);if(!n)return!1;const a=`${t}.release.${process.pid}.${Date.now()}`;await Q(i,R(t),R(a)),await b(a,i);const o=await ne(a);return!o||!ve(o,e)||await I(a)!==n?(await re(a,t,i).catch(()=>{}),!1):M(a,i,async s=>await I(s)===n)}catch(i){if(_(i,"ENOENT"))return!1;throw i}}function _t(t){return m("sha256").update(["git-lifecycle-physical-owner-v1",t.kind,t.storyId,t.sessionId,t.idempotencyKey,String(t.pid),t.createdAt,t.expiresAt,t.persistent?"persistent":"ephemeral",t.ownerNonce].join("\0")).digest("hex")}async function bi(t,e){if(!X(e.storyId)||!E(e.idempotencyKey)||!g(e.ownerDigest))return"foreign";const i=await He(t),r=p(i,"leases"),n=p(r,"integration");if(!B(n))return"absent";try{await b(r,i),await b(n,r);const a=await ne(n);return!a||a.kind!=="direct"||a.storyId!==e.storyId||a.sessionId!==e.idempotencyKey||a.idempotencyKey!==e.idempotencyKey||a.persistent!==!0||_t(a)!==e.ownerDigest?"foreign":await Et(n,a)?"released":"foreign"}catch{return"foreign"}}async function ne(t){try{await b(t,z(t));const e=p(t,"owner.json");await T(e,t);const i=JSON.parse(await F(e,"utf8"));return i.schemaVersion!==1||i.kind!=="direct"&&i.kind!=="continuous"||!X(i.storyId)||!E(i.sessionId)||!E(i.idempotencyKey)||!Number.isSafeInteger(i.pid)||Number(i.pid)<=0||!x(i.createdAt)||!x(i.expiresAt)||typeof i.persistent!="boolean"||typeof i.ownerNonce!="string"||!/^[a-f0-9]{32}$/.test(i.ownerNonce)?void 0:i}catch{return}}async function Te(t){try{await b(t,z(t));const e=p(t,"owner.json");await T(e,t);const i=JSON.parse(await F(e,"utf8"));return Number.isSafeInteger(i.pid)&&Number(i.pid)>0?Number(i.pid):void 0}catch{return}}function Ge(t,e){return t.kind===e.kind&&t.storyId===e.storyId&&t.sessionId===e.sessionId&&t.idempotencyKey===e.idempotencyKey&&t.expiresAt===e.expiresAt&&t.persistent===e.persistent}function ve(t,e){return Ge(t,e)&&t.schemaVersion===e.schemaVersion&&t.pid===e.pid&&t.createdAt===e.createdAt&&t.ownerNonce===e.ownerNonce}async function De(t){const e=await K(t),r=(await C("git",["rev-parse","--git-common-dir"],{cwd:e,encoding:"utf8",maxBuffer:1024*1024})).stdout.trim(),n=ee(r)?h(r):h(e,r),a=await K(n);if(a!==n)throw new Error("git-lifecycle-common-dir-symlink");await At(a);const s=(await C("git",["rev-parse","--git-common-dir"],{cwd:e,encoding:"utf8",maxBuffer:1024*1024})).stdout.trim();if((ee(s)?h(s):h(e,s))!==n)throw new Error("git-lifecycle-common-dir-raced");return a}async function Fe(t){const e=p(t,ce);if(B(e)||await Ne(t,ce),await L(e,"directory"),await K(e)!==e)throw new Error("git-lifecycle-runtime-directory-symlink");return e}async function Ke(t,e={}){try{return await L(t,"file"),xe(JSON.parse(await F(t,"utf8")))}catch(i){if(_(i,"ENOENT")){if(e.required)throw new Error("git-lifecycle-runtime-missing");return Re()}throw i}}async function It(t){try{await L(t,"file")}catch(e){if(_(e,"ENOENT"))return;throw e}}async function L(t,e){const i=await be(t);if(i.isSymbolicLink())throw new Error(`git-lifecycle-${e}-symlink`);if(e==="file"?!i.isFile():!i.isDirectory())throw new Error(`git-lifecycle-${e}-invalid`);if(se()&&i.uid!==process.getuid())throw new Error(`git-lifecycle-${e}-ownership-mismatch`);if(se()&&(i.mode&63)!==0)throw new Error(`git-lifecycle-${e}-permissions-unsafe`)}function Z(t,e){const i=h(t),r=h(e),n=nt(i,r);if(!n||n.startsWith("..")||ee(n)||z(r)!==i)throw new Error("git-lifecycle-private-path-escape")}async function H(t,e){const i=h(t);if(e&&Z(h(e),i),await L(i,"directory"),h(await K(i))!==i)throw new Error("git-lifecycle-directory-substituted");if(e){const r=h(e);if(await L(r,"directory"),h(await K(r))!==r)throw new Error("git-lifecycle-directory-parent-substituted")}}async function T(t,e){const i=h(t);if(Z(h(e),i),await H(h(e)),await L(i,"file"),h(await K(i))!==i)throw new Error("git-lifecycle-file-substituted")}function Me(t,e){const i=Ce(t);if(i.isSymbolicLink())throw new Error(`git-lifecycle-${e}-symlink`);if(e==="file"?!i.isFile():!i.isDirectory())throw new Error(`git-lifecycle-${e}-invalid`);if(se()&&i.uid!==process.getuid())throw new Error(`git-lifecycle-${e}-ownership-mismatch`);if(se()&&(i.mode&63)!==0)throw new Error(`git-lifecycle-${e}-permissions-unsafe`)}async function At(t){const e=await be(t);if(e.isSymbolicLink())throw new Error("git-lifecycle-common-dir-symlink");if(!e.isDirectory())throw new Error("git-lifecycle-common-dir-invalid")}function kt(t){const e=Ce(t);if(e.isSymbolicLink())throw new Error("git-lifecycle-common-dir-symlink");if(!e.isDirectory())throw new Error("git-lifecycle-common-dir-invalid")}function se(t=process.platform){return t!=="win32"&&typeof process.getuid=="function"}function xe(t){if(!t||typeof t!="object"||Array.isArray(t))throw new Error("git-lifecycle-runtime-invalid");const e=t;D(e,["schemaVersion","revision","epics","stories"],"git-lifecycle-runtime-unknown-field");const i=f(e.epics),r=f(e.stories);if(e.schemaVersion!==1||!Number.isSafeInteger(e.revision)||Number(e.revision)<0||!i||!r||Object.values(i).some(n=>!f(n))||Object.values(r).some(n=>!f(n)))throw new Error("git-lifecycle-runtime-invalid");for(const[n,a]of Object.entries(i))if(!X(n)||!Pt(a))throw new Error("git-lifecycle-runtime-epic-invalid");for(const[n,a]of Object.entries(r))if(!X(n)||!n.includes(".")||!Nt(a,n))throw new Error("git-lifecycle-runtime-story-invalid");return e}const Ct=["branch_mode","execution_branch","origin_branch","branch_lease","origin_binding","graph_revision","aggregate_qa_receipt","terminal_git_receipt","physicalMergeStatus","pr_number","git_reconciliation_receipts","git_reconciliation_debt"],Ot=["checkpoint","status","last_step","steps_completed"];function Pt(t){return D(t,Ct,"git-lifecycle-runtime-epic-unknown-field"),(t.branch_mode===void 0||t.branch_mode==="epic")&&(t.execution_branch===void 0||W(t.execution_branch))&&(t.origin_branch===void 0||W(t.origin_branch))&&(t.branch_lease===void 0||t.branch_lease===null||$t(t.branch_lease))&&(t.origin_binding===void 0||t.origin_binding===null||qt(t.origin_binding))&&(t.graph_revision===void 0||g(t.graph_revision))&&(t.aggregate_qa_receipt===void 0||t.aggregate_qa_receipt===null||Lt(t.aggregate_qa_receipt))&&(t.terminal_git_receipt===void 0||t.terminal_git_receipt===null||jt(t.terminal_git_receipt))&&(t.physicalMergeStatus===void 0||["merged","pushed","denied_external_gate","blocked_local_or_repo","not_attempted"].includes(String(t.physicalMergeStatus)))&&(t.pr_number===void 0||t.pr_number===null||Number.isSafeInteger(t.pr_number)&&Number(t.pr_number)>0)&&(t.git_reconciliation_receipts===void 0||Ft(t.git_reconciliation_receipts))&&(t.git_reconciliation_debt===void 0||Kt(t.git_reconciliation_debt))}function Nt(t,e){return D(t,Ot,"git-lifecycle-runtime-story-unknown-field"),(t.checkpoint===void 0||t.checkpoint===null||We(t.checkpoint,e))&&(t.status===void 0||E(t.status))&&(t.last_step===void 0||t.last_step===null||E(t.last_step))&&(t.steps_completed===void 0||P(t.steps_completed,128))}function $t(t){const e=f(t);return e?(D(e,["schemaVersion","ownerStoryId","sessionId","idempotencyKey","acquiredAt","expiresAt","handoffGrant","handoffConsumption"],"git-lifecycle-runtime-lease-unknown-field"),e.schemaVersion===1&&X(e.ownerStoryId)&&E(e.sessionId)&&E(e.idempotencyKey)&&x(e.acquiredAt)&&x(e.expiresAt)&&Date.parse(String(e.expiresAt))>Date.parse(String(e.acquiredAt))&&(e.handoffGrant===void 0||Vt(e.handoffGrant,e))&&(e.handoffConsumption===void 0||Bt(e.handoffConsumption,e))):!1}function Vt(t,e){const i=f(t);return i?(D(i,["schemaVersion","kind","storyId","fromSessionId","tokenDigest","bundleDigest","claimRevision","expiresAt"],"git-lifecycle-runtime-handoff-grant-unknown-field"),i.schemaVersion===1&&i.kind==="direct-yolo-setup-handoff"&&i.storyId===e.ownerStoryId&&i.fromSessionId===e.sessionId&&g(i.tokenDigest)&&g(i.bundleDigest)&&g(i.claimRevision)&&x(i.expiresAt)&&Date.parse(String(i.expiresAt))<=Date.parse(String(e.expiresAt))):!1}function Bt(t,e){const i=f(t);return i?(D(i,["schemaVersion","kind","state","storyId","fromSessionId","tokenDigest","bundleDigest","claimRevision","consumedBySessionId","consumedAt"],"git-lifecycle-runtime-handoff-consumption-unknown-field"),i.schemaVersion===1&&i.kind==="direct-yolo-setup-handoff-consumption"&&i.state==="consumed"&&i.storyId===e.ownerStoryId&&E(i.fromSessionId)&&g(i.tokenDigest)&&g(i.bundleDigest)&&g(i.claimRevision)&&i.consumedBySessionId===e.sessionId&&x(i.consumedAt)):!1}function qt(t){const e=f(t);return e?(D(e,["schemaVersion","originBranch","originHeadSha","executionBranch","capturedFromCurrentCheckout","capturedAt"],"git-lifecycle-runtime-origin-unknown-field"),e.schemaVersion===1&&W(e.originBranch)&&W(e.executionBranch)&&e.originBranch!==e.executionBranch&&w(e.originHeadSha)&&e.capturedFromCurrentCheckout===!0&&x(e.capturedAt)):!1}function Lt(t){const e=f(t);if(!e)return!1;D(e,["schemaVersion","evidenceVersion","producer","contract","command","verdict","executionHeadSha","graphRevision","manifestDigest","resultDigest","checkedAt","receiptRef","gateIds"],"git-lifecycle-runtime-aggregate-qa-unknown-field");const i=e.evidenceVersion==="p205-execution-v2"&&e.producer==="local-yolo-tdd"&&e.contract==="P205-CI-02"&&e.command===O&&g(e.manifestDigest)&&g(e.resultDigest),r=e.evidenceVersion===void 0&&e.producer===void 0&&e.contract===void 0&&e.command===void 0&&e.manifestDigest===void 0&&e.resultDigest===void 0;return e.schemaVersion===1&&(i||r)&&e.verdict==="passed"&&w(e.executionHeadSha)&&g(e.graphRevision)&&x(e.checkedAt)&&fe(e.receiptRef)&&P(e.gateIds,128,!0)}function jt(t){const e=f(t);return e?(D(e,["schemaVersion","epicId","executionBranch","originBranch","baseSha","executionHeadSha","mergeSha","pushedSha","strategy","prNumber","physicalStatus","localGateReceiptRefs","idempotencyKey","attemptStartedAt","completedAt","retryEligible","reasonCodes","publicSafe","candidateQa","providerGuard"],"git-lifecycle-runtime-terminal-receipt-unknown-field"),e.schemaVersion===1&&X(e.epicId)&&W(e.executionBranch)&&W(e.originBranch)&&w(e.baseSha)&&w(e.executionHeadSha)&&(e.mergeSha===void 0||w(e.mergeSha))&&(e.pushedSha===void 0||w(e.pushedSha))&&(e.strategy==="direct"||e.strategy==="single_pr")&&(e.candidateQa===void 0||Ht(e.candidateQa,e))&&(e.providerGuard===void 0||zt(e.providerGuard,e))&&(e.prNumber===void 0||Number.isSafeInteger(e.prNumber)&&Number(e.prNumber)>0)&&["prepared","merged","pushed","denied_external_gate","blocked_local_or_repo"].includes(String(e.physicalStatus))&&P(e.localGateReceiptRefs,128,!0)&&E(e.idempotencyKey)&&x(e.attemptStartedAt)&&(e.completedAt===void 0||x(e.completedAt))&&typeof e.retryEligible=="boolean"&&P(e.reasonCodes,128)&&e.publicSafe===!0):!1}function zt(t,e){const i=f(t);if(!i)return!1;D(i,["schemaVersion","provider","mode","source","prHeadSha","originHeadSha","checkedAt","publicSafe"],"git-lifecycle-runtime-provider-guard-unknown-field");const r=i.mode==="recovered_exact_tree"?i.source==="physical_recovery":i.mode==="strict_up_to_date_expected_head"&&["branch_protection","ruleset","branch_protection_and_ruleset"].includes(String(i.source));return i.schemaVersion===1&&i.provider==="github"&&r&&e.strategy==="single_pr"&&e.physicalStatus==="pushed"&&Number.isSafeInteger(e.prNumber)&&Number(e.prNumber)>0&&w(i.prHeadSha)&&i.prHeadSha===e.mergeSha&&w(i.originHeadSha)&&i.originHeadSha===e.baseSha&&x(i.checkedAt)&&i.publicSafe===!0}function Ht(t,e){const i=f(t);return i?(D(i,["schemaVersion","kind","contract","command","originHeadSha","executionHeadSha","mergeSha","treeSha","graphRevision","manifestDigest","resultDigest","gateIds","checkedAt","receiptRef"],"git-lifecycle-runtime-merge-candidate-unknown-field"),i.schemaVersion===1&&i.kind==="epic_merge_candidate_qa"&&i.contract==="P205-CI-02"&&i.command===O&&w(i.originHeadSha)&&i.originHeadSha===e.baseSha&&w(i.executionHeadSha)&&i.executionHeadSha===e.executionHeadSha&&w(i.mergeSha)&&i.mergeSha===e.mergeSha&&w(i.treeSha)&&g(i.graphRevision)&&g(i.manifestDigest)&&g(i.resultDigest)&&P(i.gateIds,128,!0)&&x(i.checkedAt)&&fe(i.receiptRef)):!1}function We(t,e){const i=f(t);if(!i)return!1;D(i,["schemaVersion","storyId","epicId","branch","baseSha","headSha","commits","idempotencyKey","dispatchId","bundleId","bundleDigest","graphRevision","claimRevision","receiptRefs","qaVerdict","reviewVerdict","qaReceipt","reviewReceipt","recordedAt"],"git-lifecycle-runtime-checkpoint-unknown-field");const r=String(e).split(".")[0];return i.schemaVersion===1&&i.storyId===e&&i.epicId===r&&W(i.branch)&&w(i.baseSha)&&w(i.headSha)&&i.baseSha!==i.headSha&&Mt(i.commits)&&i.commits.length===1&&i.commits[0]===i.headSha&&E(i.idempotencyKey)&&(i.dispatchId===void 0||g(i.dispatchId))&&(i.bundleId===void 0||g(i.bundleId))&&g(i.bundleDigest)&&g(i.graphRevision)&&(i.claimRevision===void 0||g(i.claimRevision))&&P(i.receiptRefs,256,!0)&&(i.qaVerdict==="passed"||i.qaVerdict==="blocked")&&["approved","changes-requested","pending"].includes(String(i.reviewVerdict))&&Tt(i.qaReceipt,i)&&(i.reviewVerdict==="pending"?i.reviewReceipt===void 0:Gt(i.reviewReceipt,i))&&x(i.recordedAt)}function Tt(t,e){const i=f(t);return i?(D(i,["schemaVersion","kind","producer","evidenceVersion","storyId","epicId","baseSha","headSha","bundleDigest","graphRevision","contract","command","manifestDigest","gateIds","resultDigest","sourceEvidenceDigest","verdict","checkedAt","receiptRef"],"git-lifecycle-runtime-story-qa-unknown-field"),i.schemaVersion===1&&i.kind==="story_qa_evidence"&&i.producer==="local-yolo-tdd"&&(i.evidenceVersion===void 0||i.evidenceVersion==="git-immutable-v1"||i.evidenceVersion==="p205-execution-v2"&&i.contract==="P205-CI-02"&&i.command===O&&g(i.manifestDigest)&&P(i.gateIds,32,!0)&&g(i.resultDigest))&&Ye(i,e)&&g(i.sourceEvidenceDigest)&&i.verdict===e.qaVerdict&&(i.verdict==="passed"||i.verdict==="blocked")&&x(i.checkedAt)&&fe(i.receiptRef)&&e.receiptRefs.includes(i.receiptRef)):!1}function Gt(t,e){const i=f(t),r=f(e.qaReceipt);return!i||!r?!1:(D(i,["schemaVersion","kind","producer","storyId","epicId","baseSha","headSha","bundleDigest","graphRevision","sourceEvidenceDigest","qaReceiptRef","verdict","reviewedAt","receiptRef"],"git-lifecycle-runtime-story-review-unknown-field"),i.schemaVersion===1&&i.kind==="story_review_evidence"&&i.producer==="root-commit-range-review"&&Ye(i,e)&&g(i.sourceEvidenceDigest)&&i.qaReceiptRef===r.receiptRef&&i.receiptRef!==r.receiptRef&&(i.verdict==="approved"||i.verdict==="changes-requested")&&(i.verdict==="approved"?e.reviewVerdict==="approved":e.reviewVerdict==="changes-requested")&&x(i.reviewedAt)&&Date.parse(String(i.reviewedAt))>=Date.parse(String(r.checkedAt))&&fe(i.receiptRef)&&e.receiptRefs.includes(i.receiptRef))}function Ye(t,e){return["storyId","epicId","baseSha","headSha","bundleDigest","graphRevision"].every(i=>t[i]===e[i])}function Ft(t){return!Array.isArray(t)||t.length>1024?!1:t.every(e=>{const i=f(e);return i?(D(i,["schemaVersion","resourceId","action","outcome","idempotencyKey","reasonCodes","recordedAt","publicSafe"],"git-lifecycle-runtime-reconciliation-receipt-unknown-field"),i.schemaVersion===1&&E(i.resourceId)&&["no_op","delete_local_branch","delete_remote_branch","close_pull_request"].includes(String(i.action))&&["applied","already_absent","dry_run","failed"].includes(String(i.outcome))&&E(i.idempotencyKey)&&P(i.reasonCodes,128)&&x(i.recordedAt)&&i.publicSafe===!0):!1})}function Kt(t){return!Array.isArray(t)||t.length>1024?!1:t.every(e=>{const i=f(e);return i?(D(i,["schemaVersion","resourceId","action","managed","reasonCodes","evidence","publicSafe"],"git-lifecycle-runtime-reconciliation-debt-unknown-field"),i.schemaVersion===1&&E(i.resourceId)&&i.action==="preserve"&&typeof i.managed=="boolean"&&P(i.reasonCodes,128)&&P(i.evidence,16)&&i.publicSafe===!0):!1})}function D(t,e,i){const r=new Set(e);if(Object.keys(t).some(n=>!r.has(n)))throw new Error(i)}function X(t){return typeof t=="string"&&/^P[1-9][0-9]*(?:\.[0-9]+)*$/.test(t)}function W(t){return typeof t=="string"&&/^[A-Za-z0-9][A-Za-z0-9._/-]{0,239}$/.test(t)&&!t.includes("..")&&!t.includes("//")&&!t.includes("@{")&&!t.endsWith("/")&&!t.endsWith(".")&&!t.split("/").some(e=>!e||e.startsWith(".")||e.endsWith(".lock"))}function de(t){return t.length>0&&t.length<=1024&&!ee(t)&&!t.includes("\0")&&!t.replaceAll("\\","/").split("/").includes("..")}function E(t){return typeof t=="string"&&t.length>0&&t.length<=240&&/^[A-Za-z0-9._:/#\-[\]]+$/.test(t)&&!t.includes("..")}function fe(t){return E(t)}function w(t){return typeof t=="string"&&/^[a-f0-9]{40,64}$/i.test(t)}function g(t){return typeof t=="string"&&/^[a-f0-9]{64}$/i.test(t)}function x(t){return typeof t=="string"&&t.length<=64&&Number.isFinite(Date.parse(t))}function P(t,e,i=!1){return Array.isArray(t)&&t.length<=e&&(!i||t.length>0)&&t.every(E)}function Mt(t){return Array.isArray(t)&&t.length>0&&t.length<=256&&t.every(w)}function Re(){return{schemaVersion:1,revision:0,epics:{},stories:{}}}async function Wt(t){const e=z(t),i={pid:process.pid,nonce:ye(16).toString("hex")},r=async()=>{await H(e),await Pe(e,R(t),JSON.stringify(i));try{await b(t,e),await T(p(t,"owner.json"),t)}catch(n){throw await M(t,e).catch(()=>{}),n}};try{await r()}catch(n){if(!_(n,"EEXIST"))throw n;await L(t,"directory");const a=await Ee(t);if(a!==void 0&&ue(a.pid))throw new Error("git-lifecycle-runtime-lock-active");if(a===void 0&&await Je(t))throw new Error("git-lifecycle-runtime-lock-active");const o=await I(t);if(!o)throw new Error("git-lifecycle-runtime-lock-owner-invalid");const s=`${t}.stale.${process.pid}.${Date.now()}`;await Q(e,R(t),R(s));try{if(await b(s,e),await I(s)!==o)throw await re(s,t,e).catch(()=>{}),new Error("git-lifecycle-runtime-lock-owner-replaced");await r()}finally{await M(s,e,async u=>await I(u)===o).catch(()=>{})}}return i}async function Yt(t,e){const i=z(t);try{await b(t,i);const r=await Ee(t);if(!r||!Qe(r,e))return!1;const n=await I(t);if(!n)return!1;const a=`${t}.release.${process.pid}.${Date.now()}`;await Q(i,R(t),R(a)),await b(a,i);const o=await Ee(a);return!o||!Qe(o,e)||await I(a)!==n?(await re(a,t,i).catch(()=>{}),!1):M(a,i,async s=>await I(s)===n)}catch(r){if(_(r,"ENOENT"))return!1;throw r}}async function Je(t){try{return Date.now()-(await rt(t)).mtimeMs<3e4}catch{return!0}}async function Ee(t){try{await b(t,z(t));const e=p(t,"owner.json");await T(e,t);const i=JSON.parse(await F(e,"utf8"));return Number.isSafeInteger(i.pid)&&Number(i.pid)>0&&(i.nonce===void 0||typeof i.nonce=="string"&&/^[a-f0-9]{32}$/.test(i.nonce))?{pid:Number(i.pid),...typeof i.nonce=="string"?{nonce:i.nonce}:{}}:void 0}catch{return}}function Qe(t,e){return t.pid===e.pid&&t.nonce!==void 0&&t.nonce===e.nonce}function ue(t){try{return process.kill(t,0),!0}catch(e){return _(e,"EPERM")}}function f(t){return t&&typeof t=="object"&&!Array.isArray(t)?t:void 0}function _(t,e){return t instanceof Error&&"code"in t&&t.code===e}export{ce as GIT_LIFECYCLE_RUNTIME_DIRECTORY,oe as GIT_LIFECYCLE_RUNTIME_FILE,Ve as LEGACY_DIRECT_YOLO_RECOVERY_COMMITS,ft as LEGACY_P174_CHECKPOINT_MIGRATIONS,O as P205_COMPLETE_COMMAND,pi as acquireGitLifecyclePhysicalIntegrationLock,oi as applyGitLifecycleRuntimeOverlay,b as assertGitLifecyclePrivateDirectory,mi as assertGitLifecyclePrivateFile,_t as computeGitLifecyclePhysicalIntegrationLockOwnerDigest,St as computeImmutableStoryQaEvidenceDigest,hi as computeLegacyDirectYoloRecoveryReceiptRef,vt as computeP205StoryQaEvidenceDigest,Rt as ensureGitLifecyclePrivateChildDirectory,si as ensureRuntimeEpic,di as ensureRuntimeStory,ni as executeP205TransientAuthority,He as gitLifecycleRuntimeDirectory,bt as gitLifecycleStoryWriteSet,Le as isAcceptedGitLifecycleStoryCheckpoint,ci as mutateGitLifecycleRuntime,gi as p205TransientAuthorityMatchesAggregate,se as posixSecurityAvailable,ui as projectP205TransientExecutionEvidence,ai as readGitLifecycleRuntime,gt as readGitLifecycleRuntimeSync,Et as releaseGitLifecyclePhysicalIntegrationLock,bi as releaseGitLifecyclePhysicalIntegrationLockForCheckpoint,M as removeGitLifecyclePrivateDirectory,fi as verifyAcceptedGitLifecycleStoryCheckpoint,ht as verifyAcceptedGitLifecycleStoryCheckpointSync,yi as verifyGitLifecyclePhysicalIntegrationLock,li as verifyLegacyCheckpointMigrationCandidateSync};
@@ -0,0 +1,26 @@
1
+ export interface AnchoredFilesystemTestOptions {
2
+ /** Deterministic race hook after identity capture and before cwd handoff. */
3
+ readonly beforeHandoff?: () => Promise<void> | void;
4
+ /** Deterministic observer after the helper owns the validated child cwd. */
5
+ readonly afterHandoff?: () => Promise<void> | void;
6
+ /** Test-only platform seam; production always uses process.platform. */
7
+ readonly platform?: NodeJS.Platform;
8
+ }
9
+ export interface AnchoredDirectoryIdentity {
10
+ readonly dev: string;
11
+ readonly ino: string;
12
+ }
13
+ export declare function secureFilesystemBoundaryAvailable(platform?: NodeJS.Platform): boolean;
14
+ export declare function anchoredAtomicWriteFile(parent: string, name: string, content: Buffer | string, options?: AnchoredFilesystemTestOptions): Promise<void>;
15
+ export declare function anchoredRemoveFile(parent: string, name: string, options?: AnchoredFilesystemTestOptions): Promise<void>;
16
+ export declare function anchoredEnsureDirectory(parent: string, name: string, options?: AnchoredFilesystemTestOptions): Promise<void>;
17
+ export declare function anchoredCreateDirectory(parent: string, name: string): Promise<AnchoredDirectoryIdentity>;
18
+ export declare function anchoredDirectoryIdentity(path: string): Promise<AnchoredDirectoryIdentity>;
19
+ /** Execute Git only after a helper owns and revalidates the sandbox directory cwd. */
20
+ export declare function anchoredExecuteGit(parent: string, name: string, expectedChild: AnchoredDirectoryIdentity, args: readonly string[], input?: Buffer | string, options?: AnchoredFilesystemTestOptions): Promise<Buffer>;
21
+ /** Gate commands inherit a pinned cwd, never a mutable sandbox pathname. */
22
+ export declare function anchoredExecuteNode(parent: string, name: string, expectedChild: AnchoredDirectoryIdentity, args: readonly string[], input?: Buffer | string, options?: AnchoredFilesystemTestOptions): Promise<Buffer>;
23
+ export declare function anchoredExecuteNpm(parent: string, name: string, expectedChild: AnchoredDirectoryIdentity, args: readonly string[]): Promise<Buffer>;
24
+ export declare function anchoredCreateOwnedDirectory(parent: string, name: string, owner: Buffer | string): Promise<void>;
25
+ export declare function anchoredRenameDirectory(parent: string, sourceName: string, destinationName: string, options?: AnchoredFilesystemTestOptions): Promise<void>;
26
+ export declare function anchoredRemoveDirectory(parent: string, name: string, options?: AnchoredFilesystemTestOptions): Promise<void>;
@@ -0,0 +1,123 @@
1
+ import{spawn as b}from"node:child_process";import{randomBytes as k}from"node:crypto";import{lstat as w,stat as v}from"node:fs/promises";const B=String.raw`
2
+ const fs = require('node:fs');
3
+ const [op, expectedDev, expectedIno, name, temporary] = process.argv.slice(1);
4
+ const fail = (code) => { process.stderr.write(code); process.exit(73); };
5
+ process.on('uncaughtException', (error) => fail('secure-filesystem-os:' + String(error && error.code || 'UNKNOWN')));
6
+ const safe = (value) => typeof value === 'string' && value.length > 0 && value.length <= 255
7
+ && !value.includes('/') && !value.includes('\\') && !value.includes('\0') && value !== '.' && value !== '..';
8
+ if (!safe(name) || (temporary && !safe(temporary))) fail('secure-filesystem-name-invalid');
9
+ const cwd = fs.statSync('.', { bigint: true });
10
+ if (String(cwd.dev) !== expectedDev || String(cwd.ino) !== expectedIno || !cwd.isDirectory()) {
11
+ fail('secure-filesystem-anchor-mismatch');
12
+ }
13
+ const noFollow = fs.constants.O_NOFOLLOW || 0;
14
+ const safeExisting = (target, kind) => {
15
+ try {
16
+ const item = fs.lstatSync(target, { bigint: true });
17
+ if (item.isSymbolicLink() || (kind === 'file' && !item.isFile()) || (kind === 'directory' && !item.isDirectory())) {
18
+ fail('secure-filesystem-entry-unsafe');
19
+ }
20
+ return item;
21
+ } catch (error) {
22
+ if (error && error.code === 'ENOENT') return null;
23
+ throw error;
24
+ }
25
+ };
26
+ const readStdin = () => fs.readFileSync(0);
27
+ if (op === 'mkdir' || op === 'mkdir-exclusive') {
28
+ try { fs.mkdirSync(name, { mode: 0o700 }); } catch (error) {
29
+ if (!error || error.code !== 'EEXIST') throw error;
30
+ if (op === 'mkdir-exclusive') fail('secure-filesystem-entry-exists');
31
+ }
32
+ const created = safeExisting(name, 'directory') || fail('secure-filesystem-directory-missing');
33
+ if (op === 'mkdir-exclusive') process.stdout.write('secure-filesystem-identity:' + String(created.dev) + ':' + String(created.ino));
34
+ } else if (op === 'create-owned-directory') {
35
+ fs.mkdirSync(name, { mode: 0o700 });
36
+ const created = safeExisting(name, 'directory') || fail('secure-filesystem-directory-missing');
37
+ process.chdir(name);
38
+ const handed = fs.statSync('.', { bigint: true });
39
+ if (created.dev !== handed.dev || created.ino !== handed.ino) fail('secure-filesystem-anchor-mismatch');
40
+ const fd = fs.openSync('owner.json', fs.constants.O_CREAT | fs.constants.O_EXCL | fs.constants.O_WRONLY | noFollow, 0o600);
41
+ try { fs.writeFileSync(fd, readStdin()); fs.fsyncSync(fd); } finally { fs.closeSync(fd); }
42
+ safeExisting('owner.json', 'file') || fail('secure-filesystem-owner-missing');
43
+ try { const child = fs.openSync('.', fs.constants.O_RDONLY); fs.fsyncSync(child); fs.closeSync(child); } catch {}
44
+ } else if (op === 'write') {
45
+ safeExisting(name, 'file');
46
+ const fd = fs.openSync(temporary, fs.constants.O_CREAT | fs.constants.O_EXCL | fs.constants.O_WRONLY | noFollow, 0o600);
47
+ try {
48
+ fs.writeFileSync(fd, readStdin());
49
+ fs.fsyncSync(fd);
50
+ } finally { fs.closeSync(fd); }
51
+ safeExisting(temporary, 'file') || fail('secure-filesystem-temporary-missing');
52
+ safeExisting(name, 'file');
53
+ fs.renameSync(temporary, name);
54
+ safeExisting(name, 'file') || fail('secure-filesystem-destination-missing');
55
+ } else if (op === 'remove') {
56
+ const item = safeExisting(name, 'file');
57
+ if (item) fs.unlinkSync(name);
58
+ } else if (op === 'rename-directory') {
59
+ safeExisting(name, 'directory') || fail('secure-filesystem-directory-missing');
60
+ if (safeExisting(temporary, 'directory')) fail('secure-filesystem-destination-exists');
61
+ fs.renameSync(name, temporary);
62
+ safeExisting(temporary, 'directory') || fail('secure-filesystem-destination-missing');
63
+ } else if (op === 'remove-directory') {
64
+ const item = safeExisting(name, 'directory');
65
+ if (item) fs.rmSync(name, { recursive: true, force: false, maxRetries: 0 });
66
+ if (safeExisting(name, 'directory')) fail('secure-filesystem-directory-remained');
67
+ } else fail('secure-filesystem-operation-invalid');
68
+ try { const parent = fs.openSync('.', fs.constants.O_RDONLY); fs.fsyncSync(parent); fs.closeSync(parent); } catch {}
69
+ `,R=String.raw`
70
+ const fs = require('node:fs');
71
+ const cp = require('node:child_process');
72
+ const [expectedParentDev, expectedParentIno, name, expectedChildDev, expectedChildIno, encodedArgs, handshake, binary] = process.argv.slice(1);
73
+ const fail = (code) => { process.stderr.write(code); process.exit(73); };
74
+ process.on('uncaughtException', (error) => fail('secure-git-os:' + String(error && error.code || 'UNKNOWN')));
75
+ const safeName = typeof name === 'string' && name.length > 0 && name.length <= 255
76
+ && !name.includes('/') && !name.includes('\\') && !name.includes('\0') && name !== '.' && name !== '..';
77
+ if (!safeName) fail('secure-git-name-invalid');
78
+ const parent = fs.statSync('.', { bigint: true });
79
+ if (!parent.isDirectory() || String(parent.dev) !== expectedParentDev || String(parent.ino) !== expectedParentIno) {
80
+ fail('secure-git-parent-anchor-mismatch');
81
+ }
82
+ const child = fs.lstatSync(name, { bigint: true });
83
+ if (!child.isDirectory() || child.isSymbolicLink()
84
+ || String(child.dev) !== expectedChildDev || String(child.ino) !== expectedChildIno) {
85
+ fail('secure-git-child-anchor-mismatch');
86
+ }
87
+ process.chdir(name);
88
+ const handed = fs.statSync('.', { bigint: true });
89
+ if (!handed.isDirectory() || String(handed.dev) !== expectedChildDev || String(handed.ino) !== expectedChildIno) {
90
+ fail('secure-git-handoff-mismatch');
91
+ }
92
+ if (handshake === '1') process.stderr.write('secure-git-handoff-ready\n');
93
+ const input = fs.readFileSync(0);
94
+ let args;
95
+ try { args = JSON.parse(Buffer.from(encodedArgs, 'base64url').toString('utf8')); } catch { fail('secure-git-args-invalid'); }
96
+ if (!Array.isArray(args) || args.length === 0 || args.length > 512
97
+ || args.some((arg) => typeof arg !== 'string' || arg.length > 4096 || arg.includes('\0'))) {
98
+ fail('secure-git-args-invalid');
99
+ }
100
+ process.umask(0o077);
101
+ if (!['git', 'node', 'npm'].includes(binary)) fail('secure-git-command-invalid');
102
+ const maxOutputBytes = binary === 'git' ? 16 * 1024 * 1024 : 64 * 1024 * 1024;
103
+ const gitEnv = { ...process.env, GIT_OPTIONAL_LOCKS: '1' };
104
+ for (const key of ['GIT_DIR', 'GIT_WORK_TREE', 'GIT_INDEX_FILE', 'GIT_OBJECT_DIRECTORY',
105
+ 'GIT_ALTERNATE_OBJECT_DIRECTORIES', 'GIT_COMMON_DIR', 'GIT_NAMESPACE', 'GIT_CEILING_DIRECTORIES']) delete gitEnv[key];
106
+ if (binary !== 'git') {
107
+ for (const key of ['NODE_OPTIONS', 'NODE_PATH', 'NEOCORTEX_RELEASE_GATE_MANIFEST']) delete gitEnv[key];
108
+ gitEnv.npm_config_global = 'false';
109
+ }
110
+ const result = cp.spawnSync(binary === 'node' ? process.execPath : binary, args, {
111
+ input,
112
+ encoding: null,
113
+ maxBuffer: maxOutputBytes,
114
+ windowsHide: true,
115
+ env: gitEnv,
116
+ });
117
+ if (result.error) fail('secure-git-command-error:' + String(result.error.code || 'UNKNOWN'));
118
+ if (result.status !== 0) fail('secure-git-command-failed:' + String(Number.isInteger(result.status) ? result.status : 1));
119
+ if (result.stdout && result.stdout.length > maxOutputBytes) fail('secure-git-output-too-large');
120
+ if (result.stdout) process.stdout.write(result.stdout);
121
+ `;function x(r=process.platform){return r!=="win32"}async function G(r,e,t,i={}){const n=`.${e}.${process.pid}.${k(8).toString("hex")}.tmp`;await m(r,["write",e,n],Buffer.isBuffer(t)?t:Buffer.from(t),i)}async function P(r,e,t={}){await m(r,["remove",e],void 0,t)}async function H(r,e,t={}){await m(r,["mkdir",e],void 0,t)}async function W(r,e){const i=(await m(r,["mkdir-exclusive",e])).toString("utf8").match(/^secure-filesystem-identity:([0-9]+):([0-9]+)$/);if(!i)throw new Error("secure-filesystem-created-identity-missing");return Object.freeze({dev:i[1],ino:i[2]})}async function X(r){if(!x())throw new Error("secure-filesystem-platform-unsupported");const e=await w(r,{bigint:!0}),t=await v(r,{bigint:!0});if(e.isSymbolicLink()||!e.isDirectory()||!t.isDirectory()||e.dev!==t.dev||e.ino!==t.ino)throw new Error("secure-filesystem-directory-unsafe");return Object.freeze({dev:String(t.dev),ino:String(t.ino)})}async function K(r,e,t,i,n,c={}){return O("git",r,e,t,i,n,c)}async function Y(r,e,t,i,n,c={}){return O("node",r,e,t,i,n,c)}async function $(r,e,t,i){return O("npm",r,e,t,i)}async function O(r,e,t,i,n,c,f={}){if(!x(f.platform??process.platform))throw new Error("secure-filesystem-platform-unsupported");if(n.length===0||n.length>512||n.some(a=>typeof a!="string"||a.length>4096||a.includes("\0")))throw new Error("secure-git-args-invalid");const d=await v(e,{bigint:!0}),s=await w(e,{bigint:!0});if(!d.isDirectory()||s.isSymbolicLink()||!s.isDirectory()||d.dev!==s.dev||d.ino!==s.ino)throw new Error("secure-filesystem-parent-invalid");await f.beforeHandoff?.();const y=r==="git"?16*1024*1024:64*1024*1024;return await new Promise((a,p)=>{const l=f.afterHandoff?"1":"0",g=Buffer.from(JSON.stringify([...n])).toString("base64url"),o=b(process.execPath,["-e",R,String(d.dev),String(d.ino),t,i.dev,i.ino,g,l,r],{cwd:e,stdio:["pipe","pipe","pipe"]}),h=[],E=[];let S=0,I=!f.afterHandoff,_=!1;const N=async()=>{if(!_){_=!0;try{await f.afterHandoff?.(),I=!0,o.stdin.end(c===void 0?void 0:Buffer.isBuffer(c)?c:Buffer.from(c))}catch(u){o.kill(),p(u)}}};o.stdout.on("data",u=>{S+=u.length,S>y?o.kill():h.push(u)}),o.stderr.on("data",u=>{E.push(u),!I&&Buffer.concat(E).includes(Buffer.from(`secure-git-handoff-ready
122
+ `))&&N()}),o.once("error",p),o.once("close",u=>{if(u===0&&S<=y)return a(Buffer.concat(h));const T=Buffer.concat(E).toString("utf8").split(`
123
+ `).find(D=>D.startsWith("secure-git-")&&D!=="secure-git-handoff-ready")??(S>y?"secure-git-output-too-large":"secure-git-helper-failed");p(new Error(T))}),f.afterHandoff||N()})}async function J(r,e,t){await m(r,["create-owned-directory",e],Buffer.isBuffer(t)?t:Buffer.from(t))}async function M(r,e,t,i={}){await m(r,["rename-directory",e,t],void 0,i)}async function q(r,e,t={}){await m(r,["remove-directory",e],void 0,t)}async function m(r,e,t,i={}){if(!x(i.platform??process.platform))throw new Error("secure-filesystem-platform-unsupported");const n=await v(r,{bigint:!0});if(!n.isDirectory())throw new Error("secure-filesystem-parent-invalid");if((await w(r,{bigint:!0})).isSymbolicLink())throw new Error("secure-filesystem-parent-symlink");return await i.beforeHandoff?.(),await new Promise((f,d)=>{const s=b(process.execPath,["-e",B,...e.slice(0,1),String(n.dev),String(n.ino),...e.slice(1)],{cwd:r,stdio:["pipe","pipe","pipe"]}),y=[];let a=0;const p=[];s.stdout.on("data",l=>{a+=l.length,a>1024?s.kill():y.push(l)}),s.stderr.on("data",l=>p.push(l)),s.once("error",d),s.once("close",l=>{if(l===0&&a<=1024)return f(Buffer.concat(y));const g=Buffer.concat(p).toString("utf8")||"secure-filesystem-helper-failed",o=new Error(g),h=g.match(/^secure-filesystem-os:(E[A-Z0-9]+)$/)?.[1];h&&(o.code=h),g==="secure-filesystem-entry-exists"&&(o.code="EEXIST"),d(o)}),s.stdin.end(t)})}export{G as anchoredAtomicWriteFile,W as anchoredCreateDirectory,J as anchoredCreateOwnedDirectory,X as anchoredDirectoryIdentity,H as anchoredEnsureDirectory,K as anchoredExecuteGit,Y as anchoredExecuteNode,$ as anchoredExecuteNpm,q as anchoredRemoveDirectory,P as anchoredRemoveFile,M as anchoredRenameDirectory,x as secureFilesystemBoundaryAvailable};
@@ -17,6 +17,17 @@ export interface GraphRetrievalHookContext {
17
17
  readonly logger?: {
18
18
  readonly warn?: (msg: string) => void;
19
19
  };
20
+ /** Injectable filesystem seam keeps failure-path tests portable across OS/users. */
21
+ readonly fileReader?: GraphRetrievalFileReader;
22
+ }
23
+ export interface GraphRetrievalFileReader {
24
+ readonly exists: (path: string) => boolean;
25
+ readonly stat: (path: string) => {
26
+ readonly size: number;
27
+ readonly mtimeMs: number;
28
+ isFile(): boolean;
29
+ };
30
+ readonly readText: (path: string) => string;
20
31
  }
21
32
  export type GraphRetrievalCommand = string;
22
33
  export type GraphRetrievalEnrichmentMetadata = GraphRetrievalMetadata & {
@@ -1 +1 @@
1
- import{createHash as T}from"node:crypto";import{existsSync as I,readFileSync as h,statSync as P}from"node:fs";import{join as y}from"node:path";import{DEFAULT_GRAPH_RETRIEVAL_BUDGETS as g,createGraphRetrievalMetadata as b,normalizeGraphRetrievalPath as i,resolveClientCommandContextPolicy as E}from"./shared-graph-retrieval-contract.js";import{admitInvocation as A}from"../../../shared/dist/invocation/index.js";const u="client-pre-command-v1",x="1970-01-01T00:00:00.000Z",R=new Set([".archive","_archive","_archives","archive","archives","archived"]);function S(t){return A(t)}function k(t){const e=S(t);if(e.outcome!=="resolved")return null;const o=E(e.selection.commandId);return o?{policy:o,selection:e.selection}:null}function p(t){return T("sha256").update(t).digest("hex")}function m(t){const e=i(t),o=e.split("/").some(n=>R.has(n.toLowerCase()));return e.length===0||e.startsWith("/")||e.startsWith("..")||e.includes("/../")||o||/(^|\/)\.env(?:$|[./-])/i.test(e)||/(^|\/)(?:credentials?|secrets?|tokens?|private-prompts?|raw-logs?)(?:\.|\/|$)/i.test(e)||/\.(?:sqlite|db|pem|key|p12|pfx|crt|cer|der|bin)$/i.test(e)}function $(t,e){const o=i(e);if(m(o))return null;const n=y(t,o);if(!I(n))return null;const r=P(n);if(!r.isFile()||r.size>96*1024)return null;const s=h(n,"utf8");return{kind:"repo-path",path:o,contentHash:p(s).slice(0,16),mtimeMs:Math.floor(r.mtimeMs)}}function _(t){let e=t;const o=e;return e=e.replace(/[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}/gi,"[REDACTED_EMAIL]"),e=e.replace(/\b(api[-_ ]?key|license[-_ ]?key|token|password|secret)\b\s*[:=]\s*[^\s`'"\])}]+/gi,"$1=[REDACTED_SECRET]"),e=e.replace(/\b(?:sk|pk|ghp|github_pat|pat)_[A-Za-z0-9_\-]{16,}\b/g,"[REDACTED_TOKEN]"),e=e.replace(/\b[A-Za-z0-9+/]{32,}={0,2}\b/g,"[REDACTED_TOKEN]"),e=e.replace(/<!--\s*(?:server|private|proprietary)[\s\S]*?-->/gi,"[REDACTED_PRIVATE_PROMPT]"),e=e.replace(/\b(?:private|proprietary|protected)\s+(?:prompt|workflow|step\s*body|orchestration)\b[^.!?\n]*/gi,"[REDACTED_PRIVATE_PROMPT]"),{text:e,redacted:e!==o}}function w(t,e=g.maxSnippetChars){const o=t.split(/\r?\n/).map(r=>r.trim()).filter(r=>r.length>0&&!r.startsWith("---")&&!r.startsWith("<!--")).slice(0,8).join(" "),n=_(o);return{summary:n.text.slice(0,e),redacted:n.redacted}}function D(t,e){const o=$(t,e.path);if(!o)return null;const n=h(y(t,o.path),"utf8"),r=w(n,e.maxSnippetChars);return{nodeType:e.nodeType,stableId:e.stableId,source:o,confidence:r.redacted?Math.min(e.confidence,.72):e.confidence,reasonCode:e.reasonCode,budgetCost:e.budgetCost,summary:r.summary,warnings:r.redacted?["redacted_sensitive_content"]:void 0,score:e.score}}function G(t){const e=`Public command ${t.commandId}; graphRetrieval profile ${t.retrievalProfile}; context is auxiliary, redacted, budgeted and non-authoritative.`;return{nodeType:"Command",stableId:`command:${t.commandId}`,source:{kind:"command",path:t.commandId,contentHash:p(e).slice(0,16)},confidence:.88,reasonCode:"command_surface_match",budgetCost:1,summary:e.slice(0,t.retrievalBudget.maxSnippetChars),score:90}}function M(t){const e=t.uiUxReview?.architectureDir;return e?[...t.positionals,e]:t.positionals}function C(t){return t.find(o=>/^@?docs\/stories\/[A-Za-z0-9._-]+\.story\.md$/u.test(o))?.replace(/^@/u,"")??null}function z(t){return t.find(o=>/^@?docs\/epics\/[A-Za-z0-9._-]+\.md$/u.test(o))?.replace(/^@/u,"")??null}function B(t){const n=C(t)?.split("/").pop()?.replace(/\.story\.md$/,"")?.match(/^(P\d+)\./i)?.[1];if(n)return n.toUpperCase();const r=t.map(s=>s.match(/^@?(?:docs\/epics\/epic-)?(P\d+)(?:\.md)?$/iu)?.[1]).find(s=>!!s);return r?r.toUpperCase():null}function H(t){return t.map(e=>e.match(/^@?((?:docs|core)\/[A-Za-z0-9_./-]+\.md)$/u)?.[1]).filter(e=>!!e).map(e=>i(e)).filter(e=>!m(e))}function N(t){return t.startsWith("docs/stories/")?{nodeType:"Story",reasonCode:"story_scope_match"}:t.startsWith("docs/epics/")?{nodeType:"Epic",reasonCode:"epic_scope_match"}:t.includes("security")||t.includes("policy")||t.includes("standard")?{nodeType:"Guardrail",reasonCode:"guardrail_match"}:{nodeType:"Doc",reasonCode:"architecture_reference"}}function c(t,e){const o=i(e.path);if(m(o))return;t.some(r=>r.nodeType===e.nodeType&&i(r.path)===o)||t.push({...e,path:o})}function O(t,e,o){const n=C(e);if(n){const a=n.split("/").pop()?.replace(/\.story\.md$/,"")??n;c(t,{path:n,nodeType:"Story",stableId:a,reasonCode:"story_scope_match",confidence:.96,budgetCost:3,score:96,maxSnippetChars:o})}const r=z(e),s=B(e);if(r){const a=r.split("/").pop()?.replace(/\.md$/,"")??r;c(t,{path:r,nodeType:"Epic",stableId:a,reasonCode:"epic_scope_match",confidence:.92,budgetCost:3,score:92,maxSnippetChars:o})}else s&&c(t,{path:`docs/epics/epic-${s}.md`,nodeType:"Epic",stableId:s,reasonCode:"epic_scope_match",confidence:.9,budgetCost:3,score:90,maxSnippetChars:o});for(const a of H(e)){const d=a.split("/").pop()?.replace(/\.md$/,"").replace(/\.story$/,"")??a,l=N(a);c(t,{path:a,stableId:d,...l,confidence:.84,budgetCost:3,score:82,maxSnippetChars:o})}}function Z(t,e,o){const n=t.retrievalBudget.maxSnippetChars,r=[];return c(r,{path:"NEOCORTEX.md",nodeType:"CanonicalMemory",stableId:"canonical-memory",reasonCode:"canonical_memory_seed",confidence:.92,budgetCost:4,score:100,maxSnippetChars:n}),c(r,{path:"AGENTS.md",nodeType:"PlatformMemory",stableId:"platform-memory:agents",reasonCode:"platform_memory_reference",confidence:.7,budgetCost:2,score:66,maxSnippetChars:n}),c(r,{path:"package.json",nodeType:"Package",stableId:"root-package",reasonCode:"package_surface_match",confidence:.78,budgetCost:2,score:72,maxSnippetChars:n}),(t.retrievalProfile!=="utility"||t.commandId==="ui-ux-review")&&c(r,{path:"docs/arquitetura-software/deterministic-graph-retrieval.md",nodeType:"Doc",stableId:"deterministic-graph-retrieval",reasonCode:"architecture_reference",confidence:.9,budgetCost:4,score:84,maxSnippetChars:n}),O(r,M(e),n),(["story-execution","diagnostic","research","review","qa","recovery","planning"].includes(t.retrievalProfile)||t.commandId==="tech-debt")&&c(r,{path:".neocortex/tech-debt-registry.json",nodeType:"Debt",stableId:"tech-debt-registry",reasonCode:"debt_area_match",confidence:.74,budgetCost:3,score:76,maxSnippetChars:n}),["story-execution","diagnostic","research","review","qa","recovery","planning","architecture"].includes(t.retrievalProfile)&&c(r,{path:"core/standards/spec-driven-development.md",nodeType:"Guardrail",stableId:"spec-driven-development",reasonCode:"guardrail_match",confidence:.82,budgetCost:3,score:78,maxSnippetChars:n}),t.retrievalProfile==="security"&&c(r,{path:"docs/architecture/solyd-security-system-contract.md",nodeType:"Guardrail",stableId:"solyd-security-system-contract",reasonCode:"guardrail_match",confidence:.86,budgetCost:3,score:84,maxSnippetChars:n}),t.retrievalProfile==="continuity"&&(c(r,{path:"core/standards/enterprise-continuity-plane.md",nodeType:"Guardrail",stableId:"enterprise-continuity-plane",reasonCode:"guardrail_match",confidence:.86,budgetCost:3,score:84,maxSnippetChars:n}),c(r,{path:"docs/runbooks/enterprise-continuity-runner.md",nodeType:"Doc",stableId:"enterprise-continuity-runner",reasonCode:"architecture_reference",confidence:.78,budgetCost:3,score:72,maxSnippetChars:n})),["utility","continuity","recovery"].includes(t.retrievalProfile)&&c(r,{path:".neocortex/state.json",nodeType:"State",stableId:"project-state",reasonCode:"state_status_match",confidence:.68,budgetCost:3,score:70,maxSnippetChars:n}),[G(t),...r.map(s=>D(o,s)).filter(s=>s!==null)]}function j(t){let e=[...t.items],o=t;const n=Math.min(t.budget.maxPayloadBytes,g.maxPayloadBytes);for(;Buffer.byteLength(JSON.stringify(o),"utf8")>n&&e.length>0;){const r=e.pop(),s=b({retrievalId:t.retrievalId,query:t.query,items:e,generatedAt:t.generatedAt,warnings:t.warnings,budgets:t.budget});o={...s,skipped:r?[...s.skipped,{stableId:r.stableId,source:r.source,reasonCode:"budget_exceeded"}]:s.skipped,contractVersion:u,command:t.command}}return o}async function W(t){const e=k(t.args);if(!e)return{applied:!1,reason:"command_not_allowlisted"};const{policy:o,selection:n}=e,r=o.commandId;try{const s=Z(o,n,t.projectRoot);if(s.length===0)return{applied:!1,reason:"no_items",command:r,profile:o.retrievalProfile};const a=_(n.positionals.join(" ").slice(0,240)).text,d=p(`${u}:${r}:${a}:${s.map(f=>`${f.source.path}:${f.source.contentHash??""}`).sort().join("|")}`).slice(0,24),l=b({retrievalId:d,query:a,items:s,generatedAt:t.nowIso??x,budgets:o.retrievalBudget}),v=j({...l,contractVersion:u,command:r});return{applied:!0,reason:"applied",command:r,profile:o.retrievalProfile,metadata:v}}catch(s){const a=s instanceof Error?s.message:String(s);return t.logger?.warn?.(`[neocortex] graph retrieval hook failed: ${a}. Proceeding without enrichment.`),{applied:!1,reason:"hook_error",command:r,profile:o.retrievalProfile,warning:a}}}export{S as admitGraphInvocation,W as runGraphRetrievalHook};
1
+ import{createHash as v}from"node:crypto";import{existsSync as T,readFileSync as I,statSync as E}from"node:fs";import{join as h}from"node:path";import{DEFAULT_GRAPH_RETRIEVAL_BUDGETS as y,createGraphRetrievalMetadata as g,normalizeGraphRetrievalPath as i,resolveClientCommandContextPolicy as P}from"./shared-graph-retrieval-contract.js";import{admitInvocation as A}from"../../../shared/dist/invocation/index.js";const u="client-pre-command-v1",x="1970-01-01T00:00:00.000Z",R=new Set([".archive","_archive","_archives","archive","archives","archived"]),S=Object.freeze({exists:T,stat:E,readText:e=>I(e,"utf8")});function k(e){return A(e)}function $(e){const t=k(e);if(t.outcome!=="resolved")return null;const o=P(t.selection.commandId);return o?{policy:o,selection:t.selection}:null}function p(e){return v("sha256").update(e).digest("hex")}function m(e){const t=i(e),o=t.split("/").some(s=>R.has(s.toLowerCase()));return t.length===0||t.startsWith("/")||t.startsWith("..")||t.includes("/../")||o||/(^|\/)\.env(?:$|[./-])/i.test(t)||/(^|\/)(?:credentials?|secrets?|tokens?|private-prompts?|raw-logs?)(?:\.|\/|$)/i.test(t)||/\.(?:sqlite|db|pem|key|p12|pfx|crt|cer|der|bin)$/i.test(t)}function D(e,t,o){const s=i(t);if(m(s))return null;const r=h(e,s);if(!o.exists(r))return null;const n=o.stat(r);if(!n.isFile()||n.size>96*1024)return null;const a=o.readText(r);return{kind:"repo-path",path:s,contentHash:p(a).slice(0,16),mtimeMs:Math.floor(n.mtimeMs)}}function b(e){let t=e;const o=t;return t=t.replace(/[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}/gi,"[REDACTED_EMAIL]"),t=t.replace(/\b(api[-_ ]?key|license[-_ ]?key|token|password|secret)\b\s*[:=]\s*[^\s`'"\])}]+/gi,"$1=[REDACTED_SECRET]"),t=t.replace(/\b(?:sk|pk|ghp|github_pat|pat)_[A-Za-z0-9_\-]{16,}\b/g,"[REDACTED_TOKEN]"),t=t.replace(/\b[A-Za-z0-9+/]{32,}={0,2}\b/g,"[REDACTED_TOKEN]"),t=t.replace(/<!--\s*(?:server|private|proprietary)[\s\S]*?-->/gi,"[REDACTED_PRIVATE_PROMPT]"),t=t.replace(/\b(?:private|proprietary|protected)\s+(?:prompt|workflow|step\s*body|orchestration)\b[^.!?\n]*/gi,"[REDACTED_PRIVATE_PROMPT]"),{text:t,redacted:t!==o}}function w(e,t=y.maxSnippetChars){const o=e.split(/\r?\n/).map(r=>r.trim()).filter(r=>r.length>0&&!r.startsWith("---")&&!r.startsWith("<!--")).slice(0,8).join(" "),s=b(o);return{summary:s.text.slice(0,t),redacted:s.redacted}}function G(e,t,o){const s=D(e,t.path,o);if(!s)return null;const r=o.readText(h(e,s.path)),n=w(r,t.maxSnippetChars);return{nodeType:t.nodeType,stableId:t.stableId,source:s,confidence:n.redacted?Math.min(t.confidence,.72):t.confidence,reasonCode:t.reasonCode,budgetCost:t.budgetCost,summary:n.summary,warnings:n.redacted?["redacted_sensitive_content"]:void 0,score:t.score}}function M(e){const t=`Public command ${e.commandId}; graphRetrieval profile ${e.retrievalProfile}; context is auxiliary, redacted, budgeted and non-authoritative.`;return{nodeType:"Command",stableId:`command:${e.commandId}`,source:{kind:"command",path:e.commandId,contentHash:p(t).slice(0,16)},confidence:.88,reasonCode:"command_surface_match",budgetCost:1,summary:t.slice(0,e.retrievalBudget.maxSnippetChars),score:90}}function z(e){const t=e.uiUxReview?.architectureDir;return t?[...e.positionals,t]:e.positionals}function _(e){return e.find(o=>/^@?docs\/stories\/[A-Za-z0-9._-]+\.story\.md$/u.test(o))?.replace(/^@/u,"")??null}function B(e){return e.find(o=>/^@?docs\/epics\/[A-Za-z0-9._-]+\.md$/u.test(o))?.replace(/^@/u,"")??null}function O(e){const s=_(e)?.split("/").pop()?.replace(/\.story\.md$/,"")?.match(/^(P\d+)\./i)?.[1];if(s)return s.toUpperCase();const r=e.map(n=>n.match(/^@?(?:docs\/epics\/epic-)?(P\d+)(?:\.md)?$/iu)?.[1]).find(n=>!!n);return r?r.toUpperCase():null}function j(e){return e.map(t=>t.match(/^@?((?:docs|core)\/[A-Za-z0-9_./-]+\.md)$/u)?.[1]).filter(t=>!!t).map(t=>i(t)).filter(t=>!m(t))}function H(e){return e.startsWith("docs/stories/")?{nodeType:"Story",reasonCode:"story_scope_match"}:e.startsWith("docs/epics/")?{nodeType:"Epic",reasonCode:"epic_scope_match"}:e.includes("security")||e.includes("policy")||e.includes("standard")?{nodeType:"Guardrail",reasonCode:"guardrail_match"}:{nodeType:"Doc",reasonCode:"architecture_reference"}}function c(e,t){const o=i(t.path);if(m(o))return;e.some(r=>r.nodeType===t.nodeType&&i(r.path)===o)||e.push({...t,path:o})}function L(e,t,o){const s=_(t);if(s){const a=s.split("/").pop()?.replace(/\.story\.md$/,"")??s;c(e,{path:s,nodeType:"Story",stableId:a,reasonCode:"story_scope_match",confidence:.96,budgetCost:3,score:96,maxSnippetChars:o})}const r=B(t),n=O(t);if(r){const a=r.split("/").pop()?.replace(/\.md$/,"")??r;c(e,{path:r,nodeType:"Epic",stableId:a,reasonCode:"epic_scope_match",confidence:.92,budgetCost:3,score:92,maxSnippetChars:o})}else n&&c(e,{path:`docs/epics/epic-${n}.md`,nodeType:"Epic",stableId:n,reasonCode:"epic_scope_match",confidence:.9,budgetCost:3,score:90,maxSnippetChars:o});for(const a of j(t)){const d=a.split("/").pop()?.replace(/\.md$/,"").replace(/\.story$/,"")??a,l=H(a);c(e,{path:a,stableId:d,...l,confidence:.84,budgetCost:3,score:82,maxSnippetChars:o})}}function N(e,t,o,s){const r=e.retrievalBudget.maxSnippetChars,n=[];return c(n,{path:"NEOCORTEX.md",nodeType:"CanonicalMemory",stableId:"canonical-memory",reasonCode:"canonical_memory_seed",confidence:.92,budgetCost:4,score:100,maxSnippetChars:r}),c(n,{path:"AGENTS.md",nodeType:"PlatformMemory",stableId:"platform-memory:agents",reasonCode:"platform_memory_reference",confidence:.7,budgetCost:2,score:66,maxSnippetChars:r}),c(n,{path:"package.json",nodeType:"Package",stableId:"root-package",reasonCode:"package_surface_match",confidence:.78,budgetCost:2,score:72,maxSnippetChars:r}),(e.retrievalProfile!=="utility"||e.commandId==="ui-ux-review")&&c(n,{path:"docs/arquitetura-software/deterministic-graph-retrieval.md",nodeType:"Doc",stableId:"deterministic-graph-retrieval",reasonCode:"architecture_reference",confidence:.9,budgetCost:4,score:84,maxSnippetChars:r}),L(n,z(t),r),(["story-execution","diagnostic","research","review","qa","recovery","planning"].includes(e.retrievalProfile)||e.commandId==="tech-debt")&&c(n,{path:".neocortex/tech-debt-registry.json",nodeType:"Debt",stableId:"tech-debt-registry",reasonCode:"debt_area_match",confidence:.74,budgetCost:3,score:76,maxSnippetChars:r}),["story-execution","diagnostic","research","review","qa","recovery","planning","architecture"].includes(e.retrievalProfile)&&c(n,{path:"core/standards/spec-driven-development.md",nodeType:"Guardrail",stableId:"spec-driven-development",reasonCode:"guardrail_match",confidence:.82,budgetCost:3,score:78,maxSnippetChars:r}),e.retrievalProfile==="security"&&c(n,{path:"docs/architecture/solyd-security-system-contract.md",nodeType:"Guardrail",stableId:"solyd-security-system-contract",reasonCode:"guardrail_match",confidence:.86,budgetCost:3,score:84,maxSnippetChars:r}),e.retrievalProfile==="continuity"&&(c(n,{path:"core/standards/enterprise-continuity-plane.md",nodeType:"Guardrail",stableId:"enterprise-continuity-plane",reasonCode:"guardrail_match",confidence:.86,budgetCost:3,score:84,maxSnippetChars:r}),c(n,{path:"docs/runbooks/enterprise-continuity-runner.md",nodeType:"Doc",stableId:"enterprise-continuity-runner",reasonCode:"architecture_reference",confidence:.78,budgetCost:3,score:72,maxSnippetChars:r})),["utility","continuity","recovery"].includes(e.retrievalProfile)&&c(n,{path:".neocortex/state.json",nodeType:"State",stableId:"project-state",reasonCode:"state_status_match",confidence:.68,budgetCost:3,score:70,maxSnippetChars:r}),[M(e),...n.map(a=>G(o,a,s)).filter(a=>a!==null)]}function Z(e){let t=[...e.items],o=e;const s=Math.min(e.budget.maxPayloadBytes,y.maxPayloadBytes);for(;Buffer.byteLength(JSON.stringify(o),"utf8")>s&&t.length>0;){const r=t.pop(),n=g({retrievalId:e.retrievalId,query:e.query,items:t,generatedAt:e.generatedAt,warnings:e.warnings,budgets:e.budget});o={...n,skipped:r?[...n.skipped,{stableId:r.stableId,source:r.source,reasonCode:"budget_exceeded"}]:n.skipped,contractVersion:u,command:e.command}}return o}async function K(e){const t=$(e.args);if(!t)return{applied:!1,reason:"command_not_allowlisted"};const{policy:o,selection:s}=t,r=o.commandId;try{const n=N(o,s,e.projectRoot,e.fileReader??S);if(n.length===0)return{applied:!1,reason:"no_items",command:r,profile:o.retrievalProfile};const a=b(s.positionals.join(" ").slice(0,240)).text,d=p(`${u}:${r}:${a}:${n.map(f=>`${f.source.path}:${f.source.contentHash??""}`).sort().join("|")}`).slice(0,24),l=g({retrievalId:d,query:a,items:n,generatedAt:e.nowIso??x,budgets:o.retrievalBudget}),C=Z({...l,contractVersion:u,command:r});return{applied:!0,reason:"applied",command:r,profile:o.retrievalProfile,metadata:C}}catch(n){const a=n instanceof Error?n.message:String(n);return e.logger?.warn?.(`[neocortex] graph retrieval hook failed: ${a}. Proceeding without enrichment.`),{applied:!1,reason:"hook_error",command:r,profile:o.retrievalProfile,warning:a}}}export{k as admitGraphInvocation,K as runGraphRetrievalHook};