agentic-kdd 3.5.3 → 3.5.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CLAUDE.md CHANGED
@@ -253,6 +253,87 @@ Si el pipeline genera una de estas operaciones:
253
253
  4. Solo proceder si el dev responde SÍ explícitamente
254
254
 
255
255
 
256
+
257
+
258
+ ## REGRESSION GUARD — Steps 4 y 9 del pipeline aa:
259
+
260
+ ### Step 4 — ANTES del build (Regression Check)
261
+
262
+ Para TODA tarea aa: que modifique archivos existentes:
263
+
264
+ 1. Identificar archivos del changeset
265
+ 2. Consultar protected_behaviors relacionados con esos archivos
266
+ 3. Si hay behaviors HIGH confidence:
267
+ - Correr los test_patterns de ese behavior
268
+ - Si alguno falla → STOP:
269
+ "🛑 REGRESSION GUARD: El cambio que vas a hacer rompería [módulo] que
270
+ estaba funcionando correctamente. Test [pattern] falla actualmente.
271
+ Arregla eso primero o usa --override-regression si el cambio es intencional."
272
+ 4. Si hay behaviors MEDIA confidence → WARN y continúa
273
+ 5. Si no hay behaviors → continúa normalmente
274
+
275
+ ### Step 9 — DESPUÉS del ciclo exitoso (Regression Register)
276
+
277
+ Después de TDD Gate PASS + QA PASS + Preservation Gate PASS:
278
+
279
+ 1. El TDD Gate ya llama registerBehavior() automáticamente
280
+ 2. Verificar que behaviors relacionados no fueron silenciosamente rotos
281
+ 3. Si verifyAfterTDD() encuentra violations → WARN en el reporte final:
282
+ "⚠️ REGRESSION: [módulo] muestra signos de regresión. Revisar."
283
+ 4. Actualizar last_verified_at de todos los behaviors verificados
284
+
285
+ ### Escalado de confianza
286
+ pass_count 1-4 → MEDIA (emerging — warn but don't block)
287
+ pass_count 5+ → HIGH (protected — block if broken)
288
+
289
+ ### Comandos disponibles
290
+ node .agentic/grafo/regression-guard.cjs status
291
+ node .agentic/grafo/regression-guard.cjs check <file1> <file2>
292
+ node .agentic/grafo/regression-guard.cjs deprecate <id>
293
+ node .agentic/grafo/regression-guard.cjs fix <id>
294
+
295
+ ## SPEC GATE — Step 2 del pipeline aa:
296
+
297
+ Antes del Build step, para TODA tarea aa: que incluya cambios de valores:
298
+
299
+ 1. Extraer valores numéricos y strings del prompt
300
+ 2. Verificar contra memoria: ¿existe alguno como regla HIGH/MEDIA confidence?
301
+ 3. Si hay contradicción:
302
+ - HIGH confidence → STOP con mensaje exacto:
303
+ "⛔ SPEC GATE: '[campo]' en memoria = [valor_memoria] pero el prompt
304
+ pide [valor_nuevo]. Esto contradice la regla: '[titulo_nodo]'
305
+ ¿Confirmas que quieres cambiar esta regla de negocio?"
306
+ - MEDIA confidence → WARN y continúa:
307
+ "⚠️ SPEC GATE: '[campo]' puede contradecir una regla en memoria.
308
+ Verificando antes de implementar."
309
+ 4. Si no hay contradicción → continúa normalmente
310
+
311
+ Valores que SIEMPRE se verifican contra memoria:
312
+ trial_days, trial_period, yearly_discount, password_min,
313
+ invoice_prefix, max_users, max_api_calls, rate_limit, timeout
314
+
315
+ ## SECURITY GATE — Step 3 del pipeline aa:
316
+
317
+ Cuando el changeset incluye archivos CRITICAL o SENSITIVE:
318
+
319
+ CRITICAL: auth.ts, middleware/, .env, secrets, jwt, token
320
+ SENSITIVE: routes/, lib/prisma, collab-manager, harness
321
+
322
+ Antes del Build step:
323
+ 1. Clasificar archivos del changeset por riesgo
324
+ 2. Para archivos CRITICAL/SENSITIVE, verificar:
325
+ a. ¿Hay queries sin filtro tenant_id? → STOP si sí
326
+ b. ¿Hay cross-tenant access protegido solo con 'admin'? → STOP
327
+ (admin = tenant-level, superadmin = platform-level)
328
+ c. ¿Hay JWT bypass o debug flags? → STOP
329
+ d. ¿Hay reply.status().send() sin return? → WARN
330
+ 3. Si hay findings CRITICAL → STOP con reporte completo
331
+ 4. Si hay findings HIGH → WARN + continúa con advertencia visible
332
+ 5. Si no hay findings → PASS, continúa normalmente
333
+
334
+ El Security Gate NO reemplaza el audit: seguridad completo.
335
+ Es una verificación rápida antes del Build para los patrones más comunes.
336
+
256
337
  ## ENCADENAMIENTO DE COMANDOS
257
338
 
258
339
  Si el mensaje tiene esta forma:
@@ -834,7 +834,57 @@ if (require.main === module) {
834
834
  }
835
835
  }
836
836
 
837
+
838
+ // ─── REGISTER PASSING TESTS (called by TDD Gate automatically) ───────────────
839
+
840
+ function registerPassingTests(db, params) {
841
+ const { passed, total, area, command } = params || {};
842
+ if (!db || !passed || passed === 0) return;
843
+
844
+ try {
845
+ // Ensure verified_contracts table exists
846
+ db.exec(`
847
+ CREATE TABLE IF NOT EXISTS verified_contracts (
848
+ id TEXT PRIMARY KEY,
849
+ name TEXT NOT NULL,
850
+ test_file TEXT,
851
+ module TEXT,
852
+ status TEXT DEFAULT 'candidate',
853
+ pass_count INTEGER DEFAULT 0,
854
+ failure_count INTEGER DEFAULT 0,
855
+ last_passed_at TEXT,
856
+ updated_at TEXT DEFAULT (datetime('now')),
857
+ created_at TEXT DEFAULT (datetime('now'))
858
+ )
859
+ `);
860
+
861
+ const contractId = `contract_${area || 'global'}_${Date.now()}`;
862
+ const existing = db.prepare(
863
+ "SELECT id, pass_count, status FROM verified_contracts WHERE module = ? AND status != 'invalidated' LIMIT 1"
864
+ ).get(area || 'global');
865
+
866
+ if (existing) {
867
+ const newCount = (existing.pass_count || 0) + 1;
868
+ const newStatus = newCount >= 7 ? 'protected' : newCount >= 3 ? 'verified' : 'candidate';
869
+ db.prepare(`
870
+ UPDATE verified_contracts SET
871
+ pass_count = ?,
872
+ status = ?,
873
+ last_passed_at = datetime('now'),
874
+ updated_at = datetime('now')
875
+ WHERE id = ?
876
+ `).run(newCount, newStatus, existing.id);
877
+ } else {
878
+ db.prepare(`
879
+ INSERT OR IGNORE INTO verified_contracts (id, name, test_file, module, status, pass_count, last_passed_at)
880
+ VALUES (?, ?, ?, ?, 'candidate', 1, datetime('now'))
881
+ `).run(contractId, `${area || 'global'} tests (${passed}/${total})`, command || 'npm test', area || 'global');
882
+ }
883
+ } catch(e) { /* silent */ }
884
+ }
885
+
837
886
  module.exports = {
887
+ registerPassingTests,
838
888
  migrateSchema,
839
889
  ingestFromCycle,
840
890
  runPreservationGate,