Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 111 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# Changelog

All notable changes to DART are documented here. This project follows
[Semantic Versioning](https://semver.org/); the wire protocol (`Hash64`, the
HRW score formula, `ChunkKey`, and epoch framing) is called out explicitly in
every release's upgrade notes.

## [v0.2.0] — 2026-08-26

The first release since v0.1.0: **30 merged fix PRs** (#23–#44, #47, #48,
#56–#61) plus packaging and discovery additions that landed as direct commits.
No breaking changes; rolling upgrades from v0.1.0 are safe for well-formed
inputs (see Upgrade notes).

### Highlights

- First tag containing the **Helm chart** (`deploy/helm/dart`) and **Fluid**
ThinRuntimeProfile/Dataset samples (`deploy/fluid`).
- First tag containing the **Kubernetes EndpointSlice discovery** module
(`providers/k8s`, a separate Go module keeping the main module
dependency-free) and the `dart-k8s` command.
- The minimalist design assumptions the cache semantics rest on are now
documented in one tracked place (`docs/design-assumptions.md`, #28).

### Additions

Four changes were committed directly (no PR) on 2026-08-13:

- `2a53b2b` — `internal/node` extracted from `cmd/dart`; EndpointSlice
discovery added as the separate `providers/k8s` module with the `dart-k8s`
binary.
- `8e6a6a3` — Helm chart for the DaemonSet shape (discovery.mode=dns|k8s) and
Fluid ThinRuntimeProfile + Dataset samples.
- `b2b7d5b` — engine passes non-range origins straight through, uncached.
- `f21f05d` — tracker evicts idle file entries.

### Fixes

- **engine / fetch data path**: validate relayed block length against geometry
before caching (#23); fail the size probe loudly when a 206 hides the total
(#25); bound the shared flight, cancel-aware joiner retry (#26); six audit
fixes — relay decline, hedge metrics, estimator, reader cache, stream
fallback, empty object (#33); past-EOF blocks error loudly, RFC-clamped tail
206 accepted (#38); reject suffix ranges on empty objects (#56); wait
coalescing joiners inline, one worker goroutine per flight (#60); reject peer
block indices that overflow signed range geometry (#61); redact credentials
from transport errors and the startup banner (#29).
- **peer transport**: stop charging caller cancellation to the circuit
breaker; bound breaker state (#30); hard-bound the breaker map under
failed-address churn (#58); reject invalid `X-DART-Hop` values at both
servers (#57).
- **cluster / membership**: credit liveness to the answering member's ID, not
the dialed address (#24); hearsay liveness, publication races, and
dedup-priority fixes (#35); member-ID alphabet guards the epoch framing;
lifecycle/tracker docs (#44); report invalid roster IDs via OnError; assert
the epoch-collision regression unconditionally (#47).
- **store / metrics**: scope the TinyLFU estimator to borrowed traffic;
class-migration and admission fixes (#34); O(1) MemStore.Len via an atomic
counter and HELP text escaped per the Prometheus text format (#41).
- **node lifecycle**: lifecycle hardening, flag validation, exact byte sizes,
routed+throttled diagnostics (#40); closeable admission gate — the store is
never closed under a live handler (#48).
- **registry mirror**: document the real credential rule for the token realm
(#32); client-credential precedence, digest-classifier alignment, path
encoding, token-cache hygiene (#39); detach the token singleflight from the
leader's context (#59).
- **tracker**: clamp client-supplied lease TTL; guard duration overflow (#27).
- **wire-adjacent hardening**: separator exclusion, fallback query stripping,
score-comment honesty (#36); golden reference implementations committed for
hashring/chunk/cluster, weighted-rank goldens, zero-alloc tree navigation
(#37).
- **docs / posture**: trusted-origin assumption for digest-keyed caching (#31);
the design-assumptions document (#28); `dart_block_fetch_seconds` inclusion
rules (#42); least-privilege RBAC, staleness posture, identity-flags pointer
(#43).

### Upgrade notes

Rolling upgrades from v0.1.0 are safe: all wire-protocol derivations — the
`Hash64` construction, the HRW `score` formula, the `ChunkKey` mix sequence,
and the epoch framing bytes — are **byte-identical** to v0.1.0 for well-formed
inputs. Two derivations changed for edge inputs only:

- Unparseable or scheme-less fallback URLs now cut the query/fragment, and
derived object identities strip a literal 0x1F byte (reachable via a
percent-encoded `%1F` in the path). A mixed-version cluster may split cache
identity for such malformed URLs — extra origin fetches, no correctness
impact (content still comes from the same origin; digest-addressed content
stays verified).
- The duplicate-ID dedup winner in `NewView` now follows the lifecycle rank
Ready > Suspect > Joining > Leaving. This is only reachable when the same
member ID appears with different states in one input — realistically a
duplicated ID in a static `-peers` list.

Peer-facing rejections (`X-DART-Hop` validation, the `MaxBlockIndex` bound)
only affect traffic a v0.1.0 peer never legitimately produces.

No configuration changes are required. The Helm chart bumps `appVersion` to
`v0.2.0`; chart version moves to 0.2.0.

### Verification

At the tagged commit: `go vet ./...` clean; `go test ./... -race -count=1` —
all packages pass; `go test ./... -cover -count=1` — all pass; GitHub Actions
CI green.

## [v0.1.0] — 2026-08-06

Initial tagged release: read-only P2P cache node with weighted-HRW placement,
preorder distribution tree, two-tier block store, registry pull-through
mirror, dependency-free Prometheus exporter, and K8s/DNS discovery wiring.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,8 @@ HTTP-backed mounts are documented in the files' headers.

## Documentation

Release history and upgrade notes live in [`CHANGELOG.md`](./CHANGELOG.md).

[`docs/`](./docs) has a reference document per package — API, semantics,
concurrency contract, test status and known limitations. Start with
[`docs/README.md`](./docs/README.md) for the index, or
Expand Down
8 changes: 5 additions & 3 deletions deploy/helm/dart/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ description: >-
variant, RBAC created automatically).
type: application
# version is the chart version; bump it on every chart change.
version: 0.1.0
# appVersion tracks the DART image tag the chart defaults to.
appVersion: "dev"
version: 0.2.0
# appVersion names the DART release (image tag) this chart version targets;
# the default image.tag stays "dev" (source-build convention) — set it to this
# value when deploying a tagged release.
appVersion: "v0.2.0"
5 changes: 4 additions & 1 deletion deploy/helm/dart/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ image:
# repository is used as-is for discovery.mode=dns and gets a "-k8s" suffix
# appended for discovery.mode=k8s (the Dockerfile's dart-k8s target), so the
# default values below resolve to "dart:dev" and "dart-k8s:dev" respectively.
# Point this at your registry for production (e.g. ghcr.io/acme/dart).
# DART images are not published to any registry: build from source
# (docker build -t dart:<tag> .) or point repository at your own registry.
# For a tagged release build, set tag to the chart's appVersion (e.g.
# v0.2.0) so the deployed image matches what the chart was written for.
repository: dart
tag: dev
pullPolicy: IfNotPresent
Expand Down
Loading