Skip to content

Support bounded digital I/O for named signal skills - #44

Draft
Jepson2k wants to merge 7 commits into
feat/tcp-calibrationfrom
feat/named-device-signals
Draft

Support bounded digital I/O for named signal skills#44
Jepson2k wants to merge 7 commits into
feat/tcp-calibrationfrom
feat/named-device-signals

Conversation

@Jepson2k

@Jepson2k Jepson2k commented Sep 7, 2026

Copy link
Copy Markdown
Collaborator

Digital I/O reads and writes accept a per-call deadline covering endpoint setup and retries. A missing read returns None; unconfirmed write acceptance raises TimeoutError. These outcomes reach the skill runtime without being mistaken for user cancellation. Existing calls retain their configured request timeout.

Both client facades expose the options and advertise io.digital. Dry-run output writes use logical output indices and report dispatch errors; preview capability identifies the need for explicit observation fixtures.

Validation: 10 simulator integration tests passed, including native I/O readback, silent-peer deadlines, skill cancellation, and tool operations. Pre-commit checks passed.

Stacked on #43. Coordinated branch: feat/named-device-signals; requires the companion waldoctl v0.16.0 contract. The Commander dependency update targets PAROL6 v0.10.0.

Companion PRs: ctl, p6, wc.

Jepson2k and others added 6 commits September 11, 2026 05:05
…ew later queries

A per-call deadline cancels a query after its datagram was sent; the reply
then sits in the receive queue and, with no request ids on the wire, is
handed to the next query of any type (returning None for its typed result
and leaving every later query one reply behind) or, for a lapsed write_io,
lets a stale index-less OK stand in for the next command's ack. Queued
replies are discarded when a new request goes out, and a per-call deadline
now bounds a single attempt instead of cancelling mid-receive.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The per-call deadline moved inside _request, which no longer bounded
endpoint setup and its retries: an io() against an absent peer waited the
client's full retry budget. The outer deadline is back around the call;
the inner one still keeps the query to a single attempt.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…-reply test

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
A command datagram now carries a 4-byte request id ahead of the msgpack
body and every OK, ERROR and RESPONSE echoes it, so the client matches a
reply to the request that is waiting for it and drops one whose caller has
already given up. That replaces the heuristic drain, which could only
guess from a datagram's type that nobody was waiting for it. Streamed
motion sends id 0 and asks for no reply.

Status broadcasts carry PROTO_VERSION in their second slot. A client
reading a status from another version raises ProtocolVersionError naming
both versions instead of failing to decode and reporting silence, which
reads as an unplugged arm. Client and controller are released together, so
there is no compatibility path for the older layout.

The readiness probe went through the codec as well: it hand-built a PING
datagram, which the controller stopped parsing the moment the envelope
changed, making a live controller read as an absent one.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ed-device-signals

# Conflicts:
#	parol6/client/dry_run_client.py
#	parol6/commands/query_commands.py
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.

1 participant