Skip to content

feat(dig-runtime): wallet-only start + native read-crypto FFI - #4

Merged
MichaelTaylor3d merged 1 commit into
mainfrom
feat/dig-runtime-wallet-only-and-read-crypto-ffi
Jul 5, 2026
Merged

feat(dig-runtime): wallet-only start + native read-crypto FFI#4
MichaelTaylor3d merged 1 commit into
mainfrom
feat/dig-runtime-wallet-only-and-read-crypto-ffi

Conversation

@MichaelTaylor3d

Copy link
Copy Markdown
Contributor

TLDR

Adds two additive C-ABI surfaces to the dig-runtime cdylib so the DIG Browser can (a) start the runtime wallet-only — no in-process node engine — and (b) verify+decrypt .dig content by calling the digstore Rust read-crypto DIRECTLY via FFI, NOT wasm (wasm is webpages-only — @MT-Dev's ruling on super #44). Implements super-repo #47 and the Rust side of #44 item 2. All existing exports unchanged.

What changed (crates/dig-runtime/src/lib.rs)

  • dig_runtime_start_wallet() — wallet-only start (feat: adopt dig-logging for real retrievable node logs (#553) #47). Brings up the wallet host + tokio runtime with NO node engine (no P2P / cache / dig_rpc dispatch). The existing full dig_runtime_start() is unchanged; the FIRST dig_runtime_start* call fixes the mode (OnceLock). In wallet-only mode dig_rpc returns a well-formed JSON-RPC error (code -32000, "node engine not available: dig-runtime started wallet-only") rather than spinning up a node.
  • dig_read_verify_decrypt() / dig_bytes_free() — native read-crypto FFI (chore(release): version hygiene — one canonical version field + drop legacy dig-companion assets #44 item 2). Exports the digstore-core.dig verify+decrypt as C-ABI — the SAME Rust the webpage dig-client-wasm wraps (ONE impl, two bindings). Verifies the served ciphertext's Merkle inclusion against the chain-anchored root, THEN AES-256-GCM-SIV decrypts, fail-closed (DIG_READ_OK/BAD_INPUT/VERIFY_FAILED/DECRYPT_FAILED/INTERNAL). Needs no runtime and no node engine — pure crypto over bytes the caller already fetched from an external node (§5.3). Byte-parity with the wasm's decryptResource (same canonical_resource_urn + derive_decryption_key + inclusion-proof core).

digstore-core is pinned to the same rev (bcb84a6…) dig-node-core/dig-wallet use, so cargo unifies to one crypto impl.

FFI contract (for the dig-browser C++ loader)

// wallet-only start (browser calls this at startup instead of dig_runtime_start)voiddig_runtime_start_wallet(void);
// read-crypto: verify Merkle inclusion vs the chain-anchored root, then decrypt. fail-closed.int32_tdig_read_verify_decrypt(
constchar*store_id_hex, // 64-hex (required)constchar*resource_key, // resource path; "" => index.html (required)constuint8_t*ciphertext, size_tciphertext_len, // plain concat of chunk ciphertextsconstchar*proof_b64, // base64 X-Dig-Inclusion-Proof (required)constchar*trusted_root_hex, // 64-hex chain-anchored root (required)constchar*salt_hex, // 64-hex private-store salt, or NULL/"" for publicconstuint32_t*chunk_lens, size_tchunk_lens_len, // per-chunk ct byte lens; NULL/0 => singleuint8_t**out_ptr, size_t*out_len); // heap plaintext; free w/ dig_bytes_freevoiddig_bytes_free(uint8_t*ptr, size_tlen);
// status: 0 OK, 1 BAD_INPUT, 2 VERIFY_FAILED, 3 DECRYPT_FAILED, 4 INTERNAL

Tests (TDD) — 14 pass

Verification (this session)

  • cargo test -p dig-runtime14 passed, 0 failed.
  • cargo clippy -p dig-runtime --all-targets -- -D warningsclean (fixed a cast_slice_from_raw_parts lint in dig_bytes_free).
  • cargo fmt --all -- --checkclean.

Blast radius

dig-runtime is a leaf cdylib — nothing in the workspace depends on it (it is the browser's DLL). All changes are additive: new exports + an internal with_node split of the runtime constructor; existing dig_rpc/dig_wallet_rpc/dig_free semantics preserved. Consumer is the dig-browser C++ loader (super #44 Part B), migrated separately.

Docs

  • SPEC.md §15 reworked (two start modes + the three FFI surfaces), new §15.1 (read-crypto FFI: signatures, inputs, status codes, buffer ownership), §1.3 corrected (browser starts wallet-only), conformance-index row 15 updated.
  • SYSTEM.md (superproject) note: line ~123 ("exactly ONE read-crypto implementation (the shared wasm)") should be updated by the orchestrator to "one Rust impl, two bindings (native FFI for the browser, wasm for webpages)" — out of this repo's scope.

Version

dig-runtime 0.1.0 → 0.2.0 (minor — additive feat, no breaking change to existing exports).

Refs super-repo #44, #47.

Add two additive C-ABI surfaces to the dig-runtime cdylib so the DIG
Browser can drop its in-process node (super #44) and verify+decrypt .dig
content by calling the digstore Rust read-crypto DIRECTLY, not through
wasm (wasm is webpages-only — @MT-Dev ruling on #44).
- dig_runtime_start_wallet(): wallet-only start — brings up the wallet
host + tokio runtime with NO node engine (no P2P / cache / dig_rpc
dispatch). The existing full dig_runtime_start() is unchanged; the
first dig_runtime_start* call fixes the mode (OnceLock). In wallet-only
mode dig_rpc returns a well-formed JSON-RPC "node engine not available"
error rather than spinning up a node. (super #47)
- dig_read_verify_decrypt() / dig_bytes_free(): the digstore-core .dig
verify+decrypt exported as C-ABI — the SAME Rust the webpage
dig-client-wasm wraps (ONE impl, two bindings: native FFI for the
browser, wasm for webpages). Verifies the served ciphertext's Merkle
inclusion against the chain-anchored root, then AES-256-GCM-SIV
decrypts, fail-closed (DIG_READ_* status codes). Needs no runtime and
no node engine — pure crypto over bytes fetched from an external node.
digstore-core is pinned to the same rev dig-node-core/dig-wallet use so
cargo unifies to one crypto impl. SPEC.md §15/§15.1 + the conformance
index updated. Version 0.1.0 -> 0.2.0 (additive; minor).
@MichaelTaylor3d
MichaelTaylor3d merged commit ded2609 into mainJul 5, 2026
9 checks passed
@MichaelTaylor3d
MichaelTaylor3d deleted the feat/dig-runtime-wallet-only-and-read-crypto-ffi branch July 5, 2026 01:47
MichaelTaylor3d added a commit that referenced this pull request Jul 10, 2026
Add two additive C-ABI surfaces to the dig-runtime cdylib so the DIG
Browser can drop its in-process node (super #44) and verify+decrypt .dig
content by calling the digstore Rust read-crypto DIRECTLY, not through
wasm (wasm is webpages-only — @MT-Dev ruling on #44).
- dig_runtime_start_wallet(): wallet-only start — brings up the wallet
host + tokio runtime with NO node engine (no P2P / cache / dig_rpc
dispatch). The existing full dig_runtime_start() is unchanged; the
first dig_runtime_start* call fixes the mode (OnceLock). In wallet-only
mode dig_rpc returns a well-formed JSON-RPC "node engine not available"
error rather than spinning up a node. (super #47)
- dig_read_verify_decrypt() / dig_bytes_free(): the digstore-core .dig
verify+decrypt exported as C-ABI — the SAME Rust the webpage
dig-client-wasm wraps (ONE impl, two bindings: native FFI for the
browser, wasm for webpages). Verifies the served ciphertext's Merkle
inclusion against the chain-anchored root, then AES-256-GCM-SIV
decrypts, fail-closed (DIG_READ_* status codes). Needs no runtime and
no node engine — pure crypto over bytes fetched from an external node.
digstore-core is pinned to the same rev dig-node-core/dig-wallet use so
cargo unifies to one crypto impl. SPEC.md §15/§15.1 + the conformance
index updated. Version 0.1.0 -> 0.2.0 (additive; minor).
Co-Authored-By: Claude <noreply@anthropic.com>
MichaelTaylor3d added a commit that referenced this pull request Jul 10, 2026
Add two additive C-ABI surfaces to the dig-runtime cdylib so the DIG
Browser can drop its in-process node (super #44) and verify+decrypt .dig
content by calling the digstore Rust read-crypto DIRECTLY, not through
wasm (wasm is webpages-only — @MT-Dev ruling on #44).
- dig_runtime_start_wallet(): wallet-only start — brings up the wallet
host + tokio runtime with NO node engine (no P2P / cache / dig_rpc
dispatch). The existing full dig_runtime_start() is unchanged; the
first dig_runtime_start* call fixes the mode (OnceLock). In wallet-only
mode dig_rpc returns a well-formed JSON-RPC "node engine not available"
error rather than spinning up a node. (super #47)
- dig_read_verify_decrypt() / dig_bytes_free(): the digstore-core .dig
verify+decrypt exported as C-ABI — the SAME Rust the webpage
dig-client-wasm wraps (ONE impl, two bindings: native FFI for the
browser, wasm for webpages). Verifies the served ciphertext's Merkle
inclusion against the chain-anchored root, then AES-256-GCM-SIV
decrypts, fail-closed (DIG_READ_* status codes). Needs no runtime and
no node engine — pure crypto over bytes fetched from an external node.
digstore-core is pinned to the same rev dig-node-core/dig-wallet use so
cargo unifies to one crypto impl. SPEC.md §15/§15.1 + the conformance
index updated. Version 0.1.0 -> 0.2.0 (additive; minor).
Co-Authored-By: Claude <noreply@anthropic.com>
MichaelTaylor3d added a commit that referenced this pull request Aug 2, 2026
Piece #3 (receiver) + #4 (holder) of store-melt propagation, over
spy-testable seams (MeltChain/MeltCache/MeltBroadcast) with the
fail-closed NC-9 gate: only a held, on-chain-confirmed melt deletes;
Err/Unknown never deletes; held-check precedes any chain read; the
TombstoneSet CAS bounds each node to one rebroadcast so the epidemic
terminates. All 8 adversarial tests green.
Refs #1316
Co-Authored-By: Claude <noreply@anthropic.com>
MichaelTaylor3d pushed a commit that referenced this pull request Aug 2, 2026
…tion (#1987)
Produce the tier-0 precache CANDIDATE SET (epic #1934, child 2/7): random
keyspace sampling picks which neighbourhoods to probe, and a pure multi-peer
reconciliation admits a content key only on an M-of-N distinct-peer quorum,
deriving each key's provider count from the lower median (never a liar's
inflated max). Feeds relevance()'s RelevanceInputs; does not score, select,
or fetch (children #1/#3/#4).
- reconcile(): per-peer dedup then quorum + median aggregate (pure, no I/O)
- sample_keyspace_points(): deterministic under an injected SplitMix64 RNG
- sample_candidates(): async composition over a NeighbourhoodProbe seam
- SPEC.md §7.10c documents the sampling + quorum contract (normative)
Bumps dig-node-core 0.28.0 -> 0.29.0 and workspace 0.77.0 -> 0.78.0 (MINOR).
Co-Authored-By: Claude <noreply@anthropic.com>
MichaelTaylor3d added a commit that referenced this pull request Aug 2, 2026
…tion (#153)
* feat(dig-node): scaffold DHT candidate sampling (#1987)
Co-Authored-By: Claude <noreply@anthropic.com>
* feat(dig-node): DHT candidate sampling + anti-Sybil quorum reconciliation (#1987)
Produce the tier-0 precache CANDIDATE SET (epic #1934, child 2/7): random
keyspace sampling picks which neighbourhoods to probe, and a pure multi-peer
reconciliation admits a content key only on an M-of-N distinct-peer quorum,
deriving each key's provider count from the lower median (never a liar's
inflated max). Feeds relevance()'s RelevanceInputs; does not score, select,
or fetch (children #1/#3/#4).
- reconcile(): per-peer dedup then quorum + median aggregate (pure, no I/O)
- sample_keyspace_points(): deterministic under an injected SplitMix64 RNG
- sample_candidates(): async composition over a NeighbourhoodProbe seam
- SPEC.md §7.10c documents the sampling + quorum contract (normative)
Bumps dig-node-core 0.28.0 -> 0.29.0 and workspace 0.77.0 -> 0.78.0 (MINOR).
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>
MichaelTaylor3d added a commit that referenced this pull request Aug 3, 2026
Piece #3 (receiver) + #4 (holder) of store-melt propagation, over
spy-testable seams (MeltChain/MeltCache/MeltBroadcast) with the
fail-closed NC-9 gate: only a held, on-chain-confirmed melt deletes;
Err/Unknown never deletes; held-check precedes any chain read; the
TombstoneSet CAS bounds each node to one rebroadcast so the epidemic
terminates. All 8 adversarial tests green.
Refs #1316
Co-Authored-By: Claude <noreply@anthropic.com>
MichaelTaylor3d added a commit that referenced this pull request Aug 3, 2026
Piece #3 (receiver) + #4 (holder) of store-melt propagation, over
spy-testable seams (MeltChain/MeltCache/MeltBroadcast) with the
fail-closed NC-9 gate: only a held, on-chain-confirmed melt deletes;
Err/Unknown never deletes; held-check precedes any chain read; the
TombstoneSet CAS bounds each node to one rebroadcast so the epidemic
terminates. All 8 adversarial tests green.
Refs #1316
Co-Authored-By: Claude <noreply@anthropic.com>
MichaelTaylor3d added a commit that referenced this pull request Aug 4, 2026
Piece #3 (receiver) + #4 (holder) of store-melt propagation, over
spy-testable seams (MeltChain/MeltCache/MeltBroadcast) with the
fail-closed NC-9 gate: only a held, on-chain-confirmed melt deletes;
Err/Unknown never deletes; held-check precedes any chain read; the
TombstoneSet CAS bounds each node to one rebroadcast so the epidemic
terminates. All 8 adversarial tests green.
Refs #1316
Co-Authored-By: Claude <noreply@anthropic.com>
MichaelTaylor3d added a commit that referenced this pull request Aug 4, 2026
Piece #3 (receiver) + #4 (holder) of store-melt propagation, over
spy-testable seams (MeltChain/MeltCache/MeltBroadcast) with the
fail-closed NC-9 gate: only a held, on-chain-confirmed melt deletes;
Err/Unknown never deletes; held-check precedes any chain read; the
TombstoneSet CAS bounds each node to one rebroadcast so the epidemic
terminates. All 8 adversarial tests green.
Refs #1316
Co-Authored-By: Claude <noreply@anthropic.com>
MichaelTaylor3d added a commit that referenced this pull request Aug 4, 2026
Piece #3 (receiver) + #4 (holder) of store-melt propagation, over
spy-testable seams (MeltChain/MeltCache/MeltBroadcast) with the
fail-closed NC-9 gate: only a held, on-chain-confirmed melt deletes;
Err/Unknown never deletes; held-check precedes any chain read; the
TombstoneSet CAS bounds each node to one rebroadcast so the epidemic
terminates. All 8 adversarial tests green.
Refs #1316
Co-Authored-By: Claude <noreply@anthropic.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@MichaelTaylor3d