@nac3/forge-cli 1.23.7 → 1.24.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/dist/bin/yf.js +0 -0
- package/dist/chat/claude.d.ts +8 -0
- package/dist/chat/claude.d.ts.map +1 -1
- package/dist/chat/claude.js.map +1 -1
- package/dist/chat/claude_cli.d.ts +23 -0
- package/dist/chat/claude_cli.d.ts.map +1 -1
- package/dist/chat/claude_cli.js +76 -2
- package/dist/chat/claude_cli.js.map +1 -1
- package/dist/chat/doctrine_digest.d.ts.map +1 -1
- package/dist/chat/doctrine_digest.js +2 -1
- package/dist/chat/doctrine_digest.js.map +1 -1
- package/dist/chat/server.d.ts.map +1 -1
- package/dist/chat/server.js +11 -0
- package/dist/chat/server.js.map +1 -1
- package/dist/chat/tools/pending.d.ts +11 -0
- package/dist/chat/tools/pending.d.ts.map +1 -1
- package/dist/chat/tools/pending.js +55 -8
- package/dist/chat/tools/pending.js.map +1 -1
- package/dist/chat/tools/shell.d.ts +39 -4
- package/dist/chat/tools/shell.d.ts.map +1 -1
- package/dist/chat/tools/shell.js +167 -7
- package/dist/chat/tools/shell.js.map +1 -1
- package/dist/chat/tools/urazuke.d.ts.map +1 -1
- package/dist/chat/tools/urazuke.js +8 -5
- package/dist/chat/tools/urazuke.js.map +1 -1
- package/dist/chat/urazuke_section.d.ts +26 -4
- package/dist/chat/urazuke_section.d.ts.map +1 -1
- package/dist/chat/urazuke_section.js +115 -9
- package/dist/chat/urazuke_section.js.map +1 -1
- package/dist/commands/pending.d.ts.map +1 -1
- package/dist/commands/pending.js +116 -12
- package/dist/commands/pending.js.map +1 -1
- package/dist/commands/urazuke.d.ts +3 -0
- package/dist/commands/urazuke.d.ts.map +1 -1
- package/dist/commands/urazuke.js +80 -3
- package/dist/commands/urazuke.js.map +1 -1
- package/dist/core/ascii_purity.d.ts +69 -0
- package/dist/core/ascii_purity.d.ts.map +1 -0
- package/dist/core/ascii_purity.js +141 -0
- package/dist/core/ascii_purity.js.map +1 -0
- package/dist/core/battery_stamp.d.ts +85 -0
- package/dist/core/battery_stamp.d.ts.map +1 -0
- package/dist/core/battery_stamp.js +237 -0
- package/dist/core/battery_stamp.js.map +1 -0
- package/dist/core/ci_gaps.d.ts +129 -0
- package/dist/core/ci_gaps.d.ts.map +1 -0
- package/dist/core/ci_gaps.js +352 -0
- package/dist/core/ci_gaps.js.map +1 -0
- package/dist/core/doc_citations.d.ts +133 -0
- package/dist/core/doc_citations.d.ts.map +1 -0
- package/dist/core/doc_citations.js +271 -0
- package/dist/core/doc_citations.js.map +1 -0
- package/dist/docs/doctrine/urazuke.md +173 -2
- package/dist/nac3/internal_manifest.d.ts.map +1 -1
- package/dist/nac3/internal_manifest.js +28 -2
- package/dist/nac3/internal_manifest.js.map +1 -1
- package/dist/pending/store.d.ts +29 -0
- package/dist/pending/store.d.ts.map +1 -1
- package/dist/pending/store.js +51 -1
- package/dist/pending/store.js.map +1 -1
- package/dist/pending/types.d.ts +23 -0
- package/dist/pending/types.d.ts.map +1 -1
- package/dist/pending/types.js.map +1 -1
- package/dist/telemetry/usage.d.ts +18 -0
- package/dist/telemetry/usage.d.ts.map +1 -1
- package/dist/telemetry/usage.js +16 -1
- package/dist/telemetry/usage.js.map +1 -1
- package/dist/urazuke/announce.d.ts +7 -0
- package/dist/urazuke/announce.d.ts.map +1 -1
- package/dist/urazuke/announce.js +20 -0
- package/dist/urazuke/announce.js.map +1 -1
- package/dist/urazuke/catalog.d.ts +1 -1
- package/dist/urazuke/catalog.d.ts.map +1 -1
- package/dist/urazuke/catalog.js.map +1 -1
- package/dist/urazuke/close_gate.d.ts +31 -4
- package/dist/urazuke/close_gate.d.ts.map +1 -1
- package/dist/urazuke/close_gate.js +70 -13
- package/dist/urazuke/close_gate.js.map +1 -1
- package/dist/urazuke/current.d.ts +28 -0
- package/dist/urazuke/current.d.ts.map +1 -1
- package/dist/urazuke/current.js +18 -5
- package/dist/urazuke/current.js.map +1 -1
- package/dist/urazuke/cycle.d.ts +3 -0
- package/dist/urazuke/cycle.d.ts.map +1 -1
- package/dist/urazuke/cycle.js +5 -3
- package/dist/urazuke/cycle.js.map +1 -1
- package/dist/urazuke/evidence.d.ts +14 -1
- package/dist/urazuke/evidence.d.ts.map +1 -1
- package/dist/urazuke/evidence.js +88 -2
- package/dist/urazuke/evidence.js.map +1 -1
- package/dist/urazuke/evidence_env.d.ts +78 -0
- package/dist/urazuke/evidence_env.d.ts.map +1 -0
- package/dist/urazuke/evidence_env.js +341 -0
- package/dist/urazuke/evidence_env.js.map +1 -0
- package/dist/urazuke/freeze.d.ts.map +1 -1
- package/dist/urazuke/freeze.js +16 -9
- package/dist/urazuke/freeze.js.map +1 -1
- package/dist/urazuke/gate.d.ts +48 -0
- package/dist/urazuke/gate.d.ts.map +1 -1
- package/dist/urazuke/gate.js +251 -25
- package/dist/urazuke/gate.js.map +1 -1
- package/dist/urazuke/gates_data.d.ts +30 -3
- package/dist/urazuke/gates_data.d.ts.map +1 -1
- package/dist/urazuke/gates_data.js +51 -5
- package/dist/urazuke/gates_data.js.map +1 -1
- package/dist/urazuke/gates_pull.d.ts +40 -0
- package/dist/urazuke/gates_pull.d.ts.map +1 -1
- package/dist/urazuke/gates_pull.js +118 -8
- package/dist/urazuke/gates_pull.js.map +1 -1
- package/dist/urazuke/manual_cases.d.ts +11 -1
- package/dist/urazuke/manual_cases.d.ts.map +1 -1
- package/dist/urazuke/manual_cases.js +1 -0
- package/dist/urazuke/manual_cases.js.map +1 -1
- package/dist/urazuke/overrides.d.ts +107 -0
- package/dist/urazuke/overrides.d.ts.map +1 -0
- package/dist/urazuke/overrides.js +128 -0
- package/dist/urazuke/overrides.js.map +1 -0
- package/dist/urazuke/probes.d.ts.map +1 -1
- package/dist/urazuke/probes.js +51 -0
- package/dist/urazuke/probes.js.map +1 -1
- package/dist/urazuke/profiles.d.ts +135 -0
- package/dist/urazuke/profiles.d.ts.map +1 -0
- package/dist/urazuke/profiles.js +470 -0
- package/dist/urazuke/profiles.js.map +1 -0
- package/dist/urazuke/receipt_audit.d.ts +67 -0
- package/dist/urazuke/receipt_audit.d.ts.map +1 -0
- package/dist/urazuke/receipt_audit.js +103 -0
- package/dist/urazuke/receipt_audit.js.map +1 -0
- package/dist/urazuke/receipts.d.ts +22 -0
- package/dist/urazuke/receipts.d.ts.map +1 -1
- package/dist/urazuke/receipts.js +44 -0
- package/dist/urazuke/receipts.js.map +1 -1
- package/dist/urazuke/report.d.ts +30 -0
- package/dist/urazuke/report.d.ts.map +1 -1
- package/dist/urazuke/report.js +39 -0
- package/dist/urazuke/report.js.map +1 -1
- package/dist/urazuke/reset.d.ts +35 -0
- package/dist/urazuke/reset.d.ts.map +1 -0
- package/dist/urazuke/reset.js +150 -0
- package/dist/urazuke/reset.js.map +1 -0
- package/dist/urazuke/retro.d.ts +5 -1
- package/dist/urazuke/retro.d.ts.map +1 -1
- package/dist/urazuke/retro.js +21 -8
- package/dist/urazuke/retro.js.map +1 -1
- package/dist/urazuke/section.d.ts.map +1 -1
- package/dist/urazuke/section.js +17 -2
- package/dist/urazuke/section.js.map +1 -1
- package/dist/urazuke/semantics.d.ts +173 -0
- package/dist/urazuke/semantics.d.ts.map +1 -0
- package/dist/urazuke/semantics.js +232 -0
- package/dist/urazuke/semantics.js.map +1 -0
- package/dist/urazuke/start.d.ts +8 -0
- package/dist/urazuke/start.d.ts.map +1 -1
- package/dist/urazuke/start.js +10 -2
- package/dist/urazuke/start.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/workflow/orchestrator.d.ts.map +1 -1
- package/dist/workflow/orchestrator.js +6 -7
- package/dist/workflow/orchestrator.js.map +1 -1
- package/docs/doctrine/urazuke.md +173 -2
- package/package.json +24 -20
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LAS CITAS A LA NADA -- la compuerta que el dueno pidio (2026-11-01).
|
|
3
|
+
*
|
|
4
|
+
* EL DEFECTO, en sus palabras: "un documento que afirma una compuerta con
|
|
5
|
+
* confianza es mas convincente que uno que falta. La ausencia se nota; la
|
|
6
|
+
* afirmacion falsa no." Van tres citas a la nada medidas en dos lotes
|
|
7
|
+
* -- `docs/PROGRAMMING_NORMS.md` citado por `.github/workflows/ci.yml` cinco
|
|
8
|
+
* meses sin existir, cuatro jobs y dos crons descritos en
|
|
9
|
+
* `docs/CI_PIPELINE.md` que nunca existieron, y un comentario de
|
|
10
|
+
* `.github/workflows/ci.yml` al que remitia `CLAUDE.md` -- y las tres
|
|
11
|
+
* describian compuertas. Esta compuerta cierra la familia: todo archivo de
|
|
12
|
+
* este repositorio citado en un documento VIGENTE tiene que existir.
|
|
13
|
+
*
|
|
14
|
+
* POR QUE EL DETECTOR ES CONSERVADOR. Una compuerta ruidosa se desactiva, y
|
|
15
|
+
* un gancho desactivado es peor que ninguno porque figura como existente
|
|
16
|
+
* (el mismo argumento con el que el dueno acoto F-15). Asi que esto NO
|
|
17
|
+
* intenta encontrar toda cita: encuentra las que son inequivocamente una
|
|
18
|
+
* afirmacion sobre ESTE repositorio HOY. Las reglas, en orden:
|
|
19
|
+
*
|
|
20
|
+
* 1. Los bloques de codigo cercados no se miran. Un `ls docs/FOO.md` de
|
|
21
|
+
* ejemplo no es una afirmacion sobre el repositorio.
|
|
22
|
+
* 2. Solo cuentan los tramos entre acentos graves y los destinos de los
|
|
23
|
+
* enlaces markdown. Una ruta en prosa suelta no se toca.
|
|
24
|
+
* 3. Con `/`: el primer segmento tiene que ser un directorio que EXISTE en
|
|
25
|
+
* la raiz y no ser generado (`dist/`, `test-results/`, `.forge/`...).
|
|
26
|
+
* La cita afirma una UBICACION, asi que se verifica tal cual.
|
|
27
|
+
* Sin `/`: es un NOMBRE, no una ubicacion, y se verifica como tal --
|
|
28
|
+
* basta que un archivo con ese nombre exista en algun lugar del
|
|
29
|
+
* repositorio. Medido: tratar `claude.ts` como archivo de la raiz daba
|
|
30
|
+
* cientos de falsos positivos, y descartarlo del todo dejaba pasar
|
|
31
|
+
* nombres que ya no existen en ninguna parte (`relay_error.ts`).
|
|
32
|
+
* 4. Nada con comodin (`*`, `?`), hueco (`<x>`, `{x}`, `$x`), dos puntos
|
|
33
|
+
* (rutas de Windows, `repo:ruta`) ni esquema (`http://`). Son formas
|
|
34
|
+
* que no afirman un archivo concreto.
|
|
35
|
+
*
|
|
36
|
+
* Y LOS DOCUMENTOS HISTORICOS NO ENTRAN, por una razon que no es comodidad:
|
|
37
|
+
* un changelog, un traspaso o un informe fechado describen el estado del
|
|
38
|
+
* repositorio EN SU FECHA, y un archivo que existia entonces y se renombro
|
|
39
|
+
* despues es historia correcta, no una cita a la nada. Medido: de 2378 citas
|
|
40
|
+
* verificables, 762 estaban muertas y la enorme mayoria vivia justamente
|
|
41
|
+
* ahi. Meterlas obligaria a una lista de permisos de cientos de entradas sin
|
|
42
|
+
* motivo real, que es la misma afirmacion sin respaldo que esto persigue. La
|
|
43
|
+
* exclusion se DECLARA (`isHistoricalDoc`) y la corrida dice cuantos
|
|
44
|
+
* documentos salteo, nunca en silencio.
|
|
45
|
+
*
|
|
46
|
+
* ASCII-only.
|
|
47
|
+
*/
|
|
48
|
+
/** Directorios de la raiz que existen pero NO son fuente: lo que hay dentro
|
|
49
|
+
* lo genera una corrida o lo escribe un producto en ejecucion, asi que un
|
|
50
|
+
* documento puede nombrarlos legitimamente sin que esten en disco. */
|
|
51
|
+
export const GENERATED_ROOTS = [
|
|
52
|
+
'dist', 'node_modules', 'test-results', 'qa_reports', 'coverage', 'build',
|
|
53
|
+
];
|
|
54
|
+
/** Extensiones que hacen que un token sin `/` cuente como cita de un nombre
|
|
55
|
+
* de archivo. Corta a proposito: un token cualquiera no es una cita. */
|
|
56
|
+
const NAME_EXT = [
|
|
57
|
+
'.md', '.json', '.yml', '.yaml', '.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs',
|
|
58
|
+
'.toml', '.sql', '.sh', '.py', '.php',
|
|
59
|
+
];
|
|
60
|
+
/** Sufijos de puntuacion que la prosa deja pegados a una ruta. */
|
|
61
|
+
function trimPunctuation(s) {
|
|
62
|
+
return s.replace(/^[('"`]+/, '').replace(/[)'"`,.;:!?]+$/, '');
|
|
63
|
+
}
|
|
64
|
+
/** La forma de la cita, o el motivo por el que no es una cita verificable. */
|
|
65
|
+
export function classifyToken(token, rootDirs) {
|
|
66
|
+
const t = token.trim();
|
|
67
|
+
if (!t)
|
|
68
|
+
return { reject: 'vacio' };
|
|
69
|
+
if (/\s/.test(t))
|
|
70
|
+
return { reject: 'tiene espacios' };
|
|
71
|
+
if (/^[a-z][a-z0-9+.-]*:\/\//i.test(t))
|
|
72
|
+
return { reject: 'es una URL' };
|
|
73
|
+
if (t.startsWith('#') || t.startsWith('mailto:'))
|
|
74
|
+
return { reject: 'es un ancla o un correo' };
|
|
75
|
+
if (/[*?<>{}$|]/.test(t))
|
|
76
|
+
return { reject: 'tiene comodin o hueco' };
|
|
77
|
+
if (t.includes(':'))
|
|
78
|
+
return { reject: 'tiene dos puntos (ruta ajena o de Windows)' };
|
|
79
|
+
if (t.includes('\\'))
|
|
80
|
+
return { reject: 'usa separador de Windows' };
|
|
81
|
+
if (t.includes('..'))
|
|
82
|
+
return { reject: 'sube de directorio' };
|
|
83
|
+
if (t.startsWith('/'))
|
|
84
|
+
return { reject: 'es absoluta' };
|
|
85
|
+
if (t.startsWith('~'))
|
|
86
|
+
return { reject: 'es del home del usuario' };
|
|
87
|
+
const clean = t.replace(/^\.\//, '').replace(/\/+$/, '');
|
|
88
|
+
if (!clean)
|
|
89
|
+
return { reject: 'vacio' };
|
|
90
|
+
const dot = clean.lastIndexOf('.');
|
|
91
|
+
const ext = dot > 0 ? clean.slice(dot).toLowerCase() : '';
|
|
92
|
+
if (clean.includes('/')) {
|
|
93
|
+
const segs = clean.split('/');
|
|
94
|
+
const first = segs[0];
|
|
95
|
+
if (!rootDirs.includes(first))
|
|
96
|
+
return { reject: 'su primer segmento no es un directorio de este repositorio' };
|
|
97
|
+
if (first.startsWith('.') && first !== '.github')
|
|
98
|
+
return { reject: 'vive en un directorio de estado local' };
|
|
99
|
+
/* Generado en CUALQUIER tramo, no solo en el primero: la salida de un
|
|
100
|
+
* build de CI (`apps/x/android/app/build/outputs/...`) la produce la
|
|
101
|
+
* corrida, asi que nombrarla no afirma un archivo en disco. */
|
|
102
|
+
if (segs.some((s) => GENERATED_ROOTS.includes(s)))
|
|
103
|
+
return { reject: 'vive en un directorio generado' };
|
|
104
|
+
return 'path';
|
|
105
|
+
}
|
|
106
|
+
if (!ext)
|
|
107
|
+
return { reject: 'no parece un archivo' };
|
|
108
|
+
if (!NAME_EXT.includes(ext))
|
|
109
|
+
return { reject: 'extension no reconocida' };
|
|
110
|
+
return 'name';
|
|
111
|
+
}
|
|
112
|
+
/** Las citas verificables de un documento markdown. */
|
|
113
|
+
export function extractCitations(md, rootDirs) {
|
|
114
|
+
const out = [];
|
|
115
|
+
const lines = md.split(/\r?\n/);
|
|
116
|
+
let fence = null;
|
|
117
|
+
for (let i = 0; i < lines.length; i++) {
|
|
118
|
+
const line = lines[i];
|
|
119
|
+
const fenceMatch = /^\s*(```+|~~~+)/.exec(line);
|
|
120
|
+
if (fenceMatch) {
|
|
121
|
+
const mark = fenceMatch[1];
|
|
122
|
+
if (fence === null)
|
|
123
|
+
fence = mark[0];
|
|
124
|
+
else if (mark[0] === fence)
|
|
125
|
+
fence = null;
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
if (fence !== null)
|
|
129
|
+
continue;
|
|
130
|
+
/* Lineas sangradas cuatro espacios: bloque de codigo indentado. */
|
|
131
|
+
if (/^ {4,}\S/.test(line) && !/^ {0,3}[-*+]/.test(line))
|
|
132
|
+
continue;
|
|
133
|
+
const tokens = [];
|
|
134
|
+
for (const m of line.matchAll(/`([^`\n]+)`/g))
|
|
135
|
+
tokens.push(m[1]);
|
|
136
|
+
for (const m of line.matchAll(/\]\(([^)\s]+)\)/g))
|
|
137
|
+
tokens.push(m[1]);
|
|
138
|
+
for (const raw of tokens) {
|
|
139
|
+
/* El ancla (`docs/X.md#seccion`) no es parte del archivo. */
|
|
140
|
+
const target0 = trimPunctuation(raw).split('#')[0];
|
|
141
|
+
const target = target0.replace(/^\.\//, '').replace(/\/+$/, '');
|
|
142
|
+
const shape = classifyToken(target, rootDirs);
|
|
143
|
+
if (typeof shape !== 'string')
|
|
144
|
+
continue;
|
|
145
|
+
if (out.some((c) => c.line === i + 1 && c.target === target))
|
|
146
|
+
continue;
|
|
147
|
+
out.push({ line: i + 1, target, raw, shape });
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return out;
|
|
151
|
+
}
|
|
152
|
+
/** Un documento que describe el estado del repositorio en su fecha, no hoy.
|
|
153
|
+
* La lista es de FORMAS de nombre, no de rutas: una lista de rutas se
|
|
154
|
+
* desactualiza con cada documento nuevo y acaba siendo una lista de
|
|
155
|
+
* permisos. */
|
|
156
|
+
export function isHistoricalDoc(rel) {
|
|
157
|
+
const p = rel.replace(/\\/g, '/');
|
|
158
|
+
const base = p.split('/').pop();
|
|
159
|
+
if (base === 'CHANGELOG.md')
|
|
160
|
+
return true;
|
|
161
|
+
/* Carpetas de contexto volcado de una sesion. */
|
|
162
|
+
if (/(^|\/)context-from-/.test(p))
|
|
163
|
+
return true;
|
|
164
|
+
if (/(^|\/)handoff\//i.test(p))
|
|
165
|
+
return true;
|
|
166
|
+
/* Nombre con fecha: un documento fechado afirma sobre su fecha. Los dos
|
|
167
|
+
* separadores se mezclan de verdad en este repositorio
|
|
168
|
+
* (`CATCHUP_PRELIMINAR_2026-06-11.md`), asi que la forma los acepta
|
|
169
|
+
* mezclados en vez de pedir uno solo. */
|
|
170
|
+
if (/[_-]\d{4}[_-]\d{2}[_-]\d{2}/.test(base))
|
|
171
|
+
return true;
|
|
172
|
+
/* Generos que son registro, no especificacion vigente. */
|
|
173
|
+
if (/^(HANDOFF|SESSION|SESION|AUTOPILOT|CODE_REVIEW|INFORME|PROMPT|RETRO|SNAPSHOT|PENDING_REGISTRY_SNAPSHOT)[_-]/i.test(base))
|
|
174
|
+
return true;
|
|
175
|
+
return false;
|
|
176
|
+
}
|
|
177
|
+
/** Las citas de un archivo de MAQUINARIA (workflow, lefthook, manifiesto):
|
|
178
|
+
* ahi una ruta no viene entre acentos graves, viene en un comentario o en
|
|
179
|
+
* un valor. Se buscan por forma y se pasan por el mismo clasificador.
|
|
180
|
+
*
|
|
181
|
+
* Esto NO se usa sobre fuentes TypeScript a proposito: un especificador de
|
|
182
|
+
* import (`./tools/x.js`) tiene forma de ruta, es relativo al archivo y
|
|
183
|
+
* apunta al transpilado, asi que daria cientos de falsos positivos.
|
|
184
|
+
* Medido antes de acotar: 307.
|
|
185
|
+
*
|
|
186
|
+
* Y aca la cita tiene que llevar EXTENSION. En un archivo de maquinaria no
|
|
187
|
+
* hay acentos graves que delimiten el token, asi que un tramo sin extension
|
|
188
|
+
* suele ser otra cosa con forma de ruta -- medido: `src/version\.ts` dentro
|
|
189
|
+
* de una expresion regular de `lefthook.yml` se lee como `src/version`. Las
|
|
190
|
+
* tres citas a la nada que este repositorio ya pago llevaban extension. */
|
|
191
|
+
export function extractMachineryCitations(text, rootDirs) {
|
|
192
|
+
const out = [];
|
|
193
|
+
const lines = text.split(/\r?\n/);
|
|
194
|
+
const re = /[A-Za-z0-9_.][A-Za-z0-9_./-]*\/[A-Za-z0-9_][A-Za-z0-9_./-]*/g;
|
|
195
|
+
for (let i = 0; i < lines.length; i++) {
|
|
196
|
+
for (const m of lines[i].matchAll(re)) {
|
|
197
|
+
const target = trimPunctuation(m[0]).replace(/^\.\//, '').replace(/\/+$/, '');
|
|
198
|
+
if (!/\.[a-z0-9]{1,6}$/i.test(target))
|
|
199
|
+
continue;
|
|
200
|
+
const shape = classifyToken(target, rootDirs);
|
|
201
|
+
if (shape !== 'path')
|
|
202
|
+
continue;
|
|
203
|
+
if (out.some((c) => c.line === i + 1 && c.target === target))
|
|
204
|
+
continue;
|
|
205
|
+
out.push({ line: i + 1, target, raw: m[0], shape });
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
return out;
|
|
209
|
+
}
|
|
210
|
+
/** EL ALCANCE QUE BLOQUEA, y por que es este y no "todos los documentos".
|
|
211
|
+
*
|
|
212
|
+
* Medido en este repositorio: de 1331 citas verificables en documentos
|
|
213
|
+
* vigentes, 206 apuntan a archivos que no existen -- y casi todas son
|
|
214
|
+
* correctas. El espacio `docs/` esta SOBRECARGADO: `docs/SQ.md` exige
|
|
215
|
+
* `docs/USER_MANUAL.md` al proyecto ADOPTANTE, `src/urazuke/catalog.ts`
|
|
216
|
+
* nombra `docs/GATES.md` como artefacto que produce el proyecto que corre
|
|
217
|
+
* el metodo, y `docs/worker/README.md` cita `src/relay.js` relativo a su
|
|
218
|
+
* propio componente. Prescribir rutas para otros proyectos es el negocio
|
|
219
|
+
* de este repositorio, asi que "toda ruta citada existe" es FALSO como
|
|
220
|
+
* regla general y una compuerta que lo exija pide una lista de permisos de
|
|
221
|
+
* cientos de entradas -- que es la misma afirmacion sin respaldo que esto
|
|
222
|
+
* persigue.
|
|
223
|
+
*
|
|
224
|
+
* Lo que si se puede exigir sin excepciones es este conjunto: los archivos
|
|
225
|
+
* que se leen como AUTORIDAD sobre la maquinaria de este repositorio. Es
|
|
226
|
+
* donde vivieron los tres defectos medidos y es chico y verificable. El
|
|
227
|
+
* resto se MIDE y se informa en la misma salida, nunca en silencio.
|
|
228
|
+
*
|
|
229
|
+
* Y dentro de ese conjunto bloquean solo las citas con forma de RUTA. Un
|
|
230
|
+
* nombre suelto (`nac-bridge.js`, `pilot.bundle.js` en el README) no afirma
|
|
231
|
+
* una ubicacion de este repositorio: nombra un artefacto de otro paquete.
|
|
232
|
+
* Una ruta si afirma: dice "esta aca". Esa es la afirmacion que las tres
|
|
233
|
+
* citas a la nada hicieron y la que esto verifica. */
|
|
234
|
+
export const AUTHORITY_SCOPE = [
|
|
235
|
+
'CLAUDE.md',
|
|
236
|
+
'README.md',
|
|
237
|
+
'PROJECT.md',
|
|
238
|
+
'docs/PROGRAMMING_NORMS.md',
|
|
239
|
+
'docs/CI_PIPELINE.md',
|
|
240
|
+
'lefthook.yml',
|
|
241
|
+
'package.json',
|
|
242
|
+
/* mas .github/workflows/*.yml, que el script expande del disco. */
|
|
243
|
+
];
|
|
244
|
+
export function renderCitationReport(r) {
|
|
245
|
+
const out = [];
|
|
246
|
+
out.push('doc-citations [compuerta]: ' + r.authority_files + ' archivos de autoridad, '
|
|
247
|
+
+ r.authority_checked + ' citas verificadas'
|
|
248
|
+
+ (r.allowed ? ', ' + r.allowed + ' permitidas por declaracion' : '')
|
|
249
|
+
+ ', ' + r.violations.length + ' a la nada.');
|
|
250
|
+
out.push('doc-citations [relevamiento, NO bloquea]: ' + r.survey_docs
|
|
251
|
+
+ ' documentos vigentes (' + r.survey_skipped_historical + ' historicos salteados), '
|
|
252
|
+
+ r.survey_checked + ' citas, ' + r.survey_dead + ' sin archivo en disco.');
|
|
253
|
+
out.push(' El relevamiento no bloquea porque este repositorio PRESCRIBE rutas para otros');
|
|
254
|
+
out.push(' proyectos (docs/SQ.md exige docs/USER_MANUAL.md al adoptante), asi que una ruta');
|
|
255
|
+
out.push(' sin archivo no es por si misma un defecto. El numero esta a la vista para que');
|
|
256
|
+
out.push(' nadie lo descubra midiendo de nuevo.');
|
|
257
|
+
if (!r.violations.length)
|
|
258
|
+
return out.join('\n');
|
|
259
|
+
out.push('');
|
|
260
|
+
out.push('CITAS A LA NADA EN EL ALCANCE QUE BLOQUEA (' + r.violations.length + '):');
|
|
261
|
+
for (const v of r.violations) {
|
|
262
|
+
out.push(' ' + v.doc + ':' + v.line + ' -> ' + v.target
|
|
263
|
+
+ (v.shape === 'name' ? ' (no existe con ese nombre en ninguna parte)' : ' (no existe)'));
|
|
264
|
+
}
|
|
265
|
+
out.push('');
|
|
266
|
+
out.push('Un documento que afirma un archivo que no existe es peor que uno que falta:');
|
|
267
|
+
out.push('la ausencia se nota, la afirmacion falsa no. Arregla la cita, crea el archivo,');
|
|
268
|
+
out.push('o declara la excepcion con su motivo en docs/.doc-citations-allow.');
|
|
269
|
+
return out.join('\n');
|
|
270
|
+
}
|
|
271
|
+
//# sourceMappingURL=doc_citations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doc_citations.js","sourceRoot":"","sources":["../../src/core/doc_citations.ts"],"names":[],"mappings":"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"}
|
|
@@ -18,8 +18,9 @@ stations (N0..N7) first and enters the loop at step 5.
|
|
|
18
18
|
the step names exist, are not stubs, say what they must; the sizing
|
|
19
19
|
record is admissible (G9); the plan items carry a spec; the evidence
|
|
20
20
|
receipts exist. `yujin.pending.close` refuses a red step. An override
|
|
21
|
-
needs the OWNER's written `force_reason` (kept in
|
|
22
|
-
|
|
21
|
+
needs the OWNER's written `force_reason` AND its `force_kind` (kept in
|
|
22
|
+
history, counted per motive -- see "A forced close carries a TYPE");
|
|
23
|
+
never pass either on your own initiative.
|
|
23
24
|
- Evidence is a RECEIPT Forge records (command, ref, exit code, counts),
|
|
24
25
|
never your summary. "Tests pass" without a receipt is a claim.
|
|
25
26
|
- A LONG run leaves its receipt the same way. `yujin.evidence.run` blocks
|
|
@@ -35,6 +36,123 @@ stations (N0..N7) first and enters the loop at step 5.
|
|
|
35
36
|
receipt, `yujin.task.list` for a task. Two closes were reported as
|
|
36
37
|
"believed" over a receipt that existed on disk the whole time.
|
|
37
38
|
|
|
39
|
+
## When does a project EXPECT a ladder?
|
|
40
|
+
|
|
41
|
+
Written here because the condition must be findable, not inferred from the
|
|
42
|
+
source (the owner's condition on F-06, 2026-11-01): "if tomorrow a project
|
|
43
|
+
should have a ladder and does not leave that trace, the notice does not
|
|
44
|
+
come out and we are where we started. The condition has to be WRITTEN
|
|
45
|
+
where someone would look for it."
|
|
46
|
+
|
|
47
|
+
The switch being ON means **the method is available**, not **you are
|
|
48
|
+
walking it**. It is ON by default in Forge developer, so injecting the
|
|
49
|
+
step block -- or warning that it is missing -- in every project with the
|
|
50
|
+
switch on would charge ~700 characters of system prompt per turn to
|
|
51
|
+
everyone who does not use the method.
|
|
52
|
+
|
|
53
|
+
So Forge warns ("enabled and NOT arriving") only when the project leaves a
|
|
54
|
+
TRACE that it expects a ladder. Exactly three traces count, any one of
|
|
55
|
+
them is enough (`expectsLadder` in `src/chat/urazuke_section.ts`):
|
|
56
|
+
|
|
57
|
+
1. **A Urazuke workflow instance exists** for the project, open or closed
|
|
58
|
+
(`findUrazukeInstance`). This is the normal trace: `yf urazuke start` /
|
|
59
|
+
`yujin.urazuke.start` leaves it.
|
|
60
|
+
2. **The frozen copy of the gate definition** is on disk
|
|
61
|
+
(`.forge/urazuke/gates.json`, PND-165): the project pinned a version of
|
|
62
|
+
the method, so it is using it.
|
|
63
|
+
3. **The method's artifacts are in the repository**: all three of
|
|
64
|
+
`docs/WORKING_AGREEMENT.md`, `docs/SEMANTIC_TREE.md` and `docs/GATES.md`
|
|
65
|
+
exist and are not stubs (`hasMethodArtifacts` in
|
|
66
|
+
`src/urazuke/probes.ts`).
|
|
67
|
+
|
|
68
|
+
With none of the three, the turn records `reason: 'not_in_use'` and stays
|
|
69
|
+
silent. That reason is itself the trace: it is in the result of
|
|
70
|
+
`buildUrazukeSection`, so "the notice did not come out" can always be
|
|
71
|
+
answered with WHICH condition failed. If you want the ladder in a project
|
|
72
|
+
that has none of the three, open it -- `yujin.urazuke.start` -- and the
|
|
73
|
+
step prompt arrives on the next turn.
|
|
74
|
+
|
|
75
|
+
## A forced close carries a TYPE, and the type is counted
|
|
76
|
+
|
|
77
|
+
M-02, decided by the owner on 2026-11-01. A plan item ships only with its
|
|
78
|
+
receipts, and some items have no red to produce at all (documentation,
|
|
79
|
+
configuration). The answer is NOT a kind of pending that authorises
|
|
80
|
+
itself -- nothing can guarantee a code item will not be declared
|
|
81
|
+
"documentation" -- it is an honest forced close that is COUNTABLE:
|
|
82
|
+
|
|
83
|
+
- `force_reason` (the owner's prose, min 15 chars) is still mandatory, and
|
|
84
|
+
- `force_kind` is mandatory with it, from a CLOSED catalogue
|
|
85
|
+
(`src/urazuke/overrides.ts`; `yf pending close --force-kind`, or
|
|
86
|
+
`force_kind` on `yujin.pending.close`). A free-text type turns the
|
|
87
|
+
counter into a cloud of synonyms, which is not counting.
|
|
88
|
+
|
|
89
|
+
The condition that makes this worth having, in the owner's words: "the
|
|
90
|
+
typed motive has to be a NUMBER in the report. You have to be able to ask
|
|
91
|
+
how many closes were forced by `documentacion_sin_rojo_posible` and get an
|
|
92
|
+
answer. If the type exists and nobody counts it, it is the same hole with
|
|
93
|
+
a better name -- and worse, because it sounds solved."
|
|
94
|
+
|
|
95
|
+
So the override is stored as DATA on the item's history entry
|
|
96
|
+
(`history[].override = {gate, kind, missing}`), and
|
|
97
|
+
`docs/RETROSPECTIVE_<date>.md` prints one row per motive and one per gate
|
|
98
|
+
bypassed. Overrides recorded before this change are still counted, in
|
|
99
|
+
their own `sin tipo` row: discounting them would have made the total DROP
|
|
100
|
+
on the day of the fix, which is the worst way to measure a debt.
|
|
101
|
+
|
|
102
|
+
## The catalogue's file names are PROTOCOL
|
|
103
|
+
|
|
104
|
+
Decided by the owner on 2026-11-01 (M-03, measured by the Urazuke
|
|
105
|
+
experiment), as a rule of the contract and not as an error message:
|
|
106
|
+
|
|
107
|
+
**The file names the step catalogue asks for are protocol and are NOT
|
|
108
|
+
translated. The CONTENT goes in the project's language.**
|
|
109
|
+
|
|
110
|
+
So a step that names `docs/ARCHITECTURE.md` is satisfied by a file at
|
|
111
|
+
exactly that path, whose prose may be entirely in Spanish. A
|
|
112
|
+
`docs/ARQUITECTURA.md` with the identical, correct content counts as
|
|
113
|
+
ABSENT -- and the gate now says so, with that reason, every time an
|
|
114
|
+
artifact is missing (`ARTIFACT_NAMES_ARE_PROTOCOL` in
|
|
115
|
+
`src/urazuke/gate.ts`), whether or not a similar-looking neighbour is
|
|
116
|
+
found next to it.
|
|
117
|
+
|
|
118
|
+
Why not a per-language alias table, which was the other option: **an alias
|
|
119
|
+
table is a second source of truth, and a second source of truth
|
|
120
|
+
desynchronises** -- the defect this project already has on record three
|
|
121
|
+
times. (Plus the price on the Forge side: 232 artifact names to maintain in
|
|
122
|
+
two languages.) It is the same line the `language-sovereignty` doctrine
|
|
123
|
+
draws for verb ids and code identifiers: translate the EXPERIENCE, never
|
|
124
|
+
the protocol.
|
|
125
|
+
|
|
126
|
+
What was unacceptable before this was never the requirement. It was the
|
|
127
|
+
SILENCE: a file with the right content next to it, counted as absent, with
|
|
128
|
+
no written reason.
|
|
129
|
+
|
|
130
|
+
## The five statuses, and why `closed` is NOT `green`
|
|
131
|
+
|
|
132
|
+
A step carries ONE of five statuses, and two of them are easy to confuse --
|
|
133
|
+
the confusion cost a report that said 0 of 24 when three steps were closed
|
|
134
|
+
(F-07, measured by the Urazuke experiment, 2026-11-01):
|
|
135
|
+
|
|
136
|
+
| status | meaning |
|
|
137
|
+
|--------------|--------------------------------------------------------------|
|
|
138
|
+
| `closed` | the canonical task of this step IS CLOSED. Consolidated progress. The BEST state a step can be in. |
|
|
139
|
+
| `green` | the gate passes and the task is STILL OPEN: it CAN be closed, nobody closed it yet. |
|
|
140
|
+
| `red` | a check is missing. It does not close. |
|
|
141
|
+
| `owner` | nothing mechanical to check; the owner signs it. |
|
|
142
|
+
| `unmeasured` | the definition in force needs an evaluator this installation cannot measure. It does NOT close and it is NOT green. |
|
|
143
|
+
|
|
144
|
+
The two rules that follow:
|
|
145
|
+
|
|
146
|
+
1. **`closed` and `green` are disjoint.** A closed step is reported as
|
|
147
|
+
`closed`, never as `green`. So **counting `green` to measure progress
|
|
148
|
+
LOSES every closed step** -- the best ones. Progress is `closed + green`
|
|
149
|
+
(`done_or_ready`), and a summary prints BOTH numbers, never one.
|
|
150
|
+
2. **Nobody counts statuses on their own.** `summarizeLadder()` in
|
|
151
|
+
`src/urazuke/current.ts` is the only counter; the verb, the CLI, the
|
|
152
|
+
retrospective and the cyclic report all read it. A second, independent
|
|
153
|
+
count is exactly the inference the method warns against: it is how the
|
|
154
|
+
distinction gets lost again, in one consumer, silently.
|
|
155
|
+
|
|
38
156
|
## How to work inside it
|
|
39
157
|
|
|
40
158
|
1. Read the URAZUKE section: red checks are what is missing. Produce the
|
|
@@ -48,3 +166,56 @@ stations (N0..N7) first and enters the loop at step 5.
|
|
|
48
166
|
when / then" + `how_verified`) before it is implemented (step 5).
|
|
49
167
|
5. No deadlines, ever: the method fixes the order and the gates, not the
|
|
50
168
|
calendar. Speed is a consequence, not the objective.
|
|
169
|
+
|
|
170
|
+
## The profiles axis: three evaluators, and where their data lives
|
|
171
|
+
|
|
172
|
+
Added 2026-11-01 (Pieza 6, D-044). The published definition requires these
|
|
173
|
+
three on the three anchors of the construction loop, and until that day this
|
|
174
|
+
installation could not measure any of them -- so adopting the published
|
|
175
|
+
definition froze three permanently unmeasurable steps.
|
|
176
|
+
|
|
177
|
+
| evaluator | step | what it measures |
|
|
178
|
+
|---|---|---|
|
|
179
|
+
| `pendings_profiles` | 5 | every open plan item that touches a screen declares its convergence group, the profiles that have it, and ONE acceptance criterion per profile |
|
|
180
|
+
| `profile_matrix` | 8 | the matrix is consistent, the navigation is DERIVED from it, and each profile's e2e reaches exactly its row |
|
|
181
|
+
| `manual_cases_per_profile` | 10 | every manual case ran once per affected profile, derived from the matrix |
|
|
182
|
+
|
|
183
|
+
The data, and the one rule that explains every choice -- **the matrix is the
|
|
184
|
+
producer**:
|
|
185
|
+
|
|
186
|
+
- `docs/PROFILE_MATRIX.md` carries the four columns of Annex H B2 and
|
|
187
|
+
nothing else: functionality, home, profiles, entry point. The table is
|
|
188
|
+
found by HEADER, so the column order is free.
|
|
189
|
+
- `.forge/profile-navigation.json` is the generated navigation, and it
|
|
190
|
+
declares a fingerprint. The evaluator **recomputes** that fingerprint from
|
|
191
|
+
the matrix and compares; it never reads the declared one and compares it
|
|
192
|
+
with itself, which would pass any file. The fingerprint is
|
|
193
|
+
self-describing (algorithm, encoding, canonical form, covers, excludes) --
|
|
194
|
+
one that cannot be reproduced from outside is not evidence.
|
|
195
|
+
- `.forge/profile-reachability.json` lists, per profile, what the e2e
|
|
196
|
+
**reached** (not what it attempted) and the id of its receipt. The
|
|
197
|
+
evaluator contrasts that id against the receipt registry: an artifact
|
|
198
|
+
whose receipt the registry does not have is prose.
|
|
199
|
+
- the two directions of "neither less nor more" fail DIFFERENTLY and never
|
|
200
|
+
merge into one red: reaching **less** than the row is a MISSING piece
|
|
201
|
+
(construction incomplete); reaching **more** is an AUTHORIZATION defect,
|
|
202
|
+
high severity by written definition. If the message does not name the
|
|
203
|
+
class, the reader under-rates it.
|
|
204
|
+
- the per-profile pending fields live in `PendingSpec` **in the registry**,
|
|
205
|
+
not in `docs/PENDING.md` (owner's decision, 2026-11-01): a gate cannot
|
|
206
|
+
measure prose, `pendings_spec` already measures there, and two sources for
|
|
207
|
+
the same datum age in opposite directions. The document is generated from
|
|
208
|
+
the registry or cites it. Write them with
|
|
209
|
+
`yf pending add --touches-screen --convergence-group ... --row-profile ...
|
|
210
|
+
--accept-for perfil=criterio`.
|
|
211
|
+
- `touches_screen` is a THREE-state field: absent means "not declared" and
|
|
212
|
+
the evaluator reports it as such -- never as "does not touch". Not looking
|
|
213
|
+
is not the same as nothing being there.
|
|
214
|
+
- the manual case ledger carries `functionality` (the link the method's
|
|
215
|
+
"derived from the matrix" implies): `yf urazuke rules sign <rule> passed
|
|
216
|
+
--by <name> --profile <id> --functionality "<row>"`. A case with a single
|
|
217
|
+
profile does NOT count as executed when its row has more.
|
|
218
|
+
|
|
219
|
+
To measure what adopting the published definition would cost BEFORE
|
|
220
|
+
adopting it: `yf urazuke rules show --published` (read only, writes
|
|
221
|
+
nothing, never blocks) and `yf urazuke gates pull`.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"internal_manifest.d.ts","sourceRoot":"","sources":["../../src/nac3/internal_manifest.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"internal_manifest.d.ts","sourceRoot":"","sources":["../../src/nac3/internal_manifest.ts"],"names":[],"mappings":"AAsBA,MAAM,MAAM,UAAU,GAClB,cAAc,GACd,SAAS,GACT,mBAAmB,GACnB,aAAa,GACb,eAAe,GACf,oBAAoB,CAAC;AAEzB,MAAM,MAAM,cAAc,GACtB,MAAM,GACN,KAAK,GACL,YAAY,GACZ,SAAS,GACT,SAAS,GACT,cAAc,GACd,KAAK,CAAC;AAEV,MAAM,MAAM,QAAQ,GAChB,QAAQ,GACR,MAAM,GACN,QAAQ,GACR,QAAQ,GACR,OAAO,GACP,YAAY,GACZ,SAAS,GACT,QAAQ,GACR,YAAY,CAAC;AAEjB,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,QAAQ,CAAC;IACf,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE;QACzB,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC;QAC3D,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;QACzB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,SAAS,CAAC,EAAE,MAAM,CAAC;QAKnB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC,CAAC;IACH,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,cAAc,CAAC;IACvB,MAAM,EAAE,UAAU,CAAC;IACnB,YAAY,EAAE,cAAc,EAAE,CAAC;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB;;;4BAGwB;IACxB,YAAY,EAAE,OAAO,GAAG,QAAQ,CAAC;IACjC;;;;;;qCAMiC;IACjC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,QAAQ,EAAE,CAAC;CACnB;AAw8GD,wBAAgB,QAAQ,IAAI,YAAY,CAOvC;AAED,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAGzD;AAED;gEACgE;AAChE,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAO9D;AAED;;;uDAGuD;AACvD,wBAAgB,YAAY,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,GAAG,IAAI,CA2CzF;AAED;;sEAEsE;AACtE,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,SAAI,GAAG,MAAM,EAAE,CAO/D"}
|
|
@@ -14,6 +14,11 @@
|
|
|
14
14
|
* ASCII-only.
|
|
15
15
|
*/
|
|
16
16
|
import { VERSION as FORGE_VERSION } from '../version.js';
|
|
17
|
+
/* M-02: el catalogo de motivos de un cierre forzado se declara UNA vez
|
|
18
|
+
* (src/urazuke/overrides.ts) y el schema del verbo lo refleja. Repetir la
|
|
19
|
+
* lista aca es la segunda fuente de verdad que se desincroniza el dia que
|
|
20
|
+
* se agregue un motivo. */
|
|
21
|
+
import { OVERRIDE_KIND_NAMES } from '../urazuke/overrides.js';
|
|
17
22
|
/* ============================================================
|
|
18
23
|
* Verb declarations
|
|
19
24
|
*
|
|
@@ -49,7 +54,7 @@ const VERBS = [
|
|
|
49
54
|
type: 'object',
|
|
50
55
|
properties: {
|
|
51
56
|
title: { type: 'string', description: 'Tab header label. Max 80 chars.', minLength: 1, maxLength: 80 },
|
|
52
|
-
kind: { type: 'string', description: 'Render mode. doc = DOCUMENTO (reporte/analisis/spec/ARQUITECTURA/
|
|
57
|
+
kind: { type: 'string', description: 'Render mode. doc = DOCUMENTO (reporte/analisis/spec/ARQUITECTURA/DISENO): content = HTML por DEFAULT (h1/h2/h3, p, ul/ol, table, blockquote, pre, strong/em; NADA de <script>/<style>/JS -- se sanitiza), se renderiza dentro de una hoja con el look Yujin. Usa HTML siempre para documentos de arquitectura, diseno y specs (formato rico). Tambien acepta markdown como fallback. Usalo por DEFAULT para cualquier documento que generes. bpmn (o flow) = DIAGRAMA DE PROCESO BPMN 2.0 -- USALO cuando el usuario pide un FLUJO / flow / proceso / circuito de negocio (NO el grafo de nodos). content = JSON {lanes?:[{id,label}], nodes:[{id, type, label, lane?, gateway?}], flows:[{from, to, label?}]}; type en startEvent|endEvent|intermediate|task|userTask|serviceTask|scriptTask|sendTask|receiveTask|gateway; gateway en exclusive|parallel|inclusive. graph = grafo de nodos dinamico (relaciones/dependencias, NO procesos): content = JSON {nodes:[{id,label,weight,kind,detail}], edges:[{from,to,kind,label}]}; md/markdown = texto; code/table/tree. html = mini-navegador en iframe sandbox. app = mini-app con JS arbitrario (viz/herramienta) en iframe sandbox aislado; usa app solo si necesitas JS real, sino doc.', enum: ['code', 'table', 'markdown', 'md', 'html', 'app', 'bpmn', 'flow', 'document', 'doc', 'tree', 'graph'] },
|
|
53
58
|
content: { type: 'string', description: 'Body text. Max 100000 chars. Para kind=graph: JSON {nodes,edges}. Para kind=bpmn/flow: JSON {lanes?,nodes,flows} (ver kind).', minLength: 1, maxLength: 100000 },
|
|
54
59
|
language: { type: 'string', description: 'For kind=code: language hint.', maxLength: 40 },
|
|
55
60
|
},
|
|
@@ -2962,6 +2967,19 @@ const VERBS = [
|
|
|
2962
2967
|
blocker_who: { type: 'string', maxLength: 80 },
|
|
2963
2968
|
priority: { type: 'number', description: '0..100 (0 = critical, 100 = nice-to-have). Default 50.' },
|
|
2964
2969
|
related_doc: { type: 'string', maxLength: 200 },
|
|
2970
|
+
/* M-01 (experimento Urazuke, 2026-11-01) -- EL SPEC, por verbo.
|
|
2971
|
+
*
|
|
2972
|
+
* La compuerta del peldano 5 (gate.ts, evaluador `plan`) falla
|
|
2973
|
+
* cuando hay pendientes del plan SIN spec. El CLI podia escribirlo
|
|
2974
|
+
* (`yf pending add --acceptance ... --how-verified ...`) y el verbo
|
|
2975
|
+
* NO, asi que un agente que registraba un hallazgo durante el
|
|
2976
|
+
* recorrido volvia ROJO un peldano ya cerrado y no tenia manera de
|
|
2977
|
+
* arreglarlo. El metodo terminaba castigando la honestidad: el
|
|
2978
|
+
* camino barato era no anotar el hallazgo. Aparecio CUATRO veces en
|
|
2979
|
+
* la corrida. La forma es la del CLI, no una nueva. */
|
|
2980
|
+
acceptance: { type: 'array', description: 'Urazuke peldano 5: criterios de aceptacion, uno por entrada, en forma "dado / cuando / entonces". Sin esto el item cuenta como SIN spec y pone el peldano 5 en rojo.' },
|
|
2981
|
+
how_verified: { type: 'string', maxLength: 2000, description: 'Urazuke peldano 5: como se verifica SIN leer codigo. Va junto con acceptance: la compuerta exige los dos.' },
|
|
2982
|
+
flows: { type: 'array', description: 'Urazuke: los flujos de usuario que toca el item (los que el e2e del peldano 8 tiene que recorrer).' },
|
|
2965
2983
|
},
|
|
2966
2984
|
required: ['title', 'category'],
|
|
2967
2985
|
},
|
|
@@ -3000,7 +3018,8 @@ const VERBS = [
|
|
|
3000
3018
|
reason: { type: 'string', enum: ['shipped', 'obsoleted', 'duplicate', 'rejected'] },
|
|
3001
3019
|
commit: { type: 'string', description: 'Git SHA that delivered the close. The affected sources are derived from it.', maxLength: 80 },
|
|
3002
3020
|
resolution: { type: 'string', description: 'How it was resolved -- the closing history summary (what was done across the evolutive/corrective cycle). Saved as a history entry AND as the technical summary of the implementation record.', maxLength: 4000 },
|
|
3003
|
-
force_reason: { type: 'string', maxLength: 500, description: 'Urazuke: ONLY when the owner explicitly decides to close a workflow task whose step is RED or out of order. The written reason (min 15 chars) is kept in the item history for the audit. Never use it on your own initiative.' },
|
|
3021
|
+
force_reason: { type: 'string', maxLength: 500, description: 'Urazuke: ONLY when the owner explicitly decides to close a workflow task whose step is RED or out of order. The written reason (min 15 chars) is kept in the item history for the audit. Never use it on your own initiative. Requires force_kind.' },
|
|
3022
|
+
force_kind: { type: 'string', maxLength: 60, description: 'Urazuke (M-02): the TYPE of the forced close, mandatory with force_reason so the retrospective can COUNT forced closes per motive. Closed catalogue.', enum: OVERRIDE_KIND_NAMES },
|
|
3004
3023
|
functional: { type: 'string', description: 'FUNCTIONAL description of what was delivered: what the user can do now and how it behaves. Mandatory with reason=shipped -- it is not in the diff.', maxLength: 8000 },
|
|
3005
3024
|
use_cases: { type: 'array', description: 'Concrete use cases now covered, one per entry.' },
|
|
3006
3025
|
files: { type: 'array', description: 'Extra affected sources. Normally empty: with `commit` they come from the SHA.' },
|
|
@@ -3057,6 +3076,13 @@ const VERBS = [
|
|
|
3057
3076
|
blocker_who: { type: 'string', maxLength: 80 },
|
|
3058
3077
|
priority: { type: 'number', description: '0..100' },
|
|
3059
3078
|
related_doc: { type: 'string', maxLength: 200 },
|
|
3079
|
+
/* M-01 -- el spec tambien por EDIT, no solo por add: un item
|
|
3080
|
+
* abierto antes de tener spec tiene que poder adquirirlo sin pasar
|
|
3081
|
+
* por la consola. Pasar uno de los dos campos reemplaza el spec
|
|
3082
|
+
* entero; no pasar ninguno lo deja intacto. */
|
|
3083
|
+
acceptance: { type: 'array', description: 'Urazuke peldano 5: criterios de aceptacion "dado / cuando / entonces", uno por entrada. Pasarlos REEMPLAZA el spec del item.' },
|
|
3084
|
+
how_verified: { type: 'string', maxLength: 2000, description: 'Urazuke peldano 5: como se verifica sin leer codigo. Va junto con acceptance.' },
|
|
3085
|
+
flows: { type: 'array', description: 'Urazuke: los flujos de usuario que toca el item.' },
|
|
3060
3086
|
},
|
|
3061
3087
|
required: ['id'],
|
|
3062
3088
|
},
|