a73x

docs/native-sprint-workflow.md

Ref:   Size: 12.3 KiB   History

# Native client sprint workflow

The repository's [sprint-delivery skill](skills/sprint-delivery/SKILL.md) supplies
the shared workflow and instructions for agents with different tool capabilities.
Any agent can read it directly; no personal skill installation is required.

Use this formula for each native client sprint. The tiling
[spec](superpowers/specs/2026-09-05-native-tiling-design.md) defines behavior;
the [delivery plan](superpowers/plans/2026-09-05-native-tiling.md) breaks it into
packages. Keep one sprint active, ending in a working demo and explicit acceptance.

1. **Review and scope.** Read the previous sprint's actions in [RETRO.md](../RETRO.md).
   Produce the reuse and ownership map required by the shared skill, using the
   [component briefs](component-ownership.md) and actual code/callers as evidence.
   Define the smallest useful deliverable, its acceptance scenarios, and what
   belongs to later sprints. Use existing agreements for material scope and
   destructive-action semantics; clarify only unresolved points before
   implementation. For other ergonomic choices, record the proposed defaults,
   implement them as trial behavior, demonstrate them, and adjust them from the
   resulting feedback. Record whether feedback comes from the recorded demo or a
   hands-on trial; hands-on feedback is optional.
2. **Tidy the starting point.** Inspect the code the sprint will touch. Make small,
   behavior-preserving refactors that simplify the planned work, review them,
   run affected checks and `make check`, and commit separately. No cleanup quota:
   if the code is ready, record that. Substantial refactors become explicit
   packages; unrelated debt goes into the backlog.
3. **Assign a bounded pair.** Reuse one implementer and one independent adversarial
   reviewer. Give them the package, relevant files, ownership boundaries,
   acceptance criteria, and each other's names. Root owns integration, independent
   acceptance, user communication, and commits. Delegate another task only when
   it can progress independently. Load skills only where they help the work.

   Cost default: explicitly select GPT-5.6 Luna for bounded implementation and
   GPT-5.6 Terra for adversarial review. Start with task-specific context instead
   of inheriting the full conversation. Escalate a concrete unresolved problem
   to a stronger model when needed. Root coordinates and integrates; assign each
   investigation one owner so agents do not repeat it independently by accident.

   Check each agent's model immediately after startup. Prefer recorded session
   `turn_context.model` metadata when available; distinguish it from the requested
   spawn setting, and do not rely on an agent's self-description. Retain available
   token counters with cached input identified separately; counters are not a
   monetary bill. After a sandbox denial, use the authorized validation route
   instead of repeating the same blocked suite or streaming its full failure log.
4. **Build a functional slice.** Establish the smallest model/interface contract,
   then connect actual input, rendering, and daemon behavior. Keep changes small
   enough to review. Avoid expanding into later sprint features.
5. **Resolve concrete review findings.** Apply the shared skill's correctness and
   structural review criteria. The reviewer supplies a scenario or structural
   finding, consequence, and expected result directly to the implementer. The
   implementer returns a fix and evidence, or a reason the finding does not apply.
   Root adjudicates disagreement against requirements and observed behavior. Agreement
   is not a substitute for independent validation.
6. **Validate through real boundaries.** Drive ordinary SDL events into an isolated
   GUI using `test/native_tiling.py`'s Rig. Compare actual framebuffer pixels and
   independently queried daemon state, including every pane's PTY dimensions.
   Exercise failure paths and event ordering. Observation helpers must not repair
   the state under test. Use real Wayland at high DPI and a scale transition;
   exercise SSH/QUIC when changes affect their behavior. Create and clean up only
   owned fixture sessions and daemons.

   An isolated compositor can exercise scale changes without changing the user's
   monitor. Start it in its own process session. Wait for a window to map before
   resizing it, or use a compositor mapping rule for fixture geometry. Record the
   compositor's renderer: a software compositor is useful for functional checks,
   but does not establish hardware frame-time performance. Run performance checks
   separately from recordings and other GUI fixtures on that compositor.

   `test/native_scale.py MUX MUXG --output HEADLESS-1` runs the retained
   200%/100%/150%/200% scale scenario, including drag cancellation, real PTY sizes
   and framebuffer checks. Set `XDG_RUNTIME_DIR`, `WAYLAND_DISPLAY`, and `SWAYSOCK`
   to an owned isolated Sway compositor and pass both release binaries. The script
   restores the output's original scale and closes its fixtures on exit.

   For responsiveness, run `make native-stress` on Linux. It builds both binaries
   in ReleaseSafe from the same build graph and drives raw `cat /dev/random` in
   one pane while probing neighbours on the same daemon and a separate daemon.
   It checks ongoing output, input through completed painted state, menus,
   divider resizing, and close/reopen under load. Daemon inspection happens after
   the timed paint observation. Report sampled latency as an upper bound; frame
   timing alone does not establish input responsiveness.

   For lifecycle work, independently observe the daemon after Detach and End,
   including another attached client. Change focus and open another modal while
   a destructive request is pending; a later confirmation must still identify
   its original target. For persistence, retain original bytes across real
   permission failures, reopen from a different working directory and scale, and
   keep a sentinel in the terminal client's layout file.

   For SSH handoff or reconnect changes on Linux, also run the real OpenSSH gate
   from the [SSH follow-up plan](superpowers/plans/2026-09-05-ssh-error-classification.md).
   `test/native_ssh.py` accepts the release daemon and GUI paths and uses its own
   loopback sshd, keys, state, and sessions. Verify authentication refusal on both
   restoration and reconnect, explicit Retry after correcting credentials,
   unavailable-host recovery, join-only restoration, and bounded shutdown.
7. **Refactor the integrated result.** Reserve this as work, even after the opening
   cleanup. Remove duplication, superseded paths, unnecessary state, and temporary
   scaffolding exposed by implementation. Review the result again. For retained
   debt, record location, consequence, reason, and next owner or trigger. Correctness
   failures cannot be deferred past acceptance.
8. **Freeze and run final gates.** Stop source edits before compilation. Run the
   required repository and native gates on the final result, retaining logs:

   ```sh
   export ZIG_GLOBAL_CACHE_DIR=/tmp/muxg-zig-cache
   make check
   make ci
   deps/zig/zig build native-core-test -Doptimize=ReleaseSafe
   deps/zig/zig build native native-test -Doptimize=ReleaseSafe
   make native-e2e
   make native-stress # Linux raw-output responsiveness
   ```

   `make ci` excludes native tests. Use the pinned compiler. Do not overlap
   other builds in the same checkout with its `make check` stage: `test/bans.sh`
   temporarily plants invalid source files to verify the source rules. Wait for
   that stage to finish before starting native builds or integration tests.

   The focused `make native-core-test` gate compiles workspace, runtime, picker,
   persistence and interaction without window/font libraries. `native-test`
   includes that same test artifact plus the frame/painter suite. Daemon and
   shared client work can use `make daemon-test` and `make client-test`, which
   reuse their artifacts from the aggregate unit gate. These focused commands
   complement the full delivery checks above.

   A sandbox denial is not a product failure: run required local socket/PTY checks with the appropriate
   authorized permissions. Rerun affected gates after meaningful changes; do not
   repeatedly run broad suites without a new reason.
9. **Record and serve the local demo.** Use Rig with `MUXG_VIDEODRIVER=wayland`
   and the current compositor environment. Create fixtures, focus the owned GUI,
   and drive the same user controls being delivered. Capture the actual compositor
   window continuously; on Sway, find its rectangle by PID with `swaymsg -t get_tree`
   and pipe repeated `grim -g GEOMETRY -s 1 -t ppm -` frames to ffmpeg. Encode H.264,
   `yuv420p`, even dimensions, and `+faststart`, without audio. Stop recording
   before closing the window so another application cannot enter the recording.
   A slideshow of screenshots is useful evidence but is not a screen recording.

   **Deliver a review webpage for every functional slice.** The page is the
   primary handoff link and contains:

   - The sprint goal and a concise account of what was achieved.
   - An embedded recording of the actual application, with playback controls
     and a direct video link. Include duration, recording environment and any
     restart cuts; a screenshot may serve as its preview.
   - What the user can see or try, and any controls needed to review it.
   - Validation results and open issues, clearly separating implemented,
     validated and accepted work. Preserve failed checks and material limits.
   - What belongs to the next slice and what feedback is needed on this one.

   Keep the page usable on desktop and mobile. Retain its source beside the
   sprint records and its video outside temporary fixture directories. Verify
   page loading, video metadata and seeking. Serve the page and its assets on
   localhost by default, using a loopback HTTP server with byte-range support.
   Give the user the local webpage URL, with the direct video link on the page.
   Publishing is optional and happens only when explicitly requested; do not
   ask about publishing during routine sprint delivery. Preserve unrelated services.

   Build both demo binaries together in an isolated release prefix:

   ```sh
   make install INSTDIR=dist/native-release BINDIR=dist/demo-bin
   ```

   The rebased install target builds both binaries in ReleaseSafe; the isolated
   `BINDIR` keeps demo setup out of the user’s installed executables. Pass
   `dist/native-release/bin/mux` and `dist/native-release/bin/muxg` to Rig.
   `make ci` can leave a Debug daemon in `zig-out`; `make native` builds only the
   GUI. Checking just `muxg --version` therefore cannot establish the daemon's
   build mode. Use the build graph's artifact paths for automated stress tests.

   For a close/reopen demo, stop the recorder before closing the first window and
   resume on the new owned window after launch. Join those continuous clips and
   disclose the restart cuts; do not capture the intervening desktop.

   For mouse acceptance, include the cursor with `grim -c` and drive the
   compositor's virtual-pointer motion/button events. SDL-injected input can
   validate application routing but does not demonstrate the compositor input
   path. Cursor-warp commands can move the visible cursor without delivering
   held-button motion. Verify actual divider movement and release, then check PTYs.

   Verify playback and HTTP range responses. Retain the recording outside
   temporary fixture directories and record the server's teardown command.

10. **Close honestly.** Inspect the final diff, commit validated work, and provide
    the review webpage with the demo, controls, test results, and material limits.
    User demo acceptance is
    distinct from passing automation. Record whether acceptance covers a recording
    or a hands-on trial, and capture any requested ergonomic adjustments separately.
    Update the spec/plan status and RETRO.md with resolved findings and checkable
    next-sprint actions. Mark acceptance only when given; a recorded-demo approval
    does not imply hands-on feedback. On acceptance, stop that demo's owned
    server and remaining GUI, recorder or compositor fixtures; remove any sharing
    route created at the user's request. Recheck process ownership and verify
    teardown. Preserve unrelated services and retain the page, recording and
    validation evidence. Then begin the next authorized sprint with step 1.