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
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@ All notable changes to this specification are documented here.

The spec document follows [Semantic Versioning](https://semver.org/). Wire formats (Permit `v1`, `closure_v1`, `closure_v2`, chain entry `v1`) version independently and are not bumped by spec-document revisions.

## [1.4.0] — 2026-05-21

Adds Step 4 claim contracts for signed permit decisions, signed permit
revocations, and scope-faithful absence adjudication for post-revocation
dispatch initiation. Permit wire format `v1`, closure formats, and chain entry
`v1` are unchanged.

- Add Step 4 claim contracts (`permit.decision.v1`, `permit.revoked.v1`, `permit.dispatch_absence_after_revocation.v1`) per multi-model design pass 2026-05-21. Scope-faithful absence adjudication, falsifiability-oriented trust model. Reserved `non_membership_profile` namespace for future SMT/NMT native non-membership. PR 1 of Step 4; emission + adjudication land in PR 2 + PR 3.

## [1.3.1] — 2026-05-20

Adds promoted scope-faithfulness negative and edge corpus fixtures for the public verifier contract. Permit wire format `v1`, closure formats, chain entry `v1`, claim registry, and semantic artifacts are unchanged.
Expand Down
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

[![License](https://img.shields.io/github/license/keelapi/keel-permit)](LICENSE)
[![Latest release](https://img.shields.io/github/v/release/keelapi/keel-permit?label=release)](https://github.com/keelapi/keel-permit/releases)
![Spec version](https://img.shields.io/badge/spec-1.3.1-blue)
![Spec version](https://img.shields.io/badge/spec-1.4.0-blue)

A pre-execution decision record for AI agent systems. A Permit records that an action was evaluated and decided, and, for dispatched allow executions, can be bound to the final provider or tool request. A Permit JSON object alone is not self-authenticating; verification is performed from signed export artifacts and the relevant public keys or key manifest. Those artifacts are verifiable without contacting the issuer when the verifier has the signed export artifacts and relevant public keys/key manifest.

Expand All @@ -12,7 +12,7 @@ This repository contains the wire-format specification, JSON schemas, and verifi

| | |
|---|---|
| Spec document version | 1.3.1 |
| Spec document version | 1.4.0 |
| Permit wire format | `v1` |
| Closure record format | `closure_v1`, `closure_v2` |
| Chain entry hash format | `v1` |
Expand Down Expand Up @@ -61,6 +61,8 @@ flowchart LR
- [`spec/permit-chain-v1.md`](spec/permit-chain-v1.md) — Delegated Permit Chain semantics
- [`spec/verifier-claims-v0.md`](spec/verifier-claims-v0.md) — Verifier claim model
- [`spec/verifier-pack-pinning-v0.md`](spec/verifier-pack-pinning-v0.md) — Pinned semantics for evidence packs
- [`spec/permit-revoked-event-v1.md`](spec/permit-revoked-event-v1.md) — Signed permit revocation event
- [`spec/dispatch-absence-after-revocation-v1.md`](spec/dispatch-absence-after-revocation-v1.md) — Scope-faithful absence adjudication after revocation

## Schemas

Expand Down
33 changes: 33 additions & 0 deletions claim_registry/v0.json
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,39 @@
"insufficient_evidence",
"unverifiable_scope"
]
},
{
"name": "permit.decision.v1",
"assertion": "The issuance-time permit decision is validly signed by the permit-binding key through the v1 binding canonical payload, including the canonical `decision`; this claim adjudicates the signed issuance decision only and never mutated row state.",
"required_evidence": "Permit decision evidence carrying the v1 binding canonical payload or fields sufficient to reconstruct it, binding_canonical_hash, binding_signature, binding_key_id, binding_issued_at, permit-binding trust root, and pinned permit decision semantics.",
"verdict_enum": [
"supported",
"disproved",
"insufficient_evidence",
"unverifiable_scope"
]
},
{
"name": "permit.revoked.v1",
"assertion": "A new-only post-cutover `permit.revoked` event is validly signed by the permit-binding key, is bound to both `permit_id` and `project_id`, and uses v1 immediate-effect semantics where `effective_at` equals `revoked_at`.",
"required_evidence": "Strict permit.revoked event payload, signature, permit-binding trust root, referenced permit/project identity, signing time or event time for key-window resolution, and pinned revoked-event semantics.",
"verdict_enum": [
"supported",
"disproved",
"insufficient_evidence",
"unverifiable_scope"
]
},
{
"name": "permit.dispatch_absence_after_revocation.v1",
"assertion": "Scope-faithful absence adjudication shows that no `dispatch.egress_bound` event appears for the revoked permit and project in the declared scope where `occurred_at` is greater than or equal to the revocation `effective_at` and less than the checkpoint boundary.",
"required_evidence": "supported permit.revoked.v1 evidence; signed export scope-faithfulness segment using scope-predicate v1 equality on project_id, permit_id, and event_type=dispatch.egress_bound plus bounded occurred_at range; checkpoint.scope_state.v1 sidecar; referenced checkpoint JSON; bridge/proof records; pinned absence, export scope-faithfulness, scope-state, and governance-chain semantics.",
"verdict_enum": [
"supported",
"disproved",
"insufficient_evidence",
"unverifiable_scope"
]
}
]
}
67 changes: 67 additions & 0 deletions schemas/permit-revoked-event.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://github.com/keelapi/keel-permit/blob/main/schemas/permit-revoked-event.schema.json",
"title": "Permit Revoked Event v1",
"description": "Strict payload shape for a post-cutover signed permit.revoked event. The normative v1 rule effective_at == revoked_at is specified in spec/permit-revoked-event-v1.md.",
"type": "object",
"additionalProperties": false,
"properties": {
"permit_id": {
"type": "string",
"format": "uuid",
"description": "UUID of the revoked permit."
},
"project_id": {
"type": "string",
"format": "uuid",
"description": "UUID of the project that owns the revoked permit. Signed to prevent cross-project replay."
},
"actor_id": {
"type": "string",
"format": "uuid",
"description": "Opaque actor UUID. Email, name, display labels, and customer-controlled identifiers are not valid actor_id values."
},
"actor_kind": {
"type": "string",
"enum": [
"user",
"service_account",
"system",
"api_key"
],
"description": "Opaque actor class for the revocation actor."
},
"reason_code": {
"type": "string",
"minLength": 1,
"maxLength": 128,
"pattern": "^[a-z][a-z0-9_]*(\\.[a-z0-9_]+)*$",
"description": "Machine-readable taxonomy code. Free-text reasons are not part of the signed v1 payload."
},
"revoked_at": {
"type": "string",
"format": "date-time",
"description": "Governance event time for the revocation."
},
"effective_at": {
"type": "string",
"format": "date-time",
"description": "Effective revocation time. v1 requires this value to equal revoked_at."
},
"signature": {
"type": "string",
"pattern": "^[A-Za-z0-9+/]{86}==$",
"description": "Base64 Ed25519 signature over the revocation event canonical hash using a permit-binding key."
}
},
"required": [
"permit_id",
"project_id",
"actor_id",
"actor_kind",
"reason_code",
"revoked_at",
"effective_at",
"signature"
]
}
Loading
Loading