Extraction plan · v1 draft · for red-pen

Customer Onboarding

The pay-then-discover front door — two small apps joined at the hip — leaves Robert’s old personal monorepo for a company home Alie can own.

EXECUTED 2026-08-20 · cut over same day: production serves from Digital-Empathy/customer-onboarding · courted, 115 tests, receipts in the repo

Jump by type: locked decisions · what moves · the journey · tripwires · honest risks · your six calls

01

Decisions locked (you, this morning)

Four calls made in-session, 2026-08-20 — everything below is built to these.

Repo shape
One repo: customer-onboarding
The two apps are siblings — they share one data store, and the checkout app writes what the discovery app reads. One home makes that visible and gives Alie one thing to own. Each app keeps its own deploy target.
Stale copy
Restart clean
June’s half-finished migration attempt has sat untouched for a month with no working copy anywhere. It gets archived with a pointer; the import is fresh from today’s source.
Checkout links
The new repo takes minting
Going forward, checkout links get made in one place — this repo. The two older link-makers stand down (stage 7). No more risk of two writers against one Stripe account.
Ownership
Alie owns it
Admin on the repo, same as the comms repo. That’s the point of the whole move.
02

The scene — what this actually is

A new practice pays Digital Empathy at checkout.digitalempathyvet.com. The moment the payment lands, their discovery workspace is created at discovery.digitalempathyvet.com and every participant gets a personal link. That whole front door — two small Cloudflare Pages apps joined by one shared data store — lives today inside Robert’s old personal monorepo (the pre-neo Eve), where Alie can’t own it, review it, or safely change it.

The move changes where the code lives — never where the data lives, and never the addresses customers use. Same web addresses, same live workspaces, same payment flow.

↘ go deeper — the exact inventory (recon receipts, 08-19/20)

Checkout appchief-of-staff/checkout-page → Pages project checkout-page. One payment page + two functions: create-checkout.js (creates a Stripe Checkout Session — card or invoice flow — from an HMAC-signed link; the signature prefix binds the flow, so a card link can’t be tampered into invoice terms) and setup-discovery.js (verifies the paid session, seeds the workspace, returns per-person links).

Discovery appchief-of-staff/brand-discovery → Pages project brand-discovery. ~71 files: the conversation engine (its own doc: “the system prompt IS the product”), ten API functions (chat · context · dashboard · manifest · participant · session · setup-chat · setup-discovery · synthesis · transcribe), docs, prompts, data.

The coupling: both apps bind the same KV namespace DISCOVERY_KV (id deaa24f6e7b9438da57e45f3fe110842). setup-discovery.js is byte-identical in both apps’ functions folders (diff-verified 08-20) — the same write path deployed twice.

Link minting today: signed checkout URLs come from chief-of-staff/scripts/lib/checkout_url.py, driven by deal-execution scripts. Separately, eve/neo carries an independent payment-link capability (src/runtime/hands/stripe-hand.ts: customer-create + checkout-link-create, kill-switched by STRIPE_HAND_ENABLED) — a potential second writer.

Uncommitted drift that travels: the discovery app’s untracked tests/setup-discovery.test.mjs and package-lock.json. The import takes the working tree at chief-of-staff commit b6f7d30; drift files named in the founding commit message.

What sheds automatically: the machine-local specialist routing lives in chief-of-staff’s root CLAUDE.md, not the apps’ own files. The discovery app’s own CLAUDE.md is self-contained product doc and travels; the checkout app has none.

03

The journey — seven stages

The proven playbook from last week’s comms-repo move, resized to these apps. Stage 3 is the load-bearing one; stage 7 is the only phase-2 item.

The one non-negotiable: the shared data store never moves. Both apps keep pointing at the live store that holds real customers’ workspaces. Extraction changes where code lives — never where data lives.
  1. Skeleton. New private repo in the company org: two app folders, a fresh README, repo-owned instructions. Nothing from the old monorepo’s machinery.
    ↘ go deeper
    Digital-Empathy/customer-onboarding, private. Folders checkout/ and discovery/. Trunk bootstrapped by branch-push + server-side rename (push-to-main is blocked machine-wide; ccio recipe: gh api .../branches/<b>/rename).
  2. The cut. Copy both apps exactly as they stand today — including real work that was never committed — and record precisely which snapshot of the old monorepo this came from. The payment-to-workspace hand-off function, currently deployed twice, gets one home.
    ↘ go deeper
    Working trees at chief-of-staff b6f7d30, drift included (tests/, package-lock.json). Strip .vercel/, .DS_Store. setup-discovery.js is authored in the checkout app; the discovery app’s byte-identical copy is retired at cutover once the checkout deployment proves it serves. Fresh-start import — the old monorepo stays the permanent archive; no history rides along.
  3. The live-config inventory — the load-bearing stage. The files in the old repo lie by omission: at least one live production setting exists only in the hosting dashboard, written down nowhere. Before anything deploys, pull the complete live configuration of both apps and write it down. Then assert byte-for-byte that everything that traveled matches the source.
    ↘ go deeper
    Found 08-20: binding DISCOVERY_CONTEXTS is referenced by the discovery app’s functions but absent from its wrangler.toml — dashboard-only. Inventory both Pages projects: bindings, env vars, secret names, custom domains. Provisioning doc lands in the repo. Known secret names so far: STRIPE_SECRET_KEY (both apps), CHECKOUT_SIGNING_SECRET (checkout), ANTHROPIC_API_KEY + OPENAI_API_KEY (discovery). Byte-parity assertion over every traveled file.
  4. Honest armor. These apps have one real test, not a suite — and this plan doesn’t pretend otherwise. The one test travels; each app gets a small smoke set; every change to the repo must pass them before it can merge.
    ↘ go deeper
    Smoke set: signed-link verification round-trip (valid signs verify, tampered flow-flip fails) · payment-session dry call · workspace manifest read. CI on every PR, merge-blocking. No parity theater beyond what exists.
  5. Court, then cutover. An independent adversary tries to break it before anything deploys. Then cutover: deploy each app from the new repo to its existing home — same projects, same addresses, same data store. No customer, no webhook, no DNS notices anything. Rolling back means re-serving the previous build.
    ↘ go deeper
    Independent court legs per the standing doctrine (authorship-independent; ccio took three rounds — take every one-liner). Cutover = wrangler pages deploy from the new repo’s clean main into projects checkout-page and brand-discovery. Pages keeps deployment history — rollback is re-serving the prior deployment. Cloudflare account migration is explicitly out of scope (later decision, same as ccio).
  6. One source of truth. After a green day: the two app folders come out of the old monorepo with a pointer left behind, and the two decoy homes — June’s stale copy and the dead standalone from February — get archived so nobody ever edits the wrong one.
    ↘ go deeper
    Named-scope removal commit in chief-of-staff (exactly two folders, pointer README left). Archive Digital-Empathy/brand-discovery (stale June copy) with a pointer; archive ae-robertsanchez/checkout-page (Vercel-era, dead since 02-20) — pending your call 3.
  7. Minting consolidates — the phase-2 item. Gated behind a green stage 6. The link-signing tool moves into the new repo as the one way checkout links get made, and both older link-makers stand down — the old monorepo’s scripts (already dormant) and eve’s newer payment-link capability (switched off with a working undo). From that day, a checkout link has one author. Who mints day-to-day is your call 4.
    ↘ go deeper
    The signing logic of checkout_url.py lands in the repo (script or admin endpoint per call 4). eve’s hand: first inventory whether it ever held a green validation record or produced live receipts; then STRIPE_HAND_ENABLED=0 — reversible by flipping back. The declaration “customer-onboarding is the sole minter” goes in both repos’ docs.

Team-readiness rides stages 1–6 rather than being a stage: a README a stranger can operate from (what this is · how a link is minted · how a workspace is seeded · how secrets are provisioned), a one-line receipt on every deploy, and a documented door for the known reality that live workspaces have needed hand-repair twice before (July) — documented, not improvised.

04

Tripwires

Each of these has already bitten once — here, or on the comms-repo move.

T-1Dashboard-hidden config
Bit during recon: a live production setting exists in no file. Stage 3 exists because of this — nothing deploys before the live inventory is on paper.
T-2The store never moves
A “clean” extraction that re-created the data store would orphan every live customer workspace. Both apps keep the production store, full stop.
T-3The doubled write path
Until the dedupe lands, the same function is served from two deployments — changing one and not the other is silent drift. Dedupe is in stage 2 on purpose.
T-4Secrets move deliberately
The dead February repo’s local files hold Robert’s personal Salesforce credentials — they die with the archive, never travel, reissued only if a future need is proven.
T-5Worktree discipline
Every command pins its working directory; commit early and often; nothing runs from the shared eve checkout. The 08-19 worktree gremlin is still at large.
T-6Clean-main deploys only
Deploys come from a clean checkout of the new repo’s main — the stale-deploy scar carries over verbatim.
05

Honest risks

Thin armor is thin
Byte-parity + smoke tests is the honest bar — not the 11k-test bar the comms repo had. Offset: the apps are small, the court leg is real, and cutover is same-target with instant rollback.
Live customers underneath
Real practices’ workspaces sit in the shared store today. The move never touches the store — and stage 3 proves the new deployments carry identical live settings before they serve a single customer request.
Minting touches sales motion
Stage 7 changes how money-links get made. Offset: phase-gated behind the green extraction, switch-off has a working undo, and until it lands nothing changes about how links are made.
The old monorepo keeps running
This plan removes exactly two folders from it and claims nothing else. Whatever else the old Eve does, it keeps doing — untangling the rest is not this arc.
06

The six calls — answered

Answered 2026-08-20, one directive: “drive towards the end state in this build.” Applied: cutover this week on the first green parity day · Alie admin after the privacy pass · the dead February repo is archived · the minting tool is built NOW in this repo (admin page fast-follow on Alie’s ask) and both older writers stand down · deploy receipts + weekly health line built in this arc · privacy pass before team access.
1
Cutover timing.
Recommended: extract and prove parity this week; cut over on the first green parity day. Same-target cutover makes the risk window minutes, not days.
4
Day-to-day minting, once this repo is the one author.
(a) the signing tool as a small script in the repo — parity with today, recommended landing point · (b) a tiny admin page so Alie can mint a link without a terminal — fast follow if she wants it · (c) eve calls the new repo when deals close — only if deal automation proves the need.
2
Access.
Alie admin is decided in spirit. Anyone else — Greg? Derek? Review duty Robert-only until earned?
3
The dead February checkout repo.
Archive it? Recommended yes — reversible, and it removes a decoy home.
5
Ops cadence.
Recommended: a receipt on every deploy + a weekly one-line health check (store reachable · both addresses serving · last deploy identified). Daily would be ceremony beyond these stakes.
6
Privacy pass before team access.
The discovery app’s docs and data carry real client work. Client names are already team-visible in Salesforce; the pass is for Robert-personal residue — one curation session, checklist in the founding PR. Recommended: yes, before anyone else gets the keys.