Architecture analysis rules
A finding records ruleId, category, severity, file, line, evidence, and recommendation. Open the named file and verify the intended design before editing it. NKLattice reports static source signals; it does not prove that an import or export is harmful.
Current built-in rules
Section titled “Current built-in rules”| Rule ID | Default level | Signal and first review step |
|---|---|---|
module-cycle |
Error | Local runtime imports form a strongly connected group. Inspect dependency direction and move a shared contract to a lower layer if needed. |
high-fan-in |
Warning | More than 8 runtime local import edges enter a module. Review its stability before changing its public interface. |
high-fan-out |
Warning | More than 10 runtime local import edges leave a module. Look for unrelated responsibilities. |
deep-dependency-chain |
Warning | A runtime local import chain exceeds 6 hops. Inspect whether intermediate layers carry useful boundaries. |
orphan-module |
Info | A non-route module has no resolved local incoming or outgoing edges in a project with multiple modules. Confirm whether it is an entry point. |
duplicate-import |
Warning | A module repeats a runtime import specifier. Combine imports if both declarations are needed. |
unused-export |
Info | An exported value in an imported non-route module has no resolved local importer. Check package and runtime consumers before removing it. |
large-component |
Warning | A file with a recognized JSX component exceeds 200 lines. Extract only a cohesive responsibility. |
deep-jsx |
Warning | JSX nesting is deeper than 6. Consider a named child component when it clarifies intent. |
high-complexity |
Warning | Approximate branch complexity exceeds 15. Review the branches and split focused logic where useful. |
These are ten rule IDs, with fan-in and fan-out counted separately. A configured module boundary contributes another finding under its own policy ID and chosen severity. Architecture policy explains the thresholds and custom boundaries.
How evidence is calculated
Section titled “How evidence is calculated”The scanner includes JS/TS source files under the analyzed root and resolves static import declarations and re-exports to other scanned files. It uses the root tsconfig.json when available. External packages and unresolved files do not become local graph edges. Declaration-level import type and export type are excluded from runtime cycles, fan-in/out, and boundary checks.
The cycle rule identifies a strongly connected group; the listed module order is not an exact execution path. Fan counts are edge counts, so repeated imports can increase them. A line number of 1 on a file-level metric points to the file, while import-specific rules can point to the import line.
The complexity number starts at 1 and increments for syntax such as if, loops, catch, conditional expressions, case blocks, and && / || expressions. It is an approximation, not a full complexity audit.
Where false positives arise
Section titled “Where false positives arise”- An
orphan-modulecan be an app entry point, a test entry point, or a file used outside local static imports. unused-exportchecks only resolved local importers and is skipped for recognized Nextapp/andpages/route files. It cannot see every external consumer, dynamic import, or runtime reflection.- The parser does not build the project or follow every
require()orimport()expression. A missing graph edge may mean a source pattern was not covered. - A
large-componentfinding applies to the whole file when it contains a top-level capitalized JSX function or variable. It does not measure one component body in isolation.
When a finding is valid but the chosen limit does not fit the team, adjust the threshold or a boundary rule in a reviewed .nklattice.json. Weight changes affect the score, not whether the finding appears.