feat/one-api
needs attentionviewing older commitd3465e8 · incrementalpre-PRreviewed 2026-07-21 00:23 UTC1H · 7M · 10L · 7I- Purpose
- Establish the One-API program: encode the decision and canonical contract grammar as .claude/ rules (no docs/, no ADRs), and land the U0 groundwork — route-metadata inventory and the merged public-id prefix registry — that every later parity wave builds on.
- Goal
- Retire docs/ADRs/ as a knowledge vehicle; every load-bearing architecture decision lives in path-scoped .claude/rules/*.md files that auto-load when working in the relevant area.
- Sub-goals
- SG-1: Encode One-API decision in .claude/rules/one-api.md + canonical-form.md SSOT rewording
- SG-2: Route classification script + machine-readable inventory of all 245 routes
- SG-3: Merge PublicIdPrefix registries — shared-kernel absorbs utility prefixes; cfj kept
- SG-4: Distill load-bearing ADRs (016/018/020) into owning rules; retire docs/ADRs/ (this commit)
- What
- SG-4 commit: domain-patterns.md absorbed ADR-016 FCIS rationale + escape hatches + outbox side-effect types + cross-domain _tag uniqueness; canonical-form.md absorbed ADR-018 dependency rules + event co-location; new contracts-read-model.md distilled ADR-020 (trigger-maintained CQRS, realtime trust boundary, parity twins, drift matrix, SECURITY DEFINER REVOKE); rls-checklist.md got the REVOKE rule; ~30 cross-references repointed across rules/skills/READMEs/schema comments; all 20 docs/ADRs/* files deleted (12k lines).
- Why
- docs/ADRs/ was a read-on-demand Tier 5 artifact that agents and contributors had to remember to consult. Path-scoped .claude/rules/*.md files auto-load when touching matching files, making the knowledge appear precisely when needed.
- Areas
- docs/ADRs+0−12081.claude/rules+193−8packages/shared-kernel+217−79packages/api+112−45packages/database+12−7.claude/skills+14−10scripts/one-api+419−0domains/utility+3−3
- Blast
- 55 files, +6303/−12319; dominated by docs/ADRs deletion (−12k). Functional code changes are comment-only (3 schema files). Rule content additions total ~200 lines across 5 rule files.
Findings · 18
correctness3
README.md points to non-existent .claude/rules/ auth rules — ADR-008 was not distilled
domains/core/README.md:76
Line 76 says 'See .claude/rules/ auth rules for detailed architecture (historically ADR-008)' but no auth*.md rule file exists. A developer following this pointer finds nothing.
INTEGRATION_STANDARDS.md line 7 retains 'on top of ADR-011' inline without redirect
services/metrics/integrations/INTEGRATION_STANDARDS.md:7
Line 5 was correctly updated but line 7 still reads 'additions on top of ADR-011' with no pointer to .claude/rules/infrastructure.md where those conventions now live.
docs/architecture/*.md files have broken relative links to now-deleted ADR files
docs/architecture/2.4-cfe-architecture-v2.md
2.4-cfe-architecture-v2.md and 2.4-cfe-bill-collection-engine-architecture.md link to docs/ADRs/013, 016, etc which were deleted in this commit.
security4
REVOKE rule omits service_role without explaining why
.claude/rules/rls-checklist.md
The rule says REVOKE FROM 'authenticated, anon, public' but never explains that service_role is a superuser where EXECUTE revoke has no effect. A future author may try to add it (breaking backend) or wonder if it's missing. Add: 'service_role intentionally omitted — it is a superuser; revoking EXECUTE has no effect'.
Existing SECURITY DEFINER helpers (get_user_org_ids, get_user_admin_org_ids) have no REVOKE — inconsistent with the new rule
packages/database/drizzle/0019_rls_helpers_and_storage.sql
The new rule says 'any new SECURITY DEFINER function ships with REVOKE' but the canonical helper examples don't have one. A future AI-authored migration could cite them as precedent and omit REVOKE on a more dangerous function. Rule should carve out 'RLS helpers scoped to auth.uid() are an exception' or ship a retroactive REVOKE.
Trigger-returning function REVOKE exemption is correct but lacks the reasoning
.claude/rules/rls-checklist.md
The rule says 'Trigger-returning functions are not RPC-exposable and need no revoke' with no explanation. Add: 'PostgreSQL prevents direct invocation of RETURNS TRIGGER functions — they require a trigger call frame and cannot be invoked via SQL or PostgREST'.
CDC parse-failure log guarantee partially depends on caller not logging raw onParseError argument
.claude/rules/contracts-read-model.md
The claim 'parse-failure logs never include row contents' holds for current callers but would silently break if a future consumer wires up an onParseError callback that logs the raw argument.
conventions6
contracts-read-model.md path glob misses packages/database/src/schema/utility-contract-overview.ts
.claude/rules/contracts-read-model.md
The Drizzle schema file is where engineers make column/policy changes that this rule guards. Without it in the glob the rule never auto-loads when editing that file. Add 'packages/database/src/schema/utility-contract-overview.ts' to the paths frontmatter.
New cross-domain _tag uniqueness rule conflicts with existing code (ContractNotFound defined in two files)
.claude/rules/domain-patterns.md
domains/utility/src/cfe-job/cfe-job.errors.ts and utility-contract.errors.ts both define ContractNotFound; JobNotFound appears in cfe-job.errors.ts and tariff-job.errors.ts. The rule is correct as aspiration but immediately misleads a contributor who finds existing duplicates. Needs a note that existing duplicates are grandfathered and renamed on next touch.
doc-check SKILL.md description field still says 'ADRs' and Step 3 has dead guidance
.claude/skills/doc-check/SKILL.md
The table row was updated but the frontmatter description says '…detect structural changes (new entities, ADRs, packages…)' and Step 3 says '- Root CLAUDE.md Architecture References (if new ADRs added)'. Both need updating.
scope.md template and create-pr skill still have 'Relevant ADRs' sections
.claude/templates/scope.md
scope.md template has '## Relevant ADRs & Patterns' with ADR-0XX placeholder; create-pr SKILL.md has '### ADRs Referenced'; intent.md has '- ADRs consulted'. Should be renamed to Relevant Rules & Patterns.
branch-provisioning SKILL.md scope.md field still called 'Relevant ADRs'
.claude/skills/branch-provisioning/SKILL.md
Step 2 lists '- **Relevant ADRs**: Which architecture decisions apply and how' as a required scope.md field. Should be '- **Relevant Rules**: Which .claude/rules/*.md files apply and how'.
infrastructure.md ## Account Segmentation (ADR-011) heading lacks retirement notice
.claude/rules/infrastructure.md
Unlike domain-patterns.md and contracts-read-model.md, the infrastructure.md heading just uses 'ADR-011' without a retirement note. Should add '(historically ADR-011 — ADR file retired; this section is its home)'.
tests2
No CI check enforces SECURITY DEFINER + REVOKE pairing in migrations
.github/workflows/
check-rls-coverage.ts validates table policies but does not scan migration SQL for unpaired SECURITY DEFINER / REVOKE. A grep in pr-checks.yml scanning .sql files would close this gap.
Cross-domain _tag uniqueness has no compile-time or runtime check
domains/cross-domain/src/
The uniqueness guarantee rests on naming discipline. A type-level AssertNoTagCollision helper would mechanically enforce this if cross-domain coordinator error composition becomes a pain point.
improvement3
Escape hatch 'skip the shell for a simple read' is unsafe for org-scoped tables without an RLS caveat
.claude/rules/domain-patterns.md
The rule says 'Skip the shell for a simple read touching one table with no events and no authorization logic.' In this codebase RLS is only active inside a createRLSDb() transaction — a raw db.select() outside of one runs as service_role and bypasses all row-level policies. A contributor reading this escape hatch for an org-scoped table (bills, contracts, sites) would skip createRLSDb() and silently leak cross-org data. Must add: 'org-scoped reads must still use createRLSDb() even without events — see rls-checklist.md. Only skip the shell for tables that are intentionally service_role-only (outbox, idempotency).' rls-checklist.md already warns about this but domain-patterns.md's escape hatch contradicts it without cross-referencing.
SECURITY DEFINER REVOKE rule duplicated verbatim in rls-checklist.md AND contracts-read-model.md
.claude/rules/contracts-read-model.md
Both files have nearly identical paragraphs about REVOKE EXECUTE including the same 0046 incident. Duplicate normative rules drift. contracts-read-model.md should reduce to a one-line cross-reference to rls-checklist.md § Helper Functions.
BAT-152 issue number in canonical-form.md prescriptive rule will become opaque over time
.claude/rules/canonical-form.md
The 'Audit before reshaping' paragraph cites 'BAT-152 SG-2' as a motivating example. Issue numbers are opaque to readers without Linear access. The same paragraph already names the concrete artifacts (periodsPersisted, persistedBillFiles) — these are self-contained. Drop the issue citation or replace with the PR number.
History · 47 commits
- 82bb5b9blockedincremental5H · 5M · 4L2026-08-12 01:48
- 90aa3d5needs attentionincremental1H · 5M · 3L2026-08-11 19:37
- 29d19a0needs attentionincremental1H · 5M · 9L2026-08-11 17:41
- 9bd8a0cneeds attentionfull0H · 5M · 9L2026-08-11 02:14
- 62ec3f7needs attentionincremental2H · 5M · 6L2026-08-10 22:51
- f93bca9needs attentionincremental2H · 5M · 8L2026-08-10 17:51
- 052db6fneeds attentionincremental1H · 3M · 4L2026-08-09 21:13
- 45699caneeds attentionincremental0H · 7M · 11L2026-08-09 17:44
- b843d8aneeds attentionincremental1H · 7M · 9L2026-08-09 04:05
- e1757b8needs attentionincremental0H · 3M · 6L2026-08-05 02:11
- 7a762faneeds attentionincremental2H · 5M · 5L2026-08-05 01:25
- 3300a60needs attentionincremental2H · 4M · 7L2026-08-04 19:06
- 0c8a7f5needs attentionincremental0H · 4M · 9L2026-08-04 18:15
- 345f42eneeds attentionincremental2H · 6M · 9L2026-08-04 17:28
- 8338a9aneeds attentionincremental5H · 14M · 14L2026-08-04 00:33
- 41be4c3needs attentionincremental0H · 5M · 7L2026-08-03 23:49
- 5ed593dneeds attentionincremental1H · 6M · 6L2026-08-03 21:32
- b333e25needs attentionincremental4H · 9M · 8L2026-08-03 21:00
- 5642cccneeds attentionincremental2H · 3M · 2L2026-08-03 20:17
- 73b0b39needs attentionincremental3H · 10M · 13L2026-07-31 18:29
- b19852eneeds attentionincremental0H · 1M · 5L2026-07-29 05:04
- 3845205needs attentionincremental3H · 6M · 4L2026-07-29 04:47
- eb8eb50needs attentionincremental0H · 1M · 2L2026-07-29 03:03
- f4720a3needs attentionincremental6H · 8M · 7L2026-07-29 02:54
- f8d341ablockedincremental2H · 2M · 5L2026-07-29 00:00
- a7f1a64needs attentionincremental2H · 8M · 8L2026-07-28 18:41
- 738b60bblockedincremental3H · 6M · 5L2026-07-28 00:46
- 2c248b6needs attentionincremental8H · 12M · 8L2026-07-27 23:23
- 1346cc0needs attentionincremental2H · 8M · 6L2026-07-27 20:15
- 0716018needs attentionincremental2H · 11M · 12L2026-07-27 19:22
- 215cd2dneeds attentionincremental3H · 6M · 5L2026-07-27 17:04
- ec46958needs attentionincremental0H · 3M · 5L2026-07-27 16:51
- de7b337blockedincremental4H · 9M · 14L2026-07-27 06:36
- b1bb9c0needs attentionincremental1H · 2M · 4L2026-07-27 05:09
- 4701d11needs attentionincremental0H · 4M · 3L2026-07-27 04:44
- e1626c4needs attentionincremental3H · 9M · 10L2026-07-27 03:21
- 195f198needs attentionincremental3H · 3M · 3L2026-07-25 01:22
- 42c7358safeincremental0H · 0M · 0L2026-07-22 20:46
- 85b9018needs attentionincremental0H · 1M · 6L2026-07-21 23:51
- a7b2a9aneeds attentionincremental0H · 9M · 12L2026-07-21 18:49
- c2ee0daneeds attentionincremental4H · 7M · 7L2026-07-21 02:17
- e8ffa5eneeds attentionincremental4H · 7M · 5L2026-07-21 01:33
- a2d2a54needs attentionincremental2H · 7M · 3L2026-07-21 00:51
- 576fbd6needs attentionfull1H · 6M · 7L2026-07-21 00:35
- d3465e8needs attentionincremental1H · 7M · 10L2026-07-21 00:23current
- dc794a7needs attentionincremental0H · 5M · 5L2026-07-20 23:46
- 9082773needs attentionfull1H · 3M · 3L2026-07-20 23:13