Skip to content

Compliance packs — authoring guide

Source: platform/content/packs/README.md · rendered from main on every deploy — edit in the repo, not here

Per ADR-0101, this directory is the source of truth for platform-curated compliance packs. Each subdirectory is one pack, ingested into the platform-shared system_* tables (migration 0048) and made available to subscribed tenants.

platform/content/packs/
├── README.md # this file
├── _example/ # reference layout — copy this when authoring a new pack
│ ├── pack.yaml
│ ├── sources/
│ │ └── regulation-text/
│ │ ├── source.yaml
│ │ └── articles/
│ │ ├── 01-overview.md
│ │ └── 02-scope.md
│ ├── golden.yaml # Promptfoo eval set — required for publish
│ └── CHANGELOG.md
├── gdpr/ # real packs land here, one directory each
├── soc2/
├── pdpa-th/
└── iso27001/

Pack slugs (directory names) match the slug field in pack.yaml and become the public identifier (tenant_pack_subscriptions.pack_slug, citation badge, admin UI). Underscore prefix (_example) marks non-shipping content — the ingest pipeline skips these.

The on-disk YAML maps 1:1 to TypeScript types exported from @puccha/rag/packs:

File Type DB target
pack.yaml PackManifest compliance_packs row
sources/*/source.yaml SourceManifest system_sources row
sources/*/*/*.md frontmatter DocumentFrontmatter system_documents row + chunks

See packages/rag/src/packs/manifest.ts for the full type definitions and field documentation.

  1. Versioningpack.yaml.version is engineering semver. Bump major on breaking chunk-anchor changes; minor on new sources or documents; patch on corrections. effective_date is the date the regulation itself took effect — it is independent of version and never changes for the same regulatory edition.
  2. Licenses must be from the approved list — see PackManifest.license in manifest.ts. Custom legalese is rejected at publish time.
  3. Document slug is stable — it is the citation identifier. Renaming a document slug after publish is a breaking change and bumps the major version.
  4. Document anchor is the deep-link — match the regulator’s official anchor where possible (e.g. #article-28-paragraph-3). This is what subscriber citations link to.
  5. Use the source’s official language for contentpack.yaml.language is the language of the chunks. A multi-language regulation lives as multiple packs (same slug, different language) — for example pdpa-th (Thai) and pdpa-th-en (English summary).
  6. No customer data, no PII, no copyrighted prose — pack content is public records and platform-authored commentary. Anything sourced from a third party must be either public-domain or licensed for redistribution under the pack’s declared license.

Pipeline (planned — landing in next slice)

Section titled “Pipeline (planned — landing in next slice)”

Per ADR-0101 §10:

Terminal window
pnpm pack:ingest <slug> # parse + write to D1 + Vectorize (idempotent)
pnpm pack:publish <slug> # flips status: draft → published; bumps published_at
pnpm pack:eval <slug> # runs golden.yaml against the current pack version

golden.yaml (Promptfoo format) is required for pack:publish to succeed (minimum 20 question-and-expected-citation pairs; faithfulness threshold ≥ 0.85 per CLAUDE.md quality gates). See ADR-0101 §10.