Add quarantined Xorg destination-key ownership and cleanup

This commit is contained in:
ak47 committed 2026-11-05 21:56:14 -05:00
1 parent 792cac5d0b
commit cd9ae05bbe
10 files changed
+988 -29

No files matched your search

+8 -2
View File
@@ -35,8 +35,9 @@ allowlist matches the external mapper's canonical subset:
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
For exact case/spelling, see `input.ValidRemoteKeyName` in
`internal/input/remote_key_names.go`, used by `ValidRemoteKey` in the wire/SDK
layer. No implicit modifier transitions, text
insertion or fallback commands are synthesized.
Go exposes `RemoteKey`, `RemoteKeyRequest`, `ValidRemoteKey` and
@@ -105,6 +106,11 @@ 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.
An unconnected [destination-key prerequisite](testing/remote-key-target.md) now
retains native codes through layout changes and uncertain effects, with a
quarantined Xorg resolver/backend. It is not attached to this mailbox and supplies
no independent process/watchdog cleanup or physical collision guarantee.
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,
+4
View File
@@ -2,6 +2,10 @@
This is an isolated prototype and a record of limitations, not a Remote input
implementation. No reader input behavior or installed executable changes.
A subsequent [Go destination-key prerequisite](remote-key-target.md) now supplies
stored-code ownership, retryable cleanup and a quarantined native resolver. It
does not inherit this Python prototype's independent EOF/watchdog behavior and
is not attached to production input.
The source baseline is `a47253d697c1aa44dea80646cad99a4fe163c7f1` on `testing`,
with the existing secret-entry work preserved. The branch was checked against
its upstream on 2026-11-03 before these tests were added.
+110
View File
@@ -0,0 +1,110 @@
# Quarantined Remote destination-key prerequisite
The reader has a destination-key ledger and an unconnected Xorg backend.
`internal/input/remote_key_ledger.go` owns at most 32 native destination codes;
`internal/platform/xorg/remote_keys.go` resolves and applies the supported
logical keys on a dedicated X connection. No production code constructs this
target, and no reader input owner is attached to `remote.key`. The Remote
command still discards relay keyboard traffic and offers no keyboard grant.
This is a native prerequisite, not a usable input service. It must remain
quarantined until independent helper cleanup, input provenance and physical
collision handling are established.
## Ownership and cleanup
One ledger belongs to one serial native owner and helper lifetime. Its caller
must validate the original lease immediately before each effect, retire on
cancellation, and finish cleanup before allowing replacement input. The ledger
itself neither issues consent nor checks lease epochs. It must not be shared
between leases or mutated concurrently.
A new logical down resolves one destination code and rejects invalid codes,
another owned name resolving to that code, or an already-held server key. It
reserves the code before attempting the down, because a native failure can leave
the outcome uncertain. Duplicate downs are idempotent and perform no additional
injection; native repeat fidelity remains unfinished. An unowned up performs
no native operation. An owned up uses its reserved code without resolving the
name again, including after layout/Num Lock changes.
Mapping failure, collision, capacity overflow or native failure stops admission.
`Retire` attempts every owned up in reverse down order. Successful ups are
removed; failed ups retain their exact code and original relative order for
explicit cleanup retry. Retirement never resumes admission. Backend errors
become constant local errors, without native diagnostic text or key names.
The native wrapper closes its connection only after successful ledger cleanup.
Failed cleanup leaves the connection and pending identities available for retry.
Opening replacement input must wait for confirmed old cleanup; a new consent
epoch does not make an old native release harmless. Closing an XTEST connection
or killing this process does not release held keys. The earlier
[Python feasibility harness](remote-input-feasibility.md) demonstrates that
limitation; its separate EOF/watchdog mechanism is not implemented by this Go
target.
## Native resolution and limits
The logical-key vocabulary now belongs to `input.ValidRemoteKeyName`; the wire
and Go SDK validators delegate to it, preserving the existing IPC schema and
Python conformance. Native input therefore uses the same bounded names as the
public SDK, without depending on the Tentacle wire package.
The backend fetches a fresh XKB map/state for each new resolution and requires
one unambiguous matching destination code. It supports group zero only;
nonzero groups are unavailable. Shift/Caps state is removed for logical base-key
resolution while Num Lock is retained. Shift-only punctuation, unavailable or
ambiguous symbols are rejected. It does not synthesize modifiers, assume a
Windows scan code equals an X code, or rewrite the global keymap. The private
fixture changes maps and lock state explicitly to exercise these cases.
See the [XKB library specification](https://xorg.freedesktop.org/archive/current/doc/libX11/XKB/xkblib.html)
for `XkbGetMap`, `XkbGetState` and `XkbTranslateKeyCode`.
Lock-key downs are unavailable until lock synchronization and reader modifier
handling have a defined policy. This includes Caps Lock even when a reader
configuration would otherwise use it as a modifier. AltGr, IME/dead keys,
general group/level handling and exact remote autorepeat remain unfinished.
The already-held-key check is not atomic with injection. A later physical or
other-client press of an owned code is not separately represented by the global
bitmap. This backend cannot preserve that press during cleanup. Fresh map reads
also do not freeze configuration changes by other clients. No physical-device,
concurrent-map-change or same-code collision guarantee is claimed.
All native wrapper methods require one serial caller on a locked OS thread.
Xlib calls and the error guard can block or terminate a process after X-server
failure. The future production target must run in an independent helper, with
bounded inherited-descriptor IPC, watchdog/EOF cleanup, exclusive ownership,
provenance, policy cancellation and explicit failure reporting. Do not attach
this synchronous wrapper to the reader event loop or directly to its mailbox.
## Private verification
From the reader checkout:
```sh
go test -race ./internal/input ./internal/tentaclewire -count=1
python3 -B tests/native_remote_keys.py
python3 -B tests/native_remote_input.py
```
The new harness requires Go, Python, Xvfb, private D-Bus and `setxkbmap`. It starts
a 24-bit Xvfb server before private D-Bus using `native_test_session.py`, with a
disposable runtime directory. It never uses the active reader, display or
accessibility bus. Missing dependencies fail the harness rather than count as
skipped acceptance. The native tests skip in ordinary unflagged Go suites;
only an actual harness run establishes their private results.
Unit tests cover stored-code releases, idempotent downs, unowned ups, alias and
preexisting collisions, constant errors, held-key limits, uncertain down/up
outcomes, partial cleanup and retry order. Six new native Go race tests verify
owned modifier cleanup, preservation of an already-held key from another
synthetic client, US/German map replacement, Num Lock changes, unsupported-group
and shift-only-symbol rejection, and lock-key refusal. They inspect server key
state, not application command delivery or hardware behavior.
The new native harness, existing ten-experiment/six-native-test feasibility
harness, input/wire/Xorg race suites, focused host keyboard/lifecycle race tests,
external Remote race suite, affected-package vet, a separate reader build,
the existing speech regression harness and Tentacles `make check` passed.
No full reader suite, installed-binary behavior,
audible speech, physical input/Braille or live NVDA/Orca acceptance was performed.