@afokapu/atdd-bun 0.10.39 → 0.10.40

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -26,12 +26,33 @@ content:
26
26
  normative_text: |
27
27
  The obligation and its arithmetic are unchanged from the Python realization — deliberately, because a repo that switches providers must not see its numbers move. What changes is only WHO runs the count.
28
28
  Cyclomatic complexity is a proxy for how many test cases a function needs before its behaviour is pinned. Above roughly ten paths, complete coverage stops being written, and the untested paths are where defects settle.
29
+ Treat the score as a sensor for too many independent decisions inside one responsibility, not as an invitation to disguise branching. A useful refactor makes the decision structure easier to name, test, and reason about; moving the same decision tree behind another call or encoding it opaquely only hides the signal.
29
30
  fix_hint: |
30
- Reduce the branching of the flagged function:
31
+ Diagnose which decisions belong together before reducing the score.
31
32
 
32
- * extract nested decision blocks into named helpers,
33
- * replace long if / else-if ladders or switch arms with a dispatch map,
34
- * collapse compound &&/||/?? conditions into well-named predicates.
33
+ Diagnose:
34
+ * group branches by the policy or responsibility they implement,
35
+ * distinguish validation and guard conditions from the core operation,
36
+ * identify repeated compound conditions that represent a domain predicate.
37
+
38
+ Prefer:
39
+ * extract a coherent decision or policy into an intention-revealing function,
40
+ * replace repeated compound conditions with well-named predicates,
41
+ * use a dispatch table or strategy only when the domain genuinely represents a stable mapping from a key to behavior,
42
+ * keep the caller's control flow readable enough to reveal the important choices.
43
+
44
+ Avoid:
45
+ * moving the same branch tree unchanged into a generically named helper,
46
+ * replacing readable control flow with indirect data structures solely to lower the measured score,
47
+ * scattering one policy across many tiny functions whose interaction is harder to follow than the original,
48
+ * changing boolean semantics, branch order, or fallback behavior while refactoring.
49
+
50
+ Verify:
51
+ * existing behavior and path-focused tests remain green,
52
+ * the triggering complexity violation is gone,
53
+ * extracted code does not create a new nesting, duplication, or length violation,
54
+ * the resulting decision boundaries correspond to meaningful responsibilities,
55
+ * the refactor introduces no new ATDD Bun violations.
35
56
  exceptions:
36
57
  - Functions with fewer than 3 code lines are not scored.
37
58
  - Test files and vendored/build directories are outside the scan.
@@ -23,8 +23,33 @@ content:
23
23
  normative_text: |
24
24
  Length is the crudest of the three per-function metrics and the hardest to argue with: a function longer than a screen cannot be read as one unit, so it is read in fragments and its invariants are reconstructed from memory each time.
25
25
  It catches a different fault from complexity. A long function may be perfectly linear — fifty sequential assignments score 1 on cyclomatic complexity — and still be doing five things that wanted names.
26
+ Treat the threshold as a sensor for weak cohesion or multiple responsibilities, not as the design objective. A successful refactor identifies a responsibility or cohesive operation that deserves its own name and boundary. Merely moving enough contiguous lines elsewhere to cross the threshold removes the signal without repairing the smell.
26
27
  fix_hint: |
27
- Split the function along its internal seams. The comment lines inside a long function usually mark them exactly: each block a comment introduces is a candidate helper, and its comment is the helper's name.
28
+ Diagnose the design problem before changing the code.
29
+
30
+ Diagnose:
31
+ * identify the distinct responsibilities, stages, or invariants managed by the function,
32
+ * look for semantic seams: blocks that can be described by one intention-revealing name,
33
+ * identify the data each candidate responsibility actually needs.
34
+
35
+ Prefer:
36
+ * extract one cohesive responsibility at a time,
37
+ * name helpers after the purpose they perform rather than the mechanics they contain,
38
+ * keep related state and decisions together,
39
+ * leave the original function as a readable description of the top-level flow.
40
+
41
+ Avoid:
42
+ * splitting at an arbitrary line boundary merely to satisfy the 50-line limit,
43
+ * helpers such as `part1`, `processRest`, `buildLinesAndTotal`, or equivalent names that expose extraction mechanics rather than responsibility,
44
+ * moving a long or complex block unchanged into another function,
45
+ * introducing a generalized abstraction unrelated to the responsibility being extracted.
46
+
47
+ Verify:
48
+ * existing behavior and tests remain green,
49
+ * the triggering length violation is gone,
50
+ * extracted functions satisfy the applicable complexity and nesting conventions,
51
+ * the resulting names and boundaries make the responsibilities easier to understand,
52
+ * the refactor introduces no new ATDD Bun violations.
28
53
  exceptions:
29
54
  - Blank lines and comment lines are not counted.
30
55
  - Test files and vendored/build directories are outside the scan.
@@ -24,12 +24,32 @@ content:
24
24
  normative_text: |
25
25
  Nesting is the metric readers feel most directly: at depth five a reader must hold five simultaneous conditions to know whether a line executes, which is past what working memory does reliably.
26
26
  It is also the most mechanically fixable — a guard clause or an extracted helper usually removes a level without changing behaviour, which is why the threshold is enforced rather than advised.
27
+ Treat excessive depth as a sensor for too much conditional context being carried at once. The objective is to make the execution conditions easier to understand, not merely to remove braces or encode the same nesting in expressions the metric counts differently.
27
28
  fix_hint: |
28
- Flatten the control flow:
29
+ Flatten the control flow by removing unnecessary conditional context.
29
30
 
30
- * invert conditions into early-return guard clauses,
31
- * extract the innermost block into its own function,
32
- * replace a nested loop with a single pass over a prepared collection.
31
+ Diagnose:
32
+ * identify conditions that reject work early and can become guards,
33
+ * identify an inner block that performs one cohesive operation,
34
+ * identify nested iteration that can be expressed as preparation followed by one clear pass.
35
+
36
+ Prefer:
37
+ * invert conditions into early-return guard clauses when doing so preserves cleanup, error, and ordering semantics,
38
+ * extract a cohesive inner operation into a named function with a small, meaningful input,
39
+ * prepare or filter a collection before iterating when that makes the algorithm clearer.
40
+
41
+ Avoid:
42
+ * converting statements into clever boolean or ternary expressions solely to evade the depth count,
43
+ * extracting an inner block that requires a long parameter list or still depends on the caller's hidden conditional context,
44
+ * duplicating cleanup, logging, or error handling across new guard clauses,
45
+ * changing evaluation order or exception behavior while flattening the function.
46
+
47
+ Verify:
48
+ * existing behavior and tests remain green, including error and boundary paths,
49
+ * the triggering nesting violation is gone,
50
+ * the flattened flow reads with fewer simultaneous preconditions,
51
+ * extracted functions satisfy the applicable length and complexity conventions,
52
+ * the refactor introduces no new ATDD Bun violations.
33
53
  exceptions:
34
54
  - Functions with fewer than 3 code lines are not scored.
35
55
  - Comment lines are ignored when measuring brace balance.
@@ -28,8 +28,32 @@ content:
28
28
  This rule is MORE ACCURATE than its Python sibling, and the difference is worth stating because it is the one place the port is not a transcription.
29
29
  The Python detector reads imports with five regexes — the best a Python process can do without a TypeScript parser. A regex cannot distinguish `import type { T } from "./t"` from a value import, so a module whose only referrer is a TYPE import is counted as reachable. But a type-only import is erased at compile time and creates no runtime edge, so that module is dead and the regex reports it alive.
30
30
  Bun ships a real TypeScript parser in-process, which returns the actual import records and omits type-only ones. Same obligation, measured correctly — and available only because the runtime is Bun. Verified on a fixture where the Python detector finds one dead file and this one finds two.
31
+ Treat an unreachable file as a sensor for unclear ownership or incomplete integration, not as a request to manufacture an import edge. A meaningful repair either removes code that has no runtime responsibility or connects code through the module that genuinely owns and uses it.
31
32
  fix_hint: |
32
- Either wire the file into the graph — import it from the module that should own it — or delete it. A file reachable only through a type import is a types module whose values have already been removed; move the type into the module that uses it.
33
+ Decide first whether the reported file should exist at runtime.
34
+
35
+ Diagnose:
36
+ * identify the responsibility the file claims to own,
37
+ * find the module that would naturally call or import it if that responsibility is required,
38
+ * determine whether the file is obsolete, incompletely integrated, or only carrying types.
39
+
40
+ Prefer:
41
+ * delete code that is genuinely unused,
42
+ * wire required runtime behavior through the module that owns that behavior,
43
+ * move a type into the module that uses it when the remaining file has no runtime values.
44
+
45
+ Avoid:
46
+ * adding a dummy import, barrel export, or other synthetic edge solely to make the file reachable,
47
+ * introducing a side-effect import unless the side effect is itself required runtime behavior,
48
+ * renaming or relocating a file merely to exploit structural-root detection,
49
+ * preserving obsolete code "just in case" instead of removing it.
50
+
51
+ Verify:
52
+ * existing behavior and tests remain green,
53
+ * any new import represents a real runtime dependency,
54
+ * deleted code has no required caller or entry point,
55
+ * the reachability finding is gone without creating a new architecture or dependency-flow violation,
56
+ * the refactor introduces no new ATDD Bun violations.
33
57
  exceptions:
34
58
  - "`index.ts` / `index.tsx` are structural (like `__init__.py`) and are never reported."
35
59
  - Test files are entrypoints, not dead code, and are excluded.
@@ -26,8 +26,32 @@ content:
26
26
  normative_text: |
27
27
  Normalization is what makes the rule useful: because identifiers are folded, renaming a variable does not hide a duplicate, so the fingerprint tracks STRUCTURE rather than text.
28
28
  The intra-layer restriction is equally deliberate. The same shape appearing in `domain/` and in `presentation/` is usually two different obligations that happen to look alike, and merging them couples layers that should move independently. Twice inside one layer is the shape that genuinely wanted extracting.
29
+ Treat a duplicate fingerprint as a sensor that two sites may share one responsibility or change reason. The goal is not to make the fingerprints differ; it is to decide whether the two fragments represent one concept that should be owned once or two concepts whose real semantic differences should remain independent.
29
30
  fix_hint: |
30
- Extract the duplicated fragment into a shared function within that layer and call it from both sites. If the two copies are drifting apart on purpose, they are not duplicates — make the difference explicit so the normalized fingerprints stop matching.
31
+ Compare the duplicated sites semantically before extracting anything.
32
+
33
+ Diagnose:
34
+ * determine whether both fragments implement the same responsibility and should change for the same reason,
35
+ * identify the smallest stable behavior they genuinely share,
36
+ * check that the shared behavior belongs inside the same architectural layer.
37
+
38
+ Prefer:
39
+ * extract a focused function or module within that layer when both sites represent one concept,
40
+ * give the shared behavior a domain- or responsibility-revealing name,
41
+ * when the sites represent different responsibilities, preserve their independence and express any real semantic differences directly.
42
+
43
+ Avoid:
44
+ * renaming identifiers, changing literals, reordering harmless statements, or making other cosmetic edits solely to defeat normalization,
45
+ * creating a cross-layer abstraction just because two layers contain similar-shaped code,
46
+ * extracting a highly parameterized generic helper that obscures the two callers' intent,
47
+ * forcing distinct responsibilities into one abstraction merely to remove the finding.
48
+
49
+ Verify:
50
+ * existing behavior and tests remain green,
51
+ * the duplicate is removed because ownership became clearer or because genuine semantic differences are now explicit,
52
+ * dependency direction and layer boundaries remain valid,
53
+ * the extracted abstraction has one coherent reason to change,
54
+ * the refactor introduces no new ATDD Bun violations.
31
55
  exceptions:
32
56
  - Test, spec, and `.d.ts` files are excluded, as are `index.ts` barrels and `__tests__` directories.
33
57
  - Trivial lines (bare braces, closing punctuation) are not counted toward the 7.
@@ -23,8 +23,32 @@ content:
23
23
  normative_text: |
24
24
  A ratio is a blunt instrument for a quality that is not quantitative, and it is used here for one narrow reason: a file with NO comments at all is common and is almost always a file whose non-obvious decisions were never written down. Ten percent is low enough that any file with a real header and a few explanatory lines clears it.
25
25
  The rule cannot tell a good comment from a bad one. It is a floor against absence, not a measure of quality, and it should not be read as encouragement to restate code in prose.
26
+ Treat the ratio as a sensor for missing design context, not as a prose quota. A successful repair leaves future readers with information the code itself cannot communicate; filler text that merely increases the numerator satisfies the arithmetic while making the source worse.
26
27
  fix_hint: |
27
- Explain the decisions the code cannot state: why this approach over the obvious one, what invariant the block maintains, which upstream constraint forces the shape. In a Bun + htmx file the GREEN header already contributes several lines toward the ratio.
28
+ Find the decisions and constraints that are currently invisible to a reader.
29
+
30
+ Diagnose:
31
+ * identify why the module exists and which responsibility it owns,
32
+ * identify non-obvious invariants, upstream constraints, compatibility choices, or failure semantics,
33
+ * identify places where the obvious implementation was intentionally not chosen.
34
+
35
+ Prefer:
36
+ * document why a design choice exists, what invariant a block preserves, or which external constraint forces the shape,
37
+ * use a concise module or GREEN header when it communicates real purpose and runtime context,
38
+ * place explanation next to the decision it clarifies.
39
+
40
+ Avoid:
41
+ * comments that simply restate the next line of code,
42
+ * filler, generated prose, repeated headings, or artificially split comment lines added to raise the ratio,
43
+ * commenting out dead code instead of deleting it,
44
+ * changing otherwise cohesive code solely to manipulate the denominator.
45
+
46
+ Verify:
47
+ * every added comment conveys information not already obvious from the code,
48
+ * stale or misleading comments are not introduced,
49
+ * the comment-ratio finding is gone,
50
+ * behavior remains unchanged and tests stay green,
51
+ * the refactor introduces no new ATDD Bun violations.
28
52
  exceptions:
29
53
  - Blank lines are excluded from both numerator and denominator.
30
54
  - Continuation lines beginning `*` inside a block comment count as comment lines.
@@ -26,8 +26,32 @@ content:
26
26
  normative_text: |
27
27
  MI is a composite, and that is the point: a file can pass every per-function threshold and still be unmaintainable through sheer accumulated size and operator density. MI is the only rule here that judges the FILE rather than its parts.
28
28
  It is an approximation and is treated as one — the threshold of 20 is set low enough that a score below it indicates a file nobody should be asked to modify, not a file that is merely imperfect.
29
+ Treat a low score as a sensor for accumulated responsibilities and information density at file scope. Because MI combines size, branching, operator density, and comments, optimizing one term mechanically can improve the number without making the module easier to change; the repair should improve cohesion and ownership first.
29
30
  fix_hint: |
30
- Split the file. MI falls fastest with the log of line count, so extracting a cohesive half into its own module raises both halves at once. Adding comments also raises the score, but comment density is a weaker term than size and should not be used as the remedy.
31
+ Diagnose why the file has accumulated too much responsibility before optimizing the score.
32
+
33
+ Diagnose:
34
+ * identify cohesive responsibilities that change for different reasons,
35
+ * identify large decision-heavy regions and repeated logic that dominate the file,
36
+ * identify whether missing design context contributes to the file being hard to modify.
37
+
38
+ Prefer:
39
+ * extract a cohesive responsibility into its own module with a clear ownership boundary,
40
+ * simplify genuinely complex or duplicated logic as part of that extraction,
41
+ * add comments only where they explain real decisions or invariants.
42
+
43
+ Avoid:
44
+ * adding filler comments merely to improve the formula's comment term,
45
+ * splitting a file at an arbitrary line boundary or into tiny fragments solely to reduce LOC,
46
+ * moving complexity unchanged into a sibling module,
47
+ * introducing a generalized abstraction unrelated to the responsibilities already present.
48
+
49
+ Verify:
50
+ * existing behavior and tests remain green,
51
+ * the resulting modules each have a coherent reason to change,
52
+ * the triggering MI finding is gone without creating length, complexity, duplication, or dependency-flow violations,
53
+ * dependency direction remains consistent with the existing architecture,
54
+ * the refactor introduces no new ATDD Bun violations.
31
55
  exceptions:
32
56
  - Files that produce zero code lines after comment stripping score 100 and never fail.
33
57
  - The score is clamped to the 0..100 range.
package/integrity.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.10.39",
2
+ "version": "0.10.40",
3
3
  "files": {
4
4
  "HOOK_AUDIT.md": "5329d840db37671b1918f688ead26865473b87db73dbc75f7c8b2a8bbe8d6d43",
5
5
  "PLANNER_PORT.md": "fb5935bac8b7ac18994de21e43ace3a5ef8cd55f85b0e3349fca261280054f11",
@@ -40,12 +40,12 @@
40
40
  "conventions/coder.bun/coder.bun.commons-cross-feature-imports-in.convention.yaml": "2d66bd3c04186fcef67a89c2b6d81a697f8f43f978ff27284a3b8a3848097182",
41
41
  "conventions/coder.bun/coder.bun.commons-domain-no-framework-import.convention.yaml": "238545a401e472cf65cba7f16d94cde8279f13d38fcb401bc00751af284de7e7",
42
42
  "conventions/coder.bun/coder.bun.commons-domain-no-outbound.convention.yaml": "34507efbb62ade3b58556b56d7323093349a264a5f09034a5131dea7506fd786",
43
- "conventions/coder.bun/coder.bun.complexity-cyclomatic.convention.yaml": "e41abbf4f89ab4165f0bc6ea157b24addceebdb190e71a9b4e94c956c8f2956c",
44
- "conventions/coder.bun/coder.bun.complexity-length.convention.yaml": "dbc5345f38099f007cb445d059a4dcca0d7f4ee6edd0514385ca3535f1dad454",
45
- "conventions/coder.bun/coder.bun.complexity-nesting.convention.yaml": "7d5a37ee0d5ccb9e97c0ba042f5c2e858e06f2361b6a47e687ec5af372c887b8",
43
+ "conventions/coder.bun/coder.bun.complexity-cyclomatic.convention.yaml": "4184e97a4cb05ed1b66ba0d149cb83939a2c6246b98e1f01b4d38aad20ed30a6",
44
+ "conventions/coder.bun/coder.bun.complexity-length.convention.yaml": "0032cc56814f260a8993bdc8c3f1cd9bb48539a4091ec62dbbab1119f99d9799",
45
+ "conventions/coder.bun/coder.bun.complexity-nesting.convention.yaml": "903d930d0c5eaa98621238f63f132d94d7ffec37550452460b1e06e016adbedd",
46
46
  "conventions/coder.bun/coder.bun.composition-consumer.convention.yaml": "5bd69cdf8cb6a73e692c73cad30dceb533f624b38a6a120fc4f8e660a2cf25e0",
47
47
  "conventions/coder.bun/coder.bun.composition-root.convention.yaml": "74e30a8fa55b304ba2922fec59ecd8626d7a3c61411bb46bc5249188607f0de5",
48
- "conventions/coder.bun/coder.bun.dead-code-reachability.convention.yaml": "bce2c0f69c5c4f31a43278f3eabe993591e823cdb714f0841361ab470a134798",
48
+ "conventions/coder.bun/coder.bun.dead-code-reachability.convention.yaml": "662377f9fc09f57bd4dda380f75e21e6698a7f4f466e5e8ec830f115ec8d6321",
49
49
  "conventions/coder.bun/coder.bun.design-connected.convention.yaml": "21d9b1f11cb92f161acd163fe94d79022a0b35e269ea0db1c9bccbcfa4241b69",
50
50
  "conventions/coder.bun/coder.bun.design-dependency-flow.convention.yaml": "e96b6850ce8d5811947a9d4b62855477a112c053524a1d97a4f7ba35efb17e07",
51
51
  "conventions/coder.bun/coder.bun.design-hierarchy-import.convention.yaml": "067de2a858dba47ec11fab3ebbae052ea15d1481d9cb702a5eacc996c74c5922",
@@ -58,7 +58,7 @@
58
58
  "conventions/coder.bun/coder.bun.dto-mapper.convention.yaml": "e6890bcb421e9c10e71788e92ba1a2f1f96eed222fd0f3259f81b175b28ec190",
59
59
  "conventions/coder.bun/coder.bun.dto-placement.convention.yaml": "488576b8eba889b008e928357e62c323784da640bdcb986a06152ac4e4424568",
60
60
  "conventions/coder.bun/coder.bun.dto-purity.convention.yaml": "2c87391f323b10e8545095c8b278547a5a4f3854ac02ddec1849f4a6c83676fc",
61
- "conventions/coder.bun/coder.bun.duplication-intra-layer.convention.yaml": "5899b2b612108509a89be54db2c6f65f7e8fd798d6828ce81dd7d67e8ae4ae0c",
61
+ "conventions/coder.bun/coder.bun.duplication-intra-layer.convention.yaml": "37c0b9da0d3b5a7c7229e0697ea283249bd42cea056b0f1d6345a408ab50a7ea",
62
62
  "conventions/coder.bun/coder.bun.error-response-bare-string.convention.yaml": "c2c0f859f6dd12702edf225c4148849e72b6c25e6d7cd28edd5d644ba277a23c",
63
63
  "conventions/coder.bun/coder.bun.error-response-code-format.convention.yaml": "3048fed00b92c2559f7c52f73cfcce07b583eb47b12d04f0851e237ae3646567",
64
64
  "conventions/coder.bun/coder.bun.green-header-order.convention.yaml": "8b00d89605cbd618c052805fb1129a7a65743c72a7627f7cd08f0685ddefa8aa",
@@ -80,8 +80,8 @@
80
80
  "conventions/coder.bun/coder.bun.layer-naming.convention.yaml": "009c21f6adbbc1e08d9781d7466b06e3d7fb7d935bf45b1df07fe37639a60a82",
81
81
  "conventions/coder.bun/coder.bun.logging-console.convention.yaml": "e85fc1038ac78799b36d1f4156b6547fb00441f1e3ac3ec93e59e7e895e37aef",
82
82
  "conventions/coder.bun/coder.bun.logging-structured.convention.yaml": "a7c8bd90762bf1516d2af63d4fe731720bec9f58431009f69af1bfebc0398759",
83
- "conventions/coder.bun/coder.bun.quality-comments.convention.yaml": "fcd42efd152c4815cd3fd7811b091321e4a0d5e13f9c251cfd82b248f27c9fd8",
84
- "conventions/coder.bun/coder.bun.quality-mi.convention.yaml": "13dd95a87d67cb9b765b41cebcc3d33b117725edc28798a7d258cd6a66363621",
83
+ "conventions/coder.bun/coder.bun.quality-comments.convention.yaml": "fdf6be3a63f1b679fae1248334e1ee7ed3b09ffd7f5b8b25007fd31de3f5ad04",
84
+ "conventions/coder.bun/coder.bun.quality-mi.convention.yaml": "d4d29a1680693e5ac472badc529ce6e04a7f7cba30e2b3e5dd36c7a36c2465c5",
85
85
  "conventions/coder.bun/coder.bun.responsive-breakpoints-declared.convention.yaml": "4632b2cfb03cae65ac415dd205f4ff0b8f2242f9546dc4cafd11a9a8391bad35",
86
86
  "conventions/coder.bun/coder.bun.responsive-no-fixed-width.convention.yaml": "09bb70ccb5350bd46007ba1cf7da55447bdb87b8b31677dacba2bddba5ea63ab",
87
87
  "conventions/coder.bun/coder.bun.responsive-viewport-meta.convention.yaml": "705b1ed788a9c5b6d6a555d96662269e09c4ba5b30a7000d37ddf91393a65a88",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@afokapu/atdd-bun",
3
- "version": "0.10.39",
3
+ "version": "0.10.40",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/afokapu/atdd-bun.git"