Commit Graph
3 Commits
Author SHA1 Message Date
ScottW514 9f7744b459 Pin forgectrl 0.1.28, forgeext 0.1.0, grblHAL-glowforge 0.1.19, forgefirm-app 0.1.31 on the pushed heads, and meta-openglow in the kas lock
The extensions work, merged into each component's default branch and
pushed, is what the recipes now fetch:

- forgectrl 55bfae9 (0.1.27 -> 0.1.28): the machine lease, the job runner,
  the controller port client and motion routes, scoped tokens, the event
  stream, the built-in registry, the operator's door to extension packages
  and the Extension packages card, the catalog from its own repository,
  and privacy advisory revision 4.
- forgeext 711f099 (first pin, 0.1.0): the extension host, and ffx new
  making a package's repository.
- grblHAL-glowforge 0da0fe6 (0.1.18 -> 0.1.19): manual homing, the X and Y
  motor release, the controller port, custom M-codes, the envelope rule,
  and the homing runner's report secret.
- forgefirm-app 021323d (0.1.30 -> 0.1.31): the report secret, and a
  homing motion cut short failing the home.
- kas lock: meta-openglow 71fad52 -> 2978522, the kernel's sandbox options
  (NF_TABLES, LANDLOCK, MEMCG, the cgroup scheduler) and their notes.

Proof: bitbake -c fetch of forgectrl, forgeext, grblhal-glowforge,
python3-gfhardware, gfhome, gfcloud and python3-ffmachine from these pins
succeeds (14 tasks), with kas moving layers/meta-openglow to 2978522. The
tree manifest from these pins holds forgectrl at 55bfae9 (211 files),
forgeext at 711f099 (90) and the driver at 0da0fe6 (175), and the coverage
lint over it finds no uncovered path (124 tests).

Acceptance: the meta-openglow move is a platform change, so the whole
catalog runs again on the image built from these pins.
2026-09-25 19:27:37 -04:00
ScottW514 1e98b37e45 forgeext on the image, and the tests of the host and of the consent
The image installs forgeext beside forgefirm-sandbox. The recipe installs
the init script from forgeext's own tree (start 91, after forgectrl at 90,
whose read-only routes the host takes the machine's state from; stop 9, down
before it). The host runs nothing while ext_enabled is 0, the default.

setup.extensions-consent (takeover): the Extensions advisory is served and
is no first-run document; ext_enabled=1 is refused without the advisory's
hash, with a stale one, without the phrase, with the phrase in another
case, and whole beside a write the daemon refuses, each leaving the setting
and the record on disk untouched; with the hash and the phrase it is
accepted, recorded under on_demand.extensions, and the data directory gains
the search bit and nothing else. The setting, the directory's mode, and the
record are put back, the record under a forgectrl restart.

exthost.service (takeover): a reference package built on the board, signed
with a key made there and added as an owner key. It is unverified before
the key is the owner's and community after; the install is refused without
the consent. Turned on over the advisory, the service is looked at from
outside (account, no_new_privs, seccomp, group, limits, chain) and from
inside (what it can read, write, dial, and open), its first line is looked
for in the forgeext logger's file, safe mode stops it, a host killed with
the service in its quiet loop takes it along within 2 s and comes back, and
ext_enabled=0 leaves no group and no chain. The package, the key, the
setting, the mode, and the record are put back, and the extension root is
compared with how it was found. The reference package exists only while the
test runs: no image carries it, and no image trusts its key.

Proven. forgetest's unit suite: 422 tests pass, 0 undefined names. On the
bench reference, image 20260920211625 with the cross-built forgectrl and
host from /tmp: setup.extensions-consent PASS and, against the image's own
daemon, FAIL at its first request; exthost.service PASS and, with the init
wrapper's kill taken out, FAIL at the killed-host check. The first runs of
exthost.service found what the host tests could not: /data/forgefirm is
0700 on the bench reference, and the service ended with EACCES on its own
entry point until forgectrl opened the directory for search with the
consent.

Acceptance. Both tests are new. exthost.service covers forgeext whole and
forgectrl's src/main.c and src/logs.*; setup.extensions-consent covers
forgectrl's consent path. The recipe, the image line, and the init
script's install are layer content, in the platform identity of every
fingerprint. forgeext joins scripts/manifest-from-tree.py with its first
pin.
2026-09-20 21:41:21 -04:00
ScottW514 5ad7ee6faa forgeext: the recipe, and the extension-signing key in the keyring
forgeext is the extension host, a component of its own: recipe
recipes-forgefirm/forgeext (cmake, pkgconfig, forgefirm-manifest, so it is
a manifest component with its own pin file). It links jansson, libarchive,
and libsodium, and runs with fwup, the keyring, and forgefirm-sandbox.
libarchive and jansson are on the image already; libsodium comes with it.
The pin is all zeros because the repository has no pushed commit to name:
the recipe builds from a working tree through externalsrc, and a build
from pins cannot fetch it until the first push sets the pin. It is not in
the image's install list.

forgefirm-keys installs a third trust anchor,
/etc/forgefirm/keys/ext/forgefirm-ext.pub: the OpenGlow extension-signing
public key, the official tier of extension packages. It is a different key
from the release key on purpose: it signs more often, and its loss must
not sign firmware. forgeext refuses an extension archive whose only valid
signature is the release key's or a factory key's.

Proven. The recipe cross-builds forgeext from the working tree, and that
binary ran the verify-and-install cases on the bench reference (image
20260920211625, from /tmp, with the board's own fwup 1.16.0 and the
image's keyring) with the results of the host test. forgefirm-keys builds
and packages the key 0644 under ext/ (0755), byte-identical to the file
here; it is 32 key bytes and is not the release key.

Acceptance. No catalog test reads either yet: forgeext's tests are the
exthost suite that comes with its daemon, and the key is layer content, in
the platform identity of every fingerprint.
2026-09-20 19:34:45 -04:00