Skip to content

feat(spec): allow custom_metadata extension carrier in permit-v1 (v1.5.0)#9

Merged
sftimeless merged 2 commits into
mainfrom
codex/spec-v1.5.0-custom-metadata
Jun 3, 2026
Merged

feat(spec): allow custom_metadata extension carrier in permit-v1 (v1.5.0)#9
sftimeless merged 2 commits into
mainfrom
codex/spec-v1.5.0-custom-metadata

Conversation

@sftimeless

Copy link
Copy Markdown
Member

Why

The Keel API authorization migration (keel-api 2026-06-02) ships Permit.custom_metadata, a JSON field carrying issuer-defined extensions. The first shipped key is shadow_override, which carries audit annotation when the issuer's shadow override layer blocks a dispatch.

Without this spec update, third-party validators built against the published permit-v1.schema.json, audit-export-bundle.schema.json, or audit-export-record.schema.json schemas would reject any permit containing custom_metadata — because all three schemas had additionalProperties: false on AuditExportPermitSource with no escape valve.

What changed

3 schema files (schemas/permit-v1.schema.json, schemas/audit-export-bundle.schema.json, schemas/audit-export-record.schema.json):

  • Added custom_metadata as an optional property on AuditExportPermitSource in every schema's properties block
  • custom_metadata uses type: ["object", "null"], default: null, and additionalProperties: true — the escape hatch for issuer-defined keys
  • The outer AuditExportPermitSource object retains additionalProperties: false — the closed-with-escape-valve pattern is intentional

spec/permit-v1.md:

  • Added custom_metadata row to §2.3 optional fields table
  • Rewrote §12 to document "closed semantics with explicit extension carrier" — validators MUST reject unknown top-level fields but MUST accept arbitrary keys inside custom_metadata
  • Reserved shadow_override under custom_metadata with its sub-field inventory
  • Added Spec version: 1.5.0 header to top of document

CHANGELOG.md: added [1.5.0] — 2026-06-02 entry

tools/export_schemas.py: added _PERMIT_EXTENSION_FIELDS constant and injected it alongside _PERMIT_CHAIN_FIELDS in _add_permit_chain_fields() so future schema re-generations from keel-api preserve custom_metadata

test-vectors/vectors/cat-01-baseline/01-02-permit-with-custom-metadata/: new scaffolded conformance vector requiring validators to PASS on a permit carrying custom_metadata: {"shadow_override": {"outcome": "blocked"}}

Backward compatibility

Fully additive. custom_metadata is optional with default: null. Every existing v1.4.x permit validates unchanged — no required fields added, no fields removed or renamed. Validators that accepted v1.4.x records are still correct for records that omit custom_metadata.

Forward design

additionalProperties: true inside custom_metadata means future issuer extension keys (beyond shadow_override) can be added without a spec version bump. Future spec versions will reserve additional custom_metadata keys as needed; consumers are instructed to ignore unknown keys gracefully.

Test plan

  • Schema JSON validity confirmed (python3 -c "import json; json.load(open(f))" on all three schemas)
  • additionalProperties: false verified still present on outer AuditExportPermitSource in all three schemas
  • additionalProperties: true verified present on custom_metadata in all three schemas
  • git diff --check passes (no whitespace issues)
  • New conformance vector 01-02 scaffolded documenting the acceptance requirement
  • Existing closure tests: no executable test suite in this repo (all vectors are scaffolded stubs pending fixture-generator); no existing tests were modified

🤖 Generated with Claude Code

@sftimeless sftimeless closed this Jun 3, 2026
@sftimeless sftimeless reopened this Jun 3, 2026
…5.0)

The Keel authorization migration (keel-api 2026-06-02) adds a permit-level
custom_metadata field carrying issuer-defined extensions, initially
shadow_override audit annotations. Without this spec update, conforming
third-party verifiers would reject permits containing the new field per §12's
closed semantics.

This update:
- Adds custom_metadata to AuditExportPermitSource in all three schemas with
  additionalProperties: true (escape hatch for additive issuer extensions)
- Documents the closed-with-escape-valve semantics in spec §12
- Reserves the shadow_override key under custom_metadata
- Bumps spec version to 1.5.0 (additive minor, backward compatible)

Refs: keel-api auth migration (AUTHORIZATION_MIGRATION_STATUS_2026-06-01.md)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@sftimeless sftimeless force-pushed the codex/spec-v1.5.0-custom-metadata branch from 3ac76dc to 3027497 Compare June 3, 2026 17:32
@sftimeless sftimeless closed this Jun 3, 2026
@sftimeless sftimeless reopened this Jun 3, 2026
The repo-integrity check requires README spec version to match the
latest CHANGELOG entry. PR #9 bumped CHANGELOG to 1.5.0 but missed
updating the two README references.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@sftimeless sftimeless merged commit af698cf into main Jun 3, 2026
1 check passed
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.

1 participant