Repository navigation
package-m3-demo: a "just run it" disk for the uci-m3 variant - #275
Merged
Merged
Conversation
`make package-m3-demo` builds dist/m3-demo/ from a clean tree: the M3 client PRG (default target en.wikipedia.org /wiki/Commodore_64, typed-host prompt), a .d64 holding it alone, and a README with the source commit, build flags, sha256s, required firmware (esp-tls/m3 f2e46946+), the M3-SPEC version and errata, hardware, usage, three test URLs and what an unsupported device shows. The script rebuilds from clean to prove the PRG reproduces, and reads it back out of the .d64 with c1541. It does not touch PACKAGE_VARIANTS or the shipped products. tools/uci/rig_https_m3_demo.py runs the disk the way a user does: mounted on drive A, LOAD"*",8,1 / RUN, the default fetch to completion, then a name-mismatch negative (94, $8D). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The first fetch's CONNECTION CLOSED is still on screen when the negative starts; the first run matched it at once. Run 1 (that bug) still PASSED the drive LOAD and the default fetch (751,108 B == Content-Length). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…upstream PR slot The firmware requirement is now "M3-SPEC v1 + errata v1.1/v1.2 firmware (validated on esp-tls/m3 f2e46946)": f2e46946 is a local branch, not fetchable upstream. The README carries a marked slot for the 1541ultimate upstream PR numbers (UPSTREAM_PRS fills it). dist/m3-demo/ gains SHA256SUMS, so the directory is exactly the pre-release's asset set. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…v-275) - "What an unsupported device shows" is labelled as per the M3 spec and the model tests, not observed on hardware with this image. - The timing and size claims are replaced by numbers measured on THIS image (PRG ed646d56) from the mounted .d64 on a U64E at 48 MHz: Wikipedia 751,108 B == Content-Length in 207 s from G to CONNECTION CLOSED; github.com/robots.txt 14,181 B == Content-Length in 7 s; the nip.io name refused with 94. The unmeasured 1 MHz claim is gone. tools/uci/rig_https_m3_demo.py now times the default fetch and runs the github URL too. - The nip.io negative's dependence on nip.io and on Wikipedia's address is stated; "validated on an Ultimate 64 Elite (U64E)" only; the SHA256SUMS comment names its files. PRG and .d64 bytes are unchanged. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… tree make ran with the caller's environment, and a recipe sees the outer `make package-m3-demo VAR=...` through MAKEFLAGS, so HTTPS_SNI=, VIC_BLANK=0 and the like reached the demo build and its README. make now runs under env -i (PATH, HOME, TMPDIR), and build/flags.stamp must show the uci-m3 cfg and only the backend's two -D's, build/https_host.inc the demo target. A modified or untracked file now stops the build instead of annotating the README: the README names a commit, and the PRG must be what it builds. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… helpers The boot prints "DHCP OK" before the menu, so waiting for it after 'I' returned at once and 'G' could land while the re-init ran; a failing re-init read as a pass. press_init (rig_https_m3.py) counts only text after the menu line and waits for the whole address. Both M3 rigs use it. The demo rig imports rig_https_m3's helpers and judges the negative with its full verdict_refuse (status line code and on screen, no REQUEST SENT), over the rows from the negative's own banner on. It restores drive A fully (our /Temp upload deleted, the drive switched back off if it was, checked against what was read), and honours C1541. test_device_prep: the discovery rule cannot see either M3 rig (no comb profile; the demo boots from the drive), so they are registered by name. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…delete fw 3.15 (3a1ff9ff) reports a mounted image as image_file='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/Temp/cache/ upload/image.d64' with image_path empty, so the restore's 'path and file' test would never re-mount a disk the operator had in drive A, and the /Temp delete (keyed on image_path == /Temp) never fired. The upload is overwritten per mount, so there is nothing to delete. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
detect_crypto_profile knew two answers. A BACKEND=uci-m3 build has neither the nistcurves equate nor a row generator, so it fell through to the fail-closed "reu" answer: prep ENABLED a 16 MB REU for an image that links no 6510 crypto, and every M3 hardware run so far had one, though the demo README says "No REU". It now recognises the M3 adapter (m3_owned) as profile "none", after the manifest equate (still authoritative) and before the fail-closed default (still what anything unrecognised gets). For "none", prep sets RAM Expansion Unit Disabled (unreadable state writes too: off is the safe direction; a refused write is exit 4), so a no-REU claim is measured on the device, recorded in device_state.json. The preflight treats it like onchip: no device call. Red (old modules): 5 new cases fail, among them the M3 preflight touching the device and prep leaving/turning the REU on. Green: all pass. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
c72352f said the upload is overwritten per mount. The second hardware run shows otherwise: the U64E (fw 3.15 3a1ff9ff) named it /Temp/cache/upload/image_1.d64, next to the first run's image.d64, which matches the harness's own note (a repeat is numbered, not overwritten). Each run leaked one .d64 into the RAM disk. The restore now FTP-deletes the file its mount created, never one that was mounted before, and only under /Temp/. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…n artifact dir adv-m3demo on c72352f. B1: wait_after fell back to the whole screen while its anchor was not yet printed, and push_keys returns before the KERNAL drains the keys, so in the demo's steps 1b and 2 the previous fetch's CONNECTION CLOSED satisfied the wait: a FAIL, and fetch_in_flight=False skipped the socket teardown. The fallback is gone (nothing counts until the anchor is on screen) and the demo waits for each fetch's own banner first. press_init never needed it: the menu sits at row 22 at the lowest and a good re-init prints four rows. press_init also matched an address still being printed; it now needs the screen to read the same twice. B2: an earlier upload in drive A (/Temp/...) was re-mounted by name, which can be OUR disk where the firmware overwrites image.d64; it is now left empty with a warning. A mount that failed after drive_on left the drive on unannounced; the restore now runs once drive A is touched, and undoes only the power when nothing was mounted. Both M3 rigs passed artifact_dir=RUN_DIR, the base dir the next run overwrites; they now use rig_https_local._create_run_dir like the others. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ags.stamp adv-m3demo N1: check_stamp read the flags but not the stamp's TOOLCHAIN line, so a ca65 shim on PATH that adds a -D built a different PRG with a README that said nothing. Asserting a toolchain hash would pin one machine's cc65 build; recording it is the cheaper half and makes a shim visible in the release's own provenance. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…, never raising Reverts ec7640a's 'earlier /Temp upload -> leave drive A empty': the U64E numbers a repeated upload (image_1.d64), so the operator's file is intact and ejecting it was the defect (adv-m3demo, B2 withdrawn). A mount that failed after drive_on still powers the drive back off, now with a warning. F3: delete_upload caught OSError/error_perm only; ftplib.error_temp, error_reply and error_proto escaped, and since it ran BEFORE the re-mount and drive_off, an FTP 4xx left the operator's disk unmounted and the drive on. It now catches ftplib.all_errors and runs last, after the comparison, and says so when our mount reported no image_file. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
adv-m3demo F2: make BACKEND=uci-m3 HTTPS_BODY_TO_REU=1 links the REU viewer and streams the body into the REU, but classified 'none', so prep would switch the REU OFF under it. 'none' now needs m3_owned AND no viewer_enter; anything else falls through to the fail-closed 'reu'. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
adv-m3demo F1: the device is prepared for A only, and A (uci-m3) now gets the REU switched off, so a comb or REU-profile B would run without one (the ~44 min spin). B's labels must classify 'onchip'; anything else is a fatal exit 2 before the lock. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
9958997's ab guard names the comb profile, so the discovery rule finds rig_https_m3.py by itself and the registration guard said to drop it. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… run Firmware line as decided: validated on esp-tls/m3-master 3a1ff9ff (fw 3.15, FPGA 126, ESP 1.309); the stale 'LOCAL branch f2e46946' comment is dropped. Figures from rig_https_m3_demo.py on PRG e4814599 (REU disabled by device prep, per its device_state.json). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
JC-000
force-pushed
the
feat/m3-demo-package
branch
from
October 6, 2026 18:28
6b9225f to
b54fcb6
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
make package-m3-demobuilds a "just run it" disk for theBACKEND=uci-m3variant (#271): TLS runs on the Ultimate's ESP32, and the C64 speaks HTTP. It writes four files todist/m3-demo/, the release assets:c64-https-uci-m3-demo.prg: 6,519 B, sha256e4814599c783aeefe03d37b194debc067c18afff3589069a97af8630edb34e24. Default targeten.wikipedia.org /wiki/Commodore_64; host and path can be typed.c64-https-uci-m3-demo.d64: sha25628a8741fe7cb0b152901a24634e440a548380a41b710f1e15ead7959d00f98ba. It holds that PRG alone, asc64-https-m3.README.txt: provenance (commit, make line, flags, toolchain path + sha256), what it needs, how to run it, three test URLs, and measured results.SHA256SUMS: sha256 of the other three files.Scope:
PACKAGE_VARIANTS,make packageand the shipped products are untouched. No release or tag was created.The build script (
tools/package/build_m3_demo.sh)git diff --quiet HEADcheck exits 0 with only an untrackedsrc/stray.spresent.?? src/stray.s.env -i PATH HOME TMPDIR), so neither an exported knob nor one passed on themake package-m3-demo VAR=…command line (it arrives through MAKEFLAGS) reaches the demo build. It then assertsbuild/flags.stamp: BACKEND=uci-m3,-C cfg/c64-https-uci-m3.cfg, exactly-D BACKEND_UCI=1 -D BACKEND_UCI_M3=1, and the demo target inhttps_host.inc.make package-m3-demo HTTPS_PORT=8443built PRG217e043ewith-D HTTPS_PORT=8443in the README.env -idies on "unexpected defines: … -D HTTPS_PORT=8443".217e043ebehind a silent README.c1541reads the PRG back out of the .d64 byte for byte.C1541=overrides the tool, in the script and the rig.Rigs
tools/uci/rig_https_m3_demo.pymounts the .d64 on drive A, runsLOAD"*",8,1/RUN, then fetches three targets:github.com /robots.txt: HTTP 200, complete;rig_https_m3.verdict_refuse(94 on screen,$8D, no handle, no REQUEST SENT), using only rows after its own banner.press_initnow counts only text after the menu line and needs the finished address, read the same twice.wait_afterno longer falls back to the whole screen, and the demo waits for each fetch's banner first. Before, the previous fetch's CONNECTION CLOSED could end a wait and skip the UCI rigs release the DeviceLock over a live firmware socket on an abnormal exit (exception / Ctrl-C) — next lane's reset poisons the lease #234 socket teardown.adv-m3demo/race_wait_after.log(it returns on poll 1).image_file);drive_on;/Temp/cache/upload/image[_N].d64upload is deleted over FTP, last, withftplib.all_errorscaught.adv-m3demo/delete_aborts_restore.log. An FTP 421 escaped the delete, which ran first, leaving calls ==['unmount']: the operator's disk not re-mounted and the drive left on._create_run_dir(...), not the base dir._reu_preflight.py,_device_prep.py). A uci-m3 build was classified as REU-profile, so prep ENABLED a 16 MB REU, though the README says "No REU"."none":m3_ownedpresent,viewer_enterabsent, and no nistcurves equate (which stays authoritative).HTTPS_BODY_TO_REU=1(it links the viewer) still classifiesreu.rig_https_m3 abrefuses a B that is not on-chip. The device is prepared for A, which now runs with the REU off. Red by code reading: the previous rig never classifiedargv[5].tools/test_device_prep.py: the demo rig (it boots from the drive, so the discovery rule cannot see it) is registered by name;rig_https_m3.pyis now discovered.prepare_deviceremoved gives 34 passed, 1 failed when registered, but 35/0 when unregistered (the old blind spot). Clean: 35/0.Acceptance (head
b54fcb6, on master489efd0)make package-m3-demo: PRGe4814599…, .d6428a8741f…,shasum -c SHA256SUMSOK. The bytes are identical to the build on the c26e268 base, where the hardware ran.check_m3_client.py: 50/50, 335 assertions.mutate_m3_client.py: 62 mutants, 62 killed. No M3 check tool or uci-m3 source changed between c26e268 and 489efd0.test_device_prep+test_reu_preflight+test_rig_skip_contract: 63 passed.$0801-$9FFF, last used$2175, 32,394 B free.Hardware
U64E fw 3.15 git
3a1ff9ff, FPGA 126, core 1.50; 48 MHz; DeviceLock; PRGe4814599, .d6428a8741f. Both runs had the REU Disabled by device prep (device_state.jsonin each per-run dir: profilenone, wantedDisabled, REU Enabled → Disabled).rig_https_m3_demo.py, 2026-10-06): PASS./robots.txt: HTTP 200, 16,739 B == Content-Length, 9 s.94,CERTIFICATE NAME MISMATCH: 0x00000004,$8D,m3_owned=0.deleted /Temp/cache/upload/image.d64.rig_https_banner.py: PASS. The banner namesEN.WIKIPEDIA.ORG; HTTP 200, 751,848 B == Content-Length; the fetch had settled when its state was read.🤖 Generated with Claude Code