pumuki 6.3.129 → 6.3.130

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.
Files changed (77) hide show
  1. package/AGENTS.md +16 -1
  2. package/CHANGELOG.md +9 -0
  3. package/README.md +14 -10
  4. package/VERSION +1 -1
  5. package/core/facts/detectors/text/android.test.ts +2583 -24
  6. package/core/facts/detectors/text/android.ts +4633 -34
  7. package/core/facts/detectors/typescript/index.test.ts +3639 -73
  8. package/core/facts/detectors/typescript/index.ts +4819 -270
  9. package/core/facts/extractHeuristicFacts.ts +271 -6
  10. package/core/rules/presets/heuristics/android.test.ts +314 -1
  11. package/core/rules/presets/heuristics/android.ts +1220 -50
  12. package/core/rules/presets/heuristics/typescript.test.ts +158 -2
  13. package/core/rules/presets/heuristics/typescript.ts +508 -0
  14. package/docs/README.md +3 -3
  15. package/docs/operations/RELEASE_NOTES.md +7 -1
  16. package/docs/operations/framework-menu-consumer-walkthrough.md +18 -15
  17. package/docs/product/API_REFERENCE.md +1 -1
  18. package/docs/product/USAGE.md +1 -1
  19. package/docs/validation/README.md +3 -1
  20. package/integrations/config/skillsCompilerTemplates.test.ts +131 -0
  21. package/integrations/config/skillsCompilerTemplates.ts +953 -7
  22. package/integrations/config/skillsDetectorRegistry.ts +451 -8
  23. package/integrations/config/skillsMarkdownRules.ts +884 -2
  24. package/integrations/evidence/buildEvidence.ts +29 -1
  25. package/integrations/evidence/platformSummary.test.ts +73 -9
  26. package/integrations/evidence/platformSummary.ts +165 -7
  27. package/integrations/evidence/repoState.ts +3 -0
  28. package/integrations/evidence/schema.ts +18 -0
  29. package/integrations/evidence/trackingContract.ts +17 -0
  30. package/integrations/evidence/writeEvidence.test.ts +3 -0
  31. package/integrations/evidence/writeEvidence.ts +29 -1
  32. package/integrations/gate/evaluateAiGate.ts +251 -8
  33. package/integrations/gate/governanceActionCatalog.ts +275 -0
  34. package/integrations/gate/remediationCatalog.ts +8 -0
  35. package/integrations/git/runPlatformGate.ts +9 -1
  36. package/integrations/lifecycle/adapter.ts +24 -0
  37. package/integrations/lifecycle/bootstrapManifest.ts +248 -0
  38. package/integrations/lifecycle/cliGovernanceConsole.ts +69 -0
  39. package/integrations/lifecycle/governanceNextAction.ts +171 -0
  40. package/integrations/lifecycle/governanceObservationSnapshot.ts +369 -0
  41. package/integrations/lifecycle/packageInfo.ts +118 -1
  42. package/integrations/lifecycle/state.ts +8 -1
  43. package/integrations/lifecycle/trackingState.ts +403 -0
  44. package/integrations/lifecycle/watch.ts +1 -1
  45. package/integrations/mcp/aiGateCheck.ts +194 -10
  46. package/integrations/mcp/alignedPlatformGate.ts +232 -0
  47. package/integrations/mcp/enterpriseServer.ts +19 -3
  48. package/integrations/mcp/preFlightCheck.ts +66 -3
  49. package/integrations/mcp/readMcpPrePushStdin.ts +7 -0
  50. package/package.json +1 -1
  51. package/scripts/build-ruralgo-s1-evidence-pack.ts +85 -0
  52. package/scripts/check-tracking-single-active.sh +1 -1
  53. package/scripts/framework-menu-advanced-view-lib.ts +49 -0
  54. package/scripts/framework-menu-consumer-actions-lib.ts +32 -32
  55. package/scripts/framework-menu-consumer-preflight-render.ts +10 -0
  56. package/scripts/framework-menu-consumer-preflight-run.ts +23 -0
  57. package/scripts/framework-menu-consumer-preflight-types.ts +12 -0
  58. package/scripts/framework-menu-consumer-runtime-actions.ts +11 -5
  59. package/scripts/framework-menu-consumer-runtime-audit.ts +0 -28
  60. package/scripts/framework-menu-consumer-runtime-evidence-classic.ts +118 -42
  61. package/scripts/framework-menu-consumer-runtime-lib.ts +38 -0
  62. package/scripts/framework-menu-consumer-runtime-menu.ts +55 -15
  63. package/scripts/framework-menu-consumer-runtime-types.ts +4 -0
  64. package/scripts/framework-menu-evidence-summary-read.ts +17 -1
  65. package/scripts/framework-menu-evidence-summary-types.ts +3 -0
  66. package/scripts/framework-menu-layout-data.ts +3 -23
  67. package/scripts/framework-menu-system-notifications-macos-applescript-dialog.ts +1 -1
  68. package/scripts/framework-menu-system-notifications-macos-dialog-payload.ts +14 -2
  69. package/scripts/framework-menu-system-notifications-macos-swift-source.ts +1 -1
  70. package/scripts/framework-menu-system-notifications-payloads-blocked.ts +128 -4
  71. package/scripts/framework-menu-system-notifications-payloads.ts +8 -1
  72. package/scripts/framework-menu-system-notifications-text.ts +7 -1
  73. package/scripts/framework-menu.ts +37 -2
  74. package/scripts/package-install-smoke-consumer-git-repo-lib.ts +10 -1
  75. package/scripts/package-install-smoke-consumer-npm-lib.ts +46 -9
  76. package/scripts/ruralgo-s1-evidence-pack-lib.ts +200 -0
  77. package/skills.lock.json +613 -698
@@ -15,10 +15,11 @@ import packageJson from '../package.json';
15
15
  const runNpmStep = (
16
16
  workspace: SmokeWorkspace,
17
17
  args: string[],
18
- context: string
18
+ context: string,
19
+ env?: NodeJS.ProcessEnv
19
20
  ): void => {
20
21
  assertSuccess(
21
- runCommand({ cwd: workspace.consumerRepo, executable: 'npm', args }),
22
+ runCommand({ cwd: workspace.consumerRepo, executable: 'npm', args, env }),
22
23
  context
23
24
  );
24
25
  };
@@ -32,7 +33,14 @@ export const installTarballIntoConsumerRepo = (
32
33
  'node_modules/\n.ai_evidence.json\n',
33
34
  'utf8'
34
35
  );
35
- runNpmStep(workspace, ['install', workspace.tarballPath ?? ''], 'npm install <tarball>');
36
+ runNpmStep(
37
+ workspace,
38
+ ['install', workspace.tarballPath ?? ''],
39
+ 'npm install <tarball>',
40
+ {
41
+ PUMUKI_SKIP_POSTINSTALL: '1',
42
+ }
43
+ );
36
44
  };
37
45
 
38
46
  export const verifyInstalledPackageCanBeRequired = (
@@ -51,10 +59,40 @@ export const verifyInstalledPackageCanBeRequired = (
51
59
  export const verifyInstalledPumukiBinaryVersion = (
52
60
  workspace: SmokeWorkspace
53
61
  ): void => {
62
+ const hasInstalledStatusVersion = (
63
+ result: ReturnType<typeof runCommand>,
64
+ ): boolean => {
65
+ let parsed: unknown;
66
+ try {
67
+ parsed = JSON.parse(result.stdout);
68
+ } catch {
69
+ return false;
70
+ }
71
+
72
+ const packageVersion =
73
+ typeof parsed === 'object' && parsed !== null && 'packageVersion' in parsed
74
+ ? (parsed as { packageVersion?: unknown }).packageVersion
75
+ : null;
76
+ const effectiveVersion =
77
+ typeof parsed === 'object'
78
+ && parsed !== null
79
+ && 'version' in parsed
80
+ && typeof (parsed as { version?: unknown }).version === 'object'
81
+ && (parsed as { version: { effective?: unknown } }).version !== null
82
+ ? (parsed as { version: { effective?: unknown } }).version.effective
83
+ : null;
84
+
85
+ return packageVersion === packageJson.version || effectiveVersion === packageJson.version;
86
+ };
87
+
54
88
  const assertInstalledStatusVersion = (
55
89
  result: ReturnType<typeof runCommand>,
56
90
  context: string
57
91
  ): void => {
92
+ if (hasInstalledStatusVersion(result)) {
93
+ return;
94
+ }
95
+
58
96
  let parsed: unknown;
59
97
  try {
60
98
  parsed = JSON.parse(result.stdout);
@@ -75,11 +113,9 @@ export const verifyInstalledPumukiBinaryVersion = (
75
113
  ? (parsed as { version: { effective?: unknown } }).version.effective
76
114
  : null;
77
115
 
78
- if (packageVersion !== packageJson.version && effectiveVersion !== packageJson.version) {
79
- throw new Error(
80
- `${context} reported unexpected version (packageVersion=${String(packageVersion)}, effectiveVersion=${String(effectiveVersion)}, expected=${packageJson.version})`
81
- );
82
- }
116
+ throw new Error(
117
+ `${context} reported unexpected version (packageVersion=${String(packageVersion)}, effectiveVersion=${String(effectiveVersion)}, expected=${packageJson.version})`
118
+ );
83
119
  };
84
120
 
85
121
  const noInstallVersionCheck = runCommand({
@@ -93,7 +129,8 @@ export const verifyInstalledPumukiBinaryVersion = (
93
129
  noInstallVersionCheck.exitCode === 0
94
130
  && !/Cannot find module|ERR_MODULE_NOT_FOUND|failed to resolve tsx runtime/.test(
95
131
  noInstallVersionCheck.combined
96
- );
132
+ )
133
+ && hasInstalledStatusVersion(noInstallVersionCheck);
97
134
  if (noInstallPassed) {
98
135
  assertNoFatalOutput(noInstallVersionCheck, 'pumuki status --json smoke');
99
136
  assertInstalledStatusVersion(noInstallVersionCheck, 'pumuki status --json smoke');
@@ -0,0 +1,200 @@
1
+ import { mkdirSync, writeFileSync } from 'node:fs';
2
+ import { dirname, resolve } from 'node:path';
3
+
4
+ type RuralGoS1EvidenceEntry = {
5
+ title: string;
6
+ mode: 'shell' | 'mcp';
7
+ command: string;
8
+ capture: ReadonlyArray<string>;
9
+ expectedFragments: ReadonlyArray<string>;
10
+ incs: ReadonlyArray<string>;
11
+ };
12
+
13
+ export type RuralGoS1EvidencePackOptions = {
14
+ cwd: string;
15
+ consumerRoot: string;
16
+ packageVersion: string;
17
+ generatedAt: string;
18
+ };
19
+
20
+ const resolvePumukiPackageSelector = (packageVersion: string): string => {
21
+ const trimmed = packageVersion.trim();
22
+ const isStableSemver = /^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$/.test(trimmed);
23
+ if (isStableSemver) {
24
+ return `pumuki@${trimmed}`;
25
+ }
26
+ return 'pumuki@latest';
27
+ };
28
+
29
+ const EVIDENCE_ENTRIES: ReadonlyArray<RuralGoS1EvidenceEntry> = [
30
+ {
31
+ title: 'Lifecycle status',
32
+ mode: 'shell',
33
+ command: 'npm run pumuki:status',
34
+ capture: [
35
+ 'Bloque `governance truth` completo.',
36
+ 'Indicadores de contrato efectivo, rama y skills surface.',
37
+ ],
38
+ expectedFragments: [
39
+ 'governance truth',
40
+ 'governance_effective',
41
+ 'contract_surface',
42
+ 'current_branch',
43
+ ],
44
+ incs: ['PUMUKI-INC-070', 'PUMUKI-INC-071', 'PUMUKI-INC-073', 'PUMUKI-INC-076'],
45
+ },
46
+ {
47
+ title: 'Lifecycle doctor',
48
+ mode: 'shell',
49
+ command: 'npm run pumuki:doctor',
50
+ capture: [
51
+ 'Veredicto humano final.',
52
+ 'Bloque `governance truth` con `next_action` visible.',
53
+ ],
54
+ expectedFragments: [
55
+ 'governance truth',
56
+ 'next_action',
57
+ 'reason_code',
58
+ 'WARN',
59
+ ],
60
+ incs: ['PUMUKI-INC-070', 'PUMUKI-INC-071', 'PUMUKI-INC-073'],
61
+ },
62
+ {
63
+ title: 'PRE_WRITE canónico',
64
+ mode: 'shell',
65
+ command: 'npx --yes --package pumuki@latest pumuki sdd validate --stage=PRE_WRITE --json',
66
+ capture: [
67
+ 'Salida JSON completa.',
68
+ 'Campos de session/mode y remediación inmediata.',
69
+ ],
70
+ expectedFragments: [
71
+ '"stage":"PRE_WRITE"',
72
+ '"decision"',
73
+ '"next_action"',
74
+ ],
75
+ incs: ['PUMUKI-INC-070', 'PUMUKI-INC-072'],
76
+ },
77
+ {
78
+ title: 'Hook pre-commit / gate',
79
+ mode: 'shell',
80
+ command: 'git commit --allow-empty -m "test: pumuki s1 validation"',
81
+ capture: [
82
+ 'Bloque de gate con `reason_code`, `instruction` y `next_action`.',
83
+ 'Si bloquea, conservar `NEXT:` y `REMEDIATION:`.',
84
+ ],
85
+ expectedFragments: [
86
+ 'reason_code=',
87
+ 'instruction=',
88
+ 'next_action=',
89
+ ],
90
+ incs: ['PUMUKI-INC-071', 'PUMUKI-INC-073', 'PUMUKI-INC-076'],
91
+ },
92
+ {
93
+ title: 'MCP pre_flight_check',
94
+ mode: 'mcp',
95
+ command: 'mcp::pre_flight_check(stage=PRE_WRITE)',
96
+ capture: [
97
+ 'Payload completo de `result`.',
98
+ 'Campos `reason_code`, `instruction`, `next_action`, `hints`.',
99
+ ],
100
+ expectedFragments: [
101
+ 'reason_code',
102
+ 'instruction',
103
+ 'next_action',
104
+ 'hints',
105
+ ],
106
+ incs: ['PUMUKI-INC-071', 'PUMUKI-INC-072', 'PUMUKI-INC-073'],
107
+ },
108
+ {
109
+ title: 'MCP auto_execute_ai_start',
110
+ mode: 'mcp',
111
+ command: 'mcp::auto_execute_ai_start(stage=PRE_WRITE)',
112
+ capture: [
113
+ 'Payload completo de `result`.',
114
+ 'Campos `action`, `reason_code`, `next_action`, `confidence_pct`.',
115
+ ],
116
+ expectedFragments: [
117
+ 'action',
118
+ 'reason_code',
119
+ 'next_action',
120
+ 'confidence_pct',
121
+ ],
122
+ incs: ['PUMUKI-INC-071', 'PUMUKI-INC-073', 'PUMUKI-INC-076'],
123
+ },
124
+ ];
125
+
126
+ const renderEntry = (params: {
127
+ entry: RuralGoS1EvidenceEntry;
128
+ consumerRoot: string;
129
+ }): string => {
130
+ const command = params.entry.mode === 'shell'
131
+ ? `cd ${params.consumerRoot} && ${params.entry.command}`
132
+ : params.entry.command;
133
+
134
+ return [
135
+ `### ${params.entry.title}`,
136
+ '',
137
+ `- mode: ${params.entry.mode}`,
138
+ `- command: \`${command}\``,
139
+ `- incs: ${params.entry.incs.join(', ')}`,
140
+ '- capture:',
141
+ ...params.entry.capture.map((item) => ` - ${item}`),
142
+ '- expected_fragments:',
143
+ ...params.entry.expectedFragments.map((item) => ` - ${item}`),
144
+ '',
145
+ ].join('\n');
146
+ };
147
+
148
+ export const buildRuralGoS1EvidencePackMarkdown = (
149
+ options: RuralGoS1EvidencePackOptions
150
+ ): string => {
151
+ const pumukiPackageSelector = resolvePumukiPackageSelector(options.packageVersion);
152
+ const evidenceEntries: ReadonlyArray<RuralGoS1EvidenceEntry> = EVIDENCE_ENTRIES.map((entry) =>
153
+ entry.title === 'PRE_WRITE canónico'
154
+ ? {
155
+ ...entry,
156
+ command: `npx --yes --package ${pumukiPackageSelector} pumuki sdd validate --stage=PRE_WRITE --json`,
157
+ }
158
+ : entry
159
+ );
160
+
161
+ return [
162
+ '# RuralGo S1 Evidence Pack',
163
+ '',
164
+ `- generated_at: ${options.generatedAt}`,
165
+ `- consumer_root: \`${options.consumerRoot}\``,
166
+ `- package_version: ${options.packageVersion}`,
167
+ '- objective: validar S1 contra PUMUKI-INC-071/073/076 y reunir soporte adicional para 070/072.',
168
+ '',
169
+ '## Uso',
170
+ '',
171
+ '- Ejecuta los comandos shell desde el consumer real tras repinear la semver publicada.',
172
+ '- Captura las respuestas MCP desde una sesión conectada al servidor enterprise.',
173
+ '- No muevas un INC a `FIXED` si falta convergencia entre lifecycle, hooks y MCP.',
174
+ '',
175
+ ...evidenceEntries.map((entry) =>
176
+ renderEntry({
177
+ entry,
178
+ consumerRoot: options.consumerRoot,
179
+ })
180
+ ),
181
+ '## Criterio rápido de cierre',
182
+ '',
183
+ '- `PUMUKI-INC-071`: candidato a FIXED si lifecycle, hooks y MCP exponen contrato efectivo del repo.',
184
+ '- `PUMUKI-INC-073`: candidato a FIXED si el verde parcial desaparece y se ve governance real.',
185
+ '- `PUMUKI-INC-076`: candidato a FIXED si hooks y surfaces muestran GitFlow/naming como parte del gate.',
186
+ '- `PUMUKI-INC-072`: no cerrar salvo que el pre-edit gate aparezca de forma homogénea y automática.',
187
+ '',
188
+ ].join('\n');
189
+ };
190
+
191
+ export const writeRuralGoS1EvidencePack = (params: {
192
+ cwd: string;
193
+ outFile: string;
194
+ markdown: string;
195
+ }): string => {
196
+ const outputPath = resolve(params.cwd, params.outFile);
197
+ mkdirSync(dirname(outputPath), { recursive: true });
198
+ writeFileSync(outputPath, params.markdown, 'utf8');
199
+ return outputPath;
200
+ };