Commit 8bebe15
authored
refactor(receipt): disentangle Receipt from Invocation (#12)
## Summary
`Receipt` becomes its own Go type, distinct from `Invocation` —
**without changing the wire format**. On the wire a receipt is still a
`/ucan/assert/receipt` invocation; that encoding tracks the UCAN WG
draft ([ucan-wg/receipt#1](ucan-wg/receipt#1))
and is unchanged here. The change is entirely in the Go API surface.
## Motivation
A receipt has always been encoded as a `/ucan/assert/receipt`
invocation, and the Go `Receipt` type embedded `invocation.Invocation`
to reuse the envelope / sigPayload / varsig plumbing. That reuse was a
sensible starting point. As more code was built on the API, a few rough
edges emerged — all on the Go side, none on the wire — that this PR
smooths out:
1. **Clearer type boundaries.** Because `*Receipt` embedded
`invocation.Invocation`, it satisfied `ucan.Invocation` — so anything
declared `func(inv ucan.Invocation)` would quietly accept a receipt.
That has worked in practice, but it makes call-site review harder and
pushes helpers like `validator.VerifyInvocationSignature` toward being
defensively written. With `Receipt` as its own type, signatures say what
they mean.
2. **Tighter discoverability.** Autocomplete on a receipt previously
surfaced the full invocation method set — `Subject`, `Audience`,
`Command`, `Proofs`, `Cause`, `Task`, … — most of which don't carry
receipt-specific information (`Command()` is always the constant,
`Subject()`/`Audience()` are always the executor). The type now exposes
only the receipt-meaningful accessors: `Issuer`, `Ran`, `Out`,
`IssuedAt`, `Nonce`, `MetadataBytes`, `SignedBytes`, `Signature`, plus
`Link`/`Bytes`.
3. **A receipt-specific options surface.** `receipt.Option` was a
re-export of `invocation.Option`, so options like `WithProofs` /
`WithCause` appeared on the receipt API without a defined meaning for a
receipt today. `receipt.Option` is now its own type that translates to
invocation options internally, exposing just `WithNonce` / `WithNoNonce`
/ `WithIssuedAt` / `WithMetadata`.
## What changed
- `Receipt` holds an `invocation.Invocation` as an **unexported field**
instead of embedding it. `*Receipt` no longer satisfies
`ucan.Invocation`.
- `ucan.Receipt` is a standalone interface — it no longer embeds
`ucan.Invocation`.
- `receipt.Option` is its own type with a receipt-only option set.
- Adds `receipt.VerifySignature`, mirroring the `invocation` /
`delegation` helpers.
- Construction (`issue` → `invocation.Invoke`) and decoding (via
`invocation.Invocation`) are unchanged, so encoded receipts are
byte-identical to `main`.
## Intentionally deferred
`prf` (proofs) and `exp` (expiration) are load-bearing receipt fields in
the WG draft — proofs for delegated receipt issuance, expiration for
assertion TTL. They are physically present on the wire today (a receipt
is an invocation), but their receipt-level semantics are still under
discussion upstream. Rather than ship half-defined accessors, the API
stays minimal now and will grow `Proofs` / `Expiration` accessors and
options once the spec settles.
## Wire compatibility
**Unchanged.** Encoded receipts are byte-identical to `main`. Two tests
pin the boundary in both directions:
- `TestWireFormatIsInvocation` — a receipt's exact bytes decode via
`invocation.Decode`, re-encode verbatim, verify through
`invocation.VerifySignature`, and carry the executor as
`iss`/`sub`/`aud`.
- `TestNotAReceipt` (invocation package) — a non-receipt invocation is
rejected by `receipt.Decode`.
## Test plan
- [x] `go build ./...` and `go vet ./...`
- [x] `go test ./...` — full suite green
- [x] `TestWireFormatIsInvocation` — receipt bytes are a valid,
verifiable invocation
- [x] `TestNotAReceipt` — non-receipt invocations don't decode as
receipts
- [x] `TestNotInvocation` — `*Receipt` does not satisfy
`ucan.Invocation`
- [x] `TestVerifySignature`, `TestOptions`, `TestIssueOK` /
`TestIssueErr`1 parent 101376a commit 8bebe15
5 files changed
Lines changed: 370 additions & 52 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
11 | 11 | | |
12 | 12 | | |
13 | 13 | | |
| 14 | + | |
14 | 15 | | |
15 | 16 | | |
16 | 17 | | |
| |||
257 | 258 | | |
258 | 259 | | |
259 | 260 | | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | | - | |
4 | | - | |
5 | | - | |
6 | | - | |
7 | | - | |
8 | | - | |
9 | | - | |
10 | | - | |
11 | | - | |
12 | | - | |
13 | | - | |
14 | | - | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
15 | 7 | | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
6 | 6 | | |
7 | 7 | | |
8 | 8 | | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
9 | 13 | | |
10 | 14 | | |
11 | 15 | | |
12 | 16 | | |
13 | 17 | | |
14 | 18 | | |
15 | 19 | | |
16 | | - | |
17 | | - | |
18 | 20 | | |
19 | 21 | | |
20 | 22 | | |
21 | 23 | | |
22 | 24 | | |
23 | | - | |
24 | | - | |
25 | | - | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
26 | 37 | | |
27 | | - | |
| 38 | + | |
28 | 39 | | |
29 | 40 | | |
30 | 41 | | |
31 | 42 | | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
32 | 53 | | |
33 | 54 | | |
34 | 55 | | |
| |||
46 | 67 | | |
47 | 68 | | |
48 | 69 | | |
49 | | - | |
50 | | - | |
51 | | - | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
52 | 106 | | |
53 | 107 | | |
54 | 108 | | |
55 | | - | |
56 | | - | |
| 109 | + | |
57 | 110 | | |
58 | 111 | | |
59 | 112 | | |
60 | | - | |
61 | | - | |
62 | 113 | | |
63 | 114 | | |
64 | 115 | | |
65 | 116 | | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
66 | 136 | | |
67 | 137 | | |
68 | 138 | | |
| |||
83 | 153 | | |
84 | 154 | | |
85 | 155 | | |
86 | | - | |
| 156 | + | |
87 | 157 | | |
88 | 158 | | |
89 | 159 | | |
| |||
121 | 191 | | |
122 | 192 | | |
123 | 193 | | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
124 | 199 | | |
125 | 200 | | |
126 | 201 | | |
| |||
139 | 214 | | |
140 | 215 | | |
141 | 216 | | |
142 | | - | |
| 217 | + | |
143 | 218 | | |
144 | 219 | | |
145 | 220 | | |
146 | 221 | | |
147 | | - | |
| 222 | + | |
148 | 223 | | |
149 | 224 | | |
150 | 225 | | |
| |||
157 | 232 | | |
158 | 233 | | |
159 | 234 | | |
160 | | - | |
161 | | - | |
162 | | - | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
163 | 238 | | |
164 | 239 | | |
165 | 240 | | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
166 | 250 | | |
167 | 251 | | |
168 | 252 | | |
| |||
0 commit comments