Enable isolated Remote speech and protect reading exports

Attach incoming software speech to reader sessions with lease checks, local output priority and isolated cancellation. Preserve every document fragment source for privacy checks and export reviewed browse current-line reading, spelling and phonetic output.

Verified focused reading and Remote race tests, complete review and external Remote race suites, private relay integration, speech regressions, affected-package vet, reader build and Tentacles make check. Audible speech, physical input/Braille and live interoperability remain unverified.
This commit is contained in:
ak47 committed 2026-11-05 15:41:08 -05:00
1 parent ac67236eca
commit 49be8309fe
27 files changed
+986 -54

No files matched your search

+120 -10
View File
@@ -2,9 +2,10 @@
Typed speech IPC now includes an explicit reader-owned incoming mailbox and
limited production observation of accessibility-event and document-reading speech. The
external coordinator connects this IPC to relay speech. Incoming speech still
has no production presentation owner and does not make Remote speak. Atomic
assembly of split incoming utterances precedes owner admission.
external coordinator connects this IPC to relay speech. Production software
sessions now attach an isolated incoming owner with lease, focus and local-output
policy. Atomic assembly of split incoming utterances precedes owner admission.
Private tests establish protocol delivery; audible acceptance remains pending.
Original base reader revision: `4f9b89e`
on `testing`; matching Tentacles base: `0c74038` on `master`, plus the pending
connection-command changes. No active or installed reader was replaced.
@@ -97,10 +98,31 @@ in an assembled line must have a known role and no password ancestry. Say All
classifies all spoken lines before admission; a sensitive or unclassified line
keeps the entire batch private, including sentence-mode continuations. Local
navigation failures stay private. Derived phonetic hints retain their parent's
origin and original observation ticket. Flat/object review, current-line commands,
origin and original observation ticket. Flat/object review, native current-line commands,
reading-context announcements, separate key-name echo and notification paths
still need explicit source and sensitivity review.
Visual-line assembly now retains each contributing object's complete captured
ancestry in `DocumentLine.SourceContexts`, independently of the caret object's
presentation context. Caret-line speech checks these sources, and Say All keeps
them when flattening fragments into a single spoken string. A password source,
password ancestor, unknown role or failed context lookup keeps the whole line
private; a sensitive Say All line keeps its entire batch private. Missing source
metadata does not prevent local reading. These checks do not opt flat/object
review into export.
Browse-mode current-line reporting, spelling and phonetic spelling now export
only with the command's captured source ancestry. The review worker retains
that ancestry from the tree producing the final movement, including after
recapture. Every source role must be known; password sources/ancestors, missing
or stale ancestry and sensitive neighboring fragments keep the report private.
Classification does not add context announcements or change local reading,
caret position, focus or Braille. Spelling retains repeated letters, character
state and phonetic expansion through the existing speech owner, with its original
lease/generation ticket and pronunciation policy. Errors remain private. Native
focused-line reads lack complete ancestry and remain private even when a supplied
snapshot appears ordinary.
Say All exports each resolved chunk immediately before its completion-paced
backend call. Sentence boundaries, pronunciation and the original request's
lease/generation are retained. A lease replacement during reading cannot export
@@ -126,15 +148,16 @@ independently. This atomic IPC admission is not atomic relay or NVDA delivery.
User/input interruption and mode/enable changes publish cancel through the same
speech-owner mutex as observed utterances. An older delivery generation cannot
publish behind that cancel. Remote publication never performs pipe, relay or
backend I/O in the input loop. Incoming cancellation ownership remains pending.
backend I/O in the input loop. Incoming cancellation uses the isolated owner
described below.
The source command now offers an explicit Return to desktop action after its
reader lease opens. It closes status and releases local input capture while the
original lease and heartbeat worker remain active. The Remote shortcut reopens
status/Disconnect. Lock/handoff, expiry and process loss still revoke the lease.
See [the terminal interaction contract](tentacle-sessions.md#reader-owned-consent-interactions).
Incoming speech ownership and live acceptance remain pending; relay-testing
warnings remain in place.
Production incoming software ownership is described below; experimental-speech
warnings remain in place pending live acceptance.
## Verification and remaining work
@@ -279,6 +302,53 @@ ownership and cancellation, without audible speech or real server scheduling.
Production mailbox attachment, local output priority, physical input and live
NVDA/Orca acceptance remain pending.
### Production incoming owner and local priority
Both local-launch and managed-session startup now attach one incoming owner when
`remote-present`, the reader availability policy, focus gate and configured
software speaker are present. Its lifecycle watcher joins cleanup on session
revocation or reader shutdown. It creates no synthesis connection until accepted
speech needs one. Hardware acquisition fails closed and retires the original
lease; no hardware device is opened by the incoming owner.
Every delivery and synthesis handoff rechecks the original process-owned lease
with `remote-present`, its deadline/context, lock/handoff, internal-form capture,
speech enable and speech mode. Denied work is discarded. Local pending/active
requests and the interruption barrier also deny new speech admission. Incoming
text bypasses local history and observation entirely; remote cancel/pause affects
only its isolated speaking client. Backend failures retire only the failing
lease epoch. Cleanup completes before the renderer starts speech under fresh
consent; a stale failure cannot revoke a replacement approval.
Local speech admission or interruption synchronously retires incoming admission
tickets. Active remote rendering cancels; older queued work is discarded without
replay. The first frame of an IPC assembly receives a reader-owned monotonic
admission timestamp. Local output records a cutoff, so an assembly or mailbox
item accepted before that output cannot acquire a fresh ticket when dequeued
later. The local-generation check is synchronous even before its asynchronous
cancellation callback runs. Mailbox budget remains retained through cleanup.
Speech accepted after the cutoff may proceed once local queue policy permits.
Ordinary software speech returns at queue acknowledgement, not audio completion.
The isolated client therefore sets SSIP `TEXT` before speaking; local reader
clients retain `MESSAGE`. Under the [SSIP priority contract](https://github.com/brailcom/speechd/blob/master/doc/ssip.texi),
TEXT waits behind MESSAGE, and a new MESSAGE cancels older TEXT output. The
relay's normal/NEXT/NOW values only order remote work and cannot raise its SSIP
priority. A server cancellation discards the current assembly and its suffix;
it does not itself revoke consent. Failed priority setup closes the candidate.
This establishes the requested protocol policy, not real-server scheduling or
audible priority acceptance. Other applications using TEXT priority can also
cancel remote output. Pause and priority retain the limited discard semantics
of the stream prerequisite; there is no replay or resume parity.
Private source-command/TLS/SSIP checks exercise complete multilingual spelling
and language output after Return to desktop, and cancel active synthesis on
Disconnect, lock, handoff and disable. Focused tests cover local announcements,
interruption, speech modes, disable/secure input, old mailbox/assembly cutoffs,
rejected local results, backend priority rejection and server cancellation.
Physical local approval, audible output, real Speech Dispatcher scheduling,
Braille and NVDA/Orca interoperability remain separate acceptance gates.
### Automated evidence
For the isolated synthesis prerequisite, focused application/backend race checks
@@ -345,9 +415,49 @@ host/wire/both-SDK race suites (host: about 127 seconds), focused application
speech/Remote/Tentacle race checks, affected-package vet, a separate reader
build, the existing speech regression harness and Tentacles `make check`.
Next: attach the stream owner to production sessions with delivery-time
policy and local output priority. Explicit status detachment is implemented; physical
input capture/release and ordinary reading while connected still need acceptance.
The production incoming-owner increment passed ten repetitions of its focused
Remote speech/source-command race cases, the complete speech-backend and
host/wire/both-SDK race suites (host: about 128 seconds), shared application
speech/Tentacle race regressions, the existing speech regression harness,
affected-package vet, a separate reader build and Tentacles `make check`.
Backend failure coverage also verifies explicit status close and a fresh setup
workflow without restarting the process. No full reader suite or live acceptance
was performed.
The subsequent fragment-privacy review adds a real accessibility-tree regression
with an ordinary caret and a neighboring password descendant on the same visual
row. Running that regression against the previous classifier with a Go source
overlay reproduced export admission; the corrected classifier denies it.
Presentation/SDK tests cover password sources, password ancestry, unknown roles,
missing contexts and unchanged local reading. Review tests retain every source
through Say All flattening and preserve local text after ancestry becomes stale.
The source-command/private-relay fixture also checks private joined caret/Say All
output never reaches relay speech frames.
Verification for this review passed: the complete AT-SPI/review race suites,
focused application Remote/speech/document/caret/current-line/flat/object-review
race regressions, ten repetitions of the document privacy race cases,
source-command/private-relay race checks, the speech regression harness, vet for
the affected packages, a separate reader build in `/tmp`, and Tentacles
`make check`. The repository check now includes document/Say All observation
regressions. Native/hardware checks and the full reader suite were not run for
this review. Physical input, audible speech, physical Braille and real
NVDA/Orca interoperability remain unverified.
The browse current-line increment passed focused application/input reading and
Remote race regressions, the complete review and external Remote race suites,
the existing speech regression harness, affected-package vet, a separate reader
build and Tentacles `make check`. The new tests cover source/neighbor privacy,
native and error exclusion, recaptured ancestry, unchanged local text after
context invalidation, pronunciation, repeated-letter character spelling, phonetic
spelling and blank lines. The source-command/private-relay fixture exports an
ordinary report and rejects a private joined neighbor. No full reader suite,
native desktop, hardware or audible acceptance was performed for this increment.
See [the live test steps](../../cthulhu-tentacles/remote/command.md#physical-keyboard-acceptance-still-pending).
Next: verify real Speech Dispatcher scheduling and audible local/remote
arbitration. Physical input capture/release and ordinary reading while connected
still need acceptance.
Review the remaining output producers before assigning exportable origins.
Atomic IPC assembly is implemented; it does not establish backend
priority/cancel behavior or audible delivery.