import type { ModelFingerprint } from "./fingerprint.js"; /** * Where the proof leaves its record: `crossline.lock`, in the repository, and * committed. * * This was the one design question with a wrong answer that looks right. * `.crossline/` is the obvious home — it already holds `last-run.json` — and it * is exactly wrong, because it is gitignored, and because CI is not the * founder's laptop and production is neither. A fingerprint written to * `.crossline/` on a laptop is not present when the GitHub Action runs; one * written by the Action vanishes with the runner. Whichever machine you pick, * the other one has nothing to compare against, and the answer cannot be "copy * this file over", which is a step, and a step is a defect. * * The thing already synchronised between all three machines is the repository. * So the fingerprint goes in it, next to `crossline.config.json`, as a tracked * file — and it earns its place there twice over: * * - it is a statement *about the schema*, and the schema is in git. The lock * belongs to the same commit as the migration that changed it, for the same * reason `package-lock.json` belongs to the same commit as `package.json`. * - it turns a dropped policy into a diff in the pull request. Nobody reads a * migration for the policy that is no longer there. Everybody reads a * removed line in a lockfile. * * Nothing asks the founder to produce it: a passing `crossline test` writes it, * every time, and their next `git add .` commits it. That is the same motion by * which `package-lock.json` arrives, which is to say no motion at all. * * There is nothing secret in it — table names, policy expressions, grants, and * the roles a request runs as. No rows, no values, no connection string. */ export declare const LOCK_FILE: string; export interface LockFile { $note: string; fingerprint: ModelFingerprint; } export declare function lockPath(cwd: string): string; export declare function writeLock(cwd: string, fingerprint: ModelFingerprint): string; /** * Read the recorded fingerprint, or null when there is none. * * A lock that will not parse, or that was written by a format this build does * not understand, is an error rather than a shrug. Silently treating it as * absent would downgrade the strong claim to the weak one without saying so, * which is the one failure mode this whole feature exists to prevent. */ export declare function readLock(cwd: string): ModelFingerprint | null;