Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
183 commits
Select commit Hold shift + click to select a range
a1b3e12
Add FROST migration scaffold package and RFC
Feb 19, 2026
2d0a5c8
Set Schnorr/FROST RFC author to Threshold Labs
Feb 19, 2026
fc58fed
Wire tbtc runtime signing flow to frost signature types
Feb 20, 2026
2702c7a
Add FROST retry and coordinator attempt metadata path
Feb 20, 2026
3fc7c9f
Fix triplet retry eligibility to use third operator seat count
Feb 20, 2026
b57775a
Add pluggable FROST signing backend execution seam
Feb 20, 2026
952946f
Wire tbtc config to selectable FROST signing backend
Feb 20, 2026
0df807c
Add native FROST signing backend scaffold
Feb 20, 2026
7817a13
Expose tbtc FROST signing backend CLI flag
Feb 20, 2026
fc4c750
Add build-tagged native FROST adapter bootstrap
Feb 20, 2026
f85b3d5
Test FROST backend selection in node startup
Feb 20, 2026
01ea9f4
Execute native-tag FROST adapter via legacy bridge
Feb 20, 2026
9734656
Harden backend-state test guidance after interim review
Feb 20, 2026
f57aa09
Add native bridge scaffold with fallback routing
Feb 20, 2026
7efb2f9
Split native and ffi backend fallback semantics
Feb 20, 2026
e42bf43
Fail fast for strict ffi mode availability
Feb 20, 2026
606e73d
Add dynamic native bridge registration for ffi
Feb 20, 2026
d007635
Register build-tagged bridge for strict ffi path
Feb 20, 2026
8e23f5e
frost/signing: add ffi executor registration path
Feb 20, 2026
ed642b2
frost/signing: restore mode on failed backend selection
Feb 20, 2026
74e894c
frost/signing: decouple request signer material from tecdsa share
Feb 20, 2026
656f62f
frost/tbtc: thread generic signer material through execute request
Feb 20, 2026
83bf3af
frost/signing: add native signer material and ffi adapter contract
Feb 20, 2026
3083e15
frost/signing: include transport context in ffi adapter request
Feb 21, 2026
31026eb
tbtc: persist native signer material envelope in signer state
Feb 21, 2026
a1525a0
frost/native: fallback when ffi signer material is unavailable
Feb 21, 2026
eeaad8f
tbtc: add signer-material resolver hook for dkg signer creation
Feb 21, 2026
4069ffe
frost/native: add provider-based build registration hooks
Feb 21, 2026
c3e8b02
frost/native: wire default transitional provider integrations
Feb 21, 2026
9aa474c
tbtc: resolve legacy signer material through build resolver on load
Feb 21, 2026
245c64c
tbtc: add frost-native legacy roundtrip migration test
Feb 21, 2026
8050396
tbtc: recover legacy key share from native envelope on load
Feb 21, 2026
6532456
tbtc: synchronize signing-done state and retransmission backoff ticks
Feb 21, 2026
8ef5071
frost/native: add v2 native round-signing protocol path
Feb 21, 2026
753bf31
tbtc: validate strict ffi path with v2 signer material
Feb 21, 2026
f765eec
Add build-tagged UniFFI native FROST signing engine scaffold
Feb 21, 2026
90caa23
tbtc: thread canonical wallet ID compatibility through chain models
Feb 21, 2026
a49e35d
tbtc: refresh bridge bindings and wire canonical wallet IDs
Feb 21, 2026
bbd1b53
tbtc: keep bridge address embed placeholder empty
Feb 21, 2026
b418549
tbtc: lower expected wallet closure resolution miss to debug
Feb 22, 2026
5d0b9da
tbtc: add wallet-id fallback coverage for ethereum adapter
Feb 22, 2026
8f9016d
feat(frost): scaffold tbtc-signer native engine registration
mswilkison Feb 23, 2026
db36fa0
refactor(frost): scaffold coarse tbtc-signer session engine path
mswilkison Feb 23, 2026
abe32f9
Add frost_tbtc_signer material payload and legacy fallback shim
mswilkison Feb 23, 2026
7d74326
Address Claude review blockers in tbtc-signer scaffold
mswilkison Feb 23, 2026
e837a32
Add tbtc-signer fallback telemetry and metric wiring
mswilkison Feb 23, 2026
f2ad3ae
Wire tbtc-signer cgo bridge with runtime symbol resolution
mswilkison Feb 23, 2026
b82db05
Add bridge payload/response tests for tbtc-signer cgo engine
mswilkison Feb 23, 2026
4ff5405
Add RunDKG support to tbtc-signer coarse bridge
mswilkison Feb 23, 2026
29a46ab
Invoke RunDKG in transitional tbtc-signer signing path
mswilkison Feb 23, 2026
af5fe87
Gate coarse round scaffold on bootstrap tbtc-signer version
mswilkison Feb 23, 2026
b953dc5
Treat RunDKG key-group as authoritative for legacy scaffold source
mswilkison Feb 23, 2026
5a9ea5b
Make bootstrap synthetic contributions deterministic and round-bound
mswilkison Feb 23, 2026
8ec68f3
Harden bootstrap gate and fallback diagnostics
mswilkison Feb 23, 2026
1c36eb5
Plumb tbtc-signer bootstrap contributions over channel
mswilkison Feb 23, 2026
f6e1943
Plumb member-scoped StartSignRound contributions
mswilkison Feb 23, 2026
cfc38dc
Pass signing participants into tbtc-signer start round
mswilkison Feb 24, 2026
9f555e6
Add threshold-cohort coverage for tbtc-signer bootstrap round
mswilkison Feb 24, 2026
69e8442
Add bootstrap attempt-variation cohort conflict coverage
mswilkison Feb 24, 2026
9ff8804
Add native FROST cohort attempt-variation coverage
mswilkison Feb 24, 2026
d63d08b
Add signer-executor cohort retry integration coverage
mswilkison Feb 24, 2026
7814f81
Add tbtc-signer runtime cohort retry integration test
mswilkison Feb 24, 2026
7f7b9a2
Fix coarse-round participant validation and member derivation consist…
mswilkison Feb 24, 2026
7012a16
Run gofmt on signing request struct
mswilkison Feb 24, 2026
ad2aeb5
Fix tbtc signer material symbols for non-frost builds
mswilkison Feb 24, 2026
a7157c9
Update tbtcpg LocalChain test double for BridgeChain method
mswilkison Feb 24, 2026
d4e8323
Make tbtc bridge access resilient to generated API variants
mswilkison Feb 24, 2026
c372eff
Harden V2 wallet event reflection and expand coverage
mswilkison Feb 24, 2026
a71975e
Stabilize tbtc signer tests for native material migration
mswilkison Feb 24, 2026
4582710
Pass explicit signing participants to tbtc-signer StartSignRound (#3868)
mswilkison Feb 24, 2026
f7f618d
Scaffold frost_tbtc_signer native engine registration (#3867)
mswilkison Feb 24, 2026
661febf
Merge remote-tracking branch 'origin/main' into feat/frost-schnorr-mi…
mswilkison Feb 24, 2026
baf63ea
Switch tbtc-signer bootstrap path to coarse signature output
mswilkison Feb 24, 2026
71b33ec
Document decode validation boundary and test decode-fallback path
mswilkison Feb 24, 2026
346e87b
Add coarse-signature success telemetry
mswilkison Feb 24, 2026
c14712a
Document coarse observer scope and nil-observer no-op
mswilkison Feb 24, 2026
98301c9
Guard tbtc-signer telemetry observer re-registration
mswilkison Feb 24, 2026
1b483cd
Wire BuildTaprootTx through keep-core wallet orchestration
mswilkison Feb 25, 2026
a11cbfa
Split native bridge operation errors and compare BuildTaprootTx IO
mswilkison Feb 25, 2026
a8e1513
Gate BuildTaprootTx signing substitution on verified native tx IO
mswilkison Feb 25, 2026
bd9efb6
Add end-to-end tests for BuildTaprootTx substitution path
mswilkison Feb 25, 2026
9a708a6
Harden BuildTaprootTx substitution E2E coverage
mswilkison Feb 25, 2026
3743421
Harden native BuildTaprootTx structural divergence checks
mswilkison Feb 25, 2026
016f2f7
Clean up legacy BuildTaprootTx IO divergence path
mswilkison Feb 25, 2026
2454c3e
Remove dead unsigned input reference converter
mswilkison Feb 25, 2026
7dff0d2
Reject signed data in unsigned transaction replacement
mswilkison Feb 25, 2026
4490ac4
Add detailed BuildTaprootTx divergence diagnostics
mswilkison Feb 26, 2026
5451d92
Harden ReplaceUnsignedTransaction against pre-populated signing data …
mswilkison Feb 26, 2026
03665fd
Cut over bootstrap tbtc-signer path to coarse signature output (#3869)
mswilkison Feb 26, 2026
69b5ffa
Classify tbtc-signer operation errors as bridge failures
mswilkison Feb 26, 2026
1c2ea9f
Apply review follow-ups for bridge error taxonomy
mswilkison Feb 26, 2026
8da4253
Harden BuildTaprootTx error-path tests
mswilkison Feb 26, 2026
ff5c0b7
Harden tbtc-signer bridge error classification (#3871)
mswilkison Feb 26, 2026
d4e95c5
Remove UniFFI SDK dependency path from frost-native build
mswilkison Feb 26, 2026
106642d
Remove dead UniFFI legacy registration stubs
mswilkison Feb 26, 2026
b10fd0c
frost/signing: enforce attempt coordinator inclusion policy
mswilkison Feb 27, 2026
5f23834
frost/signing: enforce attempt coordinator inclusion policy (#3872)
mswilkison Feb 27, 2026
99294e2
frost/signing: fail closed on invalid coarse attempt policy
mswilkison Feb 27, 2026
53bae0c
frost/signing: fail closed on invalid coarse attempt policy (#3873)
mswilkison Feb 27, 2026
b19e57c
frost/signing: add coarse attempt-policy error matrix coverage
mswilkison Feb 27, 2026
85f843c
frost/signing: add coarse attempt-policy error matrix coverage (#3874)
mswilkison Feb 27, 2026
1415e04
fix: address gosec G118 context cancellation findings
mswilkison Feb 27, 2026
7a0b24a
fix: annotate scheduler cancel lifecycle for gosec
mswilkison Feb 27, 2026
23b3b94
fix: address gosec G118 context cancellation findings (#3875)
mswilkison Feb 27, 2026
d1eaa11
frost-signing: fail-close consumed attempt replay errors
mswilkison Feb 27, 2026
4d194b9
frost-signing: fail-close consumed attempt replay errors (#3876)
mswilkison Feb 27, 2026
c3d6833
test(frost): add Gemini audit coverage for ffi error payloads
mswilkison Mar 1, 2026
37b2ce7
Merge remote-tracking branch 'origin/main' into HEAD
mswilkison May 17, 2026
6ed1b48
Fail closed on native FROST registration without crashing at init
mswilkison May 22, 2026
1fbf4a2
Refuse scaffold key-group by default; tighten witness and message hyg…
mswilkison May 22, 2026
fb62f20
Refuse scaffold FFI signing path without operator opt-in
mswilkison May 22, 2026
c70bec8
Prefer FFI error code over substring for replay detection
mswilkison May 22, 2026
03c4b99
docs(rfc): add RFC-21 ROAST coordinator, retry, and transition evidence
mswilkison May 22, 2026
f2f1e99
docs(rfc): fold review feedback into RFC-21
mswilkison May 22, 2026
6d35153
fix(frost): fail closed on native FROST registration without crashing…
mswilkison May 22, 2026
df53906
fix(frost): refuse scaffold key-group by default; tighten witness and…
mswilkison May 22, 2026
8546179
fix(frost): refuse scaffold FFI signing path without operator opt-in …
mswilkison May 22, 2026
e72867a
fix(frost): prefer FFI error code over substring for replay detection…
mswilkison May 22, 2026
5e7e8c4
docs(rfc): RFC-21 ROAST coordinator, retry, and transition evidence (…
mswilkison May 22, 2026
240186d
feat(frost/roast): RFC-21 Phase 1 -- AttemptContext type and canonica…
mswilkison May 22, 2026
cb26865
fix(frost/roast): explicitly discard byteWriter Write results
mswilkison May 22, 2026
65f3963
feat(frost/signing): RFC-21 Phase 1B -- optional AttemptContextHash f…
mswilkison May 22, 2026
62106ba
feat(frost/roast): RFC-21 Phase 1 -- AttemptContext type and canonica…
mswilkison May 22, 2026
a43a16c
feat(frost/signing): RFC-21 Phase 1B -- optional AttemptContextHash o…
mswilkison May 22, 2026
e72b695
fix(frost/signing): gate RFC-21 Phase 1B binding with frost_native bu…
mswilkison May 22, 2026
ea16280
fix(frost/signing): gate RFC-21 Phase 1B binding with frost_native bu…
mswilkison May 22, 2026
84cffcd
feat(frost/roast): RFC-21 Phase 2 -- receiver overflow tracking (no-o…
mswilkison May 22, 2026
266272c
feat(frost/roast): RFC-21 Phase 2 -- receiver overflow tracking (no-o…
mswilkison May 22, 2026
832d529
docs(rfc): lock RFC-21 Phase-3 design decisions
mswilkison May 23, 2026
6214eec
docs(rfc): lock RFC-21 Phase-3 design decisions (#3967)
mswilkison May 23, 2026
7f59fc4
feat(frost/roast): RFC-21 Phase 3.1 -- coordinator skeleton + seed br…
mswilkison May 23, 2026
cd7e222
fix(frost/roast): gofmt the TestAttemptState_String table
mswilkison May 23, 2026
d7e0546
feat(frost/roast): RFC-21 Phase 3.2 -- TransitionMessage + LocalEvide…
mswilkison May 23, 2026
634b2ed
feat(frost/roast): RFC-21 Phase 3.3 -- aggregation + bundle verification
mswilkison May 23, 2026
6f3c1ce
feat(frost/roast): RFC-21 Phase 3.4 -- NextAttempt policy + thresholds
mswilkison May 23, 2026
2f1fd39
feat(frost/roast): RFC-21 Phase 3.1 -- coordinator skeleton + seed br…
mswilkison May 23, 2026
d9450ed
feat(frost/roast): RFC-21 Phase 3.2 -- TransitionMessage + LocalEvide…
mswilkison May 23, 2026
786cead
feat(frost/roast): RFC-21 Phase 3.3 -- aggregation + bundle verificat…
mswilkison May 23, 2026
3813a62
feat(frost/roast): RFC-21 Phase 3.4 -- NextAttempt policy + threshold…
mswilkison May 23, 2026
3a6da01
feat(frost/signing): RFC-21 Phase 4.1 -- frost_roast_retry registry
mswilkison May 23, 2026
1438837
feat(frost/signing): RFC-21 Phase 4.2 -- receive loops opt into bound…
mswilkison May 23, 2026
4431a29
feat(frost/signing): RFC-21 Phase 4.3 -- submit signed snapshots on a…
mswilkison May 23, 2026
946256a
feat(frost/roast): RFC-21 Phase 4.4 -- multi-coordinator soak harness
mswilkison May 23, 2026
3992044
feat(frost/signing): RFC-21 Phase 4.1 -- frost_roast_retry registry (…
mswilkison May 23, 2026
93f54ee
feat(frost/signing): RFC-21 Phase 4.2 -- receive loops opt into bound…
mswilkison May 23, 2026
2fb9dfd
feat(frost/signing): RFC-21 Phase 4.3 -- submit signed snapshots on a…
mswilkison May 23, 2026
e2cf63f
feat(frost/roast): RFC-21 Phase 4.4 -- multi-coordinator soak harness…
mswilkison May 23, 2026
dc53455
docs(rfc): refine RFC-21 Phase 5/6 scope and add TTL backstop
mswilkison May 23, 2026
27629f3
feat(frost/roast): RFC-21 Phase 5.1 -- retry adapter scaffolding
mswilkison May 23, 2026
ccea33e
feat(frost/signing): RFC-21 Phase 5.2 -- orchestration helpers + TTL …
mswilkison May 23, 2026
3af8ba2
feat(frost/signing): RFC-21 Phase 5.3 -- readiness-gate env-var guard
mswilkison May 23, 2026
75587b0
docs(rfc): refine RFC-21 Phase 5/6 scope and add TTL backstop (#3976)
mswilkison May 23, 2026
a760b98
feat(frost/roast): RFC-21 Phase 5.1 -- retry adapter scaffolding (#3977)
mswilkison May 23, 2026
1bbe669
feat(frost/signing): RFC-21 Phase 5.2 -- orchestration helpers + TTL …
mswilkison May 23, 2026
f8c5d7b
feat(frost/signing): RFC-21 Phase 5.3 -- readiness-gate env-var guard…
mswilkison May 23, 2026
d771896
docs(rfc): RFC-21 Phase-6 error-handling discipline + V1 prerequisite
mswilkison May 23, 2026
dba0af4
feat(frost/signing): RFC-21 Phase 6.1 -- DKG group-public-key extraction
mswilkison May 23, 2026
1e14899
feat(frost/signing): RFC-21 Phase 6.2 -- BuildAttemptContextFromRequest
mswilkison May 23, 2026
fcadd9b
feat(frost/signing): RFC-21 Phase 6.3 -- wire orchestration at execut…
mswilkison May 23, 2026
9c38f76
feat(tbtc): RFC-21 Phase 6.4 -- signing-loop participant-selection di…
mswilkison May 23, 2026
86a5446
feat(frost/signing): RFC-21 Phase 7.1 -- AggregateBundle + bundle reg…
mswilkison May 23, 2026
df78854
feat(tbtc): RFC-21 Phase 7.2 -- ROAST-driven signingParticipantSelector
mswilkison May 23, 2026
889b53a
docs: add FROST/ROAST retry rollout guide
mswilkison May 23, 2026
0f8b518
docs(rfc): RFC-21 Phase-6 error-handling discipline + V1 prerequisite…
mswilkison May 23, 2026
bc28176
feat(frost/signing): RFC-21 Phase 6.1 -- DKG group-public-key extract…
mswilkison May 23, 2026
6aab2fc
feat(frost/signing): RFC-21 Phase 6.2 -- BuildAttemptContextFromReque…
mswilkison May 23, 2026
3d2ff18
feat(frost/signing): RFC-21 Phase 6.3 -- wire orchestration at execut…
mswilkison May 23, 2026
6472a40
feat(tbtc): RFC-21 Phase 6.4 -- signing-loop participant-selection di…
mswilkison May 23, 2026
9f4590e
feat(frost/signing): RFC-21 Phase 7.1 -- AggregateBundle + bundle reg…
mswilkison May 23, 2026
57de054
feat(tbtc): RFC-21 Phase 7.2 -- ROAST-driven signingParticipantSelect…
mswilkison May 23, 2026
1a2c733
docs: add FROST/ROAST retry rollout guide (#3987)
mswilkison May 23, 2026
ba612b2
feat(frost/roast): close M4 -- reject + conflict evidence categories
mswilkison May 23, 2026
999ceae
feat(frost/signing): enforce AttemptContextHash on receive (RFC-21 Ph…
mswilkison May 23, 2026
d8a1d79
feat(frost/signing): expose ROAST-retry evidence counters via clientinfo
mswilkison May 23, 2026
9bc93c1
feat(frost/roast): close M4 -- reject + conflict evidence categories …
mswilkison May 23, 2026
1597e8f
feat(frost/signing): enforce AttemptContextHash on receive (RFC-21 Ph…
mswilkison May 23, 2026
ed0a2e2
feat(frost/signing): expose ROAST-retry evidence counters via clienti…
mswilkison May 23, 2026
c8221b0
docs(frost/signing): canonicalize the static-vs-runtime error taxonomy
mswilkison May 23, 2026
32cf468
test(frost): cross-repo walletPubKeyHash derivation fixture
mswilkison May 23, 2026
ad5ae96
fix(frost): gofmt -- derivationFixture struct field alignment
mswilkison May 23, 2026
dc7adef
fix(frost): split test-path and repo-path constants; resolve fixture …
mswilkison May 23, 2026
da5f833
docs(frost/signing): canonicalize the static-vs-runtime error taxonom…
mswilkison May 24, 2026
90e0b2a
test(frost): cross-repo walletPubKeyHash derivation fixture (#3994)
mswilkison May 24, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions cmd/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,15 @@ func initTbtcFlags(cmd *cobra.Command, cfg *config.Config) {
tbtc.DefaultKeyGenerationConcurrency,
"tECDSA key generation concurrency.",
)

cmd.Flags().StringVar(
&cfg.Tbtc.FrostSigningBackend,
"tbtc.frostSigningBackend",
"",
"FROST signing backend name (legacy, native, ffi). "+
"`native` allows transitional legacy fallback; `ffi` requires native execution. "+
"Empty value selects legacy.",
)
}

// Initialize flags for Maintainer configuration.
Expand Down
7 changes: 7 additions & 0 deletions cmd/flags_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,13 @@ var cmdFlagsTests = map[string]struct {
expectedValueFromFlag: 101,
defaultValue: runtime.GOMAXPROCS(0),
},
"tbtc.frostSigningBackend": {
readValueFunc: func(c *config.Config) interface{} { return c.Tbtc.FrostSigningBackend },
flagName: "--tbtc.frostSigningBackend",
flagValue: "native",
expectedValueFromFlag: "native",
defaultValue: "",
},
"maintainer.bitcoinDifficulty": {
readValueFunc: func(c *config.Config) interface{} { return c.Maintainer.BitcoinDifficulty.Enabled },
flagName: "--bitcoinDifficulty",
Expand Down
132 changes: 132 additions & 0 deletions docs/development/frost-roast-retry-rollout.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
= FROST/ROAST Retry Rollout Guide

*Author:* Threshold Labs
*Status:* Draft
*Date:* 2026-05-23

== Summary

This document describes the operational lifecycle of the
ROAST-driven retry path introduced by RFC-21
(`docs/rfc/rfc-21-roast-coordinator-retry-and-transition-evidence.adoc`)
and implemented across Phases 1-7 of that RFC. It is intended for
node operators and release engineers planning a rollout of the new
retry semantics.

The feature ships as a build-tagged code path. A production
binary built without the tag contains *no ROAST retry code*;
every signing flow uses the pre-RFC-21 legacy retry shuffle. A
binary built with the tag still executes the legacy path unless
the operator explicitly opts in via an environment variable, and
even then the new path silently falls back to legacy whenever its
preconditions are not met.

== Activation prerequisites

All three must be true at the same time for the ROAST retry path
to influence participant selection on a given session attempt:

. *Build tag set.* The keep-core binary is built with
`-tags frost_roast_retry`. Without the tag, the dispatcher
package does not include the ROAST selector at all.
. *Operator opt-in env var.* The runtime environment defines
`KEEP_CORE_FROST_ROAST_RETRY_ENABLED=true` (case-insensitive,
whitespace-trimmed). The variable is read per call (not
cached), so an operator can flip the switch during a debugging
session without restarting the node.
. *Coordinator registered.* A caller has invoked
`signing.RegisterRoastRetryCoordinator(deps)` at process
startup with the node's operator-key signer, the network's
signature verifier, and the node's member index.

When any of these is missing, the receive loops, executor
adapter, and signing-loop selector all behave as in the legacy
pre-RFC-21 path. The behavioural rollback is therefore *configuration-
only*: toggle the env var off and the next signing attempt uses
the legacy retry shuffle.

== Behavioural matrix

[options="header"]
|===
| Build tag | Env var | Registry | Bundle present | Behaviour
| not set | _any_ | _any_ | _any_ | Legacy retry shuffle
| set | unset | _any_ | _any_ | Legacy retry shuffle (env-var gate)
| set | true | empty | _any_ | Legacy retry shuffle (no coordinator)
| set | true | populated | absent | Legacy retry shuffle (first attempt / no transition yet)
| set | true | populated | present | ROAST `EvaluateRoastRetryForSigning`
|===

The bundle is "present" once the elected coordinator's node has
produced a `TransitionMessage` at the end of a prior attempt
(see Phase 7.1 in RFC-21). Until that happens, the ROAST path is
dormant and the legacy path provides liveness.

== Error handling discipline

The orchestration layer distinguishes two error classes:

* *Static-configuration errors.* Env var unset, no coordinator
registered, signer-material format not extractable. These are
deterministic per deployment configuration: every honest signer
observes the same outcome. Logged at INFO, signing flow
continues with the legacy retry shuffle.

* *Runtime state-machine errors.* `Coordinator.BeginAttempt`
failures, internal invariant violations,
`ErrAttemptInfeasible` from the policy's threshold floor. These
are non-deterministic across nodes. Treated as *hard failures*:
the session is declared failed and the operator is notified
via the standard signing-failure log path. Falling back to
legacy on these errors would let one node use legacy retry
while another uses ROAST, which would split the signing group
on `NextAttempt` agreement.

This discipline is the load-bearing safety property of the
RFC-21 design and is enforced in
`pkg/frost/signing/roast_retry_executor_entry_frost_native.go`.

== Production rollout sequencing

. *Build the binary with the tag.* Internal builds and CI
pipelines already exercise the tag via
`go test -tags 'frost_roast_retry' ./pkg/frost/... ./pkg/tbtc/...`.
Production binaries adopt the tag once the readiness manifest
in the cross-repo tBTC monorepo's `docs/operations/` directory
flips to `present`.
. *Verify FROST/UniFFI V1 migration.* The DKG-pubkey extraction
helper rejects FrostUniFFIV1 signer material. The Phase 7
manifest flip is gated on verified migration off V1 across
production signers; until that migration completes, ROAST
retry would silently fall back to legacy on V1-bearing nodes.
. *Stage operator opt-in.* Operators set
`KEEP_CORE_FROST_ROAST_RETRY_ENABLED=true` on a subset of nodes
first. Static-configuration fallback guarantees mixed-state
deployments stay correct: nodes without the env var simply use
legacy. Beware: a node with the env var set but no registered
coordinator (e.g., due to a misconfigured startup script) still
uses legacy, so the safety property holds.
. *Monitor for runtime hard-failures.* The "ROAST orchestration"
log lines under
`keep-frost-roast-orchestration` and
`keep-frost-roast-retry` loggers indicate transitions of the
new state machine. A spike in WARN/ERROR entries from these
loggers is the early signal of trouble.
. *Roll back via env var.* If anything misbehaves, unset
`KEEP_CORE_FROST_ROAST_RETRY_ENABLED` and restart (or wait for
the per-call check to flip the next attempt). The legacy code
paths are retained through Phase 6 and 7 deliberately to make
this rollback bit-for-bit safe.

== Cross-references

* RFC-21: `docs/rfc/rfc-21-roast-coordinator-retry-and-transition-evidence.adoc`
* Build-tag scaffolding: `pkg/frost/signing/roast_retry_registration_*.go`
* Orchestration entry point: `pkg/frost/signing/roast_retry_orchestration.go`
* Executor-adapter wiring: `pkg/frost/signing/native_ffi_executor_adapter.go`
* Signing-loop dispatcher: `pkg/tbtc/signing_loop_roast_dispatcher.go`
* ROAST-driven selector: `pkg/tbtc/signing_loop_selector_frost_roast_retry.go`
* Bundle registry: `pkg/frost/signing/roast_retry_bundle_registry_*.go`
* Readiness env var: `pkg/frost/signing/roast_retry_readiness.go`
* Coordinator state machine: `pkg/frost/roast/coordinator_state.go`
* Adapter type: `pkg/frost/roast/signing_retry_adapter.go`
49 changes: 49 additions & 0 deletions docs/rfc/rfc-20-schnorr-frost-migration-scaffold.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
= RFC-20: Schnorr/FROST Migration Scaffold

*Author:* Threshold Labs
*Status:* Draft
*Date:* 2026-02-19

== Summary

This RFC introduces the initial keep-core scaffolding for migrating tBTC from
threshold ECDSA signatures to Schnorr/FROST signatures.

This change does not switch runtime signing logic yet. It defines core data
types and compatibility helpers required by follow-up protocol, chain, and
wallet orchestration changes.

== Initial Deliverables

* New `pkg/frost` package with:
** Taproot x-only output key type (`OutputKey`)
** BIP-340 Schnorr signature type (`Signature`)
** Serialization and logging helpers for Schnorr signatures
** Legacy compatibility alias helper:
`HASH160(0x02 || xOnlyOutputKey)`

== Compatibility Model

FROST wallets are expected to use 32-byte x-only keys as canonical identifiers.
During migration, legacy 20-byte wallet key hash paths are supported via
compatibility alias:

----
walletPubKeyHashCompat = HASH160(0x02 || xOnlyOutputKey)
----

== Follow-up Work

1. Add FROST signer and coordinator interfaces to replace `pkg/tecdsa/signing`.
2. Introduce FROST DKG executor replacing GG18 pre-params and DKG wiring.
3. Update tBTC chain interfaces and wallet registry integration to accept
x-only keys as canonical wallet identities.
4. Update Bitcoin transaction builders to support P2TR key-path spends.
5. Add dual-stack runtime routing: GG18 existing wallets + FROST new wallets.
6. Add full integration tests for mixed wallet generations and migration flows.

== Non-Goals (This RFC Revision)

* No production FROST coordinator implementation.
* No on-chain contract ABI migration in this repository.
* No replacement of existing GG18 runtime paths yet.
Loading