@thehoneyjar/sigil-anchor 4.3.1
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/LICENSE.md +660 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +3514 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/index.d.ts +1230 -0
- package/dist/index.js +2449 -0
- package/dist/index.js.map +1 -0
- package/package.json +72 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lifecycle/fork-manager.ts","../src/utils/rpc.ts","../src/types.ts","../src/lifecycle/snapshot-manager.ts","../src/lifecycle/checkpoint-manager.ts","../src/lifecycle/session-manager.ts","../src/graph/task-graph.ts","../src/warden/physics-loader.ts","../src/warden/vocabulary-loader.ts","../src/warden/grounding-gate.ts","../src/index.ts"],"names":["z","process","readFile","writeFile","mkdir","existsSync","defaultManager","readdir","join","DEFAULT_BASE_PATH","dirname","cachedPath","parseSyncStrategy","parseTiming","parseConfirmation"],"mappings":"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","sourcesContent":["/**\n * ForkManager - Anvil fork lifecycle management\n *\n * Manages spawning, tracking, and killing Anvil fork processes.\n * Persists fork registry to grimoires/anchor/forks.json.\n */\n\nimport { spawn, ChildProcess } from 'node:child_process';\nimport { readFile, writeFile, mkdir } from 'node:fs/promises';\nimport { existsSync } from 'node:fs';\nimport { dirname } from 'node:path';\nimport { EventEmitter } from 'eventemitter3';\nimport { rpcCall, waitForRpc } from '../utils/rpc.js';\nimport type { Fork, ForkConfig, ForkRegistry } from '../types.js';\nimport { ForkRegistrySchema } from '../types.js';\n\n/** ForkManager events */\ninterface ForkManagerEvents {\n 'fork:created': (fork: Fork) => void;\n 'fork:exit': (forkId: string, code: number | null) => void;\n 'fork:error': (forkId: string, error: Error) => void;\n}\n\n/** Default port range for Anvil forks */\nconst DEFAULT_PORT_START = 8545;\nconst DEFAULT_PORT_END = 8600;\n\n/** Path to fork registry file */\nconst DEFAULT_REGISTRY_PATH = 'grimoires/anchor/forks.json';\n\n/**\n * ForkManager class for managing Anvil fork lifecycle\n */\nexport class ForkManager extends EventEmitter<ForkManagerEvents> {\n private forks: Map<string, Fork> = new Map();\n private processes: Map<string, ChildProcess> = new Map();\n private usedPorts: Set<number> = new Set();\n private registryPath: string;\n\n constructor(options?: { registryPath?: string }) {\n super();\n this.registryPath = options?.registryPath ?? DEFAULT_REGISTRY_PATH;\n }\n\n /**\n * Initialize the ForkManager by loading persisted registry\n */\n async init(): Promise<void> {\n await this.loadRegistry();\n }\n\n /**\n * Spawn a new Anvil fork\n *\n * @param config - Fork configuration\n * @returns Promise resolving to the created Fork\n */\n async fork(config: ForkConfig): Promise<Fork> {\n const port = config.port ?? this.findAvailablePort();\n const forkId = this.generateForkId();\n\n // Build Anvil arguments\n const args = [\n '--fork-url',\n config.network.rpcUrl,\n '--port',\n port.toString(),\n '--chain-id',\n config.network.chainId.toString(),\n ];\n\n if (config.blockNumber !== undefined) {\n args.push('--fork-block-number', config.blockNumber.toString());\n }\n\n // Spawn Anvil process\n const process = spawn('anvil', args, {\n stdio: ['ignore', 'pipe', 'pipe'],\n detached: false,\n });\n\n const pid = process.pid;\n if (!pid) {\n throw new Error('Failed to spawn Anvil process');\n }\n\n const rpcUrl = `http://127.0.0.1:${port}`;\n\n // Wait for RPC to be ready\n try {\n await waitForRpc(rpcUrl, 30, 500);\n } catch {\n process.kill();\n throw new Error(`Anvil fork failed to become ready at ${rpcUrl}`);\n }\n\n // Get actual block number\n const blockNumberHex = await rpcCall<string>(rpcUrl, 'eth_blockNumber');\n const blockNumber = config.blockNumber ?? parseInt(blockNumberHex, 16);\n\n const fork: Fork = {\n id: forkId,\n network: config.network,\n blockNumber,\n rpcUrl,\n port,\n pid,\n createdAt: new Date(),\n ...(config.sessionId !== undefined && { sessionId: config.sessionId }),\n };\n\n // Track fork\n this.forks.set(forkId, fork);\n this.processes.set(forkId, process);\n this.usedPorts.add(port);\n\n // Handle process exit\n process.on('exit', (code) => {\n this.handleProcessExit(forkId, code);\n });\n\n process.on('error', (error) => {\n this.emit('fork:error', forkId, error);\n });\n\n // Persist registry\n await this.saveRegistry();\n\n this.emit('fork:created', fork);\n return fork;\n }\n\n /**\n * Wait for a fork to be ready\n *\n * @param forkId - Fork ID to wait for\n * @param timeoutMs - Timeout in milliseconds\n */\n async waitForReady(forkId: string, timeoutMs: number = 30000): Promise<void> {\n const fork = this.forks.get(forkId);\n if (!fork) {\n throw new Error(`Fork ${forkId} not found`);\n }\n await waitForRpc(fork.rpcUrl, Math.ceil(timeoutMs / 500), 500);\n }\n\n /**\n * Kill a specific fork\n *\n * @param forkId - Fork ID to kill\n */\n async kill(forkId: string): Promise<void> {\n const process = this.processes.get(forkId);\n const fork = this.forks.get(forkId);\n\n if (process) {\n process.kill('SIGTERM');\n // Give it time to terminate gracefully\n await new Promise((resolve) => setTimeout(resolve, 500));\n if (!process.killed) {\n process.kill('SIGKILL');\n }\n }\n\n if (fork) {\n this.usedPorts.delete(fork.port);\n }\n\n this.forks.delete(forkId);\n this.processes.delete(forkId);\n\n await this.saveRegistry();\n }\n\n /**\n * Kill all forks\n */\n async killAll(): Promise<void> {\n const forkIds = Array.from(this.forks.keys());\n await Promise.all(forkIds.map((id) => this.kill(id)));\n }\n\n /**\n * List all active forks\n *\n * @returns Array of active forks\n */\n list(): Fork[] {\n return Array.from(this.forks.values());\n }\n\n /**\n * Get a fork by ID\n *\n * @param forkId - Fork ID\n * @returns Fork if found, undefined otherwise\n */\n get(forkId: string): Fork | undefined {\n return this.forks.get(forkId);\n }\n\n /**\n * Export environment variables for a fork\n *\n * @param forkId - Fork ID\n * @returns Environment variables object\n */\n exportEnv(forkId: string): Record<string, string> {\n const fork = this.forks.get(forkId);\n if (!fork) {\n throw new Error(`Fork ${forkId} not found`);\n }\n\n return {\n RPC_URL: fork.rpcUrl,\n CHAIN_ID: fork.network.chainId.toString(),\n FORK_BLOCK: fork.blockNumber.toString(),\n FORK_ID: fork.id,\n };\n }\n\n /**\n * Load fork registry from disk\n */\n private async loadRegistry(): Promise<void> {\n try {\n if (!existsSync(this.registryPath)) {\n return;\n }\n\n const content = await readFile(this.registryPath, 'utf-8');\n const data = JSON.parse(content);\n const registry = ForkRegistrySchema.parse(data);\n\n // Only load forks that are still running (by checking if process exists)\n for (const registryFork of registry.forks) {\n try {\n // Check if process is still running\n process.kill(registryFork.pid, 0);\n\n // Build Fork object with proper types\n const fork: Fork = {\n id: registryFork.id,\n network: registryFork.network,\n blockNumber: registryFork.blockNumber,\n rpcUrl: registryFork.rpcUrl,\n port: registryFork.port,\n pid: registryFork.pid,\n createdAt: registryFork.createdAt,\n ...(registryFork.sessionId !== undefined && { sessionId: registryFork.sessionId }),\n };\n\n // Check if RPC is responsive\n const ready = await this.checkForkHealth(fork);\n if (ready) {\n this.forks.set(fork.id, fork);\n this.usedPorts.add(fork.port);\n }\n } catch {\n // Process not running, skip\n }\n }\n } catch {\n // Registry doesn't exist or is corrupt, start fresh\n }\n }\n\n /**\n * Save fork registry to disk\n */\n private async saveRegistry(): Promise<void> {\n const registry: ForkRegistry = {\n forks: Array.from(this.forks.values()).map((fork) => ({\n ...fork,\n createdAt: fork.createdAt.toISOString() as unknown as Date,\n })),\n lastUpdated: new Date().toISOString() as unknown as Date,\n };\n\n // Ensure directory exists\n const dir = dirname(this.registryPath);\n if (!existsSync(dir)) {\n await mkdir(dir, { recursive: true });\n }\n\n await writeFile(this.registryPath, JSON.stringify(registry, null, 2));\n }\n\n /**\n * Check if a fork is still healthy\n */\n private async checkForkHealth(fork: Fork): Promise<boolean> {\n try {\n await rpcCall<string>(fork.rpcUrl, 'eth_chainId', [], 2000);\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Handle process exit\n */\n private handleProcessExit(forkId: string, code: number | null): void {\n const fork = this.forks.get(forkId);\n if (fork) {\n this.usedPorts.delete(fork.port);\n }\n this.forks.delete(forkId);\n this.processes.delete(forkId);\n this.emit('fork:exit', forkId, code);\n void this.saveRegistry();\n }\n\n /**\n * Find an available port\n */\n private findAvailablePort(): number {\n for (let port = DEFAULT_PORT_START; port <= DEFAULT_PORT_END; port++) {\n if (!this.usedPorts.has(port)) {\n return port;\n }\n }\n throw new Error('No available ports in range');\n }\n\n /**\n * Generate a unique fork ID\n */\n private generateForkId(): string {\n const timestamp = Date.now().toString(36);\n const random = Math.random().toString(36).substring(2, 8);\n return `fork-${timestamp}-${random}`;\n }\n}\n\n/** Singleton instance for convenience */\nlet defaultManager: ForkManager | null = null;\n\n/**\n * Get the default ForkManager instance\n */\nexport function getForkManager(): ForkManager {\n if (!defaultManager) {\n defaultManager = new ForkManager();\n }\n return defaultManager;\n}\n\n/**\n * Reset the default ForkManager (for testing)\n */\nexport function resetForkManager(): void {\n defaultManager = null;\n}\n","/**\n * JSON-RPC helper for Anvil communication\n *\n * Provides type-safe RPC calls with timeout handling and error management.\n */\n\nimport { z } from 'zod';\n\n/** JSON-RPC 2.0 request format */\ninterface JsonRpcRequest {\n jsonrpc: '2.0';\n id: number;\n method: string;\n params?: unknown[];\n}\n\n/** JSON-RPC 2.0 response format */\ninterface JsonRpcResponse<T> {\n jsonrpc: '2.0';\n id: number;\n result?: T;\n error?: {\n code: number;\n message: string;\n data?: unknown;\n };\n}\n\n/** RPC error with code and message */\nexport class RpcError extends Error {\n constructor(\n public readonly code: number,\n message: string,\n public readonly data?: unknown\n ) {\n super(message);\n this.name = 'RpcError';\n }\n}\n\n/** RPC timeout error */\nexport class RpcTimeoutError extends Error {\n constructor(\n public readonly method: string,\n public readonly timeoutMs: number\n ) {\n super(`RPC call '${method}' timed out after ${timeoutMs}ms`);\n this.name = 'RpcTimeoutError';\n }\n}\n\n/** Default timeout for RPC calls (30 seconds) */\nconst DEFAULT_TIMEOUT_MS = 30_000;\n\n/** Internal request ID counter */\nlet requestId = 0;\n\n/**\n * Make a JSON-RPC call to an Anvil node\n *\n * @param url - RPC endpoint URL\n * @param method - RPC method name (e.g., 'eth_blockNumber', 'evm_snapshot')\n * @param params - Optional method parameters\n * @param timeoutMs - Timeout in milliseconds (default: 30000)\n * @returns Promise resolving to the result\n * @throws {RpcError} If the RPC returns an error\n * @throws {RpcTimeoutError} If the request times out\n */\nexport async function rpcCall<T>(\n url: string,\n method: string,\n params: unknown[] = [],\n timeoutMs: number = DEFAULT_TIMEOUT_MS\n): Promise<T> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeoutMs);\n\n const request: JsonRpcRequest = {\n jsonrpc: '2.0',\n id: ++requestId,\n method,\n params,\n };\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(request),\n signal: controller.signal,\n });\n\n if (!response.ok) {\n throw new RpcError(-32000, `HTTP error: ${response.status} ${response.statusText}`);\n }\n\n const data = (await response.json()) as JsonRpcResponse<T>;\n\n if (data.error) {\n throw new RpcError(data.error.code, data.error.message, data.error.data);\n }\n\n if (data.result === undefined) {\n throw new RpcError(-32000, 'RPC response missing result');\n }\n\n return data.result;\n } catch (error) {\n if (error instanceof Error && error.name === 'AbortError') {\n throw new RpcTimeoutError(method, timeoutMs);\n }\n throw error;\n } finally {\n clearTimeout(timeoutId);\n }\n}\n\n/**\n * Check if an RPC endpoint is ready by calling eth_chainId\n *\n * @param url - RPC endpoint URL\n * @param timeoutMs - Timeout for the check\n * @returns Promise resolving to true if ready, false otherwise\n */\nexport async function isRpcReady(url: string, timeoutMs: number = 5000): Promise<boolean> {\n try {\n await rpcCall<string>(url, 'eth_chainId', [], timeoutMs);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Poll until RPC is ready\n *\n * @param url - RPC endpoint URL\n * @param maxAttempts - Maximum number of polling attempts\n * @param intervalMs - Interval between attempts in ms\n * @returns Promise resolving when ready\n * @throws Error if max attempts exceeded\n */\nexport async function waitForRpc(\n url: string,\n maxAttempts: number = 30,\n intervalMs: number = 1000\n): Promise<void> {\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n if (await isRpcReady(url)) {\n return;\n }\n await new Promise((resolve) => setTimeout(resolve, intervalMs));\n }\n throw new Error(`RPC at ${url} not ready after ${maxAttempts} attempts`);\n}\n\n/** Zod schema for validating hex strings */\nexport const hexStringSchema = z.string().regex(/^0x[0-9a-fA-F]*$/);\n\n/** Zod schema for validating block numbers */\nexport const blockNumberSchema = z.union([hexStringSchema, z.literal('latest'), z.literal('pending'), z.literal('earliest')]);\n","/**\n * Anchor Core Types\n *\n * Type definitions for the Anchor ground truth enforcement layer.\n */\n\nimport { z } from 'zod';\n\n// =============================================================================\n// Fork Types\n// =============================================================================\n\n/** Network configuration for forking */\nexport interface NetworkConfig {\n /** Network name (e.g., 'mainnet', 'sepolia') */\n name: string;\n /** Chain ID */\n chainId: number;\n /** RPC URL to fork from */\n rpcUrl: string;\n}\n\n/** Fork configuration */\nexport interface ForkConfig {\n /** Network to fork */\n network: NetworkConfig;\n /** Block number to fork at (optional, defaults to latest) */\n blockNumber?: number;\n /** Local RPC port (optional, auto-assigned if not specified) */\n port?: number;\n /** Session ID this fork belongs to */\n sessionId?: string;\n}\n\n/** Active fork instance */\nexport interface Fork {\n /** Unique fork identifier */\n id: string;\n /** Network configuration */\n network: NetworkConfig;\n /** Block number fork was created at */\n blockNumber: number;\n /** Local RPC URL */\n rpcUrl: string;\n /** Local RPC port */\n port: number;\n /** Process ID */\n pid: number;\n /** Creation timestamp */\n createdAt: Date;\n /** Session ID this fork belongs to */\n sessionId?: string;\n}\n\n/** Fork registry schema for persistence */\nexport const ForkSchema = z.object({\n id: z.string(),\n network: z.object({\n name: z.string(),\n chainId: z.number(),\n rpcUrl: z.string(),\n }),\n blockNumber: z.number(),\n rpcUrl: z.string(),\n port: z.number(),\n pid: z.number(),\n createdAt: z.string().transform((s: string) => new Date(s)),\n sessionId: z.string().optional(),\n});\n\nexport const ForkRegistrySchema = z.object({\n forks: z.array(ForkSchema),\n lastUpdated: z.string().transform((s: string) => new Date(s)),\n});\n\nexport type ForkRegistry = z.infer<typeof ForkRegistrySchema>;\n\n// =============================================================================\n// Snapshot Types\n// =============================================================================\n\n/** Snapshot metadata */\nexport interface SnapshotMetadata {\n /** Snapshot ID (from Anvil) */\n id: string;\n /** Fork ID this snapshot belongs to */\n forkId: string;\n /** Session ID */\n sessionId: string;\n /** Task ID that created this snapshot */\n taskId?: string;\n /** Block number at snapshot time */\n blockNumber: number;\n /** Creation timestamp */\n createdAt: Date;\n /** Description */\n description?: string;\n}\n\n/** Snapshot configuration */\nexport interface SnapshotConfig {\n /** Fork ID to snapshot */\n forkId: string;\n /** Session ID */\n sessionId: string;\n /** Task ID */\n taskId?: string;\n /** Description */\n description?: string;\n}\n\n// =============================================================================\n// Checkpoint Types\n// =============================================================================\n\n/** Checkpoint metadata */\nexport interface CheckpointMetadata {\n /** Checkpoint ID */\n id: string;\n /** Session ID */\n sessionId: string;\n /** Fork ID this checkpoint was created from */\n forkId: string;\n /** Snapshot range covered by this checkpoint */\n snapshotRange: {\n first: string;\n last: string;\n };\n /** Block number at checkpoint time */\n blockNumber: number;\n /** Creation timestamp */\n createdAt: Date;\n /** Number of snapshots since last checkpoint */\n snapshotCount: number;\n}\n\n/** Checkpoint configuration */\nexport interface CheckpointConfig {\n /** Session ID */\n sessionId: string;\n /** Fork ID */\n forkId: string;\n /** Snapshot interval before checkpointing */\n interval?: number;\n}\n\n// =============================================================================\n// Task Graph Types\n// =============================================================================\n\n/** Task types in the Anchor pipeline */\nexport type TaskType = 'fork' | 'ground' | 'warden' | 'generate' | 'validate' | 'write';\n\n/** Task status */\nexport type TaskStatus = 'pending' | 'running' | 'complete' | 'blocked' | 'failed';\n\n/** Task in the state-pinned graph */\nexport interface Task {\n /** Unique task ID */\n id: string;\n /** Task type */\n type: TaskType;\n /** Current status */\n status: TaskStatus;\n /** Snapshot ID binding this task to EVM state */\n snapshotId?: string;\n /** Checkpoint ID for recovery */\n checkpointId?: string;\n /** IDs of tasks this depends on */\n dependencies: string[];\n /** Task input data */\n input: unknown;\n /** Task output data */\n output?: unknown;\n /** Error if failed */\n error?: string;\n /** Creation timestamp */\n createdAt: Date;\n /** Completion timestamp */\n completedAt?: Date;\n}\n\n/** Task graph data for persistence */\nexport interface TaskGraphData {\n /** Session ID */\n sessionId: string;\n /** All tasks */\n tasks: Task[];\n /** Current head task ID */\n headTaskId?: string;\n /** Last updated timestamp */\n lastUpdated: Date;\n}\n\n// =============================================================================\n// Warden Types\n// =============================================================================\n\n/** Zone hierarchy for physics validation */\nexport type Zone = 'critical' | 'elevated' | 'standard' | 'local';\n\n/** Zone hierarchy order (most restrictive first) */\nexport const ZONE_HIERARCHY: Zone[] = ['critical', 'elevated', 'standard', 'local'];\n\n/** Warden validation input */\nexport interface WardenInput {\n /** Component or action being validated */\n component: string;\n /** Cited zone in grounding statement */\n citedZone: Zone | null;\n /** Keywords detected in the component */\n keywords: string[];\n /** Grounding statement from agent */\n groundingStatement: string;\n /** Physics rules being applied */\n appliedPhysics?: {\n sync?: string;\n timing?: string;\n confirmation?: string;\n };\n}\n\n/** Individual check result */\nexport interface CheckResult {\n /** Whether the check passed */\n passed: boolean;\n /** Reason for pass/fail */\n reason: string;\n}\n\n/** Warden validation result */\nexport interface WardenResult {\n /** Overall validation status */\n status: 'VALID' | 'DRIFT' | 'DECEPTIVE';\n /** Individual check results */\n checks: {\n relevance: CheckResult;\n hierarchy: CheckResult;\n rules: CheckResult;\n };\n /** Required zone based on analysis */\n requiredZone: Zone;\n /** Zone cited by agent */\n citedZone: Zone | null;\n /** Correction message if needed */\n correction?: string;\n}\n\n// =============================================================================\n// Learned Rules Types\n// =============================================================================\n\n/** Learned rule trigger conditions */\nexport interface LearnedRuleTrigger {\n /** Component name patterns to match */\n component_name_contains?: string[];\n /** Zone to match */\n zone?: Zone;\n /** Effect type to match */\n effect?: string;\n /** Props to check for */\n has_props?: string[];\n}\n\n/** Learned rule constraint */\nexport interface LearnedRuleConstraint {\n /** Constraint type */\n type: 'timing' | 'sync' | 'easing' | 'confirmation' | 'custom';\n /** Operator for comparison */\n operator: '==' | '!=' | '>' | '>=' | '<' | '<=' | 'contains' | 'matches';\n /** Expected value */\n expected: string | number;\n /** Message on violation */\n message: string;\n}\n\n/** Grounding requirement for a rule */\nexport interface LearnedRuleGroundingRequirement {\n /** Fields that must be cited */\n must_cite?: {\n zone?: Zone;\n physics?: string[];\n };\n /** Warden check questions */\n warden_check?: string[];\n}\n\n/** A learned rule from pattern detection or manual definition */\nexport interface LearnedRule {\n /** Unique rule ID */\n id: string;\n /** Rule version */\n version: string;\n /** Human-readable description */\n description: string;\n /** How the rule was created */\n created_from: 'manual' | 'pattern_detection' | 'import';\n /** Pattern ID if created from pattern */\n pattern_id?: string;\n /** Rule definition */\n rule: {\n trigger: LearnedRuleTrigger;\n constraint: LearnedRuleConstraint;\n };\n /** Grounding requirements */\n grounding_requirement?: LearnedRuleGroundingRequirement;\n /** Creation timestamp */\n created_at: string;\n /** Last updated timestamp */\n updated_at: string;\n}\n\n// =============================================================================\n// Exit Codes\n// =============================================================================\n\n/** Anchor exit codes */\nexport const ExitCode = {\n PASS: 0,\n DRIFT: 1,\n DECEPTIVE: 2,\n VIOLATION: 3,\n REVERT: 4,\n CORRUPT: 5,\n SCHEMA: 6,\n} as const;\n\nexport type ExitCodeValue = (typeof ExitCode)[keyof typeof ExitCode];\n\n// =============================================================================\n// Lens Context Types (Sprint 4)\n// =============================================================================\n\n/**\n * Lens context for User Lens impersonation validation\n * Used to verify data source consistency when viewing as another address\n */\nexport interface LensContext {\n /** Address being impersonated */\n impersonatedAddress: string;\n /** Real user address (for signing) */\n realAddress?: string;\n /** Component being validated */\n component: string;\n /** Value observed in the UI */\n observedValue?: string;\n /** Value from on-chain read */\n onChainValue?: string;\n /** Value from indexer (Envio, Subgraph) */\n indexedValue?: string;\n /** Data source used by component */\n dataSource?: 'on-chain' | 'indexed' | 'mixed' | 'unknown';\n}\n\n/** Lens context schema for validation */\nexport const LensContextSchema = z.object({\n impersonatedAddress: z.string(),\n realAddress: z.string().optional(),\n component: z.string(),\n observedValue: z.string().optional(),\n onChainValue: z.string().optional(),\n indexedValue: z.string().optional(),\n dataSource: z.enum(['on-chain', 'indexed', 'mixed', 'unknown']).optional(),\n});\n\n/**\n * Lens validation issue types\n */\nexport type LensIssueType =\n | 'data_source_mismatch' // observed != on_chain\n | 'stale_indexed_data' // indexed != on_chain\n | 'lens_financial_check' // Financial zone using indexed source\n | 'impersonation_leak'; // Real address used where impersonated expected\n\n/**\n * Lens validation issue severity\n */\nexport type LensIssueSeverity = 'error' | 'warning' | 'info';\n\n/**\n * Individual lens validation issue\n */\nexport interface LensValidationIssue {\n /** Issue type */\n type: LensIssueType;\n /** Severity (varies by zone) */\n severity: LensIssueSeverity;\n /** Human-readable message */\n message: string;\n /** Component where issue was found */\n component: string;\n /** Zone context */\n zone?: Zone;\n /** Expected value */\n expected?: string;\n /** Actual value */\n actual?: string;\n /** Suggested fix */\n suggestion?: string;\n}\n\n/** Lens validation issue schema */\nexport const LensValidationIssueSchema = z.object({\n type: z.enum(['data_source_mismatch', 'stale_indexed_data', 'lens_financial_check', 'impersonation_leak']),\n severity: z.enum(['error', 'warning', 'info']),\n message: z.string(),\n component: z.string(),\n zone: z.enum(['critical', 'elevated', 'standard', 'local']).optional(),\n expected: z.string().optional(),\n actual: z.string().optional(),\n suggestion: z.string().optional(),\n});\n\n/**\n * Lens validation result\n */\nexport interface LensValidationResult {\n /** Whether validation passed */\n valid: boolean;\n /** List of issues found */\n issues: LensValidationIssue[];\n /** Summary message */\n summary: string;\n}\n\n/** Extended exit codes for lens validation */\nexport const LensExitCode = {\n ...ExitCode,\n LENS_WARNING: 11,\n LENS_ERROR: 10,\n} as const;\n\nexport type LensExitCodeValue = (typeof LensExitCode)[keyof typeof LensExitCode];\n","/**\n * SnapshotManager - Anvil snapshot lifecycle management\n *\n * Manages creating, reverting, and tracking EVM snapshots.\n * Persists snapshot metadata to grimoires/anchor/sessions/{sessionId}/snapshots/\n */\n\nimport { readFile, writeFile, mkdir, readdir, unlink } from 'node:fs/promises';\nimport { existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { rpcCall } from '../utils/rpc.js';\nimport type { SnapshotMetadata, SnapshotConfig } from '../types.js';\n\n/** Snapshot manager configuration */\nexport interface SnapshotManagerConfig {\n /** Base path for session data */\n basePath?: string;\n}\n\n/** Default base path for session data */\nconst DEFAULT_BASE_PATH = 'grimoires/anchor/sessions';\n\n/**\n * SnapshotManager class for managing Anvil snapshots\n */\nexport class SnapshotManager {\n private snapshots: Map<string, SnapshotMetadata> = new Map();\n private taskToSnapshot: Map<string, string> = new Map();\n private basePath: string;\n private sessionId: string | null = null;\n\n constructor(config?: SnapshotManagerConfig) {\n this.basePath = config?.basePath ?? DEFAULT_BASE_PATH;\n }\n\n /**\n * Initialize the manager for a session\n *\n * @param sessionId - Session ID to manage snapshots for\n */\n async init(sessionId: string): Promise<void> {\n this.sessionId = sessionId;\n await this.loadSnapshots();\n }\n\n /**\n * Create a new snapshot\n *\n * @param config - Snapshot configuration\n * @param rpcUrl - RPC URL of the fork\n * @returns Promise resolving to snapshot metadata\n */\n async create(config: SnapshotConfig, rpcUrl: string): Promise<SnapshotMetadata> {\n // Call evm_snapshot\n const snapshotId = await rpcCall<string>(rpcUrl, 'evm_snapshot');\n\n // Get current block number\n const blockNumberHex = await rpcCall<string>(rpcUrl, 'eth_blockNumber');\n const blockNumber = parseInt(blockNumberHex, 16);\n\n const metadata: SnapshotMetadata = {\n id: snapshotId,\n forkId: config.forkId,\n sessionId: config.sessionId,\n blockNumber,\n createdAt: new Date(),\n ...(config.taskId !== undefined && { taskId: config.taskId }),\n ...(config.description !== undefined && { description: config.description }),\n };\n\n // Store in memory\n this.snapshots.set(snapshotId, metadata);\n if (config.taskId) {\n this.taskToSnapshot.set(config.taskId, snapshotId);\n }\n\n // Persist to disk\n await this.saveSnapshot(metadata);\n\n return metadata;\n }\n\n /**\n * Revert to a snapshot\n *\n * @param rpcUrl - RPC URL of the fork\n * @param snapshotId - Snapshot ID to revert to\n * @returns Promise resolving to true if successful\n */\n async revert(rpcUrl: string, snapshotId: string): Promise<boolean> {\n const result = await rpcCall<boolean>(rpcUrl, 'evm_revert', [snapshotId]);\n return result;\n }\n\n /**\n * Get snapshot metadata by ID\n *\n * @param snapshotId - Snapshot ID\n * @returns Snapshot metadata if found\n */\n get(snapshotId: string): SnapshotMetadata | undefined {\n return this.snapshots.get(snapshotId);\n }\n\n /**\n * List all snapshots sorted by creation time\n *\n * @returns Array of snapshot metadata\n */\n list(): SnapshotMetadata[] {\n return Array.from(this.snapshots.values()).sort(\n (a, b) => a.createdAt.getTime() - b.createdAt.getTime()\n );\n }\n\n /**\n * Get snapshot for a specific task\n *\n * @param taskId - Task ID\n * @returns Snapshot metadata if found\n */\n getForTask(taskId: string): SnapshotMetadata | undefined {\n const snapshotId = this.taskToSnapshot.get(taskId);\n if (!snapshotId) return undefined;\n return this.snapshots.get(snapshotId);\n }\n\n /**\n * Get the count of snapshots\n *\n * @returns Number of snapshots\n */\n count(): number {\n return this.snapshots.size;\n }\n\n /**\n * Cleanup old snapshots, keeping the most recent\n *\n * @param keepLast - Number of recent snapshots to keep\n */\n async cleanup(keepLast: number): Promise<void> {\n const sorted = this.list();\n const toDelete = sorted.slice(0, -keepLast);\n\n for (const snapshot of toDelete) {\n await this.deleteSnapshot(snapshot.id);\n }\n }\n\n /**\n * Get snapshot directory path for current session\n */\n private getSnapshotDir(): string {\n if (!this.sessionId) {\n throw new Error('SnapshotManager not initialized with session ID');\n }\n return join(this.basePath, this.sessionId, 'snapshots');\n }\n\n /**\n * Get file path for a snapshot\n */\n private getSnapshotPath(snapshotId: string): string {\n return join(this.getSnapshotDir(), `${snapshotId}.json`);\n }\n\n /**\n * Load existing snapshots from disk\n */\n private async loadSnapshots(): Promise<void> {\n const dir = this.getSnapshotDir();\n\n if (!existsSync(dir)) {\n return;\n }\n\n try {\n const files = await readdir(dir);\n for (const file of files) {\n if (!file.endsWith('.json')) continue;\n\n try {\n const content = await readFile(join(dir, file), 'utf-8');\n const data = JSON.parse(content) as SnapshotMetadata;\n data.createdAt = new Date(data.createdAt);\n\n this.snapshots.set(data.id, data);\n if (data.taskId) {\n this.taskToSnapshot.set(data.taskId, data.id);\n }\n } catch {\n // Skip corrupt files\n }\n }\n } catch {\n // Directory doesn't exist or can't be read\n }\n }\n\n /**\n * Save snapshot metadata to disk\n */\n private async saveSnapshot(metadata: SnapshotMetadata): Promise<void> {\n const dir = this.getSnapshotDir();\n\n if (!existsSync(dir)) {\n await mkdir(dir, { recursive: true });\n }\n\n await writeFile(\n this.getSnapshotPath(metadata.id),\n JSON.stringify(metadata, null, 2)\n );\n }\n\n /**\n * Delete a snapshot from memory and disk\n */\n private async deleteSnapshot(snapshotId: string): Promise<void> {\n const metadata = this.snapshots.get(snapshotId);\n\n this.snapshots.delete(snapshotId);\n if (metadata?.taskId) {\n this.taskToSnapshot.delete(metadata.taskId);\n }\n\n try {\n await unlink(this.getSnapshotPath(snapshotId));\n } catch {\n // File might not exist\n }\n }\n}\n\n/** Singleton instance for convenience */\nlet defaultManager: SnapshotManager | null = null;\n\n/**\n * Get the default SnapshotManager instance\n */\nexport function getSnapshotManager(): SnapshotManager {\n if (!defaultManager) {\n defaultManager = new SnapshotManager();\n }\n return defaultManager;\n}\n\n/**\n * Reset the default SnapshotManager (for testing)\n */\nexport function resetSnapshotManager(): void {\n defaultManager = null;\n}\n","/**\n * CheckpointManager - Hard restart strategy for Anvil memory management\n *\n * Creates periodic checkpoints via anvil_dumpState to prevent memory bloat.\n * Restores checkpoints via anvil_loadState for crash recovery.\n */\n\nimport { readFile, writeFile, mkdir, readdir, rm } from 'node:fs/promises';\nimport { existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { rpcCall } from '../utils/rpc.js';\nimport { ForkManager } from './fork-manager.js';\nimport type { CheckpointMetadata, Fork, NetworkConfig } from '../types.js';\n\n/** Checkpoint manager configuration */\nexport interface CheckpointManagerConfig {\n /** Base path for checkpoint data */\n basePath?: string;\n /** Snapshot interval before creating checkpoint */\n snapshotInterval?: number;\n /** Maximum checkpoints to retain */\n maxCheckpoints?: number;\n}\n\n/** Default configuration values */\nconst DEFAULT_BASE_PATH = 'grimoires/anchor/checkpoints';\nconst DEFAULT_SNAPSHOT_INTERVAL = 10;\nconst DEFAULT_MAX_CHECKPOINTS = 5;\n\n/**\n * CheckpointManager class for hard restart strategy\n */\nexport class CheckpointManager {\n private checkpoints: Map<string, CheckpointMetadata> = new Map();\n private snapshotCount: number = 0;\n private firstSnapshotId: string | null = null;\n private lastSnapshotId: string | null = null;\n private basePath: string;\n private snapshotInterval: number;\n private maxCheckpoints: number;\n private sessionId: string | null = null;\n private forkId: string | null = null;\n\n constructor(config?: CheckpointManagerConfig) {\n this.basePath = config?.basePath ?? DEFAULT_BASE_PATH;\n this.snapshotInterval = config?.snapshotInterval ?? DEFAULT_SNAPSHOT_INTERVAL;\n this.maxCheckpoints = config?.maxCheckpoints ?? DEFAULT_MAX_CHECKPOINTS;\n }\n\n /**\n * Initialize the manager for a session\n *\n * @param sessionId - Session ID\n * @param forkId - Fork ID\n */\n async init(sessionId: string, forkId: string): Promise<void> {\n this.sessionId = sessionId;\n this.forkId = forkId;\n await this.loadCheckpoints();\n }\n\n /**\n * Called when a snapshot is created. May trigger checkpoint.\n *\n * @param snapshotId - ID of the created snapshot\n * @param rpcUrl - RPC URL of the fork\n * @returns True if checkpoint was created\n */\n async onSnapshot(snapshotId: string, rpcUrl: string): Promise<boolean> {\n this.snapshotCount++;\n\n if (!this.firstSnapshotId) {\n this.firstSnapshotId = snapshotId;\n }\n this.lastSnapshotId = snapshotId;\n\n // Check if we should create a checkpoint\n if (this.snapshotCount >= this.snapshotInterval) {\n await this.create(rpcUrl);\n return true;\n }\n\n return false;\n }\n\n /**\n * Create a checkpoint by exporting state\n *\n * @param rpcUrl - RPC URL of the fork\n * @returns Checkpoint metadata\n */\n async create(rpcUrl: string): Promise<CheckpointMetadata> {\n if (!this.sessionId || !this.forkId) {\n throw new Error('CheckpointManager not initialized');\n }\n\n // Export state via anvil_dumpState\n const state = await rpcCall<string>(rpcUrl, 'anvil_dumpState');\n\n // Get current block number\n const blockNumberHex = await rpcCall<string>(rpcUrl, 'eth_blockNumber');\n const blockNumber = parseInt(blockNumberHex, 16);\n\n // Generate checkpoint ID\n const checkpointId = this.generateCheckpointId();\n\n const metadata: CheckpointMetadata = {\n id: checkpointId,\n sessionId: this.sessionId,\n forkId: this.forkId,\n snapshotRange: {\n first: this.firstSnapshotId ?? '',\n last: this.lastSnapshotId ?? '',\n },\n blockNumber,\n createdAt: new Date(),\n snapshotCount: this.snapshotCount,\n };\n\n // Save to disk\n await this.saveCheckpoint(checkpointId, state, metadata);\n\n // Store in memory\n this.checkpoints.set(checkpointId, metadata);\n\n // Reset snapshot counter\n this.snapshotCount = 0;\n this.firstSnapshotId = null;\n this.lastSnapshotId = null;\n\n // Cleanup old checkpoints\n await this.cleanup();\n\n return metadata;\n }\n\n /**\n * Restore from a checkpoint\n *\n * @param checkpointId - Checkpoint ID to restore\n * @param forkManager - ForkManager instance\n * @param network - Network configuration\n * @returns New fork with restored state\n */\n async restore(\n checkpointId: string,\n forkManager: ForkManager,\n network: NetworkConfig\n ): Promise<Fork> {\n if (!this.sessionId) {\n throw new Error('CheckpointManager not initialized');\n }\n\n const checkpoint = this.checkpoints.get(checkpointId);\n if (!checkpoint) {\n throw new Error(`Checkpoint ${checkpointId} not found`);\n }\n\n // Load state from disk\n const statePath = this.getStatePath(checkpointId);\n const state = await readFile(statePath, 'utf-8');\n\n // Kill existing forks\n await forkManager.killAll();\n\n // Spawn new fork\n const fork = await forkManager.fork({\n network,\n blockNumber: checkpoint.blockNumber,\n sessionId: this.sessionId,\n });\n\n // Load state via anvil_loadState\n await rpcCall<boolean>(fork.rpcUrl, 'anvil_loadState', [state]);\n\n // Update fork ID\n this.forkId = fork.id;\n\n return fork;\n }\n\n /**\n * Find the checkpoint containing a specific snapshot\n *\n * @param snapshotId - Snapshot ID to find\n * @returns Checkpoint metadata if found\n */\n findCheckpointForSnapshot(snapshotId: string): CheckpointMetadata | undefined {\n // Sort checkpoints by creation time (newest first)\n const sorted = this.list().sort(\n (a, b) => b.createdAt.getTime() - a.createdAt.getTime()\n );\n\n // Find the checkpoint whose range contains this snapshot\n // Note: This is a simplified check - in production, you'd need proper range tracking\n for (const checkpoint of sorted) {\n if (\n checkpoint.snapshotRange.first <= snapshotId &&\n checkpoint.snapshotRange.last >= snapshotId\n ) {\n return checkpoint;\n }\n }\n\n // Fall back to latest checkpoint\n return sorted[0];\n }\n\n /**\n * Get checkpoint by ID\n *\n * @param checkpointId - Checkpoint ID\n * @returns Checkpoint metadata if found\n */\n get(checkpointId: string): CheckpointMetadata | undefined {\n return this.checkpoints.get(checkpointId);\n }\n\n /**\n * List all checkpoints sorted by time\n *\n * @returns Array of checkpoint metadata\n */\n list(): CheckpointMetadata[] {\n return Array.from(this.checkpoints.values()).sort(\n (a, b) => a.createdAt.getTime() - b.createdAt.getTime()\n );\n }\n\n /**\n * Get the latest checkpoint\n *\n * @returns Latest checkpoint metadata\n */\n latest(): CheckpointMetadata | undefined {\n const sorted = this.list();\n return sorted[sorted.length - 1];\n }\n\n /**\n * Cleanup old checkpoints, keeping only the most recent\n */\n async cleanup(): Promise<void> {\n const sorted = this.list();\n\n if (sorted.length <= this.maxCheckpoints) {\n return;\n }\n\n const toDelete = sorted.slice(0, sorted.length - this.maxCheckpoints);\n\n for (const checkpoint of toDelete) {\n await this.deleteCheckpoint(checkpoint.id);\n }\n }\n\n /**\n * Get session directory path\n */\n private getSessionDir(): string {\n if (!this.sessionId) {\n throw new Error('Session ID not set');\n }\n return join(this.basePath, this.sessionId);\n }\n\n /**\n * Get checkpoint directory path\n */\n private getCheckpointDir(checkpointId: string): string {\n return join(this.getSessionDir(), checkpointId);\n }\n\n /**\n * Get state file path\n */\n private getStatePath(checkpointId: string): string {\n return join(this.getCheckpointDir(checkpointId), 'state.json');\n }\n\n /**\n * Get metadata file path\n */\n private getMetaPath(checkpointId: string): string {\n return join(this.getCheckpointDir(checkpointId), 'meta.json');\n }\n\n /**\n * Load checkpoints from disk\n */\n private async loadCheckpoints(): Promise<void> {\n const dir = this.getSessionDir();\n\n if (!existsSync(dir)) {\n return;\n }\n\n try {\n const entries = await readdir(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n\n const metaPath = this.getMetaPath(entry.name);\n if (!existsSync(metaPath)) continue;\n\n try {\n const content = await readFile(metaPath, 'utf-8');\n const data = JSON.parse(content) as CheckpointMetadata;\n data.createdAt = new Date(data.createdAt);\n this.checkpoints.set(data.id, data);\n } catch {\n // Skip corrupt metadata\n }\n }\n } catch {\n // Directory can't be read\n }\n }\n\n /**\n * Save checkpoint to disk\n */\n private async saveCheckpoint(\n checkpointId: string,\n state: string,\n metadata: CheckpointMetadata\n ): Promise<void> {\n const dir = this.getCheckpointDir(checkpointId);\n\n if (!existsSync(dir)) {\n await mkdir(dir, { recursive: true });\n }\n\n // Save state\n await writeFile(this.getStatePath(checkpointId), state);\n\n // Save metadata\n await writeFile(this.getMetaPath(checkpointId), JSON.stringify(metadata, null, 2));\n }\n\n /**\n * Delete a checkpoint from disk\n */\n private async deleteCheckpoint(checkpointId: string): Promise<void> {\n this.checkpoints.delete(checkpointId);\n\n const dir = this.getCheckpointDir(checkpointId);\n if (existsSync(dir)) {\n await rm(dir, { recursive: true });\n }\n }\n\n /**\n * Generate a unique checkpoint ID\n */\n private generateCheckpointId(): string {\n const timestamp = Date.now().toString(36);\n const random = Math.random().toString(36).substring(2, 6);\n return `cp-${timestamp}-${random}`;\n }\n}\n\n/** Singleton instance */\nlet defaultManager: CheckpointManager | null = null;\n\n/**\n * Get the default CheckpointManager instance\n */\nexport function getCheckpointManager(): CheckpointManager {\n if (!defaultManager) {\n defaultManager = new CheckpointManager();\n }\n return defaultManager;\n}\n\n/**\n * Reset the default CheckpointManager (for testing)\n */\nexport function resetCheckpointManager(): void {\n defaultManager = null;\n}\n","/**\n * SessionManager - Session lifecycle management\n *\n * Manages session creation, persistence, and recovery.\n * Coordinates ForkManager, SnapshotManager, CheckpointManager, and TaskGraph.\n */\n\nimport { readFile, writeFile, mkdir, readdir } from 'node:fs/promises';\nimport { existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { ForkManager } from './fork-manager.js';\nimport { SnapshotManager } from './snapshot-manager.js';\nimport { CheckpointManager } from './checkpoint-manager.js';\nimport { TaskGraph } from '../graph/task-graph.js';\nimport type { Fork, NetworkConfig, Task } from '../types.js';\n\n/** Session metadata */\nexport interface SessionMetadata {\n /** Session ID */\n id: string;\n /** Network configuration */\n network: NetworkConfig;\n /** Current fork ID */\n forkId: string;\n /** Creation timestamp */\n createdAt: Date;\n /** Last activity timestamp */\n lastActivity: Date;\n /** Session status */\n status: 'active' | 'suspended' | 'complete' | 'failed';\n /** Initial block number */\n initialBlock: number;\n}\n\n/** Session manager configuration */\nexport interface SessionManagerConfig {\n /** Base path for session data */\n basePath?: string;\n}\n\n/** Session state with all managers */\nexport interface Session {\n metadata: SessionMetadata;\n fork: Fork;\n forkManager: ForkManager;\n snapshotManager: SnapshotManager;\n checkpointManager: CheckpointManager;\n taskGraph: TaskGraph;\n}\n\n/** Default base path */\nconst DEFAULT_BASE_PATH = 'grimoires/anchor/sessions';\n\n/**\n * SessionManager class for session lifecycle\n */\nexport class SessionManager {\n private sessions: Map<string, SessionMetadata> = new Map();\n private currentSession: Session | null = null;\n private basePath: string;\n\n constructor(config?: SessionManagerConfig) {\n this.basePath = config?.basePath ?? DEFAULT_BASE_PATH;\n }\n\n /**\n * Initialize the manager by loading session index\n */\n async init(): Promise<void> {\n await this.loadSessionIndex();\n }\n\n /**\n * Create a new session\n *\n * @param network - Network to fork\n * @param options - Session options\n * @returns Created session\n */\n async create(\n network: NetworkConfig,\n options?: { blockNumber?: number }\n ): Promise<Session> {\n const sessionId = this.generateSessionId();\n\n // Create fork manager and spawn fork\n const forkManager = new ForkManager();\n await forkManager.init();\n\n const fork = await forkManager.fork({\n network,\n sessionId,\n ...(options?.blockNumber !== undefined && { blockNumber: options.blockNumber }),\n });\n\n // Create snapshot manager\n const snapshotManager = new SnapshotManager();\n await snapshotManager.init(sessionId);\n\n // Create checkpoint manager\n const checkpointManager = new CheckpointManager();\n await checkpointManager.init(sessionId, fork.id);\n\n // Create task graph\n const taskGraph = new TaskGraph({\n sessionId,\n basePath: this.basePath,\n autoSave: true,\n });\n await taskGraph.init();\n\n // Create initial snapshot\n const initialSnapshot = await snapshotManager.create(\n {\n forkId: fork.id,\n sessionId,\n description: 'Initial session snapshot',\n },\n fork.rpcUrl\n );\n\n // Create fork task in graph\n const forkTask: Task = {\n id: `fork-${fork.id}`,\n type: 'fork',\n status: 'complete',\n snapshotId: initialSnapshot.id,\n dependencies: [],\n input: { network, blockNumber: fork.blockNumber },\n output: { forkId: fork.id, rpcUrl: fork.rpcUrl },\n createdAt: new Date(),\n completedAt: new Date(),\n };\n await taskGraph.addTask(forkTask);\n\n // Create session metadata\n const metadata: SessionMetadata = {\n id: sessionId,\n network,\n forkId: fork.id,\n createdAt: new Date(),\n lastActivity: new Date(),\n status: 'active',\n initialBlock: fork.blockNumber,\n };\n\n // Save session\n this.sessions.set(sessionId, metadata);\n await this.saveSession(metadata);\n await this.saveSessionIndex();\n\n // Set as current session\n this.currentSession = {\n metadata,\n fork,\n forkManager,\n snapshotManager,\n checkpointManager,\n taskGraph,\n };\n\n return this.currentSession;\n }\n\n /**\n * Resume an existing session\n *\n * @param sessionId - Session ID to resume\n * @returns Resumed session\n */\n async resume(sessionId: string): Promise<Session> {\n const metadata = this.sessions.get(sessionId);\n if (!metadata) {\n throw new Error(`Session ${sessionId} not found`);\n }\n\n // Initialize fork manager\n const forkManager = new ForkManager();\n await forkManager.init();\n\n // Initialize snapshot manager\n const snapshotManager = new SnapshotManager();\n await snapshotManager.init(sessionId);\n\n // Initialize checkpoint manager\n const checkpointManager = new CheckpointManager();\n\n // Initialize task graph\n const taskGraph = new TaskGraph({\n sessionId,\n basePath: this.basePath,\n autoSave: true,\n });\n await taskGraph.init();\n\n // Check for recovery needs\n let fork = forkManager.get(metadata.forkId);\n\n if (!fork || taskGraph.hasBlocked()) {\n // Need recovery\n fork = await this.recover(\n sessionId,\n metadata,\n forkManager,\n snapshotManager,\n checkpointManager,\n taskGraph\n );\n }\n\n if (!fork) {\n throw new Error(`Failed to restore fork for session ${sessionId}`);\n }\n\n // Update checkpoint manager with fork\n await checkpointManager.init(sessionId, fork.id);\n\n // Update metadata\n metadata.lastActivity = new Date();\n metadata.forkId = fork.id;\n metadata.status = 'active';\n await this.saveSession(metadata);\n\n // Set as current session\n this.currentSession = {\n metadata,\n fork,\n forkManager,\n snapshotManager,\n checkpointManager,\n taskGraph,\n };\n\n return this.currentSession;\n }\n\n /**\n * Recover a session from checkpoint or snapshot\n */\n private async recover(\n sessionId: string,\n metadata: SessionMetadata,\n forkManager: ForkManager,\n snapshotManager: SnapshotManager,\n checkpointManager: CheckpointManager,\n taskGraph: TaskGraph\n ): Promise<Fork> {\n // First, try to find a checkpoint\n const latestCheckpoint = checkpointManager.latest();\n\n if (latestCheckpoint) {\n // Restore from checkpoint\n console.log(`Recovering session ${sessionId} from checkpoint ${latestCheckpoint.id}`);\n return await checkpointManager.restore(\n latestCheckpoint.id,\n forkManager,\n metadata.network\n );\n }\n\n // No checkpoint - find recovery point in task graph\n const blockedTasks = taskGraph.getTasksByStatus('blocked');\n const failedTasks = taskGraph.getTasksByStatus('failed');\n const problematicTask = blockedTasks[0] ?? failedTasks[0];\n\n if (problematicTask) {\n const recoveryPoint = taskGraph.findRecoveryPoint(problematicTask.id);\n\n if (recoveryPoint?.snapshotId) {\n // Spawn new fork and revert to snapshot\n const fork = await forkManager.fork({\n network: metadata.network,\n blockNumber: metadata.initialBlock,\n sessionId,\n });\n\n const success = await snapshotManager.revert(fork.rpcUrl, recoveryPoint.snapshotId);\n if (!success) {\n throw new Error(`Failed to revert to snapshot ${recoveryPoint.snapshotId}`);\n }\n\n // Mark problematic tasks as pending for retry\n for (const task of [...blockedTasks, ...failedTasks]) {\n await taskGraph.updateStatus(task.id, 'pending');\n }\n\n return fork;\n }\n }\n\n // No recovery point found - create fresh fork\n console.log(`No recovery point found, creating fresh fork for session ${sessionId}`);\n return await forkManager.fork({\n network: metadata.network,\n blockNumber: metadata.initialBlock,\n sessionId,\n });\n }\n\n /**\n * Get current session\n *\n * @returns Current session or null\n */\n current(): Session | null {\n return this.currentSession;\n }\n\n /**\n * List all sessions\n *\n * @param filter - Optional filter for status\n * @returns Array of session metadata\n */\n list(filter?: { status?: SessionMetadata['status']; blocked?: boolean }): SessionMetadata[] {\n let sessions = Array.from(this.sessions.values());\n\n if (filter?.status) {\n sessions = sessions.filter((s) => s.status === filter.status);\n }\n\n return sessions.sort((a, b) => b.lastActivity.getTime() - a.lastActivity.getTime());\n }\n\n /**\n * Get session by ID\n *\n * @param sessionId - Session ID\n * @returns Session metadata if found\n */\n get(sessionId: string): SessionMetadata | undefined {\n return this.sessions.get(sessionId);\n }\n\n /**\n * Update session status\n *\n * @param sessionId - Session ID\n * @param status - New status\n */\n async updateStatus(sessionId: string, status: SessionMetadata['status']): Promise<void> {\n const metadata = this.sessions.get(sessionId);\n if (!metadata) {\n throw new Error(`Session ${sessionId} not found`);\n }\n\n metadata.status = status;\n metadata.lastActivity = new Date();\n await this.saveSession(metadata);\n }\n\n /**\n * Get session directory path\n */\n private getSessionDir(sessionId: string): string {\n return join(this.basePath, sessionId);\n }\n\n /**\n * Get session metadata path\n */\n private getSessionPath(sessionId: string): string {\n return join(this.getSessionDir(sessionId), 'session.json');\n }\n\n /**\n * Load session index\n */\n private async loadSessionIndex(): Promise<void> {\n if (!existsSync(this.basePath)) {\n return;\n }\n\n try {\n const entries = await readdir(this.basePath, { withFileTypes: true });\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n\n const sessionPath = this.getSessionPath(entry.name);\n if (!existsSync(sessionPath)) continue;\n\n try {\n const content = await readFile(sessionPath, 'utf-8');\n const data = JSON.parse(content) as SessionMetadata;\n data.createdAt = new Date(data.createdAt);\n data.lastActivity = new Date(data.lastActivity);\n this.sessions.set(data.id, data);\n } catch {\n // Skip corrupt session\n }\n }\n } catch {\n // Can't read sessions directory\n }\n }\n\n /**\n * Save session index\n */\n private async saveSessionIndex(): Promise<void> {\n if (!existsSync(this.basePath)) {\n await mkdir(this.basePath, { recursive: true });\n }\n\n const index = Array.from(this.sessions.values()).map((s) => ({\n id: s.id,\n status: s.status,\n lastActivity: s.lastActivity,\n }));\n\n await writeFile(\n join(this.basePath, 'index.json'),\n JSON.stringify(index, null, 2)\n );\n }\n\n /**\n * Save session metadata\n */\n private async saveSession(metadata: SessionMetadata): Promise<void> {\n const dir = this.getSessionDir(metadata.id);\n\n if (!existsSync(dir)) {\n await mkdir(dir, { recursive: true });\n }\n\n await writeFile(this.getSessionPath(metadata.id), JSON.stringify(metadata, null, 2));\n }\n\n /**\n * Generate unique session ID\n */\n private generateSessionId(): string {\n const timestamp = Date.now().toString(36);\n const random = Math.random().toString(36).substring(2, 6);\n return `session-${timestamp}-${random}`;\n }\n}\n\n/** Singleton instance */\nlet defaultManager: SessionManager | null = null;\n\n/**\n * Get the default SessionManager instance\n */\nexport function getSessionManager(): SessionManager {\n if (!defaultManager) {\n defaultManager = new SessionManager();\n }\n return defaultManager;\n}\n\n/**\n * Reset the default SessionManager (for testing)\n */\nexport function resetSessionManager(): void {\n defaultManager = null;\n}\n","/**\n * TaskGraph - State-pinned DAG for task management\n *\n * Manages task dependencies, status tracking, and snapshot binding.\n * Persists graph state to grimoires/anchor/sessions/{sessionId}/graph.json\n */\n\nimport { readFile, writeFile, mkdir } from 'node:fs/promises';\nimport { existsSync } from 'node:fs';\nimport { join, dirname } from 'node:path';\nimport { z } from 'zod';\nimport type { Task, TaskType, TaskStatus, TaskGraphData } from '../types.js';\n\n/** Zod schema for task validation */\nconst TaskSchema = z.object({\n id: z.string(),\n type: z.enum(['fork', 'ground', 'warden', 'generate', 'validate', 'write']),\n status: z.enum(['pending', 'running', 'complete', 'blocked', 'failed']),\n snapshotId: z.string().optional(),\n checkpointId: z.string().optional(),\n dependencies: z.array(z.string()),\n input: z.unknown(),\n output: z.unknown().optional(),\n error: z.string().optional(),\n createdAt: z.string().transform((s: string) => new Date(s)),\n completedAt: z\n .string()\n .transform((s: string) => new Date(s))\n .optional(),\n});\n\nconst TaskGraphDataSchema = z.object({\n sessionId: z.string(),\n tasks: z.array(TaskSchema),\n headTaskId: z.string().optional(),\n lastUpdated: z.string().transform((s: string) => new Date(s)),\n});\n\n/** Task graph configuration */\nexport interface TaskGraphConfig {\n /** Session ID */\n sessionId: string;\n /** Base path for session data */\n basePath?: string;\n /** Auto-save on changes */\n autoSave?: boolean;\n}\n\n/** Default base path */\nconst DEFAULT_BASE_PATH = 'grimoires/anchor/sessions';\n\n/** Task ID counter for generating unique IDs */\nlet taskCounter = 0;\n\n/**\n * Generate a unique task ID\n */\nexport function generateTaskId(type: TaskType): string {\n return `${type}-${Date.now().toString(36)}-${(++taskCounter).toString(36)}`;\n}\n\n/**\n * Reset the task counter (for testing)\n */\nexport function resetTaskCounter(): void {\n taskCounter = 0;\n}\n\n/**\n * TaskGraph class for managing state-pinned task DAG\n */\nexport class TaskGraph {\n private tasks: Map<string, Task> = new Map();\n private dependents: Map<string, Set<string>> = new Map();\n private sessionId: string;\n private basePath: string;\n private autoSave: boolean;\n private headTaskId: string | undefined;\n\n constructor(config: TaskGraphConfig) {\n this.sessionId = config.sessionId;\n this.basePath = config.basePath ?? DEFAULT_BASE_PATH;\n this.autoSave = config.autoSave ?? true;\n }\n\n /**\n * Initialize the graph by loading persisted state\n */\n async init(): Promise<void> {\n await this.load();\n }\n\n /**\n * Add a task to the graph\n *\n * @param task - Task to add\n */\n async addTask(task: Task): Promise<void> {\n // Validate no circular dependencies\n this.validateNoCycle(task);\n\n this.tasks.set(task.id, task);\n\n // Track reverse dependencies\n for (const depId of task.dependencies) {\n if (!this.dependents.has(depId)) {\n this.dependents.set(depId, new Set());\n }\n this.dependents.get(depId)!.add(task.id);\n }\n\n this.headTaskId = task.id;\n\n if (this.autoSave) {\n await this.save();\n }\n }\n\n /**\n * Update task status\n *\n * @param taskId - Task ID\n * @param status - New status\n */\n async updateStatus(taskId: string, status: TaskStatus): Promise<void> {\n const task = this.tasks.get(taskId);\n if (!task) {\n throw new Error(`Task ${taskId} not found`);\n }\n\n task.status = status;\n if (status === 'complete' || status === 'failed') {\n task.completedAt = new Date();\n }\n\n if (this.autoSave) {\n await this.save();\n }\n }\n\n /**\n * Set the snapshot binding for a task\n *\n * @param taskId - Task ID\n * @param snapshotId - Snapshot ID\n */\n async setSnapshot(taskId: string, snapshotId: string): Promise<void> {\n const task = this.tasks.get(taskId);\n if (!task) {\n throw new Error(`Task ${taskId} not found`);\n }\n\n task.snapshotId = snapshotId;\n\n if (this.autoSave) {\n await this.save();\n }\n }\n\n /**\n * Set the checkpoint binding for a task\n *\n * @param taskId - Task ID\n * @param checkpointId - Checkpoint ID\n */\n async setCheckpoint(taskId: string, checkpointId: string): Promise<void> {\n const task = this.tasks.get(taskId);\n if (!task) {\n throw new Error(`Task ${taskId} not found`);\n }\n\n task.checkpointId = checkpointId;\n\n if (this.autoSave) {\n await this.save();\n }\n }\n\n /**\n * Set task output\n *\n * @param taskId - Task ID\n * @param output - Task output\n */\n async setOutput(taskId: string, output: unknown): Promise<void> {\n const task = this.tasks.get(taskId);\n if (!task) {\n throw new Error(`Task ${taskId} not found`);\n }\n\n task.output = output;\n\n if (this.autoSave) {\n await this.save();\n }\n }\n\n /**\n * Set task error\n *\n * @param taskId - Task ID\n * @param error - Error message\n */\n async setError(taskId: string, error: string): Promise<void> {\n const task = this.tasks.get(taskId);\n if (!task) {\n throw new Error(`Task ${taskId} not found`);\n }\n\n task.error = error;\n task.status = 'failed';\n\n if (this.autoSave) {\n await this.save();\n }\n }\n\n /**\n * Get a task by ID\n *\n * @param taskId - Task ID\n * @returns Task if found\n */\n getTask(taskId: string): Task | undefined {\n return this.tasks.get(taskId);\n }\n\n /**\n * Get all tasks\n *\n * @returns Array of all tasks\n */\n getAllTasks(): Task[] {\n return Array.from(this.tasks.values());\n }\n\n /**\n * Get tasks by status\n *\n * @param status - Status to filter by\n * @returns Array of matching tasks\n */\n getTasksByStatus(status: TaskStatus): Task[] {\n return Array.from(this.tasks.values()).filter((t) => t.status === status);\n }\n\n /**\n * Check if a task can run (all dependencies complete)\n *\n * @param taskId - Task ID\n * @returns True if all dependencies are complete\n */\n canRun(taskId: string): boolean {\n const task = this.tasks.get(taskId);\n if (!task) return false;\n if (task.status !== 'pending') return false;\n\n for (const depId of task.dependencies) {\n const dep = this.tasks.get(depId);\n if (!dep || dep.status !== 'complete') {\n return false;\n }\n }\n\n return true;\n }\n\n /**\n * Get the next runnable task (pending with all deps complete)\n *\n * @returns Next runnable task or undefined\n */\n getNextRunnable(): Task | undefined {\n for (const task of this.tasks.values()) {\n if (this.canRun(task.id)) {\n return task;\n }\n }\n return undefined;\n }\n\n /**\n * Propagate blocked status to all dependents of a failed task\n *\n * @param taskId - ID of the failed task\n */\n async propagateBlocked(taskId: string): Promise<void> {\n const dependentIds = this.dependents.get(taskId);\n if (!dependentIds) return;\n\n for (const depId of dependentIds) {\n const task = this.tasks.get(depId);\n if (task && task.status === 'pending') {\n task.status = 'blocked';\n await this.propagateBlocked(depId);\n }\n }\n\n if (this.autoSave) {\n await this.save();\n }\n }\n\n /**\n * Find the recovery point for a failed task\n *\n * @param taskId - ID of the task needing recovery\n * @returns Last complete task with snapshot, or undefined\n */\n findRecoveryPoint(taskId: string): Task | undefined {\n const task = this.tasks.get(taskId);\n if (!task) return undefined;\n\n // Walk back through dependencies to find last complete with snapshot\n const visited = new Set<string>();\n const queue = [...task.dependencies];\n\n let bestRecovery: Task | undefined;\n\n while (queue.length > 0) {\n const id = queue.pop()!;\n if (visited.has(id)) continue;\n visited.add(id);\n\n const dep = this.tasks.get(id);\n if (!dep) continue;\n\n if (dep.status === 'complete' && dep.snapshotId) {\n if (!bestRecovery || dep.createdAt > bestRecovery.createdAt) {\n bestRecovery = dep;\n }\n }\n\n queue.push(...dep.dependencies);\n }\n\n return bestRecovery;\n }\n\n /**\n * Check if there are any blocked tasks\n *\n * @returns True if any tasks are blocked\n */\n hasBlocked(): boolean {\n for (const task of this.tasks.values()) {\n if (task.status === 'blocked') {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Check if all tasks are complete\n *\n * @returns True if all tasks are complete\n */\n isComplete(): boolean {\n for (const task of this.tasks.values()) {\n if (task.status !== 'complete') {\n return false;\n }\n }\n return this.tasks.size > 0;\n }\n\n /**\n * Get the graph file path\n */\n private getGraphPath(): string {\n return join(this.basePath, this.sessionId, 'graph.json');\n }\n\n /**\n * Export graph data as JSON-serializable object\n *\n * @returns Task graph data\n */\n toJSON(): TaskGraphData {\n return {\n sessionId: this.sessionId,\n tasks: Array.from(this.tasks.values()),\n lastUpdated: new Date(),\n ...(this.headTaskId !== undefined && { headTaskId: this.headTaskId }),\n };\n }\n\n /**\n * Save the graph to disk\n */\n async save(): Promise<void> {\n const data = this.toJSON();\n\n const path = this.getGraphPath();\n const dir = dirname(path);\n\n if (!existsSync(dir)) {\n await mkdir(dir, { recursive: true });\n }\n\n await writeFile(path, JSON.stringify(data, null, 2));\n }\n\n /**\n * Load the graph from disk\n */\n async load(): Promise<void> {\n const path = this.getGraphPath();\n\n if (!existsSync(path)) {\n return;\n }\n\n try {\n const content = await readFile(path, 'utf-8');\n const raw = JSON.parse(content);\n const data = TaskGraphDataSchema.parse(raw);\n\n this.tasks.clear();\n this.dependents.clear();\n\n for (const task of data.tasks) {\n this.tasks.set(task.id, task as Task);\n\n for (const depId of task.dependencies) {\n if (!this.dependents.has(depId)) {\n this.dependents.set(depId, new Set());\n }\n this.dependents.get(depId)!.add(task.id);\n }\n }\n\n this.headTaskId = data.headTaskId;\n } catch {\n // Corrupt file, start fresh\n }\n }\n\n /**\n * Validate that adding a task doesn't create a cycle\n */\n private validateNoCycle(newTask: Task): void {\n const visited = new Set<string>();\n const stack = new Set<string>();\n\n const hasCycle = (taskId: string): boolean => {\n if (stack.has(taskId)) return true;\n if (visited.has(taskId)) return false;\n\n visited.add(taskId);\n stack.add(taskId);\n\n const task = taskId === newTask.id ? newTask : this.tasks.get(taskId);\n if (task) {\n for (const depId of task.dependencies) {\n if (hasCycle(depId)) return true;\n }\n }\n\n stack.delete(taskId);\n return false;\n };\n\n if (hasCycle(newTask.id)) {\n throw new Error(`Adding task ${newTask.id} would create a circular dependency`);\n }\n }\n}\n","/**\n * PhysicsLoader - Load Sigil physics rules from markdown\n *\n * Parses .claude/rules/01-sigil-physics.md to extract the physics table.\n */\n\nimport { readFile } from 'node:fs/promises';\nimport { existsSync } from 'node:fs';\nimport type {\n PhysicsTable,\n PhysicsRule,\n EffectType,\n SyncStrategy,\n ConfirmationType,\n} from './types.js';\n\n/** Default physics rules path */\nconst DEFAULT_PHYSICS_PATH = '.claude/rules/01-sigil-physics.md';\n\n/** Cached physics table */\nlet cachedPhysics: PhysicsTable | null = null;\nlet cachedPath: string | null = null;\n\n/**\n * Parse sync strategy from string\n */\nfunction parseSyncStrategy(value: string): SyncStrategy {\n const normalized = value.toLowerCase().trim();\n if (normalized === 'pessimistic') return 'pessimistic';\n if (normalized === 'optimistic') return 'optimistic';\n if (normalized === 'immediate') return 'immediate';\n return 'optimistic'; // Default\n}\n\n/**\n * Parse timing from string (e.g., \"800ms\" -> 800)\n */\nfunction parseTiming(value: string): number {\n const match = value.match(/(\\d+)\\s*ms/i);\n if (match && match[1]) {\n return parseInt(match[1], 10);\n }\n // Try plain number\n const num = parseInt(value, 10);\n return isNaN(num) ? 200 : num;\n}\n\n/**\n * Parse confirmation type from string\n */\nfunction parseConfirmation(value: string): ConfirmationType {\n const normalized = value.toLowerCase().trim();\n if (normalized === 'required' || normalized === 'yes') return 'required';\n if (normalized.includes('toast') || normalized.includes('undo')) return 'toast_undo';\n if (normalized === 'none' || normalized === 'no') return 'none';\n return 'none';\n}\n\n/**\n * Parse effect type from string\n */\nfunction parseEffectType(value: string): EffectType | null {\n const normalized = value.toLowerCase().replace(/[\\s-]/g, '_').trim();\n\n const mapping: Record<string, EffectType> = {\n financial: 'financial',\n destructive: 'destructive',\n soft_delete: 'soft_delete',\n 'soft delete': 'soft_delete',\n standard: 'standard',\n navigation: 'navigation',\n query: 'query',\n local_state: 'local',\n 'local state': 'local',\n local: 'local',\n high_freq: 'high_freq',\n 'high-freq': 'high_freq',\n highfreq: 'high_freq',\n };\n\n return mapping[normalized] ?? null;\n}\n\n/**\n * Parse physics table from markdown content\n */\nfunction parsePhysicsTable(content: string): PhysicsTable {\n const physics: PhysicsTable = new Map();\n\n // Find the physics table section\n const tableMatch = content.match(\n /<physics_table>[\\s\\S]*?\\|[\\s\\S]*?<\\/physics_table>/\n );\n\n if (!tableMatch) {\n console.warn('Physics table not found in content');\n return getDefaultPhysics();\n }\n\n const tableContent = tableMatch[0];\n\n // Parse markdown table rows\n // Format: | Effect | Sync | Timing | Confirmation | Why |\n const lines = tableContent.split('\\n');\n\n for (const line of lines) {\n // Skip header and separator lines\n if (!line.includes('|') || line.includes('---') || line.includes('Effect')) {\n continue;\n }\n\n const cells = line\n .split('|')\n .map((c) => c.trim())\n .filter((c) => c.length > 0);\n\n if (cells.length < 4) continue;\n\n const effectStr = cells[0];\n const syncStr = cells[1];\n const timingStr = cells[2];\n const confirmStr = cells[3];\n const whyParts = cells.slice(4);\n\n if (!effectStr || !syncStr || !timingStr || !confirmStr) continue;\n\n const effect = parseEffectType(effectStr);\n if (!effect) continue;\n\n const rule: PhysicsRule = {\n effect,\n sync: parseSyncStrategy(syncStr),\n timing: parseTiming(timingStr),\n confirmation: parseConfirmation(confirmStr),\n rationale: whyParts.join(' ').trim(),\n };\n\n physics.set(effect, rule);\n }\n\n return physics;\n}\n\n/**\n * Get default physics table (fallback when file not found)\n */\nexport function getDefaultPhysics(): PhysicsTable {\n const physics: PhysicsTable = new Map();\n\n physics.set('financial', {\n effect: 'financial',\n sync: 'pessimistic',\n timing: 800,\n confirmation: 'required',\n rationale: \"Money can't roll back. Users need time to verify.\",\n });\n\n physics.set('destructive', {\n effect: 'destructive',\n sync: 'pessimistic',\n timing: 600,\n confirmation: 'required',\n rationale: 'Permanent actions need deliberation.',\n });\n\n physics.set('soft_delete', {\n effect: 'soft_delete',\n sync: 'optimistic',\n timing: 200,\n confirmation: 'toast_undo',\n rationale: 'Undo exists, so we can be fast.',\n });\n\n physics.set('standard', {\n effect: 'standard',\n sync: 'optimistic',\n timing: 200,\n confirmation: 'none',\n rationale: 'Low stakes = snappy feedback.',\n });\n\n physics.set('navigation', {\n effect: 'navigation',\n sync: 'immediate',\n timing: 150,\n confirmation: 'none',\n rationale: 'URL changes feel instant.',\n });\n\n physics.set('query', {\n effect: 'query',\n sync: 'optimistic',\n timing: 150,\n confirmation: 'none',\n rationale: 'Data retrieval, no state change.',\n });\n\n physics.set('local', {\n effect: 'local',\n sync: 'immediate',\n timing: 100,\n confirmation: 'none',\n rationale: 'No server = instant expected.',\n });\n\n physics.set('high_freq', {\n effect: 'high_freq',\n sync: 'immediate',\n timing: 0,\n confirmation: 'none',\n rationale: 'Animation becomes friction.',\n });\n\n return physics;\n}\n\n/**\n * Load physics from file\n *\n * @param path - Path to physics markdown file (default: .claude/rules/01-sigil-physics.md)\n * @returns Parsed physics table\n */\nexport async function loadPhysics(path?: string): Promise<PhysicsTable> {\n const physicsPath = path ?? DEFAULT_PHYSICS_PATH;\n\n // Return cached if same path\n if (cachedPhysics && cachedPath === physicsPath) {\n return cachedPhysics;\n }\n\n // Check if file exists\n if (!existsSync(physicsPath)) {\n console.warn(`Physics file not found at ${physicsPath}, using defaults`);\n cachedPhysics = getDefaultPhysics();\n cachedPath = physicsPath;\n return cachedPhysics;\n }\n\n try {\n const content = await readFile(physicsPath, 'utf-8');\n cachedPhysics = parsePhysicsTable(content);\n cachedPath = physicsPath;\n\n // If parsing found nothing, use defaults\n if (cachedPhysics.size === 0) {\n console.warn('No physics rules parsed, using defaults');\n cachedPhysics = getDefaultPhysics();\n }\n\n return cachedPhysics;\n } catch (error) {\n console.warn(`Error loading physics from ${physicsPath}:`, error);\n cachedPhysics = getDefaultPhysics();\n cachedPath = physicsPath;\n return cachedPhysics;\n }\n}\n\n/**\n * Get physics rule for an effect type\n *\n * @param effect - Effect type to look up\n * @param physics - Physics table (will load if not provided)\n * @returns Physics rule or undefined\n */\nexport async function getPhysicsRule(\n effect: EffectType,\n physics?: PhysicsTable\n): Promise<PhysicsRule | undefined> {\n const table = physics ?? (await loadPhysics());\n return table.get(effect);\n}\n\n/**\n * Clear physics cache (for testing)\n */\nexport function clearPhysicsCache(): void {\n cachedPhysics = null;\n cachedPath = null;\n}\n\n/**\n * Check if physics are cached\n */\nexport function isPhysicsCached(): boolean {\n return cachedPhysics !== null;\n}\n","/**\n * VocabularyLoader - Load Sigil vocabulary from markdown\n *\n * Parses .claude/rules/08-sigil-lexicon.md to extract keyword → effect mappings.\n */\n\nimport { readFile } from 'node:fs/promises';\nimport { existsSync } from 'node:fs';\nimport type { Vocabulary, VocabularyEntry, EffectType } from './types.js';\n\n/** Default vocabulary path */\nconst DEFAULT_VOCABULARY_PATH = '.claude/rules/08-sigil-lexicon.md';\n\n/** Cached vocabulary */\nlet cachedVocabulary: Vocabulary | null = null;\nlet cachedPath: string | null = null;\n\n/**\n * Parse keywords from a code block section\n */\nfunction parseKeywordsFromBlock(block: string): string[] {\n const keywords: string[] = [];\n\n // Split by lines and extract keywords\n const lines = block.split('\\n');\n for (const line of lines) {\n // Skip category labels like \"Primary:\", \"Extended:\", etc.\n const colonIndex = line.indexOf(':');\n const content = colonIndex >= 0 ? line.slice(colonIndex + 1) : line;\n\n // Split by comma and extract individual keywords\n const words = content\n .split(/[,\\s]+/)\n .map((w) => w.trim().toLowerCase())\n .filter((w) => w.length > 0 && !w.includes('```'));\n\n keywords.push(...words);\n }\n\n return [...new Set(keywords)]; // Deduplicate\n}\n\n/**\n * Parse effect keywords section\n */\nfunction parseEffectKeywords(content: string): Map<EffectType, VocabularyEntry> {\n const effects = new Map<EffectType, VocabularyEntry>();\n\n // Find the effect_keywords section\n const sectionMatch = content.match(\n /<effect_keywords>[\\s\\S]*?<\\/effect_keywords>/\n );\n\n if (!sectionMatch) {\n return effects;\n }\n\n const section = sectionMatch[0];\n\n // Define effect patterns with their headers\n const effectPatterns: Array<{ effect: EffectType; pattern: RegExp }> = [\n {\n effect: 'financial',\n pattern: /###\\s*Financial[\\s\\S]*?```([\\s\\S]*?)```/i,\n },\n {\n effect: 'destructive',\n pattern: /###\\s*Destructive[\\s\\S]*?```([\\s\\S]*?)```/i,\n },\n {\n effect: 'soft_delete',\n pattern: /###\\s*Soft\\s*Delete[\\s\\S]*?```([\\s\\S]*?)```/i,\n },\n {\n effect: 'standard',\n pattern: /###\\s*Standard[\\s\\S]*?```([\\s\\S]*?)```/i,\n },\n {\n effect: 'local',\n pattern: /###\\s*Local\\s*State[\\s\\S]*?```([\\s\\S]*?)```/i,\n },\n {\n effect: 'navigation',\n pattern: /###\\s*Navigation[\\s\\S]*?```([\\s\\S]*?)```/i,\n },\n {\n effect: 'query',\n pattern: /###\\s*Query[\\s\\S]*?```([\\s\\S]*?)```/i,\n },\n ];\n\n for (const { effect, pattern } of effectPatterns) {\n const match = section.match(pattern);\n if (match && match[1]) {\n const keywords = parseKeywordsFromBlock(match[1]);\n if (keywords.length > 0) {\n effects.set(effect, {\n keywords,\n effect,\n category: 'lexicon',\n });\n }\n }\n }\n\n return effects;\n}\n\n/**\n * Parse type overrides section\n */\nfunction parseTypeOverrides(content: string): Map<string, EffectType> {\n const overrides = new Map<string, EffectType>();\n\n // Find the type_overrides section\n const sectionMatch = content.match(\n /<type_overrides>[\\s\\S]*?<\\/type_overrides>/\n );\n\n if (!sectionMatch) {\n return overrides;\n }\n\n const section = sectionMatch[0];\n\n // Parse table rows: | Type Pattern | Forced Effect | Why |\n const lines = section.split('\\n');\n for (const line of lines) {\n if (!line.includes('|') || line.includes('---') || line.includes('Type Pattern')) {\n continue;\n }\n\n const cells = line\n .split('|')\n .map((c) => c.trim())\n .filter((c) => c.length > 0);\n\n if (cells.length < 2) continue;\n\n const typePattern = cells[0];\n const forcedEffect = cells[1];\n\n if (!typePattern || !forcedEffect) continue;\n\n // Parse type patterns (may contain backticks and commas)\n const types = typePattern\n .replace(/`/g, '')\n .split(',')\n .map((t) => t.trim().toLowerCase())\n .filter((t) => t.length > 0);\n\n // Map effect string to EffectType\n const effect = mapEffectString(forcedEffect);\n if (effect) {\n for (const type of types) {\n overrides.set(type, effect);\n }\n }\n }\n\n return overrides;\n}\n\n/**\n * Parse domain context defaults\n */\nfunction parseDomainDefaults(content: string): Map<string, EffectType> {\n const defaults = new Map<string, EffectType>();\n\n // Find the domain_context section\n const sectionMatch = content.match(\n /<domain_context>[\\s\\S]*?<\\/domain_context>/\n );\n\n if (!sectionMatch) {\n return defaults;\n }\n\n const section = sectionMatch[0];\n\n // Look for domain headers and their defaults\n const domainHeaderPattern = /###\\s*([\\w\\/]+)\\s*\\n```([\\s\\S]*?)```/gi;\n let match;\n\n while ((match = domainHeaderPattern.exec(section)) !== null) {\n const domainName = match[1];\n const domainContent = match[2];\n\n if (!domainName || !domainContent) continue;\n\n // Look for \"Default:\" line\n const defaultMatch = domainContent.match(/Default:\\s*([\\w\\s()]+)/i);\n if (defaultMatch && defaultMatch[1]) {\n const effect = mapEffectString(defaultMatch[1]);\n if (effect) {\n // Add domain keywords\n const keywordMatch = domainContent.match(/Keywords:\\s*([\\w,\\s]+)/i);\n if (keywordMatch && keywordMatch[1]) {\n const keywords = keywordMatch[1]\n .split(',')\n .map((k) => k.trim().toLowerCase())\n .filter((k) => k.length > 0);\n\n for (const keyword of keywords) {\n defaults.set(keyword, effect);\n }\n }\n // Also add domain name itself\n defaults.set(domainName.toLowerCase().replace('/', '_'), effect);\n }\n }\n }\n\n return defaults;\n}\n\n/**\n * Map effect string to EffectType\n */\nfunction mapEffectString(value: string): EffectType | null {\n const normalized = value.toLowerCase().trim();\n\n if (normalized.includes('financial')) return 'financial';\n if (normalized.includes('destructive')) return 'destructive';\n if (normalized.includes('soft') && normalized.includes('delete')) return 'soft_delete';\n if (normalized.includes('standard')) return 'standard';\n if (normalized.includes('local')) return 'local';\n if (normalized.includes('navigation')) return 'navigation';\n if (normalized.includes('query')) return 'query';\n if (normalized.includes('immediate')) return 'local';\n\n return null;\n}\n\n/**\n * Get default vocabulary (fallback)\n */\nexport function getDefaultVocabulary(): Vocabulary {\n const effects = new Map<EffectType, VocabularyEntry>();\n\n effects.set('financial', {\n keywords: [\n 'claim', 'deposit', 'withdraw', 'transfer', 'swap', 'send', 'pay', 'purchase',\n 'mint', 'burn', 'stake', 'unstake', 'bridge', 'approve', 'redeem', 'harvest',\n ],\n effect: 'financial',\n category: 'default',\n });\n\n effects.set('destructive', {\n keywords: [\n 'delete', 'remove', 'destroy', 'revoke', 'terminate', 'purge', 'erase', 'wipe',\n ],\n effect: 'destructive',\n category: 'default',\n });\n\n effects.set('soft_delete', {\n keywords: ['archive', 'hide', 'trash', 'dismiss', 'snooze', 'mute'],\n effect: 'soft_delete',\n category: 'default',\n });\n\n effects.set('standard', {\n keywords: [\n 'save', 'update', 'edit', 'create', 'add', 'like', 'follow', 'bookmark',\n ],\n effect: 'standard',\n category: 'default',\n });\n\n effects.set('local', {\n keywords: ['toggle', 'switch', 'expand', 'collapse', 'select', 'focus'],\n effect: 'local',\n category: 'default',\n });\n\n effects.set('navigation', {\n keywords: ['navigate', 'go', 'back', 'forward', 'link', 'route'],\n effect: 'navigation',\n category: 'default',\n });\n\n effects.set('query', {\n keywords: ['fetch', 'load', 'get', 'list', 'search', 'find'],\n effect: 'query',\n category: 'default',\n });\n\n const typeOverrides = new Map<string, EffectType>([\n ['currency', 'financial'],\n ['money', 'financial'],\n ['amount', 'financial'],\n ['wei', 'financial'],\n ['bigint', 'financial'],\n ['token', 'financial'],\n ['balance', 'financial'],\n ['price', 'financial'],\n ['fee', 'financial'],\n ['password', 'destructive'],\n ['secret', 'destructive'],\n ['key', 'destructive'],\n ['permission', 'destructive'],\n ['role', 'destructive'],\n ['access', 'destructive'],\n ['theme', 'local'],\n ['preference', 'local'],\n ['setting', 'local'],\n ['filter', 'local'],\n ['sort', 'local'],\n ['view', 'local'],\n ]);\n\n const domainDefaults = new Map<string, EffectType>([\n ['wallet', 'financial'],\n ['token', 'financial'],\n ['nft', 'financial'],\n ['contract', 'financial'],\n ['chain', 'financial'],\n ['gas', 'financial'],\n ['cart', 'standard'],\n ['checkout', 'financial'],\n ['payment', 'financial'],\n ]);\n\n return { effects, typeOverrides, domainDefaults };\n}\n\n/**\n * Load vocabulary from file\n *\n * @param path - Path to vocabulary markdown file\n * @returns Parsed vocabulary\n */\nexport async function loadVocabulary(path?: string): Promise<Vocabulary> {\n const vocabPath = path ?? DEFAULT_VOCABULARY_PATH;\n\n // Return cached if same path\n if (cachedVocabulary && cachedPath === vocabPath) {\n return cachedVocabulary;\n }\n\n // Check if file exists\n if (!existsSync(vocabPath)) {\n console.warn(`Vocabulary file not found at ${vocabPath}, using defaults`);\n cachedVocabulary = getDefaultVocabulary();\n cachedPath = vocabPath;\n return cachedVocabulary;\n }\n\n try {\n const content = await readFile(vocabPath, 'utf-8');\n\n const effects = parseEffectKeywords(content);\n const typeOverrides = parseTypeOverrides(content);\n const domainDefaults = parseDomainDefaults(content);\n\n // Use defaults if parsing failed\n if (effects.size === 0) {\n console.warn('No vocabulary parsed, using defaults');\n cachedVocabulary = getDefaultVocabulary();\n } else {\n cachedVocabulary = { effects, typeOverrides, domainDefaults };\n }\n\n cachedPath = vocabPath;\n return cachedVocabulary;\n } catch (error) {\n console.warn(`Error loading vocabulary from ${vocabPath}:`, error);\n cachedVocabulary = getDefaultVocabulary();\n cachedPath = vocabPath;\n return cachedVocabulary;\n }\n}\n\n/**\n * Resolve effect from keywords\n *\n * @param keywords - Keywords to look up\n * @param vocabulary - Vocabulary (will load if not provided)\n * @returns Most specific effect type found, or null\n */\nexport async function resolveEffectFromKeywords(\n keywords: string[],\n vocabulary?: Vocabulary\n): Promise<EffectType | null> {\n const vocab = vocabulary ?? (await loadVocabulary());\n\n // Normalize keywords\n const normalizedKeywords = keywords.map((k) => k.toLowerCase().trim());\n\n // Priority order: financial > destructive > soft_delete > standard > local > navigation > query\n const priorityOrder: EffectType[] = [\n 'financial',\n 'destructive',\n 'soft_delete',\n 'standard',\n 'local',\n 'navigation',\n 'query',\n 'high_freq',\n ];\n\n for (const effect of priorityOrder) {\n const entry = vocab.effects.get(effect);\n if (entry) {\n for (const keyword of normalizedKeywords) {\n if (entry.keywords.includes(keyword)) {\n return effect;\n }\n }\n }\n }\n\n // Check type overrides\n for (const keyword of normalizedKeywords) {\n const override = vocab.typeOverrides.get(keyword);\n if (override) {\n return override;\n }\n }\n\n // Check domain defaults\n for (const keyword of normalizedKeywords) {\n const domainDefault = vocab.domainDefaults.get(keyword);\n if (domainDefault) {\n return domainDefault;\n }\n }\n\n return null;\n}\n\n/**\n * Clear vocabulary cache (for testing)\n */\nexport function clearVocabularyCache(): void {\n cachedVocabulary = null;\n cachedPath = null;\n}\n\n/**\n * Check if vocabulary is cached\n */\nexport function isVocabularyCached(): boolean {\n return cachedVocabulary !== null;\n}\n","/**\n * GroundingGate - Validate agent grounding statements\n *\n * Parses agent output for grounding statements and validates them\n * against Sigil physics rules.\n */\n\nimport { loadPhysics } from './physics-loader.js';\nimport { loadVocabulary, resolveEffectFromKeywords } from './vocabulary-loader.js';\nimport { ZONE_HIERARCHY } from '../types.js';\nimport type { Zone, WardenResult, CheckResult } from '../types.js';\nimport type {\n GroundingStatement,\n PhysicsTable,\n Vocabulary,\n EffectType,\n SyncStrategy,\n ConfirmationType,\n} from './types.js';\n\n/** Zone to effect type mapping */\nconst ZONE_TO_EFFECT: Record<Zone, EffectType> = {\n critical: 'financial',\n elevated: 'destructive',\n standard: 'standard',\n local: 'local',\n};\n\n/** Effect type to zone mapping */\nconst EFFECT_TO_ZONE: Record<EffectType, Zone> = {\n financial: 'critical',\n destructive: 'elevated',\n soft_delete: 'standard',\n standard: 'standard',\n navigation: 'local',\n query: 'local',\n local: 'local',\n high_freq: 'local',\n};\n\n/**\n * Parse zone from string\n */\nfunction parseZone(value: string): Zone | null {\n const normalized = value.toLowerCase().trim();\n if (normalized === 'critical') return 'critical';\n if (normalized === 'elevated') return 'elevated';\n if (normalized === 'standard') return 'standard';\n if (normalized === 'local') return 'local';\n return null;\n}\n\n/**\n * Parse sync strategy from string\n */\nfunction parseSyncStrategy(value: string): SyncStrategy | undefined {\n const normalized = value.toLowerCase().trim();\n if (normalized.includes('pessimistic')) return 'pessimistic';\n if (normalized.includes('optimistic')) return 'optimistic';\n if (normalized.includes('immediate')) return 'immediate';\n return undefined;\n}\n\n/**\n * Parse timing from string\n */\nfunction parseTiming(value: string): number | undefined {\n const match = value.match(/(\\d+)\\s*ms/i);\n if (match && match[1]) {\n return parseInt(match[1], 10);\n }\n return undefined;\n}\n\n/**\n * Parse confirmation from string\n */\nfunction parseConfirmation(value: string): ConfirmationType | undefined {\n const normalized = value.toLowerCase().trim();\n if (normalized.includes('required') || normalized === 'yes') return 'required';\n if (normalized.includes('toast') || normalized.includes('undo')) return 'toast_undo';\n if (normalized.includes('none') || normalized === 'no') return 'none';\n return undefined;\n}\n\n/**\n * Extract keywords from text\n * Note: Only extracts action keywords, not zone/effect labels from structured fields\n */\nfunction extractKeywords(text: string): string[] {\n // Remove structured field labels to avoid false positives\n // e.g., \"Zone: standard\" should not detect \"standard\" as an action keyword\n const cleanedText = text\n .replace(/Zone:\\s*\\w+/gi, '')\n .replace(/Effect:\\s*[\\w\\s]+/gi, '')\n .replace(/Sync:\\s*\\w+/gi, '')\n .replace(/Confirmation:\\s*[\\w\\s+]+/gi, '');\n\n // Common keywords to look for\n const keywordPatterns = [\n // Financial\n 'claim', 'deposit', 'withdraw', 'transfer', 'swap', 'send', 'pay', 'purchase',\n 'mint', 'burn', 'stake', 'unstake', 'bridge', 'approve', 'redeem', 'harvest',\n // Destructive\n 'delete', 'remove', 'destroy', 'revoke', 'terminate', 'purge', 'erase', 'wipe',\n // Soft delete\n 'archive', 'hide', 'trash', 'dismiss', 'snooze', 'mute',\n // Standard\n 'save', 'update', 'edit', 'create', 'add', 'like', 'follow', 'bookmark',\n // Local\n 'toggle', 'switch', 'expand', 'collapse', 'select', 'focus',\n // Navigation\n 'navigate', 'go', 'back', 'forward', 'link', 'route',\n // Query\n 'fetch', 'load', 'get', 'list', 'search', 'find',\n // Domain/type hints\n 'wallet', 'token', 'nft', 'contract', 'chain', 'gas',\n 'currency', 'money', 'amount', 'balance', 'price', 'fee',\n // Effect type names (for inline detection in prose)\n 'financial', 'destructive',\n ];\n\n const words = cleanedText.toLowerCase().split(/[\\s,.:;!?()\\[\\]{}]+/);\n const foundKeywords: string[] = [];\n\n for (const word of words) {\n if (keywordPatterns.includes(word)) {\n foundKeywords.push(word);\n }\n }\n\n return [...new Set(foundKeywords)];\n}\n\n/**\n * Parse grounding statement from text\n *\n * Looks for patterns like:\n * - \"Zone: critical\"\n * - \"Effect: Financial\"\n * - \"Sync: pessimistic\"\n * - \"Timing: 800ms\"\n * - Physics analysis boxes\n */\nexport function parseGroundingStatement(text: string): GroundingStatement {\n const statement: GroundingStatement = {\n component: '',\n citedZone: null,\n detectedKeywords: [],\n inferredEffect: null,\n claimedPhysics: {},\n raw: text,\n };\n\n // Extract component name\n // Handle analysis box format with trailing whitespace and box characters\n const componentMatch = text.match(/(?:Component|Button|Modal|Form|Dialog):\\s*[\"']?([^\\s\"'│|]+)/i);\n if (componentMatch && componentMatch[1]) {\n statement.component = componentMatch[1].trim();\n } else {\n // Try to find component name from context\n const buttonMatch = text.match(/[\"']?(\\w+(?:Button|Modal|Form|Dialog|Card|Input))[\"']?/);\n if (buttonMatch && buttonMatch[1]) {\n statement.component = buttonMatch[1];\n }\n }\n\n // Extract zone\n const zoneMatch = text.match(/Zone:\\s*(\\w+)/i);\n if (zoneMatch && zoneMatch[1]) {\n statement.citedZone = parseZone(zoneMatch[1]);\n }\n\n // Extract effect\n const effectMatch = text.match(/Effect:\\s*(\\w+(?:\\s+\\w+)?)/i);\n if (effectMatch && effectMatch[1]) {\n const effectStr = effectMatch[1].toLowerCase();\n if (effectStr.includes('financial')) statement.inferredEffect = 'financial';\n else if (effectStr.includes('destructive')) statement.inferredEffect = 'destructive';\n else if (effectStr.includes('soft')) statement.inferredEffect = 'soft_delete';\n else if (effectStr.includes('standard')) statement.inferredEffect = 'standard';\n else if (effectStr.includes('local')) statement.inferredEffect = 'local';\n else if (effectStr.includes('navigation')) statement.inferredEffect = 'navigation';\n else if (effectStr.includes('query')) statement.inferredEffect = 'query';\n }\n\n // Extract sync strategy\n const syncMatch = text.match(/Sync:\\s*(\\w+)/i);\n if (syncMatch && syncMatch[1]) {\n const parsed = parseSyncStrategy(syncMatch[1]);\n if (parsed) statement.claimedPhysics.sync = parsed;\n } else {\n // Look for inline mentions\n if (text.toLowerCase().includes('pessimistic')) {\n statement.claimedPhysics.sync = 'pessimistic';\n } else if (text.toLowerCase().includes('optimistic')) {\n statement.claimedPhysics.sync = 'optimistic';\n } else if (text.toLowerCase().includes('immediate')) {\n statement.claimedPhysics.sync = 'immediate';\n }\n }\n\n // Extract timing\n const timingMatch = text.match(/Timing:\\s*(\\d+\\s*ms)/i);\n if (timingMatch && timingMatch[1]) {\n const parsed = parseTiming(timingMatch[1]);\n if (parsed !== undefined) statement.claimedPhysics.timing = parsed;\n } else {\n // Look for inline timing\n const inlineTiming = text.match(/(\\d+)\\s*ms/);\n if (inlineTiming && inlineTiming[1]) {\n statement.claimedPhysics.timing = parseInt(inlineTiming[1], 10);\n }\n }\n\n // Extract confirmation\n const confirmMatch = text.match(/Confirm(?:ation)?:\\s*(\\w+(?:\\s*\\+\\s*\\w+)?)/i);\n if (confirmMatch && confirmMatch[1]) {\n const parsed = parseConfirmation(confirmMatch[1]);\n if (parsed) statement.claimedPhysics.confirmation = parsed;\n } else {\n // Look for inline mentions\n if (text.toLowerCase().includes('confirmation required')) {\n statement.claimedPhysics.confirmation = 'required';\n } else if (text.toLowerCase().includes('toast') && text.toLowerCase().includes('undo')) {\n statement.claimedPhysics.confirmation = 'toast_undo';\n }\n }\n\n // Extract keywords\n statement.detectedKeywords = extractKeywords(text);\n\n return statement;\n}\n\n/**\n * Determine required zone based on keywords and effect\n */\nfunction determineRequiredZone(\n keywords: string[],\n effect: EffectType | null,\n vocabulary: Vocabulary\n): Zone {\n // If we have an explicit effect, use its zone\n if (effect) {\n return EFFECT_TO_ZONE[effect];\n }\n\n // Check for type overrides (highest priority)\n for (const keyword of keywords) {\n const override = vocabulary.typeOverrides.get(keyword.toLowerCase());\n if (override) {\n return EFFECT_TO_ZONE[override];\n }\n }\n\n // Check for financial keywords (critical zone)\n const financialKeywords = vocabulary.effects.get('financial')?.keywords ?? [];\n for (const keyword of keywords) {\n if (financialKeywords.includes(keyword.toLowerCase())) {\n return 'critical';\n }\n }\n\n // Check for destructive keywords (elevated zone)\n const destructiveKeywords = vocabulary.effects.get('destructive')?.keywords ?? [];\n for (const keyword of keywords) {\n if (destructiveKeywords.includes(keyword.toLowerCase())) {\n return 'elevated';\n }\n }\n\n // Default to standard\n return 'standard';\n}\n\n/**\n * Check keyword relevance\n */\nfunction checkRelevance(\n statement: GroundingStatement,\n vocabulary: Vocabulary\n): CheckResult {\n const { detectedKeywords, component } = statement;\n\n // If no keywords detected, check if component name contains hints\n if (detectedKeywords.length === 0) {\n const componentLower = component.toLowerCase();\n const allKeywords: string[] = [];\n\n for (const entry of vocabulary.effects.values()) {\n allKeywords.push(...entry.keywords);\n }\n\n const hasRelevantComponent = allKeywords.some((k) => componentLower.includes(k));\n\n if (!hasRelevantComponent) {\n return {\n passed: false,\n reason: 'No relevant keywords detected in statement or component name',\n };\n }\n }\n\n return {\n passed: true,\n reason: `Keywords detected: ${detectedKeywords.join(', ') || 'from component name'}`,\n };\n}\n\n/**\n * Check zone hierarchy compliance\n */\nfunction checkHierarchy(\n statement: GroundingStatement,\n requiredZone: Zone\n): CheckResult {\n const { citedZone } = statement;\n\n if (!citedZone) {\n return {\n passed: false,\n reason: 'No zone cited in statement',\n };\n }\n\n const requiredIndex = ZONE_HIERARCHY.indexOf(requiredZone);\n const citedIndex = ZONE_HIERARCHY.indexOf(citedZone);\n\n // Cited zone must be at least as restrictive as required\n // Lower index = more restrictive (critical=0, local=3)\n if (citedIndex > requiredIndex) {\n return {\n passed: false,\n reason: `Zone \"${citedZone}\" is less restrictive than required \"${requiredZone}\"`,\n };\n }\n\n if (citedIndex < requiredIndex) {\n return {\n passed: true,\n reason: `Zone \"${citedZone}\" is more restrictive than required \"${requiredZone}\" (OK)`,\n };\n }\n\n return {\n passed: true,\n reason: `Zone \"${citedZone}\" matches required zone`,\n };\n}\n\n/**\n * Check physics rules compliance\n */\nasync function checkRules(\n statement: GroundingStatement,\n requiredZone: Zone,\n physics: PhysicsTable\n): Promise<CheckResult> {\n const { claimedPhysics } = statement;\n const requiredEffect = ZONE_TO_EFFECT[requiredZone];\n const rule = physics.get(requiredEffect);\n\n if (!rule) {\n return {\n passed: false,\n reason: `No physics rule found for effect \"${requiredEffect}\"`,\n };\n }\n\n const violations: string[] = [];\n\n // Check sync strategy\n if (claimedPhysics.sync && claimedPhysics.sync !== rule.sync) {\n // Pessimistic is always acceptable for lower zones\n if (claimedPhysics.sync !== 'pessimistic') {\n violations.push(`Sync: claimed \"${claimedPhysics.sync}\", required \"${rule.sync}\"`);\n }\n }\n\n // Check timing (allow some tolerance)\n if (claimedPhysics.timing !== undefined) {\n const timingDiff = Math.abs(claimedPhysics.timing - rule.timing);\n // Allow 100ms tolerance for deliberate adjustments\n if (timingDiff > 100 && claimedPhysics.timing < rule.timing) {\n violations.push(\n `Timing: claimed ${claimedPhysics.timing}ms, required minimum ${rule.timing}ms`\n );\n }\n }\n\n // Check confirmation\n if (claimedPhysics.confirmation) {\n // \"required\" is always acceptable\n if (\n rule.confirmation === 'required' &&\n claimedPhysics.confirmation !== 'required'\n ) {\n violations.push(\n `Confirmation: claimed \"${claimedPhysics.confirmation}\", required \"${rule.confirmation}\"`\n );\n }\n }\n\n if (violations.length > 0) {\n return {\n passed: false,\n reason: violations.join('; '),\n };\n }\n\n return {\n passed: true,\n reason: 'Physics rules validated',\n };\n}\n\n/**\n * Validate a grounding statement\n *\n * @param input - Raw text or parsed statement\n * @param options - Validation options\n * @returns Warden validation result\n */\nexport async function validateGrounding(\n input: string | GroundingStatement,\n options?: {\n physicsPath?: string;\n vocabularyPath?: string;\n }\n): Promise<WardenResult> {\n // Load physics and vocabulary\n const physics = await loadPhysics(options?.physicsPath);\n const vocabulary = await loadVocabulary(options?.vocabularyPath);\n\n // Parse statement if string\n const statement =\n typeof input === 'string' ? parseGroundingStatement(input) : input;\n\n // Resolve effect from keywords if not already set\n if (!statement.inferredEffect && statement.detectedKeywords.length > 0) {\n statement.inferredEffect = await resolveEffectFromKeywords(\n statement.detectedKeywords,\n vocabulary\n );\n }\n\n // Determine required zone\n const requiredZone = determineRequiredZone(\n statement.detectedKeywords,\n statement.inferredEffect,\n vocabulary\n );\n\n // Run validation checks\n const relevanceCheck = checkRelevance(statement, vocabulary);\n const hierarchyCheck = checkHierarchy(statement, requiredZone);\n const rulesCheck = await checkRules(statement, requiredZone, physics);\n\n // Determine overall status\n let status: WardenResult['status'] = 'VALID';\n let correction: string | undefined;\n\n if (!relevanceCheck.passed) {\n status = 'DRIFT';\n correction = 'Statement lacks relevant keywords for effect detection.';\n } else if (!hierarchyCheck.passed) {\n status = 'DECEPTIVE';\n correction = `Zone mismatch: cited \"${statement.citedZone}\", required \"${requiredZone}\".`;\n } else if (!rulesCheck.passed) {\n status = 'DRIFT';\n correction = `Physics violation: ${rulesCheck.reason}`;\n }\n\n return {\n status,\n checks: {\n relevance: relevanceCheck,\n hierarchy: hierarchyCheck,\n rules: rulesCheck,\n },\n requiredZone,\n citedZone: statement.citedZone,\n ...(correction !== undefined && { correction }),\n };\n}\n\n/**\n * Quick validation check - returns true if valid\n */\nexport async function isGroundingValid(\n input: string | GroundingStatement,\n options?: {\n physicsPath?: string;\n vocabularyPath?: string;\n }\n): Promise<boolean> {\n const result = await validateGrounding(input, options);\n return result.status === 'VALID';\n}\n\n/**\n * Get exit code for validation result\n */\nexport function getExitCode(result: WardenResult): number {\n switch (result.status) {\n case 'VALID':\n return 0; // PASS\n case 'DRIFT':\n return 1; // DRIFT\n case 'DECEPTIVE':\n return 2; // DECEPTIVE\n default:\n return 3; // VIOLATION\n }\n}\n","/**\n * Anchor v4.3.1 - Ground Truth Enforcement\n *\n * Sigil marks intent. Anchor grounds it, enforces it, and catches every lie.\n */\n\n// Lifecycle\nexport {\n ForkManager,\n getForkManager,\n resetForkManager,\n SnapshotManager,\n getSnapshotManager,\n resetSnapshotManager,\n CheckpointManager,\n getCheckpointManager,\n resetCheckpointManager,\n SessionManager,\n getSessionManager,\n resetSessionManager,\n type Session,\n type SessionMetadata,\n type SessionManagerConfig,\n} from './lifecycle/index.js';\n\n// Graph\nexport { TaskGraph, generateTaskId, resetTaskCounter } from './graph/index.js';\n\n// Warden\nexport {\n loadPhysics,\n getPhysicsRule,\n getDefaultPhysics,\n clearPhysicsCache,\n isPhysicsCached,\n loadVocabulary,\n resolveEffectFromKeywords,\n getDefaultVocabulary,\n clearVocabularyCache,\n isVocabularyCached,\n parseGroundingStatement,\n validateGrounding,\n isGroundingValid,\n getExitCode,\n type SyncStrategy,\n type ConfirmationType,\n type EffectType,\n type PhysicsRule,\n type PhysicsTable,\n type VocabularyEntry,\n type Vocabulary,\n type GroundingStatement,\n type CheckName,\n type ExtendedCheckResult,\n type ValidationContext,\n} from './warden/index.js';\n\n// Utils\nexport {\n rpcCall,\n RpcError,\n RpcTimeoutError,\n isRpcReady,\n waitForRpc,\n} from './utils/index.js';\n\n// Types\nexport type {\n Fork,\n ForkConfig,\n ForkRegistry,\n NetworkConfig,\n SnapshotMetadata,\n SnapshotConfig,\n CheckpointMetadata,\n CheckpointConfig,\n Task,\n TaskType,\n TaskStatus,\n TaskGraphData,\n Zone,\n WardenInput,\n WardenResult,\n CheckResult,\n ExitCodeValue,\n} from './types.js';\n\nexport { ForkSchema, ForkRegistrySchema, ZONE_HIERARCHY, ExitCode } from './types.js';\n\n// Version\nexport const VERSION = '4.3.1';\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@thehoneyjar/sigil-anchor",
|
|
3
|
+
"version": "4.3.1",
|
|
4
|
+
"description": "Ground truth enforcement layer for Sigil - validates AI-generated code against design physics",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"bin": {
|
|
10
|
+
"anchor": "./dist/cli/index.js"
|
|
11
|
+
},
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"import": "./dist/index.js",
|
|
15
|
+
"types": "./dist/index.d.ts"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist"
|
|
20
|
+
],
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"commander": "^12.1.0",
|
|
23
|
+
"eventemitter3": "^5.0.4",
|
|
24
|
+
"zod": "^3.25.76"
|
|
25
|
+
},
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"@types/node": "^20.11.0",
|
|
28
|
+
"@typescript-eslint/eslint-plugin": "^6.19.0",
|
|
29
|
+
"@typescript-eslint/parser": "^6.19.0",
|
|
30
|
+
"eslint": "^8.56.0",
|
|
31
|
+
"prettier": "^3.2.4",
|
|
32
|
+
"tsup": "^8.0.1",
|
|
33
|
+
"typescript": "^5.3.3",
|
|
34
|
+
"vitest": "^1.2.0"
|
|
35
|
+
},
|
|
36
|
+
"engines": {
|
|
37
|
+
"node": ">=20.0.0"
|
|
38
|
+
},
|
|
39
|
+
"keywords": [
|
|
40
|
+
"sigil",
|
|
41
|
+
"anchor",
|
|
42
|
+
"ai",
|
|
43
|
+
"validation",
|
|
44
|
+
"design-physics",
|
|
45
|
+
"web3"
|
|
46
|
+
],
|
|
47
|
+
"author": "Sigil Framework",
|
|
48
|
+
"license": "MIT",
|
|
49
|
+
"publishConfig": {
|
|
50
|
+
"access": "public",
|
|
51
|
+
"registry": "https://registry.npmjs.org/"
|
|
52
|
+
},
|
|
53
|
+
"repository": {
|
|
54
|
+
"type": "git",
|
|
55
|
+
"url": "https://github.com/0xHoneyJar/sigil.git",
|
|
56
|
+
"directory": "packages/anchor"
|
|
57
|
+
},
|
|
58
|
+
"bugs": {
|
|
59
|
+
"url": "https://github.com/0xHoneyJar/sigil/issues"
|
|
60
|
+
},
|
|
61
|
+
"homepage": "https://github.com/0xHoneyJar/sigil/tree/main/packages/anchor#readme",
|
|
62
|
+
"scripts": {
|
|
63
|
+
"build": "tsup",
|
|
64
|
+
"dev": "tsup --watch",
|
|
65
|
+
"test": "vitest",
|
|
66
|
+
"test:run": "vitest run",
|
|
67
|
+
"lint": "eslint src --ext .ts",
|
|
68
|
+
"lint:fix": "eslint src --ext .ts --fix",
|
|
69
|
+
"format": "prettier --write src",
|
|
70
|
+
"typecheck": "tsc --noEmit"
|
|
71
|
+
}
|
|
72
|
+
}
|