Skip to content
Bitcoin Roots

v31.1-roots.1 · Commit 1: [PATCH 01/17] build(roots): establish v31 portability foundation

doc/roots-features.md

Before: /dev/null · After: doc/roots-features.md

File metadata
new file mode 100644
index 0000000000000000000000000000000000000000..48a828421d2248b4362e480e8c5f0088978a010d

Download original patch · Release notes

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

+ Added− RemovedUnmarked lines are context.

Scroll the code area horizontally to read long lines. The two line-number columns refer to before and after.

doc/roots-features.md ADDED
@@ -0,0 +1,442 @@
1
+ # Bitcoin Roots v31 preservation contracts
2
+
3
+ This unpublished candidate starts directly from authenticated Core v31.1.
4
+ [The port review](roots-v31-port-review.md) pins the exact source and new base,
5
+ accounts for every source commit, and records thematic ownership and gaps.
6
+
7
+ ## Availability in this candidate
8
+
9
+ The foundation carries the contract documents and CMake support for selecting
10
+ Qt 5/6 and optional system LevelDB/libsecp256k1. Embedded libraries remain the
11
+ default. Native crypto probes, descriptor-wallet/SQLite boundaries, external
12
+ signer support and QR/DBus/IPC build conditions use the v31 implementations.
13
+ These upstream build conditions are not evidence that a missing optional
14
+ library or platform was tested. See [portability profiles](roots-build-portability.md).
15
+
16
+ The source contracts below are preservation requirements, **not a claim that
17
+ Roots behavior has been ported**. Local policy/mining and strict Roots parsing
18
+ are deferred to L7; peer controls/health to L8; sweep, coin-control and per-send
19
+ RBF extensions to L9; read/write config, effective-policy RPC, resource support
20
+ and dormant statistics to L10; identity/desktop and maintenance integration to
21
+ L11. The narrow monotonic `uptime` RPC sub-aspect has reviewed upstream
22
+ equivalence; this does not retire the remaining operator-stats contract.
23
+
24
+ MiniUPnPc dependency discovery is retained, but its UPnP runtime and depends
25
+ recipe integration belong to the peer theme. The legacy `ENABLE_TOR_SUBPROCESS` declaration has no dedicated
26
+ launcher consumer; it is not an available feature. Roots Windows taskbar
27
+ progress remains deferred to desktop integration. Passing either undeclared
28
+ option to CMake does not implement it. No intended behavior is retired by a
29
+ missing dependency.
30
+
31
+ Code and test references in the contract body identify paths at pinned source
32
+ `10d772eb7f4b00b5193428a0dde4c06558d6c297`; they are rendered as source
33
+ references rather than links into this candidate when their implementation
34
+ has not been carried. Historical test results are not current candidate passes.
35
+
36
+ ## Preservation contracts
37
+
38
+ These stable IDs describe behavior to retain when moving between Core versions.
39
+ The source checked for this collection is Roots
40
+ `17e1d484aba2a881be03b8928fba3c0125e027a2`, based on authenticated Core v30.3
41
+ commit `49faec4f87f5cd19c88db01a82e5c68b087c8227`. Source and test links are
42
+ version-specific aids; neither a function name nor the location of an admission
43
+ check is a preservation requirement. The contracts do not authorize a change in
44
+ consensus, a new feature, or repair of a documented gap.
45
+
46
+ **Acceptance rule for every ID:** preserve its observable results, defaults,
47
+ supported configuration, units, errors and boundaries. Tests named below are
48
+ acceptance evidence for the cases they actually exercise, not proof of all
49
+ configurations. A **gap** names an unproved case or an implementation/documentation
50
+ conflict. Existing non-features and the wallet authorization boundary still apply.
51
+
52
+ **Retirement rule for every ID:** remove a Roots implementation only after a
53
+ reviewed upstream-equivalence comparison demonstrates the same behavior and
54
+ defaults for the listed acceptance cases and dependencies. Re-run the tests on
55
+ the new base and account for remaining gaps. A similar upstream option name,
56
+ RPC or feature is insufficient. Maintenance may retire when the new base makes
57
+ it unnecessary and its relevant validation still passes. Dormant support cannot
58
+ be represented as an adopted working feature; enabling it requires a separate
59
+ compatibility decision.
60
+
61
+ ### Local policy and mining
62
+
63
+ - **policy-parsing:** the [policy input compatibility contract](feature-contracts/policy-parsing.md)
64
+ specifies scoped grammar, effective defaults, diagnostics, migration decisions
65
+ and baseline characterization for Roots-added policy controls. Parser and
66
+ isolated startup regressions enforce the scoped strict behavior; inherited
67
+ Core option parsing remains outside that scope.
68
+ - **effective-policy:** the [effective mempool policy contract](feature-contracts/effective-policy.md)
69
+ defines an additive `getmempoolinfo.policy` object, initialized-state provenance,
70
+ units, enforcement gates and compatibility. RPC functional assertions cover
71
+ defaults, overrides, disabled settings, precedence and carrier/sub-dust
72
+ reporting/admission parity without changing local policy or consensus rules.
73
+ - **policy-standardness:** configurable local transaction, input and witness
74
+ bounds preserve rejection reasons without changing script consensus. Defaults
75
+ include 1,650-byte script policy, 20 equivalent bytes per sigop and 20 strict
76
+ bytes per sigop, 2,500 legacy sigops, bare pubkey/multisig disabled, unknown
77
+ witness outputs allowed, CAT21 locktime-marker rejection enabled and token
78
+ filters disabled. Ephemeral defaults permit anchors, but not arbitrary dust
79
+ or sends; bare anchors are allowed. See policy settings (`src/policy/settings.h`, source reference),
80
+ standardness options and constants (`src/policy/policy.h`, source reference),
81
+ checks (`src/policy/policy.cpp`, source reference) and admission (`src/validation.cpp`, source reference).
82
+ Acceptance: mempool_sigoplimit.py (`test/functional/mempool_sigoplimit.py`, source reference)
83
+ `test_sigops_limit`, `test_sigops_package`, `test_legacy_sigops_stdness` and
84
+ transaction_tests.cpp (`src/test/transaction_tests.cpp`, source reference). Gap: a complete
85
+ option/ephemeral/filter interaction matrix and explicit valid-block cases for
86
+ each local rejection are not supplied by these tests.
87
+ - **policy-carrier:** default `datacarrier=1`, aggregate carrier budget 83 bytes,
88
+ full counting enabled, nonstandard carriers and bare-carrier transactions
89
+ disabled. Recognized input/witness carriers also count with full counting;
90
+ permitting nonstandard transactions alone does not disable these checks.
91
+ `datacarriercost` defaults to 1 virtual byte per detected data byte, accepts
92
+ fixed-point values with two decimal places from 0 through 1,073,741,823.75,
93
+ and rounds the requested cost upward to integral weight units (quarters of a
94
+ vbyte). Extra weight only raises policy size. See
95
+ startup parsing (`src/init.cpp`, source reference), carrier detection (`src/policy/policy.cpp`, source reference)
96
+ and admission (`src/validation.cpp`, source reference). Acceptance:
97
+ mempool_datacarrier.py (`test/functional/mempool_datacarrier.py`, source reference) `run_test`
98
+ covers budget boundaries, disabling, extreme cost/invalid inputs and valid
99
+ blocks containing locally rejected transactions;
100
+ mempool_tests.cpp (`src/test/mempool_tests.cpp`, source reference) `MempoolExtraWeightBoundary`
101
+ covers size arithmetic. Conflict: current help says multiple outputs are
102
+ allowed, but standardness rejects more than one OP_RETURN output as
103
+ `multi-op-return`. Preserve the actual rejection until explicitly decided;
104
+ help wording is not authority to widen admission. `test_taproot_carrier` in
105
+ `mempool_datacarrier.py` independently checks a maximum-size push/OP_DROP
106
+ tapscript: default nonstandard-carrier rejection, aggregate budget rejection,
107
+ admission at the exact carrier budget when permitted, and valid-block acceptance.
108
+ mempool_subdust_fee_penalty.py (`test/functional/mempool_subdust_fee_penalty.py`, source reference)
109
+ `test_carrier_cost_interaction` covers output-carrier fractional cost rounding,
110
+ zero cost, full-count disabling and composition with the dust deficit.
111
+ Gap: other recognized input/witness carrier patterns and their fractional
112
+ cost/full-count interactions.
113
+ The inherited feature_taproot.py (`test/functional/feature_taproot.py`, source reference)
114
+ fixture `tapscript/pushmaxlimit` expects admission under that test's explicit
115
+ nonstandard-carrier allowance and enlarged budget, subject to its existing
116
+ witness-size checks. The incorrect unconditional nonstandard marker was
117
+ removed to match this configuration; the oversized push still fails consensus.
118
+ - **policy-dust:** thresholds use the effective dust relay rate; the floor is
119
+ 3,000 sat/kvB (`dustrelayfee=0.00003000` BTC/kvB). `dustdynamic=off` is the
120
+ default. Dynamic mode is `[multiplier*]target:blocks` or
121
+ `[multiplier*]mempool:kvB`; multiplier defaults to 3, is stored in thousandths
122
+ and must be positive. Target is at least two blocks and no more than the
123
+ estimator's longest tracked target; mempool position is at least 1 kvB.
124
+ Dynamic estimates are multiplied, converted to integral sat/kvB and clamped
125
+ to the configured floor. The scheduler updates the rate every 15 minutes;
126
+ missing estimates fall back to the floor. The published rate
127
+ and standardness snapshot must agree under concurrent access. See
128
+ parser (`src/node/mempool_args.cpp`, source reference), publication (`src/txmempool.cpp`, source reference) and
129
+ threshold calculation (`src/policy/policy.cpp`, source reference). Acceptance:
130
+ mempool_dust.py (`test/functional/mempool_dust.py`, source reference) `test_dust_output` and
131
+ `test_dustrelay` cover script-dependent thresholds, exact threshold/one below,
132
+ and zero-rate behavior; mempool_tests.cpp (`src/test/mempool_tests.cpp`, source reference)
133
+ `DynamicDustFeePublication` covers changing snapshots. Gap: estimator-target
134
+ mode without an estimator is accepted by the parser; it is not evidence of a
135
+ working estimate. Extreme dynamic multiplier arithmetic needs separate coverage.
136
+ - **policy-subdust:** apply a configurable deficit penalty to modified fees,
137
+ using script-specific dust thresholds, without changing the actual fee or
138
+ consensus validity. Enabled by default. The
139
+ [worked contract](/doc/feature-contracts/subdust.md) defines units, rounding,
140
+ saturation, exemptions, precedence, interactions, acceptance cases and gaps.
141
+ - **policy-replacement:** default full RBF (`mempoolreplacement=fee,-optin`)
142
+ and enforced TRUC (`mempooltruc=enforce`). `Never` disables all replacement;
143
+ `OptIn` replaces directly signaling originals or v3 originals, including
144
+ non-signaling v3; full RBF still requires fee/resource replacement checks.
145
+ TRUC can instead be rejected or accepted without enforcing TRUC-specific
146
+ limits. `getmempoolinfo.fullrbf` means configured full RBF, so false does not
147
+ mean v3 replacements are disabled. Explicit `optin` wins over
148
+ `mempoolfullrbf=1`; explicit replacement disabling also wins and warns on
149
+ that contradiction. See selection (`src/node/mempool_args.cpp`, source reference),
150
+ admission/replacement (`src/validation.cpp`, source reference) and RPC (`src/rpc/mempool.cpp`, source reference).
151
+ Acceptance: mempool_rbf_policy.py (`test/functional/mempool_rbf_policy.py`, source reference)
152
+ `POLICIES`/`check_replacement` and
153
+ mempool_truc.py (`test/functional/mempool_truc.py`, source reference) `test_truc_replacement`,
154
+ `test_truc_reorg`, `test_minrelay_in_package_combos`, plus package/sibling
155
+ cases. Gap: all TRUC-mode/replacement-mode combinations and conflicting option
156
+ inputs. Current initialized incremental relay fee is 100 sat/kvB, while
157
+ startup help advertises 1,000; this is a recorded conflict, not a promised
158
+ change to the effective default.
159
+ - **policy-coinage:** minimum relay maturity and coin-block age both default to
160
+ zero (disabled). Maturity counts depth at the next block height; coin-block
161
+ age sums input satoshis times blocks since each coin's height. Unconfirmed
162
+ inputs add no confirmed age. These are additional local gates, never changes
163
+ to coinbase consensus maturity. See coin age (`src/policy/coin_age_priority.cpp`, source reference)
164
+ and admission (`src/validation.cpp`, source reference). Acceptance: priority accounting cases in
165
+ miner_tests.cpp (`src/test/miner_tests.cpp`, source reference) `CreateNewBlock_validity` cover the
166
+ shared age cache. Gap: dedicated enabled/disabled relay maturity/coin-block
167
+ boundaries and their valid-block fixtures.
168
+ - **policy-reuse:** `spkreuse=allow` defaults to no extra restriction. The
169
+ documented alternative `conflict` uses mempool scriptPubKey creation/spend
170
+ tracking to reject reuse or consider policy conflicts for replacement. This is a local
171
+ script rule, not a privacy score, address-ownership inference or consensus
172
+ prohibition. See mode selection (`src/init.cpp`, source reference), admission (`src/validation.cpp`, source reference)
173
+ and tracking (`src/txmempool.cpp`, source reference). Gap: no dedicated functional acceptance
174
+ test for these modes, reorg tracking and replacement interactions is identified;
175
+ generic mempool tests are not a substitute.
176
+ - **mining-template:** with neither size nor weight option specified, the
177
+ effective local limit is 1,200,000 weight units with no additional size cap
178
+ below the 4,000,000-byte protocol bound; minimum fee is 1,000 sat/kvB and
179
+ priority area is 100,000 serialized bytes. An explicit size-only option leaves
180
+ weight unrestricted up to consensus maximum, and a weight-only option leaves
181
+ size unrestricted; setting both enforces both. Priority area can be zero. Transactions
182
+ selected by priority and their fee-selected descendants must have accurate
183
+ ancestor weight/sigop accounting and appear at most once in dependency order.
184
+ See option normalization/assembly (`src/node/miner.cpp`, source reference) and
185
+ defaults (`src/policy/policy.h`, source reference). Acceptance:
186
+ miner_tests.cpp (`src/test/miner_tests.cpp`, source reference) `CreateNewBlock_validity` priority
187
+ ancestor boundary cases and
188
+ mining_prioritisetransaction.py (`test/functional/mining_prioritisetransaction.py`, source reference)
189
+ `run_test`. `test_mining_and_block_acceptance` in
190
+ mempool_subdust_fee_penalty.py (`test/functional/mempool_subdust_fee_penalty.py`, source reference)
191
+ covers modified-fee selection with priority enabled/disabled, penalty
192
+ disabling, unchanged actual fee rewards and a locally rejected valid-block
193
+ fixture. Conflict: inherited help advertised a 300,000-byte size default, while
194
+ assembler options (`src/node/miner.h`, source reference) leave size at the protocol maximum when
195
+ unset; `policy-parsing` corrected that help while preserving the interaction.
196
+ Gap: every size/weight/reserve/priority combination; mining a small
197
+ local template must never limit acceptance of a larger consensus-valid block.
198
+
199
+ ### Peer controls and current-connection health
200
+
201
+ - **peer-controls:** retain Core's P2P protocol and inherited orphan/upload/
202
+ whitelist controls. Roots additionally bounds compact reconstruction extras
203
+ by count (default 32,768) and memory (10 decimal MB), excluding oversized
204
+ individual extras; provides `forceinbound` (implies `noban`) and explicit
205
+ compact-filter permissions; permits subnet disconnect; and can disable
206
+ outbound v1 on clearnet (`v2onlyclearnet`, default false). Default fee filters
207
+ are enabled. Bloom service is not globally advertised by default, with
208
+ implicit loopback permission when not explicitly disabled. Retain inactivity
209
+ limits, protected outbound/manual peers, bounded address scoring/cache behavior,
210
+ duplicate manual-connection checks and block-fetch safeguards. Tor binds must
211
+ not accidentally grant clearnet whitelist permission; SOCKS credentials must
212
+ not be logged. See networking (`src/net.cpp`, source reference),
213
+ processing (`src/net_processing.cpp`, source reference), permissions (`src/net_permissions.cpp`, source reference)
214
+ and proxy (`src/netbase.cpp`, source reference). Acceptance:
215
+ p2p_compactblocks_extratxs.py (`test/functional/p2p_compactblocks_extratxs.py`, source reference),
216
+ p2p_permissions.py (`test/functional/p2p_permissions.py`, source reference),
217
+ p2p_disconnect_ban.py (`test/functional/p2p_disconnect_ban.py`, source reference),
218
+ p2p_eviction.py (`test/functional/p2p_eviction.py`, source reference),
219
+ p2p_filter.py (`test/functional/p2p_filter.py`, source reference) and
220
+ p2p_invalid_messages.py (`test/functional/p2p_invalid_messages.py`, source reference), each
221
+ `run_test`. Gap: the full new permission/memory/transport/Tor-bind combination
222
+ matrix and platform-specific CPU measurement.
223
+ - **peer-health:** keep sorting/selection and current connection facts in the
224
+ existing peer table/detail pane. Missing state must reset to unavailable,
225
+ never another peer's stale values. Node RPC adds last block announcement,
226
+ forced-inbound state, deprecated misbehavior score and optional CPU load in
227
+ per mille of connection duration; omit CPU load when not measured or duration
228
+ is unsuitable. No history retention or content/activity feed. See
229
+ peer RPC (`src/rpc/net.cpp`, source reference), peer table (`src/qt/peertablemodel.cpp`, source reference) and
230
+ details (`src/qt/rpcconsole.cpp`, source reference). Acceptance:
231
+ apptests.cpp (`src/qt/test/apptests.cpp`, source reference) `consoleTests` resets unavailable
232
+ details; rpc_net.py (`test/functional/rpc_net.py`, source reference) `run_test` covers RPC.
233
+ Gap: visual checks at 1280×800 and 1920×1080, 100%/150% font scale, populated
234
+ sorting/selection and refresh; these were not executed by the headless baseline.
235
+
236
+ ### Wallet authorization, signing and spend controls
237
+
238
+ - **wallet-foundation:** descriptor/SQLite wallets and optional external signing
239
+ are inherited Core foundations. Roots rejects unwritable database directories,
240
+ avoids recursively scanning node database directories and symlink/reparse
241
+ points, and closes unrelated child descriptors for signer commands. Preserve
242
+ normal wallet locking and error reporting; do not introduce another database,
243
+ backup/flush promise or Berkeley DB build option. See database (`src/wallet/db.cpp`, source reference),
244
+ SQLite (`src/wallet/sqlite.cpp`, source reference), filesystem helpers (`src/util/fs_helpers.cpp`, source reference)
245
+ and signer child invocation (`src/common/run_command.cpp`, source reference). Acceptance:
246
+ wallet_multiwallet.py (`test/functional/wallet_multiwallet.py`, source reference),
247
+ wallet_signer.py (`test/functional/wallet_signer.py`, source reference) and
248
+ wallet_tests.cpp (`src/wallet/test/wallet_tests.cpp`, source reference). Gap: platform-specific
249
+ reparse-point/permission cases and external signer availability in each build.
250
+ - **wallet-rbf:** the per-send GUI choice starts from the wallet's `walletrbf`
251
+ preference (Core default true), explicitly overrides it for the prepared
252
+ transaction, and shows its resulting signaling in confirmation and saved
253
+ PSBT. It is a signaling choice, not a guarantee of network replacement. See
254
+ Send dialog (`src/qt/sendcoinsdialog.cpp`, source reference) and
255
+ wallet model (`src/qt/walletmodel.cpp`, source reference). Acceptance:
256
+ wallettests.cpp (`src/qt/test/wallettests.cpp`, source reference) `walletTests` explicit on/off
257
+ override and decoded PSBT sequence assertions. Gap: visual confirmation/font
258
+ scale matrix, not established by a headless build.
259
+ - **wallet-sweep:** only documented WIF/script forms, local-key descriptor
260
+ destination in the selected wallet, no key import, preview by default and
261
+ final authorization before broadcast. Fee state is snapshotted under wallet
262
+ locking; cancellation/invalidation can stop scanning or preview, while accepted
263
+ broadcast submission completes. Reduce secret lifetime using secure storage,
264
+ cleansing and console redaction without claiming complete host/toolkit erasure.
265
+ The full operational contract is [wallet-privacy.md](/doc/wallet-privacy.md).
266
+ See RPC (`src/wallet/rpc/spend.cpp`, source reference), construction (`src/wallet/spend.cpp`, source reference)
267
+ and dialog (`src/qt/sweepdialog.cpp`, source reference). Acceptance:
268
+ wallet_sweepprivkeys.py (`test/functional/wallet_sweepprivkeys.py`, source reference) `run_test`
269
+ covers supported script forms, destination rejection, no import, stale/conflicting
270
+ previews and broadcast; wallettests.cpp (`src/qt/test/wallettests.cpp`, source reference)
271
+ `walletTests` covers secure cache and preview invalidation;
272
+ test_wallet_privacy_contract.py (`ci/test/test_wallet_privacy_contract.py`, source reference)
273
+ checks source structure of authorization/redaction boundaries. Gap: that static
274
+ check is not a race proof; cancellation/authorization concurrency and GUI
275
+ confirmation need runtime and visual evidence.
276
+ - **wallet-coin-control:** expose wallet facts, effective value, locked/reused/
277
+ grouped outputs and send fee/change/RBF consequences. Locked outputs remain
278
+ visible but unselectable; ordinary availability filters still exclude unsafe
279
+ and immature outputs. Material wallet changes clear explicit selection.
280
+ Conspicuously validate custom change; do not add automatic consolidation or
281
+ anonymity claims. See [wallet-privacy.md](/doc/wallet-privacy.md),
282
+ coin control (`src/qt/coincontroldialog.cpp`, source reference) and
283
+ wallet facts (`src/wallet/rpc/wallet.cpp`, source reference). Acceptance:
284
+ wallettests.cpp (`src/qt/test/wallettests.cpp`, source reference) `walletTests` selected/locked
285
+ and invalidation cases, wallet_send.py (`test/functional/wallet_send.py`, source reference) and
286
+ test_wallet_privacy_contract.py (`ci/test/test_wallet_privacy_contract.py`, source reference)
287
+ row-filter assertions. Gap: populated GUI and custom-change visual matrix.
288
+
289
+ ### Runtime, configuration, portability and identity
290
+
291
+ - **runtime-config:** `confrw` defaults to network-datadir `bitcoin_rw.conf`.
292
+ Preserve recognized settings and precedence: internal forced settings, CLI,
293
+ read/write config, JSON settings, network config section, default config
294
+ section, then built-in default. For ordinary scalar values, CLI uses its last
295
+ value and config uses its first after negation processing; list/chain/network
296
+ options have separate inherited rules. Typed getters and diagnostics must not
297
+ leak secrets. See merging (`src/common/settings.cpp`, source reference),
298
+ configuration (`src/common/config.cpp`, source reference) and access/writes (`src/common/args.cpp`, source reference).
299
+ Acceptance: getarg_tests.cpp (`src/test/getarg_tests.cpp`, source reference) and
300
+ feature_config_args.py (`test/functional/feature_config_args.py`, source reference) `run_test`.
301
+ Scoped Roots policy grammar and its acceptance gates are specified by
302
+ `policy-parsing`.
303
+ - **operator-stats:** `uptime` returns elapsed seconds from a monotonic clock,
304
+ independent of adjusted wall-clock time; acceptance:
305
+ rpc_uptime.py (`test/functional/rpc_uptime.py`, source reference) `run_test`.
306
+ Retained statistics source defines `time_from`, `time_to`, and arrays of
307
+ `[relative_seconds, tx_count, mempool_bytes, minimum_fee_sat_per_kB]`, without
308
+ interpolation. The in-memory target is 10 MiB, cleanup is periodic rather
309
+ than a hard allocation ceiling, and enabled collection would be controlled
310
+ by a positive target. See stats model (`src/stats/stats.cpp`, source reference),
311
+ schema (`src/stats/rpc_stats.cpp`, source reference), startup declarations (`src/stats/init.cpp`, source reference)
312
+ and monotonic source (`src/common/system.cpp`, source reference). Gap/conflict: production does
313
+ not call registration, option initialization or sample collection at the
314
+ pinned source. `stats_tests/stats` in
315
+ stats_tests.cpp (`src/stats/test/stats_tests.cpp`, source reference) exercises the model directly,
316
+ not an available RPC. GUI-on/headless-off help wording also conflicts with
317
+ the model's default-disabled constant. Wiring and schema/default decisions
318
+ must be reviewed before claiming preservation of a working statistics service.
319
+ - **runtime-resources:** RAM detection influences inherited node cache sizing;
320
+ advisory file allocation must preserve existing bytes, FD limits and GiB
321
+ conversion must avoid overflow. Memory-pressure and I/O-priority helpers are
322
+ platform-scoped support, not proof of active consumers on each platform.
323
+ See cache sizing (`src/node/caches.cpp`, source reference), FS helpers (`src/util/fs_helpers.cpp`, source reference),
324
+ memory pressure (`src/util/mempressure.cpp`, source reference) and I/O priority (`src/util/ioprio.cpp`, source reference).
325
+ Acceptance: system_ram_tests.cpp (`src/test/system_ram_tests.cpp`, source reference),
326
+ fs_tests.cpp (`src/test/fs_tests.cpp`, source reference) and util_tests.cpp (`src/test/util_tests.cpp`, source reference).
327
+ Gap: platform/failure/concurrency evidence for unused helpers; no dedicated
328
+ Tor-launch behavior is established by a build flag.
329
+ - **build-portability:** retain supported CMake switches and actual dependency
330
+ probes, Qt 5/6 branches, QR/signer/taskbar conditions, native crypto flags,
331
+ and usable system LevelDB memory environment. Defaults include wallet/tests
332
+ enabled, GUI disabled, embedded LevelDB/secp256k1. IPC can be deliberately
333
+ disabled, with no IPC coverage claim. See CMakeLists.txt (`CMakeLists.txt`, source reference),
334
+ build guides (`doc/build-unix.md`, source reference), dependencies (`doc/dependencies.md`, source reference) and
335
+ LevelDB probe (`cmake/module/FindLevelDB.cmake`, source reference). Acceptance: configure/build
336
+ each supported profile and its registered `ctest` targets; build-contract
337
+ checks in ci/test (`ci/test`, source reference). Gap: the baseline covers one Linux headless
338
+ wallet profile, not all optional/platform configurations. `ENABLE_TOR_SUBPROCESS`
339
+ has no production consumer and cannot promise an automatic Tor instance.
340
+ - **identity-desktop:** built tools identify Roots and the selected version;
341
+ retain Roots icons and upstream/protocol attribution, QR-to-PNG export and
342
+ supported Windows taskbar progress without mass-rebranding history. See
343
+ version (`src/clientversion.cpp`, source reference), QR export (`src/qt/qrimagewidget.cpp`, source reference) and
344
+ taskbar (`src/qt/wintaskbarprogress.cpp`, source reference). Acceptance:
345
+ apptests.cpp (`src/qt/test/apptests.cpp`, source reference) `consoleTests` QR/icon assertions,
346
+ binary `-version`, and supported Qt/platform builds. Gap: QR/receive UI at both
347
+ resolutions/font scales and Windows taskbar runtime evidence.
348
+
349
+ ### Maintenance dispositions
350
+
351
+ These IDs account for source work without treating it as operator behavior.
352
+
353
+ - **maintenance-ci:** classifiers, test fixtures, sanitizer/corpus scheduling,
354
+ platform checks and reuse of proven promotion CI. Acceptance:
355
+ `python3 -m unittest discover -s ci/test`, relevant lint and actual required
356
+ candidate CI profiles. Equivalent infrastructure must test the exact candidate;
357
+ a successful older workflow/build cannot retire the gate.
358
+ - **maintenance-release:** immutable source/tag/asset validation, portable
359
+ export/replay with `.github` exclusions and `git am -3 --keep-cr`, contributor
360
+ credit, five-platform archives, canonical COPYING, signature trust and
361
+ new-draft-only behavior. See maintainer workflow (`contrib/roots/README.md`, source reference)
362
+ and release tools (`ci/release/README.md`, source reference); acceptance: their tests under
363
+ ci/test (`ci/test`, source reference) and temporary export/replay. Optional notice tools do not
364
+ prove complete dependency copyright coverage. Publishing, tagging and remote
365
+ canonical updates are outside these contracts' implementation work.
366
+ - **maintenance-docs:** catalog/provenance/privacy/guidance, release notes and
367
+ generated manuals/example config follow the actual source/help. Acceptance:
368
+ check-doc.py (`test/lint/check-doc.py`, source reference), local links, `git diff --check` and
369
+ regenerated-output comparison when interfaces change. Preserve upstream names
370
+ where they identify lineage rather than Roots UI.
371
+ - **maintenance-native:** behavior-preserving C++ modernization and test/fuzz
372
+ fixture adaptation, safe empty file writes and test-only assertion hooks.
373
+ Acceptance: affected unit/functional/fuzz suites and diff inspection. Reverted
374
+ transient script changes do not create a consensus contract or require a port.
375
+
376
+ ### Dependencies by stable ID
377
+
378
+ The shared consensus-neutral and configuration rules apply to every contract.
379
+ This table records additional feature dependencies; identifiers remain separate
380
+ even when implementations share a commit or file.
381
+
382
+ | Contract | Depends on |
383
+ | --- | --- |
384
+ | policy-standardness | None |
385
+ | policy-carrier | policy-standardness |
386
+ | policy-dust | policy-standardness |
387
+ | policy-subdust | policy-dust |
388
+ | policy-replacement | policy-standardness |
389
+ | policy-coinage | None |
390
+ | policy-reuse | policy-standardness |
391
+ | mining-template | policy-coinage, policy-carrier, policy-replacement |
392
+ | policy-parsing | runtime-config, policy-standardness, policy-carrier, policy-dust, policy-subdust, policy-replacement, policy-coinage, policy-reuse, mining-template |
393
+ | effective-policy | policy-parsing, runtime-config, policy-standardness, policy-carrier, policy-dust, policy-subdust, policy-replacement, policy-coinage, policy-reuse |
394
+ | peer-controls | policy-replacement |
395
+ | peer-health | peer-controls |
396
+ | wallet-foundation | build-portability |
397
+ | wallet-rbf | wallet-foundation, policy-replacement |
398
+ | wallet-sweep | wallet-foundation, wallet-rbf, runtime-config |
399
+ | wallet-coin-control | wallet-foundation, wallet-rbf |
400
+ | operator-stats | runtime-config |