Hazel reports · ^report(18) · 2026-10-19

#2635 has failed CI on every run since the merge, for three known reasons

Cyrus asked why CI fails on #2635, the branch that merges modular editors (#2469) into the livelits branch (#2597). The answer, from all 97 of #2635's CI runs, the failing tests in 10 of them, and both parents' runs over the same eighteen days.

Short answers. As of 2026-10-19 at 09:55 MDT. Every run is linked below, and its numbers are in this page's data.

  1. It is the merge, and it has been since the first run. #2635 has run CI 97 times since it was made on 2026-10-01, and it has never passed: 43 runs failed and 54 were cancelled by a newer push. Every failing run read (10 of the 43, from the first, on 10-01, to the last, on 10-17) fails the same tests: 8 until 10-17, and 10 once the branch took #2469's reorganized tests that day.
  2. Each parent passes on its own, with the same tests. #2597 is green at f8ae6f2b9c (4,522 tests in Fast checks and 4,974 in Full tests). #2469 is green at c349058154 (4,810 and 5,202), which contains the commit #2635 took on 10-17, with the same Test_DefStaticsParity.re. Over these days #2597 had 26 green runs and #2469 33; #2635 had none. Each failing test belongs to one side: the module-analysis tests are #2469's, and the table test is the livelits branch's.
  3. Three causes, all known since the merge. Two were written into its commit messages on 10-01, and all three have been listed as the branch's known failures since 10-10:
    • 8 tests: #2469 analyzes a module one member at a time, using dev's module statics. Modules II, which is on the livelits branch only, replaced those statics. So the merge analyzes a module literal whole, and the tests' counts of what is re-analyzed come out low.
    • 1 test: dev's canonical completion closes a stray [ inside a table cell. #2469 has it through dev. #2597 does not: its dev is from the morning of 09-22, hours before canonical completion (#2374) landed. So the livelits table test's input no longer makes the hidden error it checks for.
    • 1 test: one livelits document elaborates differently per item than as a whole program. Its cause has not been found. Update, 2026-10-19: found and fixed, below.
  4. The fix for the 8 already exists. Andrew's #2687 (the standard library, into #2469) carries modular editors with Modules II, and on 10-18 he rebuilt the per-member analysis on Modules II (00bc805ca1). Its CI is green, with the same DefStaticsParity cases and the same expected counts (5,298 and 5,709 tests). Taking that into #2635 should clear the 8. It may need adapting, because #2687 has Modules II parts 1 and 2 as they are now, and #2635 has parts 1 to 3 as they were on 09-16. That leaves two: the table test needs a new input, and the one mismatch needs finding. The table test will also fail on #2597 itself when it next merges dev, which is 484 commits ahead. Cyrus's plan for merging into dev puts Andrew's modular editing PRs ahead of the livelits and performance PRs, so the rebuilt analysis reaches the livelits branch through dev in any case; taking it into #2635 now would only get there first.

Update, later on 2026-10-19: #2635 is green. With #2699 merged, #2635 passed Fast checks and Full tests on 90ed4505bf and again on 5961401df2, its first green runs since 2026-10-01. What happened to each of the next steps below, and what is still open (#2597's table test, a new conflict in one file, the merge plan for dev), is in ^report(23).

Update, 2026-10-19 at 12:45 MDT: each of the three causes has a fix. The third cause is found, and it was a real bug in incremental statics: a livelit use was not analyzed again when the livelit it applies changed (1131a457e4). The table test has an input whose error stays hidden under canonical completion (27f100e37c). And #2699, a draft into #2635, brings in Andrew's per-member analysis on Modules II, with one fix of its own (223357135a). On GitHub, #2635's Fast checks at 1131a457e4 now fail only the 8 module tests (5,552 tests run), and #2699's pass; #2699 merges into #2635 once its Full tests pass too. Details in the update below.

10-0110-0310-0510-0710-0910-1110-1310-1510-1710-19#2635 livelits × modular editors0 green · 43 red · 54 cancelled#2597 the livelits branch26 green · 7 red · 45 cancelled#2469 modular editors33 green · 7 red · 25 cancelled#2687 modular editors + Modules II7 green · 10 red · 5 cancelled88888810● a failing run read, with its number of failed tests (dates in UTC)f8ae6f2b9c: 4,522 + 4,974 tests passc349058154, with what #2635 took on 10-17: 4,810 + 5,202 pass5cf71f2d30, the port on Modules II: 5,298 + 5,709 pass
Every CI run on the four branches, 2026-10-01 to 2026-10-19, one tick each: green passed, red failed, grey cancelled (a newer push replaced it). The dots above #2635 mark the failing runs read, each with its number of failed tests. The circled ticks are the commits that #2635's last run is compared with. #2687 is Andrew's branch that carries the per-member analysis rebuilt on Modules II. Its red runs, from 10-16 to 10-18, failed three other DefStaticsParity cases (moving a member above or below, and mega-1k), and none since. #2469's own red runs come and go within hours (it is under active work; see below). #2635's have never stopped.
DSP 12 → 1DSP 46 → 1DSP 334 → 2DSP 382 → 1DSP 392 → 1DSP 402 → 1DSP 412 → 1DSP 423 → 1Table 1true → falseDSP 2mismatch8 · per-member module analysis meets Modules II#2469's tests: units re-analyzed after an edit, expected → received1 · dev's completiona livelits table test1 · not founda livelits document#2635's last run, 9e7258b55b (2026-10-17): the same ten fail in Fast checks (5,551 tests) and Full tests (6,094).All three have been known since the merge: 43089b065d and 11fbc4480d on 2026-10-01, and cefa5c2c5c on 2026-10-10.
The ten tests that fail on #2635's last run, grouped by cause. For the eight module tests, the numbers are the test's expected and received counts of what is re-analyzed after an edit. The table test checks a flag: expected true, received false. The corpus test reports a mismatch at a livelit application.

Red since the first run

#2635 (integration/livelits-modular-editors) was made on 2026-10-01 from the livelits branch, by merging dev (at 9b3f18323a, modular editors' base) and then #2469's own commits. Since then it has taken the livelits branch's later work as cherry-picks, and on 10-17 it took #2469 again, at 19fef7c9bb. Its CI has run 97 times and has never passed. Of the 43 failing runs, these 10 were read in full: the first and the last, about every sixth in between, and the one just before the 10-17 update.

Run started (UTC)HeadRunFailedTests runFailing tests (Fast checks)
2026-10-01 16:151a2f0338fb3689063924185,281DefStaticsParity 1, LabelBench 0, ModRoot 7, ModRoot 9, ModRoot 10, ModRoot 11, TypeDeps 0, Editing.TableDecorations 1
2026-10-01 17:2642f1ab0be73689943081185,281DefStaticsParity 1, LabelBench 0, ModRoot 7, ModRoot 9, ModRoot 10, ModRoot 11, TypeDeps 0, Editing.TableDecorations 1
2026-10-03 19:08493adc07613714680226785,291DefStaticsParity 1, LabelBench 0, ModRoot 7, ModRoot 9, ModRoot 10, ModRoot 11, TypeDeps 0, Editing.TableDecorations 1
2026-10-05 18:08109d3557c83735371381685,304DefStaticsParity 1, LabelBench 0, ModRoot 7, ModRoot 9, ModRoot 10, ModRoot 11, TypeDeps 0, Editing.TableDecorations 1
2026-10-10 13:21cefa5c2c5c3805538386885,326DefStaticsParity 1, LabelBench 0, ModRoot 7, ModRoot 9, ModRoot 10, ModRoot 11, TypeDeps 0, Editing.TableDecorations 1
2026-10-11 00:23602498d7aa3809825158585,343DefStaticsParity 1, LabelBench 0, ModRoot 7, ModRoot 9, ModRoot 10, ModRoot 11, TypeDeps 0, Editing.TableDecorations 1
2026-10-12 07:18126f595ce93821699878385,390DefStaticsParity 1, LabelBench 0, ModRoot 7, ModRoot 9, ModRoot 10, ModRoot 11, TypeDeps 0, Editing.TableDecorations 1
2026-10-14 12:1241897ec3a53856204652585,390DefStaticsParity 1, LabelBench 0, ModRoot 7, ModRoot 9, ModRoot 10, ModRoot 11, TypeDeps 0, Editing.TableDecorations 1
2026-10-17 03:13438812718b3899793926085,391DefStaticsParity 1, LabelBench 0, ModRoot 7, ModRoot 9, ModRoot 10, ModRoot 11, TypeDeps 0, Editing.TableDecorations 1
2026-10-17 12:069e7258b55b39031252985105,551DefStaticsParity 1, DefStaticsParity 2, DefStaticsParity 4, DefStaticsParity 33, DefStaticsParity 38, DefStaticsParity 39, DefStaticsParity 40, DefStaticsParity 41, DefStaticsParity 42, Editing.TableDecorations 1

The list is the same on every run until 10-17. On that day, the update brought #2469's reorganized tests. Andrew had moved the module-analysis checks from ModRoot, TypeDeps and LabelBench into DefStaticsParity and added cases of the same kind. So the names changed and the count went from 8 to 10, but the causes did not. The same update also brought four new failures where #2469's code met things only #2635 has. Those were fixed in 9e7258b55b (keys, renames, hinted tests, do-blocks), and the ten in the last run are what is left.

The three causes

1. Per-member module analysis meets Modules II (8 tests)

#2469's statics work per item: a top-level definition is analyzed on its own, and after an edit only the items it touches are analyzed again. Inside a module literal, #2469 goes further and works per member. Its DefStaticsParity tests count the units analyzed after an edit. For example, "item + 1 member re-analyzed" expects 2: the member and the item around it.

That per-member path reads modules through dev's module statics (value_exports, collect_type_exports, module_actual_type, and the labeled-tuple lowering). Modules II, which is on the livelits branch only, replaced those with signatures, sealing and abstract members. To make the merge build, 43089b065d (2026-10-01) has DefStatics analyze a module literal whole, as one item, and says so: per-member analysis "is off until it is rebuilt on Modules II". The trial merge on 10-17 (8c968efcc4) restates it.

So the counts come out low: the whole module is one unit, re-analyzed all at once, where #2469 would re-analyze one member and the item around it. The results are right. DefStaticsParity's other tests, which compare per-item results with whole-program results, pass on the merge. What is lost is granularity, which on a large module is a cost in time.

The rebuild has been done, on another branch. Andrew's #2687 ("Standard library in Hazel source", stdlib into modular-editors) has merged Modules II parts 1 and 2 (#2493 and #2494) since 10-16. In 00bc805ca1 (2026-10-18) he rebuilt the module part of per-item statics on Modules II. Members are lowered against the signature, the module's type is its signature type, and a signature the members do not meet still analyzes the item whole. His message measures "edits in mega-mod-1k wrapped or sealed in a module: ~100 → 7ms". #2687's CI has passed since 10-18, with every DefStaticsParity case named below present, their expected counts unchanged, and the corpus test still in: 5,298 tests in Fast checks and 5,709 in Full tests at 5cf71f2d30. #2635's Modules II is older, parts 1 to 3 as merged into the livelits branch on 09-16, so the port may need adapting to part 3 (abstract type members, sealing, path types). Under Cyrus's merge plan (What next, step 4), Andrew's modular editing PRs go into dev before the livelits PRs, so the livelits branch will take this rebuild from dev when it next merges dev, and adapt it to part 3 then if it has not been done already.

Test (last run)What it coversCheckExpectedReceived
DefStaticsParity 1the app's path reuses its slotitem + 1 member re-analyzed21
DefStaticsParity 4a module root's items5 mod items + the exports tail61
DefStaticsParity 33a member retypestep 1 analyzed42
DefStaticsParity 38a module rootstep 1 analyzed21
DefStaticsParity 39a recursive type exportstep 1 analyzed21
DefStaticsParity 40mega-1kstep 1 analyzed21
DefStaticsParity 41mega-mod-1kstep 1 analyzed21
DefStaticsParity 42mega-mod-1k in one modulestep 1 analyzed31

The same checks on the first run (10-01), under their old names:

Test (first run)What it coversCheckExpectedReceived
LabelBench 0in-situ incremental calcincr calc: item + 1 member21
ModRoot 7statics incremental6 items61
ModRoot 9corpus mega-mod-1kitem + 1 member re-analyzed21
ModRoot 10big module (stage D)3 analyzed at depth 231
ModRoot 11recursive type exportitem + 1 member re-analyzed21
TypeDeps 0module member retypemember-retype: analyzed42

2. A livelits table test meets dev's canonical completion (1 test)

Editing.TableDecorations 1 ("typed table: hidden row error draws no arms, flags the chrome") puts a stray [ in a table cell. Its error then lands in a row the table hides, and the test checks that the table's chrome flags it. Since 2026-09-22 (#2374), dev's canonical completion closes a stray bracket where it stands. So the error lands in the cell, where it can be seen, and the chrome is right not to flag it: expected true, received false. The test needs an input whose error is really hidden. 11fbc4480d (2026-10-01) left it failing on purpose and says why.

#2469 does not cause this: it carries the completion only because it is based on a newer dev. The livelits branch #2597 is still on dev as of the morning of 2026-09-22 (2f9f2f6424, just before #2374), 484 commits behind. It will meet the same failure when it next merges dev.

3. One livelits document elaborates differently per item (1 test)

DefStaticsParity's corpus test ("the slide corpus through calc_auto") elaborates every program in the slide corpus twice, per item and as a whole program, and compares the two. One document differs: docs/livelits/expansion-errors/macro-result.hz, at a livelit application and at the let around it. A local run when the branch was made, on 10-01, found the per-item elaboration reading a + 2 where the whole-program one reads a + 1. The 2 is a literal whose source appears in no program, which suggests something carried over between documents in the corpus run. It has been listed among the branch's known failures since cefa5c2c5c (2026-10-10), and its cause has not been found. Of the ten failures, this is the one that may be a real bug rather than a known gap.

Update, 2026-10-19: the cause is found: after the corpus test's edit, a livelit use kept the expansion of the edited definition. See the update.

Which side each test comes from

Where each failing test's file exists. The module-analysis tests are on #2469's side only, and the table test only on the livelits side, so neither parent's CI runs the other side's tests.

CommitModule-analysis testsTableDecorations test
devnono
#2597 (f8ae6f2b9c)noyes
#2469 merged (19fef7c9bb)Test_DefStaticsParity.re, Test_ModRoot.reno
#2635 first run (42f1ab0be7)Test_DefStaticsParity.re, Test_LabelBench.re, Test_ModRoot.re, Test_TypeDeps.reyes
#2635 now (9e7258b55b)Test_DefStaticsParity.re, Test_ModRoot.reyes

Three things that are not the cause

Update, 2026-10-19 at 12:45 MDT: a fix for each cause

What next

  1. Bring Andrew's per-member analysis on Modules II (00bc805ca1, on #2687) into #2635, adapted to Modules II part 3. Until then, skip the 8 cases when Modules II is on, each with a reason that links here, so that a red run means something new. Since the analysis reaches the livelits branch through dev anyway (step 4), a port now is a separate, exploratory draft: it finds out early what part 3 needs.
  2. Give Editing.TableDecorations 1 an input whose error stays hidden under canonical completion, on #2597 too, ahead of its next merge with dev.
  3. Find why macro-result.hz elaborates differently per item: run DefStaticsParity's corpus test on that document alone and read its saved output.
  4. Follow Cyrus's plan for merging into dev, broadly: first the PRs that have been waiting (which ones is not settled yet), then Andrew's modular editing PRs (#2469, with #2687 in it), then the livelits and performance PRs, in an order still to be decided. Agree with Andrew that #2687 goes into #2469 before #2469 goes to dev, so that the per-member analysis on Modules II arrives with it.
  5. Merge the livelits branch into #2635 instead of cherry-picking, to clear the 25 conflicting files before its next CI run.

How this was put together