| 1 |
1 |
|
# Changelog |
| 2 |
2 |
|
|
|
3 |
+ |
## Unreleased |
|
4 |
+ |
|
|
5 |
+ |
- **Fetch checks the hub's transparency log (oxygenhub#238).** A hub that keeps a log sends its latest checkpoint with every refs answer, and each bookmark's attestation with its log entry and inclusion proof. The first fetch pins the hub's log key in `<oxy home>/tlog/<hub>` with the last checkpoint seen. A later checkpoint must be signed by that key and extend the last one: a smaller log, another root at the same size or a failed consistency proof fails the fetch, saying the hub showed two histories. An attestation not logged yet, or not proved, is only a note for now, printed by `fetch` and `pull` and in `--json`. A hub that comes back with a new log key (a new key, a reused address, a rename) is a loud note, and the new key is pinned. Older hubs and clients ignore the new fields. |
|
6 |
+ |
|
|
7 |
+ |
- **`oxy tlog verify` audits a hub's whole log (oxygenhub#238).** It accepts the hub's checkpoint by the same rules as fetch, downloads every entry and requires them to make the root the checkpoint signs, then lists this repository's entries, a key's (`--key`) or all of them (`--all`); `--json` too. It also shows which witnesses cosigned and when. |
|
8 |
+ |
|
|
9 |
+ |
- **Trusted time from witnesses (oxygenhub#240).** An entry's integrated time is the earliest time a trusted witness cosigned a checkpoint that holds it, by the witness's clock, so a hub can only make it later, never earlier. A fetch pins the hub's witnesses beside its log key (`<oxy home>/tlog/<hub>.witnesses`; a new or changed witness key is a note), counts a cosignature only when it verifies against a pinned key, and checks a delegate's delegation and a short-lived key's certificate at that time. Without one it checks them as before, at the hub's acceptance or the attestation's own time. A claimed time more than 10 minutes off the integrated time is noted, not refused, for now. The wire change is additive. |
|
10 |
+ |
|
|
11 |
+ |
- **`oxy witness serve`: a witness anyone can run (oxygenhub#238).** `oxy witness serve --name HOST --log ORIGIN=FILE …` serves the C2SP tlog-witness `add-checkpoint` call. It cosigns, with this oxy home's key and its own clock, each checkpoint that verifies with the log's key and extends the last one it cosigned, and refuses a fork. What it cosigned is kept per log in `--state`, so it survives a restart. |
|
12 |
+ |
|
|
13 |
+ |
- **`oxy show --stat` (#119).** Lists the files a change touched instead of its diff: each path with lines added and removed and its kind, renames as from → to, and a total. `--json` gives each file's counts. |
|
14 |
+ |
|
|
15 |
+ |
- **`oxy merge` takes a remote's bookmark (#117).** `oxy merge oxygenhub/develop` said "no bookmark": merge looked only at local bookmarks, so merging what a remote has meant switching to it, pulling and switching back. It now takes a remote's tracking bookmark as last fetched, as revsets do, and says where it looked when neither exists. |
|
16 |
+ |
|
|
17 |
+ |
- **Commit a resolution by paths, and amend only some paths (#118).** A conflict resolution can be committed by paths, leaving other work uncommitted on top of the resolved state, as long as the paths include every file it resolves, whole; otherwise the refusal names them. `oxy amend PATH…` folds only those paths into the head and leaves the rest uncommitted. |
|
18 |
+ |
|
|
19 |
+ |
- **`oxy doctor` checks the trust policy (#127).** A repository with no policy was "Everything looks right" while every fetch warned that nothing was verified. Doctor now has a trust line: no policy is a warning that says who sets one and how; a policy shows its serial, roots, rules and expiry, warns within 30 days of expiry and fails once it has expired. |
|
20 |
+ |
|
|
21 |
+ |
- **The same file added on both sides is one file (#101).** The same path added on two bookmarks with identical content (files, symlinks, or subrepos at the same pin) now merges with no conflict and nothing to resolve. Every peer and the hub show it the same way whatever order the changes came in, and it stays one file through later edits, moves, removals and partial commits. Different content or a different mode is still a name conflict, and directories are not unified. The stored and signed formats are unchanged. |
|
22 |
+ |
|
|
23 |
+ |
- **A bookmark nobody can verify no longer breaks every fetch (oxygenhub#266, oxygenhub#271).** A delegate or short-lived key that moved a bookmark without signing any of its changes left every client failing the whole fetch with "unknown key". A fetch now carries the identities and certificates of the keys that signed every bookmark's latest attestation and every tag's, so clients, older ones included, can verify the move. A client that still cannot verify a bookmark other than the current one leaves that bookmark as it was, warns naming it and why, and fetches the rest. The current bookmark (the one a pull takes or a clone checks out) still fails, as does a missing, unauthorised or rolled-back attestation. The signers are gathered once per operation, not on every fetch call: a repository in a bucket with 145 bookmarks had taken 14 s a fetch. |
|
24 |
+ |
|
|
25 |
+ |
- **Readers never wait for a push or gc (oxygenhub#249).** A repository can now be read safely while another process writes it. A handle reads the operation head once and keeps it, so one request never mixes two views. A read that misses reloads the pack list and tries once more. A repack retires the packs and loose objects it replaces instead of deleting them, and `gc` deletes them only an hour later; `oxy gc` says what it deleted or kept for readers. A forge no longer needs to hold readers back while it pushes or collects garbage. |
|
26 |
+ |
|
|
27 |
+ |
- **A repository kept in a bucket lists its packs less often (#116).** Every open listed the bucket's packs, and a forge opens the store once per request. The pack listing is now kept for 30 seconds and forgotten the moment this process writes or deletes a pack, so its own packs are never hidden; another writer's new pack is seen within 30 seconds. Opening a store no longer sends a request per pack, and a bucket store's stat is a HEAD of the key, not a listing. A server's `/health` counts pack listings, kept listings and other listings apart. |
|
28 |
+ |
|
|
29 |
+ |
- **Text that looks like a conflict marker no longer blocks a resolution (#126).** A file that showed oxy's own conflict markers, such as documentation or a test fixture, could never be committed as resolved ("markers remain"). A file now still has markers only when it holds a marker line oxy wrote for its conflicts. A real marker left behind is still caught. |
|
30 |
+ |
|
|
31 |
+ |
- **A carried switch no longer says carried files were removed (#120).** After a switch that carried the working copy's changes, oxy said new files were "removed from disk" although they were still there. Carried files are now left out of what was removed, and the switch names what it carried. |
|
32 |
+ |
|
| 3 |
33 |
|
## 0.4.6 (2026-10-17) |
| 4 |
34 |
|
|
| 5 |
35 |
|
- **A keyless agent's grant token is its only credential (oxygenhub#241).** A home holding an agent grant token and no hub token now offers the grant to that hub, which accepts it for fetch and push as an agent's token of the owner's account (writing when the grant gives `refs`). The agent pushes its own work, so its seal is its own; it needs no personal access token. |
|
|
… |
214 unchanged lines |