--- name: xmm-workstation description: >- Use when configuring, implementing, debugging, porting, or reviewing XMM or its compile-time workstation policy. Distinguish a local config.h edit from a new product capability, then rebuild and prove the real path. Do not use for specification-only authoring, planning, orientation, or unrelated host dotfiles. --- # XMM workstation ## One job Make one XMM workstation behavior work through the smallest owning surface: existing typed `config.h` policy when possible, or one requirement-bound C11 product slice when the capability does not exist. ## Choose the owner Read `AGENTS.md`, the applicable `SPEC.md` records, and `config.def.h` or the owning production module. - **Local configuration:** when the request changes only monitor profiles, wallpaper paths, commands, lock client, bindings, colors, inputs, app-id rules, or other already-supported policy, inspect the real host and edit only ignored `config.h`. Copy `config.def.h` first only when `config.h` is absent. Do not change requirements or tracked defaults. - **Default policy:** when the user explicitly changes shipped defaults, revise the specification first, then `config.def.h`, proof, and orientation as applicable. - **Capability:** when typed configuration cannot express the requested behavior, revise or obtain specification authority before changing C11 code or protocols. For local setup, inspect only evidence relevant to requested policy: connected output connector/EDID/modes, current compositor config, XKB settings, input capabilities, available command executables, lock client/authentication stack, audio control plane, and wallpaper files. Translate observed choices into XMM's typed tables in `config.h`; output profile and wallpaper selector/planning contracts are owned by `src/output.h` and their implementation by `src/output.c`; direct libseat/DRM ownership, EDID identity, logical-to-physical projection, physical wallpaper composition, atomic output state, bounded DRM hotplug intake/transaction rollback, and page-flip cleanup are owned by `src/direct.c`; `src/xmm.c` owns the single event-loop frame clock that coalesces damage behind one pending flip per output, while `src/render.c` must submit through implicit fences without waiting for GPU completion on that loop; direct libinput discovery, XKB compilation, typed device policy, and event normalization are owned by `src/input.c`; `src/diagnostic_log.c` owns the nonblocking stderr mirror and bounded XDG state log; `src/scheduling.c` owns minimum-`SCHED_RR` compositor elevation plus fail-closed child reset, while the installed direct binary's `cap_sys_nice=ep` is host policy; `src/render.c` owns the fixed EGL/GLESv2 composition path, nested EGL target, and modifier-aware multi-plane DMA-BUF EGLImage import; `src/dmabuf.c` owns the bounded linux-dmabuf v5 global, feedback, parameter validation, wl_buffer lifetime, and release handoff; `src/presentation.c` owns presentation-time feedback lifetime while `src/direct.c` supplies page-flip timestamps and refresh and `src/xmm.c` binds each presented surface commit to that observation; `src/scaling.c` owns viewporter and fractional-scale protocol resources and committed viewport state while `src/xmm.c` supplies per-surface preferred output scale and scene wiring; `src/xmm.c` owns `wl_output`/`wl_seat` publication, per-output rule/cache selection, and compositor-layer coverage; `src/desktop.c` owns stable output/workspace assignment, neighbor selection, visible-workspace swaps, and removed-output client migration. Do not assume the current host, package set, paths, keymap, commands, or monitor identities are product defaults. Convert a selected wallpaper once to bounded P6 outside the repository; never add PNG decoding or a converter to runtime. Translate Kanshi profiles to ordered selector/action rows using scale units of 1/120; preserve exact values such as Kanshi `1.9` as `228`, and reject `exec` hooks rather than hiding them in profile policy. Configure an audio or lock tool as direct argv only after discovering it and obtaining the user's choice. Preserve local `config.h` across tracked default updates and report any newly required decision instead of guessing it. Do not create a runtime config parser, migration layer, alias language, IPC, reload watcher, shell-string command format, or another configuration file. ## Product slice For a capability change, name the requirement, user-visible observation, real entry point, and external boundary. Trace pinned public XML when protocol order, lifetime, coordinates, or errors matter. Keep pinned source/data mechanisms (currently Spleen glyphs and the minimal libgrapheme UAX #29 implementation/tables) at their owning local seam with URL, revision/version, checksum, license, and modifications; do not replace them with ambient host font or locale behavior. Keep reusable server-global state machines such as activation, core data devices, and trusted same-session ext-data-control clipboard access in their dedicated `src/` modules, with seat/focus/surface policy supplied by the compositor owner in `src/xmm.c`. Pinned xdg-shell and xdg-decoration XML, scanner generation, and decoration negotiation remain one protocol slice; server-side mode suppresses client titlebars and must not grow a drawn decoration framework. Write the smallest failure/success assertion, then implement the cohesive C11 path with validation, checked arithmetic, bounded ownership, diagnostics, rollback, and cleanup at its owner. Do not introduce C++, Zig, a framework abstraction, helper daemon, callback registry, or test-only copy of production logic. ## Proof Use production objects, explicit clocks/seeds/events and failpoints, isolated runtime paths, and minimized fuzz regressions. Run the narrow proof, then `make test`; use `make check` when nested, sanitizer, hardware, portal, audio, output, or compatibility behavior is touched. For local configuration, validate every referenced path/argv and compile it, then exercise the affected profile/binding/wallpaper journey on the real target. Never substitute sleeps, blind retries, ambient config, mock-only platform claims, or line coverage for observable proof. The current `make check` nested journeys require a running Sway host plus `swaymsg`, `grim`, `jq`, `xkbcli`, and virtual-keyboard and virtual-pointer support; they also rebuild and repeat under ASan/UBSan. Load-qualified direct input additionally requires the final `xmm` executable to expose `cap_sys_nice=ep`; verify XMM is minimum `SCHED_RR` and its children are `SCHED_OTHER` before saturating normal-priority workers. Direct frame-stage diagnostics are compile-time-only: rebuild with `-DXMM_PERF_TRACE` when a live timing journey needs input, spawn/surface-map, client SHM copy, latch, upload, KMS-submit, and page-flip timestamps; summarize stderr with `tools/xmm-perf-report.sh `. A trace build also accepts `SIGUSR1` to capture the current direct composed frame as P6 at `XMM_CAPTURE_PPM` (default `/tmp/xmm-capture.ppm`); inspect that artifact with `tests/ppm_check` or `see` instead of inferring rendered pixels from protocol logs. For load-sensitive input work, retain an exact short-tap press/release regression, saturate only normal-priority workers, and prove the current direct target has no event-loop GPU wait before restoring a normal build for delivery. Inspect generated files, dependencies, `git diff --check`, Redgate impact, and repository status before handoff. Update this skill only when the ownership decision, configuration mechanism, implementation loop, or test gates change; never copy product semantics into it. ## Handoff Report `owner: local config | shipped default | capability`, specification impact, changed anchors, tests and live journeys, and remaining target-specific risk. If the real boundary is unavailable, name the blocked proof rather than claiming support.