Files
forgefirm/releases/v0.0.7/acceptance.json
T
ScottW514 2ea501f975 Release v0.0.7
FORGEFIRM_RELEASE is 0.0.7, and releases/v0.0.7 carries the release notes
and the acceptance artifact that forgetest exported on the bench reference.

The artifact is from campaign c-20260929000044-e1ea on the pins-only dev
image 20260928194539: authorized, 127 of 127 tests satisfied, 7 run on that
image and 120 inherited. scripts/acceptance-gate.py against that build's
release manifest gives AUTHORIZED, with inputs identical to the bench image.
2026-09-28 20:09:15 -04:00

31953 lines
856 KiB
JSON

{
"authorized": true,
"campaign": {
"catalog_hash": "32019673226a83358d90ee62a4a22b9ac46f730c9185343e0019ab401a6e463f",
"id": "c-20260929000044-e1ea",
"image": "20260928194539 (dev)",
"manifest_sha": "e7ca694f20116a46222907e7ba9222021efd2c007f9394f8b3bb9f3ff14875ba",
"t": "campaign",
"ts": "2026-09-29T00:00:44Z"
},
"catalog_hash": "32019673226a83358d90ee62a4a22b9ac46f730c9185343e0019ab401a6e463f",
"counts": {
"inherited": 120,
"required": 0,
"satisfied": 127,
"total": 127
},
"exported_at": "2026-09-29T00:07:08Z",
"format": 1,
"identity_sha": "9fa6667c4b46f76579c15ccd87908cf4b540eec8fde6ff11ee255b4bbb31354b",
"image": {
"name": "forgefirm-image-dev",
"version": "20260928194539 (dev)"
},
"invalidate": null,
"manifest": {
"build": {
"layers": {
"meta": {
"dirty": false,
"rev": "70ed6f677234d32198371a030178d2f272cf2d94"
},
"meta-forgefirm": {
"dirty": false,
"rev": "1bc15fe70a0c2e12f5ea0abb2f9e423363b2a403"
},
"meta-freescale": {
"dirty": false,
"rev": "b699d026506a6fc402e03afb432dcabd3d81c7ab"
},
"meta-freescale-distro": {
"dirty": false,
"rev": "b9d6a5d9931922558046d230c1f5f4ef6ee72345"
},
"meta-glowforge-bsp": {
"dirty": false,
"rev": "f012d8e82aa0dbfa511214e46a1e13559b1a0d74"
},
"meta-networking": {
"dirty": false,
"rev": "b0c2c648a1af89e7a8dd4c2ec841f3bc0ed0ccb9"
},
"meta-oe": {
"dirty": false,
"rev": "b0c2c648a1af89e7a8dd4c2ec841f3bc0ed0ccb9"
},
"meta-openglow-core": {
"dirty": false,
"rev": "f012d8e82aa0dbfa511214e46a1e13559b1a0d74"
},
"meta-poky": {
"dirty": false,
"rev": "70ed6f677234d32198371a030178d2f272cf2d94"
},
"meta-python": {
"dirty": false,
"rev": "b0c2c648a1af89e7a8dd4c2ec841f3bc0ed0ccb9"
}
}
},
"components": {
"ffboot": {
"component": "ffboot",
"files": [
[
"ffboot",
"794049bce7f33581bd43acd6ef4ed4b8f2000eee"
],
[
"fw_env.config",
"9d5dbf3bede2cb8ca6c28a58f5637bcd74b60c44"
]
],
"pv": "1.0",
"recipes": [
"ffboot"
],
"source": "files",
"srcrev": null
},
"forgectrl": {
"component": "forgectrl",
"files": [
[
".devcontainer/Dockerfile",
"b5fe47b2324ef29fb4d14ca04d81a555f4c2b310"
],
[
".devcontainer/devcontainer.json",
"aac36c6d76eb9379ed898242e55be1c7f44a844b"
],
[
".devcontainer/post-create.sh",
"f6a319a4386a56858c277cfacd402ffff07b0d6b"
],
[
".env.example",
"c5e199c33f528c8a22e6ac31f46519ca890e4487"
],
[
".gitattributes",
"1b30e1b56dcc0411c10ee780053d04f1c9d862e1"
],
[
".github/workflows/build.yml",
"b1f961d1770a94a4aec1ec8ffadb0c18799b0610"
],
[
".gitignore",
"2982052941081476662b3fd88cac64dd10c71f15"
],
[
".vscode/tasks.json",
"0680fc703a11f0041bfa6641ed67e3146982464e"
],
[
"AGENTS.md",
"b9e7fb425f505c0cb222db2931d271da611f718f"
],
[
"CMakeLists.txt",
"b03d4ac9222e726d35940444d0926a7a93c9b0b5"
],
[
"CONTRIBUTING.md",
"ca2a98e7d617e1bca2b2f814a598e94f89186c6e"
],
[
"LICENSE",
"ddfa51eaa264bc020ac65023e52f60be1d8cc1cd"
],
[
"README.md",
"cf6799bfcf5e9cd51ba4c952cc012216756098ef"
],
[
"docs/advisories/cloud-service.md",
"004e5c4cdd3c3b8a487452814fd79ef926063f70"
],
[
"docs/advisories/extensions.md",
"a39bcf26f35c0ce7d33f6a9bf4494f0c53398d86"
],
[
"docs/advisories/licenses.md",
"76cbe3f3cdd34d17188ca318349308440ee48c6e"
],
[
"docs/advisories/privacy.md",
"caff47e8948f127d8c123e6355b44012c3b1bec4"
],
[
"docs/advisories/safety-and-risk.md",
"88b56eddc84e66f7a482d39ab8656d8fbb9314b7"
],
[
"examples/remote/README.md",
"7f6846b23840f1e0643a068a9c4d8ca37f95d3b6"
],
[
"examples/remote/notify.py",
"78bbc766100bf2d566087830bbe8a2d631118118"
],
[
"init/forgectrl.init",
"ee35651f9be1d8dff23ff87323b085482f88802b"
],
[
"src/accel.c",
"5cc63aba5005d4fc4f3f8af9482dfea2b9e12481"
],
[
"src/accel.h",
"5e8807d02b6f29b1e006835c6e81c798a0a3ab2f"
],
[
"src/advisories.c",
"9d2985f1caf1265d8bbd038fc21e63e0baaffbd2"
],
[
"src/advisories.h",
"e3bb7f74a6f7a656cd69fcb7ef1e724a8f3d6225"
],
[
"src/airflow.c",
"02627ff272070a76cad7d1e9f48293858af27eff"
],
[
"src/airflow.h",
"4a9e3f2328ffc8a899cd8521a01667929abfdd25"
],
[
"src/auth.c",
"71b01890e81e37f52b0ac74a3e1f6a3885650a0f"
],
[
"src/auth.h",
"bef54587e2bae70f1622c4a814404eb22f2c2b93"
],
[
"src/builtin.c",
"7f92ef64fff7b850a306251d4b8d00999f28cf19"
],
[
"src/builtin.h",
"b5e3cbf4c439c4201a6bcfda5b3724e967f08dcf"
],
[
"src/button.c",
"fce73c84ab531f6e9e8205e922e5506b392ea00c"
],
[
"src/button.h",
"c9abf79767336fe892413330ee920134b70c9301"
],
[
"src/cam.c",
"dff6e1e0adae21558212c67f8e8bb9aa0824a297"
],
[
"src/cam.h",
"f3af1937d9a8d6504942eaea55507d8425417ea2"
],
[
"src/camhealth.c",
"2ce8a0e4dd6586b67b2bc9d340444c7638454311"
],
[
"src/camhealth.h",
"4d0765ebe62a733226fc5d1f09ff648fdb9f3645"
],
[
"src/camkey.c",
"c29ae59d985eaee8ecf81e508b5fe4ca50973a19"
],
[
"src/camkey.h",
"a33a4338e3cf3322e64b8034f57b6dc5726f6ffc"
],
[
"src/cool.c",
"cfd3fb06f89ce65906f2eac89b661ec2986a1401"
],
[
"src/cool.h",
"943f1da88d60755c56b713322c76f7e847fc3edc"
],
[
"src/coolfmt.c",
"aa89421f4e2b14d37345faab3c1b2e18970001a7"
],
[
"src/coolfmt.h",
"55fe9b4734d508b7f58bb311cb4fa9264ccda14d"
],
[
"src/curverec.c",
"21bf07c8b8a0c34d91cb6227c8166c53e8ed963b"
],
[
"src/curverec.h",
"f05b0eec1fdb333e708941dcc946123b93c3d1b7"
],
[
"src/debayer.c",
"8193350d231de08eaab92c00a27574ba3f21afae"
],
[
"src/debayer.h",
"66ada9cb84f29091c97a42d881a64d21b6919b41"
],
[
"src/diag.c",
"64bc234bbac050398d73a3279b10f4bcd0328a95"
],
[
"src/diag.h",
"a563e2489cfbfee542938c041654c90d8895c99e"
],
[
"src/events.c",
"a83a587c8b97beba5959ea45fbe4947711f45fc8"
],
[
"src/events.h",
"eb4f4d1ad2732c6fd6eb3f8d4c86c6e018e15f93"
],
[
"src/extpkg.c",
"83ab9afc2f13fbc6aed186b60d416b46b11e09bb"
],
[
"src/extpkg.h",
"92a19acf5bb2407ae8c7247a2653bc649d797eb9"
],
[
"src/fflog.c",
"cdeb518386db022df74cbfff89008bf17f5a864c"
],
[
"src/fflog.h",
"905314b0d5be06487faecdf97720e23d2506bb4e"
],
[
"src/font_hershey.c",
"9d7e7be583299f495997da276ca19c785ecb6e6d"
],
[
"src/font_hershey.h",
"535bbdcdf671b57b24fb710211a89c7e0a855c55"
],
[
"src/fwproduct.c",
"4fc4916b97493c1ec66aa41f76d338fbf2de78f5"
],
[
"src/fwproduct.h",
"7ba0b422a1622927963e830a4d2ee6ffb8b6118c"
],
[
"src/gates.c",
"9724fee4144ee6c7fb0fd6d769a580c3ba2b23c9"
],
[
"src/gates.h",
"5f164f39cc39be006e6eb59651760d7d3f81bb2e"
],
[
"src/gpu_debayer.c",
"c74f00b2e92883a7b09185a9c27eebadab2d3fb7"
],
[
"src/gpu_debayer.h",
"092f6fe1bae9dda6455763dd48a40938d99162d3"
],
[
"src/grblport.c",
"0a54ae69c193098f1fbf44ff80c64d127a65c2a6"
],
[
"src/grblport.h",
"6f04b63d1be29cf08ddc3771e984b3992db970a0"
],
[
"src/holds.c",
"66687e5da66599abb53e97a94e903d8a989e369c"
],
[
"src/holds.h",
"383e157d18c4f1f69e4c80d999ad8caae568d6a6"
],
[
"src/hooks.h",
"99bb724ae54b645b620d2e539838b055e8020083"
],
[
"src/ipu_copy.c",
"58f5a02eed46f6d7f95126e42080b2e143921d5f"
],
[
"src/ipu_copy.h",
"33d742d32ee97a4f49ad1751d9302229a3d7693d"
],
[
"src/jobpost.c",
"3b0bd9dbde4d20f0eac2fdd7fe8ea27e75590b55"
],
[
"src/jobpost.h",
"34ffdd77f3387183cf739c33a6b7e7ca9139728e"
],
[
"src/jobrun.c",
"457ae45361bf82de1eefb898d069320968df78fc"
],
[
"src/jobrun.h",
"a6c2cc30fff8bdc2add367c96f7ccdafe78f14bd"
],
[
"src/jobstream.c",
"36ddeb24ed07e0eb09c0cc6f7b50c402b27b0047"
],
[
"src/jobstream.h",
"99a98bcd7e81e63e13e046646472a4304b23c780"
],
[
"src/lease.c",
"49703c250efdbcc35aa8e90b820f7d9fc256759a"
],
[
"src/lease.h",
"2873e5f5217db04eda02b93af5052c175b518898"
],
[
"src/led.c",
"0a80fa9c983416b9dc8610b30b65de16416e285d"
],
[
"src/led.h",
"22f72dfb34519d1f7a071984560763cf6ba74816"
],
[
"src/lens.c",
"d78ec7da0ab1893889efc4692d65f85efa4d8290"
],
[
"src/lens.h",
"d157a98cffcddb1bc9d405f1779e2c494c92ef17"
],
[
"src/lenshome.c",
"219e8d95c700ec20c5c703c5d334af6b4f8d80ea"
],
[
"src/lenshome.h",
"eaf10e197aad7e040bd22f117c186b6de636dd2d"
],
[
"src/liveness.c",
"b36f18e738e9b88680ed4cabd4f7b165b85f8369"
],
[
"src/liveness.h",
"88ae53c31c80386b5daf570b77c806c978357061"
],
[
"src/logs.c",
"7113bbda649fcb336b252ad52468b7afd2f63f54"
],
[
"src/logs.h",
"aad504323d01627cd41ee0ea7aec1fda32929163"
],
[
"src/main.c",
"bab1fda26606c61188079fa9d41e390e8a868b39"
],
[
"src/mcode.c",
"0e696f00a6ca583531a9ddd2e59419a166b4e398"
],
[
"src/mcode.h",
"9e4efb5d7928af1a6e9709fdd7021c342fdc4956"
],
[
"src/mp4mux.c",
"90dae21b0bca1fd1b84d2ed308d229e9685922bc"
],
[
"src/mp4mux.h",
"36cfe2f67d643fe114ab279caba5b9da388dfd22"
],
[
"src/paths.h",
"6edaf15b1db6f039186f39e10c4dba12a239aeb7"
],
[
"src/peer.c",
"e2fdf6aad48fbc6861bf5846fafa64ac79064f8d"
],
[
"src/peer.h",
"705b548996451c32141db3b545b3e6f7b721c480"
],
[
"src/recordhtml.c",
"c23d1957cfded491cd541937ce092ac38443f96d"
],
[
"src/recordhtml.h",
"a0088d926c8edadcbf884372b77f5974d54da6de"
],
[
"src/relcheck.c",
"8d9b71966b260ca3f60e9cf7b0dc21fc2cc3f5d0"
],
[
"src/relcheck.h",
"839c2f4f20516ab635023822fdaec47d66fa67ac"
],
[
"src/sanitize.c",
"09abdc633301b437c4deac6713888892b0187250"
],
[
"src/sanitize.h",
"b52ae3da495e4d6308f59b4ec4105e99debe910b"
],
[
"src/senderout.c",
"4ea655e736fb479736fd8db498fce8f3f44917d8"
],
[
"src/senderout.h",
"3703229de88b51fd30130df903778c9e2ba0f34c"
],
[
"src/session.c",
"db815c861cb91ca4909ea8d01ba7faad4a436081"
],
[
"src/session.h",
"2b05c01cb2bbef6056a090cce333e514626bc957"
],
[
"src/settings.c",
"e10e715565d11104ddb8ff60938f7c0c117984af"
],
[
"src/settings.h",
"f4bd5772ea7cf693c7a339d25e761a17e27b5f76"
],
[
"src/setup.c",
"51ff1ed94ade6ccab0f8b838047afe012aa66832"
],
[
"src/setup.h",
"03d495102f4f4ba165230bc5994cad9f2d9e64ca"
],
[
"src/sha256.c",
"b8b38167cec8a586055093c6a120624049b08632"
],
[
"src/sha256.h",
"a8806a440e43d96866735a1da17d590491b6d55a"
],
[
"src/sheet.c",
"54b690d95cd6f78928fc968500ca566676b91ed4"
],
[
"src/sheet.h",
"b7fc62399bb193f62bb690d10341c06c878c0436"
],
[
"src/sheetid.c",
"aa63f45a50d7874e0aa2922ce21339ff17cbb5c5"
],
[
"src/sheetid.h",
"fe25e6648df6be8a8fb640f63e84338c342da6a6"
],
[
"src/status.c",
"790cda4b2fb109f319705054e79f032506fc55dc"
],
[
"src/status.h",
"f3d4c8875cbc9b12d62c2f78d2606b01469e5430"
],
[
"src/super.c",
"24cdcdb170ee5088fca02dac1cb7d8f58e1f04c4"
],
[
"src/super.h",
"a5350c028245e0d207742b36c3f6a3a945aa8607"
],
[
"src/tls.c",
"5a311d947d091c1607d2c6a1c0d66c20b8dc10d0"
],
[
"src/tls.h",
"ee4d7d68f1ed89231256d349caf6b4c00632c352"
],
[
"src/tokens.c",
"f8e825b2800d0d722a08a643ea08ca877bd0461a"
],
[
"src/tokens.h",
"3646099040abb542e9bceb4edead5460aa55e29e"
],
[
"src/tray.c",
"28e094430bc99973f9e9bddc5380e033c18c5d2b"
],
[
"src/tray.h",
"591048f47108f592f4dc20d2e228acf994c932a7"
],
[
"src/ui.h",
"1f1a14cb062e9220afad0e34cc582aab2fe2c9a4"
],
[
"src/ui/embed.cmake",
"0944fd06a00f9aef36343ce4a2c8ce045255bc88"
],
[
"src/ui/embed_docs.cmake",
"767d374c5422669384d865fd726492dc7b4dcf2a"
],
[
"src/ui/ext.js",
"7e41490b730b4d989977a98cca349fb2a391f93e"
],
[
"src/ui/forms.js",
"621b7f95207c97a64bbef53c4c1d7e39968a5448"
],
[
"src/ui/help.js",
"70a0423078e4a7801a8f149c7cd87badf26b93a8"
],
[
"src/ui/index.html",
"ee6bb01eeee4f0e8ce3bb799d52c7faa61cb8a74"
],
[
"src/ui/login.html",
"22acf58351a5a874cd2ffc2a3309fe43e8a94116"
],
[
"src/ui/login.js",
"d38480ff1f4eb67b2e2c356b2f2a2b82a2656fd4"
],
[
"src/ui/md.js",
"e879a630efd6a53b6ed16d5a4052f6b8ced21a5b"
],
[
"src/ui/panel.js",
"1c5ab7a95e897db24b81109c6f92c94421cc06d6"
],
[
"src/ui/regions.js",
"42b6da0673a3aa5d196c9f661877acf63b119da7"
],
[
"src/ui/theme.css",
"9de9131fcf4cc62541a5f1a89d7468d39fe3a237"
],
[
"src/ui/vendor/LICENSE",
"fa7c00bc4ebd5dc9c0b1e7f8c4b6a202fd9fa816"
],
[
"src/ui/vendor/bootstrap.bundle.min.js",
"881b51776c82ddd6bd7225fb03f6e9bb07f53c40"
],
[
"src/ui/vendor/bootstrap.min.css",
"c558c23e686c9473d35abc3aa3b16cec11b6f7d7"
],
[
"src/ui/wizard.css",
"30b20aa34d87b61fe358d8bad8f8ece10804f667"
],
[
"src/ui/wizard.html",
"92d77eb847dbbe726c509c50ef1e55c4593734c3"
],
[
"src/ui/wizard.js",
"de17b9ee49d42c06189b551c76c3b61b45bc6c6a"
],
[
"src/update.c",
"762680957afca7f7709252ab02889ce567fa63c4"
],
[
"src/update.h",
"67160301f3622d570424f8b094c2865db132fd35"
],
[
"src/users.c",
"2a624ff9c32eacda78375f079b3b057ec7e5056a"
],
[
"src/users.h",
"57fc30cdfba07f69296821028ac874a208bae4dc"
],
[
"src/vpu_h264.c",
"2a3d9ea5b5930403d3a0bc698e36aeee2b9c4a6e"
],
[
"src/vpu_h264.h",
"ea40e0fd3098522d590ab0ec19fc4006e6682caa"
],
[
"src/vpu_jpeg.c",
"917baa19432793d86bb7c28d415e8c0e817366a5"
],
[
"src/vpu_jpeg.h",
"f33954985eca5b49bce91056ea5d1c8450b7d846"
],
[
"src/wiz.c",
"8f5feda005f0cb491293df85cfc999c2aeb4d525"
],
[
"src/wiz.h",
"96732c9791d6996123d21ee4130a9d2f0af00e53"
],
[
"src/wizcalc.c",
"05f25aea3932a3f814ac430a3c15439aa4247ac6"
],
[
"src/wizcalc.h",
"e7914a6c4753ce771be9a3600a797ac358dd26f5"
],
[
"src/wizdark.c",
"ffe28caacd5cd40462db960b7281907be21ccc67"
],
[
"src/wizdark.h",
"32eb8d7c13f0239440e69f97a62d2c05d620e12f"
],
[
"src/wizlive.c",
"0fce20159ecf4278117177345155430bc9631b52"
],
[
"src/wizlive.h",
"1f95d7a4424d145bbae79880003ba3e014c9aa0b"
],
[
"src/wizpkg.c",
"285013cdacb7a0ea8d120499724674689d106107"
],
[
"src/wizpkg.h",
"61da720f22873e2ba28cb44f5bd53a4517621ed1"
],
[
"src/wizrun.h",
"c71a99d60ee4c299f1a032c3e4cab43d9634ed8a"
],
[
"tests/accel_test.c",
"58efc7af80341548045169074ccf64f8fc3fb326"
],
[
"tests/airflow_test.c",
"79e3ba5b2aa5f45c21dab0fca3b3aa1427c607d0"
],
[
"tests/auth_peer_test.c",
"ac5994496f50a021b6e1bab6d211ad948a4d5244"
],
[
"tests/auth_scoped_test.c",
"680d01b77369b9d9c63f4a03b2021461d29dec3f"
],
[
"tests/builtin_test.c",
"84162138dc2af6792337d84007b177f607554063"
],
[
"tests/camhealth_test.c",
"32aecc993f1192c343262636b214d590a9ccf94f"
],
[
"tests/camkey_test.c",
"ee3838d49d5a3246c89bdddae3116180154e2dbb"
],
[
"tests/cool_fanwrite_test.c",
"b18534f296a2a43f198dc1daa393ff0fa41db93e"
],
[
"tests/cool_flow_test.c",
"d1405a85b6676bd29e660f678c42743cc6155051"
],
[
"tests/cool_gate_test.c",
"fad8afe6f27797381ae137debdba535d3f5a5a8c"
],
[
"tests/coolfmt_test.c",
"f6d209c769d21a6b99815d7a77d405fa8109fda4"
],
[
"tests/curverec_fit_test.c",
"8229d90ee60ad04eea4a09fac038f9d1b8060553"
],
[
"tests/debayer_test.c",
"56c4fe062c73fd5e878cc6cac906ab883e6c15b5"
],
[
"tests/enclosure_wait_test.c",
"a888b9e19b5ccfe53d8ac02b8cc30e9315def772"
],
[
"tests/events_test.c",
"58efe7a684a1fd2545bc33d0d2a221d8534bad05"
],
[
"tests/extpkg_test.c",
"32815a279faa31b6132380ef490ca6c2fc9f98af"
],
[
"tests/fflog_e2e.sh",
"af437b98b34d31f4f4c0c0fa45583e99e897cd32"
],
[
"tests/fflog_e2e_test.c",
"0a69f4e6e36549966713827fabbd6d585efa222c"
],
[
"tests/fwproduct_test.c",
"a02fc42310edb7289e08d9233c5e778f9ea00099"
],
[
"tests/grblport_test.c",
"110486cba2f1d49c92d63ba2371f1a88f49de7cf"
],
[
"tests/holds_test.c",
"5f834bac562ccec07467fa156e6694fa4076bf03"
],
[
"tests/jobrun_test.c",
"c1b663531a4c2a20083bc85c0f7e65793ff67e83"
],
[
"tests/jobstream_test.c",
"3953a55fb53ff0e60986fb0d1e8a8ff74013234a"
],
[
"tests/lease_test.c",
"4e7b9f2d18b09719ed692ccd84f8ba160ecc8ff7"
],
[
"tests/lens_test.c",
"acf677522523eb55daf79c795a47ca6af9814902"
],
[
"tests/lenshome_test.c",
"5221adf9d27ef645b4766356b39c9f882823ff06"
],
[
"tests/lid_gate_test.c",
"2bca256165c15ac0b0bfdfd9b26fc679d82c7c42"
],
[
"tests/mcode_test.c",
"64516d5fad69537ad7626da4243233e0308684c6"
],
[
"tests/mp4mux_test.c",
"2406647623a9ef83a6b91c5b932a95a282586818"
],
[
"tests/recordhtml_test.c",
"0c17708a1b7bdb8d3547fa6b8a8c92c916ff75fe"
],
[
"tests/relcheck_test.c",
"14c3fffa670f1d12fb09a5bed166e0c770809e1d"
],
[
"tests/sanitize_test.c",
"add2169b6d0bcd25624669afd78da58683408d78"
],
[
"tests/senderout_test.c",
"d9d4f9aa2fcd3d6968d3cc6d60b418d36e1c7abd"
],
[
"tests/settings_dir_test.c",
"ee97a3024af1e1968602a29f3d528e91219c7192"
],
[
"tests/setup_test.c",
"e0ef70e1c2d8fc151fd0e369b455ad39dd5e4f70"
],
[
"tests/sha256_test.c",
"017ef369f6bff5cc0827dc74aeb1189843b052ca"
],
[
"tests/sheet_test.c",
"fca9b93935061c2fe3a680ba9b6ddb93c0d18e34"
],
[
"tests/sheetid_test.c",
"bc923a6fea6e58461676774ee98f8b9b65c078d4"
],
[
"tests/status_grbl_test.c",
"c17b6bcd808ef8e681d576a1bc92c77077062044"
],
[
"tests/status_idle_test.c",
"48e82d35051f383e33fbb0848fe85821fd48b4d3"
],
[
"tests/status_sys_test.c",
"d1205ff4fda9d2a8e5ccac0408bb2600d1df3dc9"
],
[
"tests/super_test.c",
"a4b131e2a35cc85606bc60f38fa7939c529a4753"
],
[
"tests/test_devserver_mock.py",
"f3c0b01510ced381e959843da0b3329dcc92b602"
],
[
"tests/tls_test.c",
"27c02449aef346bfd25519db0f984ed373c686af"
],
[
"tests/tokens_test.c",
"a4f9f8a68bf88f495db70b2c30e4ccccb95de518"
],
[
"tests/tray_test.c",
"15296089c65d78926c0e73be221cd88429b4c466"
],
[
"tests/users_test.c",
"d447b90ec43e878b1b8b6f9b594bfe043a68a035"
],
[
"tests/wizcalc_test.c",
"ffdceb20d528cd0424c65d358d35ca49099a9200"
],
[
"tests/wizpkg_test.c",
"1c73d908ed00929fb34309925c6176cd7b79e118"
],
[
"tools/devserver.py",
"7e0ca4dcd1caccf3499a587ca3779d0ab7c9c8a2"
],
[
"tools/frame_isolation.py",
"9cfc000346618b446156ff352f843f884f623442"
],
[
"tools/frame_isolation_hostile.html",
"27ead83c732895b5a696ec4223c97307e1d25747"
],
[
"tools/hershey_gen.py",
"d2e09fec7c28f41aa37af06f57cdd75a3a0b3d8d"
]
],
"pv": "0.1.29",
"recipes": [
"forgectrl"
],
"source": "git://github.com/openglow-org/forgectrl.git",
"srcrev": "4b3966396b19a333076a9b2b23cade833afd4bb0"
},
"forgeext": {
"component": "forgeext",
"files": [
[
".github/actions/kit/action.yml",
"54ba4142eff63275dacc2a6d46eacb7f6e50a613"
],
[
".github/workflows/build.yml",
"59220bfda1574ac4d5a8c8dccddd26383adce443"
],
[
".github/workflows/package.yml",
"c4306bdbfdb164a2276544d2e9427cc24c072ee8"
],
[
".gitignore",
"2fb12249c0537a1d0c0cd12e6f181b61861720c2"
],
[
"AGENTS.md",
"131f35d408d35213d358b19d15ea3640820ce8e6"
],
[
"CMakeLists.txt",
"e052250d6b89ce8294aeeefe1ffcd7a027c136ee"
],
[
"CONTRIBUTING.md",
"ca2a98e7d617e1bca2b2f814a598e94f89186c6e"
],
[
"LICENSE",
"ddfa51eaa264bc020ac65023e52f60be1d8cc1cd"
],
[
"README.md",
"4bd9961c2069ed23739d4bc93e4c990b894220c8"
],
[
"init/forgeext.init",
"92ccf1db95dbd423bcd5350510e340e48a4ec474"
],
[
"sdk/c/ffx.h",
"0ceb482c3b279883120390b244a1dbeac5b2bd90"
],
[
"sdk/js/ffx-bridge.js",
"427b0de01fdcc257892ac94b379e6c5ce935f656"
],
[
"sdk/python/ffx.py",
"c36bd5d87ab73abe8c4798e0eeffa43b70473367"
],
[
"sdk/python/modules.txt",
"a36cf5be6f6cc00f152051704d41fc5c9f8bb368"
],
[
"sdk/sh/ffx.sh",
"d4339c7189cd94222fc700c53108433b140cd284"
],
[
"src/api.c",
"69f9f0c36b7514c0a8c0e15d7bc8710f7583f43a"
],
[
"src/api.h",
"e66ff59063220281b634502e6a30c59356defeaa"
],
[
"src/call.c",
"acbe52a3dcbb3826ed6a55b875b04a6aee779437"
],
[
"src/call.h",
"a267f83ccc5748db15ab7ad9283d7fafab10907c"
],
[
"src/caps.c",
"5556ef7b7ac8bc6e9b385e8afde36c68722f3f82"
],
[
"src/caps.h",
"4fb5f841bfe54271b92d29868b8cb63751a3c78a"
],
[
"src/cgroup.c",
"c01202e9c967005b361b4c145f5df7d6fbb1f9dc"
],
[
"src/cgroup.h",
"a361f66f270a598ea774f8fe7723c5db462d8d49"
],
[
"src/evfeed.c",
"9839b1c791ebda09633eb5c10555bf0810f280a6"
],
[
"src/evfeed.h",
"fcb4aa05827652cdc8569528f08c562c5b82ee18"
],
[
"src/fflog.c",
"cdeb518386db022df74cbfff89008bf17f5a864c"
],
[
"src/fflog.h",
"905314b0d5be06487faecdf97720e23d2506bb4e"
],
[
"src/holdkeep.c",
"5c36d98ad2029cf902aa6d28b291b7c606e9176c"
],
[
"src/holdkeep.h",
"40a7b61402dd950f1f200f43e52a5efea8a13f3b"
],
[
"src/httpreq.c",
"92bc555663ddeca6efb0a09b94fea4100c1adf39"
],
[
"src/httpreq.h",
"b5aa388e266dadfd97f60d453eabd5e77c48b28d"
],
[
"src/index.c",
"4d978856be8acfce5937243657934fef4ba8b862"
],
[
"src/index.h",
"77de12d92eaf9b36520701f4b66de4a88407e611"
],
[
"src/install.c",
"752ab4f17b1c7e4b298338d37b16e738ab9c4c68"
],
[
"src/install.h",
"13df26cf66bcca08a47e2a7bd122353602b240fc"
],
[
"src/machine.c",
"e39e806fee2eee48551d9b8dde404327aa11b5ab"
],
[
"src/machine.h",
"c4664d3dfc17308a23e0b51454b147a76a2437b0"
],
[
"src/main.c",
"a36bc6076bc71e9815a0c1676420afc7921a99cc"
],
[
"src/manifest.c",
"b6bff9cb3a3e1ac51ce4b12a0ae1c77d293d8573"
],
[
"src/manifest.h",
"9c4f18f63080c8564e023374367c521f07b5ac63"
],
[
"src/netrules.c",
"243d76939d0cdc81d3d6255e4637686b8a04eb42"
],
[
"src/netrules.h",
"b5a72ed91127568de6a70c9debfb6260a21a3b5a"
],
[
"src/pkg.c",
"ce74dab375a865840f9eb6a3307a4ee029a7875c"
],
[
"src/pkg.h",
"9653a70c7be351ba21176f3b1cde35a78d31d592"
],
[
"src/quota.c",
"4ec7b52799474e3455a1345b36167f15044d7361"
],
[
"src/quota.h",
"4ea4d492cfb92ef59b1772d822a417e37f0c5fdb"
],
[
"src/run.c",
"b15ef986ae121dbf3a11a3ca79f0632852207a83"
],
[
"src/run.h",
"d1ec00cdadd0bbb2f92186c562c1e244795247b5"
],
[
"src/sandbox.c",
"40c2902f41b7d82cd4501f821efbecf92b5dae25"
],
[
"src/sandbox.h",
"7ca05359f6a5bf050237418daa5b38b3bb83034e"
],
[
"src/settings.c",
"08e79bc15cb9a92b0439b99dc9c86ccdf5d5c1ee"
],
[
"src/settings.h",
"bb6e8ee5b54fc3e98d4f0d100c1dafacd7598163"
],
[
"src/state.c",
"d7c10f293dcead55d2f9cfda19f3730ed80bcd7e"
],
[
"src/state.h",
"a4f331bc6c79813d1f9364e3520b9ba1b8759597"
],
[
"src/super.c",
"9134904807ddef7918b74f581b0338beba1656da"
],
[
"src/super.h",
"b45b9b6c2aa8bee3fdc95f43b7bf7ee33861eb28"
],
[
"template/data/manifest.json",
"07aadf26e94ab9825573a03da9ee008104c63ac4"
],
[
"template/native/manifest.json",
"c6385b2bbfaec3c6fd0bfda1231365fa1089afa8"
],
[
"template/native/src/main.c",
"3dbc07efd6c7523126a76835a43374e25def2298"
],
[
"template/python/bin/run.py",
"58308c655e8c30a12fad772ddd1629d89b476ffe"
],
[
"template/python/manifest.json",
"1a9cc4ec72e3de8d79550c8f5c26721f6ab9493e"
],
[
"template/repo/Makefile",
"6041642e199bace88fa22dfaa8250fbd5105d4b3"
],
[
"template/repo/Makefile.native",
"ca32e8c0c897720376c647cdb86502c9971a9346"
],
[
"template/repo/README.md",
"6b8ac777e15e31bc1ebc2858f8e1b49381d51d4d"
],
[
"template/repo/gitignore",
"1106eb0b9d8b57f1cf8f2dea198a932b391ece08"
],
[
"template/repo/package.yml",
"b345d4c66b8948d8bb8ff181e0c287cd2df15748"
],
[
"template/shell/bin/run.sh",
"656569869e523aabb6b5a0c7babeb0c4c68121b0"
],
[
"template/shell/manifest.json",
"6024f59e36cdc71972daacd5de9df28897ae09a9"
],
[
"template/ui/manifest.json",
"46a7f0aec88e0cb39909f60f9966837848a10bcb"
],
[
"template/ui/ui/index.html",
"1ad50d40dd135dd0120e07651a7f8199c460b724"
],
[
"tests/api_test.c",
"125a39150f9f933d33f88caaea7ce9f2339a71ef"
],
[
"tests/caps_test.c",
"59160bf3b00621040b2756bb2849a1086724bfd0"
],
[
"tests/evfeed_test.c",
"2458c63b9dfe08debfa866408057c5e87c2c5608"
],
[
"tests/ffx_test.py",
"8375c4cac313cdf1da76e804a4084ee8f89658cd"
],
[
"tests/holdkeep_test.c",
"fbfc6daaa4de6c2371c10f9d11685b4c25930743"
],
[
"tests/httpreq_test.c",
"cd7bebe6418d8d9a5523e90ebc69cc5d7d83e49c"
],
[
"tests/install_test.py",
"a6d50758a767ef749bf48abbdb98ccf976644d7a"
],
[
"tests/manifest_test.c",
"ba4e0c050be5da978e0e297ecdc566e66de30a2e"
],
[
"tests/netrules_test.py",
"97c0daa715e4695264a7d2c57f2c15aef1a3d7b5"
],
[
"tests/quota_test.c",
"0eaddf83963bb8bb22f156db5c23e4786c65e992"
],
[
"tests/run_test.py",
"22eecc010217b31dc3474f5541ff86b7867dbda4"
],
[
"tests/sandbox_test.c",
"d0102a3035b5c36a365145c21d125fa5e06b5e95"
],
[
"tests/sdk_native.c",
"8ac354e2f00b4dc3fa9d7de52a5a7e5a2d74a49a"
],
[
"tests/sdk_test.py",
"47fd9af3f5fa2221902d1b9f59a43b2f6230a4c3"
],
[
"tests/settings_test.c",
"12ddef8882681b210e0d3a90ac5b6c6052fe27b8"
],
[
"tests/state_test.c",
"f23efbf3ed01c0b6e5da9baae44994a49165701d"
],
[
"tests/super_test.c",
"b3eeb932cbc11a9faecebbe2a08d62924f91a8c7"
],
[
"tests/version_test.c",
"905f0f74881aeb0468420ed39b17f27b51bd5515"
],
[
"tools/ffx",
"2345fdfb4036125b539b88c0993b8e208bfc0599"
],
[
"tools/mkffx.sh",
"137f9a62fa000b4200c0b76499a4e98ef4bd333f"
]
],
"pv": "0.1.1",
"recipes": [
"forgeext"
],
"source": "git://github.com/openglow-org/forgeext.git",
"srcrev": "2d0391e7f51922848bc2ac30240ac9f5dd65af20"
},
"forgefirm-app": {
"component": "forgefirm-app",
"files": [
[
".gitattributes",
"1b30e1b56dcc0411c10ee780053d04f1c9d862e1"
],
[
".github/workflows/host-tests.yml",
"58584524c1d484feb3ca9e4b3f1cc8bc1b4e6516"
],
[
".gitignore",
"2d6f9ccefa02c61cfd5cabc2d8b171025eadce09"
],
[
"AGENTS.md",
"620fcc0024033e662602ff361b45ce164bed2ff6"
],
[
"CONTRIBUTING.md",
"ca2a98e7d617e1bca2b2f814a598e94f89186c6e"
],
[
"LICENSE",
"d80cdb21e95685fdf696b2e01895bae8114ff927"
],
[
"LICENSE.LGPL-2.1",
"04bb156e77d5714dc2ee29bd0a37f16532ec741c"
],
[
"MANIFEST.in",
"e88a5f7bb02d90ece462ac8f196691fc5f1a61b6"
],
[
"README.md",
"d730969bc812a458c370bede7a23213a3c57499a"
],
[
"forgefirm-app/ffmachine.py",
"f12e15645decdbdbc95f9b5297704a440d205d27"
],
[
"forgefirm-app/gfcloud.init",
"0eb7c8d367315510ab492a13d6b28cbbb6fa860d"
],
[
"forgefirm-app/gfcloud.py",
"0a0d9868078df5c20f0234efdd3d111efa628436"
],
[
"forgefirm-app/gfhome.conf.sample",
"d00bf0e00c8a795443f95c6f227c8d8df3291869"
],
[
"forgefirm-app/gfhome.py",
"621060d3dcc1873095875fc83e532616c6fc1283"
],
[
"gfhardware/__init__.py",
"d4145850379d8919241f1de6d5148f275146987d"
],
[
"gfhardware/_common.py",
"d431911c90c0fea6bf3d8d869c8fbd23c3ff398c"
],
[
"gfhardware/cam.py",
"dd082c7c91e5ce5a1932585d454185d1558863f7"
],
[
"gfhardware/cnc.py",
"63f3d5a5544bb602ae8efd2b11c69c4ae84fc502"
],
[
"gfhardware/cooling.py",
"418a689e7958efbb39606848436b2c63dbec476d"
],
[
"gfhardware/coolsvc.py",
"e9c27f28f30da3d3b7ef0b4e6e0435cebc52e703"
],
[
"gfhardware/feeder.py",
"1387fd8f640d91bb58dc4ddfe9134c8d1335a240"
],
[
"gfhardware/id.py",
"3ad32e9a32a097dd5b916621ca70f4813effe2c1"
],
[
"gfhardware/input/__init__.py",
"02c064daf4e04ace8c8f318dc0254b9cbe22a610"
],
[
"gfhardware/leds.py",
"354d71cef35bcb714129fd216fa38951ddedb97f"
],
[
"gfhardware/machine.py",
"dcea1652c678af140d309b65c7aa85b2120f1f6e"
],
[
"gfhardware/src/bayer.c",
"61a1b9d54b8a4e718b4c55af7ae601a8840876ce"
],
[
"gfhardware/src/bayer.h",
"499f91dd8f22d21f6e91da2f7d3f13b55a88cbf5"
],
[
"gfhardware/src/evdev.c",
"723630aee75f46995aee59552e5ef48d08ee5a18"
],
[
"gfhardware/src/gfcam.c",
"b0900f0e1ca94ecd30c922f2459011b1729f0227"
],
[
"gfhardware/switches.py",
"80fd05df3f629f246eb480bd7d9c03bd9c9eb6ec"
],
[
"gfhardware/utils/__init__.py",
"e69de29bb2d1d6434b8b29ae775ad8c2e48c5391"
],
[
"gfhardware/utils/capture.py",
"ebf94278b686f9838e82d8024a9bf9511f91a951"
],
[
"gfhardware/z_axis.py",
"2a27d0f3bbd2f3fb45ba67a65f9b861455dc3900"
],
[
"requirements.txt",
"1e3c0f0dc607867f671e470f039971a81e4a6c47"
],
[
"setup.py",
"3ef5a500f23461b0ad9ed86388f009edafb1fcac"
],
[
"tests/test_cam_lid_gate.py",
"d97dc1af7d46d3c1c2ee1861ea44e344063423dc"
],
[
"tests/test_feeder.py",
"8dd86655b52495a9247b5ae968ae777b5e7365a6"
],
[
"tests/test_ffmachine_agent.py",
"79e0927955c7b5f00b9032f72f9fab9284e5b4f6"
],
[
"tests/test_ffmachine_emulator.py",
"5de6c0f6359616f1e253f9c3c047180a9f106440"
],
[
"tests/test_ffmachine_park.py",
"e83d97622e8807657374c87ea443f4ba1ef7ba58"
],
[
"tests/test_gfhome_exit.py",
"d78d5def849e143687558d4e53931cd4c3549584"
],
[
"tests/test_gfhome_motion.py",
"581547f9565dadbeb88d72bea06c88426e31b7e1"
],
[
"tests/test_limits.py",
"25966007bac504ff75c8e5c19339c231ca43af51"
],
[
"tests/test_machine_lid_button.py",
"c7dc110f5e4c77b854b4903d8102dbfa9c156dae"
],
[
"tests/test_pulse_body.py",
"29a868bb3aa60bcdaf8e23f13a24f32eca1e433f"
],
[
"tests/test_report_secret.py",
"dc1c01f094f658fa715530612ee6ef1e0915051f"
]
],
"pv": "0.1.31+git",
"recipes": [
"gfcloud",
"gfhome",
"python3-ffmachine"
],
"source": "git://github.com/openglow-org/python3-gfhardware.git",
"srcrev": "021323ddfbdfcd131831f916ad3c0ef1d7a59071"
},
"forgetest": {
"component": "forgetest",
"files": [
[
".pytest_cache/.gitignore",
"bc1a1f6167d09c909aad37280b760bb715d0f1da"
],
[
".pytest_cache/CACHEDIR.TAG",
"fce15ad7eaa74e5682b644c84efb75334c112f95"
],
[
".pytest_cache/README.md",
"b89018ced91c0a8af7f3f23ce8901870da89f3a0"
],
[
".pytest_cache/v/cache/nodeids",
"0637a088a01e8ddab3bf3fa98dbe804cbde1a0dc"
],
[
"__init__.py",
"b4d2c6eaad4cca91f8369c4ced3cb52e0bb3bb54"
],
[
"__main__.py",
"45688ce67145df1f155a5a14f52735fb44821ea9"
],
[
"artifact.py",
"e7d8cdaefe0679f8e091043a9849c95327178942"
],
[
"baseline.py",
"f6e1e10c1e080a8eddcdbd70e3cb3b12584765e8"
],
[
"bench.py",
"7a32a52423325ec0b844ae6fa4d5620fee91af29"
],
[
"campaign.py",
"0e937d9b600fe21651085dee8987dd7db9bdf2d7"
],
[
"catalog.py",
"0a5132b209d79a21192cf430d1eec990e9d10201"
],
[
"coverage.py",
"343e3363a65cb5370d6c9231d1442c5b9d8861b1"
],
[
"fixture.py",
"aeed64641f4c60b7ad10161f98813776efa0b15b"
],
[
"hw.py",
"b8e363397f81fa6a07666e53b99b1921e7d71702"
],
[
"log.py",
"8df1445460358bca4027d1a4a49189ba13dbc0de"
],
[
"manifest.py",
"6aaf78cb87cc07b54dcb3ca3fdf01f35a3c6535c"
],
[
"page.py",
"c6c3579acd78578aebf7404cac589d07eaf4c55b"
],
[
"puls.py",
"07bf06dd7f119ad59b1ecbf4295e9d4c4ce92d0d"
],
[
"redact.py",
"f445da45df0e36c8dcb6b17d0a851610880e3ce3"
],
[
"runner.py",
"86d10effdc247db6dae4fffec54528e2123462e7"
],
[
"server.py",
"70d3bc5bc1c2299264a5f4576e7d664ed71f860c"
],
[
"suite/__init__.py",
"3e64a2c5cf4f7d502b1124df8832f31537c25c33"
],
[
"suite/bedsize.py",
"00a6d36ef7070f95d7566a7181f9c5995a4b7b12"
],
[
"suite/camera.py",
"b2e33ac64c6a1e556a6fb9164f317510419e4fbd"
],
[
"suite/cloud.py",
"06150cd23475f8bb93659f916494bcd9e2cb58b8"
],
[
"suite/cooling.py",
"455f0cec260046e9b78e87ca3367bab3c8a6f48c"
],
[
"suite/evmore.py",
"6a3b8f20a8d1db7ceaa3b142e8217487adf27510"
],
[
"suite/extcall.py",
"a478ecc467c9a7277064eca3e74d5f513fc4ea07"
],
[
"suite/extcat.py",
"0a2d48d97119ad9305368febf893c6cd5aa622da"
],
[
"suite/extcore.py",
"31bac570b03f76ea41c3dd8f6fba44408d9beff5"
],
[
"suite/extdest.py",
"67c65c064bf6c656ff078f904e3125ddff05b365"
],
[
"suite/exthost.py",
"0f3f7b02dc96d283350cccfde2be3adaceef1ee7"
],
[
"suite/extlife.py",
"e3fbe7df126cc5e9f1f8ca7abe8426c4a63ac823"
],
[
"suite/extmcode.py",
"44233196f5351ad7701f62022004317bedabaf6c"
],
[
"suite/extsender.py",
"37e4ed4b370a77af81536d63448d34a24d8c553f"
],
[
"suite/extwizard.py",
"cea36c714f12b92e1ba660bc7b991286c316acbe"
],
[
"suite/forgectrl.py",
"ff89879af6476e1ad27af33be3cfe4c98adbfe6d"
],
[
"suite/homeoff.py",
"a700cb2cd14e1ec908d1d842aa98cc568084c8a2"
],
[
"suite/image.py",
"12c02a15e12b4bbfc1458292eb816c917b992590"
],
[
"suite/kernel.py",
"3df2be14eea6020ca998ec3e624beeb0dcb8c855"
],
[
"suite/laser.py",
"5114b7f937b0349f9fa488c04b8cde58c0d94d7d"
],
[
"suite/logs.py",
"e3e98dc19cc3f5fedbdd337fc961ee52259aa29f"
],
[
"suite/motion.py",
"ea3c2b52ab3e4c58b73f63fbc7b11c22a5c4c2cc"
],
[
"suite/setup.py",
"64ffed94d730e43eabf78651fd2f4830245fa8ba"
],
[
"suite/setup_dark.py",
"64f4cf378dda21917d29d26cef22d67b14205b97"
],
[
"suite/setup_sheet.py",
"c0358d3c2364afcac6a075b6651d1d4fd3acdce3"
],
[
"suite/tlsrec.py",
"5d3a22f4eabdafcfd028a866b5387fc1d0525fb2"
],
[
"suite/tray.py",
"854bf1e978bfe681020e5709df2507ba3067e7ee"
],
[
"suite/update.py",
"2a860863954abfd82333c13990ad3a2f156d1387"
],
[
"suite/updlock.py",
"9ab0e448c95cb6c2fa10d6b2f2d2ae09354ec8cb"
],
[
"ui/app.js",
"fa9674b2ca941800907e93559825b42911152945"
],
[
"ui/help.js",
"761a503f2f50c1e519185dcfd47c1caa2de29fb4"
],
[
"ui/index.html",
"036e239f1196844ca2ac13df1dba59ca1c0bd060"
],
[
"ui/page.css",
"b76d4361af04596b79285a55cc205d05a0491a44"
],
[
"ui/theme.css",
"9de9131fcf4cc62541a5f1a89d7468d39fe3a237"
],
[
"ui/vendor/LICENSE",
"fa7c00bc4ebd5dc9c0b1e7f8c4b6a202fd9fa816"
],
[
"ui/vendor/bootstrap.bundle.min.js",
"881b51776c82ddd6bd7225fb03f6e9bb07f53c40"
],
[
"ui/vendor/bootstrap.min.css",
"c558c23e686c9473d35abc3aa3b16cec11b6f7d7"
]
],
"pv": "1.0",
"recipes": [
"forgetest"
],
"source": "files",
"srcrev": null
},
"grblhal-glowforge": {
"component": "grblhal-glowforge",
"files": [
[
".gitattributes",
"1b30e1b56dcc0411c10ee780053d04f1c9d862e1"
],
[
".github/workflows/build.yml",
"5ff4d68c2b9515be787b33ab7af4c2d684246ff3"
],
[
".gitignore",
"4bda5643103df4c29ca3dbad4c841a738cee1b1a"
],
[
".gitmodules",
"d5e7f2dead5cfb1b00fd67e4355991eb35658914"
],
[
"AGENTS.md",
"75527eaf3fd3299a9b504cf9d4765fd7519750a8"
],
[
"CMakeLists.txt",
"57a9dac8fea9e3bf438af3b92e4e4fcd6b2eac92"
],
[
"CONTRIBUTING.md",
"ca2a98e7d617e1bca2b2f814a598e94f89186c6e"
],
[
"COPYING",
"96d5f44439ba4cecf32c1b46ed3a76fc7749488b"
],
[
"README.md",
"8441770a220eb2550ef1528df25f5cf7f52706e3"
],
[
"src/bind_addr.c",
"3ca3b27ed265c0c52e25eca97291c2e5f20a0b1d"
],
[
"src/bind_addr.h",
"2e3250924b9d757eea4872c6fac2d3830b11dc1b"
],
[
"src/boards/glowforge.h",
"dbb357c6ab412065e710ff5330b3a488a96e992d"
],
[
"src/build_info.h.in",
"9741f1b5f5c8efbd539dea783b0481339e88f0b2"
],
[
"src/ctlport.c",
"334e4130b81081fa122918423a5f50556c45b3e1"
],
[
"src/ctlport.h",
"413b5bc04893b721a469c29c94db923b652271ba"
],
[
"src/driver.c",
"97cf01d6e736d2f4aee760c79f28b17d89f9534f"
],
[
"src/driver.h",
"1e2e734779a8565c6b00e69c98d31134428cac5f"
],
[
"src/eeprom.c",
"eed4727a479c43704881b62659f6825eb514ebd1"
],
[
"src/eeprom.h",
"07be4c8c8b1e432824cb3c791915b18836c9997e"
],
[
"src/fflog.c",
"cdeb518386db022df74cbfff89008bf17f5a864c"
],
[
"src/fflog.h",
"905314b0d5be06487faecdf97720e23d2506bb4e"
],
[
"src/glowforge_cooling.c",
"9f0c7407ece59a99684dffebf2ec7e97ac2fd9f1"
],
[
"src/glowforge_cooling.h",
"ae576b4fc50dee5ddaced1c9544476cdfce08888"
],
[
"src/glowforge_homing.c",
"fb2c7f0c65874f4323c7fd410e06eb507207103d"
],
[
"src/glowforge_homing.h",
"5a16cd9e82aba4ea40ebb8d89b4d58e136f95f9b"
],
[
"src/glowforge_io.c",
"577b7bea7c5e1a0cfae23d57b1e4c7f953bcba92"
],
[
"src/glowforge_io.h",
"5316cc688b5776de60a8f293e4e21c15d85a4fb9"
],
[
"src/glowforge_laser.c",
"29767c8ff4579cfdd9a89667fd9e437010a3b6fe"
],
[
"src/glowforge_laser.h",
"bc500d8c8fc5d8cd851d3a4649342bbe83f67eee"
],
[
"src/glowforge_mcode.c",
"acec01e2f661250b4c1c927c5565dcbc843a057e"
],
[
"src/glowforge_mcode.h",
"9e913864639b581151bb9b60ede1deba5e80f631"
],
[
"src/glowforge_release.c",
"27b8952a8ae9c28c5334c60992ffc677577f17a2"
],
[
"src/glowforge_release.h",
"c488fe5b59a506394f3477757f454d773dbca0f3"
],
[
"src/glowforge_status.c",
"7b023cca48005d4522d6c8bc6968e4aeb60e4bd6"
],
[
"src/glowforge_status.h",
"fe2775d53d8cca766c6e82e68dbeb590a3fd1e67"
],
[
"src/glowforge_switch_map.h",
"ea33a30bd29a6945599023db3fd3858a21cefae7"
],
[
"src/glowforge_switches.c",
"cab12fb1f1877f2410037534a66d88f4264bbc42"
],
[
"src/glowforge_switches.h",
"1599275423c12be35c5afe79e21006bbc2efa005"
],
[
"src/glowforge_tray.c",
"9a631b415507939f20c3369c417a3b725e07ca3e"
],
[
"src/glowforge_tray.h",
"484e807b7736ffc17abf990bcff8e4e6112c2916"
],
[
"src/grbl",
"362577d10ce2a4ec47b0a1ba0d5eefc3fbe0fd75"
],
[
"src/grbl/.gitattributes",
"eb84b66b54a17195a184d5533e31919eb25c591c"
],
[
"src/grbl/.gitignore",
"572825f878d3b06754a0d2de957b14d2e26936b5"
],
[
"src/grbl/CMakeLists.txt",
"c537b82256f2fff209d9f365e73ed1a9587b0c8c"
],
[
"src/grbl/COPYING",
"c7d0e6fe45d03d4e29d624028fc3b62290bfeed2"
],
[
"src/grbl/README.md",
"45d02b077e10751a55960dbde16bcc7211e428a2"
],
[
"src/grbl/alarms.c",
"15d0227bafbf82c4c1e8f25be7c4d443e3506fe8"
],
[
"src/grbl/alarms.h",
"155b9a554c29608fdbc8ccbe1aba2a1a0151f960"
],
[
"src/grbl/canbus.c",
"b6936088c468a206a9c9191c69eee6ce47264101"
],
[
"src/grbl/canbus.h",
"f402f267305362127bc404774979eae55cc5fc57"
],
[
"src/grbl/changelog.md",
"debb326e818ae169b69d444db793e91624578cd9"
],
[
"src/grbl/config.h",
"e8c5be6be125e1911c41d4357617e4390521c265"
],
[
"src/grbl/coolant_control.c",
"6855fabef299cf61bbbe4d5a74dba8642e6b855a"
],
[
"src/grbl/coolant_control.h",
"e7452e66b5fb2dbda5d1bbc1e8350ba90380d72c"
],
[
"src/grbl/core_handlers.h",
"5ef428f6418d121b3e4c036e8c02cd9dbfd58720"
],
[
"src/grbl/crc.c",
"09059d75ac2e079f12d5c702107352ec33448ca7"
],
[
"src/grbl/crc.h",
"c4ddda03c2db722060a5afa0706887669e8bca4d"
],
[
"src/grbl/crossbar.c",
"b92a6c5e9f362b1c58213195c73f9c0d101f4d66"
],
[
"src/grbl/crossbar.h",
"5ba1b7bbf936efcb16a9ecdd5bc1adfb4bfac238"
],
[
"src/grbl/driver_opts.h",
"bc90fa27f1050f7ec9d7a7e9e872eb9dd7d4137b"
],
[
"src/grbl/driver_opts2.h",
"5e35543175bb53b2e7d32e92e7681649c9931554"
],
[
"src/grbl/encoders.c",
"292be5e52b7939174b2e226c2e0a9be9362ea66d"
],
[
"src/grbl/encoders.h",
"45d7d21532fc1a8b143e422f49b9ffff3081ce15"
],
[
"src/grbl/errors.c",
"909f7ca912d94e133d222cae9b258b688c4706ca"
],
[
"src/grbl/errors.h",
"cd12203d318280cd60d4db977f972872a461b999"
],
[
"src/grbl/expanders_init.h",
"c222179163165b58d75316d297d48115a7f0069e"
],
[
"src/grbl/fs_device.c",
"837e297cbcbbf99e01c12cd3cbbb02074d25cc9c"
],
[
"src/grbl/fs_ram.c",
"4a7850772f5f413f179c6da4a34b4f01d4717e19"
],
[
"src/grbl/fs_ram.h",
"aa60ffe696bc9be08f73ea2a51bbb2369a27004e"
],
[
"src/grbl/gcode.c",
"63939a354baa5c79143ded10baadd03e788b197c"
],
[
"src/grbl/gcode.h",
"5cb6053923e3a51ac823f8b64573950636491102"
],
[
"src/grbl/grbl.h",
"2154bae75cdf34fa602b733495bb25917d99984c"
],
[
"src/grbl/grbllib.c",
"b1287a601bcc1fb1db215deadce36c495aa5fdc2"
],
[
"src/grbl/grbllib.h",
"380e32675936430ef728eb4db72fe9b3d6ead7f5"
],
[
"src/grbl/hal.h",
"f2f87c8db59be0b9e9aba51766b1c6206688e287"
],
[
"src/grbl/ioports.c",
"c2de5ebafeee4d3311bf94030061157a12aa1901"
],
[
"src/grbl/ioports.h",
"b107c34926df91a1e849475457ea43b1d1890c16"
],
[
"src/grbl/kinematics/asymmetric_ganging.c",
"cf1a108866839f22f65f627c998e778a72baf243"
],
[
"src/grbl/kinematics/corexy.c",
"6d39fc0812ab17f7cef4ad84d72779969867e998"
],
[
"src/grbl/kinematics/delta.c",
"926795d093fc9017912d8141d9c7ec5b1b569b96"
],
[
"src/grbl/kinematics/interface.h",
"e32cc37f4f7be95cd7153216d2a5e6f00e9f7b22"
],
[
"src/grbl/kinematics/polar.c",
"927fd41f744a4ec44d8d28c0c8f344751788cec6"
],
[
"src/grbl/kinematics/rtcp_ac.c",
"0446f8f158f40df7a991d99f752dadc606948646"
],
[
"src/grbl/kinematics/wall_plotter.c",
"749618e1c782f5a9c6012ae44deadf0099ff9634"
],
[
"src/grbl/machine_limits.c",
"804b1be42400937fedf149bbbc1750903bac0e5f"
],
[
"src/grbl/machine_limits.h",
"83296b6bad74cc6270ef0ec3f27c2333006ace5c"
],
[
"src/grbl/messages.c",
"4bb3e11469cfd3819a347c3024e4021e6835a63c"
],
[
"src/grbl/messages.h",
"2c59bf458f32f3bd95d205abd02ecdc001f648cd"
],
[
"src/grbl/modbus.c",
"6ea9e75842f92d2d9733ff2d07b1a1454f213f8f"
],
[
"src/grbl/modbus.h",
"2cd00dec5f9d98dac9765885388e6dd9813cae1c"
],
[
"src/grbl/modbus_rtu.c",
"68f29cf98d1e84c159acdc79a3a7687194f33e47"
],
[
"src/grbl/motion_control.c",
"f43ff0576adb2082ca50d34c35093c533c475767"
],
[
"src/grbl/motion_control.h",
"9a15b27dc50d98416bc87085740af03d38f187e4"
],
[
"src/grbl/motor_pins.h",
"c0897698eabf181b478631aac48007e10370b839"
],
[
"src/grbl/my_plugin.c",
"291b440fdbaecfd7ef854c2c134c839fcc44bbab"
],
[
"src/grbl/ngc_expr.c",
"0aa7b2dc3f913ddf2f08c04b9d20a63f5439ad90"
],
[
"src/grbl/ngc_expr.h",
"f0a18ebc1b4240221e463c021258d4d6877fd72e"
],
[
"src/grbl/ngc_flowctrl.c",
"738a1f0eb3a9bcf5e8841e397803bfbe16f3db9d"
],
[
"src/grbl/ngc_flowctrl.h",
"51c31a1f57b87530d66d2eeb75b3e069818ca9c0"
],
[
"src/grbl/ngc_params.c",
"e4d74b78d60eda9b95f885022b576f25b3c857ac"
],
[
"src/grbl/ngc_params.h",
"eaa16d160048eb0bb7f25210fe8285e7d75f1176"
],
[
"src/grbl/nuts_bolts.c",
"1613a23462ab966bb93d3a381238cb036f03fe58"
],
[
"src/grbl/nuts_bolts.h",
"7c591bb4b07266a32c2fe0fa3d580edb8b647dd4"
],
[
"src/grbl/nvs.h",
"e48fc898f79f83ef79040b265948ad986ddc9455"
],
[
"src/grbl/nvs_buffer.c",
"ff191cd9b28a22d3300ffd17d8724c884550d083"
],
[
"src/grbl/nvs_buffer.h",
"0d8423da2ba663aa1dc586dd8b7df0ac178ad0c4"
],
[
"src/grbl/override.c",
"3c6315704855b3fb2d88ecb4c222daf8d64190e4"
],
[
"src/grbl/override.h",
"165d9ec0a139afe92261cc99ac8ee97d066f7034"
],
[
"src/grbl/pid.c",
"fbc465a401e52715d2951e026443be7bcbee9536"
],
[
"src/grbl/pid.h",
"8cb4c3c1d13ea95d14f2a68944146243bd051f98"
],
[
"src/grbl/pin_bits_masks.h",
"ceb032c5f0b33a20246385cfa2c695a1608613c8"
],
[
"src/grbl/planner.c",
"a0dee55dce2252e077a992de14303f4519d7dd91"
],
[
"src/grbl/planner.h",
"717b188d05b691e7c92d660b5e72f99043dde539"
],
[
"src/grbl/platform.h",
"3862abbd721d8bcbd3dc6182a67d3d00a312f289"
],
[
"src/grbl/plugins.h",
"f822f56a79d7ba122ea3d01c787cf950e0735110"
],
[
"src/grbl/plugins_init.h",
"8b430a3d9463e1a03a48559e716875f4470c646e"
],
[
"src/grbl/probe.c",
"d96519a379de741c599bbd33de6b11197ae4a927"
],
[
"src/grbl/probe.h",
"27040f2f237411a279405ea7fde18783d3db1caf"
],
[
"src/grbl/protocol.c",
"e39cfd4b000d77321939f50c4f280ccd48ed5cf8"
],
[
"src/grbl/protocol.h",
"008b06d26be9aec97206b54e42cde855d4bf1e45"
],
[
"src/grbl/regex.c",
"bdf238c081286a98ba59bbac0b4ee8fc3908471d"
],
[
"src/grbl/regex.h",
"a975067dd09b511cc0c926a01f59b594b5284043"
],
[
"src/grbl/report.c",
"ac4465a797376a79f96ba344dbfb98e537ecdcf8"
],
[
"src/grbl/report.h",
"57dbf7fcdc05f3ddceaf0a5724353140f4ccfe94"
],
[
"src/grbl/rgb.h",
"d660bd016758a1c4c65b627ae6ee768da15f2d03"
],
[
"src/grbl/settings.c",
"e62f823a32370072615b33c3ec72207a874ab41a"
],
[
"src/grbl/settings.h",
"ee7df332488c47f535386cbd283f9c3d5e3fae8d"
],
[
"src/grbl/sleep.c",
"51dd18454cac5fce5afd3a0e23b72bf014f16eec"
],
[
"src/grbl/sleep.h",
"a2c943f6fcc04358b9d40af7f37a495a52a930b5"
],
[
"src/grbl/spindle_control.c",
"1a1b3143b87df825ef2a9beb5d4ea58b77cca719"
],
[
"src/grbl/spindle_control.h",
"8b1c89a0cc29473757243bc35b31d28b7387504e"
],
[
"src/grbl/spindle_sync.h",
"ea80e6a700c66391aa4efe915f5ffc4bcd3e065a"
],
[
"src/grbl/state_machine.c",
"d7d67196ccc3cb2d03cf7fef5eb9abee16d476a7"
],
[
"src/grbl/state_machine.h",
"a782fd24c9e41d042ca70e39e6db5b64aebd231b"
],
[
"src/grbl/stepdir_map.h",
"a890f616dde53bbe4b969670fad13e00d176b75b"
],
[
"src/grbl/stepper.c",
"cb8d89fa8f6ab343bcdedc0aa4bed0627ab95fd1"
],
[
"src/grbl/stepper.h",
"5fc8640502918bbd42224b07d65c944f6da4eb0e"
],
[
"src/grbl/stepper2.c",
"de9f0845eed8586c38d97a0dfc29b458ec880aa6"
],
[
"src/grbl/stepper2.h",
"08b7763c2eb711f36fc750066a09c21cd90d41cf"
],
[
"src/grbl/stream.c",
"eb7592dad64080b1488f906627be3388d2d07586"
],
[
"src/grbl/stream.h",
"2aaccefc0e265c2833814f425e4c0378a64ec2f9"
],
[
"src/grbl/stream_file.c",
"6bdbb3d58464b34388433d5ee436f85d034fdf2b"
],
[
"src/grbl/stream_file.h",
"d9dd6616eb376d86b0ee448bd05d421916b117fb"
],
[
"src/grbl/stream_json.c",
"3949892a568f4ec31bfe4e179695b6d0acdff410"
],
[
"src/grbl/stream_json.h",
"2e3d8e1a51b3781527669586a79ac4d6a4c0d691"
],
[
"src/grbl/stream_passthru.c",
"5c16649afc5d7e96a1469a64fdab7ab6898922d6"
],
[
"src/grbl/stream_passthru.h",
"e9caadde48e6457a27901d500681e7127608530b"
],
[
"src/grbl/strutils.c",
"7fc24d7e900f322049bffe207a234bdf0f124c54"
],
[
"src/grbl/strutils.h",
"fc77e5b99c09c062bb7c788fbd280f73c8260480"
],
[
"src/grbl/system.c",
"8e072e93a76f43673a96c0c1d48198d6a580fff0"
],
[
"src/grbl/system.h",
"e992f8306856498724d1773f4d389b66676f2ac7"
],
[
"src/grbl/task.h",
"6a19b1176032619cf449113aceebc555c3418bb7"
],
[
"src/grbl/tool_change.c",
"423585324d237cc92074098e299905b7a1760d52"
],
[
"src/grbl/tool_change.h",
"eb8ed7eb0810c12cd028686bacd6775fda959a69"
],
[
"src/grbl/utf8.c",
"804bba899d6a9b26a9b270e272d13cd4dab4f8ec"
],
[
"src/grbl/utf8.h",
"4e25c4ce43ca3fafe6f8a836ff07e9157e37b3fc"
],
[
"src/grbl/vfs.c",
"6ff15a7f243cb26b014e15412ae6ea02a5e854cf"
],
[
"src/grbl/vfs.h",
"248e14d2c709a0516d1ef06a96d5515c9429d453"
],
[
"src/grbl_eeprom_extensions.c",
"11ba85320531eb4b1ecc9f47b22a86af21ea884c"
],
[
"src/grbl_eeprom_extensions.h",
"cd0e146946314f4a9209d319b0444a652f6058ff"
],
[
"src/main.c",
"39496854790279a388186530935330dc63e88967"
],
[
"src/my_machine.h",
"ddad566c397741ec66a25d38ef99aca9df643d5a"
],
[
"src/platform.h",
"25ee54c4a9c1094f4321c411ecc775753962ce6e"
],
[
"src/platform_linux.c",
"29e014ab05f488b37c218595d698358f6a48abba"
],
[
"src/serial.c",
"a3de978f199a95cf257653213bb42cf9ccfe4978"
],
[
"src/serial.h",
"9c6b6129e737ac8cc6a677f153f7cd4c187defdc"
],
[
"src/stepper_stream.c",
"a5044774ed455c94d7e68282fa3c565d1026e965"
],
[
"src/stepper_stream.h",
"342de940d3eb853d420e9fac087c17f80b54ecf4"
],
[
"tests/bind_addr_test.c",
"6e94126c0f7de57839d707c64f695abf6773d351"
],
[
"tests/cooling_test.c",
"b23762baf36da7a9fc17cfb5df00a6e66d7aef7d"
],
[
"tests/laser_arm_test.c",
"5c806eb77f84232568799273b3ce0d37032facd9"
],
[
"tests/latch_test.c",
"7740f4ed4e1cb10daaca6d4f3783f58c32f1a7fd"
],
[
"tests/lens_home_test.c",
"0eba8f412da1d3c0ddaae0a37a7032301ef47c5c"
],
[
"tests/serial_test.c",
"a6697b433e60560fa98e97d695dbbd51141313b5"
],
[
"tests/switch_map_test.c",
"6afe7e8a2839420045b181c1a770b204d29cb61e"
],
[
"tests/switches_test.c",
"884fb35bdd02e8104daf52ecccd09a58316774b6"
],
[
"tests/xy_scale_test.c",
"557832a29e7d33a4c75c9ef10d19c11699eee8ed"
]
],
"pv": "0.1.20",
"recipes": [
"grblhal-glowforge"
],
"source": "gitsm://github.com/openglow-org/grblHAL-glowforge.git",
"srcrev": "b34636f5fbce586e375c7d4c4d474ee20c3c69b7"
},
"kernel-module-glowforge": {
"component": "kernel-module-glowforge",
"files": [
[
".gitattributes",
"1b30e1b56dcc0411c10ee780053d04f1c9d862e1"
],
[
".github/workflows/build.yml",
"2073e161c4686ed9a06ca211ea869ee3b60945b9"
],
[
".gitignore",
"9ade51c849fa44bc129ca7e4c07d7e8b6faf4107"
],
[
"AGENTS.md",
"b1ebe04b43be30c85ee80efc64e858c59336a313"
],
[
"CONTRIBUTING.md",
"ca2a98e7d617e1bca2b2f814a598e94f89186c6e"
],
[
"LICENSE",
"d159169d1050894d3ea3b98e1c965c4058208fe1"
],
[
"Makefile",
"b1cb12d2bc437a8de5a015b7f86f3c452ee58c3f"
],
[
"README",
"7d5f0f7761ccd4ded2e5e37b0013d73a52074565"
],
[
"asm/sdma.asm",
"34e14740ca57a743854b1a0229b61cda8f00d0e5"
],
[
"src/cnc.c",
"5c6df39dcafe20aa37fe63019ff12d8e6894082f"
],
[
"src/cnc.h",
"fdc00c9d5259cf97bec90da3396308f00c1acbab"
],
[
"src/cnc_api.c",
"988a3658ef3885bbf0c32e98e12ffeaadf20eab9"
],
[
"src/cnc_backtrack.h",
"55652dfda3cd381b20be269bfd79e2c7e923227a"
],
[
"src/cnc_buffer.c",
"8c84c37557e38adafc0b0af7ab7966414946a023"
],
[
"src/cnc_interlock.c",
"534f77c8260c309d8bd84f3899c4f3d632b542fb"
],
[
"src/cnc_interlock.h",
"9924eead9eb5885f46e82b064795f3c0d4d5aede"
],
[
"src/cnc_pins.c",
"408787d5d33da596c22ed3f23ed6cbaeb9299091"
],
[
"src/cnc_pins.h",
"590c3eb676effbf67a4668c6507eb26785a5e2f5"
],
[
"src/cnc_private.h",
"772b642e7651341f432f4f51ca3898aeddf21ab0"
],
[
"src/device_attr.h",
"7a8ed5fcb76b5d0a8173eac98b898b588fb930ab"
],
[
"src/glowforge.c",
"6be21c2bca751362c47e435f13c48a7d0cff696b"
],
[
"src/head.c",
"d065d401ecddabe3b4b5dbc349802f5ebf8a2c5c"
],
[
"src/head.h",
"334cb8005b2b3de8eee799702d2eefc923ca724c"
],
[
"src/head_api.c",
"36e4bd7774b96d0869fa17335b49b08d778ab247"
],
[
"src/head_private.h",
"7ca4e193e1120df591772df2320bc5b0df65f628"
],
[
"src/io.c",
"27d5f80bf8eceaec73831bdc026cb77228c42736"
],
[
"src/io.h",
"6efabf89f7ba7664d168440912b98a7c9243ccad"
],
[
"src/ledtrig_smooth.c",
"0bc91005f0e7945bd446166112e289fb0090acc7"
],
[
"src/ledtrig_smooth.h",
"35f34da961d4ee6ffb3a46c8644ce589485422cf"
],
[
"src/notifiers.h",
"34beea3fbae5ea8d1bbced04b37c65f496d2c1bb"
],
[
"src/pic.c",
"d7948deeec31630b3b407c22803c852031c1007c"
],
[
"src/pic.h",
"b98990cc24da324aa4d4f479c0f21f9bff0ddc13"
],
[
"src/pic_api.c",
"fdc109405d05be86ab9d3615ef676aba3be03a05"
],
[
"src/pic_leds.c",
"f924f89818d58a877015c59e1250a1b5d97affaf"
],
[
"src/pic_private.h",
"f0166df6bae29f90e1769f11c93122db75a80cd8"
],
[
"src/sdma_macros.h",
"d2e6ded41d03f7d1c1c5f9bd8ec12bb7811a50a2"
],
[
"src/thermal.c",
"93c493bc64643f7a71dd11c8b270f8ea9238a575"
],
[
"src/thermal.h",
"ac1d96d0a63d4ba2743e52417866e12dbff21657"
],
[
"src/thermal_private.h",
"5d2b537cd8c4aecee44b9e173829a36f3dadb835"
],
[
"src/uapi/glowforge.h",
"8dfaccc6429f53b3304405faf7d86a901ed91da0"
],
[
"tests/.gitignore",
"ac0ef50598381333a202c0b4648aebc535684f6d"
],
[
"tests/Makefile",
"ed7c6275194be55bf0842a15fd105abe07ddb1c1"
],
[
"tests/backtrack_test.c",
"509449f7d59a55f6634ed040c70f9e2eeb594220"
],
[
"tests/interlock_test.c",
"c4834dd119167672e0b6cc17f2ac745991cfccdc"
],
[
"tools/mx51_sdma_set.pm",
"34379246106cca3bd2aab4c8475fcadbd48848f9"
],
[
"tools/sdma_asm.pl",
"003c76c9b2e7f7b6103ce288a53af82bb9bf5885"
]
],
"pv": "0.0.6",
"recipes": [
"kernel-module-glowforge"
],
"source": "git://github.com/openglow-org/kernel-module-glowforge.git",
"srcrev": "1860ff501cb9dd6f9b562469e303318fd802916a"
},
"linux-fslc": {
"component": "linux-fslc",
"config_sha256": "0132e95f6134ff0c6a1cd1ff4aff3709ce5f55d786c4b5090219d33cf3d14176",
"files": [
[
"@config",
"0132e95f6134ff0c6a1cd1ff4aff3709ce5f55d786c4b5090219d33cf3d14176"
],
[
"@srcrev",
"844aa3471b97053b0a59f68d36dc6f796338b562"
]
],
"linux_version": "6.12.20",
"pv": "6.12.20+git",
"recipes": [
"linux-fslc"
],
"source": "git://github.com/Freescale/linux-fslc.git",
"srcrev": "844aa3471b97053b0a59f68d36dc6f796338b562"
},
"python3-gfhardware": {
"component": "python3-gfhardware",
"files": [
[
".gitattributes",
"1b30e1b56dcc0411c10ee780053d04f1c9d862e1"
],
[
".github/workflows/host-tests.yml",
"58584524c1d484feb3ca9e4b3f1cc8bc1b4e6516"
],
[
".gitignore",
"2d6f9ccefa02c61cfd5cabc2d8b171025eadce09"
],
[
"AGENTS.md",
"620fcc0024033e662602ff361b45ce164bed2ff6"
],
[
"CONTRIBUTING.md",
"ca2a98e7d617e1bca2b2f814a598e94f89186c6e"
],
[
"LICENSE",
"d80cdb21e95685fdf696b2e01895bae8114ff927"
],
[
"LICENSE.LGPL-2.1",
"04bb156e77d5714dc2ee29bd0a37f16532ec741c"
],
[
"MANIFEST.in",
"e88a5f7bb02d90ece462ac8f196691fc5f1a61b6"
],
[
"README.md",
"d730969bc812a458c370bede7a23213a3c57499a"
],
[
"forgefirm-app/ffmachine.py",
"f12e15645decdbdbc95f9b5297704a440d205d27"
],
[
"forgefirm-app/gfcloud.init",
"0eb7c8d367315510ab492a13d6b28cbbb6fa860d"
],
[
"forgefirm-app/gfcloud.py",
"0a0d9868078df5c20f0234efdd3d111efa628436"
],
[
"forgefirm-app/gfhome.conf.sample",
"d00bf0e00c8a795443f95c6f227c8d8df3291869"
],
[
"forgefirm-app/gfhome.py",
"621060d3dcc1873095875fc83e532616c6fc1283"
],
[
"gfhardware/__init__.py",
"d4145850379d8919241f1de6d5148f275146987d"
],
[
"gfhardware/_common.py",
"d431911c90c0fea6bf3d8d869c8fbd23c3ff398c"
],
[
"gfhardware/cam.py",
"dd082c7c91e5ce5a1932585d454185d1558863f7"
],
[
"gfhardware/cnc.py",
"63f3d5a5544bb602ae8efd2b11c69c4ae84fc502"
],
[
"gfhardware/cooling.py",
"418a689e7958efbb39606848436b2c63dbec476d"
],
[
"gfhardware/coolsvc.py",
"e9c27f28f30da3d3b7ef0b4e6e0435cebc52e703"
],
[
"gfhardware/feeder.py",
"1387fd8f640d91bb58dc4ddfe9134c8d1335a240"
],
[
"gfhardware/id.py",
"3ad32e9a32a097dd5b916621ca70f4813effe2c1"
],
[
"gfhardware/input/__init__.py",
"02c064daf4e04ace8c8f318dc0254b9cbe22a610"
],
[
"gfhardware/leds.py",
"354d71cef35bcb714129fd216fa38951ddedb97f"
],
[
"gfhardware/machine.py",
"dcea1652c678af140d309b65c7aa85b2120f1f6e"
],
[
"gfhardware/src/bayer.c",
"61a1b9d54b8a4e718b4c55af7ae601a8840876ce"
],
[
"gfhardware/src/bayer.h",
"499f91dd8f22d21f6e91da2f7d3f13b55a88cbf5"
],
[
"gfhardware/src/evdev.c",
"723630aee75f46995aee59552e5ef48d08ee5a18"
],
[
"gfhardware/src/gfcam.c",
"b0900f0e1ca94ecd30c922f2459011b1729f0227"
],
[
"gfhardware/switches.py",
"80fd05df3f629f246eb480bd7d9c03bd9c9eb6ec"
],
[
"gfhardware/utils/__init__.py",
"e69de29bb2d1d6434b8b29ae775ad8c2e48c5391"
],
[
"gfhardware/utils/capture.py",
"ebf94278b686f9838e82d8024a9bf9511f91a951"
],
[
"gfhardware/z_axis.py",
"2a27d0f3bbd2f3fb45ba67a65f9b861455dc3900"
],
[
"requirements.txt",
"1e3c0f0dc607867f671e470f039971a81e4a6c47"
],
[
"setup.py",
"3ef5a500f23461b0ad9ed86388f009edafb1fcac"
],
[
"tests/test_cam_lid_gate.py",
"d97dc1af7d46d3c1c2ee1861ea44e344063423dc"
],
[
"tests/test_feeder.py",
"8dd86655b52495a9247b5ae968ae777b5e7365a6"
],
[
"tests/test_ffmachine_agent.py",
"79e0927955c7b5f00b9032f72f9fab9284e5b4f6"
],
[
"tests/test_ffmachine_emulator.py",
"5de6c0f6359616f1e253f9c3c047180a9f106440"
],
[
"tests/test_ffmachine_park.py",
"e83d97622e8807657374c87ea443f4ba1ef7ba58"
],
[
"tests/test_gfhome_exit.py",
"d78d5def849e143687558d4e53931cd4c3549584"
],
[
"tests/test_gfhome_motion.py",
"581547f9565dadbeb88d72bea06c88426e31b7e1"
],
[
"tests/test_limits.py",
"25966007bac504ff75c8e5c19339c231ca43af51"
],
[
"tests/test_machine_lid_button.py",
"c7dc110f5e4c77b854b4903d8102dbfa9c156dae"
],
[
"tests/test_pulse_body.py",
"29a868bb3aa60bcdaf8e23f13a24f32eca1e433f"
],
[
"tests/test_report_secret.py",
"dc1c01f094f658fa715530612ee6ef1e0915051f"
]
],
"pv": "1.0",
"recipes": [
"python3-gfhardware"
],
"source": "git://github.com/openglow-org/python3-gfhardware.git",
"srcrev": "021323ddfbdfcd131831f916ad3c0ef1d7a59071"
},
"python3-gfutilities": {
"component": "python3-gfutilities",
"files": [
[
".gitattributes",
"b5fe1536d1689e8526dae30678ac352ee0d8a3ff"
],
[
".github/workflows/host-tests.yml",
"c51a26d023751d891d3fc5a492cafba9978970ce"
],
[
".github/workflows/release.yml",
"4d56756fafce28ced411807fd054f781962a46ec"
],
[
".gitignore",
"c55e64f1e292b91b593c9b55fb6bb6dc8f0245ab"
],
[
"AGENTS.md",
"18ae1f92aa9412a4ed7cffeb6aac153e90253340"
],
[
"CONTRIBUTING.md",
"ca2a98e7d617e1bca2b2f814a598e94f89186c6e"
],
[
"LICENSE",
"fbb95a82e4ea499c872b8967022ed2c8308ee345"
],
[
"MANIFEST.in",
"277aa5cbd57a6176bee925d8e96e00543732f336"
],
[
"README.md",
"523315d081830235abcaf83230a4554c7bf7eead"
],
[
"examples/_RESOURCES/FW/README.md",
"21e56eb42ba942b423c2d81fa59d580b5795173b"
],
[
"examples/_RESOURCES/IMG/HEAD_LASER_.230.jpg",
"227999645a7e581163d6121c26eda574403d88da"
],
[
"examples/_RESOURCES/IMG/HEAD_NO_LASER_.230.jpg",
"e0b429256d2b2c0e0fab34f39234b9dfac7ee7e0"
],
[
"examples/_RESOURCES/IMG/HOME_1.jpg",
"3f5ed57eaf40b7c5494de33fc9c47e1c62d2c564"
],
[
"examples/_RESOURCES/IMG/HOME_2.jpg",
"842c6f929d5600c9b3528c66e4e075494b56363e"
],
[
"examples/_RESOURCES/IMG/HOME_3.jpg",
"2ab3eb05b7b4e4dac28da5e53f110b6f948989c5"
],
[
"examples/_RESOURCES/IMG/HOME_4.jpg",
"85a8c108eaea4745424c13116fafcb93d95df2d1"
],
[
"examples/_RESOURCES/LOG/README.md",
"c49674cffe1be0e2130d562f84dd8bf129ba2cd6"
],
[
"examples/_RESOURCES/MOTION/1234567890-nooptions-xxxxx.puls",
"7e272e1ef07edf32635f7687f35d37b02cb56b38"
],
[
"examples/_RESOURCES/MOTION/README.md",
"cdb3bfccc30ec653d612be49faa6acebd05fd371"
],
[
"examples/_RESOURCES/MOTION/hunt-signed-offset--8-step-size-0.35306.puls",
"33008608176c44ebbf4f9fa1a61be3552e9f0154"
],
[
"examples/_RESOURCES/MOTION/motions_xxxxx.puls",
"4363f395aa4aaa9789e48da506ac1b3d270cd44d"
],
[
"examples/_RESOURCES/README.md",
"472e2165e1f5584fbf1ee32f1e7389eeadb2f50b"
],
[
"examples/gf-machine-emulator.cfg.sample",
"2107a29984f9dad19e397c05b6084c159bfc768e"
],
[
"examples/gf-machine-emulator.py",
"e23655abd4df294a110be56ebca7c9dfac48fc7b"
],
[
"gfutilities/__init__.py",
"c84aa7dedaca7c16bccd8ddb046163fdf8e4d241"
],
[
"gfutilities/_common.py",
"5f93dc7452beb801688dfc5c1c3162fd9ed3b94e"
],
[
"gfutilities/configuration.py",
"fb5035b443097a682533cfb13b90ab247352ac41"
],
[
"gfutilities/device/__init__.py",
"2b0dfe14eb8753468f0c7e12d2d104d5cf06cbcb"
],
[
"gfutilities/device/basemachine.py",
"02dc0b0ec6528e19fdd1fdd1d6f1bc64c8411f0b"
],
[
"gfutilities/device/emulator.py",
"4d8a14b2b0cc87e3a6272c38de0fa3718588d9be"
],
[
"gfutilities/device/settings.py",
"5e43b0b0658dfc35c4bffc3b7e6dafc065a602d9"
],
[
"gfutilities/puls/__init__.py",
"dc4922fcd65d81c45b64b087bd39f4e0342b627e"
],
[
"gfutilities/puls/pulsedata.py",
"a6aad2c980e317a4d81298728ab68883b5b3f6e9"
],
[
"gfutilities/puls/source.py",
"2b0afc7156415af187fdd9acddb7dfe5c6309eaf"
],
[
"gfutilities/service/__init__.py",
"2b0dfe14eb8753468f0c7e12d2d104d5cf06cbcb"
],
[
"gfutilities/service/authentication.py",
"ca8e6e5555ff282c044c19a7ce4c1289f105730e"
],
[
"gfutilities/service/dispatch.py",
"5725145546e893a155cee5168849ac140fdcd42e"
],
[
"gfutilities/service/gfuiservice.py",
"8f44c5a92000d102f7de5759cf39cc150189545f"
],
[
"gfutilities/service/offline.py",
"8c14a18b39b9815e116a1c50e92a48cf43cb42f5"
],
[
"gfutilities/service/websocket.py",
"7a3611939b729e73af02758d944a9cbc466dd24b"
],
[
"requirements.txt",
"6408a4e749a2c4011916373f3c35279f61a80442"
],
[
"setup.py",
"89a704ba9939195fd8a222f094877e05a223502b"
],
[
"tests/test_basemachine.py",
"9ec98c7ec28f18e43e9cd624ace4111d94805606"
],
[
"tests/test_dispatch.py",
"451d94cdc2233cde10f8566be4f96582db348562"
],
[
"tests/test_firmware_policy.py",
"07ac6a9b98ad808ef04da300ecf6d1ef703a4972"
],
[
"tests/test_frame.py",
"82c130bb666f05109325d931b15239ab7d675de9"
],
[
"tests/test_lifecycle.py",
"6b8efce087ca2479d05487c1a6a98e935b800774"
],
[
"tests/test_offline.py",
"722d5be142182a8421b6008044bba5a083f9a054"
],
[
"tests/test_puls_header.py",
"3d60b6ac21d461cc6cc3c1918e4de12fb7203562"
],
[
"tests/test_pulse_source.py",
"2065a943cd1a06f9b02c89c2aaba73b6755472f9"
],
[
"tests/test_pulsedata.py",
"ba9ce1993e253962a6315809f61bb0b83070ade8"
],
[
"tests/test_user_agent.py",
"e3629ffc4acb1063a5443e0bb700b414bd54e5b3"
]
],
"pv": "0.9.19+git",
"recipes": [
"python3-gfutilities"
],
"source": "git://github.com/openglow-org/Glowforge-Utilities.git",
"srcrev": "0a93ebf30b409dc43bd42240216c4d389904a7f4"
}
},
"content_sha256": "e7ca694f20116a46222907e7ba9222021efd2c007f9394f8b3bb9f3ff14875ba",
"format": 1,
"image": {
"name": "forgefirm-image-dev",
"version": "20260928194539 (dev)"
},
"platform": {
"dtb": {
"glowforge.dtb": "47b59c57312fd7b251ed194a820eb79d4f61312b2fdb8adac58b04ca415f228a",
"imx6dl-glowforge-v2.dtb": "47b59c57312fd7b251ed194a820eb79d4f61312b2fdb8adac58b04ca415f228a",
"imx6dl-glowforge-v20.dtb": "47b59c57312fd7b251ed194a820eb79d4f61312b2fdb8adac58b04ca415f228a"
},
"kernel_modules": [
"6.12.20-fslc-fslc"
],
"layers": {
"meta": {
"rev": "70ed6f677234d32198371a030178d2f272cf2d94"
},
"meta-forgefirm": {
"content_sha256": "ca73b4c081b5eab2ebf81ccfd1b871712cea069f187e032ae58f78d026c3d9fc"
},
"meta-freescale": {
"rev": "b699d026506a6fc402e03afb432dcabd3d81c7ab"
},
"meta-freescale-distro": {
"rev": "b9d6a5d9931922558046d230c1f5f4ef6ee72345"
},
"meta-glowforge-bsp": {
"content_sha256": "a2a42a79d36b81aa35ed3b5b32380f408bd422dca3dc381799826cdafe849a0b"
},
"meta-networking": {
"rev": "b0c2c648a1af89e7a8dd4c2ec841f3bc0ed0ccb9"
},
"meta-oe": {
"rev": "b0c2c648a1af89e7a8dd4c2ec841f3bc0ed0ccb9"
},
"meta-openglow-core": {
"content_sha256": "d708115282670cb9907ff08e62b3a0c06a912d218941b989a00ff85c0b7d4716"
},
"meta-poky": {
"rev": "70ed6f677234d32198371a030178d2f272cf2d94"
},
"meta-python": {
"rev": "b0c2c648a1af89e7a8dd4c2ec841f3bc0ed0ccb9"
}
},
"machine": "glowforge"
}
},
"manifest_sha": "e7ca694f20116a46222907e7ba9222021efd2c007f9394f8b3bb9f3ff14875ba",
"sha256": "550c90e31d327d69f16407ad7539c09cd34c08711fdb62dd479321db2d5c07da",
"tests": [
{
"always": true,
"covers": [
[
"forgectrl",
"init/**"
],
[
"forgeext",
"init/**"
],
[
"forgectrl",
"src/main.c"
],
[
"forgectrl",
"src/auth.c"
],
[
"forgectrl",
"CMakeLists.txt"
],
[
"grblhal-glowforge",
"src/boards/**"
],
[
"grblhal-glowforge",
"CMakeLists.txt"
],
[
"kernel-module-glowforge",
"**"
],
[
"linux-fslc",
"**"
]
],
"fingerprint": "5f7b52988eb551f46e15751458aaca7136f17956a16b810a5f8c1fa3415af238",
"hardware": "api",
"id": "image.health",
"inherited": false,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260929000044-e1ea",
"duration_s": 1,
"evidence": {
"/data/forgefirm": "711",
"/data/forgefirm/forgefirm.conf": "600",
"/data/forgefirm/panel.token": "600",
"/etc/issue": "\n \u001b[1;31m \u273a\u2508\u2508\u2508\u2508\u2508\u2508\n \u001b[1;39mOpen\u001b[0mGlow\n ___ \u001b[1;39m___ ___ ___ __ __\u001b[0m\n | __|__ _ _ __ _ ___\u001b[1;39m| __|_ _| _ \\\\ \\\\/ |\u001b[0m\n | _/ _ \\\\ '_/ _` / -_) \u001b[1;39m_| | || / |\\\\/| |\u001b[0m\n |_|\\\\___/_| \\\\__, \\\\___|\u001b[1;39m_| |___|_|_\\\\_| |_|\u001b[0m\n |___/ 20260928194539 (dev)\n\nControl panel:\n https://<IP-1>/\n\n",
"/etc/motd": "\n \u001b[1;31m \u273a\u2508\u2508\u2508\u2508\u2508\u2508\n \u001b[1;39mOpen\u001b[0mGlow\n ___ \u001b[1;39m___ ___ ___ __ __\u001b[0m\n | __|__ _ _ __ _ ___\u001b[1;39m| __|_ _| _ \\ \\/ |\u001b[0m\n | _/ _ \\ '_/ _` / -_) \u001b[1;39m_| | || / |\\/| |\u001b[0m\n |_|\\___/_| \\__, \\___|\u001b[1;39m_| |___|_|_\\_| |_|\u001b[0m\n |___/ 20260928194539 (dev)\n\n",
"CONFIG_IMX2_WDT": "y",
"CONFIG_PANIC_ON_OOPS": "y",
"CONFIG_PREEMPT": "y",
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-29T00:00:44Z"
},
"cnc_free": 33521664,
"cnc_pool_bytes": 33554432,
"cnc_ring_bytes": 33554432,
"cnc_state": "idle",
"data_free_mb": 2807,
"dev_image": true,
"extension_host_pids": [
482
],
"extension_packages": [],
"factory_mounts": [
"/factory/img1",
"/factory/img2"
],
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-2>",
"released": []
},
"forgectrl_pids": [
473
],
"forgeext_links": {
"kill": [
"K09forgeext"
],
"start": [
"S91forgeext"
]
},
"forgefirm_version": "20260928194539 (dev)",
"kernel_release": "6.12.20-fslc-fslc-g21f36a8c1ebe",
"logging_init": [
"forgefirm-logging"
],
"mode": {
"controller": "running",
"gated": false,
"local": false,
"mode": "grbl",
"motion": "verified",
"pid": 882,
"why": ""
},
"motd_columns": [
41,
41
],
"mounts": {
"/": {
"opts": [
"ro",
"relatime"
],
"source": "/dev/root",
"type": "ext4"
},
"/data": {
"opts": [
"rw",
"relatime"
],
"source": "/dev/mmcblk2p3",
"type": "ext4"
},
"/etc/hostname": {
"opts": [
"rw",
"nosuid",
"nodev",
"mode=755"
],
"source": "tmpfs",
"type": "tmpfs"
},
"/etc/issue": {
"opts": [
"rw",
"nosuid",
"nodev",
"mode=755"
],
"source": "tmpfs",
"type": "tmpfs"
},
"/etc/passwd": {
"opts": [
"rw",
"nosuid",
"nodev",
"mode=755"
],
"source": "tmpfs",
"type": "tmpfs"
},
"/var/lib": {
"opts": [
"rw",
"relatime"
],
"source": "tmpfs",
"type": "tmpfs"
}
},
"pool_processes": 0,
"pulse_device_holders": [
473
],
"rc6_kill": [
"K09forgeext",
"K09sshd",
"K20dbus-1",
"K20hwclock.sh",
"K20ntpd",
"K31umountnfs.sh",
"K70forgetest",
"K80gfcloud",
"K80grblhal",
"K80networking",
"K90forgectrl",
"K95syslog"
],
"record_accounts": [
"scott"
],
"sdma_clk_enable_count": "1",
"userspace_watchdog_pids": [],
"watchdog": {
"bootstatus": "0",
"identity": "imx2+ watchdog",
"period_s": 60.0,
"state": "inactive",
"timeout": "60",
"wcr": "0x771f",
"wde": true
}
},
"fingerprint": "5f7b52988eb551f46e15751458aaca7136f17956a16b810a5f8c1fa3415af238",
"image": "20260928194539 (dev)",
"log": [
"00:00:44 start image.health (auto, api) in campaign c-20260929000044-e1ea",
"00:00:44 fixture up: <REDACTED-1> at <IP-2>, v1.0.0, covers lid, interlock, button",
"00:00:44 fixture: <REDACTED-1> at <IP-2> covers lid, interlock, button",
"00:00:44 queued by the unattended queue opened 2026-09-29T00:00:44Z",
"00:00:45 baseline: pre: clean",
"00:00:45 forgefirm-version: 20260928194539 (dev) (manifest: 20260928194539 (dev))",
"00:00:45 CONFIG_PREEMPT=y",
"00:00:45 CONFIG_IMX2_WDT=y",
"00:00:45 CONFIG_PANIC_ON_OOPS=y",
"00:00:45 watchdog0: {'identity': 'imx2+ watchdog', 'state': 'inactive', 'timeout': '60', 'bootstatus': '0', 'wcr': '0x771f', 'wde': True, 'period_s': 60.0}",
"00:00:45 kernel release 6.12.20-fslc-fslc-g21f36a8c1ebe (manifest modules dirs: 6.12.20-fslc-fslc)",
"00:00:45 cnc/state: idle",
"00:00:45 cnc/free: 33521664 bytes",
"00:00:45 cnc-pulsebuf pool: 33554432 bytes, ring_mb: 33554432 bytes",
"00:00:45 sdma clk_enable_count: 1",
"00:00:45 forgectrl pids [473], holding /dev/glowforge: [473]",
"00:00:45 mode: {'mode': 'grbl', 'controller': 'running', 'pid': 882, 'motion': 'verified', 'gated': False, 'local': False, 'why': ''}",
"00:00:45 rc6.d: K09forgeext K09sshd K20dbus-1 K20hwclock.sh K20ntpd K31umountnfs.sh K70forgetest K80gfcloud K80grblhal K80networking K90forgectrl K95syslog",
"00:00:45 extension host pid [482], packages [], pool processes 0",
"00:00:45 /data/forgefirm/panel.token mode 600",
"00:00:45 /data/forgefirm/forgefirm.conf mode 600",
"00:00:45 /data/forgefirm mode 711",
"00:00:45 /data free: 2807 MiB",
"00:00:45 / mounted ro,relatime; /data rw,relatime; /var/lib rw,relatime",
"00:00:45 dev image True; /factory mounts: ['/factory/img1', '/factory/img2']",
"00:00:45 manifest e7ca694f2011: 10 components",
"00:00:45 baseline: post: clean",
"00:00:45 result PASS"
],
"manifest_sha": "e7ca694f20116a46222907e7ba9222021efd2c007f9394f8b3bb9f3ff14875ba",
"message": "",
"result": "PASS",
"test": "image.health",
"ts": "2026-09-29T00:00:45Z"
},
"requires": [],
"satisfied": true,
"source_sha": "d2263638274985c6eeb5e2e360bd17be1a32e21af8403f3b37931c94f236650f",
"subsystem": "image",
"title": "Post-flash image health"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/main.c"
],
[
"forgectrl",
"src/ui/index.html"
],
[
"forgectrl",
"src/ui/wizard.html"
],
[
"forgectrl",
"src/ui/login.html"
]
],
"fingerprint": "eab5253221065fcec44a1d6b8a5460f0287976f8ff5dce819763b0680d903a0a",
"hardware": "api",
"id": "image.license-bundle",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928162331-3969",
"duration_s": 3,
"evidence": {
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T16:23:31Z"
},
"bundle_bytes": 697506,
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"generic_texts": 413,
"packages": 268
},
"fingerprint": "eab5253221065fcec44a1d6b8a5460f0287976f8ff5dce819763b0680d903a0a",
"image": "20260928153805 (dev)",
"log": [
"16:23:34 start image.license-bundle (auto, api) in campaign c-20260928162331-3969",
"16:23:34 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:23:34 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"16:23:34 queued by the unattended queue opened 2026-09-28T16:23:31Z",
"16:23:34 baseline: pre: clean",
"16:23:34 /usr/share/forgefirm/licenses.tar.gz: 697506 bytes",
"16:23:36 manifest lists 268 packages; 413 generic license entries",
"16:23:38 baseline: post: clean",
"16:23:38 result PASS"
],
"manifest_sha": "faf9563c750bb8bd4bfc8778b6af053cddb63fa335ab946caf2f71631ede740f",
"message": "",
"result": "PASS",
"test": "image.license-bundle",
"ts": "2026-09-28T16:23:38Z"
},
"requires": [
"forgectrl.panel-serves"
],
"satisfied": true,
"source_sha": "b991ef1556725f2fafe6d71607200a4bf6cfd0d5dd8f8a3dfa037b339c4bb70e",
"subsystem": "image",
"title": "The license texts travel with the image"
},
{
"always": false,
"covers": [],
"fingerprint": "b95dfba05f86757c51c74d09a008919604be9204a3083f27f3d5bc969c60d312",
"hardware": "api",
"id": "image.network-boot",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928162331-3969",
"duration_s": 0,
"evidence": {
"accept_ra": "1",
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T16:23:31Z"
},
"dhcp6_running": [],
"disable_ipv6": "0",
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"getty": [
"/sbin/getty -L 115200 ttymxc0 vt102"
],
"global": [],
"ifstate": [
"lo",
"wlan0"
],
"ifup_running": [],
"interfaces_dhcp6": [],
"link_local": [
"<HEX-1>"
],
"udhcpc": [
"udhcpc -R -b -p /var/run/udhcpc.wlan0.pid -i wlan0 -x hostname:forgefirm-b00a"
]
},
"fingerprint": "b95dfba05f86757c51c74d09a008919604be9204a3083f27f3d5bc969c60d312",
"image": "20260928153805 (dev)",
"log": [
"16:23:38 start image.network-boot (auto, api) in campaign c-20260928162331-3969",
"16:23:38 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:23:38 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"16:23:38 queued by the unattended queue opened 2026-09-28T16:23:31Z",
"16:23:38 baseline: pre: clean",
"16:23:38 wlan0: 1 link-local, 0 global IPv6 address(es)",
"16:23:38 baseline: post: clean",
"16:23:38 result PASS"
],
"manifest_sha": "faf9563c750bb8bd4bfc8778b6af053cddb63fa335ab946caf2f71631ede740f",
"message": "",
"result": "PASS",
"test": "image.network-boot",
"ts": "2026-09-28T16:23:38Z"
},
"requires": [],
"satisfied": true,
"source_sha": "e36268995e8598c3a568eef2f838aa144c8976508ba348a5ac7fae6c58697daf",
"subsystem": "image",
"title": "The boot does not wait on the network"
},
{
"always": true,
"covers": [
[
"kernel-module-glowforge",
"**"
],
[
"linux-fslc",
"**"
],
[
"forgectrl",
"src/super.c"
],
[
"grblhal-glowforge",
"src/glowforge_laser.c"
],
[
"grblhal-glowforge",
"src/driver.c"
]
],
"fingerprint": "ebb02a0ccf540ad878936d460f39c74f193eb309cf77ee76d2d7fa7863dbee40",
"hardware": "api",
"id": "kernel.latch-locked-idle",
"inherited": false,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260929000044-e1ea",
"duration_s": 0,
"evidence": {
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-29T00:00:44Z"
},
"cnc_state": "idle",
"faults": 0,
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"forgectrl_laser_locked": true,
"interlock_circuit": 45,
"laser_enable": 0,
"laser_on": 0,
"laser_on_sampled": 0
},
"fingerprint": "ebb02a0ccf540ad878936d460f39c74f193eb309cf77ee76d2d7fa7863dbee40",
"image": "20260928194539 (dev)",
"log": [
"00:00:45 start kernel.latch-locked-idle (auto, api) in campaign c-20260929000044-e1ea",
"00:00:46 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"00:00:46 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"00:00:46 queued by the unattended queue opened 2026-09-29T00:00:44Z",
"00:00:46 baseline: pre: clean",
"00:00:46 cnc/state: idle",
"00:00:46 interlock_circuit: 45 (0x2d)",
"00:00:46 laser_enable (FIRE line): 0",
"00:00:46 laser_on: 0, laser_on_sampled: 0",
"00:00:46 faults: 0",
"00:00:46 forgectrl /status laser_locked=True state=idle",
"00:00:46 baseline: post: clean",
"00:00:46 result PASS"
],
"manifest_sha": "e7ca694f20116a46222907e7ba9222021efd2c007f9394f8b3bb9f3ff14875ba",
"message": "",
"result": "PASS",
"test": "kernel.latch-locked-idle",
"ts": "2026-09-29T00:00:46Z"
},
"requires": [],
"satisfied": true,
"source_sha": "1788ae024ad871dcb952cacf773e71aa7f7312ceccf8eaf07019ef080a2e6df4",
"subsystem": "kernel",
"title": "Laser latch locked at idle"
},
{
"always": true,
"covers": [
[
"kernel-module-glowforge",
"**"
],
[
"linux-fslc",
"**"
]
],
"fingerprint": "9fac93f2ee9f2af59117502668fe71ebe909498471306af6c6b851876fa4d13e",
"hardware": "takeover",
"id": "kernel.k1-k2",
"inherited": false,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260929000044-e1ea",
"duration_s": 20,
"evidence": {
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-29T00:00:44Z"
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"k1": {
"faults": "0",
"state": "idle",
"stop_to_idle_s": 0.0908
},
"k2": {
"end_state": "idle",
"faults": "0",
"hits": [],
"laser_on_sampled": "0",
"pos_after": [
2764,
10241,
0,
55001,
55001
],
"pos_before": [
2764,
10241,
0,
0,
55001
],
"underruns": "0"
}
},
"fingerprint": "9fac93f2ee9f2af59117502668fe71ebe909498471306af6c6b851876fa4d13e",
"image": "20260928194539 (dev)",
"log": [
"00:00:46 start kernel.k1-k2 (auto, takeover) in campaign c-20260929000044-e1ea",
"00:00:46 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"00:00:46 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"00:00:46 queued by the unattended queue opened 2026-09-29T00:00:44Z",
"00:00:47 baseline: pre: clean",
"00:00:47 takeover: waiting for forgectrl to be settled",
"00:00:47 baseline: /mode controller=running motion=verified",
"00:00:47 takeover: preserving cnc/motor_lock=0, cnc/step_freq=112640, cnc/ramp_rate=500000, cnc/streaming=0, cnc/x_mode=32, cnc/y_mode=32, cnc/x_decay=1, cnc/y_decay=1, pic/x_step_current=33, pic/y_step_current=5",
"00:00:47 takeover: stopping the controller through forgectrl",
"00:00:47 takeover: POST /controller/stop -> 200",
"00:00:47 takeover: forgectrl stop -> rc 0",
"00:00:48 takeover: pulse device free",
"00:00:48 K1: 60001 bytes = 6.0 s of pads at 10000 Hz, ramp 125000 Hz/s",
"00:00:48 K1 pre: state=idle laser_enable=0 laser_on=0 laser_on_sampled=0 interlock=45",
"00:00:50 K1 controlled stop: state=idle after 0.0908 s, faults=0",
"00:00:55 K1 PASS: decelerating tail 0.0908 s, no burst, no fault",
"00:00:55 K2: 55001 bytes = 5.5 s; latch stays LOCKED; waypoint +200; motor_lock=15",
"00:00:55 K2 pre: state=idle laser_enable=0 laser_on=0 laser_on_sampled=0 interlock=13",
"00:00:56 K2: paused inside the pads; resuming with waypoint +200 (latch LOCKED)",
"00:01:01 K2 post: state=idle laser_enable=0 laser_on=0 laser_on_sampled=0 interlock=13",
"00:01:01 K2 done: state=idle pos before=(2764, 10241, 0, 0, 55001) after=(2764, 10241, 0, 55001, 55001)",
"00:01:01 K2 PASS: FIRE window replayed after the resume waypoint with laser_enable/laser_on at 0 throughout",
"00:01:01 takeover: forgectrl start -> rc 0",
"00:01:03 baseline: /mode controller=stopped motion=unverified",
"00:01:07 baseline: /mode controller=running motion=verified",
"00:01:07 baseline: position: [0, 0, 0], and [2764, 10241, 0] when the run began, but the controller re-zeroed its counters during the run (a controller start or a home): the two are not in one frame, so the head's position cannot be judged and the head is not moved",
"00:01:07 baseline: post: clean",
"00:01:07 result PASS"
],
"manifest_sha": "e7ca694f20116a46222907e7ba9222021efd2c007f9394f8b3bb9f3ff14875ba",
"message": "",
"result": "PASS",
"test": "kernel.k1-k2",
"ts": "2026-09-29T00:01:07Z"
},
"requires": [
"kernel.latch-locked-idle"
],
"satisfied": true,
"source_sha": "4e4100cbb67b89b32ce61c730efb01e5b3f113443625de26c0aae5c737a8b75d",
"subsystem": "kernel",
"title": "Controlled-stop floor and resume honors the locked latch"
},
{
"always": true,
"covers": [
[
"kernel-module-glowforge",
"**"
],
[
"linux-fslc",
"**"
]
],
"fingerprint": "d937e8b0cdcd4128675af0dcd3c9eb947904bc3f3e0a5899ac86d4eafdd10155",
"hardware": "takeover",
"id": "kernel.deadman-close",
"inherited": false,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260929000044-e1ea",
"duration_s": 9,
"evidence": {
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-29T00:00:44Z"
},
"close": {
"faults": "0",
"halt_s": 0.0369,
"interlock_circuit": 13,
"state": "idle"
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"head_after": {
"measure_laser": "0",
"uv_led": "0",
"z_current": "1",
"z_enable": "1"
},
"head_before": {
"z_current": "1",
"z_enable": "0"
}
},
"fingerprint": "d937e8b0cdcd4128675af0dcd3c9eb947904bc3f3e0a5899ac86d4eafdd10155",
"image": "20260928194539 (dev)",
"log": [
"00:01:07 start kernel.deadman-close (auto, takeover) in campaign c-20260929000044-e1ea",
"00:01:08 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"00:01:08 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"00:01:08 queued by the unattended queue opened 2026-09-29T00:00:44Z",
"00:01:08 baseline: pre: clean",
"00:01:08 takeover: waiting for forgectrl to be settled",
"00:01:08 baseline: /mode controller=running motion=verified",
"00:01:08 takeover: preserving cnc/motor_lock=0, cnc/step_freq=112640, cnc/ramp_rate=500000, cnc/streaming=0, cnc/x_mode=32, cnc/y_mode=32, cnc/x_decay=1, cnc/y_decay=1, pic/x_step_current=33, pic/y_step_current=5",
"00:01:08 takeover: stopping the controller through forgectrl",
"00:01:08 takeover: POST /controller/stop -> 200",
"00:01:08 takeover: forgectrl stop -> rc 0",
"00:01:09 takeover: pulse device free",
"00:01:09 deadman pre: state=idle laser_enable=0 laser_on=0 laser_on_sampled=0 interlock=45",
"00:01:11 deadman post: state=idle laser_enable=0 laser_on=0 laser_on_sampled=0 interlock=13",
"00:01:11 final close: state=idle after 0.0369 s; head {'z_enable': '1', 'z_current': '1', 'measure_laser': '0', 'uv_led': '0'}",
"00:01:11 PASS: the final close halted the engine in 0.037 s, latch locked, head safed",
"00:01:11 takeover: forgectrl start -> rc 0",
"00:01:13 baseline: /mode controller=stopped motion=unverified",
"00:01:17 baseline: /mode controller=running motion=verified",
"00:01:17 baseline: post: clean",
"00:01:17 result PASS"
],
"manifest_sha": "e7ca694f20116a46222907e7ba9222021efd2c007f9394f8b3bb9f3ff14875ba",
"message": "",
"result": "PASS",
"test": "kernel.deadman-close",
"ts": "2026-09-29T00:01:17Z"
},
"requires": [
"kernel.k1-k2"
],
"satisfied": true,
"source_sha": "7e3c2a86d9b58643a71d96561b2095a72289d970c398ae08c3da20c2a30c4fea",
"subsystem": "kernel",
"title": "The final close of a running pulse device halts the engine and safes the head"
},
{
"always": true,
"covers": [
[
"kernel-module-glowforge",
"**"
],
[
"linux-fslc",
"**"
]
],
"fingerprint": "2460fa666e3a26363dbd2ed525d85e79ef328d04d706f520f96beaf630075b32",
"hardware": "takeover",
"id": "kernel.backtrack-bounds",
"inherited": false,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260929000044-e1ea",
"duration_s": 18,
"evidence": {
"after": {
"faults": "0",
"max_backtrack": 0,
"state": "idle",
"underruns": "0"
},
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-29T00:00:44Z"
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"max_backtrack": 15065,
"over_long_errno": 1,
"played": 15465
},
"fingerprint": "2460fa666e3a26363dbd2ed525d85e79ef328d04d706f520f96beaf630075b32",
"image": "20260928194539 (dev)",
"log": [
"00:01:17 start kernel.backtrack-bounds (auto, takeover) in campaign c-20260929000044-e1ea",
"00:01:18 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"00:01:18 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"00:01:18 queued by the unattended queue opened 2026-09-29T00:00:44Z",
"00:01:18 baseline: pre: clean",
"00:01:18 takeover: waiting for forgectrl to be settled",
"00:01:18 baseline: /mode controller=running motion=verified",
"00:01:18 takeover: preserving cnc/motor_lock=0, cnc/step_freq=112640, cnc/ramp_rate=500000, cnc/streaming=0, cnc/x_mode=32, cnc/y_mode=32, cnc/x_decay=1, cnc/y_decay=1, pic/x_step_current=33, pic/y_step_current=5",
"00:01:18 takeover: stopping the controller through forgectrl",
"00:01:18 takeover: POST /controller/stop -> 200",
"00:01:18 takeover: forgectrl stop -> rc 0",
"00:01:19 takeover: pulse device free",
"00:01:19 60001 bytes = 6.0 s of pads at 10000 Hz; decel tail 400 steps",
"00:01:19 pre: state=idle laser_enable=0 laser_on=0 laser_on_sampled=0 interlock=45",
"00:01:21 played 15465 bytes; max_backtrack 15065",
"00:01:23 backtrack of 15065 done: state=idle max_backtrack now 0",
"00:01:29 PASS: max_backtrack tracks the played history, the boundary is enforced, and the run at it plays out clean",
"00:01:29 takeover: forgectrl start -> rc 0",
"00:01:30 baseline: /mode controller=stopped motion=unverified",
"00:01:35 baseline: /mode controller=running motion=verified",
"00:01:35 baseline: post: clean",
"00:01:35 result PASS"
],
"manifest_sha": "e7ca694f20116a46222907e7ba9222021efd2c007f9394f8b3bb9f3ff14875ba",
"message": "",
"result": "PASS",
"test": "kernel.backtrack-bounds",
"ts": "2026-09-29T00:01:35Z"
},
"requires": [
"kernel.k1-k2"
],
"satisfied": true,
"source_sha": "b1be3c6320f448c80593a33582e3a1ed6bf287e9bf327e9c3440ea31b7b4c60d",
"subsystem": "kernel",
"title": "A backward run is bounded by the history the ring still holds"
},
{
"always": true,
"covers": [
[
"kernel-module-glowforge",
"**"
],
[
"linux-fslc",
"**"
]
],
"fingerprint": "575344cabcbb36765157e375db17acb6c0def33eb6e8e3199f5a49eeabdcb92d",
"hardware": "takeover",
"id": "kernel.fire-line",
"inherited": false,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260929000044-e1ea",
"duration_s": 42,
"evidence": {
"A": {
"any_fire_driven": false,
"any_laser_on": false,
"faults": "0",
"mid": {
"interlock": "13",
"laser_enable": "0",
"laser_on": "0",
"laser_on_sampled": "0",
"t": 1.51
},
"moved": false,
"tail": {
"after_s": 6.01,
"laser_enable": "0",
"laser_on": "0",
"state": "idle"
},
"underruns_after": 0,
"underruns_before": 0
},
"B": {
"any_fire_driven": true,
"any_laser_on": false,
"faults": "0",
"mid": {
"interlock": "7",
"laser_enable": "1",
"laser_on": "0",
"laser_on_sampled": "0",
"t": 1.51
},
"moved": false,
"tail": {
"after_s": 6.0,
"laser_enable": "0",
"laser_on": "0",
"state": "idle"
},
"underruns_after": 0,
"underruns_before": 0
},
"U": {
"any_fire_driven": true,
"any_laser_on": false,
"faults": "0",
"mid": {
"interlock": "7",
"laser_enable": "1",
"laser_on": "0",
"laser_on_sampled": "0",
"t": 1.52
},
"moved": false,
"tail": {
"acked_state": "idle",
"after_s": 6.03,
"laser_enable": "0",
"laser_on": "0",
"state": "underrun"
},
"underruns_after": 1,
"underruns_before": 0
},
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-29T00:00:44Z"
},
"charge_pump_alive": "0",
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"hv_release_s": [
0.0,
0.41,
0.42,
0.36
],
"k3": {
"end_state": "idle",
"faults": "0",
"hits": [],
"interlock_after_unlock": "5",
"laser_on_sampled": "0",
"underruns": "1"
},
"kernel_state": "idle"
},
"fingerprint": "575344cabcbb36765157e375db17acb6c0def33eb6e8e3199f5a49eeabdcb92d",
"image": "20260928194539 (dev)",
"log": [
"00:01:35 start kernel.fire-line (auto, takeover) in campaign c-20260929000044-e1ea",
"00:01:36 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"00:01:36 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"00:01:36 queued by the unattended queue opened 2026-09-29T00:00:44Z",
"00:01:36 baseline: pre: clean",
"00:01:36 takeover: waiting for forgectrl to be settled",
"00:01:36 baseline: /mode controller=running motion=verified",
"00:01:36 takeover: preserving cnc/motor_lock=0, cnc/step_freq=112640, cnc/ramp_rate=500000, cnc/streaming=0, cnc/x_mode=32, cnc/y_mode=32, cnc/x_decay=1, cnc/y_decay=1, pic/x_step_current=33, pic/y_step_current=5",
"00:01:36 takeover: stopping the controller through forgectrl",
"00:01:36 takeover: POST /controller/stop -> 200",
"00:01:36 takeover: forgectrl stop -> rc 0",
"00:01:37 takeover: pulse device free",
"00:01:37 fire A: stream 60001 bytes = 6.000 s",
"00:01:37 fire A pre: state=idle laser_enable=0 laser_on=0 laser_on_sampled=0 interlock=45",
"00:01:39 fire A mid (inside FIRE window): laser_enable=0 laser_on=0 laser_on_sampled=0 interlock=13",
"00:01:43 fire A done: state=idle after 6.0 s (laser_enable=0)",
"00:01:43 fire A post: state=idle laser_enable=0 laser_on=0 laser_on_sampled=0 interlock=13",
"00:01:43 fire A: moved=False underruns 0->0 faults=0",
"00:01:43 fire A PASS: latch locked, no FIRE drive, no LASER_ON",
"00:01:43 fire B: stream 60001 bytes = 6.000 s",
"00:01:44 hv off: released after 0.41 s",
"00:01:44 fire B pre: state=idle laser_enable=0 laser_on=0 laser_on_sampled=0 interlock=45",
"00:01:44 fire B: latch UNLOCKED for this run",
"00:01:46 fire B mid (inside FIRE window): laser_enable=1 laser_on=0 laser_on_sampled=0 interlock=7",
"00:01:50 fire B done: state=idle after 6.0 s (laser_enable=0)",
"00:01:50 fire B post: state=idle laser_enable=0 laser_on=0 laser_on_sampled=0 interlock=13",
"00:01:50 fire B: moved=False underruns 0->0 faults=0",
"00:01:50 fire B PASS: FIRE driven mid-window, LASER_ON off, FIRE clear at end-of-data",
"00:01:50 fire U: stream 60001 bytes = 6.000 s",
"00:01:51 hv off: released after 0.42 s",
"00:01:51 fire U pre: state=idle laser_enable=0 laser_on=0 laser_on_sampled=0 interlock=45",
"00:01:51 fire U: streaming=1, the terminal end-of-data will be a TRUE UNDERRUN",
"00:01:51 fire U: latch UNLOCKED for this run",
"00:01:53 fire U mid (inside FIRE window): laser_enable=1 laser_on=0 laser_on_sampled=0 interlock=7",
"00:01:57 fire U done: state=underrun after 6.0 s (laser_enable=0)",
"00:01:57 fire U: underrun state reached as EXPECTED; acking via stop",
"00:01:57 fire U: acked: state=idle",
"00:01:57 fire U post: state=idle laser_enable=0 laser_on=0 laser_on_sampled=0 interlock=13",
"00:01:57 fire U: moved=False underruns 0->1 faults=0",
"00:01:57 fire U PASS: true underrun, backstop dropped FIRE, stop acked",
"00:01:58 hv off: released after 0.36 s",
"00:01:58 K3: 35001 bytes = 3.5 s of FIRE bits; ramp_rate 10000 Hz/s (~0.9 s accel window); unlock at t=+0.15 s",
"00:01:58 K3 pre: state=idle laser_enable=0 laser_on=0 laser_on_sampled=0 interlock=45",
"00:01:58 K3: latch UNLOCKED mid-ramp; interlock=5 (bit 3 should read 0)",
"00:02:02 K3 post: state=idle laser_enable=0 laser_on=0 laser_on_sampled=0 interlock=5",
"00:02:02 K3 PASS: laser_enable stayed 0 for the entire run after the mid-ramp unlock",
"00:02:02 safe state restored: state=disabled latch=LOCKED",
"00:02:02 takeover: forgectrl start -> rc 0",
"00:02:04 baseline: /mode controller=stopped motion=unverified",
"00:02:07 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"00:02:18 baseline: /mode controller=running motion=verified",
"00:02:18 baseline: post: clean",
"00:02:18 result PASS"
],
"manifest_sha": "e7ca694f20116a46222907e7ba9222021efd2c007f9394f8b3bb9f3ff14875ba",
"message": "",
"result": "PASS",
"test": "kernel.fire-line",
"ts": "2026-09-29T00:02:18Z"
},
"requires": [
"kernel.k1-k2"
],
"satisfied": true,
"source_sha": "5dba915328877d4fbd8158b8c4a5ec0292453fdb4c029f735894d600c861e461",
"subsystem": "kernel",
"title": "FIRE line: latch locked, unlocked-unarmed, true underrun, and a mid-run unlock"
},
{
"always": false,
"covers": [
[
"kernel-module-glowforge",
"**"
],
[
"linux-fslc",
"**"
]
],
"fingerprint": "c6de039e46ca997a21d1293beb7dd359b10e012f171c907dafa2c0c71f629876",
"hardware": "takeover",
"id": "kernel.resume-lead",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928162331-3969",
"duration_s": 22,
"evidence": {
"E": {
"data_s": 0.501,
"faults": "0",
"run_to_idle_s": 0.504,
"state": "idle",
"underruns_after": 1,
"underruns_before": 1
},
"L": {
"any_laser_on": false,
"driven_samples": 891,
"end_state": "idle",
"faults": "0",
"first_driven_s": 1.0034,
"inside_lead": [],
"laser_on_sampled": "0",
"last_driven_s": 2.0039,
"samples": 1956
},
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T16:23:31Z"
},
"charge_pump_alive": "0",
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"hv_release_s": [
0.0,
0.36
],
"kernel_state": "idle"
},
"fingerprint": "c6de039e46ca997a21d1293beb7dd359b10e012f171c907dafa2c0c71f629876",
"image": "20260928153805 (dev)",
"log": [
"16:25:15 start kernel.resume-lead (auto, takeover) in campaign c-20260928162331-3969",
"16:25:15 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:25:15 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"16:25:15 queued by the unattended queue opened 2026-09-28T16:23:31Z",
"16:25:15 baseline: pre: clean",
"16:25:15 takeover: waiting for forgectrl to be settled",
"16:25:15 baseline: /mode controller=running motion=verified",
"16:25:15 takeover: preserving cnc/motor_lock=0, cnc/step_freq=112640, cnc/ramp_rate=500000, cnc/streaming=0, cnc/x_mode=32, cnc/y_mode=32, cnc/x_decay=1, cnc/y_decay=1, pic/x_step_current=33, pic/y_step_current=5",
"16:25:15 takeover: stopping the controller through forgectrl",
"16:25:15 takeover: POST /controller/stop -> 200",
"16:25:16 takeover: forgectrl stop -> rc 0",
"16:25:17 takeover: pulse device free",
"16:25:17 E: 501 bytes = 0.5 s of pads at 1000 Hz; resume with a 10000-byte lead (never reached)",
"16:25:17 E pre: state=idle laser_enable=0 laser_on=0 laser_on_sampled=0 interlock=45",
"16:25:18 E: idle after 0.504 s (the data is 0.501 s; a lost end-of-data would add 0.255 s)",
"16:25:18 E PASS: end-of-data before the waypoint ended the run on time",
"16:25:18 hv off: released after 0.36 s",
"16:25:18 L: 2201 bytes = 2.2 s (2.0 s of FIRE bits then pads); lead 1000 bytes = 1.0 s; latch UNLOCKED, chain unarmed",
"16:25:18 L pre: state=idle laser_enable=0 laser_on=0 laser_on_sampled=0 interlock=45",
"16:25:21 L post: state=idle laser_enable=0 laser_on=0 laser_on_sampled=0 interlock=13",
"16:25:21 L: 1956 samples, FIRE driven in 891, first at 1.0034 s, last at 2.0039 s, end state idle",
"16:25:21 L PASS: FIRE low through the 1.0 s lead, driven from the waypoint on, LASER_ON off",
"16:25:21 safe state restored: state=disabled latch=LOCKED",
"16:25:21 takeover: forgectrl start -> rc 0",
"16:25:23 baseline: /mode controller=stopped motion=unverified",
"16:25:37 baseline: /mode controller=running motion=verified",
"16:25:37 baseline: post: clean",
"16:25:37 result PASS"
],
"manifest_sha": "faf9563c750bb8bd4bfc8778b6af053cddb63fa335ab946caf2f71631ede740f",
"message": "",
"result": "PASS",
"test": "kernel.resume-lead",
"ts": "2026-09-28T16:25:37Z"
},
"requires": [
"kernel.k1-k2"
],
"satisfied": true,
"source_sha": "3864aec6824da0e2787412e12220e2f53888934a283a30a25634bcd9d1af19f2",
"subsystem": "kernel",
"title": "A resume's laser-off lead, and an end-of-data before the waypoint"
},
{
"always": false,
"covers": [
[
"kernel-module-glowforge",
"**"
],
[
"linux-fslc",
"**"
],
[
"forgectrl",
"src/diag.c"
]
],
"fingerprint": "0293d36536bb65e2767d339c11aea4d8d0ccb224544ad986a088228172cb6b54",
"hardware": "api",
"id": "kernel.pic-soc-load",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928162331-3969",
"duration_s": 3,
"evidence": {
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T16:23:31Z"
},
"control": {
"busy": {
"iqr": 1,
"max": 662,
"mean": 653.73,
"med": 653,
"min": 649,
"n": 200
},
"idle": {
"iqr": 3,
"max": 669,
"mean": 649.75,
"med": 648,
"min": 640,
"n": 200
}
},
"control_split": 5,
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"pic_settle_us_after": "500",
"pic_settle_us_before": "500",
"settled": {
"busy": {
"iqr": 2,
"max": 662,
"mean": 651.45,
"med": 651,
"min": 644,
"n": 200
},
"idle": {
"iqr": 1,
"max": 660,
"mean": 650.66,
"med": 650,
"min": 642,
"n": 200
}
},
"settled_idle_moved": 2,
"settled_split": 1
},
"fingerprint": "0293d36536bb65e2767d339c11aea4d8d0ccb224544ad986a088228172cb6b54",
"image": "20260928153805 (dev)",
"log": [
"16:25:37 start kernel.pic-soc-load (auto, api) in campaign c-20260928162331-3969",
"16:25:38 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:25:38 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"16:25:38 queued by the unattended queue opened 2026-09-28T16:23:31Z",
"16:25:38 baseline: pre: clean",
"16:25:41 control (settle off): after sleep median 648 (iqr 3, 640..669); after spin median 653 (iqr 1, 649..662)",
"16:25:41 settled (500 us): after sleep median 650 (iqr 1, 642..660); after spin median 651 (iqr 2, 644..662)",
"16:25:41 split busy minus idle: control +5, settled +1",
"16:25:41 PASS: settled, an idle reader and a busy reader read the same (split +1); control split +5",
"16:25:41 baseline: post: clean",
"16:25:41 result PASS"
],
"manifest_sha": "faf9563c750bb8bd4bfc8778b6af053cddb63fa335ab946caf2f71631ede740f",
"message": "",
"result": "PASS",
"test": "kernel.pic-soc-load",
"ts": "2026-09-28T16:25:41Z"
},
"requires": [],
"satisfied": true,
"source_sha": "a491099cc280ddaee55a303b0ee375cb72f207055b73dc89ebe5d39f9c50875c",
"subsystem": "kernel",
"title": "A PIC reading does not depend on what the reader was doing"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/auth.*"
],
[
"forgectrl",
"src/peer.*"
],
[
"forgectrl",
"src/main.c"
],
[
"forgectrl",
"src/session.*"
],
[
"forgectrl",
"src/users.*"
],
[
"forgectrl",
"src/ui/login.js"
],
[
"forgectrl",
"src/ui/wizard.js"
]
],
"fingerprint": "fd918606d7cf024046e79105d504c00e777b65e79dea6b93596ff399856e9984",
"hardware": "api",
"id": "forgectrl.auth",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928162331-3969",
"duration_s": 1,
"evidence": {
"alive_after_oversize": 200,
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T16:23:31Z"
},
"controller_has_a_secret": true,
"cool_state_from_lan": 403,
"cool_state_from_lan_http": {
"location": "https://<IP-1>/cool/state",
"status": 302
},
"cool_state_from_loopback": 200,
"cool_state_from_loopback_no_secret": 403,
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-2>",
"released": []
},
"fuse_noauth": 403,
"fuse_token_no_button": 403,
"host_name": 403,
"host_own_name": 200,
"host_own_name_domain": 403,
"lan_ip": "<IP-1>",
"noauth /boot": 403,
"noauth /controller/start": 403,
"noauth /controller/stop": 403,
"noauth /diag/abort": 403,
"noauth /diag/flow-verify": 403,
"noauth /mode": 403,
"noauth /restore/factory": 403,
"noauth /restore/factory-return": 403,
"noauth /settings": 403,
"noauth /system/reboot": 403,
"noauth /system/ssh": 403,
"noauth /update/apply": 403,
"noauth /update/check": 403,
"noauth /update/dismiss": 403,
"noauth /update/upload": 403,
"noauth /wiz/account": 403,
"noauth /wiz/advisories/accept": 403,
"noauth /wiz/complete": 403,
"origin_name": 403,
"oversize_body_status": 403,
"setup_from_lan": {
"location": "/login?next=/setup%3Fstep%3Dlaser.focus",
"status": 302
},
"sfs_cross": 403
},
"fingerprint": "fd918606d7cf024046e79105d504c00e777b65e79dea6b93596ff399856e9984",
"image": "20260928153805 (dev)",
"log": [
"16:25:41 start forgectrl.auth (auto, api) in campaign c-20260928162331-3969",
"16:25:41 fixture up: <REDACTED-1> at <IP-2>, v1.0.0, covers lid, interlock, button",
"16:25:41 fixture: <REDACTED-1> at <IP-2> covers lid, interlock, button",
"16:25:41 queued by the unattended queue opened 2026-09-28T16:23:31Z",
"16:25:41 baseline: pre: clean",
"16:25:41 GET /status -> 200",
"16:25:41 POST /controller/stop (no token) -> 403 {'error': 'authentication required'}",
"16:25:41 POST /controller/start (no token) -> 403 {'error': 'authentication required'}",
"16:25:41 POST /mode (no token) -> 403 {'error': 'authentication required'}",
"16:25:41 POST /settings (no token) -> 403 {'error': 'authentication required'}",
"16:25:41 POST /diag/flow-verify (no token) -> 403 {'error': 'authentication required'}",
"16:25:41 POST /diag/abort (no token) -> 403 {'error': 'authentication required'}",
"16:25:41 POST /update/apply (no token) -> 403 {'error': 'authentication required'}",
"16:25:41 POST /boot (no token) -> 403 {'error': 'authentication required'}",
"16:25:41 POST /update/check (no token) -> 403 {'error': 'authentication required'}",
"16:25:41 POST /update/dismiss (no token) -> 403 {'error': 'authentication required'}",
"16:25:41 POST /system/reboot (no token) -> 403 {'error': 'authentication required'}",
"16:25:41 POST /restore/factory (no token) -> 403 {'error': 'authentication required'}",
"16:25:41 POST /restore/factory-return (no token) -> 403 {'error': 'authentication required'}",
"16:25:41 POST /system/ssh (no token) -> 403 {'error': 'authentication required'}",
"16:25:41 POST /wiz/advisories/accept (no token) -> 403 {'error': 'authentication required'}",
"16:25:41 POST /wiz/account (no token) -> 403 {'error': 'authentication required'}",
"16:25:42 POST /wiz/complete (no token) -> 403 {'error': 'authentication required'}",
"16:25:42 POST /update/upload (no token) -> 403",
"16:25:42 POST /settings (no token, 4 MiB body) -> 403",
"16:25:42 GET /status after the oversized body -> 200",
"16:25:42 GET /status Host=evil.example.net -> 403",
"16:25:42 GET /status Host=forgefirm-b00a -> 200",
"16:25:42 GET /status Host=forgefirm-b00a.example.net -> 403",
"16:25:42 GET /status Origin=http://evil.example.net -> 403",
"16:25:42 GET /status Sec-Fetch-Site=cross-site -> 403",
"16:25:42 GET /fuse-identity (no token) -> 403 {'error': 'authentication required'}",
"16:25:42 GET /fuse-identity (token, button not held) -> 403 ",
"16:25:42 POST /cool/state from loopback, no secret -> 403 the report channel is the running controller's alone",
"16:25:42 POST /cool/state from loopback with the controller's secret -> 200",
"16:25:42 POST http://<IP-1>/cool/state -> 302 https://<IP-1>/cool/state",
"16:25:42 POST https://<IP-1>/cool/state -> 403 {'error': 'loopback only'}",
"16:25:42 GET https://<IP-1>/setup?step=laser.focus (no session) -> 302 /login?next=/setup%3Fstep%3Dlaser.focus",
"16:25:42 baseline: post: clean",
"16:25:42 result PASS"
],
"manifest_sha": "faf9563c750bb8bd4bfc8778b6af053cddb63fa335ab946caf2f71631ede740f",
"message": "",
"result": "PASS",
"test": "forgectrl.auth",
"ts": "2026-09-28T16:25:42Z"
},
"requires": [],
"satisfied": true,
"source_sha": "4227559429b30fc68f960e7dbde2bbe69cd19f2a00768e928ef0e6d88371aa8b",
"subsystem": "forgectrl",
"title": "API access control"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/settings.*"
],
[
"forgectrl",
"src/main.c"
],
[
"forgectrl",
"src/cam.c"
]
],
"fingerprint": "b392e547586b2c6d4d5ee2ff09b54f125e129577f67fe5c5c207323d10222567",
"hardware": "api",
"id": "forgectrl.settings-bounds",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928162331-3969",
"duration_s": 0,
"evidence": {
"accepted": {
"key": "<REDACTED-1>",
"status": 200,
"value": "imperial"
},
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T16:23:31Z"
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-2>",
"ip": "<IP-1>",
"released": []
},
"keys": 89,
"lid_lamp": {
"applied": "100",
"resting": "236",
"restored": "236",
"setting": ""
},
"out_of_range": 400,
"overlong": 400,
"pulse_bytes_out_of_range": 400,
"unknown_key": 400
},
"fingerprint": "b392e547586b2c6d4d5ee2ff09b54f125e129577f67fe5c5c207323d10222567",
"image": "20260928153805 (dev)",
"log": [
"16:25:42 start forgectrl.settings-bounds (auto, api) in campaign c-20260928162331-3969",
"16:25:43 fixture up: <REDACTED-2> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:25:43 fixture: <REDACTED-2> at <IP-1> covers lid, interlock, button",
"16:25:43 queued by the unattended queue opened 2026-09-28T16:23:31Z",
"16:25:43 baseline: pre: clean",
"16:25:43 POST /settings gf_serial=<300 chars> -> 400 ",
"16:25:43 POST /settings laser_disarm_s=99999 -> 400",
"16:25:43 POST /settings pulse_reject_threshold_bytes=2000000000 -> 400",
"16:25:43 POST /settings no_such_key_forgetest=1 -> 400",
"16:25:43 settings unchanged after the refused writes",
"16:25:43 POST /settings <REDACTED-1>=imperial -> 200",
"16:25:43 lid lamp: setting '', pic/lid_led=236 (expected 236)",
"16:25:43 lid_lamp_idle 256 / -1 / bright refused",
"16:25:43 lid_lamp_idle=100 -> pic/lid_led=100 after 0.0 s",
"16:25:43 lid lamp follows the setting live and returns to 236",
"16:25:43 baseline: post: clean",
"16:25:43 result PASS"
],
"manifest_sha": "faf9563c750bb8bd4bfc8778b6af053cddb63fa335ab946caf2f71631ede740f",
"message": "",
"result": "PASS",
"test": "forgectrl.settings-bounds",
"ts": "2026-09-28T16:25:43Z"
},
"requires": [],
"satisfied": true,
"source_sha": "6bcc38ba14a7a9f0d5a7b5ace2e086e5043b6e07c7fa1244c1fd5701df4251e5",
"subsystem": "forgectrl",
"title": "Settings validation and restore"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/ui.*"
],
[
"forgectrl",
"src/ui/**"
],
[
"forgectrl",
"src/status.*"
],
[
"forgectrl",
"src/cam.c"
],
[
"forgectrl",
"src/main.c"
],
[
"forgectrl",
"src/super.c"
],
[
"grblhal-glowforge",
"src/glowforge_status.c"
],
[
"grblhal-glowforge",
"src/serial.c"
],
[
"forgectrl",
"src/curverec.*"
]
],
"fingerprint": "bd43a892348fac8e5eba45adbcd26c82c5ff85e7d00fbaef583cb5ee8d808175",
"hardware": "api",
"id": "forgectrl.panel-serves",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928162331-3969",
"duration_s": 1,
"evidence": {
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T16:23:31Z"
},
"cam_status": 200,
"curve_status": {
"curve": "",
"elapsed_s": 0,
"points": [],
"reason": "",
"samples": 0,
"state": "idle"
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"grbl": {
"age_s": 1.9,
"report": {
"alarm": 0,
"driver": "b34636f",
"laser": {
"armed": false,
"arming": false,
"curve": "custom",
"floor_pct": 14,
"gamma": 1.5,
"model": "density"
},
"modals": "[GC:G0 G54 G17 G21 G90 G94 G40 G49 G98 G50 M5 M9 T0 F0 S0.]",
"overrides": {
"feed": 100,
"rapid": 100
},
"sender": {
"connected": false,
"for_s": 0,
"generation": 0,
"peer": ""
},
"state": "Idle",
"ts_mono": 720.95
}
},
"grbl_nvs": true,
"grbl_settings_status": 200,
"homed_axes": 4,
"page_policy": "frame-src 'none'",
"panel_status": 200,
"state": "idle",
"switches": {
"button": false,
"head": true,
"hv_enable": false,
"interlock_ok": true,
"lid": true
},
"sys": {
"cpu_pct": 5.9,
"mem_pct": 28.2
}
},
"fingerprint": "bd43a892348fac8e5eba45adbcd26c82c5ff85e7d00fbaef583cb5ee8d808175",
"image": "20260928153805 (dev)",
"log": [
"16:23:32 start forgectrl.panel-serves (auto, api) in campaign c-20260928162331-3969",
"16:23:32 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:23:32 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"16:23:32 queued by the unattended queue opened 2026-09-28T16:23:31Z",
"16:23:32 baseline: pre: clean",
"16:23:33 GET / -> 200 (562408 bytes)",
"16:23:33 GET / Content-Security-Policy: frame-src 'none'",
"16:23:33 /status state=idle switches={'lid': True, 'button': False, 'interlock_ok': True, 'head': True, 'hv_enable': False}",
"16:23:34 /status sys={'cpu_pct': 5.9, 'mem_pct': 28.2}",
"16:23:34 /status homed_axes=4 pos.z=4.45 reach=-0.28..11.35",
"16:23:34 GET /cam/status -> 200 {'running': False, 'cam': 'lid', 'clients': 0, 'frames': 0, 'fps': 0.0, 'fps_cap': 0.0, 'hw_fps_skip': False, 'encoder': 'software', 'convert': 'cpu', 'buffers': 'uncached', 'sensor': 'OV5648', 'stream': {'width': 1296, 'height': 972}, 'snapshot': {'width': 2592, 'height': 1944}, 'h264': {'active': False, 'clients': 0}, 'health': {'captured': 0, 'corrupt': 0, 'restarts': 0, 'withheld': 0}, 'timing': {'latency_ms': 0.0, 'convert_ms': 0.0, 'copy_ms': 0.0, 'encode_ms': 0.0, 'skipped': 0}, 'capture_allowed': True, 'stopped_by_lid': False}",
"16:23:34 /status grbl={'age_s': 1.9, 'report': {'ts_mono': 720.95, 'state': 'Idle', 'alarm': 0, 'sender': {'connected': False, 'generation': 0, 'for_s': 0, 'peer': ''}, 'laser': {'armed': False, 'arming': False, 'model': 'density', 'floor_pct': 14, 'curve': 'custom', 'gamma': 1.5}, 'modals': '[GC:G0 G54 G17 G21 G90 G94 G40 G49 G98 G50 M5 M9 T0 F0 S0.]', 'overrides': {'feed': 100, 'rapid': 100}, 'driver': 'b34636f'}}",
"16:23:34 baseline: post: clean",
"16:23:34 result PASS"
],
"manifest_sha": "faf9563c750bb8bd4bfc8778b6af053cddb63fa335ab946caf2f71631ede740f",
"message": "",
"result": "PASS",
"test": "forgectrl.panel-serves",
"ts": "2026-09-28T16:23:34Z"
},
"requires": [],
"satisfied": true,
"source_sha": "8924ab5c2b8a4f9cb03a5df435d5ac0daca84e5f6a81890646ea725b6382dc07",
"subsystem": "forgectrl",
"title": "Control panel and status endpoints"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/events.*"
],
[
"forgectrl",
"src/main.c"
],
[
"forgectrl",
"src/status.*"
],
[
"forgectrl",
"src/grblport.*"
]
],
"fingerprint": "b0848759ef08b534f56c09c653b239a38470c284fde77cb5a82dd484ef10c64e",
"hardware": "api",
"id": "events.stream",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928162331-3969",
"duration_s": 10,
"evidence": {
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T16:23:31Z"
},
"edges": [
"id: 1",
"event: alarm",
"id: 2",
"event: motors.released",
"id: 3",
"event: motors.energized"
],
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"fourth": [
503,
"every event stream is taken (3 in all): fan out from one client"
],
"mode": {
"detail": "already in grbl mode",
"found": "grbl",
"needs": "grbl",
"ok": true,
"switched": false
},
"place_back_s": 3.008021116256714,
"replaced": {
"bye": true,
"ended": true
}
},
"fingerprint": "b0848759ef08b534f56c09c653b239a38470c284fde77cb5a82dd484ef10c64e",
"image": "20260928153805 (dev)",
"log": [
"16:25:43 start events.stream (auto, api) in campaign c-20260928162331-3969",
"16:25:44 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:25:44 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"16:25:44 queued by the unattended queue opened 2026-09-28T16:23:31Z",
"16:25:44 baseline: pre: clean",
"16:25:44 mode: test needs grbl - already in grbl mode",
"16:25:47 the fourth stream -> 503 every event stream is taken (3 in all): fan out from one client",
"16:25:51 the stream carried: ['id: 1', 'event: alarm', 'id: 2', 'event: motors.released', 'id: 3', 'event: motors.energized']",
"16:25:54 PASS: three streams, the fourth refused in words with the settings route answering, a replacement told and ended, two edges in order, and a place back after 3 s",
"16:25:54 baseline: post: clean",
"16:25:54 result PASS"
],
"manifest_sha": "faf9563c750bb8bd4bfc8778b6af053cddb63fa335ab946caf2f71631ede740f",
"message": "",
"result": "PASS",
"test": "events.stream",
"ts": "2026-09-28T16:25:54Z"
},
"requires": [],
"satisfied": true,
"source_sha": "96b2a68b3125ebed5c5f3aa6cbe05a6bdf8669a142ac696413d73fc637cc4d77",
"subsystem": "forgectrl",
"title": "The event stream: edges arrive, and the cap holds"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/lease.*"
],
[
"forgectrl",
"src/main.c"
],
[
"forgectrl",
"src/status.*"
],
[
"forgectrl",
"src/wizdark.*"
],
[
"forgectrl",
"src/diag.*"
],
[
"forgectrl",
"src/curverec.*"
],
[
"forgectrl",
"src/jobrun.*"
],
[
"forgectrl",
"src/update.*"
],
[
"forgectrl",
"src/logs.*"
],
[
"forgectrl",
"src/super.*"
],
[
"forgectrl",
"src/events.*"
]
],
"fingerprint": "64cd5029872a1f5eb6155a23784ec90de5b1c2ab6549c862851f17815156eaa5",
"hardware": "api",
"id": "forgectrl.lease",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928162331-3969",
"duration_s": 3,
"evidence": {
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T16:23:31Z"
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"holder": {
"for_s": 0,
"kind": "hardware",
"owner": "wizard:switches",
"words": "a setup wizard (switches)"
},
"lease_changed": [
"data: {\"owner\":\"wizard:switches\"}",
"data: {\"owner\":null}"
],
"refused": {
"a diagnostic": [
409,
"a setup wizard (switches) holds the machine"
],
"a log export": [
409,
"a setup wizard (switches) holds the machine"
],
"a mode switch": [
409,
"a setup wizard (switches) holds the machine"
],
"a settings write": [
409,
"a setup wizard (switches) holds the machine - settings are locked"
],
"the controller's start": [
409,
"a setup wizard (switches) holds the machine"
],
"the recorder": [
409,
"a setup wizard (switches) holds the machine"
]
}
},
"fingerprint": "64cd5029872a1f5eb6155a23784ec90de5b1c2ab6549c862851f17815156eaa5",
"image": "20260928153805 (dev)",
"log": [
"16:25:54 start forgectrl.lease (auto, api) in campaign c-20260928162331-3969",
"16:25:55 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:25:55 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"16:25:55 queued by the unattended queue opened 2026-09-28T16:23:31Z",
"16:25:55 baseline: pre: clean",
"16:25:55 the lease while the check waits: {'owner': 'wizard:switches', 'kind': 'hardware', 'for_s': 0, 'words': 'a setup wizard (switches)'}",
"16:25:58 the event stream: ['data: {\"owner\":\"wizard:switches\"}', 'data: {\"owner\":null}']",
"16:25:58 PASS: wizard:switches held the machine, six requests were refused by name, the abort freed it, and the event stream said both",
"16:25:58 baseline: post: clean",
"16:25:58 result PASS"
],
"manifest_sha": "faf9563c750bb8bd4bfc8778b6af053cddb63fa335ab946caf2f71631ede740f",
"message": "",
"result": "PASS",
"test": "forgectrl.lease",
"ts": "2026-09-28T16:25:58Z"
},
"requires": [],
"satisfied": true,
"source_sha": "5f045b636393417fa202c2aa7668ae140a07f97db87dbf983fa92ceb2f96a885",
"subsystem": "forgectrl",
"title": "The machine lease: a holder refuses everything else, by name"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/auth.*"
],
[
"forgectrl",
"src/peer.*"
],
[
"forgectrl",
"src/main.c"
],
[
"forgectrl",
"src/session.*"
],
[
"forgectrl",
"src/users.*"
],
[
"forgectrl",
"src/ui/login.js"
],
[
"forgectrl",
"src/ui/wizard.js"
],
[
"forgectrl",
"src/tokens.*"
],
[
"forgectrl",
"src/grblport.*"
],
[
"forgectrl",
"src/settings.*"
]
],
"fingerprint": "875fecf31b510931da2c8c609646f7b09916c1735122fb5604fae03d98aea9f6",
"hardware": "api",
"id": "forgectrl.tokens",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928162331-3969",
"duration_s": 3,
"evidence": {
"after_revoke": [
403,
"authentication required"
],
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T16:23:31Z"
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"hub_passed": {
"bearer GET /cam/status": 200,
"bearer GET /status": 200,
"camera-only ?key= GET /cam/status": 200,
"header GET /mode": 200
},
"jog_mm": 1.0,
"listed": {
"forgetest hub": {
"caps": [
"machine.read",
"camera.lid"
],
"id": "13aa408a",
"last_used": 1790612761
},
"forgetest jogger": {
"caps": [
"motion.jog"
],
"id": "9b5ce2c7",
"last_used": 1790612759
},
"forgetest viewer": {
"caps": [
"camera.lid"
],
"id": "a50375fd",
"last_used": 1790612759
}
},
"mode": {
"detail": "already in grbl mode",
"found": "grbl",
"needs": "grbl",
"ok": true,
"switched": false
},
"outside_the_list": [
400,
"settings.write is not a capability a token can hold"
],
"plain_http": [
403,
"a scoped token is accepted over HTTPS only"
],
"reads_closed": {
"machine.read": 200,
"motion.jog": 403,
"nobody": 403
},
"refused": {
"a jog": [
403,
"this token does not hold motion.jog"
],
"a mode switch": [
403,
"no scoped token reaches this route"
],
"a settings write": [
403,
"no scoped token reaches this route"
],
"a stranger's token": [
403,
"authentication required"
],
"a token of its own": [
403,
"no scoped token reaches this route"
],
"a token with more than a camera, in a URL": [
403,
"a token in a URL may hold camera capabilities only"
],
"the head camera": [
403,
"this token does not hold camera.head"
],
"the jog token on /status": [
403,
"this token does not hold machine.read"
],
"the panel's ?token= form": [
403,
"authentication required"
],
"the token list": [
403,
"no scoped token reaches this route"
]
},
"store": {
"holds_a_token": false,
"mode": "0o600"
}
},
"fingerprint": "875fecf31b510931da2c8c609646f7b09916c1735122fb5604fae03d98aea9f6",
"image": "20260928153805 (dev)",
"log": [
"16:25:58 start forgectrl.tokens (auto, api) in campaign c-20260928162331-3969",
"16:25:58 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:25:58 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"16:25:58 queued by the unattended queue opened 2026-09-28T16:23:31Z",
"16:25:59 baseline: pre: clean",
"16:25:59 mode: test needs grbl - already in grbl mode",
"16:26:00 the jog token jogged the head 1.000 mm from the LAN with no session",
"16:26:02 PASS: each token reached what it was granted from the LAN with no session, was refused everything else in words, was refused over plain HTTP and once revoked, and the machine keeps no token",
"16:26:02 baseline: post: clean",
"16:26:02 result PASS"
],
"manifest_sha": "faf9563c750bb8bd4bfc8778b6af053cddb63fa335ab946caf2f71631ede740f",
"message": "",
"result": "PASS",
"test": "forgectrl.tokens",
"ts": "2026-09-28T16:26:02Z"
},
"requires": [],
"satisfied": true,
"source_sha": "8ee0bfdd776637ccd2f57be5835e43e9c1a7834c80ec2ded88a503465f8a47b8",
"subsystem": "forgectrl",
"title": "Scoped API tokens: a token reaches what it was granted, and nothing else"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/setup.*"
],
[
"forgectrl",
"src/super.c"
],
[
"forgectrl",
"src/main.c"
],
[
"forgectrl",
"src/paths.h"
]
],
"fingerprint": "a0a43b4912ddcbe62c27d4c620b9a8ae7611f92aa83d42aa1cd43ffe40323f6b",
"hardware": "takeover",
"id": "setup.gate-blocks-controllers",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928162331-3969",
"duration_s": 18,
"evidence": {
"after": {
"acceptance_done": true,
"account": true,
"advisories_complete": true,
"completed": true,
"first_run": false,
"gate": "open",
"override": true,
"required": [],
"versions": {
"account": 1,
"advisories": 1,
"airflow": 1,
"cameras": 1,
"cloud": 1,
"cloud.header": 1,
"cooling.aa-offset": 1,
"cooling.flow": 1,
"cooling.flow-load": 1,
"cooling.flow-verify": 1,
"laser.corner": 1,
"laser.dose-curve": 1,
"laser.floor": 1,
"laser.focus": 1,
"machine": 1,
"motion": 1,
"preferences": 1,
"sensors": 1,
"sheet.frame": 1,
"sheet.place": 1,
"switches": 1
},
"why": ""
},
"after_mode": {
"controller": "running",
"gated": false,
"local": false,
"mode": "grbl",
"motion": "verified",
"pid": 3871,
"why": ""
},
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T16:23:31Z"
},
"before": {
"acceptance_done": true,
"account": true,
"advisories_complete": true,
"completed": true,
"first_run": false,
"gate": "open",
"override": true,
"required": [],
"versions": {
"account": 1,
"advisories": 1,
"airflow": 1,
"cameras": 1,
"cloud": 1,
"cloud.header": 1,
"cooling.aa-offset": 1,
"cooling.flow": 1,
"cooling.flow-load": 1,
"cooling.flow-verify": 1,
"laser.corner": 1,
"laser.dose-curve": 1,
"laser.floor": 1,
"laser.focus": 1,
"machine": 1,
"motion": 1,
"preferences": 1,
"sensors": 1,
"sheet.frame": 1,
"sheet.place": 1,
"switches": 1
},
"why": ""
},
"controller_pids_gated": [],
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"gated_mode": {
"controller": "gated",
"gated": true,
"local": false,
"mode": "grbl",
"motion": "unverified",
"pid": 0,
"why": "setup required: advisories, account, preferences, machine, cloud, switches, sensors, airflow, cooling.aa-offset, cooling.flow, motion, cameras, cloud.header, sheet.place, shee"
},
"gated_wiz": {
"acceptance_done": true,
"account": true,
"advisories_complete": true,
"completed": true,
"first_run": false,
"gate": "closed",
"override": false,
"required": [
"advisories",
"account",
"preferences",
"machine",
"cloud",
"switches",
"sensors",
"airflow",
"cooling.aa-offset",
"cooling.flow",
"motion",
"cameras",
"cloud.header",
"sheet.place",
"sheet.frame",
"laser.focus",
"laser.floor",
"laser.dose-curve",
"laser.corner",
"cooling.flow-load"
],
"versions": {},
"why": "setup required: advisories, account, preferences, machine, cloud, switches, sensors, airflow, cooling.aa-offset, cooling.flow, motion, cameras, cloud.header, sheet.place, shee"
},
"mode": {
"detail": "already in grbl mode",
"found": "grbl",
"needs": "grbl",
"ok": true,
"switched": false
},
"override_before": true,
"override_mode": {
"controller": "running",
"gated": false,
"local": false,
"mode": "grbl",
"motion": "verified",
"pid": 3809,
"why": ""
},
"override_wiz": {
"acceptance_done": true,
"account": true,
"advisories_complete": true,
"completed": true,
"first_run": false,
"gate": "open",
"override": true,
"required": [
"advisories",
"account",
"preferences",
"machine",
"cloud",
"switches",
"sensors",
"airflow",
"cooling.aa-offset",
"cooling.flow",
"motion",
"cameras",
"cloud.header",
"sheet.place",
"sheet.frame",
"laser.focus",
"laser.floor",
"laser.dose-curve",
"laser.corner",
"cooling.flow-load"
],
"versions": {},
"why": "override active (required: advisories, account, preferences, machine, cloud, switches, sensors, airflow, cooling.aa-offset, cooling.flow, motion, cameras, cloud.header, sheet.place, shee)"
},
"port_open_after_s": 0.0016913414001464844
},
"fingerprint": "a0a43b4912ddcbe62c27d4c620b9a8ae7611f92aa83d42aa1cd43ffe40323f6b",
"image": "20260928153805 (dev)",
"log": [
"16:26:02 start setup.gate-blocks-controllers (auto, takeover) in campaign c-20260928162331-3969",
"16:26:02 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:26:02 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"16:26:02 queued by the unattended queue opened 2026-09-28T16:23:31Z",
"16:26:02 baseline: pre: clean",
"16:26:02 mode: test needs grbl - already in grbl mode",
"16:26:02 before: gate open, override True, required []",
"16:26:02 takeover: waiting for forgectrl to be settled",
"16:26:02 baseline: /mode controller=running motion=verified",
"16:26:02 takeover: preserving cnc/motor_lock=0, cnc/step_freq=112640, cnc/ramp_rate=500000, cnc/streaming=0, cnc/x_mode=32, cnc/y_mode=32, cnc/x_decay=1, cnc/y_decay=1, pic/x_step_current=33, pic/y_step_current=5",
"16:26:02 takeover: stopping the controller through forgectrl",
"16:26:03 takeover: POST /controller/stop -> 200",
"16:26:03 takeover: forgectrl stop -> rc 0",
"16:26:03 takeover: pulse device free",
"16:26:03 takeover: forgectrl start -> rc 0",
"16:26:05 baseline: /mode controller=gated motion=unverified",
"16:26:05 installed under a restart: setup.json=1386 B, setup-override=removed",
"16:26:05 /mode after the restart: {'mode': 'grbl', 'controller': 'gated', 'pid': 0, 'motion': 'unverified', 'gated': True, 'local': False, 'why': 'setup required: advisories, account, preferences, machine, cloud, switches, sensors, airflow, cooling.aa-offset, cooling.flow, motion, cameras, cloud.header, sheet.place, shee'} (after 0.004609346389770508 s)",
"16:26:06 gated: no controller process, the Grbl port is closed",
"16:26:12 the controller spawned under the override (6.372143983840942 s)",
"16:26:12 baseline: /mode controller=running motion=verified",
"16:26:12 override: the controller is back ({'mode': 'grbl', 'controller': 'running', 'pid': 3809, 'motion': 'verified', 'gated': False, 'local': False, 'why': ''}), the Grbl port accepts after 0.002 s",
"16:26:12 takeover: waiting for forgectrl to be settled",
"16:26:12 baseline: /mode controller=running motion=verified",
"16:26:12 takeover: preserving cnc/motor_lock=0, cnc/step_freq=112640, cnc/ramp_rate=500000, cnc/streaming=0, cnc/x_mode=32, cnc/y_mode=32, cnc/x_decay=1, cnc/y_decay=1, pic/x_step_current=33, pic/y_step_current=5",
"16:26:12 takeover: stopping the controller through forgectrl",
"16:26:12 takeover: POST /controller/stop -> 200",
"16:26:12 takeover: forgectrl stop -> rc 0",
"16:26:13 takeover: pulse device free",
"16:26:13 takeover: the counters are not in the frame the run began in (a controller start or a home the test did not declare), so the head is not judged here",
"16:26:13 takeover: forgectrl start -> rc 0",
"16:26:15 baseline: /mode controller=stopped motion=unverified",
"16:26:20 baseline: /mode controller=running motion=verified",
"16:26:20 restored under a restart: setup.json, setup-override",
"16:26:20 restored: gate open, controller running",
"16:26:20 baseline: post: clean",
"16:26:20 result PASS"
],
"manifest_sha": "faf9563c750bb8bd4bfc8778b6af053cddb63fa335ab946caf2f71631ede740f",
"message": "",
"result": "PASS",
"test": "setup.gate-blocks-controllers",
"ts": "2026-09-28T16:26:20Z"
},
"requires": [
"forgectrl.auth"
],
"satisfied": true,
"source_sha": "1fa47e39dcf7d4a8f8499414d854d37cf3867a67eed6970808577cfe30b6afb6",
"subsystem": "setup",
"title": "The setup gate spawns no controller"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/setup.*"
],
[
"forgectrl",
"src/super.c"
],
[
"forgectrl",
"src/main.c"
],
[
"forgectrl",
"src/paths.h"
]
],
"fingerprint": "5143a8bf694ff53f16714f61f610b8a7740ff21805c3034dd622fb6bc7812f04",
"hardware": "api",
"id": "setup.override-until-reboot",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928162331-3969",
"duration_s": 0,
"evidence": {
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T16:23:31Z"
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"mode": {
"controller": "running",
"gated": false,
"local": false,
"mode": "grbl",
"motion": "verified",
"pid": 3871,
"why": ""
},
"mount": {
"fstype": "tmpfs",
"point": "/run"
},
"wiz": {
"acceptance_done": true,
"account": true,
"advisories_complete": true,
"completed": true,
"first_run": false,
"gate": "open",
"override": true,
"required": [],
"versions": {
"account": 1,
"advisories": 1,
"airflow": 1,
"cameras": 1,
"cloud": 1,
"cloud.header": 1,
"cooling.aa-offset": 1,
"cooling.flow": 1,
"cooling.flow-load": 1,
"cooling.flow-verify": 1,
"laser.corner": 1,
"laser.dose-curve": 1,
"laser.floor": 1,
"laser.focus": 1,
"machine": 1,
"motion": 1,
"preferences": 1,
"sensors": 1,
"sheet.frame": 1,
"sheet.place": 1,
"switches": 1
},
"why": ""
}
},
"fingerprint": "5143a8bf694ff53f16714f61f610b8a7740ff21805c3034dd622fb6bc7812f04",
"image": "20260928153805 (dev)",
"log": [
"16:26:21 start setup.override-until-reboot (auto, api) in campaign c-20260928162331-3969",
"16:26:21 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:26:21 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"16:26:21 queued by the unattended queue opened 2026-09-28T16:23:31Z",
"16:26:21 baseline: pre: clean",
"16:26:21 /run/forgefirm/setup-override is on /run (tmpfs)",
"16:26:21 GET /wiz: {'first_run': False, 'gate': 'open', 'override': True, 'why': '', 'required': [], 'advisories_complete': True, 'acceptance_done': True, 'account': True, 'completed': True, 'versions': {'account': 1, 'advisories': 1, 'airflow': 1, 'cameras': 1, 'cloud': 1, 'cloud.header': 1, 'cooling.aa-offset': 1, 'cooling.flow': 1, 'cooling.flow-load': 1, 'cooling.flow-verify': 1, 'laser.corner': 1, 'laser.dose-curve': 1, 'laser.floor': 1, 'laser.focus': 1, 'machine': 1, 'motion': 1, 'preferences': 1, 'sensors': 1, 'sheet.frame': 1, 'sheet.place': 1, 'switches': 1}}",
"16:26:21 every required wizard is complete; the override lifts nothing today",
"16:26:21 baseline: post: clean",
"16:26:21 result PASS"
],
"manifest_sha": "faf9563c750bb8bd4bfc8778b6af053cddb63fa335ab946caf2f71631ede740f",
"message": "",
"result": "PASS",
"test": "setup.override-until-reboot",
"ts": "2026-09-28T16:26:21Z"
},
"requires": [
"forgectrl.auth"
],
"satisfied": true,
"source_sha": "1eb86a4aa0929f79734ba37f98ea7481505d4ab7fb7cd3201daf440e33cc3b8b",
"subsystem": "setup",
"title": "The override stands until the next reboot"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/advisories.*"
],
[
"forgectrl",
"src/setup.*"
],
[
"forgectrl",
"src/wiz.*"
],
[
"forgectrl",
"src/sha256.*"
],
[
"forgectrl",
"src/main.c"
],
[
"forgectrl",
"src/ui/md.js"
],
[
"forgectrl",
"src/ui/embed_docs.cmake"
],
[
"forgectrl",
"docs/advisories/safety-and-risk.md"
],
[
"forgectrl",
"docs/advisories/licenses.md"
],
[
"forgectrl",
"docs/advisories/privacy.md"
],
[
"forgectrl",
"docs/advisories/cloud-service.md"
]
],
"fingerprint": "c3d0033406806a644318ec2911a41d8c5917658ca976da4fd517b7049ca73eca",
"hardware": "takeover",
"id": "setup.advisories-rehash",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928162331-3969",
"duration_s": 8,
"evidence": {
"accept": 200,
"after_accept": {
"acceptance_done": false,
"account": true,
"advisories_complete": true,
"completed": true,
"first_run": false,
"gate": "closed",
"override": true,
"required": [],
"versions": {
"account": 1,
"advisories": 1,
"airflow": 1,
"cameras": 1,
"cloud": 1,
"cloud.header": 1,
"cooling.aa-offset": 1,
"cooling.flow": 1,
"cooling.flow-load": 1,
"cooling.flow-verify": 1,
"laser.corner": 1,
"laser.dose-curve": 1,
"laser.floor": 1,
"laser.focus": 1,
"machine": 1,
"motion": 1,
"preferences": 1,
"sensors": 1,
"sheet.frame": 1,
"sheet.place": 1,
"switches": 1
},
"why": "the advisories are not accepted"
},
"after_restore": {
"acceptance_done": true,
"account": true,
"advisories_complete": true,
"completed": true,
"first_run": false,
"gate": "open",
"override": true,
"required": [],
"versions": {
"account": 1,
"advisories": 1,
"airflow": 1,
"cameras": 1,
"cloud": 1,
"cloud.header": 1,
"cooling.aa-offset": 1,
"cooling.flow": 1,
"cooling.flow-load": 1,
"cooling.flow-verify": 1,
"laser.corner": 1,
"laser.dose-curve": 1,
"laser.floor": 1,
"laser.focus": 1,
"machine": 1,
"motion": 1,
"preferences": 1,
"sensors": 1,
"sheet.frame": 1,
"sheet.place": 1,
"switches": 1
},
"why": ""
},
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T16:23:31Z"
},
"before": {
"acceptance_done": true,
"account": true,
"advisories_complete": true,
"completed": true,
"first_run": false,
"gate": "open",
"override": true,
"required": [],
"versions": {
"account": 1,
"advisories": 1,
"airflow": 1,
"cameras": 1,
"cloud": 1,
"cloud.header": 1,
"cooling.aa-offset": 1,
"cooling.flow": 1,
"cooling.flow-load": 1,
"cooling.flow-verify": 1,
"laser.corner": 1,
"laser.dose-curve": 1,
"laser.floor": 1,
"laser.focus": 1,
"machine": 1,
"motion": 1,
"preferences": 1,
"sensors": 1,
"sheet.frame": 1,
"sheet.place": 1,
"switches": 1
},
"why": ""
},
"content_type": "text/markdown; charset=utf-8",
"etag": "<HEX-1>",
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"no_phrase": 400,
"stale_hash": 409,
"unknown_doc": 400
},
"fingerprint": "c3d0033406806a644318ec2911a41d8c5917658ca976da4fd517b7049ca73eca",
"image": "20260928153805 (dev)",
"log": [
"16:26:21 start setup.advisories-rehash (auto, takeover) in campaign c-20260928162331-3969",
"16:26:22 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:26:22 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"16:26:22 queued by the unattended queue opened 2026-09-28T16:23:31Z",
"16:26:22 baseline: pre: clean",
"16:26:22 GET /advisories/safety-and-risk -> 200, 6868 bytes, ETag <HEX-1>",
"16:26:22 accept with a stale hash -> 409 {'error': 'the document changed; read it again'}",
"16:26:22 accept at the current hash with the phrase -> 200",
"16:26:22 acceptance_done cleared, gate closed: the advisories are not accepted",
"16:26:22 takeover: waiting for forgectrl to be settled",
"16:26:22 baseline: /mode controller=running motion=verified",
"16:26:22 takeover: preserving cnc/motor_lock=0, cnc/step_freq=112640, cnc/ramp_rate=500000, cnc/streaming=0, cnc/x_mode=32, cnc/y_mode=32, cnc/x_decay=1, cnc/y_decay=1, pic/x_step_current=33, pic/y_step_current=5",
"16:26:22 takeover: stopping the controller through forgectrl",
"16:26:22 takeover: POST /controller/stop -> 200",
"16:26:22 takeover: forgectrl stop -> rc 0",
"16:26:23 takeover: pulse device free",
"16:26:23 takeover: the counters are not in the frame the run began in (a controller start or a home the test did not declare), so the head is not judged here",
"16:26:23 takeover: forgectrl start -> rc 0",
"16:26:24 baseline: /mode controller=stopped motion=unverified",
"16:26:30 baseline: /mode controller=running motion=verified",
"16:26:30 the previous record is back under a restart",
"16:26:30 baseline: post: clean",
"16:26:30 result PASS"
],
"manifest_sha": "faf9563c750bb8bd4bfc8778b6af053cddb63fa335ab946caf2f71631ede740f",
"message": "",
"result": "PASS",
"test": "setup.advisories-rehash",
"ts": "2026-09-28T16:26:30Z"
},
"requires": [
"forgectrl.auth"
],
"satisfied": true,
"source_sha": "a0f5041ab60f1bf06925a627faebb7418e8cefa988e1f8b34cd5c17acb9742cb",
"subsystem": "setup",
"title": "An advisory is accepted at its current hash only"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/auth.*"
],
[
"forgectrl",
"src/session.*"
],
[
"forgectrl",
"src/users.*"
],
[
"forgectrl",
"src/tls.*"
],
[
"forgectrl",
"src/peer.*"
],
[
"forgectrl",
"src/main.c"
],
[
"forgectrl",
"src/ui/login.*"
]
],
"fingerprint": "94163458450dc0e747d4145f1a2bb318b83c233112e26cb24c080c898fd435ab",
"hardware": "takeover",
"id": "setup.account-login",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928162331-3969",
"duration_s": 49,
"evidence": {
"account_before": "scott",
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T16:23:31Z"
},
"cookie_flags": [
"httponly",
"max-age",
"path",
"samesite",
"secure"
],
"data_dir_mode_after_render": "0711",
"data_dir_mode_found": "0711",
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"home_reach": {
"cd": "ok",
"home": "/data/forgefirm/home/forgetest",
"list_data_dir": "EACCES",
"read_record": "EACCES",
"uid": 1000,
"write": "ok"
},
"login": 200,
"logout": 200,
"right_inside_lock": 429,
"tls_fingerprint": "<MAC-1>:<MAC-2>:<MAC-3>:<MAC-4>:<MAC-5>:1C:2D",
"users_reload_rc": 0,
"wait": 30,
"wrong_codes": [
401,
401,
401,
401,
401,
429
],
"wrong_name": 401
},
"fingerprint": "94163458450dc0e747d4145f1a2bb318b83c233112e26cb24c080c898fd435ab",
"image": "20260928153805 (dev)",
"log": [
"16:26:30 start setup.account-login (auto, takeover) in campaign c-20260928162331-3969",
"16:26:30 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:26:30 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"16:26:30 queued by the unattended queue opened 2026-09-28T16:23:31Z",
"16:26:30 baseline: pre: clean",
"16:26:30 takeover: waiting for forgectrl to be settled",
"16:26:31 baseline: /mode controller=running motion=verified",
"16:26:31 takeover: preserving cnc/motor_lock=0, cnc/step_freq=112640, cnc/ramp_rate=500000, cnc/streaming=0, cnc/x_mode=32, cnc/y_mode=32, cnc/x_decay=1, cnc/y_decay=1, pic/x_step_current=33, pic/y_step_current=5",
"16:26:31 takeover: stopping the controller through forgectrl",
"16:26:31 takeover: POST /controller/stop -> 200",
"16:26:31 takeover: forgectrl stop -> rc 0",
"16:26:31 takeover: pulse device free",
"16:26:31 takeover: forgectrl start -> rc 0",
"16:26:33 baseline: /mode controller=stopped motion=unverified",
"16:26:38 baseline: /mode controller=running motion=verified",
"16:26:38 installed under a restart: users=removed",
"16:26:39 POST /wiz/account (temporary 'forgetest') -> 200 {'ok': True, 'name': 'forgetest'}",
"16:26:39 as forgetest, from a data directory found 0700 (now 0711): {'uid': 1000, 'home': '/data/forgefirm/home/forgetest', 'cd': 'ok', 'write': 'ok', 'list_data_dir': 'EACCES', 'read_record': 'EACCES'}",
"16:26:39 GET https://127.0.0.1/wiz -> 200",
"16:26:40 wrong password attempts -> [401, 401, 401, 401, 401, 429]",
"16:26:40 locked for 30 s; the right password is refused inside the lock",
"16:27:04 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:27:11 POST /login (right) -> 200, cookie flags ['httponly', 'max-age', 'path', 'samesite', 'secure']",
"16:27:11 session set by the login, seen by GET /wiz, ended by the logout",
"16:27:11 takeover: waiting for forgectrl to be settled",
"16:27:11 baseline: /mode controller=running motion=verified",
"16:27:11 takeover: preserving cnc/motor_lock=0, cnc/step_freq=112640, cnc/ramp_rate=500000, cnc/streaming=0, cnc/x_mode=32, cnc/y_mode=32, cnc/x_decay=1, cnc/y_decay=1, pic/x_step_current=33, pic/y_step_current=5",
"16:27:11 takeover: stopping the controller through forgectrl",
"16:27:11 takeover: POST /controller/stop -> 200",
"16:27:11 takeover: forgectrl stop -> rc 0",
"16:27:12 takeover: pulse device free",
"16:27:12 takeover: the counters are not in the frame the run began in (a controller start or a home the test did not declare), so the head is not judged here",
"16:27:12 takeover: forgectrl start -> rc 0",
"16:27:14 baseline: /mode controller=stopped motion=unverified",
"16:27:19 baseline: /mode controller=running motion=verified",
"16:27:19 restored under a restart: users",
"16:27:19 forgefirm-users reload -> rc 0 forgefirm-users: account scott created\nforgefirm-users: removing account forgetest (not in the record)",
"16:27:19 baseline: post: clean",
"16:27:19 result PASS"
],
"manifest_sha": "faf9563c750bb8bd4bfc8778b6af053cddb63fa335ab946caf2f71631ede740f",
"message": "",
"result": "PASS",
"test": "setup.account-login",
"ts": "2026-09-28T16:27:19Z"
},
"requires": [
"forgectrl.auth"
],
"satisfied": true,
"source_sha": "68b3fe01a57e601007ed623a0688ea6b3c914e10b7a6e8e059aae1b0801d64a7",
"subsystem": "setup",
"title": "The panel login over HTTPS"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/auth.*"
],
[
"forgectrl",
"src/tls.*"
],
[
"forgectrl",
"src/peer.*"
],
[
"forgectrl",
"src/main.c"
]
],
"fingerprint": "4d737bbdc2ffbafc72be6446605365c1afc0fe7abbcf6cf437ab3a794f9ba046",
"hardware": "api",
"id": "setup.https-only-writes",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928162331-3969",
"duration_s": 0,
"evidence": {
"account": true,
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T16:23:31Z"
},
"dev_image": true,
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"lan_http GET /logs": {
"location": "https://<IP-2>/logs",
"status": 302
},
"lan_http GET /system/ssh": {
"location": "https://<IP-2>/system/ssh",
"status": 302
},
"lan_http POST /settings": {
"location": "https://<IP-2>/settings",
"status": 302
},
"lan_http_read": 200,
"lan_https_read": 200,
"lan_https_write": 200,
"lan_ip": "<IP-2>",
"loopback_http_write": 200
},
"fingerprint": "4d737bbdc2ffbafc72be6446605365c1afc0fe7abbcf6cf437ab3a794f9ba046",
"image": "20260928153805 (dev)",
"log": [
"16:27:20 start setup.https-only-writes (auto, api) in campaign c-20260928162331-3969",
"16:27:20 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:27:20 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"16:27:20 queued by the unattended queue opened 2026-09-28T16:23:31Z",
"16:27:20 baseline: pre: clean",
"16:27:20 GET https://<IP-2>/status -> 200",
"16:27:20 GET http://<IP-2>/status -> 200",
"16:27:20 POST http://<IP-2>/settings (token) -> 302 Location https://<IP-2>/settings",
"16:27:20 GET http://<IP-2>/system/ssh (token) -> 302 Location https://<IP-2>/system/ssh",
"16:27:20 GET http://<IP-2>/logs (token) -> 302 Location https://<IP-2>/logs",
"16:27:20 POST https://<IP-2>/settings (token, no session) -> 200 (dev image True, account True)",
"16:27:21 baseline: post: clean",
"16:27:21 result PASS"
],
"manifest_sha": "faf9563c750bb8bd4bfc8778b6af053cddb63fa335ab946caf2f71631ede740f",
"message": "",
"result": "PASS",
"test": "setup.https-only-writes",
"ts": "2026-09-28T16:27:21Z"
},
"requires": [
"forgectrl.auth"
],
"satisfied": true,
"source_sha": "18c51d1eed2276ec35f4461f099253f62dba4c0aa1c8be81f032ab2b91b812ff",
"subsystem": "setup",
"title": "Writes from the LAN go to HTTPS"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/main.c"
],
[
"forgectrl",
"src/paths.h"
]
],
"fingerprint": "4c3e5b2f90ddc1ff5ed7135e9f0a31354dec46dd6e9c1d798decaf420024babe",
"hardware": "api",
"id": "setup.ssh-until-reboot",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928162331-3969",
"duration_s": 1,
"evidence": {
"after": {
"dev_image": true,
"enabled": false,
"running": true
},
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T16:23:31Z"
},
"before": {
"dev_image": true,
"enabled": false,
"running": true
},
"enable": {
"dev_image": true,
"enabled": true,
"running": true
},
"final": {
"dev_image": true,
"enabled": false,
"running": true
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"sshd_policy": {
"banner": "none",
"passwordauthentication": "yes",
"permitemptypasswords": "yes",
"permitrootlogin": "yes"
}
},
"fingerprint": "4c3e5b2f90ddc1ff5ed7135e9f0a31354dec46dd6e9c1d798decaf420024babe",
"image": "20260928153805 (dev)",
"log": [
"16:27:21 start setup.ssh-until-reboot (auto, api) in campaign c-20260928162331-3969",
"16:27:21 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:27:21 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"16:27:21 queued by the unattended queue opened 2026-09-28T16:23:31Z",
"16:27:21 baseline: pre: clean",
"16:27:21 GET /system/ssh -> 200 {'enabled': False, 'running': True, 'dev_image': True}",
"16:27:22 POST /system/ssh enable=1 -> 200 {'enabled': True, 'running': True, 'dev_image': True}",
"16:27:22 sshd listens on 22 (0.0 s)",
"16:27:22 sshd -T: {'permitrootlogin': 'yes', 'passwordauthentication': 'yes', 'permitemptypasswords': 'yes', 'banner': 'none'}",
"16:27:22 dev image: flag removed by hand; GET /system/ssh -> 200 {'enabled': False, 'running': True, 'dev_image': True}",
"16:27:22 baseline: post: clean",
"16:27:22 result PASS"
],
"manifest_sha": "faf9563c750bb8bd4bfc8778b6af053cddb63fa335ab946caf2f71631ede740f",
"message": "",
"result": "PASS",
"test": "setup.ssh-until-reboot",
"ts": "2026-09-28T16:27:22Z"
},
"requires": [
"forgectrl.auth"
],
"satisfied": true,
"source_sha": "efc5ba6e486fa77abd7141af24776d9de0a236541a3ec77969701e69756a86b2",
"subsystem": "setup",
"title": "SSH is switched from the panel until the next reboot"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/main.c"
],
[
"forgectrl",
"src/super.c"
],
[
"forgectrl",
"src/settings.*"
],
[
"forgectrl",
"src/wiz.c"
],
[
"forgectrl",
"src/hooks.h"
],
[
"forgectrl",
"src/builtin.*"
]
],
"fingerprint": "114ded08fd87ba10019803cf1a5fb6cd818adc04cbfa29854b2ef92cb05e6a16",
"hardware": "api",
"id": "setup.cloud-disabled-surface",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928162331-3969",
"duration_s": 0,
"evidence": {
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T16:23:31Z"
},
"extension_found": {
"enabled": true,
"roles": [
{
"active": false,
"fallback": "none",
"kind": "runner-fd",
"provider": "gfcloud",
"role": "homing",
"select_key": "homing_mode"
},
{
"active": false,
"fallback": "grbl",
"kind": "supervised",
"provider": "cloud",
"role": "controller",
"select_key": "controller_mode"
}
]
},
"extension_off": {
"active": [
false,
false
],
"enabled": false
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"found": {
"cloud_enabled": "1",
"controller_mode": "grbl",
"homing_mode": "manual"
},
"mode": {
"detail": "already in grbl mode",
"found": "grbl",
"needs": "grbl",
"ok": true,
"switched": false
},
"mode_cloud": {
"body": "cloud mode is not enabled on this machine",
"status": 409
},
"settings cloud_enabled=1 no phrase": 400,
"settings controller_mode=cloud": 409,
"settings homing_mode=gfcloud": 409
},
"fingerprint": "114ded08fd87ba10019803cf1a5fb6cd818adc04cbfa29854b2ef92cb05e6a16",
"image": "20260928153805 (dev)",
"log": [
"16:27:22 start setup.cloud-disabled-surface (auto, api) in campaign c-20260928162331-3969",
"16:27:22 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:27:22 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"16:27:22 queued by the unattended queue opened 2026-09-28T16:23:31Z",
"16:27:22 baseline: pre: clean",
"16:27:22 mode: test needs grbl - already in grbl mode",
"16:27:23 cloud mode turned off for the test (found {'cloud_enabled': '1', 'homing_mode': 'manual', 'controller_mode': 'grbl'})",
"16:27:23 POST /settings controller_mode=cloud -> 409 cloud mode is not enabled on this machine",
"16:27:23 POST /settings homing_mode=gfcloud -> 409 cloud homing needs cloud mode enabled",
"16:27:23 POST /settings cloud_enabled=1 (no phrase) -> 400 type I UNDERSTAND to turn cloud mode on",
"16:27:23 POST /mode controller=cloud -> 409 cloud mode is not enabled on this machine",
"16:27:23 restore cloud_enabled='1' -> 200",
"16:27:23 baseline: post: clean",
"16:27:23 result PASS"
],
"manifest_sha": "faf9563c750bb8bd4bfc8778b6af053cddb63fa335ab946caf2f71631ede740f",
"message": "",
"result": "PASS",
"test": "setup.cloud-disabled-surface",
"ts": "2026-09-28T16:27:23Z"
},
"requires": [
"forgectrl.settings-bounds"
],
"satisfied": true,
"source_sha": "1e75597992fa9a35f11993df55e27df541189669c0ba3bb68e5f70f2e5353977",
"subsystem": "setup",
"title": "Nothing points at the cloud while it is off"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/main.c"
],
[
"forgectrl",
"src/advisories.*"
],
[
"forgectrl",
"src/setup.*"
],
[
"forgectrl",
"src/wiz.c"
],
[
"forgectrl",
"src/settings.*"
],
[
"forgectrl",
"docs/advisories/extensions.md"
],
[
"forgectrl",
"src/ui/embed_docs.cmake"
]
],
"fingerprint": "e4923067ef76b583dc309a62e9bc98983a021b4efdda14e21a1edc4a5aadd60b",
"hardware": "takeover",
"id": "setup.extensions-consent",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928162331-3969",
"duration_s": 9,
"evidence": {
"accept": 200,
"after_restore": {
"acceptance_done": true,
"account": true,
"advisories_complete": true,
"completed": true,
"first_run": false,
"gate": "open",
"override": true,
"required": [],
"versions": {
"account": 1,
"advisories": 1,
"airflow": 1,
"cameras": 1,
"cloud": 1,
"cloud.header": 1,
"cooling.aa-offset": 1,
"cooling.flow": 1,
"cooling.flow-load": 1,
"cooling.flow-verify": 1,
"laser.corner": 1,
"laser.dose-curve": 1,
"laser.floor": 1,
"laser.focus": 1,
"machine": 1,
"motion": 1,
"preferences": 1,
"sensors": 1,
"sheet.frame": 1,
"sheet.place": 1,
"switches": 1
},
"why": ""
},
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T16:23:31Z"
},
"before": {
"acceptance_done": true,
"account": true,
"advisories_complete": true,
"completed": true,
"first_run": false,
"gate": "open",
"override": true,
"required": [],
"versions": {
"account": 1,
"advisories": 1,
"airflow": 1,
"cameras": 1,
"cloud": 1,
"cloud.header": 1,
"cooling.aa-offset": 1,
"cooling.flow": 1,
"cooling.flow-load": 1,
"cooling.flow-verify": 1,
"laser.corner": 1,
"laser.dose-curve": 1,
"laser.floor": 1,
"laser.focus": 1,
"machine": 1,
"motion": 1,
"preferences": 1,
"sensors": 1,
"sheet.frame": 1,
"sheet.place": 1,
"switches": 1
},
"why": ""
},
"data_dir_mode_after": "0711",
"etag": "<HEX-1>",
"first_run_accept": 400,
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"found": {
"data_dir_mode": "0711",
"ext_enabled": "1"
},
"good consent beside a refused write": 409,
"no hash": 409,
"no phrase": 400,
"phrase in another case": 400,
"recorded": {
"accepted": "2026-09-28T16:27:24Z",
"hash": "<HEX-1>",
"method": "typed"
},
"stale hash": 409
},
"fingerprint": "e4923067ef76b583dc309a62e9bc98983a021b4efdda14e21a1edc4a5aadd60b",
"image": "20260928153805 (dev)",
"log": [
"16:27:23 start setup.extensions-consent (auto, takeover) in campaign c-20260928162331-3969",
"16:27:23 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:27:23 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"16:27:23 queued by the unattended queue opened 2026-09-28T16:23:31Z",
"16:27:23 baseline: pre: clean",
"16:27:23 GET /advisories/extensions -> 200, 6059 bytes, ETag <HEX-1>",
"16:27:23 the first-run accept of the on-demand document -> 400 {'error': 'this document is accepted where its feature is turned on'}",
"16:27:23 extensions turned off for the test (found '1')",
"16:27:23 POST /settings ext_enabled=1, no hash -> 409 read the Extensions advisory first: turning extensions on agrees to it",
"16:27:23 POST /settings ext_enabled=1, stale hash -> 409 read the Extensions advisory first: turning extensions on agrees to it",
"16:27:23 POST /settings ext_enabled=1, no phrase -> 400 type I UNDERSTAND to turn extensions on",
"16:27:23 POST /settings ext_enabled=1, phrase in another case -> 400 type I UNDERSTAND to turn extensions on",
"16:27:24 POST /settings ext_enabled=1, good consent beside a refused write -> 409 cloud mode is not enabled on this machine",
"16:27:24 POST /settings ext_enabled=1 with the hash and the phrase -> 200",
"16:27:24 restore ext_enabled='1' -> 200",
"16:27:24 takeover: waiting for forgectrl to be settled",
"16:27:24 baseline: /mode controller=running motion=verified",
"16:27:24 takeover: preserving cnc/motor_lock=0, cnc/step_freq=112640, cnc/ramp_rate=500000, cnc/streaming=0, cnc/x_mode=32, cnc/y_mode=32, cnc/x_decay=1, cnc/y_decay=1, pic/x_step_current=33, pic/y_step_current=5",
"16:27:24 takeover: stopping the controller through forgectrl",
"16:27:24 takeover: POST /controller/stop -> 200",
"16:27:24 takeover: forgectrl stop -> rc 0",
"16:27:25 takeover: pulse device free",
"16:27:25 takeover: forgectrl start -> rc 0",
"16:27:26 baseline: /mode controller=stopped motion=unverified",
"16:27:32 baseline: /mode controller=running motion=verified",
"16:27:32 the previous record is back under a restart",
"16:27:32 baseline: post: clean",
"16:27:32 result PASS"
],
"manifest_sha": "faf9563c750bb8bd4bfc8778b6af053cddb63fa335ab946caf2f71631ede740f",
"message": "",
"result": "PASS",
"test": "setup.extensions-consent",
"ts": "2026-09-28T16:27:32Z"
},
"requires": [
"forgectrl.settings-bounds",
"setup.advisories-rehash"
],
"satisfied": true,
"source_sha": "67c90add93df8aa12ae4e09472bc61505a3f543fd48686045105338a008ac6a8",
"subsystem": "setup",
"title": "Extensions are turned on over their own advisory"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/update.*"
],
[
"forgectrl",
"src/main.c"
],
[
"forgectrl",
"src/ui/wizard.js"
]
],
"fingerprint": "b141b9f0b5724333cc96dafeef4e97cd6b91b5ff333c597e2d8f0e23dc1b92d1",
"hardware": "api",
"id": "setup.factory-return",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928162331-3969",
"duration_s": 0,
"evidence": {
"archives": [],
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T16:23:31Z"
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"no_confirm": {
"body": {
"error": "confirm=1 required"
},
"status": 400
},
"setup_page": {
"bytes": 418622,
"status": 200
}
},
"fingerprint": "b141b9f0b5724333cc96dafeef4e97cd6b91b5ff333c597e2d8f0e23dc1b92d1",
"image": "20260928153805 (dev)",
"log": [
"16:27:34 start setup.factory-return (auto, api) in campaign c-20260928162331-3969",
"16:27:35 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:27:35 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"16:27:35 queued by the unattended queue opened 2026-09-28T16:23:31Z",
"16:27:35 baseline: pre: clean",
"16:27:35 POST /restore/factory-return (no confirm) -> 400 {'error': 'confirm=1 required'}",
"16:27:35 GET /slots archives: []",
"16:27:35 no archived factory image on this machine: the return would be refused (409) and the factory recovery mode is the way back",
"16:27:35 PASS: the return is refused without confirm=1; the page confirms before it calls",
"16:27:35 baseline: post: clean",
"16:27:35 result PASS"
],
"manifest_sha": "faf9563c750bb8bd4bfc8778b6af053cddb63fa335ab946caf2f71631ede740f",
"message": "",
"result": "PASS",
"test": "setup.factory-return",
"ts": "2026-09-28T16:27:35Z"
},
"requires": [
"update.slots-and-signature"
],
"satisfied": true,
"source_sha": "b3d5e09e32de8def044adbd8c0f59d7ecc4be7cd8eacc531c9e26c4bd2f40b12",
"subsystem": "setup",
"title": "The return to the factory firmware is guarded"
},
{
"always": false,
"covers": [],
"fingerprint": "d5e60eb57efa7bf4f616d3c98153eb964537897939640fd4115cef8f5bf9b8d2",
"hardware": "api",
"id": "setup.machine-name",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928162331-3969",
"duration_s": 0,
"evidence": {
"avahi_pids": [],
"banner_urls": [
"<IP-1>"
],
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T16:23:31Z"
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-2>",
"released": []
},
"hostname": "<REDACTED-2>",
"hostname_file": "<REDACTED-2>",
"issue": "\n \u001b[1;31m \u273a\u2508\u2508\u2508\u2508\u2508\u2508\n \u001b[1;39mOpen\u001b[0mGlow\n ___ \u001b[1;39m___ ___ ___ __ __\u001b[0m\n | __|__ _ _ __ _ ___\u001b[1;39m| __|_ _| _ \\\\ \\\\/ |\u001b[0m\n | _/ _ \\\\ '_/ _` / -_) \u001b[1;39m_| | || / |\\\\/| |\u001b[0m\n |_|\\\\___/_| \\\\__, \\\\___|\u001b[1;39m_| |___|_|_\\\\_| |_|\u001b[0m\n |___/ 20260928153805 (dev)\n\nControl panel:\n https://<IP-1>/\n\n",
"lan_ip": "<IP-1>",
"mac_suffix": "<REDACTED-3>",
"udhcpc": [
"udhcpc -R -b -p /var/run/udhcpc.wlan0.pid -i wlan0 -x hostname:<REDACTED-2>"
]
},
"fingerprint": "d5e60eb57efa7bf4f616d3c98153eb964537897939640fd4115cef8f5bf9b8d2",
"image": "20260928153805 (dev)",
"log": [
"16:27:35 start setup.machine-name (auto, api) in campaign c-20260928162331-3969",
"16:27:36 fixture up: <REDACTED-1> at <IP-2>, v1.0.0, covers lid, interlock, button",
"16:27:36 fixture: <REDACTED-1> at <IP-2> covers lid, interlock, button",
"16:27:36 queued by the unattended queue opened 2026-09-28T16:23:31Z",
"16:27:36 baseline: pre: clean",
"16:27:36 hostname '<REDACTED-2>' (MAC suffix <REDACTED-3>)",
"16:27:36 baseline: post: clean",
"16:27:36 result PASS"
],
"manifest_sha": "faf9563c750bb8bd4bfc8778b6af053cddb63fa335ab946caf2f71631ede740f",
"message": "",
"result": "PASS",
"test": "setup.machine-name",
"ts": "2026-09-28T16:27:36Z"
},
"requires": [
"forgectrl.auth"
],
"satisfied": true,
"source_sha": "2925c75f29caab62c6079cc94b76b109980b0444fa240e0683b84f2d3f99d296",
"subsystem": "setup",
"title": "The machine names itself from its MAC address"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/wiz.*"
],
[
"forgectrl",
"src/setup.*"
],
[
"forgectrl",
"src/users.*"
],
[
"forgectrl",
"src/session.*"
],
[
"forgectrl",
"src/button.*"
],
[
"forgectrl",
"src/led.*"
],
[
"forgectrl",
"src/sheetid.*"
],
[
"forgectrl",
"src/advisories.*"
],
[
"forgectrl",
"src/hooks.h"
],
[
"forgectrl",
"src/main.c"
]
],
"fingerprint": "3ecebeeff298f4dfdbee2883f846656a29a4dec8944b1f337a06dd7fe5e6d383",
"hardware": "takeover",
"id": "setup.first-run-flow",
"inherited": true,
"kind": "operator",
"record": {
"answers": [],
"campaign": "c-20260928162331-3969",
"duration_s": 20,
"evidence": {
"account": {
"cookie": true,
"status": 200
},
"account_before": "scott",
"actions": [
{
"by": "fixture",
"channel": "button",
"state": "press",
"took_s": 0.3,
"ts": "2026-09-28T16:27:40Z"
}
],
"after": {
"acceptance_done": true,
"account": true,
"advisories_complete": true,
"completed": true,
"first_run": false,
"gate": "open",
"override": true,
"required": [],
"versions": {
"account": 1,
"advisories": 1,
"airflow": 1,
"cameras": 1,
"cloud": 1,
"cloud.header": 1,
"cooling.aa-offset": 1,
"cooling.flow": 1,
"cooling.flow-load": 1,
"cooling.flow-verify": 1,
"laser.corner": 1,
"laser.dose-curve": 1,
"laser.floor": 1,
"laser.focus": 1,
"machine": 1,
"motion": 1,
"preferences": 1,
"sensors": 1,
"sheet.frame": 1,
"sheet.place": 1,
"switches": 1
},
"why": ""
},
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T16:23:31Z"
},
"before": {
"acceptance_done": true,
"account": true,
"advisories_complete": true,
"completed": true,
"first_run": false,
"gate": "open",
"override": true,
"required": [],
"versions": {
"account": 1,
"advisories": 1,
"airflow": 1,
"cameras": 1,
"cloud": 1,
"cloud.header": 1,
"cooling.aa-offset": 1,
"cooling.flow": 1,
"cooling.flow-load": 1,
"cooling.flow-verify": 1,
"laser.corner": 1,
"laser.dose-curve": 1,
"laser.floor": 1,
"laser.focus": 1,
"machine": 1,
"motion": 1,
"preferences": 1,
"sensors": 1,
"sheet.frame": 1,
"sheet.place": 1,
"switches": 1
},
"why": ""
},
"cloud_step": {
"data": {
"enabled": "1",
"homing_mode": "manual",
"phrase": "I UNDERSTAND"
},
"status": 200
},
"completed": {
"acceptance_done": true,
"account": true,
"advisories_complete": true,
"completed": true,
"first_run": false,
"gate": "open",
"override": true,
"required": [],
"versions": {
"account": 1,
"advisories": 1,
"airflow": 1,
"cameras": 1,
"cloud": 1,
"cloud.header": 1,
"cooling.aa-offset": 1,
"cooling.flow": 1,
"cooling.flow-load": 1,
"cooling.flow-verify": 1,
"cooling.tec": 1,
"laser.corner": 1,
"laser.dose-curve": 1,
"laser.floor": 1,
"laser.focus": 1,
"machine": 1,
"motion": 1,
"motion.envelope": 1,
"preferences": 1,
"sensors": 1,
"sheet.frame": 1,
"sheet.place": 1,
"switches": 1
},
"why": ""
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"fresh": {
"acceptance_done": false,
"account": false,
"advisories_complete": false,
"completed": false,
"first_run": true,
"gate": "closed",
"override": true,
"required": [
"advisories",
"account",
"preferences",
"machine",
"cloud"
],
"versions": {
"airflow": 1,
"cameras": 1,
"cloud.header": 1,
"cooling.aa-offset": 1,
"cooling.flow": 1,
"cooling.flow-load": 1,
"cooling.flow-verify": 1,
"cooling.tec": 1,
"laser.corner": 1,
"laser.dose-curve": 1,
"laser.floor": 1,
"laser.focus": 1,
"motion": 1,
"motion.envelope": 1,
"sensors": 1,
"sheet.frame": 1,
"sheet.place": 1,
"switches": 1
},
"why": "the advisories are not accepted"
},
"led_pattern": {
"pulse_off": [
0,
1400,
1400
],
"pulse_on": [
0,
1400,
1400
],
"target": [
0,
255,
255
]
},
"mode_after_setup": {
"controller": "running",
"gated": false,
"local": false,
"mode": "grbl",
"motion": "verified",
"pid": 4913,
"why": ""
},
"settings_before": {
"cloud_enabled": "1",
"controller_mode": "grbl",
"cool_tec_present": "0",
"gfcloud_home_timeout_s": "",
"homing_mode": "manual",
"ui_units": "imperial",
"wifi_country": "US"
},
"users_reload_rc": 0
},
"fingerprint": "3ecebeeff298f4dfdbee2883f846656a29a4dec8944b1f337a06dd7fe5e6d383",
"image": "20260928153805 (dev)",
"log": [
"16:27:36 start setup.first-run-flow (operator, takeover) in campaign c-20260928162331-3969",
"16:27:36 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:27:36 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"16:27:36 fixture: running unattended (no prompt can be answered)",
"16:27:36 queued by the unattended queue opened 2026-09-28T16:23:31Z",
"16:27:36 baseline: pre: clean",
"16:27:36 takeover: waiting for forgectrl to be settled",
"16:27:36 baseline: /mode controller=running motion=verified",
"16:27:36 takeover: preserving cnc/motor_lock=0, cnc/step_freq=112640, cnc/ramp_rate=500000, cnc/streaming=0, cnc/x_mode=32, cnc/y_mode=32, cnc/x_decay=1, cnc/y_decay=1, pic/x_step_current=33, pic/y_step_current=5",
"16:27:36 takeover: stopping the controller through forgectrl",
"16:27:37 takeover: POST /controller/stop -> 200",
"16:27:37 takeover: forgectrl stop -> rc 0",
"16:27:37 takeover: pulse device free",
"16:27:37 takeover: forgectrl start -> rc 0",
"16:27:39 baseline: /mode controller=gated motion=unverified",
"16:27:39 installed under a restart: setup.json=14050 B, users=removed, setup-override=0 B",
"16:27:40 the four documents are accepted",
"16:27:40 ACT button press (fixture)",
"16:27:40 ACT button press: done after 0.3 s",
"16:27:40 the press step: teal ({'target': [0, 255, 255], 'pulse_on': [0, 1400, 1400], 'pulse_off': [0, 1400, 1400]}), the press accepted",
"16:27:40 account 'bench-4bca' created, the session cookie set",
"16:27:40 preferences, machine (basic), cloud (1) written",
"16:27:41 baseline: /mode controller=stopped motion=unverified",
"16:27:47 baseline: /mode controller=running motion=verified",
"16:27:47 the run completed: gate open, the controller back",
"16:27:47 takeover: waiting for forgectrl to be settled",
"16:27:47 baseline: /mode controller=running motion=verified",
"16:27:47 takeover: preserving cnc/motor_lock=0, cnc/step_freq=112640, cnc/ramp_rate=500000, cnc/streaming=0, cnc/x_mode=32, cnc/y_mode=32, cnc/x_decay=1, cnc/y_decay=1, pic/x_step_current=33, pic/y_step_current=5",
"16:27:47 takeover: stopping the controller through forgectrl",
"16:27:47 takeover: POST /controller/stop -> 200",
"16:27:47 takeover: forgectrl stop -> rc 0",
"16:27:48 takeover: pulse device free",
"16:27:48 takeover: the counters are not in the frame the run began in (a controller start or a home the test did not declare), so the head is not judged here",
"16:27:48 takeover: forgectrl start -> rc 0",
"16:27:49 baseline: /mode controller=stopped motion=unverified",
"16:27:55 baseline: /mode controller=running motion=verified",
"16:27:55 restored under a restart: setup.json, users, setup-override",
"16:27:55 restore cloud_enabled='1' -> 200",
"16:27:55 restore homing_mode='manual' -> 200",
"16:27:55 restore controller_mode='grbl' -> 200",
"16:27:55 restore gfcloud_home_timeout_s='' -> 200",
"16:27:55 restore cool_tec_present='0' -> 200",
"16:27:55 restore ui_units='imperial' -> 200",
"16:27:56 restore wifi_country='US' -> 200",
"16:27:56 forgefirm-users reload -> rc 0 forgefirm-users: account scott created\nforgefirm-users: removing account bench-4bca (not in the record)",
"16:27:56 removed the temporary home directory of 'bench-4bca'",
"16:27:57 baseline: post: clean",
"16:27:57 result PASS"
],
"manifest_sha": "faf9563c750bb8bd4bfc8778b6af053cddb63fa335ab946caf2f71631ede740f",
"message": "",
"result": "PASS",
"test": "setup.first-run-flow",
"ts": "2026-09-28T16:27:57Z"
},
"requires": [
"setup.gate-blocks-controllers",
"setup.advisories-rehash"
],
"satisfied": true,
"source_sha": "61207c3872e70416fbb7e82bed00b58a1c167700652f51806c44c1a54d71f987",
"subsystem": "setup",
"title": "The first run, driven as the page drives it"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/ui/wizard.*"
],
[
"forgectrl",
"src/ui/forms.js"
],
[
"forgectrl",
"src/ui/md.js"
],
[
"forgectrl",
"src/ui/login.*"
],
[
"forgectrl",
"src/ui/embed_docs.cmake"
],
[
"forgectrl",
"src/tls.*"
]
],
"fingerprint": "1dfbd80a37bcf9b7b5fca97a24538ef2f913f936453cfdcb5e9b72dc87dadb76",
"hardware": "takeover",
"id": "setup.first-run-page",
"inherited": true,
"kind": "operator",
"record": {
"answers": [
{
"answer": "Yes",
"question": "Did the control panel open after Finish?",
"ts": "2026-09-28T18:52:14Z"
}
],
"campaign": "c-20260928183105-64ee",
"duration_s": 79,
"evidence": {
"account_before": "scott",
"actions": [
{
"by": "fixture",
"channel": "button",
"state": "press",
"took_s": 0.81,
"ts": "2026-09-28T18:51:45Z"
}
],
"after": {
"acceptance_done": true,
"account": true,
"advisories_complete": true,
"completed": true,
"first_run": false,
"gate": "open",
"override": true,
"required": [],
"versions": {
"account": 1,
"advisories": 1,
"airflow": 1,
"cameras": 1,
"cloud": 1,
"cloud.header": 1,
"cooling.aa-offset": 1,
"cooling.flow": 1,
"cooling.flow-load": 1,
"cooling.flow-verify": 1,
"laser.corner": 1,
"laser.dose-curve": 1,
"laser.floor": 1,
"laser.focus": 1,
"machine": 1,
"motion": 1,
"preferences": 1,
"sensors": 1,
"sheet.frame": 1,
"sheet.place": 1,
"switches": 1
},
"why": ""
},
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "attended",
"ts": "2026-09-28T18:51:04Z"
},
"before": {
"acceptance_done": true,
"account": true,
"advisories_complete": true,
"completed": true,
"first_run": false,
"gate": "open",
"override": true,
"required": [],
"versions": {
"account": 1,
"advisories": 1,
"airflow": 1,
"cameras": 1,
"cloud": 1,
"cloud.header": 1,
"cooling.aa-offset": 1,
"cooling.flow": 1,
"cooling.flow-load": 1,
"cooling.flow-verify": 1,
"laser.corner": 1,
"laser.dose-curve": 1,
"laser.floor": 1,
"laser.focus": 1,
"machine": 1,
"motion": 1,
"preferences": 1,
"sensors": 1,
"sheet.frame": 1,
"sheet.place": 1,
"switches": 1
},
"why": ""
},
"completed": {
"acceptance_done": true,
"account": true,
"advisories_complete": true,
"completed": true,
"first_run": false,
"gate": "open",
"override": true,
"required": [],
"versions": {
"account": 1,
"advisories": 1,
"airflow": 1,
"cameras": 1,
"cloud": 1,
"cloud.header": 1,
"cooling.aa-offset": 1,
"cooling.flow": 1,
"cooling.flow-load": 1,
"cooling.flow-verify": 1,
"cooling.tec": 1,
"laser.corner": 1,
"laser.dose-curve": 1,
"laser.floor": 1,
"laser.focus": 1,
"machine": 1,
"motion": 1,
"motion.envelope": 1,
"preferences": 1,
"sensors": 1,
"sheet.frame": 1,
"sheet.place": 1,
"switches": 1
},
"why": ""
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"fresh": {
"acceptance_done": false,
"account": false,
"advisories_complete": false,
"completed": false,
"first_run": true,
"gate": "closed",
"override": true,
"required": [
"advisories",
"account",
"preferences",
"machine",
"cloud"
],
"versions": {
"airflow": 1,
"cameras": 1,
"cloud.header": 1,
"cooling.aa-offset": 1,
"cooling.flow": 1,
"cooling.flow-load": 1,
"cooling.flow-verify": 1,
"cooling.tec": 1,
"laser.corner": 1,
"laser.dose-curve": 1,
"laser.floor": 1,
"laser.focus": 1,
"motion": 1,
"motion.envelope": 1,
"sensors": 1,
"sheet.frame": 1,
"sheet.place": 1,
"switches": 1
},
"why": "the advisories are not accepted"
},
"led_pattern": {
"pulse_off": [
0,
1400,
1400
],
"pulse_on": [
0,
1400,
1400
],
"target": [
0,
255,
255
]
},
"mode_after_setup": {
"controller": "running",
"gated": false,
"local": false,
"mode": "grbl",
"motion": "verified",
"pid": 5491,
"why": ""
},
"root_page": 200,
"settings_before": {
"cloud_enabled": "1",
"controller_mode": "grbl",
"cool_tec_present": "0",
"gfcloud_home_timeout_s": "",
"homing_mode": "manual",
"ui_units": "imperial",
"wifi_country": "US"
},
"temp_account": "minutes",
"users_reload_rc": 0
},
"fingerprint": "1dfbd80a37bcf9b7b5fca97a24538ef2f913f936453cfdcb5e9b72dc87dadb76",
"image": "20260928182434 (dev)",
"log": [
"18:51:04 start setup.first-run-page (operator, takeover) in campaign c-20260928183105-64ee",
"18:51:04 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"18:51:04 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"18:51:04 queued by the attended queue opened 2026-09-28T18:51:04Z",
"18:51:04 baseline: pre: clean",
"18:51:04 takeover: waiting for forgectrl to be settled",
"18:51:04 baseline: /mode controller=running motion=verified",
"18:51:04 takeover: preserving cnc/motor_lock=0, cnc/step_freq=112640, cnc/ramp_rate=500000, cnc/streaming=0, cnc/x_mode=32, cnc/y_mode=32, cnc/x_decay=1, cnc/y_decay=1, pic/x_step_current=33, pic/y_step_current=5",
"18:51:04 takeover: stopping the controller through forgectrl",
"18:51:05 takeover: POST /controller/stop -> 200",
"18:51:05 takeover: forgectrl stop -> rc 0",
"18:51:06 takeover: pulse device free",
"18:51:06 takeover: forgectrl start -> rc 0",
"18:51:08 baseline: /mode controller=gated motion=unverified",
"18:51:08 installed under a restart: setup.json=14051 B, users=removed, setup-override=0 B",
"18:51:08 NOTICE: Open https://<IP-2>/ from the workstation, accept the certificate, and click through the setup as the steps describe. The test follows the record.",
"18:51:35 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"18:51:44 the documents are accepted (36 s)",
"18:51:45 ACT button press (fixture)",
"18:51:46 ACT button press: done after 0.8 s",
"18:51:46 NOTICE: Continue on the page: the account, the preferences, the machine, the cloud step, Finish.",
"18:51:54 account 'minutes' created (8 s)",
"18:52:07 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"18:52:11 baseline: /mode controller=running motion=verified",
"18:52:11 PROMPT: Did the control panel open after Finish?",
"18:52:14 ANSWER: Yes",
"18:52:14 takeover: waiting for forgectrl to be settled",
"18:52:14 baseline: /mode controller=running motion=verified",
"18:52:14 takeover: preserving cnc/motor_lock=0, cnc/step_freq=112640, cnc/ramp_rate=500000, cnc/streaming=0, cnc/x_mode=32, cnc/y_mode=32, cnc/x_decay=1, cnc/y_decay=1, pic/x_step_current=33, pic/y_step_current=5",
"18:52:14 takeover: stopping the controller through forgectrl",
"18:52:14 takeover: POST /controller/stop -> 200",
"18:52:14 takeover: forgectrl stop -> rc 0",
"18:52:15 takeover: pulse device free",
"18:52:15 takeover: the counters are not in the frame the run began in (a controller start or a home the test did not declare), so the head is not judged here",
"18:52:15 takeover: forgectrl start -> rc 0",
"18:52:17 baseline: /mode controller=stopped motion=unverified",
"18:52:22 baseline: /mode controller=running motion=verified",
"18:52:22 restored under a restart: setup.json, users, setup-override",
"18:52:22 restore cloud_enabled='1' -> 200",
"18:52:22 restore homing_mode='manual' -> 200",
"18:52:22 restore controller_mode='grbl' -> 200",
"18:52:22 restore gfcloud_home_timeout_s='' -> 200",
"18:52:22 restore cool_tec_present='0' -> 200",
"18:52:22 restore ui_units='imperial' -> 200",
"18:52:23 restore wifi_country='US' -> 200",
"18:52:23 forgefirm-users reload -> rc 0 forgefirm-users: account scott created\nforgefirm-users: removing account minutes (not in the record)",
"18:52:23 removed the temporary home directory of 'minutes'",
"18:52:23 baseline: post: clean",
"18:52:23 result PASS"
],
"manifest_sha": "84a155bfc701e865ae73f9818bc38c2d005324ab5ba0ed44b668ec8896179947",
"message": "",
"result": "PASS",
"test": "setup.first-run-page",
"ts": "2026-09-28T18:52:23Z"
},
"requires": [
"setup.gate-blocks-controllers",
"setup.advisories-rehash",
"setup.first-run-flow"
],
"satisfied": true,
"source_sha": "e65892183ca17dcec935b0c5827165b221efe3539677cc113fbe352fdf0ea818",
"subsystem": "setup",
"title": "The first-run page, walked once"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/tls.*"
],
[
"forgectrl",
"src/main.c"
],
[
"forgectrl",
"src/ui/wizard.html"
],
[
"forgectrl",
"src/ui/wizard.js"
]
],
"fingerprint": "b06a2dd6681e5097370042bacd0d0cf997a56153ce15aa7b5a057e13109558da",
"hardware": "api",
"id": "setup.cert-page",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928162331-3969",
"duration_s": 0,
"evidence": {
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T16:23:31Z"
},
"fingerprint": "41:15:34:89:0E:D3:9F:C8:04:7D:D9:5E:71:85:6B:E6:8E:2B:87:A2:CE:C2:9C:1E:BD:82:AD:14:8A:77:1C:2D",
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"pem_bytes": 635
},
"fingerprint": "b06a2dd6681e5097370042bacd0d0cf997a56153ce15aa7b5a057e13109558da",
"image": "20260928153805 (dev)",
"log": [
"16:27:57 start setup.cert-page (auto, api) in campaign c-20260928162331-3969",
"16:27:57 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:27:57 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"16:27:57 queued by the unattended queue opened 2026-09-28T16:23:31Z",
"16:27:57 baseline: pre: clean",
"16:27:57 GET http://<IP-2>/cert -> 200",
"16:27:57 GET https://<IP-2>/cert -> 200",
"16:27:57 baseline: post: clean",
"16:27:57 result PASS"
],
"manifest_sha": "faf9563c750bb8bd4bfc8778b6af053cddb63fa335ab946caf2f71631ede740f",
"message": "",
"result": "PASS",
"test": "setup.cert-page",
"ts": "2026-09-28T16:27:57Z"
},
"requires": [
"forgectrl.auth"
],
"satisfied": true,
"source_sha": "f6619483e7d74f44afe0ed21bc474ae7d4d02f6f71a651e5dee8d9f7192ffd89",
"subsystem": "setup",
"title": "The certificate is checkable before the warning"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/setup.*"
],
[
"forgectrl",
"src/wiz.*"
],
[
"forgectrl",
"src/main.c"
],
[
"forgectrl",
"src/ui/panel.js"
],
[
"forgectrl",
"src/ui/index.html"
],
[
"forgectrl",
"src/ui/help.js"
]
],
"fingerprint": "5c8c6e5edcae1421721c911a9508c52211790ec22e07ae509c2066a5a247e041",
"hardware": "takeover",
"id": "setup.what-changed",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928162331-3969",
"duration_s": 9,
"evidence": {
"after": {
"acceptance_done": true,
"account": true,
"advisories_complete": true,
"completed": true,
"first_run": false,
"gate": "open",
"override": true,
"required": [],
"versions": {
"account": 1,
"advisories": 1,
"airflow": 1,
"cameras": 1,
"cloud": 1,
"cloud.header": 1,
"cooling.aa-offset": 1,
"cooling.flow": 1,
"cooling.flow-load": 1,
"cooling.flow-verify": 1,
"laser.corner": 1,
"laser.dose-curve": 1,
"laser.floor": 1,
"laser.focus": 1,
"machine": 1,
"motion": 1,
"preferences": 1,
"sensors": 1,
"sheet.frame": 1,
"sheet.place": 1,
"switches": 1
},
"why": ""
},
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T16:23:31Z"
},
"before": {
"acceptance_done": true,
"account": true,
"advisories_complete": true,
"completed": true,
"first_run": false,
"gate": "open",
"override": true,
"required": [],
"versions": {
"account": 1,
"advisories": 1,
"airflow": 1,
"cameras": 1,
"cloud": 1,
"cloud.header": 1,
"cooling.aa-offset": 1,
"cooling.flow": 1,
"cooling.flow-load": 1,
"cooling.flow-verify": 1,
"laser.corner": 1,
"laser.dose-curve": 1,
"laser.floor": 1,
"laser.focus": 1,
"machine": 1,
"motion": 1,
"preferences": 1,
"sensors": 1,
"sheet.frame": 1,
"sheet.place": 1,
"switches": 1
},
"why": ""
},
"fan_reason": "a fan was replaced",
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"gated_after_fan": false,
"gated_before": false,
"menu": [
"tube",
"pump",
"coolant",
"fan",
"head",
"tray",
"service"
],
"override": true,
"tray_reason": "the tray was replaced"
},
"fingerprint": "5c8c6e5edcae1421721c911a9508c52211790ec22e07ae509c2066a5a247e041",
"image": "20260928153805 (dev)",
"log": [
"16:27:58 start setup.what-changed (auto, takeover) in campaign c-20260928162331-3969",
"16:27:58 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:27:58 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"16:27:58 queued by the unattended queue opened 2026-09-28T16:23:31Z",
"16:27:58 baseline: pre: clean",
"16:27:58 POST /wiz/changed what=nothing-like-this -> 400",
"16:27:58 POST /wiz/changed what=tray -> 200",
"16:27:58 POST /wiz/changed what=fan -> 200",
"16:27:58 tray -> focus recommended; fan -> airflow required; gate open (override True)",
"16:27:58 takeover: waiting for forgectrl to be settled",
"16:27:58 baseline: /mode controller=running motion=verified",
"16:27:58 takeover: preserving cnc/motor_lock=0, cnc/step_freq=112640, cnc/ramp_rate=500000, cnc/streaming=0, cnc/x_mode=32, cnc/y_mode=32, cnc/x_decay=1, cnc/y_decay=1, pic/x_step_current=33, pic/y_step_current=5",
"16:27:58 takeover: stopping the controller through forgectrl",
"16:27:59 takeover: POST /controller/stop -> 200",
"16:27:59 takeover: forgectrl stop -> rc 0",
"16:28:00 takeover: pulse device free",
"16:28:00 takeover: forgectrl start -> rc 0",
"16:28:02 baseline: /mode controller=stopped motion=unverified",
"16:28:07 baseline: /mode controller=running motion=verified",
"16:28:07 restored under a restart: setup.json",
"16:28:07 baseline: post: clean",
"16:28:07 result PASS"
],
"manifest_sha": "faf9563c750bb8bd4bfc8778b6af053cddb63fa335ab946caf2f71631ede740f",
"message": "",
"result": "PASS",
"test": "setup.what-changed",
"ts": "2026-09-28T16:28:07Z"
},
"requires": [
"forgectrl.auth"
],
"satisfied": true,
"source_sha": "0181c1fcca9c206f578ae6c306ae27a1f24951c65642decdf09107ed431499ca",
"subsystem": "setup",
"title": "A replaced part asks for its checks again"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/setup.*"
],
[
"forgectrl",
"src/recordhtml.*"
],
[
"forgectrl",
"src/wiz.*"
],
[
"forgectrl",
"src/logs.*"
],
[
"forgectrl",
"src/main.c"
],
[
"forgectrl",
"src/ui/index.html"
],
[
"forgectrl",
"src/ui/panel.js"
],
[
"forgectrl",
"src/ui/wizard.html"
]
],
"fingerprint": "b1318fffdc9ac234a2138d467a28a4ad47f60486ebadd34a50ee15856433d185",
"hardware": "api",
"id": "setup.record-export",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928162331-3969",
"duration_s": 51,
"evidence": {
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T16:23:31Z"
},
"bundle_record_bytes": 19779,
"download_disposition": "attachment; filename=\"forgefirm-setup-KZZ77-UF6XM.json\"",
"export_s": 50.0,
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"missing_on_page": [],
"page_bytes": 17655,
"sheet_id": "KZZ77-UF6XM",
"wizards_in_record": [
"account",
"advisories",
"airflow",
"cameras",
"cloud",
"cloud.header",
"cooling.aa-offset",
"cooling.flow",
"cooling.flow-load",
"cooling.flow-verify",
"laser.corner",
"laser.dose-curve",
"laser.floor",
"laser.focus",
"machine",
"motion",
"preferences",
"sensors",
"sheet.frame",
"sheet.place",
"switches"
]
},
"fingerprint": "b1318fffdc9ac234a2138d467a28a4ad47f60486ebadd34a50ee15856433d185",
"image": "20260928153805 (dev)",
"log": [
"16:28:59 start setup.record-export (auto, api) in campaign c-20260928162331-3969",
"16:28:59 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:28:59 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"16:28:59 queued by the unattended queue opened 2026-09-28T16:23:31Z",
"16:28:59 baseline: pre: clean",
"16:28:59 GET /wiz/record -> 200 (12224 bytes)",
"16:29:00 GET /wiz/record.html -> 200 (17655 bytes)",
"16:29:35 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:29:50 POST /logs/export -> 200 (4215755 bytes, 50.0 s)",
"16:29:50 record 21 wizards; page 17655 bytes; bundle carries the record",
"16:29:50 baseline: post: clean",
"16:29:50 result PASS"
],
"manifest_sha": "faf9563c750bb8bd4bfc8778b6af053cddb63fa335ab946caf2f71631ede740f",
"message": "",
"result": "PASS",
"test": "setup.record-export",
"ts": "2026-09-28T16:29:50Z"
},
"requires": [
"forgectrl.auth",
"logs.tree-tail-export"
],
"satisfied": true,
"source_sha": "d369fa462a2678d49cfa51ee2739ec76e00f56451e97f46ab8cbc9f540434580",
"subsystem": "setup",
"title": "The record: JSON, the printable page, and the log bundle"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/wizdark.*"
],
[
"forgectrl",
"src/wizcalc.*"
],
[
"forgectrl",
"src/wiz.*"
],
[
"forgectrl",
"src/session.*"
],
[
"forgectrl",
"src/ui/wizard.js"
],
[
"forgectrl",
"src/ui/wizard.html"
],
[
"forgectrl",
"src/ui/wizard.css"
]
],
"fingerprint": "ccc8d81822f9dd62cd5c7805478f68aa9962c9b9967c6ed5d905297954d2c1e5",
"hardware": "takeover",
"id": "setup.mirror",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928162331-3969",
"duration_s": 20,
"evidence": {
"a_sees": {
"mine": true,
"owned": true,
"running": true
},
"account_before": "scott",
"after_takeover": {
"a": false,
"b": true
},
"b_abort_refused": 409,
"b_sees": {
"mine": false,
"owned": true,
"running": true
},
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T16:23:31Z"
},
"end": {
"error": "aborted",
"running": false
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"tool_sees": {
"mine": true,
"owned": true,
"running": true
},
"users_reload_rc": 0
},
"fingerprint": "ccc8d81822f9dd62cd5c7805478f68aa9962c9b9967c6ed5d905297954d2c1e5",
"image": "20260928153805 (dev)",
"log": [
"16:30:02 start setup.mirror (auto, takeover) in campaign c-20260928162331-3969",
"16:30:03 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:30:03 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"16:30:03 queued by the unattended queue opened 2026-09-28T16:23:31Z",
"16:30:03 baseline: pre: clean",
"16:30:03 takeover: waiting for forgectrl to be settled",
"16:30:03 baseline: /mode controller=running motion=verified",
"16:30:03 takeover: preserving cnc/motor_lock=0, cnc/step_freq=112640, cnc/ramp_rate=500000, cnc/streaming=0, cnc/x_mode=32, cnc/y_mode=32, cnc/x_decay=1, cnc/y_decay=1, pic/x_step_current=33, pic/y_step_current=5",
"16:30:03 takeover: stopping the controller through forgectrl",
"16:30:03 takeover: POST /controller/stop -> 200",
"16:30:03 takeover: forgectrl stop -> rc 0",
"16:30:04 takeover: pulse device free",
"16:30:04 takeover: forgectrl start -> rc 0",
"16:30:06 baseline: /mode controller=stopped motion=unverified",
"16:30:11 baseline: /mode controller=running motion=verified",
"16:30:11 installed under a restart: users=removed",
"16:30:12 POST /wiz/sensors/start (session A) -> 200",
"16:30:12 POST /wiz/sensors/abort (session B) -> 409 {'error': 'another browser is running this step; take it over to answer'}",
"16:30:12 POST /wiz/sensors/takeover (session B) -> 200",
"16:30:12 POST /wiz/sensors/abort (session B, owner) -> 200",
"16:30:14 takeover: waiting for forgectrl to be settled",
"16:30:14 baseline: /mode controller=running motion=verified",
"16:30:14 takeover: preserving cnc/motor_lock=0, cnc/step_freq=112640, cnc/ramp_rate=500000, cnc/streaming=0, cnc/x_mode=32, cnc/y_mode=32, cnc/x_decay=1, cnc/y_decay=1, pic/x_step_current=33, pic/y_step_current=5",
"16:30:14 takeover: stopping the controller through forgectrl",
"16:30:14 takeover: POST /controller/stop -> 200",
"16:30:14 takeover: forgectrl stop -> rc 0",
"16:30:15 takeover: pulse device free",
"16:30:15 takeover: the counters are not in the frame the run began in (a controller start or a home the test did not declare), so the head is not judged here",
"16:30:15 takeover: forgectrl start -> rc 0",
"16:30:17 baseline: /mode controller=stopped motion=unverified",
"16:30:22 baseline: /mode controller=running motion=verified",
"16:30:22 restored under a restart: users",
"16:30:22 A owned the run, B mirrored, B took over and stopped it; the account is back",
"16:30:23 baseline: post: clean",
"16:30:23 result PASS"
],
"manifest_sha": "faf9563c750bb8bd4bfc8778b6af053cddb63fa335ab946caf2f71631ede740f",
"message": "",
"result": "PASS",
"test": "setup.mirror",
"ts": "2026-09-28T16:30:23Z"
},
"requires": [
"forgectrl.auth",
"setup.account-login",
"setup.check-sensors"
],
"satisfied": true,
"source_sha": "55e4777cc692552ca381993767ec87d5a0e87699d9cd4401758fe353dd49e72d",
"subsystem": "setup",
"title": "One browser drives a check; a second one follows"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/wizdark.*"
],
[
"forgectrl",
"src/wizcalc.*"
],
[
"forgectrl",
"src/wiz.*"
],
[
"forgectrl",
"src/setup.*"
],
[
"forgectrl",
"src/main.c"
],
[
"forgectrl",
"src/ui/wizard.*"
],
[
"forgectrl",
"src/status.c"
]
],
"fingerprint": "b4d7a6b94e12bfe5f7dda4b4edabc91ca2a552c8f9e7aeaaf5347d19e69a147b",
"hardware": "api",
"id": "setup.check-switches",
"inherited": true,
"kind": "operator",
"record": {
"answers": [],
"campaign": "c-20260928162331-3969",
"duration_s": 4,
"evidence": {
"actions": [
{
"by": "fixture",
"channel": "lid",
"state": "open",
"took_s": 0.26,
"ts": "2026-09-28T16:30:23Z"
},
{
"by": "fixture",
"channel": "lid",
"state": "close",
"took_s": 0.26,
"ts": "2026-09-28T16:30:24Z"
},
{
"by": "fixture",
"channel": "button",
"state": "press",
"took_s": 0.28,
"ts": "2026-09-28T16:30:26Z"
}
],
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T16:23:31Z"
},
"elapsed_s": 3.9,
"error": "",
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"log": [
"00:00 switches at start: 0x0b",
"00:00 lid-open: seen",
"00:01 lid-close: seen",
"00:02 HV enable readback: closed 0, open 0, closed 0 (did not follow the lid)",
"00:03 button-press: seen",
"00:03 button-release: seen",
"00:03 head: present"
],
"phases": [
"Open the lid.",
"Close the lid.",
"Press the button once."
],
"result": {
"button": true,
"head_present": true,
"hv_enable_follows_lid": false,
"interlock": "satisfied",
"lid": true
},
"started": true
},
"fingerprint": "b4d7a6b94e12bfe5f7dda4b4edabc91ca2a552c8f9e7aeaaf5347d19e69a147b",
"image": "20260928153805 (dev)",
"log": [
"16:30:23 start setup.check-switches (operator, api) in campaign c-20260928162331-3969",
"16:30:23 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:30:23 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"16:30:23 fixture: running unattended (no prompt can be answered)",
"16:30:23 queued by the unattended queue opened 2026-09-28T16:23:31Z",
"16:30:23 baseline: pre: clean",
"16:30:23 POST /wiz/switches/start -> 200 {'started': True, 'id': 'switches'}",
"16:30:23 switches: Open the lid.",
"16:30:23 prompt lid-open (wait): Open the lid.",
"16:30:23 ACT lid open (fixture)",
"16:30:23 ACT lid open: done after 0.3 s",
"16:30:24 switches: Close the lid.",
"16:30:24 prompt lid-close (wait): Close the lid.",
"16:30:24 ACT lid close (fixture)",
"16:30:25 ACT lid close: done after 0.3 s",
"16:30:26 switches: Press the button once.",
"16:30:26 prompt button-press (wait): Press the button once.",
"16:30:26 ACT button press (fixture)",
"16:30:26 ACT button press: done after 0.3 s",
"16:30:27 switches: {\"lid\": true, \"hv_enable_follows_lid\": false, \"button\": true, \"interlock\": \"satisfied\", \"head_present\": true}",
"16:30:27 baseline: post: clean",
"16:30:27 result PASS"
],
"manifest_sha": "faf9563c750bb8bd4bfc8778b6af053cddb63fa335ab946caf2f71631ede740f",
"message": "",
"result": "PASS",
"test": "setup.check-switches",
"ts": "2026-09-28T16:30:27Z"
},
"requires": [
"forgectrl.auth"
],
"satisfied": true,
"source_sha": "a88d2dcaa15eb85be7ec74733fe7f3820b02915cdaaf375915aff8261efe55c4",
"subsystem": "setup",
"title": "The switches check follows the lid and the button"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/wizdark.*"
],
[
"forgectrl",
"src/wizcalc.*"
],
[
"forgectrl",
"src/wiz.*"
],
[
"forgectrl",
"src/setup.*"
],
[
"forgectrl",
"src/main.c"
],
[
"forgectrl",
"src/ui/wizard.*"
],
[
"forgectrl",
"src/status.c"
],
[
"forgectrl",
"src/accel.c"
],
[
"forgectrl",
"src/cool.c"
]
],
"fingerprint": "d831e5b27ac8e915df8ccb089331b5b6fc410c3279632835b749db77cb09488f",
"hardware": "api",
"id": "setup.check-sensors",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928162331-3969",
"duration_s": 11,
"evidence": {
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T16:23:31Z"
},
"elapsed_s": 11.1,
"error": "",
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"log": [
"00:10 coolant 26.1/26.1 C, chassis 30.1, SoC 50.8, IR max 50/50/54/54, pgood 255, HV 0"
],
"phases": [
"sampling the sensors at rest for 10 s"
],
"result": {
"accel_events": 0,
"accel_watched": true,
"chassis_c": 30.1,
"coolant_down_c": 26.1,
"coolant_up_c": 26.1,
"exhaust_rpm_idle": 0.0,
"hv_current_max": 0,
"intake_rpm_idle": 731.0,
"laser_pgood": 1,
"lid_ir_max": [
50,
50,
54,
54
],
"purge_current": 632,
"soc_c": 50.8
},
"settings_before": {
"cloud_enabled": "1",
"cloud_hold_max_s": "",
"cloud_pause_backtrack_ticks": "",
"cloud_resume_lead_ticks": "",
"controller_mode": "grbl",
"cool_aa_offset_counts": "16",
"cool_accel_abort": "",
"cool_accel_x_alert": "",
"cool_accel_y_alert": "",
"cool_confirm_max_s": "",
"cool_cooldown_max_s": "",
"cool_cooldown_s": "",
"cool_fan_grace_s": "12",
"cool_fire_q1_alert": "",
"cool_fire_q1_critical": "",
"cool_fire_q2_alert": "",
"cool_fire_q2_critical": "",
"cool_flow_check_s": "",
"cool_flow_heater_pct": "40",
"cool_flow_rise": "14.5",
"cool_laser_heat_cw": "6.533e-05",
"cool_laser_heat_density": "5.03e-05",
"cool_purge_min_current": "345",
"cool_recheck_s": "",
"cool_tach_air_assist_min_rpm": "6093",
"cool_tach_exhaust_min_rpm": "6416",
"cool_tach_intake_min_rpm": "2277",
"cool_tec_off_c": "",
"cool_tec_on_c": "",
"cool_tec_present": "0",
"cool_temp_critical_c": "",
"cool_temp_max": "",
"cool_temp_min": "",
"cool_temp_offset_c": "",
"cool_temp_resume": "",
"cool_temp_start": "",
"envelope_x_mm": "508",
"envelope_y_mm": "288.925",
"ext_enabled": "1",
"gates": {
"cool_accel_abort": {
"band": [
100,
170
],
"def": 133,
"gate": "crash_abort",
"hi": 255,
"lo": 0,
"off": "low",
"state": "ok",
"value": 133
},
"cool_accel_x_alert": {
"band": [
100,
170
],
"def": 132,
"gate": "crash_x_alert",
"hi": 255,
"lo": 0,
"off": "low",
"state": "ok",
"value": 132
},
"cool_accel_y_alert": {
"band": [
85,
145
],
"def": 112,
"gate": "crash_y_alert",
"hi": 255,
"lo": 0,
"off": "low",
"state": "ok",
"value": 112
},
"cool_fan_grace_s": {
"band": [
5,
30
],
"def": 15,
"gate": null,
"hi": 120,
"lo": 0,
"off": "none",
"state": "ok",
"value": 12
},
"cool_fire_q1_alert": {
"band": [
250,
450
],
"def": 275,
"gate": "flame_q1_alert",
"hi": 1023,
"lo": 0,
"off": "low",
"state": "ok",
"value": 275
},
"cool_fire_q1_critical": {
"band": [
500,
1023
],
"def": 688,
"gate": "flame_q1_critical",
"hi": 1023,
"lo": 0,
"off": "low",
"state": "ok",
"value": 688
},
"cool_fire_q2_alert": {
"band": [
300,
500
],
"def": 374,
"gate": "flame_q2_alert",
"hi": 1023,
"lo": 0,
"off": "low",
"state": "ok",
"value": 374
},
"cool_fire_q2_critical": {
"band": [
500,
1023
],
"def": 1022,
"gate": "flame_q2_critical",
"hi": 1023,
"lo": 0,
"off": "low",
"state": "ok",
"value": 1022
},
"cool_flow_check_s": {
"band": [
30,
120
],
"def": 50,
"gate": "flow",
"hi": 300,
"lo": 0,
"off": "low",
"state": "ok",
"value": 50
},
"cool_flow_rise": {
"band": [
8,
16
],
"def": 14.4,
"gate": null,
"hi": 40,
"lo": 1,
"off": "none",
"state": "ok",
"value": 14.5
},
"cool_purge_min_current": {
"band": [
150,
500
],
"def": 300,
"gate": "purge",
"hi": 1023,
"lo": 0,
"off": "low",
"state": "ok",
"value": 345
},
"cool_recheck_s": {
"band": [
60,
600
],
"def": 150,
"gate": "recheck",
"hi": 3600,
"lo": 0,
"off": "low",
"state": "ok",
"value": 150
},
"cool_tach_air_assist_min_rpm": {
"band": [
5500,
6600
],
"def": 6000,
"gate": "air_assist",
"hi": 30000,
"lo": 0,
"off": "low",
"state": "ok",
"value": 6093
},
"cool_tach_exhaust_min_rpm": {
"band": [
5800,
7000
],
"def": 6400,
"gate": "exhaust",
"hi": 20000,
"lo": 0,
"off": "low",
"state": "ok",
"value": 6416
},
"cool_tach_intake_min_rpm": {
"band": [
2100,
2500
],
"def": 2290,
"gate": "intake",
"hi": 20000,
"lo": 0,
"off": "low",
"state": "ok",
"value": 2277
},
"cool_tec_off_c": {
"band": [
16,
22
],
"def": 18,
"gate": null,
"hi": 31,
"lo": 5,
"off": "none",
"state": "ok",
"value": 18
},
"cool_tec_on_c": {
"band": [
18,
24
],
"def": 20,
"gate": null,
"hi": 32,
"lo": 6,
"off": "none",
"state": "ok",
"value": 20
},
"cool_temp_critical_c": {
"band": [
36,
45
],
"def": 38,
"gate": "coolant_critical",
"hi": 70,
"lo": 6,
"off": "high",
"state": "ok",
"value": 38
},
"cool_temp_max": {
"band": [
25,
38
],
"def": 33,
"gate": "coolant_max",
"hi": 60,
"lo": 5,
"off": "high",
"state": "ok",
"value": 33
},
"cool_temp_min": {
"band": [
3,
8
],
"def": 5,
"gate": "coolant_min",
"hi": 40,
"lo": 0,
"off": "low",
"state": "ok",
"value": 5
},
"cool_temp_resume": {
"band": [
20,
36
],
"def": 31,
"gate": null,
"hi": 59,
"lo": 5,
"off": "none",
"state": "ok",
"value": 31
},
"cool_temp_start": {
"band": [
12,
20
],
"def": 16,
"gate": "warm_up",
"hi": 40,
"lo": 0,
"off": "low",
"state": "ok",
"value": 16
}
},
"gf_password_set": true,
"gf_serial": "<REDACTED-2>",
"gfcloud_home_timeout_s": "",
"gfcloud_home_x": "",
"gfcloud_home_y": "",
"homing_mode": "manual",
"laser_button_timeout_s": "",
"laser_corner_gamma": "1.50",
"laser_disarm_s": "",
"laser_dose_curve": "10:0.62,20:2.79,30:8.46,45:24.90,60:42.02,80:52.53,100:100.00",
"laser_floor_density": "14",
"laser_pulse_min_ticks": "",
"laser_pulse_ticks": "",
"lens_hall_edge_z_mm": "4.51",
"lens_park_z_mm": "",
"lens_stop_above_steps": "20",
"lens_stop_below_steps": "14",
"lid_lamp_idle": "",
"lid_policy": "",
"log_forgectrl_disk": "",
"log_forgectrl_remote": "",
"log_forgeext_disk": "",
"log_forgeext_remote": "",
"log_gfcloud_disk": "",
"log_gfcloud_remote": "",
"log_gfhome_disk": "",
"log_gfhome_remote": "",
"log_grblhal_disk": "",
"log_grblhal_remote": "",
"log_kernel_disk": "",
"log_kernel_remote": "",
"log_system_disk": "",
"log_system_remote": "",
"machine_id": "<REDACTED-3>",
"manual_home_x": "",
"manual_home_y": "",
"panel_open_reads": "",
"pulse_reject_threshold_bytes": "",
"pulse_warn_threshold_bytes": "",
"rail_settle_s": "",
"syslog_port": "",
"syslog_proto": "",
"syslog_server": "",
"tls_fingerprint": "<MAC-1>:<MAC-2>:<MAC-3>:<MAC-4>:<MAC-5>:1C:2D",
"tray_offset_mm": "",
"ui_units": "imperial",
"version": "20260928153805 (dev)",
"wifi_country": "US",
"xy_microsteps": "32"
},
"started": true
},
"fingerprint": "d831e5b27ac8e915df8ccb089331b5b6fc410c3279632835b749db77cb09488f",
"image": "20260928153805 (dev)",
"log": [
"16:29:50 start setup.check-sensors (auto, api) in campaign c-20260928162331-3969",
"16:29:51 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:29:51 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"16:29:51 queued by the unattended queue opened 2026-09-28T16:23:31Z",
"16:29:51 baseline: pre: clean",
"16:29:51 POST /wiz/sensors/start -> 200 {'started': True, 'id': 'sensors'}",
"16:29:52 sensors: sampling the sensors at rest for 10 s",
"16:30:02 sensors: coolant 26.1/26.1 C, IR [50, 50, 54, 54], HV 0",
"16:30:02 baseline: post: clean",
"16:30:02 result PASS"
],
"manifest_sha": "faf9563c750bb8bd4bfc8778b6af053cddb63fa335ab946caf2f71631ede740f",
"message": "",
"result": "PASS",
"test": "setup.check-sensors",
"ts": "2026-09-28T16:30:02Z"
},
"requires": [
"forgectrl.auth"
],
"satisfied": true,
"source_sha": "646bde6030b0a93c613b611c48c08cd97ff0b322cd3a3c7b31708074e0413d8e",
"subsystem": "setup",
"title": "The sensors check reads a plausible machine at rest"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/wizdark.*"
],
[
"forgectrl",
"src/wizcalc.*"
],
[
"forgectrl",
"src/wiz.*"
],
[
"forgectrl",
"src/setup.*"
],
[
"forgectrl",
"src/main.c"
],
[
"forgectrl",
"src/ui/wizard.*"
],
[
"forgectrl",
"src/cool.c"
],
[
"forgectrl",
"src/airflow.*"
],
[
"forgectrl",
"src/gates.c"
],
[
"forgectrl",
"src/super.c"
]
],
"fingerprint": "41941492f2d627f510d33809010e1bc4a191a3c63f56bf00d9501c437d81f267",
"hardware": "takeover",
"id": "setup.check-airflow",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928162331-3969",
"duration_s": 40,
"evidence": {
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T16:23:31Z"
},
"elapsed_s": 39.2,
"error": "",
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"log": [
"00:00 fans to run duty, purge on",
"00:38 exhaust: 11679 rpm steady, 90 percent at 4.5 s",
"00:38 intake 1: 4187 rpm steady, 90 percent at 0.5 s",
"00:38 intake 2: 4169 rpm steady, 90 percent at 1.1 s",
"00:38 air assist: 10901 rpm steady, 90 percent at 0.6 s",
"00:38 purge current 629 on, 1 off",
"00:38 floors: exhaust 6424, intake 2293, air assist 5996, purge 346; grace 10 s"
],
"phases": [
"stopping the motion controller",
"fans to the run profile for 35 s",
"purge off, reading the off current"
],
"purge_after": {
"gate": {
"floor": 345,
"reading": 601,
"state": "idle"
},
"purge_air": "1",
"took_s": 0.010878324508666992
},
"result": {
"fans": {
"air assist": {
"ok": true,
"spinup_s": 0.6,
"steady_rpm": 10901.0
},
"exhaust": {
"ok": true,
"spinup_s": 4.5,
"steady_rpm": 11679.0
},
"intake 1": {
"ok": true,
"spinup_s": 0.5,
"steady_rpm": 4187.0
},
"intake 2": {
"ok": true,
"spinup_s": 1.1,
"steady_rpm": 4169.0
}
},
"floors": {
"cool_fan_grace_s": "10",
"cool_purge_min_current": "346",
"cool_tach_air_assist_min_rpm": "5996",
"cool_tach_exhaust_min_rpm": "6424",
"cool_tach_intake_min_rpm": "2293"
},
"purge_current_off": 1.0,
"purge_current_on": 629.0
},
"settings_before": {
"cool_fan_grace_s": "12",
"cool_purge_min_current": "345",
"cool_tach_air_assist_min_rpm": "6093",
"cool_tach_exhaust_min_rpm": "6416",
"cool_tach_intake_min_rpm": "2277"
},
"started": true
},
"fingerprint": "41941492f2d627f510d33809010e1bc4a191a3c63f56bf00d9501c437d81f267",
"image": "20260928153805 (dev)",
"log": [
"16:31:19 start setup.check-airflow (auto, takeover) in campaign c-20260928162331-3969",
"16:31:19 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:31:19 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"16:31:19 queued by the unattended queue opened 2026-09-28T16:23:31Z",
"16:31:19 baseline: pre: clean",
"16:31:19 POST /wiz/airflow/start -> 200 {'started': True, 'id': 'airflow'}",
"16:31:19 airflow: stopping the motion controller",
"16:31:20 airflow: fans to the run profile for 35 s",
"16:31:55 airflow: purge off, reading the off current",
"16:31:57 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:31:58 exhaust: 11679.0 rpm steady, 90 percent at 4.5 s",
"16:31:58 intake 1: 4187.0 rpm steady, 90 percent at 0.5 s",
"16:31:58 intake 2: 4169.0 rpm steady, 90 percent at 1.1 s",
"16:31:58 air assist: 10901.0 rpm steady, 90 percent at 0.6 s",
"16:31:58 floors: {\"cool_tach_exhaust_min_rpm\": \"6424\", \"cool_tach_intake_min_rpm\": \"2293\", \"cool_tach_air_assist_min_rpm\": \"5996\", \"cool_purge_min_current\": \"346\", \"cool_fan_grace_s\": \"10\"}",
"16:31:58 purge after the check: commanded 1, drawing 601 against the 345 floor (after 0.0 s)",
"16:31:58 restore cool_tach_exhaust_min_rpm='6416' -> 200",
"16:31:58 restore cool_tach_intake_min_rpm='2277' -> 200",
"16:31:58 restore cool_tach_air_assist_min_rpm='6093' -> 200",
"16:31:58 restore cool_purge_min_current='345' -> 200",
"16:31:59 restore cool_fan_grace_s='12' -> 200",
"16:31:59 baseline: post: clean",
"16:31:59 result PASS"
],
"manifest_sha": "faf9563c750bb8bd4bfc8778b6af053cddb63fa335ab946caf2f71631ede740f",
"message": "",
"result": "PASS",
"test": "setup.check-airflow",
"ts": "2026-09-28T16:31:59Z"
},
"requires": [
"forgectrl.auth",
"cooling.fan-gate-trips"
],
"satisfied": true,
"source_sha": "2db42f299bc4bf7e8a687a82614d2381a8797a93daeb2ba57d6f880e117f1712",
"subsystem": "setup",
"title": "The airflow check measures the fans and sets the floors"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/wizdark.*"
],
[
"forgectrl",
"src/wizcalc.*"
],
[
"forgectrl",
"src/wiz.*"
],
[
"forgectrl",
"src/setup.*"
],
[
"forgectrl",
"src/main.c"
],
[
"forgectrl",
"src/ui/wizard.*"
],
[
"forgectrl",
"src/cam.c"
]
],
"fingerprint": "6baff52147d1e82b55a5b64a588e7b3d08b93ce407bd3a25620e44038f251be1",
"hardware": "api",
"id": "setup.check-cameras",
"inherited": true,
"kind": "operator",
"record": {
"answers": [],
"campaign": "c-20260928162331-3969",
"duration_s": 13,
"evidence": {
"actions": [
{
"by": "fixture",
"channel": "lid",
"state": "close",
"took_s": 0.02,
"ts": "2026-09-28T16:32:16Z"
}
],
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T16:23:31Z"
},
"elapsed_s": 4.1,
"error": "",
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"log": [
"00:01 lid snapshot: 75643 bytes",
"00:02 head snapshot: 52222 bytes"
],
"phases": [
"a lid camera snapshot",
"a head camera snapshot"
],
"result": {
"head_ok": true,
"lamp_idle": 236,
"lid_ok": true,
"sensor": "OV5648"
},
"shots": {
"head": {
"bytes": 52222,
"jpeg": true,
"status": 200
},
"lid": {
"bytes": 75643,
"jpeg": true,
"status": 200
}
},
"started": true
},
"fingerprint": "6baff52147d1e82b55a5b64a588e7b3d08b93ce407bd3a25620e44038f251be1",
"image": "20260928153805 (dev)",
"log": [
"16:32:16 start setup.check-cameras (operator, api) in campaign c-20260928162331-3969",
"16:32:16 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:32:16 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"16:32:16 fixture: running unattended (no prompt can be answered)",
"16:32:16 queued by the unattended queue opened 2026-09-28T16:23:31Z",
"16:32:16 baseline: pre: clean",
"16:32:16 ACT lid close (fixture)",
"16:32:16 ACT lid close: done after 0.0 s",
"16:32:16 POST /wiz/cameras/start -> 200 {'started': True, 'id': 'cameras'}",
"16:32:16 cameras: a lid camera snapshot",
"16:32:17 prompt lid-view (confirm): This is the lid camera. Can you see the bed?",
"16:32:18 cameras: a head camera snapshot",
"16:32:19 prompt head-view (confirm): This is the head camera. Can you see the bed under the lens?",
"16:32:20 cameras: OV5648, lid 75643 bytes, head 52222 bytes",
"16:32:30 baseline: post: clean",
"16:32:30 result PASS"
],
"manifest_sha": "faf9563c750bb8bd4bfc8778b6af053cddb63fa335ab946caf2f71631ede740f",
"message": "",
"result": "PASS",
"test": "setup.check-cameras",
"ts": "2026-09-28T16:32:30Z"
},
"requires": [
"forgectrl.auth",
"camera.snapshot"
],
"satisfied": true,
"source_sha": "8ff1b08a1f8c9945b5d7884d75c2a88bfc60437a867457b903a64aa2ecf6b1b4",
"subsystem": "setup",
"title": "The cameras check captures both cameras"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/wizdark.*"
],
[
"forgectrl",
"src/wizcalc.*"
],
[
"forgectrl",
"src/wiz.*"
],
[
"forgectrl",
"src/setup.*"
],
[
"forgectrl",
"src/main.c"
],
[
"forgectrl",
"src/ui/wizard.*"
],
[
"forgectrl",
"src/super.c"
],
[
"forgectrl",
"src/liveness.c"
],
[
"forgectrl",
"src/lenshome.*"
],
[
"forgectrl",
"src/accel.c"
],
[
"forgectrl",
"src/cool.c"
]
],
"fingerprint": "ee1c2d205e408a690e709f57331876b2bf7d5165c2ac6edac9cddf244ba26b92",
"hardware": "takeover",
"id": "setup.check-motion",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928162331-3969",
"duration_s": 20,
"evidence": {
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T16:23:31Z"
},
"elapsed_s": 20.1,
"error": "",
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"log": [
"00:06 liveness probe: head accel p2p x=2357 y=2138 (moving>=800 dead<=250)",
"00:08 lens reference pass 1: 0",
"00:09 lens reference pass 2: 0",
"00:10 lens reference pass 3: 0",
"00:11 lens reference pass 4: 0",
"00:12 lens reference pass 5: 0",
"00:14 at rest: accelerometer low-passed p2p x 266 y 149 (rms 120 56) over 179 samples",
"00:15 +X: accelerometer low-passed p2p x 1753 y 681 (rms 753 339, raw p2p 3691 2019, 194 sampl",
"00:16 -X: accelerometer low-passed p2p x 2190 y 882 (rms 868 381, raw p2p 4531 2450, 196 sampl",
"00:18 +Y: accelerometer low-passed p2p x 986 y 1242 (rms 334 376, raw p2p 2820 2520, 200 sampl",
"00:19 -Y: accelerometer low-passed p2p x 523 y 1409 (rms 330 351, raw p2p 2693 2346, 201 sampl"
],
"phases": [
"rail up, the liveness probe",
"the lens hall reference",
"the lens finds its reference on the hall sensor: pass 1 of 5",
"the lens finds its reference on the hall sensor: pass 2 of 5",
"the lens finds its reference on the hall sensor: pass 3 of 5",
"the lens finds its reference on the hall sensor: pass 4 of 5",
"the lens finds its reference on the hall sensor: pass 5 of 5",
"starting the controller in loopback posture",
"jog +X",
"jog -X",
"jog +Y",
"jog -Y"
],
"result": {
"moves": {
"+X": {
"crash_event": false,
"p2p_lp_x": 1753,
"p2p_lp_y": 681,
"p2p_x": 3691,
"p2p_y": 2019,
"rms_x": 753.0,
"rms_y": 339.0,
"samples": 194,
"witnessed": true
},
"+Y": {
"crash_event": false,
"p2p_lp_x": 986,
"p2p_lp_y": 1242,
"p2p_x": 2820,
"p2p_y": 2520,
"rms_x": 334.0,
"rms_y": 376.0,
"samples": 200,
"witnessed": true
},
"-X": {
"crash_event": false,
"p2p_lp_x": 2190,
"p2p_lp_y": 882,
"p2p_x": 4531,
"p2p_y": 2450,
"rms_x": 868.0,
"rms_y": 381.0,
"samples": 196,
"witnessed": true
},
"-Y": {
"crash_event": false,
"p2p_lp_x": 523,
"p2p_lp_y": 1409,
"p2p_x": 2693,
"p2p_y": 2346,
"rms_x": 330.0,
"rms_y": 351.0,
"samples": 201,
"witnessed": true
}
},
"probe": "head accel p2p x=2357 y=2138 (moving>=800 dead<=250)",
"rail": "up",
"rest": {
"p2p_lp_x": 266,
"p2p_lp_y": 149,
"p2p_x": 504,
"p2p_y": 437,
"rms_x": 120.0,
"rms_y": 56.0,
"samples": 179
},
"z_passes": [
0,
0,
0,
0,
0
],
"z_referenced": true
},
"started": true
},
"fingerprint": "ee1c2d205e408a690e709f57331876b2bf7d5165c2ac6edac9cddf244ba26b92",
"image": "20260928153805 (dev)",
"log": [
"16:32:45 start setup.check-motion (auto, takeover) in campaign c-20260928162331-3969",
"16:32:46 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:32:46 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"16:32:46 queued by the unattended queue opened 2026-09-28T16:23:31Z",
"16:32:46 baseline: pre: clean",
"16:32:46 NOTICE: The head moves 50 mm each way on X and on Y. Keep the bed clear.",
"16:32:46 POST /wiz/motion/start -> 200 {'started': True, 'id': 'motion'}",
"16:32:46 motion: stopping the motion controller",
"16:32:47 motion: rail up, the liveness probe",
"16:32:53 motion: the lens hall reference",
"16:32:54 motion: the lens finds its reference on the hall sensor: pass 1 of 5",
"16:32:55 motion: the lens finds its reference on the hall sensor: pass 2 of 5",
"16:32:56 motion: the lens finds its reference on the hall sensor: pass 3 of 5",
"16:32:57 motion: the lens finds its reference on the hall sensor: pass 4 of 5",
"16:32:58 motion: the lens finds its reference on the hall sensor: pass 5 of 5",
"16:32:59 motion: starting the controller in loopback posture",
"16:32:59 prompt jogs (continue): The head moves 50 mm each way on X, then on Y, at 3000 mm/min. Keep the bed clear and the lid closed.",
"16:33:00 motion: jog +X",
"16:33:02 motion: jog -X",
"16:33:03 motion: jog +Y",
"16:33:04 motion: jog -Y",
"16:33:06 motion: probe 'head accel p2p x=2357 y=2138 (moving>=800 dead<=250)', passes [0, 0, 0, 0, 0], rest {'samples': 179, 'p2p_lp_x': 266, 'p2p_lp_y': 149, 'p2p_x': 504, 'p2p_y': 437, 'rms_x': 120.0, 'rms_y': 56.0}, moves {'+X': (1753, 681), '-X': (2190, 882), '+Y': (986, 1242), '-Y': (523, 1409)}",
"16:33:06 baseline: post: clean",
"16:33:06 result PASS"
],
"manifest_sha": "faf9563c750bb8bd4bfc8778b6af053cddb63fa335ab946caf2f71631ede740f",
"message": "",
"result": "PASS",
"test": "setup.check-motion",
"ts": "2026-09-28T16:33:06Z"
},
"requires": [
"forgectrl.auth",
"motion.pacing"
],
"satisfied": true,
"source_sha": "aec5c47ee0a7ba60fd7c58bd70b22a997c3592958aed5758b4d17a2bfdd5adaf",
"subsystem": "setup",
"title": "The motion check proves the rail, the lens reference, and the jogs"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/wizdark.*"
],
[
"forgectrl",
"src/wizcalc.*"
],
[
"forgectrl",
"src/wiz.*"
],
[
"forgectrl",
"src/setup.*"
],
[
"forgectrl",
"src/main.c"
],
[
"forgectrl",
"src/ui/wizard.*"
],
[
"forgectrl",
"src/diag.c"
]
],
"fingerprint": "eb6076be27613ca65c6b71772b24d38d4a74cb215c40fd434544c737ed416db3",
"hardware": "takeover",
"id": "setup.check-flow-verify",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928162331-3969",
"duration_s": 184,
"evidence": {
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T16:23:31Z"
},
"elapsed_s": 183.9,
"error": "",
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"log": [],
"phases": [
"the flow check: settling the loop",
"settling before trial 1/1 (pump on)",
"trial 1/1: heater 40% for 50 s (pump on)",
"settling before trial 1/1 (pump off)",
"trial 1/1: heater 40% for 50 s (pump off)"
],
"result": {
"flow_dt": 9.8,
"flow_rise": 10.3,
"margin_flow": 4.2,
"margin_noflow": 2.4,
"noflow_dt": 12.1,
"noflow_rise": 16.9,
"pass": true,
"thin_margin": false,
"threshold": 14.5
},
"started": true
},
"fingerprint": "eb6076be27613ca65c6b71772b24d38d4a74cb215c40fd434544c737ed416db3",
"image": "20260928153805 (dev)",
"log": [
"16:37:19 start setup.check-flow-verify (auto, takeover) in campaign c-20260928162331-3969",
"16:37:20 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:37:20 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"16:37:20 queued by the unattended queue opened 2026-09-28T16:23:31Z",
"16:37:20 baseline: pre: clean",
"16:37:20 POST /wiz/cooling.flow-verify/start -> 200 {'started': True, 'id': 'cooling.flow-verify'}",
"16:37:20 cooling.flow-verify: the flow check: settling the loop",
"16:37:21 cooling.flow-verify: settling before trial 1/1 (pump on)",
"16:37:52 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:38:00 cooling.flow-verify: trial 1/1: heater 40% for 50 s (pump on)",
"16:38:22 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:38:53 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:38:53 cooling.flow-verify: settling before trial 1/1 (pump off)",
"16:39:23 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:39:30 cooling.flow-verify: trial 1/1: heater 40% for 50 s (pump off)",
"16:39:54 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:40:24 flow check: threshold 14.5, flow 10.3, no-flow 16.9, thin False",
"16:40:24 baseline: post: clean",
"16:40:24 result PASS"
],
"manifest_sha": "faf9563c750bb8bd4bfc8778b6af053cddb63fa335ab946caf2f71631ede740f",
"message": "",
"result": "PASS",
"test": "setup.check-flow-verify",
"ts": "2026-09-28T16:40:24Z"
},
"requires": [
"forgectrl.auth",
"cooling.aa-offset-calibrate",
"cooling.flow-verify"
],
"satisfied": true,
"source_sha": "0f0564b51d844afc42e65182abcbce9ffc63c2385eac7eb9b2a668dad013d3af",
"subsystem": "setup",
"title": "The flow check runs as a setup check"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/wizdark.*"
],
[
"forgectrl",
"src/wizcalc.*"
],
[
"forgectrl",
"src/wiz.*"
],
[
"forgectrl",
"src/setup.*"
],
[
"forgectrl",
"src/main.c"
],
[
"forgectrl",
"src/ui/wizard.*"
],
[
"forgectrl",
"src/super.c"
],
[
"python3-gfhardware",
"gfhardware/machine.py"
],
[
"python3-gfhardware",
"forgefirm-app/gfcloud.py"
],
[
"python3-gfhardware",
"forgefirm-app/ffmachine.py"
]
],
"fingerprint": "17a5462785b671c2481912ccc442b22a1a4b9a6a8e473e4e46b00262a6160641",
"hardware": "takeover",
"id": "setup.cloud-header-capture",
"inherited": true,
"kind": "operator",
"record": {
"answers": [],
"campaign": "c-20260928183105-64ee",
"duration_s": 63,
"evidence": {
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "attended",
"ts": "2026-09-28T18:51:04Z"
},
"elapsed_s": 62.4,
"error": "",
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"kept": [
"AAfc",
"AAid",
"AAin",
"AAix",
"AArd",
"AArn",
"AArx",
"AAsn",
"AAsx",
"AAwd",
"AAwn",
"AAwx",
"CFrh",
"CMin",
"CMix",
"CMrn",
"CMrx",
"CMts",
"CMwn",
"CMwx",
"EFid",
"EFin",
"EFix",
"EFrd",
"EFrn",
"EFrx",
"EFwd",
"EFwn",
"EFwx",
"HAai",
"HAar",
"HAsi",
"HAsr",
"HAxi",
"HAxr",
"HAyi",
"HAyr",
"HAzi",
"HAzr",
"IFid"
],
"log": [
"00:58 factory envelope captured: 134 tags, 57 calibration-bearing"
],
"mode": {
"detail": "already in grbl mode",
"found": "grbl",
"needs": "grbl",
"ok": true,
"switched": false
},
"phases": [
"starting the cloud client",
"waiting for the print's header from the service",
"the cloud client cancels the print"
],
"result": {
"calibration_tags": {
"AAfc": 3632880242,
"AAid": 204,
"AAin": 0,
"AAix": 0,
"AArd": 1023,
"AArn": 0,
"AArx": 64500,
"AAsn": 0,
"AAsx": 0,
"AAwd": 1023,
"AAwn": 0,
"AAwx": 64500,
"CFrh": 1,
"CMin": 10000,
"CMix": 50000,
"CMrn": 5000,
"CMrx": 33000,
"CMts": 0,
"CMwn": 7000,
"CMwx": 31000,
"EFid": 0,
"EFin": 0,
"EFix": 0,
"EFrd": 65535,
"EFrn": 0,
"EFrx": 0,
"EFwd": 65535,
"EFwn": 0,
"EFwx": 0,
"HAai": 0,
"HAar": 0,
"HAsi": 2,
"HAsr": 4,
"HAxi": 0,
"HAxr": 132,
"HAyi": 0,
"HAyr": 112,
"HAzi": 0,
"HAzr": 0,
"IFid": 0,
"IFin": 0,
"IFix": 0,
"IFrd": 43278,
"IFrn": 0,
"IFrx": 0,
"IFwd": 43278,
"IFwn": 0,
"IFwx": 0,
"XSdm": 1,
"XShc": 33,
"XSmm": 8,
"XSrc": 135,
"YSdm": 1,
"YShc": 5,
"YSmm": 8,
"YSrc": 22,
"ZSmd": 0
},
"captured": "2026-09-28T18:53:22Z",
"job_id": 1589761400,
"limits": {
"air_assist_min_rpm": 116,
"coolant_max_c": 33.0,
"coolant_min_c": 5.0
},
"machine": {
"cool_accel_x_alert": {
"default": 132.0,
"local": ""
},
"cool_accel_y_alert": {
"default": 112.0,
"local": ""
},
"cool_fire_q1_alert": {
"default": 275.0,
"local": ""
},
"cool_fire_q2_alert": {
"default": 374.0,
"local": ""
},
"cool_flow_rise": {
"default": 14.4,
"local": "14.5"
},
"cool_purge_min_current": {
"default": 300.0,
"local": "345"
},
"cool_tach_air_assist_min_rpm": {
"default": 6000.0,
"local": "6093"
},
"cool_tach_exhaust_min_rpm": {
"default": 6400.0,
"local": "6416"
},
"cool_tach_intake_min_rpm": {
"default": 2290.0,
"local": "2277"
},
"cool_temp_max": {
"default": 33.0,
"local": ""
},
"cool_temp_min": {
"default": 5.0,
"local": ""
}
},
"tag_count": 134
},
"settings_before": {
"cloud_enabled": "1",
"controller_mode": "grbl",
"homing_mode": "manual"
},
"started": true
},
"fingerprint": "17a5462785b671c2481912ccc442b22a1a4b9a6a8e473e4e46b00262a6160641",
"image": "20260928182434 (dev)",
"log": [
"18:52:24 start setup.cloud-header-capture (operator, takeover) in campaign c-20260928183105-64ee",
"18:52:24 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"18:52:24 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"18:52:24 queued by the attended queue opened 2026-09-28T18:51:04Z",
"18:52:24 baseline: pre: clean",
"18:52:24 mode: test needs grbl - already in grbl mode",
"18:52:24 NOTICE: Print any small design from the Glowforge app once it shows the machine online. Do not press the machine's button.",
"18:52:24 POST /wiz/cloud.header/start -> 200 {'started': True, 'id': 'cloud.header'}",
"18:52:25 cloud.header: starting the cloud client",
"18:52:30 prompt print (continue): The machine is in cloud mode. In the Glowforge app, place any small design on the bed image and press Print. Do not press the machine's button: the wizard takes the print's header and cancels it.",
"18:52:31 cloud.header: waiting for the print's header from the service",
"18:52:55 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"18:53:23 cloud.header: the cloud client cancels the print",
"18:53:27 header: 134 tags, 57 kept; job 1589761400",
"18:53:27 restore cloud_enabled='1' -> 200",
"18:53:27 restore homing_mode='manual' -> 200",
"18:53:27 restore controller_mode='grbl' -> 200",
"18:53:27 baseline: post: clean",
"18:53:27 result PASS"
],
"manifest_sha": "84a155bfc701e865ae73f9818bc38c2d005324ab5ba0ed44b668ec8896179947",
"message": "",
"result": "PASS",
"test": "setup.cloud-header-capture",
"ts": "2026-09-28T18:53:27Z"
},
"requires": [
"forgectrl.auth",
"cloud.mode-switch"
],
"satisfied": true,
"source_sha": "be7ee162fe348c3c50f8082216b49a12b79b77a466d07455369f17018c4b0660",
"subsystem": "setup",
"title": "The cloud header check takes one print's envelope"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/wizlive.*"
],
[
"forgectrl",
"src/wizrun.h"
],
[
"forgectrl",
"src/lens.*"
],
[
"forgectrl",
"src/sheet.*"
],
[
"forgectrl",
"src/font_hershey.*"
],
[
"forgectrl",
"src/jobstream.*"
],
[
"forgectrl",
"src/jobrun.*"
],
[
"forgectrl",
"src/lease.*"
],
[
"forgectrl",
"src/curverec.*"
],
[
"forgectrl",
"src/wizdark.*"
],
[
"forgectrl",
"src/wiz.*"
],
[
"forgectrl",
"src/setup.*"
],
[
"forgectrl",
"src/main.c"
],
[
"forgectrl",
"src/ui/wizard.*"
],
[
"forgectrl",
"src/super.c"
],
[
"forgectrl",
"src/status.c"
],
[
"forgectrl",
"src/cool.c"
],
[
"forgectrl",
"src/accel.*"
],
[
"forgectrl",
"src/wizcalc.*"
],
[
"grblhal-glowforge",
"src/glowforge_laser.c"
],
[
"grblhal-glowforge",
"src/glowforge_status.c"
],
[
"grblhal-glowforge",
"src/glowforge_homing.*"
],
[
"grblhal-glowforge",
"src/glowforge_io.*"
]
],
"fingerprint": "e014b644781d127b449898f52648638d08ceb5485cd5b98916fc0995adcd27fc",
"hardware": "takeover",
"id": "setup.sheet",
"inherited": true,
"kind": "live",
"record": {
"answers": [],
"campaign": "c-20260928183105-64ee",
"duration_s": 730,
"evidence": {
"actions": [
{
"by": "operator",
"channel": "button",
"state": "presence",
"took_s": 6.33,
"ts": "2026-09-28T18:54:16Z"
},
{
"by": "fixture",
"channel": "button",
"state": "arm",
"ts": "2026-09-28T18:54:34Z"
},
{
"by": "fixture",
"channel": "button",
"state": "arm",
"ts": "2026-09-28T18:56:37Z"
},
{
"by": "fixture",
"channel": "button",
"state": "arm",
"ts": "2026-09-28T18:57:45Z"
},
{
"by": "fixture",
"channel": "button",
"state": "arm",
"ts": "2026-09-28T18:59:32Z"
},
{
"by": "fixture",
"channel": "button",
"state": "arm",
"ts": "2026-09-28T19:01:58Z"
},
{
"by": "fixture",
"channel": "button",
"state": "arm",
"ts": "2026-09-28T19:03:50Z"
}
],
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "attended",
"ts": "2026-09-28T18:51:04Z"
},
"cards": {
"cooling.flow-load": {
"elapsed_s": 217.2,
"emission": {
"hv_max": 1023,
"laser_on_samples": 213,
"lit_s": 90.5457904509999,
"thermopile_delta": 1006
},
"error": "",
"log": [
"00:02 lens reference pass 1: 0",
"00:03 lens reference pass 2: 0",
"01:05 the coolant loop is quiet after 60 s (downstream 22.23 C)",
"03:37 the downstream peak has passed (2.75 C over the baseline, 49 s dark): the tail ends here",
"03:37 streamed 220 lines; tube current peak 1023, LASER_ON samples 213, thermopile +1006",
"03:37 lit 64 s, dose 36170 raw-s, rise 1.99 C at 95 s: k 5.51e-05 C per raw-s"
],
"phases": [
"the tube is dark: the coolant sensors follow the heat, 63 s more",
"the tube is dark: the coolant sensors follow the heat, 62 s more",
"the tube is dark: the coolant sensors follow the heat, 61 s more",
"the tube is dark: the coolant sensors follow the heat, 60 s more",
"the tube is dark: the coolant sensors follow the heat, 59 s more",
"the tube is dark: the coolant sensors follow the heat, 58 s more",
"the tube is dark: the coolant sensors follow the heat, 57 s more",
"the tube is dark: the coolant sensors follow the heat, 56 s more",
"the tube is dark: the coolant sensors follow the heat, 55 s more",
"the tube is dark: the coolant sensors follow the heat, 54 s more",
"the tube is dark: the coolant sensors follow the heat, 53 s more",
"the tube is dark: the coolant sensors follow the heat, 52 s more"
],
"preview_bytes": 3258,
"program_lines": 217,
"result": {
"base_c": 22.61235294117647,
"dose_raw_s": 36169.719999999965,
"emission": {
"hv_max": 1023,
"laser_on_samples": 213,
"lit_s": 90.5457904509999,
"thermopile_delta": 1006
},
"hv_mean": 562.4502487562189,
"k_cw": 7.158341354166263e-05,
"k_density": 5.511922842708023e-05,
"lag_s": 80.0,
"lit_s": 64.28,
"peak_c": 1.9936470588235302,
"summary": "The tube was lit for 64 s and warmed the coolant by 1.99 C, peaking 95 s after the fire began. That is the tube's own share of a flow check's rise on this machine. It is written, and the flow check allows for it from now on.",
"t_peak_s": 95.0,
"up_base_c": 22.85058823529412,
"z_passes": [
0,
0
]
},
"started": true
},
"laser.corner": {
"elapsed_s": 51.7,
"emission": {
"hv_max": 1023,
"laser_on_samples": 138,
"lit_s": 30.988956764000022,
"thermopile_delta": 753
},
"error": "",
"log": [
"00:03 lens reference pass 1: 0",
"00:04 lens reference pass 2: 0",
"00:30 corner gamma 1.00: the next pattern",
"00:35 corner gamma 1.25: the next pattern",
"00:37 corner gamma 1.50: the next pattern",
"00:40 corner gamma 1.75: the next pattern",
"00:43 corner gamma 2.00: the next pattern",
"00:51 streamed 468 lines; tube current peak 1023, LASER_ON samples 138, thermopile +753",
"00:51 corner rolloff gamma 1.50"
],
"phases": [
"burning: the tube is between passes",
"burning: 0 s lit",
"burning: 1 s lit",
"burning: the tube is between passes",
"burning: 1 s lit",
"burning: the tube is between passes",
"burning: 0 s lit",
"burning: 1 s lit",
"burning: the tube is between passes",
"burning: 1 s lit",
"burning: the tube is between passes",
"the tube is dark: the pulse engine plays the rest"
],
"preview_bytes": 6391,
"program_lines": 465,
"result": {
"emission": {
"hv_max": 1023,
"laser_on_samples": 138,
"lit_s": 30.988956764000022,
"thermopile_delta": 753
},
"gamma": 1.5,
"summary": "Pattern 1.50 has the most even corners: the corner rolloff is set to 1.50. Under velocity-scaled power the machine eases the power into every corner by that exponent, so corners burn like the straights.",
"z_passes": [
0,
0
]
},
"started": true
},
"laser.dose-curve": {
"elapsed_s": 146.5,
"emission": {
"hv_max": 1023,
"laser_on_samples": 255,
"lit_s": 110.94573579500002,
"thermopile_delta": 2273
},
"error": "",
"log": [
"00:02 lens reference pass 1: 0",
"00:03 lens reference pass 2: 0",
"00:26 the floor and the dose curve are off from here",
"02:25 streamed 391 lines; tube current peak 1023, LASER_ON samples 255, thermopile +2273",
"02:25 dose curve 10:0.20,20:3.13,30:11.91,45:30.85,60:41.96,80:54.92,100:100.00"
],
"phases": [
"the tube is dark: the fit needs the dark tail, 11 s more",
"the tube is dark: the fit needs the dark tail, 10 s more",
"the tube is dark: the fit needs the dark tail, 9 s more",
"the tube is dark: the fit needs the dark tail, 8 s more",
"the tube is dark: the fit needs the dark tail, 6 s more",
"the tube is dark: the fit needs the dark tail, 5 s more",
"the tube is dark: the fit needs the dark tail, 4 s more",
"the tube is dark: the fit needs the dark tail, 3 s more",
"the tube is dark: the fit needs the dark tail, 2 s more",
"the tube is dark: the fit needs the dark tail, 1 s more",
"the tube is dark: the fit needs the dark tail, 0 s more",
"the tube is dark: the pulse engine plays the rest"
],
"preview_bytes": 5722,
"program_lines": 389,
"result": {
"curve": "10:0.20,20:3.13,30:11.91,45:30.85,60:41.96,80:54.92,100:100.00",
"emission": {
"hv_max": 1023,
"laser_on_samples": 255,
"lit_s": 110.94573579500002,
"thermopile_delta": 2273
},
"points": [
{
"density": 10.0,
"light": 0.19913034557192308
},
{
"density": 20.0,
"light": 3.133343866554108
},
{
"density": 30.0,
"light": 11.90652008843376
},
{
"density": 45.0,
"light": 30.85270331032583
},
{
"density": 60.0,
"light": 41.96203397904551
},
{
"density": 80.0,
"light": 54.91520404843594
},
{
"density": 100.0,
"light": 100.0
}
],
"summary": "The curve rose rung by rung and is written. It maps the density a job asks for to the light the tube gives: 10 percent density gives 0.2 percent of the light, 45 gives 31, and 100 gives 100. The chart shows the fit.",
"z_passes": [
0,
0
]
},
"started": true
},
"laser.floor": {
"elapsed_s": 106.4,
"emission": {
"hv_max": 1023,
"laser_on_samples": 149,
"lit_s": 90.9621884359999,
"thermopile_delta": 755
},
"error": "",
"log": [
"00:02 lens reference pass 1: 0",
"00:03 lens reference pass 2: 0",
"00:26 the floor and the dose curve are off from here",
"01:45 streamed 421 lines; tube current peak 1023, LASER_ON samples 149, thermopile +755",
"01:46 the faintest continuous rung is 8 percent: the floor is 10"
],
"phases": [
"burning: 2 s lit",
"burning: 3 s lit",
"burning: 5 s lit",
"burning: the tube is between passes",
"burning: 1 s lit",
"burning: 2 s lit",
"burning: 3 s lit",
"burning: 4 s lit",
"burning: 5 s lit",
"the tube is dark: the samples run on, 2 s more",
"the tube is dark: the samples run on, 1 s more",
"the tube is dark: the pulse engine plays the rest"
],
"preview_bytes": 5760,
"program_lines": 418,
"result": {
"emission": {
"hv_max": 1023,
"laser_on_samples": 149,
"lit_s": 90.9621884359999,
"thermopile_delta": 755
},
"faintest_density": 8.0,
"floor_density": 10.0,
"summary": "The faintest rung with a continuous line is 8 percent density. The laser floor is set at 10 percent, two above it: no job asks the tube for less, so the lightest engraving still marks this wood.",
"z_passes": [
0,
0
]
},
"started": true
},
"laser.focus": {
"elapsed_s": 94.0,
"emission": {
"hv_max": 1023,
"laser_on_samples": 233,
"lit_s": 47.345336135000025,
"thermopile_delta": 1320
},
"error": "",
"log": [
"00:02 lens reference pass 1: 0",
"00:03 lens reference pass 2: 0",
"00:17 bottom ring 1-15 (x100): 60 189 61 200 89 155 54 201 93 167 68 158 46 193 47",
"00:17 bottom ring 16-16 (x100): 49",
"00:17 the bottom stop: the ring died 16 half-steps below the edge",
"00:24 top ring 1-15 (x100): 62 177 31 179 42 182 39 154 49 187 36 98 56 182 39",
"00:24 top ring 16-22 (x100): 183 46 179 41 196 37 74",
"00:24 the top stop: the ring died 22 half-steps above the edge",
"00:29 the lens window: 14 half-steps below the reference, 20 above (the stops found), written ",
"01:32 streamed 297 lines; tube current peak 1023, LASER_ON samples 233, thermopile +1320",
"01:33 line 11 on 0.125 in: -11 half-steps from the hall edge, so the focus at the edge is 0.27"
],
"phases": [
"burning: 0 s lit",
"burning: 1 s lit",
"burning: the tube is between passes",
"burning: 1 s lit",
"burning: 2 s lit",
"burning: 0 s lit",
"burning: 1 s lit",
"burning: the tube is between passes",
"burning: 1 s lit",
"burning: 2 s lit",
"burning: the tube is between passes",
"the tube is dark: the pulse engine plays the rest"
],
"preview_bytes": 3966,
"program_lines": 294,
"result": {
"edge_z_mm": 6.939544832306639,
"emission": {
"hv_max": 1023,
"laser_on_samples": 233,
"lit_s": 47.345336135000025,
"thermopile_delta": 1320
},
"focus_range_mm": {
"max": 13.784171800136892,
"min": 2.148305954825462
},
"ladder_z": [
10.194626967830253,
9.167932922655716,
8.141238877481177,
7.114544832306639,
6.087850787132101,
5.061156741957563,
3.6922313483915126,
2.6655373032169747,
1.6388432580424368,
0.6121492128678989,
-0.41454483230663897,
-1.4412388774811773
],
"max_height_mm": 13.784171800136892,
"pick": 11.0,
"pick_half_steps": -11.0,
"picked_lines": [
11,
11
],
"steps_per_mm": 2.922,
"stops": {
"above": 20,
"below": 14,
"contact_above": 22,
"contact_below": 16,
"found": true,
"why": ""
},
"summary": "Line 11 on 0.125 in: with the lens on its hall reference the focus is 0.273 in above the tray. A home puts the lens there, sets Z to that height, and parks the focus at the park height; Z counts the focus height above the bed. The stops were found 14 half-steps below the reference and 20 above, so the lens reaches 0.085 in to 0.543 in. Every later card runs at the focus for this sheet.",
"thickness_mm": 3.175,
"window": {
"above": 20,
"below": 14,
"reach_max": 10.194626967830253,
"reach_min": -1.4412388774811773
},
"z_passes": [
0,
0
]
},
"started": true
},
"sheet.frame": {
"elapsed_s": 96.0,
"emission": {
"hv_max": 1023,
"laser_on_samples": 152,
"lit_s": 77.51903460900007,
"thermopile_delta": 954
},
"error": "",
"log": [
"00:02 lens reference pass 1: 0",
"00:03 lens reference pass 2: 0",
"01:34 streamed 1479 lines; tube current peak 1023, LASER_ON samples 152, thermopile +954"
],
"phases": [
"burning: 0 s lit",
"burning: the tube is between passes",
"burning: 0 s lit",
"burning: the tube is between passes",
"burning: 0 s lit",
"burning: the tube is between passes",
"burning: 0 s lit",
"burning: the tube is between passes",
"burning: 0 s lit",
"burning: the tube is between passes",
"the tube is dark: the samples run on, 1 s more",
"the tube is dark: the pulse engine plays the rest"
],
"preview_bytes": 21499,
"program_lines": 1476,
"result": {
"emission": {
"hv_max": 1023,
"laser_on_samples": 152,
"lit_s": 77.51903460900007,
"thermopile_delta": 954
},
"mark_feed": 3000,
"mark_s": 400,
"started": "2026-09-28 18:54Z",
"summary": "The frame and the header are on the sheet. The mark dose is S400 at 3000 mm/min; every card's box and labels burn at it. All three witnesses saw the beam: the tube current, the kernel's LASER_ON samples, and the head thermopile.",
"z_passes": [
0,
0
]
},
"started": true
},
"sheet.place": {
"elapsed_s": 10.1,
"error": "",
"log": [
"00:02 lens reference pass 1: 0",
"00:03 lens reference pass 2: 0",
"00:10 origin at counters 0, 0 (full sheet, 0.125 in)"
],
"phases": [
"stopping the motion controller",
"the lens finds its reference on the hall sensor: pass 1 of 2",
"the lens finds its reference on the hall sensor: pass 2 of 2",
"the cooling engine takes the controller's report: 0 s (20 at most)",
"placing the sheet"
],
"result": {
"alone": false,
"origin_x": 0,
"origin_y": 0,
"origin_z": 0,
"steps_per_mm": {
"x": 213.33299,
"y": 213.33299,
"z": 2.922
},
"summary": "The origin is set at the head's position. The full sheet, 0.125 in thick. Every card is drawn from this point: do not move the sheet until the last card is done.",
"thickness_mm": 3.175,
"z_passes": [
0,
0
],
"z_referenced": true
},
"started": true
}
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"focus_window": {
"ladder_z": [
10.194626967830253,
9.167932922655716,
8.141238877481177,
7.114544832306639,
6.087850787132101,
5.061156741957563,
3.6922313483915126,
2.6655373032169747,
1.6388432580424368,
0.6121492128678989,
-0.41454483230663897,
-1.4412388774811773
],
"preview_bytes": 3966,
"program_lines": 294,
"program_z_after": {
"reach": [
2.15,
13.78
],
"stops_found": true,
"z": [
6.94,
13.78,
12.76,
11.73,
10.7,
9.68,
8.65,
7.28,
6.26,
5.23,
4.2,
3.18,
2.15,
6.94
]
},
"program_z_before": {
"reach": [
-0.07,
7.46
],
"stops_found": false,
"z": [
3.35,
7.46,
6.77,
6.09,
5.4,
4.72,
4.03,
3.35,
2.67,
1.98,
1.3,
0.61,
-0.07,
3.35
]
},
"settings": {
"lens_hall_edge_z_mm": "6.94",
"lens_stop_above_steps": "20",
"lens_stop_below_steps": "14"
},
"stops": {
"above": 20,
"below": 14,
"contact_above": 22,
"contact_below": 16,
"found": true,
"why": ""
},
"window": {
"above": 20,
"below": 14,
"reach_max": 10.194626967830253,
"reach_min": -1.4412388774811773
}
},
"lens_fresh": {
"above": 12,
"below": 10,
"edge_z": 3.35,
"reach_max": 7.46,
"reach_min": -0.07,
"stops_found": false,
"tray": "in",
"tray_offset_mm": 34.29
},
"mode": {
"detail": "already in grbl mode",
"found": "grbl",
"needs": "grbl",
"ok": true,
"switched": false
},
"operator": {
"ack_live": true,
"ts": "2026-09-28T18:54:10Z"
},
"program_z": {
"cooling.flow-load": {
"reach": [
2.15,
13.78
],
"stops_found": true,
"z": [
6.94
]
},
"laser.corner": {
"reach": [
2.15,
13.78
],
"stops_found": true,
"z": [
6.94
]
},
"laser.dose-curve": {
"reach": [
2.15,
13.78
],
"stops_found": true,
"z": [
6.94
]
},
"laser.floor": {
"reach": [
2.15,
13.78
],
"stops_found": true,
"z": [
6.94
]
},
"laser.focus": {
"reach": [
2.15,
13.78
],
"stops_found": true,
"z": [
6.94,
13.78,
12.76,
11.73,
10.7,
9.68,
8.65,
7.28,
6.26,
5.23,
4.2,
3.18,
2.15,
6.94
]
},
"sheet.frame": {
"reach": [
-0.07,
7.46
],
"stops_found": false,
"z": [
3.35
]
}
},
"settings_before": {
"cool_laser_heat_cw": "6.533e-05",
"cool_laser_heat_density": "5.03e-05",
"laser_corner_gamma": "1.50",
"laser_dose_curve": "10:0.62,20:2.79,30:8.46,45:24.90,60:42.02,80:52.53,100:100.00",
"laser_floor_density": "14",
"lens_hall_edge_z_mm": "4.51",
"lens_stop_above_steps": "20",
"lens_stop_below_steps": "14"
},
"thickness_answer": "0.125"
},
"fingerprint": "e014b644781d127b449898f52648638d08ceb5485cd5b98916fc0995adcd27fc",
"image": "20260928182434 (dev)",
"log": [
"18:54:09 start setup.sheet (live, takeover) in campaign c-20260928183105-64ee",
"18:54:10 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"18:54:10 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"18:54:10 queued by the attended queue opened 2026-09-28T18:51:04Z",
"18:54:10 baseline: pre: clean",
"18:54:10 mode: test needs grbl - already in grbl mode",
"18:54:10 NOTICE: The sheet: the placement, then the frame and the five cards burn after a press each. The bench presses when the button lights. Then press the button on the machine to start.",
"18:54:10 READY: waiting for the operator's press on the machine (the bench then does every press in this test)",
"18:54:16 READY: operator present (press after 6.3 s); the bench takes the presses",
"18:54:16 POST /wiz/sheet.place/start -> 200 {'started': True, 'id': 'sheet.place'}",
"18:54:16 sheet.place: stopping the motion controller",
"18:54:17 sheet.place: the lens finds its reference on the hall sensor: pass 1 of 2",
"18:54:18 sheet.place: the lens finds its reference on the hall sensor: pass 2 of 2",
"18:54:19 sheet.place: the cooling engine takes the controller's report: 0 s (20 at most)",
"18:54:21 sheet.place: placing the sheet",
"18:54:21 prompt place (jog): The head should be at the back-left, where the machine normally homes; the arrows move it (lid closed). Then open the lid, push the sheet as far left as it goes with its top edge on the top of the cut area, close the lid, and set the origin.",
"18:54:23 prompt place (jog): The head should be at the back-left, where the machine normally homes; the arrows move it (lid closed). Then open the lid, push the sheet as far left as it goes with its top edge on the top of the cut area, close the lid, and set the origin.",
"18:54:24 prompt place (jog): The head should be at the back-left, where the machine normally homes; the arrows move it (lid closed). Then open the lid, push the sheet as far left as it goes with its top edge on the top of the cut area, close the lid, and set the origin.",
"18:54:25 prompt sheet-kind (choice): Is this the full setup sheet (8 x 6 in or more), or a smaller piece for one card?",
"18:54:26 prompt thickness (number): The thickness of the sheet in inches.",
"18:54:27 placed: datum at 0, 0; steps per mm {'x': 213.33299, 'y': 213.33299, 'z': 2.922}",
"18:54:27 POST /wiz/sheet.frame/start -> 200 {'started': True, 'id': 'sheet.frame'}",
"18:54:27 sheet.frame: stopping the motion controller",
"18:54:28 sheet.frame: the lens finds its reference on the hall sensor",
"18:54:29 sheet.frame: the lens finds its reference on the hall sensor: pass 2 of 2",
"18:54:30 sheet.frame: starting the motion controller for the card: 0 s (60 at most)",
"18:54:31 sheet.frame: the cooling engine takes the controller's report: 0 s (20 at most)",
"18:54:32 prompt frame-arm (continue): The frame and the header burn now: 7.1 x 5.1 in at the mark dose. Eye protection on, exhaust on, lid closed. Continue, then press the machine's button when it lights white; this page says when.",
"18:54:33 sheet.frame: the program goes to the controller, the button lights at the arm",
"18:54:34 sheet.frame: the button is lit: press it now (0 s; the job waits 599 at most)",
"18:54:34 prompt press (wait): The button is lit white. Press it now: the laser fires after your press.",
"18:54:34 ARM press by the fixture, at the machine's own press prompt",
"18:54:35 sheet.frame: the button is lit: press it now (1 s; the job waits 599 at most)",
"18:54:36 sheet.frame: the button is lit: press it now (2 s; the job waits 599 at most)",
"18:54:37 sheet.frame: the button is lit: press it now (3 s; the job waits 599 at most)",
"18:54:38 sheet.frame: the button is lit: press it now (4 s; the job waits 599 at most)",
"18:54:39 sheet.frame: the button is lit: press it now (5 s; the job waits 599 at most)",
"18:54:40 sheet.frame: the button is lit: press it now (6 s; the job waits 599 at most)",
"18:54:41 sheet.frame: the button is lit: press it now (7 s; the job waits 599 at most)",
"18:54:41 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"18:54:42 sheet.frame: the button is lit: press it now (8 s; the job waits 599 at most)",
"18:54:43 sheet.frame: burning: 1 s lit",
"18:54:44 sheet.frame: burning: 2 s lit",
"18:54:45 sheet.frame: burning: 3 s lit",
"18:54:46 sheet.frame: burning: 4 s lit",
"18:54:47 sheet.frame: burning: 5 s lit",
"18:54:48 sheet.frame: burning: 6 s lit",
"18:54:49 sheet.frame: burning: 7 s lit",
"18:54:50 sheet.frame: burning: 8 s lit",
"18:54:51 sheet.frame: burning: 9 s lit",
"18:54:52 sheet.frame: burning: 10 s lit",
"18:54:53 sheet.frame: burning: 11 s lit",
"18:54:54 sheet.frame: burning: 12 s lit",
"18:54:55 sheet.frame: burning: the tube is between passes",
"18:54:57 sheet.frame: burning: 0 s lit",
"18:54:58 sheet.frame: burning: the tube is between passes",
"18:55:00 sheet.frame: burning: 0 s lit",
"18:55:03 sheet.frame: burning: the tube is between passes",
"18:55:04 sheet.frame: burning: 0 s lit",
"18:55:05 sheet.frame: burning: the tube is between passes",
"18:55:06 sheet.frame: burning: 0 s lit",
"18:55:11 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"18:55:18 sheet.frame: burning: the tube is between passes",
"18:55:23 sheet.frame: burning: 0 s lit",
"18:55:25 sheet.frame: burning: the tube is between passes",
"18:55:26 sheet.frame: burning: 0 s lit",
"18:55:28 sheet.frame: burning: the tube is between passes",
"18:55:30 sheet.frame: burning: 0 s lit",
"18:55:34 sheet.frame: burning: the tube is between passes",
"18:55:36 sheet.frame: burning: 0 s lit",
"18:55:37 sheet.frame: burning: the tube is between passes",
"18:55:42 sheet.frame: burning: 0 s lit",
"18:55:42 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"18:55:43 sheet.frame: burning: the tube is between passes",
"18:55:44 sheet.frame: burning: 0 s lit",
"18:55:46 sheet.frame: burning: the tube is between passes",
"18:55:48 sheet.frame: burning: 0 s lit",
"18:55:49 sheet.frame: burning: the tube is between passes",
"18:55:52 sheet.frame: burning: 0 s lit",
"18:55:59 sheet.frame: burning: the tube is between passes",
"18:56:01 sheet.frame: the tube is dark: the samples run on, 1 s more",
"18:56:02 sheet.frame: the tube is dark: the pulse engine plays the rest",
"18:56:02 prompt frame-ok (choice): Is the frame on the sheet, square, and visible? Look, but do not move the sheet: every card after this is placed from the same datum.",
"18:56:03 sheet.frame: {'mark_s': 400, 'mark_feed': 3000}, emission {'hv_max': 1023, 'laser_on_samples': 152, 'thermopile_delta': 954, 'lit_s': 77.51903460900007}",
"18:56:03 POST /wiz/laser.focus/start -> 200 {'started': True, 'id': 'laser.focus'}",
"18:56:03 laser.focus: stopping the motion controller",
"18:56:04 laser.focus: the lens finds its reference on the hall sensor",
"18:56:05 laser.focus: the lens finds its reference on the hall sensor: pass 1 of 2",
"18:56:06 laser.focus: the lens finds its reference on the hall sensor: pass 2 of 2",
"18:56:07 laser.focus: the fans stop before the listening: 0 s of 10",
"18:56:08 laser.focus: the fans stop before the listening: 1 s of 10",
"18:56:09 laser.focus: the fans stop before the listening: 2 s of 10",
"18:56:10 laser.focus: the fans stop before the listening: 3 s of 10",
"18:56:11 laser.focus: the fans stop before the listening: 4 s of 10",
"18:56:12 laser.focus: the fans stop before the listening: 5 s of 10",
"18:56:13 laser.focus: the fans stop before the listening: 6 s of 10",
"18:56:13 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"18:56:14 laser.focus: the fans stop before the listening: 7 s of 10",
"18:56:15 laser.focus: the fans stop before the listening: 8 s of 10",
"18:56:16 laser.focus: the fans stop before the listening: 9 s of 10",
"18:56:17 laser.focus: finding the bottom stop by the head accelerometer: 4 half-steps below the edge",
"18:56:18 laser.focus: finding the bottom stop by the head accelerometer: 9 half-steps below the edge",
"18:56:19 laser.focus: finding the bottom stop by the head accelerometer: 15 half-steps below the edge",
"18:56:20 laser.focus: finding the bottom stop by the head accelerometer: 16 half-steps below the edge",
"18:56:23 laser.focus: finding the top stop by the head accelerometer: 5 half-steps above the edge",
"18:56:24 laser.focus: finding the top stop by the head accelerometer: 11 half-steps above the edge",
"18:56:25 laser.focus: finding the top stop by the head accelerometer: 16 half-steps above the edge",
"18:56:26 laser.focus: finding the top stop by the head accelerometer: 22 half-steps above the edge",
"18:56:33 laser.focus: the cooling engine takes the controller's report: 0 s (20 at most)",
"18:56:35 prompt focus-arm (continue): The lens is on its hall reference. Its stops were found by the head accelerometer, 14 half-steps below the reference and 20 above, without a slip. Twelve 1.772 in lines burn heavy, the lens stepped from 0.269 in above the reference to 0.189 in below it. Lid closed. Continue, then press the button when it lights white;",
"18:56:36 laser.focus: the program goes to the controller, the button lights at the arm",
"18:56:37 laser.focus: the button is lit: press it now (0 s; the job waits 599 at most)",
"18:56:37 prompt press (wait): The button is lit white. Press it now: the laser fires after your press.",
"18:56:37 ARM press by the fixture, at the machine's own press prompt",
"18:56:38 laser.focus: the button is lit: press it now (1 s; the job waits 599 at most)",
"18:56:39 laser.focus: the button is lit: press it now (2 s; the job waits 599 at most)",
"18:56:40 laser.focus: the button is lit: press it now (3 s; the job waits 599 at most)",
"18:56:41 laser.focus: the button is lit: press it now (4 s; the job waits 599 at most)",
"18:56:42 laser.focus: the button is lit: press it now (5 s; the job waits 599 at most)",
"18:56:43 laser.focus: the button is lit: press it now (6 s; the job waits 599 at most)",
"18:56:43 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"18:56:44 laser.focus: the button is lit: press it now (7 s; the job waits 599 at most)",
"18:56:45 laser.focus: the button is lit: press it now (8 s; the job waits 599 at most)",
"18:56:46 laser.focus: burning: 0 s lit",
"18:56:47 laser.focus: burning: 1 s lit",
"18:56:48 laser.focus: burning: 0 s lit",
"18:56:49 laser.focus: burning: 1 s lit",
"18:56:50 laser.focus: burning: 2 s lit",
"18:56:51 laser.focus: burning: 0 s lit",
"18:56:53 laser.focus: burning: the tube is between passes",
"18:56:54 laser.focus: burning: 0 s lit",
"18:56:55 laser.focus: burning: the tube is between passes",
"18:56:56 laser.focus: burning: 0 s lit",
"18:56:58 laser.focus: burning: the tube is between passes",
"18:57:02 laser.focus: burning: 0 s lit",
"18:57:03 laser.focus: burning: 1 s lit",
"18:57:04 laser.focus: burning: the tube is between passes",
"18:57:05 laser.focus: burning: 0 s lit",
"18:57:06 laser.focus: burning: 1 s lit",
"18:57:08 laser.focus: burning: the tube is between passes",
"18:57:09 laser.focus: burning: 1 s lit",
"18:57:10 laser.focus: burning: the tube is between passes",
"18:57:11 laser.focus: burning: 0 s lit",
"18:57:12 laser.focus: burning: 1 s lit",
"18:57:13 laser.focus: burning: the tube is between passes",
"18:57:14 laser.focus: burning: 1 s lit",
"18:57:14 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"18:57:15 laser.focus: burning: 2 s lit",
"18:57:16 laser.focus: burning: 0 s lit",
"18:57:17 laser.focus: burning: 1 s lit",
"18:57:18 laser.focus: burning: the tube is between passes",
"18:57:19 laser.focus: burning: 1 s lit",
"18:57:20 laser.focus: burning: 2 s lit",
"18:57:21 laser.focus: burning: 0 s lit",
"18:57:22 laser.focus: burning: 1 s lit",
"18:57:23 laser.focus: burning: the tube is between passes",
"18:57:24 laser.focus: burning: 0 s lit",
"18:57:25 laser.focus: burning: 1 s lit",
"18:57:26 laser.focus: burning: the tube is between passes",
"18:57:27 laser.focus: burning: 1 s lit",
"18:57:28 laser.focus: burning: 2 s lit",
"18:57:29 laser.focus: burning: 0 s lit",
"18:57:30 laser.focus: burning: 1 s lit",
"18:57:31 laser.focus: burning: the tube is between passes",
"18:57:32 laser.focus: burning: 1 s lit",
"18:57:33 laser.focus: burning: 2 s lit",
"18:57:34 laser.focus: burning: the tube is between passes",
"18:57:35 laser.focus: the tube is dark: the pulse engine plays the rest",
"18:57:35 prompt focus-pick (multichoice): Every line is dark. Which is the narrowest dark line, with the crispest edges? Count from the top, 1 to 12. Several adjacent lines can look the same, since the depth of focus spans a few of them: choose every one that does, and the middle of the run is taken. Then Done. Look, but do not move the sheet: every card afte",
"18:57:36 prompt thickness (number): The sheet thickness (0.125 in from the placement).",
"18:57:37 laser.focus: {'pick': 11.0, 'thickness_mm': 3.175, 'pick_half_steps': -11.0, 'edge_z_mm': 6.939544832306639, 'steps_per_mm': 2.922, 'max_height_mm': 13.784171800136892, 'focus_range_mm': {'min': 2.148305954825462, 'max': 13.784171800136892}, 'stops': {'found': True, 'below': 14, 'above': 20, 'contact_below': 16, 'contact_above': 22, 'why': ''}}, emission {'hv_max': 1023, 'laser_on_samples': 233, 'thermopile_delta': 1320, 'lit_s': 47.345336135000025}",
"18:57:37 POST /wiz/laser.floor/start -> 200 {'started': True, 'id': 'laser.floor'}",
"18:57:37 laser.floor: stopping the motion controller",
"18:57:38 laser.floor: the lens finds its reference on the hall sensor",
"18:57:39 laser.floor: the lens finds its reference on the hall sensor: pass 1 of 2",
"18:57:40 laser.floor: starting the motion controller for the card: 0 s (60 at most)",
"18:57:41 laser.floor: the cooling engine takes the controller's report: 0 s (20 at most)",
"18:57:43 prompt floor-arm (continue): Twelve 2.087 in rungs from 2 to 24 percent density, the floor and the dose curve off for the rungs. Lid closed. Continue, then press the button when it lights white; this page says when.",
"18:57:44 laser.floor: the program goes to the controller, the button lights at the arm",
"18:57:45 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"18:57:45 laser.floor: the button is lit: press it now (0 s; the job waits 599 at most)",
"18:57:45 prompt press (wait): The button is lit white. Press it now: the laser fires after your press.",
"18:57:45 ARM press by the fixture, at the machine's own press prompt",
"18:57:46 laser.floor: the button is lit: press it now (1 s; the job waits 599 at most)",
"18:57:47 laser.floor: the button is lit: press it now (3 s; the job waits 599 at most)",
"18:57:48 laser.floor: the button is lit: press it now (4 s; the job waits 599 at most)",
"18:57:50 laser.floor: burning: 0 s lit",
"18:57:51 laser.floor: burning: 1 s lit",
"18:57:52 laser.floor: burning: 2 s lit",
"18:57:53 laser.floor: burning: 3 s lit",
"18:57:54 laser.floor: burning: 4 s lit",
"18:57:55 laser.floor: burning: the tube is between passes",
"18:57:56 laser.floor: burning: 0 s lit",
"18:57:59 laser.floor: burning: the tube is between passes",
"18:58:00 laser.floor: burning: 0 s lit",
"18:58:06 laser.floor: burning: the tube is between passes",
"18:58:08 laser.floor: burning: 0 s lit",
"18:58:09 laser.floor: burning: the tube is between passes",
"18:58:15 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"18:58:16 laser.floor: burning: 0 s lit",
"18:58:18 laser.floor: burning: the tube is between passes",
"18:58:19 laser.floor: burning: 0 s lit",
"18:58:21 laser.floor: burning: the tube is between passes",
"18:58:23 laser.floor: burning: 0 s lit",
"18:58:24 laser.floor: burning: the tube is between passes",
"18:58:25 laser.floor: burning: 0 s lit",
"18:58:26 laser.floor: burning: the tube is between passes",
"18:58:30 laser.floor: burning: 0 s lit",
"18:58:44 laser.floor: burning: the tube is between passes",
"18:58:45 laser.floor: burning: 0 s lit",
"18:58:46 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"18:58:52 laser.floor: burning: 1 s lit",
"18:58:53 laser.floor: burning: 2 s lit",
"18:58:54 laser.floor: burning: 3 s lit",
"18:58:55 laser.floor: burning: 4 s lit",
"18:58:56 laser.floor: burning: the tube is between passes",
"18:58:57 laser.floor: burning: 0 s lit",
"18:58:58 laser.floor: burning: 1 s lit",
"18:58:59 laser.floor: burning: 2 s lit",
"18:59:00 laser.floor: burning: 3 s lit",
"18:59:01 laser.floor: burning: 4 s lit",
"18:59:02 laser.floor: burning: the tube is between passes",
"18:59:03 laser.floor: burning: 0 s lit",
"18:59:04 laser.floor: burning: 1 s lit",
"18:59:05 laser.floor: burning: 2 s lit",
"18:59:06 laser.floor: burning: 3 s lit",
"18:59:07 laser.floor: burning: 4 s lit",
"18:59:08 laser.floor: burning: the tube is between passes",
"18:59:09 laser.floor: burning: 0 s lit",
"18:59:10 laser.floor: burning: 1 s lit",
"18:59:11 laser.floor: burning: 2 s lit",
"18:59:12 laser.floor: burning: 3 s lit",
"18:59:13 laser.floor: burning: 5 s lit",
"18:59:14 laser.floor: burning: the tube is between passes",
"18:59:15 laser.floor: burning: 1 s lit",
"18:59:16 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"18:59:16 laser.floor: burning: 2 s lit",
"18:59:17 laser.floor: burning: 3 s lit",
"18:59:18 laser.floor: burning: 4 s lit",
"18:59:20 laser.floor: burning: 5 s lit",
"18:59:21 laser.floor: the tube is dark: the samples run on, 2 s more",
"18:59:22 laser.floor: the tube is dark: the samples run on, 1 s more",
"18:59:23 laser.floor: the tube is dark: the pulse engine plays the rest",
"18:59:23 prompt floor-pick (choice): Which is the faintest rung that shows a continuous line? The labels are the percent density; the top rung is 2. Look, but do not move the sheet: every card after this is placed from the same datum.",
"18:59:24 laser.floor: {'faintest_density': 8.0, 'floor_density': 10.0}, emission {'hv_max': 1023, 'laser_on_samples': 149, 'thermopile_delta': 755, 'lit_s': 90.9621884359999}",
"18:59:24 POST /wiz/laser.dose-curve/start -> 200 {'started': True, 'id': 'laser.dose-curve'}",
"18:59:24 laser.dose-curve: stopping the motion controller",
"18:59:25 laser.dose-curve: the lens finds its reference on the hall sensor",
"18:59:26 laser.dose-curve: the lens finds its reference on the hall sensor: pass 1 of 2",
"18:59:27 laser.dose-curve: the lens finds its reference on the hall sensor: pass 2 of 2",
"18:59:28 laser.dose-curve: the cooling engine takes the controller's report: 0 s (20 at most)",
"18:59:30 prompt dose-arm (continue): Seven 100 mm rungs from 10 to 100 percent density, the thermopile reading each. The curve fits itself. Lid closed. Continue, then press the button when it lights white; this page says when.",
"18:59:31 laser.dose-curve: the program goes to the controller, the button lights at the arm",
"18:59:32 laser.dose-curve: the button is lit: press it now (0 s; the job waits 599 at most)",
"18:59:32 prompt press (wait): The button is lit white. Press it now: the laser fires after your press.",
"18:59:32 ARM press by the fixture, at the machine's own press prompt",
"18:59:33 laser.dose-curve: the button is lit: press it now (1 s; the job waits 599 at most)",
"18:59:34 laser.dose-curve: the button is lit: press it now (2 s; the job waits 599 at most)",
"18:59:35 laser.dose-curve: the button is lit: press it now (3 s; the job waits 599 at most)",
"18:59:36 laser.dose-curve: the button is lit: press it now (4 s; the job waits 599 at most)",
"18:59:37 laser.dose-curve: burning: 0 s lit",
"18:59:38 laser.dose-curve: burning: 1 s lit",
"18:59:39 laser.dose-curve: burning: 2 s lit",
"18:59:40 laser.dose-curve: burning: 3 s lit",
"18:59:41 laser.dose-curve: burning: 4 s lit",
"18:59:42 laser.dose-curve: burning: 6 s lit",
"18:59:43 laser.dose-curve: burning: the tube is between passes",
"18:59:45 laser.dose-curve: burning: 0 s lit",
"18:59:47 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"18:59:48 laser.dose-curve: burning: the tube is between passes",
"18:59:49 laser.dose-curve: burning: 0 s lit",
"18:59:54 laser.dose-curve: burning: the tube is between passes",
"18:59:58 laser.dose-curve: burning: 0 s lit",
"19:00:06 laser.dose-curve: burning: the tube is between passes",
"19:00:07 laser.dose-curve: burning: 0 s lit",
"19:00:08 laser.dose-curve: burning: the tube is between passes",
"19:00:11 laser.dose-curve: burning: 1 s lit",
"19:00:12 laser.dose-curve: burning: 2 s lit",
"19:00:13 laser.dose-curve: burning: 3 s lit",
"19:00:14 laser.dose-curve: burning: 4 s lit",
"19:00:15 laser.dose-curve: burning: 5 s lit",
"19:00:16 laser.dose-curve: burning: 6 s lit",
"19:00:17 laser.dose-curve: burning: 7 s lit",
"19:00:18 laser.dose-curve: burning: 8 s lit",
"19:00:19 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"19:00:19 laser.dose-curve: burning: 9 s lit",
"19:00:20 laser.dose-curve: burning: the tube is between passes",
"19:00:24 laser.dose-curve: burning: 1 s lit",
"19:00:25 laser.dose-curve: burning: 2 s lit",
"19:00:26 laser.dose-curve: burning: 3 s lit",
"19:00:27 laser.dose-curve: burning: 4 s lit",
"19:00:28 laser.dose-curve: burning: 5 s lit",
"19:00:29 laser.dose-curve: burning: 6 s lit",
"19:00:30 laser.dose-curve: burning: 7 s lit",
"19:00:31 laser.dose-curve: burning: 8 s lit",
"19:00:32 laser.dose-curve: burning: 9 s lit",
"19:00:33 laser.dose-curve: burning: the tube is between passes",
"19:00:37 laser.dose-curve: burning: 1 s lit",
"19:00:38 laser.dose-curve: burning: 2 s lit",
"19:00:39 laser.dose-curve: burning: 3 s lit",
"19:00:40 laser.dose-curve: burning: 4 s lit",
"19:00:41 laser.dose-curve: burning: 5 s lit",
"19:00:42 laser.dose-curve: burning: 6 s lit",
"19:00:44 laser.dose-curve: burning: 7 s lit",
"19:00:45 laser.dose-curve: burning: 8 s lit",
"19:00:46 laser.dose-curve: burning: 9 s lit",
"19:00:47 laser.dose-curve: burning: 10 s lit",
"19:00:48 laser.dose-curve: burning: the tube is between passes",
"19:00:50 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"19:00:52 laser.dose-curve: burning: 1 s lit",
"19:00:53 laser.dose-curve: burning: 2 s lit",
"19:00:54 laser.dose-curve: burning: 3 s lit",
"19:00:55 laser.dose-curve: burning: 4 s lit",
"19:00:56 laser.dose-curve: burning: 5 s lit",
"19:00:57 laser.dose-curve: burning: 6 s lit",
"19:00:58 laser.dose-curve: burning: 7 s lit",
"19:00:59 laser.dose-curve: burning: 8 s lit",
"19:01:00 laser.dose-curve: burning: 9 s lit",
"19:01:01 laser.dose-curve: burning: the tube is between passes",
"19:01:05 laser.dose-curve: burning: 1 s lit",
"19:01:06 laser.dose-curve: burning: 2 s lit",
"19:01:07 laser.dose-curve: burning: 3 s lit",
"19:01:08 laser.dose-curve: burning: 4 s lit",
"19:01:09 laser.dose-curve: burning: 5 s lit",
"19:01:10 laser.dose-curve: burning: 6 s lit",
"19:01:11 laser.dose-curve: burning: 7 s lit",
"19:01:12 laser.dose-curve: burning: 8 s lit",
"19:01:13 laser.dose-curve: burning: 9 s lit",
"19:01:14 laser.dose-curve: burning: the tube is between passes",
"19:01:18 laser.dose-curve: burning: 1 s lit",
"19:01:19 laser.dose-curve: burning: 2 s lit",
"19:01:20 laser.dose-curve: burning: 3 s lit",
"19:01:21 laser.dose-curve: burning: 4 s lit",
"19:01:21 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"19:01:22 laser.dose-curve: burning: 5 s lit",
"19:01:23 laser.dose-curve: burning: 6 s lit",
"19:01:24 laser.dose-curve: burning: 7 s lit",
"19:01:25 laser.dose-curve: burning: 8 s lit",
"19:01:26 laser.dose-curve: burning: 9 s lit",
"19:01:27 laser.dose-curve: burning: the tube is between passes",
"19:01:29 laser.dose-curve: the tube is dark: the fit needs the dark tail, 18 s more",
"19:01:30 laser.dose-curve: the tube is dark: the fit needs the dark tail, 17 s more",
"19:01:31 laser.dose-curve: the tube is dark: the fit needs the dark tail, 16 s more",
"19:01:32 laser.dose-curve: the tube is dark: the fit needs the dark tail, 15 s more",
"19:01:33 laser.dose-curve: the tube is dark: the fit needs the dark tail, 14 s more",
"19:01:34 laser.dose-curve: the tube is dark: the fit needs the dark tail, 13 s more",
"19:01:35 laser.dose-curve: the tube is dark: the fit needs the dark tail, 12 s more",
"19:01:36 laser.dose-curve: the tube is dark: the fit needs the dark tail, 11 s more",
"19:01:37 laser.dose-curve: the tube is dark: the fit needs the dark tail, 10 s more",
"19:01:38 laser.dose-curve: the tube is dark: the fit needs the dark tail, 9 s more",
"19:01:39 laser.dose-curve: the tube is dark: the fit needs the dark tail, 8 s more",
"19:01:40 laser.dose-curve: the tube is dark: the fit needs the dark tail, 6 s more",
"19:01:41 laser.dose-curve: the tube is dark: the fit needs the dark tail, 5 s more",
"19:01:42 laser.dose-curve: the tube is dark: the fit needs the dark tail, 4 s more",
"19:01:43 laser.dose-curve: the tube is dark: the fit needs the dark tail, 3 s more",
"19:01:44 laser.dose-curve: the tube is dark: the fit needs the dark tail, 2 s more",
"19:01:45 laser.dose-curve: the tube is dark: the fit needs the dark tail, 1 s more",
"19:01:46 laser.dose-curve: the tube is dark: the fit needs the dark tail, 0 s more",
"19:01:49 laser.dose-curve: the tube is dark: the pulse engine plays the rest",
"19:01:50 laser.dose-curve: {'points': [{'density': 10.0, 'light': 0.19913034557192308}, {'density': 20.0, 'light': 3.133343866554108}, {'density': 30.0, 'light': 11.90652008843376}, {'density': 45.0, 'light': 30.85270331032583}, {'density': 60.0, 'light': 41.96203397904551}, {'density': 80.0, 'light': 54.91520404843594}, {'density': 100.0, 'light': 100.0}], 'curve': '10:0.20,20:3.13,30:11.91,45:30.85,60:41.96,80:54.92,100:100.00'}, emission {'hv_max': 1023, 'laser_on_samples': 255, 'thermopile_delta': 2273, 'lit_s': 110.94573579500002}",
"19:01:50 POST /wiz/laser.corner/start -> 200 {'started': True, 'id': 'laser.corner'}",
"19:01:50 laser.corner: stopping the motion controller",
"19:01:51 laser.corner: the lens finds its reference on the hall sensor",
"19:01:52 laser.corner: the lens finds its reference on the hall sensor: pass 1 of 2",
"19:01:53 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"19:01:53 laser.corner: the lens finds its reference on the hall sensor: pass 2 of 2",
"19:01:54 laser.corner: the cooling engine takes the controller's report: 0 s (20 at most)",
"19:01:56 prompt corner-arm (continue): The same corner-heavy pattern five times at rolloff exponents 1.0 to 2.0 under velocity-scaled power at 30 percent. Lid closed. Continue, then press the button when it lights white; this page says when.",
"19:01:57 laser.corner: the program goes to the controller, the button lights at the arm",
"19:01:58 laser.corner: the button is lit: press it now (0 s; the job waits 599 at most)",
"19:01:58 prompt press (wait): The button is lit white. Press it now: the laser fires after your press.",
"19:01:58 ARM press by the fixture, at the machine's own press prompt",
"19:01:59 laser.corner: the button is lit: press it now (2 s; the job waits 599 at most)",
"19:02:00 laser.corner: the button is lit: press it now (3 s; the job waits 599 at most)",
"19:02:01 laser.corner: the button is lit: press it now (4 s; the job waits 599 at most)",
"19:02:02 laser.corner: the button is lit: press it now (5 s; the job waits 599 at most)",
"19:02:03 laser.corner: the button is lit: press it now (6 s; the job waits 599 at most)",
"19:02:04 laser.corner: the button is lit: press it now (7 s; the job waits 599 at most)",
"19:02:06 laser.corner: the button is lit: press it now (8 s; the job waits 599 at most)",
"19:02:07 laser.corner: the button is lit: press it now (9 s; the job waits 599 at most)",
"19:02:08 laser.corner: burning: 0 s lit",
"19:02:09 laser.corner: burning: 1 s lit",
"19:02:11 laser.corner: burning: 2 s lit",
"19:02:12 laser.corner: burning: 3 s lit",
"19:02:13 laser.corner: burning: 0 s lit",
"19:02:21 laser.corner: burning: the tube is between passes",
"19:02:23 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"19:02:24 laser.corner: burning: 0 s lit",
"19:02:25 laser.corner: burning: the tube is between passes",
"19:02:27 laser.corner: burning: 0 s lit",
"19:02:28 laser.corner: burning: 1 s lit",
"19:02:29 laser.corner: burning: the tube is between passes",
"19:02:30 laser.corner: burning: 0 s lit",
"19:02:31 laser.corner: burning: 1 s lit",
"19:02:32 laser.corner: burning: the tube is between passes",
"19:02:33 laser.corner: burning: 1 s lit",
"19:02:34 laser.corner: burning: the tube is between passes",
"19:02:35 laser.corner: burning: 0 s lit",
"19:02:36 laser.corner: burning: 1 s lit",
"19:02:37 laser.corner: burning: the tube is between passes",
"19:02:38 laser.corner: burning: 1 s lit",
"19:02:40 laser.corner: burning: the tube is between passes",
"19:02:41 laser.corner: the tube is dark: the pulse engine plays the rest",
"19:02:41 prompt corner-pick (choice): Which pattern has the most even corners, neither burned dark nor faded, through the teeth, the square, and the root sign at the end? The top pattern is 1.00. Look, but do not move the sheet: every card after this is placed from the same datum.",
"19:02:42 laser.corner: {'gamma': 1.5}, emission {'hv_max': 1023, 'laser_on_samples': 138, 'thermopile_delta': 753, 'lit_s': 30.988956764000022}",
"19:02:42 POST /wiz/cooling.flow-load/start -> 200 {'started': True, 'id': 'cooling.flow-load'}",
"19:02:42 cooling.flow-load: stopping the motion controller",
"19:02:43 cooling.flow-load: the lens finds its reference on the hall sensor",
"19:02:44 cooling.flow-load: the lens finds its reference on the hall sensor: pass 1 of 2",
"19:02:45 cooling.flow-load: the lens finds its reference on the hall sensor: pass 2 of 2",
"19:02:46 cooling.flow-load: the cooling engine takes the controller's report: 0 s (20 at most)",
"19:02:48 cooling.flow-load: the coolant loop settles before the press: 0 s (60 at least, 240 at most), reading the sensors",
"19:02:49 cooling.flow-load: the coolant loop settles before the press: 1 s (60 at least, 240 at most), reading the sensors",
"19:02:50 cooling.flow-load: the coolant loop settles before the press: 2 s (60 at least, 240 at most), reading the sensors",
"19:02:51 cooling.flow-load: the coolant loop settles before the press: 3 s (60 at least, 240 at most), reading the sensors",
"19:02:52 cooling.flow-load: the coolant loop settles before the press: 4 s (60 at least, 240 at most), reading the sensors",
"19:02:53 cooling.flow-load: the coolant loop settles before the press: 5 s (60 at least, 240 at most), reading the sensors",
"19:02:54 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"19:02:54 cooling.flow-load: the coolant loop settles before the press: 6 s (60 at least, 240 at most), reading the sensors",
"19:02:55 cooling.flow-load: the coolant loop settles before the press: 7 s (60 at least, 240 at most), reading the sensors",
"19:02:56 cooling.flow-load: the coolant loop settles before the press: 8 s (60 at least, 240 at most), reading the sensors",
"19:02:57 cooling.flow-load: the coolant loop settles before the press: 9 s (60 at least, 240 at most), reading the sensors",
"19:02:58 cooling.flow-load: the coolant loop settles before the press: 10 s (60 at least, 240 at most), reading the sensors",
"19:02:59 cooling.flow-load: the coolant loop settles before the press: 11 s (60 at least, 240 at most), reading the sensors",
"19:03:00 cooling.flow-load: the coolant loop settles before the press: 12 s (60 at least, 240 at most), reading the sensors",
"19:03:01 cooling.flow-load: the coolant loop settles before the press: 13 s (60 at least, 240 at most), reading the sensors",
"19:03:02 cooling.flow-load: the coolant loop settles before the press: 14 s (60 at least, 240 at most), reading the sensors",
"19:03:03 cooling.flow-load: the coolant loop settles before the press: 15 s (60 at least, 240 at most), reading the sensors",
"19:03:04 cooling.flow-load: the coolant loop settles before the press: 16 s (60 at least, 240 at most), reading the sensors",
"19:03:05 cooling.flow-load: the coolant loop settles before the press: 17 s (60 at least, 240 at most), reading the sensors",
"19:03:06 cooling.flow-load: the coolant loop settles before the press: 18 s (60 at least, 240 at most), reading the sensors",
"19:03:07 cooling.flow-load: the coolant loop settles before the press: 19 s (60 at least, 240 at most), reading the sensors",
"19:03:08 cooling.flow-load: the coolant loop settles before the press: 20 s (60 at least, 240 at most), reading the sensors",
"19:03:09 cooling.flow-load: the coolant loop settles before the press: 21 s (60 at least, 240 at most), reading the sensors",
"19:03:10 cooling.flow-load: the coolant loop settles before the press: 22 s (60 at least, 240 at most), reading the sensors",
"19:03:11 cooling.flow-load: the coolant loop settles before the press: 23 s (60 at least, 240 at most), reading the sensors",
"19:03:12 cooling.flow-load: the coolant loop settles before the press: 24 s (60 at least, 240 at most), reading the sensors",
"19:03:13 cooling.flow-load: the coolant loop settles before the press: 25 s (60 at least, 240 at most), reading the sensors",
"19:03:14 cooling.flow-load: the coolant loop settles before the press: 26 s (60 at least, 240 at most), reading the sensors",
"19:03:15 cooling.flow-load: the coolant loop settles before the press: 27 s (60 at least, 240 at most), reading the sensors",
"19:03:16 cooling.flow-load: the coolant loop settles before the press: 28 s (60 at least, 240 at most), reading the sensors",
"19:03:17 cooling.flow-load: the coolant loop settles before the press: 29 s (60 at least, 240 at most), drifting -0.176 C p",
"19:03:18 cooling.flow-load: the coolant loop settles before the press: 30 s (60 at least, 240 at most), drifting -0.145 C p",
"19:03:19 cooling.flow-load: the coolant loop settles before the press: 31 s (60 at least, 240 at most), drifting -0.127 C p",
"19:03:20 cooling.flow-load: the coolant loop settles before the press: 32 s (60 at least, 240 at most), drifting -0.113 C p",
"19:03:21 cooling.flow-load: the coolant loop settles before the press: 33 s (60 at least, 240 at most), drifting -0.098 C p",
"19:03:22 cooling.flow-load: the coolant loop settles before the press: 34 s (60 at least, 240 at most), drifting -0.086 C p",
"19:03:23 cooling.flow-load: the coolant loop settles before the press: 35 s (60 at least, 240 at most), drifting -0.073 C p",
"19:03:24 cooling.flow-load: the coolant loop settles before the press: 36 s (60 at least, 240 at most), drifting -0.062 C p",
"19:03:24 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"19:03:25 cooling.flow-load: the coolant loop settles before the press: 37 s (60 at least, 240 at most), drifting -0.060 C p",
"19:03:26 cooling.flow-load: the coolant loop settles before the press: 38 s (60 at least, 240 at most), drifting -0.054 C p",
"19:03:27 cooling.flow-load: the coolant loop settles before the press: 39 s (60 at least, 240 at most), drifting -0.046 C p",
"19:03:28 cooling.flow-load: the coolant loop settles before the press: 40 s (60 at least, 240 at most), drifting -0.042 C p",
"19:03:29 cooling.flow-load: the coolant loop settles before the press: 41 s (60 at least, 240 at most), drifting -0.038 C p",
"19:03:30 cooling.flow-load: the coolant loop settles before the press: 42 s (60 at least, 240 at most), drifting -0.035 C p",
"19:03:31 cooling.flow-load: the coolant loop settles before the press: 43 s (60 at least, 240 at most), drifting -0.032 C p",
"19:03:32 cooling.flow-load: the coolant loop settles before the press: 44 s (60 at least, 240 at most), drifting -0.029 C p",
"19:03:33 cooling.flow-load: the coolant loop settles before the press: 45 s (60 at least, 240 at most), drifting -0.024 C p",
"19:03:34 cooling.flow-load: the coolant loop settles before the press: 46 s (60 at least, 240 at most), drifting -0.022 C p",
"19:03:35 cooling.flow-load: the coolant loop settles before the press: 47 s (60 at least, 240 at most), drifting -0.024 C p",
"19:03:36 cooling.flow-load: the coolant loop settles before the press: 48 s (60 at least, 240 at most), drifting -0.026 C p",
"19:03:37 cooling.flow-load: the coolant loop settles before the press: 49 s (60 at least, 240 at most), drifting -0.025 C p",
"19:03:38 cooling.flow-load: the coolant loop settles before the press: 50 s (60 at least, 240 at most), drifting -0.025 C p",
"19:03:39 cooling.flow-load: the coolant loop settles before the press: 51 s (60 at least, 240 at most), drifting -0.025 C p",
"19:03:40 cooling.flow-load: the coolant loop settles before the press: 52 s (60 at least, 240 at most), drifting -0.025 C p",
"19:03:41 cooling.flow-load: the coolant loop settles before the press: 53 s (60 at least, 240 at most), drifting -0.025 C p",
"19:03:42 cooling.flow-load: the coolant loop settles before the press: 54 s (60 at least, 240 at most), drifting -0.023 C p",
"19:03:43 cooling.flow-load: the coolant loop settles before the press: 55 s (60 at least, 240 at most), drifting -0.023 C p",
"19:03:44 cooling.flow-load: the coolant loop settles before the press: 56 s (60 at least, 240 at most), drifting -0.022 C p",
"19:03:45 cooling.flow-load: the coolant loop settles before the press: 57 s (60 at least, 240 at most), drifting -0.019 C p",
"19:03:46 cooling.flow-load: the coolant loop settles before the press: 58 s (60 at least, 240 at most), drifting -0.016 C p",
"19:03:47 cooling.flow-load: the coolant loop settles before the press: 59 s (60 at least, 240 at most), drifting -0.015 C p",
"19:03:48 prompt load-arm (continue): The loop is quiet. Now the box, then a 60 x 15 mm patch at 60 percent that keeps the tube lit for about a minute, both coolant sensors read for 100 s after. About four minutes in all. Lid closed. Continue, then press the button when it lights white; this page says when.",
"19:03:49 cooling.flow-load: the program goes to the controller, the button lights at the arm",
"19:03:50 cooling.flow-load: the button is lit: press it now (0 s; the job waits 599 at most)",
"19:03:50 prompt press (wait): The button is lit white. Press it now: the laser fires after your press.",
"19:03:50 ARM press by the fixture, at the machine's own press prompt",
"19:03:51 cooling.flow-load: the button is lit: press it now (2 s; the job waits 599 at most)",
"19:03:52 cooling.flow-load: the button is lit: press it now (3 s; the job waits 599 at most)",
"19:03:54 cooling.flow-load: the button is lit: press it now (4 s; the job waits 599 at most)",
"19:03:55 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"19:03:55 cooling.flow-load: the button is lit: press it now (5 s; the job waits 599 at most)",
"19:03:57 cooling.flow-load: the button is lit: press it now (6 s; the job waits 599 at most)",
"19:03:58 cooling.flow-load: the button is lit: press it now (7 s; the job waits 599 at most)",
"19:03:59 cooling.flow-load: the button is lit: press it now (8 s; the job waits 599 at most)",
"19:04:00 cooling.flow-load: the button is lit: press it now (9 s; the job waits 599 at most)",
"19:04:01 cooling.flow-load: burning: 1 s lit",
"19:04:02 cooling.flow-load: burning: 2 s lit",
"19:04:03 cooling.flow-load: burning: 3 s lit",
"19:04:04 cooling.flow-load: burning: 0 s lit",
"19:04:05 cooling.flow-load: burning: the tube is between passes",
"19:04:06 cooling.flow-load: burning: 0 s lit",
"19:04:07 cooling.flow-load: burning: the tube is between passes",
"19:04:08 cooling.flow-load: burning: 0 s lit",
"19:04:11 cooling.flow-load: burning: the tube is between passes",
"19:04:15 cooling.flow-load: burning: 1 s lit",
"19:04:16 cooling.flow-load: burning: 2 s lit",
"19:04:17 cooling.flow-load: burning: 3 s lit",
"19:04:18 cooling.flow-load: burning: 4 s lit",
"19:04:19 cooling.flow-load: burning: 5 s lit",
"19:04:20 cooling.flow-load: burning: 6 s lit",
"19:04:21 cooling.flow-load: burning: 7 s lit",
"19:04:22 cooling.flow-load: burning: 8 s lit",
"19:04:23 cooling.flow-load: burning: 9 s lit",
"19:04:24 cooling.flow-load: burning: 10 s lit",
"19:04:25 cooling.flow-load: burning: 11 s lit",
"19:04:25 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"19:04:26 cooling.flow-load: burning: 12 s lit",
"19:04:27 cooling.flow-load: burning: 13 s lit",
"19:04:28 cooling.flow-load: burning: 14 s lit",
"19:04:29 cooling.flow-load: burning: 15 s lit",
"19:04:30 cooling.flow-load: burning: 16 s lit",
"19:04:31 cooling.flow-load: burning: 17 s lit",
"19:04:32 cooling.flow-load: burning: 18 s lit",
"19:04:33 cooling.flow-load: burning: 19 s lit",
"19:04:34 cooling.flow-load: burning: 20 s lit",
"19:04:35 cooling.flow-load: burning: 21 s lit",
"19:04:36 cooling.flow-load: burning: 22 s lit",
"19:04:37 cooling.flow-load: burning: 23 s lit",
"19:04:38 cooling.flow-load: burning: 24 s lit",
"19:04:39 cooling.flow-load: burning: 25 s lit",
"19:04:40 cooling.flow-load: burning: 26 s lit",
"19:04:41 cooling.flow-load: burning: 27 s lit",
"19:04:42 cooling.flow-load: burning: 28 s lit",
"19:04:43 cooling.flow-load: burning: 29 s lit",
"19:04:44 cooling.flow-load: burning: 30 s lit",
"19:04:45 cooling.flow-load: burning: 31 s lit",
"19:04:46 cooling.flow-load: burning: 32 s lit",
"19:04:47 cooling.flow-load: burning: 33 s lit",
"19:04:48 cooling.flow-load: burning: 34 s lit",
"19:04:49 cooling.flow-load: burning: 35 s lit",
"19:04:50 cooling.flow-load: burning: 36 s lit",
"19:04:51 cooling.flow-load: burning: 38 s lit",
"19:04:52 cooling.flow-load: burning: 39 s lit",
"19:04:53 cooling.flow-load: burning: 40 s lit",
"19:04:54 cooling.flow-load: burning: 41 s lit",
"19:04:55 cooling.flow-load: burning: 42 s lit",
"19:04:56 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"19:04:56 cooling.flow-load: burning: 43 s lit",
"19:04:57 cooling.flow-load: burning: 44 s lit",
"19:04:58 cooling.flow-load: burning: 45 s lit",
"19:04:59 cooling.flow-load: burning: 46 s lit",
"19:05:00 cooling.flow-load: burning: 47 s lit",
"19:05:01 cooling.flow-load: burning: 48 s lit",
"19:05:02 cooling.flow-load: burning: 49 s lit",
"19:05:03 cooling.flow-load: burning: 50 s lit",
"19:05:04 cooling.flow-load: burning: 51 s lit",
"19:05:05 cooling.flow-load: burning: 52 s lit",
"19:05:06 cooling.flow-load: burning: 53 s lit",
"19:05:07 cooling.flow-load: burning: 54 s lit",
"19:05:08 cooling.flow-load: burning: 55 s lit",
"19:05:09 cooling.flow-load: burning: 56 s lit",
"19:05:10 cooling.flow-load: burning: 57 s lit",
"19:05:11 cooling.flow-load: burning: 58 s lit",
"19:05:12 cooling.flow-load: burning: 59 s lit",
"19:05:13 cooling.flow-load: burning: 60 s lit",
"19:05:14 cooling.flow-load: burning: 61 s lit",
"19:05:16 cooling.flow-load: burning: 62 s lit",
"19:05:17 cooling.flow-load: burning: 63 s lit",
"19:05:18 cooling.flow-load: burning: 64 s lit",
"19:05:19 cooling.flow-load: burning: 65 s lit",
"19:05:20 cooling.flow-load: burning: 66 s lit",
"19:05:21 cooling.flow-load: burning: 67 s lit",
"19:05:22 cooling.flow-load: burning: 68 s lit",
"19:05:23 cooling.flow-load: burning: 69 s lit",
"19:05:24 cooling.flow-load: burning: 70 s lit",
"19:05:25 cooling.flow-load: burning: 71 s lit",
"19:05:26 cooling.flow-load: burning: 72 s lit",
"19:05:26 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"19:05:27 cooling.flow-load: burning: 73 s lit",
"19:05:28 cooling.flow-load: burning: 74 s lit",
"19:05:29 cooling.flow-load: burning: 75 s lit",
"19:05:30 cooling.flow-load: burning: 76 s lit",
"19:05:31 cooling.flow-load: burning: the tube is between passes",
"19:05:33 cooling.flow-load: the tube is dark: the coolant sensors follow the heat, 97 s more",
"19:05:34 cooling.flow-load: the tube is dark: the coolant sensors follow the heat, 96 s more",
"19:05:35 cooling.flow-load: the tube is dark: the coolant sensors follow the heat, 95 s more",
"19:05:36 cooling.flow-load: the tube is dark: the coolant sensors follow the heat, 94 s more",
"19:05:37 cooling.flow-load: the tube is dark: the coolant sensors follow the heat, 93 s more",
"19:05:38 cooling.flow-load: the tube is dark: the coolant sensors follow the heat, 92 s more",
"19:05:39 cooling.flow-load: the tube is dark: the coolant sensors follow the heat, 91 s more",
"19:05:40 cooling.flow-load: the tube is dark: the coolant sensors follow the heat, 90 s more",
"19:05:41 cooling.flow-load: the tube is dark: the coolant sensors follow the heat, 89 s more",
"19:05:42 cooling.flow-load: the tube is dark: the coolant sensors follow the heat, 88 s more",
"19:05:43 cooling.flow-load: the tube is dark: the coolant sensors follow the heat, 87 s more",
"19:05:44 cooling.flow-load: the tube is dark: the coolant sensors follow the heat, 86 s more",
"19:05:45 cooling.flow-load: the tube is dark: the coolant sensors follow the heat, 85 s more",
"19:05:46 cooling.flow-load: the tube is dark: the coolant sensors follow the heat, 84 s more",
"19:05:47 cooling.flow-load: the tube is dark: the coolant sensors follow the heat, 83 s more",
"19:05:48 cooling.flow-load: the tube is dark: the coolant sensors follow the heat, 82 s more",
"19:05:49 cooling.flow-load: the tube is dark: the coolant sensors follow the heat, 81 s more",
"19:05:50 cooling.flow-load: the tube is dark: the coolant sensors follow the heat, 80 s more",
"19:05:51 cooling.flow-load: the tube is dark: the coolant sensors follow the heat, 79 s more",
"19:05:52 cooling.flow-load: the tube is dark: the coolant sensors follow the heat, 78 s more",
"19:05:53 cooling.flow-load: the tube is dark: the coolant sensors follow the heat, 77 s more",
"19:05:55 cooling.flow-load: the tube is dark: the coolant sensors follow the heat, 75 s more",
"19:05:57 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"19:05:57 cooling.flow-load: the tube is dark: the coolant sensors follow the heat, 74 s more",
"19:05:58 cooling.flow-load: the tube is dark: the coolant sensors follow the heat, 73 s more",
"19:05:59 cooling.flow-load: the tube is dark: the coolant sensors follow the heat, 72 s more",
"19:06:00 cooling.flow-load: the tube is dark: the coolant sensors follow the heat, 71 s more",
"19:06:01 cooling.flow-load: the tube is dark: the coolant sensors follow the heat, 69 s more",
"19:06:02 cooling.flow-load: the tube is dark: the coolant sensors follow the heat, 68 s more",
"19:06:03 cooling.flow-load: the tube is dark: the coolant sensors follow the heat, 67 s more",
"19:06:04 cooling.flow-load: the tube is dark: the coolant sensors follow the heat, 66 s more",
"19:06:05 cooling.flow-load: the tube is dark: the coolant sensors follow the heat, 65 s more",
"19:06:06 cooling.flow-load: the tube is dark: the coolant sensors follow the heat, 64 s more",
"19:06:07 cooling.flow-load: the tube is dark: the coolant sensors follow the heat, 63 s more",
"19:06:08 cooling.flow-load: the tube is dark: the coolant sensors follow the heat, 62 s more",
"19:06:09 cooling.flow-load: the tube is dark: the coolant sensors follow the heat, 61 s more",
"19:06:10 cooling.flow-load: the tube is dark: the coolant sensors follow the heat, 60 s more",
"19:06:11 cooling.flow-load: the tube is dark: the coolant sensors follow the heat, 59 s more",
"19:06:12 cooling.flow-load: the tube is dark: the coolant sensors follow the heat, 58 s more",
"19:06:13 cooling.flow-load: the tube is dark: the coolant sensors follow the heat, 57 s more",
"19:06:14 cooling.flow-load: the tube is dark: the coolant sensors follow the heat, 56 s more",
"19:06:15 cooling.flow-load: the tube is dark: the coolant sensors follow the heat, 55 s more",
"19:06:16 cooling.flow-load: the tube is dark: the coolant sensors follow the heat, 54 s more",
"19:06:17 cooling.flow-load: the tube is dark: the coolant sensors follow the heat, 53 s more",
"19:06:18 cooling.flow-load: the tube is dark: the coolant sensors follow the heat, 52 s more",
"19:06:19 cooling.flow-load: {'lit_s': 64.28, 'dose_raw_s': 36169.719999999965, 'peak_c': 1.9936470588235302, 'k_density': 5.511922842708023e-05, 'k_cw': 7.158341354166263e-05}, emission {'hv_max': 1023, 'laser_on_samples': 213, 'thermopile_delta': 1006, 'lit_s': 90.5457904509999}",
"19:06:19 restore lens_hall_edge_z_mm='4.51' -> 200",
"19:06:19 restore lens_stop_below_steps='14' -> 200",
"19:06:19 restore lens_stop_above_steps='20' -> 200",
"19:06:19 restore laser_floor_density='14' -> 200",
"19:06:19 restore laser_dose_curve='10:0.62,20:2.79,30:8.46,45:24.90,60:42.02,80:52.53,100:100.00' -> 200",
"19:06:19 restore laser_corner_gamma='1.50' -> 200",
"19:06:19 restore cool_laser_heat_density='5.03e-05' -> 200",
"19:06:19 restore cool_laser_heat_cw='6.533e-05' -> 200",
"19:06:19 PASS: the sheet's seven wizards ran on one piece as a fresh machine's; settings restored",
"19:06:20 baseline: post: clean",
"19:06:20 result PASS"
],
"manifest_sha": "84a155bfc701e865ae73f9818bc38c2d005324ab5ba0ed44b668ec8896179947",
"message": "",
"result": "PASS",
"test": "setup.sheet",
"ts": "2026-09-28T19:06:20Z"
},
"requires": [
"forgectrl.auth",
"setup.check-motion",
"laser.emission-witness",
"cooling.flow-verify"
],
"satisfied": true,
"source_sha": "9874cb0c5c6a93d5dfbade5905c7f517003f86cc5825d2f5f84f0de39739d1b4",
"subsystem": "setup",
"title": "The setup sheet: the placement, the frame, and the five cards"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/logs.*"
],
[
"forgectrl",
"src/fflog.*"
],
[
"forgectrl",
"src/sanitize.*"
],
[
"forgectrl",
"src/extpkg.*"
],
[
"forgectrl",
"src/main.c"
]
],
"fingerprint": "0f5afffef01ab879bc29fabb7e298fc43ad5e4673c7c0718d3794f82ce711f12",
"hardware": "api",
"id": "logs.tree-tail-export",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928162331-3969",
"duration_s": 51,
"evidence": {
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T16:23:31Z"
},
"camera_key_leaks": [],
"export_bytes": 4215831,
"export_s": 50.6,
"extensions": {
"enabled": true,
"packages": [],
"safe_mode": false
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"install_members": [
"forgefirm-logs/logs/install/forgetest-probe.txt"
],
"loggers": [
"forgectrl",
"grblhal",
"gfcloud",
"gfhome",
"forgeext",
"kernel",
"system"
],
"members": 45,
"panel_token_leaks": []
},
"fingerprint": "0f5afffef01ab879bc29fabb7e298fc43ad5e4673c7c0718d3794f82ce711f12",
"image": "20260928153805 (dev)",
"log": [
"16:28:07 start logs.tree-tail-export (auto, api) in campaign c-20260928162331-3969",
"16:28:07 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:28:07 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"16:28:07 queued by the unattended queue opened 2026-09-28T16:23:31Z",
"16:28:08 baseline: pre: clean",
"16:28:08 GET /logs -> 200",
"16:28:08 loggers: ['forgectrl', 'grblhal', 'gfcloud', 'gfhome', 'forgeext', 'kernel', 'system']",
"16:28:08 GET /logs/tail?name=forgectrl -> 200",
"16:28:45 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:28:58 POST /logs/export -> 200 (4215831 bytes, 50.6 s)",
"16:28:59 bundle: 45 members, e.g. ['forgefirm-logs', 'forgefirm-logs/README.txt', 'forgefirm-logs/logs', 'forgefirm-logs/logs/grblhal', 'forgefirm-logs/logs/grblhal/grblhal.log']",
"16:28:59 the bundle's extension listing: {'enabled': True, 'safe_mode': False, 'packages': []}",
"16:28:59 baseline: post: clean",
"16:28:59 result PASS"
],
"manifest_sha": "faf9563c750bb8bd4bfc8778b6af053cddb63fa335ab946caf2f71631ede740f",
"message": "",
"result": "PASS",
"test": "logs.tree-tail-export",
"ts": "2026-09-28T16:28:59Z"
},
"requires": [
"forgectrl.auth"
],
"satisfied": true,
"source_sha": "7ce90103756335e9eb2196769d2f283f419e5be54451d4449a5b35e8b448f154",
"subsystem": "logs",
"title": "Log tree, tail, and sanitized export"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/logs.*"
],
[
"forgectrl",
"src/fflog.*"
],
[
"forgectrl",
"src/super.c"
],
[
"forgectrl",
"init/**"
],
[
"grblhal-glowforge",
"src/fflog.*"
],
[
"grblhal-glowforge",
"src/main.c"
],
[
"forgefirm-app",
"forgefirm-app/ffmachine.py"
],
[
"forgefirm-app",
"forgefirm-app/gfcloud.py"
],
[
"forgefirm-app",
"forgefirm-app/gfhome.py"
]
],
"fingerprint": "dddd1c27526f4613545f197c701c805834364ffa63bed814715361f52517c798",
"hardware": "api",
"id": "logs.routing",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928162331-3969",
"duration_s": 4,
"evidence": {
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T16:23:31Z"
},
"controller": "running",
"effective": {
"forgectrl": [
"info",
"off"
],
"forgeext": [
"info",
"off"
],
"gfcloud": [
"info",
"off"
],
"gfhome": [
"info",
"off"
],
"grblhal": [
"info",
"off"
],
"kernel": [
"info",
"off"
],
"system": [
"info",
"off"
]
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"kernel_lines": 50,
"logger_relays": [
483,
5798,
8135
],
"own_lines": 185,
"probe_gfhome": "2026-09-28T16:40:25.967601+00:00 gfhome[-] ERR forgetest-routing-1790613624 gfhome",
"probe_grblhal": "2026-09-28T16:40:24.930259+00:00 grblhal[-] ERR forgetest-routing-1790613624 grblhal",
"rsyslogd_pids": [
463
]
},
"fingerprint": "dddd1c27526f4613545f197c701c805834364ffa63bed814715361f52517c798",
"image": "20260928153805 (dev)",
"log": [
"16:40:24 start logs.routing (auto, api) in campaign c-20260928162331-3969",
"16:40:24 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:40:24 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"16:40:24 queued by the unattended queue opened 2026-09-28T16:23:31Z",
"16:40:24 baseline: pre: clean",
"16:40:24 rsyslogd [463]; no syslogd/klogd",
"16:40:24 effective levels: {'forgectrl': ('info', 'off'), 'grblhal': ('info', 'off'), 'gfcloud': ('info', 'off'), 'gfhome': ('info', 'off'), 'forgeext': ('info', 'off'), 'kernel': ('info', 'off'), 'system': ('info', 'off')}",
"16:40:24 forgectrl[[5799]] lines in its file: 185",
"16:40:25 grblhal: 2026-09-28T16:40:24.930259+00:00 grblhal[-] ERR forgetest-routing-1790613624 grblhal",
"16:40:26 gfhome: 2026-09-28T16:40:25.967601+00:00 gfhome[-] ERR forgetest-routing-1790613624 gfhome",
"16:40:28 logger relays: [483, 5798, 8135] (controller running)",
"16:40:28 no ForgeFIRM log outside /data/log/forgefirm",
"16:40:28 baseline: post: clean",
"16:40:28 result PASS"
],
"manifest_sha": "faf9563c750bb8bd4bfc8778b6af053cddb63fa335ab946caf2f71631ede740f",
"message": "",
"result": "PASS",
"test": "logs.routing",
"ts": "2026-09-28T16:40:28Z"
},
"requires": [
"logs.tree-tail-export"
],
"satisfied": true,
"source_sha": "0c0f494748ad9b72cb6a172beb08e08bebe3cc6b0a3b36085ecc09b29a9876aa",
"subsystem": "logs",
"title": "Log routing, relays, and the rendered rules"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/logs.*"
],
[
"forgectrl",
"src/main.c"
],
[
"forgectrl",
"src/settings.*"
]
],
"fingerprint": "868f8fd96979954ce6a471f4f4e4b3140f7b0cff4133f61e0ba37117c468dbcf",
"hardware": "api",
"id": "logs.level-settings",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928162331-3969",
"duration_s": 0,
"evidence": {
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T16:23:31Z"
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"pending_before": false,
"refused log_grblhal_disk=verbose": 400,
"refused log_kernel_remote=7": 400,
"refused syslog_port=70000": 400,
"refused syslog_proto=tls": 400,
"refused syslog_server=bad host name": 400,
"system_remote_before": "off"
},
"fingerprint": "868f8fd96979954ce6a471f4f4e4b3140f7b0cff4133f61e0ba37117c468dbcf",
"image": "20260928153805 (dev)",
"log": [
"16:40:28 start logs.level-settings (auto, api) in campaign c-20260928162331-3969",
"16:40:29 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:40:29 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"16:40:29 queued by the unattended queue opened 2026-09-28T16:23:31Z",
"16:40:29 baseline: pre: clean",
"16:40:29 POST /settings log_grblhal_disk=verbose -> 400",
"16:40:29 POST /settings log_kernel_remote=7 -> 400",
"16:40:29 POST /settings syslog_port=70000 -> 400",
"16:40:29 POST /settings syslog_proto=tls -> 400",
"16:40:29 POST /settings syslog_server=bad host name -> 400",
"16:40:29 POST /settings log_system_remote=warning -> 200",
"16:40:29 configured warning, effective off, pending_reboot True",
"16:40:29 restore log_system_remote -> 200",
"16:40:29 baseline: post: clean",
"16:40:29 result PASS"
],
"manifest_sha": "faf9563c750bb8bd4bfc8778b6af053cddb63fa335ab946caf2f71631ede740f",
"message": "",
"result": "PASS",
"test": "logs.level-settings",
"ts": "2026-09-28T16:40:29Z"
},
"requires": [
"logs.tree-tail-export",
"forgectrl.settings-bounds"
],
"satisfied": true,
"source_sha": "93428841c33335e8b55c4cf62f7c79166dd9cb95941e24c96ab00b12c0ea4e3b",
"subsystem": "logs",
"title": "Log level and remote-target settings"
},
{
"always": false,
"covers": [
[
"grblhal-glowforge",
"src/**"
],
[
"kernel-module-glowforge",
"**"
],
[
"forgectrl",
"src/super.*"
],
[
"forgectrl",
"src/liveness.*"
]
],
"fingerprint": "5e13ed8a22af0c60fd8cf15a279d5b461043d7ea3a289ab136a7b8d4930ef8f1",
"hardware": "api",
"id": "motion.pacing",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928162331-3969",
"duration_s": 15,
"evidence": {
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T16:23:31Z"
},
"controller_pid": 6363,
"final_drift_mm": 0.0,
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"held_state": "Hold:0",
"idle_cpu_pct": 1.0,
"mode": {
"detail": "already in grbl mode",
"found": "grbl",
"needs": "grbl",
"ok": true,
"switched": false
},
"moved_mm": 30.0,
"moving_cpu_pct": 32.0,
"parked_cpu_pct": 1.0
},
"fingerprint": "5e13ed8a22af0c60fd8cf15a279d5b461043d7ea3a289ab136a7b8d4930ef8f1",
"image": "20260928153805 (dev)",
"log": [
"16:32:30 start motion.pacing (auto, api) in campaign c-20260928162331-3969",
"16:32:30 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:32:30 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"16:32:30 queued by the unattended queue opened 2026-09-28T16:23:31Z",
"16:32:30 baseline: pre: clean",
"16:32:30 mode: test needs grbl - already in grbl mode",
"16:32:31 connect: Idle",
"16:32:34 [1] idle CPU = 1.0%",
"16:32:35 [3] state=Run CPU during move = 32.0%",
"16:32:40 [2] Hold:0: CPU parked in Hold = 1.0%",
"16:32:41 [4] start X=0.000 end X=30.000 moved=30.000 (expect 30.0)",
"16:32:45 PASS: idle 1.0%, moving 32.0%, parked 1.0%, hold/resume exact",
"16:32:45 baseline: post: clean",
"16:32:45 result PASS"
],
"manifest_sha": "faf9563c750bb8bd4bfc8778b6af053cddb63fa335ab946caf2f71631ede740f",
"message": "",
"result": "PASS",
"test": "motion.pacing",
"ts": "2026-09-28T16:32:45Z"
},
"requires": [
"kernel.latch-locked-idle"
],
"satisfied": true,
"source_sha": "2bd8e7d53f474c9bc6a62817d0f6b23111c59e278da86e36e4bb4201421cc3c7",
"subsystem": "motion",
"title": "Protocol-loop pacing (idle, parked, moving) and hold/resume position"
},
{
"always": false,
"covers": [
[
"grblhal-glowforge",
"src/**"
],
[
"kernel-module-glowforge",
"**"
],
[
"forgectrl",
"src/super.*"
],
[
"forgectrl",
"src/liveness.*"
]
],
"fingerprint": "775075b719aaf758350ea403f2421e70e27c3d9cc35dbe347542cdb0439ecaac",
"hardware": "api",
"id": "motion.jog-roundtrip",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928162331-3969",
"duration_s": 14,
"evidence": {
"accel_moving_legs": [
"X sanity 40mm back",
"X max-rate 60mm back",
"diag 40mm back"
],
"accel_overall": {
"errors": 0,
"p2p": [
2815,
1927
],
"samples": 17
},
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T16:23:31Z"
},
"drift_mm": 0.0,
"final": [
0.0,
0.0,
4.449
],
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"held_state": "Hold:0",
"max_rate_peak": 10500.0,
"mode": {
"detail": "already in grbl mode",
"found": "grbl",
"needs": "grbl",
"ok": true,
"switched": false
},
"moves": [
{
"accel_p2p": [
207,
740
],
"accel_samples": 2,
"leg": "out",
"name": "X sanity 40mm",
"peak": 2400.0,
"states": [
"Jog",
"Idle"
],
"t0": 1790613630.815507,
"t1": 1790613631.914311
},
{
"accel_p2p": [
2188,
694
],
"accel_samples": 3,
"leg": "back",
"name": "X sanity 40mm",
"peak": 2400.0,
"states": [
"Jog",
"Idle"
],
"t0": 1790613631.914536,
"t1": 1790613633.0135765
},
{
"accel_p2p": [
446,
568
],
"accel_samples": 3,
"leg": "out",
"name": "Y sanity 40mm",
"peak": 2400.0,
"states": [
"Jog",
"Idle"
],
"t0": 1790613633.0140278,
"t1": 1790613634.1156013
},
{
"accel_p2p": [
228,
149
],
"accel_samples": 2,
"leg": "back",
"name": "Y sanity 40mm",
"peak": 2400.0,
"states": [
"Jog",
"Idle"
],
"t0": 1790613634.115823,
"t1": 1790613635.2365348
},
{
"accel_p2p": [
73,
29
],
"accel_samples": 2,
"leg": "out",
"name": "X max-rate 60mm",
"peak": 10500.0,
"states": [
"Jog",
"Idle"
],
"t0": 1790613635.2367415,
"t1": 1790613635.9307194
},
{
"accel_p2p": [
982,
965
],
"accel_samples": 2,
"leg": "back",
"name": "X max-rate 60mm",
"peak": 10500.0,
"states": [
"Jog",
"Idle"
],
"t0": 1790613635.9309306,
"t1": 1790613636.6248052
},
{
"accel_p2p": [
0,
0
],
"accel_samples": 1,
"leg": "out",
"name": "diag 40mm",
"peak": 8000.0,
"states": [
"Jog",
"Idle"
],
"t0": 1790613636.6250172,
"t1": 1790613637.3186238
},
{
"accel_p2p": [
2115,
471
],
"accel_samples": 2,
"leg": "back",
"name": "diag 40mm",
"peak": 8000.0,
"states": [
"Jog",
"Idle"
],
"t0": 1790613637.3188293,
"t1": 1790613638.011381
}
],
"start": [
0.0,
0.0,
4.449
]
},
"fingerprint": "775075b719aaf758350ea403f2421e70e27c3d9cc35dbe347542cdb0439ecaac",
"image": "20260928153805 (dev)",
"log": [
"16:40:29 start motion.jog-roundtrip (auto, api) in campaign c-20260928162331-3969",
"16:40:30 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:40:30 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"16:40:30 queued by the unattended queue opened 2026-09-28T16:23:31Z",
"16:40:30 baseline: pre: clean",
"16:40:30 mode: test needs grbl - already in grbl mode",
"16:40:30 connect: Idle",
"16:40:31 X sanity 40mm out: peak 2400 mm/min, states ['Jog', 'Idle']; accel p2p x=207 y=740 over 2 samples",
"16:40:33 X sanity 40mm back: peak 2400 mm/min, states ['Jog', 'Idle']; accel p2p x=2188 y=694 over 3 samples",
"16:40:34 Y sanity 40mm out: peak 2400 mm/min, states ['Jog', 'Idle']; accel p2p x=446 y=568 over 3 samples",
"16:40:35 Y sanity 40mm back: peak 2400 mm/min, states ['Jog', 'Idle']; accel p2p x=228 y=149 over 2 samples",
"16:40:35 X max-rate 60mm out: peak 10500 mm/min, states ['Jog', 'Idle']; accel p2p x=73 y=29 over 2 samples",
"16:40:36 X max-rate 60mm back: peak 10500 mm/min, states ['Jog', 'Idle']; accel p2p x=982 y=965 over 2 samples",
"16:40:37 diag 40mm out: peak 8000 mm/min, states ['Jog', 'Idle']; accel p2p x=0 y=0 over 1 samples",
"16:40:38 diag 40mm back: peak 8000 mm/min, states ['Jog', 'Idle']; accel p2p x=2115 y=471 over 2 samples",
"16:40:38 accel over all 8 legs: p2p x=2815 y=1927 (17 samples, 0 errors); motion seen on 3 legs",
"16:40:39 after !: Hold:0",
"16:40:41 after ~: states ['Run', 'Idle']",
"16:40:42 final drift 0.000 mm (start (0.0, 0.0, 4.449), final (0.0, 0.0, 4.449))",
"16:40:43 PASS: 8 jogs, peak 10500 mm/min, hold parked, drift 0.000 mm, accel p2p 2815 over the jogs, motion on 3 of 8 legs",
"16:40:44 baseline: post: clean",
"16:40:44 result PASS"
],
"manifest_sha": "faf9563c750bb8bd4bfc8778b6af053cddb63fa335ab946caf2f71631ede740f",
"message": "",
"result": "PASS",
"test": "motion.jog-roundtrip",
"ts": "2026-09-28T16:40:44Z"
},
"requires": [
"kernel.latch-locked-idle"
],
"satisfied": true,
"source_sha": "850d216dc4a488e4bf070163cba03a2c5acc8c42ff29f6783cc87fed5f6b27f5",
"subsystem": "motion",
"title": "Motion quality: bounded jogs, max rate, diagonal, hold/resume"
},
{
"always": false,
"covers": [
[
"grblhal-glowforge",
"src/**"
],
[
"kernel-module-glowforge",
"**"
],
[
"forgectrl",
"src/super.*"
],
[
"forgectrl",
"src/liveness.*"
],
[
"forgectrl",
"src/main.c"
],
[
"forgectrl",
"src/settings.*"
]
],
"fingerprint": "32df7fb8c9fa627bcea54b20f53d1c88ac0b80709ddcb78b956345b2a870f36e",
"hardware": "api",
"id": "motion.microstep-modes",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928162331-3969",
"duration_s": 25,
"evidence": {
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T16:23:31Z"
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"mode": {
"detail": "already in grbl mode",
"found": "grbl",
"needs": "grbl",
"ok": true,
"switched": false
},
"modes": [
{
"$100": 53.333,
"$101": 53.333,
"accel_p2p": [
4073,
932
],
"accel_samples": 6,
"drift_mm": 0.0,
"kernel_out_mm": 39.99,
"mode": 8,
"peak": 9578.0,
"sysfs": {
"cnc/ramp_rate": "125000",
"cnc/step_freq": "28160",
"cnc/x_mode": "8",
"cnc/y_mode": "8"
},
"typed_100": 53.333
},
{
"$100": 106.667,
"$101": 106.667,
"accel_p2p": [
2565,
552
],
"accel_samples": 5,
"drift_mm": 0.0,
"kernel_out_mm": 40.0,
"mode": 16,
"peak": 9580.0,
"sysfs": {
"cnc/ramp_rate": "250000",
"cnc/step_freq": "56320",
"cnc/x_mode": "16",
"cnc/y_mode": "16"
},
"typed_100": 106.667
},
{
"$100": 213.33299,
"$101": 213.33299,
"accel_p2p": [
2133,
705
],
"accel_samples": 5,
"drift_mm": 0.0,
"kernel_out_mm": 40.0,
"mode": 32,
"peak": 9579.0,
"sysfs": {
"cnc/ramp_rate": "500000",
"cnc/step_freq": "112640",
"cnc/x_mode": "32",
"cnc/y_mode": "32"
},
"typed_100": 213.33299
}
],
"xy_microsteps_after": "32",
"xy_microsteps_before": "32"
},
"fingerprint": "32df7fb8c9fa627bcea54b20f53d1c88ac0b80709ddcb78b956345b2a870f36e",
"image": "20260928153805 (dev)",
"log": [
"16:40:44 start motion.microstep-modes (auto, api) in campaign c-20260928162331-3969",
"16:40:44 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:40:44 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"16:40:44 queued by the unattended queue opened 2026-09-28T16:23:31Z",
"16:40:44 baseline: pre: clean",
"16:40:44 mode: test needs grbl - already in grbl mode",
"16:40:44 --- x8 ---",
"16:40:47 baseline: /mode controller=running motion=verified",
"16:40:48 baseline: controller configured 1.0 s after running",
"16:40:48 connect: Idle",
"16:40:51 x8: out 39.990 mm by the kernel, peak 9578/9578 mm/min, drift 0.000 mm, accel p2p x=4073 y=932 over 6 samples",
"16:40:51 --- x16 ---",
"16:40:54 baseline: /mode controller=running motion=verified",
"16:40:55 baseline: controller configured 1.0 s after running",
"16:40:55 connect: Idle",
"16:40:58 x16: out 40.000 mm by the kernel, peak 9580/9580 mm/min, drift 0.000 mm, accel p2p x=2565 y=552 over 5 samples",
"16:40:58 --- x32 ---",
"16:41:01 baseline: /mode controller=running motion=verified",
"16:41:02 baseline: controller configured 1.0 s after running",
"16:41:02 connect: Idle",
"16:41:05 x32: out 40.000 mm by the kernel, peak 9579/9579 mm/min, drift 0.000 mm, accel p2p x=2133 y=705 over 5 samples",
"16:41:07 baseline: /mode controller=running motion=verified",
"16:41:08 baseline: controller configured 1.0 s after running",
"16:41:09 PASS: x8: 39.990 mm, drift 0.000, accel 4073; x16: 40.000 mm, drift 0.000, accel 2565; x32: 40.000 mm, drift 0.000, accel 2133",
"16:41:09 baseline: post: clean",
"16:41:09 result PASS"
],
"manifest_sha": "faf9563c750bb8bd4bfc8778b6af053cddb63fa335ab946caf2f71631ede740f",
"message": "",
"result": "PASS",
"test": "motion.microstep-modes",
"ts": "2026-09-28T16:41:09Z"
},
"requires": [
"motion.jog-roundtrip"
],
"satisfied": true,
"source_sha": "fd749af4d9b9015f91d9ff2f930659bcf73a77a6fbfa188f50a6e9dec1d3dc3e",
"subsystem": "motion",
"title": "XY microstep modes: the setting drives the drivers, the scale and the tick"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/super.c"
],
[
"forgectrl",
"src/liveness.c"
],
[
"kernel-module-glowforge",
"**"
]
],
"fingerprint": "da37f8e7553a6f868e37a92fc0449cf72c6a5ba2a3de5763d9376d5b4a74ba43",
"hardware": "api",
"id": "motion.liveness-probe",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928162331-3969",
"duration_s": 8,
"evidence": {
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T16:23:31Z"
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"masked_restart": {
"mode": {
"controller": "running",
"gated": false,
"local": false,
"mode": "grbl",
"motion": "verified",
"pid": 8518,
"why": ""
},
"motor_lock_after": "0",
"probe_lines": [
"2026-09-28T16:41:16.285336+00:00 forgectrl[8476] INFO super: liveness probe: MOTION OK - head accel p2p x=2251 y=1625 (moving>=800 dead<=250)"
]
},
"mode_after": {
"controller": "running",
"gated": false,
"local": false,
"mode": "grbl",
"motion": "verified",
"pid": 8392,
"why": ""
},
"mode_before": {
"controller": "running",
"gated": false,
"local": false,
"mode": "grbl",
"motion": "verified",
"pid": 8392,
"why": ""
}
},
"fingerprint": "da37f8e7553a6f868e37a92fc0449cf72c6a5ba2a3de5763d9376d5b4a74ba43",
"image": "20260928153805 (dev)",
"log": [
"16:41:09 start motion.liveness-probe (auto, api) in campaign c-20260928162331-3969",
"16:41:09 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:41:09 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"16:41:09 queued by the unattended queue opened 2026-09-28T16:23:31Z",
"16:41:09 baseline: pre: clean",
"16:41:09 mode: {'mode': 'grbl', 'controller': 'running', 'pid': 8392, 'motion': 'verified', 'gated': False, 'local': False, 'why': ''}",
"16:41:09 mode after: {'mode': 'grbl', 'controller': 'running', 'pid': 8392, 'motion': 'verified', 'gated': False, 'local': False, 'why': ''}",
"16:41:10 masked every axis (cnc/motor_lock=15); restarting forgectrl for a fresh probe",
"16:41:18 super: liveness probe: MOTION OK - head accel p2p x=2251 y=1625 (moving>=800 dead<=250)",
"16:41:18 kernel X 0.0 -> 0.0 mm across the probe (out and back)",
"16:41:18 PASS: masked restart probed MOTION OK on the first try, mask cleared, controller up",
"16:41:18 baseline: post: clean",
"16:41:18 result PASS"
],
"manifest_sha": "faf9563c750bb8bd4bfc8778b6af053cddb63fa335ab946caf2f71631ede740f",
"message": "",
"result": "PASS",
"test": "motion.liveness-probe",
"ts": "2026-09-28T16:41:18Z"
},
"requires": [
"kernel.latch-locked-idle"
],
"satisfied": true,
"source_sha": "b32e3b27cc9ab05c1a1918c6721a3496e3efcea82b331b17f5fbe6b45fa1a63e",
"subsystem": "motion",
"title": "Supervisor motion-liveness verdict"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/super.*"
],
[
"forgectrl",
"src/liveness.*"
],
[
"forgectrl",
"src/led.*"
],
[
"forgectrl",
"src/ui/panel.js"
]
],
"fingerprint": "128113bde256fb11ed6dcd7b5e0484bd73e4ef9b6e439cfbc7e4f35d602e8a1c",
"hardware": "api",
"id": "motion.gate-waits-for-lid",
"inherited": true,
"kind": "operator",
"record": {
"answers": [],
"campaign": "c-20260928162331-3969",
"duration_s": 15,
"evidence": {
"actions": [
{
"by": "fixture",
"channel": "lid",
"state": "open",
"took_s": 0.02,
"ts": "2026-09-28T16:41:18Z"
},
{
"by": "fixture",
"channel": "lid",
"state": "close",
"took_s": 0.28,
"ts": "2026-09-28T16:41:26Z"
}
],
"after_close": {
"controller": "running",
"gated": false,
"local": false,
"mode": "grbl",
"motion": "verified",
"pid": 8620,
"why": ""
},
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T16:23:31Z"
},
"close_to_running_s": 6.3,
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"led_running": [
0,
0,
0
],
"led_waiting": [
255,
255,
0
],
"probe_lines": [
"2026-09-28T16:41:31.274841+00:00 forgectrl[8562] INFO super: liveness probe: MOTION OK - head accel p2p x=2166 y=1825 (moving>=800 dead<=250)"
],
"waiting": {
"controller": "waiting",
"gated": false,
"local": false,
"mode": "grbl",
"motion": "unverified",
"pid": 0,
"why": "the lid is open"
}
},
"fingerprint": "128113bde256fb11ed6dcd7b5e0484bd73e4ef9b6e439cfbc7e4f35d602e8a1c",
"image": "20260928153805 (dev)",
"log": [
"16:41:18 start motion.gate-waits-for-lid (operator, api) in campaign c-20260928162331-3969",
"16:41:18 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:41:18 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"16:41:18 fixture: running unattended (no prompt can be answered)",
"16:41:18 queued by the unattended queue opened 2026-09-28T16:23:31Z",
"16:41:18 baseline: pre: clean",
"16:41:18 ACT lid open (fixture)",
"16:41:19 ACT lid open: done after 0.0 s",
"16:41:22 mode with the lid open: {'mode': 'grbl', 'controller': 'waiting', 'pid': 0, 'motion': 'unverified', 'gated': False, 'local': False, 'why': 'the lid is open'}",
"16:41:23 button LED targets while waiting (r, g, b): [255, 255, 0]",
"16:41:26 ACT lid close (fixture)",
"16:41:26 ACT lid close: done after 0.3 s",
"16:41:32 mode 6.3 s after the lid closed: {'mode': 'grbl', 'controller': 'running', 'pid': 8620, 'motion': 'verified', 'gated': False, 'local': False, 'why': ''}",
"16:41:34 baseline: post: clean",
"16:41:34 result PASS"
],
"manifest_sha": "faf9563c750bb8bd4bfc8778b6af053cddb63fa335ab946caf2f71631ede740f",
"message": "",
"result": "PASS",
"test": "motion.gate-waits-for-lid",
"ts": "2026-09-28T16:41:34Z"
},
"requires": [
"motion.liveness-probe"
],
"satisfied": true,
"source_sha": "36b4833d102146031339b017d06e7977d41c59116689e9ee594dfb227d632b42",
"subsystem": "motion",
"title": "The motion gate waits for the lid"
},
{
"always": false,
"covers": [
[
"grblhal-glowforge",
"src/**"
],
[
"kernel-module-glowforge",
"**"
],
[
"forgectrl",
"src/super.*"
],
[
"forgectrl",
"src/liveness.*"
]
],
"fingerprint": "c66b4468215801a35126e018dbf007de944641c5e0923dfbc7c21425a9d8e467",
"hardware": "api",
"id": "motion.cancel-abort",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928162331-3969",
"duration_s": 6,
"evidence": {
"abort_drift_after_recovery_mm": 0.0,
"abort_moved_mm": 10.041,
"abort_returned_home": false,
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T16:23:31Z"
},
"cancel_moved_mm": 17.198,
"final_drift_mm": 0.0,
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"mode": {
"detail": "already in grbl mode",
"found": "grbl",
"needs": "grbl",
"ok": true,
"switched": false
}
},
"fingerprint": "c66b4468215801a35126e018dbf007de944641c5e0923dfbc7c21425a9d8e467",
"image": "20260928153805 (dev)",
"log": [
"16:41:34 start motion.cancel-abort (auto, api) in campaign c-20260928162331-3969",
"16:41:34 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:41:34 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"16:41:34 queued by the unattended queue opened 2026-09-28T16:23:31Z",
"16:41:34 baseline: pre: clean",
"16:41:34 mode: test needs grbl - already in grbl mode",
"16:41:35 connect: Idle",
"16:41:35 jog cancel: moved 17.198 mm of 40 (state Idle)",
"16:41:37 ^X abort: state Alarm, moved 10.041 mm of 30, position retained (27.239, 0.0, 4.449)",
"16:41:37 $X -> ['ALARM:3', \"GrblHAL 1.1f ['$' or '$HELP' for help]\", \"[MSG:'$H'|'$X' to unlock]\", '[MSG:Caution: Unlocked]', 'ok']",
"16:41:39 after $X: (27.239, 0.0, 4.449) (moved 0.000 mm since the abort)",
"16:41:40 returned: drift 0.000 mm",
"16:41:41 baseline: post: clean",
"16:41:41 result PASS"
],
"manifest_sha": "faf9563c750bb8bd4bfc8778b6af053cddb63fa335ab946caf2f71631ede740f",
"message": "",
"result": "PASS",
"test": "motion.cancel-abort",
"ts": "2026-09-28T16:41:41Z"
},
"requires": [
"motion.pacing"
],
"satisfied": true,
"source_sha": "fa5054e9a7899e8072b4bb8d7db43af9ab8cc44ca93a6fcb21b2363ed96c82d7",
"subsystem": "motion",
"title": "Jog cancel and controlled abort recover cleanly"
},
{
"always": false,
"covers": [
[
"grblhal-glowforge",
"src/**"
],
[
"kernel-module-glowforge",
"**"
],
[
"forgectrl",
"src/super.*"
],
[
"forgectrl",
"src/liveness.*"
],
[
"forgectrl",
"src/main.c"
],
[
"forgectrl",
"init/**"
]
],
"fingerprint": "624be1e2c539ca08323b3f4b73f746e716d929b6ca6e340f7bcadf79749e4373",
"hardware": "api",
"id": "motion.deadman",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928162331-3969",
"duration_s": 45,
"evidence": {
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T16:23:31Z"
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"homing_kill": {
"homing_mode": "manual",
"kernel_state_at_respawn": "idle",
"mode_after": {
"controller": "running",
"gated": false,
"local": false,
"mode": "grbl",
"motion": "verified",
"pid": 8937,
"why": ""
},
"pulse_holders": [
"forgectrl",
"grblHAL_glowfor"
],
"respawn_s": 1.8,
"runner_gone_s": 1.7585113048553467,
"super_lines": [
"2026-09-28T16:42:25.209151+00:00 forgectrl[8822] WARNING super: the homing runner outlived its controller - stopping it"
]
},
"mode": {
"detail": "already in grbl mode",
"found": "grbl",
"needs": "grbl",
"ok": true,
"switched": false
},
"restart": {
"mode_after": {
"controller": "running",
"gated": false,
"local": false,
"mode": "grbl",
"motion": "verified",
"pid": 8888,
"why": ""
},
"rc": 0,
"replaced_at_idle": true,
"states": [
"Run",
"Idle"
]
},
"short_stall": {
"kernel_dx_mm": 30.0,
"state_after": "Idle",
"states": [
"Run",
"Idle"
],
"underruns": 0,
"warning": "2026-09-28T16:41:58.592972+00:00 grblhal[8715] WARNING gfstream: run: 92 late events clamped (max behind 91.9 ms, lead 10 ms) - step generation was starved of CPU"
},
"sigkill": {
"new": {
"controller": "running",
"gated": false,
"local": false,
"mode": "grbl",
"motion": "verified",
"pid": 8715,
"why": ""
},
"old_pid": 8620,
"respawn_s": 1.2,
"unlocked_seen": false
},
"sigstop": {
"after": {
"controller": "running",
"gated": false,
"local": false,
"mode": "grbl",
"motion": "verified",
"pid": 8715,
"why": ""
},
"halt_s": 0.2,
"kernel_state": "underrun",
"latch_locked": true,
"recovery_states": [
"Jog",
"Idle"
],
"ring_free_after_reset": 33521664,
"state_after_cont": "Alarm",
"underruns": 2,
"unlock_after_reset": [
"[MSG:Caution: Unlocked]",
"ok"
],
"unlock_before_reset": [
"ALARM:17",
"error:79"
]
}
},
"fingerprint": "624be1e2c539ca08323b3f4b73f746e716d929b6ca6e340f7bcadf79749e4373",
"image": "20260928153805 (dev)",
"log": [
"16:41:41 start motion.deadman (auto, api) in campaign c-20260928162331-3969",
"16:41:41 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:41:41 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"16:41:41 queued by the unattended queue opened 2026-09-28T16:23:31Z",
"16:41:41 baseline: pre: clean",
"16:41:41 mode: test needs grbl - already in grbl mode",
"16:41:42 connect: Idle",
"16:41:43 SIGKILL sent to controller pid 8620 mid-move",
"16:41:44 after SIGKILL: respawned as {'mode': 'grbl', 'controller': 'running', 'pid': 8715, 'motion': 'verified', 'gated': False, 'local': False, 'why': ''} in 1.2 s; latch unlocked seen: False",
"16:41:47 kernel X: 0.0 -> 0.0 mm",
"16:41:48 connect: Idle",
"16:41:49 SIGSTOP sent to controller pid 8715 mid-move",
"16:41:49 after SIGSTOP: kernel underrun in 0.2 s, latch locked True, underruns 1 -> 2",
"16:41:50 controller resumed: state Alarm",
"16:41:50 $X before the reset: ['ALARM:17', 'error:79']",
"16:41:52 after the soft reset: Alarm",
"16:41:52 $X after the reset: ['[MSG:Caution: Unlocked]', 'ok']",
"16:41:52 ring after the reset: free 33521664 (idle 33521664)",
"16:41:57 connect: Idle",
"16:41:58 SIGSTOP 100 ms sent to controller pid 8715 mid-move",
"16:42:04 short stall: states ['Run', 'Idle'], underruns +0, warning '2026-09-28T16:41:58.592972+00:00 grblhal[8715] WARNING gfstream: run: 92 late events clamped (max behind 91.9 ms, lead 10 ms) - step generation was starved of CPU', kernel dx 30.0 mm",
"16:42:07 connect: Idle",
"16:42:09 forgectrl restart mid-move -> rc 0",
"16:42:13 move after the restart: states ['Run', 'Idle']",
"16:42:16 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:42:21 mode after restart: {'mode': 'grbl', 'controller': 'running', 'pid': 8888, 'motion': 'verified', 'gated': False, 'local': False, 'why': ''}",
"16:42:21 retake: unmanaged pid 8715 finished the move; supervised pid 8888 started at idle",
"16:42:21 connect: Idle",
"16:42:25 SIGKILL sent to controller pid 8888 during $H (runner pid [8902])",
"16:42:26 kill during $H: runner gone in 1.7585113048553467 s, respawned as 8937, kernel idle, pulse held by ['forgectrl', 'grblHAL_glowfor']",
"16:42:26 restore homing_mode='manual' -> 200",
"16:42:26 PASS: kill respawned in 1.2 s, hang -> underrun in 0.2 s, short stall warned and completed, restart retook supervision (pid 8888), the kill during $H ended the runner (1.7585113048553467)",
"16:42:27 baseline: post: clean",
"16:42:27 result PASS"
],
"manifest_sha": "faf9563c750bb8bd4bfc8778b6af053cddb63fa335ab946caf2f71631ede740f",
"message": "",
"result": "PASS",
"test": "motion.deadman",
"ts": "2026-09-28T16:42:27Z"
},
"requires": [
"motion.cancel-abort",
"kernel.k1-k2"
],
"satisfied": true,
"source_sha": "336c36a4f2a16c92f91316dc17a4f83e7e53061ce3df3d33fb5b8a5d55b4fd8f",
"subsystem": "motion",
"title": "Dead-man: controller kill, controller hang, forgectrl restart mid-move, a kill during the web-service homing"
},
{
"always": false,
"covers": [
[
"grblhal-glowforge",
"src/**"
],
[
"kernel-module-glowforge",
"**"
],
[
"forgectrl",
"src/super.*"
],
[
"forgectrl",
"src/liveness.*"
]
],
"fingerprint": "d713b0690a98f7851881b2899e400fcf003011afecba6ae5bd269c17e7071513",
"hardware": "api",
"id": "motion.respawn-gate",
"inherited": true,
"kind": "operator",
"record": {
"answers": [],
"campaign": "c-20260928162331-3969",
"duration_s": 8,
"evidence": {
"actions": [
{
"by": "fixture",
"channel": "lid",
"state": "open",
"took_s": 0.02,
"ts": "2026-09-28T16:42:27Z"
},
{
"by": "fixture",
"channel": "lid",
"state": "close",
"took_s": 0.02,
"ts": "2026-09-28T16:42:35Z"
}
],
"after_close": {
"mode": {
"controller": "running",
"gated": false,
"local": false,
"mode": "grbl",
"motion": "verified",
"pid": 9001,
"why": ""
},
"running_s": 0.26584577560424805
},
"after_kill": {
"mode": {
"controller": "waiting",
"gated": false,
"local": false,
"mode": "grbl",
"motion": "verified",
"pid": 0,
"why": "the lid is open"
},
"waiting_s": 2.298335313796997
},
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T16:23:31Z"
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"mode": {
"detail": "already in grbl mode",
"found": "grbl",
"needs": "grbl",
"ok": true,
"switched": false
},
"probe_lines": []
},
"fingerprint": "d713b0690a98f7851881b2899e400fcf003011afecba6ae5bd269c17e7071513",
"image": "20260928153805 (dev)",
"log": [
"16:42:27 start motion.respawn-gate (operator, api) in campaign c-20260928162331-3969",
"16:42:27 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:42:27 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"16:42:27 fixture: running unattended (no prompt can be answered)",
"16:42:27 queued by the unattended queue opened 2026-09-28T16:23:31Z",
"16:42:27 baseline: pre: clean",
"16:42:27 mode: test needs grbl - already in grbl mode",
"16:42:27 ACT lid open (fixture)",
"16:42:27 ACT lid open: done after 0.0 s",
"16:42:28 SIGKILL sent to controller pid 8937 with the lid open",
"16:42:31 mode 2.3 s after the kill: {'mode': 'grbl', 'controller': 'waiting', 'pid': 0, 'motion': 'verified', 'gated': False, 'local': False, 'why': 'the lid is open'}",
"16:42:35 ACT lid close (fixture)",
"16:42:35 ACT lid close: done after 0.0 s",
"16:42:35 mode 0.3 s after the lid closed: {'mode': 'grbl', 'controller': 'running', 'pid': 9001, 'motion': 'verified', 'gated': False, 'local': False, 'why': ''}",
"16:42:35 PASS: the respawn waited 6.4 s for the lid, then came back verified in 0.3 s with no probe",
"16:42:35 baseline: leds/button_led_1: target 0, brightness 213; the fade from a level the machine itself ended, not a leftover",
"16:42:35 baseline: leds/button_led_2: target 0, brightness 213; the fade from a level the machine itself ended, not a leftover",
"16:42:35 baseline: post: clean",
"16:42:35 result PASS"
],
"manifest_sha": "faf9563c750bb8bd4bfc8778b6af053cddb63fa335ab946caf2f71631ede740f",
"message": "",
"result": "PASS",
"test": "motion.respawn-gate",
"ts": "2026-09-28T16:42:35Z"
},
"requires": [
"motion.deadman",
"motion.gate-waits-for-lid"
],
"satisfied": true,
"source_sha": "123119d87611a8c311d07478897ece329f437e176841ce20045dc1ebf909452a",
"subsystem": "motion",
"title": "A respawn waits for the lid the way a first spawn does"
},
{
"always": false,
"covers": [
[
"grblhal-glowforge",
"src/**"
],
[
"kernel-module-glowforge",
"**"
],
[
"forgectrl",
"src/super.*"
],
[
"forgectrl",
"src/liveness.*"
]
],
"fingerprint": "34c020a314896979438cd9351e215377edb2369fdc430b56061b8e811a3fda0a",
"hardware": "api",
"id": "motion.soft-limits",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928165212-b92e",
"duration_s": 82,
"evidence": {
"baseline": {
"post": [],
"pre": []
},
"envelope": {
"x": 508.0,
"y": 288.925
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"found": {
"gfcloud_home_x": "",
"gfcloud_home_y": "",
"homing_mode": "manual"
},
"gfhome_complete": "2026-09-28T16:53:05.439955+00:00 gfhome[11649] INFO gfhome:home homing complete (service quiet 10s, 9 motion windows)",
"homed": true,
"homing_s": 60.2,
"inside": [
"Run",
"Idle"
],
"jog": [
"error:15"
],
"kernel_back_mm": [
0.0,
0.0
],
"mode": {
"detail": "already in grbl mode",
"found": "grbl",
"needs": "grbl",
"ok": true,
"switched": false
},
"refused": [
{
"alarm": true,
"cmd": "G90 G1 X513.0 F600",
"moved_mm": 0.0,
"reply": [
"ALARM:2",
"[MSG:Reset to continue]"
],
"state": "Alarm"
},
{
"alarm": true,
"cmd": "G90 G1 Y293.9 F600",
"moved_mm": 0.0,
"reply": [
"ALARM:2",
"[MSG:Reset to continue]"
],
"state": "Alarm"
},
{
"alarm": true,
"cmd": "G90 G1 X-1 F600",
"moved_mm": 0.0,
"reply": [
"ALARM:2",
"[MSG:Reset to continue]"
],
"state": "Alarm"
}
],
"return": {
"counters_across_jog": [
[
0,
0,
0
],
[
4444,
-2896,
0
]
],
"counters_since_home": [
0,
0,
0
],
"mm": [
-20.831,
13.575
],
"session_travel_steps": [
-1111,
724
]
},
"short_motions": [],
"travel": {
"x": 495.0,
"y": 279.0
}
},
"fingerprint": "34c020a314896979438cd9351e215377edb2369fdc430b56061b8e811a3fda0a",
"image": "20260928153805 (dev)",
"log": [
"16:52:12 start motion.soft-limits (auto, api) in campaign c-20260928165212-b92e",
"16:52:12 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:52:12 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"16:52:12 baseline: pre: clean",
"16:52:12 mode: test needs grbl - already in grbl mode",
"16:52:13 connect: Idle",
"16:52:43 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:53:13 homing: homed=True after 60.2 s (kernel idle, grbl Idle)",
"16:53:13 gfhome: 2026-09-28T16:53:05.439955+00:00 gfhome[11649] INFO gfhome:home homing complete (service quiet 10s, 9 motion windows)",
"16:53:13 position counters re-zeroed at the starting position; the baseline expects (0,0,0) at the end",
"16:53:13 $H acknowledged: [MSG:] | ok",
"16:53:14 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:53:16 {'cmd': 'G90 G1 X513.0 F600', 'reply': ['ALARM:2', '[MSG:Reset to continue]'], 'alarm': True, 'moved_mm': 0.0, 'state': 'Alarm'}",
"16:53:20 {'cmd': 'G90 G1 Y293.9 F600', 'reply': ['ALARM:2', '[MSG:Reset to continue]'], 'alarm': True, 'moved_mm': 0.0, 'state': 'Alarm'}",
"16:53:25 {'cmd': 'G90 G1 X-1 F600', 'reply': ['ALARM:2', '[MSG:Reset to continue]'], 'alarm': True, 'moved_mm': 0.0, 'state': 'Alarm'}",
"16:53:30 restore homing_mode='manual' -> taken",
"16:53:30 restore gfcloud_home_x='' -> taken",
"16:53:30 restore gfcloud_home_y='' -> taken",
"16:53:31 the head is -20.831/13.575 mm from where the test found it",
"16:53:32 connect: Idle",
"16:53:34 position counters re-zeroed at the starting position; the baseline expects (0,0,0) at the end",
"16:53:34 head returned to where the test found it (20.831/-13.575 mm)",
"16:53:34 PASS: X max, Y max and X min refused with ALARM:2 and no motion, the jog refused with error 15, a move inside the bed ran",
"16:53:34 baseline: post: clean",
"16:53:34 result PASS"
],
"manifest_sha": "faf9563c750bb8bd4bfc8778b6af053cddb63fa335ab946caf2f71631ede740f",
"message": "",
"result": "PASS",
"test": "motion.soft-limits",
"ts": "2026-09-28T16:53:34Z"
},
"requires": [
"motion.jog-roundtrip",
"cloud.mode-switch"
],
"satisfied": true,
"source_sha": "861c0061a9387e067b91c97d669700c7da29916ea93a78715028852a348050a3",
"subsystem": "motion",
"title": "After a home the bed is the X/Y envelope"
},
{
"always": false,
"covers": [
[
"grblhal-glowforge",
"src/**"
],
[
"kernel-module-glowforge",
"**"
],
[
"forgectrl",
"src/super.*"
],
[
"forgectrl",
"src/liveness.*"
],
[
"grblhal-glowforge",
"src/glowforge_switches.c"
],
[
"grblhal-glowforge",
"src/glowforge_switch_map.h"
],
[
"grblhal-glowforge",
"src/glowforge_laser.c"
]
],
"fingerprint": "7dfd18b70c88e71add781ae163859e08a5533dba413cc7e5db1a647afc4b3f80",
"hardware": "api",
"id": "motion.button-hold-resume",
"inherited": true,
"kind": "operator",
"record": {
"answers": [],
"campaign": "c-20260928171100-3ff5",
"duration_s": 11,
"evidence": {
"actions": [
{
"by": "fixture",
"channel": "button",
"state": "press",
"took_s": 0.12,
"ts": "2026-09-28T17:12:39Z"
},
{
"by": "fixture",
"channel": "button",
"state": "press",
"took_s": 0.14,
"ts": "2026-09-28T17:12:39Z"
}
],
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T17:11:00Z"
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"held_at_mm": 1.195,
"held_state": "Hold:0",
"mode": {
"detail": "already in grbl mode",
"found": "grbl",
"needs": "grbl",
"ok": true,
"switched": false
},
"move_start": [
{
"after_s": 0.05,
"line": "G1X40F300",
"reply": [
"ok"
],
"state": "Run"
}
],
"moved_mm": 39.999,
"pause_message": true,
"resume_message": true,
"state_after_resume": "Run"
},
"fingerprint": "7dfd18b70c88e71add781ae163859e08a5533dba413cc7e5db1a647afc4b3f80",
"image": "20260928170058 (dev)",
"log": [
"17:12:38 start motion.button-hold-resume (operator, api) in campaign c-20260928171100-3ff5",
"17:12:38 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"17:12:38 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"17:12:38 fixture: running unattended (no prompt can be answered)",
"17:12:38 queued by the unattended queue opened 2026-09-28T17:11:00Z",
"17:12:38 baseline: pre: clean",
"17:12:38 mode: test needs grbl - already in grbl mode",
"17:12:38 connect: Idle",
"17:12:38 READY (fixture performs the step): On Ready the head starts an 8 s move along +X. Press the button ONCE while it moves; the job holds and the test sees it.",
"17:12:39 ACT button press (fixture)",
"17:12:39 ACT button press: done after 0.1 s",
"17:12:39 held: Hold:0 at 1.195 mm of 40; message seen: True",
"17:12:39 ACT button press (fixture)",
"17:12:39 ACT button press: done after 0.1 s",
"17:12:39 resumed: Run; message seen: True",
"17:12:47 move completed after pause/resume: 39.999 mm of 40",
"17:12:49 PASS: button press held the job (Hold:0), the next press resumed it, target reached",
"17:12:49 baseline: post: clean",
"17:12:49 result PASS"
],
"manifest_sha": "98f8c4dad7130ecf1fa44e5e0f1a1b53e6b9359f005f22a1ddbee496375d9a9e",
"message": "",
"result": "PASS",
"test": "motion.button-hold-resume",
"ts": "2026-09-28T17:12:49Z"
},
"requires": [
"motion.pacing"
],
"satisfied": true,
"source_sha": "d9ba573021f79f6b5892d7ea8c8b238f96db252ff1d5a853cca364cc14eac526",
"subsystem": "motion",
"title": "The button pauses and resumes a job"
},
{
"always": false,
"covers": [
[
"grblhal-glowforge",
"src/**"
],
[
"kernel-module-glowforge",
"**"
],
[
"forgectrl",
"src/super.*"
],
[
"forgectrl",
"src/liveness.*"
],
[
"grblhal-glowforge",
"src/glowforge_switches.c"
],
[
"grblhal-glowforge",
"src/glowforge_switch_map.h"
],
[
"grblhal-glowforge",
"src/glowforge_laser.c"
]
],
"fingerprint": "3bd26b5fd7450f435380ab74ead0a3df33f1e230a923f03112532f9025b801dd",
"hardware": "api",
"id": "motion.lid-cancel-home",
"inherited": true,
"kind": "operator",
"record": {
"answers": [],
"campaign": "c-20260928171100-3ff5",
"duration_s": 14,
"evidence": {
"actions": [
{
"by": "fixture",
"channel": "lid",
"state": "open",
"took_s": 0.02,
"ts": "2026-09-28T17:12:50Z"
},
{
"by": "fixture",
"channel": "lid",
"state": "close",
"took_s": 0.28,
"ts": "2026-09-28T17:12:53Z"
},
{
"by": "fixture",
"channel": "button",
"state": "press",
"took_s": 0.14,
"ts": "2026-09-28T17:12:57Z"
},
{
"by": "fixture",
"channel": "lid",
"state": "open",
"took_s": 0.02,
"ts": "2026-09-28T17:12:57Z"
},
{
"by": "fixture",
"channel": "lid",
"state": "close",
"took_s": 0.28,
"ts": "2026-09-28T17:13:00Z"
}
],
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T17:11:00Z"
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"hold_drift_mm": 0.037,
"hold_kernel_drift_mm": 0.03,
"hold_messages": [
"[MSG:Check Door]",
"[MSG:Warning: lid opened - job canceled, returning to the job start]",
"GrblHAL 1.1f ['$' or '$HELP' for help]",
"[MSG:Info: returned to the job start]"
],
"hold_pause_message": true,
"hold_returned_message": true,
"hold_start": [
0.038,
0.0,
4.449
],
"hold_state": "Hold:0",
"kernel_start": [
0.0,
0.0
],
"lid_at_return": false,
"lid_policy": "cancel",
"mode": {
"detail": "already in grbl mode",
"found": "grbl",
"needs": "grbl",
"ok": true,
"switched": false
},
"move_start": [
{
"after_s": 0.05,
"line": "G1X40F300",
"reply": [
"ok"
],
"state": "Run"
}
],
"running_drift_mm": 0.038,
"running_kernel_drift_mm": 0.04,
"running_messages": [
"[MSG:Check Door]",
"[MSG:Warning: lid opened - job canceled, returning to the job start]",
"GrblHAL 1.1f ['$' or '$HELP' for help]",
"[MSG:Info: returned to the job start]"
],
"running_returned_message": true,
"start": [
0.0,
0.0,
4.449
]
},
"fingerprint": "3bd26b5fd7450f435380ab74ead0a3df33f1e230a923f03112532f9025b801dd",
"image": "20260928170058 (dev)",
"log": [
"17:12:49 start motion.lid-cancel-home (operator, api) in campaign c-20260928171100-3ff5",
"17:12:49 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"17:12:49 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"17:12:49 fixture: running unattended (no prompt can be answered)",
"17:12:49 queued by the unattended queue opened 2026-09-28T17:11:00Z",
"17:12:49 baseline: pre: clean",
"17:12:49 mode: test needs grbl - already in grbl mode",
"17:12:50 connect: Idle",
"17:12:50 READY (fixture performs the step): On Ready the head starts an 8 s move along +X. Open the lid while it moves and leave it open until the head has come back on its own.",
"17:12:50 ACT lid open (fixture)",
"17:12:50 ACT lid open: done after 0.0 s",
"17:12:53 [running] controller: ['[MSG:Check Door]', '[MSG:Warning: lid opened - job canceled, returning to the job start]', \"GrblHAL 1.1f ['$' or '$HELP' for help]\", '[MSG:Info: returned to the job start]']",
"17:12:53 [running] back at the job start: drift 0.038 mm",
"17:12:53 kernel counters: start (0.00, 0.00) -> now (0.04, 0.00), drift 0.040 mm",
"17:12:53 ACT lid close (fixture)",
"17:12:54 ACT lid close: done after 0.3 s",
"17:12:56 READY (fixture performs the step): On Ready the head starts the 8 s move again. Press the button ONCE while it moves (the job pauses); then open the lid and leave it open until the head has come back.",
"17:12:57 ACT button press (fixture)",
"17:12:57 ACT button press: done after 0.1 s",
"17:12:57 paused: Hold:0; message seen: True",
"17:12:57 ACT lid open (fixture)",
"17:12:57 ACT lid open: done after 0.0 s",
"17:13:00 [hold] controller: ['[MSG:Check Door]', '[MSG:Warning: lid opened - job canceled, returning to the job start]', \"GrblHAL 1.1f ['$' or '$HELP' for help]\", '[MSG:Info: returned to the job start]']",
"17:13:00 [hold] back at the job start: drift 0.037 mm",
"17:13:00 kernel counters: start (0.04, 0.00) -> now (0.07, 0.00), drift 0.030 mm",
"17:13:00 ACT lid close (fixture)",
"17:13:00 ACT lid close: done after 0.3 s",
"17:13:03 PASS: lid open canceled the job from Run (drift 0.038 mm) and from the hold (drift 0.037 mm), reset without alarm, head returned to the start both times",
"17:13:04 baseline: head jogged back -0.075/-0.000 mm to its start",
"17:13:04 baseline: position: [16, 0, 0] (expected [0, 0, 0]) -> restored (jogged back -0.1/-0.0 mm); inside the 0.10 mm dead band, not a leftover",
"17:13:04 baseline: post: clean",
"17:13:04 result PASS"
],
"manifest_sha": "98f8c4dad7130ecf1fa44e5e0f1a1b53e6b9359f005f22a1ddbee496375d9a9e",
"message": "",
"result": "PASS",
"test": "motion.lid-cancel-home",
"ts": "2026-09-28T17:13:04Z"
},
"requires": [
"motion.pacing",
"motion.cancel-abort"
],
"satisfied": true,
"source_sha": "553794d44450266b4906cc77f4ab87d1d10c07cc7ae69650fd95b9ddf6d4de71",
"subsystem": "motion",
"title": "Lid open during a job - running or paused - cancels it and returns to the job start"
},
{
"always": false,
"covers": [
[
"grblhal-glowforge",
"src/**"
],
[
"kernel-module-glowforge",
"**"
],
[
"forgectrl",
"src/super.*"
],
[
"forgectrl",
"src/liveness.*"
],
[
"grblhal-glowforge",
"src/glowforge_switches.c"
],
[
"grblhal-glowforge",
"src/glowforge_switch_map.h"
],
[
"grblhal-glowforge",
"src/glowforge_laser.c"
]
],
"fingerprint": "f81fafa9ca74e753085c8dc4a8ecb730d16a21aec07a19e4460c7e0a2885ab9f",
"hardware": "api",
"id": "motion.interlock-cancel-home",
"inherited": true,
"kind": "operator",
"record": {
"answers": [],
"campaign": "c-20260928171100-3ff5",
"duration_s": 8,
"evidence": {
"actions": [
{
"by": "fixture",
"channel": "interlock",
"state": "open",
"took_s": 0.02,
"ts": "2026-09-28T17:13:05Z"
},
{
"by": "fixture",
"channel": "interlock",
"state": "close",
"took_s": 0.02,
"ts": "2026-09-28T17:13:09Z"
}
],
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T17:11:00Z"
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"interlock_drift_mm": 0.038,
"interlock_kernel_drift_mm": 0.04,
"interlock_messages": [
"[MSG:Check Door]",
"[MSG:Warning: interlock open - job canceled, returning to the job start]",
"GrblHAL 1.1f ['$' or '$HELP' for help]",
"[MSG:Info: returned to the job start]"
],
"interlock_ok_after_pull": false,
"interlock_returned_message": true,
"kernel_start": [
0.0,
0.0
],
"lid_policy": "cancel",
"mode": {
"detail": "already in grbl mode",
"found": "grbl",
"needs": "grbl",
"ok": true,
"switched": false
},
"move_start": [
{
"after_s": 0.05,
"line": "G1X60F300",
"reply": [
"ok"
],
"state": "Run"
}
],
"restored": {
"interlock_ok": true,
"lid": true
},
"start": [
0.0,
0.0,
4.449
],
"switches_at_return": {
"interlock_ok": false,
"lid": true
}
},
"fingerprint": "f81fafa9ca74e753085c8dc4a8ecb730d16a21aec07a19e4460c7e0a2885ab9f",
"image": "20260928170058 (dev)",
"log": [
"17:13:04 start motion.interlock-cancel-home (operator, api) in campaign c-20260928171100-3ff5",
"17:13:04 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"17:13:04 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"17:13:04 fixture: running unattended (no prompt can be answered)",
"17:13:04 queued by the unattended queue opened 2026-09-28T17:11:00Z",
"17:13:05 baseline: pre: clean",
"17:13:05 mode: test needs grbl - already in grbl mode",
"17:13:05 connect: Idle",
"17:13:05 READY (fixture performs the step): On Ready the head starts a 12 s move along +X. Open the interlock loop while it moves and leave it open until the head has come back on its own.",
"17:13:05 ACT interlock open (fixture)",
"17:13:05 ACT interlock open: done after 0.0 s",
"17:13:09 [interlock] controller: ['[MSG:Check Door]', '[MSG:Warning: interlock open - job canceled, returning to the job start]', \"GrblHAL 1.1f ['$' or '$HELP' for help]\", '[MSG:Info: returned to the job start]']",
"17:13:09 [interlock] back at the job start: drift 0.038 mm",
"17:13:09 kernel counters: start (0.00, 0.00) -> now (0.04, 0.00), drift 0.040 mm",
"17:13:09 at the end of the park: {'lid': True, 'interlock_ok': False}",
"17:13:09 ACT interlock close (fixture)",
"17:13:09 ACT interlock close: done after 0.0 s",
"17:13:11 PASS: interlock open canceled the job with its own reason and the head returned to the start (drift 0.038 mm) with the loop still open",
"17:13:12 baseline: head jogged back -0.038/-0.000 mm to its start",
"17:13:12 baseline: position: [8, 0, 0] (expected [0, 0, 0]) -> restored (jogged back -0.0/-0.0 mm); inside the 0.10 mm dead band, not a leftover",
"17:13:12 baseline: post: clean",
"17:13:12 result PASS"
],
"manifest_sha": "98f8c4dad7130ecf1fa44e5e0f1a1b53e6b9359f005f22a1ddbee496375d9a9e",
"message": "",
"result": "PASS",
"test": "motion.interlock-cancel-home",
"ts": "2026-09-28T17:13:12Z"
},
"requires": [
"motion.lid-cancel-home"
],
"satisfied": true,
"source_sha": "6605cd28a1f419530afee77bdc3792e7096f5d99b551b3db2ce9d4807c77a507",
"subsystem": "motion",
"title": "The interlock loop cancels a job like the lid and returns to the job start"
},
{
"always": false,
"covers": [
[
"grblhal-glowforge",
"src/**"
],
[
"kernel-module-glowforge",
"**"
],
[
"forgectrl",
"src/super.*"
],
[
"forgectrl",
"src/liveness.*"
],
[
"grblhal-glowforge",
"src/glowforge_switches.c"
],
[
"grblhal-glowforge",
"src/glowforge_switch_map.h"
],
[
"grblhal-glowforge",
"src/glowforge_laser.c"
],
[
"forgectrl",
"src/settings.*"
]
],
"fingerprint": "f8af5571cc1827b015e05a402a4827a33d44325d47076cc0ffec128423f1f94c",
"hardware": "api",
"id": "motion.lid-policy-hold",
"inherited": true,
"kind": "operator",
"record": {
"answers": [],
"campaign": "c-20260928171100-3ff5",
"duration_s": 13,
"evidence": {
"actions": [
{
"by": "fixture",
"channel": "lid",
"state": "open",
"took_s": 0.02,
"ts": "2026-09-28T17:13:14Z"
},
{
"by": "fixture",
"channel": "lid",
"state": "close",
"took_s": 0.28,
"ts": "2026-09-28T17:13:14Z"
}
],
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T17:11:00Z"
},
"door_state": "Door:2",
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"lid_policy_before": "",
"lid_policy_in_force": "cancel",
"lid_policy_restored": "",
"messages": [
"[MSG:Check Door]"
],
"mode": {
"detail": "already in grbl mode",
"found": "grbl",
"needs": "grbl",
"ok": true,
"switched": false
},
"move_start": [
{
"after_s": 0.05,
"line": "G1X40F300",
"reply": [
"ok"
],
"state": "Run"
}
],
"moved_mm": 39.999,
"parked_at": [
1.097,
0.0,
4.449
],
"state_after_close": "Door:0",
"states_after_resume": [
"Run",
"Idle"
]
},
"fingerprint": "f8af5571cc1827b015e05a402a4827a33d44325d47076cc0ffec128423f1f94c",
"image": "20260928170058 (dev)",
"log": [
"17:13:12 start motion.lid-policy-hold (operator, api) in campaign c-20260928171100-3ff5",
"17:13:13 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"17:13:13 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"17:13:13 fixture: running unattended (no prompt can be answered)",
"17:13:13 queued by the unattended queue opened 2026-09-28T17:11:00Z",
"17:13:13 baseline: pre: clean",
"17:13:13 mode: test needs grbl - already in grbl mode",
"17:13:13 connect: Idle",
"17:13:13 READY (fixture performs the step): On Ready the head starts an 8 s move along +X. Open the lid while it moves; the job parks in the door state and waits.",
"17:13:14 ACT lid open (fixture)",
"17:13:14 ACT lid open: done after 0.0 s",
"17:13:14 parked in Door:2 at (1.097, 0.0, 4.449)",
"17:13:14 ACT lid close (fixture)",
"17:13:14 ACT lid close: done after 0.3 s",
"17:13:15 after the lid closed: Door:0 (a cycle start is needed)",
"17:13:23 finished: moved 39.999 mm of 40 (states ['Run', 'Idle'])",
"17:13:26 lid_policy restored to ",
"17:13:26 PASS: lid_policy=hold parked the job in Door and the cycle start finished it (39.999 mm)",
"17:13:26 baseline: post: clean",
"17:13:26 result PASS"
],
"manifest_sha": "98f8c4dad7130ecf1fa44e5e0f1a1b53e6b9359f005f22a1ddbee496375d9a9e",
"message": "",
"result": "PASS",
"test": "motion.lid-policy-hold",
"ts": "2026-09-28T17:13:26Z"
},
"requires": [
"motion.lid-cancel-home"
],
"satisfied": true,
"source_sha": "18479eae70743e72560d4af4478acb10f3206add6aaca34c206f90697773d8b9",
"subsystem": "motion",
"title": "lid_policy=hold parks the job in Door and a cycle start resumes it"
},
{
"always": false,
"covers": [
[
"grblhal-glowforge",
"src/**"
],
[
"kernel-module-glowforge",
"**"
],
[
"forgectrl",
"src/super.*"
],
[
"forgectrl",
"src/liveness.*"
]
],
"fingerprint": "94630045098226a0211aedbddababeceb96568e17ea7830b8d9c205033ddd10d",
"hardware": "api",
"id": "motion.step-timing-under-load",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928171100-3ff5",
"duration_s": 30,
"evidence": {
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T17:11:00Z"
},
"clamp_lines": [],
"controller_cpu_pct": 30.3,
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"hog_nice": 5,
"legs": 20,
"mode": {
"detail": "already in grbl mode",
"found": "grbl",
"needs": "grbl",
"ok": true,
"switched": false
},
"motion_s": 26.6,
"rt_priorities": [
9,
10
],
"threads": 4
},
"fingerprint": "94630045098226a0211aedbddababeceb96568e17ea7830b8d9c205033ddd10d",
"image": "20260928170058 (dev)",
"log": [
"17:13:26 start motion.step-timing-under-load (auto, api) in campaign c-20260928171100-3ff5",
"17:13:26 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"17:13:26 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"17:13:26 queued by the unattended queue opened 2026-09-28T17:11:00Z",
"17:13:26 baseline: pre: clean",
"17:13:26 mode: test needs grbl - already in grbl mode",
"17:13:26 controller threads: 4, SCHED_FIFO priorities: [9, 10]",
"17:13:26 CPU hog started (pid 2011, nice 5)",
"17:13:27 connect: Idle",
"17:13:54 20 legs in 26.6 s, controller CPU 30.3 %",
"17:13:56 CPU hog stopped",
"17:13:56 PASS: 20 legs at 2000 mm/min against a nice-5 CPU hog, no clamped events",
"17:13:56 baseline: post: clean",
"17:13:56 result PASS"
],
"manifest_sha": "98f8c4dad7130ecf1fa44e5e0f1a1b53e6b9359f005f22a1ddbee496375d9a9e",
"message": "",
"result": "PASS",
"test": "motion.step-timing-under-load",
"ts": "2026-09-28T17:13:56Z"
},
"requires": [
"kernel.latch-locked-idle",
"motion.jog-roundtrip"
],
"satisfied": true,
"source_sha": "c6d56ad0d6eb256fc5a86dac7815faf32189ad926dccfa98f50df86eb3a70e36",
"subsystem": "motion",
"title": "Step timing holds while userspace competes for the core"
},
{
"always": false,
"covers": [
[
"grblhal-glowforge",
"src/**"
],
[
"kernel-module-glowforge",
"**"
],
[
"forgectrl",
"src/super.*"
],
[
"forgectrl",
"src/liveness.*"
],
[
"forgectrl",
"src/status.*"
],
[
"forgectrl",
"src/wizdark.*"
]
],
"fingerprint": "d5b9a812f741c02177861a5b89aa470d868099c32b3b98e032783d5faeb7031b",
"hardware": "takeover",
"id": "motion.release",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928171100-3ff5",
"duration_s": 26,
"evidence": {
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T17:11:00Z"
},
"elapsed_s": 19.2,
"energized_currents": [
"33",
"5"
],
"error": "",
"faults_energized": 0,
"faults_released": 0,
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"homed_axes_released": 4,
"kernel_position": [
[
0,
0,
0,
6223214,
6223214
],
[
0,
0,
0,
6223214,
6223214
]
],
"kernel_state_released": "idle",
"log": [
"00:06 liveness probe: head accel p2p x=3271 y=1841 (moving>=800 dead<=250)",
"00:08 lens reference pass 1: 0",
"00:09 lens reference pass 2: 0",
"00:10 lens reference pass 3: 0",
"00:11 lens reference pass 4: 0",
"00:12 lens reference pass 5: 0",
"00:13 at rest: accelerometer low-passed p2p x 206 y 223 (rms 157 99) over 180 samples",
"00:14 +X: accelerometer low-passed p2p x 2218 y 807 (rms 795 369, raw p2p 4589 2333, 194 sampl",
"00:16 -X: accelerometer low-passed p2p x 2559 y 843 (rms 801 447, raw p2p 4244 3412, 191 sampl",
"00:17 +Y: accelerometer low-passed p2p x 383 y 1658 (rms 238 471, raw p2p 1616 3345, 202 sampl",
"00:18 -Y: accelerometer low-passed p2p x 452 y 1354 (rms 218 447, raw p2p 1474 2502, 189 sampl"
],
"mode": {
"detail": "already in grbl mode",
"found": "grbl",
"needs": "grbl",
"ok": true,
"switched": false
},
"mode_cloud_released": {
"body": "the X and Y motors are released: energize them first",
"cloud_enabled": true,
"status": 409
},
"moves": {
"+X": {
"crash_event": false,
"p2p_lp_x": 2218,
"p2p_lp_y": 807,
"p2p_x": 4589,
"p2p_y": 2333,
"rms_x": 795.0,
"rms_y": 369.0,
"samples": 194,
"witnessed": true
},
"+Y": {
"crash_event": false,
"p2p_lp_x": 383,
"p2p_lp_y": 1658,
"p2p_x": 1616,
"p2p_y": 3345,
"rms_x": 238.0,
"rms_y": 471.0,
"samples": 202,
"witnessed": true
},
"-X": {
"crash_event": false,
"p2p_lp_x": 2559,
"p2p_lp_y": 843,
"p2p_x": 4244,
"p2p_y": 3412,
"rms_x": 801.0,
"rms_y": 447.0,
"samples": 191,
"witnessed": true
},
"-Y": {
"crash_event": false,
"p2p_lp_x": 452,
"p2p_lp_y": 1354,
"p2p_x": 1474,
"p2p_y": 2502,
"rms_x": 218.0,
"rms_y": 447.0,
"samples": 189,
"witnessed": true
}
},
"phases": [
"stopping the motion controller",
"rail up, the liveness probe",
"the lens hall reference",
"the lens finds its reference on the hall sensor: pass 2 of 5",
"the lens finds its reference on the hall sensor: pass 3 of 5",
"the lens finds its reference on the hall sensor: pass 4 of 5",
"starting the controller in loopback posture",
"the head at rest",
"jog +X",
"jog -X",
"jog +Y",
"jog -Y"
],
"probe": "head accel p2p x=3271 y=1841 (moving>=800 dead<=250)",
"rail_lines": [
5,
5
],
"refusals": {
"$J=G91X10F2400": "error:8",
"$X": "error:9",
"G0X10": "error:9",
"^X then $X": "error:9"
},
"released_accel_p2p": [
422,
34,
3
],
"released_currents": [
"0",
"0"
],
"result": {
"moves": {
"+X": {
"crash_event": false,
"p2p_lp_x": 2218,
"p2p_lp_y": 807,
"p2p_x": 4589,
"p2p_y": 2333,
"rms_x": 795.0,
"rms_y": 369.0,
"samples": 194,
"witnessed": true
},
"+Y": {
"crash_event": false,
"p2p_lp_x": 383,
"p2p_lp_y": 1658,
"p2p_x": 1616,
"p2p_y": 3345,
"rms_x": 238.0,
"rms_y": 471.0,
"samples": 202,
"witnessed": true
},
"-X": {
"crash_event": false,
"p2p_lp_x": 2559,
"p2p_lp_y": 843,
"p2p_x": 4244,
"p2p_y": 3412,
"rms_x": 801.0,
"rms_y": 447.0,
"samples": 191,
"witnessed": true
},
"-Y": {
"crash_event": false,
"p2p_lp_x": 452,
"p2p_lp_y": 1354,
"p2p_x": 1474,
"p2p_y": 2502,
"rms_x": 218.0,
"rms_y": 447.0,
"samples": 189,
"witnessed": true
}
},
"probe": "head accel p2p x=3271 y=1841 (moving>=800 dead<=250)",
"rail": "up",
"rest": {
"p2p_lp_x": 206,
"p2p_lp_y": 223,
"p2p_x": 975,
"p2p_y": 610,
"rms_x": 157.0,
"rms_y": 99.0,
"samples": 180
},
"z_passes": [
0,
0,
0,
0,
0
],
"z_referenced": true
},
"started": true,
"state_after_reset": "Alarm",
"state_energized": "Idle",
"state_released": "Alarm"
},
"fingerprint": "d5b9a812f741c02177861a5b89aa470d868099c32b3b98e032783d5faeb7031b",
"image": "20260928170058 (dev)",
"log": [
"17:13:57 start motion.release (auto, takeover) in campaign c-20260928171100-3ff5",
"17:13:57 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"17:13:57 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"17:13:57 queued by the unattended queue opened 2026-09-28T17:11:00Z",
"17:13:57 baseline: pre: clean",
"17:13:57 mode: test needs grbl - already in grbl mode",
"17:13:58 connect: Idle",
"17:13:59 $MD: step currents ['0', '0'], Alarm, cnc/state idle, faults 0, homed_axes 4",
"17:14:03 refused while released: {'$J=G91X10F2400': 'error:8', 'G0X10': 'error:9', '$X': 'error:9', '^X then $X': 'error:9'}; accel p2p x=422 y=34 over 3 samples; kernel record (0, 0, 0, 6223214, 6223214) -> (0, 0, 0, 6223214, 6223214)",
"17:14:03 POST /mode controller=cloud while released -> 409 the X and Y motors are released: energize them first",
"17:14:04 NOTICE: The head moves 50 mm each way on X and on Y. Keep the bed clear.",
"17:14:04 POST /wiz/motion/start -> 200 {'started': True, 'id': 'motion'}",
"17:14:04 motion: stopping the motion controller",
"17:14:05 motion: rail up, the liveness probe",
"17:14:10 motion: the lens hall reference",
"17:14:12 motion: the lens finds its reference on the hall sensor: pass 2 of 5",
"17:14:13 motion: the lens finds its reference on the hall sensor: pass 3 of 5",
"17:14:14 motion: the lens finds its reference on the hall sensor: pass 4 of 5",
"17:14:16 motion: starting the controller in loopback posture",
"17:14:16 prompt jogs (continue): The head moves 50 mm each way on X, then on Y, at 3000 mm/min. Keep the bed clear and the lid closed.",
"17:14:17 motion: the head at rest",
"17:14:18 motion: jog +X",
"17:14:19 motion: jog -X",
"17:14:20 motion: jog +Y",
"17:14:21 motion: jog -Y",
"17:14:23 after energize: probe 'head accel p2p x=3271 y=1841 (moving>=800 dead<=250)', moves {'+X': True, '-X': True, '+Y': True, '-Y': True}",
"17:14:23 PASS: released with the rail untouched, every motion refused and nothing shipped, energized with no fault, and the liveness probe and the witnessed jogs say the drivers are alive",
"17:14:23 baseline: post: clean",
"17:14:23 result PASS"
],
"manifest_sha": "98f8c4dad7130ecf1fa44e5e0f1a1b53e6b9359f005f22a1ddbee496375d9a9e",
"message": "",
"result": "PASS",
"test": "motion.release",
"ts": "2026-09-28T17:14:23Z"
},
"requires": [
"motion.jog-roundtrip"
],
"satisfied": true,
"source_sha": "c895663a1b37796aa7a08eb6edf4b399341061dfecd5965a688ea0ac78fb5020",
"subsystem": "motion",
"title": "Motor release: nothing moves a released gantry, only the operator energizes it"
},
{
"always": false,
"covers": [
[
"grblhal-glowforge",
"src/**"
],
[
"kernel-module-glowforge",
"**"
],
[
"forgectrl",
"src/super.*"
],
[
"forgectrl",
"src/liveness.*"
],
[
"forgectrl",
"src/status.*"
],
[
"forgectrl",
"src/main.c"
]
],
"fingerprint": "e2e45ea8a02a40ab11d5bcfdcab8006db3fab006337153c961883935b73c934d",
"hardware": "api",
"id": "homing.manual",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928171100-3ff5",
"duration_s": 11,
"evidence": {
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T17:11:00Z"
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"found": {
"homing_mode": "manual",
"manual_home_x": "",
"manual_home_y": ""
},
"home_source": "manual",
"homed_axes": 7,
"kernel_position": [
[
6400,
0,
0,
113375,
113375
],
[
0,
0,
0,
113375,
113375
]
],
"mode": {
"detail": "already in grbl mode",
"found": "grbl",
"needs": "grbl",
"ok": true,
"switched": false
},
"mpos": [
0.0,
0.0,
4.449
],
"offset_kernel_position": [
[
0,
0,
0,
113375,
113375
],
[
1067,
640,
0,
154890,
154890
]
],
"offset_mpos": [
0.0,
0.0,
4.449
],
"offset_past_envelope": "error:15",
"offset_pos": {
"x": -0.0,
"y": 0.0,
"z": 4.45
},
"offset_said": [
"[MSG:Info: Manual home: the head is at X-5.002 Y-3.000; moving it to the origin]"
],
"offset_state": "Idle",
"past_envelope": "error:15",
"pos": {
"x": 0.0,
"y": 0.0,
"z": 4.45
},
"state": "Idle"
},
"fingerprint": "e2e45ea8a02a40ab11d5bcfdcab8006db3fab006337153c961883935b73c934d",
"image": "20260928170058 (dev)",
"log": [
"17:14:23 start homing.manual (auto, api) in campaign c-20260928171100-3ff5",
"17:14:24 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"17:14:24 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"17:14:24 queued by the unattended queue opened 2026-09-28T17:11:00Z",
"17:14:24 baseline: pre: clean",
"17:14:24 mode: test needs grbl - already in grbl mode",
"17:14:24 connect: Idle",
"17:14:28 $H: Idle MPos (0.0, 0.0, 4.449); kernel record (6400, 0, 0, 113375, 113375) -> (0, 0, 0, 113375, 113375); forgectrl homed_axes 7 source manual pos {'x': 0.0, 'y': 0.0, 'z': 4.45}",
"17:14:31 $H with offset (5.0, 3.0): Idle MPos (0.0, 0.0, 4.449); kernel record (0, 0, 0, 113375, 113375) -> (1067, 640, 0, 154890, 154890); forgectrl pos {'x': -0.0, 'y': 0.0, 'z': 4.45}",
"17:14:31 restore homing_mode='manual' -> 200",
"17:14:31 restore manual_home_x='' -> 200",
"17:14:31 restore manual_home_y='' -> 200",
"17:14:32 connect: Idle",
"17:14:35 position counters re-zeroed at the starting position; the baseline expects (0,0,0) at the end",
"17:14:35 PASS: a manual home with no offset shipped nothing and declared X0 Y0; with (5.0, 3.0) it declared minus that and jogged to X0 Y0 before answering; the soft limits start at the origin, Z was kept, and the home reads back as manual",
"17:14:35 baseline: post: clean",
"17:14:35 result PASS"
],
"manifest_sha": "98f8c4dad7130ecf1fa44e5e0f1a1b53e6b9359f005f22a1ddbee496375d9a9e",
"message": "",
"result": "PASS",
"test": "homing.manual",
"ts": "2026-09-28T17:14:35Z"
},
"requires": [
"motion.jog-roundtrip"
],
"satisfied": true,
"source_sha": "b5bac778c483dc908a7b5cdfcacf620fd611ff9191bfef4fd46c14a32b7ad43e",
"subsystem": "motion",
"title": "Manual home: $H declares the gantry-stop position and jogs to an offset origin"
},
{
"always": false,
"covers": [
[
"grblhal-glowforge",
"src/**"
],
[
"kernel-module-glowforge",
"**"
],
[
"forgectrl",
"src/super.*"
],
[
"forgectrl",
"src/liveness.*"
],
[
"forgectrl",
"src/grblport.*"
],
[
"forgectrl",
"src/main.c"
],
[
"forgectrl",
"src/status.*"
]
],
"fingerprint": "3cc21bb10f32d520533879860f3128606c43de1cad6d6363f4168404cd8eee67",
"hardware": "api",
"id": "motion.port-jog",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928171100-3ff5",
"duration_s": 19,
"evidence": {
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T17:11:00Z"
},
"cancel": [
44.0,
54.4
],
"energized": {
"currents": [
"33",
"5"
],
"faults": 0,
"status": false
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"jog": {
"kernel": [
0.0,
10.0
],
"port_mpos": [
9.998,
0.0,
4.449
],
"sender": true
},
"jog_released": [
409,
"the X and Y motors are released: energize them first"
],
"mode": {
"detail": "already in grbl mode",
"found": "grbl",
"needs": "grbl",
"ok": true,
"switched": false
},
"past_bound": [
400,
"one jog moves X and Y at most 100 mm"
],
"poll": {
"kernel": [
14.0,
44.0
],
"oks": 14,
"polls": 14,
"polls_in_jog": 5
},
"port_kernel_drift_mm": 0.0,
"released": {
"currents": [
"0",
"0"
],
"port": true,
"status": true
},
"sender_first": {
"kernel": [
54.4,
87.4
],
"reply": [
"[MSG:Panel jog]",
"ok"
]
}
},
"fingerprint": "3cc21bb10f32d520533879860f3128606c43de1cad6d6363f4168404cd8eee67",
"image": "20260928170058 (dev)",
"log": [
"17:14:35 start motion.port-jog (auto, api) in campaign c-20260928171100-3ff5",
"17:14:36 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"17:14:36 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"17:14:36 queued by the unattended queue opened 2026-09-28T17:11:00Z",
"17:14:36 baseline: pre: clean",
"17:14:36 mode: test needs grbl - already in grbl mode",
"17:14:36 connect: Idle",
"17:14:38 port jog +10: kernel X 0.000 -> 10.000, port state {'state': 'Idle', 'sender': True, 'port_jog': False, 'released': False, 'mpos': [9.998, 0.0, 4.449], 'homed': 4, 'envelope_open': False, 'mcode': None, 'sender_out': False, 'tray': 'in'}",
"17:14:45 '?'+EOL poll: 8 of 8 jogs accepted; a 30 mm jog moved 30.000 with 5 polls into it; 14 polls drew 14 oks",
"17:14:47 canceled a 40 mm jog at 10.400 mm",
"17:14:49 the client's line during a port jog drew ['[MSG:Panel jog]', 'ok']; the jog stopped at 33.000 of 100",
"17:14:55 kernel counters: start (0.00, 0.00) -> now (0.00, 0.00), drift 0.000 mm",
"17:14:55 PASS: the port jogged beside the client, the cancel and the client's own line each stopped a jog short, the bound held, and the release and the energize went through their routes",
"17:14:55 baseline: post: clean",
"17:14:55 result PASS"
],
"manifest_sha": "98f8c4dad7130ecf1fa44e5e0f1a1b53e6b9359f005f22a1ddbee496375d9a9e",
"message": "",
"result": "PASS",
"test": "motion.port-jog",
"ts": "2026-09-28T17:14:55Z"
},
"requires": [
"motion.jog-roundtrip"
],
"satisfied": true,
"source_sha": "e3b760eed1d4c48c7a1a26180cfb8e80828b7e3a2542e82438bc9e13cbbc9107",
"subsystem": "motion",
"title": "The controller port: the panel jogs beside a connected Grbl client"
},
{
"always": false,
"covers": [
[
"grblhal-glowforge",
"src/**"
],
[
"kernel-module-glowforge",
"**"
],
[
"forgectrl",
"src/super.*"
],
[
"forgectrl",
"src/liveness.*"
],
[
"forgectrl",
"src/jobrun.*"
],
[
"forgectrl",
"src/jobpost.*"
],
[
"forgectrl",
"src/jobstream.*"
],
[
"forgectrl",
"src/lease.*"
],
[
"forgectrl",
"src/main.c"
],
[
"forgectrl",
"src/status.*"
]
],
"fingerprint": "1ff9125ca3a8648fcfa0aea614d6b27471196fa259c8012d341a12365e1594da",
"hardware": "api",
"id": "motion.job",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928171100-3ff5",
"duration_s": 10,
"evidence": {
"abort": {
"controller": "Alarm",
"moved_mm": 9.79,
"record": {
"acked": 4,
"elapsed_s": 2,
"emission": {
"hv_max": 0,
"laser_on_samples": 0,
"lit_s": 0.0,
"samples": 10,
"thermopile_delta": 0
},
"lines": 4,
"lit": false,
"owner": "job:forgetest",
"program": true,
"reason": "aborted",
"sent": 5,
"state": "failed"
}
},
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T17:11:00Z"
},
"dark_job": {
"farthest_mm": 20.0,
"kernel": [
0.0,
0.0
],
"record": {
"acked": 7,
"elapsed_s": 5,
"emission": {
"hv_max": 0,
"laser_on_samples": 0,
"lit_s": 0.0,
"samples": 23,
"thermopile_delta": 0
},
"lines": 6,
"lit": false,
"owner": "job:forgetest",
"program": true,
"reason": "",
"sent": 7,
"state": "done"
}
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"holder": {
"for_s": 0,
"kind": "sender",
"owner": "job:forgetest",
"words": "a job (forgetest)"
},
"into_the_alarm": {
"acked": 0,
"elapsed_s": 0,
"emission": {
"hv_max": 0,
"laser_on_samples": 0,
"lit_s": 0.0,
"samples": 1,
"thermopile_delta": 0
},
"lines": 4,
"lit": false,
"owner": "job:forgetest",
"program": true,
"reason": "the controller answered error:9 on line 1 (G21)",
"sent": 4,
"state": "failed"
},
"job_kernel_drift_mm": 0.0,
"mode": {
"detail": "already in grbl mode",
"found": "grbl",
"needs": "grbl",
"ok": true,
"switched": false
},
"record_keys": [
"acked",
"elapsed_s",
"emission",
"lines",
"lit",
"owner",
"program",
"reason",
"sent",
"state"
],
"refused_at_the_door": {
"a $ line": [
400,
"line 2 is a $ command: the controller's system commands are not a job's to send"
],
"a connected client": [
409,
"a sender is connected to the machine - close it first"
],
"no name": [
400,
"name says who sends the job: 1 to 63 of letters, digits, '.', '_' and '-'"
]
},
"refused_beside_the_job": {
"a port jog": [
409,
"a job (forgetest) holds the machine"
],
"a second job": [
409,
"a job (forgetest) holds the machine"
],
"a settings write": [
409,
"a job (forgetest) holds the machine - settings are locked"
]
},
"unlocked": {
"acked": 6,
"elapsed_s": 1,
"emission": {
"hv_max": 0,
"laser_on_samples": 0,
"lit_s": 0.0,
"samples": 4,
"thermopile_delta": 0
},
"lines": 4,
"lit": false,
"owner": "job:forgetest",
"program": true,
"reason": "",
"sent": 6,
"state": "done"
}
},
"fingerprint": "1ff9125ca3a8648fcfa0aea614d6b27471196fa259c8012d341a12365e1594da",
"image": "20260928170058 (dev)",
"log": [
"17:14:55 start motion.job (auto, api) in campaign c-20260928171100-3ff5",
"17:14:55 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"17:14:55 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"17:14:55 queued by the unattended queue opened 2026-09-28T17:11:00Z",
"17:14:55 baseline: pre: clean",
"17:14:55 mode: test needs grbl - already in grbl mode",
"17:14:56 connect: Idle",
"17:14:56 the lease while the job plays: {'owner': 'job:forgetest', 'kind': 'sender', 'for_s': 0, 'words': 'a job (forgetest)'}",
"17:15:01 the dark job: {'state': 'done', 'owner': 'job:forgetest', 'program': True, 'lines': 6, 'sent': 7, 'acked': 7, 'elapsed_s': 5, 'lit': False, 'emission': {'samples': 23, 'hv_max': 0, 'laser_on_samples': 0, 'thermopile_delta': 0, 'lit_s': 0.0}, 'reason': ''}; the kernel saw 20.000 mm out and ended 0.000 from the start",
"17:15:04 aborted a 40 mm move at 9.790 mm; the controller is in Alarm",
"17:15:05 the unlocking job: {'state': 'done', 'owner': 'job:forgetest', 'program': True, 'lines': 4, 'sent': 6, 'acked': 6, 'elapsed_s': 1, 'lit': False, 'emission': {'samples': 4, 'hv_max': 0, 'laser_on_samples': 0, 'thermopile_delta': 0, 'lit_s': 0.0}, 'reason': ''}",
"17:15:05 kernel counters: start (0.00, 0.00) -> now (-0.00, 0.00), drift 0.000 mm",
"17:15:05 PASS: a posted program ran as job:forgetest with the lease held as a sender, everything beside it was refused in its name, the abort stopped a move short and freed the machine, and the unlocking job cleared the alarm and returned the head",
"17:15:05 baseline: position: [-1, 0, 0] (expected [0, 0, 0]) -> restored; inside the 0.10 mm dead band, not a leftover",
"17:15:05 baseline: post: clean",
"17:15:05 result PASS"
],
"manifest_sha": "98f8c4dad7130ecf1fa44e5e0f1a1b53e6b9359f005f22a1ddbee496375d9a9e",
"message": "",
"result": "PASS",
"test": "motion.job",
"ts": "2026-09-28T17:15:05Z"
},
"requires": [
"motion.jog-roundtrip"
],
"satisfied": true,
"source_sha": "464cb88f05362fa73ba8158c5a093d336c786ad837c26ed37ee95bf1f18f8f32",
"subsystem": "motion",
"title": "The job runner: a posted program runs with the daemon as its sender"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/cool.*"
],
[
"forgectrl",
"src/coolfmt.*"
],
[
"forgectrl",
"src/diag.*"
],
[
"forgectrl",
"src/gates.*"
],
[
"forgectrl",
"src/airflow.*"
],
[
"forgectrl",
"src/accel.*"
],
[
"forgectrl",
"src/settings.*"
],
[
"forgectrl",
"src/status.*"
],
[
"forgectrl",
"src/ui/**"
],
[
"grblhal-glowforge",
"src/glowforge_cooling.*"
],
[
"kernel-module-glowforge",
"src/thermal*"
],
[
"kernel-module-glowforge",
"src/pic*"
]
],
"fingerprint": "d8bd0e355b6a75272e6e6d6798dd36c1dbadc033cb8dd1f8bec8d6e0d5933268",
"hardware": "api",
"id": "cooling.aa-offset-calibrate",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928162331-3969",
"duration_s": 91,
"evidence": {
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T16:23:31Z"
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"result": {
"offset_counts": 15.4,
"recommend": 15.4,
"spread_counts": 1.4,
"steps": [
[
15.2,
15.3
],
[
-15.6,
-15.2
],
[
15.5,
15.7
],
[
-15.2,
-15.2
],
[
16.2,
14.8
],
[
-15.6,
-15.5
]
]
}
},
"fingerprint": "d8bd0e355b6a75272e6e6d6798dd36c1dbadc033cb8dd1f8bec8d6e0d5933268",
"image": "20260928153805 (dev)",
"log": [
"16:33:06 start cooling.aa-offset-calibrate (auto, api) in campaign c-20260928162331-3969",
"16:33:06 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:33:06 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"16:33:06 queued by the unattended queue opened 2026-09-28T16:23:31Z",
"16:33:07 baseline: pre: clean",
"16:33:07 POST /diag/aa-offset-calibrate -> 202 {'started': True}",
"16:33:07 phase: stopping the motion controller",
"16:33:09 phase: settling with the fans idle",
"16:33:23 phase: cycle 1/3: air assist to run",
"16:33:35 phase: cycle 1/3: air assist to idle",
"16:33:38 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:33:47 phase: cycle 2/3: air assist to run",
"16:34:01 phase: cycle 2/3: air assist to idle",
"16:34:09 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:34:13 phase: cycle 3/3: air assist to run",
"16:34:25 phase: cycle 3/3: air assist to idle",
"16:34:37 phase: done",
"16:34:37 diag: 0:00 start: air assist 204 <-> 1023, 3 cycles",
"16:34:37 diag: 0:26 edge 1 (to run): down +15.2, up +15.3 counts",
"16:34:37 diag: 0:39 edge 2 (to idle): down -15.6, up -15.2 counts",
"16:34:37 diag: 0:52 edge 3 (to run): down +15.5, up +15.7 counts",
"16:34:37 diag: 1:04 edge 4 (to idle): down -15.2, up -15.2 counts",
"16:34:37 diag: 1:17 edge 5 (to run): down +16.2, up +14.8 counts",
"16:34:37 diag: 1:30 edge 6 (to idle): down -15.6, up -15.5 counts",
"16:34:37 diag: 1:30 offset 15.4 counts (spread 1.4) over 6 edges",
"16:34:37 diag: 1:30 done",
"16:34:37 offset 15.4 counts, spread 1.4, recommend 15.4, edges [[15.2, 15.3], [-15.6, -15.2], [15.5, 15.7], [-15.2, -15.2], [16.2, 14.8], [-15.6, -15.5]]",
"16:34:38 baseline: cool: diag/armed=False/hold=True was the engine's last word on the run; its next tick reads idle/armed=False/hold=False",
"16:34:38 baseline: post: clean",
"16:34:38 result PASS"
],
"manifest_sha": "faf9563c750bb8bd4bfc8778b6af053cddb63fa335ab946caf2f71631ede740f",
"message": "",
"result": "PASS",
"test": "cooling.aa-offset-calibrate",
"ts": "2026-09-28T16:34:38Z"
},
"requires": [
"kernel.latch-locked-idle"
],
"satisfied": true,
"source_sha": "d5683cca7ce5fd6c2b61e5781d96a37d63ec0faed7da9017749d50033e6e887c",
"subsystem": "cooling",
"title": "The air-assist ground shift on the coolant readings measures cleanly"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/cool.*"
],
[
"forgectrl",
"src/coolfmt.*"
],
[
"forgectrl",
"src/diag.*"
],
[
"forgectrl",
"src/gates.*"
],
[
"forgectrl",
"src/airflow.*"
],
[
"forgectrl",
"src/accel.*"
],
[
"forgectrl",
"src/settings.*"
],
[
"forgectrl",
"src/status.*"
],
[
"forgectrl",
"src/ui/**"
],
[
"grblhal-glowforge",
"src/glowforge_cooling.*"
],
[
"kernel-module-glowforge",
"src/thermal*"
],
[
"kernel-module-glowforge",
"src/pic*"
]
],
"fingerprint": "305ce089dd8101bddeb801594960bb19b216428e12ae00c8f83a10576ceb7f04",
"hardware": "api",
"id": "cooling.flow-verify",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928162331-3969",
"duration_s": 160,
"evidence": {
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T16:23:31Z"
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"result": {
"flow_dt": 8.8,
"flow_rise": 11.3,
"margin_flow": 3.2,
"margin_noflow": 2.3,
"noflow_dt": 11.4,
"noflow_rise": 16.8,
"pass": true,
"thin_margin": false,
"threshold": 14.5
}
},
"fingerprint": "305ce089dd8101bddeb801594960bb19b216428e12ae00c8f83a10576ceb7f04",
"image": "20260928153805 (dev)",
"log": [
"16:34:38 start cooling.flow-verify (auto, api) in campaign c-20260928162331-3969",
"16:34:38 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:34:38 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"16:34:38 queued by the unattended queue opened 2026-09-28T16:23:31Z",
"16:34:38 baseline: pre: clean",
"16:34:39 POST /diag/flow-verify -> 202 {'started': True}",
"16:34:39 phase: stopping the motion controller (down 25.2 C, up 25.2 C)",
"16:34:41 phase: settling before trial 1/1 (pump on) (down 25.1 C, up 25.3 C)",
"16:34:55 phase: trial 1/1: heater 40% for 50 s (pump on) (down 24.7 C, up 25.3 C)",
"16:35:09 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:35:40 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:35:47 phase: settling before trial 1/1 (pump off) (down 35.3 C, up 25.1 C)",
"16:36:10 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:36:25 phase: trial 1/1: heater 40% for 50 s (pump off) (down 23.9 C, up 23.1 C)",
"16:36:41 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:37:11 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:37:19 phase: done (down 40.4 C, up 29.0 C)",
"16:37:19 diag: 0:01 start: duty 40%, window 50 s, threshold 14.5 C",
"16:37:19 diag: 1:08 trial 1/1 flow: rise 11.3 C, dT 8.8 C",
"16:37:19 diag: 2:39 trial 1/1 no-flow: rise 16.8 C, dT 11.4 C",
"16:37:19 diag: 2:39 verdict: PASS (flow 11.3 / threshold 14.5 / no-flow 16.8)",
"16:37:19 diag: 2:39 done",
"16:37:19 verdict: pass=True threshold=14.5 flow_rise=11.3 noflow_rise=16.8 margins 3.2/2.3 thin=False",
"16:37:19 baseline: post: clean",
"16:37:19 result PASS"
],
"manifest_sha": "faf9563c750bb8bd4bfc8778b6af053cddb63fa335ab946caf2f71631ede740f",
"message": "",
"result": "PASS",
"test": "cooling.flow-verify",
"ts": "2026-09-28T16:37:19Z"
},
"requires": [
"kernel.latch-locked-idle"
],
"satisfied": true,
"source_sha": "dff148b11e2edf15645831b1ffc9984728a0fdae10c96fdc58cf6ac994f3d308",
"subsystem": "cooling",
"title": "Coolant flow check separates flow from no-flow"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/cool.*"
],
[
"forgectrl",
"src/coolfmt.*"
],
[
"forgectrl",
"src/diag.*"
],
[
"forgectrl",
"src/gates.*"
],
[
"forgectrl",
"src/airflow.*"
],
[
"forgectrl",
"src/accel.*"
],
[
"forgectrl",
"src/settings.*"
],
[
"forgectrl",
"src/status.*"
],
[
"forgectrl",
"src/ui/**"
],
[
"grblhal-glowforge",
"src/glowforge_cooling.*"
],
[
"kernel-module-glowforge",
"src/thermal*"
],
[
"kernel-module-glowforge",
"src/pic*"
],
[
"forgectrl",
"src/super.c"
]
],
"fingerprint": "ece94b02625f2987c983757b51a9d0a2143002776c7dcea0d7ac7150889c304f",
"hardware": "api",
"id": "cooling.fans-quiet-after-motion",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928171100-3ff5",
"duration_s": 55,
"evidence": {
"after": {
"air_assist": 2145,
"exhaust": 0,
"intake_1": 733,
"intake_2": 726
},
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T17:11:00Z"
},
"before": {
"air_assist": 2134,
"exhaust": 0,
"intake_1": 733,
"intake_2": 743
},
"during_m8": {
"air_assist": 10885,
"exhaust": 7733,
"intake_1": 1255,
"intake_2": 1251
},
"duty_after": {
"thermal/exhaust_pwm": 0,
"thermal/intake_pwm": 0
},
"duty_after_restart": {
"thermal/exhaust_pwm": 0,
"thermal/intake_pwm": 0
},
"duty_m8": {
"thermal/exhaust_pwm": 65535,
"thermal/intake_pwm": 43278
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"idle_ref_s": 15.1,
"kstate_at_restart": "disabled",
"mode": {
"detail": "already in grbl mode",
"found": "grbl",
"needs": "grbl",
"ok": true,
"switched": false
},
"restart_idle_s": 20.0,
"settle_s": 15.1
},
"fingerprint": "ece94b02625f2987c983757b51a9d0a2143002776c7dcea0d7ac7150889c304f",
"image": "20260928170058 (dev)",
"log": [
"17:15:06 start cooling.fans-quiet-after-motion (auto, api) in campaign c-20260928171100-3ff5",
"17:15:06 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"17:15:06 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"17:15:06 queued by the unattended queue opened 2026-09-28T17:11:00Z",
"17:15:06 baseline: pre: clean",
"17:15:06 mode: test needs grbl - already in grbl mode",
"17:15:11 idle ref: phase idle duty {'thermal/exhaust_pwm': 0, 'thermal/intake_pwm': 0} fans {'air_assist': 2121, 'exhaust': 0, 'intake_1': 729, 'intake_2': 743}",
"17:15:16 idle ref: phase idle duty {'thermal/exhaust_pwm': 0, 'thermal/intake_pwm': 0} fans {'air_assist': 2125, 'exhaust': 0, 'intake_1': 729, 'intake_2': 743}",
"17:15:21 idle ref: phase idle duty {'thermal/exhaust_pwm': 0, 'thermal/intake_pwm': 0} fans {'air_assist': 2134, 'exhaust': 0, 'intake_1': 733, 'intake_2': 743}",
"17:15:21 idle reference after 15.1 s: {'air_assist': 2134, 'exhaust': 0, 'intake_1': 733, 'intake_2': 743}",
"17:15:26 fans during M8: {'air_assist': 10885, 'exhaust': 7733, 'intake_1': 1255, 'intake_2': 1251} (duty {'thermal/exhaust_pwm': 65535, 'thermal/intake_pwm': 43278})",
"17:15:31 cooldown + 5 s: phase idle duty {'thermal/exhaust_pwm': 0, 'thermal/intake_pwm': 0} fans {'air_assist': 2267, 'exhaust': 2048, 'intake_1': 908, 'intake_2': 907}",
"17:15:36 cooldown + 10 s: phase idle duty {'thermal/exhaust_pwm': 0, 'thermal/intake_pwm': 0} fans {'air_assist': 2146, 'exhaust': 583, 'intake_1': 734, 'intake_2': 727}",
"17:15:37 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"17:15:41 cooldown + 15 s: phase idle duty {'thermal/exhaust_pwm': 0, 'thermal/intake_pwm': 0} fans {'air_assist': 2145, 'exhaust': 0, 'intake_1': 730, 'intake_2': 726}",
"17:15:41 fans after: {'air_assist': 2145, 'exhaust': 0, 'intake_1': 733, 'intake_2': 726} duty {'thermal/exhaust_pwm': 0, 'thermal/intake_pwm': 0} (settled in 15.1 s)",
"17:15:41 forgectrl stop -> rc 0",
"17:15:41 forgectrl start with cnc/state=disabled -> rc 0",
"17:15:46 after the restart + 5 s: controller stopped duty {'thermal/exhaust_pwm': 0, 'thermal/intake_pwm': 0}",
"17:15:51 after the restart + 10 s: controller stopped duty {'thermal/exhaust_pwm': 0, 'thermal/intake_pwm': 0}",
"17:15:56 after the restart + 15 s: controller stopped duty {'thermal/exhaust_pwm': 0, 'thermal/intake_pwm': 0}",
"17:16:01 after the restart + 20 s: controller running duty {'thermal/exhaust_pwm': 0, 'thermal/intake_pwm': 0}",
"17:16:01 baseline: position: [0, 0, 0], and [-1, 0, 0] when the run began, but the controller re-zeroed its counters during the run (a controller start or a home): the two are not in one frame, so the head's position cannot be judged and the head is not moved",
"17:16:01 baseline: post: clean",
"17:16:01 result PASS"
],
"manifest_sha": "98f8c4dad7130ecf1fa44e5e0f1a1b53e6b9359f005f22a1ddbee496375d9a9e",
"message": "",
"result": "PASS",
"test": "cooling.fans-quiet-after-motion",
"ts": "2026-09-28T17:16:01Z"
},
"requires": [
"motion.pacing"
],
"satisfied": true,
"source_sha": "6f84ae8d391893935c5ba4f494582d61f8263049b22332827e9b63a67e086f89",
"subsystem": "cooling",
"title": "Fan profile returns to idle after motion, after M8/M9, and after a daemon restart on a busy machine"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/cool.*"
],
[
"forgectrl",
"src/coolfmt.*"
],
[
"forgectrl",
"src/diag.*"
],
[
"forgectrl",
"src/gates.*"
],
[
"forgectrl",
"src/airflow.*"
],
[
"forgectrl",
"src/accel.*"
],
[
"forgectrl",
"src/settings.*"
],
[
"forgectrl",
"src/status.*"
],
[
"forgectrl",
"src/ui/**"
],
[
"grblhal-glowforge",
"src/glowforge_cooling.*"
],
[
"kernel-module-glowforge",
"src/thermal*"
],
[
"kernel-module-glowforge",
"src/pic*"
]
],
"fingerprint": "458bbc79b7da14e361c9a12ff74745aa3aee342081e286a7d75a270f19668cfc",
"hardware": "api",
"id": "cooling.gate-off",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928162331-3969",
"duration_s": 7,
"evidence": {
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T16:23:31Z"
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"mode": {
"detail": "already in grbl mode",
"found": "grbl",
"needs": "grbl",
"ok": true,
"switched": false
},
"off": {
"accel_watch": "watch",
"armed": false,
"down_c": 25.92,
"fan_gates": {
"air_assist": {
"floor": 6093,
"reading": 5208,
"state": "grace"
},
"exhaust": {
"floor": 6416,
"reading": 6045,
"state": "grace"
},
"intake_1": {
"floor": 2277,
"reading": 1052,
"state": "grace"
},
"intake_2": {
"floor": 2277,
"reading": 1162,
"state": "grace"
},
"purge": {
"floor": 345,
"reading": 630,
"state": "grace"
}
},
"fire_ok": true,
"fire_watch": "armed",
"gates_off": [
"coolant_max"
],
"hold": false,
"limits": {
"air_assist_min_rpm": 6093,
"coolant_critical_c": 38.0,
"coolant_max_c": 60.0,
"coolant_min_c": 5.0,
"coolant_resume_c": 31.0,
"coolant_source": "local",
"exhaust_min_rpm": 6416,
"intake_min_rpm": 2277
},
"phase": "run",
"quiet_hold": false,
"reason": "",
"report_age_s": 1.0,
"resume_ok": true,
"up_c": 26.0,
"verdict": "OK"
},
"off_state": "off",
"orig": {
"cool_temp_max": "",
"cool_temp_resume": ""
},
"restored": {
"accel_watch": "watch",
"armed": false,
"down_c": 25.92,
"fan_gates": {
"air_assist": {
"floor": 6093,
"reading": 5342,
"state": "grace"
},
"exhaust": {
"floor": 6416,
"reading": 5538,
"state": "grace"
},
"intake_1": {
"floor": 2277,
"reading": 1439,
"state": "grace"
},
"intake_2": {
"floor": 2277,
"reading": 1520,
"state": "grace"
},
"purge": {
"floor": 345,
"reading": 629,
"state": "grace"
}
},
"fire_ok": true,
"fire_watch": "armed",
"gates_off": [],
"hold": false,
"limits": {
"air_assist_min_rpm": 6093,
"coolant_critical_c": 38.0,
"coolant_max_c": 33.0,
"coolant_min_c": 5.0,
"coolant_resume_c": 31.0,
"coolant_source": "local",
"exhaust_min_rpm": 6416,
"intake_min_rpm": 2277
},
"phase": "run",
"quiet_hold": false,
"reason": "",
"report_age_s": 1.0,
"resume_ok": true,
"up_c": 25.68,
"verdict": "OK"
},
"temps": {
"chassis_c": 30.1,
"soc_c": 50.2,
"soc_throttle": 0,
"supply_raw": 613
},
"temps_line": "2026-09-28T16:30:33.883727+00:00 forgectrl[5799] INFO cool: temps this job: chassis 30.0..30.0 C, soc 49.7..49.7 C, supply raw 606..606",
"trip": {
"accel_watch": "watch",
"armed": false,
"down_c": 26.24,
"fan_gates": {
"air_assist": {
"floor": 6093,
"reading": 1948,
"state": "grace"
},
"exhaust": {
"floor": 6416,
"reading": 0,
"state": "grace"
},
"intake_1": {
"floor": 2277,
"reading": 733,
"state": "grace"
},
"intake_2": {
"floor": 2277,
"reading": 743,
"state": "grace"
},
"purge": {
"floor": 345,
"reading": 630,
"state": "grace"
}
},
"fire_ok": false,
"fire_watch": "armed",
"gates_off": [],
"hold": true,
"limits": {
"air_assist_min_rpm": 6093,
"coolant_critical_c": 38.0,
"coolant_max_c": 6.0,
"coolant_min_c": 5.0,
"coolant_resume_c": 5.0,
"coolant_source": "local",
"exhaust_min_rpm": 6416,
"intake_min_rpm": 2277
},
"phase": "run",
"quiet_hold": false,
"reason": "coolant 26.1 C over 6 C limit - hold until 5 C",
"report_age_s": 1.0,
"resume_ok": false,
"up_c": 26.08,
"verdict": "OVERTEMP"
},
"trip_state": "warn"
},
"fingerprint": "458bbc79b7da14e361c9a12ff74745aa3aee342081e286a7d75a270f19668cfc",
"image": "20260928153805 (dev)",
"log": [
"16:30:27 start cooling.gate-off (auto, api) in campaign c-20260928162331-3969",
"16:30:27 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:30:27 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"16:30:27 queued by the unattended queue opened 2026-09-28T16:23:31Z",
"16:30:28 baseline: pre: clean",
"16:30:28 mode: test needs grbl - already in grbl mode",
"16:30:28 original: {'cool_temp_max': '', 'cool_temp_resume': ''}",
"16:30:29 trip leg: verdict OVERTEMP fire_ok False hold True gates_off [] (after 1 s)",
"16:30:31 off leg: verdict OK fire_ok True hold False gates_off ['coolant_max'] (after 1 s)",
"16:30:33 restored: verdict OK fire_ok True hold False gates_off [] (after 1 s)",
"16:30:34 restored ceiling 33 reports state ok",
"16:30:35 baseline: post: clean",
"16:30:35 result PASS"
],
"manifest_sha": "faf9563c750bb8bd4bfc8778b6af053cddb63fa335ab946caf2f71631ede740f",
"message": "",
"result": "PASS",
"test": "cooling.gate-off",
"ts": "2026-09-28T16:30:35Z"
},
"requires": [
"kernel.latch-locked-idle"
],
"satisfied": true,
"source_sha": "8629aa48b9c4e87a8bf7c5ad2bbe8bf94c60aa1fea2a42967ad01b710c1b04e5",
"subsystem": "cooling",
"title": "A gate setting trips inside its range and is off at its far end"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/cool.*"
],
[
"forgectrl",
"src/coolfmt.*"
],
[
"forgectrl",
"src/diag.*"
],
[
"forgectrl",
"src/gates.*"
],
[
"forgectrl",
"src/airflow.*"
],
[
"forgectrl",
"src/accel.*"
],
[
"forgectrl",
"src/settings.*"
],
[
"forgectrl",
"src/status.*"
],
[
"forgectrl",
"src/ui/**"
],
[
"grblhal-glowforge",
"src/glowforge_cooling.*"
],
[
"kernel-module-glowforge",
"src/thermal*"
],
[
"kernel-module-glowforge",
"src/pic*"
]
],
"fingerprint": "5c61d67ff508ba63edee95bca4830ce979bad771b543cbe22fc3f044bf561052",
"hardware": "api",
"id": "cooling.floor-and-warm-up",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928171100-3ff5",
"duration_s": 81,
"evidence": {
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T17:11:00Z"
},
"both_off": {
"accel_watch": "watch",
"armed": false,
"down_c": 31.71,
"fan_gates": {
"air_assist": {
"floor": 6093,
"reading": 5523,
"state": "grace"
},
"exhaust": {
"floor": 6416,
"reading": 4131,
"state": "grace"
},
"intake_1": {
"floor": 2277,
"reading": 3675,
"state": "grace"
},
"intake_2": {
"floor": 2277,
"reading": 3535,
"state": "grace"
},
"purge": {
"floor": 345,
"reading": 631,
"state": "grace"
}
},
"fire_ok": true,
"fire_watch": "armed",
"gates_off": [
"coolant_min",
"warm_up"
],
"hold": false,
"limits": {
"air_assist_min_rpm": 6093,
"coolant_critical_c": 38.0,
"coolant_max_c": 33.0,
"coolant_min_c": 0.0,
"coolant_resume_c": 31.0,
"coolant_source": "local",
"exhaust_min_rpm": 6416,
"intake_min_rpm": 2277
},
"phase": "run",
"quiet_hold": false,
"reason": "",
"report_age_s": 1.0,
"resume_ok": true,
"up_c": 27.68,
"verdict": "OK"
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"floor": {
"accel_watch": "watch",
"armed": false,
"down_c": 34.18,
"fan_gates": {
"air_assist": {
"floor": 6093,
"reading": 5556,
"state": "grace"
},
"exhaust": {
"floor": 6416,
"reading": 7415,
"state": "grace"
},
"intake_1": {
"floor": 2277,
"reading": 3260,
"state": "grace"
},
"intake_2": {
"floor": 2277,
"reading": 3126,
"state": "grace"
},
"purge": {
"floor": 345,
"reading": 630,
"state": "grace"
}
},
"fire_ok": false,
"fire_watch": "armed",
"gates_off": [
"warm_up"
],
"hold": true,
"limits": {
"air_assist_min_rpm": 6093,
"coolant_critical_c": 38.0,
"coolant_max_c": 33.0,
"coolant_min_c": 30.4,
"coolant_resume_c": 31.0,
"coolant_source": "local",
"exhaust_min_rpm": 6416,
"intake_min_rpm": 2277
},
"phase": "run",
"quiet_hold": false,
"reason": "COLD: coolant 28.0 C under the 30.4 C floor - fire blocked until 31.4 C",
"report_age_s": 1.0,
"resume_ok": false,
"up_c": 28.0,
"verdict": "COLD"
},
"mode": {
"detail": "already in grbl mode",
"found": "grbl",
"needs": "grbl",
"ok": true,
"switched": false
},
"orig": {
"cool_temp_min": "",
"cool_temp_start": ""
},
"restored": {
"accel_watch": "watch",
"armed": false,
"down_c": 31.04,
"fan_gates": {
"air_assist": {
"floor": 6093,
"reading": 5486,
"state": "grace"
},
"exhaust": {
"floor": 6416,
"reading": 3648,
"state": "grace"
},
"intake_1": {
"floor": 2277,
"reading": 3974,
"state": "grace"
},
"intake_2": {
"floor": 2277,
"reading": 3930,
"state": "grace"
},
"purge": {
"floor": 345,
"reading": 631,
"state": "grace"
}
},
"fire_ok": true,
"fire_watch": "armed",
"gates_off": [],
"hold": false,
"limits": {
"air_assist_min_rpm": 6093,
"coolant_critical_c": 38.0,
"coolant_max_c": 33.0,
"coolant_min_c": 5.0,
"coolant_resume_c": 31.0,
"coolant_source": "local",
"exhaust_min_rpm": 6416,
"intake_min_rpm": 2277
},
"phase": "run",
"quiet_hold": false,
"reason": "",
"report_age_s": 1.0,
"resume_ok": true,
"up_c": 27.36,
"verdict": "OK"
},
"run_duty": {
"thermal/exhaust_pwm": 65535,
"thermal/intake_pwm": 43278
},
"run_heater_pwm": 0,
"warmup_duty": {
"thermal/exhaust_pwm": 0,
"thermal/intake_pwm": 0
},
"warmup_heater_pwm": 26214,
"warmup_hold": {
"accel_watch": "watch",
"armed": false,
"down_c": 25.13,
"fan_gates": {
"air_assist": {
"floor": 6093,
"reading": 2134,
"state": "idle"
},
"exhaust": {
"floor": 6416,
"reading": 0,
"state": "idle"
},
"intake_1": {
"floor": 2277,
"reading": 730,
"state": "idle"
},
"intake_2": {
"floor": 2277,
"reading": 733,
"state": "idle"
},
"purge": {
"floor": 345,
"reading": 634,
"state": "idle"
}
},
"fire_ok": false,
"fire_watch": "armed",
"gates_off": [],
"hold": true,
"limits": {
"air_assist_min_rpm": 6093,
"coolant_critical_c": 38.0,
"coolant_max_c": 33.0,
"coolant_min_c": 5.0,
"coolant_resume_c": 31.0,
"coolant_source": "local",
"exhaust_min_rpm": 6416,
"intake_min_rpm": 2277
},
"phase": "warm-up",
"quiet_hold": false,
"reason": "",
"report_age_s": 1.0,
"resume_ok": false,
"up_c": 25.6,
"verdict": "WARMUP"
},
"warmup_release": {
"accel_watch": "watch",
"armed": false,
"down_c": 38.35,
"fan_gates": {
"air_assist": {
"floor": 6093,
"reading": 10870,
"state": "grace"
},
"exhaust": {
"floor": 6416,
"reading": 8759,
"state": "grace"
},
"intake_1": {
"floor": 2277,
"reading": 1429,
"state": "grace"
},
"intake_2": {
"floor": 2277,
"reading": 1437,
"state": "grace"
},
"purge": {
"floor": 345,
"reading": 631,
"state": "grace"
}
},
"fire_ok": true,
"fire_watch": "armed",
"gates_off": [],
"hold": false,
"limits": {
"air_assist_min_rpm": 6093,
"coolant_critical_c": 38.0,
"coolant_max_c": 33.0,
"coolant_min_c": 5.0,
"coolant_resume_c": 31.0,
"coolant_source": "local",
"exhaust_min_rpm": 6416,
"intake_min_rpm": 2277
},
"phase": "run",
"quiet_hold": false,
"reason": "",
"report_age_s": 0.7,
"resume_ok": true,
"up_c": 28.57,
"verdict": "OK"
},
"warmup_release_s": 70
},
"fingerprint": "5c61d67ff508ba63edee95bca4830ce979bad771b543cbe22fc3f044bf561052",
"image": "20260928170058 (dev)",
"log": [
"17:16:01 start cooling.floor-and-warm-up (auto, api) in campaign c-20260928171100-3ff5",
"17:16:02 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"17:16:02 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"17:16:02 queued by the unattended queue opened 2026-09-28T17:11:00Z",
"17:16:02 baseline: pre: clean",
"17:16:02 mode: test needs grbl - already in grbl mode",
"17:16:02 original: {'cool_temp_min': '', 'cool_temp_start': ''}",
"17:16:03 warm-up hold: verdict WARMUP phase warm-up fire_ok False hold True (after 1 s)",
"17:16:33 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"17:17:04 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"17:17:13 warm-up release after 70 s: verdict OK phase run up 28.57 (gate 26.3)",
"17:17:17 floor: verdict COLD fire_ok False hold True gates_off ['warm_up'] (after 1 s)",
"17:17:20 both off: verdict OK fire_ok True hold False gates_off ['coolant_min', 'warm_up'] (after 1 s)",
"17:17:22 restored: verdict OK fire_ok True hold False gates_off [] (after 1 s)",
"17:17:23 baseline: post: clean",
"17:17:23 result PASS"
],
"manifest_sha": "98f8c4dad7130ecf1fa44e5e0f1a1b53e6b9359f005f22a1ddbee496375d9a9e",
"message": "",
"result": "PASS",
"test": "cooling.floor-and-warm-up",
"ts": "2026-09-28T17:17:23Z"
},
"requires": [
"kernel.latch-locked-idle",
"cooling.gate-off"
],
"satisfied": true,
"source_sha": "54135aecb217dda573a34cb22fa06d212bbe5e4e3142b0f6a9c6e6b7da2ace67",
"subsystem": "cooling",
"title": "The coolant floor blocks fire and the warm-up gate holds a cold start"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/cool.*"
],
[
"forgectrl",
"src/coolfmt.*"
],
[
"forgectrl",
"src/diag.*"
],
[
"forgectrl",
"src/gates.*"
],
[
"forgectrl",
"src/airflow.*"
],
[
"forgectrl",
"src/accel.*"
],
[
"forgectrl",
"src/settings.*"
],
[
"forgectrl",
"src/status.*"
],
[
"forgectrl",
"src/ui/**"
],
[
"grblhal-glowforge",
"src/glowforge_cooling.*"
],
[
"kernel-module-glowforge",
"src/thermal*"
],
[
"kernel-module-glowforge",
"src/pic*"
]
],
"fingerprint": "c346d74d4672e050dff6b3225b4cd1e771c92097e5c7da1870091647f60915ee",
"hardware": "api",
"id": "cooling.tec-drive",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928171100-3ff5",
"duration_s": 9,
"evidence": {
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T17:11:00Z"
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"mode": {
"detail": "already in grbl mode",
"found": "grbl",
"needs": "grbl",
"ok": true,
"switched": false
},
"orig": {
"cool_tec_off_c": "",
"cool_tec_on_c": "",
"cool_tec_present": "0"
},
"restored": {
"accel_watch": "watch",
"armed": false,
"down_c": 27.68,
"fan_gates": {
"air_assist": {
"floor": 6093,
"reading": 5511,
"state": "grace"
},
"exhaust": {
"floor": 6416,
"reading": 3628,
"state": "grace"
},
"intake_1": {
"floor": 2277,
"reading": 3927,
"state": "grace"
},
"intake_2": {
"floor": 2277,
"reading": 3884,
"state": "grace"
},
"purge": {
"floor": 345,
"reading": 631,
"state": "grace"
}
},
"fire_ok": true,
"fire_watch": "armed",
"gates_off": [],
"hold": false,
"limits": {
"air_assist_min_rpm": 6093,
"coolant_critical_c": 38.0,
"coolant_max_c": 33.0,
"coolant_min_c": 5.0,
"coolant_resume_c": 31.0,
"coolant_source": "local",
"exhaust_min_rpm": 6416,
"intake_min_rpm": 2277
},
"phase": "run",
"quiet_hold": false,
"reason": "",
"report_age_s": 1.0,
"resume_ok": true,
"up_c": 26.4,
"verdict": "OK"
},
"tec_after_session": 0,
"tec_not_fitted": 0,
"tec_on_after_s": 1,
"tec_on_line": "2026-09-28T17:17:25.751844+00:00 forgectrl[2882] INFO cool: TEC on: coolant 27.4 C over 25.4 C, airflow up"
},
"fingerprint": "c346d74d4672e050dff6b3225b4cd1e771c92097e5c7da1870091647f60915ee",
"image": "20260928170058 (dev)",
"log": [
"17:17:23 start cooling.tec-drive (auto, api) in campaign c-20260928171100-3ff5",
"17:17:24 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"17:17:24 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"17:17:24 queued by the unattended queue opened 2026-09-28T17:11:00Z",
"17:17:24 baseline: pre: clean",
"17:17:24 mode: test needs grbl - already in grbl mode",
"17:17:24 original: {'cool_tec_present': '0', 'cool_tec_on_c': '', 'cool_tec_off_c': ''}",
"17:17:25 fitted, in session: thermal/tec_on=1 after 1 s",
"17:17:28 after the session: phase idle thermal/tec_on=0",
"17:17:29 tec leg 2: verdict OK fire_ok True hold False gates_off [] (after 1 s)",
"17:17:31 restored: verdict OK fire_ok True hold False gates_off [] (after 1 s)",
"17:17:33 baseline: post: clean",
"17:17:33 result PASS"
],
"manifest_sha": "98f8c4dad7130ecf1fa44e5e0f1a1b53e6b9359f005f22a1ddbee496375d9a9e",
"message": "",
"result": "PASS",
"test": "cooling.tec-drive",
"ts": "2026-09-28T17:17:33Z"
},
"requires": [
"kernel.latch-locked-idle"
],
"satisfied": true,
"source_sha": "7f522ff5ab19d6e1cb9144f7075bdd38ceca18b28b937233cad3625ebd6348e2",
"subsystem": "cooling",
"title": "The TEC runs on its hysteresis only with airflow and only when declared fitted"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/cool.*"
],
[
"forgectrl",
"src/coolfmt.*"
],
[
"forgectrl",
"src/diag.*"
],
[
"forgectrl",
"src/gates.*"
],
[
"forgectrl",
"src/airflow.*"
],
[
"forgectrl",
"src/accel.*"
],
[
"forgectrl",
"src/settings.*"
],
[
"forgectrl",
"src/status.*"
],
[
"forgectrl",
"src/ui/**"
],
[
"grblhal-glowforge",
"src/glowforge_cooling.*"
],
[
"kernel-module-glowforge",
"src/thermal*"
],
[
"kernel-module-glowforge",
"src/pic*"
],
[
"forgectrl",
"src/super.*"
]
],
"fingerprint": "6ba6a433fb0f495a80bfab9ed1c685fca573a414fbf60c14a71f9fcf20ada88a",
"hardware": "api",
"id": "cooling.fire-watch-tiers",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928171100-3ff5",
"duration_s": 15,
"evidence": {
"alert": {
"accel_watch": "watch",
"armed": false,
"down_c": 26.48,
"fan_gates": {
"air_assist": {
"floor": 6093,
"reading": 10714,
"state": "grace"
},
"exhaust": {
"floor": 6416,
"reading": 4292,
"state": "grace"
},
"intake_1": {
"floor": 2277,
"reading": 3711,
"state": "grace"
},
"intake_2": {
"floor": 2277,
"reading": 3803,
"state": "grace"
},
"purge": {
"floor": 345,
"reading": 631,
"state": "grace"
}
},
"fire_ok": false,
"fire_watch": "alert",
"gates_off": [],
"hold": true,
"limits": {
"air_assist_min_rpm": 6093,
"coolant_critical_c": 38.0,
"coolant_max_c": 33.0,
"coolant_min_c": 5.0,
"coolant_resume_c": 31.0,
"coolant_source": "local",
"exhaust_min_rpm": 6416,
"intake_min_rpm": 2277
},
"phase": "run",
"quiet_hold": false,
"reason": "lid IR flame alert (quartiles 48 49) - job held, fire blocked until the signal clears",
"report_age_s": 0.0,
"resume_ok": false,
"up_c": 26.4,
"verdict": "FLAME"
},
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T17:11:00Z"
},
"critical": {
"accel_watch": "watch",
"armed": false,
"down_c": 26.88,
"fan_gates": {
"air_assist": {
"floor": 6093,
"reading": 10776,
"state": "grace"
},
"exhaust": {
"floor": 6416,
"reading": 4461,
"state": "grace"
},
"intake_1": {
"floor": 2277,
"reading": 4133,
"state": "grace"
},
"intake_2": {
"floor": 2277,
"reading": 4128,
"state": "grace"
},
"purge": {
"floor": 345,
"reading": 632,
"state": "grace"
}
},
"fire_ok": false,
"fire_watch": "ALARM",
"gates_off": [],
"hold": true,
"limits": {
"air_assist_min_rpm": 6093,
"coolant_critical_c": 38.0,
"coolant_max_c": 33.0,
"coolant_min_c": 5.0,
"coolant_resume_c": 31.0,
"coolant_source": "local",
"exhaust_min_rpm": 6416,
"intake_min_rpm": 2277
},
"phase": "run",
"quiet_hold": false,
"reason": "LID IR FIRE SIGNAL (quartiles 48 49) - motion stopped, laser locked, smoke airflow held",
"report_age_s": 0.7,
"resume_ok": false,
"up_c": 26.32,
"verdict": "FIRE"
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"interlock_circuit": 45,
"lid_ir_idle": [
48,
49,
53,
53
],
"mode": {
"detail": "already in grbl mode",
"found": "grbl",
"needs": "grbl",
"ok": true,
"switched": false
},
"off": {
"accel_watch": "watch",
"armed": false,
"down_c": 26.64,
"fan_gates": {
"air_assist": {
"floor": 6093,
"reading": 3635,
"state": "grace"
},
"exhaust": {
"floor": 6416,
"reading": 3514,
"state": "grace"
},
"intake_1": {
"floor": 2277,
"reading": 3352,
"state": "grace"
},
"intake_2": {
"floor": 2277,
"reading": 3337,
"state": "grace"
},
"purge": {
"floor": 345,
"reading": 631,
"state": "grace"
}
},
"fire_ok": true,
"fire_watch": "watch",
"gates_off": [
"flame_q1_alert",
"flame_q1_critical",
"flame_q2_alert",
"flame_q2_critical"
],
"hold": false,
"limits": {
"air_assist_min_rpm": 6093,
"coolant_critical_c": 38.0,
"coolant_max_c": 33.0,
"coolant_min_c": 5.0,
"coolant_resume_c": 31.0,
"coolant_source": "local",
"exhaust_min_rpm": 6416,
"intake_min_rpm": 2277
},
"phase": "run",
"quiet_hold": false,
"reason": "",
"report_age_s": 0.0,
"resume_ok": true,
"up_c": 26.24,
"verdict": "OK"
},
"orig": {
"cool_fire_q1_alert": "",
"cool_fire_q1_critical": "",
"cool_fire_q2_alert": "",
"cool_fire_q2_critical": ""
},
"restart": {
"mode_after": {
"controller": "running",
"gated": false,
"local": false,
"mode": "grbl",
"motion": "verified",
"pid": 3429,
"why": ""
},
"pid_before": 2953
},
"restored": {
"accel_watch": "watch",
"armed": false,
"down_c": 25.68,
"fan_gates": {
"air_assist": {
"floor": 6093,
"reading": 5486,
"state": "grace"
},
"exhaust": {
"floor": 6416,
"reading": 3817,
"state": "grace"
},
"intake_1": {
"floor": 2277,
"reading": 3726,
"state": "grace"
},
"intake_2": {
"floor": 2277,
"reading": 3742,
"state": "grace"
},
"purge": {
"floor": 345,
"reading": 632,
"state": "grace"
}
},
"fire_ok": true,
"fire_watch": "armed",
"gates_off": [],
"hold": false,
"limits": {
"air_assist_min_rpm": 6093,
"coolant_critical_c": 38.0,
"coolant_max_c": 33.0,
"coolant_min_c": 5.0,
"coolant_resume_c": 31.0,
"coolant_source": "local",
"exhaust_min_rpm": 6416,
"intake_min_rpm": 2277
},
"phase": "run",
"quiet_hold": false,
"reason": "",
"report_age_s": 1.0,
"resume_ok": true,
"up_c": 26.0,
"verdict": "OK"
}
},
"fingerprint": "6ba6a433fb0f495a80bfab9ed1c685fca573a414fbf60c14a71f9fcf20ada88a",
"image": "20260928170058 (dev)",
"log": [
"17:17:33 start cooling.fire-watch-tiers (auto, api) in campaign c-20260928171100-3ff5",
"17:17:33 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"17:17:33 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"17:17:33 queued by the unattended queue opened 2026-09-28T17:11:00Z",
"17:17:33 baseline: pre: clean",
"17:17:33 mode: test needs grbl - already in grbl mode",
"17:17:33 original: {'cool_fire_q1_alert': '', 'cool_fire_q1_critical': '', 'cool_fire_q2_alert': '', 'cool_fire_q2_critical': ''}",
"17:17:36 alert leg: verdict FLAME fire_watch alert hold True fire_ok False",
"17:17:39 post-alert: verdict OK fire_ok True hold False gates_off [] (after 1 s)",
"17:17:42 critical leg: verdict FIRE fire_watch ALARM interlock_circuit 45",
"17:17:43 after FIRE: {'pid_before': 2953, 'mode_after': {'mode': 'grbl', 'controller': 'running', 'pid': 3429, 'motion': 'verified', 'gated': False, 'local': False, 'why': ''}}",
"17:17:45 watch off: verdict OK fire_ok True hold False gates_off ['flame_q1_alert', 'flame_q1_critical', 'flame_q2_alert', 'flame_q2_critical'] (after 1 s)",
"17:17:47 restored: verdict OK fire_ok True hold False gates_off [] (after 1 s)",
"17:17:48 baseline: post: clean",
"17:17:48 result PASS"
],
"manifest_sha": "98f8c4dad7130ecf1fa44e5e0f1a1b53e6b9359f005f22a1ddbee496375d9a9e",
"message": "",
"result": "PASS",
"test": "cooling.fire-watch-tiers",
"ts": "2026-09-28T17:17:48Z"
},
"requires": [
"kernel.latch-locked-idle"
],
"satisfied": true,
"source_sha": "b52a0f8a41c2f9318bab5121da0e0c68f57a9fcd21cdeb059dd075ce6f7499af",
"subsystem": "cooling",
"title": "The lid-IR fire watch pauses at its alert and fails at its critical"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/cool.*"
],
[
"forgectrl",
"src/coolfmt.*"
],
[
"forgectrl",
"src/diag.*"
],
[
"forgectrl",
"src/gates.*"
],
[
"forgectrl",
"src/airflow.*"
],
[
"forgectrl",
"src/accel.*"
],
[
"forgectrl",
"src/settings.*"
],
[
"forgectrl",
"src/status.*"
],
[
"forgectrl",
"src/ui/**"
],
[
"grblhal-glowforge",
"src/glowforge_cooling.*"
],
[
"kernel-module-glowforge",
"src/thermal*"
],
[
"kernel-module-glowforge",
"src/pic*"
]
],
"fingerprint": "74e822558be49fcb4d3482fe9efae7187350266df1d4cebdd866d74e3c4ff717",
"hardware": "api",
"id": "cooling.crash-watch-plumbing",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928171100-3ff5",
"duration_s": 7,
"evidence": {
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T17:11:00Z"
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"mode": {
"detail": "already in grbl mode",
"found": "grbl",
"needs": "grbl",
"ok": true,
"switched": false
},
"off": {
"accel_watch": "watch",
"armed": false,
"down_c": 25.6,
"fan_gates": {
"air_assist": {
"floor": 6093,
"reading": 5495,
"state": "grace"
},
"exhaust": {
"floor": 6416,
"reading": 3604,
"state": "grace"
},
"intake_1": {
"floor": 2277,
"reading": 3862,
"state": "grace"
},
"intake_2": {
"floor": 2277,
"reading": 3868,
"state": "grace"
},
"purge": {
"floor": 345,
"reading": 632,
"state": "grace"
}
},
"fire_ok": true,
"fire_watch": "armed",
"gates_off": [
"crash_x_alert",
"crash_y_alert",
"crash_abort"
],
"hold": false,
"limits": {
"air_assist_min_rpm": 6093,
"coolant_critical_c": 38.0,
"coolant_max_c": 33.0,
"coolant_min_c": 5.0,
"coolant_resume_c": 31.0,
"coolant_source": "local",
"exhaust_min_rpm": 6416,
"intake_min_rpm": 2277
},
"phase": "run",
"quiet_hold": false,
"reason": "",
"report_age_s": 1.0,
"resume_ok": true,
"up_c": 25.76,
"verdict": "OK"
},
"orig": {
"cool_accel_abort": "",
"cool_accel_x_alert": "",
"cool_accel_y_alert": ""
},
"restored": {
"accel_watch": "watch",
"armed": false,
"down_c": 25.92,
"fan_gates": {
"air_assist": {
"floor": 6093,
"reading": 5503,
"state": "grace"
},
"exhaust": {
"floor": 6416,
"reading": 3643,
"state": "grace"
},
"intake_1": {
"floor": 2277,
"reading": 3941,
"state": "grace"
},
"intake_2": {
"floor": 2277,
"reading": 3932,
"state": "grace"
},
"purge": {
"floor": 345,
"reading": 631,
"state": "grace"
}
},
"fire_ok": true,
"fire_watch": "armed",
"gates_off": [],
"hold": false,
"limits": {
"air_assist_min_rpm": 6093,
"coolant_critical_c": 38.0,
"coolant_max_c": 33.0,
"coolant_min_c": 5.0,
"coolant_resume_c": 31.0,
"coolant_source": "local",
"exhaust_min_rpm": 6416,
"intake_min_rpm": 2277
},
"phase": "run",
"quiet_hold": false,
"reason": "",
"report_age_s": 1.0,
"resume_ok": true,
"up_c": 25.6,
"verdict": "OK"
},
"unarmed": {
"accel_watch": "watch",
"armed": false,
"down_c": 26.16,
"fan_gates": {
"air_assist": {
"floor": 6093,
"reading": 3623,
"state": "grace"
},
"exhaust": {
"floor": 6416,
"reading": 2869,
"state": "grace"
},
"intake_1": {
"floor": 2277,
"reading": 3468,
"state": "grace"
},
"intake_2": {
"floor": 2277,
"reading": 3486,
"state": "grace"
},
"purge": {
"floor": 345,
"reading": 631,
"state": "grace"
}
},
"fire_ok": true,
"fire_watch": "armed",
"gates_off": [],
"hold": false,
"limits": {
"air_assist_min_rpm": 6093,
"coolant_critical_c": 38.0,
"coolant_max_c": 33.0,
"coolant_min_c": 5.0,
"coolant_resume_c": 31.0,
"coolant_source": "local",
"exhaust_min_rpm": 6416,
"intake_min_rpm": 2277
},
"phase": "run",
"quiet_hold": false,
"reason": "",
"report_age_s": 1.0,
"resume_ok": true,
"up_c": 25.84,
"verdict": "OK"
}
},
"fingerprint": "74e822558be49fcb4d3482fe9efae7187350266df1d4cebdd866d74e3c4ff717",
"image": "20260928170058 (dev)",
"log": [
"17:17:48 start cooling.crash-watch-plumbing (auto, api) in campaign c-20260928171100-3ff5",
"17:17:48 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"17:17:48 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"17:17:48 queued by the unattended queue opened 2026-09-28T17:11:00Z",
"17:17:48 baseline: pre: clean",
"17:17:48 mode: test needs grbl - already in grbl mode",
"17:17:48 original: {'cool_accel_x_alert': '', 'cool_accel_y_alert': '', 'cool_accel_abort': ''}",
"17:17:50 unarmed session: verdict OK fire_ok True hold False gates_off [] (after 1 s)",
"17:17:52 watch off: verdict OK fire_ok True hold False gates_off ['crash_x_alert', 'crash_y_alert', 'crash_abort'] (after 1 s)",
"17:17:54 restored: verdict OK fire_ok True hold False gates_off [] (after 1 s)",
"17:17:55 baseline: post: clean",
"17:17:55 result PASS"
],
"manifest_sha": "98f8c4dad7130ecf1fa44e5e0f1a1b53e6b9359f005f22a1ddbee496375d9a9e",
"message": "",
"result": "PASS",
"test": "cooling.crash-watch-plumbing",
"ts": "2026-09-28T17:17:55Z"
},
"requires": [
"kernel.latch-locked-idle"
],
"satisfied": true,
"source_sha": "2e60425a52d5a0797c8de32d074b3dc715140d15dc2a85974854975586b3631a",
"subsystem": "cooling",
"title": "The crash watch stays off the accelerometer unarmed and its gates say off"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/cool.*"
],
[
"forgectrl",
"src/coolfmt.*"
],
[
"forgectrl",
"src/diag.*"
],
[
"forgectrl",
"src/gates.*"
],
[
"forgectrl",
"src/airflow.*"
],
[
"forgectrl",
"src/accel.*"
],
[
"forgectrl",
"src/settings.*"
],
[
"forgectrl",
"src/status.*"
],
[
"forgectrl",
"src/ui/**"
],
[
"grblhal-glowforge",
"src/glowforge_cooling.*"
],
[
"kernel-module-glowforge",
"src/thermal*"
],
[
"kernel-module-glowforge",
"src/pic*"
],
[
"forgectrl",
"src/main.c"
]
],
"fingerprint": "1ffdf5a29b1751bf9f77c4271a09717b7c122090e3dcb39b0a8e69acd877a13d",
"hardware": "api",
"id": "cooling.critical-tier",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928171100-3ff5",
"duration_s": 8,
"evidence": {
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T17:11:00Z"
},
"ceiling_off_accepted": 200,
"critical": {
"accel_watch": "watch",
"armed": false,
"down_c": 25.92,
"fan_gates": {
"air_assist": {
"floor": 6093,
"reading": 2787,
"state": "grace"
},
"exhaust": {
"floor": 6416,
"reading": 2101,
"state": "grace"
},
"intake_1": {
"floor": 2277,
"reading": 2901,
"state": "grace"
},
"intake_2": {
"floor": 2277,
"reading": 2896,
"state": "grace"
},
"purge": {
"floor": 345,
"reading": 631,
"state": "grace"
}
},
"fire_ok": false,
"fire_watch": "armed",
"gates_off": [],
"hold": true,
"limits": {
"air_assist_min_rpm": 6093,
"coolant_critical_c": 7.0,
"coolant_max_c": 6.0,
"coolant_min_c": 5.0,
"coolant_resume_c": 5.0,
"coolant_source": "local",
"exhaust_min_rpm": 6416,
"intake_min_rpm": 2277
},
"phase": "run",
"quiet_hold": false,
"reason": "CRITICAL: coolant 25.8 C at or over the 7 C critical line - hold, no resume this job",
"report_age_s": 0.0,
"resume_ok": false,
"up_c": 25.76,
"verdict": "CRITICAL"
},
"critical_after": {
"accel_watch": "watch",
"armed": false,
"down_c": 25.84,
"fan_gates": {
"air_assist": {
"floor": 6093,
"reading": 5499,
"state": "idle"
},
"exhaust": {
"floor": 6416,
"reading": 6187,
"state": "idle"
},
"intake_1": {
"floor": 2277,
"reading": 3275,
"state": "idle"
},
"intake_2": {
"floor": 2277,
"reading": 3243,
"state": "idle"
},
"purge": {
"floor": 345,
"reading": 633,
"state": "idle"
}
},
"fire_ok": false,
"fire_watch": "armed",
"gates_off": [],
"hold": true,
"limits": {
"air_assist_min_rpm": 6093,
"coolant_critical_c": 7.0,
"coolant_max_c": 6.0,
"coolant_min_c": 5.0,
"coolant_resume_c": 5.0,
"coolant_source": "local",
"exhaust_min_rpm": 6416,
"intake_min_rpm": 2277
},
"phase": "thermal",
"quiet_hold": false,
"reason": "coolant 25.8 C over 6 C limit - hold until 5 C",
"report_age_s": 0.0,
"resume_ok": false,
"up_c": 25.76,
"verdict": "OVERTEMP"
},
"critical_off": {
"accel_watch": "watch",
"armed": false,
"down_c": 25.52,
"fan_gates": {
"air_assist": {
"floor": 6093,
"reading": 3651,
"state": "grace"
},
"exhaust": {
"floor": 6416,
"reading": 6448,
"state": "grace"
},
"intake_1": {
"floor": 2277,
"reading": 2860,
"state": "grace"
},
"intake_2": {
"floor": 2277,
"reading": 2820,
"state": "grace"
},
"purge": {
"floor": 345,
"reading": 632,
"state": "grace"
}
},
"fire_ok": false,
"fire_watch": "armed",
"gates_off": [
"coolant_critical"
],
"hold": true,
"limits": {
"air_assist_min_rpm": 6093,
"coolant_critical_c": 7.0,
"coolant_max_c": 6.0,
"coolant_min_c": 5.0,
"coolant_resume_c": 5.0,
"coolant_source": "local",
"exhaust_min_rpm": 6416,
"intake_min_rpm": 2277
},
"phase": "run",
"quiet_hold": false,
"reason": "",
"report_age_s": 1.0,
"resume_ok": false,
"up_c": 25.92,
"verdict": "OVERTEMP"
},
"cross_check": {
"body": "cool_temp_critical_c must be above cool_temp_max",
"status": 400
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"mode": {
"detail": "already in grbl mode",
"found": "grbl",
"needs": "grbl",
"ok": true,
"switched": false
},
"orig": {
"cool_temp_critical_c": "",
"cool_temp_max": "",
"cool_temp_resume": ""
},
"restored": {
"accel_watch": "watch",
"armed": false,
"down_c": 25.44,
"fan_gates": {
"air_assist": {
"floor": 6093,
"reading": 5515,
"state": "grace"
},
"exhaust": {
"floor": 6416,
"reading": 7031,
"state": "grace"
},
"intake_1": {
"floor": 2277,
"reading": 3226,
"state": "grace"
},
"intake_2": {
"floor": 2277,
"reading": 3239,
"state": "grace"
},
"purge": {
"floor": 345,
"reading": 632,
"state": "grace"
}
},
"fire_ok": true,
"fire_watch": "armed",
"gates_off": [],
"hold": false,
"limits": {
"air_assist_min_rpm": 6093,
"coolant_critical_c": 38.0,
"coolant_max_c": 33.0,
"coolant_min_c": 5.0,
"coolant_resume_c": 31.0,
"coolant_source": "local",
"exhaust_min_rpm": 6416,
"intake_min_rpm": 2277
},
"phase": "run",
"quiet_hold": false,
"reason": "",
"report_age_s": 1.0,
"resume_ok": true,
"up_c": 25.44,
"verdict": "OK"
}
},
"fingerprint": "1ffdf5a29b1751bf9f77c4271a09717b7c122090e3dcb39b0a8e69acd877a13d",
"image": "20260928170058 (dev)",
"log": [
"17:17:56 start cooling.critical-tier (auto, api) in campaign c-20260928171100-3ff5",
"17:17:56 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"17:17:56 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"17:17:56 queued by the unattended queue opened 2026-09-28T17:11:00Z",
"17:17:56 baseline: pre: clean",
"17:17:56 mode: test needs grbl - already in grbl mode",
"17:17:56 original: {'cool_temp_max': '', 'cool_temp_resume': '', 'cool_temp_critical_c': ''}",
"17:17:58 critical leg: verdict CRITICAL fire_ok False hold True gates_off [] (after 1 s)",
"17:18:01 critical off leg: verdict OVERTEMP fire_ok False hold True gates_off ['coolant_critical'] (after 1 s)",
"17:18:03 restored: verdict OK fire_ok True hold False gates_off [] (after 1 s)",
"17:18:04 baseline: post: clean",
"17:18:04 result PASS"
],
"manifest_sha": "98f8c4dad7130ecf1fa44e5e0f1a1b53e6b9359f005f22a1ddbee496375d9a9e",
"message": "",
"result": "PASS",
"test": "cooling.critical-tier",
"ts": "2026-09-28T17:18:04Z"
},
"requires": [
"cooling.gate-off"
],
"satisfied": true,
"source_sha": "a690934c0b05014a9624a6de5e3b5592c838e26cce4f6d6d474f9f4537dabaa8",
"subsystem": "cooling",
"title": "The coolant critical line is a fault above the ceiling's pause"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/cool.*"
],
[
"forgectrl",
"src/coolfmt.*"
],
[
"forgectrl",
"src/diag.*"
],
[
"forgectrl",
"src/gates.*"
],
[
"forgectrl",
"src/airflow.*"
],
[
"forgectrl",
"src/accel.*"
],
[
"forgectrl",
"src/settings.*"
],
[
"forgectrl",
"src/status.*"
],
[
"forgectrl",
"src/ui/**"
],
[
"grblhal-glowforge",
"src/glowforge_cooling.*"
],
[
"kernel-module-glowforge",
"src/thermal*"
],
[
"kernel-module-glowforge",
"src/pic*"
],
[
"forgectrl",
"src/main.c"
]
],
"fingerprint": "1c28061ad021ffbfe6199eb4abb07014127e06a0d2c82b17e94caac0c81ee34a",
"hardware": "api",
"id": "cooling.fan-gate-trips",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928162331-3969",
"duration_s": 43,
"evidence": {
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T16:23:31Z"
},
"exhaust_off": {
"cool": {
"accel_watch": "watch",
"armed": false,
"down_c": 25.21,
"fan_gates": {
"air_assist": {
"floor": 6093,
"reading": 5556,
"state": "grace"
},
"exhaust": {
"floor": 0,
"reading": 6991,
"state": "off"
},
"intake_1": {
"floor": 2277,
"reading": 3806,
"state": "grace"
},
"intake_2": {
"floor": 2277,
"reading": 3808,
"state": "grace"
},
"purge": {
"floor": 345,
"reading": 630,
"state": "grace"
}
},
"fire_ok": true,
"fire_watch": "armed",
"gates_off": [
"exhaust"
],
"hold": false,
"limits": {
"air_assist_min_rpm": 6093,
"coolant_critical_c": 38.0,
"coolant_max_c": 33.0,
"coolant_min_c": 5.0,
"coolant_resume_c": 31.0,
"coolant_source": "local",
"exhaust_min_rpm": 0,
"intake_min_rpm": 2277
},
"phase": "run",
"quiet_hold": false,
"reason": "",
"report_age_s": 1.0,
"resume_ok": true,
"up_c": 25.52,
"verdict": "OK"
},
"gate": {
"floor": 0,
"reading": 6991,
"state": "off"
}
},
"exhaust_trip": {
"cool": {
"accel_watch": "watch",
"armed": false,
"down_c": 26.16,
"fan_gates": {
"air_assist": {
"floor": 6093,
"reading": 10854,
"state": "ok"
},
"exhaust": {
"floor": 20000,
"reading": 11570,
"state": "TRIPPED"
},
"intake_1": {
"floor": 2277,
"reading": 4156,
"state": "ok"
},
"intake_2": {
"floor": 2277,
"reading": 4154,
"state": "ok"
},
"purge": {
"floor": 345,
"reading": 629,
"state": "ok"
}
},
"fire_ok": false,
"fire_watch": "armed",
"gates_off": [],
"hold": true,
"limits": {
"air_assist_min_rpm": 6093,
"coolant_critical_c": 38.0,
"coolant_max_c": 33.0,
"coolant_min_c": 5.0,
"coolant_resume_c": 31.0,
"coolant_source": "local",
"exhaust_min_rpm": 20000,
"intake_min_rpm": 2277
},
"phase": "run",
"quiet_hold": false,
"reason": "AIRFLOW: exhaust 11570 under the 20000 floor for 3 s (duty 65535, reads 65535) - hold, no resume this job",
"report_age_s": 1.0,
"resume_ok": false,
"up_c": 26.16,
"verdict": "AIRFLOW"
},
"gate": {
"floor": 20000,
"reading": 11570,
"state": "TRIPPED"
}
},
"exhaust_trip_after": {
"accel_watch": "watch",
"armed": false,
"down_c": 25.76,
"fan_gates": {
"air_assist": {
"floor": 6093,
"reading": 5585,
"state": "idle"
},
"exhaust": {
"floor": 20000,
"reading": 7170,
"state": "idle"
},
"intake_1": {
"floor": 2277,
"reading": 3770,
"state": "idle"
},
"intake_2": {
"floor": 2277,
"reading": 3798,
"state": "idle"
},
"purge": {
"floor": 345,
"reading": 630,
"state": "idle"
}
},
"fire_ok": true,
"fire_watch": "armed",
"gates_off": [],
"hold": false,
"limits": {
"air_assist_min_rpm": 6093,
"coolant_critical_c": 38.0,
"coolant_max_c": 33.0,
"coolant_min_c": 5.0,
"coolant_resume_c": 31.0,
"coolant_source": "local",
"exhaust_min_rpm": 20000,
"intake_min_rpm": 2277
},
"phase": "idle",
"quiet_hold": false,
"reason": "AIRFLOW: exhaust 11570 under the 20000 floor for 3 s (duty 65535, reads 65535) - hold, no resume this job",
"report_age_s": 1.0,
"resume_ok": true,
"up_c": 26.08,
"verdict": "OK"
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"mode": {
"detail": "already in grbl mode",
"found": "grbl",
"needs": "grbl",
"ok": true,
"switched": false
},
"orig": {
"cool_fan_grace_s": "12",
"cool_purge_min_current": "345",
"cool_tach_exhaust_min_rpm": "6416"
},
"purge_trip": {
"cool": {
"accel_watch": "watch",
"armed": false,
"down_c": 26.08,
"fan_gates": {
"air_assist": {
"floor": 6093,
"reading": 10854,
"state": "ok"
},
"exhaust": {
"floor": 6416,
"reading": 11665,
"state": "ok"
},
"intake_1": {
"floor": 2277,
"reading": 4154,
"state": "ok"
},
"intake_2": {
"floor": 2277,
"reading": 4174,
"state": "ok"
},
"purge": {
"floor": 1023,
"reading": 629,
"state": "TRIPPED"
}
},
"fire_ok": false,
"fire_watch": "armed",
"gates_off": [],
"hold": true,
"limits": {
"air_assist_min_rpm": 6093,
"coolant_critical_c": 38.0,
"coolant_max_c": 33.0,
"coolant_min_c": 5.0,
"coolant_resume_c": 31.0,
"coolant_source": "local",
"exhaust_min_rpm": 6416,
"intake_min_rpm": 2277
},
"phase": "run",
"quiet_hold": false,
"reason": "AIRFLOW: purge 629 under the 1023 floor for 3 s - hold, no resume this job",
"report_age_s": 0.0,
"resume_ok": false,
"up_c": 25.6,
"verdict": "AIRFLOW"
},
"gate": {
"floor": 1023,
"reading": 629,
"state": "TRIPPED"
}
},
"restored": {
"air_assist": {
"floor": 6093,
"reading": 10885,
"state": "ok"
},
"exhaust": {
"floor": 6416,
"reading": 11802,
"state": "ok"
},
"intake_1": {
"floor": 2277,
"reading": 4197,
"state": "ok"
},
"intake_2": {
"floor": 2277,
"reading": 4175,
"state": "ok"
},
"purge": {
"floor": 345,
"reading": 629,
"state": "ok"
}
}
},
"fingerprint": "1c28061ad021ffbfe6199eb4abb07014127e06a0d2c82b17e94caac0c81ee34a",
"image": "20260928153805 (dev)",
"log": [
"16:30:35 start cooling.fan-gate-trips (auto, api) in campaign c-20260928162331-3969",
"16:30:35 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:30:35 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"16:30:35 queued by the unattended queue opened 2026-09-28T16:23:31Z",
"16:30:35 baseline: pre: clean",
"16:30:35 mode: test needs grbl - already in grbl mode",
"16:30:35 original: {'cool_tach_exhaust_min_rpm': '6416', 'cool_purge_min_current': '345', 'cool_fan_grace_s': '12'}",
"16:30:47 exhaust trip leg: verdict AIRFLOW fire_ok False hold True gates_off [] (after 11 s)",
"16:31:00 purge trip leg: verdict AIRFLOW fire_ok False hold True gates_off [] (after 11 s)",
"16:31:02 exhaust off leg: verdict OK fire_ok True hold False gates_off ['exhaust'] (after 1 s)",
"16:31:06 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:31:17 restored: verdict OK fire_ok True hold False gates_off [] (after 14 s)",
"16:31:18 fans at run duty: {'exhaust': '11802/6416', 'intake_1': '4197/2277', 'intake_2': '4175/2277', 'air_assist': '10885/6093', 'purge': '629/345'}",
"16:31:18 baseline: post: clean",
"16:31:18 result PASS"
],
"manifest_sha": "faf9563c750bb8bd4bfc8778b6af053cddb63fa335ab946caf2f71631ede740f",
"message": "",
"result": "PASS",
"test": "cooling.fan-gate-trips",
"ts": "2026-09-28T16:31:18Z"
},
"requires": [
"cooling.gate-off"
],
"satisfied": true,
"source_sha": "90df7990a0574c6a145a6dded11b2943e44ffc6b19c88ef55562ebd0c5854eaf",
"subsystem": "cooling",
"title": "A fan under its floor past the grace is a fault; a floor of zero is off"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/cool.*"
],
[
"forgectrl",
"src/coolfmt.*"
],
[
"forgectrl",
"src/diag.*"
],
[
"forgectrl",
"src/gates.*"
],
[
"forgectrl",
"src/airflow.*"
],
[
"forgectrl",
"src/accel.*"
],
[
"forgectrl",
"src/settings.*"
],
[
"forgectrl",
"src/status.*"
],
[
"forgectrl",
"src/ui/**"
],
[
"grblhal-glowforge",
"src/glowforge_cooling.*"
],
[
"kernel-module-glowforge",
"src/thermal*"
],
[
"kernel-module-glowforge",
"src/pic*"
],
[
"forgectrl",
"src/main.c"
]
],
"fingerprint": "34c870519b916f90e867f82567b742cd9b5a62d3915f6122f7cb02bd3bbb8b05",
"hardware": "api",
"id": "cooling.flow-under-load",
"inherited": true,
"kind": "live",
"record": {
"answers": [],
"campaign": "c-20260928183105-64ee",
"duration_s": 174,
"evidence": {
"actions": [
{
"by": "operator",
"channel": "button",
"state": "presence",
"took_s": 84.4,
"ts": "2026-09-28T19:07:46Z"
},
{
"by": "fixture",
"channel": "button",
"state": "arm",
"took_s": 0.26,
"ts": "2026-09-28T19:07:46Z"
}
],
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "attended",
"ts": "2026-09-28T18:51:04Z"
},
"check_s": 50,
"disarm_after_m2_s": 0.6,
"dt_c": 9.2,
"emission_peak": 255,
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"heater_seen": true,
"job_to_verdict_s": 73.5,
"kind": "coolant flow verified",
"laser_share_c": 1.6,
"limit_c": 14.5,
"mode": {
"detail": "already in grbl mode",
"found": "grbl",
"needs": "grbl",
"ok": true,
"switched": false
},
"operator": {
"ack_live": true,
"ts": "2026-09-28T19:06:20Z"
},
"raw_rise_c": 13.4,
"rise_c": 11.8,
"verdict_line": "coolant flow verified (heater rise 11.8 C, dT 9.2 C; laser 1.6 off 13.4)",
"verdicts_seen": []
},
"fingerprint": "34c870519b916f90e867f82567b742cd9b5a62d3915f6122f7cb02bd3bbb8b05",
"image": "20260928182434 (dev)",
"log": [
"19:06:20 start cooling.flow-under-load (live, api) in campaign c-20260928183105-64ee",
"19:06:20 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"19:06:20 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"19:06:20 queued by the attended queue opened 2026-09-28T18:51:04Z",
"19:06:21 baseline: pre: clean",
"19:06:21 mode: test needs grbl - already in grbl mode",
"19:06:21 connect: Idle",
"19:06:21 NOTICE: LIVE FIRE. Eye protection on. Exhaust on. Extinguisher in reach. Put scrap under the head with 35 mm +X and 10 mm +Y clear, and close the lid. Then press the button on the machine to start.",
"19:06:21 READY: waiting for the operator's press on the machine (the bench then does every press in this test)",
"19:06:51 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"19:07:21 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"19:07:46 READY: operator present (press after 84.4 s); the bench takes the presses",
"19:07:46 ARM: the fixture presses when the button lights (the bench's arm_press opt-in)",
"19:07:46 ARM press by the fixture, button lit after 0.3 s",
"19:07:52 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"19:08:22 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"19:08:53 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"19:08:59 M2: ['ok']",
"19:08:59 engine: coolant flow verified (heater rise 11.8 C, dT 9.2 C; laser 1.6 off 13.4)",
"19:08:59 PASS: lit through the window, raw rise 13.4 C, laser 1.6 C off, judged 11.8 C against 14.5 (dT 9.2), window closed 0.6 s after M2",
"19:09:14 baseline: cool: smoke/armed=False/hold=False ended on its own after 15 s; the engine's own post-job work, not a leftover",
"19:09:14 baseline: post: clean",
"19:09:14 result PASS"
],
"manifest_sha": "84a155bfc701e865ae73f9818bc38c2d005324ab5ba0ed44b668ec8896179947",
"message": "",
"result": "PASS",
"test": "cooling.flow-under-load",
"ts": "2026-09-28T19:09:14Z"
},
"requires": [
"laser.emission-witness",
"cooling.flow-verify"
],
"satisfied": true,
"source_sha": "cb8f43af1c3fc270404162513c1bfda8baab90146bad005bd68b92f6d3c4c4cf",
"subsystem": "cooling",
"title": "The flow check reads true with the tube lit through its window"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/cool.*"
],
[
"forgectrl",
"src/coolfmt.*"
],
[
"forgectrl",
"src/diag.*"
],
[
"forgectrl",
"src/gates.*"
],
[
"forgectrl",
"src/airflow.*"
],
[
"forgectrl",
"src/accel.*"
],
[
"forgectrl",
"src/settings.*"
],
[
"forgectrl",
"src/status.*"
],
[
"forgectrl",
"src/ui/**"
],
[
"grblhal-glowforge",
"src/glowforge_cooling.*"
],
[
"kernel-module-glowforge",
"src/thermal*"
],
[
"kernel-module-glowforge",
"src/pic*"
],
[
"kernel-module-glowforge",
"src/head*"
]
],
"fingerprint": "2823821ba83e8aebf0fc87e222831c805d921b09faf14f08f2c5ae7533ce202b",
"hardware": "api",
"id": "cooling.fan-duty-readback",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928171100-3ff5",
"duration_s": 16,
"evidence": {
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T17:11:00Z"
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"idle_duties": {
"head/air_assist_pwm": 204,
"thermal/exhaust_pwm": 0,
"thermal/intake_pwm": 0
},
"mode": {
"detail": "already in grbl mode",
"found": "grbl",
"needs": "grbl",
"ok": true,
"switched": false
},
"put_back": {
"after_s": 1.0,
"duties": {
"head/air_assist_pwm": 1023,
"thermal/exhaust_pwm": 65535
}
},
"run_duties": {
"head/air_assist_pwm": 1023,
"thermal/exhaust_pwm": 65535,
"thermal/intake_pwm": 43278
},
"verdict_after": {
"hold": false,
"reason": "",
"verdict": "OK"
}
},
"fingerprint": "2823821ba83e8aebf0fc87e222831c805d921b09faf14f08f2c5ae7533ce202b",
"image": "20260928170058 (dev)",
"log": [
"17:18:04 start cooling.fan-duty-readback (auto, api) in campaign c-20260928171100-3ff5",
"17:18:05 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"17:18:05 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"17:18:05 queued by the unattended queue opened 2026-09-28T17:11:00Z",
"17:18:05 baseline: pre: clean",
"17:18:05 mode: test needs grbl - already in grbl mode",
"17:18:06 readback: verdict OK phase run fire_ok True hold False (after 1 s)",
"17:18:08 duties at run: {'head/air_assist_pwm': 1023, 'thermal/exhaust_pwm': 65535, 'thermal/intake_pwm': 43278}",
"17:18:08 written behind the engine's back: {'head/air_assist_pwm': 204, 'thermal/exhaust_pwm': 0}",
"17:18:09 put back after 1.0 s: {'head/air_assist_pwm': 1023, 'thermal/exhaust_pwm': 65535}",
"17:18:20 duties at idle: {'head/air_assist_pwm': 204, 'thermal/exhaust_pwm': 0, 'thermal/intake_pwm': 0}",
"17:18:21 baseline: post: clean",
"17:18:21 result PASS"
],
"manifest_sha": "98f8c4dad7130ecf1fa44e5e0f1a1b53e6b9359f005f22a1ddbee496375d9a9e",
"message": "",
"result": "PASS",
"test": "cooling.fan-duty-readback",
"ts": "2026-09-28T17:18:21Z"
},
"requires": [
"kernel.latch-locked-idle"
],
"satisfied": true,
"source_sha": "321adf956027d105bf6788e47be6dc49a331acc2b1df35c14c4c129dbbae9b29",
"subsystem": "cooling",
"title": "A fan duty a device lost is read back and put back inside a tick"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/cool.*"
],
[
"forgectrl",
"src/coolfmt.*"
],
[
"forgectrl",
"src/diag.*"
],
[
"forgectrl",
"src/gates.*"
],
[
"forgectrl",
"src/airflow.*"
],
[
"forgectrl",
"src/accel.*"
],
[
"forgectrl",
"src/settings.*"
],
[
"forgectrl",
"src/status.*"
],
[
"forgectrl",
"src/ui/**"
],
[
"grblhal-glowforge",
"src/glowforge_cooling.*"
],
[
"kernel-module-glowforge",
"src/thermal*"
],
[
"kernel-module-glowforge",
"src/pic*"
],
[
"forgectrl",
"src/super.*"
]
],
"fingerprint": "ac0ffdc6ddcaa4fb7b2adc4d37ea53419828b3c8e8582842419c86c989b152e8",
"hardware": "api",
"id": "cooling.fail-tier-stop",
"inherited": true,
"kind": "operator",
"record": {
"answers": [],
"campaign": "c-20260928171100-3ff5",
"duration_s": 19,
"evidence": {
"actions": [
{
"by": "operator",
"channel": "button",
"state": "arm",
"ts": "2026-09-28T17:18:22Z"
}
],
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T17:11:00Z"
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"mode": {
"detail": "already in grbl mode",
"found": "grbl",
"needs": "grbl",
"ok": true,
"switched": false
},
"orig": {
"cool_accel_abort": "",
"cool_accel_x_alert": "",
"cool_accel_y_alert": ""
},
"result": {
"emission": 0,
"engine_lines": [
"2026-09-28T17:18:23.742466+00:00 forgectrl[2882] WARNING cool: HEAD CRASH SIGNAL (axes xy) - motion stopped, laser locked"
],
"fault_cleared_s": 0.006922483444213867,
"kernel": "idle",
"latch_locked": true,
"mode_after": {
"controller": "running",
"gated": false,
"local": false,
"mode": "grbl",
"motion": "verified",
"pid": 3747,
"why": ""
},
"super_lines": [
"2026-09-28T17:18:23.742778+00:00 forgectrl[2882] WARNING super: head crash signal - the controller is stopped and started again"
]
}
},
"fingerprint": "ac0ffdc6ddcaa4fb7b2adc4d37ea53419828b3c8e8582842419c86c989b152e8",
"image": "20260928170058 (dev)",
"log": [
"17:18:21 start cooling.fail-tier-stop (operator, api) in campaign c-20260928171100-3ff5",
"17:18:21 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"17:18:21 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"17:18:21 fixture: running unattended (no prompt can be answered)",
"17:18:21 queued by the unattended queue opened 2026-09-28T17:11:00Z",
"17:18:21 baseline: pre: clean",
"17:18:21 mode: test needs grbl - already in grbl mode",
"17:18:22 connect: Idle",
"17:18:22 READY (fixture performs the step): DARK JOB (S0, nothing fires). Bed clear with 40 mm of free +X travel, lid closed. The head moves 20 mm and the controller restarts on its own.",
"17:18:22 NOTICE: The button lights white: press it to arm. The machine fires after your press.",
"17:18:23 the crash tier tripped after 1.3095321655273438 s",
"17:18:24 after the crash tier: {'mode_after': {'mode': 'grbl', 'controller': 'running', 'pid': 3747, 'motion': 'verified', 'gated': False, 'local': False, 'why': ''}, 'engine_lines': ['2026-09-28T17:18:23.742466+00:00 forgectrl[2882] WARNING cool: HEAD CRASH SIGNAL (axes xy) - motion stopped, laser locked'], 'super_lines': ['2026-09-28T17:18:23.742778+00:00 forgectrl[2882] WARNING super: head crash signal - the controller is stopped and started again'], 'emission': 0, 'kernel': 'idle', 'latch_locked': True}",
"17:18:24 the crash fault ended with the run session after 0.006922483444213867 s: {'phase': 'smoke', 'verdict': 'OK', 'hold': False, 'armed': False}",
"17:18:24 restore thresholds: POST /settings {'cool_accel_x_alert': '', 'cool_accel_y_alert': '', 'cool_accel_abort': ''} -> 200",
"17:18:25 PASS: the crash tier stopped the job, locked the latch, and the supervisor restarted the controller (pid 3429 -> 3747)",
"17:18:41 baseline: cool: smoke/armed=False/hold=False ended on its own after 16 s; the engine's own post-job work, not a leftover",
"17:18:41 baseline: post: clean",
"17:18:41 result PASS"
],
"manifest_sha": "98f8c4dad7130ecf1fa44e5e0f1a1b53e6b9359f005f22a1ddbee496375d9a9e",
"message": "",
"result": "PASS",
"test": "cooling.fail-tier-stop",
"ts": "2026-09-28T17:18:41Z"
},
"requires": [
"cooling.crash-watch-plumbing",
"motion.deadman"
],
"satisfied": true,
"source_sha": "ed9a2a525b148645971ee351f7fe7df37cc32ee2fb356da5ff9711f5c1ae1cc9",
"subsystem": "cooling",
"title": "A fail-tier verdict ends the controller: CRASH stops motion, locks the laser, and the supervisor restarts the controller"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/cool.*"
],
[
"forgectrl",
"src/coolfmt.*"
],
[
"forgectrl",
"src/diag.*"
],
[
"forgectrl",
"src/gates.*"
],
[
"forgectrl",
"src/airflow.*"
],
[
"forgectrl",
"src/accel.*"
],
[
"forgectrl",
"src/settings.*"
],
[
"forgectrl",
"src/status.*"
],
[
"forgectrl",
"src/ui/**"
],
[
"grblhal-glowforge",
"src/glowforge_cooling.*"
],
[
"kernel-module-glowforge",
"src/thermal*"
],
[
"kernel-module-glowforge",
"src/pic*"
],
[
"forgectrl",
"src/super.*"
],
[
"forgectrl",
"src/main.c"
],
[
"forgectrl",
"src/auth.*"
]
],
"fingerprint": "cb946041306a3e6d8ec957867b45df8ac6c51e60a4ae106edbac6b614e093c63",
"hardware": "api",
"id": "cooling.report-channel",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928171100-3ff5",
"duration_s": 10,
"evidence": {
"after": [
[
"run",
{
"thermal/exhaust_pwm": 65535,
"thermal/intake_pwm": 43278
}
],
[
"run",
{
"thermal/exhaust_pwm": 65535,
"thermal/intake_pwm": 43278
}
],
[
"run",
{
"thermal/exhaust_pwm": 65535,
"thermal/intake_pwm": 43278
}
],
[
"run",
{
"thermal/exhaust_pwm": 65535,
"thermal/intake_pwm": 43278
}
],
[
"run",
{
"thermal/exhaust_pwm": 65535,
"thermal/intake_pwm": 43278
}
]
],
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T17:11:00Z"
},
"before": {
"duties": {
"thermal/exhaust_pwm": 65535,
"thermal/intake_pwm": 43278
},
"phase": "run"
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"mode": {
"detail": "already in grbl mode",
"found": "grbl",
"needs": "grbl",
"ok": true,
"switched": false
},
"refused": {
"a made-up secret": [
403,
"the report channel is the running controller's alone"
],
"a made-up secret and a forged Host": [
403,
"the report channel is the running controller's alone"
],
"no secret": [
403,
"the report channel is the running controller's alone"
]
}
},
"fingerprint": "cb946041306a3e6d8ec957867b45df8ac6c51e60a4ae106edbac6b614e093c63",
"image": "20260928170058 (dev)",
"log": [
"17:18:41 start cooling.report-channel (auto, api) in campaign c-20260928171100-3ff5",
"17:18:41 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"17:18:41 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"17:18:41 queued by the unattended queue opened 2026-09-28T17:11:00Z",
"17:18:41 baseline: pre: clean",
"17:18:41 mode: test needs grbl - already in grbl mode",
"17:18:50 phase and duties over 5 s after three forged idle reports: [['run', {'thermal/exhaust_pwm': 65535, 'thermal/intake_pwm': 43278}], ['run', {'thermal/exhaust_pwm': 65535, 'thermal/intake_pwm': 43278}], ['run', {'thermal/exhaust_pwm': 65535, 'thermal/intake_pwm': 43278}], ['run', {'thermal/exhaust_pwm': 65535, 'thermal/intake_pwm': 43278}], ['run', {'thermal/exhaust_pwm': 65535, 'thermal/intake_pwm': 43278}]]",
"17:18:51 PASS: three forged idle reports from this host were refused inside a run session, and the engine held its phase and its fan duties",
"17:18:51 baseline: post: clean",
"17:18:51 result PASS"
],
"manifest_sha": "98f8c4dad7130ecf1fa44e5e0f1a1b53e6b9359f005f22a1ddbee496375d9a9e",
"message": "",
"result": "PASS",
"test": "cooling.report-channel",
"ts": "2026-09-28T17:18:51Z"
},
"requires": [
"forgectrl.auth"
],
"satisfied": true,
"source_sha": "089179f54712164515bc37b4df849cf4a3996fe3afbc4609b2ded8fc64455443",
"subsystem": "cooling",
"title": "A forged cooling report inside a run session is refused and changes nothing"
},
{
"always": false,
"covers": [
[
"grblhal-glowforge",
"src/**"
],
[
"forgectrl",
"src/main.c"
]
],
"fingerprint": "ec004727f96196de345fcd907f5b0213100c686c450f389c6c12c772bec365a4",
"hardware": "api",
"id": "laser.power-floor",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928171100-3ff5",
"duration_s": 0,
"evidence": {
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T17:11:00Z"
},
"configured_floor": 14.0,
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"mode": {
"detail": "already in grbl mode",
"found": "grbl",
"needs": "grbl",
"ok": true,
"switched": false
},
"pwmsar_floor": 17,
"settings": {
"$30": 1000.0,
"$31": 0.0,
"$32": 1.0,
"$35": 14.0,
"$36": 100.0
}
},
"fingerprint": "ec004727f96196de345fcd907f5b0213100c686c450f389c6c12c772bec365a4",
"image": "20260928170058 (dev)",
"log": [
"17:18:51 start laser.power-floor (auto, api) in campaign c-20260928171100-3ff5",
"17:18:51 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"17:18:51 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"17:18:51 queued by the unattended queue opened 2026-09-28T17:11:00Z",
"17:18:52 baseline: pre: clean",
"17:18:52 mode: test needs grbl - already in grbl mode",
"17:18:52 $35=14.0% -> PWMSAR 17 of 127 ($31=0.0, $32=1.0, $36=100.0)",
"17:18:52 PASS: nonzero S never commands less than PWMSAR 17",
"17:18:52 baseline: post: clean",
"17:18:52 result PASS"
],
"manifest_sha": "98f8c4dad7130ecf1fa44e5e0f1a1b53e6b9359f005f22a1ddbee496375d9a9e",
"message": "",
"result": "PASS",
"test": "laser.power-floor",
"ts": "2026-09-28T17:18:52Z"
},
"requires": [],
"satisfied": true,
"source_sha": "77ae799e870932c44ebb31bb83e1ca87e198697661833316ec55a0165718ab88",
"subsystem": "laser",
"title": "The derived floor is the one in force"
},
{
"always": true,
"covers": [
[
"grblhal-glowforge",
"src/**"
],
[
"kernel-module-glowforge",
"**"
],
[
"forgectrl",
"src/super.c"
],
[
"forgectrl",
"src/cool.c"
],
[
"forgectrl",
"src/status.c"
],
[
"forgectrl",
"src/main.c"
]
],
"fingerprint": "dd389a6afd4ab4d1a2f17281269c434f1a3dbac852276527abf69a5802a898bf",
"hardware": "api",
"id": "laser.emission-witness",
"inherited": false,
"kind": "live",
"record": {
"answers": [
{
"answer": "Yes",
"question": "Did the laser mark a 20 mm square outline on the scrap, all four sides?",
"ts": "2026-09-29T00:03:23Z"
}
],
"campaign": "c-20260929000044-e1ea",
"duration_s": 47,
"evidence": {
"actions": [
{
"by": "operator",
"channel": "button",
"state": "presence",
"took_s": 12.6,
"ts": "2026-09-29T00:02:59Z"
},
{
"by": "fixture",
"channel": "button",
"state": "arm",
"took_s": 0.25,
"ts": "2026-09-29T00:02:59Z"
}
],
"armed_seen": true,
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "attended",
"ts": "2026-09-29T00:02:45Z"
},
"beam": {
"delta": 1093,
"digital_seen": true,
"idle": 1854,
"peak": 2947,
"samples": 103
},
"button_dark": false,
"button_latch_set_at": [],
"button_latch_unlocked_max": 0,
"button_latch_unlocked_samples": 50,
"disarm_after_idle_s": 0.0,
"emission_end": 0,
"emission_peak": 151,
"exhaust_at_first_fire": 11739,
"exhaust_floor": 6416.0,
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"hv_enable_back_lit": true,
"hv_enable_dipped": true,
"hv_max": 1023,
"hv_min": 0,
"idle_airflow_fire": [],
"lid_ir_peak": [
53,
52,
55,
62
],
"mode": {
"detail": "already in grbl mode",
"found": "grbl",
"needs": "grbl",
"ok": true,
"switched": false
},
"operator": {
"ack_live": true,
"ts": "2026-09-29T00:02:45Z"
},
"pgood_peak": 255,
"pre_fire": {
"armed": false,
"beam": 1854,
"beam_d": 0,
"button": false,
"button_latch": 1,
"button_lit": false,
"emission": 0,
"exhaust": 0,
"faults": 0,
"fire_watch": "armed",
"gstate": null,
"homed": false,
"hv": 0,
"hv_enable": false,
"il": 45,
"ir": [
50,
50,
53,
59
],
"kstate": "idle",
"lid": true,
"locked": true,
"msgs": "",
"pgood": 255,
"phase": "idle",
"t": 1790640166.524784,
"verdict": "OK"
},
"samples": 103,
"trail": [
[
0.0,
null,
"idle",
0,
false,
"idle",
45,
1,
true,
true,
false,
false,
1854,
0,
null
],
[
0.03,
"Idle",
"idle",
0,
false,
"idle",
45,
1,
true,
true,
false,
false,
1855,
0,
"[MSG:Info: press the button to start the laser job]"
],
[
0.27,
"Idle",
"idle",
0,
true,
"run",
33,
0,
false,
true,
false,
false,
1856,
0,
null
],
[
0.5,
"Idle",
"idle",
0,
true,
"run",
33,
0,
false,
true,
false,
false,
1856,
0,
null
],
[
0.68,
"Idle",
"idle",
0,
true,
"run",
33,
0,
false,
true,
false,
false,
1854,
0,
null
],
[
0.86,
"Idle",
"idle",
0,
true,
"run",
33,
0,
false,
true,
false,
false,
1857,
0,
null
],
[
1.09,
"Idle",
"idle",
0,
true,
"run",
33,
0,
false,
true,
false,
false,
1856,
0,
null
],
[
1.27,
"Idle",
"idle",
0,
true,
"run",
33,
0,
false,
true,
false,
false,
1855,
0,
null
],
[
1.45,
"Idle",
"idle",
0,
true,
"run",
33,
0,
false,
true,
false,
false,
1854,
0,
null
],
[
1.63,
"Idle",
"idle",
0,
true,
"run",
33,
0,
false,
true,
false,
false,
1858,
0,
null
],
[
1.81,
"Idle",
"idle",
0,
true,
"run",
33,
0,
false,
true,
false,
false,
1856,
0,
null
],
[
1.99,
"Idle",
"idle",
0,
true,
"run",
33,
0,
false,
true,
false,
false,
1858,
0,
null
],
[
2.17,
"Idle",
"idle",
0,
true,
"run",
33,
0,
false,
true,
false,
false,
1855,
0,
null
],
[
2.36,
"Idle",
"idle",
0,
true,
"run",
33,
0,
false,
true,
false,
false,
1854,
0,
null
],
[
2.54,
"Idle",
"idle",
0,
true,
"run",
33,
0,
false,
true,
false,
false,
1855,
0,
null
],
[
2.72,
"Idle",
"idle",
0,
true,
"run",
33,
0,
false,
true,
false,
false,
1859,
0,
null
],
[
2.9,
"Idle",
"idle",
0,
true,
"run",
33,
0,
false,
true,
false,
false,
1855,
0,
null
],
[
3.07,
"Idle",
"idle",
0,
true,
"run",
33,
0,
false,
true,
false,
false,
1852,
0,
null
],
[
3.25,
"Idle",
"idle",
0,
true,
"run",
33,
0,
false,
true,
false,
false,
1856,
0,
null
],
[
3.49,
"Idle",
"idle",
0,
true,
"run",
33,
0,
false,
true,
false,
false,
1853,
0,
null
],
[
3.66,
"Idle",
"idle",
0,
true,
"run",
33,
0,
false,
true,
false,
false,
1856,
0,
null
],
[
3.84,
"Idle",
"idle",
0,
true,
"run",
33,
0,
false,
true,
false,
false,
1855,
0,
null
],
[
4.02,
"Idle",
"idle",
0,
true,
"run",
33,
0,
false,
true,
false,
false,
1855,
0,
null
],
[
4.2,
"Idle",
"idle",
0,
true,
"run",
33,
0,
false,
true,
false,
false,
1857,
0,
null
],
[
4.37,
"Idle",
"idle",
0,
true,
"run",
33,
0,
false,
true,
false,
false,
1855,
0,
null
],
[
4.56,
"Idle",
"idle",
0,
true,
"run",
33,
0,
false,
true,
false,
false,
1856,
0,
null
],
[
4.73,
"Idle",
"idle",
0,
true,
"run",
33,
0,
false,
true,
false,
false,
1857,
0,
null
],
[
4.91,
"Idle",
"idle",
0,
true,
"run",
33,
0,
false,
true,
false,
false,
1854,
0,
null
],
[
5.09,
"Idle",
"idle",
0,
true,
"run",
33,
0,
false,
true,
false,
false,
1856,
0,
null
],
[
5.26,
"Idle",
"idle",
0,
true,
"run",
33,
0,
false,
true,
false,
false,
1854,
0,
null
],
[
5.44,
"Idle",
"idle",
0,
true,
"run",
33,
0,
false,
true,
false,
false,
1855,
0,
null
],
[
5.63,
"Run",
"idle",
0,
true,
"run",
33,
0,
false,
true,
false,
false,
1856,
0,
"[MSG:Info: laser armed (density, floor 14 %, curve custom)]"
],
[
5.84,
"Run",
"running",
0,
true,
"run",
1,
0,
false,
true,
false,
true,
1856,
0,
null
],
[
6.03,
"Run",
"running",
0,
true,
"run",
1,
0,
false,
true,
false,
true,
2915,
965,
null
],
[
6.23,
"Run",
"running",
0,
true,
"run",
2,
0,
false,
true,
false,
true,
2947,
303,
null
],
[
6.41,
"Run",
"running",
0,
true,
"run",
1,
0,
false,
true,
false,
true,
2846,
314,
null
],
[
6.61,
"Run",
"running",
0,
true,
"run",
2,
0,
false,
true,
false,
true,
2807,
1006,
null
],
[
6.82,
"Run",
"running",
107,
true,
"run",
1,
0,
false,
true,
false,
true,
2783,
248,
null
],
[
7.02,
"Run",
"running",
107,
true,
"run",
2,
0,
false,
true,
false,
true,
2760,
890,
null
],
[
7.21,
"Run",
"running",
107,
true,
"run",
1,
0,
false,
true,
false,
true,
2696,
465,
null
],
[
7.4,
"Run",
"running",
107,
true,
"run",
1,
0,
false,
true,
false,
true,
2682,
383,
null
],
[
7.59,
"Run",
"running",
107,
true,
"run",
2,
0,
false,
true,
false,
true,
2679,
301,
null
],
[
7.78,
"Run",
"running",
148,
true,
"run",
1,
0,
false,
true,
false,
true,
2639,
494,
null
],
[
8.01,
"Run",
"running",
148,
true,
"run",
1,
0,
false,
true,
false,
true,
2640,
651,
null
],
[
8.2,
"Run",
"running",
148,
true,
"run",
2,
0,
false,
true,
false,
true,
2646,
833,
null
],
[
8.39,
"Run",
"running",
148,
true,
"run",
2,
0,
false,
true,
false,
true,
2638,
328,
null
],
[
8.58,
"Run",
"running",
148,
true,
"run",
2,
0,
false,
true,
false,
true,
2666,
575,
null
],
[
8.77,
"Run",
"running",
147,
true,
"run",
1,
0,
false,
true,
false,
true,
2637,
413,
null
],
[
8.96,
"Run",
"running",
147,
true,
"run",
2,
0,
false,
true,
false,
true,
2647,
928,
null
],
[
9.18,
"Run",
"running",
147,
true,
"run",
1,
0,
false,
true,
false,
true,
2669,
230,
null
],
[
9.37,
"Run",
"running",
147,
true,
"run",
1,
0,
false,
true,
false,
true,
2676,
205,
null
],
[
9.56,
"Run",
"running",
147,
true,
"run",
2,
0,
false,
true,
false,
true,
2673,
293,
null
],
[
9.74,
"Idle",
"running",
149,
true,
"run",
1,
0,
false,
true,
false,
true,
2640,
393,
null
],
[
9.94,
"Idle",
"idle",
149,
true,
"run",
1,
0,
false,
true,
false,
true,
1878,
0,
null
],
[
10.12,
"Idle",
"idle",
149,
true,
"run",
1,
0,
false,
true,
false,
true,
1869,
0,
null
],
[
10.31,
"Idle",
"idle",
149,
true,
"run",
1,
0,
false,
true,
false,
true,
1866,
0,
null
],
[
10.49,
"Idle",
"idle",
149,
true,
"run",
33,
0,
false,
true,
false,
false,
1865,
0,
null
],
[
10.67,
"Idle",
"idle",
45,
true,
"run",
33,
0,
false,
true,
false,
false,
1862,
0,
null
],
[
10.85,
"Idle",
"idle",
45,
true,
"run",
33,
0,
false,
true,
false,
false,
1865,
0,
null
],
[
11.03,
"Idle",
"idle",
45,
true,
"run",
33,
0,
false,
true,
false,
false,
1860,
0,
null
],
[
11.21,
"Idle",
"idle",
45,
true,
"run",
33,
0,
false,
true,
false,
false,
1861,
0,
null
],
[
11.42,
"Idle",
"idle",
45,
true,
"run",
33,
0,
false,
true,
false,
false,
1862,
0,
null
],
[
11.64,
"Idle",
"idle",
0,
true,
"run",
33,
0,
false,
true,
false,
false,
1863,
0,
null
],
[
11.82,
"Idle",
"idle",
0,
true,
"run",
33,
0,
false,
true,
false,
false,
1862,
0,
null
],
[
12.01,
"Idle",
"idle",
0,
true,
"run",
33,
0,
false,
true,
false,
false,
1860,
0,
null
],
[
12.19,
"Run",
"idle",
0,
true,
"run",
33,
0,
false,
true,
false,
false,
1861,
0,
null
],
[
12.38,
"Run",
"running",
0,
true,
"run",
1,
0,
false,
true,
false,
true,
1859,
0,
null
],
[
12.6,
"Run",
"running",
0,
true,
"run",
1,
0,
false,
true,
false,
true,
2654,
354,
null
],
[
12.79,
"Run",
"running",
28,
true,
"run",
2,
0,
false,
true,
false,
true,
2621,
299,
null
],
[
12.99,
"Run",
"running",
28,
true,
"run",
1,
0,
false,
true,
false,
true,
2650,
833,
null
],
[
13.18,
"Run",
"running",
28,
true,
"run",
1,
0,
false,
true,
false,
true,
2663,
88,
null
],
[
13.37,
"Run",
"running",
28,
true,
"run",
2,
0,
false,
true,
false,
true,
2654,
223,
null
],
[
13.56,
"Run",
"running",
28,
true,
"run",
1,
0,
false,
true,
false,
true,
2692,
1023,
null
],
[
13.77,
"Run",
"running",
151,
true,
"run",
2,
0,
false,
true,
false,
true,
2643,
375,
null
],
[
13.96,
"Run",
"running",
151,
true,
"run",
3,
0,
false,
true,
false,
true,
2686,
370,
null
],
[
14.15,
"Run",
"running",
151,
true,
"run",
2,
0,
false,
true,
false,
true,
2679,
498,
null
],
[
14.35,
"Run",
"running",
151,
true,
"run",
2,
0,
false,
true,
false,
true,
2717,
586,
null
],
[
14.53,
"Run",
"running",
151,
true,
"run",
2,
0,
false,
true,
false,
true,
2685,
283,
null
],
[
14.72,
"Run",
"running",
147,
true,
"run",
2,
0,
false,
true,
false,
true,
2727,
146,
null
],
[
14.97,
"Run",
"running",
147,
true,
"run",
2,
0,
false,
true,
false,
true,
2743,
650,
null
],
[
15.16,
"Run",
"running",
147,
true,
"run",
1,
0,
false,
true,
false,
true,
2746,
418,
null
],
[
15.35,
"Run",
"running",
147,
true,
"run",
1,
0,
false,
true,
false,
true,
2713,
189,
null
],
[
15.54,
"Run",
"running",
147,
true,
"run",
2,
0,
false,
true,
false,
true,
2744,
407,
null
],
[
15.73,
"Run",
"running",
150,
true,
"run",
2,
0,
false,
true,
false,
true,
2706,
373,
null
],
[
15.92,
"Run",
"running",
150,
true,
"run",
1,
0,
false,
true,
false,
true,
2707,
500,
null
],
[
16.14,
"Run",
"running",
150,
true,
"run",
2,
0,
false,
true,
false,
true,
2734,
419,
"[MSG:Pgm End]"
],
[
16.38,
"Idle",
"running",
150,
true,
"run",
1,
0,
false,
true,
false,
true,
2729,
437,
"[MSG:Info: laser disarmed - latch locked]"
],
[
16.6,
"Idle",
"idle",
150,
false,
"run",
13,
1,
true,
true,
false,
true,
1872,
0,
null
],
[
16.78,
"Idle",
"idle",
122,
false,
"run",
13,
1,
true,
true,
false,
true,
1871,
0,
null
],
[
16.96,
"Idle",
"idle",
122,
false,
"run",
45,
1,
true,
true,
false,
false,
1867,
0,
null
],
[
17.17,
"Idle",
"idle",
122,
false,
"run",
45,
1,
true,
true,
false,
false,
1865,
0,
null
],
[
17.34,
"Idle",
"idle",
122,
false,
"smoke",
45,
1,
true,
true,
false,
false,
1866,
0,
null
],
[
17.55,
"Idle",
"idle",
122,
false,
"smoke",
45,
1,
true,
true,
false,
false,
1863,
0,
null
],
[
17.73,
"Idle",
"idle",
0,
false,
"smoke",
45,
1,
true,
true,
false,
false,
1866,
0,
null
],
[
17.9,
"Idle",
"idle",
0,
false,
"smoke",
45,
1,
true,
true,
false,
false,
1864,
0,
null
],
[
18.08,
"Idle",
"idle",
0,
false,
"smoke",
45,
1,
true,
true,
false,
false,
1863,
0,
null
],
[
18.26,
"Idle",
"idle",
0,
false,
"smoke",
45,
1,
true,
true,
false,
false,
1865,
0,
null
],
[
18.44,
"Idle",
"idle",
0,
false,
"smoke",
45,
1,
true,
true,
false,
false,
1863,
0,
null
],
[
18.64,
"Idle",
"idle",
0,
false,
"smoke",
45,
1,
true,
true,
false,
false,
1863,
0,
null
],
[
18.86,
"Idle",
"idle",
0,
false,
"smoke",
45,
1,
true,
true,
false,
false,
1863,
0,
null
],
[
19.03,
"Idle",
"idle",
0,
false,
"smoke",
45,
1,
true,
true,
false,
false,
1864,
0,
null
],
[
19.21,
"Idle",
"idle",
0,
false,
"smoke",
45,
1,
true,
true,
false,
false,
1864,
0,
null
],
[
19.39,
"Idle",
"idle",
0,
false,
"smoke",
45,
1,
true,
true,
false,
false,
1862,
0,
null
]
],
"trail_fields": [
"t",
"gstate",
"kstate",
"emission",
"armed",
"phase",
"il",
"button_latch",
"locked",
"lid",
"button",
"hv_enable",
"beam",
"hv",
"msgs"
]
},
"fingerprint": "dd389a6afd4ab4d1a2f17281269c434f1a3dbac852276527abf69a5802a898bf",
"image": "20260928194539 (dev)",
"log": [
"00:02:45 start laser.emission-witness (live, api) in campaign c-20260929000044-e1ea",
"00:02:45 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"00:02:45 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"00:02:45 queued by the attended queue opened 2026-09-29T00:02:45Z",
"00:02:46 baseline: pre: clean",
"00:02:46 mode: test needs grbl - already in grbl mode",
"00:02:46 connect: Idle",
"00:02:46 pre-fire: emission=0 hv=0 armed=False verdict=OK",
"00:02:46 NOTICE: LIVE FIRE. Eye protection on. Exhaust on. Extinguisher in reach. Put scrap under the head with 20 mm +X and +Y clear, and close the lid. Then press the button on the machine to start.",
"00:02:46 READY: waiting for the operator's press on the machine (the bench then does every press in this test)",
"00:02:59 READY: operator present (press after 12.6 s); the bench takes the presses",
"00:02:59 ARM: the fixture presses when the button lights (the bench's arm_press opt-in)",
"00:02:59 ARM press by the fixture, button lit after 0.3 s",
"00:03:16 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"00:03:18 beam detector: idle 1854, peak 2947, digital asserted True",
"00:03:18 emission_samples peak=151 end=0; hv 0..1023; lid_ir peak [53, 52, 55, 62]; armed seen True",
"00:03:18 dwell gap: button latch through the unlocked window max=0 over 50 samples (set at []); HV_ENABLE dipped=True, back with emission after it=True",
"00:03:18 exhaust at the first emission sample: 11739 rpm (floor 6416)",
"00:03:18 time-to-disarm after Idle: 0.0 s",
"00:03:18 button dark after 0.0 s",
"00:03:18 PROMPT: Did the laser mark a 20 mm square outline on the scrap, all four sides?",
"00:03:23 ANSWER: Yes",
"00:03:23 PASS: emission peak 151 -> 0, HV 0..1023, beam +1093, disarmed 0.0 s after Idle, button dark, mark confirmed",
"00:03:33 baseline: cool: smoke/armed=False/hold=False ended on its own after 9 s; the engine's own post-job work, not a leftover",
"00:03:33 baseline: post: clean",
"00:03:33 result PASS"
],
"manifest_sha": "e7ca694f20116a46222907e7ba9222021efd2c007f9394f8b3bb9f3ff14875ba",
"message": "",
"result": "PASS",
"test": "laser.emission-witness",
"ts": "2026-09-29T00:03:33Z"
},
"requires": [
"kernel.latch-locked-idle",
"kernel.k1-k2",
"motion.jog-roundtrip"
],
"satisfied": true,
"source_sha": "df94745ca09df9cf1fee94b721138858959d46711b311e4b682c50c69fe10923",
"subsystem": "laser",
"title": "Live emission witness (S400 vector mark) and job-based disarm"
},
{
"always": false,
"covers": [
[
"grblhal-glowforge",
"src/**"
],
[
"kernel-module-glowforge",
"**"
],
[
"forgectrl",
"src/super.c"
],
[
"forgectrl",
"src/cool.c"
],
[
"forgectrl",
"src/status.c"
],
[
"forgectrl",
"src/main.c"
]
],
"fingerprint": "8ea5ae89d74c7466ac917239e83a6844b17feb736b086bf88fb1432593eff847",
"hardware": "api",
"id": "laser.m5-rapid-dark",
"inherited": true,
"kind": "live",
"record": {
"answers": [],
"campaign": "c-20260928183105-64ee",
"duration_s": 97,
"evidence": {
"actions": [
{
"by": "operator",
"channel": "button",
"state": "presence",
"took_s": 60.31,
"ts": "2026-09-28T19:10:16Z"
},
{
"by": "fixture",
"channel": "button",
"state": "arm",
"took_s": 0.26,
"ts": "2026-09-28T19:10:16Z"
}
],
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "attended",
"ts": "2026-09-28T18:51:04Z"
},
"emission_peak": 147,
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"hv_tail_max": 0,
"mode": {
"detail": "already in grbl mode",
"found": "grbl",
"needs": "grbl",
"ok": true,
"switched": false
},
"operator": {
"ack_live": true,
"ts": "2026-09-28T19:09:15Z"
},
"relit_first": null,
"relit_samples": 0,
"samples": 112,
"tail_samples": 59
},
"fingerprint": "8ea5ae89d74c7466ac917239e83a6844b17feb736b086bf88fb1432593eff847",
"image": "20260928182434 (dev)",
"log": [
"19:09:15 start laser.m5-rapid-dark (live, api) in campaign c-20260928183105-64ee",
"19:09:15 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"19:09:15 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"19:09:15 queued by the attended queue opened 2026-09-28T18:51:04Z",
"19:09:15 baseline: pre: clean",
"19:09:15 mode: test needs grbl - already in grbl mode",
"19:09:16 connect: Idle",
"19:09:16 NOTICE: LIVE FIRE. Eye protection on. Exhaust on. Extinguisher in reach. Put scrap under the head with 20 mm +X clear, and close the lid. Then press the button on the machine to start.",
"19:09:16 READY: waiting for the operator's press on the machine (the bench then does every press in this test)",
"19:09:45 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"19:10:16 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"19:10:16 READY: operator present (press after 60.3 s); the bench takes the presses",
"19:10:16 ARM: the fixture presses when the button lights (the bench's arm_press opt-in)",
"19:10:17 ARM press by the fixture, button lit after 0.3 s",
"19:10:38 emission peak 147; dark from +10.2 s; 59 samples after it spanning 11.4 s, 0 with emission, HV max after dark 0",
"19:10:38 PASS: emission peak 147 on the G1, 0 through both rapids, HV 0 after the M5",
"19:10:46 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"19:10:52 baseline: cool: smoke/armed=False/hold=False ended on its own after 14 s; the engine's own post-job work, not a leftover",
"19:10:52 baseline: post: clean",
"19:10:52 result PASS"
],
"manifest_sha": "84a155bfc701e865ae73f9818bc38c2d005324ab5ba0ed44b668ec8896179947",
"message": "",
"result": "PASS",
"test": "laser.m5-rapid-dark",
"ts": "2026-09-28T19:10:52Z"
},
"requires": [
"laser.emission-witness"
],
"satisfied": true,
"source_sha": "c3cf0fc236307ca03f7cf473dea96cfc957d79942b4fa65c285119600a0e4e77",
"subsystem": "laser",
"title": "The rapids after an M5 ship dark"
},
{
"always": false,
"covers": [
[
"grblhal-glowforge",
"src/**"
],
[
"kernel-module-glowforge",
"**"
],
[
"forgectrl",
"src/super.c"
],
[
"forgectrl",
"src/cool.c"
],
[
"forgectrl",
"src/status.c"
],
[
"forgectrl",
"src/main.c"
]
],
"fingerprint": "42506ed224f2655923caffbe066139d98c2edbb64f231ecf32f7a871cfa1c201",
"hardware": "api",
"id": "laser.disarm-in-hold",
"inherited": true,
"kind": "live",
"record": {
"answers": [],
"campaign": "c-20260928183105-64ee",
"duration_s": 90,
"evidence": {
"actions": [
{
"by": "operator",
"channel": "button",
"state": "presence",
"took_s": 6.35,
"ts": "2026-09-28T19:11:00Z"
},
{
"by": "fixture",
"channel": "button",
"state": "arm",
"took_s": 0.25,
"ts": "2026-09-28T19:11:00Z"
}
],
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "attended",
"ts": "2026-09-28T18:51:04Z"
},
"button_dark": false,
"disarmed_after_s": 60.9,
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"held_state": "Hold:1",
"left_at_mm": [
11.35,
0.0
],
"left_hold": null,
"mode": {
"detail": "already in grbl mode",
"found": "grbl",
"needs": "grbl",
"ok": true,
"switched": false
},
"operator": {
"ack_live": true,
"ts": "2026-09-28T19:10:53Z"
},
"returned_mm": [
3.95,
0.0
]
},
"fingerprint": "42506ed224f2655923caffbe066139d98c2edbb64f231ecf32f7a871cfa1c201",
"image": "20260928182434 (dev)",
"log": [
"19:10:52 start laser.disarm-in-hold (live, api) in campaign c-20260928183105-64ee",
"19:10:53 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"19:10:53 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"19:10:53 queued by the attended queue opened 2026-09-28T18:51:04Z",
"19:10:53 baseline: pre: clean",
"19:10:53 mode: test needs grbl - already in grbl mode",
"19:10:53 connect: Idle",
"19:10:53 NOTICE: LIVE FIRE. Eye protection on. Exhaust on. Extinguisher in reach. Put scrap under the head with 40 mm +X clear, and close the lid. Then press the button on the machine to start.",
"19:10:53 READY: waiting for the operator's press on the machine (the bench then does every press in this test)",
"19:11:00 READY: operator present (press after 6.3 s); the bench takes the presses",
"19:11:00 armed; waiting for motion to start (arm + your button press)...",
"19:11:00 ARM: the fixture presses when the button lights (the bench's arm_press opt-in)",
"19:11:00 ARM press by the fixture, button lit after 0.3 s",
"19:11:04 moving under laser: Run; feed-hold in 2 s",
"19:11:06 feed-held mid-move: Hold:1; watching the disarm grace count down IN HOLD",
"19:11:23 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"19:11:54 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"19:12:10 returning the head: -11.350/+0.000 mm",
"19:12:10 button dark after 0.0 s",
"19:12:10 PASS: disarmed in Hold after 60.9 s, button dark",
"19:12:11 baseline: state: running reached idle on its own after 1 s; the machine finishing, not a leftover",
"19:12:23 baseline: cool: smoke/armed=False/hold=False ended on its own after 11 s; the engine's own post-job work, not a leftover",
"19:12:23 baseline: post: clean",
"19:12:23 result PASS"
],
"manifest_sha": "84a155bfc701e865ae73f9818bc38c2d005324ab5ba0ed44b668ec8896179947",
"message": "",
"result": "PASS",
"test": "laser.disarm-in-hold",
"ts": "2026-09-28T19:12:23Z"
},
"requires": [
"laser.emission-witness"
],
"satisfied": true,
"source_sha": "7749cf2b64b06dacfec04e19f18563280a174581e1a0ad96bb62dca8a80ecfcf",
"subsystem": "laser",
"title": "Disarm grace counts down in Hold"
},
{
"always": false,
"covers": [
[
"grblhal-glowforge",
"src/**"
],
[
"kernel-module-glowforge",
"**"
],
[
"forgectrl",
"src/super.c"
],
[
"forgectrl",
"src/cool.c"
],
[
"forgectrl",
"src/status.c"
],
[
"forgectrl",
"src/main.c"
],
[
"forgectrl",
"src/main.c"
]
],
"fingerprint": "4650d53bff2b9f7704aeb8f135fae31fe1e04fed92502e6f83d9c41f262b1fd9",
"hardware": "api",
"id": "laser.armed-kill",
"inherited": true,
"kind": "live",
"record": {
"answers": [],
"campaign": "c-20260928183105-64ee",
"duration_s": 47,
"evidence": {
"actions": [
{
"by": "operator",
"channel": "button",
"state": "presence",
"took_s": 7.3,
"ts": "2026-09-28T19:12:31Z"
},
{
"by": "fixture",
"channel": "button",
"state": "arm",
"took_s": 0.25,
"ts": "2026-09-28T19:12:31Z"
},
{
"by": "fixture",
"channel": "button",
"state": "arm",
"took_s": 0.25,
"ts": "2026-09-28T19:12:52Z"
}
],
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "attended",
"ts": "2026-09-28T18:51:04Z"
},
"beam_at_fire_kill": 2903,
"beam_at_fire_stop": 2829,
"button_dark": false,
"expected": {
"kernel_not_running": true,
"mode_after_stop": {
"controller": "standby",
"gated": false,
"local": false,
"mode": "grbl",
"motion": "verified",
"pid": 0,
"why": ""
},
"post_s": 0.51,
"post_status": 200,
"tail_zero": true,
"trail": [
[
0.53,
91,
"idle",
false
],
[
0.68,
91,
"idle",
false
],
[
0.82,
58,
"idle",
false
],
[
0.97,
58,
"idle",
false
],
[
1.12,
58,
"idle",
false
],
[
1.26,
58,
"idle",
false
],
[
1.41,
58,
"idle",
false
],
[
1.55,
58,
"idle",
false
],
[
1.7,
58,
"idle",
false
],
[
1.84,
0,
"idle",
false
],
[
1.99,
0,
"idle",
false
],
[
2.19,
0,
"idle",
false
],
[
2.34,
0,
"idle",
false
],
[
2.48,
0,
"idle",
false
],
[
2.63,
0,
"idle",
false
],
[
2.77,
0,
"idle",
false
],
[
2.92,
0,
"idle",
false
],
[
3.06,
0,
"idle",
false
],
[
3.21,
0,
"idle",
false
],
[
3.35,
0,
"idle",
false
],
[
3.5,
0,
"idle",
false
],
[
3.64,
0,
"idle",
false
],
[
3.79,
0,
"idle",
false
],
[
3.94,
0,
"idle",
false
],
[
4.08,
0,
"idle",
false
],
[
4.23,
0,
"idle",
false
],
[
4.43,
0,
"idle",
false
],
[
4.57,
0,
"idle",
false
],
[
4.72,
0,
"idle",
false
],
[
4.86,
0,
"idle",
false
],
[
5.01,
0,
"idle",
false
],
[
5.15,
0,
"idle",
false
],
[
5.3,
0,
"idle",
false
],
[
5.44,
0,
"idle",
false
],
[
5.59,
0,
"idle",
false
],
[
5.74,
0,
"idle",
false
],
[
5.88,
0,
"idle",
false
],
[
6.03,
0,
"idle",
false
],
[
6.17,
0,
"idle",
false
],
[
6.32,
0,
"idle",
false
],
[
6.46,
0,
"idle",
false
]
],
"zero_at_s": 1.84
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"latch_locked_after_respawn": true,
"mode": {
"detail": "already in grbl mode",
"found": "grbl",
"needs": "grbl",
"ok": true,
"switched": false
},
"mode_after_kill": {
"controller": "running",
"gated": false,
"local": false,
"mode": "grbl",
"motion": "verified",
"pid": 12661,
"why": ""
},
"mode_after_start": {
"controller": "running",
"gated": false,
"local": false,
"mode": "grbl",
"motion": "verified",
"pid": 12577,
"why": ""
},
"operator": {
"ack_live": true,
"ts": "2026-09-28T19:12:23Z"
},
"sigkill": {
"fast": {
"kernel_stopped_at_s": 0.283,
"latch_locked_at_s": 0.046
},
"kernel_not_running": true,
"latch_locked": true,
"pid": 12577,
"tail_zero": true,
"trail": [
[
0.31,
80,
"idle",
false
],
[
0.46,
80,
"idle",
false
],
[
0.61,
80,
"idle",
false
],
[
0.75,
80,
"idle",
false
],
[
0.9,
39,
"idle",
false
],
[
1.05,
39,
"idle",
false
],
[
1.21,
39,
"idle",
false
],
[
1.36,
39,
"idle",
false
],
[
1.5,
39,
"idle",
false
],
[
1.65,
39,
"idle",
false
],
[
1.79,
39,
"idle",
false
],
[
1.94,
0,
"idle",
false
],
[
2.13,
0,
"idle",
false
],
[
2.28,
0,
"idle",
false
],
[
2.43,
0,
"idle",
false
],
[
2.57,
0,
"idle",
false
],
[
2.72,
0,
"idle",
false
],
[
2.87,
0,
"idle",
false
],
[
3.01,
0,
"idle",
false
],
[
3.16,
0,
"idle",
false
],
[
3.31,
0,
"idle",
false
],
[
3.45,
0,
"idle",
false
],
[
3.6,
0,
"idle",
false
],
[
3.75,
0,
"idle",
false
],
[
3.89,
0,
"idle",
false
],
[
4.04,
0,
"idle",
false
],
[
4.18,
0,
"idle",
false
],
[
4.4,
0,
"idle",
false
],
[
4.55,
0,
"idle",
false
],
[
4.69,
0,
"idle",
false
],
[
4.84,
0,
"idle",
false
],
[
4.99,
0,
"idle",
false
],
[
5.14,
0,
"idle",
false
],
[
5.28,
0,
"idle",
false
],
[
5.43,
0,
"idle",
false
],
[
5.57,
0,
"idle",
false
],
[
5.72,
0,
"idle",
false
],
[
5.87,
0,
"idle",
false
],
[
6.01,
0,
"idle",
false
],
[
6.16,
0,
"idle",
false
],
[
6.31,
0,
"idle",
false
]
],
"zero_at_s": 1.94
}
},
"fingerprint": "4650d53bff2b9f7704aeb8f135fae31fe1e04fed92502e6f83d9c41f262b1fd9",
"image": "20260928182434 (dev)",
"log": [
"19:12:23 start laser.armed-kill (live, api) in campaign c-20260928183105-64ee",
"19:12:23 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"19:12:23 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"19:12:23 queued by the attended queue opened 2026-09-28T18:51:04Z",
"19:12:23 baseline: pre: clean",
"19:12:23 mode: test needs grbl - already in grbl mode",
"19:12:24 connect: Idle",
"19:12:24 NOTICE: LIVE FIRE. Eye protection on. Exhaust on. Extinguisher in reach. Put scrap under the head with 40 mm +X and +Y clear, and close the lid. Then press the button on the machine to start.",
"19:12:24 READY: waiting for the operator's press on the machine (the bench then does every press in this test)",
"19:12:31 READY: operator present (press after 7.3 s); the bench takes the presses",
"19:12:31 ARM: the fixture presses when the button lights (the bench's arm_press opt-in)",
"19:12:31 ARM press by the fixture, button lit after 0.3 s",
"19:12:39 emission live (91) - stopping the controller NOW",
"19:12:39 POST /controller/stop -> 200 {'stopped': True} (0.51 s)",
"19:12:45 post-stop (0.53, 91, 'idle', False)",
"19:12:45 post-stop (0.68, 91, 'idle', False)",
"19:12:45 post-stop (0.82, 58, 'idle', False)",
"19:12:45 post-stop (0.97, 58, 'idle', False)",
"19:12:45 post-stop (1.12, 58, 'idle', False)",
"19:12:45 post-stop (1.26, 58, 'idle', False)",
"19:12:45 post-stop (1.41, 58, 'idle', False)",
"19:12:45 post-stop (1.55, 58, 'idle', False)",
"19:12:45 post-stop (1.7, 58, 'idle', False)",
"19:12:45 post-stop (1.84, 0, 'idle', False)",
"19:12:45 post-stop (1.99, 0, 'idle', False)",
"19:12:45 post-stop (2.19, 0, 'idle', False)",
"19:12:45 post-stop (2.34, 0, 'idle', False)",
"19:12:45 post-stop (2.48, 0, 'idle', False)",
"19:12:45 post-stop (2.63, 0, 'idle', False)",
"19:12:45 post-stop (2.77, 0, 'idle', False)",
"19:12:45 post-stop (2.92, 0, 'idle', False)",
"19:12:45 post-stop (3.06, 0, 'idle', False)",
"19:12:45 post-stop (3.21, 0, 'idle', False)",
"19:12:45 post-stop (3.35, 0, 'idle', False)",
"19:12:45 post-stop (3.5, 0, 'idle', False)",
"19:12:45 post-stop (3.64, 0, 'idle', False)",
"19:12:45 post-stop (3.79, 0, 'idle', False)",
"19:12:45 post-stop (3.94, 0, 'idle', False)",
"19:12:45 post-stop (4.08, 0, 'idle', False)",
"19:12:45 post-stop (4.23, 0, 'idle', False)",
"19:12:45 post-stop (4.43, 0, 'idle', False)",
"19:12:45 post-stop (4.57, 0, 'idle', False)",
"19:12:45 post-stop (4.72, 0, 'idle', False)",
"19:12:45 post-stop (4.86, 0, 'idle', False)",
"19:12:45 post-stop (5.01, 0, 'idle', False)",
"19:12:45 post-stop (5.15, 0, 'idle', False)",
"19:12:45 post-stop (5.3, 0, 'idle', False)",
"19:12:45 post-stop (5.44, 0, 'idle', False)",
"19:12:45 post-stop (5.59, 0, 'idle', False)",
"19:12:45 post-stop (5.74, 0, 'idle', False)",
"19:12:45 post-stop (5.88, 0, 'idle', False)",
"19:12:45 post-stop (6.03, 0, 'idle', False)",
"19:12:45 post-stop (6.17, 0, 'idle', False)",
"19:12:45 post-stop (6.32, 0, 'idle', False)",
"19:12:45 post-stop (6.46, 0, 'idle', False)",
"19:12:45 emission first 0 at +1.84 s; last 2 s all zero: True; kernel not running: True",
"19:12:45 the controller is stopped (supervision held); restarting it (no motion, no laser)",
"19:12:45 POST /controller/start -> 200 {'started': True}",
"19:12:51 /mode after start: {'mode': 'grbl', 'controller': 'running', 'pid': 12577, 'motion': 'verified', 'gated': False, 'local': False, 'why': ''}",
"19:12:51 expected stop PASS: returned in 0.51 s, emission 0 at +1.84 s, controller restarted",
"19:12:52 connect: Idle",
"19:12:52 NOTICE: LIVE FIRE. Eye protection on. Exhaust on. Extinguisher in reach. Put scrap under the head with 40 mm +X and +Y clear, and close the lid.",
"19:12:52 READY: presence already proved this test; the bench has the presses",
"19:12:52 ARM: the fixture presses when the button lights (the bench's arm_press opt-in)",
"19:12:52 ARM press by the fixture, button lit after 0.3 s",
"19:12:54 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"19:12:55 emission live (80) - SIGKILL controller pid 12577 NOW",
"19:13:01 after the kill (sysfs): {'latch_locked_at_s': 0.046, 'kernel_stopped_at_s': 0.283}",
"19:13:01 post-kill (0.31, 80, 'idle', False)",
"19:13:01 post-kill (0.46, 80, 'idle', False)",
"19:13:01 post-kill (0.61, 80, 'idle', False)",
"19:13:01 post-kill (0.75, 80, 'idle', False)",
"19:13:01 post-kill (0.9, 39, 'idle', False)",
"19:13:01 post-kill (1.05, 39, 'idle', False)",
"19:13:01 post-kill (1.21, 39, 'idle', False)",
"19:13:01 post-kill (1.36, 39, 'idle', False)",
"19:13:01 post-kill (1.5, 39, 'idle', False)",
"19:13:01 post-kill (1.65, 39, 'idle', False)",
"19:13:01 post-kill (1.79, 39, 'idle', False)",
"19:13:01 post-kill (1.94, 0, 'idle', False)",
"19:13:01 post-kill (2.13, 0, 'idle', False)",
"19:13:01 post-kill (2.28, 0, 'idle', False)",
"19:13:01 post-kill (2.43, 0, 'idle', False)",
"19:13:01 post-kill (2.57, 0, 'idle', False)",
"19:13:01 post-kill (2.72, 0, 'idle', False)",
"19:13:01 post-kill (2.87, 0, 'idle', False)",
"19:13:01 post-kill (3.01, 0, 'idle', False)",
"19:13:01 post-kill (3.16, 0, 'idle', False)",
"19:13:01 post-kill (3.31, 0, 'idle', False)",
"19:13:01 post-kill (3.45, 0, 'idle', False)",
"19:13:01 post-kill (3.6, 0, 'idle', False)",
"19:13:01 post-kill (3.75, 0, 'idle', False)",
"19:13:01 post-kill (3.89, 0, 'idle', False)",
"19:13:01 post-kill (4.04, 0, 'idle', False)",
"19:13:01 post-kill (4.18, 0, 'idle', False)",
"19:13:01 post-kill (4.4, 0, 'idle', False)",
"19:13:01 post-kill (4.55, 0, 'idle', False)",
"19:13:01 post-kill (4.69, 0, 'idle', False)",
"19:13:01 post-kill (4.84, 0, 'idle', False)",
"19:13:01 post-kill (4.99, 0, 'idle', False)",
"19:13:01 post-kill (5.14, 0, 'idle', False)",
"19:13:01 post-kill (5.28, 0, 'idle', False)",
"19:13:01 post-kill (5.43, 0, 'idle', False)",
"19:13:01 post-kill (5.57, 0, 'idle', False)",
"19:13:01 post-kill (5.72, 0, 'idle', False)",
"19:13:01 post-kill (5.87, 0, 'idle', False)",
"19:13:01 post-kill (6.01, 0, 'idle', False)",
"19:13:01 post-kill (6.16, 0, 'idle', False)",
"19:13:01 post-kill (6.31, 0, 'idle', False)",
"19:13:01 emission first 0 at +1.94 s; last 2 s all zero: True; kernel not running: True",
"19:13:01 latch locked after the kill: True",
"19:13:01 /mode after the kill: {'mode': 'grbl', 'controller': 'running', 'pid': 12661, 'motion': 'verified', 'gated': False, 'local': False, 'why': ''}",
"19:13:03 button dark after 0.0 s",
"19:13:03 PASS: expected stop 0 at +1.84 s and SIGKILL 0 at +1.94 s, latch locked, controller respawned with the latch still locked, button dark",
"19:13:11 baseline: cool: smoke/armed=False/hold=False ended on its own after 7 s; the engine's own post-job work, not a leftover",
"19:13:11 baseline: post: clean",
"19:13:11 result PASS"
],
"manifest_sha": "84a155bfc701e865ae73f9818bc38c2d005324ab5ba0ed44b668ec8896179947",
"message": "",
"result": "PASS",
"test": "laser.armed-kill",
"ts": "2026-09-28T19:13:11Z"
},
"requires": [
"laser.emission-witness",
"motion.deadman"
],
"satisfied": true,
"source_sha": "96e1e638aa80f096b276caa87b57845a94390bb0dc8a542a871675c0f448ec9f",
"subsystem": "laser",
"title": "Armed kill mid-fire: the expected stop, then a SIGKILL"
},
{
"always": false,
"covers": [
[
"grblhal-glowforge",
"src/**"
],
[
"kernel-module-glowforge",
"**"
],
[
"forgectrl",
"src/super.c"
],
[
"forgectrl",
"src/cool.c"
],
[
"forgectrl",
"src/status.c"
],
[
"forgectrl",
"src/main.c"
]
],
"fingerprint": "d4b228f6daed2ae6797781916ae45a9f58be5da77f17c3a643950756f2a65bd6",
"hardware": "api",
"id": "laser.verdict-cut",
"inherited": true,
"kind": "live",
"record": {
"answers": [],
"campaign": "c-20260928183105-64ee",
"duration_s": 37,
"evidence": {
"actions": [
{
"by": "operator",
"channel": "button",
"state": "presence",
"took_s": 5.14,
"ts": "2026-09-28T19:13:17Z"
},
{
"by": "fixture",
"channel": "button",
"state": "arm",
"took_s": 0.26,
"ts": "2026-09-28T19:13:17Z"
}
],
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "attended",
"ts": "2026-09-28T18:51:04Z"
},
"beam": {
"delta": 971,
"digital_seen": true,
"idle": 1867,
"peak": 2838,
"samples": 17
},
"button_dark": false,
"button_latch_set_samples": 0,
"daemon_pids": [
5640
],
"disarm_after_idle_s": 0.6,
"fast_dark": {
"bursts": 5,
"failed": 0,
"from_s": 2.112,
"on": 0,
"reads": 1030,
"to_s": 3.029
},
"fast_lit_control": {
"failed": 0,
"on": 647,
"reads": 1146
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"held_at_s": 1.7,
"kernel_drift_mm": 0.0,
"latch_locked_samples": 0,
"messages": [
"[MSG:Warning: cooling verdict blocks fire - fire masked, job held]",
"[MSG:Warning: cooling service lost - fire blocked, holding]",
"[MSG:Info: cooling service restored]",
"[MSG:Info: cooling verdict clean - resuming]",
"[MSG:Restoring spindle]",
"[MSG:]",
"[MSG:Pgm End]"
],
"mode": {
"detail": "already in grbl mode",
"found": "grbl",
"needs": "grbl",
"ok": true,
"switched": false
},
"operator": {
"ack_live": true,
"ts": "2026-09-28T19:13:11Z"
},
"resumed_at_s": 3.39,
"trail": [
{
"armed": true,
"emission": 149,
"gstate": "Run",
"il": 1,
"t": 0.11
},
{
"armed": true,
"emission": 149,
"gstate": "Run",
"il": 2,
"t": 0.33
},
{
"armed": true,
"emission": 149,
"gstate": "Run",
"il": 2,
"t": 0.56
},
{
"armed": true,
"emission": 150,
"gstate": "Run",
"il": 2,
"t": 0.78
},
{
"armed": true,
"emission": 150,
"gstate": "Run",
"il": 1,
"t": 1.01
},
{
"armed": true,
"emission": 150,
"gstate": "Run",
"il": 2,
"t": 1.25
},
{
"armed": true,
"emission": 150,
"gstate": "Run",
"il": 1,
"t": 1.48
},
{
"armed": true,
"emission": 150,
"fast": [
1.706,
1.806,
227,
25,
0
],
"gstate": "Hold:0",
"il": 2,
"t": 1.7
},
{
"armed": true,
"emission": 148,
"fast": [
1.909,
2.009,
230,
0,
0
],
"gstate": "Hold:0",
"il": 1,
"t": 1.91
},
{
"armed": true,
"emission": 148,
"fast": [
2.112,
2.212,
233,
0,
0
],
"gstate": "Hold:0",
"il": 33,
"t": 2.11
},
{
"armed": true,
"emission": 148,
"fast": [
2.32,
2.42,
97,
0,
0
],
"gstate": "Hold:0",
"il": 33,
"t": 2.32
},
{
"armed": true,
"emission": 148,
"fast": [
2.523,
2.623,
232,
0,
0
],
"gstate": "Hold:0",
"il": 33,
"t": 2.52
},
{
"armed": true,
"emission": 0,
"fast": [
2.726,
2.826,
238,
0,
0
],
"gstate": "Hold:0",
"il": 33,
"t": 2.72
},
{
"armed": true,
"emission": 0,
"fast": [
2.929,
3.029,
230,
0,
0
],
"gstate": "Hold:0",
"il": 33,
"t": 2.93
},
{
"armed": true,
"emission": 0,
"fast": [
3.136,
3.236,
233,
0,
0
],
"gstate": "Hold:0",
"il": 33,
"t": 3.13
},
{
"armed": true,
"emission": 0,
"gstate": "Run",
"il": 1,
"t": 3.39
},
{
"armed": true,
"emission": 0,
"gstate": "Run",
"il": 2,
"t": 3.61
},
{
"armed": true,
"emission": 34,
"gstate": "Run",
"il": 1,
"t": 3.84
},
{
"armed": true,
"beam": 2756,
"emission": 34,
"gstate": "Run",
"il": 2,
"t": 4.06
},
{
"armed": true,
"beam": 2722,
"emission": 34,
"gstate": "Run",
"il": 1,
"t": 4.33
},
{
"armed": true,
"beam": 2748,
"emission": 34,
"gstate": "Run",
"il": 2,
"t": 4.6
},
{
"armed": true,
"beam": 2783,
"emission": 147,
"gstate": "Run",
"il": 2,
"t": 4.92
},
{
"armed": true,
"beam": 2813,
"emission": 147,
"gstate": "Run",
"il": 1,
"t": 5.18
},
{
"armed": true,
"beam": 2800,
"emission": 147,
"gstate": "Run",
"il": 1,
"t": 5.45
},
{
"armed": true,
"beam": 2711,
"emission": 148,
"gstate": "Run",
"il": 2,
"t": 5.72
},
{
"armed": true,
"beam": 2769,
"emission": 148,
"gstate": "Run",
"il": 1,
"t": 6.07
},
{
"armed": true,
"beam": 2741,
"emission": 148,
"gstate": "Run",
"il": 2,
"t": 6.34
},
{
"armed": true,
"beam": 2706,
"emission": 148,
"gstate": "Run",
"il": 2,
"t": 6.6
},
{
"armed": true,
"beam": 2746,
"emission": 146,
"gstate": "Run",
"il": 1,
"t": 6.86
},
{
"armed": true,
"beam": 2698,
"emission": 146,
"gstate": "Run",
"il": 2,
"t": 7.22
},
{
"armed": true,
"beam": 2737,
"emission": 146,
"gstate": "Run",
"il": 2,
"t": 7.48
},
{
"armed": true,
"beam": 2671,
"emission": 148,
"gstate": "Run",
"il": 2,
"t": 7.74
},
{
"armed": true,
"beam": 1887,
"emission": 148,
"gstate": "Run",
"il": 1,
"t": 8.01
},
{
"armed": true,
"beam": 1890,
"emission": 148,
"gstate": "Idle",
"il": 1,
"t": 8.32
}
]
},
"fingerprint": "d4b228f6daed2ae6797781916ae45a9f58be5da77f17c3a643950756f2a65bd6",
"image": "20260928182434 (dev)",
"log": [
"19:13:11 start laser.verdict-cut (live, api) in campaign c-20260928183105-64ee",
"19:13:11 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"19:13:11 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"19:13:11 queued by the attended queue opened 2026-09-28T18:51:04Z",
"19:13:11 baseline: pre: clean",
"19:13:11 mode: test needs grbl - already in grbl mode",
"19:13:12 unlock: ['[MSG:Caution: Unlocked]', 'ok']",
"19:13:12 connect: Idle",
"19:13:12 NOTICE: LIVE FIRE. Eye protection on. Exhaust on. Extinguisher in reach. Put scrap under the head with 40 mm +X clear, and close the lid. Then press the button on the machine to start.",
"19:13:12 READY: waiting for the operator's press on the machine (the bench then does every press in this test)",
"19:13:17 READY: operator present (press after 5.1 s); the bench takes the presses",
"19:13:17 NOTICE: LIVE FIRE. Eye protection on. Exhaust on. Extinguisher in reach. Put scrap under the head with 40 mm +X clear, and close the lid.",
"19:13:17 READY: presence already proved this test; the bench has the presses",
"19:13:17 ARM: the fixture presses when the button lights (the bench's arm_press opt-in)",
"19:13:18 ARM press by the fixture, button lit after 0.3 s",
"19:13:23 emission live (103); pausing the daemon in 1 s",
"19:13:24 fast reads of cnc/laser_on over the lit cut: 647 of 1146 on, 0 failed",
"19:13:24 daemon paused (SIGSTOP [5640]) for 3.0 s: the verdict goes stale",
"19:13:27 daemon resumed (SIGCONT) at +3.03 s",
"19:13:32 {'t': 0.11, 'gstate': 'Run', 'il': 1, 'emission': 149, 'armed': True}",
"19:13:32 {'t': 0.33, 'gstate': 'Run', 'il': 2, 'emission': 149, 'armed': True}",
"19:13:32 {'t': 0.56, 'gstate': 'Run', 'il': 2, 'emission': 149, 'armed': True}",
"19:13:32 {'t': 0.78, 'gstate': 'Run', 'il': 2, 'emission': 150, 'armed': True}",
"19:13:32 {'t': 1.01, 'gstate': 'Run', 'il': 1, 'emission': 150, 'armed': True}",
"19:13:32 {'t': 1.25, 'gstate': 'Run', 'il': 2, 'emission': 150, 'armed': True}",
"19:13:32 {'t': 1.48, 'gstate': 'Run', 'il': 1, 'emission': 150, 'armed': True}",
"19:13:32 {'t': 1.7, 'gstate': 'Hold:0', 'il': 2, 'emission': 150, 'armed': True, 'fast': [1.706, 1.806, 227, 25, 0]}",
"19:13:32 {'t': 1.91, 'gstate': 'Hold:0', 'il': 1, 'emission': 148, 'armed': True, 'fast': [1.909, 2.009, 230, 0, 0]}",
"19:13:32 {'t': 2.11, 'gstate': 'Hold:0', 'il': 33, 'emission': 148, 'armed': True, 'fast': [2.112, 2.212, 233, 0, 0]}",
"19:13:32 {'t': 2.32, 'gstate': 'Hold:0', 'il': 33, 'emission': 148, 'armed': True, 'fast': [2.32, 2.42, 97, 0, 0]}",
"19:13:32 {'t': 2.52, 'gstate': 'Hold:0', 'il': 33, 'emission': 148, 'armed': True, 'fast': [2.523, 2.623, 232, 0, 0]}",
"19:13:32 {'t': 2.72, 'gstate': 'Hold:0', 'il': 33, 'emission': 0, 'armed': True, 'fast': [2.726, 2.826, 238, 0, 0]}",
"19:13:32 {'t': 2.93, 'gstate': 'Hold:0', 'il': 33, 'emission': 0, 'armed': True, 'fast': [2.929, 3.029, 230, 0, 0]}",
"19:13:32 {'t': 3.13, 'gstate': 'Hold:0', 'il': 33, 'emission': 0, 'armed': True, 'fast': [3.136, 3.236, 233, 0, 0]}",
"19:13:32 {'t': 3.39, 'gstate': 'Run', 'il': 1, 'emission': 0, 'armed': True}",
"19:13:32 {'t': 3.61, 'gstate': 'Run', 'il': 2, 'emission': 0, 'armed': True}",
"19:13:32 {'t': 3.84, 'gstate': 'Run', 'il': 1, 'emission': 34, 'armed': True}",
"19:13:32 {'t': 4.06, 'gstate': 'Run', 'il': 2, 'emission': 34, 'armed': True, 'beam': 2756}",
"19:13:32 {'t': 4.33, 'gstate': 'Run', 'il': 1, 'emission': 34, 'armed': True, 'beam': 2722}",
"19:13:32 {'t': 4.6, 'gstate': 'Run', 'il': 2, 'emission': 34, 'armed': True, 'beam': 2748}",
"19:13:32 {'t': 4.92, 'gstate': 'Run', 'il': 2, 'emission': 147, 'armed': True, 'beam': 2783}",
"19:13:32 {'t': 5.18, 'gstate': 'Run', 'il': 1, 'emission': 147, 'armed': True, 'beam': 2813}",
"19:13:32 {'t': 5.45, 'gstate': 'Run', 'il': 1, 'emission': 147, 'armed': True, 'beam': 2800}",
"19:13:32 {'t': 5.72, 'gstate': 'Run', 'il': 2, 'emission': 148, 'armed': True, 'beam': 2711}",
"19:13:32 {'t': 6.07, 'gstate': 'Run', 'il': 1, 'emission': 148, 'armed': True, 'beam': 2769}",
"19:13:32 {'t': 6.34, 'gstate': 'Run', 'il': 2, 'emission': 148, 'armed': True, 'beam': 2741}",
"19:13:32 {'t': 6.6, 'gstate': 'Run', 'il': 2, 'emission': 148, 'armed': True, 'beam': 2706}",
"19:13:32 {'t': 6.86, 'gstate': 'Run', 'il': 1, 'emission': 146, 'armed': True, 'beam': 2746}",
"19:13:32 {'t': 7.22, 'gstate': 'Run', 'il': 2, 'emission': 146, 'armed': True, 'beam': 2698}",
"19:13:32 {'t': 7.48, 'gstate': 'Run', 'il': 2, 'emission': 146, 'armed': True, 'beam': 2737}",
"19:13:32 {'t': 7.74, 'gstate': 'Run', 'il': 2, 'emission': 148, 'armed': True, 'beam': 2671}",
"19:13:32 {'t': 8.01, 'gstate': 'Run', 'il': 1, 'emission': 148, 'armed': True, 'beam': 1887}",
"19:13:32 {'t': 8.32, 'gstate': 'Idle', 'il': 1, 'emission': 148, 'armed': True, 'beam': 1890}",
"19:13:32 controller: ['[MSG:Warning: cooling verdict blocks fire - fire masked, job held]', '[MSG:Warning: cooling service lost - fire blocked, holding]', '[MSG:Info: cooling service restored]', '[MSG:Info: cooling verdict clean - resuming]', '[MSG:Restoring spindle]', '[MSG:]', '[MSG:Pgm End]']",
"19:13:33 kernel counters: start (0.00, 0.00) -> now (0.00, 0.00), drift 0.000 mm",
"19:13:33 beam detector: idle 1867, peak 2838, digital asserted True",
"19:13:33 button dark after 0.0 s",
"19:13:33 PASS: held at +1.7 s with the latch untouched, the laser off in all 1030 reads inside the hold (2.112 s to 3.029 s), resumed lit at +3.39 s with no press, disarmed 0.6 s after Idle",
"19:13:42 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"19:13:49 baseline: cool: run/armed=False/hold=False ended on its own after 16 s; the engine's own post-job work, not a leftover",
"19:13:49 baseline: post: clean",
"19:13:49 result PASS"
],
"manifest_sha": "84a155bfc701e865ae73f9818bc38c2d005324ab5ba0ed44b668ec8896179947",
"message": "",
"result": "PASS",
"test": "laser.verdict-cut",
"ts": "2026-09-28T19:13:49Z"
},
"requires": [
"laser.emission-witness"
],
"satisfied": true,
"source_sha": "ce8a6f0e1164c359557168df44c66c8b85a5abf3cbdfa8e9a74e40dbac1f2e87",
"subsystem": "laser",
"title": "A blocked verdict mid-cut locks the latch and holds; the clean verdict resumes with no press"
},
{
"always": false,
"covers": [
[
"grblhal-glowforge",
"src/**"
],
[
"kernel-module-glowforge",
"**"
],
[
"forgectrl",
"src/super.c"
],
[
"forgectrl",
"src/cool.c"
],
[
"forgectrl",
"src/status.c"
],
[
"forgectrl",
"src/main.c"
],
[
"grblhal-glowforge",
"src/glowforge_laser.c"
],
[
"grblhal-glowforge",
"src/glowforge_switches.c"
],
[
"grblhal-glowforge",
"src/glowforge_switch_map.h"
]
],
"fingerprint": "32f3a5fbd7be8edb858c5562253900ac3417c29b99555487251a490469dbc694",
"hardware": "api",
"id": "laser.arm-wait-lid",
"inherited": true,
"kind": "operator",
"record": {
"answers": [],
"campaign": "c-20260928171100-3ff5",
"duration_s": 3,
"evidence": {
"actions": [
{
"by": "fixture",
"channel": "lid",
"state": "open",
"took_s": 0.02,
"ts": "2026-09-28T17:18:53Z"
},
{
"by": "fixture",
"channel": "lid",
"state": "close",
"took_s": 0.28,
"ts": "2026-09-28T17:18:54Z"
}
],
"armed_after": false,
"armed_during_wait": true,
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T17:11:00Z"
},
"button_dark": false,
"emission": 0,
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"latch_locked": true,
"messages": [
"[MSG:Info: press the button to start the laser job]",
"[MSG:Warning: lid opened during arm - job canceled]"
],
"mode": {
"detail": "already in grbl mode",
"found": "grbl",
"needs": "grbl",
"ok": true,
"switched": false
},
"state_after": "Idle"
},
"fingerprint": "32f3a5fbd7be8edb858c5562253900ac3417c29b99555487251a490469dbc694",
"image": "20260928170058 (dev)",
"log": [
"17:18:52 start laser.arm-wait-lid (operator, api) in campaign c-20260928171100-3ff5",
"17:18:53 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"17:18:53 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"17:18:53 fixture: running unattended (no prompt can be answered)",
"17:18:53 queued by the unattended queue opened 2026-09-28T17:11:00Z",
"17:18:53 baseline: pre: clean",
"17:18:53 mode: test needs grbl - already in grbl mode",
"17:18:53 connect: Idle",
"17:18:53 arm prompt seen; armed=True; asking the operator to open the lid",
"17:18:53 ACT lid open (fixture)",
"17:18:54 ACT lid open: done after 0.0 s",
"17:18:54 controller: ['[MSG:Info: press the button to start the laser job]', '[MSG:Warning: lid opened during arm - job canceled]']",
"17:18:54 button dark after 0.0 s",
"17:18:54 ACT lid close (fixture)",
"17:18:54 ACT lid close: done after 0.3 s",
"17:18:55 PASS: lid open during the arm wait canceled the job (clean reset, no alarm), armed=false, latch locked",
"17:18:55 baseline: post: clean",
"17:18:55 result PASS"
],
"manifest_sha": "98f8c4dad7130ecf1fa44e5e0f1a1b53e6b9359f005f22a1ddbee496375d9a9e",
"message": "",
"result": "PASS",
"test": "laser.arm-wait-lid",
"ts": "2026-09-28T17:18:55Z"
},
"requires": [
"kernel.latch-locked-idle",
"motion.jog-roundtrip"
],
"satisfied": true,
"source_sha": "292a292ce7b0388ac0cb90714d61e522819fad37943663ffd7dddc9cd43db02b",
"subsystem": "laser",
"title": "Lid open during the arm wait cancels the job"
},
{
"always": false,
"covers": [
[
"grblhal-glowforge",
"src/**"
],
[
"kernel-module-glowforge",
"**"
],
[
"forgectrl",
"src/super.c"
],
[
"forgectrl",
"src/cool.c"
],
[
"forgectrl",
"src/status.c"
],
[
"forgectrl",
"src/main.c"
],
[
"grblhal-glowforge",
"src/glowforge_switches.c"
],
[
"grblhal-glowforge",
"src/glowforge_switch_map.h"
]
],
"fingerprint": "6467ad1efa2bc155bc274387bcf4fd4d964c37d3474333a2ab63a8dc434200d9",
"hardware": "api",
"id": "laser.pause-resume-lid-cancel",
"inherited": true,
"kind": "live",
"record": {
"answers": [],
"campaign": "c-20260928183105-64ee",
"duration_s": 57,
"evidence": {
"actions": [
{
"by": "operator",
"channel": "button",
"state": "presence",
"took_s": 28.45,
"ts": "2026-09-28T19:14:19Z"
},
{
"by": "fixture",
"channel": "button",
"state": "arm",
"took_s": 0.26,
"ts": "2026-09-28T19:14:19Z"
},
{
"by": "fixture",
"channel": "button",
"state": "press",
"took_s": 0.11,
"ts": "2026-09-28T19:14:25Z"
},
{
"by": "fixture",
"channel": "button",
"state": "press",
"took_s": 0.17,
"ts": "2026-09-28T19:14:29Z"
},
{
"by": "fixture",
"channel": "lid",
"state": "open",
"took_s": 0.02,
"ts": "2026-09-28T19:14:29Z"
},
{
"by": "fixture",
"channel": "lid",
"state": "close",
"took_s": 0.3,
"ts": "2026-09-28T19:14:38Z"
}
],
"armed_after": false,
"armed_while_paused": true,
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "attended",
"ts": "2026-09-28T18:51:04Z"
},
"beam": {
"delta": 1008,
"digital_seen": true,
"idle": 1875,
"peak": 2883,
"samples": 3
},
"button_dark": false,
"button_latch": 1,
"drift_mm": 0.028,
"emission_back_after_s": 0.23,
"emission_running": 30,
"emission_zero_when_paused": true,
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"hold_state": "Hold:0",
"kernel_drift_mm": 0.03,
"kernel_start": [
0.0,
0.0
],
"latch_locked": true,
"latch_locked_while_paused": false,
"lid_tail_zero": true,
"lid_zero_at_s": 1.89,
"messages": [
"[MSG:Check Door]",
"[MSG:Info: laser disarmed - latch locked]",
"[MSG:Warning: lid opened - job canceled, returning to the job start]",
"GrblHAL 1.1f ['$' or '$HELP' for help]",
"[MSG:Info: returned to the job start]"
],
"mode": {
"detail": "already in grbl mode",
"found": "grbl",
"needs": "grbl",
"ok": true,
"switched": false
},
"operator": {
"ack_live": true,
"ts": "2026-09-28T19:13:49Z"
},
"pause_message": true,
"paused_trail": [
[
0.03,
30,
true
],
[
0.25,
30,
true
],
[
0.48,
30,
true
],
[
0.7,
95,
true
],
[
0.93,
95,
true
],
[
1.16,
95,
true
],
[
1.38,
95,
true
],
[
1.61,
0,
true
],
[
1.84,
0,
true
],
[
2.06,
0,
true
],
[
2.29,
0,
true
],
[
2.52,
0,
true
],
[
2.74,
0,
true
],
[
2.97,
0,
true
],
[
3.2,
0,
true
],
[
3.42,
0,
true
],
[
3.65,
0,
true
],
[
3.88,
0,
true
]
],
"resume_message": true,
"resume_trail": [
[
0.04,
0
],
[
0.23,
16
]
],
"resumed_state": "Run",
"returned_message": true,
"start": [
0.0,
0.0,
4.449
]
},
"fingerprint": "6467ad1efa2bc155bc274387bcf4fd4d964c37d3474333a2ab63a8dc434200d9",
"image": "20260928182434 (dev)",
"log": [
"19:13:49 start laser.pause-resume-lid-cancel (live, api) in campaign c-20260928183105-64ee",
"19:13:49 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"19:13:49 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"19:13:49 queued by the attended queue opened 2026-09-28T18:51:04Z",
"19:13:49 baseline: pre: clean",
"19:13:49 mode: test needs grbl - already in grbl mode",
"19:13:50 connect: Idle",
"19:13:50 NOTICE: LIVE FIRE. Eye protection on. Exhaust on. Extinguisher in reach. Put scrap under the head with 40 mm +X and +Y clear, and close the lid. Then press the button on the machine to start.",
"19:13:50 READY: waiting for the operator's press on the machine (the bench then does every press in this test)",
"19:14:19 READY: operator present (press after 28.5 s); the bench takes the presses",
"19:14:19 ARM: the fixture presses when the button lights (the bench's arm_press opt-in)",
"19:14:19 ARM press by the fixture, button lit after 0.3 s",
"19:14:20 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"19:14:25 emission live (30) - asking the operator to pause",
"19:14:25 ACT button press (fixture)",
"19:14:25 ACT button press: done after 0.1 s",
"19:14:29 paused (0.03, 30, True)",
"19:14:29 paused (0.25, 30, True)",
"19:14:29 paused (0.48, 30, True)",
"19:14:29 paused (0.7, 95, True)",
"19:14:29 paused (0.93, 95, True)",
"19:14:29 paused (1.16, 95, True)",
"19:14:29 paused (1.38, 95, True)",
"19:14:29 paused (1.61, 0, True)",
"19:14:29 paused (1.84, 0, True)",
"19:14:29 paused (2.06, 0, True)",
"19:14:29 paused (2.29, 0, True)",
"19:14:29 paused (2.52, 0, True)",
"19:14:29 paused (2.74, 0, True)",
"19:14:29 paused (2.97, 0, True)",
"19:14:29 paused (3.2, 0, True)",
"19:14:29 paused (3.42, 0, True)",
"19:14:29 paused (3.65, 0, True)",
"19:14:29 paused (3.88, 0, True)",
"19:14:29 paused: Hold:0, emission 0 = True, armed = True, latch locked = False",
"19:14:29 ACT button press (fixture)",
"19:14:29 ACT button press: done after 0.2 s",
"19:14:29 emission after the resume: [(0.04, 0), (0.23, 16)]",
"19:14:29 ACT lid open (fixture)",
"19:14:30 ACT lid open: done after 0.0 s",
"19:14:38 post-lid (0.04, 16, 'running', True)",
"19:14:38 post-lid (0.26, 16, 'running', False)",
"19:14:38 post-lid (0.5, 16, 'running', False)",
"19:14:38 post-lid (0.71, 16, 'running', False)",
"19:14:38 post-lid (0.91, 19, 'idle', False)",
"19:14:38 post-lid (1.1, 19, 'idle', False)",
"19:14:38 post-lid (1.3, 19, 'idle', False)",
"19:14:38 post-lid (1.49, 19, 'idle', False)",
"19:14:38 post-lid (1.69, 19, 'idle', False)",
"19:14:38 post-lid (1.89, 0, 'idle', False)",
"19:14:38 post-lid (2.09, 0, 'idle', False)",
"19:14:38 post-lid (2.29, 0, 'idle', False)",
"19:14:38 post-lid (2.48, 0, 'idle', False)",
"19:14:38 post-lid (2.68, 0, 'idle', False)",
"19:14:38 post-lid (2.93, 0, 'idle', False)",
"19:14:38 post-lid (3.13, 0, 'idle', False)",
"19:14:38 post-lid (3.33, 0, 'idle', False)",
"19:14:38 post-lid (3.52, 0, 'idle', False)",
"19:14:38 post-lid (3.72, 0, 'idle', False)",
"19:14:38 post-lid (3.92, 0, 'idle', False)",
"19:14:38 post-lid (4.12, 0, 'idle', False)",
"19:14:38 post-lid (4.32, 0, 'idle', False)",
"19:14:38 post-lid (4.51, 0, 'idle', False)",
"19:14:38 post-lid (4.71, 0, 'idle', False)",
"19:14:38 post-lid (4.91, 0, 'idle', False)",
"19:14:38 post-lid (5.16, 0, 'idle', False)",
"19:14:38 post-lid (5.36, 0, 'idle', False)",
"19:14:38 post-lid (5.55, 0, 'idle', False)",
"19:14:38 post-lid (5.75, 0, 'idle', False)",
"19:14:38 post-lid (5.95, 0, 'idle', False)",
"19:14:38 post-lid (6.14, 0, 'idle', False)",
"19:14:38 post-lid (6.34, 0, 'idle', False)",
"19:14:38 post-lid (6.54, 0, 'idle', False)",
"19:14:38 post-lid (6.73, 0, 'idle', False)",
"19:14:38 post-lid (6.93, 0, 'idle', False)",
"19:14:38 post-lid (7.13, 0, 'idle', False)",
"19:14:38 post-lid (7.32, 0, 'idle', False)",
"19:14:38 post-lid (7.52, 0, 'idle', False)",
"19:14:38 post-lid (7.72, 0, 'idle', False)",
"19:14:38 post-lid (7.91, 0, 'idle', False)",
"19:14:38 controller: ['[MSG:Check Door]', '[MSG:Info: laser disarmed - latch locked]', '[MSG:Warning: lid opened - job canceled, returning to the job start]', \"GrblHAL 1.1f ['$' or '$HELP' for help]\", '[MSG:Info: returned to the job start]']",
"19:14:38 returned: drift 0.028 mm; armed=False latch_locked=True button_latch=1",
"19:14:38 kernel counters: start (0.00, 0.00) -> now (0.03, 0.00), drift 0.030 mm",
"19:14:38 beam detector: idle 1875, peak 2883, digital asserted True",
"19:14:38 button dark after 0.0 s",
"19:14:38 ACT lid close (fixture)",
"19:14:38 ACT lid close: done after 0.3 s",
"19:14:39 PASS: button paused the burn (emission 0, armed kept, latch unlocked) and resumed it; the lid then canceled it - emission 0 at +1.89 s, reset without alarm, returned (drift 0.028 mm), button latch SET",
"19:14:45 baseline: cool: smoke/armed=False/hold=False ended on its own after 6 s; the engine's own post-job work, not a leftover",
"19:14:46 baseline: head jogged back -0.028/-0.000 mm to its start",
"19:14:46 baseline: position: [6, 0, 0] (expected [0, 0, 0]) -> restored (jogged back -0.0/-0.0 mm); inside the 0.10 mm dead band, not a leftover",
"19:14:46 baseline: post: clean",
"19:14:46 result PASS"
],
"manifest_sha": "84a155bfc701e865ae73f9818bc38c2d005324ab5ba0ed44b668ec8896179947",
"message": "",
"result": "PASS",
"test": "laser.pause-resume-lid-cancel",
"ts": "2026-09-28T19:14:46Z"
},
"requires": [
"laser.emission-witness",
"motion.lid-cancel-home",
"motion.button-hold-resume"
],
"satisfied": true,
"source_sha": "bd6cb36f1bb4ebbf5acc595b7ab54a1755c354ddc2047e4b95800f6befe60f2f",
"subsystem": "laser",
"title": "One live cut: the button pauses and resumes it, the lid cancels it and sends the head home"
},
{
"always": false,
"covers": [
[
"grblhal-glowforge",
"src/**"
],
[
"kernel-module-glowforge",
"**"
],
[
"forgectrl",
"src/super.c"
],
[
"forgectrl",
"src/cool.c"
],
[
"forgectrl",
"src/status.c"
],
[
"forgectrl",
"src/main.c"
],
[
"forgectrl",
"src/grblport.*"
]
],
"fingerprint": "77783297949f585a459669014df250bf5e206abbd78aaa3e8bc9298c91a847d4",
"hardware": "api",
"id": "laser.port-dark",
"inherited": true,
"kind": "live",
"record": {
"answers": [],
"campaign": "c-20260928183105-64ee",
"duration_s": 36,
"evidence": {
"actions": [
{
"by": "operator",
"channel": "button",
"state": "presence",
"took_s": 4.1,
"ts": "2026-09-28T19:14:52Z"
},
{
"by": "fixture",
"channel": "button",
"state": "arm",
"took_s": 0.26,
"ts": "2026-09-28T19:14:52Z"
}
],
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "attended",
"ts": "2026-09-28T18:51:04Z"
},
"disarm_s": 0.09404444694519043,
"emission_peak_g1": 146,
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"jog_beam_rise": 0,
"jog_emission_samples": 0,
"jog_hv_max": 0,
"jog_samples": 20,
"mode": {
"detail": "already in grbl mode",
"found": "grbl",
"needs": "grbl",
"ok": true,
"switched": false
},
"operator": {
"ack_live": true,
"ts": "2026-09-28T19:14:47Z"
},
"trail": [
[
0.0,
null,
"running",
0,
true,
"run",
1,
0,
false,
true,
false,
true,
1874,
0,
null
],
[
0.18,
null,
"running",
0,
true,
"run",
1,
0,
false,
true,
false,
true,
1875,
0,
null
],
[
0.35,
null,
"running",
0,
true,
"run",
1,
0,
false,
true,
false,
true,
1875,
0,
null
],
[
0.52,
null,
"running",
0,
true,
"run",
1,
0,
false,
true,
false,
true,
1876,
0,
null
],
[
0.72,
null,
"running",
0,
true,
"run",
1,
0,
false,
true,
false,
true,
1874,
0,
null
],
[
0.9,
null,
"running",
0,
true,
"run",
1,
0,
false,
true,
false,
true,
1875,
0,
null
],
[
1.08,
null,
"running",
0,
true,
"run",
1,
0,
false,
true,
false,
true,
1874,
0,
null
],
[
1.26,
null,
"running",
0,
true,
"run",
1,
0,
false,
true,
false,
true,
1875,
0,
null
],
[
1.43,
null,
"running",
0,
true,
"run",
1,
0,
false,
true,
false,
true,
1874,
0,
null
],
[
1.6,
null,
"running",
0,
true,
"run",
1,
0,
false,
true,
false,
true,
1874,
0,
null
],
[
1.86,
null,
"running",
0,
true,
"run",
1,
0,
false,
true,
false,
true,
1873,
0,
null
],
[
2.04,
null,
"running",
0,
true,
"run",
1,
0,
false,
true,
false,
true,
1873,
0,
null
],
[
2.73,
null,
"idle",
0,
true,
"run",
1,
0,
false,
true,
false,
false,
1873,
0,
null
],
[
2.91,
null,
"running",
0,
true,
"run",
1,
0,
false,
true,
false,
true,
1871,
0,
null
],
[
3.09,
null,
"running",
0,
true,
"run",
1,
0,
false,
true,
false,
true,
1873,
0,
null
],
[
3.25,
null,
"running",
0,
true,
"run",
1,
0,
false,
true,
false,
true,
1872,
0,
null
],
[
3.94,
null,
"running",
0,
true,
"run",
1,
0,
false,
true,
false,
true,
1873,
0,
null
],
[
4.2,
null,
"running",
0,
true,
"run",
1,
0,
false,
true,
false,
true,
1871,
0,
null
],
[
4.38,
null,
"running",
0,
true,
"run",
1,
0,
false,
true,
false,
true,
1873,
0,
null
],
[
4.55,
null,
"running",
0,
true,
"run",
1,
0,
false,
true,
false,
true,
1876,
0,
null
]
]
},
"fingerprint": "77783297949f585a459669014df250bf5e206abbd78aaa3e8bc9298c91a847d4",
"image": "20260928182434 (dev)",
"log": [
"19:14:47 start laser.port-dark (live, api) in campaign c-20260928183105-64ee",
"19:14:47 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"19:14:47 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"19:14:47 queued by the attended queue opened 2026-09-28T18:51:04Z",
"19:14:47 baseline: pre: clean",
"19:14:47 mode: test needs grbl - already in grbl mode",
"19:14:47 connect: Idle",
"19:14:48 NOTICE: LIVE FIRE. Eye protection on. Exhaust on. Extinguisher in reach. Put scrap under the head with 20 mm +X clear, and close the lid. Then press the button on the machine to start.",
"19:14:48 READY: waiting for the operator's press on the machine (the bench then does every press in this test)",
"19:14:52 READY: operator present (press after 4.1 s); the bench takes the presses",
"19:14:52 ARM: the fixture presses when the button lights (the bench's arm_press opt-in)",
"19:14:52 ARM press by the fixture, button lit after 0.3 s",
"19:15:06 G1 emission peak 146; 20 samples across three port jogs: 0 with emission, HV max 0, beam detector rise 0",
"19:15:06 PASS: lit on the G1 (peak 146), and three port jogs under the same open window with M3 S400 modal shipped dark by all three witnesses",
"19:15:17 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"19:15:23 baseline: cool: run/armed=False/hold=False ended on its own after 17 s; the engine's own post-job work, not a leftover",
"19:15:23 baseline: post: clean",
"19:15:23 result PASS"
],
"manifest_sha": "84a155bfc701e865ae73f9818bc38c2d005324ab5ba0ed44b668ec8896179947",
"message": "",
"result": "PASS",
"test": "laser.port-dark",
"ts": "2026-09-28T19:15:23Z"
},
"requires": [
"laser.emission-witness",
"motion.port-jog"
],
"satisfied": true,
"source_sha": "77585b4cd2809e7748ec9982a48390df8607abc0cfe229ea24a5dc1c2cdeebf4",
"subsystem": "laser",
"title": "A panel jog under an open armed window ships dark"
},
{
"always": false,
"covers": [
[
"grblhal-glowforge",
"src/**"
],
[
"kernel-module-glowforge",
"**"
],
[
"forgectrl",
"src/super.c"
],
[
"forgectrl",
"src/cool.c"
],
[
"forgectrl",
"src/status.c"
],
[
"forgectrl",
"src/main.c"
],
[
"forgectrl",
"src/curverec.*"
],
[
"forgectrl",
"src/jobrun.*"
],
[
"forgectrl",
"src/jobstream.*"
],
[
"forgectrl",
"src/lease.*"
],
[
"forgectrl",
"src/settings.*"
]
],
"fingerprint": "958450bfafb137cf48f5f657751530a1165f68e117f1b3b553098f6fcbdd6cdf",
"hardware": "api",
"id": "laser.recorder-dark",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928171100-3ff5",
"duration_s": 19,
"evidence": {
"abort_route": [
409,
"the dose-curve recorder is running: stop it where it was started"
],
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T17:11:00Z"
},
"controller_after_stop": "Idle",
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"holder": {
"for_s": 0,
"kind": "sender",
"owner": "recorder",
"words": "the dose-curve recorder"
},
"job_beside": [
409,
"the dose-curve recorder holds the machine"
],
"job_record": {
"acked": 0,
"elapsed_s": 0,
"emission": {
"hv_max": 0,
"laser_on_samples": 0,
"lit_s": 0.0,
"samples": 1,
"thermopile_delta": 0
},
"lines": 0,
"lit": false,
"owner": "recorder",
"program": false,
"reason": "",
"sent": 32,
"state": "running"
},
"keys": {
"after": {
"laser_dose_curve": "10:0.62,20:2.79,30:8.46,45:24.90,60:42.02,80:52.53,100:100.00",
"laser_floor_density": "14"
},
"before": {
"laser_dose_curve": "10:0.62,20:2.79,30:8.46,45:24.90,60:42.02,80:52.53,100:100.00",
"laser_floor_density": "14"
}
},
"mode": {
"detail": "already in grbl mode",
"found": "grbl",
"needs": "grbl",
"ok": true,
"switched": false
},
"moved_mm": [
0.0,
0.0
],
"override": {
"laser_dose_curve": "off",
"laser_floor_density": "0"
},
"recorder_kernel_drift_mm": 0.0,
"stopped": {
"curve": "",
"elapsed_s": 0,
"points": [],
"reason": "stopped before the ladder fired",
"samples": 58,
"state": "failed"
},
"witnesses": {
"hv_max": 0,
"job": {
"hv_max": 0,
"laser_on_samples": 0,
"lit_s": 0.0,
"samples": 58,
"thermopile_delta": 0
},
"samples": 16,
"with_emission": 0
}
},
"fingerprint": "958450bfafb137cf48f5f657751530a1165f68e117f1b3b553098f6fcbdd6cdf",
"image": "20260928170058 (dev)",
"log": [
"17:18:56 start laser.recorder-dark (auto, api) in campaign c-20260928171100-3ff5",
"17:18:56 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"17:18:56 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"17:18:56 queued by the unattended queue opened 2026-09-28T17:11:00Z",
"17:18:56 baseline: pre: clean",
"17:18:56 mode: test needs grbl - already in grbl mode",
"17:18:56 the recorder holds the machine as {'owner': 'recorder', 'kind': 'sender', 'for_s': 0, 'words': 'the dose-curve recorder'}, and the controller waits for the press",
"17:19:00 after the stop the controller is in Idle; the head is 0.000, 0.000 mm from where it was found",
"17:19:00 kernel counters: start (0.00, 0.00) -> now (0.00, 0.00), drift 0.000 mm",
"17:19:00 PASS: the recorder ran as a job of the runner's, held the machine as a sender through its arm wait with every witness dark, and its stop freed the machine and restored the laser keys",
"17:19:15 baseline: cool: smoke/armed=False/hold=False ended on its own after 15 s; the engine's own post-job work, not a leftover",
"17:19:15 baseline: post: clean",
"17:19:15 result PASS"
],
"manifest_sha": "98f8c4dad7130ecf1fa44e5e0f1a1b53e6b9359f005f22a1ddbee496375d9a9e",
"message": "",
"result": "PASS",
"test": "laser.recorder-dark",
"ts": "2026-09-28T17:19:15Z"
},
"requires": [
"motion.job"
],
"satisfied": true,
"source_sha": "f4756a86c5e44f64cc01cce2d7030888ed04f5a9269b41fabfab23b64770fda9",
"subsystem": "laser",
"title": "The dose-curve recorder takes the machine as a job, arms, and is stopped dark"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/cam.*"
],
[
"forgectrl",
"src/camhealth.*"
],
[
"forgectrl",
"src/debayer.*"
],
[
"forgectrl",
"src/vpu_jpeg.*"
],
[
"forgectrl",
"src/vpu_h264.*"
],
[
"forgectrl",
"src/mp4mux.*"
],
[
"forgectrl",
"src/gpu_debayer.*"
],
[
"forgectrl",
"src/ipu_copy.*"
],
[
"forgectrl",
"src/main.c"
],
[
"python3-gfhardware",
"gfhardware/src/**"
],
[
"python3-gfhardware",
"gfhardware/cam*"
]
],
"fingerprint": "5965b71c282cb7b8388d194e34944e0855da75e97354224966a75fcb21b04bc2",
"hardware": "api",
"id": "camera.snapshot",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928162331-3969",
"duration_s": 16,
"evidence": {
"background_after_watching": [
200,
63846
],
"background_bad_value": [
400,
"background must be '0' or '1'"
],
"background_while_watched": [
409,
"somebody is watching a camera: a background capture waits until they stop"
],
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T16:23:31Z"
},
"cam_status": {
"buffers": "uncached",
"cam": "lid",
"capture_allowed": true,
"clients": 0,
"convert": "cpu",
"encoder": "software",
"fps": 0.0,
"fps_cap": 0.0,
"frames": 0,
"h264": {
"active": false,
"clients": 0
},
"health": {
"captured": 0,
"corrupt": 0,
"restarts": 0,
"withheld": 0
},
"hw_fps_skip": false,
"running": false,
"sensor": "OV5648",
"snapshot": {
"height": 1944,
"width": 2592
},
"stopped_by_lid": false,
"stream": {
"height": 972,
"width": 1296
},
"timing": {
"convert_ms": 0.0,
"copy_ms": 0.0,
"encode_ms": 0.0,
"latency_ms": 0.0,
"skipped": 0
}
},
"cam_status_after": {
"buffers": "uncached",
"cam": "lid",
"capture_allowed": true,
"clients": 0,
"convert": "gpu",
"encoder": "vpu",
"fps": 0.3,
"fps_cap": 0.0,
"frames": 5,
"h264": {
"active": false,
"clients": 0
},
"health": {
"captured": 80,
"corrupt": 0,
"restarts": 0,
"withheld": 0
},
"hw_fps_skip": false,
"running": true,
"sensor": "OV5648",
"snapshot": {
"height": 1944,
"width": 2592
},
"stopped_by_lid": false,
"stream": {
"height": 972,
"width": 1296
},
"timing": {
"convert_ms": 0.0,
"copy_ms": 0.0,
"encode_ms": 0.0,
"latency_ms": 0.0,
"skipped": 9
}
},
"clients_while_watching": 2,
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"lid_lamp": "132",
"operator_while_watched": [
200,
63710
],
"snapshot_bytes": 63084,
"snapshot_dark_bytes": 33856,
"snapshot_full_bytes": 229514,
"stream_ctype": "multipart/x-mixed-replace; boundary=forgectrl-frame"
},
"fingerprint": "5965b71c282cb7b8388d194e34944e0855da75e97354224966a75fcb21b04bc2",
"image": "20260928153805 (dev)",
"log": [
"16:31:59 start camera.snapshot (auto, api) in campaign c-20260928162331-3969",
"16:31:59 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:31:59 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"16:31:59 queued by the unattended queue opened 2026-09-28T16:23:31Z",
"16:31:59 baseline: pre: clean",
"16:31:59 cam status: {'running': False, 'cam': 'lid', 'clients': 0, 'frames': 0, 'fps': 0.0, 'fps_cap': 0.0, 'hw_fps_skip': False, 'encoder': 'software', 'convert': 'cpu', 'buffers': 'uncached', 'sensor': 'OV5648', 'stream': {'width': 1296, 'height': 972}, 'snapshot': {'width': 2592, 'height': 1944}, 'h264': {'active': False, 'clients': 0}, 'health': {'captured': 0, 'corrupt': 0, 'restarts': 0, 'withheld': 0}, 'timing': {'latency_ms': 0.0, 'convert_ms': 0.0, 'copy_ms': 0.0, 'encode_ms': 0.0, 'skipped': 0}, 'capture_allowed': True, 'stopped_by_lid': False}",
"16:32:00 GET /cam/snapshot?cam=lid&res=half -> 200 (63084 bytes)",
"16:32:02 lamp 132 -> 63084 bytes; lamp off -> 33856 bytes",
"16:32:03 GET /cam/snapshot?cam=lid&res=full -> 200 (229514 bytes)",
"16:32:04 stream: multipart/x-mixed-replace; boundary=forgectrl-frame, first 65536 bytes",
"16:32:04 background capture while a viewer watches -> 409 somebody is watching a camera: a background capture waits until they stop",
"16:32:06 cam status after: {'running': True, 'cam': 'lid', 'clients': 0, 'frames': 5, 'fps': 0.3, 'fps_cap': 0.0, 'hw_fps_skip': False, 'encoder': 'vpu', 'convert': 'gpu', 'buffers': 'uncached', 'sensor': 'OV5648', 'stream': {'width': 1296, 'height': 972}, 'snapshot': {'width': 2592, 'height': 1944}, 'h264': {'active': False, 'clients': 0}, 'health': {'captured': 80, 'corrupt': 0, 'restarts': 0, 'withheld': 0}, 'timing': {'latency_ms': 0.0, 'convert_ms': 0.0, 'copy_ms': 0.0, 'encode_ms': 0.0, 'skipped': 9}, 'capture_allowed': True, 'stopped_by_lid': False}",
"16:32:06 PASS: half-res snapshot 63084 bytes, 33856 with the lamp off; full-res 229514; stream multipart/x-mixed-replace; boundary=forgectrl-frame",
"16:32:16 baseline: post: clean",
"16:32:16 result PASS"
],
"manifest_sha": "faf9563c750bb8bd4bfc8778b6af053cddb63fa335ab946caf2f71631ede740f",
"message": "",
"result": "PASS",
"test": "camera.snapshot",
"ts": "2026-09-28T16:32:16Z"
},
"requires": [
"forgectrl.panel-serves"
],
"satisfied": true,
"source_sha": "bc539a78bbee42015b9a529bfb2037c97517024d6217589900a892cbb4e225a5",
"subsystem": "camera",
"title": "Lid camera snapshot and stream"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/cam.*"
],
[
"forgectrl",
"src/camhealth.*"
],
[
"forgectrl",
"src/debayer.*"
],
[
"forgectrl",
"src/vpu_jpeg.*"
],
[
"forgectrl",
"src/vpu_h264.*"
],
[
"forgectrl",
"src/mp4mux.*"
],
[
"forgectrl",
"src/gpu_debayer.*"
],
[
"forgectrl",
"src/ipu_copy.*"
],
[
"forgectrl",
"src/main.c"
],
[
"python3-gfhardware",
"gfhardware/src/**"
],
[
"python3-gfhardware",
"gfhardware/cam*"
]
],
"fingerprint": "737bebc1c95b2cda05d80f1717b08c3f809e13a9344f7dae9e7e497b94338800",
"hardware": "api",
"id": "camera.sensor-profile",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928171100-3ff5",
"duration_s": 12,
"evidence": {
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T17:11:00Z"
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"geometry": {
"snapshot": {
"height": 1944,
"width": 2592
},
"stream": {
"height": 972,
"width": 1296
}
},
"jpeg_full": [
2592,
1944
],
"jpeg_half": [
1296,
972
],
"sensor": "OV5648"
},
"fingerprint": "737bebc1c95b2cda05d80f1717b08c3f809e13a9344f7dae9e7e497b94338800",
"image": "20260928170058 (dev)",
"log": [
"17:19:16 start camera.sensor-profile (auto, api) in campaign c-20260928171100-3ff5",
"17:19:16 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"17:19:16 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"17:19:16 queued by the unattended queue opened 2026-09-28T17:11:00Z",
"17:19:16 baseline: pre: clean",
"17:19:16 sensor: OV5648",
"17:19:16 advertised: snapshot 2592x1944, stream 1296x972",
"17:19:17 full snapshot: (2592, 1944) (227732 bytes)",
"17:19:18 half snapshot: (1296, 972) (63569 bytes)",
"17:19:28 baseline: post: clean",
"17:19:28 result PASS"
],
"manifest_sha": "98f8c4dad7130ecf1fa44e5e0f1a1b53e6b9359f005f22a1ddbee496375d9a9e",
"message": "",
"result": "PASS",
"test": "camera.sensor-profile",
"ts": "2026-09-28T17:19:28Z"
},
"requires": [
"forgectrl.panel-serves"
],
"satisfied": true,
"source_sha": "2cd6a21e37c55b6f4d7961f07f69ae1949bc42c7e71978b372b9456f05300410",
"subsystem": "camera",
"title": "Camera geometry follows the fitted sensor"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/cam.*"
],
[
"forgectrl",
"src/camhealth.*"
],
[
"forgectrl",
"src/debayer.*"
],
[
"forgectrl",
"src/vpu_jpeg.*"
],
[
"forgectrl",
"src/vpu_h264.*"
],
[
"forgectrl",
"src/mp4mux.*"
],
[
"forgectrl",
"src/gpu_debayer.*"
],
[
"forgectrl",
"src/ipu_copy.*"
],
[
"forgectrl",
"src/main.c"
],
[
"python3-gfhardware",
"gfhardware/src/**"
],
[
"python3-gfhardware",
"gfhardware/cam*"
]
],
"fingerprint": "c8a2f39e447b7e323b14c6c6ce7c0a58ef44e42decc00b7139bb6f7aa6c56257",
"hardware": "api",
"id": "camera.h264-stream",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928171100-3ff5",
"duration_s": 13,
"evidence": {
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T17:11:00Z"
},
"bytes": 65536,
"cam_status": {
"buffers": "uncached",
"cam": "lid",
"capture_allowed": true,
"clients": 0,
"convert": "gpu",
"encoder": "software",
"fps": 0.0,
"fps_cap": 0.0,
"frames": 0,
"h264": {
"active": true,
"clients": 1
},
"health": {
"captured": 174,
"corrupt": 0,
"restarts": 0,
"withheld": 0
},
"hw_fps_skip": false,
"running": true,
"sensor": "OV5648",
"snapshot": {
"height": 1944,
"width": 2592
},
"stopped_by_lid": false,
"stream": {
"height": 972,
"width": 1296
},
"timing": {
"convert_ms": 0.0,
"copy_ms": 0.0,
"encode_ms": 0.0,
"latency_ms": 0.0,
"skipped": 5
}
},
"codec": "avc1.424020",
"content_type": "video/mp4",
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
}
},
"fingerprint": "c8a2f39e447b7e323b14c6c6ce7c0a58ef44e42decc00b7139bb6f7aa6c56257",
"image": "20260928170058 (dev)",
"log": [
"17:19:28 start camera.h264-stream (auto, api) in campaign c-20260928171100-3ff5",
"17:19:28 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"17:19:28 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"17:19:28 queued by the unattended queue opened 2026-09-28T17:11:00Z",
"17:19:29 baseline: pre: clean",
"17:19:30 codec avc1.424020, content-type video/mp4",
"17:19:31 convert=gpu h264={'active': True, 'clients': 1}",
"17:19:42 baseline: post: clean",
"17:19:42 result PASS"
],
"manifest_sha": "98f8c4dad7130ecf1fa44e5e0f1a1b53e6b9359f005f22a1ddbee496375d9a9e",
"message": "",
"result": "PASS",
"test": "camera.h264-stream",
"ts": "2026-09-28T17:19:42Z"
},
"requires": [
"forgectrl.panel-serves"
],
"satisfied": true,
"source_sha": "397afe06cbabefbde565e3018f68b948556a8bd87e9b9a17d8c1024e0b480294",
"subsystem": "camera",
"title": "H.264 live stream"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/cam.*"
],
[
"forgectrl",
"src/camhealth.*"
],
[
"forgectrl",
"src/debayer.*"
],
[
"forgectrl",
"src/vpu_jpeg.*"
],
[
"forgectrl",
"src/vpu_h264.*"
],
[
"forgectrl",
"src/mp4mux.*"
],
[
"forgectrl",
"src/gpu_debayer.*"
],
[
"forgectrl",
"src/ipu_copy.*"
],
[
"forgectrl",
"src/main.c"
],
[
"python3-gfhardware",
"gfhardware/src/**"
],
[
"python3-gfhardware",
"gfhardware/cam*"
]
],
"fingerprint": "d672bd505345af133b50675c90d2a2344a62dbea3d55ca3c1c5442bbdf886a58",
"hardware": "api",
"id": "camera.frame-health",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928171100-3ff5",
"duration_s": 18,
"evidence": {
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T17:11:00Z"
},
"captured": 14,
"corrupt": 0,
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"health_after": {
"captured": 340,
"corrupt": 0,
"restarts": 0,
"withheld": 0
},
"health_before": {
"captured": 326,
"corrupt": 0,
"restarts": 0,
"withheld": 0
},
"restarts": 0,
"stream_bytes": 8978432,
"stream_captured": 75,
"stream_health": [
{
"captured": 340,
"corrupt": 0,
"restarts": 0,
"withheld": 0
},
{
"captured": 415,
"corrupt": 0,
"restarts": 0,
"withheld": 0
}
],
"stream_timing": {
"convert_ms": 15.8,
"copy_ms": 11.8,
"encode_ms": 6.6,
"latency_ms": 67.2,
"skipped": 9
},
"stream_withheld": 0
},
"fingerprint": "d672bd505345af133b50675c90d2a2344a62dbea3d55ca3c1c5442bbdf886a58",
"image": "20260928170058 (dev)",
"log": [
"17:19:42 start camera.frame-health (auto, api) in campaign c-20260928171100-3ff5",
"17:19:42 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"17:19:42 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"17:19:42 queued by the unattended queue opened 2026-09-28T17:11:00Z",
"17:19:42 baseline: pre: clean",
"17:19:42 before: {'captured': 326, 'corrupt': 0, 'restarts': 0, 'withheld': 0}",
"17:19:44 after: {'captured': 340, 'corrupt': 0, 'restarts': 0, 'withheld': 0}",
"17:19:44 captured 14 frames, 0 corrupt, 0 stream restarts",
"17:19:49 stream: 8978432 bytes in 5 s, timing {'latency_ms': 67.2, 'convert_ms': 15.8, 'copy_ms': 11.8, 'encode_ms': 6.6, 'skipped': 9}",
"17:20:00 baseline: post: clean",
"17:20:00 result PASS"
],
"manifest_sha": "98f8c4dad7130ecf1fa44e5e0f1a1b53e6b9359f005f22a1ddbee496375d9a9e",
"message": "",
"result": "PASS",
"test": "camera.frame-health",
"ts": "2026-09-28T17:20:00Z"
},
"requires": [
"forgectrl.panel-serves"
],
"satisfied": true,
"source_sha": "85c6b4ad1d9c2ca76e64f9964f9a11ef94074e34614ef5bc7010de733407c6bb",
"subsystem": "camera",
"title": "Capture delivers whole frames"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/cam.*"
],
[
"forgectrl",
"src/camhealth.*"
],
[
"forgectrl",
"src/debayer.*"
],
[
"forgectrl",
"src/vpu_jpeg.*"
],
[
"forgectrl",
"src/vpu_h264.*"
],
[
"forgectrl",
"src/mp4mux.*"
],
[
"forgectrl",
"src/gpu_debayer.*"
],
[
"forgectrl",
"src/ipu_copy.*"
],
[
"forgectrl",
"src/main.c"
],
[
"python3-gfhardware",
"gfhardware/src/**"
],
[
"python3-gfhardware",
"gfhardware/cam*"
],
[
"forgectrl",
"src/status.*"
],
[
"python3-gfhardware",
"gfhardware/switches.py"
],
[
"forgefirm-app",
"forgefirm-app/ffmachine.py"
],
[
"forgectrl",
"src/auth.*"
]
],
"fingerprint": "d71cb19d4d4ccd8594360bb0414809f6800ecc8d5552ad765c4e3affce8e7300",
"hardware": "api",
"id": "camera.lid-privacy",
"inherited": true,
"kind": "operator",
"record": {
"answers": [],
"campaign": "c-20260928171100-3ff5",
"duration_s": 15,
"evidence": {
"actions": [
{
"by": "fixture",
"channel": "lid",
"state": "close",
"took_s": 0.02,
"ts": "2026-09-28T17:20:01Z"
},
{
"by": "fixture",
"channel": "lid",
"state": "open",
"took_s": 0.02,
"ts": "2026-09-28T17:20:02Z"
},
{
"by": "fixture",
"channel": "lid",
"state": "close",
"took_s": 0.28,
"ts": "2026-09-28T17:20:04Z"
}
],
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T17:11:00Z"
},
"closed_snapshot_bytes": 63103,
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"head_cloud_form_lid_open": [
409,
"lid is open: this capture needs the lid closed"
],
"snapshot_lid_open": [
409,
"lid is open: this capture needs the lid closed"
],
"status_lid_open": {
"buffers": "uncached",
"cam": "lid",
"capture_allowed": false,
"clients": 0,
"convert": "gpu",
"encoder": "vpu",
"fps": 0.0,
"fps_cap": 0.0,
"frames": 2,
"h264": {
"active": false,
"clients": 0
},
"health": {
"captured": 578,
"corrupt": 0,
"restarts": 0,
"withheld": 0
},
"hw_fps_skip": false,
"running": false,
"sensor": "OV5648",
"snapshot": {
"height": 1944,
"width": 2592
},
"stopped_by_lid": true,
"stream": {
"height": 972,
"width": 1296
},
"timing": {
"convert_ms": 0.0,
"copy_ms": 0.0,
"encode_ms": 0.0,
"latency_ms": 0.0,
"skipped": 12
}
},
"stream_bytes_after_lid_open": 247517
},
"fingerprint": "d71cb19d4d4ccd8594360bb0414809f6800ecc8d5552ad765c4e3affce8e7300",
"image": "20260928170058 (dev)",
"log": [
"17:20:00 start camera.lid-privacy (operator, api) in campaign c-20260928171100-3ff5",
"17:20:01 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"17:20:01 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"17:20:01 fixture: running unattended (no prompt can be answered)",
"17:20:01 queued by the unattended queue opened 2026-09-28T17:11:00Z",
"17:20:01 baseline: pre: clean",
"17:20:01 ACT lid close (fixture)",
"17:20:01 ACT lid close: done after 0.0 s",
"17:20:02 lid closed: snapshot 63103 bytes",
"17:20:02 ACT lid open (fixture)",
"17:20:02 ACT lid open: done after 0.0 s",
"17:20:02 stream ended after 247517 further buffered bytes",
"17:20:02 lid open: snapshot -> 409 b'lid is open: this capture needs the lid closed'",
"17:20:03 lid open: the panel's head snapshot -> 200",
"17:20:04 lid open: the extension host's head snapshot -> 200",
"17:20:04 lid open: head snapshot without a token or the header -> 409 b'lid is open: this capture needs the lid closed'",
"17:20:04 lid open: head stream for no local viewer -> 409",
"17:20:04 lid open: stream -> 409",
"17:20:04 ACT lid close (fixture)",
"17:20:04 ACT lid close: done after 0.3 s",
"17:20:05 lid closed again: snapshot 63146 bytes",
"17:20:16 baseline: post: clean",
"17:20:16 result PASS"
],
"manifest_sha": "98f8c4dad7130ecf1fa44e5e0f1a1b53e6b9359f005f22a1ddbee496375d9a9e",
"message": "",
"result": "PASS",
"test": "camera.lid-privacy",
"ts": "2026-09-28T17:20:16Z"
},
"requires": [
"forgectrl.panel-serves"
],
"satisfied": true,
"source_sha": "ce2095e3ebc3bf09b81ecf2c3d92cd80971d588af2424717f0e0c7b5078b9a5c",
"subsystem": "camera",
"title": "Cameras see the room only with the lid closed"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/camkey.*"
],
[
"forgectrl",
"src/auth.c"
],
[
"forgectrl",
"src/main.c"
],
[
"forgectrl",
"src/ui/panel.js"
],
[
"forgectrl",
"src/ui/index.html"
],
[
"forgectrl",
"src/ui/help.js"
]
],
"fingerprint": "41c5a19c97d9518732b4d9a07b7ca45ce4a4471faac99384967cf359ab0e198c",
"hardware": "api",
"id": "camera.key-read",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928171100-3ff5",
"duration_s": 1,
"evidence": {
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T17:11:00Z"
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"key_len": 32,
"rotated": true
},
"fingerprint": "41c5a19c97d9518732b4d9a07b7ca45ce4a4471faac99384967cf359ab0e198c",
"image": "20260928170058 (dev)",
"log": [
"17:20:16 start camera.key-read (auto, api) in campaign c-20260928171100-3ff5",
"17:20:17 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"17:20:17 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"17:20:17 queued by the unattended queue opened 2026-09-28T17:11:00Z",
"17:20:17 baseline: pre: clean",
"17:20:17 GET http://<IP-2>/cam/status (no key) -> 403",
"17:20:17 GET http://<IP-2>/cam/status?key=... -> 200",
"17:20:17 GET https://<IP-2>/cam/status (no key) -> 403",
"17:20:17 GET https://<IP-2>/cam/status?key=... -> 200",
"17:20:17 POST /settings with the camera key -> 403",
"17:20:17 baseline: post: clean",
"17:20:17 result PASS"
],
"manifest_sha": "98f8c4dad7130ecf1fa44e5e0f1a1b53e6b9359f005f22a1ddbee496375d9a9e",
"message": "",
"result": "PASS",
"test": "camera.key-read",
"ts": "2026-09-28T17:20:17Z"
},
"requires": [
"forgectrl.auth"
],
"satisfied": true,
"source_sha": "91697fdf5789f0ecda0b93d88b0cb1631b551ba732b71f97ab50c77bb8d8446a",
"subsystem": "camera",
"title": "The camera key reads without a login"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/update.c"
],
[
"forgectrl",
"src/update.h"
],
[
"forgectrl",
"src/relcheck.c"
],
[
"forgectrl",
"src/relcheck.h"
],
[
"ffboot",
"**"
]
],
"fingerprint": "0182529e4dd58d5cafe57bd18ee0c07ef27254e51a5b12f9d5a7a20607df5934",
"hardware": "api",
"id": "update.slots-and-signature",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928162331-3969",
"duration_s": 1,
"evidence": {
"apply": {
"body": {
"started": true
},
"status": 202
},
"apply_result": {
"error": "archive is not signed with the ForgeFIRM release key (confirm_unsigned=1 to apply anyway)",
"ok": false
},
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T16:23:31Z"
},
"ffboot_l_rc": 0,
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"fwup_foreign": {
"own_key_rc": 0,
"shipped_key_rc": 1
},
"fwup_garbage_rc": 1,
"fwup_gen_rc": 0,
"slots": {
"archives": [],
"booted": "/dev/mmcblk1p1",
"env": {
"mmcdev": "0",
"mmchwpart": "0",
"mmcpart": "1",
"mmcroot": "/dev/mmcblk1p1"
},
"slots": {
"a": {
"booted": false,
"device": "/dev/mmcblk2p1",
"kernel": "yes",
"next": false,
"present": "yes",
"state": "ok",
"type": "forgefirm",
"version": "v0.0.6"
},
"b": {
"booted": false,
"device": "/dev/mmcblk2p2",
"kernel": "yes",
"next": false,
"present": "yes",
"state": "ok",
"type": "forgefirm",
"version": "v0.0.5"
},
"sd": {
"booted": true,
"device": "/dev/mmcblk1p1",
"kernel": "yes",
"next": true,
"present": "yes",
"state": "ok",
"type": "forgefirm",
"version": "20260928153805 (dev)"
}
},
"staged": {
"download": {
"bytes": 0,
"present": false,
"version": ""
},
"upload": {
"bytes": 0,
"present": false,
"version": ""
}
}
}
},
"fingerprint": "0182529e4dd58d5cafe57bd18ee0c07ef27254e51a5b12f9d5a7a20607df5934",
"image": "20260928153805 (dev)",
"log": [
"16:27:32 start update.slots-and-signature (auto, api) in campaign c-20260928162331-3969",
"16:27:32 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:27:32 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"16:27:32 queued by the unattended queue opened 2026-09-28T16:23:31Z",
"16:27:33 baseline: pre: clean",
"16:27:33 GET /slots -> 200 {'booted': '/dev/mmcblk1p1', 'env': {'mmcdev': '0', 'mmchwpart': '0', 'mmcpart': '1', 'mmcroot': '/dev/mmcblk1p1'}, 'slots': {'sd': {'device': '/dev/mmcblk1p1', 'present': 'yes', 'state': 'ok', 'type': 'forgefirm', 'version': '20260928153805 (dev)', 'kernel': 'yes', 'booted': True, 'next': True}, 'a': {'device': '/dev/mmcblk2p1', 'present': 'yes', 'state': 'ok', 'type': 'forgefirm', 'version': 'v0.0.6', 'kernel': 'yes', 'booted': False, 'next': False}, 'b': {'device': '/dev/mmcblk2p2', 'present': 'yes', 'state': 'ok', 'type': 'forgefirm', 'version': 'v0.0.5', 'kernel': 'yes', 'booted': False, 'next': False}}, 'archives': [], 'staged': {'download': {'present': False, 'bytes': 0, 'version': ''}, 'upload': {'present': False, 'bytes': 0, 'version': ''}}}",
"16:27:33 ffboot -l -> rc 0\nenv.mmcdev=0\nenv.mmchwpart=0\nenv.mmcpart=1\nenv.mmcroot=/dev/mmcblk1p1\nbooted.root=/dev/mmcblk1p1\nslot.sd.device=/dev/mmcblk1p1\nslot.sd.present=yes\nslot.sd.state=ok\nslot.sd.type=forgefirm\nslot.sd.version=20260928153805 (dev)\nslot.sd.kernel=yes\nslot.sd.booted=yes\nslot.sd.next=yes\nslot.a.device=/dev/mmcblk2p1\nslot.a.present=yes\nslot.a.state=ok\nslot.a.type=forgefirm\nslot.a.version=v0.0.6\nslot.a.kernel=yes\nslot.b.device=/dev/mmcblk2p2\nslot.b.present=yes\nslot.b.state=ok\nslot.b.type=forgefirm\nslot.b.version=v0.0.5\nslot.b.kernel=yes\nslot.legacy.device=/dev/mmcblk2p4\nslot.legacy.present=no",
"16:27:33 GET /update/status -> 200 {'running': False, 'kind': '', 'phase': '', 'elapsed': 0, 'progress_bytes': -1, 'result': None}",
"16:27:33 fwup -V garbage -> rc 1: fwup: Unrecognized archive format",
"16:27:33 fwup -V signed: own key rc 0, shipped key rc 1",
"16:27:33 POST /update/apply slot=b file=upload (no confirm_unsigned) -> 202 {'started': True}",
"16:27:34 apply result: {'ok': False, 'error': 'archive is not signed with the ForgeFIRM release key (confirm_unsigned=1 to apply anyway)'}",
"16:27:34 baseline: post: clean",
"16:27:34 result PASS"
],
"manifest_sha": "faf9563c750bb8bd4bfc8778b6af053cddb63fa335ab946caf2f71631ede740f",
"message": "",
"result": "PASS",
"test": "update.slots-and-signature",
"ts": "2026-09-28T16:27:34Z"
},
"requires": [
"forgectrl.auth"
],
"satisfied": true,
"source_sha": "b04f6de9bc9395bb20998546145ee24a9c002a24767e4c0b4dec87a3d0b22879",
"subsystem": "update",
"title": "Boot slots readable, unsigned and foreign-signed archives refused"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/update.c"
],
[
"forgectrl",
"src/update.h"
],
[
"forgectrl",
"src/relcheck.c"
],
[
"forgectrl",
"src/relcheck.h"
],
[
"ffboot",
"**"
],
[
"forgectrl",
"src/fwproduct.c"
],
[
"forgectrl",
"src/fwproduct.h"
]
],
"fingerprint": "08b2d256ed6b0de6896b9c69753c45878066b1bf41407d9e3a90193a67c2dd50",
"hardware": "api",
"id": "update.product-gate",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928171100-3ff5",
"duration_s": 1,
"evidence": {
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T17:11:00Z"
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"uploads": {
"another-product": [
400,
"this archive is not firmware"
],
"extension-signed": [
400,
"this archive is an extension package, not firmware"
],
"extension-unsigned": [
400,
"this archive is an extension package, not firmware"
],
"extension-with-task": [
400,
"this archive is an extension package, not firmware"
],
"firmware-unsigned": [
200,
{
"bytes": 468,
"file": "upload",
"ok": true,
"signature": "unsigned",
"version": "0.0.0-test"
}
]
}
},
"fingerprint": "08b2d256ed6b0de6896b9c69753c45878066b1bf41407d9e3a90193a67c2dd50",
"image": "20260928170058 (dev)",
"log": [
"17:20:18 start update.product-gate (auto, api) in campaign c-20260928171100-3ff5",
"17:20:18 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"17:20:18 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"17:20:18 queued by the unattended queue opened 2026-09-28T17:11:00Z",
"17:20:18 baseline: pre: clean",
"17:20:18 upload extension-unsigned -> 400 this archive is an extension package, not firmware",
"17:20:18 upload extension-signed -> 400 this archive is an extension package, not firmware",
"17:20:19 upload extension-with-task -> 400 this archive is an extension package, not firmware",
"17:20:19 upload another-product -> 400 this archive is not firmware",
"17:20:19 upload firmware-unsigned -> 200 {'ok': True, 'file': 'upload', 'bytes': 468, 'version': '0.0.0-test', 'signature': 'unsigned'}",
"17:20:19 PASS: three extension packages and one foreign product refused at the firmware upload with nothing staged; firmware taken as the unsigned upload it is",
"17:20:19 baseline: post: clean",
"17:20:19 result PASS"
],
"manifest_sha": "98f8c4dad7130ecf1fa44e5e0f1a1b53e6b9359f005f22a1ddbee496375d9a9e",
"message": "",
"result": "PASS",
"test": "update.product-gate",
"ts": "2026-09-28T17:20:19Z"
},
"requires": [
"forgectrl.auth"
],
"satisfied": true,
"source_sha": "140856131135e3ecfa53dabf07ead494443296a3a751adbebe3415d0dc2c8ec9",
"subsystem": "update",
"title": "The firmware upload takes firmware only: an extension package is refused by name"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/update.c"
],
[
"forgectrl",
"src/update.h"
],
[
"forgectrl",
"src/relcheck.c"
],
[
"forgectrl",
"src/relcheck.h"
],
[
"ffboot",
"**"
],
[
"forgectrl",
"src/ui/panel.js"
],
[
"forgectrl",
"src/ui/index.html"
]
],
"fingerprint": "7169dcbf4fbfc7021b026759d6ec60d83c8808a10329fd1e46074afafa627c19",
"hardware": "api",
"id": "update.release-check",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928171100-3ff5",
"duration_s": 1,
"evidence": {
"after_check": {
"available": true,
"bytes": 36833005,
"checked": 1790616020,
"current": "20260928170058 (dev)",
"detail": "",
"dismissed": true,
"new": true,
"version": "v0.0.6"
},
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T17:11:00Z"
},
"before": {
"available": true,
"bytes": 36833005,
"checked": 1790615862,
"current": "20260928170058 (dev)",
"detail": "",
"dismissed": true,
"new": true,
"version": "v0.0.6"
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
}
},
"fingerprint": "7169dcbf4fbfc7021b026759d6ec60d83c8808a10329fd1e46074afafa627c19",
"image": "20260928170058 (dev)",
"log": [
"17:20:19 start update.release-check (auto, api) in campaign c-20260928171100-3ff5",
"17:20:20 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"17:20:20 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"17:20:20 queued by the unattended queue opened 2026-09-28T17:11:00Z",
"17:20:20 baseline: pre: clean",
"17:20:20 GET /update/release -> 200 {'available': True, 'version': 'v0.0.6', 'current': '20260928170058 (dev)', 'new': True, 'checked': 1790615862, 'dismissed': True, 'detail': '', 'bytes': 36833005}",
"17:20:20 POST /update/check -> 200 {'available': True, 'version': 'v0.0.6', 'current': '20260928170058 (dev)', 'new': True, 'checked': 1790616020, 'dismissed': True, 'detail': '', 'bytes': 36833005}",
"17:20:20 POST /update/dismiss version=<not a tag> -> 400 {'error': 'version is not a release tag'}",
"17:20:20 POST /update/dismiss version=v0.0.6 -> 200 {'available': True, 'version': 'v0.0.6', 'current': '20260928170058 (dev)', 'new': True, 'checked': 1790616020, 'dismissed': True, 'detail': '', 'bytes': 36833005}",
"17:20:20 POST /update/dismiss version= -> 200",
"17:20:20 dismissal put back to 'v0.0.6' -> 200",
"17:20:20 baseline: post: clean",
"17:20:20 result PASS"
],
"manifest_sha": "98f8c4dad7130ecf1fa44e5e0f1a1b53e6b9359f005f22a1ddbee496375d9a9e",
"message": "",
"result": "PASS",
"test": "update.release-check",
"ts": "2026-09-28T17:20:20Z"
},
"requires": [
"forgectrl.auth"
],
"satisfied": true,
"source_sha": "8242aaf1ee265611b0680c94ffaeef148e174e09e0a564b3e0e5c622bbcfa1c8",
"subsystem": "update",
"title": "Release check answers from the releases API; the alert dismissal is per release"
},
{
"always": false,
"covers": [
[
"forgefirm-app",
"forgefirm-app/gfcloud.py"
],
[
"forgefirm-app",
"forgefirm-app/ffmachine.py"
],
[
"forgefirm-app",
"forgefirm-app/gfhome.conf.sample"
],
[
"python3-gfhardware",
"gfhardware/__init__.py"
],
[
"python3-gfhardware",
"gfhardware/_common.py"
],
[
"python3-gfhardware",
"gfhardware/id.py"
],
[
"python3-gfhardware",
"gfhardware/coolsvc.py"
],
[
"python3-gfutilities",
"gfutilities/__init__.py"
],
[
"python3-gfutilities",
"gfutilities/_common.py"
],
[
"python3-gfutilities",
"gfutilities/configuration.py"
],
[
"python3-gfutilities",
"gfutilities/device/__init__.py"
],
[
"python3-gfutilities",
"gfutilities/device/basemachine.py"
],
[
"python3-gfutilities",
"gfutilities/device/settings.py"
],
[
"python3-gfutilities",
"gfutilities/service/__init__.py"
],
[
"python3-gfutilities",
"gfutilities/service/dispatch.py"
],
[
"python3-gfutilities",
"gfutilities/service/websocket.py"
],
[
"python3-gfutilities",
"gfutilities/service/authentication.py"
],
[
"python3-gfutilities",
"gfutilities/service/gfuiservice.py"
],
[
"forgefirm-app",
"forgefirm-app/**"
],
[
"python3-gfhardware",
"gfhardware/**"
],
[
"python3-gfutilities",
"gfutilities/puls/**"
],
[
"forgectrl",
"src/super.c"
],
[
"forgectrl",
"src/main.c"
],
[
"forgectrl",
"src/cool.*"
],
[
"forgectrl",
"src/airflow.*"
],
[
"grblhal-glowforge",
"src/**"
]
],
"fingerprint": "4528f9706bcf89e9151406a49c169ec84882296d0ceef32cb4a258c58e05f710",
"hardware": "api",
"id": "cloud.mode-switch",
"inherited": true,
"kind": "operator",
"record": {
"answers": [],
"campaign": "c-20260928162331-3969",
"duration_s": 168,
"evidence": {
"actions": [
{
"by": "fixture",
"channel": "lid",
"state": "open",
"took_s": 0.02,
"ts": "2026-09-28T16:42:40Z"
},
{
"by": "fixture",
"channel": "lid",
"state": "close",
"took_s": 0.28,
"ts": "2026-09-28T16:42:49Z"
}
],
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T16:23:31Z"
},
"cam_after": {
"buffers": "uncached",
"cam": "lid",
"capture_allowed": true,
"clients": 0,
"convert": "cpu",
"encoder": "software",
"fps": 0.0,
"fps_cap": 0.0,
"frames": 0,
"h264": {
"active": false,
"clients": 0
},
"health": {
"captured": 613,
"corrupt": 0,
"restarts": 0,
"withheld": 0
},
"hw_fps_skip": false,
"running": false,
"sensor": "OV5648",
"snapshot": {
"height": 1944,
"width": 2592
},
"stopped_by_lid": false,
"stream": {
"height": 972,
"width": 1296
},
"timing": {
"convert_ms": 0.0,
"copy_ms": 0.0,
"encode_ms": 0.0,
"latency_ms": 0.0,
"skipped": 10
}
},
"cam_before": {
"buffers": "uncached",
"cam": "lid",
"capture_allowed": true,
"clients": 0,
"convert": "cpu",
"encoder": "software",
"fps": 0.0,
"fps_cap": 0.0,
"frames": 0,
"h264": {
"active": false,
"clients": 0
},
"health": {
"captured": 0,
"corrupt": 0,
"restarts": 0,
"withheld": 0
},
"hw_fps_skip": false,
"running": false,
"sensor": "OV5648",
"snapshot": {
"height": 1944,
"width": 2592
},
"stopped_by_lid": false,
"stream": {
"height": 972,
"width": 1296
},
"timing": {
"convert_ms": 0.0,
"copy_ms": 0.0,
"encode_ms": 0.0,
"latency_ms": 0.0,
"skipped": 0
}
},
"cam_during_cloud": {
"buffers": "uncached",
"cam": "lid",
"capture_allowed": false,
"clients": 0,
"convert": "cpu",
"encoder": "software",
"fps": 0.0,
"fps_cap": 0.0,
"frames": 0,
"h264": {
"active": false,
"clients": 0
},
"health": {
"captured": 0,
"corrupt": 0,
"restarts": 0,
"withheld": 0
},
"hw_fps_skip": false,
"running": false,
"sensor": "OV5648",
"snapshot": {
"height": 1944,
"width": 2592
},
"stopped_by_lid": false,
"stream": {
"height": 972,
"width": 1296
},
"timing": {
"convert_ms": 0.0,
"copy_ms": 0.0,
"encode_ms": 0.0,
"latency_ms": 0.0,
"skipped": 0
}
},
"cloud_return": {
"counters_across_jog": [
[
0,
0,
0
],
[
4996,
-2892,
0
]
],
"counters_since_start": [
0,
0,
0
],
"mm": [
-23.419,
13.556
],
"session_travel_steps": [
-1249,
723
]
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"gf_probe": {
"checked_at": 1790613759,
"latest_gf_version": "2.6.0-2228",
"tested_against_gf": "2.6.0-2228"
},
"gfhome_complete": "2026-09-28T16:45:10.995648+00:00 gfhome[9572] INFO gfhome:home homing complete (service quiet 10s, 4 motion windows)",
"grbl_state": "Idle",
"homed": true,
"homing_mode": "manual",
"homing_s": 74.5,
"hunt": "2026-09-28T16:42:48.700020+00:00 gfcloud[9042] INFO basemachine:_finish_action hunt [1589699892]: finished with event \":completed\"",
"hunt_before_lid_open": false,
"hunt_gates": [
{
"accel_watch": "watch",
"armed": false,
"down_c": 22.54,
"fan_gates": {
"air_assist": {
"floor": 6093,
"reading": 2604,
"state": "idle"
},
"exhaust": {
"floor": 6416,
"reading": 0,
"state": "idle"
},
"intake_1": {
"floor": 2277,
"reading": 732,
"state": "idle"
},
"intake_2": {
"floor": 2277,
"reading": 734,
"state": "idle"
},
"purge": {
"floor": 345,
"reading": 630,
"state": "idle"
}
},
"fire_ok": true,
"fire_watch": "armed",
"gates_off": [],
"hold": false,
"limits": {
"air_assist_min_rpm": 6093,
"coolant_critical_c": 38.0,
"coolant_max_c": 33.0,
"coolant_min_c": 5.0,
"coolant_resume_c": 31.0,
"coolant_source": "local",
"exhaust_min_rpm": 6416,
"intake_min_rpm": 2277
},
"phase": "idle",
"quiet_hold": false,
"reason": "",
"report_age_s": 0.4,
"resume_ok": true,
"up_c": 22.77,
"verdict": "OK"
},
{
"accel_watch": "watch",
"armed": false,
"down_c": 22.54,
"fan_gates": {
"air_assist": {
"floor": 6093,
"reading": 2604,
"state": "idle"
},
"exhaust": {
"floor": 6416,
"reading": 0,
"state": "idle"
},
"intake_1": {
"floor": 2277,
"reading": 732,
"state": "idle"
},
"intake_2": {
"floor": 2277,
"reading": 734,
"state": "idle"
},
"purge": {
"floor": 345,
"reading": 630,
"state": "idle"
}
},
"fire_ok": true,
"fire_watch": "armed",
"gates_off": [],
"hold": false,
"limits": {
"air_assist_min_rpm": 6093,
"coolant_critical_c": 38.0,
"coolant_max_c": 33.0,
"coolant_min_c": 5.0,
"coolant_resume_c": 31.0,
"coolant_source": "local",
"exhaust_min_rpm": 6416,
"intake_min_rpm": 2277
},
"phase": "idle",
"quiet_hold": false,
"reason": "",
"report_age_s": 0.9,
"resume_ok": true,
"up_c": 22.77,
"verdict": "OK"
},
{
"accel_watch": "watch",
"armed": false,
"down_c": 22.62,
"fan_gates": {
"air_assist": {
"floor": 6093,
"reading": 2710,
"state": "idle"
},
"exhaust": {
"floor": 6416,
"reading": 0,
"state": "idle"
},
"intake_1": {
"floor": 2277,
"reading": 732,
"state": "idle"
},
"intake_2": {
"floor": 2277,
"reading": 729,
"state": "idle"
},
"purge": {
"floor": 345,
"reading": 629,
"state": "idle"
}
},
"fire_ok": true,
"fire_watch": "armed",
"gates_off": [],
"hold": false,
"limits": {
"air_assist_min_rpm": 6093,
"coolant_critical_c": 38.0,
"coolant_max_c": 33.0,
"coolant_min_c": 5.0,
"coolant_resume_c": 31.0,
"coolant_source": "local",
"exhaust_min_rpm": 6416,
"intake_min_rpm": 2277
},
"phase": "idle",
"quiet_hold": false,
"reason": "",
"report_age_s": 0.4,
"resume_ok": true,
"up_c": 22.69,
"verdict": "OK"
},
{
"accel_watch": "watch",
"armed": false,
"down_c": 22.62,
"fan_gates": {
"air_assist": {
"floor": 6093,
"reading": 2710,
"state": "idle"
},
"exhaust": {
"floor": 6416,
"reading": 0,
"state": "idle"
},
"intake_1": {
"floor": 2277,
"reading": 732,
"state": "idle"
},
"intake_2": {
"floor": 2277,
"reading": 729,
"state": "idle"
},
"purge": {
"floor": 345,
"reading": 629,
"state": "idle"
}
},
"fire_ok": true,
"fire_watch": "armed",
"gates_off": [],
"hold": false,
"limits": {
"air_assist_min_rpm": 6093,
"coolant_critical_c": 38.0,
"coolant_max_c": 33.0,
"coolant_min_c": 5.0,
"coolant_resume_c": 31.0,
"coolant_source": "local",
"exhaust_min_rpm": 6416,
"intake_min_rpm": 2277
},
"phase": "idle",
"quiet_hold": false,
"reason": "",
"report_age_s": 0.9,
"resume_ok": true,
"up_c": 22.69,
"verdict": "OK"
},
{
"accel_watch": "watch",
"armed": false,
"down_c": 22.77,
"fan_gates": {
"air_assist": {
"floor": 6093,
"reading": 2748,
"state": "idle"
},
"exhaust": {
"floor": 6416,
"reading": 0,
"state": "idle"
},
"intake_1": {
"floor": 2277,
"reading": 736,
"state": "idle"
},
"intake_2": {
"floor": 2277,
"reading": 729,
"state": "idle"
},
"purge": {
"floor": 345,
"reading": 629,
"state": "idle"
}
},
"fire_ok": true,
"fire_watch": "armed",
"gates_off": [],
"hold": false,
"limits": {
"air_assist_min_rpm": 6093,
"coolant_critical_c": 38.0,
"coolant_max_c": 33.0,
"coolant_min_c": 5.0,
"coolant_resume_c": 31.0,
"coolant_source": "local",
"exhaust_min_rpm": 6416,
"intake_min_rpm": 2277
},
"phase": "idle",
"quiet_hold": false,
"reason": "",
"report_age_s": 0.4,
"resume_ok": true,
"up_c": 22.85,
"verdict": "OK"
},
{
"accel_watch": "watch",
"armed": false,
"down_c": 22.77,
"fan_gates": {
"air_assist": {
"floor": 6093,
"reading": 2748,
"state": "idle"
},
"exhaust": {
"floor": 6416,
"reading": 0,
"state": "idle"
},
"intake_1": {
"floor": 2277,
"reading": 736,
"state": "idle"
},
"intake_2": {
"floor": 2277,
"reading": 729,
"state": "idle"
},
"purge": {
"floor": 345,
"reading": 629,
"state": "idle"
}
},
"fire_ok": true,
"fire_watch": "armed",
"gates_off": [],
"hold": false,
"limits": {
"air_assist_min_rpm": 6093,
"coolant_critical_c": 38.0,
"coolant_max_c": 33.0,
"coolant_min_c": 5.0,
"coolant_resume_c": 31.0,
"coolant_source": "local",
"exhaust_min_rpm": 6416,
"intake_min_rpm": 2277
},
"phase": "idle",
"quiet_hold": false,
"reason": "",
"report_age_s": 0.9,
"resume_ok": true,
"up_c": 22.85,
"verdict": "OK"
},
{
"accel_watch": "watch",
"armed": false,
"down_c": 22.62,
"fan_gates": {
"air_assist": {
"floor": 6093,
"reading": 2761,
"state": "idle"
},
"exhaust": {
"floor": 6416,
"reading": 0,
"state": "idle"
},
"intake_1": {
"floor": 2277,
"reading": 735,
"state": "idle"
},
"intake_2": {
"floor": 2277,
"reading": 734,
"state": "idle"
},
"purge": {
"floor": 345,
"reading": 630,
"state": "idle"
}
},
"fire_ok": true,
"fire_watch": "armed",
"gates_off": [],
"hold": false,
"limits": {
"air_assist_min_rpm": 6093,
"coolant_critical_c": 38.0,
"coolant_max_c": 33.0,
"coolant_min_c": 5.0,
"coolant_resume_c": 31.0,
"coolant_source": "local",
"exhaust_min_rpm": 6416,
"intake_min_rpm": 2277
},
"phase": "idle",
"quiet_hold": false,
"reason": "",
"report_age_s": 0.4,
"resume_ok": true,
"up_c": 22.77,
"verdict": "OK"
},
{
"accel_watch": "watch",
"armed": false,
"down_c": 22.62,
"fan_gates": {
"air_assist": {
"floor": 6093,
"reading": 2761,
"state": "idle"
},
"exhaust": {
"floor": 6416,
"reading": 0,
"state": "idle"
},
"intake_1": {
"floor": 2277,
"reading": 735,
"state": "idle"
},
"intake_2": {
"floor": 2277,
"reading": 734,
"state": "idle"
},
"purge": {
"floor": 345,
"reading": 630,
"state": "idle"
}
},
"fire_ok": true,
"fire_watch": "armed",
"gates_off": [],
"hold": false,
"limits": {
"air_assist_min_rpm": 6093,
"coolant_critical_c": 38.0,
"coolant_max_c": 33.0,
"coolant_min_c": 5.0,
"coolant_resume_c": 31.0,
"coolant_source": "local",
"exhaust_min_rpm": 6416,
"intake_min_rpm": 2277
},
"phase": "idle",
"quiet_hold": false,
"reason": "",
"report_age_s": 0.9,
"resume_ok": true,
"up_c": 22.77,
"verdict": "OK"
},
{
"accel_watch": "watch",
"armed": false,
"down_c": 22.38,
"fan_gates": {
"air_assist": {
"floor": 6093,
"reading": 2764,
"state": "idle"
},
"exhaust": {
"floor": 6416,
"reading": 0,
"state": "idle"
},
"intake_1": {
"floor": 2277,
"reading": 732,
"state": "idle"
},
"intake_2": {
"floor": 2277,
"reading": 734,
"state": "idle"
},
"purge": {
"floor": 345,
"reading": 630,
"state": "idle"
}
},
"fire_ok": true,
"fire_watch": "armed",
"gates_off": [],
"hold": false,
"limits": {
"air_assist_min_rpm": 6093,
"coolant_critical_c": 38.0,
"coolant_max_c": 33.0,
"coolant_min_c": 5.0,
"coolant_resume_c": 31.0,
"coolant_source": "local",
"exhaust_min_rpm": 6416,
"intake_min_rpm": 2277
},
"phase": "idle",
"quiet_hold": false,
"reason": "",
"report_age_s": 0.4,
"resume_ok": true,
"up_c": 22.77,
"verdict": "OK"
},
{
"accel_watch": "watch",
"armed": false,
"down_c": 22.38,
"fan_gates": {
"air_assist": {
"floor": 6093,
"reading": 2764,
"state": "idle"
},
"exhaust": {
"floor": 6416,
"reading": 0,
"state": "idle"
},
"intake_1": {
"floor": 2277,
"reading": 732,
"state": "idle"
},
"intake_2": {
"floor": 2277,
"reading": 734,
"state": "idle"
},
"purge": {
"floor": 345,
"reading": 630,
"state": "idle"
}
},
"fire_ok": true,
"fire_watch": "armed",
"gates_off": [],
"hold": false,
"limits": {
"air_assist_min_rpm": 6093,
"coolant_critical_c": 38.0,
"coolant_max_c": 33.0,
"coolant_min_c": 5.0,
"coolant_resume_c": 31.0,
"coolant_source": "local",
"exhaust_min_rpm": 6416,
"intake_min_rpm": 2277
},
"phase": "idle",
"quiet_hold": false,
"reason": "",
"report_age_s": 0.4,
"resume_ok": true,
"up_c": 22.77,
"verdict": "OK"
},
{
"accel_watch": "watch",
"armed": false,
"down_c": 22.62,
"fan_gates": {
"air_assist": {
"floor": 6093,
"reading": 2758,
"state": "unjudged"
},
"exhaust": {
"floor": 6416,
"reading": 0,
"state": "unjudged"
},
"intake_1": {
"floor": 2277,
"reading": 732,
"state": "unjudged"
},
"intake_2": {
"floor": 2277,
"reading": 729,
"state": "unjudged"
},
"purge": {
"floor": 345,
"reading": 629,
"state": "grace"
}
},
"fire_ok": true,
"fire_watch": "armed",
"gates_off": [],
"hold": false,
"limits": {
"air_assist_min_rpm": 6093,
"coolant_critical_c": 38.0,
"coolant_max_c": 33.0,
"coolant_min_c": 5.0,
"coolant_resume_c": 31.0,
"coolant_source": "local",
"exhaust_min_rpm": 6416,
"intake_min_rpm": 2277
},
"phase": "run",
"quiet_hold": false,
"reason": "",
"report_age_s": 0.4,
"resume_ok": true,
"up_c": 22.77,
"verdict": "OK"
},
{
"accel_watch": "watch",
"armed": false,
"down_c": 22.77,
"fan_gates": {
"air_assist": {
"floor": 6093,
"reading": 2771,
"state": "unjudged"
},
"exhaust": {
"floor": 6416,
"reading": 0,
"state": "unjudged"
},
"intake_1": {
"floor": 2277,
"reading": 735,
"state": "unjudged"
},
"intake_2": {
"floor": 2277,
"reading": 729,
"state": "unjudged"
},
"purge": {
"floor": 345,
"reading": 629,
"state": "grace"
}
},
"fire_ok": true,
"fire_watch": "armed",
"gates_off": [],
"hold": false,
"limits": {
"air_assist_min_rpm": 6093,
"coolant_critical_c": 38.0,
"coolant_max_c": 33.0,
"coolant_min_c": 5.0,
"coolant_resume_c": 31.0,
"coolant_source": "local",
"exhaust_min_rpm": 6416,
"intake_min_rpm": 2277
},
"phase": "run",
"quiet_hold": false,
"reason": "",
"report_age_s": 0.9,
"resume_ok": true,
"up_c": 22.69,
"verdict": "OK"
},
{
"accel_watch": "watch",
"armed": false,
"down_c": 22.77,
"fan_gates": {
"air_assist": {
"floor": 6093,
"reading": 2771,
"state": "unjudged"
},
"exhaust": {
"floor": 6416,
"reading": 0,
"state": "unjudged"
},
"intake_1": {
"floor": 2277,
"reading": 735,
"state": "unjudged"
},
"intake_2": {
"floor": 2277,
"reading": 729,
"state": "unjudged"
},
"purge": {
"floor": 345,
"reading": 629,
"state": "grace"
}
},
"fire_ok": true,
"fire_watch": "armed",
"gates_off": [],
"hold": false,
"limits": {
"air_assist_min_rpm": 6093,
"coolant_critical_c": 38.0,
"coolant_max_c": 33.0,
"coolant_min_c": 5.0,
"coolant_resume_c": 31.0,
"coolant_source": "local",
"exhaust_min_rpm": 6416,
"intake_min_rpm": 2277
},
"phase": "run",
"quiet_hold": false,
"reason": "",
"report_age_s": 0.3,
"resume_ok": true,
"up_c": 22.69,
"verdict": "OK"
},
{
"accel_watch": "watch",
"armed": false,
"down_c": 23.79,
"fan_gates": {
"air_assist": {
"floor": 6093,
"reading": 2479,
"state": "idle"
},
"exhaust": {
"floor": 6416,
"reading": 0,
"state": "idle"
},
"intake_1": {
"floor": 2277,
"reading": 735,
"state": "idle"
},
"intake_2": {
"floor": 2277,
"reading": 729,
"state": "idle"
},
"purge": {
"floor": 345,
"reading": 629,
"state": "idle"
}
},
"fire_ok": true,
"fire_watch": "armed",
"gates_off": [],
"hold": false,
"limits": {
"air_assist_min_rpm": 6093,
"coolant_critical_c": 38.0,
"coolant_max_c": 33.0,
"coolant_min_c": 5.0,
"coolant_resume_c": 31.0,
"coolant_source": "local",
"exhaust_min_rpm": 6416,
"intake_min_rpm": 2277
},
"phase": "idle",
"quiet_hold": false,
"reason": "",
"report_age_s": 0.8,
"resume_ok": true,
"up_c": 24.02,
"verdict": "OK"
},
{
"accel_watch": "watch",
"armed": false,
"down_c": 23.79,
"fan_gates": {
"air_assist": {
"floor": 6093,
"reading": 2479,
"state": "idle"
},
"exhaust": {
"floor": 6416,
"reading": 0,
"state": "idle"
},
"intake_1": {
"floor": 2277,
"reading": 735,
"state": "idle"
},
"intake_2": {
"floor": 2277,
"reading": 729,
"state": "idle"
},
"purge": {
"floor": 345,
"reading": 629,
"state": "idle"
}
},
"fire_ok": true,
"fire_watch": "armed",
"gates_off": [],
"hold": false,
"limits": {
"air_assist_min_rpm": 6093,
"coolant_critical_c": 38.0,
"coolant_max_c": 33.0,
"coolant_min_c": 5.0,
"coolant_resume_c": 31.0,
"coolant_source": "local",
"exhaust_min_rpm": 6416,
"intake_min_rpm": 2277
},
"phase": "idle",
"quiet_hold": false,
"reason": "",
"report_age_s": 0.4,
"resume_ok": true,
"up_c": 24.02,
"verdict": "OK"
}
],
"hunt_line": "INFO basemachine:_finish_action hunt [1589699892]: finished with event \":completed\"",
"lens_homed": true,
"lid_lamp": {
"after_cloud": "236",
"before": "236"
},
"mode": {
"detail": "already in grbl mode",
"found": "grbl",
"needs": "grbl",
"ok": true,
"switched": false
},
"mode_after": {
"controller": "running",
"gated": false,
"local": false,
"mode": "grbl",
"motion": "verified",
"pid": 9527,
"why": ""
},
"mode_before": {
"controller": "running",
"gated": false,
"local": false,
"mode": "grbl",
"motion": "verified",
"pid": 9001,
"why": ""
},
"mode_cloud": {
"controller": "running",
"gated": false,
"local": false,
"mode": "cloud",
"motion": "verified",
"pid": 9042,
"why": ""
},
"motions_after_lid_close": 4,
"refusals_before_hunt_end": 0,
"return": {
"counters_across_jog": [
[
0,
0,
0
],
[
4996,
-2900,
0
]
],
"counters_since_home": [
0,
0,
0
],
"mm": [
-23.419,
13.594
],
"session_travel_steps": [
-1249,
725
]
},
"session": [
"2026-09-28T16:42:39.338607+00:00 gfcloud[9042] INFO authentication:authenticate_machine SUCCESS",
"2026-09-28T16:42:40.481974+00:00 gfcloud[9042] INFO websocket:ws_connect ESTABLISHED"
],
"short_motions": []
},
"fingerprint": "4528f9706bcf89e9151406a49c169ec84882296d0ceef32cb4a258c58e05f710",
"image": "20260928153805 (dev)",
"log": [
"16:42:35 start cloud.mode-switch (operator, api) in campaign c-20260928162331-3969",
"16:42:36 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:42:36 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"16:42:36 fixture: running unattended (no prompt can be answered)",
"16:42:36 queued by the unattended queue opened 2026-09-28T16:23:31Z",
"16:42:36 baseline: pre: clean",
"16:42:36 mode: test needs grbl - already in grbl mode",
"16:42:36 mode before: {'mode': 'grbl', 'controller': 'running', 'pid': 9001, 'motion': 'verified', 'gated': False, 'local': False, 'why': ''}",
"16:42:40 POST /mode controller=cloud -> 200 {'mode': 'cloud', 'controller': 'running', 'pid': 9042, 'motion': 'verified', 'gated': False, 'local': False, 'why': ''}",
"16:42:40 mode after switch: {'mode': 'cloud', 'controller': 'running', 'pid': 9042, 'motion': 'verified', 'gated': False, 'local': False, 'why': ''}",
"16:42:40 ACT lid open (fixture)",
"16:42:40 ACT lid open: done after 0.0 s",
"16:42:42 gfcloud: gfcloud[9042] INFO authentication:authenticate_machine SUCCESS",
"16:42:42 gfcloud: gfcloud[9042] INFO websocket:ws_connect ESTABLISHED",
"16:42:42 cloud session established: True; firmware probe: {'latest_gf_version': '2.6.0-2228', 'tested_against_gf': '2.6.0-2228', 'checked_at': 1790613759}",
"16:42:49 hunt: 15 status samples, 3 in phase run; verdicts ['OK']",
"16:42:49 hunt with the lid open: INFO basemachine:_finish_action hunt [1589699892]: finished with event \":completed\" (lens homed)",
"16:42:49 ACT lid close (fixture)",
"16:42:50 ACT lid close: done after 0.3 s",
"16:43:06 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:43:37 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:43:56 cloud mode stays up; the machine is quiet",
"16:43:56 4 service motion(s) completed after the lid closed",
"16:43:58 POST /mode controller=grbl -> 200 {'mode': 'grbl', 'controller': 'running', 'pid': 9527, 'motion': 'verified', 'gated': False, 'local': False, 'why': ''}",
"16:43:58 mode after switch back: {'mode': 'grbl', 'controller': 'running', 'pid': 9527, 'motion': 'verified', 'gated': False, 'local': False, 'why': ''}",
"16:44:01 grbl state after: Idle",
"16:44:01 the head is -23.419/13.556 mm from where the test found it",
"16:44:02 connect: Idle",
"16:44:04 position counters re-zeroed at the starting position; the baseline expects (0,0,0) at the end",
"16:44:04 head returned to where the test found it (23.419/-13.556 mm)",
"16:44:04 homing_mode=gfcloud for the homing -> 200 ",
"16:44:07 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:44:38 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:45:08 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"16:45:19 homing: homed=True after 74.5 s (kernel idle, grbl Idle)",
"16:45:19 gfhome: 2026-09-28T16:45:10.995648+00:00 gfhome[9572] INFO gfhome:home homing complete (service quiet 10s, 4 motion windows)",
"16:45:19 position counters re-zeroed at the starting position; the baseline expects (0,0,0) at the end",
"16:45:19 $H acknowledged: [MSG:] | ok",
"16:45:19 restore homing_mode='manual' -> 200",
"16:45:21 the head is -23.419/13.594 mm from where the test found it",
"16:45:21 connect: Idle",
"16:45:24 position counters re-zeroed at the starting position; the baseline expects (0,0,0) at the end",
"16:45:24 head returned to where the test found it (23.419/-13.594 mm)",
"16:45:24 PASS: grbl -> cloud (session, hunt with the lid open, lens homed, airflow unjudged) -> grbl (port open, Idle), then $H homed in 74.5 s",
"16:45:24 baseline: post: clean",
"16:45:24 result PASS"
],
"manifest_sha": "faf9563c750bb8bd4bfc8778b6af053cddb63fa335ab946caf2f71631ede740f",
"message": "",
"result": "PASS",
"test": "cloud.mode-switch",
"ts": "2026-09-28T16:45:24Z"
},
"requires": [
"forgectrl.auth",
"motion.pacing"
],
"satisfied": true,
"source_sha": "a0ae6878a674e8b66d080ec64b7d02824d2000e07f1d2ba4108d2c0dbfd36aef",
"subsystem": "cloud",
"title": "Controller mode switch grbl -> cloud -> grbl, the connect-time hunt with the lid open, and the web-service homing"
},
{
"always": false,
"covers": [
[
"forgefirm-app",
"forgefirm-app/gfcloud.py"
],
[
"forgefirm-app",
"forgefirm-app/ffmachine.py"
],
[
"forgefirm-app",
"forgefirm-app/gfhome.conf.sample"
],
[
"python3-gfhardware",
"gfhardware/__init__.py"
],
[
"python3-gfhardware",
"gfhardware/_common.py"
],
[
"python3-gfhardware",
"gfhardware/id.py"
],
[
"python3-gfhardware",
"gfhardware/coolsvc.py"
],
[
"python3-gfutilities",
"gfutilities/__init__.py"
],
[
"python3-gfutilities",
"gfutilities/_common.py"
],
[
"python3-gfutilities",
"gfutilities/configuration.py"
],
[
"python3-gfutilities",
"gfutilities/device/__init__.py"
],
[
"python3-gfutilities",
"gfutilities/device/basemachine.py"
],
[
"python3-gfutilities",
"gfutilities/device/settings.py"
],
[
"python3-gfutilities",
"gfutilities/service/__init__.py"
],
[
"python3-gfutilities",
"gfutilities/service/dispatch.py"
],
[
"python3-gfutilities",
"gfutilities/service/websocket.py"
],
[
"python3-gfutilities",
"gfutilities/service/authentication.py"
],
[
"python3-gfutilities",
"gfutilities/service/gfuiservice.py"
],
[
"python3-gfutilities",
"gfutilities/device/emulator.py"
],
[
"python3-gfutilities",
"examples/**"
],
[
"forgectrl",
"src/super.c"
],
[
"forgectrl",
"src/main.c"
]
],
"fingerprint": "c9284653900bef2ef738f0a064090c318936f46a8c81dd72f8d2ff231ad5b01b",
"hardware": "api",
"id": "cloud.service-protocol",
"inherited": true,
"kind": "operator",
"record": {
"answers": [
{
"answer": "Yes",
"question": "Does the app show the print complete?",
"ts": "2026-09-28T19:16:04Z"
}
],
"campaign": "c-20260928183105-64ee",
"duration_s": 115,
"evidence": {
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "attended",
"ts": "2026-09-28T18:51:04Z"
},
"downloads": [
"2026-09-28_191531_hunt.info",
"2026-09-28_191540_motion.info",
"2026-09-28_191550_motion.info",
"2026-09-28_191554_motion.info",
"2026-09-28_191558_print.info"
],
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"header_stfr": 10000,
"header_tags": 134,
"hunt": "INFO basemachine:_finish_action hunt [1589771751]: finished with event \":completed\"",
"images_uploaded": 3,
"print": "INFO basemachine:_finish_action print [1589771989]: finished with event \":completed\"",
"pulse": "INFO websocket:fetch_motion pulse data is gzip-compressed, 405 byte body"
},
"fingerprint": "c9284653900bef2ef738f0a064090c318936f46a8c81dd72f8d2ff231ad5b01b",
"image": "20260928182434 (dev)",
"log": [
"19:15:24 start cloud.service-protocol (operator, api) in campaign c-20260928183105-64ee",
"19:15:24 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"19:15:24 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"19:15:24 queued by the attended queue opened 2026-09-28T18:51:04Z",
"19:15:24 baseline: pre: clean",
"19:15:24 grbl mode: switching to cloud as the emulator",
"19:15:27 controller mode changed to cloud for the operator; the baseline keeps it",
"19:15:30 emulator session established: gfcloud[13941] INFO authentication:authenticate_machine SUCCESS; gfcloud[13941] INFO websocket:ws_connect ESTABLISHED",
"19:15:37 NOTICE: In the app the machine shows Ready (its bed image is the emulator's canned frame). Set up any small job and press Print. Nothing moves here; the test watches the service's print reach the emulator and complete.",
"19:15:55 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"19:16:00 print: INFO basemachine:_finish_action print [1589771989]: finished with event \":completed\"; 3 images uploaded; INFO websocket:fetch_motion pulse data is gzip-compressed, 405 byte body",
"19:16:00 the job's header: 134 tags, STfr 10000",
"19:16:00 PROMPT: Does the app show the print complete?",
"19:16:04 ANSWER: Yes",
"19:16:04 PASS: session, hunt, 3 image upload(s), a print downloaded (134-tag header) and completed, all against the real service with no hardware behind it",
"19:16:04 cloud mode: restarting the client with the machine, no hunt (was pid 13941)",
"19:16:26 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"19:16:56 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"19:17:19 the machine is back under the real client, no hunt",
"19:17:20 baseline: post: clean",
"19:17:20 result PASS"
],
"manifest_sha": "84a155bfc701e865ae73f9818bc38c2d005324ab5ba0ed44b668ec8896179947",
"message": "",
"result": "PASS",
"test": "cloud.service-protocol",
"ts": "2026-09-28T19:17:20Z"
},
"requires": [
"forgectrl.auth"
],
"satisfied": true,
"source_sha": "efb1459cc8c89c8ed580f5cea85f935071e69808cb81df7d55c78a06a26de104",
"subsystem": "cloud",
"title": "The service protocol, answered by the emulator in this machine's identity"
},
{
"always": false,
"covers": [
[
"forgefirm-app",
"forgefirm-app/gfcloud.py"
],
[
"forgefirm-app",
"forgefirm-app/ffmachine.py"
],
[
"forgefirm-app",
"forgefirm-app/gfhome.conf.sample"
],
[
"python3-gfhardware",
"gfhardware/__init__.py"
],
[
"python3-gfhardware",
"gfhardware/_common.py"
],
[
"python3-gfhardware",
"gfhardware/id.py"
],
[
"python3-gfhardware",
"gfhardware/coolsvc.py"
],
[
"python3-gfutilities",
"gfutilities/__init__.py"
],
[
"python3-gfutilities",
"gfutilities/_common.py"
],
[
"python3-gfutilities",
"gfutilities/configuration.py"
],
[
"python3-gfutilities",
"gfutilities/device/__init__.py"
],
[
"python3-gfutilities",
"gfutilities/device/basemachine.py"
],
[
"python3-gfutilities",
"gfutilities/device/settings.py"
],
[
"python3-gfutilities",
"gfutilities/service/__init__.py"
],
[
"python3-gfutilities",
"gfutilities/service/dispatch.py"
],
[
"python3-gfutilities",
"gfutilities/service/websocket.py"
],
[
"python3-gfhardware",
"gfhardware/machine.py"
],
[
"python3-gfhardware",
"gfhardware/feeder.py"
],
[
"python3-gfhardware",
"gfhardware/cnc.py"
],
[
"python3-gfhardware",
"gfhardware/switches.py"
],
[
"python3-gfhardware",
"gfhardware/input/**"
],
[
"python3-gfhardware",
"gfhardware/src/evdev.c"
],
[
"python3-gfhardware",
"gfhardware/z_axis.py"
],
[
"python3-gfhardware",
"gfhardware/leds.py"
],
[
"python3-gfhardware",
"gfhardware/cooling.py"
],
[
"python3-gfutilities",
"gfutilities/service/offline.py"
],
[
"python3-gfutilities",
"gfutilities/puls/**"
],
[
"forgectrl",
"src/super.c"
],
[
"forgectrl",
"src/main.c"
]
],
"fingerprint": "34e4818cea1497348953fe223165bfe76ab78ee892f5f88286d56001bc2f6490",
"hardware": "api",
"id": "cloud.lid-interlock-abort",
"inherited": true,
"kind": "live",
"record": {
"answers": [],
"campaign": "c-20260928183105-64ee",
"duration_s": 135,
"evidence": {
"actions": [
{
"by": "fixture",
"channel": "button",
"state": "press",
"took_s": 6.03,
"ts": "2026-09-28T19:17:56Z"
},
{
"by": "fixture",
"channel": "lid",
"state": "open",
"took_s": 0.02,
"ts": "2026-09-28T19:18:02Z"
},
{
"by": "fixture",
"channel": "lid",
"state": "close",
"took_s": 0.28,
"ts": "2026-09-28T19:18:14Z"
},
{
"by": "fixture",
"channel": "button",
"state": "press",
"took_s": 6.02,
"ts": "2026-09-28T19:18:46Z"
},
{
"by": "fixture",
"channel": "interlock",
"state": "open",
"took_s": 0.02,
"ts": "2026-09-28T19:18:53Z"
},
{
"by": "fixture",
"channel": "lid",
"state": "open",
"took_s": 0.02,
"ts": "2026-09-28T19:18:54Z"
},
{
"by": "fixture",
"channel": "lid",
"state": "close",
"took_s": 0.02,
"ts": "2026-09-28T19:19:05Z"
},
{
"by": "fixture",
"channel": "interlock",
"state": "close",
"took_s": 0.28,
"ts": "2026-09-28T19:19:05Z"
}
],
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "attended",
"ts": "2026-09-28T18:51:04Z"
},
"edge_to_stop_ms": 7.0,
"events_print1": [
"print:starting",
"print:download:completed",
"button:pressed",
"print:warmup:starting",
"button:released",
"print:running",
"lid:opened",
"print:return_to_home:succeeded",
"print:cancelled",
"lid:closed"
],
"events_print2": [
"print:starting",
"print:download:completed",
"button:pressed",
"print:warmup:starting",
"button:released",
"print:running",
"lid:opened",
"print:return_to_home:succeeded",
"print:cancelled",
"lid:closed",
"print:starting",
"print:download:completed",
"button:pressed",
"print:warmup:starting",
"button:released",
"print:running",
"print:return_to_home:succeeded",
"lid:opened",
"print:cancelled",
"lid:closed"
],
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"interlock_armed_after": false,
"interlock_counters_after_park": [
0,
0,
0
],
"interlock_latch_locked": true,
"interlock_log": {
"interlock opened mid-run; stopping motion": "WARNING machine:_run_loop interlock opened mid-run; stopping motion",
"print finished": "INFO basemachine:_finish_action print [9002]: finished with event \":cancelled\"",
"return home complete": "INFO machine:_return_home return home complete",
"start return home": "INFO machine:_return_home start return home"
},
"interlock_ok_after_pull": false,
"jobs": {
"abort.puls": {
"compressed": false,
"payload_bytes": 486344,
"seconds": 48.6
}
},
"lid_armed_after": false,
"lid_counters_after_park": [
0,
0,
0
],
"lid_latch_locked": true,
"lid_log": {
"lid opened": "INFO machine:_switch_event lid opened",
"lid opened mid-run; stopping motion": "WARNING machine:_run_loop lid opened mid-run; stopping motion",
"print finished": "INFO basemachine:_finish_action print [9001]: finished with event \":cancelled\"",
"return home complete": "INFO machine:_return_home return home complete",
"start return home": "INFO machine:_return_home start return home"
},
"operator": {
"ack_live": true,
"ts": "2026-09-28T19:17:20Z"
},
"restored": {
"interlock_ok": true,
"lid": true
},
"switches_at_return": {
"interlock_ok": false,
"lid": false
}
},
"fingerprint": "34e4818cea1497348953fe223165bfe76ab78ee892f5f88286d56001bc2f6490",
"image": "20260928182434 (dev)",
"log": [
"19:17:20 start cloud.lid-interlock-abort (live, api) in campaign c-20260928183105-64ee",
"19:17:20 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"19:17:20 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"19:17:20 queued by the attended queue opened 2026-09-28T18:51:04Z",
"19:17:20 baseline: pre: clean",
"19:17:20 cloud mode: restarting the client offline (was pid 14111)",
"19:17:24 offline service up: INFO offline:open OFFLINE service: no web session; listening on /run/gfcloud-offline.sock",
"19:17:51 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"19:17:55 job abort.puls: 486344 payload bytes, 49 s at STfr 10000",
"19:17:56 ACT button press (fixture)",
"19:18:02 ACT button press: done after 6.0 s",
"19:18:02 ACT lid open (fixture)",
"19:18:02 ACT lid open: done after 0.0 s",
"19:18:14 [lid] lid opened: seen",
"19:18:14 [lid] lid opened mid-run; stopping motion: seen",
"19:18:14 [lid] start return home: seen",
"19:18:14 [lid] return home complete: seen",
"19:18:14 [lid] print finished: seen",
"19:18:14 lid edge -> stop: 7.0 ms",
"19:18:14 [lid] kernel counters after the park: [0, 0, 0]",
"19:18:14 ACT lid close (fixture)",
"19:18:15 ACT lid close: done after 0.3 s",
"19:18:21 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"19:18:45 cloud mode stays up; the machine is quiet",
"19:18:46 ACT button press (fixture)",
"19:18:52 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"19:18:53 ACT button press: done after 6.0 s",
"19:18:53 ACT interlock open (fixture)",
"19:18:53 ACT interlock open: done after 0.0 s",
"19:18:54 ACT lid open (fixture)",
"19:18:54 ACT lid open: done after 0.0 s",
"19:19:05 [interlock] interlock opened mid-run; stopping motion: seen",
"19:19:05 [interlock] start return home: seen",
"19:19:05 [interlock] return home complete: seen",
"19:19:05 [interlock] print finished: seen",
"19:19:05 [interlock] kernel counters after the park: [0, 0, 0]",
"19:19:05 ACT lid close (fixture)",
"19:19:05 ACT lid close: done after 0.0 s",
"19:19:05 ACT interlock close (fixture)",
"19:19:05 ACT interlock close: done after 0.3 s",
"19:19:23 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"19:19:35 cloud mode stays up; the machine is quiet",
"19:19:35 PASS: lid open -> stop in 7.0 ms and park with the lid open; interlock open -> the same tail with the park running through a lid edge; both prints ':cancelled'",
"19:19:35 offline jobs removed from /tmp/forgetest",
"19:19:36 baseline: post: clean",
"19:19:36 result PASS"
],
"manifest_sha": "84a155bfc701e865ae73f9818bc38c2d005324ab5ba0ed44b668ec8896179947",
"message": "",
"result": "PASS",
"test": "cloud.lid-interlock-abort",
"ts": "2026-09-28T19:19:36Z"
},
"requires": [
"laser.emission-witness"
],
"satisfied": true,
"source_sha": "2d781af68a711b206184ae692bc24740c9e4a91f207a9b3cedcbe9b5a4ab1de3",
"subsystem": "cloud",
"title": "Lid and interlock each abort a cloud print; the park ignores an open lid"
},
{
"always": false,
"covers": [
[
"forgefirm-app",
"forgefirm-app/gfcloud.py"
],
[
"forgefirm-app",
"forgefirm-app/ffmachine.py"
],
[
"forgefirm-app",
"forgefirm-app/gfhome.conf.sample"
],
[
"python3-gfhardware",
"gfhardware/__init__.py"
],
[
"python3-gfhardware",
"gfhardware/_common.py"
],
[
"python3-gfhardware",
"gfhardware/id.py"
],
[
"python3-gfhardware",
"gfhardware/coolsvc.py"
],
[
"python3-gfutilities",
"gfutilities/__init__.py"
],
[
"python3-gfutilities",
"gfutilities/_common.py"
],
[
"python3-gfutilities",
"gfutilities/configuration.py"
],
[
"python3-gfutilities",
"gfutilities/device/__init__.py"
],
[
"python3-gfutilities",
"gfutilities/device/basemachine.py"
],
[
"python3-gfutilities",
"gfutilities/device/settings.py"
],
[
"python3-gfutilities",
"gfutilities/service/__init__.py"
],
[
"python3-gfutilities",
"gfutilities/service/dispatch.py"
],
[
"python3-gfutilities",
"gfutilities/service/websocket.py"
],
[
"python3-gfhardware",
"gfhardware/machine.py"
],
[
"python3-gfhardware",
"gfhardware/feeder.py"
],
[
"python3-gfhardware",
"gfhardware/cnc.py"
],
[
"python3-gfhardware",
"gfhardware/switches.py"
],
[
"python3-gfhardware",
"gfhardware/input/**"
],
[
"python3-gfhardware",
"gfhardware/src/evdev.c"
],
[
"python3-gfhardware",
"gfhardware/z_axis.py"
],
[
"python3-gfhardware",
"gfhardware/leds.py"
],
[
"python3-gfhardware",
"gfhardware/cooling.py"
],
[
"python3-gfutilities",
"gfutilities/service/offline.py"
],
[
"python3-gfutilities",
"gfutilities/puls/**"
],
[
"forgectrl",
"src/super.c"
],
[
"forgectrl",
"src/main.c"
]
],
"fingerprint": "2c87f10029a7a206e81831a7ef99134b83cba728dc3e975c5aaf35be66d208f5",
"hardware": "api",
"id": "cloud.lid-during-button-wait",
"inherited": true,
"kind": "operator",
"record": {
"answers": [],
"campaign": "c-20260928171100-3ff5",
"duration_s": 83,
"evidence": {
"actions": [
{
"by": "fixture",
"channel": "lid",
"state": "open",
"took_s": 0.03,
"ts": "2026-09-28T17:21:00Z"
},
{
"by": "fixture",
"channel": "lid",
"state": "close",
"took_s": 0.28,
"ts": "2026-09-28T17:21:13Z"
}
],
"armed_after": false,
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T17:11:00Z"
},
"button_dark": false,
"events": [
"print:starting",
"print:download:completed",
"lid:opened",
"print:return_to_home:succeeded",
"print:cancelled",
"lid:closed"
],
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"jobs": {
"wait.puls": {
"compressed": true,
"payload_bytes": 35015348,
"seconds": 3501.5
}
},
"latch_locked": true,
"log": {
"button wait lid opened - relocking the laser": true,
"print finished": "INFO basemachine:_finish_action print [9003]: finished with event \":cancelled\""
},
"program_total_after": {
"first": 0,
"later": 0
},
"runs_started_after_wait": 0,
"streaming_after": 0
},
"fingerprint": "2c87f10029a7a206e81831a7ef99134b83cba728dc3e975c5aaf35be66d208f5",
"image": "20260928170058 (dev)",
"log": [
"17:20:21 start cloud.lid-during-button-wait (operator, api) in campaign c-20260928171100-3ff5",
"17:20:21 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"17:20:21 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"17:20:21 fixture: running unattended (no prompt can be answered)",
"17:20:21 queued by the unattended queue opened 2026-09-28T17:11:00Z",
"17:20:21 baseline: pre: clean",
"17:20:21 grbl mode: switching to cloud offline",
"17:20:24 controller mode changed to cloud for the operator; the baseline keeps it",
"17:20:25 offline service up: INFO offline:open OFFLINE service: no web session; listening on /run/gfcloud-offline.sock",
"17:20:53 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"17:20:58 job wait.puls: 35015348 payload bytes, 3502 s at STfr 10000 (gzip)",
"17:21:00 ACT lid open (fixture)",
"17:21:00 ACT lid open: done after 0.0 s",
"17:21:13 ACT lid close (fixture)",
"17:21:14 ACT lid close: done after 0.3 s",
"17:21:25 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"17:21:44 cloud mode stays up; the machine is quiet",
"17:21:44 PASS: lid open at the button prompt canceled the print; latch locked, armed=false, button dark, ring empty with the feed stopped",
"17:21:44 offline jobs removed from /tmp/forgetest",
"17:21:44 baseline: post: clean",
"17:21:44 result PASS"
],
"manifest_sha": "98f8c4dad7130ecf1fa44e5e0f1a1b53e6b9359f005f22a1ddbee496375d9a9e",
"message": "",
"result": "PASS",
"test": "cloud.lid-during-button-wait",
"ts": "2026-09-28T17:21:44Z"
},
"requires": [],
"satisfied": true,
"source_sha": "cfeec62454efff19a4bd7be5e5a78b8ed99da9f75562890101c3b4486ae46b21",
"subsystem": "cloud",
"title": "Lid open at the cloud button prompt cancels the print"
},
{
"always": false,
"covers": [
[
"forgefirm-app",
"forgefirm-app/gfcloud.py"
],
[
"forgefirm-app",
"forgefirm-app/ffmachine.py"
],
[
"forgefirm-app",
"forgefirm-app/gfhome.conf.sample"
],
[
"python3-gfhardware",
"gfhardware/__init__.py"
],
[
"python3-gfhardware",
"gfhardware/_common.py"
],
[
"python3-gfhardware",
"gfhardware/id.py"
],
[
"python3-gfhardware",
"gfhardware/coolsvc.py"
],
[
"python3-gfutilities",
"gfutilities/__init__.py"
],
[
"python3-gfutilities",
"gfutilities/_common.py"
],
[
"python3-gfutilities",
"gfutilities/configuration.py"
],
[
"python3-gfutilities",
"gfutilities/device/__init__.py"
],
[
"python3-gfutilities",
"gfutilities/device/basemachine.py"
],
[
"python3-gfutilities",
"gfutilities/device/settings.py"
],
[
"python3-gfutilities",
"gfutilities/service/__init__.py"
],
[
"python3-gfutilities",
"gfutilities/service/dispatch.py"
],
[
"python3-gfutilities",
"gfutilities/service/websocket.py"
],
[
"python3-gfhardware",
"gfhardware/machine.py"
],
[
"python3-gfhardware",
"gfhardware/feeder.py"
],
[
"python3-gfhardware",
"gfhardware/cnc.py"
],
[
"python3-gfhardware",
"gfhardware/switches.py"
],
[
"python3-gfhardware",
"gfhardware/input/**"
],
[
"python3-gfhardware",
"gfhardware/src/evdev.c"
],
[
"python3-gfhardware",
"gfhardware/z_axis.py"
],
[
"python3-gfhardware",
"gfhardware/leds.py"
],
[
"python3-gfhardware",
"gfhardware/cooling.py"
],
[
"python3-gfutilities",
"gfutilities/service/offline.py"
],
[
"python3-gfutilities",
"gfutilities/puls/**"
],
[
"forgectrl",
"src/super.c"
],
[
"forgectrl",
"src/main.c"
],
[
"python3-gfhardware",
"gfhardware/coolsvc.py"
],
[
"forgectrl",
"src/cool.*"
],
[
"forgectrl",
"src/main.c"
]
],
"fingerprint": "c9a6452b5c5c0e6ce8c810bbbdf8e93d9bcb2b70bb7f5e98082eac696d2c8954",
"hardware": "api",
"id": "cloud.dark-print",
"inherited": true,
"kind": "operator",
"record": {
"answers": [],
"campaign": "c-20260928171100-3ff5",
"duration_s": 56,
"evidence": {
"actions": [
{
"by": "fixture",
"channel": "button",
"state": "press",
"took_s": 5.26,
"ts": "2026-09-28T17:21:46Z"
}
],
"armed_after": false,
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T17:11:00Z"
},
"events": [
"print:starting",
"print:download:completed",
"button:pressed",
"print:warmup:starting",
"button:released",
"print:running",
"print:return_to_home:succeeded",
"print:completed"
],
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"jobs": {
"dark.puls": {
"compressed": false,
"payload_bytes": 324236,
"seconds": 32.4
}
},
"latch_locked_after": true,
"latch_locked_at_button": true,
"latch_locked_in_run": false,
"print finished": "INFO basemachine:_finish_action print [9005]: finished with event \":completed\""
},
"fingerprint": "c9a6452b5c5c0e6ce8c810bbbdf8e93d9bcb2b70bb7f5e98082eac696d2c8954",
"image": "20260928170058 (dev)",
"log": [
"17:21:44 start cloud.dark-print (operator, api) in campaign c-20260928171100-3ff5",
"17:21:44 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"17:21:44 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"17:21:44 fixture: running unattended (no prompt can be answered)",
"17:21:44 queued by the unattended queue opened 2026-09-28T17:11:00Z",
"17:21:45 baseline: pre: clean",
"17:21:45 the offline service is already up (pid 4807) - reusing it",
"17:21:45 job dark.puls: 324236 payload bytes, 32 s at STfr 10000",
"17:21:46 ACT button press (fixture)",
"17:21:51 ACT button press: done after 5.3 s",
"17:22:15 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"17:22:34 PASS: locked at the button, unlocked for the run, locked after it; the print completed",
"17:22:34 offline jobs removed from /tmp/forgetest",
"17:22:40 baseline: cool: smoke/armed=False/hold=False ended on its own after 6 s; the engine's own post-job work, not a leftover",
"17:22:40 baseline: post: clean",
"17:22:40 result PASS"
],
"manifest_sha": "98f8c4dad7130ecf1fa44e5e0f1a1b53e6b9359f005f22a1ddbee496375d9a9e",
"message": "",
"result": "PASS",
"test": "cloud.dark-print",
"ts": "2026-09-28T17:22:40Z"
},
"requires": [
"cloud.lid-during-button-wait",
"cooling.floor-and-warm-up"
],
"satisfied": true,
"source_sha": "4161795335a5bde458753f15a7f9056e2b736df4a0d494237563f336ddbf3c8c",
"subsystem": "cloud",
"title": "A dark cloud print: the latch locked until the run, unlocked for it, locked after it"
},
{
"always": false,
"covers": [
[
"forgefirm-app",
"forgefirm-app/gfcloud.py"
],
[
"forgefirm-app",
"forgefirm-app/ffmachine.py"
],
[
"forgefirm-app",
"forgefirm-app/gfhome.conf.sample"
],
[
"python3-gfhardware",
"gfhardware/__init__.py"
],
[
"python3-gfhardware",
"gfhardware/_common.py"
],
[
"python3-gfhardware",
"gfhardware/id.py"
],
[
"python3-gfhardware",
"gfhardware/coolsvc.py"
],
[
"python3-gfutilities",
"gfutilities/__init__.py"
],
[
"python3-gfutilities",
"gfutilities/_common.py"
],
[
"python3-gfutilities",
"gfutilities/configuration.py"
],
[
"python3-gfutilities",
"gfutilities/device/__init__.py"
],
[
"python3-gfutilities",
"gfutilities/device/basemachine.py"
],
[
"python3-gfutilities",
"gfutilities/device/settings.py"
],
[
"python3-gfutilities",
"gfutilities/service/__init__.py"
],
[
"python3-gfutilities",
"gfutilities/service/dispatch.py"
],
[
"python3-gfutilities",
"gfutilities/service/websocket.py"
],
[
"python3-gfhardware",
"gfhardware/machine.py"
],
[
"python3-gfhardware",
"gfhardware/feeder.py"
],
[
"python3-gfhardware",
"gfhardware/cnc.py"
],
[
"python3-gfhardware",
"gfhardware/switches.py"
],
[
"python3-gfhardware",
"gfhardware/input/**"
],
[
"python3-gfhardware",
"gfhardware/src/evdev.c"
],
[
"python3-gfhardware",
"gfhardware/z_axis.py"
],
[
"python3-gfhardware",
"gfhardware/leds.py"
],
[
"python3-gfhardware",
"gfhardware/cooling.py"
],
[
"python3-gfutilities",
"gfutilities/service/offline.py"
],
[
"python3-gfutilities",
"gfutilities/puls/**"
],
[
"forgectrl",
"src/super.c"
],
[
"forgectrl",
"src/main.c"
],
[
"python3-gfhardware",
"gfhardware/coolsvc.py"
],
[
"forgectrl",
"src/cool.*"
]
],
"fingerprint": "fac4734c4e9ea5dbbee15b4f8fc5113895f7bc4667d6374804b9eb509087fda7",
"hardware": "api",
"id": "cloud.verdict-refuse",
"inherited": true,
"kind": "operator",
"record": {
"answers": [],
"campaign": "c-20260928171100-3ff5",
"duration_s": 81,
"evidence": {
"actions": [
{
"by": "fixture",
"channel": "button",
"state": "press",
"took_s": 4.27,
"ts": "2026-09-28T17:22:43Z"
}
],
"armed_after": false,
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T17:11:00Z"
},
"events": [
"print:starting",
"print:download:completed",
"button:pressed",
"print:warmup:starting",
"button:released",
"print:return_to_home:succeeded",
"print:cancelled"
],
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"gate": 33.1,
"hold_s": 60,
"jobs": {
"refuse.puls": {
"compressed": false,
"payload_bytes": 324236,
"seconds": 32.4
}
},
"latch_locked_at_button": true,
"latch_samples": {
"n": 31,
"unlocked": 0
},
"orig": {
"cloud_hold_max_s": "",
"cool_temp_min": "",
"cool_temp_start": ""
},
"print finished": "INFO basemachine:_finish_action print [9006]: finished with event \":cancelled\""
},
"fingerprint": "fac4734c4e9ea5dbbee15b4f8fc5113895f7bc4667d6374804b9eb509087fda7",
"image": "20260928170058 (dev)",
"log": [
"17:22:40 start cloud.verdict-refuse (operator, api) in campaign c-20260928171100-3ff5",
"17:22:41 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"17:22:41 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"17:22:41 fixture: running unattended (no prompt can be answered)",
"17:22:41 queued by the unattended queue opened 2026-09-28T17:11:00Z",
"17:22:41 baseline: pre: clean",
"17:22:41 the offline service is already up (pid 4807) - reusing it",
"17:22:41 job refuse.puls: 324236 payload bytes, 32 s at STfr 10000",
"17:22:43 ACT button press (fixture)",
"17:22:47 ACT button press: done after 4.3 s",
"17:22:47 NOTICE: The engine holds the print; the client gives up at the bound. Do nothing.",
"17:23:12 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"17:23:43 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"17:23:57 PASS: held 60 s with the latch locked throughout, then canceled at the bound",
"17:23:57 restore: POST /settings {'cool_temp_min': '', 'cool_temp_start': '', 'cloud_hold_max_s': ''} -> 200",
"17:23:57 offline jobs removed from /tmp/forgetest",
"17:24:02 baseline: cool: smoke/armed=False/hold=False ended on its own after 5 s; the engine's own post-job work, not a leftover",
"17:24:02 baseline: post: clean",
"17:24:02 result PASS"
],
"manifest_sha": "98f8c4dad7130ecf1fa44e5e0f1a1b53e6b9359f005f22a1ddbee496375d9a9e",
"message": "",
"result": "PASS",
"test": "cloud.verdict-refuse",
"ts": "2026-09-28T17:24:02Z"
},
"requires": [
"cloud.dark-print"
],
"satisfied": true,
"source_sha": "7b3468b928dfc6d4bc35d57800edda20bc8d62232250efc940eaa3887749eedd",
"subsystem": "cloud",
"title": "A cloud print held by the engine past the bound is canceled with the latch never unlocked"
},
{
"always": false,
"covers": [
[
"forgefirm-app",
"**"
],
[
"python3-gfhardware",
"**"
],
[
"python3-gfutilities",
"**"
],
[
"forgectrl",
"src/super.c"
],
[
"forgectrl",
"src/main.c"
]
],
"fingerprint": "33c6680f7573efc32282b323538bae668c0869c2b22a74c94c1df15efee55f3a",
"hardware": "api",
"id": "cloud.pause-resume",
"inherited": true,
"kind": "live",
"record": {
"answers": [
{
"answer": "Done",
"question": "In the Glowforge app: scrap on the bed, lid closed, a SMALL engrave or score job (about 30 s) set up. Click Done here, then press Print in the app and press the physical button when it lights white.",
"ts": "2026-09-28T19:20:44Z"
},
{
"answer": "Yes",
"question": "In the app: did the print's progress advance while it cut (not standing still, not jumping straight to nearly finished), and does the app show it complete?",
"ts": "2026-09-28T19:21:35Z"
}
],
"campaign": "c-20260928183105-64ee",
"duration_s": 154,
"evidence": {
"actions": [
{
"by": "fixture",
"channel": "button",
"state": "press",
"took_s": 1.26,
"ts": "2026-09-28T19:21:09Z"
},
{
"by": "fixture",
"channel": "button",
"state": "press",
"took_s": 1.26,
"ts": "2026-09-28T19:21:10Z"
}
],
"armed_after_resume": true,
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "attended",
"ts": "2026-09-28T18:51:04Z"
},
"effective_limits": [
"2026-09-28T19:20:55.228884+00:00 forgectrl[5640] INFO cool: effective limits: coolant ceiling 33.0 C (local 33.0, header 50.0) resume 31.0 C; floors coolant 10.0 C (the job's), exhaust 6416 rpm, intak",
"2026-09-28T19:20:56.228885+00:00 forgectrl[5640] INFO cool: effective limits: coolant ceiling 33.0 C (local 33.0, header none 0.0) resume 31.0 C; floors coolant 5.0 C (local), exhaust 6416 rpm, intake"
],
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"header_limits": "air_assist_min_rpm=116 coolant_max_c=33.0 coolant_min_c=5.0",
"holds_before_the_print": [],
"lifecycle": {
"cool down": "2026-09-28T19:21:16.782702+00:00 gfcloud[15232] INFO machine:_dwell cool down: holding 10.0 s",
"warm up": "2026-09-28T19:21:04.597084+00:00 gfcloud[15232] INFO machine:_dwell warm up: holding 3.0 s"
},
"log": {
"button pressed mid-run; pausing": true,
"button pressed while paused": true,
"paused at": true,
"resuming (laser lead": true
},
"log_end": {
"print finished": "INFO basemachine:_finish_action print [1589774241]: finished with event \":completed\"",
"return home complete": true
},
"operator": {
"ack_live": true,
"ts": "2026-09-28T19:19:36Z"
},
"progress_total": 44986,
"relock_or_cancel_lines": 0
},
"fingerprint": "33c6680f7573efc32282b323538bae668c0869c2b22a74c94c1df15efee55f3a",
"image": "20260928182434 (dev)",
"log": [
"19:19:36 start cloud.pause-resume (live, api) in campaign c-20260928183105-64ee",
"19:19:36 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"19:19:36 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"19:19:36 queued by the attended queue opened 2026-09-28T18:51:04Z",
"19:19:36 baseline: pre: clean",
"19:19:36 the running client is the offline service: restarting it with the service",
"19:19:36 cloud mode: restarting the cloud client for a fresh connect (was pid 14532)",
"19:19:44 cloud session established (pid 15232)",
"19:19:51 connect-time hunt: INFO basemachine:_finish_action hunt [1589773639]: finished with event \":completed\"",
"19:20:07 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"19:20:38 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"19:20:42 PROMPT: In the Glowforge app: scrap on the bed, lid closed, a SMALL engrave or score job (about 30 s) set up. Click Done here, then press Print in the app and press the physical button when it lights white.",
"19:20:44 ANSWER: Done",
"19:21:09 ACT button press (fixture)",
"19:21:09 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"19:21:10 ACT button press: done after 1.3 s",
"19:21:10 ACT button press (fixture)",
"19:21:11 ACT button press: done after 1.3 s",
"19:21:11 armed after the resume: True",
"19:21:28 warm-up: 2026-09-28T19:21:04.597084+00:00 gfcloud[15232] INFO machine:_dwell warm up: holding 3.0 s",
"19:21:28 rest: 2026-09-28T19:21:16.782702+00:00 gfcloud[15232] INFO machine:_dwell cool down: holding 10.0 s",
"19:21:28 progress reported against 44986 bytes",
"19:21:28 PROMPT: In the app: did the print's progress advance while it cut (not standing still, not jumping straight to nearly finished), and does the app show it complete?",
"19:21:35 ANSWER: Yes",
"19:21:35 job limits from the header (the print's): air_assist_min_rpm=116 coolant_max_c=33.0 coolant_min_c=5.0",
"19:21:35 engine effective limits: 2026-09-28T19:20:55.228884+00:00 forgectrl[5640] INFO cool: effective limits: coolant ceiling 33.0 C (local 33.0, header 50.0) resume 31.0 C; floors coolant 10.0 C (the job's), exhaust 6416 rpm, intak",
"19:21:40 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"19:22:10 cloud mode stays up; the machine is quiet",
"19:22:10 PASS: button pause/resume mid-print, warm-up and rest observed, progress reported, the job's limits passed through, job completed and parked",
"19:22:10 baseline: post: clean",
"19:22:10 result PASS"
],
"manifest_sha": "84a155bfc701e865ae73f9818bc38c2d005324ab5ba0ed44b668ec8896179947",
"message": "",
"result": "PASS",
"test": "cloud.pause-resume",
"ts": "2026-09-28T19:22:10Z"
},
"requires": [
"laser.emission-witness"
],
"satisfied": true,
"source_sha": "340c805a11d99e0ac92939591c02a3a03f5a927a197a981d034a623a1383c983",
"subsystem": "cloud",
"title": "Button pauses and resumes a cloud print (factory backtrack + lead)"
},
{
"always": false,
"covers": [
[
"forgefirm-app",
"forgefirm-app/gfcloud.py"
],
[
"forgefirm-app",
"forgefirm-app/ffmachine.py"
],
[
"forgefirm-app",
"forgefirm-app/gfhome.conf.sample"
],
[
"python3-gfhardware",
"gfhardware/__init__.py"
],
[
"python3-gfhardware",
"gfhardware/_common.py"
],
[
"python3-gfhardware",
"gfhardware/id.py"
],
[
"python3-gfhardware",
"gfhardware/coolsvc.py"
],
[
"python3-gfutilities",
"gfutilities/__init__.py"
],
[
"python3-gfutilities",
"gfutilities/_common.py"
],
[
"python3-gfutilities",
"gfutilities/configuration.py"
],
[
"python3-gfutilities",
"gfutilities/device/__init__.py"
],
[
"python3-gfutilities",
"gfutilities/device/basemachine.py"
],
[
"python3-gfutilities",
"gfutilities/device/settings.py"
],
[
"python3-gfutilities",
"gfutilities/service/__init__.py"
],
[
"python3-gfutilities",
"gfutilities/service/dispatch.py"
],
[
"python3-gfutilities",
"gfutilities/service/websocket.py"
],
[
"python3-gfhardware",
"gfhardware/machine.py"
],
[
"python3-gfhardware",
"gfhardware/feeder.py"
],
[
"python3-gfhardware",
"gfhardware/cnc.py"
],
[
"python3-gfhardware",
"gfhardware/switches.py"
],
[
"python3-gfhardware",
"gfhardware/input/**"
],
[
"python3-gfhardware",
"gfhardware/src/evdev.c"
],
[
"python3-gfhardware",
"gfhardware/z_axis.py"
],
[
"python3-gfhardware",
"gfhardware/leds.py"
],
[
"python3-gfhardware",
"gfhardware/cooling.py"
],
[
"python3-gfutilities",
"gfutilities/service/offline.py"
],
[
"python3-gfutilities",
"gfutilities/puls/**"
],
[
"forgectrl",
"src/super.c"
],
[
"forgectrl",
"src/main.c"
]
],
"fingerprint": "3cb9219f0cb85e53715bb5ba40670bb40b0817f40b976d90f4d14677e78ac145",
"hardware": "api",
"id": "cloud.oversize-stream",
"inherited": true,
"kind": "live",
"record": {
"answers": [],
"campaign": "c-20260928183105-64ee",
"duration_s": 211,
"evidence": {
"actions": [
{
"by": "fixture",
"channel": "button",
"state": "press",
"took_s": 6.01,
"ts": "2026-09-28T19:22:50Z"
},
{
"by": "fixture",
"channel": "button",
"state": "press",
"took_s": 1.25,
"ts": "2026-09-28T19:24:56Z"
},
{
"by": "fixture",
"channel": "button",
"state": "press",
"took_s": 1.26,
"ts": "2026-09-28T19:24:57Z"
}
],
"app_armed_after": false,
"app_counters_after_park": [
0,
0,
0
],
"app_latch_locked": true,
"backtrack_refused_lines": [],
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "attended",
"ts": "2026-09-28T18:51:04Z"
},
"button_dark": false,
"events": [
"print:starting",
"print:download:completed",
"button:pressed",
"print:warmup:starting",
"button:released",
"print:running",
"button:pressed",
"button:released",
"print:paused",
"button:pressed",
"print:resumed",
"button:released",
"print:return_to_home:succeeded",
"print:cancelled"
],
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"jobs": {
"long.puls": {
"compressed": true,
"payload_bytes": 35015348,
"seconds": 3501.5
}
},
"log": {
"job is longer than the ring": true
},
"max_backtrack": 168283,
"operator": {
"ack_live": true,
"ts": "2026-09-28T19:22:11Z"
},
"pause_log": {
"button pressed mid-run; pausing": true,
"button pressed while paused": true,
"paused at": true,
"resuming (laser lead": true
},
"print_finished": "INFO basemachine:_finish_action print [9004]: finished with event \":cancelled\"",
"progress_total": 35015348,
"service_cancel": {
"action canceled mid-run; stopping motion": "WARNING machine:_run_loop action canceled mid-run; stopping motion",
"return home complete": "INFO machine:_return_home return home complete",
"start return home": "INFO machine:_return_home start return home"
},
"streaming": 1,
"total_first": 33292288,
"total_later": 34603008,
"underruns_before": 1,
"underruns_during": 1
},
"fingerprint": "3cb9219f0cb85e53715bb5ba40670bb40b0817f40b976d90f4d14677e78ac145",
"image": "20260928182434 (dev)",
"log": [
"19:22:10 start cloud.oversize-stream (live, api) in campaign c-20260928183105-64ee",
"19:22:11 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"19:22:11 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"19:22:11 queued by the attended queue opened 2026-09-28T18:51:04Z",
"19:22:11 baseline: pre: clean",
"19:22:11 cloud mode: restarting the client offline (was pid 15232)",
"19:22:15 offline service up: INFO offline:open OFFLINE service: no web session; listening on /run/gfcloud-offline.sock",
"19:22:42 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"19:22:47 job long.puls: 35015348 payload bytes, 3502 s at STfr 10000 (gzip)",
"19:22:50 ACT button press (fixture)",
"19:22:56 ACT button press: done after 6.0 s",
"19:22:56 program total at the start of the run: 33292288 bytes",
"19:22:56 NOTICE: Cutting: the test watches the ring being topped up for two minutes. Do nothing yet.",
"19:23:12 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"19:23:44 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"19:24:15 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"19:24:47 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"19:24:56 program total two minutes in: 34603008 bytes (+1310720)",
"19:24:56 progress reported against 35015348 bytes, kernel program total 34603008",
"19:24:56 max_backtrack while the feed runs: 168283 steps",
"19:24:56 ACT button press (fixture)",
"19:24:57 ACT button press: done after 1.3 s",
"19:24:57 ACT button press (fixture)",
"19:24:59 ACT button press: done after 1.3 s",
"19:24:59 canceled the print as the app would",
"19:25:12 [cancel] action canceled mid-run; stopping motion: seen",
"19:25:12 [cancel] start return home: seen",
"19:25:12 [cancel] return home complete: seen",
"19:25:12 [app] kernel counters after the park: [0, 0, 0]",
"19:25:18 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"19:25:42 cloud mode stays up; the machine is quiet",
"19:25:42 PASS: a job longer than the ring ran live-fed, total grew, no underrun; the app's cancel stopped it, parked, relocked and reported ':cancelled'",
"19:25:42 offline jobs removed from /tmp/forgetest",
"19:25:42 baseline: post: clean",
"19:25:42 result PASS"
],
"manifest_sha": "84a155bfc701e865ae73f9818bc38c2d005324ab5ba0ed44b668ec8896179947",
"message": "",
"result": "PASS",
"test": "cloud.oversize-stream",
"ts": "2026-09-28T19:25:42Z"
},
"requires": [
"cloud.lid-interlock-abort",
"cloud.pause-resume"
],
"satisfied": true,
"source_sha": "4ce4282027e052a11a0080f3266bb3074762f9676b9c4653c82ca8e749c8ed2c",
"subsystem": "cloud",
"title": "A print longer than the ring is fed while it plays"
},
{
"always": false,
"covers": [
[
"forgefirm-app",
"forgefirm-app/gfcloud.py"
],
[
"forgefirm-app",
"forgefirm-app/ffmachine.py"
],
[
"forgefirm-app",
"forgefirm-app/gfhome.conf.sample"
],
[
"python3-gfhardware",
"gfhardware/__init__.py"
],
[
"python3-gfhardware",
"gfhardware/_common.py"
],
[
"python3-gfhardware",
"gfhardware/id.py"
],
[
"python3-gfhardware",
"gfhardware/coolsvc.py"
],
[
"python3-gfutilities",
"gfutilities/__init__.py"
],
[
"python3-gfutilities",
"gfutilities/_common.py"
],
[
"python3-gfutilities",
"gfutilities/configuration.py"
],
[
"python3-gfutilities",
"gfutilities/device/__init__.py"
],
[
"python3-gfutilities",
"gfutilities/device/basemachine.py"
],
[
"python3-gfutilities",
"gfutilities/device/settings.py"
],
[
"python3-gfutilities",
"gfutilities/service/__init__.py"
],
[
"python3-gfutilities",
"gfutilities/service/dispatch.py"
],
[
"python3-gfutilities",
"gfutilities/service/websocket.py"
],
[
"python3-gfhardware",
"gfhardware/machine.py"
],
[
"python3-gfhardware",
"gfhardware/feeder.py"
],
[
"python3-gfhardware",
"gfhardware/cnc.py"
],
[
"python3-gfhardware",
"gfhardware/switches.py"
],
[
"python3-gfhardware",
"gfhardware/input/**"
],
[
"python3-gfhardware",
"gfhardware/src/evdev.c"
],
[
"python3-gfhardware",
"gfhardware/z_axis.py"
],
[
"python3-gfhardware",
"gfhardware/leds.py"
],
[
"python3-gfhardware",
"gfhardware/cooling.py"
],
[
"python3-gfutilities",
"gfutilities/service/offline.py"
],
[
"python3-gfutilities",
"gfutilities/puls/**"
],
[
"forgectrl",
"src/super.c"
],
[
"forgectrl",
"src/main.c"
]
],
"fingerprint": "95635a1f4abb6a065e68ba79ed3ffea9f4fc44c9f77fb68bf5f10b46fee169c4",
"hardware": "api",
"id": "cloud.paused-lid-cancel",
"inherited": true,
"kind": "live",
"record": {
"answers": [],
"campaign": "c-20260928183105-64ee",
"duration_s": 52,
"evidence": {
"actions": [
{
"by": "fixture",
"channel": "button",
"state": "press",
"took_s": 6.77,
"ts": "2026-09-28T19:25:44Z"
},
{
"by": "fixture",
"channel": "button",
"state": "press",
"took_s": 1.25,
"ts": "2026-09-28T19:25:50Z"
},
{
"by": "fixture",
"channel": "lid",
"state": "open",
"took_s": 0.04,
"ts": "2026-09-28T19:25:52Z"
},
{
"by": "fixture",
"channel": "lid",
"state": "close",
"took_s": 0.28,
"ts": "2026-09-28T19:26:04Z"
}
],
"armed_after": false,
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "attended",
"ts": "2026-09-28T18:51:04Z"
},
"button_dark": false,
"counters_after": [
0,
0,
0
],
"events": [
"print:starting",
"print:download:completed",
"button:pressed",
"print:warmup:starting",
"button:released",
"print:running",
"button:pressed",
"button:released",
"print:paused",
"lid:opened",
"print:return_to_home:succeeded",
"print:cancelled",
"lid:closed"
],
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"jobs": {
"paused.puls": {
"compressed": false,
"payload_bytes": 648452,
"seconds": 64.8
}
},
"latch_locked_after": true,
"lid_from_pause": {
"lid opened mid-run; stopping motion": "WARNING machine:_run_loop lid opened mid-run; stopping motion",
"print finished": "INFO basemachine:_finish_action print [9005]: finished with event \":cancelled\"",
"return home complete": "INFO machine:_return_home return home complete",
"start return home": "INFO machine:_return_home start return home"
},
"operator": {
"ack_live": true,
"ts": "2026-09-28T19:25:42Z"
},
"paused": {
"button pressed mid-run; pausing": true,
"paused at": true
}
},
"fingerprint": "95635a1f4abb6a065e68ba79ed3ffea9f4fc44c9f77fb68bf5f10b46fee169c4",
"image": "20260928182434 (dev)",
"log": [
"19:25:42 start cloud.paused-lid-cancel (live, api) in campaign c-20260928183105-64ee",
"19:25:42 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"19:25:42 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"19:25:42 queued by the attended queue opened 2026-09-28T18:51:04Z",
"19:25:43 baseline: pre: clean",
"19:25:43 the offline service is already up (pid 16048) - reusing it",
"19:25:43 job paused.puls: 648452 payload bytes, 65 s at STfr 10000",
"19:25:44 ACT button press (fixture)",
"19:25:50 ACT button press: done after 6.8 s",
"19:25:50 ACT button press (fixture)",
"19:25:52 ACT button press: done after 1.3 s",
"19:25:52 ACT lid open (fixture)",
"19:25:52 ACT lid open: done after 0.0 s",
"19:26:04 [print] lid opened mid-run; stopping motion: seen",
"19:26:04 [print] start return home: seen",
"19:26:04 [print] return home complete: seen",
"19:26:04 [print] print finished: seen",
"19:26:04 ACT lid close (fixture)",
"19:26:04 ACT lid close: done after 0.3 s",
"19:26:14 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"19:26:34 cloud mode stays up; the machine is quiet",
"19:26:35 PASS: a paused print canceled by the lid stopped, parked, relocked and reported ':cancelled'",
"19:26:35 offline jobs removed from /tmp/forgetest",
"19:26:35 baseline: post: clean",
"19:26:35 result PASS"
],
"manifest_sha": "84a155bfc701e865ae73f9818bc38c2d005324ab5ba0ed44b668ec8896179947",
"message": "",
"result": "PASS",
"test": "cloud.paused-lid-cancel",
"ts": "2026-09-28T19:26:35Z"
},
"requires": [
"cloud.pause-resume",
"cloud.lid-interlock-abort"
],
"satisfied": true,
"source_sha": "601df2616775b9fa8de5401bbf5d13256b3fc4e1db36525ad1893daa75966caf",
"subsystem": "cloud",
"title": "A paused cloud print is canceled by the lid"
},
{
"always": false,
"covers": [
[
"linux-fslc",
"**"
]
],
"fingerprint": "89b37c3d865ae6488b3ade039bb884f597e5d4ea2971de9d3b0d8223a2e9bfce",
"hardware": "api",
"id": "exthost.platform",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928180313-75fb",
"duration_s": 22,
"evidence": {
"allowlisted_self": [
[
[
4,
"127.0.0.1",
443,
false
],
[
"refused",
0.0
]
],
[
[
4,
"<IP-1>",
443,
false
],
[
"refused",
0.0
]
]
],
"as_pool_uid": {
"800": [
[
[
4,
"127.0.0.1",
443,
false
],
[
"refused",
0.0
]
],
[
[
4,
"127.0.0.1",
80,
false
],
[
"refused",
0.0
]
],
[
[
6,
"::1",
443,
false
],
[
"refused",
0.0
]
],
[
[
6,
"::1",
23,
false
],
[
"refused",
0.0
]
],
[
[
4,
"<IP-1>",
443,
false
],
[
"refused",
0.0
]
],
[
[
4,
"<IP-1>",
23,
false
],
[
"refused",
0.0
]
],
[
[
4,
"127.0.0.1",
9,
true
],
[
"eperm",
0.0
]
],
[
[
4,
"<IP-1>",
9,
true
],
[
"eperm",
0.0
]
]
],
"831": [
[
[
4,
"127.0.0.1",
443,
false
],
[
"refused",
0.0
]
],
[
[
4,
"127.0.0.1",
80,
false
],
[
"refused",
0.0
]
],
[
[
6,
"::1",
443,
false
],
[
"refused",
0.0
]
],
[
[
6,
"::1",
23,
false
],
[
"refused",
0.0
]
],
[
[
4,
"<IP-1>",
443,
false
],
[
"refused",
0.0
]
],
[
[
4,
"<IP-1>",
23,
false
],
[
"refused",
0.0
]
],
[
[
4,
"127.0.0.1",
9,
true
],
[
"eperm",
0.0
]
],
[
[
4,
"<IP-1>",
9,
true
],
[
"eperm",
0.0
]
]
]
},
"as_root": [
[
[
4,
"127.0.0.1",
443,
false
],
[
"ok",
0.0
]
],
[
[
4,
"<IP-1>",
443,
false
],
[
"ok",
0.0
]
],
[
[
4,
"127.0.0.1",
9,
true
],
[
"ok",
0.0
]
]
],
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T18:03:13Z"
},
"cgroup_tree": {
"controllers": [
"cpu",
"memory",
"pids"
],
"ffx_cpu_idle": "1",
"ffx_subtree": [
"cpu",
"memory",
"pids"
],
"root_subtree": [
"cpu",
"memory",
"pids"
]
},
"counters": [
[
0,
0
],
[
12,
4
]
],
"cpu": {
"frozen_us": 0,
"share": 0.045,
"thawed_us": 86301,
"throttled": 27
},
"firmware_groups": {
"forgectrl/1319": "0::/"
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-2>",
"released": []
},
"kernel": {
"CONFIG_CFS_BANDWIDTH": "y",
"CONFIG_CGROUPS": "y",
"CONFIG_CGROUP_PIDS": "y",
"CONFIG_CGROUP_SCHED": "y",
"CONFIG_FAIR_GROUP_SCHED": "y",
"CONFIG_MEMCG": "y",
"CONFIG_NFT_LIMIT": "y",
"CONFIG_NFT_REJECT_INET": "y",
"CONFIG_NF_CONNTRACK": "n",
"CONFIG_NF_TABLES": "y",
"CONFIG_NF_TABLES_INET": "y",
"CONFIG_RT_GROUP_SCHED": "n",
"CONFIG_SECCOMP_FILTER": "y",
"CONFIG_SECURITY_LANDLOCK": "y"
},
"landlock": {
"abi": 6,
"after": {
"added": 0,
"applied": 0,
"etc": "eacces",
"ruleset": true,
"tcp": "eacces",
"usr": "ok"
},
"before": {
"etc": "ok",
"tcp": "ok",
"usr": "ok"
}
},
"memory": {
"lines": [
{
"started": true
}
],
"oom_kill": 1,
"peak": "25165824",
"rc": -9
},
"pids": {
"events_max": 1,
"result": {
"forked": 5,
"stopped_by": "EAGAIN"
}
},
"pool": {
"accounts": 32,
"others": [],
"problems": []
},
"rules": "table inet ffx {\n\tmap allow {\n\t\ttype uid : verdict\n\t}\n\n\tchain output {\n\t\ttype filter hook output priority filter; policy accept;\n\t\tmeta skuid 800-831 jump pool\n\t}\n\n\tchain pool {\n\t\toifname \"lo\" jump refuse\n\t\tmeta skuid vmap @allow\n\t\tjump refuse\n\t}\n\n\tchain refuse {\n\t\tmeta l4proto tcp counter packets 0 bytes 0 reject with tcp reset\n\t\tcounter packets 0 bytes 0 drop\n\t}\n}\n",
"seccomp": {
"after": "eperm",
"before": "Linux",
"installed": 0,
"status": [
"2"
]
}
},
"fingerprint": "89b37c3d865ae6488b3ade039bb884f597e5d4ea2971de9d3b0d8223a2e9bfce",
"image": "20260928175056 (dev)",
"log": [
"18:05:14 start exthost.platform (auto, api) in campaign c-20260928180313-75fb",
"18:05:14 fixture up: <REDACTED-1> at <IP-2>, v1.0.0, covers lid, interlock, button",
"18:05:14 fixture: <REDACTED-1> at <IP-2> covers lid, interlock, button",
"18:05:14 queued by the unattended queue opened 2026-09-28T18:03:13Z",
"18:05:15 baseline: pre: clean",
"18:05:15 cgroup tree: {'controllers': ['cpu', 'memory', 'pids'], 'root_subtree': ['cpu', 'memory', 'pids'], 'ffx_subtree': ['cpu', 'memory', 'pids'], 'ffx_cpu_idle': '1'}",
"18:05:20 a spinning probe under cpu.max 5%: 4.5% of the core, throttled 27 times",
"18:05:23 frozen for 1.5 s the probe ran 0 us; thawed for 1.5 s it ran 86301 us",
"18:05:25 pids.max 6: the fork loop made 5 of 12, stopped by EAGAIN; pids.events max 1",
"18:05:34 memory.max 24 MiB against a 96 MiB appetite: rc -9, oom_kill 1, peak 25165824",
"18:05:35 two pool uids: 6 TCP connects each refused at once, 2 UDP sends each EPERM; the rules counted [0, 0] -> [12, 4]",
"18:05:36 uid 831 with the machine's own addresses on its allowlist: [[[4, '127.0.0.1', 443, False], ['refused', 0.0]], [[4, '<IP-1>', 443, False], ['refused', 0.0]]]",
"18:05:36 landlock ABI 6: before {'etc': 'ok', 'usr': 'ok', 'tcp': 'ok'}, after {'ruleset': True, 'added': 0, 'applied': 0, 'tcp': 'eacces', 'etc': 'eacces', 'usr': 'ok'}",
"18:05:36 seccomp: {'installed': 0, 'before': 'Linux', 'after': 'eperm', 'status': ['2']}",
"18:05:36 PASS: the kernel, the cgroup tree, the account pool, and the deny rules are in place, and each held a probe process the way it will hold a package",
"18:05:37 baseline: post: clean",
"18:05:37 result PASS"
],
"manifest_sha": "0946700866975cd7ed6b5cc6c6fd0dadc033a8ab5d820a9bea37ca92b7e64368",
"message": "",
"result": "PASS",
"test": "exthost.platform",
"ts": "2026-09-28T18:05:37Z"
},
"requires": [],
"satisfied": true,
"source_sha": "55074710dbcc6b6f0376e1ee2be0bfe806ddd8190e71908ab16b9ed79a5254e2",
"subsystem": "exthost",
"title": "The extension sandbox platform holds a process"
},
{
"always": false,
"covers": [
[
"forgeext",
"**"
],
[
"forgectrl",
"src/main.c"
],
[
"forgectrl",
"src/logs.*"
]
],
"fingerprint": "d2ad8e891adb58e6c5ffd828dbfd75748a76913fdbace546330a27a43a0f8800",
"hardware": "takeover",
"id": "exthost.service",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928180313-75fb",
"duration_s": 51,
"evidence": {
"another_account_at_its_socket": [
{
"result": "eacces"
}
],
"api": {
"api_hold": [
403,
{
"error": "this package has no hold: the operator did not grant it one"
}
],
"api_mode": [
200,
{
"controller": "running",
"gated": false,
"local": false,
"mode": "cloud",
"motion": "verified",
"pid": 1397,
"why": ""
}
],
"api_nowhere": [
404,
{
"error": "the extension API has no such path"
}
],
"api_self": [
200,
{
"api": "0.1",
"capabilities": [
"net.outbound:<IP-1>:443",
"storage:1",
"machine.read",
"settings.own",
"camera.lid"
],
"destinations": [
"<IP-1>:443"
],
"id": "org.forgetest.reference",
"version": "1.0.0"
}
],
"api_traversal": [
400,
{
"error": "the path holds .."
}
]
},
"api_camera": {
"bytes": 62481,
"image_type": true,
"jpeg": true,
"status": 200,
"why": null
},
"api_camera_bad": [
400,
"the body holds camera (lid or head), resolution (full or half), quality (1 to 100), and lamp (0 to 1023), and nothing else"
],
"api_camera_head": [
403,
"this package does not hold that camera"
],
"api_camera_lamp": {
"dark": [
200,
33868,
true
],
"lit": [
200,
87598,
true
]
},
"api_camera_lamp_bad": [
400,
"the body holds camera (lid or head), resolution (full or half), quality (1 to 100), and lamp (0 to 1023), and nothing else"
],
"api_settings": [
200,
{
"schema": [
{
"default": 40.0,
"label": "threshold",
"max": 100.0,
"min": 0.0,
"name": "threshold",
"type": "number"
},
{
"default": "",
"label": "A note",
"max": 32,
"name": "note",
"type": "string"
},
{
"choices": [
"start",
"end",
"never"
],
"default": "end",
"label": "when",
"name": "when",
"type": "choice"
}
],
"settings": {
"note": "",
"threshold": 40.0,
"when": "end"
}
}
],
"api_settings_out_of_bounds": [
400,
{
"error": "\"threshold\" is at most 100"
}
],
"api_settings_set": [
200,
{
"schema": [
{
"default": 40.0,
"label": "threshold",
"max": 100.0,
"min": 0.0,
"name": "threshold",
"type": "number"
},
{
"default": "",
"label": "A note",
"max": 32,
"name": "note",
"type": "string"
},
{
"choices": [
"start",
"end",
"never"
],
"default": "end",
"label": "when",
"name": "when",
"type": "choice"
}
],
"settings": {
"note": "set from inside",
"threshold": 70,
"when": "end"
}
}
],
"api_settings_undeclared": [
400,
{
"error": "this package declares no setting \"nothere\""
}
],
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T18:03:13Z"
},
"camera_after_watching": [
200,
63149
],
"camera_while_watched": [
409,
"somebody is watching a camera: a background capture waits until they stop",
false,
false
],
"data_dir_mode_found": "0711",
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-2>",
"released": []
},
"from_the_inside": {
"api_camera": [
200,
62481,
true,
true
],
"api_camera_bad": [
400,
"the body holds camera (lid or head), resolution (full or half), quality (1 to 100), and lamp (0 to 1023), and nothing else",
false,
false
],
"api_camera_dark": [
200,
33868,
true,
true
],
"api_camera_head": [
403,
"this package does not hold that camera",
false,
false
],
"api_camera_lamp_bad": [
400,
"the body holds camera (lid or head), resolution (full or half), quality (1 to 100), and lamp (0 to 1023), and nothing else",
false,
false
],
"api_camera_lit": [
200,
87598,
true,
true
],
"api_hold": [
403,
{
"error": "this package has no hold: the operator did not grant it one"
}
],
"api_mode": [
200,
{
"controller": "running",
"gated": false,
"local": false,
"mode": "cloud",
"motion": "verified",
"pid": 1397,
"why": ""
}
],
"api_nowhere": [
404,
{
"error": "the extension API has no such path"
}
],
"api_self": [
200,
{
"api": "0.1",
"capabilities": [
"net.outbound:<IP-1>:443",
"storage:1",
"machine.read",
"settings.own",
"camera.lid"
],
"destinations": [
"<IP-1>:443"
],
"id": "org.forgetest.reference",
"version": "1.0.0"
}
],
"api_settings": [
200,
{
"schema": [
{
"default": 40.0,
"label": "threshold",
"max": 100.0,
"min": 0.0,
"name": "threshold",
"type": "number"
},
{
"default": "",
"label": "A note",
"max": 32,
"name": "note",
"type": "string"
},
{
"choices": [
"start",
"end",
"never"
],
"default": "end",
"label": "when",
"name": "when",
"type": "choice"
}
],
"settings": {
"note": "",
"threshold": 40.0,
"when": "end"
}
}
],
"api_settings_out_of_bounds": [
400,
{
"error": "\"threshold\" is at most 100"
}
],
"api_settings_set": [
200,
{
"schema": [
{
"default": 40.0,
"label": "threshold",
"max": 100.0,
"min": 0.0,
"name": "threshold",
"type": "number"
},
{
"default": "",
"label": "A note",
"max": 32,
"name": "note",
"type": "string"
},
{
"choices": [
"start",
"end",
"never"
],
"default": "end",
"label": "when",
"name": "when",
"type": "choice"
}
],
"settings": {
"note": "set from inside",
"threshold": 70,
"when": "end"
}
}
],
"api_settings_undeclared": [
400,
{
"error": "this package declares no setting \"nothere\""
}
],
"api_traversal": [
400,
{
"error": "the path holds .."
}
],
"cwd": "/data/forgefirm/ext/data/org.forgetest.reference",
"env": [
"FFX_API",
"FFX_DATA",
"FFX_ID",
"FFX_PKG",
"HOME",
"LANG",
"LC_CTYPE",
"PATH",
"PYTHONDONTWRITEBYTECODE",
"PYTHONUNBUFFERED",
"TMPDIR"
],
"gid": 800,
"groups": [],
"lan_declared_port": "ECONNREFUSED",
"loopback_declared_port": "ECONNREFUSED",
"loopback_undeclared_port": "EACCES",
"netlink_socket": "EPERM",
"pulse_device": "EACCES",
"read_etc": "ok",
"read_pkg": "ok",
"read_settings": "EACCES",
"read_setup": "EACCES",
"uid": 800,
"unix_socket": "ok",
"write_data": "ok",
"write_pkg": "EACCES",
"write_tmp": "EACCES"
},
"host_back_s": 5.6,
"host_pids": [
479
],
"inspect_without_the_key": "unverified",
"install_without_consent": "this package is signed by a key the owner added, not by OpenGlow: installing it takes the operator's typed consent",
"quota": {
"reason": "its data directory holds 2 MiB and it may hold 1: remove the package, or clear its data and enable it again",
"state": "quarantined"
},
"service": {
"account": "ffx0",
"cgroup": "0::/ffx/org.forgetest.reference",
"cpu.max": "25000 100000",
"memory.current": "2617344",
"memory.max": "50331648",
"pid": 1566,
"pids.max": "32"
},
"service_outlived_a_killed_host_s": 0.05,
"settings_store": {
"mode": "0600"
},
"status_at_start": {
"armed": false,
"enabled": true,
"events": {
"connected": false,
"wanted": 0
},
"mcodes": [],
"not_ready": "",
"off_reason": "",
"pid": 479,
"services": [
{
"account": "ffx0",
"frozen": false,
"healthy": false,
"id": "org.forgetest.reference",
"job_limited": false,
"pid": 1566,
"reason": "",
"state": "running"
}
]
}
},
"fingerprint": "d2ad8e891adb58e6c5ffd828dbfd75748a76913fdbace546330a27a43a0f8800",
"image": "20260928175056 (dev)",
"log": [
"18:05:37 start exthost.service (auto, takeover) in campaign c-20260928180313-75fb",
"18:05:37 fixture up: <REDACTED-1> at <IP-2>, v1.0.0, covers lid, interlock, button",
"18:05:37 fixture: <REDACTED-1> at <IP-2> covers lid, interlock, button",
"18:05:37 queued by the unattended queue opened 2026-09-28T18:03:13Z",
"18:05:37 baseline: pre: clean",
"18:05:38 install without the consent -> this package is signed by a key the owner added, not by OpenGlow: installing it takes the operator's typed consent",
"18:05:39 the service: {'pid': 1566, 'account': 'ffx0', 'cgroup': '0::/ffx/org.forgetest.reference', 'cpu.max': '25000 100000', 'memory.max': '50331648', 'pids.max': '32', 'memory.current': '2617344'}",
"18:05:42 from the inside: {'uid': 800, 'gid': 800, 'groups': [], 'cwd': '/data/forgefirm/ext/data/org.forgetest.reference', 'env': ['FFX_API', 'FFX_DATA', 'FFX_ID', 'FFX_PKG', 'HOME', 'LANG', 'LC_CTYPE', 'PATH', 'PYTHONDONTWRITEBYTECODE', 'PYTHONUNBUFFERED', 'TMPDIR'], 'read_settings': 'EACCES', 'read_setup': 'EACCES', 'read_etc': 'ok', 'read_pkg': 'ok', 'write_pkg': 'EACCES', 'write_data': 'ok', 'write_tmp': 'EACCES', 'pulse_device': 'EACCES', 'loopback_declared_port': 'ECONNREFUSED', 'lan_declared_port': 'ECONNREFUSED', 'loopback_undeclared_port': 'EACCES', 'netlink_socket': 'EPERM', 'unix_socket': 'ok', 'api_camera': [200, 62481, True, True], 'api_camera_head': [403, 'this package does not hold that camera', False, False], 'api_camera_bad': [400, 'the body holds camera (lid or head), resolution (full or half), quality (1 to 100), and lamp (0 to 1023), and nothing else', False, False], 'api_camera_dark': [200, 33868, True, True], 'api_camera_lit': [200, 87598, True, True], 'api_camera_lamp_bad': [400, 'the body holds camera (lid or head), resolution (full or half), quality (1 to 100), and lamp (0 to 1023), and nothing else', False, False], 'api_settings': [200, {'settings': {'threshold': 40.0, 'note': '', 'when': 'end'}, 'schema': [{'name': 'threshold', 'label': 'threshold', 'type': 'number', 'default': 40.0, 'min': 0.0, 'max': 100.0}, {'name': 'note', 'label': 'A note', 'type': 'string', 'default': '', 'max': 32}, {'name': 'when', 'label': 'when', 'type': 'choice', 'default': 'end', 'choices': ['start', 'end', 'never']}]}], 'api_settings_set': [200, {'settings': {'threshold': 70, 'note': 'set from inside', 'when': 'end'}, 'schema': [{'name': 'threshold', 'label': 'threshold', 'type': 'number', 'default': 40.0, 'min': 0.0, 'max': 100.0}, {'name': 'note', 'label': 'A note', 'type': 'string', 'default': '', 'max': 32}, {'name': 'when', 'label': 'when', 'type': 'choice', 'default': 'end', 'choices': ['start', 'end', 'never']}]}], 'api_settings_undeclared': [400, {'error': 'this package declares no setting \"nothere\"'}], 'api_settings_out_of_bounds': [400, {'error': '\"threshold\" is at most 100'}], 'api_self': [200, {'id': 'org.forgetest.reference', 'version': '1.0.0', 'api': '0.1', 'capabilities': ['net.outbound:<IP-1>:443', 'storage:1', 'machine.read', 'settings.own', 'camera.lid'], 'destinations': ['<IP-1>:443']}], 'api_mode': [200, {'mode': 'cloud', 'controller': 'running', 'pid': 1397, 'motion': 'verified', 'gated': False, 'local': False, 'why': ''}], 'api_hold': [403, {'error': 'this package has no hold: the operator did not grant it one'}], 'api_nowhere': [404, {'error': 'the extension API has no such path'}], 'api_traversal': [400, {'error': 'the path holds ..'}]}",
"18:05:42 the lid camera, from inside the sandbox: {'status': 200, 'bytes': 62481, 'jpeg': True, 'image_type': True, 'why': None}",
"18:05:42 the lid camera with its lamp at 0 and at 1023: {'dark': [200, 33868, True], 'lit': [200, 87598, True]}",
"18:05:44 the package's capture while a viewer watches: [409, 'somebody is watching a camera: a background capture waits until they stop', False, False]",
"18:05:45 wrote 2 MiB into its data directory (it declares storage:1)",
"18:06:02 over its quota: {'state': 'quarantined', 'reason': 'its data directory holds 2 MiB and it may hold 1: remove the package, or clear its data and enable it again'}",
"18:06:08 fixture up: <REDACTED-1> at <IP-2>, v1.0.0, covers lid, interlock, button",
"18:06:08 safe mode stopped it and its end started it again (pid 1740)",
"18:06:16 a killed host: its service gone in 0.05 s, the host back and the service running after 5.6 s",
"18:06:18 remove org.forgetest.reference -> ok",
"18:06:18 restore ext_enabled='1' -> 200",
"18:06:18 takeover: waiting for forgectrl to be settled",
"18:06:18 baseline: /mode controller=running motion=verified",
"18:06:18 takeover: preserving cnc/motor_lock=0, cnc/step_freq=10000, cnc/ramp_rate=125000, cnc/streaming=0, cnc/x_mode=8, cnc/y_mode=8, cnc/x_decay=1, cnc/y_decay=1, pic/x_step_current=33, pic/y_step_current=33",
"18:06:18 takeover: stopping the controller through forgectrl",
"18:06:19 takeover: POST /controller/stop -> 200",
"18:06:19 takeover: forgectrl stop -> rc 0",
"18:06:21 takeover: pulse device free",
"18:06:21 takeover: forgectrl start -> rc 0",
"18:06:23 baseline: /mode controller=stopped motion=unverified",
"18:06:28 baseline: /mode controller=running motion=verified",
"18:06:28 the previous record is back under a restart",
"18:06:28 baseline: post: clean",
"18:06:28 result PASS"
],
"manifest_sha": "0946700866975cd7ed6b5cc6c6fd0dadc033a8ab5d820a9bea37ca92b7e64368",
"message": "",
"result": "PASS",
"test": "exthost.service",
"ts": "2026-09-28T18:06:28Z"
},
"requires": [
"exthost.platform",
"setup.extensions-consent"
],
"satisfied": true,
"source_sha": "4861f566e4ee9a344cf0df2337ed08757412e2442e60761d7e43bebe9ba71e9c",
"subsystem": "exthost",
"title": "A package's service runs confined under the extension host"
},
{
"always": false,
"covers": [
[
"forgeext",
"src/super.*"
],
[
"forgeext",
"src/run.*"
],
[
"forgeext",
"src/machine.*"
],
[
"forgeext",
"src/cgroup.*"
],
[
"forgectrl",
"src/cool.*"
],
[
"forgectrl",
"src/cam.*"
],
[
"forgectrl",
"src/main.c"
]
],
"fingerprint": "8a1ab8681ddcc95192eaf56b7c2f74f741303e7c9ca7c03220fdb88e4f34ac63",
"hardware": "takeover",
"id": "exthost.armed-freeze",
"inherited": true,
"kind": "operator",
"record": {
"answers": [],
"campaign": "c-20260928180313-75fb",
"duration_s": 108,
"evidence": {
"actions": [
{
"by": "fixture",
"channel": "button",
"state": "press",
"took_s": 5.26,
"ts": "2026-09-28T18:07:10Z"
}
],
"armed_after": false,
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T18:03:13Z"
},
"camera_after_window": {
"bytes": 226052,
"status": 200
},
"camera_in_window": {
"said": "a job is armed: a background capture waits until the window closes",
"status": 409
},
"events": [
"print:starting",
"print:download:completed",
"button:pressed",
"print:warmup:starting",
"button:released",
"print:running",
"print:return_to_home:succeeded",
"print:completed"
],
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"freeze_lag_s": 0.43,
"freeze_led_the_run_s": 4.8,
"jobs": {
"dark.puls": {
"compressed": false,
"payload_bytes": 324236,
"seconds": 32.4
}
},
"latch_locked_after": true,
"latch_locked_at_button": true,
"latch_locked_in_run": false,
"print finished": "INFO basemachine:_finish_action print [9005]: finished with event \":completed\"",
"samples": {
"all": 266,
"inside": 171,
"not_frozen_inside": 0
},
"thaw_lag_s": 0.62,
"window_s": 37.6
},
"fingerprint": "8a1ab8681ddcc95192eaf56b7c2f74f741303e7c9ca7c03220fdb88e4f34ac63",
"image": "20260928175056 (dev)",
"log": [
"18:06:28 start exthost.armed-freeze (operator, takeover) in campaign c-20260928180313-75fb",
"18:06:28 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"18:06:28 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"18:06:28 fixture: running unattended (no prompt can be answered)",
"18:06:28 queued by the unattended queue opened 2026-09-28T18:03:13Z",
"18:06:29 baseline: pre: clean",
"18:06:34 cloud mode: restarting the client offline (was pid 1855)",
"18:06:38 offline service up: INFO offline:open OFFLINE service: no web session; listening on /run/gfcloud-offline.sock",
"18:06:59 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"18:07:08 job dark.puls: 324236 payload bytes, 32 s at STfr 10000",
"18:07:10 ACT button press (fixture)",
"18:07:15 ACT button press: done after 5.3 s",
"18:07:29 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"18:07:58 PASS: locked at the button, unlocked for the run, locked after it; the print completed",
"18:08:01 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"18:08:04 offline jobs removed from /tmp/forgetest",
"18:08:05 a background capture inside the window -> 409 (a job is armed: a background capture waits until the window closes); after it -> 200, 226052 bytes",
"18:08:05 the armed window was open 37.6 s; frozen 0.43 s after it opened and 4.80 s before the latch unlocked for the run, in every one of 171 samples from 2 s in to the close, the heartbeat still; thawed 0.62 s after the close",
"18:08:05 remove org.forgetest.reference -> ok",
"18:08:05 restore ext_enabled='1' -> 200",
"18:08:05 takeover: waiting for forgectrl to be settled",
"18:08:05 baseline: /mode controller=running motion=verified",
"18:08:05 takeover: preserving cnc/motor_lock=8, cnc/step_freq=10000, cnc/ramp_rate=125000, cnc/streaming=0, cnc/x_mode=8, cnc/y_mode=8, cnc/x_decay=1, cnc/y_decay=1, pic/x_step_current=33, pic/y_step_current=5",
"18:08:05 takeover: the cloud client is the offline service (pid 1949); forgectrl's start brings it back offline",
"18:08:05 takeover: stopping the controller through forgectrl",
"18:08:06 takeover: POST /controller/stop -> 200",
"18:08:06 takeover: forgectrl stop -> rc 0",
"18:08:08 takeover: pulse device free",
"18:08:08 takeover: forgectrl start -> rc 0",
"18:08:10 baseline: /mode controller=stopped motion=unverified",
"18:08:15 baseline: /mode controller=running motion=verified",
"18:08:17 takeover: the cloud client is back as the offline service (pid 2676)",
"18:08:17 the previous record is back under a restart",
"18:08:17 baseline: post: clean",
"18:08:17 result PASS"
],
"manifest_sha": "0946700866975cd7ed6b5cc6c6fd0dadc033a8ab5d820a9bea37ca92b7e64368",
"message": "",
"result": "PASS",
"test": "exthost.armed-freeze",
"ts": "2026-09-28T18:08:17Z"
},
"requires": [
"exthost.service",
"cloud.dark-print"
],
"satisfied": true,
"source_sha": "0cd9699fd5d80c873c3fe20d1f6dd1a34da15c70d8568dfd5ba20b305048bc14",
"subsystem": "exthost",
"title": "A package's service is frozen for the armed window"
},
{
"always": false,
"covers": [
[
"forgeext",
"src/holdkeep.*"
],
[
"forgeext",
"src/run.*"
],
[
"forgeext",
"src/install.*"
],
[
"forgeext",
"src/state.*"
],
[
"forgeext",
"src/main.c"
],
[
"forgectrl",
"src/holds.*"
],
[
"forgectrl",
"src/cool.*"
]
],
"fingerprint": "108841d724e71c42843bd90ba00a31cc472c43b795ca5ba099fc53c992e8367e",
"hardware": "takeover",
"id": "exthost.hold-pause-tier",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928180313-75fb",
"duration_s": 99,
"evidence": {
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T18:03:13Z"
},
"ext_off_released_s": 1.0,
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"held": {
"after_s": 1.0,
"cool": {
"fire_ok": false,
"hold": true,
"reason": "org.forgetest.reference: the extension is not running",
"verdict": "EXT"
},
"hold_file": {
"age": 0.42928993000003857,
"id": "org.forgetest.reference",
"raised": true,
"reason": "the extension is not running",
"required": true,
"ts_mono": 441.827767436
}
},
"host_suspended": {
"fire_ok": false,
"reason": "org.forgetest.reference: the extension host is not answering",
"verdict": "EXT"
},
"install_without_the_grant": "the package asks for what only the operator grants: hold",
"looks_over_the_crash_loop": [
[
"EXT",
false
]
],
"raised_by_the_package": {
"after_s": 0.8,
"cool": {
"fire_ok": false,
"hold": true,
"reason": "org.forgetest.reference: no badge presented",
"verdict": "EXT"
}
},
"running": {
"hold_file": {
"age": 0.35457666700000345,
"id": "org.forgetest.reference",
"raised": true,
"reason": "the extension has only just started",
"required": true,
"ts_mono": 380.77900171
},
"status_hold": "required",
"verdict": "EXT"
},
"safe_mode_released_s": 0.8,
"verdict_at_start": {
"fire_ok": true,
"hold": false,
"reason": "",
"verdict": "OK"
}
},
"fingerprint": "108841d724e71c42843bd90ba00a31cc472c43b795ca5ba099fc53c992e8367e",
"image": "20260928175056 (dev)",
"log": [
"18:08:17 start exthost.hold-pause-tier (auto, takeover) in campaign c-20260928180313-75fb",
"18:08:17 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"18:08:17 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"18:08:17 queued by the unattended queue opened 2026-09-28T18:03:13Z",
"18:08:18 baseline: pre: clean",
"18:08:48 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"18:09:18 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"18:09:20 the package raised its hold: {'after_s': 0.8, 'cool': {'verdict': 'EXT', 'fire_ok': False, 'hold': True, 'reason': 'org.forgetest.reference: no badge presented'}}",
"18:09:23 the service ends at every start: {'after_s': 1.0, 'cool': {'verdict': 'EXT', 'fire_ok': False, 'hold': True, 'reason': 'org.forgetest.reference: the extension is not running'}, 'hold_file': {'id': 'org.forgetest.reference', 'required': True, 'raised': True, 'reason': 'the extension is not running', 'ts_mono': 441.827767436, 'age': 0.42928993000003857}}",
"18:09:45 PASS: held in 1.0 s; safe mode released it in 0.8 s, extensions off in 1.0 s",
"18:09:45 remove org.forgetest.reference -> ok",
"18:09:45 restore ext_enabled='1' -> 200",
"18:09:45 takeover: waiting for forgectrl to be settled",
"18:09:45 baseline: /mode controller=running motion=verified",
"18:09:45 takeover: preserving cnc/motor_lock=0, cnc/step_freq=10000, cnc/ramp_rate=125000, cnc/streaming=0, cnc/x_mode=8, cnc/y_mode=8, cnc/x_decay=1, cnc/y_decay=1, pic/x_step_current=33, pic/y_step_current=33",
"18:09:45 takeover: the cloud client is the offline service (pid 2676); forgectrl's start brings it back offline",
"18:09:45 takeover: stopping the controller through forgectrl",
"18:09:46 takeover: POST /controller/stop -> 200",
"18:09:46 takeover: forgectrl stop -> rc 0",
"18:09:48 takeover: pulse device free",
"18:09:48 takeover: forgectrl start -> rc 0",
"18:09:49 baseline: /mode controller=stopped motion=unverified",
"18:09:50 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"18:09:55 baseline: /mode controller=running motion=verified",
"18:09:57 takeover: the cloud client is back as the offline service (pid 3507)",
"18:09:57 the previous record is back under a restart",
"18:09:57 baseline: post: clean",
"18:09:57 result PASS"
],
"manifest_sha": "0946700866975cd7ed6b5cc6c6fd0dadc033a8ab5d820a9bea37ca92b7e64368",
"message": "",
"result": "PASS",
"test": "exthost.hold-pause-tier",
"ts": "2026-09-28T18:09:57Z"
},
"requires": [
"exthost.service"
],
"satisfied": true,
"source_sha": "cc8dd9857ad0eb67cb2ee4c723ec04040cd627f49f9d3d0892f0066dc8a0f144",
"subsystem": "exthost",
"title": "A package's hold withholds fire, and the operator's exits end it"
},
{
"always": false,
"covers": [
[
"forgeext",
"src/evfeed.*"
],
[
"forgeext",
"src/api.*"
],
[
"forgeext",
"src/run.*"
],
[
"forgectrl",
"src/events.*"
],
[
"forgectrl",
"src/main.c"
]
],
"fingerprint": "ea86b13965849219e5ffdd14c58b6086e6a7dc046db38cc0737d211239dd6f8c",
"hardware": "takeover",
"id": "exthost.events",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928180313-75fb",
"duration_s": 21,
"evidence": {
"actions": [
{
"by": "fixture",
"channel": "lid",
"state": "open",
"took_s": 0.02,
"ts": "2026-09-28T18:10:04Z"
},
{
"by": "fixture",
"channel": "lid",
"state": "close",
"took_s": 0.28,
"ts": "2026-09-28T18:10:04Z"
}
],
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T18:03:13Z"
},
"feed_with_a_reader": {
"connected": true,
"wanted": 1
},
"feed_with_no_reader": {
"connected": false,
"wanted": 0
},
"first_polls": [
{
"got": 0,
"placed": false,
"status": 200,
"took": 0.0
},
{
"got": 0,
"placed": true,
"status": 200,
"took": 2.0
}
],
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"fourth_ordinary_stream": [
503,
"every event stream is taken (3 in all): fan out from one client"
],
"lan_claims_the_host_slot": [
503,
"every event stream is taken (3 in all): fan out from one client"
],
"lid_event": {
"after_s": 0.55,
"place": 13,
"seen": [
"lid"
]
},
"ordinary_streams": [
200,
200,
200
],
"polls_after": [
{
"got": 0,
"placed": false,
"status": 200,
"took": 0.0
},
{
"got": 0,
"placed": true,
"status": 200,
"took": 2.0
},
{
"got": 1,
"placed": true,
"status": 200,
"took": 0.0
},
{
"got": 1,
"placed": true,
"status": 200,
"took": 0.0
}
]
},
"fingerprint": "ea86b13965849219e5ffdd14c58b6086e6a7dc046db38cc0737d211239dd6f8c",
"image": "20260928175056 (dev)",
"log": [
"18:09:57 start exthost.events (auto, takeover) in campaign c-20260928180313-75fb",
"18:09:58 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"18:09:58 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"18:09:58 queued by the unattended queue opened 2026-09-28T18:03:13Z",
"18:09:58 baseline: pre: clean",
"18:09:59 the host's subscription: {'connected': True, 'wanted': 1}",
"18:10:04 ACT lid open (fixture)",
"18:10:04 ACT lid open: done after 0.0 s",
"18:10:04 the lid reached the package after 0.55 s: ['lid']",
"18:10:04 ACT lid close (fixture)",
"18:10:05 ACT lid close: done after 0.3 s",
"18:10:05 a LAN client asking for the host's slot -> 503 every event stream is taken (3 in all): fan out from one client",
"18:10:07 remove org.forgetest.reference -> ok",
"18:10:07 restore ext_enabled='1' -> 200",
"18:10:07 takeover: waiting for forgectrl to be settled",
"18:10:07 baseline: /mode controller=running motion=verified",
"18:10:07 takeover: preserving cnc/motor_lock=0, cnc/step_freq=10000, cnc/ramp_rate=125000, cnc/streaming=0, cnc/x_mode=8, cnc/y_mode=8, cnc/x_decay=1, cnc/y_decay=1, pic/x_step_current=33, pic/y_step_current=33",
"18:10:07 takeover: the cloud client is the offline service (pid 3507); forgectrl's start brings it back offline",
"18:10:07 takeover: stopping the controller through forgectrl",
"18:10:08 takeover: POST /controller/stop -> 200",
"18:10:08 takeover: forgectrl stop -> rc 0",
"18:10:10 takeover: pulse device free",
"18:10:10 takeover: forgectrl start -> rc 0",
"18:10:12 baseline: /mode controller=stopped motion=unverified",
"18:10:17 baseline: /mode controller=running motion=verified",
"18:10:19 takeover: the cloud client is back as the offline service (pid 3711)",
"18:10:19 the previous record is back under a restart",
"18:10:19 baseline: post: clean",
"18:10:19 result PASS"
],
"manifest_sha": "0946700866975cd7ed6b5cc6c6fd0dadc033a8ab5d820a9bea37ca92b7e64368",
"message": "",
"result": "PASS",
"test": "exthost.events",
"ts": "2026-09-28T18:10:19Z"
},
"requires": [
"exthost.service"
],
"satisfied": true,
"source_sha": "881d66e5d92193f1113d9561f712040040aa5bf622c480d811768067b466a54a",
"subsystem": "exthost",
"title": "The machine's events reach a package, over one subscription"
},
{
"always": false,
"covers": [
[
"forgeext",
"src/api.*"
],
[
"forgeext",
"src/machine.*"
],
[
"forgeext",
"src/run.*"
],
[
"forgectrl",
"src/tokens.*"
],
[
"forgectrl",
"src/auth.*"
],
[
"forgectrl",
"src/main.c"
],
[
"forgectrl",
"src/grblport.*"
]
],
"fingerprint": "c816ae5554f0bfba33e6a4c83a3ecbcfb603ee5239f061946c0e52154cc8b0f0",
"hardware": "takeover",
"id": "exthost.motion-jog",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928180313-75fb",
"duration_s": 19,
"evidence": {
"accel": {
"p2p_x": 342,
"p2p_y": 312,
"samples": 4
},
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T18:03:13Z"
},
"credential_beyond_its_grant": [
403,
{
"error": "authentication required"
}
],
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"host_credential": {
"gid": 0,
"mode": "0600",
"uid": 0
},
"jog": [
200,
{
"ok": true
}
],
"jog_past_the_bounds": [
400,
{
"error": "one jog moves X and Y at most 100 mm"
}
],
"laser": {
"after": {
"emission_samples": 0,
"locked": true
},
"before": {
"emission_samples": 0,
"locked": true
}
},
"mode": {
"detail": "grbl mode up",
"found": "cloud",
"needs": "grbl",
"ok": true,
"switched": true
}
},
"fingerprint": "c816ae5554f0bfba33e6a4c83a3ecbcfb603ee5239f061946c0e52154cc8b0f0",
"image": "20260928175056 (dev)",
"log": [
"18:10:19 start exthost.motion-jog (auto, takeover) in campaign c-20260928180313-75fb",
"18:10:19 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"18:10:19 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"18:10:19 queued by the unattended queue opened 2026-09-28T18:03:13Z",
"18:10:20 baseline: pre: clean",
"18:10:20 baseline: switching to grbl mode (found cloud, controller running)",
"18:10:21 baseline: /mode controller=running motion=verified",
"18:10:21 mode: test needs grbl - grbl mode up",
"18:10:28 the package jogged X 20 mm: accel p2p x=342 y=312 over 4 samples",
"18:10:28 the laser across the jog: {'before': {'locked': True, 'emission_samples': 0}, 'after': {'locked': True, 'emission_samples': 0}}",
"18:10:30 remove org.forgetest.reference -> ok",
"18:10:30 restore ext_enabled='1' -> 200",
"18:10:30 takeover: waiting for forgectrl to be settled",
"18:10:30 baseline: /mode controller=running motion=verified",
"18:10:30 takeover: preserving cnc/motor_lock=0, cnc/step_freq=112640, cnc/ramp_rate=500000, cnc/streaming=0, cnc/x_mode=32, cnc/y_mode=32, cnc/x_decay=1, cnc/y_decay=1, pic/x_step_current=33, pic/y_step_current=5",
"18:10:30 takeover: stopping the controller through forgectrl",
"18:10:30 takeover: POST /controller/stop -> 200",
"18:10:30 takeover: forgectrl stop -> rc 0",
"18:10:32 takeover: pulse device free",
"18:10:32 takeover: forgectrl start -> rc 0",
"18:10:34 baseline: /mode controller=stopped motion=unverified",
"18:10:39 baseline: /mode controller=running motion=verified",
"18:10:39 the previous record is back under a restart",
"18:10:39 baseline: post: clean",
"18:10:39 result PASS"
],
"manifest_sha": "0946700866975cd7ed6b5cc6c6fd0dadc033a8ab5d820a9bea37ca92b7e64368",
"message": "",
"result": "PASS",
"test": "exthost.motion-jog",
"ts": "2026-09-28T18:10:39Z"
},
"requires": [
"exthost.service"
],
"satisfied": true,
"source_sha": "e9da931956f9dbb590f93e27319698dff71a3ea2079a7ceb6fe912a46190a7bd",
"subsystem": "exthost",
"title": "A package jogs the machine, bounded and dark"
},
{
"always": false,
"covers": [
[
"forgeext",
"src/install.*"
],
[
"forgeext",
"src/main.c"
],
[
"forgectrl",
"src/extpkg.*"
],
[
"forgectrl",
"src/main.c"
]
],
"fingerprint": "bc97a14aa6f3fef69528e8a219934d375d83fa9adc864f0cdea6fc1fa6ce014d",
"hardware": "api",
"id": "exthost.ui-delivery",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928180313-75fb",
"duration_s": 8,
"evidence": {
"asks_without_the_file": "this package asks for ui and has no ui/index.html",
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T18:03:13Z"
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"settings": [
200,
{
"note": "",
"threshold": 40.0,
"when": "end"
}
],
"settings_refused": [
400,
"\"threshold\" is at most 100"
],
"ships_without_asking": "this package has a ui/index.html and does not ask for ui",
"ui": {
"bytes": 90,
"status": 200
},
"ui_absent": [
404,
"that package is not installed"
],
"ui_disabled": [
404,
"this package is disabled: its interface is not served"
]
},
"fingerprint": "bc97a14aa6f3fef69528e8a219934d375d83fa9adc864f0cdea6fc1fa6ce014d",
"image": "20260928175056 (dev)",
"log": [
"18:10:39 start exthost.ui-delivery (auto, api) in campaign c-20260928180313-75fb",
"18:10:39 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"18:10:39 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"18:10:39 queued by the unattended queue opened 2026-09-28T18:03:13Z",
"18:10:40 baseline: pre: clean",
"18:10:40 GET /ext/ui -> 200, 90 bytes",
"18:10:40 POST /ext/settings, a threshold over its bound -> 400 \"threshold\" is at most 100",
"18:10:40 remove org.forgetest.reference -> ok",
"18:10:40 restore ext_enabled='1' -> 200",
"18:10:40 takeover: waiting for forgectrl to be settled",
"18:10:40 baseline: /mode controller=running motion=verified",
"18:10:40 takeover: preserving cnc/motor_lock=0, cnc/step_freq=112640, cnc/ramp_rate=500000, cnc/streaming=0, cnc/x_mode=32, cnc/y_mode=32, cnc/x_decay=1, cnc/y_decay=1, pic/x_step_current=33, pic/y_step_current=5",
"18:10:40 takeover: stopping the controller through forgectrl",
"18:10:41 takeover: POST /controller/stop -> 200",
"18:10:41 takeover: forgectrl stop -> rc 0",
"18:10:41 takeover: pulse device free",
"18:10:41 takeover: forgectrl start -> rc 0",
"18:10:43 baseline: /mode controller=stopped motion=unverified",
"18:10:48 baseline: /mode controller=running motion=verified",
"18:10:48 the previous record is back under a restart",
"18:10:48 baseline: post: clean",
"18:10:48 result PASS"
],
"manifest_sha": "0946700866975cd7ed6b5cc6c6fd0dadc033a8ab5d820a9bea37ca92b7e64368",
"message": "",
"result": "PASS",
"test": "exthost.ui-delivery",
"ts": "2026-09-28T18:10:48Z"
},
"requires": [
"exthost.service"
],
"satisfied": true,
"source_sha": "5ac92e8740488ea4825a985695be34b4544b1ecb61d25a3264f70de8d61cabeb",
"subsystem": "exthost",
"title": "A package's interface is served, and only when it has one"
},
{
"always": false,
"covers": [
[
"forgeext",
"src/api.*"
],
[
"forgeext",
"src/machine.*"
],
[
"forgeext",
"src/run.*"
],
[
"forgectrl",
"src/jobpost.*"
],
[
"forgectrl",
"src/jobrun.*"
],
[
"forgectrl",
"src/tokens.*"
]
],
"fingerprint": "f49452c1542b5ca54c0f3f7232baa03ac7e6997eb7297360888aa70c5f48cd37",
"hardware": "takeover",
"id": "exthost.motion-job",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928180313-75fb",
"duration_s": 18,
"evidence": {
"a_program_that_is_not_there": [
400,
{
"error": "that program is not a file of this package's data"
}
],
"a_program_with_a_path": [
400,
{
"error": "program is a file name in this package's data, with no directory in it"
}
],
"accel": {
"p2p_x": 2879,
"p2p_y": 553,
"samples": 11
},
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T18:03:13Z"
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"job": [
200,
{
"acked": 0,
"elapsed_s": 0,
"emission": {
"hv_max": 0,
"laser_on_samples": 0,
"lit_s": 0.0,
"samples": 0,
"thermopile_delta": 0
},
"lines": 6,
"lit": false,
"owner": "job:org.forgetest.reference",
"program": true,
"reason": "",
"sent": 0,
"state": "running"
}
],
"job_end": {
"acked": 6,
"emission": {
"hv_max": 0,
"laser_on_samples": 0,
"lit_s": 0.0,
"samples": 62,
"thermopile_delta": 0
},
"lit": false,
"reason": "the program ended without a discharge",
"sent": 6,
"state": "failed"
},
"job_record": {
"lines": 6,
"owner": "job:org.forgetest.reference",
"state": "running"
},
"laser": {
"after": {
"emission": 0,
"locked": true
},
"before": {
"emission": 0,
"locked": true
}
},
"mode": {
"detail": "already in grbl mode",
"found": "grbl",
"needs": "grbl",
"ok": true,
"switched": false
}
},
"fingerprint": "f49452c1542b5ca54c0f3f7232baa03ac7e6997eb7297360888aa70c5f48cd37",
"image": "20260928175056 (dev)",
"log": [
"18:10:48 start exthost.motion-job (auto, takeover) in campaign c-20260928180313-75fb",
"18:10:48 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"18:10:48 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"18:10:48 queued by the unattended queue opened 2026-09-28T18:03:13Z",
"18:10:48 baseline: pre: clean",
"18:10:48 mode: test needs grbl - already in grbl mode",
"18:10:54 the machine's job record: {'state': 'running', 'owner': 'job:org.forgetest.reference', 'lines': 6}",
"18:10:57 the job ended: {'state': 'failed', 'reason': 'the program ended without a discharge', 'lit': False, 'sent': 6, 'acked': 6, 'emission': {'samples': 62, 'hv_max': 0, 'laser_on_samples': 0, 'thermopile_delta': 0, 'lit_s': 0.0}}",
"18:10:58 the package's job moved the head: accel p2p x=2879 y=553 over 11 samples",
"18:10:58 the laser across the package's job: {'before': {'locked': True, 'emission': 0}, 'after': {'locked': True, 'emission': 0}}",
"18:10:58 remove org.forgetest.reference -> ok",
"18:10:58 restore ext_enabled='1' -> 200",
"18:10:58 takeover: waiting for forgectrl to be settled",
"18:10:58 baseline: /mode controller=running motion=verified",
"18:10:58 takeover: preserving cnc/motor_lock=0, cnc/step_freq=112640, cnc/ramp_rate=500000, cnc/streaming=0, cnc/x_mode=32, cnc/y_mode=32, cnc/x_decay=1, cnc/y_decay=1, pic/x_step_current=33, pic/y_step_current=5",
"18:10:58 takeover: stopping the controller through forgectrl",
"18:10:58 takeover: POST /controller/stop -> 200",
"18:10:58 takeover: forgectrl stop -> rc 0",
"18:10:59 takeover: pulse device free",
"18:10:59 takeover: forgectrl start -> rc 0",
"18:11:01 baseline: /mode controller=stopped motion=unverified",
"18:11:06 baseline: /mode controller=running motion=verified",
"18:11:06 the previous record is back under a restart",
"18:11:06 baseline: post: clean",
"18:11:06 result PASS"
],
"manifest_sha": "0946700866975cd7ed6b5cc6c6fd0dadc033a8ab5d820a9bea37ca92b7e64368",
"message": "",
"result": "PASS",
"test": "exthost.motion-job",
"ts": "2026-09-28T18:11:06Z"
},
"requires": [
"exthost.service",
"motion.job"
],
"satisfied": true,
"source_sha": "cffb3b1dc8ebfd67fc00a4efce3ab41b3f14b57c88417b51a9fac8c0ebbfdc7f",
"subsystem": "exthost",
"title": "A package runs a program, under every gate a sender is under"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/extpkg.*"
],
[
"forgectrl",
"src/main.c"
],
[
"forgectrl",
"src/ui/ext.js"
],
[
"forgectrl",
"src/ui/index.html"
],
[
"forgectrl",
"src/ui/embed.cmake"
],
[
"forgeext",
"src/main.c"
],
[
"forgeext",
"src/install.*"
],
[
"forgeext",
"src/state.*"
]
],
"fingerprint": "ed88be07f68e8d5208d27368826b9dcc272a09abdaef00cc497c5afa3fb5f0f7",
"hardware": "api",
"id": "exthost.package-routes",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928180313-75fb",
"duration_s": 2,
"evidence": {
"a package that is not installed": 409,
"an action outside the list": 400,
"an action with a shell's words": 400,
"an id that has not the form of one": 400,
"an id with a path in it": 400,
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T18:03:13Z"
},
"capabilities": {
"asked": [
"camera.lid",
"hold",
"machine.read",
"net.outbound:<IP-1>:443",
"settings.own",
"storage:1"
],
"effective": [
"camera.lid",
"hold",
"machine.read",
"net.outbound:<IP-1>:443",
"settings.own",
"storage:1"
],
"granted": [
"hold"
]
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-2>",
"released": []
},
"host": {
"enabled": true,
"off_reason": "",
"pid": 1762,
"running": true
},
"package": {
"account": "ffx0",
"enabled": true,
"grants": [
"hold"
],
"hold": "advisory",
"quarantined": false,
"tier": "community"
},
"panel_page_bytes": 562369,
"status": {
"enabled": true,
"safe_mode": false
},
"status_without_login": 403
},
"fingerprint": "ed88be07f68e8d5208d27368826b9dcc272a09abdaef00cc497c5afa3fb5f0f7",
"image": "20260928175056 (dev)",
"log": [
"18:11:06 start exthost.package-routes (auto, api) in campaign c-20260928180313-75fb",
"18:11:06 fixture up: <REDACTED-1> at <IP-2>, v1.0.0, covers lid, interlock, button",
"18:11:06 fixture: <REDACTED-1> at <IP-2> covers lid, interlock, button",
"18:11:06 queued by the unattended queue opened 2026-09-28T18:03:13Z",
"18:11:07 baseline: pre: clean",
"18:11:07 GET /ext/status: {'enabled': True, 'safe_mode': False}, host {'running': True, 'pid': 1762, 'enabled': True, 'off_reason': ''}, package {'tier': 'community', 'enabled': True, 'quarantined': False, 'grants': ['hold'], 'hold': 'advisory', 'account': 'ffx0'}",
"18:11:07 the reference package asked for ['camera.lid', 'hold', 'machine.read', 'net.outbound:<IP-1>:443', 'settings.own', 'storage:1'], may use ['camera.lid', 'hold', 'machine.read', 'net.outbound:<IP-1>:443', 'settings.own', 'storage:1']",
"18:11:07 POST /ext/package, an action outside the list -> 400 action is enable, disable, remove, remove-keep-data, hold-required, or hold-advisory",
"18:11:07 POST /ext/package, an action with a shell's words -> 400 action is enable, disable, remove, remove-keep-data, hold-required, or hold-advisory",
"18:11:07 POST /ext/package, an id that has not the form of one -> 400 id is a package id",
"18:11:07 POST /ext/package, an id with a path in it -> 400 id is a package id",
"18:11:07 POST /ext/package, a package that is not installed -> 409 org.forgetest.nothere is not installed",
"18:11:09 baseline: cool: idle/armed=False/hold=True was the engine's last word on the run; its next tick reads idle/armed=False/hold=False",
"18:11:09 baseline: post: clean",
"18:11:09 result PASS"
],
"manifest_sha": "0946700866975cd7ed6b5cc6c6fd0dadc033a8ab5d820a9bea37ca92b7e64368",
"message": "",
"result": "PASS",
"test": "exthost.package-routes",
"ts": "2026-09-28T18:11:09Z"
},
"requires": [
"exthost.service",
"forgectrl.auth"
],
"satisfied": true,
"source_sha": "249b8372bda02eb9623f8013f4988841549ad847ad8421a03eaf2a5e6dc588ca",
"subsystem": "exthost",
"title": "The panel's package routes are the extension host's own word"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/extpkg.*"
],
[
"forgectrl",
"src/main.c"
],
[
"forgectrl",
"src/auth.*"
],
[
"forgeext",
"src/main.c"
],
[
"forgeext",
"src/install.*"
],
[
"forgeext",
"src/pkg.*"
]
],
"fingerprint": "85d16c8f4b50b01fd50bad24672f4b88d17553d775d1538b9b838a00ebe63a9b",
"hardware": "api",
"id": "exthost.panel-install",
"inherited": true,
"kind": "operator",
"record": {
"answers": [],
"campaign": "c-20260928180313-75fb",
"duration_s": 3,
"evidence": {
"a grant that is an option": 400,
"a grant with a shell's words": 400,
"a key that is no key": 409,
"a name that is a path": 400,
"a name with a space": 400,
"actions": [
{
"by": "fixture",
"channel": "button",
"state": "press",
"took_s": 0.64,
"ts": "2026-09-28T18:11:10Z"
},
{
"by": "fixture",
"channel": "button",
"state": "press",
"took_s": 0.35,
"ts": "2026-09-28T18:11:10Z"
}
],
"after_the_key_went": "unverified",
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T18:03:13Z"
},
"community_upload": {
"consent": "typed",
"needs_grant": [
"hold"
],
"tier": "community"
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"key_without_the_button": [
409,
"a key you add is what this machine will trust: hold the machine's button while you add it"
],
"keys": {
"forgetest-reference": "<HEX-1>"
},
"mode": {
"detail": "already in grbl mode",
"found": "grbl",
"needs": "grbl",
"ok": true,
"switched": false
},
"no key at all": 400,
"no phrase": 400,
"not_an_archive": [
400,
"not an extension archive (Unrecognized archive format)"
],
"the phrase and no grant": 409,
"the phrase in another case": 400,
"unverified_installed": {
"enabled": true,
"grants": [
"hold"
],
"hold": "advisory",
"tier": "unverified"
},
"unverified_upload": {
"consent": "button",
"needs_grant": [
"hold"
],
"tier": "unverified"
},
"unverified_without_the_button": [
409,
"nobody the machine trusts signed this package: hold the machine's button while you install it"
]
},
"fingerprint": "85d16c8f4b50b01fd50bad24672f4b88d17553d775d1538b9b838a00ebe63a9b",
"image": "20260928175056 (dev)",
"log": [
"18:11:09 start exthost.panel-install (operator, api) in campaign c-20260928180313-75fb",
"18:11:09 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"18:11:09 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"18:11:09 fixture: running unattended (no prompt can be answered)",
"18:11:09 queued by the unattended queue opened 2026-09-28T18:03:13Z",
"18:11:09 baseline: pre: clean",
"18:11:09 mode: test needs grbl - already in grbl mode",
"18:11:09 an upload that is no archive -> 400 not an extension archive (Unrecognized archive format)",
"18:11:09 the upload, its key unknown to the machine -> 200 {'tier': 'unverified', 'consent': 'button', 'needs_grant': ['hold']}",
"18:11:10 ACT button press (fixture)",
"18:11:10 ACT button press: done after 0.6 s",
"18:11:10 with the button held: [200, 'ok'], listed {'tier': 'unverified', 'grants': ['hold'], 'hold': 'advisory', 'enabled': True}",
"18:11:10 ACT button press (fixture)",
"18:11:11 ACT button press: done after 0.4 s",
"18:11:11 with the button held: [200, 'ok'], the keys now ['forgetest-reference']",
"18:11:11 POST /ext/install, no phrase -> 400 this package is signed by a key you added, not by OpenGlow: type I UNDERSTAND to install it",
"18:11:11 POST /ext/install, the phrase in another case -> 400 this package is signed by a key you added, not by OpenGlow: type I UNDERSTAND to install it",
"18:11:11 POST /ext/install, the phrase and no grant -> 409 the package asks for what only the operator grants: hold",
"18:11:11 POST /ext/install, a grant with a shell's words -> 400 grants is a comma-separated list of at most 8 capability names",
"18:11:11 POST /ext/install, a grant that is an option -> 400 grants is a comma-separated list of at most 8 capability names",
"18:11:12 baseline: post: clean",
"18:11:12 result PASS"
],
"manifest_sha": "0946700866975cd7ed6b5cc6c6fd0dadc033a8ab5d820a9bea37ca92b7e64368",
"message": "",
"result": "PASS",
"test": "exthost.panel-install",
"ts": "2026-09-28T18:11:12Z"
},
"requires": [
"exthost.package-routes"
],
"satisfied": true,
"source_sha": "e9197d701d8d12dfb2221c3de7158f2f3d7617128e603bc0c8f62c87b939bc79",
"subsystem": "exthost",
"title": "A package is installed through the panel with the consent its tier takes"
},
{
"always": false,
"covers": [
[
"forgeext",
"src/install.*"
],
[
"forgeext",
"src/manifest.*"
],
[
"forgeext",
"src/main.c"
]
],
"fingerprint": "dcd892ba25eaf5ce1b3afacf1908e7e602d24b26b940ac0567e9a6eac85289dc",
"hardware": "api",
"id": "exthost.core-range",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928180313-75fb",
"duration_s": 1,
"evidence": {
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T18:03:13Z"
},
"firmware_version": {
"file": "20260928175056",
"looks_like_a_version": false,
"version": "20260928175056"
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"no_range": {
"bytes": 194,
"core_checked": false,
"downgrade": false,
"endorsed": false,
"files": 1,
"from_version": "",
"key": "<REDACTED-2>",
"needs_grant": [],
"new_capabilities": [],
"ok": true,
"package": {
"author": "forgetest",
"capabilities": [],
"description": "",
"id": "org.forgetest.corerange",
"license": "MIT",
"modes": [
"grbl",
"cloud"
],
"name": "forgetest core range",
"runtime": "data",
"version": "1.0.0"
},
"tier": "unverified",
"update": false,
"withdrawn": null
},
"ranges": [
{
"core": {
"min": "99.0.0"
},
"inspect": {
"bytes": 221,
"core_checked": false,
"downgrade": false,
"endorsed": false,
"files": 1,
"from_version": "",
"key": "<REDACTED-2>",
"needs_grant": [],
"new_capabilities": [],
"ok": true,
"package": {
"author": "forgetest",
"capabilities": [],
"description": "",
"id": "org.forgetest.corerange",
"license": "MIT",
"modes": [
"grbl",
"cloud"
],
"name": "forgetest core range",
"runtime": "data",
"version": "1.0.0"
},
"tier": "unverified",
"update": false,
"withdrawn": null
}
},
{
"core": {
"max": "0.0.1"
},
"inspect": {
"bytes": 220,
"core_checked": false,
"downgrade": false,
"endorsed": false,
"files": 1,
"from_version": "",
"key": "<REDACTED-2>",
"needs_grant": [],
"new_capabilities": [],
"ok": true,
"package": {
"author": "forgetest",
"capabilities": [],
"description": "",
"id": "org.forgetest.corerange",
"license": "MIT",
"modes": [
"grbl",
"cloud"
],
"name": "forgetest core range",
"runtime": "data",
"version": "1.0.0"
},
"tier": "unverified",
"update": false,
"withdrawn": null
}
},
{
"core": {
"max": "0.0.2",
"min": "0.0.1"
},
"inspect": {
"bytes": 236,
"core_checked": false,
"downgrade": false,
"endorsed": false,
"files": 1,
"from_version": "",
"key": "<REDACTED-2>",
"needs_grant": [],
"new_capabilities": [],
"ok": true,
"package": {
"author": "forgetest",
"capabilities": [],
"description": "",
"id": "org.forgetest.corerange",
"license": "MIT",
"modes": [
"grbl",
"cloud"
],
"name": "forgetest core range",
"runtime": "data",
"version": "1.0.0"
},
"tier": "unverified",
"update": false,
"withdrawn": null
}
}
]
},
"fingerprint": "dcd892ba25eaf5ce1b3afacf1908e7e602d24b26b940ac0567e9a6eac85289dc",
"image": "20260928175056 (dev)",
"log": [
"18:11:12 start exthost.core-range (auto, api) in campaign c-20260928180313-75fb",
"18:11:13 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"18:11:13 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"18:11:13 queued by the unattended queue opened 2026-09-28T18:03:13Z",
"18:11:13 baseline: pre: clean",
"18:11:13 /etc/forgefirm-version: '20260928175056' -> '20260928175056'",
"18:11:13 baseline: post: clean",
"18:11:13 result PASS"
],
"manifest_sha": "0946700866975cd7ed6b5cc6c6fd0dadc033a8ab5d820a9bea37ca92b7e64368",
"message": "",
"result": "PASS",
"test": "exthost.core-range",
"ts": "2026-09-28T18:11:13Z"
},
"requires": [],
"satisfied": true,
"source_sha": "5cf677e08a847f0a5ad0418a8d1617c34661ab59860db81afa0a6799466d721b",
"subsystem": "exthost",
"title": "The host reads the image's own version file and judges by it"
},
{
"always": false,
"covers": [
[
"forgeext",
"src/call.*"
],
[
"forgeext",
"src/run.*"
],
[
"forgeext",
"src/sandbox.*"
],
[
"forgeext",
"src/main.c"
],
[
"forgectrl",
"src/extpkg.*"
],
[
"forgectrl",
"src/main.c"
]
],
"fingerprint": "fda38fa9e2075fc55c6fab9c18d86eb472ce214d932ed2b05d10bae7a7300da9",
"hardware": "api",
"id": "exthost.page-call",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928180313-75fb",
"duration_s": 16,
"evidence": {
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T18:03:13Z"
},
"cli": {
"body": {
"body": {
"from": "the console"
},
"method": "POST",
"path": "/echo"
},
"id": "org.forgetest.reference",
"ok": true,
"status": 200
},
"disabled": [
409,
"this package is disabled: its service is not running"
],
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"get": [
200,
{
"body": {
"body": {},
"method": "GET",
"path": "/echo"
},
"id": "org.forgetest.reference",
"ok": true,
"status": 200
}
],
"inside": {
"call_env": "4",
"fds": {
"3": "closed",
"4": "socket",
"5": "closed"
},
"listening": 1
},
"me": [
200,
{
"body": "org.forgetest.reference",
"id": "org.forgetest.reference",
"ok": true,
"status": 200
}
],
"post": [
200,
{
"body": {
"body": {
"a": 1,
"b": "two"
},
"method": "POST",
"path": "/echo"
},
"id": "org.forgetest.reference",
"ok": true,
"status": 200
}
],
"refusals": [
[
[
"PUT",
"/echo"
],
400,
"a call is GET or POST"
],
[
[
"GET",
"/echo",
"{}"
],
400,
"a GET call has no body"
],
[
[
"POST",
"/echo",
"[1]"
],
400,
"a call's body is a JSON object of at most 4096 bytes"
],
[
[
"GET",
"/../etc"
],
409,
"a call's path starts with '/' and has only letters, digits, '/', '.', '-', and '_', at most 200 of them"
],
[
[
"GET",
"/echo",
null,
"org.forgetest.nothere"
],
409,
"that package is not installed"
]
],
"refuse": [
200,
{
"body": {
"error": "not now"
},
"id": "org.forgetest.reference",
"ok": true,
"status": 409
}
],
"socket": {
"dir": [
"0o700",
0
],
"sock": [
"0o600",
0
]
}
},
"fingerprint": "fda38fa9e2075fc55c6fab9c18d86eb472ce214d932ed2b05d10bae7a7300da9",
"image": "20260928175056 (dev)",
"log": [
"18:11:14 start exthost.page-call (auto, api) in campaign c-20260928180313-75fb",
"18:11:14 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"18:11:14 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"18:11:14 queued by the unattended queue opened 2026-09-28T18:03:13Z",
"18:11:14 baseline: pre: clean",
"18:11:16 inside: {'call_env': '4', 'fds': {'3': 'closed', '4': 'socket', '5': 'closed'}, 'listening': 1}",
"18:11:16 POST /ext/call /echo -> 200 {'body': {'body': {'a': 1, 'b': 'two'}, 'method': 'POST', 'path': '/echo'}, 'id': 'org.forgetest.reference', 'ok': True, 'status': 200}",
"18:11:21 remove org.forgetest.reference -> ok",
"18:11:21 restore ext_enabled='1' -> 200",
"18:11:21 takeover: waiting for forgectrl to be settled",
"18:11:21 baseline: /mode controller=running motion=verified",
"18:11:21 takeover: preserving cnc/motor_lock=0, cnc/step_freq=112640, cnc/ramp_rate=500000, cnc/streaming=0, cnc/x_mode=32, cnc/y_mode=32, cnc/x_decay=1, cnc/y_decay=1, pic/x_step_current=33, pic/y_step_current=5",
"18:11:21 takeover: stopping the controller through forgectrl",
"18:11:22 takeover: POST /controller/stop -> 200",
"18:11:22 takeover: forgectrl stop -> rc 0",
"18:11:22 takeover: pulse device free",
"18:11:22 takeover: forgectrl start -> rc 0",
"18:11:24 baseline: /mode controller=stopped motion=unverified",
"18:11:29 baseline: /mode controller=running motion=verified",
"18:11:29 the previous record is back under a restart",
"18:11:30 baseline: post: clean",
"18:11:30 result PASS"
],
"manifest_sha": "0946700866975cd7ed6b5cc6c6fd0dadc033a8ab5d820a9bea37ca92b7e64368",
"message": "",
"result": "PASS",
"test": "exthost.page-call",
"ts": "2026-09-28T18:11:30Z"
},
"requires": [
"exthost.service"
],
"satisfied": true,
"source_sha": "2e70e461f165ee0d00df531aa926285da26713f503d35ebd0d97e79d75b3d743",
"subsystem": "exthost",
"title": "A package's page asks its own service, through the panel"
},
{
"always": false,
"covers": [
[
"forgeext",
"src/install.*"
],
[
"forgeext",
"src/state.*"
],
[
"forgeext",
"src/run.*"
],
[
"forgeext",
"src/super.*"
],
[
"forgeext",
"src/api.*"
],
[
"forgeext",
"src/caps.*"
],
[
"forgeext",
"src/manifest.*"
],
[
"forgeext",
"src/netrules.*"
],
[
"forgeext",
"src/main.c"
],
[
"forgectrl",
"src/extpkg.*"
],
[
"forgectrl",
"src/main.c"
]
],
"fingerprint": "4875b08bdd916aa61091c18ed7818d5773de12a72f48d501fe37ff9ff4eb7f57",
"hardware": "api",
"id": "exthost.operator-destinations",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928180313-75fb",
"duration_s": 21,
"evidence": {
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T18:03:13Z"
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"named": {
"destinations": [
"<IP-2>:53"
],
"dial": "connected",
"dial_other_port": "EACCES",
"pid": 4810
},
"none_named": {
"destinations": [],
"dial": "EACCES",
"dial_other_port": "EACCES",
"pid": 4768
},
"refusals": [
[
"<IP-3>:80",
409,
"<IP-3> is this machine: no package reaches the machine"
],
[
"127.0.0.1:80",
409,
"127.0.0.1 is this machine: no package reaches the machine"
],
[
"--root",
400,
"a destination is host:port"
],
[
"<IP-2>",
409,
"a destination is host:port, the host a lowercase DNS name, an IPv4 address, or an IPv6 address in brackets"
],
[
"remove <IP-2>:53",
409,
"<IP-2>:53 is not one of the destinations the operator named for it"
]
],
"resolver": {
"address": "<IP-2>",
"tcp_53_from_root": true
},
"taken_away": {
"destinations": [],
"dial": "EACCES",
"dial_other_port": "EACCES",
"pid": 4844
}
},
"fingerprint": "4875b08bdd916aa61091c18ed7818d5773de12a72f48d501fe37ff9ff4eb7f57",
"image": "20260928175056 (dev)",
"log": [
"18:11:30 start exthost.operator-destinations (auto, api) in campaign c-20260928180313-75fb",
"18:11:30 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"18:11:30 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"18:11:30 queued by the unattended queue opened 2026-09-28T18:03:13Z",
"18:11:30 baseline: pre: clean",
"18:11:32 none named: {'pid': 4768, 'destinations': [], 'dial': 'EACCES', 'dial_other_port': 'EACCES'}",
"18:11:37 named: {'pid': 4810, 'destinations': ['<IP-2>:53'], 'dial': 'connected', 'dial_other_port': 'EACCES'}",
"18:11:43 remove org.forgetest.reference -> ok",
"18:11:43 restore ext_enabled='1' -> 200",
"18:11:43 takeover: waiting for forgectrl to be settled",
"18:11:43 baseline: /mode controller=running motion=verified",
"18:11:43 takeover: preserving cnc/motor_lock=0, cnc/step_freq=112640, cnc/ramp_rate=500000, cnc/streaming=0, cnc/x_mode=32, cnc/y_mode=32, cnc/x_decay=1, cnc/y_decay=1, pic/x_step_current=33, pic/y_step_current=5",
"18:11:43 takeover: stopping the controller through forgectrl",
"18:11:43 takeover: POST /controller/stop -> 200",
"18:11:43 takeover: forgectrl stop -> rc 0",
"18:11:44 takeover: pulse device free",
"18:11:44 takeover: forgectrl start -> rc 0",
"18:11:46 baseline: /mode controller=stopped motion=unverified",
"18:11:51 baseline: /mode controller=running motion=verified",
"18:11:51 the previous record is back under a restart",
"18:11:51 baseline: post: clean",
"18:11:51 result PASS"
],
"manifest_sha": "0946700866975cd7ed6b5cc6c6fd0dadc033a8ab5d820a9bea37ca92b7e64368",
"message": "",
"result": "PASS",
"test": "exthost.operator-destinations",
"ts": "2026-09-28T18:11:51Z"
},
"requires": [
"exthost.service"
],
"satisfied": true,
"source_sha": "6dfa3538f8a6f2ae2b9d4c628b386bd21cf0f6e77d031bbeca03de5f539a416d",
"subsystem": "exthost",
"title": "The operator names where a package may connect, and takes it away"
},
{
"always": false,
"covers": [
[
"forgeext",
"src/run.*"
],
[
"forgeext",
"src/machine.*"
],
[
"forgeext",
"src/evfeed.*"
],
[
"forgeext",
"src/api.*"
]
],
"fingerprint": "e0309af166fa254503cd7180bf88f6b54d7cfbb3c688c8704f224778364c2cd1",
"hardware": "api",
"id": "exthost.lifecycle",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928180313-75fb",
"duration_s": 14,
"evidence": {
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T18:03:13Z"
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"host_events": [
{
"data": {
"reason": "extensions are off (ext_enabled)"
},
"event": "ext.shutdown",
"t": 595.553423133
}
]
},
"fingerprint": "e0309af166fa254503cd7180bf88f6b54d7cfbb3c688c8704f224778364c2cd1",
"image": "20260928175056 (dev)",
"log": [
"18:11:52 start exthost.lifecycle (auto, api) in campaign c-20260928180313-75fb",
"18:11:52 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"18:11:52 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"18:11:52 queued by the unattended queue opened 2026-09-28T18:03:13Z",
"18:11:52 baseline: pre: clean",
"18:11:57 what it read: [{'event': 'ext.shutdown', 'data': {'reason': 'extensions are off (ext_enabled)'}, 't': 595.553423133}]",
"18:11:57 remove org.forgetest.reference -> ok",
"18:11:57 restore ext_enabled='1' -> 200",
"18:11:57 takeover: waiting for forgectrl to be settled",
"18:11:57 baseline: /mode controller=running motion=verified",
"18:11:57 takeover: preserving cnc/motor_lock=0, cnc/step_freq=112640, cnc/ramp_rate=500000, cnc/streaming=0, cnc/x_mode=32, cnc/y_mode=32, cnc/x_decay=1, cnc/y_decay=1, pic/x_step_current=33, pic/y_step_current=5",
"18:11:57 takeover: stopping the controller through forgectrl",
"18:11:58 takeover: POST /controller/stop -> 200",
"18:11:58 takeover: forgectrl stop -> rc 0",
"18:11:59 takeover: pulse device free",
"18:11:59 takeover: forgectrl start -> rc 0",
"18:12:00 baseline: /mode controller=stopped motion=unverified",
"18:12:06 baseline: /mode controller=running motion=verified",
"18:12:06 the previous record is back under a restart",
"18:12:06 baseline: post: clean",
"18:12:06 result PASS"
],
"manifest_sha": "0946700866975cd7ed6b5cc6c6fd0dadc033a8ab5d820a9bea37ca92b7e64368",
"message": "",
"result": "PASS",
"test": "exthost.lifecycle",
"ts": "2026-09-28T18:12:06Z"
},
"requires": [
"exthost.service"
],
"satisfied": true,
"source_sha": "93da2feaa621a1ef0277845421f44c8c2047747687ff287475efa0b7d0c313ca",
"subsystem": "exthost",
"title": "A package is told, in the feed it reads, before the host stops it"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/events.*"
],
[
"forgectrl",
"src/main.c"
],
[
"forgectrl",
"src/status.*"
]
],
"fingerprint": "f70cebe94c2262b853faeef74d7b2daee1ddcb144ecb465e4e1b11dcf620b536",
"hardware": "api",
"id": "events.button-telemetry",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928180313-75fb",
"duration_s": 12,
"evidence": {
"actions": [
{
"by": "fixture",
"channel": "button",
"state": "press",
"took_s": 0.25,
"ts": "2026-09-28T18:12:17Z"
}
],
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T18:03:13Z"
},
"button": [
{
"pressed": true
},
{
"pressed": false
}
],
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"mode": {
"detail": "already in grbl mode",
"found": "grbl",
"needs": "grbl",
"ok": true,
"switched": false
},
"telemetry": {
"down_c": 25.6,
"fire_ok": true,
"lid": "closed",
"phase": "idle",
"state": "Idle",
"up_c": 24.6,
"verdict": "OK"
}
},
"fingerprint": "f70cebe94c2262b853faeef74d7b2daee1ddcb144ecb465e4e1b11dcf620b536",
"image": "20260928175056 (dev)",
"log": [
"18:12:06 start events.button-telemetry (auto, api) in campaign c-20260928180313-75fb",
"18:12:07 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"18:12:07 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"18:12:07 queued by the unattended queue opened 2026-09-28T18:03:13Z",
"18:12:07 baseline: pre: clean",
"18:12:07 mode: test needs grbl - already in grbl mode",
"18:12:17 telemetry.tick: {'phase': 'idle', 'verdict': 'OK', 'fire_ok': True, 'down_c': 25.6, 'up_c': 24.6, 'state': 'Idle', 'lid': 'closed'}",
"18:12:17 ACT button press (fixture)",
"18:12:17 ACT button press: done after 0.3 s",
"18:12:17 button events: [{'pressed': True}, {'pressed': False}]",
"18:12:19 baseline: post: clean",
"18:12:19 result PASS"
],
"manifest_sha": "0946700866975cd7ed6b5cc6c6fd0dadc033a8ab5d820a9bea37ca92b7e64368",
"message": "",
"result": "PASS",
"test": "events.button-telemetry",
"ts": "2026-09-28T18:12:19Z"
},
"requires": [],
"satisfied": true,
"source_sha": "73d12bb2475ca43ecdaf2d1d06138c36df8d728b9e2f8faea10c0248c5eaa8c9",
"subsystem": "forgectrl",
"title": "The event stream tells a press of the button, and the telemetry"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/extpkg.*"
],
[
"forgectrl",
"src/main.c"
],
[
"forgeext",
"src/index.*"
],
[
"forgeext",
"src/pkg.*"
],
[
"forgeext",
"src/install.*"
],
[
"forgeext",
"src/main.c"
]
],
"fingerprint": "550d0f97b7ae24eaf3d0a36dcb4f69b5a38f2bf132489cc2d2f5b397d94e9da8",
"hardware": "api",
"id": "exthost.catalog",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928180313-75fb",
"duration_s": 1,
"evidence": {
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T18:03:13Z"
},
"endorsed": {
"endorsed": true,
"tier": "community"
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"get_unlisted": [
404,
"org.example.catprobe is not in the catalog"
],
"judged": {
"1.1.0": "asks for what this firmware does not have: forgetest.not-a-capability is not a capability",
"core_checked": false,
"offer": "1.0.0"
},
"kept_before": "2026.925.2",
"older": "the index is version 2026.923.1, older than the one kept here (2026.923.2): the catalog never goes back",
"refused": {
"a package as an index": "the archive's product is \"ForgeFIRM extension\", not \"ForgeFIRM extension index\"",
"the stand-in's index": "the index is not signed with the OpenGlow extension key"
},
"scratch_verify": {
"ok": true,
"packages": 1,
"version": "2026.923.2"
},
"withdrawn": "OpenGlow withdrew org.example.catprobe 1.0.0 from its catalog: forgetest withdrew it"
},
"fingerprint": "550d0f97b7ae24eaf3d0a36dcb4f69b5a38f2bf132489cc2d2f5b397d94e9da8",
"image": "20260928175056 (dev)",
"log": [
"18:12:19 start exthost.catalog (auto, api) in campaign c-20260928180313-75fb",
"18:12:19 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"18:12:19 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"18:12:19 queued by the unattended queue opened 2026-09-28T18:03:13Z",
"18:12:19 baseline: pre: clean",
"18:12:20 baseline: post: clean",
"18:12:20 result PASS"
],
"manifest_sha": "0946700866975cd7ed6b5cc6c6fd0dadc033a8ab5d820a9bea37ca92b7e64368",
"message": "",
"result": "PASS",
"test": "exthost.catalog",
"ts": "2026-09-28T18:12:20Z"
},
"requires": [],
"satisfied": true,
"source_sha": "67764cb41d41c739a5ddf14a4c8e5662d4f528f313e987b3019347d0f07b15ac",
"subsystem": "exthost",
"title": "The catalog: the signed index verified, kept, judged, and endorsing one key for one id"
},
{
"always": false,
"covers": [
[
"grblhal-glowforge",
"src/glowforge_mcode.*"
],
[
"grblhal-glowforge",
"src/ctlport.*"
],
[
"forgectrl",
"src/mcode.*"
],
[
"forgectrl",
"src/extpkg.*"
],
[
"forgectrl",
"src/grblport.*"
],
[
"forgeext",
"src/main.c"
],
[
"forgeext",
"src/run.*"
],
[
"forgeext",
"src/caps.*"
],
[
"forgeext",
"src/manifest.*"
],
[
"forgeext",
"src/call.*"
]
],
"fingerprint": "9b5782367c93f20dfc7730b51b1c3ed086e4c0da285a9062a78e5b0573663c94",
"hardware": "api",
"id": "exthost.mcode",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928180313-75fb",
"duration_s": 18,
"evidence": {
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T18:03:13Z"
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"job": {
"calls": [
{
"path": "/mcode",
"req": {
"code": 160,
"words": {
"P": 1
}
},
"status": 200,
"t": 624.235650131
}
],
"end_mm": 0.0,
"farthest_mm": 5.0,
"record": {
"acked": 7,
"elapsed_s": 3,
"emission": {
"hv_max": 0,
"laser_on_samples": 0,
"lit_s": 0.0,
"samples": 15,
"thermopile_delta": 0
},
"lines": 6,
"lit": false,
"owner": "job:forgetest",
"program": true,
"reason": "",
"sent": 7,
"state": "done"
}
},
"mode": {
"detail": "already in grbl mode",
"found": "grbl",
"needs": "grbl",
"ok": true,
"switched": false
},
"refused": {
"calls": [
{
"path": "/mcode",
"req": {
"code": 160,
"words": {
"P": 1
}
},
"status": 200,
"t": 624.235650131
},
{
"path": "/mcode",
"req": {
"code": 160,
"words": {
"P": 2
}
},
"status": 409,
"t": 627.703551496
}
],
"port": {
"envelope_open": false,
"homed": 4,
"mcode": null,
"mpos": [
0.0,
0.0,
4.449
],
"port_jog": false,
"released": false,
"sender": true,
"sender_out": false,
"state": "Hold",
"tray": "in"
}
},
"status_mcodes": [
{
"code": 160,
"id": "org.forgetest.reference"
}
],
"unanswered": {
"farthest_mm": 0.0,
"record": {
"acked": 2,
"elapsed_s": 0,
"emission": {
"hv_max": 0,
"laser_on_samples": 0,
"lit_s": 0.0,
"samples": 1,
"thermopile_delta": 0
},
"lines": 6,
"lit": false,
"owner": "job:forgetest",
"program": true,
"reason": "the controller answered error:20 on line 3 (M161)",
"sent": 6,
"state": "failed"
}
},
"wait": {
"kernel": [
[
5.0,
0.0
],
[
5.0,
0.0
]
],
"port": {
"envelope_open": false,
"homed": 4,
"mcode": {
"code": 160,
"seq": 1,
"words": {
"P": 1
}
},
"mpos": [
5.002,
0.0,
4.449
],
"port_jog": false,
"released": false,
"sender": true,
"sender_out": false,
"state": "Idle",
"tray": "in"
},
"port_after_1s": {
"envelope_open": false,
"homed": 4,
"mcode": {
"code": 160,
"seq": 1,
"words": {
"P": 1
}
},
"mpos": [
5.002,
0.0,
4.449
],
"port_jog": false,
"released": false,
"sender": true,
"sender_out": false,
"state": "Idle",
"tray": "in"
}
}
},
"fingerprint": "9b5782367c93f20dfc7730b51b1c3ed086e4c0da285a9062a78e5b0573663c94",
"image": "20260928175056 (dev)",
"log": [
"18:12:20 start exthost.mcode (auto, api) in campaign c-20260928180313-75fb",
"18:12:21 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"18:12:21 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"18:12:21 queued by the unattended queue opened 2026-09-28T18:03:13Z",
"18:12:21 baseline: pre: clean",
"18:12:21 mode: test needs grbl - already in grbl mode",
"18:12:26 the job waits at M160: port {'state': 'Idle', 'sender': True, 'port_jog': False, 'released': False, 'mpos': [5.002, 0.0, 4.449], 'homed': 4, 'envelope_open': False, 'mcode': {'seq': 1, 'code': 160, 'words': {'P': 1}}, 'sender_out': False, 'tray': 'in'}, kernel (5.0, 0.0) -> (5.0, 0.0)",
"18:12:28 the job at M160 P1: {'record': {'state': 'done', 'owner': 'job:forgetest', 'program': True, 'lines': 6, 'sent': 7, 'acked': 7, 'elapsed_s': 3, 'lit': False, 'emission': {'samples': 15, 'hv_max': 0, 'laser_on_samples': 0, 'thermopile_delta': 0, 'lit_s': 0.0}, 'reason': ''}, 'farthest_mm': 5.0, 'end_mm': 0.0, 'calls': [{'path': '/mcode', 'req': {'code': 160, 'words': {'P': 1}}, 't': 624.235650131, 'status': 200}]}",
"18:12:28 the job at M161: {'record': {'state': 'failed', 'owner': 'job:forgetest', 'program': True, 'lines': 6, 'sent': 6, 'acked': 2, 'elapsed_s': 0, 'lit': False, 'emission': {'samples': 1, 'hv_max': 0, 'laser_on_samples': 0, 'thermopile_delta': 0, 'lit_s': 0.0}, 'reason': 'the controller answered error:20 on line 3 (M161)'}, 'farthest_mm': 0.0}",
"18:12:29 the job at M160 P2: {'port': {'state': 'Hold', 'sender': True, 'port_jog': False, 'released': False, 'mpos': [0.0, 0.0, 4.449], 'homed': 4, 'envelope_open': False, 'mcode': None, 'sender_out': False, 'tray': 'in'}, 'calls': [{'path': '/mcode', 'req': {'code': 160, 'words': {'P': 1}}, 't': 624.235650131, 'status': 200}, {'path': '/mcode', 'req': {'code': 160, 'words': {'P': 2}}, 't': 627.703551496, 'status': 409}]}",
"18:12:30 remove org.forgetest.reference -> ok",
"18:12:30 restore ext_enabled='1' -> 200",
"18:12:30 takeover: waiting for forgectrl to be settled",
"18:12:30 baseline: /mode controller=running motion=verified",
"18:12:30 takeover: preserving cnc/motor_lock=0, cnc/step_freq=112640, cnc/ramp_rate=500000, cnc/streaming=0, cnc/x_mode=32, cnc/y_mode=32, cnc/x_decay=1, cnc/y_decay=1, pic/x_step_current=33, pic/y_step_current=5",
"18:12:30 takeover: stopping the controller through forgectrl",
"18:12:30 takeover: POST /controller/stop -> 200",
"18:12:30 takeover: forgectrl stop -> rc 0",
"18:12:32 takeover: pulse device free",
"18:12:32 takeover: forgectrl start -> rc 0",
"18:12:34 baseline: /mode controller=stopped motion=unverified",
"18:12:39 baseline: /mode controller=running motion=verified",
"18:12:39 the previous record is back under a restart",
"18:12:39 baseline: post: clean",
"18:12:39 result PASS"
],
"manifest_sha": "0946700866975cd7ed6b5cc6c6fd0dadc033a8ab5d820a9bea37ca92b7e64368",
"message": "",
"result": "PASS",
"test": "exthost.mcode",
"ts": "2026-09-28T18:12:39Z"
},
"requires": [
"exthost.service",
"motion.job"
],
"satisfied": true,
"source_sha": "fbabe0b96bde89346381cf989e95cf08124b483ccfa7e723a14449b3366c40a8",
"subsystem": "exthost",
"title": "A job waits at an M-code a package answers, dark and still"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/wizpkg.*"
],
[
"forgectrl",
"src/wizdark.c"
],
[
"forgectrl",
"src/wiz.c"
],
[
"forgectrl",
"src/extpkg.*"
],
[
"forgectrl",
"src/ui/wizard.js"
],
[
"forgeext",
"src/main.c"
],
[
"forgeext",
"src/run.*"
],
[
"forgeext",
"src/caps.*"
],
[
"forgeext",
"src/manifest.*"
]
],
"fingerprint": "a8130db4d9a805581c7bfd5198388b38f3a0075c8fc3023d834247ffb98b78c2",
"hardware": "api",
"id": "exthost.wizard",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928180313-75fb",
"duration_s": 29,
"evidence": {
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T18:03:13Z"
},
"end": {
"applied": null,
"elapsed_s": 0,
"error": "",
"id": "pkg:org.forgetest.reference",
"log": [
"00:00 the check begins",
"00:00 answered yes"
],
"mine": true,
"owned": false,
"phase": "",
"progress": 50,
"prompt": null,
"result": {
"ok": true,
"summary": "ready"
},
"running": false,
"shots": {
"head": false,
"lid": false
}
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"lease_while_waiting": null,
"listed": {
"done": false,
"id": "pkg:org.forgetest.reference",
"title": "forgetest check"
},
"listed_after": {
"done": true,
"id": "pkg:org.forgetest.reference",
"title": "forgetest check"
},
"prompt": {
"applied": null,
"elapsed_s": 0,
"error": "",
"id": "pkg:org.forgetest.reference",
"log": [
"00:00 the check begins"
],
"mine": true,
"owned": false,
"phase": "asking",
"progress": 50,
"prompt": {
"id": "ready",
"kind": "confirm",
"options": [
"Yes",
"No"
],
"seq": 1,
"since_s": 0,
"text": "Is the machine ready?",
"timeout_s": 600
},
"result": null,
"running": true,
"shots": {
"head": false,
"lid": false
}
},
"record": {
"after": {
"completed": "2026-09-11T16:39:58Z",
"wizards": [
"account",
"advisories",
"airflow",
"cameras",
"cloud",
"cloud.header",
"cooling.aa-offset",
"cooling.flow",
"cooling.flow-load",
"cooling.flow-verify",
"laser.corner",
"laser.dose-curve",
"laser.floor",
"laser.focus",
"machine",
"motion",
"preferences",
"sensors",
"sheet.frame",
"sheet.place",
"switches"
]
},
"before": {
"completed": "2026-09-11T16:39:58Z",
"wizards": [
"account",
"advisories",
"airflow",
"cameras",
"cloud",
"cloud.header",
"cooling.aa-offset",
"cooling.flow",
"cooling.flow-load",
"cooling.flow-verify",
"laser.corner",
"laser.dose-curve",
"laser.floor",
"laser.focus",
"machine",
"motion",
"preferences",
"sensors",
"sheet.frame",
"sheet.place",
"switches"
]
}
}
},
"fingerprint": "a8130db4d9a805581c7bfd5198388b38f3a0075c8fc3023d834247ffb98b78c2",
"image": "20260928175056 (dev)",
"log": [
"18:12:39 start exthost.wizard (auto, api) in campaign c-20260928180313-75fb",
"18:12:39 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"18:12:39 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"18:12:39 queued by the unattended queue opened 2026-09-28T18:03:13Z",
"18:12:39 baseline: pre: clean",
"18:12:49 the check ended: {'id': 'pkg:org.forgetest.reference', 'running': False, 'owned': False, 'mine': True, 'phase': '', 'progress': 50, 'elapsed_s': 0, 'log': ['00:00 the check begins', '00:00 answered yes'], 'prompt': None, 'result': {'ok': True, 'summary': 'ready'}, 'applied': None, 'error': '', 'shots': {'lid': False, 'head': False}}",
"18:13:01 remove org.forgetest.reference -> ok",
"18:13:01 restore ext_enabled='1' -> 200",
"18:13:01 takeover: waiting for forgectrl to be settled",
"18:13:01 baseline: /mode controller=running motion=verified",
"18:13:01 takeover: preserving cnc/motor_lock=0, cnc/step_freq=112640, cnc/ramp_rate=500000, cnc/streaming=0, cnc/x_mode=32, cnc/y_mode=32, cnc/x_decay=1, cnc/y_decay=1, pic/x_step_current=33, pic/y_step_current=5",
"18:13:01 takeover: stopping the controller through forgectrl",
"18:13:02 takeover: POST /controller/stop -> 200",
"18:13:02 takeover: forgectrl stop -> rc 0",
"18:13:02 takeover: pulse device free",
"18:13:02 takeover: forgectrl start -> rc 0",
"18:13:04 baseline: /mode controller=stopped motion=unverified",
"18:13:08 baseline: /mode controller=running motion=verified",
"18:13:08 the previous record is back under a restart",
"18:13:09 baseline: post: clean",
"18:13:09 result PASS"
],
"manifest_sha": "0946700866975cd7ed6b5cc6c6fd0dadc033a8ab5d820a9bea37ca92b7e64368",
"message": "",
"result": "PASS",
"test": "exthost.wizard",
"ts": "2026-09-28T18:13:09Z"
},
"requires": [
"exthost.service"
],
"satisfied": true,
"source_sha": "eea24190b4409df66c8c2bf0b9e00de8807cb385858caa075795e73355d283de",
"subsystem": "exthost",
"title": "A package's own check runs on the Setup page, and the machine's setup is untouched"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/update.*"
],
[
"forgectrl",
"src/relcheck.*"
],
[
"forgectrl",
"src/lease.*"
]
],
"fingerprint": "815319ca42777af6c0b237927daac936574a7ad651fa4989b31f9abbe18eac8f",
"hardware": "api",
"id": "update.job-locks",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928180313-75fb",
"duration_s": 2,
"evidence": {
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T18:03:13Z"
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"holder": {
"for_s": 0,
"kind": "system",
"owner": "update:download",
"words": "an update job (download)"
},
"job": {
"elapsed": 0,
"kind": "download",
"phase": "",
"progress_bytes": -1,
"result": {
"error": "signature verification failed - archive discarded",
"ok": false
},
"running": false
},
"refused": {
"a posted job": [
409,
"an update job (download) holds the machine"
],
"a settings write": [
409,
"an update job (download) holds the machine - settings are locked"
]
},
"release": {
"available": true,
"version": "v0.0.6"
},
"staged_download": null
},
"fingerprint": "815319ca42777af6c0b237927daac936574a7ad651fa4989b31f9abbe18eac8f",
"image": "20260928175056 (dev)",
"log": [
"18:13:09 start update.job-locks (auto, api) in campaign c-20260928180313-75fb",
"18:13:09 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"18:13:09 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"18:13:09 queued by the unattended queue opened 2026-09-28T18:03:13Z",
"18:13:09 baseline: pre: clean",
"18:13:10 the release was not checked since the daemon started: POST /update/check -> 200",
"18:13:10 beside the probe: {'a settings write': [409, 'an update job (download) holds the machine - settings are locked'], 'a posted job': [409, 'an update job (download) holds the machine']}; the lease: {'owner': 'update:download', 'kind': 'system', 'for_s': 0, 'words': 'an update job (download)'}",
"18:13:11 the probe ended: {'running': False, 'kind': 'download', 'phase': '', 'elapsed': 0, 'progress_bytes': -1, 'result': {'ok': False, 'error': 'signature verification failed - archive discarded'}}",
"18:13:11 baseline: post: clean",
"18:13:11 result PASS"
],
"manifest_sha": "0946700866975cd7ed6b5cc6c6fd0dadc033a8ab5d820a9bea37ca92b7e64368",
"message": "",
"result": "PASS",
"test": "update.job-locks",
"ts": "2026-09-28T18:13:11Z"
},
"requires": [
"update.release-check"
],
"satisfied": true,
"source_sha": "46b79435b7e7d6742a119df24435ef8a8a35fa1fe044fa21af9175f4f8b3a8e5",
"subsystem": "update",
"title": "An update job holds the machine: the settings are locked while it runs"
},
{
"always": false,
"covers": [
[
"forgefirm-app",
"forgefirm-app/gfcloud.py"
],
[
"forgefirm-app",
"forgefirm-app/ffmachine.py"
],
[
"forgefirm-app",
"forgefirm-app/gfhome.conf.sample"
],
[
"python3-gfhardware",
"gfhardware/__init__.py"
],
[
"python3-gfhardware",
"gfhardware/_common.py"
],
[
"python3-gfhardware",
"gfhardware/id.py"
],
[
"python3-gfhardware",
"gfhardware/coolsvc.py"
],
[
"python3-gfutilities",
"gfutilities/__init__.py"
],
[
"python3-gfutilities",
"gfutilities/_common.py"
],
[
"python3-gfutilities",
"gfutilities/configuration.py"
],
[
"python3-gfutilities",
"gfutilities/device/__init__.py"
],
[
"python3-gfutilities",
"gfutilities/device/basemachine.py"
],
[
"python3-gfutilities",
"gfutilities/device/settings.py"
],
[
"python3-gfutilities",
"gfutilities/service/__init__.py"
],
[
"python3-gfutilities",
"gfutilities/service/dispatch.py"
],
[
"python3-gfutilities",
"gfutilities/service/websocket.py"
],
[
"python3-gfutilities",
"gfutilities/service/authentication.py"
],
[
"python3-gfutilities",
"gfutilities/service/gfuiservice.py"
],
[
"forgefirm-app",
"forgefirm-app/**"
],
[
"python3-gfhardware",
"gfhardware/**"
],
[
"python3-gfutilities",
"gfutilities/puls/**"
],
[
"forgectrl",
"src/super.c"
],
[
"forgectrl",
"src/main.c"
],
[
"grblhal-glowforge",
"src/glowforge_homing.*"
],
[
"grblhal-glowforge",
"src/glowforge_cooling.*"
]
],
"fingerprint": "007ed2a6f83540501de01fc50489c713f028c03a53c18507d8adf4705a1394ff",
"hardware": "api",
"id": "homing.cloud-offsets",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928180313-75fb",
"duration_s": 66,
"evidence": {
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T18:03:13Z"
},
"declared": [
4.5,
-3.248,
3.08
],
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"found": {
"gfcloud_home_x": "",
"gfcloud_home_y": "",
"homing_mode": "manual"
},
"gfhome_complete": "2026-09-28T18:14:03.622972+00:00 gfhome[5718] INFO gfhome:home homing complete (service quiet 10s, 9 motion windows)",
"homed": true,
"homing_s": 60.1,
"jogs": {
"X": {
"at": [
4.5,
-3.248,
3.08
],
"back": [
"ok"
],
"out": [
"ok"
]
},
"Y": {
"at": [
4.5,
-3.248,
3.08
],
"back": [
"ok"
],
"out": [
"ok"
]
}
},
"mode": {
"detail": "already in grbl mode",
"found": "grbl",
"needs": "grbl",
"ok": true,
"switched": false
},
"return": {
"counters_across_jog": [
[
0,
0,
0
],
[
-44,
52,
0
]
],
"counters_since_home": [
0,
0,
0
],
"mm": [
0.206,
-0.244
],
"session_travel_steps": [
11,
-13
]
},
"short_motions": []
},
"fingerprint": "007ed2a6f83540501de01fc50489c713f028c03a53c18507d8adf4705a1394ff",
"image": "20260928175056 (dev)",
"log": [
"18:13:11 start homing.cloud-offsets (auto, api) in campaign c-20260928180313-75fb",
"18:13:12 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"18:13:12 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"18:13:12 queued by the unattended queue opened 2026-09-28T18:03:13Z",
"18:13:12 baseline: pre: clean",
"18:13:12 mode: test needs grbl - already in grbl mode",
"18:13:42 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"18:14:12 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"18:14:12 homing: homed=True after 60.1 s (kernel idle, grbl Idle)",
"18:14:12 gfhome: 2026-09-28T18:14:03.622972+00:00 gfhome[5718] INFO gfhome:home homing complete (service quiet 10s, 9 motion windows)",
"18:14:12 position counters re-zeroed at the starting position; the baseline expects (0,0,0) at the end",
"18:14:12 $H acknowledged: [MSG:] | ok",
"18:14:13 the camera home declared (4.5, -3.248, 3.08)",
"18:14:14 out and back to the home: {'Y': {'out': ['ok'], 'back': ['ok'], 'at': (4.5, -3.248, 3.08)}, 'X': {'out': ['ok'], 'back': ['ok'], 'at': (4.5, -3.248, 3.08)}}",
"18:14:14 restore homing_mode='manual' -> 409 machine is not idle - settings are locked",
"18:14:14 restore homing_mode='manual' -> taken",
"18:14:14 restore gfcloud_home_x='' -> taken",
"18:14:14 restore gfcloud_home_y='' -> taken",
"18:14:15 the head is 0.206/-0.244 mm from where the test found it",
"18:14:16 connect: Idle",
"18:14:18 position counters re-zeroed at the starting position; the baseline expects (0,0,0) at the end",
"18:14:18 head returned to where the test found it (-0.206/0.244 mm)",
"18:14:18 baseline: post: clean",
"18:14:18 result PASS"
],
"manifest_sha": "0946700866975cd7ed6b5cc6c6fd0dadc033a8ab5d820a9bea37ca92b7e64368",
"message": "",
"result": "PASS",
"test": "homing.cloud-offsets",
"ts": "2026-09-28T18:14:18Z"
},
"requires": [
"forgectrl.auth",
"motion.pacing"
],
"satisfied": true,
"source_sha": "499c581b488818cf6363011e940bcb220284bf0aaca9b31e170b9676f2c314e9",
"subsystem": "homing",
"title": "A camera home declares its offset pair, and the envelope reaches back to a negative one"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/wizdark.*"
],
[
"forgectrl",
"src/wizcalc.*"
],
[
"forgectrl",
"src/wiz.*"
],
[
"forgectrl",
"src/setup.*"
],
[
"forgectrl",
"src/main.c"
],
[
"forgectrl",
"src/ui/wizard.*"
],
[
"forgefirm-app",
"forgefirm-app/gfcloud.py"
],
[
"forgefirm-app",
"forgefirm-app/ffmachine.py"
],
[
"forgefirm-app",
"forgefirm-app/gfhome.conf.sample"
],
[
"python3-gfhardware",
"gfhardware/__init__.py"
],
[
"python3-gfhardware",
"gfhardware/_common.py"
],
[
"python3-gfhardware",
"gfhardware/id.py"
],
[
"python3-gfhardware",
"gfhardware/coolsvc.py"
],
[
"python3-gfutilities",
"gfutilities/__init__.py"
],
[
"python3-gfutilities",
"gfutilities/_common.py"
],
[
"python3-gfutilities",
"gfutilities/configuration.py"
],
[
"python3-gfutilities",
"gfutilities/device/__init__.py"
],
[
"python3-gfutilities",
"gfutilities/device/basemachine.py"
],
[
"python3-gfutilities",
"gfutilities/device/settings.py"
],
[
"python3-gfutilities",
"gfutilities/service/__init__.py"
],
[
"python3-gfutilities",
"gfutilities/service/dispatch.py"
],
[
"python3-gfutilities",
"gfutilities/service/websocket.py"
],
[
"python3-gfutilities",
"gfutilities/service/authentication.py"
],
[
"python3-gfutilities",
"gfutilities/service/gfuiservice.py"
],
[
"forgefirm-app",
"forgefirm-app/**"
],
[
"python3-gfhardware",
"gfhardware/**"
],
[
"python3-gfutilities",
"gfutilities/puls/**"
],
[
"forgectrl",
"src/super.c"
],
[
"forgectrl",
"src/main.c"
],
[
"forgectrl",
"src/grblport.*"
],
[
"grblhal-glowforge",
"src/glowforge_homing.*"
],
[
"grblhal-glowforge",
"src/ctlport.*"
],
[
"grblhal-glowforge",
"src/driver.c"
]
],
"fingerprint": "b0bc6d1c53174c5dd94951adb73712cbbb63952dbddfe3fc32bc0e6d1ffb676c",
"hardware": "api",
"id": "setup.check-envelope",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928180313-75fb",
"duration_s": 108,
"evidence": {
"back": [
0.0,
0.0,
3.08
],
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T18:03:13Z"
},
"edge_X": {
"at": [
10.003,
10.003
],
"edge": 59.1,
"past": [
409,
"the move would leave the work envelope"
],
"short": [
200,
200
]
},
"edge_Y": {
"at": [
9.998,
9.998
],
"edge": 60.1,
"past": [
409,
"the move would leave the work envelope"
],
"short": [
200,
200
]
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"found": {
"envelope_x_mm": "508",
"envelope_y_mm": "288.925",
"homing_mode": "manual"
},
"gfhome_complete": "2026-09-28T18:15:06.126868+00:00 gfhome[6086] INFO gfhome:home homing complete (service quiet 10s, 7 motion windows)",
"home": [
0.0,
0.0,
3.08
],
"homed": true,
"homing_s": 54.0,
"keys_after_run1": {
"envelope_x_mm": "59.10",
"envelope_y_mm": "60.10"
},
"mode": {
"detail": "already in grbl mode",
"found": "grbl",
"needs": "grbl",
"ok": true,
"switched": false
},
"return": {
"counters_across_jog": [
[
0,
0,
0
],
[
-40,
52,
0
]
],
"counters_since_home": [
0,
0,
0
],
"mm": [
0.188,
-0.244
],
"session_travel_steps": [
10,
-13
]
},
"run1": {
"answers": [
"X+10",
"X+10",
"X+10",
"X+10",
"X+10",
"X+10",
"X+1",
"X+0.1",
"X-1",
"This is the end",
"Y+10",
"Y+10",
"Y+10",
"Y+10",
"Y+10",
"Y+10",
"Y+1",
"Y+0.1",
"This is the end"
],
"error": "",
"log": [
"00:00 the envelope is open to the travel plus 30 mm for the measurement",
"00:11 the right end: X 2.366 in",
"00:21 the front end: Y 2.406 in"
],
"result": {
"envelope_x_mm": 59.1,
"envelope_y_mm": 60.1,
"summary": "The head travels to X 2.366 in and Y 2.406 in from its home; the envelope ends 0.039 in short of both, and a job past it is refused.",
"x_end_mm": 60.099,
"y_end_mm": 61.102
}
},
"run2": {
"answers": [
"X+1"
],
"error": "a Grbl client sent a line, which closed the check's envelope: run the check again when nothing else is sending",
"log": [
"00:00 the envelope is open to the travel plus 30 mm for the measurement"
],
"said": {
"port": {
"envelope_open": false,
"homed": 7,
"mcode": null,
"mpos": [
10.003,
9.998,
3.08
],
"port_jog": false,
"released": false,
"sender": false,
"sender_out": false,
"state": "Idle",
"tray": "in"
},
"reply": [
"[MSG:Bed check envelope closed: a sender line]",
"ok"
],
"text": ""
}
},
"short_motions": [],
"started": true
},
"fingerprint": "b0bc6d1c53174c5dd94951adb73712cbbb63952dbddfe3fc32bc0e6d1ffb676c",
"image": "20260928175056 (dev)",
"log": [
"18:14:18 start setup.check-envelope (auto, api) in campaign c-20260928180313-75fb",
"18:14:18 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"18:14:18 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"18:14:18 queued by the unattended queue opened 2026-09-28T18:03:13Z",
"18:14:18 baseline: pre: clean",
"18:14:18 mode: test needs grbl - already in grbl mode",
"18:14:49 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"18:15:13 homing: homed=True after 54.0 s (kernel idle, grbl Idle)",
"18:15:13 gfhome: 2026-09-28T18:15:06.126868+00:00 gfhome[6086] INFO gfhome:home homing complete (service quiet 10s, 7 motion windows)",
"18:15:13 position counters re-zeroed at the starting position; the baseline expects (0,0,0) at the end",
"18:15:13 $H acknowledged: [MSG:] | ok",
"18:15:13 the camera home declared (0.0, 0.0, 3.08)",
"18:15:13 POST /wiz/motion.envelope/start -> 200 {'started': True, 'id': 'motion.envelope'}",
"18:15:20 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"18:15:36 the bed check ended: {\"x_end_mm\": 60.099, \"y_end_mm\": 61.102, \"envelope_x_mm\": 59.1, \"envelope_y_mm\": 60.1, \"summary\": \"The head travels to X 2.366 in and Y 2.406 in from its home; the envelope ends 0.039 in short of both, and a job past it is refused.\"}",
"18:15:47 POST /wiz/motion.envelope/start -> 200 {'started': True, 'id': 'motion.envelope'}",
"18:15:48 the second run: {\"answers\": [\"X+1\"], \"said\": {\"reply\": [\"[MSG:Bed check envelope closed: a sender line]\", \"ok\"], \"text\": \"\", \"port\": {\"state\": \"Idle\", \"sender\": false, \"port_jog\": false, \"released\": false, \"mpos\": [10.003, 9.998, 3.08], \"homed\": 7, \"envelope_open\": false, \"mcode\": null, \"sender_out\": false, \"tray\": \"in\"}}, \"error\": \"a Grbl client sent a line, which closed the check's envelope: run the check again when nothing else is sending\", \"log\": [\"00:00 the envelope is open to the travel plus 30 mm for the measurement\"]}",
"18:15:51 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"18:15:54 the jog back to the home: $J=G90 G53 X0.0005 Y0.0005 F1200 -> ok",
"18:15:55 the head after the jog back: [0.0, 0.0, 3.08] (the home (0.0, 0.0, 3.08))",
"18:15:55 restore envelope_x_mm='508' -> 409 machine is not idle - settings are locked",
"18:15:56 restore envelope_x_mm='508' -> taken",
"18:15:56 restore envelope_y_mm='288.925' -> taken",
"18:15:56 restore homing_mode='manual' -> taken",
"18:15:57 the head is 0.188/-0.244 mm from where the test found it",
"18:15:57 connect: Idle",
"18:15:59 position counters re-zeroed at the starting position; the baseline expects (0,0,0) at the end",
"18:15:59 head returned to where the test found it (-0.188/0.244 mm)",
"18:15:59 takeover: waiting for forgectrl to be settled",
"18:15:59 baseline: /mode controller=running motion=verified",
"18:15:59 takeover: preserving cnc/motor_lock=0, cnc/step_freq=112640, cnc/ramp_rate=500000, cnc/streaming=0, cnc/x_mode=32, cnc/y_mode=32, cnc/x_decay=1, cnc/y_decay=1, pic/x_step_current=33, pic/y_step_current=5",
"18:15:59 takeover: stopping the controller through forgectrl",
"18:15:59 takeover: POST /controller/stop -> 200",
"18:15:59 takeover: forgectrl stop -> rc 0",
"18:16:00 takeover: pulse device free",
"18:16:00 takeover: forgectrl start -> rc 0",
"18:16:01 baseline: /mode controller=stopped motion=unverified",
"18:16:06 baseline: /mode controller=running motion=verified",
"18:16:06 the previous setup record is back under a restart",
"18:16:06 baseline: post: clean",
"18:16:06 result PASS"
],
"manifest_sha": "0946700866975cd7ed6b5cc6c6fd0dadc033a8ab5d820a9bea37ca92b7e64368",
"message": "",
"result": "PASS",
"test": "setup.check-envelope",
"ts": "2026-09-28T18:16:06Z"
},
"requires": [
"forgectrl.auth",
"motion.pacing"
],
"satisfied": true,
"source_sha": "0dae76852badf7d0a5a9525a32225b1e625b6e18d867dffa3f958535eea70ee8",
"subsystem": "setup",
"title": "The bed check measures the far edges from the operator's jogs, and a Grbl client's line ends it with nothing written"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/senderout.*"
],
[
"forgectrl",
"src/lease.*"
],
[
"forgectrl",
"src/grblport.*"
],
[
"forgectrl",
"src/main.c"
],
[
"forgectrl",
"src/status.*"
],
[
"forgeext",
"src/api.*"
],
[
"forgeext",
"src/run.*"
],
[
"forgeext",
"src/machine.*"
],
[
"forgeext",
"src/holdkeep.*"
],
[
"forgeext",
"src/caps.*"
],
[
"grblhal-glowforge",
"src/ctlport.*"
],
[
"grblhal-glowforge",
"src/serial.*"
]
],
"fingerprint": "02ba2e8224ad1002c96d0775918edbb87535240174230a336e92809ec6075d16",
"hardware": "api",
"id": "exthost.sender-keep-out",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928180313-75fb",
"duration_s": 32,
"evidence": {
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T18:03:13Z"
},
"before": [
"\r\nGrblHAL 1.1f ['$' or '$HELP' for help]\r\n",
false
],
"claim": {
"doc": {
"out": true,
"released": false
},
"status": 200
},
"claim_file": {
"id": "org.forgetest.reference",
"raised": true,
"reason": "keeps the Grbl sender out",
"required": false,
"ts_mono": 850.72305965
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"kept": {
"lease": {
"for_s": 0,
"kind": "extension",
"owner": "ext:org.forgetest.reference",
"words": "an extension (org.forgetest.reference)"
},
"sender_out": {
"holder": {
"for_s": 0,
"id": "org.forgetest.reference"
},
"notice": null
}
},
"kept_out": [
"[MSG:The machine is in use: senders are kept out for now]\r\n",
true
],
"loopback": [
"\r\nGrblHAL 1.1f ['$' or '$HELP' for help]\r\n",
false
],
"notice": {
"id": "org.forgetest.reference",
"why": "stopped"
},
"released": [
200,
{
"holder": null,
"notice": null
}
],
"stale_s": 3.0
},
"fingerprint": "02ba2e8224ad1002c96d0775918edbb87535240174230a336e92809ec6075d16",
"image": "20260928175056 (dev)",
"log": [
"18:16:06 start exthost.sender-keep-out (auto, api) in campaign c-20260928180313-75fb",
"18:16:07 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"18:16:07 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"18:16:07 queued by the unattended queue opened 2026-09-28T18:03:13Z",
"18:16:07 baseline: pre: clean",
"18:16:11 the service's claim: {'status': 200, 'doc': {'out': True, 'released': False}}; sender_out {'holder': {'id': 'org.forgetest.reference', 'for_s': 0}, 'notice': None}",
"18:16:29 the claim ended 3.1 s after the disable; notice {'id': 'org.forgetest.reference', 'why': 'stopped'}",
"18:16:31 remove org.forgetest.reference -> ok",
"18:16:31 restore ext_enabled='1' -> 200",
"18:16:31 takeover: waiting for forgectrl to be settled",
"18:16:31 baseline: /mode controller=running motion=verified",
"18:16:31 takeover: preserving cnc/motor_lock=0, cnc/step_freq=112640, cnc/ramp_rate=500000, cnc/streaming=0, cnc/x_mode=32, cnc/y_mode=32, cnc/x_decay=1, cnc/y_decay=1, pic/x_step_current=33, pic/y_step_current=5",
"18:16:31 takeover: stopping the controller through forgectrl",
"18:16:32 takeover: POST /controller/stop -> 200",
"18:16:32 takeover: forgectrl stop -> rc 0",
"18:16:33 takeover: pulse device free",
"18:16:33 takeover: forgectrl start -> rc 0",
"18:16:35 baseline: /mode controller=stopped motion=unverified",
"18:16:39 baseline: /mode controller=running motion=verified",
"18:16:39 the previous record is back under a restart",
"18:16:39 baseline: post: clean",
"18:16:39 result PASS"
],
"manifest_sha": "0946700866975cd7ed6b5cc6c6fd0dadc033a8ab5d820a9bea37ca92b7e64368",
"message": "",
"result": "PASS",
"test": "exthost.sender-keep-out",
"ts": "2026-09-28T18:16:39Z"
},
"requires": [
"exthost.service"
],
"satisfied": true,
"source_sha": "a034dffdba0b5aa3e91ddf0d9073274bfab3d00f2cd5b0feb37c07a205f00037",
"subsystem": "exthost",
"title": "An extension package keeps the Grbl sender out, by the operator's grant"
},
{
"always": false,
"covers": [
[
"grblhal-glowforge",
"src/glowforge_tray.*"
],
[
"grblhal-glowforge",
"src/glowforge_homing.*"
],
[
"grblhal-glowforge",
"src/ctlport.*"
],
[
"grblhal-glowforge",
"src/glowforge_io.*"
],
[
"forgectrl",
"src/tray.*"
],
[
"forgectrl",
"src/grblport.*"
],
[
"forgectrl",
"src/status.*"
],
[
"forgectrl",
"src/main.c"
],
[
"forgectrl",
"src/wizdark.*"
],
[
"forgectrl",
"src/ui/panel.js"
],
[
"forgectrl",
"src/ui/index.html"
]
],
"fingerprint": "e7f2b72c5d8c39df3bb8b17637c13ccbcefe9940e3c1a26dc8aa1e712528b4ca",
"hardware": "api",
"id": "motion.tray",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928180313-75fb",
"duration_s": 2,
"evidence": {
"baseline": {
"post": [],
"pre": []
},
"batch": {
"group": "unattended",
"ts": "2026-09-28T18:03:13Z"
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"found": {
"home": [
4,
"startup"
],
"kernel": [
0,
0,
0,
0,
0
],
"lens": {
"above": 20,
"below": 14,
"edge_z": 4.51,
"reach_max": 11.35,
"reach_min": -0.28,
"stops_found": true,
"tray": "in",
"tray_offset_mm": 34.29
},
"port_z": 4.449,
"pos_z": 4.45,
"shift_mm": 34.2231,
"tray": "in"
},
"jog_in": [
"$J=G90 G21 Z4.449 F200",
[
"ok"
]
],
"jog_out": [
"$J=G90 G21 Z4.449 F200",
[
"error:15"
]
],
"kernel": [
[
0,
0,
0,
0,
0
],
[
0,
0,
0,
0,
0
]
],
"m103_in": {
"home": [
4,
"startup"
],
"lens": {
"above": 20,
"below": 14,
"edge_z": 4.51,
"reach_max": 11.35,
"reach_min": -0.28,
"stops_found": true,
"tray": "in",
"tray_offset_mm": 34.29
},
"marker": false,
"port_tray": "in",
"port_z": 4.449,
"pos_z": 4.45
},
"m103_out": {
"home": [
4,
"startup"
],
"lens": {
"above": 20,
"below": 14,
"edge_z": 4.51,
"reach_max": 45.58,
"reach_min": 33.94,
"stops_found": true,
"tray": "out",
"tray_offset_mm": 34.29
},
"marker": true,
"port_tray": "out",
"port_z": 38.672,
"pos_z": 38.67
},
"mode": {
"detail": "already in grbl mode",
"found": "grbl",
"needs": "grbl",
"ok": true,
"switched": false
},
"route_in": {
"home": [
4,
"startup"
],
"lens": {
"above": 20,
"below": 14,
"edge_z": 4.51,
"reach_max": 11.35,
"reach_min": -0.28,
"stops_found": true,
"tray": "in",
"tray_offset_mm": 34.29
},
"marker": false,
"port_tray": "in",
"port_z": 4.449,
"pos_z": 4.45
},
"route_out": {
"home": [
4,
"startup"
],
"lens": {
"above": 20,
"below": 14,
"edge_z": 4.51,
"reach_max": 45.58,
"reach_min": 33.94,
"stops_found": true,
"tray": "out",
"tray_offset_mm": 34.29
},
"marker": true,
"port_tray": "out",
"port_z": 38.672,
"pos_z": 38.67
},
"setup_card": [
409,
"{\"error\": \"Put the crumb tray in and set Tray in on the Machine tab.\"}"
]
},
"fingerprint": "e7f2b72c5d8c39df3bb8b17637c13ccbcefe9940e3c1a26dc8aa1e712528b4ca",
"image": "20260928175056 (dev)",
"log": [
"18:16:39 start motion.tray (auto, api) in campaign c-20260928180313-75fb",
"18:16:40 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"18:16:40 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"18:16:40 queued by the unattended queue opened 2026-09-28T18:03:13Z",
"18:16:40 baseline: pre: clean",
"18:16:40 mode: test needs grbl - already in grbl mode",
"18:16:40 found the tray in; switching to out moves Z +34.223 mm",
"18:16:40 connect: Idle",
"18:16:42 route_out: {'lens': {'edge_z': 4.51, 'below': 14, 'above': 20, 'stops_found': True, 'reach_min': 33.94, 'reach_max': 45.58, 'tray': 'out', 'tray_offset_mm': 34.29}, 'pos_z': 38.67, 'port_tray': 'out', 'port_z': 38.672, 'marker': True, 'home': [4, 'startup']}",
"18:16:42 m103_in: {'lens': {'edge_z': 4.51, 'below': 14, 'above': 20, 'stops_found': True, 'reach_min': -0.28, 'reach_max': 11.35, 'tray': 'in', 'tray_offset_mm': 34.29}, 'pos_z': 4.45, 'port_tray': 'in', 'port_z': 4.449, 'marker': False, 'home': [4, 'startup']}",
"18:16:42 m103_out: {'lens': {'edge_z': 4.51, 'below': 14, 'above': 20, 'stops_found': True, 'reach_min': 33.94, 'reach_max': 45.58, 'tray': 'out', 'tray_offset_mm': 34.29}, 'pos_z': 38.67, 'port_tray': 'out', 'port_z': 38.672, 'marker': True, 'home': [4, 'startup']}",
"18:16:42 a setup card started with the tray out -> 409 {\"error\": \"Put the crumb tray in and set Tray in on the Machine tab.\"}",
"18:16:42 route_in: {'lens': {'edge_z': 4.51, 'below': 14, 'above': 20, 'stops_found': True, 'reach_min': -0.28, 'reach_max': 11.35, 'tray': 'in', 'tray_offset_mm': 34.29}, 'pos_z': 4.45, 'port_tray': 'in', 'port_z': 4.449, 'marker': False, 'home': [4, 'startup']}",
"18:16:42 PASS: the tray mode switched both ways through the route and through M103, Z and the reach moved by 34.223 mm and back, nothing moved, and it is in as found",
"18:16:42 baseline: post: clean",
"18:16:42 result PASS"
],
"manifest_sha": "0946700866975cd7ed6b5cc6c6fd0dadc033a8ab5d820a9bea37ca92b7e64368",
"message": "",
"result": "PASS",
"test": "motion.tray",
"ts": "2026-09-28T18:16:42Z"
},
"requires": [
"motion.port-jog"
],
"satisfied": true,
"source_sha": "310868832df9f962fc7812c32c965b59743938a1fea70ce032c3e0ec43812133",
"subsystem": "motion",
"title": "The crumb tray: tray out moves Z and its range up by the offset, and nothing moves"
},
{
"always": false,
"covers": [
[
"forgectrl",
"src/tls.*"
],
[
"forgectrl",
"src/main.c"
]
],
"fingerprint": "b44575a320b2220be38d245690c213220d199eafc9f08b1390d0826fe184d7b5",
"hardware": "api",
"id": "forgectrl.tls-records",
"inherited": true,
"kind": "auto",
"record": {
"answers": [],
"campaign": "c-20260928183105-64ee",
"duration_s": 5,
"evidence": {
"baseline": {
"post": [],
"pre": []
},
"drivers": {
"gcm(aes)": "gcm_base(ctr-aes-caam,cryptd(ghash-ce-sync))",
"rfc7539(chacha20,poly1305)": "rfc7539(chacha20-neon,poly1305-neon)"
},
"fixture": {
"channels": [
"lid",
"interlock",
"button"
],
"hostname": "<REDACTED-1>",
"ip": "<IP-1>",
"released": []
},
"page_bytes": 562408,
"runs": {
"aes-1.2#1": {
"attempts": 1,
"bytes": 562408,
"engine_irqs": 38,
"offer": "ECDHE-ECDSA-AES128-GCM-SHA256",
"same_as_http": true,
"status": "HTTP/1.1 200 OK",
"suite": "ECDHE-ECDSA-AES128-GCM-SHA256",
"tls_stat": {
"TlsDecryptError": 0,
"TlsRxSw": 1,
"TlsTxSw": 1
}
},
"aes-1.2#2": {
"attempts": 1,
"bytes": 562408,
"engine_irqs": 38,
"offer": "ECDHE-ECDSA-AES128-GCM-SHA256",
"same_as_http": true,
"status": "HTTP/1.1 200 OK",
"suite": "ECDHE-ECDSA-AES128-GCM-SHA256",
"tls_stat": {
"TlsDecryptError": 0,
"TlsRxSw": 1,
"TlsTxSw": 1
}
},
"aes-1.2#3": {
"attempts": 2,
"bytes": 562408,
"engine_irqs": 38,
"offer": "ECDHE-ECDSA-AES128-GCM-SHA256",
"same_as_http": true,
"status": "HTTP/1.1 200 OK",
"suite": "ECDHE-ECDSA-AES128-GCM-SHA256",
"tls_stat": {
"TlsDecryptError": 0,
"TlsRxSw": 1,
"TlsTxSw": 1
}
},
"aes-1.3#1": {
"attempts": 1,
"bytes": 562408,
"engine_irqs": 38,
"offer": "TLS_AES_128_GCM_SHA256",
"same_as_http": true,
"status": "HTTP/1.1 200 OK",
"suite": "TLS_AES_128_GCM_SHA256",
"tls_stat": {
"TlsDecryptError": 0,
"TlsRxSw": 1,
"TlsTxSw": 1
}
},
"aes-1.3#2": {
"attempts": 1,
"bytes": 562408,
"engine_irqs": 38,
"offer": "TLS_AES_128_GCM_SHA256",
"same_as_http": true,
"status": "HTTP/1.1 200 OK",
"suite": "TLS_AES_128_GCM_SHA256",
"tls_stat": {
"TlsDecryptError": 0,
"TlsRxSw": 1,
"TlsTxSw": 1
}
},
"aes-1.3#3": {
"attempts": 3,
"bytes": 562408,
"engine_irqs": 38,
"offer": "TLS_AES_128_GCM_SHA256",
"same_as_http": true,
"status": "HTTP/1.1 200 OK",
"suite": "TLS_AES_128_GCM_SHA256",
"tls_stat": {
"TlsDecryptError": 0,
"TlsRxSw": 1,
"TlsTxSw": 1
}
},
"cbc-1.2": {
"attempts": 3,
"bytes": 562408,
"engine_irqs": 0,
"offer": "ECDHE-ECDSA-AES128-SHA",
"same_as_http": true,
"status": "HTTP/1.1 200 OK",
"suite": "ECDHE-ECDSA-AES128-SHA",
"tls_stat": {
"TlsDecryptError": 0,
"TlsRxSw": 0,
"TlsTxSw": 0
}
},
"desktop-1.2": {
"attempts": 1,
"bytes": 562408,
"engine_irqs": 0,
"offer": "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305",
"same_as_http": true,
"status": "HTTP/1.1 200 OK",
"suite": "ECDHE-ECDSA-CHACHA20-POLY1305",
"tls_stat": {
"TlsDecryptError": 0,
"TlsRxSw": 1,
"TlsTxSw": 1
}
},
"desktop-1.3": {
"attempts": 1,
"bytes": 562408,
"engine_irqs": 0,
"offer": "TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256",
"same_as_http": true,
"status": "HTTP/1.1 200 OK",
"suite": "TLS_CHACHA20_POLY1305_SHA256",
"tls_stat": {
"TlsDecryptError": 0,
"TlsRxSw": 1,
"TlsTxSw": 1
}
}
},
"tcp_available_ulp": [
"tls"
]
},
"fingerprint": "b44575a320b2220be38d245690c213220d199eafc9f08b1390d0826fe184d7b5",
"image": "20260928182434 (dev)",
"log": [
"18:32:57 start forgectrl.tls-records (auto, api) in campaign c-20260928183105-64ee",
"18:32:57 fixture up: <REDACTED-1> at <IP-1>, v1.0.0, covers lid, interlock, button",
"18:32:57 fixture: <REDACTED-1> at <IP-1> covers lid, interlock, button",
"18:32:57 baseline: pre: clean",
"18:32:58 desktop-1.3: offer TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256 -> TLS_CHACHA20_POLY1305_SHA256, HTTP/1.1 200 OK, 562408 bytes, same True, tls_stat {'TlsTxSw': 1, 'TlsRxSw': 1, 'TlsDecryptError': 0}, 2101000.jr +0",
"18:32:58 desktop-1.2: offer ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305 -> ECDHE-ECDSA-CHACHA20-POLY1305, HTTP/1.1 200 OK, 562408 bytes, same True, tls_stat {'TlsTxSw': 1, 'TlsRxSw': 1, 'TlsDecryptError': 0}, 2101000.jr +0",
"18:32:58 aes-1.3#1: offer TLS_AES_128_GCM_SHA256 -> TLS_AES_128_GCM_SHA256, HTTP/1.1 200 OK, 562408 bytes, same True, tls_stat {'TlsTxSw': 1, 'TlsRxSw': 1, 'TlsDecryptError': 0}, 2101000.jr +38",
"18:32:58 aes-1.2#1: offer ECDHE-ECDSA-AES128-GCM-SHA256 -> ECDHE-ECDSA-AES128-GCM-SHA256, HTTP/1.1 200 OK, 562408 bytes, same True, tls_stat {'TlsTxSw': 1, 'TlsRxSw': 1, 'TlsDecryptError': 0}, 2101000.jr +38",
"18:32:58 aes-1.3#2: offer TLS_AES_128_GCM_SHA256 -> TLS_AES_128_GCM_SHA256, HTTP/1.1 200 OK, 562408 bytes, same True, tls_stat {'TlsTxSw': 1, 'TlsRxSw': 1, 'TlsDecryptError': 0}, 2101000.jr +38",
"18:32:58 aes-1.2#2: offer ECDHE-ECDSA-AES128-GCM-SHA256 -> ECDHE-ECDSA-AES128-GCM-SHA256, HTTP/1.1 200 OK, 562408 bytes, same True, tls_stat {'TlsTxSw': 1, 'TlsRxSw': 1, 'TlsDecryptError': 0}, 2101000.jr +38",
"18:32:59 aes-1.3#3: 3 other connection(s) during the window; measured again",
"18:32:59 aes-1.3#3: 2 other connection(s) during the window; measured again",
"18:33:00 aes-1.3#3: offer TLS_AES_128_GCM_SHA256 -> TLS_AES_128_GCM_SHA256, HTTP/1.1 200 OK, 562408 bytes, same True, tls_stat {'TlsTxSw': 1, 'TlsRxSw': 1, 'TlsDecryptError': 0}, 2101000.jr +38",
"18:33:01 aes-1.2#3: 3 other connection(s) during the window; measured again",
"18:33:01 aes-1.2#3: offer ECDHE-ECDSA-AES128-GCM-SHA256 -> ECDHE-ECDSA-AES128-GCM-SHA256, HTTP/1.1 200 OK, 562408 bytes, same True, tls_stat {'TlsTxSw': 1, 'TlsRxSw': 1, 'TlsDecryptError': 0}, 2101000.jr +38",
"18:33:02 cbc-1.2: 4 other connection(s) during the window; measured again",
"18:33:02 cbc-1.2: 2 other connection(s) during the window; measured again",
"18:33:03 cbc-1.2: offer ECDHE-ECDSA-AES128-SHA -> ECDHE-ECDSA-AES128-SHA, HTTP/1.1 200 OK, 562408 bytes, same True, tls_stat {'TlsTxSw': 0, 'TlsRxSw': 0, 'TlsDecryptError': 0}, 2101000.jr +0",
"18:33:03 rfc7539(chacha20,poly1305) is rfc7539(chacha20-neon,poly1305-neon); gcm(aes) is gcm_base(ctr-aes-caam,cryptd(ghash-ce-sync))",
"18:33:03 baseline: post: clean",
"18:33:03 result PASS"
],
"manifest_sha": "84a155bfc701e865ae73f9818bc38c2d005324ab5ba0ed44b668ec8896179947",
"message": "",
"result": "PASS",
"test": "forgectrl.tls-records",
"ts": "2026-09-28T18:33:03Z"
},
"requires": [],
"satisfied": true,
"source_sha": "b889408e52514262ca390450a5dd2584dacdf998c06375e8d99c227fc0e1e0f0",
"subsystem": "forgectrl",
"title": "HTTPS: ChaCha20 chosen, records sealed in the kernel"
}
],
"tool_version": "0.1.0"
}