pumuki 6.3.97 → 6.3.99

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 (96) hide show
  1. package/AGENTS.md +269 -0
  2. package/CHANGELOG.md +697 -0
  3. package/README.md +4 -2
  4. package/VERSION +1 -1
  5. package/docs/README.md +13 -9
  6. package/docs/operations/RELEASE_NOTES.md +12 -76
  7. package/docs/product/HOW_IT_WORKS.md +6 -0
  8. package/docs/product/INSTALLATION.md +1 -1
  9. package/docs/product/USAGE.md +41 -4
  10. package/docs/tracking/plan-curso-pumuki-stack-my-architecture.md +118 -0
  11. package/docs/validation/README.md +6 -3
  12. package/integrations/config/skillsCustomRules.ts +18 -99
  13. package/integrations/evidence/buildEvidence.ts +0 -24
  14. package/integrations/evidence/repoState.ts +0 -3
  15. package/integrations/evidence/schema.ts +0 -18
  16. package/integrations/evidence/writeEvidence.ts +0 -24
  17. package/integrations/gate/evaluateAiGate.ts +15 -232
  18. package/integrations/gate/remediationCatalog.ts +0 -8
  19. package/integrations/git/GitService.ts +44 -5
  20. package/integrations/git/aiGateRepoPolicyFindings.ts +0 -4
  21. package/integrations/git/runPlatformGate.ts +1 -9
  22. package/integrations/git/runPlatformGateFacts.ts +19 -1
  23. package/integrations/git/runPlatformGateOutput.ts +27 -36
  24. package/integrations/lifecycle/adapter.templates.json +7 -13
  25. package/integrations/lifecycle/adapter.ts +0 -24
  26. package/integrations/lifecycle/artifacts.ts +1 -6
  27. package/integrations/lifecycle/audit.ts +101 -0
  28. package/integrations/lifecycle/cli.ts +110 -70
  29. package/integrations/lifecycle/cliSdd.ts +13 -8
  30. package/integrations/lifecycle/doctor.ts +16 -48
  31. package/integrations/lifecycle/hookManager.ts +0 -77
  32. package/integrations/lifecycle/index.ts +2 -0
  33. package/integrations/lifecycle/install.ts +0 -21
  34. package/integrations/lifecycle/npmService.ts +3 -155
  35. package/integrations/lifecycle/policyValidationSnapshot.ts +8 -2
  36. package/integrations/lifecycle/preWriteAutomation.ts +7 -77
  37. package/integrations/lifecycle/state.ts +1 -8
  38. package/integrations/lifecycle/status.ts +2 -29
  39. package/integrations/mcp/aiGateCheck.ts +26 -206
  40. package/integrations/mcp/autoExecuteAiStart.ts +87 -94
  41. package/integrations/mcp/enterpriseServer.ts +7 -23
  42. package/integrations/mcp/enterpriseStdioServer.cli.ts +4 -31
  43. package/integrations/mcp/preFlightCheck.ts +5 -51
  44. package/integrations/platform/detectPlatforms.ts +37 -0
  45. package/integrations/policy/experimentalFeatures.ts +1 -1
  46. package/integrations/sdd/evidenceScaffold.ts +2 -109
  47. package/package.json +10 -2
  48. package/scripts/check-tracking-single-active.sh +1 -1
  49. package/scripts/consumer-menu-matrix-baseline-report-lib.ts +13 -38
  50. package/scripts/consumer-postinstall-resolve-args.cjs +44 -0
  51. package/scripts/consumer-postinstall.cjs +76 -21
  52. package/scripts/framework-menu-advanced-view-lib.ts +0 -15
  53. package/scripts/framework-menu-consumer-actions-lib.ts +28 -4
  54. package/scripts/framework-menu-consumer-preflight-hints.ts +5 -2
  55. package/scripts/framework-menu-consumer-preflight-render.ts +0 -10
  56. package/scripts/framework-menu-consumer-preflight-run.ts +0 -23
  57. package/scripts/framework-menu-consumer-preflight-types.ts +0 -12
  58. package/scripts/framework-menu-consumer-runtime-actions.ts +87 -17
  59. package/scripts/framework-menu-consumer-runtime-audit.ts +36 -2
  60. package/scripts/framework-menu-consumer-runtime-evidence-classic.ts +140 -0
  61. package/scripts/framework-menu-consumer-runtime-lib.ts +2 -10
  62. package/scripts/framework-menu-consumer-runtime-menu.ts +4 -18
  63. package/scripts/framework-menu-consumer-runtime-types.ts +3 -3
  64. package/scripts/framework-menu-evidence-summary-lib.ts +1 -0
  65. package/scripts/framework-menu-evidence-summary-read.ts +57 -5
  66. package/scripts/framework-menu-evidence-summary-severity.ts +3 -1
  67. package/scripts/framework-menu-evidence-summary-types.ts +7 -0
  68. package/scripts/framework-menu-gate-lib.ts +9 -0
  69. package/scripts/framework-menu-layout-data.ts +5 -0
  70. package/scripts/framework-menu-matrix-baseline-lib.ts +15 -14
  71. package/scripts/framework-menu-matrix-canary-lib.ts +22 -1
  72. package/scripts/framework-menu-matrix-evidence-lib.ts +1 -0
  73. package/scripts/framework-menu-matrix-evidence-types.ts +13 -1
  74. package/scripts/framework-menu-matrix-runner-lib.ts +35 -0
  75. package/scripts/framework-menu-system-notifications-cause.ts +0 -24
  76. package/scripts/framework-menu-system-notifications-macos-swift-source.ts +24 -204
  77. package/scripts/framework-menu-system-notifications-macos.ts +4 -0
  78. package/scripts/framework-menu-system-notifications-payloads-blocked.ts +1 -1
  79. package/scripts/framework-menu-system-notifications-remediation.ts +13 -24
  80. package/scripts/framework-menu-system-notifications-text.ts +1 -7
  81. package/scripts/framework-menu.ts +3 -2
  82. package/scripts/package-install-smoke-consumer-git-repo-lib.ts +1 -10
  83. package/scripts/package-install-smoke-consumer-npm-lib.ts +9 -46
  84. package/scripts/pumuki-full-surface-smoke-lib.ts +37 -0
  85. package/scripts/pumuki-full-surface-smoke.ts +346 -0
  86. package/scripts/pumuki-smoke-installed-wrapper.cjs +31 -0
  87. package/integrations/evidence/trackingContract.ts +0 -150
  88. package/integrations/gate/governanceActionCatalog.ts +0 -275
  89. package/integrations/lifecycle/bootstrapManifest.ts +0 -248
  90. package/integrations/lifecycle/cliGovernanceConsole.ts +0 -69
  91. package/integrations/lifecycle/governanceNextAction.ts +0 -164
  92. package/integrations/lifecycle/governanceObservationSnapshot.ts +0 -613
  93. package/integrations/mcp/alignedPlatformGate.ts +0 -232
  94. package/integrations/mcp/readMcpPrePushStdin.ts +0 -7
  95. package/scripts/build-ruralgo-s1-evidence-pack.ts +0 -85
  96. package/scripts/ruralgo-s1-evidence-pack-lib.ts +0 -200
@@ -1,6 +1,5 @@
1
1
  import { Socket, createServer } from 'node:net';
2
2
  import { startEnterpriseMcpServer } from './enterpriseServer';
3
- import { resolveMcpEnterpriseExperimentalFeature } from '../policy/experimentalFeatures';
4
3
 
5
4
  type JsonRpcId = string | number | null;
6
5
 
@@ -99,32 +98,11 @@ const fetchJson = async (url: string, options?: RequestInit): Promise<unknown> =
99
98
  }
100
99
  };
101
100
 
102
- type EnterpriseHealthPayload = {
103
- status?: string;
104
- repoRoot?: string;
105
- experimentalFeatures?: {
106
- mcp_enterprise?: {
107
- mode?: string;
108
- };
109
- };
110
- };
111
-
112
- const canReuseEnterpriseHttp = (
113
- health: EnterpriseHealthPayload,
114
- repoRoot: string,
115
- expectedMcpMode: string
116
- ): boolean =>
117
- health.status === 'ok'
118
- && health.repoRoot === repoRoot
119
- && health.experimentalFeatures?.mcp_enterprise?.mode === expectedMcpMode;
120
-
121
101
  const startOrReuseEnterpriseHttp = async (): Promise<{
122
102
  host: string;
123
103
  port: number;
124
104
  startedByThisProcess: boolean;
125
105
  }> => {
126
- const repoRoot = process.cwd();
127
- const expectedMcpMode = resolveMcpEnterpriseExperimentalFeature().mode;
128
106
  const host = process.env.PUMUKI_ENTERPRISE_MCP_HOST ?? '127.0.0.1';
129
107
  const parsedPort = Number.parseInt(process.env.PUMUKI_ENTERPRISE_MCP_PORT ?? '', 10);
130
108
  const preferredPort = Number.isFinite(parsedPort) ? parsedPort : 7391;
@@ -132,8 +110,8 @@ const startOrReuseEnterpriseHttp = async (): Promise<{
132
110
 
133
111
  const healthUrl = `http://${host}:${requestedPort}/health`;
134
112
  try {
135
- const health = (await fetchJson(healthUrl)) as EnterpriseHealthPayload;
136
- if (canReuseEnterpriseHttp(health, repoRoot, expectedMcpMode)) {
113
+ const health = (await fetchJson(healthUrl)) as { status?: string };
114
+ if (health.status === 'ok') {
137
115
  return {
138
116
  host,
139
117
  port: requestedPort,
@@ -141,12 +119,7 @@ const startOrReuseEnterpriseHttp = async (): Promise<{
141
119
  };
142
120
  }
143
121
  } catch (error) {
144
- if (process.env.PUMUKI_DEBUG_MCP === '1') {
145
- const message = error instanceof Error ? error.message : String(error);
146
- process.stderr.write(
147
- `[pumuki-mcp-enterprise-stdio] health probe reuse skipped: ${message}\n`
148
- );
149
- }
122
+ void error;
150
123
  }
151
124
 
152
125
  const portInUse = await isPortInUse(host, requestedPort);
@@ -154,7 +127,7 @@ const startOrReuseEnterpriseHttp = async (): Promise<{
154
127
  startEnterpriseMcpServer({
155
128
  host,
156
129
  port: resolvedPort,
157
- repoRoot,
130
+ repoRoot: process.cwd(),
158
131
  });
159
132
 
160
133
  return {
@@ -1,14 +1,11 @@
1
- import {
2
- resolveGovernanceCatalogAction,
3
- type GovernanceCatalogNextAction,
4
- } from '../gate/governanceActionCatalog';
5
1
  import { evaluateAiGate, type AiGateStage, type AiGateViolation } from '../gate/evaluateAiGate';
6
2
  import { collectWorktreeAtomicSlices } from '../git/worktreeAtomicSlices';
7
3
  import { resolveLearningContextExperimentalFeature } from '../policy/experimentalFeatures';
8
4
  import { readSddLearningContext, type SddLearningContext } from '../sdd/learningInsights';
9
5
 
10
6
  const ACTIONABLE_HINTS_BY_CODE: Readonly<Record<string, string>> = {
11
- EVIDENCE_MISSING: 'Ejecuta una auditoría (1/2/3/4) para regenerar .ai_evidence.json.',
7
+ EVIDENCE_MISSING:
8
+ 'Ejecuta una auditoría (1/2/3/4 u opciones de motor 11–14) para regenerar .ai_evidence.json.',
12
9
  EVIDENCE_INVALID: 'Regenera .ai_evidence.json desde una opción de auditoría.',
13
10
  EVIDENCE_INTEGRITY_MISSING: 'Refresca evidencia para regenerar metadatos de integridad.',
14
11
  EVIDENCE_ACTIVE_RULE_IDS_EMPTY_FOR_CODE_CHANGES:
@@ -42,28 +39,6 @@ const ACTIONABLE_HINTS_BY_CODE: Readonly<Record<string, string>> = {
42
39
  'Mapea todas las reglas AUTO a detectores AST antes de continuar.',
43
40
  EVIDENCE_TIMESTAMP_FUTURE: 'Corrige la hora del sistema y regenera evidencia.',
44
41
  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
- }
67
42
  };
68
43
 
69
44
  const buildPreFlightHints = (params: {
@@ -140,8 +115,6 @@ export type EnterprisePreFlightCheckResult = {
140
115
  phase: 'GREEN' | 'RED';
141
116
  message: string;
142
117
  instruction: string;
143
- reason_code: string;
144
- next_action: GovernanceCatalogNextAction;
145
118
  stage: ReturnType<typeof evaluateAiGate>['stage'];
146
119
  policy: ReturnType<typeof evaluateAiGate>['policy'];
147
120
  violations: ReturnType<typeof evaluateAiGate>['violations'];
@@ -181,30 +154,13 @@ export const runEnterprisePreFlightCheck = (params: {
181
154
  upstream: evaluation.repo_state.git.upstream,
182
155
  learningContext,
183
156
  });
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
- });
195
157
  const phase: 'GREEN' | 'RED' = evaluation.allowed ? 'GREEN' : 'RED';
196
158
  const message = evaluation.allowed
197
159
  ? '✅ Pre-flight aprobado: puedes continuar con la implementación.'
198
- : `🔴 Pre-flight bloqueado: corrige ${reasonCode} y vuelve a ejecutar.`;
199
- const instruction = !firstViolation && evaluation.allowed
160
+ : `🔴 Pre-flight bloqueado: corrige ${evaluation.violations[0]?.code ?? 'la causa'} y vuelve a ejecutar.`;
161
+ const instruction = evaluation.allowed
200
162
  ? 'Implementa el cambio mínimo para pasar en verde y vuelve a validar.'
201
- : governanceAction.instruction;
202
- const nextAction: GovernanceCatalogNextAction = evaluation.allowed
203
- ? {
204
- kind: 'info',
205
- message: governanceAction.next_action.message,
206
- }
207
- : governanceAction.next_action;
163
+ : hints[0] ?? 'Corrige la causa bloqueante y vuelve a ejecutar el pre-flight.';
208
164
 
209
165
  return {
210
166
  tool: 'pre_flight_check',
@@ -217,8 +173,6 @@ export const runEnterprisePreFlightCheck = (params: {
217
173
  phase,
218
174
  message,
219
175
  instruction,
220
- reason_code: reasonCode,
221
- next_action: nextAction,
222
176
  stage: evaluation.stage,
223
177
  policy: evaluation.policy,
224
178
  violations: evaluation.violations,
@@ -51,6 +51,38 @@ const collectFilePaths = (facts: ReadonlyArray<Fact>): string[] => {
51
51
  .filter((path): path is string => typeof path === 'string');
52
52
  };
53
53
 
54
+ const ALLOWED_PIN_KEYS = new Set(['ios', 'android', 'backend', 'frontend']);
55
+
56
+ const readPinnedPlatformsFromEnv = (): ReadonlySet<keyof DetectedPlatforms> | null => {
57
+ const raw = process.env.PUMUKI_PIN_PLATFORMS?.trim().toLowerCase();
58
+ if (!raw) {
59
+ return null;
60
+ }
61
+ const tokens = raw
62
+ .split(',')
63
+ .map((token) => token.trim())
64
+ .filter((token) => token.length > 0)
65
+ .filter((token) => ALLOWED_PIN_KEYS.has(token)) as Array<keyof DetectedPlatforms>;
66
+ if (tokens.length === 0) {
67
+ return null;
68
+ }
69
+ return new Set(tokens);
70
+ };
71
+
72
+ const applyPinnedPlatformsFilter = (
73
+ detected: DetectedPlatforms,
74
+ pin: ReadonlySet<keyof DetectedPlatforms>
75
+ ): DetectedPlatforms => {
76
+ const next: DetectedPlatforms = {};
77
+ for (const key of pin) {
78
+ const state = detected[key];
79
+ if (state) {
80
+ next[key] = state;
81
+ }
82
+ }
83
+ return next;
84
+ };
85
+
54
86
  export const detectPlatformsFromFacts = (
55
87
  facts: ReadonlyArray<Fact>
56
88
  ): DetectedPlatforms => {
@@ -102,5 +134,10 @@ export const detectPlatformsFromFacts = (
102
134
  };
103
135
  }
104
136
 
137
+ const pin = readPinnedPlatformsFromEnv();
138
+ if (pin && pin.size > 0) {
139
+ return applyPinnedPlatformsFilter(result, pin);
140
+ }
141
+
105
142
  return result;
106
143
  };
@@ -40,7 +40,7 @@ type ExperimentalFeatureConfig = {
40
40
 
41
41
  const EXPERIMENTAL_FEATURES: Record<ExperimentalFeatureId, ExperimentalFeatureConfig> = {
42
42
  pre_write: {
43
- defaultMode: 'strict',
43
+ defaultMode: 'off',
44
44
  activationVariable: 'PUMUKI_EXPERIMENTAL_PRE_WRITE',
45
45
  legacyActivationVariable: 'PUMUKI_PREWRITE_ENFORCEMENT',
46
46
  },
@@ -1,5 +1,5 @@
1
1
  import { createHash } from 'node:crypto';
2
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
2
+ import { mkdirSync, writeFileSync } from 'node:fs';
3
3
  import { basename, dirname, isAbsolute, relative, resolve } from 'node:path';
4
4
  import { readEvidenceResult, type EvidenceReadResult } from '../evidence/readEvidence';
5
5
 
@@ -15,7 +15,6 @@ export type SddEvidenceScaffoldResult = {
15
15
  testStatus: SddEvidenceScaffoldTestStatus;
16
16
  testOutputPath: string | null;
17
17
  fromEvidencePath: string | null;
18
- traceabilityMarkdownPath: string | null;
19
18
  };
20
19
  output: {
21
20
  path: string;
@@ -45,13 +44,6 @@ export type SddEvidenceScaffoldResult = {
45
44
  source: 'pumuki-sdd-evidence';
46
45
  stack: 'sdd-evidence-scaffold';
47
46
  };
48
- traceability: {
49
- required: boolean;
50
- path: string | null;
51
- header_present: boolean;
52
- rows: number;
53
- status: 'valid';
54
- };
55
47
  // Legacy fields kept for state-sync compatibility in existing consumers.
56
48
  scenario_id: string;
57
49
  test_run: {
@@ -73,13 +65,10 @@ export type SddEvidenceScaffoldResult = {
73
65
  const computeDigest = (value: string): string =>
74
66
  `sha256:${createHash('sha256').update(value, 'utf8').digest('hex')}`;
75
67
 
76
- const TRACEABILITY_HEADER = '| ARCHIVO | SKILL | REGLA | EVIDENCIA | ESTADO |';
77
- const TRACEABILITY_CONTRACT_MARKER = 'ARCHIVO | SKILL | REGLA | EVIDENCIA | ESTADO';
78
-
79
68
  const resolveRepoBoundPath = (params: {
80
69
  repoRoot: string;
81
70
  candidatePath: string;
82
- flagName: '--from-evidence' | '--test-output' | '--traceability-markdown';
71
+ flagName: '--from-evidence' | '--test-output';
83
72
  }): string => {
84
73
  const repoRootAbsolute = resolve(params.repoRoot);
85
74
  const resolved = isAbsolute(params.candidatePath)
@@ -152,87 +141,6 @@ const resolveScenarioReference = (scenarioId: string): string => {
152
141
  return `${normalized}.feature`;
153
142
  };
154
143
 
155
- const repoRequiresTraceabilityMatrix = (repoRoot: string): boolean => {
156
- const agentsPath = resolve(repoRoot, 'AGENTS.md');
157
- if (!existsSync(agentsPath)) {
158
- return false;
159
- }
160
- const contents = readFileSync(agentsPath, 'utf8');
161
- return (
162
- contents.includes('Plantilla obligatoria de trazabilidad por turno') ||
163
- contents.includes(TRACEABILITY_CONTRACT_MARKER)
164
- );
165
- };
166
-
167
- const validateTraceabilityMarkdown = (params: {
168
- repoRoot: string;
169
- required: boolean;
170
- traceabilityMarkdownPath?: string;
171
- }): {
172
- path: string | null;
173
- header_present: boolean;
174
- rows: number;
175
- } => {
176
- if (!params.required) {
177
- return {
178
- path: params.traceabilityMarkdownPath?.trim() ? params.traceabilityMarkdownPath.trim() : null,
179
- header_present: false,
180
- rows: 0,
181
- };
182
- }
183
- const candidate = params.traceabilityMarkdownPath?.trim() ?? '';
184
- if (candidate.length === 0) {
185
- throw new Error(
186
- `[pumuki][sdd] evidence requires --traceability-markdown=<path> because this repository declares the contractual traceability matrix (${TRACEABILITY_HEADER}).`
187
- );
188
- }
189
- const absolutePath = resolveRepoBoundPath({
190
- repoRoot: params.repoRoot,
191
- candidatePath: candidate,
192
- flagName: '--traceability-markdown',
193
- });
194
- if (!existsSync(absolutePath)) {
195
- throw new Error(
196
- `[pumuki][sdd] traceability markdown file does not exist: ${candidate}. Add the contractual matrix and retry.`
197
- );
198
- }
199
- const markdown = readFileSync(absolutePath, 'utf8');
200
- const lines = markdown.split(/\r?\n/);
201
- const headerIndex = lines.findIndex((line) => line.trim() === TRACEABILITY_HEADER);
202
- if (headerIndex < 0) {
203
- throw new Error(
204
- `[pumuki][sdd] traceability markdown must include the contractual header ${TRACEABILITY_HEADER}.`
205
- );
206
- }
207
- let rows = 0;
208
- for (const line of lines.slice(headerIndex + 1)) {
209
- const trimmed = line.trim();
210
- if (!trimmed.startsWith('|')) {
211
- if (rows > 0) {
212
- break;
213
- }
214
- continue;
215
- }
216
- if (/^\|\s*-+\s*\|/.test(trimmed)) {
217
- continue;
218
- }
219
- if (trimmed === TRACEABILITY_HEADER) {
220
- continue;
221
- }
222
- rows += 1;
223
- }
224
- if (rows === 0) {
225
- throw new Error(
226
- '[pumuki][sdd] traceability markdown must include at least one data row under the contractual matrix header.'
227
- );
228
- }
229
- return {
230
- path: relative(params.repoRoot, absolutePath).split('\\').join('/'),
231
- header_present: true,
232
- rows,
233
- };
234
- };
235
-
236
144
  export const runSddEvidenceScaffold = (params?: {
237
145
  repoRoot?: string;
238
146
  dryRun?: boolean;
@@ -241,7 +149,6 @@ export const runSddEvidenceScaffold = (params?: {
241
149
  testStatus?: SddEvidenceScaffoldTestStatus;
242
150
  testOutputPath?: string;
243
151
  fromEvidencePath?: string;
244
- traceabilityMarkdownPath?: string;
245
152
  outputPath?: string;
246
153
  now?: () => Date;
247
154
  evidenceReader?: (repoRoot: string) => EvidenceReadResult;
@@ -288,12 +195,6 @@ export const runSddEvidenceScaffold = (params?: {
288
195
  evidenceResult: evidenceReader(repoRoot),
289
196
  fromEvidencePath,
290
197
  });
291
- const traceabilityRequired = repoRequiresTraceabilityMatrix(repoRoot);
292
- const traceability = validateTraceabilityMarkdown({
293
- repoRoot,
294
- required: traceabilityRequired,
295
- traceabilityMarkdownPath: params?.traceabilityMarkdownPath,
296
- });
297
198
 
298
199
  const now = params?.now ?? (() => new Date());
299
200
  const generatedAt = now().toISOString();
@@ -331,13 +232,6 @@ export const runSddEvidenceScaffold = (params?: {
331
232
  source: 'pumuki-sdd-evidence',
332
233
  stack: 'sdd-evidence-scaffold',
333
234
  },
334
- traceability: {
335
- required: traceabilityRequired,
336
- path: traceability.path,
337
- header_present: traceability.header_present,
338
- rows: traceability.rows,
339
- status: 'valid',
340
- },
341
235
  scenario_id: scenarioId,
342
236
  test_run: {
343
237
  command: testCommand,
@@ -373,7 +267,6 @@ export const runSddEvidenceScaffold = (params?: {
373
267
  testStatus,
374
268
  testOutputPath,
375
269
  fromEvidencePath,
376
- traceabilityMarkdownPath: traceability.path,
377
270
  },
378
271
  output: {
379
272
  path: outputRelativePath,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pumuki",
3
- "version": "6.3.97",
3
+ "version": "6.3.99",
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": {
@@ -54,6 +54,8 @@
54
54
  "test:saas-ingestion": "npx --yes tsx@4.21.0 --test integrations/lifecycle/__tests__/saasIngestionContract.test.ts integrations/lifecycle/__tests__/saasIngestionBuilder.test.ts integrations/lifecycle/__tests__/saasIngestionTransport.test.ts integrations/lifecycle/__tests__/saasIngestionIdempotency.test.ts integrations/lifecycle/__tests__/saasIngestionAuth.test.ts integrations/lifecycle/__tests__/saasIngestionAudit.test.ts integrations/lifecycle/__tests__/saasIngestionMetrics.test.ts integrations/lifecycle/__tests__/saasIngestionGovernance.test.ts integrations/lifecycle/__tests__/saasFederation.test.ts integrations/lifecycle/__tests__/saasEnterpriseAnalytics.test.ts integrations/lifecycle/__tests__/cli.test.ts",
55
55
  "test:operational-memory": "npx --yes tsx@4.21.0 --test integrations/lifecycle/__tests__/operationalMemoryContract.test.ts integrations/lifecycle/__tests__/operationalMemorySignals.test.ts integrations/lifecycle/__tests__/operationalMemorySnapshot.test.ts integrations/git/__tests__/runPlatformGate.test.ts integrations/git/__tests__/runPlatformGateEvidence.test.ts integrations/evidence/__tests__/buildEvidence.test.ts integrations/evidence/writeEvidence.test.ts integrations/evidence/generateEvidence.test.ts",
56
56
  "test:stage-gates": "npx --yes tsx@4.21.0 --test integrations/config/__tests__/*.test.ts integrations/gate/__tests__/*.test.ts integrations/git/__tests__/*.test.ts integrations/lifecycle/__tests__/*.test.ts integrations/sdd/__tests__/*.test.ts scripts/__tests__/*.test.ts",
57
+ "smoke:pumuki-surface": "npx --yes tsx@4.21.0 scripts/pumuki-full-surface-smoke.ts",
58
+ "smoke:pumuki-surface-installed": "node scripts/pumuki-smoke-installed-wrapper.cjs",
57
59
  "test:deterministic": "npm run test:evidence && npm run test:mcp && npm run test:heuristics",
58
60
  "ast:refresh": "node bin/pumuki-pre-commit.js",
59
61
  "ast:audit": "node bin/pumuki-pre-commit.js",
@@ -144,12 +146,13 @@
144
146
  "validation:phase5-escalation:payload": "bash scripts/build-phase5-support-portal-payload.sh",
145
147
  "validation:architecture-guardrails": "npx --yes tsx@4.21.0 --test scripts/__tests__/architecture-file-size-guardrails.test.ts",
146
148
  "validation:package-manifest": "node --import tsx scripts/check-package-manifest.ts",
149
+ "validation:pumuki-surface-smoke": "npm run -s smoke:pumuki-surface",
150
+ "validation:local-merge-bar": "npm run -s typecheck && npm run -s validation:pumuki-surface-smoke && npm test",
147
151
  "validation:package-smoke": "node --import tsx scripts/package-install-smoke.ts --mode=block",
148
152
  "validation:package-smoke:minimal": "node --import tsx scripts/package-install-smoke.ts --mode=minimal",
149
153
  "validation:lifecycle-smoke": "node --import tsx scripts/package-install-smoke.ts --mode=minimal",
150
154
  "validation:contract-suite:enterprise": "node --import tsx scripts/run-enterprise-contract-suite.ts",
151
155
  "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",
153
156
  "validation:c020-benchmark": "node --import tsx scripts/run-c020-benchmark.ts",
154
157
  "validation:clean-artifacts": "npx --yes tsx@4.21.0 scripts/clean-validation-artifacts.ts",
155
158
  "skills:compile": "npx --yes tsx@4.21.0 scripts/compile-skills-lock.ts",
@@ -249,6 +252,8 @@
249
252
  "integrations/telemetry/*.ts",
250
253
  "scripts/*.ts",
251
254
  "scripts/consumer-postinstall.cjs",
255
+ "scripts/consumer-postinstall-resolve-args.cjs",
256
+ "scripts/pumuki-smoke-installed-wrapper.cjs",
252
257
  "scripts/adapters/*.ts",
253
258
  "scripts/adapters/*.md",
254
259
  "scripts/*.sh",
@@ -260,10 +265,13 @@
260
265
  "docs/product/*.md",
261
266
  "docs/rule-packs/*.md",
262
267
  "docs/validation/*.md",
268
+ "docs/tracking/plan-curso-pumuki-stack-my-architecture.md",
263
269
  "assets/**/*",
264
270
  "vendor/skills/**/*",
265
271
  "index.js",
266
272
  "README.md",
273
+ "AGENTS.md",
274
+ "CHANGELOG.md",
267
275
  "LICENSE",
268
276
  "VERSION",
269
277
  "tsconfig.json",
@@ -31,7 +31,7 @@ for FILE in "${FILES[@]}"; do
31
31
  fi
32
32
 
33
33
  if [[ "${FILE}" == "PUMUKI-RESET-MASTER-PLAN.md" ]]; then
34
- ACTIVE_PATTERN='(^- Estado:\s*🚧\b)|(^`?\[\s*🚧\s*\]\s*-`?)|(^\|\s*[^|]+\|\s*`?\[\s*🚧\s*\]\s*-`?)'
34
+ ACTIVE_PATTERN='^- Estado: 🚧'
35
35
  else
36
36
  ACTIVE_PATTERN='^- 🚧 (`?P[0-9A-Za-z.-]+`?)'
37
37
  fi
@@ -4,10 +4,11 @@ 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';
7
8
  import type { DoctorDeepCheckLayer, LifecycleDoctorReport } from '../integrations/lifecycle/doctor';
8
9
  import type { LifecycleStatus } from '../integrations/lifecycle/status';
9
10
 
10
- const OPTION_IDS: ReadonlyArray<MatrixOptionId> = ['1', '2', '3', '4', '9'];
11
+ const OPTION_IDS: ReadonlyArray<MatrixOptionId> = [...MATRIX_MENU_OPTION_IDS];
11
12
  const DOCTOR_LAYERS: ReadonlyArray<DoctorDeepCheckLayer> = [
12
13
  'core',
13
14
  'operational',
@@ -51,45 +52,19 @@ export type ConsumerMenuMatrixBaselineSnapshot = {
51
52
  };
52
53
  };
53
54
 
55
+ const UNKNOWN_OPTION_REPORT = {
56
+ stage: 'UNKNOWN',
57
+ outcome: 'UNKNOWN',
58
+ filesScanned: 0,
59
+ totalViolations: 0,
60
+ diagnosis: 'unknown' as const,
61
+ };
62
+
54
63
  const buildEmptyRound = (): ConsumerMenuMatrixReport => {
55
64
  return {
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
- },
65
+ byOption: Object.fromEntries(
66
+ MATRIX_MENU_OPTION_IDS.map((id) => [id, { ...UNKNOWN_OPTION_REPORT }])
67
+ ) as ConsumerMenuMatrixReport['byOption'],
93
68
  };
94
69
  };
95
70
 
@@ -0,0 +1,44 @@
1
+ 'use strict';
2
+
3
+ const KNOWN_MCP_AGENTS = new Set(['cursor', 'codex', 'claude', 'repo']);
4
+
5
+ const normalizeExplicitAgent = (raw) => {
6
+ const trimmed = (raw ?? '').trim();
7
+ if (!trimmed) {
8
+ return '';
9
+ }
10
+ const lower = trimmed.toLowerCase();
11
+ if (lower === '0' || lower === 'none' || lower === 'false') {
12
+ return '';
13
+ }
14
+ if (!KNOWN_MCP_AGENTS.has(lower)) {
15
+ return '';
16
+ }
17
+ return lower;
18
+ };
19
+
20
+ const resolveConsumerPostinstallInstallExtras = (_consumerRoot, env = process.env) => {
21
+ if (env.PUMUKI_POSTINSTALL_SKIP_MCP === '1') {
22
+ return { extras: [], reason: 'skip_mcp' };
23
+ }
24
+ const withMcpFlag =
25
+ env.PUMUKI_POSTINSTALL_WITH_MCP === '1' ||
26
+ env.PUMUKI_POSTINSTALL_WITH_MCP?.toLowerCase() === 'true';
27
+ const explicit = normalizeExplicitAgent(env.PUMUKI_POSTINSTALL_MCP_AGENT);
28
+ if (explicit) {
29
+ return { extras: ['--with-mcp', `--agent=${explicit}`], reason: 'explicit_agent' };
30
+ }
31
+ if (withMcpFlag) {
32
+ return { extras: ['--with-mcp', '--agent=repo'], reason: 'explicit_repo_flag' };
33
+ }
34
+ return {
35
+ extras: [],
36
+ reason: 'disabled_default',
37
+ };
38
+ };
39
+
40
+ module.exports = {
41
+ KNOWN_MCP_AGENTS,
42
+ resolveConsumerPostinstallInstallExtras,
43
+ normalizeExplicitAgent,
44
+ };