/** * @fileoverview Change-journal writer — single-writer, fsync'd, hash-chained * append (SMI-5456 Wave 1 Step 3 / SMI-5470). * @module @skillsmith/core/journal/writer * * P-5 single-writer invariant (docs/internal/implementation/smi-5456-skillsmith-agent-wave1.md * "Shared-State / Coordination Audit"): the journal file is written by the * apply-family MCP tools ONLY, and every writer in this process funnels * through `appendJournalRecord`, which serializes behind ONE module-scoped * promise queue. That queue — not any per-caller locking — is what makes * concurrent `apply_namespace_rename` / `apply_recommended_edit` / `undo_apply` * calls in the same server process produce well-formed, correctly-chained * lines instead of interleaved/torn writes. * * Durability: each append opens the file, writes the line, calls * `FileHandle.sync()` (fsync), then closes — so a record that returns * successfully is durable on disk before the caller's apply/undo response * goes out, matching the "fsync'd appends" requirement in the plan's P-5 * table. */ import type { JournalRecord, JournalRecordInput } from './types.js'; /** * Recompute a record's `record_hash` from its other fields. Exported so the * reader can independently verify each line without duplicating the * canonicalization logic (drift between writer and reader would silently * break every chain-verification call). */ export declare function computeRecordHash(record: Omit): string; /** * Error thrown when the journal's last line cannot be parsed as a valid * record — the writer cannot safely determine the chain head to append * after. This is distinct from the reader's "corrupt tail = report, never * throw" contract: a reader is producing evidence about the past and must * degrade gracefully; a writer is about to create NEW evidence and silently * starting a fresh chain over a corrupt/tampered tail would hide exactly * the tamper signal the chain exists to surface. */ export interface JournalCorruptTailError extends Error { kind: 'journal.write.corrupt_tail'; } export declare function isCorruptTailError(err: unknown): err is JournalCorruptTailError; /** * Append a record to the journal. Serialized behind the module-scoped * write queue and fsync'd before the returned promise resolves. * * Callers (the apply-family tools) should treat a rejection as fail-soft — * the journal is an evidence trail, not a gate on the user's mutation — * and log rather than propagate. See `tools/apply-journal.helpers.ts` in * `@skillsmith/mcp-server` for the call-site convention. */ export declare function appendJournalRecord(input: JournalRecordInput): Promise; //# sourceMappingURL=writer.d.ts.map