v3/docs/adr/ADR-308-cognitum-public-api-contract.md
The funnel spans an organizational boundary: ruflo is open source; api.cognitum.one is a proprietary service. Auth (ADR-306), attribution events (ADR-305), deletion (ADR-305/309), funnel policy (ADR-305 freshness kill switch), routing (ADR-304/307), and credits (ADR-303) all cross it. Without a versioned, independently testable contract, every one of those ADRs has an unspecified dependency, and conversion numbers are irreproducible.
Define a versioned public API contract, owned jointly and checked into both repositories.
POST /v1/auth/device # device authorization flow (RFC 8628)
POST /v1/auth/token # code/refresh exchange
POST /v1/auth/revoke # token + session revocation
POST /v1/events # funnel event ingestion (idempotent)
DELETE /v1/events/{subject_id} # verifiable deletion (ADR-305/309)
GET /v1/funnel-policy # signed policy feed (freshness kill switch, opt-in only)
POST /v1/proxy/chat/completions # OpenAI-compatible cloud routing
GET /v1/credits # credit balances (the single credit authority, ADR-303)
v3/docs/api/cognitum-v1.openapi.yaml; server repo mirrors it). CI in both repos validates against the shared spec; drift fails the build./v1 is stable; breaking changes require /v2 with a documented overlap window. The CLI declares the API versions it supports.POST /v1/events (client-generated UUID per event batch) — retries never double-count impressions or conversions.CreditErrorCode / category tables. No client ever parses human-readable message text.policyVersion rules).| Unavailable | Client behavior |
|---|---|
| Auth | Local ruflo continues working fully; auth-gated capabilities degrade with a clear error |
Telemetry (/v1/events) | Drop, or bounded local queue (≤ 24 h, ≤ 1 MB); never block or slow the CLI |
| Funnel policy | Use last valid signed policy, else package default; never fail open into showing promo |
| Proxy backend | Normal error to caller; never silently reroute to another paid or cloud provider |
| Deletion | Return a durable request receipt to the user and retry server-side until confirmed |
GET /v1/funnel-policy responses are Ed25519-signed with the same key-management discipline as the helper channel; the CLI validates signature + policy schema before honoring anything (ADR-305 freshness kill switch is inert otherwise).