UNPKG

mcard-js

Version:

MCard - Content-addressable storage with cryptographic hashing, handle resolution, and vector search for Node.js and browsers

1,613 lines (1,584 loc) 85.5 kB
import { LLMRuntime, chatMonad, promptMonad } from "./chunk-K35KFTEA.js"; import { LLMConfig } from "./chunk-QXPHMSPA.js"; import { LambdaRuntime, RuntimeFactory, alphaEquivalent, alphaNormalize, alphaRename, betaReduce, boundVariables, deserializeTerm, difference, etaEquivalent, etaExpand, etaNormalize, etaReduce, etaReduceE, findEtaRedexes, findInnermostRedex, findLeftmostRedex, freeVariables, generateFresh, generateFreshFor, hasNormalForm, intersection, isAbs, isApp, isClosed, isEtaRedex, isFreeIn, isNormalForm, isRedex, isVar, loadTerm, mcardToTerm, mkAbs, mkApp, mkVar, normalize, parseLambdaExpression, prettyPrintDeep, prettyPrintShallow, reduceStep, serializeTerm, storeTerm, termExists, termToMCard } from "./chunk-CBH4YKB4.js"; import { ErrorCodes, FaroSidecar, IndexedDBEngine, LensProtocol, MCardStore, Reader, ServiceWorkerPTR, State, ValidationRegistry, VerificationStatus, Writer, computeHash, validationRegistry } from "./chunk-AWGFLRLI.js"; import { IO } from "./chunk-MPMRBT5R.js"; import { Either } from "./chunk-2KADE3SE.js"; import { SqliteNodeEngine } from "./chunk-GVX5LDLH.js"; import { SqliteWasmEngine } from "./chunk-B7VEU4S2.js"; import { ContentHandle, HandleValidationError, validateHandle } from "./chunk-U3FWUPD3.js"; import { ALGORITHM_HIERARCHY, EVENT_CONSTANTS } from "./chunk-KEC7YFG3.js"; import { CardCollection, Maybe } from "./chunk-EFKMZTT2.js"; import { FileIO_exports, Loader_exports } from "./chunk-AVXJOPUE.js"; import { ContentTypeInterpreter, MCard, createPCardDOTSMetadata, createVCardDOTSMetadata } from "./chunk-QPZ2HNSU.js"; import { GTime, HashValidator } from "./chunk-7NKII2JA.js"; import { __export } from "./chunk-MLKGABMK.js"; // src/ptr/SandboxWorker.ts var WORKER_CODE = ` // Multi-runtime sandboxed execution environment let pyodide = null; let pyodideLoading = null; // Pyodide CDN URL - can be overridden via message const PYODIDE_CDN = 'https://cdn.jsdelivr.net/pyodide/v0.24.1/full/'; // Load Pyodide on demand (lazy loading) async function loadPyodide() { if (pyodide) return pyodide; if (pyodideLoading) return pyodideLoading; pyodideLoading = (async () => { // Import Pyodide from CDN importScripts(PYODIDE_CDN + 'pyodide.js'); pyodide = await self.loadPyodide({ indexURL: PYODIDE_CDN, }); console.log('[SandboxWorker] Pyodide loaded successfully'); return pyodide; })(); return pyodideLoading; } self.onmessage = async function(e) { const request = e.data; try { if (request.method === 'pcard.execute') { const { pcard, context } = request.params; const runtime = pcard.runtime || 'javascript'; let result; if (runtime === 'python' || runtime === 'py') { result = await executePython(pcard.code, pcard.input, context); } else { result = await executeJavaScript(pcard.code, pcard.input, context); } self.postMessage({ jsonrpc: '2.0', id: request.id, result }); } else if (request.method === 'pcard.verify') { const { expectedOutput, actualOutput } = request.params; const matches = JSON.stringify(expectedOutput) === JSON.stringify(actualOutput); self.postMessage({ jsonrpc: '2.0', id: request.id, result: { verified: matches } }); } else if (request.method === 'runtime.preload') { // Preload Pyodide for faster first execution const runtime = request.params?.runtime || 'python'; if (runtime === 'python' || runtime === 'py') { await loadPyodide(); self.postMessage({ jsonrpc: '2.0', id: request.id, result: { loaded: true, runtime: 'python' } }); } else { self.postMessage({ jsonrpc: '2.0', id: request.id, result: { loaded: true, runtime: 'javascript' } }); } } else { throw new Error('Method not found: ' + request.method); } } catch (error) { self.postMessage({ jsonrpc: '2.0', id: request.id, error: { code: -32000, message: error.message || 'Execution error' } }); } }; // Execute JavaScript code in sandbox async function executeJavaScript(code, input, context) { const fn = new Function('input', 'context', code); return fn(input, context || {}); } // Execute Python code via Pyodide async function executePython(code, input, context) { const py = await loadPyodide(); // Convert input to Python dict py.globals.set('input', py.toPy(input || {})); py.globals.set('context', py.toPy(context || {})); // Wrap code to capture result const wrappedCode = \` import json # Make input accessible as variables _input = input.to_py() if hasattr(input, 'to_py') else input _context = context.to_py() if hasattr(context, 'to_py') else context # Standard variable names for CLM a = _input.get('a') if isinstance(_input, dict) else None b = _input.get('b') if isinstance(_input, dict) else None values = _input.get('values') if isinstance(_input, dict) else None result = None \${code} # Return result result \`; try { const pyResult = await py.runPythonAsync(wrappedCode); // Convert Python result to JavaScript return pyResult?.toJs ? pyResult.toJs({ dict_converter: Object.fromEntries }) : pyResult; } finally { // Clean up globals py.globals.delete('input'); py.globals.delete('context'); } } `; var SandboxWorker = class { worker = null; pythonLoaded = false; pendingRequests = /* @__PURE__ */ new Map(); defaultTimeout = 5e3; // 5 seconds /** * Initialize the sandbox worker */ async init() { const blob = new Blob([WORKER_CODE], { type: "application/javascript" }); const workerUrl = URL.createObjectURL(blob); this.worker = new Worker(workerUrl); this.worker.onmessage = this.handleMessage.bind(this); this.worker.onerror = this.handleError.bind(this); URL.revokeObjectURL(workerUrl); } requestCounter = 0; /** * Execute code in sandbox * @param code - Code to execute * @param input - Input data for the code * @param context - Optional execution context * @param runtime - Runtime to use: 'javascript' (default) or 'python' */ async execute(code, input, context, runtime = "javascript") { if (!this.worker) { throw new Error("Worker not initialized. Call init() first."); } const request = { jsonrpc: "2.0", id: ++this.requestCounter, method: "pcard.execute", params: { pcard: { code, input, runtime }, context } }; return this.sendRequest(request); } /** * Preload a runtime for faster first execution * Useful for Python which requires loading Pyodide (~10MB) * @param runtime - Runtime to preload: 'python' or 'javascript' */ async preloadRuntime(runtime = "python") { if (!this.worker) { throw new Error("Worker not initialized. Call init() first."); } const request = { jsonrpc: "2.0", id: ++this.requestCounter, method: "runtime.preload", params: { runtime } }; const result = await this.sendRequest(request); if (runtime === "python" || runtime === "py") { this.pythonLoaded = true; } return result; } /** * Check if Python runtime is loaded */ isPythonLoaded() { return this.pythonLoaded; } /** * Verify output matches expected * Note: Uses internal JSON-RPC format with direct values */ async verify(hash, expectedOutput, actualOutput) { if (!this.worker) { throw new Error("Worker not initialized. Call init() first."); } const request = { jsonrpc: "2.0", id: ++this.requestCounter, method: "pcard.verify", params: { hash, expectedOutput, actualOutput } }; return this.sendRequest(request); } /** * Send request and wait for response */ sendRequest(request) { return new Promise((resolve4, reject) => { const timeout = setTimeout(() => { this.pendingRequests.delete(request.id); reject(new Error(`Request ${request.id} timed out`)); }, this.defaultTimeout); this.pendingRequests.set(request.id, { resolve: resolve4, reject, timeout }); this.worker.postMessage(request); }); } /** * Handle worker message */ handleMessage(event) { const response = event.data; const pending = this.pendingRequests.get(response.id); if (pending) { clearTimeout(pending.timeout); this.pendingRequests.delete(response.id); if (response.error) { pending.reject(new Error(`Error ${response.error.code}: ${response.error.message}`)); } else { pending.resolve(response.result); } } } /** * Handle worker error */ handleError(event) { console.error("Worker error:", event.message); for (const [id, pending] of this.pendingRequests) { clearTimeout(pending.timeout); pending.reject(new Error(`Worker error: ${event.message}`)); } this.pendingRequests.clear(); } /** * Terminate the worker */ terminate() { if (this.worker) { for (const [id, pending] of this.pendingRequests) { clearTimeout(pending.timeout); pending.reject(new Error("Worker terminated")); } this.pendingRequests.clear(); this.worker.terminate(); this.worker = null; } } /** * Set timeout for requests */ setTimeout(ms) { this.defaultTimeout = ms; } }; // src/ptr/lambda/index.ts var lambda_exports = {}; __export(lambda_exports, { LambdaRuntime: () => LambdaRuntime, alphaEquivalent: () => alphaEquivalent, alphaNormalize: () => alphaNormalize, alphaRename: () => alphaRename, betaReduce: () => betaReduce, boundVariables: () => boundVariables, deserializeTerm: () => deserializeTerm, difference: () => difference, etaEquivalent: () => etaEquivalent, etaExpand: () => etaExpand, etaNormalize: () => etaNormalize, etaReduce: () => etaReduce, etaReduceE: () => etaReduceE, findEtaRedexes: () => findEtaRedexes, findInnermostRedex: () => findInnermostRedex, findLeftmostRedex: () => findLeftmostRedex, freeVariables: () => freeVariables, generateFresh: () => generateFresh, generateFreshFor: () => generateFreshFor, hasNormalForm: () => hasNormalForm, intersection: () => intersection, isAbs: () => isAbs, isApp: () => isApp, isClosed: () => isClosed, isEtaRedex: () => isEtaRedex, isFreeIn: () => isFreeIn, isNormalForm: () => isNormalForm, isRedex: () => isRedex, isVar: () => isVar, loadTerm: () => loadTerm, mcardToTerm: () => mcardToTerm, mkAbs: () => mkAbs, mkApp: () => mkApp, mkVar: () => mkVar, normalize: () => normalize, parseLambdaExpression: () => parseLambdaExpression, prettyPrintDeep: () => prettyPrintDeep, prettyPrintShallow: () => prettyPrintShallow, reduceStep: () => reduceStep, serializeTerm: () => serializeTerm, storeTerm: () => storeTerm, termExists: () => termExists, termToMCard: () => termToMCard }); // src/ptr/node/clm/utils.ts function resultsEqual(a, b, tolerance = 1e-9) { if (a === b) return true; if (a == null || b == null) return false; if (typeof a === "number" && typeof b === "number") { if (Number.isNaN(a) && Number.isNaN(b)) return true; if (!Number.isFinite(a) || !Number.isFinite(b)) return a === b; return Math.abs(a - b) <= tolerance * Math.max(1, Math.abs(a), Math.abs(b)); } if (Array.isArray(a) && Array.isArray(b)) { if (a.length !== b.length) return false; return a.every((val, i) => resultsEqual(val, b[i], tolerance)); } if (typeof a === "object" && typeof b === "object") { const keysA = Object.keys(a); const keysB = Object.keys(b); if (keysA.length !== keysB.length) return false; return keysA.every( (key) => keysB.includes(key) && resultsEqual(a[key], b[key], tolerance) ); } return a === b; } function asObject(input) { return typeof input === "object" && input !== null ? input : {}; } function buildBaseContext(clm, input) { const inputObj = asObject(input); return { balanced: clm.clm.balanced, params: inputObj, ...inputObj }; } function buildExecutionResult(success, result, startTime, clm, error, boundary) { return { success, result, error, executionTime: Date.now() - startTime, clm: { chapter: clm.chapter?.title || "Unknown", concept: clm.clm.abstract?.concept || "Unknown", manifestation: clm.clm.concrete?.manifestation || "Unknown", boundary } }; } function isRecursiveCLM(runtimeName) { return runtimeName.endsWith(".clm") || runtimeName.endsWith(".yaml") || runtimeName.endsWith(".yml"); } function isMultiRuntime(clm) { const runtimesConfig = clm.clm?.concrete?.runtimes_config; return Array.isArray(runtimesConfig) && runtimesConfig.length > 0; } // src/ptr/node/clm/runner.ts import * as path5 from "path"; import * as yaml2 from "yaml"; // src/model/PCard.ts import { parse } from "yaml"; var PCard = class _PCard extends MCard { parsedClm; isLens; constructor(content, hash, g_time, contentType, hashFunction, parsedClm, isLens) { super(content, hash, g_time, contentType, hashFunction); this.parsedClm = parsedClm; this.isLens = isLens; } /** * Create a new PCard from CLM content * * @param content - The CLM YAML string or bytes * @param hashAlgorithm - Hash algorithm to use * @param isLens - Whether this acts primarily as a Lens (default true) */ static async create(content, hashAlgorithm = "sha256", isLens = true) { let textContent; let bytes; if (typeof content === "string") { textContent = content; bytes = new TextEncoder().encode(content); } else { bytes = content; textContent = new TextDecoder().decode(content); } let parsedClm; try { parsedClm = parse(textContent); if (typeof parsedClm !== "object" || parsedClm === null) { throw new Error("PCard content must be a YAML dictionary"); } } catch (e) { throw new Error(`Invalid YAML content for PCard: ${e.message}`); } const hash = await HashValidator.computeHash(bytes, hashAlgorithm); const g_time = GTime.stampNow(hashAlgorithm); const contentType = ContentTypeInterpreter.detect(bytes); return new _PCard(bytes, hash, g_time, contentType, hashAlgorithm, parsedClm, isLens); } /** * Get DOTS vocabulary metadata for this PCard * * Automatically extracts dependencies from the CLM structure if available. */ getDOTSMetadata() { const tightRefs = []; const looseRefs = []; if (Array.isArray(this.parsedClm.tight_deps)) { tightRefs.push(...this.parsedClm.tight_deps); } if (Array.isArray(this.parsedClm.dependencies)) { tightRefs.push(...this.parsedClm.dependencies); } if (Array.isArray(this.parsedClm.loose_deps)) { looseRefs.push(...this.parsedClm.loose_deps); } if (Array.isArray(this.parsedClm.alternatives)) { looseRefs.push(...this.parsedClm.alternatives); } return createPCardDOTSMetadata( this.isLens, tightRefs, looseRefs ); } /** * Get the parsed CLM object */ get clm() { return this.parsedClm; } // ========================================================================= // Legacy Aliases and Recursive Accessors // ========================================================================= getSection(sectionName, aliases) { let val = this.parsedClm[sectionName]; if (val) return val; for (const alias of aliases) { val = this.parsedClm[alias]; if (val) return val; } const clmInner = this.parsedClm.clm; if (typeof clmInner === "object" && clmInner !== null) { val = clmInner[sectionName]; if (val) return val; for (const alias of aliases) { val = clmInner[alias]; if (val) return val; } } return void 0; } /** * Get the Abstract Specification section (UPTV Role: Abstract) */ get abstract() { return this.getSection("abstract", ["abstract_spec"]); } /** * Get the Concrete Implementation section (UPTV Role: Concrete) */ get concrete() { return this.getSection("concrete", ["concrete_impl", "impl"]); } /** * Get the Balanced Expectations (tests) section (UPTV Role: Balanced) */ get balanced() { return this.getSection("balanced", ["balanced_expectations", "expectations"]); } /** * Get the Abstract Specification section (Legacy) */ get abstractSpec() { return this.abstract; } /** * Get the Concrete Implementation section (Legacy) */ get concreteImpl() { return this.concrete; } /** * Get the Balanced Expectations (tests) section (Legacy) */ get balancedExpectations() { return this.balanced; } // ========================================================================= // SMC ALGEBRAIC COMBINATORS (Profunctor Composition) // ========================================================================= // // These methods implement the Symmetric Monoidal Category structure, // enabling algebraic composition of PCards as profunctors. // // Composition Laws (Categorical Coherence): // - Associativity: (f.andThen(g)).andThen(h) ≡ f.andThen(g.andThen(h)) // - Identity: id.andThen(f) ≡ f ≡ f.andThen(id) // - Tensor Associativity: (A ⊗ B) ⊗ C ≅ A ⊗ (B ⊗ C) // - Symmetry Involution: swap().swap() ≡ id // ========================================================================= /** * Sequential Composition via Coend (P ⨾ Q) * * Implements profunctor composition using the Coend formula: * * (P ⨾ Q)(A, C) = ∫ᴮ P(A, B) × Q(B, C) * * Where: * - this is P: A → B * - otherPCard is Q: B → C * - Result is P ⨾ Q: A → C * * The Coend (∫ᴮ) "integrates out" the intermediate type B by: * 1. Matching P's output type with Q's input type * 2. Creating a chain where P's result feeds into Q * 3. The composition is associative: (P ⨾ Q) ⨾ R = P ⨾ (Q ⨾ R) * * In PTR execution: * - P is executed first (prep → exec → post) * - P's output VCard becomes Q's input VCard * - Q is executed second * - Final result is Q's output VCard * * Note: Named 'andThen' to avoid conflict with Promise.then (Thenable). * * @param otherPCard - The PCard to execute after this one (Q in P ⨾ Q) * @returns A new PCard representing the composed profunctor (P ⨾ Q) */ async andThen(otherPCard) { const newClm = { chapter: { id: `composed_${this.hash.substring(0, 8)}_${otherPCard.hash.substring(0, 8)}`, title: "Sequentially Composed Function", goal: `Compose ${this.hash} then ${otherPCard.hash}` }, clm: { abstract: { type: "sequential_composition", coend_formula: "\u222B\u1D2E P(A,B) \xD7 Q(B,C)", steps: [this.hash, otherPCard.hash] }, concrete: { runtime: "ptr", operation: "compose_sequential", steps: [this.hash, otherPCard.hash] } } }; const { stringify: stringify2 } = await import("yaml"); return _PCard.create(stringify2(newClm), this.hashFunction); } /** * Tensor Product ($A \otimes B$) * * Runs this PCard and otherPCard in parallel. */ async andAlso(otherPCard) { const newClm = { chapter: { id: `parallel_${this.hash.substring(0, 8)}_${otherPCard.hash.substring(0, 8)}`, title: "Parallel Function", goal: `Run ${this.hash} and ${otherPCard.hash} in parallel` }, clm: { abstract: { type: "tensor_product", left: this.hash, right: otherPCard.hash }, concrete: { runtime: "ptr", operation: "compose_parallel", components: [this.hash, otherPCard.hash] } } }; const { stringify: stringify2 } = await import("yaml"); return _PCard.create(stringify2(newClm), this.hashFunction); } /** * Symmetry ($\sigma$) * * Swaps the input/output ports of a tensor product. */ async swap() { const newClm = { chapter: { id: `swapped_${this.hash.substring(0, 8)}`, title: "Swapped Function", goal: `Swap inputs/outputs of ${this.hash}` }, clm: { abstract: { type: "symmetry_swap", target: this.hash }, concrete: { runtime: "ptr", operation: "apply_symmetry", target: this.hash } } }; const { stringify: stringify2 } = await import("yaml"); return _PCard.create(stringify2(newClm), this.hashFunction); } // ========================================================================= // Universal Tooling Interface // ========================================================================= /** * Run the Balanced Expectations (Proof) */ verify() { return { status: "pending_verification", proof_plan: this.balanced, target: this.hash }; } /** * Run with instrumentation (eBPF/Tracing) */ profile() { return { status: "profiling_ready", target: this.hash, instrumentation: "standard" }; } /** * Run in Operative mode (Step-by-step) */ debug() { return { status: "debug_session_created", mode: "operative", target: this.hash }; } /** * Return documentation/explanation */ explain() { return { abstract: this.abstract, narrative: this.parsedClm.chapter, dots_metadata: this.getDOTSMetadata() }; } // ========================================================================= // Petri Net Transition Semantics // ========================================================================= /** * Get input VCard references (Pre-set: •t) * * These represent the preconditions that must be satisfied before * this PCard (Transition) can fire. * * @returns Array of input VCard references from CLM specification */ getInputVCardRefs() { const refs = []; const getField = (key) => { return this.parsedClm[key] || this.parsedClm.clm?.[key]; }; const inputVCards = getField("input_vcards") || getField("preconditions") || getField("requires"); if (Array.isArray(inputVCards)) { for (const ref of inputVCards) { if (typeof ref === "string") { refs.push({ handle: ref }); } else if (ref.handle) { refs.push({ handle: ref.handle, expectedHash: ref.hash || ref.expected_hash, purpose: ref.purpose }); } } } const verification = getField("verification"); const verificationRefs = verification?.pcard_refs || []; for (const ref of verificationRefs) { if (typeof ref === "string") { refs.push({ handle: `auth://${ref}`, purpose: "authenticate" }); } else if (ref.hash) { refs.push({ handle: `auth://${ref.hash}`, expectedHash: ref.hash, purpose: ref.purpose || "authenticate" }); } } return refs; } /** * Get output VCard specifications (Post-set: t•) * * These define what VCards (Tokens) this PCard produces when fired. * * @returns Array of output VCard specifications */ getOutputVCardSpecs() { const specs = []; const getField = (key) => { return this.parsedClm[key] || this.parsedClm.clm?.[key]; }; const outputVCards = getField("output_vcards") || getField("postconditions") || getField("produces"); if (Array.isArray(outputVCards)) { for (const spec of outputVCards) { if (typeof spec === "string") { specs.push({ handle: spec, type: "result" }); } else if (spec.handle) { specs.push({ handle: spec.handle, type: spec.type || "result", metadata: spec.metadata }); } } } if (specs.length === 0) { const chapter = this.parsedClm.chapter; if (chapter?.title) { const safeName = chapter.title.toLowerCase().replace(/[^a-z0-9]/g, "_"); specs.push({ handle: `clm://${safeName}/balanced`, type: "verification" }); } } return specs; } /** * Get the canonical handle for this PCard (Transition) * * @returns Handle string in form `clm://{module}/{function}/spec` */ getTransitionHandle() { const chapter = this.parsedClm.chapter; if (chapter?.id !== void 0) { const safeName = chapter.title?.toLowerCase().replace(/[^a-z0-9]/g, "_") || `chapter_${chapter.id}`; return `clm://${safeName}/spec`; } return `clm://hash/${this.hash.substring(0, 16)}/spec`; } /** * Get the balanced expectations handle for this PCard * * This is where verification history is tracked in handle_history. * * @returns Handle string for balanced expectations */ getBalancedHandle() { const specHandle = this.getTransitionHandle(); return specHandle.replace("/spec", "/balanced"); } /** * Check if this PCard (Transition) can fire given the available VCards * * A transition can fire when all input VCards (preconditions) are present. * * @param availableVCards - Map of handle → VCard hash * @returns Object with canFire boolean and missing preconditions */ canFire(availableVCards) { const inputRefs = this.getInputVCardRefs(); const missing = []; for (const ref of inputRefs) { const vCardHash = availableVCards.get(ref.handle); if (!vCardHash) { missing.push(ref.handle); } else if (ref.expectedHash && vCardHash !== ref.expectedHash) { missing.push(`${ref.handle} (hash mismatch)`); } } return { canFire: missing.length === 0, missing }; } /** * Get the runtime required for this PCard * * @returns Runtime name (e.g., 'javascript', 'python', 'lean') */ getRuntime() { return this.parsedClm.clm?.concrete?.runtime || this.parsedClm.concrete?.runtime || "javascript"; } /** * Check if this is a multi-runtime PCard * * @returns True if this PCard supports multiple runtimes */ isMultiRuntime() { const config = this.parsedClm.clm?.concrete || this.parsedClm.concrete; return Array.isArray(config?.runtimes_config) && config.runtimes_config.length > 1; } }; // src/model/VCard.ts import { parse as parse2 } from "yaml"; function parseVCardContent(card) { try { const text = card.getContentAsText(); try { return JSON.parse(text); } catch { return parse2(text); } } catch { return {}; } } var VCard = class _VCard extends MCard { // Mutable Runtime State (initialized via _initializeMutableState) _subjectDid; _controllerPubkeys; _capabilities; _externalRefs; _exportManifest; _gatekeeperLog; _pcardRefsHashes; constructor(content, hash, g_time, contentType, hashFunction, initialData) { super(content, hash, g_time, contentType, hashFunction); this._gatekeeperLog = []; this._exportManifest = []; this._initializeMutableState(initialData); } _initializeMutableState(data) { const v = data.vcard || data; this._subjectDid = v.identity?.subject_did || v.subjectDid || ""; this._controllerPubkeys = v.identity?.controller_pubkeys || v.controllerPubkeys || []; const rawCaps = v.gatekeeper?.capabilities || v.capabilities || []; this._capabilities = rawCaps.map((c) => ({ capabilityId: c.id || c.capabilityId, actorDid: c.actor || c.actorDid, scope: c.scope, resourcePattern: c.resourcePattern || c.resource_pattern, expiresAt: c.expiresAt || c.expires_at ? new Date(c.expiresAt || c.expires_at) : void 0, transferable: c.transferable || false, constraints: c.constraints })); const rawRefs = v.externalRefs || v.external_refs || []; this._externalRefs = rawRefs.map((r) => ({ uri: r.uri, contentHash: r.contentHash || r.content_hash, status: r.status, qosMetrics: r.qos || r.qosMetrics })); const rawPCardRefs = v.verification?.pcard_refs || []; this._pcardRefsHashes = rawPCardRefs.map( (r) => typeof r === "string" ? r : r.hash ); } /** * Create a new VCard from parameters. * Follows strict UPTV structure { vcard: { ... } }. */ static async createVCard(subjectDid, controllerPubkeys, capabilities = [], externalRefs = [], hashAlgorithm = "sha256") { const structure = { vcard: { type: "authentication-authorization", identity: { subject_did: subjectDid, controller_pubkeys: controllerPubkeys }, gatekeeper: { capabilities: capabilities.map((c) => ({ id: c.capabilityId, actor: c.actorDid, scope: c.scope, resource_pattern: c.resourcePattern, expires_at: c.expiresAt?.toISOString(), transferable: c.transferable, constraints: c.constraints })) }, verification: { pcard_refs: [] // Populated if provided in a separate arg or we filter externalRefs? // For now, we assume externalRefs are generic. // To strictly follow PCard Logic, we could expose pcardRefs arg, but keeping signature for now. }, external_refs: externalRefs.map((r) => ({ uri: r.uri, content_hash: r.contentHash, status: r.status, qos: r.qosMetrics })) } }; const contentString = JSON.stringify(structure, null, 2); const bytes = new TextEncoder().encode(contentString); const hash = await HashValidator.computeHash(bytes, hashAlgorithm); const g_time = GTime.stampNow(hashAlgorithm); const contentType = ContentTypeInterpreter.detect(bytes); return new _VCard(bytes, hash, g_time, contentType, hashAlgorithm, structure); } /** * Create a VCard wrapper from an existing MCard. */ static async fromMCard(card) { const content = parseVCardContent(card); return new _VCard( card.content, card.hash, card.g_time, card.contentType, card.hashFunction, content ); } getDOTSMetadata() { return createVCardDOTSMetadata(); } // ========================================================================= // Accessors // ========================================================================= get subjectDid() { return this._subjectDid; } get controllerPubkeys() { return this._controllerPubkeys; } get capabilities() { return this._capabilities; } get externalRefs() { return this._externalRefs; } // ========================================================================= // Runtime Mutability (Gatekeeper Logic) // ========================================================================= addCapability(capability) { this._capabilities.push(capability); } getValidCapabilities() { const now = /* @__PURE__ */ new Date(); return this._capabilities.filter( (c) => c.expiresAt === void 0 || new Date(c.expiresAt) > now ); } hasCapability(scope, resourceHash) { for (const cap of this.getValidCapabilities()) { if (cap.scope === scope) { const regex = new RegExp(cap.resourcePattern); if (regex.test(resourceHash)) return true; } } return false; } addPCardReference(pcardHash) { if (!this._pcardRefsHashes.includes(pcardHash)) { this._pcardRefsHashes.push(pcardHash); } this.addExternalRef({ uri: `pcard://${pcardHash}`, contentHash: pcardHash, status: "verified" }); } getPCardReferences() { const set = new Set(this._pcardRefsHashes); this._externalRefs.forEach((r) => { if (r.uri.startsWith("pcard://")) set.add(r.contentHash); }); return Array.from(set); } addExternalRef(ref) { this._externalRefs.push(ref); } getExternalRefsByStatus(status) { return this._externalRefs.filter((r) => r.status === status); } verifyExternalRef(uri, newHash) { for (const ref of this._externalRefs) { if (ref.uri === uri) { if (ref.contentHash === newHash) { ref.status = "verified"; ref.lastVerified = /* @__PURE__ */ new Date(); return true; } else { ref.status = "stale"; return false; } } } return false; } authorizeIngress(sourceDid, contentHash, capabilityId) { let authorized = false; let usedCapability; for (const cap of this.getValidCapabilities()) { if (cap.actorDid === sourceDid && (cap.scope === "write" /* WRITE */ || cap.scope === "admin" /* ADMIN */)) { if (capabilityId === void 0 || cap.capabilityId === capabilityId) { authorized = true; usedCapability = cap.capabilityId; break; } } } const event = { direction: "ingress" /* INGRESS */, timestamp: /* @__PURE__ */ new Date(), sourceDid, contentHash, authorized, capabilityUsed: usedCapability }; this._gatekeeperLog.push(event); return authorized; } registerForEgress(contentHash) { if (!this._exportManifest.includes(contentHash)) { this._exportManifest.push(contentHash); return true; } return false; } authorizeEgress(destinationDid, contentHash, capabilityId) { if (!this._exportManifest.includes(contentHash)) { this._logEgress(destinationDid, contentHash, false, void 0); return false; } let authorized = false; let usedCapability; for (const cap of this.getValidCapabilities()) { if (cap.scope === "read" /* READ */ || cap.scope === "admin" /* ADMIN */) { const regex = new RegExp(cap.resourcePattern); if (regex.test(contentHash)) { if (capabilityId === void 0 || cap.capabilityId === capabilityId) { authorized = true; usedCapability = cap.capabilityId; break; } } } } this._logEgress(destinationDid, contentHash, authorized, usedCapability); return authorized; } _logEgress(dst, hash, auth, cap) { const event = { direction: "egress" /* EGRESS */, timestamp: /* @__PURE__ */ new Date(), destinationDid: dst, contentHash: hash, authorized: auth, capabilityUsed: cap }; this._gatekeeperLog.push(event); } getGatekeeperLog(direction) { if (direction === void 0) return this._gatekeeperLog; return this._gatekeeperLog.filter((e) => e.direction === direction); } getExportManifest() { return [...this._exportManifest]; } // ========================================================================= // EOS Compliance // ========================================================================= simulateMode() { return new VCardSimulation(this); } // ========================================================================= // Petri Net Token Semantics // ========================================================================= /** * Get the handle where this VCard token currently resides * * In Petri Net terms, this is the "Place" where the token is located. * * @returns Handle string if available in content, or hash-based handle */ getTokenHandle() { const content = parseVCardContent(this); const v = content.vcard || content; return v.handle || v.token_handle || `vcard://${this.hash.substring(0, 16)}`; } /** * Check if this VCard is a VerificationVCard (result of PCard execution) * * VerificationVCards are produced by PCard transitions and contain * execution results with provenance chain. * * @returns True if this is a verification token */ isVerificationVCard() { const content = parseVCardContent(this); const v = content.vcard || content; return v.type === "verification" || v.type === "verification-result" || Boolean(v.verification?.execution_result); } /** * Get the previous hash in the provenance chain * * In Petri Net terms, this links to the input VCard that was "consumed" * when the transition fired to produce this VCard. * * @returns Previous VCard hash if this is part of a verification cascade */ getPreviousHash() { const content = parseVCardContent(this); const v = content.vcard || content; return v.previous_hash || v.previousHash || v.verification?.previous_hash; } /** * Get the PCard hash that produced this VCard (if verification) * * This links the output token to the transition that created it. * * @returns PCard hash that produced this VCard */ getSourcePCardHash() { const content = parseVCardContent(this); const v = content.vcard || content; return v.source_pcard || v.verification?.pcard_hash || v.produced_by; } /** * Create a VerificationVCard from PCard execution result * * This is the factory method for producing output tokens in the Petri Net. * * @param pcard - The PCard (Transition) that executed * @param result - Execution result * @param previousVCard - Input VCard (pre-condition) if any * @param success - Whether execution succeeded * @returns New VerificationVCard */ static async createVerificationVCard(pcard, result, previousVCard, success = true, hashAlgorithm = "sha256") { const handle = typeof pcard.getBalancedHandle === "function" ? pcard.getBalancedHandle() : `clm://hash/${pcard.hash.substring(0, 16)}/balanced`; const structure = { vcard: { type: "verification", handle, identity: { subject_did: "did:ptr:system", controller_pubkeys: [] }, verification: { pcard_hash: pcard.hash, execution_result: result, success, timestamp: (/* @__PURE__ */ new Date()).toISOString(), previous_hash: previousVCard?.hash }, gatekeeper: { capabilities: [] }, external_refs: [] } }; const contentString = JSON.stringify(structure, null, 2); const bytes = new TextEncoder().encode(contentString); const hash = await HashValidator.computeHash(bytes, hashAlgorithm); const g_time = GTime.stampNow(hashAlgorithm); const contentType = ContentTypeInterpreter.detect(bytes); return new _VCard(bytes, hash, g_time, contentType, hashAlgorithm, structure); } /** * Check if this VCard enables a specific PCard to fire * * @param requiredHandle - The handle where a precondition VCard must exist * @returns True if this VCard satisfies that precondition */ enablesTransition(requiredHandle) { const myHandle = this.getTokenHandle(); return myHandle === requiredHandle; } }; var VCardSimulation = class { vcard; log; constructor(vcard) { this.vcard = vcard; this.log = []; } logEffect(effectType, details) { this.log.push({ timestamp: /* @__PURE__ */ new Date(), effectType, details, simulated: true }); } getSimulationLog() { return this.log; } }; // src/ptr/node/core/operations/index.ts var NETWORK_BUILTINS = /* @__PURE__ */ new Set([ "http_get", "http_post", "http_put", "http_delete", "http_patch", "websocket_connect", "websocket_send", "websocket_listen", "queue_send", "queue_receive", "load_url", "mcard_send", "mcard_read", "mcard_sync", "listen_http", "listen_sync", "session_record", "run_command", "clm_orchestrator", "signaling_server", "webrtc_connect", "webrtc_send", "webrtc_listen" ]); function isNetworkBuiltin(builtin, operation) { if (builtin === false) return false; const op = (typeof builtin === "string" ? builtin : operation) || ""; if (!op) return false; if (NETWORK_BUILTINS.has(op)) return true; return op.startsWith("http_") || op.startsWith("websocket_") || op.startsWith("queue_") || op.startsWith("webrtc_"); } function isLoaderBuiltin(builtin, operation) { if (builtin === false) return false; const op = (typeof builtin === "string" ? builtin : operation) || ""; return op === "loader" || op === "load_files" || operation === "loader"; } function getHandleBuiltinType(builtin, operation) { if (builtin === false) return null; const op = (typeof builtin === "string" ? builtin : operation) || ""; if (op === "handle_version") return "version"; if (op === "handle_prune") return "prune"; return null; } function isStaticServerBuiltin(builtin, operation) { if (builtin === false) return false; const op = (typeof builtin === "string" ? builtin : operation) || ""; return op === "static_server"; } function isWebSocketServerBuiltin(builtin, operation) { if (builtin === false) return false; const op = (typeof builtin === "string" ? builtin : operation) || ""; return op === "websocket_server"; } // src/ptr/node/core/operations/handle.ts async function executeHandleVersion(ctx) { const examples = ctx.examples || []; if (examples.length) { return runVersionExamples(examples); } const inputData = ctx.input || ctx; const handle = inputData.handle || ctx.handle || ""; const versions = inputData.versions || ctx.versions || []; if (!handle) { return { success: false, error: "handle is required" }; } if (!versions.length) { return { success: false, error: "versions list is required" }; } return executeVersionSingle(handle, versions); } async function executeHandlePrune(ctx) { const examples = ctx.examples || []; if (examples.length) { return runPruneExamples(examples); } const inputData = ctx.input || ctx; const handle = inputData.handle || ctx.handle || ""; const versions = inputData.versions || ctx.versions || []; const pruneType = inputData.prune_type || ctx.prune_type || "all"; const olderThanSeconds = inputData.older_than_seconds || ctx.older_than_seconds; if (!handle) { return { success: false, error: "handle is required" }; } return executePruneSingle(handle, versions, pruneType, olderThanSeconds); } async function runVersionExamples(examples) { const results = []; for (const example of examples) { const inputData = example.input || example; const handle = inputData.handle || ""; const versions = inputData.versions || []; if (!handle || !versions.length) { results.push({ example_name: example.name || "unnamed", success: false, error: "handle and versions required" }); continue; } const result = await executeVersionSingle(handle, versions); result.example_name = example.name || "unnamed"; const expected = example.expected_output || {}; result.passed = expected.history_length !== void 0 ? result.history_length === expected.history_length : result.success || false; results.push(result); } return { success: results.every((r) => r.passed), results }; } async function executeVersionSingle(handle, versions) { const { SqliteNodeEngine: SqliteNodeEngine2 } = await import("./storage/SqliteNodeEngine.js"); const { CardCollection: CardCollection2 } = await import("./CardCollection-CEFQ5PA6.js"); const { MCard: MCard2 } = await import("./MCard-HFL7AFIH.js"); const engine = new SqliteNodeEngine2(":memory:"); const collection = new CardCollection2(engine); try { const firstContent = versions[0].content || versions[0]; const card = await MCard2.create(firstContent); await collection.addWithHandle(card, handle); for (let i = 1; i < versions.length; i++) { const content = versions[i].content || versions[i]; const newCard = await MCard2.create(content); await collection.updateHandle(handle, newCard); } const finalCard = await collection.getByHandle(handle); const history = await collection.getHandleHistory(handle); const finalContent = finalCard ? new TextDecoder().decode(finalCard.content) : null; return { success: true, handle, final_hash: finalCard ? finalCard.hash : null, final_content: finalContent, history_length: history.length, history }; } catch (e) { return { success: false, error: e.message }; } } async function runPruneExamples(examples) { const results = []; for (const example of examples) { const inputData = example.input || example; const handle = inputData.handle || ""; const versions = inputData.versions || []; const pruneType = inputData.prune_type || "all"; const olderThanSeconds = inputData.older_than_seconds; if (!handle) { results.push({ example_name: example.name || "unnamed", success: false, error: "handle is required" }); continue; } const result = await executePruneSingle(handle, versions, pruneType, olderThanSeconds); result.example_name = example.name || "unnamed"; const expected = example.expected_output || {}; if (expected.history_after !== void 0) { result.passed = result.history_after === expected.history_after; } else if (expected.deleted !== void 0) { result.passed = result.deleted === expected.deleted; } else { result.passed = result.success || false; } results.push(result); } return { success: results.every((r) => r.passed), results }; } async function executePruneSingle(handle, versions, pruneType, olderThanSeconds) { const { SqliteNodeEngine: SqliteNodeEngine2 } = await import("./storage/SqliteNodeEngine.js"); const { CardCollection: CardCollection2 } = await import("./CardCollection-CEFQ5PA6.js"); const { MCard: MCard2 } = await import("./MCard-HFL7AFIH.js"); const engine = new SqliteNodeEngine2(":memory:"); const collection = new CardCollection2(engine); try { if (versions.length) { const firstContent = versions[0].content || versions[0]; const card = await MCard2.create(firstContent); await collection.addWithHandle(card, handle); for (let i = 1; i < versions.length; i++) { const content = versions[i].content || versions[i]; const newCard = await MCard2.create(content); await collection.updateHandle(handle, newCard); } } const historyBefore = (await collection.getHandleHistory(handle)).length; let deleted = 0; if (pruneType === "all") { deleted = await collection.pruneHandleHistory(handle, { deleteAll: true }); } else if (pruneType === "older_than" && olderThanSeconds !== void 0) { deleted = await collection.pruneHandleHistory(handle, { olderThan: `${olderThanSeconds}s` }); } const historyAfter = (await collection.getHandleHistory(handle)).length; return { success: true, handle, history_before: historyBefore, deleted, history_after: historyAfter }; } catch (e) { return { success: false, error: e.message }; } } // src/ptr/node/core/operations/static-server.ts import { execSync, spawn } from "child_process"; import * as fs from "fs"; import * as path from "path"; function resolveConfigValue(val) { if (typeof val === "string" && val.startsWith("${") && val.endsWith("}")) { const envVar = val.slice(2, -1); return process.env[envVar] || val; } return val; } function isPortInUse(port) { try { const result = execSync(`lsof -ti :${port}`, { encoding: "utf8", stdio: ["pipe", "pipe", "pipe"] }); return result.trim().length > 0; } catch { return false; } } function getPidOnPort(port) { try { const result = execSync(`lsof -ti :${port}`, { encoding: "utf8", stdio: ["pipe", "pipe", "pipe"] }); const pid = parseInt(result.trim().split("\n")[0], 10); return isNaN(pid) ? null : pid; } catch { return null; } } async function executeStaticServer(config, context, chapterDir) { const action = context.action || config.action || "status"; const defaultPort = parseInt(process.env.HTTP_PORT || "8080", 10); const rawPort = context.port || config.port || defaultPort; const port = parseInt(String(resolveConfigValue(rawPort)), 10); const host = context.host || config.host || "localhost"; let rootDir = context.root_dir || config.root_dir || "."; let projectRoot = chapterDir; while (projectRoot !== path.dirname(projectRoot)) { if (fs.existsSync(path.join(projectRoot, "package.json")) || fs.existsSync(path.join(projectRoot, ".git"))) { break; } projectRoot = path.dirname(projectRoot); } if (projectRoot === path.dirname(projectRoot)) { projectRoot = process.cwd(); } if (!path.isAbsolute(rootDir)) { rootDir = path.normalize(path.join(projectRoot, rootDir)); } const pidFile = path.join(projectRoot, `.static_server_${port}.pid`); if (action === "deploy") { if (isPortInUse(port)) { const pid = getPidOnPort(port); return { success: true, message: "Server already running", pid, port, url: `http://${host}:${port}`, status: "already_running" }; } if (!fs.existsSync(rootDir) || !fs.statSync(rootDir).isDirectory()) { return { success: false, error: `Directory not found: ${rootDir}` }; } const serverCode = ` const http = require('http'); const fs = require('fs'); const path = require('path'); const port = ${port}; const host = '${host}'; const rootDir = '${rootDir.replace(/\\/g, "\\\\")}'; const mimeTypes = { '.html': 'text/html', '.js': 'text/javascript', '.css': 'text/css', '.json': 'application/jso