@devrik-tools/claude-gates 0.8.0 → 1.0.0

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 (34) hide show
  1. package/.claude-plugin/marketplace.json +3 -3
  2. package/README.es.md +102 -9
  3. package/README.md +93 -9
  4. package/cli/artifacts.mjs +213 -0
  5. package/cli/constants.mjs +14 -0
  6. package/cli/doctor.mjs +2 -1
  7. package/cli/index.mjs +54 -2
  8. package/cli/init.mjs +95 -9
  9. package/cli/install.mjs +53 -1
  10. package/cli/registry.mjs +2 -0
  11. package/cli/selection.mjs +23 -1
  12. package/cli/smoke-fixtures.json +53 -3
  13. package/cli/task.mjs +69 -4
  14. package/package.json +5 -4
  15. package/plugins/gates/.claude-plugin/plugin.json +1 -1
  16. package/plugins/gates/hooks/gates/capability-map/index.mjs +37 -208
  17. package/plugins/gates/hooks/gates/circuit-breaker/index.mjs +4 -11
  18. package/plugins/gates/hooks/gates/circuit-breaker/track.mjs +285 -0
  19. package/plugins/gates/hooks/gates/force-parallel/index.mjs +11 -12
  20. package/plugins/gates/hooks/gates/library-docs/index.mjs +107 -31
  21. package/plugins/gates/hooks/gates/no-trivial-scripts/index.mjs +114 -0
  22. package/plugins/gates/hooks/gates/require-monitor/index.mjs +126 -0
  23. package/plugins/gates/hooks/gates/require-task-split/index.mjs +88 -0
  24. package/plugins/gates/hooks/gates/skill-first/index.mjs +138 -0
  25. package/plugins/gates/hooks/gates/skill-first/track.mjs +66 -0
  26. package/plugins/gates/hooks/hooks.json +61 -1
  27. package/plugins/gates/hooks/lib/capabilities.mjs +401 -0
  28. package/plugins/gates/hooks/lib/hook-io.mjs +9 -2
  29. package/plugins/gates/hooks/lib/signals.mjs +91 -0
  30. package/plugins/gates/hooks/lib/testing.mjs +15 -4
  31. package/plugins/tasks/.claude-plugin/plugin.json +1 -1
  32. package/plugins/tasks/hooks/lib/task-store.mjs +6 -0
  33. package/plugins/tasks/hooks/register-requests.mjs +37 -10
  34. package/registry.json +106 -5
@@ -4,20 +4,20 @@
4
4
  "name": "claude-gates"
5
5
  },
6
6
  "metadata": {
7
- "description": "Installable deterministic gates (hooks) for Claude Code, selectable per project or globally with `npx @devrik99/claude-gates init`."
7
+ "description": "Installable deterministic gates (hooks) for Claude Code, selectable per project or globally with `npx @devrik-tools/claude-gates init`."
8
8
  },
9
9
  "plugins": [
10
10
  {
11
11
  "name": "gates",
12
12
  "source": "./plugins/gates",
13
13
  "description": "PreToolUse gates: destructive-command blocks, protected paths, delegation/spec/quality rules, tool-discovery and forge-pipeline enforcement. Which gates run is decided by .ai/config.json (project) or ~/.claude/claude-gates/config.json (global).",
14
- "version": "0.8.0"
14
+ "version": "0.9.0"
15
15
  },
16
16
  {
17
17
  "name": "tasks",
18
18
  "source": "./plugins/tasks",
19
19
  "description": "Deterministic task tracking: the model registers tasks via the CLI, a UserPromptSubmit hook reminds of open tasks every few messages, and a SessionStart hook lists active tasks when a session opens.",
20
- "version": "0.8.0"
20
+ "version": "0.9.0"
21
21
  }
22
22
  ]
23
23
  }
package/README.es.md CHANGED
@@ -30,7 +30,7 @@ npx @devrik-tools/claude-gates init
30
30
 
31
31
  Reinicia la sesión de Claude Code (o ejecuta `/plugin`) para que los hooks carguen.
32
32
 
33
- > **¿Por qué dos cosas?** El plugin **siempre trae los 44 gates**; la configuración decide
33
+ > **¿Por qué dos cosas?** El plugin **siempre trae los 50 gates**; la configuración decide
34
34
  > **cuáles se ejecutan**. Así puedes prender uno sin reinstalar: es una línea en un JSON.
35
35
 
36
36
  ---
@@ -67,7 +67,7 @@ ejecución), así que funciona aunque instales uno suelto por fuera.
67
67
 
68
68
  ---
69
69
 
70
- ## Los gates (44, en 10 familias)
70
+ ## Los gates (50, en 11 familias)
71
71
 
72
72
  `[on]` = encendidos por defecto; `[off]` = los prendes si los quieres.
73
73
 
@@ -79,6 +79,7 @@ ejecución), así que funciona aunque instales uno suelto por fuera.
79
79
  | `protected-paths` | on | Bloquea escrituras a `.env`, lockfiles y el propio harness. |
80
80
  | `root-whitelist` | on | Bloquea crear archivos/carpetas nuevos en la raíz fuera de la lista blanca. |
81
81
  | `no-blocking` | off | Bloquea `sleep`, `tail -f`, bucles de sondeo y servidores en primer plano. |
82
+ | `require-monitor` | on | Bloquea un comando en background (`run_in_background: true`) que no declara su monitor con el marcador `MONITOR-PLANNED:`, y bloquea cualquier ejecución posterior mientras quede un background sin monitorear. |
82
83
 
83
84
  ### 🤝 Delegation — exigencias sobre el brief al delegar a un subagente
84
85
  | Gate | | Qué hace |
@@ -88,6 +89,7 @@ ejecución), así que funciona aunque instales uno suelto por fuera.
88
89
  | `risk-level` | off | Exige declarar el nivel (QUESTION/MICRO/STANDARD/HIGH-RISK). |
89
90
  | `circuit-breaker` | off | Corta la misma delegación reintentada sin cambios reales. |
90
91
  | `no-memory-dependency` | off | Bloquea un brief que depende de que el subagente "recuerde" la conversación (marcador `memory-not-needed` para un falso positivo). |
92
+ | `force-parallel` | on | Bloquea la enésima delegación secuencial consecutiva dentro de una ventana de tiempo: las delegaciones independientes se lanzan juntas en un solo mensaje (marcador `SEQUENTIAL-JUSTIFIED` cuando la segunda depende de verdad de la primera). |
91
93
 
92
94
  ### 📋 Spec-driven flow — solo aplican si el proyecto adoptó desarrollo por specs
93
95
  | Gate | | Qué hace |
@@ -118,12 +120,14 @@ ejecución), así que funciona aunque instales uno suelto por fuera.
118
120
  | `no-coauthor` | on | Bloquea un `git commit` que lleve un trailer de atribución de IA (`Co-Authored-By`, `Generated with`, un trailer de sesión). Marcador `[allow-coauthor]` para un co-autor legítimo. |
119
121
  | `no-lint-suppression` | on | Bloquea una escritura que silencia el linter/type-checker (`eslint-disable`, `@ts-ignore`, una regla en `off`) en vez de arreglar el código. Marcador `lint-ok: <razón>` en la misma línea para un falso positivo documentado. |
120
122
  | `no-explanatory-comments` | on | Bloquea una escritura de código que agrega comentarios que narran qué hace el código. Solo pasan comentarios de decisión (el porqué, un trade-off, una limitación), directivas de herramientas, `TODO`/`FIXME` y etiquetas JSDoc con tipo. Juzga solo comentarios nuevos (diff contra disco). `comment-ok: <razón>` para una excepción documentada. |
123
+ | `no-trivial-scripts` | on | Bloquea un script inline de intérprete que hace una operación de archivos que las herramientas `Edit`/`Write` resuelven directo (`node -e` con `writeFileSync`, `python -c` con `open(…, 'w')`, `sed -i`, `perl -i`, `Set-Content`/`Add-Content`). Los scripts inline que solo computan no caen. |
121
124
 
122
125
  ### 🔎 Tool discovery — no reinventar la rueda
123
126
  | Gate | | Qué hace |
124
127
  |---|---|---|
125
128
  | `reuse-before-build` | off | Antes de construir una herramienta, consulta el mapa de herramientas del proyecto; bloquea si no auditaste (local → Context7 → web). |
126
129
  | `tool-map` | off | Registra las herramientas descubiertas en `.ai/tool-map.json` para no volver a explorar. |
130
+ | `skill-first` | off | Bloquea una escritura/comando/delegación que una **skill** disponible cubre de forma plausible hasta que la pregunta se haya hecho: cargar la skill, o decir por qué no aplica (`no skill covers this` / `using the <name> skill`). Lee el mismo catálogo que inyecta `capability-map`. |
127
131
 
128
132
  ### 🧠 Research flow — la memoria primero, nunca adivinar una librería
129
133
 
@@ -137,6 +141,26 @@ ejecución), así que funciona aunque instales uno suelto por fuera.
137
141
  |---|---|---|
138
142
  | `forge-flow` | off | En un proyecto que adoptó [forge](https://github.com/DevRik99/forge-mcp), bloquea editar/ejecutar si no hay un run de forge activo. Cierra el hueco que el MCP no puede: te obliga a pasar por el pipeline. |
139
143
 
144
+ ### 🤖 Autonomy — que una corrida sin supervisión decida en vez de preguntar
145
+
146
+ | Gate | | Qué hace |
147
+ |---|---|---|
148
+ | `autonomous-mode` | off | Con el modo autónomo prendido, bloquea `AskUserQuestion` y bloquea que el turno termine solo para esperar: reinyecta, una vez por ciclo, la instrucción de decidir y seguir, dejando pendiente solo lo que de verdad necesita al usuario. |
149
+
150
+ ### ⏹️ Completion — el turno no termina con trabajo abierto
151
+
152
+ | Gate | | Qué hace |
153
+ |---|---|---|
154
+ | `stop-pending` | on | Bloquea el evento Stop mientras el proyecto tiene tareas activas (`open`/`in_forge`); las lista y explica cómo cerrarlas con evidencia verificada o abandonarlas. Las tareas `blocked` no retienen el turno por defecto. |
155
+ | `require-task-split` | on | Bloquea escrituras y ejecución mientras una tarea activa más grande que `small` no tenga sub-tareas registradas: primero se parte en piezas verificables por separado (`task add --parent <id>`). |
156
+
157
+ ### 🗂️ Task tracking — el plugin de tareas
158
+
159
+ | Gate | | Qué hace |
160
+ |---|---|---|
161
+ | `remind-open-tasks` | on | Hace que el asistente clasifique y registre el trabajo nuevo por el CLI, y recita las tareas activas cada N mensajes. |
162
+ | `list-tasks-on-session-start` | on | Lista las tareas activas del proyecto al abrir una sesión. Silencioso si no hay ninguna. |
163
+
140
164
  ### 🩺 Sesión y contexto — validaciones al arrancar e inyección de capacidades
141
165
  | Gate | | Qué hace |
142
166
  |---|---|---|
@@ -160,7 +184,7 @@ ves y editas cada perilla:
160
184
  ```json
161
185
  {
162
186
  "adopted": "partial",
163
- "gateVersion": "3.0.0",
187
+ "gateVersion": "3.1.0",
164
188
  "gates": {
165
189
  "blockDestructiveShellCommands": {
166
190
  "enabled": true,
@@ -194,12 +218,17 @@ ves y editas cada perilla:
194
218
  commit), `lint-ok: <razón>` (un falso positivo documentado del linter), `[skip-lint]`
195
219
  (saltea el chequeo de staged-lint por un commit), `[wip]` (permite un commit
196
220
  deliberadamente amplio, no atómico), `comment-ok: <razón>` (un comentario explicativo que
197
- debe quedarse). `dependency-skills` se exime vía su lista `depsWithoutOwnApi`.
221
+ debe quedarse), `SEQUENTIAL-JUSTIFIED` (una delegación que depende de la anterior),
222
+ `MONITOR-PLANNED:` (el comando en background declara cómo se va a monitorear).
223
+ `dependency-skills` se exime vía su lista `depsWithoutOwnApi`. `skill-first` se despeja
224
+ con una frase en el contenido/prompt: `no skill covers this`, o `using the <name> skill`.
198
225
  - **Inyección de capacidades:** `capability-map` (on por defecto) es totalmente ajustable —
199
226
  elegí qué tipos exponer (`"kinds": ["skills", "agents", "commands"]`), limitá cada blurb
200
227
  (`maxClauseChars`, default 120), agregá raíces extra por tipo, regulá cada cuánto se
201
228
  re-inyecta el catálogo completo (`injectEveryMessages`, default 10 — el archivo persistido
202
- se refresca igual en cada mensaje), o apagá la persistencia (`"persist": false`) y apuntá
229
+ se refresca igual en cada mensaje; el catálogo TAMBIÉN se re-inyecta a mitad del throttle
230
+ cuando cambia el tipo de trabajo del prompt, por ejemplo depurar → publicar, lo que podés
231
+ apagar con `"reinjectOnWorkNatureChange": false`), o apagá la persistencia (`"persist": false`) y apuntá
203
232
  el mapa a otro archivo (`mapFile`). Las skills también se escanean por defecto en
204
233
  `~/.agents/skills`, `<proyecto>/.agents/skills`, `~/.ai/skills` y `<proyecto>/.ai/skills`
205
234
  (raíces exclusivas de skills que usan otros instaladores además de `.claude/skills` — sin
@@ -231,17 +260,33 @@ El archivo rota una vez a los 5 MB (`gates-log.1.jsonl`). `CLAUDE_GATES_LOG=0` l
231
260
 
232
261
  ---
233
262
 
234
- ## Tareas: cerrar exige evidencia verificada
263
+ ## Tareas: se registran con criterio y se cierran con evidencia verificada
235
264
 
236
- `task close` rechaza texto libre. Una tarea está hecha solo cuando una verificación pasa:
265
+ Una tarea lleva su criterio de verificación **desde que se crea** `task add` rechaza una
266
+ tarea que nadie puede probar terminada — y `task close` rechaza texto libre: está hecha solo
267
+ cuando la verificación pasa de verdad.
237
268
 
238
269
  ```bash
270
+ # Registrar: el criterio es obligatorio (--verify-command o --verify-path)
271
+ claude-gates task add "migrar el cargador de configuración" \
272
+ --size medium --verify-command "npm test" --verify-expect "fail 0"
273
+ claude-gates task add "escribir la guía de migración" \
274
+ --parent <id> --verify-path docs/migration.md --verify-contains "## Upgrading"
275
+
276
+ claude-gates task list [--all] # tareas activas (o todo el historial)
277
+
278
+ # Cerrar: sin --check/--exists, se vuelve a correr el criterio propio de la tarea
279
+ claude-gates task close <id>
239
280
  claude-gates task close <id> --check "npm test" --expect "fail 0" --note "suite en verde"
240
281
  claude-gates task close <id> --exists dist/report.html --contains "All green"
241
282
  claude-gates task abandon <id> --reason "obsoleta"
283
+ claude-gates task promote <id> <runId> # vincula la tarea a un run de forge
242
284
  ```
243
285
 
244
- El resultado verificado (comando, código de salida, cola de la salida, fecha) queda guardado con la tarea.
286
+ El resultado verificado (comando, código de salida, cola de la salida, fecha) queda guardado
287
+ con la tarea. Dos gates se apoyan en este store: `require-task-split` bloquea implementar una
288
+ tarea más grande que `small` sin sub-tareas, y `stop-pending` impide que el turno termine
289
+ mientras queden tareas abiertas.
245
290
 
246
291
  ---
247
292
 
@@ -253,6 +298,8 @@ npx @devrik-tools/claude-gates init
253
298
 
254
299
  # Sin menú (para CI o scripts):
255
300
  claude-gates init --project|--global --defaults|--all|--none|--families a,b|--gates x,y --yes --dry-run
301
+ claude-gates init --new # SOLO los gates sobre los que esta config nunca decidió:
302
+ # actualizás sin volver a contestar ni tocar lo ya definido
256
303
  claude-gates init --no-install # escribe la configuración pero no instala el plugin
257
304
  claude-gates init --force # aplica cambios a gates ya presentes sin preguntar
258
305
 
@@ -263,12 +310,57 @@ claude-gates status # on/off efectivo por gate y su origen (pr
263
310
  claude-gates log [--tail N] [--deny] [--gate id] [--since iso] [--json]
264
311
  claude-gates doctor # ¿Claude Code corre ESTA versión del paquete?
265
312
 
313
+ # Tareas (el store que leen los gates de completion):
314
+ claude-gates task add <título> --size <tamaño> --verify-command <cmd>|--verify-path <ruta> [--parent <id>]
315
+ claude-gates task list [--all]
316
+ claude-gates task close <id> [--check <cmd> --expect <texto>] [--exists <ruta> --contains <texto>]
317
+ claude-gates task abandon <id> --reason <texto>
318
+ claude-gates task promote <id> <runId>
319
+
266
320
  # Inspeccionar el catálogo:
267
321
  claude-gates registry --list # lista familias y gates
268
322
  claude-gates registry --check # valida registry.json y que hooks.json esté sincronizado
269
323
  claude-gates registry --sync-hooks # regenera el hooks.json de cada plugin desde el registry
324
+
325
+ # Verificar que los gates realmente reaccionan (no solo que están enganchados):
326
+ claude-gates smoke # le da a cada gate una violación conocida; sale distinto de 0 si alguno no bloquea/avisa
270
327
  ```
271
328
 
329
+ `smoke` es el chequeo de comportamiento que `registry --check` (estructura) y el hook doctor
330
+ (que los archivos existan) no hacen: le da a cada gate una violación conocida y confirma que
331
+ de verdad deniega o avisa. Los gates cuya violación necesita estado sembrado (una db, un repo
332
+ git, estado entre llamadas) reportan `skip`, nunca un falso pase. Se corre después de
333
+ instalar, o en CI, para detectar un gate enganchado que en silencio deja pasar todo.
334
+
335
+ ---
336
+
337
+ ## Artefactos generados
338
+
339
+ Todo lo que un agente produce que **no es código fuente** — un chequeo determinista que
340
+ escribió para que veas si algo funciona, una auditoría de lo que ya existe, una nota
341
+ explicando qué hizo — tiene una sola forma y un solo lugar, así se encuentra por convención
342
+ y se valida en CI en vez de caer donde al modelo se le ocurra.
343
+
344
+ ```bash
345
+ claude-gates new check mi-afirmacion --title "..." --source "qué pidió esto"
346
+ ```
347
+
348
+ | Tipo | Vive en | Para |
349
+ | ------- | ------------- | ---------------------------------------------------------------------- |
350
+ | `check` | `.ai/checks/` | Una afirmación verificable: el comando, qué debe imprimir, y la evidencia que realmente imprimió. |
351
+ | `audit` | `.ai/audits/` | Mirar antes de construir: buscado / existe / falta / decisión. |
352
+ | `note` | `.ai/notes/` | Razonamiento que si no quedaría solo en el chat. |
353
+
354
+ Cuando la misma cosa sale mal dos veces, el registro es dato y no documento: se anota la
355
+ **clase** de defecto en `.ai/reincidencias.json`, que `recurrence-lock` lee para bloquear
356
+ trabajo mutante hasta que la clase se cierre de raíz.
357
+
358
+ El contrato es `cli/artifacts.mjs`; las reglas completas están en
359
+ [`.ai/README.md`](./.ai/README.md). Dos tests lo sostienen — uno cubre el módulo, el otro
360
+ recorre el árbol `.ai/` real de este repo y falla ante cualquier artefacto desviado (sin
361
+ front matter, en el directorio equivocado, sin una sección obligatoria, o un check marcado
362
+ `passed` cuya evidencia sigue siendo el placeholder generado).
363
+
272
364
  ---
273
365
 
274
366
  ## Estructura del repositorio
@@ -285,7 +377,8 @@ plugins/gates/ El plugin de gates.
285
377
  hooks/hooks.json Generado desde registry.json (`registry --sync-hooks`). Lo carga Claude Code.
286
378
  hooks/lib/ Código compartido de los hooks (Node built-ins only).
287
379
  hooks/gates/<id>/ Un gate por carpeta: index.mjs (la regla) + test.mjs (su test).
288
- plugins/tasks/ El plugin de tareas (en construcción): persiste tareas por proyecto.
380
+ plugins/tasks/ El plugin de tareas: persiste tareas por proyecto, recuerda las abiertas
381
+ y las lista al arrancar la sesión.
289
382
  .claude-plugin/marketplace.json Lista los plugins del marketplace.
290
383
  ```
291
384
 
package/README.md CHANGED
@@ -29,7 +29,7 @@ npx @devrik-tools/claude-gates init
29
29
 
30
30
  Restart the Claude Code session (or run `/plugin`) so the hooks load.
31
31
 
32
- > **Why two things?** The plugin **always ships all 44 gates**; the config decides **which
32
+ > **Why two things?** The plugin **always ships all 50 gates**; the config decides **which
33
33
  > ones run**. So you can turn one on without reinstalling — it is one line in a JSON file.
34
34
 
35
35
  ---
@@ -65,7 +65,7 @@ works even if you install one on its own.
65
65
 
66
66
  ---
67
67
 
68
- ## The gates (in families)
68
+ ## The gates (50, in 11 families)
69
69
 
70
70
  `[on]` = enabled by default; `[off]` = enable it if you want it.
71
71
 
@@ -78,6 +78,7 @@ works even if you install one on its own.
78
78
  | `protected-paths` | on | Blocks writes to `.env`, lockfiles and the harness itself. |
79
79
  | `root-whitelist` | on | Blocks new root-level files/folders outside a whitelist. |
80
80
  | `no-blocking` | off | Blocks `sleep`, `tail -f`, polling loops and foreground servers. |
81
+ | `require-monitor` | on | Blocks a background command (`run_in_background: true`) that does not declare its monitor with a `MONITOR-PLANNED:` marker, and blocks further execution while an unmonitored background command is still pending. |
81
82
 
82
83
  ### 🤝 Delegation — requirements on the brief when delegating to a subagent
83
84
 
@@ -88,6 +89,7 @@ works even if you install one on its own.
88
89
  | `risk-level` | off | Requires a declared level (QUESTION/MICRO/STANDARD/HIGH-RISK). |
89
90
  | `circuit-breaker` | off | Cuts the same delegation retried without real changes. |
90
91
  | `no-memory-dependency` | off | Blocks a brief that relies on the subagent "remembering" the chat (add `memory-not-needed` to allow a false positive). |
92
+ | `force-parallel` | on | Blocks the Nth consecutive sequential delegation inside a time window: independent delegations must be launched together in one message (add `SEQUENTIAL-JUSTIFIED` when the second one really depends on the first). |
91
93
 
92
94
  ### 📋 Spec-driven flow — only relevant if the project adopted spec-driven development
93
95
 
@@ -120,6 +122,7 @@ works even if you install one on its own.
120
122
  | `no-coauthor` | on | Blocks a `git commit` carrying an AI/agent attribution trailer (`Co-Authored-By`, `Generated with`, a session trailer). Add `[allow-coauthor]` for one legitimate co-author. |
121
123
  | `no-lint-suppression` | on | Blocks a write that silences the linter/type-checker (`eslint-disable`, `@ts-ignore`, a rule set to `off`) instead of fixing the code. Add `lint-ok: <reason>` on the same line for a documented false positive. |
122
124
  | `no-explanatory-comments` | on | Blocks a code write that adds comments narrating what the code does. Only decision comments (why, trade-off, limitation), tool directives, `TODO`/`FIXME` and typed JSDoc tags pass. Judges only new comments (diff against disk). Add `comment-ok: <reason>` for a documented exception. |
125
+ | `no-trivial-scripts` | on | Blocks an inline interpreter script that does a file operation the `Edit`/`Write` tool handles directly (`node -e` with `writeFileSync`, `python -c` with `open(…, 'w')`, `sed -i`, `perl -i`, `Set-Content`/`Add-Content`). Inline scripts that only compute are not caught. |
123
126
 
124
127
  ### 🔎 Tool discovery — don't reinvent the wheel
125
128
 
@@ -127,6 +130,7 @@ works even if you install one on its own.
127
130
  | -------------------- | --- | ------------------------------------------------------------------------------------------------------------ |
128
131
  | `reuse-before-build` | off | Before building a tool, consults the project tool map; blocks if you did not audit (local → Context7 → web). |
129
132
  | `tool-map` | off | Records discovered tools in `.ai/tool-map.json` so exploration is not repeated. |
133
+ | `skill-first` | off | Blocks a write/command/delegation an available **skill** plausibly covers until the question was asked: load the skill, or say why it does not fit (`no skill covers this` / `using the <name> skill`). Reads the same catalog `capability-map` injects. |
130
134
 
131
135
  ### 🧠 Research flow — memory first, never guess a library
132
136
 
@@ -141,6 +145,26 @@ works even if you install one on its own.
141
145
  | ------------ | --- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
142
146
  | `forge-flow` | off | In a project that adopted [forge](https://github.com/DevRik99/forge-mcp), blocks editing/running unless an active forge run exists. Closes the hole the MCP cannot: it forces you through the pipeline. |
143
147
 
148
+ ### 🤖 Autonomy — let an unattended run decide instead of asking
149
+
150
+ | Gate | | What it does |
151
+ | ------------------ | --- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
152
+ | `autonomous-mode` | off | With autonomous mode on, blocks `AskUserQuestion` and blocks a turn that ends only to wait: it re-injects, once per cycle, the instruction to decide and proceed, leaving pending only what genuinely needs the user. |
153
+
154
+ ### ⏹️ Completion — a turn does not end with work still open
155
+
156
+ | Gate | | What it does |
157
+ | -------------------- | --- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
158
+ | `stop-pending` | on | Blocks the Stop event while this project has active tasks (`open`/`in_forge`); lists them and how to close them with verified evidence or abandon them. `blocked` tasks don't hold the turn by default. |
159
+ | `require-task-split` | on | Blocks writes and execution while an active task larger than `small` has no sub-tasks registered: split it into independently verifiable pieces first (`task add --parent <id>`). |
160
+
161
+ ### 🗂️ Task tracking — the tasks plugin
162
+
163
+ | Gate | | What it does |
164
+ | ----------------------------- | --- | ---------------------------------------------------------------------------------------------------------- |
165
+ | `remind-open-tasks` | on | Makes the assistant classify and register new work via the CLI, and recites the active tasks every N messages. |
166
+ | `list-tasks-on-session-start` | on | Lists this project's active tasks when a session opens. Silent when there are none. |
167
+
144
168
  ### 🩺 Session & context — startup checks and capability injection
145
169
 
146
170
  | Gate | | What it does |
@@ -165,7 +189,7 @@ see and edit every knob:
165
189
  ```json
166
190
  {
167
191
  "adopted": "partial",
168
- "gateVersion": "3.0.0",
192
+ "gateVersion": "3.1.0",
169
193
  "gates": {
170
194
  "blockDestructiveShellCommands": {
171
195
  "enabled": true,
@@ -206,13 +230,18 @@ see and edit every knob:
206
230
  non-memory phrase), `[allow-coauthor]` (one legitimate co-author on a commit),
207
231
  `lint-ok: <reason>` (a documented linter false positive), `[skip-lint]` (skip the
208
232
  staged-lint check for one commit), `[wip]` (allow one deliberately broad,
209
- non-atomic commit), `comment-ok: <reason>` (one explanatory comment that must stay).
210
- `dependency-skills` opts out via its `depsWithoutOwnApi` list.
233
+ non-atomic commit), `comment-ok: <reason>` (one explanatory comment that must stay),
234
+ `SEQUENTIAL-JUSTIFIED` (a delegation that genuinely depends on the previous one),
235
+ `MONITOR-PLANNED:` (the background command declares how it will be monitored).
236
+ `dependency-skills` opts out via its `depsWithoutOwnApi` list. `skill-first` clears on
237
+ one sentence in the content/prompt: `no skill covers this`, or `using the <name> skill`.
211
238
  - **Capability injection:** `capability-map` (on by default) is fully tunable — pick which
212
239
  kinds to surface (`"kinds": ["skills", "agents", "commands"]`), cap each blurb
213
240
  (`maxClauseChars`, default 120), add extra roots per kind, throttle how often the full
214
241
  catalog is re-injected (`injectEveryMessages`, default 10 — the persisted map file itself
215
- still refreshes every message), or turn off persistence (`"persist": false`) and point the
242
+ still refreshes every message; the catalog is ALSO re-injected mid-throttle whenever the
243
+ prompt's kind of work changes, e.g. debugging → releasing, which you can turn off with
244
+ `"reinjectOnWorkNatureChange": false`), or turn off persistence (`"persist": false`) and point the
216
245
  map file elsewhere (`mapFile`). Skills are also scanned by default under `~/.agents/skills`,
217
246
  `<project>/.agents/skills`, `~/.ai/skills` and `<project>/.ai/skills` (skill-only roots some
218
247
  installers use besides `.claude/skills` — no config needed), in addition to any
@@ -227,6 +256,35 @@ see and edit every knob:
227
256
 
228
257
  ---
229
258
 
259
+ ## Generated artifacts
260
+
261
+ Everything an agent produces that is **not source code** — a deterministic check it wrote
262
+ so you can see whether something works, an audit of what already exists, a note explaining
263
+ what it did — has one shape and one home, so it can be found by convention and validated
264
+ in CI instead of landing wherever the model felt like.
265
+
266
+ ```bash
267
+ claude-gates new check my-claim --title "..." --source "what asked for this"
268
+ ```
269
+
270
+ | Kind | Lives in | For |
271
+ | ------- | ------------- | ------------------------------------------------------------------ |
272
+ | `check` | `.ai/checks/` | One verifiable claim: the command, what it must print, the evidence it actually printed. |
273
+ | `audit` | `.ai/audits/` | Looking before building: searched / exists / missing / decision. |
274
+ | `note` | `.ai/notes/` | Reasoning that would otherwise live only in a chat log. |
275
+
276
+ When the same thing goes wrong twice, the record is data rather than a document: register
277
+ the defect **class** in `.ai/reincidencias.json`, which `recurrence-lock` reads to block
278
+ mutating work until the class is closed at the root.
279
+
280
+ The contract is `cli/artifacts.mjs`; the full rules are in
281
+ [`.ai/README.md`](./.ai/README.md). Two tests keep it honest — one covers the module, the
282
+ other walks this repo's own `.ai/` tree and fails on any artifact that drifted (missing
283
+ front matter, wrong directory, a missing section, or a check marked `passed` whose
284
+ evidence is still the generated placeholder).
285
+
286
+ ---
287
+
230
288
  ## Decision log
231
289
 
232
290
  Every deny, warn and Stop-block is appended as one JSON line to
@@ -243,17 +301,33 @@ The file rotates once at 5 MB (`gates-log.1.jsonl`). Set `CLAUDE_GATES_LOG=0` to
243
301
 
244
302
  ---
245
303
 
246
- ## Tasks: closing needs verified evidence
304
+ ## Tasks: registered with a criterion, closed with verified evidence
247
305
 
248
- `task close` refuses free text. A task is done only when a check passes:
306
+ A task carries its verification criterion **from the moment it is created** `task add`
307
+ refuses a task nobody can prove done — and `task close` refuses free text: it is done only
308
+ when the check actually passes.
249
309
 
250
310
  ```bash
311
+ # Register: the criterion is mandatory (--verify-command or --verify-path)
312
+ claude-gates task add "migrate the config loader" \
313
+ --size medium --verify-command "npm test" --verify-expect "fail 0"
314
+ claude-gates task add "write the migration guide" \
315
+ --parent <id> --verify-path docs/migration.md --verify-contains "## Upgrading"
316
+
317
+ claude-gates task list [--all] # active tasks (or the whole history)
318
+
319
+ # Close: with no --check/--exists, the task's own verify criterion is re-run
320
+ claude-gates task close <id>
251
321
  claude-gates task close <id> --check "npm test" --expect "fail 0" --note "suite green"
252
322
  claude-gates task close <id> --exists dist/report.html --contains "All green"
253
323
  claude-gates task abandon <id> --reason "obsolete"
324
+ claude-gates task promote <id> <runId> # link the task to a forge run
254
325
  ```
255
326
 
256
327
  The verified result (command, exit code, output tail, timestamp) is stored with the task.
328
+ Two gates lean on this store: `require-task-split` blocks implementing a task bigger than
329
+ `small` that has no sub-tasks, and `stop-pending` blocks the turn from ending while tasks
330
+ are still open.
257
331
 
258
332
  ---
259
333
 
@@ -265,6 +339,8 @@ npx @devrik-tools/claude-gates init
265
339
 
266
340
  # Non-interactive (for CI or scripts):
267
341
  claude-gates init --project|--global --defaults|--all|--none|--families a,b|--gates x,y --yes --dry-run
342
+ claude-gates init --new # ONLY gates this config never decided about — upgrade
343
+ # without re-answering or changing anything already set
268
344
  claude-gates init --no-install # write the config but do not install the plugin
269
345
  claude-gates init --force # apply changes to gates already in the file without asking
270
346
 
@@ -275,6 +351,13 @@ claude-gates status # effective on/off per gate and its source
275
351
  claude-gates log [--tail N] [--deny] [--gate id] [--since iso] [--json]
276
352
  claude-gates doctor # is Claude Code running THIS package version of the plugins?
277
353
 
354
+ # Tasks (the store the completion gates read):
355
+ claude-gates task add <title> --size <size> --verify-command <cmd>|--verify-path <path> [--parent <id>]
356
+ claude-gates task list [--all]
357
+ claude-gates task close <id> [--check <cmd> --expect <text>] [--exists <path> --contains <text>]
358
+ claude-gates task abandon <id> --reason <text>
359
+ claude-gates task promote <id> <runId>
360
+
278
361
  # Inspect the catalog:
279
362
  claude-gates registry --list # list families and gates
280
363
  claude-gates registry --check # validate registry.json and that hooks.json is in sync
@@ -306,7 +389,8 @@ plugins/gates/ The gates plugin.
306
389
  hooks/hooks.json Generated from registry.json (`registry --sync-hooks`). Loaded by Claude Code.
307
390
  hooks/lib/ Shared hook code (Node built-ins only).
308
391
  hooks/gates/<id>/ One gate per folder: index.mjs (the rule) + test.mjs (its test).
309
- plugins/tasks/ The tasks plugin (work in progress): persists per-project tasks.
392
+ plugins/tasks/ The tasks plugin: persists per-project tasks, reminds of the open ones
393
+ and lists them on session start.
310
394
  .claude-plugin/marketplace.json Lists the marketplace plugins.
311
395
  ```
312
396