pgc_ledger.py merge writes a row whose majors covers only the majors it was handed, and nothing warns. Four PRs in a row have gone red on it.
The failure
A contributor adds checks, runs the suite on one major, merges that log, commits. The row lands with majors = 18. The gate then considers a row only where its majors intersect the majors the current run observed, so:
suites (PG 18) matches the row, reports new this run=0, green
suites (PG 17) cannot match it, reads it as a check the ledger has never seen, red
The failure names the contributor's own checks with (on major 17), so it reads like their suite is broken on PG 17 when the suite passes there.
It is not a one-off
Measured today, on each branch's own tracked ledger:
PR rows added majors on them every other row
#1039 6 18 15;16;17;18;19
#1063 6 18 15;16;17;18;19
#1065 8 18 15;16;17;18;19
#1068 10 18 15;16;17;18;19
#1070 6 18 15;16;17;18;19 (jdatcmd, same trap)
Five authors' worth of the same mistake, including the person who wrote the tool, on a PR that is about ledger hygiene. When everyone makes the same mistake it is the tool's shape, not five lapses.
Why the obvious defences did not fire
- The recipe the gate prints is incomplete. It says
merge --ledger ... --date <today> <log> — singular. Following it exactly produces the broken row.
3a640b0 established the five-major requirement, and nothing enforces it.
- The merge summary already computes what it needs. It prints
majors: uniform, all N rows carry 15;16;17;18;19 when the file is uniform — so it knows what the rest of the ledger carries and says nothing when a new row is a strict subset of it.
- A local run cannot catch it.
harness_selftest.sh green does not cover the ledger gate, because the gate runs in run_all_versions.sh. Every author verified locally and was green.
What would fix it
Cheapest, and it needs no new concept: merge warns when it writes a row whose majors is a strict subset of the majors the rest of the ledger carries. The distribution is already computed for the summary line. Something like:
WARNING: 6 row(s) written with majors=18, while the other 1217 rows carry
15;16;17;18;19. The gate will refuse these on every major not listed.
Merge a log from each major, or this PR reddens on 17.
Stronger options, if wanted: make the gate's printed recipe name every gated major, or have merge exit non-zero on a strict subset unless a flag says it is deliberate. I would start with the warning, because a hard refusal would block the legitimate case of seeding a major at a time.
What I am not proposing
Not a change to the majors mechanism itself. Per-major rows are right — a check really can exist on one major and not another, and #1010 added the field for that reason. The defect is that the tool knows the new row is anomalous and does not say so.
Evidence
I cleared all five PRs by running each suite on 15/16/17/18/19 and merging five logs, which makes the rows uniform and the gate green. That is the correct fix per PR and it is entirely mechanical — which is the argument for the tool doing the telling.
pgc_ledger.py mergewrites a row whosemajorscovers only the majors it was handed, and nothing warns. Four PRs in a row have gone red on it.The failure
A contributor adds checks, runs the suite on one major, merges that log, commits. The row lands with
majors = 18. The gate then considers a row only where its majors intersect the majors the current run observed, so:suites (PG 18)matches the row, reportsnew this run=0, greensuites (PG 17)cannot match it, reads it as a check the ledger has never seen, redThe failure names the contributor's own checks with
(on major 17), so it reads like their suite is broken on PG 17 when the suite passes there.It is not a one-off
Measured today, on each branch's own tracked ledger:
Five authors' worth of the same mistake, including the person who wrote the tool, on a PR that is about ledger hygiene. When everyone makes the same mistake it is the tool's shape, not five lapses.
Why the obvious defences did not fire
merge --ledger ... --date <today> <log>— singular. Following it exactly produces the broken row.3a640b0established the five-major requirement, and nothing enforces it.majors: uniform, all N rows carry 15;16;17;18;19when the file is uniform — so it knows what the rest of the ledger carries and says nothing when a new row is a strict subset of it.harness_selftest.shgreen does not cover the ledger gate, because the gate runs inrun_all_versions.sh. Every author verified locally and was green.What would fix it
Cheapest, and it needs no new concept:
mergewarns when it writes a row whosemajorsis a strict subset of the majors the rest of the ledger carries. The distribution is already computed for the summary line. Something like:Stronger options, if wanted: make the gate's printed recipe name every gated major, or have
mergeexit non-zero on a strict subset unless a flag says it is deliberate. I would start with the warning, because a hard refusal would block the legitimate case of seeding a major at a time.What I am not proposing
Not a change to the majors mechanism itself. Per-major rows are right — a check really can exist on one major and not another, and #1010 added the field for that reason. The defect is that the tool knows the new row is anomalous and does not say so.
Evidence
I cleared all five PRs by running each suite on 15/16/17/18/19 and merging five logs, which makes the rows uniform and the gate green. That is the correct fix per PR and it is entirely mechanical — which is the argument for the tool doing the telling.