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
JavaScript
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