0xray 4.0.41 → 4.1.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 (148) hide show
  1. package/.grok-plugin/plugin.json +1 -1
  2. package/.opencode/skills/orchestrator/SKILL.md +12 -0
  3. package/.plugin/plugin.json +1 -1
  4. package/.xray/features.json +5 -5
  5. package/.xray/features.schema.json +1 -1
  6. package/AGENTS-consumer.md +10 -6
  7. package/AGENTS.md +19 -8
  8. package/LICENSE +1 -1
  9. package/README.md +65 -19
  10. package/SKILLS.md +5 -1
  11. package/dist/AGENTS.md +19 -8
  12. package/dist/CHANGELOG.md +85 -0
  13. package/dist/LICENSE +1 -1
  14. package/dist/README.md +65 -19
  15. package/dist/SKILLS.md +5 -1
  16. package/dist/cli/commands/openclaw-install.js +1 -1
  17. package/dist/cli/commands/plugin-commands.d.ts +4 -0
  18. package/dist/cli/commands/plugin-commands.js +84 -41
  19. package/dist/cli/index.js +12 -0
  20. package/dist/core/config-loader.js +4 -4
  21. package/dist/core/features-config.d.ts +1 -1
  22. package/dist/core/features-config.js +3 -3
  23. package/dist/enforcement/index.d.ts +4 -0
  24. package/dist/enforcement/index.js +4 -0
  25. package/dist/enforcement/validators/code-quality-validators.js +6 -4
  26. package/dist/governance/llm-governance-provider.d.ts +7 -1
  27. package/dist/governance/llm-governance-provider.js +72 -14
  28. package/dist/governance/local-confer.d.ts +4 -1
  29. package/dist/governance/local-confer.js +22 -1
  30. package/dist/integrations/cursor/hooks/hooks.json +6 -3
  31. package/dist/integrations/cursor/hooks/pre-tool-use.js +100 -37
  32. package/dist/integrations/cursor/hooks/xray-cloud-hook.sh +9 -1
  33. package/dist/integrations/grok/grok-cli.js +10 -37
  34. package/dist/integrations/grok/hooks/grok-hook-utils.js +8 -1
  35. package/dist/integrations/grok/hooks/pre-tool-use.js +2 -58
  36. package/dist/integrations/hermes-agent/bridge.mjs +14 -1
  37. package/dist/integrations/hooks/confer-hook-runtime.mjs +23 -1
  38. package/dist/integrations/hooks/delegation-gate-runtime.mjs +3 -2
  39. package/dist/integrations/hooks/goggles-mcp.mjs +35 -17
  40. package/dist/integrations/hooks/goggles-pipeline.mjs +46 -1
  41. package/dist/integrations/hooks/goggles-planes.json +11 -7
  42. package/dist/integrations/hooks/pre-tool-speak.mjs +76 -0
  43. package/dist/integrations/openclaw/hooks/pre-tool-gate-runtime.mjs +21 -4
  44. package/dist/integrations/openclaw/plugin/xray-pre-tool/index.js +17 -2
  45. package/dist/integrations/openclaw/plugin/xray-pre-tool/package.json +1 -1
  46. package/dist/mcps/architect-tools.server.d.ts +6 -0
  47. package/dist/mcps/architect-tools.server.js +19 -2
  48. package/dist/mcps/config/server-config-registry.js +8 -6
  49. package/dist/mcps/governance.server.d.ts +1 -0
  50. package/dist/mcps/governance.server.js +46 -0
  51. package/dist/mcps/knowledge-skills/code-review.server.js +7 -0
  52. package/dist/mcps/knowledge-skills/security-audit.server.js +5 -3
  53. package/dist/mcps/mcp-client.js +1 -1
  54. package/dist/mcps/orchestrator/handlers/complexity-handler.js +2 -2
  55. package/dist/mcps/researcher.server.js +12 -3
  56. package/dist/monitoring/{nudge-watchdog.d.ts → nudge-monitor.d.ts} +14 -5
  57. package/dist/monitoring/{nudge-watchdog.js → nudge-monitor.js} +42 -17
  58. package/dist/nucleus/autonomy-kernel.d.ts +2 -0
  59. package/dist/nucleus/autonomy-kernel.js +17 -13
  60. package/dist/nucleus/confer-host.d.ts +35 -0
  61. package/dist/nucleus/confer-host.js +55 -0
  62. package/dist/nucleus/confer.d.ts +19 -3
  63. package/dist/nucleus/confer.js +111 -55
  64. package/dist/nucleus/lead-dev-plan-persistence.js +4 -2
  65. package/dist/nucleus/suit-temperament.d.ts +1 -1
  66. package/dist/nucleus/suit-temperament.js +2 -2
  67. package/dist/nucleus/synthesis-consult-receipt.d.ts +7 -1
  68. package/dist/nucleus/synthesis-consult-receipt.js +86 -35
  69. package/dist/plugin/xray-codex-injection.js +18 -0
  70. package/dist/processors/implementations/nudge-processor.d.ts +1 -1
  71. package/dist/processors/implementations/nudge-processor.js +4 -4
  72. package/dist/reporting/framework-reporting-system.js +2 -5
  73. package/dist/reporting/log-parser.d.ts +2 -0
  74. package/dist/reporting/log-parser.js +7 -6
  75. package/dist/skills/orchestrator/SKILL.md +12 -0
  76. package/docs-site/docs/plates/activity-log.md +1 -1
  77. package/docs-site/docs/plates/bifrost.md +48 -0
  78. package/docs-site/docs/plates/boot.md +2 -2
  79. package/docs-site/docs/plates/centrifuge.md +1 -1
  80. package/docs-site/docs/plates/cursor-compact.md +1 -1
  81. package/docs-site/docs/plates/glossary.md +7 -3
  82. package/docs-site/docs/plates/goggles.md +13 -2
  83. package/docs-site/docs/plates/governance.md +1 -1
  84. package/docs-site/docs/plates/grok-compact.md +1 -1
  85. package/docs-site/docs/plates/grokbot.md +3 -1
  86. package/docs-site/docs/plates/host-pack.md +1 -1
  87. package/docs-site/docs/plates/house.md +1 -1
  88. package/docs-site/docs/plates/index.md +4 -2
  89. package/docs-site/docs/plates/inference-files.md +1 -1
  90. package/docs-site/docs/plates/kept-line.md +1 -1
  91. package/docs-site/docs/plates/kits.md +1 -1
  92. package/docs-site/docs/plates/lens-gate.md +3 -1
  93. package/docs-site/docs/plates/lens-page.md +1 -1
  94. package/docs-site/docs/plates/memory-recall.md +1 -1
  95. package/docs-site/docs/plates/notes-page.md +2 -2
  96. package/docs-site/docs/plates/orchestration.md +1 -1
  97. package/docs-site/docs/plates/package-face.md +1 -1
  98. package/docs-site/docs/plates/payload-heat.md +1 -1
  99. package/docs-site/docs/plates/pickup-stamp.md +1 -1
  100. package/docs-site/docs/plates/pre-tool.md +1 -1
  101. package/docs-site/docs/plates/processor.md +1 -1
  102. package/docs-site/docs/plates/record-map.md +1 -1
  103. package/docs-site/docs/plates/reflection-page.md +1 -1
  104. package/docs-site/docs/plates/reporting.md +1 -1
  105. package/docs-site/docs/plates/review.md +1 -1
  106. package/docs-site/docs/plates/routing.md +1 -1
  107. package/docs-site/docs/plates/session-capture.md +1 -1
  108. package/docs-site/docs/plates/site-manual.md +1 -1
  109. package/docs-site/docs/plates/stamp-plate.md +1 -1
  110. package/docs-site/docs/plates/station-card.md +1 -1
  111. package/docs-site/docs/plates/station-heat.md +1 -1
  112. package/docs-site/docs/plates/suit-organs.md +1 -1
  113. package/docs-site/docs/plates/suit-settings.md +1 -1
  114. package/docs-site/docs/plates/suit-wear.md +1 -1
  115. package/docs-site/docs/plates/suit.md +3 -3
  116. package/docs-site/docs/plates/trail-state.md +1 -1
  117. package/docs-site/docs/plates/work-fresh.md +1 -1
  118. package/docs-site/docs/plates/write-home.md +1 -1
  119. package/llms.txt +16 -6
  120. package/package.json +4 -4
  121. package/scripts/foundry/README.md +2 -2
  122. package/scripts/foundry/release-gate.mjs +111 -15
  123. package/scripts/foundry/release.mjs +8 -0
  124. package/scripts/mjs/verify-confer-core.mjs +153 -29
  125. package/scripts/mjs/verify-pipeline-facets.mjs +1 -1
  126. package/scripts/mjs/verify-user-aside-core.mjs +3 -4
  127. package/scripts/node/bridge-mcp-wiring.cjs +236 -5
  128. package/scripts/node/confer-switch.cjs +66 -0
  129. package/scripts/node/install-bridges.cjs +44 -53
  130. package/scripts/node/pack-tmp-suit-proof.mjs +14 -6
  131. package/src/integrations/openclaw/plugin/xray-pre-tool/index.js +17 -2
  132. package/src/integrations/openclaw/plugin/xray-pre-tool/package.json +1 -1
  133. package/src/mcps/architect-tools.server.ts +26 -2
  134. package/src/mcps/config/__tests__/server-config-registry.test.ts +15 -6
  135. package/src/mcps/config/server-config-registry.ts +9 -6
  136. package/src/mcps/governance.server.ts +49 -0
  137. package/src/mcps/knowledge-skills/code-review.server.ts +8 -0
  138. package/src/mcps/knowledge-skills/security-audit.server.ts +11 -12
  139. package/src/mcps/mcp-client.ts +1 -1
  140. package/src/mcps/orchestrator/handlers/complexity-handler.ts +2 -1
  141. package/src/mcps/researcher.server.ts +19 -10
  142. package/src/skills/orchestrator/SKILL.md +12 -0
  143. package/vendor/@0xray/repertoire/README.md +1 -1
  144. package/vendor/@0xray/repertoire/scripts/run-live-synthesis-checkpoint.mjs +5 -51
  145. package/xray/agents_template.md +2 -2
  146. package/xray/features.json +5 -5
  147. package/xray/features.schema.json +1 -1
  148. package/docs-site/docs/plates/live-mesh.md +0 -41
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Nudge Watchdog - Detects and breaks stuck AI patterns
2
+ * Nudge Monitor - Detects and breaks stuck AI patterns
3
3
  *
4
4
  * Monitors agent actions and detects common failure patterns:
5
5
  * - think-loop: AI keeps outputting thinking tags but no progress
@@ -8,7 +8,7 @@
8
8
  * - tool-loop: Same tool called with similar args repeatedly
9
9
  * - repair-failure: Processor indicates fix but error persists
10
10
  *
11
- * @module monitoring/nudge-watchdog
11
+ * @module monitoring/nudge-monitor
12
12
  */
13
13
  import { EventEmitter } from "events";
14
14
  export interface NudgeConfig {
@@ -33,7 +33,16 @@ export interface NudgeAction {
33
33
  suggestion: string;
34
34
  priority: number;
35
35
  }
36
- declare class NudgeWatchdog extends EventEmitter {
36
+ /** Old config key from before the rename to nudge_monitor; still read as a deprecated alias. */
37
+ export declare const LEGACY_NUDGE_CONFIG_KEY = "nudge_watchdog";
38
+ /**
39
+ * features.nudge_monitor, or the deprecated features.nudge_watchdog when nudge_monitor is unset (the new key wins
40
+ * when both are set). Using the old key logs a one-time deprecation warning.
41
+ */
42
+ export declare function resolveNudgeConfig(features: Record<string, unknown> | undefined | null, warn?: (message: string) => void): Record<string, unknown> | undefined;
43
+ /** Test hook: let the one-time deprecation warning fire again. */
44
+ export declare function resetLegacyNudgeWarning(): void;
45
+ declare class NudgeMonitor extends EventEmitter {
37
46
  private config;
38
47
  private patterns;
39
48
  private lastNudgeTime;
@@ -75,13 +84,13 @@ declare class NudgeWatchdog extends EventEmitter {
75
84
  };
76
85
  private log;
77
86
  }
78
- export declare const nudgeWatchdog: NudgeWatchdog;
87
+ export declare const nudgeMonitor: NudgeMonitor;
79
88
  export declare function recordThinkTag(): void;
80
89
  export declare function recordCodeChange(): void;
81
90
  export declare function recordToolCall(tool: string, args: string): void;
82
91
  export declare function recordFixAttempt(filePath: string, error: string): void;
83
92
  export declare function recordExplanation(): void;
84
93
  export declare function getNudgeSuggestion(type: NudgeType, context?: Record<string, unknown>): string;
85
- export declare function getNudgeWatchdog(): NudgeWatchdog;
94
+ export declare function getNudgeMonitor(): NudgeMonitor;
86
95
  export declare function recordProcessorFix(filePath: string, fixed: boolean, errorPersisted: boolean): void;
87
96
  export {};
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Nudge Watchdog - Detects and breaks stuck AI patterns
2
+ * Nudge Monitor - Detects and breaks stuck AI patterns
3
3
  *
4
4
  * Monitors agent actions and detects common failure patterns:
5
5
  * - think-loop: AI keeps outputting thinking tags but no progress
@@ -8,7 +8,7 @@
8
8
  * - tool-loop: Same tool called with similar args repeatedly
9
9
  * - repair-failure: Processor indicates fix but error persists
10
10
  *
11
- * @module monitoring/nudge-watchdog
11
+ * @module monitoring/nudge-monitor
12
12
  */
13
13
  import { EventEmitter } from "events";
14
14
  import { frameworkLogger } from "../core/framework-logger.js";
@@ -53,7 +53,32 @@ const NUDGE_MESSAGES = {
53
53
  priority: 5,
54
54
  },
55
55
  };
56
- class NudgeWatchdog extends EventEmitter {
56
+ /** Old config key from before the rename to nudge_monitor; still read as a deprecated alias. */
57
+ export const LEGACY_NUDGE_CONFIG_KEY = "nudge_watchdog";
58
+ let legacyKeyWarned = false;
59
+ /**
60
+ * features.nudge_monitor, or the deprecated features.nudge_watchdog when nudge_monitor is unset (the new key wins
61
+ * when both are set). Using the old key logs a one-time deprecation warning.
62
+ */
63
+ export function resolveNudgeConfig(features, warn = (m) => frameworkLogger.log("nudge-monitor", "deprecated-config-key", "warning", { message: m })) {
64
+ const current = features?.nudge_monitor;
65
+ if (current !== undefined && current !== null)
66
+ return current;
67
+ const legacy = features?.[LEGACY_NUDGE_CONFIG_KEY];
68
+ if (legacy !== undefined && legacy !== null) {
69
+ if (!legacyKeyWarned) {
70
+ legacyKeyWarned = true;
71
+ warn(`features.${LEGACY_NUDGE_CONFIG_KEY} is deprecated; rename it to features.nudge_monitor`);
72
+ }
73
+ return legacy;
74
+ }
75
+ return undefined;
76
+ }
77
+ /** Test hook: let the one-time deprecation warning fire again. */
78
+ export function resetLegacyNudgeWarning() {
79
+ legacyKeyWarned = false;
80
+ }
81
+ class NudgeMonitor extends EventEmitter {
57
82
  config;
58
83
  patterns = new Map();
59
84
  lastNudgeTime = 0;
@@ -73,7 +98,7 @@ class NudgeWatchdog extends EventEmitter {
73
98
  loadConfigFromFeatures() {
74
99
  try {
75
100
  const features = featuresConfigLoader.loadConfig();
76
- const nudgeConfig = features?.nudge_watchdog;
101
+ const nudgeConfig = resolveNudgeConfig(features);
77
102
  if (nudgeConfig) {
78
103
  this.config = { ...this.config, ...nudgeConfig };
79
104
  }
@@ -86,10 +111,10 @@ class NudgeWatchdog extends EventEmitter {
86
111
  if (!this.config.enabled) {
87
112
  return;
88
113
  }
89
- this.log("nudge-watchdog", "started", "info", { config: this.config });
114
+ this.log("nudge-monitor", "started", "info", { config: this.config });
90
115
  }
91
116
  stop() {
92
- this.log("nudge-watchdog", "stopped", "info");
117
+ this.log("nudge-monitor", "stopped", "info");
93
118
  }
94
119
  recordThinkTag() {
95
120
  const now = Date.now();
@@ -256,7 +281,7 @@ class NudgeWatchdog extends EventEmitter {
256
281
  if (!action)
257
282
  return null;
258
283
  this.emit("nudge", action);
259
- this.log("nudge-watchdog", "nudge-triggered", "warning", {
284
+ this.log("nudge-monitor", "nudge-triggered", "warning", {
260
285
  type: action.type,
261
286
  message: action.message,
262
287
  suggestion: action.suggestion,
@@ -328,28 +353,28 @@ class NudgeWatchdog extends EventEmitter {
328
353
  }
329
354
  }
330
355
  }
331
- export const nudgeWatchdog = new NudgeWatchdog();
356
+ export const nudgeMonitor = new NudgeMonitor();
332
357
  export function recordThinkTag() {
333
- nudgeWatchdog.recordThinkTag();
358
+ nudgeMonitor.recordThinkTag();
334
359
  }
335
360
  export function recordCodeChange() {
336
- nudgeWatchdog.recordCodeChange();
361
+ nudgeMonitor.recordCodeChange();
337
362
  }
338
363
  export function recordToolCall(tool, args) {
339
- nudgeWatchdog.recordToolCall(tool, args);
364
+ nudgeMonitor.recordToolCall(tool, args);
340
365
  }
341
366
  export function recordFixAttempt(filePath, error) {
342
- nudgeWatchdog.recordFixAttempt(filePath, error);
367
+ nudgeMonitor.recordFixAttempt(filePath, error);
343
368
  }
344
369
  export function recordExplanation() {
345
- nudgeWatchdog.recordExplanation();
370
+ nudgeMonitor.recordExplanation();
346
371
  }
347
372
  export function getNudgeSuggestion(type, context) {
348
- return nudgeWatchdog.getNudgeSuggestion(type, context);
373
+ return nudgeMonitor.getNudgeSuggestion(type, context);
349
374
  }
350
- export function getNudgeWatchdog() {
351
- return nudgeWatchdog;
375
+ export function getNudgeMonitor() {
376
+ return nudgeMonitor;
352
377
  }
353
378
  export function recordProcessorFix(filePath, fixed, errorPersisted) {
354
- nudgeWatchdog.recordProcessorFix(filePath, fixed, errorPersisted);
379
+ nudgeMonitor.recordProcessorFix(filePath, fixed, errorPersisted);
355
380
  }
@@ -38,6 +38,8 @@ export interface LeadDevPlan {
38
38
  fullSuiteGate: boolean;
39
39
  hint: string;
40
40
  };
41
+ /** New id each synthesis plan. Receipts from an older id cannot complete s.1–s.3. */
42
+ consultCycleId?: string;
41
43
  }
42
44
  export declare function isLeadDevModeActive(): boolean;
43
45
  export declare function routeSubagent(taskType: string): SubagentRoute;
@@ -2,11 +2,11 @@
2
2
  * Lead-dev plan builder — internal implementation for orchestrator + hooks.
3
3
  * Config: features.json → multi_agent_orchestration (lead_dev_mode), NOT a separate surface.
4
4
  */
5
+ import { randomUUID } from 'node:crypto';
5
6
  import * as fs from 'fs';
6
7
  import * as path from 'path';
7
8
  import { featuresConfigLoader } from '../core/features-config.js';
8
9
  import { scoreComplexity } from './thin-dispatch.js';
9
- import { conferDefaultForProfile, resolveRuntimeSuitProfile } from './suit-temperament.js';
10
10
  export const LEAD_DEV_RULES = [
11
11
  'Phased plan + detailed todos; assign best subagent; monitor output; iterate fully',
12
12
  'Lead dev takes helm — loop test fix until complete; no permission pings',
@@ -33,6 +33,19 @@ const TASK_TYPE_ROUTES = {
33
33
  security: 'security-audit',
34
34
  governance: 'enforcer',
35
35
  };
36
+ function conferExplicitlyEnabled(projectRoot) {
37
+ const featuresPath = path.join(projectRoot, '.xray', 'features.json');
38
+ if (!fs.existsSync(featuresPath))
39
+ return false;
40
+ try {
41
+ const data = JSON.parse(fs.readFileSync(featuresPath, 'utf8'));
42
+ const orch = data.multi_agent_orchestration ?? {};
43
+ return orch.confer?.enabled === true || orch.confer_on_synthesis === true;
44
+ }
45
+ catch {
46
+ return false;
47
+ }
48
+ }
36
49
  function orchestrationConfig() {
37
50
  try {
38
51
  return featuresConfigLoader.loadConfig().multi_agent_orchestration;
@@ -80,12 +93,7 @@ export function buildSynthesisCheckpointPlan(dueReason, projectRoot = process.cw
80
93
  if (!isLeadDevModeActive())
81
94
  return null;
82
95
  const cfg = orchestrationConfig();
83
- const profile = resolveRuntimeSuitProfile(projectRoot);
84
- const autoConsult = profile === 'frontier'
85
- ? cfg.confer?.enabled === true || cfg.confer_on_synthesis === true
86
- : profile === 'strict'
87
- ? true
88
- : cfg.auto_consult_major_work !== false;
96
+ const autoConsult = conferExplicitlyEnabled(projectRoot);
89
97
  const mandatoryConsults = autoConsult ? [...MANDATORY_MAJOR_CONSULTS] : [];
90
98
  if (mandatoryConsults.length === 0)
91
99
  return null;
@@ -118,13 +126,13 @@ export function buildSynthesisCheckpointPlan(dueReason, projectRoot = process.cw
118
126
  fullSuiteGate: false,
119
127
  hint: 'Synthesis checkpoint — consult mandatory agents before resuming gated work',
120
128
  },
129
+ consultCycleId: randomUUID(),
121
130
  };
122
131
  }
123
132
  export function buildLeadDevPlan(description, taskTypes = ['implement'], taskInputs = [], mcpOverallComplexity, projectRoot = process.cwd()) {
124
133
  if (!isLeadDevModeActive())
125
134
  return null;
126
135
  const cfg = orchestrationConfig();
127
- const profile = resolveRuntimeSuitProfile(projectRoot);
128
136
  const threshold = cfg.phased_plan_threshold ?? 25;
129
137
  const score = scoreComplexity(description, { taskTypes });
130
138
  const mcpScore = mcpOverallComplexity !== undefined && Number.isFinite(mcpOverallComplexity)
@@ -132,11 +140,7 @@ export function buildLeadDevPlan(description, taskTypes = ['implement'], taskInp
132
140
  : 0;
133
141
  const complexity = Math.max(score.score, mcpScore);
134
142
  const requiresPhasedPlan = complexity > threshold || taskInputs.length > 1;
135
- const autoConsult = profile === 'frontier'
136
- ? cfg.confer?.enabled === true || cfg.confer_on_synthesis === true
137
- : profile === 'strict' || conferDefaultForProfile(profile)
138
- ? cfg.auto_consult_major_work !== false
139
- : false;
143
+ const autoConsult = conferExplicitlyEnabled(projectRoot);
140
144
  const mandatoryConsults = autoConsult && requiresPhasedPlan ? [...MANDATORY_MAJOR_CONSULTS] : [];
141
145
  const phases = requiresPhasedPlan
142
146
  ? [
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Confer host port. The wearing TUI already spawned the MCP servers.
3
+ * This port writes the ask or returns the host's answer. It does not spawn a server.
4
+ */
5
+ export interface ConferHostSeat {
6
+ todoId: string;
7
+ subagent: string;
8
+ server: string;
9
+ tool: string;
10
+ args: Record<string, unknown>;
11
+ sessionId: string;
12
+ prompt: string;
13
+ dueReason: string | null;
14
+ }
15
+ export type ConferHostCall = {
16
+ status: 'pending';
17
+ askPath: string;
18
+ } | {
19
+ status: 'answered';
20
+ text: string;
21
+ };
22
+ export interface ConferHostPort {
23
+ call(seat: ConferHostSeat, projectRoot: string): Promise<ConferHostCall>;
24
+ }
25
+ export declare function conferAskPath(todoId: string, projectRoot: string): string;
26
+ /** Evidence for the host model. The schema line is not a vote. */
27
+ export declare function buildHostConferEvidence(role: string, evidence: string): string;
28
+ export declare class SessionConferHost implements ConferHostPort {
29
+ call(seat: ConferHostSeat, projectRoot: string): Promise<ConferHostCall>;
30
+ }
31
+ export declare class InProcessConferHost implements ConferHostPort {
32
+ private readonly answers;
33
+ constructor(answers: Record<string, string>);
34
+ call(seat: ConferHostSeat): Promise<ConferHostCall>;
35
+ }
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Confer host port. The wearing TUI already spawned the MCP servers.
3
+ * This port writes the ask or returns the host's answer. It does not spawn a server.
4
+ */
5
+ import * as fs from 'fs';
6
+ import * as path from 'path';
7
+ export function conferAskPath(todoId, projectRoot) {
8
+ return path.join(projectRoot, '.xray', 'state', `confer-ask-${todoId}.json`);
9
+ }
10
+ /** Evidence for the host model. The schema line is not a vote. */
11
+ export function buildHostConferEvidence(role, evidence) {
12
+ const body = evidence.trim();
13
+ return [
14
+ `## Confer evidence — ${role}`,
15
+ '',
16
+ body || 'No local evidence. The wearing TUI has the confer ask.',
17
+ '',
18
+ 'The wearing TUI writes the verdict on its own line after this evidence.',
19
+ '',
20
+ 'Verdict: PASS | CONDITIONAL | FAIL',
21
+ '- Top risks (bulleted)',
22
+ '- Hardening note / recommendations',
23
+ ].join('\n');
24
+ }
25
+ export class SessionConferHost {
26
+ async call(seat, projectRoot) {
27
+ const askPath = conferAskPath(seat.todoId, projectRoot);
28
+ fs.mkdirSync(path.dirname(askPath), { recursive: true });
29
+ const payload = {
30
+ todoId: seat.todoId,
31
+ subagent: seat.subagent,
32
+ server: seat.server,
33
+ tool: seat.tool,
34
+ args: seat.args,
35
+ sessionId: seat.sessionId,
36
+ prompt: seat.prompt,
37
+ dueReason: seat.dueReason,
38
+ };
39
+ fs.writeFileSync(askPath, `${JSON.stringify(payload, null, 2)}\n`);
40
+ return { status: 'pending', askPath };
41
+ }
42
+ }
43
+ export class InProcessConferHost {
44
+ answers;
45
+ constructor(answers) {
46
+ this.answers = answers;
47
+ }
48
+ async call(seat) {
49
+ const text = this.answers[seat.todoId] ?? this.answers[seat.subagent];
50
+ if (text === undefined) {
51
+ return { status: 'pending', askPath: '' };
52
+ }
53
+ return { status: 'answered', text };
54
+ }
55
+ }
@@ -3,6 +3,9 @@
3
3
  * Triggered automatically at synthesis checkpoint; records consult receipts + plan todos.
4
4
  */
5
5
  import { type SynthesisConsultReceipt } from './synthesis-consult-receipt.js';
6
+ import { InProcessConferHost, SessionConferHost, type ConferHostPort, type ConferHostSeat } from './confer-host.js';
7
+ export { InProcessConferHost, SessionConferHost };
8
+ export type { ConferHostPort, ConferHostSeat };
6
9
  export declare const CONFER_AGENTS: readonly ["researcher", "architect-tools", "code-review"];
7
10
  export interface ConferConfig {
8
11
  enabled: boolean;
@@ -27,12 +30,16 @@ export interface ConferAgentResult {
27
30
  error?: string;
28
31
  }
29
32
  export interface ConferQuorumResult {
30
- status: 'completed' | 'partial' | 'skipped' | 'failed';
33
+ status: 'completed' | 'partial' | 'skipped' | 'failed' | 'pending';
31
34
  agents: ConferAgentResult[];
32
35
  message: string;
33
36
  }
34
37
  export declare function conferCheckpointPath(projectRoot?: string): string;
35
38
  export declare function defaultConferConfig(): ConferConfig;
39
+ /** Fixture PASS is a test harness. Live orchestrate-task and XRAY_CONFER_FIXTURE cannot reach it. */
40
+ export declare const CONFER_FIXTURE_UNREACHABLE = "Confer fixture is unreachable outside tests";
41
+ export declare function conferFixtureAllowed(): boolean;
42
+ /** A suit profile does not enable Confer. Missing confer key stays off, including strict. */
36
43
  export declare function loadConferConfig(projectRoot?: string): ConferConfig;
37
44
  export declare function isConferEnabled(projectRoot?: string): boolean;
38
45
  export declare function loadConferCheckpoint(projectRoot?: string): ConferCheckpointState | null;
@@ -46,12 +53,21 @@ export declare function conferAgentMcpTarget(subagent: string): {
46
53
  tool: string;
47
54
  args: (prompt: string, projectRoot: string) => Record<string, unknown>;
48
55
  };
49
- export declare function invokeConferAgent(subagent: string, prompt: string, projectRoot?: string): Promise<string>;
56
+ export declare function invokeConferAgent(subagent: string, prompt: string, projectRoot?: string, host?: ConferHostPort, sessionId?: string, todoId?: string, dueReason?: string | null): Promise<string>;
50
57
  export declare function applyConferConsultResult(todoId: string, subagent: string, sessionId: string, outputText: string, projectRoot?: string): ConferAgentResult;
51
- export declare function writeFixtureConferReceipt(todoId: string, subagent: string, sessionId: string, projectRoot?: string): ConferAgentResult;
58
+ export declare function buildFixtureConferOutput(subagent: string, verdict?: SynthesisConsultReceipt['verdict'], noLlm?: boolean): string;
59
+ export declare function writeFixtureConferReceipt(todoId: string, subagent: string, sessionId: string, projectRoot?: string, verdict?: SynthesisConsultReceipt['verdict'], noLlm?: boolean): ConferAgentResult;
52
60
  export declare function runConferQuorum(projectRoot: string | undefined, sessionId: string, options?: {
53
61
  collocatedText?: string;
54
62
  dueReason?: string | null;
55
63
  fixture?: boolean;
64
+ /** Used only when fixture is true. Defaults to PASS. FAIL and UNREVIEWED do not complete the todo. */
65
+ fixtureVerdict?: SynthesisConsultReceipt['verdict'];
66
+ /** Fixture text is the real no-model localConferVote (UNREVIEWED), not a hardcoded PASS. */
67
+ fixtureNoLlm?: boolean;
68
+ /** Used only when fixture is true. Replaces the generated fixture text for every consult. */
69
+ fixtureOutput?: string;
70
+ /** Live path. Default writes an ask for the wearing TUI and does not spawn a server. */
71
+ host?: ConferHostPort;
56
72
  }): Promise<ConferQuorumResult>;
57
73
  export declare function formatConferQuorumReport(result: ConferQuorumResult): string;