61 lines
3.7 KiB
Markdown
61 lines
3.7 KiB
Markdown
|
|
# Module map — what can be worked on concurrently
|
||
|
|
|
||
|
|
Used for partitioning work across concurrent subagents. The rule is one owner
|
||
|
|
per file at a time: **never** give two concurrent agents tasks that touch the
|
||
|
|
same module. If two tasks genuinely need the same file, sequence them instead of
|
||
|
|
racing them — a rebase conflict costs more than the parallelism saved.
|
||
|
|
|
||
|
|
Read this before dispatching. It answers one question: *can these two tasks run
|
||
|
|
at the same time?*
|
||
|
|
|
||
|
|
The monorepo's four domains are the natural seam, and they are a real one: FE
|
||
|
|
and BE build and deploy independently, and `deploy.yml` checks per-leg whether a
|
||
|
|
push actually touched that domain. Two agents in two different domains will not
|
||
|
|
collide in CI either.
|
||
|
|
|
||
|
|
## Safe to assign concurrently
|
||
|
|
|
||
|
|
| Module | Files | Notes |
|
||
|
|
|---|---|---|
|
||
|
|
| Backend — API | `backend/api/**`, `backend/app.py` | Route handlers and serialisation. |
|
||
|
|
| Backend — core | `backend/core/**` | Grading, percentiles, climatology. The domain logic. |
|
||
|
|
| Backend — accounts | `backend/accounts/**` | Auth, sessions, OAuth links. |
|
||
|
|
| Backend — daemon | `backend/daemon/**` | Scheduled work. Anything named "prefetch" must not spend the Open-Meteo quota. |
|
||
|
|
| Backend — data & lake | `backend/data/**`, `backend/gen_era5_lake.py`, `backend/gen_cities.py` | |
|
||
|
|
| Backend — migrations | `backend/alembic/**`, `backend/alembic.ini` | One owner, always. Two agents generating revisions produce two heads. |
|
||
|
|
| Frontend — server | `frontend/server/**`, `frontend/app.py`, `frontend/api_client.py` | Go SSR and the Python app. |
|
||
|
|
| Frontend — static | `frontend/static/**` | |
|
||
|
|
| Frontend — templates | `frontend/templates/**`, `frontend/content/**`, `frontend/content.py` | |
|
||
|
|
| Infra — deploy | `infra/deploy/**` (excluding `secrets/`), `infra/docker-compose*.yml` | |
|
||
|
|
| Infra — secrets | `infra/deploy/secrets/**` | SOPS vault. One owner, and never alongside `infra/deploy`. |
|
||
|
|
| Infra — ops | `infra/ops/**`, `infra/lake-iceberg/**` | |
|
||
|
|
| Infra — terraform | `infra/terraform/**` | |
|
||
|
|
| Observability | `observability/**` | Grafana dashboards are provisioned from this JSON; a UI edit is overwritten. |
|
||
|
|
| Docs | `docs/**` | |
|
||
|
|
| Agent tooling | `.claude/hooks/**` | |
|
||
|
|
|
||
|
|
## Serialise — shared spine
|
||
|
|
|
||
|
|
Touched by most changes. A change here is its own task with nothing else running
|
||
|
|
against it.
|
||
|
|
|
||
|
|
| File | Why |
|
||
|
|
|---|---|
|
||
|
|
| `.forgejo/workflows/**` | CI lives **only** here, path-filtered per domain. Every domain's changes route through the same files, so two agents editing workflows conflict even when their domains do not. |
|
||
|
|
| `CLAUDE.md` and every domain `CLAUDE.md` | Read before every change; a stale one is a correctness bug. Small edits, landed fast. |
|
||
|
|
| `CUTOVER-NOTES.md` | The source of truth for what is and is not live. |
|
||
|
|
| `infra/deploy/env-topology.sh` | The single source of truth for where each environment's checkout, branch, stack and ports live. |
|
||
|
|
| `infra/deploy/deploy.sh`, `infra/deploy/stack/deploy-stack.sh` | The deploy contract's entry points. |
|
||
|
|
| `backend/CLAUDE.md` + the `/api/version` contract | FE and BE ship out of lockstep, so `PAYLOAD_VER` discipline is load-bearing. A change to the payload shape is one task spanning both domains — not two concurrent ones. |
|
||
|
|
|
||
|
|
## The recurring collisions
|
||
|
|
|
||
|
|
- **A schema change is not a backend-only task.** It is `backend/alembic` plus
|
||
|
|
whatever reads the column, and if the payload shape moves it is `PAYLOAD_VER`
|
||
|
|
and the frontend too. Scope it as one task across both domains rather than
|
||
|
|
two agents discovering each other mid-flight.
|
||
|
|
- **Adding CI for a domain edits the shared workflows.** Sequence it against any
|
||
|
|
other workflow work.
|
||
|
|
- **`infra/deploy/secrets/` and `infra/deploy/` are one owner between them.**
|
||
|
|
The rendered artifact and the thing that renders it move together.
|