Configuration¶
Qualimetrix works out of the box with sensible defaults. A configuration file lets you customize thresholds, disable rules, and exclude paths to fit your project.
Configuration File¶
Automatic discovery accepts exactly qmx.yaml or qmx.yml in the working
directory and, when neither exists, qmx.dist.yaml or qmx.dist.yml. If both
names of a pair exist, the command refuses with exit code 3 — both dist names
are refused even beside a local file, since a checkout without it would refuse
them; choose one with --config. A near spelling, such as QMX.yaml or
qmx.yaml.dist, is warned about and not loaded when no local name exists. A
local file beside a near name is loaded without that warning; a dist file
loaded in its absence keeps it, since such a name is usually a misnamed local
file. --config selects its named file explicitly, independently of automatic
discovery.
Committed defaults and a local file. Commit qmx.dist.yaml and ignore
qmx.yaml in Git: a checkout without qmx.yaml, such as CI or the GitHub
Action, reads qmx.dist.yaml. A developer's qmx.yaml
wins and is read alone — it builds on the committed file only by
importing it:
When an auto-discovered qmx.yaml or qmx.yml does not import a
qmx.dist.yaml or qmx.dist.yml beside it, the run warns that the dist file
is not used, since the local run then differs from CI. When a run without the
local file would refuse the dist file — it is not a readable regular file, is
not valid YAML, or names an import that cannot be read — the warning gives
that refusal instead. The advice names the dist file by its full path when the
local file is a symlink into another directory, whose imports resolve beside
its target. A dist file selected
with --preset is read in the preset band only: it is neither discovered nor
warned about.
A near-name warning is suppressed only when that same physical file was already selected as a custom preset; the same basename elsewhere does not suppress it. The two-file refusal identifies both files. If the working directory cannot be listed, discovery refuses with exit 3 and names the directory.
Every command that reads the document judges all its context-free values, even when it consumes only some sections. The command's CLI profile does not hide malformed authored configuration.
| Commands | Document and paths | Shared CLI settings |
|---|---|---|
check, directives |
Read the document and analyse resolved paths | Their analysis options |
debug:layer-assignment |
Read the document and analyse configured paths | --config, --preset and its analysis settings |
graph:export |
Read the document; use resolved paths when none are given | --config, --preset, --exclude, --include-generated, --include-autoload-dev, --no-cache, --workers, --memory-limit |
rules |
Read the document without requesting analysis paths; include named computed metrics and mark the current only_rules/disabled_rules selection |
--config, --preset |
baseline:generate, baseline:update, baseline:cleanup, baseline:explain |
Read the document and measure resolved paths | --config, --preset, rule selection, --include-generated, --include-autoload-dev, --no-cache, --workers, --memory-limit |
baseline:rename-channels, hook:install, hook:status, hook:uninstall, help, list, completion |
Do not read the configuration document | Their own command options |
Graph's --format/-f selects dot or json separately from the document's
analysis format. Graph consumes Run, Cache, Parallel, Coupling and memory
settings, without constructing Finding selection or the analysis output format.
You can also specify a file explicitly:
The file found or named this way is the root configuration file. It can
build on other files and built-in presets through imports.
Configuration Sections¶
Paths¶
Directories or PHP files to analyze:
Note
If you pass paths as CLI arguments (e.g., vendor/bin/qmx check src/ lib/), they take precedence over the config file.
Without authored paths in CLI, YAML or presets, defaults come from the
analysed project's invocation snapshot of composer.json. If its selected
autoload records are unusable, inferred defaults refuse with exit 3 rather
than analysing unrelated paths. Accepted fragments of a damaged manifest can
still be analysed, but inferred partial defaults do not establish a whole
project. Explicitly selecting the whole root can establish filesystem completeness with
state unknown; final removal/uncertainty can still withhold declaration claims.
Selecting a subset without a complete declared universe gives
unmeasured. See Project scope.
A missing path or an explicitly named existing non-PHP regular file refuses
with exit 3 in every measuring command before discovery.
Input directories must canonically target the captured root or a descendant;
an external alias spelling targeting an internal directory is valid. For files,
the canonical parent is checked and the last name is kept literally, including
file symlinks. . and equivalent root spellings are valid. A directory targeting
outside refuses with exit 3; --working-dir chooses the intended root.
Exclude¶
Filesystem entries removed from analysis: files, directories and other matching entries. The walk does not descend into an excluded directory:
Each entry is an explicit exact, subtree or regex selector, as under
suppress_paths; a bare string is refused. The built-in vendor, node_modules
and .git floor is separate from authored selectors. Authored exclusions apply
to named CLI, YAML and preset paths without refusing a root merely because it
was written explicitly. All matching selectors bind before an entry is pruned.
A complete run with analyzed=0, failed=0 and
excluded + generatedExcluded > 0 is intentionally empty and succeeds with
its measured scope explanation. baseline:generate writes an empty file;
any failure takes priority with exit 4. See
Paths argument.
Include Generated¶
By default, files with a @generated annotation in the first 2 KB are automatically skipped from analysis. To include them:
Equivalent CLI: --include-generated
Include Autoload Dev¶
By default, the code composer.json declares under autoload-dev is not part of the project: a run with no paths analyses only the paths autoload declares (in any autoload form: psr-4, psr-0, classmap, files), and a run is judged against those alone when Qualimetrix asks whether it covered the whole project. To count test code as part of the project in both places:
Paths you write yourself are not widened; with paths: [src], the run is reported as not covering the autoload-dev paths. In either section, an entry that is, or lies inside, a vendor, node_modules or .git directory is not part of the project: it is neither analysed by default nor counted, and a warning names it.
Equivalent CLI: --include-autoload-dev
Suppress Paths¶
Path selectors suppress violations while the files are still analyzed. Each YAML item is a one-entry mapping: exact selects one canonical project-relative path, subtree also selects /-separated descendants, and regex accepts a delimiterless PCRE fragment that Qualimetrix anchors to the whole path:
suppress_paths:
- subtree: src/Entity
- exact: src/DTO/Address.php
- regex: 'src/Metrics/.*Visitor\.php'
Also available as a CLI option: --suppress-path (merged with YAML config).
Namespace and project findings have no borrowed source file, so path selectors
do not suppress them. Migrate intended namespace suppression to
suppress_namespaces or a specific suppress_namespace_channels entry.
Declared project scope remains exempt
suppress_paths does not suppress architecture.circular-dependency cycles or
declared project-scoped diagnostics. Exemption is declared per channel;
the architecture. prefix alone grants none.
architecture.layer-violation belongs to the source declaration: global
suppress_paths matches the physical dependency site's file, while
suppress_namespaces matches the source namespace. Excluding only the target
does not suppress an outgoing violation. Git reports retain it only when
the source file changed, in both modes; see Git Integration.
Inline directives and baselines still apply to layer violations, but not to the five configuration validators. Their separate controls are described under Architecture rules. Per-rule exclusions remain available independently of global channel scope.
Suppress Namespaces¶
Suppress violations for classes in selected namespaces. Namespace selectors use the same three explicit forms; subtree follows \ namespace boundaries and regex is automatically full-subject:
suppress_namespaces:
- subtree: App\Tests
- exact: App\Generated\BuildInfo
- regex: 'App\\Legacy(?:\\[^\\]+)*'
This is useful when entire namespace subtrees should never produce violations. For per-rule exclusions, use suppress_namespaces inside a rule configuration instead (see below).
Also available as a CLI option: --suppress-namespace (merged with YAML config).
Declared project scope remains exempt
suppress_namespaces does not suppress architecture.circular-dependency cycles or
declared project-scoped diagnostics. Exemption is declared per channel;
the architecture. prefix alone grants none. The per-rule form of the option is
refused for such producers; see the note under
Works for every rule.
architecture.layer-violation belongs to the source declaration: global
suppress_paths matches the physical dependency site's file, while
suppress_namespaces matches the source namespace. Excluding only the target
does not suppress an outgoing violation. Git reports retain it only when
the source file changed, in both modes; see Git Integration.
Inline directives and baselines still apply to layer violations, but not to the five configuration validators. Their separate controls are described under Architecture rules. Per-rule exclusions remain available independently of global channel scope.
Rules¶
Control which rules are active and set custom thresholds.
Disable a rule entirely:
Override thresholds:
Each rule defines severity levels. When a metric reaches or crosses a threshold in the rule's adverse direction, a violation is reported at that severity. For example, the cyclomatic complexity rule has thresholds for methods:
This means: report a warning when a method's cyclomatic complexity reaches 15, and an error when it reaches 25.
Threshold shorthand:
If you want a single pass/fail threshold (all violations become errors), use the threshold key:
rules:
complexity.ccn:
callable:
threshold: 15 # warning=15, error=15 → all violations are errors
size.method-count:
threshold: 25 # same as warning: 25, error: 25
This is useful in CI where you want a simple pass/fail cutoff without graduated warnings. You cannot mix threshold with explicit warning/error keys from the same configuration layer (the same preset, the same qmx.yaml, or the same CLI invocation) for the same rule level — that raises a configuration error.
Overriding the mode across layers: a higher-priority layer (config file over a preset, CLI over the config file) may freely switch mode for a rule level — e.g. a strict preset sets warning/error, and --rule-opt=size.method-count:threshold=25 on the command line switches that rule to a single cutoff. The CLI's threshold overrides the preset's warning/error instead of conflicting with them:
# CLI switches this rule to simple pass/fail mode — no "cannot mix" error
bin/qmx check src/ --rule-opt=size.method-count:threshold=25
The same applies in the other direction (a lower layer's threshold overridden by a higher layer's warning/error), and to hierarchical rules at the level the keys are set (e.g. complexity.ccn's callable:/class:). Duplication is an exception: duplication.clone accepts positive min_lines, min_tokens, and error only; warning and threshold are refused, and severity uses each copy's covered code lines. Its option schema is listed in the rule table below.
Hierarchical shorthand is a per-layer form. A top threshold changes the
callable band of CCN/cognitive/NPath and preserves the class band's values and defaults.
Write class.enabled:false if class reporting should be off. A top shorthand
and an explicit write to the same expanded leaf in one layer refuse; an independent
child in a target level block can coexist. To configure both levels in one layer:
CBO and instability spread a top band to class and namespace in the writing layer. An explicit write conflicts only at an overlapping expanded leaf in that layer; independent level children coexist. A higher layer may override the expanded leaves of a lower layer without discarding unrelated values.
Each type-coverage dimension is a rule of its own, so each takes its own bare
threshold:
rules:
design.type-coverage.param:
threshold: 90
design.type-coverage.return:
threshold: 90
design.type-coverage.property:
threshold: 80
Option key spellings are interchangeable, option keys themselves are not.
max_warning, maxWarning and max-warning are the same key and all three
apply, at both depths. Being one key, it is written once: two spellings of it in
the same block — max_warning: 1 beside maxWarning: 999 — end the run with exit
code 3 instead of letting the later one win. The same holds for every key in the
document, root keys included. A key the rule does not have at that position is not
guessed at: the run stops (see Unknown rule option keys).
An empty level block writes no values. callable: {} preserves the lower
layer and uses defaults only for leaves no layer wrote. To switch a level off, write
callable: {enabled: false} — callable: false is refused, because a level has
no off-switch of its own and the value looks like the rule's.
Suppress namespaces for a rule:
Any rule can use the same explicit namespace selectors:
rules:
complexity.ccn:
suppress_namespaces:
- subtree: App\Tests
- subtree: App\Legacy
callable:
warning: 15
error: 25
coupling.cbo:
suppress_namespaces:
- subtree: App\Tests
suppress_paths:
- subtree: src/Infrastructure/DependencyInjection
This is useful when certain namespaces (e.g., tests, generated code, legacy modules) should not trigger violations for a specific rule, while still being analyzed for metrics.
Suppress selected namespace-aggregate channels for a rule:
Use suppress_namespace_channels when one violation channel is structurally inapplicable to
part of the namespace tree, but class findings and the producer's other channels must remain:
rules:
health.cohesion:
suppress_namespace_channels:
health.cohesion:
- subtree: App\Metrics\Coupling
- regex: 'App\\Generated(?:\\[^\\]+)*'
The option is a non-empty map from channel selector to a non-empty list of explicit namespace
selectors. The key uses the closed channel grammar — an exact channel
name, or X.* for the strict descendants of X, either optionally narrowed to a level with
:namespace; see Rule and channel selectors below. A bare
prefix such as health is an error, not a group: write health.*. Exact health.cohesion
leaves the sibling health.coupling untouched.
Write the channel exactly as it is named, hyphens included — these keys are not
case-normalized, so size.class-count, code-smell.* and a computed metric named
computed.my-score are written here the way they are written everywhere else.
The key must address a channel the rule it is written under actually emits. A key that
names another rule's channel, or no channel at all, ends the run with exit code 3 and a
message listing that rule's channels — it used to be accepted and exclude nothing. A key
carrying a level is judged as one thing: the channel it names must be produced by this rule
and report at that level, so coupling.*:namespace under coupling.class-rank is refused
even though a sibling coupling channel does report at namespace level.
namespace is the only level such a key can name, because the option is offered
namespace-aggregate findings and nothing else. coupling.cbo:class is refused by name — it
used to be accepted and could never fire:
rules:
coupling.cbo:
suppress_namespace_channels:
# the namespace aggregate only; the class findings of the same channel stay reported
coupling.cbo:namespace:
- subtree: App\Legacy
Writing the level is optional: a level-free key already reaches only namespace aggregates, so
coupling.cbo and coupling.cbo:namespace exclude the same findings. The pair is worth
writing when the key should say out loud which half of a two-level channel it is about.
Only namespace-aggregate findings are removed
The option filters findings whose subject is a namespace. A rule that reports per
occurrence (code-smell.*, security.*, architecture.layer-violation) or only per class
(cohesion.lcom) has nothing for it to remove, and a key naming such a channel is accepted
and then does nothing. The five layer-policy diagnostics — architecture.coverage-gap,
architecture.unreachable-layer, architecture.potential-shadow,
architecture.empty-template, architecture.pending-layer-matched — report against the project as a whole and are likewise
outside its reach; use the exclude: block inside the architecture layer configuration
instead.
Only aggregate Namespace violations are removed. Class-level health.cohesion findings in
the same namespace and sibling channels remain. The existing suppress_namespaces option is
unchanged and stays producer-wide across class and namespace findings.
Works for every rule, including the architecture rules
suppress_namespaces, suppress_namespace_channels, and suppress_paths are extracted and applied at the framework level for
rule names regardless of whether that rule's Options class declares such a field —
this is deliberately not opt-in per rule. That includes architecture.layer-violation.
Global exclusions apply to source-owned layer violations. The per-rule form explicitly
names the producer whose findings should be suppressed. See the architecture rule's
Suppression section for the reasoning.
Producers with project-scoped findings only¶
A non-empty per-rule suppress_namespaces or suppress_paths is refused at load
(exit 3) for a producer whose every channel is project-scoped: its findings are
about the project, so no path or namespace can address them. The producers are
architecture.circular-dependency, architecture.layer-declaration,
architecture.unassigned-class, baseline.unused-entry,
coupling.unmatched-framework-namespace, discovery.unmatched-exclude and
suppression.configuration. An empty list or null is accepted. The same refusal
applies when the option is written with --rule-opt. Producers with at least one
file-scoped channel (for example cohesion.lcom) and computed metrics are not
affected, even when a computed metric is configured to report only at the project
level.
The refusal happens in every command that resolves rule options: check,
directives, debug:layer-assignment, rules and baseline:generate,
baseline:update, baseline:cleanup, baseline:explain. graph:export does not
interpret rule options, so it does not refuse them. To accept known findings of
such a producer, see the baseline page for which findings a
baseline can accept; for dependency cycles, narrow what counts as an edge with
ignore-relations of architecture.circular-dependency.
Suppress paths for a rule:
Any rule can use the same explicit path selectors. Violations from matching files are suppressed:
This works alongside suppress_namespaces -- both filters are applied. Unlike the global suppress_paths, per-rule suppress_paths only affects the specific rule, not all rules.
Visibility: unlike @qmx-ignore, these suppressions happen silently by default — nothing in
the default output hints that violations were dropped. Run with -v to see a per-rule breakdown
of how many violations were suppressed this way (the namespace bucket combines
suppress_namespaces and suppress_namespace_channels, separately from suppress_paths),
and add --show-suppressed to also list each suppressed violation, alongside @qmx-ignore
suppressions.
Per-symbol threshold overrides with @qmx-threshold:
In addition to project-wide thresholds in YAML, you can override thresholds for individual classes or methods using @qmx-threshold annotations directly in source code:
/**
* @qmx-threshold complexity.ccn warning=20 error=40
*/
class ComplexStateMachine
{
// Methods in this class use higher complexity thresholds
}
The class-level override also applies to method evaluations inside the class; a narrower callable-level override takes precedence.
See Baseline > @qmx-threshold for full syntax and examples.
Rule and Channel Selectors¶
Every place that names a rule or a finding channel — disabled_rules, only_rules, their CLI
equivalents, suppress_namespace_channels, and the @qmx-ignore family in source code — reads
the name the same way:
| Form | Meaning |
|---|---|
complexity.ccn |
exactly that name, and nothing else |
complexity.* |
strictly the descendants of complexity — complexity.ccn, complexity.wmc and so on. complexity itself is not included; if a name is both a rule and a channel, address it separately |
coupling.cbo:namespace |
the channel narrowed to one level of the aggregation tree. The level is one of callable, class, file, namespace, project, and the channel must report at it |
A bare prefix is not a group. complexity on its own selects nothing and is rejected:
Configuration error: Rule selector "complexity" does not match any registered producer or channel. Write "complexity.*" to select its descendants.
Docs: https://qualimetrix.dev · AI agents: https://qualimetrix.dev/llms.txt
A X.* that has no descendants is rejected for the same reason. Most rules emit a single
channel whose name equals the rule name, so code-smell.eval.* is an error — write
code-smell.eval.
An unresolvable selector in configuration or on the command line ends the run with exit code 3 before any report is produced. Guessing at intent was the previous behaviour, and it silently turned typos into "nothing was selected".
Which side of the pair a name refers to is decided by the directive, not by the name. The same string means different things depending on where it is written:
@qmx-ignore code-smell.boolean-argumentalways names a channel, because a suppression belongs to the channel;@qmx-threshold code-smell.boolean-argumentalways names a rule, because a threshold belongs to the rule's one options object.@qmx-thresholdtherefore takes an exact rule name and accepts no wildcard at all — resetting a threshold across a group was a footgun, not a feature;- keys of the
rules:section and the owner before:in--rule-opt RULE:option=valuename a rule, exactly. A key likerules: { complexity: {...} }used to be accepted and configure nothing at all; it is now rejected.
See Baseline for the full inline-directive syntax, and Rules > Annotations for what the tool reports when a directive addresses nothing.
Disabled Rules¶
Disable specific rules, channels, or whole groups:
Equivalent CLI: --disable-rule=code-smell.boolean-argument --disable-rule=duplication.clone
To disable a whole group, use the wildcard:
Only Rules¶
Filter directly selected rules; declared diagnostic roles may also be admitted:
Equivalent CLI: --only-rule=complexity.ccn --only-rule=complexity.cognitive
Fail On¶
Control which severity levels cause a non-zero exit code:
fail_on: error # Only fail on errors (default)
# fail_on: warning # Fail on warnings too
# fail_on: none # Never fail on violations
The default is error: warnings and Info-level diagnostics are shown in the output but do not cause a non-zero exit code. Use fail_on: warning if you want warnings to also fail the build.
Use fail_on: none to keep findings from failing the run. The former YAML
fail_on: false is refused; replace it with none.
info is report-only and is not a fail_on value
warning and error are the only severities fail_on accepts — fail_on: info is
rejected with an error naming the accepted values. Severity info means "observe, do not
gate": an Info-only run always exits 0, whatever fail_on says. To gate on a diagnostic
configured at info, raise that rule's own severity instead.
annotation.unused-directive defaults to warning; explicitly set info
to preserve the former quiet cleanup severity:
fail_on does not govern configuration errors
Some channels report a mistake in the configuration rather than debt in the code — the five
layer-policy diagnostics (architecture.coverage-gap, architecture.unreachable-layer,
architecture.pending-layer-matched, architecture.potential-shadow,
architecture.empty-template) and the three inline-directive
diagnostics (annotation.unresolved-directive, annotation.unsupported-threshold,
annotation.invalid-threshold). These never take part in the fail_on comparison at all:
they end the run with a non-zero exit code even under fail_on: none, and no baseline entry
or @qmx-ignore can accept them. The tool is not judging your code there — it is saying it
cannot do what you asked.
Exclude Health¶
Exclude specific health dimensions from scoring. The excluded dimensions are not shown in the health summary and do not contribute to the overall score:
Equivalent CLI: --exclude-health=typing --exclude-health=maintainability
Memory limit¶
Set the PHP memory limit for analysis. By default, PHP's memory_limit from php.ini is used. The limit applies to the worker processes as well, where files are parsed and measured; a file a worker could not finish within it is reported as failed, and the failure names the limit.
Equivalent CLI: --memory-limit=1G. A value above PHP_INT_MAX bytes refuses with exit 3.
Format¶
Set the default output format:
Cache¶
Control AST caching for faster repeated runs:
cache:
enabled: true # Default: true
dir: /home/user/.cache/qmx # Optional explicit POSIX path outside this project
dir is parsed as a string. When caching is enabled or --clear-cache uses the location, an absolute path or a path relative to the project root must resolve to a supported POSIX path outside the project; for example, ../external-cache can qualify. A quoted numeric name is a string, then receives the same runtime path judgement if the location is used. --no-cache without clearing does not judge an unused root. The default is the user cache directory under qmx, shared across projects; old .qmx-cache entries are not read. An explicit root owned by another user or writable by group/others refuses when used; an unusable default disables caching with one warning. Root eligibility does not establish trust for every ancestor. The cache uses a current-format allowlisted AST codec; old formats are misses. When the project root is / (for example, a cron invocation from /), containment is not checked; all other location judgements still apply. short_open_tag participates in the key. Entries unread for 30 days are swept incrementally. Each open sweeps 16 of 256 shards; after 16 successful sweep steps, the per-format target is 2 GiB plus entries written since each shard's last sweep and one oversized newest entry per shard, rather than an immediate hard quota. Publication temporary files are retained for up to the same 30-day age limit so a sweep does not remove an active writer; their bytes are additional to this entry target. Old temporary files are swept in both shards and version metadata. Clearing preserves unrelated files and refuses while any detached cache directory remains.
Equivalent CLI: --no-cache to disable, --cache-dir=DIR to change directory.
Parallel Processing¶
Control the number of parallel workers for file analysis:
parallel:
workers: 4 # Fixed number of workers
# workers: 0 # Disable parallelism (sequential)
# workers: 1 # Disable parallelism (single-process)
By default, Qualimetrix auto-detects the worker count based on CPU cores. Equivalent CLI: --workers=4. On an eligible run, an explicit count above one uses processes and refuses with environment exit 3 if the first worker cannot start or answer within 10 seconds; automatic selection warns and falls back to sequential. ext-parallel threads and forks are not transports.
Tip
Use workers: 1 for debugging or single-process environments. workers: 0 disables parallelism (sequential execution); auto-detect is the default when the option is omitted.
Namespace Detection¶
Qualimetrix derives project namespaces from the invocation working directory's
composer.json and falls back to source parsing where needed. Namespace
detection is not configurable: namespace.strategy and
namespace.composer_json are rejected as unknown keys.
Coupling¶
Configure framework namespace prefixes for the CBO (Coupling Between Objects) metric. Dependencies on framework namespaces are tracked separately as coupling.cbo-app and coupling.ce-framework:
coupling:
framework-namespaces:
- subtree: Symfony
- subtree: Doctrine
- subtree: Psr
- subtree: Illuminate
When no framework-namespaces are configured, coupling.cbo-app equals coupling.cbo (no effect).
Aggregation¶
Namespace aggregation follows the analyzed declarations. Custom
aggregation.prefixes and aggregation.auto_depth settings are no longer
supported and are rejected as unknown keys.
Architecture¶
Layer rules and the allow-list for the architecture.layer-violation rule live under the top-level architecture: key. The full schema is documented in Architecture Rules; the keys most relevant to general configuration are:
architecture:
layers:
- name: 'domain-{module}' # template layer with capture variable
patterns: ['App\Module\{module}\Domain\**']
- name: shared-kernel
patterns: ['App\Shared\**']
allow:
'domain-{m}':
- shared-kernel
- target: 'domain-{m}'
relations: [implements, extends] # whitelist of dependency kinds
coverage-gap: ignore # ignore | warn | error
max_expanded_layers: 500 # cumulative cap on template expansion
Capture variables in layer names and patterns use the syntax {name} (single namespace segment) or {name:**} (cross-segment). The same variable name within one layer entry binds to one value (co-binding); variables in different entries are independent. See the layer-templates section for the full grammar.
A layer and its exclude: accept six criterion lists: patterns, attributes,
member_attributes, implements, extends, and suffix. attributes observes
attributes on the class-like declaration; member_attributes observes its own
members. match: any is the default; all requires each populated criterion
kind. Layer capture patterns and public exact | subtree | regex selectors are
distinct grammars. Membership suggests a pattern equivalent when refusing a
public selector form; YAML/CLI public selectors require explicit kind syntax
and do not translate a bare Architecture pattern.
A template with match: any refuses a captureless pattern, while match: all
can use one beside a capturing pattern.
architecture.layer-declaration independently owns declaration diagnostics and
has only enabled. Its five configuration-error channels remain live under an
unrelated --only-rule; its four ordinary channels follow channel publication.
Disabling architecture.layer-violation does not disable declaration diagnostics.
See the selection table.
An enabled architecture.unassigned-class with mode: warn or error requires
a non-empty final architecture.layers, even when the file explicitly writes
layers: []. Ignored, disabled or unselected unassigned-class does not impose
that requirement. The refusal names the configuration that wrote the mode.
max_expanded_layers caps the total number of concrete layers produced by template expansion across all templates (default 500). The cap protects against pathological broad templates whose binding tuples would blow up the layer count. Raise the ceiling explicitly when a monorepo legitimately has more bounded contexts than the default allows; overflow rejects at expansion with an actionable error.
Computed Metrics¶
The computed_metrics: root key configures the six built-in health scores (health.complexity, health.cohesion, health.coupling, health.typing, health.maintainability, health.overall) and any user-defined computed metrics. This is a large enough surface — accepted keys, thresholds, custom formulas, available variables and functions — to have its own reference: see Health Scores > Configuration for the full schema.
Presets¶
Presets are named configuration bundles that apply predefined settings — thresholds, disabled rules, fail behavior — in a single flag. Instead of manually tuning dozens of options, pick a preset that matches your project's maturity.
| Preset | Description |
|---|---|
strict |
Tight thresholds for greenfield projects. Sets fail_on: warning |
legacy |
Relaxed thresholds for legacy codebases. Disables noisy rules |
ci |
Explicit CI mode. Sets fail_on: error |
# Use a single preset
vendor/bin/qmx check src/ --preset=strict
# Combine multiple presets
vendor/bin/qmx check src/ --preset=strict,ci
# Use a custom preset file
vendor/bin/qmx check src/ --preset=./my-preset.yaml
Priority order: Presets are applied after composer.json discovery but before qmx.yaml, left to right. Your config file sits above every preset, and the command line above the file.
Multiple presets: Presets combine with each other exactly as a preset combines with your file — each key by its own policy, described in How layers combine. For example, --preset=legacy,ci gives you legacy thresholds with CI fail behavior, because fail_on is a scalar the later layer wins.
Warning
only_rules is not accumulated across layers — the last layer that writes it replaces the list whole. This is intentional: only_rules is a restrictive filter, and union would widen the scope. disabled_rules accumulates authored statements, but a later exact producer enable can reverse an earlier disable; see Rule selection.
Custom presets: Any YAML file with the same structure as qmx.yaml can be used as a preset. Pass the file path instead of a built-in name.
Presets from the configuration file: a built-in preset can also be imported by name — imports: [strict] in qmx.yaml — so every tool that reads the file, including the pre-commit hook and the GitHub Action (neither passes --preset), judges by it. See Built-in presets. A file given to --preset cannot itself import.
Splitting a configuration¶
The root configuration file can list the files it builds on under imports:
# qmx.yaml
imports:
- strict # a built-in preset, by name
- config/architecture.yaml # one file
- subtree: config/teams # every .yaml / .yml file below the directory
fail_on: error
An entry is one of three things:
- A built-in preset — a string with no
/, no\and no extension:strict,legacyorci. - A file path — any other string, ending in
.yamlor.yml(in any letter case).*,?and[are ordinary characters in it. - A selector — a one-entry mapping,
{subtree: …}or{regex: …}, that stands for a set of files; see Selectors.
Each imported file is a layer of its own, written like any configuration file.
The layers are the entries in the order written, then the root file: for the
list above, strict, config/architecture.yaml, the files below
config/teams, qmx.yaml. A later entry overrides an earlier one, and
the root file overrides them all — each key by the policy described in
How layers combine. The whole chain sits where qmx.yaml
sits: above every preset given on the command line, below the command line
itself. -v names every file in that order (Configuration loaded from:
defaults, strict, config/architecture.yaml, config/teams/a.yaml,
config/teams/b.yaml, qmx.yaml, cli).
Paths. An imports entry is resolved against the directory of the file
that writes it, so --config=sub/qmx.yaml with imports: [base.yaml] reads
sub/base.yaml, and an imported config/a.yaml with imports: [b.yaml] reads
config/b.yaml. When a file is a symlink, that is the directory of the file it
points to: a configuration linked into a project reads the bases beside it.
Every other path, in any file of the chain — paths, exclude, cache.dir —
keeps the working directory as its base, exactly as in the root file. Refusals
and -v name an imported file by that path as seen from the file that imported
it (./ dropped, .. kept) — or by its full path when that file is a symlink
— together with the file that imported it.
Built-in presets¶
imports: [strict] applies the built-in preset the way --preset=strict
does, but from the configuration file. This is what makes the pre-commit hook
and the GitHub Action — neither passes --preset — judge by the same rules as
a local qmx check --preset=strict.
- The preset sits where the file naming it sits in the chain, so the file's own
keys override it. A preset given with
--presetstays below the whole chain. - Name it by its bare name. A bare name that is not built-in is refused at its
position:
Unknown preset "x". Available presets: ci, legacy, strict. A file needs a .yaml or .yml extension.To import a file of your own, write its extension (team.yaml). - Refusals and
-vcall itstrict, andsource[]in JSON reports it as{"kind": "preset", "name": "strict", "imported_by": {…}}. The same preset given with--presetis a separate layer namedpreset:strict; naming it both ways applies it in both places. - Only built-in presets are imported by name. A preset file of your own is a file: import it by path.
Selectors¶
A selector stands for a set of files that changes without anyone editing the
root file, such as config/qmx that other tools drop their parts into. It has
the same shape as the selectors of suppress_paths:
imports:
- subtree: config/qmx # the directory and everything below it
- regex: 'vendor/acme/[^/]+/qmx-extension\.yaml' # the whole relative path matches
- Which files. Every file whose name ends in
.yamlor.yml(in any letter case) below the directory of the file that writes the entry, named by its path from that directory. A selector never reaches above that directory; a file above it is a plain string entry (../shared.yaml). subtreenames a directory below the importing file's directory and stands for every file below it, at any depth. The directory must exist.{exact: …}is refused: a single file is a plain string.regexis a PCRE fragment that must match the whole path from the importing file's directory (config/teams/a.yaml, nota.yaml), the same way as insuppress_paths. The literal directory it starts with bounds the walk:vendor/[^/]+/qmx\.yamllooks only insidevendor/, and that directory must exist and is matched by the names on disk, letter for letter. A fragment that starts with a metacharacter, or holds|or)anywhere, walks the importing file's whole directory —vendor/andnode_modules/included — and is refused by any directory below it that cannot be listed or entered, even one the pattern could never match. Start the regex with a literal directory (config/qmx/…) to limit the walk and avoid that.- Order. The files one selector stands for have no order among themselves except what their own imports and the other entries of the list demand (see Nested imports); where nothing decides, byte order of the path applies, and a later name overrides an earlier one. Name two files in the order you need as separate entries when it matters.
- Skipped, not refused. A file named as a string anywhere in the same list, a file an earlier selector already stands for, and the importing file itself. A directory reached through several names (a symlink) is walked under each name; a file found twice is imported once, under the first path in byte order.
- Refused. A directory the walk must list or enter and cannot (a missing
read or search permission is refused, not skipped); a
.yaml/.ymlname that the selector matches but that is not a regular file (a broken link, a pipe); asubtreeor a regex prefix that is not an existing directory. File names the selector does not match are never judged; directories are always entered. - No match is accepted and not reported — that is the point of a selector
over files that may be absent. The price is that a typo in the pattern
matches nothing and says nothing (a regex after its literal prefix;
.ymlfiles for a pattern that ends in\.yaml); check-vonce.
Do not select over vendor/
Every file a selector matches becomes a layer of your configuration and can
change any key, the fail threshold included. {subtree: vendor} hands that
power to every installed package. For the same reason never select a name
packages use for their own configuration (qmx.yaml): you would import
configurations that were written for other projects. Import the packages
you trust by path, or narrow a regex to the one file name an extension
convention defines.
Nested imports¶
Any file read through imports may write imports itself — a shared standard
can split itself without its consumer listing its parts. Built-in presets are
included, though none writes it. A file given to --preset may not: it is
refused, and the hint says to import the file from the configuration file or
pass each as its own --preset.
# qmx.yaml
imports: [team/standard.yaml]
fail_on: error
# team/standard.yaml
imports: [strict, thresholds.yaml] # team/thresholds.yaml
The layers are strict, team/thresholds.yaml, team/standard.yaml,
qmx.yaml: what a file imports always sits below the file, and inside one list
a later entry sits above an earlier one. A file reached twice is read once and
placed once — the diamond below is the usual case:
| Graph | Layers, lowest first |
|---|---|
F: [A, B] |
A B F |
F: [A, B], A: [D], B: [D] (a diamond) |
D A B F |
F: [D, A], A: [D] |
D A F |
F: [A, D], A: [D] |
refused |
The order is the C3 linearization (the method resolution order of Python), so a file means the same whichever file imports it (a selector written in an imported file can break that; see ADR 0140). Two refusals follow from it:
- A cycle is refused at the entry that closes it, naming the files:
… closes an import cycle: "cfg/a.yaml" imports "cfg/b.yaml" imports "cfg/a.yaml". - Contradictory precedence is refused on the file whose entries cannot all
hold, naming each demand with the entry that makes it, and how each file was
reached:
F: [A, D]writesDaboveA, whileAimportsDand so needsAaboveD. Reorder the entries or drop one.
A refusal can come from a pair of files you never wrote together: F: [a, b,
c], c: [b, d], d: [a] is refused because c puts a above b through
d. The refusal prints that derived order.
Other refusals¶
Before the file is read: the same file twice in one list (two spellings or a
symlink of one file count as the same), a file importing itself, a directory or
other non-regular file, a URL, a file that is not .yaml or .yml, and an
exact selector.
imports is a list even for one file; imports: ~ and imports: [] import
nothing.
What a later file can change¶
Override follows the merge policy of each key, so some edits have no spelling:
| Node kind | A later file… |
|---|---|
scalar (fail_on, memory_limit, thresholds) |
replaces the value |
map (cache, coupling, one rule's options) |
merges key by key |
named map (rules, computed_metrics, architecture.allow) |
merges entry by entry |
list (paths, only_rules, architecture.layers, framework_namespaces) |
replaces the whole list — cannot append |
set (exclude, suppress_*, disabled_rules, exclude_health) |
adds — cannot remove a base's entry |
shorthand (threshold) |
expands in the writing file: a later warning keeps the base's error |
~ / {} |
"not written" / "changes nothing" — never a reset |
Keep what a project may want to change — paths, exclude, suppress_* — in
the root file rather than in a shared base, since a base's set entry cannot be
taken back. A finding that a configured value matches nothing names the file
that wrote it. When that file is a base in the project's Composer install
directory (vendor/), an exclude, suppress_paths or suppress_namespaces
entry, or a value of a rule's suppress_namespace_channels entry, that matches
nothing is listed in projectScope.unjudgedValues instead of being reported —
the project could not remove it (see
Suppression rules).
Baselines and architecture.unmatched-type
An architecture.unmatched-type finding is identified by the type and
its authored path, such as architecture.layers[0].implements[1]. Moving
that criterion into an imported file, or adding a preset, keeps the finding
and its baseline entry; moving it to another path re-identifies it.
Full Example¶
# Or start with a preset and customize:
# vendor/bin/qmx check src/ --preset=strict
paths:
- src/
exclude:
- subtree: vendor
- subtree: tests/Fixtures
suppress_paths:
- subtree: src/Entity
- subtree: src/DTO
suppress_namespaces:
- subtree: App\Tests
include_generated: false
format: summary
fail_on: error # default — warnings shown but don't fail the build
cache:
enabled: true
dir: /home/user/.cache/qmx
parallel:
workers: 4
coupling:
framework-namespaces:
- subtree: Symfony
- subtree: Doctrine
exclude_health:
- typing
disabled_rules:
- code-smell.boolean-argument
- duplication.clone
rules:
complexity.ccn:
suppress_namespaces:
- subtree: App\Tests
suppress_paths:
- subtree: src/Generated
callable:
warning: 15
error: 25
size.method-count:
warning: 25
error: 40
CLI Options Override Config¶
Command-line options always take precedence over values in the configuration file. For example:
# Config says paths: [src/], but CLI overrides it
vendor/bin/qmx check lib/
# Add extra suppressed paths on top of config
vendor/bin/qmx check src/ --suppress-path='subtree:src/Generated'
This makes it easy to experiment without editing the config file.
How layers combine¶
Every source of configuration is a layer: the built-in defaults, what
composer.json discovery finds, each preset in the order given, the files and
presets qmx.yaml imports, qmx.yaml, and the
command line — each one above the ones before it.
Each layer is read as it was written. Its keys are recognised and the form of
every value it writes is judged in that layer, before anything is merged, so a
misspelt key or a wrong value in a preset is refused even when your file
overrides it. Then the layers are merged, each key by the policy it declares.
A constraint needing the merged document — a layer name architecture.allow
refers to or a computed metric referenced by a formula — is judged once, on
the merged value. Formula syntax itself is checked in every writing layer. A refusal
about a resolved value, and every warning, names the layer that wrote
the value it is about; in --format=json that is the source field (see
Output Formats). Finding's rules, only_rules and disabled_rules are declared in the
same document. Rule forms, lower writes and paths retain their actual provenance;
selection and effective bands are concluded before runtime publication.
Five rules describe the document engine; owners declare their value forms:
A value that is invalid without merged context is refused in every layer that
writes it: the wrong shape, a forbidden empty value or a value outside a closed
dictionary. A file's format: bogus or cache: {dir: ""} is still refused
under a valid --format or --cache-dir. A constraint depending on other
resolved values is judged on the winner. Text refusals name the writing layer;
JSON publishes it in source.
This includes every coupling.framework_namespaces list's nonempty namespace
patterns, valid regex syntax and 256-selector ceiling, and each
architecture.layers list's unique names and patterns, membership criteria and
template bindings. A higher list cannot hide those defects. Architecture allow
references and cycles still require the merged set of layers.
~means "not written". A key written~, or left empty (key:), leaves the value to the layer below. The key itself is still recognised: a misspelt key is refused even when its value is~. Under a map keyed by names (computed_metrics,architecture.allow),name: ~still has its name checked.- An empty map changes nothing.
cache: {}orcomputed_metrics: {}over a preset keeps every value the preset wrote. An empty map does not reset a section to its defaults; write the values you want instead. - A list replaces or accumulates, by key.
paths,only_rules,architecture.layers, one layer's target list underarchitecture.allowand a computed metric'slevelsare replaced whole by the last layer that writes them. An empty list is still a written replacement, subject to its owner's constraints:paths: []is refused.exclude,suppress_paths,suppress_namespaces,disabled_rulesandexclude_healthaccumulate: every layer adds to them. An item of a list is a value, not an unwritten key, so an item written~is refused. - A shorthand is expanded in the layer that wrote it, before any merge.
threshold: 5in a preset iswarning: 5anderror: 5in that preset, so a file that writes onlywarning: 3over it getswarning 3anderror 5. Writing a shorthand beside one of its keys in the same layer is refused. - A key has three spellings: the snake_case, kebab-case and camelCase of its
words —
fail_on,fail-on,failOn. Any other spelling of the same words (Fail_On,FAILON,failon) is refused with the accepted one, for every key in the table below.
# preset
computed_metrics:
computed.risk:
formula: "m['complexity.ccn.max'] ?? 0"
levels: [class]
threshold: 20 # warning: 20 and error: 20, in the preset
# qmx.yaml
computed_metrics:
computed.risk:
warning: 10 # the formula, levels and error 20 still come from the preset
health.typing:
enabled: false # the only way to remove a metric a lower layer wrote
What cannot be written¶
Three things have no spelling, deliberately:
- Removing a key a lower layer wrote. A higher layer cannot delete a
preset's computed metric or its
architecture.allowentry for a layer. A computed metric is switched off withenabled: false; a layer's allow list can be replaced,[]included — which allows that layer nothing, rather than removing the entry. - Replacing a preset's whole set of computed metrics. Each metric merges on its own, by name.
- Returning to the default without writing it.
~and{}both keep the layer below; to get a default value back over a preset, write that value.
An empty map reset its section in earlier releases; see the changelog for what changed.
The declared rule section¶
The generated table reflects registered declarations and is refreshed by the same generator as other document policies. Finding consumes resolved nodes, not a second raw merge.
rules— options and level blocks merge by declared leaves. Shorthand expands in its writing layer; null/empty maps preserve lower writes. The rule boolean form changes enabled only. Restoring defaults requires explicit values.
The result is warning 2 from the command line and error 5 from the preset's
shorthand — not the rule's compiled default.
Configuration warnings¶
A configuration that is legal but probably not what was meant is accepted with
a warning rather than refused. Every command that reads the configuration
prints its warnings to stderr, prefixed Warning:, and --format=json also
lists them under configurationDiagnostics, each with the layers it is about.
For example, only_rules: [] in qmx.yaml over a preset that filters the
rules is lawful — an empty only_rules applies no filter — and says so:
Warning: "only_rules" is written empty in configuration file "qmx.yaml" and replaces the list preset "./ci-filter.yaml" wrote. An empty only_rules applies no rule filter: every enabled rule runs.
Every key¶
The table is generated from the declarations the configuration engine merges
by. <name> stands for a name you choose, and [] for any item of a list: an
item's keys are read from the layer that wrote the list and never merge. The
owner of a key may still refuse a merged value the policy let through — a
formula referencing an unknown computed metric, or a layer that allows a layer
layers does not declare.
The table lists suppress-namespaces and suppress-paths under every rule, but for
producers with project-scoped findings only they accept just an empty list or
null; see Producers with project-scoped findings only.
The same holds for suppress-namespace-channels, whose entries must name a channel that
reports at the namespace level.
| Key | Value | Across layers | Written ~ |
Written empty ({}, []) |
|---|---|---|---|---|
architecture |
map | Merged key by key; a written empty map changes nothing. | Not written: the layer below stands. | Changes nothing. |
architecture.layers |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
architecture.layers[].name |
string | Read from the layer that wrote the list; never merged across layers. | Not written: as if the key were absent. | Refused: a scalar is expected. |
architecture.layers[].patterns |
read by its owner | Read from the layer that wrote the list; never merged across layers. | Not written: as if the key were absent. | Its owner decides. |
architecture.layers[].suffix |
read by its owner | Read from the layer that wrote the list; never merged across layers. | Not written: as if the key were absent. | Its owner decides. |
architecture.layers[].attributes |
read by its owner | Read from the layer that wrote the list; never merged across layers. | Not written: as if the key were absent. | Its owner decides. |
architecture.layers[].member_attributes |
read by its owner | Read from the layer that wrote the list; never merged across layers. | Not written: as if the key were absent. | Its owner decides. |
architecture.layers[].implements |
read by its owner | Read from the layer that wrote the list; never merged across layers. | Not written: as if the key were absent. | Its owner decides. |
architecture.layers[].extends |
read by its owner | Read from the layer that wrote the list; never merged across layers. | Not written: as if the key were absent. | Its owner decides. |
architecture.layers[].match |
string | Read from the layer that wrote the list; never merged across layers. | Not written: as if the key were absent. | Refused: a scalar is expected. |
architecture.layers[].pending |
boolean | Read from the layer that wrote the list; never merged across layers. | Not written: as if the key were absent. | Refused: a scalar is expected. |
architecture.layers[].exclude |
map | Read from the layer that wrote the list; never merged across layers. | Not written: as if the key were absent. | Writes nothing: as if the key were absent. |
architecture.layers[].exclude.patterns |
read by its owner | Read from the layer that wrote the list; never merged across layers. | Not written: as if the key were absent. | Its owner decides. |
architecture.layers[].exclude.suffix |
read by its owner | Read from the layer that wrote the list; never merged across layers. | Not written: as if the key were absent. | Its owner decides. |
architecture.layers[].exclude.attributes |
read by its owner | Read from the layer that wrote the list; never merged across layers. | Not written: as if the key were absent. | Its owner decides. |
architecture.layers[].exclude.member_attributes |
read by its owner | Read from the layer that wrote the list; never merged across layers. | Not written: as if the key were absent. | Its owner decides. |
architecture.layers[].exclude.implements |
read by its owner | Read from the layer that wrote the list; never merged across layers. | Not written: as if the key were absent. | Its owner decides. |
architecture.layers[].exclude.extends |
read by its owner | Read from the layer that wrote the list; never merged across layers. | Not written: as if the key were absent. | Its owner decides. |
architecture.layers[].exclude.match |
string | Read from the layer that wrote the list; never merged across layers. | Not written: as if the key were absent. | Refused: a scalar is expected. |
architecture.allow |
map by name: names checked against architecture.layers once every layer is merged |
Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
architecture.allow.<name> |
list (item: read by its owner) | The last layer that writes the list replaces it whole; an empty list replaces too. | The name is judged; the body stays with the layer below. | Replaces the list below with an empty one. |
architecture.coverage-gap |
string | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
architecture.max_expanded_layers |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
cache |
map | Merged key by key; a written empty map changes nothing. | Not written: the layer below stands. | Changes nothing. |
cache.dir |
string | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
cache.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
computed_metrics |
map by name: a name judged by the section's grammar in the layer that wrote it | Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
computed_metrics.<name> |
map | Merged key by key; a written empty map changes nothing. | The name is judged; the body stays with the layer below. | Changes nothing. |
computed_metrics.<name>.description |
string | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
computed_metrics.<name>.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
computed_metrics.<name>.error |
number | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
computed_metrics.<name>.formula |
string | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
computed_metrics.<name>.formulas |
map | Merged key by key; a written empty map changes nothing. | Not written: the layer below stands. | Changes nothing. |
computed_metrics.<name>.formulas.class |
string | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
computed_metrics.<name>.formulas.namespace |
string | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
computed_metrics.<name>.formulas.project |
string | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
computed_metrics.<name>.inverted |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
computed_metrics.<name>.levels |
list (item: string) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
computed_metrics.<name>.warning |
number | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
computed_metrics.<name>.threshold |
number | Shorthand for warning and error: expanded in the layer that wrote it, before any merge; each key then merges on its own. Writing it beside one of them in the same layer is refused. |
Not written: the layer below stands. | Refused: a scalar is expected. |
coupling |
map | Merged key by key; a written empty map changes nothing. | Not written: the layer below stands. | Changes nothing. |
coupling.framework_namespaces |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
coupling.framework_namespaces[].exact |
string | Read from the layer that wrote the list; never merged across layers. | Not written: as if the key were absent. | Refused: a scalar is expected. |
coupling.framework_namespaces[].subtree |
string | Read from the layer that wrote the list; never merged across layers. | Not written: as if the key were absent. | Refused: a scalar is expected. |
coupling.framework_namespaces[].regex |
string | Read from the layer that wrote the list; never merged across layers. | Not written: as if the key were absent. | Refused: a scalar is expected. |
disabled_rules |
list (item: string) | Every layer adds its elements; duplicates collapse. | Not written: the layer below stands. An item written ~ is refused. |
Adds nothing. |
exclude |
list (item: map) | Every layer adds its elements; duplicates collapse. | Not written: the layer below stands. An item written ~ is refused. |
Adds nothing. |
exclude[].exact |
string | Read from the layer that wrote the list; never merged across layers. | Not written: as if the key were absent. | Refused: a scalar is expected. |
exclude[].subtree |
string | Read from the layer that wrote the list; never merged across layers. | Not written: as if the key were absent. | Refused: a scalar is expected. |
exclude[].regex |
string | Read from the layer that wrote the list; never merged across layers. | Not written: as if the key were absent. | Refused: a scalar is expected. |
exclude_health |
list (item: string) | Every layer adds its elements; duplicates collapse. | Not written: the layer below stands. An item written ~ is refused. |
Adds nothing. |
fail_on |
string | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
format |
string | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
imports |
list (item: read by its owner) | Read per file, in the root file and in any file read through imports; never merged across layers. |
Not written: the file imports nothing. An item written ~ is refused. |
The file imports nothing. |
include_autoload_dev |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
include_generated |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
memory_limit |
string or integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
only_rules |
list (item: string) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. A warning says so when the list below was not empty. |
parallel |
map | Merged key by key; a written empty map changes nothing. | Not written: the layer below stands. | Changes nothing. |
parallel.workers |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
paths |
list (item: string) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules |
map by name: a name judged by the section's grammar in the layer that wrote it | Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
rules.annotation.directive |
map | Merged key by key; a written empty map changes nothing. | The name is judged; the body stays with the layer below. | Changes nothing. |
rules.annotation.directive.unused-directive-severity |
string | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.annotation.directive.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.annotation.directive.suppress-namespace-channels |
map by name: a name judged by the section's grammar in the layer that wrote it | Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
rules.annotation.directive.suppress-namespace-channels.<name> |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | The name is judged; the body stays with the layer below. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.annotation.directive.suppress-namespaces |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.annotation.directive.suppress-paths |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.architecture.circular-dependency |
map | Merged key by key; a written empty map changes nothing. | The name is judged; the body stays with the layer below. | Changes nothing. |
rules.architecture.circular-dependency.direct-as-error |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.architecture.circular-dependency.ignore-relations |
list (item: string) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.architecture.circular-dependency.max-cycle-size |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.architecture.circular-dependency.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.architecture.circular-dependency.suppress-namespace-channels |
map by name: a name judged by the section's grammar in the layer that wrote it | Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
rules.architecture.circular-dependency.suppress-namespace-channels.<name> |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | The name is judged; the body stays with the layer below. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.architecture.circular-dependency.suppress-namespaces |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.architecture.circular-dependency.suppress-paths |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.architecture.layer-declaration |
map | Merged key by key; a written empty map changes nothing. | The name is judged; the body stays with the layer below. | Changes nothing. |
rules.architecture.layer-declaration.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.architecture.layer-declaration.suppress-namespace-channels |
map by name: a name judged by the section's grammar in the layer that wrote it | Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
rules.architecture.layer-declaration.suppress-namespace-channels.<name> |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | The name is judged; the body stays with the layer below. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.architecture.layer-declaration.suppress-namespaces |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.architecture.layer-declaration.suppress-paths |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.architecture.layer-violation |
map | Merged key by key; a written empty map changes nothing. | The name is judged; the body stays with the layer below. | Changes nothing. |
rules.architecture.layer-violation.severity |
string | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.architecture.layer-violation.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.architecture.layer-violation.suppress-namespace-channels |
map by name: a name judged by the section's grammar in the layer that wrote it | Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
rules.architecture.layer-violation.suppress-namespace-channels.<name> |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | The name is judged; the body stays with the layer below. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.architecture.layer-violation.suppress-namespaces |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.architecture.layer-violation.suppress-paths |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.architecture.unassigned-class |
map | Merged key by key; a written empty map changes nothing. | The name is judged; the body stays with the layer below. | Changes nothing. |
rules.architecture.unassigned-class.mode |
string | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.architecture.unassigned-class.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.architecture.unassigned-class.suppress-namespace-channels |
map by name: a name judged by the section's grammar in the layer that wrote it | Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
rules.architecture.unassigned-class.suppress-namespace-channels.<name> |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | The name is judged; the body stays with the layer below. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.architecture.unassigned-class.suppress-namespaces |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.architecture.unassigned-class.suppress-paths |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.baseline.unused-entry |
map | Merged key by key; a written empty map changes nothing. | The name is judged; the body stays with the layer below. | Changes nothing. |
rules.baseline.unused-entry.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.baseline.unused-entry.suppress-namespace-channels |
map by name: a name judged by the section's grammar in the layer that wrote it | Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
rules.baseline.unused-entry.suppress-namespace-channels.<name> |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | The name is judged; the body stays with the layer below. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.baseline.unused-entry.suppress-namespaces |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.baseline.unused-entry.suppress-paths |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.code-smell.boolean-argument |
map | Merged key by key; a written empty map changes nothing. | The name is judged; the body stays with the layer below. | Changes nothing. |
rules.code-smell.boolean-argument.allowed-prefixes |
list (item: string) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.code-smell.boolean-argument.flag-promoted-properties |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.code-smell.boolean-argument.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.code-smell.boolean-argument.suppress-namespace-channels |
map by name: a name judged by the section's grammar in the layer that wrote it | Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
rules.code-smell.boolean-argument.suppress-namespace-channels.<name> |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | The name is judged; the body stays with the layer below. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.code-smell.boolean-argument.suppress-namespaces |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.code-smell.boolean-argument.suppress-paths |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.code-smell.constructor-overinjection |
map | Merged key by key; a written empty map changes nothing. | The name is judged; the body stays with the layer below. | Changes nothing. |
rules.code-smell.constructor-overinjection.error |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.code-smell.constructor-overinjection.warning |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.code-smell.constructor-overinjection.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.code-smell.constructor-overinjection.suppress-namespace-channels |
map by name: a name judged by the section's grammar in the layer that wrote it | Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
rules.code-smell.constructor-overinjection.suppress-namespace-channels.<name> |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | The name is judged; the body stays with the layer below. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.code-smell.constructor-overinjection.suppress-namespaces |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.code-smell.constructor-overinjection.suppress-paths |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.code-smell.constructor-overinjection.threshold |
integer | Shorthand for warning and error: expanded in the layer that wrote it, before any merge; each key then merges on its own. Writing it beside one of them in the same layer is refused. |
Not written: the layer below stands. | Refused: a scalar is expected. |
rules.code-smell.count-in-loop |
map | Merged key by key; a written empty map changes nothing. | The name is judged; the body stays with the layer below. | Changes nothing. |
rules.code-smell.count-in-loop.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.code-smell.count-in-loop.suppress-namespace-channels |
map by name: a name judged by the section's grammar in the layer that wrote it | Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
rules.code-smell.count-in-loop.suppress-namespace-channels.<name> |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | The name is judged; the body stays with the layer below. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.code-smell.count-in-loop.suppress-namespaces |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.code-smell.count-in-loop.suppress-paths |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.code-smell.debug-code |
map | Merged key by key; a written empty map changes nothing. | The name is judged; the body stays with the layer below. | Changes nothing. |
rules.code-smell.debug-code.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.code-smell.debug-code.suppress-namespace-channels |
map by name: a name judged by the section's grammar in the layer that wrote it | Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
rules.code-smell.debug-code.suppress-namespace-channels.<name> |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | The name is judged; the body stays with the layer below. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.code-smell.debug-code.suppress-namespaces |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.code-smell.debug-code.suppress-paths |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.code-smell.empty-catch |
map | Merged key by key; a written empty map changes nothing. | The name is judged; the body stays with the layer below. | Changes nothing. |
rules.code-smell.empty-catch.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.code-smell.empty-catch.suppress-namespace-channels |
map by name: a name judged by the section's grammar in the layer that wrote it | Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
rules.code-smell.empty-catch.suppress-namespace-channels.<name> |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | The name is judged; the body stays with the layer below. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.code-smell.empty-catch.suppress-namespaces |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.code-smell.empty-catch.suppress-paths |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.code-smell.error-suppression |
map | Merged key by key; a written empty map changes nothing. | The name is judged; the body stays with the layer below. | Changes nothing. |
rules.code-smell.error-suppression.allowed-functions |
list (item: string) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.code-smell.error-suppression.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.code-smell.error-suppression.suppress-namespace-channels |
map by name: a name judged by the section's grammar in the layer that wrote it | Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
rules.code-smell.error-suppression.suppress-namespace-channels.<name> |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | The name is judged; the body stays with the layer below. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.code-smell.error-suppression.suppress-namespaces |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.code-smell.error-suppression.suppress-paths |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.code-smell.eval |
map | Merged key by key; a written empty map changes nothing. | The name is judged; the body stays with the layer below. | Changes nothing. |
rules.code-smell.eval.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.code-smell.eval.suppress-namespace-channels |
map by name: a name judged by the section's grammar in the layer that wrote it | Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
rules.code-smell.eval.suppress-namespace-channels.<name> |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | The name is judged; the body stays with the layer below. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.code-smell.eval.suppress-namespaces |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.code-smell.eval.suppress-paths |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.code-smell.exit |
map | Merged key by key; a written empty map changes nothing. | The name is judged; the body stays with the layer below. | Changes nothing. |
rules.code-smell.exit.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.code-smell.exit.suppress-namespace-channels |
map by name: a name judged by the section's grammar in the layer that wrote it | Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
rules.code-smell.exit.suppress-namespace-channels.<name> |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | The name is judged; the body stays with the layer below. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.code-smell.exit.suppress-namespaces |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.code-smell.exit.suppress-paths |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.code-smell.goto |
map | Merged key by key; a written empty map changes nothing. | The name is judged; the body stays with the layer below. | Changes nothing. |
rules.code-smell.goto.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.code-smell.goto.suppress-namespace-channels |
map by name: a name judged by the section's grammar in the layer that wrote it | Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
rules.code-smell.goto.suppress-namespace-channels.<name> |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | The name is judged; the body stays with the layer below. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.code-smell.goto.suppress-namespaces |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.code-smell.goto.suppress-paths |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.code-smell.identical-subexpression |
map | Merged key by key; a written empty map changes nothing. | The name is judged; the body stays with the layer below. | Changes nothing. |
rules.code-smell.identical-subexpression.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.code-smell.identical-subexpression.suppress-namespace-channels |
map by name: a name judged by the section's grammar in the layer that wrote it | Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
rules.code-smell.identical-subexpression.suppress-namespace-channels.<name> |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | The name is judged; the body stays with the layer below. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.code-smell.identical-subexpression.suppress-namespaces |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.code-smell.identical-subexpression.suppress-paths |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.code-smell.long-parameter-list |
map | Merged key by key; a written empty map changes nothing. | The name is judged; the body stays with the layer below. | Changes nothing. |
rules.code-smell.long-parameter-list.error |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.code-smell.long-parameter-list.vo-error |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.code-smell.long-parameter-list.vo-warning |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.code-smell.long-parameter-list.warning |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.code-smell.long-parameter-list.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.code-smell.long-parameter-list.suppress-namespace-channels |
map by name: a name judged by the section's grammar in the layer that wrote it | Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
rules.code-smell.long-parameter-list.suppress-namespace-channels.<name> |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | The name is judged; the body stays with the layer below. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.code-smell.long-parameter-list.suppress-namespaces |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.code-smell.long-parameter-list.suppress-paths |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.code-smell.long-parameter-list.threshold |
integer | Shorthand for warning and error: expanded in the layer that wrote it, before any merge; each key then merges on its own. Writing it beside one of them in the same layer is refused. |
Not written: the layer below stands. | Refused: a scalar is expected. |
rules.code-smell.long-parameter-list.vo-threshold |
integer | Shorthand for vo-warning and vo-error: expanded in the layer that wrote it, before any merge; each key then merges on its own. Writing it beside one of them in the same layer is refused. |
Not written: the layer below stands. | Refused: a scalar is expected. |
rules.code-smell.superglobals |
map | Merged key by key; a written empty map changes nothing. | The name is judged; the body stays with the layer below. | Changes nothing. |
rules.code-smell.superglobals.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.code-smell.superglobals.suppress-namespace-channels |
map by name: a name judged by the section's grammar in the layer that wrote it | Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
rules.code-smell.superglobals.suppress-namespace-channels.<name> |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | The name is judged; the body stays with the layer below. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.code-smell.superglobals.suppress-namespaces |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.code-smell.superglobals.suppress-paths |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.code-smell.unreachable-code |
map | Merged key by key; a written empty map changes nothing. | The name is judged; the body stays with the layer below. | Changes nothing. |
rules.code-smell.unreachable-code.error |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.code-smell.unreachable-code.warning |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.code-smell.unreachable-code.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.code-smell.unreachable-code.suppress-namespace-channels |
map by name: a name judged by the section's grammar in the layer that wrote it | Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
rules.code-smell.unreachable-code.suppress-namespace-channels.<name> |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | The name is judged; the body stays with the layer below. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.code-smell.unreachable-code.suppress-namespaces |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.code-smell.unreachable-code.suppress-paths |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.code-smell.unreachable-code.threshold |
integer | Shorthand for warning and error: expanded in the layer that wrote it, before any merge; each key then merges on its own. Writing it beside one of them in the same layer is refused. |
Not written: the layer below stands. | Refused: a scalar is expected. |
rules.code-smell.unused-private |
map | Merged key by key; a written empty map changes nothing. | The name is judged; the body stays with the layer below. | Changes nothing. |
rules.code-smell.unused-private.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.code-smell.unused-private.suppress-namespace-channels |
map by name: a name judged by the section's grammar in the layer that wrote it | Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
rules.code-smell.unused-private.suppress-namespace-channels.<name> |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | The name is judged; the body stays with the layer below. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.code-smell.unused-private.suppress-namespaces |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.code-smell.unused-private.suppress-paths |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.cohesion.lcom |
map | Merged key by key; a written empty map changes nothing. | The name is judged; the body stays with the layer below. | Changes nothing. |
rules.cohesion.lcom.error |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.cohesion.lcom.exclude-methods |
list (item: string) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.cohesion.lcom.exclude-readonly |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.cohesion.lcom.min-methods |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.cohesion.lcom.warning |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.cohesion.lcom.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.cohesion.lcom.suppress-namespace-channels |
map by name: a name judged by the section's grammar in the layer that wrote it | Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
rules.cohesion.lcom.suppress-namespace-channels.<name> |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | The name is judged; the body stays with the layer below. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.cohesion.lcom.suppress-namespaces |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.cohesion.lcom.suppress-paths |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.cohesion.lcom.threshold |
integer | Shorthand for warning and error: expanded in the layer that wrote it, before any merge; each key then merges on its own. Writing it beside one of them in the same layer is refused. |
Not written: the layer below stands. | Refused: a scalar is expected. |
rules.complexity.ccn |
map | Merged key by key; a written empty map changes nothing. | The name is judged; the body stays with the layer below. | Changes nothing. |
rules.complexity.ccn.callable |
map | Merged key by key; a written empty map changes nothing. | Not written: the layer below stands. | Changes nothing. |
rules.complexity.ccn.callable.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.complexity.ccn.callable.error |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.complexity.ccn.callable.warning |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.complexity.ccn.callable.threshold |
integer | Shorthand for warning and error: expanded in the layer that wrote it, before any merge; each key then merges on its own. Writing it beside one of them in the same layer is refused. |
Not written: the layer below stands. | Refused: a scalar is expected. |
rules.complexity.ccn.class |
map | Merged key by key; a written empty map changes nothing. | Not written: the layer below stands. | Changes nothing. |
rules.complexity.ccn.class.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.complexity.ccn.class.max-error |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.complexity.ccn.class.max-warning |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.complexity.ccn.class.threshold |
integer | Shorthand for max-warning and max-error: expanded in the layer that wrote it, before any merge; each key then merges on its own. Writing it beside one of them in the same layer is refused. |
Not written: the layer below stands. | Refused: a scalar is expected. |
rules.complexity.ccn.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.complexity.ccn.suppress-namespace-channels |
map by name: a name judged by the section's grammar in the layer that wrote it | Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
rules.complexity.ccn.suppress-namespace-channels.<name> |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | The name is judged; the body stays with the layer below. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.complexity.ccn.suppress-namespaces |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.complexity.ccn.suppress-paths |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.complexity.ccn.threshold |
integer | Shorthand for callable.threshold: expanded in the layer that wrote it, before any merge; each key then merges on its own. Writing it beside one of them in the same layer is refused. |
Not written: the layer below stands. | Refused: a scalar is expected. |
rules.complexity.cognitive |
map | Merged key by key; a written empty map changes nothing. | The name is judged; the body stays with the layer below. | Changes nothing. |
rules.complexity.cognitive.callable |
map | Merged key by key; a written empty map changes nothing. | Not written: the layer below stands. | Changes nothing. |
rules.complexity.cognitive.callable.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.complexity.cognitive.callable.error |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.complexity.cognitive.callable.warning |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.complexity.cognitive.callable.threshold |
integer | Shorthand for warning and error: expanded in the layer that wrote it, before any merge; each key then merges on its own. Writing it beside one of them in the same layer is refused. |
Not written: the layer below stands. | Refused: a scalar is expected. |
rules.complexity.cognitive.class |
map | Merged key by key; a written empty map changes nothing. | Not written: the layer below stands. | Changes nothing. |
rules.complexity.cognitive.class.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.complexity.cognitive.class.max-error |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.complexity.cognitive.class.max-warning |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.complexity.cognitive.class.threshold |
integer | Shorthand for max-warning and max-error: expanded in the layer that wrote it, before any merge; each key then merges on its own. Writing it beside one of them in the same layer is refused. |
Not written: the layer below stands. | Refused: a scalar is expected. |
rules.complexity.cognitive.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.complexity.cognitive.suppress-namespace-channels |
map by name: a name judged by the section's grammar in the layer that wrote it | Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
rules.complexity.cognitive.suppress-namespace-channels.<name> |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | The name is judged; the body stays with the layer below. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.complexity.cognitive.suppress-namespaces |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.complexity.cognitive.suppress-paths |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.complexity.cognitive.threshold |
integer | Shorthand for callable.threshold: expanded in the layer that wrote it, before any merge; each key then merges on its own. Writing it beside one of them in the same layer is refused. |
Not written: the layer below stands. | Refused: a scalar is expected. |
rules.complexity.npath |
map | Merged key by key; a written empty map changes nothing. | The name is judged; the body stays with the layer below. | Changes nothing. |
rules.complexity.npath.callable |
map | Merged key by key; a written empty map changes nothing. | Not written: the layer below stands. | Changes nothing. |
rules.complexity.npath.callable.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.complexity.npath.callable.error |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.complexity.npath.callable.warning |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.complexity.npath.callable.threshold |
integer | Shorthand for warning and error: expanded in the layer that wrote it, before any merge; each key then merges on its own. Writing it beside one of them in the same layer is refused. |
Not written: the layer below stands. | Refused: a scalar is expected. |
rules.complexity.npath.class |
map | Merged key by key; a written empty map changes nothing. | Not written: the layer below stands. | Changes nothing. |
rules.complexity.npath.class.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.complexity.npath.class.max-error |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.complexity.npath.class.max-warning |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.complexity.npath.class.threshold |
integer | Shorthand for max-warning and max-error: expanded in the layer that wrote it, before any merge; each key then merges on its own. Writing it beside one of them in the same layer is refused. |
Not written: the layer below stands. | Refused: a scalar is expected. |
rules.complexity.npath.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.complexity.npath.suppress-namespace-channels |
map by name: a name judged by the section's grammar in the layer that wrote it | Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
rules.complexity.npath.suppress-namespace-channels.<name> |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | The name is judged; the body stays with the layer below. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.complexity.npath.suppress-namespaces |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.complexity.npath.suppress-paths |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.complexity.npath.threshold |
integer | Shorthand for callable.threshold: expanded in the layer that wrote it, before any merge; each key then merges on its own. Writing it beside one of them in the same layer is refused. |
Not written: the layer below stands. | Refused: a scalar is expected. |
rules.complexity.wmc |
map | Merged key by key; a written empty map changes nothing. | The name is judged; the body stays with the layer below. | Changes nothing. |
rules.complexity.wmc.error |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.complexity.wmc.exclude-data-classes |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.complexity.wmc.warning |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.complexity.wmc.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.complexity.wmc.suppress-namespace-channels |
map by name: a name judged by the section's grammar in the layer that wrote it | Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
rules.complexity.wmc.suppress-namespace-channels.<name> |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | The name is judged; the body stays with the layer below. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.complexity.wmc.suppress-namespaces |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.complexity.wmc.suppress-paths |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.complexity.wmc.threshold |
integer | Shorthand for warning and error: expanded in the layer that wrote it, before any merge; each key then merges on its own. Writing it beside one of them in the same layer is refused. |
Not written: the layer below stands. | Refused: a scalar is expected. |
rules.computed |
map | Merged key by key; a written empty map changes nothing. | The name is judged; the body stays with the layer below. | Changes nothing. |
rules.computed.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.computed.suppress-namespace-channels |
map by name: a name judged by the section's grammar in the layer that wrote it | Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
rules.computed.suppress-namespace-channels.<name> |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | The name is judged; the body stays with the layer below. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.computed.suppress-namespaces |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.computed.suppress-paths |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.coupling.cbo |
map | Merged key by key; a written empty map changes nothing. | The name is judged; the body stays with the layer below. | Changes nothing. |
rules.coupling.cbo.class |
map | Merged key by key; a written empty map changes nothing. | Not written: the layer below stands. | Changes nothing. |
rules.coupling.cbo.class.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.coupling.cbo.class.error |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.coupling.cbo.class.scope |
string | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.coupling.cbo.class.warning |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.coupling.cbo.class.threshold |
integer | Shorthand for warning and error: expanded in the layer that wrote it, before any merge; each key then merges on its own. Writing it beside one of them in the same layer is refused. |
Not written: the layer below stands. | Refused: a scalar is expected. |
rules.coupling.cbo.namespace |
map | Merged key by key; a written empty map changes nothing. | Not written: the layer below stands. | Changes nothing. |
rules.coupling.cbo.namespace.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.coupling.cbo.namespace.error |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.coupling.cbo.namespace.min-class-count |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.coupling.cbo.namespace.warning |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.coupling.cbo.namespace.threshold |
integer | Shorthand for warning and error: expanded in the layer that wrote it, before any merge; each key then merges on its own. Writing it beside one of them in the same layer is refused. |
Not written: the layer below stands. | Refused: a scalar is expected. |
rules.coupling.cbo.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.coupling.cbo.suppress-namespace-channels |
map by name: a name judged by the section's grammar in the layer that wrote it | Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
rules.coupling.cbo.suppress-namespace-channels.<name> |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | The name is judged; the body stays with the layer below. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.coupling.cbo.suppress-namespaces |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.coupling.cbo.suppress-paths |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.coupling.cbo.threshold |
integer | Shorthand for class.threshold and namespace.threshold: expanded in the layer that wrote it, before any merge; each key then merges on its own. Writing it beside one of them in the same layer is refused. |
Not written: the layer below stands. | Refused: a scalar is expected. |
rules.coupling.cbo.warning |
integer | Shorthand for class.warning and namespace.warning: expanded in the layer that wrote it, before any merge; each key then merges on its own. Writing it beside one of them in the same layer is refused. |
Not written: the layer below stands. | Refused: a scalar is expected. |
rules.coupling.cbo.error |
integer | Shorthand for class.error and namespace.error: expanded in the layer that wrote it, before any merge; each key then merges on its own. Writing it beside one of them in the same layer is refused. |
Not written: the layer below stands. | Refused: a scalar is expected. |
rules.coupling.cbo.scope |
string | Shorthand for class.scope: expanded in the layer that wrote it, before any merge; each key then merges on its own. Writing it beside one of them in the same layer is refused. |
Not written: the layer below stands. | Refused: a scalar is expected. |
rules.coupling.class-rank |
map | Merged key by key; a written empty map changes nothing. | The name is judged; the body stays with the layer below. | Changes nothing. |
rules.coupling.class-rank.error |
number | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.coupling.class-rank.warning |
number | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.coupling.class-rank.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.coupling.class-rank.suppress-namespace-channels |
map by name: a name judged by the section's grammar in the layer that wrote it | Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
rules.coupling.class-rank.suppress-namespace-channels.<name> |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | The name is judged; the body stays with the layer below. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.coupling.class-rank.suppress-namespaces |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.coupling.class-rank.suppress-paths |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.coupling.class-rank.threshold |
number | Shorthand for warning and error: expanded in the layer that wrote it, before any merge; each key then merges on its own. Writing it beside one of them in the same layer is refused. |
Not written: the layer below stands. | Refused: a scalar is expected. |
rules.coupling.distance |
map | Merged key by key; a written empty map changes nothing. | The name is judged; the body stays with the layer below. | Changes nothing. |
rules.coupling.distance.include-namespaces |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.coupling.distance.max-distance-error |
number | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.coupling.distance.max-distance-warning |
number | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.coupling.distance.min-type-count |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.coupling.distance.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.coupling.distance.suppress-namespace-channels |
map by name: a name judged by the section's grammar in the layer that wrote it | Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
rules.coupling.distance.suppress-namespace-channels.<name> |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | The name is judged; the body stays with the layer below. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.coupling.distance.suppress-namespaces |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.coupling.distance.suppress-paths |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.coupling.distance.threshold |
number | Shorthand for max-distance-warning and max-distance-error: expanded in the layer that wrote it, before any merge; each key then merges on its own. Writing it beside one of them in the same layer is refused. |
Not written: the layer below stands. | Refused: a scalar is expected. |
rules.coupling.instability |
map | Merged key by key; a written empty map changes nothing. | The name is judged; the body stays with the layer below. | Changes nothing. |
rules.coupling.instability.class |
map | Merged key by key; a written empty map changes nothing. | Not written: the layer below stands. | Changes nothing. |
rules.coupling.instability.class.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.coupling.instability.class.max-error |
number | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.coupling.instability.class.max-warning |
number | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.coupling.instability.class.min-afferent |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.coupling.instability.class.threshold |
number | Shorthand for max-warning and max-error: expanded in the layer that wrote it, before any merge; each key then merges on its own. Writing it beside one of them in the same layer is refused. |
Not written: the layer below stands. | Refused: a scalar is expected. |
rules.coupling.instability.namespace |
map | Merged key by key; a written empty map changes nothing. | Not written: the layer below stands. | Changes nothing. |
rules.coupling.instability.namespace.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.coupling.instability.namespace.max-error |
number | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.coupling.instability.namespace.max-warning |
number | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.coupling.instability.namespace.min-afferent |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.coupling.instability.namespace.min-type-count |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.coupling.instability.namespace.threshold |
number | Shorthand for max-warning and max-error: expanded in the layer that wrote it, before any merge; each key then merges on its own. Writing it beside one of them in the same layer is refused. |
Not written: the layer below stands. | Refused: a scalar is expected. |
rules.coupling.instability.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.coupling.instability.suppress-namespace-channels |
map by name: a name judged by the section's grammar in the layer that wrote it | Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
rules.coupling.instability.suppress-namespace-channels.<name> |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | The name is judged; the body stays with the layer below. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.coupling.instability.suppress-namespaces |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.coupling.instability.suppress-paths |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.coupling.instability.threshold |
number | Shorthand for class.threshold and namespace.threshold: expanded in the layer that wrote it, before any merge; each key then merges on its own. Writing it beside one of them in the same layer is refused. |
Not written: the layer below stands. | Refused: a scalar is expected. |
rules.coupling.instability.max-warning |
number | Shorthand for class.max-warning and namespace.max-warning: expanded in the layer that wrote it, before any merge; each key then merges on its own. Writing it beside one of them in the same layer is refused. |
Not written: the layer below stands. | Refused: a scalar is expected. |
rules.coupling.instability.max-error |
number | Shorthand for class.max-error and namespace.max-error: expanded in the layer that wrote it, before any merge; each key then merges on its own. Writing it beside one of them in the same layer is refused. |
Not written: the layer below stands. | Refused: a scalar is expected. |
rules.coupling.unmatched-framework-namespace |
map | Merged key by key; a written empty map changes nothing. | The name is judged; the body stays with the layer below. | Changes nothing. |
rules.coupling.unmatched-framework-namespace.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.coupling.unmatched-framework-namespace.suppress-namespace-channels |
map by name: a name judged by the section's grammar in the layer that wrote it | Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
rules.coupling.unmatched-framework-namespace.suppress-namespace-channels.<name> |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | The name is judged; the body stays with the layer below. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.coupling.unmatched-framework-namespace.suppress-namespaces |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.coupling.unmatched-framework-namespace.suppress-paths |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.design.data-class |
map | Merged key by key; a written empty map changes nothing. | The name is judged; the body stays with the layer below. | Changes nothing. |
rules.design.data-class.exclude-exceptions |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.design.data-class.exclude-promoted-only |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.design.data-class.exclude-readonly |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.design.data-class.min-members |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.design.data-class.wmc-threshold |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.design.data-class.woc-threshold |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.design.data-class.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.design.data-class.suppress-namespace-channels |
map by name: a name judged by the section's grammar in the layer that wrote it | Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
rules.design.data-class.suppress-namespace-channels.<name> |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | The name is judged; the body stays with the layer below. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.design.data-class.suppress-namespaces |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.design.data-class.suppress-paths |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.design.dit |
map | Merged key by key; a written empty map changes nothing. | The name is judged; the body stays with the layer below. | Changes nothing. |
rules.design.dit.error |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.design.dit.warning |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.design.dit.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.design.dit.suppress-namespace-channels |
map by name: a name judged by the section's grammar in the layer that wrote it | Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
rules.design.dit.suppress-namespace-channels.<name> |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | The name is judged; the body stays with the layer below. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.design.dit.suppress-namespaces |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.design.dit.suppress-paths |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.design.dit.threshold |
integer | Shorthand for warning and error: expanded in the layer that wrote it, before any merge; each key then merges on its own. Writing it beside one of them in the same layer is refused. |
Not written: the layer below stands. | Refused: a scalar is expected. |
rules.design.god-class |
map | Merged key by key; a written empty map changes nothing. | The name is judged; the body stays with the layer below. | Changes nothing. |
rules.design.god-class.class-loc-threshold |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.design.god-class.exclude-readonly |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.design.god-class.lcom-threshold |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.design.god-class.min-criteria |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.design.god-class.min-methods |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.design.god-class.tcc-threshold |
number | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.design.god-class.wmc-threshold |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.design.god-class.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.design.god-class.suppress-namespace-channels |
map by name: a name judged by the section's grammar in the layer that wrote it | Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
rules.design.god-class.suppress-namespace-channels.<name> |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | The name is judged; the body stays with the layer below. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.design.god-class.suppress-namespaces |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.design.god-class.suppress-paths |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.design.noc |
map | Merged key by key; a written empty map changes nothing. | The name is judged; the body stays with the layer below. | Changes nothing. |
rules.design.noc.error |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.design.noc.warning |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.design.noc.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.design.noc.suppress-namespace-channels |
map by name: a name judged by the section's grammar in the layer that wrote it | Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
rules.design.noc.suppress-namespace-channels.<name> |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | The name is judged; the body stays with the layer below. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.design.noc.suppress-namespaces |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.design.noc.suppress-paths |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.design.noc.threshold |
integer | Shorthand for warning and error: expanded in the layer that wrote it, before any merge; each key then merges on its own. Writing it beside one of them in the same layer is refused. |
Not written: the layer below stands. | Refused: a scalar is expected. |
rules.design.type-coverage.param |
map | Merged key by key; a written empty map changes nothing. | The name is judged; the body stays with the layer below. | Changes nothing. |
rules.design.type-coverage.param.error |
number | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.design.type-coverage.param.warning |
number | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.design.type-coverage.param.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.design.type-coverage.param.suppress-namespace-channels |
map by name: a name judged by the section's grammar in the layer that wrote it | Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
rules.design.type-coverage.param.suppress-namespace-channels.<name> |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | The name is judged; the body stays with the layer below. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.design.type-coverage.param.suppress-namespaces |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.design.type-coverage.param.suppress-paths |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.design.type-coverage.param.threshold |
number | Shorthand for warning and error: expanded in the layer that wrote it, before any merge; each key then merges on its own. Writing it beside one of them in the same layer is refused. |
Not written: the layer below stands. | Refused: a scalar is expected. |
rules.design.type-coverage.property |
map | Merged key by key; a written empty map changes nothing. | The name is judged; the body stays with the layer below. | Changes nothing. |
rules.design.type-coverage.property.error |
number | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.design.type-coverage.property.warning |
number | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.design.type-coverage.property.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.design.type-coverage.property.suppress-namespace-channels |
map by name: a name judged by the section's grammar in the layer that wrote it | Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
rules.design.type-coverage.property.suppress-namespace-channels.<name> |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | The name is judged; the body stays with the layer below. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.design.type-coverage.property.suppress-namespaces |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.design.type-coverage.property.suppress-paths |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.design.type-coverage.property.threshold |
number | Shorthand for warning and error: expanded in the layer that wrote it, before any merge; each key then merges on its own. Writing it beside one of them in the same layer is refused. |
Not written: the layer below stands. | Refused: a scalar is expected. |
rules.design.type-coverage.return |
map | Merged key by key; a written empty map changes nothing. | The name is judged; the body stays with the layer below. | Changes nothing. |
rules.design.type-coverage.return.error |
number | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.design.type-coverage.return.warning |
number | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.design.type-coverage.return.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.design.type-coverage.return.suppress-namespace-channels |
map by name: a name judged by the section's grammar in the layer that wrote it | Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
rules.design.type-coverage.return.suppress-namespace-channels.<name> |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | The name is judged; the body stays with the layer below. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.design.type-coverage.return.suppress-namespaces |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.design.type-coverage.return.suppress-paths |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.design.type-coverage.return.threshold |
number | Shorthand for warning and error: expanded in the layer that wrote it, before any merge; each key then merges on its own. Writing it beside one of them in the same layer is refused. |
Not written: the layer below stands. | Refused: a scalar is expected. |
rules.discovery.unmatched-exclude |
map | Merged key by key; a written empty map changes nothing. | The name is judged; the body stays with the layer below. | Changes nothing. |
rules.discovery.unmatched-exclude.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.discovery.unmatched-exclude.suppress-namespace-channels |
map by name: a name judged by the section's grammar in the layer that wrote it | Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
rules.discovery.unmatched-exclude.suppress-namespace-channels.<name> |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | The name is judged; the body stays with the layer below. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.discovery.unmatched-exclude.suppress-namespaces |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.discovery.unmatched-exclude.suppress-paths |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.duplication.clone |
map | Merged key by key; a written empty map changes nothing. | The name is judged; the body stays with the layer below. | Changes nothing. |
rules.duplication.clone.error |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.duplication.clone.min-lines |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.duplication.clone.min-tokens |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.duplication.clone.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.duplication.clone.suppress-namespace-channels |
map by name: a name judged by the section's grammar in the layer that wrote it | Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
rules.duplication.clone.suppress-namespace-channels.<name> |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | The name is judged; the body stays with the layer below. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.duplication.clone.suppress-namespaces |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.duplication.clone.suppress-paths |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.health.cohesion |
map | Merged key by key; a written empty map changes nothing. | The name is judged; the body stays with the layer below. | Changes nothing. |
rules.health.cohesion.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.health.cohesion.suppress-namespace-channels |
map by name: a name judged by the section's grammar in the layer that wrote it | Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
rules.health.cohesion.suppress-namespace-channels.<name> |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | The name is judged; the body stays with the layer below. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.health.cohesion.suppress-namespaces |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.health.cohesion.suppress-paths |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.health.complexity |
map | Merged key by key; a written empty map changes nothing. | The name is judged; the body stays with the layer below. | Changes nothing. |
rules.health.complexity.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.health.complexity.suppress-namespace-channels |
map by name: a name judged by the section's grammar in the layer that wrote it | Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
rules.health.complexity.suppress-namespace-channels.<name> |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | The name is judged; the body stays with the layer below. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.health.complexity.suppress-namespaces |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.health.complexity.suppress-paths |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.health.coupling |
map | Merged key by key; a written empty map changes nothing. | The name is judged; the body stays with the layer below. | Changes nothing. |
rules.health.coupling.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.health.coupling.suppress-namespace-channels |
map by name: a name judged by the section's grammar in the layer that wrote it | Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
rules.health.coupling.suppress-namespace-channels.<name> |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | The name is judged; the body stays with the layer below. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.health.coupling.suppress-namespaces |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.health.coupling.suppress-paths |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.health.maintainability |
map | Merged key by key; a written empty map changes nothing. | The name is judged; the body stays with the layer below. | Changes nothing. |
rules.health.maintainability.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.health.maintainability.suppress-namespace-channels |
map by name: a name judged by the section's grammar in the layer that wrote it | Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
rules.health.maintainability.suppress-namespace-channels.<name> |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | The name is judged; the body stays with the layer below. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.health.maintainability.suppress-namespaces |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.health.maintainability.suppress-paths |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.health.overall |
map | Merged key by key; a written empty map changes nothing. | The name is judged; the body stays with the layer below. | Changes nothing. |
rules.health.overall.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.health.overall.suppress-namespace-channels |
map by name: a name judged by the section's grammar in the layer that wrote it | Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
rules.health.overall.suppress-namespace-channels.<name> |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | The name is judged; the body stays with the layer below. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.health.overall.suppress-namespaces |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.health.overall.suppress-paths |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.health.typing |
map | Merged key by key; a written empty map changes nothing. | The name is judged; the body stays with the layer below. | Changes nothing. |
rules.health.typing.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.health.typing.suppress-namespace-channels |
map by name: a name judged by the section's grammar in the layer that wrote it | Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
rules.health.typing.suppress-namespace-channels.<name> |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | The name is judged; the body stays with the layer below. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.health.typing.suppress-namespaces |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.health.typing.suppress-paths |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.maintainability.mi |
map | Merged key by key; a written empty map changes nothing. | The name is judged; the body stays with the layer below. | Changes nothing. |
rules.maintainability.mi.error |
number | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.maintainability.mi.exclude-tests |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.maintainability.mi.min-statements |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.maintainability.mi.warning |
number | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.maintainability.mi.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.maintainability.mi.suppress-namespace-channels |
map by name: a name judged by the section's grammar in the layer that wrote it | Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
rules.maintainability.mi.suppress-namespace-channels.<name> |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | The name is judged; the body stays with the layer below. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.maintainability.mi.suppress-namespaces |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.maintainability.mi.suppress-paths |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.maintainability.mi.threshold |
number | Shorthand for warning and error: expanded in the layer that wrote it, before any merge; each key then merges on its own. Writing it beside one of them in the same layer is refused. |
Not written: the layer below stands. | Refused: a scalar is expected. |
rules.security.command-injection |
map | Merged key by key; a written empty map changes nothing. | The name is judged; the body stays with the layer below. | Changes nothing. |
rules.security.command-injection.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.security.command-injection.suppress-namespace-channels |
map by name: a name judged by the section's grammar in the layer that wrote it | Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
rules.security.command-injection.suppress-namespace-channels.<name> |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | The name is judged; the body stays with the layer below. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.security.command-injection.suppress-namespaces |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.security.command-injection.suppress-paths |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.security.hardcoded-credentials |
map | Merged key by key; a written empty map changes nothing. | The name is judged; the body stays with the layer below. | Changes nothing. |
rules.security.hardcoded-credentials.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.security.hardcoded-credentials.suppress-namespace-channels |
map by name: a name judged by the section's grammar in the layer that wrote it | Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
rules.security.hardcoded-credentials.suppress-namespace-channels.<name> |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | The name is judged; the body stays with the layer below. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.security.hardcoded-credentials.suppress-namespaces |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.security.hardcoded-credentials.suppress-paths |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.security.sensitive-parameter |
map | Merged key by key; a written empty map changes nothing. | The name is judged; the body stays with the layer below. | Changes nothing. |
rules.security.sensitive-parameter.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.security.sensitive-parameter.suppress-namespace-channels |
map by name: a name judged by the section's grammar in the layer that wrote it | Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
rules.security.sensitive-parameter.suppress-namespace-channels.<name> |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | The name is judged; the body stays with the layer below. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.security.sensitive-parameter.suppress-namespaces |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.security.sensitive-parameter.suppress-paths |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.security.sql-injection |
map | Merged key by key; a written empty map changes nothing. | The name is judged; the body stays with the layer below. | Changes nothing. |
rules.security.sql-injection.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.security.sql-injection.suppress-namespace-channels |
map by name: a name judged by the section's grammar in the layer that wrote it | Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
rules.security.sql-injection.suppress-namespace-channels.<name> |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | The name is judged; the body stays with the layer below. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.security.sql-injection.suppress-namespaces |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.security.sql-injection.suppress-paths |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.security.xss |
map | Merged key by key; a written empty map changes nothing. | The name is judged; the body stays with the layer below. | Changes nothing. |
rules.security.xss.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.security.xss.suppress-namespace-channels |
map by name: a name judged by the section's grammar in the layer that wrote it | Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
rules.security.xss.suppress-namespace-channels.<name> |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | The name is judged; the body stays with the layer below. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.security.xss.suppress-namespaces |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.security.xss.suppress-paths |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.size.class-count |
map | Merged key by key; a written empty map changes nothing. | The name is judged; the body stays with the layer below. | Changes nothing. |
rules.size.class-count.error |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.size.class-count.warning |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.size.class-count.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.size.class-count.suppress-namespace-channels |
map by name: a name judged by the section's grammar in the layer that wrote it | Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
rules.size.class-count.suppress-namespace-channels.<name> |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | The name is judged; the body stays with the layer below. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.size.class-count.suppress-namespaces |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.size.class-count.suppress-paths |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.size.class-count.threshold |
integer | Shorthand for warning and error: expanded in the layer that wrote it, before any merge; each key then merges on its own. Writing it beside one of them in the same layer is refused. |
Not written: the layer below stands. | Refused: a scalar is expected. |
rules.size.method-count |
map | Merged key by key; a written empty map changes nothing. | The name is judged; the body stays with the layer below. | Changes nothing. |
rules.size.method-count.error |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.size.method-count.warning |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.size.method-count.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.size.method-count.suppress-namespace-channels |
map by name: a name judged by the section's grammar in the layer that wrote it | Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
rules.size.method-count.suppress-namespace-channels.<name> |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | The name is judged; the body stays with the layer below. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.size.method-count.suppress-namespaces |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.size.method-count.suppress-paths |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.size.method-count.threshold |
integer | Shorthand for warning and error: expanded in the layer that wrote it, before any merge; each key then merges on its own. Writing it beside one of them in the same layer is refused. |
Not written: the layer below stands. | Refused: a scalar is expected. |
rules.size.property-count |
map | Merged key by key; a written empty map changes nothing. | The name is judged; the body stays with the layer below. | Changes nothing. |
rules.size.property-count.error |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.size.property-count.exclude-promoted-only |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.size.property-count.exclude-readonly |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.size.property-count.warning |
integer | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.size.property-count.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.size.property-count.suppress-namespace-channels |
map by name: a name judged by the section's grammar in the layer that wrote it | Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
rules.size.property-count.suppress-namespace-channels.<name> |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | The name is judged; the body stays with the layer below. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.size.property-count.suppress-namespaces |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.size.property-count.suppress-paths |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.size.property-count.threshold |
integer | Shorthand for warning and error: expanded in the layer that wrote it, before any merge; each key then merges on its own. Writing it beside one of them in the same layer is refused. |
Not written: the layer below stands. | Refused: a scalar is expected. |
rules.suppression.configuration |
map | Merged key by key; a written empty map changes nothing. | The name is judged; the body stays with the layer below. | Changes nothing. |
rules.suppression.configuration.enabled |
boolean | The last layer that writes the value wins. | Not written: the layer below stands. | Refused: a scalar is expected. |
rules.suppression.configuration.suppress-namespace-channels |
map by name: a name judged by the section's grammar in the layer that wrote it | Merged entry by entry, keyed by name; each entry merges by its own policy. | Not written: the layer below stands. | Changes nothing. |
rules.suppression.configuration.suppress-namespace-channels.<name> |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | The name is judged; the body stays with the layer below. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.suppression.configuration.suppress-namespaces |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
rules.suppression.configuration.suppress-paths |
list (item: map) | The last layer that writes the list replaces it whole; an empty list replaces too. | Not written: the layer below stands. An item written ~ is refused. |
Replaces the list below with an empty one. |
suppress_namespaces |
list (item: map) | Every layer adds its elements; duplicates collapse. | Not written: the layer below stands. An item written ~ is refused. |
Adds nothing. |
suppress_namespaces[].exact |
string | Read from the layer that wrote the list; never merged across layers. | Not written: as if the key were absent. | Refused: a scalar is expected. |
suppress_namespaces[].subtree |
string | Read from the layer that wrote the list; never merged across layers. | Not written: as if the key were absent. | Refused: a scalar is expected. |
suppress_namespaces[].regex |
string | Read from the layer that wrote the list; never merged across layers. | Not written: as if the key were absent. | Refused: a scalar is expected. |
suppress_paths |
list (item: map) | Every layer adds its elements; duplicates collapse. | Not written: the layer below stands. An item written ~ is refused. |
Adds nothing. |
suppress_paths[].exact |
string | Read from the layer that wrote the list; never merged across layers. | Not written: as if the key were absent. | Refused: a scalar is expected. |
suppress_paths[].subtree |
string | Read from the layer that wrote the list; never merged across layers. | Not written: as if the key were absent. | Refused: a scalar is expected. |
suppress_paths[].regex |
string | Read from the layer that wrote the list; never merged across layers. | Not written: as if the key were absent. | Refused: a scalar is expected. |
Configuration Validation¶
Qualimetrix validates your configuration file and reports clear errors for common mistakes.
Unknown keys¶
Any unrecognized key — at the root level or inside a section — produces an error with a suggestion:
Configuration error: Unknown key "parallel.workes" in configuration file "qmx.yaml" (did you mean "workers"?). Accepted keys: workers.
Docs: https://qualimetrix.dev · AI agents: https://qualimetrix.dev/llms.txt
A key is unknown whatever its value, ~ included, and in whichever layer it is
written: a preset's typo is refused like your file's. A key written in a
spelling other than its three accepted ones is refused with the accepted
spelling:
Configuration error: Key "Fail_On" in configuration file "qmx.yaml" is not written in an accepted spelling; write "fail_on" (its snake_case, camelCase and kebab-case spellings are accepted).
Docs: https://qualimetrix.dev · AI agents: https://qualimetrix.dev/llms.txt
The same spelling rule applies to rule-option keys and level segments in
--rule-opt. A wrong-case rule owner suggests the exact registered name. CLI
refusals include the complete authored flag/value expression alongside the
option source.
Type errors¶
Symfony YAML reads unquoted +2 and 2.0 as floats. Integer options refuse
both in the file, --rule-opt and dedicated aliases, name the parsed float and
explain that an integer should be written as 2. File refusals name the path;
CLI refusals also retain the complete authored expression. Quoted "+2" stays
a string. Exponent notation and overflow remain refused by integer options.
If a value has the wrong type, you'll get a clear message instead of silent fallback to defaults:
Configuration error: "cache.enabled" in configuration file "qmx.yaml" must be boolean, got string.
Docs: https://qualimetrix.dev · AI agents: https://qualimetrix.dev/llms.txt
Unknown rule names¶
Misspelled rule names in the rules: section are rejected:
Configuration error: Rule option owner "complexty.ccn" does not match any registered producer rule. Did you mean "complexity.ccn"?
Docs: https://qualimetrix.dev · AI agents: https://qualimetrix.dev/llms.txt
Unknown rule option keys¶
An option key a rule does not have is a configuration error at every depth it can be written at — the run stops with exit code 3 and nothing is analyzed:
Configuration error: Unknown key "rules.complexity.ccn.warning_threshold" in configuration file "qmx.yaml". Accepted keys: callable, class, enabled, suppress-namespace-channels, suppress-namespaces, suppress-paths, threshold.
Docs: https://qualimetrix.dev · AI agents: https://qualimetrix.dev/llms.txt
Inside a level slot the message names the slot, because the allowed set is per level and not per rule:
Configuration error: Unknown key "rules.complexity.ccn.class.warning" in configuration file "qmx.yaml". Accepted keys: enabled, max-error, max-warning, threshold.
Docs: https://qualimetrix.dev · AI agents: https://qualimetrix.dev/llms.txt
--rule-opt rejects the same undeclared keys with exit code 3, naming its own
flag (Source: option --rule-opt.); its wording and hints can differ from YAML.
The key keeps its authored spelling
An unknown key keeps its separators: max_warnign is printed as
"max_warnign", without folding. File refusals name the full authored
key path and file; CLI refusals name the flag. Allowed keys are listed in
the canonical kebab spelling of the declaration.
The shape of a value¶
The two rules below hold for every key in this document — the roots, the
sections, the rules: subtree and the level slots inside it alike. They are not
a property of rule options; rule options are simply where you meet them most
often.
Every key declares the shape its value may take. A value of another shape ends
the run with exit code 3. It is never converted into something usable, and it is
never dropped in favour of the default while the run reports success. Every
source the value arrives from is judged, not only the one that wins: a wrong
format: or cache_dir: in a file is refused even when the command line
overrides it, because a value nobody will use is still a value somebody wrote:
Configuration error: "rules.complexity.ccn.callable.warning" in configuration file "qmx.yaml" must be integer at least 0, got string.
Configuration error: "only_rules" in configuration file "qmx.yaml" must be a list, got a map.
Configuration error: "cache" in configuration file "qmx.yaml" must be a map, got a list.
These are three separate runs, one mistake apiece — a real run stops at its own
first error. Each one's stderr ends with the same documentation pointer line
shown throughout this page (e.g. Docs: https://qualimetrix.dev · AI agents:
https://qualimetrix.dev/llms.txt); it is omitted above so the three messages
can be compared side by side.
The shapes a key can ask for, in the words the refusal uses:
| Shape | Accepts |
|---|---|
| a boolean | true / false |
| a non-negative whole number | 15 or 0 — not 10.5, not "15", not -1 |
| a non-negative number | 15, 10.5 or 0 — not -0.5 |
| a number | any number of either sign (computed-metric thresholds only) |
| a string | any string, the empty one included |
| a non-empty string | a string with at least one non-blank character |
| a list of X | a YAML sequence, every element of shape X |
| a map of X | a YAML mapping you name the keys of, every value of shape X |
| a block of options | a mapping whose own keys another declaration answers for |
Six consequences are worth spelling out, because each of them used to pass unnoticed:
- A quoted number is a string.
warning: "15"is refused where a whole number is declared; writewarning: 15. This is a YAML-only distinction — values that arrive on the command line are text by construction and are converted before their shape is judged, so--rule-opt="size.method-count:threshold=25"and--rule-opt="complexity.ccn:enabled=false"are unaffected. - A whole number is not a fraction — except for the keys named here, which
declare "a non-negative number".
warning: 10.5is refused where a whole number is declared, and most thresholds in this document declare exactly that: a whole number. The keys below declare "a non-negative number" instead, and therefore accept a fraction exactly as written, because each one measures a continuously-valued metric rather than counting something: the maintainability index (maintainability.mi.error/.warning/.threshold), instability (coupling.instability.max-error/.max-warning/.threshold, the same three at theclass.andnamespace.level slots too), distance from the main sequence (coupling.distance.max-distance-error/.max-distance-warning/.threshold), ClassRank (coupling.class-rank.error/.warning/.threshold), type coverage (design.type-coverage.param.error/.warning/.threshold, the same three under.property.and.return.) and the TCC threshold ondesign.god-class.tcc-threshold. This is a property of each key's own declared shape, not of its rule or family as a whole: keys living right beside an accepting one stay whole numbers and refuse a fraction, because they count something instead of measuring it —coupling.distance.min-type-count,coupling.instability.min-afferent(at every level slot) andcoupling.instability.namespace.min-type-countare each a type or file count, not a ratio. - A threshold or a count is never negative. Every numeric option under
rules:is a count or a boundary on a measurement that cannot be negative, and a negative boundary does not tighten a rule, it inverts it:warning: -1onsize.method-countwould report every class. It is refused with the value itself, from the file and from--rule-optalike, and athreshold: -1shorthand is named asthreshold, the key that was written. Zero is accepted. A computed metric'swarning/error/thresholdkeep both signs, because its formula is yours and may well be negative. - A list and a map are not interchangeable.
only_rules: {a: complexity.ccn}andexclude_methods: {a: getName}are refused; writeonly_rules: [complexity.ccn]andexclude_methods: [getName]. The same in the other direction:cache: [dir]is refused, becausecache:is a section of named keys. - Selector lists contain one-entry mappings, not scalar shortcuts. Write
- exact: '2024'for a directory literally named2024; a bare scalar is refused forsuppress_paths,suppress_namespaces,exclude, framework namespaces, and per-rule selector lists alike. - The empty string is a shape of its own. It is refused wherever a non-empty
value is required, on the command line as well:
--fail-on=,--format=,--cache-dir=and--memory-limit=each name what they expected instead of quietly taking the default.
A key written with no value¶
Writing a key and leaving it empty — key: or the explicit YAML null key: ~ —
means the default is taken for that key's own value, at every depth and in every
section, rules: included:
cache: ~ # same as not writing cache:
coupling: ~ # same as not writing coupling:
cache:
dir: ~ # same as not writing dir:
rules:
complexity.ccn:
enabled: ~ # same as not writing enabled:
callable: ~ # same as not writing callable:
That covers the keys inside rules: that choose how a rule is read, not only
those whose value is read. A threshold key selects the shorthand form of a
hierarchical rule — threshold: on complexity.ccn, complexity.cognitive and
complexity.npath; threshold:, warning: or error: on coupling.cbo;
threshold:, max_warning: or max_error: on coupling.instability — and it
is the value written there that selects it. A ~ writes no value, so it
selects nothing and the callable: / class: / namespace: blocks beside it
are read exactly as if the key were not there:
For the same reason threshold: ~ written beside warning: / error: names no
second mode, so there is nothing for it to be mixed with:
rules:
cohesion.lcom:
threshold: ~ # no value, so no mode
warning: 5 # graduated mode, as if threshold: had not been written
Two values are still two modes, and that is still a configuration error:
rules:
cohesion.lcom:
threshold: 3 # Configuration error, exit 3:
warning: 5 # Cannot mix "threshold" with "warning"/"error"
An element of a list is the one place this does not apply, and for a reason:
an element is a value, not a key that was left unwritten, so there is nothing for
it to mean. A ~ element is refused, with its index, in every list outside
rules: and in every list a rule's options declare:
Editor support¶
Qualimetrix ships a JSON Schema of its configuration file, qmx.schema.json.
Point an editor that validates YAML against JSON Schema at it, and while you
write qmx.yaml you get:
- completion of keys, rule names and each rule's options;
- each rule's description as a hint;
- highlighting of shape errors: an unknown key, a value of the wrong type, a number below its minimum, a word outside a fixed list.
The schema checks the shape of one file, not its meaning. qmx stays the
final judge. The editor does not check formulas, selectors, regular
expressions, paths, references to declared architecture layers, constraints
that depend on other values, or anything that depends on how presets and your
file combine. It does catch a shorthand written beside its own target in one
object, such as threshold together with warning. A file the editor accepts can still be refused by qmx check.
The reverse is what the schema is built to avoid: it is generated from the
same declarations qmx reads, and it is tested never to flag a file qmx
accepts — except where the editor's YAML parser reads a value differently
(see Limitations).
Where to get the schema¶
| Source | Use it when |
|---|---|
vendor/qualimetrix/qualimetrix/qmx.schema.json |
Recommended. You installed Qualimetrix with Composer: the file always matches the installed version. |
https://raw.githubusercontent.com/qualimetrix/qualimetrix/vX.Y.Z/qmx.schema.json |
You need a fixed address, for example with the phar, which does not carry the schema. Replace vX.Y.Z with your installed version; the content at this address never changes. |
https://github.com/qualimetrix/qualimetrix/releases/latest/download/qmx.schema.json |
You always run the latest release. This address redirects to the newest release's asset; whether every editor follows the redirect has not been verified. |
Releases published before the schema was introduced have no file at these addresses.
VS Code¶
Install the YAML extension by Red Hat and make this the first line of
qmx.yaml, with the address or a path relative to the file:
qmx.yaml.example already starts with such a line. The path is resolved
relative to the config file, so it works when the file lies in the project root
next to vendor/.
An imported file needs its own modeline, with the path written relative to that
file (# yaml-language-server: $schema=../vendor/qualimetrix/qualimetrix/qmx.schema.json
for config/a.yaml).
PhpStorm¶
Open Settings → Languages & Frameworks → Schemas and DTDs → JSON Schema
Mappings, add a mapping, choose vendor/qualimetrix/qualimetrix/qmx.schema.json
(or one of the addresses above) as the schema, and add qmx.yaml, qmx.yml,
qmx.dist.yaml and qmx.dist.yml as files mapped to it. A config file with another name, passed through
--config or a preset, is bound the same way: add its name or path to the
mapping (or put the modeline from the VS Code section on its first line). The
same goes for a file the root imports: the editor binds a schema to a file by
its name, not by the file that imports it, so config/*.yaml needs its own
mapping or a modeline. If
the dialog asks for a schema version, choose JSON Schema version 7.
Limitations¶
- Different YAML parsers.
qmxreads YAML with Symfony YAML; editors use their own parser (the Red Hat extension follows YAML 1.2). A scalar the two type differently —1_000,0755, a date — can be accepted by one and flagged by the other. Where they disagree on such a value,qmx checkis right. - Match the versions. Use the schema of the
qmxversion you run. A newer release may remove keys your version still accepts, and an older schema does not know keys added since.
What's Next?¶
See the CLI Options reference for the complete list of command-line options.
Declared rule forms and prepared execution¶
rules is a declared document section. Every registered producer names its
accepted root options, level slots, value forms and threshold bands. Each
writing layer is checked before merging, even when a later layer overrides it.
There is no permissive raw option bag or second constructor-reflected vocabulary.
Unknown owners, retired keys and invalid spellings refuse with their authored
producer/key path and source before Discovery.
A rule boolean writes only enabled. true preserves thresholds, exclusions and
each level's own switch; false disables every level. A rule or level {} writes nothing,
and ~ leaves the lower value. No empty-body reset restores defaults. To restore
a default over an earlier layer, write its value explicitly. A level requires
its own declared map, such as class: {enabled: false}, rather than a rule boolean.
Shorthands expand in their own layer. Writing threshold and one of its band
halves in the same layer refuses. A top hierarchical shorthand conflicts only with
an explicit write to the same expanded leaf; independent children coexist, and across layers
expanded leaves merge. Complexity's top shorthand changes callable only and
preserves class; CBO and instability spread their flat bands to class and
namespace. A written NPath class band activates without a redundant true switch.
Explicit class.enabled: false still wins. Numeric defaults and formulas do not
change.
After merging, owners build typed options for every producer, including inactive ones, and validate effective warning/error ordering against written and default halves. An invalid band reports the real contributing sources. Selection is then concluded with option activity before any runtime state is published. A failed preflight leaves no ready snapshot and publishes no partial producer options.
enabled: true is an authored exact enable, not disposable decoration: it can
cancel a lower disable and must be admitted by the effective only filter. Keep
it when enabling is intended. A mode of ignore remains inactive: explicitly
enabling that inactive producer refuses, while enabled:false with a reportable
mode is lawful. See Rule selection for the
layer/specificity, empty-selection and channel-level rules.
Selection and built options use the same immutable invocation channel snapshot, including authored computed definitions. Producer metadata and finding channels are different sets. A producer may have several channels; dynamic channel names and declared levels are not a hardcoded default catalogue.