Skip to content

Your first Annex IV dossier

The Annex IV dossier is the single artefact a Market Surveillance Authority can ask for. Lex Custis generates it on demand.

Step 1 — pick a date range

Go to /compliance. The top card is "Annex IV regulator dossier (Art. 11 + 12 + 15 + 53 + 73)".

Pick a Period start and Period end. For a demo org with seeded data, set start = 90 days ago, end = today.

Step 2 — click "Download Annex IV dossier (.zip)"

The request hits GET /api/v1/compliance/dossier?period_start=…&period_end=…. Bundling takes a few seconds for a small period; longer periods scale with log volume.

You'll get a file named like:

dossier_acme_hr_tech_20260101_20260331.zip

Step 3 — inspect the zip

Unzip and you'll see eight files:

dossier_acme_hr_tech_20260101_20260331/
├── annex_iv.pdf                   # Art. 11 technical documentation (or .html
│                                    if WeasyPrint's system deps are missing)
├── audit_log_period.jsonl          # Art. 12 event log, HMAC-chained
├── integrity_attestation.json      # Chain verification status at bundle time
├── metrics.json                    # Art. 15 aggregates over the period
├── provider_manifest.json          # Art. 53 upstream GPAI trail
├── incidents.json                  # Art. 73 incidents detected in period
└── MANIFEST.json                   # Bundle metadata + SHA-256 per file

What's in each

annex_iv.pdf — the technical-documentation PDF. Covers cover page, system description, data governance, interaction summary, human oversight, bias monitoring, integrity verification, risk assessment. (Commercial edition extends this with deployer-specific intended-purpose and FRIA sections.)

audit_log_period.jsonl — one JSON line per audit entry in the period, ordered by sequence number. Each line includes previous_hash, current_hash, and every field that went into the HMAC payload. A regulator can re-verify the chain offline using python -m lex_custis.verify_dossier (v0.2 CLI) or by implementing the spec in architecture/hash-chain.md.

integrity_attestation.json — the result of audit_service.verify_chain() at the moment the bundle was built:

{
  "format": "lex-custis/integrity-attestation/v1",
  "organization_id": "...",
  "organization_name": "Acme HR-tech",
  "bundled_at": "2026-04-21T07:15:00+00:00",
  "verified": true,
  "total_entries": 847,
  "entries_checked": 847,
  "first_broken_at": null,
  "message": "All 847 entries verified successfully.",
  "regulation": "EU AI Act (Regulation 2024/1689), Art. 12 — automatic record-keeping"
}

metrics.json — Art. 15 aggregates: confidence min / avg / max, PII detection rate, bias-flag rate, human-oversight rate. For the period.

provider_manifest.json — distinct (provider, model) pairs used to serve inferences in the period, with call counts, first- and last-seen timestamps, and a pointer to the upstream Art. 53 disclosure for each provider.

incidents.json — full list of Art. 73 incidents detected in the period, each with classification, SLA status, submission reference if reported.

MANIFEST.json — the listing a regulator will verify first:

{
  "format": "lex-custis/annex-iv-dossier/v1",
  "organization_id": "...",
  "period_start": "2026-01-01T00:00:00+00:00",
  "period_end": "2026-03-31T23:59:59+00:00",
  "generated_at": "2026-04-21T07:15:00+00:00",
  "generated_by_user_id": "...",
  "files": [
    {"name": "annex_iv.pdf", "size_bytes": 283415, "sha256": "…"},
    {"name": "audit_log_period.jsonl", "size_bytes": 1128345, "sha256": "…"},
    
  ],
  "regulation_coverage": {
    "art_11": "annex_iv.pdf (technical documentation)",
    "art_12": "audit_log_period.jsonl (automatic event logs)",
    "art_15": "metrics.json (accuracy/confidence/bias aggregates)",
    "art_53": "provider_manifest.json (upstream GPAI trail)",
    "art_73": "incidents.json (serious incidents in period)"
  },
  "integrity_verified_at_bundle_time": true
}

In commercial editions the MANIFEST.json itself is signed (ed25519) and timestamped (RFC-3161). The OSS bundle is unsigned — you'll sign it out-of-band if you need non-repudiation for a regulator in v0.1.

Step 4 — verify offline

A regulator (or your own audit team) can verify integrity without touching your live infrastructure:

  1. Read audit_log_period.jsonl in order of sequence_number.
  2. Confirm each entry's previous_hash == the prior entry's current_hash (first entry's prev = sha256(b"LEX_CUSTIS_GENESIS")).
  3. Recompute each entry's HMAC using the per-org key (held outside the DB, typically in KMS / Vault).
  4. current_hash must equal the recomputed HMAC.

See architecture/hash-chain.md for the exact payload canonicalisation.

Step 5 — what to do with it

Depending on audience:

  • Regulator request. Attach directly to your response. The MSA wants the MANIFEST.json and the underlying files.
  • Big-4 audit. Give them the zip + read access to a fresh instance so they can reproduce.
  • Your own DPO. Schedule a quarterly review with the zip as input and a PMM plan as output.
  • Your customer's DPO (if you're a provider and they're a deployer). Share as part of Art. 13 transparency obligation.

What the dossier does not (yet) cover

  • Art. 9 risk register — deferred to v0.2 / commercial edition.
  • Art. 10 dataset registry — deferred.
  • Art. 27 FRIA — wizard in commercial edition.
  • RFC-3161 timestamping / ed25519 signature on MANIFEST.json — commercial edition.

Cross-reference with the compliance matrix to plan what else you still owe.