{
 "number": 32247,
 "repo": "bitcoin/bitcoin",
 "url": "https://github.com/bitcoin/bitcoin/pull/32247",
 "title": "BIP-348 (OP_CHECKSIGFROMSTACK) (regtest only)",
 "author": "jamesob",
 "author_association": "CONTRIBUTOR",
 "created_at": "2025-04-10T19:41:43Z",
 "updated_at": "2026-06-30T17:13:52Z",
 "age_days": 524,
 "draft": true,
 "labels": [
  "Consensus",
  "Needs rebase",
  "Needs Conceptual Review"
 ],
 "milestone": null,
 "base": "master",
 "head_sha": "ae64dcebe115d0708ea9d0ad444ec9df98fbd7cd",
 "head_ref": "2025-04-csfs",
 "head_repo": "jamesob/bitcoin",
 "head_history": [
  {
   "t": "2025-04-11T15:07:58Z",
   "sha": "cb0c9f6389abc1d24b4fb8b80eaaa539acd81f92"
  },
  {
   "t": "2025-04-26T14:21:44Z",
   "sha": "7e7b3784dd3857fa504b56fa762166e9846a0955"
  },
  {
   "t": "2025-04-30T23:55:50Z",
   "sha": "8c000e7f38e7454dbf7d3502b1e4fec3581f1cc6"
  },
  {
   "t": "2025-05-12T15:54:14Z",
   "sha": "ae64dcebe115d0708ea9d0ad444ec9df98fbd7cd"
  }
 ],
 "additions": 296,
 "deletions": 12,
 "changed_files": 20,
 "commit_count": 3,
 "size_bucket": "M",
 "mergeable_state": "dirty",
 "bot": {
  "drahtbot": {
   "present": true,
   "reviews": {
    "concept_ack": [
     {
      "login": "jonatack",
      "url": "https://github.com/bitcoin/bitcoin/pull/32247#issuecomment-2797253857"
     },
     {
      "login": "shahsb",
      "url": "https://github.com/bitcoin/bitcoin/pull/32247#issuecomment-2811995385"
     },
     {
      "login": "yuvicc",
      "url": "https://github.com/bitcoin/bitcoin/pull/32247#issuecomment-2901612231"
     },
     {
      "login": "delta1",
      "url": "https://github.com/bitcoin/bitcoin/pull/32247#issuecomment-2955583380"
     },
     {
      "login": "pinheadmz",
      "url": "https://github.com/bitcoin/bitcoin/pull/32247#issuecomment-2960013289"
     }
    ],
    "stale_ack": [
     {
      "login": "JeremyRubin",
      "url": "https://github.com/bitcoin/bitcoin/pull/32247#issuecomment-2812906642"
     }
    ]
   },
   "conflicts": [
    {
     "number": 32998,
     "title": "Bump SCRIPT_VERIFY flags to 64 bit",
     "author": "ajtowns"
    },
    {
     "number": 32473,
     "title": "Introduce per-txin sighash midstate cache for legacy/p2sh/segwitv0 scripts",
     "author": "sipa"
    },
    {
     "number": 32453,
     "title": "[Policy] Discourage Unsigned Annexes",
     "author": "JeremyRubin"
    },
    {
     "number": 31989,
     "title": "BIP-119 (OP_CHECKTEMPLATEVERIFY) (regtest only)",
     "author": "jamesob"
    },
    {
     "number": 29843,
     "title": "policy: Allow non-standard scripts with -acceptnonstdtxn=1 (test nets only)",
     "author": "ajtowns"
    },
    {
     "number": 29247,
     "title": "CAT in Tapscript (BIP-347)",
     "author": "arminsabouri"
    },
    {
     "number": 26201,
     "title": "Remove Taproot activation height",
     "author": "Sjors"
    }
   ]
  }
 },
 "acks_parsed": {
  "jonatack": {
   "kind": "concept_ack",
   "hash": null,
   "t": "2025-04-11T15:34:58Z",
   "stale": false
  },
  "shahsb": {
   "kind": "concept_ack",
   "hash": null,
   "t": "2025-04-17T07:04:51Z",
   "stale": false
  },
  "JeremyRubin": {
   "kind": "ack",
   "hash": null,
   "t": "2025-04-17T13:25:51Z",
   "stale": true
  },
  "yuvicc": {
   "kind": "concept_ack",
   "hash": null,
   "t": "2025-05-22T15:14:16Z",
   "stale": false
  },
  "delta1": {
   "kind": "concept_ack",
   "hash": null,
   "t": "2025-06-09T11:59:06Z",
   "stale": false
  }
 },
 "acks_tally": {
  "ack": 0,
  "stale_ack": 1,
  "concept_ack": 4,
  "approach_ack": 0,
  "nack": 0,
  "concept_nack": 0,
  "approach_nack": 0
 },
 "reviews": {
  "approved": 0,
  "changes_requested": 0,
  "distinct_reviewers": [
   "1440000bytes",
   "JeremyRubin",
   "benthecarman",
   "delta1",
   "instagibbs",
   "jonatack",
   "pinheadmz",
   "shahsb",
   "yuvicc"
  ]
 },
 "signals": {
  "needs_rebase": true,
  "ci_failed": false,
  "mergeable_state": "dirty",
  "last_author_activity": "2025-05-12T15:54:14Z",
  "last_reviewer_activity": "2025-07-30T17:57:29Z",
  "last_reviewer": "benthecarman",
  "author_silent_days": 493,
  "waiting_on_author_days": 413,
  "days_since_update": 78
 },
 "refs": {
  "mentioned": [
   31989
  ],
  "depends_on": [],
  "fixes": [],
  "linked_issues": [],
  "references": [
   {
    "number": 31989,
    "type": "pull",
    "state": "open",
    "merged": false,
    "merged_at": null,
    "title": "BIP-119 (OP_CHECKTEMPLATEVERIFY) (regtest only)"
   }
  ],
  "conflicts": [
   32998,
   32473,
   32453,
   31989,
   29843,
   29247,
   26201
  ]
 },
 "stack": {
  "shares_commits_with": [],
  "based_on": [],
  "base_for": []
 },
 "review_paths": [
  "src/pubkey.cpp",
  "src/script/interpreter.cpp",
  "src/script/interpreter.h"
 ],
 "body": "This implements [BIP-348 (`OP_CHECKSIGFROMSTACK`)](https://github.com/bitcoin/bips/blob/master/bip-0348.md), but only specifies a regtest deployment. There is no effective policy change, since the SCRIPT_VERIFY_* flags (as used) result in the same OP_SUCCESS-like behavior.\n\nThis change can be composed with other opcode specifications (e.g. CTV, see #31989) and bundled into the same deployment (yet to be specified).\n\nI encourage more general, conceptual discussion to happen on [Delving Bitcoin](https://delvingbitcoin.org/) and not on this pull request.\n\nSome related discussion on Delving Bitcoin here:\n- https://delvingbitcoin.org/t/ctv-csfs-can-we-reach-consensus-on-a-first-step-towards-covenants/\n\nSee also:\n- https://bitcoinops.org/en/topics/op_checksigfromstack/",
 "commits": [
  {
   "sha": "15d7aa5391cf3bd4070c1167410d7c895e6045b7",
   "date": "2025-05-12T15:38:55Z",
   "message": "Implement OP_CHECKSIGFROMSTACK\n\nSome code and ideas from Elements by stevenroose, and sanket1729\nPorting help from moonsettler.\n\nTests added to the transaction tests framework.\n\nCo-authored-by: James O'Beirne <github@au92.org>"
  },
  {
   "sha": "765a674603e67af81600e9af0de355f21874253e",
   "date": "2025-05-12T15:39:00Z",
   "message": "consensus: add a CSFS deployment for regtest only"
  },
  {
   "sha": "ae64dcebe115d0708ea9d0ad444ec9df98fbd7cd",
   "date": "2025-05-12T15:52:51Z",
   "message": "test: add BIP-348 coverage to feature_taproot"
  }
 ],
 "timeline": [
  {
   "t": "2025-04-11T15:07:58Z",
   "kind": "force_push",
   "who": "jamesob",
   "commit": "cb0c9f6389abc1d24b4fb8b80eaaa539acd81f92"
  },
  {
   "t": "2025-04-11T15:34:58Z",
   "kind": "comment",
   "who": "jonatack",
   "assoc": "MEMBER",
   "text": "Concept ACK"
  },
  {
   "t": "2025-04-16T01:37:11Z",
   "kind": "review_comment",
   "who": "JeremyRubin",
   "assoc": "CONTRIBUTOR",
   "path": "src/script/interpreter.h",
   "commit": "ae64dcebe115d0708ea9d0ad444ec9df98fbd7cd",
   "in_reply_to": null,
   "text": "should maybe use bits 24 and 25"
  },
  {
   "t": "2025-04-16T01:45:31Z",
   "kind": "review_comment",
   "who": "JeremyRubin",
   "assoc": "CONTRIBUTOR",
   "path": "src/pubkey.cpp",
   "commit": "ae64dcebe115d0708ea9d0ad444ec9df98fbd7cd",
   "in_reply_to": null,
   "text": "i think it might be better to introduce a new function, VerifySchnorrArbitrary here, that way any existing use is identical API. Or use multi dispatch."
  },
  {
   "t": "2025-04-16T01:46:03Z",
   "kind": "review_comment",
   "who": "JeremyRubin",
   "assoc": "CONTRIBUTOR",
   "path": "src/script/interpreter.cpp",
   "commit": "ae64dcebe115d0708ea9d0ad444ec9df98fbd7cd",
   "in_reply_to": null,
   "text": "usually we return via set_error, right?\n\nor I guess EvalCheckSigFromStack sets it for us -- maybe worth a comment."
  },
  {
   "t": "2025-04-16T01:57:17Z",
   "kind": "review_comment",
   "who": "JeremyRubin",
   "assoc": "CONTRIBUTOR",
   "path": "src/pubkey.cpp",
   "commit": "ae64dcebe115d0708ea9d0ad444ec9df98fbd7cd",
   "in_reply_to": null,
   "text": "needs to be asserting that msg.size() > 0"
  },
  {
   "t": "2025-04-16T01:57:34Z",
   "kind": "review_comment",
   "who": "JeremyRubin",
   "assoc": "CONTRIBUTOR",
   "path": "src/pubkey.cpp",
   "commit": "ae64dcebe115d0708ea9d0ad444ec9df98fbd7cd",
   "in_reply_to": 2045857460,
   "text": "secp256k1_schnorrsig_verify will assert otherwise"
  },
  {
   "t": "2025-04-16T02:00:40Z",
   "kind": "review_comment",
   "who": "JeremyRubin",
   "assoc": "CONTRIBUTOR",
   "path": "src/pubkey.cpp",
   "commit": "ae64dcebe115d0708ea9d0ad444ec9df98fbd7cd",
   "in_reply_to": 2045857460,
   "text": "nvm misread the ARGCHECK --> it's only checked that if msg is NULL, then length must be 0, which... makes sense!"
  },
  {
   "t": "2025-04-16T02:07:52Z",
   "kind": "review_comment",
   "who": "JeremyRubin",
   "assoc": "CONTRIBUTOR",
   "path": "src/script/interpreter.cpp",
   "commit": "ae64dcebe115d0708ea9d0ad444ec9df98fbd7cd",
   "in_reply_to": null,
   "text": "should we just update the BIP for this to just be the internalkey? At the very least, there isn't a hard reason I can think of to burn this keytype (other than checksig keytype parity)\n\nwe'd still be bound to the bytes per sigop restrictions, and it seems harmless to allow?\n\ncc @instagibbs @reardencode"
  },
  {
   "t": "2025-04-16T02:09:26Z",
   "kind": "review_comment",
   "who": "JeremyRubin",
   "assoc": "CONTRIBUTOR",
   "path": "src/script/interpreter.cpp",
   "commit": "ae64dcebe115d0708ea9d0ad444ec9df98fbd7cd",
   "in_reply_to": null,
   "text": "code wise, it shouldn't matter, but I'd set success = false here anyways?"
  },
  {
   "t": "2025-04-16T02:10:21Z",
   "kind": "review_comment",
   "who": "JeremyRubin",
   "assoc": "CONTRIBUTOR",
   "path": "src/script/interpreter.cpp",
   "commit": "ae64dcebe115d0708ea9d0ad444ec9df98fbd7cd",
   "in_reply_to": null,
   "text": "same -- it doesn't matter, but I'd set success = false."
  },
  {
   "t": "2025-04-16T02:30:00Z",
   "kind": "review_comment",
   "who": "JeremyRubin",
   "assoc": "CONTRIBUTOR",
   "path": "src/script/interpreter.cpp",
   "commit": "ae64dcebe115d0708ea9d0ad444ec9df98fbd7cd",
   "in_reply_to": null,
   "text": "on L354 we do set success variable, and according to current BIP text, we should be setting success =true explicitly in this case."
  },
  {
   "t": "2025-04-16T02:30:51Z",
   "kind": "review_comment",
   "who": "JeremyRubin",
   "assoc": "CONTRIBUTOR",
   "path": "src/script/interpreter.cpp",
   "commit": "ae64dcebe115d0708ea9d0ad444ec9df98fbd7cd",
   "in_reply_to": 2045891004,
   "text": "further, wer'e erronenously setting success=false for unknown key types, so definitely have to fix that!"
  },
  {
   "t": "2025-04-16T03:09:11Z",
   "kind": "review_comment",
   "who": "JeremyRubin",
   "assoc": "CONTRIBUTOR",
   "path": "src/script/interpreter.cpp",
   "commit": "ae64dcebe115d0708ea9d0ad444ec9df98fbd7cd",
   "in_reply_to": 2045891004,
   "text": "thought about this more; we do want success=false in all cases when sig = null, i was wrong"
  },
  {
   "t": "2025-04-16T18:41:27Z",
   "kind": "review_comment",
   "who": "instagibbs",
   "assoc": "MEMBER",
   "path": "src/script/interpreter.cpp",
   "commit": "ae64dcebe115d0708ea9d0ad444ec9df98fbd7cd",
   "in_reply_to": 2045867908,
   "text": "https://gnusha.org/pi/bitcoindev/CAD5xwhi6DYVm3sONub0x4s=Ef0TupA4j4KxY616RnacXr1GsLA@mail.gmail.com/\n\nI think I agree with 2022-you; separate opcode for key is cleaner and strictly better. Leaving it undefined might be fine?"
  },
  {
   "t": "2025-04-16T19:56:15Z",
   "kind": "review_comment",
   "who": "JeremyRubin",
   "assoc": "CONTRIBUTOR",
   "path": "src/script/interpreter.cpp",
   "commit": "ae64dcebe115d0708ea9d0ad444ec9df98fbd7cd",
   "in_reply_to": 2045867908,
   "text": "I'm fine with that -- if we want INTERNALKEY it can be it's own opcode later on.\n\nfollow up would be: does symmetry with CHECKSIG mean we should make OP_0 permanently a non-key? v.s. preserving the upgrade path?"
  },
  {
   "t": "2025-04-17T07:04:12Z",
   "kind": "review",
   "who": "shahsb",
   "assoc": "NONE",
   "state": "COMMENTED",
   "commit": "cb0c9f6389abc1d24b4fb8b80eaaa539acd81f92",
   "text": "I agree with @JeremyRubin comments..!"
  },
  {
   "t": "2025-04-17T07:04:51Z",
   "kind": "comment",
   "who": "shahsb",
   "assoc": "NONE",
   "text": "Concept ACK"
  },
  {
   "t": "2025-04-17T13:25:51Z",
   "kind": "comment",
   "who": "JeremyRubin",
   "assoc": "CONTRIBUTOR",
   "text": "cr ACK [cb0c9f6](https://github.com/bitcoin/bitcoin/pull/32247/commits/cb0c9f6389abc1d24b4fb8b80eaaa539acd81f92)\n\nThis matches the BIP's semantics, and the implementation is reasonable. Minor nits above to reduce possibility of behavior changes for other users of Schnorr APIs."
  },
  {
   "t": "2025-04-17T19:47:01Z",
   "kind": "comment",
   "who": "instagibbs",
   "assoc": "MEMBER",
   "text": "I spent a bit of time writing tests (reading directly from the BIP) for feature_taproot.py: https://github.com/instagibbs/bitcoin/tree/2025-04-bip348_tests\n\nThis should hopefully give some nice coverage of border conditions, including sigops budget and maybe inspired people to add more if they want to contribute in a positive way.\n\nhttps://github.com/instagibbs/bitcoin/tree/2025-03-bip348-inq-28 this was an alternative implementation of the core logic, but I think it matches here"
  },
  {
   "t": "2025-04-26T14:21:44Z",
   "kind": "force_push",
   "who": "jamesob",
   "commit": "7e7b3784dd3857fa504b56fa762166e9846a0955"
  },
  {
   "t": "2025-04-26T14:23:58Z",
   "kind": "comment",
   "who": "jamesob",
   "assoc": "CONTRIBUTOR",
   "text": "Thanks @instagibbs; I've compressed your test changes into a single commit and added that here."
  },
  {
   "t": "2025-04-30T23:55:50Z",
   "kind": "force_push",
   "who": "jamesob",
   "commit": "8c000e7f38e7454dbf7d3502b1e4fec3581f1cc6"
  },
  {
   "t": "2025-05-12T15:54:14Z",
   "kind": "force_push",
   "who": "jamesob",
   "commit": "ae64dcebe115d0708ea9d0ad444ec9df98fbd7cd"
  },
  {
   "t": "2025-05-22T15:14:16Z",
   "kind": "comment",
   "who": "yuvicc",
   "assoc": "CONTRIBUTOR",
   "text": "Concept ACK"
  },
  {
   "t": "2025-06-09T11:59:06Z",
   "kind": "comment",
   "who": "delta1",
   "assoc": "NONE",
   "text": "Concept ACK"
  },
  {
   "t": "2025-06-10T17:04:26Z",
   "kind": "comment",
   "who": "pinheadmz",
   "assoc": "MEMBER",
   "text": "In an effort to keep pull requests focused on technical discussion, I invite all contributors of conceptual review to post here:\n\nhttps://github.com/bitcoin-core/meta/discussions/28\n\nPlease try to keep pull request comments focused on the code changes, and move all other comments including \"concept N/ACK\" to the discussion page."
  },
  {
   "t": "2025-06-22T07:13:15Z",
   "kind": "review_comment",
   "who": "1440000bytes",
   "assoc": "NONE",
   "path": "src/script/interpreter.cpp",
   "commit": "ae64dcebe115d0708ea9d0ad444ec9df98fbd7cd",
   "in_reply_to": null,
   "text": "Why tapscript only?"
  },
  {
   "t": "2025-06-22T07:56:03Z",
   "kind": "review_comment",
   "who": "benthecarman",
   "assoc": "CONTRIBUTOR",
   "path": "src/script/interpreter.cpp",
   "commit": "ae64dcebe115d0708ea9d0ad444ec9df98fbd7cd",
   "in_reply_to": 2160245851,
   "text": "https://github.com/bitcoin/bips/blob/master/bip-0348.md"
  },
  {
   "t": "2025-06-22T08:33:02Z",
   "kind": "review_comment",
   "who": "1440000bytes",
   "assoc": "NONE",
   "path": "src/script/interpreter.cpp",
   "commit": "ae64dcebe115d0708ea9d0ad444ec9df98fbd7cd",
   "in_reply_to": 2160245851,
   "text": "I couldn't find anything in the BIP but there was some discussion in the pull request and mailing list:\n\nhttps://github.com/bitcoin/bips/pull/1535#issuecomment-2111195930\n\nhttps://groups.google.com/u/2/g/bitcoindev/c/usHmnXDuJQc/m/PbSGqDjIAgAJ\n\nI think it shouldn't be restricted to taproot. It could be used for several things and not just LN SYMMETRY."
  },
  {
   "t": "2025-07-30T17:57:29Z",
   "kind": "review_comment",
   "who": "benthecarman",
   "assoc": "CONTRIBUTOR",
   "path": "src/script/interpreter.cpp",
   "commit": "ae64dcebe115d0708ea9d0ad444ec9df98fbd7cd",
   "in_reply_to": null,
   "text": "nit: this is between EvalChecksigPreTapscript and EvalChecksigTapscript which can be a little confusing/annoying"
  }
 ],
 "labels_log": [
  {
   "t": "2025-04-11T09:23:42Z",
   "action": "labeled",
   "label": "Consensus",
   "who": "laanwj"
  },
  {
   "t": "2025-04-29T00:52:12Z",
   "action": "labeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2025-04-29T22:58:35Z",
   "action": "labeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2025-05-01T00:34:17Z",
   "action": "unlabeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2025-05-01T01:14:13Z",
   "action": "unlabeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2025-05-06T23:17:53Z",
   "action": "labeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2025-05-12T16:41:27Z",
   "action": "unlabeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2025-06-10T12:56:08Z",
   "action": "labeled",
   "label": "Needs Conceptual Review",
   "who": "glozow"
  },
  {
   "t": "2025-08-11T11:28:31Z",
   "action": "labeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  }
 ],
 "state_log": [
  {
   "t": "2025-10-22T15:58:00Z",
   "kind": "convert_to_draft",
   "who": "achow101"
  }
 ],
 "text_chars": 4667,
 "text_tokens_estimate": 1166,
 "changed_paths": [
  "src/consensus/params.h",
  "src/deploymentinfo.cpp",
  "src/kernel/chainparams.cpp",
  "src/policy/policy.h",
  "src/pubkey.cpp",
  "src/pubkey.h",
  "src/rpc/blockchain.cpp",
  "src/script/interpreter.cpp",
  "src/script/interpreter.h",
  "src/script/script.cpp",
  "src/script/script.h",
  "src/test/data/tx_invalid.json",
  "src/test/data/tx_valid.json",
  "src/test/transaction_tests.cpp",
  "src/test/versionbits_tests.cpp",
  "src/validation.cpp",
  "test/functional/feature_taproot.py",
  "test/functional/rpc_blockchain.py",
  "test/functional/test_framework/key.py",
  "test/functional/test_framework/script.py"
 ],
 "files": [
  {
   "path": "src/consensus/params.h",
   "add": 1,
   "del": 0
  },
  {
   "path": "src/deploymentinfo.cpp",
   "add": 4,
   "del": 0
  },
  {
   "path": "src/kernel/chainparams.cpp",
   "add": 5,
   "del": 0
  },
  {
   "path": "src/policy/policy.h",
   "add": 2,
   "del": 1
  },
  {
   "path": "src/pubkey.cpp",
   "add": 3,
   "del": 2
  },
  {
   "path": "src/pubkey.h",
   "add": 2,
   "del": 1
  },
  {
   "path": "src/rpc/blockchain.cpp",
   "add": 4,
   "del": 0
  },
  {
   "path": "src/script/interpreter.cpp",
   "add": 92,
   "del": 3
  },
  {
   "path": "src/script/interpreter.h",
   "add": 6,
   "del": 0
  },
  {
   "path": "src/script/script.cpp",
   "add": 3,
   "del": 0
  },
  {
   "path": "src/script/script.h",
   "add": 1,
   "del": 0
  },
  {
   "path": "src/test/data/tx_invalid.json",
   "add": 8,
   "del": 0
  },
  {
   "path": "src/test/data/tx_valid.json",
   "add": 29,
   "del": 0
  },
  {
   "path": "src/test/transaction_tests.cpp",
   "add": 2,
   "del": 0
  },
  {
   "path": "src/test/versionbits_tests.cpp",
   "add": 6,
   "del": 0
  },
  {
   "path": "src/validation.cpp",
   "add": 12,
   "del": 1
  },
  {
   "path": "test/functional/feature_taproot.py",
   "add": 85,
   "del": 1
  },
  {
   "path": "test/functional/rpc_blockchain.py",
   "add": 13,
   "del": 0
  },
  {
   "path": "test/functional/test_framework/key.py",
   "add": 0,
   "del": 1
  },
  {
   "path": "test/functional/test_framework/script.py",
   "add": 18,
   "del": 2
  }
 ],
 "test_lines": 165,
 "git": {
  "head": "ae64dcebe115d0708ea9d0ad444ec9df98fbd7cd",
  "head_matches_backup": true,
  "base": "3edf400b1020d7b88402ebc0e758b1fad2e7a781",
  "commits": [
   {
    "sha": "15d7aa5391",
    "subject": "Implement OP_CHECKSIGFROMSTACK",
    "files": 12,
    "add": 169,
    "del": 8
   },
   {
    "sha": "765a674603",
    "subject": "consensus: add a CSFS deployment for regtest only",
    "files": 8,
    "add": 45,
    "del": 4
   },
   {
    "sha": "ae64dcebe1",
    "subject": "test: add BIP-348 coverage to feature_taproot",
    "files": 3,
    "add": 86,
    "del": 4
   }
  ],
  "patch_truncated": false
 },
 "input_hash": "909be6080fab6992",
 "extracted_at": "2026-09-17T16:15:31+00:00"
}