pumuki 6.3.163 → 6.3.164

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.
package/CHANGELOG.md CHANGED
@@ -6,6 +6,13 @@ This project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [6.3.164] - 2026-05-06
10
+
11
+ ### Fixed
12
+
13
+ - **PUMUKI-INC-130 XCTest helpers brownfield:** `trackForMemoryLeaks`/factory helpers that import `XCTest` but do not define `XCTestCase` suites or `test...` methods no longer trigger `skills.ios.critical-test-quality`.
14
+ - **Skills runtime enforcement:** declarative skill registry rules stay visible in coverage metadata without being counted as missing runtime AST detectors; AUTO rules without detector mapping still fail closed.
15
+
9
16
  ## [6.3.143] - 2026-05-05
10
17
 
11
18
  ### Fixed
package/VERSION CHANGED
@@ -1 +1 @@
1
- v6.3.132
1
+ v6.3.164
@@ -683,10 +683,46 @@ func trackForMemoryLeaks(_ instance: AnyObject, file: StaticString = #filePath,
683
683
  addTeardownBlock { _ = instance }
684
684
  }
685
685
  `;
686
+ const ruralGoHelperSource = `
687
+ import XCTest
688
+
689
+ final class WeakReference<T: AnyObject> {
690
+ weak var value: T?
691
+
692
+ init(_ value: T) {
693
+ self.value = value
694
+ }
695
+ }
696
+
697
+ func trackForMemoryLeaks(
698
+ _ instance: AnyObject,
699
+ testCase: XCTestCase,
700
+ file: StaticString = #filePath,
701
+ line: UInt = #line
702
+ ) {
703
+ nonisolated(unsafe) let reference = makeSUT(instance)
704
+ testCase.addTeardownBlock {
705
+ XCTAssertNil(
706
+ reference.value,
707
+ "Instance should have been deallocated. Potential memory leak.",
708
+ file: file,
709
+ line: line
710
+ )
711
+ }
712
+ }
713
+
714
+ private func makeSUT<T: AnyObject>(_ instance: T) -> WeakReference<T> {
715
+ WeakReference(instance)
716
+ }
717
+ `;
686
718
 
687
719
  assert.equal(hasSwiftLegacyXCTestImportUsage(helperSource), false);
688
720
  assert.equal(hasSwiftModernizableXCTestSuiteUsage(helperSource), false);
689
721
  assert.equal(hasSwiftXCTestAssertionUsage(helperSource), false);
722
+ assert.equal(hasSwiftLegacyXCTestImportUsage(ruralGoHelperSource), false);
723
+ assert.equal(hasSwiftModernizableXCTestSuiteUsage(ruralGoHelperSource), false);
724
+ assert.equal(hasSwiftXCTestAssertionUsage(ruralGoHelperSource), false);
725
+ assert.equal(hasSwiftXCTUnwrapUsage(ruralGoHelperSource), false);
690
726
  });
691
727
 
692
728
  test('hasSwiftXCTUnwrapUsage detecta XCTUnwrap real y evita strings', () => {
@@ -840,6 +840,14 @@ const hasSwiftXCTestOnlyBrownfieldSuiteUsage = (source: string): boolean => {
840
840
  return !hasSwiftTestingImportUsage(source) && !hasSwiftTestingSuiteAttributeUsage(source);
841
841
  };
842
842
 
843
+ const hasSwiftXCTestHelperOrFactoryUsage = (source: string): boolean => {
844
+ return (
845
+ hasSwiftXCTestImportUsage(source) &&
846
+ !hasSwiftXCTestCaseSubclassUsage(source) &&
847
+ !hasSwiftLegacyXCTestMethodUsage(source)
848
+ );
849
+ };
850
+
843
851
  export const hasSwiftLegacyXCTestImportUsage = (source: string): boolean => {
844
852
  if (!hasSwiftXCTestImportUsage(source)) {
845
853
  return false;
@@ -885,6 +893,10 @@ export const hasSwiftXCTestAssertionUsage = (source: string): boolean => {
885
893
  return false;
886
894
  }
887
895
 
896
+ if (hasSwiftXCTestHelperOrFactoryUsage(source)) {
897
+ return false;
898
+ }
899
+
888
900
  if (hasSwiftXCTestOnlyBrownfieldSuiteUsage(source)) {
889
901
  return false;
890
902
  }
@@ -900,6 +912,10 @@ export const hasSwiftXCTUnwrapUsage = (source: string): boolean => {
900
912
  return false;
901
913
  }
902
914
 
915
+ if (hasSwiftXCTestHelperOrFactoryUsage(source)) {
916
+ return false;
917
+ }
918
+
903
919
  if (hasSwiftXCTestOnlyBrownfieldSuiteUsage(source)) {
904
920
  return false;
905
921
  }
@@ -916,6 +932,10 @@ const hasSwiftConfirmationUsage = (source: string): boolean => {
916
932
  };
917
933
 
918
934
  export const hasSwiftWaitForExpectationsUsage = (source: string): boolean => {
935
+ if (hasSwiftXCTestHelperOrFactoryUsage(source)) {
936
+ return false;
937
+ }
938
+
919
939
  const legacyWaitPattern = /\bwait\s*\(\s*for\s*:|\bwaitForExpectations\s*\(/;
920
940
  return collectSwiftFunctionDeclarations(source).some((declaration) => {
921
941
  if (!/\basync\b/.test(declaration.signature)) {
@@ -927,6 +947,10 @@ export const hasSwiftWaitForExpectationsUsage = (source: string): boolean => {
927
947
  };
928
948
 
929
949
  export const hasSwiftLegacyExpectationDescriptionUsage = (source: string): boolean => {
950
+ if (hasSwiftXCTestHelperOrFactoryUsage(source)) {
951
+ return false;
952
+ }
953
+
930
954
  return collectSwiftFunctionDeclarations(source).some((declaration) => {
931
955
  if (!/\basync\b/.test(declaration.signature)) {
932
956
  return false;
@@ -8,6 +8,15 @@ const PACKAGE_ROOT = resolve(__dirname, '..', '..');
8
8
 
9
9
  let cachedCoreSkillsLock: SkillsLockV1 | undefined;
10
10
 
11
+ const writeDebugFallback = (error: unknown): void => {
12
+ if (process.env.PUMUKI_DEBUG !== '1') {
13
+ return;
14
+ }
15
+
16
+ const message = error instanceof Error ? error.message : String(error);
17
+ process.stderr.write(`[pumuki][skills-lock] compile fallback: ${message}\n`);
18
+ };
19
+
11
20
  export const resolveCoreSkillsLockForPackageRoot = (
12
21
  packageRoot: string
13
22
  ): SkillsLockV1 | undefined => {
@@ -20,7 +29,8 @@ export const resolveCoreSkillsLockForPackageRoot = (
20
29
  if (compiledLock.bundles.length > 0) {
21
30
  return compiledLock;
22
31
  }
23
- } catch {
32
+ } catch (error) {
33
+ writeDebugFallback(error);
24
34
  }
25
35
 
26
36
  return loadSkillsLock(packageRoot);
@@ -603,7 +603,6 @@ export const loadSkillsRuleSetForStage = (
603
603
  continue;
604
604
  }
605
605
  if (evaluationMode !== 'AUTO') {
606
- unsupportedDetectorRuleIds.add(compiledRule.id);
607
606
  continue;
608
607
  }
609
608
  stageApplicableAutoRuleIds.add(compiledRule.id);
@@ -91,6 +91,15 @@ const fetchJson = async (url: string): Promise<unknown> => {
91
91
  return JSON.parse(text) as unknown;
92
92
  };
93
93
 
94
+ const writeDebugHealthProbeFailure = (error: unknown): void => {
95
+ if (process.env.PUMUKI_DEBUG !== '1') {
96
+ return;
97
+ }
98
+
99
+ const message = error instanceof Error ? error.message : String(error);
100
+ process.stderr.write(`[pumuki-mcp-evidence-stdio] health probe fallback: ${message}\n`);
101
+ };
102
+
94
103
  const startOrReuseEvidenceHttp = async (): Promise<{
95
104
  host: string;
96
105
  port: number;
@@ -108,8 +117,8 @@ const startOrReuseEvidenceHttp = async (): Promise<{
108
117
  if (health.status === 'ok') {
109
118
  return { host, port: requestedPort, route };
110
119
  }
111
- } catch {
112
- // ignored
120
+ } catch (error) {
121
+ writeDebugHealthProbeFailure(error);
113
122
  }
114
123
 
115
124
  const portInUse = await isPortInUse(host, requestedPort);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pumuki",
3
- "version": "6.3.163",
3
+ "version": "6.3.164",
4
4
  "description": "Enterprise-grade AST Intelligence System with multi-platform support (iOS, Android, Backend, Frontend) and Feature-First + DDD + Clean Architecture enforcement. Includes dynamic violations API for intelligent querying.",
5
5
  "main": "index.js",
6
6
  "bin": {