commit 895eabcb6961380c99f1de8c8f0f42964d7fba78 Author: Lucas Winther Date: Fri Sep 18 16:41:56 2026 +0200 chore: bootstrap agent-ready docs and rules Empty repository: no commits, no stack. Establishes AGENTS.md as the single source of truth, thin CLAUDE.md/GEMINI.md pointers, permission config, and the docs/ progressive-disclosure tree. Commands section is deliberately unfilled — no stack exists to verify commands against. Co-Authored-By: Claude Opus 5 (1M context) diff --git a/.claude/settings.json b/.claude/settings.json new file mode 100644 index 0000000..40f9fb9 --- /dev/null +++ b/.claude/settings.json @@ -0,0 +1,33 @@ +{ + "$schema": "https://json.schemastore.org/claude-code-settings.json", + "permissions": { + "allow": [ + "Bash(git status:*)", + "Bash(git diff:*)", + "Bash(git log:*)", + "Bash(git show:*)", + "Bash(git branch:*)", + "Bash(ls:*)", + "Bash(cat:*)", + "Bash(head:*)", + "Bash(tail:*)", + "Bash(grep:*)", + "Bash(rg:*)", + "Bash(find:*)", + "Bash(wc:*)", + "Bash(docker compose ps:*)", + "Bash(docker compose logs:*)", + "Bash(docker compose config:*)", + "Read(//home/user/recoll-modern/**)" + ], + "deny": [ + "Bash(rm -rf:*)", + "Bash(git push --force:*)", + "Bash(git push -f:*)", + "Bash(git reset --hard:*)", + "Bash(docker compose down -v:*)", + "Read(./.env)", + "Read(./.env.*)" + ] + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..736480d --- /dev/null +++ b/.gitignore @@ -0,0 +1,16 @@ +# Secrets +.env +.env.* +!.env.example + +# Agent scratch / local overrides +CLAUDE.local.md +.claude/settings.local.json +.impeccable/ +.worktrees/ + +# IDE +.idea/ + +# OS +.DS_Store diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..d8433d6 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,82 @@ +# 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, `dotnet` 10.0.302. +**Absent: `pnpm`, `uv`, `poetry`, `go`, `cargo`** — do not write commands that assume them. + +## 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/`. 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. diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..61b0784 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,9 @@ +# CLAUDE.md + +**`AGENTS.md` is the single source of truth for this repository.** Read it now and follow it exactly. + +@AGENTS.md + +This file exists only so Claude Code finds the rules, and for Claude-specific configuration that +`AGENTS.md` cannot express. It contains no project rules of its own — add those to `AGENTS.md`. +If anything here ever conflicts with `AGENTS.md`, `AGENTS.md` wins. diff --git a/GEMINI.md b/GEMINI.md new file mode 100644 index 0000000..d459430 --- /dev/null +++ b/GEMINI.md @@ -0,0 +1,8 @@ +# GEMINI.md + +**`AGENTS.md` is the single source of truth for this repository.** Read `./AGENTS.md` before doing +anything else, and follow it exactly. + +This file exists only so Gemini CLI finds the rules. Gemini CLI reads `AGENTS.md` natively, so this is +belt-and-braces. It contains no project rules of its own — add those to `AGENTS.md`. +If anything here ever conflicts with `AGENTS.md`, `AGENTS.md` wins. diff --git a/PRODUCT.md b/PRODUCT.md new file mode 100644 index 0000000..54081ff --- /dev/null +++ b/PRODUCT.md @@ -0,0 +1,66 @@ +# Product + + + +> **Stub, not an interview.** Every fact below is taken verbatim from the project brief that opened this +> repository, or marked as undecided. Nothing here was confirmed in an `/impeccable init` interview. +> Run `/impeccable init` before the first UI work and let it replace this file. + +## Platform + +web + +## Stack + +Undecided. Greenfield: no framework, no scaffold. The stack is a user decision and has not been made. +See `AGENTS.md` for the toolchains actually installed on the host. + +## Users + +Undecided — not yet interviewed. From the brief, the product is self-hosted on a server the user +controls, which implies a technical operator running it for themselves or a small group. Confirm before +designing around it. + +## Product Purpose + +A layer on top of Recoll, a Linux desktop full-text search and indexing tool. It exists to give Recoll +a modern, sleek interface, to run as a hosted service rather than a desktop app, and to hold several +independent document collections at once (stated examples: `techbooks`, `cookbooks`). + +## Positioning + +Recoll's own interfaces are a desktop GUI and a basic bundled web UI, both single-index and +single-machine. This product's stated difference is a hosted, multi-collection service with a modern +interface and an MCP server, so the same index is usable by a person in a browser and by an AI agent. + +## Operating Context + +- 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. + +## Capabilities and Constraints + +Confirmed from the brief: +- Full-text search and indexing, provided by Recoll. +- Multiple named collections, managed independently. +- Web UI, served from a Docker deployment. +- MCP server exposing the same search capability. + +Explicitly undecided: authentication, cross-collection search, indexing schedule, result preview depth, +supported document types beyond Recoll's own. See `docs/ARCHITECTURE.md` for the full list. + +## Brand Commitments + +Working name: `recoll-modern`. No logo, palette, typography, or voice has been established. +"Modern and sleek" is the only stated aesthetic constraint — recorded as-is, not expanded. + +## Evidence on Hand + +None. No screenshots, copy, sample collections, user research, or existing interface exist in this +repository. Future work must not fabricate any. + +## Product Principles + +Undecided — these are derived from a confirmed interview, which has not happened. Leaving this section +empty is deliberate; do not invent principles to fill it. diff --git a/README.md b/README.md new file mode 100644 index 0000000..1df2ccb --- /dev/null +++ b/README.md @@ -0,0 +1,9 @@ +# recoll-modern + +A modern, self-hosted web UI and MCP server on top of [Recoll](https://www.lesbonscomptes.com/recoll/) +full-text search, with support for multiple independent collections. + +Status: greenfield — no application code yet. + +Working here (human or agent): read [`AGENTS.md`](AGENTS.md). It is the single source of truth for +commands, workflow, and boundaries. Deeper context lives in [`docs/`](docs/). diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md new file mode 100644 index 0000000..4b88116 --- /dev/null +++ b/docs/ARCHITECTURE.md @@ -0,0 +1,64 @@ +# Architecture + +How `recoll-modern` is built today. Update in the same commit as any structural change. + +## Overview + +**Nothing is built yet.** This file currently records intent and the open questions that the first +spec must close. Do not read anything below "Intended shape" as describing existing code. + +The goal: a self-hosted service that wraps Recoll's indexing and full-text search behind (a) a modern +web UI and (b) an MCP server, running in Docker, with several independent collections such as +`techbooks` and `cookbooks`. + +## Map + +| Path | Responsibility | +|---|---| +| `AGENTS.md` | Agent rules; single source of truth | +| `PRODUCT.md` | Durable product context for the `impeccable` skill | +| `docs/specs/`, `docs/plans/` | Approved specs and implementation plans | + +No source directories exist yet. Add rows here as they appear. + +## Intended shape + +Not yet decided or validated. The pieces the spec has to place: + +- A Recoll layer that owns indexing and querying, per collection. +- An HTTP API consumed by both the web UI and the MCP server, so the two never diverge. +- An MCP server exposing search (and likely collection listing) as tools. +- A Docker image that contains Recoll itself, plus compose wiring for document volumes and index storage. + +## Open design questions + +The first spec must answer these. None are settled. + +1. **Collection isolation.** Recoll's model is a config directory per index (`RECOLL_CONFDIR`). + Confirm against Recoll's own docs, then decide: one config dir per collection, and what owns the + mapping from collection name to config dir and document root. +2. **Cross-collection search.** Allowed at all? If yes, merged ranking across separately-scored indexes + is not free — decide before building the UI around it. +3. **Indexing trigger.** Cron inside the container, Recoll's real-time monitor, or API-triggered runs. + Affects whether the container needs a long-running process beyond the web server. +4. **Stack.** Unchosen. See `AGENTS.md` Commands for what this host actually has installed. +5. **Auth and exposure.** Whether the service authenticates at all, or assumes a reverse proxy does it. +6. **Result presentation.** Recoll returns snippets and can extract/preview documents; decide how much + of that the API surfaces, since it drives both the UI and the MCP tool shape. + +## External dependencies + +| Dependency | What breaks without it | +|---|---| +| Recoll (in-container) | All indexing and search. Not installed on the host — see `AGENTS.md` Rules. | +| Docker + compose | The only supported way to run the service. | +| Document volumes | Nothing to index; collections resolve to empty. | + +## Invariants + +To be established with the first code. Candidates the spec should confirm and then record here: +a query never silently spans collections; indexed content is never written into the repository. + +## Known rough edges + +None yet — nothing has been built. Cross-linked backlog: `docs/TODO.md`. diff --git a/docs/DECISIONS.md b/docs/DECISIONS.md new file mode 100644 index 0000000..cefdd71 --- /dev/null +++ b/docs/DECISIONS.md @@ -0,0 +1,41 @@ +# Decisions + +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 — Override the superpowers artefact paths +**Status:** accepted +**Context:** superpowers 6.3.0 writes specs to `docs/superpowers/specs/YYYY-MM-DD--design.md` +and plans to `docs/superpowers/plans/YYYY-MM-DD-.md` (verified in the installed skill files). +That nests a second docs tree and dates artefacts that we want numbered and paired. +**Decision:** specs -> `docs/specs/NNN-slug.md`, plans -> `docs/plans/NNN-slug.md`, plan number matching +its spec number. Recorded in `AGENTS.md` so every session picks it up. +**Alternatives:** accept the defaults (two docs trees, no spec/plan pairing); symlink (fragile on Windows +and in containers). +**Consequences:** the override must be restated if `AGENTS.md` is ever trimmed; a superpowers upgrade +that changes its defaults needs this entry re-checked. + +--- + +## 2026-09-18 — Adopt AGENTS.md as single source of truth +**Status:** accepted +**Context:** The repository was empty — no commits, no stack, no agent context. Agents had nothing +durable to read and would re-explore from scratch every session. +**Decision:** `AGENTS.md` is canonical; `CLAUDE.md` and `GEMINI.md` are thin pointers with no rules of +their own. Enforceable things live in `.claude/settings.json` and `.gitignore` rather than in prose. +**Alternatives:** per-tool rule files (drift and synchronisation debt); no rules file (measurably more +steps and tokens per task). +**Consequences:** rule changes happen in one file; the pointer files must stay thin; `AGENTS.md` is an +executable-context and prompt-injection surface, so changes to it get reviewed like CI config. + +--- + +## 2026-09-18 — No DESIGN.md until the first UI exists +**Status:** accepted +**Context:** The `impeccable` skill reads `PRODUCT.md` and `DESIGN.md`. `PRODUCT.md` could be written +from the stated product intent; `DESIGN.md` could not — there is no UI, no tokens, no visual world. +**Decision:** write `PRODUCT.md` now; leave `DESIGN.md` absent. The first UI build produces it +(`/impeccable document` derives it from shipped code). +**Alternatives:** a placeholder `DESIGN.md` — rejected, it would assert a visual system that does not +exist and the skill would design against fiction. +**Consequences:** the first UI task must end by writing `DESIGN.md`, not skip it. diff --git a/docs/TODO.md b/docs/TODO.md new file mode 100644 index 0000000..8476ec3 --- /dev/null +++ b/docs/TODO.md @@ -0,0 +1,30 @@ +# TODO + +Durable backlog. Agents append here instead of leaving `TODO` comments in source. +Small, specific, independently actionable. Remove only when actually done. + +## Now +- [ ] Answer the open questions in the bootstrap report, then fill the `Commands` section of `AGENTS.md` + and delete its `TODO(maintainer)` line. +- [ ] Brainstorm -> spec `docs/specs/001-*.md` covering the open design questions in + `docs/ARCHITECTURE.md`, starting with collection isolation and the stack choice. + +## Next +- [ ] Scaffold the chosen stack; verify install/dev/test/lint/typecheck/build commands by running them, + then record the verified ones in `AGENTS.md`. +- [ ] Dockerfile + compose: Recoll in the image, volumes for documents and indexes. +- [ ] Write `PRODUCT.md` properly via `/impeccable init` — the current file is a stub from the initial + brief, not an interview. + +## Someday +- [ ] 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. + +## Known issues +- None recorded yet. + +## Recurring +- [ ] Add an `AGENTS.md` rule only in response to a real, observed agent failure — one line, ideally with + a code example. Never pre-empt hypothetical mistakes. +- [ ] Update `AGENTS.md` in the same commit as the convention it describes. A stale rules file misleads. +- [ ] Prune quarterly: delete rules whose convention changed or whose mistake no longer occurs. diff --git a/docs/plans/README.md b/docs/plans/README.md new file mode 100644 index 0000000..3653ee8 --- /dev/null +++ b/docs/plans/README.md @@ -0,0 +1,12 @@ +# Plans + +Implementation plans from the superpowers writing-plans workflow. + +- Naming: `NNN-short-slug.md`, matching its spec number. +- Links back to its spec. Bite-sized checkbox tasks with exact file paths, test commands, and commit + checkpoints. +- Written for an engineer with zero context for this codebase — spell out the obvious. +- Tick checkboxes as you go so another agent can resume an interrupted session. +- Front matter: `status: draft | approved | in-progress | done`. + +This path overrides the superpowers default (`docs/superpowers/plans/`) — see `AGENTS.md`. diff --git a/docs/specs/README.md b/docs/specs/README.md new file mode 100644 index 0000000..9effb0b --- /dev/null +++ b/docs/specs/README.md @@ -0,0 +1,11 @@ +# Specs + +Approved specifications from the superpowers brainstorming workflow. Nothing non-trivial gets +implemented without one. + +- Naming: `NNN-short-slug.md`, zero-padded, sequential. +- A spec states **what** and **why**, plus acceptance criteria. Not **how**. +- Front matter: `status: draft | approved | implemented | superseded`, and a link to its plan. +- Never delete an implemented spec; it is the record of intent. + +This path overrides the superpowers default (`docs/superpowers/specs/`) — see `AGENTS.md`.