persona-composer
Compose Dutch-context personas on-demand from external trait pools and pre-authored coupled archetype bundles. Returns 1-30 composed personas given optional constraints (domain + role catalog, count, diversity requirements, output format). All output in Dutch. Callable by other skills (ontdek-kansen, business-case-management, user-research) via the Skill tool when they need disposable, domain-relevant persona sets.
What this skill does
# Persona Composer
Je stelt Nederlandse personas samen door **pre-geschreven gekoppelde archetype-bundles** te combineren met **onafhankelijke trait-pools**. Je genereert niet vanaf nul — je assembleert uit catalogi onder `data/`. Output is in het Nederlands tenzij de caller expliciet anders vraagt.
## Kernaanpak
Een persona bestaat uit twee lagen:
1. **Gekoppelde bundels** (12 families): vooraf geschreven clusters van sterk correlerende traits (bv. werk ↔ inkomen ↔ huishouden ↔ woonvorm). Willekeurig combineren van hun onderdelen produceert implausibele mensen, dus ze worden als geheel gekozen.
2. **Onafhankelijke traits**: hobbies, media, tech, attitudes, dieet, sociale stijl, dagelijkse routine. Deze kiezen we per persona uit trait-pools, gefilterd op compatibility-tags.
Compositie = voor elke persona één bundle uit elke familie + onafhankelijke overlay + optionele domein-rol + optionele behavioral layer.
## Input-contract
De caller geeft één van:
### A — Natuurlijke taal
Voorbeeld: "8 NL mantelzorgers, diverse leeftijd, 30% migratie-achtergrond, slim format"
### B — JSON-block (voorkeur voor programmatische aanroep)
```json
{
"count": 8,
"domain": "zang" | null,
"domain_role_catalog": ["zangleraar", "koorlid-beginner", ...] | null,
"diversity": {
"age_bands": ["<25", "26-45", "46-65", "65+"],
"regions": ["G4", "middelgroot", "dorp"],
"ses": ["laag", "midden", "hoog"],
"migration_bg_share": 0.25,
"gender_mix": { "m": 0.45, "v": 0.45, "x": 0.10 }
},
"output_format": "full" | "slim" | "narrative-only",
"behavioral_layer": true | false,
"return_as": "markdown" | "structured-json",
"output_dir": "<optional caller-specified path>"
}
```
### Defaults bij ontbrekende velden
| Veld | Default |
|---|---|
| `count` | interview-modus (vraag om count) |
| `domain` | `null` (geen rol-overlay) |
| `diversity` | redelijke spreiding over leeftijd + regio + SES |
| `output_format` | `slim` |
| `behavioral_layer` | `false` |
| `return_as` | `markdown` |
| `output_dir` | `composed-personas/<YYYY-MM-DD-HHmm>/` in caller's cwd |
### Interview-modus
Als input onduidelijk is, vraag **alleen** naar: `count`, `domain` (optioneel), en ruwe `diversity`-wensen. Daarna direct composeren.
## Data-laag
Alle catalogi leven onder `${CLAUDE_PLUGIN_ROOT}/skills/persona-composer/data/`:
```
data/
├── archetype-bundles/ # 12 families, elk met meerdere MD-bundles
│ ├── work-family-housing/
│ ├── faith-routine-worldview/
│ ├── health-work-arrangement/
│ ├── identity-politics-social-trust/
│ ├── education-career-mobility/
│ ├── migration-generation-culture/
│ ├── regional-rootedness/
│ ├── parenthood-partnership-timepoverty/
│ ├── life-stage-transition/
│ ├── expertise-information-trust/
│ ├── caregiving-boundary/
│ └── financial-precarity-coping/
├── independent-traits/
│ ├── hobbies.yaml
│ ├── media-consumption.yaml
│ ├── tech-profile.yaml
│ ├── attitudes-sustainability.yaml
│ ├── attitudes-privacy.yaml
│ ├── attitudes-technology.yaml
│ ├── attitudes-health.yaml
│ ├── attitudes-housing.yaml
│ ├── attitudes-immigration.yaml
│ ├── diet-patterns.yaml
│ ├── social-style.yaml
│ ├── daily-routine-templates.yaml
│ ├── domain-roles/
│ │ └── zang.yaml (+ later andere domeinen)
│ └── names/
│ ├── first-names-nl.yaml
│ ├── first-names-migrant.yaml
│ └── last-names.yaml
└── demographics/
├── regions.yaml
├── occupations.yaml
└── income-bands.yaml
```
Laad **selectief** — nooit alle bundles tegelijk inlezen. Eerst de `## Tags` blokjes scannen, dan alleen de geselecteerde bundle volledig lezen.
## Bundle-formaat
Elke bundle is een markdown-file met deze secties:
```markdown
# <bundle-id>: <korte titel>
## Tags
age-band: <min-max of lijst>
region: <G4 / middelgroot / dorp / krimpregio / biblebelt / ...>
urbanization: <1-5>
ses: <laag / midden / hoog / variabel>
household: <single / dual-income-no-kids / gezin-jong / gezin-tiener / empty-nester / single-parent / ...>
housing: <huur-sociaal / huur-vrij / koop-appartement / koop-huis / ouderlijk / ...>
education: <VMBO / MBO / HAVO / HBO / VWO / WO>
migration-bg-compatible: <any / nl-only / migration-1st / migration-2nd / migration-3rd>
variant-hash: <unique-id binnen familie>
## Incompatible-with
- <lijst met bundle-ids of tag-criteria die uitgesloten zijn>
## Narrative building-blocks
### Work
<2-4 zinnen, concreet en NL>
### Family
<2-4 zinnen>
### Housing
<2-4 zinnen>
### Financial picture
<2-4 zinnen>
### Compositie-hooks
Overlay-bias voor onafhankelijke trait-pools:
- hobby: <bias>
- attitudes: <bias>
- media: <bias>
```
## Trait-pool-formaat (YAML)
```yaml
# hobbies.yaml
- id: koorzang
label: Koorzang (wekelijks, amateur-koor)
tags:
age: [26-45, 46-65, 65+]
ses: [laag, midden, hoog]
region: [G4, middelgroot, dorp]
bundle-affinity: [faith-routine-worldview, regional-rootedness]
- id: padel
label: Padel (2x/week met collega's)
tags:
age: [26-45]
ses: [midden, hoog]
region: [G4, middelgroot]
```
## Compositie-algoritme
Voor een aanroep met `count = N`:
### Stap 1 — Slot-planning
Verdeel N personas over de diversity-constraints. Bijvoorbeeld `count=8, age_bands=["<25","26-45","46-65","65+"], migration_bg_share=0.25`:
- Slot-plan: 2 × `<25`, 3 × `26-45`, 2 × `46-65`, 1 × `65+`; 2 slots met migratie-bg; regio-verdeling proportioneel
- Elke slot krijgt een constraint-profiel mee
### Stap 2 — Bundle-lock per slot
Voor elke slot:
1. Lees alle `## Tags`-blokken uit alle 12 families (snel, alleen metadata)
2. Filter per familie op compatible bundles voor deze slot
3. Kies één bundle per familie die onderling niet botsen (check `Incompatible-with`)
4. Als geen combinatie mogelijk: relax één constraint (eerst SES, dan regio), en probeer opnieuw
### Stap 3 — Independent overlay
Voor elke slot met gelockte bundles:
1. Lees de trait-pools die nodig zijn
2. Per pool: filter op slot-constraints + bundle-compatibility-tags + `Compositie-hooks` uit de bundels
3. Kies 1 entry (bv. tech-profile) of 2-4 entries (bv. hobbies)
### Stap 4 — Domein-rol (optioneel)
Als `domain_role_catalog` opgegeven:
1. Kies één rol uit de catalogus
2. Rol mag 1-2 onafhankelijke traits nudgen (bv. "zangleraar" → zorg dat `koorzang` of `solozang` in hobby-overlay zit)
3. Rol overrult geen bundel. Als rol incompatibel met gelockte bundels → re-roll bundels, niet de rol
### Stap 5 — Naamgeving
Kies voornaam uit juiste namenpool op basis van geboortejaar (afgeleid van leeftijdsband) en migratie-bg-tag. Achternaam uit `last-names.yaml`.
### Stap 6 — Behavioral layer (optioneel)
Als `behavioral_layer: true`: derive 18 behavioral-velden uit de narrative-cluster volgens de derivation-rules (geïnspireerd op `generate-realistic-person`). Label onzekere velden als `inferred` of `speculative`.
### Stap 7 — Plausibility-check
Run `consistency/plausibility-rules.md` + `implausible-combinations.yaml`:
- Hard fails → re-roll bundels
- Soft warns → log in `### Notes` van de persona
- Bij 2x hard fail op dezelfde combo → markeer combo als implausibel, kies andere
### Stap 8 — Render
Genereer markdown in het opgegeven `output_format`:
**`full`** (~20 secties): matcht stijl van bestaande `personas/` files
**`slim`** (13 secties): Background / Demographics / Work / Income & status / Family / Housing / Health & lifestyle / Personality & values / Hobbies & interests / Tech & media / Attitudes / Goals / Pains & frustrations
**`narrative-only`** (~1 paragraaf): één achtergrondalinea + basis-demografie + 1 hobby + 1 attitude
Elke persona krijgt een trailing traceerbaarheidsblok:
```markdown
### Compositie
- work-family-housing: <bundle-id>
- faith-routine-worldview: <bundle-id>
- health-work-arrangement: <bundle-id>
- identity-politics-social-trust: <bundle-id>
- education-career-mobility: <bundle-id>
- migration-generation-culture: <bundle-id>
- regional-rootedness: <bundle-id>
- parenthood-partnershRelated in General
modeling-omnistudio-epc-catalog
IncludedSalesforce Industries CME EPC product-modeling skill for Product2-based catalog creation. Use when creating EPC products, configuring product attributes, building offer bundles with Product Child Items, or reviewing EPC DataPack JSON metadata for product catalog changes. TRIGGER when: user creates or updates Product2 EPC records, AttributeAssignment payloads, AttributeMetadata/AttributeDefaultValues, Offer bundles, or ProductChildItem relationships. DO NOT TRIGGER when: designing OmniScripts/FlexCards/Integration Procedures (use building-omnistudio-omniscript, building-omnistudio-flexcard, or building-omnistudio-integration-procedure), implementing Apex business logic (use generating-apex), or troubleshooting deployment pipelines (use deploying-metadata).
relationship-science-coach
IncludedUse this skill for direct, practical adult relationship coaching: couples conflict, repair, trust, marriage, dating, flirting, attachment patterns, emotional connection, sex, desire differences, eroticism, kink negotiation, affection, love languages, breakups, and long-term passion. Draw on Gottman, EFT and Hold Me Tight, attachment science, modern sex research, Perel, Nagoski, Kerner, Schnarch, Love and Stosny, and flexible love-language tools. Be concrete and low-hedge. Redirect only for imminent danger, abuse, coercive control, minors, non-consent, self-harm, stalking, or medical/legal/psychiatric decisions.
building-sf-integrations
IncludedSalesforce integration architecture and runtime plumbing with 120-point scoring. Use this skill to set up Named Credentials, External Credentials, External Services, REST/SOAP callout patterns, Platform Events, and Change Data Capture. TRIGGER when: user sets up Named Credentials, External Services, REST/SOAP callouts, Platform Events, CDC, or touches .namedCredential-meta.xml files. DO NOT TRIGGER when: Connected App/OAuth config (use configuring-connected-apps), Apex-only logic (use generating-apex), or data import/export (use handling-sf-data).
venue-templates
IncludedAccess comprehensive LaTeX templates, formatting requirements, and submission guidelines for major scientific publication venues (Nature, Science, PLOS, IEEE, ACM), academic conferences (NeurIPS, ICML, CVPR, CHI), research posters, and grant proposals (NSF, NIH, DOE, DARPA). This skill should be used when preparing manuscripts for journal submission, conference papers, research posters, or grant proposals and need venue-specific formatting requirements and templates.
let-fate-decide
IncludedDraws the 12 Houses of the Zodiac Tarot spread to inject entropy into planning when prompts are vague, ambiguous, or casually delegated. Interprets the spread to guide next steps. Use when the user says 'let fate decide', 'YOLO', 'whatever', 'idk', or other nonchalant phrases, makes Yu-Gi-Oh references, or when you are about to arbitrarily pick between multiple reasonable approaches. Prefer over ask-questions-if-underspecified when the user's tone is casual or playful rather than precision-seeking.
net-ops
IncludedCross-platform network troubleshooting (Windows, macOS, Linux) via local or remote shell. Use for: DNS broken, can't resolve hostnames, nslookup/dig works but apps fail, NRPT, WFP, scutil, /etc/resolver, systemd-resolved, /etc/resolv.conf, NetworkManager, VPN DNS leak residue (ProtonVPN/Mullvad/WireGuard/AnyConnect), AV/firewall blocking DNS or DoH, Tailscale DNS interaction, intermittent connectivity, remote diagnostics over SSH.