Accept systemd credential delivery and clarify manual K1 control

This commit is contained in:
DCCONSTRUCTIONS
2026-09-07 14:44:46 +03:00
parent 102e93796b
commit a93f1f1b8b
19 changed files with 402 additions and 31 deletions
@@ -0,0 +1,76 @@
# Systemd authority and manual K1 control R9
The owner's new attempt on installed Node 0.8.6 / K1 0.1.5+private.1 passed
Bluetooth provisioning and reported network_applied. DeviceInfo then failed
with application_authority_unavailable, before the MQTT transport opened.
The inventory row represents the admitted device session and known address;
it is not proof of a healthy control channel or permission to issue START.
Private screenshots, exact operation and a timestamped/hash manifest are in
private/acceptance/k1-node086-20260907-manual-control. Cache clearing for the
owner attempt has not been independently confirmed. No agent hardware writes
or CLI Bluetooth/MQTT tests were performed.
## Credential delivery contract
The installed systemd 255 credential directory is root-owned, mode 0550,
with named service-user rx ACL, group permissions empty and other permissions
empty. The ordinary SSH user cannot traverse it to inspect the credential
leaf, and no permission bypass was attempted.
[systemd v255 write_credential](https://github.com/systemd/systemd/blob/v255/src/core/exec-credential.c#L150)
creates root-owned files and preferentially grants the service UID a read ACL;
ownership transfer is a fallback. The ACL mask appears as group-read in stat,
as also documented in [systemd issue 29435](https://github.com/systemd/systemd/issues/29435).
The previous Linux loader required service ownership and rejected every group
mode bit, so it rejected this valid delivery model. A local regression with
real bounded file reads and synthetic kernel ownership/mode reproduces that
rejection before the fix. The observed directory matches the systemd scheme;
successful loading on the actual installed service remains an acceptance gate.
The loader now opens a non-symlink credential directory and opens the fixed
leaf relative to its pinned directory descriptor. Root-owned systemd delivery
may use the read ACL mask; service-owned private fallback remains supported.
Untrusted ownership, group-write, world permissions, execute bits, symlinks,
nonregular files and oversized input are rejected. No chmod, chown, ACL change,
new key, network action or alternate secret source is used. The existing key
is retained. A cached startup availability boolean reports whether the
immutable service credential could be loaded; it grants no device authority.
## Manual operation surface
The approved device-detail composition now has one Initiate start action when
current control permits it. Settings uses the canonical SettingsCard actions
slot at the right. STOP is presented for an active acquisition; initial idle
STOP and Refresh viewer buttons are absent. A pending launch indicates progress,
and the existing live Rerun view mounts once the acquisition is streaming. If
the preview transport fails, its local recovery action is available in that
failure state and does not repeat physical START.
The enrollment completion action is Configure device. The generic host fetches
fresh inventory and opens only the uniquely matching verified session; stale,
ambiguous and disconnected sessions cannot complete this handoff. The K1
contribution supplies its own network/control status and disables the generic
rename affordance, which this driver does not implement. A pending Wi-Fi
session is labelled Wi-Fi configured / no control and explains authorization
failure. Controls remain unavailable before connection proof. A read-only
Check K1 state action is available where the backend permits recovery.
No Rerun profile, live blueprint, playback or LAB configuration changed.
The existing plugin control-operation budget, journal identities, physical
acceptance and restart/link-recovery fences remain in place. Sensor-operation
failures now use the same secret-free causal logger as enrollment failures.
## Validation
36 Python checks cover the credential contract, startup availability without
control authority, NodeBridge projection/actions and package lifecycle.
26 focused UI/architecture checks and all 797 Core frontend tests passed;
Core TypeScript and production build passed. The new UI tests exercise the
actual detail renderer for waiting, ready and streaming states, and the exact
session handoff. Scoped Ruff and diff whitespace checks passed.
Node 0.8.7 / optional K1 0.1.6 are reserved for this source. Packaging, installed
credential loading, DeviceInfo, physical START/STOP and live stream verification
must be recorded separately as observed. The connected browser tooling exposes
only an empty in-app browser, not the owner's Chrome or its cache controls;
fresh-cache physical UI acceptance remains an owner step.