CLAUDE.md
Rama main · réplica de lectura del repositorio original.
# CLAUDE.md — Development Instructions
> Name: **briefd** — your agents, briefed. Not flooded. A self-hosted "context compiler"
> for AI coding teams: git-backed domain knowledge, served to agents via MCP as
> token-budgeted context bundles.
## What this project is
One sentence: *Stop loading your team's knowledge into every prompt. Compile only what
the task needs.*
Teams working on many projects in one domain keep shared knowledge (conventions, ADRs,
specs, decisions) as Markdown in a **knowledge git repo**. This service indexes it and
serves task-relevant, token-budgeted context bundles to AI coding agents (Claude Code,
Cursor, Codex) over **MCP** and REST.
## Locked architecture decisions — do NOT revisit without an ADR
These were decided after research. Do not "improve" them mid-task. If you believe one is
wrong, stop and propose an ADR instead of changing code.
1. **Language: Go** (>= 1.26). Single static binary. Official MCP Go SDK
(`modelcontextprotocol/go-sdk`, v1.x).
2. **Storage: SQLite only** (WAL mode). One `.db` file holds documents, chunks,
embeddings, usage events, bundle cache, sync state.
3. **Search: hybrid** — SQLite **FTS5 (BM25)** + **brute-force cosine over vectors stored
in SQLite** (in-memory scan in Go, see ADR-0002) fused with **RRF, k=60**. No ANN
libraries, no vector extensions. BM25-only mode must remain available via config
(`embeddings.enabled=false`).
4. **Embeddings: local by default** — `multilingual-e5-small` (384-dim, 100+ languages;
ADR-0006) or `all-MiniLM-L6-v2` (English, faster) run by our pure-Go encoder
(ADR-0003; weights downloaded once, no ONNX runtime, no CGO), pluggable adapters:
`ollama`, `openai-compatible`, `none`. Adapter interface first, implementations
behind it.
5. **Git is the source of truth. The index is a disposable cache.** The service must be
able to rebuild the entire index from a fresh clone. Never store knowledge that exists
only in SQLite.
6. **Agents never write to the index directly.** `propose_update` creates a git
branch/commit (PR-based review). Merge → sync → reindex is the only write path.
7. **Deployment: one container, zero external services.** Never add Redis, Postgres,
Elasticsearch, Qdrant, or any message queue. Caching is in-process LRU + SQLite tables.
8. **Token budget is a hard constraint.** Any API that returns context accepts
`max_tokens` and must never exceed it. Truncation strategy lives in the bundle
packer, nowhere else.
9. **License: Apache-2.0.** No AGPL/GPL/SSPL dependencies. Check licenses before adding
any dependency.
## Repository layout
```
briefd/
├── cmd/briefd/ # main: serve | index | eval | version
├── internal/
│ ├── config/ # YAML config + env overrides
│ ├── gitsync/ # clone/pull, commit-hash diff, poll + webhook
│ ├── ingest/ # markdown parsing, chunking, front-matter
│ ├── indexer/ # walks a source, diffs against the store, upserts/deletes
│ ├── store/ # SQLite: schema, migrations, queries (sqlc or hand-written)
│ ├── search/ # fts5 query, vec query, rrf fusion
│ ├── embed/ # Embedder interface + minilm (pure Go) / ollama / openai adapters
│ ├── bundle/ # compile_bundle: selection + token packing + cache
│ ├── mcpserver/ # MCP tools (streamable HTTP)
│ ├── httpapi/ # REST + health + /metrics + embedded dashboard
│ ├── metrics/ # in-process counters/histograms (Prometheus text exposition)
│ └── tokenizer/ # token counting (tiktoken-compatible approximation)
├── eval/ # golden dataset + eval harness (see Testing)
├── testdata/knowledge/ # sample knowledge repo (fictional payments domain) used by tests
├── docs/adr/ # ADRs — one file per decision, NNNN-title.md
├── deploy/ # docker-compose.yml, Dockerfile
└── SPEC.md # product/technical spec — read before any feature work
```
## Workflow rules
- **Read `SPEC.md` before implementing any feature.** If the spec is silent or
ambiguous, ask; do not invent behavior.
- Work in **small vertical slices** that end in something runnable (see PROMPTS.md
milestones). Do not scaffold all packages upfront.
- Every non-obvious technical decision gets an ADR in `docs/adr/` in the same PR.
- Conventional commits (`feat:`, `fix:`, `docs:`, `test:`, `refactor:`).
- Update `SPEC.md` when implemented behavior legitimately diverges from it — spec and
code must not drift.
## Coding conventions
- Standard Go style; `gofmt` + `golangci-lint` clean.
- Errors: wrap with context (`fmt.Errorf("indexing %s: %w", path, err)`); no panics
outside `main`.
- No premature abstraction: interfaces only where a second implementation exists or is
specced (Embedder is the canonical example).
- The whole binary is pure Go: SQLite via `ncruces/go-sqlite3` (ADR-0002), embeddings via
`internal/embed/minilm` (ADR-0003). Do not introduce CGO without an ADR.
- All SQL lives in `internal/store`. No SQL strings elsewhere.
- Config precedence: flags > env (`BRIEFD_*`) > yaml > defaults.
## Testing rules
Two mandatory layers — a feature is not done without both where applicable:
1. **Deterministic tests** (`go test ./...`):
- Chunking: heading hierarchy preserved, size limits respected, stable chunk IDs.
- Git sync: changed/deleted files trigger incremental reindex; full rebuild from
clean clone produces identical index.
- RRF: pure-function table-driven tests.
- Budget packer: output never exceeds `max_tokens` (property-style test with random
inputs).
2. **Retrieval quality eval** (`briefd eval`):
- Golden dataset in `eval/` (corpus + queries + expected chunk IDs).
- Metrics: **Recall@5, Recall@10, MRR**.
- CI gate: fail if Recall@5 drops below the threshold in `eval/thresholds.yaml`.
- Any change to chunking, embeddings, or fusion MUST run the eval and report
before/after numbers in the PR description.
## Off limits
- Do not add external service dependencies (see locked decision #7).
- Do not modify `eval/golden/*` to make a failing eval pass.
- Do not bypass the git write path with direct index mutations.
- Do not add telemetry/phone-home of any kind.