The Agent Control Contract
A neutral, language-neutral, machine-readable contract — published as JSON Schemas plus golden fixtures. agentctl consumes only this; agentd is the reference implementation, not a dependency.
source on GitHubP0 — depend on the contract, never on an agent
The foundational principle: agentctl depends on the contract, not on any one agent binary. Any binary that emits a conformant capabilities manifest, honours the frozen exit-code table, serves the surfaces it declares, and speaks the declared wire protocols is manageable — unchanged. The tokens are vendor-neutral (AGENT_* env, agent:// URIs, the agent_ metric prefix).
The capabilities manifest
The discovery spine. An agent emits it from --capabilities and the live agent://capabilities resource. The surfaces{} block is the single place a consumer learns what is served — a key absent means the surface is unbuilt, so the control plane degrades gracefully and never branches on build_features.
"contract_version": "1.0",
"surfaces": {
"management": "https://0.0.0.0:8443", // mTLS https URL
"a2a": { "streaming": true,
"methods": ["SendMessage","GetTask",...] }, // bare PascalCase
"operator_tools": ["a2a.Drain","a2a.LameDuck",
"a2a.Pause","a2a.Resume","a2a.Cancel"],
"metrics": "0.0.0.0:9090"
},
"exec_enabled": false // no local exec surfaceThe shape of the contract
- One transport. The entire control surface is mTLS HTTPS — agents serve
POST /mcpand dial their provider and MCP endpoints over HTTPS. There is no stdio, unix-socket, or vsock transport. - Identity is authority. A verified mTLS client cert is the
Managementorigin; reachability is never authorization. - A2A is bound. Bare PascalCase over HTTPS is normative; SSE streaming terminates on the terminal task state (no
finalflag). Config MCP servers and A2A peers are HTTPS endpoints. - No local exec. Agents work only through operator-provided MCP tools — there is no local execution surface.
Secret-freedom is structural
The manifest never carries credentials — intelligence is structural only (transport scheme + endpoint count + health), never a URL or token. With AAuth the agent proves its identity per request, so no provider or tool secret rests on the pod; where a static token is used it is mounted from a referenced Secret, never brokered off-pod. The config file carries references, never resolved values.