Repository navigation
test-health-1: quarantine, the carried reds, a strict e2e-smoke, the type ratchet, reload memory - #442
Merged
Conversation
- perf/budgets.json targets reconciled with cloud plans/core/pending/research/quest-phone-perf.md §1: phone calls 300 -> 150 and shadow draws 300 -> 150 (the MID phone row, 100-150 [3P]); desktop texture memory 512 -> 1024 MB (1-2 GB [U]). The comment records the source. - Quest unchanged: 150 calls is inside <200 [M] / 100-150 [3P]; its 300k triangles / 64 MB are stricter than the research's [U] web estimates (QUESTIONS Q1). Low-phone row = follow-up (Q2). - validateBudgets clean; vitest perfBudget + budgetMeterCore 44/0; svelte-check unchanged (298/39). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…blocking tier - tests/e2e/quarantine.json: suite + optional check (substring of its FAIL label) + reason / owner / since / review — perf/budgets.json "allow" for e2e. Seeded with 25 check-level flakes (lock-ux, ui-fixes-15lmno x3, checkpoints x3, scene-load L3 1.4/6.3/4.4, net-handshake, flow-physics-actions x4, select-41 G4, avatar-feet, aquarium-reef x2, knock-physics, pack-behavior, code-workspace, animation-node, dock-strip-drop, toolbar-slots-42; sources in each reason: 50-int, deps-1, mux-pc-host, 53/57/59/65 STATUS) + the 30 whole-suite carried reds moved from battery.json "optional" (phase 2 removes them one by one). Every label was checked against today's suite text. - scripts/ci/quarantine.cjs: validate / classify / warnings / triage. Non-blocking only when EVERY failed check of the run matches an entry for that suite; a crash or timeout never matches a check. - scripts/ci/battery.cjs: `optional` gone; a red-twice suite the quarantine covers = `quarantined` (own tier in the step summary, not a red); report lists past-review / now-green entries. - tests/unit/quarantine.test.js 10/0 (counterfactuals: a new red beside a quarantined row gates; a crash gates; another suite's identical label gates). depsCi 7/0. svelte-check 298/39 (= base). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ds are fixed - ci.yml e2e-smoke: the suites run through `battery.cjs run --only …` — the old loop's `|| echo "SUITE FAILED"` could never fail the step, so "green" meant nothing. Now a red is a red, a failed suite runs once more (green on the retry = flaky, reported) and quarantine.json applies; the logs upload as an artifact. continue-on-error stays until this runs green on the PR. - What it had been hiding on GitHub runners (logs of runs 40088706029, 40013497378, 40003340521): script-guard "the render loop is still running (3 frames in 1800ms)" — the runner measures exactly 3 frames and the check wanted > 3; now 3000 ms and >= 3 (a frozen loop reads 0-1). script-guard "a slow node is paused … (null)" — the guard needs 30 slow frames in a row and the wait was a fixed 30 s at ~2 fps; the wait is now counted in frames from the rate measured just above. diagnostics "the section reads the live peer id through the store" — the id is empty until the public signaling server answers; it waits for it now (an IMPORTED id would stay empty: still red). - local, through the new path (battery.cjs run --only diagnostics,script-guard): 16/0 + 11/0, rc 0. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ever came - First strict e2e-smoke run on this PR (run 40102808352): 8 of 9 suites green, diagnostics fixed; script-guard "a slow node is paused …" still null on the runner although the wait is now 72 s (4 frames / 3000 ms measured). The guard (scriptRuntime.timed) pauses after 30 consecutive calls over 8 ms and the fixture measures 37 ms there, so either the node is not being called or it is and something resets the streak. The check now reports, on failure: how often the slow script ran, the scriptErrors map, flowPaused and the page's visibility — one CI run tells which. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…test fixes + P5 suites Unverified, from read-only root-causing (each to be run, split into one commit per suite, and its quarantine entry removed once green): - flow-physics-nodes: Base made static (95df3a6 made every /create box dynamic) — stale test - collider-live: wait on the body's speed, not 2500 ms (physics slow-motion on software GL) - flow-physics-actions: section 2 driven by a Toggle (held key re-stamped after physics reads it, < 3.3 fps reads 0 — product follow-up in STATUS); 6.5a waits for the box on B instead of crashing - game-loop-v4: A travels to the Lobby first (rooms are content partitions since R22 round 30/34) - game-sky-run: vignette is a level since e16c741 — ON reads 'high' - animation-sync: bounded poll until both peers ended the once-clip (third page's frame lag) - helpers.connect: dial the live id after both signaling links opened (re-rolled ids: behaviours) - new: tests/e2e/net-drop.test.cjs (5 s quiet + hard drop), tests/e2e/reload-memory.test.cjs (probe) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- The reference modules' callbacks get JSDoc types (hello + button: the effect's object / base pose / data / clock, the click handler's object, clamp01's value) — the 10 implicit-any errors in src/modules/hello + src/modules/button, a fixed step of -10 as the brief asks. - check-baseline.json 299/39 -> 288/39 (node scripts/check-ratchet.cjs --update). The full error list diffed against the base: nothing new, these 10 gone. JSDoc only, no behaviour change. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…lay here rows) Only ADDED rows, both intended feat/60 features that did not re-record the fixture: the Settings Storage section (7827405, 60 Q6: Storage / Storage breakdown / Cached downloads / Cache size limit) and the "Play here — start from the editor camera" shortcut row (7669ad7, 60 Q1). LOCK_RECORD=1 run, fixture diff checked to hold only those rows; then green 11/0 (e2e/v1). Quarantine entry dropped. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… .json dropdown The save format picker has been the burger's Save options dialog since 41b (15584b1/27576110/d4176aa4); there is no /json/i button to click. Open #save-options-open and read #save-format's options (Project, Scene — GLTF/JSON are opt-in toggles). Green 13/0 (e2e/v1); quarantine entry dropped. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
95df3a6 makes every /create box dynamic, so the suite's 'nothing has physics yet' premise was false and all 4 checks went red. Delete userData.physics on the three boxes first (editor-modes / fluid-flows / fb-water-sync already do). Green 11/0 (e2e/v1); quarantine entry dropped. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…rab bar 58db817 replaced .tbx-sheet-grab with the shared ui/SheetGrip (40 F1). Find the grabber as .tbx-sheet-resize [data-sheet-grip] and dispatch the pointer gesture on it (sheetDrag listens on the grip zone; the handle button is excluded from its interactive filter, so events bubble to it). Green 136/0 (e2e/v1); quarantine entry dropped. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…w for a library object R22 round 12 (cefc68e): double-clicking a library OBJECT opens #image-preview-window with imagePreviewTarget.kind 'object'; ModelPreviewWindow is the prefab shelf's now. Wait for that window (not a fixed 900 ms) and assert the kind. Green 8/0 (e2e/v1); quarantine entry dropped. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…uarantine entries dropped e77ca3f carried the fixes unverified; e2e/v1 ran each green on the dev server: - flow-physics-nodes 10/0 (stale: Base made static, 95df3a6 made every /create box dynamic) - game-sky-run 57/0 (stale: the vignette is a level since e16c741 — ON reads 'high') - game-loop-v4 19/0 (stale: A travels to the Lobby first; rooms are content partitions since R22 round 30/34) - collider-live 12/0 (timing: waits on the body's speed, not 2500 ms — physics slow-motion on software GL) - animation-sync 24/0 (timing: bounded poll until both peers ended the once-clip — the third page's frame lag) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…iew tick before the kill Two causes. (1) e77ca3f's helpers.connect dials the live id once both signaling links opened (a re-rolled id on 'unavailable-id' left the suite dialling a dead one). (2) The fired glow is 'changed since this view's FIRST live tick'; on B, the authority, the died handler fires the moment we kill, so a kill that beat B's first 100 ms tick landed in its baseline and never glowed (0 of 10 samples). Wait for B's state nodes to read live values first — the wait A already makes. Green 46/0 (e2e/v2); quarantine entry dropped. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ks quarantined by name The :431 crash (__stores undefined after a load) did not reproduce: e2e/v2 ran the whole suite, 61 pass / 4 fail. The whole-suite entry goes; the four reds get check entries with the root cause: - a foam body floats high / ...is never swamped / ...upright: rapier keeps real time only down to 7.5 fps (at most 8 substeps of 1/60 s per frame), and software GL renders ~4, so the hull lags waves that follow the session clock. Green needs a GPU slot; nothing in the test can supply the frame rate. - underwater: aligned: flips run to run (green on the base) — read 1 s after a water-quality switch while the shaders recompile. NOT fixed: kept visible in the quarantine tier with an owner and a 2026-11-07 review. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…asset send 4.5 spied peers.send for the LUT's assetfile, but assetShare sends per OPEN CONNECTION since 9c81d06 (chunked transfers + the transfer ledger), and nobody has joined yet in section 4. Give the spy an open connection to send on. Green 43/0 (e2e/v3b). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…-free region 2.2 / 4.3 read a constant 20780 px 'off the fill colour' on the full frame: play mode composites the glass bar (PlayBanner, 930ecc4) and the reticle over the canvas — helpers.grabFrame's own rule is that a colour metric looks at a chrome-free region. Clip left of centre, clear of the bar, HUD and reticle (2.1's whole-frame delta unchanged). Green 15/0 (e2e/v3b). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…r follows the selection Two stale assumptions: pulled bytes go to the shared row's folder or the root since 186248b (R22 round 9 removed the stray 'Shared' folder); and since flow v2 H1 (b2350b7) the node editor shows the SELECTED object's graph, so after /create box it opened the box's empty flow and '▶ Play' never appeared — deselect first, and let the locator wait instead of 900 ms. Green 7/0 (e2e/v3b); quarantine entry dropped. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Dark mode does not remap .bg-gray-800, so the probe reads tailwind's own value — oklch(0.278 0.033 256.848) since f3c8ef6 (tailwind 3.4 -> 4.3), not tailwind 3's rgb(31, 41, 55). Green 12/0 (e2e/v3b); quarantine entry dropped. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…wherever it sits The check pinned it as the SIXTH member; the timeline joined the family after it (896cdb9). Membership is the claim. Green 35/0 (e2e/v3b). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…n sky The check held a copy of the studio background (#3b4048) and went stale when c2005ce retuned the palette (#363b43; b7d57c7 had already logged it red on pristine 1.25.0). Read ENVIRONMENT_PRESETS[preset].background instead of copying it. Green 14/0 (e2e/v3b). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ter row 26537bb moved node search INTO the pane's context menu (its .ctx-filter row, matches as .ctx-match) and deleted the pop-up #node-search-box with its right-drag. Assert the filter row opens and lists matches; the right-drag check goes with the feature it tested. Green 10/0 (e2e/v3b); quarantine entry dropped. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…as not seen, even when the pulse fell between frames flow-physics-actions 6.5: after a peer joined, a trigger no longer hopped the box on A (key press or applyNodeTrigger alike — the suite had recorded it as unexplained, 3 runs of 3). Measured with the new 6.5 diagnostics: the stamp was newer than the history epoch, the sim ran, A was the initiator — the impulse simply never saw a rising edge. Physics actions fire on the rising VALUE of the event's pulse, and a pulse is high for 0.3 s; with a second page rendering, A dropped below ~3.3 fps and the whole pulse fell between two ticks. PRODUCT FIX (flowRuntime updatePhysicsActions): remember the trigger stamp each action last saw; a NEW stamp is a rising edge even when the value already fell. First sight is not (a pulse from before the node, which staleTrigger refuses anyway), a Toggle with no stamp keeps the value edge, and one pulse still fires once. Affects any device below ~3.3 fps (slow phones, a loaded headset), not just the test box. Test: 6.5 stamps on the session clock flowRuntime itself stamps with (a correctness tidy-up — NOT the cause; the clocks agreed to 0.15 s), prints the clocks if it goes red again, and 6.7 allows the 'camera' presence stream. Green 37/0 (e2e/v3a); the 6.5 quarantine entry dropped, 2.1/4.3/8.5 kept until a second green. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…n by rowFit's own floor The phone check said a description beside its control must keep half the row (1b6bc72). 437423c (41b H12/H13) then made rows decide by real fit: a compact control stays on the label's row while the text column keeps rowFit TEXT_MIN = 150 px — which settings-row-fit asserts, and which is under half of a 390 px phone row. The two suites contradicted each other; use the product's floor (< 149 px is squeezed). Green 98/0 (e2e/v3b); quarantine entry dropped. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
95df3a6 gives every /create primitive userData.physics {mode:'dynamic'}, and a body is only kinematic when it is not dynamic — so the spinning slab fell to the ground (y 0.198, 'dynamic') and all four checks went red from that one cause. Delete the slab's physics (and say so to B), so the spin effect is what makes it the kinematic platform. Green 14/0 (e2e/v3a); quarantine entry dropped. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…own frames 2.12 read exactly 0.000 m — on this box AND on the GPU PC (pcbat), so not just a slow renderer: B's prediction moves the ball once per RENDERED frame and is withdrawn after 400 ms of wall clock (PREDICT_MAX_MS), and the check read it after a 60 ms timer plus two round trips, i.e. between frames or after the withdrawal. Take the furthest the ball got over B's next six frames, inside the same evaluate. 2.13 now also requires A's ball to have really moved, so 'both peers still at x≈0' cannot pass as convergence before any authority move ended the prediction (2.14). Green 77/0 (e2e/v3a); the 2.12 quarantine entry dropped. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…efore its counterfactual
S7's counterfactual ('with nothing unsaved, leaving the page does not ask') reopened the file right after 'Don't save' — but since 50 Y1 (6e6c95c, shared text in the Code tab) 'Don't save' discards THIS view and deliberately leaves the room's shared buffer alone, so the reopen rejoined the edits and the page rightly asked. Revert the shared copy (reloadCodeTab, for everyone) and wait until nothing is unsaved. Green 98/0 (e2e/v3b).
For the owner (not changed): a user who pressed 'Don't save' and reopens the file sees the discarded edits again while a peer is in the room. That is the Y1 design as written; if it reads as a bug, the fix is in discardAllCodeTabs, not here.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… worst-of-all dot The status-line dot is the WORST tier of every budget (Controls worstTier), and on software GL (p95 333 ms, ~3 fps) frame time alone turns it red whatever the scene holds — so '24 objects reads green' could never pass there, and the 'goes RED' wait returned at once, reading the tooltip before the 3200-object sample landed. Judge budgetRows' objects row; check the dot only when the frame rows leave it to the objects; wait for the tooltip to name the objects. Green 35/0 (e2e/v3b); quarantine entry dropped. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…, and wait for the failure to be reported 1.3 averaged the nose-vs-travel cosine over every 250 ms interval, and an interval with no rendered frame in it (software GL) has no direction and scored 0 — two of eleven gave exactly the 0.82 measured (pcbat on a GPU read 0.99). Skip non-moving intervals, as 1.7 already does, and require six moving ones. 3.2 read the offline levels after a fixed 3 s, but since 974e8be (60 Q6 local asset cache) a fresh page's first pack fetch waits for the cache to open first: wait for a failed level to be reported (bounded, statuses printed). Green 30/0 (e2e/v3a). The two 2.x check entries stay (pack-level timing, not touched here). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ss reloads) + the thumbnail renderer always disposed Plans review #24 / roadmap-42 Follow-ups: 'editor-ui-33 dies on its 5th reload; the heap grows ~29 MB per reload'. Measured on the current union, it does not: - tests/e2e/reload-memory.test.cjs (new in e77ca3f, made honest here): per reload, after a forced GC, the JS heap (Runtime.getHeapUsage), live documents (Memory.getDOMCounters), renderer.info, and the RSS of this browser's renderer + GPU processes (SystemInfo.getProcessInfo + /proc). The first version read Performance.getMetrics, which on a reloaded target kept answering the first document's numbers (seven identical rows), and browser.process() — Playwright's Browser has none, so it never measured RSS. A premise now proves every sample is a fresh document (timeOrigin). - e2e/v3local (local slot, 6 reloads): heap 100.8 -> 100.9 MB (0.0 MB/reload), documents 3 throughout, GPU RSS 292 -> 299 MB (+1.0 MB/reload), renderer 496 -> 534 MB (levels off). editor-ui-33 — the suite that used to die — green 36/0 through its reloads (e2e/v3a). So: no leak found ACROSS reloads; the 29 MB was most likely heap read without a forced GC on the 1.33 union. Thresholds: heap <= 5 MB/reload, GPU RSS <= 25 MB/reload. - The one real leak on the way (WITHIN a page): sessions.renderSceneThumbnail returned early on an empty bounding box, or threw, WITHOUT dispose()/forceContextLoss() — a WebGL context per call held until GC, and Chromium caps live contexts at 16. Released in a finally on every exit now. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
continue-on-error removed. b4b46ab made the runner step able to fail at all (it used to '|| echo' every red away) and retries a failed suite once (green on the retry = flaky, reported); a known flake goes into tests/e2e/quarantine.json with an owner and a review date. Green on GitHub for bc453ae and e77ca3f (script-guard first try both times; the one red was b4b46ab, which bc453ae's diagnostics followed). The header now says why it gates instead of why it did not. For the owner / orchestrator: add 'e2e-smoke' to the 'main: checks' ruleset once this reaches main (protection/apply.sh carries the line). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… avatar-feet 1.7 says what it saw localFeet() dropped the walker's feet after a fixed 250 ms. The writer runs once per frame and the camera broadcast reads the previous frame's write, so below ~4 fps (or on any >250 ms hitch) every reading was stale, the camera message went out without feet, and peers hung the body under the head (3a1ec3e's own fallback). Stale now after max(250 ms, 2 frames) — Scene passes its frame time. This is from code reading (the root-cause pass): no before/after run isolates it. avatar-feet 1.7 prints the origin y per stride. e2e/v4b: 12.2 3.0 0.7 0.7 0.2 0.2 0.0 0.0 cm — no sinking and no stride without feet, but a 12 cm rise at the start of the walk that settles over ~400 ms on software GL (green on the GPU PC). Source not found: quarantined by name (owner, 2026-11-07 review) rather than loosened. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…nd G14 names what the finger hit G4 (flick): fingerCarry read 'carrying' after a fixed 250 ms and the flick aimed at the crate after a fixed 1.5 s settle — at ~4 fps the light crate was still sliding from the far carry, so the finger landed beside it (taken: null, 0.00 m/s). Wait for the carry to exist and for the crate to come to rest. Green (3.18 m/s throw). G14 (unfolded): taps wait until the PAGE is 450 ms past the last pointerup (a tap inside 400 ms of page time is a double-tap, which does not deselect), and the check prints the gizmo state at the tap. That showed the real cause — e2e/v4b: [pointerup, axis XYZ, dragging true]: the finger lands on the seated gizmo's centre handle and TransformControls starts a drag, so whether the tap lets go depends on listener order (green in v4b, red in base/v3b). The product fix is the next commit. 56/0 (e2e/v4b). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…l; net-stress runs again 44 M14 squeezes the floating connect pill to its status dot on a narrow window, and the dial input shows only after a tap on the dot — helpers.connect never pressed it, so every two-peer suite on a narrow viewport (net-stress's 800 px) died at 'could not fill the peer id' before checking anything (red at base the same way). connect presses #connect-squeeze-dot first when that is what is there. net-stress (e2e/v4a): the four-peer mesh fills (12/12 pairs, host-only dials), every host message lands (60/60 x3), fan-out bounded, every pair delivered under load, no freeze. Section 5's three rate checks need a GPU (four software-GL pages orbit at 1 fps; the suite says so itself) — quarantined by name, the whole-suite entry dropped. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…chrome in its goldens; two scenes wait on an owner call Measured, not guessed (e2e/migration/*-now.png beside tests/fixtures/golden-1.22): the 1.22 goldens carry a strip of UI chrome along their top edge (the connect pill sat inside CLIP on that build) — half of every scene's changed pixels. frameDelta takes an optional skipTop (default 0, every other caller unchanged) and the suite skips the golden's chrome rows. The quality governor is pinned too (autoQuality false): a pixel comparison cannot have dpr/shadows/AO changing under it. e2e/v4mig: aquarium 3.59% -> 1.22% (passes; its quarantine entry dropped). pool-party 5.26% and island-ocean 8.53% stay over the 3% line: by eye the scenes are the same — the change is a global tone shift (mean sum-of-channels delta ~4-9, identical run to run) plus the band along the pool rim, i.e. render changes since bd14343. Kept in the quarantine tier with that evidence and an OWNER DECISION: re-baseline the goldens on today's build (dropping their 'rendered by 1.22' provenance) or move to a perceptual metric. Not a threshold raise. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…menu again; a finger tap on the seated gizmo lets go 1) RIGHT-CLICK (play-reentry, carried since 1.41 — its recorded explanation 'after a denied XR session' was wrong): OrbitControls listens on threlte's WRAPPER and captures the pointer on every press, the right button included, so where contextmenu fires on mousedown (Linux; Chromium headless) it is dispatched to the capture element — Scene listened on the canvas and never heard it. A one-off probe on a FRESH page proved it general: 0 menu rows, contextmenu target the wrapper DIV. Scene now hears contextmenu on the wrapper (dom) and acts only for the canvas or the wrapper itself (an overlay inside keeps its own menu). Same probe after: 8 rows (e2e/v5probe); play-reentry's two right-click checks green (e2e/v5a). No passing suite drove a REAL canvas right-click before (context-menu-redesign sets the store directly), which is how this lived. 2) GIZMO TAP (select-41 G14): play-reentry-style diagnostics showed the finger landing on the seated gizmo's centre handle — at pointerup TransformControls reports axis XYZ, dragging true — and Scene's still-tap path bailed on 'dragging', so whether a tap let go of the object depended on which pointerup listener ran first. For a finger, past the still-tap test (<= 5 px, <= 400 ms), 'dragging' set by this same press no longer disqualifies the gizmo tap. By the mechanism shown in e2e/v4b; no run yet shows the race losing and then passing. The unfolded block's other flake (a tap voided by a long frame) is quarantined by name. play-reentry also: the 4c premise waits for the retry's first attempt (bounded 3 s) instead of a fixed 400 ms; the right-click checks print what the click reached. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ame, on a level camera Fly moves a fixed step per FRAME (PointerLockControls translates by speed each tick), and the suite compared distances over a wall-clock 1200 ms: on software GL the same window was 20 frames once and 10 the next (2.000 vs 1.000 units — the base's 'PARITY 50% apart'). travel() now counts, in-page, the frames in which the rig moved and reports the MEDIAN step (one settling frame at ~3 fps moved a mean 10%). Section 7 re-levels the camera as section 1 does: a rig left pitched by the sections between measured 0.09/frame (0.1 x cos 26 deg) for the same speed. Move Input's release waits for the zero instead of a fixed 300 ms. Green 55/0 (e2e/v5a); quarantine entry dropped. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…der copy; the accepted-load check is quarantined UNRESOLVED e3edaee (a11y live regions) repeats every toast's text in #a11y-live-polite, so getByText(/wants to load session/) matched two elements and the suite crashed in strict mode at :80 — which hid everything after it. The proposal/decline reads and the Accept/Decline presses now target the proposal's own .tp-toast. That exposed the last check, red in every run since and NOT explained: v5b — the proposer holds a live, uncancelled load job with both links open and nothing cleared (stuck before applySessionNow's replicated clear); v3b — A cleared and added nothing, B applied nothing. A read-only root-cause pass refuted the room-gate, job-liveness and modal hypotheses with file:line evidence. The check now prints each side's link, load job and recent diagnostics on a red; quarantined by name with that evidence (the rest of the suite gates). Possibly a product bug in the session-proposal load; flagged for the owner. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ins the quality governor 9.12 read the touch page's post stack after a fixed 1400 ms. Two causes, both measured: the stack is empty until the composer has warmed (postWarm, >10 rendered frames — section 3.2 already waits for it), and even warm the plan was EMPTY (postWarm true, postOk true, plan 0) because the quality governor drops AO on slow frames (Outline filters entries by qualityOverrides.aoOff) and software GL is slow on every page — the check was measuring the governor, not the touch rule. Wait (bounded) for postWarm + 'ao', pin autoQuality off on that page, and print the composer's state on a red. Green 93/0 (e2e/v5a); quarantine entry dropped. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…bject arrives after it shader-sync 'and compiles it locally too' (red since the base): the third peer held the graph AND the cube and never compiled. The new diagnostics settled it — no compile errors, and a reconcile run by hand compiled it at once: the graph reply (small) lands before the GLTF that carries the object, the compile finds no target, and the late-joiner reconcile waits on an objectsGroup poke that the object's arrival does not always make. PRODUCT FIX (shaderGraph compileAndApply): an object-keyed graph with no target yet retries its own compile on a short backoff (0.25 s doubling to 4 s, ~20 s in all); the reconcile still covers anything later; the scene default and edits are unaffected. The test adds the premise that C has the cube (so a red says which half never arrived) and prints the compile errors + a manual reconcile on a red. Green 21/0 (e2e/v6a); quarantine entry dropped. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ts quarantine entry says so Carried as 'red since 1.41'. It is not broken: the in-app exporter reads build/export-manifest.json, which only 'npm run build' (postbuild) writes, so against the dev-server battery it can only fail with ExportUnavailable, by design (battery.json already skips it on CI for this). Run against a production build served by scripts/serve-build.cjs it is green 9/9 (e2e/tlx: the export zip, the sequence in scene.tpscene, the exported game autoplaying through its camera shot, no page errors). The entry keeps it out of the dev-server battery's blocking tier with the real reason and the way to run it. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…window heals instead of tearing down
net-reconnect was red at the base ('the conn to B is re-opened by the backoff', 'B's new object reaches A after the heal'). Each fix below was found by a measured timeline (net-drop prints each side's window per 500 ms on a red), not by reading:
1. A signaling rebuild no longer cuts the peer links. recreatePeer destroy()ed the old Peer, and PeerJS destroy() closes every DataConnection it owns — so a signaling reconnect that stalled (watchOpen, 10 s after a wifi drop) killed every healthy conn with it (net-drop QUIET timeline: the conn died ~15 s in). A Peer that still carries open links is disconnect()ed (server socket only — 'does not close any active connections') and retired; links still negotiating are closed as destroy() did (they needed the old socket).
2. Signaling back = redial now: the window's dials while the link was down never left (peer.connect is undefined then), and its next tick can be the verdict-only one — so on 'open' every peer in the window is redialled at once, replacing a never-opened dial made while the link was down.
3. The final verdict waits out a dial still negotiating, either direction (the higher id heals through an INBOUND dial, tracked in inboundDials), up to VERDICT_GRACE_MS = 20 s: a post-drop redial measured ~12 s to open on a loaded box and the 10 s DIAL_GRACE tore it down a second before it opened.
4. A healed conn re-syncs as one session, not two worlds: its handshake no longer holds for the connect decision (a first-contact question), and its full-state request carries 'arriving' — without both, the far side opened a share-or-stash ask whose gate DROPPED everything we sent (diagnostics: gateHolds true, open both ways, edits lost).
Evidence: net-reconnect green 13/0 (e2e/v9a — red at base, and red in v3-v8 at each stage above); net-drop HARD healed with edits crossing both ways (e2e/v9b); net-handshake green (v7a). The test: B's side must be open before B's edit, heal waits are bounded by the product's own window, the mesh-fill premise by measured negotiation time, and a red prints each side's gate/decision state.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ar a two-peer session down (and a 20 s one does) New suite (from e77ca3f, made honest here): QUIET (signaling dies, data held, ICE disconnected) and HARD (the peer connection closed outright, so the window must redial) 5 s drops; per-500 ms timelines of each side's window on a red; the signaling-down premise read at the cut; the shim keeps WebSockets down while the drop holds and lifts its hold before going online. Green 21/0 (e2e/v10). Counterfactual NETDROP_MS=20000: HARD red — teardown at ~20 s + the toast (e2e/v10cf); QUIET stays green by design (a quiet drop never breaks the channel). lockControl: the 60 s lock sweep released a lock whenever its holder's conn was not open — no reconnect-window guard, unlike checkLocks (B5) — so a sweep landing inside a drop dropped a live peer's locks (v9b: 'A dropped B's lock' mid-drop). Same guard now. Consistent with v9b -> v10; not isolated by its own run. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…t an estimate of frames e2e-smoke's first run as a gate went red on script-guard, twice (run + retry) on the GitHub runner, and bc453ae's diagnostics said exactly why: {runs: 29, paused: false} both times. The guard pauses a node on its 30th consecutive slow run (SLOW_FRAMES); the test's wait was a TIME estimate from the measured frame rate, and this node slows the very frames it is measured by, so the timeout ended one run short. Wait for the badge, or for the node to have run 40 times (a real red), bounded at 180 s. Green locally 11/0 (e2e/sg1). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The two new suites join the battery (seconds = 2x the desk time until a runner measures them: net-drop 94-175 s desk, reload-memory 73-94 s desk). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… select-41 G14 — reverted, check quarantined 7451aad also let a finger's still tap count as a gizmo tap while TransformControls reported 'dragging'. The after battery shows it changed nothing: G14 (unfolded) still red with the same state at the tap (axis XYZ, dragging true). That state is read in the CAPTURE phase; Scene's pointerup listener is on window and runs after TransformControls' own pointerup, so the condition was keyed on something the handler never sees. An unproven change with a commit claiming a fix is worse than none: Scene.svelte's gizmo condition is back as it was (7451aad's right-click fix stays — it is proven by the probe, 0 -> 8 menu rows). The check is quarantined by name with this evidence: a product race not understood, for the owner. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…he third page The after battery read the joiner's door after a fixed 1.5 s and found it at x=0.03 (not yet arrived) — then measured a 'hinge drift' against that. Wait (bounded) for the door at its real world place on C first; the check still reports where it was if it never comes. Green 25/0 (e2e/v11a). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Collaborator
Author
|
In main via 60-int: released in v1.44.0 (#476). |
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.
Draft. test-health-1, the standing test-health lane (review 2026-10-24). In progress; the body is rewritten from the lane STATUS when it is done.
Landed so far:
🤖 Generated with Claude Code