@neuroverseos/governance 0.9.0 → 0.10.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.
@@ -20,6 +20,49 @@
20
20
  * RADIANT_WORLDS — default worlds directory (overridden by --worlds)
21
21
  * RADIANT_LENS — default lens id (overridden by --lens)
22
22
  */
23
+ interface ParsedArgs {
24
+ subcommand: string | undefined;
25
+ lens: string | undefined;
26
+ worlds: string | undefined;
27
+ query: string | undefined;
28
+ model: string | undefined;
29
+ exocortex: string | undefined;
30
+ teamExocortex: string | undefined;
31
+ view: string | undefined;
32
+ user: string | undefined;
33
+ personal: boolean;
34
+ entireOrg: boolean;
35
+ json: boolean;
36
+ help: boolean;
37
+ force: boolean;
38
+ rest: string[];
39
+ }
40
+ declare function parseArgs(argv: string[]): ParsedArgs;
41
+ interface ScopeConsentInput {
42
+ scope: {
43
+ type: 'org' | 'repo';
44
+ owner: string;
45
+ };
46
+ personal: boolean;
47
+ entireOrg: boolean;
48
+ resolvedUser: string | undefined;
49
+ }
50
+ type ScopeConsentResult = {
51
+ ok: true;
52
+ } | {
53
+ ok: false;
54
+ reason: 'personal_requires_user' | 'org_requires_opt_in';
55
+ };
56
+ /**
57
+ * Consent-first gate. Org-wide scopes observe every contributor across
58
+ * every repo — a global-observer stance that's opt-in, not the default.
59
+ * Personal mode requires a user to filter to.
60
+ *
61
+ * personal without user → reject (need --user or RADIANT_USER)
62
+ * org scope without --entire-org and without --personal → reject
63
+ * everything else → pass
64
+ */
65
+ declare function checkScopeConsent(input: ScopeConsentInput): ScopeConsentResult;
23
66
  declare function main(argv: string[]): Promise<void>;
24
67
 
25
- export { main };
68
+ export { type ScopeConsentInput, type ScopeConsentResult, checkScopeConsent, main, parseArgs };
@@ -20,6 +20,49 @@
20
20
  * RADIANT_WORLDS — default worlds directory (overridden by --worlds)
21
21
  * RADIANT_LENS — default lens id (overridden by --lens)
22
22
  */
23
+ interface ParsedArgs {
24
+ subcommand: string | undefined;
25
+ lens: string | undefined;
26
+ worlds: string | undefined;
27
+ query: string | undefined;
28
+ model: string | undefined;
29
+ exocortex: string | undefined;
30
+ teamExocortex: string | undefined;
31
+ view: string | undefined;
32
+ user: string | undefined;
33
+ personal: boolean;
34
+ entireOrg: boolean;
35
+ json: boolean;
36
+ help: boolean;
37
+ force: boolean;
38
+ rest: string[];
39
+ }
40
+ declare function parseArgs(argv: string[]): ParsedArgs;
41
+ interface ScopeConsentInput {
42
+ scope: {
43
+ type: 'org' | 'repo';
44
+ owner: string;
45
+ };
46
+ personal: boolean;
47
+ entireOrg: boolean;
48
+ resolvedUser: string | undefined;
49
+ }
50
+ type ScopeConsentResult = {
51
+ ok: true;
52
+ } | {
53
+ ok: false;
54
+ reason: 'personal_requires_user' | 'org_requires_opt_in';
55
+ };
56
+ /**
57
+ * Consent-first gate. Org-wide scopes observe every contributor across
58
+ * every repo — a global-observer stance that's opt-in, not the default.
59
+ * Personal mode requires a user to filter to.
60
+ *
61
+ * personal without user → reject (need --user or RADIANT_USER)
62
+ * org scope without --entire-org and without --personal → reject
63
+ * everything else → pass
64
+ */
65
+ declare function checkScopeConsent(input: ScopeConsentInput): ScopeConsentResult;
23
66
  declare function main(argv: string[]): Promise<void>;
24
67
 
25
- export { main };
68
+ export { type ScopeConsentInput, type ScopeConsentResult, checkScopeConsent, main, parseArgs };
@@ -7,7 +7,7 @@ import {
7
7
  readExocortex,
8
8
  summarizeExocortex,
9
9
  think
10
- } from "../chunk-3ZWU7C43.js";
10
+ } from "../chunk-BZYQHJDM.js";
11
11
  import {
12
12
  listLenses
13
13
  } from "../chunk-TCGGED4G.js";
@@ -17,9 +17,10 @@ import "../chunk-QLPTHTVB.js";
17
17
  import "../chunk-QWGCMQQD.js";
18
18
 
19
19
  // src/cli/radiant.ts
20
- import { readFileSync, readdirSync, statSync, existsSync } from "fs";
20
+ import { readFileSync, readdirSync, statSync, existsSync, mkdirSync, writeFileSync } from "fs";
21
21
  import { resolve, join, extname } from "path";
22
22
  var RED = "\x1B[31m";
23
+ var GREEN = "\x1B[32m";
23
24
  var DIM = "\x1B[2m";
24
25
  var BOLD = "\x1B[1m";
25
26
  var YELLOW = "\x1B[33m";
@@ -27,6 +28,9 @@ var RESET = "\x1B[0m";
27
28
  var USAGE = `
28
29
  ${BOLD}neuroverse radiant${RESET} \u2014 behavioral intelligence for collaboration systems
29
30
 
31
+ ${BOLD}Setup:${RESET}
32
+ init Scaffold a Mind Palace in the current directory
33
+
30
34
  ${BOLD}Stage A (voice layer):${RESET}
31
35
  think Send a query through the worldmodel + lens \u2192 AI-framed response
32
36
 
@@ -37,13 +41,27 @@ ${BOLD}Stage B (behavioral analysis, coming soon):${RESET}
37
41
  lenses List or describe available rendering lenses
38
42
 
39
43
  ${BOLD}Usage:${RESET}
44
+ neuroverse radiant init (scaffolds ./mind-palace/)
45
+ neuroverse radiant init ./my-palace (custom path)
40
46
  neuroverse radiant think --lens auki-builder --worlds ./worlds/ --query "What is our biggest risk?"
41
47
  neuroverse radiant think --lens auki-builder --worlds ./worlds/ < prompt.txt
42
48
  neuroverse radiant emergent aukiverse/posemesh --lens auki-builder --worlds ./worlds/
43
49
  neuroverse radiant emergent aukiverse/posemesh --lens auki-builder --worlds ./worlds/ --exocortex ~/exocortex/
50
+ neuroverse radiant emergent aukilabs/posemesh --personal --user alice
51
+ neuroverse radiant emergent aukilabs/ --entire-org --lens auki-builder --worlds ./worlds/
44
52
  neuroverse radiant lenses list
45
53
  neuroverse radiant lenses describe auki-builder
46
54
 
55
+ ${BOLD}Read modes:${RESET}
56
+ ${BOLD}Default (team):${RESET} reads all contributors in the given scope.
57
+ ${BOLD}--personal --user <login>:${RESET} reads ONLY that user's activity.
58
+ A local, private facilitator \u2014 no one else is observed. Works against
59
+ any scope; an org scope with --personal is fine.
60
+ ${BOLD}--entire-org (gated):${RESET} org-wide scope observes every contributor
61
+ across every repo. This is a global-observer stance and is opt-in.
62
+ \`radiant emergent <org>/\` without --entire-org will refuse and show
63
+ you the three choices (single repo, --personal, or explicit opt-in).
64
+
47
65
  ${BOLD}Auto-discovery:${RESET}
48
66
  You do not need to clone the target repo.
49
67
 
@@ -62,6 +80,7 @@ ${BOLD}Environment:${RESET}
62
80
  RADIANT_LENS Default lens id (overridden by --lens)
63
81
  RADIANT_MODEL AI model override (default: claude-sonnet-4-20250514)
64
82
  RADIANT_EXOCORTEX Default exocortex directory (overridden by --exocortex)
83
+ RADIANT_USER Default personal-mode user (overridden by --user)
65
84
  `.trim();
66
85
  function parseArgs(argv) {
67
86
  const result = {
@@ -73,8 +92,12 @@ function parseArgs(argv) {
73
92
  exocortex: void 0,
74
93
  teamExocortex: void 0,
75
94
  view: void 0,
95
+ user: void 0,
96
+ personal: false,
97
+ entireOrg: false,
76
98
  json: false,
77
99
  help: false,
100
+ force: false,
78
101
  rest: []
79
102
  };
80
103
  let i = 0;
@@ -106,9 +129,22 @@ function parseArgs(argv) {
106
129
  case "--view":
107
130
  result.view = argv[++i];
108
131
  break;
132
+ case "--user":
133
+ result.user = argv[++i];
134
+ break;
135
+ case "--personal":
136
+ result.personal = true;
137
+ break;
138
+ case "--entire-org":
139
+ result.entireOrg = true;
140
+ break;
109
141
  case "--json":
110
142
  result.json = true;
111
143
  break;
144
+ case "--force":
145
+ case "-f":
146
+ result.force = true;
147
+ break;
112
148
  case "--help":
113
149
  case "-h":
114
150
  result.help = true;
@@ -266,6 +302,15 @@ ${DIM}Model: ${model ?? "claude-sonnet-4-20250514 (default)"}${RESET}
266
302
  process.exit(2);
267
303
  }
268
304
  }
305
+ function checkScopeConsent(input) {
306
+ if (input.personal && !input.resolvedUser) {
307
+ return { ok: false, reason: "personal_requires_user" };
308
+ }
309
+ if (input.scope.type === "org" && !input.entireOrg && !input.personal) {
310
+ return { ok: false, reason: "org_requires_opt_in" };
311
+ }
312
+ return { ok: true };
313
+ }
269
314
  async function cmdEmergent(args) {
270
315
  const scopeStr = args.rest[0];
271
316
  if (!scopeStr) {
@@ -276,6 +321,43 @@ async function cmdEmergent(args) {
276
321
  process.exit(1);
277
322
  }
278
323
  const scope = parseScope(scopeStr);
324
+ const personalUser = args.user ?? process.env.RADIANT_USER;
325
+ const consent = checkScopeConsent({
326
+ scope,
327
+ personal: args.personal,
328
+ entireOrg: args.entireOrg,
329
+ resolvedUser: personalUser
330
+ });
331
+ if (!consent.ok) {
332
+ if (consent.reason === "personal_requires_user") {
333
+ process.stderr.write(
334
+ `${RED}Error:${RESET} --personal requires a GitHub username.
335
+ ${DIM}Pass --user <login> or set RADIANT_USER. Radiant will read
336
+ only that user's activity \u2014 no one else is observed.${RESET}
337
+ `
338
+ );
339
+ } else {
340
+ process.stderr.write(
341
+ `${YELLOW}\u26A0${RESET} ${BOLD}"${scope.owner}" is an org-wide scope.${RESET}
342
+
343
+ ${DIM}This reads activity across ALL repos in the org \u2014 a global-observer
344
+ pattern that some teams consider offside with decentralization and
345
+ cognitive-liberty principles. It's opt-in for that reason.${RESET}
346
+
347
+ Three ways forward:
348
+ ${GREEN}1.${RESET} Scope to a single repo (recommended default):
349
+ radiant emergent ${scope.owner}/<repo>
350
+
351
+ ${GREEN}2.${RESET} Read only your own activity (personal mode):
352
+ radiant emergent ${scope.owner}/ --personal --user <your-login>
353
+
354
+ ${GREEN}3.${RESET} Explicitly opt in to org-wide observation:
355
+ radiant emergent ${scope.owner}/ --entire-org
356
+ `
357
+ );
358
+ }
359
+ process.exit(1);
360
+ }
279
361
  const lensId = args.lens ?? process.env.RADIANT_LENS;
280
362
  if (!lensId) {
281
363
  process.stderr.write(
@@ -324,8 +406,11 @@ ${DIM}Set it to a GitHub PAT with repo read access.${RESET}
324
406
  const ctx = readExocortex(exocortexPath);
325
407
  exocortexStatus = summarizeExocortex(ctx);
326
408
  }
409
+ const scopeLabel = scope.type === "org" ? scope.owner + " (entire org)" : scope.owner + "/" + scope.repo;
410
+ const modeLabel = args.personal ? `personal \u2014 only ${personalUser}'s activity` : "team \u2014 all contributors";
327
411
  process.stderr.write(
328
- `${DIM}Scope: ${scope.type === "org" ? scope.owner + " (entire org)" : scope.owner + "/" + scope.repo}${RESET}
412
+ `${DIM}Scope: ${scopeLabel}${RESET}
413
+ ${DIM}Mode: ${modeLabel}${RESET}
329
414
  ${DIM}View: ${view}${RESET}
330
415
  ${DIM}Lens: ${lensId}${RESET}
331
416
  ${DIM}Model: ${model ?? "claude-sonnet-4-20250514 (default)"}${RESET}
@@ -341,7 +426,8 @@ ${DIM}Fetching activity...${RESET}
341
426
  lensId,
342
427
  ai,
343
428
  windowDays: 14,
344
- exocortexPath: exocortexPath || void 0
429
+ exocortexPath: exocortexPath || void 0,
430
+ personalUser: args.personal ? personalUser : void 0
345
431
  });
346
432
  if (!result.voiceClean) {
347
433
  process.stderr.write(
@@ -443,6 +529,204 @@ ${DIM}Use: lenses list | lenses describe <id>${RESET}
443
529
  );
444
530
  process.exit(1);
445
531
  }
532
+ var MIND_PALACE_FILES = {
533
+ "README.md": `# Mind Palace
534
+
535
+ This is your Mind Palace \u2014 structured external memory that gives Radiant
536
+ (and any agent you wire into it) persistent context about who you are,
537
+ what you're working on, and what "on track" means for you.
538
+
539
+ Radiant reads these files before every run and writes each read back into
540
+ \`reads/\`. Over time, \`knowledge.md\` accumulates what's persisted and what
541
+ hasn't \u2014 the feedback loop that turns raw activity into named behavior.
542
+
543
+ ## Files
544
+
545
+ - \`attention.md\` \u2014 what you're focused on **right now**
546
+ - \`goals.md\` \u2014 what you're working toward
547
+ - \`sprint.md\` \u2014 this week's focus
548
+ - \`identity.md\` \u2014 who you are, what you value
549
+ - \`worldmodels/\` \u2014 your thinking constitutions (drift + aligned behaviors)
550
+ - \`reads/\` \u2014 dated Radiant reads (written by \`radiant emergent\`)
551
+ - \`knowledge.md\` \u2014 accumulated pattern persistence across reads
552
+
553
+ ## How to use
554
+
555
+ 1. Fill in \`attention.md\`, \`goals.md\`, \`sprint.md\`, \`identity.md\` with
556
+ your own words. A sentence each is enough to start \u2014 the files grow
557
+ with you.
558
+ 2. Edit \`worldmodels/starter.worldmodel.md\`: add a few aligned behaviors
559
+ (what on-track looks like) and drift behaviors (what off-track looks
560
+ like). The sharper these are, the sharper Radiant's reads.
561
+ 3. Run \`neuroverse radiant emergent <owner/repo> --mind-palace .\` against
562
+ the repo you want read. Radiant compares your stated intent (these
563
+ files) to your observed activity (GitHub) and names the gap.
564
+
565
+ Edit freely. These files are yours.
566
+ `,
567
+ "attention.md": `# Attention
568
+
569
+ <!--
570
+ What are you focused on RIGHT NOW? One paragraph. Updated as you shift.
571
+ This is the file an AI agent reads at the start of a session to know
572
+ what to help with today.
573
+ -->
574
+
575
+ `,
576
+ "goals.md": `# Goals
577
+
578
+ <!--
579
+ What are you working toward? Bullet points welcome.
580
+ Longer horizon than attention \u2014 months, not days.
581
+ -->
582
+
583
+ -
584
+ `,
585
+ "sprint.md": `# Sprint
586
+
587
+ <!--
588
+ This week's focus. What do you want to ship or finish?
589
+ Keep it short \u2014 five bullets max.
590
+ -->
591
+
592
+ -
593
+ `,
594
+ "identity.md": `# Identity
595
+
596
+ <!--
597
+ Who are you, what do you value, how do you work?
598
+ This is the context an agent needs to not treat you like a stranger
599
+ every time. Write it in your own voice.
600
+ -->
601
+
602
+ `,
603
+ "knowledge.md": `# Knowledge
604
+
605
+ <!--
606
+ Radiant writes accumulated pattern persistence here across reads.
607
+ Leave this file empty on day one \u2014 it fills up as \`radiant emergent\`
608
+ runs accumulate.
609
+ -->
610
+
611
+ `,
612
+ "reads/.gitkeep": "",
613
+ "worldmodels/starter.worldmodel.md": `# Starter Worldmodel
614
+
615
+ <!--
616
+ Your thinking constitution. Radiant reads this to understand what
617
+ "aligned" and "drift" mean for your work.
618
+
619
+ The sharper the Aligned/Drift Behaviors, the sharper Radiant's reads.
620
+ When Radiant detects something matching a drift behavior below, it
621
+ labels it with THAT name \u2014 it doesn't invent new ones.
622
+ -->
623
+
624
+ ## Mission
625
+
626
+ <!-- One sentence. What are you doing in the world? -->
627
+
628
+
629
+ ## Invariants
630
+
631
+ <!--
632
+ Non-negotiable rules. If a decision violates one, it's blocked.
633
+ Keep this list short \u2014 3 to 6 items. Each should be a hard no.
634
+ -->
635
+
636
+ -
637
+
638
+ ## Aligned Behaviors
639
+
640
+ <!--
641
+ What "on track" looks like. One per line, phrased as a behavior.
642
+ Radiant will use these as canonical pattern names when it sees
643
+ matching evidence in your activity.
644
+
645
+ Example:
646
+ - ships partial-but-working features rather than waiting for the full stack
647
+ - writes decisions down before acting on them
648
+ -->
649
+
650
+ -
651
+
652
+ ## Drift Behaviors
653
+
654
+ <!--
655
+ What "off track" looks like. Same format as Aligned.
656
+ When Radiant detects drift, it will label it with these names \u2014 not
657
+ make up new ones.
658
+
659
+ Example:
660
+ - shipping pace outruns strategic decision-making
661
+ - architecture decisions surface without context about why
662
+ -->
663
+
664
+ -
665
+
666
+ ## Signals
667
+
668
+ <!--
669
+ Observable quantities you care about. Radiant scores activity
670
+ against these \u2014 5 to 7 is the sweet spot.
671
+
672
+ Example:
673
+ - shipping_velocity
674
+ - decision_ownership
675
+ - storytelling_cadence
676
+ -->
677
+
678
+ -
679
+
680
+ ## Decision Priorities
681
+
682
+ <!--
683
+ When tradeoffs appear, these resolve them. Format: "A > B".
684
+
685
+ Example:
686
+ - correctness > speed
687
+ - clarity > cleverness
688
+ -->
689
+
690
+ -
691
+ `
692
+ };
693
+ async function cmdInit(args) {
694
+ const targetDir = resolve(args.rest[0] ?? "./mind-palace");
695
+ const existed = existsSync(targetDir);
696
+ if (existed && !args.force) {
697
+ const entries = readdirSync(targetDir);
698
+ if (entries.length > 0) {
699
+ process.stderr.write(
700
+ `${RED}Error:${RESET} ${targetDir} already exists and is not empty.
701
+ ${DIM}Use --force to write into it anyway (existing files will be overwritten).${RESET}
702
+ `
703
+ );
704
+ process.exit(1);
705
+ }
706
+ }
707
+ mkdirSync(targetDir, { recursive: true });
708
+ mkdirSync(join(targetDir, "reads"), { recursive: true });
709
+ mkdirSync(join(targetDir, "worldmodels"), { recursive: true });
710
+ for (const [relPath, content] of Object.entries(MIND_PALACE_FILES)) {
711
+ const fullPath = join(targetDir, relPath);
712
+ mkdirSync(resolve(fullPath, ".."), { recursive: true });
713
+ writeFileSync(fullPath, content, "utf-8");
714
+ }
715
+ process.stdout.write(
716
+ `${GREEN}\u2713${RESET} Mind Palace scaffolded at ${BOLD}${targetDir}${RESET}
717
+
718
+ ${DIM}Next steps:${RESET}
719
+ 1. Edit ${targetDir}/attention.md \u2014 what you're focused on right now
720
+ 2. Edit ${targetDir}/worldmodels/starter.worldmodel.md \u2014 add a few
721
+ aligned and drift behaviors
722
+ 3. Run: neuroverse radiant emergent <owner/repo> \\
723
+ --worlds ${targetDir}/worldmodels \\
724
+ --exocortex ${targetDir}
725
+
726
+ ${DIM}Files are yours. Edit freely.${RESET}
727
+ `
728
+ );
729
+ }
446
730
  async function main(argv) {
447
731
  const args = parseArgs(argv);
448
732
  if (args.help || !args.subcommand) {
@@ -450,6 +734,8 @@ async function main(argv) {
450
734
  return;
451
735
  }
452
736
  switch (args.subcommand) {
737
+ case "init":
738
+ return cmdInit(args);
453
739
  case "think":
454
740
  return cmdThink(args);
455
741
  case "lenses":
@@ -457,7 +743,7 @@ async function main(argv) {
457
743
  case "emergent":
458
744
  return cmdEmergent(args);
459
745
  case "mcp": {
460
- const { startRadiantMcp } = await import("../server-JKUBUK5H.js");
746
+ const { startRadiantMcp } = await import("../server-EI5JCIBU.js");
461
747
  return startRadiantMcp(argv);
462
748
  }
463
749
  case "decision":
@@ -481,5 +767,7 @@ async function main(argv) {
481
767
  }
482
768
  }
483
769
  export {
484
- main
770
+ checkScopeConsent,
771
+ main,
772
+ parseArgs
485
773
  };