slopbrick 0.31.0 → 0.32.0

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.
@@ -4375,6 +4375,12 @@ function parseSource(source, filePath) {
4375
4375
  // sufficient for the v9 calibration goal.
4376
4376
  case "kt":
4377
4377
  case "kts":
4378
+ // v0.32.0: Swift files get the same parseBlankModule path.
4379
+ // All 5 `swift/*` rules (force-unwrap, print-debug, fatal-error-
4380
+ // thrown, implicitly-unwrapped-optional, strong-self-capture)
4381
+ // are regex-based and gate themselves on `/\.swift$/i.test(filePath)`
4382
+ // inside their `analyze()`. Same trade-off as Java/Kotlin.
4383
+ case "swift":
4378
4384
  return parseBlankModule(source);
4379
4385
  default:
4380
4386
  return parseWithSwc(source, filePath);
@@ -45551,13 +45557,13 @@ var signal_strength_default = {
45551
45557
  defaultOff: true
45552
45558
  },
45553
45559
  "swift/force-unwrap": {
45554
- recall: 0,
45555
- fpRate: 0,
45556
- ratio: 1,
45557
- precision: 0,
45558
- lastCalibratedAt: "2026-07-02T00:00:00Z",
45560
+ recall: 0.10211,
45561
+ fpRate: 0.21462,
45562
+ ratio: 0.48,
45563
+ precision: 0.1721,
45564
+ lastCalibratedAt: "2026-07-03T00:00:00Z",
45559
45565
  verdict: "DORMANT",
45560
- _calibrationNote: "v0.24: new rule (Swift force-unwrap \u2014 `as!`, `try!`, `var!.prop` in production). DORMANT until v9 Swift corpus calibration.",
45566
+ _calibrationNote: "v0.32: v9 Swift calibration (1300 neg, 568 pos). Per-file unique measurement: 58 TP files, 279 FP files, ratio=0.48. Era-confounded: pre-2022 Swift used ! freely (the only way to unwrap); modern Swift uses guard let / if let / try?. Same direction as kotlin/force-unwrap (0.35) and kotlin/runblocking-misuse (0.50). INSUFFICIENT_DATA: pos arm 568 files (below 10k floor).",
45561
45567
  aiSpecific: true,
45562
45568
  _v7Verdict: "DORMANT",
45563
45569
  _v7Lift: 1,
@@ -45566,16 +45572,21 @@ var signal_strength_default = {
45566
45572
  _v7Precision: 0,
45567
45573
  _v8Verdict: "DORMANT",
45568
45574
  _v8Lift: 1,
45575
+ _v9Verdict: "DORMANT",
45576
+ _v9Lift: 0.48,
45577
+ _v9Recall: 0.10211,
45578
+ _v9FpRate: 0.21462,
45579
+ _v9Precision: 0.1721,
45569
45580
  defaultOff: true
45570
45581
  },
45571
45582
  "swift/print-debug": {
45572
- recall: 0,
45573
- fpRate: 0,
45574
- ratio: 1,
45575
- precision: 0,
45576
- lastCalibratedAt: "2026-07-02T00:00:00Z",
45577
- verdict: "DORMANT",
45578
- _calibrationNote: "v0.24: new rule (multi-print in Swift source \u2014 use Logger / os.log). DORMANT until v9 Swift corpus calibration.",
45583
+ recall: 0.06866,
45584
+ fpRate: 0.06077,
45585
+ ratio: 1.13,
45586
+ precision: 0.3305,
45587
+ lastCalibratedAt: "2026-07-03T00:00:00Z",
45588
+ verdict: "OK",
45589
+ _calibrationNote: "v0.32: v9 Swift calibration (1300 neg, 568 pos). Per-file unique: 39 TP files, 79 FP files, ratio=1.13 (\u22651.0, OK). Total-fires measurement was ratio=1.78 (1.6x higher) but per-file is more conservative. precision=33.05% (below 50% USEFUL threshold); verdict=OK. The direction is positive: post-2024 Swift (especially AI-generated examples in OpenAI Swift, WhisperKit) uses print() for output; pre-2022 production Swift (Alamofire, Vapor, Moya) uses os.Logger / OSLog. Same direction as kotlin/println-as-log (1.84) and java/system-out-println (1.73 refined, 3.29 unrefined). INSUFFICIENT_DATA: pos arm 568 files (below 10k floor).",
45579
45590
  aiSpecific: true,
45580
45591
  _v7Verdict: "DORMANT",
45581
45592
  _v7Lift: 1,
@@ -45584,16 +45595,21 @@ var signal_strength_default = {
45584
45595
  _v7Precision: 0,
45585
45596
  _v8Verdict: "DORMANT",
45586
45597
  _v8Lift: 1,
45598
+ _v9Verdict: "OK",
45599
+ _v9Lift: 1.13,
45600
+ _v9Recall: 0.06866,
45601
+ _v9FpRate: 0.06077,
45602
+ _v9Precision: 0.3305,
45587
45603
  defaultOff: true
45588
45604
  },
45589
45605
  "swift/fatal-error-thrown": {
45590
- recall: 0,
45591
- fpRate: 0,
45592
- ratio: 1,
45593
- precision: 0,
45594
- lastCalibratedAt: "2026-07-02T00:00:00Z",
45606
+ recall: 0.06514,
45607
+ fpRate: 0.11462,
45608
+ ratio: 0.57,
45609
+ precision: 0.1989,
45610
+ lastCalibratedAt: "2026-07-03T00:00:00Z",
45595
45611
  verdict: "DORMANT",
45596
- _calibrationNote: "v0.24: new rule (`fatalError` / `preconditionFailure` in production Swift \u2014 replaces with typed default). DORMANT until v9 Swift corpus calibration.",
45612
+ _calibrationNote: "v0.32: v9 Swift calibration (1300 neg, 568 pos). Per-file unique: 37 TP files, 149 FP files, ratio=0.57. Era-confounded: pre-2022 Swift used fatalError liberally for unrecoverable states; modern Swift uses typed errors (throws) and Result types. INSUFFICIENT_DATA: pos arm 568 files.",
45597
45613
  aiSpecific: true,
45598
45614
  _v7Verdict: "DORMANT",
45599
45615
  _v7Lift: 1,
@@ -45602,16 +45618,21 @@ var signal_strength_default = {
45602
45618
  _v7Precision: 0,
45603
45619
  _v8Verdict: "DORMANT",
45604
45620
  _v8Lift: 1,
45621
+ _v9Verdict: "DORMANT",
45622
+ _v9Lift: 0.57,
45623
+ _v9Recall: 0.06514,
45624
+ _v9FpRate: 0.11462,
45625
+ _v9Precision: 0.1989,
45605
45626
  defaultOff: true
45606
45627
  },
45607
45628
  "swift/implicitly-unwrapped-optional": {
45608
- recall: 0,
45609
- fpRate: 0,
45610
- ratio: 1,
45611
- precision: 0,
45612
- lastCalibratedAt: "2026-07-02T00:00:00Z",
45629
+ recall: 0.01937,
45630
+ fpRate: 0.10692,
45631
+ ratio: 0.18,
45632
+ precision: 0.0733,
45633
+ lastCalibratedAt: "2026-07-03T00:00:00Z",
45613
45634
  verdict: "DORMANT",
45614
- _calibrationNote: "v0.24: new rule (Swift implicitly unwrapped optional \u2014 declare as Type? and unwrap with guard let). DORMANT until v9 Swift corpus calibration.",
45635
+ _calibrationNote: "v0.32: v9 Swift calibration (1300 neg, 568 pos). Per-file unique: 11 TP files, 139 FP files, ratio=0.18 \u2014 strong era-confound. Pre-2022 Swift used `var foo: Bar!` for IBOutlets and delegates; modern Swift uses `weak var` or declares as `Bar?` and unwraps with guard let. Same magnitude as kotlin/coroutine-global-scope (0.09) \u2014 strongest era-confound in v9 history. INSUFFICIENT_DATA: pos arm 568 files.",
45615
45636
  aiSpecific: true,
45616
45637
  _v7Verdict: "DORMANT",
45617
45638
  _v7Lift: 1,
@@ -45620,16 +45641,21 @@ var signal_strength_default = {
45620
45641
  _v7Precision: 0,
45621
45642
  _v8Verdict: "DORMANT",
45622
45643
  _v8Lift: 1,
45644
+ _v9Verdict: "DORMANT",
45645
+ _v9Lift: 0.18,
45646
+ _v9Recall: 0.01937,
45647
+ _v9FpRate: 0.10692,
45648
+ _v9Precision: 0.0733,
45623
45649
  defaultOff: true
45624
45650
  },
45625
45651
  "swift/strong-self-capture": {
45626
- recall: 0,
45627
- fpRate: 0,
45628
- ratio: 1,
45629
- precision: 0,
45630
- lastCalibratedAt: "2026-07-02T00:00:00Z",
45652
+ recall: 0.24824,
45653
+ fpRate: 0.44308,
45654
+ ratio: 0.56,
45655
+ precision: 0.1967,
45656
+ lastCalibratedAt: "2026-07-03T00:00:00Z",
45631
45657
  verdict: "DORMANT",
45632
- _calibrationNote: "v0.24: new rule (Swift closure captures `self` strongly \u2014 retain cycle. Use [weak self] / [unowned self]). DORMANT until v9 Swift corpus calibration.",
45658
+ _calibrationNote: "v0.32: v9 Swift calibration (1300 neg, 568 pos). Per-file unique: 141 TP files, 576 FP files, ratio=0.56. Era-confounded: pre-2022 Swift closures defaulted to strong self capture; modern Swift (Swift 5.7+) emits a warning for implicit self capture in escaping closures. The rule fires multiple times per file (multiple closures) \u2014 total fires were 2316 TP, 8913 FP, but per-file is 141 TP, 576 FP. INSUFFICIENT_DATA: pos arm 568 files.",
45633
45659
  aiSpecific: true,
45634
45660
  _v7Verdict: "DORMANT",
45635
45661
  _v7Lift: 1,
@@ -45638,6 +45664,11 @@ var signal_strength_default = {
45638
45664
  _v7Precision: 0,
45639
45665
  _v8Verdict: "DORMANT",
45640
45666
  _v8Lift: 1,
45667
+ _v9Verdict: "DORMANT",
45668
+ _v9Lift: 0.56,
45669
+ _v9Recall: 0.24824,
45670
+ _v9FpRate: 0.44308,
45671
+ _v9Precision: 0.1967,
45641
45672
  defaultOff: true
45642
45673
  },
45643
45674
  "cpp/using-namespace-std": {
@@ -45779,7 +45810,6 @@ async function scanFile(filePath, config, registry, cwd = process.cwd()) {
45779
45810
  const cache = buildParserCacheConfig(cwd);
45780
45811
  const ext = (0, import_node_path9.extname)(filePath).toLowerCase();
45781
45812
  const UNSUPPORTED_LANGS = /* @__PURE__ */ new Set([
45782
- ".swift",
45783
45813
  ".dart",
45784
45814
  ".cpp",
45785
45815
  ".cc",
@@ -4346,6 +4346,12 @@ function parseSource(source, filePath) {
4346
4346
  // sufficient for the v9 calibration goal.
4347
4347
  case "kt":
4348
4348
  case "kts":
4349
+ // v0.32.0: Swift files get the same parseBlankModule path.
4350
+ // All 5 `swift/*` rules (force-unwrap, print-debug, fatal-error-
4351
+ // thrown, implicitly-unwrapped-optional, strong-self-capture)
4352
+ // are regex-based and gate themselves on `/\.swift$/i.test(filePath)`
4353
+ // inside their `analyze()`. Same trade-off as Java/Kotlin.
4354
+ case "swift":
4349
4355
  return parseBlankModule(source);
4350
4356
  default:
4351
4357
  return parseWithSwc(source, filePath);
@@ -45522,13 +45528,13 @@ var signal_strength_default = {
45522
45528
  defaultOff: true
45523
45529
  },
45524
45530
  "swift/force-unwrap": {
45525
- recall: 0,
45526
- fpRate: 0,
45527
- ratio: 1,
45528
- precision: 0,
45529
- lastCalibratedAt: "2026-07-02T00:00:00Z",
45531
+ recall: 0.10211,
45532
+ fpRate: 0.21462,
45533
+ ratio: 0.48,
45534
+ precision: 0.1721,
45535
+ lastCalibratedAt: "2026-07-03T00:00:00Z",
45530
45536
  verdict: "DORMANT",
45531
- _calibrationNote: "v0.24: new rule (Swift force-unwrap \u2014 `as!`, `try!`, `var!.prop` in production). DORMANT until v9 Swift corpus calibration.",
45537
+ _calibrationNote: "v0.32: v9 Swift calibration (1300 neg, 568 pos). Per-file unique measurement: 58 TP files, 279 FP files, ratio=0.48. Era-confounded: pre-2022 Swift used ! freely (the only way to unwrap); modern Swift uses guard let / if let / try?. Same direction as kotlin/force-unwrap (0.35) and kotlin/runblocking-misuse (0.50). INSUFFICIENT_DATA: pos arm 568 files (below 10k floor).",
45532
45538
  aiSpecific: true,
45533
45539
  _v7Verdict: "DORMANT",
45534
45540
  _v7Lift: 1,
@@ -45537,16 +45543,21 @@ var signal_strength_default = {
45537
45543
  _v7Precision: 0,
45538
45544
  _v8Verdict: "DORMANT",
45539
45545
  _v8Lift: 1,
45546
+ _v9Verdict: "DORMANT",
45547
+ _v9Lift: 0.48,
45548
+ _v9Recall: 0.10211,
45549
+ _v9FpRate: 0.21462,
45550
+ _v9Precision: 0.1721,
45540
45551
  defaultOff: true
45541
45552
  },
45542
45553
  "swift/print-debug": {
45543
- recall: 0,
45544
- fpRate: 0,
45545
- ratio: 1,
45546
- precision: 0,
45547
- lastCalibratedAt: "2026-07-02T00:00:00Z",
45548
- verdict: "DORMANT",
45549
- _calibrationNote: "v0.24: new rule (multi-print in Swift source \u2014 use Logger / os.log). DORMANT until v9 Swift corpus calibration.",
45554
+ recall: 0.06866,
45555
+ fpRate: 0.06077,
45556
+ ratio: 1.13,
45557
+ precision: 0.3305,
45558
+ lastCalibratedAt: "2026-07-03T00:00:00Z",
45559
+ verdict: "OK",
45560
+ _calibrationNote: "v0.32: v9 Swift calibration (1300 neg, 568 pos). Per-file unique: 39 TP files, 79 FP files, ratio=1.13 (\u22651.0, OK). Total-fires measurement was ratio=1.78 (1.6x higher) but per-file is more conservative. precision=33.05% (below 50% USEFUL threshold); verdict=OK. The direction is positive: post-2024 Swift (especially AI-generated examples in OpenAI Swift, WhisperKit) uses print() for output; pre-2022 production Swift (Alamofire, Vapor, Moya) uses os.Logger / OSLog. Same direction as kotlin/println-as-log (1.84) and java/system-out-println (1.73 refined, 3.29 unrefined). INSUFFICIENT_DATA: pos arm 568 files (below 10k floor).",
45550
45561
  aiSpecific: true,
45551
45562
  _v7Verdict: "DORMANT",
45552
45563
  _v7Lift: 1,
@@ -45555,16 +45566,21 @@ var signal_strength_default = {
45555
45566
  _v7Precision: 0,
45556
45567
  _v8Verdict: "DORMANT",
45557
45568
  _v8Lift: 1,
45569
+ _v9Verdict: "OK",
45570
+ _v9Lift: 1.13,
45571
+ _v9Recall: 0.06866,
45572
+ _v9FpRate: 0.06077,
45573
+ _v9Precision: 0.3305,
45558
45574
  defaultOff: true
45559
45575
  },
45560
45576
  "swift/fatal-error-thrown": {
45561
- recall: 0,
45562
- fpRate: 0,
45563
- ratio: 1,
45564
- precision: 0,
45565
- lastCalibratedAt: "2026-07-02T00:00:00Z",
45577
+ recall: 0.06514,
45578
+ fpRate: 0.11462,
45579
+ ratio: 0.57,
45580
+ precision: 0.1989,
45581
+ lastCalibratedAt: "2026-07-03T00:00:00Z",
45566
45582
  verdict: "DORMANT",
45567
- _calibrationNote: "v0.24: new rule (`fatalError` / `preconditionFailure` in production Swift \u2014 replaces with typed default). DORMANT until v9 Swift corpus calibration.",
45583
+ _calibrationNote: "v0.32: v9 Swift calibration (1300 neg, 568 pos). Per-file unique: 37 TP files, 149 FP files, ratio=0.57. Era-confounded: pre-2022 Swift used fatalError liberally for unrecoverable states; modern Swift uses typed errors (throws) and Result types. INSUFFICIENT_DATA: pos arm 568 files.",
45568
45584
  aiSpecific: true,
45569
45585
  _v7Verdict: "DORMANT",
45570
45586
  _v7Lift: 1,
@@ -45573,16 +45589,21 @@ var signal_strength_default = {
45573
45589
  _v7Precision: 0,
45574
45590
  _v8Verdict: "DORMANT",
45575
45591
  _v8Lift: 1,
45592
+ _v9Verdict: "DORMANT",
45593
+ _v9Lift: 0.57,
45594
+ _v9Recall: 0.06514,
45595
+ _v9FpRate: 0.11462,
45596
+ _v9Precision: 0.1989,
45576
45597
  defaultOff: true
45577
45598
  },
45578
45599
  "swift/implicitly-unwrapped-optional": {
45579
- recall: 0,
45580
- fpRate: 0,
45581
- ratio: 1,
45582
- precision: 0,
45583
- lastCalibratedAt: "2026-07-02T00:00:00Z",
45600
+ recall: 0.01937,
45601
+ fpRate: 0.10692,
45602
+ ratio: 0.18,
45603
+ precision: 0.0733,
45604
+ lastCalibratedAt: "2026-07-03T00:00:00Z",
45584
45605
  verdict: "DORMANT",
45585
- _calibrationNote: "v0.24: new rule (Swift implicitly unwrapped optional \u2014 declare as Type? and unwrap with guard let). DORMANT until v9 Swift corpus calibration.",
45606
+ _calibrationNote: "v0.32: v9 Swift calibration (1300 neg, 568 pos). Per-file unique: 11 TP files, 139 FP files, ratio=0.18 \u2014 strong era-confound. Pre-2022 Swift used `var foo: Bar!` for IBOutlets and delegates; modern Swift uses `weak var` or declares as `Bar?` and unwraps with guard let. Same magnitude as kotlin/coroutine-global-scope (0.09) \u2014 strongest era-confound in v9 history. INSUFFICIENT_DATA: pos arm 568 files.",
45586
45607
  aiSpecific: true,
45587
45608
  _v7Verdict: "DORMANT",
45588
45609
  _v7Lift: 1,
@@ -45591,16 +45612,21 @@ var signal_strength_default = {
45591
45612
  _v7Precision: 0,
45592
45613
  _v8Verdict: "DORMANT",
45593
45614
  _v8Lift: 1,
45615
+ _v9Verdict: "DORMANT",
45616
+ _v9Lift: 0.18,
45617
+ _v9Recall: 0.01937,
45618
+ _v9FpRate: 0.10692,
45619
+ _v9Precision: 0.0733,
45594
45620
  defaultOff: true
45595
45621
  },
45596
45622
  "swift/strong-self-capture": {
45597
- recall: 0,
45598
- fpRate: 0,
45599
- ratio: 1,
45600
- precision: 0,
45601
- lastCalibratedAt: "2026-07-02T00:00:00Z",
45623
+ recall: 0.24824,
45624
+ fpRate: 0.44308,
45625
+ ratio: 0.56,
45626
+ precision: 0.1967,
45627
+ lastCalibratedAt: "2026-07-03T00:00:00Z",
45602
45628
  verdict: "DORMANT",
45603
- _calibrationNote: "v0.24: new rule (Swift closure captures `self` strongly \u2014 retain cycle. Use [weak self] / [unowned self]). DORMANT until v9 Swift corpus calibration.",
45629
+ _calibrationNote: "v0.32: v9 Swift calibration (1300 neg, 568 pos). Per-file unique: 141 TP files, 576 FP files, ratio=0.56. Era-confounded: pre-2022 Swift closures defaulted to strong self capture; modern Swift (Swift 5.7+) emits a warning for implicit self capture in escaping closures. The rule fires multiple times per file (multiple closures) \u2014 total fires were 2316 TP, 8913 FP, but per-file is 141 TP, 576 FP. INSUFFICIENT_DATA: pos arm 568 files.",
45604
45630
  aiSpecific: true,
45605
45631
  _v7Verdict: "DORMANT",
45606
45632
  _v7Lift: 1,
@@ -45609,6 +45635,11 @@ var signal_strength_default = {
45609
45635
  _v7Precision: 0,
45610
45636
  _v8Verdict: "DORMANT",
45611
45637
  _v8Lift: 1,
45638
+ _v9Verdict: "DORMANT",
45639
+ _v9Lift: 0.56,
45640
+ _v9Recall: 0.24824,
45641
+ _v9FpRate: 0.44308,
45642
+ _v9Precision: 0.1967,
45612
45643
  defaultOff: true
45613
45644
  },
45614
45645
  "cpp/using-namespace-std": {
@@ -45750,7 +45781,6 @@ async function scanFile(filePath, config, registry, cwd = process.cwd()) {
45750
45781
  const cache = buildParserCacheConfig(cwd);
45751
45782
  const ext = extname4(filePath).toLowerCase();
45752
45783
  const UNSUPPORTED_LANGS = /* @__PURE__ */ new Set([
45753
- ".swift",
45754
45784
  ".dart",
45755
45785
  ".cpp",
45756
45786
  ".cc",
package/dist/index.cjs CHANGED
@@ -36,7 +36,7 @@ var VERSION;
36
36
  var init_header = __esm({
37
37
  "src/types/_header.ts"() {
38
38
  "use strict";
39
- VERSION = "0.31.0";
39
+ VERSION = "0.32.0";
40
40
  }
41
41
  });
42
42
 
@@ -36609,6 +36609,12 @@ function parseSource(source, filePath) {
36609
36609
  // sufficient for the v9 calibration goal.
36610
36610
  case "kt":
36611
36611
  case "kts":
36612
+ // v0.32.0: Swift files get the same parseBlankModule path.
36613
+ // All 5 `swift/*` rules (force-unwrap, print-debug, fatal-error-
36614
+ // thrown, implicitly-unwrapped-optional, strong-self-capture)
36615
+ // are regex-based and gate themselves on `/\.swift$/i.test(filePath)`
36616
+ // inside their `analyze()`. Same trade-off as Java/Kotlin.
36617
+ case "swift":
36612
36618
  return parseBlankModule(source);
36613
36619
  default:
36614
36620
  return parseWithSwc(source, filePath);
@@ -51638,13 +51644,13 @@ var init_signal_strength = __esm({
51638
51644
  defaultOff: true
51639
51645
  },
51640
51646
  "swift/force-unwrap": {
51641
- recall: 0,
51642
- fpRate: 0,
51643
- ratio: 1,
51644
- precision: 0,
51645
- lastCalibratedAt: "2026-07-02T00:00:00Z",
51647
+ recall: 0.10211,
51648
+ fpRate: 0.21462,
51649
+ ratio: 0.48,
51650
+ precision: 0.1721,
51651
+ lastCalibratedAt: "2026-07-03T00:00:00Z",
51646
51652
  verdict: "DORMANT",
51647
- _calibrationNote: "v0.24: new rule (Swift force-unwrap \u2014 `as!`, `try!`, `var!.prop` in production). DORMANT until v9 Swift corpus calibration.",
51653
+ _calibrationNote: "v0.32: v9 Swift calibration (1300 neg, 568 pos). Per-file unique measurement: 58 TP files, 279 FP files, ratio=0.48. Era-confounded: pre-2022 Swift used ! freely (the only way to unwrap); modern Swift uses guard let / if let / try?. Same direction as kotlin/force-unwrap (0.35) and kotlin/runblocking-misuse (0.50). INSUFFICIENT_DATA: pos arm 568 files (below 10k floor).",
51648
51654
  aiSpecific: true,
51649
51655
  _v7Verdict: "DORMANT",
51650
51656
  _v7Lift: 1,
@@ -51653,16 +51659,21 @@ var init_signal_strength = __esm({
51653
51659
  _v7Precision: 0,
51654
51660
  _v8Verdict: "DORMANT",
51655
51661
  _v8Lift: 1,
51662
+ _v9Verdict: "DORMANT",
51663
+ _v9Lift: 0.48,
51664
+ _v9Recall: 0.10211,
51665
+ _v9FpRate: 0.21462,
51666
+ _v9Precision: 0.1721,
51656
51667
  defaultOff: true
51657
51668
  },
51658
51669
  "swift/print-debug": {
51659
- recall: 0,
51660
- fpRate: 0,
51661
- ratio: 1,
51662
- precision: 0,
51663
- lastCalibratedAt: "2026-07-02T00:00:00Z",
51664
- verdict: "DORMANT",
51665
- _calibrationNote: "v0.24: new rule (multi-print in Swift source \u2014 use Logger / os.log). DORMANT until v9 Swift corpus calibration.",
51670
+ recall: 0.06866,
51671
+ fpRate: 0.06077,
51672
+ ratio: 1.13,
51673
+ precision: 0.3305,
51674
+ lastCalibratedAt: "2026-07-03T00:00:00Z",
51675
+ verdict: "OK",
51676
+ _calibrationNote: "v0.32: v9 Swift calibration (1300 neg, 568 pos). Per-file unique: 39 TP files, 79 FP files, ratio=1.13 (\u22651.0, OK). Total-fires measurement was ratio=1.78 (1.6x higher) but per-file is more conservative. precision=33.05% (below 50% USEFUL threshold); verdict=OK. The direction is positive: post-2024 Swift (especially AI-generated examples in OpenAI Swift, WhisperKit) uses print() for output; pre-2022 production Swift (Alamofire, Vapor, Moya) uses os.Logger / OSLog. Same direction as kotlin/println-as-log (1.84) and java/system-out-println (1.73 refined, 3.29 unrefined). INSUFFICIENT_DATA: pos arm 568 files (below 10k floor).",
51666
51677
  aiSpecific: true,
51667
51678
  _v7Verdict: "DORMANT",
51668
51679
  _v7Lift: 1,
@@ -51671,16 +51682,21 @@ var init_signal_strength = __esm({
51671
51682
  _v7Precision: 0,
51672
51683
  _v8Verdict: "DORMANT",
51673
51684
  _v8Lift: 1,
51685
+ _v9Verdict: "OK",
51686
+ _v9Lift: 1.13,
51687
+ _v9Recall: 0.06866,
51688
+ _v9FpRate: 0.06077,
51689
+ _v9Precision: 0.3305,
51674
51690
  defaultOff: true
51675
51691
  },
51676
51692
  "swift/fatal-error-thrown": {
51677
- recall: 0,
51678
- fpRate: 0,
51679
- ratio: 1,
51680
- precision: 0,
51681
- lastCalibratedAt: "2026-07-02T00:00:00Z",
51693
+ recall: 0.06514,
51694
+ fpRate: 0.11462,
51695
+ ratio: 0.57,
51696
+ precision: 0.1989,
51697
+ lastCalibratedAt: "2026-07-03T00:00:00Z",
51682
51698
  verdict: "DORMANT",
51683
- _calibrationNote: "v0.24: new rule (`fatalError` / `preconditionFailure` in production Swift \u2014 replaces with typed default). DORMANT until v9 Swift corpus calibration.",
51699
+ _calibrationNote: "v0.32: v9 Swift calibration (1300 neg, 568 pos). Per-file unique: 37 TP files, 149 FP files, ratio=0.57. Era-confounded: pre-2022 Swift used fatalError liberally for unrecoverable states; modern Swift uses typed errors (throws) and Result types. INSUFFICIENT_DATA: pos arm 568 files.",
51684
51700
  aiSpecific: true,
51685
51701
  _v7Verdict: "DORMANT",
51686
51702
  _v7Lift: 1,
@@ -51689,16 +51705,21 @@ var init_signal_strength = __esm({
51689
51705
  _v7Precision: 0,
51690
51706
  _v8Verdict: "DORMANT",
51691
51707
  _v8Lift: 1,
51708
+ _v9Verdict: "DORMANT",
51709
+ _v9Lift: 0.57,
51710
+ _v9Recall: 0.06514,
51711
+ _v9FpRate: 0.11462,
51712
+ _v9Precision: 0.1989,
51692
51713
  defaultOff: true
51693
51714
  },
51694
51715
  "swift/implicitly-unwrapped-optional": {
51695
- recall: 0,
51696
- fpRate: 0,
51697
- ratio: 1,
51698
- precision: 0,
51699
- lastCalibratedAt: "2026-07-02T00:00:00Z",
51716
+ recall: 0.01937,
51717
+ fpRate: 0.10692,
51718
+ ratio: 0.18,
51719
+ precision: 0.0733,
51720
+ lastCalibratedAt: "2026-07-03T00:00:00Z",
51700
51721
  verdict: "DORMANT",
51701
- _calibrationNote: "v0.24: new rule (Swift implicitly unwrapped optional \u2014 declare as Type? and unwrap with guard let). DORMANT until v9 Swift corpus calibration.",
51722
+ _calibrationNote: "v0.32: v9 Swift calibration (1300 neg, 568 pos). Per-file unique: 11 TP files, 139 FP files, ratio=0.18 \u2014 strong era-confound. Pre-2022 Swift used `var foo: Bar!` for IBOutlets and delegates; modern Swift uses `weak var` or declares as `Bar?` and unwraps with guard let. Same magnitude as kotlin/coroutine-global-scope (0.09) \u2014 strongest era-confound in v9 history. INSUFFICIENT_DATA: pos arm 568 files.",
51702
51723
  aiSpecific: true,
51703
51724
  _v7Verdict: "DORMANT",
51704
51725
  _v7Lift: 1,
@@ -51707,16 +51728,21 @@ var init_signal_strength = __esm({
51707
51728
  _v7Precision: 0,
51708
51729
  _v8Verdict: "DORMANT",
51709
51730
  _v8Lift: 1,
51731
+ _v9Verdict: "DORMANT",
51732
+ _v9Lift: 0.18,
51733
+ _v9Recall: 0.01937,
51734
+ _v9FpRate: 0.10692,
51735
+ _v9Precision: 0.0733,
51710
51736
  defaultOff: true
51711
51737
  },
51712
51738
  "swift/strong-self-capture": {
51713
- recall: 0,
51714
- fpRate: 0,
51715
- ratio: 1,
51716
- precision: 0,
51717
- lastCalibratedAt: "2026-07-02T00:00:00Z",
51739
+ recall: 0.24824,
51740
+ fpRate: 0.44308,
51741
+ ratio: 0.56,
51742
+ precision: 0.1967,
51743
+ lastCalibratedAt: "2026-07-03T00:00:00Z",
51718
51744
  verdict: "DORMANT",
51719
- _calibrationNote: "v0.24: new rule (Swift closure captures `self` strongly \u2014 retain cycle. Use [weak self] / [unowned self]). DORMANT until v9 Swift corpus calibration.",
51745
+ _calibrationNote: "v0.32: v9 Swift calibration (1300 neg, 568 pos). Per-file unique: 141 TP files, 576 FP files, ratio=0.56. Era-confounded: pre-2022 Swift closures defaulted to strong self capture; modern Swift (Swift 5.7+) emits a warning for implicit self capture in escaping closures. The rule fires multiple times per file (multiple closures) \u2014 total fires were 2316 TP, 8913 FP, but per-file is 141 TP, 576 FP. INSUFFICIENT_DATA: pos arm 568 files.",
51720
51746
  aiSpecific: true,
51721
51747
  _v7Verdict: "DORMANT",
51722
51748
  _v7Lift: 1,
@@ -51725,6 +51751,11 @@ var init_signal_strength = __esm({
51725
51751
  _v7Precision: 0,
51726
51752
  _v8Verdict: "DORMANT",
51727
51753
  _v8Lift: 1,
51754
+ _v9Verdict: "DORMANT",
51755
+ _v9Lift: 0.56,
51756
+ _v9Recall: 0.24824,
51757
+ _v9FpRate: 0.44308,
51758
+ _v9Precision: 0.1967,
51728
51759
  defaultOff: true
51729
51760
  },
51730
51761
  "cpp/using-namespace-std": {
@@ -51894,7 +51925,6 @@ async function scanFile(filePath, config, registry, cwd = process.cwd()) {
51894
51925
  const cache = buildParserCacheConfig(cwd);
51895
51926
  const ext = (0, import_node_path12.extname)(filePath).toLowerCase();
51896
51927
  const UNSUPPORTED_LANGS = /* @__PURE__ */ new Set([
51897
- ".swift",
51898
51928
  ".dart",
51899
51929
  ".cpp",
51900
51930
  ".cc",
package/dist/index.js CHANGED
@@ -19,7 +19,7 @@ var VERSION;
19
19
  var init_header = __esm({
20
20
  "src/types/_header.ts"() {
21
21
  "use strict";
22
- VERSION = "0.31.0";
22
+ VERSION = "0.32.0";
23
23
  }
24
24
  });
25
25
 
@@ -36599,6 +36599,12 @@ function parseSource(source, filePath) {
36599
36599
  // sufficient for the v9 calibration goal.
36600
36600
  case "kt":
36601
36601
  case "kts":
36602
+ // v0.32.0: Swift files get the same parseBlankModule path.
36603
+ // All 5 `swift/*` rules (force-unwrap, print-debug, fatal-error-
36604
+ // thrown, implicitly-unwrapped-optional, strong-self-capture)
36605
+ // are regex-based and gate themselves on `/\.swift$/i.test(filePath)`
36606
+ // inside their `analyze()`. Same trade-off as Java/Kotlin.
36607
+ case "swift":
36602
36608
  return parseBlankModule(source);
36603
36609
  default:
36604
36610
  return parseWithSwc(source, filePath);
@@ -51616,13 +51622,13 @@ var init_signal_strength = __esm({
51616
51622
  defaultOff: true
51617
51623
  },
51618
51624
  "swift/force-unwrap": {
51619
- recall: 0,
51620
- fpRate: 0,
51621
- ratio: 1,
51622
- precision: 0,
51623
- lastCalibratedAt: "2026-07-02T00:00:00Z",
51625
+ recall: 0.10211,
51626
+ fpRate: 0.21462,
51627
+ ratio: 0.48,
51628
+ precision: 0.1721,
51629
+ lastCalibratedAt: "2026-07-03T00:00:00Z",
51624
51630
  verdict: "DORMANT",
51625
- _calibrationNote: "v0.24: new rule (Swift force-unwrap \u2014 `as!`, `try!`, `var!.prop` in production). DORMANT until v9 Swift corpus calibration.",
51631
+ _calibrationNote: "v0.32: v9 Swift calibration (1300 neg, 568 pos). Per-file unique measurement: 58 TP files, 279 FP files, ratio=0.48. Era-confounded: pre-2022 Swift used ! freely (the only way to unwrap); modern Swift uses guard let / if let / try?. Same direction as kotlin/force-unwrap (0.35) and kotlin/runblocking-misuse (0.50). INSUFFICIENT_DATA: pos arm 568 files (below 10k floor).",
51626
51632
  aiSpecific: true,
51627
51633
  _v7Verdict: "DORMANT",
51628
51634
  _v7Lift: 1,
@@ -51631,16 +51637,21 @@ var init_signal_strength = __esm({
51631
51637
  _v7Precision: 0,
51632
51638
  _v8Verdict: "DORMANT",
51633
51639
  _v8Lift: 1,
51640
+ _v9Verdict: "DORMANT",
51641
+ _v9Lift: 0.48,
51642
+ _v9Recall: 0.10211,
51643
+ _v9FpRate: 0.21462,
51644
+ _v9Precision: 0.1721,
51634
51645
  defaultOff: true
51635
51646
  },
51636
51647
  "swift/print-debug": {
51637
- recall: 0,
51638
- fpRate: 0,
51639
- ratio: 1,
51640
- precision: 0,
51641
- lastCalibratedAt: "2026-07-02T00:00:00Z",
51642
- verdict: "DORMANT",
51643
- _calibrationNote: "v0.24: new rule (multi-print in Swift source \u2014 use Logger / os.log). DORMANT until v9 Swift corpus calibration.",
51648
+ recall: 0.06866,
51649
+ fpRate: 0.06077,
51650
+ ratio: 1.13,
51651
+ precision: 0.3305,
51652
+ lastCalibratedAt: "2026-07-03T00:00:00Z",
51653
+ verdict: "OK",
51654
+ _calibrationNote: "v0.32: v9 Swift calibration (1300 neg, 568 pos). Per-file unique: 39 TP files, 79 FP files, ratio=1.13 (\u22651.0, OK). Total-fires measurement was ratio=1.78 (1.6x higher) but per-file is more conservative. precision=33.05% (below 50% USEFUL threshold); verdict=OK. The direction is positive: post-2024 Swift (especially AI-generated examples in OpenAI Swift, WhisperKit) uses print() for output; pre-2022 production Swift (Alamofire, Vapor, Moya) uses os.Logger / OSLog. Same direction as kotlin/println-as-log (1.84) and java/system-out-println (1.73 refined, 3.29 unrefined). INSUFFICIENT_DATA: pos arm 568 files (below 10k floor).",
51644
51655
  aiSpecific: true,
51645
51656
  _v7Verdict: "DORMANT",
51646
51657
  _v7Lift: 1,
@@ -51649,16 +51660,21 @@ var init_signal_strength = __esm({
51649
51660
  _v7Precision: 0,
51650
51661
  _v8Verdict: "DORMANT",
51651
51662
  _v8Lift: 1,
51663
+ _v9Verdict: "OK",
51664
+ _v9Lift: 1.13,
51665
+ _v9Recall: 0.06866,
51666
+ _v9FpRate: 0.06077,
51667
+ _v9Precision: 0.3305,
51652
51668
  defaultOff: true
51653
51669
  },
51654
51670
  "swift/fatal-error-thrown": {
51655
- recall: 0,
51656
- fpRate: 0,
51657
- ratio: 1,
51658
- precision: 0,
51659
- lastCalibratedAt: "2026-07-02T00:00:00Z",
51671
+ recall: 0.06514,
51672
+ fpRate: 0.11462,
51673
+ ratio: 0.57,
51674
+ precision: 0.1989,
51675
+ lastCalibratedAt: "2026-07-03T00:00:00Z",
51660
51676
  verdict: "DORMANT",
51661
- _calibrationNote: "v0.24: new rule (`fatalError` / `preconditionFailure` in production Swift \u2014 replaces with typed default). DORMANT until v9 Swift corpus calibration.",
51677
+ _calibrationNote: "v0.32: v9 Swift calibration (1300 neg, 568 pos). Per-file unique: 37 TP files, 149 FP files, ratio=0.57. Era-confounded: pre-2022 Swift used fatalError liberally for unrecoverable states; modern Swift uses typed errors (throws) and Result types. INSUFFICIENT_DATA: pos arm 568 files.",
51662
51678
  aiSpecific: true,
51663
51679
  _v7Verdict: "DORMANT",
51664
51680
  _v7Lift: 1,
@@ -51667,16 +51683,21 @@ var init_signal_strength = __esm({
51667
51683
  _v7Precision: 0,
51668
51684
  _v8Verdict: "DORMANT",
51669
51685
  _v8Lift: 1,
51686
+ _v9Verdict: "DORMANT",
51687
+ _v9Lift: 0.57,
51688
+ _v9Recall: 0.06514,
51689
+ _v9FpRate: 0.11462,
51690
+ _v9Precision: 0.1989,
51670
51691
  defaultOff: true
51671
51692
  },
51672
51693
  "swift/implicitly-unwrapped-optional": {
51673
- recall: 0,
51674
- fpRate: 0,
51675
- ratio: 1,
51676
- precision: 0,
51677
- lastCalibratedAt: "2026-07-02T00:00:00Z",
51694
+ recall: 0.01937,
51695
+ fpRate: 0.10692,
51696
+ ratio: 0.18,
51697
+ precision: 0.0733,
51698
+ lastCalibratedAt: "2026-07-03T00:00:00Z",
51678
51699
  verdict: "DORMANT",
51679
- _calibrationNote: "v0.24: new rule (Swift implicitly unwrapped optional \u2014 declare as Type? and unwrap with guard let). DORMANT until v9 Swift corpus calibration.",
51700
+ _calibrationNote: "v0.32: v9 Swift calibration (1300 neg, 568 pos). Per-file unique: 11 TP files, 139 FP files, ratio=0.18 \u2014 strong era-confound. Pre-2022 Swift used `var foo: Bar!` for IBOutlets and delegates; modern Swift uses `weak var` or declares as `Bar?` and unwraps with guard let. Same magnitude as kotlin/coroutine-global-scope (0.09) \u2014 strongest era-confound in v9 history. INSUFFICIENT_DATA: pos arm 568 files.",
51680
51701
  aiSpecific: true,
51681
51702
  _v7Verdict: "DORMANT",
51682
51703
  _v7Lift: 1,
@@ -51685,16 +51706,21 @@ var init_signal_strength = __esm({
51685
51706
  _v7Precision: 0,
51686
51707
  _v8Verdict: "DORMANT",
51687
51708
  _v8Lift: 1,
51709
+ _v9Verdict: "DORMANT",
51710
+ _v9Lift: 0.18,
51711
+ _v9Recall: 0.01937,
51712
+ _v9FpRate: 0.10692,
51713
+ _v9Precision: 0.0733,
51688
51714
  defaultOff: true
51689
51715
  },
51690
51716
  "swift/strong-self-capture": {
51691
- recall: 0,
51692
- fpRate: 0,
51693
- ratio: 1,
51694
- precision: 0,
51695
- lastCalibratedAt: "2026-07-02T00:00:00Z",
51717
+ recall: 0.24824,
51718
+ fpRate: 0.44308,
51719
+ ratio: 0.56,
51720
+ precision: 0.1967,
51721
+ lastCalibratedAt: "2026-07-03T00:00:00Z",
51696
51722
  verdict: "DORMANT",
51697
- _calibrationNote: "v0.24: new rule (Swift closure captures `self` strongly \u2014 retain cycle. Use [weak self] / [unowned self]). DORMANT until v9 Swift corpus calibration.",
51723
+ _calibrationNote: "v0.32: v9 Swift calibration (1300 neg, 568 pos). Per-file unique: 141 TP files, 576 FP files, ratio=0.56. Era-confounded: pre-2022 Swift closures defaulted to strong self capture; modern Swift (Swift 5.7+) emits a warning for implicit self capture in escaping closures. The rule fires multiple times per file (multiple closures) \u2014 total fires were 2316 TP, 8913 FP, but per-file is 141 TP, 576 FP. INSUFFICIENT_DATA: pos arm 568 files.",
51698
51724
  aiSpecific: true,
51699
51725
  _v7Verdict: "DORMANT",
51700
51726
  _v7Lift: 1,
@@ -51703,6 +51729,11 @@ var init_signal_strength = __esm({
51703
51729
  _v7Precision: 0,
51704
51730
  _v8Verdict: "DORMANT",
51705
51731
  _v8Lift: 1,
51732
+ _v9Verdict: "DORMANT",
51733
+ _v9Lift: 0.56,
51734
+ _v9Recall: 0.24824,
51735
+ _v9FpRate: 0.44308,
51736
+ _v9Precision: 0.1967,
51706
51737
  defaultOff: true
51707
51738
  },
51708
51739
  "cpp/using-namespace-std": {
@@ -51876,7 +51907,6 @@ async function scanFile(filePath, config, registry, cwd = process.cwd()) {
51876
51907
  const cache = buildParserCacheConfig(cwd);
51877
51908
  const ext = extname5(filePath).toLowerCase();
51878
51909
  const UNSUPPORTED_LANGS = /* @__PURE__ */ new Set([
51879
- ".swift",
51880
51910
  ".dart",
51881
51911
  ".cpp",
51882
51912
  ".cc",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "slopbrick",
3
- "version": "0.31.0",
3
+ "version": "0.32.0",
4
4
  "description": "Discovered, modeled, and governed repository structure. SlopBrick scans source code, classifies it against 95+ rules in 15 categories, computes 4 scores (aiSlopScore: lower=cleaner, engineeringHygiene, security, repositoryHealth composite), and persists the structure for AI agents and CI.",
5
5
  "type": "module",
6
6
  "bin": {