diff --git a/WORK-RECORDS.md b/WORK-RECORDS.md index dc3b916..bff26be 100644 --- a/WORK-RECORDS.md +++ b/WORK-RECORDS.md @@ -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 | diff --git a/workplans/TAMQ-WP-0014-readable-duplex-messaging-and-limits.md b/workplans/TAMQ-WP-0014-readable-duplex-messaging-and-limits.md new file mode 100644 index 0000000..ea7bf1c --- /dev/null +++ b/workplans/TAMQ-WP-0014-readable-duplex-messaging-and-limits.md @@ -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.