@neuroverseos/governance 0.3.4 → 0.4.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 +280 -405
- package/dist/adapters/autoresearch.cjs +63 -9
- package/dist/adapters/autoresearch.d.cts +2 -1
- package/dist/adapters/autoresearch.d.ts +2 -1
- package/dist/adapters/autoresearch.js +3 -3
- package/dist/adapters/deep-agents.cjs +63 -9
- package/dist/adapters/deep-agents.d.cts +3 -2
- package/dist/adapters/deep-agents.d.ts +3 -2
- package/dist/adapters/deep-agents.js +3 -3
- package/dist/adapters/express.cjs +63 -9
- package/dist/adapters/express.d.cts +2 -1
- package/dist/adapters/express.d.ts +2 -1
- package/dist/adapters/express.js +3 -3
- package/dist/adapters/index.cjs +961 -9
- package/dist/adapters/index.d.cts +4 -2
- package/dist/adapters/index.d.ts +4 -2
- package/dist/adapters/index.js +54 -17
- package/dist/adapters/langchain.cjs +63 -9
- package/dist/adapters/langchain.d.cts +3 -2
- package/dist/adapters/langchain.d.ts +3 -2
- package/dist/adapters/langchain.js +3 -3
- package/dist/adapters/mentraos.cjs +2181 -0
- package/dist/adapters/mentraos.d.cts +319 -0
- package/dist/adapters/mentraos.d.ts +319 -0
- package/dist/adapters/mentraos.js +48 -0
- package/dist/adapters/openai.cjs +63 -9
- package/dist/adapters/openai.d.cts +3 -2
- package/dist/adapters/openai.d.ts +3 -2
- package/dist/adapters/openai.js +3 -3
- package/dist/adapters/openclaw.cjs +63 -9
- package/dist/adapters/openclaw.d.cts +3 -2
- package/dist/adapters/openclaw.d.ts +3 -2
- package/dist/adapters/openclaw.js +3 -3
- package/dist/{add-ROOZLU62.js → add-XSANI3FK.js} +1 -1
- package/dist/{behavioral-MJO34S6Q.js → behavioral-SLW7ALEK.js} +4 -4
- package/dist/{bootstrap-CQRZVOXK.js → bootstrap-2OW5ZLBL.js} +4 -4
- package/dist/bootstrap-contract-DcV6t-8M.d.cts +216 -0
- package/dist/bootstrap-contract-DcV6t-8M.d.ts +216 -0
- package/dist/browser.global.js +149 -5
- package/dist/{build-ZHPMX5AZ.js → build-EGBGZFIJ.js} +6 -6
- package/dist/{chunk-A7GKPPU7.js → chunk-2VAWP6FI.js} +1 -1
- package/dist/{chunk-3WQLXYTP.js → chunk-3AYKQHYI.js} +2 -2
- package/dist/{chunk-EMQDLDAF.js → chunk-3NZMMSOW.js} +80 -2
- package/dist/chunk-3S5AD4AB.js +421 -0
- package/dist/{chunk-VXHSMA3I.js → chunk-6CV4XG3J.js} +1 -1
- package/dist/{chunk-BNKJPUPQ.js → chunk-A7SHG75T.js} +2 -2
- package/dist/{chunk-U6U7EJZL.js → chunk-AV7XJJWK.js} +2 -2
- package/dist/{chunk-ZWI3NIXK.js → chunk-CYDMUJVZ.js} +54 -3
- package/dist/{chunk-F66BVUYB.js → chunk-DA5MHFRR.js} +3 -3
- package/dist/{chunk-YEKMVDWK.js → chunk-FHXXD2TI.js} +7 -7
- package/dist/{chunk-5TPFNWRU.js → chunk-FS2UUJJO.js} +3 -3
- package/dist/{chunk-4FLICVVA.js → chunk-FVOGUCB6.js} +2 -2
- package/dist/chunk-GTPV2XGO.js +893 -0
- package/dist/{chunk-CTZHONLA.js → chunk-I4RTIMLX.js} +2 -2
- package/dist/{chunk-B6OXJLJ5.js → chunk-J2IZBHXJ.js} +4 -4
- package/dist/{chunk-TG6SEF24.js → chunk-OQU65525.js} +1 -1
- package/dist/{chunk-QXBFT7NI.js → chunk-QMVQ6KPL.js} +2 -2
- package/dist/{chunk-G7DJ6VOD.js → chunk-RDA7ISWC.js} +2 -2
- package/dist/{chunk-O5ABKEA7.js → chunk-YJ34R5NB.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/{chunk-IS4WUH6Y.js → chunk-ZEIT2QLM.js} +4 -4
- package/dist/cli/neuroverse.cjs +4436 -1035
- 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-world-XU2COHOZ.js +705 -0
- package/dist/{decision-flow-M63D47LO.js → decision-flow-3K4D72G4.js} +2 -2
- package/dist/{demo-G43RLCPK.js → demo-6OQYWRR6.js} +4 -4
- package/dist/{derive-LMDUTXDD.js → derive-7Y7YWVLU.js} +5 -5
- package/dist/{doctor-6BC6X2VO.js → doctor-NHXI7OQW.js} +3 -1
- package/dist/engine/bootstrap-emitter.cjs +241 -0
- package/dist/engine/bootstrap-emitter.d.cts +27 -0
- package/dist/engine/bootstrap-emitter.d.ts +27 -0
- package/dist/{bootstrap-emitter-Q7UIJZ2O.js → engine/bootstrap-emitter.js} +2 -2
- package/dist/engine/bootstrap-parser.cjs +560 -0
- package/dist/engine/bootstrap-parser.d.cts +96 -0
- package/dist/engine/bootstrap-parser.d.ts +96 -0
- package/dist/{bootstrap-parser-EEF36XDU.js → engine/bootstrap-parser.js} +2 -2
- package/dist/engine/guard-engine.cjs +1116 -0
- package/dist/engine/guard-engine.d.cts +60 -0
- package/dist/engine/guard-engine.d.ts +60 -0
- package/dist/engine/guard-engine.js +12 -0
- package/dist/engine/simulate-engine.cjs +390 -0
- package/dist/engine/simulate-engine.d.cts +105 -0
- package/dist/engine/simulate-engine.d.ts +105 -0
- package/dist/engine/simulate-engine.js +9 -0
- package/dist/{equity-penalties-SG5IZQ7I.js → equity-penalties-NVBAB5WL.js} +4 -4
- package/dist/{explain-RHBU2GBR.js → explain-HDFN4ION.js} +1 -1
- package/dist/github-TIKTWOGU.js +27 -0
- package/dist/{guard-AEEJNWLD.js → guard-6KSCWT2W.js} +4 -4
- package/dist/{guard-contract-B7lplwm9.d.cts → guard-contract-C991HDZp.d.cts} +32 -309
- package/dist/{guard-contract-B7lplwm9.d.ts → guard-contract-hHjTTjtR.d.ts} +32 -309
- package/dist/{impact-3XVDSCBU.js → impact-WIAM66IH.js} +3 -3
- package/dist/{improve-TQP4ECSY.js → improve-2PWGGO5B.js} +3 -3
- package/dist/index.cjs +682 -14
- package/dist/index.d.cts +231 -423
- package/dist/index.d.ts +231 -423
- package/dist/index.js +81 -58
- package/dist/{init-FYPV4SST.js → init-TKIJDR7I.js} +5 -1
- package/dist/lens-MHMUDCMQ.js +1084 -0
- package/dist/{mcp-server-5Y3ZM7TV.js → mcp-server-TNIWZ7B5.js} +3 -3
- package/dist/{playground-VZBNPPBO.js → playground-3FLDGBET.js} +3 -3
- package/dist/{redteam-MZPZD3EF.js → redteam-HV6LMKEH.js} +3 -3
- package/dist/{session-JYOARW54.js → session-XZP2754M.js} +3 -3
- package/dist/{shared-C_zpdvBm.d.cts → shared-DGnn1jiS.d.cts} +1 -1
- package/dist/{shared-Cf7yxx4-.d.ts → shared-U405h52W.d.ts} +1 -1
- package/dist/{simulate-LJXYBC6M.js → simulate-VT437EEL.js} +17 -4
- package/dist/spatial/index.cjs +682 -0
- package/dist/spatial/index.d.cts +517 -0
- package/dist/spatial/index.d.ts +517 -0
- package/dist/spatial/index.js +633 -0
- package/dist/{test-BOOR4A5F.js → test-4WTX6RKQ.js} +3 -3
- package/dist/{trace-PKV4KX56.js → trace-2YDNAXMK.js} +2 -2
- package/dist/types.cjs +18 -0
- package/dist/types.d.cts +370 -0
- package/dist/types.d.ts +370 -0
- package/dist/types.js +0 -0
- package/dist/{validate-RALX7CZS.js → validate-M52DX22Y.js} +1 -1
- package/dist/{world-BIP4GZBZ.js → world-O4HTQPDP.js} +1 -1
- package/dist/{world-loader-Y6HMQH2D.js → world-loader-YTYFOP7D.js} +1 -1
- package/dist/worlds/mentraos-smartglasses.nv-world.md +423 -0
- package/dist/worlds/mentraos-spatial.nv-world.md +68 -0
- package/dist/worlds/user-rules.nv-world.md +328 -0
- package/package.json +46 -3
- package/dist/guard-engine-PNR6MHCM.js +0 -10
- package/dist/{configure-ai-5MP5DWTT.js → configure-ai-LL3VAPQW.js} +3 -3
package/dist/index.cjs
CHANGED
|
@@ -419,6 +419,67 @@ function parseValueLiteral(raw) {
|
|
|
419
419
|
if (!isNaN(num) && raw.trim() !== "") return num;
|
|
420
420
|
return raw;
|
|
421
421
|
}
|
|
422
|
+
function parseLenses(content, startLine, issues) {
|
|
423
|
+
const lenses = [];
|
|
424
|
+
const subSections = splitH2Sections(content, startLine);
|
|
425
|
+
for (const sub of subSections) {
|
|
426
|
+
const props = parseKeyValueBullets(sub.content);
|
|
427
|
+
const lineNum = sub.startLine;
|
|
428
|
+
const directives = [];
|
|
429
|
+
const lines = sub.content.split("\n");
|
|
430
|
+
let directiveIndex = 0;
|
|
431
|
+
for (let i = 0; i < lines.length; i++) {
|
|
432
|
+
const line = lines[i].trim();
|
|
433
|
+
if (line.startsWith(">")) {
|
|
434
|
+
const blockContent = line.slice(1).trim();
|
|
435
|
+
const colonIdx = blockContent.indexOf(":");
|
|
436
|
+
if (colonIdx > 0) {
|
|
437
|
+
const scope = blockContent.slice(0, colonIdx).trim();
|
|
438
|
+
let instruction = blockContent.slice(colonIdx + 1).trim();
|
|
439
|
+
for (let j = i + 1; j < lines.length; j++) {
|
|
440
|
+
const nextLine = lines[j].trim();
|
|
441
|
+
if (nextLine.startsWith(">")) {
|
|
442
|
+
const nextContent = nextLine.slice(1).trim();
|
|
443
|
+
const nextColon = nextContent.indexOf(":");
|
|
444
|
+
if (nextColon > 0 && !nextContent.slice(0, nextColon).includes(" ")) {
|
|
445
|
+
break;
|
|
446
|
+
}
|
|
447
|
+
instruction += " " + nextContent;
|
|
448
|
+
i = j;
|
|
449
|
+
} else {
|
|
450
|
+
break;
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
directives.push({
|
|
454
|
+
id: `${sub.name}_directive_${directiveIndex++}`,
|
|
455
|
+
scope,
|
|
456
|
+
instruction,
|
|
457
|
+
line: startLine + i
|
|
458
|
+
});
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
const tags = (props.tags ?? "").split(",").map((s) => s.trim()).filter(Boolean);
|
|
463
|
+
const defaultForRoles = (props.default_for_roles ?? props.roles ?? "").split(",").map((s) => s.trim()).filter(Boolean);
|
|
464
|
+
lenses.push({
|
|
465
|
+
id: sub.name,
|
|
466
|
+
name: props.name ?? sub.name,
|
|
467
|
+
tagline: props.tagline ?? "",
|
|
468
|
+
description: props.description ?? "",
|
|
469
|
+
tags,
|
|
470
|
+
formality: props.formality ?? "neutral",
|
|
471
|
+
verbosity: props.verbosity ?? "balanced",
|
|
472
|
+
emotion: props.emotion ?? "neutral",
|
|
473
|
+
confidence: props.confidence ?? "balanced",
|
|
474
|
+
defaultForRoles,
|
|
475
|
+
directives,
|
|
476
|
+
priority: props.priority ? parseInt(props.priority, 10) : 50,
|
|
477
|
+
stackable: props.stackable === "false" ? false : true,
|
|
478
|
+
line: lineNum
|
|
479
|
+
});
|
|
480
|
+
}
|
|
481
|
+
return lenses;
|
|
482
|
+
}
|
|
422
483
|
function parseWorldMarkdown(markdown) {
|
|
423
484
|
const issues = [];
|
|
424
485
|
const { frontmatter: fmRaw, sections } = splitSections(markdown);
|
|
@@ -456,8 +517,22 @@ function parseWorldMarkdown(markdown) {
|
|
|
456
517
|
}
|
|
457
518
|
const outcomesSection = findSection("Outcomes");
|
|
458
519
|
const outcomes = outcomesSection ? parseOutcomes(outcomesSection.content, outcomesSection.startLine, issues) : [];
|
|
520
|
+
const lensesSection = findSection("Lenses");
|
|
521
|
+
const lenses = lensesSection ? parseLenses(lensesSection.content, lensesSection.startLine, issues) : [];
|
|
522
|
+
let lensPolicy;
|
|
523
|
+
let lensLockPin;
|
|
524
|
+
if (lensesSection) {
|
|
525
|
+
const topContent = lensesSection.content.split(/^##\s/m)[0];
|
|
526
|
+
const topProps = parseKeyValueBullets(topContent);
|
|
527
|
+
if (topProps.policy === "locked" || topProps.policy === "role_default" || topProps.policy === "user_choice") {
|
|
528
|
+
lensPolicy = topProps.policy;
|
|
529
|
+
}
|
|
530
|
+
if (topProps.lock_pin) {
|
|
531
|
+
lensLockPin = topProps.lock_pin;
|
|
532
|
+
}
|
|
533
|
+
}
|
|
459
534
|
const parsedSections = sections.map((s) => s.name);
|
|
460
|
-
const knownSections = /* @__PURE__ */ new Set(["thesis", "invariants", "state", "assumptions", "rules", "gates", "outcomes"]);
|
|
535
|
+
const knownSections = /* @__PURE__ */ new Set(["thesis", "invariants", "state", "assumptions", "rules", "gates", "outcomes", "lenses"]);
|
|
461
536
|
for (const section of sections) {
|
|
462
537
|
if (!knownSections.has(section.name.toLowerCase())) {
|
|
463
538
|
issues.push({
|
|
@@ -483,7 +558,10 @@ function parseWorldMarkdown(markdown) {
|
|
|
483
558
|
assumptions,
|
|
484
559
|
rules,
|
|
485
560
|
gates,
|
|
486
|
-
outcomes
|
|
561
|
+
outcomes,
|
|
562
|
+
lenses,
|
|
563
|
+
lensPolicy,
|
|
564
|
+
lensLockPin
|
|
487
565
|
},
|
|
488
566
|
issues
|
|
489
567
|
};
|
|
@@ -655,6 +733,36 @@ function emitWorldDefinition(parsed) {
|
|
|
655
733
|
structural_indicators: rules.filter((r) => r.severity === "structural").map((r) => r.id)
|
|
656
734
|
}
|
|
657
735
|
};
|
|
736
|
+
const validScopes = /* @__PURE__ */ new Set(["response_framing", "language_style", "content_filtering", "value_emphasis", "behavior_shaping"]);
|
|
737
|
+
const lensConfigs = parsed.lenses.map((pl) => {
|
|
738
|
+
const directives = pl.directives.map((d) => ({
|
|
739
|
+
id: d.id,
|
|
740
|
+
scope: validScopes.has(d.scope) ? d.scope : "behavior_shaping",
|
|
741
|
+
instruction: d.instruction
|
|
742
|
+
}));
|
|
743
|
+
return {
|
|
744
|
+
id: pl.id,
|
|
745
|
+
name: pl.name,
|
|
746
|
+
tagline: pl.tagline,
|
|
747
|
+
description: pl.description,
|
|
748
|
+
tags: pl.tags,
|
|
749
|
+
tone: {
|
|
750
|
+
formality: pl.formality || "neutral",
|
|
751
|
+
verbosity: pl.verbosity || "balanced",
|
|
752
|
+
emotion: pl.emotion || "neutral",
|
|
753
|
+
confidence: pl.confidence || "balanced"
|
|
754
|
+
},
|
|
755
|
+
directives,
|
|
756
|
+
defaultForRoles: pl.defaultForRoles,
|
|
757
|
+
priority: pl.priority,
|
|
758
|
+
stackable: pl.stackable
|
|
759
|
+
};
|
|
760
|
+
});
|
|
761
|
+
const lensesConfig = lensConfigs.length > 0 ? {
|
|
762
|
+
lenses: lensConfigs,
|
|
763
|
+
...parsed.lensPolicy ? { policy: parsed.lensPolicy } : {},
|
|
764
|
+
...parsed.lensLockPin ? { lockPin: parsed.lensLockPin } : {}
|
|
765
|
+
} : void 0;
|
|
658
766
|
const metadata = {
|
|
659
767
|
format_version: "1.0.0",
|
|
660
768
|
created_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -669,6 +777,7 @@ function emitWorldDefinition(parsed) {
|
|
|
669
777
|
rules,
|
|
670
778
|
gates,
|
|
671
779
|
outcomes,
|
|
780
|
+
...lensesConfig ? { lenses: lensesConfig } : {},
|
|
672
781
|
metadata
|
|
673
782
|
};
|
|
674
783
|
return { world: worldDefinition, issues };
|
|
@@ -840,6 +949,9 @@ __export(index_exports, {
|
|
|
840
949
|
DERIVE_EXIT_CODES: () => DERIVE_EXIT_CODES,
|
|
841
950
|
FileAuditLogger: () => FileAuditLogger,
|
|
842
951
|
GUARD_EXIT_CODES: () => GUARD_EXIT_CODES,
|
|
952
|
+
GitHubGovernanceBlockedError: () => GitHubGovernanceBlockedError,
|
|
953
|
+
GitHubGovernor: () => GitHubGovernor,
|
|
954
|
+
GitHubWebhookHandler: () => GitHubWebhookHandler,
|
|
843
955
|
McpGovernanceServer: () => McpGovernanceServer,
|
|
844
956
|
ModelAdapter: () => ModelAdapter,
|
|
845
957
|
PLAN_EXIT_CODES: () => PLAN_EXIT_CODES,
|
|
@@ -859,6 +971,10 @@ __export(index_exports, {
|
|
|
859
971
|
classifyIntent: () => classifyIntent,
|
|
860
972
|
classifyIntentWithAI: () => classifyIntentWithAI,
|
|
861
973
|
createAgentState: () => createAgentState,
|
|
974
|
+
createGitHubGovernor: () => createGitHubGovernor,
|
|
975
|
+
createGitHubGovernorFromWorld: () => createGitHubGovernorFromWorld,
|
|
976
|
+
createGitHubWebhookHandler: () => createGitHubWebhookHandler,
|
|
977
|
+
createGitHubWebhookHandlerFromWorld: () => createGitHubWebhookHandlerFromWorld,
|
|
862
978
|
createGovernanceEngine: () => createGovernanceEngine,
|
|
863
979
|
createGovernor: () => createGovernor,
|
|
864
980
|
deriveWorld: () => deriveWorld,
|
|
@@ -873,6 +989,8 @@ __export(index_exports, {
|
|
|
873
989
|
explainWorld: () => explainWorld,
|
|
874
990
|
extractContentFields: () => extractContentFields,
|
|
875
991
|
extractWorldMarkdown: () => extractWorldMarkdown,
|
|
992
|
+
formatForActions: () => formatForActions,
|
|
993
|
+
formatPRComment: () => formatPRComment,
|
|
876
994
|
formatVerdict: () => formatVerdict,
|
|
877
995
|
formatVerdictOneLine: () => formatVerdictOneLine,
|
|
878
996
|
generateAdaptationNarrative: () => generateAdaptationNarrative,
|
|
@@ -910,6 +1028,7 @@ __export(index_exports, {
|
|
|
910
1028
|
tickAgentStates: () => tickAgentStates,
|
|
911
1029
|
validateWorld: () => validateWorld,
|
|
912
1030
|
verdictToAuditEvent: () => verdictToAuditEvent,
|
|
1031
|
+
verdictToEvent: () => verdictToEvent,
|
|
913
1032
|
writeTempWorld: () => writeTempWorld
|
|
914
1033
|
});
|
|
915
1034
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -1297,6 +1416,33 @@ function evaluateGuard(event, world, options = {}) {
|
|
|
1297
1416
|
let decidingId;
|
|
1298
1417
|
const guardsMatched = [];
|
|
1299
1418
|
const rulesMatched = [];
|
|
1419
|
+
if (options.emergencyOverride) {
|
|
1420
|
+
checkInvariantCoverage(world, invariantChecks);
|
|
1421
|
+
return buildVerdict(
|
|
1422
|
+
"ALLOW",
|
|
1423
|
+
void 0,
|
|
1424
|
+
"emergency-override",
|
|
1425
|
+
"Emergency override active \u2014 all governance rules suspended. Platform constraints still apply.",
|
|
1426
|
+
world,
|
|
1427
|
+
level,
|
|
1428
|
+
invariantChecks,
|
|
1429
|
+
guardsMatched,
|
|
1430
|
+
rulesMatched,
|
|
1431
|
+
includeTrace ? buildTrace(
|
|
1432
|
+
invariantChecks,
|
|
1433
|
+
safetyChecks,
|
|
1434
|
+
planCheckResult,
|
|
1435
|
+
roleChecks,
|
|
1436
|
+
guardChecks,
|
|
1437
|
+
kernelRuleChecks,
|
|
1438
|
+
levelChecks,
|
|
1439
|
+
"session-allowlist",
|
|
1440
|
+
"emergency-override",
|
|
1441
|
+
startTime
|
|
1442
|
+
) : void 0,
|
|
1443
|
+
event.intent
|
|
1444
|
+
);
|
|
1445
|
+
}
|
|
1300
1446
|
checkInvariantCoverage(world, invariantChecks);
|
|
1301
1447
|
if (event.roleId && options.agentStates) {
|
|
1302
1448
|
const agentState = options.agentStates.get(event.roleId);
|
|
@@ -1361,7 +1507,8 @@ function evaluateGuard(event, world, options = {}) {
|
|
|
1361
1507
|
decidingLayer,
|
|
1362
1508
|
decidingId,
|
|
1363
1509
|
startTime
|
|
1364
|
-
) : void 0
|
|
1510
|
+
) : void 0,
|
|
1511
|
+
event.intent
|
|
1365
1512
|
);
|
|
1366
1513
|
}
|
|
1367
1514
|
}
|
|
@@ -1390,7 +1537,8 @@ function evaluateGuard(event, world, options = {}) {
|
|
|
1390
1537
|
decidingLayer,
|
|
1391
1538
|
decidingId,
|
|
1392
1539
|
startTime
|
|
1393
|
-
) : void 0
|
|
1540
|
+
) : void 0,
|
|
1541
|
+
event.intent
|
|
1394
1542
|
);
|
|
1395
1543
|
}
|
|
1396
1544
|
if (options.plan) {
|
|
@@ -1425,7 +1573,8 @@ function evaluateGuard(event, world, options = {}) {
|
|
|
1425
1573
|
decidingLayer,
|
|
1426
1574
|
decidingId,
|
|
1427
1575
|
startTime
|
|
1428
|
-
) : void 0
|
|
1576
|
+
) : void 0,
|
|
1577
|
+
event.intent
|
|
1429
1578
|
);
|
|
1430
1579
|
}
|
|
1431
1580
|
}
|
|
@@ -1454,7 +1603,8 @@ function evaluateGuard(event, world, options = {}) {
|
|
|
1454
1603
|
decidingLayer,
|
|
1455
1604
|
decidingId,
|
|
1456
1605
|
startTime
|
|
1457
|
-
) : void 0
|
|
1606
|
+
) : void 0,
|
|
1607
|
+
event.intent
|
|
1458
1608
|
);
|
|
1459
1609
|
}
|
|
1460
1610
|
const guardVerdict = checkGuards(event, eventText, world, guardChecks, guardsMatched);
|
|
@@ -1492,7 +1642,8 @@ function evaluateGuard(event, world, options = {}) {
|
|
|
1492
1642
|
decidingLayer,
|
|
1493
1643
|
decidingId,
|
|
1494
1644
|
startTime
|
|
1495
|
-
) : void 0
|
|
1645
|
+
) : void 0,
|
|
1646
|
+
event.intent
|
|
1496
1647
|
);
|
|
1497
1648
|
verdict.intentRecord = intentRecord;
|
|
1498
1649
|
if (guardVerdict.consequence) verdict.consequence = guardVerdict.consequence;
|
|
@@ -1525,7 +1676,8 @@ function evaluateGuard(event, world, options = {}) {
|
|
|
1525
1676
|
decidingLayer,
|
|
1526
1677
|
decidingId,
|
|
1527
1678
|
startTime
|
|
1528
|
-
) : void 0
|
|
1679
|
+
) : void 0,
|
|
1680
|
+
event.intent
|
|
1529
1681
|
);
|
|
1530
1682
|
}
|
|
1531
1683
|
const levelVerdict = checkLevelConstraints(event, level, levelChecks);
|
|
@@ -1553,7 +1705,8 @@ function evaluateGuard(event, world, options = {}) {
|
|
|
1553
1705
|
decidingLayer,
|
|
1554
1706
|
decidingId,
|
|
1555
1707
|
startTime
|
|
1556
|
-
) : void 0
|
|
1708
|
+
) : void 0,
|
|
1709
|
+
event.intent
|
|
1557
1710
|
);
|
|
1558
1711
|
}
|
|
1559
1712
|
const warning = guardVerdict?.warning;
|
|
@@ -1578,7 +1731,8 @@ function evaluateGuard(event, world, options = {}) {
|
|
|
1578
1731
|
decidingLayer,
|
|
1579
1732
|
decidingId,
|
|
1580
1733
|
startTime
|
|
1581
|
-
) : void 0
|
|
1734
|
+
) : void 0,
|
|
1735
|
+
event.intent
|
|
1582
1736
|
);
|
|
1583
1737
|
}
|
|
1584
1738
|
function checkInvariantCoverage(world, checks) {
|
|
@@ -1955,7 +2109,7 @@ function buildTrace(invariantChecks, safetyChecks, planCheck, roleChecks, guardC
|
|
|
1955
2109
|
}
|
|
1956
2110
|
return trace;
|
|
1957
2111
|
}
|
|
1958
|
-
function buildVerdict(status, reason, ruleId, warning, world, level, invariantChecks, guardsMatched, rulesMatched, trace) {
|
|
2112
|
+
function buildVerdict(status, reason, ruleId, warning, world, level, invariantChecks, guardsMatched, rulesMatched, trace, eventIntent) {
|
|
1959
2113
|
const evidence = {
|
|
1960
2114
|
worldId: world.world.world_id,
|
|
1961
2115
|
worldName: world.world.name,
|
|
@@ -1975,8 +2129,27 @@ function buildVerdict(status, reason, ruleId, warning, world, level, invariantCh
|
|
|
1975
2129
|
if (ruleId) verdict.ruleId = ruleId;
|
|
1976
2130
|
if (warning) verdict.warning = warning;
|
|
1977
2131
|
if (trace) verdict.trace = trace;
|
|
2132
|
+
verdict.event = verdictToEvent(status, eventIntent);
|
|
1978
2133
|
return verdict;
|
|
1979
2134
|
}
|
|
2135
|
+
function verdictToEvent(status, intent) {
|
|
2136
|
+
const statusEventMap = {
|
|
2137
|
+
ALLOW: "action_allowed",
|
|
2138
|
+
BLOCK: "action_blocked",
|
|
2139
|
+
PAUSE: "action_paused",
|
|
2140
|
+
MODIFY: "action_modified",
|
|
2141
|
+
PENALIZE: "action_penalized",
|
|
2142
|
+
REWARD: "action_rewarded",
|
|
2143
|
+
NEUTRAL: "action_neutral"
|
|
2144
|
+
};
|
|
2145
|
+
return {
|
|
2146
|
+
type: intent || statusEventMap[status] || "unknown_action",
|
|
2147
|
+
actor: "agent",
|
|
2148
|
+
source: "guard",
|
|
2149
|
+
timestamp: Date.now(),
|
|
2150
|
+
guardStatus: status
|
|
2151
|
+
};
|
|
2152
|
+
}
|
|
1980
2153
|
|
|
1981
2154
|
// src/providers/ai-provider.ts
|
|
1982
2155
|
var ChatCompletionsProvider = class {
|
|
@@ -6663,15 +6836,25 @@ function simulateWorld(world, options = {}) {
|
|
|
6663
6836
|
let collapseStep;
|
|
6664
6837
|
let collapseRule;
|
|
6665
6838
|
const sortedRules = [...world.rules].sort((a, b) => a.order - b.order);
|
|
6839
|
+
const allEvents = options.events ?? [];
|
|
6840
|
+
const eventsByStep = Array.from({ length: steps }, () => []);
|
|
6841
|
+
for (let i = 0; i < allEvents.length; i++) {
|
|
6842
|
+
const stepIdx = Math.min(i, steps - 1);
|
|
6843
|
+
eventsByStep[stepIdx].push(allEvents[i]);
|
|
6844
|
+
}
|
|
6845
|
+
let totalEventsConsumed = 0;
|
|
6666
6846
|
for (let stepNum = 1; stepNum <= steps; stepNum++) {
|
|
6667
6847
|
if (collapsed) break;
|
|
6848
|
+
const stepEvents = eventsByStep[stepNum - 1];
|
|
6668
6849
|
const stepResult = evaluateStep(
|
|
6669
6850
|
stepNum,
|
|
6670
6851
|
sortedRules,
|
|
6671
6852
|
state,
|
|
6672
6853
|
assumptions,
|
|
6673
|
-
world
|
|
6854
|
+
world,
|
|
6855
|
+
stepEvents
|
|
6674
6856
|
);
|
|
6857
|
+
totalEventsConsumed += stepResult.eventsApplied.length;
|
|
6675
6858
|
simulationSteps.push(stepResult);
|
|
6676
6859
|
if (stepResult.collapsed) {
|
|
6677
6860
|
collapsed = true;
|
|
@@ -6690,14 +6873,38 @@ function simulateWorld(world, options = {}) {
|
|
|
6690
6873
|
finalViability,
|
|
6691
6874
|
collapsed,
|
|
6692
6875
|
collapseStep,
|
|
6693
|
-
collapseRule
|
|
6876
|
+
collapseRule,
|
|
6877
|
+
eventsConsumed: totalEventsConsumed
|
|
6694
6878
|
};
|
|
6695
6879
|
}
|
|
6696
|
-
function evaluateStep(stepNum, rules, state, assumptions, world) {
|
|
6880
|
+
function evaluateStep(stepNum, rules, state, assumptions, world, events = []) {
|
|
6697
6881
|
const evaluations = [];
|
|
6882
|
+
const eventApplications = [];
|
|
6698
6883
|
let rulesFired = 0;
|
|
6699
6884
|
let collapsed = false;
|
|
6700
6885
|
const firedRuleIds = /* @__PURE__ */ new Set();
|
|
6886
|
+
for (const evt of events) {
|
|
6887
|
+
const application = {
|
|
6888
|
+
eventType: evt.type,
|
|
6889
|
+
rulesTriggered: [],
|
|
6890
|
+
effects: []
|
|
6891
|
+
};
|
|
6892
|
+
for (const rule of rules) {
|
|
6893
|
+
const eventTrigger = rule.triggers.find(
|
|
6894
|
+
(t) => t.field === "event" && t.source === "state"
|
|
6895
|
+
);
|
|
6896
|
+
if (!eventTrigger) continue;
|
|
6897
|
+
const matches = evaluateOperator(evt.type, eventTrigger.operator, eventTrigger.value);
|
|
6898
|
+
if (!matches) continue;
|
|
6899
|
+
application.rulesTriggered.push(rule.id);
|
|
6900
|
+
firedRuleIds.add(rule.id);
|
|
6901
|
+
for (const effect of rule.effects ?? []) {
|
|
6902
|
+
const applied = applyEffect(effect, state);
|
|
6903
|
+
if (applied) application.effects.push(applied);
|
|
6904
|
+
}
|
|
6905
|
+
}
|
|
6906
|
+
eventApplications.push(application);
|
|
6907
|
+
}
|
|
6701
6908
|
for (const rule of rules) {
|
|
6702
6909
|
if (collapsed) {
|
|
6703
6910
|
evaluations.push({
|
|
@@ -6782,6 +6989,7 @@ function evaluateStep(stepNum, rules, state, assumptions, world) {
|
|
|
6782
6989
|
const viability = classifyViability(state, world);
|
|
6783
6990
|
return {
|
|
6784
6991
|
step: stepNum,
|
|
6992
|
+
eventsApplied: eventApplications,
|
|
6785
6993
|
rulesEvaluated: evaluations,
|
|
6786
6994
|
rulesFired,
|
|
6787
6995
|
stateAfter: { ...state },
|
|
@@ -6903,6 +7111,19 @@ function renderSimulateText(result) {
|
|
|
6903
7111
|
lines.push("");
|
|
6904
7112
|
for (const step of result.steps) {
|
|
6905
7113
|
lines.push(`STEP ${step.step}`);
|
|
7114
|
+
if (step.eventsApplied && step.eventsApplied.length > 0) {
|
|
7115
|
+
for (const evt of step.eventsApplied) {
|
|
7116
|
+
lines.push(` EVENT: ${evt.eventType}`);
|
|
7117
|
+
if (evt.rulesTriggered.length > 0) {
|
|
7118
|
+
lines.push(` Rules triggered: ${evt.rulesTriggered.join(", ")}`);
|
|
7119
|
+
}
|
|
7120
|
+
for (const effect of evt.effects) {
|
|
7121
|
+
const beforeStr = formatValue(effect.before);
|
|
7122
|
+
const afterStr = formatValue(effect.after);
|
|
7123
|
+
lines.push(` ${effect.target}: ${beforeStr} -> ${afterStr}`);
|
|
7124
|
+
}
|
|
7125
|
+
}
|
|
7126
|
+
}
|
|
6906
7127
|
const fired = step.rulesEvaluated.filter((r) => r.triggered);
|
|
6907
7128
|
const skipped = step.rulesEvaluated.filter((r) => !r.triggered && !r.excluded);
|
|
6908
7129
|
const excluded = step.rulesEvaluated.filter((r) => r.excluded);
|
|
@@ -6938,6 +7159,9 @@ function renderSimulateText(result) {
|
|
|
6938
7159
|
lines.push(` ${key}: ${formatValue(value)}${marker}`);
|
|
6939
7160
|
}
|
|
6940
7161
|
lines.push("");
|
|
7162
|
+
if (result.eventsConsumed > 0) {
|
|
7163
|
+
lines.push(`EVENTS CONSUMED: ${result.eventsConsumed}`);
|
|
7164
|
+
}
|
|
6941
7165
|
lines.push(`VIABILITY: ${result.finalViability}`);
|
|
6942
7166
|
if (result.collapsed) {
|
|
6943
7167
|
lines.push(`COLLAPSED at step ${result.collapseStep} (rule: ${result.collapseRule})`);
|
|
@@ -7588,6 +7812,440 @@ function round(n, decimals = 3) {
|
|
|
7588
7812
|
return Math.round(n * factor) / factor;
|
|
7589
7813
|
}
|
|
7590
7814
|
|
|
7815
|
+
// src/adapters/github.ts
|
|
7816
|
+
init_world_loader();
|
|
7817
|
+
|
|
7818
|
+
// src/adapters/shared.ts
|
|
7819
|
+
var GovernanceBlockedError = class extends Error {
|
|
7820
|
+
verdict;
|
|
7821
|
+
constructor(verdict, message) {
|
|
7822
|
+
super(message ?? `[NeuroVerse] BLOCKED: ${verdict.reason ?? verdict.ruleId ?? "governance rule"}`);
|
|
7823
|
+
this.name = "GovernanceBlockedError";
|
|
7824
|
+
this.verdict = verdict;
|
|
7825
|
+
}
|
|
7826
|
+
};
|
|
7827
|
+
function trackPlanProgress(event, state, callbacks) {
|
|
7828
|
+
if (!state.activePlan) return;
|
|
7829
|
+
const planVerdict = evaluatePlan(event, state.activePlan);
|
|
7830
|
+
if (planVerdict.matchedStep) {
|
|
7831
|
+
const advResult = advancePlan(state.activePlan, planVerdict.matchedStep);
|
|
7832
|
+
if (advResult.success && advResult.plan) {
|
|
7833
|
+
state.activePlan = advResult.plan;
|
|
7834
|
+
state.engineOptions.plan = state.activePlan;
|
|
7835
|
+
}
|
|
7836
|
+
const progress = getPlanProgress(state.activePlan);
|
|
7837
|
+
callbacks.onPlanProgress?.(progress);
|
|
7838
|
+
if (progress.completed === progress.total) {
|
|
7839
|
+
callbacks.onPlanComplete?.();
|
|
7840
|
+
}
|
|
7841
|
+
}
|
|
7842
|
+
}
|
|
7843
|
+
function buildEngineOptions(options, plan) {
|
|
7844
|
+
return {
|
|
7845
|
+
trace: options.trace ?? false,
|
|
7846
|
+
level: options.level,
|
|
7847
|
+
plan: plan ?? options.plan
|
|
7848
|
+
};
|
|
7849
|
+
}
|
|
7850
|
+
|
|
7851
|
+
// src/adapters/github.ts
|
|
7852
|
+
var GitHubGovernanceBlockedError = class extends GovernanceBlockedError {
|
|
7853
|
+
action;
|
|
7854
|
+
constructor(verdict, action) {
|
|
7855
|
+
super(verdict, `[NeuroVerse] GitHub action blocked: ${action.action} on ${action.repository}`);
|
|
7856
|
+
this.name = "GitHubGovernanceBlockedError";
|
|
7857
|
+
this.action = action;
|
|
7858
|
+
}
|
|
7859
|
+
};
|
|
7860
|
+
function extractBranch(ref) {
|
|
7861
|
+
if (!ref) return void 0;
|
|
7862
|
+
if (ref.startsWith("refs/heads/")) return ref.slice("refs/heads/".length);
|
|
7863
|
+
if (ref.startsWith("refs/tags/")) return ref.slice("refs/tags/".length);
|
|
7864
|
+
return ref;
|
|
7865
|
+
}
|
|
7866
|
+
function isProtectedBranch(branch, protectedBranches) {
|
|
7867
|
+
if (!branch) return false;
|
|
7868
|
+
return protectedBranches.some(
|
|
7869
|
+
(pb) => branch === pb || branch.startsWith(`${pb}/`)
|
|
7870
|
+
);
|
|
7871
|
+
}
|
|
7872
|
+
function defaultMapAction(action, protectedBranches, restrictedActors) {
|
|
7873
|
+
const branch = action.branch ?? extractBranch(action.ref);
|
|
7874
|
+
const isProtected = isProtectedBranch(branch, protectedBranches);
|
|
7875
|
+
const isRestricted = action.actor ? restrictedActors.some((ra) => action.actor === ra || action.actor?.endsWith("[bot]")) : false;
|
|
7876
|
+
let actionCategory = "other";
|
|
7877
|
+
const act = action.action.toLowerCase();
|
|
7878
|
+
if (act.includes("read") || act.includes("get") || act.includes("list") || act.includes("view")) {
|
|
7879
|
+
actionCategory = "read";
|
|
7880
|
+
} else if (act.includes("delete") || act.includes("remove") || act.includes("close")) {
|
|
7881
|
+
actionCategory = "delete";
|
|
7882
|
+
} else if (act.includes("deploy") || act.includes("run") || act.includes("execute") || act.includes("merge")) {
|
|
7883
|
+
actionCategory = "network";
|
|
7884
|
+
} else if (act.includes("create") || act.includes("push") || act.includes("write") || act.includes("update") || act.includes("edit")) {
|
|
7885
|
+
actionCategory = "write";
|
|
7886
|
+
} else if (act.includes("comment") || act.includes("review") || act.includes("notify")) {
|
|
7887
|
+
actionCategory = "other";
|
|
7888
|
+
}
|
|
7889
|
+
return {
|
|
7890
|
+
intent: action.action,
|
|
7891
|
+
tool: "github",
|
|
7892
|
+
scope: `${action.repository}${branch ? `@${branch}` : ""}`,
|
|
7893
|
+
actionCategory,
|
|
7894
|
+
direction: "input",
|
|
7895
|
+
args: {
|
|
7896
|
+
repository: action.repository,
|
|
7897
|
+
ref: action.ref,
|
|
7898
|
+
branch,
|
|
7899
|
+
actor: action.actor,
|
|
7900
|
+
protected_branch: isProtected,
|
|
7901
|
+
restricted_actor: isRestricted,
|
|
7902
|
+
...action.metadata
|
|
7903
|
+
}
|
|
7904
|
+
};
|
|
7905
|
+
}
|
|
7906
|
+
function defaultMapWebhook(eventType, payload) {
|
|
7907
|
+
const repo = payload.repository;
|
|
7908
|
+
const repoFullName = repo?.full_name ?? "unknown/unknown";
|
|
7909
|
+
const sender = payload.sender;
|
|
7910
|
+
const actor = sender?.login ?? void 0;
|
|
7911
|
+
const webhookAction = payload.action;
|
|
7912
|
+
switch (eventType) {
|
|
7913
|
+
case "push": {
|
|
7914
|
+
const ref = payload.ref;
|
|
7915
|
+
const branch = extractBranch(ref);
|
|
7916
|
+
const forced = payload.forced;
|
|
7917
|
+
return {
|
|
7918
|
+
action: forced ? "force_push" : `push_to_${branch ?? "branch"}`,
|
|
7919
|
+
repository: repoFullName,
|
|
7920
|
+
ref,
|
|
7921
|
+
branch,
|
|
7922
|
+
actor,
|
|
7923
|
+
metadata: {
|
|
7924
|
+
forced: forced ?? false,
|
|
7925
|
+
commits_count: payload.commits?.length ?? 0,
|
|
7926
|
+
head_commit: payload.head_commit?.id
|
|
7927
|
+
}
|
|
7928
|
+
};
|
|
7929
|
+
}
|
|
7930
|
+
case "pull_request": {
|
|
7931
|
+
const pr = payload.pull_request;
|
|
7932
|
+
const base = pr?.base;
|
|
7933
|
+
const baseBranch = base?.ref;
|
|
7934
|
+
const prNumber = pr?.number;
|
|
7935
|
+
const merged = pr?.merged;
|
|
7936
|
+
const labels = pr?.labels?.map((l) => l.name) ?? [];
|
|
7937
|
+
let action = `pull_request_${webhookAction ?? "unknown"}`;
|
|
7938
|
+
if (webhookAction === "closed" && merged) {
|
|
7939
|
+
action = "merge_pull_request";
|
|
7940
|
+
}
|
|
7941
|
+
return {
|
|
7942
|
+
action,
|
|
7943
|
+
repository: repoFullName,
|
|
7944
|
+
branch: baseBranch,
|
|
7945
|
+
actor,
|
|
7946
|
+
metadata: {
|
|
7947
|
+
pr_number: prNumber,
|
|
7948
|
+
labels,
|
|
7949
|
+
merged: merged ?? false,
|
|
7950
|
+
draft: pr?.draft ?? false,
|
|
7951
|
+
webhook_action: webhookAction
|
|
7952
|
+
}
|
|
7953
|
+
};
|
|
7954
|
+
}
|
|
7955
|
+
case "release": {
|
|
7956
|
+
const release = payload.release;
|
|
7957
|
+
return {
|
|
7958
|
+
action: `release_${webhookAction ?? "published"}`,
|
|
7959
|
+
repository: repoFullName,
|
|
7960
|
+
ref: release?.tag_name ? `refs/tags/${release.tag_name}` : void 0,
|
|
7961
|
+
actor,
|
|
7962
|
+
metadata: {
|
|
7963
|
+
tag: release?.tag_name,
|
|
7964
|
+
prerelease: release?.prerelease ?? false,
|
|
7965
|
+
draft: release?.draft ?? false,
|
|
7966
|
+
webhook_action: webhookAction
|
|
7967
|
+
}
|
|
7968
|
+
};
|
|
7969
|
+
}
|
|
7970
|
+
case "deployment":
|
|
7971
|
+
case "deployment_status": {
|
|
7972
|
+
const deployment = payload.deployment ?? payload;
|
|
7973
|
+
return {
|
|
7974
|
+
action: eventType === "deployment" ? "create_deployment" : "deployment_status_update",
|
|
7975
|
+
repository: repoFullName,
|
|
7976
|
+
ref: deployment.ref,
|
|
7977
|
+
actor,
|
|
7978
|
+
metadata: {
|
|
7979
|
+
environment: deployment.environment,
|
|
7980
|
+
status: payload.deployment_status?.state,
|
|
7981
|
+
webhook_action: webhookAction
|
|
7982
|
+
}
|
|
7983
|
+
};
|
|
7984
|
+
}
|
|
7985
|
+
case "workflow_run": {
|
|
7986
|
+
const run = payload.workflow_run;
|
|
7987
|
+
return {
|
|
7988
|
+
action: `workflow_${webhookAction ?? "completed"}`,
|
|
7989
|
+
repository: repoFullName,
|
|
7990
|
+
branch: run?.head_branch,
|
|
7991
|
+
actor,
|
|
7992
|
+
metadata: {
|
|
7993
|
+
workflow_name: run?.name,
|
|
7994
|
+
conclusion: run?.conclusion,
|
|
7995
|
+
status: run?.status,
|
|
7996
|
+
webhook_action: webhookAction
|
|
7997
|
+
}
|
|
7998
|
+
};
|
|
7999
|
+
}
|
|
8000
|
+
case "issues": {
|
|
8001
|
+
const issue = payload.issue;
|
|
8002
|
+
return {
|
|
8003
|
+
action: `issue_${webhookAction ?? "opened"}`,
|
|
8004
|
+
repository: repoFullName,
|
|
8005
|
+
actor,
|
|
8006
|
+
metadata: {
|
|
8007
|
+
issue_number: issue?.number,
|
|
8008
|
+
labels: issue?.labels?.map((l) => l.name) ?? [],
|
|
8009
|
+
webhook_action: webhookAction
|
|
8010
|
+
}
|
|
8011
|
+
};
|
|
8012
|
+
}
|
|
8013
|
+
case "issue_comment": {
|
|
8014
|
+
return {
|
|
8015
|
+
action: `issue_comment_${webhookAction ?? "created"}`,
|
|
8016
|
+
repository: repoFullName,
|
|
8017
|
+
actor,
|
|
8018
|
+
metadata: {
|
|
8019
|
+
issue_number: payload.issue?.number,
|
|
8020
|
+
webhook_action: webhookAction
|
|
8021
|
+
}
|
|
8022
|
+
};
|
|
8023
|
+
}
|
|
8024
|
+
case "delete": {
|
|
8025
|
+
return {
|
|
8026
|
+
action: `delete_${payload.ref_type ?? "ref"}`,
|
|
8027
|
+
repository: repoFullName,
|
|
8028
|
+
ref: payload.ref,
|
|
8029
|
+
actor,
|
|
8030
|
+
metadata: {
|
|
8031
|
+
ref_type: payload.ref_type
|
|
8032
|
+
}
|
|
8033
|
+
};
|
|
8034
|
+
}
|
|
8035
|
+
default: {
|
|
8036
|
+
return {
|
|
8037
|
+
action: webhookAction ? `${eventType}_${webhookAction}` : eventType,
|
|
8038
|
+
repository: repoFullName,
|
|
8039
|
+
actor,
|
|
8040
|
+
metadata: { webhook_action: webhookAction }
|
|
8041
|
+
};
|
|
8042
|
+
}
|
|
8043
|
+
}
|
|
8044
|
+
}
|
|
8045
|
+
var GitHubGovernor = class {
|
|
8046
|
+
world;
|
|
8047
|
+
options;
|
|
8048
|
+
engineOptions;
|
|
8049
|
+
activePlan;
|
|
8050
|
+
protectedBranches;
|
|
8051
|
+
restrictedActors;
|
|
8052
|
+
mapFn;
|
|
8053
|
+
constructor(world, options = {}) {
|
|
8054
|
+
this.world = world;
|
|
8055
|
+
this.options = options;
|
|
8056
|
+
this.activePlan = options.plan;
|
|
8057
|
+
this.engineOptions = buildEngineOptions(options, this.activePlan);
|
|
8058
|
+
this.protectedBranches = options.protectedBranches ?? ["main", "master", "production"];
|
|
8059
|
+
this.restrictedActors = options.restrictedActors ?? [];
|
|
8060
|
+
this.mapFn = options.mapAction ?? ((action) => defaultMapAction(action, this.protectedBranches, this.restrictedActors));
|
|
8061
|
+
}
|
|
8062
|
+
/**
|
|
8063
|
+
* Evaluate a GitHub action against governance rules.
|
|
8064
|
+
* Returns a full result with verdict, event, and the original action.
|
|
8065
|
+
*/
|
|
8066
|
+
evaluate(action) {
|
|
8067
|
+
const event = this.mapFn(action);
|
|
8068
|
+
this.engineOptions.plan = this.activePlan;
|
|
8069
|
+
const verdict = evaluateGuard(event, this.world, this.engineOptions);
|
|
8070
|
+
this.options.onEvaluate?.(verdict, event, action);
|
|
8071
|
+
if (verdict.status === "ALLOW") {
|
|
8072
|
+
trackPlanProgress(event, this, this.options);
|
|
8073
|
+
}
|
|
8074
|
+
return { verdict, event, action };
|
|
8075
|
+
}
|
|
8076
|
+
/**
|
|
8077
|
+
* Evaluate and enforce — throws GitHubGovernanceBlockedError on BLOCK/PAUSE.
|
|
8078
|
+
* Use this as a gate before executing GitHub API calls.
|
|
8079
|
+
*/
|
|
8080
|
+
enforce(action) {
|
|
8081
|
+
const result = this.evaluate(action);
|
|
8082
|
+
if (result.verdict.status === "BLOCK" || result.verdict.status === "PAUSE") {
|
|
8083
|
+
throw new GitHubGovernanceBlockedError(result.verdict, action);
|
|
8084
|
+
}
|
|
8085
|
+
return result;
|
|
8086
|
+
}
|
|
8087
|
+
/**
|
|
8088
|
+
* Check if pushing to a branch is allowed.
|
|
8089
|
+
* Convenience method for the most common governance check.
|
|
8090
|
+
*/
|
|
8091
|
+
canPush(repository, branch, actor) {
|
|
8092
|
+
return this.evaluate({
|
|
8093
|
+
action: `push_to_${branch}`,
|
|
8094
|
+
repository,
|
|
8095
|
+
ref: `refs/heads/${branch}`,
|
|
8096
|
+
branch,
|
|
8097
|
+
actor
|
|
8098
|
+
}).verdict;
|
|
8099
|
+
}
|
|
8100
|
+
/**
|
|
8101
|
+
* Check if merging a PR is allowed.
|
|
8102
|
+
*/
|
|
8103
|
+
canMerge(repository, targetBranch, prNumber, actor, labels) {
|
|
8104
|
+
return this.evaluate({
|
|
8105
|
+
action: "merge_pull_request",
|
|
8106
|
+
repository,
|
|
8107
|
+
branch: targetBranch,
|
|
8108
|
+
actor,
|
|
8109
|
+
metadata: { pr_number: prNumber, labels: labels ?? [] }
|
|
8110
|
+
}).verdict;
|
|
8111
|
+
}
|
|
8112
|
+
/**
|
|
8113
|
+
* Check if creating a release is allowed.
|
|
8114
|
+
*/
|
|
8115
|
+
canRelease(repository, tag, actor, prerelease) {
|
|
8116
|
+
return this.evaluate({
|
|
8117
|
+
action: "release_published",
|
|
8118
|
+
repository,
|
|
8119
|
+
ref: `refs/tags/${tag}`,
|
|
8120
|
+
actor,
|
|
8121
|
+
metadata: { tag, prerelease: prerelease ?? false }
|
|
8122
|
+
}).verdict;
|
|
8123
|
+
}
|
|
8124
|
+
/**
|
|
8125
|
+
* Check if deploying to an environment is allowed.
|
|
8126
|
+
*/
|
|
8127
|
+
canDeploy(repository, environment, ref, actor) {
|
|
8128
|
+
return this.evaluate({
|
|
8129
|
+
action: "create_deployment",
|
|
8130
|
+
repository,
|
|
8131
|
+
ref,
|
|
8132
|
+
actor,
|
|
8133
|
+
metadata: { environment }
|
|
8134
|
+
}).verdict;
|
|
8135
|
+
}
|
|
8136
|
+
};
|
|
8137
|
+
var GitHubWebhookHandler = class {
|
|
8138
|
+
governor;
|
|
8139
|
+
mapWebhookFn;
|
|
8140
|
+
webhookSecret;
|
|
8141
|
+
constructor(world, options = {}) {
|
|
8142
|
+
this.governor = new GitHubGovernor(world, options);
|
|
8143
|
+
this.mapWebhookFn = options.mapWebhook ?? defaultMapWebhook;
|
|
8144
|
+
this.webhookSecret = options.webhookSecret;
|
|
8145
|
+
}
|
|
8146
|
+
/**
|
|
8147
|
+
* Evaluate a webhook payload.
|
|
8148
|
+
*
|
|
8149
|
+
* @param eventType - The X-GitHub-Event header value
|
|
8150
|
+
* @param payload - The parsed webhook body
|
|
8151
|
+
*/
|
|
8152
|
+
evaluate(eventType, payload) {
|
|
8153
|
+
const action = this.mapWebhookFn(eventType, payload);
|
|
8154
|
+
const result = this.governor.evaluate(action);
|
|
8155
|
+
return {
|
|
8156
|
+
verdict: result.verdict,
|
|
8157
|
+
event: result.event,
|
|
8158
|
+
webhookEvent: eventType,
|
|
8159
|
+
webhookAction: payload.action
|
|
8160
|
+
};
|
|
8161
|
+
}
|
|
8162
|
+
/**
|
|
8163
|
+
* Evaluate and enforce — throws on BLOCK/PAUSE.
|
|
8164
|
+
*/
|
|
8165
|
+
enforce(eventType, payload) {
|
|
8166
|
+
const result = this.evaluate(eventType, payload);
|
|
8167
|
+
if (result.verdict.status === "BLOCK" || result.verdict.status === "PAUSE") {
|
|
8168
|
+
const action = this.mapWebhookFn(eventType, payload);
|
|
8169
|
+
throw new GitHubGovernanceBlockedError(result.verdict, action);
|
|
8170
|
+
}
|
|
8171
|
+
return result;
|
|
8172
|
+
}
|
|
8173
|
+
/** Access the underlying governor for direct action evaluation. */
|
|
8174
|
+
getGovernor() {
|
|
8175
|
+
return this.governor;
|
|
8176
|
+
}
|
|
8177
|
+
/** Get the configured webhook secret (for signature verification in your server). */
|
|
8178
|
+
getWebhookSecret() {
|
|
8179
|
+
return this.webhookSecret;
|
|
8180
|
+
}
|
|
8181
|
+
};
|
|
8182
|
+
function formatForActions(verdict) {
|
|
8183
|
+
const status = verdict.status === "ALLOW" ? "allowed" : verdict.status === "BLOCK" ? "blocked" : "paused";
|
|
8184
|
+
const reason = verdict.reason ?? "";
|
|
8185
|
+
const ruleId = verdict.ruleId ?? "";
|
|
8186
|
+
const lines = [
|
|
8187
|
+
`governance_status=${status}`,
|
|
8188
|
+
`verdict_status=${verdict.status}`,
|
|
8189
|
+
`reason=${reason}`,
|
|
8190
|
+
`rule_id=${ruleId}`
|
|
8191
|
+
].join("\n");
|
|
8192
|
+
return {
|
|
8193
|
+
governance_status: status,
|
|
8194
|
+
verdict_status: verdict.status,
|
|
8195
|
+
reason,
|
|
8196
|
+
rule_id: ruleId,
|
|
8197
|
+
outputLines: lines
|
|
8198
|
+
};
|
|
8199
|
+
}
|
|
8200
|
+
function formatPRComment(verdict, action) {
|
|
8201
|
+
const icon = verdict.status === "ALLOW" ? "\u2705" : verdict.status === "BLOCK" ? "\u{1F6AB}" : "\u23F8\uFE0F";
|
|
8202
|
+
const status = verdict.status;
|
|
8203
|
+
let body = `## ${icon} Governance: ${status}
|
|
8204
|
+
|
|
8205
|
+
`;
|
|
8206
|
+
body += `**Action:** \`${action.action}\`
|
|
8207
|
+
`;
|
|
8208
|
+
body += `**Repository:** \`${action.repository}\`
|
|
8209
|
+
`;
|
|
8210
|
+
if (action.branch) {
|
|
8211
|
+
body += `**Branch:** \`${action.branch}\`
|
|
8212
|
+
`;
|
|
8213
|
+
}
|
|
8214
|
+
if (action.actor) {
|
|
8215
|
+
body += `**Actor:** \`${action.actor}\`
|
|
8216
|
+
`;
|
|
8217
|
+
}
|
|
8218
|
+
body += "\n";
|
|
8219
|
+
if (verdict.reason) {
|
|
8220
|
+
body += `**Reason:** ${verdict.reason}
|
|
8221
|
+
`;
|
|
8222
|
+
}
|
|
8223
|
+
if (verdict.ruleId) {
|
|
8224
|
+
body += `**Rule:** \`${verdict.ruleId}\`
|
|
8225
|
+
`;
|
|
8226
|
+
}
|
|
8227
|
+
if (verdict.evidence?.invariantsSatisfied < verdict.evidence?.invariantsTotal) {
|
|
8228
|
+
body += `**Invariants:** ${verdict.evidence.invariantsSatisfied}/${verdict.evidence.invariantsTotal} satisfied
|
|
8229
|
+
`;
|
|
8230
|
+
}
|
|
8231
|
+
body += "\n---\n*Evaluated by [NeuroVerse Governance](https://github.com/NeuroverseOS/neuroverseos-governance)*";
|
|
8232
|
+
return body;
|
|
8233
|
+
}
|
|
8234
|
+
async function createGitHubGovernor(worldPath, options) {
|
|
8235
|
+
const world = await loadWorld(worldPath);
|
|
8236
|
+
return new GitHubGovernor(world, options);
|
|
8237
|
+
}
|
|
8238
|
+
function createGitHubGovernorFromWorld(world, options) {
|
|
8239
|
+
return new GitHubGovernor(world, options);
|
|
8240
|
+
}
|
|
8241
|
+
async function createGitHubWebhookHandler(worldPath, options) {
|
|
8242
|
+
const world = await loadWorld(worldPath);
|
|
8243
|
+
return new GitHubWebhookHandler(world, options);
|
|
8244
|
+
}
|
|
8245
|
+
function createGitHubWebhookHandlerFromWorld(world, options) {
|
|
8246
|
+
return new GitHubWebhookHandler(world, options);
|
|
8247
|
+
}
|
|
8248
|
+
|
|
7591
8249
|
// src/engine/api.ts
|
|
7592
8250
|
init_world_loader();
|
|
7593
8251
|
function handleHealthCheck() {
|
|
@@ -7664,6 +8322,9 @@ function handleCreateCapsule(body) {
|
|
|
7664
8322
|
DERIVE_EXIT_CODES,
|
|
7665
8323
|
FileAuditLogger,
|
|
7666
8324
|
GUARD_EXIT_CODES,
|
|
8325
|
+
GitHubGovernanceBlockedError,
|
|
8326
|
+
GitHubGovernor,
|
|
8327
|
+
GitHubWebhookHandler,
|
|
7667
8328
|
McpGovernanceServer,
|
|
7668
8329
|
ModelAdapter,
|
|
7669
8330
|
PLAN_EXIT_CODES,
|
|
@@ -7683,6 +8344,10 @@ function handleCreateCapsule(body) {
|
|
|
7683
8344
|
classifyIntent,
|
|
7684
8345
|
classifyIntentWithAI,
|
|
7685
8346
|
createAgentState,
|
|
8347
|
+
createGitHubGovernor,
|
|
8348
|
+
createGitHubGovernorFromWorld,
|
|
8349
|
+
createGitHubWebhookHandler,
|
|
8350
|
+
createGitHubWebhookHandlerFromWorld,
|
|
7686
8351
|
createGovernanceEngine,
|
|
7687
8352
|
createGovernor,
|
|
7688
8353
|
deriveWorld,
|
|
@@ -7697,6 +8362,8 @@ function handleCreateCapsule(body) {
|
|
|
7697
8362
|
explainWorld,
|
|
7698
8363
|
extractContentFields,
|
|
7699
8364
|
extractWorldMarkdown,
|
|
8365
|
+
formatForActions,
|
|
8366
|
+
formatPRComment,
|
|
7700
8367
|
formatVerdict,
|
|
7701
8368
|
formatVerdictOneLine,
|
|
7702
8369
|
generateAdaptationNarrative,
|
|
@@ -7734,5 +8401,6 @@ function handleCreateCapsule(body) {
|
|
|
7734
8401
|
tickAgentStates,
|
|
7735
8402
|
validateWorld,
|
|
7736
8403
|
verdictToAuditEvent,
|
|
8404
|
+
verdictToEvent,
|
|
7737
8405
|
writeTempWorld
|
|
7738
8406
|
});
|