AGENTS.md (38336B)
1 # rhi — repository agent contract 2 3 ## 1. Scope and operating model 4 5 - This file applies to the complete repository unless a nearer `AGENTS.md` is 6 stricter. 7 - This repository owns `rhi`, the standalone Radroots evidence-reconciliation 8 and attestation service. Treat canonical event admission, provenance, 9 evidence completeness, outcome meaning, identity, persistence, and 10 publication as security-critical behavior. 11 - Keep the repository independently cloneable, buildable, testable, 12 packageable, and operable. Do not depend on private repositories, unreachable 13 or unlocked artifacts, internal monorepo paths, absolute workstation paths, 14 or private harnesses. An unpublished public dependency is allowed only when 15 its exact commit is reachable from the governed public Git source and pinned 16 by the checked-in source lock. 17 - All `.github/**` and capsule-local `.act/**` workflow definitions are 18 forbidden. Keep validation forge-agnostic, do not depend on a private 19 harness, and leave orchestration exclusively to the parent repository's root 20 `.act/**` authority. 21 - Capsule-local human specs, ADRs, runbooks, test plans, and execution evidence 22 are not owned here; place that authority under the parent repository's 23 `docs/oss/rhi/**`. Standalone machine contracts and ordinary source, test, 24 build, package, and operational assets remain capsule-owned. 25 - Do not add or retain tracked `docs/**`, `.github/**`, or `.act/**` content in 26 this capsule. Keep human documentation under the parent authority above and 27 machine-enforced declarations under governed standalone contract surfaces. 28 - RHI does not own worldwide evidence completeness, trade agreement or 29 settlement authority, relay storage/tenancy, general SDK generation, hosted 30 accounts, telemetry, artifact promotion, or deployment transport. 31 32 ## 2. Authority and preflight 33 34 - Before editing, read this file, `README`, `Cargo.toml`, 35 `radroots.service.source-lock.v2.toml`, and the relevant implementation and 36 tests. The removed prototype root `config.toml` is not configuration 37 authority. 38 - `.radroots-consumer-root` is the standalone source-lock identity and must 39 remain exactly `rhi`. The reserved pre-implementation evidence authority is 40 `contracts/services_hardening/evidence_policy.v1.json`, and the reserved 41 pre-implementation operator authority is 42 `contracts/services_hardening/operator_contract.v1.json`. RHI source and 43 configuration must implement their exact source, selector, cursor, 44 completion, coverage, digest, publication-independence, route, wire-model, 45 identity-role, pagination, mutation, doctor, exit, and TCP semantics; 46 prototype source behavior is not permission to reinterpret them. 47 - Treat checked-in source, tests, configuration, and prototype behavior as 48 implementation evidence, not permission to preserve behavior that the active 49 requirement removes. 50 - Do not invent event kinds or tags, evidence-policy fields, source semantics, 51 protocol behavior, APIs, dependencies, release processes, identity authority, 52 migration behavior, or external integration semantics. 53 - Inspect `git status --short`, the exact repository root, and nearby tests 54 before changing behavior. Preserve unrelated work and stop on an unresolved 55 evidence-integrity, identity, or publication conflict. 56 - Keep changes narrowly scoped and independently reviewable. Do not mix 57 unrelated cleanup, speculative abstractions, roadmap work, or compatibility 58 scaffolding into a checkpoint. 59 - RCLD-RSHR-195 Step 246 advances the active native Lib source lock and freezes 60 RHI state creation behind the runtime-path directory plan plus the sealed 61 service-SQLite initializer. Explicit initialization may provision only the 62 exact governed service-instance suffix after identity and catalog validation; 63 every existing-only open remains non-creating. Do not restore raw paths, raw 64 SQLx connections, filesystem probes, or directory-creation fallbacks at the 65 state-host boundary. 66 67 ## 3. Clean-slate service rule 68 69 - Do not add or preserve prototype configuration readers, `.env` runtime 70 configuration, `RHI_*` runtime selectors, worker paths, JSON/JSONL mutable 71 state, prototype config/state importers or migrations, old-path probes, 72 aliases, fallbacks, dual readers/writers or event decoders, deprecated 73 modules/APIs/re-exports, or old/new feature switches. Offline production 74 schema migration must never accept an unreleased prototype format. 75 - Remove superseded behavior and update every affected Radroots-owned consumer 76 directly. Do not hide a breaking change behind a compatibility adapter unless 77 an accepted public requirement explicitly requires one. 78 - Preserve canonical public Nostr interoperability. Clean-slate product 79 behavior never authorizes wire drift, ad hoc event kinds/tags, or relaxed 80 signature, event-ID, content, or tag validation. 81 - A breaking config, CLI, state, evidence, report, attestation, admin, error, or 82 wire change must update its public machine contracts, examples, tests, 83 generated surfaces, source guards, and release qualification in the same 84 coherent sequence. 85 86 ## 4. Canonical admission and provenance 87 88 - Bound event bytes, content, tags, per-tag and aggregate tag bytes, extras, 89 source results, and authored time before admission. Verify the Nostr event ID 90 and signature, registered kind, author, canonical mutation content and ID, 91 canonical serialization, mandatory structural tag cardinality/content 92 binding, duplicate or conflicting structural tags, and explicit time policy. 93 - Route accepted trade mutations only through the sealed 94 `admit_rhi_trade_mutation_event` boundary. Its wire limits come from the 95 validated configuration, its future-time tolerance is explicit with no 96 default, and it remains pure; persistence belongs only to the separate typed 97 repository transaction introduced by Step 184. 98 - Persist canonical mutation, every distinct signed event carrying it, and 99 every accepted source observation as separate typed facts. Two events for one 100 mutation never overwrite one another, and arrival order never selects truth. 101 - Reject malformed, unsupported, wrong-author, wrong-kind, wrong-ID, wrong-tag, 102 excessive-future, conflicting, or oversized input before it creates accepted 103 evidence, advances a checkpoint/completion, or increments dirty generation. 104 - Make exact event replay idempotent. Repeated source observation preserves the 105 first bounded provenance fact without multiplying authoritative evidence; 106 conflicting content for one mutation ID fails independently of arrival order. 107 - Persist observation and audit time from the injected wall clock using named 108 integer UTC units. Keep event-authored time as distinct untrusted input; never 109 label, persist, or reuse it as source observation time. 110 - Scope checkpoints by stable source plus exact selector/policy. Preserve 111 equal-timestamp discovery through overlap and deduplication; never use one 112 global authored timestamp as the sole cursor. 113 - Increment dirty generation only for relevant newly accepted evidence or a 114 governing policy change. Duplicate provenance, rejection, and operational 115 retry do not dirty a trade. 116 117 ## 5. Evidence reconciliation, coverage, and outcome 118 119 - Persist bounded jobs, attempts, lease ownership/expiry, failure counts, 120 source request/completion/cursor evidence, and next-attempt schedules. Use 121 compare-and-swap claims, bounded concurrency, renewable/reclaimable leases, 122 injected time and jitter, and deterministic crash/reopen recovery. 123 - Record each source result with exact selector digest, required/optional 124 authority, stable request identity, deadline, lookback/cursor, completion 125 evidence, accepted-event count, safe outcome code, and bounded timing. 126 - Derive the bounded canonical per-source request inventory only from an 127 unexpired claimed reconciliation lease and the exact normalized evidence 128 policy. Attempt, selector, and request identities are domain-separated; 129 every deadline is absolute and capped by both configuration and lease 130 expiry; result ingestion consumes at most the configured source count plus 131 one before rejecting missing, duplicate, reordered, or excess evidence. 132 - Query every configured source outside write transactions. A timeout, 133 unsupported adapter, partial result, raw upstream error, or unknown 134 completion never masquerades as success. 135 - Bind every resumed request to its exact prior authored-time/event-ID cursor, 136 subtract the configured overlap for an inclusive query start, canonicalize 137 distinct signed-event identities, retain the earliest injected provenance, 138 and reject conflicting mutation or signed-event identity reuse before the 139 Step 190 commit boundary. 140 - Freeze the exact accepted mutation, signed-event, provenance, and per-source 141 completion inventory in an immutable canonical manifest. Reducers consume a 142 canonically ordered immutable set with explicit policy digest, reducer 143 version, coverage, and observed-time input; they have no database insertion, 144 relay, scheduling, wall-clock, entropy, or network dependency. 145 - Mint the immutable reconciliation manifest only by consuming a sealed, 146 durably confirmed source-commit outcome. Bind each source result to its exact 147 selector, completion, cursor, timing, and persisted-inventory digest, and 148 bind each observation to the exact canonical signed-event and first-source 149 provenance. Do not expose a raw manifest constructor or parser from RHI. 150 - Keep Step 191 manifest materialization pure and in memory. Step 199 alone 151 owns durable manifest persistence; reducers, coverage/outcome, attestation, 152 publication, and job finalization retain their ordered owners. 153 - Reduce only the sealed owned reconciliation manifest. Retain its bounded 154 canonical mutation material privately from the confirmed Step 190 commit, 155 map its already-governed evidence coverage into the shared reducer input, 156 and bind the canonical shared projection digest to the exact manifest and 157 evidence-policy digests. Do not accept caller mutation material or add 158 SQLite, filesystem, source, relay, task, clock, entropy, or network access. 159 - Derive claim-specific coverage and outcome only from that sealed projection. 160 Missing, partial, unsupported, unavailable, ambiguous, unresolved, or absent 161 evidence is `Indeterminate`; evidence absence never becomes `Invalid`. 162 Permit `Valid` only for one clean active agreement claim and `Invalid` only 163 for one clean cancelled claim. Emit only the fixed stable reason vocabulary. 164 - Coverage is exactly `Missing`, `Partial`, `ScopeSatisfied`, or `Unsupported`. 165 ScopeSatisfied means only that the configured policy was satisfied; optional 166 evidence never substitutes for required-source completion. 167 - Outcome is exactly `Valid`, `Invalid`, or `Indeterminate`. Missing, partial, 168 unsupported, unavailable, ambiguous, or unresolved required evidence is 169 Indeterminate; absence never becomes invalidity. 170 - Fence final work by dirty generation and policy digest. A stale worker cannot 171 overwrite newer evidence, and CAS loss leaves no partial report, outbox, 172 source completion, checkpoint, or job finalization. 173 - Carry the exact committed attempt and job identities privately through the 174 sealed manifest, projection, and evaluation chain. A finalization preflight 175 is not commit authority: rerun its exact lease, generation, policy, and 176 attempt validator inside the Step 199 atomic transaction before any write. 177 - Commit a signed finalization only through the sealed attempt repository. 178 Bind publication authority to the same normalized configuration as the open 179 state host, reconcile exact prior success before testing the consumed lease, 180 and write manifest, projection, report, exact signed bytes, explicit 181 supersession, required outbox/targets, and completed job in one short SQLx 182 transaction. Disabled publication must create no outbox, and no source, 183 relay, network, filesystem, task, clock, or entropy operation may occur in 184 this boundary. 185 186 ## 6. Report, attestation, and publication invariants 187 188 - Bind every immutable report to contract ID/version, issuer public key, trade 189 ID, exact claim mutation ID, policy and manifest digests, reducer 190 contract/version, projection digest, outcome and stable reasons, integer UTC 191 observation time, attestation method `signed_evidence_snapshot`, statement 192 digest, and explicit superseded report/event reference when applicable. 193 - Construct the canonical domain-separated statement payload from governed 194 semantic fields only. Exclude self-referential digest, signature, event ID, 195 and derived fields; never invent an encoding, preimage, kind, tag, or query. 196 - Build and sign through typed governed APIs, then revalidate issuer/author, 197 exact unsigned fields, event ID, signature, canonical report binding, and 198 applicable Nostr semantics before persistence or publication. 199 - Construct a signed reconciliation attestation only by consuming the sealed 200 finalization fence and the independently verified encrypted service identity. 201 Accept authored time and exactly 32 bytes of Schnorr auxiliary randomness 202 only through injected authorities. Retain the exact independently verified 203 signed JSON bytes and their SHA-256; never rebuild, reserialize, or re-sign 204 them after the boundary succeeds. 205 - Accept an attestation supersession input only when it is derived from a prior 206 sealed verified RHI attestation, and rerun the shared report/event binding and 207 ordering validator before exposing the successor. This pure signing boundary 208 has no SQLite, filesystem, relay, network, task, or publication authority. 209 - One generation-fenced transaction commits attempt/source results, immutable 210 manifest/projection/report, supersession, exact serialized signed event 211 bytes/digest, immutable target set and initial outbox when required, accepted 212 source completion/checkpoints, and job finalization before relay I/O. 213 - Publication is explicitly `required` or `disabled`. Retry and recovery submit 214 only the committed exact bytes; never deserialize, rebuild, reserialize, 215 re-sign, or change targets. 216 - Distinguish pending, submitted, accepted, rejected, rate-limited, 217 auth-required, failed, and unknown target evidence. Submission or lost 218 acknowledgement never proves delivery or failure. 219 - Keep profile and application-handler presence as deterministic durable desired 220 state with the same commit-before-I/O and exact-byte retry discipline. 221 - Derive presence desired state only from one complete admitted configuration, 222 bind it to the latest durable configuration before mutation, and advance its 223 singleton generation only when the semantic presence authority changes. 224 Durable desired state contains only the closed mode, document-presence bits, 225 bounded target counts, queue capacity, and governed digests; it never stores 226 relay URLs, rendered or signed events, attempts, schedules, or outcomes. 227 - Build service-profile and application-handler presence only through the 228 governed typed Lib plans, then independently revalidate exact ID, signature, 229 author, kind, authored time, ordered tags, and content before persistence. 230 Commit each verified signed byte sequence and the complete immutable target 231 inventory before an injected presence sink can observe it. Preserve the 232 caller's sealed exact-byte capability across an unknown commit result so 233 reconciliation never depends on re-signing. 234 - Persist presence `submitted` in a short SQLx-owned transaction before relay 235 I/O, keep the remote await outside every transaction, and atomically append 236 the closed attempt outcome with target scheduling, outbox disposition, and 237 lease release. Cancellation or lost acknowledgement becomes durable 238 `unknown` before retry of the same retained bytes. Recover an expired stale 239 desired generation to `unknown` and supersede it without retry entropy so it 240 cannot block the current generation indefinitely. Never reconstruct exact 241 committed presence bytes or persist raw relay diagnostics. 242 243 ## 7. Configuration, identity, state, and process boundaries 244 245 - Load exactly one immutable TOML document with 246 `schema = "radroots.rhi.config"` and `schema_version = 1`. Reject unknown 247 fields at every object boundary, implicit relays/sources, 248 complete-by-default evidence, unsafe defaults, environment overlays, 249 includes, interpolation, fragments, stdin configuration for `run`, hot 250 reload, and arbitrary leaf flags. 251 - Parse bootstrap profile, instance, repo-local root, and an optional absolute 252 config path once as CLI authority; they are not TOML fields. Human output is 253 the default and governed machine output is explicit. 254 - Keep every real source explicit with a stable ID, required/optional status, 255 exact selector, deadline, lookback, overlap/cursor and failure/completion 256 policy, and relationship to publication. Bind the complete normalized 257 authority in the evidence-policy digest. Add an adapter only for a real, 258 qualified evidence source; do not invent a generic source mode. 259 - Give relays and sources unique stable IDs, canonical URLs, and explicit 260 read/write/required authority as applicable. Production public connections 261 enforce secure transport, every-answer network policy, and preserved TLS 262 SNI/certificate identity; plaintext loopback is simulator-only and is never 263 selected implicitly. 264 - Keep parsing and semantic validation pure: no path creation, identity or 265 credential access, SQLite, DNS, network, clocks, entropy, logging setup, 266 process mutation, or panic. 267 - Identity uses only the governed encrypted envelope and separately named 268 wrapping credential. Do not add plaintext or adjacent keys, implicit identity, 269 or ordinary-run generation/replacement. Validate expected public-key and 270 policy bindings before readiness. 271 - Resolve the wrapping credential only from the validated fixed artifact name 272 beneath the same instance's canonical secrets root. The resolver is 273 read-existing-only, accepts no caller path or bytes, and supports only 274 service-host and repo-local profiles. The governed envelope and credential 275 are excluded from state backups. 276 - Do not read, reseal, import, or migrate prototype or legacy identity-envelope 277 formats. Missing, wrong, legacy, or misbound envelopes and wrapping 278 credentials fail closed. 279 - Each instance owns one explicitly initialized `state.sqlite`, retained 280 `state.lock`, exclusive instance lock, and one live writer authority. Normal 281 `run` opens existing state only and verifies service, instance, source 282 generation, schema/migration checksums, identity, and policy metadata before 283 readiness. Raw pools, connections, or cloneable write authority never escape 284 typed RHI repositories; live clients mutate only through the Unix admin 285 boundary and offline state operations must prove that no daemon writer exists. 286 - Create-new state begins at the shared schema-v1 baseline and applies the 287 governed RHI schema-v2 configuration-binding migration, schema-v3 288 immutable trade-evidence migration, schema-v4 source-checkpoint and 289 dirty-generation migration, schema-v5 bounded reconciliation-job migration, 290 schema-v6 immutable reconciliation-attempt/source-result migration, and 291 schema-v7 immutable manifest, projection, report, exact signed-event, and 292 publication-workflow migration. 293 Retain at most 1,024 consecutive 294 immutable configuration generations containing only normalized 295 config/evidence-policy digests, public identity, exact contract versions, 296 injected apply time, and bounded build identity. Persist each canonical 297 mutation, independently signed Nostr event, and accepted configured-source 298 observation as distinct immutable facts in one SQLx transaction. Exact replay 299 is idempotent, conflicts fail closed, observation time remains distinct from 300 authored time, and this persistence step must not advance reconciliation 301 checkpoints or dirty generation. The composed relay-source ingest path may 302 advance only its exact scoped checkpoint after complete EOSE evidence and 303 may dirty a trade only for newly inserted mutation or signed-event evidence; 304 replayed source observation alone does neither. Never persist raw TOML, 305 paths, URLs, credential references, or protected identity material. Ordinary startup must 306 use intent-open, discover source generation under retained authority, and 307 match the latest durable binding; configuration apply is an exclusive offline 308 operation. 309 - Derive publication authority only from one complete validated configuration. 310 Required mode preserves the exact ordered write-relay target inventory, 311 requiredness, retry bounds, queue capacity, and domain-separated identities; 312 disabled mode has no target, retry, network, or hidden fallback authority. 313 Keep manifest, projection, report, signed-event bytes, and attempt rows 314 immutable, and expose outbox/target progress only through versioned 315 compare-and-swap state. Step 198 defines this catalog and performs no SQLite 316 mutation or relay I/O; later publication steps must use only the committed 317 exact signed bytes and may never rebuild, reserialize, or re-sign them. 318 Read retry/recovery payloads only through the sealed committed-publication 319 capability joined from the immutable outbox and signed-event rows. Recheck 320 the bounded stored-byte digest on every read, including after reopen. The 321 capability is not claim authority; later relay execution must borrow its 322 exact byte slice without parsing or reconstruction. 323 - Model publication target and attempt evidence only with the closed pending, 324 submitted, accepted, rejected, rate-limited, auth-required, failed, and 325 unknown vocabulary. Attempt evidence must derive its identity from the 326 sealed committed outbox and exact event digest plus bounded target ordinal 327 and attempt number; never accept caller-supplied identities, arbitrary result 328 codes, raw relay diagnostics, reversed timestamps, or implicit clock reads. 329 The model is not claim, transition, or relay authority. The durable executor 330 must revalidate every live target, lease, revision, attempt, and byte binding. 331 - Execute publication only through the dedicated exact-byte sink. Persist 332 Submitted before remote I/O, never hold a SQLx write transaction across that 333 I/O, and never parse, rebuild, reserialize, or re-sign the committed payload. 334 Append the closed attempt evidence and compare-and-swap target schedule, 335 outbox disposition, and lease release together. Cancellation or lost 336 acknowledgement after Submitted is Unknown until independent evidence; 337 expired-lease recovery must retain that evidence before bounded injected- 338 jitter retry. Never persist raw relay diagnostics or blindly repeat an 339 unknown local commit. 340 - Commit one exact reconciliation-attempt replay inventory only through the 341 typed attempt repository. Revalidate the exact live lease, dirty generation, 342 evidence policy, and every scoped prior checkpoint before mutation; persist 343 evidence, immutable results, the exact ordered fact/provenance inventory 344 digest, at most one dirty advance, and eligible checkpoints atomically. 345 Incomplete or unsupported results never advance, and committed cursor 346 evidence is minted only after durable commit confirmation. 347 - Never hold a database transaction while waiting for a source, relay, DNS, 348 identity provider, clock, entropy, signing, reduction, or backoff. 349 - Never prune active jobs/outboxes, migration history, current identity/policy 350 bindings, evidence required to reproduce a current attestation, immutable 351 report/supersession history, or exact signed bytes required for retry/audit. 352 Any allowed compaction must be explicit, transactional, bounded, and 353 verifiability-preserving. 354 - Parse the process CLI and initialize the tracing subscriber only in the binary 355 composition boundary. Libraries may emit tracing events but must not install 356 signal handlers, create Tokio runtimes, call `process::exit`, spawn arbitrary 357 executables, or detach authoritative tasks. 358 - Inject wall time, monotonic time, entropy, transport, identity providers, 359 evidence sources, and failpoints. Supervise and join every authoritative task; 360 panic, error, or unexpected successful return from a critical task must 361 coordinate shutdown and produce a nonzero process result. 362 - Compose those dependencies only through the sealed runtime-adapter boundary. 363 Wall UTC and process-local monotonic observations remain distinct; jitter is 364 bounded whole-millisecond full jitter derived only from injected entropy. 365 The transport-neutral `radroots_transport` source, subscription, and sink 366 traits are the sole generic event I/O SPI. Credential access must precede 367 independently verified encrypted-identity access, with no fallback or 368 generation. The adapter set owns one private shared `TaskSupervisor` and 369 exposes no task handle or concrete transport handle. 370 - The existing-state runtime foundation must verify durable configuration 371 before credential/identity access and must contact no event source, 372 subscriber, or publication sink. Its passive initial readiness may prove 373 only existing state, durable configuration, and verified identity. Recovery, 374 connectivity, listeners, presence desired state, signals, logging, and the 375 final supervised graph remain with their later owning checkpoints. 376 - Library code must not install signals, create a runtime, install logging, 377 call process exit, or detach an authoritative task. Those process authorities 378 remain exclusively with the final binary checkpoint. 379 - On startup, reclaim expired reconciliation/publication leases, resume durable 380 retry schedules with injected bounded jitter, retain unknown submissions, 381 finalize already-proven outcomes idempotently, and scan all authoritative 382 relationships. Impossible, corrupt, misbound, orphaned, newer-schema, or 383 checksum-invalid state fails closed or enters an explicitly safe 384 repair-required state; it is never silently deleted or guessed. 385 - The first termination signal begins bounded graceful shutdown and preserves 386 durable claims and exact publication state; a second signal forces 387 termination. Critical-task and shutdown failures remain nonzero. 388 389 ## 8. Admin, observability, recovery, and secret boundaries 390 391 - Parse the CLI once and dispatch only pure/offline bootstrap, a live Unix admin 392 client, or the daemon. Config validation/schema and pre-service initialization 393 are offline. State init/restore/verify/migrate and initial identity 394 provisioning require proof that no writer lock exists. 395 - Detailed status, redacted effective config, online backup, identity status 396 and public export, reconciliation/job/source status, bounded trade/report 397 queries, publication/target retry or refresh, metrics snapshot, and presence 398 status/refresh use bounded, versioned HTTP/JSON over a permissioned Unix 399 socket while live. Do not add TCP admin, browser auth, CORS, direct writable 400 CLI fallback, or live direct-SQLite mutation. 401 - Enforce peer credentials only to the strength qualified for the platform; 402 keep Linux Tier-1 and filesystem-permission behavior explicit. 403 - Bind every mutation to stable operation/correlation identity, idempotent 404 replay, conflicting-reuse rejection, typed bounded responses, and explicit 405 safe confirmation for destructive or identity-sensitive work. Never unlink 406 a live socket owner; remove only a proven stale socket under the resolved 407 instance runtime directory. 408 - Keep the public RHI route and document vocabulary closed against the exact 409 operator contract. Step 206 owns the seven common routes and Step 207 owns 410 the thirteen domain routes. Step 208 removes the stale, never-registered live 411 identity rekey/replace vocabulary, and Step 209 alone may claim the complete 412 20-route/33-model surface. Never expose the shared raw router, listener, JSON 413 handler, or a caller-selected socket path. 414 - Through Step 209, the active and final route sets are exactly seven common 415 plus thirteen domain routes. The Step 209 wave contract freezes the complete 416 original-wire, version, pagination, idempotency, peer, removed-route, and 417 resource negative matrices against the exact Lib source lock. Pagination is 418 bounded to 200 items, query fields are closed, authenticated cursors remain 419 bound by the handler to route/filter/snapshot, and decoded trade parameters 420 use the exact lowercase-hex trade-ID type. Identity rotation remains offline 421 create-new plus validated configuration apply and restart; Unix peer 422 admission grants no direct SQLite or identity-provider mutation authority. 423 - Step 210 freezes the one-parse CLI execution split. Every admitted command 424 selects exactly daemon, offline, or permissioned Unix-admin authority. All 425 twenty live commands map one-to-one to the final twenty-route inventory and 426 carry no offline or direct-SQLite fallback. Config initialization, 427 validation, schema, and apply; exclusive state maintenance; initial identity 428 provisioning; and doctor remain offline. Do not reparse process arguments or 429 let a live CLI plan obtain SQLite, identity-provider, source, relay, task, 430 signal, or runtime authority. 431 - Optional TCP operations expose only cached `/livez`, `/readyz`, and 432 `/metrics`; requests must not perform SQLite, source, relay, DNS, identity, 433 evidence, or credential probes. 434 - Step 212 owns the one-latest passive lifecycle/status cache and the optional 435 TCP adapter. Detailed status remains permissioned Unix-admin-only. The TCP 436 surface is exactly cached `/livez`, `/readyz`, and `/metrics`, with two fixed 437 RHI metric families and no route-registration extension, active probe, or 438 high-cardinality label authority. 439 - Keep logs as safe structured stderr output. Keep result data on stdout and 440 diagnostics on stderr. Use stable bounded public codes/messages, bounded 441 metric labels, explicit redaction, and no trade/mutation/event/report IDs or 442 arbitrary upstream text as labels. 443 - Doctor uses bounded active checks with per-check deadlines, safe structured 444 required/optional results, and a nonzero result for required failure or 445 timeout. It covers paths/permissions, writer lock, schema/integrity/free disk, 446 identity/credential, bind/network policy, required source reachability, 447 checkpoint plausibility, leases/backlog, publication invariants, and clock 448 skew without leaking protected details. 449 - Step 211 freezes the exact fifteen-check doctor inventory, its ordered 450 per-check deadlines and safe remediation codes, the `pass`, `degraded`, and 451 `fail` aggregate meanings, and process exit codes zero through six. A required 452 skipped result is failure; required failure or timeout is exit six; optional 453 non-pass is degraded success. Dropping a timed-out probe future must stop its 454 work or leave cleanup owned synchronously by that future, with no detached 455 probe task. Keep paths, raw errors, arbitrary summaries, and protected values 456 out of the bounded canonical report and process diagnostics. 457 - Step 214 freezes the failure-resilience qualification corpus across bounded 458 resources and backlogs, durable state and disk posture, corruption and 459 malformed history, cancellation and outage recovery, and safe errors. Keep 460 every named component vector executable and bind shared durability evidence 461 to the exact retained Lib source lock. Do not add a second SQLite authority, 462 a production failpoint surface, or a test environment selector. Step 215 463 alone owns actual-process and bounded-soak qualification; Steps 216 and 217 464 own native release evidence and promotion respectively. 465 - Step 215 closes wave `130-c` with the actual RHI executable. Keep the process 466 corpus loopback-only, deadline- and output-bounded, and free of production 467 failpoints or environment-selected test behavior. Every daemon must be 468 interrupted, joined, and reaped; every admin socket must be absent after 469 shutdown; and the durable state must verify after every one of the exact 470 bounded reopen-soak iterations. Step 216 owns native release artifacts, and 471 Step 217 alone owns promotion and parent-pin alignment. 472 - Keep plaintext keys, decrypted identity, wrapping credentials, tokens, raw 473 sensitive evidence, private identifiers, paths, upstream errors, and 474 equivalent protected material out of config, logs, status, metrics, audit, 475 fixtures, packages, process arguments, environment contracts, error strings, 476 and backups. Governed state backups contain neither the encrypted identity 477 envelope nor any material needed to unwrap it. 478 - Backup and restore must preserve writer-lock, manifest, digest, integrity, 479 schema, service, instance, identity, policy, permission, fsync, atomic-rename, 480 and protected-material-exclusion invariants. Orphaned or impossible state 481 fails closed or enters an explicitly safe repair-required state; never delete 482 or guess it silently. 483 484 ## 9. Rust and test discipline 485 486 - The final Rust baseline is edition 2024, resolver 3, and Rust/toolchain 487 1.97.1. Keep `Cargo.toml`, `rust-toolchain.toml`, and Cargo metadata in exact 488 agreement. 489 - Keep `#![forbid(unsafe_code)]` at crate roots; unsafe code is forbidden. Deny 490 broken rustdoc links, `dbg!`, `todo!`, and `unimplemented!` in production. 491 - Prefer pure transformations, explicit state machines, validated newtypes, 492 tagged serialized enums, narrow side-effect boundaries, and private or 493 `pub(crate)` visibility. 494 - Keep every implementation module private and expose intended library names 495 only through the curated crate root. Regenerate and byte-compare 496 `contracts/api_baselines/rhi.txt` whenever that public surface changes. 497 - Public errors must use RHI-owned stable classifications with redacted 498 Display and Debug output and no raw dependency-owned source chain. 499 - Use `thiserror` for library/domain errors and `anyhow` only at binary, xtask, 500 or one-shot composition boundaries. Avoid production `unwrap`/`expect` and 501 environment-dependent `Default`; ordinary `Debug` must never expose secrets. 502 - Add deterministic positive, negative, exact-boundary, just-over, permutation, 503 concurrency, crash/retry, cancellation, saturation, redaction, and public-wire 504 interoperability tests for every behavior change. Tests must not depend on 505 ambient network or machine-specific state and must contain no real secrets, 506 realistic private keys, or sensitive evidence. 507 - Bound every input, adapter result, queue, pool, worker, lease, retry, query, 508 response, deadline, backlog, retention set, and in-memory collection. 509 - Treat generated files as generated. Update them through the owning command 510 and run the corresponding freshness check. 511 - Keep the native release generator private to `tools/xtask`. It may read 512 only an exact clean committed capsule revision and must write only one 513 caller-selected external output directory using the closed inventory in 514 `contracts/services_hardening/native_release.v1.json`. It must retain 515 bounded streaming I/O, deterministic archives, exact mode and durability 516 checks, protected-material scanning, and stable path-free errors. 517 - Standalone package material may include the fixed systemd instance unit, 518 config example/schema, native binary/source archives, SBOM, notices, 519 provenance input, source lock, checksums, and manifest. It must not include 520 parent-owned human docs, credentials, Nix or OCI inputs/outputs, private 521 harnesses, signatures, tags, publication, deployment, or generated artifacts 522 in the source tree. 523 - RCLD-RSHR-150 Step 227 owns the fixed standalone systemd unit and 524 `systemd_qualification.v1.json`. Keep the canonical service-host directory 525 directives, stable exit-code restart split, bounded stop, empty capability 526 sets, no environment-carried credentials, systemd 252 minimum, and maximum 527 offline exposure 3.0 exact. The Linux verifier must fail closed when 528 `systemd-analyze` is absent. Do not enable compatibility-sensitive 529 `MemoryDenyWriteExecute` or syscall filters until the Step 229 integration 530 wave proves them against the real binary; do not install, enable, start, or 531 deploy a production service here. 532 533 ## 10. Canonical verification 534 535 Through RCLD-RSHR-170, run the standalone native command authority through 536 extbuild. Do not install, repair, invoke, or require Nix, and do not claim Nix, 537 NixOS-module, or Nix-produced OCI qualification: 538 539 ```text 540 cargo extbuild doctor 541 cargo extbuild run -- cargo fmt --all --check 542 cargo extbuild run -- cargo check --workspace --all-targets --locked 543 cargo extbuild run -- cargo test --workspace --all-targets --locked 544 cargo extbuild run -- cargo clippy --workspace --all-targets --locked -- -D warnings 545 cargo extbuild run -- env RUSTDOCFLAGS=-Dwarnings cargo doc --workspace --no-deps --locked 546 cargo extbuild run -- ./scripts/verify-boundaries.sh 547 cargo extbuild run -- ./scripts/verify-supply-chain.sh 548 cargo extbuild run -- ./scripts/verify-systemd.sh 549 cargo extbuild run -- ./scripts/release-acceptance.sh 550 ``` 551 552 The supply-chain gate requires exact cargo-deny 0.19.8 and cargo-vet 0.10.2, 553 the checked-in exemption inventory, the locked graph, approved licenses and 554 sources, and only the explicitly justified Nostr 0.44 advisories. Exemptions 555 are visible accepted review debt, not claims of independent source audits. 556 The complete release contract also requires locked all-target check and test 557 with serialized tests, warnings-denied all-target Clippy, warnings-denied 558 rustdoc, the source-lock and package-boundary tests, and diff hygiene. Run 559 additional coverage, SQLx freshness, source-lock, package, systemd, SBOM, 560 checksum, notice, and fresh-install gates when their surfaces change. Nix and 561 OCI remain deferred and unclaimed through RCLD-RSHR-170. Use narrower commands 562 only for iteration, and never claim a command passed unless it ran 563 successfully. 564 565 ## 11. Commits and irreversible actions 566 567 - Format commits as `<scope>: <imperative summary>`, with a blank line and 568 `- ` bullets when a body is useful. Split unrelated changes. 569 - Report the exact files changed, behavior changed, commands run, results, 570 unresolved risks, and whether the next checkpoint is safe. 571 - Do not publish, push, tag, sign, deploy, rotate credentials, change ownership, 572 or mutate external runtime state without explicit authorization for that exact 573 action.