The pthresh ladder on scrap puts the tube's two thresholds far apart: the discharge strikes between 2 and 3 percent duty, but nothing lases usefully below 16 percent (PWMSAR 20), and the rungs between show only a spot at each line start. $35 ships at 16 (grblhal-glowforge 9466f76, pinned here). The drill said current lift-off and first mark share a rung; this run falsifies that, so its docstring and read-the-material text now name both thresholds and warn that a start-of-line spot is below the threshold, not at it. A start-of-line spot is also what a full-power leak at a kernel run start would look like, so laser_stream_test gains a ladder session (rule 10): every FIRE tick must ride a commanded duty, and the fire ticks must divide evenly across rungs. Both hold exactly - six commanded duties, no others, and 28296 fire ticks on every rung - so the spots are the tube, not the stream. The harness now derives its expectations from the floor, which moves the M4 session's S500 plateau from 63 to 73. laser.power-floor is a new auto acceptance test, the suite's only non-firing one: a machine must actually carry the commissioned floor, since stored settings beat freshly baked defaults. Three cloud cuts of one square at Precision Power 1, 100 and Full Power show what the analog path is competing with: the power byte is pinned at 127 in all three, dose is FIRE-bit density on a fixed 7-tick period with the on-count dithered between adjacent integers, and the power setting never reaches the machine at all. Facts bank and item 17 carry the numbers; CAMPAIGN-LOG carries both sessions.
forgetest - the ForgeFIRM release acceptance tool
The daemon behind http://<machine>:8090/ on the dev image: runs the
acceptance catalog against the machine, keeps the append-only result log,
decides which results still apply to the image that is running, exports
the release artifact scripts/release.sh gates on, and serves the bench
diagnostics page. The contract - catalog, campaigns, fingerprints,
inheritance, the gate, the coverage rule - is
docs/ACCEPTANCE.md.
Run the host tests
cd forgetest
python3 -m unittest discover -s tests -v
Run the daemon on a workstation (against a mock or a manifest file)
FORGETEST_DATA=/tmp/ft FORGETEST_MANIFEST=../tree-manifest.json \
FORGECTRL_URL=http://<machine>:8080 python3 -m forgetest --port 8090
scripts/manifest-from-tree.py produces tree-manifest.json from the recipe
pins; the coverage lint is python3 -m forgetest.coverage --manifest ....
Environment
| Variable | Default | Purpose |
|---|---|---|
FORGETEST_DATA |
/data/forgetest |
results.jsonl, bench.jsonl, token, export/ |
FORGETEST_MANIFEST |
/etc/forgefirm-manifest.json |
the image manifest |
FORGETEST_PORT, FORGETEST_HOST |
8090, 0.0.0.0 | listener |
FORGETEST_BENCH_DIR |
/usr/share/forgetest/bench |
the installed bench scripts |
FORGETEST_BENCH_DATA |
<FORGETEST_DATA>/bench |
passed to bench tools: where they keep their data files (with GF_HOST=127.0.0.1 and the panel token in GF_TOKEN) |
FORGETEST_MARKER |
/run/forgetest.active |
takeover marker |
FORGECTRL_URL, FORGECTRL_TOKEN_FILE |
http://127.0.0.1:8080, /data/forgefirm/panel.token |
forgectrl client |
GF_SYSFS_ROOT |
/sys/glowforge/ |
kernel module sysfs |
GRBL_HOST, GRBL_PORT |
127.0.0.1, 23 | Grbl TCP |
Adding a test
Register it in the subsystem module under forgetest/suite/ with
@test(...): id subsystem.name, kind, hardware, covers, requires,
always, steps. The body gets a Context (log, check, fail,
prompt, confirm, instruct, sleep, evidence, forgectrl, sysfs,
grbl, takeover). Return normally for PASS, raise runner.Failed for
FAIL. Then run the unit tests and the coverage lint.