Update agent-facing docs to match the workflow that actually shipped in ST-509/511/512/513 and M7 (scrum4me-mcp). CLAUDE.md - Spec-tabel: link toegevoegd naar de scrum4me-mcp repo - Waar te beginnen: dual-track — Track A via mcp__scrum4me__implement_ next_story (aanbevolen), Track B is de bestaande manuele 7-stappen loop voor Codex/zonder MCP - Implementatiepatronen: rijen voor lib/task-status.ts mappers en client/server module-boundary (bv. lib/code.ts vs lib/code-server.ts) - Conventies: entity codes in commit-titles, lowercase API-status, 400/422 error-code split, verplichte test-pariteit bij contract- wijziging - Nieuwe sectie "MCP-integratie" — alle 9 tools + prompt + schema-drift cron (trig_015FFUnxjz9WMuhhWNGBQKFD, ma 08:00 Amsterdam) - Definition of Done expliciet als MVP; M7 is post-MVP agent-instruction-audit.md - Round 2 (2026-04-27) sectie met aanleiding, gecontroleerde wijzigingen en nieuwe preventieve regels (test-pariteit, status-enum boundary, error-code split, module-boundary) Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
173 lines
9.7 KiB
Markdown
173 lines
9.7 KiB
Markdown
# Agent Instruction Audit
|
|
|
|
Datum: 2026-04-25
|
|
|
|
## Aanleiding
|
|
|
|
Tijdens de code review kwamen twee soorten fouten naar voren:
|
|
|
|
- Server Actions vertrouwden client-provided IDs te veel nadat alleen de parent-resource was gecontroleerd.
|
|
- Documentatie liep achter op dependency-, API- en deploymentwijzigingen.
|
|
|
|
Dit document legt vast welke wijzigingen zijn gecontroleerd, welke documentatie is bijgewerkt en welke instructies Claude Code en Codex voortaan expliciet moeten volgen.
|
|
|
|
## Gecontroleerde wijzigingen
|
|
|
|
| Wijziging | Code-locatie | Documentatie bijgewerkt |
|
|
|---|---|---|
|
|
| Reorder-acties valideren alle IDs binnen de juiste parent-scope | `actions/stories.ts`, `actions/sprints.ts` | `docs/scrum4me-architecture.md`, `docs/patterns/server-action.md`, `docs/patterns/sort-order.md`, `CLAUDE.md`, `AGENTS.md` |
|
|
| Sprint afronden accepteert alleen stories uit de actieve sprint | `actions/sprints.ts` | `docs/scrum4me-architecture.md`, `docs/patterns/server-action.md`, `AGENTS.md` |
|
|
| Todo-promotie gebruikt scoped todo lookup en `pbi.product_id` als bron van waarheid | `actions/todos.ts` | `docs/scrum4me-architecture.md`, `docs/patterns/server-action.md`, `CLAUDE.md`, `AGENTS.md` |
|
|
| `GET /api/products` retourneert ook gedeelde producten via `product_members` | `app/api/products/route.ts` | `README.md`, `docs/scrum4me-functional-spec.md`, `docs/scrum4me-backlog.md`, `docs/patterns/route-handler.md` |
|
|
| `sharp` is directe runtime dependency | `package.json`, `package-lock.json` | `README.md`, `docs/scrum4me-architecture.md`, `CLAUDE.md` |
|
|
| Vercel Analytics is toegevoegd aan de root layout | `app/layout.tsx`, `package.json`, `package-lock.json` | `README.md`, `docs/scrum4me-architecture.md`, `CLAUDE.md` |
|
|
| `.env.example` ontbrak ondanks verwijzingen in architectuurdocs | `.env.example` | `README.md`, `docs/scrum4me-architecture.md` |
|
|
|
|
## Preventieve regels
|
|
|
|
### Access-control regels
|
|
|
|
Agents mogen nooit aannemen dat een ID veilig is omdat de UI hem normaal gesproken correct doorgeeft. Elke Server Action en Route Handler moet bij writes de volledige resource-scope bewijzen.
|
|
|
|
Concrete regels:
|
|
|
|
- Gebruik `productAccessFilter(userId)` voor product-scoped resources waar eigenaar en teamlid toegang hebben.
|
|
- Gebruik owner-only filters alleen bij echte eigenaarsacties.
|
|
- Valideer bulk-ID's met `id in (...)` plus parent-scope voordat er wordt geschreven.
|
|
- Weiger dubbele IDs in reorder- en decision-payloads.
|
|
- Leid denormalized foreign keys af van de database-parent, niet van client-input.
|
|
- Valideer runtime waarden met Zod of expliciete runtime checks; TypeScript types alleen zijn onvoldoende.
|
|
- Gebruik scoped deletes/updates nadat ownership bewezen is.
|
|
|
|
### Documentatie-regels
|
|
|
|
Een codewijziging is niet klaar als de documentatie een oud contract beschrijft. Agents moeten bij elke wijziging nagaan of deze plekken geraakt worden:
|
|
|
|
- `README.md`: setup, scripts, dependencies, deployment, API-overzicht.
|
|
- `docs/scrum4me-functional-spec.md`: functionele eisen en API-contracten.
|
|
- `docs/scrum4me-architecture.md`: stack, datamodel, securitymodel, env vars, deployment.
|
|
- `docs/scrum4me-backlog.md`: "done when"-criteria en scope van backlog-items.
|
|
- `docs/patterns/`: herbruikbare implementatiepatronen.
|
|
- `CLAUDE.md` en `AGENTS.md`: agent-regels die de fout in de toekomst voorkomen.
|
|
|
|
### Dependency-regels
|
|
|
|
- Elke runtime import moet als directe dependency in `package.json` staan.
|
|
- Als een dependency aan deploymentgedrag raakt, moet README of architectuurdocs dat noemen.
|
|
- Na `npm install` moet `package-lock.json` meegaan in dezelfde change.
|
|
|
|
### Verification-regels
|
|
|
|
Voor oplevering:
|
|
|
|
```bash
|
|
npm run lint
|
|
npm test
|
|
npm run build
|
|
```
|
|
|
|
Bij securitywijzigingen hoort minimaal een test die laat zien dat cross-user of cross-scope input wordt geweigerd. Als die test nog niet bestaat, noteer dat expliciet in de oplevering.
|
|
|
|
## Claude Code
|
|
|
|
`CLAUDE.md` is aangescherpt met:
|
|
|
|
- een verwijzing naar dit auditdocument;
|
|
- de directe stackwijzigingen voor Sharp en Vercel Analytics;
|
|
- expliciete access-control regels voor `productAccessFilter`, bulk-ID's en foreign-key afleiding;
|
|
- een docs-sync regel voor gedrags-, API-, dependency- en deploymentwijzigingen.
|
|
|
|
## Codex
|
|
|
|
`AGENTS.md` is uitgebreid van alleen Next.js-waarschuwing naar projectregels voor:
|
|
|
|
- access control;
|
|
- documentatie-sync;
|
|
- verificatiecommands.
|
|
|
|
Deze regels zijn korter dan `CLAUDE.md`, maar bewust dwingend: ze moeten direct gelezen worden bij elke Codex-taak in deze repo.
|
|
|
|
---
|
|
|
|
# Agent Instruction Audit — Round 2
|
|
|
|
Datum: 2026-04-27
|
|
|
|
## Aanleiding
|
|
|
|
Sinds ronde 1 (2026-04-25) is er substantieel werk geland dat de agent-workflow raakt:
|
|
|
|
- **ST-509** Todo description (max 2000)
|
|
- **ST-511** Entity codes voor Product/PBI/Story (auto-default + manual override + retry op race condition)
|
|
- **ST-512** REST API uitgebreid met `code`, `description`, `implementation_plan` in alle endpoints
|
|
- **ST-513** API hardening voor Claude Code: `GET /api/health`, `GET /api/products/:id/claude-context`, lowercase status-enums op de API-grens, `StoryLog.metadata` JSONB, validatie-fouten van `400` → `422`, nieuwe `docs/API.md`
|
|
- **PR #2 Codex-review-saga** — 8 testbestanden faalden bij de contract-flip; tests werden niet meebijgewerkt. Twee P2-issues van Codex: malformed JSON moet `400` blijven (P2.1), en `status: review` werd geaccepteerd terwijl de sprint-UI er niet mee om kan gaan (P2.2)
|
|
- **M7: scrum4me-mcp** — aparte MCP-server repo (`madhura68/scrum4me-mcp`) met 9 tools en 1 prompt voor Claude Code, schema gedeeld via git submodule
|
|
- **lib/code.ts vs lib/code-server.ts** — gesplitst om client-bundle vrij te houden van `pg` (gaf eerst `Module not found: 'dns'` build-error)
|
|
- **Wekelijkse schema-drift cron** (`trig_015FFUnxjz9WMuhhWNGBQKFD`) — remote agent die ma 08:00 Amsterdam de MCP-submodule syncet en typecheckt
|
|
|
|
## Gecontroleerde wijzigingen
|
|
|
|
| Wijziging | Code-locatie | Documentatie bijgewerkt |
|
|
|---|---|---|
|
|
| Lowercase status-enums op REST-grens, mappers naar DB-enum | `lib/task-status.ts`, `app/api/tasks/[id]/route.ts`, `app/api/sprints/[id]/tasks/route.ts`, `app/api/products/[id]/next-story/route.ts` | `docs/API.md`, `CLAUDE.md` |
|
|
| 400 (malformed JSON) gescheiden van 422 (zod-validatie) | `app/api/tasks/[id]/route.ts`, `app/api/stories/[id]/tasks/reorder/route.ts`, `app/api/todos/route.ts`, `app/api/stories/[id]/log/route.ts` | `docs/API.md`, `CLAUDE.md` |
|
|
| `status: review` geweigerd door PATCH `/api/tasks/:id` zolang sprint-UI geen REVIEW rendert | `app/api/tasks/[id]/route.ts` | `docs/API.md` |
|
|
| Entity codes (Product/PBI/Story) met auto-default + retry-on-P2002 | `actions/products.ts`, `actions/pbis.ts`, `actions/stories.ts`, `lib/code.ts`, `lib/code-server.ts` | `docs/scrum4me-backlog.md` (ST-511) |
|
|
| `StoryLog.metadata` JSONB | `prisma/schema.prisma`, `prisma/migrations/20260426214905_add_story_log_metadata/`, `app/api/stories/[id]/log/route.ts` | `docs/API.md` |
|
|
| Health- en bundled-context endpoints voor Claude Code | `app/api/health/route.ts`, `app/api/products/[id]/claude-context/route.ts` | `docs/API.md`, `CLAUDE.md` |
|
|
| MCP-server gepubliceerd als aparte repo | `madhura68/scrum4me-mcp` (extern) | `CLAUDE.md` (sectie MCP-integratie), `docs/scrum4me-backlog.md` (M7) |
|
|
|
|
## Nieuwe preventieve regels
|
|
|
|
### Test-pariteit bij contract-wijziging
|
|
|
|
Een wijziging die een API-contract aanraakt (status, foutcode, response-shape, request-shape) is pas klaar als `__tests__/api/` in dezelfde commit meegaat. Wat NIET acceptabel is:
|
|
|
|
- "Tests gaan rood maar de implementatie is correct" — herstel óf implementatie óf test, niet later
|
|
- Stilletjes 8 testbestanden laten breken zoals in PR #2 — Codex/CI vangt het, maar te laat in de cyclus
|
|
|
|
### Status-enums boundary-conversie
|
|
|
|
API exposeert lowercase, DB houdt UPPER_SNAKE. Conversie uitsluitend via `lib/task-status.ts`-mappers (`taskStatusToApi`, `taskStatusFromApi`, `storyStatusToApi`, `storyStatusFromApi`). Verboden:
|
|
|
|
- Ad-hoc `status.toLowerCase()` of `status.toUpperCase()` in route handlers
|
|
- Direct vergelijken van API-input met DB-enum (`if (body.status === 'IN_PROGRESS')`) — input is altijd lowercase
|
|
- Een nieuwe enum-waarde toevoegen zonder de mapper bij te werken
|
|
|
|
### Error-code split 400/422
|
|
|
|
- `400`: parse-fout op `request.json()` — wikkel altijd in `try/catch`
|
|
- `422`: zod-validatie of well-formed-maar-niet-acceptabel (bv. `task_id` van andere story)
|
|
- `403`: demo-token op write
|
|
- Documenteer per endpoint in `docs/API.md`
|
|
|
|
### Client/server module-boundary
|
|
|
|
`lib/foo-server.ts` mag DB-calls (`prisma`), node-only deps (`pg`, `crypto.createHash`) en server-actions doen. `lib/foo.ts` is pure helpers, client-veilig. Een client-component (`'use client'`) mag nooit uit een `*-server.ts`-module importeren — dat haalt `pg` of `dns` mee de bundle in en breekt de build.
|
|
|
|
### Verplichte verificatie vóór oplevering
|
|
|
|
Naast bestaande lint/test/build-stappen voor MCP-relevante wijzigingen ook:
|
|
|
|
```bash
|
|
# In scrum4me-mcp na een schema-wijziging in Scrum4Me:
|
|
npm run sync-schema && npm run prisma:generate && npm run typecheck
|
|
```
|
|
|
|
De wekelijkse cron doet dit automatisch, maar ad-hoc checken is nog steeds verstandig vóór een Scrum4Me-PR met migratie naar productie gaat.
|
|
|
|
## Claude Code
|
|
|
|
`CLAUDE.md` is uitgebreid met:
|
|
|
|
- Specificatiedocumenten-rij voor `madhura68/scrum4me-mcp`
|
|
- Dual-track workflow (Track A: MCP-prompt; Track B: manueel)
|
|
- Twee patroon-rijen: `lib/task-status.ts` en client/server module-boundary
|
|
- Vier nieuwe conventies: entity codes in commits, lowercase API-status, error-code split, test-pariteit
|
|
- Nieuwe sectie "MCP-integratie" met tools, prompt en schema-drift cron
|
|
- Definition of Done expliciet als MVP-scope; M7 is post-MVP
|
|
|
|
## Codex
|
|
|
|
`AGENTS.md` is in deze ronde **niet** bijgewerkt — Codex heeft geen MCP-toegang en de Track B-workflow daar werkt nog. Bij volgende ronde apart uitbreiden met de status-enum/error-code/test-pariteit regels (die zijn ook voor Codex relevant).
|