Severity: LOW — batch of small CH32V pipeline nits from the 2026-07-21 bench-readiness sweep. One PR, checklist style (same pattern as #1109).
Checklist
- Toolchain download checksums are all
None. crates/fbuild-toolchain/src/toolchain/riscv.rs:235-270 — all four xPack riscv toolchain archives download unverified (sha256: None TODOs). Pin real sha256 values.
- Silent series fallback.
crates/fbuild-build-mcu/src/ch32v/orchestrator.rs:92-94 — an MCU string not starting with ch32 silently falls back to series ch32v003 (and thus the V003 HAL + 16K/2K linker script). Make it a hard ConfigError.
- Dead board-JSON fields.
build.series is never read (orchestrator re-derives from the MCU name; values agree on all 19 boards today — add a validation test or drop the field). Top-level "variant": "ch32v307_evt" (V307) and "variant": "CH32V003" (V003 group) are always overridden by build.arduino.openwch.variant (db.rs:328-335) — remove or align.
- Variant pin-map reuse is undocumented. V208WBU6 →
CH32V20x/CH32V203C8 variant (QFN68 part, LQFP48 pin map), X035C8T6 → CH32X035G8U (QFN28 map), V103C8T6 → CH32V103R8T6 (64-pin map). All forced — upstream ships only those variants at the pinned commit — but LED_BUILTIN/pin constants may not match the physical board. Document in each affected JSON (_comment field) and in docs/BOARD_STATUS.md, so a "dead blink" on bench day is diagnosable in seconds.
- DTR/RTS matrix rows missing.
docs/usb-cdc-control-line-matrix.md has no row for CH32V native USB-CDC (V203/V208/V30x) or the WCH-LinkE CDC. Current behavior for unclassified 1a86 devices: family None → open with DTR=true/RTS=true (safe — WCH CDC has no host-driven reset convention). Add the rows per the boards.rs module-header policy.
- Deploy error-message nits (
crates/fbuild-daemon/src/handlers/operations/deploy.rs:70-81): (a) if firmware.bin is missing the fallback interpolates firmware.elf into the minichlink -w suggestion, which is dubious for minichlink (wlink handles ELF fine); (b) no hint that a WCH-LinkE enumerating as 1a86:8012 (DAP mode) is invisible to wlink until wlink mode-switch — a likely bench stumble.
- Codegen parity note. Vendor/PIO builder passes
-msave-restore -msmall-data-limit=8 -fno-use-cxa-atexit; fbuild uses -msmall-data-limit=0 and omits the others. Not a correctness issue — record the divergence (flash-size deltas vs reference builds) in crates/fbuild-build-mcu/src/ch32v/README.md.
Acceptance
Each item lands with its own test/doc change; bash test -p fbuild-build-mcu -p fbuild-toolchain passes; workspace clippy clean.
Severity: LOW — batch of small CH32V pipeline nits from the 2026-07-21 bench-readiness sweep. One PR, checklist style (same pattern as #1109).
Checklist
None.crates/fbuild-toolchain/src/toolchain/riscv.rs:235-270— all four xPack riscv toolchain archives download unverified (sha256: NoneTODOs). Pin real sha256 values.crates/fbuild-build-mcu/src/ch32v/orchestrator.rs:92-94— an MCU string not starting withch32silently falls back to seriesch32v003(and thus the V003 HAL + 16K/2K linker script). Make it a hardConfigError.build.seriesis never read (orchestrator re-derives from the MCU name; values agree on all 19 boards today — add a validation test or drop the field). Top-level"variant": "ch32v307_evt"(V307) and"variant": "CH32V003"(V003 group) are always overridden bybuild.arduino.openwch.variant(db.rs:328-335) — remove or align.CH32V20x/CH32V203C8variant (QFN68 part, LQFP48 pin map), X035C8T6 →CH32X035G8U(QFN28 map), V103C8T6 →CH32V103R8T6(64-pin map). All forced — upstream ships only those variants at the pinned commit — butLED_BUILTIN/pin constants may not match the physical board. Document in each affected JSON (_commentfield) and indocs/BOARD_STATUS.md, so a "dead blink" on bench day is diagnosable in seconds.docs/usb-cdc-control-line-matrix.mdhas no row for CH32V native USB-CDC (V203/V208/V30x) or the WCH-LinkE CDC. Current behavior for unclassified1a86devices: familyNone→ open with DTR=true/RTS=true (safe — WCH CDC has no host-driven reset convention). Add the rows per the boards.rs module-header policy.crates/fbuild-daemon/src/handlers/operations/deploy.rs:70-81): (a) iffirmware.binis missing the fallback interpolatesfirmware.elfinto theminichlink -wsuggestion, which is dubious for minichlink (wlink handles ELF fine); (b) no hint that a WCH-LinkE enumerating as1a86:8012(DAP mode) is invisible to wlink untilwlink mode-switch— a likely bench stumble.-msave-restore -msmall-data-limit=8 -fno-use-cxa-atexit; fbuild uses-msmall-data-limit=0and omits the others. Not a correctness issue — record the divergence (flash-size deltas vs reference builds) incrates/fbuild-build-mcu/src/ch32v/README.md.Acceptance
Each item lands with its own test/doc change;
bash test -p fbuild-build-mcu -p fbuild-toolchainpasses; workspace clippy clean.