Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 23 additions & 3 deletions SCHEMA_INDEX.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

| Directory | Form | When to use |
|-----------|------|-------------|
| [`schema/`](./schema/) | **Unified** — one file per spec version validates the whole document. Files: `klickd-v1.json`, `klickd-v2.json`, `klickd-v3.4.schema.json`. | Single-pass validators, schema registries, third-party tooling. |
| [`schemas/`](./schemas/) | **Split** — separate envelope and payload schemas for v3. Files: `klickd-envelope-v3.schema.json`, `klickd-payload-v3.schema.json`. | Secure decoders that validate the envelope *before* decryption and the payload *after*. |
| [`schema/`](./schema/) | **Unified** — one file per spec version validates the whole document. Files: `klickd-v1.json`, `klickd-v2.json`, `klickd-v3.4.schema.json`, `klickd-v4-preview.schema.json` (preview), `klickd-v4.schema.json` (GA strict candidate). | Single-pass validators, schema registries, third-party tooling. |
| [`schemas/`](./schemas/) | **Split** — separate envelope and payload schemas. Files: `klickd-envelope-v3.schema.json`, `klickd-payload-v3.schema.json`, `klickd-payload-v4-preview.schema.json` (preview), `klickd-payload-v4.schema.json` (GA strict candidate). | Secure decoders that validate the envelope *before* decryption and the payload *after*. |

Both directories are **normative for v3.x (production, current and recommended)** and are kept in sync. The split form (`schemas/`) is the canonical pre-/post-decrypt boundary; the unified form (`schema/`) is the convenience form for single-shot validation.

Expand All @@ -30,7 +30,27 @@ In addition to the normative v3 schemas, the repository ships **permissive previ
**These schemas are PERMISSIVE.** They use `additionalProperties: true` and only declare top-level hooks for the preview fields. They are intended to **accept and preserve** draft v4 structures, not to perform strict validation. They MUST NOT be used to reject a file that is otherwise a valid v3.5.1 file.

- **Normative for production?** No. Production validation MUST use `schema/klickd-v3.4.schema.json` or the split v3 schemas under `schemas/`.
- **Strict v4 validation?** Not in this preview. A future PR will introduce strict v4 schemas; until then, the preview schemas are deliberately loose.
- **Strict v4 validation?** See the **v4 GA strict schemas** section below.
- **Unknown fields?** A v4-preview reader MUST preserve unknown fields verbatim when round-tripping. See SPEC.md §33.7.

See [SPEC.md §33](./SPEC.md) and the RFCs under [`docs/rfcs/`](./docs/rfcs/) for the design source.

---

## v4 GA strict schemas (P0-2 — coexist with preview, do NOT supersede it)

To unblock the GA track described in [`docs/roadmap/ROAD-TO-V4-GA.md` §P0-2](./docs/roadmap/ROAD-TO-V4-GA.md), the repository now also ships **strict v4 schemas**. The preview schemas remain in place unchanged: both pairs coexist until the preview sunset is announced separately.

| File | Form | Status | When to use |
|------|------|--------|-------------|
| [`schemas/klickd-payload-v4.schema.json`](./schemas/klickd-payload-v4.schema.json) | **Split — payload** | **GA strict candidate (normative target)** | Strict validation of a `.klickd` v4 decrypted payload: `verification_gates` (v1 core enum), `human_veto_policy`, `claim_sources` (v1), `media_profile` (RFC-001 v1, `version`+`entries[]`, hash strict), `migration` (RFC-004 v1 frozen fields), plus carry-over v3 surface. RFC-002 v2-additive fields (`reversibility`, `blast_radius`, `contract_tests`, `success_criteria`, `verification_artifacts`) remain permissive while Draft. |
| [`schema/klickd-v4.schema.json`](./schema/klickd-v4.schema.json) | **Unified** | **GA strict candidate (normative target)** | Strict validation of a full v4 document. Encrypted files MUST carry `kdf` + `cipher` + `ciphertext` (envelope-v3 contract unchanged per §33.10 #2). |

**Coexistence rules:**

- Preview schemas (`*-v4-preview.schema.json`) remain authoritative for **preview** files (`preview: "v4.0.0-preview.1"`). They MUST continue to accept all preview vectors.
- Strict schemas (`klickd-payload-v4.schema.json`, `klickd-v4.schema.json`) are the **GA strict target**. They accept both `payload_schema_version: "4.0"` (GA) and the legacy preview value `"4.0.0-preview.1"` so the 5 persona examples and preview vectors round-trip against them.
- **Top-level `additionalProperties: true` is preserved.** SPEC.md §33.7 (unknown-field preservation) is unconditional and not relaxed by the strict schemas.
- **No SDK is bumped.** No npm / PyPI / Zenodo release is triggered. No git tag is created.

**Validation:** see [`scripts/validate_v4_schemas.py`](./scripts/validate_v4_schemas.py) for the canonical local validation runner.
13 changes: 13 additions & 0 deletions docs/roadmap/ROAD-TO-V4-GA.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,19 @@ Chaque entrée précise : *Objet → Livrables → Critères de sortie (Definiti
- validation passe sur tous les vectors v4 stricts ;
- les vectors preview restent acceptés via le schéma preview (deux schémas coexistent jusqu’au sunset).
- **Dépendances :** P0-1.
- **Statut (2026-05-24) :** **GA candidate landed (docs/schema only, no SDK/release).** Le PR P0-2 introduit
[`schemas/klickd-payload-v4.schema.json`](../../schemas/klickd-payload-v4.schema.json) et
[`schema/klickd-v4.schema.json`](../../schema/klickd-v4.schema.json) (strict sur les sections RFC-001 v1
`Accepted` et RFC-002 v1 core `Accepted` ; permissif sur les sections RFC-002 v2-additive et RFC-004 encore
en `Draft`). `additionalProperties: true` est conservé **au niveau racine** pour respecter le contrat de
préservation des champs inconnus de [SPEC.md §33.7](../../SPEC.md). Les 5 personas de
[`examples/v4/personas/`](../../examples/v4/personas/) et tous les `expected_payload` de
[`tests/vectors_v40_preview.json`](../../tests/vectors_v40_preview.json) valident contre le schéma strict.
Les schémas preview restent en place inchangés (coexistence, pas de remplacement). **Aucun bump de version
SDK, aucun tag, aucune release npm/PyPI/Zenodo.** Le runner local est
[`scripts/validate_v4_schemas.py`](../../scripts/validate_v4_schemas.py). Les vectors v4 *stricts*
(P0-6) restent à produire avant de pouvoir cocher la DoD complète ; à ce stade la DoD est validée sur le
corpus preview existant et les 5 personas.

#### P0-3 — SDK Python `klickd` 4.0.0

Expand Down
10 changes: 6 additions & 4 deletions examples/v4/personas/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,10 +123,12 @@ forte sur les sections preview).
- [x] Passphrase de test publique documentée (`klickd-example-only`), sans
jamais figurer comme contenu chiffré.
- [x] Validation contre le schéma preview permissif (cf. §5 ci-dessous).
- [ ] Validation stricte v4 ([P0-2 / P0-6](../../../docs/roadmap/ROAD-TO-V4-GA.md)) :
**différée**. Le schéma strict v4 et les vectors stricts v4 n'existent
pas encore — la DoD complète sera atteignable une fois P0-2/P0-6 mergés,
conformément à l'ordre des dépendances inscrit dans ROAD-TO-V4-GA.
- [x] Validation stricte v4 contre [`schemas/klickd-payload-v4.schema.json`](../../../schemas/klickd-payload-v4.schema.json)
(P0-2 GA candidate, livré séparément). Les 5 personas valident sans erreur —
voir [`scripts/validate_v4_schemas.py`](../../../scripts/validate_v4_schemas.py).
- [ ] Validation contre les vectors v4 *stricts*
([P0-6](../../../docs/roadmap/ROAD-TO-V4-GA.md)) :
**différée**. Les vectors v4 stricts n'existent pas encore — track P0-6.

### Reproduire la validation locale

Expand Down
1 change: 1 addition & 0 deletions schema/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ This directory contains **unified** JSON Schemas — each file validates a compl
| `klickd-v2.json` | v2.x | PBKDF2-SHA256 + 4-field AAD. |
| `klickd-v3.4.schema.json` | v3.4 (current) | Argon2id + RFC 8785 JCS AAD + `kdf`/`cipher` blocks. Forward-compatible with v3.5 fields. |
| `klickd-v4-preview.schema.json` | **v4.0.0-preview.1 (PREVIEW, non-normative, NOT GA)** | Permissive (`additionalProperties: true`) acceptance schema for draft v4 documents with top-level hooks for `media_profile` / `verification_gates` / `human_veto_policy` / `claim_sources` / `verification_artifacts` / `migration` / `context_cost` / `profile_kind`. See SPEC.md §33. |
| `klickd-v4.schema.json` | **v4 GA strict candidate (P0-2)** | Strict unified schema. Encrypted v4 files MUST carry `kdf` + `cipher` + `ciphertext` (envelope-v3 contract unchanged per §33.10 #2). Inline payload fields cross-reference `../schemas/klickd-payload-v4.schema.json`. Top-level `additionalProperties: true` preserved (SPEC.md §33.7). Coexists with the preview schema — does NOT supersede it. |

**Use these files** when a single-schema validation is sufficient (CI tooling, third-party integrations, schema registries).

Expand Down
129 changes: 129 additions & 0 deletions schema/klickd-v4.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://klickd.app/schema/v4/klickd.schema.json",
"title": "klickd v4 — Unified (Strict GA candidate, normative)",
"description": "Strict unified JSON Schema for a .klickd v4 document (envelope + optional inline payload). This schema is the GA strict equivalent of the permissive klickd-v4-preview.schema.json. It validates the envelope shape strictly (mirroring the v3 envelope contract — Argon2id + AES-256-GCM is unchanged in v4 per SPEC.md §33.10 #2) and, for unencrypted files, validates the inline payload against the strict v4 payload schema (klickd-payload-v4.schema.json). Top-level additionalProperties is TRUE to preserve unknown fields verbatim (SPEC.md §33.7 forward-compatibility invariant). Does NOT supersede the permissive preview schema (klickd-v4-preview.schema.json) — both coexist.",
"type": "object",
"additionalProperties": true,
"required": ["klickd_version", "created_at", "encrypted"],
"properties": {
"klickd_version": {
"type": "string",
"description": "Wire / envelope version. Strict v4 GA producers SHOULD emit '4.0'. v3.x values are also accepted because the v3 envelope contract is unchanged (§33.10 #2) and a v3.x file remains readable by a v4 reader.",
"pattern": "^(3|4)\\.\\d+(\\.[0-9A-Za-z-.]+)?$"
},
"preview": {
"type": "string",
"description": "OPTIONAL preview marker. Absent on GA strict files. If present, this file was written against a preview iteration (e.g. 'v4.0.0-preview.1')."
},
"created_at": {
"type": "string",
"description": "RFC 3339 UTC timestamp of file creation. Z-suffix only, no fractional seconds (matches v3 envelope strict contract).",
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$"
},
"encrypted": {
"type": "boolean"
},
"domain": {
"type": "string",
"minLength": 1,
"description": "Semantic category. Registered values follow v3 (education, work, finance, legal, creative, health, research, robotics, gaming, creator). Custom non-empty strings are permitted."
},
"profile_kind": {
"type": "string",
"description": "Top-level discriminator for the profile shape. Reserved canonical values: 'learner', 'agent', 'team', 'robot', 'creator'."
},
"domain_schema_version": {
"type": "string",
"pattern": "^([a-z][a-z0-9_-]*-\\d+\\.\\d+|\\d+\\.\\d+(\\.\\d+)?)$"
},
"kdf": {
"type": "object",
"description": "Structured KDF block — same contract as envelope-v3 §15.",
"required": ["name", "params", "salt"],
"additionalProperties": false,
"properties": {
"name": {"type": "string", "enum": ["argon2id", "pbkdf2-sha256"]},
"params": {
"oneOf": [
{
"type": "object",
"required": ["m", "t", "p"],
"additionalProperties": false,
"properties": {
"m": {"type": "integer", "minimum": 65536},
"t": {"type": "integer", "minimum": 1},
"p": {"type": "integer", "minimum": 1}
}
},
{
"type": "object",
"required": ["iterations"],
"additionalProperties": false,
"properties": {
"iterations": {"type": "integer", "minimum": 600000}
}
}
]
},
"salt": {"type": "string"}
}
},
"cipher": {
"type": "object",
"description": "Structured cipher block — same contract as envelope-v3 §16. v4 does not introduce a new cipher.",
"required": ["name", "iv"],
"additionalProperties": false,
"properties": {
"name": {"type": "string", "const": "AES-256-GCM"},
"iv": {"type": "string"}
}
},
"ciphertext": {
"type": "string",
"description": "AES-256-GCM ciphertext (base64 padded). Required when encrypted=true."
},
"iv": {
"type": "string",
"description": "Legacy top-level IV mirror, retained for v3.0 round-trip parity. New producers SHOULD place IV inside the structured cipher block."
},
"kdf_salt": {
"type": "string",
"description": "Legacy top-level salt mirror, retained for v3.0 round-trip parity."
},
"payload_schema_version": {
"type": "string",
"description": "Payload schema version when the payload is inline (encrypted=false). Strict v4 GA value: '4.0'. Preview '4.0.0-preview.1' accepted for round-trip.",
"enum": ["4.0", "4.0.0-preview.1"]
},
"media_profile": {"$ref": "https://klickd.app/schemas/v4/klickd-payload.schema.json#/properties/media_profile"},
"verification_gates": {"$ref": "https://klickd.app/schemas/v4/klickd-payload.schema.json#/properties/verification_gates"},
"human_veto_policy": {"$ref": "https://klickd.app/schemas/v4/klickd-payload.schema.json#/properties/human_veto_policy"},
"claim_sources": {"$ref": "https://klickd.app/schemas/v4/klickd-payload.schema.json#/properties/claim_sources"},
"verification_artifacts": {"$ref": "https://klickd.app/schemas/v4/klickd-payload.schema.json#/properties/verification_artifacts"},
"contract_tests": {"$ref": "https://klickd.app/schemas/v4/klickd-payload.schema.json#/properties/contract_tests"},
"success_criteria": {"$ref": "https://klickd.app/schemas/v4/klickd-payload.schema.json#/properties/success_criteria"},
"reversibility": {"$ref": "https://klickd.app/schemas/v4/klickd-payload.schema.json#/properties/reversibility"},
"blast_radius": {"$ref": "https://klickd.app/schemas/v4/klickd-payload.schema.json#/properties/blast_radius"},
"risk_thresholds": {"$ref": "https://klickd.app/schemas/v4/klickd-payload.schema.json#/properties/risk_thresholds"},
"preflight_checks": {"$ref": "https://klickd.app/schemas/v4/klickd-payload.schema.json#/properties/preflight_checks"},
"error_journal": {"$ref": "https://klickd.app/schemas/v4/klickd-payload.schema.json#/properties/error_journal"},
"migration": {"$ref": "https://klickd.app/schemas/v4/klickd-payload.schema.json#/properties/migration"},
"context_cost": {"$ref": "https://klickd.app/schemas/v4/klickd-payload.schema.json#/properties/context_cost"},
"gaming_profile": {"$ref": "https://klickd.app/schemas/v4/klickd-payload.schema.json#/properties/gaming_profile"},
"deprecated_fields": {"$ref": "https://klickd.app/schemas/v4/klickd-payload.schema.json#/properties/deprecated_fields"}
},
"allOf": [
{
"if": {
"type": "object",
"properties": {"encrypted": {"const": true}},
"required": ["encrypted"]
},
"then": {
"required": ["kdf", "cipher", "ciphertext"],
"description": "Encrypted v4 file MUST carry kdf + cipher + ciphertext (envelope-v3 contract retained)."
}
}
]
}
1 change: 1 addition & 0 deletions schemas/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ This directory contains the **split** JSON Schemas for `.klickd` v3:
| `klickd-envelope-v3.schema.json` | Outer JSON envelope (encrypted). Validates `klickd_version`, `kdf`, `cipher`, `ciphertext`, AAD-relevant fields. |
| `klickd-payload-v3.schema.json` | Inner decrypted payload. Validates `identity`, `agent_instructions`, `user_preferences`, `context`, `knowledge`, `memory`, etc. |
| `klickd-payload-v4-preview.schema.json` | **v4.0.0-preview.1 payload (PREVIEW, non-normative, NOT GA).** Permissive (`additionalProperties: true`) acceptance schema for draft v4 payloads with top-level hooks for `media_profile` / `verification_gates` / `human_veto_policy` / `claim_sources` / `verification_artifacts` / `migration` / `context_cost` / `profile_kind`. See SPEC.md §33. |
| `klickd-payload-v4.schema.json` | **v4 GA strict candidate (P0-2).** Strict payload schema: `verification_gates` (v1 enum), `human_veto_policy`, `claim_sources` (v1), `media_profile` (RFC-001 v1, `version`+`entries[]`, BLAKE3 hash strict), `migration` (RFC-004 v1 frozen fields). RFC-002 v2-additive fields (`reversibility`, `blast_radius`, `contract_tests`, `success_criteria`, `verification_artifacts`) remain permissive while Draft. Top-level `additionalProperties: true` preserved (SPEC.md §33.7). Coexists with the preview schema — does NOT supersede it. |

**Use this split form** when you need to validate the envelope *before* decryption and the payload *after* decryption as two independent steps (typical of secure decoders that fail-fast on the envelope).

Expand Down
Loading
Loading