Skip to content

Expand permit decision binding coverage to v1/v2/v3/v4 (independent offline verification of MPP + delegation permits)#29

Merged
sftimeless merged 1 commit into
mainfrom
pr-b-b2-expand-binding-coverage-2026-06-04
Jun 4, 2026
Merged

Expand permit decision binding coverage to v1/v2/v3/v4 (independent offline verification of MPP + delegation permits)#29
sftimeless merged 1 commit into
mainfrom
pr-b-b2-expand-binding-coverage-2026-06-04

Conversation

@sftimeless

Copy link
Copy Markdown
Member

Summary

Expands the permit.decision.v1 claim's binding-version pin from v1-only to v1/v2/v3/v4, so the published keel-verifier package can independently verify offline:

  • v2 permits (session/chain binding)
  • v3 permits (spend_scope_hash — MPP-era permits)
  • v4 permits (delegation_policy_hash — cross-verb dispatch, keel-api PR #239)

Before this PR, pip install keel-verifier + running it against any MPP/workflow-intent/delegation permit rejected with literal "binding_version must be v1". Runtime tamper-evidence in keel-api already covered v1-v4; this PR brings the external independent verifier to parity.

What this ships

Binding coverage expansion (additive — no v1 behavior changes):

  • verifier.py:3566 — pin loosened from binding_version == "v1" to enum {v1, v2, v3, v4}
  • data/semantics/permit/decision_v1.jsonbinding_version field is now {"enum": ["v1","v2","v3","v4"]}
  • Old v1-only semantic bundled as historical artifact for pinned packs (backcompat)

New verifier-side canonical builders (keel_verifier/canonical/permit_binding.py — ported from keel-api, byte-identical):

  • _canonical_json (UTF-8, ensure_ascii=False, sort_keys=True, separators=(",", ":"))
  • canonical_binding_payload_v1/v2/v3/v4
  • canonical_spend_scope_payload (v3 recompute input)
  • canonical_delegation_policy_payload (v4 recompute input)

Independent recompute + tamper detection:

  • v3: extract signed spend_scope_hash, recompute from resource_attributes_json, reject on mismatch with structured code permit.binding.v3.spend_scope_hash_mismatch
  • v4: same pattern for delegation_policy_hash, structured code permit.binding.v4.delegation_policy_hash_mismatch

Version + metadata:

  • pyproject.toml: 3.0.13.1.0 (additive minor)
  • CHANGELOG, capability metadata, semantic pin hash, embedded release manifest updated

Important correction to spec

Dispatch prompt incorrectly stated spend_scope_hash was added in v2 binding. Codex code-grounded against keel-api permit_binding.py:558 and found the actual layout:

  • v2: session/chain binding fields
  • v3: + spend_scope_hash (← MPP permits use v3, not v2)
  • v4: + delegation_policy_hash

Reject codes are correctly named for v3 (spend_scope) and v4 (delegation_policy) per the actual binding versions, not the spec's incorrect naming.

Source-of-truth specs

  • keel-api/docs/_strategy/SPEC_PARENT_CHILD_VERB_DELEGATION_v4_PRB_VERIFIER_DESIGN_2026-06-03.md — verifier design (B2 path)
  • keel-api/app/services/permit_binding.py — canonical builder source (mirrored byte-identically)

Test plan

  • CI green (300 passed, 6 skipped + ruff clean locally)
  • 6 byte-identity golden-vector tests prevent silent canonicalization divergence with keel-api
  • 11 recompute + tamper-detection + regression tests cover v2/v3/v4 + unknown-version rejection
  • Existing v1 validation unchanged (regression test)
  • After merge: tag v3.1.0 → release.yml publishes to PyPI
  • After PyPI publish: end-to-end smoke — pip install keel-verifier==3.1.0 + run against a production MPP permit → PASS (not "binding_version must be v1")

Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com

🤖 Generated with Claude Code

Port the keel-api permit-binding canonical builders into keel-verifier and accept permit.decision.v1 canonical payloads for binding versions v1 through v4.

Recompute v3 spend_scope_hash and v4 delegation_policy_hash from exported resource_attributes_json before accepting a signed permit decision, while preserving historical v1 semantic pins for old pinned packs.

v3 source note: keel-api PR #239 commit 03bcd1d964c6f25f9c985850d1452a19ee771a5a shows v2 adds session/chain binding fields, v3 adds spend_scope_hash, and v4 adds delegation_policy_hash.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@sftimeless sftimeless merged commit 594e453 into main Jun 4, 2026
4 checks passed
@sftimeless sftimeless deleted the pr-b-b2-expand-binding-coverage-2026-06-04 branch June 4, 2026 16:57
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