System views
The system views, one abstraction level at a time, each with a declared altitude, a notation key, an element catalog, and what it deliberately excludes.
Overview · Diagrams
Index and shared conventions
This page holds the eight architecture diagrams for the Addi platform. Each diagram is one page, one altitude, one question. We keep the pictures deliberately spare: a diagram here exists to show a boundary or a flow of responsibility, never to inventory implementation. Detail that a picture cannot carry honestly lives in the prose spine, the architecture, and each diagram names the spine sections it reads with.
Read them in numbered order. The first diagram places the platform in the world; the next six each open one interior mechanism; the last maps concerns to named technologies.
| # | Diagram | Altitude | One line | Reads with (architecture) |
|---|---|---|---|---|
| 01 | System context | Context | The platform, its people, the operator's own Claude, and everything we integrate but do not operate | Section 1, Section 4 |
| 02 | The two lanes | Container | One codebase, two production stacks, forked at the infrastructure layer only | Section 5 |
| 03 | The configuration kernel | Container | Draft, atomic versioned publish, render; feature off means dead server-side | Section 6 |
| 04 | The evidence chain | Container | Address to reports to findings to fields to underwriting, one way | Section 9 |
| 05 | The compute seam | Container | The deterministic analysis engine behind one async entry and one signed callback | Section 11 |
| 06 | The agent connection | Container | OAuth 2.1 plus MCP handshake, per-call tenant re-check, the write door, consent and audit | Section 10 |
| 07 | The write law | Container | Machine writes land into empty; over a human they become proposals | Section 8 |
| 08 | Concern to technology mapping | Container | The named technology roster, one concern per choice | Section 15 |
Shared notation key
Every diagram draws on this same set of marks. Each page restates the marks it uses, specialized to its subject, so it stands alone.
Shared element names
The same thing carries the same name in every diagram, in the prose spine, and in the unit documents. The registry: the Addi platform, internal operator, self-serve investor, property submitter, the operator's Claude, identity provider, billing processor, licensed property and rental data sources, public government and open-data sources, platform backend, web application, analysis engine, Python compute tier, reference layer, write door, published configuration, entitlement choke point, authorization surface, work queue, consent and audit records, verified address identity, artifact, finding, system field, underwriting assumptions, buy-box verdict. Most definitions live in the glossary; the remainder are defined where their diagram introduces them.
One naming rule worth stating: technologies are named exactly once, in diagram 08. Every other diagram uses the role name (identity provider, billing processor, platform backend) so that the pictures describe responsibilities, not products. This is deliberate: a boundary drawn around a role survives a product swap; a boundary drawn around a brand does not.
The set's boundary
Deliberately excluded Tier 2 Tier 3
Diagram 01 · Context
Scope: the Addi platform as a single system, the people and agents that use it, and every external party it depends on, grouped by who operates what.
Altitude: Context. The platform is one box on purpose; its interior begins at diagram 02.
Intended audience: a technical evaluator forming a first mental model of what we run, what we integrate, and what our customers bring with them.
Notation key: rectangles are systems we build and run; stadium shapes are people or systems operated by others; solid arrows are synchronous requests; dashed arrows are asynchronous or scheduled flows; subgraph boxes are ownership boundaries.
flowchart TB
subgraph customer["Brought by the customer"]
operator(["Internal operator"])
investor(["Self-serve investor"])
claude(["The operator's Claude"])
end
subgraph us["Built and operated by us"]
addi["The Addi platform"]
end
submitter(["Property submitter"])
subgraph others["Operated by others, integrated by us"]
idp(["Identity provider"])
billing(["Billing processor"])
licensed(["Licensed property and rental data sources"])
opendata(["Public government and open-data sources"])
end
operator -->|"works deals in the browser"| addi
investor -->|"signs up and analyzes properties, self-serve"| addi
claude -->|"connects over MCP, authorized with OAuth 2.1 plus PKCE"| addi
submitter -->|"submits properties by public form or inbound email"| addi
addi -->|"delegates authentication and org membership"| idp
addi -->|"settles credit-based billing"| billing
addi -.->|"reads under license into an owned reference layer"| licensed
addi -.->|"reads on our schedule into an owned reference layer"| opendata| Element | What it is |
|---|---|
| The Addi platform | An AI property intelligence platform for coliving and residential investors: an address goes in, evidence comes out, and decision surfaces sit on top. At this altitude it includes everything we build and run: the web surfaces, the backend, the analysis engine, and the owned data assets. The interior split is the subject of every following diagram. |
| Internal operator | A member of our own internal team using the invite-only internal lane. Operators work deals through pipeline stages, review evidence, and hold the approval authority that the pipeline's gates require. |
| Self-serve investor | A customer of the public user lane. They sign up without an invitation, submit addresses, and receive the same evidence chain the internal lane runs on, shaped by their tenant's entitlements. |
| The operator's Claude | The customer's own AI agent, running outside our boundary. We ship no in-app chat. Instead the platform exposes an authorization surface so the operator's Claude connects over MCP as a first-class principal, with scoped access and its writes governed exactly like any other writer. Diagram 06 opens this connection. |
| Property submitter | A person outside either lane who brings us a property, through a public intake form protected by a bot challenge at the edge, or by inbound email. Both channels land in intake; the public form is an internal-lane channel. |
| Identity provider | An external service that owns authentication and organization membership. We deliberately do not build login; the application owns roles and privileges on top of the provider's identities. Named in diagram 08. |
| Billing processor | An external service that settles the user lane's credit-based billing: plans, a customer portal, deferred downgrades. Named in diagram 08. |
| Licensed property and rental data sources | The category of commercial data we pay for. The platform reads these under license into a reference layer it owns and serves analyses from that layer rather than from live calls. |
| Public government and open-data sources | The category of public datasets we ingest under the same discipline: read on our schedule, cached, served locally at analysis time. |
What this diagram deliberately excludes Tier 3
Diagram 02 · Container
Scope: how one product serves two audiences: the invite-only internal operator dashboard and the public self-serve user product, from a single codebase.
Altitude: Container. This diagram shows deployment structure, not code structure.
Intended audience: an evaluator asking the standard two-product question: did they fork the code, and what do they pay to keep two audiences served?
Notation key: rectangles are systems we build and run; stadium shapes are systems operated by others; solid arrows are synchronous requests; subgraph boxes are ownership boundaries.
flowchart TB
codebase["One codebase: modules, surfaces, the configuration kernel"]
subgraph internal["Internal lane: invite-only operator dashboard"]
iedge["Edge project, own public domain"]
ibackend["Backend deployment"]
iidp(["Identity instance"])
end
subgraph user["User lane: public self-serve product"]
uedge["Edge project, own public domain"]
ubackend["Backend deployment"]
uidp(["Identity instance"])
end
codebase -->|"deployed unchanged"| iedge
codebase -->|"deployed unchanged"| uedge
iedge -->|"serves the web application against"| ibackend
uedge -->|"serves the web application against"| ubackend
ibackend -->|"authenticates through"| iidp
ubackend -->|"authenticates through"| uidp| Element | What it is |
|---|---|
| One codebase | Every module, surface, and the configuration kernel live in a single codebase. There is no internal edition and no consumer edition; there is one product whose shape per tenant is decided by data, not by branches. We weighed the obvious alternative, a separate consumer product, and rejected it: two codebases means every fix lands twice or drifts, and drift between an internal tool and a paid product is the kind of defect customers find first. The cost we accepted instead is that every feature must be built lane-aware from the start, with internal-only surfaces kept off the user lane by entitlement rather than by absence. |
| Internal lane | The production stack serving our own operators. Invite-only. It exists as a full, separate stack so that an experiment or incident on one lane cannot touch the other. |
| User lane | The production stack serving self-serve investors. Public signup, credit-based billing, tenant provisioning at the door. |
| Edge project (one per lane) | The edge deployment that serves the web application for its lane, on that lane's own public domain. The fork is visible here: same application, different edge project. |
| Backend deployment (one per lane) | The reactive backend for its lane: transactional data, functions, the published configuration, the write doors. Same code, separate deployment, separate data. |
| Identity instance (one per lane) | Each lane runs against its own instance of the external identity provider, so internal accounts and customer accounts never share an authentication space. |
What this diagram deliberately excludes Tier 2
Diagram 03 · Container
Scope: the lifecycle of configuration: authored as a draft, published as one atomic versioned set, rendered by every surface, and enforced server-side when a module is off.
Altitude: Container.
Intended audience: an evaluator probing whether "configurable" means real configuration-as-data with a publish discipline, or a settings page with side effects.
Notation key: rectangles are systems we build and run; stadium shapes are people; diamonds are decision points; solid arrows are synchronous commands; dashed arrows are the deactivation effects of an absent entitlement; subgraph boxes are ownership boundaries.
flowchart TB
author(["Configuration author"])
draft["Configuration draft"]
publish{"Atomic publish"}
published["Published configuration, versioned"]
surfaces["Rendering surfaces"]
choke["Entitlement choke point, fail-closed"]
doors["Module write doors"]
jobs["Scheduled jobs"]
notify["Notifications"]
author -->|"authors tenants, modules, pipelines, stages, strategies, fields"| draft
draft -->|"validated set submitted"| publish
publish -->|"concurrent publish detected: refused, author resolves"| draft
publish -->|"accepted: becomes the one live set"| published
published -->|"every surface renders this set; drafts never leak"| surfaces
published -->|"resolves every entitlement question"| choke
choke -->|"module on: business commands admitted"| doors
choke -.->|"module off: writes refuse"| doors
choke -.->|"module off: jobs deactivate"| jobs
choke -.->|"module off: notifications drop"| notify| Element | What it is |
|---|---|
| Configuration author | An administrator shaping the platform: which tenants exist, which modules each is entitled to, what the pipeline's stages and gates are, which underwriting strategies are offered, which field definitions exist. All of this is data. Changing what the product is for a tenant requires no code change; that is the kernel's reason to exist. |
| Configuration draft | Work in progress, visible only to its author. Drafts never leak into any rendering surface; a half-finished pipeline cannot appear on anyone's screen. This is a guarantee, not a styling choice, and it is enforced where the surfaces read. |
| Atomic publish | The single transition from draft to live. The whole set becomes current at once or not at all; there is no window where half the configuration is new. Concurrent publishes are caught and refused rather than merged, because a silent merge of two admins' intent is a defect factory. Rollback is a forward roll: a prior known-good set is published as a new version, so history only ever moves forward and every state the platform has been in remains on the record. |
| Published configuration, versioned | The one live set. Every surface, every write door, every scheduled job answers to this and nothing else. Versioning is what makes the atomic swap and the forward roll cheap. |
| Rendering surfaces | The screens: pipeline board, deal workspace, calculator, and the rest. They render exactly the published set. A surface holds no private opinion about what modules exist. |
| Entitlement choke point, fail-closed | The one place entitlement questions are answered. Fail-closed means an unresolvable question is a no. We chose a single choke point over per-feature checks scattered through the code because scattered checks rot: one forgotten check is an open door, and audits of many doors never end. |
| Module write doors | Each module's single command entry, shown here only as the target of enforcement; diagram 07 gives the doors their own page. Feature off means dead, server-side: a disabled module's door refuses commands outright. Hiding a button is not a security boundary; a refused write is. |
| Scheduled jobs and Notifications | The quieter halves of "off means dead". A disabled module's scheduled work deactivates and its notifications drop, so a tenant that turned a capability off cannot be surprised by its background behavior. The composed module set is the one switch that governs all three effects. |
What this diagram deliberately excludes Tier 2 Tier 3
Diagram 04 · Container
Scope: the one-way path from an address to an underwriting-ready deal: verified identity, versioned report artifacts, immutable findings, editable system fields, underwriting assumptions, and the buy-box verdict, plus the one sanctioned way to override it all: an authoritative human correction.
Altitude: Container.
Intended audience: an evaluator asking whether the numbers on a deal screen can be trusted, and what happens when the public record is wrong.
Notation key: rectangles are systems and stores we build and run; cylinders are data we own; stadium shapes are people; solid arrows are the chain's forward flow; dashed arrows are corrections and re-runs; subgraph boxes are ownership boundaries.
flowchart TB
address["Address in at the front door"]
identity["Verified address identity"]
artifacts[("Versioned report artifacts: structured reports plus agent synthesis")]
findings[("Structured findings, immutable")]
fields["System fields, editable, provenance-stamped"]
uw["Underwriting assumptions, defaults labeled"]
verdict["Buy-box verdict, reasons recorded"]
human(["Authoritative human correction"])
address -->|"first address creates the deal"| identity
identity -->|"analysis dispatched through the seam (diagram 05)"| artifacts
artifacts -->|"each artifact produces"| findings
findings -->|"project into"| fields
fields -->|"feed"| uw
fields -->|"evaluated against per-tenant criteria"| verdict
human -.->|"short-circuits downstream reads, correction recorded"| fields
identity -.->|"re-run creates a new version, never a rewrite"| artifacts| Element | What it is |
|---|---|
| Address in at the front door | The zero-question entry: the first address creates the deal and lands the user on it. Everything downstream hangs off this one act. |
| Verified address identity | Intake resolves the raw address into a verified identity that every downstream module shares. Sharing identity rather than models is a boundary rule for us: the same address is a different concept to intake, zoning, valuation, market, underwriting, and pipeline, so modules exchange the identity and keep their own models. A property is not a property. |
| Versioned report artifacts | A property is a folder of versioned artifacts: a small set of structured report types plus agent-authored synthesis. Artifacts are never silently rewritten; re-running an analysis creates a new version beside the old one. The structured reports are deterministic renders over data, not generated prose; no language model sits anywhere in the data producers. Every value carries provenance and confidence in words, and coarse-geography data is never presented at finer precision than it actually has. |
| Structured findings, immutable | Each artifact produces findings: the distilled, structured claims the report stands behind. Findings are immutable because they are evidence; evidence is not edited, it is superseded by a new version or overruled by a recorded correction. |
| System fields, editable, provenance-stamped | Findings project into fields a human can edit. This is the deliberate joint in the chain: evidence stays pristine behind it, judgment lives in front of it, and every value records what produced it, a human or one of the machine writer classes. The write law (diagram 07) governs every write here. |
| Underwriting assumptions, defaults labeled | Underwriting consumes the findings snapshot through the fields, never a report's internals. Every standard assumption routes through an overridable per-deal template, and defaults are labeled as defaults rather than silently trusted, because markets differ and a silent default is a wrong number wearing a confident face. |
| Buy-box verdict, reasons recorded | A living fit verdict evaluated against the tenant's explicit, typed criteria. It is the only automatic pipeline mover in the product, and only toward rejection, with its reasons recorded. Everywhere else a recommendation waits for a human. |
| Authoritative human correction | The real world's error handler. Public records are sometimes wrong; when a human with authority corrects a value, the correction short-circuits downstream reads and is itself recorded. The chain stays one-way: corrections enter at the fields, never by editing evidence. |
What this diagram deliberately excludes Tier 2 Tier 3
Diagram 05 · Container
Scope: the boundary between the transactional platform backend and the deterministic analysis engine: one async entry point in, one signed callback out, with the engine and its owned reference layer behind the boundary.
Altitude: Container.
Intended audience: an evaluator asking how analysis load and analysis failure are kept out of the transactional system, and how external data dependence is disciplined.
Notation key: rectangles are systems we build and run; cylinders are data we own; solid arrows are synchronous calls; dashed arrows are asynchronous callbacks and offloaded jobs; subgraph boxes are ownership and failure-domain boundaries.
flowchart TB
backend["Platform backend"]
entry["One async entry point"]
subgraph seam["Behind the seam: a separate service, its own failure domain"]
engine["Analysis engine: deterministic, fail-soft"]
reference[("Pre-cached national reference layer")]
end
python["Python compute tier, serverless"]
backend -->|"dispatch analysis"| entry
entry --> engine
engine -->|"reads, cache-first"| reference
engine -.->|"source document retrieval, spatial joins, document parsing"| python
engine -.->|"HMAC-signed callback, tenant echoed, idempotent ingestion"| backend| Element | What it is |
|---|---|
| Platform backend | The reactive backend that owns transactional and HTTP-shaped work: deals, configuration, write doors, surfaces. It dispatches an analysis and then goes back to its job; it never waits on the engine, and the engine never reaches into its tables. |
| One async entry point | The seam's front half. Everything the platform wants from the engine passes through this single asynchronous entry. One entry means one place to reason about load, authorization, and contract shape. The alternative we rejected, in-process analysis, couples a slow producer's worst day to the transactional system's response time and takes the whole product down with a data vendor's outage. |
| Analysis engine | A deterministic service in its own failure domain. Given the same inputs it produces the same reports; interpretation is code, not a model. Its outputs are the structured report types plus findings from diagram 04. Fail-soft is the contract: one missing source never blocks an analysis; the run completes with honest confidence marks on what could not be read. We prefer a complete report that admits a gap over a failed run that admits nothing. If the engine dies mid-run, the platform is degraded, not down. |
| Pre-cached national reference layer | Our cache the data, compute the meaning posture made physical: reference data is pre-cached nationally and served locally at analysis time, cache-first, with freshness tiers by kind of data. Analyses read our own layer, not a vendor's rate limit. The storage engine behind the layer sits behind a boundary so it can be swapped; that swap is designed and not yet exercised, the designed target is named in diagram 08, and the limitations register argues the sequencing. |
| Python compute tier, serverless | Genuinely heavy Python work, source document retrieval, spatial joins, document parsing, runs on a serverless Python tier rather than inside the engine's steady-state footprint. Heavy work scales to zero when idle. |
| The signed callback | The seam's back half. Results return through one HMAC-signed callback: the signature authenticates the engine, the tenant is echoed on every callback so ingestion pins each result to its tenant, and ingestion is idempotent so a retried callback is absorbed rather than applied twice. |
What this diagram deliberately excludes Tier 2 Tier 3
Diagram 06 · Container
Scope: how the operator's own Claude becomes a governed principal of the platform: the OAuth 2.1 authorization handshake, the MCP tool-call path with per-call tenant re-verification, the served doctrine, the work queue, and the write door with consent and audit.
Altitude: Container.
Intended audience: an evaluator whose first question is the right one: you gave an agent write access to a system of record?
Notation key: rectangles are systems we build and run; cylinders are data we own; stadium shapes are systems operated by others; solid arrows are synchronous calls; dashed arrows are asynchronous flows; subgraph boxes are ownership boundaries.
flowchart TB
claude(["The operator's Claude"])
subgraph platform["The Addi platform"]
auth["Authorization surface: OAuth 2.1 plus PKCE, dynamic client registration, RS256 tokens"]
mcp["MCP endpoint"]
recheck["Per-call tenant re-verification"]
doctrine["Served doctrine"]
queue["Work queue"]
reads["Module read contracts"]
door["Module write door: write law, house-style gate"]
audit[("Consent and audit records")]
end
claude -->|"authorizes with operator consent, scoped"| auth
auth -->|"issues a scoped token"| claude
claude -.->|"fetches its current skill at session start"| doctrine
claude -->|"every tool call"| mcp
mcp --> recheck
recheck -->|"reads"| reads
recheck -->|"writes"| door
queue -.->|"wake-up fires under a budget cap"| claude
claude -->|"claims one job at a time"| queue
door -.->|"every consent and every action recorded"| audit| Element | What it is |
|---|---|
| The operator's Claude | The customer's agent, outside our boundary, running on their account. We deliberately built no in-app chat and rejected the embedded chatbot with metered usage: an embedded bot makes us the middleman for a relationship the operator already has, and it couples our product to one conversation surface. Instead the platform is a well-governed counterparty to whatever agent the operator brings, over an open protocol. |
| Authorization surface | An OAuth 2.1 plus PKCE authorization surface built into the backend: dynamic client registration, RS256-signed tokens, scoped access, and consent captured as schema, not as a checkbox lost in a log. The agent holds a grant the operator gave and can inspect. |
| MCP endpoint | The platform's tool surface, speaking MCP, the open protocol for agent-to-system connection. Standard protocol on purpose: it makes our surface legible to any compliant agent and keeps us out of the business of maintaining a proprietary bridge. |
| Per-call tenant re-verification | Every tool call independently re-verifies tenant identity; nothing is trusted because the session was trusted a moment ago. This is the choke-point discipline of diagram 03 applied to the agent path. |
| Served doctrine | The agent fetches its current operating skill from the platform at session start, so behavior tracks deployed truth instead of drifting. The alternative, per-session pasted instructions, drifts by construction: whatever a session was pasted last month is what it still believes today. |
| Work queue | Autonomy as a queue: one connection, one token, one queue. Wake-ups fire instantly under budget caps, jobs are claimed one at a time, failed jobs are swept and retried. The job kinds are a small set of autonomous analysis and recommendation tasks; the roster is held at Tier 2. |
| Module read contracts | The agent reads the same composed, typed contracts every surface reads. There is no privileged agent view of raw tables. |
| Module write door | The answer to the skeptical question. Agent writes flow through the same write doors as human writes, under the write law (diagram 07): free into empty, a proposal over a human, never an overwrite. Safety here is budgets plus traceability plus reversibility, never approval gates on writes; a capability we judge genuinely risky ships read-only instead of gated. The door also applies a mechanical house-style gate to agent-authored output. Agents get the door, never the tables; that sentence is the blast-radius contract. |
| Consent and audit records | Consent and every agent action live as schema, so "what did the agent do, and who allowed it" is a query, not an investigation. |
What this diagram deliberately excludes Tier 2 Tier 3
Diagram 07 · Container
Scope: the single rule that governs every write to a field, human or machine: machine writes land freely into empty or machine-sourced fields, and never over a human-confirmed value; over a human they become proposals.
Altitude: Container. The diagram shows the write path at door level; the decision flow inside a door is held at Tier 2.
Intended audience: an evaluator asking how a platform full of machine writers, with an autonomous agent among them, avoids ever destroying human judgment.
Notation key: rectangles are systems we build and run; stadium shapes are people or writer roles; cylinders are data we own; solid arrows are the write flow; dashed arrows are recorded outcomes.
flowchart TB
machine(["Machine writer"])
humanw(["Human writer"])
door["Module write door"]
land["Write lands"]
proposal["Queued as a proposal; nothing is overwritten"]
record[("Provenance and decision record")]
machine --> door
humanw --> door
door -->|"the law admits the write"| land
door -->|"a machine write over a human-confirmed value"| proposal
land -.-> record
proposal -.->|"outcome, either way"| record| Element | What it is |
|---|---|
| Machine writer | Anything that is not a person writing through the door. The law does not care which machine is writing; every machine writer faces the same rule, which is what makes the rule auditable. |
| Human writer | A person editing through a surface. A human write lands and raises the field's protection against every future machine write. |
| Module write door | Every module has exactly one write entry. The law lives in the door, not in each writer's good intentions, so no writer can be trusted into compliance; they are structurally incapable of anything else. This is also why the agent's write access is safe to grant: agents get the door, never the tables. |
| Write lands | Free into empty. Machines fill the vast empty surface of a young deal without ceremony, because ceremony on empty fields is friction with no one to protect. |
| Queued as a proposal | The collision case. A machine that wants to change a value a human stands behind gets to say so, visibly, and wait for the human's decision. Nothing is overwritten. We rejected the obvious alternative, approval gates on every machine write, because it buries operators in reviews of harmless writes into empty fields; the law spends human attention only where a human has already spent judgment. |
| Provenance and decision record | Every landing, every proposal, and every decision on a proposal is recorded. Reversibility and traceability are the safety mechanism here, standing in the place approval gates would otherwise occupy. |
What this diagram deliberately excludes Tier 2 Tier 3
Diagram 08 · Container
Scope: the named technology roster, arranged as one concern per choice. This is the only diagram in the set that names products; every other diagram uses role names.
Altitude: Container. Concerns here are the containers the earlier diagrams drew; this page tells you what each one is made of.
Intended audience: an evaluator vetting whether the stack hangs together: whether each choice matches its concern and whether the boundaries drawn in diagrams 01 through 07 are the boundaries the technologies actually enforce.
Notation key: rectangles on the left are concerns; rectangles on the right are the technologies serving them; a solid arrow reads "is served by". Open standards appear alongside products where the standard is the load-bearing choice.
flowchart LR
subgraph concerns["Concern"]
c1["Web application surfaces"]
c2["Reactive database and transactional functions"]
c3["Server-side orchestration"]
c4["Identity and organizations"]
c5["Agent connection and authorization"]
c6["Edge delivery"]
c7["Heavy Python compute"]
c8["Warehouse target behind the reference boundary"]
c9["Billing"]
c10["Cross-service call integrity"]
c11["Toolchain and verification"]
end
subgraph tech["Choice"]
t1["SvelteKit with Svelte 5 runes, TypeScript strict, Tailwind CSS"]
t2["Convex"]
t3["Effect, server side only"]
t4["Clerk"]
t5["Anthropic Claude over MCP; OAuth 2.1 plus PKCE; RS256 JWT"]
t6["Cloudflare Pages and Workers"]
t7["Modal, Python"]
t8["Postgres with PostGIS, the designed target"]
t9["Stripe"]
t10["HMAC-SHA256 signed callbacks"]
t11["Bun, Vite, Vitest, Playwright, ESLint, Prettier"]
end
c1 --> t1
c2 --> t2
c3 --> t3
c4 --> t4
c5 --> t5
c6 --> t6
c7 --> t7
c8 --> t8
c9 --> t9
c10 --> t10
c11 --> t11| Element | What it is |
|---|---|
| Web application surfaces | SvelteKit with Svelte 5 runes, TypeScript strict, Tailwind CSS. One application codebase serving both lanes (diagram 02). |
| Reactive database and transactional functions | Convex. The platform backend of diagrams 02 through 05. |
| Server-side orchestration | Effect, server side only. It does not appear in surface code. |
| Identity and organizations | Clerk. The identity provider of diagram 01, one instance per lane (diagram 02). We do not build login. |
| Agent connection and authorization | Anthropic Claude over MCP, authorized with OAuth 2.1 plus PKCE, carrying RS256-signed JWTs. Claude is the agent runtime; MCP and OAuth 2.1 are the open standards behind the agent surface of diagram 06, and they are the only outside citations this package makes. |
| Edge delivery | Cloudflare Pages and Workers. Each lane's edge project (diagram 02). |
| Heavy Python compute | Modal running Python. The serverless tier of diagram 05 for source document retrieval, spatial joins, and document parsing. |
| Warehouse target behind the reference boundary | Postgres with PostGIS. Stated precisely: this is the designed target of the storage swap behind the reference layer of diagram 05. The boundary exists today; the swap is designed and not yet exercised, and the sequencing is argued in the limitations register. |
| Billing | Stripe. The billing processor of diagram 01: credit-based plans, a customer portal, deferred downgrades. |
| Cross-service call integrity | HMAC-SHA256 signed callbacks. The seam's return path (diagram 05). |
| Toolchain and verification | Bun as the runtime toolchain, Vite for builds, Vitest for unit tests, Playwright for end-to-end verification against live surfaces, ESLint and Prettier as mechanical style gates. |
What this diagram deliberately excludes Tier 2 Tier 3