From 9981645f4e6e1c135bf67a8858ed49ce218feb60 Mon Sep 17 00:00:00 2001 From: Lucas Winther Date: Fri, 18 Sep 2026 17:37:17 +0200 Subject: [PATCH] docs: preserve desktop packaging seam --- PRODUCT.md | 2 ++ docs/ARCHITECTURE.md | 13 ++++++++++++- docs/DECISIONS.md | 19 +++++++++++++++++++ docs/TODO.md | 3 +++ docs/specs/001-search-engine-api.md | 15 +++++++++++++-- 5 files changed, 49 insertions(+), 3 deletions(-) diff --git a/PRODUCT.md b/PRODUCT.md index 5951673..3681287 100644 --- a/PRODUCT.md +++ b/PRODUCT.md @@ -39,6 +39,8 @@ interface and an MCP server, so the same index is usable by a person in a browse - Deployed with Docker on a server; used through a browser. - Collections map to bodies of documents the user keeps, named by subject. - A second consumer is an MCP client (an AI agent), searching the same collections programmatically. +- After the hosted product through spec 004 is delivered, a cross-platform installable desktop form is + a product goal. It should reuse the web UI and API rather than create a second product surface. ## Capabilities and Constraints diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index 938c808..b7ac794 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -24,7 +24,8 @@ No source directories exist yet. Add rows here as they appear. ## Delivery order -The product is four specs, built in order. Each gets its own spec, plan and review cycle. +The product is five specs, built in order. Each gets its own spec, plan and review cycle. Spec 005 is a +future distribution track and starts only after the hosted product through 004 is delivered. | Spec | Scope | |---|---| @@ -32,6 +33,7 @@ The product is four specs, built in order. Each gets its own spec, plan and revi | 002 Web UI | Blocked on `/impeccable init` replacing the `PRODUCT.md` stub, then `DESIGN.md` | | 003 MCP server | Thin wrapper over 001's HTTP API | | 004 Multi-user management | Roles, user CRUD, per-collection permissions | +| 005 Cross-platform desktop distribution | Installable shell reusing the web UI and launching the API plus Recoll as bundled sidecars | ## Intended shape @@ -42,6 +44,9 @@ The product is four specs, built in order. Each gets its own spec, plan and revi - SQLite holds collections, membership, indexing jobs, users and sessions. - An HTTP API consumed by both the web UI and the MCP server, so the two never diverge. - A Docker image containing Recoll itself, plus compose wiring for document volumes and index storage. +- A packaging seam for a future desktop shell: application logic does not depend on Docker, state paths + and listen addresses are configurable, process startup/shutdown is explicit, and every UI operation + crosses the same HTTP API. Docker remains the only supported distribution through spec 004. ### Component boundaries @@ -136,6 +141,12 @@ draft until maintainer sign-off. | Document volumes | Nothing to index; collections resolve to empty. | | A writable volume for the index and SQLite | All state. The document volume itself may be mounted read-only. | +Docker is the only supported deployment for specs 001–004, not a permanent application-layer +dependency. Spec 005 will design cross-platform packaging of the web UI, API service, Recoll and its +document filters. A Tauri-style shell with bundled sidecars is the intended approach; choosing Tauri +itself and resolving per-platform Recoll licensing, signing, updates and filter coverage are decisions +for that spec. + ## Invariants - A query never silently spans collections: the scope is an explicit, required parameter, and the API diff --git a/docs/DECISIONS.md b/docs/DECISIONS.md index 0c2ab3c..8fe4c0a 100644 --- a/docs/DECISIONS.md +++ b/docs/DECISIONS.md @@ -3,6 +3,25 @@ Append-only, newest first. Never edit or delete an entry — supersede it with a new one that links back. One entry per decision a future maintainer would otherwise have to reverse-engineer. +## 2026-09-18 — Cross-platform desktop packaging is spec 005 +**Status:** accepted +**Supersedes:** "The product is four specs, built in order" (below, same date), only by appending a fifth +delivery after 004; the original order and boundaries of specs 001–004 remain unchanged. +**Context:** the hosted Docker service should eventually also be usable as a self-contained installable +application on Linux, macOS and Windows, without distracting from delivery of the core product. +**Decision:** desktop distribution is spec 005 and starts only after 004. Its intended architecture is a +Tauri-style shell that reuses the web UI and launches the existing HTTP API plus Recoll as bundled local +sidecars. Tauri is the leading candidate, not a selected dependency; that choice belongs to 005. +**Alternatives:** call backend libraries directly from a native shell (creates a second integration +path); hide Docker behind a launcher (still requires a container runtime and integrates poorly with the +desktop filesystem). +**Consequences:** specs 001–004 stay Docker-first, but application logic cannot depend on Docker. State +paths and listen addresses are configurable, lifecycle is explicit, and UI behavior crosses the HTTP +API. Spec 005 must resolve per-platform Recoll packaging and licensing, filters, loopback security, +signing, updates and installer formats before adding dependencies. + +--- + ## 2026-09-18 — Deployment supports a configured URL subpath **Status:** accepted **Context:** the service may sit behind an existing reverse proxy under a path such as `/recoll`, not at diff --git a/docs/TODO.md b/docs/TODO.md index f2a20b9..18a6aae 100644 --- a/docs/TODO.md +++ b/docs/TODO.md @@ -60,6 +60,9 @@ Things a resuming agent will otherwise get wrong: brief, not an interview. Blocks spec 002. ## Someday +- [ ] After delivery 004, write spec 005 for a cross-platform installable desktop distribution. Start + from a Tauri-style shell that reuses the web UI and bundles the API and Recoll as sidecars; decide + the actual framework, licensing, signing, updates and per-platform filter coverage in that spec. - [ ] Propose a CI check (Gitea Actions): assert `AGENTS.md`, `CLAUDE.md`, `GEMINI.md` and the `docs/` paths exist, and fail if `AGENTS.md` exceeds 150 lines. diff --git a/docs/specs/001-search-engine-api.md b/docs/specs/001-search-engine-api.md index b8eb29e..ac2f8bf 100644 --- a/docs/specs/001-search-engine-api.md +++ b/docs/specs/001-search-engine-api.md @@ -6,7 +6,7 @@ supersedes: none # 001 — Search engine and HTTP API -The first of four specs (see `docs/ARCHITECTURE.md`, "Delivery order"). It delivers the Recoll layer and +The first of five specs (see `docs/ARCHITECTURE.md`, "Delivery order"). It delivers the Recoll layer and the HTTP API that specs 002 (web UI) and 003 (MCP server) are both built against. It ships no UI. ## Why @@ -25,7 +25,8 @@ text and original-file retrieval · authentication · a read-only file browse en subpath hosting · health. **Out, deferred to a named spec:** the web UI (002) · the MCP server (003) · user administration, roles -and per-collection permissions (004) · real-time index monitoring · OIDC or forward-auth. +and per-collection permissions (004) · a cross-platform installable desktop distribution (005, after +004) · real-time index monitoring · OIDC or forward-auth. ## Constraints @@ -135,6 +136,9 @@ and are recorded in `docs/ARCHITECTURE.md` under "Verified Recoll mechanics"; th explicitly configured proxies. - **R30.** Errors use one envelope, `{"error": {"code", "message", "details"}}`, with the codes in the table below. +- **R31.** Docker is packaging, not an application-layer dependency. Document, index, database and + membership-map paths plus listen host, port and mount prefix are configuration. Application modules + never invoke Docker, and shutdown leaves durable jobs recoverable on the next start. | Code | Status | |---|---| @@ -164,6 +168,11 @@ changes desired state. It then atomically replaces the flat membership map and a force-reindex affected canonical paths. An engine failure leaves desired state intact; retrying export and indexing is idempotent. +Docker is the delivery target for 001, but not an application-layer dependency: state paths and listen +addresses are configurable, lifecycle is explicit, and the future web UI communicates only through the +HTTP API. These seams allow spec 005 to package the unchanged UI with the API and Recoll as local +sidecars; 001 does not select or build a desktop framework. + ## SQLite schema SQLite foreign keys are enabled. Timestamps are UTC. Collection and username comparison keys are @@ -302,6 +311,8 @@ exists. Unexpected errors return a request ID rather than exception text or file - [ ] The service refuses to start with no user and no seeded credentials (R26). - [ ] Hosting under `/recoll` produces working routes, cookies, OpenAPI and document links, while untrusted forwarded-prefix headers are ignored (R29). +- [ ] The service uses non-default state paths and listen settings without code changes, contains no + runtime Docker invocation, and recovers durable work after a cleanly handled shutdown (R31). - [ ] `uv run pytest`, `uv run ruff check .` and `uv run mypy src` pass, and the suite skips rather than fails with the container down.