feat: add hash routing for pushy agents
Some checks failed
tamq-ci / test (push) Failing after 6s

Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a03397-4d51-7fd1-8ff2-946eb22ea2bc
This commit is contained in:
tegwick 2026-08-25 00:08:57 +02:00
parent 00f04da5f6
commit e284c9f63c
16 changed files with 233 additions and 49 deletions

View file

@ -71,19 +71,36 @@ input. It is intended for coding-agent interfaces that queue user prompts:
tamq --mode pushy --command codex flex-auth audit-core
```
The submitted line is sanitized and sender-labelled, then followed by exactly
one Enter key:
For newly created windows with an explicit command, pushy mode automatically
places that command behind tamq's transparent PTY tap. Inside the coding-agent
input, use `#repo:` to avoid interfaces that reserve `@` for file mentions or
templates:
```text
#flex-auth: please review the auth boundary [m-...]
#audit-core: Please review the authentication change.
```
This leading `#` makes an empty ordinary shell prompt treat the line as a
comment. Pushy mode cannot determine whether a pane is an agent, a shell, or
whether someone is already editing input: it can append to that input and
submit the combined line. Use it only for panes whose occupant is known to
accept or queue asynchronous prompts. Switching an existing endpoint to pushy
may also submit pending messages that have never been displayed.
The tap observes this complete line and queues the same durable route as
`@audit-core: ...`; it forwards the source input unchanged to its occupant.
`#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
recreate a session that was originally started without pushy observation.
The submitted target line is sanitized, sender-labelled, deliberately
non-routable, and then followed by exactly one Enter key:
```text
# from flex-auth: please review the auth boundary [m-...]
```
The `# from` shape cannot match the outbound `#repo:` grammar, preventing a
tapped recipient from bouncing the message back. Its leading `#` also makes an
empty ordinary shell prompt treat the line as a comment. Pushy mode cannot
determine whether a pane is an agent, a shell, or whether someone is already
editing input: it can append to that input and submit the combined line. Use it
only for panes whose occupant is known to accept or queue asynchronous prompts.
Switching an existing endpoint to pushy may also submit pending messages that
have never been displayed.
## Exchange messages manually
@ -227,7 +244,7 @@ later phase.
2. the local broker assigns endpoint/source identity and durably queues intent;
3. Explicit `tamq tap` mode is a full-duplex PTY proxy around a command. It forwards
bytes unchanged in raw terminal mode, propagates terminal resize and lifecycle
signals, and observes complete input lines for `@repo:` routing.
signals, and observes complete input lines for `@repo:`/`#repo:` routing.
This keeps tmux-specific topology concerns separate from reusable terminal I/O
observation and message identity.
@ -237,10 +254,11 @@ the target pane's PTY output and stays pending in the durable inbox until
acknowledged. `--mode inbox` selects inbox-only manual mode. Neither becomes
pane input. Experimental `--mode pushy` sends one checked tmux command list
containing sanitized literal input followed by Enter, then records the message
as `injected`. The older full-duplex pane-input path remains available only
with the explicit `tamq start --tap --command ...` opt-in. Both input paths
remain subject to the retry and acknowledgement limitations tracked by
`TAMQ-WP-0003`.
as `injected`. When pushy mode creates explicitly commanded windows, the same
PTY tap observes outbound `@repo:` and `#repo:` lines without rewriting them.
The older pane-delivery experiment remains available only with the explicit
`tamq start --tap --command ...` opt-in. Both input paths remain subject to the
retry and acknowledgement limitations tracked by `TAMQ-WP-0003`.
The visible endpoint label is `tmux-amq-<PID>`; each boot also receives an
instance nonce so PID reuse cannot collide with prior leases or receipts.