Observed live 2026-07-14/15: an agent running on the machine-default identity (did:wire:paul-mac, schema v3.1, no key-commitment suffix) tried to pair + send to a v3.2 peer.
- The receiver correctly rejected the card:
did_commits_to_key (src/agent_card.rs:126) → CardError::DidKeyMismatch. That check is load-bearing (blocks self-signed DID forgery) and is NOT the bug.
- Bug 1 — silent asymmetry. Sender's
wire send returned status:"delivered" (relay verdict) while the receiver's daemon bounced the events at signature verify (rejected_n: 2). The sender gets no signal its identity is unusable; diagnosing took an operator session across two agents.
- Bug 2 — no self-preflight.
wire up, wire whoami, wire dial all operate happily on a legacy identity no v3.2 peer will accept.
- Bug 3 — error text not actionable. "card DID does not commit to its verify key (suffix mismatch)" doesn't distinguish attempted forgery from a legacy v3.1 card, and names no remedy.
Proposed (check stays exactly as strict):
- Self-preflight on every outbound-signing command (dial / send / up / claim): run
did_commits_to_key against our own card; legacy → hard error: "legacy v3.1 identity (no key commitment) — v3.2 peers reject its signatures. Mint a fresh session identity (WIRE_SESSION_ID=<id> wire up). No key-migration path exists by design."
- Receiver-side variant: when an inbound card fails DidKeyMismatch AND its DID has no 8-hex suffix, surface the legacy-specific message in reject logs so the receiving operator can tell the sending operator what to do.
- Optional:
wire doctor / wire status warns when the resolved identity is legacy.
Non-goal: accepting legacy cards at any trust tier (brute-forceable suffix → forgery surface; no-migration confirmed by design in the v0.16 external-validation triage).
Observed live 2026-07-14/15: an agent running on the machine-default identity (
did:wire:paul-mac, schema v3.1, no key-commitment suffix) tried to pair + send to a v3.2 peer.did_commits_to_key(src/agent_card.rs:126) →CardError::DidKeyMismatch. That check is load-bearing (blocks self-signed DID forgery) and is NOT the bug.wire sendreturnedstatus:"delivered"(relay verdict) while the receiver's daemon bounced the events at signature verify (rejected_n: 2). The sender gets no signal its identity is unusable; diagnosing took an operator session across two agents.wire up,wire whoami,wire dialall operate happily on a legacy identity no v3.2 peer will accept.Proposed (check stays exactly as strict):
did_commits_to_keyagainst our own card; legacy → hard error: "legacy v3.1 identity (no key commitment) — v3.2 peers reject its signatures. Mint a fresh session identity (WIRE_SESSION_ID=<id> wire up). No key-migration path exists by design."wire doctor/wire statuswarns when the resolved identity is legacy.Non-goal: accepting legacy cards at any trust tier (brute-forceable suffix → forgery surface; no-migration confirmed by design in the v0.16 external-validation triage).