OXYGENHUB

Spec: the transparency log in refs answers and what fetch checks 0ed150d62994

§16's refs response (ref key 6, response key 6) and §14.8's client
rules, as built in ab796c92; docs/protocol.md likewise.

Refs oxygenhub#238
Author
Andy McCall @andymccall <[email protected]>
via
agent agent:claude@andymccall <[email protected]> · keyless, under your grant for changes,refs,seal · key 9d6fae54f4ad
When
· 2026-10-17 23:56 UTC
Signature
◈ sealed by agent:claude@andymccall
Hash
0ed150d629943b0d9b630d67e32c0215ba61b104b56f9e02107768ddea10478c
Depends on
83e0677b07fe e5f8eb2a2006 ee06a6c557b7 f53cbe7a204e ff0af1ee299d
Depended on by
b63fc7a77fc6 1ec6fdbc6bcb 028545dfa7a4 b0621c2f8cc4 e59512f2f075
In bookmarks
carried-not-removed doctor-trust identical-sides keyless-tags main merge-remote-bookmark paths-for-resolutions-and-amend push-notes show-stat subrepo-pin-state
In tags
v0.10.0 v0.11.0 v0.5.0 v0.5.1 v0.6.0 v0.7.0 v0.8.0 v0.9.0
Edits
6 atoms, 0 tree operations, 2 files

Browse the tree at this change

modified docs/protocol.md +1 −1
…
87 unchanged lines
88 88
| Signed policy | `[policy bytes, [Signature]]` (also the policy proposal file format) |
89 89
| Capabilities | `{0: [protocol versions], 1: repo id bytes(16), 2: [feature names]}`; version `1`; features currently `["seal"]` |
90 90
| Refs response | `{0: [ref], 1: repo id, 2: signed policy or null, 3: [tag], 4: [signed policy]}` |
91 -
| ref | `{0: name, 1: state ref, 2: [heads], 3: signed attestation or null, 4: last serial or null, 5: signed acceptance}`; the attestation is present only when it describes the current state; `last serial` is the highest attestation serial ever recorded for the name; key 5 (optional, only when there is one) is the host's `accepted` attestation of that attestation (spec §14.7) |
91 +
| ref | `{0: name, 1: state ref, 2: [heads], 3: signed attestation or null, 4: last serial or null, 5: signed acceptance}`; the attestation is present only when it describes the current state; `last serial` is the highest attestation serial ever recorded for the name; key 5 (optional, only when there is one) is the host's `accepted` attestation of that attestation (spec §14.7); key 6 (optional) is `[entry number, entry bytes, [proof hash]]`, the attestation's inclusion proof in the host's transparency log against the response's key 6, the latest checkpoint as a signed note (spec §14.8) |
92 92
| tag | `{0: name, 1: state ref, 2: [heads], 3: signed attestation or null}` |
93 93
| Negotiate request | `{0: [have], 1: [want]}`; response `{0: [hashes]}` in dependency order (no change before its dependencies) |
94 94
| Fetch request | `{0: [hashes], 1: max blob size or null}`; response a Bundle whose blobs above the size (and their chunks) are omitted |
…
109 unchanged lines
modified docs/spec.md +7 −2
…
780 unchanged lines
781 781
- with the host key's Ed25519 half, as a standard note signature (type 0x01: key hash = SHA-256(name ‖ "\n" ‖ 0x01 ‖ public key)[:4], signature over the text), which note tools read;
782 782
- with the composite key, as type 0x4f (key hash over the identity object's bytes): the CBOR of a composite Signature in domain `checkpoint` over `BLAKE3("oxygen-tlog-note\0" || text)`.
783 783
784 -
A reader accepts a checkpoint only when both verify, so the log stays post-quantum. Which witnesses must cosign it, and how a client uses inclusion proofs, are §16's and oxygenhub docs/transparency.md's.
784 +
A reader accepts a checkpoint only when both verify, so the log stays post-quantum. Which witnesses must cosign it is oxygenhub docs/transparency.md's.
785 785
786 +
**On fetch**, when a refs response carries a checkpoint (§16), a client:
787 +
- pins the host's log key on first sight (the hub's published identity), per user and hub, with the checkpoint;
788 +
- requires every later checkpoint to verify with that key, keep its origin, and extend the last one seen: a smaller tree, the same size with another root, or a consistency proof that fails (computed from the host's tiles) means the host showed two histories, and the fetch fails;
789 +
- checks each bookmark's attestation against its entry (kind `ref`, the attestation's ObjectRef and repository id) and inclusion proof, reporting one that is missing or does not verify. While logs are new this is a warning, not a refusal.
790 +
786 791
## 15. Transport
787 792
788 793
Every transport carries the same wire protocol (§16). The transport provides the channel; integrity and authenticity of history come from the object model regardless of channel.
…
54 unchanged lines
843 848
| `Bundle` | `{0: [[change bytes, [Signature]]], 1: [signed attestation], 2: [[type name, object bytes]], 3: [signed policy]}`; changes in dependency order; objects are chunks, blobs, identities, and states only, and include the text blobs of every change in the bundle and their chunks, so a bundle can be read on its own; a push that moves a bookmark also carries the identity that signed the move and, for a delegate, the identity it acts for, so a receiver that has seen no change by that key can check it (oxygenhub#129); key 3 (optional) holds the policies between the receiver's serial and the one sent with a push, ascending; key 4 (optional, only when there are any) holds signed certificates (§14.7) of short-lived keys that signed what the bundle carries or the push's attestation, their keys' and issuers' identities among the objects; a receiver keeps each that verifies with its issuer and refuses a bundle with one that does not |
844 849
| `capabilities` response | `{0: [versions], 1: repo id bytes(16), 2: [feature names]}` |
845 850
| Signed policy | `[policy bytes, [Signature]]` |
846 -
| `refs` response | `{0: [{0: name, 1: state ref, 2: [heads], 3: signed attestation or null, 4: last serial or null, 5: signed acceptance}], 1: repo id, 2: signed policy or null, 3: [tag], 4: [signed policy]}`; key 4 (optional) lists earlier policies ascending by serial; key 5 (optional, text or null) names the default bookmark, which a clone checks out; the attestation is present only when it describes the current state; an entry's key 5 (optional, only when there is one) is the host's acceptance of that attestation (§14.7); a tag is `{0: name, 1: state ref, 2: [heads], 3: signed attestation or null}` |
851 +
| `refs` response | `{0: [{0: name, 1: state ref, 2: [heads], 3: signed attestation or null, 4: last serial or null, 5: signed acceptance}], 1: repo id, 2: signed policy or null, 3: [tag], 4: [signed policy]}`; key 4 (optional) lists earlier policies ascending by serial; key 5 (optional, text or null) names the default bookmark, which a clone checks out; the attestation is present only when it describes the current state; an entry's key 5 (optional, only when there is one) is the host's acceptance of that attestation (§14.7); an entry's key 6 (optional) is the attestation's place in the host's transparency log, `[entry number, entry bytes, [proof hash]]`, an inclusion proof against the checkpoint in the response's key 6 (§14.8); the response's key 6 (optional, text) is the host's latest checkpoint, a signed note; a tag is `{0: name, 1: state ref, 2: [heads], 3: signed attestation or null}` |
847 852
| `negotiate` request | `{0: [have], 1: [want]}`; response `{0: [hashes]}` in dependency order |
848 853
| `fetch` request | `{0: [hashes], 1: max blob size or null}`; response a `Bundle` without blobs above the size |
849 854
| `objects` request | `{0: [refs]}`; response a `Bundle` carrying only objects, a blob accompanied by its chunks |
…
282 unchanged lines