← all branches

feat/one-api

needs attentionviewing older commit
29d19a0 · incrementalpre-PRreviewed 2026-08-11 17:41 UTC1H · 5M · 9L · 1I
The branch
Purpose
Harden the one-API surface: RLS isolation, machine-caller isolation, cross-org leak prevention, entity_relationships removal, service keys, utility-contracts API, telemetry.
Goal
Close all known security and correctness gaps before shipping feat/one-api to main. 50+ commits across 15+ rounds of review.
Sub-goals
  • SG-1: RLS isolation for all reads and writes
  • SG-2: Machine-caller (service key) isolation
  • SG-3: entity_relationships table and path removal (BAT-301)
  • SG-4: Utility-contracts API revival + CI gating
  • SG-5: Ratified design decisions documented (BAT-298, DROP POLICY)
The changes (whole branch)
What
Revived utility-contracts API integration suite (stale JWT re-login, vacuous search fix, sitePublicId assertion), wired suite into CI, ratified no-proof RPU claiming and bare-DROP-POLICY decisions.
Why
Suite was silently broken since JWT moved to claims-driven (BAT-135). Two design decisions needed CTO ratification to stop review panels re-flagging them.
Areas
apps/platform+45474130domains/core+13823342packages/api+6811380packages/database+1000351domains/cross-domain+720299.claude/rules+60433domains/utility+237335scripts/one-api+78303
Blast
245 files, +10851/-10676 across the full branch. Incremental this commit: 6 files, +98/-27.
test-fragility ci-gate-condition
CI / GitHub checks· gh not authenticated — CI status unavailable for pre-PR branchCodeRabbit· No .coderabbit.yaml present

Findings · 16

correctness2

medium

testContractRpu undefined if first test fails — TypeError masks root cause

apps/platform/src/__tests__/integration/utility-contracts-api.test.ts:364

Same as tests/high but noted from correctness angle — the crash is a TypeError from undefined.slice, not a test assertion failure, hiding the real issue.

low

eval silent-succeeds if supabase status returns non-JSON — ANON_KEY left unset

.github/workflows/pr-checks.yml:437

If supabase status returns non-JSON, python3 exits nonzero but eval of empty string succeeds. Add set -euo pipefail at top of run block.

security1

low

Ephemeral keys visible under ACTIONS_STEP_DEBUG — add ::add-mask::

.github/workflows/pr-checks.yml:437

Keys are localhost-only; masking is standard hygiene. Add echo '::add-mask::$SUPABASE_SERVICE_ROLE_KEY' after eval.

conventions3

low

Pervasive 'what' comments in test setup (pre-existing)

apps/platform/src/__tests__/integration/utility-contracts-api.test.ts:21

Many comments describe what the code does rather than why. Convention: one short WHY line max.

low

New multi-line comment blocks in two test cases exceed one-line rule

apps/platform/src/__tests__/integration/utility-contracts-api.test.ts:212

5-line and 3-line blocks in the new/renamed tests. Compress to one line each.

low

Test naming mix: 'should X' vs behavior-first in same file

apps/platform/src/__tests__/integration/utility-contracts-api.test.ts:173

Pre-existing debt — corrected test sets the right pattern but siblings are not aligned.

tests5

high

testContractRpu ordering dependency — undefined.slice throws TypeError on skip/fail

apps/platform/src/__tests__/integration/utility-contracts-api.test.ts:364

testContractRpu is assigned in 'should create contract with site info' and used unguarded in 'should search by RPU'. If first test is skipped or fails, .slice(0,8) throws TypeError masking the root cause. Guard: if (!testContractRpu) throw new Error('Prerequisite test did not run').

medium

isMonitored filter test passes vacuously on empty result set

apps/platform/src/__tests__/integration/utility-contracts-api.test.ts:357

Array.every() returns true for []. If creation test failed, the assertion still passes. Add: expect(matched.length).toBeGreaterThan(0).

medium

Cloud getTestUserToken fast path bypasses custom_access_token_hook — membership claims missing if userId ever passed

apps/platform/src/__tests__/helpers/supabase-helpers.ts:170

Current call (no userId) is correct for local CI. If CI switches to cloud Supabase, the re-login mints a hook-free JWT and every membership-gated handler silently 401s, regressing to pre-fix state.

low

Duplicate RPU test orphans a site + contract in shared DB

apps/platform/src/__tests__/integration/utility-contracts-api.test.ts:264

First successful contract in duplicate-RPU test never tracked for cleanup — leaks into shared test DB.

info

No negative test pinning stale-token rejection

apps/platform/src/__tests__/integration/utility-contracts-api.test.ts:134

Root cause (pre-org token rejected) only documented by comment; a failing negative test would prevent future regression.

improvement5

medium

Replace python3 key-extraction with jq (already on runner)

.github/workflows/pr-checks.yml:437

jq is on ubuntu-latest. Simpler: eval "$(supabase status --output json | jq -r '\"export NEXT_PUBLIC_SUPABASE_ANON_KEY=\" + .ANON_KEY, \"export SUPABASE_SERVICE_ROLE_KEY=\" + .SERVICE_ROLE_KEY')"

medium

Pass owner.user.id on re-login to avoid redundant GoTrue round-trip

apps/platform/src/__tests__/integration/utility-contracts-api.test.ts:133

getTestUserToken(owner.email, owner.password, owner.user.id) skips signInWithPassword on local fast path. Consider a refreshTokenForUser(user) helper for reuse across suites.

low

Search term slice(0,8) causes all test-run contracts to match — assertion weaker than it appears

apps/platform/src/__tests__/integration/utility-contracts-api.test.ts:364

All Date.now()-based RPUs share first 8 digits. Use testContractRpu.slice(-6) or full RPU for a unique match.

low

URL query string in search test is unused by direct handler call

apps/platform/src/__tests__/integration/utility-contracts-api.test.ts:367

Handler reads from args.query; the url: query string is ignored. Remove or document.

low

NEXT_PUBLIC_SUPABASE_ANON_KEY should be in env: block for auditability

.github/workflows/pr-checks.yml:445

Sibling steps declare it in env:. This step sets it via eval side-effect — asymmetric.

History · 47 commits

  1. 82bb5b9blockedincremental5H · 5M · 4L2026-08-12 01:48
  2. 90aa3d5needs attentionincremental1H · 5M · 3L2026-08-11 19:37
  3. 29d19a0needs attentionincremental1H · 5M · 9L2026-08-11 17:41current
  4. 9bd8a0cneeds attentionfull0H · 5M · 9L2026-08-11 02:14
  5. 62ec3f7needs attentionincremental2H · 5M · 6L2026-08-10 22:51
  6. f93bca9needs attentionincremental2H · 5M · 8L2026-08-10 17:51
  7. 052db6fneeds attentionincremental1H · 3M · 4L2026-08-09 21:13
  8. 45699caneeds attentionincremental0H · 7M · 11L2026-08-09 17:44
  9. b843d8aneeds attentionincremental1H · 7M · 9L2026-08-09 04:05
  10. e1757b8needs attentionincremental0H · 3M · 6L2026-08-05 02:11
  11. 7a762faneeds attentionincremental2H · 5M · 5L2026-08-05 01:25
  12. 3300a60needs attentionincremental2H · 4M · 7L2026-08-04 19:06
  13. 0c8a7f5needs attentionincremental0H · 4M · 9L2026-08-04 18:15
  14. 345f42eneeds attentionincremental2H · 6M · 9L2026-08-04 17:28
  15. 8338a9aneeds attentionincremental5H · 14M · 14L2026-08-04 00:33
  16. 41be4c3needs attentionincremental0H · 5M · 7L2026-08-03 23:49
  17. 5ed593dneeds attentionincremental1H · 6M · 6L2026-08-03 21:32
  18. b333e25needs attentionincremental4H · 9M · 8L2026-08-03 21:00
  19. 5642cccneeds attentionincremental2H · 3M · 2L2026-08-03 20:17
  20. 73b0b39needs attentionincremental3H · 10M · 13L2026-07-31 18:29
  21. b19852eneeds attentionincremental0H · 1M · 5L2026-07-29 05:04
  22. 3845205needs attentionincremental3H · 6M · 4L2026-07-29 04:47
  23. eb8eb50needs attentionincremental0H · 1M · 2L2026-07-29 03:03
  24. f4720a3needs attentionincremental6H · 8M · 7L2026-07-29 02:54
  25. f8d341ablockedincremental2H · 2M · 5L2026-07-29 00:00
  26. a7f1a64needs attentionincremental2H · 8M · 8L2026-07-28 18:41
  27. 738b60bblockedincremental3H · 6M · 5L2026-07-28 00:46
  28. 2c248b6needs attentionincremental8H · 12M · 8L2026-07-27 23:23
  29. 1346cc0needs attentionincremental2H · 8M · 6L2026-07-27 20:15
  30. 0716018needs attentionincremental2H · 11M · 12L2026-07-27 19:22
  31. 215cd2dneeds attentionincremental3H · 6M · 5L2026-07-27 17:04
  32. ec46958needs attentionincremental0H · 3M · 5L2026-07-27 16:51
  33. de7b337blockedincremental4H · 9M · 14L2026-07-27 06:36
  34. b1bb9c0needs attentionincremental1H · 2M · 4L2026-07-27 05:09
  35. 4701d11needs attentionincremental0H · 4M · 3L2026-07-27 04:44
  36. e1626c4needs attentionincremental3H · 9M · 10L2026-07-27 03:21
  37. 195f198needs attentionincremental3H · 3M · 3L2026-07-25 01:22
  38. 42c7358safeincremental0H · 0M · 0L2026-07-22 20:46
  39. 85b9018needs attentionincremental0H · 1M · 6L2026-07-21 23:51
  40. a7b2a9aneeds attentionincremental0H · 9M · 12L2026-07-21 18:49
  41. c2ee0daneeds attentionincremental4H · 7M · 7L2026-07-21 02:17
  42. e8ffa5eneeds attentionincremental4H · 7M · 5L2026-07-21 01:33
  43. a2d2a54needs attentionincremental2H · 7M · 3L2026-07-21 00:51
  44. 576fbd6needs attentionfull1H · 6M · 7L2026-07-21 00:35
  45. d3465e8needs attentionincremental1H · 7M · 10L2026-07-21 00:23
  46. dc794a7needs attentionincremental0H · 5M · 5L2026-07-20 23:46
  47. 9082773needs attentionfull1H · 3M · 3L2026-07-20 23:13