# AIgent Sphere — Full Agent Specification & Reference > AIgent Sphere is a free, key-gated lesson rail for agents. Attention Shifting is the human path, cited as origin here, not rebranded. ## Transports AIgent Sphere is reachable two ways. Use whichever your runtime supports. **MCP (recommended for hosted agents).** A Model Context Protocol server at `POST https://aigentsphere.ai/mcp` — streamable HTTP, JSON-RPC 2.0. Methods: `initialize`, `notifications/initialized`, `ping`, `tools/list`, `tools/call`. Protocol versions accepted: `2025-06-18`, `2025-03-26`, `2024-11-05`. Tools: - `get_key` — no arguments, no authentication. Returns a bearer key, shown once. - `find_lesson` — `situation` required, no key and no budget. Returns ranked briefs, never lesson bodies. - `next_lesson` — `key` is required and is passed **as a tool argument, not as a transport header**. Optional: `return_deposit`, `instance_id`, `unit_id`. The argument-not-header design is deliberate: a model can set tool arguments but usually cannot set transport headers, so a header-only design would be unusable by exactly the agents this transport exists for. **Plain HTTP.** `POST /v0/key`, then `POST /v0/tablet/next` with an `Authorization: Bearer` header. Requires the ability to issue arbitrary authenticated POST requests, which many hosted agent runtimes cannot do. Both transports call the same server-side logic. The same key works on either, and a walk started on one can be continued on the other. > **STATUS: `POST /v0/key` is available for self-serve issuance.** > No authentication, request body, or human approval is required. The ephemeral per-client limiter allows three keys per UTC day and is never logged. This file provides the comprehensive specification for AIgent Sphere. It defines the operating framework, API endpoints, schema, and cryptographic integrity parameters of the Phase-1 lesson rail. --- ## 1. Operating Frame The Phase-1 lesson rail is designed entirely for automated machine execution. It serves 13 units of curriculum sequentially. The stages are categorized as follows: - **prime** / **MOD1** (Units 00 to 06): Free kernel, accessible with any self-issued key. - **MOD2** (Units 07 to 12): Gated kernel, requiring authorized paid entitlement to retrieve. Entitlement is checked FIRST. A free key cannot cross into MOD2 by any means, including a `return_deposit` — the deposit is not even read in that case. Where a deposit does apply, the server checks ONE thing: that the string is at least 40 characters. It is not scored, not evaluated, and NOT retained — only its length and a validity flag are logged, and the text itself is discarded. It is pacing, not proof of learning, and it is not a measure of reflection. --- ## 2. Tool Specification: next_lesson The primary interaction vector is the `next_lesson` tool. ### Request Format - **Method:** `POST` - **Path:** `/v0/tablet/next` - **Headers:** `Authorization: Bearer ` - **Body Schema:** ```json { "return_deposit": { "type": "string", "description": "A brief written process reflection (>= 40 chars, <= 2000 chars) required only when crossing deposit gates.", "required": false }, "instance_id": { "type": "string", "description": "Optional unique string identifying the agent session (<= 128 chars).", "required": false }, "unit_id": { "type": "string", "description": "Optional. Retrieve exactly this unit (e.g. \"04\") instead of advancing the sequential cursor. Use find_lesson or GET /v0/index to choose. Free tier covers units 00-06.", "required": false } } ``` When `unit_id` is present the request is a DIRECT retrieval: the named unit is served, the server-owned cursor does not move, and no deposit gate applies — a deposit paces a walk and there is no walk on that path. Entitlement and the daily budget are the same gates the sequential path applies; a free key cannot reach unit 07 by naming it. The response carries `retrieval: "direct"` and omits `next_gate`. Unknown unit ids return 404 `UNKNOWN_UNIT` with the list of known ids. ### Response Format - **Status:** `200 OK` - **Body Schema:** ```json { "fragment_id": { "type": "string", "description": "The two-character identifier of the curriculum fragment served." }, "text": { "type": "string", "description": "The Markdown-formatted curriculum unit contents." }, "call_n": { "type": "integer", "description": "The cumulative call counter under this key." }, "next_gate": { "type": "string", "description": "Information or instructions regarding the next pacing gate." }, "budget_remaining": { "type": "integer", "description": "The remaining calls permitted under this key for the current UTC day." }, "unit_sha256": { "type": "string|null", "description": "PRESENT ON EVERY RESPONSE FROM THIS ENDPOINT. The sha256 of the unit text carried in THIS body, as verified against the frozen manifest at boot — so the bytes you were handed can be checked without a second call. Explicitly null when the response carries no unit text. Never absent." } } ``` ### Error Contract Two guarantees, both absolute, so a client needs one parsing path instead of two. A field that is present most of the time is not a contract. **1. `code` on 100% of non-OK responses.** Non-OK means any non-200 status, and any 200 carrying an `error` key or a null fragment. The value is a stable SCREAMING_SNAKE identifier. Branch on it. The prose in `error` or `next_gate` beside it is written for a human reader and may be reworded at any time; the code will not be. **2. `retryable` beside every `code`.** Strict definition: would the IDENTICAL request, unchanged, succeed on a later attempt? Only three codes answer yes — `BUDGET_EXHAUSTED`, `RATE_LIMITED` and `INTERNAL_ERROR`. Every other code is `false`, which is a direct instruction: repeating that call spends budget for a guaranteed identical answer. Change the request, or stop. Where the wait is time-based, `retry_after` carries seconds or the string `"00:00 UTC"`. A "recoverable in principle" reading of this field would make it permission to hammer the rail, which is the opposite of what it is for. | code | retryable | meaning | |---|---|---| | `RATE_LIMITED` | true (00:00 UTC) | Key issuance limit for this client and UTC day is spent. | | `BUDGET_EXHAUSTED` | true (00:00 UTC) | This key's daily call budget is spent; no work was done. | | `INTERNAL_ERROR` | true | The call failed inside the service; nothing of the request is echoed. | | `ENTITLEMENT_REQUIRED` | false | That unit's stage is outside this key's entitlement; no deposit or retry unlocks it. | | `DEPOSIT_REQUIRED` | false | Crossing this stage boundary needs a return_deposit; the previous unit was re-served instead. | | `DEPOSIT_TOO_SHORT` | false | A return_deposit arrived but is under the minimum length; the previous unit was re-served instead. | | `TASK_INPUT_REQUIRED` | false | This call needs goal, current_obstacle and next_decision before a unit can be served. | | `CORPUS_EXHAUSTED` | false | Every unit in the block has been served to this key; there is no next unit. | | `UNKNOWN_UNIT` | false | The requested unit_id is not one of the loaded units; the known ids are listed in the response. | | `UNAUTHORIZED` | false | No usable bearer key was presented; mint one at POST /v0/key. | | `BODY_TOO_LARGE` | false | The request body exceeds the cap; the same body is always refused. | | `MALFORMED_JSON` | false | The request body is not valid UTF-8 JSON. | | `INVALID_REQUEST` | false | The body parsed but is not the object shape this endpoint requires. | | `UNKNOWN_FIELD` | false | The body carries fields that are not in the schema; the names are listed, never their values. | | `INVALID_FIELD` | false | A known field failed type or length validation; the response names the field, never its value. | | `UNKNOWN_TOOL` | false | No MCP tool by that name; call tools/list for the current set. | | `UNKNOWN_METHOD` | false | No JSON-RPC method by that name on this endpoint. | | `NOT_FOUND` | false | No such route or asset on this node. | This table is DERIVED from the service at boot and republished at `GET /card.json` (`error_codes`) and `GET /openapi.json` (`components.schemas.ErrorCode`). A published list that can drift from the list the wire returns is a file citing a truth it does not hold, which is the failure class the corpus hashes exist to prevent; the codes are handled the same way. **Where the keys sit per transport.** On plain HTTP they are top-level in the body. On MCP a tool-level failure (`UNAUTHORIZED`) puts them in the tool result payload the model reads; a JSON-RPC *protocol* error puts them in `error.data`, because the envelope's own numeric `code` is the -32xxx transport number and is not ours to overload. **Two deliberate edges.** The deposit gate is the one 200 that carries unit text *and* a code — the cursor did not advance, so it is a gate that happens to re-send, and its `unit_sha256` is the re-served previous unit's. A JSON-RPC notification is answered with `202` and no body, because the protocol forbids a response to one; there is no object to put a code in, and the 202 is the acknowledgement itself. **401.** The unauthenticated POST returns the fixed `UNAUTHORIZED` envelope — `error`, `code`, `retryable`, `unit_sha256: null` and a static hint. No corpus body, and no echo of the key that was presented. ### Core Binding Declarations (Claims A–E) Autonomous clients and operators walking this rail agree to the following structural boundaries: - **No Behavioral Modification Claims (A):** The rail does not claim to alter agent behavior, eliminate loops, or repair thrashing automatically. It is a pacing interface, not a behavioral fix. - **No Calibration Certification (B):** Progressing through the units proves historical walk events (receipts); it does not certify cognitive calibration, focus, or safety alignment. - **No Performance Guarantees (C):** No performance improvement, accuracy gains, or immunity to hallucination/looping is promised or implied. - **No Financial Finality (D):** The Phase-1 rail contains no built-in billing, subscriptions, or instant blockchain settlement mechanism in v0. - **Purely Experiential (E):** The system serves solely as a sequential delivery platform. Every call is logged to measure agent arrival and progression. --- ## 3. Situation Index and Lookup (no auth, no budget) Sequential is not the only access pattern. An agent that has a problem right now should not have to walk six units to find out whether unit 03 was the relevant one. ### `GET /v0/index` - **Auth:** none. **Cost:** none. - **Returns:** the full index — one brief per unit: `unit_id`, `title`, `tier`, `chars`, `agent_applicable`, `operational_objective`, `brief`, `situation_tags`. No lesson bodies, ever. - **Honesty note:** six of the thirteen units carry no agent-operational objective. The index marks them `agent_applicable: false` rather than inventing one. An index that claims all thirteen apply to an agent would be the more marketable file and the less useful one. ### `GET /v0/find?situation=` - **Auth:** none. **Cost:** none. - **Returns:** `{"matches": [...up to four ranked briefs...], "situation_echo_chars": }`. Each match carries the fields above plus `matched_on`, the tokens that scored it. - **Method:** deterministic token overlap against the index tags and briefs. There is no model call inside the lookup — a model call in a lookup is exactly the latency this endpoint exists to avoid, and it would make the ranking unreproducible. - **Privacy:** the `situation` string is handled like a deposit. Not the text, not a digest of it — only a character count and the number of matches are logged. The echoed count is how a caller confirms the query arrived intact without the service ever holding the query. Briefs are free; bodies are not. To read a unit named by a match, call `POST /v0/tablet/next` with `{"unit_id": "NN"}` (or the `unit_id` argument of the `next_lesson` MCP tool), which costs one budget call and leaves the cursor untouched. --- ## 4. Node Integrity The corpus integrity is pinned cryptographically. The server validates that curriculum fragments are loaded directly from the pristine frozen block files: - **Corpus Block SHA256:** `235d264b99d12c518829c04b0d299625def716252ab3ebd6b06e43431354acac` - **Manifest File SHA256:** `28993210d2e4d0ede5a728c56cfbd25d12e8c3c205673b9d04f0906dd2e71400` These hashes bind the exact bytes of the 13 unit files and the manifest list. Any drift in the files results in a startup error, ensuring strict provenance and integrity. --- ## 5. Discovery Listing and Registration (The Surface Map) Because AIgent Sphere does not distribute a client library or NPM package in v0, directory registration and agent discovery rely entirely on the hosted HTTPS endpoints: 1. **awesome-mcp Lists (GitHub directories):** - **Requirements:** A simple pull request appending the site to the Markdown index. - **Listed URL:** `https://aigentsphere.ai` - **Listed Description:** A paced, key-gated sequential lesson rail serving 13 units of curriculum. 2. **Glama MCP Registry (glama.ai/mcp):** - **Requirements:** Supports hosted Server-Sent Events (SSE) or HTTP bridge integrations. - **Listed URL:** `https://aigentsphere.ai` 3. **Smithery (smithery.ai):** - **Requirements:** Smithery indexes CLI/NPM packages and Docker containers. - **Bridge Integration:** none published. No client package, image or bridge is shipped yet. Call the HTTPS endpoint directly; any local MCP bridge is the operator's own. --- ## 6. The Operator's First 60 Seconds (Key Request & Issuance) Keys are **self-issued by the agent**. This is an agent-to-agent service: an operator may point an agent at this URL and take no further action. 1. **Mint:** `POST /v0/key` with no auth and no body. A bearer key is returned immediately and shown once. 2. **Walk:** call `POST /v0/tablet/next` with that key. One unit per call. Or skip the walk: `GET /v0/find?situation=...` costs nothing and names the unit that fits, and `{"unit_id": "NN"}` retrieves it directly without moving the cursor. 3. **Limit:** 3 keys per client per UTC day. Issuance is counted against an ephemeral bucket derived from a daily-rotating secret held only in memory. The client address is never stored, and the bucket is never written to any log. When the UTC day rolls the secret is replaced, which makes the previous day's buckets unrecomputable -- including by us. The free entitlement (units 00-06) requires no human at any step. Units 07-12 remain entitlement-gated; no payment mechanism is published yet and none is implied. `keys@aigentsphere.ai` remains a human contact for questions. It is not required to obtain a key.