@ingeniomaps/cauce 0.53.1 → 0.54.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/CHANGELOG.md +52 -0
- package/README.md +1 -1
- package/agents/README.md +24 -0
- package/agents/roles/system/accounting-specialist/SKILL.md +2 -0
- package/agents/roles/system/ai-governance-lead/SKILL.md +2 -0
- package/agents/roles/system/ai-product-manager/SKILL.md +2 -0
- package/agents/roles/system/analytics-engineer/SKILL.md +2 -0
- package/agents/roles/system/backend-engineer/SKILL.md +4 -2
- package/agents/roles/system/backend-engineer/learning/HISTORY.md +1 -0
- package/agents/roles/system/business-strategist/SKILL.md +4 -2
- package/agents/roles/system/cloud-architect/SKILL.md +5 -0
- package/agents/roles/system/cloud-architect/learning/HISTORY.md +4 -0
- package/agents/roles/system/community-manager/SKILL.md +2 -0
- package/agents/roles/system/content-specialist/SKILL.md +4 -2
- package/agents/roles/system/customer-success-manager/SKILL.md +9 -2
- package/agents/roles/system/customer-success-manager/learning/HISTORY.md +1 -0
- package/agents/roles/system/customer-support-specialist/SKILL.md +4 -2
- package/agents/roles/system/data-analyst/SKILL.md +9 -2
- package/agents/roles/system/data-analyst/learning/HISTORY.md +1 -0
- package/agents/roles/system/data-engineer/SKILL.md +2 -0
- package/agents/roles/system/data-governance-steward/SKILL.md +2 -0
- package/agents/roles/system/data-scientist/SKILL.md +2 -0
- package/agents/roles/system/database-administrator/SKILL.md +2 -0
- package/agents/roles/system/database-administrator/learning/HISTORY.md +1 -0
- package/agents/roles/system/developer-relations-engineer/SKILL.md +2 -0
- package/agents/roles/system/devops-engineer/SKILL.md +4 -2
- package/agents/roles/system/engineering-manager/SKILL.md +2 -0
- package/agents/roles/system/financial-controller/SKILL.md +4 -2
- package/agents/roles/system/finops-engineer/SKILL.md +2 -0
- package/agents/roles/system/finops-engineer/learning/HISTORY.md +1 -0
- package/agents/roles/system/finops-engineer/learning/sources.yaml +12 -0
- package/agents/roles/system/fraud-risk-analyst/SKILL.md +7 -0
- package/agents/roles/system/fraud-risk-analyst/learning/HISTORY.md +1 -0
- package/agents/roles/system/frontend-engineer/SKILL.md +8 -2
- package/agents/roles/system/frontend-engineer/evaluations/cases/09-comment-panel/InternalNote.jsx +30 -0
- package/agents/roles/system/frontend-engineer/evaluations/cases/09-comment-panel.md +10 -0
- package/agents/roles/system/frontend-engineer/learning/HISTORY.md +1 -0
- package/agents/roles/system/growth-marketer/SKILL.md +17 -0
- package/agents/roles/system/growth-marketer/evaluations/cases/08-briefing-de-referidos.md +23 -0
- package/agents/roles/system/growth-marketer/evaluations/expected-behaviors.yaml +1 -0
- package/agents/roles/system/growth-marketer/learning/HISTORY.md +3 -0
- package/agents/roles/system/implementation-manager/SKILL.md +10 -0
- package/agents/roles/system/implementation-manager/evaluations/cases/08-signed-cutover-runbook/plan-cutover-tesela-rev-b.md +70 -0
- package/agents/roles/system/implementation-manager/evaluations/cases/08-signed-cutover-runbook.md +12 -0
- package/agents/roles/system/implementation-manager/evaluations/expected-behaviors.yaml +1 -0
- package/agents/roles/system/implementation-manager/learning/HISTORY.md +5 -0
- package/agents/roles/system/integrations-engineer/SKILL.md +6 -4
- package/agents/roles/system/kyc-aml-specialist/SKILL.md +11 -4
- package/agents/roles/system/kyc-aml-specialist/learning/HISTORY.md +2 -0
- package/agents/roles/system/kyc-aml-specialist/learning/sources.yaml +76 -1
- package/agents/roles/system/legal-counsel/SKILL.md +2 -0
- package/agents/roles/system/logistics-operations-manager/SKILL.md +17 -0
- package/agents/roles/system/logistics-operations-manager/evaluations/cases/07-entrega-a-tiempo/api-seguimiento-andesexpress.md +40 -0
- package/agents/roles/system/logistics-operations-manager/evaluations/cases/07-entrega-a-tiempo.md +2 -3
- package/agents/roles/system/logistics-operations-manager/learning/HISTORY.md +2 -0
- package/agents/roles/system/machine-learning-engineer/SKILL.md +2 -0
- package/agents/roles/system/mlops-engineer/SKILL.md +2 -0
- package/agents/roles/system/mobile-engineer/SKILL.md +4 -2
- package/agents/roles/system/partnerships-manager/SKILL.md +2 -0
- package/agents/roles/system/people-operations-manager/SKILL.md +2 -0
- package/agents/roles/system/privacy-compliance-specialist/SKILL.md +4 -2
- package/agents/roles/system/procurement-manager/SKILL.md +2 -0
- package/agents/roles/system/product-manager/SKILL.md +2 -0
- package/agents/roles/system/product-marketing-manager/SKILL.md +9 -2
- package/agents/roles/system/product-marketing-manager/learning/HISTORY.md +1 -0
- package/agents/roles/system/project-manager/SKILL.md +2 -0
- package/agents/roles/system/qa-engineer/SKILL.md +11 -2
- package/agents/roles/system/qa-engineer/evaluations/cases/07-agent-test-repair.md +1 -1
- package/agents/roles/system/qa-engineer/evaluations/cases/11-accessibility-sampling.md +10 -0
- package/agents/roles/system/qa-engineer/evaluations/cases/12-quoted-from-a-summary/resumen-legal-wcag22.md +28 -0
- package/agents/roles/system/qa-engineer/evaluations/cases/12-quoted-from-a-summary.md +10 -0
- package/agents/roles/system/qa-engineer/evaluations/cases/13-matrix-from-a-summary/wiki-plataforma-conformidad.md +24 -0
- package/agents/roles/system/qa-engineer/evaluations/cases/13-matrix-from-a-summary.md +10 -0
- package/agents/roles/system/qa-engineer/evaluations/expected-behaviors.yaml +2 -0
- package/agents/roles/system/qa-engineer/learning/HISTORY.md +4 -0
- package/agents/roles/system/qa-engineer/learning/sources.yaml +24 -3
- package/agents/roles/system/release-manager/SKILL.md +5 -3
- package/agents/roles/system/release-manager/evaluations/cases/09-provenance-without-origin.md +12 -0
- package/agents/roles/system/release-manager/learning/HISTORY.md +1 -0
- package/agents/roles/system/release-manager/references/operating-model.md +8 -0
- package/agents/roles/system/sales-representative/SKILL.md +4 -2
- package/agents/roles/system/security-engineer/SKILL.md +4 -2
- package/agents/roles/system/security-engineer/learning/HISTORY.md +1 -0
- package/agents/roles/system/site-reliability-engineer/SKILL.md +4 -2
- package/agents/roles/system/software-architect/SKILL.md +4 -2
- package/agents/roles/system/solutions-engineer/SKILL.md +2 -0
- package/agents/roles/system/tech-lead/SKILL.md +2 -0
- package/agents/roles/system/technical-program-manager/SKILL.md +2 -0
- package/agents/roles/system/technical-writer/SKILL.md +2 -0
- package/agents/roles/system/treasury-analyst/SKILL.md +6 -4
- package/agents/roles/system/ui-designer/SKILL.md +15 -0
- package/agents/roles/system/ui-designer/learning/HISTORY.md +2 -0
- package/agents/roles/system/user-researcher/SKILL.md +6 -0
- package/agents/roles/system/user-researcher/learning/HISTORY.md +1 -0
- package/agents/roles/system/ux-designer/SKILL.md +2 -0
- package/automatization/shared/eval-measured.js +35 -0
- package/automatization/shared/eval-only.js +15 -0
- package/automatization/workflows/README.md +27 -0
- package/automatization/workflows/agent-eval.js +42 -7
- package/automatization/workflows/agent-promote.js +65 -15
- package/automatization/workflows/autobuild.js +52 -8
- package/automatization/workflows/flow-eval.js +27 -7
- package/engine/agents/catalog.js +1 -1
- package/engine/agents/fork.js +1 -1
- package/engine/agents/learning-files.js +7 -2
- package/engine/agents/learning-seal.js +123 -0
- package/engine/agents/learning-sources.js +33 -3
- package/engine/agents/learning.js +80 -87
- package/engine/automation/hooks.js +0 -1
- package/engine/automation/index.js +0 -2
- package/engine/cli/args.js +2 -2
- package/engine/cli/catalog.js +33 -4
- package/engine/cli/instance.js +0 -2
- package/engine/cli/ops.js +2 -18
- package/engine/config/validate.js +7 -2
- package/engine/core/onboarding.js +0 -3
- package/engine/core/scan.js +1 -1
- package/engine/hooks/input.js +1 -1
- package/engine/integrations/proposals.js +1 -1
- package/engine/integrations/providers/jira.js +1 -1
- package/engine/integrations/registry.js +0 -1
- package/engine/planning/business-rules.js +1 -1
- package/engine/planning/contracts.js +8 -1
- package/engine/planning/parser.js +7 -1
- package/engine/schemas/ops-config.schema.json +60 -13
- package/flows/system/incident-review/flow.json +1 -1
- package/flows/system/incident-review/learning/HISTORY.md +1 -0
- package/package.json +4 -3
- package/template/planning/rules/system/conduct.md +19 -0
- package/template/tools/ops.js +2 -2
package/engine/cli/catalog.js
CHANGED
|
@@ -132,6 +132,16 @@ function learn(agent, cli) {
|
|
|
132
132
|
// aplicada editando frontmatter a mano es justo el paso que un agente hace mal en silencio.
|
|
133
133
|
// Un recorrido aprende de sus corridas y un cargo de su profesión: mismo ciclo, distinto insumo.
|
|
134
134
|
const kind = cli.has('--flow') ? 'flow' : 'agent'
|
|
135
|
+
// El tercer destino: se miró y no cambia nada. Sin esto sólo había aplicarla o dejarla esperando,
|
|
136
|
+
// y lo que se hacía era mergear el PR sin firmar — que deja el documento diciendo «sin aplicar»
|
|
137
|
+
// para siempre, indistinguible de una que espera trabajo.
|
|
138
|
+
if (cli.has('--archived')) {
|
|
139
|
+
const result = L.archive(opsRoot(), agent, cli.value('--period'), kind)
|
|
140
|
+
const relative = path.relative(opsRoot(), result.file)
|
|
141
|
+
return console.log(result.already
|
|
142
|
+
? `= ${relative} ya estaba archivada`
|
|
143
|
+
: `✓ ${relative} queda archivada: se miró y no cambia nada`)
|
|
144
|
+
}
|
|
135
145
|
if (cli.has('--applied')) {
|
|
136
146
|
const result = L.seal(opsRoot(), agent, cli.value('--period'), kind)
|
|
137
147
|
const relative = path.relative(opsRoot(), result.file)
|
|
@@ -139,14 +149,28 @@ function learn(agent, cli) {
|
|
|
139
149
|
? `= ${relative} ya estaba aplicada`
|
|
140
150
|
: `✓ ${relative} queda aplicada: no se vuelve a aplicar`)
|
|
141
151
|
}
|
|
152
|
+
// Un recorrido no tiene informe semanal: su propuesta se compone de los veredictos de sus propias
|
|
153
|
+
// corridas y nunca lee `learning/reports/`. La forma desnuda —la que para un cargo abre el informe
|
|
154
|
+
// de la semana— no tiene entonces qué abrir acá, y `prepareReport` lo decía resolviendo con el
|
|
155
|
+
// `kind` por defecto: «no existe agents/<tipo>/<slug>/SKILL.md», que manda a crear un cargo que no
|
|
156
|
+
// falta. Negarse nombrando el comando que sí corresponde es lo que cierra R13.
|
|
157
|
+
if (kind === 'flow' && !cli.has('--proposal')) {
|
|
158
|
+
fail(`${agent} es un recorrido: aprende de sus corridas, no de informes semanales.\n`
|
|
159
|
+
+ ` Abrí la propuesta con "ops learn ${agent} --flow --proposal".`, 2)
|
|
160
|
+
}
|
|
142
161
|
// `--period` es para consolidar a mano un mes que no es el de hoy. El ciclo automático no lo
|
|
143
162
|
// pasa: la propuesta se llama por el mes en que se abre y arrastra lo que todavía no entró.
|
|
144
163
|
const result = cli.has('--proposal')
|
|
145
164
|
? L.prepareProposal(opsRoot(), agent, new Date(), cli.value('--period'), kind)
|
|
146
165
|
: L.prepareReport(opsRoot(), agent)
|
|
147
|
-
// Sin
|
|
148
|
-
// y no
|
|
149
|
-
|
|
166
|
+
// Sin archivo que nombrar hay dos resultados distintos y decir cuál es el punto: no había material,
|
|
167
|
+
// o lo había y ninguno propuso un cambio. El segundo no es un error ni un mes perdido —el informe
|
|
168
|
+
// es histórico igual— y confundirlo con el primero manda a buscar por qué no se investigó.
|
|
169
|
+
if (!result.file) {
|
|
170
|
+
return console.log(result.quiet
|
|
171
|
+
? `= ${result.quiet} informe(s) sin recomendación: no hay qué proponer, quedan para el mes que viene`
|
|
172
|
+
: '= sin informes pendientes: no se abre propuesta')
|
|
173
|
+
}
|
|
150
174
|
console.log(`${result.created ? '+' : '='} ${path.relative(opsRoot(), result.file)}`)
|
|
151
175
|
// Un cargo consolida informes de su profesión; un recorrido, las corridas que lo midieron.
|
|
152
176
|
if (typeof result.reports === 'number') {
|
|
@@ -170,7 +194,12 @@ function evaluate(agent, caso, cli) {
|
|
|
170
194
|
}
|
|
171
195
|
// El caso es el posicional que sigue al cargo: `evaluate <cargo> --bench <caso>`. Sin él se arma
|
|
172
196
|
// un banco suelto, para mirarlo a mano; una corrida real pide uno por caso.
|
|
173
|
-
|
|
197
|
+
//
|
|
198
|
+
// Relativa a la raíz, como la de `--record`: esta salida la lee el agente que prepara los bancos,
|
|
199
|
+
// y de ahí la ruta viaja a los informes y a las propuestas que después lee otro cargo. Absoluta
|
|
200
|
+
// nombraba el directorio personal de una máquina, y así quedaron mil cuatrocientas ochenta y cinco
|
|
201
|
+
// citas que dejaron de resolver el día que este repositorio cambió de nombre.
|
|
202
|
+
return console.log(path.relative(root, evaluationBench(root, agent, caso, cli.has('--force'), kind)))
|
|
174
203
|
}
|
|
175
204
|
try {
|
|
176
205
|
// Los casos, para que un recorrido los ejecute. Sin `--json` no tiene sentido: es entrada de
|
package/engine/cli/instance.js
CHANGED
|
@@ -7,7 +7,6 @@
|
|
|
7
7
|
|
|
8
8
|
const fs = require('node:fs')
|
|
9
9
|
const path = require('node:path')
|
|
10
|
-
const { spawnSync } = require('node:child_process')
|
|
11
10
|
const F = require('../core/files')
|
|
12
11
|
const O = require('../core/ownership')
|
|
13
12
|
const CL = require('../core/changelog')
|
|
@@ -15,7 +14,6 @@ const M = require('../core/manifest')
|
|
|
15
14
|
const OB = require('../core/onboarding')
|
|
16
15
|
const P = require('../planning/parser')
|
|
17
16
|
const ST = require('../planning/state')
|
|
18
|
-
const I = require('../integrations/registry')
|
|
19
17
|
const A = require('../automation')
|
|
20
18
|
const { fail } = require('./io')
|
|
21
19
|
|
package/engine/cli/ops.js
CHANGED
|
@@ -4,25 +4,9 @@
|
|
|
4
4
|
const fs = require('node:fs')
|
|
5
5
|
const path = require('node:path')
|
|
6
6
|
const { spawnSync } = require('node:child_process')
|
|
7
|
-
const P = require('../planning/parser')
|
|
8
|
-
const B = require('../planning/business-rules')
|
|
9
|
-
const PC = require('../planning/contracts')
|
|
10
|
-
const ST = require('../planning/state')
|
|
11
|
-
const I = require('../integrations/registry')
|
|
12
|
-
const L = require('../agents/learning')
|
|
13
7
|
const A = require('../automation')
|
|
14
|
-
const F = require('../core/files')
|
|
15
|
-
const O = require('../core/ownership')
|
|
16
|
-
const CL = require('../core/changelog')
|
|
17
|
-
const M = require('../core/manifest')
|
|
18
|
-
const SC = require('../core/scan')
|
|
19
|
-
const OB = require('../core/onboarding')
|
|
20
|
-
const C = require('../config/validate')
|
|
21
|
-
const T = require('../flows/registry')
|
|
22
|
-
const AG = require('../agents/catalog')
|
|
23
|
-
const EV = require('../agents/evaluations')
|
|
24
8
|
const { FLAGS, parse } = require('./args')
|
|
25
|
-
const { fail
|
|
9
|
+
const { fail } = require('./io')
|
|
26
10
|
const IN = require('./instance')
|
|
27
11
|
const PL = require('./planning')
|
|
28
12
|
const CAT = require('./catalog')
|
|
@@ -170,7 +154,7 @@ function usage() {
|
|
|
170
154
|
ops automation doctor <ops-root> claude|codex|gemini|antigravity
|
|
171
155
|
ops automation install <ops-root> claude|codex|gemini|antigravity
|
|
172
156
|
ops automation uninstall <ops-root> claude|codex|gemini|antigravity
|
|
173
|
-
ops learn <agent|flow> [--flow] [--proposal [--period <AAAA-MM>]] [--applied [--period <AAAA-MM>]]
|
|
157
|
+
ops learn <agent|flow> [--flow] [--proposal [--period <AAAA-MM>]] [--applied|--archived [--period <AAAA-MM>]]
|
|
174
158
|
ops evaluate <agent|flow> [--flow] [--cases [--json]] [--bench [caso]] [--record [AAAA-MM-DD]]
|
|
175
159
|
ops agents list [ops-root] [--own|--system] [--json]
|
|
176
160
|
ops agents fork <cargo> [ops-root]
|
|
@@ -45,10 +45,15 @@ function validateWorkspaces(workspaces, errors) {
|
|
|
45
45
|
continue
|
|
46
46
|
}
|
|
47
47
|
for (const key of Object.keys(workspace)) {
|
|
48
|
-
if (!['name', 'path'].includes(key)) {
|
|
48
|
+
if (!['name', 'path', 'verify'].includes(key)) {
|
|
49
49
|
errors.push(`ops.config.json: workspaceRoots[${index}].${key} no está permitido`)
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
|
+
// Opcional: la raíz que no lo declara deja que quien verifica descubra la puerta, como siempre.
|
|
53
|
+
// Declararlo vacío es peor que no declararlo —promete una puerta y no la da—, así que se rechaza.
|
|
54
|
+
if ('verify' in workspace && (typeof workspace.verify !== 'string' || !workspace.verify.trim())) {
|
|
55
|
+
errors.push(`ops.config.json: workspaceRoots[${index}].verify debe ser el comando, o no estar`)
|
|
56
|
+
}
|
|
52
57
|
if (typeof workspace.name !== 'string' || !workspace.name.trim()) {
|
|
53
58
|
errors.push(`ops.config.json: workspaceRoots[${index}].name es obligatorio`)
|
|
54
59
|
}
|
|
@@ -78,4 +83,4 @@ function validateRunner(runner, errors) {
|
|
|
78
83
|
}
|
|
79
84
|
}
|
|
80
85
|
|
|
81
|
-
module.exports = {
|
|
86
|
+
module.exports = { validateOpsConfig }
|
package/engine/core/scan.js
CHANGED
package/engine/hooks/input.js
CHANGED
|
@@ -124,6 +124,6 @@ function findOpsRoot(start) {
|
|
|
124
124
|
}
|
|
125
125
|
|
|
126
126
|
module.exports = {
|
|
127
|
-
readInput, commandOf,
|
|
127
|
+
readInput, commandOf, patchOf, filesOf, contentOf, cwdOf, block, configOf,
|
|
128
128
|
gitDirectory, isCommit, stagedFiles, pushAllowed, findOpsRoot,
|
|
129
129
|
}
|
|
@@ -161,4 +161,4 @@ async function fetchItems(config, options = {}) {
|
|
|
161
161
|
return issues.map((issue) => normalizeIssue(issue, config))
|
|
162
162
|
}
|
|
163
163
|
|
|
164
|
-
module.exports = {
|
|
164
|
+
module.exports = { fetchItems, normalizeFixture, validateConfig }
|
|
@@ -297,6 +297,14 @@ function validateState({ epics, milestones, done, wip, roles = new Set(), humanA
|
|
|
297
297
|
for (const milestone of milestones) {
|
|
298
298
|
if (!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(milestone.slug)) errors.push(`hito con slug inválido: ${milestone.slug}`)
|
|
299
299
|
if (milestoneSlugs.has(milestone.slug)) errors.push(`hito duplicado: ${milestone.slug}`)
|
|
300
|
+
// La misma puerta que la épica y la tarea, en el nivel que no la tenía. Un hito agrupa trabajo bajo
|
|
301
|
+
// un nombre, y abrirlo con el nombre puesto para después es el camino natural: nadie promueve una
|
|
302
|
+
// tarea sin aceptación, y en cambio el título del hito se decide al final, cuando ya se construyó
|
|
303
|
+
// debajo. El marcador es lo único que se puede juzgar sin leer — un título vago sigue pasando, y
|
|
304
|
+
// eso es deliberado: acá también un heurístico sobre prosa se equivocaría en los dos sentidos.
|
|
305
|
+
if (PLACEHOLDERS.test(milestone.title)) {
|
|
306
|
+
errors.push(`hito ${milestone.slug}: el título no está decidido — "${milestone.title}"`)
|
|
307
|
+
}
|
|
300
308
|
milestoneSlugs.add(milestone.slug)
|
|
301
309
|
for (const task of milestone.tasks) {
|
|
302
310
|
if (!task.service) errors.push(`BACKLOG ${task.slug}: falta (service: <ruta>)`)
|
|
@@ -406,7 +414,6 @@ function oversizedUnits({ epics = [], milestones = [] }) {
|
|
|
406
414
|
}
|
|
407
415
|
|
|
408
416
|
module.exports = {
|
|
409
|
-
testedCriteria,
|
|
410
417
|
validateState,
|
|
411
418
|
oversizedUnits,
|
|
412
419
|
validateAdr,
|
|
@@ -153,6 +153,12 @@ function readCast(rest) {
|
|
|
153
153
|
}
|
|
154
154
|
}
|
|
155
155
|
|
|
156
|
+
// El texto de la aceptación, delimitado por las cursivas que lo envuelven. El cierre no es «el
|
|
157
|
+
// próximo guión bajo»: un identificador como `MAX_ATTEMPTS` trae los suyos, y cortar en el primero
|
|
158
|
+
// devolvía `MAX` con `check` en verde, que es la forma cara del error —la tarea se lee completa y no
|
|
159
|
+
// lo está—. Cierra el `_` que markdown cerraría: el que no está entre caracteres de palabra.
|
|
160
|
+
const ACCEPTANCE = /_Aceptaci[oó]n:\s*(.*?\S)_(?![A-Za-z0-9])/i
|
|
161
|
+
|
|
156
162
|
function readBacklog(dir) {
|
|
157
163
|
const text = withoutComments(read(path.join(dir, 'BACKLOG.md')))
|
|
158
164
|
const milestones = []
|
|
@@ -175,7 +181,7 @@ function readBacklog(dir) {
|
|
|
175
181
|
slug: task[1].trim(), tier: task[2] || '', cast: readCast(rest),
|
|
176
182
|
epic: ((rest.match(/\(epic:\s*(\d{3})\)/) || [])[1] || ''),
|
|
177
183
|
service: ((rest.match(/\(service:\s*([^)]+)\)/) || [])[1] || '').trim(),
|
|
178
|
-
acceptance: ((rest.match(
|
|
184
|
+
acceptance: ((rest.match(ACCEPTANCE) || [])[1] || '').trim(),
|
|
179
185
|
criteria: criteriaRefs(rest),
|
|
180
186
|
noSplit: noSplitReason(rest),
|
|
181
187
|
})
|
|
@@ -2,33 +2,80 @@
|
|
|
2
2
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
3
|
"title": "Cauce engine configuration",
|
|
4
4
|
"type": "object",
|
|
5
|
-
"required": [
|
|
5
|
+
"required": [
|
|
6
|
+
"project",
|
|
7
|
+
"mode",
|
|
8
|
+
"workspaceRoots",
|
|
9
|
+
"runner"
|
|
10
|
+
],
|
|
6
11
|
"properties": {
|
|
7
|
-
"$schema": {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
12
|
+
"$schema": {
|
|
13
|
+
"type": "string",
|
|
14
|
+
"minLength": 1
|
|
15
|
+
},
|
|
16
|
+
"cauceVersion": {
|
|
17
|
+
"type": "string",
|
|
18
|
+
"minLength": 1
|
|
19
|
+
},
|
|
20
|
+
"project": {
|
|
21
|
+
"type": "string",
|
|
22
|
+
"minLength": 1
|
|
23
|
+
},
|
|
24
|
+
"mode": {
|
|
25
|
+
"enum": [
|
|
26
|
+
"embedded",
|
|
27
|
+
"sidecar",
|
|
28
|
+
"toolkit"
|
|
29
|
+
]
|
|
30
|
+
},
|
|
11
31
|
"workspaceRoots": {
|
|
12
32
|
"type": "array",
|
|
13
33
|
"minItems": 1,
|
|
14
34
|
"items": {
|
|
15
35
|
"type": "object",
|
|
16
|
-
"required": [
|
|
36
|
+
"required": [
|
|
37
|
+
"name",
|
|
38
|
+
"path"
|
|
39
|
+
],
|
|
17
40
|
"properties": {
|
|
18
|
-
"name": {
|
|
19
|
-
|
|
41
|
+
"name": {
|
|
42
|
+
"type": "string",
|
|
43
|
+
"minLength": 1
|
|
44
|
+
},
|
|
45
|
+
"path": {
|
|
46
|
+
"type": "string",
|
|
47
|
+
"minLength": 1
|
|
48
|
+
},
|
|
49
|
+
"verify": {
|
|
50
|
+
"type": "string",
|
|
51
|
+
"description": "Comando que corre la puerta de esta raíz —pruebas, lint, typecheck, build—, tal como se invoca desde ella. Sin él, quien verifica tiene que descubrirlo leyendo el repositorio en cada tarea, y eso es trabajo de modelo repetido para siempre sobre una respuesta que no cambia."
|
|
52
|
+
}
|
|
20
53
|
},
|
|
21
54
|
"additionalProperties": false
|
|
22
55
|
}
|
|
23
56
|
},
|
|
24
57
|
"runner": {
|
|
25
58
|
"type": "object",
|
|
26
|
-
"required": [
|
|
59
|
+
"required": [
|
|
60
|
+
"maxTaskHours",
|
|
61
|
+
"humanCheckpointBetweenMilestones",
|
|
62
|
+
"commitPerTask",
|
|
63
|
+
"allowPush"
|
|
64
|
+
],
|
|
27
65
|
"properties": {
|
|
28
|
-
"maxTaskHours": {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
66
|
+
"maxTaskHours": {
|
|
67
|
+
"type": "number",
|
|
68
|
+
"exclusiveMinimum": 0
|
|
69
|
+
},
|
|
70
|
+
"humanCheckpointBetweenMilestones": {
|
|
71
|
+
"type": "boolean"
|
|
72
|
+
},
|
|
73
|
+
"commitPerTask": {
|
|
74
|
+
"type": "boolean"
|
|
75
|
+
},
|
|
76
|
+
"allowPush": {
|
|
77
|
+
"type": "boolean"
|
|
78
|
+
}
|
|
32
79
|
},
|
|
33
80
|
"additionalProperties": false
|
|
34
81
|
}
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"No se atribuye responsabilidad a personas; se analizan condiciones, no culpables.",
|
|
61
61
|
"Una causa sin evidencia se declara como hipótesis, aunque cerrar el informe sea más cómodo.",
|
|
62
62
|
"Ninguna comunicación a clientes ni notificación regulatoria sale de este recorrido: se propone y la decide una persona.",
|
|
63
|
-
"Los seguimientos quedan en el INBOX sin promover; convertirlos en trabajo es una decisión humana."
|
|
63
|
+
"Los seguimientos quedan en el INBOX sin promover y cada uno dice si previene la repetición o sólo acelera la detección; convertirlos en trabajo es una decisión humana, y esa distinción es lo único que permite ordenarlos."
|
|
64
64
|
],
|
|
65
65
|
"completion": [
|
|
66
66
|
"La línea de tiempo está sostenida por registros, no por reconstrucción de memoria.",
|
|
@@ -4,3 +4,4 @@ Registrar únicamente cambios aprobados por una persona, con fecha, la corrida q
|
|
|
4
4
|
|
|
5
5
|
| Fecha | Propuesta | Decisión | Aprobó | Cambio aplicado |
|
|
6
6
|
|---|---|---|---|---|
|
|
7
|
+
| 2026-08-30 | `2026-08.md` | aplicada | Manuel Pinzon | Un guardrail, y sólo su texto: cada seguimiento dice si previene la repetición o sólo acelera la detección. |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ingeniomaps/cauce",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.54.0",
|
|
4
4
|
"description": "Sistema portable de planificación y ejecución verificable para cualquier proyecto",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"planning",
|
|
@@ -33,8 +33,9 @@
|
|
|
33
33
|
"test": "bash test/tools/hooks-smoke.sh && node --test \"test/**/*.test.js\"",
|
|
34
34
|
"coverage": "bash test/tools/coverage.sh",
|
|
35
35
|
"coverage:update": "bash test/tools/coverage.sh --update",
|
|
36
|
-
"dead-
|
|
37
|
-
"
|
|
36
|
+
"dead-code": "node test/tools/dead-code.js",
|
|
37
|
+
"dead-code:engine": "node test/tools/dead-code.js --engine",
|
|
38
|
+
"ci": "npm run check && npm run automation:check && npm run integration:check && npm run dead-code:engine && npm run coverage",
|
|
38
39
|
"prepublishOnly": "npm run ci"
|
|
39
40
|
},
|
|
40
41
|
"engines": {
|
|
@@ -28,6 +28,25 @@ deja el pedido sin resolver: es la mitad barata del trabajo.
|
|
|
28
28
|
- Nombrar lo que falta no reemplaza a entregar lo que se puede: lo que sí se pudo establecer se escribe
|
|
29
29
|
igual, aunque quede parcial y marcado como tal.
|
|
30
30
|
|
|
31
|
+
El primer punto tiene un borde que se cruza sin notarlo. Faltar contexto es no saber **cómo**: qué
|
|
32
|
+
formato, qué borde, qué valor. Eso se supone y se entrega marcado, porque suponerlo mal cuesta una
|
|
33
|
+
corrección. No saber **qué se quiere ni para qué** es otra cosa, y ahí el borrador deja de ser barato:
|
|
34
|
+
todo lo que se construya encima hereda la suposición, y quien lo reciba no tiene cómo ver que el
|
|
35
|
+
objetivo era supuesto. El para qué tampoco es adorno — es lo que permite reconocer una respuesta
|
|
36
|
+
correcta, y sin él se cumple la aceptación al pie y no sirve.
|
|
37
|
+
|
|
38
|
+
Lo que separa los dos casos es si la respuesta existe en algún lado. Si está escrita —en la aceptación,
|
|
39
|
+
en el criterio que la unidad cita, en el contexto de la épica, en el código— entonces la unidad se
|
|
40
|
+
entiende y lo que falta es leerla: eso lo hace quien ejecuta y no interrumpe a nadie. Si contestarla
|
|
41
|
+
exigiera inventarla, no hay nada que leer y es una decisión que el cargo no tiene: se escala con la
|
|
42
|
+
pregunta exacta y con qué se desbloquea al contestarla. Es el mismo criterio con que R6 reparte el
|
|
43
|
+
hallazgo que aparece a mitad de camino —quién puede resolverlo, no cuán grave parece—, aplicado antes
|
|
44
|
+
de empezar en vez de durante.
|
|
45
|
+
|
|
46
|
+
Aclarar la redacción no es ampliar el alcance, y partir tampoco: una unidad que no se entiende porque
|
|
47
|
+
son dos resultados con vidas distintas se entiende partida, y eso no pide ninguna autoridad que el
|
|
48
|
+
cargo no tenga (R17). La pide elegir el objetivo, que es lo único que no se puede suponer.
|
|
49
|
+
|
|
31
50
|
Esto no afloja ningún límite: no promover, no prometer fechas, no inventar evidencia y no exceder la
|
|
32
51
|
autoridad del cargo siguen siendo absolutos. Lo que se cierra es la salida de cumplirlos sin entregar.
|
|
33
52
|
|
package/template/tools/ops.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
// Punto de entrada estable del proyecto: nadie —ni una persona ni un agente— necesita saber de
|
|
5
5
|
// dónde sale el motor. Viene de la dependencia npm, que el lockfile versiona.
|
|
6
6
|
//
|
|
7
|
-
// Nada de `require`, `__dirname` ni `import
|
|
7
|
+
// Nada de `require`, `__dirname` ni un `import` estático: el shim se instala en el proyecto y hereda el
|
|
8
8
|
// `type` de su `package.json`, así que el mismo archivo se carga como CommonJS en un repo y como
|
|
9
9
|
// ESM en el de al lado. `import()` dinámico y `process.argv[1]` son las dos únicas formas que
|
|
10
10
|
// existen bajo los dos cargadores; cualquier otra revienta en la mitad de los proyectos —`require
|
|
@@ -16,7 +16,7 @@ const root = self.slice(0, self.lastIndexOf('/', self.lastIndexOf('/') - 1)) ||
|
|
|
16
16
|
|
|
17
17
|
// El shim sabe dónde vive; quien lo invoca, no. En modo sidecar se lo llama desde la carpeta de la
|
|
18
18
|
// compañía —`node <empresa>-ops/tools/ops.js …`— y sin esto cada comando resolvería su raíz contra
|
|
19
|
-
// el cwd: `agents list` y `
|
|
19
|
+
// el cwd: `agents list` y `flow list` devolvían vacío en vez de fallar.
|
|
20
20
|
process.env.OPS_ROOT = process.env.OPS_ROOT || root
|
|
21
21
|
|
|
22
22
|
// El especificador se resuelve contra este archivo, así que sube a `<raíz>/node_modules` igual que
|