Skip to content

Commit 1480d45

Browse files
exposwifty31claude
andcommitted
chore(rules): correct three stale architecture invariants CodeRabbit reads on every PR
`.coderabbit.yaml`'s `**/*` block is applied to every file in every PR, and it is live — PRs #197/#199/#200 all report `Configuration used: Path: .coderabbit.yaml`. Three of its seven architecture invariants were wrong: - "Schema lives in server/db.ts only" — db.ts has held no table since c1780d8 (2026-05-24). It is 23 lines: pool, drizzle instance, re-export. Tables live in server/schema/*.ts via the vtTable alias. The instruction was not merely stale, it pointed the reviewer at the wrong file for three months and survived an edit to this same file two months into that window. - "Medication volume must stay strictly below 100 ml" — enforced nowhere. - "Billing ledger inserts require deterministic idempotency keys" — the ledger was removed (shadow-inventory.service.ts:2). The realtime invariant was correct but had no carve-out for the sanctioned /collab-ws channel, so a correct change under server/lib/realtime-collab/ would have read as a violation. Added. .cursorrules said the right thing on lines 30 and 110 and the wrong thing on line 15 and in the heading at 151. A reader going top-down met the wrong one first. Aligned. No drift gate added: the obvious one (assert named paths exist) would not have caught this, since server/db.ts exists and merely stopped holding what was claimed. Reasoning recorded in the audit log. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent f6ab6bc commit 1480d45

3 files changed

Lines changed: 60 additions & 6 deletions

File tree

.coderabbit.yaml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,11 @@ reviews:
4848
- Caching emergency or realtime endpoints in the service worker
4949
5050
Architecture invariants (see .cursorrules, CLAUDE.md, AGENTS.md):
51-
- Schema lives in server/db.ts only; new workers register in server/app/start-schedulers.ts
51+
- Drizzle table and enum definitions live in server/schema/*.ts, declared via the `vtTable` alias, and are re-exported from server/db.ts. server/db.ts itself holds only the pool, the drizzle instance and that re-export — it defines no tables. Never ask for a table definition to be moved or added there.
52+
- New workers and recurring schedulers register in server/app/start-schedulers.ts
5253
- API client traffic goes through src/lib/api.ts; no raw fetch() in feature code
5354
- i18n user-facing copy only in locales/en.json and locales/he.json (paired keys)
54-
- Medication volume must stay strictly below 100 ml for liquids
55-
- Billing ledger inserts require deterministic idempotency keys
56-
- Realtime uses SSE + vt_event_outbox; do not introduce parallel polling transports
55+
- Realtime domain state uses SSE + vt_event_outbox; do not introduce parallel polling transports. The Socket.io channel on /collab-ws is a sanctioned exception carrying ephemeral collaboration state only (presence, cursors, typing, nudges) and must never carry domain or emergency state.
5756
5857
- path: "src/**/*.tsx"
5958
instructions: |

.cursorrules

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ These rules govern all AI-assisted work on this repository. They extend the focu
1212
- Never satisfy tenancy by joining alone if the target row’s table is not also filtered by `clinicId`.
1313
- **Never** hardcode `dev-clinic-default` in production-only code paths; it is the dev-bypass default clinic on `AuthUser` in `server/middleware/auth.ts` (`DEV_USER`) and `ensureDevUserRecord`.
1414
- Cross-clinic access is a **defect**, not a style issue.
15-
- New `pgTable` definitions in `server/db.ts` must include tenant scope: `clinicId` is **not null** and references `clinics` where the rest of the schema does; place it **immediately after the primary key** for new tables unless an existing table family uses a different column order (match neighbors).
15+
- New table definitions in `server/schema/*.ts` (declared via the `vtTable` alias) must include tenant scope: `clinicId` is **not null** and references `clinics` where the rest of the schema does; place it **immediately after the primary key** for new tables unless an existing table family uses a different column order (match neighbors).
1616

1717
## Auth
1818

@@ -148,7 +148,7 @@ These rules govern all AI-assisted work on this repository. They extend the focu
148148

149149
- Exported functions must be called from at least one route, worker, scheduler, or other service. Subset-only imports: remove unused named exports.
150150

151-
## Schema (`server/db.ts`)
151+
## Schema (`server/schema/*.ts`, re-exported from `server/db.ts`)
152152

153153
- New columns need at least one **query** in the same PR (select/insert/update/where). Before dropping a column, check **`migrations/`**, **`src/lib/offline-db.ts`**, and **`server/integrations/`**.
154154

docs/audit/PROOF_ALIGNMENT_LOG.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8600,3 +8600,58 @@ entry does not close and does not claim to.
86008600
**Verdict:** VERIFIED — every item above was observed this session by direct `gh api` output, not
86018601
restated from a commit message or a prior entry. The one non-observable item, the absence of a
86028602
registered company, is recorded as an owner statement and labelled as such.
8603+
8604+
---
8605+
8606+
## 2026-08-20 — Architecture invariants in `.coderabbit.yaml` and `.cursorrules` corrected against live code (chore/rule-invariants-drift)
8607+
8608+
**Claim:** The `**/*` path instruction CodeRabbit applies to every file in every vettrack PR carried
8609+
seven architecture invariants. Three were wrong. All seven were checked against live code and the
8610+
block was rewritten. Two contradicting lines in `.cursorrules` were aligned with the two in the same
8611+
file that were already correct.
8612+
8613+
**Evidence:**
8614+
8615+
- **The config is live, not inert.** Review comments on PRs #197, #199 and #200 each report
8616+
`Configuration used: Path: .coderabbit.yaml`. (The RN repo's PR #81 reports `Organization UI` — a
8617+
different repo with a different source. The two must not be conflated.)
8618+
- **`server/db.ts` holds no schema.** 23 lines: the pool, `drizzle(pool)`,
8619+
`export * from "./schema/index.js"`, and a legacy `initDb()` stub. `grep -c pgTable server/db.ts`
8620+
→ `0`.
8621+
- Tables are declared with `vtTable(...)` in `server/schema/*.ts`. `server/schema/helpers.ts:5` →
8622+
`export const vtTable = pgTable;`, whose own comment reads "identical table names as the original
8623+
db.ts monolith" — the helper documents the split that the instruction had not caught up with.
8624+
- **The staleness is datable.** `git log --diff-filter=A -- server/schema/core.ts` → `c1780d8f7`,
8625+
2026-05-24, `refactor: modularize server/db.ts into domain schema files (#421)`.
8626+
`git log -1 -- .coderabbit.yaml` → `27975124a`, 2026-07-28. The file was edited **two months after**
8627+
the split and the wrong line survived that edit.
8628+
- **Medication < 100 ml is enforced nowhere.** `grep -rnE '\b100\b' server src shared` filtered to
8629+
`ml|volume|liquid` → no matches.
8630+
- **The billing ledger is gone.** `find server src shared -iname '*billing*'` → no results.
8631+
`server/services/shadow-inventory.service.ts:2` → "Shadow inventory — billing ledger removed;
8632+
orphan-stock scan is a no-op." A residual guard survives at
8633+
`server/workers/integration.worker.ts:85` and was left alone; this entry does **not** claim the
8634+
removal is complete.
8635+
- **The realtime invariant was correct but incomplete.** It read "do not introduce parallel polling
8636+
transports" with no carve-out, while CLAUDE.md's frozen-surfaces section documents the `/collab-ws`
8637+
Socket.io channel as the one sanctioned additive exception. As written, a correct change under
8638+
`server/lib/realtime-collab/` would have read to the reviewer as a violation.
8639+
- **`.cursorrules` contradicted itself.** Lines 30 and 110 name `server/schema/*.ts` correctly. Line
8640+
15 said "New `pgTable` definitions in `server/db.ts`", and the section heading at line 151 read
8641+
`## Schema (server/db.ts)`. A reader going top-down met the wrong statement first, and nothing in
8642+
the file established precedence. Both corrected.
8643+
- **The edited YAML was re-parsed, not assumed.** `ruby -ryaml` → 5 `path_instructions` blocks, and
8644+
the rendered invariants text was read back to confirm what the reviewer actually receives.
8645+
8646+
**Not done, deliberately — no drift gate was added.** The obvious gate ("every path named in a rule
8647+
file must exist") would **not** have caught this bug: `server/db.ts` exists, it simply no longer holds
8648+
what the rule claimed. A gate that passes green on the exact defect it was written for is the failure
8649+
mode this week's audit found nine separate times, and shipping one here would have added the
8650+
appearance of coverage and none of it. A narrow assertion covering only this instance was judged not
8651+
to earn its maintenance.
8652+
8653+
**Also observed, not fixed:** `CLAUDE.md:123` still lists `server/lib/` as holding "Business logic
8654+
(billing, …)" though no billing file exists. Out of scope for this change; recorded so it is not lost.
8655+
8656+
**Verdict:** VERIFIED — every claim above comes from direct command output run this session, not from
8657+
a commit message or a prior entry.

0 commit comments

Comments
 (0)