78 lines
5.0 KiB
Markdown
78 lines
5.0 KiB
Markdown
# Agent RPC errors, fencing, and recovery
|
|
|
|
This document describes only the methods exposed by the current
|
|
`AgentControlService`. The package name is not a protocol version;
|
|
`RequestMeta.protocol_version=agent.v1` remains a wire-protocol value. This
|
|
contract does not change SaaS/MQ commands, ownership, or application receipts.
|
|
|
|
## Error rules
|
|
|
|
| gRPC status | Required caller behavior |
|
|
| --- | --- |
|
|
| `InvalidArgument` | Correct the request; do not replay it unchanged. |
|
|
| `Unauthenticated` | Re-establish the verified mTLS/active session before more work. Only the exact, verified session-generation cutover refusal described below permits a bounded re-report of the original fact. |
|
|
| `PermissionDenied` | Stop; no self-reported identity or unapproved peer is accepted. |
|
|
| `FailedPrecondition` | Keep admission closed until the missing state, approval, or loaded SIP revision is resolved. |
|
|
| `Aborted` / `AlreadyExists` | Preserve the original execution identity; conflicting content must not originate another call. |
|
|
| `ResourceExhausted` | Wait for an explicitly confirmed resource release; unknown calls still occupy resources. |
|
|
| `Unavailable` / `DeadlineExceeded` | Treat the result as unknown. Do not originate, upload, or issue a new call identity in response to a lost RPC reply. |
|
|
| `NotFound` | Do not invent a substitute task, call, recording, or upload grant. |
|
|
|
|
A successful transport response does not prove SaaS application receipt. An
|
|
accepted execution means only that the Agent reached its specified durable
|
|
acceptance boundary; terminal state, recording upload, and result delivery
|
|
require separate evidence.
|
|
|
|
## Active session and execution
|
|
|
|
- `GetAgentStatus` is a pre-activation probe. `ActivateAgent` binds the
|
|
Dispatcher identity to the deployed Agent/Cell, boot ID, epoch and a durable
|
|
session generation. Every approved mutation is checked against the latest
|
|
verified peer and unexpired session; a new boot does not inherit old
|
|
authorization. A missing or corrupt session journal fails closed.
|
|
- Approved Mock Agent startup refuses a pre-existing legacy execution journal
|
|
without deleting or converting it. Its disposition requires explicit
|
|
operator review; it must not be silently ignored during a switch.
|
|
- `GetLoadedSIP` reports observed revisions; an absent, stale or mismatched
|
|
revision closes admission. A Mock report is not Asterisk loading evidence.
|
|
- `ExecuteApproved` binds the original call identity to a frozen authorized
|
|
task, selected trunk, SIP revision, AI configuration and exclusive deadline.
|
|
The Agent does not recalculate outbound business rules or replace missing
|
|
values with defaults. Before invoking the Mock call adapter it records the
|
|
execution outcome needed to prevent a second originate. A lost reply or
|
|
unknown outcome cannot trigger automatic redial or another call ID.
|
|
- `ApplyApprovedTaskControl` is task-scoped: pause and stop close local
|
|
admission before registered calls drain or hang up. Stop is terminal for
|
|
the same task ID. It has no external command ID, revision CAS, or hidden
|
|
control deduplication; an explicit redelivery is processed under the
|
|
current task barrier. Failure or timeout never reopens admission by itself.
|
|
|
|
## Recording and final result
|
|
|
|
- If a verified mTLS Agent peer reports `ReportCallEnded`, `ReportCallResult`,
|
|
or `RequestRecordingUpload` across an adjacent active-session generation
|
|
change for the same Agent, Cell, boot, and Dispatcher epoch, the Dispatcher
|
|
**rejects** the fact with `Unauthenticated: verified Agent session generation
|
|
changed`. The Agent may fetch its current session and re-report only that
|
|
original idempotent fact for at most six seconds (or the earlier caller
|
|
deadline), retaining the source event, operation/idempotency key, upload ID,
|
|
asset and result payload. A different identity, expired session, unrelated
|
|
`Unauthenticated`, `PermissionDenied`, or an unknown/timed-out RPC result does
|
|
not authorize a retry. This exception never re-originates, resends an OSS
|
|
PUT, or weakens the latest-generation fence.
|
|
- `RequestRecordingUpload` issues a restricted, short-lived target for the
|
|
original recording. The Agent makes an explicit request for a new grant
|
|
after expiry; there is no automatic token renewal, SaaS upload session, or
|
|
second PUT after an unknown upload outcome.
|
|
- `ReportCallEnded` can release confirmed-ended execution capacity without
|
|
waiting for OSS or MQ delivery. Unknown call termination remains occupied.
|
|
- `ReportCallResult` reports the one final result and, when present, original
|
|
recording metadata and checksum. The Dispatcher persists facts and a shared
|
|
result-queue outbox before acknowledging. Repeated delivery keeps the
|
|
original message identity and cannot upload the recording again. Publisher
|
|
confirmation proves only queue admission, not SaaS application receipt.
|
|
|
|
Secrets, temporary tokens, raw snapshots, complete audio, and full dialogue
|
|
must not be written to logs or long-term acceptance evidence. Local TLS/Mock
|
|
checks do not establish real supplier or Asterisk compatibility.
|