OXYGENHUB

Releases 1

oxy 0.6.0 v0.6.0 · ✔ signed by Andy McCall · andymccall ·

Trust and audit
  • A shallow clone of a big repository works, and quickly (issue #137). oxy clone --depth 0 of the VS Code history failed after eleven minutes ("object … not found"): the blobs of the state's binary files are named only by the changes that set them, which a depth-0 clone does not take, so nothing brought them. They are now fetched with the checkpoint (in parts), or left to be fetched on read under --max-blob. The checkpoint itself was stored object by object, each written loose and flushed (57,498 objects at 27 a second); it is now stored in one batch, as a fetch's objects are.
  • A checkpoint is served faster, and says where its time goes (issue #137). A server gathered a checkpoint's graph blobs and their chunks one read at a time: six minutes for the VS Code state's 57,000. They are now read in two parallel batches. OXY_TIMINGS=1 now times the checkpoint's phases on both sides (checkpoint: gather its objects, serve: encode the checkpoint, remote: checkpoint answer, shallow: store the checkpoint and the rest).
  • A depth-0 clone takes no change (issue #137). oxy clone --depth 0 took the head changes themselves (the VS Code import's main has 33,835 heads), though the checkpoint already holds every change's metadata, so depth 0 now takes none (spec §17's "a checkpoint plus zero history"): its heads become the shallow boundary, and commit, push and pull on top work as before (a shallow repository takes and builds on changes below what it cloned, which the remote holds).
  • A push no longer passes a proxy's request limit (issue #133). A push to a hub behind Cloudflare, which takes at most 100 MB in one request, was refused HTTP 413 with Cloudflare's HTML page printed raw: parts of a long push were about 256 MiB, and one change's blobs went in one request however many there were. Parts are now about 64 MiB (push.batch-bytes), a part whose blobs pass that sends them first in parts of objects alone, an HTML error page is shown by its title, and a 413 says how to push in smaller parts.
  • A keyless agent's grant survives its owner's key rotation (issue #135). Every delegation an owner adds or removes renews their identity, and a repository that names the newest key as author.key read every change their agent sealed as INVALID ("key … is neither the author nor a delegate"), and its pushes were refused, because the agent's grant was signed by the owner's earlier key. A grant by a key the author's identity was rotated or renewed from now counts when it was made before that rotation; one an old key made after it does not.
  • A tag can be withdrawn, by a signed withdrawal (oxygenhub#301). There was no way to remove a tag anywhere: a mistaken release tag stayed for good. oxy tag delete NAME [-r REASON] records an untag attestation naming the tag's state, signed like a tag (a ten-minute keyless key too), and the next oxy push sends it to a remote that still has the tag; oxy push --delete tags/NAME does both at once. A receiver under a policy accepts it only from a key that may create the tag, keeps it beside the tag's creation, and lists withdrawn tags in its refs answer (key 8), so a fetch withdraws the tag there too (tag v1 was withdrawn on origin, and here). A withdrawn name is never used again, so a tag name never names two states. oxy-server's Backend gains vet_tag_withdrawal (OxygenHub refuses while a release uses the tag), and Repo::host_tag_create and host_tag_withdrawal let a host make or withdraw a tag for a signed-in user. The wire change is additive, but an older server refuses a withdrawal (wrong attestation kind), and an older client keeps a withdrawn tag.
  • A keyless agent's changes verify in a repository that has never seen its owner (issue #134). An agent's ten-minute key is certified under its owner's signed grant, and a change it signed only verified where the owner's identity was already stored: in a new repository, or one the owner had not pushed to since a key rotation, oxy log --verify and the hub said INVALID ("grant is by an unknown author"). OxygenHub now sends the grant's signer with the certificate (grantor_identity, additive), oxy keeps it (else uses <oxy home>/keys/<key>.identity, or refuses with how to put it there), and a push brings it beside the certificate, so the receiver can check the grant.

Assets