Skip to content

Broadcast the control loop's own health with STATUS - #38

Merged
Jepson2k merged 4 commits into
mainfrom
claude/par6-backend-setup-q9l7bx
Sep 4, 2026
Merged

Jepson2k merged 4 commits into
mainfrom
claude/par6-backend-setup-q9l7bx

Conversation

@Jepson2k

@Jepson2k Jepson2k commented Sep 4, 2026

Copy link
Copy Markdown
Collaborator

Whether the control loop is keeping up is a question a display asks continuously, and answering it through the loop-statistics query means polling for something the status broadcast is already sending 50 times a second. The p99 period and the overrun count now ride along with STATUS, in a loop_health mapping.

drive_health is declared beside it and stays empty here, deliberately: the drives report per-joint error flags over the serial link, not analog temperature or current registers, so there is nothing to put in it. Empty is what tells a consumer "no such sensor" rather than "all zero", and the flags surface as faults instead of a trend.

The wire field is length-guarded like every other appended slot, so a producer that predates it decodes as an empty mapping and a consumer can tell "loop healthy" from "loop not reported".

This is the parol6 half of the coordinated claude/par6-backend-setup-q9l7bx work; the waldoctl half is already merged and released in v0.12.0. The branch came over from the Jepson2k fork, where it was raised against a stale main, and is cherry-picked onto current upstream main here.

Ordering note: type checking on this branch reports two errors that are on main today and are not from this commit — the sync client and the robot factory are annotated as holding ToolSpec where make_sync_tool returns SyncTool. #37 fixes exactly that. Merge #37 first and this goes green once main is merged back in.

🤖 Generated with Claude Code

https://claude.ai/code/session_014Bo12kumRx9PHnY9bL8qgn

claude and others added 4 commits September 4, 2026 02:16
Whether the loop is keeping up is a question a display asks continuously,
and answering it through the LOOP_STATS query means polling for something
the controller already knows every tick. The period tail and the
deadline-miss count now ride the status broadcast instead, appended at the
tail so a decoder that stops at the fields it knows is unaffected.

The status cache re-encodes on change, and these two change slowly: the
percentile is recomputed once per stats window and overruns are rare, so
the payload turns over about as often as the window does rather than every
tick.

StatusBuffer also declares drive_health, which PAROL6 never fills: the
drivers report per-joint error FLAGS over the serial link, not analog
temperature or current registers, and flags are a fault surface rather
than a trend. An empty dict is the honest answer, and it is what tells a
consumer "this backend has no such sensor" rather than "all zero".

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GdLL4oE6RejS9yPeSkQXpF
The counter only ever climbs, so comparing a status frame against a query
taken after it asserts that the loop missed no deadline in between. On a
loaded macOS runner it misses one or two, which is the loop reporting
honestly, not the broadcast disagreeing with the query. The sample is now
bracketed by a query on either side, which is the actual invariant: one
monotone counter, read three times in order.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014Bo12kumRx9PHnY9bL8qgn
The shared status buffer can still hold a frame captured before the first
query, so bracketing the broadcast sample between two queries failed from
below: the frame was older than the lower bound, not disagreeing with it.
Waiting for a frame whose count has reached that reading puts the sample
between the two by construction, and the only assertion left is the one
that means something — the broadcast never runs past a query taken after
it.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014Bo12kumRx9PHnY9bL8qgn
@Jepson2k
Jepson2k merged commit b776ea3 into main Sep 4, 2026
16 of 26 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants