/** * Gate C post-apply checks (T12344 PR-5; journal spec §3.6 "post-apply-check", * §3.5 Rule 3). * * The apply writes through the write API, never the TypeScript write paths, * so a merge of two ops each valid on its own device can produce a state the * CLI would refuse while no trigger notices. A post-apply check evaluates one * multi-row invariant over the transaction's page (the rows it wrote, plus * the footprint the invariant declares) after the transaction's ops applied, * inside the same frame. A violation rolls the whole transaction back: it * becomes a revivable void plus one `post-apply` conflict per violation. * * Implemented here, on the tables that sync today: * - PAC-01 `task.tree.shape` ({@link checkTaskTreeShape}); * - PAC-15 `apply.preconditions` ({@link checkApplyPreconditions}), which is * checked before a pass, not per transaction. * PAC-03 `task.dependency.graph` is trigger-covered since T12886 * (`tasks_task_dependencies_cycle_guard_*`): a cycle-closing edge is a guard * conflict. The other families stay pending in the write-invariant registry * until their tables join the sync set. * * Read-only. * * @module store/sync/apply/post-apply * @task T12344 */ import type { DatabaseSync } from 'node:sqlite'; /** A row the transaction wrote. */ export interface PageRow { readonly table: string; readonly uid: string; /** * The op could change the row's own type (an insert, or a write of * `type`): only then are its children re-judged, since moving a row never * changes whether its children are allowed under it. */ readonly typeChanged?: boolean; } /** One broken invariant. */ export interface PostApplyViolation { /** The write-invariant registry id (e.g. `task.tree.shape`). */ readonly check: string; readonly table: string; readonly uid: string; readonly message: string; } /** * PAC-01 `task.tree.shape` over the page: for every task the transaction * wrote, no self-parent, no ancestor cycle, a parent whose type may contain * it (saga → epic → task → subtask), and every child still allowed under its * (possibly changed) type. Root rules are left to the domain write paths. * * @param db - The store, inside the apply frame. * @param page - The rows the transaction wrote. * @returns The violations; empty when the shape holds. */ export declare function checkTaskTreeShape(db: DatabaseSync, page: readonly PageRow[]): PostApplyViolation[]; /** * PAC-15 `apply.preconditions`: why no transaction may apply to this store * now, or null. A store whose twin collapse failed refuses every write * (T12535), so applying would half-write the stream. * * @param db - The store. * @returns The reason, or null. */ export declare function checkApplyPreconditions(db: DatabaseSync): string | null; //# sourceMappingURL=post-apply.d.ts.map