Skip to content

HOTSPOT-SPLIT 1/2: per-feature diagnostics, faults, property families, animation kinds; derived paint unions - #137

Merged
thejackshelton merged 46 commits into
masterfrom
hotspot-split-dragon
Oct 5, 2026
Merged

thejackshelton merged 46 commits into
masterfrom
hotspot-split-dragon

Conversation

@thejackshelton

Copy link
Copy Markdown
Contributor

HOTSPOT-SPLIT 1/2 (dragon package). Feature PRs no longer edit the same lines of the dragon registries: each feature owns its own file, and the central list has one line per feature, sorted by id, so two features only touch the same lines when their ids are neighbours. This lands before the in-flight PRs; the migration note is at the end.

What changed

  • Diagnostics: diagnostics/codes/<feature>.ts holds each feature's codes and their catalogue entries.
    • The seven legacy groups are s2, s3a, s4a, s5, tree, txt1c and anim-b1. repl-a and txt1a exist empty for the in-flight lanes.
    • codes.ts lists the legacy features first, in landing order, then the rest by id. DIAGNOSTIC_CODES keeps the same 49 codes in the same order.
    • catalogue.ts gathers the entries. The entry type and helpers moved to diagnostics/entry.ts.
    • test/diagnostic-codes.json is now the frozen legacy pin. Each later feature is pinned by test/diagnostic-codes/<feature>.json.
  • Faults: faults/<feature>.ts. The 25 faults are grouped by topic, and inl1a, inl2a and ovfl exist empty. CompilerFaults is the intersection of the groups, and NO_FAULTS holds the same values.
  • Paint registries:
    • PaintWrite and AnyLowering are derived from the registered lowerings.
    • PaintPlantName is derived from the emitters. PaintEmitter<K, P> takes the plant names as P, and the border emitter declares its two.
    • A paint module now edits only its own files.
  • Property families: properties.ts registers each family on one family(...) line in FAMILIES, in table order. LONGHANDS, SHORTHANDS, INHERITED, PROPERTY_ASPECTS and the role tables are derived from it. Shorthand order keeps overflow after flex (SHORTHANDS_MOVED). All values are unchanged.
  • Animation kinds: css/animation-kinds/<family>.ts, spread one line per family in sorted order. Shared kinds and types are in animation-kinds/kinds.ts.
  • Duplicate checks: test/registry-claims.test.ts fails when two features claim the same code, fault, longhand, shorthand, animation key, paint write kind or plant. It also fails when a central list is unsorted or a feature file is unregistered. Codes, faults, longhands and shorthands claimed twice also throw at load.

Values unchanged

Before regen, I imported both trees (origin/master and this branch) and dumped LONGHANDS, SHORTHANDS, INHERITED, PROPERTY_ASPECTS, PROPERTY_ROLE, TEXT_LONGHANDS, COLOR_LONGHANDS, NO_FAULTS, DIAGNOSTIC_CODES, CATALOGUE, ANIMATION_KINDS, the paint plants, emitter kinds, lowerings and paintWriteCss(). The two dumps are byte-identical. A type-level check showed that PaintPlantName, PaintWriteKind, keyof CompilerFaults and DiagnosticCode are the exact same unions as before.

Tests changed (intent kept)

  • diagnostics.test.ts, "the committed code lists only grow":

    • It still checks that the S2 codes and diagnostic-codes.json are in-order prefixes of the live list.
    • It now also checks that the legacy features equal diagnostic-codes.json exactly, and that every later feature equals its own pin in diagnostic-codes/<feature>.json.
    • It checks that a pin exists for every later feature and for no other, so a feature can't be removed without failing.
  • seams.test.ts spreads(): it reads each column of the FAMILIES family(...) lines (moving overflow's shorthands per SHORTHANDS_MOVED) instead of six spread blocks. The checks are unchanged: each family list is used once, each registry is its families in order, and the seams-floor.json floors still pin every name in order.

  • ua.test.ts, "diagnostics are built only from the catalogue": the exemption now covers the catalogue's own files (diagnostics/entry.ts and diagnostics/codes/<feature>.ts, where the entries now live) as well as catalogue.ts. Every other source file is still checked. A planted severity: 'error' in another file still fails the test.

Outside the spec

  • packages/dragon/src/emit/paint/border.ts: one line, the border emitter's type declares its two plants.

Verification

  • pnpm regen --force: exit 0, and git status is clean afterwards, so every generated output is byte-identical.
  • pnpm typecheck: pass.
  • pnpm test (full suite): 180 of 184 files passed. lanes.test failed only in "every device lane ran" (device step pending). ua.test was a real failure caused by the split; it is fixed in 5f58eb2 and passes alone (see "Tests changed"). android-profile.test and planted-swift.test timed out under load (120 s and 900 s) and pass when rerun alone.
  • Run on base ed58eae (origin/master).

Hot spots, measured

I replayed every merge commit on origin/master with git merge-tree --write-tree (376 merges) and counted the files that conflicted. I also read the open PRs' diffs against their bases.

hot spot conflicts in master's merges open stacks that edit it
packages/parity/src/fixtures.ts (group list) 37 all five: REPL/FORM, text, PNT1/VIS/BG2, OVFL, PNT2
packages/dragon/src/faults.ts (one-line NO_FAULTS) 15 text, OVFL
scripts/regen.ts (STEPS, MANUAL) and .gitattributes 7 text, PNT1/BG2, OVFL, PNT2
packages/dragon/src/css/properties.ts (six family spreads) 4 TDEC, VIS
paint registries (one-line PaintWrite, AnyLowering and PaintPlantName unions) 1 10 PRs: REPL, PNT1 ×6, VIS, BG2, PNT2
animation-kinds.ts 1 REPL, and every lane that adds a longhand
diagnostics/codes.ts, catalogue.ts and test/diagnostic-codes.json 0 so far REPL and TXT1a, both appending at the end

The other hot spots this PR does not split:

  • pixel-reference.test.ts (22 conflicts) is already fixed by the PIN-DERIVE: derived checks replace literal count pins that conflict on every landing #125 floors.
  • seams.test.ts and paint-seams.test.ts (7 and 5 conflicts; 13 and 15 open PRs) still pin global lists such as paintPlants(), PAINT_EMITTERS kinds and SUPPORT_FILES. They should move to floors next.
  • device-failures-*.json is device output.
  • stylesheet.ts and values.ts are code, not lists.

Migration note for in-flight lanes (do this at your next catch-up)

At the catch-up merge, take master's side of every hot-spot file below and move your additions into your own file. The
empty per-feature files named here already exist on master, so two lanes no longer edit the same lines.

All lanes

  • Diagnostic codes: do not append to diagnostics/codes.ts, catalogue.ts or test/diagnostic-codes.json (now frozen). Put your codes and their catalogue entries in packages/dragon/src/diagnostics/codes/<feature>.ts as diagnosticFeature([...codes], { CODE: error(...), ... }), and pin them in packages/dragon/test/diagnostic-codes/<feature>.json. A new feature adds its import and one line in DIAGNOSTIC_FEATURES, each in sorted order.
  • Faults: do not edit faults.ts. Put the fault type (one documented field per fault) and its defaults (false) in packages/dragon/src/faults/<feature>.ts. A new feature adds its import and one line in FAULT_GROUPS, each in sorted order.
  • Paint modules: delete your edits to PaintWrite, AnyLowering and their import type lines in lower/paint/registry.ts, and to PaintPlantName in emit/paint/registry.ts. Both are now derived. Type your lowering as PaintLowering<YourWrite> (you already do), and declare your plant names as the emitter's second type parameter: PaintEmitter<'kind-a' | 'kind-b', 'plant-1' | 'plant-2'>. A new module still adds one line to PAINT_MODULE_NAMES, LOWERINGS and EMITTERS.
  • Property families: delete your spreads from the six tables in properties.ts. A new family adds its import and one line in FAMILIES, family('<id>', X_LONGHANDS, X_SHORTHANDS, X_INHERITED, X_ASPECTS, X_CONTAINER, X_TEXT_ROLE), placed after the family it follows. Longhands added to an existing family need no properties.ts change.
  • Animation kinds: put each longhand's kind in packages/dragon/src/css/animation-kinds/<family>.ts. The paint seam families (radius, shadow, effects, outline, background-layers, scrollbar) already have empty files. A new family adds its file, its import and one ...X_ANIMATION line, each in sorted order.
  • Fixture groups: delete your import and FIXTURE_GROUPS line. Add '<group-id>': YOUR_GROUP, to GROUPS and your import, each in sorted order. Groups added after the split run after the legacy groups (after states), in id order, so run pnpm regen after the catch-up and retarget any pin that counts on your group's position (for example a values.test slice(-n); the legacy slice is now LEGACY_RUN_ORDER.length - 2 .. LEGACY_RUN_ORDER.length).
  • Regen steps: do not edit STEPS or MANUAL in scripts/regen.ts. Put your additions in scripts/regen-steps/<feature>.ts as { steps: [{ after: '<step>', step: {...} }], outputs: { '<existing step>': ['extra/glob/**'] }, manual: [{ command, outputs }] }. A new feature adds its import and one line in REGEN_FEATURES, each in sorted order. Add your .gitattributes line in sorted position (the file is sorted now).

Per lane

Expected leftovers, all one-line conflicts: two new fixture groups next to each other in sorted order, such as outline/overflow (PNT1/OVFL), radius/replaced (PNT1/REPL), controls/font-shorthand (FORM/TXT) and text-weight/transforms (TXT/PNT2); and neighbouring .gitattributes lines, such as expected-quads/expected-scroll (PNT2/OVFL).

🤖 Generated with Claude Code

thejackshelton and others added 29 commits October 4, 2026 14:13
…ator.ts) and its animator suite

The parity reference animator now wraps the translated root, so the Chrome frame lanes judge the code the generated Swift and
Kotlin run; the animator suite (rt-vectors/animator, harness op rt-animator, p1 suite after hit) checks the translations bit for
bit against it on the host and, through device-vectors, on device. No native runtime or row changes.
…ilies, animation kinds and derived paint unions

Each feature owns its own file and one sorted line in the central list: diagnostics/codes/<feature>.ts (codes with their
catalogue entries, pinned per feature in test/diagnostic-codes/<feature>.json after the frozen legacy list), faults/<feature>.ts,
css/animation-kinds/<family>.ts, and one family(...) line per property family in properties.ts. The paint write and plant
unions are derived from the registered modules, so a paint module edits only its own files. Values are unchanged (same codes,
order, catalogue, faults, longhand tables and kinds); registry-claims.test fails when two features claim one name.
…own files (entry.ts, diagnostics/codes/<feature>.ts)
Commands: pnpm regen; pnpm run parity:devices; pnpm regen
The driver released /tmp/dragon-train-quiet as soon as the machine went quiet, so jobs queued behind the request started
beside the rerun and loaded the machine again: #74's quiet rerun ran at load ~38 and failed 24 files on timeouts after its
device lanes had passed. waitForQuiet takes hold: a quiet result keeps the request until the driver's rerun ends; a failed
wait still releases it. land.test pins both.
ANIM-b1 3b part 1: the runtime animator as a translated root, with its animator suite
…f the whole suite

The quiet rerun of the full suite kept failing on timeouts (#124: 15 files, all timed out, at load still ~35 from processes
outside the heavy lease). After a failed pnpm test the driver now reads the failing files from the vitest log and reruns
each alone on a quiet machine, same assertions and timeouts; every one must pass. A run with no summary (crash, kill) or
more than SOLO_RERUN_MAX failing files reruns the whole suite as before. land.test pins the log parsing.
…ide it

The parallel scheduler took a whole-tree git add -A snapshot when one step
finished, while another was deleting and rewriting its outputs, and aborted on
'unable to stat'. Snapshots now exclude (git exclude pathspecs, same glob
semantics) the declared outputs of every step still running; those paths were
already left out of change detection, so the stray-write guard is unchanged.
land: hold the quiet request through the quiet test rerun
… maximal CSS support; COVERAGE-RANK and CI-FULLTEST lanes
…eal-world reach per size

docs/goals/milestone-2-proof/coverage-rank.md is generated by scripts/coverage-rank.ts (PR to follow)
from data/coverage-rank-input.json and the chromestatus snapshots (csspopularity and
featurepopularity, fetched 2026-10-04).
…ish; non-test proof errors stop the driver; clean other trees' ignored outputs before a proof
land: rerun each failing test file alone on a quiet machine
… reruns failing files alone; skip the master proof for a tree this run proved
regen: a snapshot never reads the outputs of a step still running beside it
@thejackshelton thejackshelton added the landing-failed The landing driver stopped this PR; see its comment label Oct 5, 2026
thejackshelton and others added 3 commits October 4, 2026 21:29
land: batched landing (one proof per batch, prefix bisect, per-PR merges in order)
… SIGTERM kills the running step through a supervisor and records INTERRUPTED, failing no PR
thejackshelton and others added 13 commits October 4, 2026 21:59
…a master left unproved; the lock records the driver and kills an orphan; cleanup after any abnormal death, including the run's devices
…king; lock pids are matched with their start times; the merge critical section starts at gh pr merge
…early one; lock files written atomically, a missing start time holds; the unproved record clears only when master is on a proven tree
…y, waits retry until a pid parses, the early-signal case uses a 3 s window; land: a stale lock is taken over by an atomic rename
#145's clean ran `git clean -fdX` with `-e !node_modules/` negations. A negation un-ignores the kept directory, so git
descended into it and deleted the ignored files nested inside: node_modules/.pnpm/*/dist/, every installed package's code.
The next proof's `pnpm test` failed to start (vitest/dist/cli.js missing) and pnpm install --frozen-lockfile did not restore it.
Pathspec excludes don't help: git clean removes a whole ignored directory as one unit. The driver now lists the ignored files
(git ls-files --others --ignored) and removes those outside the kept trees itself. land.test adds nested dist/ files under
node_modules to the kept set and a top-level dist/ to the removed set; the old clean fails it.
land: keep installs when cleaning ignored outputs before a proof (hotfix for #145)
@thejackshelton
thejackshelton merged commit 23e7e98 into master Oct 5, 2026
5 checks passed
@thejackshelton
thejackshelton deleted the hotspot-split-dragon branch October 5, 2026 04:25
thejackshelton added a commit that referenced this pull request Oct 5, 2026
…137/#138): PNT2's plants on TRANSFORM_EMITTER's type, the transforms group one GROUPS line, the quads regen step in scripts/regen-steps/pnt2.ts after ua, .gitattributes in sorted position; master's side of the hot-spot files; targets.ts keeps hitCaseIds and the refused-aware p1 hit suite beside master's animator suite
thejackshelton added a commit that referenced this pull request Oct 5, 2026
#150-#152)

# Conflicts:
#	packages/dragon/src/css/animation-kinds.ts
#	packages/dragon/src/diagnostics/catalogue.ts
#	packages/dragon/src/diagnostics/codes.ts
#	packages/dragon/src/emit/paint/registry.ts
#	packages/dragon/src/lower/paint/registry.ts
#	packages/parity/src/fixtures.ts
#	packages/parity/test/device-vectors.test.ts
#	packages/translate/test/p1-floor.json
#	packages/translate/test/translate.test.ts
thejackshelton added a commit that referenced this pull request Oct 5, 2026
…ers): the resize-capture step moves to scripts/regen-steps/mq-r1.ts (after capture, so before profile-rows), the media-runtime group to one sorted GROUPS line, .gitattributes sorted; hit suite 2092 beside master's animator suite
thejackshelton added a commit that referenced this pull request Oct 5, 2026
…138): SELD-R2's faults move to faults/seld-r2.ts (one FAULT_GROUPS line), the interaction group is one sorted GROUPS line, master's side of the central files and tests; project.ts keeps both nativeLanes and interactionLanes; p1/hit pins carried at 2060 until the regen re-derives them
thejackshelton added a commit that referenced this pull request Oct 5, 2026
… pipeline work) into inl1a-lowering. Conflicts:

- faults: INL1a's brAsSpace and inlineWrapperPerElement move into faults/inl1a.ts (HOTSPOT-SPLIT's per-feature fault files).
- ios-layout.ts: INL1a's Lowerer gains the image naturals; a replaced element is never inline-level (laid out as its own leaf beside the inline content, as REPL-a does); lowerBox's line strut counts only inline content, not replaced leaves (review finding 3 on #91: a block holding only an img gets no strut).
- native-program.ts: REPL-a's transform-moves walk with INL1a's flat inline views.
- rt-hit.ts: master's child count with INL1a's named inline-box refusal.
- computed-checks.ts and elements.ts: REPL-a's replaced check beside INL1a's inline-level and inline checks; br beside the replaced tags.
- expected-dump.ts, native-support.ts, native-build.ts, device-run.ts, targets.ts: both sides' imports, walks, plants (the line plant with image-offset-1) and corpus suites (INL1a's hit-vector count beside ANIM-b1's animator suite).
- device-lanes.test.ts and device-run.test.ts keep both sides' tests.
thejackshelton added a commit that referenced this pull request Oct 5, 2026
…peline changes) into form-a-v2; no conflicts. Generated outputs take the merged side, rebuilt by the following regen
thejackshelton added a commit that referenced this pull request Oct 5, 2026
…OTSPOT-SPLIT #137/#138) into form-a3-v2

Per the HOTSPOT-SPLIT migration note: master's animation-kinds.ts and fixtures.ts are taken whole; appearance's kind (discrete, Chrome 145 snapshot) moves to animation-kinds/box.ts, and the controls group is one sorted GROUPS line (it now runs after the legacy groups, in id order). Generated outputs take the merged side, rebuilt by the following regen.
thejackshelton added a commit that referenced this pull request Oct 5, 2026
…HOTSPOT-SPLIT #137/#138) into form-a4-v2; no conflicts and no hot-spot edits of its own. Generated outputs take the merged side, rebuilt by the following regen
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