@neuroverseos/governance 0.4.3 → 0.5.1
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 +189 -0
- package/dist/adapters/autoresearch.js +2 -2
- package/dist/adapters/deep-agents.js +2 -2
- package/dist/adapters/express.js +2 -2
- package/dist/adapters/github.js +2 -2
- package/dist/adapters/index.js +23 -21
- package/dist/adapters/langchain.js +2 -2
- package/dist/adapters/mentraos.js +8 -6
- package/dist/adapters/openai.js +2 -2
- package/dist/adapters/openclaw.js +2 -2
- package/dist/{add-XSANI3FK.js → add-JP7TC2K3.js} +1 -1
- package/dist/admin/index.cjs +2214 -0
- package/dist/admin/index.d.cts +362 -0
- package/dist/admin/index.d.ts +362 -0
- package/dist/admin/index.js +703 -0
- package/dist/{build-EGBGZFIJ.js → build-THUEYMVT.js} +5 -5
- package/dist/{chunk-YJ34R5NB.js → chunk-5RAQ5DZW.js} +3 -3
- package/dist/{chunk-RDA7ISWC.js → chunk-6UPEUMJ2.js} +3 -3
- package/dist/chunk-7UU7V3AD.js +447 -0
- package/dist/{chunk-ZEIT2QLM.js → chunk-EK77AJAH.js} +22 -4
- package/dist/{chunk-3S5AD4AB.js → chunk-FGOSKQDE.js} +3 -3
- package/dist/{chunk-GTPV2XGO.js → chunk-GJ6LM4JZ.js} +1 -441
- package/dist/chunk-H3REGQRI.js +107 -0
- package/dist/{chunk-J2IZBHXJ.js → chunk-LAKUB76X.js} +3 -3
- package/dist/{chunk-FVOGUCB6.js → chunk-R23T5SZG.js} +3 -3
- package/dist/{chunk-A7SHG75T.js → chunk-RF2L5SYG.js} +3 -3
- package/dist/{chunk-QMVQ6KPL.js → chunk-TL4DLMMW.js} +3 -3
- package/dist/{chunk-AV7XJJWK.js → chunk-TZBERHFM.js} +3 -3
- package/dist/{chunk-3AYKQHYI.js → chunk-UZBW44KD.js} +3 -3
- package/dist/{chunk-FS2UUJJO.js → chunk-XPMZB46F.js} +3 -3
- package/dist/cli/neuroverse.cjs +962 -284
- package/dist/cli/neuroverse.js +46 -22
- package/dist/cli/plan.js +1 -1
- package/dist/cli/run.cjs +242 -139
- package/dist/cli/run.js +23 -3
- package/dist/{demo-6OQYWRR6.js → demo-N5K4VXJW.js} +3 -3
- package/dist/{derive-7Y7YWVLU.js → derive-5LOMN7GO.js} +4 -4
- package/dist/{equity-penalties-NVBAB5WL.js → equity-penalties-PYCJ3Q4U.js} +6 -6
- package/dist/{explain-HDFN4ION.js → explain-42TVC3QD.js} +1 -1
- package/dist/{guard-6KSCWT2W.js → guard-TPYDFG6V.js} +16 -4
- package/dist/{improve-2PWGGO5B.js → improve-HLZGJ54Z.js} +3 -3
- package/dist/index.cjs +19 -1
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +27 -27
- package/dist/keygen-BSZH3NM2.js +77 -0
- package/dist/{lens-MHMUDCMQ.js → lens-NFGZHD76.js} +1 -1
- package/dist/{mcp-server-TNIWZ7B5.js → mcp-server-5XXNG6VC.js} +2 -2
- package/dist/migrate-NH5PVMX4.js +221 -0
- package/dist/{playground-3FLDGBET.js → playground-2EU5CFIH.js} +4 -4
- package/dist/{redteam-HV6LMKEH.js → redteam-VK6OVHAE.js} +3 -3
- package/dist/{session-XZP2754M.js → session-NGA4DUPL.js} +2 -2
- package/dist/sign-RRELHKWM.js +11 -0
- package/dist/{simulate-VT437EEL.js → simulate-4YNOBMES.js} +1 -1
- package/dist/{test-4WTX6RKQ.js → test-HDBPMQTG.js} +3 -3
- package/dist/{validate-M52DX22Y.js → validate-6MFQZ2EG.js} +1 -1
- package/dist/verify-6AVTWX75.js +151 -0
- package/dist/{world-O4HTQPDP.js → world-H5WVURKU.js} +1 -1
- package/dist/{world-loader-YTYFOP7D.js → world-loader-J47PCPDZ.js} +1 -1
- package/package.json +22 -10
- package/dist/{behavioral-SLW7ALEK.js → behavioral-SPWPGYXL.js} +3 -3
- package/dist/{bootstrap-2OW5ZLBL.js → bootstrap-IP5QMC3Q.js} +3 -3
- package/dist/{chunk-I4RTIMLX.js → chunk-EQUAWNXW.js} +0 -0
- package/dist/{chunk-DA5MHFRR.js → chunk-NTHXZAW4.js} +3 -3
- package/dist/{chunk-FHXXD2TI.js → chunk-QZ666FCV.js} +6 -6
- package/dist/{configure-ai-LL3VAPQW.js → configure-ai-5MP5DWTT.js} +3 -3
- package/dist/{decision-flow-3K4D72G4.js → decision-flow-IJPNMVQK.js} +3 -3
- /package/dist/{doctor-EC5OYTI3.js → doctor-Q5APJOTS.js} +0 -0
package/dist/cli/neuroverse.cjs
CHANGED
|
@@ -2002,10 +2002,10 @@ __export(world_loader_exports, {
|
|
|
2002
2002
|
});
|
|
2003
2003
|
async function loadWorldFromDirectory(dirPath) {
|
|
2004
2004
|
const { readFile: readFile3 } = await import("fs/promises");
|
|
2005
|
-
const { join:
|
|
2006
|
-
const { readdirSync:
|
|
2005
|
+
const { join: join13 } = await import("path");
|
|
2006
|
+
const { readdirSync: readdirSync6 } = await import("fs");
|
|
2007
2007
|
async function readJson(filename) {
|
|
2008
|
-
const filePath =
|
|
2008
|
+
const filePath = join13(dirPath, filename);
|
|
2009
2009
|
try {
|
|
2010
2010
|
const content = await readFile3(filePath, "utf-8");
|
|
2011
2011
|
return JSON.parse(content);
|
|
@@ -2035,11 +2035,11 @@ async function loadWorldFromDirectory(dirPath) {
|
|
|
2035
2035
|
const metadataJson = await readJson("metadata.json");
|
|
2036
2036
|
const rules = [];
|
|
2037
2037
|
try {
|
|
2038
|
-
const rulesDir =
|
|
2039
|
-
const ruleFiles =
|
|
2038
|
+
const rulesDir = join13(dirPath, "rules");
|
|
2039
|
+
const ruleFiles = readdirSync6(rulesDir).filter((f) => f.endsWith(".json")).sort();
|
|
2040
2040
|
for (const file of ruleFiles) {
|
|
2041
2041
|
try {
|
|
2042
|
-
const content = await readFile3(
|
|
2042
|
+
const content = await readFile3(join13(rulesDir, file), "utf-8");
|
|
2043
2043
|
rules.push(JSON.parse(content));
|
|
2044
2044
|
} catch (err) {
|
|
2045
2045
|
process.stderr.write(
|
|
@@ -2093,8 +2093,8 @@ async function loadWorld(worldPath) {
|
|
|
2093
2093
|
}
|
|
2094
2094
|
async function loadBundledWorld(name = DEFAULT_BUNDLED_WORLD) {
|
|
2095
2095
|
const { readFile: readFile3 } = await import("fs/promises");
|
|
2096
|
-
const { join:
|
|
2097
|
-
const { existsSync:
|
|
2096
|
+
const { join: join13, dirname: dirname3 } = await import("path");
|
|
2097
|
+
const { existsSync: existsSync9 } = await import("fs");
|
|
2098
2098
|
const { fileURLToPath: fileURLToPath3 } = await import("url");
|
|
2099
2099
|
const { parseWorldMarkdown: parseWorldMarkdown2 } = await Promise.resolve().then(() => (init_bootstrap_parser(), bootstrap_parser_exports));
|
|
2100
2100
|
const { emitWorldDefinition: emitWorldDefinition2 } = await Promise.resolve().then(() => (init_bootstrap_emitter(), bootstrap_emitter_exports));
|
|
@@ -2102,16 +2102,16 @@ async function loadBundledWorld(name = DEFAULT_BUNDLED_WORLD) {
|
|
|
2102
2102
|
let packageRoot;
|
|
2103
2103
|
try {
|
|
2104
2104
|
const thisFile = typeof __dirname !== "undefined" ? __dirname : dirname3(fileURLToPath3(import_meta.url));
|
|
2105
|
-
packageRoot =
|
|
2105
|
+
packageRoot = join13(thisFile, "..", "..");
|
|
2106
2106
|
} catch {
|
|
2107
2107
|
packageRoot = process.cwd();
|
|
2108
2108
|
}
|
|
2109
2109
|
const candidates = [
|
|
2110
|
-
|
|
2111
|
-
|
|
2110
|
+
join13(packageRoot, "dist", "worlds", filename),
|
|
2111
|
+
join13(packageRoot, "src", "worlds", filename)
|
|
2112
2112
|
];
|
|
2113
2113
|
for (const candidate of candidates) {
|
|
2114
|
-
if (
|
|
2114
|
+
if (existsSync9(candidate)) {
|
|
2115
2115
|
const markdown = await readFile3(candidate, "utf-8");
|
|
2116
2116
|
const parsed = parseWorldMarkdown2(markdown);
|
|
2117
2117
|
if (!parsed.world) {
|
|
@@ -2141,8 +2141,8 @@ function slugify(text) {
|
|
|
2141
2141
|
}
|
|
2142
2142
|
async function addGuard(worldDir, input) {
|
|
2143
2143
|
const { readFile: readFile3, writeFile: writeFile5 } = await import("fs/promises");
|
|
2144
|
-
const { join:
|
|
2145
|
-
const guardsPath =
|
|
2144
|
+
const { join: join13 } = await import("path");
|
|
2145
|
+
const guardsPath = join13(worldDir, "guards.json");
|
|
2146
2146
|
let config;
|
|
2147
2147
|
try {
|
|
2148
2148
|
const raw = await readFile3(guardsPath, "utf-8");
|
|
@@ -2182,13 +2182,13 @@ async function addGuard(worldDir, input) {
|
|
|
2182
2182
|
}
|
|
2183
2183
|
async function addRule(worldDir, input) {
|
|
2184
2184
|
const { readFile: readFile3, writeFile: writeFile5, mkdir: mkdir2 } = await import("fs/promises");
|
|
2185
|
-
const { join:
|
|
2186
|
-
const { readdirSync:
|
|
2187
|
-
const rulesDir =
|
|
2185
|
+
const { join: join13 } = await import("path");
|
|
2186
|
+
const { readdirSync: readdirSync6 } = await import("fs");
|
|
2187
|
+
const rulesDir = join13(worldDir, "rules");
|
|
2188
2188
|
await mkdir2(rulesDir, { recursive: true });
|
|
2189
2189
|
let nextNum = 1;
|
|
2190
2190
|
try {
|
|
2191
|
-
const existing =
|
|
2191
|
+
const existing = readdirSync6(rulesDir).filter((f) => f.match(/^rule-\d+\.json$/)).sort();
|
|
2192
2192
|
if (existing.length > 0) {
|
|
2193
2193
|
const lastFile = existing[existing.length - 1];
|
|
2194
2194
|
const match = lastFile.match(/rule-(\d+)\.json/);
|
|
@@ -2214,7 +2214,7 @@ async function addRule(worldDir, input) {
|
|
|
2214
2214
|
effect_text: input.effects ? input.effects.map((e) => `${e.target} ${e.operation} ${e.value}`).join(", ") : "No direct effects"
|
|
2215
2215
|
}
|
|
2216
2216
|
};
|
|
2217
|
-
const rulePath =
|
|
2217
|
+
const rulePath = join13(rulesDir, `rule-${ruleNum}.json`);
|
|
2218
2218
|
await writeFile5(rulePath, JSON.stringify(rule, null, 2) + "\n");
|
|
2219
2219
|
const { loadWorldFromDirectory: loadWorldFromDirectory3 } = await Promise.resolve().then(() => (init_world_loader(), world_loader_exports));
|
|
2220
2220
|
const world = await loadWorldFromDirectory3(worldDir);
|
|
@@ -2230,8 +2230,8 @@ async function addRule(worldDir, input) {
|
|
|
2230
2230
|
}
|
|
2231
2231
|
async function addInvariant(worldDir, input) {
|
|
2232
2232
|
const { readFile: readFile3, writeFile: writeFile5 } = await import("fs/promises");
|
|
2233
|
-
const { join:
|
|
2234
|
-
const invariantsPath =
|
|
2233
|
+
const { join: join13 } = await import("path");
|
|
2234
|
+
const invariantsPath = join13(worldDir, "invariants.json");
|
|
2235
2235
|
let config;
|
|
2236
2236
|
try {
|
|
2237
2237
|
const raw = await readFile3(invariantsPath, "utf-8");
|
|
@@ -2849,27 +2849,27 @@ ${candidates.map((c) => ` - ${c}`).join("\n")}`
|
|
|
2849
2849
|
}
|
|
2850
2850
|
async function collectMarkdownSources(inputPath) {
|
|
2851
2851
|
const { stat, readFile: rf, readdir } = await import("fs/promises");
|
|
2852
|
-
const { join: pathJoin, extname: extname2, basename:
|
|
2852
|
+
const { join: pathJoin, extname: extname2, basename: basename3 } = await import("path");
|
|
2853
2853
|
const stats = await stat(inputPath);
|
|
2854
2854
|
if (stats.isFile()) {
|
|
2855
2855
|
const content = await rf(inputPath, "utf-8");
|
|
2856
|
-
return [{ filename:
|
|
2856
|
+
return [{ filename: basename3(inputPath), content }];
|
|
2857
2857
|
}
|
|
2858
2858
|
if (stats.isDirectory()) {
|
|
2859
2859
|
const sources = [];
|
|
2860
|
-
await collectDir(inputPath, sources, rf, pathJoin, extname2,
|
|
2860
|
+
await collectDir(inputPath, sources, rf, pathJoin, extname2, basename3);
|
|
2861
2861
|
sources.sort((a, b) => a.filename.localeCompare(b.filename));
|
|
2862
2862
|
return sources;
|
|
2863
2863
|
}
|
|
2864
2864
|
throw new Error(`Input path is neither a file nor a directory: ${inputPath}`);
|
|
2865
2865
|
}
|
|
2866
|
-
async function collectDir(dir, sources, rf, pathJoin, extname2,
|
|
2866
|
+
async function collectDir(dir, sources, rf, pathJoin, extname2, basename3) {
|
|
2867
2867
|
const { readdir } = await import("fs/promises");
|
|
2868
2868
|
const entries = await readdir(dir, { withFileTypes: true });
|
|
2869
2869
|
for (const entry of entries) {
|
|
2870
2870
|
const fullPath = pathJoin(dir, entry.name);
|
|
2871
2871
|
if (entry.isDirectory()) {
|
|
2872
|
-
await collectDir(fullPath, sources, rf, pathJoin, extname2,
|
|
2872
|
+
await collectDir(fullPath, sources, rf, pathJoin, extname2, basename3);
|
|
2873
2873
|
} else if (entry.isFile() && extname2(entry.name).toLowerCase() === ".md") {
|
|
2874
2874
|
const content = await rf(fullPath, "utf-8");
|
|
2875
2875
|
sources.push({ filename: entry.name, content });
|
|
@@ -3528,21 +3528,21 @@ function parseArgs2(argv) {
|
|
|
3528
3528
|
}
|
|
3529
3529
|
async function writeWorldFiles(outputDir, world) {
|
|
3530
3530
|
const { writeFile: writeFile5, mkdir: mkdir2 } = await import("fs/promises");
|
|
3531
|
-
const { join:
|
|
3531
|
+
const { join: join13 } = await import("path");
|
|
3532
3532
|
await mkdir2(outputDir, { recursive: true });
|
|
3533
|
-
await writeFile5(
|
|
3534
|
-
await writeFile5(
|
|
3535
|
-
await writeFile5(
|
|
3536
|
-
await writeFile5(
|
|
3537
|
-
await writeFile5(
|
|
3538
|
-
await writeFile5(
|
|
3539
|
-
await writeFile5(
|
|
3540
|
-
const rulesDir =
|
|
3533
|
+
await writeFile5(join13(outputDir, "world.json"), JSON.stringify(world.world, null, 2));
|
|
3534
|
+
await writeFile5(join13(outputDir, "invariants.json"), JSON.stringify({ invariants: world.invariants }, null, 2));
|
|
3535
|
+
await writeFile5(join13(outputDir, "assumptions.json"), JSON.stringify(world.assumptions, null, 2));
|
|
3536
|
+
await writeFile5(join13(outputDir, "state-schema.json"), JSON.stringify(world.stateSchema, null, 2));
|
|
3537
|
+
await writeFile5(join13(outputDir, "gates.json"), JSON.stringify(world.gates, null, 2));
|
|
3538
|
+
await writeFile5(join13(outputDir, "outcomes.json"), JSON.stringify(world.outcomes, null, 2));
|
|
3539
|
+
await writeFile5(join13(outputDir, "metadata.json"), JSON.stringify(world.metadata, null, 2));
|
|
3540
|
+
const rulesDir = join13(outputDir, "rules");
|
|
3541
3541
|
await mkdir2(rulesDir, { recursive: true });
|
|
3542
3542
|
const sortedRules = [...world.rules].sort((a, b) => a.order - b.order);
|
|
3543
3543
|
for (let i = 0; i < sortedRules.length; i++) {
|
|
3544
3544
|
const ruleNum = String(i + 1).padStart(3, "0");
|
|
3545
|
-
await writeFile5(
|
|
3545
|
+
await writeFile5(join13(rulesDir, `rule-${ruleNum}.json`), JSON.stringify(sortedRules[i], null, 2));
|
|
3546
3546
|
}
|
|
3547
3547
|
}
|
|
3548
3548
|
function write(msg) {
|
|
@@ -3557,12 +3557,12 @@ function printInsight(finding2) {
|
|
|
3557
3557
|
async function main2(argv = process.argv.slice(2)) {
|
|
3558
3558
|
try {
|
|
3559
3559
|
const args = parseArgs2(argv);
|
|
3560
|
-
const { basename:
|
|
3560
|
+
const { basename: basename3 } = await import("path");
|
|
3561
3561
|
write(`
|
|
3562
3562
|
NeuroVerse World Builder
|
|
3563
3563
|
`);
|
|
3564
3564
|
write(`
|
|
3565
|
-
Analyzing: ${
|
|
3565
|
+
Analyzing: ${basename3(args.inputPath)}
|
|
3566
3566
|
`);
|
|
3567
3567
|
const derivedPath = args.outputDir ? `${args.outputDir}/source.nv-world.md` : ".neuroverse/build-output.nv-world.md";
|
|
3568
3568
|
const { mkdir: mkdir2 } = await import("fs/promises");
|
|
@@ -3673,9 +3673,9 @@ World source written to: ${derivedPath}
|
|
|
3673
3673
|
try {
|
|
3674
3674
|
const emitResult = emitWorldDefinition(parseResult.world);
|
|
3675
3675
|
await writeWorldFiles(outputDir, emitResult.world);
|
|
3676
|
-
const { join:
|
|
3676
|
+
const { join: join13 } = await import("path");
|
|
3677
3677
|
const { copyFile } = await import("fs/promises");
|
|
3678
|
-
const sourceDest =
|
|
3678
|
+
const sourceDest = join13(outputDir, "source.nv-world.md");
|
|
3679
3679
|
if (derivedPath !== sourceDest) {
|
|
3680
3680
|
await copyFile(derivedPath, sourceDest);
|
|
3681
3681
|
}
|
|
@@ -5009,8 +5009,8 @@ async function main6(argv = process.argv.slice(2)) {
|
|
|
5009
5009
|
try {
|
|
5010
5010
|
const args = parseArgs6(argv);
|
|
5011
5011
|
const { writeFile: writeFile5 } = await import("fs/promises");
|
|
5012
|
-
const { existsSync:
|
|
5013
|
-
if (
|
|
5012
|
+
const { existsSync: existsSync9 } = await import("fs");
|
|
5013
|
+
if (existsSync9(args.outputPath)) {
|
|
5014
5014
|
process.stderr.write(`File already exists: ${args.outputPath}
|
|
5015
5015
|
`);
|
|
5016
5016
|
process.stderr.write("Use a different --output path or remove the existing file.\n");
|
|
@@ -5868,22 +5868,22 @@ function parseArgs9(argv) {
|
|
|
5868
5868
|
}
|
|
5869
5869
|
async function writeWorldFiles2(outputDir, world) {
|
|
5870
5870
|
const { writeFile: writeFile5, mkdir: mkdir2 } = await import("fs/promises");
|
|
5871
|
-
const { join:
|
|
5871
|
+
const { join: join13 } = await import("path");
|
|
5872
5872
|
await mkdir2(outputDir, { recursive: true });
|
|
5873
|
-
await writeFile5(
|
|
5874
|
-
await writeFile5(
|
|
5875
|
-
await writeFile5(
|
|
5876
|
-
await writeFile5(
|
|
5877
|
-
const rulesDir =
|
|
5873
|
+
await writeFile5(join13(outputDir, "world.json"), JSON.stringify(world.world, null, 2));
|
|
5874
|
+
await writeFile5(join13(outputDir, "invariants.json"), JSON.stringify({ invariants: world.invariants }, null, 2));
|
|
5875
|
+
await writeFile5(join13(outputDir, "assumptions.json"), JSON.stringify(world.assumptions, null, 2));
|
|
5876
|
+
await writeFile5(join13(outputDir, "state-schema.json"), JSON.stringify(world.stateSchema, null, 2));
|
|
5877
|
+
const rulesDir = join13(outputDir, "rules");
|
|
5878
5878
|
await mkdir2(rulesDir, { recursive: true });
|
|
5879
5879
|
const sortedRules = [...world.rules].sort((a, b) => a.order - b.order);
|
|
5880
5880
|
for (let i = 0; i < sortedRules.length; i++) {
|
|
5881
5881
|
const ruleNum = String(i + 1).padStart(3, "0");
|
|
5882
|
-
await writeFile5(
|
|
5882
|
+
await writeFile5(join13(rulesDir, `rule-${ruleNum}.json`), JSON.stringify(sortedRules[i], null, 2));
|
|
5883
5883
|
}
|
|
5884
|
-
await writeFile5(
|
|
5885
|
-
await writeFile5(
|
|
5886
|
-
await writeFile5(
|
|
5884
|
+
await writeFile5(join13(outputDir, "gates.json"), JSON.stringify(world.gates, null, 2));
|
|
5885
|
+
await writeFile5(join13(outputDir, "outcomes.json"), JSON.stringify(world.outcomes, null, 2));
|
|
5886
|
+
await writeFile5(join13(outputDir, "metadata.json"), JSON.stringify(world.metadata, null, 2));
|
|
5887
5887
|
}
|
|
5888
5888
|
async function main9(argv = process.argv.slice(2)) {
|
|
5889
5889
|
const startTime = performance.now();
|
|
@@ -7364,6 +7364,162 @@ var init_guard_contract = __esm({
|
|
|
7364
7364
|
}
|
|
7365
7365
|
});
|
|
7366
7366
|
|
|
7367
|
+
// src/engine/audit-logger.ts
|
|
7368
|
+
function verdictToAuditEvent(event, verdict) {
|
|
7369
|
+
const auditEvent = {
|
|
7370
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
7371
|
+
worldId: verdict.evidence.worldId,
|
|
7372
|
+
worldName: verdict.evidence.worldName,
|
|
7373
|
+
worldVersion: verdict.evidence.worldVersion,
|
|
7374
|
+
intent: event.intent,
|
|
7375
|
+
tool: event.tool,
|
|
7376
|
+
scope: event.scope,
|
|
7377
|
+
actor: event.roleId,
|
|
7378
|
+
direction: event.direction,
|
|
7379
|
+
decision: verdict.status,
|
|
7380
|
+
reason: verdict.reason,
|
|
7381
|
+
ruleId: verdict.ruleId,
|
|
7382
|
+
warning: verdict.warning,
|
|
7383
|
+
guardsMatched: verdict.evidence.guardsMatched,
|
|
7384
|
+
rulesMatched: verdict.evidence.rulesMatched,
|
|
7385
|
+
invariantsSatisfied: verdict.evidence.invariantsSatisfied,
|
|
7386
|
+
invariantsTotal: verdict.evidence.invariantsTotal,
|
|
7387
|
+
enforcementLevel: verdict.evidence.enforcementLevel,
|
|
7388
|
+
durationMs: verdict.trace?.durationMs,
|
|
7389
|
+
args: event.args
|
|
7390
|
+
};
|
|
7391
|
+
if (verdict.consequence) {
|
|
7392
|
+
auditEvent.consequence = verdict.consequence;
|
|
7393
|
+
}
|
|
7394
|
+
if (verdict.reward) {
|
|
7395
|
+
auditEvent.reward = verdict.reward;
|
|
7396
|
+
}
|
|
7397
|
+
if (verdict.intentRecord) {
|
|
7398
|
+
auditEvent.originalIntent = verdict.intentRecord.originalIntent;
|
|
7399
|
+
auditEvent.finalAction = verdict.intentRecord.finalAction;
|
|
7400
|
+
}
|
|
7401
|
+
return auditEvent;
|
|
7402
|
+
}
|
|
7403
|
+
async function readAuditLog(logPath, filter) {
|
|
7404
|
+
const { readFile: readFile3 } = await import("fs/promises");
|
|
7405
|
+
let content;
|
|
7406
|
+
try {
|
|
7407
|
+
content = await readFile3(logPath, "utf-8");
|
|
7408
|
+
} catch {
|
|
7409
|
+
return [];
|
|
7410
|
+
}
|
|
7411
|
+
const events = [];
|
|
7412
|
+
for (const line of content.split("\n")) {
|
|
7413
|
+
const trimmed = line.trim();
|
|
7414
|
+
if (!trimmed) continue;
|
|
7415
|
+
try {
|
|
7416
|
+
const event = JSON.parse(trimmed);
|
|
7417
|
+
if (!filter || filter(event)) {
|
|
7418
|
+
events.push(event);
|
|
7419
|
+
}
|
|
7420
|
+
} catch {
|
|
7421
|
+
}
|
|
7422
|
+
}
|
|
7423
|
+
return events;
|
|
7424
|
+
}
|
|
7425
|
+
function summarizeAuditEvents(events) {
|
|
7426
|
+
const allowed = events.filter((e) => e.decision === "ALLOW").length;
|
|
7427
|
+
const blocked = events.filter((e) => e.decision === "BLOCK").length;
|
|
7428
|
+
const paused = events.filter((e) => e.decision === "PAUSE").length;
|
|
7429
|
+
const modified = events.filter((e) => e.decision === "MODIFY").length;
|
|
7430
|
+
const penalized = events.filter((e) => e.decision === "PENALIZE").length;
|
|
7431
|
+
const rewarded = events.filter((e) => e.decision === "REWARD").length;
|
|
7432
|
+
const neutral = events.filter((e) => e.decision === "NEUTRAL").length;
|
|
7433
|
+
const actorSet = /* @__PURE__ */ new Set();
|
|
7434
|
+
for (const e of events) {
|
|
7435
|
+
if (e.actor) actorSet.add(e.actor);
|
|
7436
|
+
}
|
|
7437
|
+
const intentMap = /* @__PURE__ */ new Map();
|
|
7438
|
+
for (const e of events) {
|
|
7439
|
+
const entry = intentMap.get(e.intent) ?? { count: 0, blocked: 0, paused: 0, penalized: 0, rewarded: 0 };
|
|
7440
|
+
entry.count++;
|
|
7441
|
+
if (e.decision === "BLOCK") entry.blocked++;
|
|
7442
|
+
if (e.decision === "PAUSE") entry.paused++;
|
|
7443
|
+
if (e.decision === "PENALIZE") entry.penalized++;
|
|
7444
|
+
if (e.decision === "REWARD") entry.rewarded++;
|
|
7445
|
+
intentMap.set(e.intent, entry);
|
|
7446
|
+
}
|
|
7447
|
+
const topIntents = [...intentMap.entries()].map(([intent, data]) => ({ intent, ...data })).sort((a, b) => b.count - a.count);
|
|
7448
|
+
const ruleMap = /* @__PURE__ */ new Map();
|
|
7449
|
+
for (const e of events) {
|
|
7450
|
+
if (e.ruleId) {
|
|
7451
|
+
ruleMap.set(e.ruleId, (ruleMap.get(e.ruleId) ?? 0) + 1);
|
|
7452
|
+
}
|
|
7453
|
+
for (const g of e.guardsMatched) {
|
|
7454
|
+
ruleMap.set(g, (ruleMap.get(g) ?? 0) + 1);
|
|
7455
|
+
}
|
|
7456
|
+
}
|
|
7457
|
+
const topRules = [...ruleMap.entries()].map(([ruleId, count]) => ({ ruleId, count })).sort((a, b) => b.count - a.count);
|
|
7458
|
+
const redirected = blocked + paused + modified + penalized;
|
|
7459
|
+
const total = events.length;
|
|
7460
|
+
return {
|
|
7461
|
+
totalActions: total,
|
|
7462
|
+
allowed,
|
|
7463
|
+
blocked,
|
|
7464
|
+
paused,
|
|
7465
|
+
modified,
|
|
7466
|
+
penalized,
|
|
7467
|
+
rewarded,
|
|
7468
|
+
neutral,
|
|
7469
|
+
actors: [...actorSet],
|
|
7470
|
+
topIntents,
|
|
7471
|
+
topRules,
|
|
7472
|
+
firstEvent: events[0]?.timestamp ?? "",
|
|
7473
|
+
lastEvent: events[events.length - 1]?.timestamp ?? "",
|
|
7474
|
+
behavioralEconomy: {
|
|
7475
|
+
totalPenalties: penalized,
|
|
7476
|
+
totalRewards: rewarded,
|
|
7477
|
+
netPressure: rewarded - penalized,
|
|
7478
|
+
redirectionRate: total > 0 ? redirected / total : 0
|
|
7479
|
+
}
|
|
7480
|
+
};
|
|
7481
|
+
}
|
|
7482
|
+
var FileAuditLogger;
|
|
7483
|
+
var init_audit_logger = __esm({
|
|
7484
|
+
"src/engine/audit-logger.ts"() {
|
|
7485
|
+
"use strict";
|
|
7486
|
+
init_guard_engine();
|
|
7487
|
+
FileAuditLogger = class {
|
|
7488
|
+
logPath;
|
|
7489
|
+
buffer = [];
|
|
7490
|
+
flushTimer = null;
|
|
7491
|
+
flushIntervalMs;
|
|
7492
|
+
constructor(logPath, options) {
|
|
7493
|
+
this.logPath = logPath;
|
|
7494
|
+
this.flushIntervalMs = options?.flushIntervalMs ?? 1e3;
|
|
7495
|
+
}
|
|
7496
|
+
log(event) {
|
|
7497
|
+
this.buffer.push(JSON.stringify(event));
|
|
7498
|
+
if (!this.flushTimer) {
|
|
7499
|
+
this.flushTimer = setTimeout(() => {
|
|
7500
|
+
void this.flush();
|
|
7501
|
+
}, this.flushIntervalMs);
|
|
7502
|
+
}
|
|
7503
|
+
}
|
|
7504
|
+
async flush() {
|
|
7505
|
+
if (this.buffer.length === 0) return;
|
|
7506
|
+
if (this.flushTimer) {
|
|
7507
|
+
clearTimeout(this.flushTimer);
|
|
7508
|
+
this.flushTimer = null;
|
|
7509
|
+
}
|
|
7510
|
+
const lines = this.buffer.splice(0).join("\n") + "\n";
|
|
7511
|
+
try {
|
|
7512
|
+
const { appendFile, mkdir: mkdir2 } = await import("fs/promises");
|
|
7513
|
+
const { dirname: dirname3 } = await import("path");
|
|
7514
|
+
await mkdir2(dirname3(this.logPath), { recursive: true });
|
|
7515
|
+
await appendFile(this.logPath, lines, "utf-8");
|
|
7516
|
+
} catch {
|
|
7517
|
+
}
|
|
7518
|
+
}
|
|
7519
|
+
};
|
|
7520
|
+
}
|
|
7521
|
+
});
|
|
7522
|
+
|
|
7367
7523
|
// src/cli/guard.ts
|
|
7368
7524
|
var guard_exports = {};
|
|
7369
7525
|
__export(guard_exports, {
|
|
@@ -7374,6 +7530,7 @@ function parseArgs11(argv) {
|
|
|
7374
7530
|
let trace = false;
|
|
7375
7531
|
let level;
|
|
7376
7532
|
let aiClassify = false;
|
|
7533
|
+
let logPath;
|
|
7377
7534
|
for (let i = 0; i < argv.length; i++) {
|
|
7378
7535
|
const arg = argv[i];
|
|
7379
7536
|
if (arg === "--world" && i + 1 < argv.length) {
|
|
@@ -7382,6 +7539,8 @@ function parseArgs11(argv) {
|
|
|
7382
7539
|
trace = true;
|
|
7383
7540
|
} else if (arg === "--ai-classify") {
|
|
7384
7541
|
aiClassify = true;
|
|
7542
|
+
} else if (arg === "--log" && i + 1 < argv.length) {
|
|
7543
|
+
logPath = argv[++i];
|
|
7385
7544
|
} else if (arg === "--level" && i + 1 < argv.length) {
|
|
7386
7545
|
const val = argv[++i];
|
|
7387
7546
|
if (val === "basic" || val === "standard" || val === "strict") {
|
|
@@ -7391,7 +7550,7 @@ function parseArgs11(argv) {
|
|
|
7391
7550
|
}
|
|
7392
7551
|
}
|
|
7393
7552
|
}
|
|
7394
|
-
return { worldPath, trace, level, aiClassify };
|
|
7553
|
+
return { worldPath, trace, level, aiClassify, logPath };
|
|
7395
7554
|
}
|
|
7396
7555
|
async function main11(argv = process.argv.slice(2)) {
|
|
7397
7556
|
try {
|
|
@@ -7451,6 +7610,11 @@ async function main11(argv = process.argv.slice(2)) {
|
|
|
7451
7610
|
const options = { trace: args.trace, level: args.level };
|
|
7452
7611
|
verdict = evaluateGuard(event, world, options);
|
|
7453
7612
|
}
|
|
7613
|
+
if (args.logPath) {
|
|
7614
|
+
const logger = new FileAuditLogger(args.logPath, { flushIntervalMs: 0 });
|
|
7615
|
+
logger.log(verdictToAuditEvent(event, verdict));
|
|
7616
|
+
await logger.flush();
|
|
7617
|
+
}
|
|
7454
7618
|
process.stdout.write(JSON.stringify(verdict, null, 2) + "\n");
|
|
7455
7619
|
const exitCode = GUARD_EXIT_CODES[verdict.status];
|
|
7456
7620
|
process.exit(exitCode);
|
|
@@ -7479,6 +7643,7 @@ var init_guard = __esm({
|
|
|
7479
7643
|
init_world_resolver();
|
|
7480
7644
|
init_guard_contract();
|
|
7481
7645
|
init_cli_utils();
|
|
7646
|
+
init_audit_logger();
|
|
7482
7647
|
}
|
|
7483
7648
|
});
|
|
7484
7649
|
|
|
@@ -8077,13 +8242,13 @@ function handleHealthCheck() {
|
|
|
8077
8242
|
}
|
|
8078
8243
|
async function handleListPresets(policiesDir) {
|
|
8079
8244
|
const { readdir, readFile: readFile3 } = await import("fs/promises");
|
|
8080
|
-
const { join:
|
|
8081
|
-
const dir = policiesDir ??
|
|
8245
|
+
const { join: join13 } = await import("path");
|
|
8246
|
+
const dir = policiesDir ?? join13(process.cwd(), "policies");
|
|
8082
8247
|
const presets = [];
|
|
8083
8248
|
try {
|
|
8084
8249
|
const files = await readdir(dir);
|
|
8085
8250
|
for (const file of files.filter((f) => f.endsWith(".txt")).sort()) {
|
|
8086
|
-
const content = await readFile3(
|
|
8251
|
+
const content = await readFile3(join13(dir, file), "utf-8");
|
|
8087
8252
|
const id = file.replace(".txt", "");
|
|
8088
8253
|
const name = id.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
|
|
8089
8254
|
const firstLine = content.split("\n").find((l) => l.trim().length > 0) ?? "";
|
|
@@ -8155,7 +8320,7 @@ function govern(action, world, options) {
|
|
|
8155
8320
|
}
|
|
8156
8321
|
async function writeTempWorld(dir, policyLines) {
|
|
8157
8322
|
const { writeFile: writeFile5, mkdir: mkdir2 } = await import("fs/promises");
|
|
8158
|
-
const { join:
|
|
8323
|
+
const { join: join13 } = await import("path");
|
|
8159
8324
|
await mkdir2(dir, { recursive: true });
|
|
8160
8325
|
const worldJson = {
|
|
8161
8326
|
world_id: "demo-live",
|
|
@@ -8197,9 +8362,9 @@ async function writeTempWorld(dir, policyLines) {
|
|
|
8197
8362
|
authoring_method: "manual-authoring"
|
|
8198
8363
|
};
|
|
8199
8364
|
await Promise.all([
|
|
8200
|
-
writeFile5(
|
|
8201
|
-
writeFile5(
|
|
8202
|
-
writeFile5(
|
|
8365
|
+
writeFile5(join13(dir, "world.json"), JSON.stringify(worldJson, null, 2)),
|
|
8366
|
+
writeFile5(join13(dir, "kernel.json"), JSON.stringify(kernelJson, null, 2)),
|
|
8367
|
+
writeFile5(join13(dir, "metadata.json"), JSON.stringify(metadataJson, null, 2))
|
|
8203
8368
|
]);
|
|
8204
8369
|
}
|
|
8205
8370
|
var init_govern = __esm({
|
|
@@ -11310,9 +11475,9 @@ async function main15(argv) {
|
|
|
11310
11475
|
}
|
|
11311
11476
|
if (worldPath) {
|
|
11312
11477
|
try {
|
|
11313
|
-
const { existsSync:
|
|
11314
|
-
const { join:
|
|
11315
|
-
const hasWorld =
|
|
11478
|
+
const { existsSync: existsSync9 } = await import("fs");
|
|
11479
|
+
const { join: join13 } = await import("path");
|
|
11480
|
+
const hasWorld = existsSync9(join13(worldPath, "world.json"));
|
|
11316
11481
|
checks.push({
|
|
11317
11482
|
label: "World file detected",
|
|
11318
11483
|
status: hasWorld ? "pass" : "fail",
|
|
@@ -11327,12 +11492,12 @@ async function main15(argv) {
|
|
|
11327
11492
|
});
|
|
11328
11493
|
}
|
|
11329
11494
|
} else {
|
|
11330
|
-
const { existsSync:
|
|
11331
|
-
const { join:
|
|
11495
|
+
const { existsSync: existsSync9 } = await import("fs");
|
|
11496
|
+
const { join: join13 } = await import("path");
|
|
11332
11497
|
const candidates = ["./world", "./.neuroverse", "./worlds"];
|
|
11333
11498
|
let found;
|
|
11334
11499
|
for (const dir of candidates) {
|
|
11335
|
-
if (
|
|
11500
|
+
if (existsSync9(join13(dir, "world.json"))) {
|
|
11336
11501
|
found = dir;
|
|
11337
11502
|
break;
|
|
11338
11503
|
}
|
|
@@ -12384,8 +12549,8 @@ async function deriveCommand(args) {
|
|
|
12384
12549
|
return;
|
|
12385
12550
|
}
|
|
12386
12551
|
const plan = result.plan;
|
|
12387
|
-
const { mkdirSync:
|
|
12388
|
-
|
|
12552
|
+
const { mkdirSync: mkdirSync5 } = await import("fs");
|
|
12553
|
+
mkdirSync5(outputDir, { recursive: true });
|
|
12389
12554
|
const worldJson = {
|
|
12390
12555
|
world_id: `plan_${plan.plan_id}`,
|
|
12391
12556
|
name: `Derived: ${plan.objective}`,
|
|
@@ -12982,11 +13147,17 @@ async function runPipeMode(config) {
|
|
|
12982
13147
|
process.stderr.write(`[neuroverse] Plan: ${state.plan.plan_id} (${state.plan.objective})
|
|
12983
13148
|
`);
|
|
12984
13149
|
}
|
|
13150
|
+
const MAX_BUFFER_SIZE = 1e6;
|
|
12985
13151
|
return new Promise((resolve5, reject) => {
|
|
12986
13152
|
let buffer = "";
|
|
12987
13153
|
process.stdin.setEncoding("utf-8");
|
|
12988
13154
|
process.stdin.on("data", (chunk) => {
|
|
12989
13155
|
buffer += chunk;
|
|
13156
|
+
if (buffer.length > MAX_BUFFER_SIZE) {
|
|
13157
|
+
process.stderr.write("[neuroverse] Warning: pipe buffer exceeded 1MB, resetting\n");
|
|
13158
|
+
buffer = "";
|
|
13159
|
+
return;
|
|
13160
|
+
}
|
|
12990
13161
|
const lines = buffer.split("\n");
|
|
12991
13162
|
buffer = lines.pop() ?? "";
|
|
12992
13163
|
for (const line of lines) {
|
|
@@ -13151,7 +13322,9 @@ var init_session = __esm({
|
|
|
13151
13322
|
init_plan_engine();
|
|
13152
13323
|
init_world_loader();
|
|
13153
13324
|
init_decision_flow_engine();
|
|
13154
|
-
SessionManager = class {
|
|
13325
|
+
SessionManager = class _SessionManager {
|
|
13326
|
+
/** Maximum unique agent IDs tracked before eviction. Prevents unbounded memory growth. */
|
|
13327
|
+
static MAX_AGENTS = 1e4;
|
|
13155
13328
|
config;
|
|
13156
13329
|
state;
|
|
13157
13330
|
engineOptions;
|
|
@@ -13215,6 +13388,16 @@ var init_session = __esm({
|
|
|
13215
13388
|
if (verdict.status === "REWARD" && verdict.reward) {
|
|
13216
13389
|
agentState = applyReward(agentState, verdict.reward, verdict.ruleId ?? "unknown");
|
|
13217
13390
|
}
|
|
13391
|
+
if (this.state.agentStates.size >= _SessionManager.MAX_AGENTS && !this.state.agentStates.has(event.roleId)) {
|
|
13392
|
+
const oldest = this.state.agentStates.keys().next().value;
|
|
13393
|
+
if (oldest !== void 0) {
|
|
13394
|
+
this.state.agentStates.delete(oldest);
|
|
13395
|
+
}
|
|
13396
|
+
process.stderr.write(
|
|
13397
|
+
`[neuroverse] Warning: agent state map at capacity (${_SessionManager.MAX_AGENTS}), evicted oldest entry
|
|
13398
|
+
`
|
|
13399
|
+
);
|
|
13400
|
+
}
|
|
13218
13401
|
this.state.agentStates.set(event.roleId, agentState);
|
|
13219
13402
|
}
|
|
13220
13403
|
this.config.onVerdict?.(verdict, event);
|
|
@@ -13368,8 +13551,15 @@ async function main18(args) {
|
|
|
13368
13551
|
const plan = planPath ? loadPlan(planPath) : autoDetectPlan();
|
|
13369
13552
|
const level = parseArg2(args, "--level");
|
|
13370
13553
|
const trace = hasFlag(args, "--trace");
|
|
13554
|
+
const logPath = parseArg2(args, "--log");
|
|
13371
13555
|
const isPipeMode = hasFlag(args, "--pipe") || !process.stdin.isTTY;
|
|
13372
13556
|
const isInteractive = hasFlag(args, "--interactive");
|
|
13557
|
+
let auditLogger;
|
|
13558
|
+
if (logPath) {
|
|
13559
|
+
auditLogger = new FileAuditLogger(logPath);
|
|
13560
|
+
process.stderr.write(`[neuroverse] Audit logging to ${logPath}
|
|
13561
|
+
`);
|
|
13562
|
+
}
|
|
13373
13563
|
if (isInteractive) {
|
|
13374
13564
|
const providerName = parseArg2(args, "--provider");
|
|
13375
13565
|
if (!providerName) {
|
|
@@ -13393,6 +13583,9 @@ async function main18(args) {
|
|
|
13393
13583
|
level,
|
|
13394
13584
|
trace,
|
|
13395
13585
|
onVerdict: (verdict, event) => {
|
|
13586
|
+
if (auditLogger) {
|
|
13587
|
+
auditLogger.log(verdictToAuditEvent(event, verdict));
|
|
13588
|
+
}
|
|
13396
13589
|
if (verdict.status !== "ALLOW") {
|
|
13397
13590
|
process.stderr.write(
|
|
13398
13591
|
` [${verdict.status}] ${event.intent} \u2014 ${verdict.reason ?? verdict.ruleId ?? "governance rule"}
|
|
@@ -13419,8 +13612,12 @@ async function main18(args) {
|
|
|
13419
13612
|
worldPath,
|
|
13420
13613
|
plan,
|
|
13421
13614
|
level,
|
|
13422
|
-
trace
|
|
13615
|
+
trace,
|
|
13616
|
+
onVerdict: auditLogger ? (verdict, event) => {
|
|
13617
|
+
auditLogger.log(verdictToAuditEvent(event, verdict));
|
|
13618
|
+
} : void 0
|
|
13423
13619
|
});
|
|
13620
|
+
if (auditLogger) await auditLogger.flush();
|
|
13424
13621
|
} else {
|
|
13425
13622
|
process.stdout.write(RUN_USAGE + "\n");
|
|
13426
13623
|
process.exit(0);
|
|
@@ -13433,6 +13630,7 @@ var init_run = __esm({
|
|
|
13433
13630
|
import_fs5 = require("fs");
|
|
13434
13631
|
import_path6 = require("path");
|
|
13435
13632
|
init_world_resolver();
|
|
13633
|
+
init_audit_logger();
|
|
13436
13634
|
RUN_USAGE = `
|
|
13437
13635
|
neuroverse run \u2014 Governed runtime for AI agents.
|
|
13438
13636
|
|
|
@@ -14224,27 +14422,27 @@ function computeWorldDiff(a, b) {
|
|
|
14224
14422
|
}
|
|
14225
14423
|
async function worldSnapshot(worldPath) {
|
|
14226
14424
|
const { readdir, readFile: readFile3, mkdir: mkdir2, writeFile: writeFile5 } = await import("fs/promises");
|
|
14227
|
-
const { join:
|
|
14425
|
+
const { join: join13 } = await import("path");
|
|
14228
14426
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19);
|
|
14229
|
-
const snapshotDir =
|
|
14427
|
+
const snapshotDir = join13(worldPath, ".snapshots", timestamp);
|
|
14230
14428
|
await mkdir2(snapshotDir, { recursive: true });
|
|
14231
14429
|
const files = await readdir(worldPath);
|
|
14232
14430
|
let copied = 0;
|
|
14233
14431
|
for (const file of files) {
|
|
14234
14432
|
if (file.endsWith(".json")) {
|
|
14235
|
-
const content = await readFile3(
|
|
14236
|
-
await writeFile5(
|
|
14433
|
+
const content = await readFile3(join13(worldPath, file), "utf-8");
|
|
14434
|
+
await writeFile5(join13(snapshotDir, file), content, "utf-8");
|
|
14237
14435
|
copied++;
|
|
14238
14436
|
}
|
|
14239
14437
|
}
|
|
14240
14438
|
try {
|
|
14241
|
-
const rulesDir =
|
|
14439
|
+
const rulesDir = join13(worldPath, "rules");
|
|
14242
14440
|
const ruleFiles = await readdir(rulesDir);
|
|
14243
|
-
await mkdir2(
|
|
14441
|
+
await mkdir2(join13(snapshotDir, "rules"), { recursive: true });
|
|
14244
14442
|
for (const file of ruleFiles) {
|
|
14245
14443
|
if (file.endsWith(".json")) {
|
|
14246
|
-
const content = await readFile3(
|
|
14247
|
-
await writeFile5(
|
|
14444
|
+
const content = await readFile3(join13(rulesDir, file), "utf-8");
|
|
14445
|
+
await writeFile5(join13(snapshotDir, "rules", file), content, "utf-8");
|
|
14248
14446
|
copied++;
|
|
14249
14447
|
}
|
|
14250
14448
|
}
|
|
@@ -14257,8 +14455,8 @@ async function worldSnapshot(worldPath) {
|
|
|
14257
14455
|
}
|
|
14258
14456
|
async function worldRollback(worldPath) {
|
|
14259
14457
|
const { readdir, readFile: readFile3, writeFile: writeFile5, mkdir: mkdir2 } = await import("fs/promises");
|
|
14260
|
-
const { join:
|
|
14261
|
-
const snapshotsDir =
|
|
14458
|
+
const { join: join13 } = await import("path");
|
|
14459
|
+
const snapshotsDir = join13(worldPath, ".snapshots");
|
|
14262
14460
|
let snapshots;
|
|
14263
14461
|
try {
|
|
14264
14462
|
snapshots = (await readdir(snapshotsDir)).sort();
|
|
@@ -14273,34 +14471,34 @@ async function worldRollback(worldPath) {
|
|
|
14273
14471
|
return;
|
|
14274
14472
|
}
|
|
14275
14473
|
const latest = snapshots[snapshots.length - 1];
|
|
14276
|
-
const snapshotDir =
|
|
14474
|
+
const snapshotDir = join13(snapshotsDir, latest);
|
|
14277
14475
|
const backupTimestamp = "pre-rollback-" + (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19);
|
|
14278
|
-
const backupDir =
|
|
14476
|
+
const backupDir = join13(snapshotsDir, backupTimestamp);
|
|
14279
14477
|
await mkdir2(backupDir, { recursive: true });
|
|
14280
14478
|
const currentFiles = await readdir(worldPath);
|
|
14281
14479
|
for (const file of currentFiles) {
|
|
14282
14480
|
if (file.endsWith(".json")) {
|
|
14283
|
-
const content = await readFile3(
|
|
14284
|
-
await writeFile5(
|
|
14481
|
+
const content = await readFile3(join13(worldPath, file), "utf-8");
|
|
14482
|
+
await writeFile5(join13(backupDir, file), content, "utf-8");
|
|
14285
14483
|
}
|
|
14286
14484
|
}
|
|
14287
14485
|
const snapshotFiles = await readdir(snapshotDir);
|
|
14288
14486
|
let restored = 0;
|
|
14289
14487
|
for (const file of snapshotFiles) {
|
|
14290
14488
|
if (file.endsWith(".json")) {
|
|
14291
|
-
const content = await readFile3(
|
|
14292
|
-
await writeFile5(
|
|
14489
|
+
const content = await readFile3(join13(snapshotDir, file), "utf-8");
|
|
14490
|
+
await writeFile5(join13(worldPath, file), content, "utf-8");
|
|
14293
14491
|
restored++;
|
|
14294
14492
|
}
|
|
14295
14493
|
}
|
|
14296
14494
|
try {
|
|
14297
|
-
const rulesDir =
|
|
14495
|
+
const rulesDir = join13(snapshotDir, "rules");
|
|
14298
14496
|
const ruleFiles = await readdir(rulesDir);
|
|
14299
|
-
await mkdir2(
|
|
14497
|
+
await mkdir2(join13(worldPath, "rules"), { recursive: true });
|
|
14300
14498
|
for (const file of ruleFiles) {
|
|
14301
14499
|
if (file.endsWith(".json")) {
|
|
14302
|
-
const content = await readFile3(
|
|
14303
|
-
await writeFile5(
|
|
14500
|
+
const content = await readFile3(join13(rulesDir, file), "utf-8");
|
|
14501
|
+
await writeFile5(join13(worldPath, "rules", file), content, "utf-8");
|
|
14304
14502
|
restored++;
|
|
14305
14503
|
}
|
|
14306
14504
|
}
|
|
@@ -14451,177 +14649,55 @@ Options:
|
|
|
14451
14649
|
}
|
|
14452
14650
|
});
|
|
14453
14651
|
|
|
14454
|
-
// src/
|
|
14455
|
-
|
|
14456
|
-
|
|
14457
|
-
|
|
14458
|
-
|
|
14459
|
-
|
|
14460
|
-
|
|
14461
|
-
|
|
14462
|
-
|
|
14463
|
-
|
|
14464
|
-
|
|
14465
|
-
|
|
14466
|
-
|
|
14467
|
-
|
|
14468
|
-
|
|
14469
|
-
|
|
14470
|
-
|
|
14471
|
-
|
|
14472
|
-
|
|
14473
|
-
|
|
14474
|
-
|
|
14475
|
-
|
|
14476
|
-
|
|
14477
|
-
|
|
14478
|
-
|
|
14479
|
-
|
|
14652
|
+
// src/cli/trace.ts
|
|
14653
|
+
var trace_exports = {};
|
|
14654
|
+
__export(trace_exports, {
|
|
14655
|
+
main: () => main20
|
|
14656
|
+
});
|
|
14657
|
+
function parseArgs16(argv) {
|
|
14658
|
+
const args = {};
|
|
14659
|
+
for (let i = 0; i < argv.length; i++) {
|
|
14660
|
+
const arg = argv[i];
|
|
14661
|
+
if (arg === "--summary") {
|
|
14662
|
+
args.summary = true;
|
|
14663
|
+
} else if (arg === "--json") {
|
|
14664
|
+
args.json = true;
|
|
14665
|
+
} else if (arg === "--help" || arg === "-h") {
|
|
14666
|
+
args.help = true;
|
|
14667
|
+
} else if (arg === "--log" && argv[i + 1]) {
|
|
14668
|
+
args.log = argv[++i];
|
|
14669
|
+
} else if (arg === "--filter" && argv[i + 1]) {
|
|
14670
|
+
args.filter = argv[++i].toUpperCase();
|
|
14671
|
+
} else if (arg === "--actor" && argv[i + 1]) {
|
|
14672
|
+
args.actor = argv[++i];
|
|
14673
|
+
} else if (arg === "--intent" && argv[i + 1]) {
|
|
14674
|
+
args.intent = argv[++i];
|
|
14675
|
+
} else if (arg === "--last" && argv[i + 1]) {
|
|
14676
|
+
args.last = argv[++i];
|
|
14677
|
+
}
|
|
14480
14678
|
}
|
|
14481
|
-
|
|
14482
|
-
|
|
14679
|
+
return args;
|
|
14680
|
+
}
|
|
14681
|
+
function formatEvent(event) {
|
|
14682
|
+
const ts = event.timestamp.split("T")[1]?.replace("Z", "").slice(0, 8) ?? event.timestamp;
|
|
14683
|
+
const icon = event.decision === "ALLOW" ? " \u2713" : event.decision === "BLOCK" ? " \u2717" : " \u23F8";
|
|
14684
|
+
const parts = [];
|
|
14685
|
+
parts.push(` [${ts}] ${event.actor ?? "unknown"}`);
|
|
14686
|
+
parts.push(` Action: ${event.intent}${event.tool ? ` (tool: ${event.tool})` : ""}`);
|
|
14687
|
+
parts.push(` Result:${icon} ${event.decision}`);
|
|
14688
|
+
if (event.guardsMatched.length > 0) {
|
|
14689
|
+
parts.push(` Guards: ${event.guardsMatched.join(", ")}`);
|
|
14483
14690
|
}
|
|
14484
|
-
if (
|
|
14485
|
-
|
|
14486
|
-
auditEvent.finalAction = verdict.intentRecord.finalAction;
|
|
14691
|
+
if (event.rulesMatched.length > 0) {
|
|
14692
|
+
parts.push(` Rules: ${event.rulesMatched.join(", ")}`);
|
|
14487
14693
|
}
|
|
14488
|
-
|
|
14489
|
-
}
|
|
14490
|
-
async function readAuditLog(logPath, filter) {
|
|
14491
|
-
const { readFile: readFile3 } = await import("fs/promises");
|
|
14492
|
-
let content;
|
|
14493
|
-
try {
|
|
14494
|
-
content = await readFile3(logPath, "utf-8");
|
|
14495
|
-
} catch {
|
|
14496
|
-
return [];
|
|
14694
|
+
if (event.reason) {
|
|
14695
|
+
parts.push(` Reason: ${event.reason}`);
|
|
14497
14696
|
}
|
|
14498
|
-
|
|
14499
|
-
|
|
14500
|
-
const trimmed = line.trim();
|
|
14501
|
-
if (!trimmed) continue;
|
|
14502
|
-
try {
|
|
14503
|
-
const event = JSON.parse(trimmed);
|
|
14504
|
-
if (!filter || filter(event)) {
|
|
14505
|
-
events.push(event);
|
|
14506
|
-
}
|
|
14507
|
-
} catch {
|
|
14508
|
-
}
|
|
14697
|
+
if (event.warning) {
|
|
14698
|
+
parts.push(` Warning: ${event.warning}`);
|
|
14509
14699
|
}
|
|
14510
|
-
return
|
|
14511
|
-
}
|
|
14512
|
-
function summarizeAuditEvents(events) {
|
|
14513
|
-
const allowed = events.filter((e) => e.decision === "ALLOW").length;
|
|
14514
|
-
const blocked = events.filter((e) => e.decision === "BLOCK").length;
|
|
14515
|
-
const paused = events.filter((e) => e.decision === "PAUSE").length;
|
|
14516
|
-
const modified = events.filter((e) => e.decision === "MODIFY").length;
|
|
14517
|
-
const penalized = events.filter((e) => e.decision === "PENALIZE").length;
|
|
14518
|
-
const rewarded = events.filter((e) => e.decision === "REWARD").length;
|
|
14519
|
-
const neutral = events.filter((e) => e.decision === "NEUTRAL").length;
|
|
14520
|
-
const actorSet = /* @__PURE__ */ new Set();
|
|
14521
|
-
for (const e of events) {
|
|
14522
|
-
if (e.actor) actorSet.add(e.actor);
|
|
14523
|
-
}
|
|
14524
|
-
const intentMap = /* @__PURE__ */ new Map();
|
|
14525
|
-
for (const e of events) {
|
|
14526
|
-
const entry = intentMap.get(e.intent) ?? { count: 0, blocked: 0, paused: 0, penalized: 0, rewarded: 0 };
|
|
14527
|
-
entry.count++;
|
|
14528
|
-
if (e.decision === "BLOCK") entry.blocked++;
|
|
14529
|
-
if (e.decision === "PAUSE") entry.paused++;
|
|
14530
|
-
if (e.decision === "PENALIZE") entry.penalized++;
|
|
14531
|
-
if (e.decision === "REWARD") entry.rewarded++;
|
|
14532
|
-
intentMap.set(e.intent, entry);
|
|
14533
|
-
}
|
|
14534
|
-
const topIntents = [...intentMap.entries()].map(([intent, data]) => ({ intent, ...data })).sort((a, b) => b.count - a.count);
|
|
14535
|
-
const ruleMap = /* @__PURE__ */ new Map();
|
|
14536
|
-
for (const e of events) {
|
|
14537
|
-
if (e.ruleId) {
|
|
14538
|
-
ruleMap.set(e.ruleId, (ruleMap.get(e.ruleId) ?? 0) + 1);
|
|
14539
|
-
}
|
|
14540
|
-
for (const g of e.guardsMatched) {
|
|
14541
|
-
ruleMap.set(g, (ruleMap.get(g) ?? 0) + 1);
|
|
14542
|
-
}
|
|
14543
|
-
}
|
|
14544
|
-
const topRules = [...ruleMap.entries()].map(([ruleId, count]) => ({ ruleId, count })).sort((a, b) => b.count - a.count);
|
|
14545
|
-
const redirected = blocked + paused + modified + penalized;
|
|
14546
|
-
const total = events.length;
|
|
14547
|
-
return {
|
|
14548
|
-
totalActions: total,
|
|
14549
|
-
allowed,
|
|
14550
|
-
blocked,
|
|
14551
|
-
paused,
|
|
14552
|
-
modified,
|
|
14553
|
-
penalized,
|
|
14554
|
-
rewarded,
|
|
14555
|
-
neutral,
|
|
14556
|
-
actors: [...actorSet],
|
|
14557
|
-
topIntents,
|
|
14558
|
-
topRules,
|
|
14559
|
-
firstEvent: events[0]?.timestamp ?? "",
|
|
14560
|
-
lastEvent: events[events.length - 1]?.timestamp ?? "",
|
|
14561
|
-
behavioralEconomy: {
|
|
14562
|
-
totalPenalties: penalized,
|
|
14563
|
-
totalRewards: rewarded,
|
|
14564
|
-
netPressure: rewarded - penalized,
|
|
14565
|
-
redirectionRate: total > 0 ? redirected / total : 0
|
|
14566
|
-
}
|
|
14567
|
-
};
|
|
14568
|
-
}
|
|
14569
|
-
var init_audit_logger = __esm({
|
|
14570
|
-
"src/engine/audit-logger.ts"() {
|
|
14571
|
-
"use strict";
|
|
14572
|
-
init_guard_engine();
|
|
14573
|
-
}
|
|
14574
|
-
});
|
|
14575
|
-
|
|
14576
|
-
// src/cli/trace.ts
|
|
14577
|
-
var trace_exports = {};
|
|
14578
|
-
__export(trace_exports, {
|
|
14579
|
-
main: () => main20
|
|
14580
|
-
});
|
|
14581
|
-
function parseArgs16(argv) {
|
|
14582
|
-
const args = {};
|
|
14583
|
-
for (let i = 0; i < argv.length; i++) {
|
|
14584
|
-
const arg = argv[i];
|
|
14585
|
-
if (arg === "--summary") {
|
|
14586
|
-
args.summary = true;
|
|
14587
|
-
} else if (arg === "--json") {
|
|
14588
|
-
args.json = true;
|
|
14589
|
-
} else if (arg === "--help" || arg === "-h") {
|
|
14590
|
-
args.help = true;
|
|
14591
|
-
} else if (arg === "--log" && argv[i + 1]) {
|
|
14592
|
-
args.log = argv[++i];
|
|
14593
|
-
} else if (arg === "--filter" && argv[i + 1]) {
|
|
14594
|
-
args.filter = argv[++i].toUpperCase();
|
|
14595
|
-
} else if (arg === "--actor" && argv[i + 1]) {
|
|
14596
|
-
args.actor = argv[++i];
|
|
14597
|
-
} else if (arg === "--intent" && argv[i + 1]) {
|
|
14598
|
-
args.intent = argv[++i];
|
|
14599
|
-
} else if (arg === "--last" && argv[i + 1]) {
|
|
14600
|
-
args.last = argv[++i];
|
|
14601
|
-
}
|
|
14602
|
-
}
|
|
14603
|
-
return args;
|
|
14604
|
-
}
|
|
14605
|
-
function formatEvent(event) {
|
|
14606
|
-
const ts = event.timestamp.split("T")[1]?.replace("Z", "").slice(0, 8) ?? event.timestamp;
|
|
14607
|
-
const icon = event.decision === "ALLOW" ? " \u2713" : event.decision === "BLOCK" ? " \u2717" : " \u23F8";
|
|
14608
|
-
const parts = [];
|
|
14609
|
-
parts.push(` [${ts}] ${event.actor ?? "unknown"}`);
|
|
14610
|
-
parts.push(` Action: ${event.intent}${event.tool ? ` (tool: ${event.tool})` : ""}`);
|
|
14611
|
-
parts.push(` Result:${icon} ${event.decision}`);
|
|
14612
|
-
if (event.guardsMatched.length > 0) {
|
|
14613
|
-
parts.push(` Guards: ${event.guardsMatched.join(", ")}`);
|
|
14614
|
-
}
|
|
14615
|
-
if (event.rulesMatched.length > 0) {
|
|
14616
|
-
parts.push(` Rules: ${event.rulesMatched.join(", ")}`);
|
|
14617
|
-
}
|
|
14618
|
-
if (event.reason) {
|
|
14619
|
-
parts.push(` Reason: ${event.reason}`);
|
|
14620
|
-
}
|
|
14621
|
-
if (event.warning) {
|
|
14622
|
-
parts.push(` Warning: ${event.warning}`);
|
|
14623
|
-
}
|
|
14624
|
-
return parts.join("\n");
|
|
14700
|
+
return parts.join("\n");
|
|
14625
14701
|
}
|
|
14626
14702
|
function formatSummary(events) {
|
|
14627
14703
|
const summary2 = summarizeAuditEvents(events);
|
|
@@ -15596,12 +15672,590 @@ var init_equity_penalties = __esm({
|
|
|
15596
15672
|
}
|
|
15597
15673
|
});
|
|
15598
15674
|
|
|
15675
|
+
// src/cli/keygen.ts
|
|
15676
|
+
var keygen_exports = {};
|
|
15677
|
+
__export(keygen_exports, {
|
|
15678
|
+
main: () => main26
|
|
15679
|
+
});
|
|
15680
|
+
function parseArgs20(argv) {
|
|
15681
|
+
let output = (0, import_path8.join)((0, import_os2.homedir)(), ".neuroverse", "keys");
|
|
15682
|
+
let name = "neuroverse";
|
|
15683
|
+
let force = false;
|
|
15684
|
+
let help = false;
|
|
15685
|
+
for (let i = 0; i < argv.length; i++) {
|
|
15686
|
+
const arg = argv[i];
|
|
15687
|
+
if ((arg === "--output" || arg === "-o") && argv[i + 1]) {
|
|
15688
|
+
output = argv[++i];
|
|
15689
|
+
} else if ((arg === "--name" || arg === "-n") && argv[i + 1]) {
|
|
15690
|
+
name = argv[++i];
|
|
15691
|
+
} else if (arg === "--force") {
|
|
15692
|
+
force = true;
|
|
15693
|
+
} else if (arg === "--help" || arg === "-h") {
|
|
15694
|
+
help = true;
|
|
15695
|
+
}
|
|
15696
|
+
}
|
|
15697
|
+
return { output, name, force, help };
|
|
15698
|
+
}
|
|
15699
|
+
async function main26(argv = process.argv.slice(2)) {
|
|
15700
|
+
const args = parseArgs20(argv);
|
|
15701
|
+
if (args.help) {
|
|
15702
|
+
process.stdout.write(USAGE5 + "\n");
|
|
15703
|
+
return;
|
|
15704
|
+
}
|
|
15705
|
+
const pubPath = (0, import_path8.join)(args.output, `${args.name}.pub`);
|
|
15706
|
+
const keyPath = (0, import_path8.join)(args.output, `${args.name}.key`);
|
|
15707
|
+
if (!args.force && ((0, import_fs7.existsSync)(pubPath) || (0, import_fs7.existsSync)(keyPath))) {
|
|
15708
|
+
process.stderr.write(`Keys already exist at ${args.output}/${args.name}.*
|
|
15709
|
+
`);
|
|
15710
|
+
process.stderr.write("Use --force to overwrite.\n");
|
|
15711
|
+
process.exit(1);
|
|
15712
|
+
}
|
|
15713
|
+
const { publicKey, privateKey } = (0, import_crypto.generateKeyPairSync)("ed25519", {
|
|
15714
|
+
publicKeyEncoding: { type: "spki", format: "pem" },
|
|
15715
|
+
privateKeyEncoding: { type: "pkcs8", format: "pem" }
|
|
15716
|
+
});
|
|
15717
|
+
(0, import_fs7.mkdirSync)(args.output, { recursive: true });
|
|
15718
|
+
(0, import_fs7.writeFileSync)(pubPath, publicKey, "utf-8");
|
|
15719
|
+
(0, import_fs7.writeFileSync)(keyPath, privateKey, { encoding: "utf-8", mode: 384 });
|
|
15720
|
+
process.stdout.write(`Keypair generated:
|
|
15721
|
+
`);
|
|
15722
|
+
process.stdout.write(` Public: ${pubPath}
|
|
15723
|
+
`);
|
|
15724
|
+
process.stdout.write(` Private: ${keyPath}
|
|
15725
|
+
`);
|
|
15726
|
+
process.stdout.write(`
|
|
15727
|
+
Share the .pub file with anyone who needs to verify your worlds.
|
|
15728
|
+
`);
|
|
15729
|
+
process.stdout.write(`Keep the .key file secret.
|
|
15730
|
+
`);
|
|
15731
|
+
}
|
|
15732
|
+
var import_crypto, import_fs7, import_path8, import_os2, USAGE5;
|
|
15733
|
+
var init_keygen = __esm({
|
|
15734
|
+
"src/cli/keygen.ts"() {
|
|
15735
|
+
"use strict";
|
|
15736
|
+
import_crypto = require("crypto");
|
|
15737
|
+
import_fs7 = require("fs");
|
|
15738
|
+
import_path8 = require("path");
|
|
15739
|
+
import_os2 = require("os");
|
|
15740
|
+
USAGE5 = `
|
|
15741
|
+
neuroverse keygen \u2014 Generate Ed25519 signing keypair
|
|
15742
|
+
|
|
15743
|
+
Usage:
|
|
15744
|
+
neuroverse keygen [--output <dir>] [--name <name>]
|
|
15745
|
+
|
|
15746
|
+
Options:
|
|
15747
|
+
--output <dir> Key directory (default: ~/.neuroverse/keys/)
|
|
15748
|
+
--name <name> Key name (default: neuroverse)
|
|
15749
|
+
--force Overwrite existing keys
|
|
15750
|
+
|
|
15751
|
+
Examples:
|
|
15752
|
+
neuroverse keygen
|
|
15753
|
+
neuroverse keygen --name production --output ./keys/
|
|
15754
|
+
`.trim();
|
|
15755
|
+
}
|
|
15756
|
+
});
|
|
15757
|
+
|
|
15758
|
+
// src/cli/sign.ts
|
|
15759
|
+
var sign_exports = {};
|
|
15760
|
+
__export(sign_exports, {
|
|
15761
|
+
buildManifest: () => buildManifest,
|
|
15762
|
+
canonicalManifest: () => canonicalManifest,
|
|
15763
|
+
main: () => main27
|
|
15764
|
+
});
|
|
15765
|
+
function parseArgs21(argv) {
|
|
15766
|
+
let worldPath = "";
|
|
15767
|
+
let keyPath = (0, import_path9.join)((0, import_os3.homedir)(), ".neuroverse", "keys", "neuroverse.key");
|
|
15768
|
+
let help = false;
|
|
15769
|
+
for (let i = 0; i < argv.length; i++) {
|
|
15770
|
+
const arg = argv[i];
|
|
15771
|
+
if (arg === "--world" && argv[i + 1]) {
|
|
15772
|
+
worldPath = argv[++i];
|
|
15773
|
+
} else if (arg === "--key" && argv[i + 1]) {
|
|
15774
|
+
keyPath = argv[++i];
|
|
15775
|
+
} else if (arg === "--help" || arg === "-h") {
|
|
15776
|
+
help = true;
|
|
15777
|
+
}
|
|
15778
|
+
}
|
|
15779
|
+
return { worldPath, keyPath, help };
|
|
15780
|
+
}
|
|
15781
|
+
function collectFiles(dir, base) {
|
|
15782
|
+
const root = base ?? dir;
|
|
15783
|
+
const files = [];
|
|
15784
|
+
for (const entry of (0, import_fs8.readdirSync)(dir)) {
|
|
15785
|
+
if (entry === ".nv-signature.json") continue;
|
|
15786
|
+
const full = (0, import_path9.join)(dir, entry);
|
|
15787
|
+
const stat = (0, import_fs8.statSync)(full);
|
|
15788
|
+
if (stat.isDirectory()) {
|
|
15789
|
+
files.push(...collectFiles(full, root));
|
|
15790
|
+
} else {
|
|
15791
|
+
files.push((0, import_path9.relative)(root, full));
|
|
15792
|
+
}
|
|
15793
|
+
}
|
|
15794
|
+
return files.sort();
|
|
15795
|
+
}
|
|
15796
|
+
function buildManifest(worldPath) {
|
|
15797
|
+
const files = collectFiles(worldPath);
|
|
15798
|
+
const manifest = {};
|
|
15799
|
+
for (const file of files) {
|
|
15800
|
+
const content = (0, import_fs8.readFileSync)((0, import_path9.join)(worldPath, file));
|
|
15801
|
+
manifest[file] = (0, import_crypto2.createHash)("sha256").update(content).digest("hex");
|
|
15802
|
+
}
|
|
15803
|
+
return manifest;
|
|
15804
|
+
}
|
|
15805
|
+
function canonicalManifest(files) {
|
|
15806
|
+
const sorted = Object.keys(files).sort();
|
|
15807
|
+
return sorted.map((k) => `${k}:${files[k]}`).join("\n");
|
|
15808
|
+
}
|
|
15809
|
+
async function main27(argv = process.argv.slice(2)) {
|
|
15810
|
+
const args = parseArgs21(argv);
|
|
15811
|
+
if (args.help) {
|
|
15812
|
+
process.stdout.write(USAGE6 + "\n");
|
|
15813
|
+
return;
|
|
15814
|
+
}
|
|
15815
|
+
if (!args.worldPath) {
|
|
15816
|
+
process.stderr.write("Error: --world <dir> is required.\n");
|
|
15817
|
+
process.exit(1);
|
|
15818
|
+
}
|
|
15819
|
+
let privateKey;
|
|
15820
|
+
try {
|
|
15821
|
+
privateKey = (0, import_fs8.readFileSync)(args.keyPath, "utf-8");
|
|
15822
|
+
} catch {
|
|
15823
|
+
process.stderr.write(`Error: Cannot read private key at ${args.keyPath}
|
|
15824
|
+
`);
|
|
15825
|
+
process.stderr.write('Run "neuroverse keygen" to generate a keypair.\n');
|
|
15826
|
+
process.exit(1);
|
|
15827
|
+
return;
|
|
15828
|
+
}
|
|
15829
|
+
const files = buildManifest(args.worldPath);
|
|
15830
|
+
const canonical = canonicalManifest(files);
|
|
15831
|
+
const manifestHash = (0, import_crypto2.createHash)("sha256").update(canonical).digest("hex");
|
|
15832
|
+
const signature = (0, import_crypto2.sign)(null, Buffer.from(manifestHash), privateKey).toString("base64");
|
|
15833
|
+
const artifact = {
|
|
15834
|
+
signatureVersion: "1.0",
|
|
15835
|
+
signedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
15836
|
+
files,
|
|
15837
|
+
manifestHash,
|
|
15838
|
+
signature
|
|
15839
|
+
};
|
|
15840
|
+
const outPath = (0, import_path9.join)(args.worldPath, ".nv-signature.json");
|
|
15841
|
+
(0, import_fs8.writeFileSync)(outPath, JSON.stringify(artifact, null, 2) + "\n", "utf-8");
|
|
15842
|
+
process.stdout.write(`Signed ${Object.keys(files).length} files in ${args.worldPath}
|
|
15843
|
+
`);
|
|
15844
|
+
process.stdout.write(`Signature: ${outPath}
|
|
15845
|
+
`);
|
|
15846
|
+
}
|
|
15847
|
+
var import_crypto2, import_fs8, import_path9, import_os3, USAGE6;
|
|
15848
|
+
var init_sign = __esm({
|
|
15849
|
+
"src/cli/sign.ts"() {
|
|
15850
|
+
"use strict";
|
|
15851
|
+
import_crypto2 = require("crypto");
|
|
15852
|
+
import_fs8 = require("fs");
|
|
15853
|
+
import_path9 = require("path");
|
|
15854
|
+
import_os3 = require("os");
|
|
15855
|
+
USAGE6 = `
|
|
15856
|
+
neuroverse sign \u2014 Sign a world artifact
|
|
15857
|
+
|
|
15858
|
+
Usage:
|
|
15859
|
+
neuroverse sign --world <dir> [--key <path>]
|
|
15860
|
+
|
|
15861
|
+
Options:
|
|
15862
|
+
--world <dir> World directory to sign (required)
|
|
15863
|
+
--key <path> Private key path (default: ~/.neuroverse/keys/neuroverse.key)
|
|
15864
|
+
|
|
15865
|
+
Examples:
|
|
15866
|
+
neuroverse sign --world ./world/
|
|
15867
|
+
neuroverse sign --world ./world/ --key ./keys/production.key
|
|
15868
|
+
`.trim();
|
|
15869
|
+
}
|
|
15870
|
+
});
|
|
15871
|
+
|
|
15872
|
+
// src/cli/verify.ts
|
|
15873
|
+
var verify_exports = {};
|
|
15874
|
+
__export(verify_exports, {
|
|
15875
|
+
main: () => main28
|
|
15876
|
+
});
|
|
15877
|
+
function parseArgs22(argv) {
|
|
15878
|
+
let worldPath = "";
|
|
15879
|
+
let keyPath = (0, import_path10.join)((0, import_os4.homedir)(), ".neuroverse", "keys", "neuroverse.pub");
|
|
15880
|
+
let json = false;
|
|
15881
|
+
let help = false;
|
|
15882
|
+
for (let i = 0; i < argv.length; i++) {
|
|
15883
|
+
const arg = argv[i];
|
|
15884
|
+
if (arg === "--world" && argv[i + 1]) {
|
|
15885
|
+
worldPath = argv[++i];
|
|
15886
|
+
} else if (arg === "--key" && argv[i + 1]) {
|
|
15887
|
+
keyPath = argv[++i];
|
|
15888
|
+
} else if (arg === "--json") {
|
|
15889
|
+
json = true;
|
|
15890
|
+
} else if (arg === "--help" || arg === "-h") {
|
|
15891
|
+
help = true;
|
|
15892
|
+
}
|
|
15893
|
+
}
|
|
15894
|
+
return { worldPath, keyPath, json, help };
|
|
15895
|
+
}
|
|
15896
|
+
async function main28(argv = process.argv.slice(2)) {
|
|
15897
|
+
const args = parseArgs22(argv);
|
|
15898
|
+
if (args.help) {
|
|
15899
|
+
process.stdout.write(USAGE7 + "\n");
|
|
15900
|
+
return;
|
|
15901
|
+
}
|
|
15902
|
+
if (!args.worldPath) {
|
|
15903
|
+
process.stderr.write("Error: --world <dir> is required.\n");
|
|
15904
|
+
process.exit(1);
|
|
15905
|
+
}
|
|
15906
|
+
const result = {
|
|
15907
|
+
valid: false,
|
|
15908
|
+
worldPath: args.worldPath,
|
|
15909
|
+
fileCount: 0,
|
|
15910
|
+
errors: []
|
|
15911
|
+
};
|
|
15912
|
+
const sigPath = (0, import_path10.join)(args.worldPath, ".nv-signature.json");
|
|
15913
|
+
if (!(0, import_fs9.existsSync)(sigPath)) {
|
|
15914
|
+
result.errors.push("No .nv-signature.json found \u2014 world is unsigned.");
|
|
15915
|
+
outputResult(result, args.json);
|
|
15916
|
+
process.exit(1);
|
|
15917
|
+
}
|
|
15918
|
+
let artifact;
|
|
15919
|
+
try {
|
|
15920
|
+
artifact = JSON.parse((0, import_fs9.readFileSync)(sigPath, "utf-8"));
|
|
15921
|
+
} catch {
|
|
15922
|
+
result.errors.push("Cannot parse .nv-signature.json \u2014 file is corrupt.");
|
|
15923
|
+
outputResult(result, args.json);
|
|
15924
|
+
process.exit(1);
|
|
15925
|
+
return;
|
|
15926
|
+
}
|
|
15927
|
+
result.signedAt = artifact.signedAt;
|
|
15928
|
+
result.fileCount = Object.keys(artifact.files).length;
|
|
15929
|
+
let publicKey;
|
|
15930
|
+
try {
|
|
15931
|
+
publicKey = (0, import_fs9.readFileSync)(args.keyPath, "utf-8");
|
|
15932
|
+
} catch {
|
|
15933
|
+
result.errors.push(`Cannot read public key at ${args.keyPath}`);
|
|
15934
|
+
outputResult(result, args.json);
|
|
15935
|
+
process.exit(1);
|
|
15936
|
+
return;
|
|
15937
|
+
}
|
|
15938
|
+
const currentFiles = buildManifest(args.worldPath);
|
|
15939
|
+
for (const file of Object.keys(currentFiles)) {
|
|
15940
|
+
if (!(file in artifact.files)) {
|
|
15941
|
+
result.errors.push(`Added: ${file} (not in signature)`);
|
|
15942
|
+
}
|
|
15943
|
+
}
|
|
15944
|
+
for (const [file, hash] of Object.entries(artifact.files)) {
|
|
15945
|
+
if (!(file in currentFiles)) {
|
|
15946
|
+
result.errors.push(`Missing: ${file} (was in signature)`);
|
|
15947
|
+
} else if (currentFiles[file] !== hash) {
|
|
15948
|
+
result.errors.push(`Changed: ${file} (hash mismatch)`);
|
|
15949
|
+
}
|
|
15950
|
+
}
|
|
15951
|
+
if (result.errors.length > 0) {
|
|
15952
|
+
outputResult(result, args.json);
|
|
15953
|
+
process.exit(1);
|
|
15954
|
+
return;
|
|
15955
|
+
}
|
|
15956
|
+
const canonical = canonicalManifest(artifact.files);
|
|
15957
|
+
const manifestHash = (0, import_crypto3.createHash)("sha256").update(canonical).digest("hex");
|
|
15958
|
+
if (manifestHash !== artifact.manifestHash) {
|
|
15959
|
+
result.errors.push("Manifest hash mismatch \u2014 signature metadata is corrupt.");
|
|
15960
|
+
outputResult(result, args.json);
|
|
15961
|
+
process.exit(1);
|
|
15962
|
+
return;
|
|
15963
|
+
}
|
|
15964
|
+
const isValid = (0, import_crypto3.verify)(null, Buffer.from(manifestHash), publicKey, Buffer.from(artifact.signature, "base64"));
|
|
15965
|
+
if (!isValid) {
|
|
15966
|
+
result.errors.push("Signature verification failed \u2014 wrong key or tampered manifest.");
|
|
15967
|
+
outputResult(result, args.json);
|
|
15968
|
+
process.exit(1);
|
|
15969
|
+
return;
|
|
15970
|
+
}
|
|
15971
|
+
result.valid = true;
|
|
15972
|
+
outputResult(result, args.json);
|
|
15973
|
+
}
|
|
15974
|
+
function outputResult(result, json) {
|
|
15975
|
+
if (json) {
|
|
15976
|
+
process.stdout.write(JSON.stringify(result, null, 2) + "\n");
|
|
15977
|
+
return;
|
|
15978
|
+
}
|
|
15979
|
+
if (result.valid) {
|
|
15980
|
+
process.stdout.write(`VALID \u2014 ${result.fileCount} files verified
|
|
15981
|
+
`);
|
|
15982
|
+
process.stdout.write(` Signed at: ${result.signedAt}
|
|
15983
|
+
`);
|
|
15984
|
+
process.stdout.write(` World: ${result.worldPath}
|
|
15985
|
+
`);
|
|
15986
|
+
} else {
|
|
15987
|
+
process.stdout.write(`INVALID \u2014 signature verification failed
|
|
15988
|
+
`);
|
|
15989
|
+
for (const error of result.errors) {
|
|
15990
|
+
process.stdout.write(` ${error}
|
|
15991
|
+
`);
|
|
15992
|
+
}
|
|
15993
|
+
}
|
|
15994
|
+
}
|
|
15995
|
+
var import_crypto3, import_fs9, import_path10, import_os4, USAGE7;
|
|
15996
|
+
var init_verify = __esm({
|
|
15997
|
+
"src/cli/verify.ts"() {
|
|
15998
|
+
"use strict";
|
|
15999
|
+
import_crypto3 = require("crypto");
|
|
16000
|
+
import_fs9 = require("fs");
|
|
16001
|
+
import_path10 = require("path");
|
|
16002
|
+
import_os4 = require("os");
|
|
16003
|
+
init_sign();
|
|
16004
|
+
USAGE7 = `
|
|
16005
|
+
neuroverse verify \u2014 Verify a signed world artifact
|
|
16006
|
+
|
|
16007
|
+
Usage:
|
|
16008
|
+
neuroverse verify --world <dir> [--key <path>]
|
|
16009
|
+
|
|
16010
|
+
Options:
|
|
16011
|
+
--world <dir> World directory to verify (required)
|
|
16012
|
+
--key <path> Public key path (default: ~/.neuroverse/keys/neuroverse.pub)
|
|
16013
|
+
--json Output result as JSON
|
|
16014
|
+
|
|
16015
|
+
Exit codes:
|
|
16016
|
+
0 Valid \u2014 world matches signature
|
|
16017
|
+
1 Invalid \u2014 signature mismatch, tampered files, or missing signature
|
|
16018
|
+
|
|
16019
|
+
Examples:
|
|
16020
|
+
neuroverse verify --world ./world/
|
|
16021
|
+
neuroverse verify --world ./world/ --key ./keys/production.pub
|
|
16022
|
+
`.trim();
|
|
16023
|
+
}
|
|
16024
|
+
});
|
|
16025
|
+
|
|
16026
|
+
// src/cli/migrate.ts
|
|
16027
|
+
var migrate_exports = {};
|
|
16028
|
+
__export(migrate_exports, {
|
|
16029
|
+
LATEST_VERSION: () => LATEST_VERSION,
|
|
16030
|
+
main: () => main29
|
|
16031
|
+
});
|
|
16032
|
+
function detectVersion(worldPath) {
|
|
16033
|
+
const metaPath = (0, import_path11.join)(worldPath, "metadata.json");
|
|
16034
|
+
if ((0, import_fs10.existsSync)(metaPath)) {
|
|
16035
|
+
try {
|
|
16036
|
+
const meta = JSON.parse((0, import_fs10.readFileSync)(metaPath, "utf-8"));
|
|
16037
|
+
if (meta.schema_version) return meta.schema_version;
|
|
16038
|
+
} catch {
|
|
16039
|
+
}
|
|
16040
|
+
}
|
|
16041
|
+
return "1.0.0";
|
|
16042
|
+
}
|
|
16043
|
+
function compareVersions(a, b) {
|
|
16044
|
+
const pa = a.split(".").map(Number);
|
|
16045
|
+
const pb = b.split(".").map(Number);
|
|
16046
|
+
for (let i = 0; i < 3; i++) {
|
|
16047
|
+
if ((pa[i] ?? 0) < (pb[i] ?? 0)) return -1;
|
|
16048
|
+
if ((pa[i] ?? 0) > (pb[i] ?? 0)) return 1;
|
|
16049
|
+
}
|
|
16050
|
+
return 0;
|
|
16051
|
+
}
|
|
16052
|
+
function findMigrationPath(from, to) {
|
|
16053
|
+
const path = [];
|
|
16054
|
+
let current = from;
|
|
16055
|
+
while (compareVersions(current, to) < 0) {
|
|
16056
|
+
const next = MIGRATIONS.find((m) => m.from === current);
|
|
16057
|
+
if (!next) break;
|
|
16058
|
+
path.push(next);
|
|
16059
|
+
current = next.to;
|
|
16060
|
+
}
|
|
16061
|
+
return path;
|
|
16062
|
+
}
|
|
16063
|
+
function parseArgs23(argv) {
|
|
16064
|
+
let worldPath = "";
|
|
16065
|
+
let dryRun = false;
|
|
16066
|
+
let backup = false;
|
|
16067
|
+
let target = LATEST_VERSION;
|
|
16068
|
+
let json = false;
|
|
16069
|
+
let help = false;
|
|
16070
|
+
for (let i = 0; i < argv.length; i++) {
|
|
16071
|
+
const arg = argv[i];
|
|
16072
|
+
if (arg === "--world" && argv[i + 1]) {
|
|
16073
|
+
worldPath = argv[++i];
|
|
16074
|
+
} else if (arg === "--dry-run") {
|
|
16075
|
+
dryRun = true;
|
|
16076
|
+
} else if (arg === "--backup") {
|
|
16077
|
+
backup = true;
|
|
16078
|
+
} else if (arg === "--target" && argv[i + 1]) {
|
|
16079
|
+
target = argv[++i];
|
|
16080
|
+
} else if (arg === "--json") {
|
|
16081
|
+
json = true;
|
|
16082
|
+
} else if (arg === "--help" || arg === "-h") {
|
|
16083
|
+
help = true;
|
|
16084
|
+
}
|
|
16085
|
+
}
|
|
16086
|
+
return { worldPath, dryRun, backup, target, json, help };
|
|
16087
|
+
}
|
|
16088
|
+
async function main29(argv = process.argv.slice(2)) {
|
|
16089
|
+
const args = parseArgs23(argv);
|
|
16090
|
+
if (args.help) {
|
|
16091
|
+
process.stdout.write(USAGE8 + "\n");
|
|
16092
|
+
return;
|
|
16093
|
+
}
|
|
16094
|
+
if (!args.worldPath) {
|
|
16095
|
+
process.stderr.write("Error: --world <dir> is required.\n");
|
|
16096
|
+
process.exit(1);
|
|
16097
|
+
}
|
|
16098
|
+
const currentVersion = detectVersion(args.worldPath);
|
|
16099
|
+
const targetVersion = args.target;
|
|
16100
|
+
if (compareVersions(currentVersion, targetVersion) >= 0) {
|
|
16101
|
+
const plan2 = {
|
|
16102
|
+
currentVersion,
|
|
16103
|
+
targetVersion,
|
|
16104
|
+
migrations: [],
|
|
16105
|
+
changes: []
|
|
16106
|
+
};
|
|
16107
|
+
if (args.json) {
|
|
16108
|
+
process.stdout.write(JSON.stringify(plan2, null, 2) + "\n");
|
|
16109
|
+
} else {
|
|
16110
|
+
process.stdout.write(`World is already at version ${currentVersion} (target: ${targetVersion})
|
|
16111
|
+
`);
|
|
16112
|
+
process.stdout.write("No migrations needed.\n");
|
|
16113
|
+
}
|
|
16114
|
+
return;
|
|
16115
|
+
}
|
|
16116
|
+
const migrationPath = findMigrationPath(currentVersion, targetVersion);
|
|
16117
|
+
if (migrationPath.length === 0) {
|
|
16118
|
+
process.stderr.write(`No migration path from ${currentVersion} to ${targetVersion}
|
|
16119
|
+
`);
|
|
16120
|
+
process.exit(1);
|
|
16121
|
+
return;
|
|
16122
|
+
}
|
|
16123
|
+
if (args.dryRun) {
|
|
16124
|
+
const plan2 = {
|
|
16125
|
+
currentVersion,
|
|
16126
|
+
targetVersion,
|
|
16127
|
+
migrations: migrationPath.map((m) => ({ from: m.from, to: m.to, description: m.description })),
|
|
16128
|
+
changes: []
|
|
16129
|
+
};
|
|
16130
|
+
if (args.json) {
|
|
16131
|
+
process.stdout.write(JSON.stringify(plan2, null, 2) + "\n");
|
|
16132
|
+
} else {
|
|
16133
|
+
process.stdout.write(`Migration plan: ${currentVersion} \u2192 ${targetVersion}
|
|
16134
|
+
`);
|
|
16135
|
+
process.stdout.write(`Steps: ${migrationPath.length}
|
|
16136
|
+
|
|
16137
|
+
`);
|
|
16138
|
+
for (const m of migrationPath) {
|
|
16139
|
+
process.stdout.write(` ${m.from} \u2192 ${m.to}: ${m.description}
|
|
16140
|
+
`);
|
|
16141
|
+
}
|
|
16142
|
+
process.stdout.write("\nRun without --dry-run to apply.\n");
|
|
16143
|
+
}
|
|
16144
|
+
return;
|
|
16145
|
+
}
|
|
16146
|
+
if (args.backup) {
|
|
16147
|
+
const backupPath = args.worldPath + ".backup";
|
|
16148
|
+
(0, import_fs10.cpSync)(args.worldPath, backupPath, { recursive: true });
|
|
16149
|
+
process.stdout.write(`Backup created: ${backupPath}
|
|
16150
|
+
`);
|
|
16151
|
+
}
|
|
16152
|
+
const allChanges = [];
|
|
16153
|
+
for (const migration of migrationPath) {
|
|
16154
|
+
process.stdout.write(`Applying: ${migration.from} \u2192 ${migration.to} (${migration.description})
|
|
16155
|
+
`);
|
|
16156
|
+
const changes = migration.apply(args.worldPath);
|
|
16157
|
+
allChanges.push(...changes);
|
|
16158
|
+
for (const change of changes) {
|
|
16159
|
+
process.stdout.write(` ${change.action}: ${change.file} \u2014 ${change.description}
|
|
16160
|
+
`);
|
|
16161
|
+
}
|
|
16162
|
+
}
|
|
16163
|
+
const plan = {
|
|
16164
|
+
currentVersion,
|
|
16165
|
+
targetVersion,
|
|
16166
|
+
migrations: migrationPath.map((m) => ({ from: m.from, to: m.to, description: m.description })),
|
|
16167
|
+
changes: allChanges
|
|
16168
|
+
};
|
|
16169
|
+
if (args.json) {
|
|
16170
|
+
process.stdout.write(JSON.stringify(plan, null, 2) + "\n");
|
|
16171
|
+
}
|
|
16172
|
+
process.stdout.write(`
|
|
16173
|
+
Migration complete: ${currentVersion} \u2192 ${targetVersion} (${allChanges.length} changes)
|
|
16174
|
+
`);
|
|
16175
|
+
}
|
|
16176
|
+
var import_fs10, import_path11, USAGE8, MIGRATIONS, LATEST_VERSION;
|
|
16177
|
+
var init_migrate = __esm({
|
|
16178
|
+
"src/cli/migrate.ts"() {
|
|
16179
|
+
"use strict";
|
|
16180
|
+
import_fs10 = require("fs");
|
|
16181
|
+
import_path11 = require("path");
|
|
16182
|
+
USAGE8 = `
|
|
16183
|
+
neuroverse migrate \u2014 World schema version migration
|
|
16184
|
+
|
|
16185
|
+
Usage:
|
|
16186
|
+
neuroverse migrate --world <dir> [options]
|
|
16187
|
+
|
|
16188
|
+
Options:
|
|
16189
|
+
--world <dir> World directory to migrate (required)
|
|
16190
|
+
--dry-run Show what would change without modifying files
|
|
16191
|
+
--backup Copy original world to <dir>.backup before migrating
|
|
16192
|
+
--target <version> Target schema version (default: latest)
|
|
16193
|
+
--json Output migration plan as JSON
|
|
16194
|
+
|
|
16195
|
+
Examples:
|
|
16196
|
+
neuroverse migrate --world ./world/ --dry-run
|
|
16197
|
+
neuroverse migrate --world ./world/ --backup
|
|
16198
|
+
neuroverse migrate --world ./world/ --target 1.1.0
|
|
16199
|
+
`.trim();
|
|
16200
|
+
MIGRATIONS = [
|
|
16201
|
+
{
|
|
16202
|
+
from: "1.0.0",
|
|
16203
|
+
to: "1.1.0",
|
|
16204
|
+
description: "Add enforcement_level to world.json, normalize metadata fields",
|
|
16205
|
+
apply: (worldPath) => {
|
|
16206
|
+
const changes = [];
|
|
16207
|
+
const worldJsonPath = (0, import_path11.join)(worldPath, "world.json");
|
|
16208
|
+
if ((0, import_fs10.existsSync)(worldJsonPath)) {
|
|
16209
|
+
const world = JSON.parse((0, import_fs10.readFileSync)(worldJsonPath, "utf-8"));
|
|
16210
|
+
if (!world.enforcement_level) {
|
|
16211
|
+
world.enforcement_level = "standard";
|
|
16212
|
+
(0, import_fs10.writeFileSync)(worldJsonPath, JSON.stringify(world, null, 2) + "\n", "utf-8");
|
|
16213
|
+
changes.push({
|
|
16214
|
+
file: "world.json",
|
|
16215
|
+
action: "modified",
|
|
16216
|
+
description: 'Added enforcement_level: "standard"'
|
|
16217
|
+
});
|
|
16218
|
+
}
|
|
16219
|
+
}
|
|
16220
|
+
const metaPath = (0, import_path11.join)(worldPath, "metadata.json");
|
|
16221
|
+
if ((0, import_fs10.existsSync)(metaPath)) {
|
|
16222
|
+
const meta = JSON.parse((0, import_fs10.readFileSync)(metaPath, "utf-8"));
|
|
16223
|
+
let modified = false;
|
|
16224
|
+
if (meta.configurator_version && !meta.authoring_method) {
|
|
16225
|
+
meta.authoring_method = meta.configurator_version;
|
|
16226
|
+
delete meta.configurator_version;
|
|
16227
|
+
modified = true;
|
|
16228
|
+
}
|
|
16229
|
+
if (!meta.schema_version) {
|
|
16230
|
+
meta.schema_version = "1.1.0";
|
|
16231
|
+
modified = true;
|
|
16232
|
+
} else {
|
|
16233
|
+
meta.schema_version = "1.1.0";
|
|
16234
|
+
modified = true;
|
|
16235
|
+
}
|
|
16236
|
+
if (modified) {
|
|
16237
|
+
(0, import_fs10.writeFileSync)(metaPath, JSON.stringify(meta, null, 2) + "\n", "utf-8");
|
|
16238
|
+
changes.push({
|
|
16239
|
+
file: "metadata.json",
|
|
16240
|
+
action: "modified",
|
|
16241
|
+
description: "Normalized metadata fields, updated schema_version to 1.1.0"
|
|
16242
|
+
});
|
|
16243
|
+
}
|
|
16244
|
+
}
|
|
16245
|
+
return changes;
|
|
16246
|
+
}
|
|
16247
|
+
}
|
|
16248
|
+
];
|
|
16249
|
+
LATEST_VERSION = MIGRATIONS.length > 0 ? MIGRATIONS[MIGRATIONS.length - 1].to : "1.0.0";
|
|
16250
|
+
}
|
|
16251
|
+
});
|
|
16252
|
+
|
|
15599
16253
|
// src/cli/configure-ai.ts
|
|
15600
16254
|
var configure_ai_exports = {};
|
|
15601
16255
|
__export(configure_ai_exports, {
|
|
15602
|
-
main: () =>
|
|
16256
|
+
main: () => main30
|
|
15603
16257
|
});
|
|
15604
|
-
function
|
|
16258
|
+
function parseArgs24(argv) {
|
|
15605
16259
|
let provider;
|
|
15606
16260
|
let model;
|
|
15607
16261
|
let apiKey;
|
|
@@ -15626,9 +16280,9 @@ function parseArgs20(argv) {
|
|
|
15626
16280
|
}
|
|
15627
16281
|
return { provider, model, apiKey, endpoint, show, test };
|
|
15628
16282
|
}
|
|
15629
|
-
async function
|
|
16283
|
+
async function main30(argv = process.argv.slice(2)) {
|
|
15630
16284
|
try {
|
|
15631
|
-
const args =
|
|
16285
|
+
const args = parseArgs24(argv);
|
|
15632
16286
|
if (args.show) {
|
|
15633
16287
|
const config2 = await loadConfig();
|
|
15634
16288
|
if (!config2) {
|
|
@@ -15829,7 +16483,7 @@ var init_prompt_utils = __esm({
|
|
|
15829
16483
|
// src/cli/configure-world.ts
|
|
15830
16484
|
var configure_world_exports = {};
|
|
15831
16485
|
__export(configure_world_exports, {
|
|
15832
|
-
main: () =>
|
|
16486
|
+
main: () => main31
|
|
15833
16487
|
});
|
|
15834
16488
|
function metricToStateVariable(metric) {
|
|
15835
16489
|
const id = metric.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_|_$/g, "");
|
|
@@ -16247,15 +16901,15 @@ function generateWorld(state) {
|
|
|
16247
16901
|
return { worldJson, stateSchema, guardsJson, rules, gatesJson, invariants, outcomes, metadata };
|
|
16248
16902
|
}
|
|
16249
16903
|
async function writeWorld(outputDir, world) {
|
|
16250
|
-
const { mkdirSync:
|
|
16904
|
+
const { mkdirSync: mkdirSync5, existsSync: existsSync9 } = await import("fs");
|
|
16251
16905
|
const { writeFile: writeFile5 } = await import("fs/promises");
|
|
16252
|
-
const { join:
|
|
16906
|
+
const { join: join13 } = await import("path");
|
|
16253
16907
|
const files = [];
|
|
16254
|
-
if (!
|
|
16255
|
-
const rulesDir =
|
|
16256
|
-
if (!
|
|
16908
|
+
if (!existsSync9(outputDir)) mkdirSync5(outputDir, { recursive: true });
|
|
16909
|
+
const rulesDir = join13(outputDir, "rules");
|
|
16910
|
+
if (!existsSync9(rulesDir)) mkdirSync5(rulesDir, { recursive: true });
|
|
16257
16911
|
const writeJson = async (name, data) => {
|
|
16258
|
-
const path =
|
|
16912
|
+
const path = join13(outputDir, name);
|
|
16259
16913
|
await writeFile5(path, JSON.stringify(data, null, 2) + "\n", "utf-8");
|
|
16260
16914
|
files.push(path);
|
|
16261
16915
|
};
|
|
@@ -16267,13 +16921,13 @@ async function writeWorld(outputDir, world) {
|
|
|
16267
16921
|
await writeJson("outcomes.json", world.outcomes);
|
|
16268
16922
|
await writeJson("metadata.json", world.metadata);
|
|
16269
16923
|
for (const rule of world.rules) {
|
|
16270
|
-
const rulePath =
|
|
16924
|
+
const rulePath = join13(rulesDir, `${rule.id}.json`);
|
|
16271
16925
|
await writeFile5(rulePath, JSON.stringify(rule, null, 2) + "\n", "utf-8");
|
|
16272
16926
|
files.push(rulePath);
|
|
16273
16927
|
}
|
|
16274
16928
|
return files;
|
|
16275
16929
|
}
|
|
16276
|
-
function
|
|
16930
|
+
function parseArgs25(argv) {
|
|
16277
16931
|
let outputDir = "./world/";
|
|
16278
16932
|
for (let i = 0; i < argv.length; i++) {
|
|
16279
16933
|
const arg = argv[i];
|
|
@@ -16283,9 +16937,9 @@ function parseArgs21(argv) {
|
|
|
16283
16937
|
}
|
|
16284
16938
|
return { outputDir };
|
|
16285
16939
|
}
|
|
16286
|
-
async function
|
|
16940
|
+
async function main31(argv = process.argv.slice(2)) {
|
|
16287
16941
|
try {
|
|
16288
|
-
const args =
|
|
16942
|
+
const args = parseArgs25(argv);
|
|
16289
16943
|
const context = await phaseContext();
|
|
16290
16944
|
const guardState = await phaseGuard(context.domain);
|
|
16291
16945
|
const systemState = await phaseSystem(context.domain);
|
|
@@ -16354,7 +17008,7 @@ async function main27(argv = process.argv.slice(2)) {
|
|
|
16354
17008
|
}
|
|
16355
17009
|
async function phaseRefine(outputDir, world) {
|
|
16356
17010
|
const { writeFile: writeFile5 } = await import("fs/promises");
|
|
16357
|
-
const { join:
|
|
17011
|
+
const { join: join13 } = await import("path");
|
|
16358
17012
|
heading("Refinement: Thresholds & Collapse");
|
|
16359
17013
|
const primaryMetric = world.gatesJson.viability_classification[0]?.field || "system_health";
|
|
16360
17014
|
info(`
|
|
@@ -16371,7 +17025,7 @@ async function phaseRefine(outputDir, world) {
|
|
|
16371
17025
|
if (!isNaN(parsed)) gate.value = parsed;
|
|
16372
17026
|
}
|
|
16373
17027
|
await writeFile5(
|
|
16374
|
-
|
|
17028
|
+
join13(outputDir, "gates.json"),
|
|
16375
17029
|
JSON.stringify(world.gatesJson, null, 2) + "\n",
|
|
16376
17030
|
"utf-8"
|
|
16377
17031
|
);
|
|
@@ -16393,7 +17047,7 @@ async function phaseRefine(outputDir, world) {
|
|
|
16393
17047
|
result: "MODEL_COLLAPSES"
|
|
16394
17048
|
};
|
|
16395
17049
|
await writeFile5(
|
|
16396
|
-
|
|
17050
|
+
join13(outputDir, "rules", `${rule.id}.json`),
|
|
16397
17051
|
JSON.stringify(rule, null, 2) + "\n",
|
|
16398
17052
|
"utf-8"
|
|
16399
17053
|
);
|
|
@@ -17127,7 +17781,7 @@ var init_lens = __esm({
|
|
|
17127
17781
|
// src/cli/lens.ts
|
|
17128
17782
|
var lens_exports = {};
|
|
17129
17783
|
__export(lens_exports, {
|
|
17130
|
-
main: () =>
|
|
17784
|
+
main: () => main32
|
|
17131
17785
|
});
|
|
17132
17786
|
async function cmdList(argv) {
|
|
17133
17787
|
let worldPath = "";
|
|
@@ -17387,9 +18041,9 @@ async function cmdAdd(argv) {
|
|
|
17387
18041
|
id = name.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_|_$/g, "");
|
|
17388
18042
|
}
|
|
17389
18043
|
const { readFile: readFile3, writeFile: writeFile5 } = await import("fs/promises");
|
|
17390
|
-
const { join:
|
|
18044
|
+
const { join: join13 } = await import("path");
|
|
17391
18045
|
const possiblePaths = [
|
|
17392
|
-
|
|
18046
|
+
join13(worldPath, "world.nv-world.md"),
|
|
17393
18047
|
worldPath
|
|
17394
18048
|
];
|
|
17395
18049
|
let mdPath = "";
|
|
@@ -17410,7 +18064,7 @@ async function cmdAdd(argv) {
|
|
|
17410
18064
|
const files = await readdir(worldPath);
|
|
17411
18065
|
const mdFile = files.find((f) => f.endsWith(".nv-world.md"));
|
|
17412
18066
|
if (mdFile) {
|
|
17413
|
-
mdPath =
|
|
18067
|
+
mdPath = join13(worldPath, mdFile);
|
|
17414
18068
|
mdContent = await readFile3(mdPath, "utf-8");
|
|
17415
18069
|
}
|
|
17416
18070
|
} catch {
|
|
@@ -17460,7 +18114,7 @@ async function cmdAdd(argv) {
|
|
|
17460
18114
|
|
|
17461
18115
|
`);
|
|
17462
18116
|
}
|
|
17463
|
-
async function
|
|
18117
|
+
async function main32(argv = process.argv.slice(2)) {
|
|
17464
18118
|
const subcommand = argv[0];
|
|
17465
18119
|
const subArgs = argv.slice(1);
|
|
17466
18120
|
try {
|
|
@@ -17538,7 +18192,7 @@ Examples:
|
|
|
17538
18192
|
});
|
|
17539
18193
|
|
|
17540
18194
|
// src/cli/neuroverse.ts
|
|
17541
|
-
var
|
|
18195
|
+
var USAGE9 = `
|
|
17542
18196
|
neuroverse \u2014 Turn ideas into worlds.
|
|
17543
18197
|
|
|
17544
18198
|
Commands:
|
|
@@ -17566,6 +18220,10 @@ Commands:
|
|
|
17566
18220
|
decision-flow Intent \u2192 Rule \u2192 Outcome visualization (behavioral governance)
|
|
17567
18221
|
equity-penalties Fortune 500 equity PENALIZE/REWARD simulation
|
|
17568
18222
|
world World management (status, diff, snapshot, rollback)
|
|
18223
|
+
keygen Generate Ed25519 signing keypair
|
|
18224
|
+
sign Sign a world artifact (cryptographic manifest)
|
|
18225
|
+
verify Verify a signed world artifact
|
|
18226
|
+
migrate Migrate world schema between versions
|
|
17569
18227
|
derive AI-assisted synthesis of .nv-world.md from markdown
|
|
17570
18228
|
bootstrap Compile .nv-world.md \u2192 world JSON files
|
|
17571
18229
|
configure-ai Configure AI provider credentials
|
|
@@ -17603,6 +18261,10 @@ Usage:
|
|
|
17603
18261
|
neuroverse equity-penalties --world <dir> [--agents N] [--rounds N] [--json]
|
|
17604
18262
|
neuroverse configure-ai --provider <name> --model <name> --api-key <key>
|
|
17605
18263
|
neuroverse configure-world [--output <dir>]
|
|
18264
|
+
neuroverse keygen [--output <dir>] [--name <name>]
|
|
18265
|
+
neuroverse sign --world <dir> [--key <path>]
|
|
18266
|
+
neuroverse verify --world <dir> [--key <path>]
|
|
18267
|
+
neuroverse migrate --world <dir> [--dry-run] [--backup]
|
|
17606
18268
|
neuroverse lens list [--world <dir>] [--json]
|
|
17607
18269
|
neuroverse lens preview <id> [--world <dir>]
|
|
17608
18270
|
neuroverse lens compile <id,...> [--world <dir>] [--role <role>] [--json]
|
|
@@ -17631,7 +18293,7 @@ Examples:
|
|
|
17631
18293
|
neuroverse doctor
|
|
17632
18294
|
neuroverse playground --world ./world/
|
|
17633
18295
|
`.trim();
|
|
17634
|
-
async function
|
|
18296
|
+
async function main33() {
|
|
17635
18297
|
const args = process.argv.slice(2);
|
|
17636
18298
|
const command = args[0];
|
|
17637
18299
|
const subArgs = args.slice(1);
|
|
@@ -17744,6 +18406,22 @@ async function main29() {
|
|
|
17744
18406
|
const { main: equityPenaltiesMain } = await Promise.resolve().then(() => (init_equity_penalties(), equity_penalties_exports));
|
|
17745
18407
|
return equityPenaltiesMain(subArgs);
|
|
17746
18408
|
}
|
|
18409
|
+
case "keygen": {
|
|
18410
|
+
const { main: keygenMain } = await Promise.resolve().then(() => (init_keygen(), keygen_exports));
|
|
18411
|
+
return keygenMain(subArgs);
|
|
18412
|
+
}
|
|
18413
|
+
case "sign": {
|
|
18414
|
+
const { main: signMain } = await Promise.resolve().then(() => (init_sign(), sign_exports));
|
|
18415
|
+
return signMain(subArgs);
|
|
18416
|
+
}
|
|
18417
|
+
case "verify": {
|
|
18418
|
+
const { main: verifyMain } = await Promise.resolve().then(() => (init_verify(), verify_exports));
|
|
18419
|
+
return verifyMain(subArgs);
|
|
18420
|
+
}
|
|
18421
|
+
case "migrate": {
|
|
18422
|
+
const { main: migrateMain } = await Promise.resolve().then(() => (init_migrate(), migrate_exports));
|
|
18423
|
+
return migrateMain(subArgs);
|
|
18424
|
+
}
|
|
17747
18425
|
case "configure-ai": {
|
|
17748
18426
|
const { main: configureAiMain } = await Promise.resolve().then(() => (init_configure_ai(), configure_ai_exports));
|
|
17749
18427
|
return configureAiMain(subArgs);
|
|
@@ -17760,7 +18438,7 @@ async function main29() {
|
|
|
17760
18438
|
case "-h":
|
|
17761
18439
|
case "help":
|
|
17762
18440
|
case void 0: {
|
|
17763
|
-
process.stdout.write(
|
|
18441
|
+
process.stdout.write(USAGE9 + "\n");
|
|
17764
18442
|
process.exit(0);
|
|
17765
18443
|
break;
|
|
17766
18444
|
}
|
|
@@ -17768,12 +18446,12 @@ async function main29() {
|
|
|
17768
18446
|
process.stderr.write(`Unknown command: "${command}"
|
|
17769
18447
|
|
|
17770
18448
|
`);
|
|
17771
|
-
process.stdout.write(
|
|
18449
|
+
process.stdout.write(USAGE9 + "\n");
|
|
17772
18450
|
process.exit(1);
|
|
17773
18451
|
}
|
|
17774
18452
|
}
|
|
17775
18453
|
}
|
|
17776
|
-
|
|
18454
|
+
main33().catch((e) => {
|
|
17777
18455
|
process.stderr.write(`Fatal: ${e}
|
|
17778
18456
|
`);
|
|
17779
18457
|
process.exit(3);
|