/** * SimulationContract — Enforced runtime guarantees for scientifically reliable simulation. * * What makes HoloScript different: the render model and the solver model are * the SAME object. This contract enforces that guarantee at runtime. * * ## Guarantees * * 1. **Geometry integrity**: Solver mesh hash === render mesh hash. No mismatch. * 2. **Unit validation**: All physical quantities carry validated units. No raw numbers. * 3. **Deterministic stepping**: Fixed timestep accumulator. Same input → same output always. * 4. **Interaction provenance**: Every user action that affects solver state is logged. * 5. **Auto-provenance**: Every solve() automatically records config + results + timing. * 6. **Replay**: Any simulation can be exactly reproduced from its provenance record. * * ## Usage * * Wrap any SimSolver in a ContractedSimulation to get all guarantees: * * const contracted = new ContractedSimulation(solver, config); * contracted.step(dt); // deterministic, logged * contracted.logInteraction('user_moved_load', { position: [25, 0, 0] }); * const provenance = contracted.getProvenance(); // full record * const replay = contracted.createReplay(); // reproducible */ import type { SimSolver, FieldData } from './SimSolver'; import { type HashMode } from './sha256'; import { type SubgridAttestation, type SubgridParams } from '@holoscript/core/paper-0c-spike'; import type { ParameterEnvelope, EnvelopeCheckResult } from '@holoscript/core/parameter-envelope'; export { hashCAELEntry, computeStateDigest, hashGeometry, hashGpuOutput, quantumForField, } from './hashes'; export type { HashMode } from './sha256'; export type { SubgridAttestation, SubgridParams } from '@holoscript/core/paper-0c-spike'; export type { ParameterEnvelope, ParameterEnvelopeRecord, EnvelopeViolationAction, EnvelopeViolation, EnvelopeCheckResult, } from '@holoscript/core/parameter-envelope'; export type ParameterEnvelopeInheritanceStatus = 'inside' | 'inside-with-warnings' | 'redischarge-required' | 'outside' | 'no-envelope' | 'source-unverified'; export interface ParameterEnvelopeProofSource { parameterEnvelope?: ParameterEnvelope; envelopeCheck?: EnvelopeCheckResult; verified?: boolean; } export interface ParameterEnvelopeInheritanceResult { status: ParameterEnvelopeInheritanceStatus; insideProof: boolean; requiresRedischarge: boolean; envelopeCheck?: EnvelopeCheckResult; diagnostics: string[]; } /** * Simulation scale taxonomy — the physical regime a solver operates in. * * Per W.QDA.001 (Query-Driven Abstraction): the right level of abstraction * is determined by the user's question, not by the substrate. Scale tagging * makes this routing explicit — Brittney dispatches to the tier the query * demands, and the acceptance envelope at that tier determines whether the * result is trustworthy. * * Short aliases (for serialization and UI): * quantum → 'qm' — Hartree-Fock, DFT, post-HF (Psi4, QE) * atomistic → 'md' — molecular dynamics (LAMMPS, GROMACS) * mesoscopic → 'meso' — coarse-grained, dissipative particle dynamics * continuum → 'continuum' — FEM, FVM, FDTD, Navier-Stokes, structural * empirical-surrogate → 'system' — learned surrogates, system-level models * * Source: research/2026-04-28_qm-as-foundational-layer-EVOLVED.md §7.2 */ export type SimulationScale = 'quantum' | 'atomistic' | 'mesoscopic' | 'continuum' | 'empirical-surrogate'; /** Short-alias map for serialization / UI. Maps canonical name → short tag. */ export declare const SCALE_ALIASES: Record; /** Reverse map: short tag → canonical name. */ export declare const SCALE_FROM_ALIAS: Record; /** * Per-scale acceptance envelope. * * Defines tolerance bounds, replay rules, and V&V criteria that are * scale-specific. Different physical regimes have fundamentally different * notions of "good enough" — quantum convergence tolerances (10⁻⁶ Hartree) * are meaningless for continuum FEM (where 1% strain error is excellent). * * Cross-tier replay (W.GOLD.189 Layer 3 extension): when two CAEL records * are produced at different scales, `acceptsCrossScale` projects both to * the coarsest common scale before applying the envelope. Under commutative * regimes (π_scale and C_q commute), ε_total = max(ε_field, ε_scale). * Non-commutative regimes return false with a diagnostic. * * Source: research/2026-04-28_qm-as-foundational-layer-EVOLVED.md §7.2, §8.1 */ export interface ScaleEnvelope { /** The scale this envelope applies to. */ scale: SimulationScale; /** * Relative tolerance for field-level acceptance. * Quantum: ~1e-6 (Hartree), atomistic: ~1e-4, continuum: ~1e-2, etc. */ tolerance: number; /** * Whether cross-scale replay is allowed for this scale. * False for scales where projection is non-commutative (e.g. plasma * kinetic-fluid coupling per EVOLVED §1.4). */ replayAllowed: boolean; /** * V&V criteria applicable at this scale. * Keys are criterion names (e.g. 'convergence', 'energy_drift', 'grid_convergence_index'); * values are scale-specific thresholds. */ vvCriteria: Record; /** * Coarser scales this scale can project to via π_scale. * Maps target scale → projection description (e.g. "averaging over MD cells"). * Empty object if this scale has no coarser projections (only 'quantum' can * project to all others; 'empirical-surrogate' projects to nothing). */ projectionsTo: Partial>; } /** * Default acceptance envelopes per scale. * * These are conservative defaults — individual contracts can override * via ContractConfig.scaleEnvelope. */ export declare const DEFAULT_SCALE_ENVELOPES: Record; /** * Cross-scale acceptance check. * * Per EVOLVED §8.1: two CAEL records produced by different solvers at * different scales are adjudicated by projecting both to the coarsest * common scale that both branches' observables admit, then applying the * per-field acceptance envelope at that scale. * * Under commutative regimes (where π_scale and C_q commute), the cross-tier * acceptance envelope composes as ε_total = max(ε_field, ε_scale). * Non-commutative regimes return `false` with a diagnostic. * * @param sourceScale The scale the solver operates at * @param targetScale The scale to project to * @param fieldTolerance Per-field tolerance (ε_field) * @returns Object with `accepted` boolean and optional `diagnostic` message */ export declare function acceptsCrossScale(sourceScale: SimulationScale, targetScale: SimulationScale, fieldTolerance: number): { accepted: boolean; diagnostic?: string; }; /** * Scale ordering for determining coarsest common scale in cross-tier replay. * Lower number = finer scale; higher = coarser. * Used to find the coarsest common scale for W.GOLD.189 cross-tier replay. */ export declare const SCALE_ORDER: Record; /** * Find the coarsest common scale between two scales. * Per EVOLVED §8.1 and W.GOLD.189 extension: project both branches' * observables to the coarsest common scale before applying the acceptance * envelope. */ export declare function coarsestCommonScale(a: SimulationScale, b: SimulationScale): SimulationScale; /** * A dense latent vector produced by a JEPA-style world model predictor. * * In the JEPA (Joint Embedding Predictive Architecture) formulation, the * predictor maps an observed physics state to a latent-space prediction of * a future or alternative state. `LatentVector` carries that prediction * along with its embedding context so downstream consumers can compute * prediction error in latent space without needing the raw field tensors. * * `WorldModelReceipt` (below) can pair this value with a solver-produced * reference state. The type alone does not establish that a trained model, * a particular encoder, or an external verifier was used. * * Paper 26 seed — "Verifiable World Models via Simulation Contracts". */ export interface LatentVector { /** Flat embedding values (e.g. output of a learned encoder). */ values: Float32Array; /** Dimensionality of the latent space (length of `values`). */ dim: number; /** * Identifier for the model/encoder that produced this vector, * e.g. "jepa-continuum-v1". Enables cross-model comparison. */ encoderId: string; /** * Simulation time (s) this vector was predicted for. * Matches `PhysicsState.simTime` in the paired receipt. */ simTime: number; } /** * A snapshot of solver-produced physical state at a fixed simulation time. * * Produced by `ContractedSimulation` after `solve()` or `step()` completes. * Contains the raw field values the solver actually computed. A * `WorldModelReceipt` treats this as its in-simulation reference state; the * type does not independently prove physical correctness. */ export interface PhysicsState { /** Simulation time (s) this state corresponds to. */ simTime: number; /** * Named scalar fields at this timestep, e.g. * { displacement: Float32Array, vonMisesStress: Float32Array }. * Keys are solver-specific field names from `SimSolver.fieldNames`. */ fields: Record; /** Geometry hash of the mesh that produced these fields. Ties state to geometry. */ geometryHash: string; /** The contract's own run identifier for traceability. */ contractId: string; /** Solver type that produced this state. */ solverType: string; } /** * A closed real interval [lo, hi]. The current WorldModelReceipt generator * emits an uncalibrated numerical envelope, not a probabilistic confidence * interval. `coverage` is reserved for independently calibrated callers. */ export interface Interval { /** Lower bound (inclusive). */ lo: number; /** Upper bound (inclusive). */ hi: number; /** Machine-readable semantics for the interval. */ kind?: 'uncalibrated-numerical-envelope' | 'calibrated-confidence-interval'; /** Probability level, present only for a calibrated confidence interval. */ coverage?: number; } /** * WorldModelReceipt — a hashed comparison record between a latent prediction * (or the generator's zero-vector baseline) and a solver-produced reference * state. * * ## Why this matters * * World models can make predictions in latent space. This record places a * prediction and a solver result next to their measured latent-space error: * * 1. A caller-supplied predictor produces `jepa_prediction`, or the generator * emits a zero-vector baseline when no predictor is supplied. * 2. `ContractedSimulation` captures the solver-produced field values in * `solver_ground_truth`. * 3. `delta_error` is the L2 norm between the prediction and the ground truth * projected back to the same embedding space. * 4. The legacy-named `confidence_bound` records an uncalibrated numerical * envelope; it does not attach a probability to the error. * 5. A compact canonical projection is hashed using the contract's declared * mode. FNV-1a is the default and is non-cryptographic; SHA-256 is opt-in. * * The current hash commits to prediction metadata/values, error metadata, and * solver field names and lengths, but not the raw solver field values. A hash * detects changes only within that projection. It does not authenticate the * producer, verify the solver, prove model quality, or establish that an * external/on-chain anchor exists. * * Paper 26 seed — "Verifiable World Models via Simulation Contracts". * TVCG scope boundary: above the submitted "Trust by Construction" paper * (external review 2026-05-17). Implementation ships now; Paper 26 scoping * requires founder review. */ export interface WorldModelReceipt { /** * Latent prediction in the legacy `jepa_prediction` field. This can be a * caller-supplied model output or the generator's zero-vector baseline; see * `predictionKind`. */ jepa_prediction: LatentVector; /** Solver-produced reference state for the same simulation point. */ solver_ground_truth: PhysicsState; /** * Prediction error: L2 distance between `jepa_prediction.values` and the * ground-truth projection in the same embedding space. * * Computed as ‖encode(solver_ground_truth) − jepa_prediction.values‖₂. * Compatibility of the caller-supplied encoder and predictor is * caller-declared; the generator enforces only non-empty labels, finite * values, equal dimensions, and matching simulation time. * * A value of 0.0 indicates numeric equality between the two supplied vectors, * not model correctness. Higher values indicate vector divergence. The scale * is caller-declared and embedding-space-relative. */ delta_error: number; /** * Legacy-named interval around `delta_error`. The current generator emits an * `uncalibrated-numerical-envelope` derived from a fixed quantization term * and the contract tolerance. It carries no probability or coverage claim. */ confidence_bound: Interval; /** * How `jepa_prediction` was obtained. The current generator always emits * this field; it is optional only so older serialized receipts remain * assignable to this interface. */ predictionKind?: 'zero-baseline' | 'caller-supplied'; /** * Unique receipt ID — `wmr--`. * Stable across re-serializations of the same run. */ receiptId: string; /** ISO-8601 timestamp when this receipt was generated. */ issuedAt: string; /** * Hash of the generator's compact canonical projection (excluding * `receiptHash`). Solver fields are represented by name and length, not raw * values. The hash can be supplied to an external anchor, but this object is * not evidence that anchoring occurred. */ receiptHash: string; /** * Hash mode used to produce `receiptHash`. `fnv1a` is the default, * non-cryptographic integrity checksum; `sha256` is opt-in. */ hashMode: 'fnv1a' | 'sha256'; /** * Contract ID of the `ContractedSimulation` that issued this receipt. * Ties the receipt to a specific geometry + solver configuration. */ contractId: string; } export interface InteractionEvent { /** Monotonic event ID */ id: number; /** Wall-clock timestamp */ timestamp: number; /** Simulation time when this interaction occurred */ simTime: number; /** Type of interaction */ type: string; /** Interaction payload (position change, load update, etc.) */ data: Record; } export interface SimulationProvenance { /** Unique run ID */ runId: string; /** Geometry hash (SHA-like fingerprint of vertex + connectivity data) */ geometryHash: string; /** Composite Contract-ID — `geometryHash` plus, when present, the * adapter fingerprint and the subgrid-parameter attestation hash * folded in deterministically. Backward-compat: when neither * `adapterFingerprint` nor `subgridParams` is set on the contract, * `contractId === geometryHash` byte-identically. */ contractId: string; /** Subgrid-parameter attestation envelope (paper-0c CAEL). Present * iff `ContractConfig.subgridParams` was provided at construction. * The envelope's `hash` is folded into `contractId`; the full envelope * (canonical form + hash + mode) is recorded by CAELRecorder into * `cael.init.payload.subgridAttestation` for replay-side verification. */ subgridAttestation?: SubgridAttestation; /** Solver type identifier */ solverType: string; /** Simulation scale (physical regime). Defaults to 'continuum'. */ scale: SimulationScale; /** Per-scale acceptance envelope applied during this run. */ scaleEnvelope: ScaleEnvelope; /** Full solver config (frozen at creation time) */ config: Record; /** Fixed timestep used */ fixedDt: number; /** Total steps executed */ totalSteps: number; /** Total simulation time */ totalSimTime: number; /** Wall-clock solve duration (ms) */ wallTimeMs: number; /** All user interactions during this simulation */ interactions: InteractionEvent[]; /** Final solver stats */ finalStats: Record; /** Contract violations found at construction time, including CAEL reason codes when available. */ contractViolations?: ContractViolation[]; /** Runtime V&V criteria measurements and violations from the scale envelope. */ vvReport?: VVReport; /** Semantic-clause violations (precondition/invariant/postcondition) — the proof witness. */ clauseViolations?: ClauseViolation[]; /** True when no error-severity structural OR clause violations were found. */ verified?: boolean; /** Whether the simulation is deterministically reproducible */ deterministic: boolean; /** Platform version */ platformVersion: string; /** Creation timestamp */ createdAt: string; /** * Terminal state digest — the last entry of `getStateDigests()` at provenance * time (the converged/final canonicalized state). Present iff at least one * state digest was captured. This is the verifiable record of where this run * *ended*, and is what a continuation declares as its seed (see * `ReceiptContinuation.seedStateDigest`). Absent for runs that captured no * state digest (e.g. a grid solver with no step/solve digest path). */ terminalStateDigest?: string; /** * Final state digest — the continuation-chain-facing name for the same value * as {@link terminalStateDigest} (the last captured state digest). Receipt * chaining reads this field: it is the digest a successor run declares as its * seed (`ContinuationLink.seedStateDigest`) and what * {@link verifyContinuationChain} matches against. Present iff a state digest * was captured. */ finalStateDigest?: string; /** * Continuation link (receipt chaining): when set, this run was declared to * *continue from* a prior run, asserting that prior run's final state as this * run's seed. Verifiable from provenance records alone via * {@link verifyContinuationChain}. (The stricter receipt-hash-anchored variant * is {@link ReceiptContinuation} + {@link verifyContinuation}.) */ continuesFrom?: ContinuationLink; /** * Valid-parameter domain carried by this receipt. This is the reusable proof * envelope: adjusted/remixed configs can be checked against it without * trusting the original caller's local ContractConfig. */ parameterEnvelope?: ParameterEnvelope; /** * Parameter-envelope check result (H1 proof machinery). * Present iff `ContractConfig.parameterEnvelope` was declared at construction. * `passed: false` → at least one error-severity violation (would have thrown). * `redischarge: true` → the run is outside its proof space; re-proof required. */ envelopeCheck?: EnvelopeCheckResult; /** * Optional provenance-chain v2 receipt for the roundtable soul-owned gate. * Receipt values are measured by `buildProvenanceChainReceiptV2`. */ provenanceChainReceiptV2?: ProvenanceChainReceiptV2; } /** * A verifiable reference from one contracted run to a PRIOR verified receipt, * declaring that prior run's terminal state as this run's seed state. This is * the lineage primitive for semantic carry-over (PROB-003 / the HoloMesh * collaborative): week N's verified terminal state becomes week N+1's * cryptographically-declared starting point. * * Every field is checkable from records by {@link verifyContinuation} — forging * any one of them makes verification fail. This is distinct from the CAEL * append-order hash chain (`prevHash`), which only proves a trace's internal * ordering, not a semantic continuation across separate runs. * * NOTE (scope): this establishes a verifiable *lineage* — the prior terminal * state is provably the declared seed. Having the solver physically re-load * that terminal state as initial conditions is solver-specific and layered on * top; this primitive is the auditable link that layer relies on. */ export interface ReceiptContinuation { /** `receiptHash` of the prior verified receipt this run continues from. */ priorReceiptHash: string; /** `contractId` of the prior run (lineage identity). */ priorContractId: string; /** `runId` of the prior run. */ priorRunId: string; /** * The prior run's `terminalStateDigest`, asserted as this run's verified seed * state. `verifyContinuation` checks this equals the prior provenance's * recorded `terminalStateDigest` — that is what makes the carry-over semantic * rather than a bare pointer. */ seedStateDigest: string; } /** * Verify a semantic carry-over link from records alone (PROB-003). * * Returns `{ valid: true }` only when the continuation provably references the * prior run's verified terminal state: * - the prior run was contract-verified (`verified === true`), * - the declared `priorReceiptHash` matches the prior receipt's actual hash, * - the declared `priorContractId` / `priorRunId` match the prior provenance, * - the declared `seedStateDigest` matches the prior provenance's recorded * `terminalStateDigest` (which must exist). * * Any forged or mismatched field yields `{ valid: false, reason }`. This is the * falsifiable check the carry-over story rests on — it does not exist as * append-order chain integrity (`verifyCAELHashChain`), which is a different * guarantee. */ export declare function verifyContinuation(continuation: ReceiptContinuation, prior: { provenance: SimulationProvenance; receiptHash: string; }): { valid: boolean; reason?: string; }; /** * A provenance-level link from one contracted run to its immediate predecessor, * declaring the predecessor's final state as this run's seed. * * Unlike {@link ReceiptContinuation} (which additionally binds the prior * `receiptHash` and is verified against the prior receipt), a `ContinuationLink` * is verifiable from the two runs' provenance records ALONE. It is what * `ContractedSimulation` records in `SimulationProvenance.continuesFrom` * ({@link ContractedSimulation.getContinuationLink}) and what * {@link verifyContinuationChain} checks. Each field is captured from the * predecessor at link-creation time. */ export interface ContinuationLink { /** `runId` of the predecessor run this run continues from. */ fromRunId: string; /** `contractId` of the predecessor run (lineage identity). */ fromContractId: string; /** * The predecessor's `finalStateDigest`, asserted as this run's seed state. * {@link verifyContinuationChain} checks this equals the predecessor's recorded * `finalStateDigest` — that is what makes the carry-over semantic, not a bare * pointer. */ seedStateDigest: string; /** The predecessor's `totalSimTime` at link-creation (where the seed sits in sim time). */ fromSimTime: number; /** Whether the predecessor was contract-verified at link-creation. Drives `verifiedCarryOver`. */ fromVerified: boolean; } /** * Verify a continuation CHAIN from provenance records alone. * * Walks an ordered array of runs and checks each non-genesis run's * `continuesFrom` link against its immediate predecessor: * - the link must be present, * - `fromRunId` / `fromContractId` must match the predecessor's identity, * - `seedStateDigest` must match the predecessor's recorded `finalStateDigest` * (otherwise the carry-over is broken/forged). * * `valid` reports STRUCTURAL integrity (the chain links up, no digest forged). * `verifiedCarryOver` additionally reports whether EVERY link carried over from a * contract-verified predecessor (`fromVerified === true`) — a chain can be * structurally valid while carrying over from an unverified run. * * An empty or single-element chain is trivially `{ valid: true }`. `brokenAt` is * the index of the first run whose link fails; `diagnostic` explains why. This is * the multi-run counterpart to {@link verifyContinuation} (which checks one * receipt-hash-anchored link). */ export declare function verifyContinuationChain(provenances: readonly SimulationProvenance[]): { valid: boolean; verifiedCarryOver: boolean; brokenAt?: number; diagnostic?: string; }; export type ProvenanceVerifierTier = 'TIER-R' | 'TIER-L'; export type ProvenanceMeasurementSource = 'measured' | 'declared'; export type ProvenanceTheoremStatus = 'hypothesis' | 'measured'; export type VendorFingerprintProbe = 'probe_scored' | 'probe_unscored' | 'substrate_generator'; export interface ProvenanceMeasurement { value: T; source: ProvenanceMeasurementSource; evidence: readonly string[]; measuredAt: string; } export interface TierRVerifierEvidence { tier: 'TIER-R'; verifierId: string; ruleSetHash: string; ruleGrounded: boolean; scoredValueAxes: readonly string[]; totalValueAxes: readonly string[]; verdict: 'pass' | 'fail'; } export interface TierLVerifierEvidence { tier: 'TIER-L'; verifierId: string; modelId: string; loggedVerdict: 'pass' | 'fail' | 'inconclusive'; confidence: number; gatesSoulOwned?: boolean; } export interface VendorFingerprintResult { probe: VendorFingerprintProbe; classifierId: string; predictedClass: string; confidence: number; classConfidences: Readonly>; sampleCount: number; perExampleTags?: readonly string[]; measuredAt: string; } export interface PreferenceObservation { sampleId: string; measuredValueIndependence: number; heldOutPreference: number; } export interface CustodyEvidence { downloadable: boolean; localRunnable: boolean; nonRevocable: boolean; } export interface ContaminationObservation { generation: number; vendorFingerprintConfidence: number; } export interface Exp2ValueLeakFalsifierInput { probeScored: VendorFingerprintResult; probeUnscored: VendorFingerprintResult; substrateGenerator?: VendorFingerprintResult; preferenceArm: readonly PreferenceObservation[]; contaminationThreshold?: number; contaminationSeries?: readonly ContaminationObservation[]; } export interface Exp2ValueLeakFalsifierResult { experimentId: 'EXP-2'; theoremStatus: 'hypothesis'; valid: boolean; status: 'ready' | 'needs-preference-arm' | 'needs-substrate-generator'; probeScoredIndependence: number; probeUnscoredIndependence: number; unscoredMinusScoredDissociation: number; substrateGeneratorIndependence: number | null; preference_correlation: number | null; contaminationThreshold: number; contaminationHalfLifeGeneration: number | null; diagnostics: readonly string[]; } export interface ProvenanceChainReceiptV2Input { subject: { contractId?: string; runId?: string; provenanceHash?: string; }; custody: CustodyEvidence; tierR: TierRVerifierEvidence; tierL?: TierLVerifierEvidence; probeScored: VendorFingerprintResult; probeUnscored: VendorFingerprintResult; substrateGenerator?: VendorFingerprintResult; preferenceArm: readonly PreferenceObservation[]; hashMode?: HashMode; receiptId?: string; issuedAt?: string; } export interface ProvenanceChainReceiptV2 { schemaVersion: 'holoscript.provenance-chain.receipt.v2'; receiptId: string; issuedAt: string; receiptHash: string; hashMode: HashMode; theoremStatus: 'hypothesis'; subject: ProvenanceChainReceiptV2Input['subject']; custody: CustodyEvidence; verifier: { ruleGrounded: TierRVerifierEvidence; learnedJudgeLog?: TierLVerifierEvidence; }; fingerprints: { probe_scored: VendorFingerprintResult; probe_unscored: VendorFingerprintResult; substrate_generator?: VendorFingerprintResult; }; measurements: { custodyScore: ProvenanceMeasurement; measuredValueIndependence: ProvenanceMeasurement; preference_correlation: ProvenanceMeasurement; specCoverage: ProvenanceMeasurement; }; exp2: Exp2ValueLeakFalsifierResult; } export interface ProvenanceChainVerificationOptions { minSpecCoverage?: number; } export interface ProvenanceChainVerification { valid: boolean; soulOwned: boolean; gateTier: 'TIER-R'; learnedJudgeLogged: boolean; diagnostics: readonly string[]; warnings: readonly string[]; } export declare function computeCustodyScore(custody: CustodyEvidence): number; export declare function computeSpecCoverage(scoredValueAxes: readonly string[], totalValueAxes: readonly string[]): number; export declare function computeMeasuredValueIndependence(fingerprint: VendorFingerprintResult): number; export declare function computePreferenceCorrelation(observations: readonly PreferenceObservation[]): number | null; export declare function runExp2ValueLeakFalsifier(input: Exp2ValueLeakFalsifierInput): Exp2ValueLeakFalsifierResult; export declare function buildProvenanceChainReceiptV2(input: ProvenanceChainReceiptV2Input): ProvenanceChainReceiptV2; export declare function verifyProvenanceChainReceiptV2(receipt: ProvenanceChainReceiptV2, options?: ProvenanceChainVerificationOptions): ProvenanceChainVerification; export interface ContractViolation { rule: string; message: string; severity: 'error' | 'warning'; /** CAEL reason code for traceability (e.g. CAEL-PHYS-001) */ code?: string; } export type VVCriterion = 'energy_drift' | 'grid_convergence_index' | string; export interface VVMeasurement { criterion: VVCriterion; measured: number; threshold: number; passed: boolean; source: 'solver-stats' | 'computed'; simTime: number; stepCount: number; } export interface VVReport { measurements: VVMeasurement[]; violations: ContractViolation[]; verified: boolean; } export interface ContractSolveResult { provenance: SimulationProvenance; vvReport: VVReport; stateDigests: readonly string[]; } export type ClauseKind = 'precondition' | 'invariant' | 'postcondition'; /** The read-only surface a clause evaluator may observe — solver fields + config + time. */ export interface ClauseContext { /** Named field snapshot via the solver (same surface computeStateDigest reads). */ getField(name: string): FieldData | null; /** The frozen contract config. */ config: Readonly>; /** Current simulation time in seconds. */ simTime: number; /** Fixed sub-steps elapsed at evaluation time. */ stepCount: number; } /** A clause evaluator returns true when the clause HOLDS, false when VIOLATED. */ export type ClauseEvaluator = (ctx: ClauseContext) => boolean; export interface ContractClause { /** Stable identifier — appears in violation messages and the receipt witness. */ id: string; kind: ClauseKind; /** What this clause asserts (the evaluator's semantics must match this). */ description: string; /** Typed evaluator over ClauseContext. Must read at least one ctx field (guard-enforced). */ evaluate: ClauseEvaluator; /** For invariants: evaluate every N fixed sub-steps (default 1). Ignored otherwise. */ cadence?: number; /** Violation severity. 'error' (default) blocks verified=true; 'warning' does not. */ severity?: 'error' | 'warning'; } export interface ClauseViolation { clauseId: string; kind: ClauseKind; /** Mirrors ContractViolation.rule (= clauseId) for uniform downstream handling. */ rule: string; message: string; severity: 'error' | 'warning'; simTime?: number; stepCount?: number; /** CAEL reason code, e.g. CAEL-CLAUSE-001. */ code?: string; } /** The clause proof witness carried into the simulation receipt. */ export interface ClauseWitness { clauses: Array<{ id: string; kind: ClauseKind; description: string; }>; violations: ClauseViolation[]; /** True iff zero error-severity clause violations occurred. */ verified: boolean; } /** * Falsifiability guard — rejects clause evaluators that are structurally * always-true (fake proof). Runs at construction, before any clause is accepted. * * Two static checks over the evaluator source (`.toString()`): * 1. Bare literal — `(ctx) => true` / `() => 1` — the most common fake. * 2. No-context read — the evaluator references none of ctx.getField / * ctx.config / ctx.simTime / ctx.stepCount, so it cannot depend on (and * therefore cannot be falsified by) simulation state. * * Limitation: only catches syntactically obvious always-true evaluators * (a determined author can write `ctx => { ctx.getField('x'); return true; }`). * The behavioral layer of the guard is the test suite: every production clause * SHOULD ship a known-fail case proving a real violation flips verified=false. */ export declare function guardClauseFalsifiability(clause: ContractClause): void; export interface ContractConfig { /** Fixed timestep in seconds (default: auto from solver CFL) */ fixedDt?: number; /** Maximum timestep accumulator (prevents spiral of death, default: 0.1s) */ maxAccumulator?: number; /** Whether to enforce unit validation (default: true) */ enforceUnits?: boolean; /** Whether to reject meshes with out-of-range element indices (default: true). Paper #4 semantic sanity. */ enforceMeshSanity?: boolean; /** * Whether to run semantic physics sanity checks beyond geometry hash * (Jacobian/sign, stiffness PD, element quality). Default: true for * continuum-scale structural/thermal solvers; false otherwise. * Paper #4 — closes the hash-consistent-but-physically-wrong gap. */ enforcePhysicsSanity?: boolean; /** Whether to log all interactions (default: true) */ logInteractions?: boolean; /** Solver type label */ solverType?: string; /** * Semantic contract clauses — typed preconditions/invariants/postconditions * over solver fields + config. Opt-in: absent → behavior unchanged. Each * evaluator is checked for fake-proof at construction (guardClauseFalsifiability). * Preconditions gate construction; invariants run during step() at their * cadence; postconditions run at getProvenance(). Carried into the receipt. */ clauses?: ContractClause[]; /** * Continuation link (receipt chaining): declare that this run continues from a * prior run, seeding from that run's final state. Recorded into * `SimulationProvenance.continuesFrom` and checkable via * `verifyContinuationChain`. Absent for fresh (genesis) runs. */ continuesFrom?: ContinuationLink; /** * Simulation scale tag — the physical regime this solver operates in. * * Per EVOLVED §7.2 and W.QDA.001: the scale determines which acceptance * envelope applies, what tolerance bounds are expected, and whether * cross-scale replay is valid. * * Default: 'continuum' (backward compat — existing single-scale contracts * are continuum FEM/CFD/structural by construction). * * Short aliases are also accepted: * 'qm' → 'quantum', 'md' → 'atomistic', 'meso' → 'mesoscopic', * 'system' → 'empirical-surrogate' */ scale?: SimulationScale; /** * Override the default acceptance envelope for the given scale. * When absent, DEFAULT_SCALE_ENVELOPES[scale] is used. * * Use this when a specific solver has tighter or looser tolerances * than the scale default (e.g. a high-precision FEM solver might * set tolerance: 1e-3 instead of the continuum default 1e-2). */ scaleEnvelope?: ScaleEnvelope; /** Use cryptographic (SHA-256) hash at the three contract hash * sites (hashGeometry, computeStateDigest, hashCAELEntry) instead * of the default FNV-1a. * * Option C (SECURITY-mode 2026-04-20): FNV-1a is the DEFAULT for * performance under the non-adversarial threat model; SHA-256 is * opt-in for adversarial-peer deployments where collision * resistance on the hash chain matters. * * Performance cost: ~9-24× slower per-hash than FNV-1a at paper-3 * scales (see bench `fnv1a-vs-sha256.bench.test.ts`). On a 10^4- * step full-building scenario, ~4.3 s of added hash overhead on * ~30 s total simulation wall time = ~14% regression. Do not flip * this on by default. * * Mode is threaded through every contract hash site via a single * dispatcher (`hashBytes` / `hashStringForCAEL`), written into * `cael.init.payload.hashMode` at trace-record time, and verified * at replay-time — mid-trace mode tampering throws. * * See: ai-ecosystem research/2026-04-20_sha256-feature-flag-design.md * (Option C + Wiring-commit prerequisites). */ useCryptographicHash?: boolean; /** Opaque adapter fingerprint for cross-adapter dispute dispatch * (paper-3 §5.2 Algorithm 1, 5b). Recorded into cael.init.payload * at trace-record time; compared by CAELReplayer.sameAdapter() * against the replay environment's current fingerprint at * replay-time to dispatch digest-enforcement mode: * same-adapter → strict digest enforcement (Item 5a behavior) * cross-adapter → skip digest enforcement (Appendix A Lemma 3 * regime boundary; fall through to metric- * comparison in the dispute oracle) * * **SECURITY NOTES** (Wave-2 SECURITY-mode audit 2026-04-20 — see * ai-ecosystem research/2026-04-20_adapter-fingerprint-security-audit.md): * * - Privacy: if supplied as a raw concatenation * (e.g. "vendor=Intel;device=UHD;driver=31.0"), this field * leaks exact hardware identifiers to anyone who reads the * trace. For traces shared externally (reviewer packages, * peer-to-peer dispute exchanges, debugging exports), PREFER * the SHA-256-hashed output of `computeAdapterFingerprint()` * below — opaque 256-bit digest that preserves * equivalence-class comparison (sameAdapter() still works) * while closing the raw-identifier leak. * * - Forgeability: this field is trust-the-caller. No validation * against the actual WebGPU adapter at runtime, no signed * attestation. In adversarial multi-agent settings a hostile * agent can forge this field to either (a) force strict * enforcement on genuinely-cross-adapter traces (DoS via * spurious StateIntegrityViolation) or (b) bypass strict * enforcement on genuinely-same-adapter traces by claiming * different hardware. For single-tenant local development * this is a non-issue; for production multi-agent contracts * the fingerprint MUST come from a trusted source (WebGPU * adapter info API called at recorder-construction time by * trusted code, not user-supplied) and ideally * cryptographically signed. Full attestation is deferred to * a follow-up (see audit memo §Future hardening). * * - Recommended use: pass the output of * `await computeAdapterFingerprint(adapterInfo)` rather than * a raw string. See helper below. * * If absent at record-time, the trace is treated as * cross-adapter for all replays (safe fallback). */ adapterFingerprint?: string; /** Subgrid parameter vector for paper-0c CAEL attestation (TODO-05). * * Set to declare the run's subgrid feedback / cooling / resolution-floor * controls — anything below the mesh resolution that distinguishes two * observationally-equivalent runs (EAGLE vs IllustrisTNG vs FIRE-3 etc.). * When present, ContractedSimulation calls * `canonicalizeSubgridParams()` (from `@holoscript/core/paper-0c-spike`), * hashes the canonical form under the contract's `useCryptographicHash` * mode, and folds the resulting hash into `getContractId()` alongside * `geometryHash` and `adapterFingerprint`. The full SubgridAttestation * envelope is exposed via `getSubgridAttestation()` and recorded in * `cael.init.payload.subgridAttestation` by CAELRecorder. * * **Backward compat**: when this field is ABSENT, `getContractId()` * returns `geometryHash` byte-identically — no envelope is constructed, * no extra hash work is done, and pre-change traces remain bit-exact * reproducible. Same "omitted means unchanged fingerprint" semantics as * `replayFingerprint.ts` (`weightCid`, `verticalProfile`). * * See: `packages/core/src/paper-0c-spike/subgrid-attestation.ts` * module header — "Why this exists" + "Integration hook". */ subgridParams?: SubgridParams; /** * Valid-parameter domain for this simulation run (H1 proof machinery). * * Declares the space of parameter values for which the run's proof is valid. * Checked at construction time: params in `ContractConfig` are checked against * each `ParameterEnvelopeRecord` whose `param` key matches a top-level field. * * - `onViolation: 'warn'` → violation recorded, run proceeds. * - `onViolation: 'error'` → construction throws `ContractViolation`. * - `onViolation: 'redischarge'` → violation recorded; receipt carries * `envelopeCheck.redischarge: true` so the * caller knows the proof must be re-run. * * The full `EnvelopeCheckResult` is carried into the provenance output so * the receipt witnesses which parameters were in/out of their envelopes. * * Absent → envelope checking is skipped (backward-compatible). */ parameterEnvelope?: ParameterEnvelope; } /** * Canonical WebGPU adapter info (subset matching the W3C WebGPU * `GPUAdapterInfo` shape). All fields are optional; missing fields * canonicalize to empty string, which still produces a stable digest * but with less discriminative power. */ export interface AdapterInfo { /** GPU vendor (e.g. "Intel", "NVIDIA", "Apple", "AMD", "Qualcomm"). */ vendor?: string; /** GPU architecture family (e.g. "gen12", "ampere", "m-series"). */ architecture?: string; /** Specific device label (e.g. "Intel UHD Graphics 620"). */ device?: string; /** Driver version string. */ driver?: string; /** Browser user-agent (pins Chrome version etc.) */ userAgent?: string; } export declare function checkSimulationParameterEnvelopeInheritance(proofSource: ParameterEnvelopeProofSource, adjustedConfig: Record): ParameterEnvelopeInheritanceResult; export declare function assertSimulationParameterEnvelopeInheritance(proofSource: ParameterEnvelopeProofSource, adjustedConfig: Record): ParameterEnvelopeInheritanceResult; /** * Compute a SHA-256 fingerprint of canonical adapter info, suitable * for `ContractConfig.adapterFingerprint` (Item 5b cross-adapter * dispatch). * * Why this helper exists (SECURITY-mode audit 2026-04-20): * - Closes the raw-hardware-identifier privacy leak: the output is * an opaque 256-bit hex string; readers see equivalence-class * identity ("these two traces used the same adapter") without * learning the raw vendor/device/driver strings. * - Canonical pipe-joined tuple prevents ambiguity between * fingerprints with different field boundaries. E.g. ("Intel", * "foo") vs ("Intelfoo", "") both raw-concat to "Intelfoo" but * pipe-canonicalize to distinct "Intel|foo" vs "Intelfoo|". * * What this helper does NOT solve: * - Forgeability: the caller decides what AdapterInfo to pass. A * hostile agent can still pass a made-up AdapterInfo to get any * fingerprint they want. Full mitigation requires an attested * source (the WebGPU adapter info API, called by trusted code, * ideally signed). Deferred to a follow-up commit — see audit * memo research/2026-04-20_adapter-fingerprint-security-audit.md * §Future hardening. * * Returns a 64-hex-char string (SHA-256 digest). Async because it * uses crypto.subtle.digest, which is Promise-based in both browser * and Node ≥ 15. */ export declare function computeAdapterFingerprint(info: AdapterInfo): Promise; /** * Paper #4 — semantic sanity beyond hash: element indices must reference real nodes. * Catches hash-consistent but physically meaningless connectivity (e.g. indices * pointing past the vertex buffer). */ export declare function validateMeshSanity(vertices: Float64Array | Float32Array | undefined, elements: Uint32Array | undefined): ContractViolation[]; /** * SEC-03 / Paper #4 semantic physics sanity beyond geometry hash. * Catches hash-identical meshes that are physically invalid (inverted elements, bad Jacobian). * Called from validateMeshSanity as the optional stage. */ export declare function checkJacobianSign(vertices: Float64Array | Float32Array | undefined, elements: Uint32Array | undefined, elementType?: 'tet4' | 'tri3' | 'unknown'): ContractViolation[]; /** * Semantic physics sanity pass beyond geometry hash (Paper #4 gap closure). * * Catches meshes that are hash-consistent and connectivity-valid but * physically meaningless: inverted elements, degenerate geometry, * or material properties that produce non-positive-definite stiffness. * * Scoped to structural/thermal continuum solvers first (tet4 / tri3). * Emits CAEL-PHYS-* reason codes for traceability. */ export declare function validatePhysicsSanity(vertices: Float64Array | Float32Array | undefined, elements: Uint32Array | undefined, config: Record): ContractViolation[]; /** * Validate physical quantities in a solver config. * Returns violations for out-of-range or suspicious values. */ export declare function validateUnits(config: Record): ContractViolation[]; /** * Fixed-timestep accumulator for frame-independent, deterministic simulation. * * Instead of solver.step(frameDelta), which varies per frame: * accumulator += frameDelta * while (accumulator >= fixedDt) { * solver.step(fixedDt) // always the same dt * accumulator -= fixedDt * } * * This ensures the same simulation produces the same results regardless * of frame rate, machine speed, or when you step. */ export declare class DeterministicStepper { private fixedDt; private maxAccumulator; private accumulator; private stepCount; private simTime; constructor(fixedDt: number, maxAccumulator?: number); /** * Advance by wall-clock delta. Returns the number of fixed steps taken. */ advance(wallDelta: number, stepFn: (dt: number) => void): number; /** Async variant of advance() — awaits each step function call. Used by asyncStep(). */ advanceAsync(wallDelta: number, stepFn: (dt: number) => Promise): Promise; getStepCount(): number; getSimTime(): number; /** The EXACT configured fixed timestep. Provenance records MUST use this * rather than recomputing simTime/stepCount — the recompute carries a * last-ULP fp error that makes serialized replay drift off the original * dt (non-bit-identical replay). See createReplay(). */ getFixedDt(): number; getAccumulator(): number; reset(): void; } /** * ContractedSimulation — Wraps any SimSolver with enforced guarantees. */ export declare class ContractedSimulation { private solver; private stepper; private interactions; private nextEventId; private geometryHash; private config; private solverType; private violations; /** Frozen clause definitions accepted at construction (after the falsifiability guard). */ private clauseDefs; /** Clause violations accumulated across precondition/invariant/postcondition evaluation. */ private clauseViolations; /** Result of envelope check at construction (null when no envelope was declared). */ private envelopeCheckResult; /** Valid-parameter domain frozen into provenance and replay receipts. */ private parameterEnvelope; private previousEnergy; private vvMeasurements; private vvViolations; private startTime; private logInteractions; /** Continuation link declared at construction (receipt chaining). */ private continuesFrom; /** * Per-step state-vector digests (paper-3 Route 2b closure path for * Property 4 cross-adapter determinism). * * Each entry is the FNV-1a hash of the quantized (*1e6 + round) state * vector AFTER that step's solver.step() completed. The quantization * resets floating-point drift per step, which means cross-adapter * replays can agree bit-exact on the digest even when their underlying * float32 reduction orders differ — as long as the pre-quantized state * vectors agree within the contract's ε tolerance (defined by the * quantum, 1/1e6 = 1 µ-unit). * * See: * research/2026-04-20_webgpu-determinism-protocol.md (ai-ecosystem) * research/2026-04-20_property-4-route-2-proof-outline.md (ai-ecosystem) * packages/engine/src/simulation/__tests__/state-canonicalize-overhead.bench.test.ts * (decision: Route 2b wins at 1.372% max overhead vs paper-3 §7 production-step median) */ private stateDigests; /** * Per-step GPU output digests (paper-4 §5.2 — GPU solver verification). * * Populated by `asyncStep()` when the wrapped solver implements * `GpuBackedSolver`. Each entry is the `hashGpuOutput()` digest of the * flat readback buffer returned by `solver.readbackOutput()` AFTER that * step's GPU dispatch completed. An empty array when using a CPU-only * solver (or when `asyncStep()` has not been called yet). * * Can be compared across replays to verify that two GPU runs produced * identical output buffers at each step (same guarantees as CPU-side * `stateDigests`, but applied to the raw GPU output before any CPU-side * field transformation). */ private gpuOutputDigests; /** * Simulation scale — the physical regime this contract operates in. * Resolved from ContractConfig.scale at construction. Default: 'continuum' * for backward compatibility (existing single-scale contracts are continuum * FEM/CFD/structural by construction). * * Per W.QDA.001 (Query-Driven Abstraction): the right level of abstraction * is determined by the user's question, not by the substrate. Scale tagging * makes this routing explicit. */ private scale; /** * Per-scale acceptance envelope. Either the custom envelope from * ContractConfig.scaleEnvelope or DEFAULT_SCALE_ENVELOPES[scale]. * Frozen at construction time. */ private scaleEnvelope; /** * Hash mode for all three contract hash sites (hashGeometry, * computeStateDigest, hashCAELEntry when this contract's recorder * wraps it). Option C (2026-04-20 SECURITY wiring): resolved from * contractConfig.useCryptographicHash at construction. Immutable * for the life of the contract. * * Per Prereq 1 (per-recorder flag scope): no env var or global * override — this is the only authoritative source. */ private hashMode; /** Public accessor for the hash mode. Used by CAELRecorder to * thread the mode into hashCAELEntry calls and into * cael.init.payload.hashMode. */ getHashMode(): HashMode; /** Public accessor for the simulation scale. */ getScale(): SimulationScale; /** Public accessor for the scale acceptance envelope. */ getScaleEnvelope(): ScaleEnvelope; /** * Subgrid-parameter attestation envelope, present iff * ContractConfig.subgridParams was provided at construction. Frozen * at construction time; null when no subgrid params were supplied. * * CAELRecorder reads this and surfaces the envelope into * cael.init.payload.subgridAttestation for replay-side verification * via verifySubgridAttestation() / verifySubgridAttestationAsync() * from `@holoscript/core/paper-0c-spike`. */ private subgridAttestation; /** Public accessor for the subgrid-parameter attestation envelope. * Returns `undefined` when the contract was constructed without * `subgridParams`. */ getSubgridAttestation(): SubgridAttestation | undefined; getParameterEnvelope(): ParameterEnvelope | undefined; /** Stable Contract-ID used to identify a contracted run. Composes * `geometryHash` plus, when present, the adapter fingerprint and * the subgrid attestation hash. Backward-compat invariant: when * neither `adapterFingerprint` nor `subgridParams` is set on the * contract, this returns `geometryHash` byte-identically (no * composition, no hashing) — so pre-change contracts produce the * same Contract-ID as before this field existed. */ private contractId; getContractId(): string; /** Stable per-instance run identifier — one id per run, fixed at construction. */ private readonly runId; getRunId(): string; /** The final (terminal) state digest of this run, if any was captured. */ private getFinalStateDigest; /** * Capture THIS run as the seed for a successor — the link a continuation run * passes as `ContractConfig.continuesFrom`. Verifiable later from provenance * records alone via {@link verifyContinuationChain}. */ getContinuationLink(): ContinuationLink; constructor(solver: SimSolver, config: Record, contractConfig?: ContractConfig); private recordVVMeasurement; private evaluateVVCriteria; /** Advance the simulation by wall-clock delta using fixed timestep. * Enforces Guarantee 1 (geometry integrity) before each step. * Captures per-step state digest for Property 4 Route 2b (cross-adapter * determinism via per-step canonicalization — see stateDigests field). */ step(wallDelta: number): number; /** * Async variant of `step()` for GPU-backed solvers (paper-4 §5.2). * * Identical to `step()` except: * 1. Each sub-step awaits the solver's `step(dt)` promise (allowing * GPU command buffer submission and synchronization to complete). * 2. After each sub-step, if the solver implements `GpuBackedSolver`, * `readbackOutput()` is called and the result is hashed via * `hashGpuOutput()` and appended to `gpuOutputDigests`. This * records a verifiable fingerprint of the raw GPU output buffer * at every fixed-timestep, closing the gap between CPU-side * contract verification and GPU-executed solvers. * 3. CPU-side `stateDigests` (Route 2b) is still populated via * `computeStateDigest()` if `fieldNames`/`getField()` are available, * so existing replay/verification tooling continues to work. * * @returns Promise — number of fixed sub-steps taken (same * semantics as synchronous `step()`). */ asyncStep(wallDelta: number): Promise; /** Return the array of per-step GPU output digests captured by `asyncStep()`. * Empty when using a CPU-only solver or before `asyncStep()` is called. */ getGpuOutputDigests(): readonly string[]; /** Return the array of per-step state digests captured so far. * Used by CAELReplayer + cross-adapter determinism verification. */ getStateDigests(): readonly string[]; /** Solve a steady-state system (not time-stepped). * Enforces Guarantee 1 (geometry integrity) before solving. * * Route 2d (paper-3 Appendix A, Wave-2 item 6): captures a single * terminal state digest at solve() completion. For steady-state * solvers the convergence loop has already damped reduction-order * variance — δ_fp is bounded by the solver's convergence tolerance * (typically ≤ 10^-6 of field scale, much tighter than in-step * atomic-reduction drift). So Route 2d typically achieves cross- * adapter bit-identity at the lattice level with margin ≥ 10^3×, * tighter than Route 2b's stepped bound. * * The terminal digest is exposed via the same getStateDigests() * API as Route 2b's per-step sequence; for a Route-2d replay there * is exactly one digest to compare. * * See: ai-ecosystem research/2026-04-20_property-4-route-2-proof-outline.md * (Limitation #3, "Route 2d sketch" — now implemented). */ solve(): Promise; /** * Compose the Contract-ID from `geometryHash` and the optional * adapter / subgrid / scale identity inputs. * * **Backward-compat invariant** (the load-bearing constraint of this * function): when `adapterFingerprint`, `subgridAttestation`, AND * `scale === 'continuum'` are all default/absent, this returns * `geometryHash` BYTE-IDENTICALLY. No hashing, no concatenation, no * prefix. Pre-change contracts that stored Contract-ID as * `geometryHash` directly remain valid. * * When at least one optional input is set (or scale is non-default), * we hash the canonical pipe-joined tuple under the contract's hash * mode. Same family as `replayFingerprint.ts`'s pipe-delimited * canonicalization. Pipe is safe because hex hashes never contain `|`. * * Field order is fixed (`geometryHash | scale | adapterFingerprint | * subgridHash`) and missing fields collapse to empty string — same * pattern as `computeAdapterFingerprint()` above. * * Hash mode: respects `this.hashMode` so a contract running under * SHA-256 produces a SHA-256-strength Contract-ID; FNV-1a-mode * contracts produce a 16-hex Contract-ID. */ private composeContractId; /** Enforce Guarantee 1: halt if geometry has been corrupted. * Re-hashes the mesh vertices and elements under the contract's * hash mode and compares against the contracted hash from * construction. Throws if they diverge. */ private enforceGeometryIntegrity; /** Log a user interaction that affects solver state. */ logInteraction(type: string, data: Record): void; /** Get a named field from the solver. */ getField(name: string): FieldData | null; /** Get solver stats. */ getStats(): Record; /** Get all contract violations found during construction. */ getViolations(): ContractViolation[]; getVVViolations(): ContractViolation[]; getVVReport(): VVReport; /** Whether the contract has any errors (not just warnings). */ hasErrors(): boolean; /** Whether any error-severity clause violations have been accumulated. */ private hasClauseErrors; /** * Build a ClauseContext snapshot from the current solver + stepper state. * The context is read-only from the clause's perspective — it delegates * field reads to the solver and exposes the frozen contract config. */ private buildClauseContext; /** * Evaluate all clauses of a given kind, recording violations. * Called for 'precondition' at construction and 'postcondition' at finalization. * Invariant evaluation is handled separately by `runInvariantClauses()`. */ private evaluateClauses; /** * Run invariant clauses for the current sub-step. * Each invariant declares an optional `cadence` (evaluate every N steps). * Cadence defaults to 1 (evaluate on every sub-step). */ private runInvariantClauses; /** * Evaluate postcondition clauses exactly once at finalization. * Guards against double-evaluation on repeated `getProvenance()` calls. */ private postconditionsEvaluated; private evaluatePostconditionsOnce; /** * Generate the full provenance record for this simulation. * This is what makes it scientifically citable. */ getProvenance(): SimulationProvenance; /** * Create a replay record: config + interactions + geometry hash. * Another instance with the same config + interactions will produce * the same results (deterministic stepping guarantees this). */ createReplay(): { config: Record; solverType: string; geometryHash: string; contractId: string; subgridAttestation?: SubgridAttestation; scale: SimulationScale; scaleEnvelope: ScaleEnvelope; interactions: InteractionEvent[]; fixedDt: number; totalSteps: number; parameterEnvelope?: ParameterEnvelope; envelopeCheck?: EnvelopeCheckResult; /** Continuation link, when this run was declared to continue from a prior * run — lineage survives replay so the chain can be re-verified. */ continuesFrom?: ContinuationLink; /** Hash mode of the original run. Replay MUST reconstruct under the same * mode or its per-step state digests will not match (sha256 vs fnv1a). */ useCryptographicHash: boolean; }; /** Verify that the current geometry matches the contracted hash * under the contract's hash mode. */ verifyGeometry(vertices: Float64Array | Float32Array, elements: Uint32Array): boolean; /** * Replay a simulation from a provenance record (Guarantee 6). * * Creates a new ContractedSimulation from the replay record's config, * verifies geometry hash matches, and re-applies all interactions at * their recorded simulation times. For steady-state solvers, calls * solve() directly. For transient solvers, steps through the recorded * time span with the original fixed timestep. * * @returns The replayed ContractedSimulation instance with its own * provenance record, which can be compared for equivalence. */ static replayFromProvenance(solverFactory: (config: Record) => SimSolver, replay: { config: Record; solverType: string; geometryHash: string; interactions: InteractionEvent[]; fixedDt: number; totalSteps: number; parameterEnvelope?: ParameterEnvelope; /** Hash mode of the original run (createReplay records this). When * omitted, falls back to the default mode for backward compatibility. */ useCryptographicHash?: boolean; }): ContractedSimulation; /** * Generate a WorldModelReceipt that pairs a caller-supplied latent prediction, * or an explicit zero-vector baseline, with the solver-produced reference * state for the current simulation. * * ## Pipeline * * The caller provides: * - `jepaPredictor`: a function that produces a `LatentVector` for the * current physics state (typically a world model running in parallel). * - `stateEncoder`: a function that projects `PhysicsState` into the same * latent space so `delta_error` is meaningful. * * This method: * 1. Captures the solver's current field values as `solver_ground_truth`. * 2. Calls `jepaPredictor` when supplied; otherwise emits a zero baseline. * 3. Calls `stateEncoder` to embed the ground truth. * 4. Validates equal, finite vector dimensions and computes their L2 distance. * 5. Assigns an uncalibrated numerical envelope from contract tolerance + * a fixed 1e-6-per-component quantization heuristic. * 6. Hashes the compact canonical receipt projection under the contract's * declared mode and records it as `receiptHash`. * * ## Default predictor / encoder * * When `jepaPredictor` is omitted, a zero-vector prediction is used * (delta_error = ‖encoded ground truth‖₂ — useful for baseline testing). * When `stateEncoder` is omitted on the zero-baseline path, a trivial * projection copies the first non-empty field's values. Receipts fail closed * when the solver exposes no non-empty typed-array field. A * caller-supplied predictor requires an explicit `stateEncoder`; the method * validates dimensions but cannot verify that both functions share semantic * encoder identity. * * @param jepaPredictor World model → latent prediction. May be async. * @param stateEncoder PhysicsState → latent embedding for comparison. * @returns A receipt with its hash mode and prediction kind disclosed. * Anchoring and producer authentication are external operations. */ generateWorldModelReceipt(jepaPredictor?: (state: PhysicsState) => LatentVector | Promise, stateEncoder?: (state: PhysicsState) => Float32Array): Promise; dispose(): void; } //# sourceMappingURL=SimulationContract.d.ts.map