# ManyChat case — provenance (BUILD-B · 2026-08-04)

## Screens

| Screen | Source file | What changed | Anonymisation |
|--------|-------------|--------------|---------------|
| Ops review workspace | `LEGIONFARM-3.0/aleksei-manychat-gh/ops.html` + `ops.js` + `applications.css` | Removed GitHub Pages remote JSON override; forced `window.__OPS_URLS__` to `./data/…`; added portfolio lift comment | Applied to `applicants_unified.json` + per-dossier `data/research/*.json` |
| Applications list | `…/applications.html` + `applications.js` + `applications.css` | Data reshaped from flat CSV export fields into the row schema `applications.js` already renders (`applicant`, `submittedBy`, etc.) | Full 2,671-row anonymised fixture |
| n8n research workflow | `…/manychat-dashboard/docs/n8n/3. Research [final]/workflow-configs/3. Research [final] (2).json` | Structure-only JSON → HTML/CSS graph on `index.html` (nodes, types, edges). No screenshot. Execution payloads omitted | N/A (no PII in structure export) |
| Prompt anatomy | `…/manychat/prompts/V3.2-workflows/Node_1_Research_Agent.md` | Section excerpts + annotations on `prompt-anatomy.html`; one internal first name → `[ops lead]` | No API keys found in file (`AIza` / `sk-` scan clean) |
| Partner analytics (Streamlit / React dist) | `manychat/dashboard/app.py`, `manychat-dashboard/frontend/dist` | **Omitted** | Requires Mongo/OAuth/`.env` — not exercised; volumes for top-228 cited as counts only |

## Volumes (each traced)

| Metric | Value | Command / evidence | Source |
|--------|------:|-------------------|--------|
| unified_applicants | 91 | `meta.totalApplicants` / `len(applicants)` | `aleksei-manychat-gh/data/applicants_unified.json` |
| matched_research | 46 | `meta.matchedResearch` | same |
| research_only | 38 | `meta.researchOnly` | same |
| pending_partnerstack | 53 | `meta.totalPartnerstack` | same / pending JSON |
| applications_csv_items | 2671 | `meta.total` | `applications.json` |
| research_dossier_files | 83 (portfolio fixtures) / 85 (source tree) | `len(list((data/research).glob("*.json")))` after anonymise write | anonymise copies matched dossiers; 2 source files unmatched by key |
| top_228_partners | 228 | `len(partners)` | `manychat/dashboard/top_228_partners.json` |
| top_partners_by_revenue_items | 200 | `len(items)` | `top_partners_by_revenue.json` |

## Anonymisation transform

1. Deterministic alias from stable hash of original partner key/email (`alias:<key>` seed).
2. Names from fixed FIRST×LAST pools; emails `partner+NNN@example.test`.
3. Employers → `"{sector} ({size bucket})"` labels.
4. All URLs, social handles, `matchVia`, and free-text dossier fields scrubbed or rewritten.
5. Dates jittered to month precision (day forced to 1).
6. Score, grade, tier, decision enums, and counts preserved exactly.
7. Second-pass scrub against source identity strings (full names, emails, LinkedIn URLs, employer+role phrases). Phone-like digit regex was **not** used after it corrupted ISO dates and CSS lengths in an earlier pass; those artifacts were regenerated from source.

## Secrets encountered (path + kind only)

- `LEGIONFARM-3.0/manychat-dashboard/.env` — env secrets (**not opened / not copied**)
- `LEGIONFARM-3.0/manychat/credentials/partnerstack.credentials.json` — API credentials (**not copied**)
- Inventory also lists partnerbase credential audit dumps — not copied

## Forbidden / not invented

- No generic CRM mock
- No claim that Streamlit analytics ran in this session
- No partnerbase CSV publish
- No merged “thousands of partners researched” headline
