Diff to enable this looks something like this:
diff --git a/.clang-tidy b/.clang-tidy
index c0a984def..941f67e03 100644
--- a/.clang-tidy
+++ b/.clang-tidy
@@ -39,11 +39,16 @@ Checks: >
-performance-no-int-to-ptr,
portability-*,
readability-*,
- -readability-function-cognitive-complexity,
-readability-identifier-length,
-readability-avoid-nested-conditional-operator,
-readability-convert-member-functions-to-static,
+CheckOptions:
+ - key: readability-function-cognitive-complexity.IgnoreMacros
+ value: 'true'
+ - key: readability-function-cognitive-complexity.Threshold
+ value: '50'
+
WarningsAsErrors: '*'
HeaderFilterRegex: '?!(3rdparty)'
FormatStyle: 'file'
I think we definitely want to ignore macros, because our logging macros are measured as extremely complex but in practice don't make the functions harder to read.
The default threshold is 25, which flags a huge number of functions, and I think is a little low. I suggest we start with a higher threshold, such as 50, for at least an initial pass.
A benefit of this (beyond pure readability) should be that we improve the clang-tidy coverage for other checks - such as bugprone-unchecked-optional-access - to silently fail, missing clear errors. By simplifying functions, reducing the scope that these checks need to analyse, we should get better coverage. One frustrating niggle is that it's not clear to me what a "safe" threshold for this is - the "cognitive complexity" does not directly correspond with the flow-analysis complexity that causes these checks to fail, and we don't know what threshold the checks fail at. But these measures are likely correlated, and we can do some work to validate where certain checks are and are not being run.
Remaining work after #8504
The check is already enabled by #7995 with Threshold=50 and IgnoreMacros=true. The remaining work is to remove the baseline suppressions through behaviour-preserving refactors.
Inventory checked against main at a6fe2f2 on 2026-10-05, excluding NodeEndpoints::init_handlers, which the now-merged #8504 addresses. The post-#8504 backlog contains six top-level functions plus two nested callbacks, covered by seven suppression sites across five files. The two mechanical follow-up PRs below are open, not yet merged.
Scores below are the historical measurements at bc7f0cf from the earlier comment, not newly measured scores on the current revision. Each refactor should verify that the registration function and all extracted callbacks meet the threshold, rather than merely moving the suppression.
| Baseline score |
Function |
Location |
Remaining approach |
Follow-up |
| 277 |
Logging sample init_handlers |
samples/apps/logging/logging.cpp:593 |
Mechanical: extract inline endpoint handlers, preserving registration, authentication, forwarding, and handler behaviour. |
#8508 (open) |
| 66 |
setup_basic_hooks |
src/node/node_state.h:3277 |
Mechanical: extract hook callbacks, preserving hook order, capture lifetimes, and commit/rollback behaviour. |
#8509 (open) |
| 125; nested callbacks 89 and 61 |
initiate_join_unsafe and its response/task callbacks |
src/node/node_state.h:1382 |
Partly mechanical: callback extraction reduces the outer score, but the callbacks themselves still need decomposition of join-response handling. |
Not started |
| 69 |
fill_range_response_from_file |
src/node/rpc/file_serving_handlers.h:173 |
Control-flow decomposition: isolate range parsing/response construction while preserving validation and HTTP semantics. |
Not started |
| 90 |
process_command_inner |
src/node/rpc/frontend.h:707 |
Careful request-path decomposition: preserve authentication, forwarding, transaction/retry behaviour, and error paths. |
Not started |
| 102 |
do_execute_request |
src/js/registry.cpp:58 |
Careful JS execution-path decomposition: preserve exception/timeout handling, ownership, and response semantics. |
Not started |
Already addressed since the earlier inventory: the two unit-test suppressions (#8482), governance ack handlers (#8484), service-state handlers (#8486), proposal handlers (#8487), file-serving handler registration (#8488), and the programmability constructor (#8489). Node endpoint registration is addressed by #8504.
Actual clang-tidy 18.1.8 measurements with IgnoreMacros=true in the open follow-ups: #8508 reduces logging init_handlers from 277 to 0, with all 41 extracted handlers scoring at most 31; #8509 reduces setup_basic_hooks from 66 to 0, with all six extracted callbacks scoring at most 12. All retained registration adapters in both PRs score 0. Neither PR changes thresholds or adds complexity suppressions.
After these two PRs land, the three control-flow refactors and the partially mechanical join-response item remain for assessment.
Diff to enable this looks something like this:
I think we definitely want to ignore macros, because our logging macros are measured as extremely complex but in practice don't make the functions harder to read.
The default threshold is 25, which flags a huge number of functions, and I think is a little low. I suggest we start with a higher threshold, such as 50, for at least an initial pass.
A benefit of this (beyond pure readability) should be that we improve the
clang-tidycoverage for other checks - such asbugprone-unchecked-optional-access- to silently fail, missing clear errors. By simplifying functions, reducing the scope that these checks need to analyse, we should get better coverage. One frustrating niggle is that it's not clear to me what a "safe" threshold for this is - the "cognitive complexity" does not directly correspond with the flow-analysis complexity that causes these checks to fail, and we don't know what threshold the checks fail at. But these measures are likely correlated, and we can do some work to validate where certain checks are and are not being run.Remaining work after #8504
The check is already enabled by #7995 with
Threshold=50andIgnoreMacros=true. The remaining work is to remove the baseline suppressions through behaviour-preserving refactors.Inventory checked against
mainat a6fe2f2 on 2026-10-05, excludingNodeEndpoints::init_handlers, which the now-merged #8504 addresses. The post-#8504 backlog contains six top-level functions plus two nested callbacks, covered by seven suppression sites across five files. The two mechanical follow-up PRs below are open, not yet merged.Scores below are the historical measurements at bc7f0cf from the earlier comment, not newly measured scores on the current revision. Each refactor should verify that the registration function and all extracted callbacks meet the threshold, rather than merely moving the suppression.
init_handlerssetup_basic_hooksinitiate_join_unsafeand its response/task callbacksfill_range_response_from_fileprocess_command_innerdo_execute_requestAlready addressed since the earlier inventory: the two unit-test suppressions (#8482), governance ack handlers (#8484), service-state handlers (#8486), proposal handlers (#8487), file-serving handler registration (#8488), and the programmability constructor (#8489). Node endpoint registration is addressed by #8504.
Actual clang-tidy 18.1.8 measurements with
IgnoreMacros=truein the open follow-ups: #8508 reduces logginginit_handlersfrom 277 to 0, with all 41 extracted handlers scoring at most 31; #8509 reducessetup_basic_hooksfrom 66 to 0, with all six extracted callbacks scoring at most 12. All retained registration adapters in both PRs score 0. Neither PR changes thresholds or adds complexity suppressions.After these two PRs land, the three control-flow refactors and the partially mechanical join-response item remain for assessment.