# Agent debugging ## Start here Read-only live snapshot: `qs ipc -c nuguland call nuguland diagnostics`. This requires a shell instance that has loaded the new endpoint; do not restart the parent desktop to test it. The version-1 snapshot projects popup state/geometry, unnamed display geometry, and coarse Niri/audio/network/vault/Noko state. It never dumps service JSON. For reproduction, run `just ui-test`, or select `just ui-test controls`, `just ui-test popouts`, `just ui-test privilege`, or `just ui-test noko`. Selections replay checked-in synthetic scenarios, not arbitrary commands or live desktop actions. The default runs all scenarios. Read the emitted evidence directory in this order: 1. `failure.json`: original error, phase, latest safe snapshot, and capture errors. 2. `replay.json`: selected fixture and exact public rerun command. 3. `failure.png`: child-compositor screenshot when capture was possible. 4. `diagnostics.jsonl` and `refactor.log`: snapshot operation IDs and corresponding popup transitions. 5. `commands.log`, fixture/compositor logs, `versions.txt`, and `outputs.json` for complete context. Popup JSON log records use `kind: popup-transition` and events `opening`, `opened`, `switched`, and `closed`. `opening` and its deferred `opened` share an operation ID; switching and closing allocate new IDs. IDs belong to the current shell instance and wrap after 2147483647; correlate within that instance's log, not across restarts. Unknown names/statuses become `unknown`; logs omit arbitrary caller strings and close reasons. Snapshots exclude editable text. Screenshots refuse revealed nonempty auth input instead of changing the failing UI. A missing screenshot is explicit in `captureErrors`, never mistaken for a passing test. The sandbox retains failures and reaps only owned children. Native regression command: `just test vault-native`. It runs every Rust test without exclusions. ## Implementation contract - One read-only `nuguland diagnostics` IPC endpoint reports an explicitly selected, versioned snapshot. Include popup lifecycle/geometry, display geometry, and coarse service availability/state. Never include clipboard text, vault records, secrets, accounts, URLs, notification bodies, window titles, authentication prompts, or raw service JSON. - Popup operations emit JSON transition records with bounded, correlated operation IDs. Opening and its deferred completion share an ID; switching and closing identify their own operation. Logs contain only explicitly selected diagnostic fields, never caller-provided free text. - `just ui-test` supports deterministic replay of named checked-in synthetic fixtures without exposing the parent session. Invalid replay requests fail before compositor startup. - UI failures retain the original error, fixture phase, latest safe snapshot, and a screenshot when the child compositor remains available. Capture failure must not replace the original failure or skip cleanup. - Fix the Rust cache-publication test hang at its cause. Keep cancellation, atomic publication, and credential-generation assertions intact. Bound child-process/barrier waits so a regression fails instead of stalling the suite. - Use existing dependencies, service ownership, public just commands, and warning gates. Do not weaken checks, expose real credentials, alter authentication behavior, or mutate the parent desktop. ## Required verification Behavioral checks for snapshot redaction and shape, log correlation/redaction, fixture selection and failure capture, and Rust cancellation/publication. Run `just test`, `just lint`, and isolated `just ui-test`. Report static, runtime, interaction, and screenshot evidence separately. ## Verification, 2026-09-06 - Static/full lint: `just lint` passed, including all 27 native tests, all JS tests, formatting, shader checks, and the existing live IPC reachability check. Qmllint retains an unused-import informational message for `SystemPanel.qml`, not a warning. - Native tests: 27 passed in 44.93 seconds via `just test vault-native`; the final lint rerun passed them in 39.95 seconds. Repeated production-cost PBKDF2 caused the apparent hang; the shared synthetic fixture now uses the SDK-valid 5000-round minimum. Production settings and the separate production-cost password test are unchanged. Helper barriers and the isolated subprocess are bounded; cancellation/publication assertions remain. A new unreleased-helper test initially raced the production five-second timeout; it now tests helper expiry directly under its own bound. - Runtime: both synthetic QML fixtures loaded cleanly, and the actual diagnostics component returned the expected redacted schema. - Interaction: all four named fixtures and the combined run completed their assertions, including runtime operation-ID correlation. - Visual: reviewed the combined run's failure screenshot and masked-input screenshot; capture preserved the actual child screen and password masking. - Remaining blocker: `just ui-test` exits nonzero because the existing all-child diagnostic gate rejects missing private login1/locale1 services and the headless software-renderer dmabuf fallback. No diagnostic gate was disabled or weakened. Heavy concurrent host builds also caused earlier bounded startup/combined-run timeouts, retained in their own evidence directories. Final combined UI evidence: `.tmp/ui-test-XwrAw8`. Named evidence: controls `.tmp/ui-test-ZVQhLT`, popouts `.tmp/ui-test-aLyoaL`, privilege `.tmp/ui-test-aMNgIM`, noko `.tmp/ui-test-dTOtCo`. The UI command is not clean until its compositor diagnostic blocker is resolved.