Skip to content
Bitcoin Roots

v31.1-roots.1 · Commit 8: [PATCH 08/17] chore(roots): integrate v31 identity and maintenance tooling

contrib/roots/README.md

Before: /dev/null · After: contrib/roots/README.md

File metadata
new file mode 100644
index 0000000000000000000000000000000000000000..98ba788f2c09128120ec9be28e419396ae4691d0

Download original patch · Release notes

Diff rows 1–347 of 347. Line numbers refer to the original before/after files.

+ Added− RemovedUnmarked lines are context.

Scroll the code area horizontally to read long lines. Before is on the left; after is on the right. Unified view fits narrow screens more easily.

contrib/roots/README.md ADDED
@@ -0,0 +1,347 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Bitcoin Roots maintainer workflow
2
+
3
+ Bitcoin Roots is maintained as a small, reviewable Git history on top of
4
+ Bitcoin Core. Bitcoin Core v31.1 is the authenticated direct base of this unpublished candidate.
5
+ Publishing, release tags and main promotion require separate authorization.
6
+ Bitcoin Knots is historical provenance for selected Roots policy features, not
7
+ an upstream, a dependency, or a source of consensus rules.
8
+
9
+ Git history is the canonical representation of Roots changes. Do not maintain
10
+ replay frameworks, patch manifests, generated evidence, frozen candidate state,
11
+ or promotion metadata alongside it. The archived replay branch is historical
12
+ evidence only; do not rewrite or depend on it.
13
+
14
+ ## Branch roles
15
+
16
+ Keep the source patch series, product integration history, and generated
17
+ release artifacts separate:
18
+
19
+ - `roots/<core-version>` is the canonical release line. It starts at the exact
20
+ matching Bitcoin Core tag and contains a linear series of semantic Roots
21
+ commits. Released tips are immutable.
22
+ - `topic/<core-version>/<area>` holds work for one reviewable area. Accepted
23
+ commits are applied to the canonical release line.
24
+ - `integration/<core-version>` is disposable combined-CI state. It may be
25
+ rebuilt and must not be used as the base for durable work.
26
+ - `main` is the currently promoted product history. An explicit promotion merge
27
+ connects it to a reviewed canonical release line; the merge result must have
28
+ exactly the same tree as that canonical tip.
29
+ - `archive/*` preserves superseded candidates and retired maintenance systems.
30
+ Archive branches are evidence, not dependencies or release inputs.
31
+
32
+ For example, `roots/29.4` starts directly at `v29.4`, while `roots/31.1`
33
+ starts directly at `v31.1`. Do not merge the complete 29.4 branch into the 31.1
34
+ branch. Port the semantic Roots commits to the new Core base, dropping behavior
35
+ that Core has adopted and adapting or splitting commits when its APIs changed.
36
+
37
+ Pull requests that promote a release into `main` and pull requests that review
38
+ the canonical patch series have different bases. Never rebase or squash the
39
+ canonical series merely to make a promotion pull request appear linear. Build
40
+ the promotion from `main`, retain the canonical tip as a merge parent, and
41
+ verify tree equality before publishing it.
42
+
43
+ ## Inspecting a maintenance branch
44
+
45
+ Start from a clean worktree and name the Core base explicitly. For the v31.1
46
+ work, the peeled Core commit is `9be056a8a72b624dae9623b2f7bded92c2a21c91`.
47
+ The following commands inspect history without changing it:
48
+
49
+ ```sh
50
+ core_base=9be056a8a72b624dae9623b2f7bded92c2a21c91
51
+ git status --short
52
+ git show --no-patch --decorate "$core_base"
53
+ git log --oneline --decorate "$core_base"..HEAD
54
+ git diff --stat "$core_base"..HEAD
55
+ git merge-base --is-ancestor "$core_base" HEAD
56
+ ```
57
+
58
+ Use `git show-ref --heads --tags` and `git rev-parse --verify <ref>` before
59
+ using a local name in automation. `git merge-base --is-ancestor A B` succeeds
60
+ only when `A` is an ancestor of `B`; it is preferable to inferring ancestry
61
+ from a graph view. Confirm object identities with `git rev-parse <ref>^{commit}`.
62
+
63
+ Authenticate the official tag and its signer key through independent trusted
64
+ sources before claiming verification. A missing local signer key is not proof
65
+ of an invalid signature. Run `git verify-tag v31.1` with the authenticated key
66
+ and record both the signature result and its trust basis.
67
+
68
+ ## Exporting and reviewing a series
69
+
70
+ Export the reviewed range directly from Git. Choose an output directory outside
71
+ the repository or an ignored disposable directory:
72
+
73
+ ```sh
74
+ git format-patch --cover-letter --output-directory /tmp/roots-patches \
75
+ "$core_base"..HEAD
76
+ git format-patch --stdout "$core_base"..HEAD > /tmp/roots-series.mbox
77
+ git diff --check "$core_base"..HEAD
78
+ ```
79
+
80
+ Before and after a rewrite, retain the previous tip in a local variable or
81
+ named branch and compare the two series. `range-diff` makes changes to commit
82
+ content and ordering visible to reviewers:
83
+
84
+ ```sh
85
+ previous_tip=<previous-reviewed-tip>
86
+ git range-diff "$core_base"..."$previous_tip" "$core_base"...HEAD
87
+ git diff --check "$previous_tip"..HEAD
88
+ ```
89
+
90
+ Do not use an exported series as a second source of truth. It is a review or
91
+ transfer artifact; the Git commits remain canonical.
92
+
93
+ ## Porting a Core release
94
+
95
+ Fetch and inspect the intended Core tag or commit first. Configure `core` to
96
+ the official Bitcoin Core repository once, or select an already-configured
97
+ remote explicitly; do not assume that every checkout has a remote named
98
+ `core`. Create a dedicated maintenance branch, then port the Roots series with
99
+ ordinary Git operations:
100
+
101
+ ```sh
102
+ core_remote=<configured-bitcoin-core-remote>
103
+ core_tag=v31.1
104
+ git remote get-url "$core_remote"
105
+ git fetch "$core_remote" --tags
106
+ core_commit=$(git rev-parse "$core_tag^{commit}")
107
+ git show --no-patch --decorate "$core_commit"
108
+ git switch --create roots/31.1 "$core_commit"
109
+ git cherry-pick -x <semantic-roots-commit>
110
+ ```
111
+
112
+ Repeat the cherry-pick for each semantic commit after deciding whether that
113
+ change is still needed. `-x` records the source commit when the new commit is a
114
+ true cherry-pick. When a conflict requires a material rewrite, explain the old
115
+ commit and the deviation in the new commit message rather than retaining a
116
+ misleading cherry-pick identity.
117
+
118
+ Compare the old and new generations as patch series:
119
+
120
+ ```sh
121
+ git range-diff v29.4..roots/29.4 v31.1..roots/31.1
122
+ ```
123
+
124
+ Resolve only identified conflicts, inspect the result with `git diff` and
125
+ targeted tests, then use `git cherry-pick --continue`. If the port premise is
126
+ wrong, stop with `git cherry-pick --abort`; do not hide a conflict with a bulk
127
+ overwrite. The range-diff must explain commits that were added, dropped, split,
128
+ or materially changed before requesting review.
129
+
130
+ ## Maintaining supported release lines
131
+
132
+ Apply a security or correctness fix first to the oldest supported Roots line
133
+ that needs it. After review and testing, cherry-pick it with `-x` into each newer
134
+ affected line. Document deviations required by newer Core code. Do not rewrite
135
+ published release commits or tags.
136
+
137
+ A maintenance release therefore advances its own canonical branch, for example
138
+ from `v29.4-roots.1` to `v29.4-roots.2`; it does not require merging a newer
139
+ Core line into the older one.
140
+
141
+ ## Promoting a canonical line into `main`
142
+
143
+ Create the promotion in a separate worktree so that the canonical branch stays
144
+ clean:
145
+
146
+ ```sh
147
+ canonical_ref=origin/roots/31.1
148
+ git switch --create promote/31.1 origin/main
149
+ git merge --no-ff --no-commit "$canonical_ref"
150
+ # Resolve deliberately, then verify the proposed index and worktree.
151
+ git diff --cached --name-status
152
+ git commit
153
+ git diff --exit-code "$canonical_ref"..HEAD
154
+ test "$(git rev-parse HEAD^{tree})" = "$(git rev-parse "$canonical_ref^{tree}")"
155
+ ```
156
+
157
+ The last two commands are the defining promotion check: the merge records both
158
+ histories, but its product tree is identical to the canonical release tip. A
159
+ promotion branch is review state and may be rebuilt with a force-with-lease;
160
+ the canonical release branch is not rewritten after publication.
161
+
162
+ ## Editing policy safely
163
+
164
+ Roots may retain configurable conservative mempool, relay, and mining-template
165
+ policy. Keep that behavior in policy/admission/template boundaries and include
166
+ operator help/configuration plus feature-owned tests in the same reviewable
167
+ commit. Do not import Knots as an upstream dependency.
168
+
169
+ Policy rejection is not block validity. For every change that can reject a
170
+ consensus-valid transaction locally, test both sides of the boundary:
171
+
172
+ 1. the configured node rejects it from admission, relay, or template selection;
173
+ 2. a consensus-valid block containing it is still accepted.
174
+
175
+ Never add RDTS/BIP110 consensus enforcement. Audit every essential touch to
176
+ `src/consensus/`, `src/script/`, or validation code, and make no incidental
177
+ consensus-adjacent cleanup. Run focused unit and functional tests while editing,
178
+ then the relevant broad suite. At handoff, also run:
179
+
180
+ ```sh
181
+ cmake -S . -B build
182
+ cmake --build build --target bitcoind test_bitcoin -j 4
183
+ build/test/functional/test_runner.py mempool_dust.py
184
+ git diff --check
185
+ git status --short
186
+ ctest --test-dir build --output-on-failure
187
+ ```
188
+
189
+ Use a configured build directory appropriate to the affected targets; see the
190
+ repository `AGENTS.md` for safe regtest and build guidance.
191
+
192
+ ## Rewrites and public history
193
+
194
+ Use interactive rebase only on an unpublished maintenance branch, and review
195
+ the resulting series before sharing it:
196
+
197
+ ```sh
198
+ git branch reviewed-before-rebase HEAD
199
+ git rebase --interactive "$core_base"
200
+ git range-diff "$core_base"...reviewed-before-rebase "$core_base"...HEAD
201
+ ```
202
+
203
+ Do not rewrite a branch other people may have based work on without explicit
204
+ coordination. When a reviewed public branch must be updated, inspect its remote
205
+ tracking state and use a lease rather than an unrestricted force push:
206
+
207
+ ```sh
208
+ git fetch origin
209
+ git log --left-right --graph --cherry-pick origin/<branch>...HEAD
210
+ git push --force-with-lease origin HEAD:<branch>
211
+ ```
212
+
213
+ Never force-push release tags. Preserve archival branches.
214
+
215
+ ## Reusing canonical CI for a pure main promotion
216
+
217
+ Run ordinary fix CI, review it and integrate the canonical topic by fast-forward
218
+ before opening/updating its main promotion PR. Preserve a two-parent promotion
219
+ with current main first and the exact current canonical tip second.
220
+ `verify-promotion-ci.py` checks blob/mode/symlink parity outside the reviewed
221
+ main-only website/guidance/lint exceptions; CI and release workflows are never
222
+ exceptions. It requires the latest complete successful PR Tests run at the exact
223
+ candidate, in this repository, targeting its canonical branch, with successful
224
+ classifier, lint and required-result jobs. Claimed promotion proof mismatches
225
+ fail; they do not waive tests. Ordinary PRs retain normal CI.
226
+
227
+ A proven promotion reuses compiled-test results, while its classifier/regression
228
+ suite, lint and applicable independent main docs/site checks still run. Explicit
229
+ `ci:full` or other `ci:*` coverage labels keep requested fresh tests. Open the
230
+ promotion after source CI passes so no duplicate matrix is scheduled while
231
+ candidate evidence is incomplete. Optional checks do not claim reproducible
232
+ binaries, and existing release tags cannot be manually rehearsed.
233
+
234
+ ## Release handoff
235
+
236
+ Release tags use the Roots form `v<core-version>-roots.<positive-integer>`;
237
+ release candidates may use `v<core-version>rc<n>-roots.<positive-integer>`.
238
+ Before creating a permanent tag, merge the reviewed promotion so the trusted
239
+ workflow is present on the default branch. The default path tags the reviewed
240
+ canonical source once; the tag runs fresh five-platform builds, required
241
+ manifest signing and new-draft creation. Independently verify that draft before
242
+ separate publication approval.
243
+
244
+ An optional `Release artifacts` manual dispatch rehearses an absent future tag
245
+ at the full 40-hex canonical commit. Manual dispatch
246
+ fetches the official Core tag from the Bitcoin Core repository, verifies the
247
+ commit against `origin/roots/<core-version>`, creates an annotated tag only in
248
+ each disposable runner checkout, and builds the same five-platform artifact
249
+ set. It has read-only repository permissions and cannot create a GitHub
250
+ release. It also refuses to run if the future tag already exists remotely.
251
+
252
+ For an explicitly requested optional rehearsal:
253
+
254
+ ```sh
255
+ release_tag=v31.1-roots.1
256
+ release_commit=$(git rev-parse origin/roots/31.1^{commit})
257
+ gh workflow run release.yml --ref main \
258
+ -f release_tag="$release_tag" -f release_commit="$release_commit"
259
+ ```
260
+
261
+ When requested, download and inspect the optional rehearsal's packages and
262
+ patch. It does not replace the final tag run or establish binary reproducibility.
263
+ Corrections renew source review, required CI and affected final-build verification.
264
+ An optional rehearsal remains optional; repeat it only when explicitly requested.
265
+ A failed final build requires diagnosis and renewed affected verification.
266
+ Fetch again and verify the annotated tag target and ancestry
267
+ immediately before pushing:
268
+
269
+ ```sh
270
+ release_tag=v31.1-roots.1
271
+ git check-ref-format "refs/tags/$release_tag"
272
+ git fetch origin roots/31.1
273
+ git fetch https://github.com/bitcoin/bitcoin.git \
274
+ refs/tags/v31.1:refs/tags/v31.1
275
+ release_commit=$(git rev-parse origin/roots/31.1^{commit})
276
+ git tag --annotate "$release_tag" "$release_commit" -m "Bitcoin Roots $release_tag"
277
+ git rev-parse "$release_tag^{commit}"
278
+ test "$(git rev-parse "$release_tag^{commit}")" = \
279
+ "$(git rev-parse origin/roots/31.1^{commit})"
280
+ ci/release/validate-release-source.sh "$release_tag"
281
+ ```
282
+
283
+ Run the retained CI/release metadata tests before pushing (this includes signing,
284
+ portable-patch replay, archive/COPYING and signed-draft gates):
285
+
286
+ ```sh
287
+ python3 -m unittest discover -s ci/test
288
+ ```
289
+
290
+ A release tag does not need to be reachable from `main`. Permanent tag pushes
291
+ start fresh five-platform builds and a tag-only signed-draft job; manual
292
+ dispatch remains a read-only rehearsal. Release validation requires the tag
293
+ target to match its canonical `roots/<core-version>` branch. The release patch
294
+ is generated from the Core tag and canonical commits at release time and is not
295
+ checked into the repository. It deliberately excludes `.github/**`: Roots'
296
+ GitHub Actions and repository-management files remain in the canonical branch
297
+ and release tag, while the portable patch contains the product code, build
298
+ support, documentation, and source tests. Replay verification requires every
299
+ path outside `.github/**` to match the release tag and confirms that the patch
300
+ leaves Core's own `.github/**` tree unchanged.
301
+
302
+ Before pushing a tag, the patch artifact can be generated and replay-verified
303
+ locally without adding it to Git:
304
+
305
+ ```sh
306
+ ci/release/create-patch-series.sh "$release_tag" \
307
+ "/tmp/bitcoin-roots-${release_tag#v}.patch"
308
+ ```
309
+
310
+ The series contains inherited CRLF files. Apply the released mbox with
311
+ `git am -3 --keep-cr <bitcoin-roots-*.patch>` so Git's mail parser preserves
312
+ those bytes. Replay verification uses the same command and checks tree equality
313
+ outside `.github/**`.
314
+
315
+ Both workflow paths build Linux x86_64/aarch64, macOS x86_64/arm64 and Windows
316
+ x86_64 packages, preserving existing project license files and staging canonical
317
+ `COPYING` before archive upload. The user deferred expanded dependency
318
+ copyright/REUSE coverage to future releases. Dependency notice collection and
319
+ its schema are optional tooling, not a current release gate; no complete
320
+ coverage claim is made. See `ci/release/README.md` for that optional interface.
321
+
322
+ The tag-only `release` environment job waits for all five builds and the patch,
323
+ downloads only its own run's outputs and runs `prepare-release.sh`. It requires
324
+ the existing organization secret `BITCOIN_ROOTS_GPG_SK`, confined to the signing
325
+ step, and verifies checked-in public-key fingerprint
326
+ `5EADD53F2CD1F0B7AEEE920D25FC5C29CD528E32`. Missing signing capability fails.
327
+ `create-ci-draft.py` independently verifies the detached manifest signature,
328
+ packet/source/patch and fresh remote identities, and creates only a new draft
329
+ with exactly eight assets: five archives, patch, SHA512SUMS and SHA512SUMS.asc.
330
+ Every existing draft/public release blocks creation. There is no update,
331
+ clobber, deletion or replacement branch; interrupted creation requires operator
332
+ inspection, never an automatic retry that replaces partial assets.
333
+
334
+ Curated notes retain contributor credit, including #24/#25, and the CI draft
335
+ adds the actual fresh run/source identity and signing disclosures. Manifest
336
+ signing is separate from Git-tag and platform-code signing. Independently
337
+ download and verify all eight draft assets and notes before separately authorized
338
+ visibility-only publication. Verify the public release again unauthenticated.
339
+ Never replace published tags/assets; maintenance uses a reviewed new release.
340
+
341
+ ## Development verification cadence
342
+
343
+ Use affected regressions and bounded smoke campaigns while editing; reserve
344
+ one full applicable suite for acceptance. Broad optional-platform, extended and
345
+ long sanitizer/fuzz coverage runs nightly or by explicit manual selection.
346
+ See [CI commands and budgets](../../ci/README.md#fast-pr-and-development-coverage).
347
+ Local workflow/fixture tests do not establish hosted CI success.