Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

しきい値の選択

bca check compares each metric against a limit you configure. This page explains where the shipped defaults come from, how to adjust them for the language you are gating, and how to pick a different set for a different job. It is for anyone editing a [thresholds] table, manually or through a coding agent.

まだゲートを設定していない場合は、仕組みについてはローカルしきい値ゲートから、すでに抱えている違反者の吸収についてはベースラインから始めてください。このページは数値そのものを扱います。

出荷時のデフォルト

bca init scaffolds this table. It is defined once in big-code-analysis-cli/src/default_thresholds.rs. The anchor column cites MISRA and Flog alongside the tools linked inline.

メトリクス上限スコープアンカー
cognitive15関数SonarSource のデフォルト
cyclomatic15関数lizard のデフォルト。MISRA と NASA のセーフティクリティカル上限
abc40関数RuboCop AbcSize の 17 と、Flog の「60 以上は危険」の中間
nargs5関数RuboCop ParameterLists の 5。Code Climate はより厳しい 4
nexits5関数Code Climate return-statements の 4
halstead.effort50000関数公表値なし。パーセンタイルから導出
loc.ploc600ファイル公表値なし。パーセンタイルから導出
loc.sloc1200ファイル肥大化の歯止めであり、実働の制限ではない
nom30コンテナCode Climate method-count の 20。PMD TooManyMethods の 10
wmc60コンテナ公表値なし。パーセンタイルから導出

これらを読むときはスコープが重要です。cognitive の制限は各関数に適用されます。nom と wmc は各クラス・struct・trait・impl・名前空間・インターフェイスに適用されます。loc.* はファイル全体のルートに適用されます。bca check がコンテナのメソッド数を関数単位の制限と比較することはありません。スコープ規則の全体は Check を参照してください。

Two of these limits need their reasoning spelled out.

loc.ploc と loc.sloc は対になっています。PLOC は空行とコメントを除いた物理コード行数を数えるので、実働のファイルサイズ制限です。判断の経緯を文書化してファイルが伸びても、この制限に対するコストはゼロです。SLOC はすべてを数えるため、はるかに緩い位置に置かれ、仕事は 1 つだけです。それは、loc.ploc をクリアしたまま、コメント量によってファイルが際限なく成長するのを止めることです。ファイルサイズを SLOC だけでゲートすると、根拠の説明 1 段落にも新しい分岐 1 つと同じ代償を課すことになり、観測される結果は、人々がその根拠説明を削除することです。

cyclomatic を McCabe の 10 ではなく 15 とするのは意図的な緩和です。10 を標準的な数値として定着させた文書である NIST 500-235 は、それを正当化できるプロセスを持つチームには引き上げを認めており、15 という高さの制限も成功裏に使われてきたと述べています。実際のコードで測定すると、10 は 15 のおよそ 2 倍の関数をフラグしますが、レビュアーが問題と呼ぶものが相応に増えるわけではありません。

デフォルト値の導出方法

Published thresholds disagree with each other by wide margins. For cyclomatic complexity alone the defaults in common tools span 7 (RuboCop) to 30 (gocyclo), with Checkstyle and PMD at 10, lizard and MISRA at 15, and ESLint at 20. Picking one by authority means picking an authority.

So each limit here is checked against measurement as well. The reference corpus, as measured for #1140, was 43 real-world repositories across 20 languages, cloned at their default branch on 2026-07-31, with test trees, vendored code, and generated files excluded. Measured with bca metrics, that is roughly a quarter of a million function spaces, forty thousand container spaces, and twenty-seven thousand files. Values are binned by the same File, Function, and Container scope bca check applies, so a container’s nom never lands in a per-function distribution.

設計ルールは、デフォルト値が中央値の言語でおよそ最悪 1% 〜 3% のスペースをフラグすべき、というものです。それを下回ると制限は機能せず、誤った安心感を与えます。それを上回るとゲートはゲートでなくなり、人々が迂回するスタイルルールになります。これは、70・80・90 パーセンタイルでリスク帯を導出する Alves, Ypma, and Visser のベンチマークアプローチをより厳格に読み替えたものです。彼らの 90 パーセンタイルは「見る価値がある」ラインとしては有用ですが、ビルドを失敗させるにはノイズが多すぎます。

Two of the previous defaults failed that rule and changed as a result. The original corpus measurement found that nargs = 7 flagged fewer than 1% of functions in the median language, and nothing at all in this project’s own source: a limit that cannot catch anything. That measurement includes nested-closure parameters, which #1196 later removed from nargs; the current own-parameter metric cannot produce a higher count on the same inputs, and the drop is largest for closure-heavy languages, so the conclusion holds. The shipped limit is therefore stricter. cognitive at 25 was inherited from clippy, which is deliberately conservative because it lints rather than gates; 15 is what the metric’s designers chose.

言語ごとのオーバーライド

メトリクスの分布は、プロジェクトよりも言語によって大きく変わります。参照コーパスにおける関数ごとの cognitive の 90 パーセンタイル値は、C# の 0 から Tcl の 21 まで広がっています。ファイルの loc.ploc の中央値は TypeScript の 16 から C の 283 までで、18 倍の開きがあります。1 つの表で両端をカバーすることはできません。

以下の表は言語ごとに測定した 97.5 パーセンタイルを示します。これは、その言語のコードの最悪 2.5% をフラグするために制限が取るべき値です。処方箋ではなく較正データとして読んでください。数値が低いのはその言語のコードが概ね単純だということであり、引き締めることが「できる」理由ではあっても、そうすべきだという証拠ではありません。

言語cognitivecyclomaticabchalstead.effortloc.ploc
Bash35256044000(サンプル不足)
C5030601900003500
C++14102554000(サンプル不足)
C#441344000700
Elixir5720150001500
Go251745890001500
Groovy16132525000450
Java751620000800
JavaScript201535170000(サンプル不足)
Kotlin1082018000300
Lua35204082000800
Objective-C18123577000(サンプル不足)
Perl352545410001500
PHP1092526000900
Python20132542000700
Ruby76195000400
Rust882034000900
Tcl45258546000(サンプル不足)
TypeScript20132560000450
TSX141065130000400

「サンプル不足」は、コーパス内のファイル数が少なすぎてファイルサイズの数値を導出できない言語を示します。Bash、Tcl、JavaScript、Objective-C の関数ごとの数値は表の中で最も小さいサンプルに基づいており、自分のコードに対して再導出する価値が最も高いものです。

The halstead.effort column comes from a different measurement than the rest of the table. It was re-measured on 2026-10-10, after the Halstead vocabulary changes in #1486 through #1573, on a rebuilt corpus of 41 repositories that is comparable to the original but not identical to it. The C, C++, and Objective-C rows were re-measured on 2026-10-15 to include the declaration modifiers of #1578 and #1579. The repository list and commits are recorded in docs/development/threshold_corpus.md. Several rows moved by a factor of two to five, and almost all of that movement came from the change of repositories, not from the metric: the same 41 repositories measured with the pre-change release differ by at most half (Python) and mostly not at all. Treat any single row as a property of the repositories that represent the language, which is one more reason to re-derive against your own. In this column the thinnest samples are Objective-C, Perl, Bash, and C++, each under 2,500 functions.

何を変えるか、そしてなぜ

ほとんどの言語にオーバーライドは不要です。必要になるケースは 3 つのグループに分かれます。

Procedural languages with large dispatch functions. C, Tcl, Bash, Lua, Perl, and Go all run two to three times the cognitive default and above the cyclomatic one. These languages lack exceptions or discourage them, so error handling is inline branching, and they favour long switch-style dispatch over polymorphism. The default cognitive limit flags 5% to 15% of their functions, against 3% in the median language. Raise cognitive first. halstead.effort carries the rest of the excess for C, Go, and Lua; Tcl, Bash, and Perl measure close to the default on it.

単一言語のリポジトリでは、これは [thresholds] テーブル全体になります。混在リポジトリでは、対象とする言語の下に置くべきです。さもないと、他のすべての言語まで一緒に引き上げてしまいます。

# Gating C. Tcl, Bash, Lua, Perl, and Go share its cognitive and
# cyclomatic shape, but not its effort: Go and Lua measure near 90000,
# and Tcl, Bash, and Perl near the default.
[thresholds.lang.c]
cognitive = 30
cyclomatic = 20
abc = 50
"halstead.effort" = 120000
"loc.ploc" = 1200
"loc.sloc" = 2000

モジュール構成要素がクラスではない言語。 nom と wmc は Container スコープであり、コンテナとは文法がクラス、struct、trait、impl、namespace、interface と呼ぶものすべてを指します。Elixir の defmodule は設計上何十もの関数を保持するため、Elixir モジュールのおよそ 3 分の 1 が nom = 30 に違反します。これはスコープの不一致であって、コードスメルではありません。Rust は反対側の端に位置します。impl ブロックは通常わずかなメソッドしか持たないため、デフォルト値が発火することはありません。

# Elixir modules and Rust impls sit at opposite ends of the same metric.
[thresholds.lang.elixir]
nom = 150
wmc = 300

[thresholds.lang.rust]
nom = 20
wmc = 40

Compact, heavily-abstracted languages. Java, Ruby, Kotlin, C#, and Elixir sit far under the defaults on every per-function metric except C#’s halstead.effort. Their 97.5th percentile cyclomatic is 4 to 8. Gating them at 15 means the gate will almost never fire, so tighten if you want it to do work.

Read the C# row with care. Its distribution is dominated by property accessors, which bca counts as functions and which are almost always trivial, so its percentiles sit lower than the code a reviewer would be looking at. The same effect applies more weakly to Java, Kotlin, and Ruby. Prefer re-deriving from your own repository over adopting any of those four rows directly; see Re-deriving for your own codebase.

すべての言語に適用されるわけではないメトリクス

nargs reports 0 for every Bash function, and that is correct and permanent: the shell has no formal parameter list, arguments arrive as $1, $2, and so on, and the limit is inert. A nargs limit therefore passes unconditionally on a Bash codebase, which reads as “no offenders” rather than “not measured”. Bash is the only language left in that position.

Perl is counted, but only where the source declares a signature (sub add($x, $y), stable since 5.20 and on by default under use v5.36). A sub without a signature takes its arguments from @_ and has no formal parameter list to measure, so it reads 0, correctly. Perl’s nargs distribution is therefore sparse on codebases predating use v5.36, and one anonymous-sub form still reads 0 because the grammar misparses its signature.

wmc, npm, and npa are only produced for languages with a class-like container. They are absent from Bash, C, Lua, Perl, and Tcl output. Go is a half case: it has no container space at all, so wmc is absent and npm / npa are reported only on the file unit root. bca check gates both on container spaces and never on the root, so no npm or npa limit can fire on Go source; see Which spaces carry NPA, NPM and WMC.

A per-language override cannot fix any of these. Bash nargs is 0 for every function, so no limit (not even 0, which fires only on a value above it) can make the gate say anything. The override mechanism tunes limits; it does not add a measurement the grammar cannot supply.

オーバーライドの適用

bca.toml に [thresholds.lang.<slug>] テーブルとして記述します。各テーブルはメトリクスごとにプロジェクトの [thresholds] の上に重ねられるため、言語は再指定しなかったすべての制限を継承します。

[thresholds]
cognitive = 15
cyclomatic = 15
nargs = 5
nom = 30
wmc = 60

# 手続き型でディスパッチが多い言語: 超過分を占める 2 つのメトリクスを引き上げます。
[thresholds.lang.c]
cognitive = 30
cyclomatic = 20
"halstead.effort" = 120000
"loc.ploc" = 1200

# defmodule はクラスではないため、nom と wmc にはモジュール規模の制限が必要です。
[thresholds.lang.elixir]
nom = 150
wmc = 300

# コンパクトで高度に抽象化された言語: 引き締めないとゲートは一度も発火しません。
[thresholds.lang.csharp]
cognitive = 8
cyclomatic = 8

The key is the canonical language slug, the same vocabulary --language accepts (cpp, csharp, objc, tsx, mozcpp, mozjs); an unknown one is a tool error rather than a silent no-op. A language with no table of its own is gated by [thresholds]. Under --tier=soft each language’s soft band is derived from its own resolved limit, so a language that raises a limit gets a soft band scaled from the raised number rather than the project-wide one. The full reference, including how --print-effective-config renders the resolved tables, is in bca check.

Two things to watch when splitting a table this way. .h is analyzed with the C++ grammar, not the C one, so a C project’s headers are gated by [thresholds.lang.cpp]; see Supported Languages for the extension map. And --threshold on the command line stays global: it overrides every per-language table too, which is what you want for a one-off run and a surprise if you expected it to compose.

The alternative is still available and still worse: keep one table sized for the loosest language and let per-file baselines carry the rest. It is simpler to maintain and weaker, because the stricter languages stop being gated at all.

Per-path overrides

A language table tunes a limit for everything written in that language. Some populations of files are a different shape from the rest of their language, and the shape is a property of the directory, not the grammar: a tree of hand-rolled dispatch tables, a generated binding layer, a parser whose state machine is one function per state. The cyclomatic count of a dispatch table is the length of its construct list, and its Halstead effort is the size of its vocabulary; neither number tells a reader anything a split would improve, and the project limit misreads every function in the directory the same way.

The per-function answer is a suppression marker on each one, and it does not scale. This repository accumulated 38 bca: suppress markers naming cyclomatic and Halstead across its per-language dispatchers, in several wordings and two operand orders, with nothing stating that the directory was exempt as a policy. A [[thresholds.path]] entry states the policy once:

[thresholds]
cyclomatic = 15
"halstead.effort" = 50000

# The per-language dispatchers are exhaustive kind tables: their
# cyclomatic is the construct list and their effort is the vocabulary.
[[thresholds.path]]
glob = "src/metrics/{abc,cognitive,cyclomatic,loc}/*.rs"
cyclomatic = 40
"halstead.effort" = 150000

An entry is an array element, so a manifest can carry several with different globs. Each names a glob and the metrics it re-limits, and inherits every limit it does not restate. The glob is matched against the file’s path relative to the directory of the config that declared it (the bca.toml, or the --config file), with the same engine and the same anchor that [check] exclude uses, so one spelling describes the same files on both surfaces. A file outside that directory is matched by its seed-relative form, exactly as a [check] exclude glob matches it: the path under the --paths seed that produced it, so with bca check -p src an entry declared outside the tree sees src/gen/a.c as gen/a.c, and its src/** does not reach it. Where several entries match one file, the last entry wins, per metric, in declaration order — the manifest’s entries first, then the --config file’s — the rule .gitignore readers already know.

An override is not a suppression. The function stays in bca check’s output and in the baseline with its real value, and the soft tier scales the overridden limit the way it scales any other: at --tier=soft=0.9 the entry above warns at cyclomatic = 36, and the ceiling an offender is measured against for exit 5 is 40, not the project’s 15. The marker takes a function out of the gate; the entry keeps it in, at a limit chosen for its population. That is the whole difference, and it is why --explain-threshold can still price a candidate limit over those files: it lists each entry that declares the metric, with the number it declares, so the count is read against the right denominator. It reports the declaration rather than a per-entry limit because entries overlap — where two match one file, the later one’s number is the limit — and the offender counts it prints are already taken against each file’s own resolved limit.

Three things the parser refuses, each naming the entry by its position in its own file and its glob: a metric name [thresholds] does not know, an entry with no glob or an empty one ("" and ./ would match nothing), and tokens, which is a cap on what the walk will parse rather than a maintainability limit and is not overridable by any layer. --print-effective-config prints every entry under [[thresholds.path]] with the metrics it declares at their hard-tier limit — --threshold applied last, the tier not applied — so the printed file replays the gate at the hard tier through --config. Under --tier soft the printed path limits are the hard limits the soft band is derived from, not the band: the band belongs to a file’s whole match set (a second entry naming only another metric changes the first’s), so no per-entry row can carry it, and a printed band would be scaled a second time on the way back in. A soft-tier run is therefore not replayed by the printout alone — the view echoes no [thresholds.soft] table and cannot mark a --threshold limit as absolute — so the hard tier is the replay contract; see Per-path limits for what a same---tier reload does and does not reproduce.

How the layers compose

This is the one statement of the order; bca check --help and the bca check reference cite it rather than restating it.

  1. [thresholds] — the project table, from bca.toml with --config merged on top.
  2. [thresholds.lang.<slug>] — the file’s language, per metric.
  3. [[thresholds.path]] — every entry whose glob matches the file, in declaration order, per metric; the last match wins.
  4. The tier — [thresholds.soft] or the soft ratio — derived from the limits the three layers above resolved to, so each table’s soft band and hard ceiling come from its own numbers. An absolute [thresholds.soft] limit applies as written to every table, path entries included, so it must sit under each one’s hard limit — an entry that lowers a metric below the soft limit is rejected before the walk, naming the entry.
  5. --threshold name=value — applied last and absolutely, to every table, never scaled.

A limit a --threshold flag names is therefore the limit that runs, for every file, whatever the tables say; and a limit only a path entry names is still computed for every file that entry matches, so the gate it adds can fire.

ユースケース別プロファイル

同じコードベースでも、ゲートの目的によって求められる制限は異なります。

ブロッキング CI ゲート

同梱のデフォルトはこのためのものです。プルリクエストを失敗させる制限は、チームが本当に問題だと合意できるものでなければなりません。偽陽性のコストがマージのブロックと論争になるからです。ベースラインと組み合わせて、ゲートが新規の違反とリグレッションでのみ失敗するようにし、そこから引き締めていきます。

同梱のデフォルトを変更せずに使い、さらに次を追加します。

[check]
baseline = ".bca-baseline.toml"

エージェントのフィードバックループ

利用者が人間のレビュアーではなくコーディングエージェントである場合、偽陽性のコストはマージのブロックではなく無駄なリファクタリング 1 回で済み、シグナルはコードを書いている最中に届きます。公表されている関数ごとの値に向けて引き締め、ファイルサイズとコンテナの制限は外してください。1 つの関数を編集しているエージェントには対処のしようがないからです。

[thresholds]
cognitive = 10
cyclomatic = 10
abc = 25
nargs = 4
nexits = 4
"halstead.effort" = 25000

これを編集ループに組み込む方法はエージェントにメトリクスを渡すを、複雑さが偶発的ではなく本質的である場合にそれをエージェントへ伝える方法は抑制マーカーを参照してください。

レガシー監査とトリアージ

When the goal is to rank an unfamiliar codebase rather than to gate it, you want the handful of functions that are worst, not a list of thousands. Set limits at roughly twice the defaults so only extreme outliers surface, run without a baseline, and use bca report markdown rather than bca check.

[thresholds]
cognitive = 40
cyclomatic = 30
abc = 80
"halstead.effort" = 250000
"loc.ploc" = 1500
nom = 60
wmc = 120

レポート出力については品質レポートで説明しています。--vcs を追加すると変更履歴によるランク付けも行われ、通常は複雑さ単独よりも優れたトリアージ順序になります。3 年間誰も触れていない複雑な関数は、バグの在り処ではありません。

セーフティクリティカルおよび規制対象

この分野の標準は制限を直接規定しており、どのような測定よりも標準が優先されます。MISRA と NASA はいずれも循環的複雑度の上限を 15 とし、JSF C++ 標準は大きな switch 文に対する文書化された例外付きで 20 を許容します。McCabe のオリジナルの 10 は、テスト予算がそれを支えられる場合に適用されます。この数値はスタイルに関する意見ではなく、基底パステスト数の境界だからです。

[thresholds]
cognitive = 15
cyclomatic = 10
abc = 30
nargs = 5
nexits = 1
"halstead.effort" = 25000

nexits = 1 は MISRA C:2023 Rule 15.5 の単一出口ルールを符号化したものです。規制対象の業務以外では異論が多く、ほとんどのコードベースでは早期リターンはコードを追いにくくするどころかむしろ単純にするため、一般的な推奨ではなくコンプライアンス設定として扱ってください。

デフォルトではゲートされないメトリクス

These are computed and present in every bca metrics output format; bca report markdown|html shows only a subset of them. They are left out of the default table on purpose.

halstead.volume には、Halstead の測定値の中で最も広く引用されるしきい値があります。関数の volume は 1000 未満に保つべきだというガイドラインです。コーパスに対して測定すると、中央値の言語で関数の約 7%、最悪の言語で 20% にフラグが立ちます。つまりランク付けには有用でも、ゲートとしては使いものにならないということです。

mi.original、mi.sei、mi.visual_studio は Maintainability Index(保守性指標)のファミリーで、低いほど悪い指標です。違反となるのは制限を下回る値です。Visual Studio のバンド(10 未満は不良、10〜19 は中程度、20 以上は良好)は、同製品が 0〜100 に再スケールした独自の出力に適用されるもので、bca はこれを mi.visual_studio として報告します。mi.original は上に有界ではなくコーパス上で 167 に達するため、オリジナルの SEI の 65 と 85 のバンドはそのまま移せません。この指標はまた、すでにゲートしているメトリクスから計算される関数でもあるため、これもゲートすると二重カウントになります。数式は対応コードメトリクスを参照してください。

npm、npa、tokens、cyclomatic.modified が省かれているのは、それぞれがテーブルに既にある何かと重複しているか、あるいはその分布が設計品質ではなく言語のイディオムに支配されているためです。

クラスターに向けた制限の引き締め

Converging a limit onto a cluster of existing values is never free while a proportional soft tier is active. Measure a candidate at both tiers before calling it free. The hard-tier reading is the one you naturally take, and it is the one that misleads.

ソフト層は制限までの距離を測ります。したがって、母集団の値のちょうど上に置かれる制限は、構造上ソフト層の超過を最大化します。その値にある関数はすべて、制限が定まった瞬間にソフト帯の内側に入り、どれだけ整理しても外には出られません。その値こそが制限「そのもの」だからです。

This project walked into it. nargs was at 7, and tightening it to 6 looked free: every offender at the tighter limit was already in the baseline, so bca check --threshold nargs=6 reported nothing:

nargs の制限ハード違反ソフト制限(0.95)ソフトの違反
7(維持)276.6560
6(提案)605.7134

Seventy-four functions sit at exactly 6. A limit of 6 puts all of them 0.3 inside the soft band at once: 74 baseline entries bought for no hard-tier gain, none of which can ever be retired short of rewriting the signatures. The limit stayed at 7; the honest alternative was the real 6 → 5 work. (#1143, #1169.)

上記の数値は #1196 より前、つまり nargs ゲートが関数自身のパラメータにネストしたすべてのクロージャの分を合算していた時期に測定されたものです。その母集団の大半はそもそもパラメータ過多ではありませんでした。制限 5 が新たにゲートしたはずの 76 関数のうち、自身のパラメータが 6 個以上あったのは 17 だけで、うち 1 つはパラメータ 1 個に本体内のクロージャが寄与した 5 個を加えたものでした。自身のパラメータのみをゲートする方式で同じツリーを再測定すると次のようになります。

nargs の制限ハード違反新規(ベースライン未登録)ソフトの違反新
7(維持)60160
61603817
5381712999

The cluster trap itself is unchanged and is the reason this section exists: the re-measurement for #1143 found 91 functions sitting at exactly 5, so a limit of 5 still put every one of them permanently inside the soft band. What changed is the size of the real work behind it: signatures rather than mixed cases.

The convergence landed on that evidence. One thing measuring it clarified, which this section previously got wrong: the cluster effect is structural for every integer metric, not a property of landing on a population’s mode. A function sitting exactly at limit L is always above 0.95 x L, so it is always in the soft band. In that measurement the ten functions at exactly 7 were in it before the change, just as the ninety-one at exactly 5 were after. What the limit choice controls is only how many sit there. Read #1143’s objection that way: it was sound because the hard-tier gain was zero, not because 6 was near a mode.

これはまた、0.95 x L と L の差が 1 未満になる小さな整数のメトリクスでは、ソフト層が持つ情報が乏しいことも意味します。halstead.effort(50000 対 47500)では実質的な仕事をしていますが、nargs(5 対 4.75。上限ぎりぎりにある適合済みの関数すべてにフラグを立てます)ではほとんど何もしていません。

bca check --explain-threshold <metric>=<limit> は、bca.toml に触れることなく、1 回の走査で両方の層を測定し、クラスターを見つけた場合はそれを名指しします。

$ bca check --explain-threshold nargs=6
nargs: candidate limit 6
  hard tier (limit 6): 60 offenders, 60 already baselined, 0 new
  soft tier (limit 5.7, 0.95x): 135 offenders, 61 already baselined, 74 new
  cluster: 75 of 75 soft-band offenders sit at exactly 6 — the candidate limit itself. …

The trap is not confined to the global table. A per-language override is another way to converge a limit onto a population, and it has the same cliff; --explain-threshold reports a language keeping its own limit on a separate line rather than folding it into the count.

この規則はソフト層を越えて一般化できます。クラスターの上に着地した制限は母集団に余地を残さないため、実際のコードを動かさなければならなくなるのは「次の」引き締めです。クラスターとクラスターの間隙にある制限を選んでください。このフラグの完全な契約については候補の制限をプレビューするを参照してください。

自分のコードベースに合わせた再導出

コーパスのパーセンタイルは出発点にすぎません。自分自身の分布のほうが優れた証拠であり、それを得るにはコマンド 1 つと短いスクリプトで足ります。

bca metrics --no-config -O json -I '*.rs' -X '**/tests/**' . > metrics.jsonl

各行が 1 ファイル分の FuncSpace ツリーです。これを走査し、関心のあるメトリクスについて各スペース自身の値を保持し、メトリクスのスコープに合わせて kind でフィルタし("function"、loc.* には "unit"、nom と wmc にはコンテナの kind)、97.5 パーセンタイルを取ります。そこに制限を設定すると、最悪の 2.5% にフラグが立ちます。

Run two checks afterwards. Count the offenders the limit produces: if it is more than a few percent of your spaces, the gate will be ignored rather than obeyed. Then look at where the values pile up. A natural distribution tails off smoothly, so a cluster of files sitting just under the limit means the limit is shaping the code rather than measuring it, and people are trimming to fit. That happened to this project’s own loc.sloc gate, which is documented in issue #1138.

bca check --write-baseline は今日時点の違反を記録するため、初日から失敗することなく、より厳しい制限を採用できます。ブートストラップ、更新、退役のフローはベースラインで説明しています。