Skip to content

Draft (Umbrella): keep-core FROST/ROAST migration scaffold tracker (not for direct merge)#3866

Draft
mswilkison wants to merge 107 commits intomainfrom
feat/frost-schnorr-migration-scaffold
Draft

Draft (Umbrella): keep-core FROST/ROAST migration scaffold tracker (not for direct merge)#3866
mswilkison wants to merge 107 commits intomainfrom
feat/frost-schnorr-migration-scaffold

Conversation

@mswilkison
Copy link

@mswilkison mswilkison commented Feb 19, 2026

Final State (as of 2026-03-01)

This draft PR is the umbrella scaffold tracker for branch feat/frost-schnorr-migration-scaffold.
It is intentionally not intended for direct merge.

Runtime/signing behavior changes associated with this scaffold have been integrated through stacked PRs and validated via phase-gated packets and independent reviews.

Canonical Status Sources

Remaining Cross-Repo Closure Items

  • Capture the first post-fix funded nightly live run artifact for Phase 4.
  • Record final approver signoff in the Phase 4 decision/packet docs.
  • Execute external org archive/redirect mapping and record results.

Notes

  • Keep this PR in draft as historical architecture/audit context rather than a merge target.

@mswilkison mswilkison changed the title Draft: Add Schnorr/FROST migration scaffold package and RFC Draft: Add Schnorr/FROST scaffold and tBTC runtime signing adapter slice Feb 20, 2026
maclane added 26 commits February 20, 2026 09:30
…3870)

## Summary
- reject replacement inputs that already contain non-empty signature
script data
- reject replacement inputs that already contain non-empty witness data
- remove unreachable loop bounds guard in replacement path
- add targeted unit coverage for both replacement rejection paths
- add field-level divergence diagnostics for native `BuildTaprootTx`
unsigned transaction comparison (version/locktime/input
refs/sequences/outputs)
- include divergence detail in both substitution errors and
observational warnings to speed root-cause triage
- add test assertions for detailed divergence reasons in
`evaluateNativeUnsignedTransactionForSigning` and wallet transaction
signing paths
- document session-id derivation stability expectations for native
`BuildTaprootTx`

## Why
- replacement API expects an unsigned transaction skeleton
- pre-populated signing data can silently alter placeholder preservation
behavior
- generic "diverges" messages slow down cross-language mismatch
debugging during rollout

## Validation
- `go test ./pkg/bitcoin -run
TestTransactionBuilder_ReplaceUnsignedTransaction`
- `go test ./pkg/tbtc -run
'TestWalletTransactionExecutor_SignTransaction_|TestEvaluateNativeUnsignedTransactionForSigning_|TestNativeBuildTaprootTxSigningSubstitutionEnabled'`
## Summary
- cut over the `frost_tbtc_signer` bootstrap path to return coarse
tbtc-signer signature output on successful `RunDKG -> StartSignRound ->
FinalizeSignRound`
- keep legacy signing fallback only for verified coarse-path failures
(bridge errors, decode failures, or structural divergence)
- wire `BuildTaprootTx` through the transitional native tbtc-signer
orchestration path
- gate `BuildTaprootTx` signing substitution on strict native-vs-legacy
transaction input/output equivalence checks
- add coarse success/fallback telemetry and observer-registration guards
- expand unit and integration coverage for coarse cutover,
retry/attempt-variation behavior, and `BuildTaprootTx` substitution
safety

## Stack Context
- base branch: `feat/frost-schnorr-migration-scaffold` (`#3866`)
- recommended review order:
  1. review `#3866` for scaffold/runtime seams
  2. review this PR as the cutover + hardening delta

## Review Guide (hot paths)
- coarse cutover + fallback semantics:
- `pkg/frost/signing/native_ffi_primitive_transitional_frost_native.go`
-
`pkg/frost/signing/native_frost_engine_tbtc_signer_registration_frost_native.go`
- `BuildTaprootTx` wiring and substitution gating:
  - `pkg/tbtc/wallet.go`
-
`pkg/tbtc/native_tbtc_signer_build_taproot_tx_frost_native_tbtc_signer.go`
  - `pkg/bitcoin/transaction_builder.go`
- coverage for tx assembly/substitution and bridge safety:
  - `pkg/tbtc/wallet_sign_transaction_build_taproot_tx_test.go`
  - `pkg/bitcoin/transaction_builder_test.go`
-
`pkg/frost/signing/native_frost_engine_tbtc_signer_registration_frost_native_test.go`

## Scope Boundaries
- in scope: bootstrap/coarse-path cutover hardening and safe
`BuildTaprootTx` integration
- out of scope: full production signer-runtime replacement and later
migration phase gates
## Summary
- classify `buildTaggedTBTCSignerOperationError` as
`ErrNativeBridgeOperationFailed` instead of
`ErrNativeCryptographyUnavailable`
- keep `ErrNativeCryptographyUnavailable` reserved for true bridge
unavailability (`status_code == -1`)
- update tbtc-signer registration/build payload/response validation
tests to assert operational failures are not treated as availability
failures
- collapse duplicate bridge-operation error constructor usage to a
single helper path
- add an explicit wallet boundary test that
`ErrNativeBridgeOperationFailed` propagates through `signTransaction`
(not swallowed by unavailability fallback)
- preserve wrapped error identity in the BuildTaprootTx signing path
(`%w`) so taxonomy can be asserted at caller boundaries
- remove the stale BuildTaprootTx fallback comment now that bridge error
classification is explicit

## Why
- observational BuildTaprootTx fallback should trigger only when native
cryptography is genuinely unavailable
- local/bridge operation failures should remain surfaced as actionable
errors and must not be misclassified as unavailable
- integration-boundary tests should lock the taxonomy guarantee before
signing substitution

## Validation
- `go test -tags 'frost_native frost_tbtc_signer' ./pkg/frost/signing`
- `go test -tags 'frost_native frost_tbtc_signer' ./pkg/tbtc -run
'TestWalletTransactionExecutor_SignTransaction_ReturnsBuildTaprootTxError|TestWalletTransactionExecutor_SignTransaction_PropagatesBuildTaprootTxBridgeOperationError|TestEvaluateNativeUnsignedTransactionForSigning_|TestWalletTransactionExecutor_SignTransaction_'`
## Summary
- enforce native attempt policy in shared included-member derivation
used by native FROST and tbtc-signer coarse paths
- reject zero attempt number, zero coordinator, coordinator not in
included cohort, and included/excluded overlap
- update attempt-variation tests to provide explicit attempt metadata
and add policy rejection coverage

## Testing
- GOCACHE=/tmp/keep-core-gocache go test -count=1 -tags frost_native
./pkg/frost/signing
- GOCACHE=/tmp/keep-core-gocache go test -count=1 -tags frost_native
./pkg/tbtc -run
"TestConfigureFrostSigningBackend|TestNewNode_ConfiguresFrostSigningBackend|TestConfigureFrostSigningBackend_FFIStrictConfigured_BuildAdapter|TestConfigureFrostSigningBackend_FFIStrictUnavailable_NoBridge|TestSigningExecutor_Sign_NativeBackend|TestSigningExecutor_Sign_FFIStrictBackend_WithNativeSignerMaterial|TestSigningExecutor_Sign_NativeBackend_FallsBackWhenOnlyLegacySignerMaterial|TestRegisterSignerMaterialResolverForBuild"
## Summary
- classify coordinator/cohort attempt-policy violations with a dedicated
sentinel error in included-member derivation
- stop tbtc-signer coarse path from falling back to legacy signing when
attempt-policy validation fails
- add regression coverage proving invalid attempt policy does not
trigger legacy fallback even when legacy private key share is present

## Testing
- GOCACHE=/tmp/keep-core-gocache go test -count=1 -tags frost_native
./pkg/frost/signing
- GOCACHE=/tmp/keep-core-gocache go test -count=1 -tags frost_native
./pkg/tbtc -run
"TestConfigureFrostSigningBackend|TestNewNode_ConfiguresFrostSigningBackend|TestConfigureFrostSigningBackend_FFIStrictConfigured_BuildAdapter|TestConfigureFrostSigningBackend_FFIStrictUnavailable_NoBridge|TestSigningExecutor_Sign_NativeBackend|TestSigningExecutor_Sign_FFIStrictBackend_WithNativeSignerMaterial|TestSigningExecutor_Sign_NativeBackend_FallsBackWhenOnlyLegacySignerMaterial|TestRegisterSignerMaterialResolverForBuild"
## Summary
- preserve invalid-attempt sentinel identity when coarse-path policy
validation fails
- extend coarse-path fail-closed regression into a matrix for zero
attempt number, zero coordinator, coordinator-not-included, empty
included set, and overlap modes
- assert each mode returns bridge-operation-failed +
invalid-attempt-policy and does not trigger fallback/RunDKG

## Testing
- GOCACHE=/tmp/keep-core-gocache go test -count=1 -tags frost_native
./pkg/frost/signing
- GOCACHE=/tmp/keep-core-gocache go test -count=1 -tags frost_native
./pkg/tbtc -run
"TestConfigureFrostSigningBackend|TestNewNode_ConfiguresFrostSigningBackend|TestConfigureFrostSigningBackend_FFIStrictConfigured_BuildAdapter|TestConfigureFrostSigningBackend_FFIStrictUnavailable_NoBridge|TestSigningExecutor_Sign_NativeBackend|TestSigningExecutor_Sign_FFIStrictBackend_WithNativeSignerMaterial|TestSigningExecutor_Sign_NativeBackend_FallsBackWhenOnlyLegacySignerMaterial|TestRegisterSignerMaterialResolverForBuild"
Summary
- add a scoped nosec G118 annotation for withCancelOnBlock where the
cancel function is intentionally returned and also invoked by the helper
goroutine
- explicitly call cancelAnnounceCtx after Announce returns in the DKG
retry loop
- ensure scheduler worker contexts always invoke their cancel function
by storing a stop wrapper and deferring cancellation in the worker
goroutine

Why
client-scan on #3874 failed on three G118 findings (context cancel
function lifecycle). This patch resolves those findings without changing
functional behavior.

Testing
- GOCACHE=/tmp/keep-core-gocache go test -count=1 ./pkg/generator
- GOCACHE=/tmp/keep-core-gocache go test -count=1 ./pkg/tbtc
- attempted local Docker gosec scan, but image pull failed with
transient EOF in this environment
## Summary
- classify signer `attempt_id already consumed for sign attempt`
failures as non-fallback bridge errors on the coarse tbtc-signer path
- add `ErrConsumedSigningAttemptReplay` sentinel for explicit
retry-policy classification
- add regression coverage proving consumed-attempt replay does not
trigger legacy fallback

## Testing
- GOCACHE=/tmp/keep-core-gocache go test -count=1 -tags frost_native
./pkg/frost/signing -run
"ConsumedAttemptReplay|InvalidAttemptPolicy|BuildTaggedLegacyCompatibleNativeExecutionFFISigningPrimitive_Sign_TBTCSignerPath"
- GOCACHE=/tmp/keep-core-gocache go test -count=1 -tags frost_native
./pkg/tbtc -run
"TestConfigureFrostSigningBackend|TestNewNode_ConfiguresFrostSigningBackend|TestConfigureFrostSigningBackend_FFIStrictConfigured_BuildAdapter|TestConfigureFrostSigningBackend_FFIStrictUnavailable_NoBridge|TestSigningExecutor_Sign_NativeBackend|TestSigningExecutor_Sign_FFIStrictBackend_WithNativeSignerMaterial|TestSigningExecutor_Sign_NativeBackend_FallsBackWhenOnlyLegacySignerMaterial|TestRegisterSignerMaterialResolverForBuild"
@mswilkison mswilkison changed the title Draft: Add Schnorr/FROST scaffold and tBTC runtime signing adapter slice Draft (Umbrella): keep-core FROST/ROAST migration scaffold tracker (not for direct merge) Mar 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant