Keep Host Service architecture chapter within byte budget

This commit is contained in:
Ouroboros 2026-10-01 23:00:20 +05:00
parent 843142c439
commit 9a966db397

View file

@ -6,7 +6,7 @@ Chat uploads have one storage owner, `gateway.files`, for Host-confined paths an
Telegram document mirroring resolves the captured `file_ref` and streams an owned file handle through its multipart client (legacy inline bytes still accepted). Its outgoing 50 MiB boundary is separate from the integration's inbound 10 MiB download limit. Oversized files stay saved in the application: a ready, already-running owner-authenticated Mini App can be opened through its entry button; otherwise the message says it cannot mirror the file and directs the owner to the app. Delivery never starts a tunnel or publishes a new public or token-bearing artifact URL, and the notice never claims the bytes were uploaded to Telegram.
The Host Service (`ouroboros/gateway/host_service.py`, `127.0.0.1:${OUROBOROS_HOST_SERVICE_PORT:-8767}`) authenticates every request with opaque `x-skill-token`, bound to payload hash, executable review, enablement and grants. Tokens contain no secrets, stale on payload edit and refuse stringification (`skill_token.py`). The frozen routes are `/identity`, `/tools/schemas`, `/chat/allocate-internal`, `/chat/inject`, `/chat/operations/{operation_ref}`, `/chat/cancel`, `/chat/decision`, `/presence/turn`, `/presence/work/{work_ref}`, `/presence/delivery`, `/ui/ws-message`, `/notify`, WS `/events`; permissions govern access. The `POST /notify` family (`gateway/host_notify.py`, grant `notify_owner`, `notify_version: 1` on `/identity`) writes a bounded plain `owner_notification` events fact, not a chat row or model turn; deferred `at`/`cron` uses the existing schedule table, keyed reposts move it, and `cancel` removes it unless the owner disabled it. A new or moved deferred row is refused before writing with `scheduler_unavailable` while the supervisor tick is absent; cancellation remains possible. Before Host Service accepts a request, a provisional server-process log sink carries immediate browser frames even during provider startup or no-provider boot; the supervisor replaces it when ready. Browser frames and the `owner.notification` topic follow the durable append; neither promises physical Telegram delivery. An immediate 503 is `outcome_unknown`, not proof no append occurred: a repeated `key` is not server-side deduplication. A naive `at` plus `timezone` is refused; an offset-bearing `at` is absolute.
The Host Service (`ouroboros/gateway/host_service.py`, `127.0.0.1:${OUROBOROS_HOST_SERVICE_PORT:-8767}`) authenticates every request with opaque `x-skill-token`, bound to payload hash, executable review, enablement and grants. Tokens contain no secrets, stale on payload edit and refuse stringification (`skill_token.py`). The frozen routes are listed in §4, including `/notify`; grants govern access. `POST /notify` (`gateway/host_notify.py`, grant `notify_owner`, `notify_version: 1` on `/identity`) appends a bounded plain `owner_notification` event, not chat or a model turn. Deferred `at`/`cron` uses the existing schedule table: keyed reposts move a row; `cancel` removes it unless owner-disabled. New or moved rows receive pre-write `scheduler_unavailable` while the supervisor tick is absent; cancellation still works. A provisional server log sink starts before Host Service accepts requests, carrying immediate browser frames even during provider startup or no-provider boot; the supervisor replaces it. Browser frames and the `owner.notification` topic follow the durable append, not proof of Telegram delivery. Immediate 503 means `outcome_unknown`; repeating a `key` does not deduplicate server-side. Naive `at` plus `timezone` is refused; offset-bearing `at` is absolute.
Transport review covers identity/attribution, bounded polling, panic cleanup, token confinement and exfiltration. An owner-bound reviewed transport can control; external slash commands bind a separate positive-identity owner slot (`supervisor/state.py`), so unidentified transports cannot bind and web identity cannot lock out the remote owner. `wait_for_response` is A2A-only; only legacy unnamed operations subscribe chat-wide.