{
 "number": 36443,
 "input_hash": "0b9471c9bd5aec33",
 "model": "ledger",
 "prompt_hash": null,
 "created": "2026-10-24T01:18:33+00:00",
 "result": {
  "summary": "Adds a `ReconstructMultipath` method to the `Descriptor` interface, allowing a unified multipath descriptor object to be reconstructed from its expanded single-path sibling descriptors. The reconstruction inspects the derivation paths of the sibling descriptors and reconstitutes the combined multipath expression. Unit tests, negative invalid-path tests, and fuzzing harness updates are added to verify round-tripping.",
  "problem": "Multipath descriptors expand into individual single-path descriptors, but there is no mechanism to invert this expansion and recover the original unified multipath descriptor from those expanded instances.",
  "card": "Adds ReconstructMultipath to reconstruct a single multipath descriptor object from an ordered set of its expanded single-path descriptors. This makes descriptor expansion reversible in memory for descriptor-aware tooling and wallet flows. The change is backed by unit tests, invalid-input tests, and fuzz testing. Depends on #36442.",
  "evidence": [
   "PR description: 'This expansion is reversible - given the expansion in the order of the multipath elements, it is possible to determine what the original multipath descriptor was. This PR adds ReconstructMultipath to produce a new Descriptor representing the multipath descriptor that produced the expansion.'"
  ],
  "scope_notes": "This PR is stacked on PR #36442 and includes its commits; only the final four commits implement and test the multipath reconstruction functionality.",
  "changed_since_previous": "Rebased onto the latest commit stack of #36442, which introduces `KeyPathElement` and changes `Parse` to return a single `std::unique_ptr<Descriptor>`; the reconstruction logic itself remains the same.",
  "thread": {
   "last_event_at": "2026-10-23T06:18:43Z",
   "events": 6,
   "head_sha": "62e70eb6f05ba52082ba03af4664c2691a12f270",
   "schema_floor": 2,
   "schema": 2
  },
  "waiting_on": [
   {
    "at": "2026-10-23",
    "id": "r:5624648052",
    "on": "author",
    "url": "https://github.com/bitcoin/bitcoin/pull/36443#pullrequestreview-5624648052",
    "what": "addressing repeated-value bug in ReconstructMultipath"
   }
  ],
  "risk": {
   "level": "medium",
   "touches": [
    "wallet",
    "rpc_api",
    "tests"
   ],
   "why": "A flaw in multipath reconstruction could produce incorrect derivation paths or invalid descriptors, potentially causing wallet derivation errors or script pubkey mismatches."
  },
  "discussion": {
   "author_status": "last statement processed 2026-10-23",
   "open_concerns": [
    "fametrano: ReconstructMultipath accepts relatives that repeat a path value, returning an invalid descriptor or an incorrect number of elements instead of failing",
    "fametrano: Reject a relative whose index is already in the step",
    "fametrano: Reject a relative whose index is already in the step for the musig path",
    "fametrano: Fail reconstruction unless the step ends with one index per input, rejecting identical inputs",
    "fametrano: Add test cases covering repeated-value inputs, with and without musig"
   ],
   "resolved_concerns": []
  },
  "reviewability": {
   "state": "Paused",
   "label": "Waiting on author",
   "reason": "Open objections from fametrano with no author reply for 9 days; review would repeat what has been asked."
  },
  "agreement": {
   "state": "Blocked",
   "summary": "Blocked: objection that needs a change, nobody has replied (fametrano)",
   "reason": "fametrano tested reconstruction against btclib-wallet and reported that repeated path values are not rejected, providing inline code suggestions and unit tests to fix the issue.",
   "evidence": [
    "fametrano (objection, correctness, must be changed, open): ReconstructMultipath accepts relatives that repeat a path value, returning an invalid descriptor or an incorrect number of elements instead of failing",
    "fametrano (suggestion, correctness, must be answered, open): Reject a relative whose index is already in the step",
    "fametrano (suggestion, correctness, must be answered, open): Reject a relative whose index is already in the step for the musig path",
    "fametrano (suggestion, correctness, must be answered, open): Fail reconstruction unless the step ends with one index per input, rejecting identical inputs",
    "fametrano (suggestion, correctness, must be answered, open): Add test cases covering repeated-value inputs, with and without musig",
    "w0xlt: Concept ACK \u2014 no reason given"
   ],
   "objections": [
    {
     "reviewer": "fametrano",
     "association": "CONTRIBUTOR",
     "type": "objection",
     "kind": "correctness",
     "harm": "ReconstructMultipath accepts relatives that repeat a path value, returning an invalid descriptor or an incorrect number of elements instead of failing",
     "request": "",
     "question": "",
     "text": "ReconstructMultipath accepts relatives that repeat a path value, returning an invalid descriptor or an incorrect number of elements instead of failing",
     "clears_with": "change",
     "blocking": true,
     "status": "open",
     "status_note": "",
     "cleared": false,
     "author_replied": false,
     "others_replied": false,
     "fix_pushed": false,
     "replies": [],
     "evidence": "2026-10-23: 'ReconstructMultipath accepts relatives that repeat a path value, and then returns a descriptor that is not their multipath form.'",
     "url": "https://github.com/bitcoin/bitcoin/pull/36443#pullrequestreview-5624648052",
     "id": "r:5624648052",
     "at": "2026-10-23",
     "status_at": null,
     "status_by": null,
     "resolution_evidence": "",
     "pin": null,
     "from_schema": 2
    },
    {
     "reviewer": "fametrano",
     "association": "CONTRIBUTOR",
     "type": "suggestion",
     "kind": "correctness",
     "harm": "",
     "request": "Reject a relative whose index is already in the step",
     "question": "",
     "text": "Reject a relative whose index is already in the step",
     "clears_with": "answer",
     "blocking": false,
     "status": "open",
     "status_note": "",
     "cleared": false,
     "author_replied": false,
     "others_replied": false,
     "fix_pushed": false,
     "replies": [],
     "evidence": "2026-10-23: 'A relative whose index is already in the step is a repeat, so reject it.'",
     "url": "https://github.com/bitcoin/bitcoin/pull/36443#discussion_r4356713203",
     "id": "rc:4356713203",
     "at": "2026-10-23",
     "status_at": null,
     "status_by": null,
     "resolution_evidence": "",
     "pin": null,
     "from_schema": 2
    },
    {
     "reviewer": "fametrano",
     "association": "CONTRIBUTOR",
     "type": "suggestion",
     "kind": "correctness",
     "harm": "",
     "request": "Reject a relative whose index is already in the step for the musig path",
     "question": "",
     "text": "Reject a relative whose index is already in the step for the musig path",
     "clears_with": "answer",
     "blocking": false,
     "status": "open",
     "status_note": "",
     "cleared": false,
     "author_replied": false,
     "others_replied": false,
     "fix_pushed": false,
     "replies": [],
     "evidence": "2026-10-23: 'Same check for the musig path.'",
     "url": "https://github.com/bitcoin/bitcoin/pull/36443#discussion_r4356713234",
     "id": "rc:4356713234",
     "at": "2026-10-23",
     "status_at": null,
     "status_by": null,
     "resolution_evidence": "",
     "pin": null,
     "from_schema": 2
    },
    {
     "reviewer": "fametrano",
     "association": "CONTRIBUTOR",
     "type": "suggestion",
     "kind": "correctness",
     "harm": "",
     "request": "Fail reconstruction unless the step ends with one index per input, rejecting identical inputs",
     "question": "",
     "text": "Fail reconstruction unless the step ends with one index per input, rejecting identical inputs",
     "clears_with": "answer",
     "blocking": false,
     "status": "open",
     "status_note": "",
     "cleared": false,
     "author_replied": false,
     "others_replied": false,
     "fix_pushed": false,
     "replies": [],
     "evidence": "2026-10-23: 'Fail unless the step ends with one index per input. This also rejects identical inputs.'",
     "url": "https://github.com/bitcoin/bitcoin/pull/36443#discussion_r4356713246",
     "id": "rc:4356713246",
     "at": "2026-10-23",
     "status_at": null,
     "status_by": null,
     "resolution_evidence": "",
     "pin": null,
     "from_schema": 2
    },
    {
     "reviewer": "fametrano",
     "association": "CONTRIBUTOR",
     "type": "suggestion",
     "kind": "correctness",
     "harm": "",
     "request": "Add test cases covering repeated-value inputs, with and without musig",
     "question": "",
     "text": "Add test cases covering repeated-value inputs, with and without musig",
     "clears_with": "answer",
     "blocking": false,
     "status": "open",
     "status_note": "",
     "cleared": false,
     "author_replied": false,
     "others_replied": false,
     "fix_pushed": false,
     "replies": [],
     "evidence": "2026-10-23: 'Add the repeated-value cases, with and without musig.'",
     "url": "https://github.com/bitcoin/bitcoin/pull/36443#discussion_r4356713256",
     "id": "rc:4356713256",
     "at": "2026-10-23",
     "status_at": null,
     "status_by": null,
     "resolution_evidence": "",
     "pin": null,
     "from_schema": 2
    }
   ],
   "support": [
    {
     "reviewer": "w0xlt",
     "reason": "no reason given",
     "substantive": false,
     "verdict": "Concept ACK",
     "id": "c:6066076341",
     "url": "https://github.com/bitcoin/bitcoin/pull/36443#issuecomment-6066076341",
     "at": "2026-10-08",
     "association": "CONTRIBUTOR",
     "evidence": "none",
     "areas": []
    }
   ],
   "participants": [
    {
     "login": "w0xlt",
     "stance": "support",
     "note": "Concept ACK",
     "association": "CONTRIBUTOR",
     "comments": 1,
     "first": "2026-10-08",
     "last": "2026-10-08"
    },
    {
     "login": "fametrano",
     "stance": "objection",
     "note": "found that ReconstructMultipath accepts repeated path values and returns invalid descriptors",
     "association": "CONTRIBUTOR",
     "comments": 5,
     "first": "2026-10-23",
     "last": "2026-10-23"
    }
   ],
   "derivation": "objection that needs a change, nobody has replied (fametrano)",
   "model_state": null,
   "corrections": [],
   "notes": "fametrano tested reconstruction against btclib-wallet and reported that repeated path values are not rejected, providing inline code suggestions and unit tests to fix the issue."
  },
  "dependencies": {
   "depends_on": [
    "#36442"
   ],
   "enables": []
  },
  "categories": [
   {
    "name": "mining",
    "member": false,
    "evidence": "Touch to src/rpc/mining.cpp is incidental refactoring/signature updates and does not alter mining or template generation logic.",
    "band": "Unranked",
    "reason_tag": "cleanup",
    "score": 0.0,
    "factors": {
     "bug_severity": 0,
     "leverage": 1,
     "performance": 0,
     "security_stability": 0,
     "user_value": 1
    },
    "rationale": "Incidental changes to mining RPC callers do not affect block template construction or mining interfaces."
   },
   {
    "name": "rpc",
    "member": false,
    "evidence": "Touches to src/rpc/ files adapt existing calls to descriptor or BIP32 helper changes rather than altering RPC behaviors or protocols.",
    "band": "Unranked",
    "reason_tag": "cleanup",
    "score": 0.0,
    "factors": {
     "bug_severity": 0,
     "leverage": 1,
     "performance": 0,
     "security_stability": 0,
     "user_value": 1
    },
    "rationale": "Changes in RPC files are caller-side updates resulting from underlying descriptor and path refactoring."
   },
   {
    "name": "tests",
    "member": false,
    "evidence": "Changes in test and benchmark files test descriptor and BIP32 functionality directly rather than modifying general test framework machinery.",
    "band": "Unranked",
    "reason_tag": "test coverage",
    "score": 0.0,
    "factors": {
     "bug_severity": 0,
     "leverage": 1,
     "performance": 0,
     "security_stability": 0,
     "user_value": 1
    },
    "rationale": "Unit tests and fuzz harnesses updated here test descriptor parsing and round-tripping, which belongs to descriptor/wallet coverage rather than test infrastructure."
   },
   {
    "name": "utils",
    "member": false,
    "evidence": "Touches to src/util/bip32.cpp and src/util/bip32.h are BIP32 keypath utilities supporting descriptor reconstruction (and stacked from #36442).",
    "band": "Unranked",
    "reason_tag": "cleanup",
    "score": 0.0,
    "factors": {
     "bug_severity": 0,
     "leverage": 1,
     "performance": 0,
     "security_stability": 0,
     "user_value": 1
    },
    "rationale": "BIP32 path parsing logic serves key and descriptor management rather than shared generic node utilities."
   },
   {
    "name": "wallet",
    "member": true,
    "evidence": "Directly implements descriptor logic under the 'Descriptors' label, modifying src/script/descriptor.cpp and wallet descriptor management.",
    "band": "P3",
    "reason_tag": "new feature",
    "score": 0.35,
    "factors": {
     "bug_severity": 0,
     "leverage": 1,
     "performance": 0,
     "security_stability": 0,
     "user_value": 1
    },
    "rationale": "Adds `ReconstructMultipath` to allow recovering a unified multipath descriptor from its expanded single-path descriptors. While an inversion mechanism provides clear utility for descriptor handling, there is no stated fund-safety risk or critical blocker making it urgent."
   }
  ],
  "confidence": "high",
  "uncertainties": [],
  "needs": []
 },
 "cost_usd": 0.0,
 "source": {
  "record": "2026-10-24T01:18:33+00:00",
  "code": "2026-10-09T01:22:05+00:00",
  "judgments": 5
 }
}