# API Specification Schema — Layer 4 Domain Schema # KNO Schema Version: 0.3.0 # CHANGELOG: # 0.3.0 (M52 P4.1, #2139): Add `visibility: public` collection default per REQ-18. # API entities are public reference knowledge consumed via # the four-surface contract. # # Layer 4 schema that extends spec-schema.kno for API definitions. # Defines the structure for documenting REST, GraphQL, and static APIs. # # PURPOSE: Define "What is an API?" as a .kno schema. # Every file describing an API surface conforms to this schema. # # EXTENDS: spec-schema.kno (Layer 3) # ENABLES: API documentation instances (spec-api.kno, kno-api.kno, etc.) # ============================================================================= # SCHEMA DECLARATION # ============================================================================= $schema: kno@0.0.9 id: 01KGK3V73KV22P75DHB5BSJ3J3 slug: api-spec type: spec version: 0.5.0 # ============================================================================= # VISIBILITY DECLARATION (REQ-18) — collection default # ============================================================================= # API entities (content/apis/*.kno) are public reference knowledge by default. # Per REQ-18, individual entities MAY override with their own `visibility:` # field (last-write-wins at the entity level). Drives the four-surface contract # per kno-system_architecture.md § Agent Surface Integration and # public-surface-parity.instructions.md. visibility: public # ============================================================================= # STANDARD TIER # ============================================================================= title: "API Specification Schema" purpose: | Define the structure for API documentation entities. **What is an API spec?** A .kno file that documents an API surface — its endpoints, operations, content negotiation, authentication, and contracts. **Layer 4 Position**: API spec extends spec-schema (Layer 3), which extends document-schema (Layer 2). This means every API spec inherits: - Identity fields (id, version) - Standard tier (title, purpose) - History tracking (_history) - Quality metadata (review_status) **Design Principle**: Simpler than OpenAPI, focused on Possibility patterns. Can transform TO OpenAPI for tooling compatibility. # ============================================================================= # RICH TIER — Taxonomy # ============================================================================= provenance: origin: id: 01KGK3V73KV22P75DHB5BSJ3J3 timestamp: "2026-02-04T01:47:56Z" tool: manual-migration taxonomy: topics: - api - rest - endpoints - documentation - contracts keywords: - api - endpoint - route - operation - request - response - rest - http - content-negotiation # ============================================================================= # RICH TIER — Relationships # ============================================================================= relationships: extends: - xri: "kno://specs/spec-schema" reason: "API spec is a specialized specification document" depends_on: - xri: "kno://specs/kno-spec" reason: "Conforms to KNO format specification" enables: - xri: "kno://apis/spec-api" reason: "Schema Registry API documentation" - xri: "kno://apis/kno-api" reason: "KNO Validation API documentation" - xri: "kno://apis/auth-api" reason: "Authentication API documentation" - xri: "kno://apis/email-api" reason: "Email API documentation" - xri: "kno://apis/connections-api" reason: "Connections API documentation" related_to: - xri: "kno://specs/document-schema" reason: "Shares document-level structure" # ============================================================================= # QUALITY # ============================================================================= quality: completeness: 0.85 last_reviewed: "2026-03-26" review_status: draft reviewed_by: "claude" # ============================================================================= # HISTORY # ============================================================================= _history: retention: full format: snapshot versions: - version: "0.4.0" date: "2026-04-26" author: "claude" summary: "Add narrows_to/widens_from predicates and operation-level error_responses block for the discriminated remediation envelope (#1956 / M52 P3.B.1)" changes: - "Added bidirectional relationship predicates `narrows_to` (forward, on auth-gated endpoint) and `widens_from` (inverse, on less-restricted endpoint). Used by the remediation middleware to suggest a less-scoped alternative when a 4xx denies access. Backlink consistency is enforced by scripts/lint-api-contract-honesty.ts (P7)." - "Added optional `error_responses` block to operation responses, carrying a `remediation` envelope (Tier 2 hand-tuned per error code). Discriminator type ∈ {wait_for_provisioning, request_scope_elevation, switch_user, register_custom_domain, none}. The `none` type is the honest closure for endpoints with no public alternative — REQUIRES a `reason` ∈ {no_public_equivalent_exists, auth_required_for_safety, not_yet_implemented} (PRO-04 / PRO-05 / P11)." - "Added optional operation-level `remediation_default: none` (with required `reason`) for endpoints that explicitly declare 'no public alternative exists'. Lint requires every auth-gated endpoint to declare ONE of: narrows_to relationship, error_responses with remediation, or remediation_default=none with reason." - "Three-Gate Test outcome (kno-foundational-principles.md § 0.6): Distinctness=FAIL — remediation is a property of API responses, not a separate entity. Reusability=N/A. Clarity=extending api-spec keeps remediation co-located with the endpoint that emits it. Decision: extend api-spec rather than create remediation-schema." - "MINOR bump: all additions are optional fields. Existing api-spec instances remain valid." - version: "0.3.0" date: "2026-04-20" author: "claude" summary: "Add optional managed_service field for capability-shaped taxonomy (#1545)" changes: - "Added optional top-level managed_service field — string aligned with the 8-category capability-shaped taxonomy (user-store, kv-secrets, blob-storage, entity-store, entity-vcs, identity, tenant-database, activity-log)" - "Three-Gate Test outcome (kno-foundational-principles.md § 0.6): Distinctness=FAIL — managed services are described by API .kno files; only a category tag was missing. Reusability=N/A. Clarity=extending api-spec keeps related data together. Decision: extend api-spec rather than create managed-service-schema." - "Generative manifest (#1543/#1544) consumes this field to expose managed_services[] grouping without hardcoded lists" - "Provider Opacity: categories are capability-shaped (what the platform offers tenants), not backend-shaped (Keycloak, MinIO, OpenBao, TerminusDB, Postgres MUST NOT appear in manifest output)" - version: "0.2.0" date: "2026-03-26" author: "claude" summary: "Add MCP tool generation control and parameter types" changes: - "Added mcp field to operations (expose, tool_name, category) for MCP tool generation" - "Added type field to parameters for Zod schema generation" - "Enables complementary field consumption: kno-router reads operational fields, MCP reads documentation fields" - "Implements F0 (#848) Wave 0 schema extension" - version: "0.1.0" date: "2026-01-11" author: "claude" summary: "Initial API specification schema" changes: - "Created Layer 4 schema extending spec-schema" - "Defined fields: base_url, api_type, endpoints, content_negotiation" - "Added authentication and servers configuration" - "Follows kernel v0.0.6 (no facets, structure expressed)" # ============================================================================= # SPECIFICATION CONTENT # ============================================================================= spec: status: Draft description: | ## What is an API Spec? An API spec is a .kno file that documents an API surface — the endpoints, operations, authentication, and content negotiation rules for a service. In Possibility's architecture, APIs include: - **Schema Registry API**: Serving schemas in multiple formats (JSON, XML, YAML) - **KNO Validation API**: Validating .kno files against schemas - **Admin APIs**: Entity management, corpus import, playbook generation - **Federation APIs**: Cross-organization data exchange ## Relationship to OpenAPI api-spec.kno is simpler than OpenAPI, focused on Possibility-specific patterns: - Endpoints grouped logically (not flattened) - Content negotiation as first-class concept - Trust and federation fields for distributed systems API specs CAN be transformed to OpenAPI for external tooling compatibility. # =========================================================================== # SCHEMA FIELDS # =========================================================================== fields: # ------------------------------------------------------------------------- # Required Fields (in addition to inherited id, type, version, title) # ------------------------------------------------------------------------- api_type: type: string required: true description: | The architectural style of the API. Common values: rest, graphql, static, rpc, federation Type is a string — new values can emerge without schema modification. Classification should be inferred from usage patterns. examples: - rest - graphql - static - rpc - federation base_url: type: string required: true description: "Primary base URL for the API" examples: - "https://specs.possibility.space" - "https://api.possibility.space" # ------------------------------------------------------------------------- # Endpoints # ------------------------------------------------------------------------- endpoints: type: array required: true description: "API endpoints grouped by resource or function" items: type: object properties: path: type: string required: true description: "URL path (supports parameters like {id})" summary: type: string description: "Brief description of the endpoint" description: type: string description: "Detailed explanation of the endpoint" operations: type: array description: "HTTP operations supported on this endpoint" items: type: object properties: method: type: string description: "HTTP method (GET, POST, PUT, PATCH, DELETE, etc.)" summary: type: string description: type: string parameters: type: array description: "Request parameters" items: type: object properties: name: type: string in: type: string description: "Location: path, query, header, body" required: type: boolean type: type: string description: "Parameter data type for schema generation: string, number, integer, boolean, array, object" description: type: string mcp: type: object description: | MCP tool generation control for this operation. When mcp.expose is true, the MCP dynamic tool generator will create a tool definition from this operation's documentation fields (summary, description, parameters). This is the complementary consumer to kno-router — same .kno source, different field sets, zero duplication. properties: expose: type: boolean description: "Whether to generate an MCP tool for this operation. Opt-in — defaults to false if omitted." tool_name: type: string description: "Override the auto-generated tool name. Default naming: {api-slug}_{method}_{path-segments}" category: type: string description: "Tool categorization for agent discovery. Examples: schema-discovery, entity-management, analysis" responses: type: object description: "Response definitions keyed by status code" content_types: type: array items: type: string description: "Supported response content types" error_responses: type: object description: | Tier 2 hand-tuned remediation envelopes per error code (#1956). Maps an HTTP status code (string) → an `error_response` object whose `remediation` field carries the discriminated remediation envelope emitted on 4xx. Keys are status codes as strings ("400", "403", "409"). Each value MAY declare an `error_codes` list to bind the remediation to specific machine-readable `error` values inside the response body (e.g. `custom_auth_domain_required`). See content/knowledge-base/remediation-block-pattern.kno for the full taxonomy and rationale. additionalProperties: type: object properties: error_codes: type: array items: type: string description: | Optional list of machine-readable `error` codes inside the response body that this remediation applies to. Omit to apply to all bodies emitted with this status code. remediation: type: object description: | Discriminated remediation envelope. Type ∈ {wait_for_provisioning, request_scope_elevation, switch_user, register_custom_domain, none}. When type=none, `reason` is REQUIRED and MUST be one of {no_public_equivalent_exists, auth_required_for_safety, not_yet_implemented}. properties: type: type: string enum: - wait_for_provisioning - request_scope_elevation - switch_user - register_custom_domain - none message: type: string description: "Human-readable, partner-facing explanation of the remediation step." reason: type: string enum: - no_public_equivalent_exists - auth_required_for_safety - not_yet_implemented description: "REQUIRED when type=none. Why this endpoint has no public alternative." next_action: type: object description: | Optional structured pointer to the next step (endpoint XRI/URL, required scope, related guide). Consumed by partner agents to chain recovery without human intervention. properties: endpoint_xri: type: string endpoint_url: type: string required_scope: type: string guide_xri: type: string remediation_default: type: string enum: - none description: | Operation-level honest closure declaring 'no public alternative exists' when no `narrows_to` relationship and no `error_responses[*].remediation` is appropriate for this endpoint. REQUIRES sibling `remediation_reason`. remediation_reason: type: string enum: - no_public_equivalent_exists - auth_required_for_safety - not_yet_implemented description: "REQUIRED when remediation_default=none. The reason this endpoint has no public alternative." narrows_to: type: array description: | Tier 1 structural default (#1956). List of endpoint XRIs that are public/less-scoped equivalents of this auth-gated endpoint. The remediation middleware uses the first entry to build a default `request_scope_elevation` envelope on 403 responses. Each target SHOULD declare a reciprocal `widens_from` entry (lint enforces this — P7). items: type: object properties: xri: type: string description: "pspace://api-endpoint/ XRI of the less-scoped equivalent." reason: type: string widens_from: type: array description: | Inverse of narrows_to (#1956). Declared on the public/less- scoped endpoint, pointing back to its auth-gated counterpart(s). Lint enforces bidirectional consistency. items: type: object properties: xri: type: string reason: type: string # ------------------------------------------------------------------------- # Content Negotiation # ------------------------------------------------------------------------- content_negotiation: type: object description: "Content negotiation configuration" properties: default_format: type: string description: "Default response format when Accept header not specified" supported_formats: type: array description: "All supported response formats" items: type: object properties: content_type: type: string description: "MIME type" extension: type: string description: "File extension alternative (e.g., .json)" description: type: string accept_mapping: type: object description: "Maps Accept header values to format identifiers" # ------------------------------------------------------------------------- # Servers / Environments # ------------------------------------------------------------------------- servers: type: array description: "Available server environments" items: type: object properties: url: type: string required: true description: type: string environment: type: string description: "Environment type: production, staging, development, local" # ------------------------------------------------------------------------- # Authentication # ------------------------------------------------------------------------- authentication: type: object description: "Authentication requirements" properties: required: type: boolean description: "Whether authentication is required" schemes: type: array items: type: string description: "Supported auth schemes: none, bearer, api_key, oauth2" description: type: string # ------------------------------------------------------------------------- # Security # ------------------------------------------------------------------------- security: type: object description: "Security configuration" properties: cors: type: object properties: allowed_origins: type: array items: type: string allowed_methods: type: array items: type: string allowed_headers: type: array items: type: string # ------------------------------------------------------------------------- # Federation / Trust (Possibility-specific) # ------------------------------------------------------------------------- trust: type: object description: "Trust configuration for federated APIs" properties: type: type: string description: "Trust level: canonical, delegated, community" verification: type: object properties: integrity_hashes: type: boolean description: "Whether responses include integrity hashes" signatures: type: boolean description: "Whether responses are signed" # ------------------------------------------------------------------------- # Managed Service Taxonomy (Possibility-specific) — Added v0.3.0 (#1545) # ------------------------------------------------------------------------- managed_service: type: string required: false description: | Optional capability-shaped taxonomy tag declaring which managed service this API surfaces to tenants. Used by the generative integration manifest to expose `managed_services[]` without a hardcoded list. **Capability-shaped, not backend-shaped.** Categories describe what the platform offers tenants — backend implementation names (Keycloak, MinIO, OpenBao, TerminusDB, Postgres) MUST NOT leak through this field. See `content/knowledge-base/provider-opacity.kno` for the principle and `content/knowledge-base/managed-services-taxonomy.kno` for the canonical category reference. **8-category taxonomy:** - `user-store` — user identity + profile storage - `kv-secrets` — per-possibility KV secrets - `blob-storage` — per-possibility object storage - `entity-store` — `.kno` entity storage - `entity-vcs` — version history for entities - `identity` — OIDC/OAuth identity provider (auth zone) - `tenant-database` — per-possibility relational database - `activity-log` — audit/activity stream Omit this field for APIs that are platform tooling, capability lifecycle, or admin surfaces (i.e. not a tenant-facing managed service). enum: - user-store - kv-secrets - blob-storage - entity-store - entity-vcs - identity - tenant-database - activity-log examples: - identity - blob-storage - entity-store # ============================================================================= # EXAMPLES # ============================================================================= examples: - id: minimal-api description: "Minimal API spec (required fields only)" content: | $schema: api-spec@0.2.0 id: my-api type: api version: 1.0.0 title: "My API" api_type: rest base_url: "https://api.example.com" endpoints: - path: /health summary: "Health check" operations: - method: GET summary: "Returns API health status" - id: mcp-enabled-api description: "API with MCP tool generation enabled" content: | $schema: api-spec@0.2.0 id: my-api type: api version: 1.0.0 title: "My API" api_type: rest base_url: "https://api.example.com" endpoints: - path: /items summary: "Item management" operations: - method: GET summary: "List all items" description: "Returns a paginated list of items the caller has access to" parameters: - name: status in: query required: false type: string description: "Filter by status: active, archived" - name: limit in: query required: false type: integer description: "Maximum items to return (default 20, max 100)" mcp: expose: true category: entity-management - method: POST summary: "Create a new item" parameters: - name: name in: body required: true type: string description: "Display name for the item" mcp: expose: true tool_name: "create_item" category: entity-management - id: spec-registry-api description: "Spec Registry API (modernized)" content: | $schema: api-spec@0.1.0 id: spec-api type: api version: 0.2.0 title: "Possibility Spec Registry API" api_type: rest base_url: "https://specs.possibility.space" endpoints: - path: /api.kno summary: "API self-description (KAML)" operations: - method: GET summary: "Agentic discovery endpoint" - path: /index.kno summary: "Spec manifest (KAML with _index)" operations: - method: GET summary: "Get manifest with O(1) lookup index" - path: /index.json summary: "Spec manifest (JSON)" operations: - method: GET summary: "Get all specs as JSON" - path: /{spec}.kno summary: "Individual spec file" operations: - method: GET summary: "Get spec by ID" parameters: - name: spec in: path required: true content_negotiation: default_format: text/yaml supported_formats: - content_type: text/yaml extension: .kno - content_type: application/json extension: .json authentication: required: false security: cors: allowed_origins: ["*"] allowed_methods: ["GET", "HEAD", "OPTIONS"] # ============================================================================= # CONTAINER TIER — Navigation Index # ============================================================================= _index: - path: "identity" line: 18 keywords: [ id, type, version, api ] - path: "spec/endpoints" line: 80 keywords: [ GET, HEAD, OPTIONS, health, index, api ] - path: "spec/responses" line: 180 keywords: [ 200, 304, 404, 406, ETag, Last-Modified ] - path: "spec/content_negotiation" line: 350 keywords: [ json, yaml, xml, Accept, content-type ] contains: - xri: "#identity" role: section title: "API Metadata" keywords: [ id, type, version ] - xri: "#spec" role: section title: "API Specification" keywords: [ endpoints, responses, content-negotiation ]