fix(control): prevent ambiguous mutation replay (#2596)

Propagate accept-thread startup errors and remove the key file. Keep image exports from being retried and continue stdio after invalid UTF-8.

Co-Authored-By: Codex <noreply@openai.com>
This commit is contained in:
vangel76
2026-10-31 22:12:18 +01:00
co-authored by Codex
parent 837d2b0748
commit 0e7dc8da53
7 changed files with 238 additions and 32 deletions
+17
View File
@@ -1,5 +1,7 @@
# Control protocol
> **Last updated:** 2026-10-31 · #2596: accept-thread startup failure disables the server and removes its key file; MCP retry policy distinguishes file exports from in-memory images.
Start the app with a control port: `wordcraft --control 7981` (or `WORDCRAFT_CONTROL_PORT=7981`).
A missing or invalid port after `--control` (not 1–65535) prints an error and exits with status 2.
It listens on `127.0.0.1` only. Send one JSON object per line, with the window's key (see
@@ -50,6 +52,21 @@ any other host it sends no key, says so, and the app refuses its requests: to dr
another machine, forward its port to `127.0.0.1` (for example `ssh -L 7981:127.0.0.1:7981 host`)
and set `WORDCRAFT_CONTROL_KEY` to that app's key.
## Delivery and startup failures
If the accept thread cannot start, startup reports that the control server is off and removes
its newly written key file; it does not report a listening server. Failure to start a worker
for one connection closes only that connection and releases its admission slot.
The server can accept a complete JSON body at EOF even without a final newline. A client that
encounters a write error must therefore treat delivery as unknown once it has attempted to
send. The MCP bridge does not replay mutations in this case, or image exports with a string
`path`; see [delivery failures](mcp.md#delivery-failures).
A request that times out while still queued is cancelled and cannot run later. If execution
has already started, the timeout reports an unknown outcome rather than promising cancellation.
Unauthenticated connections are limited to 64 while they wait for their first authorised request.
## Methods
| Method | Params | Result |