orca/config
Jinwoo Hong d15939c5fd
fix(terminal): recover rejected paired-runtime input (STA-2830) (#12675)
With a desktop client paired to a remote Orca runtime, terminal panes could report connected, writable, and `terminal.send` returning accepted — yet keystrokes never reached the agent. No error, no banner, no recovery; input silently vanished.

The ticket was really two bugs. The attach half was already fixed by #12589 (subscriber-driven daemon attach), confirmed by reproducing against current main. This fixes the remaining half: a write the host refuses had no way to tell anyone.

A capability-negotiated `WriteUnavailable` opcode carries that refusal back to the client, where it feeds the pane's pre-existing recovery hook. Capability gating matters because decoders reject unknown opcodes on desktop — and, worse, silently drop them on mobile — so the signal is negotiated in the subscribe handshake. Verified per direction: an old host strips the unknown Subscribe key, an old client omits it so the host never emits, and capability cannot be inherited across resubscribe.

Independent review then found the signal was being delivered and discarded: recovery demanded an authoritative liveness answer, and `pty:hasPty` had no `remote:` guard, so a paired pane's id fell through to the LOCAL provider, which returned false, and recovery bailed before remounting. Every test stopped at the transport boundary, so all of them passed while the pane stayed just as stuck. `pty:kill` already had exactly that guard.

The fix makes main answer LESS rather than claim more: `pty:hasPty` now returns unknown for a `remote:` id instead of a fabricated false, because main cannot speak for another host's PTY. The remount is then authorized by positive evidence — the process that owns the PTY stating it refused this specific write over a live negotiated connection — not by inference from silence. Local and app-SSH ids keep the probe, where a false genuinely means the shell died. Nothing is destroyed on this path; the remount rebuilds the renderer over the session it already had.

An end-to-end test now carries a rejected write from the host through to an actual remount, which no prior test did. A surviving mutant was also killed: the legacy-binary capability gate could previously be deleted with nothing turning red.

The reliability gate stays experimental — live paired journeys and mixed installed-release evidence remain uncollected. Fixes STA-2830.
2026-08-05 01:41:27 -07:00
..
docker/headless-pairing Fix headless Linux serve pairing readiness (#9785) 2026-07-21 18:23:20 -07:00
nsis fix(windows): separate updater from orchestration migration (#11405) 2026-07-29 15:23:06 -07:00
oxlint-plugins perf(lint): consolidate code-quality gates into Oxlint (#11117) 2026-07-28 00:21:13 -07:00
patches Fix terminal corruption after restored snapshot replay (#12363) 2026-08-03 20:00:28 -07:00
relay-assets fix(ssh): patch node-pty helper in Windows relay (#9638) 2026-07-20 19:09:18 -07:00
scripts feat(updater): restart hourly build numbers per version, restyle the timestamp (#12587) 2026-08-04 15:54:17 -07:00
dev-app-update.yml chore: move dev-app-update.yml into config/ (#1276) 2026-04-30 00:11:14 -07:00
electron-builder.config.cjs feat(updater): add an adhoc release channel for branch builds (#12051) 2026-08-02 01:46:51 -07:00
electron-vite-target.config.ts ci: parallelize PR checks and accelerate Vite builds (#10989) 2026-07-27 13:32:29 -07:00
i18n-translation-source.md docs(i18n): adopt gettext PO as the canonical translation source (#11478) 2026-07-31 11:46:25 -07:00
i18next.config.ts chore: declutter top-level repo layout (#11890) 2026-08-01 00:25:35 -07:00
knip.json Keep the app responsive when security software slows process creation (#12217) 2026-08-04 02:03:40 -07:00
localization-audit.md docs(i18n): adopt gettext PO as the canonical translation source (#11478) 2026-07-31 11:46:25 -07:00
localization-coverage-allowlist.json fix(ci): mirror missing lint steps in PR workflow (#10601) (#10623) 2026-07-27 16:26:43 -07:00
max-lines-baseline.txt chore(mobile): import the shared marine-creature corpus instead of mirroring it (#12090) 2026-08-02 01:44:03 -07:00
oxlint-code-quality-native-plugins.json perf(lint): consolidate code-quality gates into Oxlint (#11117) 2026-07-28 00:21:13 -07:00
oxlint-code-quality-type-aware.json perf(lint): consolidate code-quality gates into Oxlint (#11117) 2026-07-28 00:21:13 -07:00
oxlint-react-doctor.json chore(quality): ratchet Oxlint, React Doctor, and Zustand performance (#11034) 2026-07-27 18:58:36 -07:00
packaged-runtime-node-modules.cjs fix(packaging): prune non-target native binaries (#12174) 2026-08-03 10:54:00 -07:00
reliability-gates.jsonc fix(terminal): recover rejected paired-runtime input (STA-2830) (#12675) 2026-08-05 01:41:27 -07:00
tsconfig.cli.json Fix packaged skills CLI runtime ownership (#11627) 2026-07-30 18:27:16 -07:00
tsconfig.node.json fix(skills): stop calling the updater's own install a modified copy (#11249) 2026-07-28 17:27:26 -07:00
tsconfig.relay.json Support agent status hooks over SSH (#1865) 2026-05-14 16:06:23 -07:00
tsconfig.tc.cli.json refactor to clean up the codebase (#412) 2026-04-08 22:49:16 -07:00
tsconfig.tc.web.json test(serve): pin zero duplicate agent resumes across headless serve desktop promotion (#12666) 2026-08-05 00:34:10 -07:00
tsconfig.web.json chore: enforce exhaustive switch handling 2026-05-30 13:18:12 -07:00
vitest.config.ts test(env): keep happy-dom MutationObserver callbacks alive across GC (#12438) 2026-08-03 23:18:15 -07:00