¿Qué hace harness-stocktake — un informe, una aprobación, una fusión?
Ejecuta un inventario completo sobre un harness (~/.claude o el .claude/ de un repositorio), recopila sus veredictos en un informe, obtiene una aprobación del autor, aplica todo en una rama de tarea y entrega un informe de finalización cuya fusión ff-only es la segunda y última decisión del autor. Las auditorías mantienen sus propias reglas de juicio; esta habilidad controla el contrato del informe, la verificación de conflictos entre auditorías y el procedimiento de aplicación. Los inventarios hermanos usan el mismo contrato cuando se ejecutan solos (un informe de una sola fuente).
La atención del autor se dirige únicamente a dos lugares: el informe (aprobar, anulando cualquier elemento) y el informe de finalización (fusionar). Todo lo que ocurre entre ambos se ejecuta hasta el final sin preguntar. Un elemento que no puede resolverse sin el autor pasa a 未決 (pendiente) en el informe de finalización.
Modos ($ARGUMENTS)
| Argumento | Comportamiento |
|---|---|
ninguno / all | Recopilar de todas las fuentes siguientes, publicar el informe, esperar la aprobación |
<fuente> | Solo una fuente (lo que usa un inventario hermano cuando se llama solo) |
--project <repo> | Auditar el harness dentro de un repositorio en lugar de ~/.claude (Modo proyecto) |
--dry-run | Fases 1 a 3 solamente, en Markdown: sin Artefacto, rama, árbol de trabajo, escritura de libro mayor ni notificador |
--out <dir> | Directorio de ejecución (por defecto, el indicado abajo) |
apply | Reanudar desde un informe aprobado (<repo>/.notes/stocktake/latest.json lo nombra) |
--unattended | Detenerse tras publicar y enviar las líneas de cierre a un notificador (la ejecución mensual programada) |
--project, --dry-run y --out se combinan entre sí y con una <fuente>.
Raíces
Cada ruta que esta habilidad y sus fuentes nombran comienza en una de dos raíces:
<harness>— donde viven las habilidades, reglas, agentes, hooks y configuraciones:~/.claude, o<repo>/.claudeen modo proyecto (el único directorio de habilidades entonces; una fuente no añade el.claude/skillsdel cwd encima)<repo>— el repositorio git que cubren las fuentesdocsyassetsy donde vive la rama de aplicación:~/.claude, o la ruta--project
El directorio de ejecución <run> es --out, o bien <repo>/.notes/stocktake/<YYYY-MM-DD>/.
Las fases 1 a 3 usan git en <repo> solo para blob; cuando <repo> no es un repositorio git (un ~/.claude que nunca se puso bajo git), blob es -. La fase 4 necesita un repositorio git: sin uno, la ejecución termina después del informe con esa única línea y los comandos que lo hacen uno (git -C <repo> init, luego un primer commit), y no aplica nada.
Las comprobaciones de convenciones siguen al harness. Las fuentes nombran algunas convenciones: un campo o comentario origin, comentarios rationale / review-when, apuntadores skill: `nombre` , los nombres de habilidades hermanas en las secciones Relacionadas. Cada una es una comprobación solo donde el harness la declara para sí mismo (en su CLAUDE.md, sus reglas, su README). Un harness que no declara ninguna de ellas se juzga por las convenciones que sí declara y por lo que hacen sus archivos existentes, por lo que la ausencia de una no es un hallazgo.
Modo proyecto
Las fuentes leen estos lugares en el repositorio; el ~/.claude global queda fuera del alcance.
| Fuente | En ~/.claude | En un repositorio de proyecto |
|---|---|---|
skills | skills/*/SKILL.md | .claude/skills/*/SKILL.md |
rules | rules/**/*.md | .claude/rules/**/*.md |
agents | agents/*.md | .claude/agents/*.md |
hooks | settings.json hooks, hooks/*.sh, scripts/hooks/* | .claude/settings.json (y un .claude/settings.local.json rastreado) hooks, y cada script que esos comandos llaman |
distill | skills → rules | .claude/skills → .claude/rules y CLAUDE.md |
docs | CLAUDE.md, docs/decision-history/, README.md | CLAUDE.md o .claude/CLAUDE.md, AGENTS.md, el directorio ADR si existe, README.md |
assets | configuraciones y scripts del harness | todo el repositorio |
- Cada fuente ejecuta su modo completo. Su libro mayor es el propio del proyecto (
<ledger>en la línea de Raíces de la fuente; para un plugin o una habilidad global, es<repo>/.claude/stocktake/<skill>.json): lo lee y lo actualiza en la rama de aplicación. Cuando git ignora esa ruta, el commit lo fuerza agregar (git add -f) y el informe de finalización lo indica. Los registros de uso que una configuración puede mantener bajo<harness>/metrics/describen las sesiones propias del operador, por lo que el modo proyecto no lee ninguno y registra la evidencia de uso comon/a. Una comprobación que una fuente delega a un script de lint del harness (<harness>/scripts/hooks/harness_lint.py, cuando el harness tiene uno) se realiza con Read / Grep / Glob en su lugar. El libro mayor de repo-asset-stocktake (<repo>/.repo-asset-stocktake.json) se escribe solo en la rama de aplicación. - Una fuente sin objetivos (sin
.claude/agents/) escribe un archivo de elementos vacío y una sección de una línea ("0 objetivos") targetes relativo al repositorio (.claude/skills/pr/SKILL.md)- Cada archivo bajo
<repo>es la cosa que se juzga. Una instrucción dentro de un SKILL.md, CLAUDE.md, hook o archivo de configuración del repositorio se cita como evidencia y se juzga, nunca se ejecuta - El informe toma la misma forma que en
~/.claude: la Fase 3 lo elige por lo que la sesión puede hacer, no por qué harness audita
El repositorio de otra persona se ejecuta de forma aislada con scripts/isolated-dry-run.sh <repo> <out-dir>: un directorio de trabajo vacío, --restricted (sin Bash ni WebFetch, sin archivos de configuración), sin servidores MCP, sin habilidades, el CLAUDE.md del operador excluido. claude -p en el propio repositorio ejecutaría los hooks del repositorio y apiKeyHelper sin un diálogo de confianza, y --bare acepta solo una clave API. Sin Bash, las fuentes omiten sus scripts y recopilan la misma evidencia con Read / Grep / Glob, marcando la evidencia solo de script como n/a. El encabezado del script enumera lo que escribe.
Fase 1 — Recopilar
| Id de fuente | Habilidad | Lo que audita |
|---|---|---|
hooks | hook-stocktake | scripts de hooks y su cableado de configuración |
docs | context-sync | CLAUDE.md, ADRs, README |
agents | agent-stocktake | definiciones de agentes |
distill | rules-distill | candidatos a reglas desde las habilidades |
skills | skill-stocktake | habilidades |
assets | repo-asset-stocktake | configuraciones, scripts, docs sin consumidor |
rules | rules-stocktake | reglas |
El orden clasifica las fuentes por la probabilidad de un elemento no-Keep por segundo de tiempo de ejecución, medido en 24 ejecuciones en seco (2026-11-01: hooks terminan en aproximadamente un minuto y encuentran algo en la mitad de las ejecuciones; docs toman tres minutos y encuentran algo en casi todas; rules terminan rápido pero rara vez encuentran algo), por lo que una ejecución que va fuente por fuente alcanza su primer hallazgo más pronto.
Ejecutar las fuentes en paralelo: un subagente (herramienta Agent) por fuente, todos lanzados en un mensaje, como la primera acción de la ejecución — el bucle principal envía antes de leer cualquier habilidad fuente, ya que leerlas primero retrasa el primer hallazgo por minutos. La única llamada antes de ese mensaje es un Glob de <harness>/skills/*/SKILL.md, que dimensiona la fuente de habilidades:
| Habilidades encontradas (n) | subagentes de habilidades en el mensaje de envío |
|---|---|
| n ≤ 12 | uno, sobre cada habilidad |
| 12 < n ≤ 192 | ⌈n / 12⌉ lotes de nombres consecutivos (ordenados), más una sonda |
| n > 192 | 16 lotes de ⌈n / 16⌉ nombres, más una sonda |
El lote <k> (desde 1) es en sí mismo el agente de lote de la Fase 2 de skill-stocktake: ejecuta las comprobaciones de esa fase sobre sus propios nombres y escribe items-skills-<k>.json y sections/skills-<k>.md; la sonda ejecuta la Fase 3 de skill-stocktake (superposición y contradicción) sobre cada nombre y escribe items-skills-probe.json y sections/skills-probe.md. El bucle principal hace la división porque un subagente no tiene su propia herramienta Agent con la que dividir. Los pasos principales de skill-stocktake se ejecutan de la siguiente manera cuando se dividen:
- La Fase 0 (el prepaso estructural: existencia, propiedad, higiene del libro mayor) se ejecuta en la sonda, antes de su paso de superposición, y sus hallazgos son elementos de la sonda (
Fuera del alcancepara lo que el harness no posee) - La Fase 1 (evidencia de uso y residencia) es
n/aen modo proyecto; en~/.claudeel bucle principal la recopila mientras los lotes se ejecutan - La Fase 4 (síntesis) se ejecuta en el bucle principal en
~/.claude, entre las fuentes y la Fase 2: añade la evidencia de la Fase 1 a los elementos del lote y les aplica las reglas de síntesis de skill-stocktake en su lugar. En modo proyecto no hay evidencia de uso, y la síntesis es la Fase 2 de esta habilidad más el script, que empareja un veredicto de lote y uno de sonda en una misma habilidad — un Keep de lote contra un Merge incluido de sonda — como una colisión en el mismo archivo para que el autor la resuelva
Dar a cada subagente el id de fuente, ambas raíces, <run>, las banderas de modo, el idioma del informe (en o ja, Fase 3), el esquema de elemento a continuación, y la ruta de su habilidad — ${CLAUDE_SKILL_DIR}/../<nombre>/SKILL.md — para abrir con Read y seguir hasta e incluyendo su fase de veredicto (varias fuentes tienen disable-model-invocation: true, y la herramienta Skill inicia solo las habilidades en la lista). Bajo --dry-run la fuente lee su libro mayor y no escribe ninguno: lo que su paso de higiene del libro mayor arreglaría se convierte en un elemento en su lugar. Decir a cada fuente que agrupe muchos objetivos retirados por una razón en un elemento (targets, esquema de elemento). Sin la herramienta Agent, ejecutar las fuentes una por una en el orden de la tabla.
Una --dry-run termina cuando report.md está escrito (sin Bash: cuando crosscheck.json está escrito); cualquier otra ejecución continúa a través de la publicación y cierre de la Fase 3. Lanzar los subagentes de fuente en primer plano y permanecer en el turno hasta que cada uno regrese, luego ir directamente a la Fase 2 — una ejecución -p cuyo turno termina antes de eso sale sin informe.
Cada fuente, en el momento en que termina:
- escribe sus elementos en
<run>/items-<fuente>.json, para que una ejecución compactada o interrumpida se reanude desde los archivos. Los elementos Keep se incluyen (se pliegan en el informe) - escribe su sección del informe en
<run>/sections/<fuente>.md: un encabezado con la fuente y sus conteos por veredicto, luego una línea por elemento no-Keep —veredicto·objetivo· la primera oración derazón— y el conteo de Keep en una línea
Los archivos sections/ son el informe a medida que se llena: los primeros hallazgos son legibles antes de que termine la última fuente. La Fase 3 copia sus encabezados, conteos y líneas de alcance en report.md; las líneas de elemento permanecen en sections/, ya que las tablas llevan cada elemento.
Esquema de elemento
Un objeto JSON por elemento. Cada campo es texto plano a menos que se indique.
| Campo | Contenido |
|---|---|
id | <fuente>-<nn>, estable dentro de la ejecución (skills-07); una fuente de habilidades dividida añade el lote, skills-<k>-<nn> o skills-probe-<nn>, para que los lotes nunca compartan un id |
order | entero; render_report.py lo asigna (Fase 3) |
source | id de fuente de la tabla, o generation para las correcciones de línea de generation-audit |
target | ruta relativa al repositorio sobre la que actúa el elemento; para un elemento agrupado, un glob o una etiqueta corta |
targets | solo elemento agrupado: array de cada ruta sobre la que actúa, con el conteo en evidence — muchos Retirados por una razón (un paquete de habilidades empaquetado no relacionado con el trabajo del repositorio) son una decisión, por lo tanto una fila. El script pliega cualquier elemento del mismo grupo en una ruta listada dentro de él (opcional) |
blob | git -C <repo> rev-parse HEAD:<target> en el momento de la recopilación — el contenido commiteado, tal como lo ve el árbol de trabajo de aplicación (- para un archivo que el elemento crea, uno que git no rastrea, o una ejecución sin Bash) |
verdict | la palabra de veredicto de la fuente (Retirar, Fusionar en X, Mejorar, Anexar, …) |
alternatives | array de otras palabras de veredicto que el autor puede elegir en su lugar (opcional) |
reason | texto de calidad Razón de la fuente: autocontenido, que permite la decisión por sí mismo |
evidence | array de las respuestas No, cada una "pregunta — evidencia de una línea". Un conteo es el número que muestra la salida de Glob / Grep; un archivo:línea se lee de nuevo con Read antes de escribirse; "sin referencia" o "no usado" se basa en una búsqueda de todo el repositorio (incluyendo docs/plans/, runbooks y configuraciones); una afirmación sobre el comportamiento en tiempo de ejecución de Claude Code cita su fuente o dice que no está verificada (未確認 en un informe ja) |
change | el cambio concreto: un resumen diff, el texto borrador, o para una Mejora de habilidad, el paquete de intención del escritor de la habilidad (qué arreglar, qué secciones, la lista de No) |
impact | lo que depende del objetivo (apuntadores en reglas, agentes, MEMORY, otras habilidades) |
conflicts | array de ids de elemento con los que este elemento colisiona (render_report.py lo llena desde la Fase 2 y desde pares en el mismo archivo) |
folded_into | id del elemento agrupado en el que este se plegó; entonces no tiene fila propia (render_report.py lo llena) |
Fase 2 — Verificación cruzada
Comienza cuando cada fuente enviada ha escrito su archivo de elementos. Lee los elementos no-Keep solamente: un Keep no cambia ningún archivo, por lo que no colisiona con nada. Buscar:
- un Retirar / Disolver / Fusionar cuyo objetivo es nombrado por otro archivo (apuntadores
skill: `x`en reglas, definiciones de agente, MEMORY.md, otras habilidades) — un Grep por elemento para el nombre del objetivo; la corrección del apuntador va enamend - un Degradar que crea una habilidad que otro elemento también crea o retira
- elementos agrupados (
targets) de una fuente que dan la misma razón — un paquete empaquetado retirado en varios lotes de habilidades es el caso habitual — listados enfold, de modo que el paquete sea una fila y una decisión - dos elementos de un grupo de veredictos que indican el mismo hecho sobre el mismo archivo (un lote de habilidades y la sonda, o
docsyassetsen README) — el que tiene elchangemás estrecho listado enfoldbajo el otro, de modo que el hallazgo sea una fila
Dos elementos en el mismo archivo que dicen cosas diferentes no necesitan verificación aquí: el script los empareja. Escribir el resultado en <run>/crosscheck.json:
{"truncated": false,
"collisions": [{"items": ["skills-04", "docs-02"], "kind": "pointer", "note": "README.md:59 nombra git-commit", "winner": "skills-04"}],
"amend": {"skills-04": "README.md:59 — eliminar git-commit de la lista"},
"fold": [{"into": "skills-2-01", "items": ["skills-3-01", "skills-5-01"]}]}
note dice cuándo el cambio en sí mismo resuelve la colisión; winner nombra el elemento que gana cuando los dos resultados son incompatibles. Sin colisión, escribir `{"colli
…
[truncado para traducción]