ReserveGrid OS v0.2.0
ReserveGrid OS v0.2.0 — Credibility
Scope
v0.2.0 is a protocol-line release bundling pool-verifier hardening and policy correctness, rg-protocol alignment, and a completed template-manager. Protocol version is treated as an explicit compatibility boundary. No Arc<Mutex> fallback implementation in this release.
Pool verifier hardening and policy correctness
Runtime and filesystem
- Ensure
data/exists before any verdict log load or append (created inmain.rsprior to log operations).
HTTP export endpoints and UX
- Add bounded exports to prevent accidental huge responses:
/verdicts/log?tail=...hard capped at 50,000 lines/verdicts.csv?limit=...hard capped
- Document shell quoting requirements for query params in terminals such as
zsh. - CSV generation hygiene: avoid embedding
\ninside awriteln!format string to prevent double newlines.
Mempool client
- Reuse a single
reqwest::ClientviaOnceLockrather than creating a new client per request. - Centralize timeouts in the client builder and remove redundant per-request timeout code.
- Accept extra JSON fields (e.g.,
timestamp) via#[serde(default)]without breaking parsing. - Fix mempool tiering input: verifier now accepts
tx_countfrom template-manager/mempoolJSON (previously onlycount), preventing silent tier lock to low and restoring correct dynamic fee-tier behavior.
Policy engine correctness
- CoinbaseZero consistency: rejection is optional and relaxed:
- Reject
coinbase_value == 0only for non-empty templates and only whenreject_coinbase_zerois enabled.
- Reject
- Remove mismatch where
main.rsrejected coinbase zero unconditionally even when policy disabled it. - Ensure empty-template rejection runs before CoinbaseZero so the true reason is not masked.
Degraded mode for mempool dependency
- Remove the
unknown_mempool_tierTOML FeeTier idea (awkward deserialization, poor policy UX). - Add
unknown_mempool_as_high: bool(defaulttrue) as the degraded-mode knob. - Tier selection on mempool failure:
- Missing mempool selects High if
unknown_mempool_as_high = true, else Mid - No silent Low-tier fallback
- Missing mempool selects High if
Policy TOML format unification
- Standardize on canonical wrapper: a top-level
[policy]table with flat keys plus[policy.safety]. - Policy loader parses the wrapper consistently and rejects protocol mismatches (
policy.protocol_versionmust equalPROTOCOL_VERSION). - TOML loaders explicitly parse wrapped schemas (
[policy],[manager]) with clearer validation and protocol enforcement.
Init policy wizard
- “0 means unlimited” for
max_tx_count: convert0tou32::MAXso validation passes and semantics match the prompt. - Wizard writes canonical wrapper output (
[policy] ...) by serializing{ policy: cfg }. - Wizard writes to
config/policy.tomland ensuresconfig/exists. - Wizard includes toggles for
unknown_mempool_as_highandreject_coinbase_zero, and retainsreject_empty_templates.
State and logging hygiene
- Replace full
PolicyConfigdebug dumps with a safe concise summary. - Default policy text renders as real TOML, not debug output.
Dependency sanity
- Confirm
reqwestfeatures are correct (json,rustls-tls). - Track cleanup: avoid
tokiofull features and trim to only what is used.
100% traceable rejects and stats determinism
- Every reject yields a stable machine-readable
reason_codeplus humanreason_detail. LoggedVerdictcarriesreason_codeandreason_detail; legacyreasonis set to the stable code when available.- Stats bucketing prefers
reason_code, then falls back toreason, thenok, preventing splintered metrics. - TCP verdict path routes evaluation through a single policy evaluation function, mapping local reasons to rg-protocol wire reasons plus policy context.
Reason-code contract and docs alignment
- Canonical reason codes: standardize
TemplateVerdict.reason_codeto stablesnake_casealigned torg_protocol::VerdictReason; UI and exports preferreason_codeover legacyreason. - Policy UX: tiered floors (
min_avg_fee_lo/mid/hi) are the fee-floor inputs for dynamic tiers; examples/docs were updated accordingly.
rg-protocol alignment
- Protocol version updated for v0.2.0 and treated as an explicit compatibility boundary.
TemplateVerdictincludes stable reason coding and detail fields for operator-grade observability and downstream aggregation.- Evaluation mapping aligns verifier reasons to the wire representation with associated policy context.
Template manager (main.rs completed)
Async template sources
- Introduce async
TemplateSourceviaasync_trait. - Isolate bitcoind RPC calls with
spawn_blockingand use async backoff (tokio::time::sleep).
Stable template identity and dedupe
- Add
TemplateFingerprintbuilt from height, prevhash, tx count, total fees, and an order-independent txid hash. - Derive
template_idfrom the fingerprint via a stable hash, preventing duplicates across restarts and eliminating fake “new templates” from tx reordering.
Coinbase value correctness
- If
getblocktemplatereturnscoinbase_value == 0, template-manager computes a fallback as block subsidy + total fees and logs a warning to avoid downstream CoinbaseZero spam.
Hang prevention and bounded IO
- Add timeouts around verifier connect and the send/receive path.
- Bound writer write, newline write, and flush with timeouts.
- Bound verifier response read to prevent indefinite stalls.
Single instance lock
- Bind HTTP listener before starting the manager loop; if bind fails, exit immediately to prevent duplicate zombie managers.
HTTP observability
- Expose
/health,/templates,/mempool. - In-memory logs guarded by
RwLock, with template log capped at 500 entries.
Shared bitcoind RPC client
- Single shared
Arc<Client>built once and reused for template polling and mempool snapshots.
Stratum mode correctness and latency
- Stratum NDJSON parsing trims lines, skips empties, and logs the offending line on parse errors.
- Real async delivery uses
rx.recv().await. - Manager loop sleeps only on bitcoind backend; Stratum templates are not delayed by
poll_secs.
Dev UX and demo tooling
- Regtest reliability:
dev-regtest.shuses a dedicated datadir, kills only bitcoind instances bound to that datadir, waits for RPC readiness, fails-fast on port conflicts, and uses-namedRPC calls where applicable. - RPC single source of truth:
dev-bitcoin-cli.shis authoritative (includes demo datadir and RPC creds). - Deterministic demo loop:
dev-demo-phases.shadds health gating, balance checks, clearer phase labeling, and optional finite run control. - Traffic generator:
dev-traffic.shuses-named sendtoaddresswith explicitfee_rate, adds spendable balance checks, and exposes tuning knobs. - Stratum hygiene:
dev-stratum.shaligns with v0.2.0 policy env conventions, adds readiness gates, and fails-fast on port conflicts. - Documentation: update
docs/runbook to v0.2.0 (flat[policy]schema, env vars, regtest + Stratum workflows,reason_code/reason_detailsemantics). - Demo note: demo scripts space sends/mining to avoid ancestor-limit failures (
too many unconfirmed ancestors, error-6).
Repo policy files
- Consolidate policy TOMLs to the v0.2.0
[policy]schema and bumpprotocol_versionto match the compatibility boundary. - Refresh demo profiles (showcase/open/strict) to be schema-complete and aligned with updated demo scripts, including explicit
unknown_mempool_as_highandreject_coinbase_zerowhere applicable.