This guide assumes nothing. No Python, no terminal experience, no knowledge of what any of these boards are. It takes about twenty minutes and ends with you recording a figure, seeing the tool refuse a bad one, and understanding why the refusal is the point.
You do not need any hardware for this. Everything here runs on an ordinary laptop. The hardware guide is BARE_METAL.md, and it comes after this one.
- Part 0, What this is
- Part 1, Open a terminal
- Part 2, Install Python
- Part 3, Get the code
- Part 4, Make a virtual environment
- Part 5, Install the project
- Part 6, Run the tests
- Part 7, Look at the hardware
- Part 8, See the backlog
- Part 9, Record something
- Part 10, Get refused, on purpose
- Part 11, Close the gap
- Troubleshooting
A workbench holds five small computers. Projects run on them, a camera that recognises something, a radio carried across a field, a robot that follows a line, and each project produces numbers: how long, how much power, how far.
The problem this tool solves is that numbers rot. Six weeks after a bench session, "0.9 joules" is still on the page, and everything that made it mean anything is gone: which board, how many runs, what measured it, whether the board was warm. The number survives; its meaning does not, and it gets quoted anyway.
So this tool refuses to store a number without its provenance. If you say you measured something, you must name the instrument. If you cannot name one, you are estimating, and the tool will store it as an estimate and keep it on a list of things nobody has measured yet.
That is the whole idea. The rest of this guide is mechanics.
A terminal is a window where you type commands instead of clicking.
- Windows: press the Start button, type
powershell, press Enter. - macOS: press ⌘ and Space together, type
terminal, press Enter. - Linux: press Ctrl, Alt and T together.
A window opens with a blinking cursor. Everything below gets typed there, followed by Enter. Commands are case-sensitive, and a wrong character produces an error rather than damage, this is a safe place to make mistakes.
Python is the language this tool is written in. Check whether you already have it:
python3 --versionIf that prints Python 3.10 or higher, skip to Part 3. On Windows, try
python --version instead.
If it prints an error or a version below 3.10, install it:
- Windows: download from python.org/downloads. During installation, tick "Add Python to PATH". This matters; without it the terminal will not find Python afterwards.
- macOS: download from the same place, or if you have Homebrew:
brew install python. - Linux (Debian/Ubuntu):
sudo apt install python3 python3-venv python3-pip.
Close the terminal and open a new one, then check the version again.
If you have git:
git clone https://github.com/thierrysays/edge-ai-workbench
cd edge-ai-workbenchIf you do not, download the ZIP from the repository page on GitHub (the green
Code button, then Download ZIP), unzip it, and use cd to move into the
unzipped folder. On most systems you can type cd (with the space) and then
drag the folder onto the terminal window, which fills in the path for you.
Check you are in the right place:
lsYou should see README.md, projects, src and tests among the output. On
Windows PowerShell, ls works too.
A virtual environment is a private box for this project's dependencies, so installing something here cannot break anything else on your machine. It is one command, and it is worth the thirty seconds.
# macOS / Linux
python3 -m venv .venv
source .venv/bin/activate
# Windows PowerShell
python -m venv .venv
.venv\Scripts\Activate.ps1Your prompt now starts with (.venv). That is how you know it worked. If you
close the terminal, run the activate line again next time, the environment
persists, the activation does not.
If PowerShell refuses with a message about execution policy, run
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass and try again. That
allows scripts for this one terminal window only.
pip install -e ".[dev]"-e means "editable": the installed tool points at these files, so if you
change one the change takes effect immediately. [dev] adds the testing tools.
This project has no runtime dependencies, so the only things being
downloaded are the test and lint tools. If you install without [dev], nothing
is downloaded at all.
Check it worked:
wb --helpYou should see a list of six commands.
make testIf make is not available on Windows, run the layers directly:
python -m pytest -q150 tests should pass in a couple of seconds. Most of them check that the tool refuses something. That ratio is deliberate: a tool that accepts good input proves nothing about itself, and the input it must reject is the whole design.
wb boardsFive boards, each with four lines. The two worth reading are opens (why the
board exists here, meaning the thing no other board can do) and cannot, which
is the honest one.
cannot is not optional. The code refuses to define a board without it, because
a board described only by its strengths eventually gets handed a job it will
fail at, and that discovery costs a bench session rather than a paragraph.
wb summarySeven estimates, none of them measured. These came from the sibling repository
edge-ai-refusal-runtime, which governs an AI system and refuses actions that
would exceed an energy budget. Every figure that budget is built from is a
guess, labelled as one. This list is what it will take to stop guessing.
Notice the unit: budget-unit. In that repository the numbers are
dimensionless, so a budget denominated in them constrains nothing physical.
Finding out what one is worth in joules is the first project's entire question.
Make a project and record a figure in it:
wb new practice
wb record --project practice --board uno-q \
--quantity boot_time --unit s \
--samples 21.4 20.9 21.8 \
--instrument "stopwatch, 0.1 s resolution" \
--method "power-on to login prompt, cold boot, 3 runs" \
--operator "your name"Then read it back:
wb show --project practiceYou get the mean, the spread (±), the unit, the sample count, and the
instrument. The spread is the interesting half. A mean with no spread beside it
cannot be argued with, which is a property of advertising rather than
measurement.
Open the file it wrote: projects/practice/measurements.jsonl, in any text
editor. One line, one JSON object, sorted keys. It is meant to be read by people
and diffed in a pull request.
This is the part that shows what the tool is for. Try to record a measurement without saying what measured it:
wb record --project practice --board uno-q \
--quantity boot_time --unit s --samples 21.4 \
--method "felt about right" --operator "your name"wb: a measurement must name the instrument that produced it; an unattributed
figure is an anecdote
Now try three more refusals:
# A number that is not a number
wb record --project practice --board uno-q --quantity x --unit s \
--samples fast --method m --operator you --instrument stopwatch
# A time with no timezone, a bench in Paris and a bench in Singapore
# do not share a wall clock
wb record --project practice --board uno-q --quantity x --unit s \
--samples 1 --method m --operator you --instrument stopwatch \
--at "2026-08-21T09:00:00"
# A project name that is really a path
wb record --project ../../../tmp/escaped --board uno-q --quantity x \
--unit s --samples 1 --method m --operator you --instrument stopwatchEach one is refused with a sentence explaining why. The last one used to work: it wrote a file outside the repository entirely, until the security test layer found it. That story is in THREAT_MODEL.md as T-3.
Record an estimate, then measure it, and watch the backlog empty:
wb record --project practice --board uno-q \
--quantity idle_power --unit mW --samples 400 \
--basis "datasheet typical figure" \
--method "read from the datasheet, not measured" --operator "your name"
wb summary # idle_power appears as outstanding
wb record --project practice --board uno-q \
--quantity idle_power --unit mW --samples 512 508 519 \
--instrument "INA219, 12-bit, 0.1 ohm shunt" \
--method "60 s at idle, mean of three runs" --operator "your name"
wb summary # nothing waiting
wb gap --project practice --quantity idle_poweridle_power: estimate 400 vs measured 513 mW, the estimate was 22.0% too low
That sentence is the product. Everything else in the repository exists so that it can be said with a straight face.
Clean up when you are done:
rm -rf projects/practice| What you see | What it means |
|---|---|
python3: command not found |
Python is not installed, or not on your PATH. On Windows, reinstall with "Add Python to PATH" ticked. |
wb: command not found |
The virtual environment is not active. Run the activate line from Part 4. |
No module named edge_ai_workbench |
pip install -e . has not been run, or was run in a different environment. |
make: command not found |
Windows has no make. Use python -m pytest -q instead. |
running scripts is disabled on this system |
PowerShell execution policy. See the note at the end of Part 4. |
no project 'x' under projects/ |
Create it first with wb new x. |
not a usable project name |
Lowercase letters, digits, dot, dash and underscore, starting with a letter or digit. |
| If you want | Read |
|---|---|
| To run this on real hardware | BARE_METAL.md |
| To know what counts as a measurement | MEASUREMENT.md |
| To know what each board can and cannot do | HARDWARE.md (français) |
| To see how the tests are organised | TEST_STRATEGY.md |
| To start your own project | wb new my-project, then fill in its README |