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
110
spec/coordination-engine-adapter-v0.1.md
Normal file
110
spec/coordination-engine-adapter-v0.1.md
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
# Coordination-engine ↔ TAMQ adapter contract v0.1
|
||||
|
||||
Status: implemented local-alpha contract. TAMQ owns this transport contract;
|
||||
coordination-engine owns trigger policy, coordination leases, checkpoints, and
|
||||
workflow state.
|
||||
|
||||
## Boundary and authentication
|
||||
|
||||
The adapter connects to TAMQ's configured Unix-domain socket. The socket is
|
||||
mode `0600`, and TAMQ accepts only the same Unix user through `SO_PEERCRED` when
|
||||
the platform exposes it. There is no TCP listener or command-line bearer token.
|
||||
The client opens a new connection for every operation, so restarting TAMQ needs
|
||||
no reconnect handshake or client-side session state.
|
||||
|
||||
The client first sends `ping` with protocol `0.1`. Major versions must match and
|
||||
the service must advertise `bounded_delivery_ack_v1` and `idempotent_send_v1`.
|
||||
Unknown minor capabilities are ignored. An incompatible major version or a
|
||||
missing required capability stops the wake before message admission.
|
||||
|
||||
## Wake mapping
|
||||
|
||||
`CoordinationEngineAdapter.wake(WakeRequest)` resolves exactly one live endpoint
|
||||
whose registered repository list includes `target_repo`. Zero matches returns
|
||||
unavailable. Multiple matches require an explicit endpoint ID; TAMQ never
|
||||
chooses an arbitrary worker session.
|
||||
|
||||
The wake becomes a `send` request:
|
||||
|
||||
```json
|
||||
{
|
||||
"op": "send",
|
||||
"protocol": "0.1",
|
||||
"client_id": "coordination-engine",
|
||||
"idempotency_key": "<coordination lease id>",
|
||||
"correlation_id": "<trigger id>",
|
||||
"sender_repo": "coordination-engine",
|
||||
"target_repo": "<exact gita slug>",
|
||||
"endpoint_id": "<resolved TAMQ endpoint instance>",
|
||||
"provenance": "coordination_engine",
|
||||
"metadata": {"lease_id": "...", "trigger_id": "..."},
|
||||
"body": "<human-readable wake prompt>"
|
||||
}
|
||||
```
|
||||
|
||||
Targets and non-local senders are validated against the current `gita`
|
||||
registry. Bodies are UTF-8 text up to 8 KiB; metadata is a JSON object up to 4
|
||||
KiB. TAMQ transports the prompt but does not interpret it as task state or
|
||||
grant authority.
|
||||
|
||||
`(client_id, idempotency_key)` is unique. Repeating an identical request returns
|
||||
the original message ID with `deduplicated: true`. Reusing the key with a
|
||||
different sender, target, endpoint, or body is an error. The durable identity
|
||||
used by coordination-engine is therefore the pair of TAMQ endpoint instance
|
||||
and local message ID, correlated to its own lease and trigger IDs.
|
||||
|
||||
## Message and delivery states
|
||||
|
||||
| State | Meaning | Coordination interpretation |
|
||||
| --- | --- | --- |
|
||||
| `pending` | Accepted and eligible now or after `next_attempt_at` | Transport owns retry timing. |
|
||||
| `awaiting_ack` | Written successfully under explicit-ack policy | Recipient comprehension is still unproven. |
|
||||
| `injected` | Written successfully under injected policy | Transport delivery is complete, not task completion. |
|
||||
| `acknowledged` | Explicit acknowledgement received | Strongest TAMQ receipt; still not workflow completion. |
|
||||
| `failed` | Delivery or acknowledgement attempts exhausted | Terminal until an operator/client explicitly retries or a late ack arrives. |
|
||||
|
||||
Every delivery lease acquisition increments the persistent `attempt_count`.
|
||||
Failure releases the lease and sets `last_failure_reason` plus a bounded
|
||||
`next_attempt_at`. Lease expiry is itself a failed attempt. Retry delays default
|
||||
to 5, 15, 60, and 300 seconds and use the last value thereafter. The selected
|
||||
endpoint policy supplies `delivery_max_attempts` in the range 1–9.
|
||||
|
||||
With `delivery_ack_mode=injected`, a successful terminal write completes the
|
||||
message immediately. With `acknowledged`, success enters `awaiting_ack`; the
|
||||
default 30-second deadline then redelivers the same message ID. Duplicate visual
|
||||
or input delivery is therefore possible and recipients must correlate by
|
||||
message ID when the operation is not naturally idempotent. Exhausting the cap
|
||||
while waiting produces `failed` with reason `ack_timeout`. A late explicit ack
|
||||
wins even after terminal failure and cancels any outstanding retry. `retry`
|
||||
resets only a `failed` message's attempts and returns it to `pending`.
|
||||
|
||||
## Operations and failure semantics
|
||||
|
||||
- `endpoints`: discover live repository attachment and disambiguate a wake.
|
||||
- `send`: admit an idempotent durable message.
|
||||
- `message`: retrieve one receipt including state, attempts, deadlines, and
|
||||
correlation metadata.
|
||||
- `history`: recover receipts after either process restarts.
|
||||
- `ack`: record explicit or late acknowledgement and cancel pending delivery.
|
||||
- `retry`: operator/policy-authorized reset of terminal delivery failure.
|
||||
|
||||
Endpoint disappearance before admission is `unavailable` and creates no
|
||||
message. Disappearance after admission leaves the message durable. Repeating the
|
||||
identical wake after a replacement endpoint appears rebinds that same message
|
||||
ID, but only when its previous endpoint is no longer live; TAMQ will not move a
|
||||
message between two live sessions implicitly. A process crash after claiming a
|
||||
message is recovered through lease expiry and bounded backoff.
|
||||
|
||||
JSONL replay uses the original message ID (or a deterministic content digest)
|
||||
as a `tamq-replay` idempotency key. Repeating the same replay reports it as
|
||||
deduplicated rather than creating another message. Replay still uses normal
|
||||
gita validation and never changes coordination-engine workflow state.
|
||||
|
||||
## Ownership
|
||||
|
||||
TAMQ owns local queue rows, endpoint registration, delivery leases, retry and
|
||||
ack state, terminal interaction, and protocol capture. Coordination-engine owns
|
||||
trigger deduplication, coordination leases, actionability and safety policy,
|
||||
checkpoints, State Hub projection, and the decision to issue a wake or request
|
||||
an explicit retry. Neither system treats terminal injection as proof that an
|
||||
agent completed work.
|
||||
Loading…
Add table
Add a link
Reference in a new issue