UNPKG

trellis

Version:

Agentic State Engine — event-sourced causal graph with branching, decision traces, and realtime sync for AI-native applications

132 lines 5.02 kB
/** * Canonical op serialization and hashing. * * ADR 0021. The op hash was previously unverifiable: the kernel hashed the * caller's payload object verbatim while each backend independently * reconstructed a differently-shaped payload to store. Two writers, two shapes, * no way to recompute a hash from storage. * * This module is the single serializer. `hashKernelOp` (mint) and every * backend's `append()` (persist) must both go through it — neither may * hand-roll an object literal. That property is what makes the hash a real * content address rather than a unique-ish identifier. * * @module trellis/core */ import type { Fact, Link } from '../store/eav-store.js'; import type { KernelOp } from './backend.js'; /** * Preimage version. v1 = the legacy, unrecoverable `|`-joined format; ops * predating this module carry no `v` and are grandfathered as opaque history * (their preimages cannot be reconstructed — that was the bug). */ export declare const OP_PREIMAGE_VERSION = 2; /** * Op-level provenance (ADR 0021 §2, Phase B). * * The slot exists in the canonical shape from Phase A onward, normalized to * `null` when absent. Phase B populates it. Because both phases run the same * normalization, populating it later changes values but not shape — Phase-A ops * keep verifying, and provenance lands without a second preimage break. */ export interface OpProvenance { actorType: 'user' | 'machine' | 'ai'; origin: 'cli' | 'sdk' | 'http' | 'mcp' | 'sync' | 'migration' | 'cron'; } /** * Per-surface provenance defaults (ADR 0021 §2). * * `origin` is genuinely knowable — it is the transport the op arrived on. * `actorType` is an *assertion by the minting process*, not a proof; binding it * to a device key is ADR 0020's territory (see ADR 0021 "Deferred"). Treat * these as best-available claims: * * - `mcp` ⇒ `ai` — MCP is the agent tool protocol; the caller is an agent. * - `agent` ⇒ `ai` over `origin: 'sdk'` — an in-process AI agent calling the * kernel directly (the harness, plan execution, agent memory). Keyed by * actor rather than transport because `sdk` is the transport and `ai` is the * part that carries information. * - `cli` ⇒ `user` — a person ran a command. Note this is the weakest claim * here: agents shell out to the CLI too, and nothing distinguishes them. * - everything else ⇒ `machine` — the honest "a program did this, we do not * know on whose behalf". */ export declare const PROVENANCE: { readonly cli: { readonly actorType: "user"; readonly origin: "cli"; }; readonly http: { readonly actorType: "machine"; readonly origin: "http"; }; readonly mcp: { readonly actorType: "ai"; readonly origin: "mcp"; }; readonly sdk: { readonly actorType: "machine"; readonly origin: "sdk"; }; readonly agent: { readonly actorType: "ai"; readonly origin: "sdk"; }; readonly sync: { readonly actorType: "machine"; readonly origin: "sync"; }; readonly migration: { readonly actorType: "machine"; readonly origin: "migration"; }; readonly cron: { readonly actorType: "machine"; readonly origin: "cron"; }; }; /** The caller-supplied body of a mutation, before normalization. */ export interface OpPayloadInput { facts?: Fact[]; links?: Link[]; deleteFacts?: Fact[]; deleteLinks?: Link[]; provenance?: OpProvenance; } /** * Serialize a newly-minted op body to its canonical JSON string. * * This exact string is what backends write to the `payload` column, so the * stored bytes are the hashed bytes. */ export declare function canonicalOpBody(payload: OpPayloadInput): string; /** * Serialize a persisted op's body, preserving its own preimage version. * * Used by `append()`. Ops arriving via `appendBatch` from a peer may be v1; * those must round-trip as v1 (opaque history), not be restamped as v2. */ export declare function canonicalOpBodyFromOp(op: KernelOp): string; /** Header fields that sit outside the body but inside the preimage. */ export interface OpHeader { kind: string; timestamp: string; agentId: string; previousHash?: string; } /** Compute an op's content hash from its header and caller payload (mint path). */ export declare function hashKernelOp(header: OpHeader, payload: OpPayloadInput): Promise<string>; export interface VerifyResult { valid: boolean; /** True for pre-ADR-0021 ops, whose preimages are unrecoverable by construction. */ legacy: boolean; } /** * Recompute a persisted op's hash and compare. * * v1 ops (no `v` in the stored body) are grandfathered: reported * `{valid: true, legacy: true}` rather than failed, since their preimages * cannot be reconstructed. v2 ops must genuinely verify. */ export declare function verifyOpHash(op: KernelOp): Promise<VerifyResult>; //# sourceMappingURL=canonical-op.d.ts.map