@neuroverseos/governance 0.4.0 → 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/dist/adapters/autoresearch.d.cts +2 -1
- package/dist/adapters/autoresearch.d.ts +2 -1
- package/dist/adapters/autoresearch.js +2 -2
- package/dist/adapters/deep-agents.d.cts +3 -2
- package/dist/adapters/deep-agents.d.ts +3 -2
- package/dist/adapters/deep-agents.js +2 -2
- package/dist/adapters/express.d.cts +2 -1
- package/dist/adapters/express.d.ts +2 -1
- package/dist/adapters/express.js +2 -2
- package/dist/adapters/index.cjs +66 -1
- package/dist/adapters/index.d.cts +4 -278
- package/dist/adapters/index.d.ts +4 -278
- package/dist/adapters/index.js +33 -33
- package/dist/adapters/langchain.d.cts +3 -2
- package/dist/adapters/langchain.d.ts +3 -2
- package/dist/adapters/langchain.js +2 -2
- 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/{mentraos-YFS7FMJH.js → adapters/mentraos.js} +6 -6
- package/dist/adapters/openai.d.cts +3 -2
- package/dist/adapters/openai.d.ts +3 -2
- package/dist/adapters/openai.js +2 -2
- package/dist/adapters/openclaw.d.cts +3 -2
- package/dist/adapters/openclaw.d.ts +3 -2
- package/dist/adapters/openclaw.js +2 -2
- package/dist/{add-LYHDZ5RL.js → add-XSANI3FK.js} +1 -1
- package/dist/bootstrap-contract-DcV6t-8M.d.cts +216 -0
- package/dist/bootstrap-contract-DcV6t-8M.d.ts +216 -0
- package/dist/{build-THUEYMVT.js → build-EGBGZFIJ.js} +5 -5
- package/dist/{chunk-MFKHTE5R.js → chunk-3AYKQHYI.js} +1 -1
- package/dist/chunk-3S5AD4AB.js +421 -0
- package/dist/{chunk-V4FZHJQX.js → chunk-A7SHG75T.js} +1 -1
- package/dist/{chunk-JKGPSFGH.js → chunk-AV7XJJWK.js} +1 -1
- package/dist/{chunk-Y6WXAPKY.js → chunk-DA5MHFRR.js} +1 -1
- package/dist/{chunk-7D7PZLB7.js → chunk-FS2UUJJO.js} +3 -3
- package/dist/{chunk-TD5GKIHP.js → chunk-FVOGUCB6.js} +1 -1
- package/dist/{chunk-APU4OZIP.js → chunk-GTPV2XGO.js} +67 -2
- package/dist/{chunk-BXLTEUS4.js → chunk-I4RTIMLX.js} +2 -2
- package/dist/{chunk-5JUZ4HL7.js → chunk-J2IZBHXJ.js} +3 -3
- package/dist/{chunk-YNYCQECH.js → chunk-QMVQ6KPL.js} +1 -1
- package/dist/{chunk-25XHSTPT.js → chunk-RDA7ISWC.js} +1 -1
- package/dist/{chunk-DWHUZUEY.js → chunk-YJ34R5NB.js} +1 -1
- package/dist/{chunk-UTH7OXTM.js → chunk-ZEIT2QLM.js} +3 -3
- package/dist/cli/neuroverse.cjs +580 -28
- package/dist/cli/neuroverse.js +21 -21
- package/dist/cli/plan.js +2 -2
- package/dist/cli/run.js +2 -2
- package/dist/{demo-66MMJTEH.js → demo-6OQYWRR6.js} +3 -3
- package/dist/{derive-5LOMN7GO.js → derive-7Y7YWVLU.js} +4 -4
- package/dist/{doctor-WIO4FLA3.js → doctor-NHXI7OQW.js} +3 -2
- 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-GIMOJFOC.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-LBLGVEMU.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/{guard-engine-N7TUIUU7.js → engine/guard-engine.js} +3 -3
- 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-WWC7UDQD.js → equity-penalties-NVBAB5WL.js} +2 -2
- package/dist/{explain-MUSGDT67.js → explain-HDFN4ION.js} +1 -1
- package/dist/github-TIKTWOGU.js +27 -0
- package/dist/{guard-W3BMQPBJ.js → guard-6KSCWT2W.js} +2 -2
- package/dist/{guard-contract-CLBbTGK_.d.cts → guard-contract-C991HDZp.d.cts} +2 -369
- package/dist/{guard-contract-CLBbTGK_.d.ts → guard-contract-hHjTTjtR.d.ts} +2 -369
- package/dist/{improve-PJDAWW4Q.js → improve-2PWGGO5B.js} +3 -3
- package/dist/index.cjs +452 -0
- package/dist/index.d.cts +231 -492
- package/dist/index.d.ts +231 -492
- package/dist/index.js +76 -55
- package/dist/{lens-IP6GIZ2Q.js → lens-MHMUDCMQ.js} +92 -25
- package/dist/{mcp-server-OG3PPVD2.js → mcp-server-TNIWZ7B5.js} +2 -2
- package/dist/{playground-4BK2XQ47.js → playground-3FLDGBET.js} +2 -2
- package/dist/{redteam-BRZALBPP.js → redteam-HV6LMKEH.js} +2 -2
- package/dist/{session-SGRUT2UH.js → session-XZP2754M.js} +2 -2
- package/dist/{shared-BGzmYP5g.d.cts → shared-DGnn1jiS.d.cts} +1 -1
- package/dist/{shared-CwGpPheR.d.ts → shared-U405h52W.d.ts} +1 -1
- package/dist/{simulate-FGXKIH7V.js → simulate-VT437EEL.js} +2 -2
- 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-PT44BSYG.js → test-4WTX6RKQ.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-Q5O5TGLT.js → validate-M52DX22Y.js} +1 -1
- package/dist/{world-V52ZMH26.js → world-O4HTQPDP.js} +1 -1
- package/dist/{world-loader-C4D3VPP3.js → world-loader-YTYFOP7D.js} +1 -1
- package/dist/worlds/mentraos-spatial.nv-world.md +68 -0
- package/package.json +46 -3
- package/dist/{behavioral-SPWPGYXL.js → behavioral-SLW7ALEK.js} +3 -3
- package/dist/{bootstrap-IP5QMC3Q.js → bootstrap-2OW5ZLBL.js} +3 -3
- package/dist/{chunk-7QIAF377.js → chunk-CYDMUJVZ.js} +0 -0
- package/dist/{chunk-QZ666FCV.js → chunk-FHXXD2TI.js} +6 -6
- package/dist/{configure-ai-5MP5DWTT.js → configure-ai-LL3VAPQW.js} +3 -3
|
@@ -0,0 +1,421 @@
|
|
|
1
|
+
import {
|
|
2
|
+
GovernanceBlockedError,
|
|
3
|
+
buildEngineOptions,
|
|
4
|
+
trackPlanProgress
|
|
5
|
+
} from "./chunk-5U2MQO5P.js";
|
|
6
|
+
import {
|
|
7
|
+
evaluateGuard
|
|
8
|
+
} from "./chunk-ZAF6JH23.js";
|
|
9
|
+
import {
|
|
10
|
+
loadWorld
|
|
11
|
+
} from "./chunk-I4RTIMLX.js";
|
|
12
|
+
|
|
13
|
+
// src/adapters/github.ts
|
|
14
|
+
var GitHubGovernanceBlockedError = class extends GovernanceBlockedError {
|
|
15
|
+
action;
|
|
16
|
+
constructor(verdict, action) {
|
|
17
|
+
super(verdict, `[NeuroVerse] GitHub action blocked: ${action.action} on ${action.repository}`);
|
|
18
|
+
this.name = "GitHubGovernanceBlockedError";
|
|
19
|
+
this.action = action;
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
function extractBranch(ref) {
|
|
23
|
+
if (!ref) return void 0;
|
|
24
|
+
if (ref.startsWith("refs/heads/")) return ref.slice("refs/heads/".length);
|
|
25
|
+
if (ref.startsWith("refs/tags/")) return ref.slice("refs/tags/".length);
|
|
26
|
+
return ref;
|
|
27
|
+
}
|
|
28
|
+
function isProtectedBranch(branch, protectedBranches) {
|
|
29
|
+
if (!branch) return false;
|
|
30
|
+
return protectedBranches.some(
|
|
31
|
+
(pb) => branch === pb || branch.startsWith(`${pb}/`)
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
function defaultMapAction(action, protectedBranches, restrictedActors) {
|
|
35
|
+
const branch = action.branch ?? extractBranch(action.ref);
|
|
36
|
+
const isProtected = isProtectedBranch(branch, protectedBranches);
|
|
37
|
+
const isRestricted = action.actor ? restrictedActors.some((ra) => action.actor === ra || action.actor?.endsWith("[bot]")) : false;
|
|
38
|
+
let actionCategory = "other";
|
|
39
|
+
const act = action.action.toLowerCase();
|
|
40
|
+
if (act.includes("read") || act.includes("get") || act.includes("list") || act.includes("view")) {
|
|
41
|
+
actionCategory = "read";
|
|
42
|
+
} else if (act.includes("delete") || act.includes("remove") || act.includes("close")) {
|
|
43
|
+
actionCategory = "delete";
|
|
44
|
+
} else if (act.includes("deploy") || act.includes("run") || act.includes("execute") || act.includes("merge")) {
|
|
45
|
+
actionCategory = "network";
|
|
46
|
+
} else if (act.includes("create") || act.includes("push") || act.includes("write") || act.includes("update") || act.includes("edit")) {
|
|
47
|
+
actionCategory = "write";
|
|
48
|
+
} else if (act.includes("comment") || act.includes("review") || act.includes("notify")) {
|
|
49
|
+
actionCategory = "other";
|
|
50
|
+
}
|
|
51
|
+
return {
|
|
52
|
+
intent: action.action,
|
|
53
|
+
tool: "github",
|
|
54
|
+
scope: `${action.repository}${branch ? `@${branch}` : ""}`,
|
|
55
|
+
actionCategory,
|
|
56
|
+
direction: "input",
|
|
57
|
+
args: {
|
|
58
|
+
repository: action.repository,
|
|
59
|
+
ref: action.ref,
|
|
60
|
+
branch,
|
|
61
|
+
actor: action.actor,
|
|
62
|
+
protected_branch: isProtected,
|
|
63
|
+
restricted_actor: isRestricted,
|
|
64
|
+
...action.metadata
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
function defaultMapWebhook(eventType, payload) {
|
|
69
|
+
const repo = payload.repository;
|
|
70
|
+
const repoFullName = repo?.full_name ?? "unknown/unknown";
|
|
71
|
+
const sender = payload.sender;
|
|
72
|
+
const actor = sender?.login ?? void 0;
|
|
73
|
+
const webhookAction = payload.action;
|
|
74
|
+
switch (eventType) {
|
|
75
|
+
case "push": {
|
|
76
|
+
const ref = payload.ref;
|
|
77
|
+
const branch = extractBranch(ref);
|
|
78
|
+
const forced = payload.forced;
|
|
79
|
+
return {
|
|
80
|
+
action: forced ? "force_push" : `push_to_${branch ?? "branch"}`,
|
|
81
|
+
repository: repoFullName,
|
|
82
|
+
ref,
|
|
83
|
+
branch,
|
|
84
|
+
actor,
|
|
85
|
+
metadata: {
|
|
86
|
+
forced: forced ?? false,
|
|
87
|
+
commits_count: payload.commits?.length ?? 0,
|
|
88
|
+
head_commit: payload.head_commit?.id
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
case "pull_request": {
|
|
93
|
+
const pr = payload.pull_request;
|
|
94
|
+
const base = pr?.base;
|
|
95
|
+
const baseBranch = base?.ref;
|
|
96
|
+
const prNumber = pr?.number;
|
|
97
|
+
const merged = pr?.merged;
|
|
98
|
+
const labels = pr?.labels?.map((l) => l.name) ?? [];
|
|
99
|
+
let action = `pull_request_${webhookAction ?? "unknown"}`;
|
|
100
|
+
if (webhookAction === "closed" && merged) {
|
|
101
|
+
action = "merge_pull_request";
|
|
102
|
+
}
|
|
103
|
+
return {
|
|
104
|
+
action,
|
|
105
|
+
repository: repoFullName,
|
|
106
|
+
branch: baseBranch,
|
|
107
|
+
actor,
|
|
108
|
+
metadata: {
|
|
109
|
+
pr_number: prNumber,
|
|
110
|
+
labels,
|
|
111
|
+
merged: merged ?? false,
|
|
112
|
+
draft: pr?.draft ?? false,
|
|
113
|
+
webhook_action: webhookAction
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
case "release": {
|
|
118
|
+
const release = payload.release;
|
|
119
|
+
return {
|
|
120
|
+
action: `release_${webhookAction ?? "published"}`,
|
|
121
|
+
repository: repoFullName,
|
|
122
|
+
ref: release?.tag_name ? `refs/tags/${release.tag_name}` : void 0,
|
|
123
|
+
actor,
|
|
124
|
+
metadata: {
|
|
125
|
+
tag: release?.tag_name,
|
|
126
|
+
prerelease: release?.prerelease ?? false,
|
|
127
|
+
draft: release?.draft ?? false,
|
|
128
|
+
webhook_action: webhookAction
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
case "deployment":
|
|
133
|
+
case "deployment_status": {
|
|
134
|
+
const deployment = payload.deployment ?? payload;
|
|
135
|
+
return {
|
|
136
|
+
action: eventType === "deployment" ? "create_deployment" : "deployment_status_update",
|
|
137
|
+
repository: repoFullName,
|
|
138
|
+
ref: deployment.ref,
|
|
139
|
+
actor,
|
|
140
|
+
metadata: {
|
|
141
|
+
environment: deployment.environment,
|
|
142
|
+
status: payload.deployment_status?.state,
|
|
143
|
+
webhook_action: webhookAction
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
case "workflow_run": {
|
|
148
|
+
const run = payload.workflow_run;
|
|
149
|
+
return {
|
|
150
|
+
action: `workflow_${webhookAction ?? "completed"}`,
|
|
151
|
+
repository: repoFullName,
|
|
152
|
+
branch: run?.head_branch,
|
|
153
|
+
actor,
|
|
154
|
+
metadata: {
|
|
155
|
+
workflow_name: run?.name,
|
|
156
|
+
conclusion: run?.conclusion,
|
|
157
|
+
status: run?.status,
|
|
158
|
+
webhook_action: webhookAction
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
case "issues": {
|
|
163
|
+
const issue = payload.issue;
|
|
164
|
+
return {
|
|
165
|
+
action: `issue_${webhookAction ?? "opened"}`,
|
|
166
|
+
repository: repoFullName,
|
|
167
|
+
actor,
|
|
168
|
+
metadata: {
|
|
169
|
+
issue_number: issue?.number,
|
|
170
|
+
labels: issue?.labels?.map((l) => l.name) ?? [],
|
|
171
|
+
webhook_action: webhookAction
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
case "issue_comment": {
|
|
176
|
+
return {
|
|
177
|
+
action: `issue_comment_${webhookAction ?? "created"}`,
|
|
178
|
+
repository: repoFullName,
|
|
179
|
+
actor,
|
|
180
|
+
metadata: {
|
|
181
|
+
issue_number: payload.issue?.number,
|
|
182
|
+
webhook_action: webhookAction
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
case "delete": {
|
|
187
|
+
return {
|
|
188
|
+
action: `delete_${payload.ref_type ?? "ref"}`,
|
|
189
|
+
repository: repoFullName,
|
|
190
|
+
ref: payload.ref,
|
|
191
|
+
actor,
|
|
192
|
+
metadata: {
|
|
193
|
+
ref_type: payload.ref_type
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
default: {
|
|
198
|
+
return {
|
|
199
|
+
action: webhookAction ? `${eventType}_${webhookAction}` : eventType,
|
|
200
|
+
repository: repoFullName,
|
|
201
|
+
actor,
|
|
202
|
+
metadata: { webhook_action: webhookAction }
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
var GitHubGovernor = class {
|
|
208
|
+
world;
|
|
209
|
+
options;
|
|
210
|
+
engineOptions;
|
|
211
|
+
activePlan;
|
|
212
|
+
protectedBranches;
|
|
213
|
+
restrictedActors;
|
|
214
|
+
mapFn;
|
|
215
|
+
constructor(world, options = {}) {
|
|
216
|
+
this.world = world;
|
|
217
|
+
this.options = options;
|
|
218
|
+
this.activePlan = options.plan;
|
|
219
|
+
this.engineOptions = buildEngineOptions(options, this.activePlan);
|
|
220
|
+
this.protectedBranches = options.protectedBranches ?? ["main", "master", "production"];
|
|
221
|
+
this.restrictedActors = options.restrictedActors ?? [];
|
|
222
|
+
this.mapFn = options.mapAction ?? ((action) => defaultMapAction(action, this.protectedBranches, this.restrictedActors));
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Evaluate a GitHub action against governance rules.
|
|
226
|
+
* Returns a full result with verdict, event, and the original action.
|
|
227
|
+
*/
|
|
228
|
+
evaluate(action) {
|
|
229
|
+
const event = this.mapFn(action);
|
|
230
|
+
this.engineOptions.plan = this.activePlan;
|
|
231
|
+
const verdict = evaluateGuard(event, this.world, this.engineOptions);
|
|
232
|
+
this.options.onEvaluate?.(verdict, event, action);
|
|
233
|
+
if (verdict.status === "ALLOW") {
|
|
234
|
+
trackPlanProgress(event, this, this.options);
|
|
235
|
+
}
|
|
236
|
+
return { verdict, event, action };
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Evaluate and enforce — throws GitHubGovernanceBlockedError on BLOCK/PAUSE.
|
|
240
|
+
* Use this as a gate before executing GitHub API calls.
|
|
241
|
+
*/
|
|
242
|
+
enforce(action) {
|
|
243
|
+
const result = this.evaluate(action);
|
|
244
|
+
if (result.verdict.status === "BLOCK" || result.verdict.status === "PAUSE") {
|
|
245
|
+
throw new GitHubGovernanceBlockedError(result.verdict, action);
|
|
246
|
+
}
|
|
247
|
+
return result;
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Check if pushing to a branch is allowed.
|
|
251
|
+
* Convenience method for the most common governance check.
|
|
252
|
+
*/
|
|
253
|
+
canPush(repository, branch, actor) {
|
|
254
|
+
return this.evaluate({
|
|
255
|
+
action: `push_to_${branch}`,
|
|
256
|
+
repository,
|
|
257
|
+
ref: `refs/heads/${branch}`,
|
|
258
|
+
branch,
|
|
259
|
+
actor
|
|
260
|
+
}).verdict;
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Check if merging a PR is allowed.
|
|
264
|
+
*/
|
|
265
|
+
canMerge(repository, targetBranch, prNumber, actor, labels) {
|
|
266
|
+
return this.evaluate({
|
|
267
|
+
action: "merge_pull_request",
|
|
268
|
+
repository,
|
|
269
|
+
branch: targetBranch,
|
|
270
|
+
actor,
|
|
271
|
+
metadata: { pr_number: prNumber, labels: labels ?? [] }
|
|
272
|
+
}).verdict;
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Check if creating a release is allowed.
|
|
276
|
+
*/
|
|
277
|
+
canRelease(repository, tag, actor, prerelease) {
|
|
278
|
+
return this.evaluate({
|
|
279
|
+
action: "release_published",
|
|
280
|
+
repository,
|
|
281
|
+
ref: `refs/tags/${tag}`,
|
|
282
|
+
actor,
|
|
283
|
+
metadata: { tag, prerelease: prerelease ?? false }
|
|
284
|
+
}).verdict;
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Check if deploying to an environment is allowed.
|
|
288
|
+
*/
|
|
289
|
+
canDeploy(repository, environment, ref, actor) {
|
|
290
|
+
return this.evaluate({
|
|
291
|
+
action: "create_deployment",
|
|
292
|
+
repository,
|
|
293
|
+
ref,
|
|
294
|
+
actor,
|
|
295
|
+
metadata: { environment }
|
|
296
|
+
}).verdict;
|
|
297
|
+
}
|
|
298
|
+
};
|
|
299
|
+
var GitHubWebhookHandler = class {
|
|
300
|
+
governor;
|
|
301
|
+
mapWebhookFn;
|
|
302
|
+
webhookSecret;
|
|
303
|
+
constructor(world, options = {}) {
|
|
304
|
+
this.governor = new GitHubGovernor(world, options);
|
|
305
|
+
this.mapWebhookFn = options.mapWebhook ?? defaultMapWebhook;
|
|
306
|
+
this.webhookSecret = options.webhookSecret;
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Evaluate a webhook payload.
|
|
310
|
+
*
|
|
311
|
+
* @param eventType - The X-GitHub-Event header value
|
|
312
|
+
* @param payload - The parsed webhook body
|
|
313
|
+
*/
|
|
314
|
+
evaluate(eventType, payload) {
|
|
315
|
+
const action = this.mapWebhookFn(eventType, payload);
|
|
316
|
+
const result = this.governor.evaluate(action);
|
|
317
|
+
return {
|
|
318
|
+
verdict: result.verdict,
|
|
319
|
+
event: result.event,
|
|
320
|
+
webhookEvent: eventType,
|
|
321
|
+
webhookAction: payload.action
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Evaluate and enforce — throws on BLOCK/PAUSE.
|
|
326
|
+
*/
|
|
327
|
+
enforce(eventType, payload) {
|
|
328
|
+
const result = this.evaluate(eventType, payload);
|
|
329
|
+
if (result.verdict.status === "BLOCK" || result.verdict.status === "PAUSE") {
|
|
330
|
+
const action = this.mapWebhookFn(eventType, payload);
|
|
331
|
+
throw new GitHubGovernanceBlockedError(result.verdict, action);
|
|
332
|
+
}
|
|
333
|
+
return result;
|
|
334
|
+
}
|
|
335
|
+
/** Access the underlying governor for direct action evaluation. */
|
|
336
|
+
getGovernor() {
|
|
337
|
+
return this.governor;
|
|
338
|
+
}
|
|
339
|
+
/** Get the configured webhook secret (for signature verification in your server). */
|
|
340
|
+
getWebhookSecret() {
|
|
341
|
+
return this.webhookSecret;
|
|
342
|
+
}
|
|
343
|
+
};
|
|
344
|
+
function formatForActions(verdict) {
|
|
345
|
+
const status = verdict.status === "ALLOW" ? "allowed" : verdict.status === "BLOCK" ? "blocked" : "paused";
|
|
346
|
+
const reason = verdict.reason ?? "";
|
|
347
|
+
const ruleId = verdict.ruleId ?? "";
|
|
348
|
+
const lines = [
|
|
349
|
+
`governance_status=${status}`,
|
|
350
|
+
`verdict_status=${verdict.status}`,
|
|
351
|
+
`reason=${reason}`,
|
|
352
|
+
`rule_id=${ruleId}`
|
|
353
|
+
].join("\n");
|
|
354
|
+
return {
|
|
355
|
+
governance_status: status,
|
|
356
|
+
verdict_status: verdict.status,
|
|
357
|
+
reason,
|
|
358
|
+
rule_id: ruleId,
|
|
359
|
+
outputLines: lines
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
function formatPRComment(verdict, action) {
|
|
363
|
+
const icon = verdict.status === "ALLOW" ? "\u2705" : verdict.status === "BLOCK" ? "\u{1F6AB}" : "\u23F8\uFE0F";
|
|
364
|
+
const status = verdict.status;
|
|
365
|
+
let body = `## ${icon} Governance: ${status}
|
|
366
|
+
|
|
367
|
+
`;
|
|
368
|
+
body += `**Action:** \`${action.action}\`
|
|
369
|
+
`;
|
|
370
|
+
body += `**Repository:** \`${action.repository}\`
|
|
371
|
+
`;
|
|
372
|
+
if (action.branch) {
|
|
373
|
+
body += `**Branch:** \`${action.branch}\`
|
|
374
|
+
`;
|
|
375
|
+
}
|
|
376
|
+
if (action.actor) {
|
|
377
|
+
body += `**Actor:** \`${action.actor}\`
|
|
378
|
+
`;
|
|
379
|
+
}
|
|
380
|
+
body += "\n";
|
|
381
|
+
if (verdict.reason) {
|
|
382
|
+
body += `**Reason:** ${verdict.reason}
|
|
383
|
+
`;
|
|
384
|
+
}
|
|
385
|
+
if (verdict.ruleId) {
|
|
386
|
+
body += `**Rule:** \`${verdict.ruleId}\`
|
|
387
|
+
`;
|
|
388
|
+
}
|
|
389
|
+
if (verdict.evidence?.invariantsSatisfied < verdict.evidence?.invariantsTotal) {
|
|
390
|
+
body += `**Invariants:** ${verdict.evidence.invariantsSatisfied}/${verdict.evidence.invariantsTotal} satisfied
|
|
391
|
+
`;
|
|
392
|
+
}
|
|
393
|
+
body += "\n---\n*Evaluated by [NeuroVerse Governance](https://github.com/NeuroverseOS/neuroverseos-governance)*";
|
|
394
|
+
return body;
|
|
395
|
+
}
|
|
396
|
+
async function createGitHubGovernor(worldPath, options) {
|
|
397
|
+
const world = await loadWorld(worldPath);
|
|
398
|
+
return new GitHubGovernor(world, options);
|
|
399
|
+
}
|
|
400
|
+
function createGitHubGovernorFromWorld(world, options) {
|
|
401
|
+
return new GitHubGovernor(world, options);
|
|
402
|
+
}
|
|
403
|
+
async function createGitHubWebhookHandler(worldPath, options) {
|
|
404
|
+
const world = await loadWorld(worldPath);
|
|
405
|
+
return new GitHubWebhookHandler(world, options);
|
|
406
|
+
}
|
|
407
|
+
function createGitHubWebhookHandlerFromWorld(world, options) {
|
|
408
|
+
return new GitHubWebhookHandler(world, options);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
export {
|
|
412
|
+
GitHubGovernanceBlockedError,
|
|
413
|
+
GitHubGovernor,
|
|
414
|
+
GitHubWebhookHandler,
|
|
415
|
+
formatForActions,
|
|
416
|
+
formatPRComment,
|
|
417
|
+
createGitHubGovernor,
|
|
418
|
+
createGitHubGovernorFromWorld,
|
|
419
|
+
createGitHubWebhookHandler,
|
|
420
|
+
createGitHubWebhookHandlerFromWorld
|
|
421
|
+
};
|
|
@@ -35,7 +35,7 @@ async function addGuard(worldDir, input) {
|
|
|
35
35
|
};
|
|
36
36
|
config.guards.push(guard);
|
|
37
37
|
await writeFile(guardsPath, JSON.stringify(config, null, 2) + "\n");
|
|
38
|
-
const { loadWorldFromDirectory } = await import("./world-loader-
|
|
38
|
+
const { loadWorldFromDirectory } = await import("./world-loader-YTYFOP7D.js");
|
|
39
39
|
const world = await loadWorldFromDirectory(worldDir);
|
|
40
40
|
const report = validateWorld(world);
|
|
41
41
|
return {
|
|
@@ -83,7 +83,7 @@ async function addRule(worldDir, input) {
|
|
|
83
83
|
};
|
|
84
84
|
const rulePath = join(rulesDir, `rule-${ruleNum}.json`);
|
|
85
85
|
await writeFile(rulePath, JSON.stringify(rule, null, 2) + "\n");
|
|
86
|
-
const { loadWorldFromDirectory } = await import("./world-loader-
|
|
86
|
+
const { loadWorldFromDirectory } = await import("./world-loader-YTYFOP7D.js");
|
|
87
87
|
const world = await loadWorldFromDirectory(worldDir);
|
|
88
88
|
const report = validateWorld(world);
|
|
89
89
|
return {
|
|
@@ -118,7 +118,7 @@ async function addInvariant(worldDir, input) {
|
|
|
118
118
|
};
|
|
119
119
|
config.invariants.push(invariant);
|
|
120
120
|
await writeFile(invariantsPath, JSON.stringify(config, null, 2) + "\n");
|
|
121
|
-
const { loadWorldFromDirectory } = await import("./world-loader-
|
|
121
|
+
const { loadWorldFromDirectory } = await import("./world-loader-YTYFOP7D.js");
|
|
122
122
|
const world = await loadWorldFromDirectory(worldDir);
|
|
123
123
|
const report = validateWorld(world);
|
|
124
124
|
return {
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
} from "./chunk-ZAF6JH23.js";
|
|
8
8
|
import {
|
|
9
9
|
loadWorld
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-I4RTIMLX.js";
|
|
11
11
|
|
|
12
12
|
// src/worlds/mentraos-intent-taxonomy.ts
|
|
13
13
|
var MENTRA_INTENT_TAXONOMY = [
|
|
@@ -632,6 +632,7 @@ var MentraGovernedExecutor = class {
|
|
|
632
632
|
_userRules;
|
|
633
633
|
_emergencyOverride = false;
|
|
634
634
|
_emergencyActivatedAt = null;
|
|
635
|
+
_spatialSession = null;
|
|
635
636
|
constructor(world, options = {}, userRules = DEFAULT_USER_RULES) {
|
|
636
637
|
this.world = world;
|
|
637
638
|
this.options = options;
|
|
@@ -688,13 +689,36 @@ var MentraGovernedExecutor = class {
|
|
|
688
689
|
get emergencyActivatedAt() {
|
|
689
690
|
return this._emergencyActivatedAt;
|
|
690
691
|
}
|
|
692
|
+
// ── Spatial Governance (optional) ────────────────────────────────────────
|
|
693
|
+
/**
|
|
694
|
+
* Attach a spatial session to this executor.
|
|
695
|
+
*
|
|
696
|
+
* When attached, intents are evaluated against the spatial context
|
|
697
|
+
* (zone rules + handshake rules) AFTER user rules but BEFORE
|
|
698
|
+
* hardware and platform checks. This is Layer 1.5.
|
|
699
|
+
*
|
|
700
|
+
* Pass null to detach (e.g., when leaving a zone).
|
|
701
|
+
*/
|
|
702
|
+
setSpatialSession(session) {
|
|
703
|
+
this._spatialSession = session;
|
|
704
|
+
}
|
|
705
|
+
/** Whether a spatial session is currently active */
|
|
706
|
+
get hasSpatialSession() {
|
|
707
|
+
return this._spatialSession !== null;
|
|
708
|
+
}
|
|
709
|
+
/** Get the current spatial session description */
|
|
710
|
+
get spatialDescription() {
|
|
711
|
+
return this._spatialSession?.description ?? null;
|
|
712
|
+
}
|
|
691
713
|
/**
|
|
692
714
|
* Evaluate an intent against user rules + platform world.
|
|
693
715
|
*
|
|
694
716
|
* Three-layer evaluation:
|
|
695
|
-
* 0. Emergency override — if active, skip governance (layers 1 + 3),
|
|
717
|
+
* 0. Emergency override — if active, skip governance (layers 1 + 1.5 + 3),
|
|
696
718
|
* but STILL enforce platform constraints (layer 2)
|
|
697
719
|
* 1. User rules check — personal governance override, can BLOCK or PAUSE
|
|
720
|
+
* 1.5. Spatial governance — zone + handshake rules (optional, temporary)
|
|
721
|
+
* ↑ ONLY ACTIVE when a spatial session is attached
|
|
698
722
|
* 2. Hardware capability check — validates glasses support
|
|
699
723
|
* ↑ THIS IS A PLATFORM CONSTRAINT — never overridden
|
|
700
724
|
* 3. Platform guard engine — full world rule evaluation
|
|
@@ -725,6 +749,47 @@ var MentraGovernedExecutor = class {
|
|
|
725
749
|
return result2;
|
|
726
750
|
}
|
|
727
751
|
}
|
|
752
|
+
if (!this._emergencyOverride && this._spatialSession) {
|
|
753
|
+
const spatialResult = this._spatialSession.evaluate(intent);
|
|
754
|
+
if (!spatialResult.allowed && !spatialResult.requiresConfirmation) {
|
|
755
|
+
const verdict2 = {
|
|
756
|
+
status: "BLOCK",
|
|
757
|
+
ruleId: "spatial-zone-rule",
|
|
758
|
+
reason: spatialResult.reason,
|
|
759
|
+
evidence: makeEvidence("spatial-zone-rule")
|
|
760
|
+
};
|
|
761
|
+
const result2 = {
|
|
762
|
+
allowed: false,
|
|
763
|
+
requiresConfirmation: false,
|
|
764
|
+
verdict: verdict2,
|
|
765
|
+
intentDef,
|
|
766
|
+
appContext,
|
|
767
|
+
decidingLayer: "spatial"
|
|
768
|
+
};
|
|
769
|
+
this.options.onBlock?.(result2);
|
|
770
|
+
this.options.onEvaluate?.(result2);
|
|
771
|
+
return result2;
|
|
772
|
+
}
|
|
773
|
+
if (spatialResult.requiresConfirmation) {
|
|
774
|
+
const verdict2 = {
|
|
775
|
+
status: "PAUSE",
|
|
776
|
+
ruleId: "spatial-zone-rule",
|
|
777
|
+
reason: spatialResult.reason,
|
|
778
|
+
evidence: makeEvidence("spatial-zone-rule")
|
|
779
|
+
};
|
|
780
|
+
const result2 = {
|
|
781
|
+
allowed: false,
|
|
782
|
+
requiresConfirmation: true,
|
|
783
|
+
verdict: verdict2,
|
|
784
|
+
intentDef,
|
|
785
|
+
appContext,
|
|
786
|
+
decidingLayer: "spatial"
|
|
787
|
+
};
|
|
788
|
+
this.options.onPause?.(result2);
|
|
789
|
+
this.options.onEvaluate?.(result2);
|
|
790
|
+
return result2;
|
|
791
|
+
}
|
|
792
|
+
}
|
|
728
793
|
if (intentDef && glassesModel && !intentDef.supported_glasses.includes(glassesModel)) {
|
|
729
794
|
const verdict2 = {
|
|
730
795
|
status: "BLOCK",
|
|
@@ -96,8 +96,8 @@ async function loadBundledWorld(name = DEFAULT_BUNDLED_WORLD) {
|
|
|
96
96
|
const { join, dirname } = await import("path");
|
|
97
97
|
const { existsSync } = await import("fs");
|
|
98
98
|
const { fileURLToPath } = await import("url");
|
|
99
|
-
const { parseWorldMarkdown } = await import("./bootstrap-parser
|
|
100
|
-
const { emitWorldDefinition } = await import("./bootstrap-emitter
|
|
99
|
+
const { parseWorldMarkdown } = await import("./engine/bootstrap-parser.js");
|
|
100
|
+
const { emitWorldDefinition } = await import("./engine/bootstrap-emitter.js");
|
|
101
101
|
const filename = `${name}.nv-world.md`;
|
|
102
102
|
let packageRoot;
|
|
103
103
|
try {
|
|
@@ -5,14 +5,14 @@ import {
|
|
|
5
5
|
import {
|
|
6
6
|
evaluateGuard
|
|
7
7
|
} from "./chunk-ZAF6JH23.js";
|
|
8
|
+
import {
|
|
9
|
+
loadWorld
|
|
10
|
+
} from "./chunk-I4RTIMLX.js";
|
|
8
11
|
import {
|
|
9
12
|
advancePlan,
|
|
10
13
|
evaluatePlan,
|
|
11
14
|
getPlanProgress
|
|
12
15
|
} from "./chunk-QLPTHTVB.js";
|
|
13
|
-
import {
|
|
14
|
-
loadWorld
|
|
15
|
-
} from "./chunk-BXLTEUS4.js";
|
|
16
16
|
|
|
17
17
|
// src/runtime/mcp-server.ts
|
|
18
18
|
import { execSync } from "child_process";
|
|
@@ -7,14 +7,14 @@ import {
|
|
|
7
7
|
import {
|
|
8
8
|
evaluateGuard
|
|
9
9
|
} from "./chunk-ZAF6JH23.js";
|
|
10
|
+
import {
|
|
11
|
+
loadWorld
|
|
12
|
+
} from "./chunk-I4RTIMLX.js";
|
|
10
13
|
import {
|
|
11
14
|
advancePlan,
|
|
12
15
|
evaluatePlan,
|
|
13
16
|
getPlanProgress
|
|
14
17
|
} from "./chunk-QLPTHTVB.js";
|
|
15
|
-
import {
|
|
16
|
-
loadWorld
|
|
17
|
-
} from "./chunk-BXLTEUS4.js";
|
|
18
18
|
|
|
19
19
|
// src/runtime/session.ts
|
|
20
20
|
async function defaultToolExecutor(name, args) {
|