mattrguerra/meridian-outreach-vaultmainPrivate on GitHub, published here in full

CLAUDE-clients.md

Language Markdown7.7 KB138 lines

03-Clients/CLAUDE-clients.md

  1. ---
  2. type: claude-instructions
  3. scope: 03-Clients
  4. tags: [claude, outreach, clients, rag]
  5. created: 2026-06-16
  6. updated: 2026-08-12
  7. ---
  8. # CLAUDE: 03-Clients (scoped rules)
  9. Governs everything under `03-Clients/`. Logged in root [[CLAUDE]]. Read this before
  10. creating, editing, or enriching anything in this folder.
  11. ## Folder layout: what lives where
  12. ```
  13. 03-Clients/
  14. ├── CLAUDE-clients.md ← this file (the only .md at this level)
  15. ├── partner-client-master-list.xml ← Partner Program master list (schema 3.0)
  16. └── client-stubs/ ← ALL client stubs, one .md per client, flat
  17. ```
  18. - **Every client stub lives in `client-stubs/`.** Never at the `03-Clients/` root, never in
  19. new subfolders. The root holds exactly two files: this one and the XML map.
  20. - Dataview rollups elsewhere (tier notes, outreach notes, [[00-Index]]) query
  21. `"03-Clients/client-stubs"`, so a stub saved anywhere else silently drops out of every
  22. rollup. Keep the folder flat rather than "fixing" the queries.
  23. ## The two layers, and which one you touch
  24. 1. **Stubs (`client-stubs/*.md`):** the full per-client record. This is the write target
  25. for enrichment and human-facing work.
  26. 2. **Master list (`partner-client-master-list.xml`):** the client-centered RAG-chunked
  27. census of the Partner Program, derived from the stubs plus Bitrix. It never holds
  28. information that contradicts a stub. **When the two disagree, the stub wins** and the XML
  29. gets corrected.
  30. ## Stub anatomy: the live shape
  31. Stubs are authored by `_create_stub()` in `07-Automation/weekly_partner_pipeline.py`.
  32. `_templates/client-stub.md` mirrors it (plus a `plinth_id` slot, see Known drift). Build any
  33. hand-made stub from that template so hand-made and driver-made stubs stay identical.
  34. Sections, in order:
  35. `frontmatter` → `# First Last` → `## Snapshot` → `## Order History` →
  36. `## Research` (`### Company`, `### Person / LinkedIn`, `### Recent News & Signals`,
  37. `### Sources`) → `## Human Notes` → `## Outreach Log`
  38. `## Outreach Log` uses the six-column header shared by all stubs:
  39. `| Date | Pipeline | Channel | Template | Outcome | Next step |`
  40. There is **no `## Links` section**, and stubs carry **no tier or outreach wikilinks**.
  41. Segmentation is frontmatter-driven: see below.
  42. ### Frontmatter: universal keys
  43. In this order (every key is on every stub except `plinth_id`; see Known drift):
  44. `type` · `bitrix_id` · `plinth_id` · `first_name` · `last_name` · `email` ·
  45. `user_group` · `user_group_correct` · `industry` · `company` · `phone` · `ltv` ·
  46. `repeat_revenue` · `title` · `company_website` · `total_orders_count` ·
  47. `last_order_date` · `source` · `last_modified` · `tags`
  48. ### Conditional
  49. - `outreach_pipelines`: present only once a client enters a Bitrix funnel. Keys:
  50. `partner_outreach` (cat 24, Partner Tier Upgrade), `quarterly_checkin` (cat 36),
  51. `winback` (cat 26). Each carries `stage`, `status`, `entered`, `last_touch`, `next_step`,
  52. `next_date`. Omit the block entirely rather than writing an empty one; this mirrors
  53. `<pipelines count="0" />` in the XML.
  54. ### Do not add these
  55. - `enrichment_status`, `email_one_status`, `email_two_status`: retired. Added 2026-06-16,
  56. dropped by the 2026-07-23 rebuild; the driver has never written them since. 0 stubs.
  57. - `updated`: an old `enrich_writeback.py` defect left it on some stubs of the live book (none in the sample). **The date key is
  58. `last_modified`.** Normalize it away if you touch a stub that has both.
  59. - `outreach_type`, `seniority`, `total_orders_usd`, `city`, `state`, `winback_done_before`,
  60. `linkedin`, `company_linkedin`: legacy pre-2026-07 fields. 0 stubs.
  61. ## Segmentation: which field to trust
  62. - **`user_group_correct` is the tier.** Pipeline-computed. In the shipped sample:
  63. Palladium 86 / Platinum 29 / Iridium 8 / Rhodium 7. Filter and roll up on this.
  64. - **`user_group` is the raw Plinth store group and is blank on every sample stub (130 of
  65. 130).** Never filter on it. It is kept only as a record of what Plinth reports.
  66. - **Outreach play comes from `outreach_pipelines`**, not from a field.
  67. ## Master-list contract (schema 3.0)
  68. - **Root:** `<partner_client_master_list schema_version="3.0">`. One `<client>` element per
  69. partner client = one self-contained retrieval chunk. Chunk at the `<client>` boundary;
  70. each `<pipeline>` repeats `<client_ref>` so per-pipeline sub-chunks stay self-identifying.
  71. - **Dual identifiers:** every `<client>` carries `<bitrix_id>` (CRM contact id) and
  72. `<plinth_id>` (Plinth backend user id) alongside the stable `id` attribute (the RAG key).
  73. A blank `<bitrix_id />` means the client isn't in the CRM yet.
  74. - **Stable key:** `id` = Bitrix contact / tracker id for pipeline-mapped clients; for a
  75. partner client not yet in Bitrix, `id` = `pl-<Plinth user_id>`. Never reuse or renumber.
  76. Reconcile when the client later gets a Bitrix contact and enters a pipeline.
  77. - **`<summary>` is auto-generated** from the other fields. Regenerate it whenever any field
  78. of that client changes; never hand-edit it in isolation.
  79. - **Stub pointers:** `<stub><relative_path>` is `/03-Clients/client-stubs/<file_name>`, and
  80. the same path ends the `<summary>`. Rename or move a stub and both must be updated.
  81. - **Coverage:** every partner client (Palladium and up) should have a `<client>` chunk
  82. whether or not they're in a pipeline. The weekly `refresh-xml` stage adds missing chunks
  83. and re-stamps the rest. Two Plinth accounts that are the same person (same name + email)
  84. share one chunk; colleagues on a shared company mailbox each get their own. Non-partner
  85. customers are not auto-added.
  86. - **Sync duty:** any change to a client's identity, tier, or pipeline placement in a stub must
  87. be mirrored into that client's chunk (fields + regenerated `<summary>`) in the same
  88. change-set.
  89. - **Validate the XML parses after any edit**
  90. (`python3 -c "import xml.etree.ElementTree as ET; ET.parse(...)"`). A broken map is worse
  91. than a stale one.
  92. ## The scraping-dump contract
  93. - Append scraped/enriched data **only** under `## Research`, inside the labelled subsections
  94. (Company, Person / LinkedIn, Recent News & Signals, Sources).
  95. - Every scraped claim gets a source URL under `### Sources`. **No source, no claim.**
  96. - **Never** write into `## Human Notes`: that space is Matt's and Hazel's.
  97. - Update frontmatter (`title`, `industry`, `company_website`, `phone`) when scraping confirms
  98. or corrects it, and bump `last_modified`.
  99. - If a field is unknown, leave the `[TBD]` marker. Do not invent it.
  100. ## Linking
  101. - Link to a stub by **bare name** (`[[Celia Iverson]]`), not by path. Bare names resolve
  102. wherever the stub lives.
  103. - Exception: if the target filename is ambiguous (the same basename exists in more than one
  104. folder), use a path-qualified link with an alias, or you may resolve to the wrong file.
  105. - Stubs do **not** link out to tier or outreach notes. Don't add such links; the rollups
  106. read frontmatter.
  107. ## Known drift: verified 2026-09-21
  108. Flagged, not fixed. Read around these until they're resolved:
  109. - **A stub's `## Order History` body can lag its frontmatter.** The driver writes the body
  110. only when it creates the stub (`_create_stub()`); upgrades (`_upgrade_stub()`) refresh
  111. frontmatter only (`ltv`, `repeat_revenue`, `total_orders_count`, `last_order_date`,
  112. `user_group_correct`, `last_modified`). **Frontmatter is the live record;** trust it over
  113. the body. Example: [[Celia Iverson]] shows a higher `ltv` in frontmatter than in her body.
  114. - **The driver does not write `plinth_id` into stub frontmatter.** Stubs carry it only where
  115. it was backfilled by hand (none of the sample stubs do). The census `<plinth_id>` is always
  116. set, so resolve a stub's Plinth account through its XML chunk.
  117. ## Ledger
  118. Any change in this folder (stub edits, XML updates, moves) is a vault change: one batched
  119. entry in [[LEDGER]] before the turn ends.