This repository has been archived on 2026-10-08. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
recoll-modern/AGENTS.md
T
Lucas WintherandClaude Opus 5 def811bab4 docs: close the six open design questions for spec 001
Records the outcome of the 001 brainstorm and the Recoll spike that backed it.

Decisions: Python + FastAPI managed with uv; the product split into four specs
built in order; collections managed at runtime through the API with SQLite as
the store of record; indexing as an in-process job queue; search scope as an
explicit required parameter; results carrying metadata and snippets; real
authentication in 001 with user administration deferred to 004.

The load-bearing one is collection membership. A collection cannot be a
directory, because files sharing a directory must be able to belong to
different collections, so every document is indexed once into a single Recoll
index and membership is a user.collection extended attribute mapped to a
queryable field. Verified against Recoll 1.43.0 in a throwaway container: the
tag must be an opaque single-token ID rather than the collection name, because
Recoll tokenises the field value and matches case-insensitively, so a tag of
cook-books is also matched by collection:cook and collection:books. Names as
tags would let collections silently bleed into each other. Opaque IDs also make
renaming free, since the index is never touched.

Two operational consequences are recorded in docs/TODO.md: documents must live
on a volume with extended-attribute support, checked loudly at startup, and a
plain incremental recollindex does not notice xattr-only changes, so retagging
must go through recollindex -i on the affected file.

uv 0.12.16 was installed on this host as part of the stack decision; AGENTS.md
is corrected in the same commit, since it previously listed uv as absent.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-18 16:57:54 +02:00

84 lines
4.1 KiB
Markdown

# recoll-modern
A modern web UI and MCP server layered on Recoll full-text search: self-hosted via Docker, managing
several independent collections (e.g. `techbooks`, `cookbooks`).
**Status: greenfield.** No application code and no stack chosen yet. The first non-trivial task is a
spec, not code — see Workflow.
`AGENTS.md` is the single source of truth for agents here. `CLAUDE.md` and `GEMINI.md` only point here.
On demand: `docs/ARCHITECTURE.md`, `docs/DECISIONS.md`, `docs/TODO.md`, `PRODUCT.md`.
## Commands
TODO(maintainer): no stack yet. Fill install/dev/test/single-test/lint/typecheck/build in the same
commit that scaffolds the app, and delete this line. These must be what CI runs.
Installed on this host: `docker` 29.5.2 with `docker compose`, `node` 20.19.2, `npm` 9.2.0, `bun` 1.3.14,
`yarn` 1.22.22, `python3` 3.13.5, `uv` 0.12.16 (in `~/.local/bin`, already on `PATH`), `dotnet` 10.0.302.
**Absent: `pnpm`, `poetry`, `go`, `cargo`** — do not write commands that assume them.
`uv` is the package manager for this project; do not use bare `pip`, `venv`, or `poetry`.
## Rules
- `recoll`, `recollindex`, and `recollq` are **not installed on this host** — they exist only inside the
container. Never invoke them directly; go through the container. Tests needing them must skip when it
is down, not fail.
- The remote is **Gitea** (`gitea.lucaswinther.info`), not GitHub. `gh` does not work here — no
`gh pr create`, no `gh issue`. Use `git` plus the Gitea web UI.
- Indexed documents and Recoll config directories are user data: never committed, never deleted to
"reset" state.
## Workflow
Required skills: `superpowers`, `impeccable`. Installed per-machine, never committed — check at session
start, install if missing:
`/plugin marketplace add obra/superpowers-marketplace` then `/plugin install superpowers@superpowers-marketplace`
`npx impeccable install`
Specs -> `docs/specs/NNN-slug.md`. Plans -> `docs/plans/NNN-slug.md`, numbered to match its spec.
**This overrides the superpowers defaults** (`docs/superpowers/specs/`, `docs/superpowers/plans/`,
date-named). Without this line, artefacts scatter into a second tree.
Anything beyond a trivial fix: brainstorm -> spec (sign-off) -> plan (sign-off) -> TDD -> review.
TDD means failing test first, watch it fail, minimal code, watch it pass, commit.
Tick plan checkboxes as you go so an interrupted session is resumable.
Trivial changes (typo, version bump, one-line config): say "trivial, skipping spec" and proceed.
Use `impeccable` for user-facing UI — `shape` before building, `audit`/`polish` on existing, `harden`
before shipping. Product context: `PRODUCT.md` (a stub: run `/impeccable init` before the first UI work).
There is no `DESIGN.md` yet; the first UI build writes one, and after that never hand-roll around its tokens.
## Architecture
Nothing is built yet. `docs/ARCHITECTURE.md` holds the intended shape and the six open design questions
the first spec must close — read it before proposing any structure.
## Boundaries
Branch before touching `main`; it currently has no history beyond the bootstrap commit.
Ask first: choosing or changing the stack · new runtime dependencies · schema or public API changes ·
auth and how the service is exposed · deleting or rebuilding a Recoll index · work the approved plan
does not cover.
If the task turns out much larger than the plan assumed: stop, report, re-plan.
## Docs duties
Same commit as the code, not "later":
- `docs/ARCHITECTURE.md` — when a module, boundary, or data flow changes.
- `docs/DECISIONS.md` — append-only; any choice a future maintainer would reverse-engineer.
- `docs/TODO.md` — anything noticed and deliberately not fixed. No `TODO` comments in source.
## Git
Branches: `feat|fix|chore/<slug>`. Commits: Conventional Commits. There was no history before the
bootstrap commit, so this line *is* the convention.
## Done means verified
Do not report success on work you have not run. Before saying done: tests run *in this session* and seen
passing · lint and typecheck clean · matches the approved spec · docs duties complete · `git status`
clean and the diff is only what you intended. "It should work" is not verification.