@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
@@ -0,0 +1,60 @@
1
+ import { WorldDefinition, GovernanceEvent } from '../types.cjs';
2
+ import { a as GuardEvent, b as GuardEngineOptions, G as GuardVerdict, d as GuardStatus } from '../guard-contract-ddiIPlOg.cjs';
3
+
4
+ /**
5
+ * Guard Engine — Deterministic Governance Evaluator
6
+ *
7
+ * Pure function: (event, world, options) → verdict
8
+ *
9
+ * Evaluates a GuardEvent against a loaded WorldDefinition and produces
10
+ * a GuardVerdict with evidence and optional evaluation trace.
11
+ *
12
+ * Evaluation chain (first-match-wins on BLOCK/PAUSE):
13
+ * 1. Safety checks (prompt injection, scope escape) → PAUSE
14
+ * 1.5 Plan enforcement (task scope) → BLOCK/PAUSE
15
+ * 2. Role-specific rules (cannotDo, requiresApproval) → BLOCK/PAUSE
16
+ * 3. Declarative guards (guards.json) → BLOCK/PAUSE/WARN
17
+ * 4. Kernel rules (kernel.json forbidden patterns) → BLOCK
18
+ * 5. Level constraints (basic/standard/strict) → PAUSE
19
+ * 6. Default → ALLOW
20
+ *
21
+ * Invariant checks run unconditionally and are recorded in evidence
22
+ * but do not produce verdicts — they measure world health.
23
+ *
24
+ * INVARIANTS:
25
+ * - Deterministic: same event + same world → same verdict.
26
+ * - Zero network calls. Zero LLM calls. Zero async.
27
+ * - Every check is recorded in the trace, not just the decider.
28
+ * - No hidden logic. Everything is in the world file or declared here.
29
+ */
30
+
31
+ declare function evaluateGuard(event: GuardEvent, world: WorldDefinition, options?: GuardEngineOptions): GuardVerdict;
32
+ /**
33
+ * Build a normalized allowlist key from a GuardEvent.
34
+ *
35
+ * Format: `tool::intent` (both lowercased, intent trimmed).
36
+ * Tool defaults to '*' when absent.
37
+ *
38
+ * Callers use this to:
39
+ * 1. Add keys to the allowlist set (on user "allow-always" decision)
40
+ * 2. The engine uses it to check membership before evaluation
41
+ *
42
+ * The key is opaque — callers should always use this function
43
+ * rather than constructing keys manually.
44
+ */
45
+ declare function eventToAllowlistKey(event: GuardEvent): string;
46
+ /**
47
+ * Convert a guard verdict into a GovernanceEvent.
48
+ *
49
+ * The guard evaluation log IS the event stream.
50
+ * No Kafka, no queues — just data flowing from Guard → Simulate.
51
+ *
52
+ * Mapping:
53
+ * ALLOW → "action_allowed"
54
+ * BLOCK → "action_blocked"
55
+ * PAUSE → "action_paused"
56
+ * + semantic type from intent when available
57
+ */
58
+ declare function verdictToEvent(status: GuardStatus, intent?: string): GovernanceEvent;
59
+
60
+ export { evaluateGuard, eventToAllowlistKey, verdictToEvent };
@@ -0,0 +1,60 @@
1
+ import { WorldDefinition, GovernanceEvent } from '../types.js';
2
+ import { a as GuardEvent, b as GuardEngineOptions, G as GuardVerdict, d as GuardStatus } from '../guard-contract-q6HJAq3Q.js';
3
+
4
+ /**
5
+ * Guard Engine — Deterministic Governance Evaluator
6
+ *
7
+ * Pure function: (event, world, options) → verdict
8
+ *
9
+ * Evaluates a GuardEvent against a loaded WorldDefinition and produces
10
+ * a GuardVerdict with evidence and optional evaluation trace.
11
+ *
12
+ * Evaluation chain (first-match-wins on BLOCK/PAUSE):
13
+ * 1. Safety checks (prompt injection, scope escape) → PAUSE
14
+ * 1.5 Plan enforcement (task scope) → BLOCK/PAUSE
15
+ * 2. Role-specific rules (cannotDo, requiresApproval) → BLOCK/PAUSE
16
+ * 3. Declarative guards (guards.json) → BLOCK/PAUSE/WARN
17
+ * 4. Kernel rules (kernel.json forbidden patterns) → BLOCK
18
+ * 5. Level constraints (basic/standard/strict) → PAUSE
19
+ * 6. Default → ALLOW
20
+ *
21
+ * Invariant checks run unconditionally and are recorded in evidence
22
+ * but do not produce verdicts — they measure world health.
23
+ *
24
+ * INVARIANTS:
25
+ * - Deterministic: same event + same world → same verdict.
26
+ * - Zero network calls. Zero LLM calls. Zero async.
27
+ * - Every check is recorded in the trace, not just the decider.
28
+ * - No hidden logic. Everything is in the world file or declared here.
29
+ */
30
+
31
+ declare function evaluateGuard(event: GuardEvent, world: WorldDefinition, options?: GuardEngineOptions): GuardVerdict;
32
+ /**
33
+ * Build a normalized allowlist key from a GuardEvent.
34
+ *
35
+ * Format: `tool::intent` (both lowercased, intent trimmed).
36
+ * Tool defaults to '*' when absent.
37
+ *
38
+ * Callers use this to:
39
+ * 1. Add keys to the allowlist set (on user "allow-always" decision)
40
+ * 2. The engine uses it to check membership before evaluation
41
+ *
42
+ * The key is opaque — callers should always use this function
43
+ * rather than constructing keys manually.
44
+ */
45
+ declare function eventToAllowlistKey(event: GuardEvent): string;
46
+ /**
47
+ * Convert a guard verdict into a GovernanceEvent.
48
+ *
49
+ * The guard evaluation log IS the event stream.
50
+ * No Kafka, no queues — just data flowing from Guard → Simulate.
51
+ *
52
+ * Mapping:
53
+ * ALLOW → "action_allowed"
54
+ * BLOCK → "action_blocked"
55
+ * PAUSE → "action_paused"
56
+ * + semantic type from intent when available
57
+ */
58
+ declare function verdictToEvent(status: GuardStatus, intent?: string): GovernanceEvent;
59
+
60
+ export { evaluateGuard, eventToAllowlistKey, verdictToEvent };
@@ -2,9 +2,9 @@ import {
2
2
  evaluateGuard,
3
3
  eventToAllowlistKey,
4
4
  verdictToEvent
5
- } from "./chunk-ZAF6JH23.js";
6
- import "./chunk-QLPTHTVB.js";
7
- import "./chunk-QWGCMQQD.js";
5
+ } from "../chunk-ZAF6JH23.js";
6
+ import "../chunk-QLPTHTVB.js";
7
+ import "../chunk-QWGCMQQD.js";
8
8
  export {
9
9
  evaluateGuard,
10
10
  eventToAllowlistKey,
@@ -0,0 +1,390 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/engine/simulate-engine.ts
21
+ var simulate_engine_exports = {};
22
+ __export(simulate_engine_exports, {
23
+ renderSimulateText: () => renderSimulateText,
24
+ simulateWorld: () => simulateWorld
25
+ });
26
+ module.exports = __toCommonJS(simulate_engine_exports);
27
+ function simulateWorld(world, options = {}) {
28
+ if (!world || !world.world) {
29
+ throw new Error(
30
+ 'World definition required. simulateWorld() cannot run without a world.\nLoad one with: loadWorld("./world/") or parseWorldMarkdown(markdown)'
31
+ );
32
+ }
33
+ const steps = Math.max(1, Math.min(options.steps ?? 1, 50));
34
+ const profileName = options.profile ?? world.world.default_assumption_profile;
35
+ const state = buildInitialState(world.stateSchema, options.stateOverrides);
36
+ for (const outcome of world.outcomes?.computed_outcomes ?? []) {
37
+ if (!(outcome.id in state)) {
38
+ state[outcome.id] = outcome.primary ? 100 : 0;
39
+ }
40
+ }
41
+ const assumptions = resolveAssumptions(world.assumptions, profileName);
42
+ const initialState = { ...state };
43
+ const simulationSteps = [];
44
+ let collapsed = false;
45
+ let collapseStep;
46
+ let collapseRule;
47
+ const sortedRules = [...world.rules].sort((a, b) => a.order - b.order);
48
+ const allEvents = options.events ?? [];
49
+ const eventsByStep = Array.from({ length: steps }, () => []);
50
+ for (let i = 0; i < allEvents.length; i++) {
51
+ const stepIdx = Math.min(i, steps - 1);
52
+ eventsByStep[stepIdx].push(allEvents[i]);
53
+ }
54
+ let totalEventsConsumed = 0;
55
+ for (let stepNum = 1; stepNum <= steps; stepNum++) {
56
+ if (collapsed) break;
57
+ const stepEvents = eventsByStep[stepNum - 1];
58
+ const stepResult = evaluateStep(
59
+ stepNum,
60
+ sortedRules,
61
+ state,
62
+ assumptions,
63
+ world,
64
+ stepEvents
65
+ );
66
+ totalEventsConsumed += stepResult.eventsApplied.length;
67
+ simulationSteps.push(stepResult);
68
+ if (stepResult.collapsed) {
69
+ collapsed = true;
70
+ collapseStep = stepNum;
71
+ collapseRule = stepResult.rulesEvaluated.find((r) => r.collapsed)?.ruleId;
72
+ }
73
+ }
74
+ const finalViability = classifyViability(state, world);
75
+ return {
76
+ worldId: world.world.world_id,
77
+ worldName: world.world.name,
78
+ profile: profileName,
79
+ initialState,
80
+ steps: simulationSteps,
81
+ finalState: { ...state },
82
+ finalViability,
83
+ collapsed,
84
+ collapseStep,
85
+ collapseRule,
86
+ eventsConsumed: totalEventsConsumed
87
+ };
88
+ }
89
+ function evaluateStep(stepNum, rules, state, assumptions, world, events = []) {
90
+ const evaluations = [];
91
+ const eventApplications = [];
92
+ let rulesFired = 0;
93
+ let collapsed = false;
94
+ const firedRuleIds = /* @__PURE__ */ new Set();
95
+ for (const evt of events) {
96
+ const application = {
97
+ eventType: evt.type,
98
+ rulesTriggered: [],
99
+ effects: []
100
+ };
101
+ for (const rule of rules) {
102
+ const eventTrigger = rule.triggers.find(
103
+ (t) => t.field === "event" && t.source === "state"
104
+ );
105
+ if (!eventTrigger) continue;
106
+ const matches = evaluateOperator(evt.type, eventTrigger.operator, eventTrigger.value);
107
+ if (!matches) continue;
108
+ application.rulesTriggered.push(rule.id);
109
+ firedRuleIds.add(rule.id);
110
+ for (const effect of rule.effects ?? []) {
111
+ const applied = applyEffect(effect, state);
112
+ if (applied) application.effects.push(applied);
113
+ }
114
+ }
115
+ eventApplications.push(application);
116
+ }
117
+ for (const rule of rules) {
118
+ if (collapsed) {
119
+ evaluations.push({
120
+ ruleId: rule.id,
121
+ label: rule.label,
122
+ triggered: false,
123
+ excluded: true,
124
+ effects: [],
125
+ collapsed: false
126
+ });
127
+ continue;
128
+ }
129
+ const excluded = rule.exclusive_with ? firedRuleIds.has(rule.exclusive_with) : false;
130
+ if (excluded) {
131
+ evaluations.push({
132
+ ruleId: rule.id,
133
+ label: rule.label,
134
+ triggered: false,
135
+ excluded: true,
136
+ effects: [],
137
+ collapsed: false
138
+ });
139
+ continue;
140
+ }
141
+ const triggered = evaluateTriggers(rule.triggers, state, assumptions);
142
+ if (!triggered) {
143
+ evaluations.push({
144
+ ruleId: rule.id,
145
+ label: rule.label,
146
+ triggered: false,
147
+ excluded: false,
148
+ effects: [],
149
+ collapsed: false
150
+ });
151
+ continue;
152
+ }
153
+ firedRuleIds.add(rule.id);
154
+ rulesFired++;
155
+ const appliedEffects = [];
156
+ for (const effect of rule.effects ?? []) {
157
+ const applied = applyEffect(effect, state);
158
+ if (applied) appliedEffects.push(applied);
159
+ }
160
+ for (const ce of rule.effects_conditional ?? []) {
161
+ const conditionMet = evaluateSingleTrigger(ce.condition, state, assumptions);
162
+ const andMet = ce.and ? evaluateSingleTrigger(ce.and, state, assumptions) : true;
163
+ const orMet = ce.or ? evaluateSingleTrigger(ce.or, state, assumptions) : false;
164
+ const anyMet = ce.condition_any ? ce.condition_any.some((c) => evaluateSingleTrigger(c, state, assumptions)) : false;
165
+ const shouldApply = conditionMet && andMet || ce.or && orMet || ce.condition_any && anyMet;
166
+ if (shouldApply) {
167
+ for (const effect of ce.effects) {
168
+ const applied = applyEffect(effect, state);
169
+ if (applied) appliedEffects.push(applied);
170
+ }
171
+ }
172
+ }
173
+ let ruleCollapsed = false;
174
+ if (rule.collapse_check) {
175
+ const fieldVal = typeof state[rule.collapse_check.field] === "number" ? state[rule.collapse_check.field] : 0;
176
+ if (evaluateOperator(fieldVal, rule.collapse_check.operator, rule.collapse_check.value)) {
177
+ ruleCollapsed = true;
178
+ collapsed = true;
179
+ }
180
+ }
181
+ if (!ruleCollapsed && rule.secondary_check) {
182
+ const fieldVal = typeof state[rule.secondary_check.field] === "number" ? state[rule.secondary_check.field] : 0;
183
+ if (evaluateOperator(fieldVal, rule.secondary_check.operator, rule.secondary_check.value)) {
184
+ ruleCollapsed = true;
185
+ collapsed = true;
186
+ }
187
+ }
188
+ evaluations.push({
189
+ ruleId: rule.id,
190
+ label: rule.label,
191
+ triggered: true,
192
+ excluded: false,
193
+ effects: appliedEffects,
194
+ collapsed: ruleCollapsed,
195
+ collapseField: ruleCollapsed ? rule.collapse_check?.field ?? rule.secondary_check?.field : void 0
196
+ });
197
+ }
198
+ const viability = classifyViability(state, world);
199
+ return {
200
+ step: stepNum,
201
+ eventsApplied: eventApplications,
202
+ rulesEvaluated: evaluations,
203
+ rulesFired,
204
+ stateAfter: { ...state },
205
+ viability,
206
+ collapsed
207
+ };
208
+ }
209
+ function evaluateTriggers(triggers, state, assumptions) {
210
+ if (!triggers || triggers.length === 0) return true;
211
+ return triggers.every((t) => evaluateSingleTrigger(t, state, assumptions));
212
+ }
213
+ function evaluateSingleTrigger(trigger, state, assumptions) {
214
+ const source = trigger.source === "assumption" ? assumptions : state;
215
+ const fieldValue = source[trigger.field];
216
+ if (fieldValue === void 0) return false;
217
+ return evaluateOperator(fieldValue, trigger.operator, trigger.value);
218
+ }
219
+ function evaluateOperator(fieldValue, operator, conditionValue) {
220
+ switch (operator) {
221
+ case "==":
222
+ return fieldValue === conditionValue;
223
+ case "!=":
224
+ return fieldValue !== conditionValue;
225
+ case ">":
226
+ return typeof fieldValue === "number" && typeof conditionValue === "number" && fieldValue > conditionValue;
227
+ case "<":
228
+ return typeof fieldValue === "number" && typeof conditionValue === "number" && fieldValue < conditionValue;
229
+ case ">=":
230
+ return typeof fieldValue === "number" && typeof conditionValue === "number" && fieldValue >= conditionValue;
231
+ case "<=":
232
+ return typeof fieldValue === "number" && typeof conditionValue === "number" && fieldValue <= conditionValue;
233
+ case "in":
234
+ return Array.isArray(conditionValue) && conditionValue.includes(String(fieldValue));
235
+ default:
236
+ return false;
237
+ }
238
+ }
239
+ function applyEffect(effect, state) {
240
+ const before = state[effect.target];
241
+ let after;
242
+ switch (effect.operation) {
243
+ case "multiply":
244
+ case "multiply_dynamic": {
245
+ const current = typeof before === "number" ? before : 0;
246
+ const factor = typeof effect.value === "number" ? effect.value : 1;
247
+ after = current * factor;
248
+ break;
249
+ }
250
+ case "add":
251
+ case "add_dynamic": {
252
+ const current = typeof before === "number" ? before : 0;
253
+ const addend = typeof effect.value === "number" ? effect.value : 0;
254
+ after = current + addend;
255
+ break;
256
+ }
257
+ case "subtract":
258
+ case "subtract_dynamic": {
259
+ const current = typeof before === "number" ? before : 0;
260
+ const subtrahend = typeof effect.value === "number" ? effect.value : 0;
261
+ after = current - subtrahend;
262
+ break;
263
+ }
264
+ case "set":
265
+ case "set_dynamic":
266
+ after = effect.value;
267
+ break;
268
+ case "set_boolean":
269
+ after = !!effect.value;
270
+ break;
271
+ default:
272
+ return null;
273
+ }
274
+ state[effect.target] = after;
275
+ return {
276
+ target: effect.target,
277
+ operation: effect.operation,
278
+ value: effect.value,
279
+ before: before ?? 0,
280
+ after
281
+ };
282
+ }
283
+ function buildInitialState(schema, overrides) {
284
+ const state = {};
285
+ for (const [name, variable] of Object.entries(schema.variables ?? {})) {
286
+ state[name] = variable.default;
287
+ }
288
+ if (overrides) {
289
+ for (const [key, value] of Object.entries(overrides)) {
290
+ state[key] = value;
291
+ }
292
+ }
293
+ return state;
294
+ }
295
+ function resolveAssumptions(config, profileName) {
296
+ const profile = config.profiles?.[profileName];
297
+ return profile?.parameters ?? {};
298
+ }
299
+ function classifyViability(state, world) {
300
+ const gates = world.gates?.viability_classification ?? [];
301
+ for (const gate of gates) {
302
+ const fieldValue = state[gate.field];
303
+ if (typeof fieldValue !== "number") continue;
304
+ if (evaluateOperator(fieldValue, gate.operator, gate.value)) {
305
+ return gate.status;
306
+ }
307
+ }
308
+ return "MODEL_COLLAPSES";
309
+ }
310
+ function renderSimulateText(result) {
311
+ const lines = [];
312
+ lines.push(`SIMULATION: ${result.worldName}`);
313
+ lines.push(`Profile: ${result.profile}`);
314
+ lines.push(`Steps: ${result.steps.length}`);
315
+ lines.push("");
316
+ lines.push("INITIAL STATE");
317
+ for (const [key, value] of Object.entries(result.initialState)) {
318
+ lines.push(` ${key}: ${value}`);
319
+ }
320
+ lines.push("");
321
+ for (const step of result.steps) {
322
+ lines.push(`STEP ${step.step}`);
323
+ if (step.eventsApplied && step.eventsApplied.length > 0) {
324
+ for (const evt of step.eventsApplied) {
325
+ lines.push(` EVENT: ${evt.eventType}`);
326
+ if (evt.rulesTriggered.length > 0) {
327
+ lines.push(` Rules triggered: ${evt.rulesTriggered.join(", ")}`);
328
+ }
329
+ for (const effect of evt.effects) {
330
+ const beforeStr = formatValue(effect.before);
331
+ const afterStr = formatValue(effect.after);
332
+ lines.push(` ${effect.target}: ${beforeStr} -> ${afterStr}`);
333
+ }
334
+ }
335
+ }
336
+ const fired = step.rulesEvaluated.filter((r) => r.triggered);
337
+ const skipped = step.rulesEvaluated.filter((r) => !r.triggered && !r.excluded);
338
+ const excluded = step.rulesEvaluated.filter((r) => r.excluded);
339
+ if (fired.length === 0) {
340
+ lines.push(" No rules fired (state unchanged)");
341
+ } else {
342
+ for (const rule of fired) {
343
+ lines.push(` FIRED: ${rule.label}`);
344
+ for (const effect of rule.effects) {
345
+ const beforeStr = formatValue(effect.before);
346
+ const afterStr = formatValue(effect.after);
347
+ lines.push(` ${effect.target}: ${beforeStr} -> ${afterStr}`);
348
+ }
349
+ if (rule.collapsed) {
350
+ lines.push(` COLLAPSE on ${rule.collapseField}`);
351
+ }
352
+ }
353
+ }
354
+ if (excluded.length > 0) {
355
+ lines.push(` Excluded: ${excluded.map((r) => r.label).join(", ")}`);
356
+ }
357
+ lines.push(` Viability: ${step.viability}`);
358
+ if (step.collapsed) {
359
+ lines.push(" ** MODEL COLLAPSED **");
360
+ }
361
+ lines.push("");
362
+ }
363
+ lines.push("FINAL STATE");
364
+ for (const [key, value] of Object.entries(result.finalState)) {
365
+ const initial = result.initialState[key];
366
+ const changed = initial !== value;
367
+ const marker = changed ? " (changed)" : "";
368
+ lines.push(` ${key}: ${formatValue(value)}${marker}`);
369
+ }
370
+ lines.push("");
371
+ if (result.eventsConsumed > 0) {
372
+ lines.push(`EVENTS CONSUMED: ${result.eventsConsumed}`);
373
+ }
374
+ lines.push(`VIABILITY: ${result.finalViability}`);
375
+ if (result.collapsed) {
376
+ lines.push(`COLLAPSED at step ${result.collapseStep} (rule: ${result.collapseRule})`);
377
+ }
378
+ return lines.join("\n");
379
+ }
380
+ function formatValue(v) {
381
+ if (typeof v === "number") {
382
+ return Number.isInteger(v) ? String(v) : v.toFixed(2);
383
+ }
384
+ return String(v);
385
+ }
386
+ // Annotate the CommonJS export names for ESM import in node:
387
+ 0 && (module.exports = {
388
+ renderSimulateText,
389
+ simulateWorld
390
+ });
@@ -0,0 +1,105 @@
1
+ import { GovernanceEvent, ViabilityStatus, WorldDefinition } from '../types.cjs';
2
+
3
+ /**
4
+ * Simulate Engine — Deterministic State Evolution (Reference Simulator)
5
+ *
6
+ * Pure function: (world, options) → SimulationResult
7
+ *
8
+ * This is NeuroVerse's REFERENCE SIMULATOR — one way to model how a world
9
+ * evolves over time. It is NOT the governance engine.
10
+ *
11
+ * simulateWorld() ≠ evaluateGuard()
12
+ *
13
+ * evaluateGuard() — Runtime enforcement. Decides if an action is allowed.
14
+ * Includes safety layer, role checks, plan enforcement,
15
+ * kernel rules, level constraints. Use for governance.
16
+ *
17
+ * simulateWorld() — State evolution modeling. Evaluates rule triggers,
18
+ * applies effects, tracks viability over N steps.
19
+ * Use for scenario planning and what-if analysis.
20
+ *
21
+ * World files (.nv-world.md) are portable — they define rules, roles, and
22
+ * constraints that can be consumed by any simulator or governance engine.
23
+ * This simulator is a reference implementation, not the only interpreter.
24
+ *
25
+ * Supports:
26
+ * - Single-step evaluation (default)
27
+ * - Multi-step iteration (--steps N)
28
+ * - State overrides (start from non-default values)
29
+ * - Assumption profile selection
30
+ * - Collapse detection (early termination)
31
+ *
32
+ * INVARIANTS:
33
+ * - Deterministic: same world + same options → same result.
34
+ * - Zero network calls. Zero LLM calls. Zero async.
35
+ * - Every rule evaluation is recorded in the trace.
36
+ * - World definition is REQUIRED — no world, no simulation.
37
+ */
38
+
39
+ interface SimulateOptions {
40
+ /** Number of simulation steps (default: 1) */
41
+ steps?: number;
42
+ /** State variable overrides (start values) */
43
+ stateOverrides?: Record<string, string | number | boolean>;
44
+ /** Assumption profile to use (default: world default) */
45
+ profile?: string;
46
+ /**
47
+ * Governance events to inject into the simulation.
48
+ * Events are applied before state-driven rules each step.
49
+ * This is the bridge: Guard → Events → Simulate → State Evolution.
50
+ *
51
+ * Events are distributed across steps (round-robin) or all applied to step 1
52
+ * if there are fewer steps than events.
53
+ */
54
+ events?: GovernanceEvent[];
55
+ }
56
+ interface SimulationResult {
57
+ worldId: string;
58
+ worldName: string;
59
+ profile: string;
60
+ initialState: Record<string, string | number | boolean>;
61
+ steps: SimulationStep[];
62
+ finalState: Record<string, string | number | boolean>;
63
+ finalViability: ViabilityStatus;
64
+ collapsed: boolean;
65
+ collapseStep?: number;
66
+ collapseRule?: string;
67
+ /** Total events consumed during simulation */
68
+ eventsConsumed: number;
69
+ }
70
+ interface SimulationStep {
71
+ step: number;
72
+ /** Events applied during this step (before rules) */
73
+ eventsApplied: EventApplication[];
74
+ rulesEvaluated: RuleEvaluation[];
75
+ rulesFired: number;
76
+ stateAfter: Record<string, string | number | boolean>;
77
+ viability: ViabilityStatus;
78
+ collapsed: boolean;
79
+ }
80
+ /** Record of an event applied during simulation */
81
+ interface EventApplication {
82
+ eventType: string;
83
+ rulesTriggered: string[];
84
+ effects: AppliedEffect[];
85
+ }
86
+ interface RuleEvaluation {
87
+ ruleId: string;
88
+ label: string;
89
+ triggered: boolean;
90
+ excluded: boolean;
91
+ effects: AppliedEffect[];
92
+ collapsed: boolean;
93
+ collapseField?: string;
94
+ }
95
+ interface AppliedEffect {
96
+ target: string;
97
+ operation: string;
98
+ value: number | boolean | string;
99
+ before: string | number | boolean;
100
+ after: string | number | boolean;
101
+ }
102
+ declare function simulateWorld(world: WorldDefinition, options?: SimulateOptions): SimulationResult;
103
+ declare function renderSimulateText(result: SimulationResult): string;
104
+
105
+ export { type AppliedEffect, type EventApplication, type RuleEvaluation, type SimulateOptions, type SimulationResult, type SimulationStep, renderSimulateText, simulateWorld };