summaryrefslogtreecommitdiff
path: root/CLAUDE.md
AgeCommit message (Collapse)Author
11 hoursClarify worktree reuse workflowdocs/worktree-reuse-workflowHiFiPHile
5 daysAdd RTT console/capture tooling (tools/rtt.py), rtt skill, and HIL harness ↵Ha Thach
support (#3853) Promote SEGGER RTT from an inline debugging technique to a standalone skill backed by one stdlib-only implementation in tools/rtt.py: a CLI and importable module for console/capture over J-Link (RTTTelnetPort) and OpenOCD (rtt server) probes, with probe selection by serial or VID:PID, control-block address via --elf or --addr, bidirectional console, post-mortem ring dump, and --reset-before-attach for boot-time capture. The HIL harness reads a board's console over RTT when its probe has no VCOM ("logger": "rtt" plus a LOGGER=rtt variant define), covering device_info, pool-check aliveness, and CI wiring. Validated on 22 boards across both backends; 26 unit tests run in pre-commit.
12 dayshil, docs: reference toolchains by their official env vars, not one rig's pathshathach
~/code/pico/pico-sdk and $HOME/code/esp-idf/export.sh are the ci rig's private layout; written into instructions they silently stop being true on tusb, a dev PC, or any future rig. The docs now use the variables the vendors define -- PICO_SDK_PATH for the Pico SDK and IDF_PATH for ESP-IDF, activated explicitly as `. "$IDF_PATH/export.sh"` -- and leave where the checkouts live to each host's profile. The variables are only useful if the shells that agents actually get can see them, and `ssh <rig> 'cmd'` is non-interactive AND non-login: it reads no profile, and Debian's sshd-sourced ~/.bashrc returns at the interactive guard before most of the file. The ci rig already keeps its exports in the section ABOVE that early-return; IDF_PATH now sits there beside PICO_SDK_PATH, and the whole chain is verified from a plain non-interactive ssh: both variables visible, `. "$IDF_PATH/export.sh"` activates ESP-IDF v5.5.3 with idf.py on PATH -- no login shell, no alias, no hard-coded path. hil-pool-check documents that placement so the next rig is set up the same way.
12 daysskills, CLAUDE.md: correct instruction claims the source refuteshathach
Findings from an audit of the .claude instruction surface: 1,387 falsifiable claims extracted with a quote-gate (zero hallucinated), each verdicted against the code, the kernel at the rig's running version, or the rig itself. Only claims the current source actively refutes were touched; hard-earned rig knowledge stands as source of truth. usbtest told operators to stop the actions runner before touching hardware. Every other file forbids exactly that since the per-board flock landed - following it stops CI on a shared rig. Twice in the same file it said hil_test.py serializes usbtest batteries; hil_lock.py budgets 2 concurrent per host controller, a profiled throughput trade rather than a safety ceiling - while the recorded hazards stay: an unbudgeted battery has hard-frozen the rig through a VFIO xHCI PCIe error, and a marginal DUT port bouncing under concurrent batteries has killed a uPD720201 outright, which lowering the widths does not fix. It also cited src/usb_descriptors.h and src/tusb_config.h as if repo-relative (they are the example's own, and the comment sat above the cd that establishes the base) and presented usbtest_do_ioctl() and tools/usb/testusb.c as repo files when both are Linux kernel. usb-kernel-recover called the Renesas ppps "real per-port" in its rig layout while saying four sections earlier that VBUS stays up. Both describe the same silicon and only the second was right: owner-confirmed, the cards advertise ppps and do not implement it, so a root cycle is purely a re-enumeration - both places now say so and warn against reading uhubctl's flag as power control. The layout listed three cards; the rig has five (01/03/04/05/06:00.0; AMD 02:00.0 has none), re-derived from lspci/uhubctl/sysfs and written as a derivation recipe because bus numbers renumber every boot. The root-cycle rung also gains the board-flock requirement the other files already demand - it avoids the KERNEL device_lock, which is a different lock, and the text now names the two apart instead of reading as "no reservation needed". CLAUDE.md listed src/tusb_config.h among the key files; no such path exists - tusb_config.h is per-example, src/tusb_option.h is the file that lives there.
2026-08-18skill(read-doc): search the Calibre database instead of the filesystemhathach
Finding documents by walking the library tree misses anything the filename does not carry - Calibre stores only a truncated title and the author there, so the tags, series, publisher and description that hold most part numbers and errata IDs are invisible to it. A zero-result tree search then reads as "the document does not exist" rather than as a bad search; that happened here, and led to a confident claim that a fully populated 14,000-file library was empty. search.py queries metadata.db, ANDs its keywords across every metadata field (including the stored filename), and prints the best matches first with the exact path to read. Matching is NFKC + casefold, so a typed ASCII apostrophe or mu reaches the titles that store the typographic ones. Every printed path is checked on disk. Calibre renames <author>/<title> (<id>) when metadata is edited and leaves the old directory behind, so a miss retries by the stable book id before reporting MISSING - which distinguishes "the file is not here right now" from "no such document". The gate tests for metadata.db rather than the directory, since an unmounted or half-synced mountpoint is still a directory. Consumers that prescribed their own tree search - driver-reviewer, port-dev, the driver-review workflow, and the calibre-library references in CLAUDE.md, usbtest, etm-trace and target-debug - now point at the skill, which owns the library's location.
2026-08-18docs: hand off follow-up work as per-PR planshathach
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-18skills, docs: rewrite USB recovery from the live incidentshathach
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-18test/hil, ci: contain a wedged USB stack instead of stranding the runnerhathach
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-07-28docs: add the unified OpenOCD plan, note worktree dep symlinkshathach
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-24docs(skills): rename debug skills, drop the PC-host/TinyUSB-device assumptionhathach
Rename usb-target-debug -> target-debug, usb-debug -> usb-kernel-debug, usb-recover -> usb-kernel-recover (script filenames unchanged), and make all debug skills/agents decide tool applicability by which end of the link runs Linux: TinyUSB may run the device or host stack, and its peer may be a Linux PC, another TinyUSB board, or a Linux gadget (e.g. Raspberry Pi UDC). - usbmon: exists only when a Linux PC is the link's host - usb-kernel-debug: either Linux end; allowlist gains dwc3/libcomposite/udc_core for the gadget side of a Linux peer - usb-sniffer: the only full-visibility capture when TinyUSB is the host - target-debug: covers dcd_* and hcd_*/tuh_ debugging; channel choice by topology - update target-debugger/hil-operator agents, pre-pr, hil-validate.js, and the USB_RECOVER path constant in test/hil/usbtest.py - CLAUDE.md: fold the dcd/hcd datasheet cross-check rule into the read-doc line
2026-07-21docs: add read-doc skill, tighten CLAUDE.md and skill docs (#3778)Ha Thach
* docs: add read-doc skill for on-demand datasheet lookup Search and read MCU datasheets, reference manuals, errata, and the USB spec from a local Calibre library ($HOME/Documents/calibre-library) instead of answering register/bitfield/pinout questions from model memory. Gated on the library's existence, so it no-ops for contributors who don't have it. * docs: reference read-doc skill and tighten CLAUDE.md Point the datasheet/reference entry at the new read-doc skill, and trim sections that only duplicate a skill already owning the detail: PVS-Studio and Code Size collapse to pointers; GDB/Build/Flash command blocks condensed to essentials. 213 -> 129 lines; behavioral guidelines and the validation checklist unchanged. * docs: tighten skill redundancy; rename AGENTS.md refs to CLAUDE.md code-size: fold the step list into a sentence and drop invocation examples the argument tables already cover. hil: merge the duplicated self-lock bullets and compress the hifiphile note. usbmon: compress the group-membership setup paragraph. All commands, flags, lock rules, and report paths preserved. usb-target-debug and the pvs script only get stale AGENTS.md references renamed to CLAUDE.md (now the real file); run_pvs.sh no longer cites a --dump-files mention that CLAUDE.md dropped. * docs: fix review findings — restore Espressif cd step, ELF placeholder, code-size comment Codex/Copilot/Claude review of #3778: the condensed Espressif bullet lost its cd (idf.py resolves the project from CWD, so the command failed from repo root); the GDB example now uses the build/your_app.elf placeholder that docs/troubleshooting.rst established; the code-size invocation comment no longer references --combined, which the shown command doesn't use.
2026-07-21docs: make CLAUDE.md the real agent-instructions file (#3769)Ha Thach
* docs: make CLAUDE.md the real agent-instructions file
2026-03-04fix trailing newline in workflow files to pass pre-commithathach
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2025-11-26focus on cdc test, write lots more data, each trunk is 64 or less since ↵hathach
examples having minimum 64 bytes fifo (fs)
2025-10-03update for release 0.19.0hathach
2025-10-02add CLAUDE.md and fix pre-commit buildhathach