2026-07-05 17:21:59 +02:00
|
|
|
# Production Readiness Roadmap
|
|
|
|
|
|
|
|
|
|
This roadmap tracks the work required before `geth` becomes a dependable base
|
|
|
|
|
layer for personal scripts, infrastructure automation, and other projects.
|
|
|
|
|
Deployment has not started, so large refactors are in scope when they reduce
|
|
|
|
|
long-term risk.
|
|
|
|
|
|
|
|
|
|
Status markers:
|
|
|
|
|
|
|
|
|
|
- `[ ]` Not started
|
|
|
|
|
- `[~]` In progress
|
|
|
|
|
- `[x]` Done
|
|
|
|
|
|
|
|
|
|
## Release Principle
|
|
|
|
|
|
|
|
|
|
Do not widen the feature surface until the existing daemon, storage, protocol,
|
|
|
|
|
authorization, and operational contracts are boring to test, upgrade, and
|
|
|
|
|
debug. The project already has enough prototype capability to validate the
|
|
|
|
|
architecture; the next milestone is making those capabilities stable.
|
|
|
|
|
|
|
|
|
|
## Phase 0: Current Quality Gate
|
|
|
|
|
|
|
|
|
|
Goal: make the documented local quality gate pass before deeper refactors.
|
|
|
|
|
|
2026-07-05 18:11:35 +02:00
|
|
|
- `[x]` Restore the full workspace quality gate.
|
2026-07-05 17:21:59 +02:00
|
|
|
Acceptance criteria:
|
|
|
|
|
- `[x]` `cargo fmt --all -- --check` passes.
|
|
|
|
|
- `[x]` `cargo check --workspace --all-targets` passes.
|
|
|
|
|
- `[x]` `cargo test --workspace` passes.
|
2026-07-05 17:24:03 +02:00
|
|
|
- `[x]` `cargo clippy --workspace --all-targets -- -D warnings` passes.
|
2026-07-05 18:11:35 +02:00
|
|
|
- `[x]` CI enforces the same required checks.
|
2026-07-05 17:21:59 +02:00
|
|
|
|
|
|
|
|
## Phase 1: Daemon Subsystem Refactor
|
|
|
|
|
|
|
|
|
|
Goal: split `geth-node` into reviewable daemon subsystems without changing
|
|
|
|
|
behavior.
|
|
|
|
|
|
2026-07-05 17:27:42 +02:00
|
|
|
- `[~]` Extract daemon startup and runtime ownership.
|
2026-07-05 17:21:59 +02:00
|
|
|
Acceptance criteria:
|
2026-07-05 17:37:12 +02:00
|
|
|
- `[ ]` Daemon startup, shutdown, signal handling, socket setup, and Iroh
|
|
|
|
|
endpoint ownership live outside the main feature handler module.
|
|
|
|
|
- `[x]` Iroh accept-loop and background live-sync task spawning live outside
|
|
|
|
|
the main feature handler module.
|
2026-07-05 17:27:42 +02:00
|
|
|
- `[x]` Runtime state is represented by narrow structs with documented
|
2026-07-05 17:21:59 +02:00
|
|
|
ownership and locking rules.
|
|
|
|
|
- `[ ]` Existing daemon startup and status tests pass unchanged.
|
|
|
|
|
|
|
|
|
|
- `[ ]` Extract local control routing.
|
|
|
|
|
Acceptance criteria:
|
|
|
|
|
- `[ ]` Local `ControlRequest` dispatch is a routing layer, not the home of
|
|
|
|
|
every feature implementation.
|
|
|
|
|
- `[ ]` Each command family has a small handler module or function group.
|
|
|
|
|
- `[ ]` Local-only behavior remains covered by existing integration tests.
|
|
|
|
|
|
|
|
|
|
- `[ ]` Extract protected peer-control routing.
|
|
|
|
|
Acceptance criteria:
|
2026-07-05 17:35:40 +02:00
|
|
|
- `[x]` Shared bounded Iroh line-read and send-finish helpers live outside
|
|
|
|
|
the main feature handler module.
|
2026-07-05 17:43:24 +02:00
|
|
|
- `[x]` Outbound peer-control, pipe-wire, and overlay-wire request helpers
|
|
|
|
|
live outside the main feature handler module.
|
2026-07-05 17:21:59 +02:00
|
|
|
- `[ ]` Iroh control ALPN handling, nonce checks, peer-card validation, and
|
|
|
|
|
endpoint-binding validation are centralized.
|
|
|
|
|
- `[ ]` Feature handlers receive authenticated caller context rather than
|
|
|
|
|
repeating peer-card boilerplate.
|
|
|
|
|
- `[ ]` Remote request tests still prove discovery alone grants no access.
|
|
|
|
|
|
|
|
|
|
- `[ ]` Extract resource module handlers.
|
|
|
|
|
Acceptance criteria:
|
|
|
|
|
- `[ ]` CAS/file-root, KV, DB, document, pubsub, pipe, SSH, and overlay
|
|
|
|
|
handlers are separated enough that each can be reviewed independently.
|
|
|
|
|
- `[ ]` Each module documents its resource IDs, capabilities, and mutation
|
|
|
|
|
points.
|
|
|
|
|
- `[ ]` No generic `geth-common` crate is introduced.
|
|
|
|
|
|
2026-07-05 17:33:40 +02:00
|
|
|
- `[~]` Extract live-sync engine.
|
2026-07-05 17:21:59 +02:00
|
|
|
Acceptance criteria:
|
2026-07-05 17:33:40 +02:00
|
|
|
- `[x]` Sync cursor keys, cursor persistence, stream health recording, and
|
|
|
|
|
local sync-status reduction live in a sync-focused module.
|
2026-07-05 17:49:09 +02:00
|
|
|
- `[x]` Sync stream selection, watermarks, and run result helpers live in a
|
2026-07-05 17:33:40 +02:00
|
|
|
sync-focused module.
|
2026-07-05 17:49:09 +02:00
|
|
|
- `[x]` Per-module sync handlers have consistent interfaces.
|
2026-07-05 18:04:25 +02:00
|
|
|
- `[x]` `geth sync status --json` output remains stable.
|
2026-07-05 17:21:59 +02:00
|
|
|
|
|
|
|
|
## Phase 2: Stable Automation Contracts
|
|
|
|
|
|
|
|
|
|
Goal: make command, JSON, and protocol contracts explicit enough for scripts
|
|
|
|
|
and downstream projects.
|
|
|
|
|
|
2026-07-05 17:51:06 +02:00
|
|
|
- `[x]` Define compatibility policy.
|
2026-07-05 17:21:59 +02:00
|
|
|
Acceptance criteria:
|
2026-07-05 17:51:06 +02:00
|
|
|
- `[x]` CLI command compatibility is documented.
|
|
|
|
|
- `[x]` `--json` output compatibility is documented.
|
|
|
|
|
- `[x]` Local control JSONL compatibility is documented.
|
|
|
|
|
- `[x]` Peer wire protocol compatibility is documented.
|
|
|
|
|
- `[x]` SQLite and signed-operation compatibility are documented.
|
2026-07-05 17:21:59 +02:00
|
|
|
|
2026-07-05 18:04:25 +02:00
|
|
|
- `[~]` Add golden JSON tests.
|
2026-07-05 17:21:59 +02:00
|
|
|
Acceptance criteria:
|
2026-07-05 18:04:25 +02:00
|
|
|
- `[x]` Important script-facing commands have stable JSON fixture tests.
|
2026-07-05 17:21:59 +02:00
|
|
|
- `[ ]` Error JSON includes stable codes for common operator and automation
|
|
|
|
|
failures.
|
2026-07-05 18:04:25 +02:00
|
|
|
- `[x]` Fixture updates require intentional review.
|
2026-07-05 17:21:59 +02:00
|
|
|
|
2026-07-05 17:51:06 +02:00
|
|
|
- `[~]` Expand protocol roundtrip tests.
|
2026-07-05 17:21:59 +02:00
|
|
|
Acceptance criteria:
|
|
|
|
|
- `[ ]` Every `ControlRequest` and `ControlResponse` variant roundtrips.
|
|
|
|
|
- `[ ]` Every `PeerControlRequest` and `PeerControlResponse` variant
|
|
|
|
|
roundtrips.
|
2026-07-05 18:17:16 +02:00
|
|
|
- `[x]` Pipe and overlay wire protocol variants roundtrip.
|
2026-07-05 17:51:06 +02:00
|
|
|
- `[x]` Unknown or malformed protocol inputs fail safely.
|
2026-07-05 17:21:59 +02:00
|
|
|
|
2026-07-05 17:58:49 +02:00
|
|
|
- `[x]` Classify command stability.
|
2026-07-05 17:21:59 +02:00
|
|
|
Acceptance criteria:
|
2026-07-05 17:58:49 +02:00
|
|
|
- `[x]` Commands are marked stable, experimental, or prototype in docs.
|
|
|
|
|
- `[x]` Help text avoids production claims for experimental paths.
|
|
|
|
|
- `[x]` Prototype paths have explicit migration or removal expectations.
|
2026-07-05 17:21:59 +02:00
|
|
|
|
|
|
|
|
## Phase 3: Storage And Migration Hardening
|
|
|
|
|
|
|
|
|
|
Goal: treat local SQLite state as durable product data before users depend on
|
|
|
|
|
it.
|
|
|
|
|
|
2026-07-05 17:54:02 +02:00
|
|
|
- `[x]` Replace opportunistic schema setup with ordered migrations.
|
2026-07-05 17:21:59 +02:00
|
|
|
Acceptance criteria:
|
2026-07-05 17:54:02 +02:00
|
|
|
- `[x]` The store tracks numeric schema versions.
|
|
|
|
|
- `[x]` Each migration is transactional where SQLite supports it.
|
|
|
|
|
- `[x]` Fresh database creation and repeated opens are idempotent.
|
|
|
|
|
- `[x]` Old schema fixtures migrate to the current schema in tests.
|
2026-07-05 17:21:59 +02:00
|
|
|
|
2026-07-05 17:57:09 +02:00
|
|
|
- `[~]` Make multi-table writes transactional.
|
2026-07-05 17:21:59 +02:00
|
|
|
Acceptance criteria:
|
2026-07-05 17:57:09 +02:00
|
|
|
- `[x]` Signed operation and signature imports commit atomically.
|
2026-07-05 17:21:59 +02:00
|
|
|
- `[ ]` Multi-record sync imports cannot leave partial state after a local
|
|
|
|
|
error.
|
2026-07-05 17:57:09 +02:00
|
|
|
- `[x]` Tests cover failure injection for at least one multi-table path.
|
2026-07-05 17:21:59 +02:00
|
|
|
|
|
|
|
|
- `[ ]` Add backup and restore workflow.
|
|
|
|
|
Acceptance criteria:
|
|
|
|
|
- `[ ]` `geth backup create` or an equivalent documented command captures
|
|
|
|
|
metadata, identity public material, config, and CAS metadata expectations.
|
|
|
|
|
- `[ ]` Restore can write to a separate target home for validation.
|
|
|
|
|
- `[ ]` Backup output avoids copying private SSH admin keys.
|
|
|
|
|
- `[ ]` Docs explain what is and is not included.
|
|
|
|
|
|
2026-07-05 18:10:41 +02:00
|
|
|
- `[x]` Document database durability settings.
|
2026-07-05 17:21:59 +02:00
|
|
|
Acceptance criteria:
|
2026-07-05 18:10:41 +02:00
|
|
|
- `[x]` WAL and synchronous settings are chosen deliberately.
|
|
|
|
|
- `[x]` Crash-recovery expectations are documented.
|
|
|
|
|
- `[x]` `geth doctor` or status output reports obvious store issues.
|
2026-07-05 17:21:59 +02:00
|
|
|
|
|
|
|
|
## Phase 4: Security Boundary Closure
|
|
|
|
|
|
|
|
|
|
Goal: finish the authorization and remote-input audit before deployment.
|
|
|
|
|
|
2026-07-05 17:59:47 +02:00
|
|
|
- `[~]` Complete remote authorization matrix coverage.
|
2026-07-05 17:21:59 +02:00
|
|
|
Acceptance criteria:
|
|
|
|
|
- `[ ]` Denied and allowed paths are tested for CAS, KV, DB, document,
|
|
|
|
|
pubsub, pipe, SSH proxy/admin shell, SSH cert metadata, and revocations.
|
2026-07-05 17:59:47 +02:00
|
|
|
- `[x]` Every remote mutating or service-opening operation has an explicit
|
2026-07-05 17:21:59 +02:00
|
|
|
resource capability check before mutation or host access.
|
2026-07-05 17:59:47 +02:00
|
|
|
- `[x]` The matrix fails tests when a new remote operation lacks a guard.
|
2026-07-05 17:21:59 +02:00
|
|
|
|
|
|
|
|
- `[ ]` Add adversarial identity and bearer tests.
|
|
|
|
|
Acceptance criteria:
|
|
|
|
|
- `[ ]` Tests cover discovered-only peers.
|
|
|
|
|
- `[ ]` Tests cover wrong endpoint bindings.
|
|
|
|
|
- `[ ]` Tests cover revoked nodes.
|
|
|
|
|
- `[ ]` Tests cover stale or mismatched peer cards.
|
|
|
|
|
- `[ ]` Tests cover bearer secrets with wrong capabilities.
|
|
|
|
|
- `[ ]` Tests cover bearer attempts to mutate trust graph state.
|
|
|
|
|
|
2026-07-05 18:22:07 +02:00
|
|
|
- `[x]` Bound all remote input paths.
|
2026-07-05 17:21:59 +02:00
|
|
|
Acceptance criteria:
|
2026-07-05 18:22:07 +02:00
|
|
|
- `[x]` Remote request payloads have documented size limits.
|
|
|
|
|
- `[x]` Remote stream reads have timeouts or bounded behavior.
|
|
|
|
|
- `[x]` Oversized messages are rejected without state mutation.
|
|
|
|
|
- `[x]` Tests cover oversized payload denial for representative protocols.
|
2026-07-05 17:21:59 +02:00
|
|
|
|
|
|
|
|
- `[ ]` Audit host-opening paths.
|
|
|
|
|
Acceptance criteria:
|
|
|
|
|
- `[ ]` TCP forwarding remains loopback-only unless a later ADR expands it.
|
|
|
|
|
- `[ ]` Unix forwarding rejects unsafe paths.
|
|
|
|
|
- `[ ]` SSH proxy connects only to the intended local SSH endpoint.
|
|
|
|
|
- `[ ]` Overlay TUN setup remains explicit opt-in.
|
|
|
|
|
- `[ ]` Docs state host access risks and recovery commands.
|
|
|
|
|
|
|
|
|
|
## Phase 5: Production Cryptography Boundary
|
|
|
|
|
|
|
|
|
|
Goal: remove prototype cryptography from paths users may treat as real
|
|
|
|
|
confidential storage.
|
|
|
|
|
|
|
|
|
|
- `[ ]` Replace prototype private CAS envelope.
|
|
|
|
|
Acceptance criteria:
|
|
|
|
|
- `[ ]` The BLAKE3-XOR prototype envelope is not used for new private CAS
|
|
|
|
|
writes.
|
|
|
|
|
- `[ ]` New private CAS writes use a reviewed AEAD construction or an
|
|
|
|
|
established envelope format such as age.
|
|
|
|
|
- `[ ]` Key derivation, nonce generation, and envelope versioning are
|
|
|
|
|
documented.
|
|
|
|
|
- `[ ]` Tests cover tamper detection, wrong resource, wrong key, and nonce
|
|
|
|
|
uniqueness behavior.
|
|
|
|
|
|
|
|
|
|
- `[ ]` Define pre-release encrypted blob migration behavior.
|
|
|
|
|
Acceptance criteria:
|
|
|
|
|
- `[ ]` Existing prototype envelopes are either rejected with a clear error
|
|
|
|
|
or migrated through an explicit command.
|
|
|
|
|
- `[ ]` Docs state that prototype envelopes made before deployment are not a
|
|
|
|
|
durable security format.
|
|
|
|
|
|
|
|
|
|
## Phase 6: Sync Correctness And Fault Testing
|
|
|
|
|
|
|
|
|
|
Goal: make convergence and failure behavior predictable enough for automation.
|
|
|
|
|
|
|
|
|
|
- `[ ]` Build deterministic multi-daemon fault tests.
|
|
|
|
|
Acceptance criteria:
|
|
|
|
|
- `[ ]` Tests cover peer restart.
|
|
|
|
|
- `[ ]` Tests cover endpoint rotation.
|
|
|
|
|
- `[ ]` Tests cover temporary peer unavailability.
|
|
|
|
|
- `[ ]` Tests cover partial stream failure.
|
|
|
|
|
- `[ ]` Tests cover duplicate records and stale cursors.
|
|
|
|
|
|
|
|
|
|
- `[ ]` Define per-resource conflict semantics.
|
|
|
|
|
Acceptance criteria:
|
|
|
|
|
- `[ ]` CAS/file-root conflict semantics are documented and tested.
|
|
|
|
|
- `[ ]` KV conflict semantics are documented and tested.
|
|
|
|
|
- `[ ]` Document merge semantics are documented and tested.
|
|
|
|
|
- `[ ]` DB change application limits are documented and tested.
|
|
|
|
|
|
|
|
|
|
- `[ ]` Add live-sync retry and backoff policy.
|
|
|
|
|
Acceptance criteria:
|
|
|
|
|
- `[ ]` Failed peer streams back off without starving healthy streams.
|
|
|
|
|
- `[ ]` Retry state appears in `geth sync status --json`.
|
|
|
|
|
- `[ ]` Operators can trigger immediate retry with `geth sync now`.
|
|
|
|
|
|
|
|
|
|
## Phase 7: Script And Automation UX
|
|
|
|
|
|
|
|
|
|
Goal: make `geth` ergonomic and stable as a base layer for custom automation.
|
|
|
|
|
|
|
|
|
|
- `[ ]` Stabilize JSON errors.
|
|
|
|
|
Acceptance criteria:
|
|
|
|
|
- `[ ]` Common failures include stable machine-readable error codes.
|
|
|
|
|
- `[ ]` Human errors still include next-step recovery hints.
|
|
|
|
|
- `[ ]` Tests assert both code and operator-facing hint for representative
|
|
|
|
|
failures.
|
|
|
|
|
|
|
|
|
|
- `[ ]` Add wait commands for automation.
|
|
|
|
|
Acceptance criteria:
|
|
|
|
|
- `[ ]` `geth wait daemon` can block until local control is ready.
|
|
|
|
|
- `[ ]` `geth wait peer <node>` can block until peer control succeeds or
|
|
|
|
|
times out.
|
|
|
|
|
- `[ ]` `geth wait sync <node>` can block until required streams are healthy
|
|
|
|
|
or stale.
|
|
|
|
|
- `[ ]` Wait commands support JSON output and timeout flags.
|
|
|
|
|
|
|
|
|
|
- `[ ]` Make common commands idempotent.
|
|
|
|
|
Acceptance criteria:
|
|
|
|
|
- `[ ]` Resource creation commands can be safely repeated where practical.
|
|
|
|
|
- `[ ]` Grant creation supports deterministic caller-provided IDs.
|
|
|
|
|
- `[ ]` Repeated sync and import commands report no-op state clearly.
|
|
|
|
|
|
|
|
|
|
- `[ ]` Publish automation examples.
|
|
|
|
|
Acceptance criteria:
|
|
|
|
|
- `[ ]` Docs include shell examples.
|
|
|
|
|
- `[ ]` Docs include Python examples using CLI JSON.
|
|
|
|
|
- `[ ]` Docs include user-service automation examples.
|
|
|
|
|
- `[ ]` Examples avoid private-key copying and privileged service mutation.
|
|
|
|
|
|
|
|
|
|
## Phase 8: Observability And Operations
|
|
|
|
|
|
|
|
|
|
Goal: make production failures diagnosable from the CLI and logs.
|
|
|
|
|
|
|
|
|
|
- `[ ]` Improve structured tracing.
|
|
|
|
|
Acceptance criteria:
|
|
|
|
|
- `[ ]` Logs include fields for command, peer node, resource, capability,
|
|
|
|
|
stream, cursor, and stable error code where applicable.
|
|
|
|
|
- `[ ]` Sensitive bearer tokens and private material are not logged.
|
|
|
|
|
|
2026-07-05 18:14:52 +02:00
|
|
|
- `[x]` Expand health status.
|
2026-07-05 17:21:59 +02:00
|
|
|
Acceptance criteria:
|
2026-07-05 18:14:52 +02:00
|
|
|
- `[x]` `geth status --json` reports daemon uptime.
|
|
|
|
|
- `[x]` Store schema version is visible.
|
|
|
|
|
- `[x]` Native backend health is visible.
|
|
|
|
|
- `[x]` Iroh relay/local-discovery state is visible without exposing
|
2026-07-05 17:21:59 +02:00
|
|
|
unrelated config secrets.
|
|
|
|
|
|
|
|
|
|
- `[ ]` Add `geth doctor`.
|
|
|
|
|
Acceptance criteria:
|
|
|
|
|
- `[ ]` Doctor detects daemon not running.
|
|
|
|
|
- `[ ]` Doctor detects stale local socket.
|
|
|
|
|
- `[ ]` Doctor detects bad config.
|
|
|
|
|
- `[ ]` Doctor detects missing `ssh-keygen`.
|
|
|
|
|
- `[ ]` Doctor explains missing grants and endpoint mismatches when enough
|
|
|
|
|
local metadata exists.
|
|
|
|
|
- `[ ]` Doctor has JSON output for scripts.
|
|
|
|
|
|
|
|
|
|
## Phase 9: Packaging, Upgrade, And Release Discipline
|
|
|
|
|
|
|
|
|
|
Goal: make first deployment the start of a controlled compatibility story.
|
|
|
|
|
|
|
|
|
|
- `[ ]` Harden release artifacts.
|
|
|
|
|
Acceptance criteria:
|
|
|
|
|
- `[ ]` Linux, macOS, and Windows archives are built from tags.
|
|
|
|
|
- `[ ]` Release archives are smoke-tested directly, not only through
|
|
|
|
|
`cargo run`.
|
|
|
|
|
- `[ ]` Archives include relevant docs and license files.
|
|
|
|
|
|
|
|
|
|
- `[ ]` Add upgrade tests.
|
|
|
|
|
Acceptance criteria:
|
|
|
|
|
- `[ ]` Fixture homes from previous tagged pre-releases migrate forward.
|
|
|
|
|
- `[ ]` Upgrade tests include store schema, config, keychain/auth logs, CAS
|
|
|
|
|
metadata, and peer cards.
|
|
|
|
|
- `[ ]` Rollback expectations are documented.
|
|
|
|
|
|
|
|
|
|
- `[ ]` Publish release and support policy.
|
|
|
|
|
Acceptance criteria:
|
|
|
|
|
- `[ ]` Supported platforms are listed.
|
|
|
|
|
- `[ ]` Breaking-change policy is documented.
|
|
|
|
|
- `[ ]` Security update expectations are documented.
|
|
|
|
|
- `[ ]` User-service installation remains user-level only.
|
|
|
|
|
|
|
|
|
|
## Phase 10: Pre-Deployment Dogfood Gate
|
|
|
|
|
|
|
|
|
|
Goal: prove the system works as an actual base layer before broader use.
|
|
|
|
|
|
|
|
|
|
- `[ ]` Complete two-machine dogfood checklist.
|
|
|
|
|
Acceptance criteria:
|
|
|
|
|
- `[ ]` Fresh install works on at least two real machines.
|
|
|
|
|
- `[ ]` Owner init, enrollment, peer exchange, grant, sync status, CAS, KV,
|
|
|
|
|
document, pipe, SSH proxy, and service restart work end to end.
|
|
|
|
|
- `[ ]` Denied remote operations do not mutate serving node state.
|
|
|
|
|
- `[ ]` Backup and restore work.
|
|
|
|
|
- `[ ]` Upgrade from one tagged pre-release to the next works.
|
|
|
|
|
- `[ ]` `geth doctor` gives actionable output for intentionally broken
|
|
|
|
|
setups.
|
|
|
|
|
- `[ ]` Docs match actual commands.
|
|
|
|
|
|
|
|
|
|
## Working Order
|
|
|
|
|
|
2026-07-05 18:11:35 +02:00
|
|
|
1. `[x]` Finish Phase 0.
|
2026-07-05 17:27:42 +02:00
|
|
|
2. `[~]` Refactor `geth-node` into daemon subsystems.
|
2026-07-05 17:21:59 +02:00
|
|
|
3. `[ ]` Add stable contract and golden JSON tests.
|
|
|
|
|
4. `[ ]` Harden store migrations and backup.
|
|
|
|
|
5. `[ ]` Complete security-boundary test coverage.
|
|
|
|
|
6. `[ ]` Replace prototype private CAS cryptography.
|
|
|
|
|
7. `[ ]` Add fault-injection sync tests.
|
|
|
|
|
8. `[ ]` Improve automation commands and JSON errors.
|
|
|
|
|
9. `[ ]` Add operational health, doctor, and release gates.
|