Skip to content

spec: publish the OpenAPI description, and keep it synced - #36

Merged
jeremiahsay merged 1 commit into
mainfrom
feat/publish-openapi
Sep 18, 2026
Merged

jeremiahsay merged 1 commit into
mainfrom
feat/publish-openapi

Conversation

@jeremiahsay

Copy link
Copy Markdown
Collaborator

The gateway has served an OpenAPI 3.1 description at https://api.greencalculus.com/openapi.json for some time — it is already what postman/generate.py reads. Nothing could discover it. It is in no repository, and it is not linked from the developer docs.

A spec that tools cannot find is, for most purposes, a spec that does not exist — the point src/openapi.ts makes upstream about a capability missing from the machine-readable contract, one level out. GitHub code search, API directories, codegen and coding assistants all look for a file.

What's here

File What
spec/openapi.json 26 paths, OpenAPI 3.1. Re-serialised with sorted keys and 2-space indent so a diff is a contract change, not key-order churn from the gateway.
spec/README.md What it is, that the gateway remains the authority, codegen one-liners against both the live URL and the mirror.
.github/workflows/openapi-sync.yml Refetches every Monday, commits on change.
README.md Links the spec from Links.

Why a sync job rather than a one-off copy

A committed copy of a remote truth is a stale copy waiting to happen unless something re-reads the remote on a schedule. So something does.

The job refuses a response that parses but is not a spec — an error page or an edge-cache stub would otherwise overwrite a good mirror with something worse than nothing:

Input Result
{"error": "bad gateway"} refused — not an OpenAPI 3.x document
{"openapi":"3.1.0","paths":{"/v1/health":{}}} refused — only 1 path
The real spec accepted, 26 paths

Verification

The fetch step was extracted from the YAML and executed, not eyeballed — an embedded heredoc inside a block scalar is exactly the thing that only fails at runtime. It runs clean and reproduces the committed file byte for byte, so the weekly job commits only on a real change.

🤖 Generated with Claude Code

https://claude.ai/code/session_01NRueWxopDXHoWY2dPvsmLG

The gateway has served an OpenAPI 3.1 description at
api.greencalculus.com/openapi.json for some time. It is what
postman/generate.py already reads. But nothing could discover it: it is
in no repository, and it is not linked from the developer docs.

A spec that tools cannot find is, for most purposes, a spec that does not
exist — which is the point src/openapi.ts makes upstream about a
capability missing from the machine-readable contract, applied one level
out. GitHub code search, API directories, codegen and coding assistants
all look for a file.

- spec/openapi.json — 26 paths, re-serialised with sorted keys and
  2-space indent so a diff is a contract change rather than key-order
  churn from the gateway.
- spec/README.md — what it is, that the gateway is the authority, and
  codegen one-liners against both the live URL and the mirror.
- .github/workflows/openapi-sync.yml — refetches every Monday and commits
  on change. A committed copy of a remote truth is a stale copy waiting
  to happen unless something re-reads the remote on a schedule.

The sync job refuses a response that parses but is not a spec, so an
error page or an edge-cache stub cannot overwrite a good mirror.
Verified: an error-page JSON is refused, a 1-path stub is refused, the
real spec is accepted.

The fetch step was executed locally rather than eyeballed — it runs clean
and reproduces the committed file byte for byte, so the weekly job will
commit only on a real change.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NRueWxopDXHoWY2dPvsmLG
@jeremiahsay
jeremiahsay merged commit 27f91f5 into main Sep 18, 2026
7 checks passed
@jeremiahsay
jeremiahsay deleted the feat/publish-openapi branch September 18, 2026 11:23
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.

1 participant