Curated index of community-authored packs for SynthPanel, a lightweight LLM-agnostic research harness for synthetic focus groups.
This repository is the canonical source of truth for SynthPanel persona
and instrument packs. Downstream tooling — the synthpanel CLI, MCP
servers, and agent integrations — resolves pack IDs against default.json
in this repo. Anything bundled inside the SynthPanel package itself is a
convenience cache or example, not the authoritative catalog.
Concretely:
- Registry (this repo) = catalog. Stable pack IDs, reviewed YAML, and
the manifest at
default.jsonthat lists every pack agents can request. - SynthPanel CLI / MCP = resolver. Fetches the manifest, looks up the
requested pack ID, and pulls the YAML at
packs/<pack-id>/synthpanel-pack.yaml. - SynthPanel package = runtime. May ship a small bundled example set so the CLI works offline, but for production research the registry is the source.
If a pack ID in this repo's default.json and a bundled SynthPanel copy
disagree, the registry entry wins.
A thin, human-reviewed catalog. The root default.json is the manifest
SynthPanel fetches at runtime to power pack search and pack import gh:....
There is no runtime here — only JSON, a schema, and a PR workflow.
- A pack author drops a
synthpanel-pack.yamlunderpacks/<pack-id>/in this repo (see CONTRIBUTING.md). - They open a submission issue, then a PR adding the pack directory and
the regenerated
default.json. - A reviewer checks the submission criteria in CONTRIBUTING and merges.
added_atis stamped automatically from the pack directory's first commit byscripts/build_registry.py. - SynthPanel clients fetch
https://raw.githubusercontent.com/DataViking-Tech/synthpanel-registry/main/default.json(cached 24h) to surface the pack viasynthpanel pack searchand to resolve registeredgh:owner/repoimports.
A pack's id is the agent-facing primary key. Once a pack lands in
default.json, its id is treated as a stable, public identifier that
downstream tooling and agents may pin to indefinitely.
Three rules keep IDs stable:
- Slug shape. IDs must match
^[a-z0-9]+(-[a-z0-9]+)*$(lowercase kebab-case). Enforced byschema/default.schema.json. - Directory == ID. The pack lives at
packs/<pack-id>/synthpanel-pack.yamland the directory name MUST equal the YAML's top-levelid:. Enforced byscripts/build_registry.py. - No silent renames. Changing a pack's
idis a breaking change for every consumer that pinned it. Rename = remove + re-add under the new ID, with the old ID deprecated via the pack-removal flow.
Versioning lives on the pack YAML's top-level version: field and is
mirrored to the registry entry's version field. Agents that need
content-stability beyond ID may pin against a version (or commit SHA,
via the schema's optional ref field) — see
schema/default.schema.json.
Agents and integrations consuming this registry directly should:
- Fetch the manifest:
https://raw.githubusercontent.com/DataViking-Tech/synthpanel-registry/main/default.json— JSON Schema atschema/default.schema.json. Cache for up to 24h. - Filter by
kindto pick the right pack family:kind: persona— persona panels (ICPs, demographic cohorts, vertical buyer sets, stress-test probes). All v1 packs are personas.kind: instrument— reserved for future survey/measurement instruments. Not populated in v1; downstream tooling should treat an empty instrument set as expected.
- Resolve the YAML at the entry's
repo+path(defaultmainbranch unless an entry setsref). The full URL pattern ishttps://raw.githubusercontent.com/<repo>/<ref|main>/<path>. - Match by
idwhen a user or upstream config names a specific pack (e.g.synthpanel pack import icp-synthpanel). IDs are stable; names and descriptions are human-readable hints, not lookup keys.
The current pack catalog (IDs, kinds, descriptions, calibration counts)
is always default.json at the repo root — read it
directly rather than scraping this README, which may lag the manifest.
See schema/default.schema.json for the
authoritative JSON Schema. Validation runs in CI on every PR.
Each entry may also carry an optional calibration_count integer
summarizing how many calibration runs the pack has declared on its
calibration: list. Packs without calibration runs omit the field —
"uncalibrated" is a valid state for ICP, vertical, and stress-test packs.
See CONTRIBUTING.md → Calibration for the
field convention and JSD interpretation guide.
- Drop your pack YAML at
packs/<pack-id>/synthpanel-pack.yaml(one directory per pack; the directory name must equal the pack'sid:). - Regenerate the registry index locally:
The script walks every
pip install pyyaml jsonschema synthpanel python scripts/build_registry.pypacks/*/synthpanel-pack.yaml, validates it against synthpanel's persona-pack schema, and rewritesdefault.jsondeterministically (stable sort, canonical JSON). - Commit both the new pack and the regenerated
default.jsonin your PR.
CI runs python scripts/build_registry.py --check on every PR. Any pack
that fails persona-pack validation or any PR whose default.json is stale
relative to its packs/ tree will fail the registry-build status check.
Authors may request takedown via the pack removal issue template.