---
milestone: v1.1
audited: 2026-07-26
status: tech_debt
scores:
  requirements: 13/13
  phases: 4/4
  integration: 7/7
  flows: 1/1
gaps:
  requirements: []
  integration: []
  flows: []
tech_debt:
  - phase: 02-discovery-rebroadcast
    items:
      - "RESOLVED 2026-07-26 (quick task 260726-824, commits dca9e39 and 9afe8df): api.discover() awaited create_device() inline, letting consumer time expire the discovery idle window. _discover_with_packet() now re-marks a response once the consumer resumes the generator."
      - "02-01-SUMMARY.md carries no requirements-completed frontmatter; DISC-01 and DISC-02 are evidenced only in 02-VERIFICATION.md (lines 94-95). Cross-reference verified manually for this audit."
  - phase: 04-animation-flow-control
    items:
      - "RESOLVED 2026-07-26 (commit 049902b): 04-VALIDATION.md reconciled by /gsd-validate-phase 4 — 0 gaps, status validated, nyquist_compliant true."
  - phase: milestone
    items:
      - "SEED-001-thread-ipv6-revalidation [dormant]: revalidate wire reliability over Thread/IPv6. Acknowledged and deferred at close."
nyquist:
  compliant_phases: 4
  partial_phases: 0
  not_validated_phases: 0
  missing_phases: 0
  overall: compliant
---

# Milestone Audit: v1.1 — Wire Reliability

**Audited:** 2026-07-26
**Status:** tech_debt — all requirements satisfied, no blocking gaps, deferred items need recording

## Requirements Coverage (3-source cross-reference)

Sources: REQUIREMENTS.md traceability · phase VERIFICATION.md tables · SUMMARY.md
`requirements-completed` frontmatter.

| REQ-ID | Phase | Traceability | VERIFICATION | SUMMARY frontmatter | Final |
|--------|-------|--------------|--------------|---------------------|-------|
| DISC-01 | 02 | `[x]` Complete | ✓ SATISFIED (02-VERIFICATION:94) | absent | satisfied* |
| DISC-02 | 02 | `[x]` Complete | ✓ SATISFIED (02-VERIFICATION:95) | absent | satisfied* |
| DISC-03 | 02 | `[x]` Complete | ✓ SATISFIED (02-VERIFICATION:96) | 02-02 | satisfied |
| RETRY-01 | 03 | `[x]` Complete | passed | 03-01, 03-02, 03-03 | satisfied |
| RETRY-02 | 03 | `[x]` Complete | passed | 03-01, 03-02, 03-03 | satisfied |
| RETRY-03 | 03 | `[x]` Complete | passed | 03-01, 03-02 | satisfied |
| RETRY-04 | 03 | `[x]` Complete | passed | 03-01, 03-02 | satisfied |
| ANIM-01 | 04 | `[x]` Complete | passed | 04-02, 04-04 | satisfied |
| ANIM-02 | 04 | `[x]` Complete | passed | 04-01..04-04 | satisfied |
| ANIM-03 | 04 | `[x]` Complete | passed | 04-13 | satisfied |
| ANIM-04 | 04 | `[x]` Complete | passed | 04-01, 04-03, 04-13 | satisfied |
| DOCS-01 | 05 | `[x]` Complete | passed | 05-05, 05-06 | satisfied |
| DOCS-02 | 05 | `[x]` Complete | passed | 05-05, 05-06 | satisfied |

\* The determination matrix classes "passed + frontmatter missing" as *partial, verify
manually*. Verified manually: 02-VERIFICATION.md carries explicit SATISFIED rows with
evidence for both, and states no orphaned requirements. Recorded as tech debt, not a gap.

**Orphan check:** none. Every REQ-ID in the traceability table appears in a phase
VERIFICATION.md.

## Phase Verification

| Phase | Plans | Status | Score | Unverified | Overrides |
|-------|-------|--------|-------|------------|-----------|
| 02 Discovery Re-broadcast | 2 | passed | 4/4 | 0 | 0 |
| 03 Retry Schedule Reshape | 3 | passed | 5/5 | 0 | 0 |
| 04 Animation Flow Control | 13 | passed | 4/4 | 0 | 0 |
| 05 Reliability Documentation | 6 | passed | 12/12 | 0 | 0 |

25/25 must-have truths verified across the milestone; no phase carries an override.

## Cross-Phase Integration

7 connections verified against source, 0 broken, 1 fragile.

| Connection | Evidence | Status |
|------------|----------|--------|
| Phase 2 re-broadcast vs Phase 3 retransmit | disjoint sockets/packets/sources (`discovery.py:254-291` vs `connection.py:430-669`) — no packet can traverse both schedules, so no double-send | wired |
| Shared utilities | `allocate_source()`/`IdleDeadline` reused from `network/utils.py` by both phases | wired |
| DISC-02 dedup ordering | idle reset precedes the dedup check (`discovery.py:426-431`), so duplicate floods extend the window rather than break it | wired |
| Phase 4 vs connection layer | animation frames leave a private socket (`animator.py:392-418`), never entering the retry engine | wired |
| Ack correlation isolation | probe replies land on the animator's socket and are filtered by its own source ID (`flow.py:149`) | wired |
| ANIM-04 invisibility | consumers discard the gate result (`frame_effect.py:224`); factories unchanged (`conductor.py:682-686`) | wired |
| E2E discover → device → request/retry → animation | every hand-off exists in code (`api.py:783-792` → `discovery.py:92-111` → `base.py:443` → `connection.py:834/880/697/740` → `conductor.py:682-686`) | wired |

Discovery deliberately cannot reuse `_transmit_and_listen`: that engine stops
retransmitting after the first yield (`connection.py:576`), which would defeat DISC-01's
requirement to keep re-broadcasting after early responders answer. The separation is a
design outcome, and both sides carry traceability comments.

### Warning (non-blocking)

`api.discover()` awaits `create_device()` inside the discovery loop (`src/lifx/api.py:792`).
Consumer time counts against the idle window (documented at `discovery.py:190-194`), and
`create_device()` issues Phase 3 requests with a 16 s wall deadline (`const.py:42`) against
a ~4 s idle window. A device that answers `GetService` and then dies can suspend the
generator long enough for `deadline.idle_expired` to fire before queued responses from
later re-broadcasts are read, silently truncating the sweep.

`discover_devices()` itself is sound — the hazard lives only in the convenience wrapper.
Candidate fixes: buffer serials and construct devices after the generator completes, mark
the response after the yield returns, or raise the effective idle multiplier inside
`discover()`.

## Documentation Accuracy (Phase 5)

Spot-checked against source rather than against the plans:

- Re-broadcast timing claims in `troubleshooting.md:105-106`, `advanced-usage.md:281-282`
  and `faq.md:56` match `DISCOVERY_REBROADCAST_GAPS` and the cumulative offsets in
  `discovery.py:172-174`
- Retry claims (`troubleshooting.md:168`, `advanced-usage.md:303`, `overview.md:150`) match
  the wall-deadline design in `connection.py:524-552`
- Flow-control ownership (`overview.md:204-212`) matches `flow.py` being unexported from
  `lifx.animation.__init__`
- Application-level retry examples layer on top of library retransmits rather than
  contradicting them

## Nyquist Coverage

| Phase | VALIDATION.md | status | nyquist_compliant | Classification |
|-------|---------------|--------|-------------------|----------------|
| 02 | exists | validated | true | COMPLIANT |
| 03 | exists | validated | true | COMPLIANT |
| 04 | exists | validated | true | COMPLIANT |
| 05 | exists | validated | true | COMPLIANT |

Phase 04's file was seeded by plan-phase and never reconciled, so it read NOT-VALIDATED at
audit time. `/gsd-validate-phase 4` was run on 2026-07-26 and found 0 gaps: all four Wave 0
artefacts exist and every automated row is green (185 animation tests, 12 emulator-marked).
All four phases are now COMPLIANT.

## Verdict

No unsatisfied requirements, no orphans, no blocking integration gaps, no broken flows.
Status was `tech_debt` on four deferred items at audit time. Two were closed the same day
before the milestone was archived: phase 04's VALIDATION.md was reconciled (commit
`049902b`) and the `api.discover()` idle-window hazard was fixed with regression tests
(quick task 260726-824, commit `dca9e39`). Remaining: the missing 02-01 SUMMARY frontmatter
(cross-checked manually) and the dormant SEED-001, both carried into the close as deferred.
