oxe-cc 1.8.3 → 1.10.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.
Files changed (42) 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/.cursor/commands/oxe-quick.md +2 -2
  5. package/.cursor/commands/oxe-spec.md +3 -3
  6. package/.github/prompts/oxe-dashboard.prompt.md +2 -2
  7. package/.github/prompts/oxe-execute.prompt.md +2 -2
  8. package/.github/prompts/oxe-plan.prompt.md +2 -2
  9. package/.github/prompts/oxe-quick.prompt.md +2 -2
  10. package/.github/prompts/oxe-spec.prompt.md +3 -3
  11. package/AGENTS.md +1 -1
  12. package/CHANGELOG.md +45 -0
  13. package/README.md +32 -26
  14. package/bin/lib/oxe-context-engine.cjs +2 -0
  15. package/bin/lib/oxe-operational.cjs +230 -74
  16. package/bin/lib/oxe-project-health.cjs +43 -9
  17. package/bin/lib/oxe-rationality.cjs +146 -1
  18. package/bin/lib/oxe-release.cjs +55 -0
  19. package/bin/oxe-cc.js +60 -37
  20. package/commands/oxe/dashboard.md +2 -2
  21. package/commands/oxe/execute.md +2 -2
  22. package/commands/oxe/plan.md +2 -2
  23. package/commands/oxe/quick.md +2 -2
  24. package/commands/oxe/spec.md +3 -3
  25. package/docs/RELEASE-READINESS.md +8 -1
  26. package/lib/runtime/scheduler/multi-agent-coordinator.d.ts +48 -0
  27. package/lib/runtime/scheduler/multi-agent-coordinator.js +274 -14
  28. package/lib/runtime/workspace/strategies/git-worktree.js +18 -9
  29. package/oxe/templates/REFERENCE-ANCHORS.template.md +12 -5
  30. package/oxe/templates/SPEC.template.md +10 -0
  31. package/oxe/templates/VISUAL-INPUTS.template.json +27 -0
  32. package/oxe/templates/VISUAL-INPUTS.template.md +36 -0
  33. package/oxe/workflows/execute.md +3 -0
  34. package/oxe/workflows/plan.md +13 -9
  35. package/oxe/workflows/references/workflow-runtime-contracts.json +44 -29
  36. package/oxe/workflows/spec.md +19 -8
  37. package/oxe/workflows/ui-spec.md +3 -2
  38. package/package.json +6 -3
  39. package/packages/runtime/package.json +1 -1
  40. package/packages/runtime/src/scheduler/multi-agent-coordinator.ts +379 -47
  41. package/packages/runtime/src/workspace/strategies/git-worktree.ts +24 -16
  42. package/vscode-extension/package.json +1 -1
@@ -223,9 +223,14 @@ function summarizeReferenceAnchors(filePath, externalRefs) {
223
223
  sourceType: attrs.source_type || null,
224
224
  path: attrs.path || null,
225
225
  sourceRef: attrs.source_ref || null,
226
+ visualRef: attrs.visual_ref || null,
227
+ extractionConfidence: attrs.extraction_confidence || null,
228
+ reproducibility: attrs.reproducibility || null,
226
229
  relevance: (((match[2].match(/<relevance>([\s\S]*?)<\/relevance>/i) || [null, ''])[1]) || '').trim(),
227
230
  action: (((match[2].match(/<action>([\s\S]*?)<\/action>/i) || [null, ''])[1]) || '').trim(),
228
231
  summary: (((match[2].match(/<summary>([\s\S]*?)<\/summary>/i) || [null, ''])[1]) || '').trim(),
232
+ limitations: (((match[2].match(/<limitations>([\s\S]*?)<\/limitations>/i) || [null, ''])[1]) || '').trim(),
233
+ derivedRequirements: (((match[2].match(/<derived_requirements>([\s\S]*?)<\/derived_requirements>/i) || [null, ''])[1]) || '').trim(),
229
234
  });
230
235
  }
231
236
  if (status === 'not_applicable' && externalRefs.length) {
@@ -267,6 +272,136 @@ function summarizeReferenceAnchors(filePath, externalRefs) {
267
272
  };
268
273
  }
269
274
 
275
+ function specRequiresVisualInput(specPath) {
276
+ const raw = readTextIfExists(specPath);
277
+ if (!raw) return false;
278
+ const text = raw.toLowerCase();
279
+ if (/visualinputreadiness\s*:\s*(ready|partial|blocked)/i.test(raw)) return true;
280
+ if (/<visual_inputs?\b/i.test(raw)) return true;
281
+ if (/##+\s*entradas visuais e interpreta[çc][ãa]o/i.test(raw) && !/not_applicable|não aplicável|nao aplicavel/i.test(raw)) {
282
+ return true;
283
+ }
284
+ return /\b(visual-?inputs?|visual attachment|screenshot|mockup|imagem anexada|anexo visual)\b/i.test(text);
285
+ }
286
+
287
+ function normalizeInspectionStatus(value) {
288
+ const status = String(value || '').trim().toLowerCase();
289
+ if (!status) return 'unavailable';
290
+ return status;
291
+ }
292
+
293
+ function summarizeVisualInputs(paths = {}) {
294
+ const specPath = paths.spec || null;
295
+ const jsonPath = paths.visualInputsJson || null;
296
+ const mdPath = paths.visualInputsMd || null;
297
+ const specRequires = specRequiresVisualInput(specPath);
298
+ const json = readJsonIfExists(jsonPath);
299
+ const mdExists = Boolean(readTextIfExists(mdPath));
300
+ const exists = Boolean(json.ok || mdExists);
301
+ const applicable = specRequires || exists;
302
+ /** @type {string[]} */
303
+ const criticalGaps = [];
304
+ if (!applicable) {
305
+ return {
306
+ applicable: false,
307
+ ready: true,
308
+ visualInputReadiness: 'not_applicable',
309
+ path: jsonPath,
310
+ markdownPath: mdPath,
311
+ exists,
312
+ inputCount: 0,
313
+ criticalInputCount: 0,
314
+ blockedCount: 0,
315
+ partialCount: 0,
316
+ inputs: [],
317
+ criticalGaps: [],
318
+ };
319
+ }
320
+ if (!json.ok) {
321
+ criticalGaps.push(`VISUAL-INPUTS.json inválido ou ausente${json.error ? `: ${json.error}` : ''}`);
322
+ return {
323
+ applicable: true,
324
+ ready: false,
325
+ visualInputReadiness: 'blocked',
326
+ path: jsonPath,
327
+ markdownPath: mdPath,
328
+ exists,
329
+ inputCount: 0,
330
+ criticalInputCount: 0,
331
+ blockedCount: 1,
332
+ partialCount: 0,
333
+ inputs: [],
334
+ criticalGaps,
335
+ };
336
+ }
337
+ const data = json.data && typeof json.data === 'object' ? json.data : {};
338
+ const inputs = Array.isArray(data.inputs) ? data.inputs : [];
339
+ const topReady = data.ready !== false;
340
+ let criticalInputCount = 0;
341
+ let blockedCount = 0;
342
+ let partialCount = 0;
343
+ for (const input of inputs) {
344
+ const id = String(input && (input.id || input.source_ref || input.sourceRef) || '?');
345
+ const critical = Boolean(input && input.critical === true);
346
+ const status = normalizeInspectionStatus(input && input.inspection_status);
347
+ const confidence = Number(input && input.confidence);
348
+ const summary = String(input && input.visual_summary || '').trim();
349
+ const derived = Array.isArray(input && input.derived_requirements)
350
+ ? input.derived_requirements
351
+ : [];
352
+ if (critical) criticalInputCount += 1;
353
+ if (status === 'partial') partialCount += 1;
354
+ if (critical && status !== 'inspected') {
355
+ blockedCount += 1;
356
+ criticalGaps.push(`VISUAL-INPUTS.json entrada crítica ${id} com inspection_status=${status}`);
357
+ }
358
+ if (critical && !summary) {
359
+ blockedCount += 1;
360
+ criticalGaps.push(`VISUAL-INPUTS.json entrada crítica ${id} sem visual_summary`);
361
+ }
362
+ if (critical && !derived.length) {
363
+ blockedCount += 1;
364
+ criticalGaps.push(`VISUAL-INPUTS.json entrada crítica ${id} sem derived_requirements`);
365
+ }
366
+ if (critical && Number.isFinite(confidence) && confidence < 0.75) {
367
+ partialCount += 1;
368
+ criticalGaps.push(`VISUAL-INPUTS.json entrada crítica ${id} com confidence abaixo de 0.75`);
369
+ }
370
+ }
371
+ if (data.visualInputReadiness === 'blocked') {
372
+ blockedCount += 1;
373
+ criticalGaps.push('VISUAL-INPUTS.json declara visualInputReadiness=blocked');
374
+ }
375
+ if (Array.isArray(data.critical_gaps) && data.critical_gaps.length) {
376
+ blockedCount += data.critical_gaps.length;
377
+ criticalGaps.push(...data.critical_gaps.map((gap) => `VISUAL-INPUTS.json: ${String(gap)}`));
378
+ }
379
+ if (!topReady) {
380
+ blockedCount += 1;
381
+ criticalGaps.push('VISUAL-INPUTS.json com ready=false');
382
+ }
383
+ const uniqueGaps = Array.from(new Set(criticalGaps));
384
+ const visualInputReadiness = uniqueGaps.length
385
+ ? 'blocked'
386
+ : partialCount > 0 || data.visualInputReadiness === 'partial'
387
+ ? 'partial'
388
+ : 'ready';
389
+ return {
390
+ applicable: true,
391
+ ready: visualInputReadiness !== 'blocked',
392
+ visualInputReadiness,
393
+ path: jsonPath,
394
+ markdownPath: mdPath,
395
+ exists,
396
+ inputCount: inputs.length,
397
+ criticalInputCount,
398
+ blockedCount,
399
+ partialCount,
400
+ inputs,
401
+ criticalGaps: uniqueGaps,
402
+ };
403
+ }
404
+
270
405
  function summarizeFixturePack(filePath, planTasks, implementationPack) {
271
406
  const parsed = readJsonIfExists(filePath);
272
407
  /** @type {string[]} */
@@ -350,6 +485,11 @@ function buildExecutionRationality(paths = {}) {
350
485
  const implementationPack = summarizeImplementationPack(paths.implementationPackJson || null, planTasks);
351
486
  const referenceAnchors = summarizeReferenceAnchors(paths.referenceAnchors || null, externalRefs);
352
487
  const fixturePack = summarizeFixturePack(paths.fixturePackJson || null, planTasks, implementationPack);
488
+ const visualInputs = summarizeVisualInputs({
489
+ spec: paths.spec || null,
490
+ visualInputsJson: paths.visualInputsJson || null,
491
+ visualInputsMd: paths.visualInputsMd || null,
492
+ });
353
493
  const applicable = Boolean(paths.plan && fs.existsSync(paths.plan));
354
494
  const criticalExecutionGaps = applicable
355
495
  ? Array.from(
@@ -357,6 +497,7 @@ function buildExecutionRationality(paths = {}) {
357
497
  ...implementationPack.criticalGaps,
358
498
  ...referenceAnchors.criticalGaps,
359
499
  ...fixturePack.criticalGaps,
500
+ ...visualInputs.criticalGaps,
360
501
  ])
361
502
  )
362
503
  : [];
@@ -367,13 +508,16 @@ function buildExecutionRationality(paths = {}) {
367
508
  implementationPackReady: applicable ? implementationPack.ready : false,
368
509
  referenceAnchorsReady: applicable ? referenceAnchors.ready : false,
369
510
  fixturePackReady: applicable ? fixturePack.ready : false,
511
+ visualInputReadiness: applicable ? visualInputs.visualInputReadiness : 'not_applicable',
512
+ visualInputsReady: applicable ? visualInputs.ready : true,
370
513
  executionRationalityReady: applicable
371
- ? implementationPack.ready && referenceAnchors.ready && fixturePack.ready && criticalExecutionGaps.length === 0
514
+ ? implementationPack.ready && referenceAnchors.ready && fixturePack.ready && visualInputs.ready && criticalExecutionGaps.length === 0
372
515
  : false,
373
516
  criticalExecutionGaps,
374
517
  implementationPack,
375
518
  referenceAnchors,
376
519
  fixturePack,
520
+ visualInputs,
377
521
  };
378
522
  }
379
523
 
@@ -384,4 +528,5 @@ module.exports = {
384
528
  summarizeImplementationPack,
385
529
  summarizeReferenceAnchors,
386
530
  summarizeFixturePack,
531
+ summarizeVisualInputs,
387
532
  };
@@ -3,6 +3,7 @@
3
3
  const fs = require('fs');
4
4
  const path = require('path');
5
5
  const { spawnSync } = require('child_process');
6
+ const semver = require('semver');
6
7
 
7
8
  const oxeManifest = require('./oxe-manifest.cjs');
8
9
  const runtimeSemantics = require('./oxe-runtime-semantics.cjs');
@@ -18,6 +19,17 @@ const REQUIRED_RUNTIMES = [
18
19
  'antigravity',
19
20
  ];
20
21
 
22
+ const REQUIRED_RUNTIME_REAL_SCENARIOS_1_10 = [
23
+ 'static-html-js',
24
+ 'node-cli-api',
25
+ 'brownfield-docs',
26
+ 'multi_file_mutation',
27
+ 'multi_wave_app',
28
+ 'gate_blocked_execute',
29
+ 'partial_verify_replan',
30
+ 'promotion_blocked_by_risk',
31
+ ];
32
+
21
33
  const WRAPPER_TARGETS = [
22
34
  {
23
35
  key: '.github/prompts',
@@ -42,8 +54,10 @@ function releasePaths(projectRoot) {
42
54
  releaseDir,
43
55
  manifest: path.join(releaseDir, 'release-manifest.json'),
44
56
  smokeReport: path.join(releaseDir, 'runtime-smoke-report.json'),
57
+ runtimeRealReport: path.join(releaseDir, 'runtime-real-report.json'),
45
58
  recoveryFixtureReport: path.join(releaseDir, 'recovery-fixture-report.json'),
46
59
  multiAgentSoakReport: path.join(releaseDir, 'multi-agent-soak-report.json'),
60
+ multiAgentRealReport: path.join(releaseDir, 'multi-agent-real-report.json'),
47
61
  };
48
62
  }
49
63
 
@@ -272,11 +286,21 @@ function loadRuntimeSmokeReport(projectRoot) {
272
286
  && item.wrapper_drift_ok !== false
273
287
  && item.extra_checks_ok !== false
274
288
  && item.agent_checks_ok !== false
289
+ && item.copilot_manifest_ok !== false
290
+ && item.codex_discovery_ok !== false
275
291
  && item.uninstall_ok
276
292
  );
277
293
  });
278
294
  }
279
295
 
296
+ function loadRuntimeRealReport(projectRoot) {
297
+ return readReportSummary(
298
+ releasePaths(projectRoot).runtimeRealReport,
299
+ REQUIRED_RUNTIME_REAL_SCENARIOS_1_10,
300
+ (item) => Boolean(item && item.ok)
301
+ );
302
+ }
303
+
280
304
  function loadRecoveryFixtureReport(projectRoot) {
281
305
  return readReportSummary(releasePaths(projectRoot).recoveryFixtureReport, null, (item) => Boolean(item && item.ok));
282
306
  }
@@ -285,6 +309,21 @@ function loadMultiAgentSoakReport(projectRoot) {
285
309
  return readReportSummary(releasePaths(projectRoot).multiAgentSoakReport, null, (item) => Boolean(item && item.ok));
286
310
  }
287
311
 
312
+ function loadMultiAgentRealReport(projectRoot) {
313
+ return readReportSummary(releasePaths(projectRoot).multiAgentRealReport, null, (item) => {
314
+ if (!item || !item.ok) return false;
315
+ const records = item.report && Array.isArray(item.report.records) ? item.report.records : [];
316
+ for (const record of records) {
317
+ if (record.status !== 'merged') continue;
318
+ if (record.verify_status !== 'pass') return false;
319
+ if (!Array.isArray(record.evidence_refs) || record.evidence_refs.length === 0) return false;
320
+ if (!Array.isArray(record.applied_paths) || record.applied_paths.length === 0) return false;
321
+ if (!record.diff_summary || !Array.isArray(record.diff_summary.paths) || record.diff_summary.paths.length === 0) return false;
322
+ }
323
+ return true;
324
+ });
325
+ }
326
+
288
327
  function readVersionSnapshot(projectRoot) {
289
328
  const packageJsonPath = path.join(projectRoot, 'package.json');
290
329
  const runtimePackagePath = path.join(projectRoot, 'packages', 'runtime', 'package.json');
@@ -349,8 +388,10 @@ function buildReleaseManifest(projectRoot, options = {}) {
349
388
  } : syncWrappers(projectRoot, packageRoot);
350
389
  const semanticsAudit = runtimeSemantics.auditRuntimeTargets(projectRoot);
351
390
  const smoke = loadRuntimeSmokeReport(projectRoot);
391
+ const runtimeReal = loadRuntimeRealReport(projectRoot);
352
392
  const recovery = loadRecoveryFixtureReport(projectRoot);
353
393
  const multiAgent = loadMultiAgentSoakReport(projectRoot);
394
+ const multiAgentReal = loadMultiAgentRealReport(projectRoot);
354
395
  const manifest = {
355
396
  schema_version: 1,
356
397
  generated_at: new Date().toISOString(),
@@ -384,8 +425,10 @@ function buildReleaseManifest(projectRoot, options = {}) {
384
425
  },
385
426
  reports: {
386
427
  runtime_smoke: smoke,
428
+ runtime_real: runtimeReal,
387
429
  recovery_fixtures: recovery,
388
430
  multi_agent_soak: multiAgent,
431
+ multi_agent_real: multiAgentReal,
389
432
  },
390
433
  };
391
434
  if (options.writeManifest) {
@@ -449,12 +492,21 @@ function evaluateReleaseManifest(manifest, options = {}) {
449
492
  if (!manifest.reports.runtime_smoke.present || !manifest.reports.runtime_smoke.ok) {
450
493
  blockers.push('runtime smoke matrix incompleta ou com falhas');
451
494
  }
495
+ if (!manifest.reports.runtime_real.present || !manifest.reports.runtime_real.ok) {
496
+ blockers.push('runtime real report incompleto ou com falhas');
497
+ }
452
498
  if (!manifest.reports.recovery_fixtures.present || !manifest.reports.recovery_fixtures.ok) {
453
499
  blockers.push('recovery fixture report incompleto ou com falhas');
454
500
  }
455
501
  if (!manifest.reports.multi_agent_soak.present || !manifest.reports.multi_agent_soak.ok) {
456
502
  blockers.push('multi-agent soak report incompleto ou com falhas');
457
503
  }
504
+ const releaseVersion = semver.valid(versions.root) ? versions.root : null;
505
+ if (releaseVersion && semver.gte(releaseVersion, '1.9.1')) {
506
+ if (!manifest.reports.multi_agent_real.present || !manifest.reports.multi_agent_real.ok) {
507
+ blockers.push('multi-agent real report incompleto ou com falhas');
508
+ }
509
+ }
458
510
  if (versions.banner.mode === 'unknown') {
459
511
  warnings.push('banner.txt sem placeholder v{version} nem versão fixa detectável');
460
512
  }
@@ -482,12 +534,15 @@ function inspectReleaseReadiness(projectRoot, options = {}) {
482
534
 
483
535
  module.exports = {
484
536
  REQUIRED_RUNTIMES,
537
+ REQUIRED_RUNTIME_REAL_SCENARIOS_1_10,
485
538
  WRAPPER_TARGETS,
486
539
  releasePaths,
487
540
  collectWrapperHashes,
488
541
  loadRuntimeSmokeReport,
542
+ loadRuntimeRealReport,
489
543
  loadRecoveryFixtureReport,
490
544
  loadMultiAgentSoakReport,
545
+ loadMultiAgentRealReport,
491
546
  buildReleaseManifest,
492
547
  inspectCanonicalSource,
493
548
  evaluateReleaseManifest,
package/bin/oxe-cc.js CHANGED
@@ -1537,10 +1537,13 @@ function printOxeHealthDiagnostics(target, c, diagOpts = {}) {
1537
1537
  if (r.executionRationality && r.executionRationality.applicable === false) {
1538
1538
  console.log(` ${c ? dim : ''}Prontidão racional:${c ? reset : ''} não aplicável ainda (PLAN.md ausente)`);
1539
1539
  } else if (typeof r.executionRationalityReady === 'boolean') {
1540
- console.log(
1541
- ` ${c ? dim : ''}Prontidão racional:${c ? reset : ''} implementation=${r.implementationPackReady ? 'ok' : 'pendente'} | anchors=${r.referenceAnchorsReady ? 'ok' : 'pendente'} | fixtures=${r.fixturePackReady ? 'ok' : 'pendente'}`
1542
- );
1543
- }
1540
+ console.log(
1541
+ ` ${c ? dim : ''}Prontidão racional:${c ? reset : ''} implementation=${r.implementationPackReady ? 'ok' : 'pendente'} | anchors=${r.referenceAnchorsReady ? 'ok' : 'pendente'} | fixtures=${r.fixturePackReady ? 'ok' : 'pendente'}`
1542
+ );
1543
+ if (r.visualInputReadiness && r.visualInputReadiness !== 'not_applicable') {
1544
+ console.log(` ${c ? dim : ''}Entradas visuais:${c ? reset : ''} ${r.visualInputReadiness}`);
1545
+ }
1546
+ }
1544
1547
  if (r.contextQuality) {
1545
1548
  console.log(
1546
1549
  ` ${c ? dim : ''}Contexto:${c ? reset : ''} score=${r.contextQuality.primaryScore != null ? r.contextQuality.primaryScore : '—'} | workflow=${r.contextQuality.primaryWorkflow || '—'} | status=${r.contextQuality.primaryStatus || '—'}`
@@ -1744,10 +1747,13 @@ function runStatusFull(target) {
1744
1747
  console.log(` ${c ? yellow : ''} • ${w}${c ? reset : ''}`);
1745
1748
  }
1746
1749
  }
1747
- if (planExists) {
1748
- console.log(` ${c ? dim : ''} • Artefatos racionais:${c ? reset : ''} implementation=${report.implementationPackReady ? 'ok' : 'pendente'} · anchors=${report.referenceAnchorsReady ? 'ok' : 'pendente'} · fixtures=${report.fixturePackReady ? 'ok' : 'pendente'}`);
1749
- }
1750
- }
1750
+ if (planExists) {
1751
+ console.log(` ${c ? dim : ''} • Artefatos racionais:${c ? reset : ''} implementation=${report.implementationPackReady ? 'ok' : 'pendente'} · anchors=${report.referenceAnchorsReady ? 'ok' : 'pendente'} · fixtures=${report.fixturePackReady ? 'ok' : 'pendente'}`);
1752
+ if (report.visualInputReadiness && report.visualInputReadiness !== 'not_applicable') {
1753
+ console.log(` ${c ? dim : ''} • Entradas visuais:${c ? reset : ''} ${report.visualInputReadiness}`);
1754
+ }
1755
+ }
1756
+ }
1751
1757
 
1752
1758
  // Active run summary
1753
1759
  if (report.activeRun) {
@@ -1804,12 +1810,14 @@ function runStatusFull(target) {
1804
1810
  if (report.recoveryState) {
1805
1811
  console.log(` ${c ? dim : ''}Recovery:${c ? reset : ''} ${report.recoveryState.status || 'unknown'} · recoveries ${report.recoveryState.recoverCount ?? 0} · issues ${Array.isArray(report.recoveryState.issues) ? report.recoveryState.issues.length : 0}`);
1806
1812
  }
1807
- if (report.multiAgent) {
1808
- const agents = Array.isArray(report.multiAgent.agents) ? report.multiAgent.agents.length : 0;
1809
- const handoffs = Array.isArray(report.multiAgent.handoffs) ? report.multiAgent.handoffs.length : 0;
1810
- const ownership = Array.isArray(report.multiAgent.ownership) ? report.multiAgent.ownership.length : 0;
1811
- console.log(` ${c ? dim : ''}Multi-agent:${c ? reset : ''} ${report.multiAgent.enabled ? (report.multiAgent.mode || 'active') : 'disabled'} · agentes ${agents} · ownership ${ownership} · handoffs ${handoffs}`);
1812
- }
1813
+ if (report.multiAgent) {
1814
+ const agents = Array.isArray(report.multiAgent.agents) ? report.multiAgent.agents.length : 0;
1815
+ const handoffs = Array.isArray(report.multiAgent.handoffs) ? report.multiAgent.handoffs.length : 0;
1816
+ const ownership = Array.isArray(report.multiAgent.ownership) ? report.multiAgent.ownership.length : 0;
1817
+ const blockers = Array.isArray(report.multiAgent.mergeBlockers) ? report.multiAgent.mergeBlockers.length : 0;
1818
+ console.log(` ${c ? dim : ''}Multi-agent:${c ? reset : ''} ${report.multiAgent.enabled ? (report.multiAgent.mode || 'active') : 'disabled'} · agentes ${agents} · ownership ${ownership} · handoffs ${handoffs} · merge ${report.multiAgent.mergeReadiness || 'n/a'} · blockers ${blockers}`);
1819
+ if (report.multiAgent.nextAction) console.log(` ${c ? dim : ''}Multi-agent next:${c ? reset : ''} ${report.multiAgent.nextAction}`);
1820
+ }
1813
1821
  if (report.providerCatalog) {
1814
1822
  const summary = report.providerCatalog.summary || {};
1815
1823
  const pluginsCount = summary.pluginsCount ?? summary.total_plugins ?? (Array.isArray(summary.plugins) ? summary.plugins.length : 0);
@@ -1891,8 +1899,10 @@ function runStatus(target, opts = {}) {
1891
1899
  planConfidenceExecutable: report.planConfidenceExecutable,
1892
1900
  implementationPackReady: report.implementationPackReady,
1893
1901
  referenceAnchorsReady: report.referenceAnchorsReady,
1894
- fixturePackReady: report.fixturePackReady,
1895
- executionRationalityReady: report.executionRationalityReady,
1902
+ fixturePackReady: report.fixturePackReady,
1903
+ visualInputReadiness: report.visualInputReadiness,
1904
+ visualInputsReady: report.visualInputsReady,
1905
+ executionRationalityReady: report.executionRationalityReady,
1896
1906
  criticalExecutionGaps: report.criticalExecutionGaps,
1897
1907
  executionRationality: report.executionRationality,
1898
1908
  planReviewStatus: report.planReviewStatus,
@@ -4455,9 +4465,11 @@ async function runRuntime(opts) {
4455
4465
  : `${report.recoveryState.status} · issues=${recIssues} — rode ${c ? cyan : ''}runtime status --verbose${c ? reset : ''} para detalhes`;
4456
4466
  console.log(` ${c ? green : ''}Recovery:${c ? reset : ''} ${recLabel} · recoveries=${report.recoveryState.recoverCount ?? 0}`);
4457
4467
  }
4458
- if (multiAgent) {
4459
- console.log(` ${c ? green : ''}Multi-agent:${c ? reset : ''} ${multiAgent.enabled ? (multiAgent.mode || 'active') : 'disabled'} · agentes=${Array.isArray(multiAgent.agents) ? multiAgent.agents.length : 0} · ownership=${Array.isArray(multiAgent.ownership) ? multiAgent.ownership.length : 0}`);
4460
- }
4468
+ if (multiAgent) {
4469
+ const blockers = Array.isArray(multiAgent.mergeBlockers) ? multiAgent.mergeBlockers.length : 0;
4470
+ console.log(` ${c ? green : ''}Multi-agent:${c ? reset : ''} ${multiAgent.enabled ? (multiAgent.mode || 'active') : 'disabled'} · agentes=${Array.isArray(multiAgent.agents) ? multiAgent.agents.length : 0} · ownership=${Array.isArray(multiAgent.ownership) ? multiAgent.ownership.length : 0} · merge=${multiAgent.mergeReadiness || 'n/a'} · blockers=${blockers}`);
4471
+ if (multiAgent.nextAction) console.log(` ${c ? cyan : ''}Próxima ação:${c ? reset : ''} ${multiAgent.nextAction}`);
4472
+ }
4461
4473
  if (report.providerCatalog && report.providerCatalog.summary) {
4462
4474
  const summary = report.providerCatalog.summary;
4463
4475
  const pluginsCount = summary.pluginsCount ?? summary.total_plugins ?? (Array.isArray(summary.plugins) ? summary.plugins.length : 0);
@@ -4764,23 +4776,32 @@ async function runRuntime(opts) {
4764
4776
  }
4765
4777
  },
4766
4778
  });
4767
- if (opts.jsonOutput) {
4768
- console.log(JSON.stringify(result, null, 2));
4769
- if (result.result && result.result.failed && result.result.failed.length > 0) process.exitCode = 1;
4770
- return;
4771
- }
4772
- const r = result.result || {};
4773
- const completed = Array.isArray(r.completed) ? r.completed : [];
4774
- const failed = Array.isArray(r.failed) ? r.failed : [];
4775
- const blocked = Array.isArray(r.blocked) ? r.blocked : [];
4776
- console.log(` ${c ? green : ''}✓${c ? reset : ''} Runtime execute concluído (modo: ${result.mode})`);
4777
- console.log(` ${c ? green : ''}Completados:${c ? reset : ''} ${completed.length}`);
4779
+ if (opts.jsonOutput) {
4780
+ console.log(JSON.stringify(result, null, 2));
4781
+ if (result.result && ((result.result.failed && result.result.failed.length > 0) || result.result.status === 'blocked')) process.exitCode = 1;
4782
+ return;
4783
+ }
4784
+ const r = result.result || {};
4785
+ const completed = Array.isArray(r.completed) ? r.completed : [];
4786
+ const failed = Array.isArray(r.failed) ? r.failed : [];
4787
+ const blocked = Array.isArray(r.blocked) ? r.blocked : [];
4788
+ const okColor = r.status === 'blocked' ? yellow : green;
4789
+ console.log(` ${c ? okColor : ''}${r.status === 'blocked' ? '!' : '✓'}${c ? reset : ''} Runtime execute concluído (modo: ${result.mode})`);
4790
+ if (result.preflight) {
4791
+ console.log(` ${c ? green : ''}Preflight:${c ? reset : ''} ${result.preflight.ok ? 'ready' : 'blocked'}`);
4792
+ if (Array.isArray(result.preflight.blockers) && result.preflight.blockers.length) {
4793
+ for (const blocker of result.preflight.blockers) {
4794
+ console.log(` ${yellow}BLOCKER${reset} ${blocker}`);
4795
+ }
4796
+ }
4797
+ }
4798
+ console.log(` ${c ? green : ''}Completados:${c ? reset : ''} ${completed.length}`);
4778
4799
  if (failed.length > 0)
4779
4800
  console.log(` ${c ? red : ''}Falhos:${c ? reset : ''} ${failed.length} — ${failed.join(', ')}`);
4780
4801
  if (blocked.length > 0)
4781
4802
  console.log(` ${c ? '\x1b[33m' : ''}Bloqueados:${c ? reset : ''} ${blocked.length} — ${blocked.join(', ')}`);
4782
- if (failed.length > 0) process.exitCode = 1;
4783
- return;
4803
+ if (failed.length > 0 || r.status === 'blocked') process.exitCode = 1;
4804
+ return;
4784
4805
  } catch (err) {
4785
4806
  console.error(`${red}${err && err.message ? err.message : 'Falha ao executar runtime.'}${reset}`);
4786
4807
  process.exit(1);
@@ -4889,11 +4910,13 @@ async function runRuntime(opts) {
4889
4910
  return;
4890
4911
  }
4891
4912
  console.log(` ${c ? green : ''}Run:${c ? reset : ''} ${multiAgent.runId || '—'}`);
4892
- console.log(` ${c ? green : ''}Modo:${c ? reset : ''} ${multiAgent.enabled ? (multiAgent.mode || 'active') : 'disabled'}`);
4893
- console.log(` ${c ? green : ''}Isolamento:${c ? reset : ''} ${multiAgent.workspaceIsolationEnforced ? 'enforced' : 'shared/disabled'}`);
4894
- console.log(` ${c ? green : ''}Agentes:${c ? reset : ''} ${Array.isArray(multiAgent.agents) ? multiAgent.agents.length : 0} · ownership=${Array.isArray(multiAgent.ownership) ? multiAgent.ownership.length : 0} · handoffs=${Array.isArray(multiAgent.handoffs) ? multiAgent.handoffs.length : 0}`);
4895
- return;
4896
- }
4913
+ console.log(` ${c ? green : ''}Modo:${c ? reset : ''} ${multiAgent.enabled ? (multiAgent.mode || 'active') : 'disabled'}`);
4914
+ console.log(` ${c ? green : ''}Isolamento:${c ? reset : ''} ${multiAgent.workspaceIsolationEnforced ? 'enforced' : 'shared/disabled'}`);
4915
+ console.log(` ${c ? green : ''}Agentes:${c ? reset : ''} ${Array.isArray(multiAgent.agents) ? multiAgent.agents.length : 0} · ownership=${Array.isArray(multiAgent.ownership) ? multiAgent.ownership.length : 0} · handoffs=${Array.isArray(multiAgent.handoffs) ? multiAgent.handoffs.length : 0}`);
4916
+ console.log(` ${c ? green : ''}Merge:${c ? reset : ''} ${multiAgent.mergeReadiness || 'n/a'} · blockers=${Array.isArray(multiAgent.mergeBlockers) ? multiAgent.mergeBlockers.length : 0} · arbitration=${multiAgent.arbitrationRequired ? 'required' : 'no'}`);
4917
+ if (multiAgent.nextAction) console.log(` ${c ? cyan : ''}Próxima ação:${c ? reset : ''} ${multiAgent.nextAction}`);
4918
+ return;
4919
+ }
4897
4920
 
4898
4921
  try {
4899
4922
  const next = oxeOperational.applyRuntimeAction(opts.dir, activeSession, {
@@ -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: ebb4473c14e5b080
18
+ oxe_semantics_hash: 13daa3c62e0efaa4
19
19
  ---
20
20
 
21
21
  <!-- oxe-reasoning-contract:start -->
@@ -29,7 +29,7 @@ oxe_semantics_hash: ebb4473c14e5b080
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:** `ebb4473c14e5b080`
32
+ - **Checksum semântico:** `13daa3c62e0efaa4`
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`
@@ -22,7 +22,7 @@ oxe_tool_profile: write_bounded
22
22
  oxe_confidence_policy: explicit
23
23
  oxe_context_tier: standard
24
24
  oxe_contract_version: 2.0.0
25
- oxe_semantics_hash: 7b3446b77aef9353
25
+ oxe_semantics_hash: 0e6003de070d497f
26
26
  ---
27
27
 
28
28
  <!-- oxe-reasoning-contract:start -->
@@ -36,7 +36,7 @@ oxe_semantics_hash: 7b3446b77aef9353
36
36
  - **Política de confiança:** explícita
37
37
  - **Tier de contexto padrão:** padrão
38
38
  - **Versão do contrato:** 2.0.0
39
- - **Checksum semântico:** `7b3446b77aef9353`
39
+ - **Checksum semântico:** `0e6003de070d497f`
40
40
  - **Entrada de contexto prioritária:** `.oxe/context/packs/execute.md` e `.oxe/context/packs/execute.json`
41
41
  - **Regra pack-first:** ler o context pack primeiro; se estiver stale, incompleto ou ausente, cair para leitura direta com fallback explícito.
42
42
  - **Inspeção estruturada:** `oxe-cc context inspect --workflow execute --json`
@@ -21,7 +21,7 @@ oxe_tool_profile: mixed
21
21
  oxe_confidence_policy: rubric
22
22
  oxe_context_tier: standard
23
23
  oxe_contract_version: 2.0.0
24
- oxe_semantics_hash: 5c589398cb807029
24
+ oxe_semantics_hash: 210518babb4788d0
25
25
  ---
26
26
 
27
27
  <!-- oxe-reasoning-contract:start -->
@@ -35,7 +35,7 @@ oxe_semantics_hash: 5c589398cb807029
35
35
  - **Política de confiança:** rubrica
36
36
  - **Tier de contexto padrão:** padrão
37
37
  - **Versão do contrato:** 2.0.0
38
- - **Checksum semântico:** `5c589398cb807029`
38
+ - **Checksum semântico:** `210518babb4788d0`
39
39
  - **Entrada de contexto prioritária:** `.oxe/context/packs/plan.md` e `.oxe/context/packs/plan.json`
40
40
  - **Regra pack-first:** ler o context pack primeiro; se estiver stale, incompleto ou ausente, cair para leitura direta com fallback explícito.
41
41
  - **Inspeção estruturada:** `oxe-cc context inspect --workflow plan --json`
@@ -17,7 +17,7 @@ oxe_tool_profile: mixed
17
17
  oxe_confidence_policy: rubric
18
18
  oxe_context_tier: standard
19
19
  oxe_contract_version: 2.0.0
20
- oxe_semantics_hash: 2193373eb2691e0d
20
+ oxe_semantics_hash: ea0c06ca7b5c87bb
21
21
  ---
22
22
 
23
23
  <!-- oxe-reasoning-contract:start -->
@@ -31,7 +31,7 @@ oxe_semantics_hash: 2193373eb2691e0d
31
31
  - **Política de confiança:** rubrica
32
32
  - **Tier de contexto padrão:** padrão
33
33
  - **Versão do contrato:** 2.0.0
34
- - **Checksum semântico:** `2193373eb2691e0d`
34
+ - **Checksum semântico:** `ea0c06ca7b5c87bb`
35
35
  - **Entrada de contexto prioritária:** `.oxe/context/packs/quick.md` e `.oxe/context/packs/quick.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 quick --json`
@@ -20,7 +20,7 @@ oxe_tool_profile: read_heavy
20
20
  oxe_confidence_policy: explicit
21
21
  oxe_context_tier: standard
22
22
  oxe_contract_version: 2.0.0
23
- oxe_semantics_hash: eea8766eab635c97
23
+ oxe_semantics_hash: 4ec66ac1e704fdbf
24
24
  ---
25
25
 
26
26
  <!-- oxe-reasoning-contract:start -->
@@ -34,7 +34,7 @@ oxe_semantics_hash: eea8766eab635c97
34
34
  - **Política de confiança:** explícita
35
35
  - **Tier de contexto padrão:** padrão
36
36
  - **Versão do contrato:** 2.0.0
37
- - **Checksum semântico:** `eea8766eab635c97`
37
+ - **Checksum semântico:** `4ec66ac1e704fdbf`
38
38
  - **Entrada de contexto prioritária:** `.oxe/context/packs/spec.md` e `.oxe/context/packs/spec.json`
39
39
  - **Regra pack-first:** ler o context pack primeiro; se estiver stale, incompleto ou ausente, cair para leitura direta com fallback explícito.
40
40
  - **Inspeção estruturada:** `oxe-cc context inspect --workflow spec --json`
@@ -53,4 +53,4 @@ oxe_semantics_hash: eea8766eab635c97
53
53
 
54
54
  <!-- oxe-workflow-resolution:end -->
55
55
 
56
- Usa `$ARGUMENTS` e o contexto da conversa como entrada do utilizador (texto ou `@ficheiro`).
56
+ Usa `$ARGUMENTS`, contexto da conversa e anexos como entrada do utilizador. Se houver imagem, screenshot ou mockup e o runtime suportar visão, materializar a interpretação em `VISUAL-INPUTS`; se não suportar, declarar a limitação e não inventar detalhes visuais.
@@ -8,6 +8,7 @@ Este é o contrato mínimo para publicar uma versão estável do OXE sem drift e
8
8
  npm test
9
9
  npm run scan:assets
10
10
  npm run build:vscode-ext
11
+ npm run release:pack-check
11
12
  npx oxe-cc doctor --release --write-manifest
12
13
  ```
13
14
 
@@ -21,6 +22,7 @@ O `doctor --release` deve bloquear a publicação quando encontrar:
21
22
  - wrappers dirty após `sync-runtime-metadata` e `sync:cursor`
22
23
  - drift semântico entre workflows canónicos e superfícies geradas
23
24
  - ausência ou falha dos relatórios obrigatórios da release
25
+ - tarball npm contendo `.tgz`, `.vsix`, `.oxe/` ou sem arquivos obrigatórios do pacote
24
26
 
25
27
  ## Relatórios obrigatórios
26
28
 
@@ -28,8 +30,12 @@ Todos os artefatos abaixo devem existir em `.oxe/release/`:
28
30
 
29
31
  - `release-manifest.json`
30
32
  - `runtime-smoke-report.json`
33
+ - `runtime-real-report.json`
31
34
  - `recovery-fixture-report.json`
32
35
  - `multi-agent-soak-report.json`
36
+ - `multi-agent-real-report.json` para versões `>=1.9.1`
37
+
38
+ Na linha `>=1.10.0`, `runtime-real-report.json` deve cobrir cenários representativos além do happy path simples: multi-wave, multi-file, verify parcial, gate pendente e promoção bloqueada. O `multi-agent-real-report.json` deve provar merge com evidência, diff summary, arquivos aplicados e verify status por task; o release doctor valida esse conteúdo, não apenas a presença do arquivo.
33
39
 
34
40
  ## Defaults estáveis desta publicação
35
41
 
@@ -44,7 +50,8 @@ O pipeline de CI e o pipeline de release devem rodar o mesmo gate:
44
50
 
45
51
  1. `npm test`
46
52
  2. `npm run scan:assets`
47
- 3. `npm run release:doctor`
53
+ 3. `npm run release:pack-check`
54
+ 4. `npm run release:doctor`
48
55
 
49
56
  Se qualquer etapa falhar, a release não está pronta.
50
57