import { z } from "zod"; export declare const LEDGER_VERSION = "cotal-ledger/v1"; declare const LedgerAgentSchema: z.ZodObject<{ requested: z.ZodString; name: z.ZodString; id: z.ZodString; hash: z.ZodString; lifecycleUid: z.ZodOptional; }, z.core.$strict>; declare const LedgerSchema: z.ZodObject<{ apiVersion: z.ZodLiteral<"cotal-ledger/v1">; kind: z.ZodLiteral<"MeshLedger">; runId: z.ZodString; space: z.ZodString; server: z.ZodString; manifestHash: z.ZodString; manifestPath: z.ZodString; teardownMode: z.ZodLiteral<"ledger-scoped">; created: z.ZodObject<{ channels: z.ZodArray; agents: z.ZodArray; }, z.core.$strict>>; }, z.core.$strict>; }, z.core.$strict>; export type MeshLedger = z.infer; export type LedgerAgent = z.infer; /** Assemble a ledger from a `spawn -f` apply result. `agents` carry the manager-reply SPAWNED name * (cred-keying) + manifest `requested` key + nkey id + resolved hash; `channels` are the brand-new * registry keys this run created. */ export declare function buildLedger(opts: { runId: string; space: string; server: string; manifestHash: string; manifestPath: string; channels: string[]; agents: LedgerAgent[]; }): MeshLedger; /** Stable index hash of the manifest source text — ties a `down -f cotal.yaml` back to its ledger * (an edited file no longer matches, so `down -f` fails rather than guessing; `--run` is the * escape hatch). NOT an integrity check and NOT ownership authority — only a lookup key. */ export declare function hashManifestSource(src: string): string; /** Write the ledger to `/.cotal/manifests/.json`, `0600`, atomically and refusing a * symlinked parent. A brand-new ledger is `wx` (exclusive create); an additive update (re-apply) * goes temp-then-rename so `down -f` never reads a half-written file. */ export declare function writeLedger(root: string, ledger: MeshLedger, opts?: { update?: boolean; }): string; /** Parse + strictly validate a ledger file as **untrusted input** — schema, unknown-key rejection, * token-safe run id / agent names, concrete channel keys, and duplicate detection — so the WHOLE * ledger is proven before the caller deletes anything (no partial "validated the class I'm about to * delete" flow). Throws on any deviation. */ export declare function loadLedger(path: string): MeshLedger; /** Build the ledger row for ONE launched agent, and PARSE it rather than assert it. * * WHICH SIDE EACH FIELD COMES FROM IS THE WHOLE POINT. `requested` and `hash` are the DEPLOY * CALLER'S OWN inputs — it submitted the manifest key and resolved the drift hash before it ever * called the manager — so they are read from the plan. Only the SPAWNED identity (`name`, `id`, * `lifecycleUid`) can come from the reply, and that is exactly what the v0.4 action acceptance * floor carries (P2 item 2 ruling 3: the manifest details are deliberately NOT in the launch * output contract, because the caller can re-derive them). Reaching across the wire for a value * already in local scope is what broke this: the reply stopped carrying them, `as` could not warn, * `JSON.stringify` dropped the undefined keys, and the row only failed months later at teardown. * * PARSE, NEVER CAST. A cast is a claim about a shape the compiler then stops checking; the whole * defect lived in the gap between that claim and the wire. This throws at WRITE time, naming the * field, instead of persisting a record the reader will refuse. */ export declare function buildLedgerAgentRow(planned: { requested: string; hash: string; }, spawned: { name?: unknown; id?: unknown; lifecycleUid?: unknown; }): LedgerAgent; /** Every valid ledger under `/.cotal/manifests/`. Foreign files are skipped (a targeted * `down -f --run ` names one directly); used to resolve a `down -f cotal.yaml` to its run by * `manifestHash`. * * A REFUSED file is NOT the same as an absent one, and collapsing the two cost a release. When a * file under this root is named for its own `runId` but fails validation, it is OURS and broken, * not somebody else's: swallowing that turned a zod error NAMING the missing fields into * `findLedgerByHash`'s "was it edited since `spawn -f`?", which accuses the operator of editing a * manifest they never touched. So refusals are RETURNED alongside the valid rows and the caller * decides; the message that already existed is surfaced rather than replaced. */ export declare function listLedgers(root: string): Array<{ path: string; ledger: MeshLedger; }>; /** {@link listLedgers} plus the files this root REFUSED, so a caller can tell "no ledger here" from * "a ledger I could not read". `refused` carries the validator's own message verbatim. */ export declare function listLedgerFiles(root: string, options?: { requireReadable?: boolean; }): { valid: Array<{ path: string; ledger: MeshLedger; }>; refused: Array<{ path: string; why: string; }>; }; /** Resolve a `down -f cotal.yaml` to its ledger by the manifest's content hash. Fails (never * guesses) when nothing matches (edited file) or more than one does — `--run ` is the escape. */ export declare function findLedgerByHash(root: string, manifestHash: string): { path: string; ledger: MeshLedger; }; /** Resolve a ledger by explicit run id (the `--run ` path). Validates the id is a safe token * before deriving the path. */ export declare function findLedgerByRun(root: string, runId: string): { path: string; ledger: MeshLedger; }; /** Derive an owned agent's cred path under the known auth root from the SPAWNED name (+ the * recorded lifecycle uid when the row carries one). The ledger never stores a cred path; teardown * derives it here through the workspace's single filename source for the kind (the guarded * segment refuses any name that could escape the creds dir), so teardown can never derive a * DIFFERENT path than provisioning wrote: a uid-carrying row maps to the lifecycle-keyed file its * spawn materialized, a pre-split row to the legacy name-keyed one. * * `space` is the ledger's OWN `space` field, the mesh the run provisioned against — which is the * only space this run can have written agent secrets in, and now (P1) the segment they sit under. * Passing it keeps the derivation what it already was: teardown resolves the same path the same * run's spawn wrote, and can never reach into a co-resident tenant's segment. */ export declare function ownedCredPath(root: string, space: string, spawnedName: string, lifecycleUid?: string): string; export {}; //# sourceMappingURL=ledger.d.ts.map