Companion to PR #470 canonical deck. Renders the full top-to-bottom stack with EmberGraph slotted into its actual position. Built 2026-06-24 to give Lydo visual clarity before committing to the multi-quarter build.
Color convention (matches PR #470):
EmberKeep mediates third-party access to records the principal owns. Three things make this unusual:
The standard "Clerk + RLS + app code" pattern most SaaS products use doesn't fit because the matrix of (record ร role ร state) decisions is too large to encode inline at every consumer.
So we built a matrix. We have it. The question isn't "should we build EmberGraph" โ it's "should we let the 3 parallel engines that drifted apart stay drifted, or converge them."
| Question | Database (Supabase) | EmberGraph |
|---|---|---|
| What does it own? | The bytes | The decision |
| What's its primitive? | Rows, columns, JSONB blobs | Access decisions + audit entries |
| Example question it answers | "Give me row 12345" | "Should viewer Anne see row 12345 right now, and in what form?" |
| Stays the same across products? | Yes (Postgres is Postgres) | Yes (matrix is matrix) |
| What goes in/out? | SQL โ rows | (viewer, record, state) โ projected payload + audit log entry |
| What it does NOT know | What "Cat 1" means; what "incapacitated" means; what a "role" is | Where the bytes physically live; how indexing works |
The shortest answer: the database is the filing cabinet. EmberGraph is the librarian who knows which documents each visitor is allowed to see, in what state the owner is in, and whether to hand over a full document, summary, or refuse.
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ WHO USES THE APP โ
โ Member ยท Advisor ยท Heir ยท โ
โ AI agent ยท Attorney โ
โโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโ
โ
โโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโ
โ โ โ
โผ โผ โผ
โโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโ
โ CLERK โ โ STRIPE โ โ RESEND โ (sub-processors)
โ (auth) โ โ (billing)โ โ (email)โ
โ SOC 2 โ โ PCI-DSS โ โ โ
โโโโโโฌโโโโ โโโโโโโโโโโโ โโโโโโโโโโ
โ
โ identity
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ APPLICATION LAYER โ
โ Next.js 14 (App Router) on Vercel โ
โ โ
โ โข UI surfaces โ
โ Letters ยท Family View ยท Emergency ยท โ
โ Final Wishes ยท Settlement Packet ยท โ
โ Settings / Who has access โ
โ โข API routes โ
โ โข Business logic โ
โโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโ
โ
"can this viewer see this record? in what form?"
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ โ
โ โ
EMBERGRAPH โ
โ
โ โโโโโโโโโโโโโโโโโโโโโโ โ
โ the access decision substrate โ
โ โ
โ INPUTS โ
โ viewer identity โ from Clerk โ
โ record requested โ application โ
โ principal state โ alive ยท incap ยท deceased โ
โ role + activation โ three-stage chain โ
โ โ
โ LOGIC โ
โ 1. consult 360-cell visibility matrix โ
โ (classification ร role ร state) โ
โ 2. apply sub-filters โ
โ (release date ยท role scope ยท activation gate) โ
โ 3. produce projection โ
โ (FULL ยท SUMMARY ยท REDACTED ยท DENY) โ
โ โ
โ OUTPUTS โ
โ โธ projected payload โ caller โ
โ โธ immutable audit entry โ hash-chained log โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโคโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
"fetch these rows / these specific fields"
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ DATABASE LAYER โ
โ Supabase Postgres + Storage โ
โ โ
โ โข Records (artifacts, vault_sections, role_activations) โ
โ โข JSONB blobs โ
โ โข File pointers + storage buckets (signed URLs) โ
โ โข Coarse RLS = deny-all safety net (the FLOOR; โ
โ EmberGraph is the ceiling) โ
โ โข AES-256 encrypted at rest โ
โ โข Hash-chained audit log table โ
โโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
(for the most sensitive vault content)
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ CLIENT-SIDE SDB ENCRYPTION โ
โ โ
โ PBKDF2 โ AES-GCM 256 ยท PIN-derived โ
โ Keys never leave browser. EmberKeep cannot read SDB. โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
SUPPORTING SUBSTRATE
Anthropic + Gemini ยท GCS (backup target) ยท Vercel edge
โ
โ TODAY: AI calls bypass EmberGraph
โ (slide-7 known gap)
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ AI REDACTION LAYER (new โ gap fix)โ
โ lib/ai/redact.ts โ
โ โ
โ Every AI call routes through โ
โ EmberGraph FIRST. Model sees only โ
โ what the caller could have seen. โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Letters 6 role-display vault_sections
surfaces (every member read)
โ โ โ
โผ โผ โผ
projectArtifact() contact-roles.ts vault_share_grants
(1 surface uses (6 surfaces, bypass (coarse RLS, no
matrix) the matrix) per-classification)
โ โ โ
โผ โผ โผ
ENGINE #1 ENGINE #2 ENGINE #3
matrix-driven raw role state per-section RLS
Honest: the canonical deck says "one engine." Reality is three. The matrix is correct logic that 6 of 7 surfaces don't consult.
Letters ยท 6 role-display surfaces ยท vault_sections ยท EK 4.0 RAG
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโ
โ decideAccess() โ
โ (the SINGLE PDP) โ
โ consults matrix โ
โ applies sub-filters โ
โโโโโโโโโโโโฌโโโโโโโโโโโโ
โ
โโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโ
โผ โผ โผ
shapeRecord() decideRoleVisibility() shapeRagContext()
(Letters, (6 role-display (future EK 4.0)
vault surfaces)
sections)
โ โ โ
โผ โผ โผ
ALL audited through the hash-chained audit log
The reframing the external review locked: one decision authority, multiple enforcement paths. Not one function for everything.
TODAY (broken) TARGET (gap closed)
โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ
Application Application
โ โ
โผ โผ
Build prompt Build prompt
โ โ
โ unredacted vault content โผ
โผ EmberGraph
โ
โผ
decideAccess(AI_agent, record)
โ
โผ
Redacted payload
โ
โผ
Anthropic / Gemini โโโโโโโโโโโโโโโโ Anthropic / Gemini
โ โ
โผ โผ
Response Response
๐ด Cat-1, Cat-2, Cat-3 ๐ข Model receives only what
content shipped to model the caller could have seen.
regardless of viewer rights Audit entry recorded per call.
This is the load-bearing reason EmberGraph exists at the chokepoint. Without it, every AI feature is a manual access-control surface.
What plugs into the stack later without a redesign:
| Future product | Plugs in where | Why it works |
|---|---|---|
| EK 4.0 โ "EmberKeep Knows Me" (AI-native vault) | shapeRagContext() โ new shaper, same
decideAccess kernel |
RAG retrieval is gated by the matrix; no special-case logic |
| Attorney B2B (Eric Gold's firm scenario) | New role type added to the matrix; existing
decideAccess consults it |
Adding roles is a config change, not an architectural change |
| Wealth advisor channel (BofA / Forward Inheritance) | New role + new release_condition (e.g.
client_signed_engagement) |
Sub-filter, not new code path |
| International / jurisdiction | New axis on the matrix (jurisdiction ร classification ร role ร state) | Synthesis OPEN item; needs orthogonal modeling, not retrofit |
| Multi-principal / joint records | Schema change on records; matrix consults principal_set
instead of principal_id |
Bounded change inside the matrix layer |
| Compliance reporting (audit replay) | Already wired via hash-chained audit log + policy versioning (synthesis OPEN) | Audit log is the substrate |
The chokepoint pays for itself the second time you add a new surface.
| Layer | What's wired | What's the gap | Severity |
|---|---|---|---|
| Auth (Clerk) | โ Live, SOC 2 inherited | None | โ |
| Database (Supabase) | โ Live, 59 migrations, RLS on 39 of 60 tables | ๐ด 21 of 60 tables lack RLS (slide 3) | P0 before alpha |
| EmberGraph matrix | โ
Wired in lib/access/visibility-matrix.ts |
๐ก Only 1 of 7 surfaces consults it | P0 (parallel-engine drift) |
| AI gating | ๐ด NOT WIRED | AI calls send unredacted vault content (slide 7) | P0 before alpha |
| Audit log | โ Hash-chained, RLS deny-all UPDATE/DELETE | ๐ก Co-transactional only on Letters surface | P1 |
| Client-side SDB encryption | โ Live, PBKDF2 โ AES-GCM 256 | None | โ |
| Three-stage role activation chain | โ Schema invariants enforced | ๐ก 0 candidates in active state (no member-side
UI) |
P0 (EMB-420) |
| Dev/prod separation | ๐ด NOT WIRED โ single Supabase project | Local dev hits production DB | P0 before alpha |
| Observability / error tracking | ๐ด NOT WIRED โ PostHog stubbed, no Sentry | Production failures invisible | P1 |
| Backup + DR | ๐ข Nightly to GCS; ๐ด no documented restore | RTO/RPO unknown | P1 |
| Threat model (written) | ๐ด NOT WRITTEN | No artifact for advisor review | P1 |
security.txt |
๐ด NOT PUBLISHED | RFC 9116 noncompliance | P2 |
Pen test scheduled (locked 2026-05-22) before SOC 2 pursuit. Pen test scope must include the new chokepoint.
| Layer | Future-proof? | Confidence | Why |
|---|---|---|---|
| Database (Supabase Postgres) | โ YES | HIGH | Postgres scales; vendor not locked-in |
| Hosting (Vercel) | โ YES | HIGH | Edge runtime; serverless migration is possible |
| Auth (Clerk) | โ YES | HIGH | Standard OIDC; replaceable; SOC 2 inherited |
| EmberGraph matrix | โ YES | HIGH | Patent-track substrate; future-proofs against EK 4.0 + multi-product |
| Audit log (hash-chained) | โ YES | MEDIUM | Substrate is right; external anchoring needed at scale (synthesis) |
| Client-side SDB encryption | โ YES | HIGH | Already E2E for the sensitive layer |
| AI gating | โ NOT YET | โ | The load-bearing close; closes slide-7 gap; enables EK 4.0 |
| Dev/prod separation | โ NOT YET | โ | Substrate gap; pre-revenue is cheapest moment |
| Observability stack | โ NOT YET | โ | Required for SLO tracking |
Verdict: the stack is fundamentally sound. The gaps are specific, named, and fixable. The chokepoint convergence + AI gating + dev/prod separation are the three load-bearing closes.
The architectural commit was reviewed by 5 independent LLM reviewers
(ChatGPT, Perplexity, Gemini, Grok, Claude CoWork) against a sanitized
design doc. Full synthesis at
embergraph-external-review-synthesis-2026-06-23.md.
| # | Design question | ChatGPT | Perplexity | Gemini | Grok | CoWork | Convergence |
|---|---|---|---|---|---|---|---|
| 1 | Single chokepoint vs peer engines | PDP/PEP split | One policy authority, not one shape | Logical SoT yes, physical no | Shared kernel + adapters | Right for decision, wrong as function | 5/5 PUSHBACK |
| 2 | Wrap (A) vs merge (B) for role-display | Shared kernel + role-specific evaluators | Reject B as written | Dedicated decideRoleVisibility |
A superior; dedicated primitive | B's doc-stated definition IS the category error | 5/5 AGAINST B-as-written |
| 3 | Per-row / per-field / migrate (vault_sections) | Per-field bridge, migrate long-term | Per-field transitional | Migrate NOW | Migrate NOW (>6-9mo threshold) | False dichotomy โ per-section is a VIEW over unified store | SPLIT โ CoWork reframes |
| 4 | Classification โฅ semantic facets orthogonal | Load-bearing, day 1 | Load-bearing | Load-bearing, day 1 | Load-bearing, day 1 | Load-bearing as constraint, you're already violating it | 5/5 STRONG |
| 5 | Co-transactional audit invariant | Tier sync/aggregate | Co-trans for security-critical only | Outbox pattern; drop advisory lock | Strict; correct for trust-critical | Split the artifact (decision sync, chain spine async + anchored) | 4-DISTINCT POSITIONS |
| 6 | Sub-filter reification (all code?) | Hybrid (procedural + declarative) | Hybrid; declarative for stable | Fully declarative metadata | Hybrid, declarative-first | Separate binding (data) from evaluation (code) | 5/5 AGAINST PURE CODE |
| 7 | Three-state principal lifecycle | Decompose to 3 axes | Top bucket + state machine | Add Disputed / Reversible / Interregnum | Richer state machine | Capacity as a claim, not a property; who authorizes? | 5/5 AGAINST 3-STATE |
| 8 | Dev/prod sequencing | Upstream | Upstream | "Stop everything, fix environments" | Upstream of rebuild | Upstream, barely a question | 5/5 STRONG |
| 9 | What's missing | 8 items (versioning, temporal, break-glass, denial UX, caching, governance, regulatory drift) | Policy drift across representations; metadata escalation | Bootstrap paradox; break-glass; cryptographic boundary | Multi-principal; performance; cross-jurisdictional | State-transition authority; OIL = engine #2 reborn; right-to-erasure conflict; legal hold | NOVEL findings |
| Confidence band | # dimensions | Status |
|---|---|---|
| HIGH (5/5 panel converged + structural critique) | 10 | As locked as they can be without writing code |
| MEDIUM (clear direction, implementation choices remain) | 6 | Refines through implementation |
| LOW (novel concerns surfaced but not yet designed) | 7 | Each is a design pass we still owe |
We have the best directional design we can produce today, with 7 named gaps we haven't designed for yet. The HIGH band is decisional; the MEDIUM band is implementable; the LOW band is research-pending.
| Phase | Item | Duration | Why now |
|---|---|---|---|
| 0 | EMB-296 โ Dev/prod environment separation | ~14-15 hrs over 4-5 days | 5/5 panel locked upstream; pre-revenue cheapest moment |
| 1a | AI redaction layer (lib/ai/redact.ts) |
1-2 days | Closes slide-7 honest gap; load-bearing for advisor trust |
| 1b | 21 RLS table closures | ~1 week | Closes slide-3 honest gap; required before alpha |
| 2 | EMB-420 minimum โ member-side role-creation UI | ~1 week | Without it, 0 active roles forever; expanded scope is V2 |
| 3 | Domino #2 Strategy C โ shared decideAccess + dedicated
decideRoleVisibility |
~2-3 weeks | Eliminates the 3-engine drift; 5/5 panel; the actual chokepoint convergence |
| 4 | Observability stack โ Sentry + structured logger + cron alerting | ~1 week | Pre-revenue blind spots become P0 in prod |
Total MVP: ~5-6 weeks of focused build. Closes every slide-3 and slide-7 honest gap. Establishes the single decision authority. Ships safely before beta.
| Phase | Item | Trigger that forces the work |
|---|---|---|
| 5 | Domino #3 โ vault_sections per-field
classification |
First customer who asks "why does my attorney see HIPAA notes" |
| 6 | Lifecycle expansion to capacity-as-claim model | First contested incapacity event |
| 7 | Sub-filter binding/evaluation engine | 8+ sub-filters in the catalog |
| 8 | Owner Intent Ledger moved inside matrix decision flow | OIL builds proven downstream |
| 9 | State-transition authorization full model + break-glass | First medical-emergency surface or 2nd incapacity case |
| 10 | Audit chain external anchoring (transparency-log style) | Pen test finding OR pre-SOC-2 audit prep |
| 11 | Multi-region audit replication | EU customer OR uptime SLA upgrade past 99.9% |
| 12 | Jurisdiction modeling (4th matrix axis) | International customer OR multi-state conflict |
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ PHASE 0 โ Substrate ready (EMB-296) โ โโโ BLOCK
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ starts
โ Dev/prod separation ยท staging gate ยท per-env keys โ here
โโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ PHASE 1 โ Honest-gap closure (in parallel) โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ 1a ยท AI redaction layer (slide-7 fix) โ
โ 1b ยท 21 RLS closures (slide-3 fix) โ
โโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ PHASE 2 โ Bootstrap (EMB-420 minimum) โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ Owner UI to create role candidates โ
โ Target-side accept flow (Stage 2 fresh re-auth) โ
โ โธ unblocks every downstream domino โ
โโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ PHASE 3 โ Chokepoint convergence (Domino #2 / C) โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ Shared `decideAccess` kernel โ
โ Dedicated `decideRoleVisibility` shaper โ
โ 6 role-display surfaces refactor โ
โ CI invariant: no direct role_activations reads โ
โโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ PHASE 4 โ Production observability โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ Sentry ยท structured logging ยท cron alerting ยท APM โ
โโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โผ
โ โ โ โ alpha ready ยท beta launch โ โ โ โ
โ
โผ (driven by first-customer signal)
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ PHASE 5 โ vault_sections classification (Domino #3) โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ Per-field classification map ยท unclassified default โ
โ Mark + Eric legal review ยท codegen pipeline ship โ
โ Strategy 4: unified records + section views โ
โโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ PHASE 6 โ Lifecycle + authorization โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ Capacity-as-claim model โ
โ State-transition authorization framework โ
โ Break-glass / emergency-override design โ
โโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ PHASE 7 โ Sub-filter engine + Owner Intent Ledger โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ Code-eval + data-binding split (CoWork sharpening) โ
โ OIL moves inside matrix decision flow โ
โโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ PHASE 8 โ Scale infrastructure โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ Read replicas ยท synthetic monitoring ยท SLA tracking โ
โ Audit chain external anchoring โ
โ Multi-region replication (when EU customer signs) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
The MVP is what we ship before the Warm Lead Beta so we can sell to wealth advisors with a straight face. The marathon is what makes EmberKeep the patent-track substrate that future products (EK 4.0, attorney B2B, advisor channel) plug into.
Build the MVP next. Use it for 60-90 days. Let real customer questions drive the marathon's sequencing.
Generated 2026-06-24 by Claude Code. Visual artifact for
design clarity. Companion HTML at
full-stack-with-embergraph.html.