@andresmassello/uscha 1.51.1 → 1.51.3
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/README.md +6 -1
- package/package.json +3 -2
- package/uscha-kit/.claude/skills/uscha-mirador/SKILL.md +11 -4
- package/uscha-kit/.claude/skills/uscha-mirador/mirador-render.py +16 -8
- package/uscha-kit/.claude-plugin/plugin.json +2 -2
- package/uscha-kit/.codex-plugin/plugin.json +2 -2
- package/uscha-kit/INSTALL.md +3 -0
- package/uscha-kit/README.md +1 -1
- package/uscha-kit/VERSION +1 -1
- package/uscha-kit/install-uscha.py +9 -3
- package/uscha-kit/skills/uscha-mirador/SKILL.md +11 -4
- package/uscha-kit/skills/uscha-mirador/mirador-render.py +16 -8
- package/uscha-kit/uscha.config.json +1 -1
- package/uscha-kit/CHANGELOG-1.10.0.md +0 -84
- package/uscha-kit/CHANGELOG-1.11.0.md +0 -67
- package/uscha-kit/CHANGELOG-1.12.0.md +0 -46
- package/uscha-kit/CHANGELOG-1.13.0.md +0 -33
- package/uscha-kit/CHANGELOG-1.14.0.md +0 -42
- package/uscha-kit/CHANGELOG-1.15.0.md +0 -58
- package/uscha-kit/CHANGELOG-1.16.0.md +0 -55
- package/uscha-kit/CHANGELOG-1.17.0.md +0 -44
- package/uscha-kit/CHANGELOG-1.18.0.md +0 -42
- package/uscha-kit/CHANGELOG-1.19.0.md +0 -41
- package/uscha-kit/CHANGELOG-1.2.2.md +0 -16
- package/uscha-kit/CHANGELOG-1.2.3.md +0 -20
- package/uscha-kit/CHANGELOG-1.2.4.md +0 -10
- package/uscha-kit/CHANGELOG-1.2.5.md +0 -23
- package/uscha-kit/CHANGELOG-1.2.6.md +0 -11
- package/uscha-kit/CHANGELOG-1.2.7.md +0 -15
- package/uscha-kit/CHANGELOG-1.2.8.md +0 -24
- package/uscha-kit/CHANGELOG-1.2.9.md +0 -4
- package/uscha-kit/CHANGELOG-1.20.0.md +0 -29
- package/uscha-kit/CHANGELOG-1.21.0.md +0 -33
- package/uscha-kit/CHANGELOG-1.22.0.md +0 -60
- package/uscha-kit/CHANGELOG-1.23.0.md +0 -75
- package/uscha-kit/CHANGELOG-1.24.0.md +0 -50
- package/uscha-kit/CHANGELOG-1.25.0.md +0 -55
- package/uscha-kit/CHANGELOG-1.26.0.md +0 -70
- package/uscha-kit/CHANGELOG-1.27.0.md +0 -45
- package/uscha-kit/CHANGELOG-1.28.0.md +0 -35
- package/uscha-kit/CHANGELOG-1.29.0.md +0 -20
- package/uscha-kit/CHANGELOG-1.3.0.md +0 -74
- package/uscha-kit/CHANGELOG-1.30.0.md +0 -46
- package/uscha-kit/CHANGELOG-1.31.0.md +0 -59
- package/uscha-kit/CHANGELOG-1.32.0.md +0 -50
- package/uscha-kit/CHANGELOG-1.33.0.md +0 -46
- package/uscha-kit/CHANGELOG-1.34.0.md +0 -55
- package/uscha-kit/CHANGELOG-1.35.0.md +0 -30
- package/uscha-kit/CHANGELOG-1.36.0.md +0 -33
- package/uscha-kit/CHANGELOG-1.37.0.md +0 -41
- package/uscha-kit/CHANGELOG-1.38.0.md +0 -11
- package/uscha-kit/CHANGELOG-1.39.0.md +0 -14
- package/uscha-kit/CHANGELOG-1.4.0.md +0 -68
- package/uscha-kit/CHANGELOG-1.40.0.md +0 -16
- package/uscha-kit/CHANGELOG-1.40.1.md +0 -11
- package/uscha-kit/CHANGELOG-1.40.2.md +0 -13
- package/uscha-kit/CHANGELOG-1.41.0.md +0 -18
- package/uscha-kit/CHANGELOG-1.41.1.md +0 -53
- package/uscha-kit/CHANGELOG-1.41.2.md +0 -34
- package/uscha-kit/CHANGELOG-1.41.3.md +0 -30
- package/uscha-kit/CHANGELOG-1.42.0.md +0 -41
- package/uscha-kit/CHANGELOG-1.43.0.md +0 -37
- package/uscha-kit/CHANGELOG-1.44.0.md +0 -90
- package/uscha-kit/CHANGELOG-1.44.1.md +0 -26
- package/uscha-kit/CHANGELOG-1.45.0.md +0 -58
- package/uscha-kit/CHANGELOG-1.46.0.md +0 -50
- package/uscha-kit/CHANGELOG-1.46.1.md +0 -35
- package/uscha-kit/CHANGELOG-1.47.0.md +0 -45
- package/uscha-kit/CHANGELOG-1.48.0.md +0 -35
- package/uscha-kit/CHANGELOG-1.48.1.md +0 -55
- package/uscha-kit/CHANGELOG-1.48.2.md +0 -47
- package/uscha-kit/CHANGELOG-1.49.0.md +0 -45
- package/uscha-kit/CHANGELOG-1.5.0.md +0 -64
- package/uscha-kit/CHANGELOG-1.50.0.md +0 -52
- package/uscha-kit/CHANGELOG-1.50.1.md +0 -52
- package/uscha-kit/CHANGELOG-1.50.2.md +0 -62
- package/uscha-kit/CHANGELOG-1.51.0.md +0 -44
- package/uscha-kit/CHANGELOG-1.51.1.md +0 -33
- package/uscha-kit/CHANGELOG-1.6.0.md +0 -57
- package/uscha-kit/CHANGELOG-1.7.0.md +0 -74
- package/uscha-kit/CHANGELOG-1.8.0.md +0 -46
- package/uscha-kit/CHANGELOG-1.9.0.md +0 -112
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
# dev-loop-kit 1.15.0 — scrub del golden master (2026-07-03)
|
|
2
|
-
|
|
3
|
-
Sexta mejora del backlog PragProg (M7 de `docs/analisis-pragmatic-programmer.md`;
|
|
4
|
-
Topic 41 *"no apoyar tests en cosas no confiables"* — timestamps exactos,
|
|
5
|
-
ids, posiciones absolutas). Sin esto, cualquier salida del código original con
|
|
6
|
-
volátiles vuelve el golden master perma-rojo — y un golden perma-rojo mata la
|
|
7
|
-
credibilidad de todo el gate. Smoke suite: 97/97.
|
|
8
|
-
|
|
9
|
-
## La idea
|
|
10
|
-
|
|
11
|
-
- `golden.scrub.json` en el root de fixtures declara los volátiles:
|
|
12
|
-
`{"rules": [{"pattern": "<regex>", "replace": "<placeholder>"}]}`.
|
|
13
|
-
- `golden-diff` enmascara AMBOS lados (received y approved) antes de comparar —
|
|
14
|
-
solo texto; el binario sigue byte a byte. El match vía scrub se reporta
|
|
15
|
-
**APARTE** (`N via scrub` + conteo de sustituciones por regla): el masking
|
|
16
|
-
jamás es invisible.
|
|
17
|
-
- **Cadena de custodia**: las reglas se declaran en characterize (paso nuevo,
|
|
18
|
-
ANTES de la aprobación) y el humano las aprueba junto con los `.approved` —
|
|
19
|
-
son contrato. gate-check flaggea cualquier edición posterior a
|
|
20
|
-
`golden.scrub.json` como señal blanda SIEMPRE visible (`--strict` la gatea):
|
|
21
|
-
una regla ensanchada puede enmascarar divergencia real.
|
|
22
|
-
- Archivo de scrub inválido (JSON roto, regex rota) = **exit 2 explícito** —
|
|
23
|
-
el scrub nunca se saltea en silencio.
|
|
24
|
-
- Preferencia documentada: arreglar el determinismo EN LA FUENTE (checklist de
|
|
25
|
-
Phase 2 de characterize); el scrub es para lo que genuinamente no se controla.
|
|
26
|
-
|
|
27
|
-
## Engine (qa_ledger.py)
|
|
28
|
-
|
|
29
|
-
- `_load_scrub_rules()` / `_scrub()` + integración en `cmd_golden_diff`
|
|
30
|
-
(`matched_scrubbed`, `scrub_rules`, `scrub_substitutions` en el JSON —
|
|
31
|
-
el conteo es del lado RECEIVED; sumar ambos lados duplicaría cada volátil).
|
|
32
|
-
- gate-check: lista `scrub_rules_touched` (soft) en veredicto y JSON — cubre
|
|
33
|
-
agregar, modificar y BORRAR el archivo (borrar reglas también es editarlas).
|
|
34
|
-
- Shape estricta del archivo: top-level lista, key `rules` ausente o typo =
|
|
35
|
-
exit 2 — un error de forma no puede degradar a "cero reglas" en silencio.
|
|
36
|
-
|
|
37
|
-
## Hardening (review fresco pre-commit, 4 hallazgos aplicados)
|
|
38
|
-
|
|
39
|
-
- AttributeError cruda con lista top-level en el scrub file → exit 2 limpio.
|
|
40
|
-
- `{}` sin key `rules` cargaba cero reglas en silencio → exit 2.
|
|
41
|
-
- Doble conteo de sustituciones (received + approved al mismo dict) → solo
|
|
42
|
-
received.
|
|
43
|
-
- Borrado de `golden.scrub.json` no se flaggeaba (el check vivía solo en
|
|
44
|
-
líneas `+`) → también en `-`.
|
|
45
|
-
|
|
46
|
-
## Smoke
|
|
47
|
-
|
|
48
|
-
- **T37** — respetando INV-GOLDEN-01: crear un `.approved` es un acto HUMANO
|
|
49
|
-
incluso en tests, así que el path CLEAN-vía-scrub NO se auto-testea (misma
|
|
50
|
-
disciplina que el path CLEAN byte-a-byte desde 1.3.0). Se prueba la mecánica
|
|
51
|
-
a nivel función (enmascara, cuenta, binario intacto, divergencia real no se
|
|
52
|
-
tapa) + los paths CLI sin `.approved`: scrub no fabrica aprobación (DIVERGE
|
|
53
|
-
se mantiene), scrub inválido exit 2, gate-check flaggea ediciones.
|
|
54
|
-
|
|
55
|
-
## Diferido consciente
|
|
56
|
-
|
|
57
|
-
- Reglas por-fixture (hoy son por root de fixtures) — si un corpus real lo
|
|
58
|
-
pide, se agrega `"glob"` opcional por regla.
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
# dev-loop-kit 1.16.0 — regression-capture: Find Bugs Once (2026-07-03)
|
|
2
|
-
|
|
3
|
-
Séptima mejora del backlog PragProg (M1 de `docs/analisis-pragmatic-programmer.md`;
|
|
4
|
-
Topic 51 / Tip 94 *"Find Bugs Once"* + Tip 31 *"Failing Test Before Fixing
|
|
5
|
-
Code"*). Ataca el cierre narrado de findings: el agente reporta `fixed` y nadie
|
|
6
|
-
pregunta **qué test reproduce el bug que dice haber arreglado**.
|
|
7
|
-
Smoke suite: 106/106.
|
|
8
|
-
|
|
9
|
-
## La idea (measured beats narrated, ahora sobre el CIERRE)
|
|
10
|
-
|
|
11
|
-
- `regression-check --repo X [--fixed N] --diff/--from-git`: cruza los findings
|
|
12
|
-
cerrados con el diff que los arregla. Verdicts:
|
|
13
|
-
- **N/A** — nada cerrado, nada que exigir.
|
|
14
|
-
- **MEASURED** — el diff agrega/modifica líneas en el árbol de test
|
|
15
|
-
(clasificador compartido de los 9 stacks).
|
|
16
|
-
- **NARRATED** — desaparecieron findings sin tocar UN solo test. Aconseja
|
|
17
|
-
por default (exit 0 con warning); `--strict` gatea; `log-gate --kind
|
|
18
|
-
regression --verdict fail` lo persiste si el equipo decide bloquear.
|
|
19
|
-
- Sin `--fixed` explícito lee la suma de `fixed` de la iteración más reciente
|
|
20
|
-
del repo en el ledger — el dato ya estaba, ahora se interroga.
|
|
21
|
-
- **escape_analysis obligatoria**: resolver un `flag-blocker` ahora EXIGE
|
|
22
|
-
`--escape-analysis "<qué gate/test debió atraparlo y qué se hizo>"` —
|
|
23
|
-
la reflexión es parte del cierre, no opcional (cerrar un BLOCKER sin ella
|
|
24
|
-
es garantía de encontrarlo dos veces). Se persiste en el registro del gate.
|
|
25
|
-
|
|
26
|
-
## Decisiones de diseño (documentadas, no implícitas)
|
|
27
|
-
|
|
28
|
-
- La evidencia es a nivel **DIFF** y es mecánica: ¿el diff que arregla agrega
|
|
29
|
-
líneas NO VACÍAS en el árbol de test? — un hecho. El mapeo finding→test
|
|
30
|
-
específico sería adivinanza sin una convención de naming
|
|
31
|
-
(¿`test_regr_<fingerprint>`?): **diferido consciente**, el gate mide lo que
|
|
32
|
-
se puede medir sin inventar.
|
|
33
|
-
- **Límite disclosed (hallazgo del review fresco, aplicado)**: es un tripwire,
|
|
34
|
-
no un juez de calidad — una línea de comentario en un test file cuenta como
|
|
35
|
-
evidencia (juzgar contenido entre 9 lenguajes sería adivinanza). Mitigación
|
|
36
|
-
honesta: las líneas en blanco NO cuentan, y las señales
|
|
37
|
-
`has_test_definition`/`has_assertion` se exponen como hechos en el JSON —
|
|
38
|
-
un MEASURED sin ninguna de las dos imprime "evidencia DÉBIL" para el ojo
|
|
39
|
-
humano. La calidad de los tests la juzga pit-check (mutation testing), no
|
|
40
|
-
este gate.
|
|
41
|
-
- Advisory-first: NARRATED no bloquea por default — mismo patrón de adopción
|
|
42
|
-
incremental que acceptance trazable (1.10.0) y los advisories de 1.14.0.
|
|
43
|
-
|
|
44
|
-
## Skills
|
|
45
|
-
|
|
46
|
-
- `dev-loop`: tras loguear un pass con `--fixed > 0`, correr `regression-check`;
|
|
47
|
-
cierre NARRATED = escribir el test de regresión (el test que falla va ANTES
|
|
48
|
-
del fix).
|
|
49
|
-
|
|
50
|
-
## Smoke
|
|
51
|
-
|
|
52
|
-
- **T38**: fix sin tests → NARRATED (exit 0 advisory / `--strict` exit 1) ·
|
|
53
|
-
fix con test nuevo → MEASURED (pasa aun con `--strict`) · `--fixed 0` → N/A ·
|
|
54
|
-
lookup del `fixed` de la última iteración del ledger sin `--fixed`.
|
|
55
|
-
- **T4 endurecido**: resolver un blocker sin `--escape-analysis` → rechazado.
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
# dev-loop-kit 1.17.0 — procedencia visible de umbrales (2026-07-03)
|
|
2
|
-
|
|
3
|
-
Octava mejora del backlog PragProg (M5 de `docs/analisis-pragmatic-programmer.md`;
|
|
4
|
-
Tip 8 *"Make Quality a Requirements Issue"* + Topic 8 *"ETC es un valor, no una
|
|
5
|
-
regla"*). Resolución elegida por el humano entre tres opciones: **procedencia
|
|
6
|
-
visible** — ni fiel-al-libro (advisory por default hubiera desarmado el
|
|
7
|
-
anti-Goodhart) ni rechazo. Smoke suite: 111/111.
|
|
8
|
-
|
|
9
|
-
## La idea (el conteo es hecho · el umbral es opinión · salvo que lo declares)
|
|
10
|
-
|
|
11
|
-
- **Que el cap EXISTA es principio, no opinión**: "tests rojos ⇒ no estás
|
|
12
|
-
ready" es una definición. Los caps siguen mordiendo por default — nada se
|
|
13
|
-
afloja, ningún usuario existente ve su score subir en silencio.
|
|
14
|
-
- **El NÚMERO es opinión del kit SALVO que el humano lo declare.** El acto de
|
|
15
|
-
declaración ya existía: el `dev-loop.config.json` commiteado es humano-owned.
|
|
16
|
-
Valor explícito en `config.defaults` = requerimiento; fallback a la
|
|
17
|
-
constante del engine = default del kit. Cero schema nuevo.
|
|
18
|
-
- Lo que faltaba era la **etiqueta**: ahora cada umbral que muerde dice de
|
|
19
|
-
dónde vino.
|
|
20
|
-
|
|
21
|
-
## Engine (qa_ledger.py)
|
|
22
|
-
|
|
23
|
-
- `readiness`: el cap que muerde se etiqueta — `capped at 35: tests red —
|
|
24
|
-
umbral default del kit` vs `— umbral requerimiento (config)`. El threshold
|
|
25
|
-
de coverage se etiqueta en la línea resumen (`thr 60, declarado` /
|
|
26
|
-
`default del kit`). JSON expone `cap_source` y `thresholds_declared`.
|
|
27
|
-
- `simplicity-check`: los presupuestos declarados (config o CLI) llevan `*`
|
|
28
|
-
en la tabla; sin ninguno declarado imprime el aviso "todos los presupuestos
|
|
29
|
-
son defaults del kit — opinión, no requerimiento". JSON expone
|
|
30
|
-
`budgets_declared`.
|
|
31
|
-
|
|
32
|
-
## Skills
|
|
33
|
-
|
|
34
|
-
- `discovery`: paso 9 nuevo en la agenda — **quality bar**: "¿qué nivel de
|
|
35
|
-
calidad BASTA acá y qué dimensiones son negociables?" con propuesta acorde
|
|
36
|
-
al perfil de riesgo (un core de pagos no es un dashboard interno). Lo que el
|
|
37
|
-
humano declara va al config — declarar ES commitear el config.
|
|
38
|
-
|
|
39
|
-
## Smoke
|
|
40
|
-
|
|
41
|
-
- **T39**: cap declarado (`readiness_caps.tests_red` en config) → etiqueta
|
|
42
|
-
`requerimiento (config)` en JSON y texto · sandbox sin caps declarados →
|
|
43
|
-
lista vacía · simplicity sin declarar → aviso de opinión · presupuesto por
|
|
44
|
-
CLI → listado en `budgets_declared`.
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
# dev-loop-kit 1.18.0 — phase: la FSM derivada del workflow (2026-07-03)
|
|
2
|
-
|
|
3
|
-
Novena mejora del backlog PragProg (M4 de `docs/analisis-pragmatic-programmer.md`;
|
|
4
|
-
Topic 29 *"Juggling the Real World"* — FSM como tabla de datos). Resuelta con
|
|
5
|
-
decisión humana explícita entre tres opciones: **FSM derivada** (ni la FSM
|
|
6
|
-
declarada del análisis original, ni solo-pr-gate, ni diferir).
|
|
7
|
-
Smoke suite: 117/117.
|
|
8
|
-
|
|
9
|
-
## La idea (measured beats narrated, aplicado a la FSM misma)
|
|
10
|
-
|
|
11
|
-
- El reframe clave: una FSM donde el agente DECLARA "entro a build/qa" es
|
|
12
|
-
**estado narrado** — exactamente lo que el kit combate. Acá el estado se
|
|
13
|
-
**COMPUTA** de los hechos del ledger; no existen transiciones ilegales que
|
|
14
|
-
validar porque no hay nada que declarar.
|
|
15
|
-
- Reglas de derivación (precedencia): **escalated** (escalación abierta — el
|
|
16
|
-
acto humano pendiente pisa todo) → **pr-ready** (convergencia + tests verdes
|
|
17
|
-
medidos + 0 BLOCKER/CRITICAL) → **qa** (pasos registrados sin converger) →
|
|
18
|
-
**build** (snapshots medidos, sin QA) → **plan** (ledger virgen).
|
|
19
|
-
- La "tabla de estados × eventos" del análisis original se convierte en estas
|
|
20
|
-
reglas de derivación — documentadas en el código como datos, no prosa.
|
|
21
|
-
|
|
22
|
-
## Engine (qa_ledger.py)
|
|
23
|
-
|
|
24
|
-
- `phase --repo X` (subcomando 21): imprime el estado derivado CON su
|
|
25
|
-
evidencia. `--require pr-ready` sale 1 si los hechos no alcanzan, listando
|
|
26
|
-
exactamente qué falta ("el estado no se negocia, se construye"). JSON:
|
|
27
|
-
`{phase, evidence, required, satisfied}`.
|
|
28
|
-
- `dev-loop` Phase 6: el PR se gatea con `phase --require pr-ready` ANTES de
|
|
29
|
-
abrirse — la transición ilegal "PR sin convergencia" del análisis original
|
|
30
|
-
ahora es un hecho bloqueante mecánico, que era todo el punto de M4.
|
|
31
|
-
|
|
32
|
-
## Smoke
|
|
33
|
-
|
|
34
|
-
- **T40**: ciclo de vida completo derivado — virgen→plan · snapshot→build ·
|
|
35
|
-
QA sin converger→qa · pr-ready con findings abiertos→exit 1 · escalación
|
|
36
|
-
abierta→escalated (pisa todo) · convergido+limpio→pr-ready.
|
|
37
|
-
|
|
38
|
-
## Diferido consciente
|
|
39
|
-
|
|
40
|
-
- El estado es per-repo; un estado agregado feature-level (todos los repos
|
|
41
|
-
pr-ready + integración verde) se deriva componiendo — si el dogfooding lo
|
|
42
|
-
pide como comando propio, se agrega.
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
# dev-loop-kit 1.19.0 — spikes formales: descartable por contrato (2026-07-03)
|
|
2
|
-
|
|
3
|
-
Décima y ÚLTIMA mejora del backlog PragProg (M10 de
|
|
4
|
-
`docs/analisis-pragmatic-programmer.md`; Tip 21 *"Prototype to Learn"* +
|
|
5
|
-
Topic 37 *"It's Playtime!"*). Con esta release, **las 10 mejoras del cruce con
|
|
6
|
-
The Pragmatic Programmer están resueltas** — 8 implementadas directas y 2
|
|
7
|
-
resueltas con decisión humana explícita entre opciones (M5 procedencia, M4 FSM
|
|
8
|
-
derivada). Convención elegida por el humano: prefijo **`spike/*`**.
|
|
9
|
-
Smoke suite: 121/121.
|
|
10
|
-
|
|
11
|
-
## La idea (la versión ejecutable de "make it clear this code is disposable")
|
|
12
|
-
|
|
13
|
-
- Un riesgo de incertidumbre ALTA en discovery dispara la pregunta: "¿amerita
|
|
14
|
-
un spike time-boxed antes de congelar la SPEC?" (paso 10 de la agenda).
|
|
15
|
-
- El spike corre en una rama `spike/*` y su ÚNICO output legítimo es un
|
|
16
|
-
**ADR con lecciones** — hechos que alimentan la SPEC, jamás código mergeable.
|
|
17
|
-
- El contrato es ejecutable, estilo INV-GOLDEN-01: `phase --require pr-ready`
|
|
18
|
-
**rechaza cualquier rama `spike/*`** aunque los hechos del ledger den
|
|
19
|
-
pr-ready — "escribí el ADR y arrancá limpio en una rama normal". Sin
|
|
20
|
-
`--require` solo informa (consultar no gatea). Resuelve la tensión con
|
|
21
|
-
Stone Soup sin romper spec-first.
|
|
22
|
-
|
|
23
|
-
## Engine (qa_ledger.py)
|
|
24
|
-
|
|
25
|
-
- `_spike_branch()`: `git symbolic-ref --short -q HEAD` (funciona antes del
|
|
26
|
-
primer commit; detached HEAD o directorio sin git = sin veto, disclosed).
|
|
27
|
-
- `phase --require pr-ready`: veto de spike ANTES del veredicto; JSON expone
|
|
28
|
-
`spike_branch`.
|
|
29
|
-
|
|
30
|
-
## Smoke
|
|
31
|
-
|
|
32
|
-
- **T41**: repo pr-ready por hechos PERO en `spike/*` → exit 1 con el mensaje
|
|
33
|
-
del contrato · consulta sin `--require` → informa sin gatear · rama normal
|
|
34
|
-
→ pr-ready vuelve a pasar.
|
|
35
|
-
|
|
36
|
-
## El backlog PragProg, cerrado
|
|
37
|
-
|
|
38
|
-
M2 (1.10.0) · M9 (1.11.0) · M8 (1.12.0) · M3 (1.13.0) · M6 (1.14.0) ·
|
|
39
|
-
M7 (1.15.0) · M1 (1.16.0) · M5 (1.17.0) · M4 (1.18.0) · M10 (1.19.0).
|
|
40
|
-
Cada release: smoke verde → review fresco → hallazgos aplicados → triple
|
|
41
|
-
sync → commit único. Lo diferido consciente de cada una vive en su CHANGELOG.
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
# dev-loop-kit 1.2.2
|
|
2
|
-
|
|
3
|
-
## Fixes (simplicity-check)
|
|
4
|
-
- **[BLOCKER] `--from-git` crasheaba en Windows** — `subprocess.run` sin `encoding`
|
|
5
|
-
decodificaba el diff con cp1252 y reventaba (UnicodeDecodeError → None.splitlines).
|
|
6
|
-
Fix: `encoding="utf-8", errors="replace"`.
|
|
7
|
-
- **Salida en mojibake en consola Windows** — `main()` fuerza `stdout/stderr` a UTF-8.
|
|
8
|
-
- **No filtraba por tipo de archivo** — medía docs/config/resources como código
|
|
9
|
-
(inflaba lines/nesting; falsos OVERBUILT). Ahora solo cuenta código
|
|
10
|
-
(`_SIMPLICITY_CODE_EXT` + `SKIP_DIRS`), y reporta cuántos archivos salteó.
|
|
11
|
-
|
|
12
|
-
## Nuevo: `pit-check` (mutation testing)
|
|
13
|
-
- Gate de EFECTIVIDAD de tests (coverage miente): ingesta el `mutations.xml` de PIT,
|
|
14
|
-
reporta mutation score + **test-strength** (matados/cubiertos) + hotspots.
|
|
15
|
-
- Invariante **Tests efectivos** agregada a `templates/CONSTITUTION.md`.
|
|
16
|
-
- Tier scheduled/incremental (PIT es caro), no inner loop.
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
# dev-loop-kit 1.2.3
|
|
2
|
-
|
|
3
|
-
## Fixes (qa_ledger.py) — verificados por doble review adversarial (judgment-day, 2 rondas, 0 critical)
|
|
4
|
-
- pit-check: NON_VIABLE + RUN_ERROR excluidos del denominador (antes inflaban el score y
|
|
5
|
-
podían tirar un BELOW-GATE falso). Nuevo campo `excluded`.
|
|
6
|
-
- simplicity-check: parser robusto con máquina de estados `in_hunk` — una línea agregada
|
|
7
|
-
`++ x` (que en el diff aparece como `+++ x`) ya no se confunde con un header y deja de
|
|
8
|
-
perder el conteo del resto del hunk.
|
|
9
|
-
- simplicity-check: skip-set más angosto (`_SIMPLICITY_SKIP`) — código en paquetes
|
|
10
|
-
`generated`/`out`/`bin`/`dist` ya no se descarta del budget.
|
|
11
|
-
|
|
12
|
-
## Nuevo (CONSTITUTION.md)
|
|
13
|
-
- Invariante "Integridad del gate — no gamear al que mide": un diff que debilita el aparato
|
|
14
|
-
de medición (tests/lint/thresholds) o reescribe una masa de asserts = BLOCKER; checker
|
|
15
|
-
no-correlacionado para alto blast-radius. (Osmani, "Agentic Code Review".)
|
|
16
|
-
|
|
17
|
-
## Limitación conocida (documentada)
|
|
18
|
-
- simplicity-check espera diffs formato git (`diff --git` por archivo, como `git diff` y
|
|
19
|
-
`--from-git`). Un `diff -u` plano de POSIX sin esos headers miscuenta archivos después
|
|
20
|
-
del primero. Usar `--from-git` o `git diff > file`.
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
# dev-loop-kit 1.2.4
|
|
2
|
-
|
|
3
|
-
## Nuevo: gate-check (integridad del gate — "no gamear al que mide")
|
|
4
|
-
- Comando `qa_ledger.py gate-check`: detecta si un diff DEBILITA el aparato de medición.
|
|
5
|
-
- **BLOCKER (exit 1):** tests borrados o deshabilitados, thresholds de coverage/mutation bajados.
|
|
6
|
-
- **Revisar (soft):** supresiones de lint agregadas, asserts removidos en tests. `--strict` los gatea.
|
|
7
|
-
- Lee diffs formato git (`--from-git` / `--diff` / stdin). stdlib pura.
|
|
8
|
-
- Implementa en CÓDIGO la invariante "Integridad del gate" de la CONSTITUTION (antes solo texto).
|
|
9
|
-
- (Osmani, "Agentic Code Review": los red-flags para revisores humanos; el detector automático
|
|
10
|
-
y el principio "el aparato no lo modifica el cambio que mide" son síntesis del kit.)
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
# dev-loop-kit 1.2.5 — destilación ("gates de hechos bloquean, adivinadores de prosa avisan")
|
|
2
|
-
|
|
3
|
-
## Nuevo: golden-diff + INV-GOLDEN-01 (golden/approval testing)
|
|
4
|
-
- `qa_ledger.py golden-diff`: byte-compara `*.received.*` vs `*.approved.*`. Cualquier no-match
|
|
5
|
-
o `.received` sin `.approved` = DIVERGE (exit 1). Es un HECHO, no un juicio. Nunca toca `.approved`.
|
|
6
|
-
- Invariante `INV-GOLDEN-01` (CWE-440) en CONSTITUTION: en migraciones, golden capturado ANTES de
|
|
7
|
-
tocar el módulo; el golden lo captura un script sobre el código ORIGINAL, el agente no lo authorea.
|
|
8
|
-
- (Del HANDOFF de golden testing — pendiente a mano: skill `characterize`, hook PreToolUse que bloquee
|
|
9
|
-
escrituras a `.approved`, `.gitattributes *.approved.* binary`, y decisión de stack del harness.)
|
|
10
|
-
|
|
11
|
-
## Destilación (distinción hechos vs adivinanza)
|
|
12
|
-
- `spec-check` → **ADVISORY** por defecto (heurística sobre prosa): reporta, NO bloquea. `--strict` gatea.
|
|
13
|
-
- `simplicity-check` → el regex de "abstracciones" (falsos positivos con records/DTOs) sale del score y
|
|
14
|
-
del hard-cap; queda como métrica/flag informativa. Los caps numéricos (líneas/archivos/anidación) siguen gateando.
|
|
15
|
-
|
|
16
|
-
## Fixes de spec-check (judgment-day Ronda 1, 2 jueces, 2 critical + 4 warnings, todos resueltos)
|
|
17
|
-
- Code-fence tracking (un `# Exclusions` dentro de ```` ``` ```` ya no cuenta), setext headings,
|
|
18
|
-
checkbox vacío no cuenta como criterio, `_SC_ACCEPT` anclado (no "Success/Exit criteria"),
|
|
19
|
-
`\d` suelto ya no exime vago, stack ambiguo podado + scopeado a criterios, vagos en español sumados.
|
|
20
|
-
|
|
21
|
-
## Gates: hechos (bloquean) vs prosa (avisan)
|
|
22
|
-
- BLOQUEAN (leen hechos): golden-diff, pit-check, gate-check, readiness/rebuild, caps de simplicity.
|
|
23
|
-
- AVISAN (heurística): spec-check, abstracciones de simplicity.
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
# dev-loop-kit 1.2.6 — fix golden-diff (judgment-day, 2 jueces, coincidencia)
|
|
2
|
-
|
|
3
|
-
## Fix (cmd_golden_diff) — verificado contra los casos reproducidos por los jueces
|
|
4
|
-
- **[CRITICAL] `str.replace` global** reemplazaba TODAS las ocurrencias de `.received.`:
|
|
5
|
-
con el marcador en una carpeta padre (snapshots por fecha) o dos veces en el nombre,
|
|
6
|
-
derivaba el `.approved` mal → DIVERGE falso, y en el peor caso un **FALSE CLEAN** (dejaba
|
|
7
|
-
pasar una divergencia, exit 0). Fix: `_golden_approved_path()` deriva solo del BASENAME,
|
|
8
|
-
última ocurrencia (rpartition), nunca del path del directorio.
|
|
9
|
-
- **[real] directorios `*.received.*`** se escaneaban como fixtures → filtro `os.path.isfile`.
|
|
10
|
-
- **[gap] `Foo.received` sin extensión** se salteaba (false CLEAN) → segundo glob `*.received`.
|
|
11
|
-
- Read-only confirmado por ambos jueces: cero write/rename; el agente no puede authorear el golden.
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
# dev-loop-kit 1.2.7 — skill reverse-discovery (front brownfield)
|
|
2
|
-
|
|
3
|
-
## Nuevo skill: reverse-discovery
|
|
4
|
-
- Hermano brownfield de `discovery`, para migrar/modernizar un sistema EXISTENTE.
|
|
5
|
-
- El inverso de discovery: el sistema ya existe y su comportamiento ES la verdad → se
|
|
6
|
-
EXTRAEN hechos, no se propone forma.
|
|
7
|
-
- **Facts-only por diseño:** produce SOLO (1) un mapa del sistema (endpoints, contratos,
|
|
8
|
-
grafo de dependencias, candidatos de módulo vía análisis estático) y (2) un golden suite
|
|
9
|
-
capturado mecánicamente en los bordes. NO authorea SPEC/ADR inferidos — eso lo escribe el
|
|
10
|
-
humano leyendo los hechos; las decisiones forward de módulos van a `/adr-refine`.
|
|
11
|
-
- Hereda INV-GOLDEN-01: el agente nunca toca los `.approved`.
|
|
12
|
-
- Cae limpio del lado "hechos" de la línea hechos-vs-prosa: análisis estático + byte-captura,
|
|
13
|
-
cero heurística sobre prosa → nada frágil que se rompa.
|
|
14
|
-
- Flujo migración: reverse-discovery → humano escribe SPEC + /adr-refine → /dev-loop
|
|
15
|
-
(golden-diff + ApplicationModules.verify() verdes) → readiness + human gate.
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
# dev-loop-kit 1.2.8 — golden testing completo (characterize + hook + gitattributes)
|
|
2
|
-
|
|
3
|
-
## Nuevo skill: characterize (golden-capture)
|
|
4
|
-
- Captura el golden del código ORIGINAL con inputs reales, por un harness determinístico.
|
|
5
|
-
- 4 fases: harness → checklist de no-determinismo (locale es-AR obligatorio) → captura
|
|
6
|
-
(.received) → STOP para aprobación humana. NUNCA crea/edita un .approved.
|
|
7
|
-
- Lo orquesta reverse-discovery en su fase 2.
|
|
8
|
-
|
|
9
|
-
## Nuevo hook: hooks/block-approved-writes.ps1 (PreToolUse, INV-GOLDEN-01)
|
|
10
|
-
- Bloquea mecánicamente que el agente escriba/renombre cualquier *.approved.* (Write/Edit/
|
|
11
|
-
Bash-write → exit 2). Deja pasar lecturas. Probado.
|
|
12
|
-
- WIRING (pegar en settings.json — no lo puede hacer el agente por el guardrail de self-mod):
|
|
13
|
-
"hooks": { "PreToolUse": [ { "matcher": "*", "hooks": [
|
|
14
|
-
{ "type": "command",
|
|
15
|
-
"command": "powershell -NoProfile -ExecutionPolicy Bypass -File \"<KIT>/hooks/block-approved-writes.ps1\"" }
|
|
16
|
-
] } ] }
|
|
17
|
-
|
|
18
|
-
## Nuevo: templates/.gitattributes
|
|
19
|
-
- `*.approved.* binary` + `*.received.* binary` — line endings no generan diffs falsos
|
|
20
|
-
(crítico Windows/SQL Server). Copiar a la raíz del repo de migración.
|
|
21
|
-
|
|
22
|
-
## Estado del golden testing (del HANDOFF) — AHORA completo en el kit
|
|
23
|
-
- golden-diff (gate, byte-compare) ✓ · characterize (captura) ✓ · reverse-discovery (front
|
|
24
|
-
brownfield) ✓ · INV-GOLDEN-01 (CONSTITUTION) ✓ · hook PreToolUse ✓ · .gitattributes ✓
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
# dev-loop-kit 1.2.9 — documentación generalizada
|
|
2
|
-
- Removidas todas las referencias a proyecto/dominio específico del CONSTITUTION template
|
|
3
|
-
y de los skills characterize/reverse-discovery (ejemplos fiscales → genéricos; locale es-AR
|
|
4
|
-
→ "target locale"; money-path → "camino crítico"). El kit queda dominio-agnóstico.
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
# dev-loop-kit 1.20.0 — instalación global (2026-07-03)
|
|
2
|
-
|
|
3
|
-
Release chica de instalabilidad: el kit ahora puede instalarse UNA vez en
|
|
4
|
-
`~/.claude/` y quedar disponible para todos los proyectos, existentes y nuevos.
|
|
5
|
-
Sin cambios de engine. Smoke suite: 121/121.
|
|
6
|
-
|
|
7
|
-
## Qué cambia
|
|
8
|
-
|
|
9
|
-
- **Resolución portable del engine**: `dev-loop` y `sys-doc` resuelven
|
|
10
|
-
`qa_ledger.py` primero en el proyecto (`./.claude/skills/dev-loop/`) y caen a
|
|
11
|
-
la instalación global (`~/.claude/skills/dev-loop/`) si no hay local. La
|
|
12
|
-
instalación por proyecto sigue teniendo precedencia (un proyecto puede pinnear
|
|
13
|
-
su versión del kit copiándolo local).
|
|
14
|
-
- **Instalación global documentada completa** (README § Instalación, Opción B):
|
|
15
|
-
las SEIS skills (antes el snippet copiaba solo dev-loop y sys-doc — quedó de
|
|
16
|
-
cuando eran las únicas dos) + el hook `block-approved-writes.ps1` a
|
|
17
|
-
`~/.claude/hooks/` con registro en `~/.claude/settings.json`, para que
|
|
18
|
-
INV-GOLDEN-01 rija en todos los proyectos.
|
|
19
|
-
- **Qué sigue siendo por-proyecto** (estado, no instalable — ahora explícito):
|
|
20
|
-
`dev-loop.config.json` (los `path` son relativos a la raíz de la run, y la
|
|
21
|
-
quality bar declarada del humano vive ahí — 1.17.0), `QA-LEDGER.json`,
|
|
22
|
-
`ACCEPTANCE.md`, y el `.gitattributes` de templates para migración.
|
|
23
|
-
- Nota para la máquina donde se DESARROLLA el kit: junction/symlink por skill al
|
|
24
|
-
repo canónico en vez de copia — global siempre al día con main.
|
|
25
|
-
|
|
26
|
-
## Diferido consciente
|
|
27
|
-
|
|
28
|
-
- Un comando `install.sh`/`install.ps1` empaquetado: hoy son dos líneas de shell
|
|
29
|
-
documentadas; si el on-ramp real (dogfooding) muestra fricción, se mecaniza.
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
# dev-loop-kit 1.21.0 — namespace specloop-* (2026-07-03)
|
|
2
|
-
|
|
3
|
-
Release de naming, decidida por el humano entre tres opciones (prefijo largo /
|
|
4
|
-
prefijo corto / dejar como está): las seis skills pasan de nombres genéricos a
|
|
5
|
-
**namespace `specloop-*`**. Nombres como `discovery` o `characterize` eran
|
|
6
|
-
squatting del namespace global — cualquier otro kit podía pisarlos (evidencia:
|
|
7
|
-
el harness ya desambiguaba proyecto-vs-global con los genéricos). Se hace AHORA
|
|
8
|
-
porque es el momento más barato: antes de publicar, renombrar no rompe a nadie.
|
|
9
|
-
Sin cambios de engine. Smoke suite: 121/121.
|
|
10
|
-
|
|
11
|
-
## El mapa de renombres
|
|
12
|
-
|
|
13
|
-
| Antes | Ahora |
|
|
14
|
-
|---|---|
|
|
15
|
-
| `/discovery` | `/specloop-discovery` |
|
|
16
|
-
| `/adr-refine` | `/specloop-adr-refine` |
|
|
17
|
-
| `/reverse-discovery` | `/specloop-reverse-discovery` |
|
|
18
|
-
| `/characterize` | `/specloop-characterize` |
|
|
19
|
-
| `/dev-loop` | `/specloop-devloop` |
|
|
20
|
-
| `/sys-doc` | `/specloop-sysdoc` |
|
|
21
|
-
|
|
22
|
-
- **El path del engine cambia** (breaking para scripts que lo hardcodeaban):
|
|
23
|
-
`.claude/skills/dev-loop/qa_ledger.py` → `.claude/skills/specloop-devloop/qa_ledger.py`.
|
|
24
|
-
El fallback global (1.20.0) apunta ahora a `~/.claude/skills/specloop-devloop/`.
|
|
25
|
-
- **NO cambian**: `dev-loop-kit` (el nombre del kit), `dev-loop.config.json`
|
|
26
|
-
(el archivo de config), los subcomandos del engine, ni el schema del ledger.
|
|
27
|
-
- Instalación global: re-crear los junctions/copias con los nombres nuevos
|
|
28
|
-
(los viejos quedan rotos tras el rename de directorios).
|
|
29
|
-
- Sweep completo con truth-pass: SKILL.md (frontmatter + referencias cruzadas),
|
|
30
|
-
READMEs, templates/CLAUDE.md, decks ES/EN, playbooks ES/EN, onepagers,
|
|
31
|
-
pitches, skills-referencia, smoke. Los artefactos HISTÓRICOS (audits/*.json,
|
|
32
|
-
changelogs viejos, HANDOFFs de releases pasadas) NO se retro-editan —
|
|
33
|
-
documentan el estado de su época.
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
# dev-loop-kit 1.22.0 — doctor: diagnóstico de la instalación (2026-07-03)
|
|
2
|
-
|
|
3
|
-
`qa_ledger.py doctor` (subcomando 22) — espíritu flutter doctor: verifica que
|
|
4
|
-
spec-loop esté instalado y sano en la máquina de trabajo, Windows y Linux.
|
|
5
|
-
Smoke suite: 124/124.
|
|
6
|
-
|
|
7
|
-
## La idea
|
|
8
|
-
|
|
9
|
-
- **El engine verifica su PROPIA instalación**: las skills viven al lado de
|
|
10
|
-
`qa_ledger.py` (sea `~/.claude/skills/` global o `.claude/skills/` del
|
|
11
|
-
proyecto), así que doctor inspecciona a sus hermanos y reporta qué modo de
|
|
12
|
-
instalación detectó.
|
|
13
|
-
- **Output ASCII puro** (`[OK]` / `[ !]` / `[ X]`): es la herramienta de primer
|
|
14
|
-
contacto en máquinas vírgenes — no puede depender del encoding de la consola.
|
|
15
|
-
- **Exit 1 SOLO con errores**; los avisos no fallan (un toolchain ausente en la
|
|
16
|
-
máquina puede vivir en CI). `--json` para consumo programático.
|
|
17
|
-
|
|
18
|
-
## Qué chequea
|
|
19
|
-
|
|
20
|
-
| Check | Nivel si falla |
|
|
21
|
-
|---|---|
|
|
22
|
-
| Python ≥ 3.8 · git en PATH | error |
|
|
23
|
-
| Las 6 skills junto al engine, con frontmatter `name:` verificado | error |
|
|
24
|
-
| Hook INV-GOLDEN-01: archivo presente · registrado en `settings.json` (PreToolUse) · intérprete powershell/pwsh disponible | aviso (cada capa faltante, con el remedio) |
|
|
25
|
-
| `dev-loop.config.json` del cwd: parseable, versión, repos | error si inválido · aviso si ausente |
|
|
26
|
-
| ACCEPTANCE del config: criterios + AC-IDs trazables | aviso |
|
|
27
|
-
| Skills de QA de `qa_tools_order` (default code-review/judgment-day/improve) presentes en `.claude/skills` del proyecto o del usuario — el loop las orquesta sin traerlas | aviso (las built-in del harness no son detectables por filesystem, y lo dice) |
|
|
28
|
-
| Ledger: carga + checksum de integridad (1.13.0) | **error** si corrupto/mutado |
|
|
29
|
-
| Toolchain primario por repo type (`mvn`/`pytest`/`npm`/`go`/`cargo`/`dotnet`/`ctest`/`gradlew` del repo/`swift`/`flutter`) | aviso |
|
|
30
|
-
|
|
31
|
-
## El doctor no solo diagnostica: cura
|
|
32
|
-
|
|
33
|
-
Cada aviso/error lleva su **remedio accionable** — el comando o el link de
|
|
34
|
-
instalación (python.org, git-scm, maven/flutter/nodejs/go/rustup/dotnet/cmake/
|
|
35
|
-
gradle/swift, pwsh para el hook en Linux, y los pasos del propio kit para
|
|
36
|
-
skills/hook/config faltantes). Espíritu flutter doctor completo: corrés
|
|
37
|
-
`doctor`, instalás lo listado, re-corrés hasta verde.
|
|
38
|
-
|
|
39
|
-
## Hardening (review fresco pre-commit, aplicado)
|
|
40
|
-
|
|
41
|
-
- `startswith` sin separador final clasificaba `~/.claude/skills-evil/` como
|
|
42
|
-
instalación global → separador + `normcase` (case de drive en Windows).
|
|
43
|
-
- El header humano usaba em-dash y el JSON `ensure_ascii=False` — violaba la
|
|
44
|
-
promesa ASCII → header ASCII y `ensure_ascii=True` (el doctor promete bytes
|
|
45
|
-
ASCII SIEMPRE, es la herramienta de primer contacto).
|
|
46
|
-
- Detección de registro del hook por substring en la rama PreToolUse: límite
|
|
47
|
-
disclosed en el docstring (falso positivo rebuscado, dirección benigna).
|
|
48
|
-
|
|
49
|
-
## Notas de plataforma
|
|
50
|
-
|
|
51
|
-
- Linux: el hook es PowerShell — doctor avisa si no hay `pwsh` (instalarlo o
|
|
52
|
-
portar el twin bash, diferido consciente desde el header del .ps1).
|
|
53
|
-
- Windows: junctions de instalación global se atraviesan con normalidad
|
|
54
|
-
(doctor clasifica global vs por-proyecto por el path real del engine).
|
|
55
|
-
|
|
56
|
-
## Smoke
|
|
57
|
-
|
|
58
|
-
- **T42**: doctor en sandbox → exit 0 con config y ACCEPTANCE leídos, 6/6
|
|
59
|
-
skills, install clasificada por-proyecto · ledger corrupto → exit 1 (la
|
|
60
|
-
integridad del ledger es error, no aviso).
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
# dev-loop-kit 1.23.0 — rubric layer: el ACCEPTANCE de lo no-testeable (2026-07-03)
|
|
2
|
-
|
|
3
|
-
Origen: evaluación del concepto "rubrics" de Claude Code (Outcomes/graders) contra
|
|
4
|
-
el método. Veredicto: la ARQUITECTURA no aporta nada nuevo (maker≠checker con
|
|
5
|
-
contexto aislado ya existe); el edge real es **el artefacto** — criterio cualitativo
|
|
6
|
-
versionado. Entra con el acople corregido respecto de la propuesta original:
|
|
7
|
-
**advisory-first**, jamás dimensión ponderada del readiness (un grade LLM es guess
|
|
8
|
-
estructurado, no hecho medido — doctrina 1.10.0). Smoke suite: 139/139.
|
|
9
|
-
|
|
10
|
-
## Restricción de diseño: cero dependencia de un agente específico
|
|
11
|
-
|
|
12
|
-
Tres capas de acople decreciente — pedido explícito del humano:
|
|
13
|
-
|
|
14
|
-
1. **Núcleo (engine stdlib, cero LLM)**: `RUBRIC.md` + `spec-check --rubric` +
|
|
15
|
-
`rubric-ingest` + advisory en readiness + doctor. Un humano puede llenar el JSON
|
|
16
|
-
del grader a mano y todo funciona — **el smoke T43 lo prueba ejecutablemente**
|
|
17
|
-
(el grader.json del test se llena a mano, sin ningún LLM).
|
|
18
|
-
2. **Interfaz**: el contrato JSON
|
|
19
|
-
`{"criteria":[{"id","verdict":"pass|fail","evidence","note"}]}` — la ÚNICA
|
|
20
|
-
superficie entre el método y cualquier grader. IDs normalizados por número
|
|
21
|
-
(RB-01 == RB_1 == rb1, mismo criterio que AC-n).
|
|
22
|
-
3. **Graders pluggables**: `templates/rubric-grader-prompt.md` (markdown plano,
|
|
23
|
-
corre pegado en Codex, Gemini CLI, Cursor, un curl, o un humano) + la skill
|
|
24
|
-
`specloop-rubric` como adapter FINO de Claude Code (documentado como adapter).
|
|
25
|
-
|
|
26
|
-
## Qué hace
|
|
27
|
-
|
|
28
|
-
- **`RUBRIC.md`** (template en `templates/`): criterios `- [ ] RB-01 (peso 3) — …`
|
|
29
|
-
con anchor-pass/anchor-fail (calibran al grader, el engine no los parsea),
|
|
30
|
-
criterios negativos `RB-NEG-nn` (si aparecen, restan su peso) y `threshold: 0.NN`.
|
|
31
|
-
- **`spec-check --rubric`**: estructura = HECHO (archivo ausente, cero criterios
|
|
32
|
-
positivos, IDs duplicados normalizados, threshold ausente o fuera de (0,1] →
|
|
33
|
-
exit 1).
|
|
34
|
-
- **`rubric-ingest`** (subcomando 23): valida el contrato (IDs desconocidos =
|
|
35
|
-
error — el grader no inventa criterios), aplica **evidence-or-nothing** (un
|
|
36
|
-
veredicto que afecta el score sin cita `file:line` NO puntúa y se lista como no
|
|
37
|
-
sustentado), computa el score ponderado vs threshold y persiste un registro
|
|
38
|
-
`rubric:grade` en el ledger. **Advisory por default**: BELOW no gatea. Con
|
|
39
|
-
`--gate` o `defaults.rubric.gate: true` (procedencia: declaración humana), un
|
|
40
|
-
BELOW escribe registro gateado → bloquea convergencia y capea readiness ≤65 por
|
|
41
|
-
la maquinaria existente; un grade limpio posterior lo levanta (latest-wins).
|
|
42
|
-
- **readiness**: muestra el último grade por repo como línea advisory — NO es
|
|
43
|
-
dimensión con peso (measured beats narrated).
|
|
44
|
-
- **doctor**: si `defaults.rubric.file` está declarado, chequea existencia y
|
|
45
|
-
estructura (aviso con remedio).
|
|
46
|
-
- **`specloop-rubric`** (7ma skill): el adapter de Claude Code — contexto aislado
|
|
47
|
-
(solo diff + rúbrica, jamás el razonamiento del maker), sesgo a `fail` ante la
|
|
48
|
-
duda, y prohibido declararse el gate a sí misma.
|
|
49
|
-
|
|
50
|
-
## Hardening (review fresco pre-commit, 4 hallazgos aplicados)
|
|
51
|
-
|
|
52
|
-
- `threshold: 0.8.0` (malformado) crasheaba con ValueError cruda → se trata como
|
|
53
|
-
ausente y bloquea con mensaje.
|
|
54
|
-
- Entradas no-dict en `criteria` crasheaban → contrato roto, error explícito.
|
|
55
|
-
- **IDs duplicados en el reporte** (RB-01 y RB-1 del mismo criterio): el último
|
|
56
|
-
pisaba al primero en silencio — vector de gaming del grader → contrato roto,
|
|
57
|
-
un veredicto por criterio.
|
|
58
|
-
- El check de smoke "convergencia bloqueada por el gate" era VACUO (converged ya
|
|
59
|
-
salía 1 en ledger virgen por 'no agent steps') → el fixture ahora converge
|
|
60
|
-
ANTES, y se verifica además que un grade limpio LIBERA la convergencia
|
|
61
|
-
(latest-wins).
|
|
62
|
-
|
|
63
|
-
## La ventaja (por qué entra al método)
|
|
64
|
-
|
|
65
|
-
El criterio cualitativo (convenciones, ergonomía de API, sanidad del error
|
|
66
|
-
handling, calidad de docs) hoy vivía en la cabeza de cada pase de QA. Ahora es
|
|
67
|
-
**versionado, diffeable, auditable** (cada veredicto con evidencia al ledger) y
|
|
68
|
-
**portable** (viaja en el repo; cualquier humano/agente hereda el estándar).
|
|
69
|
-
Anchors + negativos bajan la varianza del grader.
|
|
70
|
-
|
|
71
|
-
## Límite honesto
|
|
72
|
-
|
|
73
|
-
Nicho más chico que en la era en que se evaluó la idea: el acceptance trazable
|
|
74
|
-
(1.10.0) ya cierra lo testeable — esta capa cubre SOLO lo genuinamente cualitativo,
|
|
75
|
-
y siempre como guess estructurado: nunca reemplaza un gate duro.
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
# dev-loop-kit 1.24.0 — plugin de Claude Code (2026-07-03)
|
|
2
|
-
|
|
3
|
-
El kit ahora se distribuye como **plugin instalable** para Claude Code — el repo es
|
|
4
|
-
su propio marketplace. Los schemas se verificaron contra los docs oficiales
|
|
5
|
-
(code.claude.com/docs: plugins, plugins-reference, plugin-marketplaces,
|
|
6
|
-
discover-plugins) ANTES de escribir una línea — formato de tool real jamás se
|
|
7
|
-
inventa. Smoke suite: 140/140.
|
|
8
|
-
|
|
9
|
-
## Instalación (Opción C, la recomendada para Claude Code)
|
|
10
|
-
|
|
11
|
-
```
|
|
12
|
-
/plugin marketplace add andresmassello/SPEC-LOOP
|
|
13
|
-
/plugin install specloop@specloop
|
|
14
|
-
```
|
|
15
|
-
|
|
16
|
-
- Las 7 skills quedan como `specloop:specloop-*` (el namespace del plugin se suma
|
|
17
|
-
al prefijo propio — mismo patrón que sonarqube:sonar-*).
|
|
18
|
-
- **El hook INV-GOLDEN-01 se auto-registra** (`hooks/hooks.json` con
|
|
19
|
-
`${CLAUDE_PLUGIN_ROOT}`): desaparece la edición manual de settings.json que la
|
|
20
|
-
instalación global requería. Linux: el hook sigue siendo PowerShell — pwsh +
|
|
21
|
-
ajuste del comando (el doctor lo señala con remedio).
|
|
22
|
-
- Updates versionados: el plugin declara `version`, así que `/plugin update`
|
|
23
|
-
solo actualiza con bump de release.
|
|
24
|
-
- **Cero reestructuración**: `plugin.json` soporta path custom de skills
|
|
25
|
-
(`"skills": "./.claude/skills/"`) — el layout canónico del kit no cambió, y
|
|
26
|
-
las Opciones A (por proyecto) y B (global copy/junctions) siguen intactas
|
|
27
|
-
para Codex/Gemini/Cursor. El plugin es EMPAQUETADO, no dependencia: el
|
|
28
|
-
agnosticismo no se negocia.
|
|
29
|
-
|
|
30
|
-
## Qué se agregó
|
|
31
|
-
|
|
32
|
-
- `dev-loop-kit/.claude-plugin/plugin.json` — manifest (name `specloop`,
|
|
33
|
-
skills path custom, hooks auto-registrados, MIT).
|
|
34
|
-
- `dev-loop-kit/hooks/hooks.json` — registro PreToolUse del hook del golden
|
|
35
|
-
vía `${CLAUDE_PLUGIN_ROOT}`.
|
|
36
|
-
- `.claude-plugin/marketplace.json` (root del repo) — el marketplace `specloop`
|
|
37
|
-
con source relativo `./dev-loop-kit`.
|
|
38
|
-
- **doctor**: tercer modo de instalación detectado (`plugin`, path bajo
|
|
39
|
-
`~/.claude/plugins/`); en modo plugin el hook cuenta como registrado si
|
|
40
|
-
`hooks/hooks.json` existe (auto-registro — settings.json ya no participa).
|
|
41
|
-
JSON expone `plugin_install`.
|
|
42
|
-
- **Smoke T44 — el sync de versión ahora es un HECHO**: VERSION =
|
|
43
|
-
config.version = plugin.json.version = marketplace.version, o la suite falla.
|
|
44
|
-
La regla 6 del repo pasa de triple a **quíntuple** (con CHANGELOG).
|
|
45
|
-
|
|
46
|
-
## Nota para la máquina del autor
|
|
47
|
-
|
|
48
|
-
Los junctions de la Opción B y el plugin no deben convivir (skills duplicadas):
|
|
49
|
-
la máquina donde se desarrolla el kit se queda con junctions (siempre al día con
|
|
50
|
-
main); el plugin es el canal para las demás máquinas y terceros.
|