Skip to content

fix(rp): reacquire same-name CDC after BOOTSEL deploy #1404

Description

@zackees

Problem

FastLED RP2350W peer-network validation exposed a post-flash handoff bug in released fbuild 2.5.18. The attached Pico 2 W was already in BOOTSEL as H: (RP2350, serial 2DCB876B587EA334) while Windows retained its historical runtime CDC name COM18 as health=phantom, present=no.

The fbuild-owned deploy completed the ROM transfer:

wrote H:\NEW.UF2
deploy succeeded (full flash); FBUILD_DEPLOY_PORT=

but then waited 30 seconds and returned no application port even though its final catalogue showed the matching runtime endpoint:

catalogue candidates: COM18 (serial 2DCB876B587EA334; health healthy; instance USB\VID_2E8A&PID_F00F&MI_00\...)

The failure is deterministic in crates/fbuild-deploy/src/rp2040.rs:

  1. ports_before records every catalogue name before flash, including known-unhealthy phantom/problem records.
  2. An explicit UF2=H:\ selector supplies no runtime serial or previous port.
  3. After flash, select_cdc_candidate correctly filters to healthy endpoints but, lacking an identity hint, accepts only names absent from ports_before.
  4. COM18 changed from phantom to healthy under the same name, so it is never selected or open-probed and DeploymentResult.port remains None.

This violates the delayed healthy CDC acceptance intended by #1147 while preserving #1147's important rule that the pre-flash phantom endpoint itself must never be opened, touched, or returned.

The alternate caller flow is also incomplete: FastLED AutoResearch rejects an explicitly named absent RP COM port before calling fbuild, even when the exact board is mounted in BOOTSEL and fbuild can safely use the unique UF2 volume. This makes the operator/AI translate stale COM state into UF2=<volume> manually.

A separate transient was observed during the same HIL attempt: embedded zccache hit its 300-second per-unit timeout while compiling FastLED (fl.fx+.cpp, then ESP32-C6 HEXBuilder.cpp). That is not part of this selector defect; it is recorded here only so HIL logs are not misread as network-test failures.

Plan

  1. Add a focused RED test proving that a port which was known-unhealthy before flash and returns healthy/openable under the same COM name is eligible for post-flash selection.
  2. Make the RP pre-flash name snapshot health-aware: retain unhealthy records for diagnostics and exact-device recovery, but exclude their names from the set used to decide whether a healthy endpoint is newly available.
  3. Preserve all fix(rp2040): reject phantom CDC ports and give recoverable BOOTSEL guidance #1147 safety invariants: known-unhealthy endpoints remain ineligible for 1200-baud touch, post-flash selection, open probing, and returned deploy ports.
  4. Add regression coverage for both operator-facing deploy strategies:
    • explicit UF2=<mounted BOOTSEL volume> followed by same-name CDC recovery;
    • explicit stale COMx with one unambiguous mounted BOOTSEL volume, where fbuild uses the volume and returns the recovered healthy COM endpoint.
  5. Update the FastLED AutoResearch RP preflight so it delegates this recoverable stale-COM/BOOTSEL state to fbuild rather than failing before deploy. Non-RP explicit absent ports must keep the current fast failure.
  6. Validate with focused fbuild tests, broader deploy checks, FastLED focused tests/lint, then the attached RP2350W + ESP32-C6 canonical peer-network and OTA runs.

Acceptance criteria

  • RED -> GREEN coverage proves phantom COM18 before -> healthy/openable COM18 after returns COM18.
  • A still-phantom or present/problem COM18 is never selected or open-probed.
  • A healthy pre-existing unrelated RP CDC endpoint is not misclassified as newly appeared.
  • Multiple BOOTSEL volumes or multiple newly healthy RP endpoints still fail closed; no guessing.
  • Both UF2=<volume> and stale direct-COM selector flows converge on the same health/openability-gated post-flash port recovery.
  • fbuild emits a non-empty FBUILD_DEPLOY_PORT only after a fresh healthy endpoint passes the bounded open probe.
  • FastLED delegates recoverable RP selection to fbuild while preserving absent-port preflight for non-RP boards.
  • Hardware proof on RP2350W serial 2DCB876B587EA334 records BOOTSEL/runtime transition, returned COM port, and successful RP2350W↔ESP32-C6 network plus OTA assertions.

Coordination

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status
    Triage

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions