docs: replace AGENTS.md with a CLAUDE.md written for this repo
One agent doc per repo, and it is CLAUDE.md. Two agent docs drift, and
the one nobody read is always the one holding the rule that mattered —
this repo had a CLAUDE.md whose entire content was an instruction to go
read the other file.
Composed fresh rather than reformatted. Everything factual carries over;
the structure follows what someone working here actually needs first.
Three corrections made while carrying content across:
- The release flow instructed `git add -A`. That is denied by policy
and sweeps in whatever else is dirty, including secrets. Now: stage
by name.
- The feature-branch mandate is gone. Linear history everywhere, no
per-repo exceptions as of 2026-08-08.
- The 8778/8089 split is stated explicitly rather than left implicit
in two separate sections. 8778 is wakeup.sh's reload server, 8089 is
the container — testing the wrong one silently exercises the wrong
build. Both ports verified against wakeup.sh and the deployed stack
before writing them down.
Adds the live double-ingestion defect (T-1) where someone touching
ingestion will see it, including the part that is not yet established:
whether it merely wastes GPU or actually corrupts Qdrant and Neo4j.
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,97 +0,0 @@
|
||||
|
||||
# AGENTS.md
|
||||
|
||||
> **Start every session by reading this file.**
|
||||
> This file outlines the operational protocols, coding standards, and architectural decisions for this FastAPI project.
|
||||
|
||||
## 1. Agent Operational Protocols
|
||||
|
||||
### 🧠 Work Patterns (Plan-Act-Reflect)
|
||||
* **Plan:** Before writing code, briefly outline your plan. Identify which files you will touch and what the side effects might be.
|
||||
* **Act:** Execute the changes in small, atomic steps.
|
||||
* **Reflect:** After coding, verify your work. Did you break existing tests? Did you add new tests?
|
||||
|
||||
### 📋 Work Tracking
|
||||
* **Outstanding work lives in pql, not in a markdown file.** `TODO.md` was migrated
|
||||
on 2026-08-08 and removed.
|
||||
* `pql ticket list` — open work. `pql plan whatsnext` — the next unblocked item with
|
||||
context. `pql ticket show T-N --with-children` — detail.
|
||||
* File new work with `pql ticket new bug|task|story|epic "title"` rather than adding a
|
||||
TODO section. Tickets travel with the repo: `.pql/changelog/` is committed and
|
||||
replayed by the git hooks, while the databases are ignored and rebuildable
|
||||
(`pql plan rebuild`).
|
||||
|
||||
### 🛡️ Git Discipline
|
||||
* **History is linear — no merge commits.** Work goes onto `main` directly, or onto a short-lived branch that is fast-forwarded and deleted. Never create a merge commit. (This replaced a feature-branch mandate on 2026-08-08, to match the workspace convention; `tatlock` remains the one repo that requires branches.)
|
||||
* **Commit Messages:** Use the [Conventional Commits](https://www.conventionalcommits.org/) format.
|
||||
* `feat: add user login endpoint`
|
||||
* `fix: resolve database connection timeout`
|
||||
* `refactor: split monolith dependency file`
|
||||
* **Atomic Commits:** Keep commits small. One logical change = one commit.
|
||||
|
||||
### 📝 Changelog Maintenance
|
||||
* **Update `CHANGELOG.md`** with every user-facing change.
|
||||
* Format: `## [Unreleased] - YYYY-MM-DD` followed by `### Added`, `### Changed`, or `### Fixed`.
|
||||
|
||||
### 🚀 Release Flow
|
||||
When changes are ready for deployment:
|
||||
|
||||
1. **Ask user if deploy cycle is desired **
|
||||
|
||||
2. **Update version** in `pyproject.toml`:
|
||||
- Bug fixes: bump patch version (1.8.3 → 1.8.4)
|
||||
- New features: bump minor version (1.8.4 → 1.9.0)
|
||||
|
||||
3. **Update CHANGELOG.md**:
|
||||
- Move items from `[Unreleased]` to new version section
|
||||
- Add release date: `## [1.8.4] - 2025-12-16`
|
||||
|
||||
4. **Commit and tag**:
|
||||
```bash
|
||||
git add -A
|
||||
git commit -m "fix: description of changes"
|
||||
git tag v1.8.4
|
||||
git push origin main --tags
|
||||
```
|
||||
|
||||
5. **CI/CD triggers automatically**:
|
||||
- Gitea CI builds Docker image on new tag
|
||||
- Watchtower pulls and deploys to production
|
||||
- Verify deployment: `curl http://192.168.86.149:8089/health`
|
||||
|
||||
---
|
||||
|
||||
### 🧪 Local Development Setup
|
||||
* **Always test locally first** before committing and deploying. The build-deploy loop is slow.
|
||||
* **Start the local server** with `./wakeup.sh` - logs are written to `logs/server.log` for easy tailing
|
||||
* **Auto-reload**: The wakeup script runs uvicorn in reload mode - code changes are picked up automatically without restart (except for requirements.txt changes)
|
||||
* **Test REST endpoints** against `http://localhost:8778` using curl or similar tools
|
||||
* **Only deploy** when a phase or feature is complete and tested locally
|
||||
* **Environment**: Copy `.env.example` to `.env` and configure for your local setup (Ollama, Redis, Neo4j, Qdrant, Wiki.js hosts)
|
||||
* **Running tests**: Always use the venv explicitly to avoid environment mismatches:
|
||||
```bash
|
||||
.venv/bin/python -m pytest tests/ # All tests
|
||||
.venv/bin/python -m pytest tests/ -v # Verbose output
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. FastAPI Architecture & Best Practices
|
||||
*Reference: [FastAPI Best Practices](https://github.com/zhanymkanov/fastapi-best-practices)*
|
||||
|
||||
### 📂 Project Structure (Directory-based, NOT File-type based)
|
||||
Do **not** group files by type (e.g., one huge `routers` folder). Group by **domain/module** inside a `src/` directory.
|
||||
|
||||
**Correct Structure:**
|
||||
```text
|
||||
src/
|
||||
├── auth/
|
||||
│ ├── router.py # Endpoints
|
||||
│ ├── schemas.py # Pydantic models
|
||||
│ ├── service.py # Business logic (CRUD, etc.)
|
||||
│ ├── dependencies.py# Module-specific dependencies
|
||||
│ └── config.py # Module-specific settings
|
||||
├── posts/
|
||||
│ ├── router.py
|
||||
│ └── ...
|
||||
└── main.py # App entry point
|
||||
@@ -1,17 +1,101 @@
|
||||
# Claude Code Instructions
|
||||
# CLAUDE.md — Library Desk
|
||||
|
||||
**MANDATORY: Read AGENTS.md instead of this file.**
|
||||
FastAPI service that ingests Wiki.js content and serves retrieval over it. Talks to
|
||||
Postgres (Wiki.js DB + `LISTEN/NOTIFY`), Qdrant (vectors), Neo4j (graph), Ollama
|
||||
(embeddings) and Redis (job manager). Deployed on tower-of-joy at **:8089**.
|
||||
|
||||
This project uses a unified configuration file for all LLM coding agents.
|
||||
## Ports — these differ, deliberately
|
||||
|
||||
## Instructions
|
||||
| | Port | How |
|
||||
|---|---|---|
|
||||
| Local dev | **8778** | `./wakeup.sh`, uvicorn reload mode, logs to `logs/server.log` |
|
||||
| Production | **8089** | container; health at `http://192.168.86.149:8089/health` |
|
||||
|
||||
1. **Read and follow AGENTS.md** - All project guidelines are located there
|
||||
2. **Do not modify this file** - Only update AGENTS.md
|
||||
3. **Do not create or modify other agent-specific files** - Use AGENTS.md as the single source of truth
|
||||
Testing `localhost:8089` on the dev box hits the *container*, not your reload server.
|
||||
|
||||
This approach ensures consistent behavior across all LLM coding agents without managing separate configuration files.
|
||||
## Work tracking
|
||||
|
||||
---
|
||||
Work lives in **pql**, not a markdown file. `TODO.md` was migrated and removed 2026-08-08.
|
||||
|
||||
If you need to update project guidelines, edit AGENTS.md, not this file.
|
||||
```bash
|
||||
pql ticket list # open work
|
||||
pql plan whatsnext # next unblocked item, with context
|
||||
pql ticket show T-1 # detail
|
||||
pql ticket new bug "title" # file new work
|
||||
```
|
||||
|
||||
Tickets travel with the repo — `.pql/changelog/` is committed and replayed by the git
|
||||
hooks; the databases are ignored and rebuildable with `pql plan rebuild`. Do not add a
|
||||
TODO section to a markdown file.
|
||||
|
||||
## Known live defect
|
||||
|
||||
**Every wiki page change is ingested twice** (T-1, proven against v1.9.1). The Dockerfile
|
||||
runs `uvicorn --workers 2`, `startup_event` creates a `WikiChangeListener` per worker, and
|
||||
Postgres delivers `NOTIFY` to *every* listening session. The debounce in
|
||||
`wiki_change_listener.py` is an in-process dict and cannot dedupe across workers.
|
||||
|
||||
Relevant when touching ingestion: duplicate work reaches Ollama, Qdrant and Neo4j. Whether
|
||||
it merely wastes GPU or actually corrupts state is **not yet established** — check before
|
||||
assuming either.
|
||||
|
||||
## Working here
|
||||
|
||||
**Plan, act, reflect.** Outline which files you will touch and the side effects before
|
||||
writing. Change in small atomic steps. Afterwards, verify: did existing tests break, and
|
||||
does the new behaviour have a test?
|
||||
|
||||
**Test locally first — the build-deploy loop is slow.** `./wakeup.sh` auto-reloads on code
|
||||
changes (not on `requirements.txt` changes). Deploy only when a feature is complete and
|
||||
tested.
|
||||
|
||||
Run tests through the venv explicitly, to avoid environment mismatch:
|
||||
|
||||
```bash
|
||||
.venv/bin/python -m pytest tests/
|
||||
```
|
||||
|
||||
Copy `.env.example` to `.env` and configure Ollama, Redis, Neo4j, Qdrant and Wiki.js hosts.
|
||||
|
||||
## Git
|
||||
|
||||
- **History is linear — no merge commits.** Work on `main`, or a short-lived branch that is
|
||||
fast-forwarded and deleted. (A feature-branch mandate was retired 2026-08-08 to match the
|
||||
workspace convention, which now has no per-repo exceptions.)
|
||||
- **Conventional Commits**: `feat:`, `fix:`, `refactor:`, `docs:`, `chore:`.
|
||||
- **Atomic commits** — one logical change each.
|
||||
- **Stage explicitly. Never `git add -A`** — it is denied by policy, and it sweeps in
|
||||
whatever else is dirty, including secrets.
|
||||
- Update `CHANGELOG.md` with every user-facing change, under `[Unreleased]` in `Added` /
|
||||
`Changed` / `Fixed`.
|
||||
|
||||
## Releasing
|
||||
|
||||
Ask whether a deploy is wanted first — it is not automatic.
|
||||
|
||||
1. Bump the version in `pyproject.toml` (patch for fixes, minor for features).
|
||||
2. Move `[Unreleased]` entries into a dated version section in `CHANGELOG.md`.
|
||||
3. Stage the changed files by name, commit, tag `vX.Y.Z`, `git push origin main --tags`.
|
||||
4. Gitea CI builds the image on the tag; Watchtower deploys it.
|
||||
5. Verify: `curl http://192.168.86.149:8089/health`.
|
||||
|
||||
## Architecture
|
||||
|
||||
Group by **domain, not by file type**. A single large `routers/` folder is the thing to
|
||||
avoid.
|
||||
|
||||
```text
|
||||
src/
|
||||
├── auth/
|
||||
│ ├── router.py # endpoints
|
||||
│ ├── schemas.py # pydantic models
|
||||
│ ├── service.py # business logic
|
||||
│ ├── dependencies.py # module-scoped dependencies
|
||||
│ └── config.py # module-scoped settings
|
||||
└── main.py # app entry point
|
||||
```
|
||||
|
||||
Reference: [FastAPI best practices](https://github.com/zhanymkanov/fastapi-best-practices).
|
||||
|
||||
The live contract is always `http://localhost:8089/openapi.json` (70 paths) — generated from
|
||||
running code, so it cannot drift the way this file can.
|
||||
|
||||
Reference in New Issue
Block a user