2a48815a
docs: define component owner scopes and handoffs
a73x 2026-09-05 16:15
Commit message
CLAUDE.md
| Old | New | ||
|---|---|---|---|
| @@ -81,7 +81,7 @@ a symbol by its FILE stem (`wall_pump.askOn`) — a file, not a module. | |||
| 81 | | `src/engine/` | `term`(`term.zig`) — `protocol` `replica` `grid` · `engine`(`engine.zig`) — `delta` — the daemon's ghostty-vt; no client row imports it outside a test | | 81 | | `src/engine/` | `term`(`term.zig`) — `protocol` `replica` `grid` · `engine`(`engine.zig`) — `delta` — the daemon's ghostty-vt; no client row imports it outside a test | |
| 82 | | `src/server/` | `daemon`(`server.zig`) — `server_agent` `server_sessions` `cmd` `shellint` `quic_server` `upgrade` `server_test_*` · `pty` | | 82 | | `src/server/` | `daemon`(`server.zig`) — `server_agent` `server_sessions` `cmd` `shellint` `quic_server` `upgrade` `server_test_*` · `pty` | |
| 83 | | `src/client/` | `client` — `client_core` `hosts` `handoff` `layout` `keymap` `askpass` `session_pump` `buffered_wire` `open_wait` `resolver` `discovery` · `webhub` · `wasm_core` `client_core_wasm_check` (wasm roots the build wires outside the table) | | 83 | | `src/client/` | `client` — `client_core` `hosts` `handoff` `layout` `keymap` `askpass` `session_pump` `buffered_wire` `open_wait` `resolver` `discovery` · `webhub` · `wasm_core` `client_core_wasm_check` (wasm roots the build wires outside the table) | |
| 84 | | `src/gui/` | `native`(`native.zig`) — `workspace` `runtime` `picker` `persistence` `font` `atlas` `quads` `gl` `frame` `bench` | | 84 | | `src/gui/` | `native_core`(`native_core.zig`) — `workspace` `runtime` `picker` `persistence` `interaction` · `native`(`native.zig`) — `font` `atlas` `quads` `gl` `frame` `bench` | |
| 85 | | `src/tui/` | `wall`(`wallview.zig`) — `interact` `paint` `select` `predict` `wall_host` `wall_picker` `wall_pump` `wall_layout` `wall_test_*` | | 85 | | `src/tui/` | `wall`(`wallview.zig`) — `interact` `paint` `select` `predict` `wall_host` `wall_picker` `wall_pump` `wall_layout` `wall_test_*` | |
| 86 | | `src/cli/` | `mux`(dispatch) — `main`(daemon) `mux_main`(client) `webhub_main`(hub) · `muxg`(native viewer) · `agent`(`muxa.zig`) · `cliflags`(`flags.zig`) | | 86 | | `src/cli/` | `mux`(dispatch) — `main`(daemon) `mux_main`(client) `webhub_main`(hub) · `muxg`(native viewer) · `agent`(`muxa.zig`) · `cliflags`(`flags.zig`) | |
| 87 | | `src/os/` | `server_os`(`server_os.zig`) — `server_os_linux` `server_os_macos` · `client_os`(`client_os.zig`) — `client_os_linux` `client_os_macos` · `spawn` — the platform layer, one row per side so the client never links a fork or a pty; imports nothing of ours (spec 2026-09-03) | | 87 | | `src/os/` | `server_os`(`server_os.zig`) — `server_os_linux` `server_os_macos` · `client_os`(`client_os.zig`) — `client_os_linux` `client_os_macos` · `spawn` — the platform layer, one row per side so the client never links a fork or a pty; imports nothing of ours (spec 2026-09-03) | |
RETRO.md
| Old | New | ||
|---|---|---|---|
| @@ -668,3 +668,47 @@ were invented, and mixed directories are called out explicitly. | |||
| 668 | conclusions from a narrow frame-budget miss. | 668 | conclusions from a narrow frame-budget miss. |
| 669 | - [ ] Promote the general recorder/clip fixture in a future tooling package; the | 669 | - [ ] Promote the general recorder/clip fixture in a future tooling package; the |
| 670 | repository scale gate already removed one temporary-script dependency. | 670 | repository scale gate already removed one temporary-script dependency. |
| 671 | |||
| 672 | ## Component ownership handoff — 2026-09-05 | ||
| 673 | |||
| 674 | The user asked to continue after the separation sprint. The remaining ownership | ||
| 675 | handoff is now actionable in `docs/component-ownership.md`: role edit scopes, | ||
| 676 | worktree prerequisites, focused commands, review handoffs and examples of | ||
| 677 | independent daemon work versus shared-contract changes. These role briefs can | ||
| 678 | be used for people or task-specific agents; no named assignments or CODEOWNERS | ||
| 679 | enforcement have been invented. | ||
| 680 | |||
| 681 | Opening cleanup corrected the stale GUI module table in `CLAUDE.md`. Closing | ||
| 682 | review preserved details that a directory-only split would miss: daemon | ||
| 683 | `main.zig` belongs to the shared dispatcher build, browser files live under | ||
| 684 | `src/client/`, and daemon tests do not execute every dependency's test suite. | ||
| 685 | Component owners can edit their own tests. Shared fixtures and changes to wire | ||
| 686 | or lifecycle meaning require coordination across the affected components. | ||
| 687 | |||
| 688 | Reused session metadata confirmed Luna implementation and Terra review. Root | ||
| 689 | independently checked the module roots, source-ban invocation, Make recipes and | ||
| 690 | ignored dependency paths. Reviewer corrections retained Make's macOS SDK setup | ||
| 691 | and required real native integration evidence for pane lifecycle changes. | ||
| 692 | Generated QUIC dependencies must not be rebuilt or cleaned concurrently through | ||
| 693 | a shared directory. The guide keeps existing compilation-isolation evidence | ||
| 694 | and its limits; this documentation change makes no new runtime claim. | ||
| 695 | |||
| 696 | Full `make ci` passed: terminal integration, all ten agent scenarios and | ||
| 697 | throughput, alongside its source/unit checks. The final documentation diff is | ||
| 698 | clean and the focused Make commands match the documented gates. Native source | ||
| 699 | and build wiring are unchanged, so the prior sprint's native evidence applies. | ||
| 700 | |||
| 701 | Validation logs and available cumulative agent counters are retained under | ||
| 702 | `ownership-evidence/` beside this thread's visualization artifacts. Those | ||
| 703 | counters include the agents' earlier separation work and cached input; they | ||
| 704 | are not incremental task costs. No new GUI recording is needed for this | ||
| 705 | documentation handoff, and previous demo acceptance remains pending. | ||
| 706 | |||
| 707 | ### Next actions | ||
| 708 | |||
| 709 | - [x] Make the component proposal usable as bounded owner task briefs and | ||
| 710 | correct the stale module table. | ||
| 711 | - [ ] Assign people or task-specific agents when concrete work is selected; | ||
| 712 | start internal daemon and GUI tasks in separate worktrees with these briefs. | ||
| 713 | - [ ] Record user acceptance of the existing recordings separately. Continuing | ||
| 714 | the ownership handoff does not imply their acceptance. | ||
docs/component-ownership.md
| Old | New | ||
|---|---|---|---|
| @@ -1,82 +1,111 @@ | |||
| 1 | # Component boundaries and proposed ownership | 1 | # Component boundaries and reusable ownership briefs |
| 2 | 2 | ||
| 3 | The repository already separates the daemon from the GUI in its production | 3 | These are working boundaries for parallel development. They describe file and |
| 4 | module graph. The component-separation sprint adds independent test targets and | 4 | contract ownership; they do not assign people, CODEOWNERS entries, or approval |
| 5 | separates native workspace policy from the window/painter module. These are | 5 | authority. A change that crosses a boundary needs an explicit handoff to the |
| 6 | working boundaries; the roles below are a proposal for assigning people or | 6 | affected owner. |
| 7 | agents. No named reviewers or CODEOWNERS enforcement have been assigned. | ||
| 8 | 7 | ||
| 9 | ## Start with three ownership areas | 8 | ## Ownership briefs |
| 10 | 9 | ||
| 11 | | Area | Primary responsibility and files | Focused development gate | | 10 | | Area | Owns | Focused gate | |
| 12 | | --- | --- | --- | | 11 | | --- | --- | --- | |
| 13 | | Daemon | Session lifecycle, authoritative terminal engine, PTYs, scheduling, server transport and platform operations: `src/server/`, `src/engine/engine.zig`, `src/engine/delta.zig`, `src/os/server_os*` | `make daemon-test` | | 12 | | Daemon | Authoritative terminal state and session lifecycle in `src/server/`, daemon engine files `src/engine/engine.zig` and `delta.zig`, and `src/os/server_os*` | `make daemon-test` | |
| 14 | | Native GUI | Pane/workspace policy, persistence, input, rendering and window lifecycle: `src/gui/`, `src/cli/muxg.zig` | `make native-core-test` for policy; `make native` for the complete GUI | | 13 | | Native GUI | `src/gui/native_core.zig` and its window free children (`workspace.zig`, `runtime.zig`, `picker.zig`, `persistence.zig`, `interaction.zig`), plus `src/gui/native.zig`, `frame.zig`, `bench.zig`, `atlas.zig`, `font.zig`, `quads.zig`, `gl.zig`, and `src/cli/muxg.zig` | `make native-core-test` for policy; `make native` builds `muxg` and runs `native-test` | |
| 15 | | Shared wire and client services | Frame/schema compatibility and the reusable connection, discovery and session interfaces: the `term` module (`src/engine/term.zig`, `protocol.zig`, `grid.zig`, `replica.zig`), `src/client/` shared files, `src/dial.zig`, `src/link.zig`, `src/quic.zig` and client OS support | `make client-test` for client changes; `make check` for the complete shared unit coverage | | 14 | | Shared wire/client | The `term` component (`src/engine/term.zig`, `protocol.zig`, `grid.zig`, `replica.zig`), reusable `src/client/` services, and `src/dial.zig`, `src/link.zig`, `src/quic.zig` | `make client-test`; use `make check` before handoff | |
| 16 | 15 | ||
| 17 | The daemon mode entrypoint, `src/cli/main.zig`, belongs with daemon behavior but | 16 | The daemon is the backend; terminal UI (`src/tui/`, `src/cli/mux_main.zig`), |
| 18 | is compiled by the shared `mux` dispatcher. Changes there require the complete | 17 | browser UI (`web/`, `src/client/webhub.zig`, `src/cli/webhub_main.zig`, |
| 19 | CLI checks. Likewise `make daemon-test` exercises daemon tests, not every test | 18 | `src/client/wasm_core.zig`, and `src/client/client_core_wasm_check.zig`), and |
| 20 | in the engine or transport dependencies it compiles. Focused gates accelerate | 19 | native GUI are separate frontends. |
| 21 | development; they do not replace dependency and integration validation. | 20 | The `src/client/` brief covers reusable client services and client OS support |
| 22 | 21 | (`src/os/client_os*`), but does not automatically claim the browser frontend. | |
| 23 | Terminal UI (`src/tui/`, `src/cli/mux_main.zig`) and browser UI (`web/`, | 22 | The shared `mux` dispatcher and build configuration coordinate changes that |
| 24 | `src/client/webhub.zig`, `src/cli/webhub_main.zig`, `src/client/wasm_core.zig`) | 23 | cross these areas. |
| 25 | remain separate frontend responsibilities. In particular, a blanket ownership | 24 | |
| 26 | rule for `src/client/` would incorrectly include the browser frontend. Assign | 25 | `src/cli/main.zig` implements daemon behavior but is compiled through the |
| 27 | exceptions explicitly when named CODEOWNERS entries are introduced. | 26 | shared `mux` dispatcher. Changes there need the complete CLI checks. The |
| 28 | 27 | focused daemon gate does not execute every test in the engine and transport | |
| 29 | Build configuration, the CLI dispatcher, release tooling and integration tests | 28 | dependencies it compiles. |
| 30 | need a maintainer who coordinates changes crossing these areas. They should not | 29 | |
| 31 | be edited independently by several implementation agents in the same checkout. | 30 | The native GUI is split into two build components. `native_core` owns pane |
| 32 | 31 | identity, attachment lifetime, persistence, picker state, native workspace | |
| 33 | ## The native GUI has two internal components | 32 | layout, and GUI interaction policy. It imports only `client` and `term`. |
| 34 | 33 | `native` owns the window and painter; `frame.zig` is the only GUI file that | |
| 35 | `native_core` owns `workspace.zig`, `runtime.zig`, `picker.zig`, `persistence.zig` | 34 | spells the window library. The native root reaches core through |
| 36 | and `interaction.zig`, exported by `src/gui/native_core.zig`. It imports only | 35 | `@import("native_core")`, so core files have |
| 37 | the shared `client` and `term` modules. It owns native pane identity, attachment | 36 | one module owner. `native-test` runs the full native unit suite, while |
| 38 | lifetimes, authored layout and interaction policy, and receives measured geometry | 37 | `native-core-test` runs the window free part independently. `make native-e2e` |
| 39 | and translated input through its public interfaces. | 38 | is the real window and daemon boundary check when that evidence is needed. |
| 40 | 39 | ||
| 41 | `native` owns `frame.zig` and the painter/font/atlas files. It consumes | 40 | The daemon brief normally edits `src/server/`, daemon engine files, and server |
| 42 | `native_core` through a declared module import; it cannot take a second ownership | 41 | OS files. The GUI brief normally edits `src/gui/` and `src/cli/muxg.zig`. The |
| 43 | claim on the core files through relative imports. SDL stays in `frame.zig`. | 42 | shared brief normally edits `src/engine/term.zig`, `src/client/`, and the |
| 44 | `native-test` aggregates the independent core suite and the window/painter suite. | 43 | transport files named above. `build.zig`, `Makefile`, `src/cli/mux.zig`, shared |
| 45 | 44 | protocol or wire definitions, shared client APIs, and release tooling are | |
| 46 | Keep these under one GUI owner initially. Assigning separate policy and rendering | 45 | coordination files: inspect them first and hand off before changing their |
| 47 | owners becomes useful when there is enough parallel work to justify it; their | 46 | contract or build ownership. Each owner may edit its own component tests; |
| 48 | contract already exists without another file reorganization. | 47 | shared fixtures and integration tests require coordination. Escalate a change |
| 49 | 48 | when it alters wire compatibility, session or attachment lifecycle, CLI mode | |
| 50 | ## Changes that need coordination | 49 | semantics, or the meaning of an error shared across frontends. |
| 51 | 50 | ||
| 52 | A daemon internal change can be developed and tested without compiling the GUI. | 51 | ## Task brief and handoff |
| 53 | A GUI change can be developed without compiling the daemon. Each owner should | 52 | |
| 54 | use an isolated worktree so unfinished shared build-file edits do not interfere | 53 | Start from the current checkout and read `CLAUDE.md`, the relevant component |
| 55 | with another owner's work. Repository-wide source rules still apply to every | 54 | header, and the affected contract or protocol comments. Use an isolated |
| 56 | build in a checkout. | 55 | worktree when another component is active, after ensuring its ignored pinned |
| 57 | 56 | toolchain (`deps/zig`) and generated dependency inputs (`deps/quic/out` and | |
| 58 | A wire-format or lifecycle-semantics change is a shared contract change. Its | 57 | `deps/quic/work`) are available. The QUIC build script itself is tracked. |
| 59 | author should identify affected clients, preserve old-peer behavior where | 58 | Use worktree-local generated dependencies when rebuilding them; do not run |
| 60 | required, and run relevant cross-version and real-boundary tests. GUI recovery, | 59 | concurrent builders or cleanup against shared dependency directories. Build |
| 61 | join-only restoration, End/Detach semantics, and remote attachment identity are | 60 | with the pinned toolchain through Make so macOS SDK setup is retained. For |
| 62 | examples where coordination matters even if only daemon code changes. | 61 | example, a daemon task can use: |
| 63 | 62 | ||
| 64 | Keep module internals private to their component and add reusable operations to | 63 | ```sh |
| 65 | the existing shared client/wire interfaces. Native layout policy stays separate | 64 | ZIG_GLOBAL_CACHE_DIR=/tmp/muxg-daemon-task-cache make daemon-test |
| 66 | from terminal layout policy. Domain owners can decide internal implementation; | 65 | ``` |
| 67 | changing a shared contract needs the affected owners' review. | 66 | |
| 68 | 67 | Keep edits inside the brief until a contract change is agreed. Before handing | |
| 69 | ## Evidence behind the split | 68 | off, report the touched files, the public behavior or type contract, focused |
| 70 | 69 | commands and results, and any integration gate still required. The receiving | |
| 71 | The [component-separation delivery record](superpowers/plans/2026-09-05-component-separation.md) | 70 | owner reviews the diff and runs the smallest gate that exercises the seam; |
| 72 | retains independent compilation probes in a disposable source snapshot: | 71 | the coordinator then runs the broader gate after build wiring or shared |
| 73 | 72 | semantics change. | |
| 74 | - A deliberate GUI compilation failure leaves daemon and native-core tests usable. | 73 | |
| 75 | - A deliberate daemon compilation failure leaves the GUI build/tests usable. | 74 | Examples: |
| 76 | - Native-core tests pass with window-library package metadata unavailable, while | 75 | |
| 77 | a control GUI build correctly fails. | 76 | - A daemon internal refactor preserving its public behavior can proceed with |
| 78 | 77 | daemon-owned files and tests, followed by `make check` and `make ci`. It needs | |
| 79 | The matching negative controls prove the injected failures were active. The | 78 | no GUI implementation work or GUI-owner handoff. |
| 80 | source snapshot is restored after probing; the working checkout is never poisoned. | 79 | - A daemon change to session admission uses `make daemon-test`, then hands the |
| 81 | The full delivery gates remain `make ci` plus the relevant native integration, | 80 | admission and frame behavior to the shared-client owner for client and |
| 82 | scale, recovery and responsiveness checks. | 81 | cross-version checks. |
| 82 | - A picker or pane lifecycle change starts with `make native-core-test`, then | ||
| 83 | uses `make native` and `make native-e2e` to exercise its visible behavior and | ||
| 84 | real daemon interactions. Rendering and `muxg` argument changes also need the | ||
| 85 | full native build and relevant integration scenarios. | ||
| 86 | - A protocol or cell-layout change uses `make client-test` and `make check`, | ||
| 87 | then requires the daemon and native owners to run their focused gates because | ||
| 88 | both consume the wire contract. | ||
| 89 | |||
| 90 | Focused gates shorten iteration and identify the component that failed. Every | ||
| 91 | build still runs the repository source bans, so a focused gate does not bypass | ||
| 92 | global hygiene rules. Focused gates do not replace `make check`, `make ci`, | ||
| 93 | native end to end checks, or cross version checks when the changed contract | ||
| 94 | reaches those paths. Do not claim a shared semantic change is isolated merely | ||
| 95 | because its first edit is in one folder; shared build wiring also needs the | ||
| 96 | broader checks. | ||
| 97 | |||
| 98 | ## What remains shared | ||
| 99 | |||
| 100 | Wire compatibility, session naming, attachment sizes, replay semantics, | ||
| 101 | join versus create behavior, End/Detach behavior, and remote transport error | ||
| 102 | meaning are contracts between components. Keep implementation details private, | ||
| 103 | but document and hand off changes to these meanings with affected peers and | ||
| 104 | old-peer expectations. Native layout policy remains separate from terminal wall | ||
| 105 | layout policy even when both use the same daemon sessions. | ||
| 106 | |||
| 107 | The component split is supported by independent compilation probes recorded in | ||
| 108 | the [delivery plan](superpowers/plans/2026-09-05-component-separation.md): | ||
| 109 | core tests remain usable when window metadata is unavailable, and daemon and | ||
| 110 | GUI production failures do not require each other's source to compile. Those | ||
| 111 | probes are evidence for the boundary, not a substitute for the final gates. | ||
docs/superpowers/plans/2026-09-05-component-separation.md
| Old | New | ||
|---|---|---|---|
| @@ -130,3 +130,24 @@ component gates and separate worktrees. | |||
| 130 | No directory reshuffle, repository split, named CODEOWNERS assignment or shared | 130 | No directory reshuffle, repository split, named CODEOWNERS assignment or shared |
| 131 | wire redesign is included. Future assignments should follow these tested module | 131 | wire redesign is included. Future assignments should follow these tested module |
| 132 | boundaries and account for mixed folders such as `src/client/` and `src/engine/`. | 132 | boundaries and account for mixed folders such as `src/client/` and `src/engine/`. |
| 133 | |||
| 134 | ### Ownership handoff continuation | ||
| 135 | |||
| 136 | The user's subsequent “continue” advances the ownership handoff. This is a | ||
| 137 | documentation slice: reusable role briefs, worktree prerequisites, focused gate | ||
| 138 | selection and shared-contract handoffs. It does not change the production module | ||
| 139 | graph or imply acceptance of the retained GUI recording. Human assignments stay | ||
| 140 | open until names are supplied. | ||
| 141 | |||
| 142 | Opening review found one stale module table in `CLAUDE.md`; it now lists | ||
| 143 | `native_core` and its policy files separately from `native` and its painter files. | ||
| 144 | The ownership guide remains the single source for role briefs and handoffs. | ||
| 145 | Closing review checks the guide against the actual module roots and Makefile, | ||
| 146 | including mixed-directory ownership and the limits of focused test coverage. | ||
| 147 | |||
| 148 | The completed handoff passed independent review and `make ci` (including all | ||
| 149 | terminal integration scenarios, ten agent scenarios and throughput). No native | ||
| 150 | source or build wiring changed; the prior native validation and recording remain | ||
| 151 | the applicable runtime evidence. The focused Make recipes were independently | ||
| 152 | checked against the guide. Logs and model metadata are retained in | ||
| 153 | `ownership-evidence/` beside this thread's visualization artifacts. | ||