EKO-4 až EKO-10 – kontrakty (2026-11-11)
Schváleno Adrianem 2026-11-11 (NAVRHY-10). Vše za příznaky, výchozí vypnuto. Každý projekt funguje samostatně; tyto kontrakty jen popisují, jak se volitelně propojí.
EKO-1 Federace MCP (hotovo v hostingu)
Brána POST /v1/ecosystem/mcp přidá read-only nástroje služeb jako <slug>__<nástroj>. Podmínky: manifest má links.mcp na vlastním hostu, mcp.read_only není false, nástroj má annotations.readOnlyHint = true, brána má pro službu servisní token (ONHOST_ECOSYSTEM_GATEWAY_TOKENS). Brána nikdy nepřeposílá token volajícího. Služba vydá bráně token se scope mcp:read (později OnPass client credentials).
EKO-4 Federovaný katalog
Služba publikuje offers[] v manifestu (schemas/ecosystem/onhost-service.v1.json): id, name, url (https, objednávka vždy probíhá u projektu), volitelně price {amount_minor, currency, period, vat_included}, category, recommend_to[]. OnPass katalog jen zobrazuje a odkazuje; neúčtuje, nedrží platbu, nemá lock-in. Ceny jsou orientační, závazná je cena u projektu.
EKO-5 Status page
Monitor pro každou službu z registru brány: links.health, očekávaný HTTP 200 do 5 s. Zdroj seznamu: GET /v1/ecosystem/services. Implementace v observability (OBS-4).
EKO-6 UI tokeny Brand V2
Balíček @onhost/brand-tokens (npm) a onhost/brand-tokens (composer) s CSS proměnnými --oh-* (barvy, typografie, rádiusy, mezery) a světlým/tmavým tématem. Zdroj pravdy: BrandManual_V2.pdf. Projekty přejímají postupně; žádné CDN, soubory se vkládají při buildu.
EKO-7 GDPR „smazat vše“ (OnPass onhost-id #12, příznak ONPASS_FEATURE_ERASURE_RECEIPTS vypnuto)
OnPass pošle cz.onhost.onpass.user.deleted.v1 (Standard Webhooks). data.erasure = {id, ack_url, token, deadline}. Klient smaže nebo anonymizuje data a potvrdí POST {ack_url} s hlavičkou Authorization: Bearer {token} a tělem {"outcome": "erased"|"not_found"|"retained", "retention_basis": "…"}; retention_basis je povinný u retained (účetnictví 10 let, zdravotní dokumentace). Zdroj pravdy: onhost-id docs/events.md, oddíl „Potvrzení výmazu (EKO-7)“. Když data.erasure chybí, klient nic nepotvrzuje. Subjekt je v data.sub (pairwise, jiný pro každou aplikaci), vedle něj data.client_id. retention_basis má nejvýše 300 znaků. Úplný příklad doručení (hlavičky podpisu, obálka, potvrzení a odpovědi): [fixtures/onpass-user-deleted-event.json](../../fixtures/onpass-user-deleted-event.json).
Odpovědi klienta na webhook OnPass (závazné): OnPass čte jen stavový kód. 2xx = doručeno (neopakuje se); 410 = endpoint zrušen (webhook se vypne); cokoli jiného (4xx, 5xx, timeout 5 s, přesměrování) = opakování 5 s → 5 min → 30 min → 2 h → 5 h → 10 h → 10 h → failed. Proto: neplatný podpis → 401; platná událost, která se klienta netýká (cizí data.client_id, duplicitní webhook-id, neznámý účet) → 2xx (např. 202 {"status":"ignored"}); neznámý typ události → 2xx ignored, ne 422 (OnPass posílá i consent.revoked.v1 a webhook.test.v1 a může přidat další). Odpověď do 5 s, práce asynchronně. Registr adres klientů: onhost-id docs/client-webhooks.md.
Kit: Onhost\EcosystemKit\Gdpr\ErasureReceipt::fromEvent($data, $onpassHost)->request($outcome, $basis) vrátí url, hlavičky a tělo; ack_url musí být https na hostu OnPass. Klient ho volá z handleru user.deleted za vlastním příznakem (výchozí vypnuto), token nikdy neloguje.
EKO-8 Křížová doporučení
Widget čte offers[].recommend_to z registru brány a zobrazí nejvýše 3 nabídky jiných projektů. Bez cookies, bez sledování, bez osobních údajů; odkaz s rel="noopener" a parametrem utm_source=<slug> jen pokud je zapnutý příznak projektu. Páry: útulky → zvířata → OnVet, OnHack → ONgames.
EKO-9 Centrální audit událostí
Čeká na OBS-1. Kopie CloudEvents (bez data s osobními údaji, jen id, source, type, time, subject) do observability.
EKO-10 Právní subjekt per projekt
Balíček onhost/legal-entity: konfigurace name, ico, dic, vat_payer, address, registry_note, email, web per projekt; výchozí Adrian Staněk, IČO 08094616, neplátce DPH. Používá ho fakturace, patička, obchodní podmínky a manifest (operator). Změna subjektu = změna konfigurace, ne kódu.