@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
|
@@ -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
|
+
};
|
|
@@ -6,10 +6,10 @@ import {
|
|
|
6
6
|
} from "./chunk-5U2MQO5P.js";
|
|
7
7
|
import {
|
|
8
8
|
evaluateGuard
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-ZAF6JH23.js";
|
|
10
10
|
import {
|
|
11
11
|
loadWorld
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-I4RTIMLX.js";
|
|
13
13
|
|
|
14
14
|
// src/adapters/openclaw.ts
|
|
15
15
|
var GovernanceBlockedError2 = class extends GovernanceBlockedError {
|
|
@@ -20,15 +20,25 @@ function simulateWorld(world, options = {}) {
|
|
|
20
20
|
let collapseStep;
|
|
21
21
|
let collapseRule;
|
|
22
22
|
const sortedRules = [...world.rules].sort((a, b) => a.order - b.order);
|
|
23
|
+
const allEvents = options.events ?? [];
|
|
24
|
+
const eventsByStep = Array.from({ length: steps }, () => []);
|
|
25
|
+
for (let i = 0; i < allEvents.length; i++) {
|
|
26
|
+
const stepIdx = Math.min(i, steps - 1);
|
|
27
|
+
eventsByStep[stepIdx].push(allEvents[i]);
|
|
28
|
+
}
|
|
29
|
+
let totalEventsConsumed = 0;
|
|
23
30
|
for (let stepNum = 1; stepNum <= steps; stepNum++) {
|
|
24
31
|
if (collapsed) break;
|
|
32
|
+
const stepEvents = eventsByStep[stepNum - 1];
|
|
25
33
|
const stepResult = evaluateStep(
|
|
26
34
|
stepNum,
|
|
27
35
|
sortedRules,
|
|
28
36
|
state,
|
|
29
37
|
assumptions,
|
|
30
|
-
world
|
|
38
|
+
world,
|
|
39
|
+
stepEvents
|
|
31
40
|
);
|
|
41
|
+
totalEventsConsumed += stepResult.eventsApplied.length;
|
|
32
42
|
simulationSteps.push(stepResult);
|
|
33
43
|
if (stepResult.collapsed) {
|
|
34
44
|
collapsed = true;
|
|
@@ -47,14 +57,38 @@ function simulateWorld(world, options = {}) {
|
|
|
47
57
|
finalViability,
|
|
48
58
|
collapsed,
|
|
49
59
|
collapseStep,
|
|
50
|
-
collapseRule
|
|
60
|
+
collapseRule,
|
|
61
|
+
eventsConsumed: totalEventsConsumed
|
|
51
62
|
};
|
|
52
63
|
}
|
|
53
|
-
function evaluateStep(stepNum, rules, state, assumptions, world) {
|
|
64
|
+
function evaluateStep(stepNum, rules, state, assumptions, world, events = []) {
|
|
54
65
|
const evaluations = [];
|
|
66
|
+
const eventApplications = [];
|
|
55
67
|
let rulesFired = 0;
|
|
56
68
|
let collapsed = false;
|
|
57
69
|
const firedRuleIds = /* @__PURE__ */ new Set();
|
|
70
|
+
for (const evt of events) {
|
|
71
|
+
const application = {
|
|
72
|
+
eventType: evt.type,
|
|
73
|
+
rulesTriggered: [],
|
|
74
|
+
effects: []
|
|
75
|
+
};
|
|
76
|
+
for (const rule of rules) {
|
|
77
|
+
const eventTrigger = rule.triggers.find(
|
|
78
|
+
(t) => t.field === "event" && t.source === "state"
|
|
79
|
+
);
|
|
80
|
+
if (!eventTrigger) continue;
|
|
81
|
+
const matches = evaluateOperator(evt.type, eventTrigger.operator, eventTrigger.value);
|
|
82
|
+
if (!matches) continue;
|
|
83
|
+
application.rulesTriggered.push(rule.id);
|
|
84
|
+
firedRuleIds.add(rule.id);
|
|
85
|
+
for (const effect of rule.effects ?? []) {
|
|
86
|
+
const applied = applyEffect(effect, state);
|
|
87
|
+
if (applied) application.effects.push(applied);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
eventApplications.push(application);
|
|
91
|
+
}
|
|
58
92
|
for (const rule of rules) {
|
|
59
93
|
if (collapsed) {
|
|
60
94
|
evaluations.push({
|
|
@@ -139,6 +173,7 @@ function evaluateStep(stepNum, rules, state, assumptions, world) {
|
|
|
139
173
|
const viability = classifyViability(state, world);
|
|
140
174
|
return {
|
|
141
175
|
step: stepNum,
|
|
176
|
+
eventsApplied: eventApplications,
|
|
142
177
|
rulesEvaluated: evaluations,
|
|
143
178
|
rulesFired,
|
|
144
179
|
stateAfter: { ...state },
|
|
@@ -260,6 +295,19 @@ function renderSimulateText(result) {
|
|
|
260
295
|
lines.push("");
|
|
261
296
|
for (const step of result.steps) {
|
|
262
297
|
lines.push(`STEP ${step.step}`);
|
|
298
|
+
if (step.eventsApplied && step.eventsApplied.length > 0) {
|
|
299
|
+
for (const evt of step.eventsApplied) {
|
|
300
|
+
lines.push(` EVENT: ${evt.eventType}`);
|
|
301
|
+
if (evt.rulesTriggered.length > 0) {
|
|
302
|
+
lines.push(` Rules triggered: ${evt.rulesTriggered.join(", ")}`);
|
|
303
|
+
}
|
|
304
|
+
for (const effect of evt.effects) {
|
|
305
|
+
const beforeStr = formatValue(effect.before);
|
|
306
|
+
const afterStr = formatValue(effect.after);
|
|
307
|
+
lines.push(` ${effect.target}: ${beforeStr} -> ${afterStr}`);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
263
311
|
const fired = step.rulesEvaluated.filter((r) => r.triggered);
|
|
264
312
|
const skipped = step.rulesEvaluated.filter((r) => !r.triggered && !r.excluded);
|
|
265
313
|
const excluded = step.rulesEvaluated.filter((r) => r.excluded);
|
|
@@ -295,6 +343,9 @@ function renderSimulateText(result) {
|
|
|
295
343
|
lines.push(` ${key}: ${formatValue(value)}${marker}`);
|
|
296
344
|
}
|
|
297
345
|
lines.push("");
|
|
346
|
+
if (result.eventsConsumed > 0) {
|
|
347
|
+
lines.push(`EVENTS CONSUMED: ${result.eventsConsumed}`);
|
|
348
|
+
}
|
|
298
349
|
lines.push(`VIABILITY: ${result.finalViability}`);
|
|
299
350
|
if (result.collapsed) {
|
|
300
351
|
lines.push(`COLLAPSED at step ${result.collapseStep} (rule: ${result.collapseRule})`);
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import {
|
|
2
|
-
loadConfig
|
|
3
|
-
} from "./chunk-OT6PXH54.js";
|
|
4
1
|
import {
|
|
5
2
|
createProvider
|
|
6
3
|
} from "./chunk-INWQHLPS.js";
|
|
4
|
+
import {
|
|
5
|
+
loadConfig
|
|
6
|
+
} from "./chunk-OT6PXH54.js";
|
|
7
7
|
import {
|
|
8
8
|
validateWorld
|
|
9
9
|
} from "./chunk-7P3S7MAY.js";
|
|
10
|
-
import {
|
|
11
|
-
parseWorldMarkdown
|
|
12
|
-
} from "./chunk-EMQDLDAF.js";
|
|
13
10
|
import {
|
|
14
11
|
emitWorldDefinition
|
|
15
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-YPCVY4GS.js";
|
|
13
|
+
import {
|
|
14
|
+
parseWorldMarkdown
|
|
15
|
+
} from "./chunk-3NZMMSOW.js";
|
|
16
16
|
|
|
17
17
|
// src/engine/derive-normalizer.ts
|
|
18
18
|
function findSections(lines) {
|
|
@@ -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,10 +7,10 @@ import {
|
|
|
7
7
|
} from "./chunk-5U2MQO5P.js";
|
|
8
8
|
import {
|
|
9
9
|
evaluateGuard
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-ZAF6JH23.js";
|
|
11
11
|
import {
|
|
12
12
|
loadWorld
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-I4RTIMLX.js";
|
|
14
14
|
|
|
15
15
|
// src/adapters/openai.ts
|
|
16
16
|
var GovernanceBlockedError2 = class extends GovernanceBlockedError {
|