docs/component-ownership.md
Ref: Size: 7.1 KiB History
# Component boundaries and reusable ownership briefs
These are working boundaries for parallel development. They describe file and
contract ownership; they do not assign people, CODEOWNERS entries, or approval
authority. A change that crosses a boundary needs an explicit handoff to the
affected owner.
## Ownership briefs
| Area | Owns | Focused gate |
| --- | --- | --- |
| 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` |
| Native GUI | `src/gui/native_core.zig` and its window free children (`workspace.zig`, `runtime.zig`, `picker.zig`, `persistence.zig`, `interaction.zig`, `font_options.zig`, `config.zig`, `theme.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` |
| 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 |
The daemon is the backend; terminal UI (`src/tui/`, `src/cli/mux_main.zig`),
browser UI (`web/`, `src/client/webhub.zig`, `src/cli/webhub_main.zig`,
`src/client/wasm_core.zig`, and `src/client/client_core_wasm_check.zig`), and
native GUI are separate frontends.
The `src/client/` brief covers reusable client services and client OS support
(`src/os/client_os*`), but does not automatically claim the browser frontend.
The shared `mux` dispatcher and build configuration coordinate changes that
cross these areas.
`src/cli/main.zig` implements daemon behavior but is compiled through the
shared `mux` dispatcher. Changes there need the complete CLI checks. The
focused daemon gate does not execute every test in the engine and transport
dependencies it compiles.
The native GUI is split into two build components. `native_core` owns pane
identity, attachment lifetime, persistence, picker state, native workspace
layout, GUI interaction policy, font settings, configuration parsing, and theme
values/merging.
It imports only `client` and `term`. Appearance policy tests therefore run without
window or font libraries; the native root retains aliases for its callers.
`font_options.zig` owns point-size policy. CLI/config parsers delegate to it;
`font.zig` owns installed-face validation and rasterization through font libraries.
`native` owns the window and painter; `frame.zig` is the only GUI file that
spells the window library. The native root reaches core through
`@import("native_core")`, so core files have
one module owner. `native-test` runs the full native unit suite, while
`native-core-test` runs the window free part independently. `make native-e2e`
is the real window and daemon boundary check when that evidence is needed.
The daemon brief normally edits `src/server/`, daemon engine files, and server
OS files. The GUI brief normally edits `src/gui/` and `src/cli/muxg.zig`. The
shared brief normally edits `src/engine/term.zig`, `src/client/`, and the
transport files named above. `build.zig`, `Makefile`, `src/cli/mux.zig`, shared
protocol or wire definitions, shared client APIs, and release tooling are
coordination files: inspect them first and hand off before changing their
contract or build ownership. Each owner may edit its own component tests;
shared fixtures and integration tests require coordination. Escalate a change
when it alters wire compatibility, session or attachment lifecycle, CLI mode
semantics, or the meaning of an error shared across frontends.
## Task brief and handoff
Start from the current checkout and read `CLAUDE.md`, the relevant component
header, and the affected contract or protocol comments. Use an isolated
worktree when another component is active, after ensuring its pinned toolchain
(via `mise install` for the Zig pin in `mise.toml`) is available. The QUIC
build script itself is tracked.
Use worktree-local generated dependencies when rebuilding them; if another
worktree at the same revision/platform has matching `deps/quic/out`, you can
copy it in to avoid re-downloading, but keep `deps/quic/work` local per-worktree.
That workspace
contains absolute-path build caches and should not be shared by mutable symlinks.
Do not run concurrent builders or cleanup against shared dependency directories.
Build with the pinned toolchain through Make so macOS SDK setup is retained. For
example, a daemon task can use:
```sh
ZIG_GLOBAL_CACHE_DIR=/tmp/muxg-daemon-task-cache make daemon-test
```
Keep edits inside the brief until a contract change is agreed. Before handing
off, report the touched files, the public behavior or type contract, focused
commands and results, and any integration gate still required. The receiving
owner reviews the diff and runs the smallest gate that exercises the seam;
the coordinator then runs the broader gate after build wiring or shared
semantics change.
Examples:
- A daemon internal refactor preserving its public behavior can proceed with
daemon-owned files and tests, followed by `make check` and `make ci`. It needs
no GUI implementation work or GUI-owner handoff.
- A daemon change to session admission uses `make daemon-test`, then hands the
admission and frame behavior to the shared-client owner for client and
cross-version checks.
- A picker or pane lifecycle change starts with `make native-core-test`, then
uses `make native` and `make native-e2e` to exercise its visible behavior and
real daemon interactions. Rendering and `muxg` argument changes also need the
full native build and relevant integration scenarios.
- A protocol or cell-layout change uses `make client-test` and `make check`,
then requires the daemon and native owners to run their focused gates because
both consume the wire contract.
Focused gates shorten iteration and identify the component that failed. Every
build still runs the repository source bans, so a focused gate does not bypass
global hygiene rules. Focused gates do not replace `make check`, `make ci`,
native end to end checks, or cross version checks when the changed contract
reaches those paths. Do not claim a shared semantic change is isolated merely
because its first edit is in one folder; shared build wiring also needs the
broader checks.
## What remains shared
Wire compatibility, session naming, attachment sizes, replay semantics,
join versus create behavior, End/Detach behavior, and remote transport error
meaning are contracts between components. Keep implementation details private,
but document and hand off changes to these meanings with affected peers and
old-peer expectations. Native layout policy remains separate from terminal wall
layout policy even when both use the same daemon sessions.
The component split is supported by independent compilation probes recorded in
the [delivery plan](superpowers/plans/2026-09-05-component-separation.md):
core tests remain usable when window metadata is unavailable, and daemon and
GUI production failures do not require each other's source to compile. Those
probes are evidence for the boundary, not a substitute for the final gates.