Planned rule catalog¶
!!! info "Not implemented"
This catalog describes 158 rules that are planned, not shipped. Version
0.1.0a1 implements 19 rules. Nothing on these pages
runs today. See Reconciliation for how the shipped
rules map onto this catalog.
This catalog describes the designed rule set, one page per domain: SRP, KISS, CQS, POLA, COUP, CONTRACT, STATE, LIFE, FAIL, CONC, IDIOM, NIT, and DRY. This page explains the shared model before you go read any of the domain pages.
Each rule carries an ID, a domain, and a few pieces of metadata that decide whether it fires and whether it counts toward a score.
Rule model¶
A rule has independent identity, domain, claim, concern, certainty, emission, and scoring metadata:
- ID is a stable domain-prefixed selector such as
STATE001; severity never appears in the ID. - Domain controls shared analysis configuration and its score contribution.
- Claim is
defect,risk, ordesignand describes what the rule asserts. - Concern is
hazard,review, oradvisoryand controls reporting/failure policy independently of domain. - Default is
on,hint,evidence,observe, oroff. weight = 0reports findings but removes their score contribution; it never disables a rule.
| Default | Behavior | Score |
|---|---|---|
on |
Emitted by the default profile when its concern is reported | yes |
hint |
Emitted by the review profile; intentionally unweighted | no |
evidence |
Hidden unless cited by a finding or requested with --show-evidence |
no |
observe |
Requires opt-in runtime observation and never proves absence | no by default |
off |
Experimental; enabled only by explicit domain/rule selection | no |
Domains and default weights¶
| Domain | Purpose | Weight | Default selection |
|---|---|---|---|
SRP |
Cohesion, responsibility concentration, and reasons to change. | 1.15 | on |
KISS |
Accidental complexity, control-flow pressure, and unnecessary indirection. | 1.00 | on |
CQS |
Separation of observation, mutation, and commands. | 1.00 | on |
POLA |
Behavior that contradicts names, syntax, or ordinary API expectations. | 1.00 | on |
COUP |
Dependency visibility, dependency surface, and change coupling. | 1.00 | on |
CONTRACT |
Explicit input, output, type, and behavioral contracts. | 0.90 | on |
STATE |
State ownership, invariants, transitions, and representable state space. | 1.25 | on |
LIFE |
Construction, resource ownership, cleanup, and temporal lifecycle. | 1.15 | on |
FAIL |
Failure boundaries, recovery, retries, rollback, and partial effects. | 1.25 | on |
CONC |
Task, thread, process, lock, and concurrent-state ownership. | 1.25 | on |
IDIOM |
Python-specific semantics whose equivalent rules differ by language. | 0.90 | on |
NIT |
Deliberately opinionated reviewer hints; always unweighted by default. | 0.00 | review only |
DRY |
Duplicated knowledge and drift risk; experimental and unweighted. | 0.00 | off |
SOLID, CUPID, GRASP, and similar concepts are principle tags or documented selector groups, not ID domains; YAGNI is not a static domain because future need cannot be inferred from one source snapshot, and DRY stays experimental until it detects duplicated knowledge rather than similar syntax.
Profiles and selection¶
[tool.humansays]
profile = "default"
extend-select = ["NIT", "IDIOM008"]
ignore = ["NIT002"]
[tool.humansays.concerns]
report = ["hazard", "review"]
fail-on = ["hazard"]
[tool.humansays.domains.STATE]
weight = 1.25
min_boolean_dimensions = 3
min_nullable_dimensions = 3
min_state_product = 8
[tool.humansays.domains.NIT]
weight = 0.0
[tool.humansays.per-file-ignores]
"tests/**" = ["DRY"]
"migrations/**" = ["NIT", "DRY"]
Selection order is profile → select replacement when present → extend-select → ignore → per-file ignores; ignores always win, and there is no @ selector syntax.
Domain thresholds¶
| Domain | Default knobs |
|---|---|
SRP |
minimum_lines = 40, minimum_independent_dimensions = 3, max_public_methods = 10, max_mutable_attributes = 8 |
KISS |
max_function_lines = 60, max_nesting = 4, max_branches = 12, max_loop_statements = 12, max_condition_operands = 3 |
COUP |
max_operation_dependencies = 5, data_clump_size = 3, data_clump_occurrences = 2 |
CONTRACT |
max_operation_arguments = 5, max_positional_record_fields = 2, max_dataclass_positional_fields = 3, max_generic_parameters = 2 |
STATE |
min_boolean_dimensions = 3, min_nullable_dimensions = 3, min_state_product = 8, max_sentinels = 3 |
FAIL |
max_exception_handlers = 6, require_bounded_retry = true |
NIT |
weight = 0.0; no rule-specific scoring knobs |
DRY |
weight = 0.0, minimum_occurrences = 3; experimental |
Exact IDs control only selection and suppression; shared knobs live under the domain because per-rule configuration would make the surface impossible to audit.
Every message template is one sentence and must substitute measured values when available; state-product messages must report the actual representable-state count.
Domains¶
Provenance¶
The migration provenance tables are not published. They live in the
repository's .migration/ directory as evidence-registry.md,
externalized.md, prototype-crosswalk.md, and accounting.md.