Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
436 commits
Select commit Hold shift + click to select a range
e9f5a8c
feat(tbtc): make attempt session IDs protocol-mode-aware in the retry…
lrsaturnino Jul 27, 2026
baa6446
fix(participation): order gate clock samples and make the cutover wai…
lrsaturnino Jul 27, 2026
375f10c
feat(tbtc,beacon): validate completion-bound inputs and derive roster…
lrsaturnino Jul 27, 2026
51f8627
feat(compatibility): add per-ceremony strategy bundle and legacy G1 h…
lrsaturnino Jul 27, 2026
5cd8036
feat(beacon): thread the compatibility strategy bundle through GJKR
lrsaturnino Jul 27, 2026
6279592
feat(cmd): construct the production participation gate at startup
lrsaturnino Jul 27, 2026
d58e1b1
fix(participation): validate height projectability as part of each cl…
lrsaturnino Jul 27, 2026
7a93228
feat(cmd,tbtc,beacon): share one gate and roster from startup through…
lrsaturnino Jul 27, 2026
6e462da
feat(beacon): pin the DKG ceremony bundle from a participation permit
lrsaturnino Jul 27, 2026
33647b1
feat(cmd): drive graceful quiescence from process signals
lrsaturnino Jul 27, 2026
d660e0e
feat(clientinfo,cmd): export the full artifact identity and gate state
lrsaturnino Jul 27, 2026
7b64e23
feat(beacon,participation): fence beacon DKG completion behind its pe…
lrsaturnino Jul 27, 2026
62bd2c4
feat(beacon,net): run every beacon relay path under a participation p…
lrsaturnino Jul 27, 2026
73ec932
fix(cmd): arm signal capture first and overflow-check the quiesce bac…
lrsaturnino Jul 27, 2026
921edce
chore(scripts): scaffold the Part A cutover rehearsal beside the port…
lrsaturnino Jul 27, 2026
7d8678f
feat(cmd): add the offline participation state audit for the rollback…
lrsaturnino Jul 27, 2026
0c8c681
fix(state,beacon): make held block waits and event callbacks cancella…
lrsaturnino Jul 27, 2026
db86c09
fix(cmd): drive quiescence from the moment the gate exists
lrsaturnino Jul 27, 2026
8eb6689
feat(cmd,tbtc): make the participation state audit conservative and c…
lrsaturnino Jul 27, 2026
daa8d8b
fix(scripts): make the rehearsal scaffold runnable and self-contained
lrsaturnino Jul 27, 2026
c02ef33
fix(state): release abandoned block-height waiters on cancellation
lrsaturnino Jul 27, 2026
a45d416
feat(tbtc): acquire participation permits and commit fences everywhere
lrsaturnino Jul 27, 2026
ab88ae9
feat(cmd): validate rollback evidence schemas and audit the tbtc quar…
lrsaturnino Jul 27, 2026
7022f49
ci(release): provision the rehearsal keystore from a repository secret
lrsaturnino Jul 27, 2026
76d1c35
fix(tbtc): wait for the wallet-action anchor before acquiring its permit
lrsaturnino Jul 27, 2026
5c8fe0f
fix(tbtc): activate DKG signers only after publication and classify g…
lrsaturnino Jul 27, 2026
c7b61cc
feat(cmd): bind rollback evidence to expected identities in the state…
lrsaturnino Jul 27, 2026
c1b57e3
fix(tbtc): make signer registration failure-atomic with the active save
lrsaturnino Jul 27, 2026
a926779
fix(tbtc): keep gate aborts out of coordination window failure accoun…
lrsaturnino Jul 27, 2026
dc29084
feat(tbtc): derive the wallet identity in the signer audit decode
lrsaturnino Jul 27, 2026
88a2cd4
feat(cmd): bind rollback evidence to exact artifacts and settlement s…
lrsaturnino Jul 27, 2026
e633819
docs(scripts): list the audit's required expected-identity inputs
lrsaturnino Jul 27, 2026
3bcf6e6
test(tbtc): cover the heartbeat inactivity band across the cutover
lrsaturnino Jul 27, 2026
b370328
test(tbtc): add signing and DKG cutover integration coverage
lrsaturnino Jul 27, 2026
2b7ebb2
docs: record the reviewed tss-lib fork as a hard release dependency
lrsaturnino Jul 27, 2026
583836d
test(tbtc): run real security-v2 DKG transcripts in the cutover suite
lrsaturnino Jul 27, 2026
4ae8b4b
test(ecdsa): prove the 100/90 DKG misbehavior boundary on chain
lrsaturnino Jul 27, 2026
b144871
test(tbtc): prove the 90/10 DKG split for real and at scale
lrsaturnino Jul 27, 2026
82d52af
build(scripts): race-run the tBTC cutover suites in the local proofs
lrsaturnino Jul 27, 2026
b9ad6ca
feat(tecdsa): carry the permit mode into every DKG/signing party
lrsaturnino Jul 27, 2026
1c6abf6
test(ecdsa): produce the boundary DKG result from active seats only
lrsaturnino Jul 27, 2026
746310c
test(tbtc): produce a real DKG result carrying all ten misbehaved seats
lrsaturnino Jul 27, 2026
77a0890
build(scripts): cover the full changed risk surface in the local proofs
lrsaturnino Jul 27, 2026
5b7f724
build(scripts): archive reproducible analyzer and contracts evidence …
lrsaturnino Jul 27, 2026
28faf2b
test(tbtc): state the production-scale split evidence precisely
lrsaturnino Jul 27, 2026
6372ca9
docs(scripts): record the fork-remote check and the hardened stage co…
lrsaturnino Jul 27, 2026
89f6396
build(scripts): bind every proof stage fail-closed to the dispatched SHA
lrsaturnino Jul 27, 2026
42d2d93
build(scripts): verify the build image tree by construction, not by f…
lrsaturnino Jul 27, 2026
957c228
build(scripts): restore regenerated bindings from the dispatched comm…
lrsaturnino Jul 27, 2026
8f0c83a
docs(scripts): record the branch-tip sweep of the tss-lib fork remote
lrsaturnino Jul 27, 2026
a012b7b
feat(cmd): bind the service-manager termination grace to the release …
lrsaturnino Jul 27, 2026
63dcfa1
build(scripts): give the R1 rehearsal nodes the manifest termination …
lrsaturnino Jul 27, 2026
bef908d
feat(participation): join permit owners before the forced-shutdown exit
lrsaturnino Jul 27, 2026
f6ca0c4
fix(cmd): reject trailing bytes after the release manifest object
lrsaturnino Jul 27, 2026
c993347
build(scripts): bind rehearsal evidence records to the release manifest
lrsaturnino Jul 27, 2026
1e4d483
docs(scripts): record the runtime consumption of the cancellation all…
lrsaturnino Jul 27, 2026
1a34049
build(scripts): verify the recorded termination grace of evidence rec…
lrsaturnino Jul 28, 2026
3757a9d
fix(cmd): reserve exit headroom beyond the in-process shutdown waits
lrsaturnino Jul 28, 2026
68653df
fix(cmd): bind manifest validation to the compiled cancellation allow…
lrsaturnino Jul 28, 2026
ca4eade
docs(scripts): record the compiled-allowance identity across the mani…
lrsaturnino Jul 28, 2026
eae6328
build(scripts): self-test the evidence validator on every proof run
lrsaturnino Jul 28, 2026
32dc29f
build(scripts): attest the reviewed manifest to the compiled bounds
lrsaturnino Jul 28, 2026
47c91de
fix(scripts): bind the manifest attestation to one run at one commit
lrsaturnino Jul 28, 2026
2405f7a
build(ci): gate the rehearsal scaffold's own checkers on every change
lrsaturnino Jul 28, 2026
0fa544c
test(scripts): prove the receipt lifecycle through the proof stage it…
lrsaturnino Jul 28, 2026
43af24d
build(scripts): hold the build-context classification to the real bui…
lrsaturnino Jul 28, 2026
d14c2ef
fix(scripts): read the ignore rules the build itself reads
lrsaturnino Jul 28, 2026
fcf87b9
fix(scripts): resolve the build's ignore file from the step that buil…
lrsaturnino Jul 28, 2026
7e7c8e1
fix(scripts): read the contracts toolchain from the job the stage rep…
lrsaturnino Jul 28, 2026
a090a78
build(scripts): hold the scaffold gate to the changes that can reach it
lrsaturnino Jul 28, 2026
fbb758f
build(scripts): require the scaffold gate to actually run the analysis
lrsaturnino Jul 28, 2026
0102147
build(scripts): read the scaffold gate's invocation instead of findin…
lrsaturnino Jul 28, 2026
131ad6b
docs(scripts): record what the new reachability cases take away
lrsaturnino Jul 28, 2026
72d1cc0
fix(scripts): hold the scaffold gate to what the invocation would reach
lrsaturnino Jul 28, 2026
a0709c9
docs(scripts): stop calling the gate's own required check a closure
lrsaturnino Jul 28, 2026
2294a79
docs(scripts): record the gate's external control as the one GitHub has
lrsaturnino Jul 28, 2026
a273d08
docs(scripts): require the closing gate to be a workflow this repo ca…
lrsaturnino Jul 28, 2026
27b0a81
docs(scripts): require the enforcing ruleset to be aimed at this merge
lrsaturnino Jul 28, 2026
c51ac48
fix(scripts): hold the ruleset record to GitHub's own condition shapes
lrsaturnino Jul 28, 2026
4cb3c73
docs(scripts): read a bypass list as permission, not non-application
lrsaturnino Jul 28, 2026
4cbc73d
feat(scripts): run the two container gates instead of refusing them w…
lrsaturnino Jul 28, 2026
5fb41a3
fix(scripts): read the release identity where a node actually publish…
lrsaturnino Jul 28, 2026
b8de948
fix(scripts): probe the metric names a node exposes, not the internal…
lrsaturnino Jul 28, 2026
0adb75d
fix(scripts): stop draining nodes under the manifest's grace, not a c…
lrsaturnino Jul 28, 2026
aad8a2f
fix(scripts): read a rehearsal's failures as its verdict, not as its …
lrsaturnino Jul 28, 2026
bd72d83
fix(scripts): hold the rollback barrier to both halves it is made of
lrsaturnino Jul 28, 2026
0cfeaab
fix(scripts): hold each step to the property it names, not to a proxy
lrsaturnino Jul 28, 2026
33e1b9b
feat(scripts): prove the fleet is the artifact the record names
lrsaturnino Jul 28, 2026
4ddd5ae
feat(scripts): record the chain work a step drove, not just that it ran
lrsaturnino Jul 28, 2026
2f59a02
fix(scripts): require the clock-failure step to observe both halves o…
lrsaturnino Jul 28, 2026
190205a
fix(scripts): audit the state the rollback actually left behind
lrsaturnino Jul 28, 2026
13b3368
feat(ci): let the dispatched rehearsal run the harness it advertises
lrsaturnino Jul 28, 2026
7e1cf0c
fix(scripts): hold clock failure and quiescence to both halves they name
lrsaturnino Jul 28, 2026
5efd157
fix(scripts): evidence the straggler and homogeneous controls name
lrsaturnino Jul 28, 2026
cc3980a
fix(release): stamp and require the exact commit a released artifact …
lrsaturnino Jul 28, 2026
9978a4f
test(scripts): cover the identity comparison the exact match replaced
lrsaturnino Jul 28, 2026
24880d5
docs(scripts): describe the rehearsal the scaffold now runs
lrsaturnino Jul 28, 2026
17f8643
fix(scripts): fence every candidate on the daemon, not this project's…
lrsaturnino Jul 28, 2026
5722af7
fix(scripts): require an offer before recording a refusal
lrsaturnino Jul 28, 2026
ddeefc4
fix(scripts): generate rollback evidence for the snapshot the drain left
lrsaturnino Jul 28, 2026
db6ff9d
feat(clientinfo): publish the chain the gate actually clocks against
lrsaturnino Jul 28, 2026
73357de
fix(scripts): hold the homogeneous control to both halves of its name
lrsaturnino Jul 28, 2026
cd735cc
docs(ci): name the chain-side inputs the job now provisions
lrsaturnino Jul 28, 2026
ed88d40
feat(participation): read the connected chain per scrape, on a tested…
lrsaturnino Jul 28, 2026
8157409
fix(scripts): watch for a prior artifact across the daemon, not one s…
lrsaturnino Jul 28, 2026
d6136ae
fix(scripts): decide the post-C controls on the whole driver report
lrsaturnino Jul 28, 2026
783e9f0
fix(scripts): put the refusal on the node and follow every permit to …
lrsaturnino Jul 28, 2026
153a24a
test(scripts): bind the refusal-counter list to the gated ceremony set
lrsaturnino Jul 28, 2026
3d4aeb5
fix(scripts): restore the scaffold's own shell-analysis gate to green
lrsaturnino Jul 28, 2026
49128d4
fix(scripts): read what a container reaches, not what it owns
lrsaturnino Jul 28, 2026
8b317d2
fix(scripts): bind each driven outcome to the work it belongs to
lrsaturnino Jul 28, 2026
451a8fa
fix(scripts): credit the quiescence refusal to the work that was offered
lrsaturnino Jul 28, 2026
c23b636
fix(scripts): follow each drained permit to an outcome, not to an emp…
lrsaturnino Jul 28, 2026
4c84521
refactor(scripts): drop the unbound readings the bound records replaced
lrsaturnino Jul 28, 2026
72deb53
fix(scripts): follow each permit to the work it was issued for
lrsaturnino Jul 28, 2026
dfc6ca9
feat(scripts): bind the programs a rehearsal runs to a reviewed digest
lrsaturnino Jul 28, 2026
a79cd50
feat(scripts): confirm a driver's report against the chain it names
lrsaturnino Jul 28, 2026
14acd2a
fix(release): require complete permit-bound cutover evidence
lrsaturnino Jul 28, 2026
5b22529
fix(audit): enforce exact quiescence permit identities
lrsaturnino Jul 28, 2026
ec3503d
fix(audit): bind quiescence outcomes to gate inventory
lrsaturnino Jul 28, 2026
b4e88ac
Add authoritative participation quiescence audit
lrsaturnino Jul 28, 2026
8c030c5
Persist node-owned ceremony terminal outcomes
lrsaturnino Jul 29, 2026
f01e299
fix(audit): bind DKG outcomes to persisted memberships
lrsaturnino Jul 29, 2026
2c125f8
fix(audit): bind tBTC DKG permits to accepted results
lrsaturnino Jul 29, 2026
361cc67
feat(protocol): enable legacy TSS cutover transcripts
lrsaturnino Jul 29, 2026
419d56a
Harden rollback DKG chain reconciliation
lrsaturnino Jul 29, 2026
3cdd9ee
Harden rollback chain evidence authentication
lrsaturnino Jul 29, 2026
d68396d
Record node-owned outcomes for non-DKG ceremonies
lrsaturnino Jul 29, 2026
70cc8f5
Run the mixed prior/R1 legacy stages, gate their acceptance
lrsaturnino Jul 29, 2026
a6613fb
Name the release inputs the acceptance contract now requires
lrsaturnino Jul 29, 2026
e8ea834
Settle each ceremony on the evidence class its result lives in
lrsaturnino Jul 29, 2026
0e5ca20
Join every signed wallet transaction to the reconciled Bitcoin set
lrsaturnino Jul 29, 2026
f0e58fe
Make the cross-C control account for every permit it held
lrsaturnino Jul 29, 2026
a78610e
Read the anchors a quiescence control was handed, not its phase name
lrsaturnino Jul 29, 2026
13fdab4
Ask a settled transcript who contributed, not which containers were up
lrsaturnino Jul 29, 2026
104574c
Ask the WalletRegistry whether a heartbeat's penalty landed
lrsaturnino Jul 29, 2026
6d179ec
Compare a terminal record by what it says, not where it lives
lrsaturnino Jul 29, 2026
09e875c
Tell a claim that may be on chain from one that cannot be
lrsaturnino Jul 29, 2026
f8988aa
Bind a reported penalty to the wallet the permit punished
lrsaturnino Jul 29, 2026
2616b2a
Make a relay entry provable instead of merely asserted
lrsaturnino Jul 29, 2026
9eb5080
Keep a settlement deadline ahead of the block it is set from
lrsaturnino Jul 29, 2026
bf93417
Bind a relay entry to the request its permit was issued for
lrsaturnino Jul 29, 2026
ff36937
Let the beacon decide whether a timeout penalty exists
lrsaturnino Jul 29, 2026
f4b1a46
Let the claim submission test order itself
lrsaturnino Jul 29, 2026
71a1d57
Ask a compatibility transcript to name both releases
lrsaturnino Jul 29, 2026
dce6783
Name the pre-cutover ceremonies instead of their family
lrsaturnino Jul 29, 2026
3240cd4
Let a scrape name the permits a node is holding
lrsaturnino Jul 29, 2026
23da2f3
Tell a delivered relay entry from an accepted timeout report
lrsaturnino Jul 29, 2026
fbec09b
Ask each ceremony whether the two releases interoperated on it
lrsaturnino Jul 29, 2026
8463af5
Name the permits that crossed C instead of counting them
lrsaturnino Jul 29, 2026
0eed5fd
Drain a legacy permit the gate issued before C, not one claimed to be
lrsaturnino Jul 29, 2026
b5e9ff9
Read a timeout penalty off the relay, not off an empty slot
lrsaturnino Jul 29, 2026
7fd77bf
Keep the clock-failure control off the node holding the seeded permit
lrsaturnino Jul 29, 2026
ed5bfc9
Reject a legacy permit that only turns up at the crossing
lrsaturnino Jul 29, 2026
48464f8
Follow both live modes out of a quiescence, not just the drained one
lrsaturnino Jul 29, 2026
3cadd88
Read an accepted timeout off a cleared slot too, not only a retried one
lrsaturnino Jul 29, 2026
5d280cc
Excuse the seed both readings name, not the node it was seeded on
lrsaturnino Jul 29, 2026
ca55c79
Read a timeout penalty off the beacon's own record, not off the reque…
lrsaturnino Jul 29, 2026
63f71e7
Corroborate a relay timeout penalty against the beacon's own logs
lrsaturnino Jul 29, 2026
2fb2e15
Bind a recovered relay entry to the request the beacon actually made
lrsaturnino Jul 29, 2026
7dca02b
Enumerate the endings a filed timeout report can actually have
lrsaturnino Jul 29, 2026
47bf93c
Read a relay timeout settlement off one view of the chain
lrsaturnino Jul 29, 2026
0730288
Bind a recovered relay entry to the group the request selected
lrsaturnino Jul 29, 2026
95f0118
Prove a mixed-transcript tECDSA ceremony cannot produce a signature
lrsaturnino Jul 29, 2026
ee91fc0
Record where the mixed-transcript refusal is actually proven
lrsaturnino Jul 29, 2026
1019d09
Let a scrape follow a permit past the point it stops being held
lrsaturnino Jul 29, 2026
c7129ca
Say plainly which half of a permit's ending is still the driver's word
lrsaturnino Jul 29, 2026
ee4e326
Refuse a relay entry whose group the evidence never bound
lrsaturnino Jul 29, 2026
5822e50
Watch a mixed ceremony past the refusal, and mint no wallet either
lrsaturnino Jul 29, 2026
76d75f2
Ask the node how its permit ended, not the party that started it
lrsaturnino Jul 29, 2026
e90b740
Watch a ceremony to the end of its workers, not to a quiet stretch
lrsaturnino Jul 29, 2026
1b93e34
Make the positive control positive about the gate's permits, not the …
lrsaturnino Jul 29, 2026
77b7c5a
Ask each draining node what became of the permits it let go of
lrsaturnino Jul 29, 2026
034e9ad
Say in the file which single-quoted fixtures mean to expand later
lrsaturnino Jul 29, 2026
b1f850b
Follow a permit by its whole identity, and read what its ending left …
lrsaturnino Jul 29, 2026
e0fc04b
Ask the fleet who was in a transcript, not the party that drove it
lrsaturnino Jul 29, 2026
8effb6b
Ask a finished ceremony which parties reached its result
lrsaturnino Jul 29, 2026
0ade3b1
Read the other release's share off the seats, not off the report
lrsaturnino Jul 29, 2026
65c3714
Check a holder because it published a record, not because it was named
lrsaturnino Jul 29, 2026
4ff19c9
Count a done check from this attempt's signers, in this attempt's window
lrsaturnino Jul 29, 2026
e13587b
Count a holder as a contributor when a seat in the result was its own
lrsaturnino Jul 29, 2026
a9ba91d
Ask the beacon ceremonies who produced their results too
lrsaturnino Jul 29, 2026
da6aee5
Read mixedness out of one transcript, not out of the fleet's several
lrsaturnino Jul 29, 2026
ec22bc9
Wait for the done check to rule on a message before reading its refusals
lrsaturnino Jul 29, 2026
2c29401
Say what a seat in a transcript attests, and what the wire cannot bin…
lrsaturnino Jul 29, 2026
324899b
Read the beacon ceremonies' transcripts instead of refusing them
lrsaturnino Jul 30, 2026
134a7d1
Hold a settlement to the one rendering an audit can look up
lrsaturnino Jul 30, 2026
40177f1
Hold a persisted seat to the transcript the same record published
lrsaturnino Jul 30, 2026
e6e41b5
Build the seat ownership map from permits, not from completions
lrsaturnino Jul 30, 2026
74fb68f
Say which permit seat a remapped transcript's seat came from
lrsaturnino Jul 30, 2026
223113c
Read a remapped transcript's seats against the map in one space
lrsaturnino Jul 30, 2026
e3e75f6
Say whether the account of closed permits can be followed
lrsaturnino Jul 30, 2026
2ddcc9d
Say in the rehearsal notes what a remapped transcript is joined through
lrsaturnino Jul 30, 2026
98f9ee7
Hold a one-seat permit to the seat it was issued for
lrsaturnino Jul 30, 2026
e2efc19
Refuse provenance a node declined to state
lrsaturnino Jul 30, 2026
fa2c92b
Count a permit still open toward the fleet's seats
lrsaturnino Jul 30, 2026
f385ff0
Read a DKG record's whole seat map against the accepted result
lrsaturnino Jul 30, 2026
77650d6
Activate a DKG signer only against the result this member generated
lrsaturnino Jul 30, 2026
f35d1dc
Say in the rehearsal notes what the fleet's seat map now spans
lrsaturnino Jul 30, 2026
3e4b6cf
Report the signer outputs a gate refusal is still holding
lrsaturnino Jul 30, 2026
af1a41d
Say which half of a quarantine record the namespace took
lrsaturnino Jul 30, 2026
f15dc02
Refuse a quarantine count nobody could take, and wait for the permits
lrsaturnino Jul 30, 2026
cfa1b62
Read preserved key material no audit record explains
lrsaturnino Jul 30, 2026
a99c39d
Hold the operator's account of a quarantine to what the namespace holds
lrsaturnino Jul 30, 2026
1fa59c0
Never let the node's account of preserved key material outrun the nam…
lrsaturnino Jul 30, 2026
8c83256
Drive the settled-account collector instead of injecting its answer
lrsaturnino Jul 30, 2026
1344620
Hold the generated share until the namespace has all of it
lrsaturnino Jul 30, 2026
566ac91
Count a share the namespace took long after the write began
lrsaturnino Jul 30, 2026
b0181a9
Report a quarantined share the moment the namespace takes it
lrsaturnino Jul 30, 2026
aa3e1ac
Count what the last scan found alongside what this process wrote
lrsaturnino Jul 30, 2026
e08a26f
Name the release the manifest is for, not only its bounds
lrsaturnino Jul 30, 2026
bd68929
Stop vouching for a share the namespace already said it lost
lrsaturnino Jul 30, 2026
62b93b1
Give a refused quarantine record somewhere else to put the share
lrsaturnino Jul 30, 2026
11f78d3
Refuse evidence measured against a manifest naming no release
lrsaturnino Jul 30, 2026
e604abb
Compare the two preserved forms instead of trusting the first one read
lrsaturnino Jul 30, 2026
797811b
Hold the readiness verdict to the binary that is supposed to answer it
lrsaturnino Jul 30, 2026
d217a32
Require a recorded release commit to be the one under test
lrsaturnino Jul 30, 2026
7bec6ed
Record what was built where it can name the commit it names
lrsaturnino Jul 30, 2026
7a72800
Ask the producer the question only a real release can answer
lrsaturnino Jul 30, 2026
af167ba
Ask the binary which release the readiness cases are about
lrsaturnino Jul 30, 2026
100afc1
Give the dispatch a way to say what the release was built into
lrsaturnino Jul 30, 2026
a52b022
Record the image that ran, and ask coverage of the archive
lrsaturnino Jul 30, 2026
d2d07cf
Say where the handoff's atomicity gap actually lives
lrsaturnino Jul 30, 2026
97b5036
Make rehearsal evidence complete across platforms
lrsaturnino Jul 30, 2026
47b81ea
Harden cutover rollback and platform evidence
lrsaturnino Jul 30, 2026
5414684
Harden cutover evidence and dispatch validation
lrsaturnino Jul 30, 2026
c4b4dc1
Distinguish recovered quarantine preservation
lrsaturnino Jul 30, 2026
363a3a4
Harden cutover quarantine evidence
lrsaturnino Jul 31, 2026
2b1c123
Harden restart quarantine evidence
lrsaturnino Jul 31, 2026
fa85fe2
Watch cross-cutover restart shutdown
lrsaturnino Jul 31, 2026
f8dbcbd
Harden cross-cutover restart refusal
lrsaturnino Jul 31, 2026
4290dc3
Harden restart rehearsal evidence
lrsaturnino Jul 31, 2026
b3087e2
Harden watched-stop preservation evidence
lrsaturnino Jul 31, 2026
9493c74
Make preservation sampling atomic
lrsaturnino Jul 31, 2026
d85b372
Track per-service preservation provenance
lrsaturnino Jul 31, 2026
5d335b7
Complete cutover observability log context
lrsaturnino Jul 31, 2026
66a3931
Add cutover roster evidence windows
lrsaturnino Jul 31, 2026
52fd785
Harden cutover roster evidence capture
lrsaturnino Jul 31, 2026
c1d2821
Bind cutover roster records to captured evidence
lrsaturnino Jul 31, 2026
4ad6e36
Bind cutover evidence to rehearsal context
lrsaturnino Jul 31, 2026
acfa9be
Merge mainline Solidity toolchain updates
lrsaturnino Jul 31, 2026
df690de
Fix Solidity Docker builds with current Alpine Git
lrsaturnino Jul 31, 2026
b443f6a
ci(solidity): verify Hardhat images on native AMD64
lrsaturnino Jul 31, 2026
71363d1
ci(solidity): align rehearsal Node with contract checks
lrsaturnino Jul 31, 2026
460370b
build(release): unify cutover completion checks
lrsaturnino Jul 31, 2026
1869a57
build(release): distinguish local cutover gate scopes
lrsaturnino Jul 31, 2026
e4666f3
style(release): format provenance validation
lrsaturnino Jul 31, 2026
ad259a3
fix(participation): reject unknown commit fence classes
lrsaturnino Jul 31, 2026
6554a18
fix(release): isolate prerelease Docker tags
lrsaturnino Aug 2, 2026
de410d9
fix(release): bind publication to triggering tag
lrsaturnino Aug 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
18 changes: 18 additions & 0 deletions .clusterfuzzlite/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# ClusterFuzzLite / OSS-Fuzz build image for keep-core's native Go fuzz targets.
# base-builder-go provides the Go toolchain plus the compile_native_go_fuzzer
# helper used by build.sh.
#
# Digest-pinned: the :latest tag floats and the image is rebuilt upstream
# continuously; an unpinned base silently changes the build environment (and
# is a supply-chain vector) on every CI run. Bump the digest deliberately —
# resolve the current one with:
# curl -s "https://gcr.io/v2/oss-fuzz-base/base-builder-go/manifests/latest" \
# -H "Authorization: Bearer $(curl -s 'https://gcr.io/v2/token?service=gcr.io&scope=repository:oss-fuzz-base/base-builder-go:pull' | jq -r .token)" \
# -H "Accept: application/vnd.docker.distribution.manifest.list.v2+json" -I | grep -i docker-content-digest
FROM gcr.io/oss-fuzz-base/base-builder-go@sha256:cf761fd9baac42fff453259755067a7ad8ad70dbbe7db5027211e9fabc5cac40

# The ClusterFuzzLite build_fuzzers action supplies the checked-out repo as the
# Docker build context; copy it in and build from there.
COPY . $SRC/keep-core
WORKDIR $SRC/keep-core
COPY .clusterfuzzlite/build.sh $SRC/
104 changes: 104 additions & 0 deletions .clusterfuzzlite/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# Continuous fuzzing

This directory wires keep-core's native Go fuzz targets (the `Fuzz*` functions
under `pkg/**/fuzz_test.go`) into **ClusterFuzzLite** — OSS-Fuzz's self-hosted
variant that runs in this repo's own GitHub Actions and **works on private
repos**. That last property is why ClusterFuzzLite, not OSS-Fuzz, is the right
tool for this fork (OSS-Fuzz only fuzzes public projects).

## Files

| file | purpose |
|---|---|
| `Dockerfile` | build image (`base-builder-go`) |
| `build.sh` | compiles every `Fuzz*` target into a libFuzzer binary (path-qualified output names — several `Fuzz*` funcs share a name across packages) |
| `project.yaml` | `language: go` |
| `../.github/workflows/cflite_pr.yml` | per-PR fuzzing of changed code (fast, exits on first crash) |
| `../.github/workflows/cflite_batch.yml` | scheduled longer run over all targets |

## Adding / regenerating targets

`build.sh` must list one `compile_native_go_fuzzer` line per `Fuzz*` target.
CI enforces this (`check_targets.sh` runs on every PR and fails on drift).
Regenerate after adding targets:

```sh
for f in $(grep -rln "func Fuzz.*testing.F" pkg/ --include="*_test.go" | sort); do
d=$(dirname "$f"); p="github.com/keep-network/keep-core/$d"
pref=$(echo "$d" | sed 's#^pkg/##; s#/#_#g')
grep -oE "func (Fuzz[A-Za-z0-9_]+)\(" "$f" | sed -E 's/func (Fuzz[A-Za-z0-9_]+)\(/\1/' \
| while read fn; do echo "compile_native_go_fuzzer $p $fn ${pref}_${fn}"; done
done
```

## Enabling corpus persistence (batch mode)

Batch fuzzing benefits from carrying the corpus between runs — without it
every nightly run restarts from the in-tree seeds and the 1800s budget is a
smoke test, not coverage-accumulating fuzzing. To enable:

1. Create a private storage repo, e.g. `tlabs-xyz/keep-core-security-fuzz-corpus`.
2. Add a `PERSONAL_ACCESS_TOKEN` repo secret. It MUST be a **fine-grained
PAT scoped to the storage repo only**, with `Contents: Read and write`
as its only permission. Never use a classic PAT here: the token is
interpolated into a clone URL inside a job that executes
repo-controlled build code (`build.sh`, `Dockerfile`), so an
over-scoped token would hand that code access to everything it can
reach. Set an expiry and rotate it.
3. Uncomment the `storage-repo*` lines in `cflite_batch.yml` (and
`upload-build`). Keep persistence OUT of `cflite_pr.yml`: PR jobs run
proposed code and must not see the token at all.

Until then, each batch run starts from the in-tree seed corpus.

## Fork-lifecycle policy (why this exists)

This is a **private fork** of the public `github.com/keep-network/keep-core`.
Fuzzing finds bugs in code; whether a finding is fork-relevant depends on how
far the fork has diverged. Two facts drive the policy:

- **Fixes do not flow back automatically.** A bug fixed upstream stays open in
this fork until deliberately back-merged (this engagement already hit exactly
that: upstream's OOB fix was incomplete and had to be back-merged by hand).
- **Fork-divergent code gets no upstream coverage.** OSS-Fuzz on the upstream
cannot see code that only exists here.

Policy:

1. **Run ClusterFuzzLite here** (this directory) so the fork's own code —
including divergent paths — is fuzzed in its own CI.
2. **Track upstream `main`**: reconcile within a bounded window (e.g. N commits
or one release) so shared-parser fixes found upstream reach the fork.
3. **Contribute the fuzz targets upstream** (below) so the shared parsers get
continuous OSS-Fuzz coverage at Google's scale, and so this fork inherits
that coverage on the shared code after each reconcile.

## OSS-Fuzz for the public upstream

The same `Dockerfile` / `build.sh` / targets work for OSS-Fuzz once the
`Fuzz*` targets are merged into `github.com/keep-network/keep-core`. To enroll
the upstream, open a PR to `google/oss-fuzz` adding `projects/keep-core/` with:

- `project.yaml`:

```yaml
homepage: "https://github.com/keep-network/keep-core"
language: go
primary_contact: "<security contact email>"
main_repo: "https://github.com/keep-network/keep-core"
fuzzing_engines:
- libfuzzer
sanitizers:
- address
```

- a `Dockerfile` that `git clone`s the upstream repo (instead of `COPY .`):

```dockerfile
FROM gcr.io/oss-fuzz-base/base-builder-go
RUN git clone --depth 1 https://github.com/keep-network/keep-core $SRC/keep-core
WORKDIR $SRC/keep-core
COPY build.sh $SRC/
```

- the same `build.sh` from this directory.
64 changes: 64 additions & 0 deletions .clusterfuzzlite/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#!/bin/bash -eu
#
# ClusterFuzzLite / OSS-Fuzz build script for keep-core native (testing.F)
# fuzz targets. Compiles every Fuzz* target into a libFuzzer binary. Output
# names are path-qualified because several Fuzz funcs share a name across
# packages (e.g. FuzzEphemeralPublicKeyMessageUnmarshal in gjkr/dkg/signing).
#
# Regenerate the target list with:
# grep -rhoE "func (Fuzz[A-Za-z0-9_]+)\(f \*testing.F\)" pkg/ --include="*_test.go"

cd "$SRC/keep-core"

# Fuzzers don't need VCS build stamping, and stamping can fail in the build
# container (git "dubious ownership" / detached checkout). Disable it.
export GOFLAGS="-buildvcs=false ${GOFLAGS:-}"

# compile_native_go_fuzzer rewrites each testing.F target onto the OSS-Fuzz
# libFuzzer shim; pull it into the module graph (build-container only, not
# committed to go.mod). Pinned to a commit SHA: this fetch happens outside
# go.sum protection on every CI build, so an unpinned HEAD would execute
# whatever upstream pushes. Bump deliberately.
go get github.com/AdamKorcz/go-118-fuzz-build/testing@a70c2aa677fa43583571959478decabe02a96cd6

compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/beacon/dkg/result FuzzDKGResultHashSignatureMessageUnmarshal beacon_dkg_result_FuzzDKGResultHashSignatureMessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/beacon/entry FuzzSignatureShareMessageUnmarshal beacon_entry_FuzzSignatureShareMessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/beacon/gjkr FuzzEphemeralPublicKeyMessageUnmarshal beacon_gjkr_FuzzEphemeralPublicKeyMessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/beacon/gjkr FuzzMemberCommitmentsMessageUnmarshal beacon_gjkr_FuzzMemberCommitmentsMessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/beacon/gjkr FuzzPeerSharesMessageUnmarshal beacon_gjkr_FuzzPeerSharesMessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/beacon/gjkr FuzzSecretSharesAccusationsMessageUnmarshal beacon_gjkr_FuzzSecretSharesAccusationsMessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/beacon/gjkr FuzzMemberPublicKeySharePointsMessageUnmarshal beacon_gjkr_FuzzMemberPublicKeySharePointsMessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/beacon/gjkr FuzzPointsAccusationsMessageUnmarshal beacon_gjkr_FuzzPointsAccusationsMessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/beacon/gjkr FuzzMisbehavedEphemeralKeysMessageUnmarshal beacon_gjkr_FuzzMisbehavedEphemeralKeysMessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/bitcoin FuzzNewScriptFromVarLenData bitcoin_FuzzNewScriptFromVarLenData
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/bitcoin FuzzTransactionDeserialize bitcoin_FuzzTransactionDeserialize
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/net/libp2p FuzzIdentityUnmarshal net_libp2p_FuzzIdentityUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/net/security/handshake FuzzAct1MessageUnmarshal net_security_handshake_FuzzAct1MessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/net/security/handshake FuzzAct2MessageUnmarshal net_security_handshake_FuzzAct2MessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/net/security/handshake FuzzAct3MessageUnmarshal net_security_handshake_FuzzAct3MessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/protocol/announcer FuzzAnnouncementMessageUnmarshal protocol_announcer_FuzzAnnouncementMessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/protocol/inactivity FuzzClaimSignatureMessageUnmarshal protocol_inactivity_FuzzClaimSignatureMessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/tbtc FuzzSigningDoneMessageUnmarshal tbtc_FuzzSigningDoneMessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/tbtc FuzzCoordinationMessageUnmarshal tbtc_FuzzCoordinationMessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/tbtc FuzzNoopProposalUnmarshal tbtc_FuzzNoopProposalUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/tbtc FuzzHeartbeatProposalUnmarshal tbtc_FuzzHeartbeatProposalUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/tbtc FuzzDepositSweepProposalUnmarshal tbtc_FuzzDepositSweepProposalUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/tbtc FuzzRedemptionProposalUnmarshal tbtc_FuzzRedemptionProposalUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/tbtc FuzzMovingFundsProposalUnmarshal tbtc_FuzzMovingFundsProposalUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/tbtc FuzzMovedFundsSweepProposalUnmarshal tbtc_FuzzMovedFundsSweepProposalUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/tecdsa/dkg FuzzEphemeralPublicKeyMessageUnmarshal tecdsa_dkg_FuzzEphemeralPublicKeyMessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/tecdsa/dkg FuzzTssRoundOneMessageUnmarshal tecdsa_dkg_FuzzTssRoundOneMessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/tecdsa/dkg FuzzTssRoundTwoMessageUnmarshal tecdsa_dkg_FuzzTssRoundTwoMessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/tecdsa/dkg FuzzTssRoundThreeMessageUnmarshal tecdsa_dkg_FuzzTssRoundThreeMessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/tecdsa/dkg FuzzTssFinalizationMessageUnmarshal tecdsa_dkg_FuzzTssFinalizationMessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/tecdsa/dkg FuzzResultSignatureMessageUnmarshal tecdsa_dkg_FuzzResultSignatureMessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/tecdsa/signing FuzzEphemeralPublicKeyMessageUnmarshal tecdsa_signing_FuzzEphemeralPublicKeyMessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/tecdsa/signing FuzzTssRoundOneMessageUnmarshal tecdsa_signing_FuzzTssRoundOneMessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/tecdsa/signing FuzzTssRoundTwoMessageUnmarshal tecdsa_signing_FuzzTssRoundTwoMessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/tecdsa/signing FuzzTssRoundThreeMessageUnmarshal tecdsa_signing_FuzzTssRoundThreeMessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/tecdsa/signing FuzzTssRoundFourMessageUnmarshal tecdsa_signing_FuzzTssRoundFourMessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/tecdsa/signing FuzzTssRoundFiveMessageUnmarshal tecdsa_signing_FuzzTssRoundFiveMessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/tecdsa/signing FuzzTssRoundSixMessageUnmarshal tecdsa_signing_FuzzTssRoundSixMessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/tecdsa/signing FuzzTssRoundSevenMessageUnmarshal tecdsa_signing_FuzzTssRoundSevenMessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/tecdsa/signing FuzzTssRoundEightMessageUnmarshal tecdsa_signing_FuzzTssRoundEightMessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/tecdsa/signing FuzzTssRoundNineMessageUnmarshal tecdsa_signing_FuzzTssRoundNineMessageUnmarshal
40 changes: 40 additions & 0 deletions .clusterfuzzlite/check_targets.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#!/bin/bash -eu
#
# Drift guard: fails when the set of native Fuzz* targets under pkg/
# diverges from the compile_native_go_fuzzer registration list in
# build.sh. Without this, a new Fuzz* function compiles fine under
# `go test` but silently receives zero ClusterFuzzLite coverage.
#
# Compares exact (package, function) pairs — not counts — because
# several Fuzz functions share a name across packages.

repo_root="$(cd "$(dirname "$0")/.." && pwd)"
module="github.com/keep-network/keep-core"

# Work from the repo root so grep emits relative paths: the absolute path
# never enters the sed pattern, where regex metacharacters in a checkout
# location could otherwise misparse the target list.
cd "$repo_root"

expected="$(
grep -rn --include='*_test.go' -E '^func Fuzz[A-Za-z0-9_]+\(f \*testing\.F\)' pkg |
sed -E "s|^(.+)/[^/]+\.go:[0-9]+:func (Fuzz[A-Za-z0-9_]+)\(.*$|$module/\1 \2|" |
sort -u
)"

registered="$(
grep -E '^compile_native_go_fuzzer ' .clusterfuzzlite/build.sh |
awk '{print $2, $3}' |
sort -u
)"

if ! diff <(echo "$expected") <(echo "$registered") >&2; then
echo >&2
echo "Fuzz target drift detected:" >&2
echo " < targets found in pkg/ but not registered in .clusterfuzzlite/build.sh" >&2
echo " > targets registered in build.sh but missing from pkg/" >&2
echo "Add/remove the matching compile_native_go_fuzzer line(s)." >&2
exit 1
fi

echo "OK: $(echo "$expected" | wc -l) fuzz targets, build.sh registration list in sync."
11 changes: 11 additions & 0 deletions .clusterfuzzlite/project.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# ClusterFuzzLite project configuration. For CFLite only `language` is required;
# it is consumed by the build_fuzzers / run_fuzzers GitHub Actions.
#
# (The OSS-Fuzz integration for the PUBLIC upstream repo lives in the
# google/oss-fuzz repo under projects/keep-core/ and carries additional fields
# — homepage, primary_contact, main_repo, auto_ccs. See README.md.)
language: go
fuzzing_engines:
- libfuzzer
sanitizers:
- address
6 changes: 6 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Hidden files and directories.
.*
# ...except the ClusterFuzzLite build files, which must reach the build context.
!.clusterfuzzlite
!.clusterfuzzlite/**

# Top-level directories unrelated to the build.
docs*/
Expand Down Expand Up @@ -27,6 +30,9 @@ token-tracker/
# Go stuff.
**/gen/_contracts
**/gen/**/*.go
# ...but keep the committed protobuf message code (gen/pb); the ClusterFuzzLite
# build does not run protoc, and the unmarshaler fuzz targets need it.
!**/gen/pb/*.go
!**/gen/gen.go
!**/gen/cmd/cmd.go

Expand Down
5 changes: 5 additions & 0 deletions .github/actions/docker-build-push/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ inputs:
description: True if the image should be published
required: true
default: "false"
load:
description: True if the image should be loaded into the local Docker daemon
required: false
default: "false"
gcrJsonKey:
description: JSON key for Google Container Registry service account (required if push is true)
required: false
Expand Down Expand Up @@ -69,6 +73,7 @@ runs:
labels: |
revision=${{ github.sha }}
push: ${{ inputs.push == 'true' }}
load: ${{ inputs.load == 'true' }}
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache-new

Expand Down
46 changes: 46 additions & 0 deletions .github/workflows/cflite_batch.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: ClusterFuzzLite batch fuzzing

# Scheduled longer fuzzing run over all targets to grow the corpus and reach
# deeper bugs than per-PR fuzzing can. Does not exit on first crash.
#
# Corpus/crash persistence requires a storage repo + a PERSONAL_ACCESS_TOKEN
# secret; uncomment the storage-repo lines once those exist (see
# .clusterfuzzlite/README.md). Without persistence the run still fuzzes but
# starts from the in-tree seed corpus each time.
on:
schedule:
- cron: "0 2 * * *" # daily, offset from the -race job (midnight)
workflow_dispatch:

# No security-events permission: this repo has no GitHub Advanced
# Security, so SARIF upload to code scanning would 403. Crash artifacts
# are reported via the action's run output and artifacts instead.
permissions:
contents: read

jobs:
Batch:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
sanitizer: [address]
steps:
- name: Build fuzzers (${{ matrix.sanitizer }})
id: build
uses: google/clusterfuzzlite/actions/build_fuzzers@82652fb49e77bc29c35da1167bb286e93c6bcc05 # v1
with:
language: go
sanitizer: ${{ matrix.sanitizer }}
# upload-build: true
- name: Run fuzzers (${{ matrix.sanitizer }})
id: run
uses: google/clusterfuzzlite/actions/run_fuzzers@82652fb49e77bc29c35da1167bb286e93c6bcc05 # v1
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
fuzz-seconds: 1800
mode: "batch"
sanitizer: ${{ matrix.sanitizer }}
# storage-repo: https://${{ secrets.PERSONAL_ACCESS_TOKEN }}@github.com/tlabs-xyz/keep-core-security-fuzz-corpus.git
# storage-repo-branch: main
# storage-repo-branch-coverage: gh-pages
Loading
Loading