Record audit Phase 4; LIGHTBURN: the armed window is job-based

BRINGUP gains the Phase 4 (stale-gate cluster) record - code-complete,
host-verified, hot-deployable, bench drills listed. LIGHTBURN.md now
describes the job-based armed window: relock at program end, on a
sender change, or after the spindle-off grace (counting even in Hold).
This commit is contained in:
ScottW514
2026-08-14 16:58:35 -04:00
parent daa76ca828
commit ea3fce2efd
2 changed files with 42 additions and 4 deletions
+36 -1
View File
@@ -1,11 +1,46 @@
# ForgeFIRM bring-up status & cold-start runbook
Last updated: **2026-08-14** — **audit remediation Phases 0 through 3
Last updated: **2026-08-14** — **audit remediation Phases 0 through 4
landed** (from an independent whole-tree audit dated 2026-08-13; the
remediation is sequenced behind two gates — GATE A, uncommanded energy,
before any further live-fire; GATE B, control surface + release, before
any published release).
**Phase 4 (stale-gate cluster) is code-complete and host-verified; all
of it is hot-deployable (no kernel rows).** The operator-armed window
is now **job-based**, not 60-second-idle-based: it closes at program
end (`M2`/`M30`/`%`, through the kernel-idle-guarded relock so a queue
tail is never severed), whenever the sender connection changes (the
serial layer exposes a client-session generation; the press that armed
the window belongs to the displaced session), and after the disarm
grace — which now counts down in Hold, Door, and Tool Change too, so a
job abandoned in Hold no longer sits armed for hours (X-3, G-10). The
coolant fire gate is re-checked after the button wait, immediately
before the window opens (G-4), and the wait budget is clamped to
1–3600 s — garbage or zero can no longer mean wait-forever with the
latch unlocked (G-18). Cloud mode's `_button_wait` gets the same
treatment: bounded by the shared `laser_button_timeout_s`, lid
re-checked every pass, and timeout/lid/cancel all relock the latch and
disarm (C-7). The cloud cancel-drop is fixed: a settings action
rejected mid-print no longer wipes the running action's id, so a
subsequent cancel actually stops the cut (C-1). forgectrl: a
controller stop that times out restores supervision instead of leaving
the machine permanently controller-less (F-7); settings mutations are
lock-serialized and a multi-key POST lands as one atomic replace
(F-10); graceful shutdown is busy-aware — fans hold their duty and the
verdict ages out instead of being unlinked, so `forgectrl restart` no
longer feed-holds a live cut and drops exhaust (F-12; the flow-check
heater still goes off unconditionally, as this engine's own heat
source). Host verification: forgectrl and the controller build clean,
the null-sink stream harness passes all emission rules byte-identical
to the recorded baseline, and both Python clients byte-compile.
**Bench items:** finish a job and confirm disarm at Idle within the
cycle (not at +60 s); abandon a job in Hold and confirm it disarms;
kill the pump during the button wait and confirm arming refuses;
cancel a cloud print with a settings action in flight and confirm
motion stops; `forgectrl restart` mid-(dry)-cut holds exhaust. These
are dry/no-fire drills except where GATE A already applies.
**Phase 3 (broker ownership / dead-man second pass) is code-complete
and host-verified.** The "broker changed who owns safing" theme is
closed on the code side. The supervisor writes the two safing lines
+6 -3
View File
@@ -33,9 +33,12 @@ The laser fires only inside an operator-armed window:
runs. If nobody presses within `laser_button_timeout_s` (default
300 s) the job aborts with alarm 3. Stop in LightBurn (soft reset)
cancels the wait at any time.
- One press covers the whole job — power changes and M5/M3 toggles do
not re-prompt. The window relocks after `laser_disarm_s` (default
60 s) of idle with the spindle off; the next job prompts again.
- One press covers one job — power changes and M5/M3 toggles do not
re-prompt. The window relocks when the job ends (program end
`M2`/`M30`), when the sender connection changes, or after
`laser_disarm_s` (default 60 s) with the spindle off — counting even
while a job sits paused in Hold or with the lid open; the next job
prompts again.
- S-value scale: `$30` defaults to 1000, so set LightBurn's S-max to
1000. 100 % power = S1000. Use M4 (variable/dynamic) mode for cuts
and engraves.