Repository navigation
T130: non-integer order from calc() rounds half toward +infinity and clamps to int, as Chrome does - #61
Merged
Conversation
…xt px is proven in, and in the border shorthands css/values.ts: a math function in border, border-<side>, border-block(-start/-end) and border-inline(-start/-end) is the <line-width>, typed and refused as the border-*-width longhands are (css-backgrounds-3 §3.1, css-logical-1 §6.3); shorthands/border.ts and logical.ts assign it to the width. Fixtures (values group, ltr and rtl): values-calc-contexts-block, -flex, -positioned, -display-none, -root, -root-min-max put each of calc(), min(), max() and clamp() in every box property in the block, flex-row/column, relative, absolute (cb-ltr and cb-rtl), display-none and root contexts, and gaps in every flex line mode and on a non-flex container, plus px, rem and % insets, flex-basis and gaps on a static block; values-calc-border-shorthand; values-calc-length-max, the CSS_LENGTH_MAX golden (T118J): Chrome collapses float(33554429) with -33554430 to -2 device px at every DPR. values-reject-order-fraction pins the order refusal. Retargets: values-reject-border-shorthand moves from calc(1px + 0.5vw), now accepted, to calc(1px * 2px / 1px) solid #000, still refused (typed arithmetic), refused on border-left-width. values.test.ts blinkNumber writes printf %g (3.35544e+07), which the new computed values need.
…ture, then pnpm run profile:rows and pnpm run parity:capture three times to the fixed point, then pnpm run profile:rows; pnpm run parity:dpr-capture; pnpm run layout:vectors; pnpm run layout:dpr-vectors; pnpm run layout:break-vectors; pnpm run parity:break-capture; pnpm run parity:pixel-capture; pnpm run native:gen; node --conditions=dragon-internal examples/music-player/tools/check.ts (pnpm run north-star:check lacks the condition, T124); pnpm run parity:glyph-b3 -- --write-bottom-pins; node --conditions=dragon-internal packages/parity/src/cli/media-sweep.ts (then --check: 18/18, 286 samples); pnpm run wpt:run -- --target web and pnpm run wpt:update-expectations -- --target web (no change); pnpm run tw:sweep. Profiles: 1922 rows added on each target (web and ios exact, android unsupported), none removed or changed. Tailwind 4.3.3: web and ios 2214 -> 4121 supported, none the other way, 0 mismatch
…nes -- --run-host) for the CALC-2 cases; device lanes not run (device step pending, landing-queue rule)
…h its own height treated as auto (T128) css-flexbox-1 §4.5 content size suggestion; ported from Blink third_party/blink/renderer/core/layout/flex/flex_layout_algorithm.cc at 145.0.7632.6 (BSD, The Chromium Authors; sha256 b0ea68654c62d2ca1d73d801ffca395901aa37e51569281266fc9ef87a9e892c) lines 914-923 and 1117-1120 (LayoutResult::IntrinsicBlockSize). A percentage height child of such an item is refused as percent-height-flex, since Blink resolves it against the item's set height.
…ontainer shorter than its items, px and calc() heights, empty and non-empty content, ltr and rtl; Chrome captures from pnpm run parity:capture and pnpm run parity:dpr-capture
…ize (flex_layout_algorithm.cc lines 1078-1084 at 145.0.7632.6): an item that cannot shrink takes its specified size without measuring its content, which gives the same used size and avoids 4 percent-height-flex refusals
…ure values-calc-flex-column-auto-min): pnpm run grammar:gen; pnpm run parity:capture and pnpm run profile:rows twice (fixed point); pnpm run parity:dpr-capture; pnpm run layout:vectors; pnpm run layout:dpr-vectors; pnpm run layout:break-vectors; pnpm run parity:break-capture; pnpm run parity:pixel-capture; pnpm run native:gen; node --conditions=dragon-internal examples/music-player/tools/check.ts; pnpm run tw:sweep; pnpm run wpt:run -- --target web; pnpm run wpt:update-expectations -- --target web; pnpm run parity:glyph-b3 -- --write-bottom-pins; node --conditions=dragon-internal packages/parity/src/cli/media-sweep.ts (then --check); pnpm run parity:lanes -- --run-host. Every existing vector and capture is byte-identical; emitted CSS changes only in the compilation-digest header; the new fixture adds its vectors, captures, pixel and break records; corpus.json and corpus-dpr.json carry the new engine digests
…ne as Chrome does Blink CSSMathFunctionValue::ComputeInteger (css_math_function_value.cc 89-97, range kInteger) is RoundHalfTowardsPositiveInfinity, floor(v + 0.5) in double (math_extras.h 133-139), then ClampToWithNaNTo0<int>; Chrome 145 getComputedStyle agrees on every probed value (calc(-1.5) is -1, calc(0.5) 1, calc(0.49999999999999994) 1, calc(3e9) and a 3000000000 literal 2147483647). Engine: units.ts orderInteger; the environment pass (environment.ts) resolves order with it, at every DPR; validate.ts takes any finite order (the compiler sends a folded number calculation unrounded); planted faults orderHalfEven and orderUnclamped (block.ts, harness.ts). Compiler: css/values.ts no longer refuses a non-integer order calculation; emit/web-css.ts writes it as calc(<n>) so Chrome rounds it as the engine does. Fixture values-order-calc-round (ltr and rtl): 25 flex rows of [r, X, r], halves of both signs, values beyond the int range, nested min/max/clamp and var(); each plant fails it. Tests: calc.test.ts (engine), units.test.ts (compiler), values.test.ts (plants and getComputedStyle order of all 150 items).
…the translator requires it); an infinite or NaN order calculation stays refused with its reason (units.test.ts)
…e, identical), parity:dpr-capture, layout:vectors, layout:dpr-vectors, native:gen, north-star:check (unchanged), parity:lanes -- --run-host New files only for values-order-calc-round(-rtl): Chrome captures at DPR 1, 2, 3 and 2.625, emitted CSS, vectors and snap vectors; every existing capture and vector is byte-identical. Profile rows gain the case as a proof (no status changes). The translated engines and harnesses carry orderInteger and the two order faults; corpus.json and corpus-dpr.json move with the new fault keys and vectors; lanes.json is host-only (device lanes not run).
…s carry the new compilation digest; bodies and captures unchanged), layout:break-vectors, parity:break-capture (engine equals Chrome breaks 1386/1386), parity:pixel-capture, parity:lanes -- --run-host (lanes.json unchanged) New files only for values-order-calc-round(-rtl) in break-vectors, expected-breaks and expected-pixels (manifest appended).
thejackshelton
added a commit
that referenced
this pull request
Oct 1, 2026
…in amendment 1 (catch up before review: GitHub can't use the merge driver)
…catch up before review): no source conflicts; generated outputs keep this side (master's .gitattributes merge=dragon-generated) and pnpm regen rebuilds them in the next commit
…1: catch up before review): no source conflicts; generated outputs keep this side (master's .gitattributes merge=dragon-generated) and pnpm regen rebuilds them in the next commit
… catch up before review): no source conflicts; generated outputs keep this side (master's .gitattributes merge=dragon-generated) and pnpm regen rebuilds them in the next commit
ApprovabilityVerdict: Not approved Macroscope's review found this PR not approvable — Although many changed files are generated parity artifacts, the source changes modify CSS acceptance/emission and existing flex and order layout behavior across production paths. The new intrinsic measurement logic and cross-target generated engine changes make this broader than a small, self-contained compatibility fix. You can add or adjust custom eligibility rules. Learn more. |
now in the base): css_math_function_value.cc lists packages/layout/test/calc.test.ts as a reference; new entry platform/wtf/math_extras.h (bsd-apple, header-bsd-2, tag 145.0.7632.6 sha256 c71bc62c..., lines 133-139 RoundHalfTowardsPositiveInfinity) referenced by calc.test.ts. THIRD_PARTY_NOTICES.md is rebuilt by pnpm regen next
…npm regen: fixed point after 3 passes, 34 steps run): emitted CSS (compilation digests), the translated Swift and Kotlin engines and harnesses, corpus.json and corpus-dpr.json, the values-calc-flex-column-auto-min vectors, profiles and expected-fonts, and the host-only lanes.json (device lanes not run; the train's device run supplies them)
… buildItem (the flex-shrink 0 shortcut, lines 1078-1084) and columnIntrinsicBlockSize (IntrinsicBlockSize, 914-923 and 1117-1120), now that PORT-0 (#52) is in the base; chrome-ports.test.ts 13/13
…tHub cannot apply the dragon-generated merge driver, so the PR was conflicting on generated files; no source conflicts; generated outputs keep this side and pnpm regen rebuilds them next
…s again, before the first regen: no source conflicts; generated outputs keep this side (merge=dragon-generated) and pnpm regen rebuilds them next
…und again, before the first regen: no source conflicts; generated outputs keep this side (merge=dragon-generated) and pnpm regen rebuilds them next
…npm regen: fixed point after 2 passes, 19 steps run): the translated engines and harnesses with master's EMS-b paint roots, corpus files and the host-only lanes.json (device lanes not run; the train's device run supplies them)
…y-lease.sh pnpm regen: fixed point after 3 passes, 36 steps run): emitted CSS digests, the translated engines and harnesses, corpus files, profiles, tailwind snapshot and the host-only lanes.json (device lanes not run; the train's device run supplies them)
…y-lease.sh pnpm regen: fixed point after 2 passes, 19 steps run): THIRD_PARTY_NOTICES.md with math_extras.h, emitted CSS digests, the translated engines and harnesses, corpus files and the host-only lanes.json (device lanes not run; the train's device run supplies them)
…-round: no source conflicts; generated outputs keep this side (merge=dragon-generated) and pnpm regen rebuilds them next
…npm regen: fixed point after 3 passes, 36 steps run): emitted CSS digests, profiles, the translated engines and harnesses, corpus files and the host-only lanes.json (device lanes not run; the train's device run supplies them)
…REPL-a engine and board) into flex-auto-min for train 1: flex.ts buildItem keeps master's ratio and replaced-item branches and T128's column suggestion for a sized box item (columnIntrinsicBlockSize; a replaced item keeps contentMain); percentMainHeight takes master's LayoutNode; docs/ports.json flex_layout_algorithm.cc lists master's ratio.ts port and T128's two flex.ts ports; generated outputs keep this side and pnpm regen rebuilds them next
…icts; generated outputs keep this side and pnpm regen rebuilds them
…pm regen: fixed point after 3 passes, 38 steps run, 3466.8 s): host-only lanes.json (device lanes run in the train)
…pm regen: fixed point after 3 passes, 38 steps run, 3287.8 s): host-only lanes.json (device lanes run in the train)
macroscopeapp
Bot
dismissed
their stale review
October 2, 2026 11:41
Dismissing prior approval to re-evaluate ebc17b9
Commands: pnpm regen; pnpm run parity:devices; pnpm regen
…ng stop (LAND-3 ruling); PNT1 split; FORM-a restack
- train build judges each position's device run against the device evidence committed on the train's base (lanes.json and device-failures-<target>.json), not by the lanes command's exit code: every lane must pass or fail as on the base, a failing lane may list no failure the base does not, and lane parity must pass with no stale lane (deviceRunProblems). It also checks the run rewrote lanes.json and the lanes commands exited 0 or 1. - train build runs pnpm regen again after the device run (POSITION_STEPS), so native-lanes.ts follows the run's lanes.json in the position's regen commit. - pr:review vouches for Macroscope's 'No code objects were reviewed.' skip under the 'already reviewed' guard: the head's patch id over reviewed paths must equal an earlier reviewed commit's. - A member whose PR head is a position from an earlier build is merged at that head (memberTip walks its train-made commits down to the clean head), so land's push fast-forwards it; check still predicts against the clean head's patch id. - land stops on a review/* base with the exact 'gh pr edit <n> --base master'.
…review passes a commit whose every Macroscope check was skipped with exactly 'Monthly spending limit reached (workspace setting).', prints UNREVIEWED, and still requires CI to pass and every finding to be answered (reviewExit); a near-miss title or a mixed result fails. AGENTS.md step 4 records the rule. pr-review.test.ts pins each case; the outcome pins gain unreviewed: false
LAND-3: merge-train fixes from train 1 (device run judged on evidence, regen after devices, no-code skip vouch, rebuild on an earlier position)
…ication time against the run's start, not by a content change: train 1's rebuilt position 1 merged #59's earlier position, whose lanes.json already held this tree's device run, so the new run wrote identical bytes and the build stopped with 'the device run did not rewrite'. deviceRunWrote is pinned in merge-train.test.ts
…d to 0 at restack
LAND-3b: train build tells the device run wrote lanes.json by its file time, not a content change
Commands: pnpm regen; pnpm run parity:devices; pnpm regen
T128: column flex automatic minimum size measures content with the item height as auto (Blink IntrinsicBlockSize)
Commands: pnpm regen; pnpm run parity:devices; pnpm regen
Commands: pnpm regen; pnpm run parity:devices; pnpm regen
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed
T130: a non-integer
orderfrom a math function now rounds as Chrome does. Blink's CSSMathFunctionValue::ComputeInteger (css_math_function_value.cc 89-97, range kInteger) uses RoundHalfTowardsPositiveInfinity: floor(v + 0.5) in double (math_extras.h 133-139), then ClampToWithNaNTo0. All sources are at 145.0.7632.6 (BSD). Chrome 145 getComputedStyle agrees on every probed value: calc(-1.5) gives -1, calc(0.5) gives 1, calc(0.49999999999999994) gives 1, and calc(3e9) and a 3000000000 literal both give 2147483647.units.tsaddsorderInteger.environment.ts) resolves order with it at every DPR.validate.tsaccepts any finite order, because the compiler sends a folded number calculation unrounded. NaN and infinities are still rejected.orderHalfEvenandorderUnclamped(block.ts, translate harness.ts).css/values.tsno longer refuses a non-integer order calculation.emit/web-css.tswrites it ascalc(<n>), so Chrome rounds it the same way the engine does.values-order-calc-round(ltr and rtl): 25 flex rows of [r, X, r] covering halves of both signs, values beyond the int range, nested min/max/clamp, and var(). Each plant fails it.What passed
Caught up with master to the train 1 freeze base 1f17b6e (#64 SIZE-ar, #65, #66 INL1a breaks, #67 REPL-a engine, #68 T116):
styleNeedsEnvironmentand keeps T130's order check, now also for a replaced child: REPL-a's replaced leaves carryorder, and without the check a replaced flex item's order 1.5 reached the engine unrounded at DPR 1. calc.test.ts pins it (it fails without the replaced check: [10, 0] instead of [0, 20]).Stacked on CALC-2 (#60, calc2-contexts e6e6b7f, itself on T128) for the train, with the PM ruling's retarget:
values-reject-order-fraction(CALC-2's pin of the refusal oforder: calc(1.5), which T130 makes accepted) now pinsorder: calc(1 / 0), still refused with "it divides by zero or produces an infinite or NaN value" (the compiled diagnostic matches the spec's span and message prefix). The intent is kept: an order calculation Dragon still refuses.fixture-groups/values.tsandunits.test.tskeep both sides.docs/ports.json registers T130's citations, per the PM ruling: css_math_function_value.cc lists calc.test.ts as a reference, and a new entry math_extras.h (bsd-apple, header-bsd-2, lines 133-139) is referenced by calc.test.ts.
/tmp/heavy-lease.sh pnpm regenrebuilt the generated outputs in their own commit (ebc17b9, fixed point after 3 passes).On ebc17b9:
pnpm typecheck: pass./tmp/heavy-lease.sh pnpm teston ebc17b9: queued behind the other members' regens; the result follows in a comment.Train 1 (freeze base f78f198 / 1f17b6e)
This PR is a member of merge train 1 (AGENTS.md step 8), in this order: #59 T128, #60 CALC-2, #61 T130, T129, seld-r1. The train merges each member onto the previous position, so members that touch the same lines are stacked, with their overlaps resolved and reviewed in the member branches rather than in the train: CALC-2 merges T128, T130 merges CALC-2, and T129 merges T130. Until an earlier member lands, GitHub shows its changes in this diff too. seld-r1 sits on master alone; its merges onto the earlier positions were simulated clean, and every position's reviewed-path patch id equals its member's clean head (
git merge-treechain pluspatchIdOver), so each position should be vouched at landing.The device lanes, and the regen of each position, run in the train itself: one device run per position. Master now has T116 (#68), so device-pixels is iOS 57 / Android 86 on master; each position's device run is compared against that.
Changed tests and checks
orderrule changes from integer to any finite number. The reason: the engine now owns the rounding, as the PM ruling requires (the compiler may not round).calc.test.tspins that NaN is still rejected.calc.test.ts: orderInteger against 21 Chrome rows, the plants, and document order for ties.units.test.ts: the compiler sends the value unrounded, web CSS keepscalc(), a literalorder: 1.5is still invalid, and infinite or NaN stays refused.values.test.ts: the plants and the getComputedStyle order of all 150 items.values-reject-order-fraction(from CALC-2) is retargeted fromcalc(1.5)tocalc(1 / 0), as above.🤖 Generated with Claude Code
Note
Add Chrome-compatible rounding and clamping for non-integer
orderfromcalc()ordervalues fromcalc()are now passed through unrounded and rounded by the engine: half ties round toward positive infinity, then values clamp to the signed integer range, matching Blink'sComputeInteger(seeunits.orderIntegerin units.ts).ordervalues; the environment pass resolves them via the newenvironment.resolveOrderin environment.ts.orderHalfEven,orderUnclamped) in block.ts, wired into the translate harness and generated Swift/Kotlin output.calc()/min()/max()/clamp()widths in physical and logical border shorthands are now parsed as border-width values instead of being rejected (values.ts, border.ts, logical.ts).calc(...)declarations in web-css.ts.EngineFaultsin the generated Swift/KotlinBlockfiles gained two new fields; out-of-tree consumers of these generated types must be updated.Macroscope summarized ebc17b9.