@neuroverseos/governance 0.7.0 → 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.
@@ -636,17 +636,30 @@ var init_think = __esm({
636
636
  });
637
637
 
638
638
  // src/radiant/core/scopes.ts
639
- function parseRepoScope(scope) {
639
+ function parseScope(scope) {
640
640
  const cleaned = scope.replace(/^https?:\/\//, "").replace(/^github\.com\//, "").replace(/\.git$/, "").replace(/\/$/, "");
641
- const parts = cleaned.split("/");
642
- if (parts.length < 2 || !parts[0] || !parts[1]) {
641
+ const parts = cleaned.split("/").filter(Boolean);
642
+ if (parts.length === 0 || !parts[0]) {
643
+ throw new Error(
644
+ `Cannot parse scope: "${scope}". Expected "owner/repo" or "owner".`
645
+ );
646
+ }
647
+ if (parts.length === 1) {
648
+ return { type: "org", owner: parts[0] };
649
+ }
650
+ return { type: "repo", owner: parts[0], repo: parts[1] };
651
+ }
652
+ function parseRepoScope(scope) {
653
+ const parsed = parseScope(scope);
654
+ if (parsed.type === "org") {
643
655
  throw new Error(
644
- `Cannot parse repo scope: "${scope}". Expected "owner/repo" or a GitHub URL.`
656
+ `Expected "owner/repo" but got org-level scope "${parsed.owner}". Use parseScope() for org-level.`
645
657
  );
646
658
  }
647
- return { owner: parts[0], repo: parts[1] };
659
+ return parsed;
648
660
  }
649
661
  function formatScope(scope) {
662
+ if (scope.type === "org") return `${scope.owner} (org)`;
650
663
  return `${scope.owner}/${scope.repo}`;
651
664
  }
652
665
  var init_scopes = __esm({
@@ -821,6 +834,40 @@ async function fetchJSON(url, headers) {
821
834
  }
822
835
  return await res.json();
823
836
  }
837
+ async function fetchGitHubOrgActivity(scope, token, options = {}) {
838
+ const perPage = options.perPage ?? 100;
839
+ const headers = {
840
+ Authorization: `token ${token}`,
841
+ Accept: "application/vnd.github.v3+json",
842
+ "User-Agent": "neuroverseos-radiant"
843
+ };
844
+ const repos = await fetchJSON(
845
+ `https://api.github.com/orgs/${scope.owner}/repos?sort=pushed&direction=desc&per_page=${perPage}`,
846
+ headers
847
+ );
848
+ const windowDays = options.windowDays ?? 14;
849
+ const since = new Date(Date.now() - windowDays * 24 * 60 * 60 * 1e3);
850
+ const activeRepos = repos.filter(
851
+ (r) => new Date(r.pushed_at) >= since
852
+ );
853
+ const cappedRepos = activeRepos.slice(0, 10);
854
+ const allEvents = [];
855
+ const repoNames = [];
856
+ for (const repo of cappedRepos) {
857
+ const [owner, repoName] = repo.full_name.split("/");
858
+ try {
859
+ const repoScope = { type: "repo", owner, repo: repoName };
860
+ const events = await fetchGitHubActivity(repoScope, token, options);
861
+ allEvents.push(...events);
862
+ if (events.length > 0) repoNames.push(repo.full_name);
863
+ } catch {
864
+ }
865
+ }
866
+ allEvents.sort(
867
+ (a, b) => Date.parse(a.timestamp) - Date.parse(b.timestamp)
868
+ );
869
+ return { events: allEvents, repos: repoNames };
870
+ }
824
871
  var KNOWN_AI_LOGINS, KNOWN_AI_CO_AUTHOR_NAMES;
825
872
  var init_github = __esm({
826
873
  "src/radiant/adapters/github.ts"() {
@@ -2238,7 +2285,7 @@ var init_guard_engine = __esm({
2238
2285
  async function loadWorldFromDirectory(dirPath) {
2239
2286
  const { readFile } = await import("fs/promises");
2240
2287
  const { join: join5 } = await import("path");
2241
- const { readdirSync: readdirSync4 } = await import("fs");
2288
+ const { readdirSync: readdirSync5 } = await import("fs");
2242
2289
  async function readJson(filename) {
2243
2290
  const filePath = join5(dirPath, filename);
2244
2291
  try {
@@ -2271,7 +2318,7 @@ async function loadWorldFromDirectory(dirPath) {
2271
2318
  const rules = [];
2272
2319
  try {
2273
2320
  const rulesDir = join5(dirPath, "rules");
2274
- const ruleFiles = readdirSync4(rulesDir).filter((f) => f.endsWith(".json")).sort();
2321
+ const ruleFiles = readdirSync5(rulesDir).filter((f) => f.endsWith(".json")).sort();
2275
2322
  for (const file of ruleFiles) {
2276
2323
  try {
2277
2324
  const content = await readFile(join5(rulesDir, file), "utf-8");
@@ -2735,6 +2782,14 @@ ${jargonTable}
2735
2782
 
2736
2783
  For example: don't say "update the worldmodel." Say "add a line to your strategy file."
2737
2784
 
2785
+ ## When the same invariant keeps firing
2786
+
2787
+ 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:
2788
+
2789
+ "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."
2790
+
2791
+ Don't just say "invariant held." Say what it means that people keep pushing against the same wall.
2792
+
2738
2793
  ## Health is a valid read
2739
2794
 
2740
2795
  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:
@@ -3131,9 +3186,21 @@ async function emergent(input) {
3131
3186
  priorReadContext = formatPriorReadsForPrompt(priorReads);
3132
3187
  }
3133
3188
  }
3134
- const events = await fetchGitHubActivity(input.scope, input.githubToken, {
3135
- windowDays
3136
- });
3189
+ let events;
3190
+ let orgRepos;
3191
+ if (input.scope.type === "org") {
3192
+ const orgResult = await fetchGitHubOrgActivity(
3193
+ input.scope,
3194
+ input.githubToken,
3195
+ { windowDays }
3196
+ );
3197
+ events = orgResult.events;
3198
+ orgRepos = orgResult.repos;
3199
+ } else {
3200
+ events = await fetchGitHubActivity(input.scope, input.githubToken, {
3201
+ windowDays
3202
+ });
3203
+ }
3137
3204
  const classified = classifyEvents(events);
3138
3205
  const signals = extractSignals(classified);
3139
3206
  const scores = computeScores(signals, input.worldmodelContent !== "");
@@ -3624,6 +3691,8 @@ function parseArgs(argv) {
3624
3691
  query: void 0,
3625
3692
  model: void 0,
3626
3693
  exocortex: void 0,
3694
+ teamExocortex: void 0,
3695
+ view: void 0,
3627
3696
  json: false,
3628
3697
  help: false,
3629
3698
  rest: []
@@ -3651,6 +3720,12 @@ function parseArgs(argv) {
3651
3720
  case "--exocortex":
3652
3721
  result.exocortex = argv[++i];
3653
3722
  break;
3723
+ case "--team-exocortex":
3724
+ result.teamExocortex = argv[++i];
3725
+ break;
3726
+ case "--view":
3727
+ result.view = argv[++i];
3728
+ break;
3654
3729
  case "--json":
3655
3730
  result.json = true;
3656
3731
  break;
@@ -3792,7 +3867,7 @@ async function cmdEmergent(args) {
3792
3867
  );
3793
3868
  process.exit(1);
3794
3869
  }
3795
- const scope = parseRepoScope(scopeStr);
3870
+ const scope = parseScope(scopeStr);
3796
3871
  const lensId = args.lens ?? process.env.RADIANT_LENS;
3797
3872
  if (!lensId) {
3798
3873
  process.stderr.write(
@@ -3830,6 +3905,15 @@ ${DIM}Set it to a GitHub PAT with repo read access.${RESET}
3830
3905
  const worldmodelContent = loadWorldmodelContent2(worldsPath);
3831
3906
  const model = args.model ?? process.env.RADIANT_MODEL;
3832
3907
  const ai = createAnthropicAI(anthropicKey, model || void 0);
3908
+ const view = args.view ?? process.env.RADIANT_VIEW ?? "community";
3909
+ const validViews = ["community", "team", "full"];
3910
+ if (!validViews.includes(view)) {
3911
+ process.stderr.write(
3912
+ `${RED}Error:${RESET} --view must be community, team, or full. Got "${view}".
3913
+ `
3914
+ );
3915
+ process.exit(1);
3916
+ }
3833
3917
  const exocortexPath = args.exocortex ?? process.env.RADIANT_EXOCORTEX;
3834
3918
  let exocortexStatus = "not loaded";
3835
3919
  if (exocortexPath) {
@@ -3837,7 +3921,8 @@ ${DIM}Set it to a GitHub PAT with repo read access.${RESET}
3837
3921
  exocortexStatus = summarizeExocortex(ctx);
3838
3922
  }
3839
3923
  process.stderr.write(
3840
- `${DIM}Scope: ${scope.owner}/${scope.repo}${RESET}
3924
+ `${DIM}Scope: ${scope.type === "org" ? scope.owner + " (entire org)" : scope.owner + "/" + scope.repo}${RESET}
3925
+ ${DIM}View: ${view}${RESET}
3841
3926
  ${DIM}Lens: ${lensId}${RESET}
3842
3927
  ${DIM}Model: ${model ?? "claude-sonnet-4-20250514 (default)"}${RESET}
3843
3928
  ${DIM}ExoCortex: ${exocortexStatus}${RESET}
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  createAnthropicAI,
3
3
  emergent,
4
- parseRepoScope,
4
+ parseScope,
5
5
  readExocortex,
6
6
  summarizeExocortex,
7
7
  think
8
- } from "../chunk-T6EQ7ZBG.js";
8
+ } from "../chunk-MC6O5GV5.js";
9
9
  import {
10
10
  listLenses
11
11
  } from "../chunk-VGFDMPVB.js";
@@ -57,6 +57,8 @@ function parseArgs(argv) {
57
57
  query: void 0,
58
58
  model: void 0,
59
59
  exocortex: void 0,
60
+ teamExocortex: void 0,
61
+ view: void 0,
60
62
  json: false,
61
63
  help: false,
62
64
  rest: []
@@ -84,6 +86,12 @@ function parseArgs(argv) {
84
86
  case "--exocortex":
85
87
  result.exocortex = argv[++i];
86
88
  break;
89
+ case "--team-exocortex":
90
+ result.teamExocortex = argv[++i];
91
+ break;
92
+ case "--view":
93
+ result.view = argv[++i];
94
+ break;
87
95
  case "--json":
88
96
  result.json = true;
89
97
  break;
@@ -225,7 +233,7 @@ async function cmdEmergent(args) {
225
233
  );
226
234
  process.exit(1);
227
235
  }
228
- const scope = parseRepoScope(scopeStr);
236
+ const scope = parseScope(scopeStr);
229
237
  const lensId = args.lens ?? process.env.RADIANT_LENS;
230
238
  if (!lensId) {
231
239
  process.stderr.write(
@@ -263,6 +271,15 @@ ${DIM}Set it to a GitHub PAT with repo read access.${RESET}
263
271
  const worldmodelContent = loadWorldmodelContent(worldsPath);
264
272
  const model = args.model ?? process.env.RADIANT_MODEL;
265
273
  const ai = createAnthropicAI(anthropicKey, model || void 0);
274
+ const view = args.view ?? process.env.RADIANT_VIEW ?? "community";
275
+ const validViews = ["community", "team", "full"];
276
+ if (!validViews.includes(view)) {
277
+ process.stderr.write(
278
+ `${RED}Error:${RESET} --view must be community, team, or full. Got "${view}".
279
+ `
280
+ );
281
+ process.exit(1);
282
+ }
266
283
  const exocortexPath = args.exocortex ?? process.env.RADIANT_EXOCORTEX;
267
284
  let exocortexStatus = "not loaded";
268
285
  if (exocortexPath) {
@@ -270,7 +287,8 @@ ${DIM}Set it to a GitHub PAT with repo read access.${RESET}
270
287
  exocortexStatus = summarizeExocortex(ctx);
271
288
  }
272
289
  process.stderr.write(
273
- `${DIM}Scope: ${scope.owner}/${scope.repo}${RESET}
290
+ `${DIM}Scope: ${scope.type === "org" ? scope.owner + " (entire org)" : scope.owner + "/" + scope.repo}${RESET}
291
+ ${DIM}View: ${view}${RESET}
274
292
  ${DIM}Lens: ${lensId}${RESET}
275
293
  ${DIM}Model: ${model ?? "claude-sonnet-4-20250514 (default)"}${RESET}
276
294
  ${DIM}ExoCortex: ${exocortexStatus}${RESET}
@@ -401,7 +419,7 @@ async function main(argv) {
401
419
  case "emergent":
402
420
  return cmdEmergent(args);
403
421
  case "mcp": {
404
- const { startRadiantMcp } = await import("../server-BXMC5NOE.js");
422
+ const { startRadiantMcp } = await import("../server-DFNY5N5A.js");
405
423
  return startRadiantMcp(argv);
406
424
  }
407
425
  case "decision":