fix(763): round 9 — assert the repair's reason positively, not by absence
Build ErsatzTV Image / CI toolchain image resolves (pull_request) Successful in 10s
Build ErsatzTV Image / Delimiter ban (release path) (pull_request) Successful in 22s
PR Gates / CI image pin matches docker/ci (pull_request) Successful in 17s
PR Gates / Docs update reminder (pull_request) Successful in 21s
review-verdict/h10 Review-verdict: MERGEABLE @ 462118d (base: main)
PR Gates / Fix proofs (Proves trailers) (pull_request) Successful in 14s
PR Gates / decisions lifecycle (pull_request) Successful in 23s
PR Gates / Script lint and tests (ruff + pytest) (pull_request) Failing after 14s
Review verdict / Set review-verdict status (pull_request_target) Successful in 7s
Build ErsatzTV Image / Build & test (.NET) (pull_request) Canceled after 1m31s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Canceled after 0s
Build ErsatzTV Image / Functional E2E (curl + UI contracts) (pull_request) Canceled after 0s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Canceled after 0s
Build ErsatzTV Image / API docs in sync (OpenAPI + endpoint index) (pull_request) Canceled after 0s
Build ErsatzTV Image / Formatting (changed .cs conform to .editorconfig) (pull_request) Canceled after 0s
Build ErsatzTV Image / CI toolchain image resolves (pull_request) Successful in 10s
Build ErsatzTV Image / Delimiter ban (release path) (pull_request) Successful in 22s
PR Gates / CI image pin matches docker/ci (pull_request) Successful in 17s
PR Gates / Docs update reminder (pull_request) Successful in 21s
review-verdict/h10 Review-verdict: MERGEABLE @ 462118d (base: main)
PR Gates / Fix proofs (Proves trailers) (pull_request) Successful in 14s
PR Gates / decisions lifecycle (pull_request) Successful in 23s
PR Gates / Script lint and tests (ruff + pytest) (pull_request) Failing after 14s
Review verdict / Set review-verdict status (pull_request_target) Successful in 7s
Build ErsatzTV Image / Build & test (.NET) (pull_request) Canceled after 1m31s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Canceled after 0s
Build ErsatzTV Image / Functional E2E (curl + UI contracts) (pull_request) Canceled after 0s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Canceled after 0s
Build ErsatzTV Image / API docs in sync (OpenAPI + endpoint index) (pull_request) Canceled after 0s
Build ErsatzTV Image / Formatting (changed .cs conform to .editorconfig) (pull_request) Canceled after 0s
A sixth cold review found everything in round 8 clean except one line, and it
is the rule this branch keeps rediscovering: the test pinned the new
`raced_why` only by asserting the ABSENCE of the borrowed wording. Measured —
replacing the string with `zzz` left the suite green while an operator would
get `::error::… — zzz.` beside a sticky sentinel. The sibling test 330 lines
away states the rule and follows it; this one did not.
Now asserted positively, with the em-dash and full stop discriminating the
`::error::` reason from the `::warning::` text that continues ", which cannot
be true". The `zzz` mutation reddens it.
Three nits from the same review, all verified by execution rather than reading:
- the earlier fixture's row was excluded by the strict `> $since` because the
mark became its OWN id, not because it sat below the mark.
- the predecessor comment said `main` "warned only on `null`". True of the two
EMPTY shapes being contrasted; an empty body and a non-array object warned
as well. Scoped.
- `docs/ci-cd.md` and the record described the `::error::` as a two-way split
(found vs unverifiable). Round 8's whole argument is that a complete read
returning an IMPOSSIBLE answer is a third case, not a variety of the second
— which is the operator-facing point, since it decides whether to go looking
for an API failure that never happened. Both now say three.
The review re-verified, by comment-stripped diff, that round 8 changed no
executable line beyond the `raced_why` string and the if/elif restructure, and
independently reproduced both inertness measurements and the `origin/main`
predecessor behaviour.
Verification: `scripts/tests` 1097 passed, 2 skipped; decisions_validate and
build_decisions_catalog --check exit 0.
refs #763
Decisions-Edit: yes
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1332,7 +1332,8 @@ jobs:
|
||||
# `raced=0` — a green concluded from a list that cannot be real — on the one path whose
|
||||
# failure direction is toward SUCCESS, and silently, since the walk itself reports
|
||||
# success. The predecessor was not better in the way it first appears: its
|
||||
# `jq -e 'type == "array"'` gate ACCEPTED `[]` and warned only on `null`, so the `[]` half
|
||||
# `jq -e 'type == "array"'` gate ACCEPTED `[]` and, of the two empty shapes, warned only
|
||||
# on `null` (an empty body and a non-array object warned too), so the `[]` half
|
||||
# of this fail-open was already unlogged on `main`. What is new is that the paged walk
|
||||
# additionally reports such a read as a SUCCESS, which is why the rejection lives here.
|
||||
#
|
||||
|
||||
+5
-2
@@ -1648,8 +1648,11 @@ well-formed "no statuses exist" is not retried (the body is valid), so accepting
|
||||
asked whether ANY row sat above the mark, which an unrelated newer row satisfied; this asks only whether
|
||||
the list is empty, which no unrelated row can produce.
|
||||
|
||||
The `::error::` distinguishes a verdict actually found from an unverifiable read; the sentinel
|
||||
*description* stays generic, because the classification recognises it as a fixed point.
|
||||
The `::error::` names its own cause, and there are three: a verdict actually **found**; a read that
|
||||
could not be **completed**; and a read that completed but returned an **impossible** answer. The third
|
||||
is not a variety of the second — an operator holding a sticky sentinel needs to know whether to go
|
||||
looking for an API failure that never happened. The sentinel *description* stays generic, because the
|
||||
classification recognises it as a fixed point.
|
||||
|
||||
Three properties of this workflow are security-relevant and are **structurally** asserted by tests in
|
||||
`scripts/tests/test_pr_changed_files.py` — those tests pin the workflow's shape, which is not the same
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1153,8 +1153,9 @@ if "/statuses/" in url:
|
||||
#
|
||||
# NO RACED VERDICT IS PLANTED, deliberately. An earlier shape appended one to dramatise
|
||||
# the stakes, and it was inert twice over: unconditionally it also joined the PRE-write
|
||||
# read and lifted the mark above itself, and gated to the post-write read it is never
|
||||
# served, because page 1 answers `null` before any row reaches the wire. A row the test
|
||||
# read, which set the mark to its OWN id — the strict `> $since` then excluded it — and
|
||||
# gated to the post-write read it is never served at all, because page 1 answers `null`
|
||||
# before any row reaches the wire. A row the test
|
||||
# cannot observe is decoration that reads as coverage. What is actually under test is
|
||||
# narrower and sufficient: a response asserting an empty history for a sha this job wrote
|
||||
# to must not be accepted as proof that nothing raced.
|
||||
@@ -3887,6 +3888,14 @@ def test_an_EMPTY_post_write_history_is_not_evidence_that_nothing_raced(tmp_path
|
||||
assert "was overwritten" not in log, (
|
||||
f"an unverifiable read was reported as an overwritten human verdict:\n{r.stdout[-900:]}"
|
||||
)
|
||||
# THE REASON IS PART OF THE FIX, so it is asserted POSITIVELY. An absence assertion alone leaves
|
||||
# `raced_why` unpinned — any string at all, including a placeholder, satisfies it while the
|
||||
# operator gets a sticky sentinel explained by nothing. The em-dash and full stop discriminate the
|
||||
# `::error::` reason from the `::warning::` text, which continues "…, which cannot be true".
|
||||
assert "— the status history came back empty after this job posted to it." in log, (
|
||||
"the repair did not report its own reason; the ::error:: carries whatever `raced_why` held "
|
||||
f"and nothing pins it:\n{r.stdout[-900:]}"
|
||||
)
|
||||
# The walk COMPLETED here, on a validated terminator — the answer was impossible, not unreadable.
|
||||
# Borrowing the unreadable-history wording would send an operator staring at a sticky sentinel
|
||||
# looking for an API failure that never happened.
|
||||
|
||||
Reference in New Issue
Block a user