docs(layout): fix two wrong CSS 2 citations for static position and the no-box rule - #497
Conversation
…he no-box rule
Both errors re-verified with `.claude/tools/webref` rather than trusted from
the slot memo.
§10.6.5 was cited at 7 sites as the authority for recording an abspos
placeholder's static position. `heading CSS2 10.6` gives §10.6.5 = "Absolutely
positioned, REPLACED elements", which only *uses* the term ("replace top with
the element's static position"). The definition lives in §10.3.7 and §10.6.4,
each opening "For the purposes of this section and the next, the term 'static
position' (of an element) refers…" — "and the next" being §10.3.8 / §10.6.5,
so the pair covers replaced and non-replaced alike, which is what these
placeholders record. Cited as "§10.3.7 left/right / §10.6.4 top, mapped to
logical axes": those sections define the term for PHYSICAL axes, and glossing
them as inline/block would invert in a vertical writing mode — the caveat
positioned/constraints.rs:70 already states.
§9.2.1.1 was co-cited at 3 sites for the "white space that collapses away
generates no box" rule. `body CSS2 anonymous①` (§9.2.2.1, Anonymous inline
boxes) carries it verbatim; §9.2.1.1 (Anonymous block boxes) does not — its
only "white" is in the break-around-block parenthetical, a different rule. Two
of those sites also assert the LINE-BOX consequence ("contributes zero block
size", "is not pushed"), which §9.2.2.1 does not state either; that is §9.4.2's
zero-height-line-box rule, now co-cited there.
Counting the §9.2.1.1 sites by concept rather than by a `CSS 2 §`-prefixed
string-grep (which misses `collect.rs:92`, where the prefix wraps to the line
above): 12 existed. One was wrong — `elidex-ecs` components.rs:167 said
"anonymous inline formatting context (CSS 2 §9.2.1.1)", but §9.2.1.1 is
anonymous BLOCK boxes and "anonymous inline formatting context" is not a CSS 2
term; re-cited to §9.4.2. The remaining 11 are anonymous-block-box or
anonymous-block-in-inline contexts and are correct, so they are deliberately
untouched. Classification is by the rule being cited, not the section number.
Folded in from the same slot: `CSS Text §4.1.2` was missing its level number
(`css-text-3 §4.1.2` = "Phase II: Trimming and Positioning") — fixed at all
three in-crate sites, not just the one the slot listed. collect.rs and
styled_run.rs carried no module-level citation while their sibling
whitespace.rs does; collect.rs turns text directly inside a block container
into inline items, so it cites §9.2.2.1, and styled_run.rs cites §9.4.2.
NOT folded in: the slot's `CSS 2.1` → `CSS 2` naming normalisation. Measured,
it is 172 occurrences across 52 files and 9 crates, so it is neither confined
to layout nor parallel-safe, and it is a label difference rather than an error;
normalising layout alone would self-seed the inconsistency it aims to remove.
An earlier draft of this message handed it to the citation-hygiene program —
that was wrong and is withdrawn: the umbrella's six slices cover enforcement
plumbing, detector correctness, policy retirement, the domform-submittable
sweep, is_submittable repair, and Slice 1, none of which owns spec-name prose
(`grep 'CSS 2' docs/plans/2026-07-citation-hygiene-*.md` = 0 hits). It is
tracked instead as its own slot, `#11-css2-spec-label-normalisation`.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7b2e6eb93f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
RUSTSEC-2026-0222 ("Stores can mix up type indices between engines",
upstream GHSA-hgjw-h833-99q9) covers the pinned 45.0.1, so `cargo deny`
went red the moment the advisory DB refreshed on 2026-08-01. This is not
a code regression -- main's last CI run (2026-07-30) predates the DB
refresh. It surfaces on #496 and not #497 only because `deny` is gated on
the `config` paths-filter, which includes `.github/workflows/**`.
Patched ranges are `>=24.0.12,<25`, `>=36.0.13,<37`, `>=46.0.2,<47`, and
`>=47.0.3`. Note that Dependabot #486's 47.0.2 sits in the gap between
`<47.0.0` and `>=47.0.3` and does NOT fix this -- "newer than 45" is not
the same as "patched". Taking 47.0.3 over the 46.x line because wasmtime
cuts a major monthly and patches only the current line plus LTS, so 46.x
is one release from falling off; this way we cross the majors once.
Landed independently of #486 rather than by pushing to that branch: #486
bundles 33 other bumps, each with its own review surface, and coupling
the security fix to them delays unblocking #496 for no benefit.
The version requirement carries a patch-level floor on purpose. The
workspace convention is bare majors (`wgpu = "29"`), but `wasmtime = "47"`
means `>=47.0.0` and would let a fresh resolve land back on the
vulnerable 47.0.0-47.0.2. A comment records this so a later tidy-up pass
does not silently reopen the hole.
No source changes were needed -- two majors crossed with zero API
breakage across the 144 `wasmtime::` uses in elidex-wasm-runtime, the
sole consumer. The layering trip-wires confirm the bump did not perturb
the boundary: elidex-js stays wasmtime-free (D-16) and host/ still uses
`wasmtime::`.
Verified sequentially (the parallel `mise run ci` graph races ci-sweep):
lint, test-all (12744 tests, 0 failed), doc, deny (advisories ok, bans
ok, licenses ok, sources ok), trip-wires.
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
…5 -> 7 modules) Standalone prereq split, per CLAUDE.md "1000-line debt = touch-time split": a >1000-line file with real cohesion seams is divided BEFORE the feature touching it lands, as its own PR rather than bundled into that feature. `text_height.rs` had reached 1125 lines. The rule applies to test files on the same basis as source, and to any-size touch — which is the part that had been slipping: a two-line citation fix in #497 is still a touch. The seams are the file's own: seven `// --- <scenario> ---` banners it already carried. Each becomes a submodule, the banner becoming that module's `//!` doc since the file boundary now carries that role. basic 301 12 tests text height + white-space values that keep line boxes anonymous_block 216 4 tests inline runs among block siblings layout_box 186 4 tests which participants get a LayoutBox; fragment bounds collapse 176 10 tests CSS Text 3 §4.1.1 Phase I, asserted on runs multi_style 105 3 tests nested spans with differing styles vertical 81 3 tests vertical writing modes atomic 76 2 tests display: inline-block in an IFC mod.rs 15 shared imports, reached via `use super::*` Shape mirrors the sibling `inline_flow/` split: `mod.rs` keeps `use super::*` and the submodules reach it the same way. Test bodies are moved VERBATIM — the only edits are the per-module `//!` header and, where a module needs it, the `use elidex_plugin::WhiteSpace` line the original carried once. Behaviour backstop: `elidex-layout-block` runs 325 tests before and 325 after, and the file's 38 `#[test]` items are 38 across the seven modules — counted on the pre-split tree and re-counted after, not asserted. `mise run ci` green. Cold-gate checked: no other open PR touches this file (#497 is the sequenced follow-on and merges this). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`text_height.rs` was 1125 lines, so CLAUDE.md's touch-time rule required the split to land as its own PR before this sweep's two-line citation fix in it. #500 does the split; this merge stacks the sweep on top. Conflict was modify/delete by construction — #500 deletes the file, this branch edited two comment lines in it. Resolved by accepting the deletion and re-applying both citation fixes to the modules they moved into: `text_height/basic.rs` (trailing-hang) and `text_height/collapse.rs` (leading collapsible white space). Also brings main's wasmtime 47.0.3 bump (#498) in via #500's base, so this branch's `deny` job now matches main. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ss the engine Codex review on #497 — two of three findings; the third (`text_height.rs` over 1000 lines) is discharged by the prereq split merged in the previous commit. **§9.2.2.1 was on collect.rs's module summary, which over-claims.** That section governs text *directly contained* in a block container becoming an anonymous inline element. This module also walks styled inline descendants, atomic inline boxes and out-of-flow placeholders, each governed elsewhere, so a module-level cite reads as if one section covered the whole collection algorithm — the same over-claiming class this PR exists to fix, committed while fixing it. The cite moves to the text-node arm; the summary says explicitly why it stays uncited. **The `CSS Text` level fix stopped at the crate boundary.** This branch already extended it from the one site the slot listed to all three in `elidex-layout-block`, but left seven in `elidex-render` (`builder/whitespace.rs:7,33,49,65`, `builder/tests/styling.rs:719,721,723`) — the paired implementation of the same whitespace-processing surface. That is two citation conventions for one surface, self-seeded by the very sweep meant to remove the divergence, which is the failure mode `feedback_semantic-sibling-selfseed-and-regate-breadth` records. Swept: `git grep 'CSS Text §'` over `crates/**/*.rs` is now empty. Titles verified with webref — `css-text-3` §4 = "White Space Processing & Control Characters", §4.1 = "The White Space Processing Rules". Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Codex review — all three findings takenP1 "Split the oversized test module before touching it" — correct, and the part that had been slipping is that CLAUDE.md's rule covers any-size touch: two comment lines is still a touch. Split landed as a standalone prereq, #500, not bundled here — the rule requires the division to be its own PR. This branch merges it and re-applies both citation fixes into the modules they moved to ( P1 "Normalize the same CSS Text label across the engine" — correct. This branch had already extended the fix from the one site the slot listed to all three in P2 "Scope the anonymous-inline citation to the text-node path" — correct, and the sharper point is that it is the same over-claiming class this PR fixes, committed while fixing it. §9.2.2.1 governs text directly contained in a block container; the module also walks styled inline descendants, atomic inlines and out-of-flow placeholders. Cite moved to the text-node arm, and the module summary now states why it stays uncited rather than leaving that implicit.
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8106b0056a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…p they exposed Codex round 2 on #497 — three real findings, all of them over-claims the previous round's fixes introduced. Verified against the implementation, not taken on the badge. **§9.2.2.1 on the text arm was unconditional, but the arm is recursive.** `collect_inline_items_inner` re-enters with an inline element as `parent_entity`, so `<p><span>text</span></p>` reaches the same branch — and text inside an inline box is that box's own content, not an anonymous inline. The comment now names the condition (top-level call, `parent_entity` is the block container) instead of asserting the section for every path through the arm. **`InlineFlow` was described as one-per-IFC; it is one per render-run group.** `LinePacker` buckets `flow_lines` by group entity and `positioned_subflow_key` splits a relatively-positioned or sticky subtree into its own group, so a single IFC persists several of these components. The previous wording misstated the component's cardinality and, with it, the "first top-level child" ownership claim two paragraphs down. **§9.4.2's zero-height rule is conditional and we do not meet the condition.** It exempts lines carrying an inline element with non-zero margins, padding, or borders. `any_rendered_content` is set only from a rendered glyph, an atomic inline, or a forced break, and `StyledRun` has no box-decoration fields at all — so `<p><span style="padding:10px"> </span></p>` loses both the line and the span's rectangle. The bug predates this PR; citing §9.4.2 is what newly claimed conformance to it. The doc now names the divergence rather than implying conformance, and the behaviour fix — threading decoration presence into the content test, with regression tests either way — is slot `#11-line-box-decorated-inline-content`: a layout-behaviour change is a genuine boundary for a citation sweep, not a scope cut. The fourth finding (move the split to a prerequisite change) is a false positive: it already is one, #500, and this branch merges it. Codex sees the aggregate diff rather than the PR graph. The sequencing it asks for is real and is why the merge order is #500 first. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…y self-audit
Not a Codex finding: the ≥2-round self-root-check in the converge loop fired on
the recurring shape ("a citation's scope is narrower than the paths reaching the
site"), so the same-pattern audit was run over every citation this branch adds
rather than waiting for round 3 to surface the rest.
It found one. `styled_run.rs` carried a module-level `(CSS 2 §9.4.2)` that this
branch added. §9.4.2 governs line-box formation; `StyledRun` and `InlineItem`
are its INPUT, collected before packing — so the summary claimed a scope the
module does not have, the identical shape Codex flagged on `collect.rs` in round
1 and on the arm-level relocation in round 2. It also contradicted the sibling
`collect.rs`, which this branch had just given an explicit "deliberately uncited
at module level" stance.
Worth recording what the split of this loop's findings shows: not one came from
the two citation ERRORS the slot named (§10.6.5, the §9.2.1.1 co-cite) or from
the `CSS Text` level sweep. Every one came from citations this branch ADDED
beyond that scope — the slot memo's "minor items" invited an annotation sweep
inside a correction sweep, and each new annotation is a new claim that must hold
for every path reaching it. Hence no further citations are added here; the
remaining edits only correct or narrow.
The recurring root is a process gap, not a missing abstraction: webref was used
to verify what a section SAYS, but not that every path reaching the annotated
site satisfies that section's preconditions. Round 2's recursive-arm finding and
its §9.4.2 conditional-rule finding are both exactly that omission.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
@codex review |
|
Codex Review: Didn't find any major issues. Can't wait for the next one! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4bfcb625bf
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…ts.rs (1037 -> 822) Second prereq split for #497, same rule as the first: CLAUDE.md's touch-time 1000-line discipline, which covers an any-size touch. #497 edits one doc comment on `InlineFlow` in a file that is already 1037 lines, so the split has to land before it and as its own commit rather than bundled into the feature PR. Found by Codex on #497 R4 — and the miss it exposes is process, not judgement: `feedback_split-on-touch-prereq-workflow` asks for the check over the whole TOUCH-SET before editing, and running it that way (one loop over `git diff --name-only`) reports both oversized files at once. The first split happened only because a reviewer named that file; this one existed the entire time in the same PR. Not exempt as a flat data table: the module carries 9 `impl` blocks. And the seam is not invented for this PR — `components/inline_style.rs` was already split out for the identical reason, with a comment at the declaration saying so ("to keep this shared component-definition file under the 1000-line limit; re-exported so `components::InlineStyle` still resolves"). This follows that shape exactly, on the family the file already grouped together: InlineFlow / InlineFragment / InlineFlowLine / InlineFlowRun / ColumnFlowSlice -> components/inline_flow.rs (232 lines), moved verbatim Public API is unchanged — `pub use inline_flow::{...}` keeps every path resolving, so no call site moves. `elidex-ecs` runs 274 tests before and after. Clippy rejected the initial `use super::*` (`wildcard_imports` is deny here), so the submodule imports `super::{Entity, Point}` explicitly. `mise run ci` green. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Second touch-time split this branch needs: #497 edits one doc comment on `InlineFlow` in a 1037-line `components.rs`, so per CLAUDE.md the split lands first and separately. #500 carries it; this merge stacks the sweep on top. Conflict was this branch's doc fix against the family the split moved out. Resolved by taking the split's `components.rs` and re-applying the corrected `InlineFlow` doc — one render-run GROUP within an IFC, CSS 2 §9.4.2, not the old "anonymous inline formatting context (§9.2.1.1)" — to its new home in `components/inline_flow.rs`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
@codex review |
|
Codex Review: Didn't find any major issues. Nice work! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d8e559c2a2
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…hat that hid
PAUSE + option A (step back & collapse) from the converge loop's design re-gate.
The re-gate was fired by the ≥2-round self-root-check rather than held for
TERMINAL — correctly, because it found that the loop's central fix was itself
wrong for the third time.
**The collapse.** CSS 2 §9.2.2.1 drew an IMP in R1, R2 and the re-gate. R2's
"fix" claimed the text arm in `collect.rs` is governed by §9.2.2.1 "ONLY on the
top-level call". That is falsifiable and false: the recursion arm diverts only
`display:none`, out-of-flow, atomic inlines and pseudo-elements, so it descends
through block-level children too — for `<p>a<span>b<div>c</div>d</span>e</p>` the
text arm is reached with a block container as `parent_entity`, which is exactly
§9.2.2.1's precondition.
Three wordings, three wrong, because the mechanism was wrong: §9.2.2.1's
precondition is a property of the CALLER, and a fixed comment site cannot carry
a claim that varies per call path. So the site stops asserting a subsection. The
module cites the family — CSS 2 §9.2 "Controlling box generation", whose children
are the anonymous block (§9.2.1.1), anonymous inline (§9.2.2.1), inline-box
content (§9.2.2) and `display` (§9.2.4) cases — and the arm says which rule
applies is not statically knowable there, recording both prior errors so a fourth
attempt is not made.
**What the re-gate found underneath.** CR/CRLF → LF was attributed to CSS Text 3
at 7 sites. css-text-3 §4's note says the *opposite*: "the DOM does not give any
particular meaning to carriage returns … so they are not treated as segment
breaks". The rule is HTML §13.2.3.5 "Preprocessing the input stream" ("there are
never any U+000D CR characters in the input to the tokenization stage"); elidex
runs it as a safety net for text that reached the DOM without HTML parsing —
the case that note carves out. This branch had made those labels *more precise*
(`CSS Text` → `CSS Text 3`) without checking the claim, which is the same
verified-the-section-not-the-claim gap as the §9.2.2.1 errors.
Also: "mapped to logical axes" was copied to three static-position maps, but
`inline/mod.rs` projects to physical before returning and `stack.rs` stores
physical — only `LinePacker`'s map is logical. A whitespace-only `<span>` line
was cited to §9.2.2.1, whose suppression sentence is scoped to *anonymous* inline
boxes; it is §9.4.2. `styled_run.rs` now names CSS 2 §9.2.2, the section that
does govern it, instead of only saying which one does not.
**Slots reached the ledger.** `#11-line-box-decorated-inline-content` is cited
from a production docstring but existed only as a standalone memo — invisible to
defer governance, which makes a defer behave as a scope-cut regardless of intent.
Both new slots are now registered in the layout lane's OPEN-slots block, the
closed sweep slot is struck there, and its "add module-level §9.4.2 cites" item
is marked PREMISE DISPROVED so the next reader does not re-execute what this PR
disproved twice.
`components.rs`'s `Point` import turned out to be a pass-through kept alive only
by the child reaching through `super`; importing at origin made rustc prove that.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6061da8b6b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…from them Second collapse, and the first one was wrong. PAUSE fired again: the previous commit's re-wording produced three MORE over-claims on the lines it had just rewritten (`collect.rs` arm, `styled_run.rs` module doc, `anonymous_block.rs` header), so "say it better" was the fourth failed attempt at the same shape. Splitting this loop's 15 real findings by which change produced them makes the answer unambiguous: slot's two citation ERRORS (§10.6.5, the §9.2.1.1 co-cite) 0 findings the `CSS Text` level completion 0 replacing a wrong cite (components.rs, layout_box.rs) 0 citations this branch ADDED at module / arm level 15 The mechanism was not mis-worded, it should not have existed. A module or arm citation asserts one governing section over a HETEROGENEOUS set — `collect.rs` has six arms, `StyledRun`'s enum carries text runs, atomic inlines and out-of-flow placeholders — and different sections govern different members, so every phrasing over-claims. §9.2 reads as covering §9.2.4's display suppression; §9.2.2 drops atomic and placeholder. There is no correct wording, which is why four attempts failed. The slot asked for two wrong cites to be fixed; the additions were scope this branch invented. So they are withdrawn — `collect.rs`'s module doc and text arm, and `styled_run.rs`'s module doc, return to their pre-PR text. Same conclusion for CR/CRLF, arrived at the same way. `CSS Text 3 §4.1.3` was wrong (css-text-3 §4's note: the DOM gives U+000D no meaning and does not treat it as a segment break); `HTML §13.2.3.5` was wrong too, as Codex pointed out — on a `create_text` path no input stream was ever parsed. Neither spec governs it, so the comments now say what it actually is: elidex's own defensive normalization, catching exactly the case that note carves out. Hunting for the right spec to name was the error; naming none is the fix. `anonymous_block.rs`'s header no longer attributes its two neighbour tests to §9.2.4 / CSS Display 3 — an atomic inline *does* generate a box, so grouping it with `display:none` as a "generates no box" case was wrong on its own terms. What survives is what the slot asked for: §10.6.5 → §10.3.7/§10.6.4 at 7 sites, the §9.2.1.1 co-cite dropped at 3, `CSS Text` → `CSS Text 3` engine-wide, and the two wrong cites replaced where a correct one exists. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
All three taken — and they settled the loop's actual rootYou were right on each, and together they made the pattern legible. Splitting this loop's 15 real findings by which change produced them:
So the previous commit's re-wording was the fourth failed attempt at the same shape, not a fix. A module or arm citation asserts one governing section over a heterogeneous set — Withdrawn, not re-worded: On the CR citation — you were right that HTML §13.2.3.5 does not govern a On the atomic-inline grouping — correct on its own terms: an atomic inline does generate a box, so listing it beside What survives is what the slot asked for: §10.6.5 → §10.3.7/§10.6.4 at 7 sites, the §9.2.1.1 co-cite dropped at 3, |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 45c72c0a23
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
… its citation Fifth round, same shape, and again on a line the previous collapse had touched: `whitespace.rs:23` was upgraded from `§9.2.2.1` to the `§9.2.2.1 / §9.4.2` composite, and Codex correctly notes that for `<p><span> </span></p>` the text sits inside a real inline box, so §9.2.2.1's anonymous-inline suppression is not what applies. Consistent with the withdrawal: the fix is not a third scoping of this citation. The sentence is a FORWARD REFERENCE — it says the rule runs at line-packing time, elsewhere. The site that decides the rule is `LinePacker`, and it already carries the composite (verified correct there). So the reference points and stops citing. Restating a section at a site that does not decide it is what made both previous citations on this line wrong. With this, no citation that this branch ADDED survives. What ships is the slot's scope exactly: §10.6.5 → §10.3.7/§10.6.4 at 7 sites, the §9.2.1.1 co-cite dropped at 3, `CSS Text` → `CSS Text 3` engine-wide, and two wrong cites replaced where a correct section exists. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Right again, and on a line the previous commit had touched — I'd "upgraded" it from Not re-scoped a third time. That sentence is a forward reference: it says the rule runs at line-packing time, elsewhere. That was the last one. No citation this branch added survives. What ships is the slot's scope exactly — §10.6.5 → §10.3.7/§10.6.4 at 7 sites, the §9.2.1.1 co-cite dropped at 3, For the record, the split that settled it — 16 real findings across 5 rounds, by which change produced them:
|
|
@codex review |
|
Codex Review: Didn't find any major issues. Chef's kiss. Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
|
@codex review |
|
Codex Review: Didn't find any major issues. Keep it up! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
…s.rs) (#500) Two standalone touch-time splits, kept out of the feature PR (#497) per CLAUDE.md's "1000-line debt = touch-time split" rule, which covers test files on the same basis as source and applies to an any-size touch. `inline/tests/text_height.rs` (1125 lines) -> `text_height/` x 7 modules, split on the seven `// --- <scenario> ---` banners the file already carried. 325 tests in `elidex-layout-block` before and after; the file's 38 `#[test]` items are 38 across the seven modules. `elidex-ecs/src/components.rs` (1037 -> 822) -> the inline-flow component family moves to `components/inline_flow.rs`, following the module's own precedent: `components/inline_style.rs` had already been split out for the identical reason, its declaration comment saying so. `pub use` keeps every path resolving, so no call site moves; 274 tests before and after. Not exempt as a flat data table — the module carries 9 `impl` blocks. Test bodies and component definitions are moved verbatim. The only added lines are each module's `//!` header and the imports the moves require. The second split was found by Codex on #497 R4, and the miss it exposed is procedural: `feedback_split-on-touch-prereq-workflow` asks for the check across the whole TOUCH-SET before editing, and running it that way reports both oversized files in one command. `mise run ci` green (12744 tests). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
#500 was squash-merged, so its two split commits reached main as one commit with different hashes than the ones this branch carries — git therefore saw add/add conflicts on the five files both sides create. That is the ordinary consequence of squash-merging a prereq under a stacked branch, and it was foreseeable. Resolved to THIS branch's side on all five. Verified rather than assumed: each `ours` differs from `theirs` only by the citation corrections applied after the split landed (the §9.4.2 / render-group rewrite in `inline_flow.rs`, the `CSS Text 3` level fixes, the §9.4.2-not-§9.2.2.1 correction in `layout_box.rs`, the defensive-normalization note in `collapse.rs`, the header rescope in `anonymous_block.rs`), and all five resolved files are byte-identical to this branch's pre-merge tip. Also brings in #496's trip-wires CI job. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
@codex review |
|
Codex Review: Didn't find any major issues. Already looking forward to the next diff. Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
**reconcile.rs — spec citations on the new docstring.** Codex asked for citations "governing the inline-flow, fragmentation, and repositioning behavior". Half of that over-claims: `InlineFlow` and `ColumnFlowSlice` are engine-internal ECS components and no CSS module specifies persisting a flow or carrying a column slice. But its stated concern — that a later edit cannot tell specification requirements from render bookkeeping — is exactly right, so the docstring now says which is which: the logical→physical fold cites css-writing-modes-4 §6.4 (Abstract-to-Physical Mappings) and the atomics' block-axis target cites CSS 2 §10.8, both re-verified with webref. The uncited prose inside the body is named as pre-existing and untouched, with #497's over-claim precedent cited. **plan-memo §8/§10 — an obligation asserted with unavailable evidence.** §8 said "§10's ledger actions applied" against a four-file diff, and Codex concluded they were still open. They were applied — but every target is in the user-level agent memory directory outside this repo (`git ls-files | grep -c memory/` → 0), so no reviewer could check. Codex's conclusion was wrong and its finding was right: the memo claimed a discharged obligation and gave no way to verify it. §10 now opens with where the targets live and a table of what was changed in each. Both fixes sit above the signature / outside the compared body, so the §6 body harness and the §6.1 call-site check both still pass; check/lint/test-all/doc all rc=0 and trip-wires rc=0. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…e first review of the authored surface R9 returned 5 findings and the loop's Step-4 root-check fired, so the overlay's cumulative fix-delta /elidex-review ran mid-loop rather than at TERMINAL. It returned 1 CRIT / 16 IMP / 15 MIN across five axes on a delta nine Codex rounds had already passed over. What the re-gate found that nine rounds had not, and why: the loop reviewed the memo's self-audit prose and never the surface this PR authors. Both spec defects below live in the 19-line docstring added by 702999e -- the R1 fix itself -- and R2..R9 never touched it. Code (reconcile.rs, docstring only; both harnesses still pass): * the css-writing-modes-4 6.4 citation asserted the fold "follows" the spec. It does not: 6.4's mapping is keyed on used writing-mode AND direction (block-start = top/right/left), while the fold reads is_vertical alone and applies no vertical-rl reversal -- as its own comment says. Now scoped to 6.4's axis assignment, with the deviation named. Same class as #497. * "CSS 2 10.8 left unimplemented" over-broad -- 10.8/10.8.1 leading and baseline machinery IS implemented and cited elsewhere in the crate. Scoped to vertical-align within the line box. Plan-memo, fixed at the root rather than per finding: * 5.3.1's side-store answer was refuted by the code. "Intra-pass scratch consumed before the pass ends" is false on the do_carrier path: values from all three parameters reach ColumnFlowSlice and are drained a phase later by multicol (fill.rs:235-236, lib.rs:474) -- which 7 already said, 100 lines below. Retracted explicitly and re-grounded on shape, not lifetime. The real side-store->component candidate (ColumnFlowSlice itself) is now named and routed to the successor slot, which had been inheriting the wrong question. * three sites stored reconcile.rs's line count (5.5 drift history, 5.6 table, 8's commit-message delegation). Collapsed to one command. The 8 clause was the CRIT: amend is hook-denied, so two landed messages hold permanently uncorrectable figures. That count is now stored nowhere. * 10 carried two tables in incompatible tenses with different membership, a heading declaring "the five" over six rows, and one action registered twice. Collapsed to one table keyed on target file, past tense, no count stated. * R7's strip left live damage its repair missed: two orphaned fragments and a spliced 10 row that directed the umbrella-narrowing record into the slot SoT file. Repaired. * 9 now carries the uncited-spec disposition 3 promised it, with an explicit verdict instead of a pointer. * 6's harness base pinned to 658cc30 -- floating it on origin/main would compare against the wrong block once main advances, and pass. * 3's provenance: two rows, THREE citation instances; 10.8 is dual, and the authored half is where an over-claim can live. * 5.2's back-edge defence measured against the crate (6 existing sites, 2 bidirectional) instead of asserted; its withdrawal narrative handed to the review-history memo, its normative conclusion kept because 6 and 9 ground on it. * 5.3's helper-home question reclassified own, not neutral -- its premise (a sibling module) is created by this PR. Cap unaffected at 3/3. * cold gate re-derived from a live query rather than a stored PR list. Verified: body harness 6 hunks 226 == 226; call-site 11/11 incl. the three adjacent bools; clippy 0; 325 tests pass; trip-wires rc=0; cargo doc clean under -D warnings. mise run ci still cannot pass -- it depends on deny, red on main too via RUSTSEC-2026-0244 -- and is not claimed green. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…11 IMP + 6 MIN Gate #7 (5 axes on 9748e35..3c70b91) found 17 real defects, up from 10. PAUSE fired on trigger #3 (canary), twice: the ground I wrote into e4ab330's message is false, and this branch's own R29 fix added an instruction routing readers into a grep trap the memo had already solved elsewhere. ROOT, and the first use of §0's third exit. §0 says a claim is carried by the command that produces it, "or the claim does not belong here". Across four gates I used exits one and two — attach a command, rewrite the prose — and never the third. Eight of this gate's findings are prose characterising what the memo's own apparatus covers, which is precisely "prose asserting it was checked", about the checking itself. That layer is removed, not repaired: §4's lead-in, §7.1's "the whole class, measured" heading, §8's DoD gloss. Corrections to my own previous grounds, both measured: * "no widening could ever reach the claim" was FALSE — a one-token widening reaches active-lane-detail.md. So was "the other embedded commands are key-matched": four survivors are self-annotated as not key-matched, and §7.1 was repaired-and-kept in the same commit range where §10's was deleted for the identical defect. I took that ground from an agent whose central measurement I had already disproven. * §4's cells used grep -cwE 'LayoutBox\|BoxModel', which returns 0 as written and 5 rendered. Converted to two -e patterns, the convention §10 already carries. The trip-wire itself is clean — it holds a real alternation (probe: \| → 0, | → 2). Substantive, outside the bookkeeping: * reconcile.rs "drained within the same pass" is wrong for the multicol self-carrier case, which lib.rs clears rather than drains; the conclusion survives, the mechanism did not. Same claim corrected at the memo's §5.3.1 row. * #497 withheld §9.2.2.1 (Anonymous inline boxes) from collect.rs and §9.4.2 (Inline formatting contexts) from styled_run.rs — not §9.4.2 from both. Verified against #497's body and webref; both sibling sites fixed, both now carry spec name and title. * collect.rs carried a pointer at base and this PR had expanded it into a second copy of reconcile.rs's gating inventory. Back to a pointer — one canonical home. * §7.1's table had two coordinates off the base frame the memo's own rule mandates (mod.rs:562→774, :175-177→174-176), measured against 658cc30. * §7.1's sweep is keyed on vocabulary, not on the property tested: widening it surfaces a real site AND a false positive (components.rs:189, a different subject). Marked a seed with the authoritative predicate stated, rather than dressed as an inventory. * The 508 row's key is the figure, so it missed two sibling clauses in the same registry block this landing falsifies. Booked. * The slot note enumerated a subset and read exhaustive; two umbrella slots were unregistered and named nowhere. The set is not greppable — a grep cannot tell a registration from a mention — so it is stated with its predicate and its owner. elidex-ecs:219's "mirroring clear_inline_flows" is false on the probe axis but PRE-EXISTING: the move is byte-identical, so this PR documented the asymmetry rather than causing it. Under the ratified narrowing that is a defer, routed to the successor slot. File set stays at four, so §8's claim holds. Gates: body harness 6 hunks base=226 moved=226 rc=0 · call-site rc=0 · fmt rc=0 · clippy -D warnings rc=0 · doc -D warnings rc=0 · 325 tests · trip-wires rc=0 · preflight 0 hard. mise run ci is NOT green: deny is blocked by upstream RUSTSEC-2026-0244, red on main too.
…ing mechanisms this PR cannot enumerate Gate #8 (5 axes on 3c70b91..0769415). Axis 3 read all 1022 lines and enumerated the class gate #7 claimed to remove: 28 instances, of which gate #7 removed 3 and retained 25 as load-bearing — and the commit titled "remove the meta-claim layer" left the memo +3 lines / +152 words, its §7.1 replacement adding 70 words of the layer into the subsection whose heading it stripped. THE ROOT DIAGNOSIS IS REFUTED. The recurring class is not a removable layer; it is the standing one: claims authored without measuring the complement. Axis 2 settled the carrier question by writing a test rather than reading comments: multicol > outer div > inner div gives CARRIER RESIDUE container=false outer=false inner=true. So gate #8's own "drained or cleared within the same pass" was false — a nested IFC container is reached by neither terminal path — as is the component docstring's "lives only between the IFC layout and the multicol fill within one pass". Rather than correct the mechanism a third time, this drops the mechanism claim: the safety argument rests on render never reading a stray carrier, which is what the cited docstring actually supports, and enumerating the terminal-path set is routed to the successor slot. Same move for the gating universal. "Both writes are probe-gated" is true as measured (reconcile.rs skips the write under a probe; multicol's flows is empty under one) but it is a crate-wide claim whose complement I had not measured: block/children/shift.rs:127-129 asserts the opposite for InlineFlow and uses it to argue its skip is "redundant, not just inert". That staleness is pre-existing, so this states the in-function fact and routes shift.rs. Also: the #497 precedent named the wrong section for collect.rs at both sites. #497's PR BODY says the added citation was §9.2.2.1; the landed withdrawal 45c72c0 removed §9.2 "Controlling box generation", and its own removed text says the parent was chosen "precisely because which child applies is decided per arm". I had verified against the body — a record of intent, not of fact. Both sites now cite §9.2 with that provenance rule attached. Smaller: the ColumnFlowSlice bullet gained the entity-despawn carve-out its InlineFlow sibling already had; collect.rs's pointer regained the one fact the collapse dropped (the call to reconcile_flows is unconditional, so its gated clear runs on every non-early-return pass); the citation to ColumnFlowSlice's docstring no longer covers a clause that docstring does not make. Process error recorded: I applied Axis 1 and 4 fixes while Axes 2/3/5 were still running, so the tree moved under a live review. Axis 3 detected the drift and pinned to 0769415. Gates: body harness 6 hunks base=226 moved=226 rc=0 · call-site rc=0 · fmt rc=0 · clippy -D warnings rc=0 · doc -D warnings rc=0 · 325 tests · trip-wires rc=0. File set stays at four. mise run ci is NOT green: deny is blocked by upstream RUSTSEC-2026-0244, red on main too.
Closes defer slot
#11-css2-static-position-citation-sweep(partially — see "Carved out" below).Both errors were re-verified with
.claude/tools/webrefrather than trusted from the slot memo, per CLAUDE.md § "Spec citation".Error 1 —
§10.6.5is not where "static position" is defined (7 sites)heading CSS2 10.6gives §10.6.5 = "Absolutely positioned, replaced elements", which merely uses the term ("replace top with the element's static position"). The definition lives in §10.3.7 and §10.6.4, each opening:"and the next" being §10.3.8 / §10.6.5, so the pair covers replaced and non-replaced alike — which is what these placeholders record.
Cited as "§10.3.7 left/right / §10.6.4 top, mapped to logical axes": those sections define the term for physical axes, and glossing them as inline/block would invert in a vertical writing mode.
positioned/constraints.rs:70already states that caveat.Error 2 —
§9.2.1.1co-cited for a rule it does not contain (3 sites)body CSS2 anonymous①(§9.2.2.1, Anonymous inline boxes) carries the "white space that collapses away generates no box" rule verbatim. §9.2.1.1 (Anonymous block boxes) does not — its only "white" sits in the break-around-block parenthetical, a different rule.Two of those sites also assert the line-box consequence ("contributes zero block size", "is not pushed"), which §9.2.2.1 does not state either. That is §9.4.2's zero-height-line-box rule, now co-cited.
Counting by concept, not by string
A
CSS 2 §-prefixed grep missescollect.rs:92, where the prefix wraps to the line above. By concept there were 12§9.2.1.1sites. One was wrong —elidex-ecscomponents.rs:167said "anonymous inline formatting context (CSS 2 §9.2.1.1)", but §9.2.1.1 is anonymous block boxes and "anonymous inline formatting context" is not a CSS 2 term; re-cited to §9.4.2. The remaining 11 are anonymous-block-box or anonymous-block-in-inline contexts and are correct, so they are deliberately untouched.Classification is by the rule being cited, not the section number.
Also folded in
CSS Text §4.1.2was missing its level number (css-text-3 §4.1.2= "Phase II: Trimming and Positioning") — fixed at all three in-crate sites, not just the one the slot listed.collect.rsandstyled_run.rshad no module-level citation while siblingwhitespace.rsdoes.collect.rsturns text directly inside a block container into inline items → §9.2.2.1;styled_run.rs→ §9.4.2.Carved out, not dropped
The slot's
CSS 2.1→CSS 2naming normalisation is not here. Measured: 172 occurrences / 52 files / 9 crates, with 9 files carrying both forms. Not layout-confined, not parallel-safe (it collides with the L1 CSS lane), and a label difference rather than an error. Normalising layout alone would self-seed the inconsistency it aims to remove.An earlier draft handed it to the citation-hygiene program; that was withdrawn as false — none of the umbrella's six slices owns spec-name prose (
grep 'CSS 2' docs/plans/2026-07-citation-hygiene-*.md= 0 hits). It is tracked as its own slot,#11-css2-spec-label-normalisation.🤖 Generated with Claude Code