Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Rule cards

Every core rule is a refactoring-inspection claim, not a defect prediction, health score, generic priority, or automatic architecture inference. All cards inherit these non-goals. A finding’s identity comes from its typed subject and the rule-specific semantic anchor, not prose, ordering, checkout location, or line numbers. Measurement, threshold, evidence-set, or witness changes update the finding’s content fingerprint.

All rules below are currently preview, default_enabled = false, validation_basis = fixture, semantic version 1.0.0, and ineligible for enforcement. A language can become stable only through the audited calibration protocol in calibration/README.md; other languages remain preview. The CLI’s starter configuration explicitly enables four of these rules as advisories; this does not change their manifest maturity or default-enabled state.

RuleClaim / inspection questionCapabilityPositive and negative fixturesLegitimate exceptions
reforge.codebase.large_fileA file exceeds the configured line boundary; is responsibility ownership too broad?file inventoryover/under thresholdgenerated facades, declarative tables
reforge.codebase.large_directoryA directory owns more direct source files than configured.directory inventorywide/narrow directoriesflat packages with explicit ownership
reforge.codebase.comment_hygieneAn ordinary comment has an empty, repeated, template or possible-code review hint; is it still useful?Supported analyzer language commentshint/protected/string fixtures; preview/apply and stale-plan testsintentional repetition, examples, explanations without recognized protection markers
reforge.codebase.debt_markerA source comment explicitly declares TODO/FIXME debt.source textcomment/non-comment markersgenerated or externally tracked markers
reforge.codebase.similar_functionsMultiple normalized bodies are structurally similar enough to inspect together.parsed syntax similaritycloned/distinct bodiesprotocol implementations, tests
reforge.codebase.long_functionA declared function exceeds the configured line span.syntax and symbolslong/short functionsgenerated parsers, linear tables
reforge.codebase.complex_functionEstimated branch complexity exceeds the configured bound.parsed control syntaxbranch-heavy/linear functionsexplicit state machines
reforge.codebase.deep_nestingLexical control nesting exceeds the configured bound.parsed control syntaxnested/guard-clause fixturesrecursive walkers
reforge.codebase.many_parametersA function declares more parameters than configured.symbol parametersover/under arityserialization and FFI boundaries
reforge.codebase.large_typeA type exceeds configured span or member count.type observationslarge/small declarationsgenerated schemas
reforge.codebase.large_public_surfaceA file exports more items than configured.export syntaxbroad/narrow modulesdeliberate prelude or facade
reforge.codebase.import_heavy_fileA file imports more dependencies than configured.import syntaxover/under import countcomposition roots
reforge.codebase.function_proliferationA file combines high function count, density, and small-function ratio.function inventorydense/sparse filesparser combinators
reforge.codebase.duplicate_fileMultiple files contain identical decoded source above the configured line threshold.decoded source inventoryidentical/different files, thresholds, stable copy locationsintentional templates, snapshots, independent delivery assets
reforge.codebase.redefined_nameA Python name has multiple undecorated definitions among direct children of one module, class, or function scope.Python definition syntaxrepeated definitions/distinct scopes, decorators, conditionalsintentional rebinding; captured earlier definitions
reforge.codebase.low_module_cohesionMultiple exact call-connected function clusters suggest separable module responsibilities.module function call graphmonolith/split modulesrouters, registries, controllers
reforge.codebase.unused_functionA private symbol has no supported project-local reference.symbols and referencesreferenced/unreferenced symbolsreflection, callbacks, macros
reforge.codebase.repeated_literalA literal repeats enough to inspect ownership.parsed literalsrepeated/unique literalsprotocol constants and test data
reforge.codebase.repeated_error_patternError-handling syntax repeats across sites.parsed error syntaxrepeated/distinct handlersintentionally local recovery
reforge.codebase.test_duplicationTest setup patterns repeat across tests.parsed test syntaxduplicated/distinct setupreadability-focused local setup
reforge.codebase.happy_path_only_testsA test group has assertions without detected failure/boundary cases.test syntaxpositive-only/mixed testsbehavior proven elsewhere
reforge.codebase.file_naming_driftA directory mixes file naming conventions.path inventorymixed/uniform nameslanguage-required names
reforge.codebase.directory_driftDirectory concepts exceed the configured ownership bound.paths and syntax namesmixed/cohesive fixturesplugin registries
reforge.codebase.data_clumpThe same parameter combination recurs across functions.symbol parametersrecurring/distinct setsstable protocol signatures
reforge.codebase.parallel_implementationSimilarly named capabilities are implemented independently.symbol conceptsparallel/unrelated namesplatform-specific variants
reforge.codebase.shadowed_abstractionLocal helpers overlap a shared abstraction.symbols and conceptslocal/shared overlapdeliberate compatibility shims
reforge.codebase.duplicate_type_shapeType field shapes substantially overlap.type fieldsoverlapping/distinct shapesboundary DTOs
reforge.codebase.config_key_driftConfiguration-like keys repeat or drift.literal conceptsrepeated/distinct keysexternal protocol keys
reforge.codebase.fixture_factory_driftTest fixture/factory concepts repeat independently.test symbolsduplicated/distinct factoriesdomain-specific builders
reforge.codebase.generic_bucket_driftA generic directory or file accumulates unrelated concepts.typed file/directory subjectsgeneric/cohesive bucketsintentionally tiny shared kernels
reforge.codebase.adapter_boundary_bypassNaming/syntax suggests direct access around an adapter.heuristic conceptsbypass/non-bypass fixturesmigration and bootstrap code
reforge.codebase.stale_compatibility_pathCompatibility markers lack an explicit retirement boundary.parsed compatibility syntaxstale/owned pathssupported long-term compatibility
reforge.codebase.dependency_cycleResolved project-local dependencies form a cycle.dependency graphcyclic/acyclic graphsmutually recursive generated modules
reforge.codebase.dependency_hubA file has unusually broad/deep resolved dependency topology.dependency graphhub/leaf graphscomposition roots and public facades
reforge.dataflow.adapter_flow_bypassAn exact, value-preserving path violates a complete single-language adapter policy.exact local/interprocedural flowexact bypass/conforming and unsupported fixturesexplicit exemptions
reforge.dataflow.excessive_relayAn exact path contains configured forwarding depth; inspect ownership only.exact direct-call flowlong/short relay pathspipelines, middleware, telemetry
reforge.dataflow.flow_fan_outOne exact source reaches many supported sinks/modules.exact direct-call flowfan-out/narrow pathsorchestrators and event distribution

Similarity, literal, generic-bucket, unused-function, adapter, relay, and fan-out heuristics remain preview/off until each language independently meets the calibration gates. Self-scan is regression data only and cannot promote a rule or select a threshold.

Python redefined names

Enable reforge.codebase.redefined_name explicitly under [rules].enable. It is a preview advisory and does not fail policy gates. Each finding includes all definition locations and a definition count. Tests are included unless scope.exclude-tests is enabled.

The rule compares direct definitions within a lexical scope, including async functions and classes. It skips names with decorated definitions (including property accessors and overload declarations), and does not traverse conditional, loop, or exception blocks. Dynamic assignments and import rebinding are outside its scope. A finding requests review of replacement bindings; it does not prove the earlier implementation is unused or authorize deleting it.

For example, two direct def check() declarations at lines 1 and 4 produce reforge.codebase.redefined_name with both locations and a group-size measurement of 2.

Python module cohesion and source copies

reforge.codebase.low_module_cohesion now also supports direct, undecorated Python module functions. It connects bare-name calls only when the callee is unambiguous, the names share a responsibility concept, and parameters, local bindings, imports, or module reassignments do not shadow that callee. Methods, decorated functions, nested scopes, comprehensions, and dynamic dispatch are outside this conservative model. Findings list the members of each inferred cluster; they are review evidence rather than an automatic module split.

reforge.codebase.duplicate_file groups whole files with identical decoded contents. The default minimum is 20 total lines; set codebase.min-duplicate-file-lines to a positive integer to adjust it. Empty files are ignored. Encoding markers are decoded before comparison, but comments, whitespace, and line endings are otherwise significant. Tests and generated sources follow the normal scan filters. This rule does not require successful syntax parsing. Template and case snapshots may be deliberate; review ownership and establish a baseline or an explicit, reasoned suppression before gating.