111 lines
5.5 KiB
Markdown
111 lines
5.5 KiB
Markdown
|
|
# 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.
|