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
19 changes: 14 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,16 @@ versioned independently of the reference implementation and **leads** it: a
behaviour is specified (marked *draft — not yet in reference*) before the
reference implements it. See [`spec.md` §2.1](spec.md) for the version matrix.

## [0.3.0-draft] — Unreleased
## [0.3-draft] — Unreleased

### Fixed
- §8.1 corrected: hash-chaining does **not** detect truncation of the most recent
receipts (a truncated prefix verifies clean), nor a holder of the local signing
key. Added a normative caveat requiring external head anchoring for rollback
detection — the prior "deleting any receipt breaks a check" claim was wrong.
- Version notation normalised to the `0.x` scheme everywhere (spec/protocol is
`0.x`; the reference *package* is `0.x.y`). `conformance.py` now parses a
two-component spec version.

### Added (0.3, draft — not yet in reference)
- §4.2 — the URL **query string** is folded into the `action_fingerprint`
Expand Down Expand Up @@ -34,9 +43,9 @@ reference implements it. See [`spec.md` §2.1](spec.md) for the version matrix.
### Changed
- §6 — the determinism requirement now names *evaluation time* as an input
(the `rate_limit` window), rather than implying a time-independent function.
- Document version → 0.3.0-draft.
- Document version → 0.3-draft.

## [0.1.0-draft] — initial specification
## [0.1-draft] — initial specification

### Added
- §3 canonical JSON; §4 intent hash + action fingerprint; §5–§6 deterministic
Expand All @@ -45,5 +54,5 @@ reference implements it. See [`spec.md` §2.1](spec.md) for the version matrix.
§9 authorization-token draft.
- JSON Schemas (`schema/`), CTK vectors (`ctk/`), and `validate.py`.

[0.3.0-draft]: https://github.com/Delego-Dev/specification
[0.1.0-draft]: https://github.com/Delego-Dev/specification/releases/tag/v0.1.0
[0.3-draft]: https://github.com/Delego-Dev/specification
[0.1-draft]: https://github.com/Delego-Dev/specification/releases/tag/v0.1
11 changes: 6 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

[![Contributions welcome](https://img.shields.io/badge/contributions-welcome-green.svg)](CONTRIBUTING.md)
[![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)
[![Spec](https://img.shields.io/badge/spec-v0.1.0--draft-orange.svg)](spec.md)
[![Spec](https://img.shields.io/badge/spec-v0.3--draft-orange.svg)](spec.md)

The open specification for **delego** — a deterministic **authorization & audit
protocol for AI-agent actions**. It defines how an action proposed by an agent
Expand Down Expand Up @@ -69,10 +69,11 @@ reproduce them; see [§10 Conformance](spec.md#10-conformance).

## Status & versioning

**v0.1.0 — draft.** §3–§8 formalize the reference implementation; §9
(Authorization Token) defines the next protocol increment and is not yet
implemented. The wire format is versioned with the spec — a breaking change to
the receipt fields bumps the version together (see [§8.2](spec.md#82-schema-versioning)).
**v0.3 — draft.** The spec/protocol is versioned `0.x` (the reference *package*
is `0.x.y`). 0.1–0.2 are reference-backed; 0.3 (query-string fingerprint §4.2,
authorization token §9) is specified but not yet in the reference. See the
[§2.1 version matrix](spec.md#21-protocol-versions). A breaking change to the
receipt fields bumps the version (see [§8.2](spec.md#82-schema-versioning)).

## Contributing

Expand Down
3 changes: 2 additions & 1 deletion conformance.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ def ok(msg: str) -> None:

def spec_version() -> tuple[int, ...]:
text = (ROOT / "spec.md").read_text(encoding="utf-8")
m = re.search(r"\*\*Version:\*\*\s*([0-9]+\.[0-9]+\.[0-9]+)", text)
# Spec/protocol versions are two-component (0.x); tolerate a patch too.
m = re.search(r"\*\*Version:\*\*\s*([0-9]+\.[0-9]+(?:\.[0-9]+)?)", text)
return tuple(int(x) for x in m.group(1).split("."))


Expand Down
34 changes: 23 additions & 11 deletions spec.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# delego Wire Specification

**Version:** 0.3.0 (draft) · **Status:** Draft · **License:** Apache-2.0
**Version:** 0.3 (draft) · **Status:** Draft · **License:** Apache-2.0

This document specifies the **delego protocol**: how an *action proposed by an
agent* is authorized — deterministically, with no LLM in the decision path —
Expand Down Expand Up @@ -48,12 +48,12 @@ of this document.

| Version | Status | Adds |
|---------|--------|------|
| **0.1.0** | reference-complete, CTK-backed | Canonical JSON (§3); intent hash + action fingerprint (§4); deterministic policy & decision, first-match-wins, fail-closed (§5–§6); fingerprint-bound approval / confused-deputy guard (§7); append-only, hash-linked, Ed25519-signed audit chain + verification (§8). |
| **0.2.0** | reference-complete, CTK-backed | Approval & audit hardening. Approvals are additionally bound to the `intent_hash` and made **single-use** (§7); an approved action's `execution` receipt carries the rule it was parked under, so `rate_limit` counts it (§5, §8); verification treats a malformed or partial receipt as a *failure* rather than aborting the walk (§8.1). |
| **0.3.0** | **draft — not yet in reference** | Query-string-bound fingerprint (§4.2); signed authorization token (§9, §9.1). |
| **0.1** | reference-complete, CTK-backed | Canonical JSON (§3); intent hash + action fingerprint (§4); deterministic policy & decision, first-match-wins, fail-closed (§5–§6); fingerprint-bound approval / confused-deputy guard (§7); append-only, hash-linked, Ed25519-signed audit chain + verification (§8). |
| **0.2** | reference-complete, CTK-backed | Approval & audit hardening. Approvals are additionally bound to the `intent_hash` and made **single-use** (§7); an approved action's `execution` receipt carries the rule it was parked under, so `rate_limit` counts it (§5, §8); verification treats a malformed or partial receipt as a *failure* rather than aborting the walk (§8.1). |
| **0.3** | **draft — not yet in reference** | Query-string-bound fingerprint (§4.2); signed authorization token (§9, §9.1). |

This document is at **0.3.0 (draft)**; the reference implements **0.2.0**. Clauses
introduced after 0.1.0 are tagged inline — *(since 0.2)* for reference-backed
This document is at **0.3 (draft)**; the reference implements **0.2**. Clauses
introduced after 0.1 are tagged inline — *(since 0.2)* for reference-backed
behaviour, *(0.3, draft)* for the not-yet-implemented frontier.

## 3. Canonicalization (NORMATIVE)
Expand Down Expand Up @@ -311,7 +311,19 @@ An Auditor verifies a chain by walking it in `seq` order. For each receipt it
3. **Signature** — `Ed25519_verify(pubkey, signature, UTF8(entry_hash))` succeeds.

The chain is valid iff every check passes for every receipt. Editing,
reordering, inserting, or deleting any receipt breaks at least one check.
reordering, inserting, or deleting a receipt **from anywhere but the end** breaks
at least one check.

**Truncation is not detected by chaining alone (NORMATIVE caveat).** Removing the
most recent receipts leaves a shorter but internally consistent prefix that
verifies clean — the chain commits each receipt to its predecessor, not to the
*length* of the log. Likewise, an Auditor that only holds the Authorizer's public
key cannot detect this, and an attacker who holds the (local) signing key can
re-sign an arbitrary rewrite. To detect truncation or rollback, the head **MUST**
be anchored outside the log: persist the latest `(seq, entry_hash)` somewhere the
writer can't unilaterally rewrite (a remote store, a second host, a transparency
log) and reject a chain whose last receipt doesn't match it. High-assurance
deployments **SHOULD** also keep the signing key in an HSM/KMS.

*(since 0.2)* A **structurally invalid** receipt — one not parseable as JSON, or
missing any of the eleven signed fields — **MUST** be treated as a verification
Expand Down Expand Up @@ -381,23 +393,23 @@ See [`examples/authorization-token.md`](examples/authorization-token.md) and

An implementation declares the highest protocol version (§2.1) it implements, and
**MUST** satisfy every clause at or below that version and reproduce that version's
CTK vectors. The reference implements **0.2.0**.
CTK vectors. The reference implements **0.2**.

**0.1.0**
**0.1**
- A conformant **Authorizer** MUST implement §3–§8 and reproduce the CTK
`hashing` and `decisions` vectors, and produce chains that verify per §8.1.
- A conformant **Auditor** MUST implement §8.1 and agree with the CTK `chain`
expectations (valid and tampered).

**0.2.0** (additionally)
**0.2** (additionally)
- An **Authorizer** MUST implement the §7 intent guard and single-use semantics
and reproduce the CTK `resolve` vectors; MUST attribute an approved action's
`allow` receipt to its parking rule (§5, §8); MUST `deny` a `rate_limit` it
cannot evaluate (§5).
- An **Auditor** MUST treat a malformed or partial receipt as a verification
failure, not an error (§8.1).

**0.3.0** (draft — not yet in reference)
**0.3** (draft — not yet in reference)
- An **Authorizer** binds the query string into the fingerprint (§4.2) and MAY
mint authorization tokens (§9).
- A **Broker** that participates in §9 MUST implement §9.1.
Expand Down
Loading