-**A rotation follows you everywhere (#69).**`delegate add`, `delegate remove`, `rotate` and `renew` record the successor key in the user config when it named the old key, and in the repository's own file when that pinned it, so every checkout moves together. `oxy identity show` warns when a repository pins a key other than the user config's; `oxy config --unset KEY` drops a key; `oxy identity delegate add` takes several identity files in one rotation and reminds you that agents configured with your `author.key` need the new one.
-**Oxygen Strata: a repository on a bucket (#63).**`oxy remote add NAME s3://BUCKET/PREFIX` (`--profile`, `--region`, `--endpoint`), `gs://BUCKET/PREFIX` (`--credentials`), `az://ACCOUNT/CONTAINER/PREFIX`, or `dir://PATH`, then `push`, `pull`, `clone` and `gc` against it as against any remote, with no server in between: objects are written once, the references record moves by compare-and-swap, and two pushers merge and retry rather than lose each other's work. Credentials come from each cloud's own chain. `oxy remote check` runs the conformance suite against a store before it is trusted. `docs/strata.md` is the guide; the bucket layout is not stable before 1.0.
10
11
-**The object store on any Store (#68).**`.oxy/objects` is now the same `Store` a bucket is, with the same keys and the same speed: the first step towards a repository that lives in its owner's bucket with the hub as one client of it. Signatures, seal and receipt entries are written once each, so two writers of a shared store never lose each other's; older repositories still read.
12
13
-**Scoped, expiring delegates (#67).**`oxy identity delegate add FILE --scope changes --expires 8h` lets an AI agent sign changes for you while it can never move a bookmark or tag, or seal, whatever you may do; a host that lands for you gets `changes,refs`. You can revoke a key you delegated to. Older identities still read: a bare key means every scope.
14
15
-**An agent signs as itself, you stay the author.** The agent's keys live in its own `$OXY_HOME`, and `author.signer` (or `$OXY_SIGNER`) names its key, so `oxy commit` in your checkout carries you as author and the agent's signature. `oxy log` says `via NAME` beside the author, `oxy show` has a `via` row with the agent's identity and the delegation it acted under, `oxy identity show` names each delegate, and `oxy log -r 'delegated()'` lists what agents did. The guide's §9 has the setup.
16
17
-**Revsets (#65).**`oxy log -r`, `show -r`, `verify -r` and `abandon -r` take an expression over history: symbols (bookmarks, `origin/main`, tags, change prefixes, `@`), `::X`, `X::`, `X..Y`, `|`, `&`, `~`, `deps`, `dependents`, `heads`, `roots`, `latest`, `independent`, `author`, `description`, `date` (`-7d..`), `kind`, `touches` (through renames), `conflicts`, and the trust predicates `signed_by`, `delegated`, `unsigned`, `revoked`, `attested`, `built`. Saved revsets: `oxy config revset.mine 'author(me) & ::@'` makes `mine()`. A first page takes about 10 ms on this repository; evaluation has a time budget. `docs/revset_query_language.md`.
18
19
-**`oxy gc` and `oxy git import` say what they are doing (#66, #25).** Each phase and count of a gc, and every 500 commits of an import with the commit in hand, through the spinner or as lines without a terminal.
20
21
-**Large merges import in batches (#25).** A merge touching thousands of files builds and renders its graphs 500 files at a time: a 10 000-commit slice of VS Code imports in 135 s at 1.6 GB (from 140 s at 1.6 GB, and far less for the merges alone). The whole history still needs more than 20 GB at its largest merges, which is the next piece of work.
22
23
-**Release builds link on every target.** The cloud stores send through `ureq`, so macOS and Windows builds no longer pull in a C library the cross-compiler cannot link.
-**RISC-V (#59).** Builds for 64-bit RISC-V Linux (`linux-riscv64` and a `riscv64` .deb), tested natively on an OrangePi RV2.
28
29
-**apt (oxygenhub#85).** The .deb adds the repository at https://oxygenhub.io/apt on its first install, so `apt upgrade` keeps oxy current.
30
31
-**Built by OxygenFlow.** Every file of this release comes from the dist job of the release commit's run, signed by its runner: the release's trust page shows each as an attested build.
-**Being on the bookmark you asked for (#60).**`oxy checkout BOOKMARK` switches to that bookmark (as `oxy bookmark switch` does, with `--discard` or `--carry`), where it used to write its files under the current bookmark's name, so the next commit moved the wrong bookmark. `oxy workspace add PATH BOOKMARK` makes a workspace on that bookmark rather than this one's.
34
35
-**A new workspace has its subrepos (#61).**`oxy workspace add` brings each subrepo at its pin from this workspace's own copy, with no network or sign-in, its remote pointing where the subrepo comes from.
-**Fetch says when a bookmark is behind (#56).**`oxy fetch` reports each bookmark against the remote's copy ("main is 1 change behind: oxy pull to take it", ahead, diverged) and says "up to date" only when they match; `--json` gives `ahead` and `behind`. A change that was fetched but not pulled resolves by id or hash, and `oxy show` says it is only in `origin/main`. With one remote not called `origin`, fetch, pull and push use it, and `bookmark list` and the prompt count against it.
-**Clones record local paths absolute (#57).**`oxy clone ../repo copy` and `oxy remote add NAME ../repo` store the absolute path, so fetch, pull and push still find the remote from inside the clone.
42
43
-**Faster commits (#41).** A commit writes the manifest once, its own snapshot neither records an operation nor encodes the change twice, syncs are batched, and edited files are diffed on every core: a one-file commit on the Linux tree takes 0.3 to 0.5 s (from about 3 s; Git 0.15 s, which does not sync), 1 000 files 0.8 s (from 4.9 s).
44
45
-**First commit of a large tree in half the time and less memory (#41).** The Linux tip commits in 12 to 17 s (from 38 s; Git 32 s), peaking at 2.6 GB resident (from 4.4 GB): line offsets take four bytes, inline lines are encoded without a value each, stored texts go at most 32 MiB a batch, and `oxy commit` (and describe, amend, abandon, split, squash, rebase) read only the new change's metadata to print it.
46
47
-**Diff and fsck (#41).** A diff answered from the status cache renders only the files it shows (one file on the Linux tree 0.15 s, from 1.2 s; 1 000 files level with Git), and fsck checks objects in parallel (8 to 10 s, Git 12 to 13 s).
-**Blame twice as fast (#41).**`oxy blame` prints through a buffered writer and formats each change once, and the state index's tree view loads in one step: blame of the Linux tree's MAINTAINERS (30 000 lines) is 0.08 s, from 0.16 s; tuned Git 0.06 s. The faster tree view also takes 16 ms off diff, commit and checkout.
-**`oxy log` in milliseconds (#41).** Log no longer checks the files on disk: its working-copy row shows the working copy as last recorded, "(working copy)" or "(working copy, uncommitted changes)", as Git's log never looks at the working tree; `oxy status` checks the disk. `log -n 100` is 0.03 s on the Linux tree (from 0.17 s) and 0.02 s on a 10 000-commit history.
-**Status twice as fast as Git on the Linux tree (#41).** With uncommitted work, `oxy status` answers from a status cache while every file is as the last snapshot left it, and the manifest keeps every directory's time, so the tree is listed only when a directory's entries changed. One edited file is 0.10 to 0.12 s (from 0.44 s; Git 0.22 s) and a clean status 0.09 to 0.12 s (Git 0.20 to 0.26 s), in 80 MB. `oxy diff` renders the working copy from the cache too (0.20 s, from 0.41 s; Git 0.08 s). A commit after a status takes that status's snapshot instead of walking the tree again (0.37 s, from 0.68 s; Git 0.15 s). A file written within the racy window is now hashed by the prompt's check too, as it was by status.
-**Quieter notes (#55).** Notes start with a dimmed `›` instead of `ℹ`, which many terminal fonts draw as a boxed or emoji-style "i". A spinner's final line no longer shows two ticks or runs into the next line.
-**The operation log says what each operation did (#51).**`oxy op log` gives each operation a summary, such as "main: 1 → 2 heads; working copy now 91ab4d50", with its command dimmed beneath. Runs of working-copy snapshots fold into one row, and `-n` limits the listing. `--json` adds each operation's changes.
60
-**`oxy op restore`, `oxy op revert` and `--at-op` (#52).**`op restore OP` brings back the bookmarks and working copy as they were after OP. `op revert OP` undoes OP alone and keeps everything after it. `--at-op OP` runs any read-only command on the repository as it was then. Restore and revert are operations too, so `oxy undo` takes them back. `undo` now takes back a command's own checkout with it (pull and restore record one), and brings the files back when nothing uncommitted would be lost.
61
-**Commands say where they left you (#53).** Commit, checkout, switch, rebase, merge, amend, abandon, pull, undo, restore and revert end with the working copy and the bookmark's heads, newest first, as jj does.
-**`oxy log` is a graph (#50).** Each change takes two lines: its ID (the shortest unique prefix bright), author, time, bookmarks and tags, hash and signature, then its subject. Lanes follow the change each one most directly builds on, and join where two lines of work meet, so independent work shows side by side. A dependency further than twelve rows down is marked `~`, which keeps the graph to a few lanes even on a long history. `--json` is unchanged.
-**A remote's bookmarks work like local ones (#48).**
66
-`origin/NAME` names a remote's bookmark wherever a bookmark is expected, and `oxy bookmark list --all` lists those with no local bookmark.
67
-`oxy bookmark switch NAME` makes a local bookmark from `origin/NAME` when there is none (`REMOTE/NAME` picks another remote).
68
-`oxy pull` updates every local bookmark the remote has too, not only the current one, and names the others it moved.
69
-`oxy clone` checks out the remote's default bookmark (servers now name it in `refs`), says how many other bookmarks the remote has, and takes `--recursive` to clone the subrepos. A clone, switch or pull says when subrepos are not at their pins.
70
-**A newer repository format names the oxy that cannot read it (#49).** Instead of "unsupported format version 2", oxy says the data was written by a newer oxy, and gives its own version and path, which shows an older copy earlier on `PATH`.
-**Sign in once per hub: `oxy auth login`, `status` and `logout` (#47).**`oxy auth login https://oxygenhub.io` signs in through the browser, and every repository on that hub then clones, fetches and pushes with the token, subrepos included. Nothing secret goes into a checkout any more.
73
- The token is kept in `~/.config/oxy/credentials.toml`, readable by you only, or in the system keyring through a Git credential helper (`oxy config --user auth.helper libsecret`).
74
-`--with-token` reads a token from standard input, for CI and scripts. `oxy auth logout` also revokes the token on the hub.
75
- A token goes over `https` only (plain `http` only to this machine), never to another host after a redirect. A credentials file that others can read is ignored.
76
- Lookup order: `remote.<name>.token`, `OXY_TOKEN`, the store, then an enclosing checkout's remote on the same hub. Clones no longer copy a token into a subrepo's configuration.
77
- Identity secret keys are now created owner-only, rather than tightened just after being written.
Measured on the Linux kernel's tree (95 943 files); `docs/benchmarks.md` has the tables.
80
81
-**Faster than Git on the first commit, a clean status, fsck, gc and the pack's size.**
82
-**First commit:** 21.9 s (Git 33.7 s).
83
-**Clean status:** 0.17 to 0.19 s (Git 0.22 s).
84
-**fsck:** 8.2 s (Git 12.6 s).
85
-**gc:** 33.7 s (Git 70 s).
86
-**The pack:** 293.5 MB (Git's 295.5 MB).
87
-**Level with Git on a local clone (about 17 s).** Status with one file changed, diff, commit, log, blame and checkout are two to six times faster than at 0.1.0. They are still behind Git:
88
-**Status with one file changed:** 0.41 s, against 0.22 s.
89
-**Commit:** 0.67 s, against 0.21 s.
90
-**Blame:** 0.16 s, against 0.07 s.
91
-**Checkout:** 0.74 s, against 0.35 s.
92
-**A project's `.gitignore` files count**, below `.oxyignore`. A project coming from Git no longer commits its build output, and `!` in `.oxyignore` can bring back what `.gitignore` leaves out. Ignore rules still apply to untracked paths only.
93
-**A folder holding a repository of its own is named.**`oxy status`, `oxy commit` and `status --json` (`untracked_nested`) name a folder with its own `.git` or `.oxy`, rather than skipping it silently. They say how to track its files, keep it as a subrepo, or leave it out.
94
-**`oxy rebase CHANGE --onto T --into-working-copy`.** Where a rebase would be conflicted, the target is merged into the current bookmark instead, and the conflict is resolved in the working copy, as after `oxy merge`.
95
-**mimalloc is the allocator.** Most of the speed above came from it: status, walks and index loads allocate many small values from every thread.
96
-**Internals.** Each item below is a cache and is rebuilt when it does not check:
97
- the workspace manifest is a checksummed binary file;
98
- the state index is decoded lazily, caught up by replaying a few changes, and kept for the last two states;
99
- the store caches change metadata;
100
- a pack can carry a trained zstd dictionary.
101
102
##0.1.0 (2026-09-30)
103
104
-**The first builds for people to download.**
105
- Linux x86_64 and arm64 (glibc 2.28 or later) as `.tar.gz` and `.deb`.
106
- macOS x86_64 and arm64.
107
- Windows x86_64.
108
109
All are cross-compiled from Linux with `scripts/dist.sh`, with SHA256SUMS. A prerelease: formats may still change before 1.0.