Repos at recon time: descriptor-mnemonic main (md-codec 0.35.0 / md-cli 0.6.1, in sync); mnemonic-key main; mnemonic-toolkit master ea8ba88.
Scope: decompose Theme A; pick + scope the first sub-cycle.
Theme A = "round-trip the wallet you actually have" (interop / one-directionality). Decomposes into three INDEPENDENT sub-cycles:
- A1 — concrete-descriptor round-trip. md-cli (and possibly toolkit) ingest/emit of a bare concrete descriptor.
- A2 — mk SLIP-0132 preservation. mk1 normalizes ypub/zpub/Ypub/Zpub/upub/vpub → xpub/tpub, losing the variant.
- A3 —
import-wallet --format green. export writesgreen, import can't read it (read↔write asymmetry).
-
There is NO
WalletPolicy::from_descriptor/ concrete-descriptor parser in md-codec or md-cli. (Survey claimed it exists — WRONG.) Only the outboundto_miniscript_descriptorexists (descriptor-mnemonic/crates/md-codec/src/to_miniscript.rs:53).md encoderejects anything lacking@Nplaceholders atmd-cli/src/parse/template.rs:86-89(lex_placeholders→"template contains no @i placeholders"). -
to_miniscript_descriptor(d, chain)already produces a CONCRETE miniscript descriptor (real[fp/path]xpub/chain/*keys fromd.tlv.pubkeys, single-chain)..to_string()appends the BIP-380#checksumfor free. BUTmd decodeonly callsdescriptor_to_template(md-cli/src/cmd/decode.rs:28) → template-only output. No md-cli command runs the concrete pipeline end-to-end. -
The TOOLKIT already synthesizes loadable, checksummed concrete descriptors in two paths:
export-wallet --template→wallet_export/pipeline.rs:18-31builds the string,MsDescriptor::from_str(&s).to_string()adds the#checksum;CheckedDescriptor::new()(wallet_export/mod.rs:418) enforces the suffix.export-wallet --descriptorpassthrough → re-parses + re-canonicalizes (cmd/export_wallet.rs:643-679).--format bitcoin-core→wallet_export/bitcoin_core.rs:42-86splits<0;1>multipath + emits validimportdescriptorsJSON with checksummeddesc.
-
import-walletalready parses concrete descriptors →@N+ cosigners via per-format parsers (sparrow.rs,coldcard_multisig.rs,electrum.rs, …) →wallet_import::pipeline([fp/path]xpub→@N).ParsedImport.original_descriptorpreserves the wire string incl. checksum.- The narrow remaining gap: no entry point accepts a bare concrete-descriptor STRING.
import-walletneeds a recognized wallet-FILE format;export-wallet/bundle --descriptorneeds explicit@Nannotation (toolkitparse_descriptor.rs:60-139lex_placeholdersfor the@N[fp/path]variant). So "here is a rawwsh(sortedmulti(...))from my hardware wallet, make cards" has no door.
- The narrow remaining gap: no entry point accepts a bare concrete-descriptor STRING.
-
mk SLIP-0132 (A2): guard at
mnemonic-key/crates/mk-codec/src/bytecode/xpub_compact.rs:63-68(version_to_network→Error::InvalidXpubVersionfor non-xpub/tpub version bytes). The toolkit normalizes ypub/zpub → xpub before mk1 (mnemonic-toolkit/src/slip0132.rs:66normalize_xpub_prefix), so mk1 cards carry onlyxpub/tpub. Preserving the variant on-card needs either a new mk1 wire field (script-type hint → mk-codec MINOR + new test vectors) OR re-derive-prefix-on-emit from the descriptor's script type. Toolkit already has full normalize-in +--xpub-prefixre-emit-out infra (shipped v0.6.1/v0.7). Open question: is on-card preservation actually wanted, or is normalize-in/re-emit-out sufficient? -
green (A3):
export-walletCliExportFormat::Green(cmd/export_wallet.rs:39), singlesig-only (FOLLOWUPgreen-native-multisig-pending-server-support).import-walletdispatch (cmd/import_wallet.rs:1128-1143) handles 8 formats,greenABSENT. Green's singlesig export is a plain descriptor → may already be readable via--format bitcoin-core(could be doc-only/thin, needs a real Green export file to confirm).
- No filed FOLLOWUP for "md concrete-descriptor ingest", "bare-descriptor ingest door", "mk1 SLIP-0132 preservation", or "import-wallet --format green". (SLIP-0132 toolkit normalize/re-emit entries are all SHIPPED/RESOLVED.)
- A1 (md-cli ingest+emit): md-codec wire UNCHANGED (front-end only in md-cli). md-cli MINOR. md-cli NOT in GUI schema → no schema-mirror. Manual mirror (
docs/manual/src/40-cli-reference/42-md.md) + cli-subcommands.list required. md-cli on crates.io → publish. - A1-toolkit (bare-descriptor door), if in scope: toolkit MINOR (new
--format descriptorvalue or new flag). GUI schema-mirror + manual + sibling-pin lockstep. - A2: mk-codec MINOR if new wire field (+ test vectors + toolkit re-pin + crates.io); or toolkit-only if re-emit-from-script-type.
- A3: toolkit MINOR (new
--formatvalue) + GUI schema-mirror + manual; possibly doc-only if bitcoin-core path already reads it.
A1 — concrete-descriptor round-trip, the survey headline and the only truly one-directional flow. Cleanest leverage: md-codec wire is untouched; the work is an md-cli front-end (ingest: detect [fp/path]xpub → assign @N + extract triples → existing pipeline; emit: md decode --as-descriptor --chain N → to_miniscript_descriptor(d,chain).to_string()). Open scope question for the user: standalone-md round-trip only, or also add the toolkit bare-descriptor ingest door (the higher-value but larger, lockstep-heavy piece). A2/A3 are smaller, independent follow-ons.