Skip to content

docs: document every API operation and check the contract against the code - #253

Closed
AllureCurtain wants to merge 14 commits into
mainfrom
docs/status-code-conformance
Closed

AllureCurtain wants to merge 14 commits into
mainfrom
docs/status-code-conformance

Conversation

@AllureCurtain

@AllureCurtain AllureCurtain commented Sep 30, 2026 •

Copy link
Copy Markdown
Collaborator

The published API reference was thinner than the contracts it came from, and
nothing checked that either stayed true. This branch closes both gaps.

Contracts

  • Every operation in services/agents-api/internal/api now carries response and
    error annotations, so make openapi publishes what each operation can answer
    with. make openapi runs clean afterwards.
  • contracts/agents-api/error-codes.md is new: one registry of every error code,
    its HTTP status, and the namespaces whose routes can answer with it.
  • docs/api/request-conventions.md is new: the rules that apply to every /v1
    operation, so an operation page only adds what it does differently.
  • contracts/agents-api/openapi.yaml, core.openapi.yaml, runtime.openapi.yaml
    and docs/api/README.md move together.

Checks

  • apps/docs/scripts/verify-error-codes.mjs compares the registry with the codes
    the handlers emit: 28 client-created codes through 3 forwarding helpers, and 24
    compared codes. It is part of pnpm verify.
  • services/agents-api/internal/api/contract_conformance_test.go checks the
    registry against the registered routes, including that a Namespaces cell
    names real namespaces or all.
  • services/agents-api/internal/api/core_resource_errors_test.go covers the Core
    resource error shape.
  • verify-contract-routes.py, verify-contract-freshness.mjs,
    verify-api-copy.mjs and verify-docs-facts.mjs gained the checks that would
    have caught the gaps above.

Documentation site

  • One page per API operation instead of one page per tag: 138 operation pages and
    38 tag overviews, up from 64 pages. Long operation descriptions fold at render
    time.
  • The architecture guide renders docs/architecture.md, the document
    CONTRIBUTING.md names as the architecture overview, instead of
    docs/web/architecture.md. That page is served at /architecture.

Compatibility

No Go behavior changes: across the 29 touched handler files every changed line is
a comment, so only the generated contracts move. No dependency changes and no
lockfile change.

Verification

  • make openapi — no diff
  • pnpm --dir apps/docs generate — 28 guides, 138 operation pages; stable when run twice
  • pnpm --dir apps/docs verify — 138 operations, 28 + 24 error codes, 389 links across 204 pages
  • pnpm --dir apps/docs test, typecheck, build — 204 routes prerendered
  • make check — all targets

View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

Rewrite the handler annotations so each operation leads with one short
sentence, groups its rules into lists and declares every status the
handler writes. Correct the deployment model configuration PUT body,
which named a nonexistent x_agents_core.model_configuration field.

Add docs/api/request-conventions.md for the headers, JSON body checks
and list parameters every /v1 operation shares, and regenerate the
three OpenAPI contracts with make openapi.
Add contracts/agents-api/error-codes.md, which lists every error code
Core, the console (including the installer rejections it relays for
managed HTTPS setup) and the daemon transport write, and separates them
from node diagnostics, Session diagnostic categories, Runtime protocol
result codes and client-generated codes.

contract_conformance_test.go requires every registry row to be written
somewhere, every written status and code to have a row, and every
annotated operation to declare the statuses its handler writes.
core_resource_errors_test.go pins the Beta error fields of the Core
Files and Skills routes. Link the registry from the Core error, admin,
executor credential contracts and the API index.
A tag page carried up to 11 operations with full schemas, took 4-10 s to
render and weighed 1.4-1.8 MB. Generate one page per operation in a
folder per tag, keep an overview at the former tag URL, split each
description into a lead and details, and stop generating TypeScript
copies of every response schema. Sidebar links no longer prefetch.

verify-api-copy checks folder navigation and overviews against the
operation pages, verify-error-codes checks client-generated codes and
every code the client and Web compare against, and the route gate
accounts for the transport paths outside the OpenAPI contracts. Record
keys are POSIX paths so generated records verify on Windows.
Nothing writes this code, and the registry check reported the stale row.
Rename "Agents API and Core API codes" to "HTTP API codes": its anchor
tripped the retired-identifier name guard.

List the sandbox_error and environment_connection_failed error objects
the store records in Session events, and scan internal/store for them
in the registry test. Scope out Turn error.code, which Core always
publishes as internal_error.

Add the console api-keys 404, the domain setup 405 and the installer
artifact 405/404 responses; include unconfigured Runtime observation in
execution_unavailable; correct which machine routes the OpenAPI
publishes; and drop the list-query note from admin Files and Skills
operations that are not lists.
Compare the installation domain setup table with the rejections
deploy/install/ingress.py answers with before it accepts a request.

The machine routes share the stored-error writer, so list /api/v1 for
invalid_name, not_found_error, idempotency_conflict,
executor_credential_exists and 409 sandbox_reset_in_progress, and /v1
for runtime_node_unavailable, with the machine-specific triggers.
Widen turn_conflict to Environment file writes.

Request conventions: the Environment files list also takes limit, and a
mismatched scope header gets the rejected-key 401. Drop the U+0000 rule
that Session metadata and Vault creation repeated.
An operation description in the contract is usually one long paragraph. The
page opened with all of it, which pushed the request and response sections
below the fold, and the contract text cannot be shortened without diverging
from upstream.

The reference now keeps the opening sentences under the title and folds the
rest into a collapsed block, regrouped into short paragraphs at sentence
boundaries. The contract prose itself stays verbatim, so the projection and
verify:copy are unchanged.
Rebuild the API reference and guide pages from the current contracts after
rebasing onto upstream main, including the folded operation descriptions and
the per-operation pages.
Four fixes to the generated guide record and the checks around it.

- The generated record in content/guide-sources.json no longer matched
  scripts/guides.json after the title escape was restored, so verify:docs failed
  and the two later verify steps never ran. Regenerated the guides.
- The two new guides were absent from content/docs/meta.json, so fumadocs
  dropped them from the sidebar even though they were routable and linked.
  Listed them, and taught verify-docs-facts.mjs to fail when a page under
  content/docs is missing from that list.
- docs/api/request-conventions.md claimed an operation page states only what
  differs from the conventions, although Files, Skills and Create a reusable
  Agent repeat a rule there. Stated the rule the pages follow.
- The registry's Namespaces column was documentation only. A new conformance
  test rejects a cell that is empty, names something that is not a namespace or
  claims both "all" and a single namespace.
The execution-model page rendered docs/web/architecture.md, which carries a
Mermaid fence the site cannot draw. It now renders docs/architecture.md, the
architecture overview, so the page shows its three diagrams and no Mermaid
fence is left anywhere on the site.
Upstream's Runtime MCP binding and workspace execution capabilities change
edits the public contract, so two Session operation pages and the generated
source records follow it.
The guide's URL named the old page rather than the document it now renders,
so the slug, the sidebar entry, the browser check and the generated-copy
allowlist follow the new name.
Nothing renders this file: the guide it was added for now embeds the
repository diagrams next to their source.
@SaladDay SaladDay closed this Sep 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants