{
  "schemaVersion": "1.0",
  "title": "Hermes structured runs and approvals",
  "description": "Use these five endpoint-qualified capabilities when an application needs a Hermes run ID, pollable status, structured lifecycle events, a provider approval continuation, or an explicit stop request.",
  "canonical": "https://getaip.org/docs/connectors/hermes-agent/capabilities/durable-runs-and-approvals",
  "route": "/docs/connectors/hermes-agent/capabilities/durable-runs-and-approvals",
  "source": "docs/connectors/hermes-agent/capabilities/durable-runs-and-approvals.md",
  "protocol": "Agent Interoperability Protocol",
  "protocolVersion": "1.0",
  "section": "Connectors",
  "documentType": "Connector",
  "language": "en",
  "downloads": {
    "md": "/docs/download/connectors/hermes-agent/capabilities/durable-runs-and-approvals.md",
    "txt": "/docs/download/connectors/hermes-agent/capabilities/durable-runs-and-approvals.txt",
    "json": "/docs/download/connectors/hermes-agent/capabilities/durable-runs-and-approvals.json",
    "pdf": "/docs/download/connectors/hermes-agent/capabilities/durable-runs-and-approvals.pdf"
  },
  "content": {
    "format": "text/markdown",
    "markdown": "---\ntitle: Hermes structured runs and approvals\ndescription: >-\n  Start and follow a Hermes run, resolve its provider approval, and stop active\n  work without assuming durable or replayable provider state\nkind: capability-reference\naudience: application-developer\nappliesTo: \"1.x\"\nwritingStandard: \"aip-docs/1.0\"\nlastReviewedRevision: \"97be86e9efedf07ecf1783b03800f683f107fb04\"\nconnector: hermes-agent\ncapabilityIds:\n  - cap:hermes_agent:<endpoint_id>:run_start\n  - cap:hermes_agent:<endpoint_id>:run_status\n  - cap:hermes_agent:<endpoint_id>:run_events\n  - cap:hermes_agent:<endpoint_id>:run_approval\n  - cap:hermes_agent:<endpoint_id>:run_stop\n---\n\n# Hermes structured runs and approvals\n\nUse these five endpoint-qualified capabilities when an application needs a\nHermes run ID, pollable status, structured lifecycle events, a provider\napproval continuation, or an explicit stop request.\n\nThe run is asynchronous, but its provider state is not durable. The pinned\nHermes implementation keeps run status, event queues, active-task references,\nand approval queues in one process. A restart loses them. Treat `run_id` as a\ntemporary handle, not as a durable AIP execution record.\n\n## Operations\n\nReplace `<endpoint_id>` with the normalized endpoint ID present in AIP\ndiscovery.\n\n| Operation | Provider request | Risk | AIP approval | Key | Retry |\n|---|---|---|---|---|---|\n| `run_start` | `POST /v1/runs` | Medium | No | Required | Unsafe |\n| `run_status` | `GET /v1/runs/{run_id}` | Low | No | Optional | Safe |\n| `run_events` | `GET /v1/runs/{run_id}/events` | Low | No | Optional | Safe read |\n| `run_approval` | `POST /v1/runs/{run_id}/approval` | Medium | Yes | Required | Unsafe |\n| `run_stop` | `POST /v1/runs/{run_id}/stop` | Medium | Yes | Required | Unsafe |\n\nAll five are stable AIP Workflow capabilities. Every provider request requires\nthe selected endpoint's Bearer token. The endpoint comes from the capability\nID; input cannot select another endpoint or base URL.\n\n`run_events` is a safe read in the mutation sense. Reconnecting does not replay\nevents already removed from the provider's single live queue. Do not interpret\nthe retry marker as an event-delivery guarantee.\n\n## Choose the run lifecycle\n\n| Need | Capability | Completion evidence |\n|---|---|---|\n| Obtain a handle immediately and let Hermes execute in the background | `run_start` | A `202` receipt with a new `run_id` |\n| Learn the latest provider state | `run_status` | Current status object |\n| Observe message, tool, approval, and terminal events | `run_events` | A terminal SSE event or an explicit incomplete result |\n| Answer a tool approval that this exact run is waiting for | `run_approval` | Approval response plus later status or terminal event |\n| Request interruption of an active run | `run_stop` | A `stopping` receipt plus later status or terminal event |\n\nUse a normal Chat or Responses capability when the application needs only one\nHTTP model turn. Use the governed operator capability when Hermes must delegate\nchild AIP actions and retain a recoverable AIP-to-provider binding.\n\n## Shared AIP contract\n\n| Operation | Execution modes | Data contract | Provider timeout | AIP timeout |\n|---|---|---|---:|---:|\n| `run_start` | Sync receipt; async supported and expected | Confidential; PII; redact | 60 s | 60 s |\n| `run_status` | Sync read | Internal; no PII marker; redact | 30 s | 60 s |\n| `run_events` | Async, stream, cancel; streaming expected | Confidential; no PII marker; redact | No connector HTTP timeout | 300 s |\n| `run_approval` | Sync mutation | Restricted; PII; redact | 30 s | 60 s |\n| `run_stop` | Sync mutation | Restricted; PII; redact | 30 s | 60 s |\n\nStart, approval, and stop publish `read`, `write`, and `external_network` side\neffects. Status and events publish `read` and `external_network`. None declares\na transaction. Every compensation contract says rollback is not supported.\n\nThe AIP contract also publishes a 10-second maximum queue-delay hint and a\n`99.9%` availability target. These are declared values, not measurements or\nqualification evidence.\n\nThe status schema understates the possible data. A completed status can contain\nmodel output, and a failed status can contain a redacted error. Events can\ncontain message text, tool names, previews, and approval detail. Handle both as\nconfidential application data even though the published read contracts do not\nmark them as PII-bearing.\n\n## Start a run\n\nThe connector publishes an open object schema. Hermes still requires a truthy\n`input` value. A string is the least ambiguous form. A message array is also\naccepted when its final item has usable `content`.\n\nUse the `body` object for provider input and keep transport controls at the AIP\nlevel:\n\n```json\n{\n  \"body\": {\n    \"input\": \"Prepare a concise incident summary.\",\n    \"instructions\": \"Do not perform external mutations.\",\n    \"model\": \"hermes-agent\",\n    \"session_id\": \"incident-review-2030-01\"\n  },\n  \"session_key\": \"support:incident-review\"\n}\n```\n\nThe provider also accepts `conversation_history` and `previous_response_id`.\nAn explicit, non-empty history takes precedence. When no explicit history is\npresent, Hermes can load the history and session ID stored for a previous\nResponses object. A missing previous response does not fail the start; Hermes\ncontinues without that stored history.\n\nFor a multi-message `input`, Hermes turns all usable items except the last into\nhistory. The final item's `content` becomes current input. Supply valid message\nobjects and end with the visible user request.\n\nA successful start returns immediately:\n\n```json\n{\n  \"run_id\": \"run_0123456789abcdef0123456789abcdef\",\n  \"status\": \"started\"\n}\n```\n\nThe provider HTTP status is `202`. This receipt proves only that Hermes created\nthe in-process run structures and scheduled background work. It does not prove\nthat the model started, a tool succeeded, or the run reached a terminal state.\n\n## Keep run and continuity identities separate\n\n| Identity | Owner | Purpose |\n|---|---|---|\n| AIP Action ID | AIP runtime | Governs the invocation, result, evidence, and cancellation |\n| AIP idempotency key | AIP runtime contract | Detects replay of the same capability action |\n| Hermes `run_id` | Selected Hermes process | Addresses status, events, approval, and stop |\n| Hermes `session_id` | Hermes conversation path | Selects task and conversation continuity |\n| Hermes `session_key` | Hermes memory path | Scopes long-term memory through `X-Hermes-Session-Key` |\n| Provider approval queue key | Hermes process | Is always the new `run_id`, never a client session ID |\n\nIf `session_id` is absent, Hermes uses the new `run_id` as the conversation\ntask ID. Several runs may intentionally share one explicit session ID or memory\nkey. They still receive isolated approval queues, so approval for one run cannot\nrelease another run's pending command.\n\nTrusted execution adds AIP principal, tenant, issuer, trace, delegation,\nsession, idempotency, and deadline headers. The connector verifies an\nendpoint's configured tenant binding before it sends the request.\n\n## Poll run status\n\nCall `run_status` with the exact provider handle:\n\n```json\n{\n  \"run_id\": \"run_0123456789abcdef0123456789abcdef\"\n}\n```\n\nThe connector percent-encodes the path segment and rejects carriage return,\nline feed, and NUL characters. The provider returns `404 run_not_found` when\nthe handle is absent from that process.\n\nThe current status object can contain these fields:\n\n| Field | Meaning |\n|---|---|\n| `object`, `run_id` | `hermes.run` and the provider handle |\n| `status` | Current lifecycle state |\n| `created_at`, `updated_at` | Provider Unix timestamps |\n| `session_id`, `model` | Effective conversation ID and selected model |\n| `last_event` | Latest recorded lifecycle event name |\n| `output`, `usage` | Final text and token counters after completion |\n| `error` | Redacted provider error after failure |\n\nInterpret the states as follows:\n\n| State | Meaning | Next action |\n|---|---|---|\n| `queued` | Run structures exist; execution has not entered the agent body | Poll with backoff or subscribe once |\n| `running` | Agent work is active, or an approval was answered | Continue observing |\n| `waiting_for_approval` | This run has at least one pending provider approval | Review the event and use governed `run_approval` |\n| `stopping` | Hermes accepted a stop request | Keep polling; interruption is not yet proved |\n| `completed` | Agent returned without its structured failure marker | Retain output and usage with AIP evidence |\n| `failed` | Agent returned a failure marker or raised | Inspect the redacted error and side effects |\n| `cancelled` | The run task processed cancellation | Treat prior tool effects as potentially committed |\n\nTerminal status is retained in memory for one hour after its last update, then\nbecomes eligible for the periodic sweep. There is no run-list operation. A\nmissing status can mean an unknown ID, retention expiry, or process restart.\n\n## Consume run events\n\n`run_events` opens `GET /v1/runs/{run_id}/events` and aggregates provider SSE\nframes. It accepts `run_id` and an optional positive `max_events`. The connector\ndefaults to 4096 parsed events.\n\nThe provider can emit:\n\n- `message.delta` for generated text;\n- `tool.started` and `tool.completed` for tool progress;\n- `reasoning.available` for exposed reasoning previews;\n- `approval.request` and `approval.responded` for provider approval flow;\n- `run.completed`, `run.failed`, or `run.cancelled` as terminal events.\n\nHermes sends a keepalive comment after 30 seconds without an event. Comments do\nnot enter the connector's event array. The provider sends `: stream closed`\nafter its queue sentinel; that comment is not a terminal event by itself.\n\nThe queue is live, in memory, and consumed destructively. There is no cursor,\nhistory store, fan-out, or supported resume. Use one subscriber per run. A\nsecond subscriber can split events with the first. When a subscriber closes,\nHermes removes the public queue handle, so a reconnect can return `404` while\nthe underlying run continues.\n\nIf a stream ends without a recognized terminal event, the connector marks the\nAIP action incomplete rather than completed. If `max_events` truncates the\naggregate, `terminal` is false. Poll `run_status` before deciding what happened.\n\nDetailed frame parsing, AIP stream publication, disconnects, and cancellation\nare owned by the streaming guide and cursor reference.\n\n## Resolve a pending provider approval\n\nAn `approval.request` event contains a redacted command where applicable and\nthe provider choices `once`, `session`, `always`, and `deny`. Review that event\nbefore submitting a decision.\n\nThere are two different approval gates:\n\n| Gate | What it authorizes |\n|---|---|\n| AIP approval on the `run_approval` Action | Sending one protected mutation to the selected Hermes endpoint |\n| Hermes provider approval choice | Releasing or denying pending tool work inside that exact run |\n\nThe first does not automatically decide the second. After tenant policy grants\nthe AIP action, submit the intended provider choice:\n\n```json\n{\n  \"run_id\": \"run_0123456789abcdef0123456789abcdef\",\n  \"choice\": \"once\",\n  \"resolve_all\": false\n}\n```\n\nThe published schema also accepts `approve` and `allow`; Hermes normalizes them\nto `once`. Prefer the four canonical choices so stored intent matches provider\nevents. Set `all` or `resolve_all` only when the reviewer has assessed every\ncurrently queued approval for this run. Resolution never crosses into another\nrun, even when both share a session ID.\n\nThe success object reports `run_id`, normalized `choice`, and the number of\nresolved queue entries. Hermes returns `409 approval_not_active` when the run\nno longer owns an active approval session, or `409 approval_not_pending` when\nthe queue has no pending item.\n\nThe AIP capability requires tenant-policy approval with reason, input snapshot,\nand policy-decision evidence. The approval expires after 15 minutes. It is a\nseparate record from the provider's in-memory queue.\n\n## Stop active work\n\nCall `run_stop` only for a run that is still active:\n\n```json\n{\n  \"run_id\": \"run_0123456789abcdef0123456789abcdef\"\n}\n```\n\nThe capability requires AIP approval. Hermes sets status to `stopping`, calls\nthe active agent's interrupt hook, cancels the asynchronous wrapper task, and\nwaits at most five seconds for that task. It then returns:\n\n```json\n{\n  \"run_id\": \"run_0123456789abcdef0123456789abcdef\",\n  \"status\": \"stopping\"\n}\n```\n\nThis receipt is not a terminal cancellation guarantee. The agent runs in an\nexecutor thread that task cancellation cannot preempt directly. A current tool\ncall can finish, and effects that already reached another system are not rolled\nback. Poll status and retain a terminal event when available.\n\nStopping a completed run returns `404` because Hermes has already removed its\nactive agent and task references. Runtime cancellation dispatches the same\nprovider stop operation only when the cancelled AIP action input contains a\n`run_id`; cancelling `run_start` before its receipt has no provider handle to\nstop.\n\n## Understand retention and process loss\n\n| Provider state | Storage | Current retention boundary |\n|---|---|---|\n| Active agent and task references | Process memory | Removed on completion or cancellation |\n| SSE queue | Process memory | Removed after subscription closes or by the orphan sweep |\n| Approval routing | Process memory | Removed after the run settles, stops, or is swept |\n| Terminal status | Process memory | Eligible for sweep 3600 seconds after update |\n| Non-terminal status | Process memory | No terminal TTL rule; lost on restart |\n\nRun streams become eligible for the orphan sweep 300 seconds after creation.\nThe sweep runs once per minute. It removes active references and provider\napproval routing but does not prove that an executor thread stopped. A run that\nexceeds this window can become unmanageable through events, approval, or stop\neven while underlying work is still settling.\n\nSubscribe promptly and design runs to finish within the admitted deadline. Do\nnot use the run API as a durable job store. Preserve AIP lifecycle and execution\nevidence outside this provider memory boundary.\n\n## Apply idempotency and retry rules\n\nStart, approval, and stop require a capability-scoped AIP idempotency key. The\npublished TTL is 24 hours, and collision behavior is ReturnOriginalResult. The\nHermes run handlers do not enforce the forwarded `Idempotency-Key` header.\n\nConsequently, durable replay protection depends on the AIP runtime's configured\nidempotency backend. Repeating `run_start` directly at Hermes creates another\nrun. Repeating an approval or stop after provider success commonly returns a\nconflict or not-found response rather than the original result.\n\nUse these recovery decisions:\n\n| Uncertain operation | Safe next check | Do not assume |\n|---|---|---|\n| Start returned no `run_id` | Inspect the AIP action record and runtime idempotency result | That a replay will find the first provider run |\n| Approval lost its response | Poll status and inspect the remaining live event stream | That resending the choice cannot release another pending item |\n| Stop lost its response | Poll status and look for a terminal event | That `stopping` or transport close means cancellation |\n| Status read failed | Retry with bounded backoff | That absence after restart means the run never executed |\n| Event stream disconnected | Poll status and preserve the evidence gap | That reconnect or connector retry can recover missed frames |\n\nThe provider has no endpoint for listing runs or reconciling a lost start\nreceipt. Do not auto-retry a mutating call after an unknown outcome.\n\n## Account for shared limits\n\nHermes applies one concurrency gate across Chat, Responses, and structured\nruns. The default is 10 in-flight agent runs; zero disables the cap. Saturation\nreturns `429` with `Retry-After: 1`, although the connector's typed failure does\nnot retain that response header.\n\nFor structured runs, the gate counts entries in the live run-stream map. A\ncompleted run whose event queue was never consumed can therefore occupy a slot\nuntil a subscriber drains it or the orphan sweep removes it. Consume the event\nstream even when the application also polls status.\n\nThe provider rejects request bodies over 10,000,000 bytes. The connector does\nnot publish a separate response-size bound. Trusted AIP execution can end any\noperation at its action deadline, even when the connector or provider would\notherwise keep waiting.\n\n## Handle failures\n\n| Symptom | Meaning | Response |\n|---|---|---|\n| Local schema or missing-ID rejection | The action cannot form a valid route or approval body | Correct the input; do not retry unchanged |\n| Provider `400` | Invalid JSON, missing input, invalid history, or invalid approval choice | Correct the provider body |\n| Provider `401` | Endpoint Bearer authentication failed | Verify the admitted endpoint credential revision |\n| Provider `404` | Run state or active stop target is absent from this process | Check retention and restart history before concluding it never ran |\n| Provider `409` on approval | No active approval session or no pending item | Refresh status and current events; do not force a replay |\n| Provider `429` | Shared agent concurrency is saturated | Apply bounded backoff to a new start only when prior outcome is known |\n| Transport or decode failure on mutation | Provider outcome can be unknown | Reconcile through AIP state, status, and events |\n| Stream closes without terminal evidence | Event delivery is incomplete | Poll status; preserve the gap in execution evidence |\n\nThe connector reports provider non-success bodies through a typed failure and\nmarks mutating failures as non-retryable. Authentication, tenant mismatch,\nexpired trusted deadlines, and runtime cancellation are separate failures.\n\n## Verify an integration\n\nFor each admitted endpoint, verify and retain evidence that:\n\n1. discovery exposes exactly the five expected capability IDs and contracts;\n2. one approved start returns a unique `run_id` and status becomes visible;\n3. the single event consumer observes ordered frames and a terminal condition;\n4. two runs sharing a session ID still have isolated approval queues;\n5. approval requires AIP evidence and changes only the selected run;\n6. stop is followed until `cancelled`, `failed`, or another explained outcome;\n7. a disconnected stream is reconciled through status without claiming replay;\n8. process restart and retention expiry are reported as evidence loss, not as\n   proof that no external effect occurred.\n\nRecord the AIP source revision, Hermes revision, connector and host artifact\nidentities, endpoint ID, tenant binding, credential revision, timestamps, and\nretained results. Source presence alone is not qualification or live-product\nevidence.\n\n## Related documentation\n\n- [Hermes Agent capabilities](README.md)\n- [Chat and Responses capabilities](chat-and-responses.md)\n- [Actions and sessions](../../../concepts/actions-and-sessions.md)\n- [Approvals and policy](../../../concepts/approvals-and-policy.md)\n- [Errors and recovery](../../../reference/errors.md)\n",
    "text": "Hermes structured runs and approvals\n\nUse these five endpoint-qualified capabilities when an application needs a\nHermes run ID, pollable status, structured lifecycle events, a provider\napproval continuation, or an explicit stop request.\n\nThe run is asynchronous, but its provider state is not durable. The pinned\nHermes implementation keeps run status, event queues, active-task references,\nand approval queues in one process. A restart loses them. Treat runid as a\ntemporary handle, not as a durable AIP execution record.\n\nOperations\n\nReplace  with the normalized endpoint ID present in AIP\ndiscovery.\n\n| Operation | Provider request | Risk | AIP approval | Key | Retry |\n\n| runstart | POST /v1/runs | Medium | No | Required | Unsafe |\n| runstatus | GET /v1/runs/{runid} | Low | No | Optional | Safe |\n| runevents | GET /v1/runs/{runid}/events | Low | No | Optional | Safe read |\n| runapproval | POST /v1/runs/{runid}/approval | Medium | Yes | Required | Unsafe |\n| runstop | POST /v1/runs/{runid}/stop | Medium | Yes | Required | Unsafe |\n\nAll five are stable AIP Workflow capabilities. Every provider request requires\nthe selected endpoint's Bearer token. The endpoint comes from the capability\nID; input cannot select another endpoint or base URL.\n\nrunevents is a safe read in the mutation sense. Reconnecting does not replay\nevents already removed from the provider's single live queue. Do not interpret\nthe retry marker as an event-delivery guarantee.\n\nChoose the run lifecycle\n\n| Need | Capability | Completion evidence |\n\n| Obtain a handle immediately and let Hermes execute in the background | runstart | A 202 receipt with a new runid |\n| Learn the latest provider state | runstatus | Current status object |\n| Observe message, tool, approval, and terminal events | runevents | A terminal SSE event or an explicit incomplete result |\n| Answer a tool approval that this exact run is waiting for | runapproval | Approval response plus later status or terminal event |\n| Request interruption of an active run | runstop | A stopping receipt plus later status or terminal event |\n\nUse a normal Chat or Responses capability when the application needs only one\nHTTP model turn. Use the governed operator capability when Hermes must delegate\nchild AIP actions and retain a recoverable AIP-to-provider binding.\n\nShared AIP contract\n\n| Operation | Execution modes | Data contract | Provider timeout | AIP timeout |\n\n| runstart | Sync receipt; async supported and expected | Confidential; PII; redact | 60 s | 60 s |\n| runstatus | Sync read | Internal; no PII marker; redact | 30 s | 60 s |\n| runevents | Async, stream, cancel; streaming expected | Confidential; no PII marker; redact | No connector HTTP timeout | 300 s |\n| runapproval | Sync mutation | Restricted; PII; redact | 30 s | 60 s |\n| runstop | Sync mutation | Restricted; PII; redact | 30 s | 60 s |\n\nStart, approval, and stop publish read, write, and externalnetwork side\neffects. Status and events publish read and externalnetwork. None declares\na transaction. Every compensation contract says rollback is not supported.\n\nThe AIP contract also publishes a 10-second maximum queue-delay hint and a\n99.9% availability target. These are declared values, not measurements or\nqualification evidence.\n\nThe status schema understates the possible data. A completed status can contain\nmodel output, and a failed status can contain a redacted error. Events can\ncontain message text, tool names, previews, and approval detail. Handle both as\nconfidential application data even though the published read contracts do not\nmark them as PII-bearing.\n\nStart a run\n\nThe connector publishes an open object schema. Hermes still requires a truthy\ninput value. A string is the least ambiguous form. A message array is also\naccepted when its final item has usable content.\n\nUse the body object for provider input and keep transport controls at the AIP\nlevel:\n\n{\n  \"body\": {\n    \"input\": \"Prepare a concise incident summary.\",\n    \"instructions\": \"Do not perform external mutations.\",\n    \"model\": \"hermes-agent\",\n    \"sessionid\": \"incident-review-2030-01\"\n  },\n  \"sessionkey\": \"support:incident-review\"\n}\n\nThe provider also accepts conversationhistory and previousresponseid.\nAn explicit, non-empty history takes precedence. When no explicit history is\npresent, Hermes can load the history and session ID stored for a previous\nResponses object. A missing previous response does not fail the start; Hermes\ncontinues without that stored history.\n\nFor a multi-message input, Hermes turns all usable items except the last into\nhistory. The final item's content becomes current input. Supply valid message\nobjects and end with the visible user request.\n\nA successful start returns immediately:\n\n{\n  \"runid\": \"run0123456789abcdef0123456789abcdef\",\n  \"status\": \"started\"\n}\n\nThe provider HTTP status is 202. This receipt proves only that Hermes created\nthe in-process run structures and scheduled background work. It does not prove\nthat the model started, a tool succeeded, or the run reached a terminal state.\n\nKeep run and continuity identities separate\n\n| Identity | Owner | Purpose |\n\n| AIP Action ID | AIP runtime | Governs the invocation, result, evidence, and cancellation |\n| AIP idempotency key | AIP runtime contract | Detects replay of the same capability action |\n| Hermes runid | Selected Hermes process | Addresses status, events, approval, and stop |\n| Hermes sessionid | Hermes conversation path | Selects task and conversation continuity |\n| Hermes sessionkey | Hermes memory path | Scopes long-term memory through X-Hermes-Session-Key |\n| Provider approval queue key | Hermes process | Is always the new runid, never a client session ID |\n\nIf sessionid is absent, Hermes uses the new runid as the conversation\ntask ID. Several runs may intentionally share one explicit session ID or memory\nkey. They still receive isolated approval queues, so approval for one run cannot\nrelease another run's pending command.\n\nTrusted execution adds AIP principal, tenant, issuer, trace, delegation,\nsession, idempotency, and deadline headers. The connector verifies an\nendpoint's configured tenant binding before it sends the request.\n\nPoll run status\n\nCall runstatus with the exact provider handle:\n\n{\n  \"runid\": \"run0123456789abcdef0123456789abcdef\"\n}\n\nThe connector percent-encodes the path segment and rejects carriage return,\nline feed, and NUL characters. The provider returns 404 runnotfound when\nthe handle is absent from that process.\n\nThe current status object can contain these fields:\n\n| Field | Meaning |\n\n| object, runid | hermes.run and the provider handle |\n| status | Current lifecycle state |\n| createdat, updatedat | Provider Unix timestamps |\n| sessionid, model | Effective conversation ID and selected model |\n| lastevent | Latest recorded lifecycle event name |\n| output, usage | Final text and token counters after completion |\n| error | Redacted provider error after failure |\n\nInterpret the states as follows:\n\n| State | Meaning | Next action |\n\n| queued | Run structures exist; execution has not entered the agent body | Poll with backoff or subscribe once |\n| running | Agent work is active, or an approval was answered | Continue observing |\n| waitingforapproval | This run has at least one pending provider approval | Review the event and use governed runapproval |\n| stopping | Hermes accepted a stop request | Keep polling; interruption is not yet proved |\n| completed | Agent returned without its structured failure marker | Retain output and usage with AIP evidence |\n| failed | Agent returned a failure marker or raised | Inspect the redacted error and side effects |\n| cancelled | The run task processed cancellation | Treat prior tool effects as potentially committed |\n\nTerminal status is retained in memory for one hour after its last update, then\nbecomes eligible for the periodic sweep. There is no run-list operation. A\nmissing status can mean an unknown ID, retention expiry, or process restart.\n\nConsume run events\n\nrunevents opens GET /v1/runs/{runid}/events and aggregates provider SSE\nframes. It accepts runid and an optional positive maxevents. The connector\ndefaults to 4096 parsed events.\n\nThe provider can emit:\n• message.delta for generated text;\n• tool.started and tool.completed for tool progress;\n• reasoning.available for exposed reasoning previews;\n• approval.request and approval.responded for provider approval flow;\n• run.completed, run.failed, or run.cancelled as terminal events.\n\nHermes sends a keepalive comment after 30 seconds without an event. Comments do\nnot enter the connector's event array. The provider sends : stream closed\nafter its queue sentinel; that comment is not a terminal event by itself.\n\nThe queue is live, in memory, and consumed destructively. There is no cursor,\nhistory store, fan-out, or supported resume. Use one subscriber per run. A\nsecond subscriber can split events with the first. When a subscriber closes,\nHermes removes the public queue handle, so a reconnect can return 404 while\nthe underlying run continues.\n\nIf a stream ends without a recognized terminal event, the connector marks the\nAIP action incomplete rather than completed. If maxevents truncates the\naggregate, terminal is false. Poll runstatus before deciding what happened.\n\nDetailed frame parsing, AIP stream publication, disconnects, and cancellation\nare owned by the streaming guide and cursor reference.\n\nResolve a pending provider approval\n\nAn approval.request event contains a redacted command where applicable and\nthe provider choices once, session, always, and deny. Review that event\nbefore submitting a decision.\n\nThere are two different approval gates:\n\n| Gate | What it authorizes |\n\n| AIP approval on the runapproval Action | Sending one protected mutation to the selected Hermes endpoint |\n| Hermes provider approval choice | Releasing or denying pending tool work inside that exact run |\n\nThe first does not automatically decide the second. After tenant policy grants\nthe AIP action, submit the intended provider choice:\n\n{\n  \"runid\": \"run0123456789abcdef0123456789abcdef\",\n  \"choice\": \"once\",\n  \"resolveall\": false\n}\n\nThe published schema also accepts approve and allow; Hermes normalizes them\nto once. Prefer the four canonical choices so stored intent matches provider\nevents. Set all or resolveall only when the reviewer has assessed every\ncurrently queued approval for this run. Resolution never crosses into another\nrun, even when both share a session ID.\n\nThe success object reports runid, normalized choice, and the number of\nresolved queue entries. Hermes returns 409 approvalnotactive when the run\nno longer owns an active approval session, or 409 approvalnotpending when\nthe queue has no pending item.\n\nThe AIP capability requires tenant-policy approval with reason, input snapshot,\nand policy-decision evidence. The approval expires after 15 minutes. It is a\nseparate record from the provider's in-memory queue.\n\nStop active work\n\nCall runstop only for a run that is still active:\n\n{\n  \"runid\": \"run0123456789abcdef0123456789abcdef\"\n}\n\nThe capability requires AIP approval. Hermes sets status to stopping, calls\nthe active agent's interrupt hook, cancels the asynchronous wrapper task, and\nwaits at most five seconds for that task. It then returns:\n\n{\n  \"runid\": \"run0123456789abcdef0123456789abcdef\",\n  \"status\": \"stopping\"\n}\n\nThis receipt is not a terminal cancellation guarantee. The agent runs in an\nexecutor thread that task cancellation cannot preempt directly. A current tool\ncall can finish, and effects that already reached another system are not rolled\nback. Poll status and retain a terminal event when available.\n\nStopping a completed run returns 404 because Hermes has already removed its\nactive agent and task references. Runtime cancellation dispatches the same\nprovider stop operation only when the cancelled AIP action input contains a\nrunid; cancelling runstart before its receipt has no provider handle to\nstop.\n\nUnderstand retention and process loss\n\n| Provider state | Storage | Current retention boundary |\n\n| Active agent and task references | Process memory | Removed on completion or cancellation |\n| SSE queue | Process memory | Removed after subscription closes or by the orphan sweep |\n| Approval routing | Process memory | Removed after the run settles, stops, or is swept |\n| Terminal status | Process memory | Eligible for sweep 3600 seconds after update |\n| Non-terminal status | Process memory | No terminal TTL rule; lost on restart |\n\nRun streams become eligible for the orphan sweep 300 seconds after creation.\nThe sweep runs once per minute. It removes active references and provider\napproval routing but does not prove that an executor thread stopped. A run that\nexceeds this window can become unmanageable through events, approval, or stop\neven while underlying work is still settling.\n\nSubscribe promptly and design runs to finish within the admitted deadline. Do\nnot use the run API as a durable job store. Preserve AIP lifecycle and execution\nevidence outside this provider memory boundary.\n\nApply idempotency and retry rules\n\nStart, approval, and stop require a capability-scoped AIP idempotency key. The\npublished TTL is 24 hours, and collision behavior is ReturnOriginalResult. The\nHermes run handlers do not enforce the forwarded Idempotency-Key header.\n\nConsequently, durable replay protection depends on the AIP runtime's configured\nidempotency backend. Repeating runstart directly at Hermes creates another\nrun. Repeating an approval or stop after provider success commonly returns a\nconflict or not-found response rather than the original result.\n\nUse these recovery decisions:\n\n| Uncertain operation | Safe next check | Do not assume |\n\n| Start returned no runid | Inspect the AIP action record and runtime idempotency result | That a replay will find the first provider run |\n| Approval lost its response | Poll status and inspect the remaining live event stream | That resending the choice cannot release another pending item |\n| Stop lost its response | Poll status and look for a terminal event | That stopping or transport close means cancellation |\n| Status read failed | Retry with bounded backoff | That absence after restart means the run never executed |\n| Event stream disconnected | Poll status and preserve the evidence gap | That reconnect or connector retry can recover missed frames |\n\nThe provider has no endpoint for listing runs or reconciling a lost start\nreceipt. Do not auto-retry a mutating call after an unknown outcome.\n\nAccount for shared limits\n\nHermes applies one concurrency gate across Chat, Responses, and structured\nruns. The default is 10 in-flight agent runs; zero disables the cap. Saturation\nreturns 429 with Retry-After: 1, although the connector's typed failure does\nnot retain that response header.\n\nFor structured runs, the gate counts entries in the live run-stream map. A\ncompleted run whose event queue was never consumed can therefore occupy a slot\nuntil a subscriber drains it or the orphan sweep removes it. Consume the event\nstream even when the application also polls status.\n\nThe provider rejects request bodies over 10,000,000 bytes. The connector does\nnot publish a separate response-size bound. Trusted AIP execution can end any\noperation at its action deadline, even when the connector or provider would\notherwise keep waiting.\n\nHandle failures\n\n| Symptom | Meaning | Response |\n\n| Local schema or missing-ID rejection | The action cannot form a valid route or approval body | Correct the input; do not retry unchanged |\n| Provider 400 | Invalid JSON, missing input, invalid history, or invalid approval choice | Correct the provider body |\n| Provider 401 | Endpoint Bearer authentication failed | Verify the admitted endpoint credential revision |\n| Provider 404 | Run state or active stop target is absent from this process | Check retention and restart history before concluding it never ran |\n| Provider 409 on approval | No active approval session or no pending item | Refresh status and current events; do not force a replay |\n| Provider 429 | Shared agent concurrency is saturated | Apply bounded backoff to a new start only when prior outcome is known |\n| Transport or decode failure on mutation | Provider outcome can be unknown | Reconcile through AIP state, status, and events |\n| Stream closes without terminal evidence | Event delivery is incomplete | Poll status; preserve the gap in execution evidence |\n\nThe connector reports provider non-success bodies through a typed failure and\nmarks mutating failures as non-retryable. Authentication, tenant mismatch,\nexpired trusted deadlines, and runtime cancellation are separate failures.\n\nVerify an integration\n\nFor each admitted endpoint, verify and retain evidence that:\n1. discovery exposes exactly the five expected capability IDs and contracts;\n2. one approved start returns a unique runid and status becomes visible;\n3. the single event consumer observes ordered frames and a terminal condition;\n4. two runs sharing a session ID still have isolated approval queues;\n5. approval requires AIP evidence and changes only the selected run;\n6. stop is followed until cancelled, failed, or another explained outcome;\n7. a disconnected stream is reconciled through status without claiming replay;\n8. process restart and retention expiry are reported as evidence loss, not as\n   proof that no external effect occurred.\n\nRecord the AIP source revision, Hermes revision, connector and host artifact\nidentities, endpoint ID, tenant binding, credential revision, timestamps, and\nretained results. Source presence alone is not qualification or live-product\nevidence.\n\nRelated documentation\n• Hermes Agent capabilities (README.md)\n• Chat and Responses capabilities (chat-and-responses.md)\n• Actions and sessions (../../../concepts/actions-and-sessions.md)\n• Approvals and policy (../../../concepts/approvals-and-policy.md)\n• Errors and recovery (../../../reference/errors.md)\n"
  },
  "integrity": {
    "algorithm": "sha256",
    "sourceDigest": "a5a4ae24bef06cf3e51107e1b6c5b8acf7a92faa125603ecf16d9a4c372d1724"
  }
}
