Skip to content

Commit aad873d

Browse files
mpstatonclaude
andcommitted
plan(reach-edu-instance): open augment.didi.sh to reach-edu — per-client instance, Stephenie Tesoro as first client user
The deployed stack already reads the shared SurrealDB Cloud, so reach-edu's whole canonical layer sits one auth gate away — and the gate cannot simply be relaxed: ACTIVE_CLIENT_ID pins the tenant per-instance, so loosening REQUIRED_ORG_ID would drop reach.edu logins into the humain-vc workspace. The plan recommends the house pattern instead: a sibling per-client instance (reach.augment.didi.sh — new workspace-service + shell with baked WS URL, shared client-agnostic backends, own tenant pin), org reach.edu minted in id-didi-sh, and Stephenie's first login as the acceptance test. Option B (org→client session binding, one domain for all tenants) is logged for the client-#4 era. Caveats recorded: corpus files absent from the deployed volume, shared Anthropic spend pool, and the Augment-from-DB remotes not yet deployed anywhere — recommended in-scope since the workbench is the surface Stephenie actually needs. Files changed: - context-v/plans/Open-Augment-Didi-Sh-To-Reach-Edu.md Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RW28dw3kQAKXr2ZNefCukE
1 parent 20b2f8f commit aad873d

1 file changed

Lines changed: 131 additions & 0 deletions

File tree

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
---
2+
title: "Open augment.didi.sh to reach-edu — a second tenant instance, and Stephenie Tesoro as the first client user"
3+
lede: "The deployed stack already reads the shared SurrealDB Cloud — everything reach-edu's canonical layer holds is one auth gate away. This plan opens that gate the safe way: a per-client instance (the house pattern), not a relaxed org check that would drop reach.edu users into humain-vc's workspace."
4+
date_created: 2026-07-28
5+
date_modified: 2026-07-28
6+
authors:
7+
- Michael Staton
8+
augmented_with:
9+
- Claude Code on Claude Fable 5
10+
semantic_version: 0.0.0.1
11+
tags:
12+
- Plan
13+
- Augment-It
14+
- Deployment
15+
- Multi-Tenancy
16+
- Reach-Edu
17+
status: Draft
18+
---
19+
20+
# Open augment.didi.sh to reach-edu
21+
22+
## Why care?
23+
24+
reach-edu's canonical layer is now substantial — 400+ organizations with
25+
relations and strategy tags, 500+ people, registered corpora, a CRM
26+
already seeded from it — and the humans who work the pipeline (first:
27+
**Stephenie Tesoro <stesoro@reach.edu>**, a tracker row owner) have no
28+
way to see it except over Michael's shoulder. The production stack at
29+
augment.didi.sh already talks to the same SurrealDB Cloud instance
30+
(`rustic-forest-….surreal.cloud`), so the DATA is deployed; what's
31+
single-tenant is the **door**: `DIDI_AUTH=required`,
32+
`REQUIRED_ORG_ID=humain.vc`, `ACTIVE_CLIENT_ID=humain-vc` on
33+
workspace-service.
34+
35+
## The load-bearing constraint
36+
37+
`ACTIVE_CLIENT_ID` pins the tenant PER-INSTANCE, not per-user-org.
38+
Relaxing `REQUIRED_ORG_ID` alone would authenticate reach.edu users into
39+
the humain-vc workspace. Safe multi-client therefore means either
40+
per-client instances (each with its own pin) or real org→client session
41+
binding (a feature in workspace-service). The house has a strong
42+
precedent for the former: every client already gets its own Twenty, its
43+
own hub, its own stack folder (`self-host-stack/client-stacks/<client>`).
44+
45+
## Recommended shape: a per-client instance (Option A)
46+
47+
`reach.augment.didi.sh` — a sibling instance in the same Railway project,
48+
sharing the client-agnostic backends, pinning its own tenant:
49+
50+
| Piece | Action |
51+
|---|---|
52+
| `nats`, `record-surrealdb-resolver`, `content-ingest`, `prompt-runner` | SHARED — already client-agnostic (client rides every request; canonical writes carry `client_access`) |
53+
| `workspace-service-reach` | NEW service from the same Dockerfile. Env: `DIDI_AUTH=required`, `REQUIRED_ORG_ID=reach.edu`, `ACTIVE_CLIENT_ID=reach-edu`, own tiny `/data` volume (sessions + clients root), `PORT=3001` |
54+
| `shell-reach` | NEW build of the shell with its WS URL baked to `wss://ws.reach.augment.didi.sh/ws` (the WS URL is a build-time constant — see DEPLOYMENT.md gotchas) |
55+
| `chat` / `strategy-curator` remotes | SHARED if the shell's remote registry allows cross-origin asset URLs per instance (they're static assets); else thin per-instance builds |
56+
| DNS | `reach.augment` + `ws.reach.augment` CNAMEs per the custom-domain-cutover skill; both must stay on `*.didi.sh` for the shared `didi_session` cookie |
57+
58+
Why A over org-mapping: zero new auth code in the hot path, blast-radius
59+
isolation (a reach-edu session cannot even express a humain-vc
60+
workspace), per-client kill switch, and it matches the per-client stack
61+
doctrine everywhere else.
62+
63+
**Option B (logged, not chosen): org→client binding in workspace-service**
64+
— map didi org → allowed client(s) at session establishment, one domain
65+
serves all tenants. Less infra, more auth surface; becomes worth it
66+
around client #4 or when cross-client operators (us) want one login.
67+
Revisit then.
68+
69+
## Stephenie's onboarding (the identity half)
70+
71+
1. **didi.sh account** under org `reach.edu` in id-didi-sh — the same
72+
unlock/invite flow humain's client user (Aniel) went through; the org
73+
must exist in the identity service before her invite.
74+
2. `checkMembership` then passes against `REQUIRED_ORG_ID=reach.edu` on
75+
the new instance; every write she makes carries her `didi_id` as actor
76+
(attribution rides the envelope — see Workspaces-as-Tenant-Primitive).
77+
3. Her didi_session cookie works across `*.didi.sh`, so the shared-domain
78+
requirement stands.
79+
80+
## Caveats to carry into the build
81+
82+
- **Corpus FILES are not on the deployed volume.** DB-backed surfaces
83+
(workbench, relations, tags, people) work fully; disk-half surfaces
84+
(corpus file browsing, triage's file moves) don't exist server-side.
85+
Fine for v1 — Stephenie's use is the workbench/pipeline view — but say
86+
so in her onboarding note rather than letting her find it.
87+
- **Anthropic credits** gate didi's crawls/chat for everyone, including
88+
her (currently exhausted; billing top-up pending).
89+
- **Which frontends she gets**: the deployed instance today is
90+
shell + chat + strategy-curator. The Org Workbench / search-rail
91+
remotes are NOT yet deployed anywhere — if her job is the org/pipeline
92+
view, deploying those remotes to the reach instance is part of this
93+
plan's scope (three more static-asset services + registry entries).
94+
- **prompt-runner is shared** — one Anthropic key, one spend pool across
95+
tenants. Acceptable now; per-client keys are an Option-B-era concern.
96+
97+
## Build order (when signed off)
98+
99+
1. Railway: mint `workspace-service-reach` (+ volume) and `shell-reach`
100+
with baked WS URL; wire env; deploy from `rebuild/turbo-rsbuild`.
101+
2. DNS: `reach.augment` / `ws.reach.augment` CNAMEs; wait out cert
102+
issuance per the cutover skill (including its stale-cache theater).
103+
3. Deploy the Augment-from-DB remotes (org-workbench, search-results,
104+
search-and-add, person-* ) as static-asset services; register them in
105+
shell-reach's remote registry.
106+
4. id-didi-sh: create org `reach.edu`, invite stesoro@reach.edu; verify
107+
the unlock flow end-to-end (the OAuth pilot discipline from the
108+
Twenty stacks applies: designed-but-unproven until she logs in).
109+
5. Browser drive against reach.augment.didi.sh (workbench loads, client
110+
pin is reach-edu, a humain-vc org is NOT visible), then the human
111+
walk-through: Stephenie's first login as the acceptance test.
112+
6. DEPLOYMENT.md gains the second-instance section; changelog entry.
113+
114+
## Open decisions
115+
116+
1. Sign off Option A (per-client instance) vs holding for Option B.
117+
2. Whether the Augment-from-DB remotes ship in this pass (recommended —
118+
they're the surface Stephenie actually needs) or the chat-first
119+
surface suffices for v1.
120+
3. Who sends Stephenie the invite + onboarding note (content drafted as
121+
part of step 4).
122+
123+
## See also
124+
125+
- `DEPLOYMENT.md` — the humain-vc instance this clones from, including
126+
the CLI gotchas.
127+
- [[../specs/Workspaces-as-Tenant-Primitive]] — the tenancy model;
128+
`client_access` scoping is why the shared backends are safe.
129+
- `custom-domain-cutover` skill — the DNS/cert recipe for `*.didi.sh`.
130+
- [[CRM-Starter-Export-Orgs-Then-People]] — the reach-edu Twenty that
131+
pairs with this instance for Stephenie's workflow.

0 commit comments

Comments
 (0)