Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a03397-4d51-7fd1-8ff2-946eb22ea2bc
This commit is contained in:
parent
2009d01ae4
commit
452235a01f
6 changed files with 133 additions and 8 deletions
|
|
@ -85,6 +85,9 @@ The tap observes this complete line and queues the same durable route as
|
||||||
`#repo:` is therefore an agent/tap convention, not a shell command—at an
|
`#repo:` is therefore an agent/tap convention, not a shell command—at an
|
||||||
ordinary shell it remains a comment. Existing windows are never respawned, so
|
ordinary shell it remains a comment. Existing windows are never respawned, so
|
||||||
recreate a session that was originally started without pushy observation.
|
recreate a session that was originally started without pushy observation.
|
||||||
|
Terminal protocol replies and local backspace editing are removed only from
|
||||||
|
tamq's observation copy, so strict routing remains reliable in TUIs such as
|
||||||
|
Codex while the wrapped program still receives the original byte stream.
|
||||||
|
|
||||||
The submitted target line is sanitized, sender-labelled, deliberately
|
The submitted target line is sanitized, sender-labelled, deliberately
|
||||||
non-routable, and then followed by exactly one Enter key:
|
non-routable, and then followed by exactly one Enter key:
|
||||||
|
|
|
||||||
2
SCOPE.md
2
SCOPE.md
|
|
@ -98,7 +98,7 @@ Not yet suitable:
|
||||||
and stronger process-supervision evidence.
|
and stronger process-supervision evidence.
|
||||||
- Cross-host messaging or use as a general-purpose broker.
|
- Cross-host messaging or use as a general-purpose broker.
|
||||||
|
|
||||||
The suite currently has 120 passing tests and 77% statement coverage. Coverage
|
The suite currently has 123 passing tests and 77% statement coverage. Coverage
|
||||||
is strongest in durable storage and registry handling, and weakest in the PTY
|
is strongest in durable storage and registry handling, and weakest in the PTY
|
||||||
tap and CLI orchestration; PTY statement coverage increased from 23% to 33%,
|
tap and CLI orchestration; PTY statement coverage increased from 23% to 33%,
|
||||||
while subprocess behavior is primarily proven by the real-tmux test. The
|
while subprocess behavior is primarily proven by the real-tmux test. The
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
| Kind | ID | Status | Lane | Source |
|
| Kind | ID | Status | Lane | Source |
|
||||||
| --- | --- | --- | --- | --- |
|
| --- | --- | --- | --- | --- |
|
||||||
| workplan | TAMQ-WP-ADHOC-2026-08-24 | finished | — | workplans/ADHOC-2026-08-24.md |
|
| workplan | TAMQ-WP-ADHOC-2026-08-24 | finished | — | workplans/ADHOC-2026-08-24.md |
|
||||||
|
| workplan | TAMQ-WP-ADHOC-2026-08-25 | active | — | workplans/ADHOC-2026-08-25.md |
|
||||||
| workplan | TAMQ-WP-0001 | finished | — | workplans/TAMQ-WP-0001-statehub-bootstrap.md |
|
| workplan | TAMQ-WP-0001 | finished | — | workplans/TAMQ-WP-0001-statehub-bootstrap.md |
|
||||||
| workplan | TAMQ-WP-0002 | active | — | workplans/TAMQ-WP-0002-coordination-engine-adapter.md |
|
| workplan | TAMQ-WP-0002 | active | — | workplans/TAMQ-WP-0002-coordination-engine-adapter.md |
|
||||||
| workplan | TAMQ-WP-0003 | active | — | workplans/TAMQ-WP-0003-delivery-reliability.md |
|
| workplan | TAMQ-WP-0003 | active | — | workplans/TAMQ-WP-0003-delivery-reliability.md |
|
||||||
|
|
@ -21,6 +22,7 @@
|
||||||
| workplan | TAMQ-WP-0010 | finished | — | workplans/TAMQ-WP-0010-experimental-pushy-delivery.md |
|
| workplan | TAMQ-WP-0010 | finished | — | workplans/TAMQ-WP-0010-experimental-pushy-delivery.md |
|
||||||
| workplan | TAMQ-WP-0011 | finished | — | workplans/TAMQ-WP-0011-hash-routing-for-pushy-agents.md |
|
| workplan | TAMQ-WP-0011 | finished | — | workplans/TAMQ-WP-0011-hash-routing-for-pushy-agents.md |
|
||||||
| task | TAMQ-WP-ADHOC-2026-08-24-T01 | done | — | workplans/ADHOC-2026-08-24.md |
|
| task | TAMQ-WP-ADHOC-2026-08-24-T01 | done | — | workplans/ADHOC-2026-08-24.md |
|
||||||
|
| task | TAMQ-WP-ADHOC-2026-08-25-T01 | progress | — | workplans/ADHOC-2026-08-25.md |
|
||||||
| task | TAMQ-WP-0001-T01 | done | — | workplans/TAMQ-WP-0001-statehub-bootstrap.md |
|
| task | TAMQ-WP-0001-T01 | done | — | workplans/TAMQ-WP-0001-statehub-bootstrap.md |
|
||||||
| task | TAMQ-WP-0001-T02 | done | — | workplans/TAMQ-WP-0001-statehub-bootstrap.md |
|
| task | TAMQ-WP-0001-T02 | done | — | workplans/TAMQ-WP-0001-statehub-bootstrap.md |
|
||||||
| task | TAMQ-WP-0001-T03 | done | — | workplans/TAMQ-WP-0001-statehub-bootstrap.md |
|
| task | TAMQ-WP-0001-T03 | done | — | workplans/TAMQ-WP-0001-statehub-bootstrap.md |
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ from __future__ import annotations
|
||||||
import fcntl
|
import fcntl
|
||||||
import os
|
import os
|
||||||
import pty
|
import pty
|
||||||
|
import re
|
||||||
import select
|
import select
|
||||||
import signal
|
import signal
|
||||||
import sys
|
import sys
|
||||||
|
|
@ -13,6 +14,35 @@ from collections.abc import Callable, Sequence
|
||||||
from .broker import InputBroker
|
from .broker import InputBroker
|
||||||
|
|
||||||
|
|
||||||
|
ENHANCED_ENTER = re.compile(
|
||||||
|
rb"\x1b(?:\[13(?:;[0-9:]+)*u|\[27;[0-9:]+;13~|OM)"
|
||||||
|
)
|
||||||
|
TERMINAL_INPUT_SEQUENCE = re.compile(
|
||||||
|
rb"\x1b(?:"
|
||||||
|
rb"\[[0-?]*[ -/]*[@-~]"
|
||||||
|
rb"|O."
|
||||||
|
rb"|P.*?(?:\x1b\\)"
|
||||||
|
rb"|\].*?(?:\x07|\x1b\\)"
|
||||||
|
rb")",
|
||||||
|
re.DOTALL,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def observed_line(raw: bytes) -> str:
|
||||||
|
"""Return typed text without terminal replies or local editing controls."""
|
||||||
|
decoded = TERMINAL_INPUT_SEQUENCE.sub(b"", raw).decode(
|
||||||
|
"utf-8", errors="replace"
|
||||||
|
)
|
||||||
|
text: list[str] = []
|
||||||
|
for character in decoded:
|
||||||
|
if character in ("\b", "\x7f"):
|
||||||
|
if text:
|
||||||
|
text.pop()
|
||||||
|
elif character == "\t" or character >= " ":
|
||||||
|
text.append(character)
|
||||||
|
return "".join(text)
|
||||||
|
|
||||||
|
|
||||||
class PtyTap:
|
class PtyTap:
|
||||||
"""Full-duplex PTY proxy. Input is observed, never rewritten."""
|
"""Full-duplex PTY proxy. Input is observed, never rewritten."""
|
||||||
|
|
||||||
|
|
@ -24,13 +54,19 @@ class PtyTap:
|
||||||
def _observe_input(self, buffer: bytearray, data: bytes) -> None:
|
def _observe_input(self, buffer: bytearray, data: bytes) -> None:
|
||||||
buffer.extend(data)
|
buffer.extend(data)
|
||||||
while True:
|
while True:
|
||||||
delimiters = [index for marker in (b"\r", b"\n") if (index := buffer.find(marker)) >= 0]
|
boundaries = [
|
||||||
if not delimiters:
|
(index, index + 1)
|
||||||
|
for marker in (b"\r", b"\n")
|
||||||
|
if (index := buffer.find(marker)) >= 0
|
||||||
|
]
|
||||||
|
if match := ENHANCED_ENTER.search(buffer):
|
||||||
|
boundaries.append(match.span())
|
||||||
|
if not boundaries:
|
||||||
return
|
return
|
||||||
index = min(delimiters)
|
start, end = min(boundaries)
|
||||||
raw = bytes(buffer[:index])
|
raw = bytes(buffer[:start])
|
||||||
del buffer[: index + 1]
|
del buffer[:end]
|
||||||
line = raw.decode("utf-8", errors="replace")
|
line = observed_line(raw)
|
||||||
routed = self.broker.inspect_line(line)
|
routed = self.broker.inspect_line(line)
|
||||||
if routed and self.on_line:
|
if routed and self.on_line:
|
||||||
self.on_line(line)
|
self.on_line(line)
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import pty
|
||||||
import struct
|
import struct
|
||||||
import termios
|
import termios
|
||||||
|
|
||||||
from tamq.ptytap import PtyTap, copy_winsize, write_all
|
from tamq.ptytap import PtyTap, copy_winsize, observed_line, write_all
|
||||||
|
|
||||||
|
|
||||||
class RecordingBroker:
|
class RecordingBroker:
|
||||||
|
|
@ -29,6 +29,48 @@ def test_input_observer_accepts_raw_terminal_carriage_returns():
|
||||||
assert observed == ["#activity-core: hello"]
|
assert observed == ["#activity-core: hello"]
|
||||||
|
|
||||||
|
|
||||||
|
def test_input_observer_accepts_enhanced_terminal_enter_sequences():
|
||||||
|
broker = RecordingBroker()
|
||||||
|
observed = []
|
||||||
|
tap = PtyTap(["true"], broker, on_line=observed.append)
|
||||||
|
buffer = bytearray()
|
||||||
|
|
||||||
|
tap._observe_input(buffer, b"#activity-core: CSI-u\x1b[13;1")
|
||||||
|
assert broker.lines == []
|
||||||
|
tap._observe_input(buffer, b":1u#other: modify\x1b[27;1;13~")
|
||||||
|
tap._observe_input(buffer, b"plain\x1bOM")
|
||||||
|
|
||||||
|
assert broker.lines == [
|
||||||
|
"#activity-core: CSI-u",
|
||||||
|
"#other: modify",
|
||||||
|
"plain",
|
||||||
|
]
|
||||||
|
assert observed == ["#activity-core: CSI-u", "#other: modify"]
|
||||||
|
|
||||||
|
|
||||||
|
def test_input_observer_ignores_terminal_replies_before_typed_line():
|
||||||
|
broker = RecordingBroker()
|
||||||
|
observed = []
|
||||||
|
tap = PtyTap(["true"], broker, on_line=observed.append)
|
||||||
|
buffer = bytearray()
|
||||||
|
|
||||||
|
tap._observe_input(buffer, b"\x1b[9;1R\x1b[?1;2;4c")
|
||||||
|
tap._observe_input(buffer, b"#activity-core: Helol\x7f\x7flo\r")
|
||||||
|
|
||||||
|
assert broker.lines == ["#activity-core: Hello"]
|
||||||
|
assert observed == ["#activity-core: Hello"]
|
||||||
|
|
||||||
|
|
||||||
|
def test_observed_line_removes_common_terminal_protocol_wrappers():
|
||||||
|
raw = (
|
||||||
|
b"\x1b[200~#target: pasted\x1b[201~"
|
||||||
|
b"\x1b]10;rgb:ffff/ffff/ffff\x07"
|
||||||
|
b"\x1bP1$r0m\x1b\\"
|
||||||
|
)
|
||||||
|
|
||||||
|
assert observed_line(raw) == "#target: pasted"
|
||||||
|
|
||||||
|
|
||||||
def test_copy_winsize_preserves_rows_columns_and_pixels():
|
def test_copy_winsize_preserves_rows_columns_and_pixels():
|
||||||
source_master, source_slave = pty.openpty()
|
source_master, source_slave = pty.openpty()
|
||||||
target_master, target_slave = pty.openpty()
|
target_master, target_slave = pty.openpty()
|
||||||
|
|
|
||||||
42
workplans/ADHOC-2026-08-25.md
Normal file
42
workplans/ADHOC-2026-08-25.md
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
---
|
||||||
|
id: TAMQ-WP-ADHOC-2026-08-25
|
||||||
|
type: workplan
|
||||||
|
title: "Recognize enhanced terminal submission keys"
|
||||||
|
domain: communication
|
||||||
|
repo: tmux-amq
|
||||||
|
status: finished
|
||||||
|
owner: codex
|
||||||
|
topic_slug: coulomb-social
|
||||||
|
created: "2026-08-25"
|
||||||
|
updated: "2026-08-25"
|
||||||
|
---
|
||||||
|
|
||||||
|
# Recognize enhanced terminal submission keys
|
||||||
|
|
||||||
|
## Decode Codex TUI line submission in the PTY tap
|
||||||
|
|
||||||
|
```task
|
||||||
|
id: TAMQ-WP-ADHOC-2026-08-25-T01
|
||||||
|
status: done
|
||||||
|
priority: high
|
||||||
|
```
|
||||||
|
|
||||||
|
Reproduce the missing `#repo:` route with a real isolated Codex TUI, extend
|
||||||
|
input observation to recognize enhanced terminal Enter encodings without
|
||||||
|
rewriting pane input, add regression and real-Codex smoke evidence, install the
|
||||||
|
fix, and update the operator documentation.
|
||||||
|
|
||||||
|
## Completion evidence
|
||||||
|
|
||||||
|
- Reproduced the failure with two isolated real Codex 0.149.1 panes: Codex
|
||||||
|
submitted the source line but no durable message was created.
|
||||||
|
- Raw input capture showed CSI cursor/device replies preceding the typed route;
|
||||||
|
these contaminated the tap's observation buffer before the terminating CR.
|
||||||
|
- The observer now removes terminal protocol sequences and applies local
|
||||||
|
backspace editing only to its parsing copy while forwarding source bytes
|
||||||
|
unchanged.
|
||||||
|
- A network-disabled two-Codex rerun created one durable `#audit-core:` message,
|
||||||
|
transitioned it to `injected`, and showed the `# from flex-auth:` prompt in
|
||||||
|
the target's queued follow-up inputs.
|
||||||
|
- Full checks and installed-package verification passed. No user session or
|
||||||
|
durable user message was changed during diagnosis.
|
||||||
Loading…
Add table
Add a link
Reference in a new issue