Commit Graph

376 Commits

Author SHA1 Message Date
60ab45841c docs: record F9 as dropped by decision
The sudoers grants and the wildcarded tee removal are out of this PR: the rig
account is expected to have passwordless sudo, so nothing in that file gates
anything there. Records what would need doing if the template is ever pointed
at a host without blanket sudo.
2026-08-19 10:48:53 +07:00
1956769a7c docs: correct the F4 row now that the change is reverted 2026-08-19 10:48:53 +07:00
14d8567b64 docs: record F1 and F4 as attempted, reverted and still open
Both fixes shipped in the first remediation pass and both were wrong. F1's
re-arm demotes the board permanently on any unplug because the ladder advances
on a timer with nothing attached; F4's reordering performs the very write-0 on
RB_UEP_R_DONE that set_rx_res() forces a 1 to avoid. Each entry records what a
correct fix would need.
2026-08-19 10:48:53 +07:00
58622807b0 docs: record F3 as refuted-by-hardware and still open
Case 29 passes with the clear-stall re-arm and fails without it on the CH569,
measured alone on a freshly flashed board. The review's reasoning about usbd's
ownership rules holds, but the fix built on it does not: the halt/clear-halt
path expects the endpoint to resume. The underlying interface conflict is
recorded with what fixing it would actually require.
2026-08-19 10:48:53 +07:00
0775d836b9 docs: defer the two non-regression fixes with their plan
F11 (MSC discarding the usbd_defer_func result) and F15 (-w appended rather
than assigned, changing BSP codegen for ~19 families) are confirmed but are not
regressions from this branch, so they stay out of #3779 and keep it reviewable
as a SuperSpeed PR. Both now carry enough detail in the todo to be picked up
without re-deriving them, and Phase D of the plan has the steps.

Also restates the two tap-blocked items: F4 and F16 are implemented and built,
not merely pending.
2026-08-19 10:48:53 +07:00
ab3a4aa8a1 wch: give the CH569 fallback ladder a single state owner
_fb_state, the TMR0 interrupt mask and the timer registers are one logical
state that was mutated independently at six sites, which produced four distinct
defects. fallback_enter() now owns all three and is the only writer.

Two of them become unreachable. fallback_timer_start() re-enables the vector
its stop() masked, so a tud_disconnect()/tud_connect() cycle can no longer
leave the ladder counting behind a masked interrupt whose latched expiry the
shared ISR then consumes in place of a real USBSS/LINK event. And the
partner-disappeared branch re-arms training, so a board that trained SuperSpeed
once is no longer dead until a power cycle after a replug into a USB2-only host
- FB_USB3_UP was terminal, and usbd calls neither dcd_init nor dcd_connect on
link loss.

The deferred re-init now re-checks the fallback state after its 30 ms settle
rather than trusting a check made before it: the training-exhausted branch runs
from the TMR0 ISR without consulting _hw_reinit_deferred and can land anywhere
in that window.

The warm-reset branch gains the ep_state_reset()/dcd_event_bus_reset() pair it
omitted - a warm reset returns the device to Default state exactly as the hot
reset the branch below has always reported. Its ~30 ms in-ISR settle is left
alone and recorded as follow-up: usb30_bus_reset_from_isr() deinits
synchronously and defers only settle+init, so simply deferring here would leave
the address-0 write and the TX_WARM_RST handshake driving a torn-down
controller.
2026-08-19 10:48:53 +07:00
6bb50f55fe docs: scope the plan's pytest runs to test_*.py
Collecting all of test/hil/ also picks up hil_test.py's 24 HIL case handlers,
which are named test_* but are not pytest tests. That noise is pre-existing and
identical on master; the plan should not tell an implementer to expect it green.
2026-08-19 10:48:53 +07:00
fbec844539 docs: drop a plan line reference invalidated by the try/finally fix 2026-08-19 10:48:53 +07:00
b123b56ef3 hil: do not leak the capture process when a drop-rate run fails
A failed flash (CalledProcessError, TimeoutExpired) or a missed re-enumeration
propagated out of one_run() before usb_sniffer was terminated, leaving an
orphaned capture holding the pcap open. It writes ~20 MB/s on a busy HS bus, so
a leak fills the disk while the harness moves on. The body is now wrapped in
try/finally.

Also renames the deferred-work list to name the PR it belongs to: one file per
PR under docs/superpowers/todo/.
2026-08-19 10:48:53 +07:00
23ff352f60 docs: implementation plan for the review-findings remediation
Fourteen tasks across four phases: the instrumentation fixes first, since three
of them are the instruments used to judge the rest; then the CH569 fallback
ladder behind a single state owner; then the correctness fixes; then the two
non-regressions on their own branches off master; then verification.

Records one deliberate deviation from the design: a quirk-skipped usbtest run
keeps the pass icon and gains an honest denominator rather than a new icon,
because hil_test.py classifies report cells by that prefix.
2026-08-19 10:48:53 +07:00
8201ed5f78 docs: design for remediating the 16 review findings
All 16 findings from the maximum-effort review were re-validated against the
code and all hold. The design groups them by what they cost rather than by the
review's severity ranking, because three of the cheapest are the instruments
used to judge the rest: a usbtest run that renders skipped cases as a green
full pass, a drop-rate parser that miscounts, and a quirk that never fires in
the configuration it was written for.

Classes A, B and C land in this PR; the two findings that are not regressions
from this branch go to separate PRs off master. The CH569 fallback ladder gets
a state-transition helper rather than four point fixes, since its four defects
are one root cause. Work that cannot be measured without the USB2 tap is
recorded as deferred rather than claimed as validated.
2026-08-19 10:48:53 +07:00
21329ca33c docs: CH32H417 high-speed SETUP-drop investigation
Design, plan and findings for the attempt to reach usbtest 30/30 on the
CH32H417 USB2 high-speed fallback. The outcome is a hardware limitation: the
USBHS block has no equivalent of the CH569's RB_USB_INT_BUSY, so a SETUP
arriving while a transfer completion is unserviced gets no handshake at all,
and a SETUP may not be NAKed or STALLed. Also records that high speed only
enumerates on this board with a USB2 tap inline, since PB8/PB9 are both the
USB2 pair and the only SWD/SDI pins.
2026-08-19 10:48:53 +07:00
b47dfb65e2 bsp: register WCH boards in build metadata and docs 2026-08-19 10:48:53 +07:00
19ff2ed615 examples: document and work around the i.MX RT and LPC55 USB errata
ERR050101: while an isochronous IN endpoint is active, an IN token addressed to
that same endpoint number on ANOTHER device sharing the host can silently
unprime one of this device's OUT endpoints - control, bulk, interrupt or
isochronous alike. NXP states it cannot be detected by software and raises no
interrupt, so the endpoint simply stops answering and the transfer never
completes.

The workaround is a uniqueness requirement rather than a particular number: the
isochronous IN endpoint must not share its number with any IN endpoint in use on
the bus. One family-wide constant therefore defeats it, since two affected
boards on the same hub then pick the same number and each becomes the other's
aggressor. CFG_TUSB_MIMXRT1XXX_ERRATA_ERR050101 is set only for the parts whose
errata list it - RT1015, RT1020, RT1024 and RT1050, where it is marked no fix
scheduled, plus RT1060 and RT1064 rev A - so RT1010 and the RT11xx family keep
the ordinary number and cannot collide with an affected board beside them.
Several affected boards on one hub can still be given distinct numbers with
-DEPNUM_ISO_IN.

The guard covers every example that has an isochronous IN endpoint: audio_test,
audio_4_channel_mic, uac2_headset, cdc_uac2, usbtest, video_capture and
video_capture_2ch. The video examples move the endpoint only when streaming
isochronously, since the bulk configuration is unaffected, and video_capture_2ch
takes two numbers because it has two streams.

The macro name follows CFG_TUSB_RP2_ERRATA_E2/E4/E15 already in tree, and its
is fixed, and which cannot be told apart at compile time - a way to define it to
0.

device_issues.rst records ERR050101 against every affected part with a link to
each errata sheet, and adds the LPC55S2x USB.3 speed-detection and USB.5
isochronous IN entries, neither of which TinyUSB works around. The branch's
design notes are included under docs/superpowers.

Verified: 340 wedge-free runs on mimxrt1064_evk, which previously wedged within
hours, and the macro resolving to endpoint 0x87 on mimxrt1064_evk against 0x83
on mimxrt1010_evk and stm32f407disco.
2026-08-18 22:07:49 +07:00
c7290c4d31 docs: hand off follow-up work as per-PR plans
Records the convention in CLAUDE.md -- deferred work is a SEPARATE scope that deserves
its own PR, written by another session, so it is handed off as a writing-plans doc in
docs/superpowers/followup/pr<NNN>-<topic>.md rather than accumulated in the PR that
found it.

Five handoffs from #3803: flasher_recover (convoy-safe recovery for J-Link boards, seven
validated on the rig), the blindness reporting gaps, the usbtest recovery reserve, the
IAR re-run spec, and the pci-rebind stranding question. Each carries what is already
established with its citations and measurements, what remains, and why it was split out.

One doc per follow-up, not one per PR: a per-PR file invites unrelated work into the
same document and rots as a unit.
2026-08-18 12:19:09 +07:00
f822f69a98 skills, docs: rewrite USB recovery from the live incidents
Two things the rig taught us that the old guidance got wrong.

A usbfs ioctl wedged in D state cannot be freed on a running kernel. It holds
the device lock, so usb_disconnect() blocks behind it; reboot(2) walks
device_shutdown() and takes the same lock, so every userspace reboot stalls too.
Only sysrq b (emergency_restart, which skips device_shutdown) or hypervisor
action clears it -- all cited to the kernel source. The recovery ladder is
generic across rigs now (ci.lan, hifiphile, a bench PC) and ends at hypervisor
escalation only where host access exists. Two claims are corrected outright:
JLinkExe is NOT convoy-safe, and a park-flash cannot free a device-lock owner.

The hil skill's banner list is what an operator agent matches a report against,
so it enumerates the banners that actually exist, including the D-state note --
which is explicitly NOT a wedge, since a healthy in-flight testusb is
uninterruptible for most of every case and a concurrent CI battery would
otherwise turn a clean run red.
2026-08-18 12:19:09 +07:00
3963a1b70a test/hil, ci: contain a wedged USB stack instead of stranding the runner
A wedged USB device used to take the whole HIL run with it. Every worker that
touched the poisoned node blocked uninterruptibly, the pool could not be joined,
map_async discarded every board's result, and the job ran to the GitHub ceiling
with no report at all -- while the self-hosted runner's single job slot stayed
occupied and every queued job waited behind it.

Bound the calls a worker makes itself. read_sysfs, bounded_open and run_cmd all
answer within a wall clock; read_sysfs distinguishes "absent" from "unknown",
because a blocked read is not evidence of absence, and caps stranded readers at
four (each costs a thread and an fd for the life of the process) after which the
worker declares itself blind. mtype, the gio unmount, the libmtp session and the
arecord/iperf reaps go through those bounds; the MTP session runs in a disposable
subprocess, since libmtp's ctypes calls block unkillably in D state.

Bound the run. A pool guard (HIL_POOL_TIMEOUT, 60 min) fires before any job
ceiling and still writes a report. When the pool will not shut down, the sweep
kills what the workers spawned -- descendants, not just direct children, since
flashers run in their own session -- confirms each kill actually landed, and
exits early so the runner is freed. Whatever survived is named in the report.

Deliberately shallow past that point. We do not re-scan process groups, prove
pid ownership, or escalate through sudo: a root-owned survivor is reported, not
force-killed, because signalling a pid we cannot prove is ours is the worse
failure, and the job ceiling backstops whatever this misses. A D-state holder
was never killable anyway.

Recover instead of reporting a wedge. A HUNG usbtest case reflashes its own DUT
through its roster flasher, but only where the flasher can reach its probe past
a poisoned node -- openocd pinned to a validated vid_pid, or esptool. Where it
cannot, the run says so rather than reserving budget for a path that cannot fire.

Raise the CI ceilings above the pool guard so the guard fires first and still
writes its report, and pin --retry 1 on every HIL leg: the guard is a flat
constant and does not scale with max_retry, so argparse's default of 3 would
triple the serialized usbtest tail against an unchanged guard.

Split the module: execution in hil_test/hil_flash/usbtest, infrastructure in
helper/ (locking, health, selection, shared bounded IO), and the two matrix
generators into .github/scripts/ -- ci_set_matrix.py sat in workflows/, where
GitHub treats every file as a workflow definition. 193 tests cover the bounded
paths, the kill ladder, the guard and the selector against synthetic /proc trees
and PATH-injected fakes; a real wedge cannot be manufactured on demand.
2026-08-18 12:19:09 +07:00
eef5af86aa hil, ci: scope HIL builds and tests to the boards a PR affects (#3797)
hil, ci: scope HIL builds and tests to the boards a PR affects

Add test/hil/hil_select.py, a stdlib-only selector that maps a PR diff to the
rig boards, tests and BSP families a change can affect, and wire it into CI so
pull requests build and run only those. A port change picks its families' boards,
a class change picks the examples enabling that class, and device/host changes
prune the other role. Anything unclassified — infra, an unmapped port, a selector
error — falls back to the full matrix, and push/schedule runs are untouched.
Move the shared example lists to hil_examples.py; 54 hardware-free tests cover
the rules.
2026-07-30 02:29:32 +07:00
e88fc441dd hil: split hil_test.py into hil_lock/hil_flash, add pool_check, update rig probes (#3794)
test/hil: add board-pool health check, split hil_test into focused modules (#3794)

Add test/hil/hil_pool_check.py: per-board rig health scan — probe presence,
light-example flash (dfu_runtime; device_info + serial check for host-only
boards), uid re-enumeration, safe recovery (probe authorized-toggle, board
reset), verified board_test re-park, USB topology report, and a markdown
summary table. Missing firmware is built on the spot (tools/build.py, idf.py
for espressif, one get_deps retry); row statuses: ok, flash-failed, failed,
locked. Board locks are always respected, never bypassed.

Refactor hil_test.py into hil_lock.py (flock protocol, controller permits,
hold/release/status CLI; replaces board_lock.py) and hil_flash.py (flashers,
find_firmware, run_cmd). Update WCH probe uids and the board roster in
tinyusb.json; add the hil-pool-check skill.
2026-07-29 17:29:59 +07:00
3fdd294b95 docs: add the unified OpenOCD plan, note worktree dep symlinks
The plan doc records why the fork exists and how each vendor source was
ported; the interim handoff it superseded is dropped.

CLAUDE.md: a new worktree should symlink the dependency dirs to the
primary checkout rather than re-fetching them, replacing a single
symlink only when the branch needs a different dep revision. Also allow
'linke' in codespell - WCH-LinkE is a product name.
2026-07-28 14:43:32 +07:00
c962a0bf62 docs: plan for etm-trace tightening and target-debugger integration 2026-07-24 15:56:14 +07:00
24bb035be7 Merge pull request #3786 from hathach/claude/improve-debug-skill-agent
docs(skills): debug-skill overhaul — role-neutral capture model, verified debugger arsenal, Espressif backend
2026-07-24 15:45:15 +07:00
154999dbac docs: address Codex/Copilot review on #3786
- target-debug: fault frame lives on PSP when EXC_RETURN bit2 set (FreeRTOS
  tasks) — decode LR before choosing $msp/$psp (Codex; valid, our verify
  happened to fault on MSP)
- esp-target-debug: show the Xtensa gdb for S3 in the attach recipe; clarify
  adapter serial = USB-SJ iSerial (colon MAC, hardware-verified) vs the
  CP2102N flasher uids in tinyusb.json (Codex; second half of the finding
  had the identifiers inverted)
- esp plan: align serial form with the verified command; record the real
  console-gate outcome (UART0, USB-SJ console untested) (Copilot)
- target-debug plan: Task 4 now consistently $JB/ARMv7-M matching the
  executed JLinkExe path (Copilot)
- drop IDE-local .idea files swept in by the rename commit (Copilot)
2026-07-24 15:14:02 +07:00
df3cea3d0e docs(superpowers): esp-target-debug design spec + executed implementation plan
Spec (brainstormed): own-skill backend decision, PHY-conflict map, six
verification gates, external-JTAG TODO. Plan executed same-day: all gates
run on the rig; apptrace resolved per its own gate rule as (untested).
2026-07-24 14:55:59 +07:00
21bbcb5bbf docs(target-debug): vector catch, SWO trace, verifybin, FreeRTOS threads; table integration
- Vector catch + Cortex-M fault autopsy, verified with a deliberate bad-load
  on stm32f407disco: CFSR=0x8200 (BFARVALID|PRECISERR), BFAR = exact bad
  address, stacked pc addr2lined to the faulting line; gotchas recorded
  (stale FPB comparators fire phantom SIGTRAPs — scrub first; arm DEMCR
  after reset; loads precise / stores imprecise; ARMv6-M has no CFSR/BFAR)
- SWO exception trace + hw PC sampling gate PASSED on F407: 680 KB of
  packets in 3 s (0x17 PC samples in flash range, 0x0E SysTick enter/exit);
  JLinkSWOViewerCL decodes stimulus only — raw SWORead is the recipe;
  SWOStart needs an explicit speed headless
- verifybin 'Verify successful.'; FreeRTOS -rtos plugin lists all 6
  cdc_msc_freertos tasks after a run->stop cycle (plain attach = 0xDEAD
  placeholder); semihosting anti-note; monitor-mode pointer (untested)
- Intrusiveness table gains the new rows; agent playbook bullet updated;
  retrieval gate 5/5 with a fresh reader; executed plan committed
2026-07-24 14:55:59 +07:00
3931206790 Update docs 2026-07-21 12:07:43 +02:00
9418aba918 misc fixes 2026-07-19 20:38:54 +08:00
277e618186 docs, udev: address Copilot review nits on PR #3775
- getting_started.rst: the reST inline-link markup rendered literally
  inside the code-block (not a runnable command) and lacked sudo — use a
  plain `sudo cp examples/device/99-tinyusb-examples.rules ...`.
- tools/88-tinyusb.rules: normalize the six MODE="666" entries to the
  4-digit octal MODE="0666" used everywhere else in the file.
2026-07-18 00:15:54 +07:00
e5b47c9306 skill: add usb-sniffer — wire-level capture with the ataradov hardware tap
Fourth view in the USB debugging toolset (usbmon = host URBs, usb-debug =
host reasoning, usb-target-debug = device firmware, usb-sniffer = what
actually crossed D+/D-). Covers the ataradov/usb-sniffer analyzer:
headless pcapng capture (--speed ls/fs/hs, --fold, --limit self-exit),
Wireshark/tshark analysis recipes, and the wire realities that bite:
downstream broadcast, sniffer self-capture noise, xHCI devnum != wire
address, tap-point-dependent reset visibility (hub choreography anchors),
FS-behind-HS-hub splits. Every recipe hardware-validated on the rig,
including the capture-window floor (a 3 s window provably misses the
enumeration ladder; 3M packets minimum).

Two udev files with distinct audiences, not one:
- examples/device/99-tinyusb-examples.rules (renamed from 99-tinyusb.rules):
  the user-facing rules the examples need — cafe VID access, hidraw, the
  ModemManager blacklist, a couple of board probes. getting_started.rst,
  the webusb_serial README and its source comment point here.
- tools/88-tinyusb.rules: the HIL rig's private probe/analyzer allowlist,
  now with the sniffer (6666:6620 + blank FX2LP 04b4:8613). Installed on
  the rig only; the usb-sniffer skill references it.
2026-07-17 17:32:47 +07:00
b9478a723b agent: add target-debugger — device-side root-cause loop on the HIL rig
Opus-tier agent charter for backgrounding a long hardware debug session:
instrument -> build -> flash under one held board lock -> dual-side
capture -> correlate -> refine, strictly one instance, skills as source
of truth (usb-target-debug, usbmon, usb-debug, usb-sniffer, usb-recover,
hil). The charter encodes what dogfooding established:

- diagnosis standard: evidence must show the mechanism, or a fix must
  flip the ORIGINAL failing case on hardware; stop after two
  evidence-free cycles and hand back a partial diagnosis
- lock cadence: hold for the whole session, release around hil_test.py
  runs (it self-locks per board)
- revert semantics: "fix stays, probe goes, re-verify clean" —
  instrumentation reverted, candidate fix left uncommitted and
  re-verified on a clean build, pristine firmware reflashed before
  lock release

Returns a machine-parseable diagnosis report including ruledOut[] —
disproven hypotheses are deliverables. Spec roster updated (opus/xhigh,
effort requested per agent() call).
2026-07-17 16:48:03 +07:00
f5d155256b skill: add usb-target-debug — device-side capture & debug on the HIL rig
Completes the debugging toolset (usbmon = what the host exchanged,
usb-debug = why the host acted, usb-sniffer = what crossed the wire):
TU_LOG/RTT capture, per-probe GDB autopsy without reset, RAM ring-buffer
event trace, J-Link DWT_PCSR PC-sampling, dual-side capture posture, and
board-lock rig discipline. Includes the implementation plan it executes.

Hard-won warnings baked in from real bring-up sessions: volatile ring
buffers vs -Os dead-store elimination, RTT NO_BLOCK_SKIP post-mortem
limits (no overwrite mode exists), DHCSR validity anchors for register
snapshots, release-lock-before-hil_test, and that a marginal just-recabled
link can fake a deterministic firmware bug.

Also ignore .claude/worktrees/.
2026-07-17 16:48:00 +07:00
ff69550b3d Fix max-effort review findings in lock protocol, workflows, and docs
Confirmed by a 10-finder / 28-verifier adversarial review pass:

board_lock.py — the flock is now the sole authority: drop cmd_hold's
pid-liveness pre-gate (a live hil_test.py pool worker's stale record no
longer blocks a genuinely free board); cmd_release probes the flock and
only signals a verified holder, refuses to kill hil_test.py holders
(CI mid-test), handles PermissionError; the holder daemon truncates its
lock records on SIGTERM and keeps the success pipe clear of fds 0-2
(closed-stdio hold used to leave an orphan holder while reporting
failure); --config default resolves beside the script.

hil_test.py — truncate the lock record on per-board release (pool
workers outlive their flocks); warn instead of silently failing open
when the lock dir is unusable; error out on -b names absent from the
config (was a silent zero-test exit 0, readable as a green HIL run);
drop an emptied board row in accumulate_report (variant boards left a
blank ghost row).

workflows — remove the stray positional arg that made the validate size
stage exit 2 on every run; wrap JSON.parse(args) in all six scripts;
factor pr-babysit's drifted reply recipe into postReplyRecipe and dedup
refutation replies across cycles; validate args.pr and maxCycles;
driver-review rejects an empty dimensions list; hil-validate drops a
dead guard clause and retries diagnostics with -v -r 1.

agents/docs — port-dev scopes git clang-format to its own files
(concurrent workers reformatted each other in shared checkouts);
hil-operator/hil skill wording matches actual fail-fast output; the
implementation plan is now a DO-NOT-EXECUTE historical record (banner +
checked boxes) so plan-executing agents cannot revert shipped files.

Verified: lock storm 1-winner-in-10, stale-record hold, closed-stdio
hold, dead-pid cleanup, CI-holder refusal, ghost-row 4-scenario merge,
unknown-board exit 1, py_compile + check.sh on all six workflows,
pre-commit clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Upj4hta5TNoAbidqeC1zZ6
2026-07-13 18:01:07 +07:00
0557655afb Fix review findings and add static-analyzer agent
Review-fix batch (owner-confirmed) on the multi-agent harness:

- board_lock: detach holder stdio so a captured `hold` cannot hang on the
  daemon's inherited pipe; probe locks by holder-pid liveness instead of a
  momentary flock, which could spuriously fail a concurrent acquirer
  (storm-tested: 1 winner in 10, 0/15 acquire failures under probe storm)
- hil_test: locked board renders a visible board-locked fail row so the
  report matches the exit code; stale marker cleared on a real re-run
- pr-babysit: autoPush now opt-in (default dry run); resolve recipe
  paginates reviewThreads; post-push resolve gets issue-comment fallback
- validate: size stage honors non-default base via --base-branch; pvs
  stage delegated to the new agent
- new static-analyzer agent (sonnet): PVS-Studio SAST+MISRA for one
  board, structured findings gated on files changed vs base

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rn1AN5DsTdFhRwhugfgKZi
2026-07-10 23:28:09 +07:00
e3dd9245ef feat: Claude Code multi-agent dev/test harness for TinyUSB
Add worker agents (builder, port-dev, driver-reviewer, hil-operator,
pr-monitor), deterministic workflows (validate, fanout-dev, driver-review,
hil-validate, full-check, pr-babysit) and a /pre-pr gate skill, so sessions
can fan build/test/review/PR-triage work out to tiered subagents. pr-babysit
drives a PR to green: triage CI + bot reviews, fix validated findings, verify,
push, and reply-to + resolve each inline review thread (fixed or refuted).

Replace the stop-the-runner HIL discipline with per-board flock locks:
test/hil/board_lock.py plus a fail-open guard in hil_test.py let CI and dev
sessions share the rig per board (locked boards fail fast and re-run;
HIL_NO_BOARD_LOCK=1 is a user-authorized bypass). The actions-runner is
never stopped.

Design spec, implementation plan, and real-rig smoke evidence under
docs/superpowers/.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rn1AN5DsTdFhRwhugfgKZi
2026-07-09 23:34:29 +07:00
dae3f9a366 docs: convert changelog release notes from RST to Markdown (#3746)
* docs: convert changelog release notes from RST to Markdown
2026-06-30 22:27:27 +07:00
20200b3520 docs: move changelog to docs/changelog, drop the docs/info folder
Relocate docs/info/changelog/ -> docs/changelog/ (docs/info held only the
changelog) and update all references: the toctree, README + MAINTAINERS links,
make_release.py, and the make-release skill.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 14:39:57 +07:00
0849a5c172 docs: keep the changelog page last in the toctree (maintainers before it)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 14:36:48 +07:00
ae87287f5b Revert MAINTAINERS to .rst and add it to the docs build
- restore MAINTAINERS.rst (drop the .md); make the changelog link absolute so it
  resolves both on GitHub and in the rendered docs
- docs/maintainers.rst includes the root file (same pattern as README) and is
  wired into the Documentation toctree

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 14:33:15 +07:00
461dff5911 Fix code-review findings (changelog rendering, release skill, sidebar)
- changelog: fix 3 silent RST mis-renders carried over from the old monolith
  — Markdown link in 0.7.0, mismatched/single backticks in 0.18.0 / 0.20.0
- make-release skill contributors one-liner: parallelize the gh fetch, anchor
  the bot filter (was a substring that dropped handles like "abbott"), and join
  with ", " (paste -sd cycles the delimiter -> "@a,@b @c"); finalize now stages
  only the reviewed set (git add -A -- ':!.idea'); drop the obsolete CRLF gotcha
- make_release.py: emit LF not CRLF in the repository.yml insertion (fixes the
  gotcha at the source)
- docs sidebar: drop the hardcoded furo component list; override brand.html to
  include furo's own template + the sponsor button (decoupled from furo
  internals, no upper-bound pin needed); move sponsor styles into custom.css
- .pre-commit-config.yaml: drop stale end-of-file-fixer excludes for the
  deleted contributors/CoC include shims

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 10:57:26 +07:00
0657ecf728 Address Codex review: release skill + furo requirement
- make-release skill: stage new files with git add -A in finalize, use
  unprefixed release tags (X.Y.Z), and run validate build steps in subshells
  so the cwd doesn't leak between commands
- docs/requirements.txt: require furo>=2025.12.19 so the sidebar component
  list in conf.py (incl. variant-selector.html) is always available

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 10:23:36 +07:00
ce23b8d72e Address Copilot review; move release process into the make-release skill
- README: restore the separate CH32V103 / CH583,CH582 rows in the Supported
  CPUs table — the merged row wrongly applied "ISO data loss [2]" to CH583/2
- Fix typos in historical changelog entries (santiy, Venndor, dynamnic, bagde,
  masstorage, techinical, walkaround, "Update Update") flagged by Copilot
- Replace the AGENTS.md Release section with a pointer to the make-release
  skill; add a Finalize step (maintainer commit/tag/push + GitHub release) to
  the skill so nothing is lost

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 09:10:50 +07:00
c887bd907c Bump version to 0.21.0; rework changelog, contributors, and docs
Release:
- Bump version to 0.21.0 and regenerate tusb_option.h, library.json,
  repository.yml, sonar-project.properties, boards.rst, dependencies.rst
- Add 0.21.0 release notes and split the changelog into per-release files
  under docs/info/changelog/ (date out of title, driver/class groups as
  sub-headings, DCD & HCD section after Device/Host stacks)

Contributors:
- Credit each release's PR authors in a Contributors section
- Drop the curated contributors page; add MAINTAINERS.rst

Docs:
- Update Code of Conduct to Contributor Covenant 3.0 (keep it in the repo,
  remove it from the built docs)
- Sidebar: add a home entry, rename the group to "Documentation", move
  Changelog into it, add a GitHub Sponsor button, merge external links,
  rename FAQ; hide the inline toctree on the landing page
- Add the make-release skill and update the AGENTS.md release process

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 23:38:01 +07:00
40f4c12c6b Merge pull request #3743 from hathach/claude/build-doc-skill
docs: add build-doc tooling and a README for every example
2026-06-29 12:56:16 +07:00
ba32b46ebd docs: address Copilot review on the example READMEs
- Order CFG_TUH_DEVICE_MAX before CFG_TUH_HID in the host config snippets
  (cdc_msc_hid, hid_controller) so the documented snippet has no forward
  macro reference when copied into tusb_config.h.
- Fix stale `examples.rst` references: the generator now writes per-group
  `docs/examples/<group>/index.rst` pages, so update the conf.py comment and
  the build-doc SKILL.md accordingly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 10:42:41 +07:00
4b1c8d16f7 docs: add build-doc tooling and a README for every example
Documentation tooling:
- Add the `build-doc` skill and `tools/build_doc.py` wrapper for local
  Sphinx builds (clean / -W / open).
- Enable Markdown (MyST) in conf.py and auto-collect
  examples/{device,host,dual}/*/README.md into a 3-level Examples nav
  (Examples > Device/Host/Dual > example), noting each page's source
  location and normalizing headings to a single H1.
- Remove the stale `.claude/commands/build-doc.md`; point the AGENTS.md
  Documentation section at the skill.

Example docs:
- Add a README.md for every device/host/dual example: what it does, USB
  interface table, notable tusb_config.h settings, generic CMake + Make
  build steps, and how to try it.
- Fold each *_freertos variant into its base README, noting the FreeRTOS
  source path and any RTOS-specific behavior.

Generated docs/examples/ output is git-ignored. Builds clean with
`sphinx-build -W`.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 10:16:25 +07:00
8ee82a55c9 bsp/stm32h5: fix uart definition
Signed-off-by: HiFiPhile <admin@hifiphile.com>
2026-06-27 12:53:53 +02:00
eda704ca1a hw/bsp+wch: rename the CH58x family to ch583 and OPT_MCU_CH58X to OPT_MCU_CH583
The BSP family and MCU option were named "ch58x"/"CH58X", but the supported part is
the CH583/CH582 (and the SDK repo is openwch/ch583); CH585 is a separate MCU family,
so the CH58x umbrella was misleading. Rename to the specific family:

- hw/bsp/ch58x -> hw/bsp/ch583 (dir), and the BSP-local files ch58x_it.* ->
  ch583_it.*, system_ch58x.* -> system_ch583.* (include guards/refs updated). The
  vendor SDK files (CH58x_common.h, CH58x_*.c in hw/mcu/wch/ch583) keep their names.
- OPT_MCU_CH58X -> OPT_MCU_CH583 in tusb_option.h, tusb_mcu.h, and the shared WCH
  USBFS driver (ch32_usbfs_reg.h, dcd_ch32_usbfs.c). OPT_MCU_CH582 is kept as an
  alias (same value), so either name selects the same code.
- FAMILY_MCUS CH58X -> CH583, CFG_TUSB_MCU=OPT_MCU_CH583, mcu:CH58X -> mcu:CH583 in
  the example skip lists, the CI build matrix (ci_set_matrix.py), the get_deps family
  tag, and docs/reference/boards.rst.

Board names (ch582m_evt, yd-ch582m) are unchanged. Verified: make + cmake build for
ch582m_evt, and ci.lan HIL (all device examples pass).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 15:23:08 +07:00
953abfb393 Merge remote-tracking branch 'origin/master' into add-ch58x-usbfs 2026-06-18 15:31:03 +07:00
5145b67f79 Merge remote-tracking branch 'origin/master' into stm32c5
# Conflicts:
#	README.rst
2026-06-11 17:20:15 +07:00
f19c01216f docs: revert USBFS non-ISO transfer qualification in device_issues
Restore original "Other types of transfers are not affected" statement,
removing the conditional USBHS_INT_BUSY_EN / USBFS-unconfirmed wording.

Co-authored-by: Zixun LI <HiFiPhile@users.noreply.github.com>
2026-06-02 16:59:14 +00:00