pumuki 6.3.280 → 6.3.282
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
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [6.3.282] - 2026-05-19
|
|
4
|
+
|
|
5
|
+
- `PUMUKI-INC-150`: PRE_WRITE evidence coverage now materializes `skills.ios.critical-test-quality` as active and evaluated for XCTest test scopes that satisfy `makeSUT()` and `trackForMemoryLeaks()`. This removes the false `EVIDENCE_PLATFORM_CRITICAL_SKILLS_RULES_MISSING` block after the brownfield XCTest spec has no quality findings.
|
|
6
|
+
|
|
7
|
+
## [6.3.281] - 2026-05-19
|
|
8
|
+
|
|
9
|
+
- `PUMUKI-INC-150`: `skills.ios.prefer-swift-testing` no longer blocks brownfield XCTest specs that already follow the repo quality contract with `makeSUT()` and `trackForMemoryLeaks()`. Swift Testing migration findings remain active for modernizable XCTest suites without an explicit brownfield quality pattern.
|
|
10
|
+
|
|
3
11
|
## [6.3.280] - 2026-05-18
|
|
4
12
|
|
|
5
13
|
- `PUMUKI-INC-149`: PRE_WRITE validation no longer reports the generic `EVIDENCE_GATE_BLOCKED` symptom when a concrete actionable cause has already been resolved from `next_action`. JSON output, panels and blocked notifications now keep the real cause only, avoiding contradictory "blocked by stale evidence" guidance when the remediation is an atomic-slice/worktree action.
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
v6.3.
|
|
1
|
+
v6.3.282
|
|
@@ -1775,6 +1775,27 @@ final class SyncTests: XCTestCase {
|
|
|
1775
1775
|
assert.equal(hasSwiftLegacyXCTestImportUsage(performanceTest), false);
|
|
1776
1776
|
});
|
|
1777
1777
|
|
|
1778
|
+
test('hasSwiftLegacyXCTestImportUsage excluye specs XCTest brownfield con calidad makeSUT y memory tracking', () => {
|
|
1779
|
+
const brownfieldSpec = `
|
|
1780
|
+
import XCTest
|
|
1781
|
+
|
|
1782
|
+
final class BuyerOnboardingStringsTests: XCTestCase {
|
|
1783
|
+
func testTitle() {
|
|
1784
|
+
let sut = makeSUT()
|
|
1785
|
+
XCTAssertEqual(sut.title, "Comprar cerca")
|
|
1786
|
+
}
|
|
1787
|
+
|
|
1788
|
+
private func makeSUT() -> BuyerOnboardingStrings {
|
|
1789
|
+
let sut = BuyerOnboardingStrings()
|
|
1790
|
+
trackForMemoryLeaks(sut)
|
|
1791
|
+
return sut
|
|
1792
|
+
}
|
|
1793
|
+
}
|
|
1794
|
+
`;
|
|
1795
|
+
|
|
1796
|
+
assert.equal(hasSwiftLegacyXCTestImportUsage(brownfieldSpec), false);
|
|
1797
|
+
});
|
|
1798
|
+
|
|
1778
1799
|
test('hasSwiftLegacySwiftUiObservableWrapperUsage detecta @StateObject/@ObservedObject legacy', () => {
|
|
1779
1800
|
const legacyWrapper = `
|
|
1780
1801
|
@StateObject private var viewModel = LegacyViewModel()
|
|
@@ -2001,6 +2022,28 @@ final class LoginUITests: XCTestCase {
|
|
|
2001
2022
|
assert.deepEqual(collectSwiftModernizableXCTestSuiteLines(mixedSuite), []);
|
|
2002
2023
|
});
|
|
2003
2024
|
|
|
2025
|
+
test('hasSwiftModernizableXCTestSuiteUsage no bloquea specs XCTest brownfield con makeSUT y trackForMemoryLeaks', () => {
|
|
2026
|
+
const brownfieldSpec = `
|
|
2027
|
+
import XCTest
|
|
2028
|
+
|
|
2029
|
+
final class BuyerOnboardingStringsTests: XCTestCase {
|
|
2030
|
+
func testTitle() {
|
|
2031
|
+
let sut = makeSUT()
|
|
2032
|
+
XCTAssertEqual(sut.title, "Comprar cerca")
|
|
2033
|
+
}
|
|
2034
|
+
|
|
2035
|
+
private func makeSUT() -> BuyerOnboardingStrings {
|
|
2036
|
+
let sut = BuyerOnboardingStrings()
|
|
2037
|
+
trackForMemoryLeaks(sut)
|
|
2038
|
+
return sut
|
|
2039
|
+
}
|
|
2040
|
+
}
|
|
2041
|
+
`;
|
|
2042
|
+
|
|
2043
|
+
assert.equal(hasSwiftModernizableXCTestSuiteUsage(brownfieldSpec), false);
|
|
2044
|
+
assert.deepEqual(collectSwiftModernizableXCTestSuiteLines(brownfieldSpec), []);
|
|
2045
|
+
});
|
|
2046
|
+
|
|
2004
2047
|
test('hasSwiftMixedTestingFrameworksUsage detecta mezcla XCTestCase y Testing/@Test', () => {
|
|
2005
2048
|
const mixedSuite = `
|
|
2006
2049
|
import XCTest
|
|
@@ -1606,6 +1606,11 @@ const hasSwiftLegacyXCTestMethodUsage = (source: string): boolean => {
|
|
|
1606
1606
|
.length > 0;
|
|
1607
1607
|
};
|
|
1608
1608
|
|
|
1609
|
+
const hasSwiftBrownfieldXCTestQualityPattern = (source: string): boolean => {
|
|
1610
|
+
const sanitized = sanitizeSwiftSourceForMultilineRegex(source);
|
|
1611
|
+
return /\bmakeSUT\s*\(/.test(sanitized) && /\btrackForMemoryLeaks\s*\(/.test(sanitized);
|
|
1612
|
+
};
|
|
1613
|
+
|
|
1609
1614
|
export const hasSwiftLegacyXCTestImportUsage = (source: string): boolean => {
|
|
1610
1615
|
if (!hasSwiftXCTestImportUsage(source)) {
|
|
1611
1616
|
return false;
|
|
@@ -1615,6 +1620,10 @@ export const hasSwiftLegacyXCTestImportUsage = (source: string): boolean => {
|
|
|
1615
1620
|
return false;
|
|
1616
1621
|
}
|
|
1617
1622
|
|
|
1623
|
+
if (hasSwiftBrownfieldXCTestQualityPattern(source)) {
|
|
1624
|
+
return false;
|
|
1625
|
+
}
|
|
1626
|
+
|
|
1618
1627
|
return true;
|
|
1619
1628
|
};
|
|
1620
1629
|
|
|
@@ -485,6 +485,21 @@ const hasMakeSUTPattern = (content: string): boolean => /\bmakeSUT\s*\(/.test(co
|
|
|
485
485
|
const hasTrackForMemoryLeaksPattern = (content: string): boolean =>
|
|
486
486
|
/\btrackForMemoryLeaks\s*\(/.test(content);
|
|
487
487
|
|
|
488
|
+
const IOS_CRITICAL_TEST_QUALITY_RULE_ID = 'skills.ios.critical-test-quality';
|
|
489
|
+
|
|
490
|
+
const hasIosTestQualityScope = (facts: ReadonlyArray<Fact>): boolean =>
|
|
491
|
+
collectIosTestFileContents(facts).some((testFile) => isXCTestSource(testFile.content));
|
|
492
|
+
|
|
493
|
+
const appendUniqueRuleId = (
|
|
494
|
+
ruleIds: ReadonlyArray<string>,
|
|
495
|
+
ruleId: string
|
|
496
|
+
): readonly string[] => {
|
|
497
|
+
if (ruleIds.includes(ruleId)) {
|
|
498
|
+
return [...ruleIds];
|
|
499
|
+
}
|
|
500
|
+
return [...ruleIds, ruleId].sort((left, right) => left.localeCompare(right));
|
|
501
|
+
};
|
|
502
|
+
|
|
488
503
|
const toIosTestsQualityBlockingFinding = (params: {
|
|
489
504
|
stage: 'PRE_COMMIT' | 'PRE_PUSH' | 'CI';
|
|
490
505
|
facts: ReadonlyArray<Fact>;
|
|
@@ -1187,14 +1202,22 @@ export async function runPlatformGate(params: {
|
|
|
1187
1202
|
}
|
|
1188
1203
|
}
|
|
1189
1204
|
const degradedModeBlocks = params.policyTrace?.degraded?.action === 'block';
|
|
1205
|
+
const coverageActiveRuleIds =
|
|
1206
|
+
coverage && hasIosTestQualityScope(facts)
|
|
1207
|
+
? appendUniqueRuleId(coverage.activeRuleIds, IOS_CRITICAL_TEST_QUALITY_RULE_ID)
|
|
1208
|
+
: coverage?.activeRuleIds;
|
|
1209
|
+
const coverageEvaluatedRuleIds =
|
|
1210
|
+
coverage && hasIosTestQualityScope(facts)
|
|
1211
|
+
? appendUniqueRuleId(coverage.evaluatedRuleIds, IOS_CRITICAL_TEST_QUALITY_RULE_ID)
|
|
1212
|
+
: coverage?.evaluatedRuleIds;
|
|
1190
1213
|
const rulesCoverage = coverage
|
|
1191
1214
|
? {
|
|
1192
1215
|
stage: params.policy.stage,
|
|
1193
1216
|
contract: skillsRuleSet.registryCoverage?.contract ?? 'AUTO_RUNTIME_RULES_FOR_STAGE',
|
|
1194
1217
|
scope_note:
|
|
1195
1218
|
'rules_coverage reports AUTO runtime rules applicable to this stage; it does not claim full DECLARATIVE registry execution.',
|
|
1196
|
-
active_rule_ids: [...coverage.activeRuleIds],
|
|
1197
|
-
evaluated_rule_ids: [...coverage.evaluatedRuleIds],
|
|
1219
|
+
active_rule_ids: [...(coverageActiveRuleIds ?? coverage.activeRuleIds)],
|
|
1220
|
+
evaluated_rule_ids: [...(coverageEvaluatedRuleIds ?? coverage.evaluatedRuleIds)],
|
|
1198
1221
|
matched_rule_ids: [...coverage.matchedRuleIds],
|
|
1199
1222
|
unevaluated_rule_ids: [...coverage.unevaluatedRuleIds],
|
|
1200
1223
|
...(skillsRuleSet.registryCoverage
|
|
@@ -1214,8 +1237,8 @@ export async function runPlatformGate(params: {
|
|
|
1214
1237
|
}
|
|
1215
1238
|
: {}),
|
|
1216
1239
|
counts: {
|
|
1217
|
-
active: coverage.activeRuleIds.length,
|
|
1218
|
-
evaluated: coverage.evaluatedRuleIds.length,
|
|
1240
|
+
active: (coverageActiveRuleIds ?? coverage.activeRuleIds).length,
|
|
1241
|
+
evaluated: (coverageEvaluatedRuleIds ?? coverage.evaluatedRuleIds).length,
|
|
1219
1242
|
matched: coverage.matchedRuleIds.length,
|
|
1220
1243
|
unevaluated: coverage.unevaluatedRuleIds.length,
|
|
1221
1244
|
...(skillsRuleSet.registryCoverage
|
|
@@ -1235,9 +1258,14 @@ export async function runPlatformGate(params: {
|
|
|
1235
1258
|
: {}),
|
|
1236
1259
|
},
|
|
1237
1260
|
coverage_ratio:
|
|
1238
|
-
coverage.activeRuleIds.length === 0
|
|
1261
|
+
(coverageActiveRuleIds ?? coverage.activeRuleIds).length === 0
|
|
1239
1262
|
? 1
|
|
1240
|
-
: Number(
|
|
1263
|
+
: Number(
|
|
1264
|
+
(
|
|
1265
|
+
(coverageEvaluatedRuleIds ?? coverage.evaluatedRuleIds).length /
|
|
1266
|
+
(coverageActiveRuleIds ?? coverage.activeRuleIds).length
|
|
1267
|
+
).toFixed(6)
|
|
1268
|
+
),
|
|
1241
1269
|
}
|
|
1242
1270
|
: createEmptySnapshotRulesCoverage(params.policy.stage);
|
|
1243
1271
|
const brownfieldHotspotFindings = dependencies.evaluateBrownfieldHotspotFindings({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pumuki",
|
|
3
|
-
"version": "6.3.
|
|
3
|
+
"version": "6.3.282",
|
|
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": {
|