--- name: odc-done description: Close out a change to Open Data Capture before committing, opening a PR, or reporting it done. Use also when another skill hands off its close-out, or when asked whether the current uncommitted change is ready to merge — an already-opened PR is review-pr's job. --- If you are still writing code, keep writing — this is the sweep for the moment the change is finished. **Green is not done.** Nothing downstream catches what you skip here: `.husky/pre-commit` only formats the staged files, and CI runs on a pull request to `main`, which is after this moment (`.agents/docs/architecture/testing-strategy.md`). A check you cannot meet is an **exception**: one line in your reply naming the check and why. Step 8 collects them. ## 1. Lint, then read what it rewrote ```sh pnpm lint git status --porcelain ``` `eslint --fix` writes to disk, so a green run can hand back a tree it edited. A tree that already conforms comes back untouched; a rewrite appears when your new code disagrees with `perfectionist/sort-objects` or `import/exports-last`. Those rewrites are correct — read them and keep them. A cold run builds every dependency, generates both Prisma clients and pushes the gateway schema (`.agents/docs/architecture/testing-strategy.md`). Slow is the expected state, not a hang. **Done when** `pnpm lint` exits green and every path `git status` reports is one whose diff you have read and intend to commit. TS2345 on a route literal you added is the one failure that is correct as it stands — it clears when the user regenerates `route-tree.ts`, but only if the literal matches its file path character-for-character (`.agents/skills/odc-web-route/SKILL.md`). Raise it as an exception rather than editing the tree yourself. ## 2. Test, and make the run name your file ```sh pnpm test:coverage # fails below 100% on any metric — see testing-strategy.md §Coverage pnpm exec vitest list --filesOnly # a green run prints counts only; this prints the collected files ``` A test file the listing never names was collected by nothing — `.agents/skills/odc-testing/SKILL.md` opens on that failure and owns both the diagnosis and the fix. **Done when** the run is green at 100% coverage _and_ `list --filesOnly` names every test file this change added. ## 3. Run the end-to-end suite, or raise the exception ```sh pnpm test:e2e ``` Playwright boots `apps/api`, `apps/gateway` and `apps/web` itself. The browsers must be installed once per machine — `pnpm --filter @opendatacapture/testing exec playwright install chromium firefox` (`.agents/docs/playbooks/add-e2e-test.md`, which also carries the single-spec and UI-mode invocations for when you are iterating on one failure). **Done when** the suite is green, or its exception is in your reply. ## 4. Account for both tests Every change needs a unit test **and** an end-to-end test in `testing/` (root `AGENTS.md`). **Done when** you can name the unit test file and the `testing/src/specs/` file this change added, or each missing one carries its exception. ## 5. Follow the change through its second file Each row is a pair of files that must agree, where the second is easy to leave unfinished. | You touched | What must follow | Owned by | | ----------------------------------------- | ---------------------------------------------------------------------------------- | ---------------------------------------------- | | a file under `apps/web/src/routes/` | `route-tree.ts` (the user's) and `testing/src/generated/route.d.ts` | `.agents/skills/odc-web-route/SKILL.md` | | a new folder under `packages/schemas/src` | its subpath in that package's `exports` — there is no `.` export | `packages/schemas/AGENTS.md` | | a new instrument directory | the hand-written import _and_ `create` call in `apps/api/src/demo/demo.service.ts` | `.agents/docs/playbooks/add-instrument.md` | | a wrapper under `vendor/` | `runtime/v1/package.json` devDependencies _and_ `runtime.config.js` | `.agents/docs/playbooks/add-vendor-package.md` | | an environment variable | the rest of the chain, in the playbook's order | `.agents/docs/playbooks/add-env-var.md` | | a `packages/react-core` component | `src/index.ts` — the barrel is the public API, there are no deep imports | `packages/react-core/AGENTS.md` | | a request or response shape in `apps/api` | `cli/odc-cli`, which nothing links to the API | `cli/AGENTS.md` | | a new workspace or vitest project | the tables in `workspace-map.md` and `testing-strategy.md` | `.agents/skills/odc-agent-docs/SKILL.md` | **Done when** every row whose left column matches your diff is either done or carries its exception. ## 6. If the diff touched `apps/api`, sweep every query Open `.agents/skills/odc-api/SKILL.md` before you sweep — it carries why an omitted ability silently returns an empty `where`, and how the guard and the `where` clause divide the work. **Done when** every Prisma query in the diff is accounted for — each one either names `accessibleQuery` in its `where`, or is unscoped for a reason your reply states — and every handler calling a scoped service forwards `@CurrentUser('ability')`. Every one, not a sample. ## 7. Reconcile the AGENTS.md you contradicted Where the change disagrees with a workspace `AGENTS.md`, `.agents/skills/odc-agent-docs/SKILL.md` carries the house format for the edit — open it before you write. **Done when** you have opened the `AGENTS.md` of every workspace in the diff and each one is either consistent with the change or edited in this commit. ## 8. Say what you did not verify Some exceptions were never a command: a row in step 5 you took on trust, a behaviour no test exercises. **Done when** your reply lists every exception raised above, or states that every check ran green.