# NutriCoach v1.4 authority receipt threat boundary

## Decision

The gateway is a verifier and consumer of the weekly-operations authority
receipt. It is not an issuer.

- Product runtime code exposes no public registry-identity or authority-receipt
  issuer.
- Test fixtures construct receipts in test-only helpers.
- Todo 12 binds the exact authority/config/registry receipt inputs into the
  candidate manifest.
- Todo 13 creates the exact live receipt only inside the one-use,
  permission-sealed operator workflow and binds it to the candidate, profile,
  customer, consent, owner, registry inode, and config.
- The gateway parses one immutable startup snapshot and rejects any drift
  during capability construction or runtime refresh.

An actor that can rewrite both the trusted operator config and its authority
receipt before gateway startup is an authority compromise outside the runtime
parser's threat model. An unkeyed binding digest is integrity/provenance data,
not a cryptographic signature, and must never be described as one.

## Resource ownership

Bootstrap construction owns every partially opened customer capability in an
`ExitStack`. Failure closes all descriptors in reverse order. Successful
construction explicitly transfers ownership to the adapter, which closes them
at shutdown.

## Process-interruption boundary

The owner approved the recommended production boundary on 2026-08-25:

- Recoverable `Exception` paths and asynchronous cancellation at actual await
  seams must clean up deterministically and leave the process usable.
- SIGTERM, `SystemExit`, or `KeyboardInterrupt` delivered during synchronous
  descriptor allocation/close is a process-termination boundary. The service
  must exit and rely on kernel process teardown; it does not catch an arbitrary
  instruction-level `BaseException` and continue serving.
- A test harness that catches such a termination exception, concurrently reuses
  the same raw descriptor number from an unrelated thread, and then requires
  the interrupted process to remain usable is outside the gateway runtime
  recovery contract.
- This boundary does not excuse ordinary exception leaks, provider uncertainty,
  async cancellation leaks, shutdown hangs, duplicate sends, or restart
  retries. Those remain release blockers.

A native C/Rust descriptor transaction would be required to guarantee atomic
Python object-state and kernel-FD transitions against arbitrary instruction-
level termination plus concurrent raw-FD reuse. That cross-platform release
surface is rejected for v1.4 because process termination already provides the
correct containment boundary.
