feat(windows): orchestrate one-shot RP2040 USB recovery through deploy --admin#1156
Conversation
…y --admin Wires the merged #1148 helper foundation and #1147 fail-closed state machine into an end-to-end recovery flow: - fbuild-core: UsbRecoveryOperation::RestartVerifiedParent — a present problematic composite-interface devnode (e.g. the BOOTSEL PICOBOOT function at CM_PROB_FAILED_INSTALL) may only restart its live-verified healthy parent composite, the one action that can remount the stale synthetic BOOTSEL volume; UNCLASSED_DEVICE_CLASS sentinel makes an absent Windows device class an exact-match fact - fbuild-serial: execute_recovery grows the interface->verified-parent arm (identity + VID/PID re-proved live, fail-closed otherwise); the Windows backend tolerates missing Device_Class via the sentinel; UsbProblemDevice now carries parent_instance_id and device_class - fbuild-daemon: on an RP2040 deploy that failed or flashed without a recovered CDC endpoint, compose a typed UsbRecoveryRequest from FRESH scan facts (BOOTSEL problem interface preferred over the phantom runtime CDC record) and attach it to OperationResponse.usb_recovery; the daemon never elevates and never acts on the request itself - fbuild-cli: run_recovery_for_typed_request consumes and validates the helper's nonce-bound result before the rendezvous drops; deploy orchestration launches the helper at most once under explicit interactive --admin, then either retries the deployment exactly once (skip_build, DenyAdmin — no rebuild, no second prompt) when the transfer never succeeded, or rescans for a health-eligible openable endpoint when the flash was already confirmed; Default/--no-admin/CI never elevate Closes #1152 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Warning Review limit reached
Next review available in: 1 minute Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (18)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Closes #1152 (tracked by meta #1149; consumes the merged #1148 helper foundation and the merged #1147 fail-closed state machine, PR #1153).
What changed
The Windows recovery design is now complete in practice: a deploy that detects its exact target as a known-unhealthy devnode produces a typed
UsbRecoveryRequest, and explicit interactive--admindrives the one-shot elevated helper, then resumes deployment on freshly enumerated transports only.fbuild-core
UsbRecoveryOperation::RestartVerifiedParent— the one narrow allowlist extension the issue anticipated: a present problematic USB interface devnode (...&MI_xx\..., e.g. the BOOTSEL PICOBOOT function atCM_PROB_FAILED_INSTALL) may only restart its live-verified healthy parent composite; restarting the interface alone cannot re-initialize sibling interfaces or remount the stale synthetic BOOTSEL volume (the observedERROR_FILE_INVALID1006 case).UNCLASSED_DEVICE_CLASSsentinel: an absent Windows device class (driverless devnode) becomes an exact-match identity fact, never a wildcard.fbuild-serial
execute_recovery: new PresentProblem-interface arm — parent re-inspected live (allow_phantom=false), requiredHealthyPresent, instance-ID matched, VID/PID equal to the child, elseparent-not-live/missing-verified-parentfail-closed. Plain device targets keep the original exact-childRestartTarget.Device_Class(CR_NO_SUCH_VALUE) to the sentinel instead of failing inspection;restart_verified_parentreuses the bounded disable/enable with rollback.UsbProblemDevicegainsparent_instance_id+device_class(Config-Manager-proved facts needed to compose an exact-device request).fbuild-daemon
OperationResponse.usb_recovery: Option<UsbRecoveryRequest>(skip_serializing_if, backward-compatible; CLI mirror usesserde(default)).present_usb_problem_devices()scan and callcompose_rp2040_recovery_request(newrecovery_request.rs): BOOTSEL problem interface (bootloader-UF2 identity,&MI_, proved parent) preferred over the phantom runtime CDC record; records without canonical instance/parent facts are skipped.flash_completeddistinguishes the two flows. The daemon never elevates and never acts on the request.fbuild-cli
run_recovery_for_typed_request— like the mergedlaunch_once_for_typed_requestbut actually consumes the helper's result file before the rendezvous drops, validating the rendezvous nonce and operation ID (a foreign/mismatched result fails closed).run_deployorchestration (maybe_recover_and_retry): on a response carryingusb_recovery—--adminsuggestion + physical BOOTSEL guidance, never elevates;--no-admin→ never prompts; CI/non-interactive/non-Windows → refuse with a note.--admin→ helper launched exactly once (UAC cancel is expected control flow), then:flash_completed == false→ one deploy retry withskip_build = trueandusb_recovery_policy = DenyAdmin(never rebuilds, can never prompt or recover twice);flash_completed == true→ never reflashes; bounded 10 s rescan via freshfbuild-serialenumerations requiring health eligibility + a bounded open probe before any name is reported. No stale COM name or volume handle is ever reused.Deterministic tests
usb_recovery.rs).recovery_request.rs): BOOTSEL interface preferred over phantom CDC; phantom COM12 for serial5303284720C4641Cyields the exact typed request; healthy/unrelated devices compose nothing; records without canonical identity or parent are skipped; parent-serial extraction requires matching VID/PID.--no-adminnever reach the launcher.usb_recoveryabsent in old daemon responses parses (mirrorserde(default)).Validation
Hardware
Not yet touched by this PR — the attached board (serial
5303284720C4641C) remains preserved in the exact reproduced wedge (BOOTSELRPI-RP2onG:, phantomCOM12, PICOBOOT MI_01 problem 28). The fbuild-only hardware closeout (fbuild port scanpre/post,deploy --admin,bash autoresearch rp2040 --rpc-smoke --timeout 120s --skip-linton an isolated five-digitFBUILD_DAEMON_PORT) runs immediately after merge, with evidence posted to #1152/#1147/#1149 per the meta handoff contract.🤖 Generated with Claude Code