{
  "schemaVersion": "1.0",
  "title": "Hermes operator and delegation capability",
  "description": "Use the endpoint-qualified operator capability when Hermes must plan a governed objective, call admitted AIP tools, pause for approval, resume the same provider run, or reconcile cancellation across a process restart.",
  "canonical": "https://getaip.org/docs/connectors/hermes-agent/capabilities/operator-and-delegation",
  "route": "/docs/connectors/hermes-agent/capabilities/operator-and-delegation",
  "source": "docs/connectors/hermes-agent/capabilities/operator-and-delegation.md",
  "protocol": "Agent Interoperability Protocol",
  "protocolVersion": "1.0",
  "section": "Connectors",
  "documentType": "Connector",
  "language": "en",
  "downloads": {
    "md": "/docs/download/connectors/hermes-agent/capabilities/operator-and-delegation.md",
    "txt": "/docs/download/connectors/hermes-agent/capabilities/operator-and-delegation.txt",
    "json": "/docs/download/connectors/hermes-agent/capabilities/operator-and-delegation.json",
    "pdf": "/docs/download/connectors/hermes-agent/capabilities/operator-and-delegation.pdf"
  },
  "content": {
    "format": "text/markdown",
    "markdown": "---\ntitle: Hermes operator and delegation capability\ndescription: >-\n  Run or resume the governed Hermes operator and route native delegation\n  without treating provider state or model prose as AIP execution authority\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>:operator\n---\n\n# Hermes operator and delegation capability\n\nUse the endpoint-qualified `operator` capability when Hermes must plan a\ngoverned objective, call admitted AIP tools, pause for approval, resume the same\nprovider run, or reconcile cancellation across a process restart.\n\nThis lifecycle adds a durable AIP binding around a volatile Hermes structured\nrun. It does not make Hermes run storage durable. The binding prevents an\nunknown external start or approval command from being replayed automatically.\n\nThe same connector can also own first-class AIP delegation. That route is\ndisabled by default and uses a different entry contract: the child Action keeps\nits real capability ID, while the delegate principal selects the Hermes\nendpoint.\n\n## Operation contract\n\nReplace `<endpoint_id>` with the normalized endpoint ID present in AIP\ndiscovery.\n\n| Field | Published value |\n|---|---|\n| Capability | `cap:hermes_agent:<endpoint_id>:operator` |\n| Provider request | `POST /v1/runs` with endpoint Bearer authentication |\n| Kind and stability | Agent; stable |\n| Risk and approval | High; tenant-policy AIP approval required |\n| Idempotency | Required; capability scope; 24-hour TTL; ReturnOriginalResult |\n| Side effects | `read`, `write`, `send_message`, `external_network`, `code_execution` |\n| Data | Confidential; contains PII; redaction required |\n| Execution | Sync, async, streaming, and cancellation supported |\n| Expected completion | Streaming; `async_expected` is true |\n| Expected latency and timeout | 30 seconds and 15 minutes |\n| Transaction | None |\n| Compensation | Rollback not supported; approval required |\n\nThe approval policy lasts 15 minutes and requires a reason, input snapshot,\nand policy-decision evidence. The contract also declares a 10-second maximum\nqueue-delay hint and a `99.9%` availability target. These are declarations, not\nobserved performance or qualification evidence.\n\n## Choose direct operator work or delegation\n\n| Need | Entry | Capability carried by the Action | Result authority |\n|---|---|---|---|\n| Ask Hermes to plan and execute a bounded objective | Invoke `operator` with `objective` | Hermes `operator` capability | Governed operator binding and provider terminal result |\n| Continue a source operator Action after a provider approval prompt | Invoke `operator` with `resume` in a new Action | Hermes `operator` capability | Stored source binding plus provider continuation |\n| Delegate one exact native AIP child Action to Hermes | Send a `DelegationRequest` to `agent:hermes_operator:<endpoint_id>` | The child's actual target capability | Native child Action queue and lifecycle result |\n\n`candidate_capabilities` in a direct objective is a model hint. It does not add\nan admitted capability, authorize a call, bypass approval, or replace schema\nvalidation. The AIP MCP server remains the execution boundary for downstream\nactions.\n\nFirst-class delegation is stricter. Hermes receives one exact `aip_call`\nargument object and instructions to invoke it once without rewriting it. The\nconnector ignores Hermes final prose as the delegated business result.\n\n## Submit a direct objective\n\nThe input schema selects exactly one branch: `objective` or `resume`. Do not\nsend both.\n\nAn objective request accepts:\n\n| Field | Constraint | Purpose |\n|---|---|---|\n| `objective` | Required non-empty string | The bounded outcome for Hermes to pursue |\n| `context` | Any JSON value | Application context treated as data, not authority |\n| `candidate_capabilities` | At most 256 non-empty strings | Hints about relevant admitted capabilities |\n| `constraints` | Object | Task-specific limits that do not override AIP policy |\n\nA bounded input can look like this:\n\n```json\n{\n  \"objective\": \"Read the open support case and prepare a factual summary.\",\n  \"context\": {\n    \"case_id\": \"case-example-2030\"\n  },\n  \"candidate_capabilities\": [\n    \"cap:support:case.get\"\n  ],\n  \"constraints\": {\n    \"allow_mutations\": false\n  }\n}\n```\n\nSet the AIP Action ID, idempotency key, approval decision, identity, deadline,\nand delegation chain on the Action itself. Do not place them inside this input.\n\nThe connector serializes a provider payload with kind\n`aip_operator_objective`. It assigns the stable Hermes session ID\n`aip-operator-<action_id>` and adds deployment-owned system instructions. Those\ninstructions require server-assigned downstream Action IDs, prohibit reuse of\nthe enclosing operator Action ID, and reject fabricated results or approvals.\n\nThe serialized provider input defaults to at most 1 MiB. An optional model is\nselected only by deployment policy. Client input cannot choose an endpoint URL,\nprovider credential, system instruction, or model route for the operator.\n\n## Understand the durable binding\n\nBefore the connector calls Hermes, it creates one profile-state record under\n`aip.connector.hermes_agent.operator_runs.v1`, keyed by the source AIP Action\nID.\n\n| Binding field | Purpose |\n|---|---|\n| `action_id`, `request_fingerprint` | Detect exact replay and changed-input reuse |\n| `endpoint_id`, `run_id`, `session_id` | Correlate AIP state to one endpoint and provider run |\n| `start_claim` | Fence the non-idempotent external start |\n| `delegation_id`, `parent_action_id` | Correlate a first-class delegated child |\n| `status`, `cancel_requested` | Retain lifecycle and cancellation intent |\n| `last_event`, `next_sequence` | Retain event progress for AIP publication |\n| `approval_generation`, `approval_commands` | Fence provider approval continuations |\n| `pending_approval` | Retain the redacted current approval event |\n| `output`, `error` | Replay the terminal AIP result without starting Hermes again |\n| `created_at`, `updated_at` | Record durable state transitions |\n\n“Durable” means durable in the configured AIP profile-state backend. It does\nnot describe the provider's in-memory run API. A deployment that uses an\nephemeral state backend cannot claim restart recovery merely because this\nrecord type exists.\n\nThe standalone Hermes host wires its prepared runtime profile-state store into\nthe connector. It also supplies the runtime approval store, Action queue, and\nlifecycle store needed for delegated result verification.\n\n## Follow the operator states\n\n| State | Meaning | Replay behavior |\n|---|---|---|\n| `starting` | AIP owns the source Action, but no provider `run_id` is bound | One exclusive start claim may call Hermes |\n| `running` | A provider `run_id` is durably bound | Re-entry observes the existing run |\n| `waiting_for_approval` | A provider approval event is retained | Return `RequiresHuman`; wait for a new resume Action |\n| `cancelling` | Cancellation intent is durable and stop reconciliation is active | Do not start or approve new work |\n| `completed` | Provider completion is retained | Return the stored completed result |\n| `failed` | A definitive provider or connector failure is retained | Return the stored failed result |\n| `cancelled` | Provider terminal cancellation is retained | Return the stored cancelled result |\n| `outcome_unknown` | An external mutation may have happened without durable confirmation | Return failure and never replay automatically |\n\n`completed`, `failed`, `cancelled`, and `outcome_unknown` are terminal binding\nstates. A waiting approval is not terminal provider state, but it produces an\nAIP `RequiresHuman` result for the current invocation.\n\n## Read an operator result\n\nEvery operator result exposes the source binding rather than an unstructured\nprovider body:\n\n```json\n{\n  \"endpoint_id\": \"primary\",\n  \"run_id\": \"run_0123456789abcdef0123456789abcdef\",\n  \"session_id\": \"aip-operator-act_0123456789abcdef0123456789abcdef\",\n  \"source_action_id\": \"act_0123456789abcdef0123456789abcdef\",\n  \"delegation_id\": null,\n  \"parent_action_id\": null,\n  \"status\": \"completed\",\n  \"last_event\": \"run.completed\",\n  \"pending_approval\": null,\n  \"provider\": {\n    \"event\": \"run.completed\",\n    \"output\": \"The requested case was read and summarized.\"\n  }\n}\n```\n\nThe output schema requires `endpoint_id`, `session_id`, `source_action_id`, and\n`status`. The connector also emits the nullable correlation, approval, and\nprovider fields shown above.\n\nA direct objective maps terminal binding state to Completed, Failed, Cancelled,\nor RequiresHuman. A resume invocation returns that source outcome under the new\nresume Action ID, while `source_action_id` continues to identify the original\nbinding. For first-class delegation, the native child Action result replaces\nthe provider operator output as the business result.\n\n## Fence provider start\n\nHermes `POST /v1/runs` is not provider-idempotent. The connector protects it\nwith a compare-and-set claim that contains a unique claim ID, connector\ninstance ID, acquisition time, and expiry. The default claim window is 60\nseconds.\n\nConcurrent invocations with the same Action and fingerprint observe one\nbinding. Only the claim winner sends the provider start. Other invocations wait\nfor a bound `run_id` or a terminal record.\n\nThe outcomes are deliberately asymmetric:\n\n| Start outcome | Binding result |\n|---|---|\n| Provider `4xx` | Definitive `failed`; the run was rejected before acceptance |\n| Success with a non-empty `run_id` | Bind the ID, clear the claim, and observe that run |\n| Success without `run_id` | `outcome_unknown` |\n| Transport failure or provider `5xx` | `outcome_unknown` |\n| Claim owner disappears or expires before binding | `outcome_unknown` |\n\nAnother process never steals an unbound external-start claim and sends a second\nstart. It marks the source outcome unknown instead. Reusing the source Action\nID with a different endpoint, input, or delegation request produces an\nidempotency collision.\n\nThe required AIP idempotency key remains important for runtime-level replay.\nThe connector's second fence is keyed by Action ID. The provider does not\nenforce the forwarded idempotency header on its run-start route.\n\n## Observe events and recover by polling\n\nImmediately after binding a new run, the connector attempts the provider SSE\nstream. It records every event name and next AIP sequence in profile state and\npublishes typed AIP stream chunks when trusted execution supplied a stream.\n\n| Provider event | AIP stream kind | Binding effect |\n|---|---|---|\n| `message.delta` | Data | Advance sequence |\n| `reasoning.available` | Thought | Advance sequence |\n| `tool.started`, `tool.completed` | Tool | Advance sequence |\n| `approval.request` | PendingApproval | Increment approval generation and wait |\n| `run.failed` | Error | Retain terminal failure |\n| `run.completed`, `run.cancelled` | Done | Retain the corresponding terminal state |\n| Other event | Progress | Retain name and advance sequence |\n\nThe default limit is 4096 events, and one SSE frame is capped at 1 MiB. The\noperator observation defaults to 15 minutes and uses the trusted AIP deadline\nwhen one is shorter.\n\nIf initial event subscription returns `404`, the HTTP request fails, or the\nstream decode fails, the connector polls `GET /v1/runs/{run_id}` instead. A\nreplayed invocation and restart recovery also poll rather than trying to resume\nan already consumed provider stream.\n\nPolling defaults to every 250 ms. It recognizes `queued`, `running`,\n`waiting_for_approval`, `stopping`, `completed`, `failed`, and `cancelled`.\nAnother state fails closed as unsupported.\n\n## Resume a provider approval\n\nAn `approval.request` stores the redacted provider event, increments the source\nbinding's approval generation, and returns an AIP `RequiresHuman` result. The\noperator capability itself remains high risk and AIP-approval governed.\n\nAfter review, create a new operator Action with a new Action ID and idempotency\nkey. Point it to the source Action:\n\n```json\n{\n  \"resume\": {\n    \"source_action_id\": \"act_0123456789abcdef0123456789abcdef\",\n    \"choice\": \"once\",\n    \"resolve_all\": false\n  }\n}\n```\n\nThe allowed choices are exactly `once`, `session`, `always`, and `deny`. The\nresume endpoint must match the source binding's endpoint. `resolve_all` applies\nonly to pending provider approvals in that run.\n\nThe connector records each resume command inside the source binding before it\ncontacts Hermes. The record contains the resume Action ID, canonical\nfingerprint, approval generation, decision, claim owner, timestamps, and one of\nthese states:\n\n| Command state | Meaning |\n|---|---|\n| `claimed` | One connector invocation owns the provider approval call |\n| `applied` | Hermes accepted the decision; exact replay returns stored progress |\n| `rejected` | Hermes returned a definitive `4xx` before applying it |\n| `outcome_unknown` | Hermes may have applied the decision; replay is blocked |\n\nThe claim uses the same default 60-second fencing window as provider start.\nThe ledger is capped at 256 commands per source run. Reusing a resume Action ID\nwith changed input is rejected. A transport failure or `5xx` marks both the\ncommand and source binding outcome unknown.\n\nThis command ledger is separate from the tenant-policy AIP approval record that\nauthorizes the resume Action. It is also separate from the provider's own\nin-memory approval queue.\n\n## Reconcile cancellation\n\nCancellation first writes `cancel_requested` to the durable source binding. It\ncan therefore arrive before Hermes returns a `run_id`. Once the ID is bound,\nthe connector sends `POST /v1/runs/{run_id}/stop` and polls status.\n\nThis connector path runs only while the cancelled source or resume Action is\nactive in the AIP runtime. After an operator invocation has returned\n`RequiresHuman`, that invocation is no longer active. Cancelling its native\nAIP lifecycle record does not call the connector again and therefore does not\nstop the waiting Hermes run.\n\nTo refuse the pending provider operation, submit a separately governed\noperator resume with `choice: deny`. To request full interruption while no\noperator Action is active, use the separately approved `run_stop` capability\nwith the retained `run_id`, then reconcile the operator binding as an\noperational exception. The public operator input has no standalone stop branch.\n\nThe default cancellation grace window is 15 seconds. A racing `completed` or\n`failed` state remains authoritative. Only provider-confirmed `cancelled`\nbecomes the connector's cancelled operator result. A missing or non-terminal\nresult at the end of the grace window becomes\n`connector.hermes_agent.cancellation_outcome_unknown`.\n\nThe native cancel endpoint returns an AIP `cancelled` response after an active\nhandler's cancellation callback succeeds. That response does not expose the\nconnector's provider reconciliation result and is not proof that Hermes reached\n`cancelled`. Retain provider or operator-binding evidence separately.\n\nCancellation does not roll back model calls, tools, messages, or external\neffects. A provider `stopping` receipt is progress, not terminal evidence.\n\n## Route first-class delegation\n\nThe delegated entry does not invoke the public `operator` capability with an\nobjective. A native `DelegationRequest` selects a configured endpoint through\nthe delegate principal:\n\n```text\nagent:hermes_operator:<endpoint_id>\n```\n\nThe delegate must be an Agent principal. The connector checks the endpoint's\ntenant boundary before it accepts the route.\n\nDelegation policy is fail-closed:\n\n- `delegation_enabled` defaults to `false`;\n- enabling it requires explicit capability-ID and scope prefix lists;\n- `*` opts into an unrestricted dimension and should receive explicit review;\n- the current chain length must be below the configured depth limit;\n- durable connector-level approval verification defaults to enabled;\n- any approval exemption uses a textual capability prefix and should be as\n  narrow as one complete capability ID.\n\nNormal AIP authorization, capability contracts, tenant checks, and downstream\napproval still apply. The connector-level exemption changes only its extra\ndelegation approval check.\n\nFor an admitted request, the connector serializes the exact child Action as\n`aip_call_arguments`. It renames the serialized `id` field to `action_id` and\nremoves `identity`, because the authenticated MCP transport supplies identity.\nInstructions require Hermes to call `aip_call` exactly once with those\narguments and forbid another state-changing tool.\n\nDo not expose recursive `aip_delegate` as a model-facing shortcut. The external\nAIP runtime owns the delegation graph, depth, cycle, scope, approval, and child\nAction invariants.\n\n## Verify the delegated result\n\nHermes completion means only that the provider operator run ended. For\nfirst-class delegation, the connector then resolves the exact native child\nAction from the authoritative Action queue and lifecycle store.\n\nThe resolver verifies:\n\n1. immutable Action ID, capability, input, mode, idempotency, timeout,\n   conversation, delegation, federation, callback, observability, compliance,\n   approval, and transaction fields;\n2. application memory context, while allowing trusted `_aip` enrichment;\n3. a non-expired transport-authenticated principal with `action:write`;\n4. the same expected Hermes principal in queue owner, authenticated owner, and\n   actor context;\n5. equality between Action identity and resolved trusted identity;\n6. the exact valid tenant partition;\n7. agreement between queue and lifecycle results;\n8. the expected child Action ID on the terminal result.\n\nIf no child execution appears, the resolver waits four poll intervals, bounded\nto one through five seconds, then fails with\n`delegated_execution_not_observed`. Once the child is observed, it may wait to\nthe operator resolution deadline for a terminal result.\n\nA terminal queue record without a durable result, disagreement between stores,\ncontract drift, identity mismatch, or tenant mismatch fails closed. Hermes\nfinal text never substitutes for the missing native result.\n\n## Apply operator policy bounds\n\n| Policy field | Default | Valid bound or rule |\n|---|---:|---|\n| `delegation_enabled` | `false` | Explicit opt-in |\n| `delegation_requires_approval` | `true` | Durable approval store required when applied |\n| `model` | None | Deployment-owned optional route |\n| `system_instructions` | Governed built-in text | Non-empty; at most 131072 bytes |\n| `timeout_ms` | `900000` | 1000–86400000 |\n| `poll_interval_ms` | `250` | 10–60000 |\n| `max_events` | `4096` | 1–100000 |\n| `max_input_bytes` | `1048576` | 1024–16777216 |\n| `max_delegation_depth` | `16` | 1–128 |\n| `start_claim_ttl_ms` | `60000` | 1000–300000 |\n| `cancel_grace_ms` | `15000` | 1000–300000 |\n| Capability and scope prefixes | Empty | Must both be explicit when delegation is enabled |\n\nThe connector validates this policy before an operator run. Empty or oversized\nprefixes are rejected. Prefix matching is textual `starts_with`, not a semantic\ncapability or scope parser.\n\n## Handle failures\n\n| Failure | Meaning | Response |\n|---|---|---|\n| `connector.hermes_agent.operator_policy` | Policy denial, changed-input reuse, or a missing source binding | Correct policy or identity; do not retry unchanged |\n| `connector.hermes_agent.operator_state` | Profile-state read, parse, compare-and-set, or contention failure | Protect the state backend and inspect its revision history |\n| `operator_outcome_unknown` | Provider start may have happened before durable binding | Reconcile externally; never auto-start again |\n| `approval_outcome_unknown` | Provider may have accepted a resume command | Inspect source state; never resend that command blindly |\n| `cancellation_outcome_unknown` | Stop did not reach a confirmed terminal state | Treat earlier effects as uncertain and escalate |\n| Delegated integrity or identity error | Native child state disagrees with the requested contract | Fail closed and retain both store records |\n| Delegated execution not observed | Hermes completed without the exact child Action | Reject model prose as evidence |\n\nThe connector returns terminal binding results idempotently. Temporary provider\nread failures can fall back to polling, but no failure turns an unknown external\nmutation into a safe replay.\n\n## Verify an integration\n\nFor each enabled endpoint, retain evidence that:\n\n1. the operator manifest matches the contract and requires AIP approval;\n2. concurrent replay of one source Action creates one provider run;\n3. changed input under the same Action ID is rejected;\n4. a lost unbound start becomes `outcome_unknown` after process replacement;\n5. an approval prompt returns `RequiresHuman`, and exact resume replay sends one\n   provider command;\n6. cancellation is called cancelled only after provider terminal evidence;\n7. delegation remains disabled without both explicit allowlists;\n8. the model-facing payload contains exact `aip_call` arguments without\n   identity;\n9. the resolver rejects altered contracts, forged owners, tenant drift, and\n   disagreement between durable stores;\n10. the profile-state, approval, Action-queue, and lifecycle backends used by\n    the artifact have the claimed durability.\n\nRecord exact AIP, connector-host, Hermes, policy, endpoint, tenant, credential,\nand storage identities with timestamps and retained results. Source tests show\nimplemented controls; they are not evidence that a deployed artifact passed\nthem.\n\n## Related documentation\n\n- [Hermes Agent capabilities](README.md)\n- [Structured runs and approvals](durable-runs-and-approvals.md)\n- [Delegation](../../../concepts/delegation.md)\n- [Approvals and policy](../../../concepts/approvals-and-policy.md)\n- [Errors and recovery](../../../reference/errors.md)\n",
    "text": "Hermes operator and delegation capability\n\nUse the endpoint-qualified operator capability when Hermes must plan a\ngoverned objective, call admitted AIP tools, pause for approval, resume the same\nprovider run, or reconcile cancellation across a process restart.\n\nThis lifecycle adds a durable AIP binding around a volatile Hermes structured\nrun. It does not make Hermes run storage durable. The binding prevents an\nunknown external start or approval command from being replayed automatically.\n\nThe same connector can also own first-class AIP delegation. That route is\ndisabled by default and uses a different entry contract: the child Action keeps\nits real capability ID, while the delegate principal selects the Hermes\nendpoint.\n\nOperation contract\n\nReplace  with the normalized endpoint ID present in AIP\ndiscovery.\n\n| Field | Published value |\n\n| Capability | cap:hermesagent::operator |\n| Provider request | POST /v1/runs with endpoint Bearer authentication |\n| Kind and stability | Agent; stable |\n| Risk and approval | High; tenant-policy AIP approval required |\n| Idempotency | Required; capability scope; 24-hour TTL; ReturnOriginalResult |\n| Side effects | read, write, sendmessage, externalnetwork, codeexecution |\n| Data | Confidential; contains PII; redaction required |\n| Execution | Sync, async, streaming, and cancellation supported |\n| Expected completion | Streaming; asyncexpected is true |\n| Expected latency and timeout | 30 seconds and 15 minutes |\n| Transaction | None |\n| Compensation | Rollback not supported; approval required |\n\nThe approval policy lasts 15 minutes and requires a reason, input snapshot,\nand policy-decision evidence. The contract also declares a 10-second maximum\nqueue-delay hint and a 99.9% availability target. These are declarations, not\nobserved performance or qualification evidence.\n\nChoose direct operator work or delegation\n\n| Need | Entry | Capability carried by the Action | Result authority |\n\n| Ask Hermes to plan and execute a bounded objective | Invoke operator with objective | Hermes operator capability | Governed operator binding and provider terminal result |\n| Continue a source operator Action after a provider approval prompt | Invoke operator with resume in a new Action | Hermes operator capability | Stored source binding plus provider continuation |\n| Delegate one exact native AIP child Action to Hermes | Send a DelegationRequest to agent:hermesoperator: | The child's actual target capability | Native child Action queue and lifecycle result |\n\ncandidatecapabilities in a direct objective is a model hint. It does not add\nan admitted capability, authorize a call, bypass approval, or replace schema\nvalidation. The AIP MCP server remains the execution boundary for downstream\nactions.\n\nFirst-class delegation is stricter. Hermes receives one exact aipcall\nargument object and instructions to invoke it once without rewriting it. The\nconnector ignores Hermes final prose as the delegated business result.\n\nSubmit a direct objective\n\nThe input schema selects exactly one branch: objective or resume. Do not\nsend both.\n\nAn objective request accepts:\n\n| Field | Constraint | Purpose |\n\n| objective | Required non-empty string | The bounded outcome for Hermes to pursue |\n| context | Any JSON value | Application context treated as data, not authority |\n| candidatecapabilities | At most 256 non-empty strings | Hints about relevant admitted capabilities |\n| constraints | Object | Task-specific limits that do not override AIP policy |\n\nA bounded input can look like this:\n\n{\n  \"objective\": \"Read the open support case and prepare a factual summary.\",\n  \"context\": {\n    \"caseid\": \"case-example-2030\"\n  },\n  \"candidatecapabilities\": [\n    \"cap:support:case.get\"\n  ],\n  \"constraints\": {\n    \"allowmutations\": false\n  }\n}\n\nSet the AIP Action ID, idempotency key, approval decision, identity, deadline,\nand delegation chain on the Action itself. Do not place them inside this input.\n\nThe connector serializes a provider payload with kind\naipoperatorobjective. It assigns the stable Hermes session ID\naip-operator- and adds deployment-owned system instructions. Those\ninstructions require server-assigned downstream Action IDs, prohibit reuse of\nthe enclosing operator Action ID, and reject fabricated results or approvals.\n\nThe serialized provider input defaults to at most 1 MiB. An optional model is\nselected only by deployment policy. Client input cannot choose an endpoint URL,\nprovider credential, system instruction, or model route for the operator.\n\nUnderstand the durable binding\n\nBefore the connector calls Hermes, it creates one profile-state record under\naip.connector.hermesagent.operatorruns.v1, keyed by the source AIP Action\nID.\n\n| Binding field | Purpose |\n\n| actionid, requestfingerprint | Detect exact replay and changed-input reuse |\n| endpointid, runid, sessionid | Correlate AIP state to one endpoint and provider run |\n| startclaim | Fence the non-idempotent external start |\n| delegationid, parentactionid | Correlate a first-class delegated child |\n| status, cancelrequested | Retain lifecycle and cancellation intent |\n| lastevent, nextsequence | Retain event progress for AIP publication |\n| approvalgeneration, approvalcommands | Fence provider approval continuations |\n| pendingapproval | Retain the redacted current approval event |\n| output, error | Replay the terminal AIP result without starting Hermes again |\n| createdat, updatedat | Record durable state transitions |\n\n“Durable” means durable in the configured AIP profile-state backend. It does\nnot describe the provider's in-memory run API. A deployment that uses an\nephemeral state backend cannot claim restart recovery merely because this\nrecord type exists.\n\nThe standalone Hermes host wires its prepared runtime profile-state store into\nthe connector. It also supplies the runtime approval store, Action queue, and\nlifecycle store needed for delegated result verification.\n\nFollow the operator states\n\n| State | Meaning | Replay behavior |\n\n| starting | AIP owns the source Action, but no provider runid is bound | One exclusive start claim may call Hermes |\n| running | A provider runid is durably bound | Re-entry observes the existing run |\n| waitingforapproval | A provider approval event is retained | Return RequiresHuman; wait for a new resume Action |\n| cancelling | Cancellation intent is durable and stop reconciliation is active | Do not start or approve new work |\n| completed | Provider completion is retained | Return the stored completed result |\n| failed | A definitive provider or connector failure is retained | Return the stored failed result |\n| cancelled | Provider terminal cancellation is retained | Return the stored cancelled result |\n| outcomeunknown | An external mutation may have happened without durable confirmation | Return failure and never replay automatically |\n\ncompleted, failed, cancelled, and outcomeunknown are terminal binding\nstates. A waiting approval is not terminal provider state, but it produces an\nAIP RequiresHuman result for the current invocation.\n\nRead an operator result\n\nEvery operator result exposes the source binding rather than an unstructured\nprovider body:\n\n{\n  \"endpointid\": \"primary\",\n  \"runid\": \"run0123456789abcdef0123456789abcdef\",\n  \"sessionid\": \"aip-operator-act0123456789abcdef0123456789abcdef\",\n  \"sourceactionid\": \"act0123456789abcdef0123456789abcdef\",\n  \"delegationid\": null,\n  \"parentactionid\": null,\n  \"status\": \"completed\",\n  \"lastevent\": \"run.completed\",\n  \"pendingapproval\": null,\n  \"provider\": {\n    \"event\": \"run.completed\",\n    \"output\": \"The requested case was read and summarized.\"\n  }\n}\n\nThe output schema requires endpointid, sessionid, sourceactionid, and\nstatus. The connector also emits the nullable correlation, approval, and\nprovider fields shown above.\n\nA direct objective maps terminal binding state to Completed, Failed, Cancelled,\nor RequiresHuman. A resume invocation returns that source outcome under the new\nresume Action ID, while sourceactionid continues to identify the original\nbinding. For first-class delegation, the native child Action result replaces\nthe provider operator output as the business result.\n\nFence provider start\n\nHermes POST /v1/runs is not provider-idempotent. The connector protects it\nwith a compare-and-set claim that contains a unique claim ID, connector\ninstance ID, acquisition time, and expiry. The default claim window is 60\nseconds.\n\nConcurrent invocations with the same Action and fingerprint observe one\nbinding. Only the claim winner sends the provider start. Other invocations wait\nfor a bound runid or a terminal record.\n\nThe outcomes are deliberately asymmetric:\n\n| Start outcome | Binding result |\n\n| Provider 4xx | Definitive failed; the run was rejected before acceptance |\n| Success with a non-empty runid | Bind the ID, clear the claim, and observe that run |\n| Success without runid | outcomeunknown |\n| Transport failure or provider 5xx | outcomeunknown |\n| Claim owner disappears or expires before binding | outcomeunknown |\n\nAnother process never steals an unbound external-start claim and sends a second\nstart. It marks the source outcome unknown instead. Reusing the source Action\nID with a different endpoint, input, or delegation request produces an\nidempotency collision.\n\nThe required AIP idempotency key remains important for runtime-level replay.\nThe connector's second fence is keyed by Action ID. The provider does not\nenforce the forwarded idempotency header on its run-start route.\n\nObserve events and recover by polling\n\nImmediately after binding a new run, the connector attempts the provider SSE\nstream. It records every event name and next AIP sequence in profile state and\npublishes typed AIP stream chunks when trusted execution supplied a stream.\n\n| Provider event | AIP stream kind | Binding effect |\n\n| message.delta | Data | Advance sequence |\n| reasoning.available | Thought | Advance sequence |\n| tool.started, tool.completed | Tool | Advance sequence |\n| approval.request | PendingApproval | Increment approval generation and wait |\n| run.failed | Error | Retain terminal failure |\n| run.completed, run.cancelled | Done | Retain the corresponding terminal state |\n| Other event | Progress | Retain name and advance sequence |\n\nThe default limit is 4096 events, and one SSE frame is capped at 1 MiB. The\noperator observation defaults to 15 minutes and uses the trusted AIP deadline\nwhen one is shorter.\n\nIf initial event subscription returns 404, the HTTP request fails, or the\nstream decode fails, the connector polls GET /v1/runs/{runid} instead. A\nreplayed invocation and restart recovery also poll rather than trying to resume\nan already consumed provider stream.\n\nPolling defaults to every 250 ms. It recognizes queued, running,\nwaitingforapproval, stopping, completed, failed, and cancelled.\nAnother state fails closed as unsupported.\n\nResume a provider approval\n\nAn approval.request stores the redacted provider event, increments the source\nbinding's approval generation, and returns an AIP RequiresHuman result. The\noperator capability itself remains high risk and AIP-approval governed.\n\nAfter review, create a new operator Action with a new Action ID and idempotency\nkey. Point it to the source Action:\n\n{\n  \"resume\": {\n    \"sourceactionid\": \"act0123456789abcdef0123456789abcdef\",\n    \"choice\": \"once\",\n    \"resolveall\": false\n  }\n}\n\nThe allowed choices are exactly once, session, always, and deny. The\nresume endpoint must match the source binding's endpoint. resolveall applies\nonly to pending provider approvals in that run.\n\nThe connector records each resume command inside the source binding before it\ncontacts Hermes. The record contains the resume Action ID, canonical\nfingerprint, approval generation, decision, claim owner, timestamps, and one of\nthese states:\n\n| Command state | Meaning |\n\n| claimed | One connector invocation owns the provider approval call |\n| applied | Hermes accepted the decision; exact replay returns stored progress |\n| rejected | Hermes returned a definitive 4xx before applying it |\n| outcomeunknown | Hermes may have applied the decision; replay is blocked |\n\nThe claim uses the same default 60-second fencing window as provider start.\nThe ledger is capped at 256 commands per source run. Reusing a resume Action ID\nwith changed input is rejected. A transport failure or 5xx marks both the\ncommand and source binding outcome unknown.\n\nThis command ledger is separate from the tenant-policy AIP approval record that\nauthorizes the resume Action. It is also separate from the provider's own\nin-memory approval queue.\n\nReconcile cancellation\n\nCancellation first writes cancelrequested to the durable source binding. It\ncan therefore arrive before Hermes returns a runid. Once the ID is bound,\nthe connector sends POST /v1/runs/{runid}/stop and polls status.\n\nThis connector path runs only while the cancelled source or resume Action is\nactive in the AIP runtime. After an operator invocation has returned\nRequiresHuman, that invocation is no longer active. Cancelling its native\nAIP lifecycle record does not call the connector again and therefore does not\nstop the waiting Hermes run.\n\nTo refuse the pending provider operation, submit a separately governed\noperator resume with choice: deny. To request full interruption while no\noperator Action is active, use the separately approved runstop capability\nwith the retained runid, then reconcile the operator binding as an\noperational exception. The public operator input has no standalone stop branch.\n\nThe default cancellation grace window is 15 seconds. A racing completed or\nfailed state remains authoritative. Only provider-confirmed cancelled\nbecomes the connector's cancelled operator result. A missing or non-terminal\nresult at the end of the grace window becomes\nconnector.hermesagent.cancellationoutcomeunknown.\n\nThe native cancel endpoint returns an AIP cancelled response after an active\nhandler's cancellation callback succeeds. That response does not expose the\nconnector's provider reconciliation result and is not proof that Hermes reached\ncancelled. Retain provider or operator-binding evidence separately.\n\nCancellation does not roll back model calls, tools, messages, or external\neffects. A provider stopping receipt is progress, not terminal evidence.\n\nRoute first-class delegation\n\nThe delegated entry does not invoke the public operator capability with an\nobjective. A native DelegationRequest selects a configured endpoint through\nthe delegate principal:\n\nagent:hermesoperator:\n\nThe delegate must be an Agent principal. The connector checks the endpoint's\ntenant boundary before it accepts the route.\n\nDelegation policy is fail-closed:\n• delegationenabled defaults to false;\n• enabling it requires explicit capability-ID and scope prefix lists;\n•  opts into an unrestricted dimension and should receive explicit review;\n• the current chain length must be below the configured depth limit;\n• durable connector-level approval verification defaults to enabled;\n• any approval exemption uses a textual capability prefix and should be as\n  narrow as one complete capability ID.\n\nNormal AIP authorization, capability contracts, tenant checks, and downstream\napproval still apply. The connector-level exemption changes only its extra\ndelegation approval check.\n\nFor an admitted request, the connector serializes the exact child Action as\naipcallarguments. It renames the serialized id field to actionid and\nremoves identity, because the authenticated MCP transport supplies identity.\nInstructions require Hermes to call aipcall exactly once with those\narguments and forbid another state-changing tool.\n\nDo not expose recursive aipdelegate as a model-facing shortcut. The external\nAIP runtime owns the delegation graph, depth, cycle, scope, approval, and child\nAction invariants.\n\nVerify the delegated result\n\nHermes completion means only that the provider operator run ended. For\nfirst-class delegation, the connector then resolves the exact native child\nAction from the authoritative Action queue and lifecycle store.\n\nThe resolver verifies:\n1. immutable Action ID, capability, input, mode, idempotency, timeout,\n   conversation, delegation, federation, callback, observability, compliance,\n   approval, and transaction fields;\n2. application memory context, while allowing trusted aip enrichment;\n3. a non-expired transport-authenticated principal with action:write;\n4. the same expected Hermes principal in queue owner, authenticated owner, and\n   actor context;\n5. equality between Action identity and resolved trusted identity;\n6. the exact valid tenant partition;\n7. agreement between queue and lifecycle results;\n8. the expected child Action ID on the terminal result.\n\nIf no child execution appears, the resolver waits four poll intervals, bounded\nto one through five seconds, then fails with\ndelegatedexecutionnotobserved. Once the child is observed, it may wait to\nthe operator resolution deadline for a terminal result.\n\nA terminal queue record without a durable result, disagreement between stores,\ncontract drift, identity mismatch, or tenant mismatch fails closed. Hermes\nfinal text never substitutes for the missing native result.\n\nApply operator policy bounds\n\n| Policy field | Default | Valid bound or rule |\n\n| delegationenabled | false | Explicit opt-in |\n| delegationrequiresapproval | true | Durable approval store required when applied |\n| model | None | Deployment-owned optional route |\n| systeminstructions | Governed built-in text | Non-empty; at most 131072 bytes |\n| timeoutms | 900000 | 1000–86400000 |\n| pollintervalms | 250 | 10–60000 |\n| maxevents | 4096 | 1–100000 |\n| maxinputbytes | 1048576 | 1024–16777216 |\n| maxdelegationdepth | 16 | 1–128 |\n| startclaimttlms | 60000 | 1000–300000 |\n| cancelgracems | 15000 | 1000–300000 |\n| Capability and scope prefixes | Empty | Must both be explicit when delegation is enabled |\n\nThe connector validates this policy before an operator run. Empty or oversized\nprefixes are rejected. Prefix matching is textual startswith, not a semantic\ncapability or scope parser.\n\nHandle failures\n\n| Failure | Meaning | Response |\n\n| connector.hermesagent.operatorpolicy | Policy denial, changed-input reuse, or a missing source binding | Correct policy or identity; do not retry unchanged |\n| connector.hermesagent.operatorstate | Profile-state read, parse, compare-and-set, or contention failure | Protect the state backend and inspect its revision history |\n| operatoroutcomeunknown | Provider start may have happened before durable binding | Reconcile externally; never auto-start again |\n| approvaloutcomeunknown | Provider may have accepted a resume command | Inspect source state; never resend that command blindly |\n| cancellationoutcomeunknown | Stop did not reach a confirmed terminal state | Treat earlier effects as uncertain and escalate |\n| Delegated integrity or identity error | Native child state disagrees with the requested contract | Fail closed and retain both store records |\n| Delegated execution not observed | Hermes completed without the exact child Action | Reject model prose as evidence |\n\nThe connector returns terminal binding results idempotently. Temporary provider\nread failures can fall back to polling, but no failure turns an unknown external\nmutation into a safe replay.\n\nVerify an integration\n\nFor each enabled endpoint, retain evidence that:\n1. the operator manifest matches the contract and requires AIP approval;\n2. concurrent replay of one source Action creates one provider run;\n3. changed input under the same Action ID is rejected;\n4. a lost unbound start becomes outcomeunknown after process replacement;\n5. an approval prompt returns RequiresHuman, and exact resume replay sends one\n   provider command;\n6. cancellation is called cancelled only after provider terminal evidence;\n7. delegation remains disabled without both explicit allowlists;\n8. the model-facing payload contains exact aipcall arguments without\n   identity;\n9. the resolver rejects altered contracts, forged owners, tenant drift, and\n   disagreement between durable stores;\n10. the profile-state, approval, Action-queue, and lifecycle backends used by\n    the artifact have the claimed durability.\n\nRecord exact AIP, connector-host, Hermes, policy, endpoint, tenant, credential,\nand storage identities with timestamps and retained results. Source tests show\nimplemented controls; they are not evidence that a deployed artifact passed\nthem.\n\nRelated documentation\n• Hermes Agent capabilities (README.md)\n• Structured runs and approvals (durable-runs-and-approvals.md)\n• Delegation (../../../concepts/delegation.md)\n• Approvals and policy (../../../concepts/approvals-and-policy.md)\n• Errors and recovery (../../../reference/errors.md)\n"
  },
  "integrity": {
    "algorithm": "sha256",
    "sourceDigest": "1b20b812a82dbfc7b3086b34b66eed97795d6ac211562b757b2a67e8781877f8"
  }
}
