From f9190ffddc0603c0928096cebd60174b302bee07 Mon Sep 17 00:00:00 2001 From: ScottW514 Date: Sun, 18 Oct 2026 19:45:26 -0400 Subject: [PATCH] Release v0.0.9 FORGEFIRM_RELEASE is 0.0.9, and releases/v0.0.9 carries the release notes and the acceptance artifact that forgetest exported on the bench reference. The artifact is from campaign c-20261018224638-4ca0 on the pins-only dev image 20261018222431: authorized, 43 of 43 tests satisfied, all 43 run on that image and none inherited. scripts/acceptance-gate.py against that build's release manifest gives AUTHORIZED, with inputs identical to the bench image. --- .../images/forgefirm-release.inc | 2 +- releases/v0.0.9/acceptance.json | 15851 ++++++++++++++++ releases/v0.0.9/acceptance.md | 57 + releases/v0.0.9/notes.md | 25 + 4 files changed, 15934 insertions(+), 1 deletion(-) create mode 100644 releases/v0.0.9/acceptance.json create mode 100644 releases/v0.0.9/acceptance.md create mode 100644 releases/v0.0.9/notes.md diff --git a/meta-forgefirm/recipes-forgefirm/images/forgefirm-release.inc b/meta-forgefirm/recipes-forgefirm/images/forgefirm-release.inc index a39a5e8..cfa1aff 100644 --- a/meta-forgefirm/recipes-forgefirm/images/forgefirm-release.inc +++ b/meta-forgefirm/recipes-forgefirm/images/forgefirm-release.inc @@ -17,4 +17,4 @@ # it to equal the rootfs stamp, the .fw meta-version and the release tag, # and the acceptance test image.health compares the stamp on the running # machine with the manifest's. -FORGEFIRM_RELEASE ?= "0.0.8" +FORGEFIRM_RELEASE ?= "0.0.9" diff --git a/releases/v0.0.9/acceptance.json b/releases/v0.0.9/acceptance.json new file mode 100644 index 0000000..1aea342 --- /dev/null +++ b/releases/v0.0.9/acceptance.json @@ -0,0 +1,15851 @@ +{ + "authorized": true, + "campaign": { + "catalog_hash": "b38332a30994e16a499a9ded530062291bacabf873138461dd54421e2174c29b", + "id": "c-20261018224638-4ca0", + "image": "20261018222431 (dev)", + "manifest_sha": "70ecd7867c2698d17f2f3c38db772868eda3364f541242c93fb5db4e1d593bcd", + "t": "campaign", + "ts": "2026-10-18T22:46:38Z" + }, + "catalog_hash": "b38332a30994e16a499a9ded530062291bacabf873138461dd54421e2174c29b", + "counts": { + "inherited": 0, + "required": 0, + "satisfied": 43, + "total": 43 + }, + "exported_at": "2026-10-18T23:33:36Z", + "format": 1, + "identity_sha": "60af177b23dda40eeb34d464f87ff6b65e4e2e966c1ea581514644875de9c8a4", + "image": { + "name": "forgefirm-image-dev", + "version": "20261018222431 (dev)" + }, + "invalidate": null, + "manifest": { + "build": { + "layers": { + "meta": { + "dirty": false, + "rev": "70ed6f677234d32198371a030178d2f272cf2d94" + }, + "meta-forgefirm": { + "dirty": false, + "rev": "5036517e2273fe388d31be0d4939ef3544ec3b5a" + }, + "meta-freescale": { + "dirty": false, + "rev": "b699d026506a6fc402e03afb432dcabd3d81c7ab" + }, + "meta-freescale-distro": { + "dirty": false, + "rev": "b9d6a5d9931922558046d230c1f5f4ef6ee72345" + }, + "meta-glowforge-bsp": { + "dirty": false, + "rev": "c542ce6ec5799df9cf0f689eb883c790c71a414b" + }, + "meta-networking": { + "dirty": false, + "rev": "b0c2c648a1af89e7a8dd4c2ec841f3bc0ed0ccb9" + }, + "meta-oe": { + "dirty": false, + "rev": "b0c2c648a1af89e7a8dd4c2ec841f3bc0ed0ccb9" + }, + "meta-openglow-core": { + "dirty": false, + "rev": "c542ce6ec5799df9cf0f689eb883c790c71a414b" + }, + "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", + "26b922a02a25139c2ab4dc25349d60595343e419" + ], + [ + ".gitignore", + "5a14dec4b997a715fbcc330b634860e954070cc3" + ], + [ + ".vscode/tasks.json", + "8c78e4557ab5871f4d60baba00435e5bde74d68f" + ], + [ + "AGENTS.md", + "d0c93e493845666f18f19dca605c4e5b2a63562f" + ], + [ + "CMakeLists.txt", + "cbbe2a487272ba2143b784384bff0d2f2682f970" + ], + [ + "CONTRIBUTING.md", + "ca2a98e7d617e1bca2b2f814a598e94f89186c6e" + ], + [ + "LICENSE", + "ddfa51eaa264bc020ac65023e52f60be1d8cc1cd" + ], + [ + "README.md", + "8aadec7f8267cb8e2ddcb2660a546c60a3213a27" + ], + [ + "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", + "21fd08e3f0b5fd117247166048a53495b31777ee" + ], + [ + "src/auth.h", + "bef54587e2bae70f1622c4a814404eb22f2c2b93" + ], + [ + "src/builtin.c", + "7f92ef64fff7b850a306251d4b8d00999f28cf19" + ], + [ + "src/builtin.h", + "b5e3cbf4c439c4201a6bcfda5b3724e967f08dcf" + ], + [ + "src/button.c", + "876921173b0940762d8b300c466a60150af4864b" + ], + [ + "src/button.h", + "c9abf79767336fe892413330ee920134b70c9301" + ], + [ + "src/cam.c", + "27819487ce62d7f7e8f2c4aaccb59b9402f1eb3b" + ], + [ + "src/cam.h", + "f3af1937d9a8d6504942eaea55507d8425417ea2" + ], + [ + "src/camhealth.c", + "2ce8a0e4dd6586b67b2bc9d340444c7638454311" + ], + [ + "src/camhealth.h", + "4d0765ebe62a733226fc5d1f09ff648fdb9f3645" + ], + [ + "src/camkey.c", + "7058ee497de36a3c06c8848602d017b462ad20c3" + ], + [ + "src/camkey.h", + "a33a4338e3cf3322e64b8034f57b6dc5726f6ffc" + ], + [ + "src/cool.c", + "2abe4234a613f7909e217c2c640bd35902a3e439" + ], + [ + "src/cool.h", + "3b5101adbfe8e6f4bd68c8ffe0fd11ec7c69c132" + ], + [ + "src/coolfmt.c", + "aa89421f4e2b14d37345faab3c1b2e18970001a7" + ], + [ + "src/coolfmt.h", + "55fe9b4734d508b7f58bb311cb4fa9264ccda14d" + ], + [ + "src/curverec.c", + "927136670279b3e05e2fd3bade3124bce5bf0f7c" + ], + [ + "src/curverec.h", + "f05b0eec1fdb333e708941dcc946123b93c3d1b7" + ], + [ + "src/debayer.c", + "8193350d231de08eaab92c00a27574ba3f21afae" + ], + [ + "src/debayer.h", + "66ada9cb84f29091c97a42d881a64d21b6919b41" + ], + [ + "src/diag.c", + "046d4c3dce9b3e2ea0f1b243867f8f469beb8f3e" + ], + [ + "src/diag.h", + "3c3f7da5c1a128e83e6ab64b43a97d173494515f" + ], + [ + "src/events.c", + "2d3294ae6a6e846fcbcaa888ec4d9c7299b1d0bb" + ], + [ + "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", + "9ee971b3b2d78c80dace8f6f4eebaec0df0de3b6" + ], + [ + "src/gates.h", + "73cf6cea98f4f97ae76eb549b28bb89738d9a2e5" + ], + [ + "src/gpu_debayer.c", + "c74f00b2e92883a7b09185a9c27eebadab2d3fb7" + ], + [ + "src/gpu_debayer.h", + "092f6fe1bae9dda6455763dd48a40938d99162d3" + ], + [ + "src/grblport.c", + "af7d30dae338afad2de15309a585da0a8f07b7c2" + ], + [ + "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", + "84f3cb73a9969a8bec3dae3271f4d2200917cb71" + ], + [ + "src/jobpost.h", + "34ffdd77f3387183cf739c33a6b7e7ca9139728e" + ], + [ + "src/jobrun.c", + "1f209054d10342846a265bd30c1c64089ab79854" + ], + [ + "src/jobrun.h", + "27c83fed5e18638c9183036d4e4d62d1f8b7ebc6" + ], + [ + "src/jobstream.c", + "d0bf9bd9506487b29dbce033ec2605a4e8b85b26" + ], + [ + "src/jobstream.h", + "99a98bcd7e81e63e13e046646472a4304b23c780" + ], + [ + "src/lease.c", + "49703c250efdbcc35aa8e90b820f7d9fc256759a" + ], + [ + "src/lease.h", + "1db6e25e3e54123f21e6748aec22e0c97955d646" + ], + [ + "src/led.c", + "0a80fa9c983416b9dc8610b30b65de16416e285d" + ], + [ + "src/led.h", + "22f72dfb34519d1f7a071984560763cf6ba74816" + ], + [ + "src/lens.c", + "d78ec7da0ab1893889efc4692d65f85efa4d8290" + ], + [ + "src/lens.h", + "d157a98cffcddb1bc9d405f1779e2c494c92ef17" + ], + [ + "src/lensfind.c", + "8c6890b7d79c4818c6f663a0dda6aebf25fb4415" + ], + [ + "src/lensfind.h", + "e82e3eae998b600101b03e45994e167606547902" + ], + [ + "src/lenshome.c", + "219e8d95c700ec20c5c703c5d334af6b4f8d80ea" + ], + [ + "src/lenshome.h", + "eaf10e197aad7e040bd22f117c186b6de636dd2d" + ], + [ + "src/liveness.c", + "a3244ff519e91cdebff8b4f555bfd468c24e7a56" + ], + [ + "src/liveness.h", + "88ae53c31c80386b5daf570b77c806c978357061" + ], + [ + "src/logs.c", + "60483e914e8293410468d9beccf5fee4e0c8297b" + ], + [ + "src/logs.h", + "2e4be0d770314da791a35b8b8ae4039786bab399" + ], + [ + "src/main.c", + "f2d806cf36687b6304e6df5afd417d3e9f6596c5" + ], + [ + "src/mcode.c", + "0e696f00a6ca583531a9ddd2e59419a166b4e398" + ], + [ + "src/mcode.h", + "9e4efb5d7928af1a6e9709fdd7021c342fdc4956" + ], + [ + "src/mp4mux.c", + "90dae21b0bca1fd1b84d2ed308d229e9685922bc" + ], + [ + "src/mp4mux.h", + "36cfe2f67d643fe114ab279caba5b9da388dfd22" + ], + [ + "src/paths.h", + "353d700ba7d1ca19be01ff8a6d51c7055b0e3953" + ], + [ + "src/peer.c", + "e2fdf6aad48fbc6861bf5846fafa64ac79064f8d" + ], + [ + "src/peer.h", + "705b548996451c32141db3b545b3e6f7b721c480" + ], + [ + "src/recordhtml.c", + "c23d1957cfded491cd541937ce092ac38443f96d" + ], + [ + "src/recordhtml.h", + "a0088d926c8edadcbf884372b77f5974d54da6de" + ], + [ + "src/relcheck.c", + "dd0ee9f79108b7af70c9aa513b8616f58b0f4353" + ], + [ + "src/relcheck.h", + "d8400ebcbc8221c1d126f209eb2b82da5835b018" + ], + [ + "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", + "3a912c445c07c3f5c5317982bff8ba98f2e567b4" + ], + [ + "src/setup.h", + "2b505527610445748f15a938e6b06df750b137e6" + ], + [ + "src/sha256.c", + "b8b38167cec8a586055093c6a120624049b08632" + ], + [ + "src/sha256.h", + "a8806a440e43d96866735a1da17d590491b6d55a" + ], + [ + "src/sheet.c", + "4287d80d97a072eae25654ccf19c6f38fe3dde8c" + ], + [ + "src/sheet.h", + "a0c5b99678e4ea67c60f22a4568790c3f99b0808" + ], + [ + "src/sheetid.c", + "aa63f45a50d7874e0aa2922ce21339ff17cbb5c5" + ], + [ + "src/sheetid.h", + "fe25e6648df6be8a8fb640f63e84338c342da6a6" + ], + [ + "src/status.c", + "ace129367f60a3e9c9feaee7b95d919fa5d8c4ae" + ], + [ + "src/status.h", + "87ce147e381c477c9f31012022009cdadb339422" + ], + [ + "src/super.c", + "2aca1d0b11f9dcacf485862e05aa936f81bc8501" + ], + [ + "src/super.h", + "a5350c028245e0d207742b36c3f6a3a945aa8607" + ], + [ + "src/testhook.h", + "2c93bfebe873139f6f1247a9db71f0fc5a9cd1a9" + ], + [ + "src/tls.c", + "5a311d947d091c1607d2c6a1c0d66c20b8dc10d0" + ], + [ + "src/tls.h", + "ee4d7d68f1ed89231256d349caf6b4c00632c352" + ], + [ + "src/tokens.c", + "e7f48fb277e9caf3b47dcca22a3b0331bf7f7016" + ], + [ + "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", + "16f8e738968a4c9fad2f83a34da7213de3d1f658" + ], + [ + "src/ui/index.html", + "1a3cdb3d046ccfa80236a42b2349fdc8dc30cdf4" + ], + [ + "src/ui/login.html", + "22acf58351a5a874cd2ffc2a3309fe43e8a94116" + ], + [ + "src/ui/login.js", + "d38480ff1f4eb67b2e2c356b2f2a2b82a2656fd4" + ], + [ + "src/ui/md.js", + "e879a630efd6a53b6ed16d5a4052f6b8ced21a5b" + ], + [ + "src/ui/panel.js", + "0fc084bfad0bd6d49130a3d7d70d6890f308ba94" + ], + [ + "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", + "58fb7f89e312cfce3f58d4b66a8b22ed51d8ee88" + ], + [ + "src/ui/wizard.html", + "ffa04d335994470e719ed6777b0d98b6c030f68c" + ], + [ + "src/ui/wizard.js", + "6fda00f50afe21439e8c43df53c607320ac9bbd5" + ], + [ + "src/update.c", + "78aa70a4532e14084323d4de7e9939ca7295a758" + ], + [ + "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", + "ea1955501c603b815bc657f9cfcfb68074d20480" + ], + [ + "src/wiz.h", + "96732c9791d6996123d21ee4130a9d2f0af00e53" + ], + [ + "src/wizcalc.c", + "0a4eecb0f541680191aa6219d61fdbe0dbbb05c4" + ], + [ + "src/wizcalc.h", + "e6e8dce6e4d3efa99956ce17d3ee4452b6efc550" + ], + [ + "src/wizdark.c", + "ea3c242f0f5dd5b9dce159fae4f51a2d72ad9337" + ], + [ + "src/wizdark.h", + "4b7f02a1f8881af4b059476756e131ff59f48e15" + ], + [ + "src/wizlive.c", + "5b88bde34248920bbc7bdd0ef12893898785821b" + ], + [ + "src/wizlive.h", + "34d74f911f6d0e393083194dd4de91dd36373aa9" + ], + [ + "src/wizpkg.c", + "5f3016416b20aac444efc658957c99baf1d60ea1" + ], + [ + "src/wizpkg.h", + "61da720f22873e2ba28cb44f5bd53a4517621ed1" + ], + [ + "src/wizrun.h", + "0b25bc939fb1b07c889952435b63f9382756ad46" + ], + [ + "tests/accel_test.c", + "58efc7af80341548045169074ccf64f8fc3fb326" + ], + [ + "tests/airflow_test.c", + "79e3ba5b2aa5f45c21dab0fca3b3aa1427c607d0" + ], + [ + "tests/auth_scoped_test.c", + "051f06d7281425748a677f9c02b351809fea9d0e" + ], + [ + "tests/builtin_test.c", + "41529e775dcc03f72b7825a3ad345d7473f84c01" + ], + [ + "tests/camhealth_test.c", + "32aecc993f1192c343262636b214d590a9ccf94f" + ], + [ + "tests/camkey_test.c", + "ee3838d49d5a3246c89bdddae3116180154e2dbb" + ], + [ + "tests/cool_flow_test.c", + "a2f6bb9f4326be524225319ada69f4af8db01495" + ], + [ + "tests/cool_gate_test.c", + "209119bc12469a24d18ae32eb22ad604ab429afd" + ], + [ + "tests/coolfmt_test.c", + "c41dfc0a8ce10bea8d81125f834ee8b525bd7b56" + ], + [ + "tests/curverec_fit_test.c", + "a0f7eb4c6e0d5a2db69de53a5f008caffc3a0aaa" + ], + [ + "tests/curverec_test.c", + "eecff248c7ba7c9a51b1c996fa6b08dc4d781aa5" + ], + [ + "tests/debayer_test.c", + "56c4fe062c73fd5e878cc6cac906ab883e6c15b5" + ], + [ + "tests/enclosure_wait_test.c", + "7d731329ad651dfa8df2fd587b4722eedbf68a23" + ], + [ + "tests/events_test.c", + "9163f25d05ff2206b1e2dd3fbcd5dfbdad24ca19" + ], + [ + "tests/extpkg_test.c", + "44458197a0a19fdf22002fba91e45035981568e2" + ], + [ + "tests/fflog_e2e.sh", + "94496f871c94a138bb5f7916b49b556fb3385b08" + ], + [ + "tests/fflog_e2e_test.c", + "0a69f4e6e36549966713827fabbd6d585efa222c" + ], + [ + "tests/fwproduct_test.c", + "a02fc42310edb7289e08d9233c5e778f9ea00099" + ], + [ + "tests/grblport_test.c", + "7543e3a231f5f2e4a7c4f280baf93548e624d21f" + ], + [ + "tests/holds_test.c", + "5f834bac562ccec07467fa156e6694fa4076bf03" + ], + [ + "tests/holds_wire_test.c", + "e1642c79ee3f42b61b89bd6de082210b819b973a" + ], + [ + "tests/host_ext.sh", + "d7a97bdb6c3b8052184b0de416239c65cc2123dd" + ], + [ + "tests/host_ext_forgeext.c", + "6e3d2b192ba4e6a6d46c455aedc86e59d13bbbff" + ], + [ + "tests/host_guard.sh", + "1dd3ff3236a7723337ee49b8d8454cfce5084d07" + ], + [ + "tests/host_lan.sh", + "853a8ae6a6bbef8652b16fbfd4522c11cca7d32b" + ], + [ + "tests/host_lease.sh", + "8eedd65ca43c675a29f2c70032ca6f10327fd454" + ], + [ + "tests/host_routes.sh", + "be76ebac3065d4a93892ae02988a0336dd16721b" + ], + [ + "tests/host_setup.sh", + "b2406438ed66861baba5e23bbea8c796c86442fc" + ], + [ + "tests/host_start.sh", + "6d8fc10ca356b165eea3905afa887f67c190dd18" + ], + [ + "tests/host_update.sh", + "ca635206909fa65bf9a5316eb7e99653ca2bfc79" + ], + [ + "tests/jobpost_test.c", + "07f6771b74382e508fcd88f69891009c03a64862" + ], + [ + "tests/jobrun_test.c", + "d3e62e0d9e5d0bb2c8d66dd0f882ccd59acf9486" + ], + [ + "tests/lease_test.c", + "c369d8878383de941ea8c1043ca5b05ed2cba21b" + ], + [ + "tests/lens_test.c", + "acf677522523eb55daf79c795a47ca6af9814902" + ], + [ + "tests/lenshome_test.c", + "f9e09f95efa56b2847b71c553b3384cbf01fcf5b" + ], + [ + "tests/logs_export_test.c", + "7595a3a5bc44dba465104628b0dea2ecce08d3d0" + ], + [ + "tests/logs_test.c", + "16b6f013c3625bf60ebdcf64549a23f668ed8ba2" + ], + [ + "tests/mcode_test.c", + "a935d6d93593f2e46e023f0fb89c65526f12ab38" + ], + [ + "tests/mp4mux_test.c", + "2406647623a9ef83a6b91c5b932a95a282586818" + ], + [ + "tests/recordhtml_test.c", + "b62a4dca0820900ea52371b8e66d7d9ee8585652" + ], + [ + "tests/relcheck_test.c", + "6dbb3939364850d1921444c9fd5366f099b7164e" + ], + [ + "tests/sanitize_test.c", + "add2169b6d0bcd25624669afd78da58683408d78" + ], + [ + "tests/senderout_test.c", + "d3c0eeb03f77401a085e6474c728e6185a44c417" + ], + [ + "tests/settings_dir_test.c", + "ee97a3024af1e1968602a29f3d528e91219c7192" + ], + [ + "tests/setup_test.c", + "1825cc715e36c0a3c5b3b86c45c638502410452e" + ], + [ + "tests/sha256_test.c", + "017ef369f6bff5cc0827dc74aeb1189843b052ca" + ], + [ + "tests/sheet_test.c", + "606012c287a40bf1e9e46629efc8ea4d4e410db4" + ], + [ + "tests/sheetid_test.c", + "bc923a6fea6e58461676774ee98f8b9b65c078d4" + ], + [ + "tests/status_test.c", + "8f939caf8521014ce691c138c17b214a7f041aa8" + ], + [ + "tests/super_test.c", + "fb99bc458a884932931ea3850f700c9ed4134449" + ], + [ + "tests/test_routes.py", + "e19fa48d88e14a6a6325643abbe9bab2f8d2158f" + ], + [ + "tests/tls_test.c", + "a6a59ac2ddc9d77d9c19c6b99303cb5d2073a649" + ], + [ + "tests/tokens_test.c", + "4847ecd23b6406ade57ce795849b0cbe4639e380" + ], + [ + "tests/tray_test.c", + "f28546741a452d0b937ebc1b072e7a4b1a8943d1" + ], + [ + "tests/ulfius_image.sh", + "1e564547bb3953a446ee9d806d5e2c7e22d607ec" + ], + [ + "tests/users_test.c", + "d447b90ec43e878b1b8b6f9b594bfe043a68a035" + ], + [ + "tests/wizard_walk.py", + "d1719629cf822088204f9e07eb32d6f449a2e924" + ], + [ + "tests/wizcalc_test.c", + "fb2665a4ca3438a0fa34750e718c14af0eabc82c" + ], + [ + "tests/wizlive_test.c", + "d21dbb8b145a4204879aa6cc34fbebb73052879f" + ], + [ + "tests/wizpkg_test.c", + "36c2d0e7cc262b51e7f3bb934b8009d5e6fd622d" + ], + [ + "tools/check_ui_js.py", + "84b5b84c9a400395766bd28b570f059a52691a4a" + ], + [ + "tools/devserver.py", + "de8318cce3547fd104a70e557e956d8c75d06c98" + ], + [ + "tools/frame_isolation.py", + "9cfc000346618b446156ff352f843f884f623442" + ], + [ + "tools/frame_isolation_hostile.html", + "27ead83c732895b5a696ec4223c97307e1d25747" + ], + [ + "tools/hershey_gen.py", + "d2e09fec7c28f41aa37af06f57cdd75a3a0b3d8d" + ] + ], + "pv": "0.1.34", + "recipes": [ + "forgectrl" + ], + "source": "git://github.com/openglow-org/forgectrl.git", + "srcrev": "b235be3e8ac5fcd88080b00c9d441dbda9c0014c" + }, + "forgeext": { + "component": "forgeext", + "files": [ + [ + ".github/actions/kit/action.yml", + "54ba4142eff63275dacc2a6d46eacb7f6e50a613" + ], + [ + ".github/workflows/build.yml", + "1847f4c58b7fabfd51108220b32654b1ade16847" + ], + [ + ".github/workflows/package.yml", + "c4306bdbfdb164a2276544d2e9427cc24c072ee8" + ], + [ + ".gitignore", + "2fb12249c0537a1d0c0cd12e6f181b61861720c2" + ], + [ + "AGENTS.md", + "e17173ac842c8a67a0c3128e340e9a58b02b92c5" + ], + [ + "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", + "d8a2885addbdae1c6368749a3eb70989daa5a3ce" + ], + [ + "src/cgroup.h", + "d3c19f05e39231bdffe4318ae64d79596d52ab1f" + ], + [ + "src/evfeed.c", + "9c045819f6f3dd68f2b60f276874260ba278d99e" + ], + [ + "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", + "0943e916ac0eeb96b26f9217c73f65ee13204888" + ], + [ + "src/install.h", + "68536455344cbb1f2fb9e59934edc3a32e3b0509" + ], + [ + "src/machine.c", + "f662542c4c5fb056662e951b918d6531c7732679" + ], + [ + "src/machine.h", + "3f2c42285972f334e7adca30bb3675bf80e6b27d" + ], + [ + "src/main.c", + "a36bc6076bc71e9815a0c1676420afc7921a99cc" + ], + [ + "src/manifest.c", + "b6bff9cb3a3e1ac51ce4b12a0ae1c77d293d8573" + ], + [ + "src/manifest.h", + "9c4f18f63080c8564e023374367c521f07b5ac63" + ], + [ + "src/netrules.c", + "2d8cfaa9ae2830ae070bc7784e843d8e162838c8" + ], + [ + "src/netrules.h", + "b5a72ed91127568de6a70c9debfb6260a21a3b5a" + ], + [ + "src/pkg.c", + "c1c1058396df7cf86ae1067c9cd582491fb8300c" + ], + [ + "src/pkg.h", + "9653a70c7be351ba21176f3b1cde35a78d31d592" + ], + [ + "src/quota.c", + "8ceea5997ac5ff1efba6cf69e5a3fb579a2520e2" + ], + [ + "src/quota.h", + "fda75152302e168cd713bbf7e62d089ff9c1f24d" + ], + [ + "src/run.c", + "6e8502051f49cb44c26c252e4d122484299ee0c3" + ], + [ + "src/run.h", + "d1ec00cdadd0bbb2f92186c562c1e244795247b5" + ], + [ + "src/sandbox.c", + "40c2902f41b7d82cd4501f821efbecf92b5dae25" + ], + [ + "src/sandbox.h", + "7ca05359f6a5bf050237418daa5b38b3bb83034e" + ], + [ + "src/settings.c", + "08e79bc15cb9a92b0439b99dc9c86ccdf5d5c1ee" + ], + [ + "src/settings.h", + "bb6e8ee5b54fc3e98d4f0d100c1dafacd7598163" + ], + [ + "src/state.c", + "87e4e7f9e883993c977e3bc93f95dfb908d95379" + ], + [ + "src/state.h", + "3ccfd53bb5dc1b13805de2bd91d496eeca34652c" + ], + [ + "src/super.c", + "1eef517ece818aaf627b71dcfdeae05c59f9df86" + ], + [ + "src/super.h", + "79019eb1ade6a033b28e61efaa186b52fec737ff" + ], + [ + "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", + "82d266a1e0bdd98c26697842c7fb5d3990161e34" + ], + [ + "tests/ffx_test.py", + "529cfedc7596f5fc893d6cfe8b62d8184bf57164" + ], + [ + "tests/holdkeep_test.c", + "fbfc6daaa4de6c2371c10f9d11685b4c25930743" + ], + [ + "tests/httpreq_test.c", + "cd7bebe6418d8d9a5523e90ebc69cc5d7d83e49c" + ], + [ + "tests/install_test.py", + "d85760a49e6ada83f9293236e95a8fd749ca26af" + ], + [ + "tests/manifest_test.c", + "ba4e0c050be5da978e0e297ecdc566e66de30a2e" + ], + [ + "tests/netrules_test.py", + "2c2c6eb477632b225e9add19cbef39056dc11d2d" + ], + [ + "tests/quota_test.c", + "8d2dab526aac9edbadf5270e21767bf2cb1d0d90" + ], + [ + "tests/run_test.py", + "fd06dfe55e8c7febbef4446fdb380691ff96e0ba" + ], + [ + "tests/sandbox_test.c", + "49c6e957d2714fb02dc2b28992724f2f31922704" + ], + [ + "tests/sdk_native.c", + "98d3e9d849e765b4a1920950863824aca2305fd1" + ], + [ + "tests/sdk_test.py", + "e7b3460fa53ea4562b14f376aad644249f687864" + ], + [ + "tests/settings_test.c", + "12ddef8882681b210e0d3a90ac5b6c6052fe27b8" + ], + [ + "tests/state_test.c", + "084c462d77c5ba8aa9c74014af4506e3edcd07e2" + ], + [ + "tests/super_test.c", + "3dbfa2bec74cfa1f2d921b3aabf4da613894fcc1" + ], + [ + "tests/version_test.c", + "905f0f74881aeb0468420ed39b17f27b51bd5515" + ], + [ + "tools/ffx", + "2345fdfb4036125b539b88c0993b8e208bfc0599" + ], + [ + "tools/mkffx.sh", + "137f9a62fa000b4200c0b76499a4e98ef4bd333f" + ] + ], + "pv": "0.1.5", + "recipes": [ + "forgeext" + ], + "source": "git://github.com/openglow-org/forgeext.git", + "srcrev": "ebd959256d3da9f648d6975ba740bee86ad69c7b" + }, + "forgefirm-app": { + "component": "forgefirm-app", + "files": [ + [ + ".gitattributes", + "1b30e1b56dcc0411c10ee780053d04f1c9d862e1" + ], + [ + ".github/workflows/host-tests.yml", + "58584524c1d484feb3ca9e4b3f1cc8bc1b4e6516" + ], + [ + ".gitignore", + "2d6f9ccefa02c61cfd5cabc2d8b171025eadce09" + ], + [ + "AGENTS.md", + "4a7ce5a094fd55cfadafa0163e297f58bce92d53" + ], + [ + "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", + "8ddd091c31b5ff137b059954544e5150df448999" + ], + [ + "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", + "fe458d2d4722c9f25fb465e4496f3cef70af3f6f" + ], + [ + "tests/test_feeder.py", + "97128d63718ac1145c9f0a7d9a2ec792e6eaa136" + ], + [ + "tests/test_ffmachine_agent.py", + "4620f0f6969ff340ec4dea9898bec52f1f912c7b" + ], + [ + "tests/test_ffmachine_emulator.py", + "48903249737d886cb65cd85e7132e0c56d84b71c" + ], + [ + "tests/test_ffmachine_park.py", + "e83d97622e8807657374c87ea443f4ba1ef7ba58" + ], + [ + "tests/test_gfhome_exit.py", + "d78d5def849e143687558d4e53931cd4c3549584" + ], + [ + "tests/test_gfhome_motion.py", + "581547f9565dadbeb88d72bea06c88426e31b7e1" + ], + [ + "tests/test_limits.py", + "927ca8f77cd35c55a295484ae1179e745636ac38" + ], + [ + "tests/test_machine_lid_button.py", + "70fe5c0e850c675ff42868d2bdf3e54502abc11e" + ], + [ + "tests/test_report_secret.py", + "dc1c01f094f658fa715530612ee6ef1e0915051f" + ], + [ + "tests/test_switch_bits.py", + "2c8acd285c9a7cea4c8ae0c8285b556f753c1b23" + ] + ], + "pv": "0.1.33+git", + "recipes": [ + "gfcloud", + "gfhome", + "python3-ffmachine" + ], + "source": "git://github.com/openglow-org/python3-gfhardware.git", + "srcrev": "6fb146a13c51765eec492bf758946e573ae25297" + }, + "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", + "4711297eb47c611f5bebb683aaf3a9fc139e3bf9" + ], + [ + "bench.py", + "7a32a52423325ec0b844ae6fa4d5620fee91af29" + ], + [ + "campaign.py", + "0e937d9b600fe21651085dee8987dd7db9bdf2d7" + ], + [ + "catalog.py", + "b3fd77c15b8932d95451c456f9f1914ffce1097b" + ], + [ + "coverage.py", + "6080b3275a4a7f53c830ccef48c207e266819cb5" + ], + [ + "fixture.py", + "ee907b19c040246ec0be88d444a9386ab50aacd5" + ], + [ + "hw.py", + "56f0bff7e208523c7ce47895dc185758b8c47d33" + ], + [ + "log.py", + "8df1445460358bca4027d1a4a49189ba13dbc0de" + ], + [ + "manifest.py", + "bc9ba99aa98f019c30b89d3cd39afa11c62e7ed1" + ], + [ + "page.py", + "c6c3579acd78578aebf7404cac589d07eaf4c55b" + ], + [ + "puls.py", + "07bf06dd7f119ad59b1ecbf4295e9d4c4ce92d0d" + ], + [ + "redact.py", + "f445da45df0e36c8dcb6b17d0a851610880e3ce3" + ], + [ + "runner.py", + "d23028d2fa8eba9099fc156ad0537b0b669533bc" + ], + [ + "server.py", + "70d3bc5bc1c2299264a5f4576e7d664ed71f860c" + ], + [ + "suite/__init__.py", + "e31d4cfa33b69ce7eb28edce42ce95f42a964210" + ], + [ + "suite/camera.py", + "22e1c733759c9c2b50d9ac49dda899ae8230d371" + ], + [ + "suite/cloud.py", + "490baa7f41afb43c3cbf80f8efc7a0ce5b2cf935" + ], + [ + "suite/cooling.py", + "cc6349c2aaa6258d0e5419a26cc8a75a5aeb344e" + ], + [ + "suite/exthost.py", + "292de2cc8db0f608461c881f11b4d904c840888b" + ], + [ + "suite/forgectrl.py", + "278338b0d7e64d51155869c7dcb122a7d3425104" + ], + [ + "suite/homeoff.py", + "021aa0b3922614091422251f7dfa1ed6222b3d48" + ], + [ + "suite/image.py", + "61d1986daffa4e1fa0b4d64bcf103b5d278b6174" + ], + [ + "suite/kernel.py", + "3df2be14eea6020ca998ec3e624beeb0dcb8c855" + ], + [ + "suite/laser.py", + "478dedb2d16f3e66585b9e829700de0c2aa5708f" + ], + [ + "suite/motion.py", + "3a661ce27d631df402e37025d846d5ebbdd041aa" + ], + [ + "suite/setup.py", + "f422a7df126aa54990ca6ac08ac41ef76986e24d" + ], + [ + "suite/setup_burns.py", + "d65079a39286d0781b0a0a495e8ff02eb51d73f5" + ], + [ + "suite/setup_dark.py", + "12a9d33bb1aa309a3fc89bf9616a499885fa2cf4" + ], + [ + "suite/tlsrec.py", + "5d3a22f4eabdafcfd028a866b5387fc1d0525fb2" + ], + [ + "suite/update.py", + "f799f741a365e0073f96263315bb7eb018c75078" + ], + [ + "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", + "1cfce87ffb70796e55d901a004888facffe45357" + ], + [ + ".gitignore", + "4bda5643103df4c29ca3dbad4c841a738cee1b1a" + ], + [ + ".gitmodules", + "d5e7f2dead5cfb1b00fd67e4355991eb35658914" + ], + [ + "AGENTS.md", + "40282c56d0e3506ff72692d22db5e77bedb1bdde" + ], + [ + "CMakeLists.txt", + "6af75f41bf19c5c4a4bde335e512bfe630ae3f62" + ], + [ + "CONTRIBUTING.md", + "ca2a98e7d617e1bca2b2f814a598e94f89186c6e" + ], + [ + "COPYING", + "96d5f44439ba4cecf32c1b46ed3a76fc7749488b" + ], + [ + "README.md", + "35f668db03d26355cc5badd844351cdb36f1b6c8" + ], + [ + "src/bind_addr.c", + "3ca3b27ed265c0c52e25eca97291c2e5f20a0b1d" + ], + [ + "src/bind_addr.h", + "2e3250924b9d757eea4872c6fac2d3830b11dc1b" + ], + [ + "src/boards/glowforge.h", + "dbb357c6ab412065e710ff5330b3a488a96e992d" + ], + [ + "src/build_info.h.in", + "9741f1b5f5c8efbd539dea783b0481339e88f0b2" + ], + [ + "src/ctlport.c", + "8487b859999bf55fdd053005637928961c814af3" + ], + [ + "src/ctlport.h", + "413b5bc04893b721a469c29c94db923b652271ba" + ], + [ + "src/driver.c", + "55efa3bda71d9b9a460ee420963627a6db51a614" + ], + [ + "src/driver.h", + "1e2e734779a8565c6b00e69c98d31134428cac5f" + ], + [ + "src/eeprom.c", + "eed4727a479c43704881b62659f6825eb514ebd1" + ], + [ + "src/eeprom.h", + "07be4c8c8b1e432824cb3c791915b18836c9997e" + ], + [ + "src/fflog.c", + "cdeb518386db022df74cbfff89008bf17f5a864c" + ], + [ + "src/fflog.h", + "905314b0d5be06487faecdf97720e23d2506bb4e" + ], + [ + "src/glowforge_cooling.c", + "1d8f01e410af3028b20a2ba902dbea68a48998f4" + ], + [ + "src/glowforge_cooling.h", + "ae576b4fc50dee5ddaced1c9544476cdfce08888" + ], + [ + "src/glowforge_homing.c", + "c17826cf15d6ec0e25ad63873cd897ebfb3a9987" + ], + [ + "src/glowforge_homing.h", + "5a16cd9e82aba4ea40ebb8d89b4d58e136f95f9b" + ], + [ + "src/glowforge_io.c", + "3cc1e3b18647333d36f7cbe1661f526c62addd9d" + ], + [ + "src/glowforge_io.h", + "7b714e9e1928501b25ecd6818f3840f5354e0dc9" + ], + [ + "src/glowforge_laser.c", + "29767c8ff4579cfdd9a89667fd9e437010a3b6fe" + ], + [ + "src/glowforge_laser.h", + "bc500d8c8fc5d8cd851d3a4649342bbe83f67eee" + ], + [ + "src/glowforge_mcode.c", + "acec01e2f661250b4c1c927c5565dcbc843a057e" + ], + [ + "src/glowforge_mcode.h", + "d2db188cae7d8c56af263396d08a0f9685bff63f" + ], + [ + "src/glowforge_release.c", + "8ff24224d43b73385e09f6c3c2112269047a6203" + ], + [ + "src/glowforge_release.h", + "c488fe5b59a506394f3477757f454d773dbca0f3" + ], + [ + "src/glowforge_status.c", + "973e206fe37affed7950aba4a74f7f6d3ca1def2" + ], + [ + "src/glowforge_status.h", + "584b00fe13fbe9f8887b3a77f41d19bc66bda339" + ], + [ + "src/glowforge_switch_map.h", + "ea33a30bd29a6945599023db3fd3858a21cefae7" + ], + [ + "src/glowforge_switches.c", + "98bc9c0e1147c0c42298d268266f97c36625c785" + ], + [ + "src/glowforge_switches.h", + "06e394de0bee4987a569f1d180d1ab1b08069e3b" + ], + [ + "src/glowforge_tray.c", + "9a631b415507939f20c3369c417a3b725e07ca3e" + ], + [ + "src/glowforge_tray.h", + "484e807b7736ffc17abf990bcff8e4e6112c2916" + ], + [ + "src/grbl", + "a3a8d3990604898ef611b9f22f057b4f9405f16e" + ], + [ + "src/grbl/.gitattributes", + "eb84b66b54a17195a184d5533e31919eb25c591c" + ], + [ + "src/grbl/.gitignore", + "572825f878d3b06754a0d2de957b14d2e26936b5" + ], + [ + "src/grbl/AGENTS.md", + "e2e8f312aa149b0731ffd16d86c3ba94a12731b4" + ], + [ + "src/grbl/CMakeLists.txt", + "c537b82256f2fff209d9f365e73ed1a9587b0c8c" + ], + [ + "src/grbl/COPYING", + "c7d0e6fe45d03d4e29d624028fc3b62290bfeed2" + ], + [ + "src/grbl/FORK-CHANGES.md", + "90b4250623f67f07a57f322382391502415240d2" + ], + [ + "src/grbl/README.md", + "46397c5447170ee6dc5bc5b90aec11eeced87ea8" + ], + [ + "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", + "9068be93aa5ed21c701b76d5d85730bb6eee0a71" + ], + [ + "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", + "6bbd032b42c62d96f44cc57e8408e1f8a9969ff2" + ], + [ + "src/stepper_stream.h", + "f469e3d405ab76f290a8422172d68c52bb5305ac" + ], + [ + "tests/cooling_test.c", + "542f24d0a9aa101ece74d971d8648ef9619b120a" + ], + [ + "tests/laser_arm_test.c", + "624b7940dc9619441d7fdfa689788bf9333e0caa" + ], + [ + "tests/latch_test.c", + "a415756ebbee81405f74ab646ee142f4d9fe8ee2" + ], + [ + "tests/lens_home_test.c", + "af867bd9bc31db334957532cf4b693b96bdf3999" + ], + [ + "tests/serial_test.c", + "bf1e04288123a0d3e73ab8d6e53f95e6765f99b5" + ], + [ + "tests/switch_map_test.c", + "55120d21731b854b3be997a20b0f4d963c7ff4c6" + ], + [ + "tests/switches_test.c", + "c8c482807b9580de71821c5aaa851cca4d5c69b3" + ], + [ + "tests/xy_scale_test.c", + "6b681fdc0b45e9dbed1dc2a2c0c699535435dd37" + ] + ], + "pv": "0.1.22", + "recipes": [ + "grblhal-glowforge" + ], + "source": "gitsm://github.com/openglow-org/grblHAL-glowforge.git", + "srcrev": "e15972005c6e3e3b5bcb4d7408df0eaf83b5cc43" + }, + "kernel-module-glowforge": { + "component": "kernel-module-glowforge", + "files": [ + [ + ".gitattributes", + "1b30e1b56dcc0411c10ee780053d04f1c9d862e1" + ], + [ + ".github/workflows/build.yml", + "2073e161c4686ed9a06ca211ea869ee3b60945b9" + ], + [ + ".gitignore", + "9ade51c849fa44bc129ca7e4c07d7e8b6faf4107" + ], + [ + "AGENTS.md", + "a2a38f6e336ae884533f4470af9ebae99febbe52" + ], + [ + "CONTRIBUTING.md", + "ca2a98e7d617e1bca2b2f814a598e94f89186c6e" + ], + [ + "LICENSE", + "d159169d1050894d3ea3b98e1c965c4058208fe1" + ], + [ + "Makefile", + "b1cb12d2bc437a8de5a015b7f86f3c452ee58c3f" + ], + [ + "README", + "7d5f0f7761ccd4ded2e5e37b0013d73a52074565" + ], + [ + "asm/sdma.asm", + "34e14740ca57a743854b1a0229b61cda8f00d0e5" + ], + [ + "src/cnc.c", + "63cdd026ece408d73f947b95e795aa9cdba084fa" + ], + [ + "src/cnc.h", + "fdc00c9d5259cf97bec90da3396308f00c1acbab" + ], + [ + "src/cnc_api.c", + "988a3658ef3885bbf0c32e98e12ffeaadf20eab9" + ], + [ + "src/cnc_backtrack.h", + "2dba5e6fbc354b8de520095771315054b27cfc21" + ], + [ + "src/cnc_buffer.c", + "211748e67583557f0c86f2ed5d6843831c2e8d8c" + ], + [ + "src/cnc_interlock.c", + "534f77c8260c309d8bd84f3899c4f3d632b542fb" + ], + [ + "src/cnc_interlock.h", + "9924eead9eb5885f46e82b064795f3c0d4d5aede" + ], + [ + "src/cnc_pins.c", + "408787d5d33da596c22ed3f23ed6cbaeb9299091" + ], + [ + "src/cnc_pins.h", + "590c3eb676effbf67a4668c6507eb26785a5e2f5" + ], + [ + "src/cnc_private.h", + "503cc5c768d34078be0d7d3bd7ad7fdf3815ab09" + ], + [ + "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", + "991d85d39d5cfe1df57355be4f86933172245502" + ], + [ + "tests/interlock_test.c", + "c4834dd119167672e0b6cc17f2ac745991cfccdc" + ], + [ + "tools/mx51_sdma_set.pm", + "34379246106cca3bd2aab4c8475fcadbd48848f9" + ], + [ + "tools/sdma_asm.pl", + "003c76c9b2e7f7b6103ce288a53af82bb9bf5885" + ] + ], + "pv": "0.0.8", + "recipes": [ + "kernel-module-glowforge" + ], + "source": "git://github.com/openglow-org/kernel-module-glowforge.git", + "srcrev": "dab378da805d8a31ecb6906d51fcfd3cefe3789f" + }, + "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", + "4a7ce5a094fd55cfadafa0163e297f58bce92d53" + ], + [ + "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", + "8ddd091c31b5ff137b059954544e5150df448999" + ], + [ + "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", + "fe458d2d4722c9f25fb465e4496f3cef70af3f6f" + ], + [ + "tests/test_feeder.py", + "97128d63718ac1145c9f0a7d9a2ec792e6eaa136" + ], + [ + "tests/test_ffmachine_agent.py", + "4620f0f6969ff340ec4dea9898bec52f1f912c7b" + ], + [ + "tests/test_ffmachine_emulator.py", + "48903249737d886cb65cd85e7132e0c56d84b71c" + ], + [ + "tests/test_ffmachine_park.py", + "e83d97622e8807657374c87ea443f4ba1ef7ba58" + ], + [ + "tests/test_gfhome_exit.py", + "d78d5def849e143687558d4e53931cd4c3549584" + ], + [ + "tests/test_gfhome_motion.py", + "581547f9565dadbeb88d72bea06c88426e31b7e1" + ], + [ + "tests/test_limits.py", + "927ca8f77cd35c55a295484ae1179e745636ac38" + ], + [ + "tests/test_machine_lid_button.py", + "70fe5c0e850c675ff42868d2bdf3e54502abc11e" + ], + [ + "tests/test_report_secret.py", + "dc1c01f094f658fa715530612ee6ef1e0915051f" + ], + [ + "tests/test_switch_bits.py", + "2c8acd285c9a7cea4c8ae0c8285b556f753c1b23" + ] + ], + "pv": "1.0", + "recipes": [ + "python3-gfhardware" + ], + "source": "git://github.com/openglow-org/python3-gfhardware.git", + "srcrev": "6fb146a13c51765eec492bf758946e573ae25297" + }, + "python3-gfutilities": { + "component": "python3-gfutilities", + "files": [ + [ + ".gitattributes", + "b5fe1536d1689e8526dae30678ac352ee0d8a3ff" + ], + [ + ".github/workflows/host-tests.yml", + "c51a26d023751d891d3fc5a492cafba9978970ce" + ], + [ + ".github/workflows/release.yml", + "4d56756fafce28ced411807fd054f781962a46ec" + ], + [ + ".gitignore", + "c55e64f1e292b91b593c9b55fb6bb6dc8f0245ab" + ], + [ + "AGENTS.md", + "1221e0fbfea45f6db7619319425d9ebc7494d80f" + ], + [ + "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", + "f1a47de1185d165942acad1adf62a29201ece8a5" + ], + [ + "requirements.txt", + "6408a4e749a2c4011916373f3c35279f61a80442" + ], + [ + "setup.py", + "89a704ba9939195fd8a222f094877e05a223502b" + ], + [ + "tests/test_basemachine.py", + "e96b1b1d6dcd2d4d31cd8fc7de50a168567e6838" + ], + [ + "tests/test_dispatch.py", + "e9703429bc02de983b4760d1f91665e2a0cc91ee" + ], + [ + "tests/test_firmware_policy.py", + "364920b74dca5b5aec0e9df55d54b0a51d95d448" + ], + [ + "tests/test_frame.py", + "80ae7b2acb7642f5ca83d675c717677abd1a6273" + ], + [ + "tests/test_lifecycle.py", + "7a69a015f59f3d40afca77d9d3c356b58b6dc3ad" + ], + [ + "tests/test_offline.py", + "281dabc1d7232a9923dafa3f75474da6560a85c7" + ], + [ + "tests/test_puls_header.py", + "d05dc2d3af19e4aed6b16adfedd596bad8c8f592" + ], + [ + "tests/test_pulse_source.py", + "2065a943cd1a06f9b02c89c2aaba73b6755472f9" + ], + [ + "tests/test_pulsedata.py", + "aa2185a0f536118489cbe0f9fbd46db915f1e304" + ], + [ + "tests/test_user_agent.py", + "e3629ffc4acb1063a5443e0bb700b414bd54e5b3" + ] + ], + "pv": "0.9.21+git", + "recipes": [ + "python3-gfutilities" + ], + "source": "git://github.com/openglow-org/Glowforge-Utilities.git", + "srcrev": "b9e74b8c0238a994fd19308f13ce1ff54591eb39" + } + }, + "content_sha256": "70ecd7867c2698d17f2f3c38db772868eda3364f541242c93fb5db4e1d593bcd", + "format": 1, + "image": { + "name": "forgefirm-image-dev", + "version": "20261018222431 (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": "d7a98e2fdf32b4de85c467c32013300e554f64080902a800e3f300952e3abb7a" + }, + "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": "70ecd7867c2698d17f2f3c38db772868eda3364f541242c93fb5db4e1d593bcd", + "sha256": "97018f73354c1b768b893f1538c43d8c506e06e8bd788ab4e194968910c4e5f1", + "tests": [ + { + "always": true, + "covers": [ + [ + "forgectrl", + "init/**" + ], + [ + "forgeext", + "init/**" + ], + [ + "forgectrl", + "src/main.c" + ], + [ + "forgectrl", + "src/auth.c" + ], + [ + "forgectrl", + "src/status.*" + ], + [ + "forgectrl", + "CMakeLists.txt" + ], + [ + "grblhal-glowforge", + "src/boards/**" + ], + [ + "grblhal-glowforge", + "CMakeLists.txt" + ], + [ + "kernel-module-glowforge", + "**" + ], + [ + "linux-fslc", + "**" + ] + ], + "fingerprint": "c09a5064128085b64beeaaed3c15522b475e47169d7246414ff938667998ee2b", + "hardware": "api", + "id": "image.health", + "inherited": false, + "kind": "auto", + "record": { + "answers": [], + "campaign": "c-20261018224638-4ca0", + "duration_s": 0, + "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 |___/ 20261018222431 (dev)\n\nControl panel:\n https:///\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 |___/ 20261018222431 (dev)\n\n", + "CONFIG_IMX2_WDT": "y", + "CONFIG_PANIC_ON_OOPS": "y", + "CONFIG_PREEMPT": "y", + "accept_ra": "1", + "baseline": { + "post": [], + "pre": [] + }, + "batch": { + "group": "unattended", + "ts": "2026-10-18T22:46:38Z" + }, + "cnc_free": 33521664, + "cnc_pool_bytes": 33554432, + "cnc_ring_bytes": 33554432, + "cnc_state": "idle", + "data_free_mb": 2768, + "dev_image": true, + "dhcp6_running": [], + "disable_ipv6": "0", + "extension_host_pids": [ + 481 + ], + "extension_packages": [], + "factory_mounts": [ + "/factory/img1", + "/factory/img2" + ], + "fixture": { + "channels": [ + "lid", + "interlock", + "button" + ], + "hostname": "", + "ip": "", + "released": [] + }, + "forgectrl_pids": [ + 472 + ], + "forgefirm_version": "20261018222431 (dev)", + "getty": [ + "/sbin/getty -L 115200 ttymxc0 vt102" + ], + "global": [], + "ifstate": [ + "lo", + "wlan0" + ], + "ifup_running": [], + "kernel_release": "6.12.20-fslc-fslc-g21f36a8c1ebe", + "link_local": [ + "" + ], + "mode": { + "controller": "running", + "gated": false, + "local": false, + "mode": "grbl", + "motion": "verified", + "pid": 589, + "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": [ + 472 + ], + "record_accounts": [ + "scott" + ], + "sdma_clk_enable_count": "1", + "temps": { + "chassis_c": 29.2, + "soc_c": 46.8, + "soc_throttle": 0, + "supply_raw": 593 + }, + "udhcpc": [ + "udhcpc -R -b -p /var/run/udhcpc.wlan0.pid -i wlan0 -x hostname:forgefirm-b00a" + ], + "userspace_watchdog_pids": [], + "watchdog": { + "bootstatus": "0", + "identity": "imx2+ watchdog", + "period_s": 60.0, + "state": "inactive", + "timeout": "60", + "wcr": "0x771f", + "wde": true + } + }, + "fingerprint": "c09a5064128085b64beeaaed3c15522b475e47169d7246414ff938667998ee2b", + "image": "20261018222431 (dev)", + "log": [ + "22:46:38 start image.health (auto, api) in campaign c-20261018224638-4ca0", + "22:46:38 fixture up: at , v1.0.0, covers lid, interlock, button", + "22:46:38 fixture: at covers lid, interlock, button", + "22:46:38 queued by the unattended queue opened 2026-10-18T22:46:38Z", + "22:46:38 baseline: pre: clean", + "22:46:38 forgefirm-version: 20261018222431 (dev) (manifest: 20261018222431 (dev))", + "22:46:38 CONFIG_PREEMPT=y", + "22:46:38 CONFIG_IMX2_WDT=y", + "22:46:38 CONFIG_PANIC_ON_OOPS=y", + "22:46:38 watchdog0: {'identity': 'imx2+ watchdog', 'state': 'inactive', 'timeout': '60', 'bootstatus': '0', 'wcr': '0x771f', 'wde': True, 'period_s': 60.0}", + "22:46:38 kernel release 6.12.20-fslc-fslc-g21f36a8c1ebe (manifest modules dirs: 6.12.20-fslc-fslc)", + "22:46:38 cnc/state: idle", + "22:46:38 cnc/free: 33521664 bytes", + "22:46:38 cnc-pulsebuf pool: 33554432 bytes, ring_mb: 33554432 bytes", + "22:46:38 sdma clk_enable_count: 1", + "22:46:38 forgectrl pids [472], holding /dev/glowforge: [472]", + "22:46:38 mode: {'mode': 'grbl', 'controller': 'running', 'pid': 589, 'motion': 'verified', 'gated': False, 'local': False, 'why': ''}", + "22:46:38 temps: {'chassis_c': 29.2, 'supply_raw': 593, 'soc_c': 46.8, 'soc_throttle': 0}", + "22:46:38 extension host pid [481], packages [], pool processes 0", + "22:46:38 /data/forgefirm/panel.token mode 600", + "22:46:38 /data/forgefirm/forgefirm.conf mode 600", + "22:46:38 /data/forgefirm mode 711", + "22:46:38 /data free: 2768 MiB", + "22:46:38 / mounted ro,relatime; /data rw,relatime; /var/lib rw,relatime", + "22:46:38 dev image True; /factory mounts: ['/factory/img1', '/factory/img2']", + "22:46:38 manifest 70ecd7867c26: 10 components", + "22:46:39 wlan0: 1 link-local, 0 global IPv6 address(es)", + "22:46:39 baseline: post: clean", + "22:46:39 result PASS" + ], + "manifest_sha": "70ecd7867c2698d17f2f3c38db772868eda3364f541242c93fb5db4e1d593bcd", + "message": "", + "result": "PASS", + "test": "image.health", + "ts": "2026-10-18T22:46:39Z" + }, + "requires": [], + "satisfied": true, + "source_sha": "e853691c651c9d51475848e8227713aad1752e2cd9f17b4ebb6c9ae448adc5ca", + "subsystem": "image", + "title": "Post-flash image health" + }, + { + "always": true, + "covers": [ + [ + "kernel-module-glowforge", + "**" + ], + [ + "linux-fslc", + "**" + ], + [ + "forgectrl", + "src/super.c" + ], + [ + "grblhal-glowforge", + "src/glowforge_laser.c" + ], + [ + "grblhal-glowforge", + "src/driver.c" + ] + ], + "fingerprint": "5b5c6673f7129c32caed954646694a36a2d29541616204dec59fb10c36079005", + "hardware": "api", + "id": "kernel.latch-locked-idle", + "inherited": false, + "kind": "auto", + "record": { + "answers": [], + "campaign": "c-20261018224638-4ca0", + "duration_s": 0, + "evidence": { + "baseline": { + "post": [], + "pre": [] + }, + "batch": { + "group": "unattended", + "ts": "2026-10-18T22:46:38Z" + }, + "cnc_state": "idle", + "faults": 0, + "fixture": { + "channels": [ + "lid", + "interlock", + "button" + ], + "hostname": "", + "ip": "", + "released": [] + }, + "forgectrl_laser_locked": true, + "interlock_circuit": 45, + "laser_enable": 0, + "laser_on": 0, + "laser_on_sampled": 0 + }, + "fingerprint": "5b5c6673f7129c32caed954646694a36a2d29541616204dec59fb10c36079005", + "image": "20261018222431 (dev)", + "log": [ + "22:46:39 start kernel.latch-locked-idle (auto, api) in campaign c-20261018224638-4ca0", + "22:46:39 fixture up: at , v1.0.0, covers lid, interlock, button", + "22:46:39 fixture: at covers lid, interlock, button", + "22:46:39 queued by the unattended queue opened 2026-10-18T22:46:38Z", + "22:46:39 baseline: pre: clean", + "22:46:39 cnc/state: idle", + "22:46:39 interlock_circuit: 45 (0x2d)", + "22:46:39 laser_enable (FIRE line): 0", + "22:46:39 laser_on: 0, laser_on_sampled: 0", + "22:46:39 faults: 0", + "22:46:39 forgectrl /status laser_locked=True state=idle", + "22:46:39 baseline: post: clean", + "22:46:39 result PASS" + ], + "manifest_sha": "70ecd7867c2698d17f2f3c38db772868eda3364f541242c93fb5db4e1d593bcd", + "message": "", + "result": "PASS", + "test": "kernel.latch-locked-idle", + "ts": "2026-10-18T22:46:39Z" + }, + "requires": [], + "satisfied": true, + "source_sha": "a28d36c14c91592a21bf164ca1b39ea6ae4eabdbd2d91a0ac25182a78028301c", + "subsystem": "kernel", + "title": "Laser latch locked at idle" + }, + { + "always": true, + "covers": [ + [ + "kernel-module-glowforge", + "**" + ], + [ + "linux-fslc", + "**" + ] + ], + "fingerprint": "f937296e7c7568c68373e1ff24f550d79df94a3dbdb229f1a11723597552e77c", + "hardware": "takeover", + "id": "kernel.k1-k2", + "inherited": false, + "kind": "auto", + "record": { + "answers": [], + "campaign": "c-20261018224638-4ca0", + "duration_s": 21, + "evidence": { + "baseline": { + "post": [], + "pre": [] + }, + "batch": { + "group": "unattended", + "ts": "2026-10-18T22:46:38Z" + }, + "fixture": { + "channels": [ + "lid", + "interlock", + "button" + ], + "hostname": "", + "ip": "", + "released": [] + }, + "k1": { + "faults": "0", + "state": "idle", + "stop_to_idle_s": 0.0909 + }, + "k2": { + "end_state": "idle", + "faults": "0", + "hits": [], + "laser_on_sampled": "0", + "pos_after": [ + 0, + 0, + 0, + 55001, + 55001 + ], + "pos_before": [ + 0, + 0, + 0, + 0, + 55001 + ], + "underruns": "0" + } + }, + "fingerprint": "f937296e7c7568c68373e1ff24f550d79df94a3dbdb229f1a11723597552e77c", + "image": "20261018222431 (dev)", + "log": [ + "22:46:40 start kernel.k1-k2 (auto, takeover) in campaign c-20261018224638-4ca0", + "22:46:40 fixture up: at , v1.0.0, covers lid, interlock, button", + "22:46:40 fixture: at covers lid, interlock, button", + "22:46:40 queued by the unattended queue opened 2026-10-18T22:46:38Z", + "22:46:40 baseline: pre: clean", + "22:46:40 takeover: waiting for forgectrl to be settled", + "22:46:40 baseline: /mode controller=running motion=verified", + "22:46: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", + "22:46:40 takeover: stopping the controller through forgectrl", + "22:46:40 takeover: POST /controller/stop -> 200", + "22:46:40 takeover: forgectrl stop -> rc 0", + "22:46:42 takeover: pulse device free", + "22:46:42 K1: 60001 bytes = 6.0 s of pads at 10000 Hz, ramp 125000 Hz/s", + "22:46:42 K1 pre: state=idle laser_enable=0 laser_on=0 laser_on_sampled=0 interlock=45", + "22:46:44 K1 controlled stop: state=idle after 0.0909 s, faults=0", + "22:46:48 K1 PASS: decelerating tail 0.0909 s, no burst, no fault", + "22:46:48 K2: 55001 bytes = 5.5 s; latch stays LOCKED; waypoint +200; motor_lock=15", + "22:46:48 K2 pre: state=idle laser_enable=0 laser_on=0 laser_on_sampled=0 interlock=13", + "22:46:49 K2: paused inside the pads; resuming with waypoint +200 (latch LOCKED)", + "22:46:54 K2 post: state=idle laser_enable=0 laser_on=0 laser_on_sampled=0 interlock=13", + "22:46:54 K2 done: state=idle pos before=(0, 0, 0, 0, 55001) after=(0, 0, 0, 55001, 55001)", + "22:46:54 K2 PASS: FIRE window replayed after the resume waypoint with laser_enable/laser_on at 0 throughout", + "22:46:54 takeover: forgectrl start -> rc 0", + "22:46:56 baseline: /mode controller=stopped motion=unverified", + "22:47:01 baseline: /mode controller=running motion=verified", + "22:47:02 baseline: post: clean", + "22:47:02 result PASS" + ], + "manifest_sha": "70ecd7867c2698d17f2f3c38db772868eda3364f541242c93fb5db4e1d593bcd", + "message": "", + "result": "PASS", + "test": "kernel.k1-k2", + "ts": "2026-10-18T22:47:02Z" + }, + "requires": [ + "kernel.latch-locked-idle" + ], + "satisfied": true, + "source_sha": "fdb921f759e826a1e0a3831fa0a12d240e8318f0a8a3cbb1c77f9c3ff4c842f6", + "subsystem": "kernel", + "title": "Controlled-stop floor and resume honors the locked latch" + }, + { + "always": true, + "covers": [ + [ + "kernel-module-glowforge", + "**" + ], + [ + "linux-fslc", + "**" + ] + ], + "fingerprint": "0ee8d3835b31ee77c44b3e5bf44a8cbdc9aa875baa83a9c1e8ea155a16a6f954", + "hardware": "takeover", + "id": "kernel.deadman-close", + "inherited": false, + "kind": "auto", + "record": { + "answers": [], + "campaign": "c-20261018224638-4ca0", + "duration_s": 10, + "evidence": { + "baseline": { + "post": [], + "pre": [] + }, + "batch": { + "group": "unattended", + "ts": "2026-10-18T22:46:38Z" + }, + "close": { + "faults": "0", + "halt_s": 0.0369, + "interlock_circuit": 13, + "state": "idle" + }, + "fixture": { + "channels": [ + "lid", + "interlock", + "button" + ], + "hostname": "", + "ip": "", + "released": [] + }, + "head_after": { + "measure_laser": "0", + "uv_led": "0", + "z_current": "1", + "z_enable": "1" + }, + "head_before": { + "z_current": "1", + "z_enable": "0" + } + }, + "fingerprint": "0ee8d3835b31ee77c44b3e5bf44a8cbdc9aa875baa83a9c1e8ea155a16a6f954", + "image": "20261018222431 (dev)", + "log": [ + "22:47:02 start kernel.deadman-close (auto, takeover) in campaign c-20261018224638-4ca0", + "22:47:02 fixture up: at , v1.0.0, covers lid, interlock, button", + "22:47:02 fixture: at covers lid, interlock, button", + "22:47:02 queued by the unattended queue opened 2026-10-18T22:46:38Z", + "22:47:02 baseline: pre: clean", + "22:47:02 takeover: waiting for forgectrl to be settled", + "22:47:02 baseline: /mode controller=running motion=verified", + "22:47: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", + "22:47:02 takeover: stopping the controller through forgectrl", + "22:47:02 takeover: POST /controller/stop -> 200", + "22:47:02 takeover: forgectrl stop -> rc 0", + "22:47:03 takeover: pulse device free", + "22:47:03 deadman pre: state=idle laser_enable=0 laser_on=0 laser_on_sampled=0 interlock=45", + "22:47:05 deadman post: state=idle laser_enable=0 laser_on=0 laser_on_sampled=0 interlock=13", + "22:47:05 final close: state=idle after 0.0369 s; head {'z_enable': '1', 'z_current': '1', 'measure_laser': '0', 'uv_led': '0'}", + "22:47:05 PASS: the final close halted the engine in 0.037 s, latch locked, head safed", + "22:47:05 takeover: forgectrl start -> rc 0", + "22:47:07 baseline: /mode controller=stopped motion=unverified", + "22:47:12 baseline: /mode controller=running motion=verified", + "22:47:12 baseline: post: clean", + "22:47:12 result PASS" + ], + "manifest_sha": "70ecd7867c2698d17f2f3c38db772868eda3364f541242c93fb5db4e1d593bcd", + "message": "", + "result": "PASS", + "test": "kernel.deadman-close", + "ts": "2026-10-18T22:47:12Z" + }, + "requires": [ + "kernel.k1-k2" + ], + "satisfied": true, + "source_sha": "3de85cc0a2e5ed1ff47e9ea262a85eb4518b1e33508af94bf6e0dabc89274bad", + "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": "4085907667f8b66972b3febacb34acf936cc06d361b3b2e46447f262aaf6e15f", + "hardware": "takeover", + "id": "kernel.backtrack-bounds", + "inherited": false, + "kind": "auto", + "record": { + "answers": [], + "campaign": "c-20261018224638-4ca0", + "duration_s": 18, + "evidence": { + "after": { + "faults": "0", + "max_backtrack": 0, + "state": "idle", + "underruns": "0" + }, + "baseline": { + "post": [], + "pre": [] + }, + "batch": { + "group": "unattended", + "ts": "2026-10-18T22:46:38Z" + }, + "fixture": { + "channels": [ + "lid", + "interlock", + "button" + ], + "hostname": "", + "ip": "", + "released": [] + }, + "max_backtrack": 15065, + "over_long_errno": 1, + "played": 15465 + }, + "fingerprint": "4085907667f8b66972b3febacb34acf936cc06d361b3b2e46447f262aaf6e15f", + "image": "20261018222431 (dev)", + "log": [ + "22:47:12 start kernel.backtrack-bounds (auto, takeover) in campaign c-20261018224638-4ca0", + "22:47:12 fixture up: at , v1.0.0, covers lid, interlock, button", + "22:47:12 fixture: at covers lid, interlock, button", + "22:47:12 queued by the unattended queue opened 2026-10-18T22:46:38Z", + "22:47:12 baseline: pre: clean", + "22:47:12 takeover: waiting for forgectrl to be settled", + "22:47:12 baseline: /mode controller=running motion=verified", + "22:47: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", + "22:47:12 takeover: stopping the controller through forgectrl", + "22:47:12 takeover: POST /controller/stop -> 200", + "22:47:13 takeover: forgectrl stop -> rc 0", + "22:47:13 takeover: pulse device free", + "22:47:13 60001 bytes = 6.0 s of pads at 10000 Hz; decel tail 400 steps", + "22:47:13 pre: state=idle laser_enable=0 laser_on=0 laser_on_sampled=0 interlock=45", + "22:47:15 played 15465 bytes; max_backtrack 15065", + "22:47:17 backtrack of 15065 done: state=idle max_backtrack now 0", + "22:47:23 PASS: max_backtrack tracks the played history, the boundary is enforced, and the run at it plays out clean", + "22:47:23 takeover: forgectrl start -> rc 0", + "22:47:25 baseline: /mode controller=stopped motion=unverified", + "22:47:30 baseline: /mode controller=running motion=verified", + "22:47:30 baseline: post: clean", + "22:47:30 result PASS" + ], + "manifest_sha": "70ecd7867c2698d17f2f3c38db772868eda3364f541242c93fb5db4e1d593bcd", + "message": "", + "result": "PASS", + "test": "kernel.backtrack-bounds", + "ts": "2026-10-18T22:47:30Z" + }, + "requires": [ + "kernel.k1-k2" + ], + "satisfied": true, + "source_sha": "21c1c610c4ca8748e00ec6726a647fd857c069593c258a9b559bbe2e80e0dc7a", + "subsystem": "kernel", + "title": "A backward run is bounded by the history the ring still holds" + }, + { + "always": true, + "covers": [ + [ + "kernel-module-glowforge", + "**" + ], + [ + "linux-fslc", + "**" + ] + ], + "fingerprint": "75e4582d461893d2875b5414d6023ef7c28f2742c1703f56f0ba6f4f9ee74a9b", + "hardware": "takeover", + "id": "kernel.fire-line", + "inherited": false, + "kind": "auto", + "record": { + "answers": [], + "campaign": "c-20261018224638-4ca0", + "duration_s": 43, + "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.04, + "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.51 + }, + "moved": false, + "tail": { + "acked_state": "idle", + "after_s": 6.02, + "laser_enable": "0", + "laser_on": "0", + "state": "underrun" + }, + "underruns_after": 1, + "underruns_before": 0 + }, + "baseline": { + "post": [], + "pre": [] + }, + "batch": { + "group": "unattended", + "ts": "2026-10-18T22:46:38Z" + }, + "charge_pump_alive": "0", + "fixture": { + "channels": [ + "lid", + "interlock", + "button" + ], + "hostname": "", + "ip": "", + "released": [] + }, + "hv_release_s": [ + 0.0, + 0.41, + 0.41, + 0.41 + ], + "k3": { + "end_state": "idle", + "faults": "0", + "hits": [], + "interlock_after_unlock": "5", + "laser_on_sampled": "0", + "underruns": "1" + }, + "kernel_state": "idle" + }, + "fingerprint": "75e4582d461893d2875b5414d6023ef7c28f2742c1703f56f0ba6f4f9ee74a9b", + "image": "20261018222431 (dev)", + "log": [ + "22:47:30 start kernel.fire-line (auto, takeover) in campaign c-20261018224638-4ca0", + "22:47:31 fixture up: at , v1.0.0, covers lid, interlock, button", + "22:47:31 fixture: at covers lid, interlock, button", + "22:47:31 queued by the unattended queue opened 2026-10-18T22:46:38Z", + "22:47:31 baseline: pre: clean", + "22:47:31 takeover: waiting for forgectrl to be settled", + "22:47:31 baseline: /mode controller=running motion=verified", + "22:47: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", + "22:47:31 takeover: stopping the controller through forgectrl", + "22:47:31 takeover: POST /controller/stop -> 200", + "22:47:31 takeover: forgectrl stop -> rc 0", + "22:47:33 takeover: pulse device free", + "22:47:33 fire A: stream 60001 bytes = 6.000 s", + "22:47:33 fire A pre: state=idle laser_enable=0 laser_on=0 laser_on_sampled=0 interlock=45", + "22:47:35 fire A mid (inside FIRE window): laser_enable=0 laser_on=0 laser_on_sampled=0 interlock=13", + "22:47:40 fire A done: state=idle after 6.0 s (laser_enable=0)", + "22:47:40 fire A post: state=idle laser_enable=0 laser_on=0 laser_on_sampled=0 interlock=13", + "22:47:40 fire A: moved=False underruns 0->0 faults=0", + "22:47:40 fire A PASS: latch locked, no FIRE drive, no LASER_ON", + "22:47:40 fire B: stream 60001 bytes = 6.000 s", + "22:47:40 hv off: released after 0.41 s", + "22:47:40 fire B pre: state=idle laser_enable=0 laser_on=0 laser_on_sampled=0 interlock=45", + "22:47:41 fire B: latch UNLOCKED for this run", + "22:47:42 fire B mid (inside FIRE window): laser_enable=1 laser_on=0 laser_on_sampled=0 interlock=7", + "22:47:47 fire B done: state=idle after 6.0 s (laser_enable=0)", + "22:47:47 fire B post: state=idle laser_enable=0 laser_on=0 laser_on_sampled=0 interlock=13", + "22:47:47 fire B: moved=False underruns 0->0 faults=0", + "22:47:47 fire B PASS: FIRE driven mid-window, LASER_ON off, FIRE clear at end-of-data", + "22:47:47 fire U: stream 60001 bytes = 6.000 s", + "22:47:47 hv off: released after 0.41 s", + "22:47:47 fire U pre: state=idle laser_enable=0 laser_on=0 laser_on_sampled=0 interlock=45", + "22:47:48 fire U: streaming=1, the terminal end-of-data will be a TRUE UNDERRUN", + "22:47:48 fire U: latch UNLOCKED for this run", + "22:47:49 fire U mid (inside FIRE window): laser_enable=1 laser_on=0 laser_on_sampled=0 interlock=7", + "22:47:54 fire U done: state=underrun after 6.0 s (laser_enable=0)", + "22:47:54 fire U: underrun state reached as EXPECTED; acking via stop", + "22:47:54 fire U: acked: state=idle", + "22:47:54 fire U post: state=idle laser_enable=0 laser_on=0 laser_on_sampled=0 interlock=13", + "22:47:54 fire U: moved=False underruns 0->1 faults=0", + "22:47:54 fire U PASS: true underrun, backstop dropped FIRE, stop acked", + "22:47:54 hv off: released after 0.41 s", + "22:47:54 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", + "22:47:54 K3 pre: state=idle laser_enable=0 laser_on=0 laser_on_sampled=0 interlock=45", + "22:47:55 K3: latch UNLOCKED mid-ramp; interlock=5 (bit 3 should read 0)", + "22:47:58 K3 post: state=idle laser_enable=0 laser_on=0 laser_on_sampled=0 interlock=5", + "22:47:58 K3 PASS: laser_enable stayed 0 for the entire run after the mid-ramp unlock", + "22:47:58 safe state restored: state=disabled latch=LOCKED", + "22:47:58 takeover: forgectrl start -> rc 0", + "22:48:00 baseline: /mode controller=stopped motion=unverified", + "22:48:02 fixture up: at , v1.0.0, covers lid, interlock, button", + "22:48:14 baseline: /mode controller=running motion=verified", + "22:48:14 baseline: post: clean", + "22:48:14 result PASS" + ], + "manifest_sha": "70ecd7867c2698d17f2f3c38db772868eda3364f541242c93fb5db4e1d593bcd", + "message": "", + "result": "PASS", + "test": "kernel.fire-line", + "ts": "2026-10-18T22:48:14Z" + }, + "requires": [ + "kernel.k1-k2" + ], + "satisfied": true, + "source_sha": "254ffbe9fb6338badf09cd51ce5d43ba564eb1ac3eec0692903d5fd2e16c017a", + "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": "8516093abae1415ec66123e4651f096a77853447d0a3d52accced3ec3f79ffcf", + "hardware": "takeover", + "id": "kernel.resume-lead", + "inherited": false, + "kind": "auto", + "record": { + "answers": [], + "campaign": "c-20261018224638-4ca0", + "duration_s": 22, + "evidence": { + "E": { + "data_s": 0.501, + "faults": "0", + "run_to_idle_s": 0.505, + "state": "idle", + "underruns_after": 1, + "underruns_before": 1 + }, + "L": { + "any_laser_on": false, + "driven_samples": 848, + "end_state": "idle", + "faults": "0", + "first_driven_s": 1.0036, + "inside_lead": [], + "laser_on_sampled": "0", + "last_driven_s": 2.004, + "samples": 1870 + }, + "baseline": { + "post": [], + "pre": [] + }, + "batch": { + "group": "unattended", + "ts": "2026-10-18T22:46:38Z" + }, + "charge_pump_alive": "0", + "fixture": { + "channels": [ + "lid", + "interlock", + "button" + ], + "hostname": "", + "ip": "", + "released": [] + }, + "hv_release_s": [ + 0.0, + 0.36 + ], + "kernel_state": "idle" + }, + "fingerprint": "8516093abae1415ec66123e4651f096a77853447d0a3d52accced3ec3f79ffcf", + "image": "20261018222431 (dev)", + "log": [ + "22:48:14 start kernel.resume-lead (auto, takeover) in campaign c-20261018224638-4ca0", + "22:48:15 fixture up: at , v1.0.0, covers lid, interlock, button", + "22:48:15 fixture: at covers lid, interlock, button", + "22:48:15 queued by the unattended queue opened 2026-10-18T22:46:38Z", + "22:48:15 baseline: pre: clean", + "22:48:15 takeover: waiting for forgectrl to be settled", + "22:48:15 baseline: /mode controller=running motion=verified", + "22:48: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", + "22:48:15 takeover: stopping the controller through forgectrl", + "22:48:15 takeover: POST /controller/stop -> 200", + "22:48:15 takeover: forgectrl stop -> rc 0", + "22:48:17 takeover: pulse device free", + "22:48:17 E: 501 bytes = 0.5 s of pads at 1000 Hz; resume with a 10000-byte lead (never reached)", + "22:48:17 E pre: state=idle laser_enable=0 laser_on=0 laser_on_sampled=0 interlock=45", + "22:48:18 E: idle after 0.505 s (the data is 0.501 s; a lost end-of-data would add 0.255 s)", + "22:48:18 E PASS: end-of-data before the waypoint ended the run on time", + "22:48:18 hv off: released after 0.36 s", + "22:48: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", + "22:48:18 L pre: state=idle laser_enable=0 laser_on=0 laser_on_sampled=0 interlock=45", + "22:48:21 L post: state=idle laser_enable=0 laser_on=0 laser_on_sampled=0 interlock=13", + "22:48:21 L: 1870 samples, FIRE driven in 848, first at 1.0036 s, last at 2.004 s, end state idle", + "22:48:21 L PASS: FIRE low through the 1.0 s lead, driven from the waypoint on, LASER_ON off", + "22:48:21 safe state restored: state=disabled latch=LOCKED", + "22:48:21 takeover: forgectrl start -> rc 0", + "22:48:23 baseline: /mode controller=stopped motion=unverified", + "22:48:37 baseline: /mode controller=running motion=verified", + "22:48:37 baseline: post: clean", + "22:48:37 result PASS" + ], + "manifest_sha": "70ecd7867c2698d17f2f3c38db772868eda3364f541242c93fb5db4e1d593bcd", + "message": "", + "result": "PASS", + "test": "kernel.resume-lead", + "ts": "2026-10-18T22:48:37Z" + }, + "requires": [ + "kernel.k1-k2" + ], + "satisfied": true, + "source_sha": "4e4d262d6f5a3e551640f652b67162e7c614ab5c3f9aff1e192be701060d5209", + "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": "b1ebe6beb422d98176debd8f967a5b287d693db9f459cebea3c758c0e0fabb96", + "hardware": "api", + "id": "kernel.pic-soc-load", + "inherited": false, + "kind": "auto", + "record": { + "answers": [], + "campaign": "c-20261018224638-4ca0", + "duration_s": 3, + "evidence": { + "baseline": { + "post": [], + "pre": [] + }, + "batch": { + "group": "unattended", + "ts": "2026-10-18T22:46:38Z" + }, + "control": { + "busy": { + "iqr": 2, + "max": 673, + "mean": 665.64, + "med": 665, + "min": 661, + "n": 200 + }, + "idle": { + "iqr": 2, + "max": 678, + "mean": 661.11, + "med": 660, + "min": 651, + "n": 200 + } + }, + "control_split": 5, + "fixture": { + "channels": [ + "lid", + "interlock", + "button" + ], + "hostname": "", + "ip": "", + "released": [] + }, + "pic_settle_us_after": "500", + "pic_settle_us_before": "500", + "settled": { + "busy": { + "iqr": 2, + "max": 677, + "mean": 663.47, + "med": 663, + "min": 653, + "n": 200 + }, + "idle": { + "iqr": 1, + "max": 671, + "mean": 662.59, + "med": 662, + "min": 658, + "n": 200 + } + }, + "settled_idle_moved": 2, + "settled_split": 1 + }, + "fingerprint": "b1ebe6beb422d98176debd8f967a5b287d693db9f459cebea3c758c0e0fabb96", + "image": "20261018222431 (dev)", + "log": [ + "22:48:37 start kernel.pic-soc-load (auto, api) in campaign c-20261018224638-4ca0", + "22:48:38 fixture up: at , v1.0.0, covers lid, interlock, button", + "22:48:38 fixture: at covers lid, interlock, button", + "22:48:38 queued by the unattended queue opened 2026-10-18T22:46:38Z", + "22:48:38 baseline: pre: clean", + "22:48:41 control (settle off): after sleep median 660 (iqr 2, 651..678); after spin median 665 (iqr 2, 661..673)", + "22:48:41 settled (500 us): after sleep median 662 (iqr 1, 658..671); after spin median 663 (iqr 2, 653..677)", + "22:48:41 split busy minus idle: control +5, settled +1", + "22:48:41 PASS: settled, an idle reader and a busy reader read the same (split +1); control split +5", + "22:48:41 baseline: post: clean", + "22:48:41 result PASS" + ], + "manifest_sha": "70ecd7867c2698d17f2f3c38db772868eda3364f541242c93fb5db4e1d593bcd", + "message": "", + "result": "PASS", + "test": "kernel.pic-soc-load", + "ts": "2026-10-18T22:48:41Z" + }, + "requires": [], + "satisfied": true, + "source_sha": "283ea7885d663e45432ad09e716320b05b626f962a83d2e45bc97db13077606e", + "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/button.*" + ], + [ + "forgectrl", + "src/ui/login.*" + ], + [ + "forgectrl", + "src/ui/wizard.js" + ] + ], + "fingerprint": "75a8c16ceda10074c814317e7f164f63f17b4aa06610fbbc7830e90d31807d5f", + "hardware": "api", + "id": "forgectrl.auth", + "inherited": false, + "kind": "auto", + "record": { + "answers": [], + "campaign": "c-20261018224638-4ca0", + "duration_s": 1, + "evidence": { + "alive_after_oversize": 200, + "baseline": { + "post": [], + "pre": [] + }, + "batch": { + "group": "unattended", + "ts": "2026-10-18T22:46:38Z" + }, + "controller_has_a_secret": true, + "cool_state_from_lan": 403, + "cool_state_from_lan_http": { + "location": "https:///cool/state", + "status": 302 + }, + "cool_state_from_loopback": 200, + "cool_state_from_loopback_no_secret": 403, + "fixture": { + "channels": [ + "lid", + "interlock", + "button" + ], + "hostname": "", + "ip": "", + "released": [] + }, + "fuse_noauth": 403, + "fuse_token_no_button": 403, + "host_name": 403, + "host_own_name": 200, + "host_own_name_domain": 403, + "lan_ip": "", + "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": "75a8c16ceda10074c814317e7f164f63f17b4aa06610fbbc7830e90d31807d5f", + "image": "20261018222431 (dev)", + "log": [ + "22:48:41 start forgectrl.auth (auto, api) in campaign c-20261018224638-4ca0", + "22:48:41 fixture up: at , v1.0.0, covers lid, interlock, button", + "22:48:41 fixture: at covers lid, interlock, button", + "22:48:41 queued by the unattended queue opened 2026-10-18T22:46:38Z", + "22:48:41 baseline: pre: clean", + "22:48:41 GET /status -> 200", + "22:48:41 POST /controller/stop (no token) -> 403 {'error': 'authentication required'}", + "22:48:41 POST /controller/start (no token) -> 403 {'error': 'authentication required'}", + "22:48:41 POST /mode (no token) -> 403 {'error': 'authentication required'}", + "22:48:41 POST /settings (no token) -> 403 {'error': 'authentication required'}", + "22:48:41 POST /diag/flow-verify (no token) -> 403 {'error': 'authentication required'}", + "22:48:41 POST /diag/abort (no token) -> 403 {'error': 'authentication required'}", + "22:48:41 POST /update/apply (no token) -> 403 {'error': 'authentication required'}", + "22:48:41 POST /boot (no token) -> 403 {'error': 'authentication required'}", + "22:48:41 POST /update/check (no token) -> 403 {'error': 'authentication required'}", + "22:48:41 POST /update/dismiss (no token) -> 403 {'error': 'authentication required'}", + "22:48:41 POST /system/reboot (no token) -> 403 {'error': 'authentication required'}", + "22:48:41 POST /restore/factory (no token) -> 403 {'error': 'authentication required'}", + "22:48:41 POST /restore/factory-return (no token) -> 403 {'error': 'authentication required'}", + "22:48:41 POST /system/ssh (no token) -> 403 {'error': 'authentication required'}", + "22:48:41 POST /wiz/advisories/accept (no token) -> 403 {'error': 'authentication required'}", + "22:48:41 POST /wiz/account (no token) -> 403 {'error': 'authentication required'}", + "22:48:41 POST /wiz/complete (no token) -> 403 {'error': 'authentication required'}", + "22:48:41 POST /update/upload (no token) -> 403", + "22:48:42 POST /settings (no token, 4 MiB body) -> 403", + "22:48:42 GET /status after the oversized body -> 200", + "22:48:42 GET /status Host=evil.example.net -> 403", + "22:48:42 GET /status Host=forgefirm-b00a -> 200", + "22:48:42 GET /status Host=forgefirm-b00a.example.net -> 403", + "22:48:42 GET /status Origin=http://evil.example.net -> 403", + "22:48:42 GET /status Sec-Fetch-Site=cross-site -> 403", + "22:48:42 GET /fuse-identity (no token) -> 403 {'error': 'authentication required'}", + "22:48:42 GET /fuse-identity (token, button not held) -> 403 ", + "22:48:42 POST /cool/state from loopback, no secret -> 403 the report channel is the running controller's alone", + "22:48:42 POST /cool/state from loopback with the controller's secret -> 200", + "22:48:42 POST http:///cool/state -> 302 https:///cool/state", + "22:48:42 POST https:///cool/state -> 403 {'error': 'loopback only'}", + "22:48:42 GET https:///setup?step=laser.focus (no session) -> 302 /login?next=/setup%3Fstep%3Dlaser.focus", + "22:48:42 baseline: post: clean", + "22:48:42 result PASS" + ], + "manifest_sha": "70ecd7867c2698d17f2f3c38db772868eda3364f541242c93fb5db4e1d593bcd", + "message": "", + "result": "PASS", + "test": "forgectrl.auth", + "ts": "2026-10-18T22:48:42Z" + }, + "requires": [], + "satisfied": true, + "source_sha": "caf34f23772a84eb3533dd8bfd3c175aab888648ceea8ccbe6a4d50e51464b9d", + "subsystem": "forgectrl", + "title": "API access control" + }, + { + "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/button.*" + ], + [ + "forgectrl", + "src/led.*" + ], + [ + "forgectrl", + "src/status.c" + ] + ], + "fingerprint": "5f00dfd1197c238fb3a14d3ff57044018fa83613b4b15969a8a26ec5fd9401c5", + "hardware": "api", + "id": "setup.check-switches", + "inherited": false, + "kind": "operator", + "record": { + "answers": [], + "campaign": "c-20261018224638-4ca0", + "duration_s": 4, + "evidence": { + "actions": [ + { + "by": "fixture", + "channel": "lid", + "state": "open", + "took_s": 0.26, + "ts": "2026-10-18T22:48:43Z" + }, + { + "by": "fixture", + "channel": "lid", + "state": "close", + "took_s": 0.26, + "ts": "2026-10-18T22:48:44Z" + }, + { + "by": "fixture", + "channel": "button", + "state": "press", + "took_s": 0.26, + "ts": "2026-10-18T22:48:45Z" + } + ], + "baseline": { + "post": [], + "pre": [] + }, + "batch": { + "group": "unattended", + "ts": "2026-10-18T22:46:38Z" + }, + "elapsed_s": 3.9, + "error": "", + "fixture": { + "channels": [ + "lid", + "interlock", + "button" + ], + "hostname": "", + "ip": "", + "released": [] + }, + "log": [ + "00:00 switches at start: 0x0b", + "00:00 lid-open: seen", + "00:01 lid-close: seen", + "00:01 HV enable readback: closed 0, open 0, closed 0 (did not follow the lid)", + "00:02 button-press: seen", + "00:02 button-release: seen", + "00:02 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": "5f00dfd1197c238fb3a14d3ff57044018fa83613b4b15969a8a26ec5fd9401c5", + "image": "20261018222431 (dev)", + "log": [ + "22:48:42 start setup.check-switches (operator, api) in campaign c-20261018224638-4ca0", + "22:48:42 fixture up: at , v1.0.0, covers lid, interlock, button", + "22:48:42 fixture: at covers lid, interlock, button", + "22:48:42 fixture: running unattended (no prompt can be answered)", + "22:48:42 queued by the unattended queue opened 2026-10-18T22:46:38Z", + "22:48:43 baseline: pre: clean", + "22:48:43 POST /wiz/switches/start -> 200 {'started': True, 'id': 'switches'}", + "22:48:43 switches: Open the lid.", + "22:48:43 prompt lid-open (wait): Open the lid.", + "22:48:43 ACT lid open (fixture)", + "22:48:43 ACT lid open: done after 0.3 s", + "22:48:44 switches: Close the lid.", + "22:48:44 prompt lid-close (wait): Close the lid.", + "22:48:44 ACT lid close (fixture)", + "22:48:44 ACT lid close: done after 0.3 s", + "22:48:45 switches: Press the button once.", + "22:48:45 prompt button-press (wait): Press the button once.", + "22:48:45 ACT button press (fixture)", + "22:48:45 ACT button press: done after 0.3 s", + "22:48:47 switches: {\"lid\": true, \"hv_enable_follows_lid\": false, \"button\": true, \"interlock\": \"satisfied\", \"head_present\": true}", + "22:48:47 baseline: post: clean", + "22:48:47 result PASS" + ], + "manifest_sha": "70ecd7867c2698d17f2f3c38db772868eda3364f541242c93fb5db4e1d593bcd", + "message": "", + "result": "PASS", + "test": "setup.check-switches", + "ts": "2026-10-18T22:48:47Z" + }, + "requires": [ + "forgectrl.auth" + ], + "satisfied": true, + "source_sha": "3656c25ac687bb31ac618fed8b8cd3235d1f5eb2b4bf932b2513cbb6e9c07539", + "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/button.*" + ], + [ + "forgectrl", + "src/led.*" + ], + [ + "forgectrl", + "src/cool.c" + ], + [ + "forgectrl", + "src/airflow.*" + ], + [ + "forgectrl", + "src/gates.c" + ], + [ + "forgectrl", + "src/super.c" + ] + ], + "fingerprint": "f67ce5ca242a552790891d294ba3744242ab962836590f3a7c398497ccc0450d", + "hardware": "takeover", + "id": "setup.check-airflow", + "inherited": false, + "kind": "auto", + "record": { + "answers": [], + "campaign": "c-20261018224638-4ca0", + "duration_s": 40, + "evidence": { + "baseline": { + "post": [], + "pre": [] + }, + "batch": { + "group": "unattended", + "ts": "2026-10-18T22:46:38Z" + }, + "elapsed_s": 38.2, + "error": "", + "fixture": { + "channels": [ + "lid", + "interlock", + "button" + ], + "hostname": "", + "ip": "", + "released": [] + }, + "intakes": { + "counted": "2", + "found": 2, + "intake_2_silent": false + }, + "log": [ + "00:00 fans to run duty, purge on", + "00:38 exhaust: 11620 rpm steady, 90 percent at 4.5 s", + "00:38 intake 1: 4152 rpm steady, 90 percent at 6.6 s", + "00:38 intake 2: 4159 rpm steady, 90 percent at 6.6 s", + "00:38 air assist: 10885 rpm steady, 90 percent at 0.8 s", + "00:38 purge current 629 on, 1 off", + "00:38 floors: exhaust 6391, intake 2283, air assist 5987, purge 346; grace 12 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": 630, + "state": "idle" + }, + "purge_air": "1", + "took_s": 0.010473251342773438 + }, + "result": { + "fans": { + "air assist": { + "ok": true, + "spinup_s": 0.8, + "steady_rpm": 10885.0 + }, + "exhaust": { + "ok": true, + "spinup_s": 4.5, + "steady_rpm": 11620.0 + }, + "intake 1": { + "ok": true, + "spinup_s": 6.6, + "steady_rpm": 4152.0 + }, + "intake 2": { + "ok": true, + "spinup_s": 6.6, + "steady_rpm": 4159.0 + } + }, + "floors": { + "cool_fan_grace_s": "12", + "cool_purge_min_current": "346", + "cool_tach_air_assist_min_rpm": "5987", + "cool_tach_exhaust_min_rpm": "6391", + "cool_tach_intake_min_rpm": "2283" + }, + "intake_fans": 2, + "purge_current_off": 1.0, + "purge_current_on": 629.0 + }, + "settings_before": { + "cool_fan_grace_s": "12", + "cool_intake_fans": "2", + "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": "f67ce5ca242a552790891d294ba3744242ab962836590f3a7c398497ccc0450d", + "image": "20261018222431 (dev)", + "log": [ + "22:48:47 start setup.check-airflow (auto, takeover) in campaign c-20261018224638-4ca0", + "22:48:47 fixture up: at , v1.0.0, covers lid, interlock, button", + "22:48:47 fixture: at covers lid, interlock, button", + "22:48:47 queued by the unattended queue opened 2026-10-18T22:46:38Z", + "22:48:47 baseline: pre: clean", + "22:48:47 POST /wiz/airflow/start -> 200 {'started': True, 'id': 'airflow'}", + "22:48:47 airflow: stopping the motion controller", + "22:48:48 airflow: fans to the run profile for 35 s", + "22:49:18 fixture up: at , v1.0.0, covers lid, interlock, button", + "22:49:23 airflow: purge off, reading the off current", + "22:49:26 intake fans: 2 (the machine counted 2)", + "22:49:26 exhaust: 11620.0 rpm steady, 90 percent at 4.5 s", + "22:49:26 intake 1: 4152.0 rpm steady, 90 percent at 6.6 s", + "22:49:26 intake 2: 4159.0 rpm steady, 90 percent at 6.6 s", + "22:49:26 air assist: 10885.0 rpm steady, 90 percent at 0.8 s", + "22:49:26 floors: {\"cool_tach_exhaust_min_rpm\": \"6391\", \"cool_tach_intake_min_rpm\": \"2283\", \"cool_tach_air_assist_min_rpm\": \"5987\", \"cool_purge_min_current\": \"346\", \"cool_fan_grace_s\": \"12\"}", + "22:49:26 purge after the check: commanded 1, drawing 630 against the 345 floor (after 0.0 s)", + "22:49:26 restore cool_tach_exhaust_min_rpm='6416' -> 200", + "22:49:26 restore cool_tach_intake_min_rpm='2277' -> 200", + "22:49:26 restore cool_tach_air_assist_min_rpm='6093' -> 200", + "22:49:26 restore cool_purge_min_current='345' -> 200", + "22:49:26 restore cool_fan_grace_s='12' -> 200", + "22:49:26 restore cool_intake_fans='2' -> 200", + "22:49:27 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", + "22:49:27 baseline: post: clean", + "22:49:27 result PASS" + ], + "manifest_sha": "70ecd7867c2698d17f2f3c38db772868eda3364f541242c93fb5db4e1d593bcd", + "message": "", + "result": "PASS", + "test": "setup.check-airflow", + "ts": "2026-10-18T22:49:27Z" + }, + "requires": [ + "forgectrl.auth" + ], + "satisfied": true, + "source_sha": "dde4e1601f9b9c4395d241c0578d5213511e9b789ed6be9703a1683a2a7660f8", + "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/button.*" + ], + [ + "forgectrl", + "src/led.*" + ], + [ + "forgectrl", + "src/super.c" + ], + [ + "forgectrl", + "src/liveness.c" + ], + [ + "forgectrl", + "src/lenshome.*" + ], + [ + "forgectrl", + "src/accel.c" + ], + [ + "forgectrl", + "src/cool.c" + ] + ], + "fingerprint": "5afda9620a292412677b073b95dbf9c95a48aa7a08aa79f20d2dc424d9a29541", + "hardware": "takeover", + "id": "setup.check-motion", + "inherited": false, + "kind": "auto", + "record": { + "answers": [], + "campaign": "c-20261018224638-4ca0", + "duration_s": 20, + "evidence": { + "baseline": { + "post": [], + "pre": [] + }, + "batch": { + "group": "unattended", + "ts": "2026-10-18T22:46:38Z" + }, + "elapsed_s": 20.2, + "error": "", + "fixture": { + "channels": [ + "lid", + "interlock", + "button" + ], + "hostname": "", + "ip": "", + "released": [] + }, + "log": [ + "00:06 liveness probe: head accel p2p x=3537 y=1407 (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 276 y 182 (rms 153 72) over 176 samples", + "00:15 +X: accelerometer low-passed p2p x 2441 y 784 (rms 821 369, raw p2p 4230 2067, 190 sampl", + "00:17 -X: accelerometer low-passed p2p x 2394 y 858 (rms 794 365, raw p2p 4614 2207, 193 sampl", + "00:18 +Y: accelerometer low-passed p2p x 906 y 1373 (rms 393 392, raw p2p 4228 2254, 196 sampl", + "00:19 -Y: accelerometer low-passed p2p x 862 y 1158 (rms 306 305, raw p2p 2702 1977, 193 sampl" + ], + "phases": [ + "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", + "the head at rest", + "jog +X", + "jog -X", + "jog +Y", + "jog -Y" + ], + "result": { + "moves": { + "+X": { + "crash_event": false, + "p2p_lp_x": 2441, + "p2p_lp_y": 784, + "p2p_x": 4230, + "p2p_y": 2067, + "rms_x": 821.0, + "rms_y": 369.0, + "samples": 190, + "witnessed": true + }, + "+Y": { + "crash_event": false, + "p2p_lp_x": 906, + "p2p_lp_y": 1373, + "p2p_x": 4228, + "p2p_y": 2254, + "rms_x": 393.0, + "rms_y": 392.0, + "samples": 196, + "witnessed": true + }, + "-X": { + "crash_event": false, + "p2p_lp_x": 2394, + "p2p_lp_y": 858, + "p2p_x": 4614, + "p2p_y": 2207, + "rms_x": 794.0, + "rms_y": 365.0, + "samples": 193, + "witnessed": true + }, + "-Y": { + "crash_event": false, + "p2p_lp_x": 862, + "p2p_lp_y": 1158, + "p2p_x": 2702, + "p2p_y": 1977, + "rms_x": 306.0, + "rms_y": 305.0, + "samples": 193, + "witnessed": true + } + }, + "probe": "head accel p2p x=3537 y=1407 (moving>=800 dead<=250)", + "rail": "up", + "rest": { + "p2p_lp_x": 276, + "p2p_lp_y": 182, + "p2p_x": 976, + "p2p_y": 475, + "rms_x": 153.0, + "rms_y": 72.0, + "samples": 176 + }, + "z_passes": [ + 0, + 0, + 0, + 0, + 0 + ], + "z_referenced": true + }, + "started": true + }, + "fingerprint": "5afda9620a292412677b073b95dbf9c95a48aa7a08aa79f20d2dc424d9a29541", + "image": "20261018222431 (dev)", + "log": [ + "22:49:43 start setup.check-motion (auto, takeover) in campaign c-20261018224638-4ca0", + "22:49:43 fixture up: at , v1.0.0, covers lid, interlock, button", + "22:49:43 fixture: at covers lid, interlock, button", + "22:49:43 queued by the unattended queue opened 2026-10-18T22:46:38Z", + "22:49:43 baseline: pre: clean", + "22:49:43 NOTICE: The head moves 50 mm each way on X and on Y. Keep the bed clear.", + "22:49:43 POST /wiz/motion/start -> 200 {'started': True, 'id': 'motion'}", + "22:49:43 motion: stopping the motion controller", + "22:49:44 motion: rail up, the liveness probe", + "22:49:49 motion: the lens hall reference", + "22:49:50 motion: the lens finds its reference on the hall sensor: pass 1 of 5", + "22:49:52 motion: the lens finds its reference on the hall sensor: pass 2 of 5", + "22:49:53 motion: the lens finds its reference on the hall sensor: pass 3 of 5", + "22:49:54 motion: the lens finds its reference on the hall sensor: pass 4 of 5", + "22:49:55 motion: the lens finds its reference on the hall sensor: pass 5 of 5", + "22:49:56 motion: starting the controller in loopback posture", + "22:49:56 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.", + "22:49:57 motion: the head at rest", + "22:49:58 motion: jog +X", + "22:49:59 motion: jog -X", + "22:50:00 motion: jog +Y", + "22:50:01 motion: jog -Y", + "22:50:03 motion: probe 'head accel p2p x=3537 y=1407 (moving>=800 dead<=250)', passes [0, 0, 0, 0, 0], rest {'samples': 176, 'p2p_lp_x': 276, 'p2p_lp_y': 182, 'p2p_x': 976, 'p2p_y': 475, 'rms_x': 153.0, 'rms_y': 72.0}, moves {'+X': (2441, 784), '-X': (2394, 858), '+Y': (906, 1373), '-Y': (862, 1158)}", + "22:50:03 baseline: post: clean", + "22:50:03 result PASS" + ], + "manifest_sha": "70ecd7867c2698d17f2f3c38db772868eda3364f541242c93fb5db4e1d593bcd", + "message": "", + "result": "PASS", + "test": "setup.check-motion", + "ts": "2026-10-18T22:50:03Z" + }, + "requires": [ + "forgectrl.auth", + "motion.pacing" + ], + "satisfied": true, + "source_sha": "c0cbdbed26872925bb3801b972f636d6fcb907b589c24de839be236790f76c57", + "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/button.*" + ], + [ + "forgectrl", + "src/led.*" + ], + [ + "forgectrl", + "src/lensfind.*" + ], + [ + "forgectrl", + "src/lens.*" + ], + [ + "forgectrl", + "src/lenshome.*" + ], + [ + "forgectrl", + "src/accel.c" + ], + [ + "forgectrl", + "src/cool.c" + ], + [ + "forgectrl", + "src/super.c" + ] + ], + "fingerprint": "fdd1044cb2708e08b3a15b64a97e499b02bf34c2704d19d2064261d074f31892", + "hardware": "takeover", + "id": "setup.check-lens", + "inherited": false, + "kind": "auto", + "record": { + "answers": [], + "campaign": "c-20261018224638-4ca0", + "duration_s": 20, + "evidence": { + "baseline": { + "post": [], + "pre": [] + }, + "batch": { + "group": "unattended", + "ts": "2026-10-18T22:46:38Z" + }, + "elapsed_s": 19.1, + "error": "", + "fixture": { + "channels": [ + "lid", + "interlock", + "button" + ], + "hostname": "", + "ip": "", + "released": [] + }, + "log": [ + "00:02 lens reference pass 1: 0", + "00:03 lens reference pass 2: 0", + "00:16 bottom ring 1-12 (x100): 39 117 72 156 88 89 56 155 108 90 67 211", + "00:16 the stops could not be found: the lens slipped at the bottom stop before its ring died", + "00:18 the lens window: 10 half-steps below the reference, 12 above (the fallback)", + "00:19 lens: lens on the hall edge (3 off, 3 back)" + ], + "phases": [ + "the fans stop before the listening: 1 s of 10", + "the fans stop before the listening: 2 s of 10", + "the fans stop before the listening: 3 s of 10", + "the fans stop before the listening: 4 s of 10", + "the fans stop before the listening: 5 s of 10", + "the fans stop before the listening: 6 s of 10", + "the fans stop before the listening: 7 s of 10", + "the fans stop before the listening: 8 s of 10", + "the fans stop before the listening: 9 s of 10", + "finding the bottom stop by the head accelerometer: 4 half-steps below the edge", + "finding the bottom stop by the head accelerometer: 9 half-steps below the edge", + "finding the bottom stop by the head accelerometer: 12 half-steps below the edge" + ], + "restart": { + "mode": "grbl", + "pid": 1473, + "start": 200, + "stop": 200 + }, + "result": { + "stops": { + "above": 0, + "below": 0, + "contact_above": 0, + "contact_below": 0, + "found": false, + "why": "the lens slipped at the bottom stop before its ring died" + }, + "summary": "The stops could not be found on this head (the lens slipped at the bottom stop before its ring died). The lens keeps a reduced travel that clears the stops on any head. Please open an issue at github.com/openglow-org/forgefirm or post on community.openglow.org so the head can be looked at.", + "window": { + "above": 12, + "below": 10, + "found": false + }, + "z_passes": [ + 0, + 0 + ] + }, + "settings_before": { + "lens_stop_above_steps": "20", + "lens_stop_below_steps": "14" + }, + "started": true, + "window": { + "settings": [ + "10", + "12" + ], + "status": { + "above": 12, + "below": 10, + "edge_z": 4.51, + "reach_max": 8.62, + "reach_min": 1.09, + "stops_found": true, + "tray": "in", + "tray_offset_mm": 34.29 + }, + "stops": { + "above": 0, + "below": 0, + "contact_above": 0, + "contact_below": 0, + "found": false, + "why": "the lens slipped at the bottom stop before its ring died" + }, + "window": { + "above": 12, + "below": 10, + "found": false + } + } + }, + "fingerprint": "fdd1044cb2708e08b3a15b64a97e499b02bf34c2704d19d2064261d074f31892", + "image": "20261018222431 (dev)", + "log": [ + "22:50:04 start setup.check-lens (auto, takeover) in campaign c-20261018224638-4ca0", + "22:50:04 fixture up: at , v1.0.0, covers lid, interlock, button", + "22:50:04 fixture: at covers lid, interlock, button", + "22:50:04 queued by the unattended queue opened 2026-10-18T22:46:38Z", + "22:50:04 baseline: pre: clean", + "22:50:04 POST /wiz/lens.travel/start -> 200 {'started': True, 'id': 'lens.travel'}", + "22:50:04 lens.travel: stopping the motion controller", + "22:50:05 lens.travel: the lens finds its reference on the hall sensor", + "22:50:06 lens.travel: the lens finds its reference on the hall sensor: pass 1 of 2", + "22:50:07 lens.travel: the lens finds its reference on the hall sensor: pass 2 of 2", + "22:50:08 lens.travel: the fans stop before the listening: 0 s of 10", + "22:50:09 lens.travel: the fans stop before the listening: 1 s of 10", + "22:50:10 lens.travel: the fans stop before the listening: 2 s of 10", + "22:50:11 lens.travel: the fans stop before the listening: 3 s of 10", + "22:50:12 lens.travel: the fans stop before the listening: 4 s of 10", + "22:50:13 lens.travel: the fans stop before the listening: 5 s of 10", + "22:50:14 lens.travel: the fans stop before the listening: 6 s of 10", + "22:50:15 lens.travel: the fans stop before the listening: 7 s of 10", + "22:50:16 lens.travel: the fans stop before the listening: 8 s of 10", + "22:50:17 lens.travel: the fans stop before the listening: 9 s of 10", + "22:50:18 lens.travel: finding the bottom stop by the head accelerometer: 4 half-steps below the edge", + "22:50:19 lens.travel: finding the bottom stop by the head accelerometer: 9 half-steps below the edge", + "22:50:20 lens.travel: finding the bottom stop by the head accelerometer: 12 half-steps below the edge", + "22:50:23 lens travel: 10 half-steps below the edge, 12 above (the fallback: the lens slipped at the bottom stop before its ring died); contact 0/0", + "22:50:23 restore lens_stop_below_steps='14' -> 200", + "22:50:23 restore lens_stop_above_steps='20' -> 200", + "22:50:23 restarting the controller on the window as found: POST /controller/stop -> 200 {'stopped': True}", + "22:50:23 POST /controller/start -> 200 {'started': True}", + "22:50:24 baseline: post: clean", + "22:50:24 result PASS" + ], + "manifest_sha": "70ecd7867c2698d17f2f3c38db772868eda3364f541242c93fb5db4e1d593bcd", + "message": "", + "result": "PASS", + "test": "setup.check-lens", + "ts": "2026-10-18T22:50:24Z" + }, + "requires": [ + "forgectrl.auth", + "setup.check-motion" + ], + "satisfied": true, + "source_sha": "438e014057796d154c7f14e14832c3c2a5712212a623a1e6f7dbcde0c49e9876", + "subsystem": "setup", + "title": "The lens travel check finds the stops and writes the window" + }, + { + "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/button.*" + ], + [ + "forgectrl", + "src/led.*" + ], + [ + "forgectrl", + "src/super.c" + ], + [ + "python3-gfhardware", + "gfhardware/machine.py" + ], + [ + "python3-gfhardware", + "forgefirm-app/gfcloud.py" + ], + [ + "python3-gfhardware", + "forgefirm-app/ffmachine.py" + ] + ], + "fingerprint": "21f011466a227b6551c24ed95622049622d6820bda0b72b31e9f73048b175ec0", + "hardware": "takeover", + "id": "setup.cloud-header-capture", + "inherited": false, + "kind": "operator", + "record": { + "answers": [], + "campaign": "c-20261018224638-4ca0", + "duration_s": 76, + "evidence": { + "baseline": { + "post": [], + "pre": [] + }, + "batch": { + "group": "attended", + "ts": "2026-10-18T23:07:24Z" + }, + "elapsed_s": 75.5, + "error": "", + "fixture": { + "channels": [ + "lid", + "interlock", + "button" + ], + "hostname": "", + "ip": "", + "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": [ + "01:11 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", + "back to GRBL mode" + ], + "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-10-18T23:08:35Z", + "job_id": 1596428785, + "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": "21f011466a227b6551c24ed95622049622d6820bda0b72b31e9f73048b175ec0", + "image": "20261018222431 (dev)", + "log": [ + "23:07:24 start setup.cloud-header-capture (operator, takeover) in campaign c-20261018224638-4ca0", + "23:07:24 fixture up: at , v1.0.0, covers lid, interlock, button", + "23:07:24 fixture: at covers lid, interlock, button", + "23:07:24 queued by the attended queue opened 2026-10-18T23:07:24Z", + "23:07:24 baseline: pre: clean", + "23:07:24 mode: test needs grbl - already in grbl mode", + "23:07:24 NOTICE: Print any small design from the Glowforge app once it shows the machine online. Do not press the machine's button.", + "23:07:24 POST /wiz/cloud.header/start -> 200 {'started': True, 'id': 'cloud.header'}", + "23:07:25 cloud.header: starting the cloud client", + "23:07:29 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.", + "23:07:30 cloud.header: waiting for the print's header from the service", + "23:07:54 fixture up: at , v1.0.0, covers lid, interlock, button", + "23:08:26 fixture up: at , v1.0.0, covers lid, interlock, button", + "23:08:36 cloud.header: the cloud client cancels the print", + "23:08:39 cloud.header: back to GRBL mode", + "23:08:40 header: 134 tags, 57 kept; job 1596428785", + "23:08:40 restore cloud_enabled='1' -> 200", + "23:08:40 restore homing_mode='manual' -> 200", + "23:08:40 restore controller_mode='grbl' -> 200", + "23:08:40 baseline: post: clean", + "23:08:40 result PASS" + ], + "manifest_sha": "70ecd7867c2698d17f2f3c38db772868eda3364f541242c93fb5db4e1d593bcd", + "message": "", + "result": "PASS", + "test": "setup.cloud-header-capture", + "ts": "2026-10-18T23:08:40Z" + }, + "requires": [ + "forgectrl.auth", + "cloud.mode-switch" + ], + "satisfied": true, + "source_sha": "094090b0111d8701eb5225b06008c1f937b024d58b371b1a2df0ca304888b2f7", + "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/lenshome.*" + ], + [ + "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" + ], + [ + "grblhal-glowforge", + "src/glowforge_laser.c" + ], + [ + "grblhal-glowforge", + "src/glowforge_status.c" + ], + [ + "grblhal-glowforge", + "src/glowforge_homing.*" + ], + [ + "grblhal-glowforge", + "src/glowforge_io.*" + ] + ], + "fingerprint": "96b8d738499d0f273c6934be167cdba4338987f5ca9a24011efd7f52edac9a5e", + "hardware": "takeover", + "id": "setup.focus", + "inherited": false, + "kind": "live", + "record": { + "answers": [], + "campaign": "c-20261018224638-4ca0", + "duration_s": 88, + "evidence": { + "actions": [ + { + "by": "operator", + "channel": "button", + "state": "presence", + "took_s": 3.4, + "ts": "2026-10-18T23:09:56Z" + }, + { + "by": "fixture", + "channel": "button", + "state": "arm", + "ts": "2026-10-18T23:10:07Z" + } + ], + "baseline": { + "post": [], + "pre": [] + }, + "batch": { + "group": "attended", + "ts": "2026-10-18T23:07:24Z" + }, + "elapsed_s": 69.9, + "emission": { + "beam_sensor_seen": true, + "hv_max": 1023, + "laser_on_samples": 235, + "lit_s": 47.34946822399979, + "thermopile_delta": 1202 + }, + "emission_seen": { + "hv_max": 1016, + "laser_on_max": 235, + "reads": 70 + }, + "error": "", + "fixture": { + "channels": [ + "lid", + "interlock", + "button" + ], + "hostname": "", + "ip": "", + "released": [] + }, + "focus_window": { + "edge": "6.94", + "held": { + "settings": { + "lens_stop_above_steps": "20", + "lens_stop_below_steps": "14" + }, + "stops_found": true, + "window": [ + 14, + 20 + ] + }, + "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": 3922, + "program_lines": 295, + "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": [ + -1.44, + 10.19 + ], + "stops_found": true, + "z": [ + 3.35, + 10.19, + 9.17, + 8.14, + 7.11, + 6.09, + 5.06, + 3.69, + 2.67, + 1.64, + 0.61, + -0.41, + -1.44, + 3.35 + ] + }, + "window": { + "above": 20, + "below": 14, + "reach_max": 10.194626967830253, + "reach_min": -1.4412388774811773 + } + }, + "head_at_start": { + "home_source": "startup", + "homed_axes": 4, + "judged": false, + "pos": { + "x": 0.0, + "y": 0.0, + "z": 4.45 + } + }, + "lens_fresh": { + "above": 20, + "below": 14, + "edge_z": 3.35, + "reach_max": 10.19, + "reach_min": -1.44, + "stops_found": true, + "tray": "in", + "tray_offset_mm": 34.29 + }, + "log": [ + "00:02 lens reference pass 1: 0", + "00:04 lens reference pass 2: 0", + "00:05 lens: lens on the hall edge (3 off, 3 back)", + "00:05 the head is home, the operator says", + "01:09 streamed 298 lines; tube current peak 1023, LASER_ON samples 235, thermopile +1202", + "01:09 line 11 on 0.125 in: -11 half-steps from the hall edge, so the focus at the edge is 0.27" + ], + "mode": { + "detail": "already in grbl mode", + "found": "grbl", + "needs": "grbl", + "ok": true, + "switched": false + }, + "operator": { + "ack_live": true, + "ts": "2026-10-18T23:09:52Z" + }, + "phases": [ + "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 samples run on, 0 s more", + "the tube is dark: the pulse engine plays the rest" + ], + "program_tail": { + "laser.focus": [ + "G0 Z6.94", + "G0 X0 Y0", + "G92.1", + "M2" + ] + }, + "program_z": { + "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 + ] + } + }, + "restart": { + "mode": "grbl", + "pid": 5563, + "start": 200, + "stop": 200 + }, + "result": { + "edge_z_mm": 6.939544832306639, + "emission": { + "beam_sensor_seen": true, + "hv_max": 1023, + "laser_on_samples": 235, + "lit_s": 47.34946822399979, + "thermopile_delta": 1202 + }, + "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, + "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 lens reaches 0.085 in to 0.543 in, a reduced travel until the Lens travel check runs.", + "thickness_mm": 3.175, + "window": { + "above": 20, + "below": 14, + "reach_max": 10.194626967830253, + "reach_min": -1.4412388774811773 + }, + "z_passes": [ + 0, + 0 + ] + }, + "settings_before": { + "lens_hall_edge_z_mm": "4.51", + "lens_stop_above_steps": "20", + "lens_stop_below_steps": "14" + }, + "started": true, + "thickness_answer": "0.125" + }, + "fingerprint": "96b8d738499d0f273c6934be167cdba4338987f5ca9a24011efd7f52edac9a5e", + "image": "20261018222431 (dev)", + "log": [ + "23:09:52 start setup.focus (live, takeover) in campaign c-20261018224638-4ca0", + "23:09:52 fixture up: at , v1.0.0, covers lid, interlock, button", + "23:09:52 fixture: at covers lid, interlock, button", + "23:09:52 queued by the attended queue opened 2026-10-18T23:07:24Z", + "23:09:52 baseline: pre: clean", + "23:09:52 mode: test needs grbl - already in grbl mode", + "23:09:52 NOTICE: The focus burn: twelve lines on the scrap after a press. The bench presses when the button lights. Then press the button on the machine to start.", + "23:09:52 READY: waiting for the operator's press on the machine (the bench then does every press in this test)", + "23:09:56 READY: operator present (press after 3.4 s); the bench takes the presses", + "23:09:56 the head's place rests on the operator's word at the ready gate (X and Y unreferenced: homed_axes 4, home_source startup, pos {'x': 0.0, 'y': 0.0, 'z': 4.45})", + "23:09:56 POST /wiz/laser.focus/start -> 200 {'started': True, 'id': 'laser.focus'}", + "23:09:56 prompt gantry-stops (confirm): This burn is drawn from the head's home against the gantry stops (Install, Gantry stops). Are the gantry stops installed?", + "23:09:57 laser.focus: the lens finds its reference on the hall sensor: pass 1 of 2", + "23:09:59 laser.focus: the lens finds its reference on the hall sensor: pass 2 of 2", + "23:10:01 laser.focus: starting the motion controller: 0 s (60 at most)", + "23:10:01 prompt home (choice): Every card is drawn from the head's home: the back-left corner, against the gantry stops. Is the head there?", + "23:10:02 laser.focus: the cooling engine takes the controller's report: 0 s (20 at most)", + "23:10:03 prompt scrap (continue): Open the lid and put a flat scrap of wood, at least 3.071 in by 2.677 in, in the back-left corner of the cut area: as far left as it goes, its top edge at the top of the cut area. Close the lid.", + "23:10:04 prompt thickness (number): The scrap's thickness in inches.", + "23:10:06 prompt focus-arm (continue): The lens is on its hall reference. Twelve 1.772 in lines burn heavy, the lens stepped from 0.269 in above the reference to 0.189 in below it (a reduced travel: run the Lens travel check for this head's own). Lid closed. Continue, then press the button when it lights white; this page says when.", + "23:10:07 laser.focus: the program goes to the controller, the button lights at the arm", + "23:10:07 prompt press (wait): The button is lit white. Press it now: the laser fires after your press.", + "23:10:07 ARM press by the fixture, at the machine's own press prompt", + "23:10:08 laser.focus: the button is lit: press it now (1 s; the job waits 600 at most)", + "23:10:09 laser.focus: the program goes to the controller, the button lights at the arm: 2 s", + "23:10:10 laser.focus: the program goes to the controller, the button lights at the arm: 3 s", + "23:10:11 laser.focus: the program goes to the controller, the button lights at the arm: 4 s", + "23:10:12 laser.focus: the program goes to the controller, the button lights at the arm: 5 s", + "23:10:13 laser.focus: the program goes to the controller, the button lights at the arm: 6 s", + "23:10:14 laser.focus: the program goes to the controller, the button lights at the arm: 7 s", + "23:10:15 laser.focus: the program goes to the controller, the button lights at the arm: 8 s", + "23:10:16 laser.focus: the program goes to the controller, the button lights at the arm: 9 s", + "23:10:17 laser.focus: burning: 1 s lit", + "23:10:18 laser.focus: burning: 2 s lit", + "23:10:19 laser.focus: burning: 3 s lit", + "23:10:20 laser.focus: burning: 4 s lit", + "23:10:21 laser.focus: burning: the tube is between passes", + "23:10:22 laser.focus: burning: 0 s lit", + "23:10:22 fixture up: at , v1.0.0, covers lid, interlock, button", + "23:10:26 laser.focus: burning: the tube is between passes", + "23:10:27 laser.focus: burning: 0 s lit", + "23:10:28 laser.focus: burning: the tube is between passes", + "23:10:29 laser.focus: burning: 0 s lit", + "23:10:30 laser.focus: burning: the tube is between passes", + "23:10:33 laser.focus: burning: 1 s lit", + "23:10:34 laser.focus: burning: the tube is between passes", + "23:10:35 laser.focus: burning: 0 s lit", + "23:10:36 laser.focus: burning: 1 s lit", + "23:10:37 laser.focus: burning: the tube is between passes", + "23:10:38 laser.focus: burning: 1 s lit", + "23:10:39 laser.focus: burning: 2 s lit", + "23:10:40 laser.focus: burning: 0 s lit", + "23:10:41 laser.focus: burning: 1 s lit", + "23:10:42 laser.focus: burning: the tube is between passes", + "23:10:43 laser.focus: burning: 1 s lit", + "23:10:44 laser.focus: burning: 2 s lit", + "23:10:45 laser.focus: burning: the tube is between passes", + "23:10:46 laser.focus: burning: 1 s lit", + "23:10:47 laser.focus: burning: the tube is between passes", + "23:10:48 laser.focus: burning: 0 s lit", + "23:10:49 laser.focus: burning: 1 s lit", + "23:10:50 laser.focus: burning: the tube is between passes", + "23:10:51 laser.focus: burning: 1 s lit", + "23:10:52 laser.focus: burning: the tube is between passes", + "23:10:53 fixture up: at , v1.0.0, covers lid, interlock, button", + "23:10:53 laser.focus: burning: 0 s lit", + "23:10:54 laser.focus: burning: 1 s lit", + "23:10:55 laser.focus: burning: the tube is between passes", + "23:10:56 laser.focus: burning: 1 s lit", + "23:10:57 laser.focus: burning: 2 s lit", + "23:10:58 laser.focus: burning: 0 s lit", + "23:10:59 laser.focus: burning: 1 s lit", + "23:11:00 laser.focus: burning: the tube is between passes", + "23:11:01 laser.focus: burning: 1 s lit", + "23:11:02 laser.focus: burning: 2 s lit", + "23:11:03 laser.focus: burning: the tube is between passes", + "23:11:04 laser.focus: the tube is dark: the samples run on, 0 s more", + "23:11:05 laser.focus: the tube is dark: the pulse engine plays the rest", + "23:11:05 prompt focus-pick (multichoice): Which dark line is the narrowest, with the crispest edges? Count from the top, 1 to 12. Neighbors can look the same, since the depth of focus spans a few lines: choose every one that does, and the middle is taken. Then Done. Look, but do not move the scrap until the step is done.", + "23:11:06 seen from here: LASER_ON count peak 235, tube current peak 1016 over 70 polls", + "23:11:06 the beam sensor rose 1202 (seen: True)", + "23:11:06 focus: line 11.0, the edge at 6.939544832306639 mm, the window 14/20", + "23:11:06 restore lens_hall_edge_z_mm='4.51' -> 200", + "23:11:07 restore lens_stop_below_steps='14' -> 200", + "23:11:07 restore lens_stop_above_steps='20' -> 200", + "23:11:07 restarting the controller on the edge and the window as found: POST /controller/stop -> 200 {'stopped': True}", + "23:11:07 POST /controller/start -> 200 {'started': True}", + "23:11:07 PASS: the focus burn ran in the window the machine holds and wrote the edge alone; settings restored and the controller restarted on them", + "23:11:20 baseline: cool: smoke/armed=False/hold=False ended on its own after 13 s; the engine's own post-job work, not a leftover", + "23:11:20 baseline: post: clean", + "23:11:20 result PASS" + ], + "manifest_sha": "70ecd7867c2698d17f2f3c38db772868eda3364f541242c93fb5db4e1d593bcd", + "message": "", + "result": "PASS", + "test": "setup.focus", + "ts": "2026-10-18T23:11:20Z" + }, + "requires": [ + "forgectrl.auth", + "setup.check-motion", + "laser.emission-witness", + "setup.check-lens" + ], + "satisfied": true, + "source_sha": "b52ac2f2a3851019f35159261b4e4eaa8657c2b9c145ce6cf4c95317d6032130", + "subsystem": "setup", + "title": "The focus burn: the ladder in the lens window, and the edge it writes" + }, + { + "always": false, + "covers": [ + [ + "grblhal-glowforge", + "src/**" + ], + [ + "kernel-module-glowforge", + "**" + ], + [ + "forgectrl", + "src/super.*" + ], + [ + "forgectrl", + "src/liveness.*" + ] + ], + "fingerprint": "65e2c1530968698934ea7b650cb06a08fc766520ebf5cfe5f9d285cd28b56508", + "hardware": "api", + "id": "motion.pacing", + "inherited": false, + "kind": "auto", + "record": { + "answers": [], + "campaign": "c-20261018224638-4ca0", + "duration_s": 15, + "evidence": { + "baseline": { + "post": [], + "pre": [] + }, + "batch": { + "group": "unattended", + "ts": "2026-10-18T22:46:38Z" + }, + "controller_pid": 1298, + "final_drift_mm": 0.0, + "fixture": { + "channels": [ + "lid", + "interlock", + "button" + ], + "hostname": "", + "ip": "", + "released": [] + }, + "held_state": "Hold:0", + "idle_cpu_pct": 1.3, + "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.3 + }, + "fingerprint": "65e2c1530968698934ea7b650cb06a08fc766520ebf5cfe5f9d285cd28b56508", + "image": "20261018222431 (dev)", + "log": [ + "22:49:27 start motion.pacing (auto, api) in campaign c-20261018224638-4ca0", + "22:49:27 fixture up: at , v1.0.0, covers lid, interlock, button", + "22:49:27 fixture: at covers lid, interlock, button", + "22:49:27 queued by the unattended queue opened 2026-10-18T22:46:38Z", + "22:49:27 baseline: pre: clean", + "22:49:27 mode: test needs grbl - already in grbl mode", + "22:49:28 connect: Idle", + "22:49:31 [1] idle CPU = 1.3%", + "22:49:33 [3] state=Run CPU during move = 32.0%", + "22:49:37 [2] Hold:0: CPU parked in Hold = 1.3%", + "22:49:39 [4] start X=0.000 end X=30.000 moved=30.000 (expect 30.0)", + "22:49:42 PASS: idle 1.3%, moving 32.0%, parked 1.3%, hold/resume exact", + "22:49:43 baseline: post: clean", + "22:49:43 result PASS" + ], + "manifest_sha": "70ecd7867c2698d17f2f3c38db772868eda3364f541242c93fb5db4e1d593bcd", + "message": "", + "result": "PASS", + "test": "motion.pacing", + "ts": "2026-10-18T22:49:43Z" + }, + "requires": [ + "kernel.latch-locked-idle" + ], + "satisfied": true, + "source_sha": "7c0b5ccb1507dcc058d662e1b6c07cb7b4de32ff73fa9daab45834b3984933a1", + "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.*" + ], + [ + "forgectrl", + "src/main.c" + ] + ], + "fingerprint": "167f7bc47a2856820b32b2051804688c42b76d95902f22b48366dc475e710d2c", + "hardware": "api", + "id": "motion.jog-roundtrip", + "inherited": false, + "kind": "auto", + "record": { + "answers": [], + "campaign": "c-20261018224638-4ca0", + "duration_s": 18, + "evidence": { + "accel_moving_legs": [ + "X max-rate 60mm back", + "diag 40mm back" + ], + "accel_overall": { + "errors": 0, + "p2p": [ + 3934, + 1766 + ], + "samples": 17 + }, + "baseline": { + "post": [], + "pre": [] + }, + "batch": { + "group": "unattended", + "ts": "2026-10-18T22:46:38Z" + }, + "drift_mm": 0.0, + "final": [ + 0.0, + 0.0, + 4.449 + ], + "fixture": { + "channels": [ + "lid", + "interlock", + "button" + ], + "hostname": "", + "ip": "", + "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": [ + 2, + 181 + ], + "accel_samples": 2, + "leg": "out", + "name": "X sanity 40mm", + "peak": 2400.0, + "states": [ + "Jog", + "Idle" + ], + "t0": 1792363825.4100647, + "t1": 1792363826.524853 + }, + { + "accel_p2p": [ + 725, + 531 + ], + "accel_samples": 3, + "leg": "back", + "name": "X sanity 40mm", + "peak": 2400.0, + "states": [ + "Jog", + "Idle" + ], + "t0": 1792363826.5250788, + "t1": 1792363827.6371784 + }, + { + "accel_p2p": [ + 464, + 141 + ], + "accel_samples": 3, + "leg": "out", + "name": "Y sanity 40mm", + "peak": 2400.0, + "states": [ + "Jog", + "Idle" + ], + "t0": 1792363827.6374068, + "t1": 1792363828.7526503 + }, + { + "accel_p2p": [ + 493, + 124 + ], + "accel_samples": 2, + "leg": "back", + "name": "Y sanity 40mm", + "peak": 2400.0, + "states": [ + "Jog", + "Idle" + ], + "t0": 1792363828.7528515, + "t1": 1792363829.8636105 + }, + { + "accel_p2p": [ + 139, + 230 + ], + "accel_samples": 2, + "leg": "out", + "name": "X max-rate 60mm", + "peak": 10500.0, + "states": [ + "Jog", + "Idle" + ], + "t0": 1792363829.8638222, + "t1": 1792363830.5692635 + }, + { + "accel_p2p": [ + 2239, + 12 + ], + "accel_samples": 2, + "leg": "back", + "name": "X max-rate 60mm", + "peak": 10500.0, + "states": [ + "Jog", + "Idle" + ], + "t0": 1792363830.5694687, + "t1": 1792363831.2644637 + }, + { + "accel_p2p": [ + 0, + 0 + ], + "accel_samples": 1, + "leg": "out", + "name": "diag 40mm", + "peak": 8000.0, + "states": [ + "Jog", + "Idle" + ], + "t0": 1792363831.2646766, + "t1": 1792363831.9733396 + }, + { + "accel_p2p": [ + 833, + 1722 + ], + "accel_samples": 2, + "leg": "back", + "name": "diag 40mm", + "peak": 8000.0, + "states": [ + "Jog", + "Idle" + ], + "t0": 1792363831.9735389, + "t1": 1792363832.6655304 + } + ], + "reset": { + "faults": [ + "0", + "0" + ], + "homed_after": 4, + "homed_before": 4, + "kernel_after": [ + 3487, + 0, + 0, + 0, + 0 + ], + "kernel_before": [ + 0, + 0, + 0, + 1421172, + 1421172 + ], + "kernel_delta_steps": [ + 3487, + 0, + 0 + ], + "kernel_end_state": "idle", + "kernel_handed_back": [ + 0, + 0, + 0, + 67339, + 67339 + ], + "last_running_s": 0.3381, + "left_running_s": 0.3441, + "lost_messages": [], + "mpos_after": [ + 16.345, + 0.0, + 4.449 + ], + "mpos_before": [ + 0.0, + 0.0, + 4.449 + ], + "mpos_delta_steps": [ + 3486.93, + 0.0, + 0.0 + ], + "queue_at_x": 22301, + "ramp_rate": 500000, + "ramp_s": 0.2235, + "ramp_ticks": 12686, + "readback_log": [ + "2026-10-18T22:50:39.323005+00:00 grblhal[1494] INFO soft reset: the kernel ramped the motion down; the position drops 31 0 0 steps that never played" + ], + "ring_after": 0, + "ring_at_idle": 315, + "samples": 59, + "spm": [ + 213.33299, + 213.33299, + 2.922 + ], + "state_after_x": "Alarm", + "step_freq": 112640, + "t_x": 1792363838.974, + "tail": { + "fraction": 0.037, + "rate_hz": 4188, + "window_s": 0.0291 + }, + "underruns": [ + 1, + 1 + ], + "unlock": [ + "[MSG:Caution: Unlocked]", + "ok" + ] + }, + "start": [ + 0.0, + 0.0, + 4.449 + ] + }, + "fingerprint": "167f7bc47a2856820b32b2051804688c42b76d95902f22b48366dc475e710d2c", + "image": "20261018222431 (dev)", + "log": [ + "22:50:24 start motion.jog-roundtrip (auto, api) in campaign c-20261018224638-4ca0", + "22:50:24 fixture up: at , v1.0.0, covers lid, interlock, button", + "22:50:24 fixture: at covers lid, interlock, button", + "22:50:24 queued by the unattended queue opened 2026-10-18T22:46:38Z", + "22:50:24 baseline: pre: clean", + "22:50:24 mode: test needs grbl - already in grbl mode", + "22:50:25 connect: Idle", + "22:50:26 X sanity 40mm out: peak 2400 mm/min, states ['Jog', 'Idle']; accel p2p x=2 y=181 over 2 samples", + "22:50:27 X sanity 40mm back: peak 2400 mm/min, states ['Jog', 'Idle']; accel p2p x=725 y=531 over 3 samples", + "22:50:28 Y sanity 40mm out: peak 2400 mm/min, states ['Jog', 'Idle']; accel p2p x=464 y=141 over 3 samples", + "22:50:29 Y sanity 40mm back: peak 2400 mm/min, states ['Jog', 'Idle']; accel p2p x=493 y=124 over 2 samples", + "22:50:30 X max-rate 60mm out: peak 10500 mm/min, states ['Jog', 'Idle']; accel p2p x=139 y=230 over 2 samples", + "22:50:31 X max-rate 60mm back: peak 10500 mm/min, states ['Jog', 'Idle']; accel p2p x=2239 y=12 over 2 samples", + "22:50:31 diag 40mm out: peak 8000 mm/min, states ['Jog', 'Idle']; accel p2p x=0 y=0 over 1 samples", + "22:50:32 diag 40mm back: peak 8000 mm/min, states ['Jog', 'Idle']; accel p2p x=833 y=1722 over 2 samples", + "22:50:32 accel over all 8 legs: p2p x=3934 y=1766 (17 samples, 0 errors); motion seen on 2 legs", + "22:50:34 after !: Hold:0", + "22:50:36 after ~: states ['Run', 'Idle']", + "22:50:42 soft reset during the move: kernel idle 344 ms after the ^X (queue 22301 ticks at the ^X, ramp 12686 ticks over 224 ms), tail {'window_s': 0.0291, 'rate_hz': 4188, 'fraction': 0.037}; kernel delta [3487, 0, 0] steps, MPos delta [3486.93, 0.0, 0.0] steps, homed 4 -> 4, ring 0 after the reset, read-back ['2026-10-18T22:50:39.323005+00:00 grblhal[1494] INFO soft reset: the kernel ramped the motion down; the position drops 31 0 0 steps that never played']", + "22:50:42 final drift 0.000 mm (start (0.0, 0.0, 4.449), final (0.0, 0.0, 4.449))", + "22:50:42 PASS: 8 jogs, peak 10500 mm/min, hold parked, drift 0.000 mm, accel p2p 3934 over the jogs, motion on 2 of 8 legs", + "22:50:42 baseline: post: clean", + "22:50:42 result PASS" + ], + "manifest_sha": "70ecd7867c2698d17f2f3c38db772868eda3364f541242c93fb5db4e1d593bcd", + "message": "", + "result": "PASS", + "test": "motion.jog-roundtrip", + "ts": "2026-10-18T22:50:42Z" + }, + "requires": [ + "kernel.latch-locked-idle", + "kernel.k1-k2" + ], + "satisfied": true, + "source_sha": "c06681105fb24527a6b7a9e194d0ae67556a2b514dab4b44a7fa1e4d3a83bf83", + "subsystem": "motion", + "title": "Motion quality: bounded jogs, max rate, diagonal, hold/resume, a soft reset during a move" + }, + { + "always": false, + "covers": [ + [ + "grblhal-glowforge", + "src/**" + ], + [ + "kernel-module-glowforge", + "**" + ], + [ + "forgectrl", + "src/super.*" + ], + [ + "forgectrl", + "src/liveness.*" + ], + [ + "forgectrl", + "src/main.c" + ], + [ + "forgectrl", + "src/settings.*" + ] + ], + "fingerprint": "d35091e337f818139ee937c9119bb858d26cfc3bcc582a684ef77cfb72985761", + "hardware": "api", + "id": "motion.microstep-modes", + "inherited": false, + "kind": "auto", + "record": { + "answers": [], + "campaign": "c-20261018224638-4ca0", + "duration_s": 24, + "evidence": { + "baseline": { + "post": [], + "pre": [] + }, + "batch": { + "group": "unattended", + "ts": "2026-10-18T22:46:38Z" + }, + "fixture": { + "channels": [ + "lid", + "interlock", + "button" + ], + "hostname": "", + "ip": "", + "released": [] + }, + "mode": { + "detail": "already in grbl mode", + "found": "grbl", + "needs": "grbl", + "ok": true, + "switched": false + }, + "modes": [ + { + "$100": 53.333, + "$101": 53.333, + "accel_p2p": [ + 2826, + 586 + ], + "accel_samples": 5, + "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": [ + 3373, + 439 + ], + "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": [ + 3419, + 472 + ], + "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": "d35091e337f818139ee937c9119bb858d26cfc3bcc582a684ef77cfb72985761", + "image": "20261018222431 (dev)", + "log": [ + "22:50:43 start motion.microstep-modes (auto, api) in campaign c-20261018224638-4ca0", + "22:50:43 fixture up: at , v1.0.0, covers lid, interlock, button", + "22:50:43 fixture: at covers lid, interlock, button", + "22:50:43 queued by the unattended queue opened 2026-10-18T22:46:38Z", + "22:50:43 baseline: pre: clean", + "22:50:43 mode: test needs grbl - already in grbl mode", + "22:50:43 --- x8 ---", + "22:50:45 baseline: /mode controller=running motion=verified", + "22:50:46 baseline: controller configured 1.0 s after running", + "22:50:47 connect: Idle", + "22:50:49 x8: out 39.990 mm by the kernel, peak 9578/9578 mm/min, drift 0.000 mm, accel p2p x=2826 y=586 over 5 samples", + "22:50:49 --- x16 ---", + "22:50:52 baseline: /mode controller=running motion=verified", + "22:50:53 baseline: controller configured 1.0 s after running", + "22:50:53 connect: Idle", + "22:50:56 x16: out 40.000 mm by the kernel, peak 9580/9580 mm/min, drift 0.000 mm, accel p2p x=3373 y=439 over 5 samples", + "22:50:56 --- x32 ---", + "22:50:59 baseline: /mode controller=running motion=verified", + "22:51:00 baseline: controller configured 1.0 s after running", + "22:51:00 connect: Idle", + "22:51:03 x32: out 40.000 mm by the kernel, peak 9579/9579 mm/min, drift 0.000 mm, accel p2p x=3419 y=472 over 5 samples", + "22:51:05 baseline: /mode controller=running motion=verified", + "22:51:06 baseline: controller configured 1.0 s after running", + "22:51:07 PASS: x8: 39.990 mm, drift 0.000, accel 2826; x16: 40.000 mm, drift 0.000, accel 3373; x32: 40.000 mm, drift 0.000, accel 3419", + "22:51:07 baseline: post: clean", + "22:51:07 result PASS" + ], + "manifest_sha": "70ecd7867c2698d17f2f3c38db772868eda3364f541242c93fb5db4e1d593bcd", + "message": "", + "result": "PASS", + "test": "motion.microstep-modes", + "ts": "2026-10-18T22:51:07Z" + }, + "requires": [ + "motion.jog-roundtrip" + ], + "satisfied": true, + "source_sha": "73e3878439b4589d44de7d62818de18b54db8244930e5d8e2c508848af3ad440", + "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": "13a6687b9e1cd4d5005886cc68b30931f9461a9b23b32e26e945720c933ffcd1", + "hardware": "api", + "id": "motion.liveness-probe", + "inherited": false, + "kind": "auto", + "record": { + "answers": [], + "campaign": "c-20261018224638-4ca0", + "duration_s": 9, + "evidence": { + "baseline": { + "post": [], + "pre": [] + }, + "batch": { + "group": "unattended", + "ts": "2026-10-18T22:46:38Z" + }, + "fixture": { + "channels": [ + "lid", + "interlock", + "button" + ], + "hostname": "", + "ip": "", + "released": [] + }, + "masked_restart": { + "mode": { + "controller": "running", + "gated": false, + "local": false, + "mode": "grbl", + "motion": "verified", + "pid": 1711, + "why": "" + }, + "motor_lock_after": "0", + "probe_lines": [ + "2026-10-18T22:51:14.369551+00:00 forgectrl[1683] INFO super: liveness probe: MOTION OK - head accel p2p x=3491 y=1456 (moving>=800 dead<=250)" + ] + }, + "mode_after": { + "controller": "running", + "gated": false, + "local": false, + "mode": "grbl", + "motion": "verified", + "pid": 1622, + "why": "" + }, + "mode_before": { + "controller": "running", + "gated": false, + "local": false, + "mode": "grbl", + "motion": "verified", + "pid": 1622, + "why": "" + } + }, + "fingerprint": "13a6687b9e1cd4d5005886cc68b30931f9461a9b23b32e26e945720c933ffcd1", + "image": "20261018222431 (dev)", + "log": [ + "22:51:07 start motion.liveness-probe (auto, api) in campaign c-20261018224638-4ca0", + "22:51:07 fixture up: at , v1.0.0, covers lid, interlock, button", + "22:51:07 fixture: at covers lid, interlock, button", + "22:51:07 queued by the unattended queue opened 2026-10-18T22:46:38Z", + "22:51:08 baseline: pre: clean", + "22:51:08 mode: {'mode': 'grbl', 'controller': 'running', 'pid': 1622, 'motion': 'verified', 'gated': False, 'local': False, 'why': ''}", + "22:51:08 mode after: {'mode': 'grbl', 'controller': 'running', 'pid': 1622, 'motion': 'verified', 'gated': False, 'local': False, 'why': ''}", + "22:51:08 masked every axis (cnc/motor_lock=15); restarting forgectrl for a fresh probe", + "22:51:16 super: liveness probe: MOTION OK - head accel p2p x=3491 y=1456 (moving>=800 dead<=250)", + "22:51:16 kernel X 0.0 -> 0.0 mm across the probe (out and back)", + "22:51:16 PASS: masked restart probed MOTION OK on the first try, mask cleared, controller up", + "22:51:16 baseline: post: clean", + "22:51:16 result PASS" + ], + "manifest_sha": "70ecd7867c2698d17f2f3c38db772868eda3364f541242c93fb5db4e1d593bcd", + "message": "", + "result": "PASS", + "test": "motion.liveness-probe", + "ts": "2026-10-18T22:51:16Z" + }, + "requires": [ + "kernel.latch-locked-idle" + ], + "satisfied": true, + "source_sha": "c0696e95b8c60c40589e2470d437dda25a60c78a854c8db3bd78cb6307717861", + "subsystem": "motion", + "title": "Supervisor motion-liveness verdict" + }, + { + "always": false, + "covers": [ + [ + "grblhal-glowforge", + "src/**" + ], + [ + "kernel-module-glowforge", + "**" + ], + [ + "forgectrl", + "src/super.*" + ], + [ + "forgectrl", + "src/liveness.*" + ], + [ + "forgectrl", + "src/main.c" + ], + [ + "forgectrl", + "init/**" + ] + ], + "fingerprint": "583f95537e21401412908d5861c0de976d1ecfcd8f37dc56b945aa3272fd67d6", + "hardware": "api", + "id": "motion.deadman", + "inherited": false, + "kind": "auto", + "record": { + "answers": [], + "campaign": "c-20261018224638-4ca0", + "duration_s": 45, + "evidence": { + "baseline": { + "post": [], + "pre": [] + }, + "batch": { + "group": "unattended", + "ts": "2026-10-18T22:46:38Z" + }, + "fixture": { + "channels": [ + "lid", + "interlock", + "button" + ], + "hostname": "", + "ip": "", + "released": [] + }, + "homing_kill": { + "homing_mode": "manual", + "kernel_state_at_respawn": "idle", + "mode_after": { + "controller": "running", + "gated": false, + "local": false, + "mode": "grbl", + "motion": "verified", + "pid": 1904, + "why": "" + }, + "pulse_holders": [ + "forgectrl", + "grblHAL_glowfor" + ], + "respawn_s": 2.0, + "runner_gone_s": 2.0123884677886963, + "super_lines": [ + "2026-10-18T22:52:00.421374+00:00 forgectrl[1809] 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": 1865, + "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-10-18T22:51:33.637493+00:00 grblhal[1751] WARNING gfstream: run: 94 late events clamped (max behind 92.5 ms, lead 10 ms) - step generation was starved of CPU" + }, + "sigkill": { + "new": { + "controller": "running", + "gated": false, + "local": false, + "mode": "grbl", + "motion": "verified", + "pid": 1751, + "why": "" + }, + "old_pid": 1711, + "respawn_s": 1.2, + "unlocked_seen": false + }, + "sigstop": { + "after": { + "controller": "running", + "gated": false, + "local": false, + "mode": "grbl", + "motion": "verified", + "pid": 1751, + "why": "" + }, + "halt_s": 0.21, + "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": "583f95537e21401412908d5861c0de976d1ecfcd8f37dc56b945aa3272fd67d6", + "image": "20261018222431 (dev)", + "log": [ + "22:51:16 start motion.deadman (auto, api) in campaign c-20261018224638-4ca0", + "22:51:16 fixture up: at , v1.0.0, covers lid, interlock, button", + "22:51:16 fixture: at covers lid, interlock, button", + "22:51:16 queued by the unattended queue opened 2026-10-18T22:46:38Z", + "22:51:16 baseline: pre: clean", + "22:51:16 mode: test needs grbl - already in grbl mode", + "22:51:17 connect: Idle", + "22:51:18 SIGKILL sent to controller pid 1711 mid-move", + "22:51:19 after SIGKILL: respawned as {'mode': 'grbl', 'controller': 'running', 'pid': 1751, 'motion': 'verified', 'gated': False, 'local': False, 'why': ''} in 1.2 s; latch unlocked seen: False", + "22:51:22 kernel X: 0.0 -> 0.0 mm", + "22:51:23 connect: Idle", + "22:51:24 SIGSTOP sent to controller pid 1751 mid-move", + "22:51:24 after SIGSTOP: kernel underrun in 0.21 s, latch locked True, underruns 1 -> 2", + "22:51:25 controller resumed: state Alarm", + "22:51:25 $X before the reset: ['ALARM:17', 'error:79']", + "22:51:27 after the soft reset: Alarm", + "22:51:27 $X after the reset: ['[MSG:Caution: Unlocked]', 'ok']", + "22:51:27 ring after the reset: free 33521664 (idle 33521664)", + "22:51:32 connect: Idle", + "22:51:33 SIGSTOP 100 ms sent to controller pid 1751 mid-move", + "22:51:39 short stall: states ['Run', 'Idle'], underruns +0, warning '2026-10-18T22:51:33.637493+00:00 grblhal[1751] WARNING gfstream: run: 94 late events clamped (max behind 92.5 ms, lead 10 ms) - step generation was starved of CPU', kernel dx 30.0 mm", + "22:51:42 connect: Idle", + "22:51:44 forgectrl restart mid-move -> rc 0", + "22:51:48 fixture up: at , v1.0.0, covers lid, interlock, button", + "22:51:48 move after the restart: states ['Run', 'Idle']", + "22:51:56 mode after restart: {'mode': 'grbl', 'controller': 'running', 'pid': 1865, 'motion': 'verified', 'gated': False, 'local': False, 'why': ''}", + "22:51:56 retake: unmanaged pid 1751 finished the move; supervised pid 1865 started at idle", + "22:51:56 connect: Idle", + "22:52:00 SIGKILL sent to controller pid 1865 during $H (runner pid [1877])", + "22:52:02 kill during $H: runner gone in 2.0123884677886963 s, respawned as 1904, kernel idle, pulse held by ['forgectrl', 'grblHAL_glowfor']", + "22:52:02 restore homing_mode='manual' -> 200", + "22:52:02 PASS: kill respawned in 1.2 s, hang -> underrun in 0.21 s, short stall warned and completed, restart retook supervision (pid 1865), the kill during $H ended the runner (2.0123884677886963)", + "22:52:02 baseline: post: clean", + "22:52:02 result PASS" + ], + "manifest_sha": "70ecd7867c2698d17f2f3c38db772868eda3364f541242c93fb5db4e1d593bcd", + "message": "", + "result": "PASS", + "test": "motion.deadman", + "ts": "2026-10-18T22:52:02Z" + }, + "requires": [ + "motion.pacing", + "kernel.k1-k2" + ], + "satisfied": true, + "source_sha": "9af0217eb8432f930efa00a8635e0b9c6d748ff07724524157f1ac17ee3d003f", + "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": "845f1fb14651012b35906e0efb077c0bba52ec50c9b2dd7c3c2f7e4f10b12d03", + "hardware": "api", + "id": "motion.step-timing-under-load", + "inherited": false, + "kind": "auto", + "record": { + "answers": [], + "campaign": "c-20261018224638-4ca0", + "duration_s": 30, + "evidence": { + "baseline": { + "post": [], + "pre": [] + }, + "batch": { + "group": "unattended", + "ts": "2026-10-18T22:46:38Z" + }, + "clamp_lines": [], + "controller_cpu_pct": 30.6, + "fixture": { + "channels": [ + "lid", + "interlock", + "button" + ], + "hostname": "", + "ip": "", + "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": "845f1fb14651012b35906e0efb077c0bba52ec50c9b2dd7c3c2f7e4f10b12d03", + "image": "20261018222431 (dev)", + "log": [ + "22:52:02 start motion.step-timing-under-load (auto, api) in campaign c-20261018224638-4ca0", + "22:52:03 fixture up: at , v1.0.0, covers lid, interlock, button", + "22:52:03 fixture: at covers lid, interlock, button", + "22:52:03 queued by the unattended queue opened 2026-10-18T22:46:38Z", + "22:52:03 baseline: pre: clean", + "22:52:03 mode: test needs grbl - already in grbl mode", + "22:52:03 controller threads: 4, SCHED_FIFO priorities: [9, 10]", + "22:52:03 CPU hog started (pid 1932, nice 5)", + "22:52:03 connect: Idle", + "22:52:30 20 legs in 26.6 s, controller CPU 30.6 %", + "22:52:32 CPU hog stopped", + "22:52:32 PASS: 20 legs at 2000 mm/min against a nice-5 CPU hog, no clamped events", + "22:52:33 baseline: post: clean", + "22:52:33 result PASS" + ], + "manifest_sha": "70ecd7867c2698d17f2f3c38db772868eda3364f541242c93fb5db4e1d593bcd", + "message": "", + "result": "PASS", + "test": "motion.step-timing-under-load", + "ts": "2026-10-18T22:52:33Z" + }, + "requires": [ + "kernel.latch-locked-idle", + "motion.jog-roundtrip" + ], + "satisfied": true, + "source_sha": "506323b4fc5b9590e8a7cba67a5b9f6f0188d586114e9efe477d1eb4d779eece", + "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": "7c82f74b964351d8cdbc8c2cac6a59583684f7f852bd5c75789a1d0fe6dd4935", + "hardware": "takeover", + "id": "motion.release", + "inherited": false, + "kind": "auto", + "record": { + "answers": [], + "campaign": "c-20261018224638-4ca0", + "duration_s": 26, + "evidence": { + "baseline": { + "post": [], + "pre": [] + }, + "batch": { + "group": "unattended", + "ts": "2026-10-18T22:46:38Z" + }, + "elapsed_s": 19.2, + "energized_currents": [ + "33", + "5" + ], + "error": "", + "faults_energized": 0, + "faults_released": 0, + "fixture": { + "channels": [ + "lid", + "interlock", + "button" + ], + "hostname": "", + "ip": "", + "released": [] + }, + "homed_axes_released": 4, + "kernel_position": [ + [ + 0, + 0, + 0, + 3259780, + 3259780 + ], + [ + 0, + 0, + 0, + 3259780, + 3259780 + ] + ], + "kernel_state_released": "idle", + "log": [ + "00:06 liveness probe: head accel p2p x=2367 y=2189 (moving>=800 dead<=250)", + "00:08 lens reference pass 1: 0", + "00:08 lens reference pass 2: 0", + "00:09 lens reference pass 3: 0", + "00:10 lens reference pass 4: 0", + "00:12 lens reference pass 5: 0", + "00:13 at rest: accelerometer low-passed p2p x 280 y 133 (rms 170 57) over 176 samples", + "00:14 +X: accelerometer low-passed p2p x 1756 y 871 (rms 787 415, raw p2p 3762 3157, 195 sampl", + "00:16 -X: accelerometer low-passed p2p x 2001 y 922 (rms 811 473, raw p2p 5151 3624, 192 sampl", + "00:17 +Y: accelerometer low-passed p2p x 438 y 1696 (rms 224 771, raw p2p 1266 3163, 193 sampl", + "00:18 -Y: accelerometer low-passed p2p x 388 y 1526 (rms 221 576, raw p2p 1266 2820, 192 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": 1756, + "p2p_lp_y": 871, + "p2p_x": 3762, + "p2p_y": 3157, + "rms_x": 787.0, + "rms_y": 415.0, + "samples": 195, + "witnessed": true + }, + "+Y": { + "crash_event": false, + "p2p_lp_x": 438, + "p2p_lp_y": 1696, + "p2p_x": 1266, + "p2p_y": 3163, + "rms_x": 224.0, + "rms_y": 771.0, + "samples": 193, + "witnessed": true + }, + "-X": { + "crash_event": false, + "p2p_lp_x": 2001, + "p2p_lp_y": 922, + "p2p_x": 5151, + "p2p_y": 3624, + "rms_x": 811.0, + "rms_y": 473.0, + "samples": 192, + "witnessed": true + }, + "-Y": { + "crash_event": false, + "p2p_lp_x": 388, + "p2p_lp_y": 1526, + "p2p_x": 1266, + "p2p_y": 2820, + "rms_x": 221.0, + "rms_y": 576.0, + "samples": 192, + "witnessed": true + } + }, + "phases": [ + "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", + "the head at rest", + "jog +X", + "jog -X", + "jog +Y", + "jog -Y" + ], + "probe": "head accel p2p x=2367 y=2189 (moving>=800 dead<=250)", + "rail_lines": [ + 9, + 9 + ], + "refusals": { + "$J=G91X10F2400": "error:8", + "$X": "error:9", + "G0X10": "error:9", + "^X then $X": "error:9" + }, + "released_accel_p2p": [ + 261, + 92, + 3 + ], + "released_currents": [ + "0", + "0" + ], + "result": { + "moves": { + "+X": { + "crash_event": false, + "p2p_lp_x": 1756, + "p2p_lp_y": 871, + "p2p_x": 3762, + "p2p_y": 3157, + "rms_x": 787.0, + "rms_y": 415.0, + "samples": 195, + "witnessed": true + }, + "+Y": { + "crash_event": false, + "p2p_lp_x": 438, + "p2p_lp_y": 1696, + "p2p_x": 1266, + "p2p_y": 3163, + "rms_x": 224.0, + "rms_y": 771.0, + "samples": 193, + "witnessed": true + }, + "-X": { + "crash_event": false, + "p2p_lp_x": 2001, + "p2p_lp_y": 922, + "p2p_x": 5151, + "p2p_y": 3624, + "rms_x": 811.0, + "rms_y": 473.0, + "samples": 192, + "witnessed": true + }, + "-Y": { + "crash_event": false, + "p2p_lp_x": 388, + "p2p_lp_y": 1526, + "p2p_x": 1266, + "p2p_y": 2820, + "rms_x": 221.0, + "rms_y": 576.0, + "samples": 192, + "witnessed": true + } + }, + "probe": "head accel p2p x=2367 y=2189 (moving>=800 dead<=250)", + "rail": "up", + "rest": { + "p2p_lp_x": 280, + "p2p_lp_y": 133, + "p2p_x": 944, + "p2p_y": 418, + "rms_x": 170.0, + "rms_y": 57.0, + "samples": 176 + }, + "z_passes": [ + 0, + 0, + 0, + 0, + 0 + ], + "z_referenced": true + }, + "started": true, + "state_after_reset": "Alarm", + "state_energized": "Idle", + "state_released": "Alarm" + }, + "fingerprint": "7c82f74b964351d8cdbc8c2cac6a59583684f7f852bd5c75789a1d0fe6dd4935", + "image": "20261018222431 (dev)", + "log": [ + "22:52:33 start motion.release (auto, takeover) in campaign c-20261018224638-4ca0", + "22:52:33 fixture up: at , v1.0.0, covers lid, interlock, button", + "22:52:33 fixture: at covers lid, interlock, button", + "22:52:33 queued by the unattended queue opened 2026-10-18T22:46:38Z", + "22:52:33 baseline: pre: clean", + "22:52:33 mode: test needs grbl - already in grbl mode", + "22:52:34 connect: Idle", + "22:52:35 $MD: step currents ['0', '0'], Alarm, cnc/state idle, faults 0, homed_axes 4", + "22:52:39 refused while released: {'$J=G91X10F2400': 'error:8', 'G0X10': 'error:9', '$X': 'error:9', '^X then $X': 'error:9'}; accel p2p x=261 y=92 over 3 samples; kernel record (0, 0, 0, 3259780, 3259780) -> (0, 0, 0, 3259780, 3259780)", + "22:52:39 POST /mode controller=cloud while released -> 409 the X and Y motors are released: energize them first", + "22:52:40 NOTICE: The head moves 50 mm each way on X and on Y. Keep the bed clear.", + "22:52:40 POST /wiz/motion/start -> 200 {'started': True, 'id': 'motion'}", + "22:52:40 motion: stopping the motion controller", + "22:52:41 motion: rail up, the liveness probe", + "22:52:46 motion: the lens hall reference", + "22:52:47 motion: the lens finds its reference on the hall sensor: pass 1 of 5", + "22:52:48 motion: the lens finds its reference on the hall sensor: pass 2 of 5", + "22:52:49 motion: the lens finds its reference on the hall sensor: pass 3 of 5", + "22:52:50 motion: the lens finds its reference on the hall sensor: pass 4 of 5", + "22:52:51 motion: the lens finds its reference on the hall sensor: pass 5 of 5", + "22:52:52 motion: starting the controller in loopback posture", + "22:52:52 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.", + "22:52:53 motion: the head at rest", + "22:52:54 motion: jog +X", + "22:52:55 motion: jog -X", + "22:52:56 motion: jog +Y", + "22:52:57 motion: jog -Y", + "22:52:59 after energize: probe 'head accel p2p x=2367 y=2189 (moving>=800 dead<=250)', moves {'+X': True, '-X': True, '+Y': True, '-Y': True}", + "22:52:59 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", + "22:52:59 baseline: post: clean", + "22:52:59 result PASS" + ], + "manifest_sha": "70ecd7867c2698d17f2f3c38db772868eda3364f541242c93fb5db4e1d593bcd", + "message": "", + "result": "PASS", + "test": "motion.release", + "ts": "2026-10-18T22:52:59Z" + }, + "requires": [ + "motion.jog-roundtrip" + ], + "satisfied": true, + "source_sha": "249e36b4bebb85be1c706d5735164c6321f193e6b180ad6f070ed9ef5748dbca", + "subsystem": "motion", + "title": "Motor release: nothing moves a released gantry, only the operator energizes it" + }, + { + "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": "0b172a1d48a879020957670682d8e588b69652c08c2dc9ab9044031d94df518a", + "hardware": "api", + "id": "cooling.aa-offset-calibrate", + "inherited": false, + "kind": "auto", + "record": { + "answers": [], + "campaign": "c-20261018224638-4ca0", + "duration_s": 92, + "evidence": { + "baseline": { + "post": [], + "pre": [] + }, + "batch": { + "group": "unattended", + "ts": "2026-10-18T22:46:38Z" + }, + "fixture": { + "channels": [ + "lid", + "interlock", + "button" + ], + "hostname": "", + "ip": "", + "released": [] + }, + "result": { + "offset_counts": 15.5, + "recommend": 15.5, + "spread_counts": 1.7, + "steps": [ + [ + 16.0, + 15.4 + ], + [ + -15.5, + -15.5 + ], + [ + 15.5, + 14.6 + ], + [ + -15.1, + -15.5 + ], + [ + 15.6, + 15.5 + ], + [ + -15.6, + -16.3 + ] + ] + } + }, + "fingerprint": "0b172a1d48a879020957670682d8e588b69652c08c2dc9ab9044031d94df518a", + "image": "20261018222431 (dev)", + "log": [ + "22:53:00 start cooling.aa-offset-calibrate (auto, api) in campaign c-20261018224638-4ca0", + "22:53:00 fixture up: at , v1.0.0, covers lid, interlock, button", + "22:53:00 fixture: at covers lid, interlock, button", + "22:53:00 queued by the unattended queue opened 2026-10-18T22:46:38Z", + "22:53:00 baseline: pre: clean", + "22:53:00 POST /diag/aa-offset-calibrate -> 202 {'started': True}", + "22:53:00 phase: stopping the motion controller", + "22:53:02 phase: settling with the fans idle", + "22:53:16 phase: cycle 1/3: air assist to run", + "22:53:28 phase: cycle 1/3: air assist to idle", + "22:53:30 fixture up: at , v1.0.0, covers lid, interlock, button", + "22:53:40 phase: cycle 2/3: air assist to run", + "22:53:54 phase: cycle 2/3: air assist to idle", + "22:54:01 fixture up: at , v1.0.0, covers lid, interlock, button", + "22:54:06 phase: cycle 3/3: air assist to run", + "22:54:18 phase: cycle 3/3: air assist to idle", + "22:54:31 fixture up: at , v1.0.0, covers lid, interlock, button", + "22:54:32 phase: done", + "22:54:32 diag: 0:00 start: air assist 204 <-> 1023, 3 cycles", + "22:54:32 diag: 0:27 edge 1 (to run): down +16.0, up +15.4 counts", + "22:54:32 diag: 0:40 edge 2 (to idle): down -15.5, up -15.5 counts", + "22:54:32 diag: 0:52 edge 3 (to run): down +15.5, up +14.6 counts", + "22:54:32 diag: 1:05 edge 4 (to idle): down -15.1, up -15.5 counts", + "22:54:32 diag: 1:18 edge 5 (to run): down +15.6, up +15.5 counts", + "22:54:32 diag: 1:30 edge 6 (to idle): down -15.6, up -16.3 counts", + "22:54:32 diag: 1:30 offset 15.5 counts (spread 1.7) over 6 edges", + "22:54:32 diag: 1:30 done", + "22:54:32 offset 15.5 counts, spread 1.7, recommend 15.5, edges [[16.0, 15.4], [-15.5, -15.5], [15.5, 14.6], [-15.1, -15.5], [15.6, 15.5], [-15.6, -16.3]]", + "22:54:32 baseline: post: clean", + "22:54:32 result PASS" + ], + "manifest_sha": "70ecd7867c2698d17f2f3c38db772868eda3364f541242c93fb5db4e1d593bcd", + "message": "", + "result": "PASS", + "test": "cooling.aa-offset-calibrate", + "ts": "2026-10-18T22:54:32Z" + }, + "requires": [ + "kernel.latch-locked-idle" + ], + "satisfied": true, + "source_sha": "8a40e4653ab3c9a5bdc6fa8c141ecb4f63e49e5b1546b530a2b11ffd4b6d4c64", + "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": "a6ff88946822557015d1ecbd5e23ea0527d244a151f94f05157d0bca318a63c9", + "hardware": "api", + "id": "cooling.flow-verify", + "inherited": false, + "kind": "auto", + "record": { + "answers": [], + "campaign": "c-20261018224638-4ca0", + "duration_s": 157, + "evidence": { + "baseline": { + "post": [], + "pre": [] + }, + "batch": { + "group": "unattended", + "ts": "2026-10-18T22:46:38Z" + }, + "fixture": { + "channels": [ + "lid", + "interlock", + "button" + ], + "hostname": "", + "ip": "", + "released": [] + }, + "result": { + "flow_dt": 9.1, + "flow_rise": 10.5, + "margin_flow": 4.0, + "margin_noflow": 1.8, + "noflow_dt": 11.7, + "noflow_rise": 16.3, + "pass": true, + "thin_margin": false, + "threshold": 14.5 + } + }, + "fingerprint": "a6ff88946822557015d1ecbd5e23ea0527d244a151f94f05157d0bca318a63c9", + "image": "20261018222431 (dev)", + "log": [ + "22:54:33 start cooling.flow-verify (auto, api) in campaign c-20261018224638-4ca0", + "22:54:33 fixture up: at , v1.0.0, covers lid, interlock, button", + "22:54:33 fixture: at covers lid, interlock, button", + "22:54:33 queued by the unattended queue opened 2026-10-18T22:46:38Z", + "22:54:33 baseline: pre: clean", + "22:54:33 POST /diag/flow-verify -> 202 {'started': True}", + "22:54:33 phase: stopping the motion controller (down 24.9 C, up 24.8 C)", + "22:54:35 phase: settling before trial 1/1 (pump on) (down 24.9 C, up 24.9 C)", + "22:54:49 phase: trial 1/1: heater 40% for 50 s (pump on) (down 24.9 C, up 24.9 C)", + "22:55:04 fixture up: at , v1.0.0, covers lid, interlock, button", + "22:55:35 fixture up: at , v1.0.0, covers lid, interlock, button", + "22:55:41 phase: settling before trial 1/1 (pump off) (down 34.9 C, up 25.0 C)", + "22:56:05 fixture up: at , v1.0.0, covers lid, interlock, button", + "22:56:17 phase: trial 1/1: heater 40% for 50 s (pump off) (down 23.2 C, up 22.6 C)", + "22:56:36 fixture up: at , v1.0.0, covers lid, interlock, button", + "22:57:06 fixture up: at , v1.0.0, covers lid, interlock, button", + "22:57:09 phase: done (down 39.7 C, up 28.1 C)", + "22:57:09 diag: 0:00 start: duty 40%, window 50 s, threshold 14.5 C", + "22:57:09 diag: 1:07 trial 1/1 flow: rise 10.5 C, dT 9.1 C", + "22:57:09 diag: 2:35 trial 1/1 no-flow: rise 16.3 C, dT 11.7 C", + "22:57:09 diag: 2:35 verdict: PASS (flow 10.5 / threshold 14.5 / no-flow 16.3)", + "22:57:09 diag: 2:35 done", + "22:57:09 verdict: pass=True threshold=14.5 flow_rise=10.5 noflow_rise=16.3 margins 4.0/1.8 thin=False", + "22:57:10 baseline: post: clean", + "22:57:10 result PASS" + ], + "manifest_sha": "70ecd7867c2698d17f2f3c38db772868eda3364f541242c93fb5db4e1d593bcd", + "message": "", + "result": "PASS", + "test": "cooling.flow-verify", + "ts": "2026-10-18T22:57:10Z" + }, + "requires": [ + "kernel.latch-locked-idle" + ], + "satisfied": true, + "source_sha": "6ab41e5ccf73559de77d6e8709cbd18d93e9d5d8d2e09cdb024467fc82f59c67", + "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/main.c" + ] + ], + "fingerprint": "945f0999e92965d478e18fc458f01a628d86d51c231b6656fb3f012fda63f670", + "hardware": "api", + "id": "cooling.flow-under-load", + "inherited": false, + "kind": "live", + "record": { + "answers": [], + "campaign": "c-20261018224638-4ca0", + "duration_s": 95, + "evidence": { + "actions": [ + { + "by": "operator", + "channel": "button", + "state": "presence", + "took_s": 5.44, + "ts": "2026-10-18T23:11:27Z" + }, + { + "by": "fixture", + "channel": "button", + "state": "arm", + "took_s": 0.25, + "ts": "2026-10-18T23:11:27Z" + } + ], + "baseline": { + "post": [], + "pre": [] + }, + "batch": { + "group": "attended", + "ts": "2026-10-18T23:07:24Z" + }, + "check_s": 50, + "disarm_after_m2_s": 0.6, + "dt_c": 9.4, + "emission_peak": 255, + "fixture": { + "channels": [ + "lid", + "interlock", + "button" + ], + "hostname": "", + "ip": "", + "released": [] + }, + "heater_seen": true, + "job_to_verdict_s": 72.8, + "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-10-18T23:11:21Z" + }, + "raw_rise_c": 13.0, + "rise_c": 11.4, + "verdict_line": "coolant flow verified (heater rise 11.4 C, dT 9.4 C; laser 1.6 off 13.0)", + "verdicts_seen": [] + }, + "fingerprint": "945f0999e92965d478e18fc458f01a628d86d51c231b6656fb3f012fda63f670", + "image": "20261018222431 (dev)", + "log": [ + "23:11:21 start cooling.flow-under-load (live, api) in campaign c-20261018224638-4ca0", + "23:11:21 fixture up: at , v1.0.0, covers lid, interlock, button", + "23:11:21 fixture: at covers lid, interlock, button", + "23:11:21 queued by the attended queue opened 2026-10-18T23:07:24Z", + "23:11:21 baseline: pre: clean", + "23:11:21 mode: test needs grbl - already in grbl mode", + "23:11:21 connect: Idle", + "23:11: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.", + "23:11:21 READY: waiting for the operator's press on the machine (the bench then does every press in this test)", + "23:11:27 READY: operator present (press after 5.4 s); the bench takes the presses", + "23:11:27 ARM: the fixture presses when the button lights (the bench's arm_press opt-in)", + "23:11:28 ARM press by the fixture, button lit after 0.3 s", + "23:11:51 fixture up: at , v1.0.0, covers lid, interlock, button", + "23:12:21 fixture up: at , v1.0.0, covers lid, interlock, button", + "23:12:40 M2: ['ok']", + "23:12:40 engine: coolant flow verified (heater rise 11.4 C, dT 9.4 C; laser 1.6 off 13.0)", + "23:12:40 PASS: lit through the window, raw rise 13.0 C, laser 1.6 C off, judged 11.4 C against 14.5 (dT 9.4), window closed 0.6 s after M2", + "23:12:52 fixture up: at , v1.0.0, covers lid, interlock, button", + "23:12:56 baseline: cool: run/armed=False/hold=False ended on its own after 16 s; the engine's own post-job work, not a leftover", + "23:12:56 baseline: post: clean", + "23:12:56 result PASS" + ], + "manifest_sha": "70ecd7867c2698d17f2f3c38db772868eda3364f541242c93fb5db4e1d593bcd", + "message": "", + "result": "PASS", + "test": "cooling.flow-under-load", + "ts": "2026-10-18T23:12:56Z" + }, + "requires": [ + "laser.emission-witness", + "cooling.flow-verify" + ], + "satisfied": true, + "source_sha": "e4b507a6169c09c94f7f37949b11f14c0911f0e950d5a0fa24eab2b022fbe77a", + "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*" + ], + [ + "forgectrl", + "src/super.*" + ] + ], + "fingerprint": "60d2294f67748c01238aa127a2f2361d0f8e6b086cb6446e1b25ffbf7b014101", + "hardware": "api", + "id": "cooling.fail-tier-stop", + "inherited": false, + "kind": "operator", + "record": { + "answers": [], + "campaign": "c-20261018224638-4ca0", + "duration_s": 20, + "evidence": { + "actions": [ + { + "by": "operator", + "channel": "button", + "state": "arm", + "ts": "2026-10-18T22:57:11Z" + } + ], + "baseline": { + "post": [], + "pre": [] + }, + "batch": { + "group": "unattended", + "ts": "2026-10-18T22:46:38Z" + }, + "fixture": { + "channels": [ + "lid", + "interlock", + "button" + ], + "hostname": "", + "ip": "", + "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-10-18T22:57:12.684928+00:00 forgectrl[1809] WARNING cool: HEAD CRASH SIGNAL (axes y) - motion stopped, laser locked" + ], + "fault_cleared_s": 0.005177021026611328, + "kernel": "idle", + "latch_locked": true, + "mode_after": { + "controller": "running", + "gated": false, + "local": false, + "mode": "grbl", + "motion": "verified", + "pid": 2296, + "why": "" + }, + "super_lines": [ + "2026-10-18T22:57:12.685236+00:00 forgectrl[1809] WARNING super: head crash signal - the controller is stopped and started again" + ] + } + }, + "fingerprint": "60d2294f67748c01238aa127a2f2361d0f8e6b086cb6446e1b25ffbf7b014101", + "image": "20261018222431 (dev)", + "log": [ + "22:57:10 start cooling.fail-tier-stop (operator, api) in campaign c-20261018224638-4ca0", + "22:57:10 fixture up: at , v1.0.0, covers lid, interlock, button", + "22:57:10 fixture: at covers lid, interlock, button", + "22:57:10 fixture: running unattended (no prompt can be answered)", + "22:57:10 queued by the unattended queue opened 2026-10-18T22:46:38Z", + "22:57:10 baseline: pre: clean", + "22:57:10 mode: test needs grbl - already in grbl mode", + "22:57:11 connect: Idle", + "22:57:11 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.", + "22:57:11 NOTICE: The button lights white: press it to arm. The machine fires after your press.", + "22:57:12 the crash tier tripped after 1.569854974746704 s", + "22:57:13 after the crash tier: {'mode_after': {'mode': 'grbl', 'controller': 'running', 'pid': 2296, 'motion': 'verified', 'gated': False, 'local': False, 'why': ''}, 'engine_lines': ['2026-10-18T22:57:12.684928+00:00 forgectrl[1809] WARNING cool: HEAD CRASH SIGNAL (axes y) - motion stopped, laser locked'], 'super_lines': ['2026-10-18T22:57:12.685236+00:00 forgectrl[1809] WARNING super: head crash signal - the controller is stopped and started again'], 'emission': 0, 'kernel': 'idle', 'latch_locked': True}", + "22:57:13 the crash fault ended with the run session after 0.005177021026611328 s: {'phase': 'smoke', 'verdict': 'OK', 'hold': False, 'armed': False}", + "22:57:14 restore thresholds: POST /settings {'cool_accel_x_alert': '', 'cool_accel_y_alert': '', 'cool_accel_abort': ''} -> 200", + "22:57:14 PASS: the crash tier stopped the job, locked the latch, and the supervisor restarted the controller (pid 2242 -> 2296)", + "22:57:30 baseline: cool: smoke/armed=False/hold=False ended on its own after 16 s; the engine's own post-job work, not a leftover", + "22:57:30 baseline: post: clean", + "22:57:30 result PASS" + ], + "manifest_sha": "70ecd7867c2698d17f2f3c38db772868eda3364f541242c93fb5db4e1d593bcd", + "message": "", + "result": "PASS", + "test": "cooling.fail-tier-stop", + "ts": "2026-10-18T22:57:30Z" + }, + "requires": [ + "motion.deadman" + ], + "satisfied": true, + "source_sha": "277a0bccb446e23de5e227350c36fc20edf6602f38c2494cbe457afeb9ff4f47", + "subsystem": "cooling", + "title": "A fail-tier verdict ends the controller: CRASH stops motion, locks the laser, and the supervisor restarts the controller" + }, + { + "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": "c86cfd96ff02973a6053bcd78ac9247955cbcc14d89499f2089a5de91ae85460", + "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-10-18T23:09:40Z" + } + ], + "campaign": "c-20261018224638-4ca0", + "duration_s": 71, + "evidence": { + "actions": [ + { + "by": "operator", + "channel": "button", + "state": "presence", + "took_s": 28.4, + "ts": "2026-10-18T23:09:10Z" + }, + { + "by": "fixture", + "channel": "button", + "state": "arm", + "took_s": 0.26, + "ts": "2026-10-18T23:09:10Z" + } + ], + "armed_seen": true, + "baseline": { + "post": [], + "pre": [] + }, + "batch": { + "group": "attended", + "ts": "2026-10-18T23:07:24Z" + }, + "beam": { + "delta": 932, + "digital_seen": true, + "idle": 1677, + "peak": 2609, + "samples": 102 + }, + "button_dark": false, + "button_latch_set_at": [], + "button_latch_unlocked_max": 0, + "button_latch_unlocked_samples": 88, + "disarm_after_idle_s": 1.2, + "emission_end": 0, + "emission_peak": 149, + "exhaust_at_first_fire": 11653, + "exhaust_floor": 6416.0, + "fixture": { + "channels": [ + "lid", + "interlock", + "button" + ], + "hostname": "", + "ip": "", + "released": [] + }, + "hv_enable_back_lit": true, + "hv_enable_dipped": true, + "hv_max": 929, + "hv_min": 0, + "idle_airflow_fire": [], + "lid_ir_peak": [ + 53, + 52, + 55, + 61 + ], + "mode": { + "detail": "already in grbl mode", + "found": "grbl", + "needs": "grbl", + "ok": true, + "switched": false + }, + "operator": { + "ack_live": true, + "ts": "2026-10-18T23:08:40Z" + }, + "pgood_peak": 255, + "pre_fire": { + "armed": false, + "beam": 1677, + "beam_d": 0, + "button": false, + "button_latch": 1, + "button_lit": false, + "emission": 0, + "exhaust": 3251, + "faults": 0, + "fire_watch": "armed", + "gstate": null, + "homed": false, + "hv": 0, + "hv_enable": false, + "il": 45, + "ir": [ + 49, + 48, + 51, + 53 + ], + "kstate": "idle", + "lid": true, + "locked": true, + "msgs": "", + "pgood": 255, + "phase": "idle", + "t": 1792364921.4694262, + "verdict": "OK" + }, + "rapid": { + "back_at_s": 4.03, + "emission_reads": { + "gap_max_s": 0.276, + "read": 37, + "unread": 0 + }, + "hv_max": 0, + "hv_reads": { + "gap_max_s": 0.276, + "read": 37, + "unread": 0 + }, + "locked_at_dark": false, + "locked_at_out": false, + "out_at_s": 0.63, + "relit": [], + "sampled_past_close_s": 3.01, + "samples": 23, + "span_s": 5.21, + "x_max": 20.002, + "x_start": 0.0 + }, + "samples": 139, + "trail": [ + [ + 0.0, + null, + "idle", + 0, + false, + "idle", + 45, + 1, + true, + true, + false, + false, + 1818, + 0, + null + ], + [ + 0.03, + "Idle", + "idle", + 0, + false, + "idle", + 45, + 1, + true, + true, + false, + false, + 1815, + 0, + "[MSG:Info: press the button to start the laser job]" + ], + [ + 0.21, + "Idle", + "idle", + 0, + true, + "idle", + 37, + 1, + false, + true, + false, + false, + 1818, + 0, + null + ], + [ + 0.39, + "Idle", + "idle", + 0, + true, + "idle", + 33, + 0, + false, + true, + true, + false, + 1817, + 0, + null + ], + [ + 0.57, + "Idle", + "idle", + 0, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1816, + 0, + null + ], + [ + 0.75, + "Idle", + "idle", + 0, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1817, + 0, + null + ], + [ + 0.97, + "Idle", + "idle", + 0, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1817, + 0, + null + ], + [ + 1.16, + "Idle", + "idle", + 0, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1819, + 0, + null + ], + [ + 1.4, + "Idle", + "idle", + 0, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1819, + 0, + null + ], + [ + 1.58, + "Idle", + "idle", + 0, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1818, + 0, + null + ], + [ + 1.75, + "Idle", + "idle", + 0, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1819, + 0, + null + ], + [ + 1.93, + "Idle", + "idle", + 0, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1818, + 0, + null + ], + [ + 2.11, + "Idle", + "idle", + 0, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1821, + 0, + null + ], + [ + 2.32, + "Idle", + "idle", + 0, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1817, + 0, + null + ], + [ + 2.5, + "Idle", + "idle", + 0, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1823, + 0, + null + ], + [ + 2.68, + "Idle", + "idle", + 0, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1818, + 0, + null + ], + [ + 2.85, + "Idle", + "idle", + 0, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1819, + 0, + null + ], + [ + 3.03, + "Idle", + "idle", + 0, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1823, + 0, + null + ], + [ + 3.21, + "Idle", + "idle", + 0, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1818, + 0, + null + ], + [ + 3.41, + "Idle", + "idle", + 0, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1819, + 0, + null + ], + [ + 3.59, + "Idle", + "idle", + 0, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1821, + 0, + null + ], + [ + 3.77, + "Idle", + "idle", + 0, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1819, + 0, + null + ], + [ + 3.94, + "Idle", + "idle", + 0, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1821, + 0, + null + ], + [ + 4.17, + "Idle", + "idle", + 0, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1821, + 0, + null + ], + [ + 4.35, + "Idle", + "idle", + 0, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1819, + 0, + null + ], + [ + 4.54, + "Idle", + "idle", + 0, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1820, + 0, + null + ], + [ + 4.77, + "Idle", + "idle", + 0, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1819, + 0, + null + ], + [ + 4.94, + "Idle", + "idle", + 0, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1821, + 0, + null + ], + [ + 5.12, + "Idle", + "idle", + 0, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1819, + 0, + null + ], + [ + 5.3, + "Idle", + "idle", + 0, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1823, + 0, + null + ], + [ + 5.47, + "Idle", + "idle", + 0, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1823, + 0, + null + ], + [ + 5.71, + "Run", + "idle", + 0, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1820, + 0, + "[MSG:Info: laser armed (density, floor 14 %, curve custom)]" + ], + [ + 5.99, + "Run", + "running", + 0, + true, + "run", + 1, + 0, + false, + true, + false, + true, + 1825, + 0, + null + ], + [ + 6.18, + "Run", + "running", + 0, + true, + "run", + 2, + 0, + false, + true, + false, + true, + 2589, + 170, + null + ], + [ + 6.37, + "Run", + "running", + 0, + true, + "run", + 2, + 0, + false, + true, + false, + true, + 2609, + 735, + null + ], + [ + 6.57, + "Run", + "running", + 0, + true, + "run", + 1, + 0, + false, + true, + false, + true, + 2559, + 305, + null + ], + [ + 6.77, + "Run", + "running", + 95, + true, + "run", + 2, + 0, + false, + true, + false, + true, + 2539, + 311, + null + ], + [ + 6.96, + "Run", + "running", + 95, + true, + "run", + 1, + 0, + false, + true, + false, + true, + 2527, + 403, + null + ], + [ + 7.15, + "Run", + "running", + 95, + true, + "run", + 2, + 0, + false, + true, + false, + true, + 2575, + 692, + null + ], + [ + 7.35, + "Run", + "running", + 95, + true, + "run", + 2, + 0, + false, + true, + false, + true, + 2507, + 449, + null + ], + [ + 7.54, + "Run", + "running", + 95, + true, + "run", + 1, + 0, + false, + true, + false, + true, + 2544, + 887, + null + ], + [ + 7.75, + "Run", + "running", + 146, + true, + "run", + 1, + 0, + false, + true, + false, + true, + 2524, + 498, + null + ], + [ + 7.99, + "Run", + "running", + 146, + true, + "run", + 1, + 0, + false, + true, + false, + true, + 2530, + 259, + null + ], + [ + 8.18, + "Run", + "running", + 146, + true, + "run", + 2, + 0, + false, + true, + false, + true, + 2506, + 262, + null + ], + [ + 8.37, + "Run", + "running", + 146, + true, + "run", + 2, + 0, + false, + true, + false, + true, + 2534, + 505, + null + ], + [ + 8.57, + "Run", + "running", + 146, + true, + "run", + 2, + 0, + false, + true, + false, + true, + 2513, + 221, + null + ], + [ + 8.76, + "Run", + "running", + 146, + true, + "run", + 1, + 0, + false, + true, + false, + true, + 2511, + 340, + null + ], + [ + 8.97, + "Run", + "running", + 146, + true, + "run", + 2, + 0, + false, + true, + false, + true, + 2524, + 184, + null + ], + [ + 9.16, + "Run", + "running", + 146, + true, + "run", + 2, + 0, + false, + true, + false, + true, + 2534, + 374, + null + ], + [ + 9.35, + "Run", + "running", + 146, + true, + "run", + 2, + 0, + false, + true, + false, + true, + 2584, + 617, + null + ], + [ + 9.55, + "Run", + "running", + 146, + true, + "run", + 2, + 0, + false, + true, + false, + true, + 2529, + 426, + null + ], + [ + 9.74, + "Run", + "running", + 148, + true, + "run", + 1, + 0, + false, + true, + false, + true, + 2577, + 327, + null + ], + [ + 9.92, + "Idle", + "running", + 148, + true, + "run", + 2, + 0, + false, + true, + false, + true, + 2542, + 782, + null + ], + [ + 10.15, + "Idle", + "idle", + 148, + true, + "run", + 1, + 0, + false, + true, + false, + true, + 1835, + 0, + null + ], + [ + 10.38, + "Idle", + "idle", + 148, + true, + "run", + 1, + 0, + false, + true, + false, + true, + 1834, + 0, + null + ], + [ + 10.56, + "Idle", + "idle", + 148, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1833, + 0, + null + ], + [ + 10.75, + "Idle", + "idle", + 57, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1831, + 0, + null + ], + [ + 10.93, + "Idle", + "idle", + 57, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1832, + 0, + null + ], + [ + 11.15, + "Idle", + "idle", + 57, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1835, + 0, + null + ], + [ + 11.36, + "Idle", + "idle", + 57, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1835, + 0, + null + ], + [ + 11.54, + "Idle", + "idle", + 57, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1835, + 0, + null + ], + [ + 11.78, + "Idle", + "idle", + 0, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1829, + 0, + null + ], + [ + 11.96, + "Idle", + "idle", + 0, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1833, + 0, + null + ], + [ + 12.14, + "Idle", + "idle", + 0, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1833, + 0, + null + ], + [ + 12.45, + "Run", + "running", + 0, + true, + "run", + 1, + 0, + false, + true, + false, + true, + 1834, + 0, + null + ], + [ + 12.64, + "Run", + "running", + 0, + true, + "run", + 1, + 0, + false, + true, + false, + true, + 2568, + 197, + null + ], + [ + 12.83, + "Run", + "running", + 18, + true, + "run", + 2, + 0, + false, + true, + false, + true, + 2562, + 298, + null + ], + [ + 13.02, + "Run", + "running", + 18, + true, + "run", + 1, + 0, + false, + true, + false, + true, + 2586, + 264, + null + ], + [ + 13.21, + "Run", + "running", + 18, + true, + "run", + 3, + 0, + false, + true, + false, + true, + 2559, + 129, + null + ], + [ + 13.4, + "Run", + "running", + 18, + true, + "run", + 2, + 0, + false, + true, + false, + true, + 2521, + 193, + null + ], + [ + 13.59, + "Run", + "running", + 18, + true, + "run", + 1, + 0, + false, + true, + false, + true, + 2557, + 607, + null + ], + [ + 13.78, + "Run", + "running", + 148, + true, + "run", + 2, + 0, + false, + true, + false, + true, + 2546, + 669, + null + ], + [ + 13.98, + "Run", + "running", + 148, + true, + "run", + 2, + 0, + false, + true, + false, + true, + 2549, + 306, + null + ], + [ + 14.17, + "Run", + "running", + 148, + true, + "run", + 1, + 0, + false, + true, + false, + true, + 2599, + 416, + null + ], + [ + 14.36, + "Run", + "running", + 148, + true, + "run", + 2, + 0, + false, + true, + false, + true, + 2506, + 497, + null + ], + [ + 14.57, + "Run", + "running", + 148, + true, + "run", + 1, + 0, + false, + true, + false, + true, + 2487, + 484, + null + ], + [ + 14.76, + "Run", + "running", + 149, + true, + "run", + 1, + 0, + false, + true, + false, + true, + 2516, + 549, + null + ], + [ + 14.95, + "Run", + "running", + 149, + true, + "run", + 2, + 0, + false, + true, + false, + true, + 2515, + 475, + null + ], + [ + 15.14, + "Run", + "running", + 149, + true, + "run", + 2, + 0, + false, + true, + false, + true, + 2559, + 350, + null + ], + [ + 15.33, + "Run", + "running", + 149, + true, + "run", + 1, + 0, + false, + true, + false, + true, + 2540, + 929, + null + ], + [ + 15.59, + "Run", + "running", + 149, + true, + "run", + 2, + 0, + false, + true, + false, + true, + 2497, + 669, + null + ], + [ + 15.78, + "Run", + "running", + 149, + true, + "run", + 2, + 0, + false, + true, + false, + true, + 2538, + 170, + null + ], + [ + 15.97, + "Run", + "running", + 149, + true, + "run", + 2, + 0, + false, + true, + false, + true, + 2554, + 119, + null + ], + [ + 16.16, + "Run", + "running", + 149, + true, + "run", + 2, + 0, + false, + true, + false, + true, + 2509, + 196, + null + ], + [ + 16.35, + "Idle", + "running", + 149, + true, + "run", + 2, + 0, + false, + true, + false, + true, + 2558, + 449, + null + ], + [ + 16.53, + "Idle", + "running", + 149, + true, + "run", + 1, + 0, + false, + true, + false, + true, + 2517, + 319, + null + ], + [ + 16.71, + "Idle", + "idle", + 132, + true, + "run", + 1, + 0, + false, + true, + false, + true, + 1842, + 0, + null + ], + [ + 16.89, + "Idle", + "idle", + 132, + true, + "run", + 1, + 0, + false, + true, + false, + true, + 1841, + 0, + null + ], + [ + 17.07, + "Idle", + "idle", + 132, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1839, + 0, + null + ], + [ + 17.25, + "Idle", + "idle", + 132, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1839, + 0, + null + ], + [ + 17.42, + "Idle", + "idle", + 132, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1839, + 0, + null + ], + [ + 17.6, + "Idle", + "idle", + 132, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1838, + 0, + null + ], + [ + 17.79, + "Idle", + "idle", + 0, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1837, + 0, + null + ], + [ + 17.96, + "Idle", + "idle", + 0, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1836, + 0, + null + ], + [ + 18.14, + "Idle", + "idle", + 0, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1835, + 0, + null + ], + [ + 18.32, + "Idle", + "idle", + 0, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1834, + 0, + null + ], + [ + 18.5, + "Idle", + "idle", + 0, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1834, + 0, + null + ], + [ + 18.67, + "Idle", + "idle", + 0, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1837, + 0, + null + ], + [ + 18.85, + "Idle", + "idle", + 0, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1834, + 0, + null + ], + [ + 19.03, + "Idle", + "idle", + 0, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1835, + 0, + null + ], + [ + 19.21, + "Idle", + "idle", + 0, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1834, + 0, + null + ], + [ + 19.39, + "Idle", + "idle", + 0, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1833, + 0, + null + ], + [ + 19.55, + "Idle", + "idle", + 0, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1836, + 0, + null + ], + [ + 19.72, + "Run", + "running", + 0, + true, + "run", + 1, + 0, + false, + true, + false, + true, + 1837, + 0, + null + ], + [ + 19.97, + "Run", + "running", + 0, + true, + "run", + 1, + 0, + false, + true, + false, + true, + 1837, + 0, + null + ], + [ + 20.18, + "Idle", + "running", + 0, + true, + "run", + 1, + 0, + false, + true, + false, + true, + 1836, + 0, + null + ], + [ + 20.42, + "Idle", + "idle", + 0, + true, + "run", + 1, + 0, + false, + true, + false, + true, + 1837, + 0, + null + ], + [ + 20.66, + "Idle", + "idle", + 0, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1841, + 0, + null + ], + [ + 20.91, + "Idle", + "idle", + 0, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1836, + 0, + null + ], + [ + 21.15, + "Idle", + "idle", + 0, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1839, + 0, + null + ], + [ + 21.39, + "Idle", + "idle", + 0, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1840, + 0, + null + ], + [ + 21.63, + "Idle", + "idle", + 0, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1835, + 0, + null + ], + [ + 21.87, + "Idle", + "idle", + 0, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1841, + 0, + null + ], + [ + 22.13, + "Idle", + "idle", + 0, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1840, + 0, + null + ], + [ + 22.35, + "Idle", + "idle", + 0, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1838, + 0, + null + ], + [ + 22.6, + "Idle", + "idle", + 0, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1840, + 0, + null + ], + [ + 22.84, + "Idle", + "idle", + 0, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1839, + 0, + null + ], + [ + 23.11, + "Run", + "running", + 0, + true, + "run", + 1, + 0, + false, + true, + false, + true, + 1841, + 0, + null + ], + [ + 23.33, + "Run", + "running", + 0, + true, + "run", + 1, + 0, + false, + true, + false, + true, + 1842, + 0, + null + ], + [ + 23.58, + "Idle", + "running", + 0, + true, + "run", + 1, + 0, + false, + true, + false, + true, + 1839, + 0, + null + ], + [ + 23.82, + "Idle", + "idle", + 0, + true, + "run", + 1, + 0, + false, + true, + false, + true, + 1841, + 0, + null + ], + [ + 24.06, + "Idle", + "idle", + 0, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1839, + 0, + null + ], + [ + 24.33, + "Idle", + "idle", + 0, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1837, + 0, + null + ], + [ + 24.55, + "Idle", + "idle", + 0, + true, + "run", + 33, + 0, + false, + true, + false, + false, + 1835, + 0, + null + ], + [ + 24.76, + "Idle", + "idle", + 0, + false, + "run", + 45, + 1, + true, + true, + false, + false, + 1838, + 0, + null + ], + [ + 24.96, + "Idle", + "idle", + 0, + false, + "run", + 45, + 1, + true, + true, + false, + false, + 1840, + 0, + null + ], + [ + 25.16, + "Idle", + "idle", + 0, + false, + "run", + 45, + 1, + true, + true, + false, + false, + 1839, + 0, + null + ], + [ + 25.41, + "Idle", + "idle", + 0, + false, + "run", + 45, + 1, + true, + true, + false, + false, + 1838, + 0, + null + ], + [ + 25.62, + "Idle", + "idle", + 0, + false, + "smoke", + 45, + 1, + true, + true, + false, + false, + 1839, + 0, + null + ], + [ + 25.82, + "Idle", + "idle", + 0, + false, + "smoke", + 45, + 1, + true, + true, + false, + false, + 1839, + 0, + null + ], + [ + 26.02, + "Idle", + "idle", + 0, + false, + "smoke", + 45, + 1, + true, + true, + false, + false, + 1836, + 0, + null + ], + [ + 26.22, + "Idle", + "idle", + 0, + false, + "smoke", + 45, + 1, + true, + true, + false, + false, + 1836, + 0, + null + ], + [ + 26.42, + "Idle", + "idle", + 0, + false, + "smoke", + 45, + 1, + true, + true, + false, + false, + 1836, + 0, + null + ], + [ + 26.63, + "Idle", + "idle", + 0, + false, + "smoke", + 45, + 1, + true, + true, + false, + false, + 1836, + 0, + null + ], + [ + 26.83, + "Idle", + "idle", + 0, + false, + "smoke", + 45, + 1, + true, + true, + false, + false, + 1838, + 0, + null + ], + [ + 27.03, + "Idle", + "idle", + 0, + false, + "smoke", + 45, + 1, + true, + true, + false, + false, + 1835, + 0, + null + ], + [ + 27.23, + "Idle", + "idle", + 0, + false, + "smoke", + 45, + 1, + true, + true, + false, + false, + 1837, + 0, + null + ], + [ + 27.43, + "Idle", + "idle", + 0, + false, + "smoke", + 45, + 1, + true, + true, + false, + false, + 1837, + 0, + null + ], + [ + 27.64, + "Idle", + "idle", + 0, + false, + "smoke", + 45, + 1, + true, + true, + false, + false, + 1838, + 0, + null + ] + ], + "trail_fields": [ + "t", + "gstate", + "kstate", + "emission", + "armed", + "phase", + "il", + "button_latch", + "locked", + "lid", + "button", + "hv_enable", + "beam", + "hv", + "msgs" + ] + }, + "fingerprint": "c86cfd96ff02973a6053bcd78ac9247955cbcc14d89499f2089a5de91ae85460", + "image": "20261018222431 (dev)", + "log": [ + "23:08:40 start laser.emission-witness (live, api) in campaign c-20261018224638-4ca0", + "23:08:40 fixture up: at , v1.0.0, covers lid, interlock, button", + "23:08:40 fixture: at covers lid, interlock, button", + "23:08:40 queued by the attended queue opened 2026-10-18T23:07:24Z", + "23:08:41 baseline: pre: clean", + "23:08:41 mode: test needs grbl - already in grbl mode", + "23:08:41 connect: Idle", + "23:08:41 pre-fire: emission=0 hv=0 armed=False verdict=OK", + "23:08:41 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.", + "23:08:41 READY: waiting for the operator's press on the machine (the bench then does every press in this test)", + "23:09:10 READY: operator present (press after 28.4 s); the bench takes the presses", + "23:09:10 ARM: the fixture presses when the button lights (the bench's arm_press opt-in)", + "23:09:10 ARM press by the fixture, button lit after 0.3 s", + "23:09:11 fixture up: at , v1.0.0, covers lid, interlock, button", + "23:09:38 beam detector: idle 1677, peak 2609, digital asserted True", + "23:09:38 emission_samples peak=149 end=0; hv 0..929; lid_ir peak [53, 52, 55, 61]; armed seen True", + "23:09:38 dwell gap: button latch through the unlocked window max=0 over 88 samples (set at []); HV_ENABLE dipped=True, back with emission after it=True", + "23:09:38 exhaust at the first emission sample: 11653 rpm (floor 6416)", + "23:09:38 the rapid after the M5: 23 samples over 5.2 s from the dark point to the close, out at +0.63 s, back at +4.03 s; sampled 3.01 s past the close, 0 of 37 samples with emission, HV max 0, 37 of 37 carried the LASER_ON count, longest unread stretch 0.276 s; the window closed 1.2 s after the head was back", + "23:09:38 button dark after 0.0 s", + "23:09:38 PROMPT: Did the laser mark a 20 mm square outline on the scrap, all four sides?", + "23:09:40 ANSWER: Yes", + "23:09:40 PASS: emission peak 149 -> 0, HV 0..929, beam +932; the rapid after the M5 dark (HV max 0); disarmed 1.2 s after the head was back, button dark, mark confirmed", + "23:09:42 fixture up: at , v1.0.0, covers lid, interlock, button", + "23:09:51 baseline: cool: smoke/armed=False/hold=False ended on its own after 11 s; the engine's own post-job work, not a leftover", + "23:09:51 baseline: post: clean", + "23:09:51 result PASS" + ], + "manifest_sha": "70ecd7867c2698d17f2f3c38db772868eda3364f541242c93fb5db4e1d593bcd", + "message": "", + "result": "PASS", + "test": "laser.emission-witness", + "ts": "2026-10-18T23:09:51Z" + }, + "requires": [ + "kernel.latch-locked-idle", + "kernel.k1-k2", + "motion.jog-roundtrip" + ], + "satisfied": true, + "source_sha": "95a24204411309e65a827def1c57ac8e6867f5c3b1127227e962175711cf16b1", + "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" + ], + [ + "forgectrl", + "src/main.c" + ] + ], + "fingerprint": "fcad9a2ae69c87684673820533b2be59062de34e001c4da99f290e7342c954ad", + "hardware": "api", + "id": "laser.armed-kill", + "inherited": false, + "kind": "live", + "record": { + "answers": [], + "campaign": "c-20261018224638-4ca0", + "duration_s": 43, + "evidence": { + "actions": [ + { + "by": "operator", + "channel": "button", + "state": "presence", + "took_s": 6.1, + "ts": "2026-10-18T23:13:04Z" + }, + { + "by": "fixture", + "channel": "button", + "state": "arm", + "took_s": 0.26, + "ts": "2026-10-18T23:13:04Z" + }, + { + "by": "fixture", + "channel": "button", + "state": "arm", + "took_s": 0.25, + "ts": "2026-10-18T23:13:22Z" + } + ], + "baseline": { + "post": [], + "pre": [] + }, + "batch": { + "group": "attended", + "ts": "2026-10-18T23:07:24Z" + }, + "beam_at_fire_kill": 2620, + "beam_at_fire_stop": 2654, + "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.54, + 110, + "idle", + false + ], + [ + 0.68, + 110, + "idle", + false + ], + [ + 0.87, + 51, + "idle", + false + ], + [ + 1.02, + 51, + "idle", + false + ], + [ + 1.16, + 51, + "idle", + false + ], + [ + 1.31, + 51, + "idle", + false + ], + [ + 1.45, + 51, + "idle", + false + ], + [ + 1.6, + 51, + "idle", + false + ], + [ + 1.74, + 51, + "idle", + false + ], + [ + 1.89, + 0, + "idle", + false + ], + [ + 2.03, + 0, + "idle", + false + ], + [ + 2.18, + 0, + "idle", + false + ], + [ + 2.32, + 0, + "idle", + false + ], + [ + 2.47, + 0, + "idle", + false + ], + [ + 2.61, + 0, + "idle", + false + ], + [ + 2.76, + 0, + "idle", + false + ], + [ + 2.91, + 0, + "idle", + false + ], + [ + 3.07, + 0, + "idle", + false + ], + [ + 3.21, + 0, + "idle", + false + ], + [ + 3.36, + 0, + "idle", + false + ], + [ + 3.5, + 0, + "idle", + false + ], + [ + 3.65, + 0, + "idle", + false + ], + [ + 3.79, + 0, + "idle", + false + ], + [ + 3.94, + 0, + "idle", + false + ], + [ + 4.11, + 0, + "idle", + false + ], + [ + 4.26, + 0, + "idle", + false + ], + [ + 4.4, + 0, + "idle", + false + ], + [ + 4.55, + 0, + "idle", + false + ], + [ + 4.69, + 0, + "idle", + false + ], + [ + 4.84, + 0, + "idle", + false + ], + [ + 4.98, + 0, + "idle", + false + ], + [ + 5.13, + 0, + "idle", + false + ], + [ + 5.28, + 0, + "idle", + false + ], + [ + 5.42, + 0, + "idle", + false + ], + [ + 5.57, + 0, + "idle", + false + ], + [ + 5.72, + 0, + "idle", + false + ], + [ + 5.86, + 0, + "idle", + false + ], + [ + 6.01, + 0, + "idle", + false + ], + [ + 6.15, + 0, + "idle", + false + ], + [ + 6.32, + 0, + "idle", + false + ], + [ + 6.47, + 0, + "idle", + false + ] + ], + "zero_at_s": 1.89 + }, + "fixture": { + "channels": [ + "lid", + "interlock", + "button" + ], + "hostname": "", + "ip": "", + "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": 6422, + "why": "" + }, + "mode_after_start": { + "controller": "running", + "gated": false, + "local": false, + "mode": "grbl", + "motion": "verified", + "pid": 6371, + "why": "" + }, + "operator": { + "ack_live": true, + "ts": "2026-10-18T23:12:57Z" + }, + "sigkill": { + "fast": { + "kernel_stopped_at_s": 0.271, + "latch_locked_at_s": 0.032 + }, + "kernel_not_running": true, + "latch_locked": true, + "pid": 6371, + "tail_zero": true, + "trail": [ + [ + 0.3, + 96, + "idle", + false + ], + [ + 0.45, + 96, + "idle", + false + ], + [ + 0.6, + 96, + "idle", + false + ], + [ + 0.75, + 96, + "idle", + false + ], + [ + 0.89, + 96, + "idle", + false + ], + [ + 1.04, + 14, + "idle", + false + ], + [ + 1.19, + 14, + "idle", + false + ], + [ + 1.34, + 14, + "idle", + false + ], + [ + 1.49, + 14, + "idle", + false + ], + [ + 1.63, + 14, + "idle", + false + ], + [ + 1.78, + 14, + "idle", + false + ], + [ + 1.93, + 14, + "idle", + false + ], + [ + 2.07, + 0, + "idle", + false + ], + [ + 2.22, + 0, + "idle", + false + ], + [ + 2.39, + 0, + "idle", + false + ], + [ + 2.54, + 0, + "idle", + false + ], + [ + 2.68, + 0, + "idle", + false + ], + [ + 2.83, + 0, + "idle", + false + ], + [ + 2.98, + 0, + "idle", + false + ], + [ + 3.12, + 0, + "idle", + false + ], + [ + 3.27, + 0, + "idle", + false + ], + [ + 3.45, + 0, + "idle", + false + ], + [ + 3.6, + 0, + "idle", + false + ], + [ + 3.74, + 0, + "idle", + false + ], + [ + 3.89, + 0, + "idle", + false + ], + [ + 4.04, + 0, + "idle", + false + ], + [ + 4.18, + 0, + "idle", + false + ], + [ + 4.33, + 0, + "idle", + false + ], + [ + 4.48, + 0, + "idle", + false + ], + [ + 4.62, + 0, + "idle", + false + ], + [ + 4.77, + 0, + "idle", + false + ], + [ + 4.92, + 0, + "idle", + false + ], + [ + 5.07, + 0, + "idle", + false + ], + [ + 5.21, + 0, + "idle", + false + ], + [ + 5.36, + 0, + "idle", + false + ], + [ + 5.5, + 0, + "idle", + false + ], + [ + 5.65, + 0, + "idle", + false + ], + [ + 5.8, + 0, + "idle", + false + ], + [ + 5.94, + 0, + "idle", + false + ], + [ + 6.11, + 0, + "idle", + false + ], + [ + 6.25, + 0, + "idle", + false + ] + ], + "zero_at_s": 2.07 + } + }, + "fingerprint": "fcad9a2ae69c87684673820533b2be59062de34e001c4da99f290e7342c954ad", + "image": "20261018222431 (dev)", + "log": [ + "23:12:57 start laser.armed-kill (live, api) in campaign c-20261018224638-4ca0", + "23:12:57 fixture up: at , v1.0.0, covers lid, interlock, button", + "23:12:57 fixture: at covers lid, interlock, button", + "23:12:57 queued by the attended queue opened 2026-10-18T23:07:24Z", + "23:12:57 baseline: pre: clean", + "23:12:57 mode: test needs grbl - already in grbl mode", + "23:12:58 connect: Idle", + "23:12:58 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.", + "23:12:58 READY: waiting for the operator's press on the machine (the bench then does every press in this test)", + "23:13:04 READY: operator present (press after 6.1 s); the bench takes the presses", + "23:13:04 ARM: the fixture presses when the button lights (the bench's arm_press opt-in)", + "23:13:04 ARM press by the fixture, button lit after 0.3 s", + "23:13:09 emission live (110) - stopping the controller NOW", + "23:13:09 POST /controller/stop -> 200 {'stopped': True} (0.51 s)", + "23:13:15 post-stop (0.54, 110, 'idle', False)", + "23:13:15 post-stop (0.68, 110, 'idle', False)", + "23:13:15 post-stop (0.87, 51, 'idle', False)", + "23:13:15 post-stop (1.02, 51, 'idle', False)", + "23:13:15 post-stop (1.16, 51, 'idle', False)", + "23:13:15 post-stop (1.31, 51, 'idle', False)", + "23:13:15 post-stop (1.45, 51, 'idle', False)", + "23:13:15 post-stop (1.6, 51, 'idle', False)", + "23:13:15 post-stop (1.74, 51, 'idle', False)", + "23:13:15 post-stop (1.89, 0, 'idle', False)", + "23:13:15 post-stop (2.03, 0, 'idle', False)", + "23:13:15 post-stop (2.18, 0, 'idle', False)", + "23:13:15 post-stop (2.32, 0, 'idle', False)", + "23:13:15 post-stop (2.47, 0, 'idle', False)", + "23:13:15 post-stop (2.61, 0, 'idle', False)", + "23:13:15 post-stop (2.76, 0, 'idle', False)", + "23:13:15 post-stop (2.91, 0, 'idle', False)", + "23:13:15 post-stop (3.07, 0, 'idle', False)", + "23:13:15 post-stop (3.21, 0, 'idle', False)", + "23:13:15 post-stop (3.36, 0, 'idle', False)", + "23:13:15 post-stop (3.5, 0, 'idle', False)", + "23:13:15 post-stop (3.65, 0, 'idle', False)", + "23:13:15 post-stop (3.79, 0, 'idle', False)", + "23:13:15 post-stop (3.94, 0, 'idle', False)", + "23:13:15 post-stop (4.11, 0, 'idle', False)", + "23:13:15 post-stop (4.26, 0, 'idle', False)", + "23:13:15 post-stop (4.4, 0, 'idle', False)", + "23:13:15 post-stop (4.55, 0, 'idle', False)", + "23:13:15 post-stop (4.69, 0, 'idle', False)", + "23:13:15 post-stop (4.84, 0, 'idle', False)", + "23:13:15 post-stop (4.98, 0, 'idle', False)", + "23:13:15 post-stop (5.13, 0, 'idle', False)", + "23:13:15 post-stop (5.28, 0, 'idle', False)", + "23:13:15 post-stop (5.42, 0, 'idle', False)", + "23:13:15 post-stop (5.57, 0, 'idle', False)", + "23:13:15 post-stop (5.72, 0, 'idle', False)", + "23:13:15 post-stop (5.86, 0, 'idle', False)", + "23:13:15 post-stop (6.01, 0, 'idle', False)", + "23:13:15 post-stop (6.15, 0, 'idle', False)", + "23:13:15 post-stop (6.32, 0, 'idle', False)", + "23:13:15 post-stop (6.47, 0, 'idle', False)", + "23:13:15 emission first 0 at +1.89 s; last 2 s all zero: True; kernel not running: True", + "23:13:15 the controller is stopped (supervision held); restarting it (no motion, no laser)", + "23:13:15 POST /controller/start -> 200 {'started': True}", + "23:13:21 /mode after start: {'mode': 'grbl', 'controller': 'running', 'pid': 6371, 'motion': 'verified', 'gated': False, 'local': False, 'why': ''}", + "23:13:21 expected stop PASS: returned in 0.51 s, emission 0 at +1.89 s, controller restarted", + "23:13:22 connect: Idle", + "23:13:22 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.", + "23:13:22 READY: presence already proved this test; the bench has the presses", + "23:13:22 ARM: the fixture presses when the button lights (the bench's arm_press opt-in)", + "23:13:22 ARM press by the fixture, button lit after 0.3 s", + "23:13:23 emission live (96) - SIGKILL controller pid 6371 NOW", + "23:13:28 fixture up: at , v1.0.0, covers lid, interlock, button", + "23:13:30 after the kill (sysfs): {'latch_locked_at_s': 0.032, 'kernel_stopped_at_s': 0.271}", + "23:13:30 post-kill (0.3, 96, 'idle', False)", + "23:13:30 post-kill (0.45, 96, 'idle', False)", + "23:13:30 post-kill (0.6, 96, 'idle', False)", + "23:13:30 post-kill (0.75, 96, 'idle', False)", + "23:13:30 post-kill (0.89, 96, 'idle', False)", + "23:13:30 post-kill (1.04, 14, 'idle', False)", + "23:13:30 post-kill (1.19, 14, 'idle', False)", + "23:13:30 post-kill (1.34, 14, 'idle', False)", + "23:13:30 post-kill (1.49, 14, 'idle', False)", + "23:13:30 post-kill (1.63, 14, 'idle', False)", + "23:13:30 post-kill (1.78, 14, 'idle', False)", + "23:13:30 post-kill (1.93, 14, 'idle', False)", + "23:13:30 post-kill (2.07, 0, 'idle', False)", + "23:13:30 post-kill (2.22, 0, 'idle', False)", + "23:13:30 post-kill (2.39, 0, 'idle', False)", + "23:13:30 post-kill (2.54, 0, 'idle', False)", + "23:13:30 post-kill (2.68, 0, 'idle', False)", + "23:13:30 post-kill (2.83, 0, 'idle', False)", + "23:13:30 post-kill (2.98, 0, 'idle', False)", + "23:13:30 post-kill (3.12, 0, 'idle', False)", + "23:13:30 post-kill (3.27, 0, 'idle', False)", + "23:13:30 post-kill (3.45, 0, 'idle', False)", + "23:13:30 post-kill (3.6, 0, 'idle', False)", + "23:13:30 post-kill (3.74, 0, 'idle', False)", + "23:13:30 post-kill (3.89, 0, 'idle', False)", + "23:13:30 post-kill (4.04, 0, 'idle', False)", + "23:13:30 post-kill (4.18, 0, 'idle', False)", + "23:13:30 post-kill (4.33, 0, 'idle', False)", + "23:13:30 post-kill (4.48, 0, 'idle', False)", + "23:13:30 post-kill (4.62, 0, 'idle', False)", + "23:13:30 post-kill (4.77, 0, 'idle', False)", + "23:13:30 post-kill (4.92, 0, 'idle', False)", + "23:13:30 post-kill (5.07, 0, 'idle', False)", + "23:13:30 post-kill (5.21, 0, 'idle', False)", + "23:13:30 post-kill (5.36, 0, 'idle', False)", + "23:13:30 post-kill (5.5, 0, 'idle', False)", + "23:13:30 post-kill (5.65, 0, 'idle', False)", + "23:13:30 post-kill (5.8, 0, 'idle', False)", + "23:13:30 post-kill (5.94, 0, 'idle', False)", + "23:13:30 post-kill (6.11, 0, 'idle', False)", + "23:13:30 post-kill (6.25, 0, 'idle', False)", + "23:13:30 emission first 0 at +2.07 s; last 2 s all zero: True; kernel not running: True", + "23:13:30 latch locked after the kill: True", + "23:13:30 /mode after the kill: {'mode': 'grbl', 'controller': 'running', 'pid': 6422, 'motion': 'verified', 'gated': False, 'local': False, 'why': ''}", + "23:13:32 button dark after 0.0 s", + "23:13:32 PASS: expected stop 0 at +1.89 s and SIGKILL 0 at +2.07 s, latch locked, controller respawned with the latch still locked, button dark", + "23:13:40 baseline: cool: smoke/armed=False/hold=False ended on its own after 8 s; the engine's own post-job work, not a leftover", + "23:13:40 baseline: post: clean", + "23:13:40 result PASS" + ], + "manifest_sha": "70ecd7867c2698d17f2f3c38db772868eda3364f541242c93fb5db4e1d593bcd", + "message": "", + "result": "PASS", + "test": "laser.armed-kill", + "ts": "2026-10-18T23:13:40Z" + }, + "requires": [ + "laser.emission-witness", + "motion.deadman" + ], + "satisfied": true, + "source_sha": "7f9f194cd8239e7213968330b3d775f6d4b17a4c3c1124d5296adcca034b219c", + "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" + ], + [ + "grblhal-glowforge", + "src/glowforge_switches.c" + ], + [ + "grblhal-glowforge", + "src/glowforge_switch_map.h" + ] + ], + "fingerprint": "f3a0ad773b639fcdfda61ca43f15749c5f93d27f1b40978b84ff82c10f13d29c", + "hardware": "api", + "id": "laser.pause-resume-lid-cancel", + "inherited": false, + "kind": "live", + "record": { + "answers": [], + "campaign": "c-20261018224638-4ca0", + "duration_s": 36, + "evidence": { + "actions": [ + { + "by": "operator", + "channel": "button", + "state": "presence", + "took_s": 6.35, + "ts": "2026-10-18T23:13:48Z" + }, + { + "by": "fixture", + "channel": "button", + "state": "arm", + "took_s": 0.25, + "ts": "2026-10-18T23:13:48Z" + }, + { + "by": "fixture", + "channel": "button", + "state": "press", + "took_s": 0.11, + "ts": "2026-10-18T23:13:55Z" + }, + { + "by": "fixture", + "channel": "button", + "state": "press", + "took_s": 0.12, + "ts": "2026-10-18T23:13:59Z" + }, + { + "by": "fixture", + "channel": "lid", + "state": "open", + "took_s": 0.02, + "ts": "2026-10-18T23:14:00Z" + }, + { + "by": "fixture", + "channel": "lid", + "state": "close", + "took_s": 0.28, + "ts": "2026-10-18T23:14:08Z" + } + ], + "armed_after": false, + "armed_while_paused": true, + "baseline": { + "post": [], + "pre": [] + }, + "batch": { + "group": "attended", + "ts": "2026-10-18T23:07:24Z" + }, + "beam": { + "delta": 742, + "digital_seen": true, + "idle": 1859, + "peak": 2601, + "samples": 4 + }, + "button_dark": false, + "button_latch": 1, + "drift_mm": 0.028, + "emission_back_after_s": 0.42, + "emission_running": 96, + "emission_zero_when_paused": true, + "fixture": { + "channels": [ + "lid", + "interlock", + "button" + ], + "hostname": "", + "ip": "", + "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-10-18T23:13:41Z" + }, + "pause_message": true, + "paused_trail": [ + [ + 0.03, + 96, + true + ], + [ + 0.25, + 96, + true + ], + [ + 0.48, + 96, + true + ], + [ + 0.71, + 81, + true + ], + [ + 0.99, + 81, + true + ], + [ + 1.21, + 81, + true + ], + [ + 1.44, + 81, + true + ], + [ + 1.67, + 0, + true + ], + [ + 1.89, + 0, + true + ], + [ + 2.12, + 0, + true + ], + [ + 2.34, + 0, + true + ], + [ + 2.57, + 0, + true + ], + [ + 2.8, + 0, + true + ], + [ + 3.02, + 0, + true + ], + [ + 3.25, + 0, + true + ], + [ + 3.47, + 0, + true + ], + [ + 3.7, + 0, + true + ], + [ + 3.93, + 0, + true + ] + ], + "resume_message": true, + "resume_trail": [ + [ + 0.04, + 0 + ], + [ + 0.23, + 0 + ], + [ + 0.42, + 23 + ] + ], + "resumed_state": "Run", + "returned_message": true, + "start": [ + 0.0, + 0.0, + 4.449 + ] + }, + "fingerprint": "f3a0ad773b639fcdfda61ca43f15749c5f93d27f1b40978b84ff82c10f13d29c", + "image": "20261018222431 (dev)", + "log": [ + "23:13:41 start laser.pause-resume-lid-cancel (live, api) in campaign c-20261018224638-4ca0", + "23:13:41 fixture up: at , v1.0.0, covers lid, interlock, button", + "23:13:41 fixture: at covers lid, interlock, button", + "23:13:41 queued by the attended queue opened 2026-10-18T23:07:24Z", + "23:13:41 baseline: pre: clean", + "23:13:41 mode: test needs grbl - already in grbl mode", + "23:13:42 unlock: ['[MSG:Caution: Unlocked]', 'ok']", + "23:13:42 connect: Idle", + "23:13:42 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.", + "23:13:42 READY: waiting for the operator's press on the machine (the bench then does every press in this test)", + "23:13:48 READY: operator present (press after 6.3 s); the bench takes the presses", + "23:13:48 ARM: the fixture presses when the button lights (the bench's arm_press opt-in)", + "23:13:49 ARM press by the fixture, button lit after 0.3 s", + "23:13:55 emission live (96) - asking the operator to pause", + "23:13:55 ACT button press (fixture)", + "23:13:55 ACT button press: done after 0.1 s", + "23:13:59 paused (0.03, 96, True)", + "23:13:59 paused (0.25, 96, True)", + "23:13:59 paused (0.48, 96, True)", + "23:13:59 paused (0.71, 81, True)", + "23:13:59 paused (0.99, 81, True)", + "23:13:59 paused (1.21, 81, True)", + "23:13:59 paused (1.44, 81, True)", + "23:13:59 paused (1.67, 0, True)", + "23:13:59 paused (1.89, 0, True)", + "23:13:59 paused (2.12, 0, True)", + "23:13:59 paused (2.34, 0, True)", + "23:13:59 paused (2.57, 0, True)", + "23:13:59 paused (2.8, 0, True)", + "23:13:59 paused (3.02, 0, True)", + "23:13:59 paused (3.25, 0, True)", + "23:13:59 paused (3.47, 0, True)", + "23:13:59 paused (3.7, 0, True)", + "23:13:59 paused (3.93, 0, True)", + "23:13:59 paused: Hold:0, emission 0 = True, armed = True, latch locked = False", + "23:13:59 ACT button press (fixture)", + "23:13:59 ACT button press: done after 0.1 s", + "23:14:00 emission after the resume: [(0.04, 0), (0.23, 0), (0.42, 23)]", + "23:14:00 ACT lid open (fixture)", + "23:14:00 ACT lid open: done after 0.0 s", + "23:14:08 post-lid (0.04, 23, 'running', True)", + "23:14:08 post-lid (0.26, 23, 'running', False)", + "23:14:08 post-lid (0.51, 23, 'running', False)", + "23:14:08 post-lid (0.71, 23, 'running', False)", + "23:14:08 post-lid (0.9, 34, 'idle', False)", + "23:14:08 post-lid (1.1, 34, 'idle', False)", + "23:14:08 post-lid (1.29, 34, 'idle', False)", + "23:14:08 post-lid (1.49, 34, 'idle', False)", + "23:14:08 post-lid (1.69, 34, 'idle', False)", + "23:14:08 post-lid (1.89, 0, 'idle', False)", + "23:14:08 post-lid (2.08, 0, 'idle', False)", + "23:14:08 post-lid (2.28, 0, 'idle', False)", + "23:14:08 post-lid (2.48, 0, 'idle', False)", + "23:14:08 post-lid (2.67, 0, 'idle', False)", + "23:14:08 post-lid (2.87, 0, 'idle', False)", + "23:14:08 post-lid (3.07, 0, 'idle', False)", + "23:14:08 post-lid (3.26, 0, 'idle', False)", + "23:14:08 post-lid (3.46, 0, 'idle', False)", + "23:14:08 post-lid (3.65, 0, 'idle', False)", + "23:14:08 post-lid (3.85, 0, 'idle', False)", + "23:14:08 post-lid (4.05, 0, 'idle', False)", + "23:14:08 post-lid (4.25, 0, 'idle', False)", + "23:14:08 post-lid (4.44, 0, 'idle', False)", + "23:14:08 post-lid (4.64, 0, 'idle', False)", + "23:14:08 post-lid (4.84, 0, 'idle', False)", + "23:14:08 post-lid (5.03, 0, 'idle', False)", + "23:14:08 post-lid (5.23, 0, 'idle', False)", + "23:14:08 post-lid (5.43, 0, 'idle', False)", + "23:14:08 post-lid (5.62, 0, 'idle', False)", + "23:14:08 post-lid (5.86, 0, 'idle', False)", + "23:14:08 post-lid (6.06, 0, 'idle', False)", + "23:14:08 post-lid (6.25, 0, 'idle', False)", + "23:14:08 post-lid (6.45, 0, 'idle', False)", + "23:14:08 post-lid (6.64, 0, 'idle', False)", + "23:14:08 post-lid (6.84, 0, 'idle', False)", + "23:14:08 post-lid (7.04, 0, 'idle', False)", + "23:14:08 post-lid (7.23, 0, 'idle', False)", + "23:14:08 post-lid (7.43, 0, 'idle', False)", + "23:14:08 post-lid (7.63, 0, 'idle', False)", + "23:14:08 post-lid (7.82, 0, 'idle', False)", + "23:14:08 post-lid (8.07, 0, 'idle', False)", + "23:14:08 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]']", + "23:14:08 returned: drift 0.028 mm; armed=False latch_locked=True button_latch=1", + "23:14:08 kernel counters: start (0.00, 0.00) -> now (0.03, 0.00), drift 0.030 mm", + "23:14:08 beam detector: idle 1859, peak 2601, digital asserted True", + "23:14:08 button dark after 0.0 s", + "23:14:08 ACT lid close (fixture)", + "23:14:08 ACT lid close: done after 0.3 s", + "23:14:09 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", + "23:14:12 fixture up: at , v1.0.0, covers lid, interlock, button", + "23:14:16 baseline: cool: smoke/armed=False/hold=False ended on its own after 7 s; the engine's own post-job work, not a leftover", + "23:14:18 baseline: head jogged back -0.028/-0.000 mm to its start", + "23:14:18 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", + "23:14:18 baseline: post: clean", + "23:14:18 result PASS" + ], + "manifest_sha": "70ecd7867c2698d17f2f3c38db772868eda3364f541242c93fb5db4e1d593bcd", + "message": "", + "result": "PASS", + "test": "laser.pause-resume-lid-cancel", + "ts": "2026-10-18T23:14:18Z" + }, + "requires": [ + "laser.emission-witness" + ], + "satisfied": true, + "source_sha": "e89cf3007e54fd62e75c796ea9cd7f4cbe9851d966c58e45bc71068043ba4362", + "subsystem": "laser", + "title": "One live cut: the button pauses and resumes it, the lid cancels it and sends the head home" + }, + { + "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": "60ac33ab644bcf1cf18d1f22d1aa2da8d9dd506767f2821a7c5c6813acdace69", + "hardware": "api", + "id": "camera.snapshot", + "inherited": false, + "kind": "auto", + "record": { + "answers": [], + "campaign": "c-20261018224638-4ca0", + "duration_s": 16, + "evidence": { + "background_after_watching": [ + 200, + 95535 + ], + "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-10-18T22:46:38Z" + }, + "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": 4, + "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": 1, + "fixture": { + "channels": [ + "lid", + "interlock", + "button" + ], + "hostname": "", + "ip": "", + "released": [] + }, + "lid_lamp": "132", + "operator_while_watched": [ + 200, + 95552 + ], + "snapshot_bytes": 94890, + "snapshot_dark_bytes": 49877, + "snapshot_full_bytes": 301044, + "stream_ctype": "multipart/x-mixed-replace; boundary=forgectrl-frame" + }, + "fingerprint": "60ac33ab644bcf1cf18d1f22d1aa2da8d9dd506767f2821a7c5c6813acdace69", + "image": "20261018222431 (dev)", + "log": [ + "22:57:30 start camera.snapshot (auto, api) in campaign c-20261018224638-4ca0", + "22:57:30 fixture up: at , v1.0.0, covers lid, interlock, button", + "22:57:30 fixture: at covers lid, interlock, button", + "22:57:30 queued by the unattended queue opened 2026-10-18T22:46:38Z", + "22:57:30 baseline: pre: clean", + "22:57:30 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}", + "22:57:31 GET /cam/snapshot?cam=lid&res=half -> 200 (94890 bytes)", + "22:57:33 lamp 132 -> 94890 bytes; lamp off -> 49877 bytes", + "22:57:34 GET /cam/snapshot?cam=lid&res=full -> 200 (301044 bytes)", + "22:57:35 stream: multipart/x-mixed-replace; boundary=forgectrl-frame, first 65536 bytes", + "22:57:35 background capture while a viewer watches -> 409 somebody is watching a camera: a background capture waits until they stop", + "22:57:38 cam status after: {'running': True, 'cam': 'lid', 'clients': 0, 'frames': 4, '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}", + "22:57:38 PASS: half-res snapshot 94890 bytes, 49877 with the lamp off; full-res 301044; stream multipart/x-mixed-replace; boundary=forgectrl-frame", + "22:57:47 baseline: post: clean", + "22:57:47 result PASS" + ], + "manifest_sha": "70ecd7867c2698d17f2f3c38db772868eda3364f541242c93fb5db4e1d593bcd", + "message": "", + "result": "PASS", + "test": "camera.snapshot", + "ts": "2026-10-18T22:57:47Z" + }, + "requires": [], + "satisfied": true, + "source_sha": "ef51a9cb61a787f0e760006fa271b499176eb8f01cd4a04acb55be9f207329e0", + "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": "0dda2319a9934bc240145d421c4d4a51326b7461eaf30103c0e33984a1abfbe8", + "hardware": "api", + "id": "camera.sensor-profile", + "inherited": false, + "kind": "auto", + "record": { + "answers": [], + "campaign": "c-20261018224638-4ca0", + "duration_s": 13, + "evidence": { + "baseline": { + "post": [], + "pre": [] + }, + "batch": { + "group": "unattended", + "ts": "2026-10-18T22:46:38Z" + }, + "fixture": { + "channels": [ + "lid", + "interlock", + "button" + ], + "hostname": "", + "ip": "", + "released": [] + }, + "geometry": { + "snapshot": { + "height": 1944, + "width": 2592 + }, + "stream": { + "height": 972, + "width": 1296 + } + }, + "jpeg_full": [ + 2592, + 1944 + ], + "jpeg_half": [ + 1296, + 972 + ], + "sensor": "OV5648" + }, + "fingerprint": "0dda2319a9934bc240145d421c4d4a51326b7461eaf30103c0e33984a1abfbe8", + "image": "20261018222431 (dev)", + "log": [ + "22:57:47 start camera.sensor-profile (auto, api) in campaign c-20261018224638-4ca0", + "22:57:47 fixture up: at , v1.0.0, covers lid, interlock, button", + "22:57:47 fixture: at covers lid, interlock, button", + "22:57:47 queued by the unattended queue opened 2026-10-18T22:46:38Z", + "22:57:47 baseline: pre: clean", + "22:57:47 sensor: OV5648", + "22:57:47 advertised: snapshot 2592x1944, stream 1296x972", + "22:57:49 full snapshot: (2592, 1944) (300170 bytes)", + "22:57:49 half snapshot: (1296, 972) (95757 bytes)", + "22:58:00 baseline: post: clean", + "22:58:00 result PASS" + ], + "manifest_sha": "70ecd7867c2698d17f2f3c38db772868eda3364f541242c93fb5db4e1d593bcd", + "message": "", + "result": "PASS", + "test": "camera.sensor-profile", + "ts": "2026-10-18T22:58:00Z" + }, + "requires": [], + "satisfied": true, + "source_sha": "5d572142d1c3073188493518b55a39a5c6e9c1a110d5bb36d595eef5f4a75e50", + "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": "c34d83443a3cd0338042fb0cc32dc75c5c8a85e31381227780747c82eb1cc545", + "hardware": "api", + "id": "camera.h264-stream", + "inherited": false, + "kind": "auto", + "record": { + "answers": [], + "campaign": "c-20261018224638-4ca0", + "duration_s": 12, + "evidence": { + "baseline": { + "post": [], + "pre": [] + }, + "batch": { + "group": "unattended", + "ts": "2026-10-18T22:46:38Z" + }, + "bytes": 65536, + "cam_status": { + "buffers": "uncached", + "cam": "lid", + "capture_allowed": true, + "clients": 0, + "convert": "gpu", + "encoder": "vpu", + "fps": 0.0, + "fps_cap": 0.0, + "frames": 0, + "h264": { + "active": true, + "clients": 1 + }, + "health": { + "captured": 373, + "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": 13 + } + }, + "codec": "avc1.424020", + "content_type": "video/mp4", + "fixture": { + "channels": [ + "lid", + "interlock", + "button" + ], + "hostname": "", + "ip": "", + "released": [] + } + }, + "fingerprint": "c34d83443a3cd0338042fb0cc32dc75c5c8a85e31381227780747c82eb1cc545", + "image": "20261018222431 (dev)", + "log": [ + "22:58:01 start camera.h264-stream (auto, api) in campaign c-20261018224638-4ca0", + "22:58:01 fixture up: at , v1.0.0, covers lid, interlock, button", + "22:58:01 fixture: at covers lid, interlock, button", + "22:58:01 queued by the unattended queue opened 2026-10-18T22:46:38Z", + "22:58:01 baseline: pre: clean", + "22:58:02 codec avc1.424020, content-type video/mp4", + "22:58:02 convert=gpu h264={'active': True, 'clients': 1}", + "22:58:14 baseline: post: clean", + "22:58:14 result PASS" + ], + "manifest_sha": "70ecd7867c2698d17f2f3c38db772868eda3364f541242c93fb5db4e1d593bcd", + "message": "", + "result": "PASS", + "test": "camera.h264-stream", + "ts": "2026-10-18T22:58:14Z" + }, + "requires": [], + "satisfied": true, + "source_sha": "09ea64f2553a27090e38aae787094d84582453707aa93562ca2a4a22e8f7ed83", + "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": "4ed3732a26795634f5c464a3e841f818d8d841b9eba40963a66dc4f2d37666b9", + "hardware": "api", + "id": "camera.frame-health", + "inherited": false, + "kind": "auto", + "record": { + "answers": [], + "campaign": "c-20261018224638-4ca0", + "duration_s": 18, + "evidence": { + "baseline": { + "post": [], + "pre": [] + }, + "batch": { + "group": "unattended", + "ts": "2026-10-18T22:46:38Z" + }, + "captured": 14, + "corrupt": 0, + "fixture": { + "channels": [ + "lid", + "interlock", + "button" + ], + "hostname": "", + "ip": "", + "released": [] + }, + "health_after": { + "captured": 540, + "corrupt": 0, + "restarts": 0, + "withheld": 0 + }, + "health_before": { + "captured": 526, + "corrupt": 0, + "restarts": 0, + "withheld": 0 + }, + "restarts": 0, + "stream_bytes": 12648448, + "stream_captured": 75, + "stream_health": [ + { + "captured": 540, + "corrupt": 0, + "restarts": 0, + "withheld": 0 + }, + { + "captured": 615, + "corrupt": 0, + "restarts": 0, + "withheld": 0 + } + ], + "stream_timing": { + "convert_ms": 16.1, + "copy_ms": 11.8, + "encode_ms": 7.1, + "latency_ms": 67.4, + "skipped": 18 + }, + "stream_withheld": 0 + }, + "fingerprint": "4ed3732a26795634f5c464a3e841f818d8d841b9eba40963a66dc4f2d37666b9", + "image": "20261018222431 (dev)", + "log": [ + "22:58:14 start camera.frame-health (auto, api) in campaign c-20261018224638-4ca0", + "22:58:14 fixture up: at , v1.0.0, covers lid, interlock, button", + "22:58:14 fixture: at covers lid, interlock, button", + "22:58:14 queued by the unattended queue opened 2026-10-18T22:46:38Z", + "22:58:14 baseline: pre: clean", + "22:58:14 before: {'captured': 526, 'corrupt': 0, 'restarts': 0, 'withheld': 0}", + "22:58:16 after: {'captured': 540, 'corrupt': 0, 'restarts': 0, 'withheld': 0}", + "22:58:16 captured 14 frames, 0 corrupt, 0 stream restarts", + "22:58:21 stream: 12648448 bytes in 5 s, timing {'latency_ms': 67.4, 'convert_ms': 16.1, 'copy_ms': 11.8, 'encode_ms': 7.1, 'skipped': 18}", + "22:58:32 baseline: post: clean", + "22:58:32 result PASS" + ], + "manifest_sha": "70ecd7867c2698d17f2f3c38db772868eda3364f541242c93fb5db4e1d593bcd", + "message": "", + "result": "PASS", + "test": "camera.frame-health", + "ts": "2026-10-18T22:58:32Z" + }, + "requires": [], + "satisfied": true, + "source_sha": "d14d6464e7214d9a395560b32712fe0ea82eddf5b06c214fa51a0bc9d85bb635", + "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": "4bafe8e6630c701753586f94decaa0da43b35d5cc7809d0a6cb4d83afee19970", + "hardware": "api", + "id": "camera.lid-privacy", + "inherited": false, + "kind": "operator", + "record": { + "answers": [], + "campaign": "c-20261018224638-4ca0", + "duration_s": 15, + "evidence": { + "actions": [ + { + "by": "fixture", + "channel": "lid", + "state": "close", + "took_s": 0.02, + "ts": "2026-10-18T22:58:33Z" + }, + { + "by": "fixture", + "channel": "lid", + "state": "open", + "took_s": 0.03, + "ts": "2026-10-18T22:58:34Z" + }, + { + "by": "fixture", + "channel": "lid", + "state": "close", + "took_s": 0.28, + "ts": "2026-10-18T22:58:36Z" + } + ], + "baseline": { + "post": [], + "pre": [] + }, + "batch": { + "group": "unattended", + "ts": "2026-10-18T22:46:38Z" + }, + "closed_snapshot_bytes": 95677, + "fixture": { + "channels": [ + "lid", + "interlock", + "button" + ], + "hostname": "", + "ip": "", + "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": 778, + "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": 20 + } + }, + "stream_bytes_after_lid_open": 356877 + }, + "fingerprint": "4bafe8e6630c701753586f94decaa0da43b35d5cc7809d0a6cb4d83afee19970", + "image": "20261018222431 (dev)", + "log": [ + "22:58:32 start camera.lid-privacy (operator, api) in campaign c-20261018224638-4ca0", + "22:58:33 fixture up: at , v1.0.0, covers lid, interlock, button", + "22:58:33 fixture: at covers lid, interlock, button", + "22:58:33 fixture: running unattended (no prompt can be answered)", + "22:58:33 queued by the unattended queue opened 2026-10-18T22:46:38Z", + "22:58:33 baseline: pre: clean", + "22:58:33 ACT lid close (fixture)", + "22:58:33 ACT lid close: done after 0.0 s", + "22:58:34 lid closed: snapshot 95677 bytes", + "22:58:34 ACT lid open (fixture)", + "22:58:34 ACT lid open: done after 0.0 s", + "22:58:34 stream ended after 356877 further buffered bytes", + "22:58:34 lid open: snapshot -> 409 b'lid is open: this capture needs the lid closed'", + "22:58:35 lid open: the panel's head snapshot -> 200", + "22:58:36 lid open: the extension host's head snapshot -> 200", + "22:58:36 lid open: head snapshot without a token or the header -> 409 b'lid is open: this capture needs the lid closed'", + "22:58:36 lid open: head stream for no local viewer -> 409", + "22:58:36 lid open: stream -> 409", + "22:58:36 ACT lid close (fixture)", + "22:58:36 ACT lid close: done after 0.3 s", + "22:58:37 lid closed again: snapshot 95485 bytes", + "22:58:48 baseline: post: clean", + "22:58:48 result PASS" + ], + "manifest_sha": "70ecd7867c2698d17f2f3c38db772868eda3364f541242c93fb5db4e1d593bcd", + "message": "", + "result": "PASS", + "test": "camera.lid-privacy", + "ts": "2026-10-18T22:58:48Z" + }, + "requires": [], + "satisfied": true, + "source_sha": "6bc85a083096f3e2828d2162ef730b78eb3783a88617941cecc0bea550b89c46", + "subsystem": "camera", + "title": "Cameras see the room only with the lid closed" + }, + { + "always": false, + "covers": [ + [ + "forgectrl", + "src/update.c" + ], + [ + "forgectrl", + "src/update.h" + ], + [ + "forgectrl", + "src/relcheck.c" + ], + [ + "forgectrl", + "src/relcheck.h" + ], + [ + "ffboot", + "**" + ] + ], + "fingerprint": "0aab6ce9ab2c03cce8edb40a3a3d31bd5d71acc52baa2b5326d1ab4036fc8428", + "hardware": "api", + "id": "update.slots-and-signature", + "inherited": false, + "kind": "auto", + "record": { + "answers": [], + "campaign": "c-20261018224638-4ca0", + "duration_s": 1, + "evidence": { + "apply": { + "body": { + "started": true + }, + "status": 202 + }, + "apply_log": [ + "2026-10-18T22:58:49.617053+00:00 forgectrl[1809] NOTICE update: writing the uploaded archive into slot b", + "2026-10-18T22:58:49.860800+00:00 forgectrl[1809] WARNING update: the apply failed: archive is not signed with the ForgeFIRM release key (confirm_unsigned=1 to apply anyway)" + ], + "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-10-18T22:46:38Z" + }, + "ffboot_l_rc": 0, + "fixture": { + "channels": [ + "lid", + "interlock", + "button" + ], + "hostname": "", + "ip": "", + "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.7" + }, + "sd": { + "booted": true, + "device": "/dev/mmcblk1p1", + "kernel": "yes", + "next": true, + "present": "yes", + "state": "ok", + "type": "forgefirm", + "version": "20261018222431 (dev)" + } + }, + "staged": { + "download": { + "bytes": 38488287, + "present": true, + "version": "v0.0.7" + }, + "upload": { + "bytes": 0, + "present": false, + "version": "" + } + } + } + }, + "fingerprint": "0aab6ce9ab2c03cce8edb40a3a3d31bd5d71acc52baa2b5326d1ab4036fc8428", + "image": "20261018222431 (dev)", + "log": [ + "22:58:48 start update.slots-and-signature (auto, api) in campaign c-20261018224638-4ca0", + "22:58:49 fixture up: at , v1.0.0, covers lid, interlock, button", + "22:58:49 fixture: at covers lid, interlock, button", + "22:58:49 queued by the unattended queue opened 2026-10-18T22:46:38Z", + "22:58:49 baseline: pre: clean", + "22:58:49 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': '20261018222431 (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.7', 'kernel': 'yes', 'booted': False, 'next': False}}, 'archives': [], 'staged': {'download': {'present': True, 'bytes': 38488287, 'version': 'v0.0.7'}, 'upload': {'present': False, 'bytes': 0, 'version': ''}}}", + "22:58:49 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=20261018222431 (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.7\nslot.b.kernel=yes\nslot.legacy.device=/dev/mmcblk2p4\nslot.legacy.present=no", + "22:58:49 GET /update/status -> 200 {'running': False, 'kind': '', 'phase': '', 'elapsed': 0, 'progress_bytes': -1, 'result': None}", + "22:58:49 fwup -V garbage -> rc 1: fwup: Unrecognized archive format", + "22:58:49 fwup -V signed: own key rc 0, shipped key rc 1", + "22:58:49 POST /update/apply slot=b file=upload (no confirm_unsigned) -> 202 {'started': True}", + "22:58:50 apply result: {'ok': False, 'error': 'archive is not signed with the ForgeFIRM release key (confirm_unsigned=1 to apply anyway)'}", + "22:58:50 baseline: post: clean", + "22:58:50 result PASS" + ], + "manifest_sha": "70ecd7867c2698d17f2f3c38db772868eda3364f541242c93fb5db4e1d593bcd", + "message": "", + "result": "PASS", + "test": "update.slots-and-signature", + "ts": "2026-10-18T22:58:50Z" + }, + "requires": [ + "forgectrl.auth" + ], + "satisfied": true, + "source_sha": "7e276c113518419469f10f8ff23408d3047d7f0863ce99b0f0178320f0795573", + "subsystem": "update", + "title": "Boot slots readable, unsigned and foreign-signed archives refused" + }, + { + "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": "57d696cefbd3cf910340f2e2a081767d659081c72d829e6de2b1f9bad8c25df3", + "hardware": "api", + "id": "cloud.mode-switch", + "inherited": false, + "kind": "operator", + "record": { + "answers": [], + "campaign": "c-20261018224638-4ca0", + "duration_s": 128, + "evidence": { + "actions": [ + { + "by": "fixture", + "channel": "lid", + "state": "open", + "took_s": 0.02, + "ts": "2026-10-18T22:58:55Z" + }, + { + "by": "fixture", + "channel": "lid", + "state": "close", + "took_s": 0.29, + "ts": "2026-10-18T22:59:05Z" + } + ], + "baseline": { + "post": [], + "pre": [] + }, + "batch": { + "group": "unattended", + "ts": "2026-10-18T22:46:38Z" + }, + "cam_after": { + "buffers": "uncached", + "cam": "lid", + "capture_allowed": true, + "clients": 0, + "convert": "gpu", + "encoder": "vpu", + "fps": 0.0, + "fps_cap": 0.0, + "frames": 0, + "h264": { + "active": false, + "clients": 0 + }, + "health": { + "captured": 1398, + "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": 32 + } + }, + "cam_before": { + "buffers": "uncached", + "cam": "lid", + "capture_allowed": true, + "clients": 0, + "convert": "gpu", + "encoder": "vpu", + "fps": 0.0, + "fps_cap": 0.0, + "frames": 0, + "h264": { + "active": false, + "clients": 0 + }, + "health": { + "captured": 949, + "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": 24 + } + }, + "cam_during_cloud": { + "buffers": "uncached", + "cam": "lid", + "capture_allowed": false, + "clients": 0, + "convert": "gpu", + "encoder": "vpu", + "fps": 0.0, + "fps_cap": 0.0, + "frames": 0, + "h264": { + "active": false, + "clients": 0 + }, + "health": { + "captured": 949, + "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": 24 + } + }, + "cloud_return": { + "counters_across_jog": [ + [ + 0, + 0, + 0 + ], + [ + 4972, + -2760, + 0 + ] + ], + "counters_since_start": [ + 0, + 0, + 0 + ], + "mm": [ + -23.306, + 12.938 + ], + "session_travel_steps": [ + -1243, + 690 + ] + }, + "fixture": { + "channels": [ + "lid", + "interlock", + "button" + ], + "hostname": "", + "ip": "", + "released": [] + }, + "gf_probe": { + "checked_at": 1792364334, + "latest_gf_version": "2.6.0-2228", + "tested_against_gf": "2.6.0-2228" + }, + "gfhome_complete": "2026-10-18T23:00:46.816658+00:00 gfhome[3218] INFO gfhome:home homing complete (service quiet 10s, 9 motion windows)", + "grbl_state": "Idle", + "homed": true, + "homing_mode": "manual", + "homing_s": 45.7, + "hunt": "2026-10-18T22:59:04.829476+00:00 gfcloud[2914] INFO basemachine:_finish_action hunt [1596426040]: finished with event \":completed\"", + "hunt_before_lid_open": false, + "hunt_gates": [ + { + "accel_watch": "watch", + "armed": false, + "down_c": 22.3, + "fan_gates": { + "air_assist": { + "floor": 6093, + "reading": 2534, + "state": "idle" + }, + "exhaust": { + "floor": 6416, + "reading": 0, + "state": "idle" + }, + "intake_1": { + "floor": 2277, + "reading": 730, + "state": "idle" + }, + "intake_2": { + "floor": 2277, + "reading": 731, + "state": "idle" + }, + "purge": { + "floor": 345, + "reading": 631, + "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": "HEAD CRASH SIGNAL (axes y) - motion stopped, laser locked", + "report_age_s": 0.3, + "resume_ok": true, + "up_c": 22.23, + "verdict": "OK" + }, + { + "accel_watch": "watch", + "armed": false, + "down_c": 22.3, + "fan_gates": { + "air_assist": { + "floor": 6093, + "reading": 2534, + "state": "idle" + }, + "exhaust": { + "floor": 6416, + "reading": 0, + "state": "idle" + }, + "intake_1": { + "floor": 2277, + "reading": 730, + "state": "idle" + }, + "intake_2": { + "floor": 2277, + "reading": 731, + "state": "idle" + }, + "purge": { + "floor": 345, + "reading": 631, + "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": "HEAD CRASH SIGNAL (axes y) - motion stopped, laser locked", + "report_age_s": 0.8, + "resume_ok": true, + "up_c": 22.23, + "verdict": "OK" + }, + { + "accel_watch": "watch", + "armed": false, + "down_c": 22.23, + "fan_gates": { + "air_assist": { + "floor": 6093, + "reading": 2671, + "state": "idle" + }, + "exhaust": { + "floor": 6416, + "reading": 0, + "state": "idle" + }, + "intake_1": { + "floor": 2277, + "reading": 729, + "state": "idle" + }, + "intake_2": { + "floor": 2277, + "reading": 726, + "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": "HEAD CRASH SIGNAL (axes y) - motion stopped, laser locked", + "report_age_s": 0.3, + "resume_ok": true, + "up_c": 22.23, + "verdict": "OK" + }, + { + "accel_watch": "watch", + "armed": false, + "down_c": 22.23, + "fan_gates": { + "air_assist": { + "floor": 6093, + "reading": 2671, + "state": "idle" + }, + "exhaust": { + "floor": 6416, + "reading": 0, + "state": "idle" + }, + "intake_1": { + "floor": 2277, + "reading": 729, + "state": "idle" + }, + "intake_2": { + "floor": 2277, + "reading": 726, + "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": "HEAD CRASH SIGNAL (axes y) - motion stopped, laser locked", + "report_age_s": 0.8, + "resume_ok": true, + "up_c": 22.23, + "verdict": "OK" + }, + { + "accel_watch": "watch", + "armed": false, + "down_c": 22.23, + "fan_gates": { + "air_assist": { + "floor": 6093, + "reading": 2727, + "state": "idle" + }, + "exhaust": { + "floor": 6416, + "reading": 0, + "state": "idle" + }, + "intake_1": { + "floor": 2277, + "reading": 733, + "state": "idle" + }, + "intake_2": { + "floor": 2277, + "reading": 726, + "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": "HEAD CRASH SIGNAL (axes y) - motion stopped, laser locked", + "report_age_s": 0.3, + "resume_ok": true, + "up_c": 21.91, + "verdict": "OK" + }, + { + "accel_watch": "watch", + "armed": false, + "down_c": 22.23, + "fan_gates": { + "air_assist": { + "floor": 6093, + "reading": 2727, + "state": "idle" + }, + "exhaust": { + "floor": 6416, + "reading": 0, + "state": "idle" + }, + "intake_1": { + "floor": 2277, + "reading": 733, + "state": "idle" + }, + "intake_2": { + "floor": 2277, + "reading": 726, + "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": "HEAD CRASH SIGNAL (axes y) - motion stopped, laser locked", + "report_age_s": 0.8, + "resume_ok": true, + "up_c": 21.91, + "verdict": "OK" + }, + { + "accel_watch": "watch", + "armed": false, + "down_c": 22.23, + "fan_gates": { + "air_assist": { + "floor": 6093, + "reading": 2751, + "state": "idle" + }, + "exhaust": { + "floor": 6416, + "reading": 0, + "state": "idle" + }, + "intake_1": { + "floor": 2277, + "reading": 732, + "state": "idle" + }, + "intake_2": { + "floor": 2277, + "reading": 731, + "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": "HEAD CRASH SIGNAL (axes y) - motion stopped, laser locked", + "report_age_s": 0.3, + "resume_ok": true, + "up_c": 22.3, + "verdict": "OK" + }, + { + "accel_watch": "watch", + "armed": false, + "down_c": 22.23, + "fan_gates": { + "air_assist": { + "floor": 6093, + "reading": 2751, + "state": "idle" + }, + "exhaust": { + "floor": 6416, + "reading": 0, + "state": "idle" + }, + "intake_1": { + "floor": 2277, + "reading": 732, + "state": "idle" + }, + "intake_2": { + "floor": 2277, + "reading": 731, + "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": "HEAD CRASH SIGNAL (axes y) - motion stopped, laser locked", + "report_age_s": 0.8, + "resume_ok": true, + "up_c": 22.3, + "verdict": "OK" + }, + { + "accel_watch": "watch", + "armed": false, + "down_c": 22.07, + "fan_gates": { + "air_assist": { + "floor": 6093, + "reading": 2756, + "state": "idle" + }, + "exhaust": { + "floor": 6416, + "reading": 0, + "state": "idle" + }, + "intake_1": { + "floor": 2277, + "reading": 733, + "state": "idle" + }, + "intake_2": { + "floor": 2277, + "reading": 732, + "state": "idle" + }, + "purge": { + "floor": 345, + "reading": 628, + "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": "HEAD CRASH SIGNAL (axes y) - motion stopped, laser locked", + "report_age_s": 0.3, + "resume_ok": true, + "up_c": 21.99, + "verdict": "OK" + }, + { + "accel_watch": "watch", + "armed": false, + "down_c": 22.07, + "fan_gates": { + "air_assist": { + "floor": 6093, + "reading": 2756, + "state": "idle" + }, + "exhaust": { + "floor": 6416, + "reading": 0, + "state": "idle" + }, + "intake_1": { + "floor": 2277, + "reading": 733, + "state": "idle" + }, + "intake_2": { + "floor": 2277, + "reading": 732, + "state": "idle" + }, + "purge": { + "floor": 345, + "reading": 628, + "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": "HEAD CRASH SIGNAL (axes y) - motion stopped, laser locked", + "report_age_s": 0.8, + "resume_ok": true, + "up_c": 21.99, + "verdict": "OK" + }, + { + "accel_watch": "watch", + "armed": false, + "down_c": 22.23, + "fan_gates": { + "air_assist": { + "floor": 6093, + "reading": 2756, + "state": "idle" + }, + "exhaust": { + "floor": 6416, + "reading": 0, + "state": "idle" + }, + "intake_1": { + "floor": 2277, + "reading": 730, + "state": "idle" + }, + "intake_2": { + "floor": 2277, + "reading": 732, + "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": "HEAD CRASH SIGNAL (axes y) - motion stopped, laser locked", + "report_age_s": 0.3, + "resume_ok": true, + "up_c": 22.15, + "verdict": "OK" + }, + { + "accel_watch": "watch", + "armed": false, + "down_c": 22.23, + "fan_gates": { + "air_assist": { + "floor": 6093, + "reading": 2756, + "state": "idle" + }, + "exhaust": { + "floor": 6416, + "reading": 0, + "state": "idle" + }, + "intake_1": { + "floor": 2277, + "reading": 730, + "state": "idle" + }, + "intake_2": { + "floor": 2277, + "reading": 732, + "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": "HEAD CRASH SIGNAL (axes y) - motion stopped, laser locked", + "report_age_s": 0.2, + "resume_ok": true, + "up_c": 22.15, + "verdict": "OK" + }, + { + "accel_watch": "watch", + "armed": false, + "down_c": 22.23, + "fan_gates": { + "air_assist": { + "floor": 6093, + "reading": 2757, + "state": "unjudged" + }, + "exhaust": { + "floor": 6416, + "reading": 0, + "state": "unjudged" + }, + "intake_1": { + "floor": 2277, + "reading": 729, + "state": "unjudged" + }, + "intake_2": { + "floor": 2277, + "reading": 731, + "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.23, + "verdict": "OK" + }, + { + "accel_watch": "watch", + "armed": false, + "down_c": 22.23, + "fan_gates": { + "air_assist": { + "floor": 6093, + "reading": 2757, + "state": "unjudged" + }, + "exhaust": { + "floor": 6416, + "reading": 0, + "state": "unjudged" + }, + "intake_1": { + "floor": 2277, + "reading": 729, + "state": "unjudged" + }, + "intake_2": { + "floor": 2277, + "reading": 731, + "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.8, + "resume_ok": true, + "up_c": 22.23, + "verdict": "OK" + }, + { + "accel_watch": "watch", + "armed": false, + "down_c": 22.07, + "fan_gates": { + "air_assist": { + "floor": 6093, + "reading": 2772, + "state": "unjudged" + }, + "exhaust": { + "floor": 6416, + "reading": 0, + "state": "unjudged" + }, + "intake_1": { + "floor": 2277, + "reading": 729, + "state": "unjudged" + }, + "intake_2": { + "floor": 2277, + "reading": 726, + "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.0, + "resume_ok": true, + "up_c": 22.15, + "verdict": "OK" + }, + { + "accel_watch": "watch", + "armed": false, + "down_c": 22.07, + "fan_gates": { + "air_assist": { + "floor": 6093, + "reading": 2772, + "state": "unjudged" + }, + "exhaust": { + "floor": 6416, + "reading": 0, + "state": "unjudged" + }, + "intake_1": { + "floor": 2277, + "reading": 729, + "state": "unjudged" + }, + "intake_2": { + "floor": 2277, + "reading": 726, + "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.5, + "resume_ok": true, + "up_c": 22.15, + "verdict": "OK" + }, + { + "accel_watch": "watch", + "armed": false, + "down_c": 23.08, + "fan_gates": { + "air_assist": { + "floor": 6093, + "reading": 2456, + "state": "idle" + }, + "exhaust": { + "floor": 6416, + "reading": 0, + "state": "idle" + }, + "intake_1": { + "floor": 2277, + "reading": 733, + "state": "idle" + }, + "intake_2": { + "floor": 2277, + "reading": 727, + "state": "idle" + }, + "purge": { + "floor": 345, + "reading": 631, + "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.3, + "resume_ok": true, + "up_c": 23.24, + "verdict": "OK" + } + ], + "hunt_line": "INFO basemachine:_finish_action hunt [1596426040]: 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": 3187, + "why": "" + }, + "mode_before": { + "controller": "running", + "gated": false, + "local": false, + "mode": "grbl", + "motion": "verified", + "pid": 2296, + "why": "" + }, + "mode_cloud": { + "controller": "running", + "gated": false, + "local": false, + "mode": "cloud", + "motion": "verified", + "pid": 2914, + "why": "" + }, + "motions_after_lid_close": 3, + "refusals_before_hunt_end": 0, + "return": { + "counters_across_jog": [ + [ + 0, + 0, + 0 + ], + [ + 4972, + -2760, + 0 + ] + ], + "counters_since_home": [ + 0, + 0, + 0 + ], + "mm": [ + -23.306, + 12.938 + ], + "session_travel_steps": [ + -1243, + 690 + ] + }, + "session": [ + "2026-10-18T22:58:54.351478+00:00 gfcloud[2914] INFO authentication:authenticate_machine SUCCESS", + "2026-10-18T22:58:55.458830+00:00 gfcloud[2914] INFO websocket:ws_connect ESTABLISHED" + ], + "short_motions": [] + }, + "fingerprint": "57d696cefbd3cf910340f2e2a081767d659081c72d829e6de2b1f9bad8c25df3", + "image": "20261018222431 (dev)", + "log": [ + "22:58:50 start cloud.mode-switch (operator, api) in campaign c-20261018224638-4ca0", + "22:58:51 fixture up: at , v1.0.0, covers lid, interlock, button", + "22:58:51 fixture: at covers lid, interlock, button", + "22:58:51 fixture: running unattended (no prompt can be answered)", + "22:58:51 queued by the unattended queue opened 2026-10-18T22:46:38Z", + "22:58:51 baseline: pre: clean", + "22:58:51 mode: test needs grbl - already in grbl mode", + "22:58:51 mode before: {'mode': 'grbl', 'controller': 'running', 'pid': 2296, 'motion': 'verified', 'gated': False, 'local': False, 'why': ''}", + "22:58:55 POST /mode controller=cloud -> 200 {'mode': 'cloud', 'controller': 'running', 'pid': 2914, 'motion': 'verified', 'gated': False, 'local': False, 'why': ''}", + "22:58:55 mode after switch: {'mode': 'cloud', 'controller': 'running', 'pid': 2914, 'motion': 'verified', 'gated': False, 'local': False, 'why': ''}", + "22:58:55 ACT lid open (fixture)", + "22:58:55 ACT lid open: done after 0.0 s", + "22:58:57 gfcloud: gfcloud[2914] INFO authentication:authenticate_machine SUCCESS", + "22:58:57 gfcloud: gfcloud[2914] INFO websocket:ws_connect ESTABLISHED", + "22:58:57 cloud session established: True; firmware probe: {'latest_gf_version': '2.6.0-2228', 'tested_against_gf': '2.6.0-2228', 'checked_at': 1792364334}", + "22:59:05 hunt: 17 status samples, 4 in phase run; verdicts ['OK']", + "22:59:05 hunt with the lid open: INFO basemachine:_finish_action hunt [1596426040]: finished with event \":completed\" (lens homed)", + "22:59:05 ACT lid close (fixture)", + "22:59:06 ACT lid close: done after 0.3 s", + "22:59:21 fixture up: at , v1.0.0, covers lid, interlock, button", + "22:59:52 fixture up: at , v1.0.0, covers lid, interlock, button", + "23:00:01 cloud mode stays up; the machine is quiet", + "23:00:01 3 service motion(s) completed after the lid closed", + "23:00:02 POST /mode controller=grbl -> 200 {'mode': 'grbl', 'controller': 'running', 'pid': 3187, 'motion': 'verified', 'gated': False, 'local': False, 'why': ''}", + "23:00:02 mode after switch back: {'mode': 'grbl', 'controller': 'running', 'pid': 3187, 'motion': 'verified', 'gated': False, 'local': False, 'why': ''}", + "23:00:05 grbl state after: Idle", + "23:00:05 the head is -23.306/12.938 mm from where the test found it", + "23:00:06 connect: Idle", + "23:00:08 position counters re-zeroed at the starting position; the baseline expects (0,0,0) at the end", + "23:00:08 head returned to where the test found it (23.306/-12.938 mm)", + "23:00:08 homing_mode=gfcloud for the homing -> 200 ", + "23:00:23 fixture up: at , v1.0.0, covers lid, interlock, button", + "23:00:53 fixture up: at , v1.0.0, covers lid, interlock, button", + "23:00:54 homing: homed=True after 45.7 s (kernel idle, grbl Idle)", + "23:00:54 gfhome: 2026-10-18T23:00:46.816658+00:00 gfhome[3218] INFO gfhome:home homing complete (service quiet 10s, 9 motion windows)", + "23:00:54 position counters re-zeroed at the starting position; the baseline expects (0,0,0) at the end", + "23:00:55 $H acknowledged: [MSG:] | ok", + "23:00:55 restore homing_mode='manual' -> 200", + "23:00:56 the head is -23.306/12.938 mm from where the test found it", + "23:00:56 connect: Idle", + "23:00:59 position counters re-zeroed at the starting position; the baseline expects (0,0,0) at the end", + "23:00:59 head returned to where the test found it (23.306/-12.938 mm)", + "23:00:59 PASS: grbl -> cloud (session, hunt with the lid open, lens homed, airflow unjudged) -> grbl (port open, Idle), then $H homed in 45.7 s", + "23:00:59 baseline: post: clean", + "23:00:59 result PASS" + ], + "manifest_sha": "70ecd7867c2698d17f2f3c38db772868eda3364f541242c93fb5db4e1d593bcd", + "message": "", + "result": "PASS", + "test": "cloud.mode-switch", + "ts": "2026-10-18T23:00:59Z" + }, + "requires": [ + "forgectrl.auth", + "motion.pacing" + ], + "satisfied": true, + "source_sha": "e50ce19c9ca31acb3606b76442ad939634b42ae85e1a7bbbf9979465934affef", + "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": "8dcf22e87ec0464d7855eb9564c9258cabc8da11c3e58e51729d58a9c3fd8dd9", + "hardware": "api", + "id": "cloud.service-protocol", + "inherited": false, + "kind": "operator", + "record": { + "answers": [ + { + "answer": "Yes", + "question": "Does the app show the print complete?", + "ts": "2026-10-18T23:14:54Z" + } + ], + "campaign": "c-20261018224638-4ca0", + "duration_s": 72, + "evidence": { + "baseline": { + "post": [], + "pre": [] + }, + "batch": { + "group": "attended", + "ts": "2026-10-18T23:07:24Z" + }, + "downloads": [ + "2026-10-18_231423_hunt.info", + "2026-10-18_231428_motion.info", + "2026-10-18_231438_motion.info", + "2026-10-18_231442_motion.info", + "2026-10-18_231445_print.info" + ], + "fixture": { + "channels": [ + "lid", + "interlock", + "button" + ], + "hostname": "", + "ip": "", + "released": [] + }, + "header_stfr": 10000, + "header_tags": 134, + "hunt": "INFO basemachine:_finish_action hunt [1596430472]: finished with event \":completed\"", + "images_uploaded": 3, + "print": "INFO basemachine:_finish_action print [1596430581]: finished with event \":completed\"", + "pulse": "INFO websocket:fetch_motion pulse data is gzip-compressed, 405 byte body" + }, + "fingerprint": "8dcf22e87ec0464d7855eb9564c9258cabc8da11c3e58e51729d58a9c3fd8dd9", + "image": "20261018222431 (dev)", + "log": [ + "23:14:18 start cloud.service-protocol (operator, api) in campaign c-20261018224638-4ca0", + "23:14:18 fixture up: at , v1.0.0, covers lid, interlock, button", + "23:14:18 fixture: at covers lid, interlock, button", + "23:14:18 queued by the attended queue opened 2026-10-18T23:07:24Z", + "23:14:18 baseline: pre: clean", + "23:14:18 grbl mode: switching to cloud as the emulator", + "23:14:21 controller mode changed to cloud for the operator; the baseline keeps it", + "23:14:24 emulator session established: gfcloud[6818] INFO authentication:authenticate_machine SUCCESS; gfcloud[6818] INFO websocket:ws_connect ESTABLISHED", + "23:14:26 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.", + "23:14:46 print: INFO basemachine:_finish_action print [1596430581]: finished with event \":completed\"; 3 images uploaded; INFO websocket:fetch_motion pulse data is gzip-compressed, 405 byte body", + "23:14:46 the job's header: 134 tags, STfr 10000", + "23:14:46 PROMPT: Does the app show the print complete?", + "23:14:49 fixture up: at , v1.0.0, covers lid, interlock, button", + "23:14:54 ANSWER: Yes", + "23:14:54 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", + "23:14:54 cloud mode: restarting the client with the machine, no hunt (was pid 6818)", + "23:15:20 fixture up: at , v1.0.0, covers lid, interlock, button", + "23:15:30 the machine is back under the real client, no hunt", + "23:15:30 baseline: post: clean", + "23:15:30 result PASS" + ], + "manifest_sha": "70ecd7867c2698d17f2f3c38db772868eda3364f541242c93fb5db4e1d593bcd", + "message": "", + "result": "PASS", + "test": "cloud.service-protocol", + "ts": "2026-10-18T23:15:30Z" + }, + "requires": [ + "forgectrl.auth" + ], + "satisfied": true, + "source_sha": "4eb22732bab44127c93af962265ba7a6b1dfe1fb196a001edd89c45590b1f291", + "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": "bfbed8e9460c45df9870d1433d1467ff54980dc79d383eeb68178fc2d0f65fd3", + "hardware": "api", + "id": "cloud.lid-interlock-abort", + "inherited": false, + "kind": "live", + "record": { + "answers": [], + "campaign": "c-20261018224638-4ca0", + "duration_s": 136, + "evidence": { + "actions": [ + { + "by": "fixture", + "channel": "button", + "state": "press", + "took_s": 6.76, + "ts": "2026-10-18T23:16:06Z" + }, + { + "by": "fixture", + "channel": "lid", + "state": "open", + "took_s": 0.02, + "ts": "2026-10-18T23:16:13Z" + }, + { + "by": "fixture", + "channel": "lid", + "state": "close", + "took_s": 0.28, + "ts": "2026-10-18T23:16:25Z" + }, + { + "by": "fixture", + "channel": "button", + "state": "press", + "took_s": 6.01, + "ts": "2026-10-18T23:16:57Z" + }, + { + "by": "fixture", + "channel": "interlock", + "state": "open", + "took_s": 0.02, + "ts": "2026-10-18T23:17:03Z" + }, + { + "by": "fixture", + "channel": "lid", + "state": "open", + "took_s": 0.02, + "ts": "2026-10-18T23:17:04Z" + }, + { + "by": "fixture", + "channel": "lid", + "state": "close", + "took_s": 0.28, + "ts": "2026-10-18T23:17:15Z" + }, + { + "by": "fixture", + "channel": "interlock", + "state": "close", + "took_s": 0.28, + "ts": "2026-10-18T23:17:16Z" + } + ], + "baseline": { + "post": [], + "pre": [] + }, + "batch": { + "group": "attended", + "ts": "2026-10-18T23:07:24Z" + }, + "edge_to_stop_ms": 3.9, + "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": "", + "ip": "", + "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-10-18T23:15:31Z" + }, + "restored": { + "interlock_ok": true, + "lid": true + }, + "switches_at_return": { + "interlock_ok": false, + "lid": false + } + }, + "fingerprint": "bfbed8e9460c45df9870d1433d1467ff54980dc79d383eeb68178fc2d0f65fd3", + "image": "20261018222431 (dev)", + "log": [ + "23:15:30 start cloud.lid-interlock-abort (live, api) in campaign c-20261018224638-4ca0", + "23:15:31 fixture up: at , v1.0.0, covers lid, interlock, button", + "23:15:31 fixture: at covers lid, interlock, button", + "23:15:31 queued by the attended queue opened 2026-10-18T23:07:24Z", + "23:15:31 baseline: pre: clean", + "23:15:31 cloud mode: restarting the client offline (was pid 6878)", + "23:15:35 offline service up: INFO offline:open OFFLINE service: no web session; listening on /run/gfcloud-offline.sock", + "23:16:02 fixture up: at , v1.0.0, covers lid, interlock, button", + "23:16:05 job abort.puls: 486344 payload bytes, 49 s at STfr 10000", + "23:16:06 ACT button press (fixture)", + "23:16:13 ACT button press: done after 6.8 s", + "23:16:13 ACT lid open (fixture)", + "23:16:13 ACT lid open: done after 0.0 s", + "23:16:25 [lid] lid opened: seen", + "23:16:25 [lid] lid opened mid-run; stopping motion: seen", + "23:16:25 [lid] start return home: seen", + "23:16:25 [lid] return home complete: seen", + "23:16:25 [lid] print finished: seen", + "23:16:25 lid edge -> stop: 3.9 ms", + "23:16:25 [lid] kernel counters after the park: [0, 0, 0]", + "23:16:25 ACT lid close (fixture)", + "23:16:25 ACT lid close: done after 0.3 s", + "23:16:32 fixture up: at , v1.0.0, covers lid, interlock, button", + "23:16:55 cloud mode stays up; the machine is quiet", + "23:16:57 ACT button press (fixture)", + "23:17:03 ACT button press: done after 6.0 s", + "23:17:03 ACT interlock open (fixture)", + "23:17:03 ACT interlock open: done after 0.0 s", + "23:17:03 fixture up: at , v1.0.0, covers lid, interlock, button", + "23:17:04 ACT lid open (fixture)", + "23:17:04 ACT lid open: done after 0.0 s", + "23:17:15 [interlock] interlock opened mid-run; stopping motion: seen", + "23:17:15 [interlock] start return home: seen", + "23:17:15 [interlock] return home complete: seen", + "23:17:15 [interlock] print finished: seen", + "23:17:15 [interlock] kernel counters after the park: [0, 0, 0]", + "23:17:15 ACT lid close (fixture)", + "23:17:16 ACT lid close: done after 0.3 s", + "23:17:16 ACT interlock close (fixture)", + "23:17:16 ACT interlock close: done after 0.3 s", + "23:17:34 fixture up: at , v1.0.0, covers lid, interlock, button", + "23:17:46 cloud mode stays up; the machine is quiet", + "23:17:46 PASS: lid open -> stop in 3.9 ms and park with the lid open; interlock open -> the same tail with the park running through a lid edge; both prints ':cancelled'", + "23:17:46 offline jobs removed from /tmp/forgetest", + "23:17:46 baseline: post: clean", + "23:17:46 result PASS" + ], + "manifest_sha": "70ecd7867c2698d17f2f3c38db772868eda3364f541242c93fb5db4e1d593bcd", + "message": "", + "result": "PASS", + "test": "cloud.lid-interlock-abort", + "ts": "2026-10-18T23:17:46Z" + }, + "requires": [ + "laser.emission-witness" + ], + "satisfied": true, + "source_sha": "2f3c281371954a1ee27f2bd685eb0ae60e3624504b39a5144187bad09e040577", + "subsystem": "cloud", + "title": "Lid and interlock each abort a cloud print; the park ignores an open lid" + }, + { + "always": false, + "covers": [ + [ + "forgefirm-app", + "**" + ], + [ + "python3-gfhardware", + "**" + ], + [ + "python3-gfutilities", + "**" + ], + [ + "forgectrl", + "src/super.c" + ], + [ + "forgectrl", + "src/main.c" + ] + ], + "fingerprint": "95d0ec7cf1b53894034e37c235da36d4e8ab2871b72314e0326eeee1fb2a914f", + "hardware": "api", + "id": "cloud.pause-resume", + "inherited": false, + "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-10-18T23:20:00Z" + }, + { + "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-10-18T23:20:52Z" + } + ], + "campaign": "c-20261018224638-4ca0", + "duration_s": 220, + "evidence": { + "actions": [ + { + "by": "fixture", + "channel": "button", + "state": "press", + "took_s": 1.26, + "ts": "2026-10-18T23:20:26Z" + }, + { + "by": "fixture", + "channel": "button", + "state": "press", + "took_s": 1.01, + "ts": "2026-10-18T23:20:27Z" + } + ], + "armed_after_resume": true, + "baseline": { + "post": [], + "pre": [] + }, + "batch": { + "group": "attended", + "ts": "2026-10-18T23:07:24Z" + }, + "effective_limits": [ + "2026-10-18T23:20:10.759816+00:00 forgectrl[4205] 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-10-18T23:20:11.759797+00:00 forgectrl[4205] 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": "", + "ip": "", + "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-10-18T23:20:33.910586+00:00 gfcloud[7385] INFO machine:_dwell cool down: holding 10.0 s", + "warm up": "2026-10-18T23:20:22.060266+00:00 gfcloud[7385] 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 [1596432120]: finished with event \":completed\"", + "return home complete": true + }, + "operator": { + "ack_live": true, + "ts": "2026-10-18T23:17:47Z" + }, + "progress_total": 41240, + "relock_or_cancel_lines": 0 + }, + "fingerprint": "95d0ec7cf1b53894034e37c235da36d4e8ab2871b72314e0326eeee1fb2a914f", + "image": "20261018222431 (dev)", + "log": [ + "23:17:46 start cloud.pause-resume (live, api) in campaign c-20261018224638-4ca0", + "23:17:47 fixture up: at , v1.0.0, covers lid, interlock, button", + "23:17:47 fixture: at covers lid, interlock, button", + "23:17:47 queued by the attended queue opened 2026-10-18T23:07:24Z", + "23:17:47 baseline: pre: clean", + "23:17:47 the running client is the offline service: restarting it with the service", + "23:17:47 cloud mode: restarting the cloud client for a fresh connect (was pid 7004)", + "23:17:53 cloud session established (pid 7385)", + "23:18:04 connect-time hunt: INFO basemachine:_finish_action hunt [1596431443]: finished with event \":completed\"", + "23:18:17 fixture up: at , v1.0.0, covers lid, interlock, button", + "23:18:49 fixture up: at , v1.0.0, covers lid, interlock, button", + "23:19:21 fixture up: at , v1.0.0, covers lid, interlock, button", + "23:19:51 fixture up: at , v1.0.0, covers lid, interlock, button", + "23:19:53 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.", + "23:20:00 ANSWER: Done", + "23:20:22 fixture up: at , v1.0.0, covers lid, interlock, button", + "23:20:26 ACT button press (fixture)", + "23:20:27 ACT button press: done after 1.3 s", + "23:20:27 ACT button press (fixture)", + "23:20:28 ACT button press: done after 1.0 s", + "23:20:28 armed after the resume: True", + "23:20:45 warm-up: 2026-10-18T23:20:22.060266+00:00 gfcloud[7385] INFO machine:_dwell warm up: holding 3.0 s", + "23:20:45 rest: 2026-10-18T23:20:33.910586+00:00 gfcloud[7385] INFO machine:_dwell cool down: holding 10.0 s", + "23:20:45 progress reported against 41240 bytes", + "23:20:45 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?", + "23:20:52 ANSWER: Yes", + "23:20:52 job limits from the header (the print's): air_assist_min_rpm=116 coolant_max_c=33.0 coolant_min_c=5.0", + "23:20:52 engine effective limits: 2026-10-18T23:20:10.759816+00:00 forgectrl[4205] 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", + "23:20:53 fixture up: at , v1.0.0, covers lid, interlock, button", + "23:21:25 fixture up: at , v1.0.0, covers lid, interlock, button", + "23:21:26 cloud mode stays up; the machine is quiet", + "23:21:26 PASS: button pause/resume mid-print, warm-up and rest observed, progress reported, the job's limits passed through, job completed and parked", + "23:21:27 baseline: post: clean", + "23:21:27 result PASS" + ], + "manifest_sha": "70ecd7867c2698d17f2f3c38db772868eda3364f541242c93fb5db4e1d593bcd", + "message": "", + "result": "PASS", + "test": "cloud.pause-resume", + "ts": "2026-10-18T23:21:27Z" + }, + "requires": [ + "laser.emission-witness" + ], + "satisfied": true, + "source_sha": "575e176f9dcc353fa31dd950129d19de07a9af3e8db3d2a42600802f05f5edd0", + "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": "05ea8ebf09927b7f81ae201e21ad5f24de1fc37f21c973285361b92d2e526c07", + "hardware": "api", + "id": "cloud.oversize-stream", + "inherited": false, + "kind": "live", + "record": { + "answers": [], + "campaign": "c-20261018224638-4ca0", + "duration_s": 211, + "evidence": { + "actions": [ + { + "by": "fixture", + "channel": "button", + "state": "press", + "took_s": 6.03, + "ts": "2026-10-18T23:22:06Z" + }, + { + "by": "fixture", + "channel": "button", + "state": "press", + "took_s": 1.26, + "ts": "2026-10-18T23:24:13Z" + }, + { + "by": "fixture", + "channel": "button", + "state": "press", + "took_s": 1.26, + "ts": "2026-10-18T23:24:14Z" + } + ], + "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-10-18T23:07:24Z" + }, + "button_dark": false, + "events": [ + "print:starting", + "print:download:completed", + "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": "", + "ip": "", + "released": [] + }, + "jobs": { + "long.puls": { + "compressed": true, + "payload_bytes": 35015348, + "seconds": 3501.5 + } + }, + "log": { + "job is longer than the ring": true + }, + "max_backtrack": 168023, + "operator": { + "ack_live": true, + "ts": "2026-10-18T23:21:27Z" + }, + "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": 2, + "underruns_during": 2 + }, + "fingerprint": "05ea8ebf09927b7f81ae201e21ad5f24de1fc37f21c973285361b92d2e526c07", + "image": "20261018222431 (dev)", + "log": [ + "23:21:27 start cloud.oversize-stream (live, api) in campaign c-20261018224638-4ca0", + "23:21:27 fixture up: at , v1.0.0, covers lid, interlock, button", + "23:21:27 fixture: at covers lid, interlock, button", + "23:21:27 queued by the attended queue opened 2026-10-18T23:07:24Z", + "23:21:27 baseline: pre: clean", + "23:21:27 cloud mode: restarting the client offline (was pid 7385)", + "23:21:32 offline service up: INFO offline:open OFFLINE service: no web session; listening on /run/gfcloud-offline.sock", + "23:21:58 fixture up: at , v1.0.0, covers lid, interlock, button", + "23:22:04 job long.puls: 35015348 payload bytes, 3502 s at STfr 10000 (gzip)", + "23:22:06 ACT button press (fixture)", + "23:22:13 ACT button press: done after 6.0 s", + "23:22:13 program total at the start of the run: 33292288 bytes", + "23:22:13 NOTICE: Cutting: the test watches the ring being topped up for two minutes. Do nothing yet.", + "23:22:29 fixture up: at , v1.0.0, covers lid, interlock, button", + "23:23:00 fixture up: at , v1.0.0, covers lid, interlock, button", + "23:23:31 fixture up: at , v1.0.0, covers lid, interlock, button", + "23:24:02 fixture up: at , v1.0.0, covers lid, interlock, button", + "23:24:13 program total two minutes in: 34603008 bytes (+1310720)", + "23:24:13 progress reported against 35015348 bytes, kernel program total 34603008", + "23:24:13 max_backtrack while the feed runs: 168023 steps", + "23:24:13 ACT button press (fixture)", + "23:24:14 ACT button press: done after 1.3 s", + "23:24:14 ACT button press (fixture)", + "23:24:15 ACT button press: done after 1.3 s", + "23:24:15 canceled the print as the app would", + "23:24:28 [cancel] action canceled mid-run; stopping motion: seen", + "23:24:28 [cancel] start return home: seen", + "23:24:28 [cancel] return home complete: seen", + "23:24:28 [app] kernel counters after the park: [0, 0, 0]", + "23:24:32 fixture up: at , v1.0.0, covers lid, interlock, button", + "23:24:58 cloud mode stays up; the machine is quiet", + "23:24:58 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'", + "23:24:58 offline jobs removed from /tmp/forgetest", + "23:24:58 baseline: post: clean", + "23:24:58 result PASS" + ], + "manifest_sha": "70ecd7867c2698d17f2f3c38db772868eda3364f541242c93fb5db4e1d593bcd", + "message": "", + "result": "PASS", + "test": "cloud.oversize-stream", + "ts": "2026-10-18T23:24:58Z" + }, + "requires": [ + "cloud.lid-interlock-abort", + "cloud.pause-resume" + ], + "satisfied": true, + "source_sha": "25856148e06569b9101ac94b8a8040ccdc0c1f2de47c7331911dad96257136b0", + "subsystem": "cloud", + "title": "A print longer than the ring is fed while it plays" + }, + { + "always": false, + "covers": [ + [ + "linux-fslc", + "**" + ] + ], + "fingerprint": "f5e27183c3b5da698a6b01f699458378cbc9b36919e96069c390d60d6a3f9fd7", + "hardware": "api", + "id": "exthost.platform", + "inherited": false, + "kind": "auto", + "record": { + "answers": [], + "campaign": "c-20261018224638-4ca0", + "duration_s": 22, + "evidence": { + "allowlisted_self": [ + [ + [ + 4, + "127.0.0.1", + 443, + false + ], + [ + "refused", + 0.0 + ] + ], + [ + [ + 4, + "", + 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, + "", + 443, + false + ], + [ + "refused", + 0.0 + ] + ], + [ + [ + 4, + "", + 23, + false + ], + [ + "refused", + 0.0 + ] + ], + [ + [ + 4, + "127.0.0.1", + 9, + true + ], + [ + "eperm", + 0.0 + ] + ], + [ + [ + 4, + "", + 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, + "", + 443, + false + ], + [ + "refused", + 0.0 + ] + ], + [ + [ + 4, + "", + 23, + false + ], + [ + "refused", + 0.0 + ] + ], + [ + [ + 4, + "127.0.0.1", + 9, + true + ], + [ + "eperm", + 0.0 + ] + ], + [ + [ + 4, + "", + 9, + true + ], + [ + "eperm", + 0.0 + ] + ] + ] + }, + "as_root": [ + [ + [ + 4, + "127.0.0.1", + 443, + false + ], + [ + "ok", + 0.0 + ] + ], + [ + [ + 4, + "", + 443, + false + ], + [ + "ok", + 0.0 + ] + ], + [ + [ + 4, + "127.0.0.1", + 9, + true + ], + [ + "ok", + 0.0 + ] + ] + ], + "baseline": { + "post": [], + "pre": [] + }, + "batch": { + "group": "unattended", + "ts": "2026-10-18T22:46:38Z" + }, + "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.0508, + "thawed_us": 83975, + "throttled": 40 + }, + "firmware_groups": { + "forgectrl/1809": "0::/", + "grblHAL_glowfor/3380": "0::/" + }, + "fixture": { + "channels": [ + "lid", + "interlock", + "button" + ], + "hostname": "", + "ip": "", + "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": "f5e27183c3b5da698a6b01f699458378cbc9b36919e96069c390d60d6a3f9fd7", + "image": "20261018222431 (dev)", + "log": [ + "23:00:59 start exthost.platform (auto, api) in campaign c-20261018224638-4ca0", + "23:00:59 fixture up: at , v1.0.0, covers lid, interlock, button", + "23:00:59 fixture: at covers lid, interlock, button", + "23:00:59 queued by the unattended queue opened 2026-10-18T22:46:38Z", + "23:00:59 baseline: pre: clean", + "23:01:00 cgroup tree: {'controllers': ['cpu', 'memory', 'pids'], 'root_subtree': ['cpu', 'memory', 'pids'], 'ffx_subtree': ['cpu', 'memory', 'pids'], 'ffx_cpu_idle': '1'}", + "23:01:04 a spinning probe under cpu.max 5%: 5.1% of the core, throttled 40 times", + "23:01:08 frozen for 1.5 s the probe ran 0 us; thawed for 1.5 s it ran 83975 us", + "23:01:09 pids.max 6: the fork loop made 5 of 12, stopped by EAGAIN; pids.events max 1", + "23:01:18 memory.max 24 MiB against a 96 MiB appetite: rc -9, oom_kill 1, peak 25165824", + "23:01:20 two pool uids: 6 TCP connects each refused at once, 2 UDP sends each EPERM; the rules counted [0, 0] -> [12, 4]", + "23:01:20 uid 831 with the machine's own addresses on its allowlist: [[[4, '127.0.0.1', 443, False], ['refused', 0.0]], [[4, '', 443, False], ['refused', 0.0]]]", + "23:01:21 landlock ABI 6: before {'etc': 'ok', 'usr': 'ok', 'tcp': 'ok'}, after {'ruleset': True, 'added': 0, 'applied': 0, 'tcp': 'eacces', 'etc': 'eacces', 'usr': 'ok'}", + "23:01:21 seccomp: {'installed': 0, 'before': 'Linux', 'after': 'eperm', 'status': ['2']}", + "23:01:21 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", + "23:01:21 baseline: post: clean", + "23:01:21 result PASS" + ], + "manifest_sha": "70ecd7867c2698d17f2f3c38db772868eda3364f541242c93fb5db4e1d593bcd", + "message": "", + "result": "PASS", + "test": "exthost.platform", + "ts": "2026-10-18T23:01:21Z" + }, + "requires": [], + "satisfied": true, + "source_sha": "5780699f9a9c712ac520f3301e379107ed037aceabc1eb365c4a3f46f2451713", + "subsystem": "exthost", + "title": "The extension sandbox platform holds a process" + }, + { + "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": "c01584bb2409f0f4c0cc4eaf356740e6bee2f77b9e7ce13f3ab69548af74f17c", + "hardware": "takeover", + "id": "exthost.armed-freeze", + "inherited": false, + "kind": "operator", + "record": { + "answers": [], + "campaign": "c-20261018224638-4ca0", + "duration_s": 108, + "evidence": { + "actions": [ + { + "by": "fixture", + "channel": "button", + "state": "press", + "took_s": 6.02, + "ts": "2026-10-18T23:02:02Z" + } + ], + "armed_after": false, + "baseline": { + "post": [], + "pre": [] + }, + "batch": { + "group": "unattended", + "ts": "2026-10-18T22:46:38Z" + }, + "camera_after_window": { + "bytes": 298956, + "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": "", + "ip": "", + "released": [] + }, + "freeze_lag_s": 0.42, + "freeze_led_the_run_s": 5.4, + "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": 271, + "inside": 174, + "not_frozen_inside": 0 + }, + "thaw_lag_s": 0.21, + "window_s": 38.1 + }, + "fingerprint": "c01584bb2409f0f4c0cc4eaf356740e6bee2f77b9e7ce13f3ab69548af74f17c", + "image": "20261018222431 (dev)", + "log": [ + "23:01:21 start exthost.armed-freeze (operator, takeover) in campaign c-20261018224638-4ca0", + "23:01:22 fixture up: at , v1.0.0, covers lid, interlock, button", + "23:01:22 fixture: at covers lid, interlock, button", + "23:01:22 fixture: running unattended (no prompt can be answered)", + "23:01:22 queued by the unattended queue opened 2026-10-18T22:46:38Z", + "23:01:22 baseline: pre: clean", + "23:01:27 grbl mode: switching to cloud offline", + "23:01:29 controller mode changed to cloud for the operator; the baseline keeps it", + "23:01:30 offline service up: INFO offline:open OFFLINE service: no web session; listening on /run/gfcloud-offline.sock", + "23:01:53 fixture up: at , v1.0.0, covers lid, interlock, button", + "23:02:00 job dark.puls: 324236 payload bytes, 32 s at STfr 10000", + "23:02:02 ACT button press (fixture)", + "23:02:08 ACT button press: done after 6.0 s", + "23:02:23 fixture up: at , v1.0.0, covers lid, interlock, button", + "23:02:51 PASS: locked at the button, unlocked for the run, locked after it; the print completed", + "23:02:54 fixture up: at , v1.0.0, covers lid, interlock, button", + "23:02:57 offline jobs removed from /tmp/forgetest", + "23:02:58 a background capture inside the window -> 409 (a job is armed: a background capture waits until the window closes); after it -> 200, 298956 bytes", + "23:02:58 the armed window was open 38.1 s; frozen 0.42 s after it opened and 5.40 s before the latch unlocked for the run, in every one of 174 samples from 2 s in to the close, the heartbeat still; thawed 0.21 s after the close", + "23:02:58 remove org.forgetest.reference -> ok", + "23:02:58 restore ext_enabled='0' -> 200", + "23:02:58 takeover: waiting for forgectrl to be settled", + "23:02:58 baseline: /mode controller=running motion=verified", + "23:02:58 takeover: preserving cnc/motor_lock=8, cnc/step_freq=10000, cnc/ramp_rate=500000, 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", + "23:02:58 takeover: the cloud client is the offline service (pid 3535); forgectrl's start brings it back offline", + "23:02:58 takeover: stopping the controller through forgectrl", + "23:02:59 takeover: POST /controller/stop -> 200", + "23:02:59 takeover: forgectrl stop -> rc 0", + "23:03:01 takeover: pulse device free", + "23:03:01 takeover: forgectrl start -> rc 0", + "23:03:03 baseline: /mode controller=stopped motion=unverified", + "23:03:07 baseline: /mode controller=running motion=verified", + "23:03:09 takeover: the cloud client is back as the offline service (pid 4232)", + "23:03:09 the previous record is back under a restart", + "23:03:09 baseline: post: clean", + "23:03:09 result PASS" + ], + "manifest_sha": "70ecd7867c2698d17f2f3c38db772868eda3364f541242c93fb5db4e1d593bcd", + "message": "", + "result": "PASS", + "test": "exthost.armed-freeze", + "ts": "2026-10-18T23:03:09Z" + }, + "requires": [ + "exthost.platform" + ], + "satisfied": true, + "source_sha": "7cb2ac9b31d03ebcb894a3c167caba73f497d18b563c4688bf62dcefe00bd017", + "subsystem": "exthost", + "title": "A package's service is frozen for the armed window" + }, + { + "always": false, + "covers": [ + [ + "forgectrl", + "src/tls.*" + ], + [ + "forgectrl", + "src/main.c" + ] + ], + "fingerprint": "8a4b069ca0cabd9b75e9d936c4ca23e0b307e5ebd9b0bf50e658ae30a17f2716", + "hardware": "api", + "id": "forgectrl.tls-records", + "inherited": false, + "kind": "auto", + "record": { + "answers": [], + "campaign": "c-20261018224638-4ca0", + "duration_s": 5, + "evidence": { + "baseline": { + "post": [], + "pre": [] + }, + "batch": { + "group": "unattended", + "ts": "2026-10-18T22:46:38Z" + }, + "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": "", + "ip": "", + "released": [] + }, + "page_bytes": 565725, + "runs": { + "aes-1.2#1": { + "attempts": 2, + "bytes": 565725, + "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": 2, + "bytes": 565725, + "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": 1, + "bytes": 565725, + "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": 3, + "bytes": 565725, + "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": 565725, + "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": 2, + "bytes": 565725, + "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": 1, + "bytes": 565725, + "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": 565725, + "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": 565725, + "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": "8a4b069ca0cabd9b75e9d936c4ca23e0b307e5ebd9b0bf50e658ae30a17f2716", + "image": "20261018222431 (dev)", + "log": [ + "23:03:09 start forgectrl.tls-records (auto, api) in campaign c-20261018224638-4ca0", + "23:03:10 fixture up: at , v1.0.0, covers lid, interlock, button", + "23:03:10 fixture: at covers lid, interlock, button", + "23:03:10 queued by the unattended queue opened 2026-10-18T22:46:38Z", + "23:03:10 baseline: pre: clean", + "23:03:10 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, 565725 bytes, same True, tls_stat {'TlsTxSw': 1, 'TlsRxSw': 1, 'TlsDecryptError': 0}, 2101000.jr +0", + "23:03:10 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, 565725 bytes, same True, tls_stat {'TlsTxSw': 1, 'TlsRxSw': 1, 'TlsDecryptError': 0}, 2101000.jr +0", + "23:03:10 aes-1.3#1: 1 other connection(s) during the window; measured again", + "23:03:11 aes-1.3#1: 1 other connection(s) during the window; measured again", + "23:03:12 aes-1.3#1: offer TLS_AES_128_GCM_SHA256 -> TLS_AES_128_GCM_SHA256, HTTP/1.1 200 OK, 565725 bytes, same True, tls_stat {'TlsTxSw': 1, 'TlsRxSw': 1, 'TlsDecryptError': 0}, 2101000.jr +38", + "23:03:12 aes-1.2#1: 1 other connection(s) during the window; measured again", + "23:03:13 aes-1.2#1: offer ECDHE-ECDSA-AES128-GCM-SHA256 -> ECDHE-ECDSA-AES128-GCM-SHA256, HTTP/1.1 200 OK, 565725 bytes, same True, tls_stat {'TlsTxSw': 1, 'TlsRxSw': 1, 'TlsDecryptError': 0}, 2101000.jr +38", + "23:03:13 aes-1.3#2: offer TLS_AES_128_GCM_SHA256 -> TLS_AES_128_GCM_SHA256, HTTP/1.1 200 OK, 565725 bytes, same True, tls_stat {'TlsTxSw': 1, 'TlsRxSw': 1, 'TlsDecryptError': 0}, 2101000.jr +38", + "23:03:13 aes-1.2#2: 1 other connection(s) during the window; measured again", + "23:03:14 aes-1.2#2: offer ECDHE-ECDSA-AES128-GCM-SHA256 -> ECDHE-ECDSA-AES128-GCM-SHA256, HTTP/1.1 200 OK, 565725 bytes, same True, tls_stat {'TlsTxSw': 1, 'TlsRxSw': 1, 'TlsDecryptError': 0}, 2101000.jr +38", + "23:03:14 aes-1.3#3: 1 other connection(s) during the window; measured again", + "23:03:15 aes-1.3#3: offer TLS_AES_128_GCM_SHA256 -> TLS_AES_128_GCM_SHA256, HTTP/1.1 200 OK, 565725 bytes, same True, tls_stat {'TlsTxSw': 1, 'TlsRxSw': 1, 'TlsDecryptError': 0}, 2101000.jr +38", + "23:03:15 aes-1.2#3: offer ECDHE-ECDSA-AES128-GCM-SHA256 -> ECDHE-ECDSA-AES128-GCM-SHA256, HTTP/1.1 200 OK, 565725 bytes, same True, tls_stat {'TlsTxSw': 1, 'TlsRxSw': 1, 'TlsDecryptError': 0}, 2101000.jr +38", + "23:03:15 cbc-1.2: offer ECDHE-ECDSA-AES128-SHA -> ECDHE-ECDSA-AES128-SHA, HTTP/1.1 200 OK, 565725 bytes, same True, tls_stat {'TlsTxSw': 0, 'TlsRxSw': 0, 'TlsDecryptError': 0}, 2101000.jr +0", + "23:03:15 rfc7539(chacha20,poly1305) is rfc7539(chacha20-neon,poly1305-neon); gcm(aes) is gcm_base(ctr-aes-caam,cryptd(ghash-ce-sync))", + "23:03:15 baseline: post: clean", + "23:03:15 result PASS" + ], + "manifest_sha": "70ecd7867c2698d17f2f3c38db772868eda3364f541242c93fb5db4e1d593bcd", + "message": "", + "result": "PASS", + "test": "forgectrl.tls-records", + "ts": "2026-10-18T23:03:15Z" + }, + "requires": [], + "satisfied": true, + "source_sha": "89b2b38c8657c63eccb39f517a8b6f69da70c6eaea00779c641ac050375b70c9", + "subsystem": "forgectrl", + "title": "HTTPS: ChaCha20 chosen, records sealed in the kernel" + } + ], + "tool_version": "0.1.0" +} diff --git a/releases/v0.0.9/acceptance.md b/releases/v0.0.9/acceptance.md new file mode 100644 index 0000000..caad541 --- /dev/null +++ b/releases/v0.0.9/acceptance.md @@ -0,0 +1,57 @@ +# ForgeFIRM acceptance - 20261018222431 (dev) + +- Image: `20261018222431 (dev)` (forgefirm-image-dev) +- Manifest identity: `70ecd7867c2698d17f2f3c38db772868eda3364f541242c93fb5db4e1d593bcd` +- Catalog: `b38332a30994e16a499a9ded530062291bacabf873138461dd54421e2174c29b` +- Campaign: `c-20261018224638-4ca0` opened 2026-10-18T22:46:38Z +- Exported: 2026-10-18T23:33:36Z +- **Release authorized: YES** +- Tests: 43 total, 43 satisfied (0 inherited), 0 required + +| Test | Kind | Result | Run at | Campaign | Inherited | +|---|---|---|---|---|---| +| `image.health` | auto, core | PASS | 2026-10-18T22:46:39Z | `c-20261018224638-4ca0` | no | +| `kernel.latch-locked-idle` | auto, core | PASS | 2026-10-18T22:46:39Z | `c-20261018224638-4ca0` | no | +| `kernel.k1-k2` | auto, core, takeover | PASS | 2026-10-18T22:47:02Z | `c-20261018224638-4ca0` | no | +| `kernel.deadman-close` | auto, core, takeover | PASS | 2026-10-18T22:47:12Z | `c-20261018224638-4ca0` | no | +| `kernel.backtrack-bounds` | auto, core, takeover | PASS | 2026-10-18T22:47:30Z | `c-20261018224638-4ca0` | no | +| `kernel.fire-line` | auto, core, takeover | PASS | 2026-10-18T22:48:14Z | `c-20261018224638-4ca0` | no | +| `kernel.resume-lead` | auto, takeover | PASS | 2026-10-18T22:48:37Z | `c-20261018224638-4ca0` | no | +| `kernel.pic-soc-load` | auto | PASS | 2026-10-18T22:48:41Z | `c-20261018224638-4ca0` | no | +| `forgectrl.auth` | auto | PASS | 2026-10-18T22:48:42Z | `c-20261018224638-4ca0` | no | +| `setup.check-switches` | operator | PASS | 2026-10-18T22:48:47Z | `c-20261018224638-4ca0` | no | +| `setup.check-airflow` | auto, takeover | PASS | 2026-10-18T22:49:27Z | `c-20261018224638-4ca0` | no | +| `setup.check-motion` | auto, takeover | PASS | 2026-10-18T22:50:03Z | `c-20261018224638-4ca0` | no | +| `setup.check-lens` | auto, takeover | PASS | 2026-10-18T22:50:24Z | `c-20261018224638-4ca0` | no | +| `setup.cloud-header-capture` | operator, takeover | PASS | 2026-10-18T23:08:40Z | `c-20261018224638-4ca0` | no | +| `setup.focus` | live, takeover | PASS | 2026-10-18T23:11:20Z | `c-20261018224638-4ca0` | no | +| `motion.pacing` | auto | PASS | 2026-10-18T22:49:43Z | `c-20261018224638-4ca0` | no | +| `motion.jog-roundtrip` | auto | PASS | 2026-10-18T22:50:42Z | `c-20261018224638-4ca0` | no | +| `motion.microstep-modes` | auto | PASS | 2026-10-18T22:51:07Z | `c-20261018224638-4ca0` | no | +| `motion.liveness-probe` | auto | PASS | 2026-10-18T22:51:16Z | `c-20261018224638-4ca0` | no | +| `motion.deadman` | auto | PASS | 2026-10-18T22:52:02Z | `c-20261018224638-4ca0` | no | +| `motion.step-timing-under-load` | auto | PASS | 2026-10-18T22:52:33Z | `c-20261018224638-4ca0` | no | +| `motion.release` | auto, takeover | PASS | 2026-10-18T22:52:59Z | `c-20261018224638-4ca0` | no | +| `cooling.aa-offset-calibrate` | auto | PASS | 2026-10-18T22:54:32Z | `c-20261018224638-4ca0` | no | +| `cooling.flow-verify` | auto | PASS | 2026-10-18T22:57:10Z | `c-20261018224638-4ca0` | no | +| `cooling.flow-under-load` | live | PASS | 2026-10-18T23:12:56Z | `c-20261018224638-4ca0` | no | +| `cooling.fail-tier-stop` | operator | PASS | 2026-10-18T22:57:30Z | `c-20261018224638-4ca0` | no | +| `laser.emission-witness` | live, core | PASS | 2026-10-18T23:09:51Z | `c-20261018224638-4ca0` | no | +| `laser.armed-kill` | live | PASS | 2026-10-18T23:13:40Z | `c-20261018224638-4ca0` | no | +| `laser.pause-resume-lid-cancel` | live | PASS | 2026-10-18T23:14:18Z | `c-20261018224638-4ca0` | no | +| `camera.snapshot` | auto | PASS | 2026-10-18T22:57:47Z | `c-20261018224638-4ca0` | no | +| `camera.sensor-profile` | auto | PASS | 2026-10-18T22:58:00Z | `c-20261018224638-4ca0` | no | +| `camera.h264-stream` | auto | PASS | 2026-10-18T22:58:14Z | `c-20261018224638-4ca0` | no | +| `camera.frame-health` | auto | PASS | 2026-10-18T22:58:32Z | `c-20261018224638-4ca0` | no | +| `camera.lid-privacy` | operator | PASS | 2026-10-18T22:58:48Z | `c-20261018224638-4ca0` | no | +| `update.slots-and-signature` | auto | PASS | 2026-10-18T22:58:50Z | `c-20261018224638-4ca0` | no | +| `cloud.mode-switch` | operator | PASS | 2026-10-18T23:00:59Z | `c-20261018224638-4ca0` | no | +| `cloud.service-protocol` | operator | PASS | 2026-10-18T23:15:30Z | `c-20261018224638-4ca0` | no | +| `cloud.lid-interlock-abort` | live | PASS | 2026-10-18T23:17:46Z | `c-20261018224638-4ca0` | no | +| `cloud.pause-resume` | live | PASS | 2026-10-18T23:21:27Z | `c-20261018224638-4ca0` | no | +| `cloud.oversize-stream` | live | PASS | 2026-10-18T23:24:58Z | `c-20261018224638-4ca0` | no | +| `exthost.platform` | auto | PASS | 2026-10-18T23:01:21Z | `c-20261018224638-4ca0` | no | +| `exthost.armed-freeze` | operator, takeover | PASS | 2026-10-18T23:03:09Z | `c-20261018224638-4ca0` | no | +| `forgectrl.tls-records` | auto | PASS | 2026-10-18T23:03:15Z | `c-20261018224638-4ca0` | no | + +Artifact sha256: `97018f73354c1b768b893f1538c43d8c506e06e8bd788ab4e194968910c4e5f1` diff --git a/releases/v0.0.9/notes.md b/releases/v0.0.9/notes.md new file mode 100644 index 0000000..a817320 --- /dev/null +++ b/releases/v0.0.9/notes.md @@ -0,0 +1,25 @@ +ForgeFIRM v0.0.9 is a beta release. + +The setup is simpler, and it is safe to run again. On some machines, running First fire a second time, or after a power cycle, drove the head into the side of the machine. The setup sheet and its steps (Place the sheet, First fire, Dose curve, Corner rolloff, Flow under load) are gone. Focus and the optional Laser floor now each burn on their own small scrap in the back-left corner, starting from home against the gantry stops. A new Lens travel check measures the lens with the laser off. Only the first steps, through Intake fans and Coolant flow, are required. The rest are recommended, and Finish later takes you to the control panel. + +Also fixed: + +- Stopping mid-move (a reset from your Grbl sender, Abort in the control panel, or a cooling fault) now slows the head to a stop and keeps its position, so the machine stays homed. +- A rare stream fault that could replay leftover motion, with the laser off, at the start of the next job now stops with an alarm. +- The setup's burns no longer need the head's beam sensor, which reads nothing on some heads. +- The setup no longer shows the head as "not detected". +- The TEC check is gone. It could never pass, and it turned the TEC off on Pro machines. Your answer in the Your machine step now sets whether a TEC is fitted. +- A setup question or wait that times out now ends its step with the reason and a way to run it again. +- The coolant flow calibration no longer leaves its trial settings behind after an abort. +- The logs now record which firmware runs at every start and every update, so a log export shows how a machine was updated. +- Extensions: a rollback or an interrupted install no longer leaves an extension broken. + +After you update: + +- If your machine has not done the Intake fans or Coolant flow step, the setup asks for it, and the machine waits for it before it runs a job. +- Pro owners who ran the setup on an earlier release: make sure Cooling protection > Coolant loop > TEC (Pro chiller) is on. The old TEC check turned it off. +- If you ran the setup sheet on an earlier release and your jobs now land offset from where you placed them, send G92.1 once from your Grbl sender. + +Expect bugs. When you find one, open an issue in this repository or report it on the community forum at https://community.openglow.org so it can be fixed. + +Every release below 0.1.0 is a beta release. Installation, usage, and safety are documented at https://docs.forgefirm.org/.