The device can install the project's releases from Gitea itself, with no PC and no card (docs/milestones/R1.md, Q162-Q174).
Settings > Firmware:Latest release (check, then a release page with the tag's message and Install), Older releases (the last ten, going back asks differently). Settings > Check for updates: once a day, one Toast per version, never installs by itself.
The download goes straight into the inactive slot through the existing install path: signature checked after 160 bytes, hash at the end, then Probation and rollback as usual.
Trust: the two ISRG roots only (ADR 0009). The Update File's signature is still what decides what installs.
lib/release (host-tested): a streaming JSON scanner, the release reader, HTTP heads, chunked bodies, URLs, the decisions. 456 host tests pass.
Debug Builds get update pretend | probe | damage | daily to try what can't be tried otherwise.
Follow-ups: #52 (auto-install), #53 (release channel), #54 (resume a download).
The memory finding
A TLS connection to the server peaks at about 52 KB of heap, with or without checking the certificate. With IRC connected a check left 3 KB and a download 836 bytes. A check, list or install a person asks for now makes IRC step aside and reconnect; the lowest free heap during a download with IRC connected is 38 KB. The daily check never interrupts IRC, so with IRC connected for days it doesn't run.
Checked on the device
The real signed v0.10.0 installed twice (console, then the screen), restarted and confirmed on Probation; a cut download, a flipped signature byte and a flipped image byte are each refused; github.com, example.com and four badssl.com variants are refused; the daily check ran and announced by itself, and stayed quiet with IRC connected. Full table, and what was not checked (the certificate name in isolation, retry and suppression on the device), in docs/milestones/R1.md.
.gitea/workflows/ci.yml: pushes to branches other than main no longer run anything, so a pull request runs CI once instead of twice (once for the push, once for the PR). This PR is the first to run that way.
Closes #6.
## What
The device can install the project's releases from Gitea itself, with no PC and no card (docs/milestones/R1.md, Q162-Q174).
- **Settings > Firmware:** *Latest release* (check, then a release page with the tag's message and Install), *Older releases* (the last ten, going back asks differently). **Settings > Check for updates:** once a day, one Toast per version, never installs by itself.
- **The download goes straight into the inactive slot** through the existing install path: signature checked after 160 bytes, hash at the end, then Probation and rollback as usual.
- **Trust:** the two ISRG roots only (ADR 0009). The Update File's signature is still what decides what installs.
- `lib/release` (host-tested): a streaming JSON scanner, the release reader, HTTP heads, chunked bodies, URLs, the decisions. 456 host tests pass.
- Debug Builds get `update pretend | probe | damage | daily` to try what can't be tried otherwise.
- Follow-ups: #52 (auto-install), #53 (release channel), #54 (resume a download).
## The memory finding
A TLS connection to the server peaks at about 52 KB of heap, with or without checking the certificate. With IRC connected a check left 3 KB and a download 836 bytes. A check, list or install a person asks for now makes IRC step aside and reconnect; the lowest free heap during a download with IRC connected is 38 KB. **The daily check never interrupts IRC, so with IRC connected for days it doesn't run.**
## Checked on the device
The real signed v0.10.0 installed twice (console, then the screen), restarted and confirmed on Probation; a cut download, a flipped signature byte and a flipped image byte are each refused; github.com, example.com and four badssl.com variants are refused; the daily check ran and announced by itself, and stayed quiet with IRC connected. Full table, and what was **not** checked (the certificate name in isolation, retry and suppression on the device), in `docs/milestones/R1.md`.
## One change outside #6
`.gitea/workflows/ci.yml`: pushes to branches other than `main` no longer run anything, so a pull request runs CI once instead of twice (once for the push, once for the PR). This PR is the first to run that way.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
A streaming JSON scanner (a 33 KB list of releases costs a few hundred
bytes), the release reader built on it, HTTP response heads and chunked
bodies, URLs, and the decisions: which release is an update, whether to
announce it, and which download URLs the device takes. Tested against the
real answers of git.twis.la.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
The roots (ISRG X1 and X2), an HTTPS client that reads the answer as a
stream, GiteaReleases (the latest and a list of ten), the Update
Service's requests, install from Gitea through the existing install path,
the daily check's schedule, the Check for updates setting, and console
commands: update check | list | status | install <tag>.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
A release downloads straight into the inactive slot through the existing
install path: the signature is checked after 160 bytes, before anything
is written, the hash at the end. Tried on the device against the real
server: a download cut short, a flipped byte in the signature and one in
the image are each refused with the running firmware untouched; the real
v0.10.0 installed, restarted, and confirmed itself on Probation.
A TLS connection to Gitea peaks at about 52 KB of heap whether or not the
certificate is verified. With IRC connected (66 KB free) a check left 3 KB
and a download 836 bytes. A check, list or install a person asks for now
makes IRC step aside (holdForUpdate) and come back after: the lowest free
heap during a full download with IRC connected is 38 KB. The daily check
never interrupts IRC; with IRC up it waits. A TLS connection starts with
80 KB free (it was 55).
Debug Builds get test knobs: update probe <host>, update damage cut|flip,
update pretend <version>.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
Latest release (checked on Enter, or c), Older releases (the last ten,
newest first), a release page with the tag's message, and an install
dialog; going back to an older release asks differently. A failed check
someone asked for shows a Toast. A Debug Build shows the latest release
and says it can't install it: it would take its console away.
Tried on the device: a check, the list, the release page, the dialog
(Cancel is the default; Back cancels), and the install from the screen
with its progress screen, then the restart into the release build and its
confirmation.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
The announcement was cut at the notification's 48 bytes; it now reads
"v0.11.0 is out: see Settings > Firmware". README: Updates from Gitea
and its limits. ADR 0009: the device trusts the two ISRG roots. R1.md:
what was built and the checks on the device, with what wasn't checked.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
A branch with an open pull request ran twice per push: once for the push,
once for the pull request. Pushes to main still run the tests and publish
the badges; every other branch is tested by its pull request.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
twisla
merged commit df2aaddbc8 into main2026-10-06 14:29:02 +00:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Closes #6.
What
The device can install the project's releases from Gitea itself, with no PC and no card (docs/milestones/R1.md, Q162-Q174).
lib/release(host-tested): a streaming JSON scanner, the release reader, HTTP heads, chunked bodies, URLs, the decisions. 456 host tests pass.update pretend | probe | damage | dailyto try what can't be tried otherwise.The memory finding
A TLS connection to the server peaks at about 52 KB of heap, with or without checking the certificate. With IRC connected a check left 3 KB and a download 836 bytes. A check, list or install a person asks for now makes IRC step aside and reconnect; the lowest free heap during a download with IRC connected is 38 KB. The daily check never interrupts IRC, so with IRC connected for days it doesn't run.
Checked on the device
The real signed v0.10.0 installed twice (console, then the screen), restarted and confirmed on Probation; a cut download, a flipped signature byte and a flipped image byte are each refused; github.com, example.com and four badssl.com variants are refused; the daily check ran and announced by itself, and stayed quiet with IRC connected. Full table, and what was not checked (the certificate name in isolation, retry and suppression on the device), in
docs/milestones/R1.md.One change outside #6
.gitea/workflows/ci.yml: pushes to branches other thanmainno longer run anything, so a pull request runs CI once instead of twice (once for the push, once for the PR). This PR is the first to run that way.🤖 Generated with Claude Code
https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT