Skip to content
Skip to main content
Novel Systems home
Decision log
D-070August 5, 2026

Publish the DDL, because a count is a claim about a document and the reviewer came for the document

Decided

the four migration files are concatenated, unedited and in application order, into public/schema.sql; check:schema regenerates and diffs on every build; /schema, /migrations and /migrations.sql 308 to it; and both pages that assert something about the database now link to it.

Affects: scripts/build-schema-sql.mjs (new), public/schema.sql (new, generated), package.json (schema:generate, check:schema, both chains), lib/engineering-practice.ts (VERIFY_CHECK_COUNT 16 → 17), scripts/check-links.mjs (NON_PAGE_ROUTES), next.config.mjs (three redirects), app/engineering/page.tsx, app/security/page.tsx.

What produced it. A technical review of task 2 found: "No public CREATE TABLE statements for trades, price_books, margin_floors, cut_rules, quotes. No visible migration history," and "a reviewer can't tell if margin floors are enforced at the DB layer or only in JS."

The second finding was false and answerable in one click — /engineering#schema renders margin_rules_at_or_above_code_floor and quotes_applied_margin_floor_range as SQL extracted from migration 0003, above a paragraph that says exactly this. The reviewer never reached it. Nothing on /security linked there, which is where they were standing when the question occurred to them, and where the isolation pillar asserts FORCE ROW LEVEL SECURITY and a NOBYPASSRLS role in language precise enough to demand a check.

The first finding was true about the artifact. /engineering#schema published an inventory — four migrations, their line counts, tables, indexes, policies and check constraints — and two quoted constraints. It did not publish the DDL, and no address served it.

Why the inventory was not enough, stated generally. A count is a claim about a document. The person counting the rows of a table like that one is, almost by definition, the person who has stopped accepting summaries; handing them a better summary answers someone else's question. D-069 recorded that discoverability failures present as confident negative findings from people who looked. This is the layer below: an artifact that can only be described cannot be checked, and the reviewer who wants to check it will record that it does not exist — which, for their purposes, is the correct finding.

Rejected: `pg_dump --schema-only`. Tidier and worse. It publishes the end state and destroys the order, and the order is the thing under review — whether the floor was a constraint from the start or bolted on afterwards, whether a policy predates the table it protects, whether anything was ever loosened. A dump also discards the migrations' own commentary, and 0003 spends thirty lines explaining why margin_rules may raise the floor and may not lower it. That paragraph is more persuasive than the DDL it introduces.

Rejected: serving it from a route handler that reads the migrations at build time. No committed copy means no drift, which is genuinely better, but it also means the artifact is invisible in review and in git log, and it puts a filesystem read outside the app directory into a build on a platform that traces its inputs. public/openapi.json already settled this shape: generate, commit, and check. Two artifacts with one arrangement between them.

Why the output is byte-stable. No timestamp, no commit sha, nothing that differs between two runs over identical inputs. A generator whose output changes when its input did not cannot be diffed, and a drift check that always fails is deleted within the week — D-032.

The seventeenth verify check. check:schema was broken deliberately in both directions before commit: an edited public/schema.sql reports the first differing line, and a MIGRATION_COUNT that disagrees with the directory listing fails before generating anything. The second guard exists because without it, deleting a migration would quietly shorten the published schema while every other check in the suite stayed green — each one internally consistent with a repository that had lost a file.

What would make this wrong. Three things. If a migration ever needs to contain a credential, a customer identifier, or anything else not publishable, this file stops being safe to generate mechanically and the generator needs a redaction pass — which would be the moment to reconsider publishing at all, because a redacted schema invites precisely the doubt it was meant to remove. If the migration commentary ever starts being written for a public audience rather than for the next engineer, the file will get worse in a way no check can see. And /engineering#schema's rendered inventory and this concatenation are two derivations of one directory; they agree today because both read it, but a third surface that restates a count by hand would break that quietly.