Skip to content

refactor(parser): retire the Class whole-document shim (U8, removal gate 5)#5639

Merged
matthewevans merged 1 commit into
mainfrom
ship/u8-class-doc-emitter
Jul 12, 2026
Merged

refactor(parser): retire the Class whole-document shim (U8, removal gate 5)#5639
matthewevans merged 1 commit into
mainfrom
ship/u8-class-doc-emitter

Conversation

@matthewevans

Copy link
Copy Markdown
Member

parsed_abilities_to_doc_ir was the last category-ordered document façade and
the sole producer of SpanPrecision::WholeDocument. It was not dead code: its
one caller was the live Class-card branch, so this is a conversion, not a
deletion. Class now emits through DocEmitter at its printed source line, like
every other preprocessor (Saga, Attraction, Leveler, Spacecraft) since U4.

  • parse_class_oracle_text returns Vec<(usize, OracleNodeIr)> — each item
    tagged with the source line it was printed on — instead of pushing into a
    category-bucketed ParsedAbilities. LevelSection now carries the line index
    of every retained line; reminder-stripping rewrites a line's TEXT but never
    its INDEX, so the index stays a faithful pointer into lines. The result
    in-param is dropped: it was always empty at the Class branch.
  • The four-item cascade this unblocks: the shim, OracleSourceSpan::whole_document,
    SpanPrecision::WholeDocument, and the WholeDocument arms of the renderer
    caveats. The caveats themselves STAY: they are shared with the live
    SpanPrecision::ChainRelative tier (U5 debt), whose spans are equally not
    card-absolute. carries_fragment() / check_fragment_precision() remain the
    fail-closed authority — the guard is bidirectional, so it still rejects an
    Exact span with no fragment.

Why the output is unchanged: lower_oracle_ir re-buckets document items BY
CATEGORY into ParsedAbilities, so cross-category interleaving never reaches
card-data.json; parse_class_oracle_text already pushed into each bucket in
source order; and CR 707.9a printed slots are stamped in finish() by
PER-CATEGORY counting, which never depended on visit order.

Evidence (full-pool export, data/card-data.json, 35,396 faces):
base 950c667 sha ab448fc64cb965907455257bcd98de68f58c58272bd7cb515703dae306740854
after this commit sha ab448fc64cb965907455257bcd98de68f58c58272bd7cb515703dae306740854 (byte-identical)
Non-vacuity: the shim reached exactly 38 Class faces, so a full-pool green is
vacuous on the other 35,358. Forced probe — invert the Class span sort key —
diverges on exactly 38 faces, all 38 of them Class, zero collateral. The green
was watched go red before it was accepted.
(A first probe that reversed EMISSION order came back identical, which is
correct and not a defect: OracleDocBuilder keys items by (first_line, ordinal) and re-sorts, so emission order is genuinely irrelevant — see
builder_returns_items_in_source_order_regardless_of_emission_order. That is
also why the retired category-order emission and source-order emission agree.)

Two doc.rs precision tests are re-pointed at the surviving tiers rather than
deleted, so they keep discriminating: is_exact would be tautologically true
without a non-card-absolute case, so the coarse side is now ChainRelative;
the co-located-sibling test now uses two Exact spans on one line (Kicker {2}{G}), the real live case. The "must not carry a fragment" direction of the
fragment/precision guard is now unrepresentable — it moved from a runtime
rejection to a type-level impossibility.

cargo check --all-targets: 0 errors, 0 warnings. 7,973 parser tests pass.
scripts/check-parser-combinators.sh: PASS.

…ate 5)

`parsed_abilities_to_doc_ir` was the last category-ordered document façade and
the sole producer of `SpanPrecision::WholeDocument`. It was not dead code: its
one caller was the live Class-card branch, so this is a conversion, not a
deletion. Class now emits through `DocEmitter` at its printed source line, like
every other preprocessor (Saga, Attraction, Leveler, Spacecraft) since U4.

- `parse_class_oracle_text` returns `Vec<(usize, OracleNodeIr)>` — each item
  tagged with the source line it was printed on — instead of pushing into a
  category-bucketed `ParsedAbilities`. `LevelSection` now carries the line index
  of every retained line; reminder-stripping rewrites a line's TEXT but never
  its INDEX, so the index stays a faithful pointer into `lines`. The `result`
  in-param is dropped: it was always empty at the Class branch.
- The four-item cascade this unblocks: the shim, `OracleSourceSpan::whole_document`,
  `SpanPrecision::WholeDocument`, and the WholeDocument arms of the renderer
  caveats. The caveats themselves STAY: they are shared with the live
  `SpanPrecision::ChainRelative` tier (U5 debt), whose spans are equally not
  card-absolute. `carries_fragment()` / `check_fragment_precision()` remain the
  fail-closed authority — the guard is bidirectional, so it still rejects an
  Exact span with no fragment.

Why the output is unchanged: `lower_oracle_ir` re-buckets document items BY
CATEGORY into `ParsedAbilities`, so cross-category interleaving never reaches
card-data.json; `parse_class_oracle_text` already pushed into each bucket in
source order; and CR 707.9a printed slots are stamped in `finish()` by
PER-CATEGORY counting, which never depended on visit order.

Evidence (full-pool export, data/card-data.json, 35,396 faces):
  base   950c667  sha ab448fc64cb965907455257bcd98de68f58c58272bd7cb515703dae306740854
  after  this commit sha ab448fc64cb965907455257bcd98de68f58c58272bd7cb515703dae306740854  (byte-identical)
Non-vacuity: the shim reached exactly 38 Class faces, so a full-pool green is
vacuous on the other 35,358. Forced probe — invert the Class span sort key —
diverges on exactly 38 faces, all 38 of them Class, zero collateral. The green
was watched go red before it was accepted.
(A first probe that reversed EMISSION order came back identical, which is
correct and not a defect: `OracleDocBuilder` keys items by `(first_line,
ordinal)` and re-sorts, so emission order is genuinely irrelevant — see
`builder_returns_items_in_source_order_regardless_of_emission_order`. That is
also why the retired category-order emission and source-order emission agree.)

Two doc.rs precision tests are re-pointed at the surviving tiers rather than
deleted, so they keep discriminating: `is_exact` would be tautologically true
without a non-card-absolute case, so the coarse side is now `ChainRelative`;
the co-located-sibling test now uses two Exact spans on one line (`Kicker
{2}{G}`), the real live case. The "must not carry a fragment" direction of the
fragment/precision guard is now unrepresentable — it moved from a runtime
rejection to a type-level impossibility.

cargo check --all-targets: 0 errors, 0 warnings. 7,973 parser tests pass.
scripts/check-parser-combinators.sh: PASS.
@matthewevans
matthewevans enabled auto-merge July 12, 2026 05:46
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

@matthewevans
matthewevans added this pull request to the merge queue Jul 12, 2026
@github-actions

Copy link
Copy Markdown

Parse changes introduced by this PR

✓ No card-parse changes detected.

Merged via the queue into main with commit e5871f5 Jul 12, 2026
13 checks passed
@matthewevans
matthewevans deleted the ship/u8-class-doc-emitter branch July 12, 2026 06:09
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