@neuroverseos/governance 0.6.1 → 0.7.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 +0 -3
- package/dist/{chunk-AEVT7DSZ.js → chunk-T6EQ7ZBG.js} +366 -3
- package/dist/cli/neuroverse.cjs +770 -129
- package/dist/cli/radiant.cjs +2078 -139
- package/dist/cli/radiant.js +8 -1
- package/dist/radiant/index.cjs +1554 -5
- package/dist/radiant/index.d.cts +146 -8
- package/dist/radiant/index.d.ts +146 -8
- package/dist/radiant/index.js +18 -3
- package/dist/server-BXMC5NOE.js +271 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -55,7 +55,6 @@ NeuroVerse gives you composable primitives:
|
|
|
55
55
|
|
|
56
56
|
These blocks let you build robots/agents that can traverse heterogeneous spaces while remaining policy-compliant, auditable, and deterministic.
|
|
57
57
|
|
|
58
|
-
<<<<<<< codex/review-open-source-repo-for-ai-architecture
|
|
59
58
|
### Mental Model: Layered Rules (World → Law → Situation)
|
|
60
59
|
|
|
61
60
|
If you're explaining this to developers or non-technical stakeholders, use this:
|
|
@@ -202,8 +201,6 @@ Use this section to show real runtime behavior and response time.
|
|
|
202
201
|
4. **Level 4 — Spatial + Multi-Actor Governance**
|
|
203
202
|
Add zone opt-in, handshake negotiation, and dynamic policy composition.
|
|
204
203
|
|
|
205
|
-
=======
|
|
206
|
-
>>>>>>> main
|
|
207
204
|
---
|
|
208
205
|
|
|
209
206
|
## 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) {
|
|
@@ -421,6 +427,305 @@ function summarizeExocortex(ctx) {
|
|
|
421
427
|
return `${loaded.join(", ")} (${ctx.filesLoaded} files)`;
|
|
422
428
|
}
|
|
423
429
|
|
|
430
|
+
// src/radiant/memory/palace.ts
|
|
431
|
+
import { readFileSync as readFileSync2, writeFileSync, mkdirSync, readdirSync, existsSync as existsSync2 } from "fs";
|
|
432
|
+
import { join as join2, resolve as resolve2 } from "path";
|
|
433
|
+
function writeRead(exocortexDir, frontmatter, text) {
|
|
434
|
+
const dir = resolve2(exocortexDir, "radiant", "reads");
|
|
435
|
+
mkdirSync(dir, { recursive: true });
|
|
436
|
+
const date = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
437
|
+
const filename = `${date}.md`;
|
|
438
|
+
const filepath = join2(dir, filename);
|
|
439
|
+
const content = `${frontmatter}
|
|
440
|
+
|
|
441
|
+
${text}
|
|
442
|
+
`;
|
|
443
|
+
writeFileSync(filepath, content, "utf-8");
|
|
444
|
+
return filepath;
|
|
445
|
+
}
|
|
446
|
+
function updateKnowledge(exocortexDir, persistence, options) {
|
|
447
|
+
const dir = resolve2(exocortexDir, "radiant");
|
|
448
|
+
mkdirSync(dir, { recursive: true });
|
|
449
|
+
const filepath = join2(dir, "knowledge.md");
|
|
450
|
+
const totalReads = options?.totalReads ?? 0;
|
|
451
|
+
const existingUntriggered = loadUntriggeredCounts(filepath);
|
|
452
|
+
const lines = [
|
|
453
|
+
"# Radiant \u2014 Accumulated Behavioral Knowledge",
|
|
454
|
+
"",
|
|
455
|
+
`Last updated: ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}`,
|
|
456
|
+
`Total reads: ${totalReads}`,
|
|
457
|
+
"",
|
|
458
|
+
"---",
|
|
459
|
+
"",
|
|
460
|
+
"## Evolution proposals",
|
|
461
|
+
""
|
|
462
|
+
];
|
|
463
|
+
const addCandidates = persistence.filter((p) => p.occurrences >= 3);
|
|
464
|
+
if (addCandidates.length > 0) {
|
|
465
|
+
lines.push("### Consider adding");
|
|
466
|
+
lines.push("");
|
|
467
|
+
lines.push("These candidate patterns keep recurring. They are not yet in the worldmodel.");
|
|
468
|
+
lines.push("If they represent real behavioral patterns worth tracking, add them.");
|
|
469
|
+
lines.push("If they were temporary, dismiss them.");
|
|
470
|
+
lines.push("");
|
|
471
|
+
for (const p of addCandidates) {
|
|
472
|
+
lines.push(
|
|
473
|
+
`- **${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).`
|
|
474
|
+
);
|
|
475
|
+
}
|
|
476
|
+
lines.push("");
|
|
477
|
+
}
|
|
478
|
+
if (options?.declaredItems && options.declaredItems.length > 0) {
|
|
479
|
+
const triggered = new Set(options.triggeredItems ?? []);
|
|
480
|
+
const removeCandidates = [];
|
|
481
|
+
for (const item of options.declaredItems) {
|
|
482
|
+
if (!triggered.has(item.name)) {
|
|
483
|
+
const prior = existingUntriggered.get(item.name) ?? 0;
|
|
484
|
+
const count = prior + 1;
|
|
485
|
+
existingUntriggered.set(item.name, count);
|
|
486
|
+
if (count >= 4) {
|
|
487
|
+
removeCandidates.push({ item, weeksSilent: count });
|
|
488
|
+
}
|
|
489
|
+
} else {
|
|
490
|
+
existingUntriggered.set(item.name, 0);
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
if (removeCandidates.length > 0) {
|
|
494
|
+
lines.push("### Consider removing");
|
|
495
|
+
lines.push("");
|
|
496
|
+
lines.push("These items are declared in the worldmodel but haven't triggered in multiple reads.");
|
|
497
|
+
lines.push("Either the team has internalized them (the rule is redundant) or they haven't been tested.");
|
|
498
|
+
lines.push("A lean worldmodel with 5 sharp invariants is stronger than a bloated one with 20.");
|
|
499
|
+
lines.push("");
|
|
500
|
+
for (const { item, weeksSilent } of removeCandidates) {
|
|
501
|
+
lines.push(
|
|
502
|
+
`- **${item.name}** (${item.type}) \u2014 hasn't triggered in ${weeksSilent} reads. Internalized or untested? Review whether it still earns its place.`
|
|
503
|
+
);
|
|
504
|
+
}
|
|
505
|
+
lines.push("");
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
if (options?.triggeredItems && options.triggeredItems.length > 0) {
|
|
509
|
+
lines.push("### Keep (recently active)");
|
|
510
|
+
lines.push("");
|
|
511
|
+
lines.push("These worldmodel items triggered governance in the most recent read. They're earning their place.");
|
|
512
|
+
lines.push("");
|
|
513
|
+
for (const name of options.triggeredItems) {
|
|
514
|
+
lines.push(`- **${name}** \u2014 triggered this read. Holding.`);
|
|
515
|
+
}
|
|
516
|
+
lines.push("");
|
|
517
|
+
}
|
|
518
|
+
lines.push("---");
|
|
519
|
+
lines.push("");
|
|
520
|
+
lines.push("## Pattern persistence (all observed)");
|
|
521
|
+
lines.push("");
|
|
522
|
+
for (const p of persistence) {
|
|
523
|
+
const status = p.occurrences >= 4 ? "**persistent**" : p.occurrences >= 2 ? "recurring" : "observed once";
|
|
524
|
+
lines.push(`### ${p.name}`);
|
|
525
|
+
lines.push(`- Status: ${status}`);
|
|
526
|
+
lines.push(`- Observed ${p.occurrences} time${p.occurrences > 1 ? "s" : ""}: ${p.dates.join(", ")}`);
|
|
527
|
+
lines.push("");
|
|
528
|
+
}
|
|
529
|
+
lines.push("---");
|
|
530
|
+
lines.push("");
|
|
531
|
+
lines.push("<!-- untriggered_counts (machine-readable, do not edit)");
|
|
532
|
+
for (const [name, count] of existingUntriggered.entries()) {
|
|
533
|
+
lines.push(`${name}=${count}`);
|
|
534
|
+
}
|
|
535
|
+
lines.push("-->");
|
|
536
|
+
writeFileSync(filepath, lines.join("\n"), "utf-8");
|
|
537
|
+
return filepath;
|
|
538
|
+
}
|
|
539
|
+
function loadUntriggeredCounts(filepath) {
|
|
540
|
+
const counts = /* @__PURE__ */ new Map();
|
|
541
|
+
if (!existsSync2(filepath)) return counts;
|
|
542
|
+
try {
|
|
543
|
+
const content = readFileSync2(filepath, "utf-8");
|
|
544
|
+
const match = content.match(
|
|
545
|
+
/<!-- untriggered_counts[\s\S]*?-->/
|
|
546
|
+
);
|
|
547
|
+
if (match) {
|
|
548
|
+
const lines = match[0].split("\n");
|
|
549
|
+
for (const line of lines) {
|
|
550
|
+
const eq = line.match(/^([^=]+)=(\d+)$/);
|
|
551
|
+
if (eq) {
|
|
552
|
+
counts.set(eq[1], parseInt(eq[2], 10));
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
} catch {
|
|
557
|
+
}
|
|
558
|
+
return counts;
|
|
559
|
+
}
|
|
560
|
+
function loadPriorReads(exocortexDir) {
|
|
561
|
+
const dir = resolve2(exocortexDir, "radiant", "reads");
|
|
562
|
+
if (!existsSync2(dir)) return [];
|
|
563
|
+
const files = readdirSync(dir).filter((f) => f.endsWith(".md")).sort();
|
|
564
|
+
const reads = [];
|
|
565
|
+
for (const filename of files) {
|
|
566
|
+
const filepath = join2(dir, filename);
|
|
567
|
+
const content = readFileSync2(filepath, "utf-8");
|
|
568
|
+
const date = filename.replace(".md", "");
|
|
569
|
+
const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
570
|
+
const frontmatter = fmMatch ? fmMatch[1] : "";
|
|
571
|
+
const patternNames = [];
|
|
572
|
+
const nameMatches = frontmatter.matchAll(/- name: ["']?([^"'\n]+)["']?/g);
|
|
573
|
+
for (const m of nameMatches) {
|
|
574
|
+
patternNames.push(m[1].trim());
|
|
575
|
+
}
|
|
576
|
+
reads.push({ date, filename, patternNames, frontmatter });
|
|
577
|
+
}
|
|
578
|
+
return reads;
|
|
579
|
+
}
|
|
580
|
+
function computePersistence(priorReads, currentPatternNames) {
|
|
581
|
+
const allPatterns = /* @__PURE__ */ new Map();
|
|
582
|
+
for (const read of priorReads) {
|
|
583
|
+
for (const name of read.patternNames) {
|
|
584
|
+
const dates = allPatterns.get(name) ?? [];
|
|
585
|
+
if (!dates.includes(read.date)) dates.push(read.date);
|
|
586
|
+
allPatterns.set(name, dates);
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
590
|
+
for (const name of currentPatternNames) {
|
|
591
|
+
const dates = allPatterns.get(name) ?? [];
|
|
592
|
+
if (!dates.includes(today)) dates.push(today);
|
|
593
|
+
allPatterns.set(name, dates);
|
|
594
|
+
}
|
|
595
|
+
return Array.from(allPatterns.entries()).map(([name, dates]) => ({
|
|
596
|
+
name,
|
|
597
|
+
occurrences: dates.length,
|
|
598
|
+
dates: dates.sort()
|
|
599
|
+
})).sort((a, b) => b.occurrences - a.occurrences);
|
|
600
|
+
}
|
|
601
|
+
function formatPriorReadsForPrompt(priorReads) {
|
|
602
|
+
if (priorReads.length === 0) return "";
|
|
603
|
+
const lines = [
|
|
604
|
+
"## Prior Radiant reads (history)",
|
|
605
|
+
"",
|
|
606
|
+
`Radiant has run ${priorReads.length} time${priorReads.length > 1 ? "s" : ""} before on this scope.`,
|
|
607
|
+
"If you see patterns that appeared in prior reads, note their persistence.",
|
|
608
|
+
"Patterns that recur across 3+ reads are strong candidates for declaration in the strategy file.",
|
|
609
|
+
""
|
|
610
|
+
];
|
|
611
|
+
for (const read of priorReads.slice(-4)) {
|
|
612
|
+
lines.push(`### Read from ${read.date}`);
|
|
613
|
+
if (read.patternNames.length > 0) {
|
|
614
|
+
lines.push(`Patterns observed: ${read.patternNames.join(", ")}`);
|
|
615
|
+
} else {
|
|
616
|
+
lines.push("No patterns extracted from frontmatter.");
|
|
617
|
+
}
|
|
618
|
+
lines.push("");
|
|
619
|
+
}
|
|
620
|
+
return lines.join("\n");
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
// src/radiant/core/governance.ts
|
|
624
|
+
async function auditGovernance(events, worldPath) {
|
|
625
|
+
let world;
|
|
626
|
+
try {
|
|
627
|
+
world = await loadWorld(worldPath);
|
|
628
|
+
} catch {
|
|
629
|
+
return emptyAudit(events.length, "Could not load compiled worldmodel for governance audit.");
|
|
630
|
+
}
|
|
631
|
+
const verdicts = [];
|
|
632
|
+
for (const ce of events) {
|
|
633
|
+
const intent = ce.event.content?.slice(0, 500) || ce.event.kind || "activity";
|
|
634
|
+
const scope = ce.event.metadata?.scope || void 0;
|
|
635
|
+
try {
|
|
636
|
+
const result = evaluateGuard(
|
|
637
|
+
{
|
|
638
|
+
intent,
|
|
639
|
+
scope,
|
|
640
|
+
actionCategory: mapKindToCategory(ce.event.kind)
|
|
641
|
+
},
|
|
642
|
+
world
|
|
643
|
+
);
|
|
644
|
+
verdicts.push({
|
|
645
|
+
eventId: ce.event.id,
|
|
646
|
+
domain: ce.domain,
|
|
647
|
+
status: result.status,
|
|
648
|
+
reason: result.reason,
|
|
649
|
+
ruleId: result.ruleId,
|
|
650
|
+
warning: result.warning
|
|
651
|
+
});
|
|
652
|
+
} catch {
|
|
653
|
+
verdicts.push({
|
|
654
|
+
eventId: ce.event.id,
|
|
655
|
+
domain: ce.domain,
|
|
656
|
+
status: "ALLOW",
|
|
657
|
+
reason: "guard evaluation skipped (error)"
|
|
658
|
+
});
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
const human = bucketVerdicts(verdicts.filter((v) => v.domain === "life"));
|
|
662
|
+
const cyber = bucketVerdicts(verdicts.filter((v) => v.domain === "cyber"));
|
|
663
|
+
const joint = bucketVerdicts(verdicts.filter((v) => v.domain === "joint"));
|
|
664
|
+
const summary = buildSummary(human, cyber, joint, events.length);
|
|
665
|
+
return {
|
|
666
|
+
totalEvents: events.length,
|
|
667
|
+
human,
|
|
668
|
+
cyber,
|
|
669
|
+
joint,
|
|
670
|
+
summary
|
|
671
|
+
};
|
|
672
|
+
}
|
|
673
|
+
function bucketVerdicts(verdicts) {
|
|
674
|
+
const nonAllow = verdicts.filter((v) => v.status !== "ALLOW");
|
|
675
|
+
return {
|
|
676
|
+
allow: verdicts.filter((v) => v.status === "ALLOW").length,
|
|
677
|
+
modify: verdicts.filter((v) => v.status === "MODIFY").length,
|
|
678
|
+
block: verdicts.filter((v) => v.status === "BLOCK").length,
|
|
679
|
+
details: nonAllow
|
|
680
|
+
};
|
|
681
|
+
}
|
|
682
|
+
function buildSummary(human, cyber, joint, total) {
|
|
683
|
+
const humanTriggered = human.modify + human.block;
|
|
684
|
+
const cyberTriggered = cyber.modify + cyber.block;
|
|
685
|
+
const jointTriggered = joint.modify + joint.block;
|
|
686
|
+
const totalTriggered = humanTriggered + cyberTriggered + jointTriggered;
|
|
687
|
+
if (totalTriggered === 0) {
|
|
688
|
+
return `${total} events evaluated. All passed. The cocoon held \u2014 no governance triggered.`;
|
|
689
|
+
}
|
|
690
|
+
const parts = [];
|
|
691
|
+
parts.push(`${total} events evaluated. ${totalTriggered} triggered governance.`);
|
|
692
|
+
if (humanTriggered > 0) {
|
|
693
|
+
parts.push(`Human side: ${humanTriggered} (${human.block} blocked, ${human.modify} modified).`);
|
|
694
|
+
}
|
|
695
|
+
if (cyberTriggered > 0) {
|
|
696
|
+
parts.push(`AI side: ${cyberTriggered} (${cyber.block} blocked, ${cyber.modify} modified).`);
|
|
697
|
+
}
|
|
698
|
+
if (jointTriggered > 0) {
|
|
699
|
+
parts.push(`Joint work: ${jointTriggered} (${joint.block} blocked, ${joint.modify} modified).`);
|
|
700
|
+
}
|
|
701
|
+
if (humanTriggered > 0 && cyberTriggered > 0) {
|
|
702
|
+
const ratio = humanTriggered / cyberTriggered;
|
|
703
|
+
if (ratio > 2) {
|
|
704
|
+
parts.push("Human side is testing the frame more than AI. Either the worldmodel needs calibrating for human workflows, or humans are genuinely drifting.");
|
|
705
|
+
} else if (ratio < 0.5) {
|
|
706
|
+
parts.push("AI side is testing the frame more than humans. Check whether the AI's output patterns match the declared invariants.");
|
|
707
|
+
} else {
|
|
708
|
+
parts.push("Roughly balanced between human and AI \u2014 both sides are testing the frame.");
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
return parts.join(" ");
|
|
712
|
+
}
|
|
713
|
+
function mapKindToCategory(kind) {
|
|
714
|
+
if (!kind) return "other";
|
|
715
|
+
if (kind.includes("commit") || kind.includes("merge")) return "write";
|
|
716
|
+
if (kind.includes("review") || kind.includes("comment")) return "read";
|
|
717
|
+
return "other";
|
|
718
|
+
}
|
|
719
|
+
function emptyAudit(total, reason) {
|
|
720
|
+
return {
|
|
721
|
+
totalEvents: total,
|
|
722
|
+
human: { allow: 0, modify: 0, block: 0, details: [] },
|
|
723
|
+
cyber: { allow: 0, modify: 0, block: 0, details: [] },
|
|
724
|
+
joint: { allow: 0, modify: 0, block: 0, details: [] },
|
|
725
|
+
summary: reason
|
|
726
|
+
};
|
|
727
|
+
}
|
|
728
|
+
|
|
424
729
|
// src/radiant/core/domain.ts
|
|
425
730
|
function isLifeSide(k) {
|
|
426
731
|
return k === "human" || k === "unknown";
|
|
@@ -718,7 +1023,7 @@ Only recommend a move when the evidence actually calls for one.
|
|
|
718
1023
|
}
|
|
719
1024
|
],
|
|
720
1025
|
"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.
|
|
1026
|
+
"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
1027
|
}
|
|
723
1028
|
\`\`\`
|
|
724
1029
|
|
|
@@ -874,6 +1179,27 @@ Lens: ${input.lens.name}`
|
|
|
874
1179
|
` Composite: ${formatScore(input.scores.R)}`
|
|
875
1180
|
].join("\n");
|
|
876
1181
|
sections.push(alignBlock);
|
|
1182
|
+
if (input.governance && input.governance.totalEvents > 0) {
|
|
1183
|
+
const gov = input.governance;
|
|
1184
|
+
const govLines = ["GOVERNANCE", "", ` ${gov.summary}`];
|
|
1185
|
+
const showSide = (label, side) => {
|
|
1186
|
+
if (side.allow + side.modify + side.block === 0) return;
|
|
1187
|
+
govLines.push("");
|
|
1188
|
+
govLines.push(` ${label}:`);
|
|
1189
|
+
govLines.push(` ${side.allow} ALLOW \xB7 ${side.modify} MODIFY \xB7 ${side.block} BLOCK`);
|
|
1190
|
+
for (const d of side.details.slice(0, 3)) {
|
|
1191
|
+
const reason = d.reason ? ` \u2192 ${d.reason}` : "";
|
|
1192
|
+
govLines.push(` ${d.status}: ${d.eventId}${reason}`);
|
|
1193
|
+
}
|
|
1194
|
+
if (side.details.length > 3) {
|
|
1195
|
+
govLines.push(` ... and ${side.details.length - 3} more`);
|
|
1196
|
+
}
|
|
1197
|
+
};
|
|
1198
|
+
showSide("Human side", gov.human);
|
|
1199
|
+
showSide("AI side", gov.cyber);
|
|
1200
|
+
showSide("Human\u2013AI joint", gov.joint);
|
|
1201
|
+
sections.push(govLines.join("\n"));
|
|
1202
|
+
}
|
|
877
1203
|
sections.push(renderDepth(input.priorReadCount ?? 0, input.windowDays));
|
|
878
1204
|
return sections.join("\n\n");
|
|
879
1205
|
}
|
|
@@ -1043,10 +1369,15 @@ async function emergent(input) {
|
|
|
1043
1369
|
const windowDays = input.windowDays ?? 14;
|
|
1044
1370
|
let statedIntent;
|
|
1045
1371
|
let exocortexContext;
|
|
1372
|
+
let priorReadContext = "";
|
|
1046
1373
|
if (input.exocortexPath) {
|
|
1047
1374
|
exocortexContext = readExocortex(input.exocortexPath);
|
|
1048
1375
|
const formatted = formatExocortexForPrompt(exocortexContext);
|
|
1049
1376
|
if (formatted) statedIntent = formatted;
|
|
1377
|
+
const priorReads = loadPriorReads(input.exocortexPath);
|
|
1378
|
+
if (priorReads.length > 0) {
|
|
1379
|
+
priorReadContext = formatPriorReadsForPrompt(priorReads);
|
|
1380
|
+
}
|
|
1050
1381
|
}
|
|
1051
1382
|
const events = await fetchGitHubActivity(input.scope, input.githubToken, {
|
|
1052
1383
|
windowDays
|
|
@@ -1061,11 +1392,18 @@ async function emergent(input) {
|
|
|
1061
1392
|
lens,
|
|
1062
1393
|
ai: input.ai,
|
|
1063
1394
|
canonicalPatterns: input.canonicalPatterns,
|
|
1064
|
-
statedIntent
|
|
1395
|
+
statedIntent: statedIntent ? statedIntent + (priorReadContext ? "\n\n" + priorReadContext : "") : priorReadContext || void 0
|
|
1065
1396
|
});
|
|
1066
1397
|
const rewrittenPatterns = patterns.map((p) => lens.rewrite(p));
|
|
1067
1398
|
const allDescriptions = rewrittenPatterns.map((p) => p.description).join("\n");
|
|
1068
1399
|
const voiceViolations = checkForbiddenPhrases(lens, allDescriptions);
|
|
1400
|
+
let governance;
|
|
1401
|
+
if (input.worldPath) {
|
|
1402
|
+
try {
|
|
1403
|
+
governance = await auditGovernance(classified, input.worldPath);
|
|
1404
|
+
} catch {
|
|
1405
|
+
}
|
|
1406
|
+
}
|
|
1069
1407
|
const rendered = render({
|
|
1070
1408
|
scope: input.scope,
|
|
1071
1409
|
windowDays,
|
|
@@ -1075,8 +1413,27 @@ async function emergent(input) {
|
|
|
1075
1413
|
scores,
|
|
1076
1414
|
lens,
|
|
1077
1415
|
meaning: meaning || void 0,
|
|
1078
|
-
move: move || void 0
|
|
1416
|
+
move: move || void 0,
|
|
1417
|
+
governance
|
|
1079
1418
|
});
|
|
1419
|
+
if (input.exocortexPath) {
|
|
1420
|
+
try {
|
|
1421
|
+
const readPath = writeRead(input.exocortexPath, rendered.frontmatter, rendered.text);
|
|
1422
|
+
const priorReads = loadPriorReads(input.exocortexPath);
|
|
1423
|
+
const currentPatternNames = rewrittenPatterns.map((p) => p.name);
|
|
1424
|
+
const persistence = computePersistence(priorReads, currentPatternNames);
|
|
1425
|
+
const triggeredItems = governance ? [
|
|
1426
|
+
...governance.human.details.map((d) => d.ruleId).filter(Boolean),
|
|
1427
|
+
...governance.cyber.details.map((d) => d.ruleId).filter(Boolean),
|
|
1428
|
+
...governance.joint.details.map((d) => d.ruleId).filter(Boolean)
|
|
1429
|
+
] : [];
|
|
1430
|
+
updateKnowledge(input.exocortexPath, persistence, {
|
|
1431
|
+
triggeredItems,
|
|
1432
|
+
totalReads: priorReads.length + 1
|
|
1433
|
+
});
|
|
1434
|
+
} catch {
|
|
1435
|
+
}
|
|
1436
|
+
}
|
|
1080
1437
|
return {
|
|
1081
1438
|
text: rendered.text,
|
|
1082
1439
|
frontmatter: rendered.frontmatter,
|
|
@@ -1187,6 +1544,12 @@ export {
|
|
|
1187
1544
|
readExocortex,
|
|
1188
1545
|
formatExocortexForPrompt,
|
|
1189
1546
|
summarizeExocortex,
|
|
1547
|
+
writeRead,
|
|
1548
|
+
updateKnowledge,
|
|
1549
|
+
loadPriorReads,
|
|
1550
|
+
computePersistence,
|
|
1551
|
+
formatPriorReadsForPrompt,
|
|
1552
|
+
auditGovernance,
|
|
1190
1553
|
classifyActorDomain,
|
|
1191
1554
|
classifyEvents,
|
|
1192
1555
|
extractSignals,
|