Skip to content

Phase 3b: Discovery state machine, catalog-ready gate, timeout, fail-closed #62

Description

@itsniper

Parent: #52

Requirements

  • Per-peripheral discovery SM driven by callbacks (FR-10.3.1).
  • Default ready = catalog-ready (FR-10.3.7)—not "all notifies subscribed."
  • Distinct readiness stream/await vs connection state (FR-10.3.2).
  • Configurable discovery timeout (FR-10.3.3).
  • Disconnect mid-discovery = hard reset; invalidate catalog (FR-10.3.4).
  • Missing required UUIDs = fail-closed, report missing (FR-10.3.5).
  • Enforced gate for any characteristic I/O entry points that exist (FR-10.3.6).

Lifecycle interactions (from #51)

  • Discovery suppresses idle. Discovery must hold a work lease (or equivalent demand) for its duration. Without it, a lease released while discovery is in flight starts the 5s idle grace and tears the link down mid-discovery.
  • Timeout vs. idle interval. Document and test the relationship between the discovery timeout and the global idleDisconnectInterval (default 5s). If discovery holds demand, the two are independent; if not, any timeout ≥ the idle interval is unreachable.
  • No discovery without demand. Skip auto-discovery for links with zero demand (Tier-0 grace-window blip, restored link with no hold) — they are about to be cancelled.
  • Awaiting readiness needs a completion signal. acquireWorkLease returns when a connect is issued, not completed; connect failures reach the holder only through the connection-state stream. Build an await-linked primitive (or per-attempt failure delivery) underneath the readiness await so awaitReady can fail promptly on link failure instead of waiting out the timeout.
  • Terminal link failures. .failed(reason: .notFound) published from delegate context retains demand by design. Readiness must surface it as a typed failure rather than hanging until the discovery timeout.
  • Radio invalidation. invalidatePeripherals() (now triggered by .poweredOff as well as resetting/unsupported/unauthorized) must drive the peripheral not-ready and discard discovery bookkeeping, the same as a mid-discovery disconnect.

Acceptance criteria

  • connected never presented as ready
  • Await ready / fail fast behaviors covered by tests
  • Timeout and missing-UUID failures typed and documented
  • Idle teardown cannot interrupt an in-flight discovery
  • Link failure during an in-flight readiness await surfaces promptly, not at timeout
  • Radio power cycle mid-discovery resets discovery state and reports not-ready

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions