diff --git a/openspec/changes/add-nix-devshell/.openspec.yaml b/openspec/changes/archive/2026-08-01-add-nix-devshell/.openspec.yaml similarity index 100% rename from openspec/changes/add-nix-devshell/.openspec.yaml rename to openspec/changes/archive/2026-08-01-add-nix-devshell/.openspec.yaml diff --git a/openspec/changes/add-nix-devshell/design.md b/openspec/changes/archive/2026-08-01-add-nix-devshell/design.md similarity index 100% rename from openspec/changes/add-nix-devshell/design.md rename to openspec/changes/archive/2026-08-01-add-nix-devshell/design.md diff --git a/openspec/changes/add-nix-devshell/proposal.md b/openspec/changes/archive/2026-08-01-add-nix-devshell/proposal.md similarity index 100% rename from openspec/changes/add-nix-devshell/proposal.md rename to openspec/changes/archive/2026-08-01-add-nix-devshell/proposal.md diff --git a/openspec/changes/add-nix-devshell/specs/nix-development-environment/spec.md b/openspec/changes/archive/2026-08-01-add-nix-devshell/specs/nix-development-environment/spec.md similarity index 100% rename from openspec/changes/add-nix-devshell/specs/nix-development-environment/spec.md rename to openspec/changes/archive/2026-08-01-add-nix-devshell/specs/nix-development-environment/spec.md diff --git a/openspec/changes/add-nix-devshell/tasks.md b/openspec/changes/archive/2026-08-01-add-nix-devshell/tasks.md similarity index 100% rename from openspec/changes/add-nix-devshell/tasks.md rename to openspec/changes/archive/2026-08-01-add-nix-devshell/tasks.md diff --git a/openspec/specs/nix-development-environment/spec.md b/openspec/specs/nix-development-environment/spec.md new file mode 100644 index 0000000..99be053 --- /dev/null +++ b/openspec/specs/nix-development-environment/spec.md @@ -0,0 +1,112 @@ +# nix-development-environment Specification + +## Purpose +Define the reproducible x86_64 Linux development environment and isolated devtools preview lifecycle used to build, test, drive, and visually inspect the real GPUI application without touching user data. +## Requirements +### Requirement: Reproducible full-workspace development shell +The repository SHALL provide a pinned Nix flake development shell for x86_64 Linux containing the Rust toolchain and native dependencies required to compile, link, and test both `trawler-core` and the GPUI `trawler` application. + +#### Scenario: Clean shell builds the workspace +- **WHEN** a developer enters the shell from a clean checkout with `nix develop` +- **THEN** the Rust version matches `rust-toolchain.toml` +- **AND** `cargo check --workspace --all-targets` completes without missing native-library or pkg-config errors + +#### Scenario: Full tests link in the shell +- **WHEN** a developer runs `cargo test --workspace` inside the shell +- **THEN** the GPUI test binary links with its Linux XCB, xkbcommon, font, and graphics dependencies +- **AND** the non-ignored workspace tests execute + +### Requirement: Isolated real-application preview +The repository SHALL provide smoke and long-lived session commands that launch the real GPUI Trawler application with the `devtools` feature on a private virtual display and software Vulkan renderer without requiring an existing graphical login session. + +#### Scenario: Preview starts on a headless host +- **WHEN** the preview command runs with no pre-existing `DISPLAY` or Wayland session +- **THEN** it starts an isolated virtual display +- **AND** starts the minimal window-management support required for devtools window discovery +- **AND** launches a `--features devtools` Trawler binary with `TRAWLER_DEVTOOLS=1` +- **AND** discovers the localhost JSONL endpoint through the fixture graph's `devtools.port` + +#### Scenario: Startup failure is bounded and diagnosable +- **WHEN** the virtual display, renderer, application, or devtools endpoint fails to start +- **THEN** the command exits non-zero within a bounded timeout +- **AND** reports which stage failed and preserves or prints the relevant application log location + +### Requirement: Long-lived iterative preview session +The preview workflow SHALL support keeping one isolated application session alive across multiple agent operations until explicit stop or interruption. + +#### Scenario: Agent navigates incrementally +- **WHEN** an agent starts a serve session and sends multiple `keys`, `type`, `dump`, `bounds`, or `screenshot` requests over time +- **THEN** every request targets the same running Trawler process and fixture graph +- **AND** state from earlier requests remains visible to later requests + +#### Scenario: Session can be rediscovered +- **WHEN** a serve session is healthy and a later command runs from the repository +- **THEN** the command discovers validated session metadata including the graph, display, process, log, and devtools endpoint +- **AND** `status` reports the session as live without starting another application + +#### Scenario: Session stops explicitly +- **WHEN** the agent requests stop +- **THEN** the application, window manager, and virtual display terminate +- **AND** disposable session state and metadata are removed while requested artifacts remain + +### Requirement: Deterministic semantic and visual verification +The preview workflow SHALL drive Trawler through its existing devtools protocol and produce both machine-readable semantic state and a PNG captured by the devtools screenshot command. + +#### Scenario: Semantic state is observable +- **WHEN** the preview client sends valid `keys`, `type`, and `dump` requests +- **THEN** each request receives one valid JSON response in order +- **AND** the dump reflects the resulting fixture-graph UI state + +#### Scenario: Screenshot is previewable +- **WHEN** the preview client sends a `screenshot` request with an output path +- **THEN** the application returns a successful response +- **AND** the output is a non-empty, valid PNG containing the Trawler window + +#### Scenario: One-shot smoke uses the session lifecycle +- **WHEN** the smoke command runs +- **THEN** it starts one isolated session, executes a multi-step fixture flow, saves semantic/log/PNG artifacts, and stops through the same lifecycle controls used by serve mode + +### Requirement: Preview cannot touch the user's graph +The preview command MUST create and use a deterministic disposable fixture graph under a temporary directory it owns, and MUST NOT infer or use Trawler's default graph directory. + +#### Scenario: Preview uses disposable fixtures +- **WHEN** a preview session starts +- **THEN** it seeds a fresh graph with Trawler's fixture builder +- **AND** sets `TRAWLER_GRAPH_DIR` explicitly to that graph before application startup + +#### Scenario: Unsafe graph override is refused +- **WHEN** a requested graph path is outside the helper-owned scratch root, already exists unexpectedly, or resolves to the default graph location +- **THEN** the helper exits before launching Trawler +- **AND** does not modify that graph path + +#### Scenario: Real desktop installation remains isolated +- **WHEN** a real Linux desktop installation and an automated preview exist at the same time +- **THEN** the preview uses a different display, renderer, binary, graph directory, and process lifecycle +- **AND** it does not replace global packages or acquire the real graph's lock + +### Requirement: Preview lifecycle is self-cleaning +The preview workflow SHALL clean up application and virtual-display processes and disposable graph state after smoke completion, explicit serve stop, failure, or interruption while preserving explicitly requested output artifacts. + +#### Scenario: Successful run cleans up +- **WHEN** semantic and screenshot verification complete +- **THEN** the application, window manager, and virtual display are stopped +- **AND** the temporary fixture graph is removed +- **AND** requested dump, log, and screenshot artifacts remain available + +#### Scenario: Interrupted run cleans up +- **WHEN** preview startup or a one-shot smoke command receives an interrupt or one of its child processes exits unexpectedly +- **THEN** remaining application, window-manager, and display processes are terminated +- **AND** cleanup is safe to run more than once + +#### Scenario: Stale session is diagnosable +- **WHEN** long-lived session metadata remains after a child process exits unexpectedly or is killed externally +- **THEN** `status` reports it as stale rather than live +- **AND** a subsequent `stop` safely removes remaining owned processes and state + +### Requirement: Nix preview workflow is documented +The repository SHALL document how to enter the shell, run the full tests, use smoke and long-lived preview sessions, inspect semantic and PNG outputs, launch manually on a real Linux desktop with a scratch graph, troubleshoot native graphics startup, and clean up, while stating that Windows remains Trawler's product target and raw pointer injection is not available through devtools. + +#### Scenario: New developer follows documented path +- **WHEN** a developer follows the documentation from a clean NixOS checkout +- **THEN** every required command and expected artifact path is stated explicitly +- **AND** no step requires operating on the user's real graph or installing packages globally