forgectrl 6040e64 carries the three fixes behind the pinned 93fb22e: the
test header reached the way the sibling tests reach theirs, the key added
to /status carried in the panel dev-server mock, and the lens test's
carriage driven by the sweep's own steps rather than by a clock. The
shipping behavior is unchanged from 93fb22e; the pin names what passed.
Verified with bitbake -c fetch.
forgectrl 93fb22e fits the lens outcome text in the buffer the supervisor
shares with the probe. grblHAL-glowforge 97be92b takes the lens reference
from the realtime hook rather than settings-changed, so the controller no
longer overwrites the Z it just referenced.
Both verified with bitbake -c fetch at these revisions.
forgectrl dd40dc8 takes the lens onto its hall edge in the motion-verify
window and gates the spawn when it cannot, and carries the per-axis
anchor, homed_axes on /status, and the panel reading Z from its own bit.
grblHAL-glowforge ef0f764 takes that reference as it loads its settings,
re-zeroes the kernel counters the daemon's GPIO steps never reached, and
drops M103.
Both verified with bitbake -c fetch at these revisions.
The three components carry documentation-only commits: the README
becomes an index card, AGENTS.md lands, and the comments that pointed at
the retired BRINGUP.md now point at the documentation site.
The pins move because the tree is already past the image that
20260907224817 built: a comment in the kernel config fragment
glowforge.cfg changed the meta-glowforge-bsp layer content hash, which
the manifest counts as a platform change. Measured against that image's
manifest: meta-forgefirm and meta-openglow-core are unchanged,
meta-glowforge-bsp is not. A fresh image build and a full acceptance
campaign therefore precede any release, and holding these pins back
would buy nothing.
Verified: every pinned revision is on its public remote, and
bitbake -c fetch resolves all of them.
grblhal-glowforge e2ba043 carries the core fork at 362577d, whose block
ring index covers $398 up to 1000. Fetch-verified with bitbake -c fetch.
Pin bump only.
forgectrl 0.1.6 (b1eee4d): the xy_microsteps setting and the quiet hold route.
grblhal-glowforge 0.1.5 (48d5f1d): the XY scale, tick and stop ramp derived
from the microstep mode, plus the producer lead ceiling.
forgefirm-app 0.1.25+git (d1c47b8): the checked header keys note; the
python3-gfhardware pin in meta-glowforge-bsp moves with it.
Fetch-verified with bitbake -c fetch. Pin bump only: the acceptance
consequence is the catalog invalidation the manifest already derives.
forgectrl carries the GRBL settings store into the data directory, which
the acceptance suite already asserts. grblhal-glowforge follows the core
off the deprecated settings-changed event and moves the core submodule to
the fork rebased onto build 20260905.
Both revisions fetch.
meta-forgefirm: the forgefirm-users init replays the account at boot;
sshd refuses root and empty passwords and runs only while the panel
turns it on; the release image keeps an empty root password for the
console; the console banner; avahi announces forgefirm.local; https in
libmicrohttpd and ulfius; the panel on 80 and 443; the license bundle on
the rootfs; release.sh checks the root policy on the built rootfs.
forgetest: the commission suites (commission, commission_dark,
commission_sheet: 23 cases); the runner turns cloud mode on with the
typed phrase for a test that declares it; the baseline's motor_lock is
0; the log-export test checks the bundle for the camera key; the record
helpers write bytes as given and join the daemon's paths as POSIX. The
stream harness gains rule 24: a hold verdict is held again after a
resume. Bench drills: lens_travel.py and lens_stop_accel.py.
Docs: BRINGUP carries the present state; CAMPAIGN-LOG carries the dated
record.
The request-body cap is on the bench. Image 20260904131106 carried
forgectrl ff89288 through a build overlay, and campaign
c-20260904132654-d731 authorized it, 56 of 56.
The pin now says what the campaign ran.
forgectrl 8ef9509 at 0.1.2, grblhal-glowforge 2f5edee at 0.1.2, and the
forgefirm-app recipes at dd0ebf3, 0.1.23+git. These are the sources the
full campaign on image 20260903211413 passed against, now that their
repositories are pushed and the build no longer needs the local overlay.
B-16: BB_SIGNATURE_LOCAL_DIRS_EXCLUDE in the distro conf names __pycache__
and .pytest_cache, so a workstation's bytecode caches never enter a
file:// checksum (proven in the build VM: a cache under the package leaves
the fetch task alone, a source change reruns it).
kernel.resume-lead: two phases behind one takeover at a 1 kHz tick. E, a
resume whose lead is longer than the data ends at end-of-data within a few
ticks (a lost end-of-data would show as 255 ms). L, a 1000-byte lead over
FIRE bits with the latch unlocked and the chain unarmed keeps the FIRE
line low through the lead and drives it from the waypoint byte on. The
bench proof for the module's K-4 and K-8 fixes; the catalog counts 55
tests, 0 uncovered.
BRINGUP items 9 and 11 and the CAMPAIGN-LOG entry record the batch and the
campaign rule: no campaign until every audit finding is on one image.
The audit remediation's commits and the bench session's fixes in the
three repositories, pushed and bench-proven on image 20260902144848
(built from the same commits through a local pin overlay). Each PV
moves with its SRCREV; the manifest records the PV.
The daemons log to /dev/log with non-blocking datagrams and drop what
the socket will not take. The kernel's default queue for a unix datagram
socket is 10; forgectrl's arm-time burst alone was about 20, so the
lines around every job start were lost, and the daemon reported 18 to
46 dropped per job on the bench. The logging init sets
net.unix.max_dgram_qlen to 512 before rsyslog and the daemons start;
nothing on the image applied sysctl files before.
Bench: set at runtime on 20260902144848 for the rest of the session.
Catalog consequence: a layer change; the meta-forgefirm content hash
moves and nothing inherits on the image that ships it.
BRINGUP describes the present: the 54-test catalog and its seven-test
always core, the tier counts, the shipped low-temperature gates, the
density floor ($35 = 10), the two local core commits, the ffboot env
write, the aa-offset route, the current bench image, and the bench
measurements the audit asks for (pooled into the next session). The
workstation shell notes and every em dash are gone.
forgetest: the takeover waits for the cloud client too (found by its
command line); the unauthenticated /boot probe names the endpoint's
parameter; the UI prose is American English. Recipes: forgetest
fetches its package directory and init script only and drops
__pycache__ at unpack; the dev image no longer re-adds forgectrl; the
release image's remove list drops the gfui-client the BSP no longer
has; the platform identity strips the kernel's local-version hash
from the modules directory name, so a re-patched kernel keeps its
fingerprints. grblhal restart is stop then start. release.sh --dev
packs the dev image. fixture.sh refuses a readable env file.
Bench tools: the live-fire drills measure the lid-IR baseline before
every run and point at the fire-watch thresholds the engine reads;
one thermistor conversion (gfbench.degc) serves every drill; the six
dated measurement records leave the tool directory; feeder.c names the
two sysfs writes its caller makes.
Host tests: forgetest 258 pass; the coverage lint reports no uncovered
path across 54 tests. Acceptance: forgectrl.auth covers the /boot
probe; update.* cover ffboot and the manifest identity; the runbook
and bench-tool changes have no catalog consequence.
A read-only mount of an ext4 slot still replays its journal, which
writes to the partition the probe was not meant to touch. The probe
mounts with noload: the journal is left as it is and the slot's
content is read as it stands.
Acceptance: update.slots covers ffboot -l (covers map ffboot/**).
FORGEFIRM_RELEASE said 0.1.0, the first non-beta number by the settled
rule, so the first cut was either refused as 0.0.1 or shipped as a
non-beta. The recipe now says 0.0.1, and release.sh refuses a version at
or above 0.1.0 while the README carries the beta banner.
The inheritance walk skipped every record that was not a PASS on the
current fingerprint, so a FAIL or ERROR recorded after a PASS on the
same image was stepped over and the older PASS inherited into the next
campaign. The newest record on the fingerprint now decides: a PASS is
inherited, a FAIL or ERROR blocks it (reason failed-since), an ABORTED
run says nothing. Unit tests for all three orders.
ffboot, the tool that rewrites the boot environment on every install and
slot switch, was packaged from scripts/ outside every fingerprint. It
now lives in the recipe's files and the recipe inherits the manifest
class; the tree manifest tool fingerprints file components the same
way, and the update tests cover the component.
forgectrl.settings-bounds fell back to ui_units=mm, which the whitelist
refuses, so the always-required test failed on a fresh machine; the
fallback is metric.
The recipe URLs, the release and install URLs, the vendor check and the CI checkouts name openglow-org, and the grblHAL core fork is openglow-org/grblHAL-core. No catalog change is owed: the recipe edits move the meta-forgefirm content hash, which every test fingerprint folds in through the platform block, so the whole catalog re-runs on its own.
The supply's power-good line is active high, static across HV enable and emission, and driven; the facts bank and CAMPAIGN-LOG carry the measurement and the item closes. The kernel-drill latch-unlock guard read the old inverted value as HV not good, a check that was vacuous and would refuse every run once the module reads the line correctly; it now uses the chain's own witnesses, the charge-pump watchdog and the engine state. pgood_probe.py watches the line beside the chain through the kernel readbacks and is registered on the bench page. The dev image lists python3-mmap and python3-ctypes again for the pad-level bench tools the python trim had left without them.
forgectrl 161686f adds the head-accelerometer crash watch (two tiers
on the LIS2HH12's interrupt generators, armed inside the laser's
armed window). The catalog grows cooling.crash-watch-plumbing - the
unarmed half of the watch provable without a button press: accel_watch
stays at watch through an unarmed session, three zeros read as the
three crash gates off, an out-of-range threshold is refused - and
_COOL_COVERS widens to src/accel.*. The armed-tier bench drill is a
BRINGUP next-work item.
The de-risk drill script's CTRL7 write moves from bit 0 (4D_IG1) to
bit 2 (LIR1), the latch the datasheet actually puts there; the drill's
findings did not depend on latching (a continuous gravity signal).
The factory-shaped watch is implemented, host-tested and bench-proven
with the lamp as the flame stand-in (CAMPAIGN-LOG has the run, the
fault-class mapping and the recorded interpretation). BRINGUP: the item
closed, items 2 to 18 are now 1 to 17, the references follow, and the
facts bank reads the armed posture. Pin forgectrl for its doc fix.
Both tiers of the factory-shaped fire watch, proven with the lid lamp
as the flame stand-in: a q1 alert under the lamp's reading holds the
session as FLAME and does not survive into a fresh one; a q1 critical
latches FIRE with the laser latch locked; all four thresholds at zero
read as the four flame gates off; restored, the watch reads armed. Pin
forgectrl 77a643441c1c0c745a38aabebc68340d26204ce0 (the watch itself).
The TEC policy at room temperature: declared fitted with its thresholds
under the loop, a run session drives the line on and the session's end
returns it to 0; declared not fitted the line stays 0; the cross-checks
refuse off over on and off under the floor. Pin forgectrl
7d8a58035ca7fadebcae47ea9fd53ef2dd810bac (the TEC drive).
The first bench run released in 15 s on the heater slug; the engine now
judges a one-minute rolling minimum, and the test refuses a release
under 60 s. Pin forgectrl 9d0b757f492281d2628da6800db61a1f490fd125.
The catalog case for the two low-side gates: at room temperature the
start gate 1 C above the loop holds the next session in warm-up (heater
on, fans idle, fire blocked) and releases into run at the gate; with the
start gate off, a floor above the loop holds COLD; both at 0 are off and
say so; restored, everything reads as before. Pin forgectrl
5a12f55db6ac632dfc720d9937ca581a7703b7c3 (the gates themselves).
cooling.aa-offset-calibrate gives the tool 540 s (its 420 s stationary
gate plus the six edges) and says so in its steps. Pin forgectrl
7dbb5e1e55a12e6bd1364d920f46c96a3ae2d4ce (the tool settles at the flow
tools' gate before its first edge).
The release rootfs carried python3-modules (tkinter, idle, 2to3, pydoc,
ensurepip, venv, asyncio, multiprocessing, xmlrpc) through the python3
meta-package, and libgnutls30, nettle, libgmp10, libunistring5 and
libtasn1 through libmicrohttpd (https) and ulfius (GnuTLS). Nothing on
the image uses either. Each Python recipe declares the module packages it
imports; forgetest declares its own, so the dev image carries no module
the release image lacks.
Pins: forgectrl 0e907f7db54b7a4c90b660f198d49e5c66b667b5 (armed shown from a
fresh report only, zero smoke phase for a dark session), grblhal-glowforge
fa9ed7834faab6f48367dc1ca5a5109b474f788d (rail enable only standalone).
BRINGUP: the lid IR lamp response measured over the full range; no camera
register file under /data; the rail policy and the cool status items
closed; laser.armed-kill stays in its domain; the debug-kernel drill
constraints.
Platform change (layer content): the full campaign is owed on the built
image.
The M101 dose-model switch with its derived per-model floors, and the
controller's published state files with their /status echo and panel
card. Both proven host-side and, for the switch, on the bench (the
mswitch drill); the catalog covers the changes through the model-aware
laser.power-floor, laser.power-model-switch and the extended
forgectrl.panel-serves.
The pin carries the calibrate tool's sampling fix (3 s at 8 Hz a side).
aa_offset_check.py proves the correction on a machine: M8 brings the fans
to the run profile, dark, while the raw coolant counts, /status and the
engine's readings are averaged before, during and after; it turns the
flow check off for its session and restores it. On the bench page as
aa-offset-check. CAMPAIGN-LOG records the tool's first run, the applied
value (16 counts) and the proof: the readings held within 0.1 C under
the run profile where they dropped 1.0 C uncorrected. BRINGUP item 21
names what remains.
No catalog consequence: a bench tool and records.
forgectrl 25cf969 lets status.c link without the cooling engine (the
image build compiles the status host tests), so the pin moves to it;
verified with bitbake -c fetch. offset_probe.py joins the bench-page
registry (survey, ladder and jog; the armed dwell stays a hand-run mode)
and takes "survey" as a mode word.
The pin carries the compensation (cool_aa_offset_counts, the
aa-offset-calibrate diagnostic, the panel's Apply); verified with
bitbake -c fetch. The catalog gains cooling.aa-offset-calibrate, which
runs the tool and checks its recommendation and spread.
scripts/bench/offset_probe.py is the differential probe that found the
source: one actuator switched at a time with both sensors at 25 Hz
(survey), the air-assist duty ladder, the gantry jogging under the fan,
and an armed dark dwell. CAMPAIGN-LOG records the four probes and the
result; BRINGUP item 21 names the setting and the calibrate as what
remains on this machine, and item 23 opens the initial commissioning
procedure.
No catalog consequence beyond the new case: a bench tool and records.
grblHAL-glowforge a7dcdca: the arm at the first laser-on is decided by the
window alone, and an RX overrun drops the overrunning line whole and stops
the job. forgectrl 2f18b16: the flow check's baseline and end are means,
and the tube's share of the rise is taken off before the limit. Both
verified with bitbake -c fetch.
Comment only. The edit changes the content hash of meta-forgefirm, which
the acceptance manifest counts as a platform change, so the next image
needs a full campaign. Accepted: a full campaign is planned.