Skip to content

Decision 8: census.json becomes derived (CI computes, guard refuses PR diffs); lint-baseline counts become a base-vs-head never-down check #3569

Closed
1 of 1 issue completed

Description

@noahgift

Operator ruling, decision 8 (2026-09-20). This is the ontology slot's first aprender PR.

Step 1 — the measurement the ruling asks for, done

Last 20 merged commits on origin/main:

file touched by
contracts/census.json 4 / 20
contracts/lint-baseline.json 5 / 20

And the keys that move in lint-baseline.json, read from the last six commits that touched it, split exactly as the ruling predicts:

class keys observed
monotone counts contracts_total (1837→1852), entity_types_registered (1→9), extractors_implemented (1→6), contracts_shaped, contracts_anchored, shapes_unarmed, legacy_unresolved_depends_on
decisions armed_shapes ([ont-shapes-v1, ladder-measured] → +ladder-green)

So roughly a quarter of all merged PRs rewrite one of these files, and in lint-baseline.json the churn is almost entirely counts. armed_shapes is the only key observed that is a decision — which is the one the ruling keeps committed.

Step 2 — what lands

contracts/census.json becomes derived.

  • PRs stop committing it; CI computes it and gates on its invariants, not its bytes.
  • A guard refuses any PR whose diff touches it.
  • The train is its single writer, at T-0.

contracts/lint-baseline.json keeps only decisions.

  • The monotone counts leave the file and become a base-versus-head never-down check — computed, compared, never stored.
  • Keys like armed_shapes stay committed, because arming a shape is a decision a human makes and a reviewer must see in a diff.

Interim, until the above lands

A path guard labels any PR touching either file touches-shared-contracts, and those PRs merge in a queue group of one, behind slice M. Label created.

Acceptance

  • A PR that edits contracts/census.json is refused by the guard, with the reason naming the file. Falsifier: plant such a diff and require RED.
  • With census.json absent from a PR, CI computes it and its invariant check passes; corrupt one invariant and the check goes RED.
  • The never-down check fails when a count regresses base→head, and passes when it rises or holds. Both directions proven, or it is decoration.
  • armed_shapes still appears in a normal diff and still requires review to change.

Note the ruling corrects

The ontology slot is not blocked today. The fleet pv pin bump (#3567), the pmat ticket for ONT-11, and the capability ledger touch neither file. Earlier notes on #3080 and #3269 said slot 3 was blocked pending this decision — that is now wrong, and the slot starts with those three while this PR is written.

Refs #3080, #3269, #3559, #3567

Activity

  1. added this to the 0.69.0 milestone on Sep 20, 2026
  2. modified the milestones: 0.69.0, 0.70.0 on Sep 20, 2026
  3. noahgift commented on Sep 20, 2026

    @noahgift
    MemberAuthor

    Measured 2026-09-20 on #3581: there are three derivatives, not two, and they are strictly serialized — each invisible until the one before it clears

    One added contract file obliges three generated artifacts:

    1. contracts/census.json — FAIL contracts/census.json .n_files=1799 but HEAD carries 1800
    2. contracts.nt
    3. README's generated CONTRACT_COUNT block — FALSIFY-README-002: the CONTRACT_COUNT block states 1799, the merge tree carries 1800

    The third was masked by the first. It could not be seen until the census was regenerated, because the census check fails earlier and the run stops there. So the real cost is not one confusing message — it is three CI rounds for one file, each revealing the next obligation only after the previous fix lands, on a pool where a full round is tens of minutes and this was a T-0 gate PR.

    That changes the fix. "Name both derivatives in the failure message" is not enough: the number is three, and a message that names the one derivative it happened to check still leaves the author to discover the rest serially. The gate must evaluate all three and report every one that is stale in a single run, so one regeneration pass closes the whole set. Detecting them independently is what makes the count knowable; reporting them together is what makes it one round instead of three.

    Note also the downstream noise this produced: check_readme_claims.sh row 4 (rc=0 wanted 1, lags by one under --exact) read as a second, unrelated defect and is not one — it is the documented aprender#3516 consequence of the same stale census (the planted cc-1 claim lands exactly on the stale count, so the verdict correctly says PASS and the row reads red). Confirmed 7/7 with the census regenerated. One root cause presented as three failures across two guards.

    Credit: measured by the slice-M lane while clearing #3581.

    Refs #3581, #3516, #3420, #3494.

  4. noahgift commented on Sep 20, 2026

    @noahgift
    MemberAuthor

    Amendment: it is not three derivatives. It is three, plus a guard that fires on the remedy — and that fourth round hits a contributor who did everything right, in the right order.

    Measured on #3581 across four CI rounds:

    round red cause
    1 guard-cargo + shard 1/3 census.json, contracts.nt stale
    2 guard-cargo README CONTRACT_COUNT — masked by the census red in round 1
    3 guard-tree §11.1 ont-delta — caused by round 2's mandatory fix

    Rounds 1→2 are the masking already recorded here. Round 3 is a different defect and my earlier fix for this issue does not address it.

    make readme-sync is not optional — guard-cargo's FALSIFY-README-002 refuses the PR without it. But README.md is one of §11.1's five named prose sinks, so running the mandatory remedy reclassifies the PR as a sweep and demands an ont-delta: line in the body that was not required a moment earlier. Doing the required thing creates the next violation.

    So "name every stale derivative in one run" — the fix I wrote on this issue an hour ago — is necessary and still insufficient. A contributor who regenerates all three derivatives in one pass, correctly, on the first try, still eats round 3, because the fourth failure is not a derivative at all. It is a classification side effect of the repair.

    The generalisable rule

    A mandatory remedy must announce the obligations it creates. make readme-sync should say, at the moment it edits README.md, that it has just made this PR a §11.1 sweep and that the body now needs an ont-delta: line. The information exists at exactly the point of the edit and is currently discovered one CI round later, from a guard that names §11.1 and not readme-sync.

    That is cheaper than the alternative (teaching §11.1 to exempt generated README edits), and it is more honest: the PR is touching a prose sink, so the classification is correct. What is wrong is that nothing connects the cause to the consequence.

    Added to done_when

    1. Any target that edits a §11.1 prose sink as a required step prints the obligation it has just created, naming the guard that will otherwise fire and the body line that satisfies it.
    2. Falsifier: run the target on a clean tree and assert the notice appears; remove the notice and assert the case table goes RED. A notice nobody asserts is the class this repo keeps re-finding.

    Also recorded: a round 4 that did not happen because it was checked

    The slice-M lane edited the contract's references: line (.py → .awk) after generating contracts.nt. If reference strings fed the graph, it would have been stale again and shard 1/3 would have failed on the next round. Re-extracted and compared: contracts.nt and census.json are both byte-identical to a fresh run. They do not feed it. Verified rather than assumed, which is the only reason it is a footnote instead of round 4.

    Credit: measured by the slice-M lane on #3581 (2246d0940 → d51343bee), both polarities verified against the real guard — PASS with the ont-delta: line, FAILED: §11.1 … without.

    Refs #3581, #3516.

  5. modified the milestones: 0.70.0, 0.71.0 on Sep 23, 2026
  6. noahgift commented on Sep 23, 2026

    @noahgift
    MemberAuthor

    milestone → 0.71.0 per docs/roadmaps/milestone-triage-2026-09-23.md (#4024), operator approval 2026-09-23 (relayed by aprender-cf). Reason: debt ratchet pillars B/C (#3997: pv at the deepest level, ontology merge), slice 2

  7. modified the milestones: 0.71.0, 0.70.0 on Sep 23, 2026
  8. added
    ont-0.70Ontology spec work that must finish in 0.70 (operator 2026-09-23)
    on Sep 23, 2026
  9. 20 remaining items

  10. modified the milestones: 0.70.0, 0.71.0 on Oct 4, 2026
  11. noahgift commented on Oct 12, 2026

    @noahgift
    MemberAuthor

    evidence for close: #4655 @ 989cb01 (on main), checked by reading main: scripts/check_census_derived.sh refuses any non-train diff to contracts/census.json naming the file, and checks a freshly computed census's invariants (--census FILE), with a --self-test case table whose RED rows must go RED; contracts/lint-baseline.json now opens "counters are MEASURED comparand->head by scripts/check_ont_ratchet.sh (#3569); this file holds decisions only", and keeps armed_gates / armed_shapes as reviewed decisions. Both directions of the never-down check are rows in scripts/check_ont_ratchet.sh --self-test (e.g. "contracts_anchored RISES: GREEN" / "contracts_anchored FALLS: RED", "contracts_shaped RISES: GREEN" / "FALLS: RED").

  12. noahgift commented on Oct 12, 2026

    @noahgift
    MemberAuthor

    evidence for close: 989cb01 (#4655), ancestor of main 6bd89b0. Checked at main: scripts/check_census_derived.sh refuses a PR diff to census.json and names the file, and it runs on every PR through guard_tree.sh; scripts/contracts_gate.sh (step_census) checks a freshly computed census; scripts/check_ont_ratchet.sh --self-test has rise→GREEN and fall→RED rows for never-down; lint-baseline.json now holds decisions only (armed_shapes, armed_gates).

  13. noahgift commented on Oct 12, 2026

    @noahgift
    MemberAuthor

    Cop batch close (FLOW-004 drain, ≤43/d): fix verified on main — merged #4655 ; ancestor of origin/main: 989cb01 . Evidence: #3569 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High priorityont-0.70Ontology spec work that must finish in 0.70 (operator 2026-09-23)owner:aprender-a7owner sessionsize:MK̂ 3-4 h

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions