0xray 4.0.7 → 4.0.8
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/.xray/features.json +1 -1
- package/dist/CHANGELOG.md +12 -0
- package/dist/governance/llm-governance-provider.d.ts +1 -0
- package/dist/governance/llm-governance-provider.js +3 -0
- package/dist/governance/local-confer.d.ts +10 -0
- package/dist/governance/local-confer.js +27 -0
- package/dist/mcps/knowledge-skills/code-review.server.js +8 -13
- package/dist/mcps/knowledge-skills/security-audit.server.js +8 -13
- package/dist/mcps/researcher.server.js +10 -16
- package/package.json +1 -1
- package/scripts/foundry/release-gate.mjs +1 -1
- package/src/mcps/knowledge-skills/code-review.server.ts +18 -20
- package/src/mcps/knowledge-skills/security-audit.server.ts +18 -20
- package/src/mcps/researcher.server.ts +20 -24
- package/xray/features.json +1 -1
package/.xray/features.json
CHANGED
package/dist/CHANGELOG.md
CHANGED
|
@@ -34,6 +34,18 @@ The format is based on [Conventional Commits](https://www.conventionalcommits.or
|
|
|
34
34
|
|
|
35
35
|
---
|
|
36
36
|
|
|
37
|
+
## [4.0.8] - 2026-09-11
|
|
38
|
+
|
|
39
|
+
### 🔄 Changes
|
|
40
|
+
|
|
41
|
+
### 🔎 Other Changes
|
|
42
|
+
- fix(foundry): mill release gate uses test:comprehensive like mill CI (bd980ea3f)
|
|
43
|
+
- fix(confer): allow undefined on optional local vote fields (e4436af8f)
|
|
44
|
+
- fix(confer): abstain locally; do not rubber-stamp analyze_proposal (0f6c61cbe)
|
|
45
|
+
- fix(confer): local vote when nested LLM is not configured (eb6004b07)
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
37
49
|
## [4.0.7] - 2026-09-09
|
|
38
50
|
|
|
39
51
|
Nested mill **0.1.9**. Inventory writes `dna` (keccak256 of canonical JSON without `mintedAt`). Inspect echoes dna + pack `0xray-suit`. Mill does not mint on chain. Not 5.0.0.
|
|
@@ -5,6 +5,7 @@ export interface GovernanceVote {
|
|
|
5
5
|
reasoning: string;
|
|
6
6
|
}
|
|
7
7
|
export declare function resolveHermesBin(): string;
|
|
8
|
+
export declare function isGovernanceLlmConfigured(): boolean;
|
|
8
9
|
export declare function hermesCliAvailable(): boolean;
|
|
9
10
|
export declare function tryLLMGovernance(role: GovernanceRole, proposalTitle: string, proposalDescription: string, evidence: string[], proposalType: string): Promise<GovernanceVote | null>;
|
|
10
11
|
export declare function checkHermesOAuthStatus(): {
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { GovernanceRole, GovernanceVote } from "./llm-governance-provider.js";
|
|
2
|
+
export type LocalConferInput = {
|
|
3
|
+
role: GovernanceRole;
|
|
4
|
+
highConfidenceTrapPresent?: boolean | undefined;
|
|
5
|
+
recommendedAgent?: string | null | undefined;
|
|
6
|
+
llmConfigured?: boolean | undefined;
|
|
7
|
+
};
|
|
8
|
+
/** Receipt when nested LLM is absent or returned no vote. Never approve — analyze_proposal feeds mergeVotes. */
|
|
9
|
+
export declare function localConferVote(input: LocalConferInput): GovernanceVote;
|
|
10
|
+
export declare function formatGovernanceVoteText(vote: GovernanceVote, extra?: string): string;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/** Receipt when nested LLM is absent or returned no vote. Never approve — analyze_proposal feeds mergeVotes. */
|
|
2
|
+
export function localConferVote(input) {
|
|
3
|
+
const role = input.role;
|
|
4
|
+
if (input.llmConfigured) {
|
|
5
|
+
return {
|
|
6
|
+
decision: "abstain",
|
|
7
|
+
confidence: 0.5,
|
|
8
|
+
reasoning: `Local confer (${role}); nested LLM configured but returned no vote.`,
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
if (input.highConfidenceTrapPresent) {
|
|
12
|
+
const agent = input.recommendedAgent?.trim() || "architect";
|
|
13
|
+
return {
|
|
14
|
+
decision: "abstain",
|
|
15
|
+
confidence: 0.62,
|
|
16
|
+
reasoning: `Local confer (${role}); nested LLM not configured. Repertoire high-confidence ontological trap — route to ${agent} before implementation.`,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
return {
|
|
20
|
+
decision: "abstain",
|
|
21
|
+
confidence: 0.58,
|
|
22
|
+
reasoning: `Local confer (${role}); nested LLM not configured.`,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
export function formatGovernanceVoteText(vote, extra = "") {
|
|
26
|
+
return `DECISION: ${vote.decision}\nCONFIDENCE: ${vote.confidence.toFixed(2)}\nREASONING: ${vote.reasoning}${extra}`;
|
|
27
|
+
}
|
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
import { XrayKnowledgeSkillBase } from "../shared/knowledge-skill-base.js";
|
|
8
8
|
import * as fs from "fs";
|
|
9
9
|
import * as path from "path";
|
|
10
|
-
import { tryLLMGovernance } from "../../governance/llm-governance-provider.js";
|
|
10
|
+
import { isGovernanceLlmConfigured, tryLLMGovernance, } from "../../governance/llm-governance-provider.js";
|
|
11
|
+
import { formatGovernanceVoteText, localConferVote } from "../../governance/local-confer.js";
|
|
11
12
|
class XrayCodeReviewServer extends XrayKnowledgeSkillBase {
|
|
12
13
|
constructor() {
|
|
13
14
|
super("code-review", "3.1.0");
|
|
@@ -315,22 +316,16 @@ class XrayCodeReviewServer extends XrayKnowledgeSkillBase {
|
|
|
315
316
|
*/
|
|
316
317
|
async analyzeProposal(args) {
|
|
317
318
|
const { proposalTitle = "", proposalDescription = "", evidence = [], proposalType = "" } = args;
|
|
318
|
-
const vote = await tryLLMGovernance("code-review", proposalTitle, proposalDescription, evidence, proposalType)
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
type: "text",
|
|
324
|
-
text: "DECISION: abstain\nCONFIDENCE: 0.50\nREASONING: No LLM governance provider configured. Install Hermes on PATH (hermes -z) with xai-oauth, or set XRAY_GOVERNANCE_LLM_ENABLED=true + XRAY_LLM_ENDPOINT.",
|
|
325
|
-
},
|
|
326
|
-
],
|
|
327
|
-
};
|
|
328
|
-
}
|
|
319
|
+
const vote = (await tryLLMGovernance("code-review", proposalTitle, proposalDescription, evidence, proposalType)) ??
|
|
320
|
+
localConferVote({
|
|
321
|
+
role: "code-review",
|
|
322
|
+
llmConfigured: isGovernanceLlmConfigured(),
|
|
323
|
+
});
|
|
329
324
|
return {
|
|
330
325
|
content: [
|
|
331
326
|
{
|
|
332
327
|
type: "text",
|
|
333
|
-
text:
|
|
328
|
+
text: formatGovernanceVoteText(vote),
|
|
334
329
|
},
|
|
335
330
|
],
|
|
336
331
|
};
|
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
import * as fs from "fs";
|
|
8
8
|
import * as path from "path";
|
|
9
9
|
import { XrayKnowledgeSkillBase } from "../shared/knowledge-skill-base.js";
|
|
10
|
-
import { tryLLMGovernance } from "../../governance/llm-governance-provider.js";
|
|
10
|
+
import { isGovernanceLlmConfigured, tryLLMGovernance, } from "../../governance/llm-governance-provider.js";
|
|
11
|
+
import { formatGovernanceVoteText, localConferVote } from "../../governance/local-confer.js";
|
|
11
12
|
class XraySecurityAuditServer extends XrayKnowledgeSkillBase {
|
|
12
13
|
constructor() {
|
|
13
14
|
super("security-audit", "3.1.0");
|
|
@@ -660,22 +661,16 @@ class XraySecurityAuditServer extends XrayKnowledgeSkillBase {
|
|
|
660
661
|
*/
|
|
661
662
|
async analyzeProposal(args) {
|
|
662
663
|
const { proposalTitle = "", proposalDescription = "", evidence = [], proposalType = "" } = args;
|
|
663
|
-
const vote = await tryLLMGovernance("security-audit", proposalTitle, proposalDescription, evidence, proposalType)
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
type: "text",
|
|
669
|
-
text: "DECISION: abstain\nCONFIDENCE: 0.50\nREASONING: No LLM governance provider configured. Install Hermes on PATH (hermes -z) with xai-oauth, or set XRAY_GOVERNANCE_LLM_ENABLED=true + XRAY_LLM_ENDPOINT.",
|
|
670
|
-
},
|
|
671
|
-
],
|
|
672
|
-
};
|
|
673
|
-
}
|
|
664
|
+
const vote = (await tryLLMGovernance("security-audit", proposalTitle, proposalDescription, evidence, proposalType)) ??
|
|
665
|
+
localConferVote({
|
|
666
|
+
role: "security-audit",
|
|
667
|
+
llmConfigured: isGovernanceLlmConfigured(),
|
|
668
|
+
});
|
|
674
669
|
return {
|
|
675
670
|
content: [
|
|
676
671
|
{
|
|
677
672
|
type: "text",
|
|
678
|
-
text:
|
|
673
|
+
text: formatGovernanceVoteText(vote),
|
|
679
674
|
},
|
|
680
675
|
],
|
|
681
676
|
};
|
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
import * as fs from "fs";
|
|
11
11
|
import * as path from "path";
|
|
12
12
|
import { frameworkLogger } from "../core/framework-logger.js";
|
|
13
|
-
import { tryLLMGovernance } from "../governance/llm-governance-provider.js";
|
|
13
|
+
import { isGovernanceLlmConfigured, tryLLMGovernance, } from "../governance/llm-governance-provider.js";
|
|
14
|
+
import { formatGovernanceVoteText, localConferVote } from "../governance/local-confer.js";
|
|
14
15
|
import { initializeMemoryRouting } from "../memory-routing/index.js";
|
|
15
16
|
import { buildMemoryRoutingEvidence, formatMemoryRoutingBlock, resolveResearcherMemoryContext, } from "./researcher-confidence.js";
|
|
16
17
|
import { XrayKnowledgeSkillBase } from "./shared/knowledge-skill-base.js";
|
|
@@ -390,28 +391,21 @@ class XrayLibrarianServer extends XrayKnowledgeSkillBase {
|
|
|
390
391
|
if (memoryContext?.confidence.highConfidenceTrapPresent) {
|
|
391
392
|
enrichedEvidence.push(...buildMemoryRoutingEvidence(memoryContext));
|
|
392
393
|
}
|
|
393
|
-
const vote = await tryLLMGovernance("researcher", proposalTitle || "", proposalDescription || "", enrichedEvidence, proposalType || "")
|
|
394
|
+
const vote = (await tryLLMGovernance("researcher", proposalTitle || "", proposalDescription || "", enrichedEvidence, proposalType || "")) ??
|
|
395
|
+
localConferVote({
|
|
396
|
+
role: "researcher",
|
|
397
|
+
llmConfigured: isGovernanceLlmConfigured(),
|
|
398
|
+
highConfidenceTrapPresent: memoryContext?.confidence.highConfidenceTrapPresent,
|
|
399
|
+
recommendedAgent: memoryContext?.recommendedAgent,
|
|
400
|
+
});
|
|
394
401
|
const memoryRoutingBlock = memoryContext?.confidence.highConfidenceTrapPresent
|
|
395
402
|
? `\n${formatMemoryRoutingBlock(memoryContext)}`
|
|
396
403
|
: "";
|
|
397
|
-
if (!vote) {
|
|
398
|
-
const abstainReason = memoryContext?.confidence.highConfidenceTrapPresent
|
|
399
|
-
? "No LLM governance provider configured. Repertoire detected a high-confidence ontological trap — route to the recommended agent before proceeding."
|
|
400
|
-
: "No LLM governance provider configured. Install Hermes on PATH (hermes -z) with xai-oauth, or set XRAY_GOVERNANCE_LLM_ENABLED=true + XRAY_LLM_ENDPOINT.";
|
|
401
|
-
return {
|
|
402
|
-
content: [
|
|
403
|
-
{
|
|
404
|
-
type: "text",
|
|
405
|
-
text: `DECISION: abstain\nCONFIDENCE: 0.50\nREASONING: ${abstainReason}${memoryRoutingBlock}`,
|
|
406
|
-
},
|
|
407
|
-
],
|
|
408
|
-
};
|
|
409
|
-
}
|
|
410
404
|
return {
|
|
411
405
|
content: [
|
|
412
406
|
{
|
|
413
407
|
type: "text",
|
|
414
|
-
text:
|
|
408
|
+
text: formatGovernanceVoteText(vote, memoryRoutingBlock),
|
|
415
409
|
},
|
|
416
410
|
],
|
|
417
411
|
};
|
package/package.json
CHANGED
|
@@ -9,7 +9,11 @@ import { XrayKnowledgeSkillBase } from "../shared/knowledge-skill-base.js";
|
|
|
9
9
|
import * as fs from "fs";
|
|
10
10
|
import * as path from "path";
|
|
11
11
|
import { createGracefulShutdown } from "../../utils/shutdown-handler.js";
|
|
12
|
-
import {
|
|
12
|
+
import {
|
|
13
|
+
isGovernanceLlmConfigured,
|
|
14
|
+
tryLLMGovernance,
|
|
15
|
+
} from "../../governance/llm-governance-provider.js";
|
|
16
|
+
import { formatGovernanceVoteText, localConferVote } from "../../governance/local-confer.js";
|
|
13
17
|
|
|
14
18
|
interface CodeReviewResult {
|
|
15
19
|
file: string;
|
|
@@ -435,30 +439,24 @@ class XrayCodeReviewServer extends XrayKnowledgeSkillBase {
|
|
|
435
439
|
async analyzeProposal(args: AnalyzeProposalArgs) {
|
|
436
440
|
const { proposalTitle = "", proposalDescription = "", evidence = [], proposalType = "" } = args;
|
|
437
441
|
|
|
438
|
-
const vote =
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
type: "text",
|
|
451
|
-
text: "DECISION: abstain\nCONFIDENCE: 0.50\nREASONING: No LLM governance provider configured. Install Hermes on PATH (hermes -z) with xai-oauth, or set XRAY_GOVERNANCE_LLM_ENABLED=true + XRAY_LLM_ENDPOINT.",
|
|
452
|
-
},
|
|
453
|
-
],
|
|
454
|
-
};
|
|
455
|
-
}
|
|
442
|
+
const vote =
|
|
443
|
+
(await tryLLMGovernance(
|
|
444
|
+
"code-review",
|
|
445
|
+
proposalTitle,
|
|
446
|
+
proposalDescription,
|
|
447
|
+
evidence,
|
|
448
|
+
proposalType,
|
|
449
|
+
)) ??
|
|
450
|
+
localConferVote({
|
|
451
|
+
role: "code-review",
|
|
452
|
+
llmConfigured: isGovernanceLlmConfigured(),
|
|
453
|
+
});
|
|
456
454
|
|
|
457
455
|
return {
|
|
458
456
|
content: [
|
|
459
457
|
{
|
|
460
458
|
type: "text",
|
|
461
|
-
text:
|
|
459
|
+
text: formatGovernanceVoteText(vote),
|
|
462
460
|
},
|
|
463
461
|
],
|
|
464
462
|
};
|
|
@@ -8,7 +8,11 @@
|
|
|
8
8
|
import * as fs from "fs";
|
|
9
9
|
import * as path from "path";
|
|
10
10
|
import { XrayKnowledgeSkillBase } from "../shared/knowledge-skill-base.js";
|
|
11
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
isGovernanceLlmConfigured,
|
|
13
|
+
tryLLMGovernance,
|
|
14
|
+
} from "../../governance/llm-governance-provider.js";
|
|
15
|
+
import { formatGovernanceVoteText, localConferVote } from "../../governance/local-confer.js";
|
|
12
16
|
|
|
13
17
|
interface SecurityVulnerability {
|
|
14
18
|
id: string;
|
|
@@ -995,30 +999,24 @@ class XraySecurityAuditServer extends XrayKnowledgeSkillBase {
|
|
|
995
999
|
async analyzeProposal(args: AnalyzeProposalArgs) {
|
|
996
1000
|
const { proposalTitle = "", proposalDescription = "", evidence = [], proposalType = "" } = args;
|
|
997
1001
|
|
|
998
|
-
const vote =
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
type: "text",
|
|
1011
|
-
text: "DECISION: abstain\nCONFIDENCE: 0.50\nREASONING: No LLM governance provider configured. Install Hermes on PATH (hermes -z) with xai-oauth, or set XRAY_GOVERNANCE_LLM_ENABLED=true + XRAY_LLM_ENDPOINT.",
|
|
1012
|
-
},
|
|
1013
|
-
],
|
|
1014
|
-
};
|
|
1015
|
-
}
|
|
1002
|
+
const vote =
|
|
1003
|
+
(await tryLLMGovernance(
|
|
1004
|
+
"security-audit",
|
|
1005
|
+
proposalTitle,
|
|
1006
|
+
proposalDescription,
|
|
1007
|
+
evidence,
|
|
1008
|
+
proposalType,
|
|
1009
|
+
)) ??
|
|
1010
|
+
localConferVote({
|
|
1011
|
+
role: "security-audit",
|
|
1012
|
+
llmConfigured: isGovernanceLlmConfigured(),
|
|
1013
|
+
});
|
|
1016
1014
|
|
|
1017
1015
|
return {
|
|
1018
1016
|
content: [
|
|
1019
1017
|
{
|
|
1020
1018
|
type: "text",
|
|
1021
|
-
text:
|
|
1019
|
+
text: formatGovernanceVoteText(vote),
|
|
1022
1020
|
},
|
|
1023
1021
|
],
|
|
1024
1022
|
};
|
|
@@ -12,7 +12,11 @@ import { type CallToolResult } from "@modelcontextprotocol/sdk/types.js";
|
|
|
12
12
|
import * as fs from "fs";
|
|
13
13
|
import * as path from "path";
|
|
14
14
|
import { frameworkLogger } from "../core/framework-logger.js";
|
|
15
|
-
import {
|
|
15
|
+
import {
|
|
16
|
+
isGovernanceLlmConfigured,
|
|
17
|
+
tryLLMGovernance,
|
|
18
|
+
} from "../governance/llm-governance-provider.js";
|
|
19
|
+
import { formatGovernanceVoteText, localConferVote } from "../governance/local-confer.js";
|
|
16
20
|
import { initializeMemoryRouting } from "../memory-routing/index.js";
|
|
17
21
|
import {
|
|
18
22
|
buildMemoryRoutingEvidence,
|
|
@@ -472,39 +476,31 @@ class XrayLibrarianServer extends XrayKnowledgeSkillBase {
|
|
|
472
476
|
enrichedEvidence.push(...buildMemoryRoutingEvidence(memoryContext));
|
|
473
477
|
}
|
|
474
478
|
|
|
475
|
-
const vote =
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
479
|
+
const vote =
|
|
480
|
+
(await tryLLMGovernance(
|
|
481
|
+
"researcher",
|
|
482
|
+
proposalTitle || "",
|
|
483
|
+
proposalDescription || "",
|
|
484
|
+
enrichedEvidence,
|
|
485
|
+
proposalType || "",
|
|
486
|
+
)) ??
|
|
487
|
+
localConferVote({
|
|
488
|
+
role: "researcher",
|
|
489
|
+
llmConfigured: isGovernanceLlmConfigured(),
|
|
490
|
+
highConfidenceTrapPresent: memoryContext?.confidence.highConfidenceTrapPresent,
|
|
491
|
+
recommendedAgent: memoryContext?.recommendedAgent,
|
|
492
|
+
});
|
|
482
493
|
|
|
483
494
|
const memoryRoutingBlock =
|
|
484
495
|
memoryContext?.confidence.highConfidenceTrapPresent
|
|
485
496
|
? `\n${formatMemoryRoutingBlock(memoryContext)}`
|
|
486
497
|
: "";
|
|
487
498
|
|
|
488
|
-
if (!vote) {
|
|
489
|
-
const abstainReason = memoryContext?.confidence.highConfidenceTrapPresent
|
|
490
|
-
? "No LLM governance provider configured. Repertoire detected a high-confidence ontological trap — route to the recommended agent before proceeding."
|
|
491
|
-
: "No LLM governance provider configured. Install Hermes on PATH (hermes -z) with xai-oauth, or set XRAY_GOVERNANCE_LLM_ENABLED=true + XRAY_LLM_ENDPOINT.";
|
|
492
|
-
|
|
493
|
-
return {
|
|
494
|
-
content: [
|
|
495
|
-
{
|
|
496
|
-
type: "text",
|
|
497
|
-
text: `DECISION: abstain\nCONFIDENCE: 0.50\nREASONING: ${abstainReason}${memoryRoutingBlock}`,
|
|
498
|
-
},
|
|
499
|
-
],
|
|
500
|
-
};
|
|
501
|
-
}
|
|
502
|
-
|
|
503
499
|
return {
|
|
504
500
|
content: [
|
|
505
501
|
{
|
|
506
502
|
type: "text",
|
|
507
|
-
text:
|
|
503
|
+
text: formatGovernanceVoteText(vote, memoryRoutingBlock),
|
|
508
504
|
},
|
|
509
505
|
],
|
|
510
506
|
};
|