A headless PC can be claimed, and a refused broker says so
Both found by operating the stack rather than writing it: the local processes were OOM-killed and bringing them back hit two gaps. The headless agent had no way to be claimed at all. Bootstrap lived only in desktop/internal/cloud, so the one configuration the agent binary exists for - a back-office PC with no window - could only be onboarded by hand-editing agent.json, which is the state the desktop's Setup screen was built to end. `behavision-agent claim <code>` closes it; the CLI joins its arguments because the code is printed in groups for reading aloud and an operator pasting it will paste the spaces too. Second: after the site's broker password was re-rolled, mosquitto logged "not authorised" while the agent logged "timed out". Those need opposite actions - re-link this PC, or go and look at the network - and paho's SetConnectRetry collapses them, because it retries internally and the connect token never completes. describeStall asks whether a TCP socket opens at all, and says what is known rather than guessing at a reason the broker never gives. Verified end to end: minted a code from the platform as the owner, claimed with the new command, broker connected, and the shop went to online: true with 1/1 cameras on w600k_r50. Also corrects this machine's memory in CLAUDE.md from 16 GB to 8 GB. It feeds the model-fallback reasoning, and the local gallery already holds 17 embeddings tagged w600k_mbf beside 19 tagged w600k_r50 - the fallback has silently fired before. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HViLj9gYNRtSr7YVZmW5sn
This commit is contained in:
57
CLAUDE.md
57
CLAUDE.md
@@ -152,7 +152,8 @@ own camera, same-person similarity p05 0.719 vs 0.620) → `arcface_int8.onnx`
|
||||
the chain. AdaFace slots are wired but empty: drop a converted
|
||||
`adaface_ir50.onnx` in and it is picked up, BGR channel order already
|
||||
handled (see `color_order_for`). The dev machine is
|
||||
memory-starved (16 GB, often < 1.5 GB free): the 260 MB model fails with
|
||||
memory-starved (**8 GB**, measured 0.45 GB free with a browser and Docker
|
||||
open): the 260 MB model fails with
|
||||
"bad allocation"; int8 quantization of it segfaulted (OOM). w600k_mbf comes
|
||||
from InsightFace buffalo_sc; genderage.onnx from buffalo_l. On failure,
|
||||
the encoder retries loading with `ORT_DISABLE_ALL` graph optimization.
|
||||
@@ -2257,3 +2258,57 @@ Verified against the real office camera with no object storage configured: a
|
||||
90,587-byte frame stored in Postgres, served as `image/jpeg` to a signed-in
|
||||
user, **401 without a session**, and rendered on both the Cameras and Shops
|
||||
cards.
|
||||
|
||||
## Claiming a headless PC, and telling a refused broker from an absent one
|
||||
|
||||
Both found by the local stack falling over on a memory-starved machine and
|
||||
needing to be brought back — the kind of thing that only surfaces when the
|
||||
software is operated rather than written.
|
||||
|
||||
### `behavision-agent claim <code>`
|
||||
|
||||
The desktop app has had a Setup screen since enrolment was built. The **headless
|
||||
agent had nothing**: `Bootstrap` lived only in `desktop/internal/cloud`, so the
|
||||
one configuration the agent binary exists for — a back-office PC with no window
|
||||
— could not be claimed at all. The only route was hand-editing `agent.json`,
|
||||
which is exactly the state that Setup screen was built to end.
|
||||
|
||||
`agent/pkg/enrol` is that call, and the CLI joins its arguments rather than
|
||||
demanding quotes: the code is printed in groups so it can be read aloud, and an
|
||||
operator pasting it will paste the spaces too. It clears `Standalone`, and a
|
||||
config that fails to save is **reported** — a claim that is not on disk works
|
||||
until the next restart and then silently is not claimed, which looks exactly
|
||||
like a wrong code.
|
||||
|
||||
### A rejected connection and an unreachable broker are not the same fault
|
||||
|
||||
Measured, on the real stack: after the site's broker password was re-rolled,
|
||||
mosquitto logged `not authorised` while the agent logged **`connect to
|
||||
tcp://... timed out`**. Those need opposite actions — re-link this PC, or go and
|
||||
look at the network — and paho's `SetConnectRetry` is why they collapse into
|
||||
one: it retries internally, so the connect token never completes and *every*
|
||||
failure arrives as a timeout.
|
||||
|
||||
`describeStall` asks the one question that separates them: can a TCP socket be
|
||||
opened to the broker at all? Reachable-but-not-accepted names the likely cause
|
||||
and the command to fix it; unreachable says to check the network. It does not
|
||||
claim to know the exact reason — the broker does not tell a rejected client why,
|
||||
and a TLS failure looks the same from here — so it reports what is known rather
|
||||
than guessing. Same rule as `artifact` vs `no_faces` in the commissioning
|
||||
verdicts, and the `connected` pointer being three states rather than two.
|
||||
|
||||
`brokerHostPort` parses with `net/url`, never by scanning for the first `:` —
|
||||
this package has already been bitten once by IPv6 literals being bracketed and
|
||||
full of them.
|
||||
|
||||
### The dev machine is 8 GB, not 16
|
||||
|
||||
Corrected in this file, because it feeds a real decision. Measured while the
|
||||
stack was up: **0.45 GB free** with a browser and Docker Desktop open, and
|
||||
Docker alone is allocated 4 GB of the 8. The engine's steady state is only
|
||||
~260 MB, so the OOM kill happened during a build (npm + go + Docker at once),
|
||||
not in normal running — but the margin is what makes `/api/health` reporting
|
||||
`recognition_model` worth checking after every restart. The local gallery
|
||||
already holds **17 embeddings tagged `w600k_mbf` and 19 tagged `w600k_r50`**:
|
||||
proof that the fallback has silently fired before, and that model-tagging is
|
||||
what stopped it corrupting anything.
|
||||
|
||||
Reference in New Issue
Block a user