docs: the 2026-08-31 pass over the small items

CAMPAIGN-LOG: the rail policy, the /cool/status changes, the armed-kill
placement, the image trims with the 20260831130656 manifest, the lid IR
lamp step, the SDIO count, the lens-shading search, the debug-kernel
assessment, and the bench cleanup; the four closed items in the
superseded notes.

BRINGUP: item 18 closed (the trims landed), items 19 to 22 are now 18 to
21; the release rootfs size fact reads the measured 89 MiB.
This commit is contained in:
ScottW514
2026-08-31 10:19:20 -04:00
parent b334c4cc33
commit c01699ee94
2 changed files with 175 additions and 21 deletions
+6 -21
View File
@@ -1077,7 +1077,8 @@ is committed.
`{version, download_url}` → resumable download to `/data/glowforge.fw` →
verify against `/glowforge/pubkeys` → apply to the INACTIVE slot →
`fw_setenv mmcpart mmcroot` → reboot. Factory `rootfs.ext4` is 65 MiB; the
ForgeFIRM rootfs is ~141 MB used, so it fits a 200 MiB slot with headroom.
ForgeFIRM release rootfs uses about 89 MiB, so it fits a 200 MiB slot with
headroom.
- **Facts about the factory 2024 firmware** (learned during the slot install):
no `/factory/imgN` mounts, the generic `fw_env.config` points at the WRONG
device (use the per-device `fw_env_mmcblk2.config` — ffboot's selection
@@ -1328,23 +1329,7 @@ Open items only. Anything closed is in `CAMPAIGN-LOG.md`.
are established. A pause on contact, on the factory's shape, would be
the first use.
18. **Image trims not taken.** Two rootfs reductions the kernel review left
on the table, each wanting a check before it lands. The `python3`
meta-package installs `python3-modules` (tkinter, idle, 2to3, pydoc,
ensurepip, venv, the debugger, doctest, asyncio, multiprocessing,
xmlrpc: ~10 MB) where the apps declare `python3-core` and a few modules,
so replacing it with the explicit set needs an import audit of gfcloud,
gfhome, gfhardware and gfutilities (the cloud tests are the check).
`libgnutls30`, `libunistring5`, `nettle` and `libgmp10` (~4.9 MB) sit on
the rootfs with no package depending on them and no binary linking them;
a `PACKAGE_EXCLUDE` experiment on a build would name the holder if there
is one. Five helper modules are built and not shipped (`crc7`,
`crc-ccitt`, `libcrc32c`, `st-accel-spi`, `st-sensors-spi`: 0.1 MB,
harmless). The debug features stay in the release kernel by decision
(`KPROBES`, `PERF_EVENTS`, `BPF_SYSCALL`, `DEBUG_FS`, `DEVMEM`,
`MAGIC_SYSRQ`: no runtime cost unused, root-only exposure, and root can
load modules anyway).
19. **A sender change while a job runs: discussion.** Today a sender that
18. **A sender change while a job runs: discussion.** Today a sender that
disconnects mid-job leaves the motion running to the end of what the
controller holds, with the window closed and fire suppressed (the
consent belonged to the displaced session), so the job finishes dark
@@ -1363,7 +1348,7 @@ Open items only. Anything closed is in `CAMPAIGN-LOG.md`.
running on leaves a clean stop position but wastes the piece. Decide
with the gapless pause and resume item (16), which owns the resume
mechanics.
20. **The flow check while the tube is lit.** The arm-time heater check
19. **The flow check while the tube is lit.** The arm-time heater check
starts at the session open, so with a prompt press the tube is lit
for most of its window, and a lit CW window adds about 1.5 C to the
rise (0.5 C at 45 % density) against a 1.6 C margin; on top of that the
@@ -1396,7 +1381,7 @@ Open items only. Anything closed is in `CAMPAIGN-LOG.md`.
remains; a scope on the two sensor lines during a cut is the next
instrument. It sits inside the ceiling's 2 C hysteresis and the flow
check reads means, so it is a measurement item, not a gate item.
21. **Laser power-good: what the line means.** `cnc/laser_pgood` and its
20. **Laser power-good: what the line means.** `cnc/laser_pgood` and its
sampled count are defined in the UAPI (active low, one sample every
~3.9 ms), the facts bank records that the sampled count reads 0 through
real cutting, and the cooling engine warns
@@ -1408,7 +1393,7 @@ Open items only. Anything closed is in `CAMPAIGN-LOG.md`.
scope against `hv_current` through an armed cut, its meaning written
into the facts bank and the UAPI, and then either a warning that means
something or no warning.
22. **Initial commissioning: measure and set the machine's own numbers
21. **Initial commissioning: measure and set the machine's own numbers
methodically.** Every tunable that was measured on the bench machine
and shipped as a default varies from machine to machine: the flow
check's bands and `cool_flow_rise`, the tube's heat coefficients
+169
View File
@@ -4559,6 +4559,121 @@ check takes the tube's share off; `cool_flow_rise` needs no warm-end
value. Records `bench-data/flow_warm_log_20260829b.txt`,
`flow_warm_results_20260829b.json`.
## 2026-08-31: the low-hanging items, one pass
One session over the small open items, grouped into one build and one
bench window. Host proof first, bench facts second, build third.
**Rail policy (item 8, closed).** The GRBL driver wrote `cnc/enable` at
init and at homing resume under the broker too. Now both writes run only
when the driver opened the device itself (`!gfio_pulse_inherited()`);
under the broker forgectrl owns the rail. The kernel probe starts in
`disabled`, so a standalone controller still needs the write.
grblHAL-glowforge fa9ed78; SERVICES.md "Rail policy" retagged
`[implemented]`, no `[contract]` item is left. Proof: the null-sink build,
`laser_stream_test.py` and `laser_lifecycle_test.py` green; a `$H` homing
pass on the built image is the bench check.
**`/cool/status` (item 8, closed).** Two changes in forgectrl 0e907f7.
`armed` in the document now comes from `coolfmt_armed()`: the last
report's flag while that report is within the 5 s timeout, false after
(`tests/coolfmt_test.c`, five cases). A run session that never had the
armed window open gets a zero-length smoke phase (`session_armed`,
cleared as a session opens and set on any armed tick), so a homing
motion, a hunt or a dark job goes run, thermal gate, idle. The cloud
hunt keeps reporting `run`: the cloud catalog asserts it (the hunt's
run phase carries the factory's motion fan profile), so the client is
right and the engine changed. forgectrl host tests 14 of 14 under
`-Werror`.
**`laser.armed-kill` placement (item 12, decided).** It stays in the
laser domain. The always-required core carries the emission witness with
the armed-window disarm; the kill path is the forgectrl supervisor, and
the `forgectrl/src/main.c` entry in the test's map re-requires it on each
forgectrl change. Recorded in the site's Acceptance page (forgefirm-docs
657d32e).
**Image trims (item 18).** The import audit (an AST pass over
python3-gfhardware, gfutilities, forgetest and the bench scripts against
poky's `python3-manifest.json`) maps the runtime imports to `python3-core`
plus `fcntl`, `json`, `logging`, `netclient`, `threading` (gfhardware and
the apps) and `datetime`, `io`, `json`, `logging`, `threading`
(gfutilities); forgetest adds `compression`, `crypt`, `io`, `math`,
`netclient`, `netserver`, `shell`, `statistics`. The recipes declare
those (meta-openglow 722bc00, forgetest.bb) and the image drops the
`python3` meta-package that pulled `python3-modules`. The four libraries
were not orphans: pkgdata names `libmicrohttpd` (its `https`
PACKAGECONFIG) and `ulfius` (`WITH_GNUTLS`) as the holders of gnutls,
which pulls nettle, gmp, libunistring and libtasn1. forgectrl serves
plain HTTP and no websockets, so `libmicrohttpd_%.bbappend` removes
`https` and ulfius builds with `-DWITH_GNUTLS=off -DWITH_WEBSOCKET=off`.
forgefirm b334c4c. Built as release 20260831130656: the manifest lists 30 `python3-*`
packages where the previous image had 62 (`python3-modules`,
`python3-tkinter`, `-2to3`, `-asyncio`, `-idle`, `-pydoc`, `-venv` and
the rest of the meta-package family gone; `python3-core`, `-fcntl`,
`-json`, `-logging`, `-netclient`, `-threading`, `-datetime`, `-io` and
what `requests`, `urllib3` and `websocket-client` pull stay), and
`libgnutls30`, `nettle`, `libgmp10` and `libtasn1-6` are gone.
`libunistring5` stays: `libidn2-0` holds it, and `libcurl4` holds
`libidn2-0` (curl's IDN support, about 1 MB together; not taken). The
release rootfs ext4 went from 151.3 MB to 129.8 MB and the wic.gz from
44.0 MB to 35.1 MB. Platform change: the full campaign is owed on this
image, and the cloud tests are the module check. The dev image is 20260831141210; against the release it adds only the
emulator fixtures, `python3-statistics` (declared by forgetest for the
bench scripts, with `python3-numbers` behind it) and `libgmp10` (gdb,
from `tools-debug`), so the campaign on it proves the release module set.
**Lid IR against the lamp (item 4).** The four `pic/lid_ir_*` channels
read at eleven `lid_led` levels (sysfs brightness 0 to 1023, 2 s settle,
three samples 1 s apart), lid closed, machine idle, on dev 20260831021059:
| lid_led | ir1 | ir2 | ir3 | ir4 |
|---|---|---|---|---|
| 0 | 2 | 2 | 1 to 2 | 2 |
| 64 | 18 to 19 | 17 | 18 to 19 | 20 |
| 128 | 32 to 33 | 32 | 33 to 35 | 34 to 35 |
| 192 | 43 to 44 | 42 to 43 | 44 to 45 | 45 to 46 |
| 256 | 54 to 56 | 54 to 55 | 57 to 60 | 60 to 61 |
| 384 | 77 | 75 to 77 | 81 to 83 | 82 to 85 |
| 512 | 96 to 98 | 95 to 97 | 103 to 104 | 104 to 105 |
| 640 | 115 | 113 to 115 | 121 to 123 | 123 to 124 |
| 768 | 131 to 133 | 131 to 133 | 139 to 140 | 141 to 143 |
| 896 | 146 to 148 | 147 to 148 | 157 to 160 | 157 to 159 |
| 1023 | 161 to 162 | 161 to 163 | 172 | 173 to 177 |
A straight line on every channel, about 0.16 counts per unit, channels 3
and 4 about 7 percent above 1 and 2. The factory header's alert (275)
and critical (688) sit above a fully lit lamp, and its baseline (3)
matches the dark floor (2): the factory rides out the lamp by choosing
thresholds above it. What stays unproven is the header's channel
mapping, since all four channels behave alike while the header leaves
the third and fourth quartiles at zero. The next cloud job's header is
the comparison.
**Wi-Fi SDIO (item 11).** `dmesg | grep -c "sdio .* failed"` read 0 after
30 min on dev 20260831021059.
**Lens-shading files (item 6).** `/data` is one partition for every slot,
and a search of it (names with cam, lenc, regs, lens, shad, calib, four
levels deep) found no camera register file. If the factory pushes such
files, the app fetches them at run time; a factory-slot session with the
app running is the step before any reimplementation.
**Debug-kernel checks (item 10, assessed).** Not a quick check: a module
unload powers the 40 V rail off (`stepper_power_off` in the remove path),
and a forced `-EPROBE_DEFER` needs the 40 V regulator or the SDMA device
unbound under the module's probe. Both are the rail-cycle gamble the
rail policy exists to avoid. The item now says so; it waits for a bench
slot that accepts the gamble.
**Bench hygiene.** The 2026-08-20 factory-session shim was still on the
board: `/data/manufacturing/run.sh` (the app launcher with the bench CA)
and `/data/glowforge.conf` (server URLs and pin pointed at the bench
proxy), while their `/data/bench-scratch/f1` was already gone. Removed as
the tool's teardown does (no `glowforge.conf.orig` existed, so the conf
is deleted and the factory app runs on its built-in defaults). `/data`
holds only factory state and ForgeFIRM's own files again.
## Superseded status notes
### Shared machine services — remaining polish, as listed 2026-08-13
@@ -6026,6 +6141,60 @@ The first live recording on image 20260831021059 then fit all seven rungs and th
The corner look on image 20260831021059 with the machine's own recorded curve: the operator lowered the corner rolloff from the default 2 to 1.5 and expects to go lower - the knob works, its right value is per machine, and the commissioning item gains a side-by-side chooser (the same pattern cut at several settings, the operator picks by eye, Apply writes the winner) as the tool for it. With that, every question the tree-root working file `LASER_DUTY_WORK.md` held is answered or homed: the model decision (density only), the measured curves, the floors, the switch's rise and removal, the rolloff, the recorder, and the raster proofs. Its conclusions live in BRINGUP's "Laser control (GRBL mode)" and the facts bank, its dated record in this log, and the file is deleted per its own charter. BRINGUP's "Next work" item 16 (the laser power model) closes and the later items renumber down by one (17 to 23 become 16 to 22).
### Rail policy (item 8 bullet), closed 2026-08-31
Closed: grblHAL-glowforge fa9ed78 writes `cnc/enable` only standalone;
SERVICES.md "Rail policy" is `[implemented]`. The entry above has the proof.
- **Rail policy** (the one `[contract]` item left in SERVICES.md). The GRBL
driver still writes `cnc/enable` at init and at homing resume —
idempotent, since the rail is already up, so this is tidiness rather than
a bounce source.
### `/cool/status` cosmetics (item 8 bullet), closed 2026-08-31
Closed: forgectrl 0e907f7, `armed` from a fresh report only and a
zero-length smoke phase for a session that never armed. The hunt keeps
reporting `run` by design. The entry above has the proof.
- **`/cool/status` cosmetics.** The endpoint echoes the last reported `armed`
flag even when that report is stale (`report_age_s` tells the truth), and a
gfcloud homing session reports every motion as a job, so the engine cycles
run → smoke → idle per motion. Both are silent and safe.
### The armed-kill core question (item 12), closed 2026-08-31
Closed: `laser.armed-kill` stays in its domain, recorded in the site's
Acceptance page (forgefirm-docs 657d32e).
whether `laser.armed-kill` belongs in the always-required core rather
than its domain is still an open call (the core carries the emission
witness).
### Image trims not taken (item 18), closed 2026-08-31
Closed: both reductions landed in forgefirm b334c4c and meta-openglow
722bc00 and are on release 20260831130656 (the entry above has the
manifest). The five unshipped helper modules and the debug features
stay as decided there.
18. **Image trims not taken.** Two rootfs reductions the kernel review left
on the table, each wanting a check before it lands. The `python3`
meta-package installs `python3-modules` (tkinter, idle, 2to3, pydoc,
ensurepip, venv, the debugger, doctest, asyncio, multiprocessing,
xmlrpc: ~10 MB) where the apps declare `python3-core` and a few modules,
so replacing it with the explicit set needs an import audit of gfcloud,
gfhome, gfhardware and gfutilities (the cloud tests are the check).
`libgnutls30`, `libunistring5`, `nettle` and `libgmp10` (~4.9 MB) sit on
the rootfs with no package depending on them and no binary linking them;
a `PACKAGE_EXCLUDE` experiment on a build would name the holder if there
is one. Five helper modules are built and not shipped (`crc7`,
`crc-ccitt`, `libcrc32c`, `st-accel-spi`, `st-sensors-spi`: 0.1 MB,
harmless). The debug features stay in the release kernel by decision
(`KPROBES`, `PERF_EVENTS`, `BPF_SYSCALL`, `DEBUG_FS`, `DEVMEM`,
`MAGIC_SYSRQ`: no runtime cost unused, root-only exposure, and root can
load modules anyway).
## Reference notes
### Head-IRQ source validation — the beam-emission hypothesis