Skip to content

Latest commit

 

History

3 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

api-spine-oh

Kurz auf Deutsch. Der API-Spine ist der eine getypte Kern hinter den Fassaden der Plattform: vierzehn Operationen, die REST-Spezifikation aus dem Code erzeugt, der Client aus der Spezifikation erzeugt, jede Operation genau einer Zeile eines Fähigkeitsregisters zugeordnet. Lesend über dem Verzeichnis, dem Siegelregister und dem Werkzeug-Inventar; dazu ein Passkey-Login. Anleitung unten auf Englisch.

api-spine-oh is the API of the association OpenHelvetia: one typed core behind the platform's facades. The REST specification is emitted from the code (dropshot), the client is generated from the specification (progenitor), and the MCP tool surface of the gateway binds to the same functions — never a second implementation of the same semantics. Fourteen operations, each mapped to exactly one row of a capability register that lives in code; a test proves that register and specification cover each other exactly.


Contents

  1. Before you start
  2. Get it running in five minutes
  3. The operations
  4. Your first calls
  5. How the pieces fit
  6. What is in this repository
  7. How it is verified
  8. When something does not work
  9. Where this repository comes from
  10. Contributing, security, licence

1. Before you start

Need Why How to get it
Rust, stable (rustc and cargo) everything here is built from source https://rustup.rs — one command, then open a new terminal and run cargo --version
Git to clone this repository macOS: xcode-select --install; Linux: your package manager; Windows: https://git-scm.com

The tests need no network. Linux and macOS are what the association builds on; Windows works in principle, use WSL if in doubt.

2. Get it running in five minutes

Clone

git clone https://github.com/OpenHelvetia/api-spine-oh.git
cd api-spine-oh

Run the tests (offline; the end-to-end tests start the server on a free local port)

cargo test --locked --manifest-path registry/api/spine/Cargo.toml
cargo test --locked --manifest-path registry/api/client/Cargo.toml
cargo test --locked --manifest-path registry/api/facts/Cargo.toml
cargo test --locked --manifest-path profile/auth/login/Cargo.toml

Serve the API locally, read-only, over the entries in this repository:

cargo run --locked --manifest-path registry/api/spine/Cargo.toml -- serve --root . --port 8710

What you should see: oh-api serving on 127.0.0.1:8710. Then, in a second terminal:

curl -sS http://127.0.0.1:8710/capabilities
curl -sS http://127.0.0.1:8710/directory

Print the specification exactly as the server emits it:

cargo run --locked --manifest-path registry/api/spine/Cargo.toml -- emit-openapi

3. The operations

Method Path What it answers
GET /capabilities the capability register: every operation with its id, method, path and which clients exercise it
GET /directory the directory envelope (v0.2, authority: manifest), one schema-shaped row per entry
GET /registry/{slug}/manifest the byte-identical manifest of one entry; 404 when there is none
GET /ns/artifacts the seal register: every sealed artifact with its hash
GET /tools the gateway's tool inventory with the weight of every call
GET /publish the three admission routes into the directory
GET /facts/{domain} the latest measured facts of a domain (checker, benchmark)
GET /facts/{domain}/badge the same, as a badge document
POST /login/register/begin, /login/register/finish passkey registration (WebAuthn)
POST /login/authenticate/begin, /login/authenticate/finish passkey login, issuing a session
POST /login/logout ends a session
GET /login/whoami who the caller is — the one authorised call

The read operations serve the repository as it is: no write path exists in the code. The login operations run only when a login backend is configured; without one the server refuses them rather than improvising a store.

4. Your first calls

With the server from §2 running:

curl -sS http://127.0.0.1:8710/publish
curl -sS http://127.0.0.1:8710/registry/openhelvetia-fedlex-mcp/manifest | head -c 400
curl -sS -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8710/registry/no-such-entry/manifest

The last line answers 404 — an absent entry is an honest not-found, never an empty object.

5. How the pieces fit

  • registry/api/spine — the server and the capability register; emit-openapi prints the specification.
  • registry/api/openapi.json — the committed specification; the corpus gate fails when it differs from what the code emits.
  • registry/api/gen-client + registry/api/client — the client is generated from the specification and committed; a second gate fails on drift. Consumers use the client, never hand-written calls.
  • registry/api/facts — the bitemporal fact core the /facts operations read.
  • profile/auth, profile/org — authorisation and the organisation model; profile/auth/login with store and serve — passkeys, sessions, and their storage.

6. What is in this repository

Path What
registry/api/spine/ the server, the register, the tests (end-to-end over a real local server)
registry/api/openapi.json the specification, emitted from the code
registry/api/client/, registry/api/gen-client/ the generated client and its generator
registry/api/facts/ the fact core
profile/auth/, profile/org/ authorisation, organisation model, passkey login
registry/entries/ the directory's entries the server reads
registry/standard/directory.schema.json, artifacts.json the envelope schema the tests validate against, and the seal register /ns/artifacts mirrors
mcp/gateway/tool-inventory.json the inventory /tools serves
LICENSE, NOTICE Apache-2.0 and the attributions

7. How it is verified

The spine's tests prove that the capability register and the specification's operations cover each other exactly, that /directory satisfies the same directory schema the website emits, that every read operation answers over a real local server, and that the login flow works end to end against an in-memory backend. The client's end-to-end test walks every non-login capability through the generated client. Two drift gates in the corpus keep the committed specification and client equal to what the code emits.

8. When something does not work

You see What it means What to do
error: package … requires rustc 1.xx your Rust is too old rustup update stable
serve exits at once the root has no registry/entries pass --root pointing at the folder you cloned
a login route answers that no backend is configured this build serves read-only that is intended; the login backend is a deployment concern
the port is taken another process listens on 8710 choose another --port

Where this repository comes from

The association develops all its modules in one corpus, on its own GitLab, where every change runs through a gate (formatting, Clippy without warnings, all tests, seal and drift checks). This repository is assembled from that corpus by the publication lane (tools/publish-module.sh there): it takes the crates and exactly the files their builds and tests need, runs the tests in the assembled tree, and pushes here. Each publication is one commit whose message names the corpus commit.

This copy was published from corpus commit 93e2d01 on 2026-09-06.

Contributing, security, licence

  • Issues here are welcome: a wrong result, a missing case, an unclear sentence in this README. Please include the command you ran and what came back.
  • Changes go through the corpus and arrive here with the next publication; a pull request here is read and carried over by hand.
  • Security reports, in confidence: admin@openhelvetia.swiss. The association answers within a working week.
  • Licence: Apache-2.0 (LICENSE, attribution in NOTICE).

About

The OpenHelvetia API spine: fourteen read-only and login operations behind the platform's facades, the OpenAPI specification emitted from code, the client generated from it, the capability register in code

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages