docs: plan readable duplex messaging
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 16:22:14 +02:00
parent ca4e78ad07
commit 1fd15e3f45
2 changed files with 253 additions and 0 deletions

View file

@ -23,6 +23,7 @@
| workplan | TAMQ-WP-0011 | finished | — | workplans/TAMQ-WP-0011-hash-routing-for-pushy-agents.md |
| workplan | TAMQ-WP-0012 | finished | — | workplans/TAMQ-WP-0012-pushy-feedback-circuit-breaker.md |
| workplan | TAMQ-WP-0013 | finished | — | workplans/TAMQ-WP-0013-emergency-cleanup.md |
| workplan | TAMQ-WP-0014 | ready | — | workplans/TAMQ-WP-0014-readable-duplex-messaging-and-limits.md |
| task | TAMQ-WP-ADHOC-2026-08-24-T01 | done | — | workplans/ADHOC-2026-08-24.md |
| task | TAMQ-WP-ADHOC-2026-08-25-T01 | done | — | workplans/ADHOC-2026-08-25.md |
| task | TAMQ-WP-0001-T01 | done | — | workplans/TAMQ-WP-0001-statehub-bootstrap.md |
@ -73,3 +74,10 @@
| task | TAMQ-WP-0013-T01 | done | — | workplans/TAMQ-WP-0013-emergency-cleanup.md |
| task | TAMQ-WP-0013-T02 | done | — | workplans/TAMQ-WP-0013-emergency-cleanup.md |
| task | TAMQ-WP-0013-T03 | done | — | workplans/TAMQ-WP-0013-emergency-cleanup.md |
| task | TAMQ-WP-0014-T01 | todo | — | workplans/TAMQ-WP-0014-readable-duplex-messaging-and-limits.md |
| task | TAMQ-WP-0014-T02 | wait | — | workplans/TAMQ-WP-0014-readable-duplex-messaging-and-limits.md |
| task | TAMQ-WP-0014-T03 | wait | — | workplans/TAMQ-WP-0014-readable-duplex-messaging-and-limits.md |
| task | TAMQ-WP-0014-T04 | wait | — | workplans/TAMQ-WP-0014-readable-duplex-messaging-and-limits.md |
| task | TAMQ-WP-0014-T05 | wait | — | workplans/TAMQ-WP-0014-readable-duplex-messaging-and-limits.md |
| task | TAMQ-WP-0014-T06 | wait | — | workplans/TAMQ-WP-0014-readable-duplex-messaging-and-limits.md |
| task | TAMQ-WP-0014-T07 | wait | — | workplans/TAMQ-WP-0014-readable-duplex-messaging-and-limits.md |

View file

@ -0,0 +1,245 @@
---
id: TAMQ-WP-0014
type: workplan
title: "Readable duplex messaging, runtime commands, and line limits"
domain: communication
repo: tmux-amq
status: ready
owner: codex
topic_slug: coulomb-social
planning_priority: P0
planning_order: 19
created: "2026-08-25"
updated: "2026-08-25"
---
# Readable duplex messaging, runtime commands, and line limits
Replace the shell-oriented `@`/`#` protocol with a readable `To:`/`From:`
protocol that can originate in either operator input or worker output, add an
operator-only runtime command lane, separate input placement from submission,
and impose session-lifetime per-window message/input/output line budgets.
This is a breaking local-alpha protocol change. It deliberately removes the
old address aliases and changes `pushy` so that submission requires the new
`trigger` mode.
## Required protocol contract
The normalized line grammar is case-sensitive and recognized only at the start
of a logical line:
| Observed source | Line | Effect |
| --- | --- | --- |
| Operator input in `alpha` | `To:beta: Hello!` | Queue one message with operator provenance. |
| Worker output in `alpha` | `To:beta: Hello!` | Queue one message with worker provenance. |
| Delivery of operator message | n/a | Render/inject `From:alpha/o: Hello!`. |
| Delivery of worker message | n/a | Render/inject `From:alpha: Hello!`. |
| Operator input | `Cmd: mode=trigger` | Apply an allowlisted runtime setting and report the result locally. |
| Worker output | `Cmd: mode=trigger` | Ordinary worker output; it must not mutate tamq. |
Recipient names use exact gita-registered repository slugs, with the repository
between the first and second colon and a non-empty message body after it.
Leading separator whitespace is removed from the body. `From:` is delivery
framing only and is never routable. Durable message identity remains metadata
rather than visible protocol text.
The mode contract becomes:
| Mode | Target behavior |
| --- | --- |
| `inbox` | Store durably without changing the target terminal. |
| `output` | Display the `From:` line as terminal output above stable input. |
| `pushy` | Place the `From:` line in the target's input buffer without submitting it. |
| `trigger` | Perform pushy placement and then submit exactly once, as one Enter. |
`output` remains the default. `pushy` and `trigger` remain explicit,
experimental choices because tamq cannot infer the foreground program or the
state of its input buffer.
## Running-limit contract
The service owns one atomic ledger for every repository window in a managed
tmux session. A tap or broker restart must not reset the ledger; a newly created
managed-session generation starts a new ledger. The three independent counters
overlap intentionally:
- `messages`: accepted outbound `To:` lines from either origin in this window;
inbound delivery and rejected attempts do not increment it.
- `input`: complete logical lines submitted by the operator in this window,
including an operator `To:` or `Cmd:` line.
- `output`: complete normalized logical lines emitted by the worker in this
window, including a worker `To:` line.
Tamq-generated `From:tamq:` notices, routed `From:` deliveries, terminal
protocol replies, and display redraw fragments do not increment input or output
counts and cannot feed back into routing. Input and output counts continue to
advance while messaging is blocked; only an explicit reset or a new session
generation clears them.
Defaults are `maxmsg = 8`, `maxin = 1024`, and `maxout = 32768`. They are
positive integer configuration keys and startup options `--maxmsg`, `--maxin`,
and `--maxout`; startup options override configuration. Admission checks the
source window before durable enqueue. Equality blocks: when any relevant count
is already greater than or equal to its limit, no message is created. If more
than one limit is exceeded, report the first in deterministic order:
`messages`, `input`, `output`.
Every blocked attempt produces exactly one local, stable-row notice in the
source terminal:
```text
From:tamq: Messaging blocked! Running linecount XXX limited by MMM lines of messages/input/output in this terminal. Use 'Cmd: reset-limits' to unblock.
```
`XXX`, `MMM`, and the final dimension word are replaced with the applicable
counter, limit, and `messages`, `input`, or `output`. `Cmd: reset-limits`
atomically resets all three counters for the current source window only.
## Resolve PTY attribution and line semantics
```task
id: TAMQ-WP-0014-T01
status: todo
priority: critical
```
Capture real shell and coding-agent PTY traffic and define one terminal-neutral
normalization boundary for logical input and output lines. Demonstrate that a
worker-rendered `To:` row can be observed once through ANSI redraws, while an
operator `To:` line echoed or repainted by the worker cannot be misclassified
as a second worker message. Correlate exact recent operator-line fingerprints,
deduplicate stable output row transitions, and fail closed when provenance is
ambiguous. Preserve raw byte forwarding, geometry, mouse behavior, cursor
state, and alternate-screen behavior.
This is the feasibility gate for the workplan. Generic PTYs do not inherently
label output as program-authored versus echoed input; do not replace that
missing signal with coding-agent-specific assumptions. Record the accepted
line/echo boundary and fixtures before routing worker output.
## Replace routing grammar and persist provenance
```task
id: TAMQ-WP-0014-T02
status: wait
priority: critical
```
After T01, implement one parser and event model for operator-input and
worker-output `To:` lines. Validate exact recipients, store an explicit
`operator_input` or `worker_output` provenance value with every durable
message, and render the corresponding `From:sender/o:` or `From:sender:` line.
Make `From:` non-routable at tap and broker boundaries. Remove `@`, `@repo:`,
bare-`@` composer, latest-counterparty shorthand, `#repo:`, and their generated
shims rather than retaining hidden aliases.
Cover punctuation, UTF-8, whitespace, malformed/missing recipients, unknown
repos, multiline normalization, exact origin attribution, output redraw
deduplication, echo suppression, and feedback-chain containment.
## Separate pushy placement from trigger submission
```task
id: TAMQ-WP-0014-T03
status: wait
priority: high
```
Redefine `pushy` as literal input-buffer placement without Enter and add
`trigger` as the same sanitized placement followed by exactly one Enter.
Retain `inbox` and stable terminal `output` behavior. Carry provenance framing
unchanged through every mode, expose the selected mode through CLI/status and
endpoint registration, and add a new service capability so startup replaces a
stale broker that implements the old pushy-submit or legacy framing contract.
Prove with real tmux targets that pushy never submits, trigger submits once,
neither mode repeats after accepted delivery, and no mode turns delivered
`From:` text into another outbound message.
## Add the operator-only runtime command lane
```task
id: TAMQ-WP-0014-T04
status: wait
priority: high
```
Recognize `Cmd:` only from operator input. Start with an allowlist of
`mode=inbox|output|pushy|trigger`, `maxmsg=N`, `maxin=N`, `maxout=N`, and
`reset-limits`; reject malformed, unknown, negative, or out-of-range settings
without changing state. Apply settings atomically to the current managed
session endpoint, persist them across tap/broker restart, and emit a local
`From:tamq:` confirmation or error excluded from routing and counters. Worker
output beginning `Cmd:` must remain inert.
Preserve terminal neutrality explicitly: the current transparent PTY path
cannot recognize a complete line and then retroactively remove bytes already
forwarded to the foreground program. Before implementation, choose and test one
of these honest contracts: observed `Cmd:` lines also remain visible to the
worker, or a separately activated operator control input path buffers and
renders them without forwarding. Do not silently swallow arbitrary typing,
delay normal input, or implement an agent-specific erasure trick.
## Enforce atomic per-window line budgets
```task
id: TAMQ-WP-0014-T05
status: wait
priority: critical
```
Add the session-generation/window ledger, configured defaults, startup flags,
runtime updates, and reset command. Count normalized input and output events at
their single authoritative observation points. Perform counter inspection,
message admission, and accepted-message increment in one transaction so
simultaneous operator and worker sends cannot cross a limit. A blocked attempt
must create no durable message, lease, delivery, or injected input and must
produce exactly the specified source-terminal notice without incrementing any
tamq-generated-output count.
Cover equality and over-limit boundaries, all three dimensions, deterministic
precedence, overlapping input/message and output/message accounting,
per-window isolation, current-window reset, runtime limit changes below a
current count, broker/tap restart, managed-session replacement, concurrent
sends, and notice feedback suppression.
## Migrate the alpha contract and documentation
```task
id: TAMQ-WP-0014-T06
status: wait
priority: high
```
Update root/start help, completion, config examples, README, SCOPE, protocol
documentation, and diagnostics for `To:`/`From:`/`Cmd:`, origin suffixes, four
modes, counters, reset behavior, and the intentional removal of `@/#` aliases.
Remove obsolete generated shims during managed-session reconciliation and
cleanup without touching user-owned commands. Identify this as an alpha
breaking change and make mixed-version startup fail or upgrade rather than
quietly accepting incompatible traffic.
Keep limits distinct from `TAMQ-WP-0003`: these counters bound new message
generation, while WP0003 still owns bounded delivery retry attempts and
acknowledgement policy. Hold `TAMQ-WP-0002` adapter implementation against the
new protocol until this workplan's local contract is proven.
## Prove the installed end-to-end workflow
```task
id: TAMQ-WP-0014-T07
status: wait
priority: critical
```
Run unit, pseudo-terminal, real-tmux, upgrade, and installed-package tests with
two repository windows and real worker-style alternate-screen output. Prove
operator and worker sends in both directions, exact `/o` attribution, inert
worker `Cmd:`, allowed operator commands, pushy placement, trigger submission,
stable-row output, every limit and reset path, service restart continuity, and
cleanup. Include a controlled installed `make install` smoke without modifying
unrelated panes or durable history, and leave runaway-safe cleanup available.
Do not mark the workplan finished while T01 attribution is only simulated or
while a worker output replay can duplicate an operator message.