Skip to content

feat(wire-version): release-precision pins + wire validator + namespace#1814

Merged
bokelley merged 2 commits into
mainfrom
bokelley/wire-version-followups
May 17, 2026
Merged

feat(wire-version): release-precision pins + wire validator + namespace#1814
bokelley merged 2 commits into
mainfrom
bokelley/wire-version-followups

Conversation

@bokelley
Copy link
Copy Markdown
Contributor

Summary

Three follow-ups from the expert review of PR #1807. Bundled because they share the wire-version helper surface.

Issue Change
#1 `resolveBundleKey` accepts release-precision pins (`'3.1-beta'`, `'3.1-beta.0'`). `resolveSchemaRoot` fuzzy-resolves to the highest cached prerelease directory whose own release-precision form matches.
#2 `validateAdcpVersionWire(value)` public assertion. Throws with a hint pointing at `toReleasePrecisionWire` on non-spec wire values. Wired as defensive postcondition in `buildVersionEnvelope`.
#3 `wireVersion` namespace groups the three helpers (`isSupported`, `normalize`, `validate`) under one barrel export. Top-level exports kept for back-compat.

Why this matters

#1: AdCP 3.1's `supported_versions` capability advertises versions in release-precision shape (`["3.1-beta"]`). A buyer reading that off the wire and trying to pin to it would hit a `ConfigurationError` before this change. Discovery → pin asymmetry the protocol expert flagged on #1807.

#2: When the seller AJV-rejects an outgoing request with a pattern mismatch on `adcp_version`, the buyer's stack frame is long gone and the spec PR URL is the only clue. A pre-flight assertion that names `toReleasePrecisionWire` in the error message turns this into a one-line fix instead of a debugging session. DX expert's suggestion on #1807.

#3: The barrel had two version helpers; this PR adds a third. The DX expert flagged that three is the right threshold to flip atomically rather than continuing to add top-level exports. The namespace is the recommended path going forward; top-level exports stay for back-compat (no deprecation churn).

Worked example

```ts
import { wireVersion } from '@adcp/sdk';

// Pin to a version a seller advertised on the wire.
const sellerSupports = ['3.0', '3.1-beta'];
const pin = sellerSupports.find(v => wireVersion.isSupported(v)) ?? '3.0';

// Construct a wire-shaped value defensively.
const wire = wireVersion.normalize('3.1.0-beta.0'); // '3.1-beta.0'
wireVersion.validate(wire); // throws on non-spec shape — error names normalize()
```

Test plan

  • 16 new test cases across `test/lib/adcp-wire-version-followups.test.js`.
  • All 47 wire-version tests pass (new + existing four suites).
  • `npm run format:check` clean.
  • `npm run typecheck` clean (pre-push gate).
  • CI green.

Reviewer note

Each change is small enough to skip a full run-by-experts round in my judgement. If you want a full pass anyway, say the word and I'll fire the four reviewers in parallel.

🤖 Generated with Claude Code

bokelley and others added 2 commits May 17, 2026 07:27
Three follow-ups surfaced during the expert review of #1807. Each is
small and additive; bundled because they share the wire-version helper
surface.

Issue #1: resolveBundleKey accepts release-precision pins.
AdCP 3.1's supported_versions capability advertises versions in
release-precision shape (["3.1-beta"]), and a buyer reading that off
the wire must be able to construct a client pinned to it. Before:
new AdcpClient({ adcpVersion: '3.1-beta' }) threw ConfigurationError.
Now: resolveBundleKey accepts MAJOR.MINOR-PRE and returns verbatim;
resolveSchemaRoot fuzzy-resolves to the highest cached prerelease dir
whose own release-precision form matches (so '3.1-beta' finds
schemas/cache/3.1.0-beta.0/, '3.1-beta.0' matches it exactly).

Issue #2: validateAdcpVersionWire public assertion.
Throws ConfigurationError with a hint pointing at toReleasePrecisionWire
when given a non-spec wire value. Use when constructing request
envelopes by hand (storyboard fixtures, conformance harnesses, custom
transports). Also wired as a defensive postcondition in
buildVersionEnvelope so future refactors can't silently emit non-spec
shapes.

Issue #3: wireVersion namespace.
Groups the three helpers (isSupported, normalize, validate) under one
barrel export. Stable target for future additions. Top-level exports
kept for back-compat — not deprecated.

Tests cover all three plus regression checks against the existing
test suites (47 tests pass across the wire-version surface).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
CI failed on the release-precision-pinned-bundle test because it
relied on schemas/cache/3.1.0-beta.0/ existing — that directory is
gitignored and only present in dev workspaces that have synced a
3.1 prerelease cache. CI only syncs the SDK-pinned ADCP_VERSION.

Fix: create a synthetic 98.0.0-test.0/ fixture directory in before(),
exercise the fuzzy lookup against it (a pin of '98.0-test' should
resolve via the release-precision form '98.0-test.0'), and clean up
in after(). The fixture's major version (98) is far outside any
plausible real AdCP cache so a stray leftover can't conflict.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@bokelley bokelley merged commit b7cf5d6 into main May 17, 2026
10 checks passed
@bokelley bokelley deleted the bokelley/wire-version-followups branch May 17, 2026 11:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant