pumuki 6.3.72 → 6.3.75
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/docs/README.md +9 -7
- package/docs/operations/RELEASE_NOTES.md +0 -7
- package/docs/product/USAGE.md +2 -5
- package/docs/validation/README.md +3 -1
- package/integrations/evidence/buildEvidence.ts +14 -0
- package/integrations/evidence/repoState.ts +3 -0
- package/integrations/evidence/schema.ts +18 -0
- package/integrations/evidence/trackingContract.ts +146 -0
- package/integrations/evidence/writeEvidence.ts +14 -0
- package/integrations/gate/evaluateAiGate.ts +166 -3
- package/integrations/gate/governanceActionCatalog.ts +275 -0
- package/integrations/gate/remediationCatalog.ts +8 -0
- package/integrations/git/GitService.ts +0 -25
- package/integrations/git/aiGateRepoPolicyFindings.ts +4 -0
- package/integrations/git/runPlatformGate.ts +9 -1
- package/integrations/git/runPlatformGateFacts.ts +0 -7
- package/integrations/git/runPlatformGateOutput.ts +36 -27
- package/integrations/lifecycle/adapter.ts +24 -0
- package/integrations/lifecycle/bootstrapManifest.ts +248 -0
- package/integrations/lifecycle/cli.ts +45 -11
- package/integrations/lifecycle/cliSdd.ts +4 -3
- package/integrations/lifecycle/doctor.ts +49 -1
- package/integrations/lifecycle/governanceNextAction.ts +164 -0
- package/integrations/lifecycle/governanceObservationSnapshot.ts +315 -0
- package/integrations/lifecycle/install.ts +21 -0
- package/integrations/lifecycle/state.ts +8 -1
- package/integrations/lifecycle/status.ts +29 -2
- package/integrations/mcp/aiGateCheck.ts +140 -10
- package/integrations/mcp/alignedPlatformGate.ts +232 -0
- package/integrations/mcp/autoExecuteAiStart.ts +92 -85
- package/integrations/mcp/enterpriseServer.ts +6 -6
- package/integrations/mcp/preFlightCheck.ts +51 -5
- package/integrations/mcp/readMcpPrePushStdin.ts +7 -0
- package/integrations/policy/experimentalFeatures.ts +1 -1
- package/package.json +2 -4
- package/scripts/build-ruralgo-s1-evidence-pack.ts +85 -0
- package/scripts/consumer-menu-matrix-baseline-report-lib.ts +38 -13
- package/scripts/framework-menu-consumer-actions-lib.ts +4 -28
- package/scripts/framework-menu-consumer-preflight-hints.ts +2 -5
- package/scripts/framework-menu-consumer-preflight-render.ts +6 -0
- package/scripts/framework-menu-consumer-preflight-run.ts +19 -0
- package/scripts/framework-menu-consumer-preflight-types.ts +8 -0
- package/scripts/framework-menu-consumer-runtime-actions.ts +6 -86
- package/scripts/framework-menu-consumer-runtime-audit.ts +2 -36
- package/scripts/framework-menu-consumer-runtime-lib.ts +0 -2
- package/scripts/framework-menu-consumer-runtime-types.ts +1 -3
- package/scripts/framework-menu-evidence-summary-lib.ts +0 -1
- package/scripts/framework-menu-evidence-summary-read.ts +5 -57
- package/scripts/framework-menu-evidence-summary-severity.ts +1 -3
- package/scripts/framework-menu-evidence-summary-types.ts +0 -7
- package/scripts/framework-menu-gate-lib.ts +0 -9
- package/scripts/framework-menu-layout-data.ts +0 -5
- package/scripts/framework-menu-matrix-baseline-lib.ts +14 -15
- package/scripts/framework-menu-matrix-canary-lib.ts +1 -22
- package/scripts/framework-menu-matrix-evidence-lib.ts +0 -1
- package/scripts/framework-menu-matrix-evidence-types.ts +1 -13
- package/scripts/framework-menu-matrix-runner-lib.ts +0 -35
- package/scripts/framework-menu-system-notifications-macos.ts +0 -4
- package/scripts/framework-menu.ts +0 -3
- package/scripts/ruralgo-s1-evidence-pack-lib.ts +200 -0
- package/AGENTS.md +0 -269
- package/CHANGELOG.md +0 -666
- package/docs/tracking/plan-curso-pumuki-stack-my-architecture.md +0 -111
- package/scripts/framework-menu-consumer-runtime-evidence-classic.ts +0 -140
|
@@ -1,11 +1,14 @@
|
|
|
1
|
+
import {
|
|
2
|
+
resolveGovernanceCatalogAction,
|
|
3
|
+
type GovernanceCatalogNextAction,
|
|
4
|
+
} from '../gate/governanceActionCatalog';
|
|
1
5
|
import { evaluateAiGate, type AiGateStage, type AiGateViolation } from '../gate/evaluateAiGate';
|
|
2
6
|
import { collectWorktreeAtomicSlices } from '../git/worktreeAtomicSlices';
|
|
3
7
|
import { resolveLearningContextExperimentalFeature } from '../policy/experimentalFeatures';
|
|
4
8
|
import { readSddLearningContext, type SddLearningContext } from '../sdd/learningInsights';
|
|
5
9
|
|
|
6
10
|
const ACTIONABLE_HINTS_BY_CODE: Readonly<Record<string, string>> = {
|
|
7
|
-
EVIDENCE_MISSING:
|
|
8
|
-
'Ejecuta una auditoría (1/2/3/4 u opciones de motor 11–14) para regenerar .ai_evidence.json.',
|
|
11
|
+
EVIDENCE_MISSING: 'Ejecuta una auditoría (1/2/3/4) para regenerar .ai_evidence.json.',
|
|
9
12
|
EVIDENCE_INVALID: 'Regenera .ai_evidence.json desde una opción de auditoría.',
|
|
10
13
|
EVIDENCE_INTEGRITY_MISSING: 'Refresca evidencia para regenerar metadatos de integridad.',
|
|
11
14
|
EVIDENCE_ACTIVE_RULE_IDS_EMPTY_FOR_CODE_CHANGES:
|
|
@@ -39,6 +42,28 @@ const ACTIONABLE_HINTS_BY_CODE: Readonly<Record<string, string>> = {
|
|
|
39
42
|
'Mapea todas las reglas AUTO a detectores AST antes de continuar.',
|
|
40
43
|
EVIDENCE_TIMESTAMP_FUTURE: 'Corrige la hora del sistema y regenera evidencia.',
|
|
41
44
|
GITFLOW_PROTECTED_BRANCH: 'Evita trabajo directo en ramas protegidas (usa feature/*).',
|
|
45
|
+
GITFLOW_BRANCH_NAMING_INVALID:
|
|
46
|
+
'La rama actual no cumple GitFlow. Usa feature/*, bugfix/*, hotfix/*, release/*, chore/*, refactor/* o docs/*.',
|
|
47
|
+
TRACKING_CANONICAL_SOURCE_CONFLICT:
|
|
48
|
+
'AGENTS.md y los README del repo no apuntan a la misma fuente canónica de tracking.',
|
|
49
|
+
TRACKING_CANONICAL_FILE_MISSING:
|
|
50
|
+
'El repo declara un MD de tracking canónico que ahora mismo no existe.',
|
|
51
|
+
TRACKING_CANONICAL_IN_PROGRESS_INVALID:
|
|
52
|
+
'El MD canónico de tracking debe dejar exactamente una task o fase en construcción.',
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const normalizeGovernanceCatalogCode = (code: string): string => {
|
|
56
|
+
switch (code) {
|
|
57
|
+
case 'EVIDENCE_INVALID':
|
|
58
|
+
case 'EVIDENCE_CHAIN_INVALID':
|
|
59
|
+
return 'EVIDENCE_INVALID_OR_CHAIN';
|
|
60
|
+
case 'GITFLOW_PROTECTED_BRANCH':
|
|
61
|
+
return 'GITFLOW_PROTECTED_BRANCH_CONTEXT';
|
|
62
|
+
case 'GITFLOW_BRANCH_NAMING_INVALID':
|
|
63
|
+
return 'GITFLOW_BRANCH_NAMING_INVALID_CONTEXT';
|
|
64
|
+
default:
|
|
65
|
+
return code;
|
|
66
|
+
}
|
|
42
67
|
};
|
|
43
68
|
|
|
44
69
|
const buildPreFlightHints = (params: {
|
|
@@ -115,6 +140,8 @@ export type EnterprisePreFlightCheckResult = {
|
|
|
115
140
|
phase: 'GREEN' | 'RED';
|
|
116
141
|
message: string;
|
|
117
142
|
instruction: string;
|
|
143
|
+
reason_code: string;
|
|
144
|
+
next_action: GovernanceCatalogNextAction;
|
|
118
145
|
stage: ReturnType<typeof evaluateAiGate>['stage'];
|
|
119
146
|
policy: ReturnType<typeof evaluateAiGate>['policy'];
|
|
120
147
|
violations: ReturnType<typeof evaluateAiGate>['violations'];
|
|
@@ -154,13 +181,30 @@ export const runEnterprisePreFlightCheck = (params: {
|
|
|
154
181
|
upstream: evaluation.repo_state.git.upstream,
|
|
155
182
|
learningContext,
|
|
156
183
|
});
|
|
184
|
+
const firstViolation = evaluation.violations[0];
|
|
185
|
+
const reasonCode = firstViolation?.code ?? 'READY';
|
|
186
|
+
const governanceAction = firstViolation
|
|
187
|
+
? resolveGovernanceCatalogAction({
|
|
188
|
+
code: normalizeGovernanceCatalogCode(firstViolation.code),
|
|
189
|
+
stage: evaluation.stage,
|
|
190
|
+
})
|
|
191
|
+
: resolveGovernanceCatalogAction({
|
|
192
|
+
code: 'READY',
|
|
193
|
+
stage: evaluation.stage,
|
|
194
|
+
});
|
|
157
195
|
const phase: 'GREEN' | 'RED' = evaluation.allowed ? 'GREEN' : 'RED';
|
|
158
196
|
const message = evaluation.allowed
|
|
159
197
|
? '✅ Pre-flight aprobado: puedes continuar con la implementación.'
|
|
160
|
-
: `🔴 Pre-flight bloqueado: corrige ${
|
|
161
|
-
const instruction = evaluation.allowed
|
|
198
|
+
: `🔴 Pre-flight bloqueado: corrige ${reasonCode} y vuelve a ejecutar.`;
|
|
199
|
+
const instruction = !firstViolation && evaluation.allowed
|
|
162
200
|
? 'Implementa el cambio mínimo para pasar en verde y vuelve a validar.'
|
|
163
|
-
:
|
|
201
|
+
: governanceAction.instruction;
|
|
202
|
+
const nextAction: GovernanceCatalogNextAction = evaluation.allowed
|
|
203
|
+
? {
|
|
204
|
+
kind: 'info',
|
|
205
|
+
message: governanceAction.next_action.message,
|
|
206
|
+
}
|
|
207
|
+
: governanceAction.next_action;
|
|
164
208
|
|
|
165
209
|
return {
|
|
166
210
|
tool: 'pre_flight_check',
|
|
@@ -173,6 +217,8 @@ export const runEnterprisePreFlightCheck = (params: {
|
|
|
173
217
|
phase,
|
|
174
218
|
message,
|
|
175
219
|
instruction,
|
|
220
|
+
reason_code: reasonCode,
|
|
221
|
+
next_action: nextAction,
|
|
176
222
|
stage: evaluation.stage,
|
|
177
223
|
policy: evaluation.policy,
|
|
178
224
|
violations: evaluation.violations,
|
|
@@ -40,7 +40,7 @@ type ExperimentalFeatureConfig = {
|
|
|
40
40
|
|
|
41
41
|
const EXPERIMENTAL_FEATURES: Record<ExperimentalFeatureId, ExperimentalFeatureConfig> = {
|
|
42
42
|
pre_write: {
|
|
43
|
-
defaultMode: '
|
|
43
|
+
defaultMode: 'strict',
|
|
44
44
|
activationVariable: 'PUMUKI_EXPERIMENTAL_PRE_WRITE',
|
|
45
45
|
legacyActivationVariable: 'PUMUKI_PREWRITE_ENFORCEMENT',
|
|
46
46
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pumuki",
|
|
3
|
-
"version": "6.3.
|
|
3
|
+
"version": "6.3.75",
|
|
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": {
|
|
@@ -149,6 +149,7 @@
|
|
|
149
149
|
"validation:lifecycle-smoke": "node --import tsx scripts/package-install-smoke.ts --mode=minimal",
|
|
150
150
|
"validation:contract-suite:enterprise": "node --import tsx scripts/run-enterprise-contract-suite.ts",
|
|
151
151
|
"validation:consumer-matrix-baseline": "node --import tsx scripts/build-consumer-menu-matrix-baseline.ts",
|
|
152
|
+
"validation:ruralgo-s1-evidence-pack": "npx --yes tsx@4.21.0 scripts/build-ruralgo-s1-evidence-pack.ts",
|
|
152
153
|
"validation:c020-benchmark": "node --import tsx scripts/run-c020-benchmark.ts",
|
|
153
154
|
"validation:clean-artifacts": "npx --yes tsx@4.21.0 scripts/clean-validation-artifacts.ts",
|
|
154
155
|
"skills:compile": "npx --yes tsx@4.21.0 scripts/compile-skills-lock.ts",
|
|
@@ -259,13 +260,10 @@
|
|
|
259
260
|
"docs/product/*.md",
|
|
260
261
|
"docs/rule-packs/*.md",
|
|
261
262
|
"docs/validation/*.md",
|
|
262
|
-
"docs/tracking/plan-curso-pumuki-stack-my-architecture.md",
|
|
263
263
|
"assets/**/*",
|
|
264
264
|
"vendor/skills/**/*",
|
|
265
265
|
"index.js",
|
|
266
266
|
"README.md",
|
|
267
|
-
"AGENTS.md",
|
|
268
|
-
"CHANGELOG.md",
|
|
269
267
|
"LICENSE",
|
|
270
268
|
"VERSION",
|
|
271
269
|
"tsconfig.json",
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import {
|
|
2
|
+
buildRuralGoS1EvidencePackMarkdown,
|
|
3
|
+
writeRuralGoS1EvidencePack,
|
|
4
|
+
} from './ruralgo-s1-evidence-pack-lib';
|
|
5
|
+
|
|
6
|
+
type CliOptions = {
|
|
7
|
+
consumerRoot: string;
|
|
8
|
+
outFile: string;
|
|
9
|
+
packageVersion: string;
|
|
10
|
+
generatedAt: string;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const parseArgs = (argv: ReadonlyArray<string>): CliOptions => {
|
|
14
|
+
const options: CliOptions = {
|
|
15
|
+
consumerRoot: '<RURALGO_REPO_ROOT>',
|
|
16
|
+
outFile: '.audit-reports/ruralgo-s1/ruralgo-s1-evidence-pack.md',
|
|
17
|
+
packageVersion: 'unknown',
|
|
18
|
+
generatedAt: new Date().toISOString(),
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
22
|
+
const token = argv[index];
|
|
23
|
+
const next = argv[index + 1];
|
|
24
|
+
switch (token) {
|
|
25
|
+
case '--consumer-root':
|
|
26
|
+
if (!next) {
|
|
27
|
+
throw new Error('missing value for --consumer-root');
|
|
28
|
+
}
|
|
29
|
+
options.consumerRoot = next;
|
|
30
|
+
index += 1;
|
|
31
|
+
break;
|
|
32
|
+
case '--out':
|
|
33
|
+
if (!next) {
|
|
34
|
+
throw new Error('missing value for --out');
|
|
35
|
+
}
|
|
36
|
+
options.outFile = next;
|
|
37
|
+
index += 1;
|
|
38
|
+
break;
|
|
39
|
+
case '--package-version':
|
|
40
|
+
if (!next) {
|
|
41
|
+
throw new Error('missing value for --package-version');
|
|
42
|
+
}
|
|
43
|
+
options.packageVersion = next;
|
|
44
|
+
index += 1;
|
|
45
|
+
break;
|
|
46
|
+
case '--generated-at':
|
|
47
|
+
if (!next) {
|
|
48
|
+
throw new Error('missing value for --generated-at');
|
|
49
|
+
}
|
|
50
|
+
options.generatedAt = next;
|
|
51
|
+
index += 1;
|
|
52
|
+
break;
|
|
53
|
+
default:
|
|
54
|
+
throw new Error(`unknown argument: ${token}`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return options;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const main = (): number => {
|
|
62
|
+
const cwd = process.cwd();
|
|
63
|
+
const options = parseArgs(process.argv.slice(2));
|
|
64
|
+
const markdown = buildRuralGoS1EvidencePackMarkdown({
|
|
65
|
+
cwd,
|
|
66
|
+
consumerRoot: options.consumerRoot,
|
|
67
|
+
packageVersion: options.packageVersion,
|
|
68
|
+
generatedAt: options.generatedAt,
|
|
69
|
+
});
|
|
70
|
+
const outputPath = writeRuralGoS1EvidencePack({
|
|
71
|
+
cwd,
|
|
72
|
+
outFile: options.outFile,
|
|
73
|
+
markdown,
|
|
74
|
+
});
|
|
75
|
+
process.stdout.write(`ruralgo s1 evidence pack generated at ${outputPath}\n`);
|
|
76
|
+
return 0;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
try {
|
|
80
|
+
process.exitCode = main();
|
|
81
|
+
} catch (error) {
|
|
82
|
+
const message = error instanceof Error ? error.message : 'unknown error';
|
|
83
|
+
process.stderr.write(`ruralgo s1 evidence pack failed: ${message}\n`);
|
|
84
|
+
process.exitCode = 1;
|
|
85
|
+
}
|
|
@@ -4,11 +4,10 @@ import type {
|
|
|
4
4
|
ConsumerMenuMatrixReport,
|
|
5
5
|
MatrixOptionId,
|
|
6
6
|
} from './framework-menu-matrix-baseline-lib';
|
|
7
|
-
import { MATRIX_MENU_OPTION_IDS } from './framework-menu-matrix-evidence-lib';
|
|
8
7
|
import type { DoctorDeepCheckLayer, LifecycleDoctorReport } from '../integrations/lifecycle/doctor';
|
|
9
8
|
import type { LifecycleStatus } from '../integrations/lifecycle/status';
|
|
10
9
|
|
|
11
|
-
const OPTION_IDS: ReadonlyArray<MatrixOptionId> = [
|
|
10
|
+
const OPTION_IDS: ReadonlyArray<MatrixOptionId> = ['1', '2', '3', '4', '9'];
|
|
12
11
|
const DOCTOR_LAYERS: ReadonlyArray<DoctorDeepCheckLayer> = [
|
|
13
12
|
'core',
|
|
14
13
|
'operational',
|
|
@@ -52,19 +51,45 @@ export type ConsumerMenuMatrixBaselineSnapshot = {
|
|
|
52
51
|
};
|
|
53
52
|
};
|
|
54
53
|
|
|
55
|
-
const UNKNOWN_OPTION_REPORT = {
|
|
56
|
-
stage: 'UNKNOWN',
|
|
57
|
-
outcome: 'UNKNOWN',
|
|
58
|
-
filesScanned: 0,
|
|
59
|
-
totalViolations: 0,
|
|
60
|
-
diagnosis: 'unknown' as const,
|
|
61
|
-
};
|
|
62
|
-
|
|
63
54
|
const buildEmptyRound = (): ConsumerMenuMatrixReport => {
|
|
64
55
|
return {
|
|
65
|
-
byOption:
|
|
66
|
-
|
|
67
|
-
|
|
56
|
+
byOption: {
|
|
57
|
+
'1': {
|
|
58
|
+
stage: 'UNKNOWN',
|
|
59
|
+
outcome: 'UNKNOWN',
|
|
60
|
+
filesScanned: 0,
|
|
61
|
+
totalViolations: 0,
|
|
62
|
+
diagnosis: 'unknown',
|
|
63
|
+
},
|
|
64
|
+
'2': {
|
|
65
|
+
stage: 'UNKNOWN',
|
|
66
|
+
outcome: 'UNKNOWN',
|
|
67
|
+
filesScanned: 0,
|
|
68
|
+
totalViolations: 0,
|
|
69
|
+
diagnosis: 'unknown',
|
|
70
|
+
},
|
|
71
|
+
'3': {
|
|
72
|
+
stage: 'UNKNOWN',
|
|
73
|
+
outcome: 'UNKNOWN',
|
|
74
|
+
filesScanned: 0,
|
|
75
|
+
totalViolations: 0,
|
|
76
|
+
diagnosis: 'unknown',
|
|
77
|
+
},
|
|
78
|
+
'4': {
|
|
79
|
+
stage: 'UNKNOWN',
|
|
80
|
+
outcome: 'UNKNOWN',
|
|
81
|
+
filesScanned: 0,
|
|
82
|
+
totalViolations: 0,
|
|
83
|
+
diagnosis: 'unknown',
|
|
84
|
+
},
|
|
85
|
+
'9': {
|
|
86
|
+
stage: 'UNKNOWN',
|
|
87
|
+
outcome: 'UNKNOWN',
|
|
88
|
+
filesScanned: 0,
|
|
89
|
+
totalViolations: 0,
|
|
90
|
+
diagnosis: 'unknown',
|
|
91
|
+
},
|
|
92
|
+
},
|
|
68
93
|
};
|
|
69
94
|
};
|
|
70
95
|
|
|
@@ -9,10 +9,6 @@ export type ConsumerLegacyMenuContext = {
|
|
|
9
9
|
runStrictRepoAndStaged: () => Promise<void>;
|
|
10
10
|
runStrictStagedOnly: () => Promise<void>;
|
|
11
11
|
runStandardCriticalHigh: () => Promise<void>;
|
|
12
|
-
runEngineStagedNoPreflight: () => Promise<void>;
|
|
13
|
-
runEngineUnstagedNoPreflight: () => Promise<void>;
|
|
14
|
-
runEngineStagedAndUnstagedNoPreflight: () => Promise<void>;
|
|
15
|
-
runEngineFullRepoNoPreflight: () => Promise<void>;
|
|
16
12
|
runPatternChecks: () => Promise<void>;
|
|
17
13
|
runEslintAudit: () => Promise<void>;
|
|
18
14
|
runAstIntelligence: () => Promise<void>;
|
|
@@ -26,44 +22,24 @@ export const createConsumerLegacyMenuActions = (
|
|
|
26
22
|
return [
|
|
27
23
|
{
|
|
28
24
|
id: '1',
|
|
29
|
-
label: '
|
|
25
|
+
label: 'Read-only full audit (repo analysis · PRE_COMMIT)',
|
|
30
26
|
execute: params.runFullAudit,
|
|
31
27
|
},
|
|
32
28
|
{
|
|
33
29
|
id: '2',
|
|
34
|
-
label: '
|
|
30
|
+
label: 'Read-only strict REPO+STAGING (CI/CD · PRE_PUSH)',
|
|
35
31
|
execute: params.runStrictRepoAndStaged,
|
|
36
32
|
},
|
|
37
33
|
{
|
|
38
34
|
id: '3',
|
|
39
|
-
label: '
|
|
35
|
+
label: 'Read-only strict STAGING only (dev · PRE_COMMIT)',
|
|
40
36
|
execute: params.runStrictStagedOnly,
|
|
41
37
|
},
|
|
42
38
|
{
|
|
43
39
|
id: '4',
|
|
44
|
-
label: '
|
|
40
|
+
label: 'Read-only audit of STAGED+UNSTAGED working tree (PRE_PUSH policy)',
|
|
45
41
|
execute: params.runStandardCriticalHigh,
|
|
46
42
|
},
|
|
47
|
-
{
|
|
48
|
-
id: '11',
|
|
49
|
-
label: 'Engine audit · STAGED only (no preflight · PRE_COMMIT)',
|
|
50
|
-
execute: params.runEngineStagedNoPreflight,
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
id: '12',
|
|
54
|
-
label: 'Engine audit · UNSTAGED only (no preflight · PRE_COMMIT)',
|
|
55
|
-
execute: params.runEngineUnstagedNoPreflight,
|
|
56
|
-
},
|
|
57
|
-
{
|
|
58
|
-
id: '13',
|
|
59
|
-
label: 'Engine audit · STAGED + UNSTAGED (no preflight · PRE_COMMIT)',
|
|
60
|
-
execute: params.runEngineStagedAndUnstagedNoPreflight,
|
|
61
|
-
},
|
|
62
|
-
{
|
|
63
|
-
id: '14',
|
|
64
|
-
label: 'Engine audit · FULL tracked repo (no preflight · PRE_COMMIT)',
|
|
65
|
-
execute: params.runEngineFullRepoNoPreflight,
|
|
66
|
-
},
|
|
67
43
|
{
|
|
68
44
|
id: '5',
|
|
69
45
|
label: 'Legacy read-only pattern checks snapshot',
|
|
@@ -7,8 +7,7 @@ import type {
|
|
|
7
7
|
} from './framework-menu-consumer-preflight-types';
|
|
8
8
|
|
|
9
9
|
export const ACTIONABLE_HINTS_BY_CODE: Readonly<Record<string, string>> = {
|
|
10
|
-
EVIDENCE_MISSING:
|
|
11
|
-
'ejecuta una auditoría (1/2/3/4 o motor 11–14) para regenerar .ai_evidence.json.',
|
|
10
|
+
EVIDENCE_MISSING: 'ejecuta una auditoría (1/2/3/4) para regenerar .ai_evidence.json.',
|
|
12
11
|
EVIDENCE_INVALID: 'regenera .ai_evidence.json desde una opción de auditoría.',
|
|
13
12
|
EVIDENCE_STALE: 'refresca evidencia antes de continuar con commit/push.',
|
|
14
13
|
EVIDENCE_TIMESTAMP_INVALID: 'regenera evidencia para obtener un timestamp válido.',
|
|
@@ -55,9 +54,7 @@ export const buildConsumerPreflightHints = (
|
|
|
55
54
|
const actionableHintsByCode = resolveActionableHintsByCode(dependencies);
|
|
56
55
|
|
|
57
56
|
if (hasViolationCode(violations, 'EVIDENCE_MISSING')) {
|
|
58
|
-
hints.push(
|
|
59
|
-
'Evidence missing: ejecuta una auditoría (1/2/3/4 o motor 11–14) para regenerar .ai_evidence.json.'
|
|
60
|
-
);
|
|
57
|
+
hints.push('Evidence missing: ejecuta una auditoría (1/2/3/4) para regenerar .ai_evidence.json.');
|
|
61
58
|
handledCodes.add('EVIDENCE_MISSING');
|
|
62
59
|
}
|
|
63
60
|
if (hasViolationCode(violations, 'EVIDENCE_INVALID')) {
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { renderLegacyPanel, resolveLegacyPanelOuterWidth } from './framework-menu-legacy-audit-lib';
|
|
2
2
|
import { buildConsumerPreflightBlockingCauseLines } from './framework-menu-consumer-preflight-hints';
|
|
3
|
+
import { buildGovernanceNextActionSummaryLines } from '../integrations/lifecycle/governanceNextAction';
|
|
4
|
+
import { buildGovernanceObservationSummaryLines } from '../integrations/lifecycle/governanceObservationSnapshot';
|
|
3
5
|
import type {
|
|
4
6
|
ConsumerPreflightRenderOptions,
|
|
5
7
|
ConsumerPreflightResult,
|
|
@@ -19,6 +21,10 @@ const buildConsumerPreflightPanelLines = (
|
|
|
19
21
|
`Evidence source: source=${evidence.source.source} path=${evidence.source.path} digest=${evidence.source.digest ?? 'null'} generated_at=${evidence.source.generated_at ?? 'null'}`,
|
|
20
22
|
`Gate: ${preflight.status} (${preflight.result.violations.length} violations)`,
|
|
21
23
|
];
|
|
24
|
+
lines.push('', 'Governance truth:');
|
|
25
|
+
lines.push(...buildGovernanceObservationSummaryLines(preflight.governanceObservation));
|
|
26
|
+
lines.push('', 'Governance next action:');
|
|
27
|
+
lines.push(...buildGovernanceNextActionSummaryLines(preflight.governanceNextAction));
|
|
22
28
|
lines.push(...buildConsumerPreflightBlockingCauseLines(preflight));
|
|
23
29
|
|
|
24
30
|
if (preflight.hints.length > 0) {
|
|
@@ -2,6 +2,11 @@ import {
|
|
|
2
2
|
evaluateAiGate,
|
|
3
3
|
type AiGateCheckResult,
|
|
4
4
|
} from '../integrations/gate/evaluateAiGate';
|
|
5
|
+
import { readLifecycleExperimentalFeaturesSnapshot } from '../integrations/lifecycle/experimentalFeaturesSnapshot';
|
|
6
|
+
import { LifecycleGitService } from '../integrations/lifecycle/gitService';
|
|
7
|
+
import { readGovernanceObservationSnapshot } from '../integrations/lifecycle/governanceObservationSnapshot';
|
|
8
|
+
import { readGovernanceNextAction } from '../integrations/lifecycle/governanceNextAction';
|
|
9
|
+
import { readLifecyclePolicyValidationSnapshot } from '../integrations/lifecycle/policyValidationSnapshot';
|
|
5
10
|
import {
|
|
6
11
|
emitSystemNotification,
|
|
7
12
|
type PumukiCriticalNotificationEvent,
|
|
@@ -28,6 +33,7 @@ const defaultDependencies: ConsumerPreflightDependencies = {
|
|
|
28
33
|
event: params.event,
|
|
29
34
|
repoRoot: params.repoRoot,
|
|
30
35
|
}),
|
|
36
|
+
readGovernanceNextAction,
|
|
31
37
|
};
|
|
32
38
|
|
|
33
39
|
const buildNotificationEvents = (
|
|
@@ -86,6 +92,17 @@ export const runConsumerPreflight = (
|
|
|
86
92
|
repoRoot,
|
|
87
93
|
stage: params.stage,
|
|
88
94
|
});
|
|
95
|
+
const governanceObservation = readGovernanceObservationSnapshot({
|
|
96
|
+
repoRoot,
|
|
97
|
+
experimentalFeatures: readLifecycleExperimentalFeaturesSnapshot(),
|
|
98
|
+
policyValidation: readLifecyclePolicyValidationSnapshot(repoRoot),
|
|
99
|
+
git: new LifecycleGitService(),
|
|
100
|
+
});
|
|
101
|
+
const governanceNextAction = activeDependencies.readGovernanceNextAction({
|
|
102
|
+
repoRoot,
|
|
103
|
+
stage: params.stage,
|
|
104
|
+
governanceObservation,
|
|
105
|
+
});
|
|
89
106
|
const hints = buildConsumerPreflightHints(result, params.stage);
|
|
90
107
|
const notificationEvents = buildNotificationEvents(result);
|
|
91
108
|
const notificationResults = notificationEvents.map((event) =>
|
|
@@ -99,6 +116,8 @@ export const runConsumerPreflight = (
|
|
|
99
116
|
stage: params.stage,
|
|
100
117
|
status: result.status,
|
|
101
118
|
result,
|
|
119
|
+
governanceObservation,
|
|
120
|
+
governanceNextAction,
|
|
102
121
|
hints,
|
|
103
122
|
notificationResults,
|
|
104
123
|
};
|
|
@@ -2,6 +2,11 @@ import type {
|
|
|
2
2
|
AiGateCheckResult,
|
|
3
3
|
AiGateViolation,
|
|
4
4
|
} from '../integrations/gate/evaluateAiGate';
|
|
5
|
+
import type {
|
|
6
|
+
GovernanceNextActionReader,
|
|
7
|
+
GovernanceNextActionSummary,
|
|
8
|
+
} from '../integrations/lifecycle/governanceNextAction';
|
|
9
|
+
import type { GovernanceObservationSnapshot } from '../integrations/lifecycle/governanceObservationSnapshot';
|
|
5
10
|
import type {
|
|
6
11
|
PumukiCriticalNotificationEvent,
|
|
7
12
|
SystemNotificationEmitResult,
|
|
@@ -13,6 +18,8 @@ export type ConsumerPreflightResult = {
|
|
|
13
18
|
stage: ConsumerPreflightStage;
|
|
14
19
|
status: AiGateCheckResult['status'];
|
|
15
20
|
result: AiGateCheckResult;
|
|
21
|
+
governanceObservation: GovernanceObservationSnapshot;
|
|
22
|
+
governanceNextAction: GovernanceNextActionSummary;
|
|
16
23
|
hints: ReadonlyArray<string>;
|
|
17
24
|
notificationResults: ReadonlyArray<SystemNotificationEmitResult>;
|
|
18
25
|
};
|
|
@@ -26,6 +33,7 @@ export type ConsumerPreflightDependencies = {
|
|
|
26
33
|
event: PumukiCriticalNotificationEvent;
|
|
27
34
|
repoRoot: string;
|
|
28
35
|
}) => SystemNotificationEmitResult;
|
|
36
|
+
readGovernanceNextAction: GovernanceNextActionReader;
|
|
29
37
|
};
|
|
30
38
|
|
|
31
39
|
export type ConsumerPreflightRenderOptions = {
|
|
@@ -5,7 +5,6 @@ import {
|
|
|
5
5
|
exportConsumerRuntimeMarkdown,
|
|
6
6
|
notifyConsumerRuntimeAuditSummary,
|
|
7
7
|
printConsumerRuntimeEmptyScopeHint,
|
|
8
|
-
printPrePushTrackedEvidenceDiskHint,
|
|
9
8
|
renderConsumerRuntimeAstBreakdown,
|
|
10
9
|
renderConsumerRuntimeEslintAudit,
|
|
11
10
|
renderConsumerRuntimeFileDiagnostics,
|
|
@@ -21,9 +20,7 @@ type ConsumerRuntimeActionDependencies = {
|
|
|
21
20
|
runRepoGate: () => Promise<ConsumerRuntimeGateResult | void>;
|
|
22
21
|
runRepoAndStagedGate: () => Promise<ConsumerRuntimeGateResult | void>;
|
|
23
22
|
runStagedGate: () => Promise<ConsumerRuntimeGateResult | void>;
|
|
24
|
-
runUnstagedGate: () => Promise<ConsumerRuntimeGateResult | void>;
|
|
25
23
|
runWorkingTreeGate: () => Promise<ConsumerRuntimeGateResult | void>;
|
|
26
|
-
runWorkingTreePreCommitGate: () => Promise<ConsumerRuntimeGateResult | void>;
|
|
27
24
|
runPreflight?: (
|
|
28
25
|
stage: 'PRE_COMMIT' | 'PRE_PUSH'
|
|
29
26
|
) => Promise<string | void> | string | void;
|
|
@@ -91,25 +88,18 @@ export const createConsumerRuntimeActions = (
|
|
|
91
88
|
} else {
|
|
92
89
|
dependencies.clearSummaryOverride();
|
|
93
90
|
}
|
|
94
|
-
const summary = renderConsumerRuntimeSummary({
|
|
95
|
-
repoRoot: dependencies.repoRoot,
|
|
96
|
-
write: dependencies.write,
|
|
97
|
-
useColor: dependencies.useColor,
|
|
98
|
-
summaryOverride: dependencies.getSummaryOverride(),
|
|
99
|
-
});
|
|
100
91
|
notifyConsumerRuntimeAuditSummary(
|
|
101
92
|
{
|
|
102
93
|
emitNotification: dependencies.emitNotification,
|
|
103
94
|
repoRoot: dependencies.repoRoot,
|
|
104
95
|
},
|
|
105
|
-
|
|
96
|
+
renderConsumerRuntimeSummary({
|
|
97
|
+
repoRoot: dependencies.repoRoot,
|
|
98
|
+
write: dependencies.write,
|
|
99
|
+
useColor: dependencies.useColor,
|
|
100
|
+
summaryOverride: dependencies.getSummaryOverride(),
|
|
101
|
+
})
|
|
106
102
|
);
|
|
107
|
-
if (
|
|
108
|
-
!gateResult?.blocked
|
|
109
|
-
&& (summary.outcome === 'PASS' || summary.outcome === 'WARN')
|
|
110
|
-
) {
|
|
111
|
-
printPrePushTrackedEvidenceDiskHint({ write: dependencies.write });
|
|
112
|
-
}
|
|
113
103
|
},
|
|
114
104
|
runStrictStagedOnly: async () => {
|
|
115
105
|
await runConsumerRuntimePreflight(dependencies, 'PRE_COMMIT');
|
|
@@ -145,78 +135,8 @@ export const createConsumerRuntimeActions = (
|
|
|
145
135
|
},
|
|
146
136
|
summary
|
|
147
137
|
);
|
|
148
|
-
if (summary.outcome === 'PASS' || summary.outcome === 'WARN') {
|
|
149
|
-
printPrePushTrackedEvidenceDiskHint({ write: dependencies.write });
|
|
150
|
-
}
|
|
151
138
|
printConsumerRuntimeEmptyScopeHint({ write: dependencies.write }, summary, 'workingTree');
|
|
152
139
|
},
|
|
153
|
-
runEngineStagedNoPreflight: async () => {
|
|
154
|
-
await dependencies.runStagedGate();
|
|
155
|
-
dependencies.clearSummaryOverride();
|
|
156
|
-
const summary = renderConsumerRuntimeSummary({
|
|
157
|
-
repoRoot: dependencies.repoRoot,
|
|
158
|
-
write: dependencies.write,
|
|
159
|
-
useColor: dependencies.useColor,
|
|
160
|
-
});
|
|
161
|
-
notifyConsumerRuntimeAuditSummary(
|
|
162
|
-
{
|
|
163
|
-
emitNotification: dependencies.emitNotification,
|
|
164
|
-
repoRoot: dependencies.repoRoot,
|
|
165
|
-
},
|
|
166
|
-
summary
|
|
167
|
-
);
|
|
168
|
-
printConsumerRuntimeEmptyScopeHint({ write: dependencies.write }, summary, 'staged');
|
|
169
|
-
},
|
|
170
|
-
runEngineUnstagedNoPreflight: async () => {
|
|
171
|
-
await dependencies.runUnstagedGate();
|
|
172
|
-
dependencies.clearSummaryOverride();
|
|
173
|
-
const summary = renderConsumerRuntimeSummary({
|
|
174
|
-
repoRoot: dependencies.repoRoot,
|
|
175
|
-
write: dependencies.write,
|
|
176
|
-
useColor: dependencies.useColor,
|
|
177
|
-
});
|
|
178
|
-
notifyConsumerRuntimeAuditSummary(
|
|
179
|
-
{
|
|
180
|
-
emitNotification: dependencies.emitNotification,
|
|
181
|
-
repoRoot: dependencies.repoRoot,
|
|
182
|
-
},
|
|
183
|
-
summary
|
|
184
|
-
);
|
|
185
|
-
printConsumerRuntimeEmptyScopeHint({ write: dependencies.write }, summary, 'unstaged');
|
|
186
|
-
},
|
|
187
|
-
runEngineStagedAndUnstagedNoPreflight: async () => {
|
|
188
|
-
await dependencies.runWorkingTreePreCommitGate();
|
|
189
|
-
dependencies.clearSummaryOverride();
|
|
190
|
-
const summary = renderConsumerRuntimeSummary({
|
|
191
|
-
repoRoot: dependencies.repoRoot,
|
|
192
|
-
write: dependencies.write,
|
|
193
|
-
useColor: dependencies.useColor,
|
|
194
|
-
});
|
|
195
|
-
notifyConsumerRuntimeAuditSummary(
|
|
196
|
-
{
|
|
197
|
-
emitNotification: dependencies.emitNotification,
|
|
198
|
-
repoRoot: dependencies.repoRoot,
|
|
199
|
-
},
|
|
200
|
-
summary
|
|
201
|
-
);
|
|
202
|
-
printConsumerRuntimeEmptyScopeHint({ write: dependencies.write }, summary, 'workingTree');
|
|
203
|
-
},
|
|
204
|
-
runEngineFullRepoNoPreflight: async () => {
|
|
205
|
-
await dependencies.runRepoGate();
|
|
206
|
-
dependencies.clearSummaryOverride();
|
|
207
|
-
const summary = renderConsumerRuntimeSummary({
|
|
208
|
-
repoRoot: dependencies.repoRoot,
|
|
209
|
-
write: dependencies.write,
|
|
210
|
-
useColor: dependencies.useColor,
|
|
211
|
-
});
|
|
212
|
-
notifyConsumerRuntimeAuditSummary(
|
|
213
|
-
{
|
|
214
|
-
emitNotification: dependencies.emitNotification,
|
|
215
|
-
repoRoot: dependencies.repoRoot,
|
|
216
|
-
},
|
|
217
|
-
summary
|
|
218
|
-
);
|
|
219
|
-
},
|
|
220
140
|
runPatternChecks: async () => {
|
|
221
141
|
dependencies.write(`\n${renderConsumerRuntimePatternChecks(dependencies.repoRoot)}\n`);
|
|
222
142
|
},
|
|
@@ -14,7 +14,6 @@ import {
|
|
|
14
14
|
readEvidenceSummaryForMenu,
|
|
15
15
|
type FrameworkMenuEvidenceSummary,
|
|
16
16
|
} from './framework-menu-evidence-summary-lib';
|
|
17
|
-
import { renderVintageEvidenceReport } from './framework-menu-consumer-runtime-evidence-classic';
|
|
18
17
|
import type {
|
|
19
18
|
ConsumerRuntimeBlockedGate,
|
|
20
19
|
ConsumerRuntimeNotificationDependencies,
|
|
@@ -57,36 +56,9 @@ export const renderConsumerRuntimeSummary = (
|
|
|
57
56
|
width: resolveLegacyPanelOuterWidth(),
|
|
58
57
|
color: dependencies.useColor(),
|
|
59
58
|
})}\n`);
|
|
60
|
-
|
|
61
|
-
const vintageSource =
|
|
62
|
-
summary.status === 'ok' && !dependencies.summaryOverride
|
|
63
|
-
? readEvidenceSummaryForMenu(dependencies.repoRoot, {
|
|
64
|
-
topFindingsLimit: 45,
|
|
65
|
-
topFileLocationsLimit: 15,
|
|
66
|
-
topFilesLimit: 10,
|
|
67
|
-
})
|
|
68
|
-
: summary;
|
|
69
|
-
renderVintageEvidenceReport({
|
|
70
|
-
write: dependencies.write,
|
|
71
|
-
summary: vintageSource,
|
|
72
|
-
useColor: dependencies.useColor,
|
|
73
|
-
});
|
|
74
59
|
return summary;
|
|
75
60
|
};
|
|
76
61
|
|
|
77
|
-
export const printPrePushTrackedEvidenceDiskHint = (params: {
|
|
78
|
-
write: ConsumerRuntimeSummaryDependencies['write'];
|
|
79
|
-
}): void => {
|
|
80
|
-
params.write(
|
|
81
|
-
'\n' +
|
|
82
|
-
[
|
|
83
|
-
'ℹ PRE_PUSH + `.ai_evidence.json` tracked: on PASS/WARN the gate may skip rewriting the file on disk',
|
|
84
|
-
' (avoids dirty tracked evidence). Local dev: PUMUKI_PRE_PUSH_ALWAYS_WRITE_TRACKED_EVIDENCE=1 forces disk write.',
|
|
85
|
-
].join('\n') +
|
|
86
|
-
'\n'
|
|
87
|
-
);
|
|
88
|
-
};
|
|
89
|
-
|
|
90
62
|
export const buildConsumerRuntimeBlockedSummary = (
|
|
91
63
|
blocked: ConsumerRuntimeBlockedGate
|
|
92
64
|
): FrameworkMenuEvidenceSummary => ({
|
|
@@ -144,18 +116,12 @@ export const printConsumerRuntimeEmptyScopeHint = (
|
|
|
144
116
|
}
|
|
145
117
|
if (scope === 'staged') {
|
|
146
118
|
dependencies.write(
|
|
147
|
-
'\nℹ Scope vacío (staged): no hay archivos soportados en staged para auditar. Resultado PASS por alcance vacío; usa 1
|
|
148
|
-
);
|
|
149
|
-
return;
|
|
150
|
-
}
|
|
151
|
-
if (scope === 'unstaged') {
|
|
152
|
-
dependencies.write(
|
|
153
|
-
'\nℹ Scope vacío (unstaged): no hay cambios sin stage ni untracked auditable. Resultado PASS por alcance vacío; usa 1, 14 u opciones 11–13 según el alcance que necesites.\n'
|
|
119
|
+
'\nℹ Scope vacío (staged): no hay archivos soportados en staged para auditar. Resultado PASS por alcance vacío; usa 1 o 2 para validar repo completo.\n'
|
|
154
120
|
);
|
|
155
121
|
return;
|
|
156
122
|
}
|
|
157
123
|
dependencies.write(
|
|
158
|
-
'\nℹ Scope vacío (working tree): no hay archivos soportados en staged/unstaged para auditar. Resultado PASS por alcance vacío; usa 1
|
|
124
|
+
'\nℹ Scope vacío (working tree): no hay archivos soportados en staged/unstaged para auditar. Resultado PASS por alcance vacío; usa 1 o 2 para validar repo completo.\n'
|
|
159
125
|
);
|
|
160
126
|
};
|
|
161
127
|
|