0xray 2.1.4 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/CHANGELOG.md +31 -0
- package/dist/cli/commands/govern.d.ts +29 -0
- package/dist/cli/commands/govern.js +152 -0
- package/dist/cli/index.js +29 -216
- package/dist/core/framework-logger.js +30 -1
- package/dist/delegation/index.d.ts +1 -2
- package/dist/delegation/index.js +1 -2
- package/dist/enforcement/enforcer-tools.js +1 -1
- package/dist/execution/proposal-applier.d.ts +1 -9
- package/dist/execution/proposal-applier.js +18 -173
- package/dist/governance/codex-policy.service.d.ts +7 -25
- package/dist/governance/codex-policy.service.js +8 -26
- package/dist/governance/governance-core.d.ts +22 -28
- package/dist/governance/governance-core.js +31 -101
- package/dist/governance/governance-service.d.ts +1 -0
- package/dist/governance/governance-service.js +67 -4
- package/dist/governance/governance-types.d.ts +5 -2
- package/dist/inference/index.d.ts +3 -4
- package/dist/inference/inference-accumulator.js +1 -1
- package/dist/inference/inference-cycle.d.ts +12 -18
- package/dist/inference/inference-cycle.js +120 -335
- package/dist/integrations/base/index.d.ts +0 -1
- package/dist/integrations/base/index.js +0 -2
- package/dist/integrations/grok/hooks/pre-tool-use.js +4 -18
- package/dist/integrations/hermes-agent/bridge.mjs +9 -0
- package/dist/mcps/config/server-config-registry.js +1 -1
- package/dist/mcps/governance.server.js +3 -4
- package/dist/mcps/knowledge-skills/api-design.server.js +10 -0
- package/dist/mcps/knowledge-skills/architecture-patterns.server.js +10 -0
- package/dist/mcps/knowledge-skills/bug-triage-specialist.server.js +10 -0
- package/dist/mcps/knowledge-skills/code-analyzer.server.js +10 -0
- package/dist/mcps/knowledge-skills/code-review.server.js +10 -0
- package/dist/mcps/knowledge-skills/content-creator.server.js +10 -0
- package/dist/mcps/knowledge-skills/database-design.server.js +10 -0
- package/dist/mcps/knowledge-skills/devops-deployment.server.js +10 -0
- package/dist/mcps/knowledge-skills/git-workflow.server.js +10 -0
- package/dist/mcps/knowledge-skills/growth-strategist.server.js +10 -0
- package/dist/mcps/knowledge-skills/log-monitor.server.js +10 -0
- package/dist/mcps/knowledge-skills/mobile-development.server.js +10 -0
- package/dist/mcps/knowledge-skills/multimodal-looker.server.js +10 -0
- package/dist/mcps/knowledge-skills/performance-optimization.server.js +10 -0
- package/dist/mcps/knowledge-skills/project-analysis.server.js +10 -0
- package/dist/mcps/knowledge-skills/refactoring-strategies.server.js +10 -0
- package/dist/mcps/knowledge-skills/security-audit.server.js +10 -0
- package/dist/mcps/knowledge-skills/seo-consultant.server.js +10 -0
- package/dist/mcps/knowledge-skills/skill-invocation.server.d.ts +4 -0
- package/dist/mcps/knowledge-skills/skill-invocation.server.js +33 -14
- package/dist/mcps/knowledge-skills/strategist.server.js +10 -0
- package/dist/mcps/knowledge-skills/tech-writer.server.js +10 -0
- package/dist/mcps/knowledge-skills/testing-strategy.server.js +10 -0
- package/dist/mcps/knowledge-skills/ui-ux-design.server.js +10 -0
- package/dist/metrics/agent-metrics.d.ts +2 -1
- package/dist/nucleus/govern-http.d.ts +59 -0
- package/dist/nucleus/govern-http.js +172 -0
- package/dist/nucleus/index.d.ts +14 -0
- package/dist/nucleus/index.js +9 -0
- package/dist/nucleus/kernel.d.ts +51 -0
- package/dist/nucleus/kernel.js +62 -0
- package/dist/nucleus/plugin-registry.d.ts +104 -0
- package/dist/nucleus/plugin-registry.js +147 -0
- package/dist/orchestrator/orchestrator.d.ts +0 -1
- package/dist/orchestrator/orchestrator.js +0 -21
- package/dist/postprocessor/PostProcessor.d.ts +13 -1
- package/dist/postprocessor/PostProcessor.js +41 -1
- package/dist/postprocessor/autofix/AutoFixEngine.d.ts +0 -8
- package/dist/postprocessor/autofix/AutoFixEngine.js +0 -54
- package/dist/postprocessor/metamorphosis/MetamorphosisEngine.d.ts +25 -0
- package/dist/postprocessor/metamorphosis/MetamorphosisEngine.js +10 -0
- package/dist/postprocessor/metamorphosis/SelfProposalEngine.d.ts +68 -0
- package/dist/postprocessor/metamorphosis/SelfProposalEngine.js +371 -0
- package/dist/skills/orchestrator/SKILL.md +1 -1
- package/dist/state/index.d.ts +0 -2
- package/package.json +4 -3
- package/scripts/node/universal-version-manager.js +2 -2
- package/src/mcps/config/__tests__/server-config-registry.test.ts +6 -15
- package/src/mcps/config/server-config-registry.ts +1 -1
- package/src/mcps/governance.server.ts +3 -5
- package/src/mcps/knowledge-skills/api-design.server.ts +9 -0
- package/src/mcps/knowledge-skills/architecture-patterns.server.ts +9 -0
- package/src/mcps/knowledge-skills/bug-triage-specialist.server.ts +9 -0
- package/src/mcps/knowledge-skills/code-analyzer.server.ts +9 -0
- package/src/mcps/knowledge-skills/code-review.server.ts +9 -0
- package/src/mcps/knowledge-skills/content-creator.server.ts +9 -0
- package/src/mcps/knowledge-skills/database-design.server.ts +9 -0
- package/src/mcps/knowledge-skills/devops-deployment.server.ts +9 -0
- package/src/mcps/knowledge-skills/git-workflow.server.ts +9 -0
- package/src/mcps/knowledge-skills/growth-strategist.server.ts +9 -0
- package/src/mcps/knowledge-skills/log-monitor.server.ts +9 -0
- package/src/mcps/knowledge-skills/mobile-development.server.ts +9 -0
- package/src/mcps/knowledge-skills/multimodal-looker.server.ts +9 -0
- package/src/mcps/knowledge-skills/performance-optimization.server.ts +9 -0
- package/src/mcps/knowledge-skills/project-analysis.server.ts +9 -0
- package/src/mcps/knowledge-skills/refactoring-strategies.server.ts +9 -0
- package/src/mcps/knowledge-skills/security-audit.server.ts +9 -0
- package/src/mcps/knowledge-skills/seo-consultant.server.ts +9 -0
- package/src/mcps/knowledge-skills/session-management.server.ts +1 -0
- package/src/mcps/knowledge-skills/skill-invocation.server.ts +44 -29
- package/src/mcps/knowledge-skills/strategist.server.ts +9 -0
- package/src/mcps/knowledge-skills/tech-writer.server.ts +9 -0
- package/src/mcps/knowledge-skills/testing-strategy.server.ts +9 -0
- package/src/mcps/knowledge-skills/ui-ux-design.server.ts +9 -0
- package/src/skills/orchestrator/SKILL.md +1 -1
- package/.opencode/agents/testing-best-practices.yml +0 -12
- package/dist/analytics/consent-manager.d.ts +0 -93
- package/dist/analytics/consent-manager.js +0 -258
- package/dist/analytics/simple-pattern-analyzer.d.ts +0 -80
- package/dist/analytics/simple-pattern-analyzer.js +0 -297
- package/dist/cli/commands/analytics-disable.d.ts +0 -9
- package/dist/cli/commands/analytics-disable.js +0 -72
- package/dist/cli/commands/analytics-enable-action.d.ts +0 -8
- package/dist/cli/commands/analytics-enable-action.js +0 -82
- package/dist/cli/commands/analytics-preview.d.ts +0 -9
- package/dist/cli/commands/analytics-preview.js +0 -106
- package/dist/cli/commands/analytics-status.d.ts +0 -9
- package/dist/cli/commands/analytics-status.js +0 -68
- package/dist/cli/server.d.ts +0 -1
- package/dist/cli/server.js +0 -147
- package/dist/core/errors.d.ts +0 -3
- package/dist/core/errors.js +0 -10
- package/dist/core/logging-config.d.ts +0 -11
- package/dist/core/logging-config.js +0 -43
- package/dist/core/trace-context.d.ts +0 -12
- package/dist/core/trace-context.js +0 -33
- package/dist/delegation/voting-coordinator.d.ts +0 -49
- package/dist/delegation/voting-coordinator.js +0 -375
- package/dist/enforcement/test-auto-healing.d.ts +0 -83
- package/dist/enforcement/test-auto-healing.js +0 -325
- package/dist/integrations/base/ExampleIntegration.d.ts +0 -47
- package/dist/integrations/base/ExampleIntegration.js +0 -181
- package/dist/mcps/knowledge-skills/testing-best-practices.server.d.ts +0 -34
- package/dist/mcps/knowledge-skills/testing-best-practices.server.js +0 -831
- package/dist/mcps/orchestrator.server.d.ts +0 -10
- package/dist/mcps/orchestrator.server.js +0 -19
- package/dist/orchestrator/self-direction-activation.d.ts +0 -109
- package/dist/orchestrator/self-direction-activation.js +0 -245
- package/dist/orchestrator/universal-librarian-consultation.d.ts +0 -98
- package/dist/orchestrator/universal-librarian-consultation.js +0 -216
- package/dist/orchestrator/universal-registry-bridge.d.ts +0 -85
- package/dist/orchestrator/universal-registry-bridge.js +0 -247
- package/dist/performance/performance-budget-enforcer.d.ts +0 -158
- package/dist/performance/performance-budget-enforcer.js +0 -434
- package/dist/performance/performance-regression-tester.d.ts +0 -108
- package/dist/performance/performance-regression-tester.js +0 -342
- package/dist/skills/testing-best-practices/SKILL.md +0 -37
- package/dist/state/context-providers.d.ts +0 -4
- package/dist/state/context-providers.js +0 -1
- package/dist/state/state-types.d.ts +0 -5
- package/dist/state/state-types.js +0 -1
- package/dist/utils/batch-operations.d.ts +0 -25
- package/dist/utils/batch-operations.js +0 -292
- package/dist/utils/test-template-generator.d.ts +0 -25
- package/dist/utils/test-template-generator.js +0 -178
- package/dist/utils/token-manager.d.ts +0 -48
- package/dist/utils/token-manager.js +0 -163
- package/src/mcps/knowledge-skills/testing-best-practices.server.test.ts +0 -136
- package/src/mcps/knowledge-skills/testing-best-practices.server.ts +0 -1183
- package/src/mcps/orchestrator.server.ts +0 -34
- package/src/opencode/agents/testing-best-practices.yml +0 -12
- package/src/skills/testing-best-practices/SKILL.md +0 -37
|
@@ -2,31 +2,20 @@ import * as fs from "fs";
|
|
|
2
2
|
import * as path from "path";
|
|
3
3
|
import { shouldTriggerCycle, accumulateCorpus } from "./inference-accumulator.js";
|
|
4
4
|
import { DeployVerifier } from "./deploy-verifier.js";
|
|
5
|
-
import { VotingCoordinator } from "../delegation/voting-coordinator.js";
|
|
6
5
|
import { XrayStateManager } from "../state/state-manager.js";
|
|
7
6
|
import { frameworkLogger } from "../core/framework-logger.js";
|
|
8
|
-
import { getGovernanceIntegration } from "../integrations/governance/index.js";
|
|
9
7
|
import { featuresConfigLoader } from "../core/features-config.js";
|
|
10
8
|
import { mcpClientManager } from "../mcps/mcp-client.js";
|
|
11
9
|
import { getConfigDir } from "../core/config-paths.js";
|
|
12
10
|
import { invokeViaOpencode as invokeOpencodeFromEngine } from "../execution/opencode-cli-invoker.js";
|
|
13
11
|
import { ProposalApplier } from "../execution/proposal-applier.js";
|
|
14
|
-
|
|
15
|
-
const
|
|
16
|
-
const GOVERNANCE_AGENTS = {
|
|
17
|
-
// Real individual knowledge-skill MCP servers (have analyze_proposal handlers)
|
|
18
|
-
fix: ["code-review", "security-audit", "researcher"],
|
|
19
|
-
refactor: ["code-review", "security-audit", "researcher"],
|
|
20
|
-
guard: ["code-review", "security-audit", "researcher"],
|
|
21
|
-
automate: ["code-review", "security-audit", "researcher"],
|
|
22
|
-
codify: ["code-review", "security-audit", "researcher"],
|
|
23
|
-
};
|
|
12
|
+
import { handleGovernRequest } from "../nucleus/govern-http.js";
|
|
13
|
+
const CONSOLIDATED_STATE_FILE = "inference-state.json";
|
|
24
14
|
export class InferenceCycle {
|
|
25
15
|
// Singleton registry + state management to prevent recursive agent spawning
|
|
26
16
|
static instances = new Map();
|
|
27
17
|
static reEntryLock = false;
|
|
28
18
|
static governedProposalIds = new Set();
|
|
29
|
-
static votingCoordinator = null;
|
|
30
19
|
static getInstance(projectRoot, options) {
|
|
31
20
|
const root = path.resolve(projectRoot || process.cwd());
|
|
32
21
|
if (!InferenceCycle.instances.has(root)) {
|
|
@@ -38,7 +27,6 @@ export class InferenceCycle {
|
|
|
38
27
|
InferenceCycle.instances.clear();
|
|
39
28
|
InferenceCycle.reEntryLock = false;
|
|
40
29
|
InferenceCycle.governedProposalIds.clear();
|
|
41
|
-
InferenceCycle.votingCoordinator = null;
|
|
42
30
|
}
|
|
43
31
|
inferenceDir;
|
|
44
32
|
stateDir;
|
|
@@ -98,7 +86,6 @@ export class InferenceCycle {
|
|
|
98
86
|
InferenceCycle.governedProposalIds.add(p.id);
|
|
99
87
|
this.setPhase("complete");
|
|
100
88
|
this.saveCycleState(cycleId);
|
|
101
|
-
this.saveGovernanceState(this.getCoordinator());
|
|
102
89
|
const result = this.buildResult(cycleId, true, "external proposals", startTime, undefined, proposals, votes);
|
|
103
90
|
this.appendHistory(result);
|
|
104
91
|
frameworkLogger.log("inference-cycle", "external-governance-complete", "info", {
|
|
@@ -124,7 +111,7 @@ export class InferenceCycle {
|
|
|
124
111
|
const cycleId = `cycle-${Date.now()}`;
|
|
125
112
|
try {
|
|
126
113
|
this.setPhase("collecting");
|
|
127
|
-
const lastCycleFile = path.join(this.stateDir,
|
|
114
|
+
const lastCycleFile = path.join(this.stateDir, CONSOLIDATED_STATE_FILE);
|
|
128
115
|
const threshold = this.options.force ? { trigger: true, reason: "force flag set" } : shouldTriggerCycle(this.inferenceDir, lastCycleFile);
|
|
129
116
|
if (!threshold.trigger) {
|
|
130
117
|
this.setPhase("idle");
|
|
@@ -188,7 +175,6 @@ export class InferenceCycle {
|
|
|
188
175
|
}
|
|
189
176
|
this.setPhase("complete");
|
|
190
177
|
this.saveCycleState(cycleId);
|
|
191
|
-
this.saveGovernanceState(this.getCoordinator());
|
|
192
178
|
this.appendHistory(this.buildResult(cycleId, true, threshold.reason, startTime, corpus, proposals, votes, deployResult));
|
|
193
179
|
return this.buildResult(cycleId, true, threshold.reason, startTime, corpus, proposals, votes, deployResult);
|
|
194
180
|
}
|
|
@@ -270,19 +256,8 @@ export class InferenceCycle {
|
|
|
270
256
|
this.adjustConfidenceFromHistory(proposals);
|
|
271
257
|
proposals.sort((a, b) => b.confidence - a.confidence);
|
|
272
258
|
}
|
|
273
|
-
getCoordinator() {
|
|
274
|
-
if (!InferenceCycle.votingCoordinator) {
|
|
275
|
-
const stateManager = this.getGovernanceStateManager();
|
|
276
|
-
InferenceCycle.votingCoordinator = new VotingCoordinator(stateManager);
|
|
277
|
-
}
|
|
278
|
-
return InferenceCycle.votingCoordinator;
|
|
279
|
-
}
|
|
280
259
|
async applyProposals(proposals) {
|
|
281
|
-
const applier = new ProposalApplier(this.projectRoot
|
|
282
|
-
if (this.options.skipResearcherReview)
|
|
283
|
-
return "go";
|
|
284
|
-
return this.researcherReview(p, prUrl);
|
|
285
|
-
});
|
|
260
|
+
const applier = new ProposalApplier(this.projectRoot);
|
|
286
261
|
const results = await applier.applyProposals(proposals);
|
|
287
262
|
for (const r of results) {
|
|
288
263
|
const p = proposals.find(pr => pr.id === r.proposalId);
|
|
@@ -453,9 +428,36 @@ Respond with EXACTLY one of:
|
|
|
453
428
|
}
|
|
454
429
|
}
|
|
455
430
|
async governProposals(proposals) {
|
|
456
|
-
// Primary path
|
|
457
|
-
// This
|
|
458
|
-
|
|
431
|
+
// v3: Primary path through the nucleus kernel (handleGovernRequest)
|
|
432
|
+
// This gives ALL proposals the same contract: 3-agent + Dynamo governance,
|
|
433
|
+
// metamorphosis scoring, dynamic skills, and structured logging.
|
|
434
|
+
// The MCP governance server remains the standard external surface; this is the
|
|
435
|
+
// internal uniform path that the MCP server also delegates to.
|
|
436
|
+
try {
|
|
437
|
+
const governanceResponse = await this.governViaNucleus(proposals);
|
|
438
|
+
frameworkLogger.log("inference-cycle", "governance-nucleus-success", "info", {
|
|
439
|
+
proposalCount: proposals.length,
|
|
440
|
+
overall: governanceResponse.overallDecision,
|
|
441
|
+
});
|
|
442
|
+
return this.convertNucleusResponse(governanceResponse, proposals);
|
|
443
|
+
}
|
|
444
|
+
catch (err) {
|
|
445
|
+
frameworkLogger.log("inference-cycle", "governance-nucleus-failed", "warning", {
|
|
446
|
+
error: err instanceof Error ? err.message : String(err),
|
|
447
|
+
stack: err instanceof Error ? err.stack : undefined,
|
|
448
|
+
});
|
|
449
|
+
// In forced pure MCP mode we must not silently fall back
|
|
450
|
+
if (process.env.XRAY_FORCE_MCP_GOVERNANCE === 'true') {
|
|
451
|
+
throw err;
|
|
452
|
+
}
|
|
453
|
+
// Fallback: try the Governance MCP directly (the standard external surface)
|
|
454
|
+
frameworkLogger.log("inference-cycle", "governance-mcp-fallback", "warning", {
|
|
455
|
+
message: "Nucleus path failed; falling back to Governance MCP.",
|
|
456
|
+
originalError: err instanceof Error ? err.message : String(err),
|
|
457
|
+
});
|
|
458
|
+
}
|
|
459
|
+
// Fallback: MCP governance server
|
|
460
|
+
const useGovernanceMcp = process.env.XRAY_FORCE_MCP_GOVERNANCE === 'true' ||
|
|
459
461
|
this.isGovernanceMcpPreferred();
|
|
460
462
|
if (useGovernanceMcp) {
|
|
461
463
|
try {
|
|
@@ -477,35 +479,79 @@ Respond with EXACTLY one of:
|
|
|
477
479
|
]);
|
|
478
480
|
const text = result?.content?.[0]?.text || "";
|
|
479
481
|
const parsed = this.parseGovernanceMcpResponse(text, proposals);
|
|
480
|
-
frameworkLogger.log("inference-cycle", "governance-mcp-
|
|
482
|
+
frameworkLogger.log("inference-cycle", "governance-mcp-fallback-success", "info", {
|
|
481
483
|
proposalCount: proposals.length,
|
|
482
484
|
overall: parsed.overallDecision,
|
|
483
485
|
});
|
|
484
486
|
return parsed.votes;
|
|
485
487
|
}
|
|
486
488
|
catch (err) {
|
|
487
|
-
frameworkLogger.log("inference-cycle", "governance-mcp-failed", "error", {
|
|
489
|
+
frameworkLogger.log("inference-cycle", "governance-mcp-fallback-failed", "error", {
|
|
488
490
|
error: err instanceof Error ? err.message : String(err),
|
|
489
491
|
});
|
|
490
|
-
// In forced pure MCP mode we must not silently fall back
|
|
491
|
-
if (process.env.XRAY_FORCE_MCP_GOVERNANCE === 'true') {
|
|
492
|
-
throw err;
|
|
493
|
-
}
|
|
494
|
-
// In normal mode, fall back to legacy path with deprecation warning.
|
|
495
|
-
// The legacy path will be removed once all consumers have migrated to the Governance MCP + Dynamo Solar SSOT model.
|
|
496
|
-
frameworkLogger.log("inference-cycle", "governance-legacy-fallback", "warning", {
|
|
497
|
-
message: "Falling back to legacy governance path. This path is deprecated and will be removed in a future version.",
|
|
498
|
-
});
|
|
499
492
|
}
|
|
500
493
|
}
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
494
|
+
throw new Error("All governance paths exhausted: nucleus and MCP fallback both failed");
|
|
495
|
+
}
|
|
496
|
+
/**
|
|
497
|
+
* Map InferenceProposal.source to GovernanceProposal.source.
|
|
498
|
+
* Inference-specific sources (recurring_problem, recurring_pattern, wrong_turn)
|
|
499
|
+
* all normalize to 'inference'. Future tuning/mod-specific sources can be added here.
|
|
500
|
+
*/
|
|
501
|
+
static SOURCE_MAP = {
|
|
502
|
+
'recurring_problem': 'inference',
|
|
503
|
+
'recurring_pattern': 'inference',
|
|
504
|
+
'wrong_turn': 'inference',
|
|
505
|
+
};
|
|
506
|
+
/**
|
|
507
|
+
* Convert InferenceProposal[] to GovernanceRequest and route through
|
|
508
|
+
* the nucleus kernel (handleGovernRequest). This is the v3 uniform path.
|
|
509
|
+
*/
|
|
510
|
+
async governViaNucleus(proposals) {
|
|
511
|
+
const governanceRequest = {
|
|
512
|
+
proposals: proposals.map(p => ({
|
|
513
|
+
id: p.id,
|
|
514
|
+
type: p.type,
|
|
515
|
+
title: p.title,
|
|
516
|
+
description: p.description,
|
|
517
|
+
evidence: p.evidence,
|
|
518
|
+
source: InferenceCycle.SOURCE_MAP[p.source] || 'inference',
|
|
519
|
+
confidence: p.confidence,
|
|
520
|
+
})),
|
|
521
|
+
context: {
|
|
522
|
+
project: 'xray',
|
|
523
|
+
phase: 'inference-cycle',
|
|
524
|
+
source: 'inference-cycle',
|
|
525
|
+
},
|
|
526
|
+
options: {
|
|
527
|
+
requireExternalDynamo: true,
|
|
528
|
+
},
|
|
529
|
+
};
|
|
530
|
+
return handleGovernRequest(governanceRequest);
|
|
531
|
+
}
|
|
532
|
+
/**
|
|
533
|
+
* Convert a GovernanceResponse (nucleus kernel format) back to the
|
|
534
|
+
* InferenceCycleResult["votes"] format that the rest of the cycle expects.
|
|
535
|
+
*/
|
|
536
|
+
convertNucleusResponse(response, proposals) {
|
|
537
|
+
return proposals.map((p, i) => {
|
|
538
|
+
const result = response.results[i];
|
|
539
|
+
if (!result) {
|
|
540
|
+
return {
|
|
541
|
+
proposalId: p.id,
|
|
542
|
+
decision: 'reject',
|
|
543
|
+
confidence: 0,
|
|
544
|
+
details: ['nucleus: no result returned'],
|
|
545
|
+
};
|
|
546
|
+
}
|
|
547
|
+
const decision = result.finalDecision === 'approve' ? 'approve' : result.finalDecision === 'reject' ? 'reject' : 'abstain';
|
|
548
|
+
return {
|
|
549
|
+
proposalId: p.id,
|
|
550
|
+
decision,
|
|
551
|
+
confidence: result.averageConfidence,
|
|
552
|
+
details: result.votes?.map((v) => `${v.server || v.agentName || 'agent'}: ${v.decision} (${v.confidence})`) || [result.reasoningSummary],
|
|
553
|
+
};
|
|
554
|
+
});
|
|
509
555
|
}
|
|
510
556
|
isGovernanceMcpPreferred() {
|
|
511
557
|
try {
|
|
@@ -547,230 +593,6 @@ Respond with EXACTLY one of:
|
|
|
547
593
|
return { votes, overallDecision: "needs_revision" };
|
|
548
594
|
}
|
|
549
595
|
}
|
|
550
|
-
/**
|
|
551
|
-
* Oscillator 1: Internal VotingCoordinator-based governance
|
|
552
|
-
*/
|
|
553
|
-
async governProposalsInternal(proposals) {
|
|
554
|
-
// Defensive: if pure MCP mode is forced, use individual skill servers only
|
|
555
|
-
if ((process.env.XRAY_FORCE_MCP_GOVERNANCE) === 'true') {
|
|
556
|
-
return this.governProposalsWithIndividualSkills(proposals);
|
|
557
|
-
}
|
|
558
|
-
const coordinator = this.getCoordinator();
|
|
559
|
-
const sessionId = `inference-governance-${Date.now()}`;
|
|
560
|
-
const results = [];
|
|
561
|
-
const todoPrompt = [
|
|
562
|
-
`Vote on ${proposals.length} inference proposals. Output EXACTLY one PROPOSAL block per proposal.`,
|
|
563
|
-
``,
|
|
564
|
-
`FORMAT (exact, no extra text, no markdown):`,
|
|
565
|
-
`PROPOSAL: <number>`,
|
|
566
|
-
` AGENT: architect`,
|
|
567
|
-
` DECISION: approve|reject|abstain`,
|
|
568
|
-
` CONFIDENCE: 0.XX`,
|
|
569
|
-
` REASONING: <brief reason>`,
|
|
570
|
-
``,
|
|
571
|
-
`Example:`,
|
|
572
|
-
`PROPOSAL: 1`,
|
|
573
|
-
` AGENT: architect`,
|
|
574
|
-
` DECISION: approve`,
|
|
575
|
-
` CONFIDENCE: 0.85`,
|
|
576
|
-
` REASONING: Cleanup reduces maintenance burden`,
|
|
577
|
-
``,
|
|
578
|
-
`PROPOSALS:`,
|
|
579
|
-
];
|
|
580
|
-
for (let i = 0; i < proposals.length; i++) {
|
|
581
|
-
const p = proposals[i];
|
|
582
|
-
todoPrompt.push(`${i + 1}. [${p.type}] "${p.title}"`);
|
|
583
|
-
}
|
|
584
|
-
try {
|
|
585
|
-
const jsonOutput = await this.invokeAgentInternal("architect", todoPrompt.join("\n"));
|
|
586
|
-
const allVotes = this.parseSubagentVotes(jsonOutput, proposals);
|
|
587
|
-
for (const proposal of proposals) {
|
|
588
|
-
const agents = GOVERNANCE_AGENTS[proposal.type] ?? ["code-reviewer"];
|
|
589
|
-
const participants = ["architect", ...agents];
|
|
590
|
-
const voteId = await coordinator.initiateVoting(sessionId, proposal.title, proposal.description, participants, {
|
|
591
|
-
complexity: Math.min(50, 10 + proposal.evidence.length * 5 + (proposal.confidence > 0.8 ? 10 : 0)),
|
|
592
|
-
riskLevel: proposal.type === "fix" ? "low" : proposal.type === "guard" ? "high" : "medium",
|
|
593
|
-
hasSecurityConcerns: proposal.type === "guard" || proposal.type === "fix",
|
|
594
|
-
hasArchitecturalImpact: proposal.type === "codify" || proposal.type === "automate",
|
|
595
|
-
participantCount: participants.length,
|
|
596
|
-
});
|
|
597
|
-
const proposalVotes = allVotes.filter((v) => v.proposalId === proposal.id);
|
|
598
|
-
for (const v of proposalVotes) {
|
|
599
|
-
coordinator.submitVote(voteId, v.agentName, v.decision, v.confidence, v.reasoning);
|
|
600
|
-
}
|
|
601
|
-
const resolved = coordinator.resolveVoting(voteId);
|
|
602
|
-
if (resolved) {
|
|
603
|
-
results.push({
|
|
604
|
-
proposalId: proposal.id,
|
|
605
|
-
decision: resolved.decision === "approve" ? "approve" : "reject",
|
|
606
|
-
confidence: resolved.confidence,
|
|
607
|
-
details: resolved.details?.map((d) => `${d.agentName}: vote=${d.vote}, weight=${d.weight.toFixed(2)}`) || [],
|
|
608
|
-
});
|
|
609
|
-
if (resolved.details) {
|
|
610
|
-
for (const detail of resolved.details) {
|
|
611
|
-
this.getCoordinator().getAggregator().updateAgentPerformance(detail.agentName, resolved.decision, detail.vote, detail.vote === resolved.decision, proposal.confidence);
|
|
612
|
-
}
|
|
613
|
-
}
|
|
614
|
-
}
|
|
615
|
-
else {
|
|
616
|
-
results.push(this.rejectNoQuorum(proposal, "agents did not vote (no quorum)"));
|
|
617
|
-
}
|
|
618
|
-
}
|
|
619
|
-
}
|
|
620
|
-
catch (error) {
|
|
621
|
-
frameworkLogger.log("inference-cycle", "architect-governance-failed", "error", { error: String(error) });
|
|
622
|
-
for (const proposal of proposals) {
|
|
623
|
-
results.push(this.rejectNoQuorum(proposal, `agent invocation failed: ${error instanceof Error ? error.message : String(error)}`));
|
|
624
|
-
}
|
|
625
|
-
}
|
|
626
|
-
const metrics = coordinator.getMetrics();
|
|
627
|
-
frameworkLogger.log("inference-cycle", "governance-metrics", "info", {
|
|
628
|
-
totalVotes: metrics.totalVotes,
|
|
629
|
-
avgConfidence: metrics.averageConfidence.toFixed(2),
|
|
630
|
-
strategyUsage: metrics.strategyUsage,
|
|
631
|
-
});
|
|
632
|
-
return results;
|
|
633
|
-
}
|
|
634
|
-
/**
|
|
635
|
-
* Pure individual knowledge-skill MCP path for governance.
|
|
636
|
-
* Used when XRAY_FORCE_MCP_GOVERNANCE=true.
|
|
637
|
-
* Each proposal is evaluated directly by the relevant skill servers using analyze_proposal.
|
|
638
|
-
*/
|
|
639
|
-
async governProposalsWithIndividualSkills(proposals) {
|
|
640
|
-
const results = [];
|
|
641
|
-
const GOVERNANCE_AGENTS = {
|
|
642
|
-
fix: ["code-review", "security-audit", "researcher"],
|
|
643
|
-
refactor: ["code-review", "security-audit", "researcher"],
|
|
644
|
-
guard: ["code-review", "security-audit", "researcher"],
|
|
645
|
-
automate: ["code-review", "security-audit", "researcher"],
|
|
646
|
-
codify: ["code-review", "security-audit", "researcher"],
|
|
647
|
-
};
|
|
648
|
-
for (const proposal of proposals) {
|
|
649
|
-
const agents = GOVERNANCE_AGENTS[proposal.type] ?? ["code-review", "security-audit"];
|
|
650
|
-
const skillVotes = [];
|
|
651
|
-
for (const agent of agents) {
|
|
652
|
-
try {
|
|
653
|
-
const skillResult = await mcpClientManager.callServerTool(agent, "analyze_proposal", {
|
|
654
|
-
proposalTitle: proposal.title,
|
|
655
|
-
proposalDescription: proposal.description,
|
|
656
|
-
evidence: proposal.evidence,
|
|
657
|
-
proposalType: proposal.type,
|
|
658
|
-
});
|
|
659
|
-
let structured = "";
|
|
660
|
-
const contents = skillResult?.content || [];
|
|
661
|
-
for (const c of contents) {
|
|
662
|
-
if (c?.text && c.text.includes("DECISION:")) {
|
|
663
|
-
structured = c.text.trim();
|
|
664
|
-
break;
|
|
665
|
-
}
|
|
666
|
-
}
|
|
667
|
-
if (!structured) {
|
|
668
|
-
const full = JSON.stringify(skillResult);
|
|
669
|
-
const m = full.match(/DECISION:\s*(approve|reject|abstain)[\s\S]{0,300}?REASONING:[^\n"]*/i);
|
|
670
|
-
if (m)
|
|
671
|
-
structured = m[0].trim();
|
|
672
|
-
}
|
|
673
|
-
skillVotes.push({
|
|
674
|
-
agent,
|
|
675
|
-
toolUsed: "analyze_proposal",
|
|
676
|
-
rawResponse: structured || JSON.stringify(skillResult),
|
|
677
|
-
structuredVote: structured || null,
|
|
678
|
-
});
|
|
679
|
-
}
|
|
680
|
-
catch (err) {
|
|
681
|
-
skillVotes.push({
|
|
682
|
-
agent,
|
|
683
|
-
toolUsed: "analyze_proposal",
|
|
684
|
-
rawResponse: `error: ${err}`,
|
|
685
|
-
structuredVote: null,
|
|
686
|
-
});
|
|
687
|
-
}
|
|
688
|
-
}
|
|
689
|
-
const approves = skillVotes.filter((v) => v.structuredVote && v.structuredVote.includes("DECISION: approve")).length;
|
|
690
|
-
const rejects = skillVotes.filter((v) => v.structuredVote && v.structuredVote.includes("DECISION: reject")).length;
|
|
691
|
-
const decision = approves > rejects ? "approve" : (rejects > approves ? "reject" : "abstain");
|
|
692
|
-
let avgConf = 0.75;
|
|
693
|
-
const confMatches = skillVotes.map((v) => {
|
|
694
|
-
if (!v.structuredVote)
|
|
695
|
-
return 0.75;
|
|
696
|
-
const m = v.structuredVote.match(/CONFIDENCE:\s*([0-9.]+)/);
|
|
697
|
-
return m ? parseFloat(m[1]) : 0.75;
|
|
698
|
-
});
|
|
699
|
-
if (confMatches.length > 0)
|
|
700
|
-
avgConf = confMatches.reduce((a, b) => a + b, 0) / confMatches.length;
|
|
701
|
-
results.push({
|
|
702
|
-
proposalId: proposal.id,
|
|
703
|
-
decision: decision,
|
|
704
|
-
confidence: Math.round(avgConf * 100) / 100,
|
|
705
|
-
details: skillVotes.map((v) => `${v.agent}: ${v.structuredVote?.split('\n')[0] || 'no structured vote'}`),
|
|
706
|
-
});
|
|
707
|
-
}
|
|
708
|
-
return results;
|
|
709
|
-
}
|
|
710
|
-
/**
|
|
711
|
-
* Merge internal and external governance votes.
|
|
712
|
-
* A proposal passes both oscillators — must be approved by internal AND external.
|
|
713
|
-
*/
|
|
714
|
-
mergeGovernanceVotes(internalVotes, externalVotes, proposals) {
|
|
715
|
-
const merged = [];
|
|
716
|
-
for (const proposal of proposals) {
|
|
717
|
-
const internal = internalVotes.find((v) => v.proposalId === proposal.id);
|
|
718
|
-
const external = externalVotes.find((v) => v.proposalId === proposal.id);
|
|
719
|
-
if (!internal) {
|
|
720
|
-
merged.push(this.rejectNoQuorum(proposal, "internal governance vote missing"));
|
|
721
|
-
continue;
|
|
722
|
-
}
|
|
723
|
-
const internalApproved = internal.decision === "approve";
|
|
724
|
-
const externalApproved = external?.decision === "approve";
|
|
725
|
-
const bothApproved = internalApproved && (!external || externalApproved);
|
|
726
|
-
merged.push({
|
|
727
|
-
proposalId: proposal.id,
|
|
728
|
-
decision: bothApproved ? "approve" : "reject",
|
|
729
|
-
confidence: internal.confidence * (external ? external.confidence : 1.0),
|
|
730
|
-
details: [
|
|
731
|
-
...internal.details,
|
|
732
|
-
...(external ? [`External governance: ${external.decision} (conf: ${external.confidence.toFixed(2)})`, ...external.details] : []),
|
|
733
|
-
],
|
|
734
|
-
});
|
|
735
|
-
}
|
|
736
|
-
return merged;
|
|
737
|
-
}
|
|
738
|
-
// Removed: buildOrchestratorGovernancePrompt (replaced by inline TODO prompt in governProposals)
|
|
739
|
-
/**
|
|
740
|
-
* Govern proposals using external chrono-warp-drive Dynamo endpoint
|
|
741
|
-
*/
|
|
742
|
-
async governProposalsExternal(proposals) {
|
|
743
|
-
const governanceIntegration = getGovernanceIntegration();
|
|
744
|
-
if (!governanceIntegration) {
|
|
745
|
-
throw new Error("Governance integration not available");
|
|
746
|
-
}
|
|
747
|
-
// Build agent reviews from proposal evidence
|
|
748
|
-
const agentReviews = proposals.flatMap((p) => p.evidence.slice(0, 2).map((e) => `[${p.type}] ${e}`));
|
|
749
|
-
try {
|
|
750
|
-
const batchResult = await governanceIntegration.checkProposals(proposals, agentReviews, []);
|
|
751
|
-
const votes = batchResult.results.map((result) => ({
|
|
752
|
-
proposalId: result.governanceResponse.proposalId,
|
|
753
|
-
decision: result.vote.toLowerCase() === "yes" ? "approve" : "reject",
|
|
754
|
-
confidence: result.governanceResponse.confidence,
|
|
755
|
-
details: [
|
|
756
|
-
`Governance: ${result.governanceResponse.recommendation}`,
|
|
757
|
-
`Isotope: ${result.governanceResponse.governanceIsotopeId}`,
|
|
758
|
-
...result.governanceResponse.reasons.slice(0, 2),
|
|
759
|
-
],
|
|
760
|
-
}));
|
|
761
|
-
frameworkLogger.log("inference-cycle", "external-governance-complete", "info", {
|
|
762
|
-
proposalCount: proposals.length,
|
|
763
|
-
passedCount: batchResult.results.filter((r) => r.passed).length,
|
|
764
|
-
});
|
|
765
|
-
return votes;
|
|
766
|
-
}
|
|
767
|
-
catch (error) {
|
|
768
|
-
frameworkLogger.log("inference-cycle", "external-governance-failed", "error", {
|
|
769
|
-
error: error instanceof Error ? error.message : String(error),
|
|
770
|
-
});
|
|
771
|
-
return proposals.map((p) => this.rejectNoQuorum(p, "external governance endpoint failed"));
|
|
772
|
-
}
|
|
773
|
-
}
|
|
774
596
|
async invokeAgentInternal(agentName, prompt) {
|
|
775
597
|
frameworkLogger.log("inference-cycle", "invoke-agent-internal", "info", {
|
|
776
598
|
agentName,
|
|
@@ -921,13 +743,15 @@ Respond with EXACTLY one of:
|
|
|
921
743
|
if (!fs.existsSync(this.stateDir)) {
|
|
922
744
|
fs.mkdirSync(this.stateDir, { recursive: true });
|
|
923
745
|
}
|
|
924
|
-
const
|
|
746
|
+
const statePath = path.join(this.stateDir, CONSOLIDATED_STATE_FILE);
|
|
925
747
|
const stateManager = new XrayStateManager();
|
|
926
|
-
if (fs.existsSync(
|
|
748
|
+
if (fs.existsSync(statePath)) {
|
|
927
749
|
try {
|
|
928
|
-
const data = JSON.parse(fs.readFileSync(
|
|
929
|
-
|
|
930
|
-
|
|
750
|
+
const data = JSON.parse(fs.readFileSync(statePath, "utf-8"));
|
|
751
|
+
if (data.governanceState) {
|
|
752
|
+
for (const [key, value] of Object.entries(data.governanceState)) {
|
|
753
|
+
stateManager.set(key, value);
|
|
754
|
+
}
|
|
931
755
|
}
|
|
932
756
|
}
|
|
933
757
|
catch {
|
|
@@ -936,26 +760,6 @@ Respond with EXACTLY one of:
|
|
|
936
760
|
}
|
|
937
761
|
return stateManager;
|
|
938
762
|
}
|
|
939
|
-
saveGovernanceState(coordinator) {
|
|
940
|
-
const stateFile = path.join(this.stateDir, "governance-state.json");
|
|
941
|
-
try {
|
|
942
|
-
// Export the coordinator's internal state (voting history, metrics, etc.)
|
|
943
|
-
const history = coordinator.getVotingHistory();
|
|
944
|
-
const metrics = coordinator.getMetrics();
|
|
945
|
-
const exportData = {
|
|
946
|
-
votingHistory: history,
|
|
947
|
-
metrics,
|
|
948
|
-
exportedAt: new Date().toISOString(),
|
|
949
|
-
};
|
|
950
|
-
if (!fs.existsSync(this.stateDir)) {
|
|
951
|
-
fs.mkdirSync(this.stateDir, { recursive: true });
|
|
952
|
-
}
|
|
953
|
-
fs.writeFileSync(stateFile, JSON.stringify(exportData, null, 2));
|
|
954
|
-
}
|
|
955
|
-
catch (error) {
|
|
956
|
-
frameworkLogger.log("inference-cycle", "governance-state-save-failed", "warning", { error: String(error) });
|
|
957
|
-
}
|
|
958
|
-
}
|
|
959
763
|
extractTextFromNdjson(output) {
|
|
960
764
|
const texts = [];
|
|
961
765
|
for (const line of output.split("\n")) {
|
|
@@ -975,26 +779,9 @@ Respond with EXACTLY one of:
|
|
|
975
779
|
return texts.join("\n").trim();
|
|
976
780
|
}
|
|
977
781
|
resolveOpencodeRoot() {
|
|
978
|
-
// Use the provider-agnostic config path resolver (prefers .xray
|
|
782
|
+
// Use the provider-agnostic config path resolver (prefers .xray/ over legacy .opencode)
|
|
979
783
|
const configDir = getConfigDir(this.projectRoot);
|
|
980
|
-
|
|
981
|
-
if (configDir.includes(".xray") || configDir.includes("xray")) {
|
|
982
|
-
return path.dirname(configDir);
|
|
983
|
-
}
|
|
984
|
-
// Legacy fallback
|
|
985
|
-
let dir = this.projectRoot;
|
|
986
|
-
for (let i = 0; i < 10; i++) {
|
|
987
|
-
if (fs.existsSync(path.join(dir, ".opencode")))
|
|
988
|
-
return dir;
|
|
989
|
-
const parent = path.dirname(dir);
|
|
990
|
-
if (parent === dir)
|
|
991
|
-
break;
|
|
992
|
-
dir = parent;
|
|
993
|
-
}
|
|
994
|
-
const cwd = process.cwd();
|
|
995
|
-
if (fs.existsSync(path.join(cwd, ".opencode")))
|
|
996
|
-
return cwd;
|
|
997
|
-
return this.projectRoot;
|
|
784
|
+
return path.dirname(configDir);
|
|
998
785
|
}
|
|
999
786
|
rejectNoQuorum(proposal, reason) {
|
|
1000
787
|
return {
|
|
@@ -1062,37 +849,35 @@ Respond with EXACTLY one of:
|
|
|
1062
849
|
if (!fs.existsSync(this.stateDir)) {
|
|
1063
850
|
fs.mkdirSync(this.stateDir, { recursive: true });
|
|
1064
851
|
}
|
|
1065
|
-
|
|
852
|
+
const statePath = path.join(this.stateDir, CONSOLIDATED_STATE_FILE);
|
|
853
|
+
const existing = fs.existsSync(statePath) ? JSON.parse(fs.readFileSync(statePath, "utf-8")) : {};
|
|
854
|
+
existing.cycleState = {
|
|
1066
855
|
cycleId,
|
|
1067
856
|
completedAt: new Date().toISOString(),
|
|
1068
857
|
phase: this.phase,
|
|
1069
|
-
}
|
|
858
|
+
};
|
|
859
|
+
fs.writeFileSync(statePath, JSON.stringify(existing, null, 2));
|
|
1070
860
|
}
|
|
1071
861
|
appendHistory(result) {
|
|
1072
862
|
if (!fs.existsSync(this.stateDir)) {
|
|
1073
863
|
fs.mkdirSync(this.stateDir, { recursive: true });
|
|
1074
864
|
}
|
|
1075
|
-
const
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
try {
|
|
1079
|
-
history = JSON.parse(fs.readFileSync(historyPath, "utf-8"));
|
|
1080
|
-
}
|
|
1081
|
-
catch {
|
|
1082
|
-
history = [];
|
|
1083
|
-
}
|
|
1084
|
-
}
|
|
865
|
+
const statePath = path.join(this.stateDir, CONSOLIDATED_STATE_FILE);
|
|
866
|
+
const existing = fs.existsSync(statePath) ? JSON.parse(fs.readFileSync(statePath, "utf-8")) : {};
|
|
867
|
+
let history = existing.history || [];
|
|
1085
868
|
history.push(result);
|
|
1086
869
|
if (history.length > 50)
|
|
1087
870
|
history = history.slice(-50);
|
|
1088
|
-
|
|
871
|
+
existing.history = history;
|
|
872
|
+
fs.writeFileSync(statePath, JSON.stringify(existing, null, 2));
|
|
1089
873
|
}
|
|
1090
874
|
loadHistory() {
|
|
1091
|
-
const
|
|
1092
|
-
if (!fs.existsSync(
|
|
875
|
+
const statePath = path.join(this.stateDir, CONSOLIDATED_STATE_FILE);
|
|
876
|
+
if (!fs.existsSync(statePath))
|
|
1093
877
|
return [];
|
|
1094
878
|
try {
|
|
1095
|
-
|
|
879
|
+
const data = JSON.parse(fs.readFileSync(statePath, "utf-8"));
|
|
880
|
+
return data.history || [];
|
|
1096
881
|
}
|
|
1097
882
|
catch {
|
|
1098
883
|
return [];
|
|
@@ -16,7 +16,7 @@ function findGovernanceCore() {
|
|
|
16
16
|
const here = path.dirname(new URL(import.meta.url).pathname);
|
|
17
17
|
|
|
18
18
|
// Priority: explicit dev root
|
|
19
|
-
const devRoot = ;
|
|
19
|
+
const devRoot = process.env.XRAY_DEV_ROOT || '';
|
|
20
20
|
if (devRoot) {
|
|
21
21
|
const devCandidate = path.resolve(devRoot, 'dist/governance/governance-core.js');
|
|
22
22
|
if (fs.existsSync(devCandidate)) return devCandidate;
|
|
@@ -92,23 +92,9 @@ async function main() {
|
|
|
92
92
|
let govDetails = null;
|
|
93
93
|
|
|
94
94
|
if (corePath) {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
const result = core.applyDecisionMatrix({
|
|
99
|
-
resonance,
|
|
100
|
-
isotopicRatio: resonance > 0.8 ? 0.96 : 0.7,
|
|
101
|
-
vortexVolume: 1_000_000,
|
|
102
|
-
historicalCoherence: 0.82,
|
|
103
|
-
solarActivity: 'active',
|
|
104
|
-
});
|
|
105
|
-
govDetails = result;
|
|
106
|
-
recommendation = result.recommendation || 'NEEDS_REVISION';
|
|
107
|
-
log(`Solar decision: ${recommendation} (resonance=${resonance.toFixed(2)})`);
|
|
108
|
-
}
|
|
109
|
-
} catch (e) {
|
|
110
|
-
log(`Governance core error: ${e.message}`);
|
|
111
|
-
}
|
|
95
|
+
// Governance core no longer exposes the legacy PHI/TAU matrix (purged in v3).
|
|
96
|
+
// Resonance is still derived locally for logging/decision notes.
|
|
97
|
+
log(`Using local resonance derivation (core matrix purged)`);
|
|
112
98
|
} else {
|
|
113
99
|
log('Governance core not located — using safe default');
|
|
114
100
|
}
|
|
@@ -42,6 +42,15 @@ import { homedir } from "os";
|
|
|
42
42
|
|
|
43
43
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
44
44
|
|
|
45
|
+
// Redirect console methods to stderr so only the final JSON result goes to stdout.
|
|
46
|
+
// Any dynamically loaded module using console.log/info/debug/warn will then
|
|
47
|
+
// write diagnostic output to stderr, keeping stdout clean for JSON.parse.
|
|
48
|
+
const _stderrWrite = process.stderr.write.bind(process.stderr);
|
|
49
|
+
console.log = (...args) => { _stderrWrite(args.join(' ') + '\n'); };
|
|
50
|
+
console.info = (...args) => { _stderrWrite('[INFO] ' + args.join(' ') + '\n'); };
|
|
51
|
+
console.debug = (...args) => { _stderrWrite('[DEBUG] ' + args.join(' ') + '\n'); };
|
|
52
|
+
console.warn = (...args) => { _stderrWrite('[WARN] ' + args.join(' ') + '\n'); };
|
|
53
|
+
|
|
45
54
|
// ── Framework components (lazy-loaded) ───────────────────────
|
|
46
55
|
let ProcessorManager = null;
|
|
47
56
|
let StrRayStateManager = null;
|
|
@@ -160,7 +160,7 @@ export class ServerConfigRegistry {
|
|
|
160
160
|
this.register({
|
|
161
161
|
serverName: 'orchestrator',
|
|
162
162
|
command: 'node',
|
|
163
|
-
args: [`${basePath}/orchestrator
|
|
163
|
+
args: [`${basePath}/orchestrator/server.js`],
|
|
164
164
|
timeout: 60000,
|
|
165
165
|
});
|
|
166
166
|
// Estimation Validator Server
|