Contracts
hosted-posture.md
Contract: hosted posture
Repo hosted.drain | Personal [hosted] drain | Env narrower set | Effective drain |
|---|---|---|---|
| true | true | no | on |
| true | true | yes | off (reason: narrower name) |
| true | false/absent/invalid | – | off (reason: personal scope) |
| false/absent/invalid | any | – | off (reason: repository scope) |
credential access (plan.md D2, F-1/F-2; budget.py stays stdlib-only and is not an edge):
(__init__ is not gated).
cache or keyring read; fan-out, producers, live-work, the widen prereq probe return silently.
Live drain is off (<reason>). Enable with: spec-kitty moments drain on [--repo].
ledger, tracked status.json, decisions/, run.events.jsonl and kitty-ops/ are unaffected in every case.
automatic callers use resolve_server_target_or_none() and stay silent.
- Drain off ⇒ these edges raise
DrainDisabled(or return the stated sentinel) before any network, thread or transport.ZeitgeistClient.offer→ returnsOfferOutcome.DRAIN_DISABLED(no thread; neverDROPPED_UNREACHABLE);filtered_stream.FilteredStream.seed_from_snapshot/.watchandhistory.read_history→ raiseDrainDisabled;resolution.SaasCapabilityGateway.check_repo_admission/.mint_capability→ raiseDrainDisabled- Drain off ⇒
resolve_credentials,resolve_focus_capability(andresolve_focus_lease) returnNonebefore any - Drain off ⇒ every relay CLI command and MCP relay tool pre-flights
require_drain("relay")before any credential read. - CLI surfaces map
DrainDisabledto one line, the constanthosted_posture.DRAIN_GUIDANCE_LINE: - Authored send/reply refuse with
AuthoredMessageErrorcodedrain_off; a drain refusal is never retried. - Ledger
projectiontrue ⇒ refresh after each durably persisted transition; false ⇒ no automatic refresh. The lane - Endpoint unconfigured ⇒ explicit callers get
HostedEndpointUnconfigured(guidance, exit non-zero, no traceback);