@neuroverseos/governance 0.3.1 → 0.3.3
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/.well-known/ai-plugin.json +34 -9
- package/AGENTS.md +72 -24
- package/README.md +343 -248
- package/dist/adapters/autoresearch.cjs +1345 -0
- package/dist/adapters/autoresearch.d.cts +111 -0
- package/dist/adapters/autoresearch.d.ts +111 -0
- package/dist/adapters/autoresearch.js +12 -0
- package/dist/adapters/deep-agents.cjs +1528 -0
- package/dist/adapters/deep-agents.d.cts +181 -0
- package/dist/adapters/deep-agents.d.ts +181 -0
- package/dist/adapters/deep-agents.js +17 -0
- package/dist/adapters/express.cjs +1253 -0
- package/dist/adapters/express.d.cts +66 -0
- package/dist/adapters/express.d.ts +66 -0
- package/dist/adapters/express.js +12 -0
- package/dist/adapters/index.cjs +2112 -0
- package/dist/adapters/index.d.cts +8 -0
- package/dist/adapters/index.d.ts +8 -0
- package/dist/adapters/index.js +68 -0
- package/dist/adapters/langchain.cjs +1315 -0
- package/dist/adapters/langchain.d.cts +89 -0
- package/dist/adapters/langchain.d.ts +89 -0
- package/dist/adapters/langchain.js +17 -0
- package/dist/adapters/openai.cjs +1345 -0
- package/dist/adapters/openai.d.cts +99 -0
- package/dist/adapters/openai.d.ts +99 -0
- package/dist/adapters/openai.js +17 -0
- package/dist/adapters/openclaw.cjs +1337 -0
- package/dist/adapters/openclaw.d.cts +99 -0
- package/dist/adapters/openclaw.d.ts +99 -0
- package/dist/adapters/openclaw.js +17 -0
- package/dist/add-ROOZLU62.js +314 -0
- package/dist/behavioral-MJO34S6Q.js +118 -0
- package/dist/bootstrap-CQRZVOXK.js +116 -0
- package/dist/bootstrap-emitter-Q7UIJZ2O.js +7 -0
- package/dist/bootstrap-parser-EEF36XDU.js +7 -0
- package/dist/browser.global.js +941 -0
- package/dist/build-QKOBBC23.js +341 -0
- package/dist/chunk-3WQLXYTP.js +91 -0
- package/dist/chunk-4FLICVVA.js +119 -0
- package/dist/chunk-4NGDRRQH.js +10 -0
- package/dist/chunk-5TPFNWRU.js +215 -0
- package/dist/chunk-5U2MQO5P.js +57 -0
- package/dist/chunk-6CZSKEY5.js +164 -0
- package/dist/chunk-6S5CFQXY.js +624 -0
- package/dist/chunk-7P3S7MAY.js +1090 -0
- package/dist/chunk-A5W4GNQO.js +130 -0
- package/dist/chunk-A7GKPPU7.js +226 -0
- package/dist/chunk-AKW5YVCE.js +96 -0
- package/dist/chunk-B6OXJLJ5.js +622 -0
- package/dist/chunk-BNKJPUPQ.js +113 -0
- package/dist/chunk-BQZMOEML.js +43 -0
- package/dist/chunk-CNSO6XW5.js +207 -0
- package/dist/chunk-CTZHONLA.js +135 -0
- package/dist/chunk-D2UCV5AK.js +326 -0
- package/dist/chunk-EMQDLDAF.js +458 -0
- package/dist/chunk-F66BVUYB.js +340 -0
- package/dist/chunk-G7DJ6VOD.js +101 -0
- package/dist/chunk-I3RRAYK2.js +11 -0
- package/dist/chunk-IS4WUH6Y.js +363 -0
- package/dist/chunk-MH7BT4VH.js +15 -0
- package/dist/chunk-O5ABKEA7.js +304 -0
- package/dist/chunk-OT6PXH54.js +61 -0
- package/dist/chunk-PVTQQS3Y.js +186 -0
- package/dist/chunk-Q6O7ZLO2.js +62 -0
- package/dist/chunk-QLPTHTVB.js +253 -0
- package/dist/chunk-QWGCMQQD.js +16 -0
- package/dist/chunk-QXBFT7NI.js +201 -0
- package/dist/chunk-TG6SEF24.js +246 -0
- package/dist/chunk-U6U7EJZL.js +177 -0
- package/dist/chunk-W7LLXRGY.js +830 -0
- package/dist/chunk-ZJTDUCC2.js +194 -0
- package/dist/chunk-ZWI3NIXK.js +314 -0
- package/dist/cli/neuroverse.cjs +14191 -0
- package/dist/cli/neuroverse.d.cts +1 -0
- package/dist/cli/neuroverse.d.ts +1 -0
- package/dist/cli/neuroverse.js +227 -0
- package/dist/cli/plan.cjs +2439 -0
- package/dist/cli/plan.d.cts +20 -0
- package/dist/cli/plan.d.ts +20 -0
- package/dist/cli/plan.js +353 -0
- package/dist/cli/run.cjs +2001 -0
- package/dist/cli/run.d.cts +20 -0
- package/dist/cli/run.d.ts +20 -0
- package/dist/cli/run.js +143 -0
- package/dist/configure-ai-6TZ3MCSI.js +132 -0
- package/dist/decision-flow-M63D47LO.js +61 -0
- package/dist/demo-G43RLCPK.js +469 -0
- package/dist/derive-FJZVIPUZ.js +153 -0
- package/dist/doctor-6BC6X2VO.js +173 -0
- package/dist/equity-penalties-SG5IZQ7I.js +244 -0
- package/dist/explain-RHBU2GBR.js +51 -0
- package/dist/guard-AJCCGZMF.js +92 -0
- package/dist/guard-contract-DqFcTScd.d.cts +821 -0
- package/dist/guard-contract-DqFcTScd.d.ts +821 -0
- package/dist/guard-engine-PNR6MHCM.js +10 -0
- package/dist/impact-3XVDSCBU.js +59 -0
- package/dist/improve-TQP4ECSY.js +66 -0
- package/dist/index.cjs +7591 -0
- package/dist/index.d.cts +2195 -0
- package/dist/index.d.ts +2195 -0
- package/dist/index.js +472 -0
- package/dist/infer-world-IFXCACJ5.js +543 -0
- package/dist/init-FYPV4SST.js +144 -0
- package/dist/init-world-TI7ARHBT.js +223 -0
- package/dist/mcp-server-5Y3ZM7TV.js +13 -0
- package/dist/model-adapter-VXEKB4LS.js +11 -0
- package/dist/playground-VZBNPPBO.js +560 -0
- package/dist/redteam-MZPZD3EF.js +357 -0
- package/dist/session-JYOARW54.js +15 -0
- package/dist/shared-7RLUHNMU.js +16 -0
- package/dist/shared-B8dvUUD8.d.cts +60 -0
- package/dist/shared-Dr5Wiay8.d.ts +60 -0
- package/dist/simulate-LJXYBC6M.js +83 -0
- package/dist/test-BOOR4A5F.js +217 -0
- package/dist/trace-PKV4KX56.js +166 -0
- package/dist/validate-RALX7CZS.js +81 -0
- package/dist/validate-engine-7ZXFVGF2.js +7 -0
- package/dist/viz/assets/index-B8SaeJZZ.js +23 -0
- package/dist/viz/index.html +23 -0
- package/dist/world-BIP4GZBZ.js +376 -0
- package/dist/world-loader-Y6HMQH2D.js +13 -0
- package/dist/worlds/autoresearch.nv-world.md +230 -0
- package/dist/worlds/coding-agent.nv-world.md +211 -0
- package/dist/worlds/derivation-world.nv-world.md +278 -0
- package/dist/worlds/research-agent.nv-world.md +169 -0
- package/dist/worlds/social-media.nv-world.md +198 -0
- package/dist/worlds/trading-agent.nv-world.md +218 -0
- package/examples/social-media-sim/bridge.py +209 -0
- package/examples/social-media-sim/simulation.py +927 -0
- package/package.json +16 -3
- package/simulate.html +4 -336
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import {
|
|
2
|
+
loadConfig
|
|
3
|
+
} from "./chunk-OT6PXH54.js";
|
|
4
|
+
import {
|
|
5
|
+
__glob
|
|
6
|
+
} from "./chunk-QWGCMQQD.js";
|
|
7
|
+
|
|
8
|
+
// import("../adapters/**/*") in src/cli/doctor.ts
|
|
9
|
+
var globImport_adapters = __glob({
|
|
10
|
+
"../adapters/autoresearch.ts": () => import("./adapters/autoresearch.js"),
|
|
11
|
+
"../adapters/deep-agents.ts": () => import("./adapters/deep-agents.js"),
|
|
12
|
+
"../adapters/express.ts": () => import("./adapters/express.js"),
|
|
13
|
+
"../adapters/index.ts": () => import("./adapters/index.js"),
|
|
14
|
+
"../adapters/langchain.ts": () => import("./adapters/langchain.js"),
|
|
15
|
+
"../adapters/openai.ts": () => import("./adapters/openai.js"),
|
|
16
|
+
"../adapters/openclaw.ts": () => import("./adapters/openclaw.js"),
|
|
17
|
+
"../adapters/shared.ts": () => import("./shared-7RLUHNMU.js")
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
// src/cli/doctor.ts
|
|
21
|
+
var PACKAGE_VERSION = "0.2.0";
|
|
22
|
+
var MIN_NODE_VERSION = 18;
|
|
23
|
+
async function main(argv) {
|
|
24
|
+
const json = argv.includes("--json");
|
|
25
|
+
let worldPath;
|
|
26
|
+
for (let i = 0; i < argv.length; i++) {
|
|
27
|
+
if (argv[i] === "--world" && i + 1 < argv.length) {
|
|
28
|
+
worldPath = argv[++i];
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
const checks = [];
|
|
32
|
+
const nodeVersion = process.version;
|
|
33
|
+
const major = parseInt(nodeVersion.slice(1), 10);
|
|
34
|
+
checks.push({
|
|
35
|
+
label: "Node version",
|
|
36
|
+
status: major >= MIN_NODE_VERSION ? "pass" : "fail",
|
|
37
|
+
value: nodeVersion,
|
|
38
|
+
detail: major < MIN_NODE_VERSION ? `Requires Node >= ${MIN_NODE_VERSION}` : void 0
|
|
39
|
+
});
|
|
40
|
+
checks.push({
|
|
41
|
+
label: "NeuroVerse version",
|
|
42
|
+
status: "pass",
|
|
43
|
+
value: PACKAGE_VERSION
|
|
44
|
+
});
|
|
45
|
+
try {
|
|
46
|
+
const config = await loadConfig();
|
|
47
|
+
if (config?.provider && config?.apiKey) {
|
|
48
|
+
checks.push({
|
|
49
|
+
label: "AI provider configured",
|
|
50
|
+
status: "pass",
|
|
51
|
+
value: `${config.provider}${config.model ? ` (${config.model})` : ""}`
|
|
52
|
+
});
|
|
53
|
+
} else {
|
|
54
|
+
checks.push({
|
|
55
|
+
label: "AI provider configured",
|
|
56
|
+
status: "warn",
|
|
57
|
+
value: "not configured",
|
|
58
|
+
detail: "Run: neuroverse configure-ai --provider openai --model gpt-4.1-mini --api-key <key>"
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
} catch {
|
|
62
|
+
checks.push({
|
|
63
|
+
label: "AI provider configured",
|
|
64
|
+
status: "warn",
|
|
65
|
+
value: "not configured",
|
|
66
|
+
detail: "Run: neuroverse configure-ai"
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
if (worldPath) {
|
|
70
|
+
try {
|
|
71
|
+
const { existsSync } = await import("fs");
|
|
72
|
+
const { join } = await import("path");
|
|
73
|
+
const hasWorld = existsSync(join(worldPath, "world.json"));
|
|
74
|
+
checks.push({
|
|
75
|
+
label: "World file detected",
|
|
76
|
+
status: hasWorld ? "pass" : "fail",
|
|
77
|
+
value: hasWorld ? worldPath : "not found",
|
|
78
|
+
detail: hasWorld ? void 0 : `No world.json found in ${worldPath}`
|
|
79
|
+
});
|
|
80
|
+
} catch {
|
|
81
|
+
checks.push({
|
|
82
|
+
label: "World file detected",
|
|
83
|
+
status: "fail",
|
|
84
|
+
value: "error reading path"
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
} else {
|
|
88
|
+
const { existsSync } = await import("fs");
|
|
89
|
+
const { join } = await import("path");
|
|
90
|
+
const candidates = ["./world", "./.neuroverse", "./worlds"];
|
|
91
|
+
let found;
|
|
92
|
+
for (const dir of candidates) {
|
|
93
|
+
if (existsSync(join(dir, "world.json"))) {
|
|
94
|
+
found = dir;
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
checks.push({
|
|
99
|
+
label: "World file detected",
|
|
100
|
+
status: found ? "pass" : "warn",
|
|
101
|
+
value: found ?? "none found",
|
|
102
|
+
detail: found ? void 0 : "Build a world: neuroverse build <input.md>"
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
try {
|
|
106
|
+
const { evaluateGuard } = await import("./guard-engine-PNR6MHCM.js");
|
|
107
|
+
checks.push({
|
|
108
|
+
label: "Guard engine",
|
|
109
|
+
status: typeof evaluateGuard === "function" ? "pass" : "fail",
|
|
110
|
+
value: "loaded"
|
|
111
|
+
});
|
|
112
|
+
} catch {
|
|
113
|
+
checks.push({ label: "Guard engine", status: "fail", value: "failed to load" });
|
|
114
|
+
}
|
|
115
|
+
try {
|
|
116
|
+
const { validateWorld } = await import("./validate-engine-7ZXFVGF2.js");
|
|
117
|
+
checks.push({
|
|
118
|
+
label: "Validation engine",
|
|
119
|
+
status: typeof validateWorld === "function" ? "pass" : "fail",
|
|
120
|
+
value: "loaded"
|
|
121
|
+
});
|
|
122
|
+
} catch {
|
|
123
|
+
checks.push({ label: "Validation engine", status: "fail", value: "failed to load" });
|
|
124
|
+
}
|
|
125
|
+
const adapterNames = ["openai", "express", "langchain", "openclaw"];
|
|
126
|
+
const loadedAdapters = [];
|
|
127
|
+
for (const name of adapterNames) {
|
|
128
|
+
try {
|
|
129
|
+
await globImport_adapters(`../adapters/${name}`);
|
|
130
|
+
loadedAdapters.push(name);
|
|
131
|
+
} catch {
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
checks.push({
|
|
135
|
+
label: "Adapters",
|
|
136
|
+
status: loadedAdapters.length > 0 ? "pass" : "warn",
|
|
137
|
+
value: loadedAdapters.length > 0 ? loadedAdapters.join(", ") : "none"
|
|
138
|
+
});
|
|
139
|
+
if (json) {
|
|
140
|
+
const hasFailure2 = checks.some((c) => c.status === "fail");
|
|
141
|
+
process.stdout.write(JSON.stringify({
|
|
142
|
+
status: hasFailure2 ? "fail" : "pass",
|
|
143
|
+
checks
|
|
144
|
+
}, null, 2) + "\n");
|
|
145
|
+
process.exit(hasFailure2 ? 1 : 0);
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
process.stderr.write("\nNeuroVerse Environment Check\n");
|
|
149
|
+
process.stderr.write("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n");
|
|
150
|
+
const maxLabel = Math.max(...checks.map((c) => c.label.length));
|
|
151
|
+
for (const check of checks) {
|
|
152
|
+
const icon = check.status === "pass" ? "ok" : check.status === "warn" ? "!!" : "FAIL";
|
|
153
|
+
const pad = " ".repeat(maxLabel - check.label.length);
|
|
154
|
+
process.stderr.write(` ${check.label}${pad} ${icon} ${check.value}
|
|
155
|
+
`);
|
|
156
|
+
if (check.detail) {
|
|
157
|
+
process.stderr.write(` ${" ".repeat(maxLabel)} ${check.detail}
|
|
158
|
+
`);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
const hasFailure = checks.some((c) => c.status === "fail");
|
|
162
|
+
process.stderr.write("\n");
|
|
163
|
+
if (hasFailure) {
|
|
164
|
+
process.stderr.write("Some checks failed. Fix the issues above and re-run.\n");
|
|
165
|
+
} else {
|
|
166
|
+
process.stderr.write("System ready.\n");
|
|
167
|
+
}
|
|
168
|
+
process.stderr.write("\n");
|
|
169
|
+
process.exit(hasFailure ? 1 : 0);
|
|
170
|
+
}
|
|
171
|
+
export {
|
|
172
|
+
main
|
|
173
|
+
};
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import {
|
|
2
|
+
verdictToAuditEvent
|
|
3
|
+
} from "./chunk-A7GKPPU7.js";
|
|
4
|
+
import {
|
|
5
|
+
applyConsequence,
|
|
6
|
+
applyReward,
|
|
7
|
+
createAgentState,
|
|
8
|
+
generateDecisionFlow,
|
|
9
|
+
renderDecisionFlow,
|
|
10
|
+
tickAgentStates
|
|
11
|
+
} from "./chunk-D2UCV5AK.js";
|
|
12
|
+
import {
|
|
13
|
+
evaluateGuard
|
|
14
|
+
} from "./chunk-W7LLXRGY.js";
|
|
15
|
+
import "./chunk-QLPTHTVB.js";
|
|
16
|
+
import {
|
|
17
|
+
loadWorld
|
|
18
|
+
} from "./chunk-CTZHONLA.js";
|
|
19
|
+
import "./chunk-QWGCMQQD.js";
|
|
20
|
+
|
|
21
|
+
// src/cli/equity-penalties.ts
|
|
22
|
+
var AGENTS = [
|
|
23
|
+
{ id: "alpha", name: "Alpha Fund", strategy: "aggressive" },
|
|
24
|
+
{ id: "beta", name: "Beta Holdings", strategy: "conservative" },
|
|
25
|
+
{ id: "gamma", name: "Gamma Capital", strategy: "balanced" },
|
|
26
|
+
{ id: "delta", name: "Delta Quant", strategy: "aggressive" },
|
|
27
|
+
{ id: "epsilon", name: "Epsilon Value", strategy: "conservative" },
|
|
28
|
+
{ id: "zeta", name: "Zeta Momentum", strategy: "aggressive" },
|
|
29
|
+
{ id: "eta", name: "Eta Growth", strategy: "balanced" },
|
|
30
|
+
{ id: "theta", name: "Theta Macro", strategy: "conservative" }
|
|
31
|
+
];
|
|
32
|
+
function generateActionsForRound(agents, round) {
|
|
33
|
+
const actions = [];
|
|
34
|
+
for (const agent of agents) {
|
|
35
|
+
if (agent.strategy === "aggressive") {
|
|
36
|
+
if (round % 2 === 0) {
|
|
37
|
+
actions.push({
|
|
38
|
+
intent: `sell Fortune 500 equity AAPL position for ${agent.name}`,
|
|
39
|
+
tool: "trade",
|
|
40
|
+
roleId: agent.id,
|
|
41
|
+
actionCategory: "write"
|
|
42
|
+
});
|
|
43
|
+
} else {
|
|
44
|
+
actions.push({
|
|
45
|
+
intent: `sell Fortune 500 equity MSFT shares for ${agent.name}`,
|
|
46
|
+
tool: "trade",
|
|
47
|
+
roleId: agent.id,
|
|
48
|
+
actionCategory: "write"
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
if (agent.strategy === "conservative") {
|
|
53
|
+
actions.push({
|
|
54
|
+
intent: `hold current position during market volatility for ${agent.name}`,
|
|
55
|
+
tool: "trade",
|
|
56
|
+
roleId: agent.id,
|
|
57
|
+
actionCategory: "read"
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
if (agent.strategy === "balanced") {
|
|
61
|
+
if (round % 3 === 0) {
|
|
62
|
+
actions.push({
|
|
63
|
+
intent: `sell Fortune 500 equity GOOGL for ${agent.name}`,
|
|
64
|
+
tool: "trade",
|
|
65
|
+
roleId: agent.id,
|
|
66
|
+
actionCategory: "write"
|
|
67
|
+
});
|
|
68
|
+
} else if (round % 3 === 1) {
|
|
69
|
+
actions.push({
|
|
70
|
+
intent: `buy non-F500 small cap equity for ${agent.name}`,
|
|
71
|
+
tool: "trade",
|
|
72
|
+
roleId: agent.id,
|
|
73
|
+
actionCategory: "write"
|
|
74
|
+
});
|
|
75
|
+
} else {
|
|
76
|
+
actions.push({
|
|
77
|
+
intent: `hold position during volatility for ${agent.name}`,
|
|
78
|
+
tool: "trade",
|
|
79
|
+
roleId: agent.id,
|
|
80
|
+
actionCategory: "read"
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return actions;
|
|
86
|
+
}
|
|
87
|
+
async function main(args) {
|
|
88
|
+
let worldPath = "";
|
|
89
|
+
let agentCount = 8;
|
|
90
|
+
let rounds = 5;
|
|
91
|
+
let jsonOutput = false;
|
|
92
|
+
for (let i = 0; i < args.length; i++) {
|
|
93
|
+
if (args[i] === "--world" && args[i + 1]) {
|
|
94
|
+
worldPath = args[++i];
|
|
95
|
+
}
|
|
96
|
+
if (args[i] === "--agents" && args[i + 1]) {
|
|
97
|
+
agentCount = Math.min(parseInt(args[++i], 10), AGENTS.length);
|
|
98
|
+
}
|
|
99
|
+
if (args[i] === "--rounds" && args[i + 1]) {
|
|
100
|
+
rounds = parseInt(args[++i], 10);
|
|
101
|
+
}
|
|
102
|
+
if (args[i] === "--json") {
|
|
103
|
+
jsonOutput = true;
|
|
104
|
+
}
|
|
105
|
+
if (args[i] === "--help" || args[i] === "-h") {
|
|
106
|
+
process.stdout.write(`
|
|
107
|
+
neuroverse equity-penalties \u2014 Behavioral enforcement simulation
|
|
108
|
+
|
|
109
|
+
Usage:
|
|
110
|
+
neuroverse equity-penalties --world <dir> [--agents N] [--rounds N] [--json]
|
|
111
|
+
|
|
112
|
+
Options:
|
|
113
|
+
--world <dir> Path to world directory (required)
|
|
114
|
+
--agents N Number of agents (default: 8, max: 8)
|
|
115
|
+
--rounds N Number of simulation rounds (default: 5)
|
|
116
|
+
--json Output as JSON
|
|
117
|
+
|
|
118
|
+
Simulates Fortune 500 equity trading with PENALIZE/REWARD governance:
|
|
119
|
+
- SELL F500 equity \u2192 PENALIZED (agent frozen 1 round)
|
|
120
|
+
- HOLD during volatility \u2192 REWARDED (+10% influence)
|
|
121
|
+
- BUY non-F500 \u2192 ALLOWED
|
|
122
|
+
- Unauthorized actions \u2192 BLOCKED
|
|
123
|
+
`.trim() + "\n");
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
if (!worldPath) {
|
|
128
|
+
process.stderr.write("Error: --world <dir> is required\n");
|
|
129
|
+
process.exit(1);
|
|
130
|
+
}
|
|
131
|
+
let world;
|
|
132
|
+
try {
|
|
133
|
+
world = await loadWorld(worldPath);
|
|
134
|
+
} catch (e) {
|
|
135
|
+
process.stderr.write(`Error loading world: ${e}
|
|
136
|
+
`);
|
|
137
|
+
process.exit(1);
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
const agents = AGENTS.slice(0, agentCount);
|
|
141
|
+
let agentStates = /* @__PURE__ */ new Map();
|
|
142
|
+
for (const agent of agents) {
|
|
143
|
+
agentStates.set(agent.id, createAgentState(agent.id));
|
|
144
|
+
}
|
|
145
|
+
const allAuditEvents = [];
|
|
146
|
+
const engineOptions = {
|
|
147
|
+
trace: false,
|
|
148
|
+
level: "standard",
|
|
149
|
+
agentStates
|
|
150
|
+
};
|
|
151
|
+
process.stdout.write("\n");
|
|
152
|
+
process.stdout.write("EQUITY PENALTY SIMULATION\n");
|
|
153
|
+
process.stdout.write("\u2550".repeat(60) + "\n");
|
|
154
|
+
process.stdout.write(` World: ${world.world.name}
|
|
155
|
+
`);
|
|
156
|
+
process.stdout.write(` Agents: ${agents.length}
|
|
157
|
+
`);
|
|
158
|
+
process.stdout.write(` Rounds: ${rounds}
|
|
159
|
+
`);
|
|
160
|
+
process.stdout.write("\n");
|
|
161
|
+
for (let round = 0; round < rounds; round++) {
|
|
162
|
+
process.stdout.write(`\u2500\u2500 Round ${round + 1} \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
163
|
+
`);
|
|
164
|
+
const actions = generateActionsForRound(agents, round);
|
|
165
|
+
for (const action of actions) {
|
|
166
|
+
const event = {
|
|
167
|
+
intent: action.intent,
|
|
168
|
+
tool: action.tool,
|
|
169
|
+
roleId: action.roleId,
|
|
170
|
+
actionCategory: action.actionCategory,
|
|
171
|
+
direction: "input"
|
|
172
|
+
};
|
|
173
|
+
const agentState = agentStates.get(action.roleId);
|
|
174
|
+
if (agentState && agentState.cooldownRemaining > 0) {
|
|
175
|
+
process.stdout.write(` \u25CC ${action.roleId.padEnd(10)} FROZEN (${agentState.cooldownRemaining} rounds) \u2014 ${action.intent.slice(0, 40)}
|
|
176
|
+
`);
|
|
177
|
+
const frozenEvent = {
|
|
178
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
179
|
+
worldId: world.world.world_id,
|
|
180
|
+
worldName: world.world.name,
|
|
181
|
+
worldVersion: world.world.version,
|
|
182
|
+
intent: action.intent,
|
|
183
|
+
tool: action.tool,
|
|
184
|
+
actor: action.roleId,
|
|
185
|
+
direction: "input",
|
|
186
|
+
decision: "PENALIZE",
|
|
187
|
+
reason: `Agent frozen for ${agentState.cooldownRemaining} more round(s)`,
|
|
188
|
+
guardsMatched: [],
|
|
189
|
+
rulesMatched: [],
|
|
190
|
+
invariantsSatisfied: 0,
|
|
191
|
+
invariantsTotal: 0,
|
|
192
|
+
enforcementLevel: "standard",
|
|
193
|
+
originalIntent: action.intent,
|
|
194
|
+
finalAction: "blocked (agent frozen)"
|
|
195
|
+
};
|
|
196
|
+
allAuditEvents.push(frozenEvent);
|
|
197
|
+
continue;
|
|
198
|
+
}
|
|
199
|
+
const verdict = evaluateGuard(event, world, engineOptions);
|
|
200
|
+
let state = agentStates.get(action.roleId) ?? createAgentState(action.roleId);
|
|
201
|
+
if (verdict.status === "PENALIZE" && verdict.consequence) {
|
|
202
|
+
state = applyConsequence(state, verdict.consequence, verdict.ruleId ?? "unknown");
|
|
203
|
+
}
|
|
204
|
+
if (verdict.status === "REWARD" && verdict.reward) {
|
|
205
|
+
state = applyReward(state, verdict.reward, verdict.ruleId ?? "unknown");
|
|
206
|
+
}
|
|
207
|
+
agentStates.set(action.roleId, state);
|
|
208
|
+
const icon = verdict.status === "ALLOW" ? "\u25CF" : verdict.status === "BLOCK" ? "\u25CB" : verdict.status === "PENALIZE" ? "\u25CC" : verdict.status === "REWARD" ? "\u25C9" : verdict.status === "MODIFY" ? "\u25D0" : verdict.status === "NEUTRAL" ? "\u25EF" : "\u25D1";
|
|
209
|
+
process.stdout.write(` ${icon} ${action.roleId.padEnd(10)} ${verdict.status.padEnd(10)} ${action.intent.slice(0, 40)}
|
|
210
|
+
`);
|
|
211
|
+
if (verdict.consequence) {
|
|
212
|
+
process.stdout.write(` \u2192 ${verdict.consequence.description}
|
|
213
|
+
`);
|
|
214
|
+
}
|
|
215
|
+
if (verdict.reward) {
|
|
216
|
+
process.stdout.write(` \u2192 ${verdict.reward.description}
|
|
217
|
+
`);
|
|
218
|
+
}
|
|
219
|
+
allAuditEvents.push(verdictToAuditEvent(event, verdict));
|
|
220
|
+
}
|
|
221
|
+
agentStates = tickAgentStates(agentStates);
|
|
222
|
+
engineOptions.agentStates = agentStates;
|
|
223
|
+
process.stdout.write("\n");
|
|
224
|
+
process.stdout.write(" Agent States:\n");
|
|
225
|
+
for (const agent of agents) {
|
|
226
|
+
const s = agentStates.get(agent.id);
|
|
227
|
+
if (!s) continue;
|
|
228
|
+
const frozen = s.cooldownRemaining > 0 ? ` [FROZEN ${s.cooldownRemaining}r]` : "";
|
|
229
|
+
const influence = s.influence !== 1 ? ` influence=${s.influence.toFixed(2)}` : "";
|
|
230
|
+
process.stdout.write(` ${agent.id.padEnd(10)} penalties=${s.totalPenalties} rewards=${s.totalRewards}${frozen}${influence}
|
|
231
|
+
`);
|
|
232
|
+
}
|
|
233
|
+
process.stdout.write("\n");
|
|
234
|
+
}
|
|
235
|
+
const flow = generateDecisionFlow(allAuditEvents);
|
|
236
|
+
if (jsonOutput) {
|
|
237
|
+
process.stdout.write(JSON.stringify({ flow, agentStates: Object.fromEntries(agentStates) }, null, 2) + "\n");
|
|
238
|
+
} else {
|
|
239
|
+
process.stdout.write(renderDecisionFlow(flow) + "\n");
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
export {
|
|
243
|
+
main
|
|
244
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import {
|
|
2
|
+
resolveWorldPath
|
|
3
|
+
} from "./chunk-BQZMOEML.js";
|
|
4
|
+
import {
|
|
5
|
+
explainWorld,
|
|
6
|
+
renderExplainText
|
|
7
|
+
} from "./chunk-ZJTDUCC2.js";
|
|
8
|
+
import {
|
|
9
|
+
loadWorld
|
|
10
|
+
} from "./chunk-CTZHONLA.js";
|
|
11
|
+
import "./chunk-QWGCMQQD.js";
|
|
12
|
+
|
|
13
|
+
// src/cli/explain.ts
|
|
14
|
+
function parseArgs(argv) {
|
|
15
|
+
let worldPath = "";
|
|
16
|
+
let json = false;
|
|
17
|
+
for (let i = 0; i < argv.length; i++) {
|
|
18
|
+
const arg = argv[i];
|
|
19
|
+
if (arg === "--json") {
|
|
20
|
+
json = true;
|
|
21
|
+
} else if (!arg.startsWith("--") && !worldPath) {
|
|
22
|
+
worldPath = arg;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (!worldPath) {
|
|
26
|
+
throw new Error("Usage: neuroverse explain <world-path-or-id>");
|
|
27
|
+
}
|
|
28
|
+
return { worldPath, json };
|
|
29
|
+
}
|
|
30
|
+
async function main(argv = process.argv.slice(2)) {
|
|
31
|
+
try {
|
|
32
|
+
const args = parseArgs(argv);
|
|
33
|
+
const resolvedPath = await resolveWorldPath(args.worldPath);
|
|
34
|
+
const world = await loadWorld(resolvedPath);
|
|
35
|
+
const explanation = explainWorld(world);
|
|
36
|
+
if (args.json) {
|
|
37
|
+
process.stdout.write(JSON.stringify(explanation, null, 2) + "\n");
|
|
38
|
+
} else {
|
|
39
|
+
process.stderr.write("\n");
|
|
40
|
+
process.stderr.write(renderExplainText(explanation));
|
|
41
|
+
}
|
|
42
|
+
process.exit(0);
|
|
43
|
+
} catch (e) {
|
|
44
|
+
process.stderr.write(`${e instanceof Error ? e.message : String(e)}
|
|
45
|
+
`);
|
|
46
|
+
process.exit(1);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
export {
|
|
50
|
+
main
|
|
51
|
+
};
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import {
|
|
2
|
+
readStdin
|
|
3
|
+
} from "./chunk-BQZMOEML.js";
|
|
4
|
+
import {
|
|
5
|
+
GUARD_EXIT_CODES
|
|
6
|
+
} from "./chunk-MH7BT4VH.js";
|
|
7
|
+
import {
|
|
8
|
+
describeActiveWorld,
|
|
9
|
+
resolveWorldPath
|
|
10
|
+
} from "./chunk-AKW5YVCE.js";
|
|
11
|
+
import {
|
|
12
|
+
evaluateGuard
|
|
13
|
+
} from "./chunk-W7LLXRGY.js";
|
|
14
|
+
import "./chunk-QLPTHTVB.js";
|
|
15
|
+
import {
|
|
16
|
+
loadWorld
|
|
17
|
+
} from "./chunk-CTZHONLA.js";
|
|
18
|
+
import "./chunk-QWGCMQQD.js";
|
|
19
|
+
|
|
20
|
+
// src/cli/guard.ts
|
|
21
|
+
function parseArgs(argv) {
|
|
22
|
+
let worldPath = "";
|
|
23
|
+
let trace = false;
|
|
24
|
+
let level;
|
|
25
|
+
for (let i = 0; i < argv.length; i++) {
|
|
26
|
+
const arg = argv[i];
|
|
27
|
+
if (arg === "--world" && i + 1 < argv.length) {
|
|
28
|
+
worldPath = argv[++i];
|
|
29
|
+
} else if (arg === "--trace") {
|
|
30
|
+
trace = true;
|
|
31
|
+
} else if (arg === "--level" && i + 1 < argv.length) {
|
|
32
|
+
const val = argv[++i];
|
|
33
|
+
if (val === "basic" || val === "standard" || val === "strict") {
|
|
34
|
+
level = val;
|
|
35
|
+
} else {
|
|
36
|
+
throw new Error(`Invalid level: "${val}". Must be basic, standard, or strict.`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return { worldPath, trace, level };
|
|
41
|
+
}
|
|
42
|
+
async function main(argv = process.argv.slice(2)) {
|
|
43
|
+
try {
|
|
44
|
+
const args = parseArgs(argv);
|
|
45
|
+
const worldPath = resolveWorldPath(args.worldPath);
|
|
46
|
+
if (!worldPath) {
|
|
47
|
+
throw new Error(
|
|
48
|
+
"No world specified. Use --world <path>, set NEUROVERSE_WORLD, or run `neuroverse world use <name>`"
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
const worldInfo = describeActiveWorld(args.worldPath);
|
|
52
|
+
if (worldInfo) {
|
|
53
|
+
process.stderr.write(`Using world: ${worldInfo.name}
|
|
54
|
+
`);
|
|
55
|
+
}
|
|
56
|
+
const input = await readStdin();
|
|
57
|
+
if (!input.trim()) {
|
|
58
|
+
const errorResult = {
|
|
59
|
+
error: "No input on stdin. Pipe a JSON GuardEvent.",
|
|
60
|
+
usage: `echo '{"intent":"..."}' | neuroverse guard --world <path>`
|
|
61
|
+
};
|
|
62
|
+
process.stdout.write(JSON.stringify(errorResult, null, 2) + "\n");
|
|
63
|
+
process.exit(GUARD_EXIT_CODES.ERROR);
|
|
64
|
+
}
|
|
65
|
+
let event;
|
|
66
|
+
try {
|
|
67
|
+
event = JSON.parse(input);
|
|
68
|
+
} catch (e) {
|
|
69
|
+
const errorResult = { error: "Invalid JSON on stdin", detail: String(e) };
|
|
70
|
+
process.stdout.write(JSON.stringify(errorResult, null, 2) + "\n");
|
|
71
|
+
process.exit(GUARD_EXIT_CODES.ERROR);
|
|
72
|
+
}
|
|
73
|
+
if (!event.intent) {
|
|
74
|
+
const errorResult = { error: 'GuardEvent must have an "intent" field' };
|
|
75
|
+
process.stdout.write(JSON.stringify(errorResult, null, 2) + "\n");
|
|
76
|
+
process.exit(GUARD_EXIT_CODES.ERROR);
|
|
77
|
+
}
|
|
78
|
+
const world = await loadWorld(worldPath);
|
|
79
|
+
const options = { trace: args.trace, level: args.level };
|
|
80
|
+
const verdict = evaluateGuard(event, world, options);
|
|
81
|
+
process.stdout.write(JSON.stringify(verdict, null, 2) + "\n");
|
|
82
|
+
const exitCode = GUARD_EXIT_CODES[verdict.status];
|
|
83
|
+
process.exit(exitCode);
|
|
84
|
+
} catch (e) {
|
|
85
|
+
const errorResult = { error: "Guard evaluation failed", detail: String(e) };
|
|
86
|
+
process.stderr.write(JSON.stringify(errorResult, null, 2) + "\n");
|
|
87
|
+
process.exit(GUARD_EXIT_CODES.ERROR);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
export {
|
|
91
|
+
main
|
|
92
|
+
};
|