Skip to content

sdk(python,v4): P0-3 — align klickd Python SDK with v4 GA strict schema#43

Merged
Davincc77 merged 2 commits into
mainfrom
sdk/python-v4-ga-p0-3
May 24, 2026
Merged

sdk(python,v4): P0-3 — align klickd Python SDK with v4 GA strict schema#43
Davincc77 merged 2 commits into
mainfrom
sdk/python-v4-ga-p0-3

Conversation

@Davincc77
Copy link
Copy Markdown
Owner

Summary

Wires the Python SDK (packages/pypi/klickd/) onto the v4 GA strict schema candidate landed by #42, without bumping the package version and without touching the frozen v3 envelope crypto contract (SPEC.md §33.10 #2).

  • New surface: klickd.validate(payload, strict=True|False, target=\"payload\"|\"unified\") + non-raising klickd.validate_iter_errors(...).
  • Bundles the four v4 schemas as package data under klickd/schemas/.
  • jsonschema is an optional extra (pip install klickd[validate]); load/save users are unaffected.
  • v4 TypedDicts for media_profile v1 / verification_gates v1 / human_veto_policy / claim_sources / migration.
  • README: documents the new validation entry point + §33.7 verbatim round-trip on v4 additive fields.

Governance — preserved

  • ❌ No package version bump (stays at 4.0.0a1).
  • ❌ No PyPI publish, no Git tag, no Zenodo DOI, no @klickd/core change.
  • ❌ No SDK alignment of R4-P0-2 docs-only codes (KLICKD_E_PASS_MISMATCH, KLICKD_E_SAVE_LOCAL, KLICKD_E_LEGACY_VERSION, KLICKD_E_CORRUPT, KLICKD_E_POLICY_LOCKED, KLICKD_E_UNSAFE_QR) — R4-P0-2 §4 explicitly defers this to a later track.
  • ✅ Code + tests + docs only. Phase B governance respected.

Strict / preview design

  • The strict schema (P0-2) accepts both \"4.0\" and \"4.0.0-preview.1\" in payload_schema_version, by design, so preview-era files round-trip against the strict surface without rewriting.
  • target=\"payload\" validates the inner payload schema (common case after load_klickd).
  • target=\"unified\" validates an envelope-shaped dict (useful for the wizard's import path).

Test plan

  • python3 -m pytest -q inside packages/pypi/klickd/63/63 pass (17 existing + 46 new).
  • 5 R4-P0-3 personas validate against strict payload + unified + preview schemas.
  • 5 personas round-trip verbatim (single + double round-trip; structural equality).
  • Negative cases reject (unknown gate level, missing media hash, unknown modality, unsupported payload_schema_version, encrypted envelope missing kdf/cipher/ciphertext).
  • Both structured + flat verification_gates shapes accepted; flat form with invalid level rejected.
  • v3.x payloads load/save unchanged (zero regression).
  • Unknown top-level fields validate AND round-trip verbatim (§33.7).
  • python3 scripts/validate_v4_schemas.py → all v4 strict-schema validations pass.
  • python3 verify_vectors.py59/59 pass (v2.5 / v3.0 / adversarial / v4.0-preview).
  • node verify_vectors.mjs → 29/29 pass, 13 skip (hash-wasm not installed locally; same as main).
  • Wheel build: python3 -m build --wheel succeeds; bundled schemas appear exactly once under klickd/schemas/.

Impact on next P0 tracks

  • P0-4 (SDK TS @klickd/core 4.0.0) is now unblocked — Python parity surface is validate(payload, strict=...) and the four bundled schemas. JS implementation should mirror the same strict / preview × payload / unified matrix.
  • P0-6 (strict vectors) can hook into klickd.validate directly once vectors land.

🤖 Generated with Claude Code

Karim13014 and others added 2 commits May 24, 2026 21:48
Adds a v4 schema validation surface to the Python SDK (P0-3) without
bumping the package version (`4.0.0a1`) and without touching the v3
envelope crypto contract (SPEC.md §33.10 #2 frozen).

What ships:

- `klickd.validate(payload, strict=True|False, target="payload"|"unified")`
  with the strict GA candidate (P0-2) and permissive v4 preview schemas
  bundled as package data under `klickd/schemas/`.
- `klickd.validate_iter_errors(...)` non-raising variant for wizards
  (R4-P0-1 reload-verification surface area).
- Optional `[validate]` extra (`pip install klickd[validate]`) —
  `jsonschema` stays optional so callers who only need load/save are
  unaffected.
- v4 TypedDicts: `KlickdMediaProfileV1`, `KlickdVerificationGatesV1`,
  `KlickdGateEntry`, `KlickdHumanVetoPolicy`, `KlickdClaimSources`,
  `KlickdMigrationV1` (additive to `KlickdPayload`).
- README block documenting the new surface + the §33.7 verbatim
  round-trip guarantee on v4 additive fields.

What does NOT ship:

- No envelope/version bump, no PyPI publish, no Git tag, no Zenodo DOI
  — Phase B governance reminder respected.
- No SDK alignment of the docs-only R4-P0-2 codes (`KLICKD_E_PASS_MISMATCH`,
  `KLICKD_E_SAVE_LOCAL`, `KLICKD_E_LEGACY_VERSION`, `KLICKD_E_CORRUPT`,
  `KLICKD_E_POLICY_LOCKED`, `KLICKD_E_UNSAFE_QR`); R4-P0-2 §4 explicitly
  defers SDK exposure to a later track.

Tests (63 / 63 pass):

- 5 R4-P0-3 personas validate against strict payload + unified + preview.
- 5 personas round-trip verbatim (single + double round-trip).
- Negative cases: unknown gate level, missing media hash, unknown
  modality, unsupported `payload_schema_version`, encrypted envelope
  missing kdf/cipher/ciphertext.
- Both structured + flat `verification_gates` shapes accepted.
- Preview value `"4.0.0-preview.1"` accepted by strict schema (P0-2
  design — preview-era files round-trip without rewrite).
- v3.x payloads unaffected (no regression).
- Unknown top-level fields validate AND round-trip verbatim.
- `tests/test_v4_preview_roundtrip.py` and `tests/test_roundtrip.py`
  unchanged and still green.

Repo-level checks: `scripts/validate_v4_schemas.py` ✓ ;
`verify_vectors.py` 59/59 ✓ ; JS `verify_vectors.mjs` 29/29 ✓ .

Refs: P0-3 in `docs/roadmap/ROAD-TO-V4-GA.md`, depends on P0-1 + P0-2
(merged in #42).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The new tests/test_v4_ga_strict.py suite uses klickd.validate, which is
gated on the optional jsonschema dependency. The CI step now installs
the [validate] extra so the strict-schema tests execute; the test file
also pytest.importorskip()s on jsonschema so a local run without the
extra cleanly skips the validation tests instead of erroring.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@Davincc77 Davincc77 merged commit 4136282 into main May 24, 2026
3 checks passed
@Davincc77 Davincc77 deleted the sdk/python-v4-ga-p0-3 branch May 24, 2026 22:23
Davincc77 added a commit that referenced this pull request May 24, 2026
#44)

Mirrors PR #43 (Python SDK V4 GA alignment, merged 4136282) on the
TypeScript side:

- New validate(payload, { strict, target }) and validateIterErrors
  matching the Python surface (klickd.validate). Throws
  KlickdError(KLICKD_E_SCHEMA) with the same 8-issue summary format.
- Bundles all four v4 schemas (payload+unified x strict+preview) under
  src/schemas/, byte-identical to the canonical files in schemas/ and
  schema/. getBundledSchema(key) and listBundledSchemas() mirror
  Python's _load_schema affordance.
- ajv (>=8.12) added as an OPTIONAL peerDependency — callers that do
  not invoke validate() keep the v3 crypto-only surface. Lazy-loaded
  through ajv/dist/2020.js for Draft 2020-12 support; missing-ajv
  raises KLICKD_E_SCHEMA with a clear install hint.
- KlickdPayload extended with the additive v4 GA fields (profile_kind,
  media_profile, verification_gates, human_veto_policy, claim_sources,
  migration, ...) and the v1-frozen sub-types (KlickdMediaProfileEntry,
  KlickdGateEntry, KlickdGateLevel, ...) — parity with
  packages/pypi/klickd/src/klickd/_types.py.
- New Jest suite v4-ga-strict.test.ts mirroring the Python pytest matrix:
  5 personas validated against strict+preview+unified schemas, double
  round-trip preservation, negative cases (unknown gate level, missing
  media hash, bad modality, unsupported schema version, missing
  envelope kdf), both structured and flat gate forms accepted,
  preview/GA cross-acceptance, v3.x non-regression, unknown-field
  preservation (SPEC.md §33.7), validateIterErrors path/message shape,
  and KlickdError(code/httpStatus) shape.

Results: 61/61 Jest, 63/63 Python pytest, 59/59 Python vectors, 42/42 JS
vectors, validate_v4_schemas.py all green, package integrity unchanged.

No package version bump. No publish. tsup build flagged with --external
ajv and --loader .json=copy so the bundled schemas ship in dist/.

Co-authored-by: Claude <claude@anthropic.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants