Skip to content

Production handbook

Tenchi keeps production infrastructure outside the framework core, but it gives each concern a defined place. Process resources live in lifespan, request resources live in the context scope, external systems sit behind application-owned ports, and operational entrypoints call the same use cases as HTTP.

This handbook turns that model into concrete recipes for a service that needs to survive retries, concurrent writes, partial failures, and deployment changes.

What Tenchi owns

Tenchi provides the application seams and boundary guarantees:

ConcernTenchi's partYour application's part
ConfigurationExplicit composition and lifespan stateLoad and validate environment-specific values
DatabaseLifespan and request-scoped context managersChoose a driver, migrations, transaction isolation, and adapters
AuthenticationBoundary hooks and public-contract metadataVerify credentials and supply the identity port
AuthorizationPlain use cases and pure policiesDefine abilities and owner-scoped repository methods
RetriesCanonical fingerprints, durable store transitions, typed replay, and declared errorsImplement storage in the command transaction and choose key scope and retention
Rate limitingAtomic fixed-window store protocol, policy validation, and a standard 429Choose authenticated scope, shared storage, transaction semantics, and edge limits
Inbound webhooksExact-body verifier bindings, required composition, request limits, and typed validationVerify the provider protocol, attach service identity, enforce replay rules, and store event ids
Background workValidated job messages, handler bindings, dispatch, and scoped contextsChoose a queue or outbox, schedule workers, and define retry policy
Operational maintenanceValidated named tasks, CLI/MCP discovery, and scoped executionDefine safe dry runs, operator access, and rollout procedure
ObservabilityFinalized outcomes plus an optional OpenTelemetry bridgeConfigure the SDK, transport instrumentation, exporters, alerts, and retention
DeploymentHealth routes, request limits, deadlines, tenchi check, and environment preflightConfigure the ASGI server, proxy, secrets, migrations, dependency credentials, and rollout
The core does not select your infrastructure

Tenchi does not bundle an ORM, queue, scheduler, telemetry SDK, or settings package. Those libraries remain replaceable adapters. The handbook defines how they participate in the application lifecycle and failure model.

Build the production boundary

Use the following order when turning a working Tenchi application into a deployed service:

  1. Validate configuration and secrets once at startup.
  2. Open process resources and one transaction per request.
  3. Put outbound SDKs, repositories, clocks, and identity lookups behind ports.
  4. Make retried commands idempotent and defer external effects through a durable worker boundary.
  5. Apply authenticated operation quotas and configure edge limits.
  6. Verify inbound webhook bytes and collapse provider redeliveries.
  7. Emit low-cardinality request and worker telemetry.
  8. Declare read-only checks for the target environment.
  9. Configure health, limits, middleware, and the release gate.

Authentication and authorization have their own boundary-to-policy workflow. Testing follows the same resource model: use memory adapters for application behavior, then exercise real transactions and lifespan in integration tests.

Choose a consistency requirement before an adapter

A port should say what its caller needs, not which vendor implements it. A command repository normally needs strong reads and writes in the current transaction. A search port can explicitly permit stale results and use a read replica. A notification port can promise only that work was durably accepted, not that an email was delivered during the request.

Keep those meanings visible in method names and docstrings. Wiring can then change from SQLite to PostgreSQL, an in-process adapter to a service client, or a primary connection to a replica without silently weakening a use case.

Define the failure owner

For every boundary, decide which component owns each outcome:

This avoids ambiguous failures such as retrying invalid payloads forever, committing state before its outbox record, or treating a logging outage as an API failure.

Production baseline

Before the first deployment, verify that the service has:

The deployment guide turns this list into the final release sequence.