Add lease-bound Remote key IPC and SDK validation

This commit is contained in:
ak47 committed 2026-11-05 21:28:29 -05:00
1 parent 9ac33560dc
commit 792cac5d0b
12 files changed
+807 -9

No files matched your search

+119
View File
@@ -0,0 +1,119 @@
# Experimental Remote keyboard IPC prerequisite
The protocol 1.1 host recognizes `remote.key`, with public Go types and matching
Python validation. Reader code can explicitly attach a bounded incoming-key
mailbox. No production input owner is attached: ordinary reader sessions return
owner-unavailable, and the external Remote command still discards keyboard
payloads. This is not desktop keyboard control.
## Wire contract
One child-to-host request carries one logical transition:
```json
{"lease":"0123456789abcdef0123456789abcdef","epoch":1,"sequence":2,
"key":{"name":"Control_R","pressed":false}}
```
All fields are required, including boolean `pressed` on release. Field names
are exact; unknown fields, duplicate keys, nulls, missing values, nonboolean
press state and invalid numeric identities are rejected. Epoch and sequence
are positive uint64 values. Lease identifiers have the existing 32-byte bound;
only the actual token issued to this process can authorize work.
`name` identifies one canonical unshifted logical key. It is neither text to
type nor an X keycode, Windows VK/scan code, script path or command. The bounded
allowlist matches the external mapper's canonical subset:
- Lowercase Latin letter names, top-row digits, F1–F24 and KP_0–KP_9.
- Left/right Shift, Control, Alt and Super; Menu, lock keys, Pause and Print.
- Backspace, Tab, Return, Escape and Space; main navigation, Insert and Delete.
- Keypad Enter, navigation, Begin, Insert, Delete and arithmetic/separator keys.
- The eleven explicit punctuation identities supported by the external US
profile. The owner must resolve the destination layout; this does not grant
permission to guess a matching physical key or change the global keymap.
Aliases such as `Prior`, uppercase text, shifted character names, AltGr,
dead/IME keys, arbitrary Unicode and unrecognized names remain unsupported.
For exact case/spelling, see `ValidRemoteKey` in
`internal/tentaclewire/remote_key.go`. No implicit modifier transitions, text
insertion or fallback commands are synthesized.
Go exposes `RemoteKey`, `RemoteKeyRequest`, `ValidRemoteKey` and
`ValidRemoteKeyRequest` through `sdk/go/tentacle`. Python exposes
`valid_remote_key` and `valid_remote_key_request` from
`cthulhu_tentacle.session`. They validate representation, not consent or native
availability. Generic `SessionClient.Call`/`call` still permits method-specific
host errors; callers may use the validators before submitting work. Older hosts
return unsupported-operation for this addition.
## Authorization and admission
The host requires the current process session's live controlled-role lease and
the separately approved `keyboard-inject` grant. Installation grants, observer
consent, controller role, relay membership and a child's claimed origin cannot
authorize injection. Parameters contain no local-origin or consent override.
`remote.key` shares the strictly increasing operation sequence with heartbeat,
close and other lease operations. An accepted key advances it without renewing
the heartbeat deadline. Replayed, foreign, expired or cancelled operations are
denied. Invalid parameters and missing-owner errors do not consume the lease
sequence or enqueue work.
`Session.EnableRemoteKeys` is a reader API, not a child RPC. It attaches one
256-item mailbox. Retained queued plus in-flight keys are bounded by 256 items
and 256 KiB of canonical encoded request bytes, including lease/sequence
metadata. Receiving a delivery does not return capacity. Its idempotent
`Release` returns capacity after delivery or discard, only to the original
lease. A release from a retired worker cannot alter replacement accounting.
The RPC result `{}` acknowledges mailbox admission only. It does not acknowledge
XTEST, application delivery or key recovery. Saturation revokes the lease and
drains pending work rather than dropping a key-up and continuing. Heartbeat,
revocation and shutdown do not wait for a native worker.
## Ownership and retirement
`RemoteKeyDelivery` retains the original lease, operation sequence, typed key
and cancellation context. A future input owner must check that context and
`Session.RemoteContext(lease, "keyboard-inject")` immediately before applying
each effect, alongside current focus, lock/handoff and native policy. Context
alone does not replace the deadline check. No native callback is invoked while
the host session mutex is held.
Revoke, explicit close, replacement, expiry, policy cancellation, disable and
session failure cancel accepted work and clear pending keys. Local policy
cancellation invalidates the delivery context synchronously, before asynchronous
notification/drain callbacks acquire the session lock. Restoring availability
never revives the original lease. A new explicit approval creates a new epoch.
The native owner must keep its own destination key ledger, resolve repeats and
lock state, reject physical/injected collisions and guarantee cleanup even if
the Tentacle, reader or network disappears. Cleanup must not depend on this
mailbox admitting a last up. The external outgoing encoder's transport write
acknowledgements and this API's mailbox admission are separate contracts;
neither establishes actual destination input completion.
## Verification and remaining gates
Strict representation tests compare Go and Python validators, including both
transitions, all letter/digit/function ranges, uint64 boundaries, missing/null
values, exact field names and rejected metadata. Real Go/Python SDK child
processes exercise owner-unavailable, admission, permission/role/process checks,
shared heartbeat ordering, replay, malformed requests, capacity retention,
concurrent idempotent release, overflow and retirement/replacement. The external
bridge verifies that every canonical mapper result satisfies the public SDK
contract. None of these tests injects a desktop key.
No capture event API, production Xorg input owner, independent native cleanup
helper, core escape/bypass integration or installed Remote keyboard command is
provided. Physical-source approval, physical collision/recovery, audible speech,
Braille and real NVDA/Orca interoperability remain unverified. Private IPC and
relay checks close no live release gate.
This increment passed the full wire/host/both-SDK race suites (host: about
128 seconds), focused application Remote connection/speech race tests, the
existing speech regression harness, affected-package vet, a separate reader
build and Tentacles `make check`. The lifecycle regression now checks malformed
typed keys and keeps its unsupported-operation check on Braille. No full reader
suite or native/hardware acceptance was performed; no active reader was replaced.
+9 -4
View File
@@ -11,8 +11,10 @@ remote control. A later [reader authorization increment](tentacle-remote-authori
adds the core consent procedure, sensitive XI2 forms and lock/handoff policy.
The external source-built Remote command now requests that consent through a
typed interaction; physical-keyboard approval remains unverified. There is no
output observer, keyboard service, clipboard service,
or Braille session service. The unrestricted `Session.AuthorizeRemote` hook is
production keyboard, clipboard or Braille session service. Subsequent speech
integration supplies limited observation and isolated incoming software speech;
the [keyboard IPC prerequisite](tentacle-remote-keyboard.md) adds a typed mailbox
without a native input owner. The unrestricted `Session.AuthorizeRemote` hook is
limited to development managers; reader managers require a core approval ticket.
Packaging Remote itself remains premature.
@@ -167,8 +169,10 @@ The process supervisor still enforces cleanup for a child ignoring cancellation.
Typed speech IPC now extends this transport; see
[the speech contract](tentacle-remote-speech.md). It uses the same ordered event
queue for exported speech and a separate 64-item incoming mailbox. Limited
production speech observation is connected; incoming presentation ownership is
still pending. Keyboard/Braille/clipboard effects remain unsupported.
production speech observation and isolated incoming software speech are connected.
The [keyboard IPC prerequisite](tentacle-remote-keyboard.md) adds `remote.key`
and a separate bounded mailbox, unavailable without a reader input owner.
Production keyboard/Braille/clipboard effects remain unsupported.
## Implemented lifecycle operations
@@ -192,6 +196,7 @@ Child calls:
| `remote.heartbeat` | `lease`, `epoch`, `sequence` | `{}` |
| `remote.close` | `lease`, `epoch`, `sequence` | `{}` |
| `remote.present` | `lease`, `epoch`, `sequence`, typed `speech` | `{}` after mailbox admission; unavailable without reader owner |
| `remote.key` | `lease`, `epoch`, `sequence`, typed `key` | `{}` after mailbox admission; controlled `keyboard-inject` only; unavailable without reader input owner |
The action token must match the unconsumed core approval. Role must match exactly,
and grants must be a nonempty subset of the approved install grants. Controller