DR-002: Synthetic Demo Data
Date: 2026-10-15
Status: Active
Decision
The public demo site uses only synthetic personas generated by script. No real chat data is committed to the repository or deployed to the live site.
Context
The goal of the demo site is to showcase the methodology — how the linguistic feature extraction and persona generation works — without requiring users to install the tool or share their own data.
Options for demo data:
- Use anonymized real data (my own chat history)
- Use synthetic data generated by script
- Use no data (documentation only)
Real chat data, even anonymized, carries re-identification risk:
- Catchphrases might be unique enough to identify me
- Conversation timestamps reveal time zone and routines
- Code-switching patterns correlate with identity
- Contact names (even hashed) could leak through message content
Options Considered
Option A: Anonymized real data (rejected)
- Extract my own WeChat history
- Replace names with pseudonyms
- Aggregate timestamps to hour-of-day bins
- Remove identifying catchphrases
- Rejected: Still risky. "Anonymous" data can often be re-identified through feature correlation. Not worth the privacy trade-off for a demo.
Option B: No data, docs only (rejected)
- Explain the methodology in prose
- Show example outputs as static text
- No interactive persona gallery
- Rejected: Less engaging. Users want to see working examples, not just descriptions.
Option C: Synthetic personas (chosen)
- Script generates 150+ synthetic messages per persona
- Vary linguistic features: length, emoji, code-switching, catchphrases
- Run the original pipeline to produce realistic stats
- Commit generated
metadata.json,stats.json,profile.md,persona_prompt.txt
Why
Privacy: Zero risk. No real data involved.
Pedagogical clarity: Synthetic personas can be designed to highlight specific feature combinations (e.g., one persona with high emoji rate, one with heavy code-switching). This makes the demo more educational than cherry-picked real examples.
Reproducibility: Generation script is committed. Anyone can regenerate or extend the personas.
Honest labeling: The site clearly states "synthetic personas only" on every page. No attempt to pass them off as real.
What Happened
Generated 6 synthetic personas with diverse profiles:
| Persona | Avg Length | Code-Switch | Emoji Rate | Style |
| ----------------------- | ---------- | ----------- | ---------- | ------------ |
| Bilingual Early Adopter | 25 chars | 40% | 0.3/msg | casual_tech |
| Concise Mandarin | 12 chars | 0% | 0.05/msg | formal_zh |
| Expressive English | 60 chars | 100% | 0.25/msg | expressive |
| Balanced Bilingual | 35 chars | 50% | 0.15/msg | professional |
| Emoji Enthusiast | 18 chars | 10% | 0.6/msg | playful_zh |
| Technical Researcher | 55 chars | 70% | 0.08/msg | academic |
The synthetic data spans the feature space well (verified by inter-persona variance analysis on /validation). Users can explore diverse linguistic patterns without any real privacy risk.
Metrics:
- 6 personas × 150 messages = 900 synthetic messages total
- Generation time: ~2 seconds on M2 MacBook Air
- Committed data size: ~120 KB (profiles + stats + prompts)
What I'd Change
If extending the demo:
- More personas: Could generate 20+ personas to show finer-grained variation. Current set of 6 is sufficient for proof-of-concept.
- Parametric generation: Instead of hard-coded message templates, sample from linguistic models (e.g., n-gram models conditioned on desired feature values). Would produce more naturalistic synthetic text.
- Adversarial evaluation: Test whether LLMs using the synthetic persona prompts actually replicate the target feature distributions (prompt effectiveness validation, now added in this upgrade).
For this demo, simple template-based generation was adequate.