oficina-opencode 2.0.1 → 2.1.1
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 +164 -14
- package/commands/oficina.md +22 -9
- package/dist/core/atomic.d.ts +85 -0
- package/dist/core/atomic.d.ts.map +1 -0
- package/dist/core/atomic.js +186 -0
- package/dist/core/atomic.js.map +1 -0
- package/dist/core/bus.d.ts +76 -56
- package/dist/core/bus.d.ts.map +1 -1
- package/dist/core/bus.js +141 -100
- package/dist/core/bus.js.map +1 -1
- package/dist/core/catalog.d.ts +27 -0
- package/dist/core/catalog.d.ts.map +1 -1
- package/dist/core/catalog.js +41 -6
- package/dist/core/catalog.js.map +1 -1
- package/dist/core/cost.d.ts +275 -0
- package/dist/core/cost.d.ts.map +1 -0
- package/dist/core/cost.js +724 -0
- package/dist/core/cost.js.map +1 -0
- package/dist/core/docsync.d.ts +124 -0
- package/dist/core/docsync.d.ts.map +1 -0
- package/dist/core/docsync.js +191 -0
- package/dist/core/docsync.js.map +1 -0
- package/dist/core/evidence.d.ts +314 -0
- package/dist/core/evidence.d.ts.map +1 -0
- package/dist/core/evidence.js +602 -0
- package/dist/core/evidence.js.map +1 -0
- package/dist/core/fsx.d.ts.map +1 -1
- package/dist/core/fsx.js +7 -1
- package/dist/core/fsx.js.map +1 -1
- package/dist/core/gates.d.ts +9 -2
- package/dist/core/gates.d.ts.map +1 -1
- package/dist/core/gates.js +19 -3
- package/dist/core/gates.js.map +1 -1
- package/dist/core/ids.d.ts +48 -0
- package/dist/core/ids.d.ts.map +1 -0
- package/dist/core/ids.js +87 -0
- package/dist/core/ids.js.map +1 -0
- package/dist/core/leases.d.ts +45 -0
- package/dist/core/leases.d.ts.map +1 -1
- package/dist/core/leases.js +85 -17
- package/dist/core/leases.js.map +1 -1
- package/dist/core/office.d.ts +72 -1
- package/dist/core/office.d.ts.map +1 -1
- package/dist/core/office.js +173 -6
- package/dist/core/office.js.map +1 -1
- package/dist/core/paths.d.ts +11 -1
- package/dist/core/paths.d.ts.map +1 -1
- package/dist/core/paths.js +28 -4
- package/dist/core/paths.js.map +1 -1
- package/dist/core/recovery.d.ts +87 -0
- package/dist/core/recovery.d.ts.map +1 -0
- package/dist/core/recovery.js +325 -0
- package/dist/core/recovery.js.map +1 -0
- package/dist/core/sandbox.d.ts +179 -0
- package/dist/core/sandbox.d.ts.map +1 -0
- package/dist/core/sandbox.js +546 -0
- package/dist/core/sandbox.js.map +1 -0
- package/dist/core/state.d.ts +7 -0
- package/dist/core/state.d.ts.map +1 -1
- package/dist/core/state.js +15 -1
- package/dist/core/state.js.map +1 -1
- package/dist/core/stores.d.ts +65 -0
- package/dist/core/stores.d.ts.map +1 -0
- package/dist/core/stores.js +115 -0
- package/dist/core/stores.js.map +1 -0
- package/dist/core/tripwire.d.ts +87 -0
- package/dist/core/tripwire.d.ts.map +1 -0
- package/dist/core/tripwire.js +203 -0
- package/dist/core/tripwire.js.map +1 -0
- package/dist/core/types.d.ts +33 -1
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js +1 -0
- package/dist/core/types.js.map +1 -1
- package/dist/hooks/scopeGuard.d.ts +86 -13
- package/dist/hooks/scopeGuard.d.ts.map +1 -1
- package/dist/hooks/scopeGuard.js +296 -62
- package/dist/hooks/scopeGuard.js.map +1 -1
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +185 -2
- package/dist/index.js.map +1 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +158 -0
- package/dist/tools/index.js.map +1 -1
- package/docs/COMPATIBILITY.md +98 -0
- package/docs/GARANTIAS.md +190 -0
- package/docs/PLAN-V2.1.md +144 -0
- package/docs/QUE-ES.md +15 -0
- package/docs/catalog-facts.json +27 -0
- package/package.json +6 -2
- package/skills/oficina/SKILL.md +191 -69
- package/skills/oficina/reference/mesh.md +11 -2
|
@@ -0,0 +1,602 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Requirement-to-Evidence Graph: la capa que falta entre "compila" y "está".
|
|
3
|
+
*
|
|
4
|
+
* Los gates técnicos dicen que el código no está roto. No dicen que la card
|
|
5
|
+
* resolvió lo que el usuario pidió. Una card puede compilar, pasar lint,
|
|
6
|
+
* pasar todos los tests y aun así tener la autenticación mal, porque ningún
|
|
7
|
+
* test contemplaba ese escenario: el criterio de aceptación era "el login
|
|
8
|
+
* valida credenciales" y la suite solo verificaba que `login()` devolvía 200.
|
|
9
|
+
*
|
|
10
|
+
* Este módulo cierra ese hueco. Cada criterio de aceptación se convierte en
|
|
11
|
+
* un nodo de requisito; cada evidencia (artefacto, test, gate, inspección,
|
|
12
|
+
* evidencia externa) se engancha a un requisito con un nivel de verificación.
|
|
13
|
+
* La regla que gobierna todo el módulo: si a un requisito obligatorio le
|
|
14
|
+
* falta evidencia suficiente, la card NO puede declararse done.
|
|
15
|
+
*
|
|
16
|
+
* Decisiones de diseño que conviene no romper:
|
|
17
|
+
*
|
|
18
|
+
* 1. La pirámide de niveles ordena CONFianza, no cantidad:
|
|
19
|
+
* 1 = estático (compila, lintea), 2 = comportamiento (algo lo ejercita),
|
|
20
|
+
* 3 = validación de requisitos (alguien lo contrastó contra el criterio),
|
|
21
|
+
* 4 = auditoría independiente (otro agente, no el owner, lo revisó).
|
|
22
|
+
* `reachedLevel` es el MÁXIMO de la evidencia del requisito, nunca el
|
|
23
|
+
* promedio: promediar dejaría pasar una card con un test y cinco gates
|
|
24
|
+
* cuando ningún requisito tiene un test.
|
|
25
|
+
*
|
|
26
|
+
* 2. El módulo no llama a `Date.now()`. Todo timestamp entra por `clock` o
|
|
27
|
+
* por `recordedAt`; sin ninguno se usa un epoch fijo. Un grafo que depende
|
|
28
|
+
* del reloj no es reproducible y sus tests miden el reloj, no el grafo.
|
|
29
|
+
*
|
|
30
|
+
* 3. No hay IO. Todo entra por parámetros y sale por el return. El módulo no
|
|
31
|
+
* sabe dónde viven los artefactos: recibe rutas como strings.
|
|
32
|
+
*
|
|
33
|
+
* 4. La evidencia se vincula por el TEXTO EXACTO del criterio de aceptación,
|
|
34
|
+
* no por índice, porque el texto es lo que el humano lee y lo que el
|
|
35
|
+
* Commander escribió; el índice solo desambigua duplicados. Si el texto no
|
|
36
|
+
* coincide, la evidencia se engancha igual por índice pero queda un riesgo
|
|
37
|
+
* visible: prefiero evidencia mal etiquetada con riesgo a evidencia
|
|
38
|
+
* perdida en silencio.
|
|
39
|
+
*
|
|
40
|
+
* 5. El módulo no importa `Card` de `types.ts`. Necesita el id y los
|
|
41
|
+
* criterios de aceptación, y nada más: acoplarse al schema completo de la
|
|
42
|
+
* card haría que cada cambio de card_schema rompiera el grafo de evidencia
|
|
43
|
+
* sin que tenga relación alguna con él.
|
|
44
|
+
*/
|
|
45
|
+
import path from "node:path";
|
|
46
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
47
|
+
// Constantes
|
|
48
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
49
|
+
/** Cuántos criterios de aceptación son obligatorios por defecto. */
|
|
50
|
+
export const DEFAULT_MANDATORY_COUNT = 2;
|
|
51
|
+
/** Nivel de evidencia exigido por defecto: comportamiento, no estático. */
|
|
52
|
+
export const DEFAULT_REQUIRED_LEVEL = 2;
|
|
53
|
+
/**
|
|
54
|
+
* Epoch por defecto para la evidencia sin reloj inyectado.
|
|
55
|
+
*
|
|
56
|
+
* Feo a propósito: mejor una fecha obviamente sintética que un timestamp
|
|
57
|
+
* silenciosamente dependiente del momento en que corrió el test.
|
|
58
|
+
*/
|
|
59
|
+
export const DEFAULT_RECORDED_AT = "1970-01-01T00:00:00.000Z";
|
|
60
|
+
/** Agente por defecto cuando nadie dice quién registró la evidencia. */
|
|
61
|
+
export const DEFAULT_RECORDED_BY = "unknown";
|
|
62
|
+
/**
|
|
63
|
+
* Nivel máximo que puede alcanzar cada tipo de evidencia.
|
|
64
|
+
*
|
|
65
|
+
* Un artefacto es una descripción del trabajo, no el trabajo: describe
|
|
66
|
+
* comportamiento pero no lo demuestra más allá de lo que el autor afirma.
|
|
67
|
+
* Por eso tope 2. La inspección manual llega a 3. Solo una revisión de otro
|
|
68
|
+
* agente, que puede decir "esto no cumple", llega a 4.
|
|
69
|
+
*/
|
|
70
|
+
const KIND_MAX_LEVEL = {
|
|
71
|
+
artifact: 2,
|
|
72
|
+
test: 2,
|
|
73
|
+
gate: 2,
|
|
74
|
+
inspection: 4,
|
|
75
|
+
external: 4,
|
|
76
|
+
};
|
|
77
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
78
|
+
// Helpers internos
|
|
79
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
80
|
+
/** Convierte un número a nivel válido. Cualquier cosa fuera de 1..4 es 0. */
|
|
81
|
+
function toLevel(value) {
|
|
82
|
+
if (value === 1)
|
|
83
|
+
return 1;
|
|
84
|
+
if (value === 2)
|
|
85
|
+
return 2;
|
|
86
|
+
if (value === 3)
|
|
87
|
+
return 3;
|
|
88
|
+
if (value === 4)
|
|
89
|
+
return 4;
|
|
90
|
+
return 0;
|
|
91
|
+
}
|
|
92
|
+
/** Recorta un nivel al máximo que admite su tipo de evidencia. */
|
|
93
|
+
function clampLevel(level, max) {
|
|
94
|
+
const capped = toLevel(Math.min(Math.max(Math.trunc(level), 1), 4));
|
|
95
|
+
if (capped === 0)
|
|
96
|
+
return 1;
|
|
97
|
+
return capped <= max ? capped : max;
|
|
98
|
+
}
|
|
99
|
+
/** Slug estable para ids y refs: sin acentos, sin mayúsculas, sin ruido. */
|
|
100
|
+
function slugify(text) {
|
|
101
|
+
// `Diacritic` es la forma Unicode de quitar las marcas combinantes que
|
|
102
|
+
// deja NFD ("autenticación" -> "autenticacion") sin escribir un rango de
|
|
103
|
+
// caracteres combinantes a mano.
|
|
104
|
+
const normalized = text
|
|
105
|
+
.normalize("NFD")
|
|
106
|
+
.replace(/\p{Diacritic}/gu, "")
|
|
107
|
+
.toLowerCase()
|
|
108
|
+
.replace(/[^a-z0-9]+/g, "-")
|
|
109
|
+
.replace(/^-+|-+$/g, "");
|
|
110
|
+
return normalized.slice(0, 48) || "ref";
|
|
111
|
+
}
|
|
112
|
+
/** Id estable de un nodo de requisito. */
|
|
113
|
+
export function requirementId(cardId, index) {
|
|
114
|
+
return `req-${slugify(cardId)}-${index}`;
|
|
115
|
+
}
|
|
116
|
+
/** Id estable de un nodo de evidencia. */
|
|
117
|
+
export function evidenceId(cardId, requirementIndex, kind, ref) {
|
|
118
|
+
const idx = requirementIndex >= 0 ? String(requirementIndex) : "x";
|
|
119
|
+
return `ev-${slugify(cardId)}-${idx}-${kind}-${slugify(ref)}`;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Resuelve el timestamp de una evidencia.
|
|
123
|
+
*
|
|
124
|
+
* Precedencia: `recordedAt` explícito > `clock` inyectado > epoch fijo.
|
|
125
|
+
*/
|
|
126
|
+
function resolveRecordedAt(opts) {
|
|
127
|
+
if (opts.recordedAt)
|
|
128
|
+
return opts.recordedAt;
|
|
129
|
+
if (opts.clock)
|
|
130
|
+
return new Date(opts.clock()).toISOString();
|
|
131
|
+
return DEFAULT_RECORDED_AT;
|
|
132
|
+
}
|
|
133
|
+
/** Índices de criterios obligatorios. */
|
|
134
|
+
function resolveMandatoryIndexes(total, options) {
|
|
135
|
+
if (options.mandatoryIndexes) {
|
|
136
|
+
return new Set(options.mandatoryIndexes.filter((i) => i >= 0 && i < total));
|
|
137
|
+
}
|
|
138
|
+
const count = Math.min(Math.max(options.mandatoryCount ?? DEFAULT_MANDATORY_COUNT, 0), total);
|
|
139
|
+
return new Set(Array.from({ length: count }, (_, i) => i));
|
|
140
|
+
}
|
|
141
|
+
/** Escapa texto para una celda de tabla markdown. */
|
|
142
|
+
function escapeCell(text) {
|
|
143
|
+
return text.replace(/\s+/g, " ").replace(/\|/g, "\\|");
|
|
144
|
+
}
|
|
145
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
146
|
+
// Construcción
|
|
147
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
148
|
+
/**
|
|
149
|
+
* Crea un nodo de requisito por cada criterio de aceptación de la card.
|
|
150
|
+
*
|
|
151
|
+
* Los primeros `mandatoryCount` criterios (2 por defecto) quedan obligatorios.
|
|
152
|
+
* La obligatoriedad existe porque no todos los criterios cortan el objetivo:
|
|
153
|
+
* "el botón dice Hola" puede quedar sin probar y la card sigue sirviendo,
|
|
154
|
+
* pero "el login valida credenciales" no.
|
|
155
|
+
*/
|
|
156
|
+
export function buildRequirementNodes(card, options = {}) {
|
|
157
|
+
const mandatory = resolveMandatoryIndexes(card.acceptance.length, options);
|
|
158
|
+
return card.acceptance.map((requirement, index) => ({
|
|
159
|
+
id: requirementId(card.id, index),
|
|
160
|
+
cardId: card.id,
|
|
161
|
+
requirement,
|
|
162
|
+
index,
|
|
163
|
+
mandatory: mandatory.has(index),
|
|
164
|
+
evidence: [],
|
|
165
|
+
reachedLevel: 0,
|
|
166
|
+
status: "unsatisfied",
|
|
167
|
+
risks: [],
|
|
168
|
+
}));
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Recalcula el estado derivado de un requisito a partir de su evidencia.
|
|
172
|
+
*
|
|
173
|
+
* Todo el estado (`reachedLevel`, `status`, `risks`) se deriva de la
|
|
174
|
+
* evidencia, nunca se anota a mano: si el estado puede quedar desincronizado
|
|
175
|
+
* con los hechos, el grafo miente.
|
|
176
|
+
*/
|
|
177
|
+
function recomputeRequirement(req, requiredLevel) {
|
|
178
|
+
const valid = req.evidence.filter((e) => e.passed !== false);
|
|
179
|
+
let reached = 0;
|
|
180
|
+
for (const e of valid) {
|
|
181
|
+
reached = reached === 0 ? e.level : toLevel(Math.max(reached, e.level));
|
|
182
|
+
}
|
|
183
|
+
const status = reached === 0 ? "unsatisfied" : reached >= requiredLevel ? "satisfied" : "partial";
|
|
184
|
+
const risks = [];
|
|
185
|
+
for (const e of req.evidence) {
|
|
186
|
+
if (e.passed === false) {
|
|
187
|
+
risks.push(`Hay evidencia que documenta un fallo: ${e.ref}`);
|
|
188
|
+
}
|
|
189
|
+
if (e.requirement !== req.requirement) {
|
|
190
|
+
risks.push(`La evidencia ${e.ref} cita «${e.requirement}», que no es el texto del criterio`);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
if (valid.length > 0 && reached < requiredLevel) {
|
|
194
|
+
risks.push(`Nivel de evidencia insuficiente: ${reached} < ${requiredLevel}`);
|
|
195
|
+
}
|
|
196
|
+
if (req.mandatory && req.evidence.length === 0) {
|
|
197
|
+
risks.push("Sin evidencia registrada para un requisito obligatorio");
|
|
198
|
+
}
|
|
199
|
+
return { ...req, evidence: [...req.evidence], reachedLevel: reached, status, risks };
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Recalcula los campos derivados del grafo completo.
|
|
203
|
+
*
|
|
204
|
+
* `missingMandatory` incluye tanto los requisitos obligatorios SIN evidencia
|
|
205
|
+
* como los que tienen evidencia por debajo del nivel exigido: en los dos
|
|
206
|
+
* casos falta evidencia *suficiente*, que es lo que importa para cerrar.
|
|
207
|
+
*/
|
|
208
|
+
function recompute(graph) {
|
|
209
|
+
const requiredLevel = graph.requiredLevel ?? DEFAULT_REQUIRED_LEVEL;
|
|
210
|
+
const requirements = graph.requirements.map((r) => recomputeRequirement(r, requiredLevel));
|
|
211
|
+
const mandatory = requirements.filter((r) => r.mandatory);
|
|
212
|
+
const missingMandatory = mandatory
|
|
213
|
+
.filter((r) => r.status !== "satisfied")
|
|
214
|
+
.map((r) => r.requirement);
|
|
215
|
+
let minLevel = 0;
|
|
216
|
+
if (mandatory.length > 0) {
|
|
217
|
+
minLevel = mandatory[0].reachedLevel;
|
|
218
|
+
for (const r of mandatory) {
|
|
219
|
+
minLevel = toLevel(Math.min(minLevel, r.reachedLevel));
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
const complete = missingMandatory.length === 0;
|
|
223
|
+
let summary;
|
|
224
|
+
if (mandatory.length === 0) {
|
|
225
|
+
summary =
|
|
226
|
+
requirements.length === 0
|
|
227
|
+
? "La card no declara criterios de aceptación: no hay nada que verificar."
|
|
228
|
+
: `${requirements.length} criterio(s) de aceptación, ninguno obligatorio.`;
|
|
229
|
+
}
|
|
230
|
+
else if (complete) {
|
|
231
|
+
summary = `Los ${mandatory.length} requisito(s) obligatorio(s) tienen evidencia suficiente (nivel mínimo ${minLevel}).`;
|
|
232
|
+
}
|
|
233
|
+
else {
|
|
234
|
+
summary = `Faltan ${missingMandatory.length} requisito(s) obligatorio(s): ${missingMandatory.join("; ")}.`;
|
|
235
|
+
}
|
|
236
|
+
return { ...graph, requirements, missingMandatory, complete, minLevel, summary };
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Encuentra el requisito al que pertenece una evidencia.
|
|
240
|
+
*
|
|
241
|
+
* Primero por texto exacto (la identidad del criterio es su texto); el
|
|
242
|
+
* índice solo desambigua duplicados. Si el texto no coincide con ninguno, se
|
|
243
|
+
* cae al índice: la evidencia se guarda y la discrepancia queda registrada
|
|
244
|
+
* como riesgo en el requerimiento.
|
|
245
|
+
*/
|
|
246
|
+
function resolveTarget(requirements, node) {
|
|
247
|
+
if (requirements.length === 0)
|
|
248
|
+
return undefined;
|
|
249
|
+
const exact = requirements.filter((r) => r.requirement === node.requirement);
|
|
250
|
+
if (exact.length === 1)
|
|
251
|
+
return exact[0];
|
|
252
|
+
if (exact.length > 1) {
|
|
253
|
+
return exact.find((r) => r.index === node.requirementIndex) ?? exact[0];
|
|
254
|
+
}
|
|
255
|
+
return requirements.find((r) => r.index === node.requirementIndex);
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Agrega una evidencia al grafo y recalcula el estado.
|
|
259
|
+
*
|
|
260
|
+
* La función es pura: no muta el grafo recibido, devuelve uno nuevo. Quien
|
|
261
|
+
* la llame puede conservar el anterior para comparar versiones.
|
|
262
|
+
*/
|
|
263
|
+
export function addEvidence(graph, node) {
|
|
264
|
+
const requirements = graph.requirements.map((r) => ({ ...r, evidence: [...r.evidence] }));
|
|
265
|
+
const target = resolveTarget(requirements, node);
|
|
266
|
+
if (!target) {
|
|
267
|
+
const orphans = [...(graph.orphanedEvidence ?? []), node];
|
|
268
|
+
return recompute({ ...graph, requirements, orphanedEvidence: orphans });
|
|
269
|
+
}
|
|
270
|
+
// El flag `mandatory` de la evidencia lo manda el requisito: el criterio
|
|
271
|
+
// manda sobre lo que diga la evidencia, no al revés.
|
|
272
|
+
target.evidence.push({ ...node, mandatory: target.mandatory });
|
|
273
|
+
return recompute({ ...graph, requirements });
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Construye el grafo de evidencia de una card.
|
|
277
|
+
*
|
|
278
|
+
* Es el camino normal: se pasa la card, la lista de evidencia y las opciones.
|
|
279
|
+
* La evidencia se aplica en orden, así que el orden de la lista importa
|
|
280
|
+
* para el orden interno (no para el estado, que se recalcula siempre).
|
|
281
|
+
*/
|
|
282
|
+
export function buildEvidenceGraph(card, evidence, options = {}) {
|
|
283
|
+
const requiredLevel = options.requiredLevel ?? DEFAULT_REQUIRED_LEVEL;
|
|
284
|
+
let graph = {
|
|
285
|
+
cardId: card.id,
|
|
286
|
+
requirements: buildRequirementNodes(card, options),
|
|
287
|
+
missingMandatory: [],
|
|
288
|
+
complete: false,
|
|
289
|
+
minLevel: 0,
|
|
290
|
+
summary: "",
|
|
291
|
+
requiredLevel,
|
|
292
|
+
orphanedEvidence: [],
|
|
293
|
+
};
|
|
294
|
+
for (const node of evidence) {
|
|
295
|
+
graph = addEvidence(graph, node);
|
|
296
|
+
}
|
|
297
|
+
return recompute(graph);
|
|
298
|
+
}
|
|
299
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
300
|
+
// Constructores de evidencia
|
|
301
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
302
|
+
/** Base común de los constructores de evidencia. */
|
|
303
|
+
function makeEvidence(args) {
|
|
304
|
+
const index = args.opts.requirementIndex ?? -1;
|
|
305
|
+
return {
|
|
306
|
+
id: evidenceId(args.cardId, index, args.kind, args.ref),
|
|
307
|
+
cardId: args.cardId,
|
|
308
|
+
requirement: args.requirement,
|
|
309
|
+
requirementIndex: index,
|
|
310
|
+
mandatory: args.opts.mandatory ?? false,
|
|
311
|
+
kind: args.kind,
|
|
312
|
+
level: args.level,
|
|
313
|
+
ref: args.ref,
|
|
314
|
+
note: args.note,
|
|
315
|
+
recordedAt: resolveRecordedAt(args.opts),
|
|
316
|
+
recordedBy: args.opts.recordedBy ?? DEFAULT_RECORDED_BY,
|
|
317
|
+
passed: args.passed,
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Evidencia de artefacto: un archivo de `.oficina/artifacts/<cardId>/`.
|
|
322
|
+
*
|
|
323
|
+
* Tope nivel 2. Un `handoff.md` describe lo que el agente dice que hizo;
|
|
324
|
+
* believe, but verify: el artefacto es el relato, no la ejecución.
|
|
325
|
+
*/
|
|
326
|
+
export function evidenceFromArtifact(artifactPath, cardId, requirement, opts = {}) {
|
|
327
|
+
const ref = artifactPath.replace(/\\/g, "/");
|
|
328
|
+
return makeEvidence({
|
|
329
|
+
cardId,
|
|
330
|
+
requirement,
|
|
331
|
+
kind: "artifact",
|
|
332
|
+
level: clampLevel(opts.level ?? 2, KIND_MAX_LEVEL.artifact),
|
|
333
|
+
ref,
|
|
334
|
+
note: opts.note ?? `artefacto ${path.basename(ref)}`,
|
|
335
|
+
passed: true,
|
|
336
|
+
opts,
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Evidencia de test: un test citado que ejercita el requisito.
|
|
341
|
+
*
|
|
342
|
+
* Tope nivel 2: un test demuestra comportamiento, no criterio de negocio
|
|
343
|
+
* auditado. Si el test fue citado pero no lo cubre, el riesgo queda escrito
|
|
344
|
+
* en la nota; la auditoría de nivel 4 es la que verifica esa cobertura.
|
|
345
|
+
*/
|
|
346
|
+
export function evidenceFromTest(testRef, cardId, requirement, opts = {}) {
|
|
347
|
+
return makeEvidence({
|
|
348
|
+
cardId,
|
|
349
|
+
requirement,
|
|
350
|
+
kind: "test",
|
|
351
|
+
level: clampLevel(opts.level ?? 2, KIND_MAX_LEVEL.test),
|
|
352
|
+
ref: testRef,
|
|
353
|
+
note: opts.note ?? `test ${testRef}`,
|
|
354
|
+
passed: true,
|
|
355
|
+
opts,
|
|
356
|
+
});
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* Elige qué fase de un gate se cita como evidencia.
|
|
360
|
+
*
|
|
361
|
+
* Se prefiere la fase de tests: es la única que ejercita comportamiento, así
|
|
362
|
+
* que es la que aporta nivel 2. Si no hay fase de tests, se cita la primera
|
|
363
|
+
* disponible (build, typecheck, lint…) que aporta nivel 1.
|
|
364
|
+
*/
|
|
365
|
+
function pickGatePhase(input) {
|
|
366
|
+
const phases = [...(input.technical ?? []), ...(input.security ?? [])];
|
|
367
|
+
if (phases.length === 0)
|
|
368
|
+
return input;
|
|
369
|
+
return phases.find((p) => p.phase === "test") ?? phases[0];
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* Evidencia de gate: el resultado de una fase ejecutada.
|
|
373
|
+
*
|
|
374
|
+
* Nivel 2 solo para la fase de tests; el resto de fases son estáticas
|
|
375
|
+
* (nivel 1). Un gate que falló se registra igual, con `passed: false`: saber
|
|
376
|
+
* qué se rompió es información, no verificación.
|
|
377
|
+
*/
|
|
378
|
+
export function evidenceFromGate(gateResult, cardId, requirement, opts = {}) {
|
|
379
|
+
const cited = pickGatePhase(gateResult);
|
|
380
|
+
const phase = cited.phase ?? "gate";
|
|
381
|
+
const level = phase === "test" ? 2 : 1;
|
|
382
|
+
const passed = cited.outcome !== undefined ? cited.outcome === "pass" : (cited.passed ?? false);
|
|
383
|
+
const detail = opts.note ?? cited.detail ?? cited.reason ?? (cited.outcome ? `gate ${phase}: ${cited.outcome}` : `gate ${phase}`);
|
|
384
|
+
return makeEvidence({
|
|
385
|
+
cardId,
|
|
386
|
+
requirement,
|
|
387
|
+
kind: "gate",
|
|
388
|
+
level: clampLevel(opts.level ?? level, KIND_MAX_LEVEL.gate),
|
|
389
|
+
ref: `gate:${phase}`,
|
|
390
|
+
note: detail,
|
|
391
|
+
passed,
|
|
392
|
+
opts,
|
|
393
|
+
});
|
|
394
|
+
}
|
|
395
|
+
/**
|
|
396
|
+
* Evidencia de inspección manual documentada.
|
|
397
|
+
*
|
|
398
|
+
* Una inspección es nivel 3: alguien se puso a contrastar el resultado
|
|
399
|
+
* contra el criterio. Pasa a nivel 4 SOLO si la hizo un revisor distinto del
|
|
400
|
+
* owner, porque ahí deja de ser la opinión del autor y pasa a ser una
|
|
401
|
+
* auditoría que puede contradecirlo.
|
|
402
|
+
*/
|
|
403
|
+
export function evidenceFromInspection(inspectionRef, cardId, requirement, opts = {}) {
|
|
404
|
+
const isAudit = Boolean(opts.owner && opts.reviewer && opts.owner !== opts.reviewer);
|
|
405
|
+
const level = isAudit ? 4 : 3;
|
|
406
|
+
return makeEvidence({
|
|
407
|
+
cardId,
|
|
408
|
+
requirement,
|
|
409
|
+
kind: "inspection",
|
|
410
|
+
level: clampLevel(opts.level ?? level, KIND_MAX_LEVEL.inspection),
|
|
411
|
+
ref: inspectionRef,
|
|
412
|
+
note: opts.note ?? (isAudit ? `auditoría de ${opts.reviewer} (owner: ${opts.owner})` : `inspección ${inspectionRef}`),
|
|
413
|
+
passed: true,
|
|
414
|
+
opts,
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
* Evidencia de auditoría independiente: la revisó un agente que no es el
|
|
419
|
+
* owner.
|
|
420
|
+
*
|
|
421
|
+
* A diferencia de `evidenceFromInspection`, acá el nivel 4 es parte del
|
|
422
|
+
* contrato: si no hay owner y revisor distintos, la auditoría no ocurrió y
|
|
423
|
+
* se lanza el error en vez de devolver una evidencia de nivel 3 con cara de
|
|
424
|
+
* auditoría. Un "audit" que en realidad es auto-revisión es el peor de los
|
|
425
|
+
* dos mundos: parece verificado y no lo está.
|
|
426
|
+
*/
|
|
427
|
+
export function evidenceFromAudit(auditRef, cardId, requirement, opts = {}) {
|
|
428
|
+
if (!opts.owner || !opts.reviewer) {
|
|
429
|
+
throw new Error("Una auditoría requiere owner y reviewer: sin ambos no se puede afirmar independencia");
|
|
430
|
+
}
|
|
431
|
+
if (opts.owner === opts.reviewer) {
|
|
432
|
+
throw new Error(`Una auditoría no puede tener al mismo owner y reviewer (${opts.owner})`);
|
|
433
|
+
}
|
|
434
|
+
return makeEvidence({
|
|
435
|
+
cardId,
|
|
436
|
+
requirement,
|
|
437
|
+
kind: "inspection",
|
|
438
|
+
level: clampLevel(opts.level ?? 4, KIND_MAX_LEVEL.inspection),
|
|
439
|
+
ref: auditRef,
|
|
440
|
+
note: opts.note ?? `auditoría de ${opts.reviewer} sobre el trabajo de ${opts.owner}`,
|
|
441
|
+
passed: true,
|
|
442
|
+
opts,
|
|
443
|
+
});
|
|
444
|
+
}
|
|
445
|
+
/**
|
|
446
|
+
* Evidencia externa: un link, una captura, un reporte de terceros.
|
|
447
|
+
*
|
|
448
|
+
* Nivel 1 por defecto. No se puede verificar desde adentro del repo, así que
|
|
449
|
+
* por sí sola no demuestra comportamiento; quien la registra puede subirla de
|
|
450
|
+
* nivel si documentó el contexto.
|
|
451
|
+
*/
|
|
452
|
+
export function evidenceFromExternal(externalRef, cardId, requirement, opts = {}) {
|
|
453
|
+
return makeEvidence({
|
|
454
|
+
cardId,
|
|
455
|
+
requirement,
|
|
456
|
+
kind: "external",
|
|
457
|
+
level: clampLevel(opts.level ?? 1, KIND_MAX_LEVEL.external),
|
|
458
|
+
ref: externalRef,
|
|
459
|
+
note: opts.note ?? `evidencia externa ${externalRef}`,
|
|
460
|
+
passed: true,
|
|
461
|
+
opts,
|
|
462
|
+
});
|
|
463
|
+
}
|
|
464
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
465
|
+
// Veredicto de cierre
|
|
466
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
467
|
+
/**
|
|
468
|
+
* ¿Se puede declarar `done` esta card?
|
|
469
|
+
*
|
|
470
|
+
* Es el corazón del módulo. Responde con una razón legible, en español, que
|
|
471
|
+
* diga QUÉ falta — no solo que falta. Un "no" sin explicación hace que el
|
|
472
|
+
* agente adivine y vuelva a hacer lo mismo.
|
|
473
|
+
*
|
|
474
|
+
* Reglas:
|
|
475
|
+
* - Sin criterios de aceptación no hay nada verificable → no cierra.
|
|
476
|
+
* - Si algún requisito obligatorio no está `satisfied` → no cierra.
|
|
477
|
+
* - Si el nivel mínimo entre los obligatorios no alcanza el exigido → no cierra.
|
|
478
|
+
*/
|
|
479
|
+
export function canCloseCard(graph, limits = {}) {
|
|
480
|
+
const requireAcceptance = limits.requireAcceptance ?? true;
|
|
481
|
+
// El nivel exigido es el más estricto de los dos: el del grafo y el del
|
|
482
|
+
// que evalúa. Nadie baja el listón por pedido.
|
|
483
|
+
let requiredLevel = toLevel(Math.max(graph.requiredLevel ?? DEFAULT_REQUIRED_LEVEL, limits.requiredLevel ?? DEFAULT_REQUIRED_LEVEL));
|
|
484
|
+
if (requiredLevel === 0)
|
|
485
|
+
requiredLevel = DEFAULT_REQUIRED_LEVEL;
|
|
486
|
+
if (requireAcceptance && graph.requirements.length === 0) {
|
|
487
|
+
return {
|
|
488
|
+
ok: false,
|
|
489
|
+
reason: "La card no declara criterios de aceptación: no hay nada verificable, así que no puede declararse done.",
|
|
490
|
+
};
|
|
491
|
+
}
|
|
492
|
+
if (graph.missingMandatory.length > 0) {
|
|
493
|
+
const details = graph.requirements
|
|
494
|
+
.filter((r) => r.mandatory && r.status !== "satisfied")
|
|
495
|
+
.map((r) => `«${r.requirement}» (evidencia actual: nivel ${r.reachedLevel}, exigido: ${requiredLevel})`);
|
|
496
|
+
return {
|
|
497
|
+
ok: false,
|
|
498
|
+
reason: `Falta evidencia suficiente para ${graph.missingMandatory.length} requisito(s) obligatorio(s): ${details.join("; ")}.`,
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
// El chequeo de nivel solo aplica si hay requisitos obligatorios: `minLevel`
|
|
502
|
+
// en 0 con cero obligatorios significa "no hay nada que medir", no "nivel 0
|
|
503
|
+
// alcanzado". Confundir los dos volvería imposible de cerrar una card sin
|
|
504
|
+
// requisitos obligatorios.
|
|
505
|
+
const hasMandatory = graph.requirements.some((r) => r.mandatory);
|
|
506
|
+
if (hasMandatory && graph.minLevel < requiredLevel) {
|
|
507
|
+
return {
|
|
508
|
+
ok: false,
|
|
509
|
+
reason: `El nivel de evidencia mínimo entre los requisitos obligatorios (${graph.minLevel}) es inferior al exigido (${requiredLevel}).`,
|
|
510
|
+
};
|
|
511
|
+
}
|
|
512
|
+
const mandatoryCount = graph.requirements.filter((r) => r.mandatory).length;
|
|
513
|
+
return {
|
|
514
|
+
ok: true,
|
|
515
|
+
reason: `Los ${mandatoryCount} requisito(s) obligatorio(s) tienen evidencia suficiente (nivel mínimo ${graph.minLevel}, exigido ${requiredLevel}).`,
|
|
516
|
+
};
|
|
517
|
+
}
|
|
518
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
519
|
+
// Render
|
|
520
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
521
|
+
/**
|
|
522
|
+
* Renderiza el grafo como markdown legible.
|
|
523
|
+
*
|
|
524
|
+
* Va al artefacto de la card: un humano tiene que poder leer, en treinta
|
|
525
|
+
* segundos, si los criterios de aceptación del Commander están respaldados
|
|
526
|
+
* o si son deseos.
|
|
527
|
+
*/
|
|
528
|
+
export function renderEvidenceGraph(graph) {
|
|
529
|
+
const requiredLevel = graph.requiredLevel ?? DEFAULT_REQUIRED_LEVEL;
|
|
530
|
+
const lines = [];
|
|
531
|
+
lines.push(`# Grafo de evidencia — ${graph.cardId}`);
|
|
532
|
+
lines.push("");
|
|
533
|
+
lines.push(`**Resumen:** ${graph.summary}`);
|
|
534
|
+
lines.push("");
|
|
535
|
+
lines.push(`**Estado:** ${graph.complete ? "COMPLETO" : "INCOMPLETO"}`);
|
|
536
|
+
lines.push("");
|
|
537
|
+
lines.push(`**Nivel mínimo entre requisitos obligatorios:** ${graph.minLevel} (exigido: ${requiredLevel})`);
|
|
538
|
+
lines.push("");
|
|
539
|
+
lines.push("## Requisitos");
|
|
540
|
+
lines.push("");
|
|
541
|
+
lines.push("| # | Requisito | Obligatorio | Estado | Nivel | Evidencia |");
|
|
542
|
+
lines.push("|---|-----------|-------------|--------|-------|-----------|");
|
|
543
|
+
for (const r of graph.requirements) {
|
|
544
|
+
lines.push(`| ${r.index + 1} | ${escapeCell(r.requirement)} | ${r.mandatory ? "sí" : "no"} | ${r.status} | ${r.reachedLevel} | ${r.evidence.length} |`);
|
|
545
|
+
}
|
|
546
|
+
lines.push("");
|
|
547
|
+
lines.push("## Detalle por requisito");
|
|
548
|
+
lines.push("");
|
|
549
|
+
for (const r of graph.requirements) {
|
|
550
|
+
lines.push(`### ${r.index + 1}. ${r.requirement}`);
|
|
551
|
+
lines.push("");
|
|
552
|
+
lines.push(`- **Obligatorio:** ${r.mandatory ? "sí" : "no"}`);
|
|
553
|
+
lines.push(`- **Estado:** ${r.status}`);
|
|
554
|
+
lines.push(`- **Nivel alcanzado:** ${r.reachedLevel} / ${requiredLevel}`);
|
|
555
|
+
lines.push("");
|
|
556
|
+
if (r.evidence.length === 0) {
|
|
557
|
+
lines.push("- Sin evidencia registrada.");
|
|
558
|
+
}
|
|
559
|
+
else {
|
|
560
|
+
lines.push("**Evidencia:**");
|
|
561
|
+
lines.push("");
|
|
562
|
+
for (const e of r.evidence) {
|
|
563
|
+
const flag = e.passed === false ? " — FALLIDA" : "";
|
|
564
|
+
const note = e.note ? ` — ${e.note}` : "";
|
|
565
|
+
lines.push(`- \`${e.kind}\` **${e.ref}** (nivel ${e.level})${flag}${note} — registrado por ${e.recordedBy} (${e.recordedAt})`);
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
lines.push("");
|
|
569
|
+
lines.push("**Riesgos:**");
|
|
570
|
+
if (r.risks.length === 0) {
|
|
571
|
+
lines.push("- Ninguno.");
|
|
572
|
+
}
|
|
573
|
+
else {
|
|
574
|
+
for (const risk of r.risks) {
|
|
575
|
+
lines.push(`- ${risk}`);
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
lines.push("");
|
|
579
|
+
}
|
|
580
|
+
lines.push("## Requisitos obligatorios pendientes");
|
|
581
|
+
lines.push("");
|
|
582
|
+
if (graph.missingMandatory.length === 0) {
|
|
583
|
+
lines.push("- Ninguno: todos los requisitos obligatorios tienen evidencia suficiente.");
|
|
584
|
+
}
|
|
585
|
+
else {
|
|
586
|
+
for (const m of graph.missingMandatory) {
|
|
587
|
+
lines.push(`- ${m}`);
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
lines.push("");
|
|
591
|
+
const orphans = graph.orphanedEvidence ?? [];
|
|
592
|
+
if (orphans.length > 0) {
|
|
593
|
+
lines.push("## Evidencia sin vincular");
|
|
594
|
+
lines.push("");
|
|
595
|
+
for (const e of orphans) {
|
|
596
|
+
lines.push(`- \`${e.kind}\` ${e.ref} — cita «${e.requirement}», que no es un criterio de aceptación de esta card.`);
|
|
597
|
+
}
|
|
598
|
+
lines.push("");
|
|
599
|
+
}
|
|
600
|
+
return lines.join("\n");
|
|
601
|
+
}
|
|
602
|
+
//# sourceMappingURL=evidence.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evidence.js","sourceRoot":"","sources":["../../src/core/evidence.ts"],"names":[],"mappings":"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"}
|
package/dist/core/fsx.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fsx.d.ts","sourceRoot":"","sources":["../../src/core/fsx.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAOH,yDAAyD;AACzD,wBAAsB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAUnF;AAED,wDAAwD;AACxD,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAErF;AAED;;;;;GAKG;AACH,wBAAsB,QAAQ,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,
|
|
1
|
+
{"version":3,"file":"fsx.d.ts","sourceRoot":"","sources":["../../src/core/fsx.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAOH,yDAAyD;AACzD,wBAAsB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAUnF;AAED,wDAAwD;AACxD,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAErF;AAED;;;;;GAKG;AACH,wBAAsB,QAAQ,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAoB1E;AAED,oDAAoD;AACpD,wBAAsB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAO5E;AAED,yBAAyB;AACzB,wBAAgB,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEhD;AAED,uDAAuD;AACvD,wBAAsB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE9D;AAED,mEAAmE;AACnE,wBAAsB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAOlE;AAED,yEAAyE;AACzE,wBAAsB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAQjE;AAED,oCAAoC;AACpC,wBAAsB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEpE;AAED,qCAAqC;AACrC,wBAAgB,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAE9C;AAED,8DAA8D;AAC9D,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED,4CAA4C;AAC5C,wBAAgB,MAAM,CAAC,KAAK,GAAE,MAAM,MAAiB,GAAG,MAAM,CAE7D"}
|
package/dist/core/fsx.js
CHANGED
|
@@ -44,7 +44,13 @@ export async function readJson(filePath) {
|
|
|
44
44
|
if (code === "ENOENT")
|
|
45
45
|
return undefined;
|
|
46
46
|
if (err instanceof SyntaxError) {
|
|
47
|
-
//
|
|
47
|
+
// Un archivo vacio casi siempre es una escritura en curso (otro
|
|
48
|
+
// proceso lo esta creando), no corrupcion. Ponerlo en cuarentena
|
|
49
|
+
// lo destruye: el escritor que estaba en medio pierde su archivo.
|
|
50
|
+
// Un archivo con contenido que no parsea SI es corrupcion.
|
|
51
|
+
const raw = await fs.readFile(filePath, "utf8").catch(() => "");
|
|
52
|
+
if (raw.trim().length === 0)
|
|
53
|
+
return undefined;
|
|
48
54
|
const quarantine = `${filePath}.corrupt-${Date.now()}`;
|
|
49
55
|
await fs.rename(filePath, quarantine).catch(() => { });
|
|
50
56
|
return undefined;
|