| … | … | @@ -6,6 +6,83 @@ documented here. Dates in YYYY-MM-DD. |
| 6 | 6 | |
| 7 | 7 | The packages are versioned in lockstep. |
| 8 | 8 | |
| 9 | ## [0.25.0-rc.5] — 2026-07-28 | |
| 10 | ||
| 11 | **Preferred canary prerelease.** Supersedes rc.4. Restores a set of features that | |
| 12 | convergence refactors had orphaned — the code was gone but the tests, docs, and | |
| 13 | capability claims still described it — and fixes three defects that were live on | |
| 14 | the public read plane. | |
| 15 | ||
| 16 | ### Fixed — public read plane | |
| 17 | - **Every non-HEAD file GET returned 502.** `HyperGateway.handle()` dereferenced | |
| 18 | the optional exact-app `context` without a null guard, and `gateway-server` | |
| 19 | serves the `/v1/hyper/:key/...` route with no context. Any request for drive | |
| 20 | content threw before headers were sent. | |
| 21 | - **The per-window egress byte budget was silently unenforced** on exact | |
| 22 | app-origin responses. The gateway's storage-lease wrapper re-entered | |
| 23 | `handle(req, res)` without forwarding `context`, dropping | |
| 24 | `reserveResponseBytes` along with the `X-Hive-App-Key` / `X-Hive-Byte-Mode` | |
| 25 | headers. | |
| 26 | ||
| 27 | ### Fixed — storage durability | |
| 28 | - **A seed reported success when its durable registry write failed.** | |
| 29 | `AppRegistry.set()` persists fire-and-forget, so the drive served traffic and | |
| 30 | then was simply absent after restart. The seed path now persists explicitly, | |
| 31 | awaits it, and restores the pre-seed entry on failure. | |
| 32 | - **Durable retirement could begin while an HTTP response was still streaming** | |
| 33 | from pinned core sessions. `unseedApp` now takes the same per-drive storage | |
| 34 | lease HyperGateway holds for reads. It bypasses the lease once the authority | |
| 35 | stops accepting mutations, because `stop()` retires every drive after that | |
| 36 | point and must still be able to close its own drives. | |
| 37 | - **A concurrent shutdown and forget retired the same drive twice** — closing the | |
| 38 | drive, persisting the delete, and releasing the storage commitment two times. | |
| 39 | Both callers now share one coalesced retirement owner. | |
| 40 | - **Mixed-case app keys bypassed the live-entry check**, seeding a duplicate | |
| 41 | drive for the same content under a different storage-admission mutation key. | |
| 42 | - **Manifest indexing read from the live drive**, so indexed metadata did not | |
| 43 | have to match the proven version. It now reads `{ wait: false }` from a | |
| 44 | checkout pinned to the storage proof, with fork/length stability checks, and | |
| 45 | always closes the checkout. This also removes a timed-out manifest read that | |
| 46 | left an in-flight network request alive after its caller had given up. | |
| 47 | ||
| 48 | ### Restored (orphaned by convergence refactors) | |
| 49 | - **Seed-admission queue.** The old spin-wait mutex could not cancel: a caller | |
| 50 | that timed out, or a node shutting down, still had its queued closure run | |
| 51 | later against the registry and storage ledger. Queued work is now cancellable; | |
| 52 | work that has already started runs to completion. | |
| 53 | - **`getDriveSize` authoritative-proof mode** (`requireAuthoritative`, | |
| 54 | `pinSnapshots`). `length` and `byteLength` are separate getters, so an append | |
| 55 | between them produced a tuple that never existed and under-counted the drive. | |
| 56 | They are now read as one bracketed tuple, and pinned snapshots reject | |
| 57 | `DRIVE_VERSION_CHANGED_DURING_PROOF`. | |
| 58 | - **Ordered auxiliary share-bundle teardown**, which had no production caller at | |
| 59 | all — snapshot sessions and download trackers leaked on every PVSS | |
| 60 | share-bundle read. | |
| 61 | - **Exact drive-discovery teardown and download-snapshot-core release** during | |
| 62 | drive retirement, with per-owner retry on failure. | |
| 63 | - **`hiverelay-forward` transport advertisement.** The client path resolver gates | |
| 64 | on `supported_transports`, which never contained it, so the shipped | |
| 65 | source-ip-hidden / hidden-1hop privacy tier was unreachable end to end. | |
| 66 | ||
| 67 | ### Fail-closed hardening | |
| 68 | - Seed and repair now stop before Corestore session, Hyperdrive adoption, or | |
| 69 | storage reservation when the physical authority cannot accept durable writes, | |
| 70 | instead of failing later with a reservation error that masked the cause. | |
| 71 | - Seeding before recovery inventories seal reports | |
| 72 | `STORAGE_RECOVERY_INVENTORY_PENDING`. | |
| 73 | ||
| 74 | ### Tests | |
| 75 | - The unit suite previously aborted at test 727 on a hard `TypeError` in the | |
| 76 | app-lifecycle teardown path, leaving most of the 327 files unexecuted. It now | |
| 77 | runs 3510 tests with 3 known failures (serve-only recovery mode, and two | |
| 78 | startup-rollback cases blocked on the Corestore-7 storage-sweep question). | |
| 79 | ||
| 80 | ### Fleet | |
| 81 | - Canary target: `v0.25.0-rc.5`. Stable remains `v0.24.3`. | |
| 82 | - `sydney` and `dallas` are held off this rollout (Track B blind public-test | |
| 83 | hosts). `dallas` has no updater installed and is excluded by construction; | |
| 84 | `sydney` must be pinned explicitly before any `stable` bump. | |
| 85 | ||
| 9 | 86 | ## [0.25.0-rc.4] — 2026-07-26 |
| 10 | 87 | |
| 11 | 88 | **Preferred canary prerelease.** Do not deploy rc.1–rc.3. |
| … | … | @@ -14,7 +14,7 @@ and key-material fields at the schema boundary. |
| 14 | 14 | a one-page dashboard, first-run setup, wallet destination, service selection, |
| 15 | 15 | and persistent identity behind each platform's authenticated app proxy. |
| 16 | 16 | |
| 17 | **Open source (Apache 2.0)** | **[GitHub](https://github.com/bigdestiny2/P2P-Hiverelay)** | **[npm](https://www.npmjs.com/package/p2p-hiverelay)** | **Status: v0.25.0-rc.4** | |
| 17 | **Open source (Apache 2.0)** | **[GitHub](https://github.com/bigdestiny2/P2P-Hiverelay)** | **[npm](https://www.npmjs.com/package/p2p-hiverelay)** | **Status: v0.25.0-rc.5** | |
| 18 | 18 | |
| 19 | 19 | The four packages are versioned in lockstep: |
| 20 | 20 |
| … | … | @@ -1,12 +1,12 @@ |
| 1 | 1 | { |
| 2 | 2 | "name": "p2p-hiverelay-monorepo", |
| 3 | "version": "0.25.0-rc.4", | |
| 3 | "version": "0.25.0-rc.5", | |
| 4 | 4 | "lockfileVersion": 3, |
| 5 | 5 | "requires": true, |
| 6 | 6 | "packages": { |
| 7 | 7 | "": { |
| 8 | 8 | "name": "p2p-hiverelay-monorepo", |
| 9 | "version": "0.25.0-rc.4", | |
| 9 | "version": "0.25.0-rc.5", | |
| 10 | 10 | "hasInstallScript": true, |
| 11 | 11 | "license": "Apache-2.0", |
| 12 | 12 | "workspaces": [ |
| … | … | @@ -8204,7 +8204,7 @@ |
| 8204 | 8204 | }, |
| 8205 | 8205 | "packages/client": { |
| 8206 | 8206 | "name": "p2p-hiverelay-client", |
| 8207 | "version": "0.25.0-rc.4", | |
| 8207 | "version": "0.25.0-rc.5", | |
| 8208 | 8208 | "license": "Apache-2.0", |
| 8209 | 8209 | "dependencies": { |
| 8210 | 8210 | "@noble/hashes": "^2.2.0", |
| … | … | @@ -8257,7 +8257,7 @@ |
| 8257 | 8257 | }, |
| 8258 | 8258 | "packages/core": { |
| 8259 | 8259 | "name": "p2p-hiverelay", |
| 8260 | "version": "0.25.0-rc.4", | |
| 8260 | "version": "0.25.0-rc.5", | |
| 8261 | 8261 | "license": "Apache-2.0", |
| 8262 | 8262 | "dependencies": { |
| 8263 | 8263 | "@grpc/grpc-js": "^1.14.4", |
| … | … | @@ -8333,7 +8333,7 @@ |
| 8333 | 8333 | }, |
| 8334 | 8334 | "packages/services": { |
| 8335 | 8335 | "name": "p2p-hiveservices", |
| 8336 | "version": "0.25.0-rc.4", | |
| 8336 | "version": "0.25.0-rc.5", | |
| 8337 | 8337 | "license": "Apache-2.0", |
| 8338 | 8338 | "dependencies": { |
| 8339 | 8339 | "@noble/curves": "^2.2.0", |
| … | … | @@ -8380,7 +8380,7 @@ |
| 8380 | 8380 | }, |
| 8381 | 8381 | "packages/verifier": { |
| 8382 | 8382 | "name": "p2p-hiverelay-verifier", |
| 8383 | "version": "0.25.0-rc.4", | |
| 8383 | "version": "0.25.0-rc.5", | |
| 8384 | 8384 | "license": "Apache-2.0", |
| 8385 | 8385 | "dependencies": { |
| 8386 | 8386 | "b4a": "^1.8.1" |
| … | … | @@ -1,6 +1,6 @@ |
| 1 | 1 | { |
| 2 | 2 | "name": "p2p-hiverelay-monorepo", |
| 3 | "version": "0.25.0-rc.4", | |
| 3 | "version": "0.25.0-rc.5", | |
| 4 | 4 | "description": "Monorepo root for HiveRelay (Core + Services + Client)", |
| 5 | 5 | "private": true, |
| 6 | 6 | "type": "module", |
| … | … | @@ -51,6 +51,9 @@ |
| 51 | 51 | "release:check-image-manifest": "node scripts/check-release-image-manifest.mjs", |
| 52 | 52 | "release:smoke-image": "node scripts/smoke-release-image.mjs", |
| 53 | 53 | "fleet:check-rollout": "node scripts/check-fleet-rollout.mjs", |
| 54 | "dashboard:admin-operator": "node dashboard-admin-operator/server.cjs", | |
| 55 | "dashboard:admin-operator:dev": "PORT=3458 FLEET_INTERVAL=30 node dashboard-admin-operator/server.cjs", | |
| 56 | "fleet:control": "node dashboard-admin-operator/server.cjs", | |
| 54 | 57 | "umbrel:check-gallery": "node scripts/check-umbrel-gallery.mjs", |
| 55 | 58 | "umbrel:export-official": "node scripts/export-official-umbrel-app.mjs", |
| 56 | 59 | "umbrel:write-runtime-review": "node scripts/write-umbrel-runtime-review-evidence.mjs", |
| … | … | @@ -1,6 +1,6 @@ |
| 1 | 1 | { |
| 2 | 2 | "name": "p2p-hiverelay-client", |
| 3 | "version": "0.25.0-rc.4", | |
| 3 | "version": "0.25.0-rc.5", | |
| 4 | 4 | "description": "Unified client SDK for HiveRelay (Core + Services). Talks to either via capability flags advertised by relay nodes.", |
| 5 | 5 | "type": "module", |
| 6 | 6 | "main": "index.js", |
| … | … | @@ -61,7 +61,7 @@ |
| 61 | 61 | "corestore": "^7.11.0", |
| 62 | 62 | "hyperdrive": "^13.3.2", |
| 63 | 63 | "hyperswarm": "^4.17.0", |
| 64 | "p2p-hiverelay": "^0.25.0-rc.4", | |
| 64 | "p2p-hiverelay": "^0.25.0-rc.5", | |
| 65 | 65 | "sodium-universal": "^5.0.1" |
| 66 | 66 | }, |
| 67 | 67 | "engines": { |
| … | … | @@ -1,6 +1,6 @@ |
| 1 | 1 | { |
| 2 | 2 | "name": "p2p-hiverelay", |
| 3 | "version": "0.25.0-rc.4", | |
| 3 | "version": "0.25.0-rc.5", | |
| 4 | 4 | "description": "HiveRelay Core — minimal always-on P2P availability infrastructure (seeding, circuit relay, proof-of-relay, gateway)", |
| 5 | 5 | "type": "module", |
| 6 | 6 | "main": "core/index.js", |
| … | … | @@ -1,6 +1,6 @@ |
| 1 | 1 | { |
| 2 | 2 | "name": "p2p-hiveservices", |
| 3 | "version": "0.25.0-rc.4", | |
| 3 | "version": "0.25.0-rc.5", | |
| 4 | 4 | "description": "HiveRelay Services — application-layer services (AI inference, identity, schemas, SLAs, storage CRUD) that ride on top of HiveRelay Core", |
| 5 | 5 | "type": "module", |
| 6 | 6 | "exports": { |
| … | … | @@ -20,7 +20,7 @@ |
| 20 | 20 | "@noble/hashes": "^2.2.0", |
| 21 | 21 | "@noble/secp256k1": "^3.1.0", |
| 22 | 22 | "b4a": "^1.8.1", |
| 23 | "p2p-hiverelay": "^0.25.0-rc.4", | |
| 23 | "p2p-hiverelay": "^0.25.0-rc.5", | |
| 24 | 24 | "sodium-universal": "^5.0.1" |
| 25 | 25 | }, |
| 26 | 26 | "engines": { |
| … | … | @@ -1,6 +1,6 @@ |
| 1 | 1 | { |
| 2 | 2 | "name": "p2p-hiverelay-verifier", |
| 3 | "version": "0.25.0-rc.4", | |
| 3 | "version": "0.25.0-rc.5", | |
| 4 | 4 | "description": "Independent reference verifier for HiveRelay — reads raw hypercores from multiple relays and reports divergence. Ships separately from the main client SDK so cross-client verification is meaningful (see docs/THREAT-MODEL.md action item #3).", |
| 5 | 5 | "type": "module", |
| 6 | 6 | "main": "index.js", |
| … | … | @@ -167,7 +167,7 @@ Three paths, smallest to widest reach: |
| 167 | 167 | ## Status |
| 168 | 168 | |
| 169 | 169 | Package source targets multi-arch image tarballs (x86_64 + aarch64), |
| 170 | v0.25.0-rc.4, one-page dashboard via `HIVERELAY_UI_SIMPLE`, review-mode first boot, | |
| 170 | v0.25.0-rc.5, one-page dashboard via `HIVERELAY_UI_SIMPLE`, review-mode first boot, | |
| 171 | 171 | and a first-boot-only 10 GB storage cap. Current `v0.20.2` package verification |
| 172 | 172 | is externally gated on the published GHCR image/tag and digest; once that image |
| 173 | 173 | exists, `make verify IMAGE_DIGEST=sha256:<multi-arch-digest>` is the release |