@imolko/ultra-agent 0.1.0-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.
Files changed (239) hide show
  1. package/README.md +93 -0
  2. package/bin/cli.js +2 -0
  3. package/dist-node/bin.d.ts +2 -0
  4. package/dist-node/bin.d.ts.map +1 -0
  5. package/dist-node/bin.js +5 -0
  6. package/dist-node/bin.js.map +1 -0
  7. package/dist-node/cli.d.ts +41 -0
  8. package/dist-node/cli.d.ts.map +1 -0
  9. package/dist-node/cli.js +170 -0
  10. package/dist-node/cli.js.map +1 -0
  11. package/dist-node/index.d.ts +14 -0
  12. package/dist-node/index.d.ts.map +1 -0
  13. package/dist-node/index.js +40 -0
  14. package/dist-node/index.js.map +1 -0
  15. package/dist-node/init-lint.d.ts +43 -0
  16. package/dist-node/init-lint.d.ts.map +1 -0
  17. package/dist-node/init-lint.js +84 -0
  18. package/dist-node/init-lint.js.map +1 -0
  19. package/dist-node/manifest.d.ts +33 -0
  20. package/dist-node/manifest.d.ts.map +1 -0
  21. package/dist-node/manifest.js +59 -0
  22. package/dist-node/manifest.js.map +1 -0
  23. package/dist-node/materializer.d.ts +52 -0
  24. package/dist-node/materializer.d.ts.map +1 -0
  25. package/dist-node/materializer.js +194 -0
  26. package/dist-node/materializer.js.map +1 -0
  27. package/dist-node/package-root.d.ts +5 -0
  28. package/dist-node/package-root.d.ts.map +1 -0
  29. package/dist-node/package-root.js +17 -0
  30. package/dist-node/package-root.js.map +1 -0
  31. package/dist-node/payload.d.ts +22 -0
  32. package/dist-node/payload.d.ts.map +1 -0
  33. package/dist-node/payload.js +49 -0
  34. package/dist-node/payload.js.map +1 -0
  35. package/dist-node/pointer-hub.d.ts +22 -0
  36. package/dist-node/pointer-hub.d.ts.map +1 -0
  37. package/dist-node/pointer-hub.js +50 -0
  38. package/dist-node/pointer-hub.js.map +1 -0
  39. package/dist-node/publication.cli.d.ts +9 -0
  40. package/dist-node/publication.cli.d.ts.map +1 -0
  41. package/dist-node/publication.cli.js +17 -0
  42. package/dist-node/publication.cli.js.map +1 -0
  43. package/dist-node/publication.d.ts +23 -0
  44. package/dist-node/publication.d.ts.map +1 -0
  45. package/dist-node/publication.js +47 -0
  46. package/dist-node/publication.js.map +1 -0
  47. package/dist-node/reconcile.cli.d.ts +11 -0
  48. package/dist-node/reconcile.cli.d.ts.map +1 -0
  49. package/dist-node/reconcile.cli.js +39 -0
  50. package/dist-node/reconcile.cli.js.map +1 -0
  51. package/dist-node/reconcile.d.ts +30 -0
  52. package/dist-node/reconcile.d.ts.map +1 -0
  53. package/dist-node/reconcile.js +51 -0
  54. package/dist-node/reconcile.js.map +1 -0
  55. package/dist-node/ship/prompts/fix.md +22 -0
  56. package/dist-node/ship/prompts/implement.md +34 -0
  57. package/dist-node/ship/prompts/review.md +28 -0
  58. package/dist-node/ship/ship.agent.d.ts +22 -0
  59. package/dist-node/ship/ship.agent.d.ts.map +1 -0
  60. package/dist-node/ship/ship.agent.js +142 -0
  61. package/dist-node/ship/ship.agent.js.map +1 -0
  62. package/dist-node/ship/ship.args.d.ts +15 -0
  63. package/dist-node/ship/ship.args.d.ts.map +1 -0
  64. package/dist-node/ship/ship.args.js +93 -0
  65. package/dist-node/ship/ship.args.js.map +1 -0
  66. package/dist-node/ship/ship.context.d.ts +12 -0
  67. package/dist-node/ship/ship.context.d.ts.map +1 -0
  68. package/dist-node/ship/ship.context.js +3 -0
  69. package/dist-node/ship/ship.context.js.map +1 -0
  70. package/dist-node/ship/ship.d.ts +4 -0
  71. package/dist-node/ship/ship.d.ts.map +1 -0
  72. package/dist-node/ship/ship.js +221 -0
  73. package/dist-node/ship/ship.js.map +1 -0
  74. package/dist-node/ship/ship.mr.d.ts +9 -0
  75. package/dist-node/ship/ship.mr.d.ts.map +1 -0
  76. package/dist-node/ship/ship.mr.js +171 -0
  77. package/dist-node/ship/ship.mr.js.map +1 -0
  78. package/dist-node/ship/ship.output.d.ts +9 -0
  79. package/dist-node/ship/ship.output.d.ts.map +1 -0
  80. package/dist-node/ship/ship.output.js +21 -0
  81. package/dist-node/ship/ship.output.js.map +1 -0
  82. package/dist-node/ship/ship.tracker.d.ts +37 -0
  83. package/dist-node/ship/ship.tracker.d.ts.map +1 -0
  84. package/dist-node/ship/ship.tracker.js +220 -0
  85. package/dist-node/ship/ship.tracker.js.map +1 -0
  86. package/dist-node/version.cli.d.ts +9 -0
  87. package/dist-node/version.cli.d.ts.map +1 -0
  88. package/dist-node/version.cli.js +30 -0
  89. package/dist-node/version.cli.js.map +1 -0
  90. package/dist-node/version.d.ts +24 -0
  91. package/dist-node/version.d.ts.map +1 -0
  92. package/dist-node/version.js +76 -0
  93. package/dist-node/version.js.map +1 -0
  94. package/docs/adr/ADR-0000-proceso-y-formato-de-adrs.md +115 -0
  95. package/docs/adr/foundational/A-001-clean-architecture-4-capas.md +88 -0
  96. package/docs/adr/foundational/A-002-cqrs-semantico.md +58 -0
  97. package/docs/adr/foundational/A-003-tdd.md +97 -0
  98. package/docs/adr/foundational/A-005-either-return-custom-methods.md +80 -0
  99. package/docs/adr/foundational/A-006-feature-completion-criteria.md +47 -0
  100. package/docs/adr/foundational/A-007-data-contract-fail-fast.md +109 -0
  101. package/docs/adr/foundational/A-008-bounded-context-decomposition.md +130 -0
  102. package/docs/adr/foundational/A-009-use-case-taxonomy.md +99 -0
  103. package/docs/adr/foundational/A-010-propiedad-emision-eventos-dominio.md +95 -0
  104. package/docs/adr/foundational/A-011-characterization-first-refactoring.md +90 -0
  105. package/docs/adr/foundational/A-012-helm-mecanismo-primario-despliegue.md +67 -0
  106. package/docs/adr/foundational/A-013-contrato-settings-unica-fuente-configuracion.md +74 -0
  107. package/docs/adr/foundational/A-014-generacion-artefactos-despliegue-desde-contrato-settings.md +75 -0
  108. package/docs/adr/foundational/A-015-cloudevents-estandar-eventos.md +85 -0
  109. package/docs/adr/foundational/A-016-cicd-gitlab-pipeline-raiz-pipelines-modulares.md +92 -0
  110. package/docs/adr/foundational/A-017-taxonomia-repositorios-librerias-sistemas.md +93 -0
  111. package/docs/adr/foundational/A-018-practicas-build-imagenes-docker.md +85 -0
  112. package/docs/adr/foundational/A-019-convenciones-autoria-helm-charts.md +97 -0
  113. package/docs/adr/foundational/A-020-entorno-desarrollo-estandarizado-devcontainer.md +58 -0
  114. package/docs/adr/foundational/A-022-formato-reporte-tests-ctrf.md +55 -0
  115. package/docs/adr/foundational/A-023-composicion-bloques-prompt-agentes.md +65 -0
  116. package/docs/adr/foundational/A-024-features-slices-verticales-portables.md +41 -0
  117. package/docs/adr/foundational/A-025-anatomia-mecanica-feature-puertos-adaptadores-drivers.md +104 -0
  118. package/docs/adr/foundational/A-026-infraestructura-compartida.md +44 -0
  119. package/docs/adr/foundational/A-027-patron-wiring-entry-point.md +67 -0
  120. package/docs/adr/foundational/A-029-verbos-intencion-metodos-lado-negocio.md +54 -0
  121. package/docs/adr/foundational/A-030-global-development-tooling.md +52 -0
  122. package/docs/adr/foundational/A-031-ubiquitous-language.md +64 -0
  123. package/docs/adr/foundational/A-032-domain-artifact-documentation-format.md +128 -0
  124. package/docs/adr/foundational/A-033-estandar-mensajes-commit.md +127 -0
  125. package/docs/adr/foundational/A-034-canonical-skill-set.md +64 -0
  126. package/docs/adr/foundational/A-035-captura-ideas-reanclaje-candies.md +51 -0
  127. package/docs/adr/foundational/A-036-adopcion-wayfinder-ortogonalidad-labels.md +37 -0
  128. package/docs/adr/foundational/A-037-formalizacion-taxonomia-labels.md +98 -0
  129. package/docs/adr/foundational/A-038-issues-referencian-skills-nombre.md +54 -0
  130. package/docs/adr/foundational/A-039-pipeline-ship-issues-hijos-spec.md +64 -0
  131. package/docs/adr/foundational/A-040-punteros-configuracion-repo-skills.md +44 -0
  132. package/docs/adr/foundational/A-041-estrategia-de-ramas.md +45 -0
  133. package/docs/adr/foundational/A-042-formato-documentos-issue-tracker.md +78 -0
  134. package/docs/adr/foundational/A-043-vocabulario-etiquetas-adrs.md +42 -0
  135. package/docs/adr/foundational/A-044-composicion-funcional-procesos-operaciones.md +44 -0
  136. package/docs/adr/foundational/A-045-guardrails-aplicables-no-directrices.md +48 -0
  137. package/docs/adr/foundational/A-046-metricas-de-forma-y-legibilidad-del-codigo.md +50 -0
  138. package/docs/adr/foundational/A-047-dependencias-explicitas-sin-globales-ambientales.md +40 -0
  139. package/docs/adr/foundational/A-048-cobertura-minima-codigo.md +39 -0
  140. package/docs/adr/foundational/A-049-materializacion-bucle-guardrails-extension-nativa-pi.md +49 -0
  141. package/docs/adr/foundational/A-050-el-caso-de-uso-pide-al-dominio-no-lee-su-representacion.md +50 -0
  142. package/docs/adr/foundational/A-051-orden-imports-por-distancia.md +47 -0
  143. package/docs/adr/foundational/A-052-distribucion-metodologia-paquete-versionado.md +42 -0
  144. package/docs/adr/foundational/A-053-errores-compartidos-entre-features-dos-hogares-por-capa.md +43 -0
  145. package/docs/adr/foundational/A-054-contrato-costura-driver-port-raw-data-canal-error.md +65 -0
  146. package/docs/adr/foundational/index.md +98 -0
  147. package/docs/adr/index.md +19 -0
  148. package/docs/adr/python/P-001-dependencias-por-feature-fastapi-depends.md +63 -0
  149. package/docs/adr/python/P-002-inyeccion-token-por-request-sin-persistirlo.md +35 -0
  150. package/docs/adr/python/P-003-sqlalchemy-async-connection-pooling.md +59 -0
  151. package/docs/adr/python/P-004-serializer-json-custom-modelos-pydantic.md +47 -0
  152. package/docs/adr/python/P-005-patrones-pitfalls-nicegui.md +148 -0
  153. package/docs/adr/python/P-006-convenciones-pytest.md +96 -0
  154. package/docs/adr/python/P-007-ci-python-alineacion-poetry-version-unica.md +55 -0
  155. package/docs/adr/python/P-008-empaquetado-infraestructura-compartida-por-tecnologia.md +38 -0
  156. package/docs/adr/python/index.md +14 -0
  157. package/docs/adr/typescript/T-001-ddd-artifact-validation-zod-primitives.md +136 -0
  158. package/docs/adr/typescript/T-002-test-documentation-jsdoc.md +133 -0
  159. package/docs/adr/typescript/T-003-readme-formatting-domain-artifacts.md +51 -0
  160. package/docs/adr/typescript/T-005-input-optionality-use-case-not-entity.md +130 -0
  161. package/docs/adr/typescript/T-006-small-enums-inlined-zod-regex.md +77 -0
  162. package/docs/adr/typescript/T-007-controller-input-zod-schema.md +79 -0
  163. package/docs/adr/typescript/T-008-expressive-use-case-pipe.md +207 -0
  164. package/docs/adr/typescript/T-009-mdx-brace-escaping.md +80 -0
  165. package/docs/adr/typescript/T-010-stack-tooling-typescript-dominio.md +53 -0
  166. package/docs/adr/typescript/T-011-ultra-reporter-herramienta-canonica-documentacion.md +52 -0
  167. package/docs/adr/typescript/T-012-npm-workspaces-estructura-monorepo-clean-architecture.md +54 -0
  168. package/docs/adr/typescript/T-013-definicion-eventos-versionados-ultra-ddd.md +45 -0
  169. package/docs/adr/typescript/T-014-publicacion-distribucion-librerias-npm-semver.md +53 -0
  170. package/docs/adr/typescript/T-015-method-placement-definition.md +35 -0
  171. package/docs/adr/typescript/T-016-contrato-settings-zod.md +34 -0
  172. package/docs/adr/typescript/T-017-characterization-tests-golden-files.md +39 -0
  173. package/docs/adr/typescript/T-018-procedencia-campos-frontmatter.md +55 -0
  174. package/docs/adr/typescript/T-019-ultra-generator-herramienta-canonica-generacion.md +35 -0
  175. package/docs/adr/typescript/T-020-ultra-settings-herramienta-canonica-exportacion-despliegue.md +36 -0
  176. package/docs/adr/typescript/T-021-pipe-flujo-datos-operadores-semantica-contexto-inmutable.md +105 -0
  177. package/docs/adr/typescript/T-022-construction-is-execution-single-boundary.md +112 -0
  178. package/docs/adr/typescript/T-023-registry-cli-declara-dependencias-reales.md +84 -0
  179. package/docs/adr/typescript/T-024-paquete-ultra-agent-manifiesto-pi-peers-cli.md +39 -0
  180. package/docs/adr/typescript/T-025-publicacion-npm-trusted-publishing-procedencia.md +59 -0
  181. package/docs/adr/typescript/index.md +30 -0
  182. package/eslint/index.mjs +721 -0
  183. package/package.json +94 -0
  184. package/pi/extensions/handoff/README.md +92 -0
  185. package/pi/extensions/handoff/handoff-prompt.txt +9 -0
  186. package/pi/extensions/handoff/index.ts +296 -0
  187. package/pi/extensions/handoff/package.json +12 -0
  188. package/pi/extensions/qa-guardrail/README.md +108 -0
  189. package/pi/extensions/qa-guardrail/adapters/cli.ts +100 -0
  190. package/pi/extensions/qa-guardrail/adapters/eslint.ts +90 -0
  191. package/pi/extensions/qa-guardrail/adapters/registry.ts +45 -0
  192. package/pi/extensions/qa-guardrail/baseline.ts +74 -0
  193. package/pi/extensions/qa-guardrail/cerco.ts +134 -0
  194. package/pi/extensions/qa-guardrail/check.ts +185 -0
  195. package/pi/extensions/qa-guardrail/config.ts +189 -0
  196. package/pi/extensions/qa-guardrail/delta.ts +52 -0
  197. package/pi/extensions/qa-guardrail/feedback.ts +26 -0
  198. package/pi/extensions/qa-guardrail/index.ts +311 -0
  199. package/pi/extensions/qa-guardrail/nstop.ts +82 -0
  200. package/pi/extensions/qa-guardrail/package.json +12 -0
  201. package/pi/extensions/qa-guardrail/selection.ts +98 -0
  202. package/pi/extensions/qa-guardrail/types.ts +64 -0
  203. package/scripts/copy-assets.sh +10 -0
  204. package/scripts/reconcile-tags.sh +94 -0
  205. package/scripts/release-beta.sh +64 -0
  206. package/scripts/release-build.sh +53 -0
  207. package/scripts/release.sh +51 -0
  208. package/scripts/verify-adr-consistency.py +217 -0
  209. package/skills/code-review/SKILL.md +66 -0
  210. package/skills/codebase-design/SKILL.md +46 -0
  211. package/skills/configure-repo/SKILL.md +33 -0
  212. package/skills/diagnose-bug/SKILL.md +63 -0
  213. package/skills/domain-modeling/SKILL.md +56 -0
  214. package/skills/grill-me/SKILL.md +34 -0
  215. package/skills/i-have-an-idea/SKILL.md +166 -0
  216. package/skills/implement/SKILL.md +22 -0
  217. package/skills/research/SKILL.md +17 -0
  218. package/skills/ship/SKILL.md +26 -0
  219. package/skills/spike/SKILL.md +27 -0
  220. package/skills/tdd/SKILL.md +68 -0
  221. package/skills/tdd/references/deep-modules.md +53 -0
  222. package/skills/tdd/references/interface-design.md +74 -0
  223. package/skills/tdd/references/mocking.md +80 -0
  224. package/skills/tdd/references/refactoring.md +49 -0
  225. package/skills/tdd/references/tests.md +184 -0
  226. package/skills/to-specs/SKILL.md +141 -0
  227. package/skills/to-tasks/SKILL.md +143 -0
  228. package/skills/triage/SKILL.md +73 -0
  229. package/skills/ultra-generator/SKILL.md +263 -0
  230. package/skills/ultra-generator/references/aggregate-root.md +149 -0
  231. package/skills/ultra-generator/references/domain-event.md +174 -0
  232. package/skills/ultra-generator/references/entity.md +133 -0
  233. package/skills/ultra-generator/references/service.md +92 -0
  234. package/skills/ultra-generator/references/value-object.md +135 -0
  235. package/skills/wayfinder/SKILL.md +201 -0
  236. package/skills/workflow/SKILL.md +31 -0
  237. package/skills/writing-for-agents/SKILL-MECHANICS.md +32 -0
  238. package/skills/writing-for-agents/SKILL.md +86 -0
  239. package/skills/writing-for-agents/references/adrs.md +19 -0
@@ -0,0 +1,39 @@
1
+ # A-048: Cobertura mínima de código
2
+
3
+ **Estado**: Aceptado
4
+
5
+ **Fecha**: 2026-09-04
6
+
7
+ **originally**: imolko
8
+
9
+ **tags**: testing
10
+
11
+ ## Contexto
12
+
13
+ Sin un piso numérico, la cobertura de código se erosiona en silencio: cada contribución sin test baja el número y la suite verde deja de garantizar que el comportamiento queda verificado.
14
+
15
+ Los tests ya tienen canon: el ciclo TDD ([A-003](./A-003-tdd.md)) fija qué artefactos se prueban y con qué aserciones. Falta fijar el cuánto: el piso de cobertura que un repositorio debe sostener.
16
+
17
+ Sin una decisión canónica, cada repositorio fija su propio umbral — o ninguno —, y la cobertura deja de ser una señal comparable entre proyectos.
18
+
19
+ ## Decisión
20
+
21
+ Todo repositorio de Imolko exige una **cobertura mínima de código del 80% de líneas**, medida sobre el código testeable por la herramienta de cobertura de su ecosistema. La cobertura de líneas es la fracción de líneas que ejercita la suite de tests. El piso se verifica como **gate en la integración continua** ([A-016](./A-016-cicd-gitlab-pipeline-raiz-pipelines-modulares.md)): por debajo del 80%, el pipeline falla.
22
+
23
+ La verificación de la cobertura pertenece a la capa de tests del guardrail ([A-045](./A-045-guardrails-aplicables-no-directrices.md)); se mide al correr la suite completa.
24
+
25
+ Qué artefactos quedan cubiertos lo fija [A-003](./A-003-tdd.md); este ADR fija el cuánto. El alcance de lo medido — qué código cuenta como testeable y qué se excluye (generado, glue de infraestructura, wiring de entrada) — lo define el tier de lenguaje y la configuración del repositorio.
26
+
27
+ ## Consecuencias
28
+
29
+ ### Positivas
30
+
31
+ - **Señal objetiva**: la cobertura es un número verificable por máquina, no una preferencia.
32
+ - **Sin erosión silenciosa**: bajar del 80% rompe el pipeline; la cobertura no se degrada por goteo.
33
+ - **Comparable entre proyectos**: un mismo piso para todos los repositorios de Imolko.
34
+
35
+ ### Negativas
36
+
37
+ - **Migración**: el código existente por debajo del 80% debe migrarse, feature por feature.
38
+ - **Juego de cobertura**: tests que ejecutan líneas sin verificar su comportamiento inflan el número; la calidad de la aserción la fija [A-003](./A-003-tdd.md) (aserciones semánticas).
39
+ - **Fricción en código de pega**: el glue de infraestructura y el wiring de entrada presionan el piso; la válvula es la exclusión declarada en la configuración del ecosistema.
@@ -0,0 +1,49 @@
1
+ # A-049: Materialización del bucle de guardrails como extensión nativa del agente pi
2
+
3
+ **Estado**: Aceptado
4
+
5
+ **Fecha**: 2026-09-01
6
+
7
+ **originally**: imolko
8
+
9
+ **tags**: agentes, tooling
10
+
11
+ ## Contexto
12
+
13
+ [A-045](./A-045-guardrails-aplicables-no-directrices.md) gobierna la salida del agente con guardrails aplicables en dos capas — tests ([A-003](./A-003-tdd.md)) y linting, cuyas métricas fija [A-046](./A-046-metricas-de-forma-y-legibilidad-del-codigo.md) — y exige tres propiedades: (1) bucle de retroalimentación tras cada edición, (2) corte tras N fallos sobre el mismo archivo, (3) cerco sin atajos (sin desactivar reglas en línea ni editar la configuración).
14
+
15
+ A-045 delega la materialización del cerco al tier de lenguaje, lo que cubre las reglas (la configuración del linter, según A-046) pero no el **bucle** que las ejecuta dentro del ciclo de edición del agente. Ese bucle — cuándo se lintea, qué se reporta, cuándo se corta, qué se protege — no tiene dueño, y sin dueño cada repositorio lo improvisa o no lo materializa.
16
+
17
+ El agente de codificación canónico es **pi** ([A-030](./A-030-global-development-tooling.md)), así que el bucle se materializa como una extensión nativa de pi (`qa-guardrail`). La alternativa — apoyarse en una herramienta de calidad genérica con `bin`/`args` configurables — abriría un vector de ejecución arbitraria en manos del agente: el cerco solo se autosella si la configuración selecciona y acota, nunca ejecuta.
18
+
19
+ Por último, cuando el guardrail se introduce en un codebase que ya arrastra violaciones de A-046 (migración en curso, feature por feature), el bucle no debe atribuir al agente las violaciones heredadas: de lo contrario el agente se ahoga en ruido que no creó. La retroalimentación debe ser delta-scoped.
20
+
21
+ ## Decisión
22
+
23
+ Materializar el bucle de A-045 como una extensión nativa de pi, construida de forma nativa (no sobre `pi-code-quality`) y bajo TDD ([A-003](./A-003-tdd.md)):
24
+
25
+ 1. **Configuración de solo selección** — un archivo de configuración versionado declara qué adaptador whitelisted cubre qué archivos: `tools: [{ id, include, exclude, rootMarkers, enabled? }]`. Sin `bin`, `args` ni `formatter`: la configuración selecciona y acota, nunca ejecuta (cerco).
26
+ 2. **Capa de adaptadores** — interfaz uniforme `lint(file) → Violation[]` y registro whitelisted de adaptadores (`eslint` hoy; `ruff`/`pylint` futuros). Carga perezosa: cargar la extensión no requiere ningún linter; un binario ausente produce warning, no fallo de carga.
27
+ 3. **Ejecución por adaptador** — el adaptador `eslint` corre in-process (API Node de ESLint, instancia única reutilizada, reconstruida si cambia la configuración); los adaptadores Python futuros invocan su CLI. El runner es agnóstico del mecanismo.
28
+ 4. **Retroalimentación delta-scoped** — en `tool_result` de `write`/`edit`, se lintea el archivo y se reporta solo el delta contra una línea base congelada «tal como el agente encontró el archivo» (capturada en `tool_call` antes de la primera edición; vacía para archivos nuevos). El agente solo ve — y solo responde por — las violaciones que introduce.
29
+ 5. **Corte en N** — contador consecutivo de deltas-fallo por archivo, N=3, reinicio con delta limpio. Al Nth: bloqueo de `write`/`edit` a ese archivo + mensaje «STOP, reportar a la persona» + notificación a la persona; el desbloqueo es humano (`/qa-guardrail reset <archivo>`).
30
+ 6. **Cerco** — lista protegida hardcodeada (no configurable): la definición de reglas (`eslint.config.mjs`), la configuración de la propia extensión (`.pi/qa-guardrail.json`) y su propio código (`.pi/extensions/qa-guardrail/**`). Las directivas de desactivación de reglas se detectan independientemente del linter: las nuevas se bloquean en `tool_call`; las heredadas se listan solo en el barrido (`/qa-guardrail check`).
31
+ 7. **Alcance v1** — solo linting, solo el entry `eslint`. Sin formatter.
32
+
33
+ ## Consecuencias
34
+
35
+ ### Positivas
36
+
37
+ - **Calidad determinista**: la regla se cumple o el bucle se detiene, sin depender del modelo.
38
+ - **Sin vector de ejecución arbitraria**: la configuración no puede invocar binarios arbitrarios; el cerco es autosellante.
39
+ - **«Solo mis cambios»**: la retroalimentación delta-scoped no atribuye al agente violaciones heredadas (humanas o de migración).
40
+ - **Carga sin dependencias**: la extensión carga sin ningún linter; cada adaptador toca su dependencia solo al usarse.
41
+
42
+ ### Negativas
43
+
44
+ - **Costo de propiedad**: una extensión con un esquema deliberadamente menos flexible que una herramienta genérica de calidad (sin `bin`/`args`, sin formatter).
45
+ - **Migración invisible hasta tocar el archivo**: las violaciones heredadas no se reportan salvo que el archivo se edite (por diseño).
46
+ - **Punto ciego estructural durante la migración**: agravar una función ya-no-conforme no se reporta (la violación ya estaba en la línea base).
47
+ - **Falso positivo por desplazamiento de líneas**: la identidad delta es `(rule, line, column)`, así que un edit que desplace líneas por encima de una violación heredada cambia su `line` y puede reportarla como introducida (un falso delta-fallo que suma al corte N). Es el punto ciego inverso del anterior.
48
+ - **Cerco limitado a `write`/`edit`**: el cerco opera sobre `tool_call` de write/edit, por lo que `bash` queda fuera de su superficie de enforcement; es una limitación estructural del cerco, no una desviación.
49
+ - **`eslint` como peer implícito**: el adaptador in-process hace de eslint un peer en tiempo de ejecución; la extensión no era un paquete distribuible hasta declararlos. Resuelto en [A-052](./A-052-distribucion-metodologia-paquete-versionado.md): el paquete de distribución declara `eslint` como dependencia para que la extensión sea distribuible.
@@ -0,0 +1,50 @@
1
+ # A-050: El caso de uso habla en términos del dominio, no lee ni retorna su representación serializada
2
+
3
+ **Estado**: Aceptado
4
+
5
+ **Fecha**: 2026-09-16
6
+
7
+ **originally**: imolko
8
+
9
+ **tags**: arquitectura, dominio
10
+
11
+ ## Contexto
12
+
13
+ El caso de uso opera con agregados y value objects; la infraestructura, con tablas, filas y mensajes ([A-025](./A-025-anatomia-mecanica-feature-puertos-adaptadores-drivers.md)). Para cruzar esa frontera, los artefactos de dominio exponen su representación serializada — primitive, payload, snapshot — y el adaptador es quien la consume para hablar con el driver port. Esa representación es la costura de infraestructura, no el vocabulario del caso de uso.
14
+
15
+ Cuando el caso de uso lee esa representación para decidir o derivar conceptos, pierde el lenguaje del dominio: compara cadenas (`claim.getPrimitive().status === 'Open'`) o ensambla un agregado leyendo las tripas de otro (`stockMovement.getPrimitive().lines[0]…`). El concepto de negocio queda esparcido y duplicado feature a feature, y el compilador no lo vigila. El grep del árbol muestra el mismo patrón en casi todas las features; en `abrir-reclamo` se manifestó como la comparación del `status`.
16
+
17
+ ## Decisión
18
+
19
+ El caso de uso obtiene hechos y conceptos del dominio **pidiéndoselos** — invocando consultas, predicados y fábricas del dominio —, nunca **leyendo** la representación serializada del objeto. La representación serializada la consumen el adaptador (para serializar al driver) y los tests (para verificar estado); no es vocabulario del caso de uso.
20
+
21
+ La lectura serializada en el caso de uso esconde cuatro fugas, cada una con su corrección:
22
+
23
+ | Fuga | Olor | Corrección |
24
+ |------|------|------------|
25
+ | **Decidir sobre estado** | `claim.getPrimitive().status === 'Open'` | un predicado del dominio: `claim.isOpen()` |
26
+ | **Ensamblar un agregado desde otro** | construir un payload leyendo `movement.getPrimitive()` | una fábrica del dominio: `Claim.open(...)` |
27
+ | **Extraer primitivo para un puerto** | `port.findById(vo.getPrimitive())` | el puerto declara el value object, no el primitivo |
28
+ | **Retornar un primitivo en la salida** | `toOutput` devuelve `ctx.claimId.getPrimitive()` | el `OutputDto` lleva el value object; la traducción a primitivo/wire la hace la frontera (controlador o presentador) |
29
+
30
+ Simétricamente, el caso de uso también **retorna** en términos del dominio: el `OutputDto` lleva value objects, no primitivos. La traducción del value object a su forma plana (primitivo/wire) la hace la frontera — el controlador o el presentador de la app ([A-025](./A-025-anatomia-mecanica-feature-puertos-adaptadores-drivers.md)) —, no el caso de uso.
31
+
32
+ Cuando el dominio modela un concepto como primitivo — p. ej. `Claim.referenceId` es un `string`, y `ReferenceNotFoundError`/`ClaimAlreadyExistsError` llevan `referenceId: string` —, una consulta del dominio puede retornar ese primitivo: es un *getter de primitivo* ([A-005](./A-005-either-return-custom-methods.md)), y el puerto puede permanecer primitivo. La regla "el puerto declara el value object" aplica cuando el dominio tiene un value object para ese concepto.
33
+
34
+ La regla es un guardrail ([A-045](./A-045-guardrails-aplicables-no-directrices.md)): la cumple la materialización del tier de lenguaje, no la voluntad del autor. El destino es una regla de lint que prohíbe invocar `getPrimitive`/`getPayload`/`getSnapshot` en los casos de uso; se despliega feature a feature — hoy cubre las features ya migradas (p. ej. `abrir-reclamo`) y, para el resto, la comparación de `status`/`state`/`type`.
35
+
36
+ Este ADR fija *qué* puede leer y retornar el caso de uso; *qué* retornan los métodos que debe invocar lo fija [A-005](./A-005-either-return-custom-methods.md).
37
+
38
+ ## Consecuencias
39
+
40
+ ### Positivas
41
+
42
+ - **Conceptos en un solo lugar**: el estado y sus transiciones viven en el dominio; el caso de uso los invoca por nombre, preservando el lenguaje ubicuo ([A-031](./A-031-ubiquitous-language.md)).
43
+ - **Guardrail verificable**: la regla de lint fija la forma; el compilador fija el tipo.
44
+ - **Sin duplicación**: el mismo predicado se escribe una vez en el dominio y se invoca desde cada feature que lo necesita.
45
+
46
+ ### Negativas
47
+
48
+ - **Más métodos en el dominio**: cada consulta, predicado o fábrica es un método nuevo que hay que ubicar en el dominio y testear.
49
+ - **Migración larga**: el patrón está esparcido en casi todas las features; se refactoriza feature a feature.
50
+ - **Tensión con la API actual**: las fábricas (`*.create(payload)`) y algunos puertos (`findById(string)`) hoy reciben primitivos; eliminarlos exige rediseñarlos antes de poder quitar toda lectura serializada.
@@ -0,0 +1,47 @@
1
+ # A-051: Orden de imports por distancia al archivo
2
+
3
+ **Estado**: Aceptado
4
+
5
+ **Fecha**: 2026-09-28
6
+
7
+ **originally**: imolko
8
+
9
+ **tags**: arquitectura, tooling
10
+
11
+ ## Contexto
12
+
13
+ Cada archivo declara sus imports en el orden en que aparecieron, sin criterio: el paquete externo, el módulo del proyecto y el vecino de carpeta se mezclan en la cabecera. El desorden tiene costos concretos:
14
+
15
+ - **Lectura**: para saber de qué depende un archivo hay que recorrer toda la cabecera en lugar de leer un bloque.
16
+ - **Ruido en revisión**: reordenar imports a mano produce diffs que ocultan el cambio real.
17
+ - **Dirección de dependencias invisible**: la distancia entre un archivo y lo que importa es la señal más barata de con qué capa está hablando; mezclada, la señal se pierde.
18
+
19
+ La forma del código ya tiene un canon numérico ([A-046](./A-046-metricas-de-forma-y-legibilidad-del-codigo.md)) y un mecanismo de enforcement ([A-045](./A-045-guardrails-aplicables-no-directrices.md)); falta fijar el orden de los imports como parte de esa forma.
20
+
21
+ ## Decisión
22
+
23
+ Los imports de un archivo se ordenan en **capas de distancia creciente** desde el archivo:
24
+
25
+ 1. **Librerías externas**: builtins del runtime y paquetes de terceros.
26
+ 2. **Paquetes del proyecto**: workspaces y alias del repositorio, más externos que la carpeta que contiene el archivo.
27
+ 3. **Imports relativos**: de la carpeta más lejana a la más cercana al archivo.
28
+
29
+ Dentro de cada capa el orden es **alfabético ascendente**. Entre imports relativos, los de subcarpetas —un salto más lejanos— preceden a los del mismo directorio —los más cercanos al archivo—.
30
+
31
+ La regla es agnóstica al lenguaje. La verifica la capa de linting ([A-045](./A-045-guardrails-aplicables-no-directrices.md)), es auto-corregible, y su materialización concreta —configuración, nombres de reglas, excepciones— vive en el repositorio. Los **imports de efecto lateral**, aquellos sin especificadores cuyo único propósito es ejecutar el módulo, quedan fuera de la regla: su posición puede ser semánticamente significativa y el ordenador no los mueve.
32
+
33
+ El código existente que aún no cumple la regla se migra de forma incremental: una línea base en el linting congela las violaciones actuales como deuda visible, mientras el código nuevo ya nace ordenado. Al migrar un archivo, su deuda se elimina.
34
+
35
+ ## Consecuencias
36
+
37
+ ### Positivas
38
+
39
+ - **Cabecera legible**: los imports se leen en bloques de distancia; el bloque dice de dónde viene el archivo.
40
+ - **Dirección de dependencias visible**: un paquete externo arriba y un vecino de carpeta abajo exponen la capa del archivo sin leer su cuerpo.
41
+ - **Revisión sin ruido**: el orden deja de ser preferencia y el reordenamiento aparece solo cuando cambian las dependencias.
42
+ - **Enforcement barato**: la regla es auto-corregible; el agente ordena en el ciclo de edición y la persona no negocia el orden.
43
+
44
+ ### Negativas
45
+
46
+ - **Deuda de migración**: los archivos que no cumplen la regla permanecen en la línea base de linting hasta migrarse, uno por uno.
47
+ - **Efecto lateral manual**: los imports que deben ejecutarse primero (polyfills, registro de metadatos) no los cubre la regla; su posición depende de quien los escribe.
@@ -0,0 +1,42 @@
1
+ # A-052: Distribución de la metodología como paquete versionado
2
+
3
+ **Estado**: Aceptado
4
+
5
+ **Fecha**: 2026-10-02
6
+
7
+ **originally**: imolko
8
+
9
+ **tags**: agentes, tooling
10
+
11
+ ## Contexto
12
+
13
+ La metodología ultra —el conjunto canónico de skills ([A-034](./A-034-canonical-skill-set.md)) y el registro ADR de los tiers A, T y P— vive en un único repositorio pero no tiene mecanismo de instalación ni de actualización. Cada proyecto que quiere adoptar la metodología copia los skills y el registro a mano: no hay forma de saber qué versión está usando, ni de incorporar cambios posteriores sin volver a copiar a ciegas.
14
+
15
+ El formato de los skills ya es el estándar Agent Skills, agnóstico al harness, y pi —el agente canónico ([A-030](./A-030-global-development-tooling.md))— tiene un sistema de paquetes nativo. Pero no existe una decisión que fije *cómo* se distribuye la metodología, *qué* se distribuye y *qué ocurre* cuando un consumidor la modifica o la actualiza. El equipo quiere, además, servir a varios agentes (pi como primario), no a uno solo.
16
+
17
+ ## Decisión
18
+
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
+
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 un consumidor concreto (por ejemplo el tier G de Guarura) no forman parte del paquete.
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
+ 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
+ 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.
26
+ 6. **Punteros neutrales al harness.** Los skills leen los punteros del repositorio desde `docs/agents/repo-config.md`, con un bloque `## Agent skills` en `AGENTS.md`/`CLAUDE.md` como ancla —no desde `.pi/`—. Esto sustituye la ubicación fijada en [A-040](./A-040-punteros-configuracion-repo-skills.md).
27
+ 7. **Versionado.** El paquete es una librería ([A-017](./A-017-taxonomia-repositorios-librerias-sistemas.md)): SemVer derivado de los tipos de Conventional Commits ([A-033](./A-033-estandar-mensajes-commit.md)) con canal `-beta`. Los detalles de empaquetado npm (manifiesto `pi`, peers y CLI) viven en el tier TypeScript.
28
+
29
+ ## Consecuencias
30
+
31
+ ### Positivas
32
+
33
+ - **Instalación y actualización reproducibles**: un comando instala y otro reconcilia; la versión instalada queda registrada en el manifiesto.
34
+ - **Metodología única**: todos los proyectos comparten la misma versión canónica, sin forks privados que divergen.
35
+ - **Agente-agnóstico**: los skills se distribuyen por el estándar Agent Skills; las extensiones de pi son una capa adicional, no un requisito.
36
+ - **Sin pérdidas silenciosas**: la deriva se detecta y se resuelve de forma explícita (A-007).
37
+
38
+ ### Negativas
39
+
40
+ - **Un instalador que mantener**: el CLI y el manifiesto de versión son artefactos más que evolucionar.
41
+ - **Suscripción rígida**: personalizar un skill canónico exige escribir uno de proyecto, no editarlo —más fricción que un fork libre.
42
+ - **Doble fuente parcial**: el espejo de ADRs del consumidor duplica el registro canónico; la reconciliación mitiga la deriva pero no la elimina.
@@ -0,0 +1,43 @@
1
+ # A-053: Errores compartidos entre features: dos hogares por capa
2
+
3
+ **Estado**: Aceptado
4
+
5
+ **Fecha**: 2026-10-02
6
+
7
+ **originally**: imolko
8
+
9
+ **tags**: arquitectura, dominio
10
+
11
+ ## Contexto
12
+
13
+ Los casos de uso de `features/` producen errores que tienden a duplicarse feature a feature: la misma ausencia o el mismo fallo tecnológico reaparece en cada slice con clases idénticas salvo por el nombre de la feature. Son dos especies distintas:
14
+
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
+ - **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
+
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 Guarura (G-015); al ser independiente del dominio, se eleva aquí al tier fundacional.
19
+
20
+ ## Decisión
21
+
22
+ **Dos especies, dos hogares, por capa.** Un error compartido entre features tiene un único hogar según su capa:
23
+
24
+ 1. **Referencias de dominio** — errores de "no existe"/insuficiencia sobre un agregado del dominio — son **errores de dominio** y viven en el **contexto compartido del dominio** que [A-008](./A-008-bounded-context-decomposition.md) describe (el `shared-kernel`). Su identidad se ancla al **agregado** al que refieren, no a la feature que lo consume.
25
+ 2. **Fallos de infraestructura** — caída de base de datos, de bus de eventos, de generador de identificadores y afines — son **errores de la capa de aplicación** y viven en un **catálogo compartido paralelo a los slices de feature** ([A-024](./A-024-features-slices-verticales-portables.md)). Su identidad se ancla a la **preocupación de infraestructura** que los produce.
26
+
27
+ `shared-infra/<tech>/` y `representations/<protocol>/` **no** son hogares: las features nunca importan `shared-infra/` ([A-025](./A-025-anatomia-mecanica-feature-puertos-adaptadores-drivers.md), [A-026](./A-026-infraestructura-compartida.md)) y un catálogo de errores no es una forma de wire de protocolo ([A-026](./A-026-infraestructura-compartida.md)). El catálogo compartido de errores de infraestructura es un módulo hermano dentro del paquete de features, no una feature: las features lo importan sin violar «una feature nunca importa otra feature» ([A-024](./A-024-features-slices-verticales-portables.md)).
28
+
29
+ **La identidad del error es contrato.** Cada especie hereda la base de error de su capa (la base de error de dominio o la de caso de uso), y su identidad canónica es estable y no se renumera. La forma concreta de esa identidad —el esquema del identificador, las clases base— es materialización del tier de lenguaje, no parte de esta decisión.
30
+
31
+ ## Consecuencias
32
+
33
+ ### Positivas
34
+
35
+ - **Un único hogar por especie**: cada error duplicado vive una sola vez; corregirlo lo corrige en todas las features.
36
+ - **Identidad estable**: la identidad del error deja de depender del nombre de la feature y refleja el agregado o la preocupación a la que refiere.
37
+ - **Alineación con A-025/A-008**: las referencias de dominio se consolidan donde [A-025](./A-025-anatomia-mecanica-feature-puertos-adaptadores-drivers.md) las clasifica (error de dominio) y donde [A-008](./A-008-bounded-context-decomposition.md) aloja el vocabulario compartido; los fallos de infraestructura quedan en la capa de aplicación.
38
+
39
+ ### Negativas
40
+
41
+ - **Dos catálogos que navegar**: hay que distinguir «referencia de dominio» de «fallo de infraestructura» para elegir hogar; confundirlas reintroduce la duplicación.
42
+ - **Migración**: consolidar un error duplicado cambia su identidad; los contratos y las aserciones que la codifican deben migrarse en el mismo cambio.
43
+ - **Excepción acotada a A-024**: el catálogo compartido es un módulo compartido dentro del paquete de features, no una feature; el principio «sin librería compartida de ports» ([A-024](./A-024-features-slices-verticales-portables.md)) sigue intacto porque estos no son ports.
@@ -0,0 +1,65 @@
1
+ # A-054: Contrato de la costura del driver port: raw data y canal de error
2
+
3
+ **Estado**: Aceptado
4
+
5
+ **Fecha**: 2026-10-02
6
+
7
+ **originally**: imolko
8
+
9
+ **tags**: arquitectura
10
+
11
+ ## Contexto
12
+
13
+ El driver port es la costura raw-data entre el adaptador y el driver tecnológico ([A-025](./A-025-anatomia-mecanica-feature-puertos-adaptadores-drivers.md)). [A-025](./A-025-anatomia-mecanica-feature-puertos-adaptadores-drivers.md) fija su vocabulario —mementos/snapshots, eventos en formato estándar y DTOs planos, sin errores de dominio, sin tipos tecnológicos, `null` para la ausencia— y dónde se decide cada fallo: los errores de dominio en el adaptador y los tecnológicos en el driver. No fija, en cambio, tres cosas:
14
+
15
+ 1. **Por dónde viaja el fallo tecnológico** una vez que el driver lo detecta. Sin ese canal, el driver tiene tres salidas y ninguna es correcta: tragar el fallo y devolver `null` (colapsa «no existe» con «la base falló», contra [A-007](./A-007-data-contract-fail-fast.md)); lanzar una excepción (contra [A-005](./A-005-either-return-custom-methods.md) y [A-007](./A-007-data-contract-fail-fast.md)); o devolver el error de la feature (el driver port arrastra errores de dominio, contra [A-025](./A-025-anatomia-mecanica-feature-puertos-adaptadores-drivers.md)).
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
+ 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
+
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 Guarura (G-023); al ser independiente del dominio, se eleva aquí al tier fundacional.
20
+
21
+ ## Decisión
22
+
23
+ ### 1. El raw data cruza la costura en ambas direcciones
24
+
25
+ El driver port usa raw data en **todo** el cruce, no solo en el retorno. Ningún agregado, entidad ni value object del dominio cruza la costura, ni de salida ni de entrada.
26
+
27
+ - **Lectura/verificación** — el retorno es la forma raw (memento/snapshot) o `null`; los filtros son DTOs planos, nunca value objects del dominio.
28
+ - **Escritura** — el parámetro es la forma raw que corresponde a la costura: la **envolvente estándar** (eventos en formato estándar, [A-015](./A-015-cloudevents-estandar-eventos.md)) cuando es event-shaped, o el **memento/snapshot del agregado** cuando no lo es. `save(snapshot)` es la forma correcta; `save(aggregate)` no lo es.
29
+ - **Quién produce la forma raw** — el adaptador. En la lectura consume el memento y restaura el agregado; en la escritura produce el memento o la envolvente desde los hechos y la entrega al driver. La versión para concurrencia optimista viaja en el memento o la envolvente, no como estado del agregado.
30
+ - **Qué forma raw toca por agregado** lo decide su estrategia de persistencia; esta decisión no cambia esa elección: fija que, sea cual sea, el objeto con comportamiento no cruza.
31
+
32
+ ### 2. El driver port devuelve el canal de error del ecosistema
33
+
34
+ Todo método del driver port declara el canal de error del ecosistema en su variante asíncrona, según la naturaleza de la operación ([A-025](./A-025-anatomia-mecanica-feature-puertos-adaptadores-drivers.md)): las lecturas y verificaciones retornan el resultado de verificación; las mutaciones, el de ejecución. El tipo concreto del canal es materialización del tier de lenguaje.
35
+
36
+ ### 3. La ausencia sigue siendo `null` en el canal de éxito
37
+
38
+ `null` no cambia de significado: es la ausencia del dato en el vocabulario raw de la costura. La ausencia viaja en el canal de éxito; el fallo tecnológico, en el canal de error. En una consulta que retorna una colección, la colección vacía no es error. El adaptador decide:
39
+
40
+ - ausencia → error de dominio (o veredicto negativo);
41
+ - fallo tecnológico → error de infraestructura de la feature ([A-053](./A-053-errores-compartidos-entre-features-dos-hogares-por-capa.md)).
42
+
43
+ ### 4. El error del driver port es genérico, ajeno a la feature
44
+
45
+ El canal de error del driver port porta el fallo tecnológico en su forma neutra, no la unión de errores de la feature ni un error tecnológico concreto. El driver port conserva así el vocabulario raw de [A-025](./A-025-anatomia-mecanica-feature-puertos-adaptadores-drivers.md): sin errores de dominio y sin tipos de una tecnología concreta. La infraestructura compartida no importa el catálogo de errores de la feature para reportar un fallo ([A-026](./A-026-infraestructura-compartida.md)).
46
+
47
+ ### 5. El adaptador traduce en ambas direcciones y ensancha el canal
48
+
49
+ El adaptador es el único lugar de la traducción tipada dominio ↔ raw data ([A-025](./A-025-anatomia-mecanica-feature-puertos-adaptadores-drivers.md)): restaura el agregado desde el memento en la lectura, produce el memento/la envolvente en la escritura, y traduce el fallo genérico del driver a la unión de errores de la feature. El error de infraestructura compartido ([A-053](./A-053-errores-compartidos-entre-features-dos-hogares-por-capa.md)) integra la unión de errores de la feature que lo consume.
50
+
51
+ ## Consecuencias
52
+
53
+ ### Positivas
54
+
55
+ - **Dos causas, dos canales**: «no existe» y «la base falló» dejan de colapsar en un único `null`; el caso de uso no reporta una ausencia de negocio ante una caída de infraestructura ([A-007](./A-007-data-contract-fail-fast.md)).
56
+ - **Sin excepciones ni fallbacks**: el fallo tecnológico viaja como valor del canal del ecosistema ([A-005](./A-005-either-return-custom-methods.md), [A-007](./A-007-data-contract-fail-fast.md)).
57
+ - **Costura raw intacta en todo el cruce**: ni los tipos de dominio de salida ni los de entrada cruzan el driver port; el adaptador es el único traductor.
58
+ - **Regla de escritura explícita**: el caso no event-sourced deja de depender de interpretar [A-025](./A-025-anatomia-mecanica-feature-puertos-adaptadores-drivers.md); `save(aggregate)` queda marcado como no conforme.
59
+
60
+ ### Negativas
61
+
62
+ - **Un contrato más que aprender en la costura**: el driver que lee distingue ausencia de fallo; el que escribe, éxito de fallo; y ambos reciben/producen raw data.
63
+ - **Drivers existentes por migrar**: los driver ports que reciben el agregado o un value object no cumplen todavía este contrato; la migración es incremental.
64
+ - **Adaptador más explícito**: cada lectura mapea el fallo del driver a un error de feature y cada escritura produce la forma raw.
65
+ - **Deuda de guardrail**: el lint impone dirección de dependencias y prohíbe los tipos sin especificar en los driver ports, pero no detecta «objeto con comportamiento en la costura» ni «sin canal»; mientras no se añada, la conformidad depende de la revisión.
@@ -0,0 +1,98 @@
1
+ # ADRs Fundacionales (A-XXX)
2
+
3
+ Decisiones de arquitectura metodológicas y agnósticas al lenguaje. Aplican a todos los proyectos de Imolko (TypeScript, Python, etc.). El proceso y el formato están documentados en [ADR-0000](../ADR-0000-proceso-y-formato-de-adrs.md); el vocabulario de etiquetas vive en [A-043](./A-043-vocabulario-etiquetas-adrs.md).
4
+
5
+ Los 51 ADRs se agrupan en seis fases narrativas que cuentan el ciclo de desarrollo de Imolko, desde los conceptos de arquitectura hasta el despliegue de aplicaciones, el flujo de trabajo con agentes y el desarrollo de agentes. A-004, A-021 y A-028 permanecen omitidas intencionalmente.
6
+
7
+ ## Arquitectura
8
+
9
+ La estructura fundacional del sistema: capas, puertos y drivers, bounded contexts, el lenguaje ubicuo y las taxonomías que organizan casos de uso y repositorios.
10
+
11
+ | # | Título | Estado | Etiquetas |
12
+ |---|--------|--------|-----------|
13
+ | A-001 | [Clean Architecture con 4 capas](./A-001-clean-architecture-4-capas.md) | Aceptado | arquitectura |
14
+ | A-024 | [Features como slices verticales portables](./A-024-features-slices-verticales-portables.md) | Aceptado | arquitectura |
15
+ | A-025 | [Anatomía y mecánica de una feature: puertos, adaptadores y drivers](./A-025-anatomia-mecanica-feature-puertos-adaptadores-drivers.md) | Aceptado | arquitectura |
16
+ | A-026 | [Infraestructura compartida (shared-infra)](./A-026-infraestructura-compartida.md) | Aceptado | arquitectura |
17
+ | A-027 | [Patrón de wiring entry-point](./A-027-patron-wiring-entry-point.md) | Aceptado | arquitectura |
18
+ | A-002 | [Separación de comandos y consultas](./A-002-cqrs-semantico.md) | Aceptado | arquitectura |
19
+ | A-008 | [Descomposición en Bounded Contexts](./A-008-bounded-context-decomposition.md) | Aceptado | arquitectura, dominio |
20
+ | A-009 | [Taxonomía de criticidad de casos de uso](./A-009-use-case-taxonomy.md) | Aceptado | arquitectura, dominio |
21
+ | A-017 | [Taxonomía de repositorios: sistemas, librerías y configuración](./A-017-taxonomia-repositorios-librerias-sistemas.md) | Aceptado | arquitectura |
22
+ | A-010 | [Propiedad de la emisión de eventos de dominio](./A-010-propiedad-emision-eventos-dominio.md) | Aceptado | arquitectura, eventos |
23
+ | A-029 | [Verbos de intención para métodos del lado del negocio](./A-029-verbos-intencion-metodos-lado-negocio.md) | Aceptado | dominio |
24
+ | A-031 | [Lenguaje ubicuo](./A-031-ubiquitous-language.md) | Aceptado | dominio, agentes |
25
+ | A-050 | [El caso de uso habla en términos del dominio, no lee ni retorna su representación serializada](./A-050-el-caso-de-uso-pide-al-dominio-no-lee-su-representacion.md) | Aceptado | arquitectura, dominio |
26
+ | A-053 | [Errores compartidos entre features: dos hogares por capa](./A-053-errores-compartidos-entre-features-dos-hogares-por-capa.md) | Aceptado | arquitectura, dominio |
27
+ | A-054 | [Contrato de la costura del driver port: raw data y canal de error](./A-054-contrato-costura-driver-port-raw-data-canal-error.md) | Aceptado | arquitectura |
28
+
29
+ ## Desarrollo y Calidad
30
+
31
+ Cómo se escribe, se prueba y se completa el código: TDD, convenciones de escritura y criterios de calidad que rigen el ciclo de desarrollo.
32
+
33
+ | # | Título | Estado | Etiquetas |
34
+ |---|--------|--------|-----------|
35
+ | A-003 | [Desarrollo basado en pruebas (TDD)](./A-003-tdd.md) | Aceptado | testing |
36
+ | A-005 | [Métodos del lado del negocio retornan `Result` (Either)](./A-005-either-return-custom-methods.md) | Aceptado | dominio |
37
+ | A-006 | [Criterios de completitud de artefactos de dominio y features (definition of done)](./A-006-feature-completion-criteria.md) | Aceptado | testing |
38
+ | A-007 | [Contrato de datos: fallo en origen, sin fallbacks silenciosos](./A-007-data-contract-fail-fast.md) | Aceptado | testing |
39
+ | A-011 | [Refactoring con characterization tests](./A-011-characterization-first-refactoring.md) | Aceptado | testing |
40
+ | A-044 | [Composición funcional de procesos y operaciones](./A-044-composicion-funcional-procesos-operaciones.md) | Aceptado | arquitectura |
41
+ | A-046 | [Métricas de forma y legibilidad del código](./A-046-metricas-de-forma-y-legibilidad-del-codigo.md) | Aceptado | arquitectura |
42
+ | A-047 | [Dependencias explícitas: sin globales ambientales](./A-047-dependencias-explicitas-sin-globales-ambientales.md) | Aceptado | arquitectura |
43
+ | A-048 | [Cobertura mínima de código](./A-048-cobertura-minima-codigo.md) | Aceptado | testing |
44
+ | A-051 | [Orden de imports por distancia al archivo](./A-051-orden-imports-por-distancia.md) | Aceptado | arquitectura, tooling |
45
+
46
+ ## Despliegue
47
+
48
+ Cómo se empaqueta y despliega una aplicación: Helm, configuración, eventos, CI/CD, imágenes Docker y el entorno estandarizado.
49
+
50
+ | # | Título | Estado | Etiquetas |
51
+ |---|--------|--------|-----------|
52
+ | A-012 | [Helm como mecanismo primario de despliegue para aplicaciones servidor](./A-012-helm-mecanismo-primario-despliegue.md) | Aceptado | despliegue |
53
+ | A-019 | [Convenciones de autoría de Helm charts](./A-019-convenciones-autoria-helm-charts.md) | Aceptado | despliegue |
54
+ | A-013 | [Contrato de settings como única fuente de configuración de la aplicación](./A-013-contrato-settings-unica-fuente-configuracion.md) | Aceptado | configuracion |
55
+ | A-014 | [Generación de artefactos de despliegue desde el contrato de settings](./A-014-generacion-artefactos-despliegue-desde-contrato-settings.md) | Aceptado | despliegue, configuracion |
56
+ | A-015 | [CloudEvents como estándar de eventos](./A-015-cloudevents-estandar-eventos.md) | Aceptado | eventos |
57
+ | A-016 | [CI/CD con GitLab: pipeline raíz y pipelines modulares por app](./A-016-cicd-gitlab-pipeline-raiz-pipelines-modulares.md) | Aceptado | despliegue, tooling |
58
+ | A-018 | [Prácticas de build de imágenes Docker](./A-018-practicas-build-imagenes-docker.md) | Aceptado | despliegue |
59
+ | A-020 | [Entorno de desarrollo estandarizado con DevContainer](./A-020-entorno-desarrollo-estandarizado-devcontainer.md) | Aceptado | tooling |
60
+
61
+ ## Herramientas
62
+
63
+ Formatos, estándares y herramientas transversales del flujo de trabajo: el vocabulario de etiquetas de los ADRs, el reporte de tests, el toolchain global, la documentación de artefactos, los mensajes de commit y las ramas.
64
+
65
+ | # | Título | Estado | Etiquetas |
66
+ |---|--------|--------|-----------|
67
+ | A-043 | [Vocabulario de etiquetas de los ADRs](./A-043-vocabulario-etiquetas-adrs.md) | Aceptado | tooling |
68
+ | A-022 | [Formato de reporte de tests (CTRF)](./A-022-formato-reporte-tests-ctrf.md) | Aceptado | testing, tooling |
69
+ | A-030 | [Herramientas de desarrollo globales](./A-030-global-development-tooling.md) | Aceptado | tooling, agentes |
70
+ | A-032 | [Formato de documentación de artefactos de dominio y features](./A-032-domain-artifact-documentation-format.md) | Aceptado | dominio, tooling |
71
+ | A-033 | [Estándar de mensajes de commit](./A-033-estandar-mensajes-commit.md) | Aceptado | tooling, agentes |
72
+ | A-041 | [Estrategia de ramas del repositorio](./A-041-estrategia-de-ramas.md) | Aceptado | tooling, despliegue |
73
+
74
+ ## Flujo de agentes
75
+
76
+ El flujo de trabajo del agente de codificación sobre el issue tracker: el conjunto canónico de skills, la convención de referenciarlos por nombre, la captura de ideas, wayfinder, la taxonomía de labels, el pipeline ship, los punteros de configuración del repo y el formato de los documentos.
77
+
78
+ | # | Título | Estado | Etiquetas |
79
+ |---|--------|--------|-----------|
80
+ | A-034 | [Conjunto canónico de skills del asistente de codificación](./A-034-canonical-skill-set.md) | Aceptado | agentes, tooling |
81
+ | A-038 | [Los issues referencian los skills relevantes por nombre](./A-038-issues-referencian-skills-nombre.md) | Aceptado | agentes, tooling |
82
+ | A-035 | [Captura de ideas y re-anclaje de candies al flujo de agentes](./A-035-captura-ideas-reanclaje-candies.md) | Aceptado | agentes, tooling |
83
+ | A-036 | [Wayfinding y ortogonalidad de labels del issue tracker](./A-036-adopcion-wayfinder-ortogonalidad-labels.md) | Aceptado | agentes, tooling |
84
+ | A-037 | [Formalización de la taxonomía de labels del issue tracker](./A-037-formalizacion-taxonomia-labels.md) | Aceptado | agentes, tooling |
85
+ | A-039 | [Pipeline ship para implementar los issues hijos de un spec](./A-039-pipeline-ship-issues-hijos-spec.md) | Aceptado | agentes, tooling |
86
+ | A-040 | [Punteros de configuración del repositorio para los skills](./A-040-punteros-configuracion-repo-skills.md) | Reemplazado | agentes, tooling |
87
+ | A-042 | [Formato de los documentos del issue tracker](./A-042-formato-documentos-issue-tracker.md) | Aceptado | agentes, tooling |
88
+ | A-045 | [Guardrails aplicables, no directrices](./A-045-guardrails-aplicables-no-directrices.md) | Aceptado | agentes, tooling |
89
+ | A-049 | [Materialización del bucle de guardrails como extensión nativa del agente pi](./A-049-materializacion-bucle-guardrails-extension-nativa-pi.md) | Aceptado | agentes, tooling |
90
+ | A-052 | [Distribución de la metodología como paquete versionado](./A-052-distribucion-metodologia-paquete-versionado.md) | Aceptado | agentes, tooling |
91
+
92
+ ## Desarrollo de agentes
93
+
94
+ Estándares para construir los colaboradores LLM que un proyecto invoca: la composición de sus prompts en bloques. Aplica solo a los proyectos que desarrollan agentes.
95
+
96
+ | # | Título | Estado | Etiquetas |
97
+ |---|--------|--------|-----------|
98
+ | A-023 | [Estándar de composición de bloques de prompt para agentes](./A-023-composicion-bloques-prompt-agentes.md) | Aceptado | agentes, tooling |
@@ -0,0 +1,19 @@
1
+ # Architecture Decision Records (ADR)
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 proyecto que adopta la metodología añade su propio tier de proyecto con sus decisiones de dominio; el tier G de Guarura fue un ejemplo de tier de proyecto y no forma parte de la metodología distribuida ([A-052](./foundational/A-052-distribucion-metodologia-paquete-versionado.md)).
4
+
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
+
7
+ ## Tiers
8
+
9
+ Los ADRs de metodología se organizan en tres tiers según su alcance. La jerarquía completa (reglas de referencia, numeración y gate) está en [ADR-0000](./ADR-0000-proceso-y-formato-de-adrs.md).
10
+
11
+ - **Fundacional (A)** — [`foundational/index.md`](./foundational/index.md): decisiones metodológicas agnósticas al lenguaje (Clean Architecture, TDD, comandos y consultas, DDD).
12
+ - **TypeScript (T)** — [`typescript/index.md`](./typescript/index.md): decisiones específicas del ecosistema TypeScript/Zod/Node.js.
13
+ - **Python (P)** — [`python/index.md`](./python/index.md): decisiones específicas del ecosistema Python (FastAPI, SQLAlchemy, Pydantic).
14
+
15
+ Cada repositorio consumidor mantiene su propio **tier de proyecto** con sus decisiones de dominio, fuera de los tres tiers de metodología.
16
+
17
+ ## Formato
18
+
19
+ Cada ADR sigue el formato de Michael Nygard (Contexto, Decisión, Consecuencias) con el frontmatter del proyecto. El detalle completo del formato, la jerarquía, el gate y el ciclo de vida está en [ADR-0000](./ADR-0000-proceso-y-formato-de-adrs.md). El vocabulario de etiquetas vive en [A-043](./foundational/A-043-vocabulario-etiquetas-adrs.md).
@@ -0,0 +1,63 @@
1
+ # P-001: Dependencias por feature con FastAPI Depends
2
+
3
+ **Estado**: Aceptado
4
+
5
+ **Fecha**: 2026-08-13
6
+
7
+ **originally**: cortex-005
8
+
9
+ **Enriquecido desde**: Cortex ADR 005 — Dependency providers with FastAPI Depends
10
+
11
+ ## Contexto
12
+
13
+ Cada feature de una API en Python necesita resolver sus dependencias en cada request. Algunas son **compartidas** por todas las features — cliente de IA, estado de sesión, usuario autenticado — y otras son **específicas** de una feature — almacenamiento de objetos, búsqueda vectorial, puertos de un dominio concreto.
14
+
15
+ Montar esas dependencias a mano en cada handler genera duplicación y ciclos de vida inconsistentes: un endpoint las inicializa en un orden y otro en otro, y no queda clara cuál es la fuente canónica de cada servicio.
16
+
17
+ ## Decisión
18
+
19
+ Usar el sistema de inyección de dependencias de FastAPI, `Depends()`, con **dos capas**.
20
+
21
+ ### 1. Dependencias conocidas (compartidas)
22
+
23
+ Una función proveedora única agrupa las dependencias que todas las features comparten. Recibe por `Depends()` cada proveedor individual y retorna un contenedor (un dataclass) con las dependencias ya resueltas:
24
+
25
+ ```python
26
+ def known_deps_provider(
27
+ ai_client = Depends(ai_client_provider),
28
+ session_state = Depends(session_state_provider),
29
+ current_user = Depends(current_user_provider),
30
+ ) -> KnownDependencies:
31
+ return KnownDependencies(
32
+ ai_client=ai_client,
33
+ session_state=session_state,
34
+ current_user=current_user,
35
+ )
36
+ ```
37
+
38
+ ### 2. Dependencias custom (por feature)
39
+
40
+ Cada feature declara su propia función `*_deps`, que recibe el contenedor de dependencias conocidas y retorna los servicios adicionales que esa feature necesita:
41
+
42
+ ```python
43
+ def generate_blueprint_deps(known: KnownDependencies) -> dict:
44
+ return {
45
+ "object_storage": object_storage_service,
46
+ "vector_search": vector_search_service,
47
+ }
48
+ ```
49
+
50
+ Ambas capas se inyectan al construir el router y quedan disponibles en el contexto del request.
51
+
52
+ ## Consecuencias
53
+
54
+ ### Positivas
55
+
56
+ - **Declarativo por feature**: cada feature pide solo lo que necesita; no hay una "sopa global" de dependencias.
57
+ - **Resolución per-request**: FastAPI resuelve la cadena de `Depends()` de forma perezosa en cada request.
58
+ - **Testeable**: ambas capas son funciones que se pueden sustituir en tests.
59
+
60
+ ### Negativas
61
+
62
+ - **Grafo implícito**: hay que seguir la cadena de `Depends()` para entender el orden de inicialización.
63
+ - **Contenedor único**: agregar una dependencia conocida nueva toca el contenedor compartido y, por lo tanto, a todas las features.
@@ -0,0 +1,35 @@
1
+ # P-002: Inyección de token por request sin persistirlo
2
+
3
+ **Estado**: Aceptado
4
+
5
+ **Fecha**: 2026-08-13
6
+
7
+ **originally**: cortex-003
8
+
9
+ **Enriquecido desde**: Cortex ADR 003 — Per-request token injection (never stored)
10
+
11
+ ## Contexto
12
+
13
+ Una API necesita autenticarse contra un servicio externo (por ejemplo, un ACL que resguarda archivos y tareas) usando un token que pertenece a cada tenant. Guardar ese token en variables de entorno o en el contrato de settings acoplaría la aplicación al token de un tenant concreto y crearía un riesgo de seguridad si la aplicación se ve comprometida.
14
+
15
+ ## Decisión
16
+
17
+ - Los tokens se pasan **por request** mediante una cabecera HTTP dedicada (por ejemplo `X-<Proveedor>-Token`).
18
+ - La aplicación **nunca persiste** el token: crea un cliente acotado al lifetime del request y lo descarta al terminar.
19
+ - Si la cabecera falta, el endpoint responde `401 Unauthorized`.
20
+ - El contrato de settings **excluye explícitamente** cualquier campo de token: las credenciales por tenant no son configuración de la aplicación ([A-013](../foundational/A-013-contrato-settings-unica-fuente-configuracion.md)).
21
+
22
+ Los procesos en background que no tienen contexto HTTP (workers, jobs) siguen el mismo principio, pero usan variables de entorno porque no existe un request al que asociar el token.
23
+
24
+ ## Consecuencias
25
+
26
+ ### Positivas
27
+
28
+ - **Multi-tenant**: una única instancia puede servir a varios tenants, cada uno con su propio token.
29
+ - **Seguridad**: un proceso comprometido no tiene tokens de larga vida que exfiltrar.
30
+ - **Stateless**: no se necesita afinidad de sesión para almacenar tokens.
31
+
32
+ ### Negativas
33
+
34
+ - **Carga para el llamador**: cada request debe incluir la cabecera; el gateway o el cliente lo asumen.
35
+ - **Validación diferida**: el token no se valida en el ingreso del request, sino en la primera llamada al servicio externo.