Two independent cold reviews (Codex GPT-5.6 cross-family, and an isolated
Opus agent) converged on the same blocker, which is fixed here along with
everything else they found.
BLOCKER — the mark walk turned a fail-closed case into a fail-open. The
high-water mark gates the post-write race check entirely: `max_id_before=-1`
skips it. Before paging, only a failure of the single page-1 request could
reach that. Requiring a COMPLETE walk newly routed a page-2 hiccup, an
over-cap history, or one malformed id on a later page into the same hole, so
a human rejection racing the write was left green where `main` repaired.
A partial list now still yields a mark: it can only be LOWER than the true
maximum, which makes the check more eager, never blinder. Only a read
returning no rows at all abandons it — the pre-existing #849 gap, unchanged
and now asserted by a test so it stays visible.
WITHDRAWN — the "currency witness". It produced two defects from one
mechanism, which is the signal to remove rather than patch twice: counting
ANY row above the mark does not witness this job's write, so a stale-but-valid
snapshot carrying an unrelated newer row passed while hiding a rejection; and
a schema-valid stale read is not retried, so one such response turned a
transient anomaly into a permanent sentinel. The hazard has no mechanism here
either — Gitea is a single instance with no read replicas. Removing it
restores the pre-change exposure on that path, a non-regression.
Also fixed, each a fail-open with a fixture and an executed mutation:
- `.creator` is type-tested before indexing. `.creator.login` on a non-object
exits jq 5 and `set -e` took the step down after the green was posted and
before the repair. Reproduced by both reviewers.
- the mark is the max over NUMERIC ids only. jq orders strings above every
number, so one `"id": "99999"` passed the numeric gate and inflated the
mark until nothing looked newer.
- an unusable `raced` count now repairs instead of "not acting on it".
- `sort=highestindex` (ASC, measured) so a row inserted mid-walk appends at
the end rather than at position 0 on a page already read. An unknown sort
value silently falls back to DESC, so this is insurance, not load-bearing,
and the comment says so.
- `ph_ok`/`ph_rows` renamed off `read_existing_verdict`'s `st_ok`. No live
bug, but a name collision in a 1400-line step.
Tests the reviews showed were missing, each proved by an executed mutation:
- verdict beyond a SHORT page (a deliberately unfaithful truncated response
— against a faithful double a short page is always the last, so the rule
"terminate only on an EMPTY page" was unobservable)
- pre-write paging failure still yields a usable mark
- pre-write read returning nothing abandons the mark and says so
- a TRANSIENT page failure is retried (the retry was unproven code: every
other error mode fails on every attempt, so disarming it reddened nothing)
- a string id cannot inflate the mark
- a malformed `creator` row does not kill the job
Stub corrections, both the same class as the earlier `[]`-vs-`null` gap: it
served one flat list (so paging was unobservable) and computed its own-post id
with `max()` over mixed str/int, which raised TypeError and made the string-id
test pass because the DOUBLE crashed rather than because the mark was right.
Mutation matrix, all executed, each reddening exactly its named test: retry
disarmed; numeric-max reverted; partial-mark fallback removed; short-page
terminates; page-1-only walk; post-write fail-closed flipped open; jq
type-guard reverted. The unusable-count arm is unreachable by any fixture and
is annotated as such rather than claimed as proved.
Verification: `scripts/tests` 1090 passed, 2 skipped; decisions_validate and
build_decisions_catalog --check both exit 0; terminator, clamp, sort order and
id monotonicity all re-measured live on Gitea 1.27.1.
refs #763
Decisions-Edit: yes
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>