pciutils/usbutils aren't guaranteed present, especially on minimal or
live-boot systems — exactly the kind of environment someone testing
Archipelago compatibility is likely to be running. Rewrote WiFi/ethernet
detection to read /sys/class/net/$iface/device directly first (vendor,
device, driver via uevent — always available, no package needed), the same
approach as manually finding a chip by hand: enumerate interfaces, read
vendor/device IDs from sysfs, get the driver from uevent/modalias. Only
reaches for lspci/lsusb, when installed, to turn a hex ID into a friendly
name; falls back to a small built-in vendor-ID table (Intel, Broadcom,
Realtek, Atheros, MediaTek, Ralink) plus the raw ID + driver name
otherwise. Also now handles USB and SDIO wifi chips, not just PCI.
Found and fixed a real bug while testing this against actual hardware
(this box's virtio NIC): the naive `basename` of the resolved device path
breaks for drivers like virtio-net that wrap the real PCI function one
level deeper in sysfs (.../0000:00:12.0/virtio2) — basename alone grabs
"virtio2", which lspci -s rejects as "Invalid slot number". Fixed by
extracting the last domain:bus:device.function-shaped path component
instead of trusting the final one.
Verified for real, not just written: ran with lspci installed (gets the
friendly "Red Hat, Inc. Virtio network device" name), then genuinely
removed lspci/lsusb from the system (moved the binaries aside, restored
after) and reran — falls back correctly to vendor ID + driver name instead
of erroring or going blank. Passes shellcheck clean both times.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Reads /proc, /sys, and common CLI tools (lscpu, lsblk, lspci, lsusb) to
print a YAML block matching data/schema.json: device model (DMI on x86,
/proc/device-tree/model on ARM SBCs), form factor (best-effort — battery
presence, DMI chassis type, device-tree presence), CPU, RAM, root storage
type/size, WiFi chip (PCI, then USB, then falls back to driver name rather
than guessing wrong), ethernet. Fields it can't detect (archy_version,
install_method, status) are left as clearly-marked TODOs rather than
guessed. Local-only — no network calls, changes nothing.
Tested for real on this box (a QEMU VM): correctly identified it as a VM,
correctly fell back to "other" with a TODO for form_factor rather than
guessing, output validated as parseable YAML. Passes shellcheck clean.
Linked from the homepage, report.html, and CONTRIBUTING.md.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Registered a repo-scoped self-hosted runner (hcl-local-deploy) directly on
the box serving hcl.archipelago-foundation.org, running in host (not
docker) execution mode. Deploy is a plain local rsync — no SSH keys or
remote credentials needed, since the runner already has filesystem access
to the docroot. Runs as the debian user with no sudo; docroot ownership
was changed from www-data to debian so this works without any privilege
escalation (nginx only needs read access to serve it).
ci.yml now runs on pull_request only — deploy.yml already validates before
deploying on push to main, so running both on every push would just
duplicate the check.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Lenovo ThinkPad X250 report from issue #1 (submitted via the site form).
Reconstructed cpu/archy_version from the issue body by hand — the
submitted YAML had them glued together with no newline between
("...2.60GHz"1.8.10-alpha), which buildYaml() does not reproduce on these
same field values in isolation (tested directly), so this looks like a
Gitea draft-restore or browser-autofill artifact during actual submission
rather than a bug in the form itself. Values used here are unambiguous
either way. Left the ThinkPad T430 example in place; only removing the Pi
one was requested.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Gitea 1.27.1 on this instance silently ignores the ?template= param for
.github/ISSUE_TEMPLATE/hardware-report.yml — the structured fields never
render, just a blank title/body editor (confirmed live: same URL that's
supposed to load the form shows nothing). Rather than debug Gitea's YAML
issue-forms support, site/report.html is a plain form matching the schema
that builds a title + markdown body (with a ready-to-merge YAML block) and
opens Gitea's issues/new with them pre-filled via query params, which does
work on this instance (verified live).
Verified the full round trip in a real browser: filled the form, submitted,
confirmed the opened Gitea tab has the correct title and a body containing
valid YAML matching every field. Did not actually click "Create Issue" —
no reason to leave a test issue on the tracker.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Modeled on three researched precedents (see README): OpenWrt's Table of
Hardware for the browsable sortable/filterable table UX, postmarketOS's
working/community/testing tiers for the status field (collapsed to
working/partial/broken here), and RaspiBlitz's scattered GitHub-issues
approach as a negative example to avoid — hence structured YAML report
files validated against a JSON Schema instead of free-text issue threads.
- data/reports/*.yml + data/schema.json: one file per report, schema
requires `issues` whenever status is partial/broken
- scripts/build.py: validates every report and builds site/data.json,
fails loudly on bad data (same idea as archy's own
validate-app-manifest.sh)
- site/: plain HTML/CSS/JS, no framework or build step, fetches data.json
client-side — search, filter by status/form-factor, sortable columns,
click a row for issues/notes detail
- .github/ISSUE_TEMPLATE/hardware-report.yml: structured submission path
for contributors who don't want to touch git directly
- .gitea/workflows/ci.yml: runs the build/validate step on push and PRs
Not yet deployed anywhere — see README's Deployment section.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>