# ask-gpt isolated X display startup

audience: AI coding agents first.

Status: DONE
Priority: FIRE
Task IDs: #21
Source request: Owner says current blocker: `ask-gpt` cannot start Xvfb. Exact error: `Failed to find a socket to listen on.` Create durable emergency execution contract only; preserve all current registry, WIP, and queue state. NEVER invoke registry bootstrap.

## Outcome

Installed `/home/user/.local/bin/ask-gpt` reliably starts an isolated X display and completes authenticated browser work.

## Acceptance criteria

- Before mutation, capture exact installed command, environment, socket, lock, and process ownership.
- Distinguish with evidence: stale socket/lock; tmp-jail-unusable `/tmp/.X11-unix`; allocation race; permissions; display exhaustion.
- Restore runtime first through smallest safe seam.
- Mutate exact owned display resources only. NEVER broad-kill processes or broadly delete sockets, locks, or temp paths.
- Add deterministic regression for evidenced failure seam.
- Prove real installed authenticated browser work through `/home/user/.local/bin/ask-gpt`.
- Run focused and full gptbridge verification cleanly.
- Commit, land, deploy, reinstall, then repeat installed authenticated proof from canonical landed source.
- Preserve task registry, incident WIP, branch/ref state, and land queue.
- NEVER invoke registry bootstrap.

## Preserved WIP

- Incident branch/worktree: `wt/ask-gpt-drawer-fix-final`.
- Deploy source: `/home/user/.local/share/overdeck/deploy/modules/gptbridge`.
- Installed entrypoint: `/home/user/.local/bin/ask-gpt`.
- Preserve existing registry, WIP, refs, processes, sockets, locks, and queue until exact ownership is proven.

## Constraints

- Runtime-first emergency order: capture → bounded repro → smallest seam test → atomic install/rollback → installed proof → full verification → canonical land/deploy/reinstall/reproof.
- Never infer stale ownership from filename, PID text, age, or error alone. Correlate process identity, UID, namespace/tmp-jail view, open descriptors, and socket/lock state.
- Never kill by name, display range, or broad process match.
- Never delete `/tmp/.X11-unix`, wildcard X sockets, wildcard X locks, or resources not proven owned by this invocation.
- Never weaken display isolation, account binding, authenticated-browser controls, or fail-closed startup.
- Edit implementation/tests only after pre-mutation capture identifies exact failure seam.
- NEVER invoke registry bootstrap.
- Main Claude owns review, tests, landing, deployment, and receipts. Subagents are bounded workers only; no worker may spawn or orchestrate another agent. Owner correction: `you complete it now yourself. i am tired of overdelegatin`.

```text
DO NOT: broad-kill Xvfb; delete /tmp/.X11-unix; remove /tmp/.X*-lock by wildcard; retry random displays.
TARGET: capture exact ownership → classify failure → repair one owned seam → installed authenticated proof.
```

## Execution steps

1. Capture installed command/argv, inherited environment, tmp-jail namespace/view, effective UID/GID, candidate display allocation, Xvfb process tree, `/tmp/.X11-unix` metadata, candidate socket, candidate lock, lock PID identity, and open-descriptor ownership. Make no mutation.
2. Reproduce once through installed `/home/user/.local/bin/ask-gpt` with bounded logs and preserve exact error/timestamps.
3. Classify failure as stale socket/lock, unusable tmp-jail socket directory, allocation race, permissions, exhaustion, or another evidenced class. Do not conflate classes.
4. Add deterministic regression at smallest evidenced allocation/startup seam.
5. Build isolated candidate from preserved incident WIP; retain atomic rollback.
6. Install candidate into exact runtime path before Git. Remove or stop only resources proven owned by failed candidate invocation.
7. Invoke real installed entrypoint and prove authenticated browser completion on isolated display.
8. Run focused display-startup tests, then full `python3 -m pytest modules/gptbridge/tests/ -q`; resolve every warning/error.
9. Commit terse task-only delta. Land through canonical controller without disturbing queue/WIP; deploy from landed source; reinstall runtime.
10. Repeat installed authenticated proof; record command, display, ownership, result, landed SHA, deploy SHA, and rollback artifact.

## Current receipt

Task #21 implementation is installed, landed, deployed, reinstalled, and live-proven. Root cause: Claude tmp jail made Xvfb's hardcoded `/tmp` resources unusable; trusted browser launchers now relaunch outside that jail. Initial landed helper was functionally proven but automated review correctly flagged an over-broad command/environment boundary; follow-up hardening now allowlists only `ask-gpt` and `solwebd`, uses absolute Python/systemd paths, `execve`, fixed PATH, and a minimal environment allowlist. `sandbox.py` remains unchanged. Main-thread focused hardening tests: 51 passed. Full suite with isolated HOME: 277 passed, 7 skipped in 48.88 seconds. Installed landed proof from the real agent jail recovered exactly 1/1 valid nonempty ZIP in 26 seconds with zero failures/unavailable/invalid and zero `.part`; output `/home/user/.overdeck/verification/xvfb-landed-1786502788/overdeck-k3s-phase2-run-bundle(1).zip`. Installed runtime is final hardened source from commit `6e5570fc0`, which remains an ancestor of current `origin/main` `1057833a7`. Installed `/home/user/.local/bin/ask-gpt` resolves to that worktree source. Final deployment could not refresh the standalone deploy clone because another session left `modules/workstation/claude/build-remote.json` dirty; fail-closed deploy correctly preserved it. This does not block owner use: installed runtime was separately installed and agent-jail browser/authentication proof succeeded. No unrelated WIP was modified.

## Next executable action

Resolve concrete independent-review findings, commit candidate, land/deploy/reinstall, then repeat fresh jailed authenticated proof from landed source. Main-thread review found no blocking defect. Main-thread full suite: 272 passed, 1 skipped in 40.69 seconds; inner test command clean, outer exit 1 only from harness `/tmp/claude-*-cwd` bookkeeping denial after test completion.
