pumuki 6.3.142 → 6.3.143

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/CHANGELOG.md CHANGED
@@ -6,6 +6,13 @@ This project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [6.3.143] - 2026-05-05
10
+
11
+ ### Fixed
12
+
13
+ - **PUMUKI-INC-060 baseline TDD/BDD fresco:** los cambios in-scope bloquean si la evidencia de baseline TDD/BDD está caducada, obligando a reejecutar los tests baseline del componente antes de editar código relacionado.
14
+ - **Ventana configurable de evidencia:** `PUMUKI_TDD_BDD_EVIDENCE_MAX_AGE_SECONDS` permite ajustar la frescura máxima; por defecto son 900 segundos y los valores inválidos mantienen el modo estricto.
15
+
9
16
  ## [6.3.142] - 2026-05-05
10
17
 
11
18
  ### Fixed
@@ -4,6 +4,12 @@ This file tracks the active deterministic framework line used in this repository
4
4
  Canonical release chronology lives in `CHANGELOG.md`.
5
5
  This file keeps only the operational highlights and rollout notes that matter while running the framework.
6
6
 
7
+ ### 2026-05-05 (v6.3.143)
8
+
9
+ - **RuralGo PUMUKI-INC-060:** PRE_WRITE deja de aceptar evidencia TDD/BDD de baseline caducada para cambios in-scope.
10
+ - **Baseline antes de editar:** si el componente tocado requiere TDD/BDD, la evidencia debe ser reciente y pasada; si no, Pumuki bloquea y pide reejecutar baseline tests.
11
+ - **Rollout:** publicar `pumuki@6.3.143`, repinear primero RuralGo y revalidar `status`, `doctor` y el bloqueo por evidencia stale.
12
+
7
13
  ### 2026-05-05 (v6.3.142)
8
14
 
9
15
  - **RuralGo PUMUKI-INC-059:** PRE_WRITE vuelve a pedir hechos AST para iOS SOLID aunque el flag experimental de heurísticas esté apagado.
@@ -76,10 +76,33 @@ const isTimelineOrdered = (timestamps: ReadonlyArray<string | undefined>): boole
76
76
  return true;
77
77
  };
78
78
 
79
+ const DEFAULT_EVIDENCE_MAX_AGE_SECONDS = 900;
80
+
81
+ const resolveEvidenceMaxAgeSeconds = (): number => {
82
+ const raw = process.env.PUMUKI_TDD_BDD_EVIDENCE_MAX_AGE_SECONDS?.trim();
83
+ if (!raw) {
84
+ return DEFAULT_EVIDENCE_MAX_AGE_SECONDS;
85
+ }
86
+ const parsed = Number.parseInt(raw, 10);
87
+ if (!Number.isFinite(parsed) || parsed <= 0) {
88
+ return DEFAULT_EVIDENCE_MAX_AGE_SECONDS;
89
+ }
90
+ return parsed;
91
+ };
92
+
93
+ const resolveEvidenceAgeSeconds = (generatedAt: string, nowMs: number): number | null => {
94
+ const generatedAtMs = new Date(generatedAt).getTime();
95
+ if (Number.isNaN(generatedAtMs)) {
96
+ return null;
97
+ }
98
+ return Math.max(0, Math.floor((nowMs - generatedAtMs) / 1000));
99
+ };
100
+
79
101
  export const enforceTddBddPolicy = (params: {
80
102
  facts: ReadonlyArray<Fact>;
81
103
  repoRoot: string;
82
104
  branch: string | null;
105
+ now?: () => number;
83
106
  }): TddBddEnforcementResult => {
84
107
  const scope = classifyTddBddScope(params.facts);
85
108
  const baseSnapshot: TddBddSnapshot = {
@@ -210,6 +233,46 @@ export const enforceTddBddPolicy = (params: {
210
233
  };
211
234
  }
212
235
 
236
+ const maxAgeSeconds = resolveEvidenceMaxAgeSeconds();
237
+ const ageSeconds = resolveEvidenceAgeSeconds(
238
+ evidenceRead.evidence.generated_at,
239
+ params.now?.() ?? Date.now()
240
+ );
241
+ if (ageSeconds === null || ageSeconds > maxAgeSeconds) {
242
+ const messageAge =
243
+ ageSeconds === null ? 'unknown' : `${ageSeconds}s`;
244
+ const finding = buildFinding({
245
+ ruleId: 'generic_tdd_baseline_required',
246
+ code: 'TDD_BDD_EVIDENCE_STALE',
247
+ message:
248
+ `TDD/BDD evidence is stale for this PRE_WRITE baseline: age=${messageAge}, max=${maxAgeSeconds}s. Re-run the baseline tests for the touched component and refresh evidence before editing related code.`,
249
+ filePath: evidenceRead.path,
250
+ });
251
+ return {
252
+ findings: [finding],
253
+ snapshot: {
254
+ ...baseSnapshot,
255
+ status: 'blocked',
256
+ evidence: {
257
+ ...baseSnapshot.evidence,
258
+ state: 'valid',
259
+ version: evidenceRead.evidence.version,
260
+ slices_total: evidenceRead.evidence.slices.length,
261
+ slices_valid: 0,
262
+ slices_invalid: evidenceRead.evidence.slices.length,
263
+ integrity_ok: evidenceRead.integrity.valid,
264
+ errors: ['TDD_BDD_EVIDENCE_STALE'],
265
+ baseline: {
266
+ required: true,
267
+ passed: 0,
268
+ missing: 0,
269
+ failed: 0,
270
+ },
271
+ },
272
+ },
273
+ };
274
+ }
275
+
213
276
  const sliceFindings: Finding[] = [];
214
277
  const seenSliceIds = new Set<string>();
215
278
  let validSlices = 0;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pumuki",
3
- "version": "6.3.142",
3
+ "version": "6.3.143",
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": {