llm-connect/contracts/functional/messages-admission.md
tegwick 718e6730e4
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Provide a private Unix listener for owner-metered Messages
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a07ff8-19d0-7820-b4d0-1353833cb7fc
2026-09-09 22:20:55 +02:00

5.8 KiB

Owner-hosted Messages admission

llm_connect.messages_gate supplies an opt-in, stdlib-only Messages listener. It is separate from LLMServer and is never enabled by normal serve mode. The work record is LLM-WP-0009; factory integration is HFACT-WP-0001-T01 and REINAH-WP-0003-T05/T06.

Contract

The owner constructs immutable MessagesPolicy with an exact model, tariff reference, maximum admitted context/output, integer micro-USD per-token upper rates, explicit beta allowlist, body limit and request timeout. There is no built-in live price, FX source, token estimate or default beta grant. Input rates must conservatively cover input, both cache-write lifetimes, cache reads and all accepted multipliers. Accepted provider limits and tariff validity remain an operator policy responsibility; a fixture policy cannot establish them.

RequestMeter.reserve_request(token, policy_sha256, liability_microusd) must atomically check authority and remaining parent capacity, persist the hold and return an opaque receipt before the transport opens a provider connection. The reserved amount is full context times the maximum input rate plus requested output times the maximum output rate. This deliberately trades utilization for a bound that does not depend on unproven local token estimation.

request_active(receipt) checks the run and lease. complete_request(receipt, observed_microusd) records trusted terminal accounting while retaining the full reservation. Any exception, cancellation, non-200 response, truncated stream, unknown fee/model/content feature or missing usage leaves an unknown hold. A retry is another request and cannot be forwarded through an unresolved hold. The forwarder neither retries nor follows redirects; it ignores proxy variables and accepts only a fixed HTTPS provider origin (loopback HTTP is explicit for tests). Only owner headers and the accepted beta list reach that origin.

The listener accepts POST /v1/messages[?beta=true] with an opaque x-api-key route token. No /execute, arbitrary URL, alternate authorization or compressed request route is available. Duplicate JSON/header fields and unsupported API features refuse. The supported subset is streaming text, custom client tools, ordinary thinking/effort and ephemeral cache controls. Context management is limited to the CLI's exact keep-all-thinking form; server compaction, server tools, media/URL blocks, model fallback, extended context and extra paid features need separate implementation and accepted bounds.

SSE terminal accounting includes input, output, cache creation and cache reads; output deltas are cumulative. The final stream event is held until the durable completion returns so a following tool-loop request cannot race that write. Request bodies, provider bodies and credentials are not written to logs or request receipts. Client metadata is untrusted context, never authorization.

Owning integration and remaining admission

Rein's RequestLedger implements this protocol as child holds in the existing private SQLite envelope. Parent reservations continue to account for daily/total capacity; child requests cannot mint a second allowance. Its explicit schema provisioning never runs automatically on missing state. A trusted owner binds one route to the admitted parent run, exact policy digest and queue lease expiry; the parent already binds worker, definition, project, target, grant and runtime digests. Route tokens are random, stored only as hashes, cannot be rebound or renewed by the workload, and revoke on parent terminal observation.

The next integration must host the listener in the trusted owner boundary, keep provider credentials and ledger inaccessible to the sandbox, deliver only its run token/base URL, bind actual lease loss to route revocation, and prove direct provider and alternate-route denial. This module does not install a listener, configure a sandbox, resolve credentials, or promote a profile. The installed CLI fixture demonstrates transport/ledger behavior in a fake-provider namespace; it does not prove secret or network separation between real owner/workload processes. LLM-WP-0009-T03 retains this owner integration return.

Verification and primary protocol references

tests/test_messages_gate.py exercises the policy, protocol and bounded refusal. Rein's tests/test_request_admission.py exercises actual HTTP and SQLite capacity, concurrency, recovery, lease loss and uncertain outcomes. Its opt-in tests/test_native_cli_boundary.py also uses the installed 2.1.266 CLI: the USD 0.01 counterexample is refused before any fake upstream call, while a permitted two-request tool session succeeds. All rates/FX/keys in those tests are synthetic and have no production authority.

Protocol references inspected 2026-09-09: Messages, streaming, context editing, prompt caching.

Private Unix hosting

MessagesServer(..., unix_path=Path(...)) binds AF_UNIX only, mode 0600 inside an owner-owned mode 0700 directory. It refuses an existing path rather than unlinking another listener, and removes only its own socket inode on stop. At most 16 request handlers are active; idle header reads time out. TCP host/port selection cannot coexist with Unix mode. The protocol and durable meter interface are unchanged. Rein's MessagesOwner supplies the private listener, accepted lease and cancellation hooks; sand-boxer mounts only the socket and enforces sole routing. The provider key and ledger remain outside the workload. This source/library path is tested with a fake provider; accepted custody, protected bootstrap/artifact and Railiance placement are still required by LLM-WP-0009-T03.