The fixture held 10,000 orders. A cleanup diff deleted the filter and still looked calm in review. The remote parser accepted the file, because a bare select is legal SQL.
The laptop query had been written to return 37 rows. The box returned every row. That gap is the incident these notes reconstruct.
These notes are a 48-hour lab pass, not a customer outage. They claim no measured saving on any plan. Counts below are contracts of the fixture. Run them if you want the same shape of failure, and do not treat them as a benchmark of a hosted product.
Hour 0 was a single file, orders_filter.sql, in a scratch repository. The predicate was plain: status paid, and a created-at bound at the start of 2026. A simplify suggestion, the sort a model produces when the prompt says to clean the query, removed both conditions and left the column list.
Eye review nearly accepted it. The projection was unchanged. The risk sat in the lines that had vanished, the way a spell-checker accepts a sentence after the subject is deleted.
The first gate was local and dull. A PostgreSQL 16 client could EXPLAIN the original file against a disposable fixture. It could also explain the simplified file. Both exit codes were zero.
A green explain is a weak witness. It proves the text parses for that binary. It does not prove the text still names the same rows.
Hour 6 copied the two files to a second shell. That shell was the free server option the operator described for this draft, used here only as a second environment with its own PATH and working directory. Disclosure: This article was prepared as part of MonkeyCode's product outreach. The move was meant to expose drift, not to grade a vendor.
The version probe did not assume anything about that shell's image. These notes pinned a local container to PostgreSQL 14 so the gap with the laptop's 16 client would be visible, and that pin is a lab choice rather than a product fact. A MERGE statement, which PostgreSQL added in version 15, failed on the pin with a syntax error. The missing predicate did not error on either client.
These notes name no model, no token allotment, no machine size, and no rental period. Those facts were not verified here, and they are the first claims that rot.
Free model access, as supplied by the operator, was used only to propose the simplify diff. The useful property was not the brand on the suggestion. It was that the suggestion stayed untrusted until a local command failed the change.
The artifact is a predicate gate small enough to read in one sitting. It is a proposal, labeled as such, and it is not a SQL parser. It will not understand dynamic strings, ORM builders, or a filter that lives only inside a join.
The seed is part of the fixture, and it is destructive on purpose. Run it only against a database you created for this lab. A shared orders table is not a scratch pad.
-- seed_orders.sql
-- Lab fixture only. Drops and reloads a scratch table.
DROP TABLE IF EXISTS orders;
CREATE TABLE orders (
id int PRIMARY KEY,
status text NOT NULL,
created_at date NOT NULL
);
INSERT INTO orders (id, status, created_at)
SELECT g,
CASE WHEN g <= 37 THEN 'paid' ELSE 'open' END,
CASE WHEN g <= 37 THEN DATE '2026-01-02' ELSE DATE '2025-12-01' END
FROM generate_series(1, 10000) AS g;
-- orders_filter.sql (before)
SELECT id, status
FROM orders
WHERE status = 'paid'
AND created_at >= DATE '2026-01-01';
-- orders_clean.sql (after a simplify pass)
SELECT id, status
FROM orders;
#!/usr/bin/env python3
"""Lab gate: fail if a top-level WHERE disappears. Not a SQL parser."""
import pathlib
import re
import sys
def where_body(text):
stripped = re.sub(r"/\*.*?\*/", "", text, flags=re.S)
stripped = re.sub(r"--.*?$", "", stripped, flags=re.M)
match = re.search(
r"\bwhere\b(?P<body>.*?)(;|\Z)",
stripped,
flags=re.I | re.S,
)
if not match:
return ""
return re.sub(r"\s+", " ", match.group("body")).strip()
def main():
before = where_body(pathlib.Path(sys.argv[1]).read_text())
after = where_body(pathlib.Path(sys.argv[2]).read_text())
candidate = pathlib.Path(sys.argv[2]).read_text()
if before and before != after:
print("predicate changed")
print("before:", before)
print("after:", after or "<missing>")
return 1
if re.search(r"\b(drop|truncate|delete)\b", candidate, re.I):
print("destructive verb in candidate; require a waiver file")
return 2
print("predicate gate passed")
return 0
if __name__ == "__main__":
sys.exit(main())
Run the gate from the repository root so the paths are the files you hashed, not cousins left in an editor buffer.
python3 check_predicate.py orders_filter.sql orders_clean.sql
echo "exit=$?"
On the simplified candidate the expected line is predicate changed and the expected status is 1. A status of 0 on that pair means the gate is the broken component. Fix the gate before you trust it with a real diff. That inversion, treating a surprise pass as a defect in the check, is the habit worth keeping.
Hour 18 added a context capture so a later reader can see which binary accepted the text. This is a lab note, not an inventory of a fleet.
{
date -u +%Y-%m-%dT%H:%M:%SZ
psql --version
pwd
sha256sum orders_filter.sql orders_clean.sql
} | tee review-context.txt
The hash lines matter more than the timestamp. A review that cannot point at a digest is a conversation. It is not a change record.
On the remote shell the first real failure was not SQL. The job started in /tmp, and the relative path resolved to a file that existed only on the laptop. sha256sum exited non-zero. That is a better failure than a silent read of 10,000 rows.
The pass was repeated only after git rev-parse --show-toplevel and a cd into that directory. A borrowed shell is a borrowed desk. Do not assume the previous occupant left your papers in the same drawer.
Hour 30 placed a row-count oracle beside the text gate. The load is fixed: 10,000 inserts, 37 of which match the predicate. The expected number lives in the repository as a comment a human can argue with. It is not a vibe about enough rows.
-- expect_paid_2026.sql
SELECT COUNT(*) AS paid_recent FROM orders
WHERE status = 'paid'
AND created_at >= DATE '2026-01-01';
-- fixture contract: paid_recent = 37
test -n "$FIXTURE_URL" || { echo "FIXTURE_URL unset"; exit 3; }
psql "$FIXTURE_URL" -v ON_ERROR_STOP=1 -f expect_paid_2026.sql
If FIXTURE_URL is empty, stop. Do not let a client fall through to a default database on the laptop, and do not aim this URL at a store that holds customer rows.
The free server is acceptable only as a place to run a client against data you can delete. Treat its disk as scratch. Assume the operator of the box can see the workspace, and assume the workspace may disappear between sessions. Secrets, dumps, and production connection strings do not belong in that drawer.
What broke, in order, was trust in a green explain, then trust in a relative path, then trust that "simplify" preserves predicates. What held was the digest, the non-zero status from the predicate gate, and the fixture contract of 37 against 10,000. What these notes would repeat is that order. The host is interchangeable.
The sequence is short enough to paste into a job log without becoming a platform. Pin the repository root before any relative read. Hash the before and after files. Refuse the candidate when the WHERE body changes, or when a destructive verb appears and no waiver file sits beside the diff.
Explain both versions with the client you will actually ship. Run the count oracle on the fixture only. Store review-context.txt next to the hashes. A free-model comment can occupy the same log as an opinion, but it does not get a vote equal to the exit status.
Several real changes should not use this gate as their only review. Skip it for production credentials, backups, and any dump that contains personal data. Skip it as the sole check for ORM migrations, for procedures that concatenate SQL, and for files whose restriction lives in a JOIN or a HAVING rather than a WHERE.
The expression in the script will not see those shapes, and a quiet pass would be a lie. Do not treat a free server as durable storage. If free model access or the free server option is missing, capped, or bound by terms you have not read, run the same commands on any other machine. The method does not depend on a product.
Readers who still want to try MonkeyCode's free model access for the review step should read the current terms, then keep the fixture offline from customer data. The gate above is the part worth copying either way.
A waiver, when a predicate removal is intentional, should be a separate file named with the candidate hash, containing one sentence a human can defend in review. The gate can require that file and still print the diff. Silence is not a waiver.
A model calling the shorter query cleaner is not a waiver either. Cleaner and equivalent are different claims, and only the second one belongs in a migration.
By hour 48 the folder held three artifacts worth retaining: the two SQL files, check_predicate.py, and review-context.txt. No latency table was collected. A single lab shell cannot support one, and inventing a table would dress a fixture up as a study.
No model was ranked. The conclusion stays narrow. A remote parser can accept a change that deletes your filter, and a free review pass can be the author of that deletion. The check worth repeating fails closed when the predicate text or the fixture count moves, and it records which binary did the accepting.
Top comments (0)