mirror of
https://github.com/openglow-org/forgefirm.git
synced 2026-09-27 16:51:12 -07:00
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:
+36
-1
@@ -1,11 +1,46 @@
|
|||||||
# ForgeFIRM bring-up status & cold-start runbook
|
# 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
|
landed** (from an independent whole-tree audit dated 2026-08-13; the
|
||||||
remediation is sequenced behind two gates — GATE A, uncommanded energy,
|
remediation is sequenced behind two gates — GATE A, uncommanded energy,
|
||||||
before any further live-fire; GATE B, control surface + release, before
|
before any further live-fire; GATE B, control surface + release, before
|
||||||
any published release).
|
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
|
**Phase 3 (broker ownership / dead-man second pass) is code-complete
|
||||||
and host-verified.** The "broker changed who owns safing" theme is
|
and host-verified.** The "broker changed who owns safing" theme is
|
||||||
closed on the code side. The supervisor writes the two safing lines
|
closed on the code side. The supervisor writes the two safing lines
|
||||||
|
|||||||
+6
-3
@@ -33,9 +33,12 @@ The laser fires only inside an operator-armed window:
|
|||||||
runs. If nobody presses within `laser_button_timeout_s` (default
|
runs. If nobody presses within `laser_button_timeout_s` (default
|
||||||
300 s) the job aborts with alarm 3. Stop in LightBurn (soft reset)
|
300 s) the job aborts with alarm 3. Stop in LightBurn (soft reset)
|
||||||
cancels the wait at any time.
|
cancels the wait at any time.
|
||||||
- One press covers the whole job — power changes and M5/M3 toggles do
|
- One press covers one job — power changes and M5/M3 toggles do not
|
||||||
not re-prompt. The window relocks after `laser_disarm_s` (default
|
re-prompt. The window relocks when the job ends (program end
|
||||||
60 s) of idle with the spindle off; the next job prompts again.
|
`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
|
- 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
|
1000. 100 % power = S1000. Use M4 (variable/dynamic) mode for cuts
|
||||||
and engraves.
|
and engraves.
|
||||||
|
|||||||
Reference in New Issue
Block a user