Extraction plan · v1 draft · for red-pen

Sales Visibility — the move out of eve

The call-and-email capture system leaves the personal repo and becomes company infrastructure your team can read, review, and build on — without the live worker ever blinking.

Draft for Robert’s annotation · not approved · no building yet
01

What’s already set

Your direction from today, plus the two choices that keep the move boring. Everything below is built to these.

Direction
It moves
The call-and-email capture system leaves your personal repo and becomes company infrastructure other people can read, review, and eventually build on. Alie asked for exactly this on 08-17 — her words: without it getting into “your personal assistant land.”
Method
Lift and trim
The system, its full test armor, and its ops tooling move. Its dependencies move trimmed: the one import that drags in your personal-assistant machinery is replaced by a small local file. Your private world — commitment reading, beliefs, the world model — stays home.
Continuity
The live worker doesn’t blink
Cutover is one deploy of the same worker on the same Cloudflare account and URL. Granola’s webhook, the every-10-minute ticks, the 6am audit — nothing external notices the code changed homes. Moving the Cloudflare account itself is a separate, later decision.
02

The journey — eight stages, extraction to team-ready

Follow the system as it moves. The two accented stages are where the risk lives; everything else is mechanical.

The one non-negotiable: the test armor travels or the system didn’t move. An extraction that ports the code and leaves the wiring tests behind silently re-opens every hole the courts closed. Test-count parity with the old home is asserted, not assumed.
  1. Skeleton. A new private repo in the Digital Empathy GitHub org — DECIDED and live: customer-comms-input — with its own build, test, and deploy tooling. Nothing in the scaffolding assumes your personal repo exists.
    ↘ go deeper — what the skeleton holds
    package.json · tsconfig pair (src + scripts) · vitest config · wrangler.call-log.toml (same worker name eve-call-log-sync, same crons */10 and 7 12 * * *, same [vars]) · secrets provisioning doc (values never committed).
  2. The cut. The personal-assistant world enters the system through one import — a Gmail types file that also carries the machinery reading your inbox for commitments, which drags in beliefs and the world model behind it. Replace that import with a ~40-line local types file, alias two borrowed “epoch” types in the transports, and the entire personal tail falls away. The compiler is the first gate: the new repo either resolves entirely within itself or the cut isn’t done.
    ↘ go deeper — the verified dependency rings (re-measured today via the import graph, 32 nodes)
    The module (8 files): worker · sync · sweep · email-mirror · sales-classifier · salesforce-client · granola-client · webhook-signature.

    Ring 1, travels trimmed: gmail-transport (minus world-epoch types; thread-cache coupling drops — the module constructs it with threadCache = null, verified) · gmail-body · salesforce-transport · sources/salesforce (trimmed) · sf-rest-executor · sf-write-rail + its five (action, executor, gateway, policy, ledger) · slack-write · anthropic-request · llm-usage-line.

    Replaced, not moved: sources/gmail.ts → local gmail-types.ts (~40 lines: RawGmailThread and friends) · contract/world epoch types → local aliases.

    Does NOT travel (the personal tail): commitment-extractor · commitment-prompt · platform/commitment · belief · world-model · contract/world · contract/trust · contract/person-id · contract/entity-ref · chunked-map-store.
  3. Armor over. Every wiring test travels and runs green in the new home — same fixtures, same assertions, count-matched against the old home at the moment of extraction (357 at the 08-18 measure; they’ve grown with the last sixteen merges, so the count is re-measured, then asserted).
  4. Ops and paper over. The deploy script, the zero-write rehearsal, the daily 6am audit, the on-demand sweep trigger, the corpus grading suite — the tools that operate and grade this system move with it. So do its documents: the reliability matrix, the intent briefs, the conventions study, the trial records — after a privacy pass (client names are fine in a company-internal repo; anything about your personal assistant is not, and stays home).
    ↘ go deeper — the ops inventory
    deploy-call-log.sh · daily-independent-audit.ts · rehearse-email-mirror.ts · fire-admin-sweep.ts · probe-auto-lane-candidates.ts · reconcile-call-log.ts · check-granola-*.ts · rotate-granola-webhook.ts · email-corpus-sheet / score / consistency · corpus-context-probe · corpus-decisions-run. The scheduled 6am task repoints to the new repo at cutover (stage 6), not before.
  5. Prove parity — three independent legs, none graded by the extractor. (a) The full test suite green in the new repo, count-matched. (b) An adversarial court leg diffs old-versus-new behavior on the same fixtures. (c) The live referee: the zero-write rehearsal and the daily audit run from the new repo against the live system — the verdict line must be identical to the same-hour run from the old home. Real mail, real calls, recomputable by anyone.
    ↘ go deeper — why the audit is the strongest leg
    Tests prove the mechanism; the audit proves the decisions on real data (the 08-18 lesson: 11k tests and 8 courts missed what the system decides about real mail). Two audit runs an hour apart from two checkouts hitting the same live world must produce the same line: same writes traced, same refusal classes, same counts. Any divergence is the extraction talking.
  6. Cutover. One deploy from the new repo’s clean main. Same worker name, account, URL — the webhook and every cron keep working untouched. The next morning’s audit line, now produced from the new repo, is the cutover receipt.
  7. One home. After that green morning: the module, its tests, and its ops tooling are deleted from the personal repo in a single named-scope change; the old repo keeps the full history and a pointer to the new home. Between extraction and cutover the old copy is frozen to critical-fixes-only (each such fix lands in both homes) — the freeze window is days, not weeks, precisely so that burden stays near zero.
  8. Team-ready. A README that a smart newcomer can act on (what this is, how to run the rehearsal, how to read the morning line, how secrets are provisioned) · merge-blocking CI running typecheck and the full suite on every change · named code owners · access grants per your call below.
03

Tripwires — each has bitten once already

Standing rules the move must not violate. These are inherited scars, not hypotheticals.

Armor parity is asserted. The test count in the new home equals the old home’s count for the same files, checked mechanically at extraction — never eyeballed.
Secrets change hands deliberately. Nine live secrets power the system. Eight get a provisioning doc in the new repo. The ninth — the Gmail grant — reads your mailbox, which is the system’s whole point: it stays your personal grant no matter who owns the code.
The webhook stays untouched because the worker URL stays untouched. Re-pointing it enters scope only if the Cloudflare account moves — a later decision, not this one.
The trial never skips a day. The 6am audit runs from the old home during the freeze window and from the new one after cutover. Any extraction bug becomes a same-morning “unexplained” line, not a quiet regression.
Deploys only from a clean checkout of the new repo’s main. The deploy bundles whatever tree it runs in — the stale-deploy scar from 08-18 carries over verbatim.
04

Honest risks

What could actually go wrong, and what stands in the way of each.

Drift hiding in the trim. The local types file and two aliases are the only rewritten code — if the move breaks anything, it breaks there. Mitigation: all three parity legs, and especially the live audit-line identity, which checks decisions on real mail rather than types on paper.
Two homes drifting during the freeze. Mitigation: the window is short (target: same week), frozen to critical fixes only, and the cutover date is set before extraction starts — not discovered afterward.
Docs privacy. The court records quote real subjects and client names. Clients are already visible to the team in Salesforce; the pass exists for anything personal-assistant-shaped, which stays home. One curation session, checklist in the extraction change.
History baggage. Preserving per-file history would drag old commit messages from the personal repo into a repo other people read. Recommended instead: fresh start, with the new repo’s first commit pinning exactly which moment of the old repo it was cut from — the old repo stays the permanent archive.
05

Your six calls

The red-pen targets. Starred ones shape everything else; the rest have safe defaults you can wave through.

1. Repo name and org — ANSWERED

Robert, 2026-08-19: customer-comms-input in the Digital-Empathy org, private — live with the founding import.

2. Who gets access, at what level?

Alie read (she asked to read it) · Greg — write? · Derek — any? Code-owner review stays with you until someone else earns it?

3. Cutover timing against the trial

Recommended: extract and prove parity this week, cut over on the first morning with a green parity run — the daily audit is the net either way, and it never skips a day. Alternative: extract now but hold cutover until the two-week trial exits. Extraction itself proceeds under either answer.

4. History

Fresh start (recommended, see the risk card) or preserved per-file history?

5. Cloudflare account

Stay on yours for now (recommended — keeps the webhook and URL untouched). Does the eventual account move get its own plan later, or fold into this arc?

6. The grading tools

The corpus labeling page and weekly-sample tooling (trial leg 2) — move with the system (recommended; they grade this system and nothing else) or stay?

06

Reference strip

By-type lookup into the same atoms.

Stages: skeleton · the cut · armor · ops+paper · parity · cutover · one home · team-ready
Rules: five tripwires · Risks: four cards · Decisions: three set · six open
Canonical source: docs/ai/design/extraction-plan-sales-visibility-2026-08-19.md · prior scope: extraction-scope-call-log-to-de-2026-08-18.md