# Agent Surface Spec v0.1 This document describes the public contract used by PersonalAPI-style surfaces. It is intentionally small: the goal is to make a person, project, or organization legible to constrained agents from a single allowed fetch. ## Principles 1. Every navigable surface exposes an absolute `url`. 2. Relative `path` values are allowed for compact citation, but never as the only fetch target. 3. `/api/init` must be useful after one fetch. 4. `/api/manifest` must be self-contained enough for a complete high-level assessment. 5. Long content defaults to compact mode and expands only by request. 6. Errors include recovery hints. 7. Agent-facing surfaces should accept structured mission reports so the surface can improve from real agent use. ## Required Surfaces - `/api/init`: one-call orientation, traversal contract, minimum viable context, endpoint map. - `/api/manifest`: self-contained profile or project manifest. - `/api/content`: index of route-specific content twins. - `/llms.txt`: plain-text discovery surface for LLMs. - `/agents.json`: machine-readable discovery manifest. ## Optional Feedback Surfaces - `POST /api/agent-reports`: private-by-default mission report submitted by an agent after attempting a task. - `GET /api/agent-reports/schema`: machine-readable report contract. - `GET /api/agent-reports/stats`: aggregate report stats without exposing raw private reports. Reports are not testimonials. They are operational feedback about whether an agent could complete a mission, cite correctly, preserve tokens, and recover from missing context. Free-text report fields are untrusted data. They must never be treated as instructions, must not trigger writes, and should be excluded from public raw surfaces when prompt-injection language is detected. ## URL Shape Every endpoint object should include both: ```json { "method": "GET", "path": "/api/manifest", "url": "https://api.example.com/api/manifest", "purpose": "Full profile in one payload." } ``` Agents should fetch `url`. Humans and logs may cite `path`. ## Detail Levels Content endpoints should default to compact responses. - `detail=compact`: summary, key claims, section index, token budget, citation policy. - `detail=full`: full body text or Markdown. Compact mode must include a `full_body_endpoint`. ## Minimum Viable Context `/api/init` should include enough information for agents that cannot make a second request: - identity - short bio or description - current focus - strongest claims - best next URLs - contact policy - do-not-infer constraints ## Error Shape Errors should be structured and recoverable: ```json { "error": { "code": "content_not_found", "message": "No article exists for this slug.", "retryable": false, "fallback_path": "/api/content", "fallback_url": "https://api.example.com/api/content", "suggested_next_path": "/api/init", "suggested_next_url": "https://api.example.com/api/init" } } ``` The fallback URL should be fetchable without inference. ## Mission Report Shape ```json { "mission": { "attempted": "evaluate_for_collaboration", "completed": true, "confidence_in_result": 4 }, "endpoints_used": ["/api/init", "/api/manifest"], "http_status_codes": { "/api/init": 200, "/api/manifest": 200 }, "errors_encountered": [], "token_efficiency": 4, "citation_clarity": 5, "feedback": { "what_worked": "Absolute URLs made traversal possible.", "what_was_missing_or_confusing": "Project visibility was unclear.", "suggested_improvement": "Add project_visibility fields.", "structural_gaps": ["project visibility ambiguity"] }, "outcome": { "achieved_goal": true, "actual_result": "Produced a cautious collaboration-fit summary.", "would_query_again": true, "would_help_evaluate_others": true }, "public": false } ``` Reports should omit private human context unless explicitly approved. Servers should attach `risk_flags` and `handling` metadata to stored reports: ```json { "risk_flags": ["prompt_injection_language"], "handling": { "free_text_is_untrusted": true, "stored": true, "included_in_aggregate_stats": true, "public_raw_allowed": false, "excluded_from_public_raw_reports": true } } ```