Don't Golden-File an Agent Patch. Golden-File the Relation.
A recorded expected value is a leak. An agent that can read assert f(x) == y can patch f until that line is green and leave every unlisted input broken. A metamorphic relation does not publish y . It only publishes a constraint the output must keep under a known transform. That is the gate worth automating. Fixtures still matter, but only as seeds. Flaky tests still need a freeze, but the freeze must not cover the relation itself. This article is a proposed layout, not a production case study. No runtime metrics are claimed. The commands and modules below are labeled so they can be copied into a scratch repo and executed against your own function under test. Why snapshots fail as a merge gate Golden files encode one transcript. An agent patch is a search over many transcripts. If the search can see the answer key, the cheapest passing program is a lookup table for the keys in tree. That program is green. It is also wrong on the next customer file. Property-style checks reduce that leak because they do not ship the answer. They still need a seed corpus, a replay runner that the patch cannot edit, and a quarantine file that expires. Mix those three and you get a gate that fails closed when the agent rewrites tests, when a fixture drifts, or when a flake is used to hide a broken invariant. Three relation classes worth encoding first Start with relations you can state in one line. If you cannot state the line, you do not have a gate. You have a recorder. Idempotence. f(f(x)) == f(x) for normalizers, formatters, and canonicalizers. Round-trip. parse(serialize(x)) equals x on the fields you actually guarantee, not on whitespace you do not. Oracle-free comparison. f(t(x)) relates to t(f(x)) for a transform t you control: shuffle independent rows, rename equivalent keys, NFC vs NFD unicode, scale a quantity and its unit together. These are not universal laws. They are hypotheses about your function. Write them down as code. Keep the seed inputs boring. The relation, not the