oxe-cc 1.5.0 → 1.5.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.
Files changed (38) hide show
  1. package/.cursor/commands/oxe-dashboard.md +2 -2
  2. package/.cursor/commands/oxe-execute.md +2 -2
  3. package/.cursor/commands/oxe-plan.md +2 -2
  4. package/.github/prompts/oxe-dashboard.prompt.md +2 -2
  5. package/.github/prompts/oxe-execute.prompt.md +2 -2
  6. package/.github/prompts/oxe-plan.prompt.md +2 -2
  7. package/CHANGELOG.md +25 -0
  8. package/README.md +2 -2
  9. package/bin/lib/oxe-context-engine.cjs +9 -4
  10. package/bin/lib/oxe-dashboard.cjs +119 -53
  11. package/bin/lib/oxe-project-health.cjs +368 -111
  12. package/bin/lib/oxe-rationality.cjs +385 -0
  13. package/bin/oxe-cc.js +57 -31
  14. package/commands/oxe/dashboard.md +2 -2
  15. package/commands/oxe/execute.md +2 -2
  16. package/commands/oxe/plan.md +2 -2
  17. package/docs/RUNTIME-SMOKE-MATRIX.md +1 -1
  18. package/lib/sdk/index.cjs +10 -6
  19. package/lib/sdk/index.d.ts +78 -24
  20. package/oxe/templates/CONFIG.md +1 -1
  21. package/oxe/templates/EXECUTION-RUNTIME.template.md +1 -1
  22. package/oxe/templates/FIXTURE-PACK.template.json +34 -0
  23. package/oxe/templates/FIXTURE-PACK.template.md +21 -0
  24. package/oxe/templates/IMPLEMENTATION-PACK.template.json +52 -0
  25. package/oxe/templates/IMPLEMENTATION-PACK.template.md +36 -0
  26. package/oxe/templates/PLAN.template.md +46 -37
  27. package/oxe/templates/REFERENCE-ANCHORS.template.md +24 -0
  28. package/oxe/templates/config.template.json +1 -1
  29. package/oxe/workflows/execute.md +36 -20
  30. package/oxe/workflows/next.md +1 -1
  31. package/oxe/workflows/plan.md +80 -22
  32. package/oxe/workflows/references/flow-robustness-contract.md +3 -3
  33. package/oxe/workflows/references/workflow-runtime-contracts.json +127 -95
  34. package/oxe/workflows/verify.md +4 -4
  35. package/package.json +1 -1
  36. package/packages/runtime/package.json +1 -1
  37. package/vscode-extension/oxe-agents-1.5.1.vsix +0 -0
  38. package/vscode-extension/package.json +1 -1
@@ -0,0 +1,385 @@
1
+ 'use strict';
2
+
3
+ const fs = require('fs');
4
+
5
+ function readTextIfExists(filePath) {
6
+ try {
7
+ return filePath && fs.existsSync(filePath) ? fs.readFileSync(filePath, 'utf8') : null;
8
+ } catch {
9
+ return null;
10
+ }
11
+ }
12
+
13
+ function readJsonIfExists(filePath) {
14
+ const text = readTextIfExists(filePath);
15
+ if (!text) return { ok: false, data: null, error: null };
16
+ try {
17
+ return { ok: true, data: JSON.parse(text), error: null };
18
+ } catch (error) {
19
+ return {
20
+ ok: false,
21
+ data: null,
22
+ error: error instanceof Error ? error.message : String(error),
23
+ };
24
+ }
25
+ }
26
+
27
+ function parseAttrs(fragment) {
28
+ /** @type {Record<string, string>} */
29
+ const attrs = {};
30
+ const raw = String(fragment || '');
31
+ for (const match of raw.matchAll(/([A-Za-z0-9_:-]+)="([^"]*)"/g)) {
32
+ attrs[match[1]] = match[2];
33
+ }
34
+ return attrs;
35
+ }
36
+
37
+ function normalizeTaskMode(value) {
38
+ const mode = String(value || '').trim().toLowerCase();
39
+ if (!mode) return 'mutating';
40
+ return mode;
41
+ }
42
+
43
+ function isMutatingMode(mode) {
44
+ return !new Set(['docs_only', 'not_applicable', 'external', 'docs-only']).has(normalizeTaskMode(mode));
45
+ }
46
+
47
+ function isTaskRiskKeyword(task) {
48
+ const text = `${task.title || ''} ${task.body || ''}`.toLowerCase();
49
+ return /(parser|parse|layout|integra|integration|contrato|contract|migra|migration|fila|queue|service bus|event grid|builder|payload|transform|cnab|listener|schema|ddl)/.test(text);
50
+ }
51
+
52
+ /**
53
+ * @param {string | null} planPath
54
+ * @returns {Array<{
55
+ * id: string,
56
+ * title: string,
57
+ * files: string[],
58
+ * complexity: string | null,
59
+ * body: string,
60
+ * }>}
61
+ */
62
+ function parsePlanTasks(planPath) {
63
+ const raw = readTextIfExists(planPath);
64
+ if (!raw) return [];
65
+ const parts = raw.split(/^###\s+(T\d+)\s*[—-]?\s*/m);
66
+ if (parts.length < 3) return [];
67
+ /** @type {ReturnType<typeof parsePlanTasks>} */
68
+ const tasks = [];
69
+ for (let i = 1; i < parts.length; i += 2) {
70
+ const id = String(parts[i] || '').trim();
71
+ const rest = String(parts[i + 1] || '').split(/^###\s+T\d+/m)[0];
72
+ const title = (((rest.match(/^([^\n]+)/) || [null, ''])[1]) || '').trim();
73
+ const filesLine = (((rest.match(/\*\*Arquivos\s+prov[aá]veis:\*\*\s*([^\n]+)/i) || [null, ''])[1]) || '').trim();
74
+ const backtickPaths = Array.from(filesLine.matchAll(/`([^`]+)`/g)).map((match) => match[1].trim()).filter(Boolean);
75
+ const files = backtickPaths.length
76
+ ? backtickPaths
77
+ : filesLine.split(',').map((entry) => entry.trim()).filter(Boolean);
78
+ const complexity = (((rest.match(/\*\*Complexidade:\*\*\s*([A-Z]+)/i) || [null, ''])[1]) || '').trim() || null;
79
+ tasks.push({ id, title, files, complexity, body: rest });
80
+ }
81
+ return tasks;
82
+ }
83
+
84
+ /**
85
+ * @param {string | null} planAgentsPath
86
+ * @returns {string[]}
87
+ */
88
+ function readExternalRefs(planAgentsPath) {
89
+ const parsed = readJsonIfExists(planAgentsPath);
90
+ if (!parsed.ok || !parsed.data || typeof parsed.data !== 'object') return [];
91
+ const agents = Array.isArray(parsed.data.agents) ? parsed.data.agents : [];
92
+ return agents
93
+ .flatMap((agent) => Array.isArray(agent && agent.inputs) ? agent.inputs : [])
94
+ .map((input) => String(input || '').trim())
95
+ .filter((input) => /^external-ref:/i.test(input));
96
+ }
97
+
98
+ function summarizeImplementationPack(filePath, planTasks) {
99
+ const parsed = readJsonIfExists(filePath);
100
+ /** @type {string[]} */
101
+ const criticalGaps = [];
102
+ if (!parsed.ok) {
103
+ return {
104
+ path: filePath,
105
+ exists: Boolean(readTextIfExists(filePath)),
106
+ parseError: parsed.error,
107
+ ready: false,
108
+ tasks: [],
109
+ taskCount: 0,
110
+ mutatingTasks: 0,
111
+ criticalGaps: [`IMPLEMENTATION-PACK.json inválido ou ausente${parsed.error ? `: ${parsed.error}` : ''}`],
112
+ };
113
+ }
114
+ const data = parsed.data && typeof parsed.data === 'object' ? parsed.data : {};
115
+ const tasks = Array.isArray(data.tasks) ? data.tasks : [];
116
+ const byId = new Map(tasks.map((task) => [String(task && task.id || task && task.task_id || '').trim(), task]).filter((entry) => entry[0]));
117
+ const allowedModes = new Set(['mutating', 'docs_only', 'not_applicable', 'external', 'docs-only']);
118
+ for (const planTask of planTasks) {
119
+ if (!byId.has(planTask.id)) {
120
+ criticalGaps.push(`IMPLEMENTATION-PACK.json sem contrato para ${planTask.id}`);
121
+ }
122
+ }
123
+ let mutatingTasks = 0;
124
+ for (const task of tasks) {
125
+ const id = String(task && task.id || task && task.task_id || '').trim();
126
+ const mode = normalizeTaskMode(task && task.mode);
127
+ const exactPaths = Array.isArray(task && task.exact_paths) ? task.exact_paths.map((entry) => String(entry || '').trim()).filter(Boolean) : [];
128
+ const symbols = Array.isArray(task && task.symbols) ? task.symbols : [];
129
+ const contracts = Array.isArray(task && task.contracts) ? task.contracts : [];
130
+ const expectedChecks = Array.isArray(task && task.expected_checks) ? task.expected_checks : [];
131
+ const gaps = Array.isArray(task && task.critical_gaps) ? task.critical_gaps : [];
132
+ if (!id) {
133
+ criticalGaps.push('IMPLEMENTATION-PACK.json com task sem id');
134
+ continue;
135
+ }
136
+ if (!allowedModes.has(mode)) {
137
+ criticalGaps.push(`IMPLEMENTATION-PACK.json tarefa ${id} com mode inválido: ${mode}`);
138
+ }
139
+ if (task && task.ready === false) {
140
+ criticalGaps.push(`IMPLEMENTATION-PACK.json tarefa ${id} marcada como not ready`);
141
+ }
142
+ if (gaps.length) {
143
+ criticalGaps.push(`IMPLEMENTATION-PACK.json tarefa ${id} com critical_gaps abertos`);
144
+ }
145
+ if (isMutatingMode(mode)) {
146
+ mutatingTasks += 1;
147
+ if (!exactPaths.length) {
148
+ criticalGaps.push(`IMPLEMENTATION-PACK.json tarefa ${id} sem exact_paths`);
149
+ }
150
+ if (exactPaths.some((entry) => entry.includes('...'))) {
151
+ criticalGaps.push(`IMPLEMENTATION-PACK.json tarefa ${id} com exact_paths ambíguos (...)`);
152
+ }
153
+ if (String(task && task.write_set || '').trim().toLowerCase() !== 'closed') {
154
+ criticalGaps.push(`IMPLEMENTATION-PACK.json tarefa ${id} com write_set aberto`);
155
+ }
156
+ if (!symbols.length) {
157
+ criticalGaps.push(`IMPLEMENTATION-PACK.json tarefa ${id} sem symbols`);
158
+ }
159
+ if (!contracts.length) {
160
+ criticalGaps.push(`IMPLEMENTATION-PACK.json tarefa ${id} sem contracts`);
161
+ }
162
+ if (!expectedChecks.length) {
163
+ criticalGaps.push(`IMPLEMENTATION-PACK.json tarefa ${id} sem expected_checks`);
164
+ }
165
+ }
166
+ }
167
+ if (data.ready === false) {
168
+ criticalGaps.push('IMPLEMENTATION-PACK.json com ready=false');
169
+ }
170
+ if (Array.isArray(data.critical_gaps) && data.critical_gaps.length) {
171
+ criticalGaps.push(...data.critical_gaps.map((gap) => `IMPLEMENTATION-PACK.json: ${String(gap)}`));
172
+ }
173
+ return {
174
+ path: filePath,
175
+ exists: true,
176
+ parseError: null,
177
+ ready: Boolean(data.ready) && criticalGaps.length === 0,
178
+ tasks,
179
+ taskCount: tasks.length,
180
+ mutatingTasks,
181
+ criticalGaps: Array.from(new Set(criticalGaps)),
182
+ };
183
+ }
184
+
185
+ function summarizeReferenceAnchors(filePath, externalRefs) {
186
+ const raw = readTextIfExists(filePath);
187
+ /** @type {string[]} */
188
+ const criticalGaps = [];
189
+ if (!raw) {
190
+ return {
191
+ path: filePath,
192
+ exists: false,
193
+ ready: false,
194
+ anchors: [],
195
+ missingCriticalCount: externalRefs.length,
196
+ staleCount: 0,
197
+ criticalGaps: ['REFERENCE-ANCHORS.md ausente'],
198
+ };
199
+ }
200
+ const rootMatch = raw.match(/<reference_anchors\b([^>]*)>([\s\S]*?)<\/reference_anchors>/i);
201
+ if (!rootMatch) {
202
+ return {
203
+ path: filePath,
204
+ exists: true,
205
+ ready: false,
206
+ anchors: [],
207
+ missingCriticalCount: externalRefs.length,
208
+ staleCount: 0,
209
+ criticalGaps: ['REFERENCE-ANCHORS.md sem bloco <reference_anchors>'],
210
+ };
211
+ }
212
+ const rootAttrs = parseAttrs(rootMatch[1]);
213
+ const status = String(rootAttrs.status || '').toLowerCase();
214
+ /** @type {Array<Record<string, unknown>>} */
215
+ const anchors = [];
216
+ for (const match of rootMatch[2].matchAll(/<anchor\b([^>]*)>([\s\S]*?)<\/anchor>/gi)) {
217
+ const attrs = parseAttrs(match[1]);
218
+ anchors.push({
219
+ id: attrs.id || null,
220
+ task: attrs.task || null,
221
+ critical: String(attrs.critical || '').toLowerCase() === 'true',
222
+ status: String(attrs.status || 'missing').toLowerCase(),
223
+ sourceType: attrs.source_type || null,
224
+ path: attrs.path || null,
225
+ sourceRef: attrs.source_ref || null,
226
+ relevance: (((match[2].match(/<relevance>([\s\S]*?)<\/relevance>/i) || [null, ''])[1]) || '').trim(),
227
+ action: (((match[2].match(/<action>([\s\S]*?)<\/action>/i) || [null, ''])[1]) || '').trim(),
228
+ summary: (((match[2].match(/<summary>([\s\S]*?)<\/summary>/i) || [null, ''])[1]) || '').trim(),
229
+ });
230
+ }
231
+ if (status === 'not_applicable' && externalRefs.length) {
232
+ criticalGaps.push('REFERENCE-ANCHORS.md marcado como not_applicable, mas há external-ref no blueprint');
233
+ }
234
+ let missingCriticalCount = 0;
235
+ let staleCount = 0;
236
+ for (const anchor of anchors) {
237
+ const anchorStatus = String(anchor.status || 'missing').toLowerCase();
238
+ if (anchorStatus === 'stale') staleCount += 1;
239
+ if (anchor.critical && anchorStatus !== 'resolved') {
240
+ missingCriticalCount += 1;
241
+ criticalGaps.push(`REFERENCE-ANCHORS.md âncora crítica ${anchor.id || anchor.sourceRef || '?'} em estado ${anchorStatus}`);
242
+ }
243
+ }
244
+ for (const ref of externalRefs) {
245
+ const matched = anchors.find((anchor) => String(anchor.sourceRef || '').trim() === ref);
246
+ if (!matched) {
247
+ missingCriticalCount += 1;
248
+ criticalGaps.push(`REFERENCE-ANCHORS.md sem âncora materializada para ${ref}`);
249
+ } else if (String(matched.status || '').toLowerCase() !== 'resolved') {
250
+ missingCriticalCount += 1;
251
+ criticalGaps.push(`REFERENCE-ANCHORS.md com ${ref} em estado ${matched.status}`);
252
+ }
253
+ }
254
+ if (String(rootAttrs.ready || '').toLowerCase() === 'false') {
255
+ criticalGaps.push('REFERENCE-ANCHORS.md com ready=false');
256
+ }
257
+ return {
258
+ path: filePath,
259
+ exists: true,
260
+ ready: status === 'not_applicable'
261
+ ? criticalGaps.length === 0
262
+ : Boolean(String(rootAttrs.ready || '').toLowerCase() !== 'false') && criticalGaps.length === 0,
263
+ anchors,
264
+ missingCriticalCount,
265
+ staleCount,
266
+ criticalGaps: Array.from(new Set(criticalGaps)),
267
+ };
268
+ }
269
+
270
+ function summarizeFixturePack(filePath, planTasks, implementationPack) {
271
+ const parsed = readJsonIfExists(filePath);
272
+ /** @type {string[]} */
273
+ const criticalGaps = [];
274
+ if (!parsed.ok) {
275
+ return {
276
+ path: filePath,
277
+ exists: Boolean(readTextIfExists(filePath)),
278
+ parseError: parsed.error,
279
+ ready: false,
280
+ fixtures: [],
281
+ fixtureCount: 0,
282
+ criticalGaps: [`FIXTURE-PACK.json inválido ou ausente${parsed.error ? `: ${parsed.error}` : ''}`],
283
+ };
284
+ }
285
+ const data = parsed.data && typeof parsed.data === 'object' ? parsed.data : {};
286
+ const fixtures = Array.isArray(data.fixtures) ? data.fixtures : [];
287
+ const byTask = new Map();
288
+ for (const fixture of fixtures) {
289
+ const taskId = String(fixture && fixture.task_id || fixture && fixture.taskId || '').trim();
290
+ if (!taskId) continue;
291
+ if (!byTask.has(taskId)) byTask.set(taskId, []);
292
+ byTask.get(taskId).push(fixture);
293
+ }
294
+ if (data.ready === false) {
295
+ criticalGaps.push('FIXTURE-PACK.json com ready=false');
296
+ }
297
+ if (Array.isArray(data.critical_gaps) && data.critical_gaps.length) {
298
+ criticalGaps.push(...data.critical_gaps.map((gap) => `FIXTURE-PACK.json: ${String(gap)}`));
299
+ }
300
+ const implementationTasks = Array.isArray(implementationPack.tasks) ? implementationPack.tasks : [];
301
+ for (const task of implementationTasks) {
302
+ const taskId = String(task && task.id || task && task.task_id || '').trim();
303
+ if (!taskId) continue;
304
+ const planTask = planTasks.find((candidate) => candidate.id === taskId);
305
+ const requiresFixture = task && task.requires_fixture === true
306
+ || (planTask ? isTaskRiskKeyword(planTask) : false);
307
+ if (!requiresFixture) continue;
308
+ const entries = byTask.get(taskId) || [];
309
+ if (!entries.length) {
310
+ criticalGaps.push(`FIXTURE-PACK.json sem fixture para ${taskId}`);
311
+ continue;
312
+ }
313
+ const readyFixture = entries.find((entry) => String(entry && entry.status || '').toLowerCase() === 'ready');
314
+ if (!readyFixture) {
315
+ criticalGaps.push(`FIXTURE-PACK.json sem fixture ready para ${taskId}`);
316
+ continue;
317
+ }
318
+ if (!Array.isArray(readyFixture.expected_checks) || readyFixture.expected_checks.length === 0) {
319
+ criticalGaps.push(`FIXTURE-PACK.json fixture de ${taskId} sem expected_checks`);
320
+ }
321
+ if (Array.isArray(readyFixture.critical_gaps) && readyFixture.critical_gaps.length) {
322
+ criticalGaps.push(`FIXTURE-PACK.json fixture de ${taskId} com critical_gaps abertos`);
323
+ }
324
+ }
325
+ return {
326
+ path: filePath,
327
+ exists: true,
328
+ parseError: null,
329
+ ready: Boolean(data.ready) && criticalGaps.length === 0,
330
+ fixtures,
331
+ fixtureCount: fixtures.length,
332
+ criticalGaps: Array.from(new Set(criticalGaps)),
333
+ };
334
+ }
335
+
336
+ /**
337
+ * @param {{
338
+ * plan?: string | null,
339
+ * planAgents?: string | null,
340
+ * implementationPackJson?: string | null,
341
+ * implementationPackMd?: string | null,
342
+ * referenceAnchors?: string | null,
343
+ * fixturePackJson?: string | null,
344
+ * fixturePackMd?: string | null,
345
+ * }} paths
346
+ */
347
+ function buildExecutionRationality(paths = {}) {
348
+ const planTasks = parsePlanTasks(paths.plan || null);
349
+ const externalRefs = readExternalRefs(paths.planAgents || null);
350
+ const implementationPack = summarizeImplementationPack(paths.implementationPackJson || null, planTasks);
351
+ const referenceAnchors = summarizeReferenceAnchors(paths.referenceAnchors || null, externalRefs);
352
+ const fixturePack = summarizeFixturePack(paths.fixturePackJson || null, planTasks, implementationPack);
353
+ const criticalExecutionGaps = Array.from(
354
+ new Set([
355
+ ...implementationPack.criticalGaps,
356
+ ...referenceAnchors.criticalGaps,
357
+ ...fixturePack.criticalGaps,
358
+ ])
359
+ );
360
+ const applicable = Boolean(paths.plan && fs.existsSync(paths.plan));
361
+ return {
362
+ applicable,
363
+ planTaskCount: planTasks.length,
364
+ externalReferenceCount: externalRefs.length,
365
+ implementationPackReady: applicable ? implementationPack.ready : false,
366
+ referenceAnchorsReady: applicable ? referenceAnchors.ready : false,
367
+ fixturePackReady: applicable ? fixturePack.ready : false,
368
+ executionRationalityReady: applicable
369
+ ? implementationPack.ready && referenceAnchors.ready && fixturePack.ready && criticalExecutionGaps.length === 0
370
+ : false,
371
+ criticalExecutionGaps,
372
+ implementationPack,
373
+ referenceAnchors,
374
+ fixturePack,
375
+ };
376
+ }
377
+
378
+ module.exports = {
379
+ buildExecutionRationality,
380
+ parsePlanTasks,
381
+ readExternalRefs,
382
+ summarizeImplementationPack,
383
+ summarizeReferenceAnchors,
384
+ summarizeFixturePack,
385
+ };
package/bin/oxe-cc.js CHANGED
@@ -1527,15 +1527,20 @@ function printOxeHealthDiagnostics(target, c, diagOpts = {}) {
1527
1527
  if (r.eventsSummary) {
1528
1528
  console.log(` ${c ? dim : ''}Tracing:${c ? reset : ''} ${r.eventsSummary.total} evento(s)`);
1529
1529
  }
1530
- if (r.planSelfEvaluation && r.planSelfEvaluation.hasSection) {
1531
- const best = r.planSelfEvaluation.bestPlan || '—';
1532
- const conf =
1533
- typeof r.planSelfEvaluation.confidence === 'number' ? `${r.planSelfEvaluation.confidence}%` : '—';
1534
- console.log(` ${c ? dim : ''}Plano (autoavaliação):${c ? reset : ''} melhor=${best} | confiança=${conf}`);
1535
- }
1536
- if (r.contextQuality) {
1537
- console.log(
1538
- ` ${c ? dim : ''}Contexto:${c ? reset : ''} score=${r.contextQuality.primaryScore != null ? r.contextQuality.primaryScore : ''} | workflow=${r.contextQuality.primaryWorkflow || ''} | status=${r.contextQuality.primaryStatus || ''}`
1530
+ if (r.planSelfEvaluation && r.planSelfEvaluation.hasSection) {
1531
+ const best = r.planSelfEvaluation.bestPlan || '—';
1532
+ const conf =
1533
+ typeof r.planSelfEvaluation.confidence === 'number' ? `${r.planSelfEvaluation.confidence}%` : '—';
1534
+ console.log(` ${c ? dim : ''}Plano (autoavaliação):${c ? reset : ''} melhor=${best} | confiança=${conf}`);
1535
+ }
1536
+ if (typeof r.executionRationalityReady === 'boolean') {
1537
+ console.log(
1538
+ ` ${c ? dim : ''}Prontidão racional:${c ? reset : ''} implementation=${r.implementationPackReady ? 'ok' : 'pendente'} | anchors=${r.referenceAnchorsReady ? 'ok' : 'pendente'} | fixtures=${r.fixturePackReady ? 'ok' : 'pendente'}`
1539
+ );
1540
+ }
1541
+ if (r.contextQuality) {
1542
+ console.log(
1543
+ ` ${c ? dim : ''}Contexto:${c ? reset : ''} score=${r.contextQuality.primaryScore != null ? r.contextQuality.primaryScore : '—'} | workflow=${r.contextQuality.primaryWorkflow || '—'} | status=${r.contextQuality.primaryStatus || '—'}`
1539
1544
  );
1540
1545
  }
1541
1546
  if (r.semanticsDrift) {
@@ -1696,17 +1701,24 @@ function runStatusFull(target) {
1696
1701
  console.log(` ${coverageCell(codebaseExists, 'codebase scan')} ${coverageCell(specExists, 'SPEC.md')} ${coverageCell(planExists, 'PLAN.md')} ${coverageCell(verifyExists, 'VERIFY.md')} ${coverageCell(lessonsExists, 'LESSONS.md')}`);
1697
1702
 
1698
1703
  // Readiness gate
1699
- const ready = specExists && planExists && !report.planWarn.length && !report.runtimeWarn.length;
1704
+ const ready = specExists
1705
+ && planExists
1706
+ && report.executionRationalityReady
1707
+ && !report.planWarn.length
1708
+ && !report.runtimeWarn.length;
1700
1709
  const gateColor = ready ? green : yellow;
1701
1710
  console.log(`\n ${c ? yellow : ''}Readiness gate${c ? reset : ''}`);
1702
1711
  console.log(` ${c ? gateColor : ''}${ready ? '✓ Pronto para executar' : '✗ Não pronto para executar'}${c ? reset : ''}`);
1703
1712
  if (!specExists) console.log(` ${c ? dim : ''} • SPEC.md ausente — rode /oxe-spec${c ? reset : ''}`);
1704
1713
  if (!planExists) console.log(` ${c ? dim : ''} • PLAN.md ausente — rode /oxe-plan${c ? reset : ''}`);
1705
- if (report.planWarn.length) {
1706
- for (const w of report.planWarn) {
1707
- console.log(` ${c ? yellow : ''} • ${w}${c ? reset : ''}`);
1708
- }
1709
- }
1714
+ if (report.planWarn.length) {
1715
+ for (const w of report.planWarn) {
1716
+ console.log(` ${c ? yellow : ''} • ${w}${c ? reset : ''}`);
1717
+ }
1718
+ }
1719
+ if (planExists) {
1720
+ console.log(` ${c ? dim : ''} • Artefatos racionais:${c ? reset : ''} implementation=${report.implementationPackReady ? 'ok' : 'pendente'} · anchors=${report.referenceAnchorsReady ? 'ok' : 'pendente'} · fixtures=${report.fixturePackReady ? 'ok' : 'pendente'}`);
1721
+ }
1710
1722
 
1711
1723
  // Active run summary
1712
1724
  if (report.activeRun) {
@@ -1792,18 +1804,24 @@ function runStatusFull(target) {
1792
1804
  }
1793
1805
 
1794
1806
  // Plan self-evaluation
1795
- if (report.planSelfEvaluation) {
1796
- const pse = report.planSelfEvaluation;
1797
- console.log(`\n ${c ? yellow : ''}Autoavaliação do plano${c ? reset : ''}`);
1798
- if (pse.best_plan_current != null) {
1799
- const bestColor = pse.best_plan_current ? green : red;
1800
- console.log(` ${c ? dim : ''}Melhor plano atual:${c ? reset : ''} ${c ? bestColor : ''}${pse.best_plan_current ? 'sim' : 'não'}${c ? reset : ''}`);
1801
- }
1802
- if (pse.confidence != null) {
1803
- const confColor = Number(pse.confidence) >= 70 ? green : Number(pse.confidence) >= 50 ? yellow : red;
1804
- console.log(` ${c ? dim : ''}Confiança:${c ? reset : ''} ${c ? confColor : ''}${pse.confidence}%${c ? reset : ''}`);
1805
- }
1806
- }
1807
+ if (report.planSelfEvaluation) {
1808
+ const pse = report.planSelfEvaluation;
1809
+ const threshold = report.planConfidenceThreshold || 90;
1810
+ console.log(`\n ${c ? yellow : ''}Autoavaliação do plano${c ? reset : ''}`);
1811
+ if (pse.best_plan_current != null) {
1812
+ const bestColor = pse.best_plan_current ? green : red;
1813
+ console.log(` ${c ? dim : ''}Melhor plano atual:${c ? reset : ''} ${c ? bestColor : ''}${pse.best_plan_current ? 'sim' : 'não'}${c ? reset : ''}`);
1814
+ }
1815
+ if (pse.confidence != null) {
1816
+ const confColor = report.planConfidenceExecutable
1817
+ ? green
1818
+ : Number(pse.confidence) >= Math.max(80, threshold - 10)
1819
+ ? yellow
1820
+ : red;
1821
+ console.log(` ${c ? dim : ''}Confiança:${c ? reset : ''} ${c ? confColor : ''}${pse.confidence}%${c ? reset : ''}`);
1822
+ console.log(` ${c ? dim : ''}Gate executável:${c ? reset : ''} > ${threshold}%${pse.executable ? ' (atingido)' : ' (ainda não atingido)'}`);
1823
+ }
1824
+ }
1807
1825
 
1808
1826
  console.log(`\n ${c ? dim : ''}Próximo passo:${c ? reset : ''} ${c ? cyan : ''}${report.next && report.next.cursorCmd ? report.next.cursorCmd : '—'}${c ? reset : ''}`);
1809
1827
  console.log(` ${c ? dim : ''}Motivo:${c ? reset : ''} ${report.next && report.next.reason ? report.next.reason : '—'}`);
@@ -1835,10 +1853,18 @@ function runStatus(target, opts = {}) {
1835
1853
  activeSession: report.activeSession,
1836
1854
  scanDate: report.scanDate,
1837
1855
  staleScan: report.stale,
1838
- compactDate: report.compactDate,
1839
- staleCompact: report.staleCompact,
1840
- planSelfEvaluation: report.planSelfEvaluation,
1841
- planReviewStatus: report.planReviewStatus,
1856
+ compactDate: report.compactDate,
1857
+ staleCompact: report.staleCompact,
1858
+ planSelfEvaluation: report.planSelfEvaluation,
1859
+ planConfidenceThreshold: report.planConfidenceThreshold,
1860
+ planConfidenceExecutable: report.planConfidenceExecutable,
1861
+ implementationPackReady: report.implementationPackReady,
1862
+ referenceAnchorsReady: report.referenceAnchorsReady,
1863
+ fixturePackReady: report.fixturePackReady,
1864
+ executionRationalityReady: report.executionRationalityReady,
1865
+ criticalExecutionGaps: report.criticalExecutionGaps,
1866
+ executionRationality: report.executionRationality,
1867
+ planReviewStatus: report.planReviewStatus,
1842
1868
  activeRun: report.activeRun,
1843
1869
  eventsSummary: report.eventsSummary,
1844
1870
  runtimeMode: report.runtimeMode,
@@ -15,7 +15,7 @@ oxe_tool_profile: read_heavy
15
15
  oxe_confidence_policy: explicit
16
16
  oxe_context_tier: standard
17
17
  oxe_contract_version: 2.0.0
18
- oxe_semantics_hash: 37f74d8be3442fe1
18
+ oxe_semantics_hash: ebb4473c14e5b080
19
19
  ---
20
20
 
21
21
  <!-- oxe-reasoning-contract:start -->
@@ -29,7 +29,7 @@ oxe_semantics_hash: 37f74d8be3442fe1
29
29
  - **Política de confiança:** explícita
30
30
  - **Tier de contexto padrão:** padrão
31
31
  - **Versão do contrato:** 2.0.0
32
- - **Checksum semântico:** `37f74d8be3442fe1`
32
+ - **Checksum semântico:** `ebb4473c14e5b080`
33
33
  - **Entrada de contexto prioritária:** `.oxe/context/packs/dashboard.md` e `.oxe/context/packs/dashboard.json`
34
34
  - **Regra pack-first:** ler o context pack primeiro; se estiver stale, incompleto ou ausente, cair para leitura direta com fallback explícito.
35
35
  - **Inspeção estruturada:** `oxe-cc context inspect --workflow dashboard --json`
@@ -17,7 +17,7 @@ oxe_tool_profile: write_bounded
17
17
  oxe_confidence_policy: explicit
18
18
  oxe_context_tier: standard
19
19
  oxe_contract_version: 2.0.0
20
- oxe_semantics_hash: 14ddb483209b28b3
20
+ oxe_semantics_hash: 7b3446b77aef9353
21
21
  ---
22
22
 
23
23
  <!-- oxe-reasoning-contract:start -->
@@ -31,7 +31,7 @@ oxe_semantics_hash: 14ddb483209b28b3
31
31
  - **Política de confiança:** explícita
32
32
  - **Tier de contexto padrão:** padrão
33
33
  - **Versão do contrato:** 2.0.0
34
- - **Checksum semântico:** `14ddb483209b28b3`
34
+ - **Checksum semântico:** `7b3446b77aef9353`
35
35
  - **Entrada de contexto prioritária:** `.oxe/context/packs/execute.md` e `.oxe/context/packs/execute.json`
36
36
  - **Regra pack-first:** ler o context pack primeiro; se estiver stale, incompleto ou ausente, cair para leitura direta com fallback explícito.
37
37
  - **Inspeção estruturada:** `oxe-cc context inspect --workflow execute --json`
@@ -16,7 +16,7 @@ oxe_tool_profile: mixed
16
16
  oxe_confidence_policy: rubric
17
17
  oxe_context_tier: standard
18
18
  oxe_contract_version: 2.0.0
19
- oxe_semantics_hash: 7809d830a5f5ff4a
19
+ oxe_semantics_hash: 5c589398cb807029
20
20
  ---
21
21
 
22
22
  <!-- oxe-reasoning-contract:start -->
@@ -30,7 +30,7 @@ oxe_semantics_hash: 7809d830a5f5ff4a
30
30
  - **Política de confiança:** rubrica
31
31
  - **Tier de contexto padrão:** padrão
32
32
  - **Versão do contrato:** 2.0.0
33
- - **Checksum semântico:** `7809d830a5f5ff4a`
33
+ - **Checksum semântico:** `5c589398cb807029`
34
34
  - **Entrada de contexto prioritária:** `.oxe/context/packs/plan.md` e `.oxe/context/packs/plan.json`
35
35
  - **Regra pack-first:** ler o context pack primeiro; se estiver stale, incompleto ou ausente, cair para leitura direta com fallback explícito.
36
36
  - **Inspeção estruturada:** `oxe-cc context inspect --workflow plan --json`
@@ -1,6 +1,6 @@
1
1
  # OXE — Runtime Smoke Matrix
2
2
 
3
- > Estado de suporte por runtime de IA. Atualizado em v1.5.0.
3
+ > Estado de suporte por runtime de IA. Atualizado em v1.5.1.
4
4
  >
5
5
  > `✓` = suportado e testado | `~` = suportado parcialmente | `✗` = não suportado | `?` = não testado
6
6
 
package/lib/sdk/index.cjs CHANGED
@@ -20,6 +20,7 @@ const azure = require('../../bin/lib/oxe-azure.cjs');
20
20
  const context = require('../../bin/lib/oxe-context-engine.cjs');
21
21
  const runtimeSemantics = require('../../bin/lib/oxe-runtime-semantics.cjs');
22
22
  const release = require('../../bin/lib/oxe-release.cjs');
23
+ const rationality = require('../../bin/lib/oxe-rationality.cjs');
23
24
 
24
25
  const PACKAGE_ROOT = path.join(__dirname, '..', '..');
25
26
 
@@ -541,9 +542,10 @@ module.exports = {
541
542
  /** Parsing de artefatos OXE (PLAN, SPEC, STATE, hypotheses, confidence, lessons). */
542
543
  parsePlan,
543
544
  parseSpec,
544
- parseHypotheses: context.parseHypotheses,
545
- parseConfidenceVector: context.parseConfidenceVector,
546
- parseState,
545
+ parseHypotheses: context.parseHypotheses,
546
+ parseConfidenceVector: context.parseConfidenceVector,
547
+ parseExecutionPlanTasks: rationality.parsePlanTasks,
548
+ parseState,
547
549
  validateDecisionFidelity,
548
550
  parseLessonsMetrics,
549
551
  updateLessonMetric,
@@ -568,9 +570,11 @@ module.exports = {
568
570
  planAgentsWarnings: health.planAgentsWarnings,
569
571
  phaseCoherenceWarnings: health.phaseCoherenceWarnings,
570
572
  specSectionWarnings: health.specSectionWarnings,
571
- planWaveWarningsFixed: health.planWaveWarningsFixed,
572
- planTaskAceiteWarnings: health.planTaskAceiteWarnings,
573
- verifyGapsWithoutSummaryWarning: health.verifyGapsWithoutSummaryWarning,
573
+ planWaveWarningsFixed: health.planWaveWarningsFixed,
574
+ planTaskAceiteWarnings: health.planTaskAceiteWarnings,
575
+ buildExecutionRationality: health.buildExecutionRationality,
576
+ executionRationalityWarningsFromSummary: health.executionRationalityWarningsFromSummary,
577
+ verifyGapsWithoutSummaryWarning: health.verifyGapsWithoutSummaryWarning,
574
578
  expandExecutionProfile: health.expandExecutionProfile,
575
579
  ALLOWED_CONFIG_KEYS: health.ALLOWED_CONFIG_KEYS,
576
580
  EXECUTION_PROFILES: health.EXECUTION_PROFILES,