Appearance
Operating-manual corrections log
CLAUDE.md used to record every correction beside the sentence it corrected — "this said X until 2026-08-28" — which is how it reached 3,677 lines with 81 such lines (measured 2026-09-23). Under the context-architecture programme (QRS-1288) a wrong sentence is replaced in place and its history is recorded here, append-only. This page is Tier 4: never auto-loaded, read when you need to know why a rule reads as it does.
How to read this table
Each row is one dated correction exactly as CLAUDE.md carried it at commit 00c1eca, with the section it sat in. The live fact now lives in the destination page named in Claude context architecture § 9 for that section; the row here is the history. Retired vocabulary inside a row names what was retired — it is not a live claim.
How to add a row
- Replace the wrong sentence in the live page or rule with the correct one — no annotation beside it.
- Append a row here: date · where it lived · what it said · what is true · the
QRS-###. - If the correction changes a rule's short form, regenerate
CLAUDE.mdwithnpm run check:context -- --write.
The 81 corrections carried by CLAUDE.md on 2026-09-23
| Old line | Section | The correction as recorded |
|---|---|---|
| 30 | Header & inventory | > is i-m-sharing-my-other-indexed-wozniak.md (measured 2026-08-28). The document this file declares |
| 48 | What QRSETU is | > ⚠ THE "THREE PILLARS / THREE PRODUCTS" FRAMING IS RETIRED, AND THIS SECTION TAUGHT IT UNTIL 2026-08-12. |
| 52 | What QRSETU is | > reason — while check:docs did not scan this file until 2026-08-24 (QRS-567), and it does now — a live run |
| 62 | What QRSETU is | Cloudflare Workers (+ CDN caching) — ⚠ not Pages, and this said Pages until 2026-08-28. |
| 120 | Three user categories | 2026-08-13, and this bullet said the OPPOSITE until then].** It read: *"Category 3 is the marketplace |
| 136 | Three user categories | FUTURE work until 2026-08-28.** Consumers live in their own **apps/mobile/src/tiers/consumer/ |
| 257 | First rule: toolchain | in the repo (measured 2026-08-28; guides/ holds 16 other pages). Cross-platform setup steps are |
| 282 | Second rule: Dev is SSOT | schema decision in this repo until 2026-08-07 was taken against it — which is how the drift kept |
| 381 | Third rule: automate the check | this said "1:1" until 2026-08-28); contract-file controls asserted against testIDs for STRUCTURE |
| 513 | Fifth rule: gating controls access | written in ADR-0021**, which this file asserted until 2026-08-28; grep it and you will not find it. |
| 524 | Fifth rule: gating controls access | obey this rule, and every one of them did until 2026-08-15 — the three source fields existed, were |
| 570 | Fifth rule: gating controls access | tier must obey today, not one it inherits on creation. ⚠ It said the opposite until 2026-08-28, |
| 598 | Sixth rule: promotion is measured | > and diffs them, and this sentence denied it existed until 2026-08-28. What is genuinely missing is a |
| 796 | Engineering standards | "enforced in CI" until 2026-08-28.** Zero hits for bundle-size / bundlesize / web-vitals / |
| 811 | Engineering standards | and is built and at parity with Android as of 2026-08-02; the transitional iOS PWA is retired. |
| 931 | Engineering standards | claimed a guarded-build preflight until 2026-08-28. An agreement nobody checks decays silently; that is precisely how C: refilled twice. |
| 995 | Engineering standards | until 2026-08-28** — which is this section's own lesson landing on this section. Re-measured: |
| 997 | Engineering standards | schema_migration), and delivery-log.md holds 74 distinct entries as of 2026-08-28 (47 numbered ids + 27 |
| 1024 | Engineering standards | - ⚠ It was a BLANKET AMNESTY until 2026-08-12, and the broken version looked correct. The gate read |
| 1133 | Commands | # ⚠⚠ AND IT NEVER RAN AT ALL ON WINDOWS UNTIL 2026-09-07 |
| 1214 | Commands | # ⚠⚠ IT DID NOT SCAN CLAUDE.md OR README.md UNTIL 2026-08-24, |
| 1369 | Commands | # ⚠ NOT 1:1 with it, and this line said "1:1" until 2026-08-28: |
| 1380 | Commands | # ⚠⚠ S3 SWEPT tiers/user ONLY UNTIL 2026-09-04, so for every |
| 1481 | Commands | # anywhere in the repo (measured 2026-08-24 by enumerating every |
| 1730 | Commands | # STOCK VITEPRESS INDIGO until 2026-08-18, i.e. the docs for a |
| 1816 | Commands | # ⚠ It went UNDOCUMENTED here until 2026-08-13, found by widening |
| 1883 | Commands | # ⚠ AND THE CARD IS NOT AT /:slug — measured 2026-08-24, and this file said /:slug in four places. |
| 1923 | Commands | THREE unit-test runners, split by workspace (this said "two" until 2026-08-12, before apps/web existed): |
| 2015 | Commands | that attribute** (this said "both" until 2026-08-28); |
| 2082 | Commands | (npm run test:hooks, 50/50 green as of 2026-08-24; it read "32/32 as of 2026-08-17" until then) |
| 2085 | Commands | ⚠ **This paragraph named FOUR of the seven until 2026-08-17, and session-preview-staleness.mjs was |
| 2155 | Where the code lives | built" until 2026-08-28. The merchant desktop console (/merchant/*) and the |
| 2186 | Mobile app structure | create.tsx in the present tense until 2026-08-28. The tier has since gained banking, |
| 2191 | Mobile app structure | the top of this file** — it said "Eight" until 2026-08-13 and there were eleven, the three |
| 2206 | Mobile app structure | - Three src/ directories this file omitted until 2026-08-12: src/dev/, src/release/, and — the one |
| 2215 | Mobile app structure | than hand-paired constants. ⚠ This said user ⇎ admin only, until 2026-08-28; |
| 2221 | Data access | > ⚠ THIS RULE IS HONOURED BUT NOT ENFORCED, and it was tagged [ENFORCED] until 2026-08-12. |
| 2236 | Data access | until 2026-08-13, omitting orders and setuCardEditor). Which of them are actually |
| 2298 | Platform model | ⚠ It is NOT lint-gated, and this said "lint-gated" until 2026-08-28 — archetype has zero |
| 2340 | Setu Card & templates | renderer exists in apps/web; this said "nothing is built yet" until 2026-08-28 — this is Phase 0 documentation, written before the code, per D10 below. |
| 2352 | Setu Card & templates | status, feature_code, — ⚠ this called it card_templates until 2026-08-28, and no such table |
| 2387 | Setu Card & templates | profiles was dropped by the ADR-0020 baseline and this cited it until 2026-08-28**; no vendor data ever moves, |
| 2432 | Setu Card & templates | - ⚠ **CACHE INVALIDATION IS WIRED — this bullet claimed the opposite until 2026-08-12 and the claim was |
| 2509 | Payments | "CURRENTLY-TRUE" UNTIL 2026-08-28.** Keep the original measurement as the record of why they mattered; |
| 2531 | Supabase client | that module** (measured 2026-08-28), and the file explains why. It is a DI'd factory, |
| 2548 | Supabase client | listed it as an exception until 2026-08-28. context has no stub at all — workspaces: [] is a valid answer, so a test |
| 2552 | Supabase client | "2 of 7" until 2026-08-03 (really 4 of 9), "4 of 9" until 2026-08-12 (really 9 of 13), and |
| 2553 | Supabase client | "9 of 13" until 2026-08-13 — where the numerator was finally right and the denominator was stale |
| 2583 | Supabase client | looking in the wrong place — that misread is most of why this bullet said what it said. |
| 2620 | Edge Functions | pinned to 2.111.0 — ⚠ this said 2.30.0 until 2026-08-28; two different numbers on purpose, and backend/shared-kit.md gave the frontend's as |
| 2621 | Edge Functions | the pin until 2026-08-12). |
| 2642 | Edge Functions | "eleven" (of which seven were archived and five never existed), then "SIX" until 2026-08-13. |
| 2652 | Edge Functions | it carries SEVEN verify_jwt = false entries** (measured 2026-08-28), razorpay-webhook among |
| 2655 | Edge Functions | declared verify_jwt = true, and manage-order was declared in the same change. This bullet read |
| 2670 | Edge Functions | - manage-profile is NOT the reference implementation any longer, though this file said so until |
| 2676 | Edge Functions | named nowhere in this file until 2026-08-28: commission.ts, r2.ts, workspace.ts, plus |
| 2705 | Design system | ⚠ THERE ARE TWO CLAUDE DESIGN PROJECTS AND THIS SECTION NAMED ONLY ONE UNTIL 2026-08-09 (QRS-451). |
| 2716 | Design system | > ⚠⚠ AND THE DESKTOP CONSOLE CARRIES AN UNRESOLVED CONFLICT WITH ADR-0011 THAT IS NOT A DETAIL. SCREENS.md specifies it as "a SEPARATE route group in apps/web, DOM/React over shadcn/Radix primitives … not React Native Web and not a scaled phone screen" — i.e. a second implementation of the merchant product, 16 screens, in the idiom apps/web does not have (measured 2026-08-20 and ** … |
| 2748 | Screen that does not exist | > ⚠ The "consumer dashboard" was listed here as undesigned until 2026-08-13 and it is not. The design |
| 2765 | Screen that does not exist | that was missing until 2026-08-09 (QRS-448).** All four parts are required; doing three of them |
| 2811 | Screen that does not exist | - ⚠ THIS STEP SAID "INHERITS" UNTIL 2026-08-29, AND THAT WORD WAS THE DEFECT. Placement next |
| 2848 | Screen that does not exist | ⚠ THE DOM HALF HAS STARTED, AND THIS PARAGRAPH SAID IT "DOES NOT EXIST" UNTIL 2026-08-22. It read: |
| 2871 | Screen that does not exist | Plus Jakarta Sans until 2026-08-28; that is webFonts.ui, the DOM stack, a different symbol; Devanagari/mixed = Noto Sans Devanagari |
| 2937 | Naming | (⚠ "fifteen" until 2026-08-28). Rather |
| 3100 | Lint & format | (⚠ this named only check:readmes until 2026-08-28) (ESLint --fix --max-warnings=0 + Prettier on |
| 3133 | Testing model | profiles-era files until 2026-08-28. |
| 3139 | Testing model | ⚠ "Every rule is mutation-tested" WAS FALSE and this line asserted it until 2026-08-24. There is no |
| 3274 | Environments & CI | ⚠ This bullet asserted "SEVEN workflows exist" until 2026-08-17 and there were EIGHT — it omitted |
| 3280 | Environments & CI | ⚠ This file claimed "No deploy workflow exists yet" until 2026-08-12; deploy-prod.yml does exist. |
| 3300 | Environments & CI | metrics, and this said "still un-bootstrapped" until 2026-08-28. The first two attempts never |
| 3339 | Environments & CI | until 2026-08-28), which strengthens rather than weakens the case below. The shared @/ui async primitive that collapses them is **deliberately not |
| 3367 | Environments & CI | |
| 3435 | Dev portal & tracker | and — ⚠ omitted from this list until 2026-08-28 — communications/, payments/ and strategy/, |
| 3444 | Dev portal & tracker | **verticals/ was missing from this list entirely until 2026-08-12, which is a real gap rather than an |
| 3448 | Dev portal & tracker | (21 pages), which this list omitted entirely until 2026-08-28** — plus _template/discovery.md, |
| 3465 | Dev portal & tracker | ⚠ **That trigger fired long ago — the log stands at 74 distinct entries as of 2026-08-28 (47 numbered ids + 27 |
| 3469 | Dev portal & tracker | the sequence — six gaps, where this line recorded one until 2026-08-28. |
| 3496 | Dev portal & tracker | 0001-0012, 0014-0017, 0019-0032** — ⚠ this stopped at 0028 until 2026-08-28; ADR-0029 |
| 3559 | Frontend platform | until 2026-08-24, in the same file that lists /b/ /s/ /w/ as archived vocabulary) and |
| 3627 | check:docs | said 124/123 until 2026-08-28; the gate prints all four numbers, so read them off a run |
| 3630 | check:docs | ⚠ **IT DID NOT SCAN CLAUDE.md OR README.md UNTIL 2026-08-24 (QRS-567, now CLOSED), AND BOTH HAD |
The two header banners CLAUDE.md carried until 2026-09-23
Provenance — moved from CLAUDE.md on 2026-09-23 (QRS-1288)
Verbatim text of the two banner paragraphs that sat under the generated inventory block (commit 00c1eca). Both are history: the plan file they name no longer exists, and the pillar framing they warn about was retired 2026-07-23.
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
This repo is executing an approved production-standards program. The authoritative, full plan is at ⚠ a plan file that NO LONGER EXISTS —
C:\Users\bnlah\.claude\plans\holds four files and none isi-m-sharing-my-other-indexed-wozniak.md(measured 2026-08-28). The document this file declares authoritative over itself is a dangling reference, and it propagated tomemory/qrsetu-standards-plan.mdandsupabase/docs/PROMOTION_RUNBOOK.md.nefoxx-reference-docs/— the proven patterns from the sibling NEFOXX platform — DOES exist, and that half being true is what made the whole sentence read as verified. This file is the day-to-day operating manual and must stay aligned with that plan. The codebase is mid-transition: some standards below are already enforced, others are being retrofitted feature-by-feature (strangler-fig). Each standard is tagged [ENFORCED] (applies to all new code now; migrate existing when you touch it) or [TRANSITIONAL] (current reality that the plan is moving away from — do not add to it).
Corrections made 2026-09-24, after the first /compact (QRS-1288, QRS-1289)
Provenance
Found by reading the new CLAUDE.md back after the owner's /compact, and by the transcript's hook_success entries. Each sentence below was replaced in place; this is the only record of the old text.
| Where | Said | Now says | Measured by |
|---|---|---|---|
CLAUDE.md §0 | "Where new knowledge goes: §10" | §11 (§10 is Environments) | reading the file |
CLAUDE.md §7 repo map and §8 lead-in | .claude/context-routing.json | .claude/context-map.json (the routing file no longer exists) | ls .claude/*.json |
CLAUDE.md §7 | "Nested CLAUDE.md files … load when you work there" | they are mandatory reads in their layer rule | Phase 8: created mid-session they did not load, main session or subagent; a fresh session is still untested |
CLAUDE.md §11.3 | area invariants go in .claude/rules/<area>.md (≤ 60 lines, with paths:) | in the area's manifest (a context-map.json layer or the domain page's context:) | the rules are generated since approach C; a hand-written rule fails G3 |
guides/claude-context-architecture.md §1 finding, §1.1 table, §1.8, §2, §14, §15 row 11, §19, Re-measured | the SessionStart hook injects project-state.md in full, ~49K tokens every session; fixed load ~178K | the hook printed it, the harness delivered a 2 KB preview (~750 tokens); fixed load ~130K | the transcript: "Output too large (130KB) … Preview (first 2KB)" at session start and after /compact (QRS-1289) |
tools/hooks/pre-compact-state.mjs | "After compaction, that file is re-injected automatically by the SessionStart hook" | an EXTRACT is re-injected, with each thread's line range | QRS-1289 |
tools/hooks/session-state.mjs header | "puts the project-state record into context" (the whole body) | prints an extract within the hook budget | QRS-1289 |
Corrections made 2026-09-24, running /init (QRS-1290, QRS-1291)
| Where | Said | Now says | Measured by |
|---|---|---|---|
CLAUDE.md §0 | "Ceilings: npm run check:context (350 lines, 35,000 chars; …)" | check:context ratchets at the measured size; growth needs a Context-Ceiling: trailer | .claude/context-ceiling.json held 264 lines / 27,186 chars; no 350 or 35,000 limit in tools/check-context-map.mjs |
CLAUDE.md §9 Pre-push row | 12 gates, ending "check:qa-suite · e2e:quick" | the 11 that .husky/pre-push runs; e2e:quick is not among them (QRS-1292) | .husky/pre-push, whose header says the web e2e suite is "Deliberately NOT here" |
CLAUDE.md §8 auth route (from .claude/context-map.json) | "ADR-0018 is cited by 25 files and does not exist" | "ADR-0018 is cited but does not exist" (QRS-1291) | grep found 14 .md files or 51 across code and SQL, never 25; the count had no stated scope |
Corrections made 2026-09-28, the Admin Panel MVP assessment (QRS-1422)
Provenance
Found by re-reading the repo while assessing the Admin Panel MVP (QRS-1404). Each sentence below was replaced in place in the page named; this is the only record of the old text.
| Where | Said | Now says | Measured by |
|---|---|---|---|
architecture/admin-portal-backend-assessment.md: the one-line finding, §4.1 map, §6 table, §6.1, §8 matrix (User management, Audit logs), §9 item 5, §13 G3 | audit_log has "zero rows and zero writers" · "0 WRITERS" · "no writer" · "no function or trigger writes to it (69 functions inspected)" · "A writer." · "audit writer" | zero rows and no ADMIN writer; its one writer is set_my_primary_context, which inserts a row, best-effort, when a principal changes their own primary context | 20260817230500_v2_set_my_primary_context.sql:104, the only insert into public.audit_log in the live migrations (grep); no Edge Function names audit_log. The migration predates the page's 2026-08-26 measurement, so the claim was wrong that day (QRS-1422) |
| same page: §4 table, §4.1 map, §5.1, §8 matrix (Roles & permissions), §12 item 4 | role_key "is read by NO policy and NO function" · "enforced by NOTHING" · "stored, enforced by nothing" | read by no policy and by exactly one function: set_workspace_location refuses unless the caller's active membership holds owner or admin; get_my_context only projects it | 20260822140000_v2_set_workspace_location.sql:76-83 (QRS-1422) |
| same page: §7.4, §8 matrix (Communication (WhatsApp)), §11.4 | "No table anywhere for … WhatsApp templates, campaigns, consent or message ledger" · Communication (WhatsApp) "🔴 not supported", owing "Everything in ADR-0029/0030 … templates … message log" · "WhatsApp everything" | the template registry and the outbound message ledger exist, added after the measurement by 20260901120000_v2_communications_whatsapp.sql; still missing: consent, suppression, campaigns, inbound, template-status sync, cost | the migration's five create table lines (:47, :84, :131, :190, :332) and the registry seed (20260901140000_v2_whatsapp_registry_seed.sql:81-87) (QRS-1422) |
| same page, under the title | no banner | a SUPERSEDED IN PART banner pointing at the Admin Panel MVP assessment | the page it points at exists (QRS-1404) |
architecture/current-state.md, the preamble's 2026-08-26 re-measurement note | "audit_log has zero rows and zero writers" | zero rows and no admin writer (its one writer is set_my_primary_context) | as the first row (QRS-1422) |
architecture/current-state.md, the preamble's "Two absences" paragraph | "workspace_members.role_key is bare text with no CHECK and no FK" | text held to five values by an interim CHECK (owner · admin · manager · member · viewer), no FK and no roles table | 20260808210000_v2_production_hardening.sql:210-211, constraint workspace_members_role_key_known (QRS-1422) |
communications/leads-and-crm.md, the RBAC artifact table | "exists as bare text default 'owner' — no CHECK, no FK" | text default 'owner' held to five values by an interim CHECK, no FK | 20260808210000_v2_production_hardening.sql:210-211 (QRS-1422) |
communications/index.md, the section banner | "NOTHING IN THIS SECTION IS BUILT … There is no whatsapp_* or communication_* migration, no communication Edge Function, and no Admin Hub surface. Every page states this at the top" | partly built: the WhatsApp OTP path and its ledger (five tables, the registry seed; send-auth-otp and whatsapp-webhook use them); not built: consent, campaigns, inbound, usage rollups, any non-OTP send, any Admin Hub surface | 20260901120000 and 20260901140000; send-auth-otp/index.ts:53-63 imports the ledger writers from _shared/communication.ts; whatsapp-webhook/index.ts:170-203 (QRS-1422) |
communications/data-model.md, the opening paragraph | "Every table on this page is DESIGNED, NOT BUILT. There is no communication_* or whatsapp_* migration in the repo (verified 2026-08-21 …)" | five of the nine tables are built by 20260901120000; four are designed and named there as deliberately absent; where a column differs, the migration is the contract | 20260901120000_v2_communications_whatsapp.sql:22-32 (the refused four) and its create table lines (QRS-1422) |
guides/migrations.md, § The baseline | "supabase/migrations/20260710134136_baseline_schema_from_prod.sql … Verified 58/58 tables and 118/118 RLS policies identical between Dev and Prod" | the live schema is the v2 baseline from ADR-0020, starting at 20260808090000_v2_extensions.sql; the squash is retired in supabase/migrations/_archive_pre_v2/ | find supabase -name '20260710134136*' returns only the _archive_pre_v2/ copy; that folder's README.md: "40 files, archived 2026-08-08" (QRS-1422) |
packages/data/src/index.ts:1-2, the header comment | "Supabase client, RPC/EF services, TanStack Query hooks, EDGE_FN maps, query keys" · "Skeleton for now" | the Supabase client, the RPC/EF services and their *_RPC / *_EDGE_FN name maps; no TanStack Query hooks and no query keys (the hooks sit in apps/mobile features); the barrel decides which seam is wired | grep of packages/data and apps/web for useQuery, useMutation, QueryClient, tanstack: no code, only comments and READMEs; @tanstack/react-query is a dependency of apps/mobile only (apps/mobile/package.json:44) (QRS-1422) |
apps/web/src/ui/README.md, the "Two things a reader will otherwise get wrong" list | "This app is LIGHT-ONLY in R1. … .dark is never applied here" | light and dark both apply (system, light or dark, default system) on the landing, merchant, consumer and admin roots; only the public Setu Card renders light only | apps/web/src/app/theme.ts:34, :51, :53, :89-91; root.tsx:91, :129 (QRS-1422) |
apps/web/src/ui/README.md, Purpose, Structure and Parity status | "consumed by landing, public and (later) admin" · a Structure list without Select.tsx and Icon.tsx · "no screen consumes these primitives" | consumed by the merchant console, the marketplace and the consumer biodata page: Select and Icon in merchant screens, cn widely; Button and TextField unused outside the folder | an import scan of apps/web/src outside src/ui and tests: 11 files import @/ui (QRS-1422) |
apps/web/src/tiers/admin/README.md, Purpose and Dependencies | "Stack 1 (RR8, DOM, shadcn)" · "shadcn primitives from apps/web/src/ui" | the hand-written DOM primitives in apps/web/src/ui, with no shadcn or Radix dependency; plus the note that ADR-0034 (Proposed) moves the admin surface to apps/admin | apps/web/package.json:24-42 has no shadcn and no @radix-ui/*; Radix reaches the lockfile only through expo-router and vaul (QRS-1422) |
dev-tracker/tracker.md, QRS-890 | "audit_log has ZERO rows, ZERO policies and NO WRITER" · "All 69 public functions were inspected and none writes to it" | NO ADMIN WRITER; exactly one function writes to it, set_my_primary_context, and it is not an admin action | as the first row (QRS-1422) |
architecture/adr/0006-rbac-and-authorization-model.md, the banner | role_key values owner|admin|manager|staff|agent | owner|admin|manager|member|viewer, the migration's CHECK | supabase/migrations/20260808210000_v2_production_hardening.sql:209-211, never altered later (QRS-1422) |
architecture/adr/0028-url-namespace-and-audience-routing.md, Consequences | "one Cloudflare Pages project" | Cloudflare Workers | apps/web/wrangler.jsonc:1-9, .github/workflows/deploy-web.yml:258-275 (QRS-1422) |
architecture/proposals/platform-operator-control-plane.md, the protocol block's foreign-key entry | audit_log_actor_user_id_fkey -> public.users(id) ON DELETE NO ACTION | ON DELETE SET NULL as authored; the live constraint not re-read, so live state unverified | supabase/migrations/20260808200000_v2_audit_idempotency_touch.sql:70 (QRS-1422) |
same proposal, the protocol block's audit_log measurement | "0 rows, 0 policies, no function or trigger writes to it" | 0 rows and 0 policies as measured; one function writes to it | supabase/migrations/20260817230500_v2_set_my_primary_context.sql:104, a migration that predates the 2026-08-26 measurement (QRS-1422) |
CLAUDE.md §5 and the generated migrations rule (its manifest, .claude/context-map.json) | bounded contexts get a schema: "biodata, meetings" | "biodata only"; meetings was withdrawn in ADR-0031 A1 | adr/0031-domain-schemas-for-bounded-contexts.md:148-150, :210-212; the only create schema statements are extensions and biodata (QRS-1422) |
packages/data/README.md, Purpose | "TanStack Query hooks, EDGE_FN maps, query keys" | the client, the RPC/EF services and their name maps; TanStack Query is an apps/mobile dependency | no @tanstack dependency in packages/data/package.json (QRS-1422) |
apps/web/src/stores/README.md, Responsibilities | server state "is TanStack Query in @qrsetu/data" | server state comes from the @qrsetu/data services; apps/web has no TanStack Query | no @tanstack dependency in apps/web/package.json and no match under apps/web/src (QRS-1422) |
architecture/admin-portal-backend-assessment.md, the lifecycle-operations table (Suspend row) | "no policy or function reads" users.status | no policy reads it and nothing enforces it; get_my_context projects it and soft_delete_account checks it for idempotency | supabase/migrations/20260904150210_v2_soft_delete_cascade.sql:70 (QRS-1422) |
dev-tracker/tracker.md, QRS-870's title | "a soft delete that NOTHING READS" | NOTHING ENFORCES; two functions read it | as the row above (QRS-1422) |
architecture/user-lifecycle.md, finding 2 | "IT IS READ BY NOTHING. users.status appears exactly ONCE in the entire repository" · a 'deleted' row "can still sign in" | ENFORCED BY NOTHING; get_my_context and soft_delete_account read it; a soft delete sticks through an Auth ban (QRS-909), and a 'suspended' row still signs in | supabase/migrations/20260904150210_v2_soft_delete_cascade.sql:70; found by the independent review of the Stage 0 set (QRS-1422) |
| same page, the vocabulary row | "read by nothing" | "enforced by nothing (read only by get_my_context and soft_delete_account)" | as the row above (QRS-1422) |
design-system/communication-crm-refinement.md, the RBAC paragraph | role_key "is bare text default 'owner' with no CHECK and no FK" | held to five values by an interim CHECK, no FK | 20260808210000_v2_production_hardening.sql:210-211 (QRS-1422) |