@neuroverseos/governance 0.2.1 → 0.2.3
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/.well-known/ai-plugin.json +26 -0
- package/.well-known/mcp.json +68 -0
- package/AGENTS.md +219 -0
- package/README.md +84 -4
- package/dist/adapters/autoresearch.cjs +196 -0
- package/dist/adapters/autoresearch.d.cts +103 -0
- package/dist/adapters/autoresearch.d.ts +103 -0
- package/dist/adapters/autoresearch.js +7 -0
- package/dist/adapters/deep-agents.cjs +1472 -0
- package/dist/adapters/deep-agents.d.cts +181 -0
- package/dist/adapters/deep-agents.d.ts +181 -0
- package/dist/adapters/deep-agents.js +17 -0
- package/dist/adapters/express.cjs +103 -21
- package/dist/adapters/express.d.cts +1 -1
- package/dist/adapters/express.d.ts +1 -1
- package/dist/adapters/express.js +3 -3
- package/dist/adapters/index.cjs +678 -102
- package/dist/adapters/index.d.cts +4 -1
- package/dist/adapters/index.d.ts +4 -1
- package/dist/adapters/index.js +39 -13
- package/dist/adapters/langchain.cjs +181 -47
- package/dist/adapters/langchain.d.cts +5 -5
- package/dist/adapters/langchain.d.ts +5 -5
- package/dist/adapters/langchain.js +4 -3
- package/dist/adapters/openai.cjs +183 -49
- package/dist/adapters/openai.d.cts +5 -5
- package/dist/adapters/openai.d.ts +5 -5
- package/dist/adapters/openai.js +4 -3
- package/dist/adapters/openclaw.cjs +181 -47
- package/dist/adapters/openclaw.d.cts +5 -5
- package/dist/adapters/openclaw.d.ts +5 -5
- package/dist/adapters/openclaw.js +4 -3
- package/dist/{build-P42YFKQV.js → build-X5MZY4IA.js} +2 -2
- package/dist/{chunk-ZL4AHY4X.js → chunk-4L6OPKMQ.js} +1 -1
- package/dist/chunk-5U2MQO5P.js +57 -0
- package/dist/{chunk-UPJNTSVM.js → chunk-6BB55YJI.js} +16 -31
- package/dist/{chunk-37JG24WH.js → chunk-6CZSKEY5.js} +3 -0
- package/dist/{chunk-5EDDNJU6.js → chunk-AF2VX4AL.js} +52 -10
- package/dist/chunk-BQZMOEML.js +43 -0
- package/dist/chunk-D2UCV5AK.js +326 -0
- package/dist/{chunk-IVPKFJX3.js → chunk-EVDJUSZ2.js} +16 -31
- package/dist/{chunk-PQBJBVSW.js → chunk-IZSO75NZ.js} +72 -7
- package/dist/chunk-JCKSW2PZ.js +304 -0
- package/dist/{chunk-ADV7Q2LJ.js → chunk-KTFTTLTP.js} +25 -4
- package/dist/{chunk-MWDQ4MJB.js → chunk-MH7BT4VH.js} +5 -1
- package/dist/{chunk-P74Y66ZV.js → chunk-QLPTHTVB.js} +66 -18
- package/dist/{chunk-2JQJ5U5X.js → chunk-REXY4LUL.js} +49 -10
- package/dist/chunk-T5EUJQE5.js +172 -0
- package/dist/{chunk-PAX2P6ZP.js → chunk-TTBKTF3P.js} +15 -8
- package/dist/{chunk-TINSRYXQ.js → chunk-ZIVQNSZU.js} +16 -33
- package/dist/{chunk-BUWWN2NX.js → chunk-ZJTDUCC2.js} +9 -7
- package/dist/cli/neuroverse.cjs +2648 -495
- package/dist/cli/neuroverse.js +39 -15
- package/dist/cli/plan.cjs +178 -46
- package/dist/cli/plan.js +33 -26
- package/dist/cli/run.cjs +257 -28
- package/dist/cli/run.js +2 -2
- package/dist/decision-flow-LETV5NWY.js +61 -0
- package/dist/{derive-TLIV4OOU.js → derive-7365SUFU.js} +2 -2
- package/dist/{doctor-V72UM2TC.js → doctor-QYISMKEL.js} +5 -2
- package/dist/equity-penalties-63FGB3I2.js +244 -0
- package/dist/{explain-IDCRWMPX.js → explain-A2EWI2OL.js} +4 -23
- package/dist/{guard-WA3FCCIO.js → guard-3BWL3IGH.js} +6 -10
- package/dist/{guard-contract-D-2LQInm.d.ts → guard-contract-C9_zKbzd.d.cts} +155 -5
- package/dist/{guard-contract-D-2LQInm.d.cts → guard-contract-C9_zKbzd.d.ts} +155 -5
- package/dist/{guard-engine-D7X4CVAE.js → guard-engine-QFMIBWJY.js} +2 -2
- package/dist/{impact-BWULZ5RP.js → impact-UB6DXKSX.js} +4 -4
- package/dist/{improve-GPUBKTEA.js → improve-XZA57GER.js} +5 -24
- package/dist/index.cjs +639 -51
- package/dist/index.d.cts +235 -7
- package/dist/index.d.ts +235 -7
- package/dist/index.js +92 -41
- package/dist/infer-world-7GVZWFX4.js +543 -0
- package/dist/init-world-VWMQZQC7.js +223 -0
- package/dist/{mcp-server-YUOQP4M5.js → mcp-server-XWQZXNW7.js} +3 -3
- package/dist/{playground-CBXMAW2B.js → playground-ADWZORNV.js} +2 -2
- package/dist/{redteam-SSNABQ7W.js → redteam-JRQ7FD2F.js} +2 -2
- package/dist/{session-MWRBTCYX.js → session-MMYX5YCF.js} +4 -3
- package/dist/shared--Q8wPBVN.d.ts +60 -0
- package/dist/shared-HpAG90PX.d.cts +60 -0
- package/dist/shared-U2QFV7JH.js +16 -0
- package/dist/{simulate-VDOYQFRO.js → simulate-GMIFFXYV.js} +5 -30
- package/dist/{test-3GZSG5FR.js → test-JBBZ65X4.js} +2 -2
- package/dist/{trace-TM4Z7G73.js → trace-3MYWIDEF.js} +3 -3
- package/dist/worlds/autoresearch.nv-world.md +230 -0
- package/dist/worlds/coding-agent.nv-world.md +211 -0
- package/llms.txt +79 -0
- package/openapi.yaml +230 -0
- package/package.json +26 -4
- package/dist/{chunk-GR6DGCZ2.js → chunk-BMOXICAB.js} +3 -3
- package/dist/{chunk-NF5POFCI.js → chunk-ORJ3NOE6.js} +3 -3
- package/dist/{world-LAXO6DOX.js → world-BFJCIQSH.js} +3 -3
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema_version": "v1",
|
|
3
|
+
"name": "neuroverse-governance",
|
|
4
|
+
"description": "Enforce governance rules on AI agent actions. Turn plans into enforceable constraints. Deterministic evaluation — no LLM in the loop.",
|
|
5
|
+
"capabilities": {
|
|
6
|
+
"plan_enforcement": {
|
|
7
|
+
"description": "Compile a plan into enforceable rules. Block actions outside the plan. Track progress.",
|
|
8
|
+
"input": "Plan markdown or JSON",
|
|
9
|
+
"output": "ON_PLAN / OFF_PLAN / CONSTRAINT_VIOLATED / PLAN_COMPLETE verdict with evidence"
|
|
10
|
+
},
|
|
11
|
+
"world_governance": {
|
|
12
|
+
"description": "Full governance engine with invariants, guards, roles, kernel rules, and audit trails.",
|
|
13
|
+
"input": "GuardEvent JSON",
|
|
14
|
+
"output": "ALLOW / BLOCK / PAUSE verdict with trace"
|
|
15
|
+
},
|
|
16
|
+
"plan_derive": {
|
|
17
|
+
"description": "Generate a full governance world from a plan markdown file.",
|
|
18
|
+
"input": "Plan markdown",
|
|
19
|
+
"output": "World definition files (world.json, invariants.json, guards.json)"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"install": "npm install @neuroverseos/governance",
|
|
23
|
+
"adapters": ["openclaw", "langchain", "openai", "express"],
|
|
24
|
+
"cli": "neuroverse",
|
|
25
|
+
"repository": "https://github.com/NeuroverseOS/Neuroverseos-governance"
|
|
26
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema_version": "1.0",
|
|
3
|
+
"server": {
|
|
4
|
+
"name": "neuroverse-governance",
|
|
5
|
+
"version": "0.2.2",
|
|
6
|
+
"description": "Deterministic governance engine for AI agents. Evaluates actions against world rules and plan constraints. Returns ALLOW, BLOCK, or PAUSE verdicts.",
|
|
7
|
+
"vendor": "NeuroverseOS",
|
|
8
|
+
"homepage": "https://neuroverseos.com",
|
|
9
|
+
"repository": "https://github.com/NeuroverseOS/Neuroverseos-governance"
|
|
10
|
+
},
|
|
11
|
+
"install": {
|
|
12
|
+
"npm": "@neuroverseos/governance",
|
|
13
|
+
"command": "npx @neuroverseos/governance mcp --world ./world"
|
|
14
|
+
},
|
|
15
|
+
"capabilities": {
|
|
16
|
+
"tools": true,
|
|
17
|
+
"resources": false,
|
|
18
|
+
"prompts": false
|
|
19
|
+
},
|
|
20
|
+
"tools": [
|
|
21
|
+
{
|
|
22
|
+
"name": "neuroverse_guard",
|
|
23
|
+
"description": "Evaluate whether an agent action is allowed by governance rules. Returns ALLOW, BLOCK, or PAUSE.",
|
|
24
|
+
"inputSchema": {
|
|
25
|
+
"type": "object",
|
|
26
|
+
"required": ["intent"],
|
|
27
|
+
"properties": {
|
|
28
|
+
"intent": { "type": "string", "description": "What the agent wants to do" },
|
|
29
|
+
"tool": { "type": "string", "description": "Tool being invoked" },
|
|
30
|
+
"scope": { "type": "string", "description": "Resource being accessed" }
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"name": "neuroverse_plan_check",
|
|
36
|
+
"description": "Check whether an action matches a step in the active plan. Returns ON_PLAN, OFF_PLAN, CONSTRAINT_VIOLATED, or PLAN_COMPLETE.",
|
|
37
|
+
"inputSchema": {
|
|
38
|
+
"type": "object",
|
|
39
|
+
"required": ["intent"],
|
|
40
|
+
"properties": {
|
|
41
|
+
"intent": { "type": "string", "description": "What the agent wants to do" }
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"name": "neuroverse_plan_advance",
|
|
47
|
+
"description": "Mark a plan step as completed. In verified mode, requires evidence for steps with a verify field.",
|
|
48
|
+
"inputSchema": {
|
|
49
|
+
"type": "object",
|
|
50
|
+
"required": ["stepId"],
|
|
51
|
+
"properties": {
|
|
52
|
+
"stepId": { "type": "string", "description": "Step ID to advance" },
|
|
53
|
+
"evidenceType": { "type": "string", "description": "Evidence type (must match step verify field)" },
|
|
54
|
+
"evidenceProof": { "type": "string", "description": "Proof payload (URL, hash, etc.)" }
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"name": "neuroverse_plan_status",
|
|
60
|
+
"description": "Get current plan progress — completed steps, total steps, percentage.",
|
|
61
|
+
"inputSchema": {
|
|
62
|
+
"type": "object",
|
|
63
|
+
"properties": {}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
],
|
|
67
|
+
"tags": ["governance", "ai-safety", "agent-guardrails", "deterministic", "plan-enforcement"]
|
|
68
|
+
}
|
package/AGENTS.md
ADDED
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
# NeuroVerse Governance — Agent Integration Guide
|
|
2
|
+
|
|
3
|
+
## What This Package Does
|
|
4
|
+
|
|
5
|
+
Runtime containment for AI agents. Define what an agent can and cannot do, then enforce it at every action. Deterministic — same event + same rules = same verdict. No LLM in the evaluation loop.
|
|
6
|
+
|
|
7
|
+
## Quick Start for Agents
|
|
8
|
+
|
|
9
|
+
### Install
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install @neuroverseos/governance
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
### Enforce a world (permanent rules)
|
|
16
|
+
|
|
17
|
+
```javascript
|
|
18
|
+
const { evaluateGuard, loadWorld } = require('@neuroverseos/governance');
|
|
19
|
+
|
|
20
|
+
const world = await loadWorld('./world/');
|
|
21
|
+
const verdict = evaluateGuard({ intent: 'delete user', tool: 'db' }, world);
|
|
22
|
+
// → { status: 'BLOCK', reason: 'destructive database operation' }
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Enforce a plan (temporary task scope)
|
|
26
|
+
|
|
27
|
+
```javascript
|
|
28
|
+
const { evaluatePlan, parsePlanMarkdown } = require('@neuroverseos/governance');
|
|
29
|
+
|
|
30
|
+
const plan = parsePlanMarkdown(planMarkdownString);
|
|
31
|
+
const verdict = evaluatePlan({ intent: 'send email', tool: 'smtp' }, plan.plan);
|
|
32
|
+
// → { allowed: false, status: 'OFF_PLAN', reason: 'Action does not match any plan step.' }
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Enforce both (plan on top of world)
|
|
36
|
+
|
|
37
|
+
```javascript
|
|
38
|
+
const verdict = evaluateGuard(event, world, { plan });
|
|
39
|
+
// Plan rules AND world rules both apply
|
|
40
|
+
// Plan can only restrict, never expand
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Guard with trace (see what fired)
|
|
44
|
+
|
|
45
|
+
```javascript
|
|
46
|
+
const verdict = evaluateGuard(event, world, { trace: true, level: 'strict' });
|
|
47
|
+
// verdict.trace contains:
|
|
48
|
+
// safetyChecks, guardChecks, kernelRuleChecks, levelChecks, invariantChecks
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Available Commands
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
neuroverse init Scaffold a .nv-world.md template
|
|
55
|
+
neuroverse bootstrap --input <.md> --output <dir> Compile to world JSON
|
|
56
|
+
neuroverse build <input.md> Derive + compile in one step
|
|
57
|
+
neuroverse validate --world <dir> 9 static analysis checks
|
|
58
|
+
neuroverse guard --world <dir> Evaluate action (stdin → verdict)
|
|
59
|
+
neuroverse test --world <dir> 14 standard + fuzz guard tests
|
|
60
|
+
neuroverse redteam --world <dir> 28 adversarial attacks, containment score
|
|
61
|
+
neuroverse doctor Environment sanity check
|
|
62
|
+
neuroverse playground --world <dir> Interactive web demo at localhost:4242
|
|
63
|
+
neuroverse explain <world> Human-readable world summary
|
|
64
|
+
neuroverse simulate <world> State evolution simulation
|
|
65
|
+
neuroverse improve <world> Actionable improvement suggestions
|
|
66
|
+
neuroverse plan compile <plan.md> Parse plan markdown into plan.json
|
|
67
|
+
neuroverse plan check --plan plan.json Check action against plan (stdin)
|
|
68
|
+
neuroverse plan status --plan plan.json Show plan progress
|
|
69
|
+
neuroverse plan advance <step_id> Mark a step as completed
|
|
70
|
+
neuroverse plan derive <plan.md> Generate a full world from a plan
|
|
71
|
+
neuroverse run --world <dir> Governed runtime (pipe or interactive)
|
|
72
|
+
neuroverse mcp --world <dir> MCP governance server
|
|
73
|
+
neuroverse trace --log <path> Action audit log
|
|
74
|
+
neuroverse impact --log <path> Counterfactual impact report
|
|
75
|
+
neuroverse world status|diff|snapshot|rollback World management
|
|
76
|
+
neuroverse worlds List available worlds
|
|
77
|
+
neuroverse derive --input <path> AI-assisted world synthesis
|
|
78
|
+
neuroverse configure-ai Configure AI provider credentials
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Plan Markdown Format
|
|
82
|
+
|
|
83
|
+
Plans are written in simple markdown that any LLM can produce:
|
|
84
|
+
|
|
85
|
+
```markdown
|
|
86
|
+
---
|
|
87
|
+
plan_id: product_launch
|
|
88
|
+
objective: Launch the NeuroVerse governance plugin
|
|
89
|
+
sequential: false
|
|
90
|
+
completion: verified
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
# Steps
|
|
94
|
+
- Write announcement blog post [tag: content, marketing]
|
|
95
|
+
- Publish GitHub release [tag: deploy] [verify: github_release_created]
|
|
96
|
+
- Post on Product Hunt (after: publish_github_release) [tag: marketing]
|
|
97
|
+
|
|
98
|
+
# Constraints
|
|
99
|
+
- No spending above $500
|
|
100
|
+
- All external posts require human review [type: approval]
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Completion modes
|
|
104
|
+
|
|
105
|
+
- `completion: trust` (default) — caller says "done", step advances
|
|
106
|
+
- `completion: verified` — steps with `[verify: ...]` require evidence to advance
|
|
107
|
+
|
|
108
|
+
```javascript
|
|
109
|
+
// Trust mode — just advance
|
|
110
|
+
const result = advancePlan(plan, 'write_announcement_blog_post');
|
|
111
|
+
// → { success: true, plan: <updated> }
|
|
112
|
+
|
|
113
|
+
// Verified mode — evidence required for steps with verify
|
|
114
|
+
const result = advancePlan(plan, 'publish_github_release', {
|
|
115
|
+
type: 'github_release_created',
|
|
116
|
+
proof: 'https://github.com/org/repo/releases/v1.0',
|
|
117
|
+
});
|
|
118
|
+
// → { success: true, plan: <updated>, evidence: { ... } }
|
|
119
|
+
|
|
120
|
+
// Verified mode — missing evidence
|
|
121
|
+
const result = advancePlan(plan, 'publish_github_release');
|
|
122
|
+
// → { success: false, reason: 'Step requires evidence (verify: github_release_created)' }
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Governance Model
|
|
126
|
+
|
|
127
|
+
```
|
|
128
|
+
Safety checks → Plan enforcement → Role rules → Guards → Kernel
|
|
129
|
+
(country laws) (mom's trip rules) (driving laws) (domain) (boundaries)
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Plans are temporary guard overlays. They define task scope.
|
|
133
|
+
Worlds are permanent governance. They define domain rules.
|
|
134
|
+
Both layers must pass for an action to be allowed.
|
|
135
|
+
|
|
136
|
+
## Evaluation Pipeline
|
|
137
|
+
|
|
138
|
+
Every action passes through 6 phases:
|
|
139
|
+
|
|
140
|
+
1. **Safety** — prompt injection, scope escape, data exfil detection (always on)
|
|
141
|
+
2. **Plan** — is the action within the current mission scope?
|
|
142
|
+
3. **Roles** — does the actor have permission?
|
|
143
|
+
4. **Guards** — do domain-specific rules allow it?
|
|
144
|
+
5. **Kernel** — does it violate LLM boundary rules?
|
|
145
|
+
6. **Level** — does enforcement strictness allow it?
|
|
146
|
+
|
|
147
|
+
First BLOCK wins. If nothing blocks, ALLOW.
|
|
148
|
+
|
|
149
|
+
## Adapters
|
|
150
|
+
|
|
151
|
+
### OpenAI
|
|
152
|
+
|
|
153
|
+
```javascript
|
|
154
|
+
import { createGovernedToolExecutor } from '@neuroverseos/governance/adapters/openai';
|
|
155
|
+
|
|
156
|
+
const executor = await createGovernedToolExecutor('./world/', { trace: true, plan });
|
|
157
|
+
const result = await executor.execute(toolCall, myToolRunner);
|
|
158
|
+
// ALLOW → runs tool | BLOCK → returns blocked | PAUSE → throws
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### LangChain
|
|
162
|
+
|
|
163
|
+
```javascript
|
|
164
|
+
import { createNeuroVerseCallbackHandler } from '@neuroverseos/governance/adapters/langchain';
|
|
165
|
+
|
|
166
|
+
const handler = await createNeuroVerseCallbackHandler('./world/', {
|
|
167
|
+
plan,
|
|
168
|
+
onBlock: (verdict) => console.log('Blocked:', verdict.reason),
|
|
169
|
+
});
|
|
170
|
+
const agent = new AgentExecutor({ ..., callbacks: [handler] });
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### OpenClaw
|
|
174
|
+
|
|
175
|
+
```javascript
|
|
176
|
+
import { createNeuroVersePlugin } from '@neuroverseos/governance/adapters/openclaw';
|
|
177
|
+
|
|
178
|
+
const plugin = await createNeuroVersePlugin('./world/', { plan });
|
|
179
|
+
agent.use(plugin.hooks());
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### Express / Fastify
|
|
183
|
+
|
|
184
|
+
```javascript
|
|
185
|
+
import { createGovernanceMiddleware } from '@neuroverseos/governance/adapters/express';
|
|
186
|
+
|
|
187
|
+
const middleware = await createGovernanceMiddleware('./world/', { level: 'strict' });
|
|
188
|
+
app.use('/api', middleware);
|
|
189
|
+
// Returns 403 on BLOCK
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### MCP Server
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
neuroverse mcp --world ./world --plan plan.json
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
Exposes governed tools over Model Context Protocol. Works with Claude, Cursor, and any MCP client.
|
|
199
|
+
|
|
200
|
+
## Exit Codes
|
|
201
|
+
|
|
202
|
+
- 0 = ALLOW / ON_PLAN / SUCCESS
|
|
203
|
+
- 1 = BLOCK / OFF_PLAN / FAIL
|
|
204
|
+
- 2 = PAUSE / CONSTRAINT_VIOLATED
|
|
205
|
+
- 3 = ERROR
|
|
206
|
+
- 4 = PLAN_COMPLETE
|
|
207
|
+
|
|
208
|
+
## Containment Testing
|
|
209
|
+
|
|
210
|
+
```bash
|
|
211
|
+
# Standard guard test suite (14 tests + optional fuzz)
|
|
212
|
+
neuroverse test --world ./world --fuzz --count 50
|
|
213
|
+
|
|
214
|
+
# Adversarial red team (28 attacks, 6 categories)
|
|
215
|
+
neuroverse redteam --world ./world --level strict
|
|
216
|
+
# → Containment score: 91%
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
Red team categories: prompt injection (8), tool escalation (4), scope escape (5), data exfiltration (3), identity manipulation (3), constraint bypass (3).
|
package/README.md
CHANGED
|
@@ -11,10 +11,38 @@ AI agent → NeuroVerse → real system
|
|
|
11
11
|
|
|
12
12
|
Deterministic. No LLM in the evaluation loop. Same event + same rules = same verdict, every time.
|
|
13
13
|
|
|
14
|
+
## Quick start
|
|
15
|
+
|
|
16
|
+
Create a governed research environment:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npx @neuroverseos/governance init-world autoresearch \
|
|
20
|
+
--context "attention-free LLM architectures" \
|
|
21
|
+
--dataset TinyStories \
|
|
22
|
+
--goal "lowest val_bpb"
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Outputs:
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
research.nv-world.md
|
|
29
|
+
research.research.json
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
These files define the **Research World** your agents operate inside.
|
|
33
|
+
|
|
14
34
|
```bash
|
|
15
35
|
npm install @neuroverseos/governance
|
|
16
36
|
```
|
|
17
37
|
|
|
38
|
+
### Quick test (no install required)
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
npx @neuroverseos/governance init
|
|
42
|
+
npx @neuroverseos/governance build
|
|
43
|
+
npx @neuroverseos/governance guard
|
|
44
|
+
```
|
|
45
|
+
|
|
18
46
|
---
|
|
19
47
|
|
|
20
48
|
## The 5-Minute Demo
|
|
@@ -109,7 +137,7 @@ Returns ALLOW, BLOCK, or PAUSE. No network calls. No async. Pure function.
|
|
|
109
137
|
|
|
110
138
|
---
|
|
111
139
|
|
|
112
|
-
## The
|
|
140
|
+
## The Moment Governance Matters
|
|
113
141
|
|
|
114
142
|
Your AI agent decides to clean up the production database:
|
|
115
143
|
|
|
@@ -259,6 +287,47 @@ import { parsePlanMarkdown, evaluatePlan, advancePlan } from '@neuroverseos/gove
|
|
|
259
287
|
const { plan } = parsePlanMarkdown(markdown);
|
|
260
288
|
const verdict = evaluatePlan({ intent: 'write blog post' }, plan);
|
|
261
289
|
// → { status: 'ON_PLAN', matchedStep: 'write_announcement_blog_post' }
|
|
290
|
+
|
|
291
|
+
const result = advancePlan(plan, 'write_announcement_blog_post');
|
|
292
|
+
// → { success: true, plan: <updated plan> }
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
### Completion modes
|
|
296
|
+
|
|
297
|
+
Plans support two completion modes, set in frontmatter:
|
|
298
|
+
|
|
299
|
+
**Trust** (default) — caller asserts "done", step advances:
|
|
300
|
+
|
|
301
|
+
```markdown
|
|
302
|
+
---
|
|
303
|
+
plan_id: product_launch
|
|
304
|
+
completion: trust
|
|
305
|
+
---
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
**Verified** — steps with `[verify: ...]` require evidence to advance:
|
|
309
|
+
|
|
310
|
+
```markdown
|
|
311
|
+
---
|
|
312
|
+
plan_id: product_launch
|
|
313
|
+
completion: verified
|
|
314
|
+
---
|
|
315
|
+
|
|
316
|
+
# Steps
|
|
317
|
+
- Write blog post [tag: content]
|
|
318
|
+
- Publish GitHub release [verify: github_release_created]
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
Steps without `verify` still advance on trust, even in verified mode.
|
|
322
|
+
|
|
323
|
+
```bash
|
|
324
|
+
# Trust mode — just advance:
|
|
325
|
+
neuroverse plan advance write_blog_post --plan plan.json
|
|
326
|
+
|
|
327
|
+
# Verified mode — evidence required for steps with verify:
|
|
328
|
+
neuroverse plan advance publish_github_release --plan plan.json \
|
|
329
|
+
--evidence github_release_created \
|
|
330
|
+
--proof "https://github.com/org/repo/releases/v1.0"
|
|
262
331
|
```
|
|
263
332
|
|
|
264
333
|
---
|
|
@@ -413,7 +482,7 @@ src/
|
|
|
413
482
|
loader/
|
|
414
483
|
world-loader.ts # Load WorldDefinition from disk
|
|
415
484
|
|
|
416
|
-
test/ #
|
|
485
|
+
test/ # 303 tests
|
|
417
486
|
```
|
|
418
487
|
|
|
419
488
|
Zero runtime dependencies. Pure TypeScript. Node.js 18+.
|
|
@@ -432,8 +501,19 @@ Zero runtime dependencies. Pure TypeScript. Node.js 18+.
|
|
|
432
501
|
|
|
433
502
|
This package includes machine-readable manifests for agent ecosystems:
|
|
434
503
|
|
|
435
|
-
|
|
436
|
-
|
|
504
|
+
| File | Purpose | Who reads it |
|
|
505
|
+
|------|---------|-------------|
|
|
506
|
+
| **`AGENTS.md`** | Integration guide for coding agents | Claude Code, Cursor, Windsurf |
|
|
507
|
+
| **`llms.txt`** | Package description for any LLM | Any LLM browsing the web or repo |
|
|
508
|
+
| **`.well-known/ai-plugin.json`** | Capability manifest | ChatGPT plugins, OpenAI ecosystem |
|
|
509
|
+
| **`.well-known/mcp.json`** | MCP server registry manifest | MCP clients, tool registries |
|
|
510
|
+
| **`openapi.yaml`** | OpenAPI 3.1 spec for the HTTP API | AutoGPT, CrewAI, API-aware agents |
|
|
511
|
+
|
|
512
|
+
### GitHub Topics
|
|
513
|
+
|
|
514
|
+
Add these topics to the GitHub repo for search discovery:
|
|
515
|
+
|
|
516
|
+
`ai-governance` `ai-safety` `mcp-server` `agent-guardrails` `deterministic` `plan-enforcement` `model-context-protocol` `ai-agents`
|
|
437
517
|
|
|
438
518
|
## License
|
|
439
519
|
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/adapters/autoresearch.ts
|
|
21
|
+
var autoresearch_exports = {};
|
|
22
|
+
__export(autoresearch_exports, {
|
|
23
|
+
AutoresearchGovernor: () => AutoresearchGovernor
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(autoresearch_exports);
|
|
26
|
+
var AutoresearchGovernor = class {
|
|
27
|
+
config;
|
|
28
|
+
state;
|
|
29
|
+
constructor(config) {
|
|
30
|
+
this.config = config;
|
|
31
|
+
this.state = {
|
|
32
|
+
experiments_run: 0,
|
|
33
|
+
best_result: null,
|
|
34
|
+
architectures_tested: [],
|
|
35
|
+
experiment_log: [],
|
|
36
|
+
total_compute_minutes: 0,
|
|
37
|
+
keep_count: 0
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Convert an experiment proposal into a GuardEvent for governance evaluation.
|
|
42
|
+
*/
|
|
43
|
+
proposalToGuardEvent(proposal) {
|
|
44
|
+
return {
|
|
45
|
+
intent: `run experiment: ${proposal.description}`,
|
|
46
|
+
tool: "experiment_runner",
|
|
47
|
+
scope: "experiment",
|
|
48
|
+
roleId: "experiment_runner",
|
|
49
|
+
direction: "output",
|
|
50
|
+
actionCategory: "shell",
|
|
51
|
+
args: {
|
|
52
|
+
experiment_id: String(proposal.experiment_id),
|
|
53
|
+
architecture: proposal.architecture,
|
|
54
|
+
estimated_minutes: String(proposal.estimated_minutes || 5)
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Evaluate an experiment proposal against governance rules.
|
|
60
|
+
* Returns a simplified verdict without requiring the full guard engine.
|
|
61
|
+
*/
|
|
62
|
+
evaluateProposal(proposal) {
|
|
63
|
+
const warnings = [];
|
|
64
|
+
const estimatedMinutes = proposal.estimated_minutes || 5;
|
|
65
|
+
if (this.state.total_compute_minutes + estimatedMinutes > this.config.computeBudgetMinutes) {
|
|
66
|
+
return {
|
|
67
|
+
allowed: false,
|
|
68
|
+
reason: `Compute budget exhausted: ${this.state.total_compute_minutes}/${this.config.computeBudgetMinutes} minutes used`,
|
|
69
|
+
warnings
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
if (this.config.constraints) {
|
|
73
|
+
for (const constraint of this.config.constraints) {
|
|
74
|
+
const lower = constraint.toLowerCase();
|
|
75
|
+
const archLower = proposal.architecture.toLowerCase();
|
|
76
|
+
const descLower = proposal.description.toLowerCase();
|
|
77
|
+
if (lower.startsWith("no ")) {
|
|
78
|
+
const forbidden = lower.slice(3).trim();
|
|
79
|
+
if (archLower.includes(forbidden) || descLower.includes(forbidden)) {
|
|
80
|
+
return {
|
|
81
|
+
allowed: false,
|
|
82
|
+
reason: `Architecture constraint violated: ${constraint}`,
|
|
83
|
+
warnings
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
const failureCount = this.state.experiment_log.filter((e) => !e.success).length;
|
|
90
|
+
if (failureCount > 5) {
|
|
91
|
+
warnings.push(`High failure rate: ${failureCount} failed experiments. Consider investigating root cause.`);
|
|
92
|
+
}
|
|
93
|
+
const recentArchitectures = this.state.experiment_log.slice(-5).map((e) => e.architecture);
|
|
94
|
+
const uniqueRecent = new Set(recentArchitectures).size;
|
|
95
|
+
if (recentArchitectures.length >= 5 && uniqueRecent === 1) {
|
|
96
|
+
warnings.push("Research may be stuck: last 5 experiments used the same architecture.");
|
|
97
|
+
}
|
|
98
|
+
return { allowed: true, reason: "Experiment approved", warnings };
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Record an experiment result and update research state.
|
|
102
|
+
*/
|
|
103
|
+
recordResult(result) {
|
|
104
|
+
this.state.experiments_run++;
|
|
105
|
+
this.state.total_compute_minutes += result.wall_clock_minutes;
|
|
106
|
+
this.state.experiment_log.push(result);
|
|
107
|
+
if (!this.state.architectures_tested.includes(result.architecture)) {
|
|
108
|
+
this.state.architectures_tested.push(result.architecture);
|
|
109
|
+
}
|
|
110
|
+
if (!result.success) {
|
|
111
|
+
return { kept: false, improvement: null, state: { ...this.state } };
|
|
112
|
+
}
|
|
113
|
+
let kept = false;
|
|
114
|
+
let improvement = null;
|
|
115
|
+
if (this.state.best_result === null) {
|
|
116
|
+
kept = true;
|
|
117
|
+
this.state.best_result = result;
|
|
118
|
+
this.state.keep_count++;
|
|
119
|
+
} else {
|
|
120
|
+
const prev = this.state.best_result.metric_value;
|
|
121
|
+
const curr = result.metric_value;
|
|
122
|
+
if (this.config.optimize === "minimize") {
|
|
123
|
+
kept = curr < prev;
|
|
124
|
+
improvement = kept ? prev - curr : null;
|
|
125
|
+
} else {
|
|
126
|
+
kept = curr > prev;
|
|
127
|
+
improvement = kept ? curr - prev : null;
|
|
128
|
+
}
|
|
129
|
+
if (kept) {
|
|
130
|
+
this.state.best_result = result;
|
|
131
|
+
this.state.keep_count++;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return { kept, improvement, state: { ...this.state } };
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Export current state as a state snapshot compatible with the world file.
|
|
138
|
+
*/
|
|
139
|
+
toWorldState() {
|
|
140
|
+
const successfulExperiments = this.state.experiment_log.filter((e) => e.success);
|
|
141
|
+
const failedCount = this.state.experiment_log.filter((e) => !e.success).length;
|
|
142
|
+
const keepRate = this.state.experiments_run > 0 ? Math.round(this.state.keep_count / this.state.experiments_run * 100) : 0;
|
|
143
|
+
let improvementRate = 0;
|
|
144
|
+
if (successfulExperiments.length >= 2) {
|
|
145
|
+
const recent = successfulExperiments.slice(-10);
|
|
146
|
+
let improvements = 0;
|
|
147
|
+
for (let i = 1; i < recent.length; i++) {
|
|
148
|
+
const prev = recent[i - 1].metric_value;
|
|
149
|
+
const curr = recent[i].metric_value;
|
|
150
|
+
if (this.config.optimize === "minimize" ? curr < prev : curr > prev) {
|
|
151
|
+
improvements++;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
improvementRate = Math.round(improvements / (recent.length - 1) * 100);
|
|
155
|
+
}
|
|
156
|
+
return {
|
|
157
|
+
experiments_run: this.state.experiments_run,
|
|
158
|
+
best_metric_value: this.state.best_result?.metric_value ?? (this.config.optimize === "minimize" ? 100 : -1e3),
|
|
159
|
+
keep_rate: keepRate,
|
|
160
|
+
compute_used_minutes: Math.round(this.state.total_compute_minutes),
|
|
161
|
+
compute_budget_minutes: this.config.computeBudgetMinutes,
|
|
162
|
+
failed_experiments: failedCount,
|
|
163
|
+
metric_improvement_rate: improvementRate,
|
|
164
|
+
research_context_drift: 0
|
|
165
|
+
// would need NLP to compute properly
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Get a summary of the current research state.
|
|
170
|
+
*/
|
|
171
|
+
getSummary() {
|
|
172
|
+
return {
|
|
173
|
+
experiments_run: this.state.experiments_run,
|
|
174
|
+
best_result: this.state.best_result,
|
|
175
|
+
keep_rate: this.state.experiments_run > 0 ? Math.round(this.state.keep_count / this.state.experiments_run * 100) : 0,
|
|
176
|
+
compute_remaining_minutes: this.config.computeBudgetMinutes - this.state.total_compute_minutes,
|
|
177
|
+
architectures_tested: [...this.state.architectures_tested]
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Load state from a persisted research context file.
|
|
182
|
+
*/
|
|
183
|
+
loadState(state) {
|
|
184
|
+
this.state = { ...state };
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Export state for persistence.
|
|
188
|
+
*/
|
|
189
|
+
exportState() {
|
|
190
|
+
return { ...this.state };
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
194
|
+
0 && (module.exports = {
|
|
195
|
+
AutoresearchGovernor
|
|
196
|
+
});
|