One firmware: the Debug Console in every build, off until switched on (#68) #70

Merged
twisla merged 2 commits from console-setting into main 2026-10-06 21:58:27 +00:00
Owner

For #68. The design round ended somewhere simpler than a configurable token for Debug Builds: no Debug Builds. One firmware has the Debug Console, off until its owner switches it on, with a token that belongs to the device (ADR 0010, Q188 to Q195 in docs/milestones/R1.md).

What changes

  • The console and the test commands are in every firmware. cardputer-adv-debug, RORO_DEBUG, +debug, scripts/debug_flags.py, update install … force and "a Debug Build doesn't install releases" are gone. CI builds one firmware.
  • Off by default, and off when the stored setting is missing or invalid. Off, nothing listens, and neither the task nor the 4 KB ring exists.
  • Settings → Debug Console: the switch, the address, the token (made by the device, 100 bits, shown large), "New token", "Type a token". DBG in the Status Bar.
  • Challenge and answer (HMAC-SHA256): the token never crosses the network. Five wrong answers close the console for a minute. This breaks old clients, as decided.
  • USB serial only: debug on, debug token <value>, debug token new; scripts/flash.sh --debug provisions a device with them.
  • scripts/rdbg.py: -t/--token, $RORO_DEBUG_TOKEN, or the file; fetches a release's ELF to decode a crash.
  • Docs: ADR 0010 (ADR 0004 marked superseded in part), README, CONTEXT, R1, and the site's developer pages rewritten around "switch the console on".

Measured: 1,881,799 bytes of flash and 54,700 of static RAM, against 1,851,387 / 54,612 for the release build and 1,874,887 / 58,780 for the Debug Build.

Checked: 468 host tests (12 new: token, HMAC against RFC 4231, the shared vector with rdbg.py, the lockout across the clock's wrap, the settings). On the device: off by default after an update from a Debug Build; switching on; login; DBG; debug on/token refused over the console; six wrong tokens, the lock and the recovery; three crash abort, Safe Mode with the console, the crash decoded; the setting surviving an update; debug off.

Not checked: scripts/flash.sh --debug over USB (no device on USB); "New token" and "Type a token" from the page; the Toast on screen; fetching a release's ELF.

After merging: the site will describe this before any release has it (v0.11.0 has no console at all). A tag after the merge puts them back in step.

🤖 Generated with Claude Code

https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT

For #68. The design round ended somewhere simpler than a configurable token for Debug Builds: **no Debug Builds**. One firmware has the Debug Console, off until its owner switches it on, with a token that belongs to the device (ADR 0010, Q188 to Q195 in docs/milestones/R1.md). **What changes** - The console and the test commands are in every firmware. `cardputer-adv-debug`, `RORO_DEBUG`, `+debug`, `scripts/debug_flags.py`, `update install … force` and "a Debug Build doesn't install releases" are gone. CI builds one firmware. - **Off by default**, and off when the stored setting is missing or invalid. Off, nothing listens, and neither the task nor the 4 KB ring exists. - **Settings → Debug Console**: the switch, the address, the token (made by the device, 100 bits, shown large), "New token", "Type a token". `DBG` in the Status Bar. - **Challenge and answer** (HMAC-SHA256): the token never crosses the network. Five wrong answers close the console for a minute. **This breaks old clients**, as decided. - **USB serial only:** `debug on`, `debug token <value>`, `debug token new`; `scripts/flash.sh --debug` provisions a device with them. - `scripts/rdbg.py`: `-t`/`--token`, `$RORO_DEBUG_TOKEN`, or the file; fetches a release's ELF to decode a crash. - Docs: ADR 0010 (ADR 0004 marked superseded in part), README, CONTEXT, R1, and the site's developer pages rewritten around "switch the console on". **Measured:** 1,881,799 bytes of flash and 54,700 of static RAM, against 1,851,387 / 54,612 for the release build and 1,874,887 / 58,780 for the Debug Build. **Checked:** 468 host tests (12 new: token, HMAC against RFC 4231, the shared vector with `rdbg.py`, the lockout across the clock's wrap, the settings). On the device: off by default after an update from a Debug Build; switching on; login; `DBG`; `debug on`/`token` refused over the console; six wrong tokens, the lock and the recovery; three `crash abort`, Safe Mode with the console, the crash decoded; the setting surviving an update; `debug off`. **Not checked:** `scripts/flash.sh --debug` over USB (no device on USB); "New token" and "Type a token" from the page; the Toast on screen; fetching a release's ELF. **After merging:** the site will describe this before any release has it (v0.11.0 has no console at all). A tag after the merge puts them back in step. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
twisla added 1 commit 2026-10-06 20:59:40 +00:00
One firmware: the Debug Console in every build, off until switched on, with the device's own token
Site / build (pull_request) Successful in 9s
CI / build (pull_request) Successful in 7m20s
c68741cc46
There is no Debug Build any more (ADR 0010, issue #68, Q188 to Q195). The
console and the test commands are compiled into every firmware. It listens
only while Settings > Debug Console is on, which isn't the default; off,
neither its task nor its 4 KB ring exists. The token is made by the device
and shown on that page; a client proves it knows it by answering a challenge
with an HMAC, so it never crosses the network, and five wrong answers close
the console for a minute. DBG in the Status Bar while it listens.

Over USB serial only: debug on, debug token <value>, debug token new.
scripts/flash.sh --debug uses them to set a device up with the developer's
token. scripts/rdbg.py takes the token from -t, $RORO_DEBUG_TOKEN or the
file, answers the challenge, and fetches a release's ELF to decode a crash.

Gone: the cardputer-adv-debug environment, RORO_DEBUG, the +debug version,
scripts/debug_flags.py, update install ... force, and the rule that a Debug
Build doesn't install releases. Old clients and old firmwares don't talk to
each other.

Against the builds it replaces: 30 KB more flash and 88 bytes more static
RAM than the release, 4 KB less RAM than the Debug Build. 468 host tests.
Checked on the device: off by default, login, the pause after wrong tokens,
Safe Mode with the console, the setting surviving an update, debug off.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
twisla added 1 commit 2026-10-06 21:50:44 +00:00
Debug Console: the listener is checked and retried, and debug off <seconds> comes back by itself
Site / build (pull_request) Successful in 14s
CI / build (pull_request) Successful in 7m10s
1874a1b586
The framework's server begin() fails without a word: the console's task now
asks whether it listens, says so, and tries again. `debug off <seconds>`
closes the console and reopens it after the pause, which is the only way to
test its closing and reopening from afar.

Checked on the device: 25 closings and reopenings, each back a second after
the pause. Free heap dips about 270 bytes for each connection the device
closes and is all back two minutes later (TCP keeps a closed connection that
long): not a leak.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
twisla merged commit 6be05b782d into main 2026-10-06 21:58:27 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: twisla/roro9stack#70