mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-11-14 10:39:32 +01:00
fix: apply the review items for #694 at merge
- src/web/routes/session-routes.ts:2102: the guarded-submit 409 now applies to tagged input (clientId + seq) only; untagged input is held like a WebSocket frame. The raw write (:2228) goes through holdForGuardedLease and answers 200 once held (a send-and-wait reads `delivered` from the held write; a full queue releases the waiter and answers 409); a mux write takes its own turn in writeViaMux. - test/guarded-lease-held-input.test.ts: real-Session route tests for an untagged raw POST during the lease (written after the Enter) and a held send-and-wait (delivered: true); both fail without the fix. - test/routes/session-routes.test.ts + test/mocks/mock-session.ts: the 409 test now covers tagged input only; new tests for untagged raw (held), untagged mux (own turn) and a full hold queue (409); MockSession gains holdForGuardedLease/releaseGuardedLease and a lease-aware writeViaMux. - src/session.ts:4787 (guardedInputHeld JSDoc) + write() + docs/architecture-invariants.md: write() refuses during the lease only, so cron's paste mode can land ahead of input still draining. - docs/api-reference.md: the input route's 409 is for tagged input; untagged input is held. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
2aad93914e
commit
6368128f1e
7 files changed
+221
-32
No files matched your search
+17
-13
@@ -426,11 +426,12 @@ worker's prompt but never submitted, and the wait then runs its full timeout on
|
||||
turn that never started. Verified live; this is the most common silent failure on
|
||||
this endpoint.
|
||||
|
||||
Any input, waiting or not, answers `409 CONFLICT` with nothing written while an
|
||||
experimental guarded submit holds the session's input lease, or input held behind
|
||||
it is still being written (a few milliseconds; see
|
||||
[guarded input](#experimental-bounded-agent-inspection-and-guarded-input)).
|
||||
Retry it.
|
||||
Input tagged with `clientId` and `seq`, waiting or not, answers `409 CONFLICT`
|
||||
with nothing written while an experimental guarded submit holds the session's
|
||||
input lease, or input held behind it is still being written (a few milliseconds;
|
||||
see [guarded input](#experimental-bounded-agent-inspection-and-guarded-input)).
|
||||
Retry it. Untagged input is held instead and written in arrival order once the
|
||||
lease is released.
|
||||
|
||||
A **plain prompt** (printable text followed by exactly one `\r`, nothing else) is
|
||||
delivered through tmux even without `useMux`: the text is typed, Enter is pressed as
|
||||
@@ -716,15 +717,18 @@ outcome. That covers terminal WebSocket keystrokes (each frame is acknowledged
|
||||
only once it is written, so a frame typed during the lease lands before the one
|
||||
typed after it), Shift+Enter and Ctrl+Enter from `POST .../send-key`, approval
|
||||
answers and Codeman's own managed writes. A held write that is still being sent
|
||||
holds everything behind it. `POST /api/v1/sessions/:id/input` instead answers
|
||||
`409 CONFLICT` ("A guarded submit is in progress on this session; nothing was
|
||||
written") for that span, the lease plus the held input's drain, rather than a
|
||||
`200` for bytes that were never written; a tagged `clientId`/`seq` frame keeps
|
||||
its seq, so the browser's durable queue, whose POST fallback sends one frame at a
|
||||
time and keeps it on a `409`, delivers it on the next retry. A lease holds at
|
||||
most 256 inputs or 1 MiB; past that a WebSocket is closed with code `1013` and
|
||||
holds everything behind it. A tagged `POST /api/v1/sessions/:id/input` (one
|
||||
carrying `clientId` and `seq`) instead answers `409 CONFLICT` ("A guarded submit
|
||||
is in progress on this session; nothing was written") for that span, the lease
|
||||
plus the held input's drain, rather than a `200` for bytes that were never
|
||||
written; it keeps its seq, so the browser's durable queue, whose POST fallback
|
||||
sends one frame at a time and keeps it on a `409`, delivers it on the next retry.
|
||||
Untagged input to that route is held like a WebSocket frame, because its senders
|
||||
(the phone accessory keys, the Stop button) never read the answer. A lease holds
|
||||
at most 256 inputs or 1 MiB; past that a WebSocket is closed with code `1013` and
|
||||
nothing later from it is applied, so the browser reconnects and resends every
|
||||
unacknowledged frame in order, and `send-key` answers `409 CONFLICT`.
|
||||
unacknowledged frame in order, and `send-key` and an untagged raw input answer
|
||||
`409 CONFLICT`.
|
||||
|
||||
Direct auxiliary key operations participate in the same pending-write and input
|
||||
lease checks. Complete allowlisted focus/mouse reports and empty writes preserve
|
||||
|
||||
Reference in new issue
Block a user