feat(api): /v1 alias router for stable external contract (Issue A)

Mounts an explicit allowlist of public handlers under /v1 alongside the
existing unversioned paths. External clients (AKC, OpenClaw, future
tools) should target /v1; internal callers (hooks, wiki, admin UI) keep
working unchanged. Breaking schema changes will bump the prefix to /v2.

- src/atocore/main.py: _V1_PUBLIC_PATHS allowlist + second router
- tests/test_v1_aliases.py: parity + OpenAPI presence (5 tests)
- README.md: API versioning section
- DEV-LEDGER.md: session log, test_count 459 -> 463

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-21 20:04:46 -04:00
parent 90001c1956
commit 5fbd7e6094
4 changed files with 137 additions and 2 deletions

View File

@@ -40,6 +40,26 @@ python scripts/atocore_client.py audit-query "gigabit" 5
| GET | /health | Health check |
| GET | /debug/context | Inspect last context pack |
## API versioning
The public contract for external clients (AKC, OpenClaw, future tools) is
served under a `/v1` prefix. Every public endpoint is available at both its
unversioned path and under `/v1` — e.g. `POST /entities` and `POST /v1/entities`
route to the same handler.
Rules:
- New public endpoints land at the latest version prefix.
- Backwards-compatible additions stay on the current version.
- Breaking schema changes to an existing endpoint bump the prefix (`/v2/...`)
and leave the prior version in place until clients migrate.
- Unversioned paths are retained for internal callers (hooks, scripts, the
wiki/admin UI). Do not rely on them from external clients — use `/v1`.
The authoritative list of versioned paths is in `src/atocore/main.py`
(`_V1_PUBLIC_PATHS`). `GET /openapi.json` reflects both the versioned and
unversioned forms.
## Architecture
```text