1133201f30
- Review screen: slug-resolved species/wcat groupers, case-insensitive attrs, fig-*/feat-* tag pickers (METADATA-30/40), AI-assist labels + AI bubbles. - App orchestrator: single writable flow store, capture→review→publish, Resume boot. - API client (slabs.ts) mirroring live backend routes; Blob name fix. - Playwright e2e (7 tests, hermetic mock): canvas PNG seed, client-UUID mock, SKU blur commit, ready-state reactive fix; expect timeout 4s, 2 workers. - e2e green 7/7 in 6s; check_requirements + check_coverage PASS.
3.5 KiB
3.5 KiB
AGENTS.md
docs/REQUIREMENTS.md is the only normative text. All other docs cite IDs; none define requirements.
Structure contract (read before creating or moving any doc)
- Requirements live only in
docs/REQUIREMENTS.md; milestone scope indocs/MILESTONES.md. - Before creating or moving any doc under
docs/, look up its home indocs/STRUCTURE.md. - If no home exists, stop — do not create a new artifact.
- To change a requirement: edit the single row in
REQUIREMENTS.md; updateTest; if scope changed, updateMILESTONES.md. Do not create a doc. - Run
python tools/check_requirements.pyafter any docs change; it must pass.
Agent runtime rules
- Subagents run on one local GPU and cannot handle concurrency. Invoke one at a time; never in parallel.
Build & test (verified commands)
Frontend (frontend/, Svelte 4 + Vite + TS, no router):
cd frontend && npm install
npm run test # node --import tsx --test src/**/*.test.ts (unit)
npm run build # tsc --noEmit && vite build (type-check + build)
npm run test:e2e # playwright test (see Pitfalls: mocks the API)
Backend (backend/, FastAPI + stdlib sqlite, no ORM, deps pinned in backend/requirements.txt):
cd backend && python -m pytest tests/ -q
uvicorn backend.app:app --host 127.0.0.1 --port 18081
No Makefile, no CI workflows, no Gitea CI — nothing runs in a pipeline; the only automation is the local commands above plus the human UAT walk (deploy/uat_walk.sh).
Conventions
- The LIVE FastAPI routes in
backend/*.pyare the API source of truth;docs/contracts/API.mdis aspirational and can drift (it describes a polling model the backend never shipped). Read the router, not the doc, before wiring a client. - Frontend is one Svelte app, no router:
App.svelteswitches on awritableflow store. Screens live underfrontend/src/<area>/. - Commit subjects:
feat(scope): …/fix(scope): …/test(scope): …/chore(scope): …, often citing a requirement ID or Gitea number.
Gates (must pass before claiming work complete)
Run from repo root:
python tools/check_requirements.py
python tools/check_coverage.py
Exit 0 on both = pass.
Pitfalls
- E2E mocks the API:
tests/e2e/*.spec.tsuse Playwrightpage.route('**/api/v1/**')with fixture ids — there is no live backend under e2e. A greentest:e2eis not proof the real backend works; that's the humandeploy/uat_walk.sh(real Woo, never a mock — QUALITY-105). - Ports on the 5060 UAT host (192.168.1.202): FastAPI
18083, FE18082/10881are typically already up (compose ondeploy/docker-compose.yml). Check before binding; don't assume18081is free. SLAB_UAT_UNMASK_SECRETS=1makesGET /settingsreturn decrypted Woo/inference secrets — dev-test only, never set in prod (SETTINGS-75 masking is the default).- Never hardcode live Woo category/term ids into app code (QUALITY-105 / METADATA-5); resolve groupers by slug (
species,wcat) at runtime. tscwon't catch Svelte template errors;npm run build(which runstsc --noEmit) is the real type gate for the frontend.
Pointers (read these for everything else)
- Docs map and shipped status:
docs/README.md - Scope and ID subsets:
docs/MILESTONES.md - M3 behavior:
docs/capabilities/CREATE.md - Hosts, ports, UAT environment:
docs/DEPLOYMENT.mdanddeploy/INVENTORY.md - Task ordering for M3:
.planning/milestones/v0.5/M3/task_breakdown.md - Product invariants and acceptance criteria: the requirement rows in
docs/REQUIREMENTS.md(cite by ID)