# \[BIP Draft\] Co-signer Spending Policies

**URL:** <https://delvingbitcoin.org/t/bip-draft-co-signer-spending-policies/2955>\
**Category:** Protocol Design\
**Created:** [October 10, 2026, 4:40am UTC](https://delvingbitcoin.org/t/bip-draft-co-signer-spending-policies/2955 "2026-10-10T04:40:58Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![lukecarriere](https://delvingbitcoin.org/user_avatar/delvingbitcoin.org/lukecarriere/32/2409_2.png) [@lukecarriere](https://delvingbitcoin.org/u/lukecarriere)\
**Post date:** [October 10, 2026, 4:40am UTC](https://delvingbitcoin.org/t/bip-draft-co-signer-spending-policies/2955/1 "2026-10-10T04:40:58Z")

</div>

I’d like feedback on a draft that standardizes the policy a co-signer enforces, not the co-signer itself.

A co-signer that signs only when a predicate holds is a known way to emulate covenants today. Towns described the multisig version of this in 2021. Recent work (Halseth’s blinded co-signers, Chain Code Delegation, predicate blind signatures, bonded co-signers) and products such as Liquidium and Lendasat each define their own policy. A wallet built for one cannot use a co-signer or oracle built for another.

The draft is one policy format for that. It covers open verification, blinded verification, and enclave verification, and conditions taken from the transaction or from external attestations. Co-signers must accept DLC oracle attestations, so existing oracles can be evidence sources unchanged. Anything script can enforce is required to be in script. Every policy keeps a spending path that needs no co-signer.

BIP Draft: [bip-cosigner-spending-policies/bip-cosigner-spending-policies.md at 468fdd1b75647432ed56c3a2b5579cbcfedaec74 · lukecarriere/bip-cosigner-spending-policies · GitHub](https://github.com/lukecarriere/bip-cosigner-spending-policies/blob/468fdd1b75647432ed56c3a2b5579cbcfedaec74/bip-cosigner-spending-policies.md)

I am not requesting a BIP number. I want to know whether this is the right layer to standardize, and comments on the open questions in the draft: canonical JSON or TLV; whether blinded verification can be specified now; whether the statement attestation format belongs here or in the DLC specifications; whether the output expression language is the right size; and whether the fallback path must be timelocked.

Luke Carriere

---

<div class="post-metadata">

**Author:** ![PREDGE](https://delvingbitcoin.org/user_avatar/delvingbitcoin.org/predge/32/2433_2.png) [@PREDGE](https://delvingbitcoin.org/u/PREDGE)\
**Post date:** [October 22, 2026, 9:01pm UTC](https://delvingbitcoin.org/t/bip-draft-co-signer-spending-policies/2955/2 "2026-10-22T21:01:05Z")

</div>

On statement-v0: the signed tuple is event ID, outcome and timestamp, and nothing says whether the outcome can still change. For escrow delivery and other events settled by people, attestors often publish a first answer and correct it later. A co-signer that sees a valid statement within max age would sign on the first one. Either add a finality flag to the signed tuple and let evidence conditions require it, or say in the escrow example that the template should wait out a dispute window. On JSON vs TLV: whichever wins, the policy ID needs test vectors for the exact bytes, canonical JSON is where implementations tend to drift.

---

<div class="post-metadata">

**Author:** ![tehiyadu](https://delvingbitcoin.org/user_avatar/delvingbitcoin.org/tehiyadu/32/2468_2.png) [@tehiyadu](https://delvingbitcoin.org/u/tehiyadu)\
**Post date:** [October 27, 2026, 3:12pm UTC](https://delvingbitcoin.org/t/bip-draft-co-signer-spending-policies/2955/3 "2026-10-27T15:12:46Z")

</div>

The policy hash should commit to the exact verifier semantics, not merely a parseable document. In particular, define whether unknown fields are rejected, how duplicate keys are handled, and whether defaults are explicit; otherwise two implementations could accept the same bytes but enforce different conditions. This is separate from choosing JSON or TLV. I’d also domain-separate the policy commitment from statement and transaction hashes, and include the format version in its preimage.

---

<div class="post-metadata">

**Author:** ![lukecarriere](https://delvingbitcoin.org/user_avatar/delvingbitcoin.org/lukecarriere/32/2409_2.png) [@lukecarriere](https://delvingbitcoin.org/u/lukecarriere)\
**Post date:** [October 28, 2026, 2:37pm UTC](https://delvingbitcoin.org/t/bip-draft-co-signer-spending-policies/2955/4 "2026-10-28T14:37:19Z")

</div>

Thanks, agreed. The draft defines the policy ID as the BIP340 tagged hash (tag `CSP/policy`) of the canonical serialization, but it doesn’t pin down what the verifier does with that document. I’ll add these rules, independent of JSON vs TLV:

- Unknown fields make the policy invalid, and a co-signer MUST refuse to sign under it. Extensions go through new profile versions, not ignored fields.
- Duplicate keys make the policy invalid.
- There are no implicit defaults. Every field is serialized explicitly, so the hashed bytes are exactly the conditions enforced.
- The format version is the first field in the preimage, and the tag becomes `CSP/policy/v0` to match `CSP/statement/v0`.

Policy and statement commitments already use separate tags. I’ll say explicitly that every CSP tag is distinct from the BIP340/341 tags, and I’ll add test vectors that include rejected documents (unknown field, duplicate key, missing field), alongside the exact-bytes vectors @PREDGE asked for.

---

<div class="post-metadata">

**Author:** ![lukecarriere](https://delvingbitcoin.org/user_avatar/delvingbitcoin.org/lukecarriere/32/2409_2.png) [@lukecarriere](https://delvingbitcoin.org/u/lukecarriere)\
**Post date:** [October 28, 2026, 2:38pm UTC](https://delvingbitcoin.org/t/bip-draft-co-signer-spending-policies/2955/5 "2026-10-28T14:38:05Z")

</div>

Thanks, good catch. As written, `statement-v0` signs event ID, outcome and timestamp, and says nothing about whether the outcome can still change, so a co-signer could act on a first answer that’s later corrected. I’ll add a finality flag to the signed tuple and let evidence conditions require it. The escrow example will require a final statement, and it will note that a template can wait out a dispute window instead when an attestor never marks finality. Attestations that use DLC nonce pre-commitment are already effectively final, since signing two outcomes for one event reveals the attestor’s key. Agreed on test vectors for the exact policy ID bytes. They’ll ship with whichever serialization wins.
