Repository navigation
Conversation
Consolidated, de-duplicated review of the launcher, all runtime and installer modules, the Steam helpers, system/ hooks, CI workflows and the test tree. Per-module reports with full reasoning are under docs/reviews/2026-09-28/. Top findings: the startup guard's `pkill -9 -f PolyMC` matches the launcher's own cmdline; SLOT_DIED frees the slot before teardown so hung JVMs are never killed on the default proxy path; the dex XWindowAttributes struct omits colormap so map_state reads the wrong field. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013yYdp31rf3ha67LhUaJZuS
Six phases (CI trust first, then the three Criticals, blast radius, session stability flag-gated, installer, security, system hooks), dependency graph, per-PR checklist, and the HW-3 Deck validation session mapped to tests/hardware stages. Tracking issue: #200. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013yYdp31rf3ha67LhUaJZuS
…view One file per Critical/High/Medium finding plus one grouped Low/Info checklist per module. Each carries a unified diff that was syntax-checked and `git apply --check`ed against the pristine tree, the unit test and mutation to add, and the hardware step that proves the fix. These are the bodies posted as sub-issues of tracking issue #200. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013yYdp31rf3ha67LhUaJZuS
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013yYdp31rf3ha67LhUaJZuS
…DIR/mcss Export MCSS_HELPER_DIR / MCSS_PROXY_PADS_DIR / MCSS_PROXY_VIRT_DIR under the suite tmpdir before sourcing the launcher, stub proxy_stop_slot/slot_free in T6.3, and refuse to run if the helper dir ever resolves outside the tmpdir. Since #150 flipped MCSS_CONTROLLER_PROXY to 1, the SLOT_DIED handler's real proxy_stop_slot could kill a live session's slot-2 evsieve during a Deck run. Fixes #203 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013yYdp31rf3ha67LhUaJZuS
…r the tmpdir T4.5/T4.8 drive the real teardown_instance, which process-group-kills the state file's bwrap_pid; the old literals (99998/99999, 11110..44440) were below kernel.pid_max, so a reachable PGID could be SIGTERM/SIGKILLed on an un-namespaced run. Same guard as tests/test_orchestrator.sh. The two fixtures also point MCSS_GEOM_DIR at the tmpdir so a run no longer deletes the live /tmp/mcss-geom/slotN cache (T12). Fixes #202 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013yYdp31rf3ha67LhUaJZuS
) hw_reap_stale_session ran four unconditional name-matched `pkill -9 -f` sweeps (kwin_wayland, latestUpdate, bwrap.*PolyMC, SteamLaunch.*) on every stage launch/stop. On SteamOS Desktop Mode and Bazzite hosts kwin_wayland is the operator's whole session, and `-f latestUpdate` matched any `tail -f .../latestUpdate-1/latest.log` in another terminal. Replace them with _hw_session_pids: marked processes (SPLITSCREEN_DEBUG_LOG= in environ), their descendants (covers the unmarked kwin_wayland under a marked wrapper), and the Steam reaper identified as the unmarked parent of a marked launcher, minus the harness ancestor chain. One ps snapshot, SIGKILL in a bounded 5-sweep loop. New tests/test_hw_helpers_reap.sh builds that tree from renamed sleeps and asserts the set, the exclusions, the reap, and that no pkill/killall invocation remains. Mutation: re-adding the latestUpdate pkill fails T1.1 and T1.6. Fixes #201 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013yYdp31rf3ha67LhUaJZuS
…etired one
T3.1/T3.9 still encoded the highest-slot rule that compute_grid_mode
deliberately replaced (2026-06-23), so the suite was red on correct code
(7/9, tolerated by a CI baseline of 7) and went 9/9 green if the fix was
reverted. Rewrite the table to the count contract ({2}->full, {1,3}->half,
{2,4}->half, {3}->full), assert the scale-down cell mapping in T3.9, and
raise the CI baseline to 9. Mutation: reverting compute_grid_mode to
highest-slot now fails 5 T3.1 cases and T3.9.
Fixes #204
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yYdp31rf3ha67LhUaJZuS
…ually reaps _mock_cleanup looped over $MOCKBIN/*.pid files that nothing wrote, so every `sleep 30` mock dialog outlived its test (6-8 orphans per run) and T3.2/T3.3 found the mock with a name-matched pgrep. The mock now writes $$ and execs the sleep, T3.2/T3.3 read the pid from the file, and a new T3.5 asserts the cleanup reaps by pid. Mutations: dropping the exec or the .pid write go red. Fixes #205 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013yYdp31rf3ha67LhUaJZuS
UhidPad.axis committed the value to self._axes and only then hit the range check in encode_report, so one `axis LX 300` poisoned the pad: every later press/hat/release re-raised on the stored value until `neutral`. Validate first, like press()/hat(); expose it in --self-test and assert it in T5.4. Mutation: reverting axis() to store-then-send reports rejected,axes=1. Fixes #206 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013yYdp31rf3ha67LhUaJZuS
…wn rule The helper carried a hand copy of the grid/cell policy that had drifted from compute_grid_mode/apply_layout (any slot>=3 -> quad; half cells by slot number instead of order): 10 of 32 (subset, slot) pairs disagreed, hidden only because every stage passes a contiguous set. It now sources window_manager.sh lazily and uses compute_grid_mode + compute_slot_geometry with the apply_layout cell rule. New tests/test_hw_helpers_geometry.sh sweeps all 32 pairs against an independent oracle (red on the old copy; mutation that maps quad cells by order goes red). Fixes #207 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013yYdp31rf3ha67LhUaJZuS
…ubshell's stderr The suite's hand-copied installer list had drifted (version_stamp.sh, #89, was never added) and its `2>&1` sat outside the command substitution, so a `readonly variable` line from a double-source escaped to the terminal and the case still passed. Parse INSTALLER_MODULE_FILES from the installer and move the redirect inside. With stderr captured the suite exposed controller_proxy.sh's unguarded top-level readonly block, which now uses the house _*_CONSTANTS_LOCKED guard. Mutation: a readonly appended to version_stamp.sh goes red. Fixes #208 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013yYdp31rf3ha67LhUaJZuS
_hw_session_pids listed zombies (already dead, unsignallable), which kept the 5-sweep loop re-running until PID 1 reaped them; on a container init that made test_hw_helpers_reap.sh T1.4 flaky (3/5 runs). Skip stat Z in the ps snapshot and treat a zombie as dead in the test. Refs #201 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013yYdp31rf3ha67LhUaJZuS
The old gate compared only `passed >= BASELINE` and discarded each suite's exit code, so test_uhid_pad.sh could lose 5 of 23 tests with CI green, a suite that recorded [FAIL] lines but still printed a full count passed, and seven CI-safe suites were not gated at all. Now every tests/test_*.sh found by glob runs under a per-suite timeout with output to a file (never a $(...) capture, #80/#103), and the gate is the exit status plus the presence of a standard "X/Y tests passed" summary. A KNOWN_FAIL map holds the exact summary a known-red suite must print (empty since #204). The three suites that printed "[OK] ..." get the standard footer; test_phase_b_lifecycle.sh is the one explicit SKIP. Job timeout 30 min. Fixes #225 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013yYdp31rf3ha67LhUaJZuS
T13 asserts the "fuse-overlayfs not available -> single create, no retry" path, but _build_isolated_base symlinked every real /usr/bin tool, so on GitHub's ubuntu runner (which ships fuse-overlayfs) the module found it and retried: 19/20 on the first gated run of #225. Exclude it like git/distrobox/podman/cargo/sha256sum; T12/T14 already add their own placeholder. Verified 20/20 with a fake /usr/bin/fuse-overlayfs present. Refs #225 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013yYdp31rf3ha67LhUaJZuS
…leep ubuntu-latest moved to 26.04, whose coreutils is a multi-call binary (uutils): a copy named "steam" dispatches on argv[0], prints "coreutils: unknown program 'steam'" and exits, so T5.1 ran with no Steam process and failed on the first CI run gated by exit status (#225). A #! script gets its comm from the script file, so it is "steam" on any coreutils. T5.1 now also checks the fixture before asserting, so a broken fake reports as a fixture failure instead of a guard regression. Mutation checked: disabling the guard in remove-from-steam.py turns T5.1 red; renaming the fake turns it red with the fixture message. Refs #225 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Phase 0 of the 2026-09-28 code review (#200): the review documents, the fix plan, and the test-suite fixes that have to land before anything else, so the CI gate can be trusted when the product fixes start.
What's in it
docs/reviews/2026-09-28/: 177 findings, a phased fix and hardware-verification plan, and draft bodies for [T1] Hardware helper hw_reap_stale_session pkill -9 -f kwin_wayland/latestUpdate kills the operator's desktop #201–[A14-A28] Orchestrator/launcher low & info findings: subshell state loss, kill 0, dead code, hygiene #267.pkill -9 -f kwin_wayland(which killed the operator's desktop).test_uninstall_purge.shT5.1.ubuntu-latestis now Ubuntu 26.04, whose coreutils is a multi-call binary: the fixture's copy of/bin/sleepnamedsteamprintedcoreutils: unknown program 'steam'and exited, so no "Steam" process existed. The fake is now a#!script, and the test checks the fixture before asserting. The uninstaller's guard was fine, and the new gate caught a real fixture break, which is what it's for.Production code changed:
modules/controller_proxy.sh(for #208's guarded readonly block) and nothing else. Everything else is tests, CI and docs.Testing
tests/test_uninstall_purge.sh: 22/22 locally on a checkout outside/tmp.remove-from-steam.pyturns T5.1 red.shellcheck -S warningis clean on the changed test.Found while testing, not fixed here
uninstall-minecraft-splitscreen.sh:444deletes the helper by path match ([[ "$helper" == /tmp/* ]] && rm -f), so a checkout under/tmploses its ownremove-from-steam.pyon an uninstall run, including from the test suite. That's a product bug, out of scope for this test-only PR; it belongs with F14 in #260.Fixes #201
Fixes #202
Fixes #203
Fixes #204
Fixes #205
Fixes #206
Fixes #207
Fixes #208
Fixes #225
Refs #200
🤖 Generated with Claude Code