v0.1.0 — first cut

The first release of tutti, a LAN audio renderer probe.

What's in the binary
--------------------
- SSDP M-SEARCH multicast across every up + multicast IPv4 interface,
  with stdlib-only socket handling. mDNS browse over the seven
  audio-relevant DNS-SD service types via grandcat/zeroconf.
- UPnP device descriptor fetch + parse to a canonical struct;
  ConnectionManager:GetProtocolInfo capture with derived
  format-class counts (FLAC/MP3/AAC/Opus/WAV/DSD/...).
- Library decision matrix: every fetched descriptor is run through
  reimplementations of go-upnpcast and huin/goupnp parsers; the
  manifest records each library's verdict with a machine-readable
  reason code.
- AVTransport drive (opt-in via --drive): SetAVTransportURI + Play
  against test tones embedded in the binary, with PLAYING precheck,
  per-tone DIDL-Lite envelope, polled GetTransportInfo +
  GetPositionInfo, parallel Stop emission between runs, and
  metadata-source derivation by comparing the device's echoed
  TrackMetaData against the two metadata surfaces (DIDL-Lite vs
  embedded tags).
- Redaction by construction: RFC1918 LAN addresses, Subsonic auth
  params, Authorization headers all scrubbed at capture time. The
  manifest records every redaction it applied. UDN is preserved on
  purpose (it's the bug-evidence centerpiece).
- Schema v1 (schema/manifest.v1.json), validated by tutti at the
  end of every capture and again by 'tutti validate' on demand.
  Vacuity rules catch captures that pass schema-shape but record
  nothing useful.

Binaries, signatures, attestations
----------------------------------
- Cross-compiled for linux/amd64, linux/arm64, darwin/arm64,
  windows/amd64 (the windows binary appends .exe; both go-build
  and cosign sign the post-rename name correctly thanks to
  dunn.dev/pipeline 2.1.1).
- Per-binary cosign signatures (keyless via GitLab OIDC), per-binary
  .sha256 sidecars, per-binary CycloneDX SBOM, per-binary SLSA v1.0
  provenance attestation. All linked from this release page.
- macOS binary is not yet code-signed; first-run friction is one
  'xattr -d com.apple.quarantine' away. Notarization is on the
  roadmap.

Corpus
------
- evidence/eversolo-dmp-a6/ — first device. Captured against a real
  Eversolo DMP-A6 Master Gen 2 on 2026-05-09. Three findings:
  both Go control-point libraries accept (no parser hazard);
  GetProtocolInfo announces 392 sinks but 0 DSD entries despite
  the device playing DSD natively (the Plutinosoft Sink-list
  pathology); device honors DIDL-Lite metadata, not embedded tags.

Site
----
- tutti.dunn.dev (deployed via Cloudflare Pages on main) carries
  three sections: an educational landing with a streaming-flow
  state diagram and three failure-mode cards; /learn/ — three
  long-form references covering protocols, why-it-goes-wrong, and
  an implementations catalog of 35 entries; /devices/ — the
  rendered corpus.

Acknowledgments
---------------
- alexballas/go2tv and supersonic-app/go-upnpcast for the parser
  patterns reimplemented in tutti's library-decision module.
- huin/goupnp for the second comparison target.
- plutinosoft/Platinum (the SDK on the Eversolo's renderer side)
  for being the very thing tutti exists to profile.
- The narjo-eversolo-upnp Python toolkit, which produced the first
  device capture and motivated tutti's existence.