Codex 0 · Chapter 10 — API Boundaries
Chapter 10 of the institutional specification.
- Authority rank
- 2
- Version
- v2.0
- Adopted
- unrecorded
- Held by
- Stewardship Office
- System
- SYS-12
Source · docs/codices/CODEX-0/10-api-boundaries.md · registered by rule
This chapter specifies what an API boundary is, the rules that govern its stability and change, and the binding rule for each of API-01 through API-11.
10.0 Purpose
A boundary is the only lawful way one system, division, or external party reaches another's data. This chapter turns Codex 5's boundary list and Codex 0 §11 into an enforceable specification: stability classes, versioning, deprecation, validation, error semantics, idempotency, pagination, rate limiting, authentication, and the caller rule that binds internal tooling to the same discipline as the public internet.
10.1 Scope and non-scope
In scope: the boundary concept, its lifecycle, and the specific rule that binds each of API-01 through API-11. Out of scope: the entities crossing the boundary (Codex 5), the engines behind the boundary (Codex 3), the surfaces that call the boundary (Chapter 11), and the workflows that traverse several boundaries in sequence (Chapter 09).
10.2 What a boundary is
10.2.1 A boundary is a declared, versioned contract for reading or writing a bounded set of canonical entities, owned by exactly one division, consumed by any authorised caller.
10.2.2 A boundary is not a controller, a route handler, or a database table. It is the contract those things implement. Multiple internal implementations may sit behind one boundary; the contract, not the implementation, is what integrators depend on.
10.2.3 A boundary is stabilised before anything integrates against it (Codex 0 §11). "Stabilised" has the specific meaning given in 10.3.
10.3 Stability classes
| Class | Meaning | Who may integrate | Change rule |
|---|---|---|---|
experimental | Contract may change without notice | internal callers only, explicitly opted in | any change permitted, must be logged in the boundary's changelog |
stable | Contract is fit for external integration; breaking changes require the procedure in 10.4 | internal and external callers | breaking change requires a new version, a migration window, a decision record |
permanent | Contract may only be extended, never broken, for the life of the institution | anyone, including third parties with no ongoing relationship to Anabasis | no breaking change, ever; only additive fields |
10.3.1 A boundary enters experimental the day its first caller (internal) is written against it. It may remain experimental indefinitely; there is no clock forcing promotion.
10.3.2 A boundary is promoted to stable only by a decision record naming the promotion, the boundary's owner, and the first external or cross-division consumer that requires it.
10.3.3 A boundary is promoted to permanent only where the institution has made a public, generational promise about it — currently: Credential & Verification (API-05) is the sole entry required to reach permanent, because a credential's public verifiability is a promise made to a person, not to a caller.
10.4 Versioning and deprecation
10.4.1 Every boundary is versioned. A version identifier appears in every request and response; callers are never left to guess which contract they are speaking.
10.4.2 A breaking change (removed field, renamed field, changed meaning, changed status code semantics) requires: a new version, published alongside the old one; a decision record naming what breaks and why; and a migration window.
10.4.3 The migration window is no shorter than ninety days for stable boundaries and is not permitted at all for permanent boundaries — see 10.4.5.
10.4.4 During a migration window both versions serve traffic. The old version is marked deprecated in its own contract (not just in documentation) so that automated callers can detect it.
10.4.5 A permanent boundary does not have a migration window because it does not have breaking changes. Extension (new optional fields, new optional endpoints) is always available; removal or redefinition of an existing field is prohibited outright, not merely windowed.
10.4.6 A boundary may not be retired while any caller — internal or external — is recorded as still depending on it, per the registry's "future dependents" field.
10.5 Validation at the edge
10.5.1 No unvalidated input reaches a handler (Codex 5, restated). Validation happens at the boundary, not inside the engine it fronts.
10.5.2 Validation failure returns a structured error (10.7) naming the specific field and constraint violated. It never fails silently and never partially applies a write.
10.5.3 A boundary validates both shape (type, required fields) and business constraint (role scope, entity state, e.g. "Enrolment must be active to accept a submission"). Shape validation without state validation is incomplete.
10.6 Idempotency
10.6.1 Every write operation that could plausibly be retried by a caller (network failure, timeout) accepts an idempotency key. A repeated call with the same key produces the same result without a duplicate side effect.
10.6.2 Idempotency keys are required, not optional, for any operation that creates a canonical entity carrying institutional consequence: Enrolment, Credential, Investment, AuditRecord.
10.6.3 Idempotency is enforced at the boundary, not left to the caller's discipline; a boundary without idempotency enforcement on its consequential writes is not stable.
10.7 Error semantics
10.7.1 Every error response states: a machine-readable code, a human-readable message safe to display, and — where applicable — the specific field or constraint. Errors do not leak internal implementation detail (stack traces, table names, query text).
10.7.2 Errors are classified consistently across all boundaries: validation (caller's input is malformed or violates a stated constraint), authorization (caller lacks the grant), state (the target entity is not in a state that permits the action), not_found, rate_limited, unavailable (transient), and internal (a defect, always logged and never described to the caller as their fault).
10.7.3 A caller can distinguish "retry is safe" from "retry will not help" from every error response. unavailable and rate_limited are retryable; validation, authorization, state, and not_found are not.
10.8 Pagination
10.8.1 Every list-returning endpoint is paginated by default; there is no unbounded "return everything" mode reachable without explicit, logged, elevated access.
10.8.2 Pagination is cursor-based for any collection that can grow without bound or that changes while being paged (Event, AuditRecord, Publication); offset-based pagination is permitted only for small, bounded, largely static collections (a Curriculum's list of schools).
10.8.3 A page's size is bounded by a documented maximum the caller cannot exceed by request.
10.9 Rate limiting
10.9.1 Every boundary enforces a rate limit scoped to the authenticated caller (Identity, ENT-02), not to IP address alone, so that a shared network does not collectively throttle unrelated members.
10.9.2 Rate limit state is communicated to the caller in every response (remaining quota, reset time), not discovered only by hitting the limit.
10.9.3 permanent boundaries (currently API-05) apply a materially higher default limit to anonymous verification lookups than any other public endpoint, because verification is the boundary's entire public purpose and must not be throttled into practical unavailability.
10.10 Authentication classes
| Class | Who | Applies to |
|---|---|---|
public | no credential required | credential verification (API-05 read path), public content boundaries |
member | authenticated Person via API-01 | any boundary reading or writing that Person's own data |
role-scoped | authenticated Person holding a specific Role (ENT-05) | boundaries gated by function — Faculty grading, Advisor engagement access |
service | machine-to-machine credential issued to a named internal system or approved partner | internal tooling, partner integrations under signed agreement |
10.10.1 A service credential is issued to a named system, never shared across systems, and is revocable independently of any human's access.
10.10.2 No boundary grants a caller more than its authenticated class permits by checking a client-supplied flag; authorization is always resolved server-side from stored Role and Membership records (Codex 1, Article VI.5).
10.11 The internal-versus-external caller rule
10.11.1 Internal tooling calls the same boundaries external surfaces call. There is no privileged private path around a boundary for internal use (Codex 0 §12, restated, and binding here as an API rule, not only a tooling rule).
10.11.2 The distinction between an internal and an external caller is the authentication class and rate limit applied to it (10.9, 10.10), never a separate contract, a separate validation path, or direct database access.
10.11.3 Where an internal tool needs a capability no boundary yet exposes, the correct action is to extend the boundary — even if experimental — not to write a bypass. A bypass discovered in review is treated as a defect, not an optimization.
10.12 API-01 through API-11
10.12.1 API-01 — Identity & Access
Owner: DIV-05. Responsibility: authentication, session, and the resolution of Role and Membership into an authorization decision. Consumers: every authenticated surface and boundary. Entities crossed: Identity (ENT-02), Role (ENT-05), Membership (ENT-04). Stability: partial implementation, target class stable. Binding rule: authorization is resolved here and only here; no other boundary re-implements role checking locally (Codex 1, Article VI.5).
10.12.2 API-02 — Person & Membership
Owner: DIV-05. Responsibility: the single canonical Person record and their memberships across the institution and partner organizations. Consumers: everything. Entities crossed: Person (ENT-01), Organization (ENT-03), Membership (ENT-04). Stability: partial, target stable. Binding rule: a Person is never duplicated to represent a new role or organization relationship (Codex 0 §4.1); this boundary is the single point where that rule is enforced in code.
10.12.3 API-03 — Curriculum
Owner: DIV-01. Responsibility: the school → program → course → module → lesson hierarchy and its versions. Consumers: ENG-03, enterprise cohort delivery (WF-05), partner integrations. Entities crossed: Curriculum (ENT-09). Stability: partial. Binding rule: a curriculum revision is additive-versioned (Codex 5, normalization rule 3); a Scholar mid-unit is never silently moved to a new version (Chapter 09, §9.5, stage 9).
10.12.4 API-04 — Progress & Assessment
Owner: DIV-01. Responsibility: enrolment progress, submissions, and assessment records. Consumers: dashboards (DASH-02, DASH-03), credentialing (API-05). Entities crossed: Enrolment (ENT-10), Artifact (ENT-17), CapabilityAssessment (ENT-07). Stability: partial. Binding rule: no write to this boundary may mark an assessment complete without the review stage defined in Chapter 09 §9.3, stage 7-8 having occurred.
10.12.5 API-05 — Credential & Verification
Owner: DIV-01. Responsibility: issuance, revocation, and public verification of credentials. Consumers: public verification callers, employers, partners, every downstream system that trusts a credential. Entities crossed: Credential (ENT-08). Stability: target permanent (currently reserved, per registry). Binding rule: credential verification must still resolve in twenty years — this boundary's read path for verification is the one entry point in the entire institution exempt from the normal stable migration-window procedure, because it may never break at all (10.4.5). A revoked credential remains resolvable and states its revocation (Chapter 09 §9.2.6.3).
10.12.6 API-06 — Engagement
Owner: DIV-02. Responsibility: advisory engagement lifecycle, staffing, delivery, and outcomes. Consumers: advisor tooling, enterprise dashboard (DASH-04, DASH-07). Entities crossed: Engagement (ENT-12). Stability: reserved. Binding rule: an Engagement's outcome record may be amended only with both parties' consent and is versioned, never edited unilaterally in place (Chapter 09 §9.4, stage 5).
10.12.7 API-07 — Publication & Index
Owner: DIV-03. Responsibility: publications and versioned index series. Consumers: public site, annual report, curriculum revision pipeline. Entities crossed: Publication (ENT-13), Index (ENT-14). Stability: reserved, code-data today. Binding rule: a published item is retracted, never deleted; an index value is superseded by a new dated value, never revised in place (Chapter 09 §9.9, stage 3).
10.12.8 API-08 — Venture & Capital
Owner: DIV-04. Responsibility: venture pipeline stage, milestones, and investment records. Consumers: founder and investor portals (reserved surfaces). Entities crossed: Venture (ENT-15), Investment (ENT-16). Stability: reserved. Binding rule: an executed Investment is amended only by a new dated instrument, never edited in place (Chapter 09 §9.6, stage 7).
10.12.9 API-09 — Knowledge Graph
Owner: DIV-05. Responsibility: capability, curriculum, publication, and person-capability graph edges. Consumers: ENG-03, ENG-09, AGT-02. Entities crossed: graph edges over ENT-06/09/13. Stability: reserved. Binding rule: an edge is corrected by a versioned change, not a silent overwrite, so that "what the graph believed on date X" remains reconstructable — this is the property that makes the Adaptive engine's recommendations explainable after the fact (Codex 3, Article on explainability, restated).
10.12.10 API-10 — Reporting & Analytics
Owner: DIV-05. Responsibility: aggregate reporting for executive, steward, and enterprise consumers. Consumers: DASH-07, DASH-08, DASH-09, annual report (WF-07). Entities crossed: aggregates over all entities, within agreed scope. Stability: reserved. Binding rule: this boundary never returns individual-level data beyond the scope an Organization agreed to (Chapter 09 §9.7, stage 6); scope is enforced at the boundary, not trusted to the caller's discretion.
10.12.11 API-11 — Audit
Owner: DIV-05. Responsibility: the immutable record of consequential actions. Consumers: governance, security review, TOOL-11, DASH-08, DASH-10. Entities crossed: AuditRecord (ENT-19). Stability: reserved. Binding rule: this boundary is append-only at the data layer — no caller, regardless of role, may issue an update or delete against an AuditRecord through any path (Codex 1, Article VI.6).
10.13 Interfaces
10.13.1 Every boundary's contract is published in a machine-readable schema (OpenAPI, GraphQL SDL, or equivalent) checked into the codebase alongside its implementation, not maintained separately in prose.
10.13.2 A boundary's registry entry (API- ID) names its current stability class; the class is not asserted informally in a decision record without updating the registry.
10.14 Invariants
- 1No boundary serves a write without validating both shape and state at the edge.
- 2No consequential write is possible without an idempotency key.
- 3No
permanentboundary is ever given a breaking change. - 4No caller — internal or external — reaches a canonical entity except through a declared boundary.
- 5Authorization is resolved once, at API-01, and never re-implemented locally by another boundary.
- 6Every error response is classified and safe to display.
10.15 Prohibitions
- 1No boundary may be marked
stablewhile any of its consequential writes lack idempotency enforcement. - 2No internal tool may be given a database connection that bypasses a boundary in place of extending that boundary.
- 3No boundary may silently drop a field on breaking change without a version, migration window, and decision record.
- 4No boundary may return unbounded result sets to any caller without explicit, logged, elevated access.
- 5No boundary may leak internal implementation detail in an error response.
10.16 Open questions
- 1The specific ninety-day migration-window minimum (10.4.3) has not yet been tested against a real breaking change; the number is a starting position pending a decision record from the first case.
- 2Whether partner institutions (Codex 0 §15.2) require a distinct authentication class beyond
serviceis undecided. - 3The machine-readable schema format has not been chosen; Chapter 07 (Engineering Doctrine reference) or a future decision record should settle it before API-01 is promoted to
stable.
10.17 Governing Codices
Codex 1 (Article VI.5–VI.6, server-side enforcement and auditability); Codex 0 §11 (boundary narrative); Codex 5 (canonical entities, contract rules, boundary list); Codex 0 Registry §3 (API- entries); Chapter 09 (workflows that traverse these boundaries); Chapter 11 (surfaces that call them); Codex 7 (engineering standards for implementation); Codex 9 (decision records required for breaking change and stability promotion).