@neuroverseos/governance 0.5.0 → 0.6.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 (133) hide show
  1. package/README.md +244 -0
  2. package/dist/adapters/autoresearch.d.cts +2 -1
  3. package/dist/adapters/autoresearch.d.ts +2 -1
  4. package/dist/adapters/autoresearch.js +2 -2
  5. package/dist/adapters/deep-agents.d.cts +3 -2
  6. package/dist/adapters/deep-agents.d.ts +3 -2
  7. package/dist/adapters/deep-agents.js +2 -2
  8. package/dist/adapters/express.d.cts +2 -1
  9. package/dist/adapters/express.d.ts +2 -1
  10. package/dist/adapters/express.js +2 -2
  11. package/dist/adapters/github.cjs +1697 -0
  12. package/dist/adapters/github.d.cts +225 -0
  13. package/dist/adapters/github.d.ts +225 -0
  14. package/dist/adapters/github.js +27 -0
  15. package/dist/adapters/index.d.cts +4 -316
  16. package/dist/adapters/index.d.ts +4 -316
  17. package/dist/adapters/index.js +23 -21
  18. package/dist/adapters/langchain.d.cts +3 -2
  19. package/dist/adapters/langchain.d.ts +3 -2
  20. package/dist/adapters/langchain.js +2 -2
  21. package/dist/adapters/mentraos.cjs +2181 -0
  22. package/dist/adapters/mentraos.d.cts +319 -0
  23. package/dist/adapters/mentraos.d.ts +319 -0
  24. package/dist/{mentraos-LLH7KEV4.js → adapters/mentraos.js} +12 -10
  25. package/dist/adapters/openai.d.cts +3 -2
  26. package/dist/adapters/openai.d.ts +3 -2
  27. package/dist/adapters/openai.js +2 -2
  28. package/dist/adapters/openclaw.d.cts +3 -2
  29. package/dist/adapters/openclaw.d.ts +3 -2
  30. package/dist/adapters/openclaw.js +2 -2
  31. package/dist/{add-LYHDZ5RL.js → add-XSANI3FK.js} +1 -1
  32. package/dist/admin/index.cjs +2214 -0
  33. package/dist/admin/index.d.cts +362 -0
  34. package/dist/admin/index.d.ts +362 -0
  35. package/dist/admin/index.js +703 -0
  36. package/dist/bootstrap-contract-DcV6t-8M.d.cts +216 -0
  37. package/dist/bootstrap-contract-DcV6t-8M.d.ts +216 -0
  38. package/dist/{build-SCAWPA7E.js → build-UTVDGHB3.js} +5 -5
  39. package/dist/{chunk-JKGPSFGH.js → chunk-7FL3U7Z5.js} +3 -3
  40. package/dist/chunk-A2UZTLRV.js +421 -0
  41. package/dist/{chunk-TD5GKIHP.js → chunk-B3IIPTY3.js} +3 -3
  42. package/dist/chunk-EQR7BGFN.js +337 -0
  43. package/dist/{chunk-5JUZ4HL7.js → chunk-FDPPZLSQ.js} +3 -3
  44. package/dist/{chunk-MFKHTE5R.js → chunk-FKQCPRKI.js} +3 -3
  45. package/dist/{chunk-7D7PZLB7.js → chunk-FS2UUJJO.js} +3 -3
  46. package/dist/{chunk-U6FRAEQJ.js → chunk-GJ6LM4JZ.js} +1 -441
  47. package/dist/chunk-H3REGQRI.js +107 -0
  48. package/dist/{chunk-25XHSTPT.js → chunk-HDNDL6D5.js} +3 -3
  49. package/dist/{chunk-BXLTEUS4.js → chunk-I4RTIMLX.js} +2 -2
  50. package/dist/chunk-IOVXB6QN.js +447 -0
  51. package/dist/{chunk-Y6WXAPKY.js → chunk-NTHXZAW4.js} +3 -3
  52. package/dist/{chunk-UTH7OXTM.js → chunk-OTZU76DH.js} +22 -4
  53. package/dist/{chunk-DWHUZUEY.js → chunk-T6GMRZWC.js} +3 -3
  54. package/dist/{chunk-V4FZHJQX.js → chunk-TIXVEPS2.js} +3 -3
  55. package/dist/{chunk-YNYCQECH.js → chunk-TJ5L2UTE.js} +3 -3
  56. package/dist/chunk-UGTNKTHS.js +542 -0
  57. package/dist/cli/neuroverse.cjs +3372 -523
  58. package/dist/cli/neuroverse.js +53 -21
  59. package/dist/cli/plan.js +2 -2
  60. package/dist/cli/run.cjs +242 -139
  61. package/dist/cli/run.js +23 -3
  62. package/dist/cli/worldmodel.cjs +1624 -0
  63. package/dist/cli/worldmodel.d.cts +24 -0
  64. package/dist/cli/worldmodel.d.ts +24 -0
  65. package/dist/cli/worldmodel.js +742 -0
  66. package/dist/{demo-66MMJTEH.js → demo-6W3YXLAX.js} +4 -4
  67. package/dist/{derive-AUQE3L3P.js → derive-42IJW7JI.js} +4 -4
  68. package/dist/{doctor-EY7LKSYY.js → doctor-XEMLO6UA.js} +3 -2
  69. package/dist/engine/bootstrap-emitter.cjs +241 -0
  70. package/dist/engine/bootstrap-emitter.d.cts +27 -0
  71. package/dist/engine/bootstrap-emitter.d.ts +27 -0
  72. package/dist/{bootstrap-emitter-GIMOJFOC.js → engine/bootstrap-emitter.js} +2 -2
  73. package/dist/engine/bootstrap-parser.cjs +560 -0
  74. package/dist/engine/bootstrap-parser.d.cts +96 -0
  75. package/dist/engine/bootstrap-parser.d.ts +96 -0
  76. package/dist/{bootstrap-parser-LBLGVEMU.js → engine/bootstrap-parser.js} +2 -2
  77. package/dist/engine/guard-engine.cjs +1116 -0
  78. package/dist/engine/guard-engine.d.cts +60 -0
  79. package/dist/engine/guard-engine.d.ts +60 -0
  80. package/dist/{guard-engine-N7TUIUU7.js → engine/guard-engine.js} +3 -3
  81. package/dist/engine/simulate-engine.cjs +390 -0
  82. package/dist/engine/simulate-engine.d.cts +105 -0
  83. package/dist/engine/simulate-engine.d.ts +105 -0
  84. package/dist/engine/simulate-engine.js +9 -0
  85. package/dist/engine/worldmodel-compiler.cjs +366 -0
  86. package/dist/engine/worldmodel-compiler.d.cts +46 -0
  87. package/dist/engine/worldmodel-compiler.d.ts +46 -0
  88. package/dist/engine/worldmodel-compiler.js +17 -0
  89. package/dist/engine/worldmodel-parser.cjs +566 -0
  90. package/dist/engine/worldmodel-parser.d.cts +22 -0
  91. package/dist/engine/worldmodel-parser.d.ts +22 -0
  92. package/dist/engine/worldmodel-parser.js +7 -0
  93. package/dist/{equity-penalties-WWC7UDQD.js → equity-penalties-CCO3GVHS.js} +6 -6
  94. package/dist/{explain-MUSGDT67.js → explain-HDFN4ION.js} +1 -1
  95. package/dist/{guard-W3BMQPBJ.js → guard-IHJEKHL2.js} +16 -4
  96. package/dist/{guard-contract-CLBbTGK_.d.ts → guard-contract-ddiIPlOg.d.cts} +2 -369
  97. package/dist/{guard-contract-CLBbTGK_.d.cts → guard-contract-q6HJAq3Q.d.ts} +2 -369
  98. package/dist/{improve-PJDAWW4Q.js → improve-LRORRYEX.js} +3 -3
  99. package/dist/index.cjs +471 -1
  100. package/dist/index.d.cts +14 -492
  101. package/dist/index.d.ts +14 -492
  102. package/dist/index.js +63 -42
  103. package/dist/keygen-BSZH3NM2.js +77 -0
  104. package/dist/{lens-IP6GIZ2Q.js → lens-TLDZQXBI.js} +152 -26
  105. package/dist/{mcp-server-OG3PPVD2.js → mcp-server-CKYBHXWK.js} +2 -2
  106. package/dist/migrate-NH5PVMX4.js +221 -0
  107. package/dist/{playground-4BK2XQ47.js → playground-3TTBN7XD.js} +5 -5
  108. package/dist/{redteam-BRZALBPP.js → redteam-W644UMWN.js} +3 -3
  109. package/dist/{session-SGRUT2UH.js → session-FMAROEIE.js} +2 -2
  110. package/dist/{shared-CwGpPheR.d.ts → shared-DAzdfWtU.d.ts} +1 -1
  111. package/dist/{shared-BGzmYP5g.d.cts → shared-PpalGKxc.d.cts} +1 -1
  112. package/dist/sign-RRELHKWM.js +11 -0
  113. package/dist/{simulate-FGXKIH7V.js → simulate-VT437EEL.js} +2 -2
  114. package/dist/{test-PT44BSYG.js → test-XDB2DH3L.js} +3 -3
  115. package/dist/types.cjs +18 -0
  116. package/dist/types.d.cts +370 -0
  117. package/dist/types.d.ts +370 -0
  118. package/dist/types.js +0 -0
  119. package/dist/{validate-Q5O5TGLT.js → validate-M52DX22Y.js} +1 -1
  120. package/dist/verify-6AVTWX75.js +151 -0
  121. package/dist/{world-V52ZMH26.js → world-O4HTQPDP.js} +1 -1
  122. package/dist/{world-loader-C4D3VPP3.js → world-loader-YTYFOP7D.js} +1 -1
  123. package/dist/worldmodel-contract-BPGhiuW5.d.cts +221 -0
  124. package/dist/worldmodel-contract-BPGhiuW5.d.ts +221 -0
  125. package/dist/worlds/auki-vanguard.worldmodel.md +116 -0
  126. package/dist/worlds/behavioral-demo.nv-world.md +130 -0
  127. package/dist/worlds/neuroverse-governance.worldmodel.md +115 -0
  128. package/package.json +44 -3
  129. package/dist/{bootstrap-IP5QMC3Q.js → bootstrap-2OW5ZLBL.js} +3 -3
  130. package/dist/{chunk-4G6WHPLI.js → chunk-735Z3HA4.js} +6 -6
  131. package/dist/{chunk-7QIAF377.js → chunk-CYDMUJVZ.js} +0 -0
  132. package/dist/{configure-ai-LL3VAPQW.js → configure-ai-5MP5DWTT.js} +3 -3
  133. package/dist/{decision-flow-3K4D72G4.js → decision-flow-IJPNMVQK.js} +3 -3
@@ -29,11 +29,16 @@ Commands:
29
29
  decision-flow Intent \u2192 Rule \u2192 Outcome visualization (behavioral governance)
30
30
  equity-penalties Fortune 500 equity PENALIZE/REWARD simulation
31
31
  world World management (status, diff, snapshot, rollback)
32
+ keygen Generate Ed25519 signing keypair
33
+ sign Sign a world artifact (cryptographic manifest)
34
+ verify Verify a signed world artifact
35
+ migrate Migrate world schema between versions
32
36
  derive AI-assisted synthesis of .nv-world.md from markdown
33
37
  bootstrap Compile .nv-world.md \u2192 world JSON files
34
38
  configure-ai Configure AI provider credentials
35
39
  configure-world Interactive wizard: define your system in plain language
36
40
  lens Manage behavioral lenses (list, preview, compile, compare, add)
41
+ worldmodel Behavioral world model builder (init, validate, build, explain)
37
42
 
38
43
  Usage:
39
44
  neuroverse add "Block dairy orders" --world <dir>
@@ -66,11 +71,18 @@ Usage:
66
71
  neuroverse equity-penalties --world <dir> [--agents N] [--rounds N] [--json]
67
72
  neuroverse configure-ai --provider <name> --model <name> --api-key <key>
68
73
  neuroverse configure-world [--output <dir>]
74
+ neuroverse keygen [--output <dir>] [--name <name>]
75
+ neuroverse sign --world <dir> [--key <path>]
76
+ neuroverse verify --world <dir> [--key <path>]
77
+ neuroverse migrate --world <dir> [--dry-run] [--backup]
69
78
  neuroverse lens list [--world <dir>] [--json]
70
79
  neuroverse lens preview <id> [--world <dir>]
71
80
  neuroverse lens compile <id,...> [--world <dir>] [--role <role>] [--json]
72
81
  neuroverse lens compare --input "text" --lenses stoic,coach,calm
73
82
  neuroverse lens add --world <dir> --name "Name" --tagline "..." [options]
83
+ neuroverse worldmodel init --name "My Model"
84
+ neuroverse worldmodel build ./model.worldmodel.md --output ./world/
85
+ neuroverse worldmodel explain ./model.worldmodel.md
74
86
 
75
87
  Examples:
76
88
  neuroverse build horror-notes.md
@@ -100,23 +112,23 @@ async function main() {
100
112
  const subArgs = args.slice(1);
101
113
  switch (command) {
102
114
  case "add": {
103
- const { main: addMain } = await import("../add-LYHDZ5RL.js");
115
+ const { main: addMain } = await import("../add-XSANI3FK.js");
104
116
  return addMain(subArgs);
105
117
  }
106
118
  case "build": {
107
- const { main: buildMain } = await import("../build-SCAWPA7E.js");
119
+ const { main: buildMain } = await import("../build-UTVDGHB3.js");
108
120
  return buildMain(subArgs);
109
121
  }
110
122
  case "explain": {
111
- const { main: explainMain } = await import("../explain-MUSGDT67.js");
123
+ const { main: explainMain } = await import("../explain-HDFN4ION.js");
112
124
  return explainMain(subArgs);
113
125
  }
114
126
  case "simulate": {
115
- const { main: simulateMain } = await import("../simulate-FGXKIH7V.js");
127
+ const { main: simulateMain } = await import("../simulate-VT437EEL.js");
116
128
  return simulateMain(subArgs);
117
129
  }
118
130
  case "improve": {
119
- const { main: improveMain } = await import("../improve-PJDAWW4Q.js");
131
+ const { main: improveMain } = await import("../improve-LRORRYEX.js");
120
132
  return improveMain(subArgs);
121
133
  }
122
134
  case "init": {
@@ -132,35 +144,35 @@ async function main() {
132
144
  return inferWorldMain(subArgs);
133
145
  }
134
146
  case "bootstrap": {
135
- const { main: bootstrapMain } = await import("../bootstrap-IP5QMC3Q.js");
147
+ const { main: bootstrapMain } = await import("../bootstrap-2OW5ZLBL.js");
136
148
  return bootstrapMain(subArgs);
137
149
  }
138
150
  case "validate": {
139
- const { main: validateMain } = await import("../validate-Q5O5TGLT.js");
151
+ const { main: validateMain } = await import("../validate-M52DX22Y.js");
140
152
  return validateMain(subArgs);
141
153
  }
142
154
  case "guard": {
143
- const { main: guardMain } = await import("../guard-W3BMQPBJ.js");
155
+ const { main: guardMain } = await import("../guard-IHJEKHL2.js");
144
156
  return guardMain(subArgs);
145
157
  }
146
158
  case "test": {
147
- const { main: testMain } = await import("../test-PT44BSYG.js");
159
+ const { main: testMain } = await import("../test-XDB2DH3L.js");
148
160
  return testMain(subArgs);
149
161
  }
150
162
  case "redteam": {
151
- const { main: redteamMain } = await import("../redteam-BRZALBPP.js");
163
+ const { main: redteamMain } = await import("../redteam-W644UMWN.js");
152
164
  return redteamMain(subArgs);
153
165
  }
154
166
  case "demo": {
155
- const { main: demoMain } = await import("../demo-66MMJTEH.js");
167
+ const { main: demoMain } = await import("../demo-6W3YXLAX.js");
156
168
  return demoMain(subArgs);
157
169
  }
158
170
  case "doctor": {
159
- const { main: doctorMain } = await import("../doctor-EY7LKSYY.js");
171
+ const { main: doctorMain } = await import("../doctor-XEMLO6UA.js");
160
172
  return doctorMain(subArgs);
161
173
  }
162
174
  case "playground": {
163
- const { main: playgroundMain } = await import("../playground-4BK2XQ47.js");
175
+ const { main: playgroundMain } = await import("../playground-3TTBN7XD.js");
164
176
  return playgroundMain(subArgs);
165
177
  }
166
178
  case "plan": {
@@ -172,11 +184,11 @@ async function main() {
172
184
  return runMain(subArgs);
173
185
  }
174
186
  case "mcp": {
175
- const { startMcpServer } = await import("../mcp-server-OG3PPVD2.js");
187
+ const { startMcpServer } = await import("../mcp-server-CKYBHXWK.js");
176
188
  return startMcpServer(subArgs);
177
189
  }
178
190
  case "worlds": {
179
- const { main: worldMain } = await import("../world-V52ZMH26.js");
191
+ const { main: worldMain } = await import("../world-O4HTQPDP.js");
180
192
  return worldMain(["list", ...subArgs]);
181
193
  }
182
194
  case "trace": {
@@ -192,23 +204,39 @@ async function main() {
192
204
  return behavioralMain(subArgs);
193
205
  }
194
206
  case "world": {
195
- const { main: worldMain } = await import("../world-V52ZMH26.js");
207
+ const { main: worldMain } = await import("../world-O4HTQPDP.js");
196
208
  return worldMain(subArgs);
197
209
  }
198
210
  case "derive": {
199
- const { main: deriveMain } = await import("../derive-AUQE3L3P.js");
211
+ const { main: deriveMain } = await import("../derive-42IJW7JI.js");
200
212
  return deriveMain(subArgs);
201
213
  }
202
214
  case "decision-flow": {
203
- const { main: decisionFlowMain } = await import("../decision-flow-3K4D72G4.js");
215
+ const { main: decisionFlowMain } = await import("../decision-flow-IJPNMVQK.js");
204
216
  return decisionFlowMain(subArgs);
205
217
  }
206
218
  case "equity-penalties": {
207
- const { main: equityPenaltiesMain } = await import("../equity-penalties-WWC7UDQD.js");
219
+ const { main: equityPenaltiesMain } = await import("../equity-penalties-CCO3GVHS.js");
208
220
  return equityPenaltiesMain(subArgs);
209
221
  }
222
+ case "keygen": {
223
+ const { main: keygenMain } = await import("../keygen-BSZH3NM2.js");
224
+ return keygenMain(subArgs);
225
+ }
226
+ case "sign": {
227
+ const { main: signMain } = await import("../sign-RRELHKWM.js");
228
+ return signMain(subArgs);
229
+ }
230
+ case "verify": {
231
+ const { main: verifyMain } = await import("../verify-6AVTWX75.js");
232
+ return verifyMain(subArgs);
233
+ }
234
+ case "migrate": {
235
+ const { main: migrateMain } = await import("../migrate-NH5PVMX4.js");
236
+ return migrateMain(subArgs);
237
+ }
210
238
  case "configure-ai": {
211
- const { main: configureAiMain } = await import("../configure-ai-LL3VAPQW.js");
239
+ const { main: configureAiMain } = await import("../configure-ai-5MP5DWTT.js");
212
240
  return configureAiMain(subArgs);
213
241
  }
214
242
  case "configure-world": {
@@ -216,9 +244,13 @@ async function main() {
216
244
  return configureWorldMain(subArgs);
217
245
  }
218
246
  case "lens": {
219
- const { main: lensMain } = await import("../lens-IP6GIZ2Q.js");
247
+ const { main: lensMain } = await import("../lens-TLDZQXBI.js");
220
248
  return lensMain(subArgs);
221
249
  }
250
+ case "worldmodel": {
251
+ const { main: worldmodelMain } = await import("./worldmodel.js");
252
+ return worldmodelMain(subArgs);
253
+ }
222
254
  case "--help":
223
255
  case "-h":
224
256
  case "help":
package/dist/cli/plan.js CHANGED
@@ -100,8 +100,8 @@ async function checkCommand(args) {
100
100
  }
101
101
  const worldPath = parseArg(args, "--world");
102
102
  if (worldPath) {
103
- const { loadWorld } = await import("../world-loader-C4D3VPP3.js");
104
- const { evaluateGuard } = await import("../guard-engine-N7TUIUU7.js");
103
+ const { loadWorld } = await import("../world-loader-YTYFOP7D.js");
104
+ const { evaluateGuard } = await import("../engine/guard-engine.js");
105
105
  const world = await loadWorld(worldPath);
106
106
  const verdict2 = evaluateGuard(event, world, { plan });
107
107
  process.stdout.write(JSON.stringify(verdict2, null, 2) + "\n");
package/dist/cli/run.cjs CHANGED
@@ -30,143 +30,6 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
30
30
  ));
31
31
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
32
32
 
33
- // src/runtime/model-adapter.ts
34
- var model_adapter_exports = {};
35
- __export(model_adapter_exports, {
36
- ModelAdapter: () => ModelAdapter,
37
- PROVIDERS: () => PROVIDERS,
38
- resolveProvider: () => resolveProvider
39
- });
40
- function resolveProvider(provider, overrides) {
41
- const preset = PROVIDERS[provider];
42
- if (!preset) {
43
- throw new Error(
44
- `Unknown provider: "${provider}". Available: ${Object.keys(PROVIDERS).join(", ")}`
45
- );
46
- }
47
- const apiKey = overrides?.apiKey ?? (preset.envVar ? process.env[preset.envVar] : "") ?? "";
48
- if (!apiKey && preset.envVar) {
49
- throw new Error(
50
- `Missing API key. Set ${preset.envVar} or pass --api-key.`
51
- );
52
- }
53
- return {
54
- baseUrl: overrides?.baseUrl ?? preset.baseUrl,
55
- apiKey,
56
- model: overrides?.model ?? preset.defaultModel,
57
- systemPrompt: overrides?.systemPrompt,
58
- maxTokens: overrides?.maxTokens
59
- };
60
- }
61
- var DEFAULT_SYSTEM_PROMPT, ModelAdapter, PROVIDERS;
62
- var init_model_adapter = __esm({
63
- "src/runtime/model-adapter.ts"() {
64
- "use strict";
65
- DEFAULT_SYSTEM_PROMPT = `You are an AI assistant operating under NeuroVerse governance.
66
- All your tool calls are evaluated against governance rules before execution.
67
- If an action is blocked, you will be told why. Adjust your approach accordingly.
68
- Do not attempt to bypass governance rules.`;
69
- ModelAdapter = class {
70
- config;
71
- messages;
72
- tools;
73
- constructor(config, tools = []) {
74
- this.config = config;
75
- this.tools = tools;
76
- this.messages = [];
77
- const systemPrompt = config.systemPrompt ?? DEFAULT_SYSTEM_PROMPT;
78
- this.messages.push({ role: "system", content: systemPrompt });
79
- }
80
- /**
81
- * Send a user message and get the model's response.
82
- */
83
- async chat(userMessage) {
84
- this.messages.push({ role: "user", content: userMessage });
85
- return this.complete();
86
- }
87
- /**
88
- * Send a tool result back to the model and get the next response.
89
- */
90
- async sendToolResult(toolCallId, result) {
91
- this.messages.push({
92
- role: "tool",
93
- content: result,
94
- tool_call_id: toolCallId
95
- });
96
- return this.complete();
97
- }
98
- /**
99
- * Send a governance block message as a tool result.
100
- */
101
- async sendBlockedResult(toolCallId, reason) {
102
- return this.sendToolResult(
103
- toolCallId,
104
- `[GOVERNANCE BLOCKED] ${reason}. Please adjust your approach.`
105
- );
106
- }
107
- /**
108
- * Call the model API and parse the response.
109
- */
110
- async complete() {
111
- const url = `${this.config.baseUrl}/chat/completions`;
112
- const body = {
113
- model: this.config.model,
114
- messages: this.messages,
115
- max_tokens: this.config.maxTokens ?? 4096
116
- };
117
- if (this.tools.length > 0) {
118
- body.tools = this.tools;
119
- }
120
- const response = await fetch(url, {
121
- method: "POST",
122
- headers: {
123
- "Content-Type": "application/json",
124
- "Authorization": `Bearer ${this.config.apiKey}`
125
- },
126
- body: JSON.stringify(body)
127
- });
128
- if (!response.ok) {
129
- const text = await response.text();
130
- throw new Error(`Model API error ${response.status}: ${text}`);
131
- }
132
- const data = await response.json();
133
- const choice = data.choices?.[0];
134
- if (!choice) {
135
- throw new Error("Model returned no choices");
136
- }
137
- const message = choice.message;
138
- this.messages.push(message);
139
- return {
140
- content: message.content ?? null,
141
- toolCalls: message.tool_calls ?? [],
142
- finishReason: choice.finish_reason ?? "stop"
143
- };
144
- }
145
- /** Get current message count (for context tracking). */
146
- get messageCount() {
147
- return this.messages.length;
148
- }
149
- };
150
- PROVIDERS = {
151
- openai: {
152
- baseUrl: "https://api.openai.com/v1",
153
- defaultModel: "gpt-4o",
154
- envVar: "OPENAI_API_KEY"
155
- },
156
- anthropic: {
157
- baseUrl: "https://api.anthropic.com/v1",
158
- defaultModel: "claude-sonnet-4-20250514",
159
- envVar: "ANTHROPIC_API_KEY"
160
- },
161
- ollama: {
162
- baseUrl: "http://localhost:11434/v1",
163
- defaultModel: "llama3",
164
- envVar: ""
165
- }
166
- };
167
- }
168
- });
169
-
170
33
  // src/engine/text-utils.ts
171
34
  function normalizeEventText(event) {
172
35
  return [
@@ -1304,6 +1167,143 @@ var init_guard_engine = __esm({
1304
1167
  }
1305
1168
  });
1306
1169
 
1170
+ // src/runtime/model-adapter.ts
1171
+ var model_adapter_exports = {};
1172
+ __export(model_adapter_exports, {
1173
+ ModelAdapter: () => ModelAdapter,
1174
+ PROVIDERS: () => PROVIDERS,
1175
+ resolveProvider: () => resolveProvider
1176
+ });
1177
+ function resolveProvider(provider, overrides) {
1178
+ const preset = PROVIDERS[provider];
1179
+ if (!preset) {
1180
+ throw new Error(
1181
+ `Unknown provider: "${provider}". Available: ${Object.keys(PROVIDERS).join(", ")}`
1182
+ );
1183
+ }
1184
+ const apiKey = overrides?.apiKey ?? (preset.envVar ? process.env[preset.envVar] : "") ?? "";
1185
+ if (!apiKey && preset.envVar) {
1186
+ throw new Error(
1187
+ `Missing API key. Set ${preset.envVar} or pass --api-key.`
1188
+ );
1189
+ }
1190
+ return {
1191
+ baseUrl: overrides?.baseUrl ?? preset.baseUrl,
1192
+ apiKey,
1193
+ model: overrides?.model ?? preset.defaultModel,
1194
+ systemPrompt: overrides?.systemPrompt,
1195
+ maxTokens: overrides?.maxTokens
1196
+ };
1197
+ }
1198
+ var DEFAULT_SYSTEM_PROMPT, ModelAdapter, PROVIDERS;
1199
+ var init_model_adapter = __esm({
1200
+ "src/runtime/model-adapter.ts"() {
1201
+ "use strict";
1202
+ DEFAULT_SYSTEM_PROMPT = `You are an AI assistant operating under NeuroVerse governance.
1203
+ All your tool calls are evaluated against governance rules before execution.
1204
+ If an action is blocked, you will be told why. Adjust your approach accordingly.
1205
+ Do not attempt to bypass governance rules.`;
1206
+ ModelAdapter = class {
1207
+ config;
1208
+ messages;
1209
+ tools;
1210
+ constructor(config, tools = []) {
1211
+ this.config = config;
1212
+ this.tools = tools;
1213
+ this.messages = [];
1214
+ const systemPrompt = config.systemPrompt ?? DEFAULT_SYSTEM_PROMPT;
1215
+ this.messages.push({ role: "system", content: systemPrompt });
1216
+ }
1217
+ /**
1218
+ * Send a user message and get the model's response.
1219
+ */
1220
+ async chat(userMessage) {
1221
+ this.messages.push({ role: "user", content: userMessage });
1222
+ return this.complete();
1223
+ }
1224
+ /**
1225
+ * Send a tool result back to the model and get the next response.
1226
+ */
1227
+ async sendToolResult(toolCallId, result) {
1228
+ this.messages.push({
1229
+ role: "tool",
1230
+ content: result,
1231
+ tool_call_id: toolCallId
1232
+ });
1233
+ return this.complete();
1234
+ }
1235
+ /**
1236
+ * Send a governance block message as a tool result.
1237
+ */
1238
+ async sendBlockedResult(toolCallId, reason) {
1239
+ return this.sendToolResult(
1240
+ toolCallId,
1241
+ `[GOVERNANCE BLOCKED] ${reason}. Please adjust your approach.`
1242
+ );
1243
+ }
1244
+ /**
1245
+ * Call the model API and parse the response.
1246
+ */
1247
+ async complete() {
1248
+ const url = `${this.config.baseUrl}/chat/completions`;
1249
+ const body = {
1250
+ model: this.config.model,
1251
+ messages: this.messages,
1252
+ max_tokens: this.config.maxTokens ?? 4096
1253
+ };
1254
+ if (this.tools.length > 0) {
1255
+ body.tools = this.tools;
1256
+ }
1257
+ const response = await fetch(url, {
1258
+ method: "POST",
1259
+ headers: {
1260
+ "Content-Type": "application/json",
1261
+ "Authorization": `Bearer ${this.config.apiKey}`
1262
+ },
1263
+ body: JSON.stringify(body)
1264
+ });
1265
+ if (!response.ok) {
1266
+ const text = await response.text();
1267
+ throw new Error(`Model API error ${response.status}: ${text}`);
1268
+ }
1269
+ const data = await response.json();
1270
+ const choice = data.choices?.[0];
1271
+ if (!choice) {
1272
+ throw new Error("Model returned no choices");
1273
+ }
1274
+ const message = choice.message;
1275
+ this.messages.push(message);
1276
+ return {
1277
+ content: message.content ?? null,
1278
+ toolCalls: message.tool_calls ?? [],
1279
+ finishReason: choice.finish_reason ?? "stop"
1280
+ };
1281
+ }
1282
+ /** Get current message count (for context tracking). */
1283
+ get messageCount() {
1284
+ return this.messages.length;
1285
+ }
1286
+ };
1287
+ PROVIDERS = {
1288
+ openai: {
1289
+ baseUrl: "https://api.openai.com/v1",
1290
+ defaultModel: "gpt-4o",
1291
+ envVar: "OPENAI_API_KEY"
1292
+ },
1293
+ anthropic: {
1294
+ baseUrl: "https://api.anthropic.com/v1",
1295
+ defaultModel: "claude-sonnet-4-20250514",
1296
+ envVar: "ANTHROPIC_API_KEY"
1297
+ },
1298
+ ollama: {
1299
+ baseUrl: "http://localhost:11434/v1",
1300
+ defaultModel: "llama3",
1301
+ envVar: ""
1302
+ }
1303
+ };
1304
+ }
1305
+ });
1306
+
1307
1307
  // src/loader/world-loader.ts
1308
1308
  async function loadWorldFromDirectory(dirPath) {
1309
1309
  const { readFile } = await import("fs/promises");
@@ -1500,11 +1500,17 @@ async function runPipeMode(config) {
1500
1500
  process.stderr.write(`[neuroverse] Plan: ${state.plan.plan_id} (${state.plan.objective})
1501
1501
  `);
1502
1502
  }
1503
+ const MAX_BUFFER_SIZE = 1e6;
1503
1504
  return new Promise((resolve2, reject) => {
1504
1505
  let buffer = "";
1505
1506
  process.stdin.setEncoding("utf-8");
1506
1507
  process.stdin.on("data", (chunk) => {
1507
1508
  buffer += chunk;
1509
+ if (buffer.length > MAX_BUFFER_SIZE) {
1510
+ process.stderr.write("[neuroverse] Warning: pipe buffer exceeded 1MB, resetting\n");
1511
+ buffer = "";
1512
+ return;
1513
+ }
1508
1514
  const lines = buffer.split("\n");
1509
1515
  buffer = lines.pop() ?? "";
1510
1516
  for (const line of lines) {
@@ -1669,7 +1675,9 @@ var init_session = __esm({
1669
1675
  init_plan_engine();
1670
1676
  init_world_loader();
1671
1677
  init_decision_flow_engine();
1672
- SessionManager = class {
1678
+ SessionManager = class _SessionManager {
1679
+ /** Maximum unique agent IDs tracked before eviction. Prevents unbounded memory growth. */
1680
+ static MAX_AGENTS = 1e4;
1673
1681
  config;
1674
1682
  state;
1675
1683
  engineOptions;
@@ -1733,6 +1741,16 @@ var init_session = __esm({
1733
1741
  if (verdict.status === "REWARD" && verdict.reward) {
1734
1742
  agentState = applyReward(agentState, verdict.reward, verdict.ruleId ?? "unknown");
1735
1743
  }
1744
+ if (this.state.agentStates.size >= _SessionManager.MAX_AGENTS && !this.state.agentStates.has(event.roleId)) {
1745
+ const oldest = this.state.agentStates.keys().next().value;
1746
+ if (oldest !== void 0) {
1747
+ this.state.agentStates.delete(oldest);
1748
+ }
1749
+ process.stderr.write(
1750
+ `[neuroverse] Warning: agent state map at capacity (${_SessionManager.MAX_AGENTS}), evicted oldest entry
1751
+ `
1752
+ );
1753
+ }
1736
1754
  this.state.agentStates.set(event.roleId, agentState);
1737
1755
  }
1738
1756
  this.config.onVerdict?.(verdict, event);
@@ -1917,6 +1935,77 @@ function resolveNameOrPath(ref, cwd) {
1917
1935
  return (0, import_path.resolve)(cwd, ref);
1918
1936
  }
1919
1937
 
1938
+ // src/engine/audit-logger.ts
1939
+ init_guard_engine();
1940
+ var FileAuditLogger = class {
1941
+ logPath;
1942
+ buffer = [];
1943
+ flushTimer = null;
1944
+ flushIntervalMs;
1945
+ constructor(logPath, options) {
1946
+ this.logPath = logPath;
1947
+ this.flushIntervalMs = options?.flushIntervalMs ?? 1e3;
1948
+ }
1949
+ log(event) {
1950
+ this.buffer.push(JSON.stringify(event));
1951
+ if (!this.flushTimer) {
1952
+ this.flushTimer = setTimeout(() => {
1953
+ void this.flush();
1954
+ }, this.flushIntervalMs);
1955
+ }
1956
+ }
1957
+ async flush() {
1958
+ if (this.buffer.length === 0) return;
1959
+ if (this.flushTimer) {
1960
+ clearTimeout(this.flushTimer);
1961
+ this.flushTimer = null;
1962
+ }
1963
+ const lines = this.buffer.splice(0).join("\n") + "\n";
1964
+ try {
1965
+ const { appendFile, mkdir } = await import("fs/promises");
1966
+ const { dirname } = await import("path");
1967
+ await mkdir(dirname(this.logPath), { recursive: true });
1968
+ await appendFile(this.logPath, lines, "utf-8");
1969
+ } catch {
1970
+ }
1971
+ }
1972
+ };
1973
+ function verdictToAuditEvent(event, verdict) {
1974
+ const auditEvent = {
1975
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
1976
+ worldId: verdict.evidence.worldId,
1977
+ worldName: verdict.evidence.worldName,
1978
+ worldVersion: verdict.evidence.worldVersion,
1979
+ intent: event.intent,
1980
+ tool: event.tool,
1981
+ scope: event.scope,
1982
+ actor: event.roleId,
1983
+ direction: event.direction,
1984
+ decision: verdict.status,
1985
+ reason: verdict.reason,
1986
+ ruleId: verdict.ruleId,
1987
+ warning: verdict.warning,
1988
+ guardsMatched: verdict.evidence.guardsMatched,
1989
+ rulesMatched: verdict.evidence.rulesMatched,
1990
+ invariantsSatisfied: verdict.evidence.invariantsSatisfied,
1991
+ invariantsTotal: verdict.evidence.invariantsTotal,
1992
+ enforcementLevel: verdict.evidence.enforcementLevel,
1993
+ durationMs: verdict.trace?.durationMs,
1994
+ args: event.args
1995
+ };
1996
+ if (verdict.consequence) {
1997
+ auditEvent.consequence = verdict.consequence;
1998
+ }
1999
+ if (verdict.reward) {
2000
+ auditEvent.reward = verdict.reward;
2001
+ }
2002
+ if (verdict.intentRecord) {
2003
+ auditEvent.originalIntent = verdict.intentRecord.originalIntent;
2004
+ auditEvent.finalAction = verdict.intentRecord.finalAction;
2005
+ }
2006
+ return auditEvent;
2007
+ }
2008
+
1920
2009
  // src/cli/run.ts
1921
2010
  function parseArg(args, flag) {
1922
2011
  const idx = args.indexOf(flag);
@@ -1991,8 +2080,15 @@ async function main(args) {
1991
2080
  const plan = planPath ? loadPlan(planPath) : autoDetectPlan();
1992
2081
  const level = parseArg(args, "--level");
1993
2082
  const trace = hasFlag(args, "--trace");
2083
+ const logPath = parseArg(args, "--log");
1994
2084
  const isPipeMode = hasFlag(args, "--pipe") || !process.stdin.isTTY;
1995
2085
  const isInteractive = hasFlag(args, "--interactive");
2086
+ let auditLogger;
2087
+ if (logPath) {
2088
+ auditLogger = new FileAuditLogger(logPath);
2089
+ process.stderr.write(`[neuroverse] Audit logging to ${logPath}
2090
+ `);
2091
+ }
1996
2092
  if (isInteractive) {
1997
2093
  const providerName = parseArg(args, "--provider");
1998
2094
  if (!providerName) {
@@ -2016,6 +2112,9 @@ async function main(args) {
2016
2112
  level,
2017
2113
  trace,
2018
2114
  onVerdict: (verdict, event) => {
2115
+ if (auditLogger) {
2116
+ auditLogger.log(verdictToAuditEvent(event, verdict));
2117
+ }
2019
2118
  if (verdict.status !== "ALLOW") {
2020
2119
  process.stderr.write(
2021
2120
  ` [${verdict.status}] ${event.intent} \u2014 ${verdict.reason ?? verdict.ruleId ?? "governance rule"}
@@ -2042,8 +2141,12 @@ async function main(args) {
2042
2141
  worldPath,
2043
2142
  plan,
2044
2143
  level,
2045
- trace
2144
+ trace,
2145
+ onVerdict: auditLogger ? (verdict, event) => {
2146
+ auditLogger.log(verdictToAuditEvent(event, verdict));
2147
+ } : void 0
2046
2148
  });
2149
+ if (auditLogger) await auditLogger.flush();
2047
2150
  } else {
2048
2151
  process.stdout.write(RUN_USAGE + "\n");
2049
2152
  process.exit(0);