Decision 0045
What is plugged in is a fact, with a role and the profile that grants access
Architecture decision record 0045: What is plugged in is a fact, with a role and the profile that grants access
Context
The plan’s device center is a graph of what is attached — USB and serial devices, debug probes, their identifiers, interfaces, drivers, permissions and inferred capabilities — and a quiet notification on connection with “open” and “use with current project”. The facts had a flat list of USB devices: ids and names, no interfaces, no nodes, no idea what any of it was for. “What is plugged in” was a question the machine could not answer in its own terms, and “I see an ST-Link but you cannot open it” was a diagnosis it could not make.
The curated udev profiles (ADR-0023’s contribution on-ramp) already say which devices a person may reach. Read the other way round, they say what a device seen on the bus is asking for.
Prior decisions
ADR-0028 makes facts structured and read from the kernel, never parsed from shell output. ADR-0023 makes device rules curated profiles rather than free-form udev. ADR-0029 names the probes and boards Tacid is for.
Decision
system.devices is the graph, read from sysfs; a role and a profile are inferred from a
table that mirrors the curated rules; tacid device shows it, and the rules model answers
“what is plugged in”.
For every USB device the fact gives its ids, names and serial, its driver, and its interfaces —
each with its class, its driver and the device nodes the kernel put under it, /dev/ttyACM0
or /dev/hidraw0, with the mode and group each node has right now, or nothing when the node is
not there to be looked at. What a device is for comes from one table: the ST-Link, J-Link, Pi,
Black Magic, FTDI, CP210x, CH340 and Nordic ids the profiles name, and any product that calls
itself CMSIS-DAP; the table names the profile beside the role, so the answer to “why can I not
open it” is one declaration away — tacid.hardware.udev.profiles = [ "stlink" ] — and the
table can only name profiles that exist. A keyboard is an input device with no profile, because
the kernel serves it without a rule; a hub is a hub.
The notification on connection, and “use with current project”, are the shell’s and the project tools’ to build, and this record does not claim them.
Consequences
tacid devicereads the graph as one line per device;tacid ask "what is plugged in"is answered offline from the same fact.- The lifecycle test puts a USB keyboard on the machine’s bus and finds it, by id and by name, as an input device.
- The role table and the udev profiles are two lists of the same devices, in two languages. A profile added without a row here is a grant the device center cannot point at; the contribution on-ramp for a probe is now the rule and the row together.
Alternatives rejected
- Reading
lsusb. Facts are read from the kernel, not parsed from a tool’s output. - Guessing capabilities from interface classes alone. A class says “CDC data”, not “this is the debug probe you flash with”; the ids do, and the profiles already list them.