pumuki 6.3.127 → 6.3.128
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/VERSION +1 -1
- package/integrations/config/skillsRuleSet.ts +48 -29
- package/integrations/evidence/rulesCoverage.ts +41 -0
- package/integrations/evidence/schema.ts +14 -0
- package/integrations/git/runPlatformGate.ts +24 -0
- package/integrations/lifecycle/audit.ts +51 -1
- package/package.json +1 -1
- package/scripts/framework-menu-consumer-actions-lib.ts +1 -1
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
v6.3.
|
|
1
|
+
v6.3.128
|
|
@@ -21,13 +21,25 @@ export type SkillsRuleSetLoadResult = {
|
|
|
21
21
|
mappedHeuristicRuleIds: ReadonlySet<string>;
|
|
22
22
|
requiresHeuristicFacts: boolean;
|
|
23
23
|
unsupportedAutoRuleIds?: ReadonlyArray<string>;
|
|
24
|
+
registryCoverage?: {
|
|
25
|
+
contract: 'AUTO_RUNTIME_RULES_FOR_STAGE';
|
|
26
|
+
stage: Exclude<GateStage, 'STAGED'>;
|
|
27
|
+
registryTotals: {
|
|
28
|
+
total: number;
|
|
29
|
+
auto: number;
|
|
30
|
+
declarative: number;
|
|
31
|
+
};
|
|
32
|
+
stageApplicableAutoRuleIds: ReadonlyArray<string>;
|
|
33
|
+
declarativeRuleIds: ReadonlyArray<string>;
|
|
34
|
+
excludedDeclarativeReason: string;
|
|
35
|
+
};
|
|
24
36
|
};
|
|
25
37
|
|
|
26
38
|
const STAGE_RANK: Record<Exclude<GateStage, 'STAGED'>, number> = {
|
|
27
|
-
PRE_WRITE:
|
|
28
|
-
PRE_COMMIT:
|
|
39
|
+
PRE_WRITE: 10,
|
|
40
|
+
PRE_COMMIT: 20,
|
|
29
41
|
PRE_PUSH: 30,
|
|
30
|
-
CI:
|
|
42
|
+
CI: 40,
|
|
31
43
|
};
|
|
32
44
|
|
|
33
45
|
const PLATFORM_KEYS: ReadonlyArray<keyof DetectedPlatforms> = [
|
|
@@ -445,31 +457,7 @@ const toRuleDefinition = (params: {
|
|
|
445
457
|
};
|
|
446
458
|
}
|
|
447
459
|
|
|
448
|
-
|
|
449
|
-
// excluded from runtime rule conversion and reported separately.
|
|
450
|
-
return {
|
|
451
|
-
id: params.rule.id,
|
|
452
|
-
description: params.rule.description,
|
|
453
|
-
severity,
|
|
454
|
-
platform: params.rule.platform,
|
|
455
|
-
locked: params.rule.locked ?? true,
|
|
456
|
-
confidence: params.rule.confidence,
|
|
457
|
-
when: {
|
|
458
|
-
kind: 'FileContent',
|
|
459
|
-
regex: ['a^'],
|
|
460
|
-
},
|
|
461
|
-
then: {
|
|
462
|
-
kind: 'Finding',
|
|
463
|
-
message: `[Declarative] ${params.rule.description}`,
|
|
464
|
-
code: `${toCode(params.rule.id)}_DECLARATIVE`,
|
|
465
|
-
source: runtimeIrSource,
|
|
466
|
-
},
|
|
467
|
-
scope: resolveScopeForPlatform(
|
|
468
|
-
params.rule.platform,
|
|
469
|
-
params.repoRoot,
|
|
470
|
-
params.observedFilePaths
|
|
471
|
-
),
|
|
472
|
-
};
|
|
460
|
+
return undefined;
|
|
473
461
|
};
|
|
474
462
|
|
|
475
463
|
const hasDetectedPlatforms = (detectedPlatforms?: DetectedPlatforms): boolean => {
|
|
@@ -546,11 +534,23 @@ export const loadSkillsRuleSetForStage = (
|
|
|
546
534
|
const rulesById = new Map<string, RuleDefinition>();
|
|
547
535
|
const mappedHeuristicRuleIds = new Set<string>();
|
|
548
536
|
const unsupportedAutoRuleIds = new Set<string>();
|
|
537
|
+
const registryRuleIds = new Set<string>();
|
|
538
|
+
const registryAutoRuleIds = new Set<string>();
|
|
539
|
+
const registryDeclarativeRuleIds = new Set<string>();
|
|
540
|
+
const stageApplicableAutoRuleIds = new Set<string>();
|
|
549
541
|
|
|
550
542
|
for (const bundle of activeBundles) {
|
|
551
543
|
const bundlePolicy = policy?.bundles[bundle.name];
|
|
552
544
|
|
|
553
545
|
for (const compiledRule of bundle.rules) {
|
|
546
|
+
registryRuleIds.add(compiledRule.id);
|
|
547
|
+
const evaluationMode = resolveRuleEvaluationMode(compiledRule);
|
|
548
|
+
if (evaluationMode === 'AUTO') {
|
|
549
|
+
registryAutoRuleIds.add(compiledRule.id);
|
|
550
|
+
} else {
|
|
551
|
+
registryDeclarativeRuleIds.add(compiledRule.id);
|
|
552
|
+
}
|
|
553
|
+
|
|
554
554
|
if (
|
|
555
555
|
!isRulePlatformActive({
|
|
556
556
|
rule: compiledRule,
|
|
@@ -561,7 +561,13 @@ export const loadSkillsRuleSetForStage = (
|
|
|
561
561
|
}
|
|
562
562
|
|
|
563
563
|
const mappedRuleIds = resolveMappedHeuristicRuleIdsForCompiledRule(compiledRule);
|
|
564
|
-
|
|
564
|
+
if (!stageApplies(stage, compiledRule.stage)) {
|
|
565
|
+
continue;
|
|
566
|
+
}
|
|
567
|
+
if (evaluationMode !== 'AUTO') {
|
|
568
|
+
continue;
|
|
569
|
+
}
|
|
570
|
+
stageApplicableAutoRuleIds.add(compiledRule.id);
|
|
565
571
|
if (evaluationMode === 'AUTO' && mappedRuleIds.length === 0) {
|
|
566
572
|
unsupportedAutoRuleIds.add(compiledRule.id);
|
|
567
573
|
continue;
|
|
@@ -596,5 +602,18 @@ export const loadSkillsRuleSetForStage = (
|
|
|
596
602
|
mappedHeuristicRuleIds,
|
|
597
603
|
requiresHeuristicFacts: mappedHeuristicRuleIds.size > 0,
|
|
598
604
|
unsupportedAutoRuleIds: [...unsupportedAutoRuleIds].sort(),
|
|
605
|
+
registryCoverage: {
|
|
606
|
+
contract: 'AUTO_RUNTIME_RULES_FOR_STAGE',
|
|
607
|
+
stage,
|
|
608
|
+
registryTotals: {
|
|
609
|
+
total: registryRuleIds.size,
|
|
610
|
+
auto: registryAutoRuleIds.size,
|
|
611
|
+
declarative: registryDeclarativeRuleIds.size,
|
|
612
|
+
},
|
|
613
|
+
stageApplicableAutoRuleIds: [...stageApplicableAutoRuleIds].sort(),
|
|
614
|
+
declarativeRuleIds: [...registryDeclarativeRuleIds].sort(),
|
|
615
|
+
excludedDeclarativeReason:
|
|
616
|
+
'DECLARATIVE skills are registry contract/policy rules. They are not executed as PRE_COMMIT runtime detectors; only AUTO rules applicable to the current stage are evaluated.',
|
|
617
|
+
},
|
|
599
618
|
};
|
|
600
619
|
};
|
|
@@ -34,6 +34,9 @@ export const createEmptySnapshotRulesCoverage = (
|
|
|
34
34
|
stage: GateStage
|
|
35
35
|
): SnapshotRulesCoverage => ({
|
|
36
36
|
stage,
|
|
37
|
+
contract: 'AUTO_RUNTIME_RULES_FOR_STAGE',
|
|
38
|
+
scope_note:
|
|
39
|
+
'No runtime rules were evaluated for this stage. DECLARATIVE registry rules are not runtime detectors.',
|
|
37
40
|
active_rule_ids: [],
|
|
38
41
|
evaluated_rule_ids: [],
|
|
39
42
|
matched_rule_ids: [],
|
|
@@ -60,6 +63,11 @@ export const normalizeSnapshotRulesCoverage = (
|
|
|
60
63
|
const matchedRuleIds = normalizeStringArray(value.matched_rule_ids);
|
|
61
64
|
const unevaluatedRuleIds = normalizeStringArray(value.unevaluated_rule_ids);
|
|
62
65
|
const unsupportedAutoRuleIds = normalizeStringArray(value.unsupported_auto_rule_ids ?? []);
|
|
66
|
+
const stageApplicableAutoRuleIds = normalizeStringArray(
|
|
67
|
+
value.stage_applicable_auto_rule_ids ?? []
|
|
68
|
+
);
|
|
69
|
+
const declarativeRuleIds = normalizeStringArray(value.declarative_rule_ids ?? []);
|
|
70
|
+
const registryTotals = value.registry_totals;
|
|
63
71
|
|
|
64
72
|
const derivedCounts = {
|
|
65
73
|
active: activeRuleIds.length,
|
|
@@ -83,6 +91,15 @@ export const normalizeSnapshotRulesCoverage = (
|
|
|
83
91
|
),
|
|
84
92
|
};
|
|
85
93
|
|
|
94
|
+
if (registryTotals) {
|
|
95
|
+
counts.registry_total = normalizeCount(registryTotals.total);
|
|
96
|
+
counts.registry_auto = normalizeCount(registryTotals.auto);
|
|
97
|
+
counts.registry_declarative = normalizeCount(registryTotals.declarative);
|
|
98
|
+
}
|
|
99
|
+
if (stageApplicableAutoRuleIds.length > 0) {
|
|
100
|
+
counts.stage_applicable_auto = stageApplicableAutoRuleIds.length;
|
|
101
|
+
}
|
|
102
|
+
|
|
86
103
|
if (unsupportedAutoCount > 0) {
|
|
87
104
|
counts.unsupported_auto = unsupportedAutoCount;
|
|
88
105
|
}
|
|
@@ -94,6 +111,10 @@ export const normalizeSnapshotRulesCoverage = (
|
|
|
94
111
|
|
|
95
112
|
const normalized: SnapshotRulesCoverage = {
|
|
96
113
|
stage,
|
|
114
|
+
contract: value.contract ?? 'AUTO_RUNTIME_RULES_FOR_STAGE',
|
|
115
|
+
scope_note:
|
|
116
|
+
value.scope_note ??
|
|
117
|
+
'rules_coverage reports AUTO runtime rules applicable to this stage, not total DECLARATIVE registry surface.',
|
|
97
118
|
active_rule_ids: activeRuleIds,
|
|
98
119
|
evaluated_rule_ids: evaluatedRuleIds,
|
|
99
120
|
matched_rule_ids: matchedRuleIds,
|
|
@@ -102,6 +123,26 @@ export const normalizeSnapshotRulesCoverage = (
|
|
|
102
123
|
coverage_ratio: coverageRatio,
|
|
103
124
|
};
|
|
104
125
|
|
|
126
|
+
if (registryTotals) {
|
|
127
|
+
normalized.registry_totals = {
|
|
128
|
+
total: normalizeCount(registryTotals.total),
|
|
129
|
+
auto: normalizeCount(registryTotals.auto),
|
|
130
|
+
declarative: normalizeCount(registryTotals.declarative),
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (stageApplicableAutoRuleIds.length > 0) {
|
|
135
|
+
normalized.stage_applicable_auto_rule_ids = stageApplicableAutoRuleIds;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (declarativeRuleIds.length > 0) {
|
|
139
|
+
normalized.declarative_rule_ids = declarativeRuleIds;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (typeof value.declarative_excluded_reason === 'string') {
|
|
143
|
+
normalized.declarative_excluded_reason = value.declarative_excluded_reason;
|
|
144
|
+
}
|
|
145
|
+
|
|
105
146
|
if (unsupportedAutoRuleIds.length > 0 || unsupportedAutoCount > 0) {
|
|
106
147
|
normalized.unsupported_auto_rule_ids = unsupportedAutoRuleIds;
|
|
107
148
|
}
|
|
@@ -47,16 +47,30 @@ export type SnapshotEvaluationMetrics = {
|
|
|
47
47
|
|
|
48
48
|
export type SnapshotRulesCoverage = {
|
|
49
49
|
stage: GateStage;
|
|
50
|
+
contract?: 'AUTO_RUNTIME_RULES_FOR_STAGE';
|
|
51
|
+
scope_note?: string;
|
|
50
52
|
active_rule_ids: string[];
|
|
51
53
|
evaluated_rule_ids: string[];
|
|
52
54
|
matched_rule_ids: string[];
|
|
53
55
|
unevaluated_rule_ids: string[];
|
|
54
56
|
unsupported_auto_rule_ids?: string[];
|
|
57
|
+
registry_totals?: {
|
|
58
|
+
total: number;
|
|
59
|
+
auto: number;
|
|
60
|
+
declarative: number;
|
|
61
|
+
};
|
|
62
|
+
stage_applicable_auto_rule_ids?: string[];
|
|
63
|
+
declarative_rule_ids?: string[];
|
|
64
|
+
declarative_excluded_reason?: string;
|
|
55
65
|
counts: {
|
|
56
66
|
active: number;
|
|
57
67
|
evaluated: number;
|
|
58
68
|
matched: number;
|
|
59
69
|
unevaluated: number;
|
|
70
|
+
registry_total?: number;
|
|
71
|
+
registry_auto?: number;
|
|
72
|
+
registry_declarative?: number;
|
|
73
|
+
stage_applicable_auto?: number;
|
|
60
74
|
unsupported_auto?: number;
|
|
61
75
|
};
|
|
62
76
|
coverage_ratio: number;
|
|
@@ -1115,10 +1115,24 @@ export async function runPlatformGate(params: {
|
|
|
1115
1115
|
const rulesCoverage = coverage
|
|
1116
1116
|
? {
|
|
1117
1117
|
stage: params.policy.stage,
|
|
1118
|
+
contract: skillsRuleSet.registryCoverage?.contract ?? 'AUTO_RUNTIME_RULES_FOR_STAGE',
|
|
1119
|
+
scope_note:
|
|
1120
|
+
'rules_coverage reports AUTO runtime rules applicable to this stage; it does not claim full DECLARATIVE registry execution.',
|
|
1118
1121
|
active_rule_ids: [...coverage.activeRuleIds],
|
|
1119
1122
|
evaluated_rule_ids: [...coverage.evaluatedRuleIds],
|
|
1120
1123
|
matched_rule_ids: [...coverage.matchedRuleIds],
|
|
1121
1124
|
unevaluated_rule_ids: [...coverage.unevaluatedRuleIds],
|
|
1125
|
+
...(skillsRuleSet.registryCoverage
|
|
1126
|
+
? {
|
|
1127
|
+
registry_totals: skillsRuleSet.registryCoverage.registryTotals,
|
|
1128
|
+
stage_applicable_auto_rule_ids: [
|
|
1129
|
+
...skillsRuleSet.registryCoverage.stageApplicableAutoRuleIds,
|
|
1130
|
+
],
|
|
1131
|
+
declarative_rule_ids: [...skillsRuleSet.registryCoverage.declarativeRuleIds],
|
|
1132
|
+
declarative_excluded_reason:
|
|
1133
|
+
skillsRuleSet.registryCoverage.excludedDeclarativeReason,
|
|
1134
|
+
}
|
|
1135
|
+
: {}),
|
|
1122
1136
|
...((skillsRuleSet.unsupportedAutoRuleIds?.length ?? 0) > 0
|
|
1123
1137
|
? {
|
|
1124
1138
|
unsupported_auto_rule_ids: [...(skillsRuleSet.unsupportedAutoRuleIds ?? [])],
|
|
@@ -1129,6 +1143,16 @@ export async function runPlatformGate(params: {
|
|
|
1129
1143
|
evaluated: coverage.evaluatedRuleIds.length,
|
|
1130
1144
|
matched: coverage.matchedRuleIds.length,
|
|
1131
1145
|
unevaluated: coverage.unevaluatedRuleIds.length,
|
|
1146
|
+
...(skillsRuleSet.registryCoverage
|
|
1147
|
+
? {
|
|
1148
|
+
registry_total: skillsRuleSet.registryCoverage.registryTotals.total,
|
|
1149
|
+
registry_auto: skillsRuleSet.registryCoverage.registryTotals.auto,
|
|
1150
|
+
registry_declarative:
|
|
1151
|
+
skillsRuleSet.registryCoverage.registryTotals.declarative,
|
|
1152
|
+
stage_applicable_auto:
|
|
1153
|
+
skillsRuleSet.registryCoverage.stageApplicableAutoRuleIds.length,
|
|
1154
|
+
}
|
|
1155
|
+
: {}),
|
|
1132
1156
|
...((skillsRuleSet.unsupportedAutoRuleIds?.length ?? 0) > 0
|
|
1133
1157
|
? {
|
|
1134
1158
|
unsupported_auto: (skillsRuleSet.unsupportedAutoRuleIds ?? []).length,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { readEvidence } from '../evidence/readEvidence';
|
|
2
|
-
import type { AiEvidenceV2_1, SnapshotFinding } from '../evidence/schema';
|
|
2
|
+
import type { AiEvidenceV2_1, SnapshotFinding, SnapshotRulesCoverage } from '../evidence/schema';
|
|
3
3
|
import { GitService, type IGitService } from '../git/GitService';
|
|
4
4
|
import { hasAllowedExtension } from '../git/gitDiffUtils';
|
|
5
5
|
import { runPlatformGate } from '../git/runPlatformGate';
|
|
@@ -31,6 +31,18 @@ export type LifecycleAuditResult = {
|
|
|
31
31
|
snapshot_outcome: string | null;
|
|
32
32
|
findings_count: number;
|
|
33
33
|
blocking_findings_count: number;
|
|
34
|
+
rules_coverage: SnapshotRulesCoverage | null;
|
|
35
|
+
rule_id_normalization: {
|
|
36
|
+
contract: 'registry_or_declared_runtime_normalization';
|
|
37
|
+
registry_rule_ids_count: number;
|
|
38
|
+
finding_rule_ids_count: number;
|
|
39
|
+
entries: ReadonlyArray<{
|
|
40
|
+
runtime_rule_id: string;
|
|
41
|
+
registry_rule_id: string | null;
|
|
42
|
+
status: 'registry_1_to_1' | 'runtime_derived';
|
|
43
|
+
normalization: string;
|
|
44
|
+
}>;
|
|
45
|
+
};
|
|
34
46
|
findings: ReadonlyArray<LifecycleAuditFinding>;
|
|
35
47
|
policy_reconcile_hint: string;
|
|
36
48
|
};
|
|
@@ -114,6 +126,39 @@ const extractAuditFindings = (params: {
|
|
|
114
126
|
return [];
|
|
115
127
|
};
|
|
116
128
|
|
|
129
|
+
const buildRuleIdNormalization = (params: {
|
|
130
|
+
findings: ReadonlyArray<LifecycleAuditFinding>;
|
|
131
|
+
rulesCoverage: SnapshotRulesCoverage | undefined;
|
|
132
|
+
}): LifecycleAuditResult['rule_id_normalization'] => {
|
|
133
|
+
const registryRuleIds = new Set([
|
|
134
|
+
...(params.rulesCoverage?.stage_applicable_auto_rule_ids ?? []),
|
|
135
|
+
...(params.rulesCoverage?.declarative_rule_ids ?? []),
|
|
136
|
+
]);
|
|
137
|
+
const findingRuleIds = [...new Set(params.findings.map((finding) => finding.ruleId))].sort();
|
|
138
|
+
return {
|
|
139
|
+
contract: 'registry_or_declared_runtime_normalization',
|
|
140
|
+
registry_rule_ids_count: registryRuleIds.size,
|
|
141
|
+
finding_rule_ids_count: findingRuleIds.length,
|
|
142
|
+
entries: findingRuleIds.map((ruleId) => {
|
|
143
|
+
if (registryRuleIds.has(ruleId)) {
|
|
144
|
+
return {
|
|
145
|
+
runtime_rule_id: ruleId,
|
|
146
|
+
registry_rule_id: ruleId,
|
|
147
|
+
status: 'registry_1_to_1',
|
|
148
|
+
normalization: 'finding ruleId is an exact skills registry rule id',
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
return {
|
|
152
|
+
runtime_rule_id: ruleId,
|
|
153
|
+
registry_rule_id: null,
|
|
154
|
+
status: 'runtime_derived',
|
|
155
|
+
normalization:
|
|
156
|
+
'finding ruleId is emitted by baseline/runtime governance outside the skills registry; see rules_coverage for the AUTO skills scope evaluated at this stage',
|
|
157
|
+
};
|
|
158
|
+
}),
|
|
159
|
+
};
|
|
160
|
+
};
|
|
161
|
+
|
|
117
162
|
export const runLifecycleAudit = async (params: {
|
|
118
163
|
stage: LifecycleAuditStage;
|
|
119
164
|
auditMode: 'gate' | 'engine';
|
|
@@ -192,6 +237,11 @@ export const runLifecycleAudit = async (params: {
|
|
|
192
237
|
snapshot_outcome: snapshotOutcome,
|
|
193
238
|
findings_count: findings.length,
|
|
194
239
|
blocking_findings_count: findings.filter((finding) => finding.blocking).length,
|
|
240
|
+
rules_coverage: evidence?.snapshot.rules_coverage ?? null,
|
|
241
|
+
rule_id_normalization: buildRuleIdNormalization({
|
|
242
|
+
findings,
|
|
243
|
+
rulesCoverage: evidence?.snapshot.rules_coverage,
|
|
244
|
+
}),
|
|
195
245
|
findings,
|
|
196
246
|
policy_reconcile_hint: POLICY_RECONCILE_HINT,
|
|
197
247
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pumuki",
|
|
3
|
-
"version": "6.3.
|
|
3
|
+
"version": "6.3.128",
|
|
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": {
|
|
@@ -61,7 +61,7 @@ export const createConsumerLegacyMenuActions = (
|
|
|
61
61
|
},
|
|
62
62
|
{
|
|
63
63
|
id: '14',
|
|
64
|
-
label: 'Engine audit ·
|
|
64
|
+
label: 'Engine audit · tracked repo files (AUTO runtime rules · PRE_COMMIT)',
|
|
65
65
|
execute: params.runEngineFullRepoNoPreflight,
|
|
66
66
|
},
|
|
67
67
|
{
|