pi-fabric 0.79.0 → 0.80.0

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 (48) hide show
  1. package/dist/chunks/{chunk-HDTW3CML.js → chunk-6XUQ7MKH.js} +4 -2
  2. package/dist/chunks/{chunk-HDTW3CML.js.map → chunk-6XUQ7MKH.js.map} +2 -2
  3. package/dist/chunks/{chunk-UKZ452XN.js → chunk-75CLSHZE.js} +2 -2
  4. package/dist/chunks/{chunk-5OVYFN4A.js → chunk-BUXNRNJC.js} +2 -2
  5. package/dist/chunks/{chunk-OTB7OOQS.js → chunk-IITDYSG5.js} +62 -1
  6. package/dist/chunks/chunk-IITDYSG5.js.map +7 -0
  7. package/dist/chunks/{chunk-6GRNSFDJ.js → chunk-NTI5LLEM.js} +2 -1
  8. package/dist/chunks/{chunk-6GRNSFDJ.js.map → chunk-NTI5LLEM.js.map} +2 -2
  9. package/dist/chunks/{chunk-NXTORPRY.js → chunk-U3DHW7UQ.js} +47 -11
  10. package/dist/chunks/chunk-U3DHW7UQ.js.map +7 -0
  11. package/dist/chunks/{chunk-5IFANSBG.js → chunk-W7PLBXJH.js} +170 -14
  12. package/dist/chunks/chunk-W7PLBXJH.js.map +7 -0
  13. package/dist/chunks/{fabric-runtime-state-YKNG3IDT.js → fabric-runtime-state-EMLV5K2G.js} +7 -7
  14. package/dist/commands/fabric.d.ts.map +1 -1
  15. package/dist/core/action-registry.d.ts +5 -1
  16. package/dist/core/action-registry.d.ts.map +1 -1
  17. package/dist/core/action-registry.js +2 -2
  18. package/dist/entropy/compiled-store.d.ts +1 -0
  19. package/dist/entropy/compiled-store.d.ts.map +1 -1
  20. package/dist/entropy/compiled-surface.d.ts +6 -0
  21. package/dist/entropy/compiled-surface.d.ts.map +1 -1
  22. package/dist/entropy/index.d.ts +1 -0
  23. package/dist/entropy/index.d.ts.map +1 -1
  24. package/dist/entropy/index.js +12 -4
  25. package/dist/entropy/passes.d.ts.map +1 -1
  26. package/dist/entropy/sessions.d.ts +1 -0
  27. package/dist/entropy/sessions.d.ts.map +1 -1
  28. package/dist/entropy/surface.d.ts +1 -0
  29. package/dist/entropy/surface.d.ts.map +1 -1
  30. package/dist/entropy/trial.d.ts +34 -0
  31. package/dist/entropy/trial.d.ts.map +1 -0
  32. package/dist/index.d.ts.map +1 -1
  33. package/dist/index.js +127 -22
  34. package/dist/index.js.map +2 -2
  35. package/dist/memory/discovery.d.ts +1 -0
  36. package/dist/memory/discovery.d.ts.map +1 -1
  37. package/dist/memory/discovery.js +5 -3
  38. package/dist/providers/memory-provider.js +2 -2
  39. package/docs/certification.md +1 -1
  40. package/docs/entropy.md +74 -17
  41. package/docs/speculation.md +13 -0
  42. package/package.json +1 -1
  43. package/dist/chunks/chunk-5IFANSBG.js.map +0 -7
  44. package/dist/chunks/chunk-NXTORPRY.js.map +0 -7
  45. package/dist/chunks/chunk-OTB7OOQS.js.map +0 -7
  46. /package/dist/chunks/{chunk-UKZ452XN.js.map → chunk-75CLSHZE.js.map} +0 -0
  47. /package/dist/chunks/{chunk-5OVYFN4A.js.map → chunk-BUXNRNJC.js.map} +0 -0
  48. /package/dist/chunks/{fabric-runtime-state-YKNG3IDT.js.map → fabric-runtime-state-EMLV5K2G.js.map} +0 -0
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  COMPILED_SURFACE_VERSION,
3
3
  MAX_COMPILED_SURFACE_PROPOSALS
4
- } from "./chunk-OTB7OOQS.js";
4
+ } from "./chunk-IITDYSG5.js";
5
5
  import {
6
6
  writeJsonAtomic
7
7
  } from "./chunk-3SGRTVFP.js";
@@ -221,6 +221,7 @@ var parseCompiledSurfaceFile = (value) => {
221
221
  evidenceDigest: value.evidenceDigest.trim()
222
222
  };
223
223
  };
224
+ var parseCompiledSurfaceArtifact = (value) => parseCompiledSurfaceFile(value);
224
225
  var loadCompiledSurface = (agentDir) => {
225
226
  const file = compiledPath(compiledSurfaceDirectory(agentDir));
226
227
  let raw;
@@ -267,7 +268,8 @@ var saveCompiledSurface = (agentDir, file) => withExclusiveFileLock(
267
268
  export {
268
269
  withExclusiveFileLock,
269
270
  compiledSurfaceDirectory,
271
+ parseCompiledSurfaceArtifact,
270
272
  loadCompiledSurface,
271
273
  saveCompiledSurface
272
274
  };
273
- //# sourceMappingURL=chunk-HDTW3CML.js.map
275
+ //# sourceMappingURL=chunk-6XUQ7MKH.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/entropy/compiled-store.ts", "../../src/core/file-lock.ts"],
4
- "sourcesContent": ["// Persistence for the compiled entropy surface: <agent dir>/fabric/entropy/\n// compiled.json, locked across Pi processes sharing the agent directory.\n// A damaged artifact surfaces as an error and blocks compiles from\n// overwriting it \u2014 the same discipline as the repair table. The artifact is\n// clock-free, so saving byte-identical content is a no-op.\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { writeJsonAtomic } from \"../core/atomic-write.js\";\nimport { withExclusiveFileLock } from \"../core/file-lock.js\";\nimport {\n COMPILED_SURFACE_VERSION,\n MAX_COMPILED_SURFACE_PROPOSALS,\n type CompiledSurfaceAppliedProposal,\n type CompiledSurfaceFile,\n type CompiledSurfaceGateRecord,\n type CompiledSurfaceOverlayEntry,\n type CompiledSurfaceQuarantineEntry,\n} from \"./compiled-surface.js\";\n\nconst COMPILED_LOCK_ATTEMPTS = 50;\nconst COMPILED_LOCK_DELAY_MS = 5;\nconst COMPILED_STALE_LOCK_MS = 30_000;\n\nexport const compiledSurfaceDirectory = (agentDir: string): string =>\n path.join(agentDir, \"fabric\", \"entropy\");\n\nconst compiledPath = (directory: string): string => path.join(directory, \"compiled.json\");\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nconst errorCode = (error: unknown): string | undefined =>\n isRecord(error) && typeof error.code === \"string\" ? error.code : undefined;\n\nconst errorText = (error: unknown): string =>\n (error instanceof Error ? error.message : String(error)).slice(0, 200);\n\nconst parseOverlayEntry = (value: unknown): CompiledSurfaceOverlayEntry | undefined => {\n if (!isRecord(value) || typeof value.ref !== \"string\" || !value.ref.trim()) return undefined;\n if (!isRecord(value.inputSchema)) return undefined;\n if (typeof value.baseSchemaDigest !== \"string\" || !value.baseSchemaDigest.trim()) {\n return undefined;\n }\n return {\n ref: value.ref.trim(),\n inputSchema: value.inputSchema,\n baseSchemaDigest: value.baseSchemaDigest.trim(),\n };\n};\n\nconst parseQuarantineEntry = (value: unknown): CompiledSurfaceQuarantineEntry | undefined => {\n if (!isRecord(value) || typeof value.ref !== \"string\" || !value.ref.trim()) return undefined;\n if (typeof value.baseSchemaDigest !== \"string\" || !value.baseSchemaDigest.trim()) {\n return undefined;\n }\n return { ref: value.ref.trim(), baseSchemaDigest: value.baseSchemaDigest.trim() };\n};\n\nconst parseAppliedProposal = (value: unknown): CompiledSurfaceAppliedProposal | undefined => {\n if (!isRecord(value)) return undefined;\n if (typeof value.kind !== \"string\" || !value.kind.trim()) return undefined;\n if (typeof value.ref !== \"string\" || !value.ref.trim()) return undefined;\n if (typeof value.detail !== \"string\" || !value.detail.trim()) return undefined;\n return {\n kind: value.kind.trim() as CompiledSurfaceAppliedProposal[\"kind\"],\n ref: value.ref.trim(),\n detail: value.detail.trim(),\n };\n};\n\nconst parseGateRecord = (value: unknown): CompiledSurfaceGateRecord | undefined => {\n if (!isRecord(value) || typeof value.passed !== \"boolean\") return undefined;\n if (typeof value.beforeScore !== \"number\" || typeof value.afterScore !== \"number\") {\n return undefined;\n }\n if (!Array.isArray(value.reasons) || !value.reasons.every((r) => typeof r === \"string\")) {\n return undefined;\n }\n return {\n passed: value.passed,\n beforeScore: value.beforeScore,\n afterScore: value.afterScore,\n reasons: value.reasons,\n };\n};\n\n// Guarded parse of the whole artifact. Any metric version is accepted: the\n// overlay schemas are data gated against recorded calls, so a metric bump\n// does not invalidate them; the version rides along as provenance.\nconst parseCompiledSurfaceFile = (value: unknown): CompiledSurfaceFile | undefined => {\n if (!isRecord(value) || value.version !== COMPILED_SURFACE_VERSION) return undefined;\n if (!Number.isSafeInteger(value.metricVersion) || (value.metricVersion as number) < 1) {\n return undefined;\n }\n if (!Array.isArray(value.actions) || !value.actions.every((entry) => parseOverlayEntry(entry))) {\n return undefined;\n }\n if (\n !Array.isArray(value.quarantined) ||\n !value.quarantined.every((entry) => parseQuarantineEntry(entry))\n ) {\n return undefined;\n }\n if (\n !Array.isArray(value.applied) ||\n value.applied.length > MAX_COMPILED_SURFACE_PROPOSALS ||\n !value.applied.every((entry) => parseAppliedProposal(entry))\n ) {\n return undefined;\n }\n if (!parseGateRecord(value.gate)) return undefined;\n if (typeof value.evidenceDigest !== \"string\" || !value.evidenceDigest.trim()) return undefined;\n const overlaySeen = new Set<string>();\n for (const entry of value.actions) {\n const parsed = parseOverlayEntry(entry)!;\n if (overlaySeen.has(parsed.ref)) return undefined;\n overlaySeen.add(parsed.ref);\n }\n return {\n version: COMPILED_SURFACE_VERSION,\n metricVersion: value.metricVersion as number,\n actions: value.actions.map((entry) => parseOverlayEntry(entry)!),\n quarantined: value.quarantined.map((entry) => parseQuarantineEntry(entry)!),\n applied: value.applied.map((entry) => parseAppliedProposal(entry)!),\n gate: parseGateRecord(value.gate)!,\n evidenceDigest: value.evidenceDigest.trim(),\n };\n};\n\nexport interface LoadedCompiledSurface {\n file?: CompiledSurfaceFile;\n error?: string;\n}\n\nexport const loadCompiledSurface = (agentDir: string): LoadedCompiledSurface => {\n const file = compiledPath(compiledSurfaceDirectory(agentDir));\n let raw: string;\n try {\n raw = fs.readFileSync(file, \"utf8\");\n } catch (error) {\n // A missing artifact means the surface was never compiled; anything\n // else is damage that callers must surface, not silently rebuild.\n if (errorCode(error) === \"ENOENT\") return {};\n return { error: `compiled surface is unreadable: ${errorText(error)}` };\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n return { error: \"compiled surface is malformed JSON\" };\n }\n const parsedFile = parseCompiledSurfaceFile(parsed);\n if (!parsedFile) return { error: \"compiled surface is invalid\" };\n return { file: parsedFile };\n};\n\nexport interface SavedCompiledSurface {\n file: CompiledSurfaceFile;\n written: boolean;\n}\n\nexport const saveCompiledSurface = (\n agentDir: string,\n file: CompiledSurfaceFile,\n): SavedCompiledSurface =>\n withExclusiveFileLock(\n {\n directory: compiledSurfaceDirectory(agentDir),\n lockName: \"compiled.lock\",\n timeoutMessage: \"Timed out waiting for the compiled entropy surface lock\",\n attempts: COMPILED_LOCK_ATTEMPTS,\n delayMs: COMPILED_LOCK_DELAY_MS,\n staleMs: COMPILED_STALE_LOCK_MS,\n },\n () => {\n // A damaged artifact must never be silently rebuilt; fail so the\n // compile records the rejection and leaves the file for recovery.\n const loaded = loadCompiledSurface(agentDir);\n if (loaded.error) throw new Error(loaded.error);\n const target = compiledPath(compiledSurfaceDirectory(agentDir));\n const serialized = `${JSON.stringify(file, null, 2)}\\n`;\n try {\n if (fs.readFileSync(target, \"utf8\") === serialized) return { file, written: false };\n } catch {\n // Missing file: proceed to write.\n }\n writeJsonAtomic(target, file, { space: 2, newline: true, mode: 0o600, dirMode: 0o700 });\n return { file, written: true };\n },\n );", "// Cross-process exclusive lock for Fabric's durable stores (the repair\n// table, the compiled entropy surface). Acquisition is a bounded retry over\n// mkdir; stale-lock recovery is an exclusive rename claim, so racing\n// reapers can never delete a lock a fresh writer owns.\n\nimport { randomUUID } from \"node:crypto\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\n\nconst DEFAULT_LOCK_ATTEMPTS = 50;\nconst DEFAULT_LOCK_DELAY_MS = 5;\nconst DEFAULT_STALE_LOCK_MS = 30_000;\n\nexport interface ExclusiveLockOptions {\n directory: string;\n lockName: string;\n /** Error message when acquisition times out. */\n timeoutMessage: string;\n staleMs?: number;\n attempts?: number;\n delayMs?: number;\n}\n\nconst errorCode = (error: unknown): string | undefined =>\n typeof error === \"object\" && error !== null && \"code\" in error\n ? String((error as { code?: unknown }).code)\n : undefined;\n\nconst sleepSync = (() => {\n try {\n const buffer = new Int32Array(new SharedArrayBuffer(4));\n return (ms: number): void => {\n Atomics.wait(buffer, 0, 0, ms);\n };\n } catch {\n return (): void => undefined;\n }\n})();\n\nconst processAlive = (pid: number): boolean => {\n if (!Number.isSafeInteger(pid) || pid <= 0) return false;\n try {\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n};\n\n// Stale-lock recovery must be an exclusive claim. Stat-then-delete is\n// TOCTOU: two reapers (or a reaper and a fresh writer that recreated the\n// lock in between) can both pass their checks, and the slower rm then\n// deletes a lock the faster one already replaced. rename() is the claim \u2014\n// only one process can move the directory, and removal targets the claimed\n// path, never the live lock path. A claim that turns out to hold a live\n// lock is renamed back before any destructive step; a live lock is never\n// deleted, even if the rename-back races a fresh writer.\nconst reapStaleLock = (lock: string, verify: (claimed: string) => boolean): boolean => {\n const claim = `${lock}.reap-${process.pid}-${randomUUID()}`;\n try {\n fs.renameSync(lock, claim);\n } catch {\n return false;\n }\n if (!verify(claim)) {\n try {\n fs.renameSync(claim, lock);\n } catch {\n // `lock` was recreated after the claim. Re-verify before any\n // destructive step so a claimed live lock is only ever abandoned as\n // garbage, never deleted.\n if (verify(claim)) fs.rmSync(claim, { recursive: true, force: true });\n }\n return false;\n }\n fs.rmSync(claim, { recursive: true, force: true });\n return true;\n};\n\nexport const withExclusiveFileLock = <T>(\n options: ExclusiveLockOptions,\n operation: () => T,\n): T => {\n const attempts = options.attempts ?? DEFAULT_LOCK_ATTEMPTS;\n const delayMs = options.delayMs ?? DEFAULT_LOCK_DELAY_MS;\n const staleMs = options.staleMs ?? DEFAULT_STALE_LOCK_MS;\n fs.mkdirSync(options.directory, { recursive: true, mode: 0o700 });\n const lock = path.join(options.directory, options.lockName);\n const ownerPath = path.join(lock, \"owner\");\n const token = randomUUID();\n let acquired = false;\n for (let attempt = 0; attempt < attempts; attempt++) {\n try {\n fs.mkdirSync(lock, { mode: 0o700 });\n try {\n fs.writeFileSync(ownerPath, `${token}\\n${process.pid}\\n${Date.now()}\\n`, {\n encoding: \"utf-8\",\n mode: 0o600,\n });\n } catch (error) {\n fs.rmSync(lock, { recursive: true, force: true });\n throw error;\n }\n acquired = true;\n break;\n } catch (error) {\n if (errorCode(error) !== \"EEXIST\") throw error;\n try {\n const firstOwner = fs.readFileSync(ownerPath, \"utf8\");\n const [, pidText, createdText] = firstOwner.trim().split(\"\\n\");\n const stale = Date.now() - Number(createdText) > staleMs;\n if (stale && !processAlive(Number(pidText))) {\n const secondOwner = fs.readFileSync(ownerPath, \"utf8\");\n if (\n secondOwner === firstOwner &&\n reapStaleLock(lock, (claimed) => {\n try {\n const owner = fs.readFileSync(path.join(claimed, \"owner\"), \"utf8\");\n const [, pid, created] = owner.trim().split(\"\\n\");\n return Date.now() - Number(created) > staleMs && !processAlive(Number(pid));\n } catch {\n return false;\n }\n })\n ) {\n continue;\n }\n }\n } catch {\n try {\n // Ownerless lock (crash between mkdir and the owner write): age is\n // the only signal, and the claim re-verifies it after the rename.\n const first = fs.statSync(lock);\n if (\n Date.now() - first.mtimeMs > staleMs &&\n reapStaleLock(lock, (claimed) => {\n try {\n return Date.now() - fs.statSync(claimed).mtimeMs > staleMs;\n } catch {\n return false;\n }\n })\n ) {\n continue;\n }\n } catch {\n // Lock creation or stale recovery raced; retry the bounded acquisition.\n }\n }\n if (attempt === attempts - 1) break;\n sleepSync(delayMs);\n }\n }\n if (!acquired) throw new Error(options.timeoutMessage);\n try {\n return operation();\n } finally {\n try {\n const owner = fs.readFileSync(ownerPath, \"utf8\");\n if (owner.startsWith(`${token}\\n`)) {\n fs.rmSync(lock, { recursive: true, force: true });\n }\n } catch {\n // A recovering process already removed this lock.\n }\n }\n};"],
5
- "mappings": "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",
4
+ "sourcesContent": ["// Persistence for the compiled entropy surface: <agent dir>/fabric/entropy/\n// compiled.json, locked across Pi processes sharing the agent directory.\n// A damaged artifact surfaces as an error and blocks compiles from\n// overwriting it \u2014 the same discipline as the repair table. The artifact is\n// clock-free, so saving byte-identical content is a no-op.\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { writeJsonAtomic } from \"../core/atomic-write.js\";\nimport { withExclusiveFileLock } from \"../core/file-lock.js\";\nimport {\n COMPILED_SURFACE_VERSION,\n MAX_COMPILED_SURFACE_PROPOSALS,\n type CompiledSurfaceAppliedProposal,\n type CompiledSurfaceFile,\n type CompiledSurfaceGateRecord,\n type CompiledSurfaceOverlayEntry,\n type CompiledSurfaceQuarantineEntry,\n} from \"./compiled-surface.js\";\n\nconst COMPILED_LOCK_ATTEMPTS = 50;\nconst COMPILED_LOCK_DELAY_MS = 5;\nconst COMPILED_STALE_LOCK_MS = 30_000;\n\nexport const compiledSurfaceDirectory = (agentDir: string): string =>\n path.join(agentDir, \"fabric\", \"entropy\");\n\nconst compiledPath = (directory: string): string => path.join(directory, \"compiled.json\");\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nconst errorCode = (error: unknown): string | undefined =>\n isRecord(error) && typeof error.code === \"string\" ? error.code : undefined;\n\nconst errorText = (error: unknown): string =>\n (error instanceof Error ? error.message : String(error)).slice(0, 200);\n\nconst parseOverlayEntry = (value: unknown): CompiledSurfaceOverlayEntry | undefined => {\n if (!isRecord(value) || typeof value.ref !== \"string\" || !value.ref.trim()) return undefined;\n if (!isRecord(value.inputSchema)) return undefined;\n if (typeof value.baseSchemaDigest !== \"string\" || !value.baseSchemaDigest.trim()) {\n return undefined;\n }\n return {\n ref: value.ref.trim(),\n inputSchema: value.inputSchema,\n baseSchemaDigest: value.baseSchemaDigest.trim(),\n };\n};\n\nconst parseQuarantineEntry = (value: unknown): CompiledSurfaceQuarantineEntry | undefined => {\n if (!isRecord(value) || typeof value.ref !== \"string\" || !value.ref.trim()) return undefined;\n if (typeof value.baseSchemaDigest !== \"string\" || !value.baseSchemaDigest.trim()) {\n return undefined;\n }\n return { ref: value.ref.trim(), baseSchemaDigest: value.baseSchemaDigest.trim() };\n};\n\nconst parseAppliedProposal = (value: unknown): CompiledSurfaceAppliedProposal | undefined => {\n if (!isRecord(value)) return undefined;\n if (typeof value.kind !== \"string\" || !value.kind.trim()) return undefined;\n if (typeof value.ref !== \"string\" || !value.ref.trim()) return undefined;\n if (typeof value.detail !== \"string\" || !value.detail.trim()) return undefined;\n return {\n kind: value.kind.trim() as CompiledSurfaceAppliedProposal[\"kind\"],\n ref: value.ref.trim(),\n detail: value.detail.trim(),\n };\n};\n\nconst parseGateRecord = (value: unknown): CompiledSurfaceGateRecord | undefined => {\n if (!isRecord(value) || typeof value.passed !== \"boolean\") return undefined;\n if (typeof value.beforeScore !== \"number\" || typeof value.afterScore !== \"number\") {\n return undefined;\n }\n if (!Array.isArray(value.reasons) || !value.reasons.every((r) => typeof r === \"string\")) {\n return undefined;\n }\n return {\n passed: value.passed,\n beforeScore: value.beforeScore,\n afterScore: value.afterScore,\n reasons: value.reasons,\n };\n};\n\n// Guarded parse of the whole artifact. Any metric version is accepted: the\n// overlay schemas are data gated against recorded calls, so a metric bump\n// does not invalidate them; the version rides along as provenance.\nconst parseCompiledSurfaceFile = (value: unknown): CompiledSurfaceFile | undefined => {\n if (!isRecord(value) || value.version !== COMPILED_SURFACE_VERSION) return undefined;\n if (!Number.isSafeInteger(value.metricVersion) || (value.metricVersion as number) < 1) {\n return undefined;\n }\n if (!Array.isArray(value.actions) || !value.actions.every((entry) => parseOverlayEntry(entry))) {\n return undefined;\n }\n if (\n !Array.isArray(value.quarantined) ||\n !value.quarantined.every((entry) => parseQuarantineEntry(entry))\n ) {\n return undefined;\n }\n if (\n !Array.isArray(value.applied) ||\n value.applied.length > MAX_COMPILED_SURFACE_PROPOSALS ||\n !value.applied.every((entry) => parseAppliedProposal(entry))\n ) {\n return undefined;\n }\n if (!parseGateRecord(value.gate)) return undefined;\n if (typeof value.evidenceDigest !== \"string\" || !value.evidenceDigest.trim()) return undefined;\n const overlaySeen = new Set<string>();\n for (const entry of value.actions) {\n const parsed = parseOverlayEntry(entry)!;\n if (overlaySeen.has(parsed.ref)) return undefined;\n overlaySeen.add(parsed.ref);\n }\n return {\n version: COMPILED_SURFACE_VERSION,\n metricVersion: value.metricVersion as number,\n actions: value.actions.map((entry) => parseOverlayEntry(entry)!),\n quarantined: value.quarantined.map((entry) => parseQuarantineEntry(entry)!),\n applied: value.applied.map((entry) => parseAppliedProposal(entry)!),\n gate: parseGateRecord(value.gate)!,\n evidenceDigest: value.evidenceDigest.trim(),\n };\n};\n\n// Public guarded parse for artifact files that did not come from this\n// agent dir: exported artifacts being imported, or certification fixtures.\n// The same validation the store applies to its own file, so nothing trusts\n// an artifact shape the store would refuse to load.\nexport const parseCompiledSurfaceArtifact = (\n value: unknown,\n): CompiledSurfaceFile | undefined => parseCompiledSurfaceFile(value);\n\nexport interface LoadedCompiledSurface {\n file?: CompiledSurfaceFile;\n error?: string;\n}\n\nexport const loadCompiledSurface = (agentDir: string): LoadedCompiledSurface => {\n const file = compiledPath(compiledSurfaceDirectory(agentDir));\n let raw: string;\n try {\n raw = fs.readFileSync(file, \"utf8\");\n } catch (error) {\n // A missing artifact means the surface was never compiled; anything\n // else is damage that callers must surface, not silently rebuild.\n if (errorCode(error) === \"ENOENT\") return {};\n return { error: `compiled surface is unreadable: ${errorText(error)}` };\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n return { error: \"compiled surface is malformed JSON\" };\n }\n const parsedFile = parseCompiledSurfaceFile(parsed);\n if (!parsedFile) return { error: \"compiled surface is invalid\" };\n return { file: parsedFile };\n};\n\nexport interface SavedCompiledSurface {\n file: CompiledSurfaceFile;\n written: boolean;\n}\n\nexport const saveCompiledSurface = (\n agentDir: string,\n file: CompiledSurfaceFile,\n): SavedCompiledSurface =>\n withExclusiveFileLock(\n {\n directory: compiledSurfaceDirectory(agentDir),\n lockName: \"compiled.lock\",\n timeoutMessage: \"Timed out waiting for the compiled entropy surface lock\",\n attempts: COMPILED_LOCK_ATTEMPTS,\n delayMs: COMPILED_LOCK_DELAY_MS,\n staleMs: COMPILED_STALE_LOCK_MS,\n },\n () => {\n // A damaged artifact must never be silently rebuilt; fail so the\n // compile records the rejection and leaves the file for recovery.\n const loaded = loadCompiledSurface(agentDir);\n if (loaded.error) throw new Error(loaded.error);\n const target = compiledPath(compiledSurfaceDirectory(agentDir));\n const serialized = `${JSON.stringify(file, null, 2)}\\n`;\n try {\n if (fs.readFileSync(target, \"utf8\") === serialized) return { file, written: false };\n } catch {\n // Missing file: proceed to write.\n }\n writeJsonAtomic(target, file, { space: 2, newline: true, mode: 0o600, dirMode: 0o700 });\n return { file, written: true };\n },\n );", "// Cross-process exclusive lock for Fabric's durable stores (the repair\n// table, the compiled entropy surface). Acquisition is a bounded retry over\n// mkdir; stale-lock recovery is an exclusive rename claim, so racing\n// reapers can never delete a lock a fresh writer owns.\n\nimport { randomUUID } from \"node:crypto\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\n\nconst DEFAULT_LOCK_ATTEMPTS = 50;\nconst DEFAULT_LOCK_DELAY_MS = 5;\nconst DEFAULT_STALE_LOCK_MS = 30_000;\n\nexport interface ExclusiveLockOptions {\n directory: string;\n lockName: string;\n /** Error message when acquisition times out. */\n timeoutMessage: string;\n staleMs?: number;\n attempts?: number;\n delayMs?: number;\n}\n\nconst errorCode = (error: unknown): string | undefined =>\n typeof error === \"object\" && error !== null && \"code\" in error\n ? String((error as { code?: unknown }).code)\n : undefined;\n\nconst sleepSync = (() => {\n try {\n const buffer = new Int32Array(new SharedArrayBuffer(4));\n return (ms: number): void => {\n Atomics.wait(buffer, 0, 0, ms);\n };\n } catch {\n return (): void => undefined;\n }\n})();\n\nconst processAlive = (pid: number): boolean => {\n if (!Number.isSafeInteger(pid) || pid <= 0) return false;\n try {\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n};\n\n// Stale-lock recovery must be an exclusive claim. Stat-then-delete is\n// TOCTOU: two reapers (or a reaper and a fresh writer that recreated the\n// lock in between) can both pass their checks, and the slower rm then\n// deletes a lock the faster one already replaced. rename() is the claim \u2014\n// only one process can move the directory, and removal targets the claimed\n// path, never the live lock path. A claim that turns out to hold a live\n// lock is renamed back before any destructive step; a live lock is never\n// deleted, even if the rename-back races a fresh writer.\nconst reapStaleLock = (lock: string, verify: (claimed: string) => boolean): boolean => {\n const claim = `${lock}.reap-${process.pid}-${randomUUID()}`;\n try {\n fs.renameSync(lock, claim);\n } catch {\n return false;\n }\n if (!verify(claim)) {\n try {\n fs.renameSync(claim, lock);\n } catch {\n // `lock` was recreated after the claim. Re-verify before any\n // destructive step so a claimed live lock is only ever abandoned as\n // garbage, never deleted.\n if (verify(claim)) fs.rmSync(claim, { recursive: true, force: true });\n }\n return false;\n }\n fs.rmSync(claim, { recursive: true, force: true });\n return true;\n};\n\nexport const withExclusiveFileLock = <T>(\n options: ExclusiveLockOptions,\n operation: () => T,\n): T => {\n const attempts = options.attempts ?? DEFAULT_LOCK_ATTEMPTS;\n const delayMs = options.delayMs ?? DEFAULT_LOCK_DELAY_MS;\n const staleMs = options.staleMs ?? DEFAULT_STALE_LOCK_MS;\n fs.mkdirSync(options.directory, { recursive: true, mode: 0o700 });\n const lock = path.join(options.directory, options.lockName);\n const ownerPath = path.join(lock, \"owner\");\n const token = randomUUID();\n let acquired = false;\n for (let attempt = 0; attempt < attempts; attempt++) {\n try {\n fs.mkdirSync(lock, { mode: 0o700 });\n try {\n fs.writeFileSync(ownerPath, `${token}\\n${process.pid}\\n${Date.now()}\\n`, {\n encoding: \"utf-8\",\n mode: 0o600,\n });\n } catch (error) {\n fs.rmSync(lock, { recursive: true, force: true });\n throw error;\n }\n acquired = true;\n break;\n } catch (error) {\n if (errorCode(error) !== \"EEXIST\") throw error;\n try {\n const firstOwner = fs.readFileSync(ownerPath, \"utf8\");\n const [, pidText, createdText] = firstOwner.trim().split(\"\\n\");\n const stale = Date.now() - Number(createdText) > staleMs;\n if (stale && !processAlive(Number(pidText))) {\n const secondOwner = fs.readFileSync(ownerPath, \"utf8\");\n if (\n secondOwner === firstOwner &&\n reapStaleLock(lock, (claimed) => {\n try {\n const owner = fs.readFileSync(path.join(claimed, \"owner\"), \"utf8\");\n const [, pid, created] = owner.trim().split(\"\\n\");\n return Date.now() - Number(created) > staleMs && !processAlive(Number(pid));\n } catch {\n return false;\n }\n })\n ) {\n continue;\n }\n }\n } catch {\n try {\n // Ownerless lock (crash between mkdir and the owner write): age is\n // the only signal, and the claim re-verifies it after the rename.\n const first = fs.statSync(lock);\n if (\n Date.now() - first.mtimeMs > staleMs &&\n reapStaleLock(lock, (claimed) => {\n try {\n return Date.now() - fs.statSync(claimed).mtimeMs > staleMs;\n } catch {\n return false;\n }\n })\n ) {\n continue;\n }\n } catch {\n // Lock creation or stale recovery raced; retry the bounded acquisition.\n }\n }\n if (attempt === attempts - 1) break;\n sleepSync(delayMs);\n }\n }\n if (!acquired) throw new Error(options.timeoutMessage);\n try {\n return operation();\n } finally {\n try {\n const owner = fs.readFileSync(ownerPath, \"utf8\");\n if (owner.startsWith(`${token}\\n`)) {\n fs.rmSync(lock, { recursive: true, force: true });\n }\n } catch {\n // A recovering process already removed this lock.\n }\n }\n};"],
5
+ "mappings": "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",
6
6
  "names": ["fs", "path", "path", "errorCode", "fs"]
7
7
  }
@@ -6,7 +6,7 @@ import {
6
6
  } from "./chunk-SOBEXOWK.js";
7
7
  import {
8
8
  NESTED_TOOL_CALL_ID_PREFIX
9
- } from "./chunk-NXTORPRY.js";
9
+ } from "./chunk-U3DHW7UQ.js";
10
10
  import {
11
11
  THINKING_DIGEST_CUSTOM_TYPE,
12
12
  buildThinkingDigest,
@@ -2447,4 +2447,4 @@ export {
2447
2447
  resolveFabricIdentity,
2448
2448
  MainAgentController
2449
2449
  };
2450
- //# sourceMappingURL=chunk-UKZ452XN.js.map
2450
+ //# sourceMappingURL=chunk-75CLSHZE.js.map
@@ -15,7 +15,7 @@ import {
15
15
  enumerateAllSessions,
16
16
  resolveScope,
17
17
  resolveSessionTarget
18
- } from "./chunk-6GRNSFDJ.js";
18
+ } from "./chunk-NTI5LLEM.js";
19
19
  import {
20
20
  expandSessionEntriesChecked,
21
21
  normalizeSession
@@ -865,4 +865,4 @@ export {
865
865
  normalizeMemoryArgs,
866
866
  MemoryProvider
867
867
  };
868
- //# sourceMappingURL=chunk-5OVYFN4A.js.map
868
+ //# sourceMappingURL=chunk-BUXNRNJC.js.map
@@ -41,6 +41,66 @@ var isQuarantinedRef = (ref, liveSchema, file) => {
41
41
  if (!entry) return false;
42
42
  return schemaDigest(liveSchema) === entry.baseSchemaDigest;
43
43
  };
44
+ var byRefOrder = (left, right) => left.ref < right.ref ? -1 : left.ref > right.ref ? 1 : 0;
45
+ var mergeCompiledSurfaces = (local, incoming, live) => {
46
+ const liveByRef = new Map(live.actions.map((action) => [action.ref, action.inputSchema]));
47
+ const liveDigestOf = (ref) => {
48
+ const schema = liveByRef.get(ref);
49
+ return schema === void 0 ? void 0 : schemaDigest(schema);
50
+ };
51
+ const overlayRefs = new Set((local?.actions ?? []).map((entry) => entry.ref));
52
+ const quarantineRefs = new Set((local?.quarantined ?? []).map((entry) => entry.ref));
53
+ const actions = [...local?.actions ?? []];
54
+ const quarantined = [...local?.quarantined ?? []];
55
+ let droppedOverlays = 0;
56
+ let droppedQuarantines = 0;
57
+ for (const entry of incoming.actions) {
58
+ if (overlayRefs.has(entry.ref) || quarantineRefs.has(entry.ref)) continue;
59
+ if (liveDigestOf(entry.ref) !== entry.baseSchemaDigest) {
60
+ droppedOverlays++;
61
+ continue;
62
+ }
63
+ actions.push(entry);
64
+ overlayRefs.add(entry.ref);
65
+ }
66
+ for (const entry of incoming.quarantined) {
67
+ if (overlayRefs.has(entry.ref) || quarantineRefs.has(entry.ref)) continue;
68
+ if (liveDigestOf(entry.ref) !== entry.baseSchemaDigest) {
69
+ droppedQuarantines++;
70
+ continue;
71
+ }
72
+ quarantined.push(entry);
73
+ quarantineRefs.add(entry.ref);
74
+ }
75
+ actions.sort(byRefOrder);
76
+ quarantined.sort(byRefOrder);
77
+ const applied = [];
78
+ const seenApplied = /* @__PURE__ */ new Set();
79
+ for (const source of [local?.applied ?? [], incoming.applied]) {
80
+ for (const entry of source) {
81
+ const identity = `${entry.kind}:${entry.ref}:${entry.detail}`;
82
+ if (seenApplied.has(identity)) continue;
83
+ seenApplied.add(identity);
84
+ if (applied.length >= MAX_COMPILED_SURFACE_PROPOSALS) break;
85
+ applied.push(entry);
86
+ }
87
+ }
88
+ const file = {
89
+ version: COMPILED_SURFACE_VERSION,
90
+ metricVersion: local?.metricVersion ?? incoming.metricVersion,
91
+ actions,
92
+ quarantined,
93
+ applied,
94
+ gate: local?.gate ?? incoming.gate,
95
+ evidenceDigest: stableJsonHash({
96
+ actions,
97
+ quarantined,
98
+ applied,
99
+ sources: [...local ? [local.evidenceDigest] : [], incoming.evidenceDigest]
100
+ })
101
+ };
102
+ return { file, droppedOverlays, droppedQuarantines };
103
+ };
44
104
  var replaySuccessfulCalls = (surface, traces, touchedRefs) => {
45
105
  const schemaByRef = new Map(surface.actions.map((action) => [action.ref, action.inputSchema]));
46
106
  const violations = [];
@@ -79,6 +139,7 @@ export {
79
139
  applyCompiledSurface,
80
140
  quarantinedRefNames,
81
141
  isQuarantinedRef,
142
+ mergeCompiledSurfaces,
82
143
  replaySuccessfulCalls
83
144
  };
84
- //# sourceMappingURL=chunk-OTB7OOQS.js.map
145
+ //# sourceMappingURL=chunk-IITDYSG5.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/entropy/compiled-surface.ts"],
4
+ "sourcesContent": ["// The compiled entropy surface: the durable artifact the autonomous\n// compiler maintains beside the repair table. Every overlay entry records\n// the digest of the live schema it was compiled against, and every consult\n// re-proves that digest against the live declared schema \u2014 an entry whose\n// base changed underneath it drops out instead of mis-enforcing. The\n// artifact is clock-free and deterministic: the same evidence compiles to\n// the same bytes.\n\nimport { Value } from \"typebox/value\";\nimport { stableJsonHash } from \"../core/stable-hash.js\";\nimport type { EntropyProposal, EntropySurfaceSnapshot, EntropyTraceInput } from \"./types.js\";\n\nexport const COMPILED_SURFACE_VERSION = 1 as const;\nexport const MAX_COMPILED_SURFACE_PROPOSALS = 256;\n\nexport interface CompiledSurfaceOverlayEntry {\n ref: string;\n inputSchema: Record<string, unknown>;\n baseSchemaDigest: string;\n}\n\nexport interface CompiledSurfaceQuarantineEntry {\n ref: string;\n baseSchemaDigest: string;\n}\n\nexport interface CompiledSurfaceAppliedProposal {\n kind: EntropyProposal[\"kind\"];\n ref: string;\n detail: string;\n}\n\nexport interface CompiledSurfaceGateRecord {\n passed: boolean;\n beforeScore: number;\n afterScore: number;\n reasons: string[];\n}\n\nexport interface CompiledSurfaceFile {\n version: typeof COMPILED_SURFACE_VERSION;\n metricVersion: number;\n actions: CompiledSurfaceOverlayEntry[];\n quarantined: CompiledSurfaceQuarantineEntry[];\n applied: CompiledSurfaceAppliedProposal[];\n gate: CompiledSurfaceGateRecord;\n evidenceDigest: string;\n}\n\nconst isPlainRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nexport const schemaDigest = (schema: unknown): string => stableJsonHash(schema);\n\n// Overlay consult for one ref: the compiled schema replaces the declared\n// schema only while the base digest still proves the declared surface did\n// not change underneath the compile.\nexport const effectiveSchemaFor = (\n ref: string,\n liveSchema: unknown,\n file?: CompiledSurfaceFile,\n): unknown => {\n const entry = file?.actions.find((candidate) => candidate.ref === ref);\n if (!entry) return liveSchema;\n return schemaDigest(liveSchema) === entry.baseSchemaDigest ? entry.inputSchema : liveSchema;\n};\n\n// Whole-surface overlay for measurement and export: tightened schemas where\n// the base still matches, quarantined refs hidden where the base still\n// matches. Stale entries fall back to the live surface, never mis-enforce.\nexport const applyCompiledSurface = (\n live: EntropySurfaceSnapshot,\n file?: CompiledSurfaceFile,\n): EntropySurfaceSnapshot => {\n if (!file || (file.actions.length === 0 && file.quarantined.length === 0)) return live;\n const byRef = new Map<string, unknown>(\n live.actions.map((action) => [action.ref, action.inputSchema]),\n );\n const overlayByRef = new Map(file.actions.map((entry) => [entry.ref, entry]));\n const quarantineByRef = new Map(file.quarantined.map((entry) => [entry.ref, entry]));\n const actions: EntropySurfaceSnapshot[\"actions\"] = [];\n for (const action of live.actions) {\n const overlay = overlayByRef.get(action.ref);\n if (overlay && schemaDigest(byRef.get(action.ref)) === overlay.baseSchemaDigest) {\n actions.push({ ref: action.ref, inputSchema: overlay.inputSchema });\n continue;\n }\n const quarantine = quarantineByRef.get(action.ref);\n if (quarantine && schemaDigest(byRef.get(action.ref)) === quarantine.baseSchemaDigest) {\n continue;\n }\n actions.push(action);\n }\n return { version: 1, actions };\n};\n\n// Name-only quarantine view for catalog filtering: hiding there is\n// advisory, so no digest proof is required. Resolution denial is the\n// digested isQuarantinedRef below.\nexport const quarantinedRefNames = (file?: CompiledSurfaceFile): ReadonlySet<string> =>\n new Set(file?.quarantined.map((entry) => entry.ref));\n\n// Resolution denial with digest proof: a quarantined ref stays callable\n// only when the live schema changed underneath the compile.\nexport const isQuarantinedRef = (\n ref: string,\n liveSchema: unknown,\n file?: CompiledSurfaceFile,\n): boolean => {\n const entry = file?.quarantined.find((candidate) => candidate.ref === ref);\n if (!entry) return false;\n return schemaDigest(liveSchema) === entry.baseSchemaDigest;\n};\n\nexport interface MergedCompiledSurface {\n file: CompiledSurfaceFile;\n droppedOverlays: number;\n droppedQuarantines: number;\n}\n\nconst byRefOrder = (left: { ref: string }, right: { ref: string }): number =>\n left.ref < right.ref ? -1 : left.ref > right.ref ? 1 : 0;\n\n// Federation merge: incoming entries earn a slot only where their recorded\n// base digest proves against the live declared surface and the local\n// artifact has nothing to say about that ref (conflicts skip, local wins).\n// Every consult re-proves merged entries against the live schema, so an\n// imported artifact can never enforce a schema the local surface does not\n// still declare. The applied ledger unions by identity, local first,\n// capped at the store's maximum.\nexport const mergeCompiledSurfaces = (\n local: CompiledSurfaceFile | undefined,\n incoming: CompiledSurfaceFile,\n live: EntropySurfaceSnapshot,\n): MergedCompiledSurface => {\n const liveByRef = new Map(live.actions.map((action) => [action.ref, action.inputSchema]));\n const liveDigestOf = (ref: string): string | undefined => {\n const schema = liveByRef.get(ref);\n return schema === undefined ? undefined : schemaDigest(schema);\n };\n const overlayRefs = new Set((local?.actions ?? []).map((entry) => entry.ref));\n const quarantineRefs = new Set((local?.quarantined ?? []).map((entry) => entry.ref));\n const actions = [...(local?.actions ?? [])];\n const quarantined = [...(local?.quarantined ?? [])];\n let droppedOverlays = 0;\n let droppedQuarantines = 0;\n for (const entry of incoming.actions) {\n if (overlayRefs.has(entry.ref) || quarantineRefs.has(entry.ref)) continue;\n if (liveDigestOf(entry.ref) !== entry.baseSchemaDigest) {\n droppedOverlays++;\n continue;\n }\n actions.push(entry);\n overlayRefs.add(entry.ref);\n }\n for (const entry of incoming.quarantined) {\n if (overlayRefs.has(entry.ref) || quarantineRefs.has(entry.ref)) continue;\n if (liveDigestOf(entry.ref) !== entry.baseSchemaDigest) {\n droppedQuarantines++;\n continue;\n }\n quarantined.push(entry);\n quarantineRefs.add(entry.ref);\n }\n actions.sort(byRefOrder);\n quarantined.sort(byRefOrder);\n const applied: CompiledSurfaceAppliedProposal[] = [];\n const seenApplied = new Set<string>();\n for (const source of [local?.applied ?? [], incoming.applied]) {\n for (const entry of source) {\n const identity = `${entry.kind}:${entry.ref}:${entry.detail}`;\n if (seenApplied.has(identity)) continue;\n seenApplied.add(identity);\n if (applied.length >= MAX_COMPILED_SURFACE_PROPOSALS) break;\n applied.push(entry);\n }\n }\n const file: CompiledSurfaceFile = {\n version: COMPILED_SURFACE_VERSION,\n metricVersion: local?.metricVersion ?? incoming.metricVersion,\n actions,\n quarantined,\n applied,\n gate: local?.gate ?? incoming.gate,\n evidenceDigest: stableJsonHash({\n actions,\n quarantined,\n applied,\n sources: [...(local ? [local.evidenceDigest] : []), incoming.evidenceDigest],\n }),\n };\n return { file, droppedOverlays, droppedQuarantines };\n};\n\nexport interface ReplayViolation {\n ref: string;\n reason: string;\n}\n\n// Replay preservation: every successful call to a ref the compile touched\n// must still parse against the candidate surface \u2014 resolution plus the same\n// TypeBox check the registry's validate stage uses. Untouched refs keep\n// their schema by identity, so replay stays scoped to the touched set.\nexport const replaySuccessfulCalls = (\n surface: EntropySurfaceSnapshot,\n traces: readonly EntropyTraceInput[],\n touchedRefs: ReadonlySet<string>,\n): ReplayViolation[] => {\n const schemaByRef = new Map(surface.actions.map((action) => [action.ref, action.inputSchema]));\n const violations: ReplayViolation[] = [];\n for (const sourceTrace of traces) {\n for (const operation of sourceTrace.operations) {\n if (operation.outcome !== \"succeeded\") continue;\n if (operation.ref.startsWith(\"fabric.\")) continue;\n if (!touchedRefs.has(operation.ref)) continue;\n const schema = schemaByRef.get(operation.ref);\n if (schema === undefined) {\n violations.push({ ref: operation.ref, reason: \"absent from the candidate surface\" });\n continue;\n }\n let valid = false;\n try {\n valid = isPlainRecord(schema) && Value.Check(schema, operation.args);\n } catch {\n valid = false;\n }\n if (!valid) {\n violations.push({\n ref: operation.ref,\n reason: \"recorded arguments no longer validate against the compiled schema\",\n });\n }\n }\n }\n return violations;\n};"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -103,9 +103,10 @@ var resolveScope = (input) => {
103
103
  export {
104
104
  encodeCwdDir,
105
105
  sessionDirForCwd,
106
+ sessionsDirRoot,
106
107
  enumerateAllSessions,
107
108
  AmbiguousSessionError,
108
109
  resolveSessionTarget,
109
110
  resolveScope
110
111
  };
111
- //# sourceMappingURL=chunk-6GRNSFDJ.js.map
112
+ //# sourceMappingURL=chunk-NTI5LLEM.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/memory/discovery.ts"],
4
- "sourcesContent": ["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { readSessionHeader } from \"./normalize.js\";\n\nexport interface SessionRef {\n id: string;\n file: string;\n cwd: string;\n mtime: number;\n}\n\nexport interface ResolveScopeInput {\n agentDir: string;\n cwd: string;\n scope: string;\n sessionId?: string;\n sessionFile?: string;\n maxSessions: number;\n}\n\nconst SESSIONS_SUBDIR = \"sessions\";\n\nconst isJsonlFile = (name: string): boolean => name.endsWith(\".jsonl\");\n\n/** Encode a cwd into the safe directory name pi stores session files under. */\nexport const encodeCwdDir = (cwd: string): string =>\n `--${path.resolve(cwd).replace(/^[/\\\\]/, \"\").replace(/[/\\\\:]/g, \"-\")}--`;\n\n/** Directory pi stores this project's session JSONL files under. */\nexport const sessionDirForCwd = (cwd: string, agentDir: string): string =>\n path.join(agentDir, SESSIONS_SUBDIR, encodeCwdDir(cwd));\n\nconst listJsonlInDir = (dir: string): string[] => {\n try {\n return fs\n .readdirSync(dir, { withFileTypes: true })\n .filter((entry) => entry.isFile() && isJsonlFile(entry.name))\n .map((entry) => path.join(dir, entry.name));\n } catch {\n return [];\n }\n};\n\nconst statMtime = (file: string): number => {\n try {\n return fs.statSync(file).mtimeMs;\n } catch {\n return 0;\n }\n};\n\nconst refFromFile = (file: string): SessionRef => {\n const header = readSessionHeader(file);\n return {\n id: header?.sessionId ?? path.basename(file, \".jsonl\"),\n file,\n cwd: header?.cwd ?? \"\",\n mtime: statMtime(file),\n };\n};\n\nconst sessionsDirRoot = (agentDir: string): string => path.join(agentDir, SESSIONS_SUBDIR);\n\nconst compareRefsByRecency = (left: SessionRef, right: SessionRef): number => {\n if (right.mtime !== left.mtime) return right.mtime - left.mtime;\n return left.file < right.file ? -1 : left.file > right.file ? 1 : 0;\n};\n\n/**\n * Enumerate every session JSONL file under the agent dir, newest first by\n * file mtime. Bounded by `maxSessions`. Returns refs with resolved cwd and\n * sessionId from each file header (falling back to the file stem).\n */\nexport const enumerateAllSessions = (agentDir: string, maxSessions: number): SessionRef[] => {\n const root = sessionsDirRoot(agentDir);\n let projectDirs: string[] = [];\n try {\n projectDirs = fs\n .readdirSync(root, { withFileTypes: true })\n .filter((entry) => entry.isDirectory())\n .map((entry) => path.join(root, entry.name));\n } catch {\n return [];\n }\n const files: string[] = [];\n for (const dir of projectDirs) {\n for (const file of listJsonlInDir(dir)) files.push(file);\n }\n return files\n .map(refFromFile)\n .sort(compareRefsByRecency)\n .slice(0, Math.max(1, maxSessions));\n};\n\nconst newestSessionInDir = (dir: string): SessionRef | null => {\n const files = listJsonlInDir(dir);\n if (files.length === 0) return null;\n return files\n .map(refFromFile)\n .sort(compareRefsByRecency)[0]!;\n};\n\nexport class AmbiguousSessionError extends Error {\n readonly code = \"ambiguous_session\";\n\n constructor(\n readonly session: string,\n readonly candidates: string[],\n ) {\n super(`Session id ${JSON.stringify(session)} is ambiguous; use an exact session file path.`);\n this.name = \"AmbiguousSessionError\";\n }\n}\n\nexport const resolveSessionTarget = (\n agentDir: string,\n target: string,\n): SessionRef | null => {\n if (target.endsWith(\".jsonl\") && fs.existsSync(target)) {\n return refFromFile(path.resolve(target));\n }\n const all = enumerateAllSessions(agentDir, Number.MAX_SAFE_INTEGER);\n const byId = all.filter((ref) => ref.id === target);\n if (byId.length > 1) throw new AmbiguousSessionError(target, byId.map((ref) => ref.file));\n if (byId.length === 1) return byId[0]!;\n const byStem = all.filter((ref) => path.basename(ref.file, \".jsonl\") === target);\n if (byStem.length > 1) throw new AmbiguousSessionError(target, byStem.map((ref) => ref.file));\n return byStem[0] ?? null;\n};\n\n/**\n * Resolve a scope string into the concrete set of session files to search.\n *\n * - `session` (default): the current session file (from invocation context\n * if available, else the newest session for the current cwd).\n * - `project`: all sessions stored under the current cwd's default session dir.\n * - `global`: all sessions under the agent dir, bounded by `maxSessions`.\n * - `session:<id-or-path>`: one specific session by id or file path.\n */\nexport const resolveScope = (input: ResolveScopeInput): SessionRef[] => {\n const scope = input.scope?.trim();\n if (scope.startsWith(\"session:\")) {\n const target = scope.slice(\"session:\".length).trim();\n const ref = resolveSessionTarget(input.agentDir, target);\n return ref ? [ref] : [];\n }\n if (scope === \"global\") {\n return enumerateAllSessions(input.agentDir, input.maxSessions);\n }\n if (scope === \"project\") {\n const dir = sessionDirForCwd(input.cwd, input.agentDir);\n return listJsonlInDir(dir)\n .map(refFromFile)\n .sort(compareRefsByRecency)\n .slice(0, Math.max(1, input.maxSessions));\n }\n // default: session\n if (input.sessionFile) {\n const ref = refFromFile(input.sessionFile);\n return [ref];\n }\n const dir = sessionDirForCwd(input.cwd, input.agentDir);\n const newest = newestSessionInDir(dir);\n return newest ? [newest] : [];\n};\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { readSessionHeader } from \"./normalize.js\";\n\nexport interface SessionRef {\n id: string;\n file: string;\n cwd: string;\n mtime: number;\n}\n\nexport interface ResolveScopeInput {\n agentDir: string;\n cwd: string;\n scope: string;\n sessionId?: string;\n sessionFile?: string;\n maxSessions: number;\n}\n\nconst SESSIONS_SUBDIR = \"sessions\";\n\nconst isJsonlFile = (name: string): boolean => name.endsWith(\".jsonl\");\n\n/** Encode a cwd into the safe directory name pi stores session files under. */\nexport const encodeCwdDir = (cwd: string): string =>\n `--${path.resolve(cwd).replace(/^[/\\\\]/, \"\").replace(/[/\\\\:]/g, \"-\")}--`;\n\n/** Directory pi stores this project's session JSONL files under. */\nexport const sessionDirForCwd = (cwd: string, agentDir: string): string =>\n path.join(agentDir, SESSIONS_SUBDIR, encodeCwdDir(cwd));\n\nconst listJsonlInDir = (dir: string): string[] => {\n try {\n return fs\n .readdirSync(dir, { withFileTypes: true })\n .filter((entry) => entry.isFile() && isJsonlFile(entry.name))\n .map((entry) => path.join(dir, entry.name));\n } catch {\n return [];\n }\n};\n\nconst statMtime = (file: string): number => {\n try {\n return fs.statSync(file).mtimeMs;\n } catch {\n return 0;\n }\n};\n\nconst refFromFile = (file: string): SessionRef => {\n const header = readSessionHeader(file);\n return {\n id: header?.sessionId ?? path.basename(file, \".jsonl\"),\n file,\n cwd: header?.cwd ?? \"\",\n mtime: statMtime(file),\n };\n};\n\nexport const sessionsDirRoot = (agentDir: string): string => path.join(agentDir, SESSIONS_SUBDIR);\n\nconst compareRefsByRecency = (left: SessionRef, right: SessionRef): number => {\n if (right.mtime !== left.mtime) return right.mtime - left.mtime;\n return left.file < right.file ? -1 : left.file > right.file ? 1 : 0;\n};\n\n/**\n * Enumerate every session JSONL file under the agent dir, newest first by\n * file mtime. Bounded by `maxSessions`. Returns refs with resolved cwd and\n * sessionId from each file header (falling back to the file stem).\n */\nexport const enumerateAllSessions = (agentDir: string, maxSessions: number): SessionRef[] => {\n const root = sessionsDirRoot(agentDir);\n let projectDirs: string[] = [];\n try {\n projectDirs = fs\n .readdirSync(root, { withFileTypes: true })\n .filter((entry) => entry.isDirectory())\n .map((entry) => path.join(root, entry.name));\n } catch {\n return [];\n }\n const files: string[] = [];\n for (const dir of projectDirs) {\n for (const file of listJsonlInDir(dir)) files.push(file);\n }\n return files\n .map(refFromFile)\n .sort(compareRefsByRecency)\n .slice(0, Math.max(1, maxSessions));\n};\n\nconst newestSessionInDir = (dir: string): SessionRef | null => {\n const files = listJsonlInDir(dir);\n if (files.length === 0) return null;\n return files\n .map(refFromFile)\n .sort(compareRefsByRecency)[0]!;\n};\n\nexport class AmbiguousSessionError extends Error {\n readonly code = \"ambiguous_session\";\n\n constructor(\n readonly session: string,\n readonly candidates: string[],\n ) {\n super(`Session id ${JSON.stringify(session)} is ambiguous; use an exact session file path.`);\n this.name = \"AmbiguousSessionError\";\n }\n}\n\nexport const resolveSessionTarget = (\n agentDir: string,\n target: string,\n): SessionRef | null => {\n if (target.endsWith(\".jsonl\") && fs.existsSync(target)) {\n return refFromFile(path.resolve(target));\n }\n const all = enumerateAllSessions(agentDir, Number.MAX_SAFE_INTEGER);\n const byId = all.filter((ref) => ref.id === target);\n if (byId.length > 1) throw new AmbiguousSessionError(target, byId.map((ref) => ref.file));\n if (byId.length === 1) return byId[0]!;\n const byStem = all.filter((ref) => path.basename(ref.file, \".jsonl\") === target);\n if (byStem.length > 1) throw new AmbiguousSessionError(target, byStem.map((ref) => ref.file));\n return byStem[0] ?? null;\n};\n\n/**\n * Resolve a scope string into the concrete set of session files to search.\n *\n * - `session` (default): the current session file (from invocation context\n * if available, else the newest session for the current cwd).\n * - `project`: all sessions stored under the current cwd's default session dir.\n * - `global`: all sessions under the agent dir, bounded by `maxSessions`.\n * - `session:<id-or-path>`: one specific session by id or file path.\n */\nexport const resolveScope = (input: ResolveScopeInput): SessionRef[] => {\n const scope = input.scope?.trim();\n if (scope.startsWith(\"session:\")) {\n const target = scope.slice(\"session:\".length).trim();\n const ref = resolveSessionTarget(input.agentDir, target);\n return ref ? [ref] : [];\n }\n if (scope === \"global\") {\n return enumerateAllSessions(input.agentDir, input.maxSessions);\n }\n if (scope === \"project\") {\n const dir = sessionDirForCwd(input.cwd, input.agentDir);\n return listJsonlInDir(dir)\n .map(refFromFile)\n .sort(compareRefsByRecency)\n .slice(0, Math.max(1, input.maxSessions));\n }\n // default: session\n if (input.sessionFile) {\n const ref = refFromFile(input.sessionFile);\n return [ref];\n }\n const dir = sessionDirForCwd(input.cwd, input.agentDir);\n const newest = newestSessionInDir(dir);\n return newest ? [newest] : [];\n};\n"],
5
+ "mappings": "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",
6
6
  "names": ["dir"]
7
7
  }
@@ -9,7 +9,7 @@ import {
9
9
  effectiveSchemaFor,
10
10
  isQuarantinedRef,
11
11
  quarantinedRefNames
12
- } from "./chunk-OTB7OOQS.js";
12
+ } from "./chunk-IITDYSG5.js";
13
13
  import {
14
14
  FABRIC_NESTED_TOOL_CALL_ID_PREFIX
15
15
  } from "./chunk-HDKEA77S.js";
@@ -711,7 +711,13 @@ var ActionRegistry = class {
711
711
  tools = /* @__PURE__ */ new Map();
712
712
  byServer.set(server, tools);
713
713
  }
714
- tools.set(toolName, { name: toolName, inputSchema: descriptor.inputSchema });
714
+ tools.set(toolName, {
715
+ name: toolName,
716
+ inputSchema: effectiveInputSchema(
717
+ `mcp.${descriptor.name}`,
718
+ descriptor.inputSchema
719
+ )
720
+ });
715
721
  }
716
722
  if (byServer.size > 0) {
717
723
  sources.mcpServers = [...byServer.entries()].map(([server, tools]) => ({
@@ -727,7 +733,10 @@ var ActionRegistry = class {
727
733
  if (descriptors.length > 0) {
728
734
  sources.extensionTools = descriptors.map((descriptor) => ({
729
735
  name: descriptor.name,
730
- inputSchema: descriptor.inputSchema
736
+ inputSchema: effectiveInputSchema(
737
+ `extensions.${descriptor.name}`,
738
+ descriptor.inputSchema
739
+ )
731
740
  }));
732
741
  }
733
742
  } catch {
@@ -735,9 +744,17 @@ var ActionRegistry = class {
735
744
  }
736
745
  return sources;
737
746
  }
747
+ // The model-facing discovery view: quarantined refs hide here, and the
748
+ // compiled overlay teaches: listed schemas show the compiled shape so
749
+ // tightened enums are visible before the first call. Pass `declared: true`
750
+ // for the compile's base-surface truth, which keeps quarantined refs
751
+ // visible and schemas declared so base-digest proofs and artifact
752
+ // carry-forward read the live contract. Capability-view paths stay
753
+ // declared everywhere (see describe): committed views pin declared
754
+ // digests, and a surface activation must never invalidate them.
738
755
  async list(request, context) {
739
756
  if (context.capabilityView) {
740
- const refs = Object.keys(context.capabilityView.bindings).filter((ref) => !request.provider || ref.startsWith(`${request.provider}.`)).filter((ref) => !activeQuarantinedRefNames().has(ref)).sort();
757
+ const refs = Object.keys(context.capabilityView.bindings).filter((ref) => !request.provider || ref.startsWith(`${request.provider}.`)).filter((ref) => request.declared || !activeQuarantinedRefNames().has(ref)).sort();
741
758
  const actions = await Promise.all(refs.map((ref) => this.describe(ref, context)));
742
759
  const query = request.query?.normalize("NFKC").trim().toLowerCase();
743
760
  return actions.filter((action) => !request.namespace || action.namespace === request.namespace).filter(
@@ -749,8 +766,17 @@ var ActionRegistry = class {
749
766
  providers.map(async (provider) => {
750
767
  const descriptors = await provider.list(request, context);
751
768
  return descriptors.filter(
752
- (descriptor) => !activeQuarantinedRefNames().has(`${provider.name}.${descriptor.name}`)
753
- ).map((descriptor) => resolveDescriptor(provider, descriptor));
769
+ (descriptor) => request.declared || !activeQuarantinedRefNames().has(`${provider.name}.${descriptor.name}`)
770
+ ).map((descriptor) => {
771
+ const action = resolveDescriptor(provider, descriptor);
772
+ return request.declared ? action : {
773
+ ...action,
774
+ inputSchema: effectiveInputSchema(
775
+ action.ref,
776
+ action.inputSchema
777
+ )
778
+ };
779
+ });
754
780
  })
755
781
  );
756
782
  const limit = Math.max(1, Math.min(request.limit ?? 100, 1e3));
@@ -1248,7 +1274,10 @@ var ActionRegistry = class {
1248
1274
  * Prepare + pre-launch a speculative call discovered in a partially
1249
1275
  * streamed program (see src/speculation). Pure pipeline only: descriptor
1250
1276
  * resolution, the eligibility gate on the resolved action, argument
1251
- * preparation, and schema validation. authorize/approve/audits are skipped
1277
+ * preparation, and schema validation. The compiled entropy surface gates
1278
+ * launches too: quarantined refs never pre-launch and overlays validate
1279
+ * prepared arguments, so the store never warms a call the serve path
1280
+ * would reject. authorize/approve/audits are skipped
1252
1281
  * because the eligibility gate restricts this path to actions that never
1253
1282
  * prompt, and the real call re-runs the full pipeline on a serve miss.
1254
1283
  * Side-channel outputs are captured into `replay` so the serve path can
@@ -1267,8 +1296,15 @@ var ActionRegistry = class {
1267
1296
  if (expectedDescriptorHash && actionDescriptorHash(action) !== expectedDescriptorHash) {
1268
1297
  return void 0;
1269
1298
  }
1299
+ if (isActiveQuarantine(provider.name, actionName, descriptor.inputSchema)) {
1300
+ return void 0;
1301
+ }
1270
1302
  if (!this.#speculationEligibility(action)) return void 0;
1271
- const catalogInput = applyActiveArgRepairs(action.ref, args, action.inputSchema);
1303
+ const effectiveSchema = effectiveInputSchema(
1304
+ action.ref,
1305
+ action.inputSchema
1306
+ );
1307
+ const catalogInput = applyActiveArgRepairs(action.ref, args, effectiveSchema);
1272
1308
  const preparedArgs = provider.prepareArguments ? await runAbortable(context.signal, () => provider.prepareArguments(actionName, catalogInput, context)) : catalogInput;
1273
1309
  if (typeof preparedArgs !== "object" || preparedArgs === null || Array.isArray(preparedArgs)) {
1274
1310
  return void 0;
@@ -1276,9 +1312,9 @@ var ActionRegistry = class {
1276
1312
  const repairedArgs = applyActiveArgRepairs(
1277
1313
  action.ref,
1278
1314
  preparedArgs,
1279
- action.inputSchema
1315
+ effectiveSchema
1280
1316
  );
1281
- if (validationMessage(action.inputSchema, repairedArgs)) return void 0;
1317
+ if (validationMessage(effectiveSchema, repairedArgs)) return void 0;
1282
1318
  const nestedToolCallId = `${NESTED_TOOL_CALL_ID_PREFIX}spec-${randomUUID2()}`;
1283
1319
  return {
1284
1320
  preparedArgs: repairedArgs,
@@ -1525,4 +1561,4 @@ export {
1525
1561
  NESTED_TOOL_CALL_ID_PREFIX,
1526
1562
  ActionRegistry
1527
1563
  };
1528
- //# sourceMappingURL=chunk-NXTORPRY.js.map
1564
+ //# sourceMappingURL=chunk-U3DHW7UQ.js.map