Repository navigation
Optimize UI performance - #16
Merged
Merged
Conversation
aakashH242
marked this pull request as ready for review
November 12, 2026 08:17
20 tasks
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.
This PR collects UI optimizations for XFlog; further issues can be added before merging.
Closes #15.
Closes #17.
Current changes
render()orupdate()invalidates the cache; clearing the scene resets it. Selection, animation, scrubbing, zoom, resize and audience-group configuration reuse it.Files:
src/xflog/assets/constellation.js,tests/constellation_check.mjs, andtests/constellation_selection_check.mjs.Verification
node tests/constellation_selection_check.mjs src/xflog/assets— passed. The revised test fails against the previous PR head specifically because three grouping changes perform three extra scans.uv run --no-sync pytest -q— 614 passed, including the registered-lens identity checks.uv run --no-sync ruff check src tests .github/scripts,uv run --no-sync ruff format --check src tests .github/scripts, andbash -n install.sh— passed.uv build --out-dir /tmp/xflog-pr16-review-dist— passed; the wheel's constellation asset matches source byte-for-byte.UV_PROJECT_ENVIRONMENT=/tmp/xflog-pr16-headless uv sync --locked --extra dev --offline, thenUV_PROJECT_ENVIRONMENT=/tmp/xflog-pr16-headless uv run --no-sync python -c "import importlib.util; assert importlib.util.find_spec('gradio') is None"andUV_PROJECT_ENVIRONMENT=/tmp/xflog-pr16-headless uv run --no-sync pytest -q tests/test_runtime.py tests/test_identity.py tests/test_cli.py— Gradio absent; 80 passed.A seeded property check exercised 120 unique-ID datasets across all six registered lenses plus ungrouped at three zoom levels: 2,520 layouts preserved their event-ID and actor-ID sets.
Scan-count comparison
For each of 100, 500, 1,000 and 5,000 synthetic events, the same simulated-DOM scene ran an initial render, 24 animation frames, one grouping change and two zoom redraws:
Grouping and redraws no longer rescan actors; explicit data updates still do. These are deterministic scan counts using fixture IDs in a simulated DOM, not browser FPS measurements.
Review and limitations
Gauntlet v1.1.0: PASS_WITHIN_SCOPE. Three distinct solo re-attacks covered the data/grouping contract, regression and instrumentation oracle, and seeded layout plus performance cases. The original issue's bounded comparison is preserved, and the new comparison and review ledger are recorded locally under
evidence/pr16-review-fixes/(ignored by Git). No independent reviewer is claimed. No live X, physical-device, or browser-FPS testing was performed for this revision. Malformed histories with conflicting duplicate event IDs and invalid unregistered grouping configurations are outside the supported application contract.Issue #17: Constellation DOM lookup reuse
uv run --no-sync pytest -q(614 passed);uv run --no-sync pytest -q tests/test_assets.py -k constellation(2 passed); Ruff lint/format,bash -n install.sh,git diff --check,uv build --out-dir /tmp/xflog-issue17-final-dist, wheel asset byte comparison, and headless core tests (80 passed; Gradio absent) all passed.querySelectorcalls; each revised sample made zero. Group selection, overview, zoom and a 390px viewport were also exercised without page errors or external requests. Instrumented selector timings lack the resolution to support an FPS or latency claim.evidence/issue17-dom-cache/(ignored by Git). Browser interaction was automated; no live X or physical device was tested.Cross-boundary lifecycle and actor-parent follow-up
The parent owns the history container, while the constellation owns the scene references and animation work inside it. Previously, the parent could replace that container's contents for loading or error UI without clearing the active constellation, leaving a pending frame writing to detached elements. The parent now calls
scene.clear()before both replacements; empty and Journal paths already did so. Clear/destroy cancel pending frames, release scene references and pointer capture, and reset drag state. Connectivity checks prevent animation or selection on a detached app/history element; a fresh render acquires new nodes.Actor buttons now retain their
.constellation-personparent for each rendered scene. Rendering resolves one parent per actor; explicit and animation-driven selection reuse it. Redraws replace the collection, and cleanup releases it.Regression coverage includes real offline-app Chromium tests with controlled requests and animation frames, plus Node tests for parent traversal counts, detached references, pointer cleanup, unmount, repeated clear and accessibility. Both checked-in browser tests independently failed on the original
c024af0snapshot and passed on the fix, including the distinct error-fallback race. Browser tests explicitly skip if Chromium or the optional UI is unavailable.Structural measurements: with three actors, the old implementation performed three additional
.closest()lookups per selection; the revised implementation performs zero after the three construction lookups. In controlled real-browser scenarios, original loading, error-race and unmount paths each left one paint pending and modified the detached sky; the fix left zero pending and preserved the old node. These measurements do not imply an FPS improvement.Validation on final snapshot:
node tests/constellation_selection_check.mjs src/xflog/assets— passed.node tests/constellation_check.mjs src/xflog/assetswithout its required catalog argument — failed on the existing test interface (JSON.parse(undefined)); passing the catalog fromaudience_groups.catalog(...), astests/test_assets.pydoes, passed.uv run --no-sync pytest -q— 616 passed, including two actual Chromium app integration tests.uv run --no-sync ruff check src tests .github/scripts;uv run --no-sync ruff format --check src tests .github/scripts;bash -n install.sh;git diff --check— passed.uv build --out-dir /tmp/xflog-pr16-final-dist— passed; wheelapp.jsandconstellation.jsmatch source bytes.UV_PROJECT_ENVIRONMENT=/tmp/xflog-pr16-headless uv run --no-sync pytest -q tests/test_runtime.py tests/test_identity.py tests/test_cli.py— 80 passed. Missing-Chromium regression test run — two expected skips.Gauntlet 1.2.0: PASS_WITHIN_SCOPE. Retrieved the exact head
e563c3d3ddc8bb97b52c8d8dad2ab737dba623b4of the specified merged skill PR (its branch was deleted). Independent ownership and test-oracle reviews plus a real-browser differential re-attack covered the final snapshot. A reviewer found and helped correct a vacuous drag test and a destroy-time pointer-capture gap. Local ignored evidence is inevidence/pr16-lifecycle-review/. No live X, production data, physical-pointer device or uninstrumented FPS test was used.Resolved in the selection follow-up below: the former per-button
geometry.people.find(...)selection path has been replaced by per-render first-match references.GitHub CI after commit
e283194: Python 3.12, 3.13, 3.14 and headless package jobs passed. The Python jobs skipped the two browser integration tests because Chromium is not installed on the runners; those tests passed locally in Chromium. Headless CI ran 80 core tests.Revalidation at
e283194: Two independent reviewers rechecked the parent/component ownership and test oracles. The originalc024af0fails the actor-parent traversal test (243 lookups versus 240 expected); the current head passes. An offline Chromium differential reproduced the old detached-node animation during loading and a distinct error race, and confirmed that the current head cancels it and recovers on retry. The full local suite again passed (616 tests), with 80 headless core tests and the prior CI run passing on this same commit.External host unmount limit: If a host removes the entire app root outside XFlog's history-replacement paths, connectivity checks stop painting and selection immediately; the app's periodic disconnect check calls
destroy()and releases cached references, normally within 10 seconds. Parent-owned history replacement itself clears references before replacing the contents.Issue #18: index group positions during layout
Closes #18.
The point-placement loop repeatedly searched occupied groups and their members for each event entry. It now builds one per-layout
Mapkeyed by entry object from the final occupied groups, recording each entry's group, member index and original group index. Grouped reverse flattening, coordinates, colors, duplicate-ID behavior and distinct actions by one actor are preserved. This removes the targeted quadratic group/member lookup; it does not make the entire layout linear.The existing layout test now checks the original linear placement oracle and recorded baseline geometry across empty, singleton, dense, sparse, unknown and dynamic groups, multiple actions per actor, duplicate IDs, two widths and six zooms. A positive-controlled operation counter detects the original searches: on the 24-entry fixture the previous implementation performs 24 group finds, 60 membership checks and 48 index searches; the new point-placement path performs zero. An independent 6,300-case seeded comparison matched the complete baseline/current layout outputs.
Paired measurements: Node 24.18.0, Linux x86_64, i7-12700F, 1280×900, zoom 0.8; 3 warmups and 9 alternating samples per fixture. Full-layout medians in milliseconds (unisolated machine; not FPS):
The full 35-case local benchmark also records p95, occupied-group distributions and separately instrumented stage times. On 10,000 ungrouped entries, the index build median was 0.489 ms; instrumented point placement was 24.065 ms before and 1.207 ms after. The original point path performed 10,000
includesand 20,000indexOfcalls; the new path performed none and used 10,000 Map sets/gets. No reliable heap or browser FPS measurement was taken, and small inputs show mixed results.Verification:
uv run --no-sync pytest -q— 616 passed; both constellation Node checks passed when the existing layout check was supplied its audience-group catalog. Ruff lint/format,bash -n install.sh,git diff --check,uv build --out-dir /tmp/xflog-issue18-dist, wheel/source asset comparison and 80 isolated no-Gradio core tests passed. The new regression fails against originale283194specifically on the expected linear-search counts. Offline Chromium 156.0.8078.4 at desktop and mobile sizes compared the same synthetic baseline/current UI, including grouping, zoom and selection; screenshots were visually inspected and no page errors or external requests occurred. Mobile pointer selection, real X, physical devices, screen readers and other browsers were not tested.Gauntlet 1.2.0: PASS_WITHIN_SCOPE. Independent contract/oracle and browser re-attacks plus a seeded full-layout differential found no remaining scoped defect; geometry and lookup counts are measured separately from latency. The rounded golden geometry digest was checked with Node 22 and 24 and several locales, but not on other CPU architectures or ICU versions. Review and benchmark evidence is retained locally in
evidence/issue18-layout-index/(ignored by Git). The separateselect()event lookup is addressed in the selection follow-up below.GitHub CI on
98d92f2: Python 3.12, 3.13, 3.14 and Headless package passed (run 43192106197). Each Python job reported 614 passed and two browser tests skipped because Chromium is not installed on the runners; both browser tests passed locally.Selection event-to-person lookup
The previously deferred per-button
geometry.people.find(...)lookup inselect()is now resolved. Each private scene render builds a temporary Map keyed by the uncoerced event ID, keeping the first geometry match; each actor-button entry holds the matching person. The Map itself is not retained, and clear/destroy release the scene-owned button/person references. Zoom, grouping, resize, history render and update reconstruct them. Selected buttons still use the current event; unselected buttons use the first matching representative. Layout geometry is unchanged; the actor-click follow-up below reuses these references.The selection test exercises a positive-controlled search counter, manual and animation-driven selection, same-actor actions, update/removal/rerender, empty/clear/destroy/recreation, and conflicting duplicate IDs in separate groups. The previous
98d92f2fails the targeted count assertion. Two deliberate stale-cache mutants fail separate update and rerender assertions; the old implementation with count limits relaxed passes the behavior oracle.Paired selection measurements — actual
createConstellationandselect()with a simulated DOM, Node 24.18.0 on Linux x86_64 / i7-12700F, 1280×900; three warmups, nine alternating samples. Medians in milliseconds:At 10,000 unique event IDs the baseline targeted path made 10,000 finds and 50,005,000 predicate calls per selection. The new path made 10,000 direct person-reference reads per selection; construction made 10,000 Map sets and gets. Map+binding also includes simulated
querySelectorAll,closestand object creation. These are mock-DOM measurements on an unisolated machine, not browser FPS or heap results; p95 from nine samples is noisy. Existing one-off geometry finds andcurrent()behavior for pathological duplicate IDs remain.Validation:
node tests/constellation_selection_check.mjs src/xflog/assets; catalog-suppliedconstellation_check.mjs;uv run --no-sync pytest -q(616 passed); Ruff check/format;bash -n install.sh;git diff --check;uv build --out-dir /tmp/xflog-selection-index-distand wheel/source asset comparison; and 80 isolated no-Gradio core tests passed. Offline Chromium 156 baseline/current comparisons used nine dummy events on desktop and mobile, exercising grouping, selection, keyboard and zoom; desktop pointer was tested, mobile pointer was not. No provider requests, page errors, physical-device tests or browser FPS measurements.Gauntlet 1.2.0: PASS_WITHIN_SCOPE. Independent review found a stale-cache test-oracle gap, which was fixed and checked with targeted mutants; a separate final lifecycle re-attack found no additional in-scope issue. Browser differential and structural/benchmark re-attacks passed. Local ignored evidence is under
evidence/selection-person-index/. External whole-app unmount continues to use the pre-existing connectivity guard and periodic destroy; references may remain until that poll.GitHub CI on
aa73033: Python 3.12, 3.13, 3.14 and Headless package passed (run 43194560057). Each Python job reported 614 passed and two browser tests skipped because Chromium is not installed on the runners; both browser tests passed locally.Cached actor clicks and stale-scene guard
Actor-button clicks now reuse the per-render first-match person reference instead of searching
geometry.peopleagain. Each handler captures a scalar scene version and checks that its geometry, root, history element, button containment and event ID are still current before acting. A button retained across update, redraw, clear or destroy cannot open or navigate the replacement scene, even if its event ID is reused or the old node is reattached. First-match behavior for duplicate IDs remains unchanged.The Node regression now asserts exactly three geometry finds for manual selection and seven for the exercised animation selection, both at 24 and 500 actor buttons; a selected actor click uses only its one existing position search. It covers live selected/unselected clicks, same-actor actions, duplicate IDs, removed and reused IDs, clear/destroy/recreation, detached/reattached nodes, disconnected roots, ID mutation and preserving an in-progress navigation. An offline Chromium test dispatches an actual click on a detached button after a same-ID redraw, verifies no dialog opens, then confirms the live button opens normally. The original
aa73033fails both the click search count and the browser regression.Verification: focused Node selection and catalog-supplied layout tests passed;
uv run --no-sync pytest -q— 617 passed, including three local Chromium lifecycle tests. Ruff lint/format,bash -n install.sh,git diff --check,uv build --out-dir /tmp/xflog-click-guard-dist, wheel/source asset comparison, and 80 isolated no-Gradio core tests passed. The earlier selection benchmark was not rerun becauseselect()is unchanged; this removes one extra linear search on actor click and is not an FPS claim.Gauntlet 1.2.0: PASS_WITHIN_SCOPE. Independent lifecycle and test-oracle reviews reproduced the baseline stale actions, then checked six targeted guard/lookup mutants and a navigation-cancellation mutant against the final tests. A separate baseline-vs-current Chromium run confirmed the real DOM dispatch failure and fix. Local ignored evidence:
evidence/selection-click-guard/. No live X, physical device, non-Chromium browser, screen-reader or FPS testing.GitHub CI on
bd2808f: Python 3.12, 3.13, 3.14 and Headless package passed (run 43197817838). Each Python job reported 614 passed and three browser tests skipped because Chromium is not installed on the runners; all three browser tests passed locally.Issue #19: build group connections in one pass
Closes #19.
The renderer formerly filtered all positioned entries separately for every occupied group when preparing constellation links. It now builds a render-local group-to-entries Map in one pass, then emits links in the original group and member order. Endpoint direction (
ais the later entry,bthe previous one), group colors, dash styles, SVG markup and spark/trail index association are preserved. The index is discarded after each render. The previous strict-comparison behavior for malformedNaNgroup keys is explicitly preserved; unmatched groups are ignored as before. No fallback grouping was added. The follow-up below skips connection preparation in overview and streams the one-group case.The renderer regression compares ordered SVG group, path, color and dash against the original per-group filter oracle, and checks actual spark/trail positions by index. Fixtures cover empty/singleton, ungrouped, balanced, dominant plus singleton groups, dynamic/unknown groups, repeated actors and duplicate IDs across groups; overview, zoom, update and clear are exercised. A positive-controlled counter reports 4 full geometry filters on the previous commit and zero on the current renderer for the four-group fixture. Six deliberate mutations of ordering, direction, group membership, dash, spark index and
NaNmatching all fail the tests.Paired benchmark: the actual connection-preparation statements were extracted from
bd2808fand the new renderer and run on identicalconstellationLayout()geometry. Node 24.18.0, Linux x86_64 / i7-12700F, 1280×900, zoom 0.8; four warmups and eleven alternating samples. Total preparation medians (ms) for 16 balanced groups:For 10,000 entries across 128 small groups, median preparation was 10.5451 → 0.2544 ms, with 1,280,000 → 10,000 point visits. Small or single-group workloads can be slower (100 ungrouped: 0.0064 → 0.0161 ms; 10,000 in one grouped bucket: 0.2971 → 0.4993 ms). Full local evidence covers 35 size/distribution cases, p95, exact ordered link equality and separately instrumented indexing/link-generation phases. These are unisolated Node measurements of the extracted preparation block, not whole-render time, heap usage or FPS; they do not establish that the entire renderer is linear.
Validation:
node tests/constellation_selection_check.mjs src/xflog/assets; catalog-suppliedconstellation_check.mjs;uv run --no-sync pytest -q(617 passed, including three Chromium lifecycle tests); Ruff lint/format,bash -n install.sh,git diff --check,uv build --out-dir /tmp/xflog-group-connections-dist, wheel/source asset comparison, and 80 isolated no-Gradio core tests all passed. An independent offline Chromium 156 comparison of the same synthetic data with reduced motion and controlled active animation matched ordered paths and each spark/trail coordinate across overview, expansion, selection and zoom, with no page errors or provider requests.Gauntlet 1.2.0: PASS_WITHIN_SCOPE. Independent contract/oracle and browser reviews, targeted mutations and the paired benchmark covered the final snapshot; local ignored evidence is under
evidence/issue19-connections/. The actual browser fixture had nine events and two groups; mobile, physical devices, screen readers, other browsers and browser FPS were not tested.GitHub CI on
616ed77: Python 3.12, 3.13, 3.14 and Headless package passed (run 43241842614). Each Python job reported 614 passed and three browser tests skipped because Chromium is not installed on the runners; all three browser tests passed locally.Follow-up: avoid unused overview and single-group connection work
linksempty without constructing the group-to-people index, traversing positioned people for connection preparation, or allocating connection objects. The rest ofrender()still processes people, including its separate post-markuppeopleByEventselection lookup. Zooming back rebuilds links and animation bindings.===semantics and a previous-person reference; empty groups do nothing. Multiple groups keep the existing render-local Map and ordering algorithm.NaNremains excluded under strict comparison.NaNinputs. Fake animation frames check that overview never writes to old sparks/trails, then verify exact paths and animation association after zooming back. Isolated mutations for stale references, missing overview/strict-equality/NaN guards and reversed direction fail as expected; 1,500 additional seeded synthetic geometries match the filter oracle.Paired Node benchmark: actual preparation blocks extracted from original filter
bd2808f, indexed PR head616ed77, and this change, fed identical realconstellationLayout()data. Node 24.18.0, Linux x86_64, i7-12700F, 1280×900; 8 warmups and 31 alternating batched samples; no CPU isolation. Table shows first-run median (p95) total milliseconds; final index/generation phase medians are separately instrumented and should not be added to total.At 10,000 entries in overview, indexed → revised connection-preparation geometry-person visits were 10,000 → 0 and connection objects 9,984 → 0; ordinary one-group visits remain 10,000 but the temporary index and its bucket are gone. Multi-group visits remain 10,000. For four groups the second run also measured 0.23175 ms indexed vs 0.32952 ms revised (filter 0.49299 ms): this is a repeatable isolated benchmark slowdown versus the indexed head, although still faster than the original filter. A separate four-version control-flow experiment gave different relative timings; the cause is not established. These timings exclude layout, DOM, paint and full-render latency and do not establish FPS changes. The ignored local benchmark scripts, phase/p95 data and both runs are under
evidence/overview-single-group/.Validation:
node tests/constellation_selection_check.mjs src/xflog/assets; catalog-suppliednode tests/constellation_check.mjs;uv run --no-sync pytest -q(617 passed, including 3 local Chromium lifecycle tests); Ruff lint/format,bash -n install.sh,git diff --check;uv build --out-dir /tmp/xflog-connections-final-distand wheel/source asset comparison; and 80 no-Gradio core tests passed. Offline Chromium 156 differential runs (desktop 1280×900 and mobile 390×844; normal and reduced motion) matched the prior renderer across ungrouped, overview, expansion, keyboard and zoom stages; desktop also exercised pointer selection. The mobile comparison did not perform a pointer click. There were no page errors or external requests.Gauntlet v1.2.0: BUDGET_EXHAUSTED, not a pass. Correctness/API, frontend/accessibility and performance/operations were reviewed. A final test-counter repair reset the clean-review streak; two clean re-attacks remained before the six-round standard budget expired, short of the required three. An independent review identified and verified a repair to a stale-animation test oracle. Separate final attacks covered mutation-tested strict equality and lifecycle, controlled browser transitions, and seeded oracle/paired performance evidence. The four-group benchmark trade-off remains as described above; other browser engines, physical devices and whole-render/FPS performance were not tested. No merge or release is included.
GitHub CI on
cefcd56: Python 3.12, 3.13, 3.14 and Headless package passed (run 43247527964). Each Python job had 614 passed and 3 Chromium tests skipped on the runner; all three Chromium tests passed locally. The headless job passed 80 tests.GitHub CI on final head
eb72599: Python 3.12, 3.13, 3.14 and Headless package passed (run 43248167861). Each Python runner reported 614 passed and 3 skipped Chromium tests; all three passed locally. The headless job passed 80 tests.Fresh final verification: connection-only measurement scope
The earlier
BUDGET_EXHAUSTEDresult above describes that completed review and is not relabeled. This separately requested Gauntlet v1.2.0 review ofeb72599and its test-only follow-up clarifies the counters: overview avoids the connection-preparation group index, point traversal and link objects; it still renders people and builds the separate event-to-person selection lookup after markup. The test observes that later lookup and has positive controls for discardedfilterandmapconnection work. Eleven isolated mutations fail, including strict equality/NaN, ordering, endpoint direction, color/dash, stale sparks and discarded overview work; normal selected-event interaction still passes. No production algorithm was changed.Fresh paired benchmark: actual blocks from original filter
bd2808f, indexed head616ed77, andeb72599received identical realconstellationLayoutgeometry. Node 24.18.0 on Linux x86_64/i7-12700F; CPU 2 affinity (not CPU isolation); 24 warmups and 96 measured samples, all six execution orders balanced, batched per case. Cells show run 1 median (p95) / run 2 median (p95) in milliseconds:The counts are for connection preparation only. With 10,000 entries in four groups, filter/indexed/current visits were 40,000/10,000/10,000 with 9,996 emitted links each; at 128 groups they were 1,280,000/10,000/10,000 with 9,872 links each. In 16-group overview, indexed/current visits were 10,000/0 and links 9,984/0. These zero counts exclude layout, markup and the selection lookup.
The previously reported ~0.10 ms four-group gap did not recur in the fresh paired runs, although the revised median was 0.014–0.020 ms slower there. A second order-balanced five-version cause experiment produced indexed/current four-group medians of 0.19933/0.19733 and 0.20867/0.20100 ms. Changing branch order or allocation order did not consistently explain or improve the result. These experiments demonstrate context-sensitive timings, not a proven V8/GC cause or full-render regression; no production rewrite is justified. No FPS or browser-latency improvement is claimed. Local reproducible scripts, p95s, raw samples and counts are in the ignored
evidence/final-pr16-review/performance/directory.Fresh Gauntlet v1.2.0: PASS_WITHIN_SCOPE. Correctness/API, frontend/accessibility and performance/operations were reviewed. After the final test-oracle repairs, three distinct clean re-attacks covered independent strict-filter and mutation oracles; controlled lifecycle/browser and selection transitions; and the measurement harness, counts and competing performance results. No unresolved scoped defect was found. This does not supersede the earlier review's budget-exhausted status. The bounded result does not prove all possible instrumentation patterns, establish a root cause for benchmark variation, or measure full-render/FPS behavior.
Fresh verification: Node selection and catalog-supplied layout checks; 617 Python tests including three local Chromium lifecycle tests; Ruff lint/format, shell syntax and diff checks; package build and wheel/source asset equality; 80 no-Gradio core tests. Offline Chromium 156 comparisons matched paths and states at desktop/mobile sizes with normal/reduced motion; pointer click was exercised on desktop only. No live X requests were made.
GitHub CI on final head
5bbf827: Python 3.12, 3.13, 3.14 and Headless package passed (run 43252407670). Each Python runner reported 614 passed and three Chromium tests skipped; all three passed locally. The headless job passed 80 tests.Release preparation
Prepare patch release v1.0.11: update the package version and lockfile and add a changelog entry covering the constellation performance and lifecycle improvements. Local verification: 617 tests, Ruff lint and format, shell syntax, lockfile check and package build passed. The release workflow publishes the version-matched package and generates the GitHub release notes from this entry.