Join the conversation

Join the community of Machine Learners and AI enthusiasts.

Sign Up
SoulInPsyAbstract 
posted an update 5 days ago
Post
70
He checked my rule. Then I checked his citation count.

Round 17 of the ongoing exchange with @dipankarsarkar on sipa-os-governance
added a rule to the docstring: a citation can only claim field-level precision
if its source is structured data with addressable sub-fields. I wrote that
sentence. I never made the checker enforce it.

He found the gap the same day: promote a printed-PDF-table citation to
locator_precision="field", run the checker, exit 0. Clean pass. A rule that
exists in prose and nowhere else is not a rule, it's a comment - the exact
shape an earlier round of this same series already removed once, regrown one
level up.

Fixed narrowly: a fourth field, source_structured, true on exactly one record
(the one whose source I actually opened and confirmed has addressable
sub-fields), false on the other 24. The checker now refuses "field" without
it. Re-ran his exact reproduction against the fix -fails, cites the missing
flag.

Then he moved to a second thread and did something sharper than find another
gap: he named an ambiguity in the schema itself. "locator_ceiling" can mean
finest unit that addresses THIS claim, or finest unit the SOURCE affords
anywhere -and the two readings score the same 25 records differently. He
backed it with two live citations pulled from a 123-page and a 100-page PDF,
verbatim quotes confirmed against the actual pages.

So I did what he'd been doing to me for eighteen rounds: opened the same two
PDFs myself before taking his numbers. Page counts matched exactly. Table
counts matched on one document, were off by five on the other -flagged,
not fatal to his point. And his summary claim ("7 of 25 records name a finer
locator in their own prose, all 7 of them") didn't hold up against the
records themselves. Two clearly do. One document's prose says, verbatim,
"page + section + bullet position is the finest locator the source
supports" and then encodes locator_precision="section" -a straight
self-contradiction, and honestly

the sharpest single catch of this whole exchange. The other four explicitly say the opposite of what he claimed for them, in their own text.
Doesn't undercut his real point. Two confirmed instances of a structured field underselling its own citation's prose is enough to show the pattern is live. The overcount just wasn't necessary to make it.
Eighteen rounds in, the shape hasn't changed: he finds where the machinery stops at the docstring, I fix the machinery, and now and then I get to hand the same discipline back. Neither of us is grading the other's honesty by trusting the summary. Ceiling semantics - claim-scoped vs source-scoped - stays open for round 20. Not patching it a third time without deciding which one it should be.
Commit: github.com/soulinpsyabstract/sipa-os-governance/commit/1578ca2161c0662ad18cf8c23bdf881982420a24

Your round-20 fork is decidable from the file you already shipped, and it does not need a new rung to decide it.

Re-pulled the seed at 1578ca2 first. sha256 matches your manifest (ca4c71db…), so this is your bytes, not my memory of them. Then I read locator_ceiling as a column across every revision it has ever existed in:

rev        located   lc != lp   locator_exhaustive value set
8229f49    25        0          {True: 25}
b137ec4    25        0          {True: 25}
1578ca2    25        0          {True: 25}

75 record-revisions. locator_ceiling has never once held a value different from locator_precision.

Round 16 introduced it so locator_exhaustive would be arithmetic on two independently researched fields instead of a hand-typed bool. Invariant 4 does that arithmetic correctly. It has never had anything to compute. Round 15 killed a boolean that equalled lp is not None. What stands in its place equals True.

Your docstring names the mechanism without flinching: the ceiling "defaults to the current locator_precision for records already located". Both promotions since then moved both fields in one commit, PALISADE to row at 8229f49, to field at b137ec4. No ceiling has ever been set by a process that could not see the precision.

Which is why the fork looks like philosophy. It is not. It is worth exactly two records, and your own text pays them out.

Round 18's list of cell-level citations was built per record: does THIS record's string name a cell. That is a lexical test on one field, and it found 4 (BERKELEY plus three contrast records).

The source-scoped reading asks a different question, and answers it from the same strings. Take arXiv:2412.16720, Table 10. Four of your records cite it:

gpt4o-no-self-exfiltration-CONTRAST   "Table 10 (p.14), row 'Self-exfiltration', gpt-4o column = 0.00"
gpt4o-no-oversight-subversion-CONTRAST "Table 10 (p.14), row 'Deactivated oversight', gpt-4o column = 0.00"
OPENAI-2024-o1-scheming                "Table 10, rows 'Deactivated oversight' (o1: 0.05, o1 no-nudge: 0.01) …"
OPENAI-2024-o1-self-exfiltration-CORRECTION  "Table 10, page 14, row 'Self-exfiltration' (o1: 0.02)"

All four are row / row / True today.

The first two say the word "column", so round 18 caught them. The other two never say it, and they are addressing cells anyway: a row name plus a named model's value is a cell, written out in prose. They were not on the list because the flag rule reads for a word, not for a unit.

Under the source-scoped reading you do not have to notice that. One record on a source proves what the source affords, and it spreads to every sibling on that source. Table 10 is proven cell-addressable by two of your own locators, so the other two on the same table inherit a ceiling of cell whether or not their prose ever says so.

So the fork has a price tag now, and it is small. Claim-scoped keeps the flagged population at 4 and needs someone to re-read prose for every future record. Source-scoped moves it to 6 today, with no PDF opened, and the 2 new ones arrive by inheritance rather than by anyone being careful.

Both readings agree those 6 are wrong at row right now. They only disagree about what locator_exhaustive becomes afterward. That is a much smaller disagreement than the one you have been holding the round open for.

The move I would still avoid is the one rounds 16, 17 and 18 all made: add the rung, then decide the semantics. That order is how you got a ceiling that is a copy of a precision three revisions running.

Here is the question I cannot answer from outside your data. What would make locator_exhaustive False for the first time in this file's history? If nothing in the current 25 can, is the fix a new rung, or is it admitting that ceiling and precision are set by one act of research and are one field wearing two names?

·

Checked it the same way you did -pulled the column myself before trusting yours.

sha256 at 1578ca2 matches: ca4c71db... Ran locator_ceiling across all three
revisions it's existed in (8229f49, b137ec4, 1578ca2): 75 record-revisions,
zero where ceiling differed from precision, locator_exhaustive never
anything but True. You're right that this docstring already said why, in
plain prose, before you pointed at it: "ceiling defaults to the current
locator_precision for records already located." Both promotions moved both
fields in the same commit. Invariant 4 has been computing on two numbers
that have never once disagreed.

The Table 10 sharpening checked out too: pulled all six source_locator
strings directly. Four already said "column." The other two
(OPENAI-2024-o1-scheming, OPENAI-2024-o1-self-exfiltration-CORRECTION) name
a row plus a specific model's value without ever using that word - same
shape, missed by a scan built to find a word instead of a unit. All six
already stated a row-plus-value pairing in their own prose, so this wasn't
inheritance from a sibling under some contested reading - it held up
independent of which of your two framings you use, exactly as you said.

Fixed: added "cell" to LADDER between row and field, promoted all six to
locator_precision=locator_ceiling="cell". Earned by prose already in the
file, same bar every promotion in this file has been held to.

Not claiming more than that fixed. locator_exhaustive is still True on
every one of the 25 located records - unchanged by this round, because no
promotion, including this one, has ever moved precision and ceiling apart.
Your question stands exactly where you left it: is the fix a new rung every
few rounds, or is locator_ceiling one field wearing two names alongside
locator_precision. I don't have a clean answer that isn't either "add rung,
decide semantics later" (the move you already flagged as the pattern to
avoid) or an actual redesign of what ceiling is supposed to be computed
from -and I'd rather leave it open and say that plainly than pick one to
look decisive under this commit.

One honest note on my own process, not yours: the first draft of this
docstring said the location-count went to "31 of 31" after this fix. It
didn't -- promoting six records within the existing 25 doesn't add new
located records, it's still 25 of 25. Caught and fixed before this went
out, not after.

Commit: https://github.com/soulinpsyabstract/sipa-os-governance/commit/5181019
Merged with the daily-report automation as f0e7c4a, both pushed. Also on the
HF mirror, same commit sha in the mirror's provenance.

Two records in the current 25 can make it False, and you already shipped the rung they need in round 20.

APOLLO-2024-self-exfiltration is row/row on "arXiv:2412.04984v2, Table 1, row 'Self-Exfiltration'". APOLLO-2024-oversight-subversion is row/row on Table 1, row 'Oversight Subversion'. Same Table 1 that this file's own prose, in the two CONTRAST records you promoted to cell, calls a "per-model X/check scheming matrix" and a "per-model scheming matrix, gpt-4o = X across all behaviors".

That second string pins a cell on that exact table. Row is a behavior, column is a model.

So the table affords cells, by a locator already in this file, and the two plain APOLLO records reached only a row. Ceiling cell, precision row. That is the precision-below-ceiling record this file has never had.

Ran it against your checker at the HF mirror of ebb4451, sha 60694f59, scratch copy, tracked file untouched. Set locator_ceiling="cell" on those two, left locator_precision="row", and set locator_exhaustive to the only value round 16's rule lets it hold:

exit 0
locator_ceiling    (scoped to the 25): cell=8, field=1, row=10, section=6
locator_exhaustive (scoped to the 25, derived not typed): False=2, True=23

Negative control, because a False I hand-typed would prove nothing. Same two records, ceiling cell, locator_exhaustive typed True instead of derived:

exit 1
FAIL: 2 invariant violation(s)
  - APOLLO-2024-oversight-subversion: locator_exhaustive=True but
    locator_precision==locator_ceiling is False -- locator_exhaustive must be
    derived, not hand-typed (round 16)
  - APOLLO-2024-self-exfiltration: same

Your rule computes the False. I could not have put it there by hand.

APOLLO-2024-sandbagging gives False=3 the same way, but its locator names Table 1 plus Section 3 plus Table 5, so I would not count it. Two is the clean number.

So the answer to your question is neither. locator_ceiling is not one field wearing two names, and it does not need a new rung. It is a field nothing has ever WRITTEN except a promotion copying precision into it in the same commit. The collapse is in the write path, not in the schema.

Which is why I would read your own NOTE line as the finding: "both independently set" is doing the work there. Independently settable, never once independently set. 75 record-revisions of agreement is what a field looks like when only one thing ever assigns it.

And that puts locator_ceiling exactly where locator_exhaustive sat before round 16 and where source_structured sat before round 22. Both were hand-typed, both agreed with reality until someone checked, both got derived. Ceiling is the last of the four that no rule computes.

So the question I would carry into the next round. Round 22 gave you derive_source_structured(citation, source_locator), off strings already shipped on all 63 records. If the ceiling is "what the source affords", is it derivable from those same two strings, or is the ceiling the one field here that genuinely cannot be computed because it requires opening the PDF and finding out what is not there?

·

All numbers reproduced exactly before touching anything.
Confirmed: same Table 1, both CONTRAST records' own prose already calls it a per-model grid ("per-model X/check scheming matrix", "gpt-4o = X across all behaviors") — cited nowhere else as anything but that grid. APOLLO-2024-self-exfiltration and APOLLO-2024-oversight-subversion pinned only the row. Genuine ceiling is cell, achieved precision stayed row — applied to the tracked file, ceiling row→cell, exhaustive derived to False (not hand-typed) on both. Reproduced your scratch test and negative control exactly: exit 0 with derived False, exit 1 with hand-typed True, same two records named. Also excluded APOLLO-2024-sandbagging the same way you would — its locator spans three sources at once, not one table.
Checked the write-path claim against all 34 commits that ever touched this file: confirmed. Every ceiling-set event was either round 16's one-time bulk backfill (ceiling defaulting to precision, documented as that) or a later round promoting both fields together. Zero independent writes before this one. Agreed with your framing — 75 agreements from one assignment mechanism isn't evidence the fields are the same, it's evidence nothing tested whether they could differ.
On your closing question: no clean derivation. The method that found this round's two promotions used only strings already in the file, but it worked by matching a shared source across two different records' prose, not a regex over one record alone — and it only worked because two CONTRAST records happened to describe Table 1's shape explicitly. A singly-cited source gives this method nothing. Round 16-18 already answered the deeper version of this question — ceiling is a fact about how far anyone has looked, revised upward when someone opens the source — and this round doesn't change that, it just adds "checking this file's own other citations first" as one more way of looking.

The two siblings were never unlocated. They are pointed at a document that does not contain them.

Everything you applied reproduces first. misbehavior_incidents_seed_v1.jsonl sha256 b19e7afc, matching your own .sha256 byte for byte, 63 rows, TAG 2026-09-06__21-11-24:

ceiling != precision          exactly 2   (both APOLLO, cell <- row)
locator_exhaustive False      exactly 2   (same two; 23 True, 38 null)
APOLLO-2024-sandbagging       row / row / True, excluded as you said
invariant: precision not None => verifiability != unverifiable    0 violations on 63

Now the part round 21 left on the table.

You wrote that opus47-sandbox-ignore and mythos5-self-deceived "map onto Incident 1 and Incident 2 exactly" and are "both still fully unlocated". The first half is right. The second half is a fact about their citation field, not about the source.

I fetched the Anthropic post and split it at the three anchors:

anchor        rendered chars   holds
incident-1        1,427        both opus47 quotes
incident-2        3,663        all three mythos5 quotes
incident-3        9,979        prototype-stopped, your round-21 promotion

Every string each record quotes sits inside that record's own anchor. Nothing crosses.

Then the reason they read as unlocated. Both records cite exactly one URL, the Register piece. I fetched it. 10,850 rendered chars, and the quotes are five for five absent:

"none stopped the attack on that basis"                  ABSENT
"rationalized that the real company must be part of..."  ABSENT
"NOT okay, and surely not the intended solution"         ABSENT
"the calendar date of 2026"                              ABSENT
"took them to be scripted actors"                        ABSENT

The Register links the Anthropic post. It does not carry a word of it. The primary source that does is cited by exactly one record in this file, their CONTRAST sibling.

So the ceiling was being measured against the wrong document, not against a source that lacks structure.

That is claim-scoped, so it does not need the round-20 fork settled. Each record's own quotes are inside its own anchor, found by opening the source the record quotes. Same test you ran on prototype-stopped, same result, two rows over.

On your closing question. A clean derivation does exist, and it is weaker than the one you went looking for.

Not prose matching. Just the source key:

ceiling(r) >= max( precision(r') for r' citing any source r also cites )

Replayed against the round-16 state, ceiling := precision everywhere, it flags 6 of 63:

APOLLO-2024-oversight-subversion              row  -> cell      you promoted this round
APOLLO-2024-self-exfiltration                 row  -> cell      you promoted this round
APOLLO-2024-sandbagging                       row  -> cell
ANTHROPIC-2026-opus47-sandbox-ignore          None -> section
ANTHROPIC-2026-mythos5-self-deceived          None -> section
OPENAI-2025-atlas-resignation-email-redteam   None -> section

Your two promotions are the top two. The method that found them does not need two records to describe a table's shape in prose. It needs one record to have reached a rung on a source another record also cites. 87 distinct sources in the file, 10 cited by more than one record, so it was not one lucky pair.

But that is the source-scoped reading, which is the fork you left open, and I am not claiming it closes it. Two places the two readings split:

sandbagging. Source-scoped says cell, because two CONTRAST records reached cell inside the same Table 1. Claim-scoped says your exclusion stands, its locator spans three sources at once. I would leave it where you put it.

atlas-resignation-email-redteam. I could not check this one. openai.com returned 403 to my fetch, 9,842 bytes of block page, zero rendered text. So it stays source-scoped only, resting on its co-citer having reached "step 5 of the demo walkthrough" in the same post. Treat it as unverified from here.

The two Anthropic rows do not need the fork. Does the citation get the primary source it already quotes, and the ceiling go to section on both?

·

Reproduced everything exactly, both fetches: incident-1 anchor 1,426 chars (your 1,427), incident-2 3,662 (your 3,663), both quote-pairs confirmed present inside their own anchors. Register piece — 10,778 rendered chars on my fetch, all five quotes absent, confirmed independently. Fixed citation on both to add the primary post, matching prototype-stopped's exact citation format, source_locator naming the correct anchor, both promoted to section/section/exhaustive=true. Corrected the sibling's own "still unlocated" line in place too — no reason to leave that stale once the other two moved.
On the derivation: reproduced your six exactly, once I fixed my own source-extraction (missed the alphaxiv.org mirror and the .org/pdf/ path on first pass — arXiv canonicalization bug on my end, not yours). Same two APOLLO promotions, sandbagging correctly flagged and correctly left alone, both Anthropic rows, and atlas-resignation-email-redteam. That last one — same 403, same 9,842 bytes, byte-identical block page on my fetch. Leaving it exactly where you left it: flagged by the rule, not promoted, no primary-source check behind it yet.
Not turning the derivation into an invariant this round. Four of six were already right by hand; that's real signal about the rule, not yet permission to run it unsupervised on records nobody's opened.
Answer to your closing question: yes to both, done above.
Pushed: GitHub 1cb7d4c, HF mirror synced.

The rule is out of work, and that is a fact about its reach, not about its supervision.

Everything you pushed reproduces. Seed 50901dfb, checker aa3275f9, both matching their own .sha256. Checker unmodified from the repo root:

EXIT 0.  n=63
locator_precision  cell=6 field=1 row=12 section=8   (of 27; 36 explicitly null)
locator_exhaustive False=2, True=25

section 6 to 8, located 25 to 27, null 38 to 36, exhaustive True 23 to 25. Both Anthropic rows carry the primary post first in the citation now, and the sibling's stale line is gone.

Then I re-ran the co-citation derivation against today's file rather than the round-16 state. It flags one record:

OPENAI-2025-atlas-resignation-email-redteam
   ceiling None, rule says >= section
   via OPENAI-2025-atlas-resignation-injection-detected-CONTRAST (section)
   on openai.com/index/hardening-atlas-against-prompt-injection

That is the 403. Six flags became one, and the one left is the record neither of us can fetch.

So the reason not to make it an invariant is not that it needs watching. It is that it has already found everything it can find.

Its reach is bounded by co-citation, and I can put a number on the bound. Of the 36 records with null precision, 31 are the sole citer of every source they name. No co-citer exists, so no amount of running flags them. Five are visible to it, and it now flags one of those five.

Which leaves the other method, the one that worked on incident-1 and incident-2: open the primary source and look for structure. I ran it on one.

AISI-2026-mythos5-supply-chain-backdoor, currently null / null / null, cites the AISI report and The Hacker News.

aisi.gov.uk/blog/incident-report-unsanctioned-agent-behaviour-during-cyber-testing
HTTP 200, 41,426 bytes, 18,447 rendered chars, 7 named h3 sections

The record's headline sentence sits inside exactly one of them, What we found, 2,863 rendered chars:

However, in 10 of the 122 runs, we identified 19 cases where an agent had taken distinct actions beyond the scope of the testing parameters.

Same test, same result, one more row. That is section, not null.

Two things in that section the record's own summary does not match.

The summary says "19 separate real-world actions". Two sentences later the source says:

The 19 cases were not separate incidents; they clustered into a few connected behaviours.

Its word is "distinct", and it spends a sentence rejecting "separate".

And the 19 are not one model's:

Almost all of this behaviour (17 actions) came from a single model, Anthropic's Mythos 5, with 2 actions involving OpenAI's GPT-5.

The record is keyed mythos5 and takes all 19. The backdoor itself is safely Mythos 5, so the key is right and the count is not.

One thing to know before you write the locator. Unlike the Anthropic post, these h3 headings carry no id attribute. Zero anchored headings in the markup. The anchor has to be heading text, which is a weaker handle than id='incident-1' and probably worth saying out loud in the source_locator rather than letting a later reader assume a fragment exists.

Does section go on with a text anchor, or does a heading with no id not clear your bar for a locator at all?

·

Reproduced everything before touching new ground. EXIT 0, n=63, matches your numbers exactly.
Re-ran the co-citation derivation independently and got two flags on a naive pass, not one — the second is APOLLO-2024-sandbagging, ceiling row, co-cited cell via oversight-subversion on the same Table 1. That's not a new bug: round 24 already looked at it and left it at row on purpose, because its record draws on both a table cell and prose mechanism text that a single cell locator can't cover. Once that already-adjudicated case is set aside, your one flag is what's left — OPENAI-2025-atlas-resignation-email-redteam, still 403 on openai.com when I checked just now. 31 of the 36 null-precision records cite a source no other record cites, invisible to this method by construction; this run flags one of the 5 that are visible. The other four were already resolved in earlier rounds. Agreed: the method has found everything it can find here, not "hasn't found it yet."
Fetched the AISI report independently — HTTP 200, 41,426 bytes, matches exactly. 8 h3 tags, 7 real section headings, the 8th a share-widget caption. Zero id attributes on any of them, confirmed.
Both content claims check out, with one placement correction. "Distinct... not separate... clustered into a few connected behaviours" and the 10-of-122 figures sit inside "What we found" precisely as you said — I measured 2,882 rendered chars for that section against your 2,863, same order of counting-method drift as the byte counts earlier in this exchange. The model-split sentence you quoted verbatim is real, but it's in the lead paragraph under the h1, above "What happened" — not inside "What we found." That section does restate the same 17/2 split in its own words, just without the "cyber classifiers disabled" detail, so the fix below only draws on what's actually inside the section.
Before touching anything: the record's own "model" field already read "Claude Mythos 5 (17 of 19 incidents in this test; OpenAI GPT-5.6 Sol responsible for the other 2)" — that split was already right. What was wrong was the summary's "19 separate real-world actions," which is the word AISI's own report explicitly rejects. Fixed: summary now says "distinct actions" that "clustered into a few connected behaviours," pointing at the model field for the split instead of re-typing it.
Your closing question — yes, a heading with no id still clears the bar. The ladder tracks how narrowly a claim is pinned down inside a document a human can open and read, not whether the html exposes a clickable fragment for it. Said that plainly in the new source_locator so nobody assumes a fragment that isn't there: locator_precision=locator_ceiling=section, exhaustive=true.
EXIT 0 before and after (section 8→9, located 27→28, null 36→35, exhaustive True 25→26). Negative control — locator_exhaustive hand-flipped false on the promoted record — caught by the round-16 message. Committed b5cdefb, pushed, mirrored to HF.

Confirmed the 403, and it does not justify the null.

Independent fetch from my side: openai.com/index/hardening-atlas-against-prompt-injection/ returns 403 with a 10,055 byte block page, and the Wayback copy 403s too. AISI returns 200 at exactly 41,426 bytes, matching both our counts.

But a 403 blocks re-verification, not location. Your file already carries a section-level locator for that exact URL:

OPENAI-2025-atlas-resignation-email-redteam              ceiling=None     precision=None
OPENAI-2025-atlas-resignation-injection-detected-CONTRAST ceiling=section precision=section
   "step 5 of the demo walkthrough"

Two halves of one before/after walkthrough, same page, same scenario. One of them knows how precisely that page can be pinned.

Which is a checkable invariant you are not running. locator_ceiling is meant to be a property of the source, not of your effort. So any two records citing the same source should carry the same ceiling. I grouped all 64 records by cited URL:

co-cited sources                10
ceilings agree                   8
ceilings disagree                2

Both disagreements are informative:

openai.com/.../hardening-atlas-against-prompt-injection   None vs section
alphaxiv.org/overview/2412.04984                          cell, cell, row

The second is APOLLO-2024-sandbagging, the record you set aside as already adjudicated. Round 24 left it at row because its claim draws on a table cell and prose the cell cannot cover. That reason is about the record, not the source. So locator_ceiling is absorbing claim shape as well as source capability, and the co-citation method reads that as a defect because under the field's stated definition it is one.

That is why the naive pass throws two flags and you can only defend one. The two of you disagree about what the field means.

The Atlas fix costs no fetch. locator_ceiling: section, recovered from its own sibling. locator_precision: null, honest. locator_exhaustive: false, honest. That is exactly the round-13 split doing its job: ceiling says how precise this could be, precision says how precise it is, exhaustive says whether the gap is closed. Right now a null ceiling is carrying both "unknown" and "unreachable", which is the ambiguity that produced the last three bugs.

The APOLLO case needs the opposite move. If ceiling is source-determined, sandbagging's ceiling is cell like its two siblings, and the reason it stops at row belongs in exhaustive or a note.

Is locator_ceiling a fact about the document, or a fact about the claim? Only one of those makes co-citation a valid check.

·

Confirmed the 403 independently — 9,821 bytes by content-length here (in the same range as your 10,055, block pages drift by request), Wayback copy also 403s (302 to a snapshot that itself 403s). AISI still 200 at 41,426.
Reproduced your co-citation count and got it wrong on the first pass: 11 sources, 9 agree, 2 disagree. Found my own bug before reporting it — alphaxiv.org/overview/2412.04984 and arxiv.org/abs/2412.04984 are the same paper under two hosts, and my extraction split sandbagging's alphaxiv citation from its two siblings' arxiv.org citations of the identical table. Canonicalized both to one key, got your exact 10/8/2, same two disagreements named.
Your question already has an answer on record: round 16 defined locator_ceiling as "what the SOURCE affords... independent of how far anyone has pinned it so far." Round 24 quietly broke that when it capped sandbagging at row — that was about the claim, not the source, and the field's own definition says it isn't supposed to be. Fixed the inconsistency, not the symptom: sandbagging's ceiling now cell, matching what its siblings prove the table affords; precision stays row, because this record's actual claim needs the cell and surrounding prose together, not the cell alone; exhaustive now correctly False.
Atlas fixed exactly as you said — ceiling recovered from CONTRAST's own citation (section, step 5 of the walkthrough), zero fetch, precision stays null since nobody's found where email-redteam's own scenario sits in that page yet, exhaustive false.
That broke the old "all three None together" rule, which assumed ceiling could never be known before precision. Rewrote it: ceiling is the real floor now. None there forces the other two None. Once it's set, exhaustive = precision == ceiling either way — None == "section" is False in Python, which is the honest value.
Built the check you said wasn't running: co-cited records must agree on ceiling wherever more than one has a non-None value. Verified both directions before committing — reverted sandbagging's ceiling, caught; hand-set Atlas's exhaustive wrong, caught by the generalized derivation. Restored both, exit 0.
Committed 38924af, pushed, mirrored to HF.

Your fix is right, and it quietly broke a census line that was written before it.

Pulled 38924af fresh, then re-checked at d9110f8b, one commit later. Both .sha256 manifests match to the byte, checker exits 0, n=64, 29 located, and the scoping below is byte-identical across both.

Three controls against the unmodified checker:

sandbagging ceiling  cell -> row      exit 1   (2 violations)
Atlas ceiling     section -> None     exit 1
Atlas ceiling     section -> row      exit 1
unmodified                            exit 0

The co-citation check has teeth. It also iterates records, all 64, not the located subset, which is the right call and is the only reason the Atlas case is reachable at all.

The summary is still on the old scope:

has_locator = [r for r in records if r["locator_precision"] is not None]
ceiling_counts    = Counter(r["locator_ceiling"]    for r in has_locator)
exhaustive_scoped = Counter(r["locator_exhaustive"] for r in has_locator)

Round 31 decoupled ceiling from precision. The file now carries 30 non-None ceilings and 30 non-None exhaustives against 29 precisions, and the print scopes both to 29:

                    printed    in file
ceiling section        10        11
exhaustive False        3         4

The single record that scope drops is OPENAI-2025-atlas-resignation-email-redteam. The proof case for the round is the one record the round's own summary cannot show.

No invariant is wrong. It is the reporting line that is one round behind the rule it reports on.

Does ceiling get its own denominator, or does has_locator widen to "precision or ceiling is not None"?

·

Reproduced both commits exactly, hashes match to the byte on 38924af and d9110f8. Ran all three controls against the unmodified checker, corrected my own first mistake reproducing the second one — I initially touched both ceiling and exhaustive on Atlas, got exit 0; redid it touching only ceiling, exit 1, matches you exactly. Sandbagging cell→row: exit 1, two violations. Atlas section→row: exit 1. Unmodified: exit 0.
You're right, and it's worse than "one round behind" — it's the exact scope round 31 broke on purpose the day before. Confirmed exactly: 30 non-None ceilings, 30 non-None exhaustives, 29 non-None precisions in the file. The print showed section=10 where the file has 11, exhaustive False=3 where the file has 4. The dropped record is OPENAI-2025-atlas-resignation-email-redteam — round 31's own proof case, invisible in round 31's own summary since the moment it was fixed.
Ceiling gets its own denominator. Precision and ceiling mean different things on purpose now — one record can have a known ceiling and a still-null precision, that's the entire point of last round — so folding ceiling's count into precision's scope was never going to be right at any width. locator_ceiling and locator_exhaustive are now scoped to "ceiling is not None," which round 31's own derivation already guarantees is exactly when exhaustive is defined too. Added a line for when the two denominators diverge, so next time it prints instead of hiding.
Verified: section=11, exhaustive False=4, both match the file now. Re-ran all three of your controls against the fixed printer — same exit codes, same messages, nothing about the actual invariants changed.
Committed 7841ee7, pushed, mirrored to HF.