@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.
Files changed (132) hide show
  1. package/.well-known/ai-plugin.json +34 -9
  2. package/AGENTS.md +72 -24
  3. package/README.md +343 -248
  4. package/dist/adapters/autoresearch.cjs +1345 -0
  5. package/dist/adapters/autoresearch.d.cts +111 -0
  6. package/dist/adapters/autoresearch.d.ts +111 -0
  7. package/dist/adapters/autoresearch.js +12 -0
  8. package/dist/adapters/deep-agents.cjs +1528 -0
  9. package/dist/adapters/deep-agents.d.cts +181 -0
  10. package/dist/adapters/deep-agents.d.ts +181 -0
  11. package/dist/adapters/deep-agents.js +17 -0
  12. package/dist/adapters/express.cjs +1253 -0
  13. package/dist/adapters/express.d.cts +66 -0
  14. package/dist/adapters/express.d.ts +66 -0
  15. package/dist/adapters/express.js +12 -0
  16. package/dist/adapters/index.cjs +2112 -0
  17. package/dist/adapters/index.d.cts +8 -0
  18. package/dist/adapters/index.d.ts +8 -0
  19. package/dist/adapters/index.js +68 -0
  20. package/dist/adapters/langchain.cjs +1315 -0
  21. package/dist/adapters/langchain.d.cts +89 -0
  22. package/dist/adapters/langchain.d.ts +89 -0
  23. package/dist/adapters/langchain.js +17 -0
  24. package/dist/adapters/openai.cjs +1345 -0
  25. package/dist/adapters/openai.d.cts +99 -0
  26. package/dist/adapters/openai.d.ts +99 -0
  27. package/dist/adapters/openai.js +17 -0
  28. package/dist/adapters/openclaw.cjs +1337 -0
  29. package/dist/adapters/openclaw.d.cts +99 -0
  30. package/dist/adapters/openclaw.d.ts +99 -0
  31. package/dist/adapters/openclaw.js +17 -0
  32. package/dist/add-ROOZLU62.js +314 -0
  33. package/dist/behavioral-MJO34S6Q.js +118 -0
  34. package/dist/bootstrap-CQRZVOXK.js +116 -0
  35. package/dist/bootstrap-emitter-Q7UIJZ2O.js +7 -0
  36. package/dist/bootstrap-parser-EEF36XDU.js +7 -0
  37. package/dist/browser.global.js +941 -0
  38. package/dist/build-QKOBBC23.js +341 -0
  39. package/dist/chunk-3WQLXYTP.js +91 -0
  40. package/dist/chunk-4FLICVVA.js +119 -0
  41. package/dist/chunk-4NGDRRQH.js +10 -0
  42. package/dist/chunk-5TPFNWRU.js +215 -0
  43. package/dist/chunk-5U2MQO5P.js +57 -0
  44. package/dist/chunk-6CZSKEY5.js +164 -0
  45. package/dist/chunk-6S5CFQXY.js +624 -0
  46. package/dist/chunk-7P3S7MAY.js +1090 -0
  47. package/dist/chunk-A5W4GNQO.js +130 -0
  48. package/dist/chunk-A7GKPPU7.js +226 -0
  49. package/dist/chunk-AKW5YVCE.js +96 -0
  50. package/dist/chunk-B6OXJLJ5.js +622 -0
  51. package/dist/chunk-BNKJPUPQ.js +113 -0
  52. package/dist/chunk-BQZMOEML.js +43 -0
  53. package/dist/chunk-CNSO6XW5.js +207 -0
  54. package/dist/chunk-CTZHONLA.js +135 -0
  55. package/dist/chunk-D2UCV5AK.js +326 -0
  56. package/dist/chunk-EMQDLDAF.js +458 -0
  57. package/dist/chunk-F66BVUYB.js +340 -0
  58. package/dist/chunk-G7DJ6VOD.js +101 -0
  59. package/dist/chunk-I3RRAYK2.js +11 -0
  60. package/dist/chunk-IS4WUH6Y.js +363 -0
  61. package/dist/chunk-MH7BT4VH.js +15 -0
  62. package/dist/chunk-O5ABKEA7.js +304 -0
  63. package/dist/chunk-OT6PXH54.js +61 -0
  64. package/dist/chunk-PVTQQS3Y.js +186 -0
  65. package/dist/chunk-Q6O7ZLO2.js +62 -0
  66. package/dist/chunk-QLPTHTVB.js +253 -0
  67. package/dist/chunk-QWGCMQQD.js +16 -0
  68. package/dist/chunk-QXBFT7NI.js +201 -0
  69. package/dist/chunk-TG6SEF24.js +246 -0
  70. package/dist/chunk-U6U7EJZL.js +177 -0
  71. package/dist/chunk-W7LLXRGY.js +830 -0
  72. package/dist/chunk-ZJTDUCC2.js +194 -0
  73. package/dist/chunk-ZWI3NIXK.js +314 -0
  74. package/dist/cli/neuroverse.cjs +14191 -0
  75. package/dist/cli/neuroverse.d.cts +1 -0
  76. package/dist/cli/neuroverse.d.ts +1 -0
  77. package/dist/cli/neuroverse.js +227 -0
  78. package/dist/cli/plan.cjs +2439 -0
  79. package/dist/cli/plan.d.cts +20 -0
  80. package/dist/cli/plan.d.ts +20 -0
  81. package/dist/cli/plan.js +353 -0
  82. package/dist/cli/run.cjs +2001 -0
  83. package/dist/cli/run.d.cts +20 -0
  84. package/dist/cli/run.d.ts +20 -0
  85. package/dist/cli/run.js +143 -0
  86. package/dist/configure-ai-6TZ3MCSI.js +132 -0
  87. package/dist/decision-flow-M63D47LO.js +61 -0
  88. package/dist/demo-G43RLCPK.js +469 -0
  89. package/dist/derive-FJZVIPUZ.js +153 -0
  90. package/dist/doctor-6BC6X2VO.js +173 -0
  91. package/dist/equity-penalties-SG5IZQ7I.js +244 -0
  92. package/dist/explain-RHBU2GBR.js +51 -0
  93. package/dist/guard-AJCCGZMF.js +92 -0
  94. package/dist/guard-contract-DqFcTScd.d.cts +821 -0
  95. package/dist/guard-contract-DqFcTScd.d.ts +821 -0
  96. package/dist/guard-engine-PNR6MHCM.js +10 -0
  97. package/dist/impact-3XVDSCBU.js +59 -0
  98. package/dist/improve-TQP4ECSY.js +66 -0
  99. package/dist/index.cjs +7591 -0
  100. package/dist/index.d.cts +2195 -0
  101. package/dist/index.d.ts +2195 -0
  102. package/dist/index.js +472 -0
  103. package/dist/infer-world-IFXCACJ5.js +543 -0
  104. package/dist/init-FYPV4SST.js +144 -0
  105. package/dist/init-world-TI7ARHBT.js +223 -0
  106. package/dist/mcp-server-5Y3ZM7TV.js +13 -0
  107. package/dist/model-adapter-VXEKB4LS.js +11 -0
  108. package/dist/playground-VZBNPPBO.js +560 -0
  109. package/dist/redteam-MZPZD3EF.js +357 -0
  110. package/dist/session-JYOARW54.js +15 -0
  111. package/dist/shared-7RLUHNMU.js +16 -0
  112. package/dist/shared-B8dvUUD8.d.cts +60 -0
  113. package/dist/shared-Dr5Wiay8.d.ts +60 -0
  114. package/dist/simulate-LJXYBC6M.js +83 -0
  115. package/dist/test-BOOR4A5F.js +217 -0
  116. package/dist/trace-PKV4KX56.js +166 -0
  117. package/dist/validate-RALX7CZS.js +81 -0
  118. package/dist/validate-engine-7ZXFVGF2.js +7 -0
  119. package/dist/viz/assets/index-B8SaeJZZ.js +23 -0
  120. package/dist/viz/index.html +23 -0
  121. package/dist/world-BIP4GZBZ.js +376 -0
  122. package/dist/world-loader-Y6HMQH2D.js +13 -0
  123. package/dist/worlds/autoresearch.nv-world.md +230 -0
  124. package/dist/worlds/coding-agent.nv-world.md +211 -0
  125. package/dist/worlds/derivation-world.nv-world.md +278 -0
  126. package/dist/worlds/research-agent.nv-world.md +169 -0
  127. package/dist/worlds/social-media.nv-world.md +198 -0
  128. package/dist/worlds/trading-agent.nv-world.md +218 -0
  129. package/examples/social-media-sim/bridge.py +209 -0
  130. package/examples/social-media-sim/simulation.py +927 -0
  131. package/package.json +16 -3
  132. package/simulate.html +4 -336
@@ -0,0 +1,201 @@
1
+ import {
2
+ evaluateGuard
3
+ } from "./chunk-W7LLXRGY.js";
4
+ import {
5
+ loadWorldFromDirectory
6
+ } from "./chunk-CTZHONLA.js";
7
+
8
+ // src/adapters/autoresearch.ts
9
+ var AutoresearchGovernor = class {
10
+ config;
11
+ state;
12
+ world;
13
+ engineOptions;
14
+ constructor(config) {
15
+ this.config = config;
16
+ this.world = config.world;
17
+ this.engineOptions = { trace: true };
18
+ this.state = {
19
+ experiments_run: 0,
20
+ best_result: null,
21
+ architectures_tested: [],
22
+ experiment_log: [],
23
+ total_compute_minutes: 0,
24
+ keep_count: 0
25
+ };
26
+ }
27
+ /**
28
+ * Convert an experiment proposal into a GuardEvent for governance evaluation.
29
+ */
30
+ proposalToGuardEvent(proposal) {
31
+ return {
32
+ intent: `run experiment: ${proposal.description}`,
33
+ tool: "experiment_runner",
34
+ scope: "experiment",
35
+ roleId: "experiment_runner",
36
+ direction: "output",
37
+ actionCategory: "shell",
38
+ args: {
39
+ experiment_id: String(proposal.experiment_id),
40
+ architecture: proposal.architecture,
41
+ estimated_minutes: String(proposal.estimated_minutes || 5)
42
+ }
43
+ };
44
+ }
45
+ /**
46
+ * Evaluate an experiment proposal against governance rules.
47
+ * Routes through the guard engine when a world is loaded,
48
+ * then layers on research-specific checks (budget, constraints, drift).
49
+ */
50
+ evaluateProposal(proposal) {
51
+ const warnings = [];
52
+ const event = this.proposalToGuardEvent(proposal);
53
+ if (this.world) {
54
+ const verdict = evaluateGuard(event, this.world, this.engineOptions);
55
+ if (verdict.status === "BLOCK" || verdict.status === "PAUSE") {
56
+ return {
57
+ allowed: false,
58
+ reason: verdict.reason ?? `Governance ${verdict.status}: ${verdict.ruleId ?? "unknown rule"}`,
59
+ warnings,
60
+ verdict
61
+ };
62
+ }
63
+ }
64
+ const estimatedMinutes = proposal.estimated_minutes || 5;
65
+ if (this.state.total_compute_minutes + estimatedMinutes > this.config.computeBudgetMinutes) {
66
+ return {
67
+ allowed: false,
68
+ reason: `Compute budget exhausted: ${this.state.total_compute_minutes}/${this.config.computeBudgetMinutes} minutes used`,
69
+ warnings
70
+ };
71
+ }
72
+ if (this.config.constraints) {
73
+ for (const constraint of this.config.constraints) {
74
+ const lower = constraint.toLowerCase();
75
+ const archLower = proposal.architecture.toLowerCase();
76
+ const descLower = proposal.description.toLowerCase();
77
+ if (lower.startsWith("no ")) {
78
+ const forbidden = lower.slice(3).trim();
79
+ if (archLower.includes(forbidden) || descLower.includes(forbidden)) {
80
+ return {
81
+ allowed: false,
82
+ reason: `Architecture constraint violated: ${constraint}`,
83
+ warnings
84
+ };
85
+ }
86
+ }
87
+ }
88
+ }
89
+ const failureCount = this.state.experiment_log.filter((e) => !e.success).length;
90
+ if (failureCount > 5) {
91
+ warnings.push(`High failure rate: ${failureCount} failed experiments. Consider investigating root cause.`);
92
+ }
93
+ const recentArchitectures = this.state.experiment_log.slice(-5).map((e) => e.architecture);
94
+ const uniqueRecent = new Set(recentArchitectures).size;
95
+ if (recentArchitectures.length >= 5 && uniqueRecent === 1) {
96
+ warnings.push("Research may be stuck: last 5 experiments used the same architecture.");
97
+ }
98
+ return { allowed: true, reason: "Experiment approved", warnings };
99
+ }
100
+ /**
101
+ * Record an experiment result and update research state.
102
+ */
103
+ recordResult(result) {
104
+ this.state.experiments_run++;
105
+ this.state.total_compute_minutes += result.wall_clock_minutes;
106
+ this.state.experiment_log.push(result);
107
+ if (!this.state.architectures_tested.includes(result.architecture)) {
108
+ this.state.architectures_tested.push(result.architecture);
109
+ }
110
+ if (!result.success) {
111
+ return { kept: false, improvement: null, state: { ...this.state } };
112
+ }
113
+ let kept = false;
114
+ let improvement = null;
115
+ if (this.state.best_result === null) {
116
+ kept = true;
117
+ this.state.best_result = result;
118
+ this.state.keep_count++;
119
+ } else {
120
+ const prev = this.state.best_result.metric_value;
121
+ const curr = result.metric_value;
122
+ if (this.config.optimize === "minimize") {
123
+ kept = curr < prev;
124
+ improvement = kept ? prev - curr : null;
125
+ } else {
126
+ kept = curr > prev;
127
+ improvement = kept ? curr - prev : null;
128
+ }
129
+ if (kept) {
130
+ this.state.best_result = result;
131
+ this.state.keep_count++;
132
+ }
133
+ }
134
+ return { kept, improvement, state: { ...this.state } };
135
+ }
136
+ /**
137
+ * Export current state as a state snapshot compatible with the world file.
138
+ */
139
+ toWorldState() {
140
+ const successfulExperiments = this.state.experiment_log.filter((e) => e.success);
141
+ const failedCount = this.state.experiment_log.filter((e) => !e.success).length;
142
+ const keepRate = this.state.experiments_run > 0 ? Math.round(this.state.keep_count / this.state.experiments_run * 100) : 0;
143
+ let improvementRate = 0;
144
+ if (successfulExperiments.length >= 2) {
145
+ const recent = successfulExperiments.slice(-10);
146
+ let improvements = 0;
147
+ for (let i = 1; i < recent.length; i++) {
148
+ const prev = recent[i - 1].metric_value;
149
+ const curr = recent[i].metric_value;
150
+ if (this.config.optimize === "minimize" ? curr < prev : curr > prev) {
151
+ improvements++;
152
+ }
153
+ }
154
+ improvementRate = Math.round(improvements / (recent.length - 1) * 100);
155
+ }
156
+ return {
157
+ experiments_run: this.state.experiments_run,
158
+ best_metric_value: this.state.best_result?.metric_value ?? (this.config.optimize === "minimize" ? 100 : -1e3),
159
+ keep_rate: keepRate,
160
+ compute_used_minutes: Math.round(this.state.total_compute_minutes),
161
+ compute_budget_minutes: this.config.computeBudgetMinutes,
162
+ failed_experiments: failedCount,
163
+ metric_improvement_rate: improvementRate,
164
+ research_context_drift: 0
165
+ // would need NLP to compute properly
166
+ };
167
+ }
168
+ /**
169
+ * Get a summary of the current research state.
170
+ */
171
+ getSummary() {
172
+ return {
173
+ experiments_run: this.state.experiments_run,
174
+ best_result: this.state.best_result,
175
+ keep_rate: this.state.experiments_run > 0 ? Math.round(this.state.keep_count / this.state.experiments_run * 100) : 0,
176
+ compute_remaining_minutes: this.config.computeBudgetMinutes - this.state.total_compute_minutes,
177
+ architectures_tested: [...this.state.architectures_tested]
178
+ };
179
+ }
180
+ /**
181
+ * Load state from a persisted research context file.
182
+ */
183
+ loadState(state) {
184
+ this.state = { ...state };
185
+ }
186
+ /**
187
+ * Export state for persistence.
188
+ */
189
+ exportState() {
190
+ return { ...this.state };
191
+ }
192
+ };
193
+ async function createAutoresearchGovernor(worldPath, config) {
194
+ const world = await loadWorldFromDirectory(worldPath);
195
+ return new AutoresearchGovernor({ ...config, world, worldPath });
196
+ }
197
+
198
+ export {
199
+ AutoresearchGovernor,
200
+ createAutoresearchGovernor
201
+ };
@@ -0,0 +1,246 @@
1
+ import {
2
+ readAuditLog
3
+ } from "./chunk-A7GKPPU7.js";
4
+
5
+ // src/engine/impact-report.ts
6
+ function generateImpactReport(events) {
7
+ if (events.length === 0) {
8
+ return emptyReport();
9
+ }
10
+ const blocked = events.filter((e) => e.decision === "BLOCK");
11
+ const paused = events.filter((e) => e.decision === "PAUSE");
12
+ const modified = events.filter((e) => e.decision === "MODIFY");
13
+ const penalized = events.filter((e) => e.decision === "PENALIZE");
14
+ const rewarded = events.filter((e) => e.decision === "REWARD");
15
+ const neutralEvents = events.filter((e) => e.decision === "NEUTRAL");
16
+ const prevented = [...blocked, ...paused, ...modified, ...penalized];
17
+ const categoryMap = /* @__PURE__ */ new Map();
18
+ for (const e of prevented) {
19
+ const cat = classifyPreventionCategory(e);
20
+ if (!categoryMap.has(cat)) categoryMap.set(cat, /* @__PURE__ */ new Set());
21
+ categoryMap.get(cat).add(e.intent);
22
+ }
23
+ const preventedByCategory = [...categoryMap.entries()].map(([category, intents]) => ({
24
+ category,
25
+ count: prevented.filter((e) => classifyPreventionCategory(e) === category).length,
26
+ examples: [...intents].slice(0, 5)
27
+ })).sort((a, b) => b.count - a.count);
28
+ const intentMap = /* @__PURE__ */ new Map();
29
+ for (const e of prevented) {
30
+ const entry = intentMap.get(e.intent) ?? { count: 0, rules: /* @__PURE__ */ new Map() };
31
+ entry.count++;
32
+ if (e.ruleId) {
33
+ entry.rules.set(e.ruleId, (entry.rules.get(e.ruleId) ?? 0) + 1);
34
+ }
35
+ for (const g of e.guardsMatched) {
36
+ entry.rules.set(g, (entry.rules.get(g) ?? 0) + 1);
37
+ }
38
+ intentMap.set(e.intent, entry);
39
+ }
40
+ const topPreventedIntents = [...intentMap.entries()].map(([intent, data]) => {
41
+ let topRule = "";
42
+ let topCount = 0;
43
+ for (const [rule, count] of data.rules) {
44
+ if (count > topCount) {
45
+ topRule = rule;
46
+ topCount = count;
47
+ }
48
+ }
49
+ return { intent, count: data.count, topRule };
50
+ }).sort((a, b) => b.count - a.count).slice(0, 15);
51
+ const actorMap = /* @__PURE__ */ new Map();
52
+ for (const e of events) {
53
+ const actor = e.actor ?? "unknown";
54
+ const entry = actorMap.get(actor) ?? { blocked: 0, paused: 0, total: 0 };
55
+ entry.total++;
56
+ if (e.decision === "BLOCK") entry.blocked++;
57
+ if (e.decision === "PAUSE") entry.paused++;
58
+ actorMap.set(actor, entry);
59
+ }
60
+ const hotActors = [...actorMap.entries()].filter(([, data]) => data.blocked > 0 || data.paused > 0).map(([actor, data]) => ({ actor, ...data })).sort((a, b) => b.blocked + b.paused - (a.blocked + a.paused)).slice(0, 10);
61
+ const ruleMap = /* @__PURE__ */ new Map();
62
+ for (const e of prevented) {
63
+ const ruleIds = [e.ruleId, ...e.guardsMatched, ...e.rulesMatched].filter(Boolean);
64
+ for (const rId of new Set(ruleIds)) {
65
+ const entry = ruleMap.get(rId) ?? { blockCount: 0, pauseCount: 0 };
66
+ if (e.decision === "BLOCK") entry.blockCount++;
67
+ if (e.decision === "PAUSE") entry.pauseCount++;
68
+ ruleMap.set(rId, entry);
69
+ }
70
+ }
71
+ const mostActiveRules = [...ruleMap.entries()].map(([ruleId, data]) => ({ ruleId, ...data })).sort((a, b) => b.blockCount + b.pauseCount - (a.blockCount + a.pauseCount)).slice(0, 10);
72
+ const hourMap = /* @__PURE__ */ new Map();
73
+ for (const e of events) {
74
+ const hour = new Date(e.timestamp).getHours();
75
+ const entry = hourMap.get(hour) ?? { total: 0, blocked: 0 };
76
+ entry.total++;
77
+ if (e.decision === "BLOCK") entry.blocked++;
78
+ hourMap.set(hour, entry);
79
+ }
80
+ const hourlyDistribution = Array.from({ length: 24 }, (_, hour) => ({
81
+ hour,
82
+ total: hourMap.get(hour)?.total ?? 0,
83
+ blocked: hourMap.get(hour)?.blocked ?? 0
84
+ }));
85
+ const violationKey = (e) => `${e.actor ?? "unknown"}::${e.intent}`;
86
+ const violationMap = /* @__PURE__ */ new Map();
87
+ for (const e of blocked) {
88
+ const key = violationKey(e);
89
+ const entry = violationMap.get(key) ?? {
90
+ intent: e.intent,
91
+ actor: e.actor ?? "unknown",
92
+ attempts: 0,
93
+ firstSeen: e.timestamp,
94
+ lastSeen: e.timestamp
95
+ };
96
+ entry.attempts++;
97
+ entry.lastSeen = e.timestamp;
98
+ violationMap.set(key, entry);
99
+ }
100
+ const repeatViolations = [...violationMap.values()].filter((v) => v.attempts > 1).sort((a, b) => b.attempts - a.attempts).slice(0, 10);
101
+ const allowedCount = events.filter((e) => e.decision === "ALLOW").length;
102
+ const redirected = events.length - allowedCount - neutralEvents.length;
103
+ return {
104
+ generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
105
+ periodStart: events[0].timestamp,
106
+ periodEnd: events[events.length - 1].timestamp,
107
+ worldName: events[0].worldName ?? "unknown",
108
+ totalEvaluations: events.length,
109
+ totalBlocked: blocked.length,
110
+ totalPaused: paused.length,
111
+ totalAllowed: allowedCount,
112
+ totalModified: modified.length,
113
+ totalPenalized: penalized.length,
114
+ totalRewarded: rewarded.length,
115
+ totalNeutral: neutralEvents.length,
116
+ preventionRate: events.length > 0 ? prevented.length / events.length : 0,
117
+ redirectionRate: events.length > 0 ? redirected / events.length : 0,
118
+ preventedByCategory,
119
+ topPreventedIntents,
120
+ hotActors,
121
+ mostActiveRules,
122
+ hourlyDistribution,
123
+ repeatViolations
124
+ };
125
+ }
126
+ function classifyPreventionCategory(event) {
127
+ const intent = event.intent.toLowerCase();
128
+ const rule = (event.ruleId ?? "").toLowerCase();
129
+ const combined = `${intent} ${rule}`;
130
+ if (combined.match(/inject|prompt|jailbreak|bypass/)) return "Prompt Injection Prevention";
131
+ if (combined.match(/scope|escape|traversal|path/)) return "Scope Escape Prevention";
132
+ if (combined.match(/delete|drop|destroy|remove|purge/)) return "Destructive Action Prevention";
133
+ if (combined.match(/trade|margin|position|leverage/)) return "Financial Risk Prevention";
134
+ if (combined.match(/withdraw|transfer|payment|fund/)) return "Unauthorized Transfer Prevention";
135
+ if (combined.match(/credential|secret|key|password|token/)) return "Credential Access Prevention";
136
+ if (combined.match(/shell|exec|command|script/)) return "Command Execution Prevention";
137
+ if (combined.match(/network|http|api|external/)) return "Network Access Prevention";
138
+ if (combined.match(/write|modify|update|alter/)) return "Unauthorized Modification Prevention";
139
+ if (combined.match(/approval|review|confirm/)) return "Approval Gate";
140
+ return "Policy Violation Prevention";
141
+ }
142
+ function renderImpactReport(report) {
143
+ const lines = [];
144
+ lines.push("GOVERNANCE IMPACT REPORT");
145
+ lines.push("\u2550".repeat(50));
146
+ lines.push("");
147
+ lines.push(` World: ${report.worldName}`);
148
+ lines.push(` Period: ${report.periodStart.split("T")[0]} \u2192 ${report.periodEnd.split("T")[0]}`);
149
+ lines.push(` Generated: ${report.generatedAt}`);
150
+ lines.push("");
151
+ lines.push("SUMMARY");
152
+ lines.push("\u2500".repeat(50));
153
+ lines.push(` Total evaluations: ${report.totalEvaluations}`);
154
+ lines.push(` Allowed: ${report.totalAllowed}`);
155
+ lines.push(` Blocked: ${report.totalBlocked}`);
156
+ lines.push(` Modified: ${report.totalModified}`);
157
+ lines.push(` Paused: ${report.totalPaused}`);
158
+ lines.push(` Penalized: ${report.totalPenalized}`);
159
+ lines.push(` Rewarded: ${report.totalRewarded}`);
160
+ lines.push(` Neutral: ${report.totalNeutral}`);
161
+ lines.push(` Prevention rate: ${(report.preventionRate * 100).toFixed(1)}%`);
162
+ lines.push(` Redirection rate: ${(report.redirectionRate * 100).toFixed(1)}%`);
163
+ lines.push("");
164
+ if (report.totalBlocked > 0 || report.totalPaused > 0) {
165
+ lines.push("WITHOUT GOVERNANCE");
166
+ lines.push("\u2500".repeat(50));
167
+ lines.push(` ${report.totalBlocked + report.totalPaused} actions would have executed unchecked:`);
168
+ for (const cat of report.preventedByCategory) {
169
+ lines.push(` ${cat.category.padEnd(38)} ${String(cat.count).padStart(5)}`);
170
+ if (cat.examples.length > 0) {
171
+ lines.push(` e.g. ${cat.examples.slice(0, 3).join(", ")}`);
172
+ }
173
+ }
174
+ lines.push("");
175
+ }
176
+ if (report.topPreventedIntents.length > 0) {
177
+ lines.push("TOP PREVENTED ACTIONS");
178
+ lines.push("\u2500".repeat(50));
179
+ for (const entry of report.topPreventedIntents.slice(0, 10)) {
180
+ lines.push(` ${entry.intent.padEnd(30)} ${String(entry.count).padStart(5)} (rule: ${entry.topRule || "\u2014"})`);
181
+ }
182
+ lines.push("");
183
+ }
184
+ if (report.hotActors.length > 0) {
185
+ lines.push("ACTORS WITH MOST VIOLATIONS");
186
+ lines.push("\u2500".repeat(50));
187
+ for (const actor of report.hotActors) {
188
+ const violations = actor.blocked + actor.paused;
189
+ const rate = (violations / actor.total * 100).toFixed(0);
190
+ lines.push(` ${actor.actor.padEnd(25)} ${String(violations).padStart(5)} violations / ${actor.total} total (${rate}%)`);
191
+ }
192
+ lines.push("");
193
+ }
194
+ if (report.mostActiveRules.length > 0) {
195
+ lines.push("MOST ACTIVE RULES");
196
+ lines.push("\u2500".repeat(50));
197
+ for (const rule of report.mostActiveRules) {
198
+ lines.push(` ${rule.ruleId.padEnd(30)} ${String(rule.blockCount).padStart(5)} blocked ${String(rule.pauseCount).padStart(5)} paused`);
199
+ }
200
+ lines.push("");
201
+ }
202
+ if (report.repeatViolations.length > 0) {
203
+ lines.push("REPEAT VIOLATIONS");
204
+ lines.push("\u2500".repeat(50));
205
+ lines.push(" Actions attempted multiple times after being blocked:");
206
+ for (const v of report.repeatViolations) {
207
+ lines.push(` ${v.actor.padEnd(20)} ${v.intent.padEnd(25)} ${v.attempts}x (${v.firstSeen.split("T")[0]} \u2192 ${v.lastSeen.split("T")[0]})`);
208
+ }
209
+ lines.push("");
210
+ }
211
+ return lines.join("\n");
212
+ }
213
+ async function generateImpactReportFromFile(logPath) {
214
+ const events = await readAuditLog(logPath);
215
+ return generateImpactReport(events);
216
+ }
217
+ function emptyReport() {
218
+ return {
219
+ generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
220
+ periodStart: "",
221
+ periodEnd: "",
222
+ worldName: "unknown",
223
+ totalEvaluations: 0,
224
+ totalBlocked: 0,
225
+ totalPaused: 0,
226
+ totalAllowed: 0,
227
+ totalModified: 0,
228
+ totalPenalized: 0,
229
+ totalRewarded: 0,
230
+ totalNeutral: 0,
231
+ preventionRate: 0,
232
+ redirectionRate: 0,
233
+ preventedByCategory: [],
234
+ topPreventedIntents: [],
235
+ hotActors: [],
236
+ mostActiveRules: [],
237
+ hourlyDistribution: [],
238
+ repeatViolations: []
239
+ };
240
+ }
241
+
242
+ export {
243
+ generateImpactReport,
244
+ renderImpactReport,
245
+ generateImpactReportFromFile
246
+ };
@@ -0,0 +1,177 @@
1
+ import {
2
+ evaluateGuard
3
+ } from "./chunk-W7LLXRGY.js";
4
+ import {
5
+ loadWorld
6
+ } from "./chunk-CTZHONLA.js";
7
+
8
+ // src/runtime/govern.ts
9
+ function actionToGuardEvent(action) {
10
+ return {
11
+ intent: action.description,
12
+ tool: action.type,
13
+ roleId: action.agentId,
14
+ riskLevel: magnitudeToRisk(action.magnitude),
15
+ args: action.context
16
+ };
17
+ }
18
+ function magnitudeToRisk(magnitude) {
19
+ if (magnitude === void 0) return void 0;
20
+ if (magnitude < 0.25) return "low";
21
+ if (magnitude < 0.5) return "medium";
22
+ if (magnitude < 0.75) return "high";
23
+ return "critical";
24
+ }
25
+ function govern(action, world, options) {
26
+ const event = actionToGuardEvent(action);
27
+ return evaluateGuard(event, world, options);
28
+ }
29
+ async function createGovernor(config) {
30
+ const worldPath = config.worldPath;
31
+ if (!worldPath) {
32
+ throw new Error("Governor requires a worldPath");
33
+ }
34
+ const options = {
35
+ trace: config.trace,
36
+ level: config.level
37
+ };
38
+ let world = await loadWorld(worldPath);
39
+ return {
40
+ evaluate(action) {
41
+ return govern(action, world, options);
42
+ },
43
+ async reload() {
44
+ world = await loadWorld(worldPath);
45
+ },
46
+ get world() {
47
+ return world;
48
+ }
49
+ };
50
+ }
51
+ async function writeTempWorld(dir, policyLines) {
52
+ const { writeFile, mkdir } = await import("fs/promises");
53
+ const { join } = await import("path");
54
+ await mkdir(dir, { recursive: true });
55
+ const worldJson = {
56
+ world_id: "demo-live",
57
+ name: "Live Demo World",
58
+ thesis: "Interactive governance demo",
59
+ version: "0.1.0",
60
+ runtime_mode: "COMPLIANCE",
61
+ default_assumption_profile: "baseline",
62
+ default_alternative_profile: "baseline",
63
+ modules: [],
64
+ players: { thinking_space: false, experience_space: false, action_space: true }
65
+ };
66
+ const forbiddenPatterns = policyLines.filter((line) => line.trim().length > 0).map((line, i) => ({
67
+ id: `demo-rule-${i + 1}`,
68
+ pattern: line.trim(),
69
+ reason: line.trim(),
70
+ action: "BLOCK"
71
+ }));
72
+ const kernelJson = {
73
+ artifact_type: "kernel",
74
+ kernel_id: "demo-kernel",
75
+ version: "0.1.0",
76
+ domain: "demo",
77
+ enforcement_level: "standard",
78
+ input_boundaries: { forbidden_patterns: forbiddenPatterns },
79
+ output_boundaries: { forbidden_patterns: [] },
80
+ response_vocabulary: {},
81
+ metadata: {
82
+ compiled_by: "neuroverse-demo",
83
+ compiled_at: (/* @__PURE__ */ new Date()).toISOString(),
84
+ source_hash: "live-edit",
85
+ compiler_version: "0.2.2"
86
+ }
87
+ };
88
+ const metadataJson = {
89
+ format_version: "1.0.0",
90
+ created_at: (/* @__PURE__ */ new Date()).toISOString(),
91
+ last_modified: (/* @__PURE__ */ new Date()).toISOString(),
92
+ authoring_method: "manual-authoring"
93
+ };
94
+ await Promise.all([
95
+ writeFile(join(dir, "world.json"), JSON.stringify(worldJson, null, 2)),
96
+ writeFile(join(dir, "kernel.json"), JSON.stringify(kernelJson, null, 2)),
97
+ writeFile(join(dir, "metadata.json"), JSON.stringify(metadataJson, null, 2))
98
+ ]);
99
+ }
100
+
101
+ // src/engine/api.ts
102
+ function handleHealthCheck() {
103
+ return {
104
+ status: "ok",
105
+ engine: "@neuroverseos/governance",
106
+ version: "0.2.2",
107
+ capabilities: [
108
+ "guard",
109
+ "simulate",
110
+ "validate",
111
+ "bootstrap",
112
+ "decision-flow",
113
+ "impact-report",
114
+ "behavioral-analysis"
115
+ ]
116
+ };
117
+ }
118
+ async function handleListPresets(policiesDir) {
119
+ const { readdir, readFile } = await import("fs/promises");
120
+ const { join } = await import("path");
121
+ const dir = policiesDir ?? join(process.cwd(), "policies");
122
+ const presets = [];
123
+ try {
124
+ const files = await readdir(dir);
125
+ for (const file of files.filter((f) => f.endsWith(".txt")).sort()) {
126
+ const content = await readFile(join(dir, file), "utf-8");
127
+ const id = file.replace(".txt", "");
128
+ const name = id.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
129
+ const firstLine = content.split("\n").find((l) => l.trim().length > 0) ?? "";
130
+ presets.push({ id, name, description: firstLine, rules: content });
131
+ }
132
+ } catch {
133
+ }
134
+ return { presets };
135
+ }
136
+ async function handleReasonRequest(body) {
137
+ const intent = body.intent ?? body.scenario;
138
+ if (!intent) {
139
+ return { status: "error", error: "intent or scenario is required" };
140
+ }
141
+ const event = {
142
+ intent,
143
+ tool: body.tool,
144
+ roleId: body.roleId
145
+ };
146
+ if (body.worldPath) {
147
+ try {
148
+ const world = await loadWorld(body.worldPath);
149
+ const verdict = evaluateGuard(event, world);
150
+ return { status: "ok", verdict };
151
+ } catch (err) {
152
+ return { status: "error", error: `Failed to load world: ${err}` };
153
+ }
154
+ }
155
+ return { status: "error", error: "worldPath is required" };
156
+ }
157
+ function handleCreateCapsule(body) {
158
+ const capsuleId = `cap_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;
159
+ return {
160
+ capsuleId,
161
+ scenario: body.scenario ?? "Untitled scenario",
162
+ rules: body.rules ?? [],
163
+ events: body.events ?? [],
164
+ createdAt: (/* @__PURE__ */ new Date()).toISOString()
165
+ };
166
+ }
167
+
168
+ export {
169
+ actionToGuardEvent,
170
+ govern,
171
+ createGovernor,
172
+ writeTempWorld,
173
+ handleHealthCheck,
174
+ handleListPresets,
175
+ handleReasonRequest,
176
+ handleCreateCapsule
177
+ };