did-btcr2-js

ADR 010: did:btcr2 v0.2 Spec Alignment and Spec-Tracking Policy

Status: Accepted

Date: 2026-02-13

Commits: 5578915, fd33387, 2f56b5c

Context

The did:btcr2 specification is developed in the open at DCDPR and versioned. The reference implementation (this repo) exists to track that spec as closely as the test suite and codebase can afford to. Between August 2025 and February 2026 the spec moved from v0.1 to v0.2, touching:

This wasn’t a small diff. Three commits spanning ~3 weeks landed the v0.2 alignment: 5578915 / fd33387 (2026-01-21) for terminology and initial renames, 2f56b5c (2026-02-13) for the beacon and update architectural changes.

The larger question this work surfaced: and the reason it deserves an ADR rather than just a PR description: is what the project’s stance is toward spec revisions. Two answers were possible.

Options considered

  1. Track the latest spec version unconditionally, accepting breaking changes as they come. The reference implementation stays canonical. Consumers pin to specific library versions to stay on older spec versions if they must. The library never pretends to implement both v0.1 and v0.2 simultaneously.
  2. Support multiple spec versions simultaneously behind a configuration flag or a discriminator. The library exposes both v0.1 and v0.2 code paths; callers pick. This matches what some other DID-method reference implementations do, and smooths the adoption curve for downstream consumers.

Decision

Option 1. The implementation tracks the current spec. When the spec makes a breaking change, the library makes a breaking release. There is no dual-path support for older spec versions, no “compatibility mode” flag, no feature gating.

The v0.2 migration is the first exercise of this policy. Concretely:

Terminology (BREAKING, across multiple packages):

Beacon architectural change: The v0.1 AggregateBeacon base class held mutable state: signals, sidecar, bitcoin client: on the instance. The v0.2 Beacon base class holds only the beacon’s service. Signals, sidecar, and any transport are passed in as method parameters. BeaconFactory.establish(service) returns a Beacon typed by the service’s beacon type; callers then invoke beacon.processSignals(signals, sidecar, ...) with data they already have. This change is what makes the later sans-I/O refactor possible: stateless beacons are a prerequisite for the state-machine design in ADR 016 and ADR 025.

Related concrete fixes that came along:

Update flow:

Spec links: Every @see https://dcdpr.github.io/did-btcr2/algorithms.html#... link updated from the v0.1 §4.x anchors to v0.2 §7.x anchors.

Version bumps: api 0.1.1 to 0.2.0, cli 0.2.0 to 0.3.0, common 3.1.0, cryptosuite 4.0.0 to 5.0.0, keypair 0.8.0 to 0.9.0, kms 0.1.1 to 0.2.0, method 0.19.0 to 0.20.0. Coordinated breaking release across the graph.

Consequences

Positive

Negative

Explicitly accepted trade-offs

References