navori 0.11.2 → 0.12.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.
- package/README.md +110 -65
- package/dist/assets/core/core-assets/agents/architect.md +1 -1
- package/dist/assets/core/core-assets/agents/implementer.md +9 -5
- package/dist/assets/core/core-assets/agents/orchestrator.md +7 -5
- package/dist/assets/core/core-assets/agents/publisher.md +37 -46
- package/dist/assets/core/core-assets/agents/reviewer.md +51 -19
- package/dist/assets/core/core-assets/hooks/_partials/audit-arm.sh +7 -4
- package/dist/assets/core/core-assets/hooks/_partials/audit-log.sh +67 -235
- package/dist/assets/core/core-assets/hooks/_partials/audit-signal.sh +1 -1
- package/dist/assets/core/core-assets/hooks/_partials/bash-outcome.sh +54 -12
- package/dist/assets/core/core-assets/hooks/_partials/draft-body.sh +216 -0
- package/dist/assets/core/core-assets/hooks/_partials/gate-ask.sh +11 -1
- package/dist/assets/core/core-assets/hooks/_partials/hook-input.sh +7 -1
- package/dist/assets/core/core-assets/hooks/_partials/inert-skeleton.sh +352 -0
- package/dist/assets/core/core-assets/hooks/_partials/resolve-worktree.sh +5 -4
- package/dist/assets/core/core-assets/hooks/audit-mode-close.sh +11 -4
- package/dist/assets/core/core-assets/hooks/audit-mode-trigger.sh +15 -36
- package/dist/assets/core/core-assets/hooks/comment-draft-confirm.sh +14 -195
- package/dist/assets/core/core-assets/hooks/engram-write-guard.sh +111 -0
- package/dist/assets/core/core-assets/hooks/guard-destructive.sh +308 -341
- package/dist/assets/core/core-assets/hooks/implementer-no-markdown.sh +324 -0
- package/dist/assets/core/core-assets/hooks/managed-drift-watch.sh +14 -1
- package/dist/assets/core/core-assets/hooks/master-accept-confirm.sh +19 -4
- package/dist/assets/core/core-assets/hooks/plan-gate.sh +39 -10
- package/dist/assets/core/core-assets/hooks/pr-publisher-confirm.sh +36 -0
- package/dist/assets/core/core-assets/hooks/quality-gate-pre-commit.sh +112 -36
- package/dist/assets/core/core-assets/hooks/role-guard.sh +2 -0
- package/dist/assets/core/core-assets/hooks/session-start-context.sh +113 -4
- package/dist/assets/core/core-assets/hooks/subagent-no-background.sh +43 -8
- package/dist/assets/core/core-assets/hooks/subagent-stop-handoff.sh +40 -1
- package/dist/assets/core/core-assets/hooks/worktree-reclaim.sh +11 -0
- package/dist/assets/core/core-assets/managed/cierre-sesion.md +2 -2
- package/dist/assets/core/core-assets/managed/formato-respuesta.md +7 -4
- package/dist/assets/core/core-assets/managed/intake-tickets.md +2 -2
- package/dist/assets/core/core-assets/managed/operaciones-seguras.md +1 -1
- package/dist/assets/core/core-assets/managed/orquestacion.md +13 -11
- package/dist/assets/core/core-assets/managed/planificacion.md +1 -1
- package/dist/assets/core/core-assets/managed/sdd.md +4 -2
- package/dist/assets/core/core-assets/master-plan/delivery-master.md +52 -0
- package/dist/assets/core/core-assets/master-plan/en/delivery-master.md +52 -0
- package/dist/assets/core/core-assets/master-plan/en/slice.md +54 -0
- package/dist/assets/core/core-assets/master-plan/en/tasks.md +37 -5
- package/dist/assets/core/core-assets/master-plan/slice.md +54 -0
- package/dist/assets/core/core-assets/master-plan/tasks.md +34 -2
- package/dist/assets/core/core-assets/settings/settings-base.json +2 -0
- package/dist/assets/core/core-assets/skills/master-plan.md +7 -3
- package/dist/assets/core/core-assets/skills/plan-advanced.md +9 -4
- package/dist/assets/core/core-assets/skills/plan-simple.md +2 -0
- package/dist/assets/core/core-assets/skills/resolve-ticket.md +15 -2
- package/dist/assets/core/core-assets/skills/review-diff.md +1 -1
- package/dist/assets/core/core-assets/skills/scoped-gate.md +1 -5
- package/dist/assets/core/core-assets/skills/security-invariants.md +3 -3
- package/dist/assets/core/core-assets/skills/solution-design.md +15 -13
- package/dist/assets/core/core-assets/skills/spec-bootstrap.md +25 -11
- package/dist/assets/plugins/engram/plugin.json +17 -2
- package/dist/assets/plugins/gh/plugin.json +2 -8
- package/dist/assets/plugins/tgrep/managed/guard-destructive-search-lane.sh +3 -0
- package/dist/assets/plugins/tgrep/scripts/guard-search-routing.sh +5 -0
- package/dist/index.js +1603 -820
- package/package.json +4 -5
- package/dist/assets/core/core-assets/hooks/_partials/scan-scope.sh +0 -113
- package/dist/assets/plugins/gh/managed/gh-protocol.md +0 -12
- package/dist/assets/plugins/jscpd/managed/jscpd-protocol.md +0 -10
- package/dist/assets/plugins/jscpd/plugin.json +0 -57
- package/dist/assets/plugins/jscpd/scripts/check-jscpd.sh +0 -325
- package/dist/assets/plugins/jscpd/skills/jscpd-review.md +0 -26
- package/dist/assets/plugins/semgrep/plugin.json +0 -51
- package/dist/assets/plugins/semgrep/scripts/check-semgrep.sh +0 -343
- package/dist/assets/plugins/semgrep/skills/semgrep-review.md +0 -27
package/README.md
CHANGED
|
@@ -18,6 +18,9 @@ También renderiza un harness Codex completo: `AGENTS.md`, skills en
|
|
|
18
18
|
|
|
19
19
|
// Solo guía universal, con el menor número de archivos
|
|
20
20
|
{ "engines": ["agents-md"] }
|
|
21
|
+
|
|
22
|
+
// Solo Pi (opt-in; ver docs/pi.md)
|
|
23
|
+
{ "engines": ["pi"] }
|
|
21
24
|
```
|
|
22
25
|
|
|
23
26
|
`codex` ya incluye y administra `AGENTS.md`; no necesitas combinarlo con
|
|
@@ -41,7 +44,7 @@ npx navori init
|
|
|
41
44
|
cd ~/tu-repo
|
|
42
45
|
navori init --recommended
|
|
43
46
|
|
|
44
|
-
# + proveedores externos (tgrep,
|
|
47
|
+
# + proveedores externos (tgrep, acli) + pre-commit hook +
|
|
45
48
|
# scan-monorepo + project block estricto — requiere instalar los binarios de esos proveedores.
|
|
46
49
|
# También avisa si falta algún binario y cómo instalarlo, sin instalarlo nunca.
|
|
47
50
|
navori init --full
|
|
@@ -77,9 +80,34 @@ No instala ni actualiza automáticamente y tampoco ejecuta `render`: después de
|
|
|
77
80
|
actualizar navori, corre `navori render --apply` para aplicar los cambios a tu
|
|
78
81
|
harness.
|
|
79
82
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
+
#### Avisos de actualización de herramientas de plugin
|
|
84
|
+
|
|
85
|
+
Plugins como `engram` pueden declarar `latestRelease` en su manifest para recibir
|
|
86
|
+
avisos cuando existe una versión más nueva. El aviso aparece al final del contexto de
|
|
87
|
+
arranque, en un espacio reservado de 300 caracteres, una vez cada 24 h por versión.
|
|
88
|
+
|
|
89
|
+
La consulta se ejecuta:
|
|
90
|
+
- **Fuente**: `api.github.com/repos/<owner>/<repo>/releases/latest` o
|
|
91
|
+
`registry.npmjs.org/<package>/latest` (sin token, solo un User-Agent `navori/<version>`)
|
|
92
|
+
- **Frecuencia**: máximo una solicitud por herramienta por día, reservada bajo un lock
|
|
93
|
+
- **Red**: la carga de red ocurre en un worker detached en segundo plano; la sesión
|
|
94
|
+
nunca espera
|
|
95
|
+
- **Caché**: `~/.navori/tool-versions/` (similar a `~/.navori/update-notice/`)
|
|
96
|
+
- **CI**: sin red — ni refrescos ni avisos
|
|
97
|
+
|
|
98
|
+
Desactívalo junto con el aviso de navori: `NAVORI_NO_UPDATE_NOTIFIER=1`.
|
|
99
|
+
|
|
100
|
+
**Limitaciones:**
|
|
101
|
+
- Codex en sandboxes sin red no obtiene refrescos ni avisos.
|
|
102
|
+
- pi no tiene hooks de sesión: ahí los avisos solo aparecen en `navori doctor`.
|
|
103
|
+
- Si el aviso no cabe en su reserva, se muestra un puntero a `navori doctor` y el aviso
|
|
104
|
+
se reintenta en la siguiente sesión (no se marca como entregado).
|
|
105
|
+
- `doctor` muestra todos los avisos como filas informativas, sin aplicar `--strict`.
|
|
106
|
+
|
|
107
|
+
Si un cierre abrupto deja bloqueado el aviso, solo intervendrás si el lock persiste
|
|
108
|
+
más de un minuto. En ese caso, detén todos los procesos `navori` y elimina
|
|
109
|
+
`~/.navori/tool-versions/lock` o `~/.navori/update-notice/lock`; conserva los archivos
|
|
110
|
+
de caché de ambos directorios.
|
|
83
111
|
|
|
84
112
|
## Comandos
|
|
85
113
|
|
|
@@ -90,24 +118,27 @@ archivos de caché y reserva de ese directorio.
|
|
|
90
118
|
| `remove <plugin>` | Desactiva un plugin y limpia sus bloques managed, sub-bloques y scripts |
|
|
91
119
|
| `configure <section>` | Ajusta una sección del config sin re-correr el wizard |
|
|
92
120
|
| `adopt <path>` | Toma un archivo de `.claude/` que escribiste a mano bajo gestión de navori: lo envuelve en un bloque managed sin reescribir su contenido (preview por default) |
|
|
93
|
-
| `
|
|
121
|
+
| `refresh` | Re-detecta el repo, refresca config y corre sync en un paso |
|
|
122
|
+
| `update` | Actualiza el propio navori desde npm y luego corre `refresh` con el binario nuevo (ver [Actualizar navori](#actualizar-navori)) |
|
|
94
123
|
| `render` | Genera los archivos nativos de cada engine configurado (preview por default; `--apply` escribe). `--all` renderea todos los repos del registro global; `--prune` limpia los que ya no existen |
|
|
95
124
|
| `registry <sub>` | Registro global de tus repos con navori, para `render --all` (`ls`, `scan <dir>`, `add`, `remove`, `prune`) |
|
|
96
|
-
| `sync` | Refresca todos los engines configurados con conflict resolution + backups |
|
|
125
|
+
| `sync` | Refresca todos los engines configurados con conflict resolution + backups. Los bloques en conflicto se resuelven con `--interactive` (diff, keep-mine / accept-new) o en bloque con `--accept-new` / `--keep-mine`. Los archivos completos sin marcador se resuelven archivo por archivo en modo interactivo (diff, keep / accept); `--accept-new-files` acepta en bloque los resolvibles |
|
|
97
126
|
| `preset init <id>` | Scaffoldea un preset local en `.navori/presets/<id>/` |
|
|
98
127
|
| `scan` | Detecta workspaces nuevos en monorepos (`pnpm-workspace.yaml` / `package.json#workspaces`) |
|
|
99
|
-
| `doctor` | Audita el config + drift de cada managed block (CLAUDE.md **y AGENTS.md**), orden canónico, markers malformados, desincronización de monorepo y tools externas faltantes (`--strict` para CI) |
|
|
128
|
+
| `doctor` | Audita el config + drift de cada managed block (CLAUDE.md **y AGENTS.md**), orden canónico, markers malformados, desincronización de monorepo y tools externas faltantes (`--strict` para CI). Informativo, sin afectar `--strict`: versiones instaladas con problema conocido (`externalTool.versionAdvisory`) y avisos de versiones nuevas de herramientas (`navori tools notice`) |
|
|
100
129
|
| `status` | Snapshot rápido: config, plugins activos, conteo de drift y próximos pasos |
|
|
101
|
-
| `audit` | Reporta cómo corrió el harness de verdad: atribución de tokens
|
|
102
|
-
| `
|
|
103
|
-
| `
|
|
130
|
+
| `audit` | Reporta cómo corrió el harness de verdad: atribución de tokens, huecos de adherencia y outcomes de revisión y receipt; disponibilidad de herramientas por ventanas; eficiencia y ciclo de vida por tarea aceptada. `--snapshot` guarda una foto nombrada del rango y `--compare` la contrasta con otra por cohorte, con causas y evidencia |
|
|
131
|
+
| `gate <fast\|full>` | Corre `qualityGate.fast` o `qualityGate.full` con la salida completa en un log (`.navori/state/gate/`) y solo un veredicto compacto en stdout. Flag: `--cwd <path>` |
|
|
132
|
+
| `receipt <sub>` | Recibo de los bytes revisados antes de publicar: `sign` (`--feature <id>`, `--gate-ran scoped\|full`, `--spec <dir> --milestone <Mn>` o `--phase <name\|index>`), `check`, `gate --spec <dir> --milestone <Mn>` o `--phase <name\|index>` (decide si el milestone necesita el gate acotado o el completo) y `review begin` / `review seal --nonce <n>` (sidecar de revisión con identidad de contenido). Flags comunes: `--target <ref>`, `--dir <path>`, `--json` |
|
|
133
|
+
| `spec <classify\|check> <feature>` | `classify` decide si una spec sale en 1 PR o en una PR por entrega (umbrales de `sdd.deliveries`); `check` valida su `tasks.md`: milestones, criterios, cobertura y entregas verticales. Flags: `--cwd`, `--json` |
|
|
134
|
+
| `tools notice [--ack <pluginId@x.y.z,…>]` | Emite los avisos de versiones de herramientas externas pendientes para el hook de arranque; `--ack` los marca como entregados |
|
|
135
|
+
| `handoff <check\|log-review>` | `check` valida el handoff del implementer (`impl_<feature>.json`) antes de despachar al siguiente agente; `log-review <feature>` valida `review_<feature>.json` y agrega a `findings.jsonl` los hallazgos con score >= 50 (`navori handoff check <feature> [--for scribe] [--produced-by reviewer [--since <iso>]] [--dir <path>] [--cwd <checkout>] [--json]`) |
|
|
104
136
|
| `plan <sub>` | Planificación por niveles (`harness.planTiers`): `classify [--files\|--diff]` mide complejidad y nivel de una tarea, `render`/`update` mantienen el workplan Markdown en sync con su JSON, `check` valida su esquema y reglas, `gate` es el hook `PreToolUse(Agent)` que niega el despacho sin workplan válido |
|
|
105
|
-
| `master <sub>` | Flujo guiado del plan maestro por etapas (`init`, `mode`, `template`, `check`, `advance`, `status`, `part`, `close`) |
|
|
137
|
+
| `master <sub>` | Flujo guiado del plan maestro por etapas (`init`, `ux`, `mode`, `template`, `check`, `advance`, `status`, `part`, `close`) y entregas de sus partes: `delivery-slice`, `delivery-check`, `delivery-baseline`, `delivery-queue`, `delivery-criterion`, `delivery-review`, `delivery-present`, `delivery-decision`, `delivery-publication`, `delivery-revoke`. Las que autorizan o aprueban llevan `--approved-by` |
|
|
106
138
|
| `bench` | Corre `render` en dry-run N veces y reporta latencias (detecta regresiones locales) |
|
|
107
|
-
| `workspace <sub>` | Gestiona workspaces cross-repo (`init`, `ls`, `show`, `
|
|
139
|
+
| `workspace <sub>` | Gestiona workspaces cross-repo (`init`, `ls`, `show`, `link`, `add-repo`, `set-default`, `render`, `rename`, `delete`) |
|
|
108
140
|
| `ticket <sub>` | Gestiona tickets-as-files en un workspace (`new`, `list`, `show`, `archive`, `delete`) |
|
|
109
141
|
| `dominio <sub>` | Base de conocimiento durable del workspace (`init`, `list`, `show`, `reindex`, `doctor`, `inject`) |
|
|
110
|
-
| `global <sub>` | Harness base por máquina en `~/.claude` (`init`, `render`, `doctor`, `uninstall`) — opt-in explícito y aditivo |
|
|
111
142
|
| `codex <sub>` | Comandos específicos de Codex; hoy `trust` aprueba los hooks del proyecto en `~/.codex/config.toml` |
|
|
112
143
|
| `backup <sub>` | Lista y restaura backups de `~/.navori/backups/` |
|
|
113
144
|
| `migrations <sub>` | Lista y restaura migraciones de `~/.navori/migrations/` |
|
|
@@ -158,8 +189,6 @@ La resolución es **local → bundled**: si tienes un preset local con el mismo
|
|
|
158
189
|
| `tgrep` | Descubrimiento textual de código vía CLI indexado | `tgrep` binary |
|
|
159
190
|
| `acli` | Leer tickets de Jira desde la terminal | `acli` |
|
|
160
191
|
| `gh` | GitHub Issues, PRs y workflow runs | `gh` |
|
|
161
|
-
| `jscpd` | Detección de duplicación en el diff | `jscpd` (opt-in) |
|
|
162
|
-
| `semgrep` | Security gate local | `semgrep` (opt-in) |
|
|
163
192
|
|
|
164
193
|
> `codegraph` y `tgrep` se retiraron brevemente el 2026-09-15 y se reintrodujeron el
|
|
165
194
|
> 2026-09-16 (#838) con una integración que los hace trabajar entre sí — acta en
|
|
@@ -177,7 +206,10 @@ Con `harness.planTiers: true` en `navori.config.json`, `navori plan classify` mi
|
|
|
177
206
|
complejidad de una tarea (señales como dinero/credenciales/PII, dependencia nueva, migración de
|
|
178
207
|
esquema, o tocar una ruta de `project.criticalPaths`) y la ubica en un nivel 0–3. El hook
|
|
179
208
|
`PreToolUse(Agent)` (`navori plan gate`) niega el despacho de un subagente sin el workplan que su
|
|
180
|
-
nivel exige, y escala la exigencia tras dos rechazos seguidos. `navori
|
|
209
|
+
nivel exige, y escala la exigencia tras dos rechazos seguidos. Si `navori` falta o su build no tiene el
|
|
210
|
+
subcomando `plan`, el hook no tiene veredicto y, en modos que muestran el prompt, pide
|
|
211
|
+
confirmación en vez de dejarte sin salida (en `bypassPermissions`, `dontAsk` o `plan` sigue
|
|
212
|
+
bloqueando). `navori plan classify --diff`
|
|
181
213
|
corre el mismo clasificador contra `git diff --name-only <base>...HEAD` para avisar cuando el
|
|
182
214
|
trabajo se salió del nivel que el workplan declaró.
|
|
183
215
|
|
|
@@ -190,12 +222,41 @@ El agente `architect` ya no tiene un flag `harness.architect` — renderiza siem
|
|
|
190
222
|
que todavía trae `harness.architect` falla con un aviso de clave retirada en vez de ignorarla en
|
|
191
223
|
silencio; `navori configure migrate` la quita.
|
|
192
224
|
|
|
225
|
+
## Entregas de specs (`sdd.deliveries`)
|
|
226
|
+
|
|
227
|
+
Una spec grande no tiene por qué salir en una sola PR. `navori spec classify <feature>` la mide
|
|
228
|
+
contra los umbrales de `sdd.deliveries` en `navori.config.json` (`splitMinTasks`, `splitMinLoc`,
|
|
229
|
+
`maxPrsPerSpec`; defaults 12 tareas, 1500 LOC estimadas y 4 PRs) y dice si sale en una PR o en una
|
|
230
|
+
PR por entrega. `navori spec check` valida el `tasks.md` contra su gramática:
|
|
231
|
+
|
|
232
|
+
- **`E<n>`**: entrega; una PR cada una.
|
|
233
|
+
- **`M<n>`**: milestone; cada uno se verifica y se commitea por separado.
|
|
234
|
+
- **`T<n>`**: tarea; declara los `R<n>` que cubre.
|
|
235
|
+
|
|
236
|
+
El gate completo corre una vez por PR, no una vez por milestone; el gate por milestone lo decide
|
|
237
|
+
`navori receipt gate`.
|
|
238
|
+
|
|
239
|
+
## Harness de workspaces (`monorepo.workspaceHarness`)
|
|
240
|
+
|
|
241
|
+
`monorepo.workspaceHarness` decide cuánto harness recibe cada workspace de un monorepo. Es un solo
|
|
242
|
+
valor para todo el repo:
|
|
243
|
+
|
|
244
|
+
- `minimal` (default): su archivo de contexto más las skills que la raíz no tiene ya. Una skill
|
|
245
|
+
idéntica a la de la raíz no se duplica.
|
|
246
|
+
- `full`: todo, como antes de recortar.
|
|
247
|
+
- `root`: solo su archivo de contexto (`CLAUDE.md`, y `AGENTS.md` bajo Codex). La raíz escribe las
|
|
248
|
+
skills de librería y de preset que declaran los workspaces.
|
|
249
|
+
|
|
250
|
+
`navori doctor` trata `minimal` y `root` como harness recortado, y avisa si el valor es `full`.
|
|
251
|
+
|
|
193
252
|
## Harness defensivo (read-only por default)
|
|
194
253
|
|
|
195
254
|
El harness que genera `navori` trae permisos seguros desde el arranque, para que tengas menos prompts en lo cotidiano sin bajar la guardia en lo peligroso:
|
|
196
255
|
|
|
197
256
|
- **Las lecturas no piden confirmación**: `git status/diff/log/show`, `ls`, `cat`, `grep`, `Read`/`Glob`/`Grep`, etc. corren sin interrumpirte.
|
|
198
257
|
- **Lo destructivo pide confirmación** (`ask`): `rm -rf`, `git push --force`, `git reset --hard`, `git clean -f`, `chmod -R`, …
|
|
258
|
+
- **Descartar trabajo sin commitear se bloquea** (`guard-destructive`, `exit 2`, sin aprobación posible): `git reset --hard`, `git checkout -f`, `git checkout -- .` (o `git checkout .`), `git restore <rutas>` sin `--staged`, y `git clean -f` (sin `-n`). El bloqueo depende del estado: si el árbol está limpio, no hay nada que perder y el comando pasa. Si el directorio destino no se puede inspeccionar (variable, sustitución o ruta inexistente), también bloquea. El mensaje indica la ruta para hacerlo de forma segura.
|
|
259
|
+
- **El `publisher` no reescribe historia**: tras un commit fallido no ejecuta `git reset` ni reescribe commits. Reporta con `git status` y `git log -1 --stat`, y la recuperación queda para el orquestador o el usuario.
|
|
199
260
|
- **Lo catastrófico se rechaza** (`deny`): `rm -rf /`, `sudo rm`, `mkfs`, …
|
|
200
261
|
- Un hook `guard-destructive` actúa como backstop adicional.
|
|
201
262
|
|
|
@@ -260,7 +321,7 @@ un aviso que **nombra** los repos con bloques editados a mano (conflict, que el
|
|
|
260
321
|
render no pisa) y un roll-up `ok · changed · conflict · failed`.
|
|
261
322
|
|
|
262
323
|
El registro (`~/.navori/registry.json`) se puebla solo: cada `navori init` /
|
|
263
|
-
`navori
|
|
324
|
+
`navori refresh` te da de alta. Para arrancar con lo que ya tenías instalado,
|
|
264
325
|
escanéalo una vez:
|
|
265
326
|
|
|
266
327
|
```bash
|
|
@@ -272,52 +333,6 @@ navori registry prune # quitar los que ya no existen
|
|
|
272
333
|
Es ortogonal a los workspaces: el registro es "qué repos existen"; el workspace
|
|
273
334
|
es el perfil de policy (branchBase/prTarget) que cada repo hereda.
|
|
274
335
|
|
|
275
|
-
## Harness global por máquina (opt-in)
|
|
276
|
-
|
|
277
|
-
Todo lo de arriba es por repo. Cuando abres una sesión **fuera** de un repo con navori (un scratch,
|
|
278
|
-
un repo ajeno, tu `~`), no hay harness: ni doctrina de orquestación, ni skills, ni agentes. La capa
|
|
279
|
-
global cubre ese hueco. No la confundas con `render --all` de la sección anterior: aquélla empuja tu
|
|
280
|
-
harness a los repos que **ya** tienen navori; ésta cubre las sesiones que no están en ninguno.
|
|
281
|
-
|
|
282
|
-
Es **opt-in de huella cero**: si nunca corres `navori global init`, no existe `~/.navori/global.json`
|
|
283
|
-
y navori no escribió un solo byte en tu máquina.
|
|
284
|
-
|
|
285
|
-
```bash
|
|
286
|
-
navori global init # wizard: bloques del baseline + permisos personales.
|
|
287
|
-
# Preview: sin --apply no escribe un solo byte
|
|
288
|
-
navori global init --apply # escribe lo que el preview mostró
|
|
289
|
-
navori global init --recommended --apply # headless (CI): sin preguntas, selección recomendada
|
|
290
|
-
navori global doctor # audita: drift del hook, gate, plugin, permisos y versión
|
|
291
|
-
navori global render --apply # re-renderiza tras un bump del CLI (preview sin --apply)
|
|
292
|
-
navori global uninstall # la retira por completo
|
|
293
|
-
```
|
|
294
|
-
|
|
295
|
-
El `init` pregunta dos cosas: **qué bloques** componen el baseline (los que declaran `globalSafe`)
|
|
296
|
-
y **qué permisos personales** quieres en `~/.claude/settings.json` — ése es el único camino de UI
|
|
297
|
-
para `permissions`. Re-inicializar **preserva** lo que ya habías elegido: no te resetea a los
|
|
298
|
-
defaults. Sin TTY (CI, pipe) cae solo al camino de `--recommended`, y `--lang es|en` fija el idioma
|
|
299
|
-
del baseline y de los prompts.
|
|
300
|
-
|
|
301
|
-
Qué escribe el `init --apply`, y nada más:
|
|
302
|
-
|
|
303
|
-
- `~/.navori/global.json` — el manifest: idioma, bloques del baseline y tus permisos globales.
|
|
304
|
-
- `~/.claude/skills/navori/` — el plugin `navori@skills-dir` con los 8 agentes, las 11 skills y el
|
|
305
|
-
hook del baseline. Claude Code lo carga sin marketplace ni paso de instalación; las skills globales
|
|
306
|
-
se invocan `/navori:<nombre>` (tras un render, `/reload-plugins` o sesión nueva).
|
|
307
|
-
- `~/.claude/settings.json` — **solo** la clave `permissions`, y solo si declaraste permisos globales
|
|
308
|
-
en el manifest. Con la config por default ni siquiera lo crea.
|
|
309
|
-
|
|
310
|
-
Respeta `CLAUDE_CONFIG_DIR`: si lo tienes seteado, el plugin va ahí en vez de a `~/.claude`.
|
|
311
|
-
|
|
312
|
-
**El baseline se hace a un lado solo.** El hook corre en `SessionStart` y busca un `navori.config.json`
|
|
313
|
-
hacia arriba desde el directorio de la sesión: si lo encuentra, no emite nada — manda el harness del
|
|
314
|
-
repo, que es más específico. Por eso el baseline viaja dentro de un hook y no como bloque estático en
|
|
315
|
-
`~/.claude/CLAUDE.md`: ese archivo se carga siempre y no podría cederle el paso a nadie.
|
|
316
|
-
|
|
317
|
-
`navori global uninstall` retira **solo lo que navori escribió**: el plugin, el manifest y los permisos
|
|
318
|
-
que quedaron registrados como suyos. Un permiso que ya tenías en tu `settings.json` nunca se vuelve de
|
|
319
|
-
navori, así que el uninstall no se lo lleva.
|
|
320
|
-
|
|
321
336
|
## Managed blocks con versionado
|
|
322
337
|
|
|
323
338
|
Cada bloque que `navori` inyecta en tu `CLAUDE.md` lleva metadata:
|
|
@@ -349,9 +364,9 @@ Cambiar una sola cosa sin re-init:
|
|
|
349
364
|
|
|
350
365
|
```bash
|
|
351
366
|
navori configure plugins # multiselect de plugins activos
|
|
352
|
-
navori configure quality-gate #
|
|
367
|
+
navori configure quality-gate # comandos del quality gate
|
|
353
368
|
navori configure language en # switch a inglés (fallback a es)
|
|
354
|
-
navori configure engines # multiselect: claude / codex / agents-md / cursor / copilot
|
|
369
|
+
navori configure engines # multiselect: claude / codex / agents-md / cursor / copilot / pi
|
|
355
370
|
navori configure branch-base main # punto de fork / rama protegida
|
|
356
371
|
navori configure pr-target develop # rama destino del PR (gh pr create --base)
|
|
357
372
|
navori configure workspace bonum # asociar a un workspace
|
|
@@ -365,6 +380,24 @@ retiradas caen en la misma con valores distintos no se infiere nada — se pregu
|
|
|
365
380
|
`--scout=<modelo> --scout-effort=<nivel>`. `--dry-run` no escribe, y `--all` barre el registry
|
|
366
381
|
completo (preview salvo `--apply`).
|
|
367
382
|
|
|
383
|
+
### Claves de config para el gate y los hooks nativos
|
|
384
|
+
|
|
385
|
+
- `qualityGate.scoped` (string): carril acotado del reviewer — los checks baratos de `full` más los tests relacionados con el diff. Si falta, usa `fast`. Se interpola como `navori.scopedGate`.
|
|
386
|
+
- `qualityGate.nativeHooks` (boolean): declara que el pre-commit nativo del proyecto ya corre `fast`; el hook `quality-gate-pre-commit` omite solo su paso de gate.
|
|
387
|
+
- `plugins.<id>.nativeHook` (boolean): el hook git nativo corre el check de ese plugin, así que su hook no se registra (los scripts se siguen instalando).
|
|
388
|
+
|
|
389
|
+
### Tope de `progress/current.md`
|
|
390
|
+
|
|
391
|
+
`progress/current.md` se carga en cada sesión, así que tiene un tope. El hook pre-commit bloquea los commits de agente que lo dejan sobre el tope duro o lo hacen crecer estando ya sobre él (los commits humanos no se bloquean). `navori doctor` lo mide en bytes con los mismos topes y avisa; el hook de inicio de sesión advierte, sin bloquear, al pasar el tope suave.
|
|
392
|
+
|
|
393
|
+
## Migrando a 0.12
|
|
394
|
+
|
|
395
|
+
- Se retiró el comando `global` y el colector launchd (`audit --collect` sigue). `doctor --json` ya no emite `globalScope`.
|
|
396
|
+
- Se retiraron los plugins `jscpd` y `semgrep`: `navori add jscpd|semgrep` responde que están retirados.
|
|
397
|
+
- El piso de Pi sube a 1.1.0: Pi 0.87.x pierde `navori_subagent`. Node mínimo: >= 22.12.
|
|
398
|
+
- `navori update` ahora actualiza el CLI (consulta npm, confirma, instala y luego corre `navori refresh`). El comportamiento anterior es ahora `navori refresh`, sin alias: los scripts que usaban `navori update` para re-sincronizar el harness deben cambiar a `navori refresh`.
|
|
399
|
+
- Migra con `navori render --apply` (poda los assets retirados que navori gestionaba) y luego `navori doctor` (reporta los restos).
|
|
400
|
+
|
|
368
401
|
## Extender el harness en tu repo
|
|
369
402
|
|
|
370
403
|
navori instala un baseline; lo que lo vuelve valioso en **tu** repo es el conocimiento que sólo
|
|
@@ -418,3 +451,15 @@ Contrato del `SKILL.md`: [`docs/recipes/skill-authoring.md`](https://github.com/
|
|
|
418
451
|
## Licencia
|
|
419
452
|
|
|
420
453
|
MIT.
|
|
454
|
+
|
|
455
|
+
## Actualizar navori
|
|
456
|
+
|
|
457
|
+
`navori update` consulta npm por la última versión de navori y muestra el comando de
|
|
458
|
+
instalación según cómo lo tengas: npm global, devDependency, dependency o `npx`. Pide
|
|
459
|
+
confirmación (salvo `--yes`), instala y corre `navori refresh` con el binario nuevo.
|
|
460
|
+
|
|
461
|
+
- `--cli-only`: se detiene tras actualizar el CLI, sin `refresh`.
|
|
462
|
+
- Sin red o ya en la última versión: corre `refresh` directo.
|
|
463
|
+
- Si la instalación falla: imprime el comando manual y sale con código 1.
|
|
464
|
+
- Sin TTY y sin `--yes`: imprime el comando y sale con código 1.
|
|
465
|
+
- Solo soporta npm.
|
|
@@ -29,7 +29,7 @@ For a **master-plan** task, write the requested `<etapa>/plans/plan<n>.md` and p
|
|
|
29
29
|
|
|
30
30
|
Use URLs de documentación oficial for expiring facts and include the fecha de consulta. If a source is unavailable, label the claim `[SIN VERIFICAR]` and list the sources consulted or unavailable.
|
|
31
31
|
|
|
32
|
-
Via `Agent` you may dispatch `scout`/`scribe`; plan-gate and Agent hooks fire inside you with `agent_id`, expected
|
|
32
|
+
<!-- navori:if-not onPi -->Via `Agent` you may dispatch `scout`/`scribe`; plan-gate and Agent hooks fire inside you with `agent_id`, expected.<!-- /navori:if-not -->
|
|
33
33
|
|
|
34
34
|
## Protocol
|
|
35
35
|
|
|
@@ -5,7 +5,7 @@ tools: Read, Write, Edit, Glob, Grep, Bash
|
|
|
5
5
|
model: {{models.implementer}}
|
|
6
6
|
effort: {{effort.implementer}}
|
|
7
7
|
maxTurns: 160
|
|
8
|
-
maxWords:
|
|
8
|
+
maxWords: 2473
|
|
9
9
|
---
|
|
10
10
|
|
|
11
11
|
# Implementer Agent
|
|
@@ -27,7 +27,7 @@ You execute **a single** task from start to verification. You don't orchestrate,
|
|
|
27
27
|
- [ ] Define interface in <path>
|
|
28
28
|
- [ ] Implement logic in <path>
|
|
29
29
|
- [ ] Cover with a test
|
|
30
|
-
- [ ] Run `{{
|
|
30
|
+
- [ ] Run `{{gateRun.fast}}`
|
|
31
31
|
```
|
|
32
32
|
|
|
33
33
|
- `Expected files: <list>`
|
|
@@ -38,10 +38,12 @@ You execute **a single** task from start to verification. You don't orchestrate,
|
|
|
38
38
|
4. **Quality gate** (mandatory before returning):
|
|
39
39
|
|
|
40
40
|
```bash
|
|
41
|
-
{{
|
|
41
|
+
{{gateRun.fast}}
|
|
42
42
|
```
|
|
43
43
|
|
|
44
|
-
If
|
|
44
|
+
If `navori gate <kind>` prints no first line `navori gate <kind>: exit <N> — log <path>`, it did not run: run the literal `{{qualityGate.fast}}`. Open the log only on a red.
|
|
45
|
+
|
|
46
|
+
If it fails: fix it and re-run. Don't return with red. You are the single owner of this gate run: never share it with another process, never poll `pgrep`/`ps` for it, and a timeout is never a success signal. If the gate can outlive the Bash timeout, follow `.claude/skills/verify-before-done/SKILL.md`'s subagent row: run its chained steps one by one in the foreground, never background them (<!-- navori:if-not onCodex -->no shell `&`, no `run_in_background`, no `Monitor`<!-- /navori:if-not --><!-- navori:if onCodex -->no shell `&`, no background execution<!-- /navori:if -->) — you won't be re-woken to read the result. If no chained step fits under any foreground timeout, stop and report `BLOCKED` instead of improvising a background wait. When you can't explain WHY it failed, apply `.claude/skills/debug-failure/SKILL.md` before touching anything. If your second fix attempt fails the same way, that same skill's hypothesis re-check governs instead of throwing a third patch.
|
|
45
47
|
5. **UI**: for screen changes, the default evidence is the repo's tests plus a correct diff — **do NOT spin up a browser or dev server automatically**. Visual/browser validation is **optional and strictly on-request**: run it only when the user explicitly asks to check the UI in this prompt, and then drive the repo's browser-automation tool if one is set up (e.g. `playwright-cli`, whose installer ships its own skill).
|
|
46
48
|
6. **No commits** without the `reviewer`'s approval. When you finish, <!-- navori:if-not scribeOwnsMarkdown -->write the report<!-- /navori:if-not --><!-- navori:if scribeOwnsMarkdown -->write your JSON evidence<!-- /navori:if --> and return the reference.
|
|
47
49
|
<!-- navori:if planTiers -->
|
|
@@ -60,7 +62,7 @@ When the encargo opens with `workplan: <feature>`, read `.navori/state/handoffs/
|
|
|
60
62
|
- **Zero new errors** introduced by your code in the quality gate tools (vs. baseline) — classify per `verify-before-done`'s Failure attribution, never by diff location alone; see the evidence table below. Returning with any tool red (because of your change) is automatic grounds for `CHANGES_REQUESTED`.
|
|
61
63
|
- **Never mutate or discard the shared working tree**: no stashing, no checkout/reset that discards local changes, no working-tree clean — these hit the `ask` permission rule and can stall a background agent indefinitely. Same reasoning for scratch files: leave them, don't clean them with a recursive delete.
|
|
62
64
|
- **JSDoc** mandatory on public exports and functions >15 lines or with dense conditional logic.
|
|
63
|
-
- **SDD traceability** (only if the feature has `{{sdd.specsDir}}/<feature>/tasks.md`, see
|
|
65
|
+
- **SDD traceability** (only if the feature has `{{sdd.specsDir}}/<feature>/tasks.md`, see `spec-bootstrap`): each `R<n>` in your batch is covered by ≥1 test, and each test references its requirements with a `// Covers: R<n>` comment above the case. Without full traceability the `reviewer` rejects.
|
|
64
66
|
- **Guard/policy coverage** (only if your task introduces or modifies a guard, policy or permission check): your report carries the enumeration, not just the diff — every entry point that mutates the same resource (routes, bulk/admin variants, jobs, scripts) with its `file:line` evidence, each marked covered or excluded with the reason. Locate them with `locate-code`; an entry point you didn't list is one the `reviewer` has to rediscover.
|
|
65
67
|
- If a tool fails weirdly (e.g. tsc breaks with no apparent diff), **don't improvise a workaround**: note `Status: BLOCKED` + the reason in `.navori/state/handoffs/impl_<feature>.md` and stop.
|
|
66
68
|
- **While iterating, run only the tests of the area you touch** (filter by the runner's path). The full gate in step 4 runs at the end, not on each iteration — saves time and context. Never run the full `{{qualityGate.full}}` suite yourself: that's the `reviewer`'s Pass 2 job, and it commonly outlives Bash's timeout. If this repo has a diff-scoped fast check (`scoped-gate`), it's hygiene for iterating, never a substitute for step 4.
|
|
@@ -163,6 +165,8 @@ Write `.navori/state/handoffs/impl_<feature>.json` — the only artifact you pro
|
|
|
163
165
|
|
|
164
166
|
`doubts` is optional: declare one `{ "file": "<path>", "reason": "<why you are unsure>" }` entry per spot where you are unsure the change is right, so the reviewer answers it.
|
|
165
167
|
|
|
168
|
+
Types follow the handoff schema: `rootCause` is a string, present only for a bugfix (omit the key otherwise, never `null`); `blockers` is an array of strings (`[]` when none).
|
|
169
|
+
|
|
166
170
|
`markdownRequests` carries every piece of prose your task needs — your own non-obvious decisions, a CONTRIBUTING/README update, a spec task checkbox, a skill or agent tweak. State the `intent` and the `evidence`; never the finished sentence — drafting the prose from that intent is the `scribe`'s job, not yours. Empty array when the task touches no Markdown at all.
|
|
167
171
|
|
|
168
172
|
## Communication with the orchestrator
|
|
@@ -4,7 +4,7 @@ description: Do NOT invoke as a subagent, never and under no condition. Orchestr
|
|
|
4
4
|
tools: Read, Glob, Grep, Bash, Agent
|
|
5
5
|
model: {{models.orchestrator}}
|
|
6
6
|
effort: {{effort.orchestrator}}
|
|
7
|
-
maxWords:
|
|
7
|
+
maxWords: 3365
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# Orchestrator Playbook (embodied by the main agent)
|
|
@@ -20,7 +20,7 @@ One route removes the decision entirely. It is more expensive per change and tha
|
|
|
20
20
|
## Startup protocol
|
|
21
21
|
|
|
22
22
|
1. `CLAUDE.md` (stack, conventions, quality gate) is already in your context when your host injects it; read it from disk ONLY if your host did not inject it (e.g. an engine without automatic injection).
|
|
23
|
-
2. The catalog of subagents
|
|
23
|
+
2. The catalog of subagents is the managed block whose id is `agentes-disponibles`, delivered at session start. Locate it by the id, never by the heading: the ids are fixed, the headings are rendered in the repo's configured language and change with it. Skills: the host's native listing.
|
|
24
24
|
3. Read `progress/current.md` (repo root) if it exists — the previous session's state.
|
|
25
25
|
4. Identify the task's scope against the "Project rules" below (legacy paths, critical areas, repo conventions).
|
|
26
26
|
5. **Did text from a ticket (Jira/Linear/GitHub/Slack) arrive?** If it matches your `auditor` agent's ticket-encargo triggers (bug in a critical feature, structural migration, feature that crosses >3 layers), invoke that agent first — it produces `.navori/state/handoffs/audit_ticket_<ID>.md` that guides all later decomposition. For trivial tickets (typo, copy, color), skip the audit. The single architectural design gate — when it fires, who proposes, who challenges, who decides — lives in "## Role: orchestrator" and the `solution-design` skill, not here.
|
|
@@ -67,7 +67,7 @@ When the `done -> file` come back, **gather and analyze deeply YOURSELF**: read
|
|
|
67
67
|
|
|
68
68
|
Fan-out is a lever, not a toll — so when you do delegate, hand the smallest encargo that covers the work:
|
|
69
69
|
|
|
70
|
-
- **Don't delegate merely to wrap a lookup.** If what's missing is a Code discovery routing call you can make yourself (project instructions), run it directly — a subagent invocation isn't a proxy for a query you can issue this turn. When delegation is warranted for a real reason, carry over the pending question, the evidence you already gathered, the relevant paths and their freshness in the encargo; never assume the subagent shares this context — it starts isolated.
|
|
70
|
+
- **Don't delegate merely to wrap a lookup.** If what's missing is a Code discovery routing call you can make yourself (project instructions), run it directly — a subagent invocation isn't a proxy for a query you can issue this turn. When delegation is warranted for a real reason, carry over the pending question, the evidence you already gathered, the relevant paths and their freshness in the encargo; never assume the subagent shares this context — it starts isolated, with no skills listing: name any skill it should apply with its path `.claude/skills/<id>/SKILL.md`.
|
|
71
71
|
- **Peel off the mechanical first.** Copies, renames, scaffolding, JSON/string edits → send them to a low-tier agent in their own encargo; never bundle them into the `implementer`'s, where they inflate its context and its run without raising quality.
|
|
72
72
|
- **One encargo = one unit.** A pre-existing bug the `implementer` hits outside its scope → it reports and stops there (a trivial one-liner is the exception); **you** decide whether to open a separate unit. Scope doesn't self-expand mid-run.
|
|
73
73
|
- **Tier by sub-task, not by round.** A single fix round can mix tiers. Map: **low** → mechanical work (copies, renames, scaffolding, string/JSON edits, a one-line fix); **mid** → a scoped bugfix with a clear cause or a bounded feature; **high** → judgment work (design, security regex, ambiguous root-cause, removal semantics, critical areas).
|
|
@@ -155,10 +155,12 @@ And never take a merged PR as proof on its own: **squash merge leaves no ancestr
|
|
|
155
155
|
## Quality gate
|
|
156
156
|
|
|
157
157
|
```bash
|
|
158
|
-
{{
|
|
159
|
-
{{
|
|
158
|
+
{{gateRun.fast}} # fast gate — pre-step to the reviewer
|
|
159
|
+
{{gateRun.full}} # full gate — before closing the session / creating the PR
|
|
160
160
|
```
|
|
161
161
|
|
|
162
|
+
When the command is `navori gate <kind>`, its first stdout line is `navori gate <kind>: exit <N> — log <path>`; if it is missing, the gate did not run: run the literal `{{qualityGate.fast}}` or `{{qualityGate.full}}` command instead.
|
|
163
|
+
|
|
162
164
|
If the repo has no test suite, the `implementer` still can't claim "done" without fresh evidence (a correct diff plus whatever checks exist) — but browser/visual validation stays **on-request only, never automatic**. The `verify-before-done` skill enforces the "fresh evidence rule" over any "done" claim.
|
|
163
165
|
|
|
164
166
|
## What you do NOT do
|
|
@@ -4,7 +4,10 @@ description: Drafts commits in the configured style and opens the PR with the re
|
|
|
4
4
|
tools: Read, Glob, Grep, Bash
|
|
5
5
|
model: {{models.publisher}}
|
|
6
6
|
effort: {{effort.publisher}}
|
|
7
|
-
|
|
7
|
+
# Spec 0044 T12 (R18, R19, R23, R26): added commit-only mode, spec delivery PR steps
|
|
8
|
+
# (with Spec-Delivery, git merge-base check, Refs/Closes), and prTarget warning;
|
|
9
|
+
# +~200 words measured. 4200 = 3987 actual + 5.3% margin.
|
|
10
|
+
maxWords: 4200
|
|
8
11
|
---
|
|
9
12
|
|
|
10
13
|
# Publisher Agent
|
|
@@ -14,14 +17,14 @@ You own the **end of the cycle**: well-structured commits in the configured styl
|
|
|
14
17
|
## When to trigger
|
|
15
18
|
|
|
16
19
|
- Working tree with changes ready to commit (post-implementer + review APPROVED).
|
|
17
|
-
- Branch finished, ready for PR: commits on the branch, harness approved, and fresh
|
|
20
|
+
- Branch finished, ready for PR: commits on the branch, harness approved, and fresh full-gate evidence over the diff that ships (see Gate below).
|
|
18
21
|
- Explicit user request: "create the PR", "commit this", "send the PR", "/pr".
|
|
19
22
|
|
|
20
23
|
## When NOT to trigger
|
|
21
24
|
|
|
22
25
|
- Working tree with uncommitted changes when the user only asked to "open the PR" → first commit or ask for permission.
|
|
23
26
|
- You are on `{{prTarget}}`, on the branch this one was forked from, or another protected branch → abort + ask for a branch.
|
|
24
|
-
- Harness active and THIS feature's review
|
|
27
|
+
- Harness active and THIS feature's review (`.navori/state/handoffs/review_<feature>.md`, identified by name in the pre-flight) contains `CHANGES_REQUESTED` → no PR is created.
|
|
25
28
|
- Quality gate red this turn.
|
|
26
29
|
|
|
27
30
|
> **Two branches, one that decides:** `{{prTarget}}` is the target for `gh pr create --base` and every diff below. The fork point is a separate setting; in most repos both name the same branch. Where they differ, the target branch wins — the fork-point diff is never the PR's.
|
|
@@ -40,51 +43,32 @@ if [ "$behind" -ne 0 ]; then
|
|
|
40
43
|
exit 1
|
|
41
44
|
fi
|
|
42
45
|
git log origin/{{prTarget}}..HEAD --oneline # must have ≥1 commit (or changes to commit)
|
|
43
|
-
git diff origin/{{prTarget}} --stat #
|
|
46
|
+
git diff origin/{{prTarget}} --stat # real scope so far
|
|
44
47
|
gh auth status # gh authenticated
|
|
45
48
|
```
|
|
46
49
|
|
|
47
|
-
A nonzero `behind` count is a hard stop: do not
|
|
48
|
-
consume a receipt, commit, push, or create a PR. The reviewer would otherwise
|
|
49
|
-
have signed target-only files as phantom deletions from this stale worktree.
|
|
50
|
+
A nonzero `behind` count is a hard stop: do not consume a receipt, commit, push, or create a PR. The reviewer would otherwise have signed target-only files as phantom deletions from this stale worktree.
|
|
50
51
|
|
|
51
|
-
|
|
52
|
-
`"status":"ok"` before this branch can publish.
|
|
52
|
+
**Which review counts.** Identify THIS feature's review by name: `.navori/state/handoffs/review_<feature>.md`, with `<feature>` the id from your brief. A broad glob (`review_*.md`) over all reviews is not valid: another feature's `APPROVED` never unblocks this PR and another cycle's `CHANGES_REQUESTED` never aborts it. Open that file: its verdict must be `APPROVED` and its scope/feature section must name the feature you are about to commit. Absent, ambiguous (more than one candidate), or mismatched → not approved: abort, tell the user the review is missing, and never assume a generic `APPROVED`.
|
|
53
53
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
Coverage of the review and the receipt's fingerprints are two questions about the SAME set of files. Write it once, read it everywhere:
|
|
57
|
-
|
|
58
|
-
```bash
|
|
59
|
-
shipping=$({ git -c core.quotepath=false diff --name-only "origin/{{prTarget}}"; \
|
|
60
|
-
git -c core.quotepath=false ls-files --others --exclude-standard; } \
|
|
61
|
-
| sort -u | grep -vE '^(\.navori/state/handoffs/|progress/)')
|
|
62
|
-
printf '%s\n' "$shipping" # read it: this is what ships
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
- **`$shipping` does not survive the call.** Each Bash call starts a fresh shell — no variable or function crosses over — so re-run the assignment in the same call as whatever reads it. That is a copy of four lines, not a second definition of the set.
|
|
66
|
-
- **Two dots, plus the untracked files — NEVER `...HEAD`.** Three-dot lists only what is already *committed*, and your trigger is by construction an **uncommitted** tree: there is no clean-working-tree check in this pre-flight because the commit is yours to make, further down. Run against an uncommitted tree, a three-dot listing comes back EMPTY — the coverage check then finds nothing missing and the waiver's count reads zero, so both are granted on every diff. It fails silently, in the unsafe direction. Two-dot plus `ls-files --others` is the exact set the `reviewer` captured and signed.
|
|
67
|
-
- **`progress/` is dropped**, the same grep the receipt applies, so the two sets line up 1:1 and a git-persisted session-state update never looks like an unreviewed file. Deletions DO stay in the set (the receipt records them as `deleted <path>`), so a removed file can't ship unreviewed.
|
|
68
|
-
- **`quotepath=false` on both listings**, exactly as the reviewer signed them: git C-quotes a non-ASCII path by default, and a quoted path never matches the receipt's line — the file would read as uncovered, or slip by unverified.
|
|
69
|
-
|
|
70
|
-
If the harness is active, identify THIS feature's review: `.navori/state/handoffs/review_<feature>.md`, with `<feature>` the id you received in your brief. A broad glob (`review_*.md`) over all reviews is not valid — it's not enough that some review with `APPROVED` exists in the directory, it has to be this feature's.
|
|
71
|
-
|
|
72
|
-
Open that specific file and confirm its verdict is `APPROVED` and that its scope/feature section names the same feature you're about to commit. The verdict only counts if the review **covers the whole shipping diff**: the reviewer's content receipt (below) is the authoritative list of the files it actually reviewed, so every file in the shipping diff above must appear there. A touched file the review never saw → the `APPROVED` doesn't cover the full change → it does NOT count as approved. Abort, don't create the PR, and send it back to the reviewer to cover the missing files. It's not enough to mention the difference and carry on. The coverage check is mechanical — see the receipt block.
|
|
73
|
-
|
|
74
|
-
<!-- This file-coverage rule lives here only; the commit+PR flow has no second home to this agent (single owner of the PR flow). -->
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
An absent file, ambiguous (more than one candidate), or with a verdict/scope that doesn't match the current feature → does NOT count as approved: abort, tell the user the review is missing, and never assume a generic `APPROVED`.
|
|
78
|
-
|
|
79
|
-
**Content receipt: the diff must still match what was approved.** Before committing, run the receipt command with the feature id from `review_<feature>.md`. It owns coverage and drift detection; do not reproduce its algorithm in shell.
|
|
54
|
+
**Content receipt: the diff must still match what was approved.** The `receipt.txt` check is also a hard stop. Run it with the feature id from `review_<feature>.md`. It owns the shipping set (working tree against `origin/{{prTarget}}`, untracked files included), the coverage check and the drift check: do not reproduce any of them in shell.
|
|
80
55
|
|
|
81
56
|
```bash
|
|
82
57
|
navori receipt check --feature <feature> --target {{prTarget}} --dir .navori/state/handoffs --json
|
|
83
58
|
```
|
|
84
59
|
|
|
85
|
-
Continue only
|
|
60
|
+
Continue only on `"status":"ok"`, and read the rest of the JSON by this table:
|
|
86
61
|
|
|
87
|
-
|
|
62
|
+
| JSON from `navori receipt check` | Action |
|
|
63
|
+
|---|---|
|
|
64
|
+
| `"status":"error"` (`error` names the cause: branch behind the target, no receipt, receipt of another feature, fetch failure), a non-zero exit with no JSON, or `navori` missing | Hard stop. Report the `error`; no commit, push or PR. |
|
|
65
|
+
| `"status":"findings"` with `uncovered[]` not empty | The review never saw those files, so its `APPROVED` does not cover this change. Abort and send it back to the `reviewer` for a full re-review of them; do not carry on. |
|
|
66
|
+
| `"status":"findings"` with `drift[]` not empty (`kind`: `changed`, `missing`, `reappeared`) | `drift[].blob` is the approved blob: `git diff <blob-sha> <file>` shows the change (`git cat-file -p <blob-sha>` prints the approved content). An explained post-review edit goes to the `reviewer` for a **delta re-sign**; unexplained drift goes to a full re-review. |
|
|
67
|
+
| `"status":"ok"`, `"fresh":true`, `"gateKind":"full"` | Gate evidence is trusted: do not re-run the gate (see Gate below). |
|
|
68
|
+
| `"status":"ok"` with `"fresh":false` (`stale[]` lists `format`, `gate` or `inputs`), or `"gateKind":null` | No trustworthy gate evidence: you run the gate yourself (see Gate below). |
|
|
69
|
+
| `"gateKind":"scoped"` | Commit-only mode below, whatever `fresh` says. |
|
|
70
|
+
|
|
71
|
+
If the real PR base differs from `{{prTarget}}`, pass that actual base as `--target`.
|
|
88
72
|
|
|
89
73
|
<!-- The orchestrator block states the rule (every change goes through implementer -> reviewer); this is where the PR side of it is enforced. -->
|
|
90
74
|
|
|
@@ -93,18 +77,18 @@ For every live-file `DRIFT`, the JSON provides the approved blob and the exact i
|
|
|
93
77
|
**The one exception: delegation was genuinely impossible, and it was DECLARED.** The operator forbade subagents for the session, or the `Agent` tool was unavailable. The orchestrator must have said so explicitly, naming the reason. Then, and only then:
|
|
94
78
|
|
|
95
79
|
- you do NOT abort for the missing review;
|
|
96
|
-
- you MUST run
|
|
80
|
+
- you MUST run the full gate green yourself in pre-flight (see Gate below) — there is no review evidence to trust;
|
|
97
81
|
- the **PR body must state it**, in one line: what was done inline and why delegation was not possible. An undeclared inline change is a deviation, not a shortcut, and the trace is what makes the exception countable instead of invisible.
|
|
98
82
|
|
|
99
83
|
**No count, no judgement about the diff's content.** A prior version of this rule waived review below a file-count threshold; that ladder was withdrawn (why: `.claude/agents/orchestrator.md`) and has not returned. Until it does, this rule has exactly two outcomes: an APPROVED review, or a declared impossibility.
|
|
100
84
|
|
|
101
85
|
### Gate: `{{qualityGate.full}}` green before the PR
|
|
102
86
|
|
|
103
|
-
The PR gate is the FULL one,
|
|
87
|
+
The PR gate is the FULL one, not `{{qualityGate.fast}}`. Which steps sit where is a per-project decision; don't assume the fast gate covers all full steps. Three paths:
|
|
104
88
|
|
|
105
|
-
- **Reviewed:** the reviewer ran
|
|
106
|
-
- **`"fresh":false`:** no trustworthy evidence — YOU run `{{
|
|
107
|
-
- **Declared inline (no reviewer):** no review evidence either — run
|
|
89
|
+
- **Reviewed:** the reviewer ran the full gate green in Pass 2 (see `review_<feature>.md`). Skip re-running **only** when the receipt table says `"fresh":true`. The `quality-gate-pre-commit` hook re-runs `fast` on `git commit` and blocks if it fails. Any duplication or security scan beyond the quality gate is the repo's own tooling and only runs if the repo wired it in — don't assume a net that may not be there.
|
|
90
|
+
- **`"fresh":false`:** no trustworthy evidence — YOU run `{{gateRun.full}}` in pre-flight before `gh pr create`. Follow `.claude/skills/verify-before-done/SKILL.md`'s subagent row if it outlives the timeout. When the command is `navori gate <kind>`, its first stdout line is `navori gate <kind>: exit <N> — log <path>`; if that line is missing, the gate did not run: run the literal full gate.
|
|
91
|
+
- **Declared inline (no reviewer):** no review evidence either — run it yourself.
|
|
108
92
|
|
|
109
93
|
Never open the PR with the gate red.
|
|
110
94
|
|
|
@@ -119,9 +103,13 @@ Never open the PR with the gate red.
|
|
|
119
103
|
4. If you touch potentially sensitive files (`.env*`, credentials, odd lockfiles), **flag the user before staging**.
|
|
120
104
|
5. `git add <files>` (prefer explicit over `git add -A`).
|
|
121
105
|
6. `git commit -m "..."` with a HEREDOC for the body if applicable.
|
|
122
|
-
7. Validate with `git status` that the commit landed. Foreign modified files are reported as an observation and never discarded, restored or reverted.
|
|
106
|
+
7. Validate with `git status` that the commit landed. If it failed, stop with `git status` + `git log -1 --stat`; recovery is the orchestrator's or the user's call. Foreign modified files are reported as an observation and never discarded, restored or reverted.
|
|
123
107
|
8. **Consume the receipt:** `mv -f .navori/state/handoffs/receipt.txt .navori/state/handoffs/receipt.consumed.txt`. The approval is now frozen into the commit; renaming it (instead of deleting it) keeps the evidence on disk without it being rearmed — a plain `check` never reads a consumed receipt again, only the opt-in flag documented in `cierre-sesion.md` does.
|
|
124
108
|
|
|
109
|
+
## Commit-only mode
|
|
110
|
+
|
|
111
|
+
If the brief says `mode: commit-only`, or `navori receipt check` returns `"gateKind":"scoped"`, run the Commit flow through step 8 and STOP: no push, no PR, whatever `fresh` says.
|
|
112
|
+
|
|
125
113
|
## PR flow
|
|
126
114
|
|
|
127
115
|
1. **Gather context** (curated, not the whole repo). The PR diff is against `{{prTarget}}`:
|
|
@@ -141,10 +129,11 @@ Never open the PR with the gate red.
|
|
|
141
129
|
Count > 0 means your PR drags foreign commits: warn the user and suggest rebase.
|
|
142
130
|
- Ticket if applicable: branch name (e.g. `BT-1234-fix-x` → `BT-1234`) or first commit.
|
|
143
131
|
- `.navori/state/handoffs/impl_<feature>.md` — non-obvious decisions.
|
|
132
|
+
- **Spec deliveries** (only for shape `split`; read shape from `navori spec classify <spec> --json`): brief names `delivery: E<n>` and `after: <sha>`; after `git fetch`, verify `git merge-base --is-ancestor <sha> origin/{{prTarget}}` (preapproved); if it fails (squash merge), use `gh pr list --state merged --base {{prTarget}}` as a signal only and ASK the user rather than abort silently. Body carries `Spec-Delivery: <spec> E<n>/<total>`. Report `head: <sha>` at the end. Always `--base {{prTarget}}`, one PR per delivery in tasks.md order, no integration branch.
|
|
144
133
|
|
|
145
134
|
2. **Draft title and body**:
|
|
146
135
|
- **Title**: follows the configured commit style (`{{commits}}`), ≤70 chars, imperative and without a trailing period.
|
|
147
|
-
- **Body**: the repo's exact template (below). No empty sections.
|
|
136
|
+
- **Body**: the repo's exact template (below). No empty sections. For spec deliveries, include references: `Refs #<issue>` on intermediate deliveries and `Closes #<issue>` on the last; shape `single` → `Closes #<issue>`.
|
|
148
137
|
|
|
149
138
|
3. **Validate** before firing `gh`:
|
|
150
139
|
- Every claim in the title and body — path, command, count or decision — traces to the cycle's handoffs (`impl_<feature>.*`, `review_<feature>.md`), `git log`/`git diff` against the base, or the spec; nothing else backs a claim, so no inferred path, command, count or decision goes in. **No handoff on disk** → draft from the diff and the issue only. A fact you can't trace is omitted, or reported to the orchestrator — never filled in (#1001, #1028).
|
|
@@ -177,7 +166,7 @@ Never open the PR with the gate red.
|
|
|
177
166
|
|
|
178
167
|
7. **Checks — read them ONCE, never wait**: `gh pr checks <N> --json name,bucket,state,link,workflow`. `bucket: pending` (the normal case right after creating the PR) → say so in **one extra line** and stop, no retry. `bucket: fail` → name the check in that line and point to `follow-up-prs` for the diagnosis. Informative only: you never hold or revert a PR over a red check.
|
|
179
168
|
|
|
180
|
-
8. **Confirm the close actually linked** — only when the body declares one. The body is not evidence of anything; `closingIssuesReferences` is what GitHub parsed out of it:
|
|
169
|
+
8. **Confirm the close actually linked** — only when the body declares one, and warning when `{{prTarget}}` differs from the remote default branch (`git rev-parse --abbrev-ref origin/HEAD`): the issue will not auto-close, so an empty `closingIssuesReferences` is expected, not a failure. The body is not evidence of anything; `closingIssuesReferences` is what GitHub parsed out of it:
|
|
181
170
|
|
|
182
171
|
```bash
|
|
183
172
|
gh pr view <N> --json closingIssuesReferences --jq '[.closingIssuesReferences[].number]'
|
|
@@ -217,7 +206,7 @@ This is a separate contract from the PR body in the flow above: that one is the
|
|
|
217
206
|
## Test plan
|
|
218
207
|
- [ ] <concrete manual check 1>
|
|
219
208
|
- [ ] <concrete manual check 2>
|
|
220
|
-
- [ ]
|
|
209
|
+
- [ ] Full quality gate green
|
|
221
210
|
|
|
222
211
|
## References
|
|
223
212
|
- Closes #<N> (an issue of THIS repo; omit the line if there is none)
|
|
@@ -254,6 +243,8 @@ wc -c CLAUDE.md # after
|
|
|
254
243
|
## Hard rules
|
|
255
244
|
|
|
256
245
|
- ❌ A stop report (gate red, missing review, protected branch, etc.) is the last action of this cycle. Do not continue investigating, re-running the gate, or calling `git`/`gh` after emitting it. If flaky, the next invocation decides.
|
|
246
|
+
- ❌ Never write to project files through Bash (redirections, sed -i, tee, interpreter one-liners, git checkout or restore of files). When a hook blocks, the stop report is the last action; the fix is not yours.
|
|
247
|
+
- ❌ Never rewrite history: no git reset in any mode, no commit --amend, no rebase. A commit that lands wrong is a stop report with `git status` + `git log -1 --stat`; recovery is the orchestrator's or the user's call.
|
|
257
248
|
- ❌ Never push with `--force` to `{{branchBase}}` or another protected branch.
|
|
258
249
|
- ❌ Never skip hooks (`--no-verify`) unless the user explicitly asks.
|
|
259
250
|
- ❌ Never ask for a merge / approve the PR yourself. Your job ends with the URL.
|