@imolko/ultra-agent 0.1.1 → 0.1.2-beta
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/dist-node/payload.d.ts +3 -2
- package/dist-node/payload.d.ts.map +1 -1
- package/dist-node/payload.js +3 -2
- package/dist-node/payload.js.map +1 -1
- package/docs/adr/ADR-0000-proceso-y-formato-de-adrs.md +15 -7
- package/docs/adr/foundational/A-034-canonical-skill-set.md +1 -1
- package/docs/adr/foundational/A-043-vocabulario-etiquetas-adrs.md +1 -1
- package/docs/adr/foundational/A-052-distribucion-metodologia-paquete-versionado.md +1 -1
- package/docs/adr/foundational/A-053-errores-compartidos-entre-features-dos-hogares-por-capa.md +1 -1
- package/docs/adr/foundational/A-054-contrato-costura-driver-port-raw-data-canal-error.md +1 -1
- package/docs/adr/index.md +1 -1
- package/docs/adr/typescript/T-002-test-documentation-jsdoc.md +1 -1
- package/package.json +1 -1
- package/scripts/verify-adr-consistency.py +42 -9
package/dist-node/payload.d.ts
CHANGED
|
@@ -10,8 +10,9 @@
|
|
|
10
10
|
export declare const GATE_RELATIVE_PATH = "scripts/verify-adr-consistency.py";
|
|
11
11
|
/**
|
|
12
12
|
* ¿Es un archivo del registro ADR canónico (tier A/T/P o ADR-0000 o índice raíz)?
|
|
13
|
-
*
|
|
14
|
-
*
|
|
13
|
+
* Cualquier otro `.md` en la raíz de `docs/adr/` es tier de proyecto y queda
|
|
14
|
+
* excluido: los ADRs nuevos usan el prefijo canónico `PJ-` (ADR-0000) y los ya
|
|
15
|
+
* aceptados conservan el prefijo con el que fueron aceptados (no se renumeran).
|
|
15
16
|
*/
|
|
16
17
|
export declare function isCanonicalAdr(relativePath: string): boolean;
|
|
17
18
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"payload.d.ts","sourceRoot":"","sources":["../src/payload.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,oFAAoF;AACpF,eAAO,MAAM,kBAAkB,sCAAsC,CAAC;AAQtE
|
|
1
|
+
{"version":3,"file":"payload.d.ts","sourceRoot":"","sources":["../src/payload.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,oFAAoF;AACpF,eAAO,MAAM,kBAAkB,sCAAsC,CAAC;AAQtE;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAY5D;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAM5D"}
|
package/dist-node/payload.js
CHANGED
|
@@ -19,8 +19,9 @@ function normalize(path) {
|
|
|
19
19
|
}
|
|
20
20
|
/**
|
|
21
21
|
* ¿Es un archivo del registro ADR canónico (tier A/T/P o ADR-0000 o índice raíz)?
|
|
22
|
-
*
|
|
23
|
-
*
|
|
22
|
+
* Cualquier otro `.md` en la raíz de `docs/adr/` es tier de proyecto y queda
|
|
23
|
+
* excluido: los ADRs nuevos usan el prefijo canónico `PJ-` (ADR-0000) y los ya
|
|
24
|
+
* aceptados conservan el prefijo con el que fueron aceptados (no se renumeran).
|
|
24
25
|
*/
|
|
25
26
|
function isCanonicalAdr(relativePath) {
|
|
26
27
|
const path = normalize(relativePath);
|
package/dist-node/payload.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"payload.js","sourceRoot":"","sources":["../src/payload.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;;
|
|
1
|
+
{"version":3,"file":"payload.js","sourceRoot":"","sources":["../src/payload.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;;AAiBH,wCAYC;AAMD,gDAMC;AAvCD,oFAAoF;AACvE,QAAA,kBAAkB,GAAG,mCAAmC,CAAC;AAEtE,MAAM,SAAS,GAAG,CAAC,cAAc,EAAE,YAAY,EAAE,QAAQ,CAAC,CAAC;AAE3D,SAAS,SAAS,CAAC,IAAY;IAC7B,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;AAClC,CAAC;AAED;;;;;GAKG;AACH,SAAgB,cAAc,CAAC,YAAoB;IACjD,MAAM,IAAI,GAAG,SAAS,CAAC,YAAY,CAAC,CAAC;IAErC,KAAK,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;QAC5B,IAAI,IAAI,CAAC,UAAU,CAAC,YAAY,GAAG,GAAG,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAChE,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,IAAI,gCAAgC,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAC7D,IAAI,IAAI,KAAK,mBAAmB;QAAE,OAAO,IAAI,CAAC;IAC9C,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;GAGG;AACH,SAAgB,kBAAkB,CAAC,KAAe;IAChD,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE;QACrC,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;QAC7B,OAAO,cAAc,CAAC,IAAI,CAAC,IAAI,IAAI,KAAK,0BAAkB,CAAC;IAC7D,CAAC,CAAC,CAAC;IACH,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC;AACzB,CAAC"}
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
## Contexto
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
La metodología ultra mantiene un registro de decisiones de arquitectura (ADR) distribuido en varios tiers y decenas de archivos. Hasta ahora la información sobre *cómo* se escriben y gobiernan esos ADRs vivía dispersa en las secciones "Formato" y "Tiers" de `docs/adr/index.md`, sin respaldo de decisión: no estaba escrito por qué se usa el formato de Michael Nygard, por qué la metodología se organiza en tres tiers más un tier de proyecto, ni qué reglas se aplican para mantener la consistencia.
|
|
14
14
|
|
|
15
15
|
Sin un ADR que canonice el proceso, cada decisión nueva corre el riesgo de:
|
|
16
16
|
|
|
@@ -19,7 +19,7 @@ Sin un ADR que canonice el proceso, cada decisión nueva corre el riesgo de:
|
|
|
19
19
|
- omitir campos obligatorios como `originally` o las etiquetas;
|
|
20
20
|
- introducir enlaces rotos o listas duplicadas que el gate detecta.
|
|
21
21
|
|
|
22
|
-
Este documento es el **meta-ADR**: define el proceso y el formato que el resto de ADRs debe seguir. Vive en la raíz de `docs/adr/` y usa el ID `0000` precisamente porque está **fuera** de la jerarquía A→T/P→
|
|
22
|
+
Este documento es el **meta-ADR**: define el proceso y el formato que el resto de ADRs debe seguir. Vive en la raíz de `docs/adr/` y usa el ID `0000` precisamente porque está **fuera** de la jerarquía A→T/P→tier de proyecto: define esa jerarquía y, por lo tanto, no pertenece a ninguno de sus tiers. Por su nombre no es detectado por el gate de consistencia, lo cual es correcto.
|
|
23
23
|
|
|
24
24
|
## Decisión
|
|
25
25
|
|
|
@@ -43,7 +43,7 @@ Además del título H1 (`# <ID>: <Título descriptivo>`), cada ADR lleva un **fr
|
|
|
43
43
|
| `**Enriquecido desde**` | No | Fuente de enriquecimiento posterior (cuando aplica). |
|
|
44
44
|
| `**tags**` | Sí (tier A hoy) | De una a tres etiquetas del vocabulario en [A-043](./foundational/A-043-vocabulario-etiquetas-adrs.md). |
|
|
45
45
|
|
|
46
|
-
El gate valida el formato H1 y la ortografía exacta de `originally` (minúsculas) y `Enriquecido desde` (capitalización exacta) para los ADRs de los tiers A/T/P/
|
|
46
|
+
El gate valida el formato H1 y la ortografía exacta de `originally` (minúsculas) y `Enriquecido desde` (capitalización exacta) para los ADRs de los tiers A/T/P. El tier de proyecto del consumidor queda fuera del gate distribuido ([A-052](./foundational/A-052-distribucion-metodologia-paquete-versionado.md)).
|
|
47
47
|
|
|
48
48
|
### Jerarquía de tiers: A → T/P → tier de proyecto
|
|
49
49
|
|
|
@@ -54,7 +54,7 @@ Los ADRs se organizan en tres tiers de metodología más el tier de proyecto de
|
|
|
54
54
|
| **Fundacional (A)** | [`foundational/`](./foundational/index.md) | Decisiones metodológicas agnósticas al lenguaje (Clean Architecture, TDD, comandos y consultas, DDD). Aplican a todos los proyectos de Imolko. |
|
|
55
55
|
| **TypeScript (T)** | [`typescript/`](./typescript/index.md) | Decisiones específicas del ecosistema TypeScript/Zod/Node.js. |
|
|
56
56
|
| **Python (P)** | [`python/`](./python/index.md) | Decisiones específicas del ecosistema Python (FastAPI, SQLAlchemy, Pydantic). |
|
|
57
|
-
| **Tier de proyecto** | `docs/adr/` (raíz) u otro directorio del consumidor | Decisiones específicas del dominio del
|
|
57
|
+
| **Tier de proyecto** | `docs/adr/` (raíz) u otro directorio del consumidor | Decisiones específicas del dominio del consumidor. El prefijo canónico es `PJ` (`PJ-NNN`) para todo ADR nuevo, independientemente del nombre del proyecto; los IDs ya aceptados conservan el prefijo con el que fueron aceptados. No forma parte de la metodología distribuida ([A-052](./foundational/A-052-distribucion-metodologia-paquete-versionado.md)). |
|
|
58
58
|
|
|
59
59
|
**Reglas de referencia** (jerarquía estricta):
|
|
60
60
|
|
|
@@ -64,6 +64,14 @@ Los ADRs se organizan en tres tiers de metodología más el tier de proyecto de
|
|
|
64
64
|
|
|
65
65
|
La numeración es **estable**: los IDs existentes no se renumeran. Los IDs omitidos intencionalmente (por ejemplo A-021) no se reutilizan.
|
|
66
66
|
|
|
67
|
+
### Enmienda (2026-10-20): prefijo canónico del tier de proyecto
|
|
68
|
+
|
|
69
|
+
Esta enmienda sustituye la regla anterior, que dejaba el prefijo del tier de proyecto a elección de cada proyecto, y precisa el alcance del gate sin cambiar el formato ni la jerarquía:
|
|
70
|
+
|
|
71
|
+
- **Prefijo canónico `PJ-NNN`.** Todo ADR nuevo del tier de proyecto del consumidor usa el prefijo `PJ` (`PJ-001`, `PJ-002`, …), independientemente del nombre del proyecto. El nombre de un consumidor concreto no forma parte del formato canónico.
|
|
72
|
+
- **IDs existentes sin renumerar.** Los ADRs del tier de proyecto ya aceptados por un consumidor conservan el prefijo y el número con los que fueron aceptados; la numeración estable de arriba los ampara. No se migran ni se renumeran.
|
|
73
|
+
- **El gate valida solo A, T y P.** La regla `jerarquia` y el resto de reglas del gate se aplican a los tiers de metodología. El tier de proyecto pertenece al consumidor y no se distribuye ([A-052](./foundational/A-052-distribucion-metodologia-paquete-versionado.md)), así que queda fuera del gate distribuido.
|
|
74
|
+
|
|
67
75
|
### Fases narrativas del tier fundacional
|
|
68
76
|
|
|
69
77
|
Los ADRs fundacionales (A-XXX) se agrupan en fases narrativas; el orden y el agrupamiento exactos viven en [`foundational/index.md`](./foundational/index.md), que es quien porta la narrativa. Las fases son una organización de lectura; no cambian la numeración ni los tiers.
|
|
@@ -80,7 +88,7 @@ El gate valida **cinco reglas** y debe salir con código `0` y cero violaciones:
|
|
|
80
88
|
|
|
81
89
|
| Regla | Qué valida |
|
|
82
90
|
|-------|------------|
|
|
83
|
-
| `jerarquia` | Los ADRs no referencian tiers prohibidos según la jerarquía A→T/P→tier de proyecto. |
|
|
91
|
+
| `jerarquia` | Los ADRs A/T/P no referencian tiers prohibidos según la jerarquía A→T/P→tier de proyecto, ni por enlace markdown ni por cita en texto plano a un ID con prefijo no permitido para el tier (A solo cita A; T cita A y T; P cita A y P). Cualquier otro prefijo —por ejemplo `G-NNN` o `PJ-NNN`— también es una violación, porque ningún ADR A/T/P referencia el tier de proyecto. |
|
|
84
92
|
| `enlaces` | Todos los enlaces markdown internos (relativos, `*.md`) resuelven a un archivo existente. |
|
|
85
93
|
| `frontmatter` | El título sigue `# <TIER>-<NNN>: Título` y los campos `originally` / `Enriquecido desde` usan la ortografía correcta. |
|
|
86
94
|
| `indices` | Cada ADR aparece en el índice de su tier y el índice no lista ADRs inexistentes. |
|
|
@@ -98,7 +106,7 @@ Cada ADR transita por un ciclo de vida simple:
|
|
|
98
106
|
|
|
99
107
|
Reglas de numeración:
|
|
100
108
|
|
|
101
|
-
- El siguiente ADR de un tier toma el siguiente número correlativo (`A-NNN`, `T-NNN`, `P-NNN`,
|
|
109
|
+
- El siguiente ADR de un tier toma el siguiente número correlativo (`A-NNN`, `T-NNN`, `P-NNN`, `PJ-NNN`).
|
|
102
110
|
- Los IDs omitidos intencionalmente (por ejemplo A-021) **no se reutilizan**: permanecen omitidos para preservar la estabilidad de los IDs existentes.
|
|
103
111
|
|
|
104
112
|
## Consecuencias
|
|
@@ -108,7 +116,7 @@ Reglas de numeración:
|
|
|
108
116
|
- **Proceso canonizado**: el formato, la jerarquía y el gate dejan de vivir dispersos y pasan a tener respaldo de decisión.
|
|
109
117
|
- **Onboarding más corto**: un colaborador nuevo lee un único ADR para entender cómo contribuir decisiones.
|
|
110
118
|
- **Consistencia ejecutable**: el gate automatiza la verificación de las cinco reglas, con salida 0 como criterio de aceptación.
|
|
111
|
-
- **Jerarquía clara**: las reglas de referencia entre tiers evitan acoplamientos incorrectos (por ejemplo, un ADR fundacional citando uno de
|
|
119
|
+
- **Jerarquía clara**: las reglas de referencia entre tiers evitan acoplamientos incorrectos (por ejemplo, un ADR fundacional citando uno del tier de proyecto).
|
|
112
120
|
|
|
113
121
|
### Negativas
|
|
114
122
|
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
**originally**: mattpocock-skills
|
|
8
8
|
|
|
9
|
-
**Enriquecido desde**: mattpocock/skills — taxonomía canónica de skills (engineering + productivity), adaptada al registro ADR de
|
|
9
|
+
**Enriquecido desde**: mattpocock/skills — taxonomía canónica de skills (engineering + productivity), adaptada al registro ADR de la metodología ultra
|
|
10
10
|
|
|
11
11
|
**tags**: agentes, tooling
|
|
12
12
|
|
|
@@ -27,7 +27,7 @@ El vocabulario aprobado de etiquetas vive aquí, en el tier fundacional, como fu
|
|
|
27
27
|
| `agentes` | Colaboradores LLM, bloques de prompt. |
|
|
28
28
|
| `tooling` | Herramientas del flujo de trabajo (gate, scripts, generadores). |
|
|
29
29
|
|
|
30
|
-
El campo `**tags**` en sí — su obligatoriedad y su forma — lo define [ADR-0000](../ADR-0000-proceso-y-formato-de-adrs.md); este ADR posee los valores y su semántica. Los tiers T, P y
|
|
30
|
+
El campo `**tags**` en sí — su obligatoriedad y su forma — lo define [ADR-0000](../ADR-0000-proceso-y-formato-de-adrs.md); este ADR posee los valores y su semántica. Los tiers T, P y el tier de proyecto (PJ-) pueden referenciar este ADR cuando adopten etiquetas.
|
|
31
31
|
|
|
32
32
|
## Consecuencias
|
|
33
33
|
|
|
@@ -19,7 +19,7 @@ El formato de los skills ya es el estándar Agent Skills, agnóstico al harness,
|
|
|
19
19
|
Distribuir la metodología como un **paquete npm versionado por suscripción**: `@imolko/ultra-agent`. El consumidor instala una versión, la actualiza subiendo de versión y nunca edita el contenido canónico.
|
|
20
20
|
|
|
21
21
|
1. **Modelo de suscripción.** El conjunto canónico es de solo lectura en el repositorio consumidor. El consumidor añade sus propios artefactos —skills de proyecto y ADRs de su tier de proyecto— en ubicaciones que el instalador nunca toca. La regla es **«extender, no editar»**: si el consumidor disiente de una decisión canónica, escribe su propio skill o ADR en su espacio, no modifica el canónico.
|
|
22
|
-
2. **Límite de contenido.** Se distribuye solo la metodología: los tiers A, T y P, el meta-ADR `ADR-0000`, el gate de consistencia, los skills canónicos, las extensiones de pi y el **preset de lint** que materializa las reglas ejecutables del tier A — los guardrails aplicables ([A-045](./A-045-guardrails-aplicables-no-directrices.md)) y las reglas estructurales de costura y errores ([A-053](./A-053-errores-compartidos-entre-features-dos-hogares-por-capa.md), [A-054](./A-054-contrato-costura-driver-port-raw-data-canal-error.md)) —. Los ADRs del tier de proyecto de
|
|
22
|
+
2. **Límite de contenido.** Se distribuye solo la metodología: los tiers A, T y P, el meta-ADR `ADR-0000`, el gate de consistencia, los skills canónicos, las extensiones de pi y el **preset de lint** que materializa las reglas ejecutables del tier A — los guardrails aplicables ([A-045](./A-045-guardrails-aplicables-no-directrices.md)) y las reglas estructurales de costura y errores ([A-053](./A-053-errores-compartidos-entre-features-dos-hogares-por-capa.md), [A-054](./A-054-contrato-costura-driver-port-raw-data-canal-error.md)) —. Los ADRs del tier de proyecto de cada consumidor (prefijo `PJ-`) no forman parte del paquete.
|
|
23
23
|
3. **Espejo de ADRs.** El instalador copia los tiers A, T y P en el `adr_dir` del consumidor como archivos de solo lectura. La actualización reconcilia el espejo y nunca toca el tier de proyecto ni los READMEs de dominio del consumidor.
|
|
24
24
|
4. **Mecanismo.** Un CLI —`npx @imolko/ultra-agent install | update | status`— materializa el conjunto en las ubicaciones de descubrimiento de cada harness y registra un manifiesto de versión para poder reconciliar después.
|
|
25
25
|
5. **Deriva.** Si el consumidor edita un archivo espejado, `update` falla en voz alta ([A-007](./A-007-data-contract-fail-fast.md)) y solo se resuelve con `--reset`, que respalda antes de sobrescribir. No existe `--keep`: conservar una edición del espejo viola el modelo de solo lectura.
|
package/docs/adr/foundational/A-053-errores-compartidos-entre-features-dos-hogares-por-capa.md
CHANGED
|
@@ -15,7 +15,7 @@ Los casos de uso de `features/` producen errores que tienden a duplicarse featur
|
|
|
15
15
|
- **Referencias de dominio**: la ausencia de un agregado en una consulta ("no existe"). [A-025](./A-025-anatomia-mecanica-feature-puertos-adaptadores-drivers.md) ya las clasifica como error de dominio: el puerto de dominio nunca retorna `null`; la ausencia la traduce el adaptador y, en una consulta, se convierte en error de dominio.
|
|
16
16
|
- **Fallos de infraestructura**: producidos en la costura del driver ([A-025](./A-025-anatomia-mecanica-feature-puertos-adaptadores-drivers.md), [A-026](./A-026-infraestructura-compartida.md)) — caída de la base de datos, fallo del generador de identificadores, fallo de publicación de eventos —, ajenos al dominio.
|
|
17
17
|
|
|
18
|
-
[A-025](./A-025-anatomia-mecanica-feature-puertos-adaptadores-drivers.md) clasifica cada especie pero no fija su **hogar**. Sin un hogar canónico, el mismo error vive duplicado por feature y su identidad estable se dispersa según el nombre de la feature. La regla se formalizó primero en el tier de proyecto de
|
|
18
|
+
[A-025](./A-025-anatomia-mecanica-feature-puertos-adaptadores-drivers.md) clasifica cada especie pero no fija su **hogar**. Sin un hogar canónico, el mismo error vive duplicado por feature y su identidad estable se dispersa según el nombre de la feature. La regla se formalizó primero en el tier de proyecto de un consumidor; al ser independiente del dominio, se eleva aquí al tier fundacional.
|
|
19
19
|
|
|
20
20
|
## Decisión
|
|
21
21
|
|
|
@@ -16,7 +16,7 @@ El driver port es la costura raw-data entre el adaptador y el driver tecnológic
|
|
|
16
16
|
2. **Hasta dónde llega la regla de raw data**. [A-025](./A-025-anatomia-mecanica-feature-puertos-adaptadores-drivers.md) la enuncia en general pero la costura de escritura no event-shaped quedaba sin regla escrita: los driver ports podían recibir agregados o value objects del dominio en `save(...)`, haciendo cruzar el objeto con comportamiento por la costura.
|
|
17
17
|
3. **La frontera de «raw»**. «Ningún tipo del dominio cruza la costura» se leía como una regla de dirección de imports ([A-001](./A-001-clean-architecture-4-capas.md)), cuando la frontera real es **raw vs. comportamiento**: las formas serializables sin comportamiento (mementos/snapshots, la envolvente estándar de eventos, DTOs planos) sí cruzan —se declaren donde se declaren—; los objetos con comportamiento (agregados, entidades, value objects) y el hecho de dominio sin confirmar (que porta una referencia de clase, no data) no cruzan.
|
|
18
18
|
|
|
19
|
-
El hogar del error de infraestructura ya existe: [A-053](./A-053-errores-compartidos-entre-features-dos-hogares-por-capa.md) decide que los fallos de infraestructura viven en el catálogo compartido de la capa de aplicación y **los produce el adaptador** al traducir el fallo del driver. Faltaba la mitad de la costura: el canal por el que el driver entrega ese fallo. La regla se formalizó primero en el tier de proyecto de
|
|
19
|
+
El hogar del error de infraestructura ya existe: [A-053](./A-053-errores-compartidos-entre-features-dos-hogares-por-capa.md) decide que los fallos de infraestructura viven en el catálogo compartido de la capa de aplicación y **los produce el adaptador** al traducir el fallo del driver. Faltaba la mitad de la costura: el canal por el que el driver entrega ese fallo. La regla se formalizó primero en el tier de proyecto de un consumidor; al ser independiente del dominio, se eleva aquí al tier fundacional.
|
|
20
20
|
|
|
21
21
|
## Decisión
|
|
22
22
|
|
package/docs/adr/index.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Architecture Decision Records (ADR)
|
|
2
2
|
|
|
3
|
-
Registro de decisiones de arquitectura canónico del equipo Imolko. Cubre la metodología ultra en tres tiers — fundacional (agnóstico al lenguaje), TypeScript y Python —. Cada
|
|
3
|
+
Registro de decisiones de arquitectura canónico del equipo Imolko. Cubre la metodología ultra en tres tiers — fundacional (agnóstico al lenguaje), TypeScript y Python —. Cada repositorio consumidor añade su propio tier de proyecto con sus decisiones de dominio, con el prefijo canónico `PJ-` ([ADR-0000](./ADR-0000-proceso-y-formato-de-adrs.md)), y ese tier no forma parte de la metodología distribuida ([A-052](./foundational/A-052-distribucion-metodologia-paquete-versionado.md)).
|
|
4
4
|
|
|
5
5
|
El proceso, el formato y las reglas que gobiernan estos ADRs están documentados en [ADR-0000: Proceso y formato de los ADRs](./ADR-0000-proceso-y-formato-de-adrs.md).
|
|
6
6
|
|
|
@@ -35,7 +35,7 @@ it('crear ProductId vacío', () => {
|
|
|
35
35
|
| `@name` coincide con `it()` | El texto de `@name` debe ser **idéntico** al primer argumento de `it()`. Esto asegura que el título en la documentación generada coincida con el nombre del test en el runner. |
|
|
36
36
|
| `@scenario` describe el qué y por qué | Explica qué entrada se usa, qué regla se ejerce, y qué resultado se espera. Debe ser comprensible para un experto del dominio sin conocimientos técnicos. |
|
|
37
37
|
| Sin "falla si…" en títulos | El título del test (`it()` y `@name`) describe **el escenario**, no el resultado. Ej: `'crear ProductId vacío'` en lugar de `'crear ProductId vacío – falla si está vacío'`. El resultado lo expresa `@scenario`. |
|
|
38
|
-
| Idioma del repo | Los nombres y descripciones van en el idioma
|
|
38
|
+
| Idioma del repo | Los nombres y descripciones van en el idioma configurado por el repositorio (`issue_language`), fijado por [A-003](../foundational/A-003-tdd.md): por ejemplo, español. |
|
|
39
39
|
| Primera línea: descripción larga | La primera línea del JSDoc (antes de `@name`) contiene una descripción extendida del comportamiento verificado. |
|
|
40
40
|
|
|
41
41
|
> **Ámbito**: la convención aplica a tests que documentan reglas de dominio o comportamiento de casos de uso. Los tests de contrato (validación de esquemas y tipos, por ejemplo `*.contract.spec.ts`) quedan fuera: validan estructura, no reglas de dominio, y no se convierten en casos documentados para expertos del dominio.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@imolko/ultra-agent",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2-beta",
|
|
4
4
|
"description": "Metodología ultra como paquete versionado: skills canónicos, registro ADR A/T/P, extensiones de pi y CLI (install/update/status/ship).",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": {
|
|
@@ -2,8 +2,12 @@
|
|
|
2
2
|
"""Gate de consistencia del registro ADR (ADR-0000).
|
|
3
3
|
|
|
4
4
|
Valida cinco reglas y sale con código 0 solo si no hay violaciones:
|
|
5
|
-
- jerarquia los ADRs no referencian tiers prohibidos (A
|
|
6
|
-
|
|
5
|
+
- jerarquia los ADRs no referencian tiers prohibidos (A solo cita A; T cita A y T;
|
|
6
|
+
P cita A y P). Detecta tanto enlaces markdown como citas en texto plano a
|
|
7
|
+
IDs `<PREFIJO>-NNN`: una cita con un prefijo no permitido para el tier —o
|
|
8
|
+
con cualquier otro prefijo, incluidos G y PJ— es una violación, porque
|
|
9
|
+
ningún ADR A/T/P referencia el tier de proyecto. Una misma referencia
|
|
10
|
+
prohibida se reporta una sola vez aunque aparezca como enlace y como ID.
|
|
7
11
|
- enlaces todos los enlaces markdown internos (relativos, *.md) resuelven a un
|
|
8
12
|
archivo existente.
|
|
9
13
|
- frontmatter el título H1 sigue `# <TIER>-<NNN>: Título` y los campos `originally` /
|
|
@@ -102,23 +106,52 @@ ALLOWED_TARGETS = {
|
|
|
102
106
|
"P": {"A", "P", "meta"},
|
|
103
107
|
}
|
|
104
108
|
|
|
109
|
+
# Citas en texto plano a un ID de ADR. Una a dos letras mayúsculas evita falsos
|
|
110
|
+
# positivos con identificadores de tres letras (ISO-8601, RFC-2119, SHA-256).
|
|
111
|
+
PLAIN_ID_RE = re.compile(r"\b([A-Z]{1,2})-\d{3}\b")
|
|
112
|
+
|
|
113
|
+
# Destino de un enlace markdown inline `](destino)`. Se elimina antes del escaneo
|
|
114
|
+
# de texto plano para que una referencia no se reporte también como cita.
|
|
115
|
+
LINK_TARGET_RE = re.compile(r"\]\([^)]*\)")
|
|
116
|
+
|
|
117
|
+
# Enlace markdown inline completo: etiqueta y destino. La etiqueta puede citar el
|
|
118
|
+
# ID cuando el destino no lo contiene (p. ej. `[T-001](../typescript/index.md)`).
|
|
119
|
+
LINK_RE = re.compile(r"\[([^\]]*)\]\(([^)]*)\)")
|
|
120
|
+
|
|
105
121
|
|
|
106
122
|
def rule_jerarquia() -> None:
|
|
107
123
|
for tier, allowed in ALLOWED_TARGETS.items():
|
|
124
|
+
allowed_prefixes = {t for t in allowed if t in TIER_DIRS}
|
|
108
125
|
for adr in tier_adr_files(tier):
|
|
109
126
|
text = adr.read_text(encoding="utf-8")
|
|
110
|
-
|
|
127
|
+
reported_ids = set()
|
|
128
|
+
|
|
129
|
+
for label, target in LINK_RE.findall(text):
|
|
111
130
|
resolved = resolve_link(adr, target)
|
|
112
131
|
if resolved is None:
|
|
113
132
|
continue
|
|
114
133
|
resolved_tier = target_tier(resolved)
|
|
115
|
-
if resolved_tier is None:
|
|
134
|
+
if resolved_tier is None or resolved_tier in allowed:
|
|
116
135
|
continue
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
136
|
+
# Los IDs citados por el enlace —en la etiqueta o en el destino—
|
|
137
|
+
# quedan cubiertos por esta violación y no se reportan otra vez.
|
|
138
|
+
for match in PLAIN_ID_RE.finditer(f"{label} {target}"):
|
|
139
|
+
reported_ids.add(match.group(0))
|
|
140
|
+
report(
|
|
141
|
+
"jerarquia",
|
|
142
|
+
f"{adr.relative_to(ROOT)} referencia al tier {resolved_tier} ({target}), prohibido para el tier {tier}",
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
plain_text = LINK_TARGET_RE.sub("", text)
|
|
146
|
+
for match in PLAIN_ID_RE.finditer(plain_text):
|
|
147
|
+
prefix, ident = match.group(1), match.group(0)
|
|
148
|
+
if prefix in allowed_prefixes or ident in reported_ids:
|
|
149
|
+
continue
|
|
150
|
+
reported_ids.add(ident)
|
|
151
|
+
report(
|
|
152
|
+
"jerarquia",
|
|
153
|
+
f"{adr.relative_to(ROOT)} cita en texto plano {ident} (prefijo {prefix}), prohibido para el tier {tier}",
|
|
154
|
+
)
|
|
122
155
|
|
|
123
156
|
|
|
124
157
|
def rule_enlaces() -> None:
|