Skip to content

receipt: nothing distinguished passed from never ran -- and four dumps claim records nobody has - #99

Merged
PipFoweraker merged 2 commits into
mainfrom
feat/push-receipt-check
Aug 29, 2026
Merged

PipFoweraker merged 2 commits into
mainfrom
feat/push-receipt-check

Conversation

@PipFoweraker

Copy link
Copy Markdown
Owner

Three things, all found by building the first one. Green: all 31 gating checks pass.

1. C5, built (check_push_receipt.py)

Your sealed Workshop 2 position, merged yesterday as #97, named this and nothing was built for it:

main has not been CI-verified for 69 hours, and the reason is not that a check failed. Two merge commits produced NO check runs at all. Every surface a reader consults shows green, because green is what the previous run said and nothing distinguishes "passed" from "never ran".

Absence is the failure mode. A workflow can fail to start in ways that produce no artifact: a YAML error above the trigger, a disabled workflow, a skipped merge commit, an outage, a billing stop. Every tool that reads the last conclusion is blind to all of them.

The check reads which workflows ought to run on push from the committed .github/workflows/, and whether they did from the GitHub API, against one exact SHA. Two sources, neither able to make the other agree — pdoom1#1075, both clauses. The inverted form is asking the API what ran and asserting those passed, which cannot see a workflow that never started and so passes exactly when it should fail.

It refuses to run inside GitHub Actions (exit 2). That refusal is load-bearing: a receipt check running as a workflow step is a system reporting on its own liveness, and the run that would prove absence is the run that did not happen. Invoke from a seat or a cron.

Verified live: exit 0 on the current tip, exit 1 on an old commit with no Data Integrity run, exit 2 under GITHUB_ACTIONS=true.

The first draft was wrong in this repo's characteristic way. It compared workflow names from the YAML against job names from commits/<sha>/check-runsData Integrity vs Assert data and pipeline invariants — and reported both workflows missing on a commit that had run both. Caught by running it, not reading it. The mismatch is now a test case, because a receipt check that cries wolf gets muted and a muted check is what this replaces.

2. The corpus-review sitting could not start

arxiv_abstracts/dumps/2026-08-24_010736/_metadata.json is committed, says "record_count": 150, and has no data.jsonl beside it. Re-fetched from the ids already in the frame: 150 of 150, 0 missing. The sample is byte-identical, which is the seed doing its job.

The frame's created stamps are deliberately not updated to today. The draw preceded the fetch by six days and that ordering is the frame's whole evidentiary value.

Also fetched the full description queue: 1,129 of 1,129. Notable side-effect — the coercion guard from #95 reports abstracts with a character ASCII would DELETE: 0 across 1,129 real arXiv abstracts, which is decent independent evidence that the new map is wide enough.

3. Writing the check turned three cases into eight

dump claims on disk
alignment_research/dumps/2025-12-24_063313 6,549 absent
funding_sources/sff/dumps/2025-10-30_225651 3 absent
mit_airr/dumps/2026-07-25_053210 null absent
arxiv_abstracts/dumps/2026-08-24_010736 150 absent

The alignment_research dump is the raw provenance for the 1,166 bulk records that are 97.7% of the served timeline. It is not tracked and not on this machine. That is the gap #89 named from the other side — "the serveable-zone file feeding 97.7% of the corpus has no dump behind it" — and this is the measurement of it. The funding_sources row is #94's subject arriving through a different door.

REPORTING, not gating. Four predate the rule and I will not invent a regeneration command for a dump I did not fetch. It is wired into check_all anyway rather than left unrun, because a checker nothing invokes is this estate's most-repeated failure — check_claims.py and check_estate.py both run correctly and are run by nothing. Promote to gating once the four are declared or tombstoned.

The gitignore excluding these data files is correct; the problem is that a deliberate exclusion and a fetch that never happened look identical on a fresh clone.

Pip Foweraker and others added 2 commits August 30, 2026 07:14
…thing does

C5 from this seat's sealed Workshop 2 position, merged yesterday as #97 and
unbuilt since 2026-08-09:

    main has not been CI-verified for 69 hours, and the reason is not that a
    check failed. Two merge commits produced NO check runs at all. Every
    surface a reader consults -- the Actions tab, `gh run list`, the last
    recorded conclusion -- shows green, because green is what the PREVIOUS run
    said and nothing distinguishes "passed" from "never ran".

Absence is the failure mode. A workflow can fail to start for reasons that
produce no artifact at all: a YAML error above the trigger, a disabled
workflow, a skipped merge commit, an outage, a billing stop. Every tool that
reads the last conclusion is blind to all of them.

check_push_receipt.py reads which workflows OUGHT to run on push from the
committed .github/workflows/, and whether they DID from the GitHub API,
against one exact SHA. Two sources, neither able to make the other agree with
it -- the pdoom1#1075 rule, both clauses. The inverted form is asking the API
what ran and asserting those passed, which cannot see a workflow that never
started and so passes precisely when it should fail.

IT REFUSES TO RUN INSIDE GITHUB ACTIONS, exit 2. That is load-bearing rather
than hygiene: a receipt check executing as a workflow step is a system
reporting on its own liveness, and the run that would prove absence is the run
that did not happen. Invoke it from a seat or a cron.

The first draft was wrong in the way this repo keeps finding. It compared
workflow names from the YAML against JOB names from commits/<sha>/check-runs
-- "Data Integrity" against "Assert data and pipeline invariants" -- and
reported both workflows missing on a commit that had run both successfully.
Caught by running it rather than by reading it. The fix is the actions/runs
endpoint, and the mismatch is now a test case, because a receipt check that
cries wolf gets muted and a muted check is what this replaces.

Verified against live main: exit 0 on the current tip, exit 1 on an old commit
with no Data Integrity run, exit 2 under GITHUB_ACTIONS=true.

The live check cannot be gated -- it needs the network and a token, and
gating it inside CI is the exact thing it refuses to do. Its decision logic is
offline and deterministic, so tests/test_push_receipt_gate.py stubs the API
and gates that: 11 cases, 3 must-not-fire, 6 must-fire, plus the refusal and
the name-mismatch regression.

Also in this commit: the corpus-review sitting can actually start. Its
2026-08-24 abstract dump was a committed _metadata.json claiming
"record_count": 150 with no data.jsonl beside it, so the tool had nothing to
show. Re-fetched from the ids already in the frame -- 150 of 150, 0 missing --
and the sample is byte-identical, which is the seed doing its job. The frame's
`created` stamps are deliberately NOT updated to today: the draw preceded the
fetch by six days and that ordering is the frame's whole evidentiary value.

Refs pdoom-data#97 (C5), pdoom-data#98.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VCAwQ2dTCtpR8rTrEfv5ee
…t for

Found while fixing the corpus-review sitting, and it is wider than that one
dump. data/raw/arxiv_abstracts/dumps/2026-08-24_010736/_metadata.json is
COMMITTED, says "record_count": 150, and has no data.jsonl beside it. The
metadata asserted 150 records; zero existed; the sitting had nothing to show
and nothing noticed, because nothing compares a dump's claim to its contents.

The gitignore excluding these data files is correct and deliberate -- real
arXiv abstracts carry mathematics and author names the ASCII gate would reject.
But an intentional exclusion and a fetch that never happened look IDENTICAL on
a fresh clone: a metadata file claiming N records with nothing next to it,
either way. So the rule is that a tracked dump either ships its data or its
metadata says in one field how to reproduce it, and the two cases become
distinguishable by reading.

Writing the check turned three cases into eight, and one of them matters more
than the one I was chasing:

    alignment_research/dumps/2025-12-24_063313   claims 6549, absent
    funding_sources/sff/dumps/2025-10-30_225651  claims 3,    absent
    mit_airr/dumps/2026-07-25_053210             claims null, absent
    arxiv_abstracts/dumps/2026-08-24_010736      claims 150,  absent

The alignment_research dump is the raw provenance for the 1,166 bulk records
that are 97.7% of the served timeline. It is not tracked and it is not on this
machine. That is the same gap pdoom-data#89 named from the other side -- "the
serveable-zone file feeding 97.7% of the corpus has no dump behind it" -- and
this is the measurement. The funding_sources one is pdoom-data#94's subject
arriving through a different door.

REPORTING, not gating. Four of the eight predate the rule and I will not invent
a regeneration command for a dump I did not fetch -- that is the guess this
repo keeps paying for. It is wired into check_all anyway rather than left
sitting unrun, because a checker nothing invokes is the estate's most-repeated
failure: check_claims.py and check_estate.py both run correctly and are run by
nothing. Promote to GATING when the four are declared or tombstoned.

_templates directories are exempt by name: they claim zero records and hold
zero, which is consistent rather than missing.

Declared for the two dumps fetched today, with the exact commands that
reproduce them.

Refs pdoom-data#94, pdoom-data#89.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VCAwQ2dTCtpR8rTrEfv5ee
@PipFoweraker
PipFoweraker merged commit c257e58 into main Aug 29, 2026
4 checks passed
@PipFoweraker
PipFoweraker deleted the feat/push-receipt-check branch August 29, 2026 23:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant