semantics//contracts//knowledge/ content for a known system. This guide runs the posthog pack (canonic-packs) end to end against a real (seeded) Postgres database, so you can see the whole story — install, validation, and querying — without a real PostHog instance.
Full source:
scripts/posthog_pack_demo/Prerequisites
- Docker with Compose
- A checkout of the canonic repository (the compose file builds the daemon from
scripts/posthog_pack_demo/Dockerfile) - Network access from inside the container to clone
canonic-packsfrom GitHub at startup — no local checkout needed, see “Where the pack content comes from” below - An MCP client, for example the MCP Inspector, or plain
curl
Start
From the repository root:installing the posthog context pack..., a line listing the installed files, and then Uvicorn’s Uvicorn running on http://0.0.0.0:7474 line.
What happened
entrypoint.sh ran, non-interactively:
posthog_exports.events/persons actually exist on the posthog_db connection (required_tables, a live introspection call). It then templated and wrote:
semantics/posthog_db/ph_events.yaml,ph_persons.yaml— one row per event, one row per(team_id, distinct_id), joined many-to-one.contracts/metrics/active_users.yaml,new_users.yaml,activated_users.yaml,activation_rate.yaml.contracts/guardrails/posthog-exclude-internal-traffic.yaml— amandatory_filterbuilt from theinternal_email_domains: yourcompany.comparam inpack-params.json, always AND-ed into any query againstph_eventsregardless of severity.knowledge/global/activation-definition.md,internal-traffic-caveat.md.
provenance: human_curated plus a pack_source: {pack: posthog, version, variant: postgres} tag, then validated with the project’s ordinary semantic/contract/knowledge checks — the same review posture as hand-written content, just starting from a known-good definition instead of an inferred one.
The seed data
postgres/init/02_seed.sql seeds one team (team_id = 1) with 30 persons over the last 30 days:
- All 30 signed up (
user_signed_up). - 3 are tagged with an internal
@yourcompany.comemail — excluded from every metric byexclude-internal-traffic. - 9 of the remaining 27 also fired
report_created(the activation event). - Everyone gets a few
$pageview/dashboard_viewednoise events spread across the window.
The pack’s
first_answer (active_users, 30d window) runs automatically right after install — its result is the first thing canonic pack add prints.
Query it
http://localhost:7474 with that same bearer token and query active_users, new_users, activated_users, or activation_rate via the query tool. posthog-demo-local-dev is canonic.docker.yaml’s single static demo token (mcp.auth.tokens) — --transport http refuses to start with no auth mechanism configured at all.
Stop
-v to also drop the seeded Postgres volume; without it, a later up reuses the same data (Postgres only runs its init scripts against a fresh volume) and reinstalls the pack fresh each time (install_pack overwrites unconditionally, so this is always safe).
Where the pack content comes from
No--repo is passed, so canonic pack add falls back to its own built-in default — the canonic-packs GitHub repo (canonic/cli/commands/pack.py::_DEFAULT_REPO) — shallow-cloned fresh into .canonic/packs-cache/ on every container start. That clone needs git on PATH, which the shared root Dockerfile doesn’t have (adding it there would grow every image built from it, not just this demo), so this demo builds from its own Dockerfile instead — an exact copy of the root one plus git.
Point this at a real PostHog instance
Nothing about the pack mechanism itself changes. Swapcanonic.docker.yaml’s posthog_db connection for your real warehouse’s Postgres batch-export database, and either:
- keep
--params-file/--yesand editpack-params.json’ssignup_event/activation_eventto your actual event names, or - drop both flags and run
canonic pack add posthoginteractively —choose_fromthen queries your live database for a top-50 custom-event picklist instead of using the seeded params.
Where to go next
canonic packfor every flag, andpack validate’s CI-friendly, connection-free pathcanonic setup— the same install routine is also offered from the setup wizard’s pack branch- Marketplace with Keycloak for the same “Docker demo on top of a shipped example” pattern applied to OAuth/RBAC instead of context packs