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.
- package/dist/chunks/{chunk-HDTW3CML.js → chunk-6XUQ7MKH.js} +4 -2
- package/dist/chunks/{chunk-HDTW3CML.js.map → chunk-6XUQ7MKH.js.map} +2 -2
- package/dist/chunks/{chunk-UKZ452XN.js → chunk-75CLSHZE.js} +2 -2
- package/dist/chunks/{chunk-5OVYFN4A.js → chunk-BUXNRNJC.js} +2 -2
- package/dist/chunks/{chunk-OTB7OOQS.js → chunk-IITDYSG5.js} +62 -1
- package/dist/chunks/chunk-IITDYSG5.js.map +7 -0
- package/dist/chunks/{chunk-6GRNSFDJ.js → chunk-NTI5LLEM.js} +2 -1
- package/dist/chunks/{chunk-6GRNSFDJ.js.map → chunk-NTI5LLEM.js.map} +2 -2
- package/dist/chunks/{chunk-NXTORPRY.js → chunk-U3DHW7UQ.js} +47 -11
- package/dist/chunks/chunk-U3DHW7UQ.js.map +7 -0
- package/dist/chunks/{chunk-5IFANSBG.js → chunk-W7PLBXJH.js} +170 -14
- package/dist/chunks/chunk-W7PLBXJH.js.map +7 -0
- package/dist/chunks/{fabric-runtime-state-YKNG3IDT.js → fabric-runtime-state-EMLV5K2G.js} +7 -7
- package/dist/commands/fabric.d.ts.map +1 -1
- package/dist/core/action-registry.d.ts +5 -1
- package/dist/core/action-registry.d.ts.map +1 -1
- package/dist/core/action-registry.js +2 -2
- package/dist/entropy/compiled-store.d.ts +1 -0
- package/dist/entropy/compiled-store.d.ts.map +1 -1
- package/dist/entropy/compiled-surface.d.ts +6 -0
- package/dist/entropy/compiled-surface.d.ts.map +1 -1
- package/dist/entropy/index.d.ts +1 -0
- package/dist/entropy/index.d.ts.map +1 -1
- package/dist/entropy/index.js +12 -4
- package/dist/entropy/passes.d.ts.map +1 -1
- package/dist/entropy/sessions.d.ts +1 -0
- package/dist/entropy/sessions.d.ts.map +1 -1
- package/dist/entropy/surface.d.ts +1 -0
- package/dist/entropy/surface.d.ts.map +1 -1
- package/dist/entropy/trial.d.ts +34 -0
- package/dist/entropy/trial.d.ts.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +127 -22
- package/dist/index.js.map +2 -2
- package/dist/memory/discovery.d.ts +1 -0
- package/dist/memory/discovery.d.ts.map +1 -1
- package/dist/memory/discovery.js +5 -3
- package/dist/providers/memory-provider.js +2 -2
- package/docs/certification.md +1 -1
- package/docs/entropy.md +74 -17
- package/docs/speculation.md +13 -0
- package/package.json +1 -1
- package/dist/chunks/chunk-5IFANSBG.js.map +0 -7
- package/dist/chunks/chunk-NXTORPRY.js.map +0 -7
- package/dist/chunks/chunk-OTB7OOQS.js.map +0 -7
- /package/dist/chunks/{chunk-UKZ452XN.js.map → chunk-75CLSHZE.js.map} +0 -0
- /package/dist/chunks/{chunk-5OVYFN4A.js.map → chunk-BUXNRNJC.js.map} +0 -0
- /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-
|
|
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-
|
|
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-
|
|
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-
|
|
2450
|
+
//# sourceMappingURL=chunk-75CLSHZE.js.map
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
enumerateAllSessions,
|
|
16
16
|
resolveScope,
|
|
17
17
|
resolveSessionTarget
|
|
18
|
-
} from "./chunk-
|
|
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-
|
|
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-
|
|
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-
|
|
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\
|
|
5
|
-
"mappings": ";;;;;AAAA,OAAO,QAAQ;AACf,OAAO,UAAU;AAmBjB,IAAM,kBAAkB;AAExB,IAAM,cAAc,CAAC,SAA0B,KAAK,SAAS,QAAQ;AAG9D,IAAM,eAAe,CAAC,QAC3B,KAAK,KAAK,QAAQ,GAAG,EAAE,QAAQ,UAAU,EAAE,EAAE,QAAQ,WAAW,GAAG,CAAC;AAG/D,IAAM,mBAAmB,CAAC,KAAa,aAC5C,KAAK,KAAK,UAAU,iBAAiB,aAAa,GAAG,CAAC;AAExD,IAAM,iBAAiB,CAAC,QAA0B;AAChD,MAAI;AACF,WAAO,GACJ,YAAY,KAAK,EAAE,eAAe,KAAK,CAAC,EACxC,OAAO,CAAC,UAAU,MAAM,OAAO,KAAK,YAAY,MAAM,IAAI,CAAC,EAC3D,IAAI,CAAC,UAAU,KAAK,KAAK,KAAK,MAAM,IAAI,CAAC;AAAA,EAC9C,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAEA,IAAM,YAAY,CAAC,SAAyB;AAC1C,MAAI;AACF,WAAO,GAAG,SAAS,IAAI,EAAE;AAAA,EAC3B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,IAAM,cAAc,CAAC,SAA6B;AAChD,QAAM,SAAS,kBAAkB,IAAI;AACrC,SAAO;AAAA,IACL,IAAI,QAAQ,aAAa,KAAK,SAAS,MAAM,QAAQ;AAAA,IACrD;AAAA,IACA,KAAK,QAAQ,OAAO;AAAA,IACpB,OAAO,UAAU,IAAI;AAAA,EACvB;AACF;
|
|
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-
|
|
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, {
|
|
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:
|
|
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) =>
|
|
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.
|
|
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
|
|
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
|
-
|
|
1315
|
+
effectiveSchema
|
|
1280
1316
|
);
|
|
1281
|
-
if (validationMessage(
|
|
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-
|
|
1564
|
+
//# sourceMappingURL=chunk-U3DHW7UQ.js.map
|