docs/superpowers/plans/2026-09-05-component-separation.md
Ref: Size: 8.8 KiB History
# Component separation and independent development The user authorized another separation sprint after interaction ownership commit `efc99d5`, followed by a clearer division of ownership so daemon and GUI work can proceed independently. Prior recorded-demo acceptance remains pending; this is explicit advancement authorization, not retrospective demo approval. Status: implemented, reviewed and validated. All final delivery gates passed; the retained recording awaits user acceptance. Ownership roles are proposed; no people are assigned. ## Scope and contract Opening inspection found the daemon and GUI already independent in the production module graph. The shared client facade serves actual common transport/discovery needs; splitting it would require a larger change without evidence of benefit. No separate preparatory cleanup was needed. The smallest useful change is independent component testing and an independently owned native policy module: | Module | Owns | Declared production imports | | --- | --- | --- | | `native_core` | workspace, runtime, picker, persistence, interaction | client, term | | `native` | frame adapter, font/atlas/painter, frame timing | native_core, client, term | | `daemon` | existing server core and children | Unchanged | `src/gui/native_core.zig` is the only module root that reaches its five child files by relative import. The frame adapter consumes them through the declared `native_core` import. Compatibility aliases in `native.zig` preserve its public API without creating a second source owner. Native layout, runtime, shared client behavior and all controls remain unchanged. `native-core-test` compiles its own test artifact with shared QUIC support and no window/font libraries. `native-test` runs that same artifact plus the frame/painter tests. `daemon-test` and `client-test` reuse their existing run nodes from aggregate `test`; there is no second test implementation or duplicate artifact. All native targets remain opt-in. Root owned the build graph, Makefile, independent validation and documentation. Luna implemented and wired the core root and GUI imports. Terra independently reviewed both changes and the ownership/test contracts. Fresh short contexts were used, and recorded `turn_context.model` metadata confirmed Luna and Terra immediately at startup. Closing cleanup corrected a forbidden window-library name in the new root's comment, removed a redundant test alias and updated the build comments. No production behavior was changed during cleanup. ## Acceptance and evidence The final integrated ReleaseSafe build passed 47 native tests: 20 in the independent core and 27 in the frame/painter suite. The new root contributes one registration test; existing test coverage is retained. Independent compilation was tested in a disposable snapshot containing the final module/build changes. Each deliberate failure has a matching negative control: | Snapshot condition | Expected independent result | Negative control | | --- | --- | --- | | Frame contains a deliberate compile error | `daemon-test native-core-test` pass | `native-test` fails with the planted GUI diagnostic | | Daemon contains a deliberate compile error | `native native-test` pass | `daemon-test` fails with the planted daemon diagnostic | | Window-library pkg-config search paths are empty | `native-core-test` passes | `native` fails to resolve its required packages | All six checks passed. The snapshot files were restored in `finally`; the shared checkout was never modified by the probes. This proves compile/test isolation, not that shared wire changes can be made without coordinating their semantics. Repository-wide source rules and shared build-file validity still apply. Final gates use `ZIG_GLOBAL_CACHE_DIR=/tmp/muxg-zig-cache`, the pinned compiler, and authorized local socket/PTY access: | Gate | Result | | --- | --- | | `deps/zig/zig build install native native-test -Doptimize=ReleaseSafe -p dist/native-component-release --summary all` | Passed; both release binaries from one graph, 47 tests | | Independent compilation probes above | Passed | | `make native-e2e` | Passed; 62 scenarios | | Prior-daemon compatibility | Passed separately; 63 total native integration scenarios | | Real OpenSSH/Wayland recovery | All five groups passed at 200% | | Wayland scale and raw-output stress | Scale passed; stress passed on normal-logging repeat, earlier misses retained | | `make check` / `make ci` | Passed on the final fixture repair | The full CI attempt exposed the recurring terminal picker fixture race from the prior sprint. Its script pressed Enter and immediately selected row 2 while the host poll could still contain only session 0. That selection was clamped; waiting for silence afterward could not repair it. The repaired script waits for the actual unselected born-session row (`2 1`) before pressing 2, retaining the selected-row and holder-count assertions and all original timeouts. Terra rejected an initial wait on session 0 because it would accept the stale list. The focused 15-scenario host group and the subsequent independent full CI run both passed. No terminal production code changed. The first Wayland stress run narrowly missed the 20 ms frame p99 budget at 20.176 ms. The previously validated interaction release also missed it on that compositor (20.567 ms before reopen, 20.270 ms afterward). After restarting the owned compositor with normal logging, preserving its geometry, scale and GLES2 renderer settings, the final release passed unchanged budgets: 18.992 ms before reopen and 18.246 ms afterward. This does not establish the exact cause of the variation. Debug startup identified NVIDIA GeForce RTX 3080; normal-logging startup did not repeat the device identification. Keep that provenance limit with the measurement rather than inferring a performance improvement. The successful 30.1-second stress run read 104.6 MB. Sampled input-to-painted maxima were 55.5 ms on the shared daemon and 55.4 ms on the separate daemon, 94 samples each. The 5 ms polling interval and observation overhead make these upper bounds. Runs used an isolated compositor without concurrent GUI fixtures or recording, and no budget was relaxed. No new macOS result is claimed. A 56.8-second actual GUI recording uses the final release at 200%, H.264 1100×700 with no audio. It shows the unchanged menu, resize, delayed End, restoration and replacement behavior through three continuous clips with two restart cuts. Input is through ordinary SDL events; this is not a new compositor mouse-path trial. The fixtures and owned compositor were stopped. The recording is retained at: `/home/xanderle/.codex/visualizations/2026/09/05/01a071c2-5767-7790-a335-1a84536c9ca5/native-component-trial.mp4`. Logs, exact probe commands, both stress failures and the successful repeat, source/release hashes, recording driver and model metadata are in the sibling `component-evidence/` directory. User recording acceptance is separate from all automated checks. No new Tailscale route or payload was published. ## Ownership follow-up The [ownership proposal](../../component-ownership.md) starts with daemon, native GUI, and shared wire/client services. GUI policy and rendering now have a usable internal boundary, but assigning them separate people is optional. Terminal and browser frontends retain their own responsibilities. Shared build/release and contract changes require coordination; ordinary internal work uses the focused component gates and separate worktrees. No directory reshuffle, repository split, named CODEOWNERS assignment or shared wire redesign is included. Future assignments should follow these tested module boundaries and account for mixed folders such as `src/client/` and `src/engine/`. ### Ownership handoff continuation The user's subsequent “continue” advances the ownership handoff. This is a documentation slice: reusable role briefs, worktree prerequisites, focused gate selection and shared-contract handoffs. It does not change the production module graph or imply acceptance of the retained GUI recording. Human assignments stay open until names are supplied. Opening review found one stale module table in `CLAUDE.md`; it now lists `native_core` and its policy files separately from `native` and its painter files. The ownership guide remains the single source for role briefs and handoffs. Closing review checks the guide against the actual module roots and Makefile, including mixed-directory ownership and the limits of focused test coverage. The completed handoff passed independent review and `make ci` (including all terminal integration scenarios, ten agent scenarios and throughput). No native source or build wiring changed; the prior native validation and recording remain the applicable runtime evidence. The focused Make recipes were independently checked against the guide. Logs and model metadata are retained in `ownership-evidence/` beside this thread's visualization artifacts.