feat(cli): dig-store store-status subcommand (#1349)#30
Conversation
WIP stub: establishes the branch for the `dig-store store-status <store_id>` subcommand consuming dig-store 0.5.0 get_store_status via a small coinset-backed dig_chainsource_interface::ChainSource adapter. Implementation follows.
…_status (#1349) Add `dig-store store-status <store_id> [--json] [--confirmation-target N] [--coinset-url URL]`, reporting a store's aggregate ON-CHAIN status (live/ melted/not-found, confirmations, live root, owner puzzle hash, program hash, head signature, coin id, verified, generations). The CLI is a THIN consumer of the fail-closed `dig_store::get_store_status` (dig-store 0.5.0, NC-9, already triple-gated) — it never re-implements the lineage walk. A small coinset-backed adapter presents digs' existing hardened `digstore_chain::coinset::Coinset` transport as the canonical `dig_chainsource_interface::ChainSource`, implementing only the three reads the aggregator exercises (coin_spend, coin_record, peak_height) and failing closed (Err, never a false absence) on the rest. Store status is a raw Chia-chain read, not a dig-node content read, so it does NOT use the dig-node content ladder; the endpoint resolves as --coinset-url > $DIG_COINSET_URL > the default coinset.org URL, giving the user a first-class custom-endpoint override for this surface. Bumps the workspace 0.17.2 -> 0.18.0 (additive minor: a new subcommand). Tests: adapter transport-mapping + fail-closed (None vs Err) + off-path Unsupported; store-id parsing (hex / 0x / URN); coinset-url resolution; Live/Melted/NotFound rendering + --json shape; and end-to-end NotFound + fail-closed through the library against the canonical MockChainSource.
|
Implementation complete — CI running (HEAD 6aa3a0d). DONE
Local gate GREEN: Post-merge (§3.5): NEXT: watch CI to green; hand to scoped gate (reviewer + light security on the adapter fail-closed mapping + endpoint resolution). Do NOT merge (orchestrator gates). |
|
CI fully GREEN at HEAD 6aa3a0d — all 10 checks pass (build & test ubuntu + windows, Analyze rust/actions/js, CodeQL, commitlint, version-increment, supply-chain audit, dig-client-wasm). Ready for the scoped gate (reviewer + light security on the adapter fail-closed mapping + endpoint resolution). Not marking ready / not merging — orchestrator gates + merges. |
MichaelTaylor3d
left a comment
There was a problem hiding this comment.
Scoped correctness review (fresh context) — VERDICT: PASS
Re-run of the gate leg that died to a session cap. Reviewed the CLI + adapter wiring only; the dig_store::get_store_status lineage logic (NC-9, triple-gated in the library) was NOT re-reviewed, per scope.
Verified
- Option B adapter is a thin transport bridge (
crates/digstore-cli/src/ops/coinset_chain_source.rs):CoinsetChainSource<C: ChainReads>implementsdig_chainsource_interface::ChainSourceby mapping digs' existing hardenedCoinset/ChainReads. Only the 3 methodsget_store_statusexercises are real (coin_record,coin_spend,peak_height); the other 4 fail closed withChainSourceError::Unsupported. No lineage/Live-Melted decision is re-implemented in the CLI/adapter — it composes the library aggregator. - Fail-closed contract preserved: every
ChainReadserror maps toChainSourceError::Transport, never a falseOk(None); unknown coin and unspent-tip both correctly yieldOk(None)(coin_spend.rs:754-774). Well covered by adapter tests + the end-to-endtransport_failure_fails_closed_not_absenttest through the real library +MockChainSource. block_onsafety:digstore_cli::run()(lib.rs:42) is a plain sync entrypoint (no#[tokio::main]), so the adapter's owned current-thread runtime drivingblock_onnever nests inside an ambient runtime. The module doc claim holds.- Subcommand distinct from
status:Command::StoreStatusregistered asstore-status(cli.rs:221), no overload of the working-treestatus; human table renders allStoreStatusfields with-forNone;--jsonemitsStoreStatusdirectly. Dispatch is consistent (early no-workspace return + listed in theunreachable!("handled above")arm). - §5.3 ruling honored: raw Chia-chain read via coinset with
--coinset-url>$DIG_COINSET_URL>digstore_chain::config::DEFAULT_COINSET_URL(store_status.rs:381-391); NOT the dig-node content ladder; no hardcoded coinset URL as the only path. - Deps:
dig-store="0.5"+dig-chainsource-interface="0.1"from crates.io, nogit=. Single chia-sdk tree (chia-protocol 0.26, chia-wallet-sdk 0.30, chia-sdk-driver 0.30 — no dups). - dig-constants check: (1) nothing here belongs in
dig-constants— the coinset default already lives indigstore_chain::config, confirmation-target comes fromdig_store::DEFAULT_CONFIRMATION_TARGET; store-id parsing is local input handling, not a shared value. (2) no hardcoded literal here duplicates adig-constants-published value. Clear. - Tests: 22 new tests (10 adapter + 11 command + 1 cli-parse). All CI green on ubuntu + windows; CodeQL/GHAS/supply-chain/version-increment/commitlint all pass.
- readable-code §2.5: intent-revealing names, WHY-comments, doc-comments on public items, small pure
human_rows/status_label. Nosagerefs. Honors digs' CONTRIBUTING (no Co-Authored-By). - SemVer: 0.17.2 → 0.18.0 minor (additive new capability). Correct.
Non-gating notes (not blockers)
- PR is a draft and the body still reads "WIP / draft — do not merge" though implementation + tests have landed and CI is green. Orchestrator should mark ready-for-review + refresh the body before merge.
head_signaturealwaysNoneis a known library gap (#1348), correctly surfaced as-; out of scope here.
No CHANGES-REQUIRED findings.
Closes #1349.
What
Adds a new
dig-store store-status <store_id> [--json] [--confirmation-target N] [--coinset-url URL]subcommand that reports a store's aggregate on-chain status by composing the NC-9 fail-closeddig_store::get_store_status(dig-store 0.5.0) — a thin consumer, NOT a re-implementation. Distinct from the existing working-treestatuscommand (no overload).Integration approach (Option B, orchestrator-approved)
digs has no
dig_chainsource_interface::ChainSourcetoday (its chain access isdigstore-chain::ChainReads/Coinset+ a separatedigstore-prover::ChainSource). A small coinset-backed adapter wraps digs' existing hardenedCoinset(retry/timeout #84) as adig_chainsource_interface::ChainSource, implementing only the 3 methodsget_store_statusexercises (coin_spend,coin_record,peak_height); the other 4 fail closed withUnsupported. The money-critical lineage walk lives inside dig-store (already triple-gated).§5.3 ruling
store-statusis a raw Chia-chain read, NOT a dig-node content read, so it does NOT use the dig.local/localhost/rpc.dig.net content ladder. It reads via coinset with a user-facing custom-endpoint override:--coinset-url/$DIG_COINSET_URL.Follow-ups (NOT chased here)
head_signatureis alwaysNone(library gap, #1348).Status
WIP / draft — do not merge. Implementation + tests landing next.
Blast radius
gitnexus DISABLED; scoped via ripgrep + read. New subcommand = additive: new
Command::StoreStatusvariant + a new command module + a new adapter module; touchescli.rs(enum + args),commands/mod.rs(dispatch), CLICargo.toml(2 new deps). No existing symbol edited.