pumuki 6.3.24 → 6.3.26

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.
@@ -3,7 +3,7 @@ import test from 'node:test';
3
3
  import { typescriptRules } from './typescript';
4
4
 
5
5
  test('typescriptRules define reglas heurísticas locked para plataforma generic', () => {
6
- assert.equal(typescriptRules.length, 18);
6
+ assert.equal(typescriptRules.length, 19);
7
7
 
8
8
  const ids = typescriptRules.map((rule) => rule.id);
9
9
  assert.deepEqual(ids, [
@@ -25,6 +25,7 @@ test('typescriptRules define reglas heurísticas locked para plataforma generic'
25
25
  'heuristics.ts.solid.lsp.override-not-implemented.ast',
26
26
  'heuristics.ts.solid.dip.framework-import.ast',
27
27
  'heuristics.ts.solid.dip.concrete-instantiation.ast',
28
+ 'heuristics.ts.god-class-large-class.ast',
28
29
  ]);
29
30
 
30
31
  const byId = new Map(typescriptRules.map((rule) => [rule.id, rule]));
@@ -44,10 +45,18 @@ test('typescriptRules define reglas heurísticas locked para plataforma generic'
44
45
  byId.get('heuristics.ts.solid.dip.concrete-instantiation.ast')?.then.code,
45
46
  'HEURISTICS_SOLID_DIP_CONCRETE_INSTANTIATION_AST'
46
47
  );
48
+ assert.equal(
49
+ byId.get('heuristics.ts.god-class-large-class.ast')?.then.code,
50
+ 'HEURISTICS_GOD_CLASS_LARGE_CLASS_AST'
51
+ );
47
52
 
48
53
  for (const rule of typescriptRules) {
49
54
  assert.equal(rule.platform, 'generic');
50
- assert.equal(rule.severity, 'WARN');
55
+ if (rule.id === 'heuristics.ts.god-class-large-class.ast') {
56
+ assert.equal(rule.severity, 'ERROR');
57
+ } else {
58
+ assert.equal(rule.severity, 'WARN');
59
+ }
51
60
  assert.equal(rule.locked, true);
52
61
  assert.equal(rule.when.kind, 'Heuristic');
53
62
  assert.equal(rule.then.kind, 'Finding');
@@ -0,0 +1,421 @@
1
+ # Execution Board (Simple)
2
+
3
+ Único MD activo para seguimiento operativo diario.
4
+
5
+ ## Leyenda
6
+ - ✅ Hecho
7
+ - 🚧 En construccion (maximo 1)
8
+ - ⏳ Pendiente
9
+ - ⛔ Bloqueado
10
+
11
+ ## Estado Actual
12
+ - Objetivo: validación completa de funcionalidades + reglas AST en repo mock y repo real externo.
13
+ - Fuente de checklist: inventario automático desde `package.json`, `integrations/lifecycle/cli.ts`, `core/rules/presets/**` e `integrations/config/skillsCompilerTemplates.ts`.
14
+ - Política: una sola tarea en construcción.
15
+
16
+ ## Evidencia Mock (actual)
17
+ - Repo: `/Users/juancarlosmerlosalbarracin/Developer/Projects/pumuki-mock-consumer`
18
+ - Baseline sin SDD previo: ✅ (`openspec/`, `.ai_evidence.json`, `.pumuki/`, `pumuki.rules.ts`, `skills.lock.json`, `skills.sources.json` ausentes antes de instalar)
19
+ - Baseline limpio + reinstall desde cero: ✅ (sin hooks previos, sin artefactos previos, install nuevo)
20
+ - Matriz mock E2E: ✅ `clean=0/0/0`, `violations=1/1/1`, `mixed=1/1/1`
21
+ - Lifecycle remove (managed OpenSpec): ✅ fix aplicado + test dedicado en verde (`integrations/lifecycle/__tests__/remove.test.ts`)
22
+ - Lifecycle remove (legacy bootstrap state): ✅ fix aplicado para registrar `openSpecManagedArtifacts` incluso cuando `openspec/` ya existía antes de `install` (`integrations/lifecycle/openSpecBootstrap.ts`)
23
+ - Evidencia principal: `/Users/juancarlosmerlosalbarracin/Developer/Projects/pumuki-mock-consumer/artifacts/pumuki-matrix-summary.json`
24
+ - Nota: `P6.T8` sigue en construcción hasta completar repo real externo + relleno completo checklist.
25
+
26
+ ## Fase P6 (Seguimiento)
27
+ - ✅ `P6.T1` Matriz explícita de verificación total definida.
28
+ - ✅ `P6.T2` Validación funcional en repo real interno (`ast-intelligence-hooks`) ejecutada.
29
+ - ✅ `P6.T3` Validación funcional en repo mock (smoke minimal + block) ejecutada.
30
+ - ✅ `P6.T4` Auditoría de reglas ejecutada en suites internas.
31
+ - ✅ `P6.T5` Seguimiento simplificado en MD único (`docs/EXECUTION_BOARD.md`).
32
+ - ✅ `P6.T6` Higiene enterprise aplicada (basura y huérfanos purgados).
33
+ - ✅ `P6.T7` Checklist exhaustiva unificada creada (funcionalidades + reglas AST sin omisiones).
34
+ - 🚧 `P6.T8` Ejecutar checklist completa en repo mock + repo real externo y rellenar evidencia item por item.
35
+ - ⏳ `P6.T9` Consolidar cierre final y veredicto enterprise del bloque P6.
36
+
37
+ ## Checklist A — Funcionalidades (sin omisiones)
38
+ Totales: bins=10, lifecycle_commands=20, npm_scripts=98, exports=8, total_items=136.
39
+
40
+ ### A.1 Binaries (`package.json#bin`)
41
+ - [ ] `bin:ast-hooks` | mock: ⏳ | real: ⏳ | evidencia: ⏳
42
+ - [x] `bin:pumuki` | mock: ✅ | real: ⏳ | evidencia: mock:/Users/juancarlosmerlosalbarracin/Developer/Projects/pumuki-mock-consumer/artifacts/pumuki-matrix-summary.json (run_id=pumuki-matrix-20260228T110809Z-85568)
43
+ - [ ] `bin:pumuki-ast-hooks` | mock: ⏳ | real: ⏳ | evidencia: ⏳
44
+ - [x] `bin:pumuki-ci` | mock: ✅ | real: ⏳ | evidencia: mock:/Users/juancarlosmerlosalbarracin/Developer/Projects/pumuki-mock-consumer/artifacts/pumuki-matrix-summary.json (run_id=pumuki-matrix-20260228T110809Z-85568)
45
+ - [ ] `bin:pumuki-framework` | mock: ⏳ | real: ⏳ | evidencia: ⏳
46
+ - [ ] `bin:pumuki-mcp-enterprise` | mock: ⏳ | real: ⏳ | evidencia: ⏳
47
+ - [ ] `bin:pumuki-mcp-evidence` | mock: ⏳ | real: ⏳ | evidencia: ⏳
48
+ - [x] `bin:pumuki-pre-commit` | mock: ✅ | real: ⏳ | evidencia: mock:/Users/juancarlosmerlosalbarracin/Developer/Projects/pumuki-mock-consumer/artifacts/pumuki-matrix-summary.json (run_id=pumuki-matrix-20260228T110809Z-85568)
49
+ - [x] `bin:pumuki-pre-push` | mock: ✅ | real: ⏳ | evidencia: mock:/Users/juancarlosmerlosalbarracin/Developer/Projects/pumuki-mock-consumer/artifacts/pumuki-matrix-summary.json (run_id=pumuki-matrix-20260228T110809Z-85568)
50
+ - [ ] `bin:pumuki-pre-write` | mock: ⏳ | real: ⏳ | evidencia: ⏳
51
+
52
+ ### A.2 Comandos Lifecycle (`integrations/lifecycle/cli.ts#HELP_TEXT`)
53
+ - [x] `cmd:pumuki install` | mock: ✅ | real: ⏳ | evidencia: mock:/Users/juancarlosmerlosalbarracin/Developer/Projects/pumuki-mock-consumer/artifacts/pumuki-matrix-summary.json (run_id=pumuki-matrix-20260228T110809Z-85568)
54
+ - [x] `cmd:pumuki uninstall [--purge-artifacts]` | mock: ✅ | real: ⏳ | evidencia: mock:/Users/juancarlosmerlosalbarracin/Developer/Projects/pumuki-mock-consumer/artifacts/pumuki-matrix-summary.json (run_id=pumuki-matrix-20260228T110809Z-85568)
55
+ - [x] `cmd:pumuki remove` | mock: ✅ | real: ⏳ | evidencia: mock:/Users/juancarlosmerlosalbarracin/Developer/Projects/pumuki-mock-consumer/artifacts/pumuki-matrix-summary.json (run_id=pumuki-matrix-20260228T110809Z-85568)
56
+ - [ ] `cmd:pumuki update [--latest|--spec=<package-spec>]` | mock: ⏳ | real: ⏳ | evidencia: ⏳
57
+ - [x] `cmd:pumuki doctor` | mock: ✅ | real: ⏳ | evidencia: mock:/Users/juancarlosmerlosalbarracin/Developer/Projects/pumuki-mock-consumer/artifacts/pumuki-matrix-summary.json (run_id=pumuki-matrix-20260228T110809Z-85568)
58
+ - [x] `cmd:pumuki status` | mock: ✅ | real: ⏳ | evidencia: mock:/Users/juancarlosmerlosalbarracin/Developer/Projects/pumuki-mock-consumer/artifacts/pumuki-matrix-summary.json (run_id=pumuki-matrix-20260228T110809Z-85568)
59
+ - [ ] `cmd:pumuki loop run --objective=<text> [--max-attempts=<n>] [--json]` | mock: ⏳ | real: ⏳ | evidencia: ⏳
60
+ - [ ] `cmd:pumuki loop status --session=<session-id> [--json]` | mock: ⏳ | real: ⏳ | evidencia: ⏳
61
+ - [ ] `cmd:pumuki loop stop --session=<session-id> [--json]` | mock: ⏳ | real: ⏳ | evidencia: ⏳
62
+ - [ ] `cmd:pumuki loop resume --session=<session-id> [--json]` | mock: ⏳ | real: ⏳ | evidencia: ⏳
63
+ - [ ] `cmd:pumuki loop list [--json]` | mock: ⏳ | real: ⏳ | evidencia: ⏳
64
+ - [ ] `cmd:pumuki loop export --session=<session-id> [--output-json=<path>] [--json]` | mock: ⏳ | real: ⏳ | evidencia: ⏳
65
+ - [ ] `cmd:pumuki adapter install --agent=<name> [--dry-run] [--json]` | mock: ⏳ | real: ⏳ | evidencia: ⏳
66
+ - [ ] `cmd:pumuki analytics hotspots report [--top=<n>] [--since-days=<n>] [--json] [--output-json=<path>] [--output-markdown=<path>]` | mock: ⏳ | real: ⏳ | evidencia: ⏳
67
+ - [ ] `cmd:pumuki analytics hotspots diagnose [--json]` | mock: ⏳ | real: ⏳ | evidencia: ⏳
68
+ - [ ] `cmd:pumuki sdd status [--json]` | mock: ⏳ | real: ⏳ | evidencia: ⏳
69
+ - [ ] `cmd:pumuki sdd validate [--stage=PRE_WRITE|PRE_COMMIT|PRE_PUSH|CI] [--json]` | mock: ⏳ | real: ⏳ | evidencia: ⏳
70
+ - [ ] `cmd:pumuki sdd session --open --change=<change-id> [--ttl-minutes=<n>] [--json]` | mock: ⏳ | real: ⏳ | evidencia: ⏳
71
+ - [ ] `cmd:pumuki sdd session --refresh [--ttl-minutes=<n>] [--json]` | mock: ⏳ | real: ⏳ | evidencia: ⏳
72
+ - [ ] `cmd:pumuki sdd session --close [--json]` | mock: ⏳ | real: ⏳ | evidencia: ⏳
73
+
74
+ ### A.3 Scripts (`package.json#scripts`)
75
+ - [ ] `script:adapter:install` | mock: ⏳ | real: ⏳ | evidencia: ⏳
76
+ - [ ] `script:ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
77
+ - [ ] `script:ast:audit` | mock: ⏳ | real: ⏳ | evidencia: ⏳
78
+ - [ ] `script:ast:check-version` | mock: ⏳ | real: ⏳ | evidencia: ⏳
79
+ - [ ] `script:ast:gitflow` | mock: ⏳ | real: ⏳ | evidencia: ⏳
80
+ - [ ] `script:ast:guard:logs` | mock: ⏳ | real: ⏳ | evidencia: ⏳
81
+ - [ ] `script:ast:guard:restart` | mock: ⏳ | real: ⏳ | evidencia: ⏳
82
+ - [ ] `script:ast:guard:start` | mock: ⏳ | real: ⏳ | evidencia: ⏳
83
+ - [ ] `script:ast:guard:status` | mock: ⏳ | real: ⏳ | evidencia: ⏳
84
+ - [ ] `script:ast:guard:stop` | mock: ⏳ | real: ⏳ | evidencia: ⏳
85
+ - [ ] `script:ast:refresh` | mock: ⏳ | real: ⏳ | evidencia: ⏳
86
+ - [ ] `script:ast:release` | mock: ⏳ | real: ⏳ | evidencia: ⏳
87
+ - [ ] `script:audit` | mock: ⏳ | real: ⏳ | evidencia: ⏳
88
+ - [ ] `script:audit-library` | mock: ⏳ | real: ⏳ | evidencia: ⏳
89
+ - [ ] `script:build:ts` | mock: ⏳ | real: ⏳ | evidencia: ⏳
90
+ - [ ] `script:check-version` | mock: ⏳ | real: ⏳ | evidencia: ⏳
91
+ - [ ] `script:framework:menu` | mock: ⏳ | real: ⏳ | evidencia: ⏳
92
+ - [ ] `script:gitflow` | mock: ⏳ | real: ⏳ | evidencia: ⏳
93
+ - [ ] `script:gitflow:reset` | mock: ⏳ | real: ⏳ | evidencia: ⏳
94
+ - [ ] `script:gitflow:status` | mock: ⏳ | real: ⏳ | evidencia: ⏳
95
+ - [ ] `script:gitflow:workflow` | mock: ⏳ | real: ⏳ | evidencia: ⏳
96
+ - [ ] `script:install-hooks` | mock: ⏳ | real: ⏳ | evidencia: ⏳
97
+ - [ ] `script:lint` | mock: ⏳ | real: ⏳ | evidencia: ⏳
98
+ - [ ] `script:maintenance:library` | mock: ⏳ | real: ⏳ | evidencia: ⏳
99
+ - [ ] `script:mcp:enterprise` | mock: ⏳ | real: ⏳ | evidencia: ⏳
100
+ - [ ] `script:mcp:evidence` | mock: ⏳ | real: ⏳ | evidencia: ⏳
101
+ - [ ] `script:pumuki:doctor` | mock: ⏳ | real: ⏳ | evidencia: ⏳
102
+ - [ ] `script:pumuki:install` | mock: ⏳ | real: ⏳ | evidencia: ⏳
103
+ - [ ] `script:pumuki:remove` | mock: ⏳ | real: ⏳ | evidencia: ⏳
104
+ - [ ] `script:pumuki:sdd:pre-write` | mock: ⏳ | real: ⏳ | evidencia: ⏳
105
+ - [ ] `script:pumuki:status` | mock: ⏳ | real: ⏳ | evidencia: ⏳
106
+ - [ ] `script:pumuki:uninstall` | mock: ⏳ | real: ⏳ | evidencia: ⏳
107
+ - [ ] `script:pumuki:update` | mock: ⏳ | real: ⏳ | evidencia: ⏳
108
+ - [ ] `script:skills:compile` | mock: ⏳ | real: ⏳ | evidencia: ⏳
109
+ - [ ] `script:skills:import:custom` | mock: ⏳ | real: ⏳ | evidencia: ⏳
110
+ - [ ] `script:skills:lock:check` | mock: ⏳ | real: ⏳ | evidencia: ⏳
111
+ - [ ] `script:test` | mock: ⏳ | real: ⏳ | evidencia: ⏳
112
+ - [ ] `script:test:deterministic` | mock: ⏳ | real: ⏳ | evidencia: ⏳
113
+ - [ ] `script:test:evidence` | mock: ⏳ | real: ⏳ | evidencia: ⏳
114
+ - [ ] `script:test:heuristics` | mock: ⏳ | real: ⏳ | evidencia: ⏳
115
+ - [ ] `script:test:mcp` | mock: ⏳ | real: ⏳ | evidencia: ⏳
116
+ - [ ] `script:test:operational-memory` | mock: ⏳ | real: ⏳ | evidencia: ⏳
117
+ - [ ] `script:test:saas-ingestion` | mock: ⏳ | real: ⏳ | evidencia: ⏳
118
+ - [ ] `script:test:stage-gates` | mock: ⏳ | real: ⏳ | evidencia: ⏳
119
+ - [ ] `script:typecheck` | mock: ⏳ | real: ⏳ | evidencia: ⏳
120
+ - [ ] `script:validate:adapter-hooks-local` | mock: ⏳ | real: ⏳ | evidencia: ⏳
121
+ - [ ] `script:validation:adapter-readiness` | mock: ⏳ | real: ⏳ | evidencia: ⏳
122
+ - [ ] `script:validation:adapter-real-session-report` | mock: ⏳ | real: ⏳ | evidencia: ⏳
123
+ - [ ] `script:validation:adapter-session-status` | mock: ⏳ | real: ⏳ | evidencia: ⏳
124
+ - [ ] `script:validation:architecture-guardrails` | mock: ⏳ | real: ⏳ | evidencia: ⏳
125
+ - [ ] `script:validation:c020-benchmark` | mock: ⏳ | real: ⏳ | evidencia: ⏳
126
+ - [ ] `script:validation:clean-artifacts` | mock: ⏳ | real: ⏳ | evidencia: ⏳
127
+ - [ ] `script:validation:consumer-ci-artifacts` | mock: ⏳ | real: ⏳ | evidencia: ⏳
128
+ - [ ] `script:validation:consumer-ci-auth-check` | mock: ⏳ | real: ⏳ | evidencia: ⏳
129
+ - [ ] `script:validation:consumer-startup-triage` | mock: ⏳ | real: ⏳ | evidencia: ⏳
130
+ - [ ] `script:validation:consumer-startup-unblock-status` | mock: ⏳ | real: ⏳ | evidencia: ⏳
131
+ - [ ] `script:validation:consumer-support-bundle` | mock: ⏳ | real: ⏳ | evidencia: ⏳
132
+ - [ ] `script:validation:consumer-support-ticket-draft` | mock: ⏳ | real: ⏳ | evidencia: ⏳
133
+ - [ ] `script:validation:consumer-workflow-lint` | mock: ⏳ | real: ⏳ | evidencia: ⏳
134
+ - [ ] `script:validation:lifecycle-smoke` | mock: ⏳ | real: ⏳ | evidencia: ⏳
135
+ - [ ] `script:validation:mock-consumer-ab-report` | mock: ⏳ | real: ⏳ | evidencia: ⏳
136
+ - [ ] `script:validation:package-manifest` | mock: ⏳ | real: ⏳ | evidencia: ⏳
137
+ - [ ] `script:validation:package-smoke` | mock: ⏳ | real: ⏳ | evidencia: ⏳
138
+ - [ ] `script:validation:package-smoke:minimal` | mock: ⏳ | real: ⏳ | evidencia: ⏳
139
+ - [ ] `script:validation:phase5-blockers-readiness` | mock: ⏳ | real: ⏳ | evidencia: ⏳
140
+ - [ ] `script:validation:phase5-escalation:close-submission` | mock: ⏳ | real: ⏳ | evidencia: ⏳
141
+ - [ ] `script:validation:phase5-escalation:mark-submitted` | mock: ⏳ | real: ⏳ | evidencia: ⏳
142
+ - [ ] `script:validation:phase5-escalation:payload` | mock: ⏳ | real: ⏳ | evidencia: ⏳
143
+ - [ ] `script:validation:phase5-escalation:prepare` | mock: ⏳ | real: ⏳ | evidencia: ⏳
144
+ - [ ] `script:validation:phase5-escalation:ready-to-submit` | mock: ⏳ | real: ⏳ | evidencia: ⏳
145
+ - [ ] `script:validation:phase5-execution-closure` | mock: ⏳ | real: ⏳ | evidencia: ⏳
146
+ - [ ] `script:validation:phase5-execution-closure-status` | mock: ⏳ | real: ⏳ | evidencia: ⏳
147
+ - [ ] `script:validation:phase5-external-handoff` | mock: ⏳ | real: ⏳ | evidencia: ⏳
148
+ - [ ] `script:validation:phase5-latest:ready-check` | mock: ⏳ | real: ⏳ | evidencia: ⏳
149
+ - [ ] `script:validation:phase5-latest:refresh` | mock: ⏳ | real: ⏳ | evidencia: ⏳
150
+ - [ ] `script:validation:phase5-latest:sync-docs` | mock: ⏳ | real: ⏳ | evidencia: ⏳
151
+ - [ ] `script:validation:phase5-post-support:refresh` | mock: ⏳ | real: ⏳ | evidencia: ⏳
152
+ - [ ] `script:validation:phase8:autopilot` | mock: ⏳ | real: ⏳ | evidencia: ⏳
153
+ - [ ] `script:validation:phase8:close-ready` | mock: ⏳ | real: ⏳ | evidencia: ⏳
154
+ - [ ] `script:validation:phase8:doctor` | mock: ⏳ | real: ⏳ | evidencia: ⏳
155
+ - [ ] `script:validation:phase8:loop-guard` | mock: ⏳ | real: ⏳ | evidencia: ⏳
156
+ - [ ] `script:validation:phase8:loop-guard-coverage` | mock: ⏳ | real: ⏳ | evidencia: ⏳
157
+ - [ ] `script:validation:phase8:mark-followup-posted-now` | mock: ⏳ | real: ⏳ | evidencia: ⏳
158
+ - [ ] `script:validation:phase8:mark-followup-replied-now` | mock: ⏳ | real: ⏳ | evidencia: ⏳
159
+ - [ ] `script:validation:phase8:mark-followup-state` | mock: ⏳ | real: ⏳ | evidencia: ⏳
160
+ - [ ] `script:validation:phase8:next-step` | mock: ⏳ | real: ⏳ | evidencia: ⏳
161
+ - [ ] `script:validation:phase8:ready-handoff` | mock: ⏳ | real: ⏳ | evidencia: ⏳
162
+ - [ ] `script:validation:phase8:resume-after-billing` | mock: ⏳ | real: ⏳ | evidencia: ⏳
163
+ - [ ] `script:validation:phase8:status-pack` | mock: ⏳ | real: ⏳ | evidencia: ⏳
164
+ - [ ] `script:validation:phase8:tick` | mock: ⏳ | real: ⏳ | evidencia: ⏳
165
+ - [ ] `script:validation:progress-single-active` | mock: ⏳ | real: ⏳ | evidencia: ⏳
166
+ - [ ] `script:verify:adapter-hooks-runtime` | mock: ⏳ | real: ⏳ | evidencia: ⏳
167
+ - [ ] `script:violations` | mock: ⏳ | real: ⏳ | evidencia: ⏳
168
+ - [ ] `script:violations:demo` | mock: ⏳ | real: ⏳ | evidencia: ⏳
169
+ - [ ] `script:violations:list` | mock: ⏳ | real: ⏳ | evidencia: ⏳
170
+ - [ ] `script:violations:show` | mock: ⏳ | real: ⏳ | evidencia: ⏳
171
+ - [ ] `script:violations:summary` | mock: ⏳ | real: ⏳ | evidencia: ⏳
172
+ - [ ] `script:violations:top` | mock: ⏳ | real: ⏳ | evidencia: ⏳
173
+
174
+ ### A.4 Exports (`package.json#exports`)
175
+ - [ ] `export:.` | mock: ⏳ | real: ⏳ | evidencia: ⏳
176
+ - [ ] `export:./core/gate/evaluateGate` | mock: ⏳ | real: ⏳ | evidencia: ⏳
177
+ - [ ] `export:./core/gate/evaluateRules` | mock: ⏳ | real: ⏳ | evidencia: ⏳
178
+ - [ ] `export:./integrations/git` | mock: ⏳ | real: ⏳ | evidencia: ⏳
179
+ - [ ] `export:./integrations/lifecycle` | mock: ⏳ | real: ⏳ | evidencia: ⏳
180
+ - [ ] `export:./integrations/mcp` | mock: ⏳ | real: ⏳ | evidencia: ⏳
181
+ - [ ] `export:./integrations/sdd` | mock: ⏳ | real: ⏳ | evidencia: ⏳
182
+ - [ ] `export:./package.json` | mock: ⏳ | real: ⏳ | evidencia: ⏳
183
+
184
+ ## Checklist B — Reglas AST (sin omisiones)
185
+ Total reglas AST inventariadas: 235.
186
+
187
+ - [ ] `rule:android.no-global-scope` | mock: ⏳ | real: ⏳ | evidencia: ⏳
188
+ - [ ] `rule:android.no-run-blocking` | mock: ⏳ | real: ⏳ | evidencia: ⏳
189
+ - [ ] `rule:android.no-thread-sleep` | mock: ⏳ | real: ⏳ | evidencia: ⏳
190
+ - [ ] `rule:backend.avoid-explicit-any` | mock: ⏳ | real: ⏳ | evidencia: ⏳
191
+ - [ ] `rule:backend.no-console-log` | mock: ⏳ | real: ⏳ | evidencia: ⏳
192
+ - [ ] `rule:backend.no-empty-catch` | mock: ⏳ | real: ⏳ | evidencia: ⏳
193
+ - [ ] `rule:common.error.empty_catch` | mock: ⏳ | real: ⏳ | evidencia: ⏳
194
+ - [ ] `rule:common.network.missing_error_handling` | mock: ⏳ | real: ⏳ | evidencia: ⏳
195
+ - [ ] `rule:common.types.record_unknown_requires_type` | mock: ⏳ | real: ⏳ | evidencia: ⏳
196
+ - [ ] `rule:common.types.undefined_in_base_type` | mock: ⏳ | real: ⏳ | evidencia: ⏳
197
+ - [ ] `rule:common.types.unknown_without_guard` | mock: ⏳ | real: ⏳ | evidencia: ⏳
198
+ - [ ] `rule:domain-change-without-tests` | mock: ⏳ | real: ⏳ | evidencia: ⏳
199
+ - [ ] `rule:frontend.avoid-single-letter-variables` | mock: ⏳ | real: ⏳ | evidencia: ⏳
200
+ - [ ] `rule:frontend.no-console-log` | mock: ⏳ | real: ⏳ | evidencia: ⏳
201
+ - [ ] `rule:frontend.no-debugger` | mock: ⏳ | real: ⏳ | evidencia: ⏳
202
+ - [ ] `rule:heuristics.android.globalscope.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
203
+ - [ ] `rule:heuristics.android.run-blocking.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
204
+ - [ ] `rule:heuristics.android.thread-sleep.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
205
+ - [ ] `rule:heuristics.ios.anyview.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
206
+ - [ ] `rule:heuristics.ios.callback-style.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
207
+ - [ ] `rule:heuristics.ios.dispatchgroup.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
208
+ - [ ] `rule:heuristics.ios.dispatchqueue.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
209
+ - [ ] `rule:heuristics.ios.dispatchsemaphore.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
210
+ - [ ] `rule:heuristics.ios.force-cast.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
211
+ - [ ] `rule:heuristics.ios.force-try.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
212
+ - [ ] `rule:heuristics.ios.force-unwrap.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
213
+ - [ ] `rule:heuristics.ios.navigation-view.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
214
+ - [ ] `rule:heuristics.ios.observable-object.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
215
+ - [ ] `rule:heuristics.ios.on-tap-gesture.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
216
+ - [ ] `rule:heuristics.ios.operation-queue.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
217
+ - [ ] `rule:heuristics.ios.string-format.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
218
+ - [ ] `rule:heuristics.ios.task-detached.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
219
+ - [ ] `rule:heuristics.ios.uiscreen-main-bounds.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
220
+ - [ ] `rule:heuristics.ios.unchecked-sendable.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
221
+ - [ ] `rule:heuristics.ts.buffer-alloc-unsafe-slow.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
222
+ - [ ] `rule:heuristics.ts.buffer-alloc-unsafe.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
223
+ - [ ] `rule:heuristics.ts.child-process-exec-file-sync.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
224
+ - [ ] `rule:heuristics.ts.child-process-exec-file-untrusted-args.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
225
+ - [ ] `rule:heuristics.ts.child-process-exec-file.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
226
+ - [ ] `rule:heuristics.ts.child-process-exec-sync.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
227
+ - [ ] `rule:heuristics.ts.child-process-exec.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
228
+ - [ ] `rule:heuristics.ts.child-process-fork.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
229
+ - [ ] `rule:heuristics.ts.child-process-import.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
230
+ - [ ] `rule:heuristics.ts.child-process-shell-true.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
231
+ - [ ] `rule:heuristics.ts.child-process-spawn-sync.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
232
+ - [ ] `rule:heuristics.ts.child-process-spawn.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
233
+ - [ ] `rule:heuristics.ts.console-error.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
234
+ - [ ] `rule:heuristics.ts.console-log.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
235
+ - [ ] `rule:heuristics.ts.debugger.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
236
+ - [ ] `rule:heuristics.ts.delete-operator.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
237
+ - [ ] `rule:heuristics.ts.document-write.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
238
+ - [ ] `rule:heuristics.ts.dynamic-shell-invocation.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
239
+ - [ ] `rule:heuristics.ts.empty-catch.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
240
+ - [ ] `rule:heuristics.ts.eval.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
241
+ - [ ] `rule:heuristics.ts.explicit-any.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
242
+ - [ ] `rule:heuristics.ts.fs-access-callback.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
243
+ - [ ] `rule:heuristics.ts.fs-access-sync.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
244
+ - [ ] `rule:heuristics.ts.fs-append-file-callback.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
245
+ - [ ] `rule:heuristics.ts.fs-append-file-sync.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
246
+ - [ ] `rule:heuristics.ts.fs-chmod-callback.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
247
+ - [ ] `rule:heuristics.ts.fs-chmod-sync.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
248
+ - [ ] `rule:heuristics.ts.fs-chown-callback.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
249
+ - [ ] `rule:heuristics.ts.fs-chown-sync.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
250
+ - [ ] `rule:heuristics.ts.fs-close-callback.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
251
+ - [ ] `rule:heuristics.ts.fs-close-sync.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
252
+ - [ ] `rule:heuristics.ts.fs-copy-file-callback.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
253
+ - [ ] `rule:heuristics.ts.fs-copy-file-sync.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
254
+ - [ ] `rule:heuristics.ts.fs-cp-callback.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
255
+ - [ ] `rule:heuristics.ts.fs-cp-sync.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
256
+ - [ ] `rule:heuristics.ts.fs-exists-callback.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
257
+ - [ ] `rule:heuristics.ts.fs-exists-sync.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
258
+ - [ ] `rule:heuristics.ts.fs-fchmod-callback.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
259
+ - [ ] `rule:heuristics.ts.fs-fchmod-sync.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
260
+ - [ ] `rule:heuristics.ts.fs-fchown-callback.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
261
+ - [ ] `rule:heuristics.ts.fs-fchown-sync.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
262
+ - [ ] `rule:heuristics.ts.fs-fdatasync-callback.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
263
+ - [ ] `rule:heuristics.ts.fs-fdatasync-sync.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
264
+ - [ ] `rule:heuristics.ts.fs-fstat-callback.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
265
+ - [ ] `rule:heuristics.ts.fs-fstat-sync.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
266
+ - [ ] `rule:heuristics.ts.fs-fsync-callback.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
267
+ - [ ] `rule:heuristics.ts.fs-fsync-sync.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
268
+ - [ ] `rule:heuristics.ts.fs-ftruncate-callback.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
269
+ - [ ] `rule:heuristics.ts.fs-ftruncate-sync.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
270
+ - [ ] `rule:heuristics.ts.fs-futimes-callback.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
271
+ - [ ] `rule:heuristics.ts.fs-futimes-sync.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
272
+ - [ ] `rule:heuristics.ts.fs-lchmod-callback.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
273
+ - [ ] `rule:heuristics.ts.fs-lchown-callback.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
274
+ - [ ] `rule:heuristics.ts.fs-link-callback.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
275
+ - [ ] `rule:heuristics.ts.fs-link-sync.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
276
+ - [ ] `rule:heuristics.ts.fs-lstat-callback.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
277
+ - [ ] `rule:heuristics.ts.fs-lstat-sync.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
278
+ - [ ] `rule:heuristics.ts.fs-lutimes-callback.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
279
+ - [ ] `rule:heuristics.ts.fs-lutimes-sync.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
280
+ - [ ] `rule:heuristics.ts.fs-mkdir-callback.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
281
+ - [ ] `rule:heuristics.ts.fs-mkdir-sync.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
282
+ - [ ] `rule:heuristics.ts.fs-mkdtemp-callback.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
283
+ - [ ] `rule:heuristics.ts.fs-mkdtemp-sync.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
284
+ - [ ] `rule:heuristics.ts.fs-open-callback.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
285
+ - [ ] `rule:heuristics.ts.fs-open-sync.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
286
+ - [ ] `rule:heuristics.ts.fs-opendir-callback.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
287
+ - [ ] `rule:heuristics.ts.fs-opendir-sync.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
288
+ - [ ] `rule:heuristics.ts.fs-promises-access.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
289
+ - [ ] `rule:heuristics.ts.fs-promises-append-file.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
290
+ - [ ] `rule:heuristics.ts.fs-promises-chmod.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
291
+ - [ ] `rule:heuristics.ts.fs-promises-chown.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
292
+ - [ ] `rule:heuristics.ts.fs-promises-copy-file.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
293
+ - [ ] `rule:heuristics.ts.fs-promises-cp.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
294
+ - [ ] `rule:heuristics.ts.fs-promises-link.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
295
+ - [ ] `rule:heuristics.ts.fs-promises-lstat.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
296
+ - [ ] `rule:heuristics.ts.fs-promises-mkdir.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
297
+ - [ ] `rule:heuristics.ts.fs-promises-mkdtemp.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
298
+ - [ ] `rule:heuristics.ts.fs-promises-open.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
299
+ - [ ] `rule:heuristics.ts.fs-promises-opendir.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
300
+ - [ ] `rule:heuristics.ts.fs-promises-read-file.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
301
+ - [ ] `rule:heuristics.ts.fs-promises-readdir.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
302
+ - [ ] `rule:heuristics.ts.fs-promises-readlink.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
303
+ - [ ] `rule:heuristics.ts.fs-promises-realpath.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
304
+ - [ ] `rule:heuristics.ts.fs-promises-rename.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
305
+ - [ ] `rule:heuristics.ts.fs-promises-rm.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
306
+ - [ ] `rule:heuristics.ts.fs-promises-stat.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
307
+ - [ ] `rule:heuristics.ts.fs-promises-symlink.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
308
+ - [ ] `rule:heuristics.ts.fs-promises-unlink.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
309
+ - [ ] `rule:heuristics.ts.fs-promises-utimes.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
310
+ - [ ] `rule:heuristics.ts.fs-promises-write-file.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
311
+ - [ ] `rule:heuristics.ts.fs-read-callback.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
312
+ - [ ] `rule:heuristics.ts.fs-read-file-callback.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
313
+ - [ ] `rule:heuristics.ts.fs-read-file-sync.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
314
+ - [ ] `rule:heuristics.ts.fs-read-sync.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
315
+ - [ ] `rule:heuristics.ts.fs-readdir-callback.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
316
+ - [ ] `rule:heuristics.ts.fs-readdir-sync.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
317
+ - [ ] `rule:heuristics.ts.fs-readlink-callback.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
318
+ - [ ] `rule:heuristics.ts.fs-readlink-sync.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
319
+ - [ ] `rule:heuristics.ts.fs-readv-callback.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
320
+ - [ ] `rule:heuristics.ts.fs-readv-sync.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
321
+ - [ ] `rule:heuristics.ts.fs-realpath-callback.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
322
+ - [ ] `rule:heuristics.ts.fs-realpath-sync.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
323
+ - [ ] `rule:heuristics.ts.fs-rename-callback.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
324
+ - [ ] `rule:heuristics.ts.fs-rename-sync.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
325
+ - [ ] `rule:heuristics.ts.fs-rm-callback.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
326
+ - [ ] `rule:heuristics.ts.fs-rm-sync.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
327
+ - [ ] `rule:heuristics.ts.fs-rmdir-callback.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
328
+ - [ ] `rule:heuristics.ts.fs-rmdir-sync.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
329
+ - [ ] `rule:heuristics.ts.fs-stat-callback.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
330
+ - [ ] `rule:heuristics.ts.fs-stat-sync.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
331
+ - [ ] `rule:heuristics.ts.fs-statfs-callback.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
332
+ - [ ] `rule:heuristics.ts.fs-statfs-sync.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
333
+ - [ ] `rule:heuristics.ts.fs-symlink-callback.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
334
+ - [ ] `rule:heuristics.ts.fs-symlink-sync.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
335
+ - [ ] `rule:heuristics.ts.fs-truncate-callback.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
336
+ - [ ] `rule:heuristics.ts.fs-truncate-sync.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
337
+ - [ ] `rule:heuristics.ts.fs-unlink-callback.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
338
+ - [ ] `rule:heuristics.ts.fs-unlink-sync.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
339
+ - [ ] `rule:heuristics.ts.fs-unwatch-file-callback.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
340
+ - [ ] `rule:heuristics.ts.fs-utimes-callback.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
341
+ - [ ] `rule:heuristics.ts.fs-utimes-sync.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
342
+ - [ ] `rule:heuristics.ts.fs-watch-callback.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
343
+ - [ ] `rule:heuristics.ts.fs-watch-file-callback.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
344
+ - [ ] `rule:heuristics.ts.fs-write-callback.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
345
+ - [ ] `rule:heuristics.ts.fs-write-file-callback.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
346
+ - [ ] `rule:heuristics.ts.fs-write-file-sync.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
347
+ - [ ] `rule:heuristics.ts.fs-write-sync.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
348
+ - [ ] `rule:heuristics.ts.fs-writev-callback.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
349
+ - [ ] `rule:heuristics.ts.fs-writev-sync.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
350
+ - [ ] `rule:heuristics.ts.function-constructor.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
351
+ - [ ] `rule:heuristics.ts.god-class-large-class.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
352
+ - [ ] `rule:heuristics.ts.hardcoded-secret-token.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
353
+ - [ ] `rule:heuristics.ts.inner-html.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
354
+ - [ ] `rule:heuristics.ts.insecure-token-date-now.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
355
+ - [ ] `rule:heuristics.ts.insecure-token-math-random.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
356
+ - [ ] `rule:heuristics.ts.insert-adjacent-html.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
357
+ - [ ] `rule:heuristics.ts.jwt-decode-without-verify.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
358
+ - [ ] `rule:heuristics.ts.jwt-sign-no-expiration.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
359
+ - [ ] `rule:heuristics.ts.jwt-verify-ignore-expiration.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
360
+ - [ ] `rule:heuristics.ts.new-promise-async.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
361
+ - [ ] `rule:heuristics.ts.process-env-mutation.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
362
+ - [ ] `rule:heuristics.ts.process-exit.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
363
+ - [ ] `rule:heuristics.ts.set-interval-string.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
364
+ - [ ] `rule:heuristics.ts.set-timeout-string.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
365
+ - [ ] `rule:heuristics.ts.solid.dip.concrete-instantiation.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
366
+ - [ ] `rule:heuristics.ts.solid.dip.framework-import.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
367
+ - [ ] `rule:heuristics.ts.solid.isp.interface-command-query-mix.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
368
+ - [ ] `rule:heuristics.ts.solid.lsp.override-not-implemented.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
369
+ - [ ] `rule:heuristics.ts.solid.ocp.discriminator-switch.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
370
+ - [ ] `rule:heuristics.ts.solid.srp.class-command-query-mix.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
371
+ - [ ] `rule:heuristics.ts.tls-env-override.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
372
+ - [ ] `rule:heuristics.ts.tls-reject-unauthorized-false.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
373
+ - [ ] `rule:heuristics.ts.vm-dynamic-code-execution.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
374
+ - [ ] `rule:heuristics.ts.weak-crypto-hash.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
375
+ - [ ] `rule:heuristics.ts.weak-token-randomuuid.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
376
+ - [ ] `rule:heuristics.ts.with-statement.ast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
377
+ - [ ] `rule:ios.no-alamofire` | mock: ⏳ | real: ⏳ | evidencia: ⏳
378
+ - [ ] `rule:ios.no-anyview` | mock: ⏳ | real: ⏳ | evidencia: ⏳
379
+ - [ ] `rule:ios.no-completion-handlers-outside-bridges` | mock: ⏳ | real: ⏳ | evidencia: ⏳
380
+ - [ ] `rule:ios.no-force-unwrap` | mock: ⏳ | real: ⏳ | evidencia: ⏳
381
+ - [ ] `rule:ios.no-gcd` | mock: ⏳ | real: ⏳ | evidencia: ⏳
382
+ - [ ] `rule:ios.no-jsonserialization` | mock: ⏳ | real: ⏳ | evidencia: ⏳
383
+ - [ ] `rule:ios.no-print` | mock: ⏳ | real: ⏳ | evidencia: ⏳
384
+ - [ ] `rule:ios.no_anyview` | mock: ⏳ | real: ⏳ | evidencia: ⏳
385
+ - [ ] `rule:ios.no_completion_handlers` | mock: ⏳ | real: ⏳ | evidencia: ⏳
386
+ - [ ] `rule:ios.no_dispatchqueue` | mock: ⏳ | real: ⏳ | evidencia: ⏳
387
+ - [ ] `rule:ios.no_print` | mock: ⏳ | real: ⏳ | evidencia: ⏳
388
+ - [ ] `rule:ios.tdd.domain-changes-require-tests` | mock: ⏳ | real: ⏳ | evidencia: ⏳
389
+ - [ ] `rule:skills.android.no-globalscope` | mock: ⏳ | real: ⏳ | evidencia: ⏳
390
+ - [ ] `rule:skills.android.no-runblocking` | mock: ⏳ | real: ⏳ | evidencia: ⏳
391
+ - [ ] `rule:skills.android.no-thread-sleep` | mock: ⏳ | real: ⏳ | evidencia: ⏳
392
+ - [ ] `rule:skills.backend.avoid-explicit-any` | mock: ⏳ | real: ⏳ | evidencia: ⏳
393
+ - [ ] `rule:skills.backend.enforce-clean-architecture` | mock: ⏳ | real: ⏳ | evidencia: ⏳
394
+ - [ ] `rule:skills.backend.no-console-log` | mock: ⏳ | real: ⏳ | evidencia: ⏳
395
+ - [ ] `rule:skills.backend.no-empty-catch` | mock: ⏳ | real: ⏳ | evidencia: ⏳
396
+ - [ ] `rule:skills.backend.no-god-classes` | mock: ⏳ | real: ⏳ | evidencia: ⏳
397
+ - [ ] `rule:skills.backend.no-solid-violations` | mock: ⏳ | real: ⏳ | evidencia: ⏳
398
+ - [ ] `rule:skills.frontend.avoid-explicit-any` | mock: ⏳ | real: ⏳ | evidencia: ⏳
399
+ - [ ] `rule:skills.frontend.enforce-clean-architecture` | mock: ⏳ | real: ⏳ | evidencia: ⏳
400
+ - [ ] `rule:skills.frontend.no-console-log` | mock: ⏳ | real: ⏳ | evidencia: ⏳
401
+ - [ ] `rule:skills.frontend.no-empty-catch` | mock: ⏳ | real: ⏳ | evidencia: ⏳
402
+ - [ ] `rule:skills.frontend.no-god-classes` | mock: ⏳ | real: ⏳ | evidencia: ⏳
403
+ - [ ] `rule:skills.frontend.no-solid-violations` | mock: ⏳ | real: ⏳ | evidencia: ⏳
404
+ - [ ] `rule:skills.ios.no-anyview` | mock: ⏳ | real: ⏳ | evidencia: ⏳
405
+ - [ ] `rule:skills.ios.no-callback-style-outside-bridges` | mock: ⏳ | real: ⏳ | evidencia: ⏳
406
+ - [ ] `rule:skills.ios.no-dispatchgroup` | mock: ⏳ | real: ⏳ | evidencia: ⏳
407
+ - [ ] `rule:skills.ios.no-dispatchqueue` | mock: ⏳ | real: ⏳ | evidencia: ⏳
408
+ - [ ] `rule:skills.ios.no-dispatchsemaphore` | mock: ⏳ | real: ⏳ | evidencia: ⏳
409
+ - [ ] `rule:skills.ios.no-force-cast` | mock: ⏳ | real: ⏳ | evidencia: ⏳
410
+ - [ ] `rule:skills.ios.no-force-try` | mock: ⏳ | real: ⏳ | evidencia: ⏳
411
+ - [ ] `rule:skills.ios.no-force-unwrap` | mock: ⏳ | real: ⏳ | evidencia: ⏳
412
+ - [ ] `rule:skills.ios.no-navigation-view` | mock: ⏳ | real: ⏳ | evidencia: ⏳
413
+ - [ ] `rule:skills.ios.no-observable-object` | mock: ⏳ | real: ⏳ | evidencia: ⏳
414
+ - [ ] `rule:skills.ios.no-on-tap-gesture` | mock: ⏳ | real: ⏳ | evidencia: ⏳
415
+ - [ ] `rule:skills.ios.no-operation-queue` | mock: ⏳ | real: ⏳ | evidencia: ⏳
416
+ - [ ] `rule:skills.ios.no-string-format` | mock: ⏳ | real: ⏳ | evidencia: ⏳
417
+ - [ ] `rule:skills.ios.no-task-detached` | mock: ⏳ | real: ⏳ | evidencia: ⏳
418
+ - [ ] `rule:skills.ios.no-uiscreen-main-bounds` | mock: ⏳ | real: ⏳ | evidencia: ⏳
419
+ - [ ] `rule:skills.ios.no-unchecked-sendable` | mock: ⏳ | real: ⏳ | evidencia: ⏳
420
+ - [ ] `rule:workflow.bdd.insufficient_features` | mock: ⏳ | real: ⏳ | evidencia: ⏳
421
+ - [ ] `rule:workflow.bdd.missing_feature_files` | mock: ⏳ | real: ⏳ | evidencia: ⏳
package/docs/README.md CHANGED
@@ -4,14 +4,15 @@ Canonical index for active Pumuki documentation.
4
4
 
5
5
  ## Ciclo Activo (Seguimiento Temporal)
6
6
 
7
- - Ciclo activo: sin tracking temporal abierto en `docs/validation/`.
8
- - Cierre más reciente: `C023` (MVP hotspots + No-MVP SaaS ingestion diagnostics) consolidado en `docs/REFRACTOR_PROGRESS.md`.
9
- - Alcance actual: monorepo local, sin SaaS ni multi-repo en MVP.
7
+ - Seguimiento diario (único y simplificado): `docs/EXECUTION_BOARD.md`.
8
+ - Cierre más reciente previo: `P5` (auditoría exhaustiva C025 consolidada) en `docs/REFRACTOR_PROGRESS.md`.
9
+ - Alcance actual: validar funcionamiento real de capacidades públicas y auditoría completa de reglas en repo real y/o mock.
10
10
  - Ultimo cierre oficial previo: ciclo `022` consolidado en `docs/validation/c022-phase-acceptance-contract.md`.
11
11
  - Politica: una sola tarea en construccion (`🚧`) en todo momento.
12
12
 
13
13
  ## Product and Architecture
14
14
 
15
+ - `docs/EXECUTION_BOARD.md`: tablero activo de seguimiento (simple).
15
16
  - `docs/ARCHITECTURE.md`: normative architecture contract.
16
17
  - `docs/HOW_IT_WORKS.md`: facts-to-gate execution flow.
17
18
  - `docs/API_REFERENCE.md`: public APIs, binaries, and command surfaces.
@@ -8,6 +8,10 @@ Estado operativo activo del repositorio.
8
8
  - ⏳ Pendiente
9
9
  - ⛔ Bloqueado
10
10
 
11
+ ## Seguimiento activo
12
+ El seguimiento operativo diario vive en `docs/EXECUTION_BOARD.md`.
13
+ Este archivo se mantiene como histórico auditable de fases y evidencias.
14
+
11
15
  ## Plan maestro activo (post-MVP)
12
16
  Fuente unica de seguimiento operativo. No se abren nuevos MDs temporales de tracking.
13
17
 
@@ -161,7 +165,171 @@ Fuente unica de seguimiento operativo. No se abren nuevos MDs temporales de trac
161
165
  - PR `#462` merged (`feature/p4-loop-runner-core` -> `develop`).
162
166
  - PR `#463` merged (`develop` -> `main`, merge admin por policy de rama).
163
167
  - sincronización final completada con `main` y `develop` alineadas.
164
- - 🚧 `P4.T9` Release de cierre post-P4 (`v6.3.24`): bump de versión, validación final y publicación npm.
168
+ - `P4.T9` Release de cierre post-P4 (`v6.3.24`) completado.
169
+ - bump de versión aplicado:
170
+ - `package.json` -> `6.3.24`
171
+ - `VERSION` -> `v6.3.24`
172
+ - documentación de release actualizada:
173
+ - `CHANGELOG.md`
174
+ - `docs/RELEASE_NOTES.md`
175
+ - validación final en verde:
176
+ - `npm run typecheck`
177
+ - `npm test`
178
+ - publicación npm en verde:
179
+ - `npm publish --access public`
180
+ - `npm view pumuki version dist-tags --json` => `latest: 6.3.24`
181
+ - ✅ `P4.T10` Standby post-release `6.3.24` cerrado por inicio de bloque `C025`.
182
+
183
+ ### Fase P5 — Auditoría exhaustiva C025 (funcionalidades + reglas)
184
+ - ✅ `P5.T1` Inicializar tracking estable de C025 con índice maestro y catálogos exhaustivos.
185
+ - documentos creados e indexados:
186
+ - `docs/validation/pumuki-audit-master-index.md` (temporal, retirado en `P5.T9`)
187
+ - `docs/validation/pumuki-functionalities-audit.md` (temporal, retirado en `P5.T9`)
188
+ - `docs/validation/pumuki-rules-audit.md` (temporal, retirado en `P5.T9`)
189
+ - inventario funcional inicial cargado:
190
+ - `10` bins, `98` scripts, `20` comandos lifecycle, `33` exports modulares, `1022` funciones exportadas.
191
+ - inventario de reglas inicial cargado:
192
+ - `234` rule IDs (`227` activas, `7` deprecadas), reconciliadas con `docs/rule-packs/*`.
193
+ - ✅ `P5.T2` Ejecutar lote inicial de validación funcional externa crítica (lifecycle/sdd/loop/analytics/mcp) con evidencia reproducible.
194
+ - evidencia ejecutada:
195
+ - `node bin/pumuki.js status --json` (`PASS`)
196
+ - `node bin/pumuki.js doctor --json` (`PASS`)
197
+ - `node bin/pumuki.js sdd status --json` (`PASS`, OpenSpec ausente reportado)
198
+ - `node bin/pumuki.js sdd validate --stage=PRE_COMMIT --json` (`BLOCK esperado`: `OPENSPEC_MISSING`)
199
+ - `node bin/pumuki.js loop list --json` (`PASS`: `[]`)
200
+ - `node bin/pumuki.js analytics hotspots diagnose --json` (`PASS`: `degraded` esperado por ausencia de contrato/audit)
201
+ - `npm run test:mcp` (`PASS`: `130/130`)
202
+ - ✅ `P5.T3` Ejecutar lote inicial de violaciones de reglas críticas y reglas `skills.*`.
203
+ - evidencia de lote crítico/skills:
204
+ - `npx --yes tsx@4.21.0 --test integrations/config/__tests__/skillsRuleSet.test.ts integrations/config/__tests__/skillsCustomRules.test.ts integrations/config/__tests__/skillsContracts.test.ts integrations/gate/__tests__/stagePolicies.test.ts core/facts/__tests__/extractHeuristicFacts.test.ts core/gate/evaluateRules.test.ts core/rules/presets/backendRuleSet.test.ts core/rules/presets/frontendRuleSet.test.ts core/rules/presets/iosEnterpriseRuleSet.test.ts core/rules/presets/androidRuleSet.test.ts` => `55/55 PASS`.
205
+ - `npx jest --runInBand --coverage=false core/gate/__tests__/evaluateRules.spec.ts` => `11/11 PASS`.
206
+ - ✅ `P5.T4` Publicar delta #1 de hallazgos y remediaciones priorizadas.
207
+ - delta #1:
208
+ - cobertura inicial validada: crítico/alto (`55/55`), spec focal (`11/11`), medium/low (`46/46`).
209
+ - hallazgo y corrección TDD aplicados:
210
+ - fallo RED en `core/rules/presets/heuristics/typescript.test.ts` (`19 !== 18`) tras introducir `heuristics.ts.god-class-large-class.ast`.
211
+ - GREEN: actualización de expectativas (conteo, id y severidad `ERROR` para la nueva regla).
212
+ - validación de cierre: `npm run typecheck` `PASS`.
213
+ - ✅ `P5.T5` Ejecutar validación representativa de reglas en repo real (`ast-intelligence-hooks`) y levantar primer informe de falsos positivos/negativos.
214
+ - evidencia:
215
+ - `node bin/pumuki.js analytics hotspots report --top=20 --since-days=30 --json` (`PASS`)
216
+ - `node bin/pumuki.js analytics hotspots diagnose --json` (`PASS`, `degraded` esperado por falta de contrato/audit SaaS)
217
+ - `node bin/pumuki.js sdd status --json` (`PASS`)
218
+ - `npm run test:stage-gates` (`PASS`: `904/908`, `4 skipped`)
219
+ - veredicto del corte:
220
+ - sin falsos positivos/falsos negativos nuevos detectados en esta muestra representativa.
221
+ - hallazgo corregido previamente era de expectativas de test (`typescript.test.ts`), no de motor de reglas.
222
+ - ✅ `P5.T6` Completar cobertura regla-a-regla restante (100%) y consolidar backlog final de ajustes por prioridad.
223
+ - cobertura consolidada:
224
+ - matriz de reglas `234/234` consolidada y cerrada en este tracker (tracking temporal C025 retirado en `P5.T9`).
225
+ - validación de suites de reglas:
226
+ - `npx --yes tsx@4.21.0 --test core/rules/presets/*.test.ts core/rules/presets/heuristics/*.test.ts integrations/config/__tests__/*.test.ts integrations/gate/__tests__/*.test.ts core/facts/__tests__/extractHeuristicFacts.test.ts core/gate/evaluateRules.test.ts` (`268/268 PASS`)
227
+ - `npx jest --runInBand --coverage=false core/gate/__tests__/evaluateRules.spec.ts` (`11/11 PASS`)
228
+ - estabilidad global durante ejecución:
229
+ - `npm test` (`PASS`)
230
+ - ✅ `P5.T7` Completar validación funcional interna por función exportada (lotes C1..C4) y consolidar backlog funcional final.
231
+ - evidencia por lotes:
232
+ - `npx --yes tsx@4.21.0 --test core/facts/__tests__/extractHeuristicFacts.test.ts core/gate/*.test.ts` => `37/37 PASS`
233
+ - `npx --yes tsx@4.21.0 --test integrations/config/__tests__/*.test.ts integrations/gate/__tests__/*.test.ts integrations/git/__tests__/*.test.ts` => `365/365 PASS`
234
+ - `npx --yes tsx@4.21.0 --test integrations/lifecycle/__tests__/*.test.ts integrations/sdd/__tests__/*.test.ts integrations/mcp/__tests__/*.test.ts` => `348/348 PASS`
235
+ - `npx --yes tsx@4.21.0 --test scripts/__tests__/*.test.ts` => `321/325 PASS` (`4 skipped`, `0 failed`)
236
+ - ✅ `P5.T8` Completar validación funcional externa pendiente (bins críticos y subcomandos restantes) y cerrar validación técnica C025.
237
+ - evidencia de cierre:
238
+ - `npm run validation:package-smoke:minimal` => `PASS` (`pre-commit/pre-push/ci` en `0`).
239
+ - `npm run validation:package-smoke` => `PASS` (`pre-commit/pre-push/ci` en `1/BLOCK` esperado para modo block).
240
+ - `npm run typecheck` => `PASS`.
241
+ - `npm test` => `PASS` (`906/906`, `0 failed`, `4 skipped` en lote tsx + `23/23` en jest specs).
242
+ - remediación aplicada:
243
+ - ajuste TDD en fixtures de smoke minimal para evitar falso bloqueo por `new_feature` en pre-commit:
244
+ - `scripts/package-install-smoke-fixtures-content-lib.ts`
245
+ - `scripts/__tests__/package-install-smoke-fixtures-content-lib.test.ts`
246
+ - ✅ `P5.T9` Consolidar cierre documental C025 en documentos estables y retirar tracking temporal redundante.
247
+ - consolidación estable:
248
+ - `docs/REFRACTOR_PROGRESS.md` (estado y evidencia final C025).
249
+ - `docs/README.md` (índice canónico sin tracking temporal activo).
250
+ - `docs/validation/README.md` (índice mínimo de validación estable).
251
+ - retiro tracking temporal:
252
+ - eliminados `docs/validation/pumuki-audit-master-index.md`
253
+ - eliminados `docs/validation/pumuki-functionalities-audit.md`
254
+ - eliminados `docs/validation/pumuki-rules-audit.md`
255
+ - ✅ `P5.T10` Standby operativo post-C025 cerrado por apertura de bloque `P6` de verificación exhaustiva real/mock.
256
+
257
+ ### Fase P6 — Verificación exhaustiva real/mock (funcionalidades + reglas)
258
+ - ✅ `P6.T1` Definir matriz explícita de verificación total (funcionalidades + reglas) con trazabilidad por entorno (`real/mock`) y evidencia ejecutable.
259
+ - objetivo no negociable:
260
+ - comprobar funcionamiento real de todas las capacidades públicas de Pumuki;
261
+ - comprobar auditoría/cobertura de todas las reglas, sin excepción, en repo real y/o mock.
262
+ - alcance inicial de matriz:
263
+ - superficies funcionales públicas: bins, comandos lifecycle/sdd/loop/analytics/mcp, scripts de validación y exports operativos;
264
+ - catálogo de reglas: `ruleId` activas + deprecadas con estado explícito por entorno de validación.
265
+ - ✅ `P6.T2` Ejecutar matriz funcional end-to-end en repo real (`ast-intelligence-hooks`) y registrar evidencia por comando/capacidad.
266
+ - evidencia real ejecutada:
267
+ - `node bin/pumuki.js status --json`
268
+ - `node bin/pumuki.js doctor --json`
269
+ - `node bin/pumuki.js sdd status --json`
270
+ - `node bin/pumuki.js loop list --json`
271
+ - `node bin/pumuki.js analytics hotspots report --top=20 --since-days=90 --json`
272
+ - `node bin/pumuki.js analytics hotspots diagnose --json`
273
+ - `npm run typecheck`
274
+ - `npm run test:stage-gates`
275
+ - `npm run test:deterministic`
276
+ - resultado:
277
+ - todas las ejecuciones en verde (`exit_code=0`).
278
+ - evidencia consolidada en `.audit_tmp/p6-t2-real-mock/*`.
279
+ - ✅ `P6.T3` Ejecutar matriz funcional end-to-end en repo mock de consumidor (aislado) para validar flujos de instalación/gates/lifecycle.
280
+ - evidencia mock ejecutada:
281
+ - `npm run validation:package-smoke:minimal`
282
+ - `npm run validation:package-smoke`
283
+ - resultado:
284
+ - ambos flujos en verde (`exit_code=0`), incluyendo modo block esperado.
285
+ - evidencia consolidada en `.audit_tmp/p6-t2-real-mock/*`.
286
+ - ✅ `P6.T4` Ejecutar auditoría regla-a-regla (100%) en mock controlado y confirmación de muestra representativa en repo real.
287
+ - evidencia de reglas:
288
+ - `npx --yes tsx@4.21.0 --test core/rules/presets/*.test.ts core/rules/presets/heuristics/*.test.ts integrations/config/__tests__/*.test.ts integrations/gate/__tests__/*.test.ts core/facts/__tests__/extractHeuristicFacts.test.ts core/gate/evaluateRules.test.ts`
289
+ - `npx jest --runInBand --coverage=false core/gate/__tests__/evaluateRules.spec.ts`
290
+ - resultado:
291
+ - suites en verde (`exit_code=0`) y cobertura de catálogo de reglas mantenida.
292
+ - confirmación de runtime real en comandos analytics/sdd/gates del mismo lote P6.
293
+ - ✅ `P6.T5` Migración del seguimiento activo a tablero corto (`docs/EXECUTION_BOARD.md`) completada.
294
+ - ✅ `P6.T6` Auditoría de higiene enterprise aplicada y purga de basura no oficial.
295
+ - limpieza local aplicada:
296
+ - eliminados artefactos efímeros: `.audit_tmp/`, `.audit-reports/`, `.coverage/`, `.pumuki/`, `.claude/`, `.ai_evidence.json`.
297
+ - eliminado archivo trackeado huérfano: `.hook-system/config.json`.
298
+ - eliminados PNGs huérfanos sin referencias internas:
299
+ - `assets/ast_intelligence_01.png`
300
+ - `assets/ast_intelligence_02.png`
301
+ - `assets/ast_intelligence_03.png`
302
+ - `assets/ast_intelligence_04.png`
303
+ - `assets/ast_intelligence_05.png`
304
+ - `assets/Hook_01.png`
305
+ - `assets/Hook_02.png`
306
+ - `assets/ai_gate.png`
307
+ - `assets/ai-start.png`
308
+ - `assets/pre-flight-check.png`
309
+ - ✅ `P6.T7` Checklist exhaustiva unificada creada en MD único (`docs/EXECUTION_BOARD.md`) con funcionalidades + reglas AST sin omisiones.
310
+ - cobertura checklist:
311
+ - funcionalidades inventariadas: `136` (`bin=10`, `lifecycle_commands=20`, `scripts=98`, `exports=8`).
312
+ - reglas AST inventariadas: `235` (`core_rules + skills_rules` en catálogo único).
313
+ - 🚧 `P6.T8` Ejecutar checklist completa en repo mock + repo real externo y rellenar evidencia item por item.
314
+ - progreso actual (mock):
315
+ - repo mock validado: `/Users/juancarlosmerlosalbarracin/Developer/Projects/pumuki-mock-consumer`.
316
+ - baseline sin SDD confirmado (`openspec/`, `.ai_evidence.json`, `.pumuki/`, `pumuki.rules.ts`, `skills.lock.json`, `skills.sources.json` ausentes).
317
+ - baseline reiniciado desde cero (uninstall/remove + purge + reinstall `pumuki@6.3.24`).
318
+ - matriz E2E mock ejecutada en verde:
319
+ - run_id: `pumuki-matrix-20260228T110809Z-85568`
320
+ - `clean`: `pre-commit=0`, `pre-push=0`, `ci=0`
321
+ - `violations`: `pre-commit=1`, `pre-push=1`, `ci=1` (bloqueo esperado)
322
+ - `mixed`: `pre-commit=1`, `pre-push=1`, `ci=1` (bloqueo esperado)
323
+ - fix lifecycle aplicado:
324
+ - `pumuki remove` ahora desinstala `@fission-ai/openspec` cuando fue bootstrap gestionado por Pumuki.
325
+ - `runOpenSpecBootstrap` ahora vuelve a registrar artefactos OpenSpec gestionados en estado incluso en repos legacy con `openspec/` preexistente.
326
+ - tests en verde: `npx --yes tsx@4.21.0 --test integrations/lifecycle/__tests__/consumerPackage.test.ts integrations/lifecycle/__tests__/remove.test.ts`
327
+ - tests en verde (regresión legacy): `npx --yes tsx@4.21.0 --test integrations/lifecycle/__tests__/openSpecBootstrap.test.ts integrations/lifecycle/__tests__/install.test.ts integrations/lifecycle/__tests__/remove.test.ts`
328
+ - typecheck en verde: `npm run -s typecheck`
329
+ - evidencia: `/Users/juancarlosmerlosalbarracin/Developer/Projects/pumuki-mock-consumer/artifacts/pumuki-matrix-summary.json`
330
+ - pendiente para cerrar `P6.T8`:
331
+ - ejecutar lote equivalente en repo real externo y completar relleno checklist item-por-item.
332
+ - ⏳ `P6.T9` Consolidar cierre final P6 en documentación estable.
165
333
 
166
334
  ## Plan Por Fases (Ciclo 014)
167
335
  Plan base visible para seguimiento previo y durante la implementacion.
@@ -11,6 +11,10 @@ Este directorio contiene solo documentación oficial y estable de validación pa
11
11
  - `mock-consumer-integration-runbook.md`
12
12
  - `skills-rollout-consumer-repositories.md`
13
13
 
14
+ ## Estado operativo actual
15
+
16
+ - Ciclo activo de seguimiento diario: `docs/EXECUTION_BOARD.md`.
17
+
14
18
  ## Política de higiene
15
19
 
16
20
  - Los reportes de ejecución/cierre de ciclos se generan en `.audit_tmp` o `.audit-reports`.
@@ -24,3 +28,5 @@ Este directorio contiene solo documentación oficial y estable de validación pa
24
28
  - `docs/TESTING.md`
25
29
  - `docs/API_REFERENCE.md`
26
30
  - `docs/evidence-v2.1.md`
31
+ - El cierre de `C025` (auditoría exhaustiva de funcionalidades + reglas) quedó consolidado en:
32
+ - `docs/REFRACTOR_PROGRESS.md` (estado, evidencia y cierre del bloque P5).
@@ -21,12 +21,15 @@ const readPackageJson = (repoRoot: string): ConsumerPackageJson => {
21
21
  return JSON.parse(raw) as ConsumerPackageJson;
22
22
  };
23
23
 
24
- export const resolveCurrentPumukiDependency = (repoRoot: string): {
24
+ export const resolveDeclaredDependency = (params: {
25
+ repoRoot: string;
26
+ dependencyName: string;
27
+ }): {
25
28
  source: ConsumerDependencySource;
26
29
  spec?: string;
27
30
  } => {
28
- const pkg = readPackageJson(repoRoot);
29
- const dependencyName = getCurrentPumukiPackageName();
31
+ const pkg = readPackageJson(params.repoRoot);
32
+ const dependencyName = params.dependencyName;
30
33
 
31
34
  const dependencySpec = pkg.dependencies?.[dependencyName];
32
35
  if (typeof dependencySpec === 'string') {
@@ -49,6 +52,15 @@ export const resolveCurrentPumukiDependency = (repoRoot: string): {
49
52
  };
50
53
  };
51
54
 
55
+ export const resolveCurrentPumukiDependency = (repoRoot: string): {
56
+ source: ConsumerDependencySource;
57
+ spec?: string;
58
+ } =>
59
+ resolveDeclaredDependency({
60
+ repoRoot,
61
+ dependencyName: getCurrentPumukiPackageName(),
62
+ });
63
+
52
64
  export const hasDeclaredDependenciesBeyondPumuki = (repoRoot: string): boolean => {
53
65
  const pkg = readPackageJson(repoRoot);
54
66
  const pumukiPackage = getCurrentPumukiPackageName();
@@ -52,6 +52,14 @@ const OPENSPEC_LEGACY_NPM_PACKAGE_NAME = 'openspec';
52
52
  const OPENSPEC_PROJECT_MD = 'openspec/project.md';
53
53
  const OPENSPEC_ARCHIVE_GITKEEP = 'openspec/changes/archive/.gitkeep';
54
54
  const OPENSPEC_SPECS_GITKEEP = 'openspec/specs/.gitkeep';
55
+ const OPENSPEC_MANAGED_ARTIFACTS = [
56
+ OPENSPEC_PROJECT_MD,
57
+ OPENSPEC_ARCHIVE_GITKEEP,
58
+ OPENSPEC_SPECS_GITKEEP,
59
+ ] as const;
60
+
61
+ const resolvePresentManagedArtifacts = (repoRoot: string): ReadonlyArray<string> =>
62
+ OPENSPEC_MANAGED_ARTIFACTS.filter((relativePath) => existsSync(join(repoRoot, relativePath)));
55
63
 
56
64
  export type OpenSpecCompatibilityMigrationResult = {
57
65
  repoRoot: string;
@@ -172,10 +180,11 @@ export const runOpenSpecBootstrap = (params: {
172
180
  }
173
181
 
174
182
  const projectInitializedBefore = isOpenSpecProjectInitialized(params.repoRoot);
175
- const managedArtifacts = !projectInitializedBefore
176
- ? scaffoldOpenSpecProject(params.repoRoot)
177
- : [];
178
- if (managedArtifacts.length > 0) {
183
+ if (!projectInitializedBefore) {
184
+ scaffoldOpenSpecProject(params.repoRoot);
185
+ }
186
+ const managedArtifacts = resolvePresentManagedArtifacts(params.repoRoot);
187
+ if (!projectInitializedBefore && managedArtifacts.length > 0) {
179
188
  actions.push('scaffold:openspec-project');
180
189
  }
181
190
 
@@ -1,9 +1,11 @@
1
1
  import { existsSync, readFileSync, readdirSync, rmSync, unlinkSync } from 'node:fs';
2
2
  import { dirname, join } from 'node:path';
3
- import { resolveCurrentPumukiDependency } from './consumerPackage';
3
+ import { resolveCurrentPumukiDependency, resolveDeclaredDependency } from './consumerPackage';
4
4
  import { LifecycleGitService, type ILifecycleGitService } from './gitService';
5
5
  import { LifecycleNpmService, type ILifecycleNpmService } from './npmService';
6
6
  import { getCurrentPumukiPackageName } from './packageInfo';
7
+ import { OPENSPEC_NPM_PACKAGE_NAME } from '../sdd/openSpecCli';
8
+ import { readOpenSpecManagedArtifacts } from './state';
7
9
  import { runLifecycleUninstall } from './uninstall';
8
10
 
9
11
  export type LifecycleRemoveResult = {
@@ -218,6 +220,11 @@ export const runLifecycleRemove = (params?: {
218
220
  const git = params?.git ?? new LifecycleGitService();
219
221
  const npm = params?.npm ?? new LifecycleNpmService();
220
222
  const repoRoot = git.resolveRepoRoot(params?.cwd ?? process.cwd());
223
+ const openSpecManagedArtifacts = readOpenSpecManagedArtifacts(git, repoRoot);
224
+ const openSpecDependency = resolveDeclaredDependency({
225
+ repoRoot,
226
+ dependencyName: OPENSPEC_NPM_PACKAGE_NAME,
227
+ });
221
228
 
222
229
  const uninstallResult = runLifecycleUninstall({
223
230
  cwd: repoRoot,
@@ -231,6 +238,12 @@ export const runLifecycleRemove = (params?: {
231
238
  repoRoot,
232
239
  packageName,
233
240
  });
241
+ const shouldUninstallManagedOpenSpecDependency =
242
+ openSpecManagedArtifacts.length > 0 && openSpecDependency.source !== 'none';
243
+
244
+ if (shouldUninstallManagedOpenSpecDependency) {
245
+ npm.runNpm(['uninstall', OPENSPEC_NPM_PACKAGE_NAME], repoRoot);
246
+ }
234
247
 
235
248
  if (currentDependency.source === 'none') {
236
249
  cleanupPumukiTraceDirectories({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pumuki",
3
- "version": "6.3.24",
3
+ "version": "6.3.26",
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": {
@@ -8,7 +8,7 @@ if [[ ! -f "${FILE}" ]]; then
8
8
  exit 1
9
9
  fi
10
10
 
11
- ACTIVE_PATTERN="^- 🚧 \`P[0-9A-Za-z-]+\` "
11
+ ACTIVE_PATTERN="^- 🚧 \`P[0-9A-Za-z.-]+\` "
12
12
  ACTIVE_COUNT="$(rg -n "${ACTIVE_PATTERN}" "${FILE}" | wc -l | tr -d ' ')"
13
13
 
14
14
  echo "[progress-single-active] file=${FILE}"
@@ -1,6 +1,6 @@
1
1
  export const SMOKE_BASELINE_FILE = {
2
2
  path: 'apps/backend/src/baseline.ts',
3
- content: ["export const baseline = (): string => 'ok';", ''].join('\n'),
3
+ content: ["const baseline = (): string => 'ok';", ''].join('\n'),
4
4
  };
5
5
 
6
6
  export const SMOKE_RANGE_PAYLOAD_FILES: Record<string, string> = {
@@ -41,8 +41,8 @@ export const SMOKE_RANGE_PAYLOAD_FILES: Record<string, string> = {
41
41
  };
42
42
 
43
43
  export const SMOKE_STAGED_ONLY_FILE = {
44
- path: 'apps/backend/src/staged-smoke.ts',
45
- content: ['export const stagedSmoke = (): string => "ok";', ''].join('\n'),
44
+ path: 'apps/backend/src/baseline.ts',
45
+ content: ['const baseline = (): string => "ok-minimal";', ''].join('\n'),
46
46
  };
47
47
 
48
48
  export const SMOKE_STAGED_ONLY_VIOLATION_FILE = {
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file