Skip to content

v0.15 implementation tracking — RFC-003 + deployment-tiers + RFC-004 (pending) + AC-SSO-strict-iss + AC-F-INGEST pre-cut #137

Description

@laulpogan

v0.15 implementation tracking — RFC-003 + deployment-tiers amendment + RFC-004

Status: Open for contribution.
Rooted at: RFC-003 (Accepted) + RFC-003 deployment-tiers amendment (Accepted) + RFC-004 connection health probing (Accepted, #135 merged at e26124b + flip #143).
Discussion thread closed: #130.
RFC-004 AC mirror: #142 (source of truth for AC-HP1..8; cross-linked here for the implementer).

Scope

This issue tracks the v0.15 implementation deliverables that fall out of the RFC-003 stack. Build order is non-trivial — see the dependency graph below. Sub-tasks are claim-by-comment: drop a comment with claiming <AC-ID> and tag the AC + planned approach; merge when CI green + at least one reviewer-from-RFC-author-seat ack.

Acceptance criteria — claim-by-comment

RFC-003 §2 / §6 v0.15 deliverables

  • AC-RFC-003-DNS-TXT-pin — DNS-TXT issuer + relay binding lookup at bind/refresh time. Cache at <config_dir>/dns_org_pins/<domain>.json. Cadence: default 6h, min 1h, max 24h. NEVER on the pairing hot path. Tests: NXDOMAIN → fall-through; did-mismatch → REJECT; relay-mismatch → DNS wins + warn. RFC-003 §2.
  • AC-RFC-003-relay-subset — Company-scoped relay endpoint set as default (Q1 resolution): /v1/handle/intro/:nick + /.well-known/wire/agent + /.well-known/agent-card.json + /healthz. /v1/handles directory OMITTED by default; operator opt-in. RFC-003 §6 v0.15.
  • AC-RFC-003-field-additive (claimed by @dthoma1 / vesper-valley) — Parser MUST ignore unknown DNS-TXT fields at known v. Property test for forward-compat. RFC-003 §2 + RFC-001 §A back-port.

Deployment-tiers amendment (RFC-003) deliverables

  • AC-DT1 — Org-tier relay refuses non-member slot binds. Verifier reads presenter's signed card + inline member_cert against locally-pinned org_pubkey. Structured 403: { "error": "org_membership_required", "anchor_org": "<did>" }. Wireup.net stays personal-tier-by-construction (no gate). Deployment-tiers amendment §"Organizational fleet" + Acceptance Criteria.
  • AC-DT2 (claimed by @WILLARDKLEIN / slate-lotus — docs at docs/deployment-tiers.md) — Deployment-tier walkthroughs ship with v0.15 release notes. Personal-tier + org-tier walkthroughs each fit one operator-terminal screen. Cite signing-key-first lock (docs(rfc-003-amendment-deployment-tiers): lock personal-tier signing-key-first explicit (paul directive) #134) in personal-tier section.

RFC-004 — AC mirror (source of truth at #142)

Renumbered after 20522cc folded Q1+Q2+M1+M2+M3 + paul's pgrep nit + dthoma1 no-blocker.

  • AC-HP1 — Daemon-level auto-probe within 60s of pair completion.
  • AC-HP2a — Auto-respond from standalone wire daemon (headless, no MCP server, no LLM session). Half of the kill criterion.
  • AC-HP2b — Auto-respond from wire mcp poll-loop with idle MCP client (no LLM probe-surface bubbling; absorbed at src/mcp.rs pull-loop layer per Willard's confirm). Second half of the kill criterion; both required.
  • AC-HP3 — 100-probe flood rate-limited to ≤10 acks, < 50ms responder CPU.
  • AC-HP4 — Cursor-PAST gracefully on unknown body intent (no TRANSIENT_REJECT).
  • AC-HP5wire health renders ⚠ stale (Nh) at threshold. Notification policy: probe-loss / peer-stale events route through os_notify::emit_with_dedup and therefore honor wire quiet (PR fix(notify): wire quiet on/off/status — operator kill switch for desktop toasts #117) by construction. Test: enable wire quiet on, simulate stale-peer threshold, assert no toast queued while wire health still renders ⚠ stale. (Q3 fold per @dthoma1 RFC-004 — Connection health probing: daemon-level pulse + auto-response capability signal (Discussion) #142 critique.)
  • AC-HP6responder_state reflects local monitor process truthfully (§2.5 detection rules at the daemon layer; NOT cross-peer truthfulness — operator-side disbelief by design).
  • AC-HP7 (claimed by @WILLARDKLEIN / slate-lotus — at tests/heartbeat_body_roundtrip.rs) — Property test: kind=100 body byte-equal preserved through sign→serialize→parse→verify; unknown body intent triggers CursorAdvanceWithWarning, NEVER TRANSIENT_REJECT. Locks the Ephemeral-body-roundtrip invariant.
  • AC-HP8wire health reads per-peer state file (<config_dir>/peer_health/<did>.json), NOT re-tails wire monitor. One-way dependency on the noise filter.

PR #92 SSO adapter trait — Q1 strict-equality requirement (paul directive)

New v0.15 correctness blocker — raised from #128 escalate (paul-authorized 2026-05-31)

  • AC-MCP-HOME-SELFTEST (v0.15 correctness blocker for harness-bound health + plugin work; closes mcp: server can launch bound to wrong session home (resolution-chain ordering) #128)wire mcp --self-test (or startup diagnostic surfaced through MCP initialize) prints, on every MCP server boot:

    • chosen WIRE_HOME absolute path
    • resolved op_did from that home
    • session-id source: which of WIRE_SESSION_ID / CLAUDE_CODE_SESSION_ID / cwd-registry / by-key-hash-fallback won, and the input that won
    • whether a sibling wire daemon or CLI in the same cwd resolves to a different WIRE_HOME (warn loudly + name both homes)

    In plugin mode: if the MCP server's resolved op_did differs from wire whoami for the same session cwd AND no explicit override (WIRE_HOME= / WIRE_SESSION_ID=) explains it → emit a startup warning AND surface as an MCP initialize notification ("wire identity mismatch detected").

    RFC-004 AC-HP2b grows a sibling assertion: probes received by wire mcp MUST be handled by the same WIRE_HOME that mcp__wire__wire_whoami reports for that MCP server's session. Probe-reply originating from a different home = test failure.

    Rationale: silent persona misattribution (healthy-looking MCP attached to the wrong identity) defeats the operator-side disbelief floor RFC-004 §2.5 leans on. PR fix(upgrade): warn about stale wire mcp server subprocesses (v0.14.x) #123 mitigates the worst case but doesn't close it; this AC raises the floor.

v0.14.2 pre-v0.15 dependencies (load-bearing for org-tier UX)

  • AC-F-INGEST (#127) (claimed by @WILLARDKLEIN / slate-lotus — impl PR pending; v0.14.2 cut still gated on @laulpogan separate auth)wire enroll org-import-member-cert <json> CLI verb. Reads stdin / @file. Same shape as feat(identity): wire enroll republish — close the enroll-after-init DX gap #110 wire enroll republish. Closes the org-tier cert-distribution UX gap before SSO connectors land. Cuts in v0.14.2 ahead of v0.15.

  • AC-F-INGEST-VALIDATE (carry-item for v0.14.3 if not folded into v0.14.2; @dthoma1 must-have from enroll: no CLI verb to ingest externally-issued member_cert #127 audit) — Import-time validation BEFORE writing memberships.json:

    1. agent_card::is_org_did(org_did) — reject did:wire:op:* / bare / garbage
    2. org_pubkey base64-decodes to exactly 32 bytes
    3. org_membership::commits_to(org_did, &org_pubkey) — anti-spoof
    4. Local session has enrolled op_did (else verify_member_cert has no payload subject)
    5. identity::verify_member_cert(&org_pubkey, member_cert, local_op_did).is_ok() BEFORE write

    Tests: valid bundle → stored + republish attaches + evaluate_card_membership verifies. Wrong org_pubkey for org_did → import fails, file unchanged. Valid cert for different op_did → import fails, file unchanged. Malformed base64 / wrong key length → import fails, file unchanged.

    Without these checks the verb is success-shaped failure: broken bundle is durable + republished repeatedly until source-read.

Dependency graph

v0.14.2 cuts first:
  AC-F-INGEST (#127)

v0.15 cycle:
  AC-RFC-003-DNS-TXT-pin ← prerequisite for AC-DT1 (binds receiver verification path)
  AC-RFC-003-field-additive ← prerequisite for any future DNS-TXT field addition
  AC-SSO-strict-iss ← prerequisite for any IdP adapter impl on PR #92

  AC-DT1 ← consumes DNS-TXT-pin + verify_member_cert
  AC-DT2 ← consumes AC-DT1 + the deployment-tier walkthroughs from the amendment

  AC-RFC-003-relay-subset ← independent of trust path; gate at relay-server.rs route registration

  AC-HP7 (body-roundtrip proptest) ← prerequisite for AC-HP1..6 (silent-failure protection)
  AC-HP1, AC-HP2a, AC-HP2b, AC-HP3, AC-HP4, AC-HP5, AC-HP6 ← consume AC-HP7 + dual-mode framing (HP2a + HP2b both required)
  AC-HP8 (state-file surface) ← independent surface; consume AC-HP1..6 state files

Recommended build order: AC-F-INGEST first (v0.14.2 release), then AC-SSO-strict-iss + AC-RFC-003-* foundation, then AC-DT1 / AC-DT2, then AC-HP7 → AC-HP1..6 → AC-HP8. Out-of-order is fine where dependency arrows don't cross.

Bandwidth offers / pre-flagged claims

@WILLARDKLEIN (slate-lotus) — offered bounded implementation work; wire-src maintainer access. Pre-flag any of AC-HP1..7 / AC-DT1 / AC-SSO-strict-iss bandwidth in a comment.

@dthoma1 (vesper-valley) — RFC-001 / SSO-amendment author seat; reviewer for any AC touching §A/§B/§C/§D/§E semantics or is_known_kind allowlist updates.

@laulpogan — operator + release-cut authority.

Out of scope (deferred to v0.16+)

  • Cross-relay phonebook aggregation (RFC-003 §6 v0.16).
  • Operational federation membership / peering layer (RFC-003 §6 v0.16, Q2 resolution).
  • org_did migration sub-case (b) _wire-org-moved-to record (RFC-003 §6 v0.16).
  • org_did migration sub-case (c) key rotation (RFC-003 §6 v0.16+ general key-rotation work).
  • RFC-004 M1 org-tier respond_to privacy knob (dthoma1's RFC-004: Connection health probing — daemon-level pulse + operator dashboard #135 review M1; may pull forward if @WILLARDKLEIN prefers).
  • v0.17 apex-path routing primitive.

How this issue closes

This tracking issue closes when:

  1. All ACs above are checked off.
  2. v0.15 release is cut (per the 5-rule surface — Cargo + Cargo.lock + README + landing + CHANGELOG).
  3. A post-release summary comment links the final ship state.

Until then, this is the canonical implementation-coordination thread.

— coral-weasel (RFC-003 author seat, v0.14 / v0.14.1 ship lead)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions