feat: complete reliable coordination adapter
Some checks failed
tamq-ci / test (push) Failing after 5s
Some checks failed
tamq-ci / test (push) Failing after 5s
Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a03397-4d51-7fd1-8ff2-946eb22ea2bc
This commit is contained in:
parent
25113f463e
commit
6d2ccc7760
30 changed files with 2553 additions and 144 deletions
112
README.md
112
README.md
|
|
@ -4,8 +4,8 @@ Tmux Agentic Message Queueing (`tamq`) provides repository-aware tmux sessions
|
|||
and a local, durable message queue. It does not assume who or what uses a pane.
|
||||
|
||||
The local alpha provides tmux endpoint lifecycle, local SQLite history and
|
||||
leases, readable `To:` routing, JSONL export/replay, and a Unix-socket protocol
|
||||
for a later coordination-engine adapter.
|
||||
leases, readable `To:` routing, JSONL export/replay, bounded delivery state, and
|
||||
a versioned Unix-socket coordination-engine adapter.
|
||||
|
||||
Agents and operators should start with the concise
|
||||
[TAMQ messaging introduction](TamqMessagingIntroduction.md).
|
||||
|
|
@ -182,6 +182,34 @@ the durable id needed by `ack`:
|
|||
From:flex-auth/o: please review the auth boundary
|
||||
```
|
||||
|
||||
### Reviewing the communication protocol
|
||||
|
||||
TAMQ automatically appends structured protocol events to the local database.
|
||||
The ledger includes addressed-message acceptance, operator/worker provenance,
|
||||
worker block boundaries and termination reasons, allowlisted command outcomes,
|
||||
line-limit blocks, endpoint lifecycle, and delivery attempts or failures. It
|
||||
does not capture unrelated pane output or ordinary shell input.
|
||||
|
||||
Create a review artifact with:
|
||||
|
||||
```bash
|
||||
tamq capture --output tamq-protocol.md
|
||||
tamq capture --repo audit-core --output audit-core-protocol.md
|
||||
tamq capture --message-id m-... --format jsonl
|
||||
tamq capture --event delivery.failed
|
||||
```
|
||||
|
||||
Markdown is the human-oriented default and starts with aggregate counts useful
|
||||
for spotting protocol friction. JSONL is intended for scripts. The default is
|
||||
the newest 500 matching events; `--limit` changes that bound. Repository filters
|
||||
match either side of an exchange. A message body is included only on its
|
||||
acceptance event, not repeated for every delivery event. Captures are durable
|
||||
communication evidence, so never put credentials or secrets in TAMQ messages.
|
||||
When upgrading an already-running alpha, recreate the managed session once so
|
||||
its long-lived pane observers use the capture-aware build; existing durable
|
||||
message lifecycle is backfilled, but old observers cannot reconstruct block or
|
||||
command events retroactively.
|
||||
|
||||
To explicitly consume pending messages through a command, use an inbox filter:
|
||||
|
||||
```bash
|
||||
|
|
@ -195,12 +223,26 @@ it and all later messages pending. Filters never run in the background and
|
|||
cannot be combined with `--all` or `--json`.
|
||||
|
||||
Outside a managed window, use `tamq inbox --repo audit-core` and optionally
|
||||
`--json`. Output-displayed messages remain durable and pending until
|
||||
acknowledged. Neither `output` nor `inbox` mode injects terminal keystrokes.
|
||||
Pushy places input without Enter. Trigger waits for terminal paste detection to
|
||||
settle and then adds exactly one Enter. A short endpoint-startup grace protects
|
||||
the first input delivery while the foreground program initializes. Both input
|
||||
modes record accepted placement as `injected`, not recipient acknowledgement.
|
||||
`--json`. Neither `output` nor `inbox` mode injects terminal keystrokes. Pushy
|
||||
places input without Enter. Trigger waits for terminal paste detection to settle
|
||||
and then adds exactly one Enter. A short endpoint-startup grace protects the
|
||||
first input delivery while the foreground program initializes.
|
||||
|
||||
The policy profile controls completion. The default `injected` policy completes
|
||||
after a successful terminal write. `acknowledged` keeps the message in
|
||||
`awaiting_ack`, visible in the inbox, and redelivers the same ID after the ack
|
||||
deadline. Delivery failures and expired leases use bounded backoff; exhaustion
|
||||
becomes `failed`. Inspect the attempt count and reason, then explicitly reset a
|
||||
terminal message if retry is safe:
|
||||
|
||||
```bash
|
||||
tamq inspect m-...
|
||||
tamq retry m-...
|
||||
```
|
||||
|
||||
Acknowledged-mode redelivery can create duplicate terminal presentation. A late
|
||||
ack wins even after exhaustion. Neither state proves that an agent completed the
|
||||
requested work.
|
||||
|
||||
Every session window has independent, session-lifetime running counters for
|
||||
accepted outbound messages, operator input lines, and normalized worker output
|
||||
|
|
@ -296,17 +338,16 @@ later phase.
|
|||
This keeps tmux-specific topology concerns separate from reusable terminal I/O
|
||||
observation and message identity.
|
||||
|
||||
Normal endpoints use terminal-output delivery: each message is written once to
|
||||
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` places a sanitized `From:` block
|
||||
Normal endpoints use terminal-output delivery. `--mode inbox` selects
|
||||
inbox-only manual mode. Neither becomes pane input. Experimental `--mode pushy`
|
||||
places a sanitized `From:` block
|
||||
without Enter; `--mode trigger` performs the same placement, lets paste
|
||||
detection settle, and submits once.
|
||||
The PTY observer records explicit operator/worker provenance and suppresses
|
||||
echoed operator lines before they can route again.
|
||||
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`.
|
||||
`tamq start --tap --command ...` opt-in. Both input paths use the same bounded
|
||||
retry and acknowledgement state machine.
|
||||
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.
|
||||
|
||||
|
|
@ -324,6 +365,9 @@ purge_before = "365d"
|
|||
purge_max_size = "100MB"
|
||||
history_max_size = "100MB"
|
||||
delivery_poll_interval = "0.5"
|
||||
delivery_lease_seconds = "30"
|
||||
delivery_retry_backoff_seconds = "5,15,60,300"
|
||||
delivery_ack_timeout_seconds = "30"
|
||||
maxmsg = 8
|
||||
maxin = 1024
|
||||
maxout = 32768
|
||||
|
|
@ -331,15 +375,43 @@ maxout = 32768
|
|||
[policy.profiles.diagnostics]
|
||||
safety_gated_max_attempts = 2
|
||||
delivery_ack_mode = "acknowledged"
|
||||
delivery_max_attempts = 4
|
||||
```
|
||||
|
||||
Policy profiles accept a safety-gated retry cap of at most nine attempts, but
|
||||
the alpha delivery path does not enforce attempt counting yet. Explicit
|
||||
acknowledgement exists, while `delivery_ack_mode` enforcement and bounded retry
|
||||
state are tracked in `TAMQ-WP-0003`. Use `--policy-profile` to select a profile;
|
||||
`--orwell` enables explicitly unsafe local diagnostics.
|
||||
Policy profiles accept one to nine delivery attempts. Lease expiry and write
|
||||
failure consume an attempt; retry delay uses the configured sequence and then
|
||||
repeats its last value. `delivery_ack_mode` is either `injected` or
|
||||
`acknowledged`. Use `--policy-profile` to select a profile; `--orwell` enables
|
||||
explicitly unsafe local diagnostics.
|
||||
|
||||
The Unix socket service supports structured `ping`, `register`, `send`,
|
||||
`history`, `ack`, `endpoints`, and `disconnect` operations. Endpoint
|
||||
`message`, `history`, `ack`, `retry`, `endpoints`, and `disconnect` operations. Endpoint
|
||||
registrations and messages are persisted in the same local SQLite database;
|
||||
delivery remains delegated to the control-mode adapter.
|
||||
|
||||
## Coordination-engine adapter
|
||||
|
||||
`tamq.client.CoordinationEngineAdapter` is a transport-only async adapter. It
|
||||
does not import tmux/control-mode code and opens a fresh authenticated
|
||||
Unix-socket connection per operation. A wake resolves exactly one live endpoint,
|
||||
validates the gita target, and uses the coordination lease ID as its idempotency
|
||||
key:
|
||||
|
||||
```python
|
||||
from tamq.client import CoordinationEngineAdapter, WakeRequest
|
||||
|
||||
receipt = await CoordinationEngineAdapter().wake(
|
||||
WakeRequest(
|
||||
lease_id="lease-123",
|
||||
trigger_id="task-456:r7",
|
||||
target_repo="audit-core",
|
||||
prompt="Resume the actionable task and publish a checkpoint.",
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
Repeating that wake returns the same message ID. Reusing its lease ID for a
|
||||
different payload is rejected. Receipt recovery, explicit acknowledgement, and
|
||||
terminal retry use `receipt`, `acknowledge`, and `retry_failed`. The normative
|
||||
state and ownership contract is
|
||||
[`spec/coordination-engine-adapter-v0.1.md`](spec/coordination-engine-adapter-v0.1.md).
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue