@neuroverseos/governance 0.6.1 → 0.8.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/README.md +43 -7
- package/dist/{chunk-AEVT7DSZ.js → chunk-MC6O5GV5.js} +486 -12
- package/dist/cli/neuroverse.cjs +868 -142
- package/dist/cli/radiant.cjs +2173 -149
- package/dist/cli/radiant.js +29 -4
- package/dist/radiant/index.cjs +2083 -13
- package/dist/radiant/index.d.cts +392 -21
- package/dist/radiant/index.d.ts +392 -21
- package/dist/radiant/index.js +426 -3
- package/dist/server-DFNY5N5A.js +271 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -3,12 +3,51 @@
|
|
|
3
3
|
[](https://www.npmjs.com/package/@neuroverseos/governance)
|
|
4
4
|
[](LICENSE.md)
|
|
5
5
|
|
|
6
|
-
**
|
|
6
|
+
**Behavioral governance for AI systems.** Give meaning to behavior — meaning relative to the behavioral models that have been declared and governed.
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Human intelligence and artificial intelligence are two different kinds of intelligence working together. All organizations, all systems, gather people around declared shared intent. NeuroverseOS tools help define those intentions into behaviors — and those behaviors become a constitution carried out at runtime.
|
|
9
9
|
|
|
10
|
-
**
|
|
11
|
-
|
|
10
|
+
NeuroverseOS is the universe where human and AI meet to work together, defined by the behaviors the organization has agreed upon. **Radiant** is the behavioral intelligence layer built on top: it reads what happened, compares it against what was declared, and tells you where the work aligns and where it drifts.
|
|
11
|
+
|
|
12
|
+
Together they put you in a cocoon of behavior — not a cage, a cocoon. Something that holds your shape while you're becoming what you said you'd become.
|
|
13
|
+
|
|
14
|
+
## Two products, one package
|
|
15
|
+
|
|
16
|
+
| Layer | What it does | Who uses it |
|
|
17
|
+
|---|---|---|
|
|
18
|
+
| **NeuroverseOS** | Governance engine — worldmodel compiler, guard engine, lens system, plan enforcement | Developers building governed AI apps |
|
|
19
|
+
| **Radiant** | Behavioral intelligence — reads activity, gives it meaning through the worldmodel, measures human-AI alignment | Teams and organizations (starting with Auki/ExoCortex) |
|
|
20
|
+
|
|
21
|
+
Both ship in `@neuroverseos/governance`. Install once, use either or both.
|
|
22
|
+
|
|
23
|
+
## Radiant — behavioral intelligence for collaboration
|
|
24
|
+
|
|
25
|
+
Radiant gives meaning to behavior. It reads activity (GitHub commits, PRs, reviews), classifies each event by who did it (human, AI, or both together), extracts behavioral signals, identifies patterns through AI interpretation governed by the worldmodel, and produces a structured read:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npx @neuroverseos/governance radiant emergent aukiverse/posemesh \
|
|
29
|
+
--lens auki-builder --worlds ./worlds/
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Output:
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
EMERGENT — what patterns are visible in the team's work
|
|
36
|
+
MEANING — what it means against the worldmodel
|
|
37
|
+
MOVE — what to do about it (or "nothing's broken, keep shipping")
|
|
38
|
+
ALIGNMENT — L/C/N/R scores (human, AI, collaboration, composite)
|
|
39
|
+
GOVERNANCE — audit trail: which events triggered governance, on which side
|
|
40
|
+
DEPTH — what Radiant can see now vs what unlocks with more reads
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Three scores nobody else measures:
|
|
44
|
+
- **L** — is the human's work aligned with the declared model?
|
|
45
|
+
- **C** — is the AI's output aligned with the declared model?
|
|
46
|
+
- **N** — when human and AI work together, is shared meaning preserved through the worldmodel? This score only exists because the worldmodel exists.
|
|
47
|
+
|
|
48
|
+
For the full Radiant documentation, see [`src/radiant/examples/auki/README.md`](src/radiant/examples/auki/README.md).
|
|
49
|
+
|
|
50
|
+
## Governance engine — deterministic rules for AI
|
|
12
51
|
|
|
13
52
|
```
|
|
14
53
|
What AI can do → Rules (permissions)
|
|
@@ -55,7 +94,6 @@ NeuroVerse gives you composable primitives:
|
|
|
55
94
|
|
|
56
95
|
These blocks let you build robots/agents that can traverse heterogeneous spaces while remaining policy-compliant, auditable, and deterministic.
|
|
57
96
|
|
|
58
|
-
<<<<<<< codex/review-open-source-repo-for-ai-architecture
|
|
59
97
|
### Mental Model: Layered Rules (World → Law → Situation)
|
|
60
98
|
|
|
61
99
|
If you're explaining this to developers or non-technical stakeholders, use this:
|
|
@@ -202,8 +240,6 @@ Use this section to show real runtime behavior and response time.
|
|
|
202
240
|
4. **Level 4 — Spatial + Multi-Actor Governance**
|
|
203
241
|
Add zone opt-in, handshake negotiation, and dynamic policy composition.
|
|
204
242
|
|
|
205
|
-
=======
|
|
206
|
-
>>>>>>> main
|
|
207
243
|
---
|
|
208
244
|
|
|
209
245
|
## The Product: Three Screens
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getLens
|
|
3
3
|
} from "./chunk-VGFDMPVB.js";
|
|
4
|
+
import {
|
|
5
|
+
loadWorld
|
|
6
|
+
} from "./chunk-I4RTIMLX.js";
|
|
7
|
+
import {
|
|
8
|
+
evaluateGuard
|
|
9
|
+
} from "./chunk-ZAF6JH23.js";
|
|
4
10
|
|
|
5
11
|
// src/radiant/core/prompt.ts
|
|
6
12
|
function composeSystemPrompt(worldmodelContent, lens) {
|
|
@@ -139,17 +145,30 @@ function resolveLens(id) {
|
|
|
139
145
|
}
|
|
140
146
|
|
|
141
147
|
// src/radiant/core/scopes.ts
|
|
142
|
-
function
|
|
148
|
+
function parseScope(scope) {
|
|
143
149
|
const cleaned = scope.replace(/^https?:\/\//, "").replace(/^github\.com\//, "").replace(/\.git$/, "").replace(/\/$/, "");
|
|
144
|
-
const parts = cleaned.split("/");
|
|
145
|
-
if (parts.length
|
|
150
|
+
const parts = cleaned.split("/").filter(Boolean);
|
|
151
|
+
if (parts.length === 0 || !parts[0]) {
|
|
152
|
+
throw new Error(
|
|
153
|
+
`Cannot parse scope: "${scope}". Expected "owner/repo" or "owner".`
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
if (parts.length === 1) {
|
|
157
|
+
return { type: "org", owner: parts[0] };
|
|
158
|
+
}
|
|
159
|
+
return { type: "repo", owner: parts[0], repo: parts[1] };
|
|
160
|
+
}
|
|
161
|
+
function parseRepoScope(scope) {
|
|
162
|
+
const parsed = parseScope(scope);
|
|
163
|
+
if (parsed.type === "org") {
|
|
146
164
|
throw new Error(
|
|
147
|
-
`
|
|
165
|
+
`Expected "owner/repo" but got org-level scope "${parsed.owner}". Use parseScope() for org-level.`
|
|
148
166
|
);
|
|
149
167
|
}
|
|
150
|
-
return
|
|
168
|
+
return parsed;
|
|
151
169
|
}
|
|
152
170
|
function formatScope(scope) {
|
|
171
|
+
if (scope.type === "org") return `${scope.owner} (org)`;
|
|
153
172
|
return `${scope.owner}/${scope.repo}`;
|
|
154
173
|
}
|
|
155
174
|
|
|
@@ -333,12 +352,46 @@ async function fetchJSON(url, headers) {
|
|
|
333
352
|
}
|
|
334
353
|
return await res.json();
|
|
335
354
|
}
|
|
355
|
+
async function fetchGitHubOrgActivity(scope, token, options = {}) {
|
|
356
|
+
const perPage = options.perPage ?? 100;
|
|
357
|
+
const headers = {
|
|
358
|
+
Authorization: `token ${token}`,
|
|
359
|
+
Accept: "application/vnd.github.v3+json",
|
|
360
|
+
"User-Agent": "neuroverseos-radiant"
|
|
361
|
+
};
|
|
362
|
+
const repos = await fetchJSON(
|
|
363
|
+
`https://api.github.com/orgs/${scope.owner}/repos?sort=pushed&direction=desc&per_page=${perPage}`,
|
|
364
|
+
headers
|
|
365
|
+
);
|
|
366
|
+
const windowDays = options.windowDays ?? 14;
|
|
367
|
+
const since = new Date(Date.now() - windowDays * 24 * 60 * 60 * 1e3);
|
|
368
|
+
const activeRepos = repos.filter(
|
|
369
|
+
(r) => new Date(r.pushed_at) >= since
|
|
370
|
+
);
|
|
371
|
+
const cappedRepos = activeRepos.slice(0, 10);
|
|
372
|
+
const allEvents = [];
|
|
373
|
+
const repoNames = [];
|
|
374
|
+
for (const repo of cappedRepos) {
|
|
375
|
+
const [owner, repoName] = repo.full_name.split("/");
|
|
376
|
+
try {
|
|
377
|
+
const repoScope = { type: "repo", owner, repo: repoName };
|
|
378
|
+
const events = await fetchGitHubActivity(repoScope, token, options);
|
|
379
|
+
allEvents.push(...events);
|
|
380
|
+
if (events.length > 0) repoNames.push(repo.full_name);
|
|
381
|
+
} catch {
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
allEvents.sort(
|
|
385
|
+
(a, b) => Date.parse(a.timestamp) - Date.parse(b.timestamp)
|
|
386
|
+
);
|
|
387
|
+
return { events: allEvents, repos: repoNames };
|
|
388
|
+
}
|
|
336
389
|
function createMockGitHubAdapter(fixedEvents) {
|
|
337
390
|
return async () => fixedEvents;
|
|
338
391
|
}
|
|
339
392
|
|
|
340
393
|
// src/radiant/adapters/exocortex.ts
|
|
341
|
-
import { readFileSync, existsSync } from "fs";
|
|
394
|
+
import { readFileSync, existsSync, readdirSync, statSync } from "fs";
|
|
342
395
|
import { join, resolve } from "path";
|
|
343
396
|
function readExocortex(dirPath) {
|
|
344
397
|
const dir = resolve(dirPath);
|
|
@@ -409,6 +462,46 @@ ${ctx.methods}`);
|
|
|
409
462
|
}
|
|
410
463
|
return sections.join("\n\n");
|
|
411
464
|
}
|
|
465
|
+
function readTeamExocortices(teamDir) {
|
|
466
|
+
const dir = resolve(teamDir);
|
|
467
|
+
if (!existsSync(dir)) return [];
|
|
468
|
+
const entries = readdirSync(dir);
|
|
469
|
+
const results = [];
|
|
470
|
+
for (const entry of entries) {
|
|
471
|
+
const entryPath = join(dir, entry);
|
|
472
|
+
try {
|
|
473
|
+
const stat = statSync(entryPath);
|
|
474
|
+
if (stat.isDirectory()) {
|
|
475
|
+
const ctx = readExocortex(entryPath);
|
|
476
|
+
if (ctx.filesLoaded > 0) {
|
|
477
|
+
results.push({ name: entry, context: ctx });
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
} catch {
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
return results;
|
|
484
|
+
}
|
|
485
|
+
function formatTeamExocorticesForPrompt(team) {
|
|
486
|
+
if (team.length === 0) return "";
|
|
487
|
+
const sections = [
|
|
488
|
+
"## Team Intent (cross-exocortex read)",
|
|
489
|
+
"",
|
|
490
|
+
`Reading ${team.length} team members' exocortices. Compare each person's`,
|
|
491
|
+
"stated intent against the observed activity AND against each other.",
|
|
492
|
+
"Surface: duplicate focus, missing coverage, silent pivots,",
|
|
493
|
+
"and areas where no one is carrying the work.",
|
|
494
|
+
""
|
|
495
|
+
];
|
|
496
|
+
for (const { name, context } of team) {
|
|
497
|
+
sections.push(`### ${name}`);
|
|
498
|
+
if (context.attention) sections.push(`**Attention:** ${context.attention.split("\n")[0]}`);
|
|
499
|
+
if (context.goals) sections.push(`**Goals:** ${context.goals.split("\n").slice(0, 3).join("; ")}`);
|
|
500
|
+
if (context.sprint) sections.push(`**Sprint:** ${context.sprint.split("\n").slice(0, 3).join("; ")}`);
|
|
501
|
+
sections.push("");
|
|
502
|
+
}
|
|
503
|
+
return sections.join("\n");
|
|
504
|
+
}
|
|
412
505
|
function summarizeExocortex(ctx) {
|
|
413
506
|
if (ctx.filesLoaded === 0) return "no exocortex files found";
|
|
414
507
|
const loaded = [];
|
|
@@ -421,6 +514,305 @@ function summarizeExocortex(ctx) {
|
|
|
421
514
|
return `${loaded.join(", ")} (${ctx.filesLoaded} files)`;
|
|
422
515
|
}
|
|
423
516
|
|
|
517
|
+
// src/radiant/memory/palace.ts
|
|
518
|
+
import { readFileSync as readFileSync2, writeFileSync, mkdirSync, readdirSync as readdirSync2, existsSync as existsSync2 } from "fs";
|
|
519
|
+
import { join as join2, resolve as resolve2 } from "path";
|
|
520
|
+
function writeRead(exocortexDir, frontmatter, text) {
|
|
521
|
+
const dir = resolve2(exocortexDir, "radiant", "reads");
|
|
522
|
+
mkdirSync(dir, { recursive: true });
|
|
523
|
+
const date = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
524
|
+
const filename = `${date}.md`;
|
|
525
|
+
const filepath = join2(dir, filename);
|
|
526
|
+
const content = `${frontmatter}
|
|
527
|
+
|
|
528
|
+
${text}
|
|
529
|
+
`;
|
|
530
|
+
writeFileSync(filepath, content, "utf-8");
|
|
531
|
+
return filepath;
|
|
532
|
+
}
|
|
533
|
+
function updateKnowledge(exocortexDir, persistence, options) {
|
|
534
|
+
const dir = resolve2(exocortexDir, "radiant");
|
|
535
|
+
mkdirSync(dir, { recursive: true });
|
|
536
|
+
const filepath = join2(dir, "knowledge.md");
|
|
537
|
+
const totalReads = options?.totalReads ?? 0;
|
|
538
|
+
const existingUntriggered = loadUntriggeredCounts(filepath);
|
|
539
|
+
const lines = [
|
|
540
|
+
"# Radiant \u2014 Accumulated Behavioral Knowledge",
|
|
541
|
+
"",
|
|
542
|
+
`Last updated: ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}`,
|
|
543
|
+
`Total reads: ${totalReads}`,
|
|
544
|
+
"",
|
|
545
|
+
"---",
|
|
546
|
+
"",
|
|
547
|
+
"## Evolution proposals",
|
|
548
|
+
""
|
|
549
|
+
];
|
|
550
|
+
const addCandidates = persistence.filter((p) => p.occurrences >= 3);
|
|
551
|
+
if (addCandidates.length > 0) {
|
|
552
|
+
lines.push("### Consider adding");
|
|
553
|
+
lines.push("");
|
|
554
|
+
lines.push("These candidate patterns keep recurring. They are not yet in the worldmodel.");
|
|
555
|
+
lines.push("If they represent real behavioral patterns worth tracking, add them.");
|
|
556
|
+
lines.push("If they were temporary, dismiss them.");
|
|
557
|
+
lines.push("");
|
|
558
|
+
for (const p of addCandidates) {
|
|
559
|
+
lines.push(
|
|
560
|
+
`- **${p.name}** \u2014 observed ${p.occurrences} times (${p.dates.join(", ")}). Add to auki-strategy.worldmodel.md \u2192 Evolution Layer \u2192 Drift Behaviors (if concerning) or Aligned Behaviors (if healthy).`
|
|
561
|
+
);
|
|
562
|
+
}
|
|
563
|
+
lines.push("");
|
|
564
|
+
}
|
|
565
|
+
if (options?.declaredItems && options.declaredItems.length > 0) {
|
|
566
|
+
const triggered = new Set(options.triggeredItems ?? []);
|
|
567
|
+
const removeCandidates = [];
|
|
568
|
+
for (const item of options.declaredItems) {
|
|
569
|
+
if (!triggered.has(item.name)) {
|
|
570
|
+
const prior = existingUntriggered.get(item.name) ?? 0;
|
|
571
|
+
const count = prior + 1;
|
|
572
|
+
existingUntriggered.set(item.name, count);
|
|
573
|
+
if (count >= 4) {
|
|
574
|
+
removeCandidates.push({ item, weeksSilent: count });
|
|
575
|
+
}
|
|
576
|
+
} else {
|
|
577
|
+
existingUntriggered.set(item.name, 0);
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
if (removeCandidates.length > 0) {
|
|
581
|
+
lines.push("### Consider removing");
|
|
582
|
+
lines.push("");
|
|
583
|
+
lines.push("These items are declared in the worldmodel but haven't triggered in multiple reads.");
|
|
584
|
+
lines.push("Either the team has internalized them (the rule is redundant) or they haven't been tested.");
|
|
585
|
+
lines.push("A lean worldmodel with 5 sharp invariants is stronger than a bloated one with 20.");
|
|
586
|
+
lines.push("");
|
|
587
|
+
for (const { item, weeksSilent } of removeCandidates) {
|
|
588
|
+
lines.push(
|
|
589
|
+
`- **${item.name}** (${item.type}) \u2014 hasn't triggered in ${weeksSilent} reads. Internalized or untested? Review whether it still earns its place.`
|
|
590
|
+
);
|
|
591
|
+
}
|
|
592
|
+
lines.push("");
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
if (options?.triggeredItems && options.triggeredItems.length > 0) {
|
|
596
|
+
lines.push("### Keep (recently active)");
|
|
597
|
+
lines.push("");
|
|
598
|
+
lines.push("These worldmodel items triggered governance in the most recent read. They're earning their place.");
|
|
599
|
+
lines.push("");
|
|
600
|
+
for (const name of options.triggeredItems) {
|
|
601
|
+
lines.push(`- **${name}** \u2014 triggered this read. Holding.`);
|
|
602
|
+
}
|
|
603
|
+
lines.push("");
|
|
604
|
+
}
|
|
605
|
+
lines.push("---");
|
|
606
|
+
lines.push("");
|
|
607
|
+
lines.push("## Pattern persistence (all observed)");
|
|
608
|
+
lines.push("");
|
|
609
|
+
for (const p of persistence) {
|
|
610
|
+
const status = p.occurrences >= 4 ? "**persistent**" : p.occurrences >= 2 ? "recurring" : "observed once";
|
|
611
|
+
lines.push(`### ${p.name}`);
|
|
612
|
+
lines.push(`- Status: ${status}`);
|
|
613
|
+
lines.push(`- Observed ${p.occurrences} time${p.occurrences > 1 ? "s" : ""}: ${p.dates.join(", ")}`);
|
|
614
|
+
lines.push("");
|
|
615
|
+
}
|
|
616
|
+
lines.push("---");
|
|
617
|
+
lines.push("");
|
|
618
|
+
lines.push("<!-- untriggered_counts (machine-readable, do not edit)");
|
|
619
|
+
for (const [name, count] of existingUntriggered.entries()) {
|
|
620
|
+
lines.push(`${name}=${count}`);
|
|
621
|
+
}
|
|
622
|
+
lines.push("-->");
|
|
623
|
+
writeFileSync(filepath, lines.join("\n"), "utf-8");
|
|
624
|
+
return filepath;
|
|
625
|
+
}
|
|
626
|
+
function loadUntriggeredCounts(filepath) {
|
|
627
|
+
const counts = /* @__PURE__ */ new Map();
|
|
628
|
+
if (!existsSync2(filepath)) return counts;
|
|
629
|
+
try {
|
|
630
|
+
const content = readFileSync2(filepath, "utf-8");
|
|
631
|
+
const match = content.match(
|
|
632
|
+
/<!-- untriggered_counts[\s\S]*?-->/
|
|
633
|
+
);
|
|
634
|
+
if (match) {
|
|
635
|
+
const lines = match[0].split("\n");
|
|
636
|
+
for (const line of lines) {
|
|
637
|
+
const eq = line.match(/^([^=]+)=(\d+)$/);
|
|
638
|
+
if (eq) {
|
|
639
|
+
counts.set(eq[1], parseInt(eq[2], 10));
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
} catch {
|
|
644
|
+
}
|
|
645
|
+
return counts;
|
|
646
|
+
}
|
|
647
|
+
function loadPriorReads(exocortexDir) {
|
|
648
|
+
const dir = resolve2(exocortexDir, "radiant", "reads");
|
|
649
|
+
if (!existsSync2(dir)) return [];
|
|
650
|
+
const files = readdirSync2(dir).filter((f) => f.endsWith(".md")).sort();
|
|
651
|
+
const reads = [];
|
|
652
|
+
for (const filename of files) {
|
|
653
|
+
const filepath = join2(dir, filename);
|
|
654
|
+
const content = readFileSync2(filepath, "utf-8");
|
|
655
|
+
const date = filename.replace(".md", "");
|
|
656
|
+
const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
657
|
+
const frontmatter = fmMatch ? fmMatch[1] : "";
|
|
658
|
+
const patternNames = [];
|
|
659
|
+
const nameMatches = frontmatter.matchAll(/- name: ["']?([^"'\n]+)["']?/g);
|
|
660
|
+
for (const m of nameMatches) {
|
|
661
|
+
patternNames.push(m[1].trim());
|
|
662
|
+
}
|
|
663
|
+
reads.push({ date, filename, patternNames, frontmatter });
|
|
664
|
+
}
|
|
665
|
+
return reads;
|
|
666
|
+
}
|
|
667
|
+
function computePersistence(priorReads, currentPatternNames) {
|
|
668
|
+
const allPatterns = /* @__PURE__ */ new Map();
|
|
669
|
+
for (const read of priorReads) {
|
|
670
|
+
for (const name of read.patternNames) {
|
|
671
|
+
const dates = allPatterns.get(name) ?? [];
|
|
672
|
+
if (!dates.includes(read.date)) dates.push(read.date);
|
|
673
|
+
allPatterns.set(name, dates);
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
677
|
+
for (const name of currentPatternNames) {
|
|
678
|
+
const dates = allPatterns.get(name) ?? [];
|
|
679
|
+
if (!dates.includes(today)) dates.push(today);
|
|
680
|
+
allPatterns.set(name, dates);
|
|
681
|
+
}
|
|
682
|
+
return Array.from(allPatterns.entries()).map(([name, dates]) => ({
|
|
683
|
+
name,
|
|
684
|
+
occurrences: dates.length,
|
|
685
|
+
dates: dates.sort()
|
|
686
|
+
})).sort((a, b) => b.occurrences - a.occurrences);
|
|
687
|
+
}
|
|
688
|
+
function formatPriorReadsForPrompt(priorReads) {
|
|
689
|
+
if (priorReads.length === 0) return "";
|
|
690
|
+
const lines = [
|
|
691
|
+
"## Prior Radiant reads (history)",
|
|
692
|
+
"",
|
|
693
|
+
`Radiant has run ${priorReads.length} time${priorReads.length > 1 ? "s" : ""} before on this scope.`,
|
|
694
|
+
"If you see patterns that appeared in prior reads, note their persistence.",
|
|
695
|
+
"Patterns that recur across 3+ reads are strong candidates for declaration in the strategy file.",
|
|
696
|
+
""
|
|
697
|
+
];
|
|
698
|
+
for (const read of priorReads.slice(-4)) {
|
|
699
|
+
lines.push(`### Read from ${read.date}`);
|
|
700
|
+
if (read.patternNames.length > 0) {
|
|
701
|
+
lines.push(`Patterns observed: ${read.patternNames.join(", ")}`);
|
|
702
|
+
} else {
|
|
703
|
+
lines.push("No patterns extracted from frontmatter.");
|
|
704
|
+
}
|
|
705
|
+
lines.push("");
|
|
706
|
+
}
|
|
707
|
+
return lines.join("\n");
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
// src/radiant/core/governance.ts
|
|
711
|
+
async function auditGovernance(events, worldPath) {
|
|
712
|
+
let world;
|
|
713
|
+
try {
|
|
714
|
+
world = await loadWorld(worldPath);
|
|
715
|
+
} catch {
|
|
716
|
+
return emptyAudit(events.length, "Could not load compiled worldmodel for governance audit.");
|
|
717
|
+
}
|
|
718
|
+
const verdicts = [];
|
|
719
|
+
for (const ce of events) {
|
|
720
|
+
const intent = ce.event.content?.slice(0, 500) || ce.event.kind || "activity";
|
|
721
|
+
const scope = ce.event.metadata?.scope || void 0;
|
|
722
|
+
try {
|
|
723
|
+
const result = evaluateGuard(
|
|
724
|
+
{
|
|
725
|
+
intent,
|
|
726
|
+
scope,
|
|
727
|
+
actionCategory: mapKindToCategory(ce.event.kind)
|
|
728
|
+
},
|
|
729
|
+
world
|
|
730
|
+
);
|
|
731
|
+
verdicts.push({
|
|
732
|
+
eventId: ce.event.id,
|
|
733
|
+
domain: ce.domain,
|
|
734
|
+
status: result.status,
|
|
735
|
+
reason: result.reason,
|
|
736
|
+
ruleId: result.ruleId,
|
|
737
|
+
warning: result.warning
|
|
738
|
+
});
|
|
739
|
+
} catch {
|
|
740
|
+
verdicts.push({
|
|
741
|
+
eventId: ce.event.id,
|
|
742
|
+
domain: ce.domain,
|
|
743
|
+
status: "ALLOW",
|
|
744
|
+
reason: "guard evaluation skipped (error)"
|
|
745
|
+
});
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
const human = bucketVerdicts(verdicts.filter((v) => v.domain === "life"));
|
|
749
|
+
const cyber = bucketVerdicts(verdicts.filter((v) => v.domain === "cyber"));
|
|
750
|
+
const joint = bucketVerdicts(verdicts.filter((v) => v.domain === "joint"));
|
|
751
|
+
const summary = buildSummary(human, cyber, joint, events.length);
|
|
752
|
+
return {
|
|
753
|
+
totalEvents: events.length,
|
|
754
|
+
human,
|
|
755
|
+
cyber,
|
|
756
|
+
joint,
|
|
757
|
+
summary
|
|
758
|
+
};
|
|
759
|
+
}
|
|
760
|
+
function bucketVerdicts(verdicts) {
|
|
761
|
+
const nonAllow = verdicts.filter((v) => v.status !== "ALLOW");
|
|
762
|
+
return {
|
|
763
|
+
allow: verdicts.filter((v) => v.status === "ALLOW").length,
|
|
764
|
+
modify: verdicts.filter((v) => v.status === "MODIFY").length,
|
|
765
|
+
block: verdicts.filter((v) => v.status === "BLOCK").length,
|
|
766
|
+
details: nonAllow
|
|
767
|
+
};
|
|
768
|
+
}
|
|
769
|
+
function buildSummary(human, cyber, joint, total) {
|
|
770
|
+
const humanTriggered = human.modify + human.block;
|
|
771
|
+
const cyberTriggered = cyber.modify + cyber.block;
|
|
772
|
+
const jointTriggered = joint.modify + joint.block;
|
|
773
|
+
const totalTriggered = humanTriggered + cyberTriggered + jointTriggered;
|
|
774
|
+
if (totalTriggered === 0) {
|
|
775
|
+
return `${total} events evaluated. All passed. The cocoon held \u2014 no governance triggered.`;
|
|
776
|
+
}
|
|
777
|
+
const parts = [];
|
|
778
|
+
parts.push(`${total} events evaluated. ${totalTriggered} triggered governance.`);
|
|
779
|
+
if (humanTriggered > 0) {
|
|
780
|
+
parts.push(`Human side: ${humanTriggered} (${human.block} blocked, ${human.modify} modified).`);
|
|
781
|
+
}
|
|
782
|
+
if (cyberTriggered > 0) {
|
|
783
|
+
parts.push(`AI side: ${cyberTriggered} (${cyber.block} blocked, ${cyber.modify} modified).`);
|
|
784
|
+
}
|
|
785
|
+
if (jointTriggered > 0) {
|
|
786
|
+
parts.push(`Joint work: ${jointTriggered} (${joint.block} blocked, ${joint.modify} modified).`);
|
|
787
|
+
}
|
|
788
|
+
if (humanTriggered > 0 && cyberTriggered > 0) {
|
|
789
|
+
const ratio = humanTriggered / cyberTriggered;
|
|
790
|
+
if (ratio > 2) {
|
|
791
|
+
parts.push("Human side is testing the frame more than AI. Either the worldmodel needs calibrating for human workflows, or humans are genuinely drifting.");
|
|
792
|
+
} else if (ratio < 0.5) {
|
|
793
|
+
parts.push("AI side is testing the frame more than humans. Check whether the AI's output patterns match the declared invariants.");
|
|
794
|
+
} else {
|
|
795
|
+
parts.push("Roughly balanced between human and AI \u2014 both sides are testing the frame.");
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
return parts.join(" ");
|
|
799
|
+
}
|
|
800
|
+
function mapKindToCategory(kind) {
|
|
801
|
+
if (!kind) return "other";
|
|
802
|
+
if (kind.includes("commit") || kind.includes("merge")) return "write";
|
|
803
|
+
if (kind.includes("review") || kind.includes("comment")) return "read";
|
|
804
|
+
return "other";
|
|
805
|
+
}
|
|
806
|
+
function emptyAudit(total, reason) {
|
|
807
|
+
return {
|
|
808
|
+
totalEvents: total,
|
|
809
|
+
human: { allow: 0, modify: 0, block: 0, details: [] },
|
|
810
|
+
cyber: { allow: 0, modify: 0, block: 0, details: [] },
|
|
811
|
+
joint: { allow: 0, modify: 0, block: 0, details: [] },
|
|
812
|
+
summary: reason
|
|
813
|
+
};
|
|
814
|
+
}
|
|
815
|
+
|
|
424
816
|
// src/radiant/core/domain.ts
|
|
425
817
|
function isLifeSide(k) {
|
|
426
818
|
return k === "human" || k === "unknown";
|
|
@@ -690,6 +1082,14 @@ ${jargonTable}
|
|
|
690
1082
|
|
|
691
1083
|
For example: don't say "update the worldmodel." Say "add a line to your strategy file."
|
|
692
1084
|
|
|
1085
|
+
## When the same invariant keeps firing
|
|
1086
|
+
|
|
1087
|
+
If the prior read history or the current evidence shows the same worldmodel invariant being triggered repeatedly (by the same side \u2014 human or AI), name it in MEANING and ask the real question:
|
|
1088
|
+
|
|
1089
|
+
"This invariant has been tested N times across M reads. Always on the [human/AI] side. Either the team needs alignment on WHY this rule exists \u2014 or the team is telling you something the worldmodel hasn't absorbed yet."
|
|
1090
|
+
|
|
1091
|
+
Don't just say "invariant held." Say what it means that people keep pushing against the same wall.
|
|
1092
|
+
|
|
693
1093
|
## Health is a valid read
|
|
694
1094
|
|
|
695
1095
|
If the activity is healthy and aligned with the worldmodel, SAY SO. Don't fabricate problems. Over-prescription is a voice failure. Legitimate outputs include:
|
|
@@ -718,7 +1118,7 @@ Only recommend a move when the evidence actually calls for one.
|
|
|
718
1118
|
}
|
|
719
1119
|
],
|
|
720
1120
|
"meaning": "3-5 sentences. Weave the patterns into ONE strategic thesis. Compress. The reader should finish this paragraph and understand the one thing that matters most in this read. Plain English \u2014 no system jargon.",
|
|
721
|
-
"move": "1-3 direct imperatives, OR explicit 'nothing to act on' if the read is healthy. Do not fabricate urgency.
|
|
1121
|
+
"move": "1-3 direct imperatives, OR explicit 'nothing to act on' if the read is healthy. Do not fabricate urgency. When a candidate pattern has high confidence (>0.6), tell the reader EXACTLY where to declare it: 'If you want Radiant to track [pattern_name] over time, add it to auki-strategy.worldmodel.md under Evolution Layer \u2192 Drift Behaviors (or Aligned Behaviors if it is positive). If you don't, Radiant will rediscover it from scratch next run.' Be specific about the file and section \u2014 don't make them guess."
|
|
722
1122
|
}
|
|
723
1123
|
\`\`\`
|
|
724
1124
|
|
|
@@ -874,6 +1274,27 @@ Lens: ${input.lens.name}`
|
|
|
874
1274
|
` Composite: ${formatScore(input.scores.R)}`
|
|
875
1275
|
].join("\n");
|
|
876
1276
|
sections.push(alignBlock);
|
|
1277
|
+
if (input.governance && input.governance.totalEvents > 0) {
|
|
1278
|
+
const gov = input.governance;
|
|
1279
|
+
const govLines = ["GOVERNANCE", "", ` ${gov.summary}`];
|
|
1280
|
+
const showSide = (label, side) => {
|
|
1281
|
+
if (side.allow + side.modify + side.block === 0) return;
|
|
1282
|
+
govLines.push("");
|
|
1283
|
+
govLines.push(` ${label}:`);
|
|
1284
|
+
govLines.push(` ${side.allow} ALLOW \xB7 ${side.modify} MODIFY \xB7 ${side.block} BLOCK`);
|
|
1285
|
+
for (const d of side.details.slice(0, 3)) {
|
|
1286
|
+
const reason = d.reason ? ` \u2192 ${d.reason}` : "";
|
|
1287
|
+
govLines.push(` ${d.status}: ${d.eventId}${reason}`);
|
|
1288
|
+
}
|
|
1289
|
+
if (side.details.length > 3) {
|
|
1290
|
+
govLines.push(` ... and ${side.details.length - 3} more`);
|
|
1291
|
+
}
|
|
1292
|
+
};
|
|
1293
|
+
showSide("Human side", gov.human);
|
|
1294
|
+
showSide("AI side", gov.cyber);
|
|
1295
|
+
showSide("Human\u2013AI joint", gov.joint);
|
|
1296
|
+
sections.push(govLines.join("\n"));
|
|
1297
|
+
}
|
|
877
1298
|
sections.push(renderDepth(input.priorReadCount ?? 0, input.windowDays));
|
|
878
1299
|
return sections.join("\n\n");
|
|
879
1300
|
}
|
|
@@ -1043,14 +1464,31 @@ async function emergent(input) {
|
|
|
1043
1464
|
const windowDays = input.windowDays ?? 14;
|
|
1044
1465
|
let statedIntent;
|
|
1045
1466
|
let exocortexContext;
|
|
1467
|
+
let priorReadContext = "";
|
|
1046
1468
|
if (input.exocortexPath) {
|
|
1047
1469
|
exocortexContext = readExocortex(input.exocortexPath);
|
|
1048
1470
|
const formatted = formatExocortexForPrompt(exocortexContext);
|
|
1049
1471
|
if (formatted) statedIntent = formatted;
|
|
1472
|
+
const priorReads = loadPriorReads(input.exocortexPath);
|
|
1473
|
+
if (priorReads.length > 0) {
|
|
1474
|
+
priorReadContext = formatPriorReadsForPrompt(priorReads);
|
|
1475
|
+
}
|
|
1476
|
+
}
|
|
1477
|
+
let events;
|
|
1478
|
+
let orgRepos;
|
|
1479
|
+
if (input.scope.type === "org") {
|
|
1480
|
+
const orgResult = await fetchGitHubOrgActivity(
|
|
1481
|
+
input.scope,
|
|
1482
|
+
input.githubToken,
|
|
1483
|
+
{ windowDays }
|
|
1484
|
+
);
|
|
1485
|
+
events = orgResult.events;
|
|
1486
|
+
orgRepos = orgResult.repos;
|
|
1487
|
+
} else {
|
|
1488
|
+
events = await fetchGitHubActivity(input.scope, input.githubToken, {
|
|
1489
|
+
windowDays
|
|
1490
|
+
});
|
|
1050
1491
|
}
|
|
1051
|
-
const events = await fetchGitHubActivity(input.scope, input.githubToken, {
|
|
1052
|
-
windowDays
|
|
1053
|
-
});
|
|
1054
1492
|
const classified = classifyEvents(events);
|
|
1055
1493
|
const signals = extractSignals(classified);
|
|
1056
1494
|
const scores = computeScores(signals, input.worldmodelContent !== "");
|
|
@@ -1061,11 +1499,18 @@ async function emergent(input) {
|
|
|
1061
1499
|
lens,
|
|
1062
1500
|
ai: input.ai,
|
|
1063
1501
|
canonicalPatterns: input.canonicalPatterns,
|
|
1064
|
-
statedIntent
|
|
1502
|
+
statedIntent: statedIntent ? statedIntent + (priorReadContext ? "\n\n" + priorReadContext : "") : priorReadContext || void 0
|
|
1065
1503
|
});
|
|
1066
1504
|
const rewrittenPatterns = patterns.map((p) => lens.rewrite(p));
|
|
1067
1505
|
const allDescriptions = rewrittenPatterns.map((p) => p.description).join("\n");
|
|
1068
1506
|
const voiceViolations = checkForbiddenPhrases(lens, allDescriptions);
|
|
1507
|
+
let governance;
|
|
1508
|
+
if (input.worldPath) {
|
|
1509
|
+
try {
|
|
1510
|
+
governance = await auditGovernance(classified, input.worldPath);
|
|
1511
|
+
} catch {
|
|
1512
|
+
}
|
|
1513
|
+
}
|
|
1069
1514
|
const rendered = render({
|
|
1070
1515
|
scope: input.scope,
|
|
1071
1516
|
windowDays,
|
|
@@ -1075,8 +1520,27 @@ async function emergent(input) {
|
|
|
1075
1520
|
scores,
|
|
1076
1521
|
lens,
|
|
1077
1522
|
meaning: meaning || void 0,
|
|
1078
|
-
move: move || void 0
|
|
1523
|
+
move: move || void 0,
|
|
1524
|
+
governance
|
|
1079
1525
|
});
|
|
1526
|
+
if (input.exocortexPath) {
|
|
1527
|
+
try {
|
|
1528
|
+
const readPath = writeRead(input.exocortexPath, rendered.frontmatter, rendered.text);
|
|
1529
|
+
const priorReads = loadPriorReads(input.exocortexPath);
|
|
1530
|
+
const currentPatternNames = rewrittenPatterns.map((p) => p.name);
|
|
1531
|
+
const persistence = computePersistence(priorReads, currentPatternNames);
|
|
1532
|
+
const triggeredItems = governance ? [
|
|
1533
|
+
...governance.human.details.map((d) => d.ruleId).filter(Boolean),
|
|
1534
|
+
...governance.cyber.details.map((d) => d.ruleId).filter(Boolean),
|
|
1535
|
+
...governance.joint.details.map((d) => d.ruleId).filter(Boolean)
|
|
1536
|
+
] : [];
|
|
1537
|
+
updateKnowledge(input.exocortexPath, persistence, {
|
|
1538
|
+
triggeredItems,
|
|
1539
|
+
totalReads: priorReads.length + 1
|
|
1540
|
+
});
|
|
1541
|
+
} catch {
|
|
1542
|
+
}
|
|
1543
|
+
}
|
|
1080
1544
|
return {
|
|
1081
1545
|
text: rendered.text,
|
|
1082
1546
|
frontmatter: rendered.frontmatter,
|
|
@@ -1180,13 +1644,23 @@ export {
|
|
|
1180
1644
|
composeSystemPrompt,
|
|
1181
1645
|
checkForbiddenPhrases,
|
|
1182
1646
|
think,
|
|
1647
|
+
parseScope,
|
|
1183
1648
|
parseRepoScope,
|
|
1184
1649
|
formatScope,
|
|
1185
1650
|
fetchGitHubActivity,
|
|
1651
|
+
fetchGitHubOrgActivity,
|
|
1186
1652
|
createMockGitHubAdapter,
|
|
1187
1653
|
readExocortex,
|
|
1188
1654
|
formatExocortexForPrompt,
|
|
1655
|
+
readTeamExocortices,
|
|
1656
|
+
formatTeamExocorticesForPrompt,
|
|
1189
1657
|
summarizeExocortex,
|
|
1658
|
+
writeRead,
|
|
1659
|
+
updateKnowledge,
|
|
1660
|
+
loadPriorReads,
|
|
1661
|
+
computePersistence,
|
|
1662
|
+
formatPriorReadsForPrompt,
|
|
1663
|
+
auditGovernance,
|
|
1190
1664
|
classifyActorDomain,
|
|
1191
1665
|
classifyEvents,
|
|
1192
1666
|
extractSignals,
|