test: the commit check starts every request clean, and the fence docs claim what it holds

The test's own writes are committed before a request, so a handler's Core DML can no longer hide
in a transaction the test had already opened. The entry-point probe answers on a marked line the
API's logging cannot mix into. A listed commit whose function no longer commits fails the fence.
CLAUDE.md and the backend README now name what an AST cannot see; the route-commit tests no longer
claim their read-back holds the commit.
This commit is contained in:
2026-10-20 01:56:31 +02:00
parent c5f121139b
commit 6ea750a698
6 changed files with 59 additions and 21 deletions
+8 -8
View File
@@ -119,17 +119,17 @@ def _request_dep(db, unfinished: list[str]):
and the suite stays green over a handler that forgot to commit (deep review, debt burn). So a
request that ends normally with a write it did not commit — flushed, or still only staged — is
recorded, and the test fails on it at teardown. Only the ROOT transaction's end clears it: a
savepoint released inside the handler commits nothing. The test's own staged rows are flushed before the request starts — they are the
test's business, not the handler's. A request that raises is rolled back, as production's
savepoint released inside the handler commits nothing. What the test itself staged or wrote is
committed before the request starts — it is the test's business, not the handler's, and a
request then begins with no write open, so any write left at its end is the handler's. A request that raises is rolled back, as production's
`close()` rolls it back: without that, what a failing handler flushed but never committed stayed
readable to the rest of the test — the one state production cannot be in (an issue created
on the tracker before a failed upload was kept only by an explicit commit, and nothing saw it
missing)."""
def dep(conn: HTTPConnection):
db.flush()
db.commit()
state = {"dirty": False}
before = _write_xact(db)
def flushed(session, ctx):
state["dirty"] = True
@@ -145,10 +145,10 @@ def _request_dep(db, unfinished: list[str]):
yield db
staged = db.new or db.deleted or any(db.is_modified(o) for o in db.dirty)
# Core DML (`db.execute(update(...))`) fires no flush and stages nothing; the database
# itself says whether a write is open — a transaction that wrote and was not committed
# holds an id it did not hold when the request began (see `release_read_connection`). A
# row lock (`FOR UPDATE`) takes one too: the handler ends what it locked.
core_dml = (after := _write_xact(db)) is not None and after != before
# itself says whether a write is open — the request began with none, and a transaction
# that wrote and was not committed holds an id (see `release_read_connection`). A row
# lock (`FOR UPDATE`) takes one too: the handler ends what it locked.
core_dml = _write_xact(db) is not None
if state["dirty"] or staged or core_dml:
unfinished.append(f"{conn.scope.get('method', 'WS')} {conn.url.path}")
except Exception: