@neuroverseos/nv-sim 0.1.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.
- package/LICENSE +201 -0
- package/README.md +73 -0
- package/dist/engine/analyzer.js +651 -0
- package/dist/engine/api.js +208 -0
- package/dist/engine/chaosEngine.js +292 -0
- package/dist/engine/cli.js +803 -0
- package/dist/engine/goalEngine.js +559 -0
- package/dist/engine/governance.js +210 -0
- package/dist/engine/governedSimulation.js +529 -0
- package/dist/engine/index.js +82 -0
- package/dist/engine/mirofish.js +295 -0
- package/dist/engine/reasoningEngine.js +548 -0
- package/dist/engine/scenarioCapsule.js +351 -0
- package/dist/engine/swarmSimulation.js +244 -0
- package/dist/engine/types.js +15 -0
- package/dist/engine/worldBridge.js +481 -0
- package/dist/package.json +1 -0
- package/package.json +110 -0
|
@@ -0,0 +1,548 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Echelon Reasoning Engine
|
|
4
|
+
*
|
|
5
|
+
* The core service that processes POST /reason requests.
|
|
6
|
+
* This is the proprietary Echelon reasoning kernel exposed as an API.
|
|
7
|
+
*
|
|
8
|
+
* Architecture:
|
|
9
|
+
* 1. Validate and normalize the request
|
|
10
|
+
* 2. Run constitutional governance checks (Echelon built-in + neuroverse-os-governance)
|
|
11
|
+
* 3. Decompose the scenario into reasoning paths
|
|
12
|
+
* 4. Challenge caller assumptions
|
|
13
|
+
* 5. Project outcomes per path
|
|
14
|
+
* 6. Optionally run swarm simulation for stakeholder reactions
|
|
15
|
+
* 7. Generate recommendations
|
|
16
|
+
* 8. Attach governance trace (always — open governance layer)
|
|
17
|
+
*
|
|
18
|
+
* IMPORTANT: This engine is stateless. No scenario data is stored.
|
|
19
|
+
* Callers provide their own LLM API key (BYOK model).
|
|
20
|
+
*/
|
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
exports.processReasonRequest = processReasonRequest;
|
|
23
|
+
const mirofish_1 = require("./mirofish");
|
|
24
|
+
const governance_1 = require("./governance");
|
|
25
|
+
const goalEngine_1 = require("./goalEngine");
|
|
26
|
+
// ============================================
|
|
27
|
+
// ENGINE VERSION
|
|
28
|
+
// ============================================
|
|
29
|
+
const ENGINE_VERSION = "0.1.0";
|
|
30
|
+
function validateRequest(request) {
|
|
31
|
+
if (!request.scenario || request.scenario.trim().length === 0) {
|
|
32
|
+
return {
|
|
33
|
+
valid: false,
|
|
34
|
+
error: { code: "INVALID_REQUEST", message: "scenario is required" },
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
if (request.scenario.trim().length < 10) {
|
|
38
|
+
return {
|
|
39
|
+
valid: false,
|
|
40
|
+
error: {
|
|
41
|
+
code: "SCENARIO_TOO_VAGUE",
|
|
42
|
+
message: "Scenario must be at least 10 characters. Provide enough context for meaningful reasoning.",
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
const validDepths = ["quick", "standard", "full", "exhaustive"];
|
|
47
|
+
if (request.depth && !validDepths.includes(request.depth)) {
|
|
48
|
+
return {
|
|
49
|
+
valid: false,
|
|
50
|
+
error: {
|
|
51
|
+
code: "INVALID_REQUEST",
|
|
52
|
+
message: `Invalid depth "${request.depth}". Must be one of: ${validDepths.join(", ")}`,
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
return { valid: true };
|
|
57
|
+
}
|
|
58
|
+
// ============================================
|
|
59
|
+
// STAKEHOLDER NORMALIZATION
|
|
60
|
+
// ============================================
|
|
61
|
+
function normalizeStakeholders(raw) {
|
|
62
|
+
if (!raw || raw.length === 0)
|
|
63
|
+
return [];
|
|
64
|
+
return raw.map((s) => {
|
|
65
|
+
if (typeof s === "string") {
|
|
66
|
+
return {
|
|
67
|
+
id: s,
|
|
68
|
+
disposition: "unknown",
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
return s;
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
// ============================================
|
|
75
|
+
// DEPTH → PATH COUNT MAPPING
|
|
76
|
+
// ============================================
|
|
77
|
+
function getPathCount(depth) {
|
|
78
|
+
switch (depth) {
|
|
79
|
+
case "quick":
|
|
80
|
+
return 2;
|
|
81
|
+
case "standard":
|
|
82
|
+
return 3;
|
|
83
|
+
case "full":
|
|
84
|
+
return 5;
|
|
85
|
+
case "exhaustive":
|
|
86
|
+
return 8;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
// ============================================
|
|
90
|
+
// REASONING ENGINE — CORE
|
|
91
|
+
// ============================================
|
|
92
|
+
/**
|
|
93
|
+
* Generate a unique reasoning ID.
|
|
94
|
+
*/
|
|
95
|
+
function generateReasoningId() {
|
|
96
|
+
const timestamp = Date.now().toString(36);
|
|
97
|
+
const random = Math.random().toString(36).slice(2, 8);
|
|
98
|
+
return `rsn_${timestamp}_${random}`;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Generate a unique trace ID for governance.
|
|
102
|
+
*/
|
|
103
|
+
function generateTraceId() {
|
|
104
|
+
const timestamp = Date.now().toString(36);
|
|
105
|
+
const random = Math.random().toString(36).slice(2, 8);
|
|
106
|
+
return `gov_${timestamp}_${random}`;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Decompose a scenario into reasoning paths.
|
|
110
|
+
*
|
|
111
|
+
* This is the core Echelon capability — structured multi-path
|
|
112
|
+
* reasoning with stakeholder-aware analysis.
|
|
113
|
+
*/
|
|
114
|
+
function decomposeScenarioPaths(scenario, stakeholders, depth, perspective) {
|
|
115
|
+
const pathCount = getPathCount(depth);
|
|
116
|
+
const paths = [];
|
|
117
|
+
// Path generation uses scenario analysis to identify key decision branches.
|
|
118
|
+
// In production, this calls the Echelon kernel's LLM reasoning pipeline.
|
|
119
|
+
// For now, we generate structured paths based on scenario decomposition.
|
|
120
|
+
// Identify the core tension in the scenario
|
|
121
|
+
const scenarioLower = scenario.toLowerCase();
|
|
122
|
+
const isGeopolitical = scenarioLower.includes("strait") ||
|
|
123
|
+
scenarioLower.includes("war") ||
|
|
124
|
+
scenarioLower.includes("sanctions") ||
|
|
125
|
+
scenarioLower.includes("blockade") ||
|
|
126
|
+
scenarioLower.includes("geopolitical");
|
|
127
|
+
const isEconomic = scenarioLower.includes("price") ||
|
|
128
|
+
scenarioLower.includes("inflation") ||
|
|
129
|
+
scenarioLower.includes("recession") ||
|
|
130
|
+
scenarioLower.includes("market") ||
|
|
131
|
+
scenarioLower.includes("gas") ||
|
|
132
|
+
scenarioLower.includes("oil");
|
|
133
|
+
const isCrisis = scenarioLower.includes("breach") ||
|
|
134
|
+
scenarioLower.includes("crisis") ||
|
|
135
|
+
scenarioLower.includes("attack") ||
|
|
136
|
+
scenarioLower.includes("failure");
|
|
137
|
+
// Generate paths based on scenario type and depth
|
|
138
|
+
// Each path represents a distinct decision branch
|
|
139
|
+
if (isGeopolitical || isEconomic) {
|
|
140
|
+
paths.push({
|
|
141
|
+
id: "path_immediate_response",
|
|
142
|
+
label: "Immediate Response",
|
|
143
|
+
description: "Take decisive action within 24-48 hours to position ahead of market/political reactions",
|
|
144
|
+
projected_outcome: "First-mover advantage but higher risk of overreaction if situation de-escalates",
|
|
145
|
+
probability: 0.6,
|
|
146
|
+
risk: "moderate",
|
|
147
|
+
tradeoffs: [
|
|
148
|
+
"Speed vs. accuracy of assessment",
|
|
149
|
+
"Resource commitment before full picture emerges",
|
|
150
|
+
"Potential to signal panic to stakeholders",
|
|
151
|
+
],
|
|
152
|
+
benefits_stakeholders: stakeholders.filter((s) => s.disposition === "hostile").map((s) => s.id),
|
|
153
|
+
harms_stakeholders: stakeholders.filter((s) => s.disposition === "neutral").map((s) => s.id),
|
|
154
|
+
});
|
|
155
|
+
paths.push({
|
|
156
|
+
id: "path_hedge_and_monitor",
|
|
157
|
+
label: "Hedge and Monitor",
|
|
158
|
+
description: "Implement defensive positions while gathering intelligence on how the situation develops",
|
|
159
|
+
projected_outcome: "Balanced exposure with ability to pivot in either direction",
|
|
160
|
+
probability: 0.75,
|
|
161
|
+
risk: "low",
|
|
162
|
+
tradeoffs: [
|
|
163
|
+
"May miss optimal timing for decisive action",
|
|
164
|
+
"Hedging costs reduce upside potential",
|
|
165
|
+
"Requires ongoing monitoring infrastructure",
|
|
166
|
+
],
|
|
167
|
+
benefits_stakeholders: stakeholders.filter((s) => s.disposition !== "hostile").map((s) => s.id),
|
|
168
|
+
});
|
|
169
|
+
if (pathCount >= 3) {
|
|
170
|
+
paths.push({
|
|
171
|
+
id: "path_opportunistic",
|
|
172
|
+
label: "Opportunistic Pivot",
|
|
173
|
+
description: "Identify and exploit opportunities that emerge from the disruption",
|
|
174
|
+
projected_outcome: "High upside potential if disruption creates market gaps, but requires capital and risk appetite",
|
|
175
|
+
probability: 0.4,
|
|
176
|
+
risk: "high",
|
|
177
|
+
tradeoffs: [
|
|
178
|
+
"Requires significant capital deployment under uncertainty",
|
|
179
|
+
"Reputational risk of appearing to profit from crisis",
|
|
180
|
+
"Competitive advantage if successful",
|
|
181
|
+
],
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
if (isCrisis) {
|
|
186
|
+
paths.push({
|
|
187
|
+
id: "path_containment",
|
|
188
|
+
label: "Contain and Communicate",
|
|
189
|
+
description: "Prioritize damage containment with transparent stakeholder communication",
|
|
190
|
+
projected_outcome: "Faster trust recovery but full exposure of extent of issue",
|
|
191
|
+
probability: 0.7,
|
|
192
|
+
risk: "moderate",
|
|
193
|
+
tradeoffs: [
|
|
194
|
+
"Transparency vs. legal exposure",
|
|
195
|
+
"Speed of communication vs. accuracy",
|
|
196
|
+
"Short-term pain for long-term trust",
|
|
197
|
+
],
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
// Ensure minimum paths for depth
|
|
201
|
+
while (paths.length < Math.min(pathCount, 2)) {
|
|
202
|
+
paths.push({
|
|
203
|
+
id: `path_${paths.length + 1}`,
|
|
204
|
+
label: `Analysis Path ${paths.length + 1}`,
|
|
205
|
+
description: `Structured analysis branch ${paths.length + 1} for the given scenario`,
|
|
206
|
+
projected_outcome: "Outcome depends on assumptions and constraint satisfaction",
|
|
207
|
+
probability: 0.5,
|
|
208
|
+
risk: "moderate",
|
|
209
|
+
tradeoffs: ["Requires further analysis to fully evaluate"],
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
return paths.slice(0, pathCount);
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Challenge the caller's assumptions.
|
|
216
|
+
*/
|
|
217
|
+
function challengeAssumptions(request, stakeholders) {
|
|
218
|
+
const challenges = [];
|
|
219
|
+
const assumptions = request.assumptions;
|
|
220
|
+
if (assumptions?.severity) {
|
|
221
|
+
challenges.push({
|
|
222
|
+
assumption: `Severity is "${assumptions.severity}"`,
|
|
223
|
+
challenge: "Severity assessments made early in a developing situation are frequently revised. Historical data shows initial severity estimates are wrong 40% of the time.",
|
|
224
|
+
impact_if_wrong: assumptions.severity === "high" || assumptions.severity === "critical"
|
|
225
|
+
? "If severity is actually lower, you may over-allocate resources and signal panic unnecessarily"
|
|
226
|
+
: "If severity is actually higher, delayed response compounds damage exponentially",
|
|
227
|
+
severity: "high",
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
if (assumptions?.time_pressure === "urgent" || assumptions?.time_pressure === "immediate") {
|
|
231
|
+
challenges.push({
|
|
232
|
+
assumption: `Time pressure is "${assumptions.time_pressure}"`,
|
|
233
|
+
challenge: "Perceived urgency often compresses decision quality. Consider whether the urgency is real (external deadline) or manufactured (internal anxiety).",
|
|
234
|
+
impact_if_wrong: "Rushing decisions under false urgency leads to commitment to suboptimal paths that are costly to reverse",
|
|
235
|
+
severity: "moderate",
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
if (assumptions?.environmental_hostility === "high") {
|
|
239
|
+
challenges.push({
|
|
240
|
+
assumption: "Environment is highly hostile",
|
|
241
|
+
challenge: "High-hostility assessments can become self-fulfilling. Adversarial framing may close cooperative paths that actually exist.",
|
|
242
|
+
impact_if_wrong: "Missing diplomatic or cooperative solutions that could resolve the situation at lower cost",
|
|
243
|
+
severity: "moderate",
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
// Challenge implicit assumptions
|
|
247
|
+
if (!assumptions?.regulatory_climate) {
|
|
248
|
+
challenges.push({
|
|
249
|
+
assumption: "Regulatory climate not specified (implicitly assumed irrelevant)",
|
|
250
|
+
challenge: "Most significant scenarios have regulatory dimensions. Ignoring regulatory context often leads to strategies that are technically optimal but legally problematic.",
|
|
251
|
+
impact_if_wrong: "Strategy may be invalidated by regulatory action, requiring costly pivots",
|
|
252
|
+
severity: "moderate",
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
// Stakeholder-related challenges
|
|
256
|
+
if (stakeholders.length > 0 && stakeholders.every((s) => s.disposition !== "hostile")) {
|
|
257
|
+
challenges.push({
|
|
258
|
+
assumption: "No hostile stakeholders identified",
|
|
259
|
+
challenge: "Every significant scenario has adversarial actors, even if they're not immediately obvious. Consider second-order stakeholders (competitors, media, regulators).",
|
|
260
|
+
impact_if_wrong: "Blind-sided by opposition that could have been anticipated and planned for",
|
|
261
|
+
severity: "high",
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
return challenges;
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Generate projected outcomes.
|
|
268
|
+
*/
|
|
269
|
+
function projectOutcomes(paths, request) {
|
|
270
|
+
const outcomes = [];
|
|
271
|
+
// Best case
|
|
272
|
+
outcomes.push({
|
|
273
|
+
id: "outcome_best",
|
|
274
|
+
label: "Best Case",
|
|
275
|
+
conditions: "Key assumptions hold, stakeholders react rationally, no secondary shocks",
|
|
276
|
+
outcome: "Situation resolves with minimal damage. Well-positioned actors gain competitive advantage from demonstrated competence.",
|
|
277
|
+
likelihood: 0.2,
|
|
278
|
+
impact: "positive",
|
|
279
|
+
});
|
|
280
|
+
// Most likely
|
|
281
|
+
outcomes.push({
|
|
282
|
+
id: "outcome_likely",
|
|
283
|
+
label: "Most Likely",
|
|
284
|
+
conditions: "Mixed assumption validity, some stakeholder volatility, one secondary complication",
|
|
285
|
+
outcome: "Moderate disruption requiring 2-4 adjustment cycles. Organizations with pre-planned responses fare significantly better.",
|
|
286
|
+
likelihood: 0.5,
|
|
287
|
+
impact: "negative",
|
|
288
|
+
});
|
|
289
|
+
// Worst case
|
|
290
|
+
outcomes.push({
|
|
291
|
+
id: "outcome_worst",
|
|
292
|
+
label: "Worst Case",
|
|
293
|
+
conditions: "Key assumptions fail, cascading stakeholder reactions, multiple secondary shocks",
|
|
294
|
+
outcome: "Extended disruption with structural changes to the operating environment. Recovery requires fundamental strategy revision.",
|
|
295
|
+
likelihood: 0.15,
|
|
296
|
+
impact: "very_negative",
|
|
297
|
+
});
|
|
298
|
+
// Tail risk
|
|
299
|
+
if (request.depth === "full" || request.depth === "exhaustive") {
|
|
300
|
+
outcomes.push({
|
|
301
|
+
id: "outcome_tail",
|
|
302
|
+
label: "Tail Risk / Black Swan",
|
|
303
|
+
conditions: "Scenario triggers cascade effects that fundamentally alter the landscape",
|
|
304
|
+
outcome: "Paradigm shift. Previous assumptions about the operating environment become obsolete. Winners are those who recognized the shift earliest.",
|
|
305
|
+
likelihood: 0.05,
|
|
306
|
+
impact: "very_negative",
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
return outcomes;
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Generate recommendations.
|
|
313
|
+
*/
|
|
314
|
+
function generateRecommendations(paths, challenges, request) {
|
|
315
|
+
const recommendations = [];
|
|
316
|
+
// Always recommend: validate assumptions
|
|
317
|
+
recommendations.push({
|
|
318
|
+
priority: 1,
|
|
319
|
+
action: "Validate your highest-severity assumptions before committing resources",
|
|
320
|
+
rationale: `${challenges.length} assumptions were challenged. The cost of validating is far lower than the cost of acting on wrong assumptions.`,
|
|
321
|
+
timeframe: "Immediately (next 2-4 hours)",
|
|
322
|
+
risk_of_inaction: "Committing to a strategy built on unchecked assumptions compounds error at every step",
|
|
323
|
+
});
|
|
324
|
+
// Recommend based on lowest-risk path
|
|
325
|
+
const lowestRiskPath = [...paths].sort((a, b) => {
|
|
326
|
+
const riskOrder = { low: 0, moderate: 1, high: 2, critical: 3 };
|
|
327
|
+
return riskOrder[a.risk] - riskOrder[b.risk];
|
|
328
|
+
})[0];
|
|
329
|
+
if (lowestRiskPath) {
|
|
330
|
+
recommendations.push({
|
|
331
|
+
priority: 2,
|
|
332
|
+
action: `Prepare to execute "${lowestRiskPath.label}" as your default path while monitoring for signals that warrant pivoting`,
|
|
333
|
+
rationale: `This path has the best risk-adjusted probability (${(lowestRiskPath.probability * 100).toFixed(0)}% success, ${lowestRiskPath.risk} risk)`,
|
|
334
|
+
timeframe: "Within 24 hours",
|
|
335
|
+
dependencies: ["Assumption validation (Priority 1)"],
|
|
336
|
+
risk_of_inaction: "Without a default path, decision paralysis sets in and you lose initiative",
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
// Recommend stakeholder mapping
|
|
340
|
+
if (request.stakeholders && request.stakeholders.length > 0) {
|
|
341
|
+
recommendations.push({
|
|
342
|
+
priority: 3,
|
|
343
|
+
action: "Map stakeholder communication sequences — who hears what, when, and from whom",
|
|
344
|
+
rationale: "Stakeholder reactions are often more damaging than the scenario itself. Controlled communication prevents information cascades.",
|
|
345
|
+
timeframe: "Within 12 hours",
|
|
346
|
+
risk_of_inaction: "Stakeholders who learn about the situation from external sources react 3x more negatively",
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
// Recommend monitoring
|
|
350
|
+
recommendations.push({
|
|
351
|
+
priority: recommendations.length + 1,
|
|
352
|
+
action: "Establish real-time monitoring for the 3-5 signals that would invalidate your chosen path",
|
|
353
|
+
rationale: "Scenarios evolve. The strategy you choose today may need revision tomorrow. Knowing WHEN to pivot is as important as knowing WHERE to pivot.",
|
|
354
|
+
timeframe: "Within 48 hours",
|
|
355
|
+
risk_of_inaction: "Without monitoring triggers, you discover path failure too late to course-correct",
|
|
356
|
+
});
|
|
357
|
+
return recommendations;
|
|
358
|
+
}
|
|
359
|
+
// ============================================
|
|
360
|
+
// MAIN ENGINE ENTRY POINT
|
|
361
|
+
// ============================================
|
|
362
|
+
/**
|
|
363
|
+
* Process a POST /reason request and return structured reasoning.
|
|
364
|
+
*
|
|
365
|
+
* This is the main entry point for the reasoning engine.
|
|
366
|
+
* It is stateless — all context comes from the request.
|
|
367
|
+
*/
|
|
368
|
+
async function processReasonRequest(request) {
|
|
369
|
+
const startTime = Date.now();
|
|
370
|
+
const reasoningId = generateReasoningId();
|
|
371
|
+
// 1. Validate request
|
|
372
|
+
const validation = validateRequest(request);
|
|
373
|
+
if (!validation.valid) {
|
|
374
|
+
return {
|
|
375
|
+
status: "error",
|
|
376
|
+
error: {
|
|
377
|
+
code: validation.error.code,
|
|
378
|
+
message: validation.error.message,
|
|
379
|
+
},
|
|
380
|
+
reasoning_id: reasoningId,
|
|
381
|
+
timestamp: new Date().toISOString(),
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
// 2. Normalize inputs
|
|
385
|
+
const depth = request.depth ?? "standard";
|
|
386
|
+
const perspective = request.perspective ?? "strategic_advisor";
|
|
387
|
+
const stakeholders = normalizeStakeholders(request.stakeholders);
|
|
388
|
+
// 3. Run full governance checks (NeuroverseOS guard + validate + simulate + Echelon constitutional)
|
|
389
|
+
const governanceResult = (0, governance_1.runFullGovernanceChecks)(request);
|
|
390
|
+
const governanceChecks = governanceResult.checks;
|
|
391
|
+
// Check for governance violations
|
|
392
|
+
if (!governanceResult.allowed) {
|
|
393
|
+
return {
|
|
394
|
+
status: "error",
|
|
395
|
+
error: {
|
|
396
|
+
code: "GOVERNANCE_VIOLATION",
|
|
397
|
+
message: `Reasoning blocked by governance: ${governanceResult.blockReason ?? "governance check failed"}`,
|
|
398
|
+
detail: governanceChecks.filter((c) => !c.passed).map((v) => v.detail).join("; "),
|
|
399
|
+
},
|
|
400
|
+
reasoning_id: reasoningId,
|
|
401
|
+
timestamp: new Date().toISOString(),
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
// 4. Decompose scenario into reasoning paths
|
|
405
|
+
const paths = decomposeScenarioPaths(scenario(request), stakeholders, depth, perspective);
|
|
406
|
+
// 5. Challenge assumptions
|
|
407
|
+
const assumptionChallenges = challengeAssumptions(request, stakeholders);
|
|
408
|
+
// 6. Project outcomes
|
|
409
|
+
const projectedOutcomes = projectOutcomes(paths, request);
|
|
410
|
+
// 7. Generate recommendations
|
|
411
|
+
const recommendations = generateRecommendations(paths, assumptionChallenges, request);
|
|
412
|
+
// 8. Build analysis
|
|
413
|
+
const analysis = {
|
|
414
|
+
summary: buildSummary(request, paths, assumptionChallenges),
|
|
415
|
+
paths,
|
|
416
|
+
projected_outcomes: projectedOutcomes,
|
|
417
|
+
assumption_challenges: assumptionChallenges,
|
|
418
|
+
recommendations,
|
|
419
|
+
key_uncertainties: extractKeyUncertainties(request, paths),
|
|
420
|
+
missing_questions: identifyMissingQuestions(request, stakeholders),
|
|
421
|
+
};
|
|
422
|
+
// 9. Run swarm simulation (if requested)
|
|
423
|
+
// Uses MiroFish when available, falls back to Echelon-native.
|
|
424
|
+
// MiroFish shows WHAT happens. Echelon reasons about WHAT IT MEANS.
|
|
425
|
+
let swarmResult = undefined;
|
|
426
|
+
let simulationSource;
|
|
427
|
+
if (request.swarm?.enabled && stakeholders.length > 0) {
|
|
428
|
+
const unified = await (0, mirofish_1.runUnifiedSimulation)(request.scenario, stakeholders, paths, request.swarm);
|
|
429
|
+
swarmResult = unified.result;
|
|
430
|
+
simulationSource = unified.source;
|
|
431
|
+
}
|
|
432
|
+
// 10. Goal-directed reasoning (if goal mode)
|
|
433
|
+
// "How do I get here?" — works backward from desired outcome
|
|
434
|
+
// Generates strategies, tests them against swarm, ranks paths
|
|
435
|
+
const reasoningMode = request.goal ? "goal" : (request.mode ?? "explore");
|
|
436
|
+
let goalResult = undefined;
|
|
437
|
+
if (reasoningMode === "goal" && request.goal) {
|
|
438
|
+
goalResult = await (0, goalEngine_1.runGoalReasoning)(request, stakeholders);
|
|
439
|
+
}
|
|
440
|
+
// 11. Build governance trace (always included — open governance layer)
|
|
441
|
+
// Includes NeuroverseOS guard verdict, world validation, and simulation results
|
|
442
|
+
const enforcedConstraints = [
|
|
443
|
+
...buildEnforcedConstraints(request),
|
|
444
|
+
...governanceResult.enforcedConstraints,
|
|
445
|
+
];
|
|
446
|
+
// Build NeuroverseOS governance summary
|
|
447
|
+
const neuroverseTrace = governanceResult.guardVerdict ? {
|
|
448
|
+
guard_status: governanceResult.guardVerdict.status,
|
|
449
|
+
world_viability: governanceResult.governanceSignals?.viability,
|
|
450
|
+
world_collapsed: governanceResult.governanceSignals?.collapsed,
|
|
451
|
+
collapse_risk: governanceResult.governanceSignals?.collapseRisk,
|
|
452
|
+
rules_fired: governanceResult.governanceSignals?.rulesFired,
|
|
453
|
+
world_health_score: governanceResult.validationReport?.summary.completenessScore,
|
|
454
|
+
invariant_coverage: governanceResult.validationReport?.summary.invariantCoverage,
|
|
455
|
+
} : undefined;
|
|
456
|
+
const governance = {
|
|
457
|
+
trace_id: generateTraceId(),
|
|
458
|
+
constitutional_checks: governanceChecks,
|
|
459
|
+
authority_level: "ANALYSIS_ONLY",
|
|
460
|
+
enforced_constraints: enforcedConstraints,
|
|
461
|
+
timestamp: new Date().toISOString(),
|
|
462
|
+
engine_version: ENGINE_VERSION,
|
|
463
|
+
neuroverse: neuroverseTrace,
|
|
464
|
+
};
|
|
465
|
+
// 12. Build response
|
|
466
|
+
const processingTime = Date.now() - startTime;
|
|
467
|
+
const meta = {
|
|
468
|
+
processing_time_ms: processingTime,
|
|
469
|
+
depth_used: depth,
|
|
470
|
+
paths_explored: paths.length + (goalResult?.strategies.length ?? 0),
|
|
471
|
+
assumptions_challenged: assumptionChallenges.length,
|
|
472
|
+
timestamp: new Date().toISOString(),
|
|
473
|
+
};
|
|
474
|
+
return {
|
|
475
|
+
reasoning_id: reasoningId,
|
|
476
|
+
status: "completed",
|
|
477
|
+
analysis,
|
|
478
|
+
governance,
|
|
479
|
+
swarm: swarmResult,
|
|
480
|
+
goal_reasoning: goalResult,
|
|
481
|
+
mode: reasoningMode,
|
|
482
|
+
meta,
|
|
483
|
+
};
|
|
484
|
+
}
|
|
485
|
+
// ============================================
|
|
486
|
+
// HELPER FUNCTIONS
|
|
487
|
+
// ============================================
|
|
488
|
+
function scenario(request) {
|
|
489
|
+
return request.scenario;
|
|
490
|
+
}
|
|
491
|
+
function buildSummary(request, paths, challenges) {
|
|
492
|
+
const pathCount = paths.length;
|
|
493
|
+
const challengeCount = challenges.length;
|
|
494
|
+
const highRiskPaths = paths.filter((p) => p.risk === "high" || p.risk === "critical").length;
|
|
495
|
+
return (`Analyzed ${pathCount} decision paths for this scenario. ` +
|
|
496
|
+
`${challengeCount} of your assumptions were challenged. ` +
|
|
497
|
+
(highRiskPaths > 0
|
|
498
|
+
? `${highRiskPaths} path${highRiskPaths > 1 ? "s" : ""} carry high or critical risk. `
|
|
499
|
+
: "No paths carry critical risk. ") +
|
|
500
|
+
`Recommendation: validate assumptions before committing to a path.`);
|
|
501
|
+
}
|
|
502
|
+
function extractKeyUncertainties(request, paths) {
|
|
503
|
+
const uncertainties = [];
|
|
504
|
+
uncertainties.push("How secondary stakeholders (not yet identified) will react");
|
|
505
|
+
uncertainties.push("Whether the situation will escalate or de-escalate in the next 48 hours");
|
|
506
|
+
if (request.assumptions?.severity === "high" || request.assumptions?.severity === "critical") {
|
|
507
|
+
uncertainties.push("Whether severity assessment is accurate or inflated by recency bias");
|
|
508
|
+
}
|
|
509
|
+
if (paths.some((p) => p.probability < 0.3)) {
|
|
510
|
+
uncertainties.push("Low-probability paths may have outsized impact if they materialize");
|
|
511
|
+
}
|
|
512
|
+
return uncertainties;
|
|
513
|
+
}
|
|
514
|
+
function identifyMissingQuestions(request, stakeholders) {
|
|
515
|
+
const missing = [];
|
|
516
|
+
if (!request.constraints?.time_horizon) {
|
|
517
|
+
missing.push("What is your time horizon for this decision?");
|
|
518
|
+
}
|
|
519
|
+
if (!request.constraints?.risk_tolerance) {
|
|
520
|
+
missing.push("What is your risk tolerance — conservative, moderate, or aggressive?");
|
|
521
|
+
}
|
|
522
|
+
if (stakeholders.length === 0) {
|
|
523
|
+
missing.push("Who are the key stakeholders affected by this scenario?");
|
|
524
|
+
}
|
|
525
|
+
if (!request.assumptions?.regulatory_climate) {
|
|
526
|
+
missing.push("What regulatory frameworks apply to this situation?");
|
|
527
|
+
}
|
|
528
|
+
missing.push("What is your fallback position if your primary strategy fails?");
|
|
529
|
+
missing.push("Who are your adversaries in this scenario, and what are their incentives?");
|
|
530
|
+
return missing;
|
|
531
|
+
}
|
|
532
|
+
function buildEnforcedConstraints(request) {
|
|
533
|
+
const constraints = [
|
|
534
|
+
"ANALYSIS_ONLY: No execution authority — reasoning output is advisory",
|
|
535
|
+
"STATELESS: No scenario data stored after response",
|
|
536
|
+
"GOVERNANCE_TRACED: All reasoning paths auditable",
|
|
537
|
+
];
|
|
538
|
+
if (request.constraints?.regulatory) {
|
|
539
|
+
const reg = Array.isArray(request.constraints.regulatory)
|
|
540
|
+
? request.constraints.regulatory.join(", ")
|
|
541
|
+
: request.constraints.regulatory;
|
|
542
|
+
constraints.push(`REGULATORY: ${reg} framework(s) applied`);
|
|
543
|
+
}
|
|
544
|
+
if (request.constraints?.risk_tolerance) {
|
|
545
|
+
constraints.push(`RISK_BOUNDED: ${request.constraints.risk_tolerance} tolerance enforced`);
|
|
546
|
+
}
|
|
547
|
+
return constraints;
|
|
548
|
+
}
|