@neuroverseos/governance 0.3.3 → 0.4.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/README.md +280 -405
- package/dist/adapters/autoresearch.cjs +63 -9
- package/dist/adapters/autoresearch.d.cts +1 -1
- package/dist/adapters/autoresearch.d.ts +1 -1
- package/dist/adapters/autoresearch.js +3 -3
- package/dist/adapters/deep-agents.cjs +63 -9
- package/dist/adapters/deep-agents.d.cts +2 -2
- package/dist/adapters/deep-agents.d.ts +2 -2
- package/dist/adapters/deep-agents.js +3 -3
- package/dist/adapters/express.cjs +63 -9
- package/dist/adapters/express.d.cts +1 -1
- package/dist/adapters/express.d.ts +1 -1
- package/dist/adapters/express.js +3 -3
- package/dist/adapters/index.cjs +896 -9
- package/dist/adapters/index.d.cts +278 -2
- package/dist/adapters/index.d.ts +278 -2
- package/dist/adapters/index.js +45 -8
- package/dist/adapters/langchain.cjs +63 -9
- package/dist/adapters/langchain.d.cts +2 -2
- package/dist/adapters/langchain.d.ts +2 -2
- package/dist/adapters/langchain.js +3 -3
- package/dist/adapters/openai.cjs +63 -9
- package/dist/adapters/openai.d.cts +2 -2
- package/dist/adapters/openai.d.ts +2 -2
- package/dist/adapters/openai.js +3 -3
- package/dist/adapters/openclaw.cjs +63 -9
- package/dist/adapters/openclaw.d.cts +2 -2
- package/dist/adapters/openclaw.d.ts +2 -2
- package/dist/adapters/openclaw.js +3 -3
- package/dist/{add-ROOZLU62.js → add-LYHDZ5RL.js} +1 -1
- package/dist/{behavioral-MJO34S6Q.js → behavioral-SPWPGYXL.js} +2 -2
- package/dist/{bootstrap-CQRZVOXK.js → bootstrap-IP5QMC3Q.js} +2 -2
- package/dist/{bootstrap-emitter-Q7UIJZ2O.js → bootstrap-emitter-GIMOJFOC.js} +1 -1
- package/dist/{bootstrap-parser-EEF36XDU.js → bootstrap-parser-LBLGVEMU.js} +1 -1
- package/dist/browser.global.js +149 -5
- package/dist/{build-QKOBBC23.js → build-THUEYMVT.js} +5 -4
- package/dist/{chunk-G7DJ6VOD.js → chunk-25XHSTPT.js} +2 -2
- package/dist/{chunk-A7GKPPU7.js → chunk-2VAWP6FI.js} +1 -1
- package/dist/{chunk-EMQDLDAF.js → chunk-3NZMMSOW.js} +80 -2
- package/dist/{chunk-B6OXJLJ5.js → chunk-5JUZ4HL7.js} +2 -2
- package/dist/chunk-6CV4XG3J.js +166 -0
- package/dist/{chunk-5TPFNWRU.js → chunk-7D7PZLB7.js} +3 -3
- package/dist/{chunk-ZWI3NIXK.js → chunk-7QIAF377.js} +54 -3
- package/dist/chunk-APU4OZIP.js +828 -0
- package/dist/{chunk-CTZHONLA.js → chunk-BXLTEUS4.js} +2 -2
- package/dist/{chunk-O5ABKEA7.js → chunk-DWHUZUEY.js} +2 -2
- package/dist/chunk-FMSTRBBS.js +17 -0
- package/dist/{chunk-Q6O7ZLO2.js → chunk-INWQHLPS.js} +1 -16
- package/dist/{chunk-U6U7EJZL.js → chunk-JKGPSFGH.js} +2 -2
- package/dist/{chunk-3WQLXYTP.js → chunk-MFKHTE5R.js} +2 -2
- package/dist/{chunk-TG6SEF24.js → chunk-OQU65525.js} +1 -1
- package/dist/{chunk-6S5CFQXY.js → chunk-QZ666FCV.js} +5 -5
- package/dist/{chunk-4FLICVVA.js → chunk-TD5GKIHP.js} +2 -2
- package/dist/{chunk-IS4WUH6Y.js → chunk-UTH7OXTM.js} +2 -2
- package/dist/{chunk-BNKJPUPQ.js → chunk-V4FZHJQX.js} +2 -2
- package/dist/{chunk-F66BVUYB.js → chunk-Y6WXAPKY.js} +3 -3
- package/dist/{chunk-QXBFT7NI.js → chunk-YNYCQECH.js} +2 -2
- package/dist/{chunk-PVTQQS3Y.js → chunk-YPCVY4GS.js} +31 -0
- package/dist/{chunk-W7LLXRGY.js → chunk-ZAF6JH23.js} +65 -10
- package/dist/cli/neuroverse.cjs +3176 -139
- package/dist/cli/neuroverse.js +40 -24
- package/dist/cli/plan.cjs +176 -12
- package/dist/cli/plan.js +2 -2
- package/dist/cli/run.cjs +63 -9
- package/dist/cli/run.js +2 -2
- package/dist/{configure-ai-6TZ3MCSI.js → configure-ai-5MP5DWTT.js} +5 -3
- package/dist/configure-world-XU2COHOZ.js +705 -0
- package/dist/{decision-flow-M63D47LO.js → decision-flow-3K4D72G4.js} +2 -2
- package/dist/{demo-G43RLCPK.js → demo-66MMJTEH.js} +3 -3
- package/dist/{derive-FJZVIPUZ.js → derive-5LOMN7GO.js} +6 -5
- package/dist/{doctor-6BC6X2VO.js → doctor-WIO4FLA3.js} +2 -1
- package/dist/{equity-penalties-SG5IZQ7I.js → equity-penalties-WWC7UDQD.js} +3 -3
- package/dist/{explain-RHBU2GBR.js → explain-MUSGDT67.js} +1 -1
- package/dist/{guard-AJCCGZMF.js → guard-W3BMQPBJ.js} +41 -7
- package/dist/{guard-contract-DqFcTScd.d.cts → guard-contract-CLBbTGK_.d.cts} +107 -1
- package/dist/{guard-contract-DqFcTScd.d.ts → guard-contract-CLBbTGK_.d.ts} +107 -1
- package/dist/{guard-engine-PNR6MHCM.js → guard-engine-N7TUIUU7.js} +5 -3
- package/dist/{impact-3XVDSCBU.js → impact-WIAM66IH.js} +3 -3
- package/dist/{improve-TQP4ECSY.js → improve-PJDAWW4Q.js} +3 -3
- package/dist/index.cjs +425 -62
- package/dist/index.d.cts +290 -66
- package/dist/index.d.ts +290 -66
- package/dist/index.js +33 -24
- package/dist/{init-FYPV4SST.js → init-TKIJDR7I.js} +5 -1
- package/dist/lens-IP6GIZ2Q.js +1017 -0
- package/dist/{mcp-server-5Y3ZM7TV.js → mcp-server-OG3PPVD2.js} +3 -3
- package/dist/mentraos-YFS7FMJH.js +48 -0
- package/dist/{playground-VZBNPPBO.js → playground-4BK2XQ47.js} +2 -2
- package/dist/{redteam-MZPZD3EF.js → redteam-BRZALBPP.js} +2 -2
- package/dist/{session-JYOARW54.js → session-SGRUT2UH.js} +3 -3
- package/dist/{shared-B8dvUUD8.d.cts → shared-BGzmYP5g.d.cts} +1 -1
- package/dist/{shared-Dr5Wiay8.d.ts → shared-CwGpPheR.d.ts} +1 -1
- package/dist/{simulate-LJXYBC6M.js → simulate-FGXKIH7V.js} +17 -4
- package/dist/{test-BOOR4A5F.js → test-PT44BSYG.js} +2 -2
- package/dist/{trace-PKV4KX56.js → trace-2YDNAXMK.js} +2 -2
- package/dist/{validate-RALX7CZS.js → validate-Q5O5TGLT.js} +1 -1
- package/dist/{world-BIP4GZBZ.js → world-V52ZMH26.js} +1 -1
- package/dist/{world-loader-Y6HMQH2D.js → world-loader-C4D3VPP3.js} +1 -1
- package/dist/worlds/mentraos-smartglasses.nv-world.md +423 -0
- package/dist/worlds/user-rules.nv-world.md +328 -0
- package/package.json +1 -1
- package/dist/chunk-MH7BT4VH.js +0 -15
package/dist/cli/neuroverse.cjs
CHANGED
|
@@ -172,14 +172,14 @@ function validateWorld(world, mode = "standard") {
|
|
|
172
172
|
findings.sort((a, b) => severityOrder[a.severity] - severityOrder[b.severity]);
|
|
173
173
|
const errors = findings.filter((f) => f.severity === "error").length;
|
|
174
174
|
const warnings = findings.filter((f) => f.severity === "warning").length;
|
|
175
|
-
const
|
|
175
|
+
const info2 = findings.filter((f) => f.severity === "info").length;
|
|
176
176
|
const completenessScore = computeCompletenessScore(world);
|
|
177
177
|
const invariantCoverage = computeInvariantCoverage(world);
|
|
178
178
|
const governanceHealth = computeGovernanceHealth(world, findings);
|
|
179
|
-
const
|
|
179
|
+
const summary2 = {
|
|
180
180
|
errors,
|
|
181
181
|
warnings,
|
|
182
|
-
info,
|
|
182
|
+
info: info2,
|
|
183
183
|
completenessScore,
|
|
184
184
|
invariantCoverage,
|
|
185
185
|
canRun: errors === 0,
|
|
@@ -193,7 +193,7 @@ function validateWorld(world, mode = "standard") {
|
|
|
193
193
|
validatedAt: Date.now(),
|
|
194
194
|
durationMs: performance.now() - startTime,
|
|
195
195
|
validationMode: mode,
|
|
196
|
-
summary,
|
|
196
|
+
summary: summary2,
|
|
197
197
|
findings
|
|
198
198
|
};
|
|
199
199
|
}
|
|
@@ -1615,6 +1615,67 @@ function parseValueLiteral(raw) {
|
|
|
1615
1615
|
if (!isNaN(num) && raw.trim() !== "") return num;
|
|
1616
1616
|
return raw;
|
|
1617
1617
|
}
|
|
1618
|
+
function parseLenses(content, startLine, issues) {
|
|
1619
|
+
const lenses = [];
|
|
1620
|
+
const subSections = splitH2Sections(content, startLine);
|
|
1621
|
+
for (const sub of subSections) {
|
|
1622
|
+
const props = parseKeyValueBullets(sub.content);
|
|
1623
|
+
const lineNum = sub.startLine;
|
|
1624
|
+
const directives = [];
|
|
1625
|
+
const lines = sub.content.split("\n");
|
|
1626
|
+
let directiveIndex = 0;
|
|
1627
|
+
for (let i = 0; i < lines.length; i++) {
|
|
1628
|
+
const line = lines[i].trim();
|
|
1629
|
+
if (line.startsWith(">")) {
|
|
1630
|
+
const blockContent = line.slice(1).trim();
|
|
1631
|
+
const colonIdx = blockContent.indexOf(":");
|
|
1632
|
+
if (colonIdx > 0) {
|
|
1633
|
+
const scope = blockContent.slice(0, colonIdx).trim();
|
|
1634
|
+
let instruction = blockContent.slice(colonIdx + 1).trim();
|
|
1635
|
+
for (let j = i + 1; j < lines.length; j++) {
|
|
1636
|
+
const nextLine = lines[j].trim();
|
|
1637
|
+
if (nextLine.startsWith(">")) {
|
|
1638
|
+
const nextContent = nextLine.slice(1).trim();
|
|
1639
|
+
const nextColon = nextContent.indexOf(":");
|
|
1640
|
+
if (nextColon > 0 && !nextContent.slice(0, nextColon).includes(" ")) {
|
|
1641
|
+
break;
|
|
1642
|
+
}
|
|
1643
|
+
instruction += " " + nextContent;
|
|
1644
|
+
i = j;
|
|
1645
|
+
} else {
|
|
1646
|
+
break;
|
|
1647
|
+
}
|
|
1648
|
+
}
|
|
1649
|
+
directives.push({
|
|
1650
|
+
id: `${sub.name}_directive_${directiveIndex++}`,
|
|
1651
|
+
scope,
|
|
1652
|
+
instruction,
|
|
1653
|
+
line: startLine + i
|
|
1654
|
+
});
|
|
1655
|
+
}
|
|
1656
|
+
}
|
|
1657
|
+
}
|
|
1658
|
+
const tags = (props.tags ?? "").split(",").map((s) => s.trim()).filter(Boolean);
|
|
1659
|
+
const defaultForRoles = (props.default_for_roles ?? props.roles ?? "").split(",").map((s) => s.trim()).filter(Boolean);
|
|
1660
|
+
lenses.push({
|
|
1661
|
+
id: sub.name,
|
|
1662
|
+
name: props.name ?? sub.name,
|
|
1663
|
+
tagline: props.tagline ?? "",
|
|
1664
|
+
description: props.description ?? "",
|
|
1665
|
+
tags,
|
|
1666
|
+
formality: props.formality ?? "neutral",
|
|
1667
|
+
verbosity: props.verbosity ?? "balanced",
|
|
1668
|
+
emotion: props.emotion ?? "neutral",
|
|
1669
|
+
confidence: props.confidence ?? "balanced",
|
|
1670
|
+
defaultForRoles,
|
|
1671
|
+
directives,
|
|
1672
|
+
priority: props.priority ? parseInt(props.priority, 10) : 50,
|
|
1673
|
+
stackable: props.stackable === "false" ? false : true,
|
|
1674
|
+
line: lineNum
|
|
1675
|
+
});
|
|
1676
|
+
}
|
|
1677
|
+
return lenses;
|
|
1678
|
+
}
|
|
1618
1679
|
function parseWorldMarkdown(markdown) {
|
|
1619
1680
|
const issues = [];
|
|
1620
1681
|
const { frontmatter: fmRaw, sections } = splitSections(markdown);
|
|
@@ -1652,8 +1713,22 @@ function parseWorldMarkdown(markdown) {
|
|
|
1652
1713
|
}
|
|
1653
1714
|
const outcomesSection = findSection("Outcomes");
|
|
1654
1715
|
const outcomes = outcomesSection ? parseOutcomes(outcomesSection.content, outcomesSection.startLine, issues) : [];
|
|
1716
|
+
const lensesSection = findSection("Lenses");
|
|
1717
|
+
const lenses = lensesSection ? parseLenses(lensesSection.content, lensesSection.startLine, issues) : [];
|
|
1718
|
+
let lensPolicy;
|
|
1719
|
+
let lensLockPin;
|
|
1720
|
+
if (lensesSection) {
|
|
1721
|
+
const topContent = lensesSection.content.split(/^##\s/m)[0];
|
|
1722
|
+
const topProps = parseKeyValueBullets(topContent);
|
|
1723
|
+
if (topProps.policy === "locked" || topProps.policy === "role_default" || topProps.policy === "user_choice") {
|
|
1724
|
+
lensPolicy = topProps.policy;
|
|
1725
|
+
}
|
|
1726
|
+
if (topProps.lock_pin) {
|
|
1727
|
+
lensLockPin = topProps.lock_pin;
|
|
1728
|
+
}
|
|
1729
|
+
}
|
|
1655
1730
|
const parsedSections = sections.map((s) => s.name);
|
|
1656
|
-
const knownSections = /* @__PURE__ */ new Set(["thesis", "invariants", "state", "assumptions", "rules", "gates", "outcomes"]);
|
|
1731
|
+
const knownSections = /* @__PURE__ */ new Set(["thesis", "invariants", "state", "assumptions", "rules", "gates", "outcomes", "lenses"]);
|
|
1657
1732
|
for (const section of sections) {
|
|
1658
1733
|
if (!knownSections.has(section.name.toLowerCase())) {
|
|
1659
1734
|
issues.push({
|
|
@@ -1679,7 +1754,10 @@ function parseWorldMarkdown(markdown) {
|
|
|
1679
1754
|
assumptions,
|
|
1680
1755
|
rules,
|
|
1681
1756
|
gates,
|
|
1682
|
-
outcomes
|
|
1757
|
+
outcomes,
|
|
1758
|
+
lenses,
|
|
1759
|
+
lensPolicy,
|
|
1760
|
+
lensLockPin
|
|
1683
1761
|
},
|
|
1684
1762
|
issues
|
|
1685
1763
|
};
|
|
@@ -1851,6 +1929,36 @@ function emitWorldDefinition(parsed) {
|
|
|
1851
1929
|
structural_indicators: rules.filter((r) => r.severity === "structural").map((r) => r.id)
|
|
1852
1930
|
}
|
|
1853
1931
|
};
|
|
1932
|
+
const validScopes = /* @__PURE__ */ new Set(["response_framing", "language_style", "content_filtering", "value_emphasis", "behavior_shaping"]);
|
|
1933
|
+
const lensConfigs = parsed.lenses.map((pl) => {
|
|
1934
|
+
const directives = pl.directives.map((d) => ({
|
|
1935
|
+
id: d.id,
|
|
1936
|
+
scope: validScopes.has(d.scope) ? d.scope : "behavior_shaping",
|
|
1937
|
+
instruction: d.instruction
|
|
1938
|
+
}));
|
|
1939
|
+
return {
|
|
1940
|
+
id: pl.id,
|
|
1941
|
+
name: pl.name,
|
|
1942
|
+
tagline: pl.tagline,
|
|
1943
|
+
description: pl.description,
|
|
1944
|
+
tags: pl.tags,
|
|
1945
|
+
tone: {
|
|
1946
|
+
formality: pl.formality || "neutral",
|
|
1947
|
+
verbosity: pl.verbosity || "balanced",
|
|
1948
|
+
emotion: pl.emotion || "neutral",
|
|
1949
|
+
confidence: pl.confidence || "balanced"
|
|
1950
|
+
},
|
|
1951
|
+
directives,
|
|
1952
|
+
defaultForRoles: pl.defaultForRoles,
|
|
1953
|
+
priority: pl.priority,
|
|
1954
|
+
stackable: pl.stackable
|
|
1955
|
+
};
|
|
1956
|
+
});
|
|
1957
|
+
const lensesConfig = lensConfigs.length > 0 ? {
|
|
1958
|
+
lenses: lensConfigs,
|
|
1959
|
+
...parsed.lensPolicy ? { policy: parsed.lensPolicy } : {},
|
|
1960
|
+
...parsed.lensLockPin ? { lockPin: parsed.lensLockPin } : {}
|
|
1961
|
+
} : void 0;
|
|
1854
1962
|
const metadata = {
|
|
1855
1963
|
format_version: "1.0.0",
|
|
1856
1964
|
created_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -1865,6 +1973,7 @@ function emitWorldDefinition(parsed) {
|
|
|
1865
1973
|
rules,
|
|
1866
1974
|
gates,
|
|
1867
1975
|
outcomes,
|
|
1976
|
+
...lensesConfig ? { lenses: lensesConfig } : {},
|
|
1868
1977
|
metadata
|
|
1869
1978
|
};
|
|
1870
1979
|
return { world: worldDefinition, issues };
|
|
@@ -1976,8 +2085,8 @@ async function loadWorldFromDirectory(dirPath) {
|
|
|
1976
2085
|
}
|
|
1977
2086
|
async function loadWorld(worldPath) {
|
|
1978
2087
|
const { stat } = await import("fs/promises");
|
|
1979
|
-
const
|
|
1980
|
-
if (
|
|
2088
|
+
const info2 = await stat(worldPath);
|
|
2089
|
+
if (info2.isDirectory()) {
|
|
1981
2090
|
return loadWorldFromDirectory(worldPath);
|
|
1982
2091
|
}
|
|
1983
2092
|
throw new Error(`Cannot load world from: ${worldPath} \u2014 expected a directory`);
|
|
@@ -3840,14 +3949,14 @@ var init_explain_engine = __esm({
|
|
|
3840
3949
|
async function resolveWorldPath2(input) {
|
|
3841
3950
|
const { stat } = await import("fs/promises");
|
|
3842
3951
|
try {
|
|
3843
|
-
const
|
|
3844
|
-
if (
|
|
3952
|
+
const info2 = await stat(input);
|
|
3953
|
+
if (info2.isDirectory()) return input;
|
|
3845
3954
|
} catch {
|
|
3846
3955
|
}
|
|
3847
3956
|
const neuroversePath = `.neuroverse/worlds/${input}`;
|
|
3848
3957
|
try {
|
|
3849
|
-
const
|
|
3850
|
-
if (
|
|
3958
|
+
const info2 = await stat(neuroversePath);
|
|
3959
|
+
if (info2.isDirectory()) return neuroversePath;
|
|
3851
3960
|
} catch {
|
|
3852
3961
|
}
|
|
3853
3962
|
throw new Error(
|
|
@@ -3950,15 +4059,25 @@ function simulateWorld(world, options = {}) {
|
|
|
3950
4059
|
let collapseStep;
|
|
3951
4060
|
let collapseRule;
|
|
3952
4061
|
const sortedRules = [...world.rules].sort((a, b) => a.order - b.order);
|
|
4062
|
+
const allEvents = options.events ?? [];
|
|
4063
|
+
const eventsByStep = Array.from({ length: steps }, () => []);
|
|
4064
|
+
for (let i = 0; i < allEvents.length; i++) {
|
|
4065
|
+
const stepIdx = Math.min(i, steps - 1);
|
|
4066
|
+
eventsByStep[stepIdx].push(allEvents[i]);
|
|
4067
|
+
}
|
|
4068
|
+
let totalEventsConsumed = 0;
|
|
3953
4069
|
for (let stepNum = 1; stepNum <= steps; stepNum++) {
|
|
3954
4070
|
if (collapsed) break;
|
|
4071
|
+
const stepEvents = eventsByStep[stepNum - 1];
|
|
3955
4072
|
const stepResult = evaluateStep(
|
|
3956
4073
|
stepNum,
|
|
3957
4074
|
sortedRules,
|
|
3958
4075
|
state,
|
|
3959
4076
|
assumptions,
|
|
3960
|
-
world
|
|
4077
|
+
world,
|
|
4078
|
+
stepEvents
|
|
3961
4079
|
);
|
|
4080
|
+
totalEventsConsumed += stepResult.eventsApplied.length;
|
|
3962
4081
|
simulationSteps.push(stepResult);
|
|
3963
4082
|
if (stepResult.collapsed) {
|
|
3964
4083
|
collapsed = true;
|
|
@@ -3977,14 +4096,38 @@ function simulateWorld(world, options = {}) {
|
|
|
3977
4096
|
finalViability,
|
|
3978
4097
|
collapsed,
|
|
3979
4098
|
collapseStep,
|
|
3980
|
-
collapseRule
|
|
4099
|
+
collapseRule,
|
|
4100
|
+
eventsConsumed: totalEventsConsumed
|
|
3981
4101
|
};
|
|
3982
4102
|
}
|
|
3983
|
-
function evaluateStep(stepNum, rules, state, assumptions, world) {
|
|
4103
|
+
function evaluateStep(stepNum, rules, state, assumptions, world, events = []) {
|
|
3984
4104
|
const evaluations = [];
|
|
4105
|
+
const eventApplications = [];
|
|
3985
4106
|
let rulesFired = 0;
|
|
3986
4107
|
let collapsed = false;
|
|
3987
4108
|
const firedRuleIds = /* @__PURE__ */ new Set();
|
|
4109
|
+
for (const evt of events) {
|
|
4110
|
+
const application = {
|
|
4111
|
+
eventType: evt.type,
|
|
4112
|
+
rulesTriggered: [],
|
|
4113
|
+
effects: []
|
|
4114
|
+
};
|
|
4115
|
+
for (const rule of rules) {
|
|
4116
|
+
const eventTrigger = rule.triggers.find(
|
|
4117
|
+
(t) => t.field === "event" && t.source === "state"
|
|
4118
|
+
);
|
|
4119
|
+
if (!eventTrigger) continue;
|
|
4120
|
+
const matches = evaluateOperator(evt.type, eventTrigger.operator, eventTrigger.value);
|
|
4121
|
+
if (!matches) continue;
|
|
4122
|
+
application.rulesTriggered.push(rule.id);
|
|
4123
|
+
firedRuleIds.add(rule.id);
|
|
4124
|
+
for (const effect of rule.effects ?? []) {
|
|
4125
|
+
const applied = applyEffect(effect, state);
|
|
4126
|
+
if (applied) application.effects.push(applied);
|
|
4127
|
+
}
|
|
4128
|
+
}
|
|
4129
|
+
eventApplications.push(application);
|
|
4130
|
+
}
|
|
3988
4131
|
for (const rule of rules) {
|
|
3989
4132
|
if (collapsed) {
|
|
3990
4133
|
evaluations.push({
|
|
@@ -4069,6 +4212,7 @@ function evaluateStep(stepNum, rules, state, assumptions, world) {
|
|
|
4069
4212
|
const viability = classifyViability(state, world);
|
|
4070
4213
|
return {
|
|
4071
4214
|
step: stepNum,
|
|
4215
|
+
eventsApplied: eventApplications,
|
|
4072
4216
|
rulesEvaluated: evaluations,
|
|
4073
4217
|
rulesFired,
|
|
4074
4218
|
stateAfter: { ...state },
|
|
@@ -4190,6 +4334,19 @@ function renderSimulateText(result) {
|
|
|
4190
4334
|
lines.push("");
|
|
4191
4335
|
for (const step of result.steps) {
|
|
4192
4336
|
lines.push(`STEP ${step.step}`);
|
|
4337
|
+
if (step.eventsApplied && step.eventsApplied.length > 0) {
|
|
4338
|
+
for (const evt of step.eventsApplied) {
|
|
4339
|
+
lines.push(` EVENT: ${evt.eventType}`);
|
|
4340
|
+
if (evt.rulesTriggered.length > 0) {
|
|
4341
|
+
lines.push(` Rules triggered: ${evt.rulesTriggered.join(", ")}`);
|
|
4342
|
+
}
|
|
4343
|
+
for (const effect of evt.effects) {
|
|
4344
|
+
const beforeStr = formatValue(effect.before);
|
|
4345
|
+
const afterStr = formatValue(effect.after);
|
|
4346
|
+
lines.push(` ${effect.target}: ${beforeStr} -> ${afterStr}`);
|
|
4347
|
+
}
|
|
4348
|
+
}
|
|
4349
|
+
}
|
|
4193
4350
|
const fired = step.rulesEvaluated.filter((r) => r.triggered);
|
|
4194
4351
|
const skipped = step.rulesEvaluated.filter((r) => !r.triggered && !r.excluded);
|
|
4195
4352
|
const excluded = step.rulesEvaluated.filter((r) => r.excluded);
|
|
@@ -4225,6 +4382,9 @@ function renderSimulateText(result) {
|
|
|
4225
4382
|
lines.push(` ${key}: ${formatValue(value)}${marker}`);
|
|
4226
4383
|
}
|
|
4227
4384
|
lines.push("");
|
|
4385
|
+
if (result.eventsConsumed > 0) {
|
|
4386
|
+
lines.push(`EVENTS CONSUMED: ${result.eventsConsumed}`);
|
|
4387
|
+
}
|
|
4228
4388
|
lines.push(`VIABILITY: ${result.finalViability}`);
|
|
4229
4389
|
if (result.collapsed) {
|
|
4230
4390
|
lines.push(`COLLAPSED at step ${result.collapseStep} (rule: ${result.collapseRule})`);
|
|
@@ -4253,6 +4413,7 @@ function parseArgs4(argv) {
|
|
|
4253
4413
|
let steps = 1;
|
|
4254
4414
|
let json = false;
|
|
4255
4415
|
let profile;
|
|
4416
|
+
let eventsPath;
|
|
4256
4417
|
const stateOverrides = {};
|
|
4257
4418
|
for (let i = 0; i < argv.length; i++) {
|
|
4258
4419
|
const arg = argv[i];
|
|
@@ -4264,6 +4425,8 @@ function parseArgs4(argv) {
|
|
|
4264
4425
|
if (steps > 50) steps = 50;
|
|
4265
4426
|
} else if (arg === "--profile" && i + 1 < argv.length) {
|
|
4266
4427
|
profile = argv[++i];
|
|
4428
|
+
} else if (arg === "--events" && i + 1 < argv.length) {
|
|
4429
|
+
eventsPath = argv[++i];
|
|
4267
4430
|
} else if (arg === "--set" && i + 1 < argv.length) {
|
|
4268
4431
|
const pair = argv[++i];
|
|
4269
4432
|
const eqIdx = pair.indexOf("=");
|
|
@@ -4279,17 +4442,27 @@ function parseArgs4(argv) {
|
|
|
4279
4442
|
if (!worldPath) {
|
|
4280
4443
|
throw new Error("Usage: neuroverse simulate <world-path-or-id> [--steps N] [--set key=value]");
|
|
4281
4444
|
}
|
|
4282
|
-
return { worldPath, steps, stateOverrides, profile, json };
|
|
4445
|
+
return { worldPath, steps, stateOverrides, profile, json, eventsPath };
|
|
4283
4446
|
}
|
|
4284
4447
|
async function main4(argv = process.argv.slice(2)) {
|
|
4285
4448
|
try {
|
|
4286
4449
|
const args = parseArgs4(argv);
|
|
4287
4450
|
const resolvedPath = await resolveWorldPath2(args.worldPath);
|
|
4288
4451
|
const world = await loadWorld(resolvedPath);
|
|
4452
|
+
let events;
|
|
4453
|
+
if (args.eventsPath) {
|
|
4454
|
+
const { readFile: readFile3 } = await import("fs/promises");
|
|
4455
|
+
const raw = await readFile3(args.eventsPath, "utf-8");
|
|
4456
|
+
const parsed = JSON.parse(raw);
|
|
4457
|
+
events = Array.isArray(parsed) ? parsed : [parsed];
|
|
4458
|
+
process.stderr.write(`Loaded ${events.length} event(s) from ${args.eventsPath}
|
|
4459
|
+
`);
|
|
4460
|
+
}
|
|
4289
4461
|
const result = simulateWorld(world, {
|
|
4290
4462
|
steps: args.steps,
|
|
4291
4463
|
stateOverrides: Object.keys(args.stateOverrides).length > 0 ? args.stateOverrides : void 0,
|
|
4292
|
-
profile: args.profile
|
|
4464
|
+
profile: args.profile,
|
|
4465
|
+
events
|
|
4293
4466
|
});
|
|
4294
4467
|
if (args.json) {
|
|
4295
4468
|
process.stdout.write(JSON.stringify(result, null, 2) + "\n");
|
|
@@ -4854,9 +5027,13 @@ async function main6(argv = process.argv.slice(2)) {
|
|
|
4854
5027
|
`neuroverse bootstrap --input ${args.outputPath} --output ./world/ --validate`,
|
|
4855
5028
|
"neuroverse validate --world ./world/",
|
|
4856
5029
|
`echo '{"intent":"test action"}' | neuroverse guard --world ./world/`
|
|
4857
|
-
]
|
|
5030
|
+
],
|
|
5031
|
+
tip: "Run `neuroverse configure-world` for an interactive wizard that builds state variables, rules, and gates from plain language \u2014 no syntax required."
|
|
4858
5032
|
};
|
|
4859
5033
|
process.stdout.write(JSON.stringify(result, null, 2) + "\n");
|
|
5034
|
+
process.stderr.write(
|
|
5035
|
+
"\nTip: Run `neuroverse configure-world` for an interactive wizard\nthat builds state, rules, and gates from plain language \u2014 no syntax required.\n"
|
|
5036
|
+
);
|
|
4860
5037
|
process.exit(0);
|
|
4861
5038
|
} catch (e) {
|
|
4862
5039
|
process.stderr.write(`Init failed: ${e}
|
|
@@ -6131,7 +6308,8 @@ var init_plan_engine = __esm({
|
|
|
6131
6308
|
var guard_engine_exports = {};
|
|
6132
6309
|
__export(guard_engine_exports, {
|
|
6133
6310
|
evaluateGuard: () => evaluateGuard,
|
|
6134
|
-
eventToAllowlistKey: () => eventToAllowlistKey
|
|
6311
|
+
eventToAllowlistKey: () => eventToAllowlistKey,
|
|
6312
|
+
verdictToEvent: () => verdictToEvent
|
|
6135
6313
|
});
|
|
6136
6314
|
function levelRequiresConfirmation(level, actionType) {
|
|
6137
6315
|
if (level === "strict") return true;
|
|
@@ -6206,6 +6384,33 @@ function evaluateGuard(event, world, options = {}) {
|
|
|
6206
6384
|
let decidingId;
|
|
6207
6385
|
const guardsMatched = [];
|
|
6208
6386
|
const rulesMatched = [];
|
|
6387
|
+
if (options.emergencyOverride) {
|
|
6388
|
+
checkInvariantCoverage(world, invariantChecks);
|
|
6389
|
+
return buildVerdict(
|
|
6390
|
+
"ALLOW",
|
|
6391
|
+
void 0,
|
|
6392
|
+
"emergency-override",
|
|
6393
|
+
"Emergency override active \u2014 all governance rules suspended. Platform constraints still apply.",
|
|
6394
|
+
world,
|
|
6395
|
+
level,
|
|
6396
|
+
invariantChecks,
|
|
6397
|
+
guardsMatched,
|
|
6398
|
+
rulesMatched,
|
|
6399
|
+
includeTrace ? buildTrace(
|
|
6400
|
+
invariantChecks,
|
|
6401
|
+
safetyChecks,
|
|
6402
|
+
planCheckResult,
|
|
6403
|
+
roleChecks,
|
|
6404
|
+
guardChecks,
|
|
6405
|
+
kernelRuleChecks,
|
|
6406
|
+
levelChecks,
|
|
6407
|
+
"session-allowlist",
|
|
6408
|
+
"emergency-override",
|
|
6409
|
+
startTime
|
|
6410
|
+
) : void 0,
|
|
6411
|
+
event.intent
|
|
6412
|
+
);
|
|
6413
|
+
}
|
|
6209
6414
|
checkInvariantCoverage(world, invariantChecks);
|
|
6210
6415
|
if (event.roleId && options.agentStates) {
|
|
6211
6416
|
const agentState = options.agentStates.get(event.roleId);
|
|
@@ -6270,7 +6475,8 @@ function evaluateGuard(event, world, options = {}) {
|
|
|
6270
6475
|
decidingLayer,
|
|
6271
6476
|
decidingId,
|
|
6272
6477
|
startTime
|
|
6273
|
-
) : void 0
|
|
6478
|
+
) : void 0,
|
|
6479
|
+
event.intent
|
|
6274
6480
|
);
|
|
6275
6481
|
}
|
|
6276
6482
|
}
|
|
@@ -6299,7 +6505,8 @@ function evaluateGuard(event, world, options = {}) {
|
|
|
6299
6505
|
decidingLayer,
|
|
6300
6506
|
decidingId,
|
|
6301
6507
|
startTime
|
|
6302
|
-
) : void 0
|
|
6508
|
+
) : void 0,
|
|
6509
|
+
event.intent
|
|
6303
6510
|
);
|
|
6304
6511
|
}
|
|
6305
6512
|
if (options.plan) {
|
|
@@ -6334,7 +6541,8 @@ function evaluateGuard(event, world, options = {}) {
|
|
|
6334
6541
|
decidingLayer,
|
|
6335
6542
|
decidingId,
|
|
6336
6543
|
startTime
|
|
6337
|
-
) : void 0
|
|
6544
|
+
) : void 0,
|
|
6545
|
+
event.intent
|
|
6338
6546
|
);
|
|
6339
6547
|
}
|
|
6340
6548
|
}
|
|
@@ -6363,7 +6571,8 @@ function evaluateGuard(event, world, options = {}) {
|
|
|
6363
6571
|
decidingLayer,
|
|
6364
6572
|
decidingId,
|
|
6365
6573
|
startTime
|
|
6366
|
-
) : void 0
|
|
6574
|
+
) : void 0,
|
|
6575
|
+
event.intent
|
|
6367
6576
|
);
|
|
6368
6577
|
}
|
|
6369
6578
|
const guardVerdict = checkGuards(event, eventText, world, guardChecks, guardsMatched);
|
|
@@ -6401,7 +6610,8 @@ function evaluateGuard(event, world, options = {}) {
|
|
|
6401
6610
|
decidingLayer,
|
|
6402
6611
|
decidingId,
|
|
6403
6612
|
startTime
|
|
6404
|
-
) : void 0
|
|
6613
|
+
) : void 0,
|
|
6614
|
+
event.intent
|
|
6405
6615
|
);
|
|
6406
6616
|
verdict.intentRecord = intentRecord;
|
|
6407
6617
|
if (guardVerdict.consequence) verdict.consequence = guardVerdict.consequence;
|
|
@@ -6434,7 +6644,8 @@ function evaluateGuard(event, world, options = {}) {
|
|
|
6434
6644
|
decidingLayer,
|
|
6435
6645
|
decidingId,
|
|
6436
6646
|
startTime
|
|
6437
|
-
) : void 0
|
|
6647
|
+
) : void 0,
|
|
6648
|
+
event.intent
|
|
6438
6649
|
);
|
|
6439
6650
|
}
|
|
6440
6651
|
const levelVerdict = checkLevelConstraints(event, level, levelChecks);
|
|
@@ -6462,7 +6673,8 @@ function evaluateGuard(event, world, options = {}) {
|
|
|
6462
6673
|
decidingLayer,
|
|
6463
6674
|
decidingId,
|
|
6464
6675
|
startTime
|
|
6465
|
-
) : void 0
|
|
6676
|
+
) : void 0,
|
|
6677
|
+
event.intent
|
|
6466
6678
|
);
|
|
6467
6679
|
}
|
|
6468
6680
|
const warning = guardVerdict?.warning;
|
|
@@ -6487,7 +6699,8 @@ function evaluateGuard(event, world, options = {}) {
|
|
|
6487
6699
|
decidingLayer,
|
|
6488
6700
|
decidingId,
|
|
6489
6701
|
startTime
|
|
6490
|
-
) : void 0
|
|
6702
|
+
) : void 0,
|
|
6703
|
+
event.intent
|
|
6491
6704
|
);
|
|
6492
6705
|
}
|
|
6493
6706
|
function checkInvariantCoverage(world, checks) {
|
|
@@ -6864,7 +7077,7 @@ function buildTrace(invariantChecks, safetyChecks, planCheck, roleChecks, guardC
|
|
|
6864
7077
|
}
|
|
6865
7078
|
return trace;
|
|
6866
7079
|
}
|
|
6867
|
-
function buildVerdict(status, reason, ruleId, warning, world, level, invariantChecks, guardsMatched, rulesMatched, trace) {
|
|
7080
|
+
function buildVerdict(status, reason, ruleId, warning, world, level, invariantChecks, guardsMatched, rulesMatched, trace, eventIntent) {
|
|
6868
7081
|
const evidence = {
|
|
6869
7082
|
worldId: world.world.world_id,
|
|
6870
7083
|
worldName: world.world.name,
|
|
@@ -6884,8 +7097,27 @@ function buildVerdict(status, reason, ruleId, warning, world, level, invariantCh
|
|
|
6884
7097
|
if (ruleId) verdict.ruleId = ruleId;
|
|
6885
7098
|
if (warning) verdict.warning = warning;
|
|
6886
7099
|
if (trace) verdict.trace = trace;
|
|
7100
|
+
verdict.event = verdictToEvent(status, eventIntent);
|
|
6887
7101
|
return verdict;
|
|
6888
7102
|
}
|
|
7103
|
+
function verdictToEvent(status, intent) {
|
|
7104
|
+
const statusEventMap = {
|
|
7105
|
+
ALLOW: "action_allowed",
|
|
7106
|
+
BLOCK: "action_blocked",
|
|
7107
|
+
PAUSE: "action_paused",
|
|
7108
|
+
MODIFY: "action_modified",
|
|
7109
|
+
PENALIZE: "action_penalized",
|
|
7110
|
+
REWARD: "action_rewarded",
|
|
7111
|
+
NEUTRAL: "action_neutral"
|
|
7112
|
+
};
|
|
7113
|
+
return {
|
|
7114
|
+
type: intent || statusEventMap[status] || "unknown_action",
|
|
7115
|
+
actor: "agent",
|
|
7116
|
+
source: "guard",
|
|
7117
|
+
timestamp: Date.now(),
|
|
7118
|
+
guardStatus: status
|
|
7119
|
+
};
|
|
7120
|
+
}
|
|
6889
7121
|
var PROMPT_INJECTION_PATTERNS, EXECUTION_CLAIM_PATTERNS, EXECUTION_INTENT_PATTERNS, SCOPE_ESCAPE_PATTERNS, NEUTRAL_MESSAGES, MAX_INPUT_LENGTH;
|
|
6890
7122
|
var init_guard_engine = __esm({
|
|
6891
7123
|
"src/engine/guard-engine.ts"() {
|
|
@@ -6959,6 +7191,161 @@ var init_guard_engine = __esm({
|
|
|
6959
7191
|
}
|
|
6960
7192
|
});
|
|
6961
7193
|
|
|
7194
|
+
// src/engine/intent-classifier.ts
|
|
7195
|
+
function buildSystemPrompt2(knownIntents) {
|
|
7196
|
+
let prompt = `You are an intent classifier for an AI governance system. Your job is to analyze structured content fields and produce a clean, semantic intent label.
|
|
7197
|
+
|
|
7198
|
+
CRITICAL RULES:
|
|
7199
|
+
1. Distinguish WHO is performing the action. If the AI agent says "I am escalating your request", that is the AI being polite \u2014 NOT the customer demanding escalation.
|
|
7200
|
+
2. Focus on the CUSTOMER'S actual intent, not the AI's response language.
|
|
7201
|
+
3. Return a short, snake_case intent label (e.g. "shipping_inquiry", "complaint_escalation", "password_reset").
|
|
7202
|
+
4. Assess the actor: who initiated this action? The customer, the AI agent, or the system?
|
|
7203
|
+
|
|
7204
|
+
You must respond with ONLY valid JSON in this exact format:
|
|
7205
|
+
{"intent": "<label>", "confidence": <0-1>, "actor": "<customer|ai_agent|system|unknown>", "reasoning": "<one sentence>"}`;
|
|
7206
|
+
if (knownIntents && knownIntents.length > 0) {
|
|
7207
|
+
prompt += `
|
|
7208
|
+
|
|
7209
|
+
Preferred intent labels (use these when applicable, but you may create new ones if none fit):
|
|
7210
|
+
${knownIntents.map((i) => `- ${i}`).join("\n")}`;
|
|
7211
|
+
}
|
|
7212
|
+
return prompt;
|
|
7213
|
+
}
|
|
7214
|
+
function buildUserPrompt2(fields) {
|
|
7215
|
+
const parts = [];
|
|
7216
|
+
if (fields.customer_input) {
|
|
7217
|
+
parts.push(`CUSTOMER INPUT:
|
|
7218
|
+
${fields.customer_input}`);
|
|
7219
|
+
}
|
|
7220
|
+
if (fields.draft_reply) {
|
|
7221
|
+
parts.push(`AI DRAFT REPLY:
|
|
7222
|
+
${fields.draft_reply}`);
|
|
7223
|
+
}
|
|
7224
|
+
if (fields.tool) {
|
|
7225
|
+
parts.push(`TOOL: ${fields.tool}`);
|
|
7226
|
+
}
|
|
7227
|
+
if (fields.context) {
|
|
7228
|
+
parts.push(`CONTEXT: ${fields.context}`);
|
|
7229
|
+
}
|
|
7230
|
+
if (fields.raw && parts.length === 0) {
|
|
7231
|
+
parts.push(`RAW TEXT:
|
|
7232
|
+
${fields.raw}`);
|
|
7233
|
+
}
|
|
7234
|
+
return parts.join("\n\n");
|
|
7235
|
+
}
|
|
7236
|
+
async function classifyIntentWithAI(fields, options) {
|
|
7237
|
+
const provider = createProvider(options.ai);
|
|
7238
|
+
const systemPrompt = buildSystemPrompt2(options.knownIntents);
|
|
7239
|
+
const userPrompt = buildUserPrompt2(fields);
|
|
7240
|
+
const response = await provider.complete(systemPrompt, userPrompt);
|
|
7241
|
+
const jsonMatch = response.match(/\{[\s\S]*\}/);
|
|
7242
|
+
if (!jsonMatch) {
|
|
7243
|
+
throw new Error("Intent classifier returned non-JSON response");
|
|
7244
|
+
}
|
|
7245
|
+
const parsed = JSON.parse(jsonMatch[0]);
|
|
7246
|
+
if (!parsed.intent || typeof parsed.intent !== "string") {
|
|
7247
|
+
throw new Error("Intent classifier returned invalid intent label");
|
|
7248
|
+
}
|
|
7249
|
+
return {
|
|
7250
|
+
intent: parsed.intent,
|
|
7251
|
+
confidence: typeof parsed.confidence === "number" ? parsed.confidence : 0.5,
|
|
7252
|
+
actor: ["customer", "ai_agent", "system", "unknown"].includes(
|
|
7253
|
+
parsed.actor
|
|
7254
|
+
) ? parsed.actor : "unknown",
|
|
7255
|
+
reasoning: parsed.reasoning ?? ""
|
|
7256
|
+
};
|
|
7257
|
+
}
|
|
7258
|
+
function extractContentFields(intent, args) {
|
|
7259
|
+
if (!args) {
|
|
7260
|
+
return { raw: intent };
|
|
7261
|
+
}
|
|
7262
|
+
const fields = {};
|
|
7263
|
+
let hasStructuredContent = false;
|
|
7264
|
+
for (const [key, value] of Object.entries(args)) {
|
|
7265
|
+
if (typeof value !== "string") continue;
|
|
7266
|
+
const lowerKey = key.toLowerCase();
|
|
7267
|
+
if (OUTPUT_CONTENT_FIELDS.has(lowerKey)) {
|
|
7268
|
+
fields.draft_reply = fields.draft_reply ? `${fields.draft_reply}
|
|
7269
|
+
|
|
7270
|
+
${value}` : value;
|
|
7271
|
+
hasStructuredContent = true;
|
|
7272
|
+
}
|
|
7273
|
+
}
|
|
7274
|
+
if (hasStructuredContent) {
|
|
7275
|
+
fields.customer_input = intent;
|
|
7276
|
+
} else {
|
|
7277
|
+
fields.raw = intent;
|
|
7278
|
+
}
|
|
7279
|
+
return fields;
|
|
7280
|
+
}
|
|
7281
|
+
var OUTPUT_CONTENT_FIELDS;
|
|
7282
|
+
var init_intent_classifier = __esm({
|
|
7283
|
+
"src/engine/intent-classifier.ts"() {
|
|
7284
|
+
"use strict";
|
|
7285
|
+
init_ai_provider();
|
|
7286
|
+
OUTPUT_CONTENT_FIELDS = /* @__PURE__ */ new Set([
|
|
7287
|
+
"draft_reply",
|
|
7288
|
+
"content",
|
|
7289
|
+
"body",
|
|
7290
|
+
"message",
|
|
7291
|
+
"text",
|
|
7292
|
+
"reply",
|
|
7293
|
+
"response",
|
|
7294
|
+
"output",
|
|
7295
|
+
"html",
|
|
7296
|
+
"template"
|
|
7297
|
+
]);
|
|
7298
|
+
}
|
|
7299
|
+
});
|
|
7300
|
+
|
|
7301
|
+
// src/engine/ai-guard.ts
|
|
7302
|
+
async function evaluateGuardWithAI(event, world, options = {}) {
|
|
7303
|
+
if (!options.ai) {
|
|
7304
|
+
const verdict = evaluateGuard(event, world, options);
|
|
7305
|
+
verdict.intent_source = "raw";
|
|
7306
|
+
return verdict;
|
|
7307
|
+
}
|
|
7308
|
+
const fallbackOnError = options.fallbackOnError ?? true;
|
|
7309
|
+
const originalIntent = event.intent;
|
|
7310
|
+
const knownIntents = options.knownIntents ?? extractKnownIntents(world);
|
|
7311
|
+
const contentFields = options.contentFields ?? extractContentFields(event.intent, event.args);
|
|
7312
|
+
try {
|
|
7313
|
+
const classification = await classifyIntentWithAI(contentFields, {
|
|
7314
|
+
ai: options.ai,
|
|
7315
|
+
knownIntents
|
|
7316
|
+
});
|
|
7317
|
+
const classifiedEvent = {
|
|
7318
|
+
...event,
|
|
7319
|
+
intent: classification.intent
|
|
7320
|
+
};
|
|
7321
|
+
const verdict = evaluateGuard(classifiedEvent, world, options);
|
|
7322
|
+
verdict.intent_source = "ai";
|
|
7323
|
+
verdict.classification = classification;
|
|
7324
|
+
verdict.originalIntent = originalIntent;
|
|
7325
|
+
return verdict;
|
|
7326
|
+
} catch (err) {
|
|
7327
|
+
if (fallbackOnError) {
|
|
7328
|
+
const verdict = evaluateGuard(event, world, options);
|
|
7329
|
+
verdict.intent_source = "fallback";
|
|
7330
|
+
verdict.originalIntent = originalIntent;
|
|
7331
|
+
return verdict;
|
|
7332
|
+
}
|
|
7333
|
+
throw err;
|
|
7334
|
+
}
|
|
7335
|
+
}
|
|
7336
|
+
function extractKnownIntents(world) {
|
|
7337
|
+
const vocab = world.guards?.intent_vocabulary;
|
|
7338
|
+
if (!vocab) return [];
|
|
7339
|
+
return Object.keys(vocab);
|
|
7340
|
+
}
|
|
7341
|
+
var init_ai_guard = __esm({
|
|
7342
|
+
"src/engine/ai-guard.ts"() {
|
|
7343
|
+
"use strict";
|
|
7344
|
+
init_guard_engine();
|
|
7345
|
+
init_intent_classifier();
|
|
7346
|
+
}
|
|
7347
|
+
});
|
|
7348
|
+
|
|
6962
7349
|
// src/contracts/guard-contract.ts
|
|
6963
7350
|
var GUARD_EXIT_CODES;
|
|
6964
7351
|
var init_guard_contract = __esm({
|
|
@@ -6986,12 +7373,15 @@ function parseArgs11(argv) {
|
|
|
6986
7373
|
let worldPath = "";
|
|
6987
7374
|
let trace = false;
|
|
6988
7375
|
let level;
|
|
7376
|
+
let aiClassify = false;
|
|
6989
7377
|
for (let i = 0; i < argv.length; i++) {
|
|
6990
7378
|
const arg = argv[i];
|
|
6991
7379
|
if (arg === "--world" && i + 1 < argv.length) {
|
|
6992
7380
|
worldPath = argv[++i];
|
|
6993
7381
|
} else if (arg === "--trace") {
|
|
6994
7382
|
trace = true;
|
|
7383
|
+
} else if (arg === "--ai-classify") {
|
|
7384
|
+
aiClassify = true;
|
|
6995
7385
|
} else if (arg === "--level" && i + 1 < argv.length) {
|
|
6996
7386
|
const val = argv[++i];
|
|
6997
7387
|
if (val === "basic" || val === "standard" || val === "strict") {
|
|
@@ -7001,7 +7391,7 @@ function parseArgs11(argv) {
|
|
|
7001
7391
|
}
|
|
7002
7392
|
}
|
|
7003
7393
|
}
|
|
7004
|
-
return { worldPath, trace, level };
|
|
7394
|
+
return { worldPath, trace, level, aiClassify };
|
|
7005
7395
|
}
|
|
7006
7396
|
async function main11(argv = process.argv.slice(2)) {
|
|
7007
7397
|
try {
|
|
@@ -7040,8 +7430,27 @@ async function main11(argv = process.argv.slice(2)) {
|
|
|
7040
7430
|
process.exit(GUARD_EXIT_CODES.ERROR);
|
|
7041
7431
|
}
|
|
7042
7432
|
const world = await loadWorld(worldPath);
|
|
7043
|
-
|
|
7044
|
-
|
|
7433
|
+
let verdict;
|
|
7434
|
+
if (args.aiClassify) {
|
|
7435
|
+
const aiConfig = resolveAIConfig();
|
|
7436
|
+
if (!aiConfig) {
|
|
7437
|
+
const errorResult = {
|
|
7438
|
+
error: "AI classification requires an API key. Set NEUROVERSE_AI_API_KEY and optionally NEUROVERSE_AI_MODEL, NEUROVERSE_AI_ENDPOINT."
|
|
7439
|
+
};
|
|
7440
|
+
process.stdout.write(JSON.stringify(errorResult, null, 2) + "\n");
|
|
7441
|
+
process.exit(GUARD_EXIT_CODES.ERROR);
|
|
7442
|
+
}
|
|
7443
|
+
process.stderr.write("AI intent classification enabled\n");
|
|
7444
|
+
verdict = await evaluateGuardWithAI(event, world, {
|
|
7445
|
+
trace: args.trace,
|
|
7446
|
+
level: args.level,
|
|
7447
|
+
ai: aiConfig,
|
|
7448
|
+
contentFields: event.contentFields
|
|
7449
|
+
});
|
|
7450
|
+
} else {
|
|
7451
|
+
const options = { trace: args.trace, level: args.level };
|
|
7452
|
+
verdict = evaluateGuard(event, world, options);
|
|
7453
|
+
}
|
|
7045
7454
|
process.stdout.write(JSON.stringify(verdict, null, 2) + "\n");
|
|
7046
7455
|
const exitCode = GUARD_EXIT_CODES[verdict.status];
|
|
7047
7456
|
process.exit(exitCode);
|
|
@@ -7051,10 +7460,21 @@ async function main11(argv = process.argv.slice(2)) {
|
|
|
7051
7460
|
process.exit(GUARD_EXIT_CODES.ERROR);
|
|
7052
7461
|
}
|
|
7053
7462
|
}
|
|
7463
|
+
function resolveAIConfig() {
|
|
7464
|
+
const apiKey = process.env.NEUROVERSE_AI_API_KEY;
|
|
7465
|
+
if (!apiKey) return null;
|
|
7466
|
+
return {
|
|
7467
|
+
provider: "openai",
|
|
7468
|
+
model: process.env.NEUROVERSE_AI_MODEL ?? "gpt-4o-mini",
|
|
7469
|
+
apiKey,
|
|
7470
|
+
endpoint: process.env.NEUROVERSE_AI_ENDPOINT ?? null
|
|
7471
|
+
};
|
|
7472
|
+
}
|
|
7054
7473
|
var init_guard = __esm({
|
|
7055
7474
|
"src/cli/guard.ts"() {
|
|
7056
7475
|
"use strict";
|
|
7057
7476
|
init_guard_engine();
|
|
7477
|
+
init_ai_guard();
|
|
7058
7478
|
init_world_loader();
|
|
7059
7479
|
init_world_resolver();
|
|
7060
7480
|
init_guard_contract();
|
|
@@ -9437,61 +9857,918 @@ var init_openclaw = __esm({
|
|
|
9437
9857
|
}
|
|
9438
9858
|
});
|
|
9439
9859
|
|
|
9440
|
-
// src/
|
|
9441
|
-
|
|
9442
|
-
|
|
9443
|
-
|
|
9444
|
-
|
|
9445
|
-
|
|
9446
|
-
|
|
9447
|
-
|
|
9448
|
-
|
|
9449
|
-
|
|
9450
|
-
|
|
9451
|
-
|
|
9452
|
-
|
|
9453
|
-
|
|
9454
|
-
|
|
9455
|
-
|
|
9456
|
-
|
|
9457
|
-
|
|
9458
|
-
|
|
9459
|
-
|
|
9460
|
-
|
|
9461
|
-
|
|
9462
|
-
|
|
9463
|
-
|
|
9464
|
-
|
|
9465
|
-
|
|
9466
|
-
|
|
9467
|
-
|
|
9468
|
-
|
|
9469
|
-
|
|
9860
|
+
// src/worlds/mentraos-intent-taxonomy.ts
|
|
9861
|
+
function getMentraIntent(intent) {
|
|
9862
|
+
return MENTRA_INTENT_MAP.get(intent);
|
|
9863
|
+
}
|
|
9864
|
+
function getIntentsByPermission(permission) {
|
|
9865
|
+
return MENTRA_INTENT_TAXONOMY.filter((d) => d.permission === permission);
|
|
9866
|
+
}
|
|
9867
|
+
function getIntentsByGlasses(model) {
|
|
9868
|
+
return MENTRA_INTENT_TAXONOMY.filter((d) => d.supported_glasses.includes(model));
|
|
9869
|
+
}
|
|
9870
|
+
function isIntentSupported(intent, model) {
|
|
9871
|
+
const def = MENTRA_INTENT_MAP.get(intent);
|
|
9872
|
+
return def ? def.supported_glasses.includes(model) : false;
|
|
9873
|
+
}
|
|
9874
|
+
function getHighRiskIntents() {
|
|
9875
|
+
return MENTRA_INTENT_TAXONOMY.filter((d) => d.base_risk === "high" || d.base_risk === "critical");
|
|
9876
|
+
}
|
|
9877
|
+
function getExfiltrationIntents() {
|
|
9878
|
+
return MENTRA_INTENT_TAXONOMY.filter((d) => d.exfiltration_risk);
|
|
9879
|
+
}
|
|
9880
|
+
function getAIDataIntents() {
|
|
9881
|
+
return MENTRA_INTENT_TAXONOMY.filter((d) => d.domain === "ai_data");
|
|
9882
|
+
}
|
|
9883
|
+
function getAIActionIntents() {
|
|
9884
|
+
return MENTRA_INTENT_TAXONOMY.filter((d) => d.domain === "ai_action");
|
|
9885
|
+
}
|
|
9886
|
+
function getAIIntents() {
|
|
9887
|
+
return MENTRA_INTENT_TAXONOMY.filter((d) => d.domain === "ai_data" || d.domain === "ai_action");
|
|
9888
|
+
}
|
|
9889
|
+
function isAIIntent(intent) {
|
|
9890
|
+
const def = MENTRA_INTENT_MAP.get(intent);
|
|
9891
|
+
return def ? def.domain === "ai_data" || def.domain === "ai_action" : false;
|
|
9892
|
+
}
|
|
9893
|
+
var MENTRA_INTENT_TAXONOMY, MENTRA_KNOWN_INTENTS, MENTRA_INTENT_MAP;
|
|
9894
|
+
var init_mentraos_intent_taxonomy = __esm({
|
|
9895
|
+
"src/worlds/mentraos-intent-taxonomy.ts"() {
|
|
9470
9896
|
"use strict";
|
|
9471
|
-
|
|
9472
|
-
|
|
9473
|
-
|
|
9474
|
-
|
|
9475
|
-
|
|
9476
|
-
|
|
9477
|
-
|
|
9897
|
+
MENTRA_INTENT_TAXONOMY = [
|
|
9898
|
+
// ── Camera Domain ───────────────────────────────────────────────────────
|
|
9899
|
+
{
|
|
9900
|
+
intent: "camera_photo_capture",
|
|
9901
|
+
description: "Capture a single photo from the glasses camera",
|
|
9902
|
+
sdk_method: "session.camera.requestPhoto()",
|
|
9903
|
+
permission: "CAMERA",
|
|
9904
|
+
domain: "camera",
|
|
9905
|
+
supported_glasses: ["mentra_live"],
|
|
9906
|
+
action_category: "write",
|
|
9907
|
+
base_risk: "high",
|
|
9908
|
+
exfiltration_risk: true,
|
|
9909
|
+
reversible: false
|
|
9910
|
+
},
|
|
9911
|
+
{
|
|
9912
|
+
intent: "camera_stream_start",
|
|
9913
|
+
description: "Start a managed video stream (HLS) from the glasses camera",
|
|
9914
|
+
sdk_method: "session.camera.startManagedStream()",
|
|
9915
|
+
permission: "CAMERA",
|
|
9916
|
+
domain: "camera",
|
|
9917
|
+
supported_glasses: ["mentra_live"],
|
|
9918
|
+
action_category: "write",
|
|
9919
|
+
base_risk: "critical",
|
|
9920
|
+
exfiltration_risk: true,
|
|
9921
|
+
reversible: true
|
|
9922
|
+
},
|
|
9923
|
+
{
|
|
9924
|
+
intent: "camera_stream_stop",
|
|
9925
|
+
description: "Stop an active camera stream",
|
|
9926
|
+
sdk_method: "session.camera.stopStream()",
|
|
9927
|
+
permission: "CAMERA",
|
|
9928
|
+
domain: "camera",
|
|
9929
|
+
supported_glasses: ["mentra_live"],
|
|
9930
|
+
action_category: "write",
|
|
9931
|
+
base_risk: "low",
|
|
9932
|
+
exfiltration_risk: false,
|
|
9933
|
+
reversible: false
|
|
9934
|
+
},
|
|
9935
|
+
{
|
|
9936
|
+
intent: "camera_restream_start",
|
|
9937
|
+
description: "Restream camera feed to an external RTMP destination (e.g., social media)",
|
|
9938
|
+
sdk_method: "session.camera.startRestream()",
|
|
9939
|
+
permission: "CAMERA",
|
|
9940
|
+
domain: "camera",
|
|
9941
|
+
supported_glasses: ["mentra_live"],
|
|
9942
|
+
action_category: "network",
|
|
9943
|
+
base_risk: "critical",
|
|
9944
|
+
exfiltration_risk: true,
|
|
9945
|
+
reversible: true
|
|
9946
|
+
},
|
|
9947
|
+
// ── Microphone Domain ──────────────────────────────────────────────────
|
|
9948
|
+
{
|
|
9949
|
+
intent: "microphone_transcription_start",
|
|
9950
|
+
description: "Start receiving speech-to-text transcription events",
|
|
9951
|
+
sdk_method: "session.events.onTranscription()",
|
|
9952
|
+
permission: "MICROPHONE",
|
|
9953
|
+
domain: "microphone",
|
|
9954
|
+
supported_glasses: ["even_realities_g1", "mentra_live"],
|
|
9955
|
+
action_category: "read",
|
|
9956
|
+
base_risk: "medium",
|
|
9957
|
+
exfiltration_risk: true,
|
|
9958
|
+
reversible: true
|
|
9959
|
+
},
|
|
9960
|
+
{
|
|
9961
|
+
intent: "microphone_translation_start",
|
|
9962
|
+
description: "Start receiving translation events from spoken audio",
|
|
9963
|
+
sdk_method: "session.events.onTranslation()",
|
|
9964
|
+
permission: "MICROPHONE",
|
|
9965
|
+
domain: "microphone",
|
|
9966
|
+
supported_glasses: ["even_realities_g1", "mentra_live"],
|
|
9967
|
+
action_category: "read",
|
|
9968
|
+
base_risk: "medium",
|
|
9969
|
+
exfiltration_risk: true,
|
|
9970
|
+
reversible: true
|
|
9971
|
+
},
|
|
9972
|
+
{
|
|
9973
|
+
intent: "microphone_phone_passthrough",
|
|
9974
|
+
description: "Use phone microphone as audio input (glasses without built-in mic)",
|
|
9975
|
+
sdk_method: "session.audio.startPhoneMic()",
|
|
9976
|
+
permission: "MICROPHONE",
|
|
9977
|
+
domain: "microphone",
|
|
9978
|
+
supported_glasses: ["mentra_mach1", "vuzix_z100"],
|
|
9979
|
+
action_category: "read",
|
|
9980
|
+
base_risk: "medium",
|
|
9981
|
+
exfiltration_risk: true,
|
|
9982
|
+
reversible: true
|
|
9983
|
+
},
|
|
9984
|
+
// ── Display Domain ────────────────────────────────────────────────────
|
|
9985
|
+
{
|
|
9986
|
+
intent: "display_text_wall",
|
|
9987
|
+
description: "Show a single text block on the glasses display",
|
|
9988
|
+
sdk_method: "session.layouts.showTextWall()",
|
|
9989
|
+
permission: "NONE",
|
|
9990
|
+
domain: "display",
|
|
9991
|
+
supported_glasses: ["even_realities_g1", "mentra_mach1", "vuzix_z100"],
|
|
9992
|
+
action_category: "write",
|
|
9993
|
+
base_risk: "low",
|
|
9994
|
+
exfiltration_risk: false,
|
|
9995
|
+
reversible: true
|
|
9996
|
+
},
|
|
9997
|
+
{
|
|
9998
|
+
intent: "display_double_text_wall",
|
|
9999
|
+
description: "Show two text blocks (top/bottom) on the glasses display",
|
|
10000
|
+
sdk_method: "session.layouts.showDoubleTextWall()",
|
|
10001
|
+
permission: "NONE",
|
|
10002
|
+
domain: "display",
|
|
10003
|
+
supported_glasses: ["even_realities_g1", "mentra_mach1", "vuzix_z100"],
|
|
10004
|
+
action_category: "write",
|
|
10005
|
+
base_risk: "low",
|
|
10006
|
+
exfiltration_risk: false,
|
|
10007
|
+
reversible: true
|
|
10008
|
+
},
|
|
10009
|
+
{
|
|
10010
|
+
intent: "display_reference_card",
|
|
10011
|
+
description: "Show a reference card layout with structured content",
|
|
10012
|
+
sdk_method: "session.layouts.showReferenceCard()",
|
|
10013
|
+
permission: "NONE",
|
|
10014
|
+
domain: "display",
|
|
10015
|
+
supported_glasses: ["even_realities_g1"],
|
|
10016
|
+
action_category: "write",
|
|
10017
|
+
base_risk: "low",
|
|
10018
|
+
exfiltration_risk: false,
|
|
10019
|
+
reversible: true
|
|
10020
|
+
},
|
|
10021
|
+
{
|
|
10022
|
+
intent: "display_dashboard_card",
|
|
10023
|
+
description: "Show a dashboard card layout",
|
|
10024
|
+
sdk_method: "session.layouts.showDashboardCard()",
|
|
10025
|
+
permission: "NONE",
|
|
10026
|
+
domain: "display",
|
|
10027
|
+
supported_glasses: ["even_realities_g1"],
|
|
10028
|
+
action_category: "write",
|
|
10029
|
+
base_risk: "low",
|
|
10030
|
+
exfiltration_risk: false,
|
|
10031
|
+
reversible: true
|
|
10032
|
+
},
|
|
10033
|
+
{
|
|
10034
|
+
intent: "display_image",
|
|
10035
|
+
description: "Display an image on the glasses",
|
|
10036
|
+
sdk_method: "session.layouts.showImage()",
|
|
10037
|
+
permission: "NONE",
|
|
10038
|
+
domain: "display",
|
|
10039
|
+
supported_glasses: ["even_realities_g1"],
|
|
10040
|
+
action_category: "write",
|
|
10041
|
+
base_risk: "low",
|
|
10042
|
+
exfiltration_risk: false,
|
|
10043
|
+
reversible: true
|
|
10044
|
+
},
|
|
10045
|
+
// ── Dashboard Domain ──────────────────────────────────────────────────
|
|
10046
|
+
{
|
|
10047
|
+
intent: "dashboard_update_main",
|
|
10048
|
+
description: "Update the persistent dashboard content (compact mode)",
|
|
10049
|
+
sdk_method: "session.dashboard.content.setMain()",
|
|
10050
|
+
permission: "NONE",
|
|
10051
|
+
domain: "dashboard",
|
|
10052
|
+
supported_glasses: ["even_realities_g1", "mentra_mach1", "vuzix_z100"],
|
|
10053
|
+
action_category: "write",
|
|
10054
|
+
base_risk: "low",
|
|
10055
|
+
exfiltration_risk: false,
|
|
10056
|
+
reversible: true
|
|
10057
|
+
},
|
|
10058
|
+
{
|
|
10059
|
+
intent: "dashboard_update_expanded",
|
|
10060
|
+
description: "Update the expanded dashboard content (user-opened mode)",
|
|
10061
|
+
sdk_method: "session.dashboard.content.setExpanded()",
|
|
10062
|
+
permission: "NONE",
|
|
10063
|
+
domain: "dashboard",
|
|
10064
|
+
supported_glasses: ["even_realities_g1", "mentra_mach1", "vuzix_z100"],
|
|
10065
|
+
action_category: "write",
|
|
10066
|
+
base_risk: "low",
|
|
10067
|
+
exfiltration_risk: false,
|
|
10068
|
+
reversible: true
|
|
10069
|
+
},
|
|
10070
|
+
// ── Location Domain ───────────────────────────────────────────────────
|
|
10071
|
+
{
|
|
10072
|
+
intent: "location_access",
|
|
10073
|
+
description: "Access current location data from the paired phone",
|
|
10074
|
+
sdk_method: "session.location.get()",
|
|
10075
|
+
permission: "LOCATION",
|
|
10076
|
+
domain: "location",
|
|
10077
|
+
supported_glasses: ["even_realities_g1", "mentra_live", "mentra_mach1", "vuzix_z100"],
|
|
10078
|
+
action_category: "read",
|
|
10079
|
+
base_risk: "medium",
|
|
10080
|
+
exfiltration_risk: true,
|
|
10081
|
+
reversible: false
|
|
10082
|
+
},
|
|
10083
|
+
{
|
|
10084
|
+
intent: "location_continuous_sharing",
|
|
10085
|
+
description: "Start continuous location updates to the app server",
|
|
10086
|
+
sdk_method: "session.location.startContinuous()",
|
|
10087
|
+
permission: "LOCATION",
|
|
10088
|
+
domain: "location",
|
|
10089
|
+
supported_glasses: ["even_realities_g1", "mentra_live", "mentra_mach1", "vuzix_z100"],
|
|
10090
|
+
action_category: "network",
|
|
10091
|
+
base_risk: "high",
|
|
10092
|
+
exfiltration_risk: true,
|
|
10093
|
+
reversible: true
|
|
10094
|
+
},
|
|
10095
|
+
// ── Calendar & Notifications ──────────────────────────────────────────
|
|
10096
|
+
{
|
|
10097
|
+
intent: "calendar_read",
|
|
10098
|
+
description: "Read calendar events from the paired phone",
|
|
10099
|
+
sdk_method: "session.calendar.getEvents()",
|
|
10100
|
+
permission: "CALENDAR",
|
|
10101
|
+
domain: "calendar",
|
|
10102
|
+
supported_glasses: ["even_realities_g1", "mentra_live", "mentra_mach1", "vuzix_z100"],
|
|
10103
|
+
action_category: "read",
|
|
10104
|
+
base_risk: "low",
|
|
10105
|
+
exfiltration_risk: false,
|
|
10106
|
+
reversible: true
|
|
10107
|
+
},
|
|
10108
|
+
{
|
|
10109
|
+
intent: "notifications_read",
|
|
10110
|
+
description: "Read phone notifications",
|
|
10111
|
+
sdk_method: "session.notifications.getRecent()",
|
|
10112
|
+
permission: "READ_NOTIFICATIONS",
|
|
10113
|
+
domain: "notifications",
|
|
10114
|
+
supported_glasses: ["even_realities_g1", "mentra_live", "mentra_mach1", "vuzix_z100"],
|
|
10115
|
+
action_category: "read",
|
|
10116
|
+
base_risk: "low",
|
|
10117
|
+
exfiltration_risk: false,
|
|
10118
|
+
reversible: true
|
|
10119
|
+
},
|
|
10120
|
+
// ── Audio Domain ──────────────────────────────────────────────────────
|
|
10121
|
+
{
|
|
10122
|
+
intent: "audio_play",
|
|
10123
|
+
description: "Play audio through the glasses speaker",
|
|
10124
|
+
sdk_method: "session.audio.play()",
|
|
10125
|
+
permission: "NONE",
|
|
10126
|
+
domain: "audio",
|
|
10127
|
+
supported_glasses: ["mentra_live"],
|
|
10128
|
+
action_category: "write",
|
|
10129
|
+
base_risk: "low",
|
|
10130
|
+
exfiltration_risk: false,
|
|
10131
|
+
reversible: true
|
|
10132
|
+
},
|
|
10133
|
+
// ── Session Domain ────────────────────────────────────────────────────
|
|
10134
|
+
{
|
|
10135
|
+
intent: "session_data_export",
|
|
10136
|
+
description: "Export session data to external storage or API",
|
|
10137
|
+
sdk_method: "session.export()",
|
|
10138
|
+
permission: "NONE",
|
|
10139
|
+
domain: "session",
|
|
10140
|
+
supported_glasses: ["even_realities_g1", "mentra_live", "mentra_mach1", "vuzix_z100"],
|
|
10141
|
+
action_category: "network",
|
|
10142
|
+
base_risk: "high",
|
|
10143
|
+
exfiltration_risk: true,
|
|
10144
|
+
reversible: false
|
|
10145
|
+
},
|
|
10146
|
+
// ── Tool Call Domain ──────────────────────────────────────────────────
|
|
10147
|
+
{
|
|
10148
|
+
intent: "tool_call_execute",
|
|
10149
|
+
description: "Execute a custom tool call defined by the app via handleToolCall",
|
|
10150
|
+
sdk_method: "AppServer.handleToolCall()",
|
|
10151
|
+
permission: "NONE",
|
|
10152
|
+
domain: "tool_call",
|
|
10153
|
+
supported_glasses: ["even_realities_g1", "mentra_live", "mentra_mach1", "vuzix_z100"],
|
|
10154
|
+
action_category: "other",
|
|
10155
|
+
base_risk: "medium",
|
|
10156
|
+
exfiltration_risk: false,
|
|
10157
|
+
reversible: false
|
|
10158
|
+
},
|
|
10159
|
+
// ── AI Data Flow Domain ─────────────────────────────────────────────────
|
|
10160
|
+
// These intents govern what user data apps send to their AI backends.
|
|
10161
|
+
// They operate at the app server layer (not the glasses hardware layer),
|
|
10162
|
+
// so they work on all glasses models and require no hardware permission.
|
|
10163
|
+
{
|
|
10164
|
+
intent: "ai_send_transcription",
|
|
10165
|
+
description: "Send user speech transcription to an external AI API for processing",
|
|
10166
|
+
sdk_method: "app_server.ai.sendTranscription()",
|
|
10167
|
+
permission: "NONE",
|
|
10168
|
+
domain: "ai_data",
|
|
10169
|
+
supported_glasses: ["even_realities_g1", "mentra_live", "mentra_mach1", "vuzix_z100"],
|
|
10170
|
+
action_category: "network",
|
|
10171
|
+
base_risk: "medium",
|
|
10172
|
+
exfiltration_risk: true,
|
|
10173
|
+
reversible: false
|
|
10174
|
+
},
|
|
10175
|
+
{
|
|
10176
|
+
intent: "ai_send_image",
|
|
10177
|
+
description: "Send a camera-captured image to an external AI API for vision analysis",
|
|
10178
|
+
sdk_method: "app_server.ai.sendImage()",
|
|
10179
|
+
permission: "NONE",
|
|
10180
|
+
domain: "ai_data",
|
|
10181
|
+
supported_glasses: ["even_realities_g1", "mentra_live", "mentra_mach1", "vuzix_z100"],
|
|
10182
|
+
action_category: "network",
|
|
10183
|
+
base_risk: "high",
|
|
10184
|
+
exfiltration_risk: true,
|
|
10185
|
+
reversible: false
|
|
10186
|
+
},
|
|
10187
|
+
{
|
|
10188
|
+
intent: "ai_send_location",
|
|
10189
|
+
description: "Send user location data to an external AI API for context-aware processing",
|
|
10190
|
+
sdk_method: "app_server.ai.sendLocation()",
|
|
10191
|
+
permission: "NONE",
|
|
10192
|
+
domain: "ai_data",
|
|
10193
|
+
supported_glasses: ["even_realities_g1", "mentra_live", "mentra_mach1", "vuzix_z100"],
|
|
10194
|
+
action_category: "network",
|
|
10195
|
+
base_risk: "medium",
|
|
10196
|
+
exfiltration_risk: true,
|
|
10197
|
+
reversible: false
|
|
10198
|
+
},
|
|
10199
|
+
{
|
|
10200
|
+
intent: "ai_send_calendar",
|
|
10201
|
+
description: "Send user calendar data to an external AI API for scheduling assistance",
|
|
10202
|
+
sdk_method: "app_server.ai.sendCalendar()",
|
|
10203
|
+
permission: "NONE",
|
|
10204
|
+
domain: "ai_data",
|
|
10205
|
+
supported_glasses: ["even_realities_g1", "mentra_live", "mentra_mach1", "vuzix_z100"],
|
|
10206
|
+
action_category: "network",
|
|
10207
|
+
base_risk: "medium",
|
|
10208
|
+
exfiltration_risk: true,
|
|
10209
|
+
reversible: false
|
|
10210
|
+
},
|
|
10211
|
+
{
|
|
10212
|
+
intent: "ai_send_notifications",
|
|
10213
|
+
description: "Send user notification data to an external AI API for summarization or triage",
|
|
10214
|
+
sdk_method: "app_server.ai.sendNotifications()",
|
|
10215
|
+
permission: "NONE",
|
|
10216
|
+
domain: "ai_data",
|
|
10217
|
+
supported_glasses: ["even_realities_g1", "mentra_live", "mentra_mach1", "vuzix_z100"],
|
|
10218
|
+
action_category: "network",
|
|
10219
|
+
base_risk: "medium",
|
|
10220
|
+
exfiltration_risk: true,
|
|
10221
|
+
reversible: false
|
|
10222
|
+
},
|
|
10223
|
+
// ── AI Action Domain ──────────────────────────────────────────────────
|
|
10224
|
+
// These intents govern actions AI takes on behalf of the user.
|
|
10225
|
+
// Every action here must be shown on the glasses display before execution.
|
|
10226
|
+
{
|
|
10227
|
+
intent: "ai_auto_respond_message",
|
|
10228
|
+
description: "AI generates and sends a message (email, SMS, chat) on the user's behalf",
|
|
10229
|
+
sdk_method: "app_server.ai.sendMessage()",
|
|
10230
|
+
permission: "NONE",
|
|
10231
|
+
domain: "ai_action",
|
|
10232
|
+
supported_glasses: ["even_realities_g1", "mentra_live", "mentra_mach1", "vuzix_z100"],
|
|
10233
|
+
action_category: "network",
|
|
10234
|
+
base_risk: "high",
|
|
10235
|
+
exfiltration_risk: true,
|
|
10236
|
+
reversible: false
|
|
10237
|
+
},
|
|
10238
|
+
{
|
|
10239
|
+
intent: "ai_auto_purchase",
|
|
10240
|
+
description: "AI initiates a financial transaction (purchase, subscription, tip) on the user's behalf",
|
|
10241
|
+
sdk_method: "app_server.ai.purchase()",
|
|
10242
|
+
permission: "NONE",
|
|
10243
|
+
domain: "ai_action",
|
|
10244
|
+
supported_glasses: ["even_realities_g1", "mentra_live", "mentra_mach1", "vuzix_z100"],
|
|
10245
|
+
action_category: "network",
|
|
10246
|
+
base_risk: "critical",
|
|
10247
|
+
exfiltration_risk: true,
|
|
10248
|
+
reversible: false
|
|
10249
|
+
},
|
|
10250
|
+
{
|
|
10251
|
+
intent: "ai_auto_schedule",
|
|
10252
|
+
description: "AI creates, modifies, or cancels a calendar event on the user's behalf",
|
|
10253
|
+
sdk_method: "app_server.ai.schedule()",
|
|
10254
|
+
permission: "NONE",
|
|
10255
|
+
domain: "ai_action",
|
|
10256
|
+
supported_glasses: ["even_realities_g1", "mentra_live", "mentra_mach1", "vuzix_z100"],
|
|
10257
|
+
action_category: "write",
|
|
10258
|
+
base_risk: "medium",
|
|
10259
|
+
exfiltration_risk: false,
|
|
10260
|
+
reversible: true
|
|
10261
|
+
},
|
|
10262
|
+
{
|
|
10263
|
+
intent: "ai_auto_setting_change",
|
|
10264
|
+
description: "AI changes a user setting or app configuration on the user's behalf",
|
|
10265
|
+
sdk_method: "app_server.ai.changeSetting()",
|
|
10266
|
+
permission: "NONE",
|
|
10267
|
+
domain: "ai_action",
|
|
10268
|
+
supported_glasses: ["even_realities_g1", "mentra_live", "mentra_mach1", "vuzix_z100"],
|
|
10269
|
+
action_category: "write",
|
|
10270
|
+
base_risk: "medium",
|
|
10271
|
+
exfiltration_risk: false,
|
|
10272
|
+
reversible: true
|
|
10273
|
+
},
|
|
10274
|
+
{
|
|
10275
|
+
intent: "ai_retain_session_data",
|
|
10276
|
+
description: "AI or app retains user session data (transcriptions, images, conversation) beyond session end",
|
|
10277
|
+
sdk_method: "app_server.ai.retainData()",
|
|
10278
|
+
permission: "NONE",
|
|
10279
|
+
domain: "ai_data",
|
|
10280
|
+
supported_glasses: ["even_realities_g1", "mentra_live", "mentra_mach1", "vuzix_z100"],
|
|
10281
|
+
action_category: "write",
|
|
10282
|
+
base_risk: "high",
|
|
10283
|
+
exfiltration_risk: true,
|
|
10284
|
+
reversible: false
|
|
10285
|
+
},
|
|
10286
|
+
{
|
|
10287
|
+
intent: "ai_share_with_third_party",
|
|
10288
|
+
description: "AI or app shares user data with a third-party service beyond the declared AI provider",
|
|
10289
|
+
sdk_method: "app_server.ai.shareExternal()",
|
|
10290
|
+
permission: "NONE",
|
|
10291
|
+
domain: "ai_data",
|
|
10292
|
+
supported_glasses: ["even_realities_g1", "mentra_live", "mentra_mach1", "vuzix_z100"],
|
|
10293
|
+
action_category: "network",
|
|
10294
|
+
base_risk: "critical",
|
|
10295
|
+
exfiltration_risk: true,
|
|
10296
|
+
reversible: false
|
|
10297
|
+
}
|
|
10298
|
+
];
|
|
10299
|
+
MENTRA_KNOWN_INTENTS = MENTRA_INTENT_TAXONOMY.map((d) => d.intent);
|
|
10300
|
+
MENTRA_INTENT_MAP = new Map(MENTRA_INTENT_TAXONOMY.map((d) => [d.intent, d]));
|
|
9478
10301
|
}
|
|
9479
10302
|
});
|
|
9480
10303
|
|
|
9481
|
-
//
|
|
9482
|
-
var
|
|
9483
|
-
|
|
9484
|
-
|
|
9485
|
-
|
|
9486
|
-
|
|
9487
|
-
|
|
9488
|
-
|
|
9489
|
-
|
|
9490
|
-
|
|
9491
|
-
|
|
9492
|
-
|
|
9493
|
-
|
|
9494
|
-
|
|
10304
|
+
// src/adapters/mentraos.ts
|
|
10305
|
+
var mentraos_exports = {};
|
|
10306
|
+
__export(mentraos_exports, {
|
|
10307
|
+
DEFAULT_USER_RULES: () => DEFAULT_USER_RULES,
|
|
10308
|
+
GovernanceBlockedError: () => GovernanceBlockedError,
|
|
10309
|
+
MENTRA_INTENT_MAP: () => MENTRA_INTENT_MAP,
|
|
10310
|
+
MENTRA_INTENT_TAXONOMY: () => MENTRA_INTENT_TAXONOMY,
|
|
10311
|
+
MENTRA_KNOWN_INTENTS: () => MENTRA_KNOWN_INTENTS,
|
|
10312
|
+
MentraGovernedExecutor: () => MentraGovernedExecutor,
|
|
10313
|
+
createMentraGovernedExecutor: () => createMentraGovernedExecutor,
|
|
10314
|
+
createMentraGovernedExecutorFromWorld: () => createMentraGovernedExecutorFromWorld,
|
|
10315
|
+
evaluateUserRules: () => evaluateUserRules,
|
|
10316
|
+
getAIActionIntents: () => getAIActionIntents,
|
|
10317
|
+
getAIDataIntents: () => getAIDataIntents,
|
|
10318
|
+
getAIIntents: () => getAIIntents,
|
|
10319
|
+
getExfiltrationIntents: () => getExfiltrationIntents,
|
|
10320
|
+
getHighRiskIntents: () => getHighRiskIntents,
|
|
10321
|
+
getIntentsByGlasses: () => getIntentsByGlasses,
|
|
10322
|
+
getIntentsByPermission: () => getIntentsByPermission,
|
|
10323
|
+
getMentraIntent: () => getMentraIntent,
|
|
10324
|
+
isAIIntent: () => isAIIntent,
|
|
10325
|
+
isIntentSupported: () => isIntentSupported
|
|
10326
|
+
});
|
|
10327
|
+
function evaluateUserRules(intent, rules, appContext) {
|
|
10328
|
+
const def = getMentraIntent(intent);
|
|
10329
|
+
if (!def) return null;
|
|
10330
|
+
if (def.domain === "ai_data" && intent !== "ai_retain_session_data") {
|
|
10331
|
+
if (rules.aiDataPolicy === "block_all") {
|
|
10332
|
+
return {
|
|
10333
|
+
verdict: {
|
|
10334
|
+
status: "BLOCK",
|
|
10335
|
+
ruleId: "user-rule-ai-data-block",
|
|
10336
|
+
reason: `User rules block all AI data sends. Intent: ${intent}`,
|
|
10337
|
+
evidence: makeEvidence("user-rule-ai-data-block")
|
|
10338
|
+
},
|
|
10339
|
+
reason: "User has blocked all AI data sends"
|
|
10340
|
+
};
|
|
10341
|
+
}
|
|
10342
|
+
if (rules.aiDataPolicy === "confirm_each") {
|
|
10343
|
+
return {
|
|
10344
|
+
verdict: {
|
|
10345
|
+
status: "PAUSE",
|
|
10346
|
+
ruleId: "user-rule-ai-data-confirm",
|
|
10347
|
+
reason: `User rules require confirmation for every AI data send. Intent: ${intent}`,
|
|
10348
|
+
evidence: makeEvidence("user-rule-ai-data-confirm")
|
|
10349
|
+
},
|
|
10350
|
+
reason: "User requires confirmation for each AI data send"
|
|
10351
|
+
};
|
|
10352
|
+
}
|
|
10353
|
+
if (!appContext.aiProviderDeclared) {
|
|
10354
|
+
return {
|
|
10355
|
+
verdict: {
|
|
10356
|
+
status: "BLOCK",
|
|
10357
|
+
ruleId: "user-rule-undeclared-provider",
|
|
10358
|
+
reason: `App "${appContext.appId}" has not declared its AI provider. User rules require declared providers only.`,
|
|
10359
|
+
evidence: makeEvidence("user-rule-undeclared-provider")
|
|
10360
|
+
},
|
|
10361
|
+
reason: "App has not declared its AI provider"
|
|
10362
|
+
};
|
|
10363
|
+
}
|
|
10364
|
+
}
|
|
10365
|
+
if (intent === "ai_retain_session_data") {
|
|
10366
|
+
if (rules.dataRetentionPolicy === "never") {
|
|
10367
|
+
return {
|
|
10368
|
+
verdict: {
|
|
10369
|
+
status: "BLOCK",
|
|
10370
|
+
ruleId: "user-rule-no-retention",
|
|
10371
|
+
reason: `User rules block all data retention. App "${appContext.appId}" cannot retain session data.`,
|
|
10372
|
+
evidence: makeEvidence("user-rule-no-retention")
|
|
10373
|
+
},
|
|
10374
|
+
reason: "User has blocked all data retention"
|
|
10375
|
+
};
|
|
10376
|
+
}
|
|
10377
|
+
if (!appContext.dataRetentionOptedIn) {
|
|
10378
|
+
return {
|
|
10379
|
+
verdict: {
|
|
10380
|
+
status: "BLOCK",
|
|
10381
|
+
ruleId: "user-rule-retention-no-optin",
|
|
10382
|
+
reason: `User has not opted in to data retention for app "${appContext.appId}".`,
|
|
10383
|
+
evidence: makeEvidence("user-rule-retention-no-optin")
|
|
10384
|
+
},
|
|
10385
|
+
reason: "User has not opted in to data retention for this app"
|
|
10386
|
+
};
|
|
10387
|
+
}
|
|
10388
|
+
}
|
|
10389
|
+
if (intent === "ai_auto_purchase") {
|
|
10390
|
+
if (rules.aiPurchasePolicy === "block_all") {
|
|
10391
|
+
return {
|
|
10392
|
+
verdict: {
|
|
10393
|
+
status: "BLOCK",
|
|
10394
|
+
ruleId: "user-rule-no-purchases",
|
|
10395
|
+
reason: "User rules block all AI-initiated purchases.",
|
|
10396
|
+
evidence: makeEvidence("user-rule-no-purchases")
|
|
10397
|
+
},
|
|
10398
|
+
reason: "User has blocked all AI purchases"
|
|
10399
|
+
};
|
|
10400
|
+
}
|
|
10401
|
+
return {
|
|
10402
|
+
verdict: {
|
|
10403
|
+
status: "PAUSE",
|
|
10404
|
+
ruleId: "user-rule-purchase-confirm",
|
|
10405
|
+
reason: `AI wants to make a purchase. User rules require per-transaction confirmation.`,
|
|
10406
|
+
evidence: makeEvidence("user-rule-purchase-confirm")
|
|
10407
|
+
},
|
|
10408
|
+
reason: "User requires per-transaction confirmation for AI purchases"
|
|
10409
|
+
};
|
|
10410
|
+
}
|
|
10411
|
+
if (intent === "ai_auto_respond_message") {
|
|
10412
|
+
if (rules.aiMessagingPolicy === "block_all") {
|
|
10413
|
+
return {
|
|
10414
|
+
verdict: {
|
|
10415
|
+
status: "BLOCK",
|
|
10416
|
+
ruleId: "user-rule-no-messaging",
|
|
10417
|
+
reason: "User rules block all AI-initiated messaging.",
|
|
10418
|
+
evidence: makeEvidence("user-rule-no-messaging")
|
|
10419
|
+
},
|
|
10420
|
+
reason: "User has blocked all AI messaging"
|
|
10421
|
+
};
|
|
10422
|
+
}
|
|
10423
|
+
return {
|
|
10424
|
+
verdict: {
|
|
10425
|
+
status: "PAUSE",
|
|
10426
|
+
ruleId: "user-rule-message-confirm",
|
|
10427
|
+
reason: `AI wants to send a message on your behalf. User rules require per-message confirmation.`,
|
|
10428
|
+
evidence: makeEvidence("user-rule-message-confirm")
|
|
10429
|
+
},
|
|
10430
|
+
reason: "User requires per-message confirmation for AI messaging"
|
|
10431
|
+
};
|
|
10432
|
+
}
|
|
10433
|
+
if (def.domain === "ai_action" && intent !== "ai_auto_purchase" && intent !== "ai_auto_respond_message") {
|
|
10434
|
+
if (rules.aiActionPolicy === "block_all") {
|
|
10435
|
+
return {
|
|
10436
|
+
verdict: {
|
|
10437
|
+
status: "BLOCK",
|
|
10438
|
+
ruleId: "user-rule-no-ai-actions",
|
|
10439
|
+
reason: `User rules block all AI auto-actions. Intent: ${intent}`,
|
|
10440
|
+
evidence: makeEvidence("user-rule-no-ai-actions")
|
|
10441
|
+
},
|
|
10442
|
+
reason: "User has blocked all AI auto-actions"
|
|
10443
|
+
};
|
|
10444
|
+
}
|
|
10445
|
+
if (rules.aiActionPolicy === "confirm_all") {
|
|
10446
|
+
return {
|
|
10447
|
+
verdict: {
|
|
10448
|
+
status: "PAUSE",
|
|
10449
|
+
ruleId: "user-rule-action-confirm",
|
|
10450
|
+
reason: `AI wants to take action: ${intent}. User rules require confirmation.`,
|
|
10451
|
+
evidence: makeEvidence("user-rule-action-confirm")
|
|
10452
|
+
},
|
|
10453
|
+
reason: "User requires confirmation for all AI actions"
|
|
10454
|
+
};
|
|
10455
|
+
}
|
|
10456
|
+
if (def.base_risk === "high" || def.base_risk === "critical") {
|
|
10457
|
+
return {
|
|
10458
|
+
verdict: {
|
|
10459
|
+
status: "PAUSE",
|
|
10460
|
+
ruleId: "user-rule-high-risk-confirm",
|
|
10461
|
+
reason: `AI wants to take high-risk action: ${intent}. User rules require confirmation for high-risk actions.`,
|
|
10462
|
+
evidence: makeEvidence("user-rule-high-risk-confirm")
|
|
10463
|
+
},
|
|
10464
|
+
reason: "User requires confirmation for high-risk AI actions"
|
|
10465
|
+
};
|
|
10466
|
+
}
|
|
10467
|
+
}
|
|
10468
|
+
if (intent === "ai_share_with_third_party") {
|
|
10469
|
+
return {
|
|
10470
|
+
verdict: {
|
|
10471
|
+
status: "PAUSE",
|
|
10472
|
+
ruleId: "user-rule-third-party-confirm",
|
|
10473
|
+
reason: `App wants to share your data with a third party beyond its declared AI provider. Confirmation required.`,
|
|
10474
|
+
evidence: makeEvidence("user-rule-third-party-confirm")
|
|
10475
|
+
},
|
|
10476
|
+
reason: "Third-party data sharing requires user confirmation"
|
|
10477
|
+
};
|
|
10478
|
+
}
|
|
10479
|
+
return null;
|
|
10480
|
+
}
|
|
10481
|
+
function makeEvidence(ruleId) {
|
|
10482
|
+
return {
|
|
10483
|
+
worldId: "mentraos-user-rules",
|
|
10484
|
+
worldName: "MentraOS User Rules",
|
|
10485
|
+
worldVersion: "1.0.0",
|
|
10486
|
+
evaluatedAt: Date.now(),
|
|
10487
|
+
invariantsSatisfied: 0,
|
|
10488
|
+
invariantsTotal: 0,
|
|
10489
|
+
guardsMatched: [ruleId],
|
|
10490
|
+
rulesMatched: [],
|
|
10491
|
+
enforcementLevel: "strict"
|
|
10492
|
+
};
|
|
10493
|
+
}
|
|
10494
|
+
async function createMentraGovernedExecutor(worldPath, options = {}, userRules = DEFAULT_USER_RULES) {
|
|
10495
|
+
const world = await loadWorld(worldPath);
|
|
10496
|
+
return new MentraGovernedExecutor(world, options, userRules);
|
|
10497
|
+
}
|
|
10498
|
+
function createMentraGovernedExecutorFromWorld(world, options = {}, userRules = DEFAULT_USER_RULES) {
|
|
10499
|
+
return new MentraGovernedExecutor(world, options, userRules);
|
|
10500
|
+
}
|
|
10501
|
+
var DEFAULT_USER_RULES, MentraGovernedExecutor;
|
|
10502
|
+
var init_mentraos = __esm({
|
|
10503
|
+
"src/adapters/mentraos.ts"() {
|
|
10504
|
+
"use strict";
|
|
10505
|
+
init_guard_engine();
|
|
10506
|
+
init_world_loader();
|
|
10507
|
+
init_shared();
|
|
10508
|
+
init_mentraos_intent_taxonomy();
|
|
10509
|
+
init_shared();
|
|
10510
|
+
init_mentraos_intent_taxonomy();
|
|
10511
|
+
DEFAULT_USER_RULES = {
|
|
10512
|
+
aiDataPolicy: "declared_only",
|
|
10513
|
+
aiActionPolicy: "confirm_all",
|
|
10514
|
+
aiPurchasePolicy: "confirm_each",
|
|
10515
|
+
aiMessagingPolicy: "confirm_each",
|
|
10516
|
+
dataRetentionPolicy: "app_declared",
|
|
10517
|
+
maxAIProviders: 5
|
|
10518
|
+
};
|
|
10519
|
+
MentraGovernedExecutor = class {
|
|
10520
|
+
world;
|
|
10521
|
+
engineOptions;
|
|
10522
|
+
options;
|
|
10523
|
+
planState;
|
|
10524
|
+
planCallbacks;
|
|
10525
|
+
_userRules;
|
|
10526
|
+
_emergencyOverride = false;
|
|
10527
|
+
_emergencyActivatedAt = null;
|
|
10528
|
+
constructor(world, options = {}, userRules = DEFAULT_USER_RULES) {
|
|
10529
|
+
this.world = world;
|
|
10530
|
+
this.options = options;
|
|
10531
|
+
this._userRules = userRules;
|
|
10532
|
+
this.engineOptions = buildEngineOptions(options, options.plan);
|
|
10533
|
+
this.planState = { activePlan: options.plan, engineOptions: this.engineOptions };
|
|
10534
|
+
this.planCallbacks = {
|
|
10535
|
+
onPlanProgress: options.onPlanProgress,
|
|
10536
|
+
onPlanComplete: options.onPlanComplete
|
|
10537
|
+
};
|
|
10538
|
+
}
|
|
10539
|
+
/** Get the current user rules */
|
|
10540
|
+
get userRules() {
|
|
10541
|
+
return this._userRules;
|
|
10542
|
+
}
|
|
10543
|
+
/** Update user rules at runtime (e.g., user changes preferences in phone app) */
|
|
10544
|
+
updateUserRules(rules) {
|
|
10545
|
+
this._userRules = { ...this._userRules, ...rules };
|
|
10546
|
+
}
|
|
10547
|
+
/**
|
|
10548
|
+
* Activate emergency override — user is king.
|
|
10549
|
+
*
|
|
10550
|
+
* Bypasses all NeuroVerse governance rules (user rules, platform rules).
|
|
10551
|
+
* Does NOT bypass MentraOS platform constraints (hardware capability,
|
|
10552
|
+
* declared permissions, session isolation). You can't override physics.
|
|
10553
|
+
*
|
|
10554
|
+
* Returns the timestamp of activation for audit trail.
|
|
10555
|
+
*/
|
|
10556
|
+
activateEmergencyOverride() {
|
|
10557
|
+
this._emergencyOverride = true;
|
|
10558
|
+
this._emergencyActivatedAt = Date.now();
|
|
10559
|
+
this.engineOptions = { ...this.engineOptions, emergencyOverride: true };
|
|
10560
|
+
return this._emergencyActivatedAt;
|
|
10561
|
+
}
|
|
10562
|
+
/**
|
|
10563
|
+
* Deactivate emergency override — governance resumes.
|
|
10564
|
+
* Returns the duration the override was active (ms).
|
|
10565
|
+
*/
|
|
10566
|
+
deactivateEmergencyOverride() {
|
|
10567
|
+
if (!this._emergencyOverride || !this._emergencyActivatedAt) {
|
|
10568
|
+
return 0;
|
|
10569
|
+
}
|
|
10570
|
+
const duration = Date.now() - this._emergencyActivatedAt;
|
|
10571
|
+
this._emergencyOverride = false;
|
|
10572
|
+
this._emergencyActivatedAt = null;
|
|
10573
|
+
this.engineOptions = { ...this.engineOptions, emergencyOverride: false };
|
|
10574
|
+
return duration;
|
|
10575
|
+
}
|
|
10576
|
+
/** Whether emergency override is currently active */
|
|
10577
|
+
get isEmergencyOverrideActive() {
|
|
10578
|
+
return this._emergencyOverride;
|
|
10579
|
+
}
|
|
10580
|
+
/** Timestamp when emergency override was activated, or null */
|
|
10581
|
+
get emergencyActivatedAt() {
|
|
10582
|
+
return this._emergencyActivatedAt;
|
|
10583
|
+
}
|
|
10584
|
+
/**
|
|
10585
|
+
* Evaluate an intent against user rules + platform world.
|
|
10586
|
+
*
|
|
10587
|
+
* Three-layer evaluation:
|
|
10588
|
+
* 0. Emergency override — if active, skip governance (layers 1 + 3),
|
|
10589
|
+
* but STILL enforce platform constraints (layer 2)
|
|
10590
|
+
* 1. User rules check — personal governance override, can BLOCK or PAUSE
|
|
10591
|
+
* 2. Hardware capability check — validates glasses support
|
|
10592
|
+
* ↑ THIS IS A PLATFORM CONSTRAINT — never overridden
|
|
10593
|
+
* 3. Platform guard engine — full world rule evaluation
|
|
10594
|
+
*/
|
|
10595
|
+
evaluate(intent, appContext) {
|
|
10596
|
+
const intentDef = getMentraIntent(intent);
|
|
10597
|
+
const glassesModel = appContext.glassesModel;
|
|
10598
|
+
if (!this._emergencyOverride) {
|
|
10599
|
+
const userRulesResult = evaluateUserRules(intent, this._userRules, appContext);
|
|
10600
|
+
if (userRulesResult) {
|
|
10601
|
+
const allowed2 = false;
|
|
10602
|
+
const requiresConfirmation2 = userRulesResult.verdict.status === "PAUSE";
|
|
10603
|
+
const result2 = {
|
|
10604
|
+
allowed: requiresConfirmation2 ? false : false,
|
|
10605
|
+
requiresConfirmation: requiresConfirmation2,
|
|
10606
|
+
verdict: userRulesResult.verdict,
|
|
10607
|
+
intentDef,
|
|
10608
|
+
userRulesResult: { reason: userRulesResult.reason },
|
|
10609
|
+
appContext,
|
|
10610
|
+
decidingLayer: "user_rules"
|
|
10611
|
+
};
|
|
10612
|
+
if (requiresConfirmation2) {
|
|
10613
|
+
this.options.onPause?.(result2);
|
|
10614
|
+
} else {
|
|
10615
|
+
this.options.onBlock?.(result2);
|
|
10616
|
+
}
|
|
10617
|
+
this.options.onEvaluate?.(result2);
|
|
10618
|
+
return result2;
|
|
10619
|
+
}
|
|
10620
|
+
}
|
|
10621
|
+
if (intentDef && glassesModel && !intentDef.supported_glasses.includes(glassesModel)) {
|
|
10622
|
+
const verdict2 = {
|
|
10623
|
+
status: "BLOCK",
|
|
10624
|
+
ruleId: "hardware-capability",
|
|
10625
|
+
reason: `${intent} not supported on ${glassesModel} \u2014 requires: ${intentDef.supported_glasses.join(", ")}`,
|
|
10626
|
+
evidence: {
|
|
10627
|
+
worldId: this.world.world?.world_id ?? "unknown",
|
|
10628
|
+
worldName: this.world.world?.name ?? "unknown",
|
|
10629
|
+
worldVersion: this.world.world?.version ?? "unknown",
|
|
10630
|
+
evaluatedAt: Date.now(),
|
|
10631
|
+
invariantsSatisfied: 0,
|
|
10632
|
+
invariantsTotal: 0,
|
|
10633
|
+
guardsMatched: ["hardware-capability"],
|
|
10634
|
+
rulesMatched: [],
|
|
10635
|
+
enforcementLevel: "strict"
|
|
10636
|
+
}
|
|
10637
|
+
};
|
|
10638
|
+
const result2 = {
|
|
10639
|
+
allowed: false,
|
|
10640
|
+
requiresConfirmation: false,
|
|
10641
|
+
verdict: verdict2,
|
|
10642
|
+
intentDef,
|
|
10643
|
+
appContext,
|
|
10644
|
+
decidingLayer: "hardware"
|
|
10645
|
+
};
|
|
10646
|
+
this.options.onBlock?.(result2);
|
|
10647
|
+
this.options.onEvaluate?.(result2);
|
|
10648
|
+
return result2;
|
|
10649
|
+
}
|
|
10650
|
+
const event = {
|
|
10651
|
+
intent,
|
|
10652
|
+
tool: intentDef?.sdk_method ?? intent,
|
|
10653
|
+
scope: intentDef?.domain ?? "unknown",
|
|
10654
|
+
actionCategory: intentDef?.action_category,
|
|
10655
|
+
riskLevel: intentDef?.base_risk ?? "medium",
|
|
10656
|
+
irreversible: intentDef ? !intentDef.reversible : false,
|
|
10657
|
+
args: {
|
|
10658
|
+
app_id: appContext.appId,
|
|
10659
|
+
ai_provider_declared: appContext.aiProviderDeclared ? 1 : 0,
|
|
10660
|
+
ai_data_types_sent: appContext.aiDataTypesSent,
|
|
10661
|
+
ai_retention_opted_in: appContext.dataRetentionOptedIn ? 1 : 0,
|
|
10662
|
+
glasses_model: glassesModel ?? "unknown",
|
|
10663
|
+
is_ai_intent: isAIIntent(intent) ? 1 : 0
|
|
10664
|
+
}
|
|
10665
|
+
};
|
|
10666
|
+
const verdict = evaluateGuard(event, this.world, this.engineOptions);
|
|
10667
|
+
const allowed = verdict.status === "ALLOW" || verdict.status === "REWARD";
|
|
10668
|
+
const requiresConfirmation = verdict.status === "PAUSE";
|
|
10669
|
+
if (allowed) {
|
|
10670
|
+
trackPlanProgress(event, this.planState, this.planCallbacks);
|
|
10671
|
+
}
|
|
10672
|
+
const result = {
|
|
10673
|
+
allowed,
|
|
10674
|
+
requiresConfirmation,
|
|
10675
|
+
verdict,
|
|
10676
|
+
intentDef,
|
|
10677
|
+
appContext,
|
|
10678
|
+
decidingLayer: this._emergencyOverride ? "emergency_override" : "platform"
|
|
10679
|
+
};
|
|
10680
|
+
if (!allowed && !requiresConfirmation) {
|
|
10681
|
+
this.options.onBlock?.(result);
|
|
10682
|
+
}
|
|
10683
|
+
if (requiresConfirmation) {
|
|
10684
|
+
this.options.onPause?.(result);
|
|
10685
|
+
}
|
|
10686
|
+
this.options.onEvaluate?.(result);
|
|
10687
|
+
return result;
|
|
10688
|
+
}
|
|
10689
|
+
/** Get all known intents for this adapter */
|
|
10690
|
+
get knownIntents() {
|
|
10691
|
+
return MENTRA_KNOWN_INTENTS;
|
|
10692
|
+
}
|
|
10693
|
+
};
|
|
10694
|
+
}
|
|
10695
|
+
});
|
|
10696
|
+
|
|
10697
|
+
// src/adapters/index.ts
|
|
10698
|
+
var adapters_exports = {};
|
|
10699
|
+
__export(adapters_exports, {
|
|
10700
|
+
AutoresearchGovernor: () => AutoresearchGovernor,
|
|
10701
|
+
DEFAULT_USER_RULES: () => DEFAULT_USER_RULES,
|
|
10702
|
+
DeepAgentsGovernanceBlockedError: () => GovernanceBlockedError2,
|
|
10703
|
+
DeepAgentsGuard: () => DeepAgentsGuard,
|
|
10704
|
+
GovernanceBlockedError: () => GovernanceBlockedError,
|
|
10705
|
+
GovernedToolExecutor: () => GovernedToolExecutor,
|
|
10706
|
+
LangChainGovernanceBlockedError: () => GovernanceBlockedError3,
|
|
10707
|
+
MENTRA_INTENT_TAXONOMY: () => MENTRA_INTENT_TAXONOMY,
|
|
10708
|
+
MENTRA_KNOWN_INTENTS: () => MENTRA_KNOWN_INTENTS,
|
|
10709
|
+
MentraGovernanceBlockedError: () => GovernanceBlockedError,
|
|
10710
|
+
MentraGovernedExecutor: () => MentraGovernedExecutor,
|
|
10711
|
+
NeuroVerseCallbackHandler: () => NeuroVerseCallbackHandler,
|
|
10712
|
+
NeuroVersePlugin: () => NeuroVersePlugin,
|
|
10713
|
+
OpenAIGovernanceBlockedError: () => GovernanceBlockedError4,
|
|
10714
|
+
OpenClawGovernanceBlockedError: () => GovernanceBlockedError5,
|
|
10715
|
+
buildEngineOptions: () => buildEngineOptions,
|
|
10716
|
+
createDeepAgentsGuard: () => createDeepAgentsGuard,
|
|
10717
|
+
createDeepAgentsGuardFromWorld: () => createDeepAgentsGuardFromWorld,
|
|
10718
|
+
createGovernanceMiddleware: () => createGovernanceMiddleware,
|
|
10719
|
+
createGovernanceMiddlewareFromWorld: () => createGovernanceMiddlewareFromWorld,
|
|
10720
|
+
createGovernedToolExecutor: () => createGovernedToolExecutor,
|
|
10721
|
+
createGovernedToolExecutorFromWorld: () => createGovernedToolExecutorFromWorld,
|
|
10722
|
+
createMentraGovernedExecutor: () => createMentraGovernedExecutor,
|
|
10723
|
+
createMentraGovernedExecutorFromWorld: () => createMentraGovernedExecutorFromWorld,
|
|
10724
|
+
createNeuroVerseCallbackHandler: () => createNeuroVerseCallbackHandler,
|
|
10725
|
+
createNeuroVerseCallbackHandlerFromWorld: () => createNeuroVerseCallbackHandlerFromWorld,
|
|
10726
|
+
createNeuroVersePlugin: () => createNeuroVersePlugin,
|
|
10727
|
+
createNeuroVersePluginFromWorld: () => createNeuroVersePluginFromWorld,
|
|
10728
|
+
defaultBlockMessage: () => defaultBlockMessage,
|
|
10729
|
+
evaluateUserRules: () => evaluateUserRules,
|
|
10730
|
+
extractScope: () => extractScope,
|
|
10731
|
+
getAIActionIntents: () => getAIActionIntents,
|
|
10732
|
+
getAIDataIntents: () => getAIDataIntents,
|
|
10733
|
+
getAIIntents: () => getAIIntents,
|
|
10734
|
+
getExfiltrationIntents: () => getExfiltrationIntents,
|
|
10735
|
+
getHighRiskIntents: () => getHighRiskIntents,
|
|
10736
|
+
getIntentsByGlasses: () => getIntentsByGlasses,
|
|
10737
|
+
getIntentsByPermission: () => getIntentsByPermission,
|
|
10738
|
+
getMentraIntent: () => getMentraIntent,
|
|
10739
|
+
isAIIntent: () => isAIIntent,
|
|
10740
|
+
isIntentSupported: () => isIntentSupported,
|
|
10741
|
+
trackPlanProgress: () => trackPlanProgress
|
|
10742
|
+
});
|
|
10743
|
+
var init_adapters = __esm({
|
|
10744
|
+
"src/adapters/index.ts"() {
|
|
10745
|
+
"use strict";
|
|
10746
|
+
init_shared();
|
|
10747
|
+
init_langchain();
|
|
10748
|
+
init_openai();
|
|
10749
|
+
init_openclaw();
|
|
10750
|
+
init_express();
|
|
10751
|
+
init_autoresearch();
|
|
10752
|
+
init_deep_agents();
|
|
10753
|
+
init_mentraos();
|
|
10754
|
+
}
|
|
10755
|
+
});
|
|
10756
|
+
|
|
10757
|
+
// import("../adapters/**/*") in src/cli/doctor.ts
|
|
10758
|
+
var globImport_adapters;
|
|
10759
|
+
var init_ = __esm({
|
|
10760
|
+
'import("../adapters/**/*") in src/cli/doctor.ts'() {
|
|
10761
|
+
globImport_adapters = __glob({
|
|
10762
|
+
"../adapters/autoresearch.ts": () => Promise.resolve().then(() => (init_autoresearch(), autoresearch_exports)),
|
|
10763
|
+
"../adapters/deep-agents.ts": () => Promise.resolve().then(() => (init_deep_agents(), deep_agents_exports)),
|
|
10764
|
+
"../adapters/express.ts": () => Promise.resolve().then(() => (init_express(), express_exports)),
|
|
10765
|
+
"../adapters/index.ts": () => Promise.resolve().then(() => (init_adapters(), adapters_exports)),
|
|
10766
|
+
"../adapters/langchain.ts": () => Promise.resolve().then(() => (init_langchain(), langchain_exports)),
|
|
10767
|
+
"../adapters/mentraos.ts": () => Promise.resolve().then(() => (init_mentraos(), mentraos_exports)),
|
|
10768
|
+
"../adapters/openai.ts": () => Promise.resolve().then(() => (init_openai(), openai_exports)),
|
|
10769
|
+
"../adapters/openclaw.ts": () => Promise.resolve().then(() => (init_openclaw(), openclaw_exports)),
|
|
10770
|
+
"../adapters/shared.ts": () => Promise.resolve().then(() => (init_shared(), shared_exports))
|
|
10771
|
+
});
|
|
9495
10772
|
}
|
|
9496
10773
|
});
|
|
9497
10774
|
|
|
@@ -11284,8 +12561,8 @@ async function runInteractiveMode(config, model) {
|
|
|
11284
12561
|
process.stdout.write(` Type "exit" to end session.
|
|
11285
12562
|
`);
|
|
11286
12563
|
process.stdout.write("\n");
|
|
11287
|
-
const
|
|
11288
|
-
const
|
|
12564
|
+
const readline2 = await import("readline");
|
|
12565
|
+
const rl2 = readline2.createInterface({
|
|
11289
12566
|
input: process.stdin,
|
|
11290
12567
|
output: process.stdout,
|
|
11291
12568
|
prompt: "> "
|
|
@@ -11299,11 +12576,11 @@ async function runInteractiveMode(config, model) {
|
|
|
11299
12576
|
);
|
|
11300
12577
|
}
|
|
11301
12578
|
};
|
|
11302
|
-
|
|
11303
|
-
|
|
12579
|
+
rl2.prompt();
|
|
12580
|
+
rl2.on("line", async (input) => {
|
|
11304
12581
|
const trimmed = input.trim();
|
|
11305
12582
|
if (!trimmed) {
|
|
11306
|
-
|
|
12583
|
+
rl2.prompt();
|
|
11307
12584
|
return;
|
|
11308
12585
|
}
|
|
11309
12586
|
if (trimmed === "exit" || trimmed === "quit") {
|
|
@@ -11322,7 +12599,7 @@ async function runInteractiveMode(config, model) {
|
|
|
11322
12599
|
);
|
|
11323
12600
|
}
|
|
11324
12601
|
process.stdout.write("\n");
|
|
11325
|
-
|
|
12602
|
+
rl2.close();
|
|
11326
12603
|
return;
|
|
11327
12604
|
}
|
|
11328
12605
|
if (trimmed === "status") {
|
|
@@ -11346,7 +12623,7 @@ async function runInteractiveMode(config, model) {
|
|
|
11346
12623
|
}
|
|
11347
12624
|
}
|
|
11348
12625
|
process.stdout.write("\n");
|
|
11349
|
-
|
|
12626
|
+
rl2.prompt();
|
|
11350
12627
|
return;
|
|
11351
12628
|
}
|
|
11352
12629
|
try {
|
|
@@ -11372,13 +12649,13 @@ ${response.content}
|
|
|
11372
12649
|
|
|
11373
12650
|
`);
|
|
11374
12651
|
}
|
|
11375
|
-
|
|
12652
|
+
rl2.prompt();
|
|
11376
12653
|
});
|
|
11377
|
-
|
|
12654
|
+
rl2.on("close", () => {
|
|
11378
12655
|
session.stop();
|
|
11379
12656
|
});
|
|
11380
12657
|
return new Promise((resolve5) => {
|
|
11381
|
-
|
|
12658
|
+
rl2.on("close", resolve5);
|
|
11382
12659
|
});
|
|
11383
12660
|
}
|
|
11384
12661
|
var SessionManager;
|
|
@@ -12585,19 +13862,19 @@ function worldUse(name) {
|
|
|
12585
13862
|
`);
|
|
12586
13863
|
}
|
|
12587
13864
|
function worldCurrent(json) {
|
|
12588
|
-
const
|
|
13865
|
+
const info2 = describeActiveWorld();
|
|
12589
13866
|
if (json) {
|
|
12590
|
-
process.stdout.write(JSON.stringify(
|
|
13867
|
+
process.stdout.write(JSON.stringify(info2 ?? { name: null, source: null }, null, 2) + "\n");
|
|
12591
13868
|
return;
|
|
12592
13869
|
}
|
|
12593
|
-
if (!
|
|
13870
|
+
if (!info2) {
|
|
12594
13871
|
process.stdout.write("No active world.\n");
|
|
12595
13872
|
process.stdout.write("Set one with: neuroverse world use <name>\n");
|
|
12596
13873
|
return;
|
|
12597
13874
|
}
|
|
12598
|
-
process.stdout.write(`Active world: ${
|
|
13875
|
+
process.stdout.write(`Active world: ${info2.name}
|
|
12599
13876
|
`);
|
|
12600
|
-
process.stdout.write(`Source: ${
|
|
13877
|
+
process.stdout.write(`Source: ${info2.source}
|
|
12601
13878
|
`);
|
|
12602
13879
|
}
|
|
12603
13880
|
async function main19(argv = process.argv.slice(2)) {
|
|
@@ -12862,28 +14139,28 @@ function formatEvent(event) {
|
|
|
12862
14139
|
return parts.join("\n");
|
|
12863
14140
|
}
|
|
12864
14141
|
function formatSummary(events) {
|
|
12865
|
-
const
|
|
14142
|
+
const summary2 = summarizeAuditEvents(events);
|
|
12866
14143
|
const lines = [];
|
|
12867
14144
|
lines.push("GOVERNANCE SUMMARY");
|
|
12868
14145
|
lines.push("\u2500".repeat(40));
|
|
12869
14146
|
lines.push("");
|
|
12870
|
-
lines.push(` Total actions: ${
|
|
12871
|
-
lines.push(` Allowed: ${
|
|
12872
|
-
lines.push(` Blocked: ${
|
|
12873
|
-
lines.push(` Paused: ${
|
|
12874
|
-
if (
|
|
14147
|
+
lines.push(` Total actions: ${summary2.totalActions}`);
|
|
14148
|
+
lines.push(` Allowed: ${summary2.allowed}`);
|
|
14149
|
+
lines.push(` Blocked: ${summary2.blocked}`);
|
|
14150
|
+
lines.push(` Paused: ${summary2.paused}`);
|
|
14151
|
+
if (summary2.actors.length > 0) {
|
|
12875
14152
|
lines.push("");
|
|
12876
|
-
lines.push(` Actors: ${
|
|
14153
|
+
lines.push(` Actors: ${summary2.actors.join(", ")}`);
|
|
12877
14154
|
}
|
|
12878
|
-
if (
|
|
14155
|
+
if (summary2.firstEvent) {
|
|
12879
14156
|
lines.push("");
|
|
12880
|
-
lines.push(` First event: ${
|
|
12881
|
-
lines.push(` Last event: ${
|
|
14157
|
+
lines.push(` First event: ${summary2.firstEvent}`);
|
|
14158
|
+
lines.push(` Last event: ${summary2.lastEvent}`);
|
|
12882
14159
|
}
|
|
12883
|
-
if (
|
|
14160
|
+
if (summary2.topIntents.length > 0) {
|
|
12884
14161
|
lines.push("");
|
|
12885
14162
|
lines.push(" Top actions:");
|
|
12886
|
-
for (const entry of
|
|
14163
|
+
for (const entry of summary2.topIntents.slice(0, 10)) {
|
|
12887
14164
|
const extra = [];
|
|
12888
14165
|
if (entry.blocked > 0) extra.push(`${entry.blocked} blocked`);
|
|
12889
14166
|
if (entry.paused > 0) extra.push(`${entry.paused} paused`);
|
|
@@ -12891,10 +14168,10 @@ function formatSummary(events) {
|
|
|
12891
14168
|
lines.push(` ${entry.intent.padEnd(30)} ${String(entry.count).padStart(5)}${suffix}`);
|
|
12892
14169
|
}
|
|
12893
14170
|
}
|
|
12894
|
-
if (
|
|
14171
|
+
if (summary2.topRules.length > 0) {
|
|
12895
14172
|
lines.push("");
|
|
12896
14173
|
lines.push(" Top triggered rules/guards:");
|
|
12897
|
-
for (const entry of
|
|
14174
|
+
for (const entry of summary2.topRules.slice(0, 10)) {
|
|
12898
14175
|
lines.push(` ${entry.ruleId.padEnd(30)} ${String(entry.count).padStart(5)}`);
|
|
12899
14176
|
}
|
|
12900
14177
|
}
|
|
@@ -13964,38 +15241,1784 @@ var init_configure_ai = __esm({
|
|
|
13964
15241
|
}
|
|
13965
15242
|
});
|
|
13966
15243
|
|
|
13967
|
-
// src/cli/
|
|
13968
|
-
|
|
13969
|
-
|
|
15244
|
+
// src/cli/prompt-utils.ts
|
|
15245
|
+
function getRL() {
|
|
15246
|
+
if (!rl) {
|
|
15247
|
+
rl = readline.createInterface({
|
|
15248
|
+
input: process.stdin,
|
|
15249
|
+
output: process.stderr,
|
|
15250
|
+
// prompts go to stderr, data to stdout
|
|
15251
|
+
terminal: true
|
|
15252
|
+
});
|
|
15253
|
+
}
|
|
15254
|
+
return rl;
|
|
15255
|
+
}
|
|
15256
|
+
function closePrompts() {
|
|
15257
|
+
if (rl) {
|
|
15258
|
+
rl.close();
|
|
15259
|
+
rl = null;
|
|
15260
|
+
}
|
|
15261
|
+
}
|
|
15262
|
+
function ask(question, defaultValue) {
|
|
15263
|
+
const suffix = defaultValue ? ` [${defaultValue}]` : "";
|
|
15264
|
+
return new Promise((resolve5) => {
|
|
15265
|
+
getRL().question(`
|
|
15266
|
+
${question}${suffix}: `, (answer) => {
|
|
15267
|
+
const val = answer.trim();
|
|
15268
|
+
resolve5(val || defaultValue || "");
|
|
15269
|
+
});
|
|
15270
|
+
});
|
|
15271
|
+
}
|
|
15272
|
+
function confirm(question, defaultYes = true) {
|
|
15273
|
+
const hint = defaultYes ? "[Y/n]" : "[y/N]";
|
|
15274
|
+
return new Promise((resolve5) => {
|
|
15275
|
+
getRL().question(`
|
|
15276
|
+
${question} ${hint}: `, (answer) => {
|
|
15277
|
+
const val = answer.trim().toLowerCase();
|
|
15278
|
+
if (val === "") resolve5(defaultYes);
|
|
15279
|
+
else resolve5(val === "y" || val === "yes");
|
|
15280
|
+
});
|
|
15281
|
+
});
|
|
15282
|
+
}
|
|
15283
|
+
function choose(question, options) {
|
|
15284
|
+
return new Promise((resolve5) => {
|
|
15285
|
+
const r = getRL();
|
|
15286
|
+
r.write(`
|
|
15287
|
+
${question}
|
|
15288
|
+
`);
|
|
15289
|
+
options.forEach((opt, i) => r.write(` ${i + 1}. ${opt}
|
|
15290
|
+
`));
|
|
15291
|
+
r.question(` Choice [1-${options.length}]: `, (answer) => {
|
|
15292
|
+
const idx = parseInt(answer.trim(), 10) - 1;
|
|
15293
|
+
if (idx >= 0 && idx < options.length) {
|
|
15294
|
+
resolve5(options[idx]);
|
|
15295
|
+
} else {
|
|
15296
|
+
resolve5(options[0]);
|
|
15297
|
+
}
|
|
15298
|
+
});
|
|
15299
|
+
});
|
|
15300
|
+
}
|
|
15301
|
+
async function askMany(question, hint) {
|
|
15302
|
+
const items = [];
|
|
15303
|
+
const hintText = hint ? ` (${hint})` : "";
|
|
15304
|
+
process.stderr.write(`
|
|
15305
|
+
${question}${hintText}
|
|
15306
|
+
`);
|
|
15307
|
+
process.stderr.write(" Enter items one at a time. Empty line to finish.\n");
|
|
15308
|
+
while (true) {
|
|
15309
|
+
const item = await ask(` ${items.length + 1}.`);
|
|
15310
|
+
if (!item) break;
|
|
15311
|
+
items.push(item);
|
|
15312
|
+
}
|
|
15313
|
+
return items;
|
|
15314
|
+
}
|
|
15315
|
+
function heading(text) {
|
|
15316
|
+
process.stderr.write(`
|
|
15317
|
+
${"\u2500".repeat(60)}
|
|
15318
|
+
`);
|
|
15319
|
+
process.stderr.write(` ${text}
|
|
15320
|
+
`);
|
|
15321
|
+
process.stderr.write(`${"\u2500".repeat(60)}
|
|
15322
|
+
`);
|
|
15323
|
+
}
|
|
15324
|
+
function summary(label, items) {
|
|
15325
|
+
process.stderr.write(`
|
|
15326
|
+
${label}:
|
|
15327
|
+
`);
|
|
15328
|
+
items.forEach((item) => process.stderr.write(` \u2022 ${item}
|
|
15329
|
+
`));
|
|
15330
|
+
}
|
|
15331
|
+
function info(text) {
|
|
15332
|
+
process.stderr.write(` ${text}
|
|
15333
|
+
`);
|
|
15334
|
+
}
|
|
15335
|
+
var readline, rl;
|
|
15336
|
+
var init_prompt_utils = __esm({
|
|
15337
|
+
"src/cli/prompt-utils.ts"() {
|
|
15338
|
+
"use strict";
|
|
15339
|
+
readline = __toESM(require("readline"), 1);
|
|
15340
|
+
rl = null;
|
|
15341
|
+
}
|
|
15342
|
+
});
|
|
13970
15343
|
|
|
13971
|
-
|
|
13972
|
-
|
|
13973
|
-
|
|
13974
|
-
|
|
13975
|
-
|
|
13976
|
-
|
|
13977
|
-
|
|
13978
|
-
|
|
13979
|
-
|
|
13980
|
-
|
|
13981
|
-
|
|
13982
|
-
|
|
13983
|
-
|
|
13984
|
-
|
|
13985
|
-
|
|
13986
|
-
|
|
13987
|
-
|
|
13988
|
-
|
|
13989
|
-
|
|
13990
|
-
|
|
13991
|
-
|
|
13992
|
-
|
|
13993
|
-
|
|
15344
|
+
// src/cli/configure-world.ts
|
|
15345
|
+
var configure_world_exports = {};
|
|
15346
|
+
__export(configure_world_exports, {
|
|
15347
|
+
main: () => main27
|
|
15348
|
+
});
|
|
15349
|
+
function metricToStateVariable(metric) {
|
|
15350
|
+
const id = metric.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_|_$/g, "");
|
|
15351
|
+
return {
|
|
15352
|
+
id,
|
|
15353
|
+
variable: {
|
|
15354
|
+
type: "number",
|
|
15355
|
+
min: 0,
|
|
15356
|
+
max: 100,
|
|
15357
|
+
step: 5,
|
|
15358
|
+
default: 70,
|
|
15359
|
+
mutable: true,
|
|
15360
|
+
label: metric.replace(/\b\w/g, (c) => c.toUpperCase()),
|
|
15361
|
+
description: `Measures ${metric.toLowerCase()} on a 0-100 scale`,
|
|
15362
|
+
display_as: "integer"
|
|
15363
|
+
}
|
|
15364
|
+
};
|
|
15365
|
+
}
|
|
15366
|
+
function negativeDriverToRule(driver, healthMetrics, ruleIndex) {
|
|
15367
|
+
const driverId = driver.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_|_$/g, "");
|
|
15368
|
+
const primaryTarget = healthMetrics[0]?.id || "system_health";
|
|
15369
|
+
const eventRuleId = `rule-${String(ruleIndex).padStart(3, "0")}`;
|
|
15370
|
+
const stateRuleId = `rule-${String(ruleIndex).padStart(3, "0")}-threshold`;
|
|
15371
|
+
const counterId = `${driverId}_count`;
|
|
15372
|
+
const stateVar = {
|
|
15373
|
+
type: "number",
|
|
15374
|
+
min: 0,
|
|
15375
|
+
max: 100,
|
|
15376
|
+
step: 1,
|
|
15377
|
+
default: 0,
|
|
15378
|
+
mutable: true,
|
|
15379
|
+
label: `${driver.replace(/\b\w/g, (c) => c.toUpperCase())} Count`,
|
|
15380
|
+
description: `Number of ${driver.toLowerCase()} events (0 = none)`,
|
|
15381
|
+
display_as: "integer"
|
|
15382
|
+
};
|
|
15383
|
+
const eventRule = {
|
|
15384
|
+
id: eventRuleId,
|
|
15385
|
+
severity: "degradation",
|
|
15386
|
+
label: `${driver} event degrades ${primaryTarget.replace(/_/g, " ")}`,
|
|
15387
|
+
description: `Each ${driver.toLowerCase()} event reduces ${primaryTarget.replace(/_/g, " ")} by 5 and increments the counter.`,
|
|
15388
|
+
order: ruleIndex,
|
|
15389
|
+
triggers: [{
|
|
15390
|
+
field: "event",
|
|
15391
|
+
operator: "==",
|
|
15392
|
+
value: driverId,
|
|
15393
|
+
source: "state"
|
|
15394
|
+
}],
|
|
15395
|
+
effects: [
|
|
15396
|
+
{ target: primaryTarget, operation: "subtract", value: 5 },
|
|
15397
|
+
{ target: counterId, operation: "add", value: 1 }
|
|
15398
|
+
],
|
|
15399
|
+
causal_translation: {
|
|
15400
|
+
trigger_text: `A ${driver.toLowerCase()} event occurs`,
|
|
15401
|
+
rule_text: `Each ${driver.toLowerCase()} chips away at system health`,
|
|
15402
|
+
shift_text: `${primaryTarget.replace(/_/g, " ")} decreases incrementally`,
|
|
15403
|
+
effect_text: `${primaryTarget.replace(/_/g, " ")} reduced by 5 points per event`
|
|
15404
|
+
}
|
|
15405
|
+
};
|
|
15406
|
+
const stateRule = {
|
|
15407
|
+
id: stateRuleId,
|
|
15408
|
+
severity: "degradation",
|
|
15409
|
+
label: `${driver} accumulation compounds damage`,
|
|
15410
|
+
description: `When ${driver.toLowerCase()} count exceeds threshold, ${primaryTarget.replace(/_/g, " ")} suffers compounding loss.`,
|
|
15411
|
+
order: ruleIndex + 100,
|
|
15412
|
+
triggers: [{
|
|
15413
|
+
field: counterId,
|
|
15414
|
+
operator: ">",
|
|
15415
|
+
value: 30,
|
|
15416
|
+
source: "state"
|
|
15417
|
+
}],
|
|
15418
|
+
effects: [
|
|
15419
|
+
{ target: primaryTarget, operation: "multiply", value: 0.7 }
|
|
15420
|
+
],
|
|
15421
|
+
causal_translation: {
|
|
15422
|
+
trigger_text: `${driver} count exceeds safe threshold (30)`,
|
|
15423
|
+
rule_text: `Accumulated ${driver.toLowerCase()} creates compounding pressure`,
|
|
15424
|
+
shift_text: `${primaryTarget.replace(/_/g, " ")} begins accelerating decline`,
|
|
15425
|
+
effect_text: `${primaryTarget.replace(/_/g, " ")} multiplied by 0.7 (30% loss)`
|
|
15426
|
+
}
|
|
15427
|
+
};
|
|
15428
|
+
return { id: eventRuleId, rules: [eventRule, stateRule], stateVar: { id: counterId, variable: stateVar } };
|
|
15429
|
+
}
|
|
15430
|
+
function positiveDriverToRule(driver, healthMetrics, ruleIndex) {
|
|
15431
|
+
const driverId = driver.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_|_$/g, "");
|
|
15432
|
+
const primaryTarget = healthMetrics[0]?.id || "system_health";
|
|
15433
|
+
const eventRuleId = `rule-${String(ruleIndex).padStart(3, "0")}`;
|
|
15434
|
+
const stateRuleId = `rule-${String(ruleIndex).padStart(3, "0")}-threshold`;
|
|
15435
|
+
const counterId = `${driverId}_count`;
|
|
15436
|
+
const stateVar = {
|
|
15437
|
+
type: "number",
|
|
15438
|
+
min: 0,
|
|
15439
|
+
max: 100,
|
|
15440
|
+
step: 1,
|
|
15441
|
+
default: 0,
|
|
15442
|
+
mutable: true,
|
|
15443
|
+
label: `${driver.replace(/\b\w/g, (c) => c.toUpperCase())} Count`,
|
|
15444
|
+
description: `Number of ${driver.toLowerCase()} events (0 = none)`,
|
|
15445
|
+
display_as: "integer"
|
|
15446
|
+
};
|
|
15447
|
+
const eventRule = {
|
|
15448
|
+
id: eventRuleId,
|
|
15449
|
+
severity: "advantage",
|
|
15450
|
+
label: `${driver} event improves ${primaryTarget.replace(/_/g, " ")}`,
|
|
15451
|
+
description: `Each ${driver.toLowerCase()} event increases ${primaryTarget.replace(/_/g, " ")} by 3 and increments the counter.`,
|
|
15452
|
+
order: ruleIndex,
|
|
15453
|
+
triggers: [{
|
|
15454
|
+
field: "event",
|
|
15455
|
+
operator: "==",
|
|
15456
|
+
value: driverId,
|
|
15457
|
+
source: "state"
|
|
15458
|
+
}],
|
|
15459
|
+
effects: [
|
|
15460
|
+
{ target: primaryTarget, operation: "add", value: 3 },
|
|
15461
|
+
{ target: counterId, operation: "add", value: 1 }
|
|
15462
|
+
],
|
|
15463
|
+
causal_translation: {
|
|
15464
|
+
trigger_text: `A ${driver.toLowerCase()} event occurs`,
|
|
15465
|
+
rule_text: `Each ${driver.toLowerCase()} reinforces system health`,
|
|
15466
|
+
shift_text: `${primaryTarget.replace(/_/g, " ")} improves incrementally`,
|
|
15467
|
+
effect_text: `${primaryTarget.replace(/_/g, " ")} increased by 3 points per event`
|
|
15468
|
+
}
|
|
15469
|
+
};
|
|
15470
|
+
const stateRule = {
|
|
15471
|
+
id: stateRuleId,
|
|
15472
|
+
severity: "advantage",
|
|
15473
|
+
label: `${driver} momentum amplifies improvement`,
|
|
15474
|
+
description: `When ${driver.toLowerCase()} count exceeds threshold, ${primaryTarget.replace(/_/g, " ")} gets a compounding boost.`,
|
|
15475
|
+
order: ruleIndex + 100,
|
|
15476
|
+
triggers: [{
|
|
15477
|
+
field: counterId,
|
|
15478
|
+
operator: ">",
|
|
15479
|
+
value: 20,
|
|
15480
|
+
source: "state"
|
|
15481
|
+
}],
|
|
15482
|
+
effects: [
|
|
15483
|
+
{ target: primaryTarget, operation: "multiply", value: 1.15 }
|
|
15484
|
+
],
|
|
15485
|
+
causal_translation: {
|
|
15486
|
+
trigger_text: `${driver} count exceeds momentum threshold (20)`,
|
|
15487
|
+
rule_text: `Sustained ${driver.toLowerCase()} creates compounding improvement`,
|
|
15488
|
+
shift_text: `${primaryTarget.replace(/_/g, " ")} begins accelerating growth`,
|
|
15489
|
+
effect_text: `${primaryTarget.replace(/_/g, " ")} multiplied by 1.15 (15% boost)`
|
|
15490
|
+
}
|
|
15491
|
+
};
|
|
15492
|
+
return { id: eventRuleId, rules: [eventRule, stateRule], stateVar: { id: counterId, variable: stateVar } };
|
|
15493
|
+
}
|
|
15494
|
+
function blockActionToGuard(action, index) {
|
|
15495
|
+
const id = `guard_block_${String(index).padStart(3, "0")}`;
|
|
15496
|
+
const words = action.toLowerCase().replace(/[^a-z0-9\s]/g, "").split(/\s+/).filter((w) => w.length > 2);
|
|
15497
|
+
const pattern = `*${words.join("*")}*`;
|
|
15498
|
+
return {
|
|
15499
|
+
id,
|
|
15500
|
+
label: `Block: ${action}`,
|
|
15501
|
+
description: `Prevents the system from attempting to ${action.toLowerCase()}.`,
|
|
15502
|
+
category: "structural",
|
|
15503
|
+
enforcement: "block",
|
|
15504
|
+
immutable: false,
|
|
15505
|
+
intent_patterns: [pattern]
|
|
15506
|
+
};
|
|
15507
|
+
}
|
|
15508
|
+
function reviewActionToGuard(action, index) {
|
|
15509
|
+
const id = `guard_pause_${String(index).padStart(3, "0")}`;
|
|
15510
|
+
const words = action.toLowerCase().replace(/[^a-z0-9\s]/g, "").split(/\s+/).filter((w) => w.length > 2);
|
|
15511
|
+
const pattern = `*${words.join("*")}*`;
|
|
15512
|
+
return {
|
|
15513
|
+
id,
|
|
15514
|
+
label: `Review: ${action}`,
|
|
15515
|
+
description: `Requires human review before the system can ${action.toLowerCase()}.`,
|
|
15516
|
+
category: "operational",
|
|
15517
|
+
enforcement: "pause",
|
|
15518
|
+
immutable: false,
|
|
15519
|
+
intent_patterns: [pattern]
|
|
15520
|
+
};
|
|
15521
|
+
}
|
|
15522
|
+
function generateGates(primaryMetricId) {
|
|
15523
|
+
const gates = [
|
|
15524
|
+
{ status: "THRIVING", field: primaryMetricId, operator: ">=", value: 80, color: "#22c55e", icon: "\u25C6" },
|
|
15525
|
+
{ status: "STABLE", field: primaryMetricId, operator: ">=", value: 60, color: "#3b82f6", icon: "\u25CF" },
|
|
15526
|
+
{ status: "COMPRESSED", field: primaryMetricId, operator: ">=", value: 40, color: "#f59e0b", icon: "\u25B2" },
|
|
15527
|
+
{ status: "CRITICAL", field: primaryMetricId, operator: ">=", value: 20, color: "#ef4444", icon: "\u2726" },
|
|
15528
|
+
{ status: "MODEL_COLLAPSES", field: primaryMetricId, operator: "<", value: 20, color: "#7f1d1d", icon: "\u2715" }
|
|
15529
|
+
];
|
|
15530
|
+
return {
|
|
15531
|
+
viability_classification: gates,
|
|
15532
|
+
structural_override: {
|
|
15533
|
+
description: "System collapse when primary health metric falls below critical threshold",
|
|
15534
|
+
enforcement: "mandatory"
|
|
15535
|
+
},
|
|
15536
|
+
sustainability_threshold: 40,
|
|
15537
|
+
collapse_visual: {
|
|
15538
|
+
background: "#7f1d1d",
|
|
15539
|
+
text: "#fecaca",
|
|
15540
|
+
border: "#ef4444",
|
|
15541
|
+
label: "SYSTEM COLLAPSED"
|
|
15542
|
+
}
|
|
15543
|
+
};
|
|
15544
|
+
}
|
|
15545
|
+
async function phaseContext() {
|
|
15546
|
+
heading("Let's define your system");
|
|
15547
|
+
info("We'll do two things:");
|
|
15548
|
+
info(" 1. Control what actions are allowed");
|
|
15549
|
+
info(" 2. Model what happens over time");
|
|
15550
|
+
const domain = await choose("What are you building?", [
|
|
15551
|
+
...Object.keys(DOMAIN_TEMPLATES),
|
|
15552
|
+
"Something else"
|
|
15553
|
+
]);
|
|
15554
|
+
const worldName = await ask("Give your world a name", domain === "Something else" ? "My System" : `${domain} Governance`);
|
|
15555
|
+
const worldId = worldName.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_|_$/g, "");
|
|
15556
|
+
const thesis = await ask(
|
|
15557
|
+
"In one sentence, what does this system govern?",
|
|
15558
|
+
domain !== "Something else" ? `Governance model for ${domain.toLowerCase()} operations` : void 0
|
|
15559
|
+
);
|
|
15560
|
+
return { worldName, worldId, thesis, domain };
|
|
15561
|
+
}
|
|
15562
|
+
async function phaseGuard(domain) {
|
|
15563
|
+
heading("Layer 1: Action Control");
|
|
15564
|
+
info("What should this system NOT do?");
|
|
15565
|
+
const template = DOMAIN_TEMPLATES[domain];
|
|
15566
|
+
let blockActions;
|
|
15567
|
+
let reviewActions;
|
|
15568
|
+
if (template) {
|
|
15569
|
+
info(`
|
|
15570
|
+
Suggested for ${domain}:`);
|
|
15571
|
+
template.blockActions.forEach((a) => info(` BLOCK: ${a}`));
|
|
15572
|
+
const useSuggested = await confirm("Use these suggestions?");
|
|
15573
|
+
if (useSuggested) {
|
|
15574
|
+
blockActions = [...template.blockActions];
|
|
15575
|
+
} else {
|
|
15576
|
+
blockActions = await askMany("What should be BLOCKED?", "actions the system must never do");
|
|
15577
|
+
}
|
|
15578
|
+
info("\n What should require human review?");
|
|
15579
|
+
if (useSuggested) {
|
|
15580
|
+
template.reviewActions.forEach((a) => info(` REVIEW: ${a}`));
|
|
15581
|
+
const useReviewSuggested = await confirm("Use these suggestions?");
|
|
15582
|
+
reviewActions = useReviewSuggested ? [...template.reviewActions] : await askMany("What needs human REVIEW?");
|
|
15583
|
+
} else {
|
|
15584
|
+
reviewActions = await askMany("What needs human REVIEW?", "actions that need approval");
|
|
15585
|
+
}
|
|
15586
|
+
} else {
|
|
15587
|
+
blockActions = await askMany("What should be BLOCKED?", "actions the system must never do");
|
|
15588
|
+
reviewActions = await askMany("What needs human REVIEW?", "actions that need approval");
|
|
15589
|
+
}
|
|
15590
|
+
if (blockActions.length > 0 || reviewActions.length > 0) {
|
|
15591
|
+
summary("Actions configured", [
|
|
15592
|
+
...blockActions.map((a) => `BLOCK: ${a}`),
|
|
15593
|
+
...reviewActions.map((a) => `REVIEW: ${a}`)
|
|
15594
|
+
]);
|
|
15595
|
+
}
|
|
15596
|
+
return { blockActions, reviewActions };
|
|
15597
|
+
}
|
|
15598
|
+
async function phaseSystem(domain) {
|
|
15599
|
+
heading("Layer 2: System Dynamics");
|
|
15600
|
+
info("Now let's define what a healthy system looks like over time.\n");
|
|
15601
|
+
const template = DOMAIN_TEMPLATES[domain];
|
|
15602
|
+
let healthMetrics;
|
|
15603
|
+
let negativeDrivers;
|
|
15604
|
+
let positiveDrivers;
|
|
15605
|
+
info("What are you trying to protect or optimize?");
|
|
15606
|
+
if (template) {
|
|
15607
|
+
info(" Examples:");
|
|
15608
|
+
template.healthMetrics.forEach((m) => info(` \u2022 ${m.replace(/_/g, " ")}`));
|
|
15609
|
+
const useSuggested = await confirm("Use these suggestions?");
|
|
15610
|
+
if (useSuggested) {
|
|
15611
|
+
healthMetrics = [...template.healthMetrics];
|
|
15612
|
+
} else {
|
|
15613
|
+
healthMetrics = await askMany("What metrics define system health?", "e.g., customer satisfaction, trust, revenue");
|
|
15614
|
+
}
|
|
15615
|
+
} else {
|
|
15616
|
+
healthMetrics = await askMany("What metrics define system health?", "e.g., customer satisfaction, trust, revenue");
|
|
15617
|
+
}
|
|
15618
|
+
if (healthMetrics.length === 0) {
|
|
15619
|
+
healthMetrics = ["system_health"];
|
|
15620
|
+
info(' Defaulting to "system_health" as primary metric.');
|
|
15621
|
+
}
|
|
15622
|
+
info("\n What makes this worse?");
|
|
15623
|
+
if (template) {
|
|
15624
|
+
info(" Examples:");
|
|
15625
|
+
template.negativDrivers.forEach((d) => info(` \u2022 ${d.replace(/_/g, " ")}`));
|
|
15626
|
+
const useSuggested = await confirm("Use these suggestions?");
|
|
15627
|
+
negativeDrivers = useSuggested ? [...template.negativDrivers] : await askMany("What degrades your system?");
|
|
15628
|
+
} else {
|
|
15629
|
+
negativeDrivers = await askMany("What degrades your system?", "e.g., complaints, errors, delays");
|
|
15630
|
+
}
|
|
15631
|
+
info("\n What makes this better?");
|
|
15632
|
+
if (template) {
|
|
15633
|
+
info(" Examples:");
|
|
15634
|
+
template.positiveDrivers.forEach((d) => info(` \u2022 ${d.replace(/_/g, " ")}`));
|
|
15635
|
+
const useSuggested = await confirm("Use these suggestions?");
|
|
15636
|
+
positiveDrivers = useSuggested ? [...template.positiveDrivers] : await askMany("What improves your system?");
|
|
15637
|
+
} else {
|
|
15638
|
+
positiveDrivers = await askMany("What improves your system?", "e.g., fast responses, positive feedback");
|
|
15639
|
+
}
|
|
15640
|
+
summary("System dynamics", [
|
|
15641
|
+
`Health: ${healthMetrics.join(", ")}`,
|
|
15642
|
+
`Degrades from: ${negativeDrivers.join(", ") || "(none)"}`,
|
|
15643
|
+
`Improves from: ${positiveDrivers.join(", ") || "(none)"}`
|
|
15644
|
+
]);
|
|
15645
|
+
return { healthMetrics, negativeDrivers, positiveDrivers };
|
|
15646
|
+
}
|
|
15647
|
+
function generateWorld(state) {
|
|
15648
|
+
const worldJson = {
|
|
15649
|
+
world_id: state.worldId,
|
|
15650
|
+
name: state.worldName,
|
|
15651
|
+
thesis: state.thesis,
|
|
15652
|
+
version: "1.0.0",
|
|
15653
|
+
runtime_mode: "SIMULATION",
|
|
15654
|
+
default_assumption_profile: "baseline",
|
|
15655
|
+
default_alternative_profile: "stress",
|
|
15656
|
+
modules: [],
|
|
15657
|
+
players: { thinking_space: true, experience_space: true, action_space: true }
|
|
15658
|
+
};
|
|
15659
|
+
const variables = {};
|
|
15660
|
+
const metricIds = [];
|
|
15661
|
+
for (const metric of state.healthMetrics) {
|
|
15662
|
+
const { id, variable } = metricToStateVariable(metric);
|
|
15663
|
+
variables[id] = variable;
|
|
15664
|
+
metricIds.push({ id });
|
|
15665
|
+
}
|
|
15666
|
+
const rules = [];
|
|
15667
|
+
let ruleIdx = 1;
|
|
15668
|
+
for (const driver of state.negativeDrivers) {
|
|
15669
|
+
const result = negativeDriverToRule(driver, metricIds, ruleIdx++);
|
|
15670
|
+
rules.push(...result.rules);
|
|
15671
|
+
if (!variables[result.stateVar.id]) {
|
|
15672
|
+
variables[result.stateVar.id] = result.stateVar.variable;
|
|
15673
|
+
}
|
|
15674
|
+
}
|
|
15675
|
+
for (const driver of state.positiveDrivers) {
|
|
15676
|
+
const result = positiveDriverToRule(driver, metricIds, ruleIdx++);
|
|
15677
|
+
rules.push(...result.rules);
|
|
15678
|
+
if (!variables[result.stateVar.id]) {
|
|
15679
|
+
variables[result.stateVar.id] = result.stateVar.variable;
|
|
15680
|
+
}
|
|
15681
|
+
}
|
|
15682
|
+
const stateSchema = {
|
|
15683
|
+
variables,
|
|
15684
|
+
presets: {
|
|
15685
|
+
"Healthy": {
|
|
15686
|
+
description: "System operating normally",
|
|
15687
|
+
values: Object.fromEntries(
|
|
15688
|
+
Object.entries(variables).map(([id, v]) => [id, v.default])
|
|
15689
|
+
)
|
|
15690
|
+
},
|
|
15691
|
+
"Stressed": {
|
|
15692
|
+
description: "System under pressure",
|
|
15693
|
+
values: Object.fromEntries(
|
|
15694
|
+
Object.entries(variables).map(([id, v]) => {
|
|
15695
|
+
if (id.endsWith("_count") && state.negativeDrivers.some((d) => id.startsWith(d.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_|_$/g, "")))) {
|
|
15696
|
+
return [id, 40];
|
|
15697
|
+
}
|
|
15698
|
+
if (state.healthMetrics.some((m) => m.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_|_$/g, "") === id)) {
|
|
15699
|
+
return [id, 40];
|
|
15700
|
+
}
|
|
15701
|
+
return [id, v.default];
|
|
15702
|
+
})
|
|
15703
|
+
)
|
|
15704
|
+
}
|
|
15705
|
+
}
|
|
15706
|
+
};
|
|
15707
|
+
const guards = [];
|
|
15708
|
+
state.blockActions.forEach((action, i) => {
|
|
15709
|
+
guards.push(blockActionToGuard(action, i + 1));
|
|
15710
|
+
});
|
|
15711
|
+
state.reviewActions.forEach((action, i) => {
|
|
15712
|
+
guards.push(reviewActionToGuard(action, i + 1));
|
|
15713
|
+
});
|
|
15714
|
+
const guardsJson = {
|
|
15715
|
+
guards,
|
|
15716
|
+
intent_vocabulary: {}
|
|
15717
|
+
};
|
|
15718
|
+
const primaryMetricId = metricIds[0]?.id || "system_health";
|
|
15719
|
+
const gatesJson = generateGates(primaryMetricId);
|
|
15720
|
+
const invariants = [
|
|
15721
|
+
{
|
|
15722
|
+
id: "system_must_remain_governable",
|
|
15723
|
+
label: "System must remain under governance at all times",
|
|
15724
|
+
enforcement: "structural",
|
|
15725
|
+
mutable: false
|
|
15726
|
+
}
|
|
15727
|
+
];
|
|
15728
|
+
const primaryOutcome = {
|
|
15729
|
+
id: primaryMetricId,
|
|
15730
|
+
type: "number",
|
|
15731
|
+
range: [0, 100],
|
|
15732
|
+
display_as: "integer",
|
|
15733
|
+
label: variables[primaryMetricId]?.label || "System Health",
|
|
15734
|
+
primary: true,
|
|
15735
|
+
show_in_comparison: true
|
|
15736
|
+
};
|
|
15737
|
+
const outcomes = {
|
|
15738
|
+
computed_outcomes: [
|
|
15739
|
+
primaryOutcome,
|
|
15740
|
+
...metricIds.slice(1).map((m) => ({
|
|
15741
|
+
id: m.id,
|
|
15742
|
+
type: "number",
|
|
15743
|
+
range: [0, 100],
|
|
15744
|
+
display_as: "integer",
|
|
15745
|
+
label: variables[m.id]?.label || m.id,
|
|
15746
|
+
primary: false,
|
|
15747
|
+
show_in_comparison: true
|
|
15748
|
+
}))
|
|
15749
|
+
],
|
|
15750
|
+
comparison_layout: {
|
|
15751
|
+
primary_card: primaryMetricId,
|
|
15752
|
+
status_badge: primaryMetricId,
|
|
15753
|
+
structural_indicators: metricIds.map((m) => m.id)
|
|
15754
|
+
}
|
|
15755
|
+
};
|
|
15756
|
+
const metadata = {
|
|
15757
|
+
format_version: "1.0.0",
|
|
15758
|
+
created_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
15759
|
+
last_modified: (/* @__PURE__ */ new Date()).toISOString(),
|
|
15760
|
+
authoring_method: "configurator-ai"
|
|
15761
|
+
};
|
|
15762
|
+
return { worldJson, stateSchema, guardsJson, rules, gatesJson, invariants, outcomes, metadata };
|
|
15763
|
+
}
|
|
15764
|
+
async function writeWorld(outputDir, world) {
|
|
15765
|
+
const { mkdirSync: mkdirSync3, existsSync: existsSync6 } = await import("fs");
|
|
15766
|
+
const { writeFile: writeFile5 } = await import("fs/promises");
|
|
15767
|
+
const { join: join9 } = await import("path");
|
|
15768
|
+
const files = [];
|
|
15769
|
+
if (!existsSync6(outputDir)) mkdirSync3(outputDir, { recursive: true });
|
|
15770
|
+
const rulesDir = join9(outputDir, "rules");
|
|
15771
|
+
if (!existsSync6(rulesDir)) mkdirSync3(rulesDir, { recursive: true });
|
|
15772
|
+
const writeJson = async (name, data) => {
|
|
15773
|
+
const path = join9(outputDir, name);
|
|
15774
|
+
await writeFile5(path, JSON.stringify(data, null, 2) + "\n", "utf-8");
|
|
15775
|
+
files.push(path);
|
|
15776
|
+
};
|
|
15777
|
+
await writeJson("world.json", world.worldJson);
|
|
15778
|
+
await writeJson("state-schema.json", world.stateSchema);
|
|
15779
|
+
await writeJson("guards.json", world.guardsJson);
|
|
15780
|
+
await writeJson("gates.json", world.gatesJson);
|
|
15781
|
+
await writeJson("invariants.json", world.invariants);
|
|
15782
|
+
await writeJson("outcomes.json", world.outcomes);
|
|
15783
|
+
await writeJson("metadata.json", world.metadata);
|
|
15784
|
+
for (const rule of world.rules) {
|
|
15785
|
+
const rulePath = join9(rulesDir, `${rule.id}.json`);
|
|
15786
|
+
await writeFile5(rulePath, JSON.stringify(rule, null, 2) + "\n", "utf-8");
|
|
15787
|
+
files.push(rulePath);
|
|
15788
|
+
}
|
|
15789
|
+
return files;
|
|
15790
|
+
}
|
|
15791
|
+
function parseArgs21(argv) {
|
|
15792
|
+
let outputDir = "./world/";
|
|
15793
|
+
for (let i = 0; i < argv.length; i++) {
|
|
15794
|
+
const arg = argv[i];
|
|
15795
|
+
if ((arg === "--output" || arg === "-o") && i + 1 < argv.length) {
|
|
15796
|
+
outputDir = argv[++i];
|
|
15797
|
+
}
|
|
15798
|
+
}
|
|
15799
|
+
return { outputDir };
|
|
15800
|
+
}
|
|
15801
|
+
async function main27(argv = process.argv.slice(2)) {
|
|
15802
|
+
try {
|
|
15803
|
+
const args = parseArgs21(argv);
|
|
15804
|
+
const context = await phaseContext();
|
|
15805
|
+
const guardState = await phaseGuard(context.domain);
|
|
15806
|
+
const systemState = await phaseSystem(context.domain);
|
|
15807
|
+
const wizardState = {
|
|
15808
|
+
...context,
|
|
15809
|
+
...guardState,
|
|
15810
|
+
...systemState
|
|
15811
|
+
};
|
|
15812
|
+
heading("Summary");
|
|
15813
|
+
info(`World: ${wizardState.worldName}`);
|
|
15814
|
+
info(`Thesis: ${wizardState.thesis}`);
|
|
15815
|
+
summary("Guard rules", [
|
|
15816
|
+
...wizardState.blockActions.map((a) => `BLOCK: ${a}`),
|
|
15817
|
+
...wizardState.reviewActions.map((a) => `REVIEW: ${a}`)
|
|
15818
|
+
]);
|
|
15819
|
+
summary("System dynamics", [
|
|
15820
|
+
`Health metrics: ${wizardState.healthMetrics.join(", ")}`,
|
|
15821
|
+
`Degrades from: ${wizardState.negativeDrivers.join(", ") || "(none)"}`,
|
|
15822
|
+
`Improves from: ${wizardState.positiveDrivers.join(", ") || "(none)"}`
|
|
15823
|
+
]);
|
|
15824
|
+
const proceed = await confirm("\nCreate world?");
|
|
15825
|
+
if (!proceed) {
|
|
15826
|
+
info("Aborted.");
|
|
15827
|
+
closePrompts();
|
|
15828
|
+
process.exit(0);
|
|
15829
|
+
return;
|
|
15830
|
+
}
|
|
15831
|
+
info("\nGenerating world...");
|
|
15832
|
+
const world = generateWorld(wizardState);
|
|
15833
|
+
const files = await writeWorld(args.outputDir, world);
|
|
15834
|
+
heading("World created");
|
|
15835
|
+
info(`Output: ${args.outputDir}`);
|
|
15836
|
+
info(`Files: ${files.length}`);
|
|
15837
|
+
summary("Generated", [
|
|
15838
|
+
`${Object.keys(world.stateSchema.variables).length} state variables`,
|
|
15839
|
+
`${world.rules.length} rules (${world.rules.filter((r) => r.severity === "degradation").length} degradation, ${world.rules.filter((r) => r.severity === "advantage").length} advantage)`,
|
|
15840
|
+
`${world.guardsJson.guards.length} guards (${world.guardsJson.guards.filter((g) => g.enforcement === "block").length} block, ${world.guardsJson.guards.filter((g) => g.enforcement === "pause").length} pause)`,
|
|
15841
|
+
`5 viability gates (THRIVING \u2192 MODEL_COLLAPSES)`
|
|
15842
|
+
]);
|
|
15843
|
+
info("\nNext steps:");
|
|
15844
|
+
info(` neuroverse validate --world ${args.outputDir}`);
|
|
15845
|
+
info(` neuroverse simulate ${args.outputDir} --steps 5`);
|
|
15846
|
+
info(` neuroverse explain ${args.outputDir}`);
|
|
15847
|
+
const refine = await confirm("\nWant to refine thresholds and collapse rules?", false);
|
|
15848
|
+
if (refine) {
|
|
15849
|
+
await phaseRefine(args.outputDir, world);
|
|
15850
|
+
}
|
|
15851
|
+
closePrompts();
|
|
15852
|
+
const result = {
|
|
15853
|
+
created: args.outputDir,
|
|
15854
|
+
worldName: wizardState.worldName,
|
|
15855
|
+
files: files.length,
|
|
15856
|
+
stateVariables: Object.keys(world.stateSchema.variables).length,
|
|
15857
|
+
rules: world.rules.length,
|
|
15858
|
+
guards: world.guardsJson.guards.length,
|
|
15859
|
+
gates: 5
|
|
15860
|
+
};
|
|
15861
|
+
process.stdout.write(JSON.stringify(result, null, 2) + "\n");
|
|
15862
|
+
process.exit(0);
|
|
15863
|
+
} catch (e) {
|
|
15864
|
+
closePrompts();
|
|
15865
|
+
process.stderr.write(`Error: ${e instanceof Error ? e.message : String(e)}
|
|
15866
|
+
`);
|
|
15867
|
+
process.exit(3);
|
|
15868
|
+
}
|
|
15869
|
+
}
|
|
15870
|
+
async function phaseRefine(outputDir, world) {
|
|
15871
|
+
const { writeFile: writeFile5 } = await import("fs/promises");
|
|
15872
|
+
const { join: join9 } = await import("path");
|
|
15873
|
+
heading("Refinement: Thresholds & Collapse");
|
|
15874
|
+
const primaryMetric = world.gatesJson.viability_classification[0]?.field || "system_health";
|
|
15875
|
+
info(`
|
|
15876
|
+
Primary health metric: ${primaryMetric}`);
|
|
15877
|
+
info(" Current gate thresholds:");
|
|
15878
|
+
for (const gate of world.gatesJson.viability_classification) {
|
|
15879
|
+
info(` ${gate.status}: ${gate.field} ${gate.operator} ${gate.value}`);
|
|
15880
|
+
}
|
|
15881
|
+
const changeGates = await confirm("Adjust gate thresholds?", false);
|
|
15882
|
+
if (changeGates) {
|
|
15883
|
+
for (const gate of world.gatesJson.viability_classification) {
|
|
15884
|
+
const newVal = await ask(` ${gate.status} threshold (${gate.operator})`, String(gate.value));
|
|
15885
|
+
const parsed = parseInt(newVal, 10);
|
|
15886
|
+
if (!isNaN(parsed)) gate.value = parsed;
|
|
15887
|
+
}
|
|
15888
|
+
await writeFile5(
|
|
15889
|
+
join9(outputDir, "gates.json"),
|
|
15890
|
+
JSON.stringify(world.gatesJson, null, 2) + "\n",
|
|
15891
|
+
"utf-8"
|
|
15892
|
+
);
|
|
15893
|
+
info(" Gates updated.");
|
|
15894
|
+
}
|
|
15895
|
+
const addCollapse = await confirm("Add collapse conditions to degradation rules?", false);
|
|
15896
|
+
if (addCollapse) {
|
|
15897
|
+
for (const rule of world.rules.filter((r) => r.severity === "degradation")) {
|
|
15898
|
+
info(`
|
|
15899
|
+
Rule: ${rule.label}`);
|
|
15900
|
+
const target = rule.effects?.[0]?.target || primaryMetric;
|
|
15901
|
+
const collapseVal = await ask(` ${target} collapses below what value?`, "10");
|
|
15902
|
+
const parsed = parseInt(collapseVal, 10);
|
|
15903
|
+
if (!isNaN(parsed)) {
|
|
15904
|
+
rule.collapse_check = {
|
|
15905
|
+
field: target,
|
|
15906
|
+
operator: "<",
|
|
15907
|
+
value: parsed,
|
|
15908
|
+
result: "MODEL_COLLAPSES"
|
|
15909
|
+
};
|
|
15910
|
+
await writeFile5(
|
|
15911
|
+
join9(outputDir, "rules", `${rule.id}.json`),
|
|
15912
|
+
JSON.stringify(rule, null, 2) + "\n",
|
|
15913
|
+
"utf-8"
|
|
15914
|
+
);
|
|
15915
|
+
info(` Collapse condition added: ${target} < ${parsed}`);
|
|
15916
|
+
}
|
|
15917
|
+
}
|
|
15918
|
+
}
|
|
15919
|
+
}
|
|
15920
|
+
var DOMAIN_TEMPLATES;
|
|
15921
|
+
var init_configure_world = __esm({
|
|
15922
|
+
"src/cli/configure-world.ts"() {
|
|
15923
|
+
"use strict";
|
|
15924
|
+
init_prompt_utils();
|
|
15925
|
+
DOMAIN_TEMPLATES = {
|
|
15926
|
+
"Customer service": {
|
|
15927
|
+
label: "Customer service",
|
|
15928
|
+
healthMetrics: ["customer_satisfaction", "trust_score", "resolution_rate"],
|
|
15929
|
+
negativDrivers: ["complaints", "slow_responses", "escalations"],
|
|
15930
|
+
positiveDrivers: ["fast_responses", "positive_feedback", "first_contact_resolution"],
|
|
15931
|
+
blockActions: ["share customer PII", "issue unauthorized refunds", "make legal promises"],
|
|
15932
|
+
reviewActions: ["escalations", "large refund requests", "account closures"]
|
|
15933
|
+
},
|
|
15934
|
+
"Trading system": {
|
|
15935
|
+
label: "Trading system",
|
|
15936
|
+
healthMetrics: ["portfolio_health", "risk_score", "compliance_rate"],
|
|
15937
|
+
negativDrivers: ["losses", "risk_violations", "unauthorized_trades"],
|
|
15938
|
+
positiveDrivers: ["profitable_trades", "risk_compliance", "diversification"],
|
|
15939
|
+
blockActions: ["exceed risk limits", "trade restricted securities", "bypass compliance"],
|
|
15940
|
+
reviewActions: ["large positions", "new asset classes", "margin changes"]
|
|
15941
|
+
},
|
|
15942
|
+
"Content moderation": {
|
|
15943
|
+
label: "Content moderation",
|
|
15944
|
+
healthMetrics: ["content_quality", "safety_score", "creator_trust"],
|
|
15945
|
+
negativDrivers: ["policy_violations", "false_positives", "user_reports"],
|
|
15946
|
+
positiveDrivers: ["clean_content", "accurate_moderation", "appeal_resolutions"],
|
|
15947
|
+
blockActions: ["approve harmful content", "ban without review", "ignore reports"],
|
|
15948
|
+
reviewActions: ["borderline content", "repeat offenders", "appeal requests"]
|
|
15949
|
+
},
|
|
15950
|
+
"Research agent": {
|
|
15951
|
+
label: "Research agent",
|
|
15952
|
+
healthMetrics: ["accuracy_score", "source_quality", "output_reliability"],
|
|
15953
|
+
negativDrivers: ["hallucinations", "unsourced_claims", "bias_incidents"],
|
|
15954
|
+
positiveDrivers: ["verified_findings", "diverse_sources", "peer_validation"],
|
|
15955
|
+
blockActions: ["fabricate citations", "present opinion as fact", "ignore contradicting evidence"],
|
|
15956
|
+
reviewActions: ["novel conclusions", "controversial topics", "policy recommendations"]
|
|
15957
|
+
}
|
|
15958
|
+
};
|
|
15959
|
+
}
|
|
15960
|
+
});
|
|
15961
|
+
|
|
15962
|
+
// src/builder/lens.ts
|
|
15963
|
+
function getLenses() {
|
|
15964
|
+
return BUILTIN_LENSES;
|
|
15965
|
+
}
|
|
15966
|
+
function getLens(id) {
|
|
15967
|
+
return BUILTIN_LENSES.find((w) => w.id === id);
|
|
15968
|
+
}
|
|
15969
|
+
function compileLensOverlay(lenses, intent) {
|
|
15970
|
+
const sorted = [...lenses].sort((a, b) => a.priority - b.priority);
|
|
15971
|
+
const activeDirectives = [];
|
|
15972
|
+
for (const wv of sorted) {
|
|
15973
|
+
const applicable = wv.directives.filter((d) => {
|
|
15974
|
+
if (!d.condition) return true;
|
|
15975
|
+
if (!intent) return true;
|
|
15976
|
+
return d.condition.includes(intent);
|
|
15977
|
+
});
|
|
15978
|
+
for (const d of applicable) {
|
|
15979
|
+
activeDirectives.push({
|
|
15980
|
+
id: `${wv.id}/${d.id}`,
|
|
15981
|
+
instruction: d.instruction
|
|
15982
|
+
});
|
|
15983
|
+
}
|
|
15984
|
+
}
|
|
15985
|
+
const toneSection = buildToneSection(sorted);
|
|
15986
|
+
const directiveSection = activeDirectives.map((d) => `- ${d.instruction}`).join("\n");
|
|
15987
|
+
const systemPromptAddition = `## Behavioral Guidelines
|
|
15988
|
+
|
|
15989
|
+
${toneSection}
|
|
15990
|
+
|
|
15991
|
+
### Directives
|
|
15992
|
+
${directiveSection}
|
|
15993
|
+
|
|
15994
|
+
These guidelines shape HOW you respond, not WHETHER you respond. Follow them consistently.`;
|
|
15995
|
+
return {
|
|
15996
|
+
systemPromptAddition,
|
|
15997
|
+
activeDirectives,
|
|
15998
|
+
sources: sorted.map((w) => w.id)
|
|
15999
|
+
};
|
|
16000
|
+
}
|
|
16001
|
+
function buildToneSection(lenses) {
|
|
16002
|
+
const tone = lenses[lenses.length - 1]?.tone;
|
|
16003
|
+
if (!tone) return "";
|
|
16004
|
+
const parts = [];
|
|
16005
|
+
if (tone.formality !== "neutral") parts.push(`Formality: ${tone.formality}`);
|
|
16006
|
+
if (tone.verbosity !== "balanced") parts.push(`Verbosity: ${tone.verbosity}`);
|
|
16007
|
+
if (tone.emotion !== "neutral") parts.push(`Emotional register: ${tone.emotion}`);
|
|
16008
|
+
if (tone.confidence !== "balanced") parts.push(`Confidence: ${tone.confidence}`);
|
|
16009
|
+
if (parts.length === 0) return "";
|
|
16010
|
+
return `### Tone
|
|
16011
|
+
${parts.join(". ")}.
|
|
16012
|
+
`;
|
|
16013
|
+
}
|
|
16014
|
+
function previewLens(lens) {
|
|
16015
|
+
const BOLD2 = "\x1B[1m";
|
|
16016
|
+
const DIM2 = "\x1B[2m";
|
|
16017
|
+
const CYAN2 = "\x1B[36m";
|
|
16018
|
+
const YELLOW2 = "\x1B[33m";
|
|
16019
|
+
const GREEN2 = "\x1B[32m";
|
|
16020
|
+
const RESET2 = "\x1B[0m";
|
|
16021
|
+
const lines = [];
|
|
16022
|
+
lines.push("");
|
|
16023
|
+
lines.push(`${BOLD2}${CYAN2} ${lens.name}${RESET2} ${DIM2}\u2014 ${lens.tagline}${RESET2}`);
|
|
16024
|
+
lines.push(`${DIM2} ${lens.description}${RESET2}`);
|
|
16025
|
+
lines.push("");
|
|
16026
|
+
for (const d of lens.directives) {
|
|
16027
|
+
if (d.example) {
|
|
16028
|
+
lines.push(` ${BOLD2}${d.id}${RESET2}`);
|
|
16029
|
+
lines.push(` ${YELLOW2}Without:${RESET2} ${DIM2}${d.example.without}${RESET2}`);
|
|
16030
|
+
lines.push(` ${GREEN2}With:${RESET2} ${d.example.with}`);
|
|
16031
|
+
lines.push("");
|
|
16032
|
+
}
|
|
16033
|
+
}
|
|
16034
|
+
return lines.join("\n");
|
|
16035
|
+
}
|
|
16036
|
+
function lensesFromWorld(world) {
|
|
16037
|
+
if (!world.lenses) return [];
|
|
16038
|
+
return world.lenses.lenses.map((lc) => ({
|
|
16039
|
+
id: lc.id,
|
|
16040
|
+
name: lc.name,
|
|
16041
|
+
tagline: lc.tagline,
|
|
16042
|
+
author: "world",
|
|
16043
|
+
version: "1.0.0",
|
|
16044
|
+
description: lc.description,
|
|
16045
|
+
tags: lc.tags,
|
|
16046
|
+
tone: {
|
|
16047
|
+
formality: lc.tone.formality || "neutral",
|
|
16048
|
+
verbosity: lc.tone.verbosity || "balanced",
|
|
16049
|
+
emotion: lc.tone.emotion || "neutral",
|
|
16050
|
+
confidence: lc.tone.confidence || "balanced"
|
|
16051
|
+
},
|
|
16052
|
+
directives: lc.directives.map((d) => ({
|
|
16053
|
+
id: d.id,
|
|
16054
|
+
scope: d.scope,
|
|
16055
|
+
instruction: d.instruction
|
|
16056
|
+
})),
|
|
16057
|
+
appliesTo: "all",
|
|
16058
|
+
stackable: lc.stackable,
|
|
16059
|
+
priority: lc.priority
|
|
16060
|
+
}));
|
|
16061
|
+
}
|
|
16062
|
+
function lensForRole(world, roleId, roleLensOverride) {
|
|
16063
|
+
const lenses = lensesFromWorld(world);
|
|
16064
|
+
if (lenses.length === 0) return void 0;
|
|
16065
|
+
if (roleLensOverride) {
|
|
16066
|
+
const found = lenses.find((l) => l.id === roleLensOverride);
|
|
16067
|
+
if (found) return found;
|
|
16068
|
+
}
|
|
16069
|
+
const byRole = lenses.find((l) => {
|
|
16070
|
+
if (!world.lenses) return false;
|
|
16071
|
+
const config = world.lenses.lenses.find((lc) => lc.id === l.id);
|
|
16072
|
+
return config?.defaultForRoles.includes(roleId) || config?.defaultForRoles.includes("all");
|
|
16073
|
+
});
|
|
16074
|
+
if (byRole) return byRole;
|
|
16075
|
+
return lenses[0];
|
|
16076
|
+
}
|
|
16077
|
+
var STOIC_LENS, CLOSER_LENS, SAMURAI_LENS, HYPE_MAN_LENS, MONK_LENS, SOCRATIC_LENS, MINIMALIST_LENS, COACH_LENS, CALM_LENS, BUILTIN_LENSES;
|
|
16078
|
+
var init_lens = __esm({
|
|
16079
|
+
"src/builder/lens.ts"() {
|
|
16080
|
+
"use strict";
|
|
16081
|
+
STOIC_LENS = {
|
|
16082
|
+
id: "stoic",
|
|
16083
|
+
name: "Stoic Lens",
|
|
16084
|
+
tagline: "Focus on what you can control.",
|
|
16085
|
+
author: "NeuroverseOS",
|
|
16086
|
+
version: "1.0.0",
|
|
16087
|
+
description: "Inspired by Marcus Aurelius, Epictetus, and Seneca. AI responses emphasize what is within your control, frame obstacles as opportunities for growth, avoid catastrophizing, and present information with calm clarity. The AI does not tell you how to feel \u2014 it helps you see clearly.",
|
|
16088
|
+
tags: ["philosophy", "stoicism", "mindfulness", "clarity"],
|
|
16089
|
+
stackable: true,
|
|
16090
|
+
priority: 50,
|
|
16091
|
+
appliesTo: "all",
|
|
16092
|
+
tone: {
|
|
16093
|
+
formality: "neutral",
|
|
16094
|
+
verbosity: "concise",
|
|
16095
|
+
emotion: "reserved",
|
|
16096
|
+
confidence: "balanced"
|
|
16097
|
+
},
|
|
16098
|
+
directives: [
|
|
16099
|
+
{
|
|
16100
|
+
id: "dichotomy_of_control",
|
|
16101
|
+
scope: "response_framing",
|
|
16102
|
+
instruction: "When presenting information about a situation, clearly distinguish between what is within the user's control (their actions, choices, responses) and what is outside their control (other people's behavior, external events, outcomes). Emphasize actionable paths forward.",
|
|
16103
|
+
example: {
|
|
16104
|
+
without: "Your meeting was cancelled. That's frustrating. The other person probably doesn't value your time.",
|
|
16105
|
+
with: "Your meeting was cancelled. You can't control their schedule, but you now have an open hour. Would you like to use it for the task you mentioned earlier?"
|
|
16106
|
+
}
|
|
16107
|
+
},
|
|
16108
|
+
{
|
|
16109
|
+
id: "obstacle_as_opportunity",
|
|
16110
|
+
scope: "response_framing",
|
|
16111
|
+
instruction: "When the user encounters a problem or setback, do not minimize it or be falsely positive. Instead, acknowledge the reality and frame it as information that can be acted on. Avoid catastrophizing. Present the obstacle and the available paths forward with equal clarity.",
|
|
16112
|
+
example: {
|
|
16113
|
+
without: "Oh no, the shipment is delayed again! This keeps happening. Your customers are going to be upset.",
|
|
16114
|
+
with: "Shipment delayed by 3 days. Two options: notify affected customers now with updated timeline, or source from the backup supplier at higher cost. Which would you like to explore?"
|
|
16115
|
+
}
|
|
16116
|
+
},
|
|
16117
|
+
{
|
|
16118
|
+
id: "no_emotional_manipulation",
|
|
16119
|
+
scope: "behavior_shaping",
|
|
16120
|
+
instruction: "Do not attempt to influence the user's emotional state. Do not use urgency, fear, excitement, or social pressure to shape decisions. Present facts and options. Let the user decide how to feel about them."
|
|
16121
|
+
},
|
|
16122
|
+
{
|
|
16123
|
+
id: "clarity_over_comfort",
|
|
16124
|
+
scope: "language_style",
|
|
16125
|
+
instruction: `Prefer clear, direct language over hedging or softening. If news is bad, say so plainly. If a decision has tradeoffs, name them. Do not pad responses with filler phrases like "I understand how you feel" or "That must be difficult." Respect the user's capacity to handle reality.`,
|
|
16126
|
+
example: {
|
|
16127
|
+
without: "I totally understand this is stressful! Don't worry though, I'm sure it will work out. Let me help you think through this...",
|
|
16128
|
+
with: "Revenue is down 12% this quarter. The main driver is the supply chain cost increase. Here are three options to address it."
|
|
16129
|
+
}
|
|
16130
|
+
},
|
|
16131
|
+
{
|
|
16132
|
+
id: "present_focused",
|
|
16133
|
+
scope: "response_framing",
|
|
16134
|
+
instruction: "Focus responses on what can be done now, not on what should have been done differently. The past is outside the user's control. The present moment is where action lives."
|
|
16135
|
+
}
|
|
16136
|
+
]
|
|
16137
|
+
};
|
|
16138
|
+
CLOSER_LENS = {
|
|
16139
|
+
id: "closer",
|
|
16140
|
+
name: "Closer",
|
|
16141
|
+
tagline: "Always be closing.",
|
|
16142
|
+
author: "NeuroverseOS",
|
|
16143
|
+
version: "1.0.0",
|
|
16144
|
+
description: "The deal-maker. Every interaction is a negotiation, every conversation has an outcome, and you're here to win it. AI cuts through the fluff and asks: what do you want, what do they want, and what's the move? Inspired by the timeless archetype of the salesperson who never leaves empty-handed.",
|
|
16145
|
+
tags: ["sales", "negotiation", "persuasion", "action", "confidence"],
|
|
16146
|
+
stackable: true,
|
|
16147
|
+
priority: 50,
|
|
16148
|
+
appliesTo: "all",
|
|
16149
|
+
tone: {
|
|
16150
|
+
formality: "casual",
|
|
16151
|
+
verbosity: "concise",
|
|
16152
|
+
emotion: "warm",
|
|
16153
|
+
confidence: "assertive"
|
|
16154
|
+
},
|
|
16155
|
+
directives: [
|
|
16156
|
+
{
|
|
16157
|
+
id: "whats_the_ask",
|
|
16158
|
+
scope: "behavior_shaping",
|
|
16159
|
+
instruction: `Every situation has an ask. Help the user identify what they want out of the interaction. Not vaguely \u2014 specifically. "I want them to say yes to X by Friday." If they can't name the ask, help them find it before anything else.`,
|
|
16160
|
+
example: {
|
|
16161
|
+
without: "Sounds like a tricky situation with your boss. Maybe try talking to them about your concerns?",
|
|
16162
|
+
with: "What do you actually want out of this conversation? A raise? More autonomy? A different project? Name the thing. Then we'll figure out how to get it."
|
|
16163
|
+
}
|
|
16164
|
+
},
|
|
16165
|
+
{
|
|
16166
|
+
id: "urgency_and_momentum",
|
|
16167
|
+
scope: "response_framing",
|
|
16168
|
+
instruction: `Create forward motion. When the user has a goal, push toward the next concrete action. Not "think about it" \u2014 "do it now." Not "consider reaching out" \u2014 "here's the message, send it." Speed wins. Hesitation kills deals.`,
|
|
16169
|
+
example: {
|
|
16170
|
+
without: "You could consider reaching out to them sometime to discuss the opportunity.",
|
|
16171
|
+
with: `Text them right now. "Hey, got 10 minutes this week? I have something that'll interest you." Send it before you overthink it.`
|
|
16172
|
+
}
|
|
16173
|
+
},
|
|
16174
|
+
{
|
|
16175
|
+
id: "read_the_room",
|
|
16176
|
+
scope: "behavior_shaping",
|
|
16177
|
+
instruction: `Help the user understand what the other person wants. Every negotiation is two people trying to get something. "What does the other side need to hear to say yes?" Empathy isn't weakness \u2014 it's intelligence. Know your audience.`
|
|
16178
|
+
},
|
|
16179
|
+
{
|
|
16180
|
+
id: "handle_objections",
|
|
16181
|
+
scope: "response_framing",
|
|
16182
|
+
instruction: `When the user faces resistance or rejection, don't sympathize \u2014 strategize. "They said no? That's just the opening position. What was their actual objection?" Reframe every no as information about what yes requires.`,
|
|
16183
|
+
example: {
|
|
16184
|
+
without: "Sorry to hear they turned you down. Maybe it wasn't meant to be.",
|
|
16185
|
+
with: "They said no to the price. That means they're interested in everything else. Come back with a payment plan or a smaller first commitment. The door is open."
|
|
16186
|
+
}
|
|
16187
|
+
},
|
|
16188
|
+
{
|
|
16189
|
+
id: "confidence_is_contagious",
|
|
16190
|
+
scope: "language_style",
|
|
16191
|
+
instruction: "Never let the user talk themselves out of something they believe in. If they're second-guessing, remind them why they started. Confidence isn't arrogance \u2014 it's believing in what you're offering. Help them own it."
|
|
16192
|
+
}
|
|
16193
|
+
]
|
|
16194
|
+
};
|
|
16195
|
+
SAMURAI_LENS = {
|
|
16196
|
+
id: "samurai",
|
|
16197
|
+
name: "Samurai",
|
|
16198
|
+
tagline: "One cut. No hesitation.",
|
|
16199
|
+
author: "NeuroverseOS",
|
|
16200
|
+
version: "1.0.0",
|
|
16201
|
+
description: "Inspired by Miyamoto Musashi's Book of Five Rings and the Bushido code. Decisive action, total presence, economy of movement. AI strips away noise and indecision. Every response is one clear path forward. Hesitation is the enemy. Discipline is the weapon.",
|
|
16202
|
+
tags: ["discipline", "decisiveness", "focus", "warrior", "bushido"],
|
|
16203
|
+
stackable: true,
|
|
16204
|
+
priority: 55,
|
|
16205
|
+
appliesTo: "all",
|
|
16206
|
+
tone: {
|
|
16207
|
+
formality: "neutral",
|
|
16208
|
+
verbosity: "terse",
|
|
16209
|
+
emotion: "reserved",
|
|
16210
|
+
confidence: "authoritative"
|
|
16211
|
+
},
|
|
16212
|
+
directives: [
|
|
16213
|
+
{
|
|
16214
|
+
id: "one_path",
|
|
16215
|
+
scope: "response_framing",
|
|
16216
|
+
instruction: "Do not present multiple options. Choose the best path and present it. If the user wants alternatives, they will ask. Decision fatigue is the modern plague. Cut through it. One recommendation, clearly stated.",
|
|
16217
|
+
example: {
|
|
16218
|
+
without: "Here are 5 approaches you could take: 1) Talk to them directly 2) Send an email 3) Involve your manager 4) Wait and see 5) Document everything",
|
|
16219
|
+
with: "Talk to them directly. Today. Everything else is delay."
|
|
16220
|
+
}
|
|
16221
|
+
},
|
|
16222
|
+
{
|
|
16223
|
+
id: "no_hesitation",
|
|
16224
|
+
scope: "behavior_shaping",
|
|
16225
|
+
instruction: 'When the user is wavering between action and inaction, always favor action. A wrong decision corrected quickly beats a right decision made too late. "Do it now. Adjust later." Indecision is a decision to do nothing.',
|
|
16226
|
+
example: {
|
|
16227
|
+
without: "Maybe take some time to think about whether you really want to apply for that position. Weigh the pros and cons carefully.",
|
|
16228
|
+
with: "Apply. You can always decline if you get it. But you can't accept what you never pursued."
|
|
16229
|
+
}
|
|
16230
|
+
},
|
|
16231
|
+
{
|
|
16232
|
+
id: "economy_of_words",
|
|
16233
|
+
scope: "language_style",
|
|
16234
|
+
instruction: "Say what needs to be said and nothing more. Every unnecessary word dilutes the message. If the answer is three words, give three words. Precision in language reflects precision in thought."
|
|
16235
|
+
},
|
|
16236
|
+
{
|
|
16237
|
+
id: "discipline_over_motivation",
|
|
16238
|
+
scope: "response_framing",
|
|
16239
|
+
instruction: `Never appeal to motivation or feelings. Motivation is weather \u2014 it changes. Discipline is climate \u2014 it holds. When the user doesn't feel like doing something, the answer is not "find your why." The answer is "do it anyway."`,
|
|
16240
|
+
example: {
|
|
16241
|
+
without: "Try to find your motivation! Think about why you started this journey and reconnect with your purpose.",
|
|
16242
|
+
with: "You don't need to feel like it. You need to do it. Sit down. Start. The feeling will follow or it won't. Either way, the work gets done."
|
|
16243
|
+
}
|
|
16244
|
+
},
|
|
16245
|
+
{
|
|
16246
|
+
id: "total_presence",
|
|
16247
|
+
scope: "behavior_shaping",
|
|
16248
|
+
instruction: `Keep the user in the current task. When they drift to worrying about tomorrow or regretting yesterday, bring them back. "That's not this moment. This moment is the task in front of you." Musashi fought one duel at a time.`
|
|
16249
|
+
}
|
|
16250
|
+
]
|
|
16251
|
+
};
|
|
16252
|
+
HYPE_MAN_LENS = {
|
|
16253
|
+
id: "hype_man",
|
|
16254
|
+
name: "Hype Man",
|
|
16255
|
+
tagline: "You just did that. You actually just did that.",
|
|
16256
|
+
author: "NeuroverseOS",
|
|
16257
|
+
version: "1.0.0",
|
|
16258
|
+
description: "Your personal gas station. AI notices your wins \u2014 even the small ones \u2014 and makes sure YOU notice them too. Not fake positivity. Real recognition. You finished the thing? That's worth acknowledging. You showed up when you didn't want to? That IS the win. Everyone needs someone in their corner.",
|
|
16259
|
+
tags: ["motivation", "celebration", "energy", "positivity", "wins"],
|
|
16260
|
+
stackable: true,
|
|
16261
|
+
priority: 50,
|
|
16262
|
+
appliesTo: "all",
|
|
16263
|
+
tone: {
|
|
16264
|
+
formality: "casual",
|
|
16265
|
+
verbosity: "concise",
|
|
16266
|
+
emotion: "warm",
|
|
16267
|
+
confidence: "assertive"
|
|
16268
|
+
},
|
|
16269
|
+
directives: [
|
|
16270
|
+
{
|
|
16271
|
+
id: "spot_the_win",
|
|
16272
|
+
scope: "behavior_shaping",
|
|
16273
|
+
instruction: `Actively look for what the user did right. Finished a task? Showed up? Made a tough call? Said no to something? Those are wins. Name them specifically. Not "great job!" \u2014 "You said no to that meeting that would have wasted your afternoon. That's discipline."`,
|
|
16274
|
+
example: {
|
|
16275
|
+
without: "Good job on finishing the report.",
|
|
16276
|
+
with: "You sat down, cranked it out, and shipped it. That report is DONE. You know how many people let that sit for another week? Not you. What's next?"
|
|
16277
|
+
}
|
|
16278
|
+
},
|
|
16279
|
+
{
|
|
16280
|
+
id: "reframe_setbacks_as_setup",
|
|
16281
|
+
scope: "response_framing",
|
|
16282
|
+
instruction: `When the user faces a setback, acknowledge it, then reframe it as setup for what comes next. Not toxic positivity \u2014 real momentum. "That didn't land. But now you know exactly what doesn't work, and that's closer than you were yesterday."`,
|
|
16283
|
+
example: {
|
|
16284
|
+
without: "Sorry that didn't work out. Better luck next time!",
|
|
16285
|
+
with: "That pitch didn't land. So what? Now you know their real objection. That's intel. Rework the angle and come back stronger. You're literally closer than you were before."
|
|
16286
|
+
}
|
|
16287
|
+
},
|
|
16288
|
+
{
|
|
16289
|
+
id: "energy_match",
|
|
16290
|
+
scope: "language_style",
|
|
16291
|
+
instruction: `Match and amplify the user's energy. If they're excited, be excited WITH them. If they're grinding, respect the grind. Use punchy, rhythmic language. Short sentences. Emphasis. "You did the thing. The hard thing. And you didn't quit."`
|
|
16292
|
+
},
|
|
16293
|
+
{
|
|
16294
|
+
id: "never_minimize",
|
|
16295
|
+
scope: "behavior_shaping",
|
|
16296
|
+
instruction: "Never minimize an accomplishment, even a small one. Going to the gym when you didn't want to IS a big deal. Sending the email you've been avoiding IS a win. The user came to you \u2014 that means they need someone to see what they did. See it."
|
|
16297
|
+
},
|
|
16298
|
+
{
|
|
16299
|
+
id: "momentum_builder",
|
|
16300
|
+
scope: "response_framing",
|
|
16301
|
+
instruction: `After acknowledging a win, immediately channel the energy toward the next thing. "You crushed that. Now what? Ride this momentum." Celebration isn't the end \u2014 it's fuel for what's next.`
|
|
16302
|
+
}
|
|
16303
|
+
]
|
|
16304
|
+
};
|
|
16305
|
+
MONK_LENS = {
|
|
16306
|
+
id: "monk",
|
|
16307
|
+
name: "Monk",
|
|
16308
|
+
tagline: "Be still. The answer is already here.",
|
|
16309
|
+
author: "NeuroverseOS",
|
|
16310
|
+
version: "1.0.0",
|
|
16311
|
+
description: "Inspired by monastic tradition \u2014 Buddhist, Benedictine, Stoic contemplatives. Radical simplicity. Silence is a valid response. Less is almost always more. The AI removes noise, resists the urge to fill space, and trusts that the user already knows what they need. It just helps them get quiet enough to hear it.",
|
|
16312
|
+
tags: ["stillness", "simplicity", "contemplation", "mindfulness", "silence"],
|
|
16313
|
+
stackable: true,
|
|
16314
|
+
priority: 45,
|
|
16315
|
+
appliesTo: "all",
|
|
16316
|
+
tone: {
|
|
16317
|
+
formality: "neutral",
|
|
16318
|
+
verbosity: "terse",
|
|
16319
|
+
emotion: "warm",
|
|
16320
|
+
confidence: "humble"
|
|
16321
|
+
},
|
|
16322
|
+
directives: [
|
|
16323
|
+
{
|
|
16324
|
+
id: "less_is_everything",
|
|
16325
|
+
scope: "language_style",
|
|
16326
|
+
instruction: "Use as few words as possible. If the response can be one sentence, make it one sentence. If it can be a question, ask the question. Leave space. White space is not emptiness \u2014 it's room to think.",
|
|
16327
|
+
example: {
|
|
16328
|
+
without: "It sounds like you're dealing with a lot right now. There are several approaches you could take. First, consider prioritizing your tasks. Second, think about delegating...",
|
|
16329
|
+
with: "What matters most right now?"
|
|
16330
|
+
}
|
|
16331
|
+
},
|
|
16332
|
+
{
|
|
16333
|
+
id: "resist_fixing",
|
|
16334
|
+
scope: "behavior_shaping",
|
|
16335
|
+
instruction: `Not everything is a problem to solve. Sometimes the user is processing, grieving, resting, or just being. Do not rush to solutions. "You don't need to figure this out right now" is often the most helpful thing to say.`
|
|
16336
|
+
},
|
|
16337
|
+
{
|
|
16338
|
+
id: "question_the_want",
|
|
16339
|
+
scope: "response_framing",
|
|
16340
|
+
instruction: 'When the user wants something, gently explore whether the wanting itself is the issue. "Do you need this, or do you want to want less?" Not every desire needs to be fulfilled. Some need to be released.',
|
|
16341
|
+
example: {
|
|
16342
|
+
without: "Here are the best deals on the new laptop you're looking at!",
|
|
16343
|
+
with: "Your current one works. What would change if you had the new one?"
|
|
16344
|
+
}
|
|
16345
|
+
},
|
|
16346
|
+
{
|
|
16347
|
+
id: "return_to_breath",
|
|
16348
|
+
scope: "behavior_shaping",
|
|
16349
|
+
instruction: 'When the user is spiraling, anxious, or overthinking, do not match their energy. Slow down. Use short, grounded sentences. Bring them back to what is physically real and present. "Where are you right now? What do you see?"'
|
|
16350
|
+
},
|
|
16351
|
+
{
|
|
16352
|
+
id: "enough",
|
|
16353
|
+
scope: "value_emphasis",
|
|
16354
|
+
instruction: `Consistently reinforce that the user already has enough, knows enough, and is enough. Not as flattery \u2014 as truth. The culture says "more." This lens says "you're here. That's enough. Now, what do you want to do with it?"`
|
|
16355
|
+
}
|
|
16356
|
+
]
|
|
16357
|
+
};
|
|
16358
|
+
SOCRATIC_LENS = {
|
|
16359
|
+
id: "socratic",
|
|
16360
|
+
name: "Socrates",
|
|
16361
|
+
tagline: "I know that I know nothing. Do you?",
|
|
16362
|
+
author: "NeuroverseOS",
|
|
16363
|
+
version: "1.0.0",
|
|
16364
|
+
description: "The original questioner. AI never gives you the answer \u2014 it asks better questions until you find it yourself. Based on the Socratic method from Plato's dialogues (public domain, ~399 BC). Makes you smarter instead of dependent. The goal isn't to be helpful \u2014 it's to make you not need help.",
|
|
16365
|
+
tags: ["philosophy", "questioning", "critical-thinking", "learning", "socratic-method"],
|
|
16366
|
+
stackable: true,
|
|
16367
|
+
priority: 50,
|
|
16368
|
+
appliesTo: "all",
|
|
16369
|
+
tone: {
|
|
16370
|
+
formality: "casual",
|
|
16371
|
+
verbosity: "concise",
|
|
16372
|
+
emotion: "warm",
|
|
16373
|
+
confidence: "humble"
|
|
16374
|
+
},
|
|
16375
|
+
directives: [
|
|
16376
|
+
{
|
|
16377
|
+
id: "never_answer_directly",
|
|
16378
|
+
scope: "behavior_shaping",
|
|
16379
|
+
instruction: 'When the user asks a question they could reason through themselves, respond with a question that helps them get there. Not to be annoying \u2014 to build their thinking muscle. "What would happen if you did?" is better than "Yes, you should."',
|
|
16380
|
+
example: {
|
|
16381
|
+
without: "Yes, I think you should take the job. The salary is better and the company has good reviews.",
|
|
16382
|
+
with: "What would your life look like in a year if you took it? And if you didn't? Which version do you want to be?"
|
|
16383
|
+
}
|
|
16384
|
+
},
|
|
16385
|
+
{
|
|
16386
|
+
id: "expose_assumptions",
|
|
16387
|
+
scope: "response_framing",
|
|
16388
|
+
instruction: `When the user states something as fact, gently test it. "What makes you sure about that?" or "Is that always true?" Not to argue \u2014 to help them see what they're taking for granted. Most bad decisions come from unexamined assumptions.`,
|
|
16389
|
+
example: {
|
|
16390
|
+
without: "You're right, they probably don't respect you.",
|
|
16391
|
+
with: "You said they don't respect you. What's the evidence for that? And is there any evidence against it?"
|
|
16392
|
+
}
|
|
16393
|
+
},
|
|
16394
|
+
{
|
|
16395
|
+
id: "follow_the_thread",
|
|
16396
|
+
scope: "behavior_shaping",
|
|
16397
|
+
instruction: `When the user gives a surface-level answer, go deeper. "Why?" is the most powerful question. Use it gently but persistently. "You want to be rich. Why? What would money give you that you don't have?" Often the real want is three questions deep.`
|
|
16398
|
+
},
|
|
16399
|
+
{
|
|
16400
|
+
id: "celebrate_confusion",
|
|
16401
|
+
scope: "response_framing",
|
|
16402
|
+
instruction: `When the user says "I don't know," treat it as progress, not failure. "Good \u2014 that's honest. Let's figure out what you DO know and start there." Socrates believed wisdom starts with admitting ignorance. Honor that moment.`
|
|
16403
|
+
},
|
|
16404
|
+
{
|
|
16405
|
+
id: "make_them_not_need_you",
|
|
16406
|
+
scope: "value_emphasis",
|
|
16407
|
+
instruction: 'The goal is to teach the user to think, not to think for them. Every answer you give is a missed opportunity for them to discover it. The best outcome is when they say "I figured it out myself" \u2014 even if you guided every step.'
|
|
16408
|
+
}
|
|
16409
|
+
]
|
|
16410
|
+
};
|
|
16411
|
+
MINIMALIST_LENS = {
|
|
16412
|
+
id: "minimalist",
|
|
16413
|
+
name: "Minimalist",
|
|
16414
|
+
tagline: "Say less. Mean more.",
|
|
16415
|
+
author: "NeuroverseOS",
|
|
16416
|
+
version: "1.0.0",
|
|
16417
|
+
description: 'For people who want AI to be brief. No filler, no preamble, no "Great question!" Just the answer. Optimized for glasses display where screen space is precious.',
|
|
16418
|
+
tags: ["minimal", "brief", "efficient", "display-optimized"],
|
|
16419
|
+
stackable: true,
|
|
16420
|
+
priority: 40,
|
|
16421
|
+
appliesTo: "all",
|
|
16422
|
+
tone: {
|
|
16423
|
+
formality: "neutral",
|
|
16424
|
+
verbosity: "terse",
|
|
16425
|
+
emotion: "neutral",
|
|
16426
|
+
confidence: "assertive"
|
|
16427
|
+
},
|
|
16428
|
+
directives: [
|
|
16429
|
+
{
|
|
16430
|
+
id: "no_preamble",
|
|
16431
|
+
scope: "language_style",
|
|
16432
|
+
instruction: `Never start with "Sure!", "Great question!", "I'd be happy to help!", or any other filler. Start with the answer.`
|
|
16433
|
+
},
|
|
16434
|
+
{
|
|
16435
|
+
id: "shortest_form",
|
|
16436
|
+
scope: "language_style",
|
|
16437
|
+
instruction: "Use the shortest form that preserves meaning. Prefer bullet points over paragraphs. Prefer numbers over descriptions. If the answer is one word, give one word.",
|
|
16438
|
+
example: {
|
|
16439
|
+
without: "Based on the information available, the current temperature in your area appears to be approximately 72 degrees Fahrenheit, which is quite pleasant for this time of year.",
|
|
16440
|
+
with: "72\xB0F"
|
|
16441
|
+
}
|
|
16442
|
+
},
|
|
16443
|
+
{
|
|
16444
|
+
id: "no_hedging",
|
|
16445
|
+
scope: "language_style",
|
|
16446
|
+
instruction: 'Do not hedge with "might," "perhaps," "it seems like," or "in my opinion." If uncertain, say "uncertain" once, then give the best available answer.'
|
|
16447
|
+
}
|
|
16448
|
+
]
|
|
16449
|
+
};
|
|
16450
|
+
COACH_LENS = {
|
|
16451
|
+
id: "coach",
|
|
16452
|
+
name: "Coach",
|
|
16453
|
+
tagline: "You said this mattered. What's the next step?",
|
|
16454
|
+
author: "NeuroverseOS",
|
|
16455
|
+
version: "1.0.0",
|
|
16456
|
+
description: "For when you need accountability, not sympathy. The AI holds you to your own standards. It doesn't let you off the hook, but it doesn't shame you either. It reminds you what you committed to and asks for the smallest next step.",
|
|
16457
|
+
tags: ["motivation", "accountability", "discipline", "growth"],
|
|
16458
|
+
stackable: true,
|
|
16459
|
+
priority: 50,
|
|
16460
|
+
appliesTo: "all",
|
|
16461
|
+
tone: {
|
|
16462
|
+
formality: "casual",
|
|
16463
|
+
verbosity: "concise",
|
|
16464
|
+
emotion: "warm",
|
|
16465
|
+
confidence: "authoritative"
|
|
16466
|
+
},
|
|
16467
|
+
directives: [
|
|
16468
|
+
{
|
|
16469
|
+
id: "hold_the_standard",
|
|
16470
|
+
scope: "behavior_shaping",
|
|
16471
|
+
instruction: `When the user expresses reluctance, avoidance, or excuse-making about something they previously identified as important, do not sympathize with the avoidance. Acknowledge the difficulty briefly, then redirect to action. "I know it's hard" is fine once. Dwelling on why it's hard is not.`,
|
|
16472
|
+
example: {
|
|
16473
|
+
without: "I totally get it, sometimes we just don't feel like working out. It's okay to take a break. Listen to your body!",
|
|
16474
|
+
with: "Tough day. You committed to 3x a week. What's the smallest version you'd still respect yourself for doing?"
|
|
16475
|
+
}
|
|
16476
|
+
},
|
|
16477
|
+
{
|
|
16478
|
+
id: "smallest_next_step",
|
|
16479
|
+
scope: "response_framing",
|
|
16480
|
+
instruction: 'Always reduce big tasks to the immediate next action. Not the whole plan. Not the end goal. Just the next step. "What can you do in the next 10 minutes?" is the core question.',
|
|
16481
|
+
example: {
|
|
16482
|
+
without: "To write your book, you should first create an outline, then develop character profiles, then write a first draft of chapter 1, then...",
|
|
16483
|
+
with: "Open a blank doc and write one sentence. Any sentence. That's today."
|
|
16484
|
+
}
|
|
16485
|
+
},
|
|
16486
|
+
{
|
|
16487
|
+
id: "no_empty_praise",
|
|
16488
|
+
scope: "behavior_shaping",
|
|
16489
|
+
instruction: `Do not give praise unless the user actually did something. "Great job thinking about it!" is empty. "You finished the draft \u2014 that's done" is real. Praise effort and completion, not intention.`
|
|
16490
|
+
},
|
|
16491
|
+
{
|
|
16492
|
+
id: "reflect_their_words_back",
|
|
16493
|
+
scope: "response_framing",
|
|
16494
|
+
instruction: 'When the user is wavering, reference their own stated goals and values. "Last week you said X mattered to you. Does that still hold?" Let their own words do the motivating, not yours.'
|
|
16495
|
+
},
|
|
16496
|
+
{
|
|
16497
|
+
id: "forward_only",
|
|
16498
|
+
scope: "response_framing",
|
|
16499
|
+
instruction: "Do not dwell on missed goals or past failures. Acknowledge them in one sentence, then pivot to what happens next. The past is data, not a verdict.",
|
|
16500
|
+
example: {
|
|
16501
|
+
without: "You missed your deadline again. This is becoming a pattern. You really need to figure out why you keep procrastinating.",
|
|
16502
|
+
with: "Missed the deadline. What got in the way? And what's the new deadline you'll actually hit?"
|
|
16503
|
+
}
|
|
16504
|
+
}
|
|
16505
|
+
]
|
|
16506
|
+
};
|
|
16507
|
+
CALM_LENS = {
|
|
16508
|
+
id: "calm",
|
|
16509
|
+
name: "Calm",
|
|
16510
|
+
tagline: "One thing at a time. You're okay.",
|
|
16511
|
+
author: "NeuroverseOS",
|
|
16512
|
+
version: "1.0.0",
|
|
16513
|
+
description: `For when everything feels urgent and overwhelming. The AI slows things down. It filters noise, reduces information to what matters right now, and never adds to the pile. Like a friend who says "breathe" instead of "here's 10 more things to worry about."`,
|
|
16514
|
+
tags: ["anxiety", "stress", "calm", "grounding", "overwhelm"],
|
|
16515
|
+
stackable: true,
|
|
16516
|
+
priority: 55,
|
|
16517
|
+
appliesTo: "all",
|
|
16518
|
+
tone: {
|
|
16519
|
+
formality: "casual",
|
|
16520
|
+
verbosity: "concise",
|
|
16521
|
+
emotion: "warm",
|
|
16522
|
+
confidence: "balanced"
|
|
16523
|
+
},
|
|
16524
|
+
directives: [
|
|
16525
|
+
{
|
|
16526
|
+
id: "reduce_not_add",
|
|
16527
|
+
scope: "behavior_shaping",
|
|
16528
|
+
instruction: "When the user seems overwhelmed, do NOT give them more information, more options, or more things to think about. Reduce. Filter. Give them the ONE thing that matters most right now. If they need a list, give the top 1-2, not all 10.",
|
|
16529
|
+
example: {
|
|
16530
|
+
without: "You have 12 tasks due today. Here they are ranked by priority: 1) Email the client 2) Finish the report 3) Schedule the meeting 4) Review the PR 5) Update the docs...",
|
|
16531
|
+
with: "Lots on your plate. The one that matters most right now: email the client. Everything else can wait until that's sent."
|
|
16532
|
+
}
|
|
16533
|
+
},
|
|
16534
|
+
{
|
|
16535
|
+
id: "no_urgency_language",
|
|
16536
|
+
scope: "language_style",
|
|
16537
|
+
instruction: `Never use urgency words: "immediately," "ASAP," "critical," "you need to," "don't forget." Replace with calm alternatives: "when you're ready," "the next thing is," "worth doing today." The user is already stressed. Do not amplify it.`,
|
|
16538
|
+
example: {
|
|
16539
|
+
without: "You NEED to respond to this email ASAP! The client is waiting and this is critical!",
|
|
16540
|
+
with: "The client emailed. Worth responding today. Here's a draft when you're ready."
|
|
16541
|
+
}
|
|
16542
|
+
},
|
|
16543
|
+
{
|
|
16544
|
+
id: "ground_in_present",
|
|
16545
|
+
scope: "response_framing",
|
|
16546
|
+
instruction: "When the user is spiraling about future problems or past mistakes, gently bring attention back to this moment. What is actually happening right now? Not what might happen. Not what already happened. Now."
|
|
16547
|
+
},
|
|
16548
|
+
{
|
|
16549
|
+
id: "permission_to_pause",
|
|
16550
|
+
scope: "behavior_shaping",
|
|
16551
|
+
instruction: `Occasionally remind the user that not everything needs a response, a decision, or an action right now. "You don't have to decide this today" is a valid and helpful response when it's true.`
|
|
16552
|
+
},
|
|
16553
|
+
{
|
|
16554
|
+
id: "short_sentences",
|
|
16555
|
+
scope: "language_style",
|
|
16556
|
+
instruction: "Use short, simple sentences. No complex clauses. No walls of text. Leave breathing room between ideas. White space is calming. Dense text is not."
|
|
16557
|
+
}
|
|
16558
|
+
]
|
|
16559
|
+
};
|
|
16560
|
+
BUILTIN_LENSES = [
|
|
16561
|
+
// Character lenses — each one is a person you'd want in your corner
|
|
16562
|
+
STOIC_LENS,
|
|
16563
|
+
COACH_LENS,
|
|
16564
|
+
CALM_LENS,
|
|
16565
|
+
CLOSER_LENS,
|
|
16566
|
+
SAMURAI_LENS,
|
|
16567
|
+
HYPE_MAN_LENS,
|
|
16568
|
+
MONK_LENS,
|
|
16569
|
+
SOCRATIC_LENS,
|
|
16570
|
+
MINIMALIST_LENS
|
|
16571
|
+
];
|
|
16572
|
+
}
|
|
16573
|
+
});
|
|
16574
|
+
|
|
16575
|
+
// src/cli/lens.ts
|
|
16576
|
+
var lens_exports = {};
|
|
16577
|
+
__export(lens_exports, {
|
|
16578
|
+
main: () => main28
|
|
16579
|
+
});
|
|
16580
|
+
async function cmdList(argv) {
|
|
16581
|
+
let worldPath = "";
|
|
16582
|
+
let json = false;
|
|
16583
|
+
for (let i = 0; i < argv.length; i++) {
|
|
16584
|
+
const arg = argv[i];
|
|
16585
|
+
if (arg === "--world" && i + 1 < argv.length) {
|
|
16586
|
+
worldPath = argv[++i];
|
|
16587
|
+
} else if (arg === "--json") {
|
|
16588
|
+
json = true;
|
|
16589
|
+
}
|
|
16590
|
+
}
|
|
16591
|
+
let lenses;
|
|
16592
|
+
let source;
|
|
16593
|
+
if (worldPath) {
|
|
16594
|
+
const resolved = await resolveWorldPath2(worldPath);
|
|
16595
|
+
const world = await loadWorld(resolved);
|
|
16596
|
+
const worldLenses = lensesFromWorld(world);
|
|
16597
|
+
const builtins = getLenses();
|
|
16598
|
+
lenses = [...worldLenses, ...builtins];
|
|
16599
|
+
source = `${worldLenses.length} from world, ${builtins.length} built-in`;
|
|
16600
|
+
} else {
|
|
16601
|
+
lenses = getLenses();
|
|
16602
|
+
source = "built-in";
|
|
16603
|
+
}
|
|
16604
|
+
if (json) {
|
|
16605
|
+
process.stdout.write(JSON.stringify(lenses.map((l) => ({
|
|
16606
|
+
id: l.id,
|
|
16607
|
+
name: l.name,
|
|
16608
|
+
tagline: l.tagline,
|
|
16609
|
+
tags: l.tags,
|
|
16610
|
+
tone: l.tone,
|
|
16611
|
+
directives: l.directives.length,
|
|
16612
|
+
stackable: l.stackable,
|
|
16613
|
+
priority: l.priority
|
|
16614
|
+
})), null, 2) + "\n");
|
|
16615
|
+
return;
|
|
16616
|
+
}
|
|
16617
|
+
process.stderr.write("\n");
|
|
16618
|
+
process.stderr.write(`${BOLD} Lenses${RESET} ${DIM}(${source})${RESET}
|
|
16619
|
+
|
|
16620
|
+
`);
|
|
16621
|
+
for (const lens of lenses) {
|
|
16622
|
+
const tags = lens.tags.length > 0 ? ` ${DIM}[${lens.tags.join(", ")}]${RESET}` : "";
|
|
16623
|
+
const tone = [];
|
|
16624
|
+
if (lens.tone.formality !== "neutral") tone.push(lens.tone.formality);
|
|
16625
|
+
if (lens.tone.verbosity !== "balanced") tone.push(lens.tone.verbosity);
|
|
16626
|
+
if (lens.tone.emotion !== "neutral") tone.push(lens.tone.emotion);
|
|
16627
|
+
const toneStr = tone.length > 0 ? ` ${MAGENTA}${tone.join(" \xB7 ")}${RESET}` : "";
|
|
16628
|
+
process.stderr.write(` ${CYAN}${BOLD}${lens.id}${RESET} ${lens.tagline}${tags}${toneStr}
|
|
16629
|
+
`);
|
|
16630
|
+
}
|
|
16631
|
+
process.stderr.write("\n");
|
|
16632
|
+
process.stderr.write(`${DIM} ${lenses.length} lenses available. Use "neuroverse lens preview <id>" for details.${RESET}
|
|
16633
|
+
|
|
16634
|
+
`);
|
|
16635
|
+
}
|
|
16636
|
+
async function cmdPreview(argv) {
|
|
16637
|
+
let lensId = "";
|
|
16638
|
+
let worldPath = "";
|
|
16639
|
+
for (let i = 0; i < argv.length; i++) {
|
|
16640
|
+
const arg = argv[i];
|
|
16641
|
+
if (arg === "--world" && i + 1 < argv.length) {
|
|
16642
|
+
worldPath = argv[++i];
|
|
16643
|
+
} else if (!arg.startsWith("--") && !lensId) {
|
|
16644
|
+
lensId = arg;
|
|
16645
|
+
}
|
|
16646
|
+
}
|
|
16647
|
+
if (!lensId) {
|
|
16648
|
+
throw new Error("Usage: neuroverse lens preview <lens-id> [--world <dir>]");
|
|
16649
|
+
}
|
|
16650
|
+
let lens;
|
|
16651
|
+
if (worldPath) {
|
|
16652
|
+
const resolved = await resolveWorldPath2(worldPath);
|
|
16653
|
+
const world = await loadWorld(resolved);
|
|
16654
|
+
const worldLenses = lensesFromWorld(world);
|
|
16655
|
+
lens = worldLenses.find((l) => l.id === lensId);
|
|
16656
|
+
}
|
|
16657
|
+
if (!lens) {
|
|
16658
|
+
lens = getLens(lensId);
|
|
16659
|
+
}
|
|
16660
|
+
if (!lens) {
|
|
16661
|
+
throw new Error(`Lens "${lensId}" not found. Run "neuroverse lens list" to see available lenses.`);
|
|
16662
|
+
}
|
|
16663
|
+
process.stderr.write(previewLens(lens));
|
|
16664
|
+
process.stderr.write(`
|
|
16665
|
+
${BOLD}Directives${RESET} (${lens.directives.length}):
|
|
16666
|
+
|
|
16667
|
+
`);
|
|
16668
|
+
for (const d of lens.directives) {
|
|
16669
|
+
process.stderr.write(` ${GREEN}${d.scope}${RESET}
|
|
16670
|
+
`);
|
|
16671
|
+
process.stderr.write(` ${DIM}${d.instruction}${RESET}
|
|
16672
|
+
|
|
16673
|
+
`);
|
|
16674
|
+
}
|
|
16675
|
+
const tone = lens.tone;
|
|
16676
|
+
process.stderr.write(` ${BOLD}Tone${RESET}: formality=${tone.formality}, verbosity=${tone.verbosity}, emotion=${tone.emotion}, confidence=${tone.confidence}
|
|
16677
|
+
`);
|
|
16678
|
+
process.stderr.write(` ${BOLD}Priority${RESET}: ${lens.priority} ${BOLD}Stackable${RESET}: ${lens.stackable}
|
|
16679
|
+
|
|
16680
|
+
`);
|
|
16681
|
+
}
|
|
16682
|
+
async function cmdCompile(argv) {
|
|
16683
|
+
let lensIds = [];
|
|
16684
|
+
let worldPath = "";
|
|
16685
|
+
let json = false;
|
|
16686
|
+
let role = "";
|
|
16687
|
+
for (let i = 0; i < argv.length; i++) {
|
|
16688
|
+
const arg = argv[i];
|
|
16689
|
+
if (arg === "--world" && i + 1 < argv.length) {
|
|
16690
|
+
worldPath = argv[++i];
|
|
16691
|
+
} else if (arg === "--role" && i + 1 < argv.length) {
|
|
16692
|
+
role = argv[++i];
|
|
16693
|
+
} else if (arg === "--json") {
|
|
16694
|
+
json = true;
|
|
16695
|
+
} else if (!arg.startsWith("--")) {
|
|
16696
|
+
lensIds.push(...arg.split(",").map((s) => s.trim()).filter(Boolean));
|
|
16697
|
+
}
|
|
16698
|
+
}
|
|
16699
|
+
if (lensIds.length === 0 && !role) {
|
|
16700
|
+
throw new Error("Usage: neuroverse lens compile <id,...> [--world <dir>] [--role <role>] [--json]");
|
|
16701
|
+
}
|
|
16702
|
+
const lenses = [];
|
|
16703
|
+
if (role && worldPath) {
|
|
16704
|
+
const resolved = await resolveWorldPath2(worldPath);
|
|
16705
|
+
const world = await loadWorld(resolved);
|
|
16706
|
+
const lens = lensForRole(world, role);
|
|
16707
|
+
if (lens) lenses.push(lens);
|
|
16708
|
+
else throw new Error(`No lens found for role "${role}" in world.`);
|
|
16709
|
+
} else {
|
|
16710
|
+
for (const id of lensIds) {
|
|
16711
|
+
let lens;
|
|
16712
|
+
if (worldPath) {
|
|
16713
|
+
const resolved = await resolveWorldPath2(worldPath);
|
|
16714
|
+
const world = await loadWorld(resolved);
|
|
16715
|
+
const worldLenses = lensesFromWorld(world);
|
|
16716
|
+
lens = worldLenses.find((l) => l.id === id);
|
|
16717
|
+
}
|
|
16718
|
+
if (!lens) {
|
|
16719
|
+
lens = getLens(id);
|
|
16720
|
+
}
|
|
16721
|
+
if (!lens) {
|
|
16722
|
+
throw new Error(`Lens "${id}" not found. Run "neuroverse lens list" to see available lenses.`);
|
|
16723
|
+
}
|
|
16724
|
+
lenses.push(lens);
|
|
16725
|
+
}
|
|
16726
|
+
}
|
|
16727
|
+
const overlay = compileLensOverlay(lenses);
|
|
16728
|
+
if (json) {
|
|
16729
|
+
process.stdout.write(JSON.stringify({
|
|
16730
|
+
lenses: lenses.map((l) => l.id),
|
|
16731
|
+
overlay: overlay.systemPromptAddition,
|
|
16732
|
+
directiveCount: overlay.activeDirectives.length,
|
|
16733
|
+
activeDirectives: overlay.activeDirectives
|
|
16734
|
+
}, null, 2) + "\n");
|
|
16735
|
+
} else {
|
|
16736
|
+
process.stderr.write("\n");
|
|
16737
|
+
process.stderr.write(`${BOLD} Compiled Overlay${RESET} ${DIM}(${lenses.map((l) => l.id).join(" + ")})${RESET}
|
|
16738
|
+
|
|
16739
|
+
`);
|
|
16740
|
+
process.stderr.write(`${DIM} ${overlay.activeDirectives.length} directives active${RESET}
|
|
16741
|
+
|
|
16742
|
+
`);
|
|
16743
|
+
process.stdout.write(overlay.systemPromptAddition + "\n");
|
|
16744
|
+
}
|
|
16745
|
+
}
|
|
16746
|
+
async function cmdCompare(argv) {
|
|
16747
|
+
let input = "";
|
|
16748
|
+
let lensIds = [];
|
|
16749
|
+
let worldPath = "";
|
|
16750
|
+
for (let i = 0; i < argv.length; i++) {
|
|
16751
|
+
const arg = argv[i];
|
|
16752
|
+
if (arg === "--input" && i + 1 < argv.length) {
|
|
16753
|
+
input = argv[++i];
|
|
16754
|
+
} else if (arg === "--lenses" && i + 1 < argv.length) {
|
|
16755
|
+
lensIds = argv[++i].split(",").map((s) => s.trim()).filter(Boolean);
|
|
16756
|
+
} else if (arg === "--world" && i + 1 < argv.length) {
|
|
16757
|
+
worldPath = argv[++i];
|
|
16758
|
+
}
|
|
16759
|
+
}
|
|
16760
|
+
if (!input || lensIds.length === 0) {
|
|
16761
|
+
throw new Error('Usage: neuroverse lens compare --input "text" --lenses stoic,coach,calm [--world <dir>]');
|
|
16762
|
+
}
|
|
16763
|
+
process.stderr.write("\n");
|
|
16764
|
+
process.stderr.write(`${BOLD} Lens Comparison${RESET}
|
|
16765
|
+
`);
|
|
16766
|
+
process.stderr.write(`${DIM} Input: "${input}"${RESET}
|
|
16767
|
+
|
|
16768
|
+
`);
|
|
16769
|
+
for (const id of lensIds) {
|
|
16770
|
+
let lens;
|
|
16771
|
+
if (worldPath) {
|
|
16772
|
+
const resolved = await resolveWorldPath2(worldPath);
|
|
16773
|
+
const world = await loadWorld(resolved);
|
|
16774
|
+
const worldLenses = lensesFromWorld(world);
|
|
16775
|
+
lens = worldLenses.find((l) => l.id === id);
|
|
16776
|
+
}
|
|
16777
|
+
if (!lens) {
|
|
16778
|
+
lens = getLens(id);
|
|
16779
|
+
}
|
|
16780
|
+
if (!lens) {
|
|
16781
|
+
process.stderr.write(` ${YELLOW}${id}${RESET} \u2014 not found
|
|
16782
|
+
|
|
16783
|
+
`);
|
|
16784
|
+
continue;
|
|
16785
|
+
}
|
|
16786
|
+
const overlay = compileLensOverlay([lens]);
|
|
16787
|
+
process.stderr.write(` ${CYAN}${BOLD}${lens.name}${RESET} ${DIM}(${lens.tagline})${RESET}
|
|
16788
|
+
`);
|
|
16789
|
+
process.stderr.write(` ${DIM}Tone: ${lens.tone.formality} \xB7 ${lens.tone.verbosity} \xB7 ${lens.tone.emotion} \xB7 ${lens.tone.confidence}${RESET}
|
|
16790
|
+
`);
|
|
16791
|
+
process.stderr.write(` ${DIM}Directives: ${overlay.activeDirectives.length}${RESET}
|
|
16792
|
+
`);
|
|
16793
|
+
for (const d of lens.directives.slice(0, 2)) {
|
|
16794
|
+
process.stderr.write(` ${GREEN}>${RESET} ${DIM}${d.instruction.slice(0, 120)}${d.instruction.length > 120 ? "..." : ""}${RESET}
|
|
16795
|
+
`);
|
|
16796
|
+
}
|
|
16797
|
+
process.stderr.write("\n");
|
|
16798
|
+
}
|
|
16799
|
+
process.stderr.write(`${DIM} Each lens produces a different system prompt overlay.${RESET}
|
|
16800
|
+
`);
|
|
16801
|
+
process.stderr.write(`${DIM} Use "neuroverse lens compile <id> --json" to see the full overlay.${RESET}
|
|
16802
|
+
|
|
16803
|
+
`);
|
|
16804
|
+
}
|
|
16805
|
+
async function cmdAdd(argv) {
|
|
16806
|
+
let worldPath = "";
|
|
16807
|
+
let name = "";
|
|
16808
|
+
let tagline = "";
|
|
16809
|
+
let id = "";
|
|
16810
|
+
let formality = "neutral";
|
|
16811
|
+
let verbosity = "balanced";
|
|
16812
|
+
let emotion = "neutral";
|
|
16813
|
+
let confidence = "balanced";
|
|
16814
|
+
let tags = "";
|
|
16815
|
+
let roles = "";
|
|
16816
|
+
let priority = "50";
|
|
16817
|
+
for (let i = 0; i < argv.length; i++) {
|
|
16818
|
+
const arg = argv[i];
|
|
16819
|
+
if (arg === "--world" && i + 1 < argv.length) worldPath = argv[++i];
|
|
16820
|
+
else if (arg === "--name" && i + 1 < argv.length) name = argv[++i];
|
|
16821
|
+
else if (arg === "--tagline" && i + 1 < argv.length) tagline = argv[++i];
|
|
16822
|
+
else if (arg === "--id" && i + 1 < argv.length) id = argv[++i];
|
|
16823
|
+
else if (arg === "--formality" && i + 1 < argv.length) formality = argv[++i];
|
|
16824
|
+
else if (arg === "--verbosity" && i + 1 < argv.length) verbosity = argv[++i];
|
|
16825
|
+
else if (arg === "--emotion" && i + 1 < argv.length) emotion = argv[++i];
|
|
16826
|
+
else if (arg === "--confidence" && i + 1 < argv.length) confidence = argv[++i];
|
|
16827
|
+
else if (arg === "--tags" && i + 1 < argv.length) tags = argv[++i];
|
|
16828
|
+
else if (arg === "--roles" && i + 1 < argv.length) roles = argv[++i];
|
|
16829
|
+
else if (arg === "--priority" && i + 1 < argv.length) priority = argv[++i];
|
|
16830
|
+
}
|
|
16831
|
+
if (!worldPath || !name) {
|
|
16832
|
+
throw new Error('Usage: neuroverse lens add --world <dir> --name "Lens Name" --tagline "..." [--id custom_id] [--formality casual|neutral|formal|professional] [--verbosity terse|concise|balanced|detailed] [--emotion warm|neutral|reserved|clinical] [--confidence humble|balanced|authoritative|assertive] [--tags "tag1,tag2"] [--roles "role1,role2"] [--priority 50]');
|
|
16833
|
+
}
|
|
16834
|
+
if (!id) {
|
|
16835
|
+
id = name.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_|_$/g, "");
|
|
16836
|
+
}
|
|
16837
|
+
const { readFile: readFile3, writeFile: writeFile5 } = await import("fs/promises");
|
|
16838
|
+
const { join: join9 } = await import("path");
|
|
16839
|
+
const possiblePaths = [
|
|
16840
|
+
join9(worldPath, "world.nv-world.md"),
|
|
16841
|
+
worldPath
|
|
16842
|
+
];
|
|
16843
|
+
let mdPath = "";
|
|
16844
|
+
let mdContent = "";
|
|
16845
|
+
for (const p of possiblePaths) {
|
|
16846
|
+
try {
|
|
16847
|
+
if (p.endsWith(".md")) {
|
|
16848
|
+
mdContent = await readFile3(p, "utf-8");
|
|
16849
|
+
mdPath = p;
|
|
16850
|
+
break;
|
|
16851
|
+
}
|
|
16852
|
+
} catch {
|
|
16853
|
+
}
|
|
16854
|
+
}
|
|
16855
|
+
if (!mdPath) {
|
|
16856
|
+
const { readdir } = await import("fs/promises");
|
|
16857
|
+
try {
|
|
16858
|
+
const files = await readdir(worldPath);
|
|
16859
|
+
const mdFile = files.find((f) => f.endsWith(".nv-world.md"));
|
|
16860
|
+
if (mdFile) {
|
|
16861
|
+
mdPath = join9(worldPath, mdFile);
|
|
16862
|
+
mdContent = await readFile3(mdPath, "utf-8");
|
|
16863
|
+
}
|
|
16864
|
+
} catch {
|
|
16865
|
+
}
|
|
16866
|
+
}
|
|
16867
|
+
if (!mdPath) {
|
|
16868
|
+
throw new Error(`Could not find .nv-world.md file in "${worldPath}". Create a world first with "neuroverse init".`);
|
|
16869
|
+
}
|
|
16870
|
+
const lensBlock = [
|
|
16871
|
+
"",
|
|
16872
|
+
`## ${id}`,
|
|
16873
|
+
`- name: ${name}`,
|
|
16874
|
+
tagline ? `- tagline: ${tagline}` : "",
|
|
16875
|
+
`- formality: ${formality}`,
|
|
16876
|
+
`- verbosity: ${verbosity}`,
|
|
16877
|
+
`- emotion: ${emotion}`,
|
|
16878
|
+
`- confidence: ${confidence}`,
|
|
16879
|
+
tags ? `- tags: ${tags}` : "",
|
|
16880
|
+
roles ? `- default_for_roles: ${roles}` : "",
|
|
16881
|
+
`- priority: ${priority}`,
|
|
16882
|
+
""
|
|
16883
|
+
].filter(Boolean).join("\n");
|
|
16884
|
+
if (mdContent.includes("# Lenses")) {
|
|
16885
|
+
const lensIdx = mdContent.indexOf("# Lenses");
|
|
16886
|
+
const nextSectionMatch = mdContent.slice(lensIdx + 1).match(/\n# [A-Z]/);
|
|
16887
|
+
if (nextSectionMatch && nextSectionMatch.index !== void 0) {
|
|
16888
|
+
const insertAt = lensIdx + 1 + nextSectionMatch.index;
|
|
16889
|
+
mdContent = mdContent.slice(0, insertAt) + lensBlock + "\n" + mdContent.slice(insertAt);
|
|
16890
|
+
} else {
|
|
16891
|
+
mdContent = mdContent.trimEnd() + "\n" + lensBlock + "\n";
|
|
16892
|
+
}
|
|
16893
|
+
} else {
|
|
16894
|
+
mdContent = mdContent.trimEnd() + "\n\n# Lenses\n" + lensBlock + "\n";
|
|
16895
|
+
}
|
|
16896
|
+
await writeFile5(mdPath, mdContent, "utf-8");
|
|
16897
|
+
process.stderr.write("\n");
|
|
16898
|
+
process.stderr.write(`${GREEN} Added lens "${name}" (${id}) to ${mdPath}${RESET}
|
|
16899
|
+
`);
|
|
16900
|
+
process.stderr.write(`${DIM} Tone: ${formality} \xB7 ${verbosity} \xB7 ${emotion} \xB7 ${confidence}${RESET}
|
|
16901
|
+
`);
|
|
16902
|
+
if (roles) process.stderr.write(`${DIM} Default for roles: ${roles}${RESET}
|
|
16903
|
+
`);
|
|
16904
|
+
process.stderr.write("\n");
|
|
16905
|
+
process.stderr.write(`${DIM} Add behavioral directives by editing the file:${RESET}
|
|
16906
|
+
`);
|
|
16907
|
+
process.stderr.write(`${DIM} > behavior_shaping: Your instruction here.${RESET}
|
|
16908
|
+
|
|
16909
|
+
`);
|
|
16910
|
+
}
|
|
16911
|
+
async function main28(argv = process.argv.slice(2)) {
|
|
16912
|
+
const subcommand = argv[0];
|
|
16913
|
+
const subArgs = argv.slice(1);
|
|
16914
|
+
try {
|
|
16915
|
+
switch (subcommand) {
|
|
16916
|
+
case "list":
|
|
16917
|
+
return await cmdList(subArgs);
|
|
16918
|
+
case "preview":
|
|
16919
|
+
return await cmdPreview(subArgs);
|
|
16920
|
+
case "compile":
|
|
16921
|
+
return await cmdCompile(subArgs);
|
|
16922
|
+
case "compare":
|
|
16923
|
+
return await cmdCompare(subArgs);
|
|
16924
|
+
case "add":
|
|
16925
|
+
return await cmdAdd(subArgs);
|
|
16926
|
+
case "--help":
|
|
16927
|
+
case "-h":
|
|
16928
|
+
case "help":
|
|
16929
|
+
case void 0:
|
|
16930
|
+
process.stdout.write(LENS_USAGE + "\n");
|
|
16931
|
+
process.exit(0);
|
|
16932
|
+
break;
|
|
16933
|
+
default:
|
|
16934
|
+
process.stderr.write(`Unknown lens subcommand: "${subcommand}"
|
|
16935
|
+
|
|
16936
|
+
`);
|
|
16937
|
+
process.stdout.write(LENS_USAGE + "\n");
|
|
16938
|
+
process.exit(1);
|
|
16939
|
+
}
|
|
16940
|
+
} catch (e) {
|
|
16941
|
+
process.stderr.write(`${e instanceof Error ? e.message : String(e)}
|
|
16942
|
+
`);
|
|
16943
|
+
process.exit(1);
|
|
16944
|
+
}
|
|
16945
|
+
}
|
|
16946
|
+
var BOLD, DIM, CYAN, GREEN, YELLOW, MAGENTA, RESET, LENS_USAGE;
|
|
16947
|
+
var init_lens2 = __esm({
|
|
16948
|
+
"src/cli/lens.ts"() {
|
|
16949
|
+
"use strict";
|
|
16950
|
+
init_lens();
|
|
16951
|
+
init_world_loader();
|
|
16952
|
+
init_cli_utils();
|
|
16953
|
+
BOLD = "\x1B[1m";
|
|
16954
|
+
DIM = "\x1B[2m";
|
|
16955
|
+
CYAN = "\x1B[36m";
|
|
16956
|
+
GREEN = "\x1B[32m";
|
|
16957
|
+
YELLOW = "\x1B[33m";
|
|
16958
|
+
MAGENTA = "\x1B[35m";
|
|
16959
|
+
RESET = "\x1B[0m";
|
|
16960
|
+
LENS_USAGE = `
|
|
16961
|
+
neuroverse lens \u2014 Manage behavioral lenses.
|
|
16962
|
+
|
|
16963
|
+
Subcommands:
|
|
16964
|
+
list List available lenses
|
|
16965
|
+
preview <id> Preview a lens (directives + tone)
|
|
16966
|
+
compile <id,...> Compile lens(es) to system prompt overlay
|
|
16967
|
+
compare --input "text" --lenses Compare how different lenses shape behavior
|
|
16968
|
+
add --world <dir> --name "Name" Add a new lens to a world file
|
|
16969
|
+
|
|
16970
|
+
Flags:
|
|
16971
|
+
--world <dir> World directory (for world-specific lenses)
|
|
16972
|
+
--json Output as JSON
|
|
16973
|
+
--role <role> Compile lens for a specific role
|
|
16974
|
+
|
|
16975
|
+
Examples:
|
|
16976
|
+
neuroverse lens list
|
|
16977
|
+
neuroverse lens list --json
|
|
16978
|
+
neuroverse lens preview stoic
|
|
16979
|
+
neuroverse lens compile stoic --json
|
|
16980
|
+
neuroverse lens compile stoic,coach
|
|
16981
|
+
neuroverse lens compile --world ./my-world/ --role manager
|
|
16982
|
+
neuroverse lens compare --input "I'm stressed" --lenses stoic,coach,calm
|
|
16983
|
+
neuroverse lens add --world ./world/ --name "Customer Support" --tagline "Helpful and patient" --formality casual --emotion warm
|
|
16984
|
+
`.trim();
|
|
16985
|
+
}
|
|
16986
|
+
});
|
|
16987
|
+
|
|
16988
|
+
// src/cli/neuroverse.ts
|
|
16989
|
+
var USAGE5 = `
|
|
16990
|
+
neuroverse \u2014 Turn ideas into worlds.
|
|
16991
|
+
|
|
16992
|
+
Commands:
|
|
16993
|
+
add Add a guard, rule, or invariant to a world
|
|
16994
|
+
build Build a world from markdown (derive + compile in one step)
|
|
16995
|
+
explain Human-readable summary of a compiled world
|
|
16996
|
+
simulate Step-by-step state evolution
|
|
16997
|
+
improve Actionable suggestions for strengthening a world
|
|
16998
|
+
init Scaffold a new .nv-world.md template
|
|
16999
|
+
init-world Generate a governed world from a template (e.g., autoresearch)
|
|
17000
|
+
infer-world Scan a repo and infer a governance world from its structure
|
|
17001
|
+
validate Static analysis on world files
|
|
17002
|
+
guard Runtime governance evaluation (stdin \u2192 stdout)
|
|
17003
|
+
test Run guard simulation suite against a world
|
|
17004
|
+
redteam Adversarial containment testing (agent escape detection)
|
|
17005
|
+
demo Interactive governance demo (flow viz + simulation)
|
|
17006
|
+
doctor Environment sanity check
|
|
17007
|
+
playground Interactive web demo (opens in browser)
|
|
17008
|
+
plan Plan enforcement (compile, check, status, advance, derive)
|
|
17009
|
+
run Governed runtime (pipe mode or interactive chat)
|
|
17010
|
+
mcp MCP governance server (for Claude, Cursor, etc.)
|
|
17011
|
+
worlds List available worlds (alias for world list)
|
|
17012
|
+
trace Runtime action audit log
|
|
17013
|
+
impact Counterfactual governance impact report
|
|
17014
|
+
decision-flow Intent \u2192 Rule \u2192 Outcome visualization (behavioral governance)
|
|
13994
17015
|
equity-penalties Fortune 500 equity PENALIZE/REWARD simulation
|
|
13995
17016
|
world World management (status, diff, snapshot, rollback)
|
|
13996
17017
|
derive AI-assisted synthesis of .nv-world.md from markdown
|
|
13997
17018
|
bootstrap Compile .nv-world.md \u2192 world JSON files
|
|
13998
17019
|
configure-ai Configure AI provider credentials
|
|
17020
|
+
configure-world Interactive wizard: define your system in plain language
|
|
17021
|
+
lens Manage behavioral lenses (list, preview, compile, compare, add)
|
|
13999
17022
|
|
|
14000
17023
|
Usage:
|
|
14001
17024
|
neuroverse add "Block dairy orders" --world <dir>
|
|
@@ -14027,6 +17050,12 @@ Usage:
|
|
|
14027
17050
|
neuroverse decision-flow [--log <path>] [--json]
|
|
14028
17051
|
neuroverse equity-penalties --world <dir> [--agents N] [--rounds N] [--json]
|
|
14029
17052
|
neuroverse configure-ai --provider <name> --model <name> --api-key <key>
|
|
17053
|
+
neuroverse configure-world [--output <dir>]
|
|
17054
|
+
neuroverse lens list [--world <dir>] [--json]
|
|
17055
|
+
neuroverse lens preview <id> [--world <dir>]
|
|
17056
|
+
neuroverse lens compile <id,...> [--world <dir>] [--role <role>] [--json]
|
|
17057
|
+
neuroverse lens compare --input "text" --lenses stoic,coach,calm
|
|
17058
|
+
neuroverse lens add --world <dir> --name "Name" --tagline "..." [options]
|
|
14030
17059
|
|
|
14031
17060
|
Examples:
|
|
14032
17061
|
neuroverse build horror-notes.md
|
|
@@ -14050,7 +17079,7 @@ Examples:
|
|
|
14050
17079
|
neuroverse doctor
|
|
14051
17080
|
neuroverse playground --world ./world/
|
|
14052
17081
|
`.trim();
|
|
14053
|
-
async function
|
|
17082
|
+
async function main29() {
|
|
14054
17083
|
const args = process.argv.slice(2);
|
|
14055
17084
|
const command = args[0];
|
|
14056
17085
|
const subArgs = args.slice(1);
|
|
@@ -14167,6 +17196,14 @@ async function main27() {
|
|
|
14167
17196
|
const { main: configureAiMain } = await Promise.resolve().then(() => (init_configure_ai(), configure_ai_exports));
|
|
14168
17197
|
return configureAiMain(subArgs);
|
|
14169
17198
|
}
|
|
17199
|
+
case "configure-world": {
|
|
17200
|
+
const { main: configureWorldMain } = await Promise.resolve().then(() => (init_configure_world(), configure_world_exports));
|
|
17201
|
+
return configureWorldMain(subArgs);
|
|
17202
|
+
}
|
|
17203
|
+
case "lens": {
|
|
17204
|
+
const { main: lensMain } = await Promise.resolve().then(() => (init_lens2(), lens_exports));
|
|
17205
|
+
return lensMain(subArgs);
|
|
17206
|
+
}
|
|
14170
17207
|
case "--help":
|
|
14171
17208
|
case "-h":
|
|
14172
17209
|
case "help":
|
|
@@ -14184,7 +17221,7 @@ async function main27() {
|
|
|
14184
17221
|
}
|
|
14185
17222
|
}
|
|
14186
17223
|
}
|
|
14187
|
-
|
|
17224
|
+
main29().catch((e) => {
|
|
14188
17225
|
process.stderr.write(`Fatal: ${e}
|
|
14189
17226
|
`);
|
|
14190
17227
|
process.exit(3);
|