Source

Meridian Outreach Vault

The Obsidian vault behind a print and display shop's quarterly client outreach: a weekly pipeline that keeps a partner-client census current, and audited email drafts a person approves. The company and its clients are fictional; the client book is a generated sample run through the real pipeline.

  • Python
  • Obsidian
Repository
mattrguerra/meridian-outreach-vault
Branch
main
Files
271 files · 38 folders
Languages
Python 100%
Visibility
Private on GitHub, published here in full

Meridian Outreach Vault

The Obsidian vault and Claude Cowork project behind a print and display shop's quarterly client outreach. One linked note per partner client, a machine-readable census over all of them, a weekly pipeline that keeps both current from the order system, and a drafting pipeline that turns research into audited emails a person approves before anything is sent.

The company is fictional, and so is every client. This vault was built for, and run every week at, a real print and display shop. Here it serves Meridian Display Co., the invented company behind meridian-ops-board, meridian-crm-mcp, meridian-orders-mcp and meridian-skills. The notes, rules, code and history are the real ones with the business taken out: staff, clients, programs, products, links and numbers are invented. The one real person is Matt Guerra, who built and ran it.

The client book is a generated sample. No real client record survived the move. In its place, 07-Automation/sample/generate_sample.py invents 381 order-system accounts, two weeks of orders and two weeks of CRM deals, and run_sample.py replays two Monday runs of the real weekly driver against them. Every stub in 03-Clients/, the census, both weekly workbooks and the outreach audit are that driver's own output. On top of that, ten stubs carry hand-written research and eleven sample drafts sit in the email pipeline, all invented. The history notes (LEDGER, DECISIONS, CHANGELOG) describe the system as it ran on the real book, at real scale, with invented numbers.

For live numbers, start at 00-Index. For how Claude works here, see CLAUDE.

What it does

  • Keeps a census of the Partner Program. Every client whose lifetime spend puts them in a tier (Palladium, Platinum, Iridium, Rhodium) has a stub in 03-Clients/client-stubs/ and a chunk in 03-Clients/partner-client-master-list.xml, carrying their order-system id, CRM contact id and every outreach funnel they sit in.
  • Runs itself weekly. The Weekly Partner Client Pipeline pulls the week's orders from Plinth (the order system), recomputes lifetime value, classifies, refuses to continue if any total shrank, writes and upgrades stubs, refreshes the census and the roster workbook, reconciles the CRM's deals, proposes who to contact next, and audits who was actually contacted and when.
  • Drafts outreach with a human in the loop. Emails are drafted in Matt's voice from the stub's sourced research, scored for confidence, audited in three passes (facts, voice, template), and moved stage by stage through 05-Outputs/First Email/ and 05-Outputs/Second Email/. Nothing is sent, and no CRM record is written, without a person.

Vault map

Folder What's in it
01-Tiers/ Partner tier notes (Palladium / Platinum / Iridium / Rhodium, and Retail) with Dataview rollups of their members.
02-Outreach/ Outreach play notes, the approved email templates, call scripts.
03-Clients/ client-stubs/ (one note per client, flat), the XML census, and the folder rules (CLAUDE-clients).
04-Working/ In-progress review notes.
05-Outputs/ The two email pipelines, each weekly run's artifacts (partner-runs/), and the outreach audit workbooks.
06-Resources/ The drafting prompts.
07-Automation/ The weekly driver, its config, SOP, routing rules, runbook, schedule, local data, and the sample generator.
08-Planning/ Human-only planning space. Claude reads it, never writes to it.

The weekly pipeline

07-Automation/weekly_partner_pipeline.py is the entry point of one deterministic program (Python, pyyaml, openpyxl; the code is the 07-Automation/partner_pipeline/ package, one module per stage) that never calls an API itself: the scheduled Claude session makes the Plinth and Bitrix calls through their MCP servers and hands the raw responses to it. The design decisions worth reading:

  • Incremental by necessity. Plinth's orders.fetch silently truncates large result sets (about 70 orders a response, no "has more" flag) and its offsets overlap. So lifetime value is never asked of the API: it comes from a local, append-only order history seeded once from the roster workbook, and each week's pull is paged day by day until a page adds nothing new. See DECISIONS, 2026-07-22.
  • The no-shrink guardrail. Lifetime totals can only grow. If one shrinks, verify exits 2 and the run stops before anything is written: missing data must never demote a client.
  • Relationship over arithmetic. An approved-merge registry folds one person's duplicate accounts together, and per-email tier overrides hold a directly-partnered account at its tier whatever each mailbox spent, and keep it out of cold outreach entirely.
  • Identity-level exclusion. Opt-outs and open deals are unioned across every census chunk that shares an email or a name, so a duplicate record can't route someone who asked not to be contacted.
  • Contact means a send. The audit counts only stage entries with a real email, call or DM behind them (SEND_TOKENS), keeps retired stages named so old sends still count, collapses same-minute workflow re-entries, and reuses cached histories for deals that cannot have changed.
  • Human-gated writes. The driver writes to the vault only. Every CRM change (a deal, a stage move) goes through a person.

The drafting pipeline

Stage Meaning
01 - Drafted Written, not yet audited.
02 - Audit Result/audit-PASS Cleared the three-pass audit (confidence scored as a percentage).
02 - Audit Result/audit-FAIL Failed the audit; needs rework before it can move on.
03 - Unsent Audit passed and approved. Queued to send.
04 - Sent Sent.
05 - Archive Permanently withdrawn: opt-out, or otherwise taken out for good.
06 - Parked Temporary hold for a non-audit issue (vault or routing) pending review.

Drafts use the matt-guerra-email skill for voice and follow the rules in Email-1-Drafting-Prompt and Email-2-Drafting-Prompt: no em dashes, none of the giveaway vocabulary, and no claim without a source.

Replay the sample

The replay is the regression check: rebuilt from nothing, the sample must come out the same. Run it on a scratch copy, because it rewrites the generated state:

pip install -r 07-Automation/requirements.txt
cp -R . /tmp/vault-replay && cd /tmp/vault-replay
rm -rf 03-Clients/client-stubs 03-Clients/partner-client-master-list.xml \
       05-Outputs/partner-runs 07-Automation/data/order_history.json \
       07-Automation/data/outreach_touch_cache.json
python3 07-Automation/sample/generate_sample.py
python3 07-Automation/sample/run_sample.py
diff -rq -x .git -x '*.xlsx' -x raw -x __pycache__ "$OLDPWD" .

The diff should list only the ten stubs with hand-written research: they are examples added on top, and the replay does not regenerate them. The workbooks match cell for cell but not byte for byte, so they are left out of the diff. The replay also copies each day's Plinth pages into 05-Outputs/partner-runs/raw/, which is not committed; the one committed copy is 07-Automation/sample/inputs/plinth/.

To browse, open the folder as a vault in Obsidian and install the Dataview community plugin (enable JavaScript queries). See SETUP.

Working here

Two operators work this vault through separate Cowork projects synced over Obsidian: Matt and Hazel. Every change is logged in LEDGER with who made it, attributed by session email. Before you build on someone else's synced changes, skim the ledger to see what they touched.

Reference

00-Index · CLAUDE · MEMORY · HEARTBEAT · LEDGER · DECISIONS · CHANGELOG · SETUP · MODEL_GUIDE · SKILLS_REFERENCE · CLAUDE-clients · Source-Documents