@neuroverseos/governance 0.10.0 → 0.11.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/dist/adapters/autoresearch.cjs +19 -1
- package/dist/adapters/autoresearch.d.cts +1 -1
- package/dist/adapters/autoresearch.d.ts +1 -1
- package/dist/adapters/autoresearch.js +2 -2
- package/dist/adapters/deep-agents.cjs +19 -1
- package/dist/adapters/deep-agents.d.cts +2 -2
- package/dist/adapters/deep-agents.d.ts +2 -2
- package/dist/adapters/deep-agents.js +2 -2
- package/dist/adapters/express.cjs +19 -1
- package/dist/adapters/express.d.cts +1 -1
- package/dist/adapters/express.d.ts +1 -1
- package/dist/adapters/express.js +2 -2
- package/dist/adapters/github.cjs +19 -1
- package/dist/adapters/github.d.cts +2 -2
- package/dist/adapters/github.d.ts +2 -2
- package/dist/adapters/github.js +2 -2
- package/dist/adapters/index.cjs +19 -1
- package/dist/adapters/index.d.cts +2 -2
- package/dist/adapters/index.d.ts +2 -2
- package/dist/adapters/index.js +8 -8
- package/dist/adapters/langchain.cjs +19 -1
- package/dist/adapters/langchain.d.cts +2 -2
- package/dist/adapters/langchain.d.ts +2 -2
- package/dist/adapters/langchain.js +2 -2
- package/dist/adapters/mentraos.cjs +19 -1
- package/dist/adapters/mentraos.d.cts +2 -2
- package/dist/adapters/mentraos.d.ts +2 -2
- package/dist/adapters/mentraos.js +2 -2
- package/dist/adapters/openai.cjs +19 -1
- package/dist/adapters/openai.d.cts +2 -2
- package/dist/adapters/openai.d.ts +2 -2
- package/dist/adapters/openai.js +2 -2
- package/dist/adapters/openclaw.cjs +19 -1
- package/dist/adapters/openclaw.d.cts +2 -2
- package/dist/adapters/openclaw.d.ts +2 -2
- package/dist/adapters/openclaw.js +2 -2
- package/dist/admin/index.cjs +19 -1
- package/dist/admin/index.js +1 -1
- package/dist/audit-CRJOB4CP.js +93 -0
- package/dist/audit-behavior-C62FdRAC.d.cts +100 -0
- package/dist/audit-behavior-DFy7LeYv.d.ts +100 -0
- package/dist/{behavioral-SPWPGYXL.js → behavioral-4TKMHZQZ.js} +2 -2
- package/dist/{chunk-OQU65525.js → chunk-24YW7BHC.js} +1 -1
- package/dist/{chunk-BZYQHJDM.js → chunk-2KTPIE57.js} +25 -5
- package/dist/{chunk-TJ5L2UTE.js → chunk-5K3LATTM.js} +1 -1
- package/dist/{chunk-HDNDL6D5.js → chunk-5LDBYOSJ.js} +1 -1
- package/dist/{chunk-FDPPZLSQ.js → chunk-5ZWKM7MO.js} +1 -1
- package/dist/{chunk-B3IIPTY3.js → chunk-6MB6TMAG.js} +1 -1
- package/dist/{chunk-IOVXB6QN.js → chunk-GXTAHCND.js} +1 -1
- package/dist/{chunk-FKQCPRKI.js → chunk-MAOIHKFO.js} +1 -1
- package/dist/{chunk-ZAF6JH23.js → chunk-MBOW6YXN.js} +19 -1
- package/dist/{chunk-A2UZTLRV.js → chunk-MLXKSX3L.js} +1 -1
- package/dist/{chunk-7FL3U7Z5.js → chunk-MWGEXHOD.js} +1 -1
- package/dist/{chunk-6CV4XG3J.js → chunk-QFDFAWZ6.js} +1 -1
- package/dist/{chunk-2VAWP6FI.js → chunk-RAS62JXV.js} +1 -1
- package/dist/{chunk-OTZU76DH.js → chunk-XAF3CYCW.js} +1 -1
- package/dist/{chunk-T6GMRZWC.js → chunk-XTYQCTDD.js} +1 -1
- package/dist/{chunk-TIXVEPS2.js → chunk-YN7OI5ZV.js} +1 -1
- package/dist/cli/neuroverse.cjs +224 -93
- package/dist/cli/neuroverse.js +16 -12
- package/dist/cli/plan.cjs +18 -0
- package/dist/cli/radiant.cjs +42 -4
- package/dist/cli/radiant.js +3 -3
- package/dist/cli/run.cjs +18 -0
- package/dist/cli/run.js +4 -4
- package/dist/{decision-flow-IJPNMVQK.js → decision-flow-5VI5YG6A.js} +2 -2
- package/dist/{demo-6W3YXLAX.js → demo-GYX6CYHC.js} +2 -2
- package/dist/engine/guard-engine.cjs +19 -1
- package/dist/engine/guard-engine.d.cts +21 -1
- package/dist/engine/guard-engine.d.ts +21 -1
- package/dist/engine/guard-engine.js +1 -1
- package/dist/{equity-penalties-CCO3GVHS.js → equity-penalties-NOM46NEO.js} +2 -2
- package/dist/{guard-IHJEKHL2.js → guard-PQ3SYV4Y.js} +3 -3
- package/dist/{guard-contract-ddiIPlOg.d.cts → guard-contract-Oznf-Kgq.d.cts} +32 -0
- package/dist/{guard-contract-q6HJAq3Q.d.ts → guard-contract-w_i_6gh-.d.ts} +32 -0
- package/dist/{impact-WIAM66IH.js → impact-LDJLTVRU.js} +3 -3
- package/dist/index.cjs +62 -1
- package/dist/index.d.cts +4 -3
- package/dist/index.d.ts +4 -3
- package/dist/index.js +49 -8
- package/dist/{mcp-server-CKYBHXWK.js → mcp-server-W3MWSKD7.js} +2 -2
- package/dist/{playground-3TTBN7XD.js → playground-SSZRNUAF.js} +1 -1
- package/dist/radiant/index.cjs +43 -5
- package/dist/radiant/index.d.cts +20 -0
- package/dist/radiant/index.d.ts +20 -0
- package/dist/radiant/index.js +2 -2
- package/dist/{redteam-W644UMWN.js → redteam-KCULS7EW.js} +1 -1
- package/dist/{server-EI5JCIBU.js → server-EGRGGSM2.js} +2 -2
- package/dist/{session-FMAROEIE.js → session-PZLTL22G.js} +2 -2
- package/dist/{shared-PpalGKxc.d.cts → shared-BC8mOpt0.d.cts} +1 -1
- package/dist/{shared-DAzdfWtU.d.ts → shared-CP63gNNW.d.ts} +1 -1
- package/dist/{test-XDB2DH3L.js → test-LIHGWHBA.js} +1 -1
- package/dist/{trace-2YDNAXMK.js → trace-DC3D7XPD.js} +2 -2
- package/package.json +1 -1
- /package/dist/{doctor-XEMLO6UA.js → doctor-SIWQGTAO.js} +0 -0
package/dist/admin/index.cjs
CHANGED
|
@@ -322,8 +322,26 @@ function isExternalScope(scope) {
|
|
|
322
322
|
];
|
|
323
323
|
return !internalPatterns.some((p) => p.test(scope));
|
|
324
324
|
}
|
|
325
|
-
var MAX_INPUT_LENGTH = 1e5;
|
|
326
325
|
function evaluateGuard(event, world, options = {}) {
|
|
326
|
+
const verdict = evaluateGuardCore(event, world, options);
|
|
327
|
+
return options.mode === "observe" ? toShadowVerdict(verdict) : verdict;
|
|
328
|
+
}
|
|
329
|
+
function toShadowVerdict(verdict) {
|
|
330
|
+
if (verdict.status === "ALLOW") return verdict;
|
|
331
|
+
return {
|
|
332
|
+
...verdict,
|
|
333
|
+
status: "ALLOW",
|
|
334
|
+
shadowStatus: verdict.status,
|
|
335
|
+
shadowReason: verdict.reason,
|
|
336
|
+
// Preserve the original reason as shadowReason and wipe the
|
|
337
|
+
// top-level reason so callers that display `reason` for BLOCK/PAUSE
|
|
338
|
+
// don't accidentally surface an enforcement message.
|
|
339
|
+
reason: void 0,
|
|
340
|
+
warning: verdict.reason ? `Observe mode: would have ${verdict.status.toLowerCase()} \u2014 ${verdict.reason}` : `Observe mode: would have ${verdict.status.toLowerCase()}`
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
var MAX_INPUT_LENGTH = 1e5;
|
|
344
|
+
function evaluateGuardCore(event, world, options = {}) {
|
|
327
345
|
const startTime = performance.now();
|
|
328
346
|
const level = options.level ?? "standard";
|
|
329
347
|
const includeTrace = options.trace ?? false;
|
package/dist/admin/index.js
CHANGED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import {
|
|
2
|
+
readStdin
|
|
3
|
+
} from "./chunk-BQZMOEML.js";
|
|
4
|
+
import {
|
|
5
|
+
resolveWorldPath
|
|
6
|
+
} from "./chunk-AKW5YVCE.js";
|
|
7
|
+
import {
|
|
8
|
+
loadWorld
|
|
9
|
+
} from "./chunk-I4RTIMLX.js";
|
|
10
|
+
import {
|
|
11
|
+
evaluateGuard
|
|
12
|
+
} from "./chunk-MBOW6YXN.js";
|
|
13
|
+
import "./chunk-QLPTHTVB.js";
|
|
14
|
+
import "./chunk-QWGCMQQD.js";
|
|
15
|
+
|
|
16
|
+
// src/cli/audit.ts
|
|
17
|
+
function parseArgs(argv) {
|
|
18
|
+
let worldPath = "";
|
|
19
|
+
let trace = false;
|
|
20
|
+
let level;
|
|
21
|
+
let multi = false;
|
|
22
|
+
let crossingsOnly = false;
|
|
23
|
+
for (let i = 0; i < argv.length; i++) {
|
|
24
|
+
const a = argv[i];
|
|
25
|
+
if (a === "--world") worldPath = argv[++i] ?? "";
|
|
26
|
+
else if (a === "--trace") trace = true;
|
|
27
|
+
else if (a === "--level") {
|
|
28
|
+
const v = argv[++i];
|
|
29
|
+
if (v === "basic" || v === "standard" || v === "strict") level = v;
|
|
30
|
+
} else if (a === "--multi") multi = true;
|
|
31
|
+
else if (a === "--crossings-only") crossingsOnly = true;
|
|
32
|
+
}
|
|
33
|
+
return { worldPath, trace, level, multi, crossingsOnly };
|
|
34
|
+
}
|
|
35
|
+
function usage() {
|
|
36
|
+
process.stderr.write(
|
|
37
|
+
"Usage: neuroverse audit --world <path> [--trace] [--level basic|standard|strict] [--multi] [--crossings-only]\n\nReads GuardEvent JSON from stdin. With --multi, reads a JSON array.\nEvaluates in observe mode \u2014 no enforcement. Verdicts carry\nshadowStatus/shadowReason for any event that would have crossed.\n"
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
async function main(argv = process.argv.slice(2)) {
|
|
41
|
+
const args = parseArgs(argv);
|
|
42
|
+
if (!args.worldPath) {
|
|
43
|
+
usage();
|
|
44
|
+
process.exit(1);
|
|
45
|
+
}
|
|
46
|
+
let world;
|
|
47
|
+
try {
|
|
48
|
+
const resolved = resolveWorldPath(args.worldPath);
|
|
49
|
+
world = await loadWorld(resolved);
|
|
50
|
+
} catch (err) {
|
|
51
|
+
process.stderr.write(`Failed to load world: ${err instanceof Error ? err.message : err}
|
|
52
|
+
`);
|
|
53
|
+
process.exit(1);
|
|
54
|
+
}
|
|
55
|
+
let raw = "";
|
|
56
|
+
try {
|
|
57
|
+
raw = await readStdin();
|
|
58
|
+
} catch (err) {
|
|
59
|
+
process.stderr.write(`Failed to read stdin: ${err instanceof Error ? err.message : err}
|
|
60
|
+
`);
|
|
61
|
+
process.exit(1);
|
|
62
|
+
}
|
|
63
|
+
if (!raw.trim()) {
|
|
64
|
+
process.stderr.write("No input on stdin. Pipe a GuardEvent or a JSON array with --multi.\n");
|
|
65
|
+
process.exit(1);
|
|
66
|
+
}
|
|
67
|
+
let parsed;
|
|
68
|
+
try {
|
|
69
|
+
parsed = JSON.parse(raw);
|
|
70
|
+
} catch (err) {
|
|
71
|
+
process.stderr.write(`Invalid JSON on stdin: ${err instanceof Error ? err.message : err}
|
|
72
|
+
`);
|
|
73
|
+
process.exit(1);
|
|
74
|
+
}
|
|
75
|
+
const options = { trace: args.trace, level: args.level, mode: "observe" };
|
|
76
|
+
if (args.multi) {
|
|
77
|
+
if (!Array.isArray(parsed)) {
|
|
78
|
+
process.stderr.write("--multi expects a JSON array on stdin.\n");
|
|
79
|
+
process.exit(1);
|
|
80
|
+
}
|
|
81
|
+
const verdicts = parsed.map(
|
|
82
|
+
(e) => evaluateGuard(e, world, options)
|
|
83
|
+
);
|
|
84
|
+
const out = args.crossingsOnly ? verdicts.filter((v) => v.shadowStatus && v.shadowStatus !== "ALLOW") : verdicts;
|
|
85
|
+
process.stdout.write(JSON.stringify(out, null, 2) + "\n");
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
const verdict = evaluateGuard(parsed, world, options);
|
|
89
|
+
process.stdout.write(JSON.stringify(verdict, null, 2) + "\n");
|
|
90
|
+
}
|
|
91
|
+
export {
|
|
92
|
+
main
|
|
93
|
+
};
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { d as GuardStatus, G as GuardVerdict } from './guard-contract-Oznf-Kgq.cjs';
|
|
2
|
+
import { WorldDefinition } from './types.cjs';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @neuroverseos/governance — auditBehavior
|
|
6
|
+
*
|
|
7
|
+
* Takes an observed event (from the Radiant pipeline: a commit, a PR, a
|
|
8
|
+
* Slack message, a Notion edit) and evaluates it against a worldmodel in
|
|
9
|
+
* observe mode — without any enforcement side effects. Returns the shadow
|
|
10
|
+
* verdict so callers can record crossings of declared invariants.
|
|
11
|
+
*
|
|
12
|
+
* This is the primitive that lets Bevia / Radiant / Mirror-Mode tooling
|
|
13
|
+
* show leaders where their worldmodel is being bumped against, without
|
|
14
|
+
* imposing any stop/pause/modify semantics on the team's work.
|
|
15
|
+
*
|
|
16
|
+
* Relationship to evaluateGuard:
|
|
17
|
+
*
|
|
18
|
+
* evaluateGuard({ intent, ... }, world, { mode: 'enforce' })
|
|
19
|
+
* → what an AI agent receives when governance says "BLOCK this action"
|
|
20
|
+
*
|
|
21
|
+
* evaluateGuard({ intent, ... }, world, { mode: 'observe' })
|
|
22
|
+
* → what tooling like Bevia receives when governance says "this would
|
|
23
|
+
* have been blocked if enforced, but pass through and record"
|
|
24
|
+
*
|
|
25
|
+
* auditBehavior(event, world)
|
|
26
|
+
* → convenience on top of the observe path that (a) maps a
|
|
27
|
+
* behavioral event into a synthetic GuardEvent, (b) calls
|
|
28
|
+
* evaluateGuard in observe mode, and (c) returns a Crossing
|
|
29
|
+
* record shaped for behavioral logs.
|
|
30
|
+
*
|
|
31
|
+
* The mapping from behavioral events to GuardEvents is intentionally
|
|
32
|
+
* conservative: we use the event's `kind` as the tool, its `content` as
|
|
33
|
+
* the intent, and pass through timestamp + actor as metadata. Callers
|
|
34
|
+
* that want richer mappings (classifying event semantics into tool
|
|
35
|
+
* namespaces, etc.) can construct a GuardEvent directly and call
|
|
36
|
+
* evaluateGuard themselves.
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Minimal shape an observed event needs to be auditable. Matches the
|
|
41
|
+
* Radiant `Event` type's relevant fields but doesn't require importing
|
|
42
|
+
* the full radiant domain module — keeps auditBehavior consumable by any
|
|
43
|
+
* adapter that emits events.
|
|
44
|
+
*/
|
|
45
|
+
interface AuditableEvent {
|
|
46
|
+
/** Source-system-unique id (e.g. "github-push-abc123", "slack-msg-789"). */
|
|
47
|
+
id: string;
|
|
48
|
+
/** ISO 8601. */
|
|
49
|
+
timestamp: string;
|
|
50
|
+
/** Free-form kind tag from the adapter — 'commit', 'pr_opened', 'chat_message', etc. */
|
|
51
|
+
kind?: string;
|
|
52
|
+
/** Textual content of the event — commit message, PR body, chat text, etc. */
|
|
53
|
+
content?: string;
|
|
54
|
+
/** Actor id that produced the event. */
|
|
55
|
+
actorId?: string;
|
|
56
|
+
/** Actor kind — 'human' | 'ai' | 'bot' | 'unknown'. */
|
|
57
|
+
actorKind?: string;
|
|
58
|
+
/** Optional repo / channel / page reference, passed through as GuardEvent.scope. */
|
|
59
|
+
scope?: string;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* A single crossing record — an observed event that would have triggered
|
|
63
|
+
* a non-ALLOW verdict if the world were running in enforce mode.
|
|
64
|
+
*
|
|
65
|
+
* When `wouldHaveBlocked` is `false`, the event passed all layers cleanly
|
|
66
|
+
* and no crossing occurred. Crossing records are most useful when
|
|
67
|
+
* `wouldHaveBlocked` is `true` — that's a moment the leader said they
|
|
68
|
+
* cared about, and here's evidence their team bumped into it.
|
|
69
|
+
*/
|
|
70
|
+
interface Crossing {
|
|
71
|
+
eventId: string;
|
|
72
|
+
timestamp: string;
|
|
73
|
+
kind?: string;
|
|
74
|
+
actorId?: string;
|
|
75
|
+
/** The status the engine would have returned in enforce mode. */
|
|
76
|
+
shadowStatus: GuardStatus;
|
|
77
|
+
/** Human-readable reason the shadow verdict fired. */
|
|
78
|
+
shadowReason?: string;
|
|
79
|
+
/** Rule or guard id that produced the shadow verdict. */
|
|
80
|
+
ruleId?: string;
|
|
81
|
+
/** Shortened quote of the event content — useful for a crossings panel. */
|
|
82
|
+
excerpt?: string;
|
|
83
|
+
/** True when the engine would have blocked/paused/etc. in enforce mode. */
|
|
84
|
+
wouldHaveBlocked: boolean;
|
|
85
|
+
/** Full verdict in case callers want the complete object. */
|
|
86
|
+
verdict: GuardVerdict;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Evaluate a single behavioral event against a world in observe mode.
|
|
90
|
+
*/
|
|
91
|
+
declare function auditBehavior(event: AuditableEvent, world: WorldDefinition): Crossing;
|
|
92
|
+
/**
|
|
93
|
+
* Convenience: audit a whole stream of events. Returns one Crossing per
|
|
94
|
+
* event; the caller can filter `wouldHaveBlocked` to get only the
|
|
95
|
+
* interesting ones. Deterministic — same events + same world = same
|
|
96
|
+
* crossings, every time.
|
|
97
|
+
*/
|
|
98
|
+
declare function auditBehaviors(events: AuditableEvent[], world: WorldDefinition): Crossing[];
|
|
99
|
+
|
|
100
|
+
export { type AuditableEvent as A, type Crossing as C, auditBehavior as a, auditBehaviors as b };
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { d as GuardStatus, G as GuardVerdict } from './guard-contract-w_i_6gh-.js';
|
|
2
|
+
import { WorldDefinition } from './types.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @neuroverseos/governance — auditBehavior
|
|
6
|
+
*
|
|
7
|
+
* Takes an observed event (from the Radiant pipeline: a commit, a PR, a
|
|
8
|
+
* Slack message, a Notion edit) and evaluates it against a worldmodel in
|
|
9
|
+
* observe mode — without any enforcement side effects. Returns the shadow
|
|
10
|
+
* verdict so callers can record crossings of declared invariants.
|
|
11
|
+
*
|
|
12
|
+
* This is the primitive that lets Bevia / Radiant / Mirror-Mode tooling
|
|
13
|
+
* show leaders where their worldmodel is being bumped against, without
|
|
14
|
+
* imposing any stop/pause/modify semantics on the team's work.
|
|
15
|
+
*
|
|
16
|
+
* Relationship to evaluateGuard:
|
|
17
|
+
*
|
|
18
|
+
* evaluateGuard({ intent, ... }, world, { mode: 'enforce' })
|
|
19
|
+
* → what an AI agent receives when governance says "BLOCK this action"
|
|
20
|
+
*
|
|
21
|
+
* evaluateGuard({ intent, ... }, world, { mode: 'observe' })
|
|
22
|
+
* → what tooling like Bevia receives when governance says "this would
|
|
23
|
+
* have been blocked if enforced, but pass through and record"
|
|
24
|
+
*
|
|
25
|
+
* auditBehavior(event, world)
|
|
26
|
+
* → convenience on top of the observe path that (a) maps a
|
|
27
|
+
* behavioral event into a synthetic GuardEvent, (b) calls
|
|
28
|
+
* evaluateGuard in observe mode, and (c) returns a Crossing
|
|
29
|
+
* record shaped for behavioral logs.
|
|
30
|
+
*
|
|
31
|
+
* The mapping from behavioral events to GuardEvents is intentionally
|
|
32
|
+
* conservative: we use the event's `kind` as the tool, its `content` as
|
|
33
|
+
* the intent, and pass through timestamp + actor as metadata. Callers
|
|
34
|
+
* that want richer mappings (classifying event semantics into tool
|
|
35
|
+
* namespaces, etc.) can construct a GuardEvent directly and call
|
|
36
|
+
* evaluateGuard themselves.
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Minimal shape an observed event needs to be auditable. Matches the
|
|
41
|
+
* Radiant `Event` type's relevant fields but doesn't require importing
|
|
42
|
+
* the full radiant domain module — keeps auditBehavior consumable by any
|
|
43
|
+
* adapter that emits events.
|
|
44
|
+
*/
|
|
45
|
+
interface AuditableEvent {
|
|
46
|
+
/** Source-system-unique id (e.g. "github-push-abc123", "slack-msg-789"). */
|
|
47
|
+
id: string;
|
|
48
|
+
/** ISO 8601. */
|
|
49
|
+
timestamp: string;
|
|
50
|
+
/** Free-form kind tag from the adapter — 'commit', 'pr_opened', 'chat_message', etc. */
|
|
51
|
+
kind?: string;
|
|
52
|
+
/** Textual content of the event — commit message, PR body, chat text, etc. */
|
|
53
|
+
content?: string;
|
|
54
|
+
/** Actor id that produced the event. */
|
|
55
|
+
actorId?: string;
|
|
56
|
+
/** Actor kind — 'human' | 'ai' | 'bot' | 'unknown'. */
|
|
57
|
+
actorKind?: string;
|
|
58
|
+
/** Optional repo / channel / page reference, passed through as GuardEvent.scope. */
|
|
59
|
+
scope?: string;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* A single crossing record — an observed event that would have triggered
|
|
63
|
+
* a non-ALLOW verdict if the world were running in enforce mode.
|
|
64
|
+
*
|
|
65
|
+
* When `wouldHaveBlocked` is `false`, the event passed all layers cleanly
|
|
66
|
+
* and no crossing occurred. Crossing records are most useful when
|
|
67
|
+
* `wouldHaveBlocked` is `true` — that's a moment the leader said they
|
|
68
|
+
* cared about, and here's evidence their team bumped into it.
|
|
69
|
+
*/
|
|
70
|
+
interface Crossing {
|
|
71
|
+
eventId: string;
|
|
72
|
+
timestamp: string;
|
|
73
|
+
kind?: string;
|
|
74
|
+
actorId?: string;
|
|
75
|
+
/** The status the engine would have returned in enforce mode. */
|
|
76
|
+
shadowStatus: GuardStatus;
|
|
77
|
+
/** Human-readable reason the shadow verdict fired. */
|
|
78
|
+
shadowReason?: string;
|
|
79
|
+
/** Rule or guard id that produced the shadow verdict. */
|
|
80
|
+
ruleId?: string;
|
|
81
|
+
/** Shortened quote of the event content — useful for a crossings panel. */
|
|
82
|
+
excerpt?: string;
|
|
83
|
+
/** True when the engine would have blocked/paused/etc. in enforce mode. */
|
|
84
|
+
wouldHaveBlocked: boolean;
|
|
85
|
+
/** Full verdict in case callers want the complete object. */
|
|
86
|
+
verdict: GuardVerdict;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Evaluate a single behavioral event against a world in observe mode.
|
|
90
|
+
*/
|
|
91
|
+
declare function auditBehavior(event: AuditableEvent, world: WorldDefinition): Crossing;
|
|
92
|
+
/**
|
|
93
|
+
* Convenience: audit a whole stream of events. Returns one Crossing per
|
|
94
|
+
* event; the caller can filter `wouldHaveBlocked` to get only the
|
|
95
|
+
* interesting ones. Deterministic — same events + same world = same
|
|
96
|
+
* crossings, every time.
|
|
97
|
+
*/
|
|
98
|
+
declare function auditBehaviors(events: AuditableEvent[], world: WorldDefinition): Crossing[];
|
|
99
|
+
|
|
100
|
+
export { type AuditableEvent as A, type Crossing as C, auditBehavior as a, auditBehaviors as b };
|
|
@@ -5,8 +5,8 @@ import {
|
|
|
5
5
|
} from "./chunk-CNSO6XW5.js";
|
|
6
6
|
import {
|
|
7
7
|
readAuditLog
|
|
8
|
-
} from "./chunk-
|
|
9
|
-
import "./chunk-
|
|
8
|
+
} from "./chunk-RAS62JXV.js";
|
|
9
|
+
import "./chunk-MBOW6YXN.js";
|
|
10
10
|
import "./chunk-QLPTHTVB.js";
|
|
11
11
|
import "./chunk-QWGCMQQD.js";
|
|
12
12
|
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
} from "./chunk-I4RTIMLX.js";
|
|
7
7
|
import {
|
|
8
8
|
evaluateGuard
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-MBOW6YXN.js";
|
|
10
10
|
|
|
11
11
|
// src/radiant/core/compress.ts
|
|
12
12
|
function compressWorldmodel(content) {
|
|
@@ -1830,6 +1830,7 @@ async function auditGovernance(events, worldPath) {
|
|
|
1830
1830
|
return emptyAudit(events.length, "Could not load compiled worldmodel for governance audit.");
|
|
1831
1831
|
}
|
|
1832
1832
|
const verdicts = [];
|
|
1833
|
+
const crossings = [];
|
|
1833
1834
|
for (const ce of events) {
|
|
1834
1835
|
const intent = ce.event.content?.slice(0, 500) || ce.event.kind || "activity";
|
|
1835
1836
|
const scope = ce.event.metadata?.scope || void 0;
|
|
@@ -1840,16 +1841,32 @@ async function auditGovernance(events, worldPath) {
|
|
|
1840
1841
|
scope,
|
|
1841
1842
|
actionCategory: mapKindToCategory(ce.event.kind)
|
|
1842
1843
|
},
|
|
1843
|
-
world
|
|
1844
|
+
world,
|
|
1845
|
+
{ mode: "observe" }
|
|
1844
1846
|
);
|
|
1847
|
+
const shadow = result.shadowStatus ?? "ALLOW";
|
|
1845
1848
|
verdicts.push({
|
|
1846
1849
|
eventId: ce.event.id,
|
|
1847
1850
|
domain: ce.domain,
|
|
1848
|
-
status:
|
|
1849
|
-
reason: result.
|
|
1851
|
+
status: shadow,
|
|
1852
|
+
reason: result.shadowReason,
|
|
1850
1853
|
ruleId: result.ruleId,
|
|
1851
1854
|
warning: result.warning
|
|
1852
1855
|
});
|
|
1856
|
+
if (shadow !== "ALLOW") {
|
|
1857
|
+
crossings.push({
|
|
1858
|
+
eventId: ce.event.id,
|
|
1859
|
+
timestamp: ce.event.timestamp,
|
|
1860
|
+
kind: ce.event.kind,
|
|
1861
|
+
actorId: ce.event.actor.id,
|
|
1862
|
+
shadowStatus: shadow,
|
|
1863
|
+
shadowReason: result.shadowReason,
|
|
1864
|
+
ruleId: result.ruleId,
|
|
1865
|
+
excerpt: intent.length > 280 ? intent.slice(0, 279) + "\u2026" : intent,
|
|
1866
|
+
wouldHaveBlocked: true,
|
|
1867
|
+
verdict: result
|
|
1868
|
+
});
|
|
1869
|
+
}
|
|
1853
1870
|
} catch {
|
|
1854
1871
|
verdicts.push({
|
|
1855
1872
|
eventId: ce.event.id,
|
|
@@ -1868,6 +1885,7 @@ async function auditGovernance(events, worldPath) {
|
|
|
1868
1885
|
human,
|
|
1869
1886
|
cyber,
|
|
1870
1887
|
joint,
|
|
1888
|
+
crossings,
|
|
1871
1889
|
summary
|
|
1872
1890
|
};
|
|
1873
1891
|
}
|
|
@@ -1923,6 +1941,7 @@ function emptyAudit(total, reason) {
|
|
|
1923
1941
|
human: { allow: 0, modify: 0, block: 0, details: [] },
|
|
1924
1942
|
cyber: { allow: 0, modify: 0, block: 0, details: [] },
|
|
1925
1943
|
joint: { allow: 0, modify: 0, block: 0, details: [] },
|
|
1944
|
+
crossings: [],
|
|
1926
1945
|
summary: reason
|
|
1927
1946
|
};
|
|
1928
1947
|
}
|
|
@@ -2899,7 +2918,8 @@ Compare stated intent against actual GitHub activity. Gaps = drift.`;
|
|
|
2899
2918
|
scores,
|
|
2900
2919
|
eventCount: events.length,
|
|
2901
2920
|
activeAdapters,
|
|
2902
|
-
worldStack
|
|
2921
|
+
worldStack,
|
|
2922
|
+
governance
|
|
2903
2923
|
};
|
|
2904
2924
|
}
|
|
2905
2925
|
function filterEventsByUser(events, username) {
|
|
@@ -89,8 +89,26 @@ function isExternalScope(scope) {
|
|
|
89
89
|
];
|
|
90
90
|
return !internalPatterns.some((p) => p.test(scope));
|
|
91
91
|
}
|
|
92
|
-
var MAX_INPUT_LENGTH = 1e5;
|
|
93
92
|
function evaluateGuard(event, world, options = {}) {
|
|
93
|
+
const verdict = evaluateGuardCore(event, world, options);
|
|
94
|
+
return options.mode === "observe" ? toShadowVerdict(verdict) : verdict;
|
|
95
|
+
}
|
|
96
|
+
function toShadowVerdict(verdict) {
|
|
97
|
+
if (verdict.status === "ALLOW") return verdict;
|
|
98
|
+
return {
|
|
99
|
+
...verdict,
|
|
100
|
+
status: "ALLOW",
|
|
101
|
+
shadowStatus: verdict.status,
|
|
102
|
+
shadowReason: verdict.reason,
|
|
103
|
+
// Preserve the original reason as shadowReason and wipe the
|
|
104
|
+
// top-level reason so callers that display `reason` for BLOCK/PAUSE
|
|
105
|
+
// don't accidentally surface an enforcement message.
|
|
106
|
+
reason: void 0,
|
|
107
|
+
warning: verdict.reason ? `Observe mode: would have ${verdict.status.toLowerCase()} \u2014 ${verdict.reason}` : `Observe mode: would have ${verdict.status.toLowerCase()}`
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
var MAX_INPUT_LENGTH = 1e5;
|
|
111
|
+
function evaluateGuardCore(event, world, options = {}) {
|
|
94
112
|
const startTime = performance.now();
|
|
95
113
|
const level = options.level ?? "standard";
|
|
96
114
|
const includeTrace = options.trace ?? false;
|