@neuroverseos/governance 0.6.0 → 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.
@@ -0,0 +1,3249 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/radiant/index.ts
31
+ var radiant_exports = {};
32
+ __export(radiant_exports, {
33
+ DEFAULT_EVIDENCE_GATE: () => DEFAULT_EVIDENCE_GATE,
34
+ DEFAULT_SIGNAL_EXTRACTORS: () => DEFAULT_SIGNAL_EXTRACTORS,
35
+ LENSES: () => LENSES,
36
+ RADIANT_PACKAGE_VERSION: () => RADIANT_PACKAGE_VERSION,
37
+ auditGovernance: () => auditGovernance,
38
+ aukiBuilderLens: () => aukiBuilderLens,
39
+ checkForbiddenPhrases: () => checkForbiddenPhrases,
40
+ classifyActorDomain: () => classifyActorDomain,
41
+ classifyEvents: () => classifyEvents,
42
+ composeSystemPrompt: () => composeSystemPrompt,
43
+ computePersistence: () => computePersistence,
44
+ createAnthropicAI: () => createAnthropicAI,
45
+ createMockAI: () => createMockAI,
46
+ createMockGitHubAdapter: () => createMockGitHubAdapter,
47
+ emergent: () => emergent,
48
+ extractSignals: () => extractSignals,
49
+ fetchGitHubActivity: () => fetchGitHubActivity,
50
+ formatExocortexForPrompt: () => formatExocortexForPrompt,
51
+ formatPriorReadsForPrompt: () => formatPriorReadsForPrompt,
52
+ formatScope: () => formatScope,
53
+ getLens: () => getLens,
54
+ interpretPatterns: () => interpretPatterns,
55
+ isPresent: () => isPresent,
56
+ isScored: () => isScored,
57
+ isSentinel: () => isSentinel,
58
+ listLenses: () => listLenses,
59
+ loadPriorReads: () => loadPriorReads,
60
+ parseRepoScope: () => parseRepoScope,
61
+ presenceAverage: () => presenceAverage,
62
+ readExocortex: () => readExocortex,
63
+ render: () => render,
64
+ scoreComposite: () => scoreComposite,
65
+ scoreCyber: () => scoreCyber,
66
+ scoreLife: () => scoreLife,
67
+ scoreNeuroVerse: () => scoreNeuroVerse,
68
+ summarizeExocortex: () => summarizeExocortex,
69
+ think: () => think,
70
+ updateKnowledge: () => updateKnowledge,
71
+ writeRead: () => writeRead
72
+ });
73
+ module.exports = __toCommonJS(radiant_exports);
74
+
75
+ // src/radiant/types.ts
76
+ var DEFAULT_EVIDENCE_GATE = { k: 3, c: 0.5 };
77
+ function isScored(s) {
78
+ return typeof s === "number";
79
+ }
80
+ function isSentinel(s) {
81
+ return typeof s === "string";
82
+ }
83
+
84
+ // src/radiant/core/math.ts
85
+ function isPresent(o, gate = DEFAULT_EVIDENCE_GATE) {
86
+ return o.eventCount >= gate.k && o.confidence >= gate.c;
87
+ }
88
+ function presenceAverage(items, gate = DEFAULT_EVIDENCE_GATE) {
89
+ const present = items.filter((i) => isPresent(i, gate));
90
+ if (present.length === 0) return "INSUFFICIENT_EVIDENCE";
91
+ const sum = present.reduce((acc, i) => acc + i.score, 0);
92
+ return sum / present.length;
93
+ }
94
+ function scoreLife(capability, gate = DEFAULT_EVIDENCE_GATE) {
95
+ return presenceAverage(capability.dimensions, gate);
96
+ }
97
+ function scoreCyber(capability, gate = DEFAULT_EVIDENCE_GATE) {
98
+ return presenceAverage(capability.dimensions, gate);
99
+ }
100
+ function scoreNeuroVerse(components, worldmodelLoaded, gate = DEFAULT_EVIDENCE_GATE) {
101
+ if (!worldmodelLoaded) return "UNAVAILABLE";
102
+ return presenceAverage(components, gate);
103
+ }
104
+ function scoreComposite(a_L, a_C, a_N) {
105
+ const available = [];
106
+ if (isScored(a_L)) available.push(a_L);
107
+ if (isScored(a_C)) available.push(a_C);
108
+ if (isScored(a_N)) available.push(a_N);
109
+ if (available.length === 0) return "INSUFFICIENT_EVIDENCE";
110
+ return available.reduce((a, b) => a + b, 0) / available.length;
111
+ }
112
+
113
+ // src/radiant/core/domain.ts
114
+ function isLifeSide(k) {
115
+ return k === "human" || k === "unknown";
116
+ }
117
+ function isCyberSide(k) {
118
+ return k === "ai" || k === "bot";
119
+ }
120
+ function crossesBoundary(a, b) {
121
+ return isLifeSide(a) && isCyberSide(b) || isCyberSide(a) && isLifeSide(b);
122
+ }
123
+ function classifyActorDomain(event) {
124
+ const primaryKind = event.actor.kind;
125
+ const coKinds = (event.coActors ?? []).map((a) => a.kind);
126
+ const allKinds = [primaryKind, ...coKinds];
127
+ const hasLife = allKinds.some(isLifeSide);
128
+ const hasCyber = allKinds.some(isCyberSide);
129
+ if (hasLife && hasCyber) {
130
+ return "joint";
131
+ }
132
+ if (event.respondsTo && crossesBoundary(primaryKind, event.respondsTo.actor.kind)) {
133
+ return "joint";
134
+ }
135
+ return isCyberSide(primaryKind) ? "cyber" : "life";
136
+ }
137
+
138
+ // src/radiant/lenses/auki-builder.ts
139
+ var AUKI_VANGUARD_FRAME = {
140
+ domains: [
141
+ "future-foresight",
142
+ "narrative-dynamics",
143
+ "shared-prosperity"
144
+ ],
145
+ overlaps: [
146
+ {
147
+ domains: ["future-foresight", "narrative-dynamics"],
148
+ emergent_state: "Inspiration",
149
+ description: "Visionary leaders inspire action by painting a vivid picture of a better future, helping people understand how to get there together. Emerges when long-range thinking meets language that rallies."
150
+ },
151
+ {
152
+ domains: ["narrative-dynamics", "shared-prosperity"],
153
+ emergent_state: "Trust",
154
+ description: "Built through authentic storytelling and consistent delivery on promises, creating a community where contributors feel secure in their contributions. Emerges when clear intent meets fair distribution \u2014 coalitions form here."
155
+ },
156
+ {
157
+ domains: ["shared-prosperity", "future-foresight"],
158
+ emergent_state: "Hope",
159
+ description: "Propels decentralized communities toward a collective future where resources are equitably distributed and success is shared by all. Emerges when long-term infrastructure is architected for collective benefit \u2014 the DePIN / Intercognitive posture."
160
+ }
161
+ ],
162
+ center_identity: "Collective Vanguard Leader",
163
+ evaluation_questions: [
164
+ "What long-range architectural thinking is present? Systems design, scenario planning, critical thinking, ethical judgment \u2014 which of these is visible, which is weak?",
165
+ "What communication and meaning-making is happening? Storytelling, cultural sensitivity, audience engagement, persuasive writing \u2014 who is telling the story of how the pieces connect?",
166
+ "What collaborative and fairness work is happening? Stakeholder management, partnership development, incentive alignment, community building \u2014 who is building coalitions and making sure value flows equitably?",
167
+ "Which overlap states surface \u2014 Inspiration (vision + narrative), Trust (narrative + fairness), Hope (fairness + long-term thinking)?",
168
+ "Is the integration complete (Collective Vanguard Leader manifests across all three dimensions) or is one dimension absent / weak?",
169
+ "If one dimension is weak, what specific skill inside it is the lowest-friction activation point?"
170
+ ],
171
+ scoring_rubric: `For any Auki activity, identify which specific skills are strongly present, which are weak, which are absent. Cite specific evidence for each. Name the overlap emergent states that surface using their plain-English names (Inspiration, Trust, Hope). Do not surface the bucket names (Future Foresight, Narrative Dynamics, Shared Prosperity) in the output \u2014 those are internal reasoning scaffolds, not reader-facing labels. Translate bucket-level findings into skill-level observations: not "Future Foresight is present" but "the architectural thinking is strong \u2014 the systems design is clear"; not "Shared Prosperity is weak" but "partnership development is missing" or "incentive alignment hasn't been established." Center identity (Collective Vanguard Leader) may be named sparingly, only when all three dimensions fully integrate.`,
172
+ /**
173
+ * The skills inside each domain. These are the OUTPUT-FACING vocabulary —
174
+ * the observable behaviors and capabilities readers understand. When the
175
+ * AI renders findings, it uses these skill names, not the bucket names.
176
+ *
177
+ * From Kirsten\'s original vanguard diagram (see exemplars/vanguard-diagram).
178
+ */
179
+ domain_skills: {
180
+ "future-foresight": [
181
+ "strategic thinking",
182
+ "systems design",
183
+ "scenario planning",
184
+ "futurism and trend analysis",
185
+ "critical thinking",
186
+ "innovative problem-solving",
187
+ "data-driven decision-making",
188
+ "ethical judgment and governance",
189
+ "risk assessment and mitigation",
190
+ "curiosity and open-mindedness"
191
+ ],
192
+ "narrative-dynamics": [
193
+ "storytelling and narrative crafting",
194
+ "behavioral psychology and memetics",
195
+ "emotional intelligence",
196
+ "communication and presentation skills",
197
+ "cultural sensitivity and adaptation",
198
+ "social media and viral messaging strategy",
199
+ "brand building and positioning",
200
+ "persuasive writing",
201
+ "visualization and design thinking",
202
+ "audience analysis and engagement"
203
+ ],
204
+ "shared-prosperity": [
205
+ "stakeholder management",
206
+ "collaborative leadership",
207
+ "conflict resolution and mediation",
208
+ "economic and tokenomic design",
209
+ "incentive alignment",
210
+ "community building and management",
211
+ "inclusivity and equity advocacy",
212
+ "partnership development",
213
+ "transparency and accountability",
214
+ "negotiation and diplomacy"
215
+ ]
216
+ },
217
+ /**
218
+ * The translation rule: bucket names stay internal; skills + overlap
219
+ * state names surface in output. This is enforced by both the
220
+ * output-directive (guidance to the AI) and the forbidden-phrases list
221
+ * (renderer-level rejection of any output leaking bucket names).
222
+ */
223
+ output_translation: {
224
+ never_surface_in_output: [
225
+ "Future Foresight",
226
+ "Narrative Dynamics",
227
+ "Shared Prosperity"
228
+ ],
229
+ surface_freely: [
230
+ "Inspiration",
231
+ "Trust",
232
+ "Hope"
233
+ // plus any specific skill name from domain_skills above
234
+ ],
235
+ surface_sparingly: ["Collective Vanguard Leader"],
236
+ translation_examples: [
237
+ {
238
+ internal_reasoning: "Future Foresight is strong",
239
+ external_expression: "the architectural thinking is strong; the systems design is clear"
240
+ },
241
+ {
242
+ internal_reasoning: "Shared Prosperity is weak",
243
+ external_expression: "partnership development is missing; no one has established incentive alignment across teams"
244
+ },
245
+ {
246
+ internal_reasoning: "Narrative Dynamics is absent",
247
+ external_expression: "no one is telling the story of how these pieces connect; the audience does not see the shared vision yet"
248
+ }
249
+ ]
250
+ }
251
+ };
252
+ var AUKI_VOCABULARY = {
253
+ proper_nouns: [
254
+ "$AUKI",
255
+ "Posemesh",
256
+ "Auki Labs",
257
+ "Posemesh Foundation",
258
+ "Intercognitive Foundation",
259
+ "Intercognitive",
260
+ "Sixth Protocol",
261
+ "Fifth Protocol",
262
+ "DePIN",
263
+ "Cactus",
264
+ "Terri",
265
+ "Mech Jagger",
266
+ "peaq",
267
+ "Mawari",
268
+ "GEODNET",
269
+ "Nine Pillars of AI Accessibility",
270
+ "the real world web",
271
+ "the posemesh"
272
+ ],
273
+ // Generic term → Auki-native replacement
274
+ preferred: {
275
+ device: "participant",
276
+ client: "participant",
277
+ "coordinate system": "domain",
278
+ "QR code for calibration": "portal",
279
+ "work request": "task",
280
+ "location alignment": "calibrate",
281
+ "sensor reading": "observation",
282
+ "physical environment": "environment",
283
+ "the network (public-facing)": "the real world web",
284
+ "the network (technical)": "the posemesh",
285
+ "coordination between devices": "spatial orchestration",
286
+ "buying services": "burning tokens for credits",
287
+ "full autonomy": "the full stack",
288
+ "non-GPS environments": "GPS-denied environments",
289
+ "our partners": "the Intercognitive coalition (Auki, peaq, Mawari, GEODNET)"
290
+ },
291
+ architecture: [
292
+ "domain",
293
+ "domain cluster",
294
+ "domain manager",
295
+ "domain owner",
296
+ "semantic layer",
297
+ "topography layer",
298
+ "rendering layer",
299
+ "partitions",
300
+ "observations",
301
+ "portals",
302
+ "participant",
303
+ "supply participant",
304
+ "demand participant",
305
+ "capabilities",
306
+ "tasks",
307
+ "discovery service",
308
+ "DHT",
309
+ "substrate",
310
+ "spatial orchestration",
311
+ "app-free navigation",
312
+ "marker-free VPS",
313
+ "spatially aware",
314
+ "the stack",
315
+ "the robotics stack",
316
+ "GPS-denied",
317
+ "locomotion",
318
+ "manipulation",
319
+ "spatio-semantic perception",
320
+ "mapping",
321
+ "positioning",
322
+ "hybrid robotics",
323
+ "AI copilot",
324
+ "shared spatial layer"
325
+ ],
326
+ economic: [
327
+ "burn",
328
+ "credit",
329
+ "deflationary mint",
330
+ "reputation",
331
+ "vacancy",
332
+ "treasury",
333
+ "utilization rate",
334
+ "initial supply",
335
+ "total supply",
336
+ "organization",
337
+ "trustless",
338
+ "peer-to-peer transactions",
339
+ "machine passports",
340
+ "machine economy"
341
+ ],
342
+ framing: [
343
+ "machine perception",
344
+ "spatial computing",
345
+ "collaborative perception",
346
+ "cognitive liberty",
347
+ "perception-first",
348
+ "protocol-not-product",
349
+ "sovereignty",
350
+ "decentralization",
351
+ "territory capture",
352
+ "foundations-before-execution",
353
+ "make the world machine-readable",
354
+ "connective tissue between digital and physical",
355
+ "open, permissionless, interoperable, private",
356
+ "skip the bottleneck, ship the leverage",
357
+ "coalition before standard",
358
+ "hybrid over pure",
359
+ "augmentation without surveillance",
360
+ "civilization-scale infrastructure",
361
+ "public good, not proprietary asset",
362
+ "Inspiration",
363
+ "Trust",
364
+ "Hope",
365
+ "Collective Vanguard Leader"
366
+ ],
367
+ // System-internal concepts → plain English for output.
368
+ // Readers don't know Radiant's vocabulary. Speaking it to them is jargon.
369
+ jargon_translations: {
370
+ "worldmodel": "your strategy file",
371
+ "canonical pattern": "something Radiant tracks by name over time",
372
+ "candidate pattern": "something Radiant noticed but hasn't been told to watch for",
373
+ "evidence gate": "how much activity Radiant needs before it speaks",
374
+ "invariant": "a rule you declared non-negotiable",
375
+ "signal extraction": "reading the activity",
376
+ "alignment score": "how aligned the work is with what you said matters",
377
+ "actor domain": "who did the work (a person, an AI, or both together)",
378
+ "presence-based averaging": "only counts what actually happened",
379
+ "drift detection": "noticing when things are shifting from what you said you wanted",
380
+ "lens rewrite": "framing adjustment before output",
381
+ "INSUFFICIENT_EVIDENCE": "not enough to say confidently",
382
+ "UNAVAILABLE": "we can't measure this yet"
383
+ }
384
+ };
385
+ var AUKI_VOICE = {
386
+ register: 'diagnosis mode \u2014 compressed, strategic, builder-direct. Closer to the closing paragraph of an Auki year-recap ("2025 was foundations. 2026 is execution.") than to its month-by-month celebration.',
387
+ active_voice: "required",
388
+ specificity: "required",
389
+ hype_vocabulary: "forbidden",
390
+ hedging: "forbidden",
391
+ playfulness: "rare",
392
+ close_with_strategic_frame: "preferred",
393
+ punchline_move: "sparing",
394
+ honesty_about_failure: "required",
395
+ output_translation: `Reason internally through the three-domain frame (Future Foresight, Narrative Dynamics, Shared Prosperity) \u2014 that is the analytical scaffold. Express findings externally in the skills vocabulary INSIDE each domain (e.g. "strategic thinking," "partnership development," "storytelling," "incentive alignment"). Use the overlap state names (Inspiration, Trust, Hope) as plain-English emergent feelings. Do NOT surface the bucket names themselves (Future Foresight, Narrative Dynamics, Shared Prosperity) as labels in output \u2014 they are the model-maker's scaffold, not reader vocabulary. Readers understand skills, not buckets. The bucket names are in the forbidden_phrases list; the renderer will fail output that leaks them. Collective Vanguard Leader may be named sparingly when all three dimensions are fully integrated.`
396
+ };
397
+ var AUKI_FORBIDDEN_PHRASES = Object.freeze([
398
+ // Domain bucket names — never surface to readers; translate to skills
399
+ "future foresight",
400
+ "narrative dynamics",
401
+ "shared prosperity",
402
+ // AI-assistant hedging
403
+ "it may be beneficial to consider",
404
+ "there appears to be",
405
+ "one possible interpretation",
406
+ "it might be worth exploring",
407
+ "it might be worth considering",
408
+ "consider whether",
409
+ "it is worth noting",
410
+ "please note that",
411
+ "it should be noted",
412
+ "in conclusion",
413
+ // Corporate / marketing
414
+ "unparalleled",
415
+ "best-in-class",
416
+ "industry-leading",
417
+ "revolutionary",
418
+ "cutting-edge",
419
+ "state-of-the-art",
420
+ "thrilled to announce",
421
+ "excited to share",
422
+ "game-changing",
423
+ "synergy",
424
+ "synergies",
425
+ "stakeholders",
426
+ // too corporate; prefer named actors
427
+ "end-users",
428
+ "value proposition",
429
+ "paradigm shift",
430
+ // Generic motion
431
+ "going forward",
432
+ "moving forward",
433
+ "at the end of the day",
434
+ "touching base",
435
+ "circle back",
436
+ "deep dive",
437
+ "level set",
438
+ "low-hanging fruit"
439
+ ]);
440
+ var AUKI_PREFERRED_PATTERNS = Object.freeze([
441
+ // Direct declarative observation
442
+ "[Specific skill] is strong here. [Named evidence].",
443
+ "[Specific skill] is breaking here. [Named evidence].",
444
+ "[Specific skill] is missing. [Named consequence].",
445
+ // Skills-level diagnosis (replaces the bucket-speak pattern)
446
+ "The [specific skill] is clear \u2014 [specific evidence]. But [another specific skill] is missing \u2014 [specific effect]. [Imperative move].",
447
+ "What is missing is [specific skill], not effort.",
448
+ "[Trust | Inspiration | Hope] won't emerge until [skill-A] and [skill-B] happen together.",
449
+ // Imperative move
450
+ "Force [action] or [consequence].",
451
+ "Tighten this or it fragments.",
452
+ "Skip the bottleneck, ship the leverage.",
453
+ "Coalition before standard.",
454
+ // Strategic close — list-becomes-argument (from year-recap)
455
+ "Combine [A, B, C] and suddenly [strategic implication].",
456
+ "[Phase A] was [what you built]. [Phase B] is [what you execute].",
457
+ // Binary stakes (from Intercognitive)
458
+ "[Centralize X in the hands of a few] or [build a decentralized alternative].",
459
+ // Short thesis compression (from glossary)
460
+ "[Subject] is [essential-function] \u2014 [one-line precision].",
461
+ // Named specificity
462
+ "[Named partner/place/number] is the one that matters here.",
463
+ // Honest texture (from year-recap)
464
+ "[Specific thing] is not yet [state] \u2014 [honest qualifier].",
465
+ // Pivot to reality before solution (from hybrid robotics)
466
+ "The truth is [current reality]. [Better approach] is [the move].",
467
+ // Overlap-state compression (surfacing the emergent feel, not the buckets)
468
+ "Trust is not emerging because [specific narrative skill] and [specific coalition skill] are not happening together.",
469
+ "Inspiration is landing here \u2014 [specific evidence of vision + rally].",
470
+ "Hope is present \u2014 [specific evidence of long-term thinking meeting fair distribution]."
471
+ ]);
472
+ var AUKI_STRATEGIC_PATTERNS = Object.freeze([
473
+ "Skip the bottleneck, ship the leverage \u2014 identify the hard layers in the stack, build on the layers that deliver value now.",
474
+ "Coalition before standard \u2014 form the group that will set the rules before the rules need to exist.",
475
+ "Foundations before execution \u2014 build the infrastructure that makes the thing possible; then scale.",
476
+ "Hybrid over pure \u2014 augment humans with AI where full autonomy is not ready; transition later.",
477
+ "Decentralized > proprietary \u2014 when choosing architecture, prefer open / community-governed / interoperable over closed / owned / siloed.",
478
+ "Layered analysis first, strategic move second \u2014 decompose before deciding.",
479
+ 'Named specificity over abstractions \u2014 cite people, places, partners, numbers; never "stakeholders" or "the industry."',
480
+ "Community deployment before public release \u2014 validate with a small group of operators before opening the door.",
481
+ "Cognitive liberty as inviolable constraint \u2014 block any move that violates sovereignty over spatial/sensor data, regardless of other benefits.",
482
+ "Compress mission to one sentence \u2014 one memorable thesis carries more weight than a manifesto."
483
+ ]);
484
+ var AUKI_EXEMPLARS = Object.freeze([
485
+ {
486
+ path: "intercognitive-foundation.md",
487
+ title: "The Intercognitive Foundation",
488
+ exhibits: ["future-foresight", "narrative-dynamics", "shared-prosperity"],
489
+ integration_quality: "full \u2014 all three domains integrated; Collective Vanguard Leader manifests through the coalition itself",
490
+ notes: 'The perfect vanguard exemplar. Future Foresight: inflection-point framing, Nine Pillars architecture. Narrative Dynamics: "the physical world cannot remain a blind spot," rally language, invitation to join. Shared Prosperity: coalition of four founding members, "no single entity should own," community governance, public good framing. When Radiant outputs something that feels vanguard-complete, it should resemble this in structure and tone.'
491
+ },
492
+ {
493
+ path: "hybrid-robotics-essay.md",
494
+ title: "The Case for Hybrid Robotics",
495
+ exhibits: ["future-foresight", "shared-prosperity"],
496
+ integration_quality: "partial \u2014 Future Foresight dominant, Shared Prosperity secondary, Narrative Dynamics present but informing rather than rallying. Overlap: Hope emerges (long-horizon infrastructure for collective benefit).",
497
+ notes: 'Auki teaching how it thinks. The stack-analysis \u2192 bottleneck-identification \u2192 skip-and-ship pattern is a reusable Auki reasoning move. When the AI applies "systems-first" and "leverage-oriented" thinking, it should resemble this essay \u2014 structured, honest about current reality, pivoting to a better approach via layered reasoning.'
498
+ },
499
+ {
500
+ path: "glossary.md",
501
+ title: "Auki Glossary",
502
+ exhibits: ["future-foresight"],
503
+ integration_quality: 'primary-dominant \u2014 Future Foresight dominant (precise technical definitions as long-range conceptual infrastructure). Shared Prosperity implicit (glossary is open, cross-referenced, serves the ecosystem). Narrative Dynamics flashes once ("a mesh of machines reasoning about pose") but is not primary.',
504
+ notes: 'Source of the vocabulary map. Also teaches compression style: one-line precision definitions, cross-reference density, occasional poetic compression. When the renderer produces short thesis sentences, aim for the "mesh of machines reasoning about pose" level of compression.'
505
+ },
506
+ {
507
+ path: "year-recap-2025.md",
508
+ title: "Auki 2025 Year-End Recap",
509
+ exhibits: ["narrative-dynamics", "shared-prosperity"],
510
+ integration_quality: "partial \u2014 Narrative Dynamics dominant, Shared Prosperity strong, Future Foresight arrives only in the closing paragraph. Overlap: Trust emerges (stakeholders can see their place in the collective progress).",
511
+ notes: 'The celebration register \u2014 warm, specific, named. Not the diagnosis register the lens primarily enforces, but the same DNA. Use this exemplar when calibrating how Auki names specifics (Pepito in Bali, Mika Haak at HQ, the HK web3 robotics cabal) and how the "\u2014 literally" punchline move lands. Do NOT mimic the celebration warmth in diagnosis outputs.'
512
+ }
513
+ ]);
514
+ function aukiBuilderRewrite(pattern) {
515
+ if (pattern.evidence.cited_invariant) {
516
+ return {
517
+ ...pattern,
518
+ framing: "invariant pressure",
519
+ emphasis: "worldmodel invariant cited by this observation \u2014 surface the cross-reference",
520
+ compress: true
521
+ };
522
+ }
523
+ if (pattern.type === "candidate") {
524
+ return {
525
+ ...pattern,
526
+ framing: "emergent observation (not yet in worldmodel)",
527
+ emphasis: "candidate pattern \u2014 surface the vanguard-domain analysis (which domain activated this?)",
528
+ compress: true
529
+ };
530
+ }
531
+ return {
532
+ ...pattern,
533
+ framing: "system-level consequence",
534
+ emphasis: "coordination + leverage",
535
+ compress: true
536
+ };
537
+ }
538
+ var aukiBuilderLens = {
539
+ name: "auki-builder",
540
+ description: "Renders behavioral interpretation through the vanguard leadership model \u2014 Future Foresight, Narrative Dynamics, Shared Prosperity. Role-based, not personal. Encodes how Auki-grade builders think and speak when the vanguard model is running. Companion to auki-vanguard.worldmodel.md (the abstract DNA) and the exemplars at src/radiant/examples/auki/exemplars/ (worked implementations).",
541
+ primary_frame: {
542
+ domains: AUKI_VANGUARD_FRAME.domains,
543
+ overlaps: AUKI_VANGUARD_FRAME.overlaps,
544
+ center_identity: AUKI_VANGUARD_FRAME.center_identity,
545
+ evaluation_questions: AUKI_VANGUARD_FRAME.evaluation_questions,
546
+ scoring_rubric: AUKI_VANGUARD_FRAME.scoring_rubric
547
+ },
548
+ vocabulary: AUKI_VOCABULARY,
549
+ voice: AUKI_VOICE,
550
+ forbidden_phrases: AUKI_FORBIDDEN_PHRASES,
551
+ preferred_patterns: AUKI_PREFERRED_PATTERNS,
552
+ strategic_patterns: AUKI_STRATEGIC_PATTERNS,
553
+ exemplar_refs: AUKI_EXEMPLARS,
554
+ rewrite: aukiBuilderRewrite
555
+ };
556
+
557
+ // src/radiant/lenses/index.ts
558
+ var LENSES = Object.freeze({
559
+ "auki-builder": aukiBuilderLens
560
+ });
561
+ function getLens(id) {
562
+ return LENSES[id];
563
+ }
564
+ function listLenses() {
565
+ return Object.freeze(Object.keys(LENSES));
566
+ }
567
+
568
+ // src/radiant/core/signals.ts
569
+ function classifyEvents(events) {
570
+ return events.map((event) => ({
571
+ event,
572
+ domain: classifyActorDomain(event)
573
+ }));
574
+ }
575
+ function extractSignals(events, extractors = DEFAULT_SIGNAL_EXTRACTORS) {
576
+ const domains = ["life", "cyber", "joint"];
577
+ const out = [];
578
+ for (const extractor of extractors) {
579
+ for (const domain of domains) {
580
+ const r = extractor.extract(events, domain);
581
+ out.push({
582
+ id: extractor.id,
583
+ domain,
584
+ score: r.score,
585
+ eventCount: r.eventCount,
586
+ confidence: r.confidence
587
+ });
588
+ }
589
+ }
590
+ return out;
591
+ }
592
+ var ZERO = { score: 0, eventCount: 0, confidence: 0 };
593
+ function inDomain(events, domain) {
594
+ return events.filter((e) => e.domain === domain);
595
+ }
596
+ function confidenceFromCount(count) {
597
+ return Math.min(1, count / 10);
598
+ }
599
+ function clamp100(n) {
600
+ if (n < 0) return 0;
601
+ if (n > 100) return 100;
602
+ return n;
603
+ }
604
+ var CLARITY_EXTRACTOR = {
605
+ id: "clarity",
606
+ description: "Informativeness of event content \u2014 commit messages, PR bodies, review text",
607
+ extract(events, domain) {
608
+ const sub = inDomain(events, domain);
609
+ if (sub.length === 0) return ZERO;
610
+ const totalScore = sub.reduce((acc, e) => {
611
+ const len = (e.event.content ?? "").length;
612
+ const norm = Math.min(len, 200) / 200;
613
+ return acc + norm * 100;
614
+ }, 0);
615
+ return {
616
+ score: clamp100(totalScore / sub.length),
617
+ eventCount: sub.length,
618
+ confidence: confidenceFromCount(sub.length)
619
+ };
620
+ }
621
+ };
622
+ var OWNERSHIP_EXTRACTOR = {
623
+ id: "ownership",
624
+ description: "Clarity of accountability \u2014 fraction of events with a known primary actor",
625
+ extract(events, domain) {
626
+ const sub = inDomain(events, domain);
627
+ if (sub.length === 0) return ZERO;
628
+ const attributed = sub.filter((e) => e.event.actor.kind !== "unknown").length;
629
+ return {
630
+ score: clamp100(attributed / sub.length * 100),
631
+ eventCount: sub.length,
632
+ confidence: confidenceFromCount(sub.length)
633
+ };
634
+ }
635
+ };
636
+ var FOLLOW_THROUGH_EXTRACTOR = {
637
+ id: "follow_through",
638
+ description: "Fraction of events that were followed up \u2014 i.e. referenced by a later event",
639
+ extract(events, domain) {
640
+ const sub = inDomain(events, domain);
641
+ if (sub.length === 0) return ZERO;
642
+ const referencedIds = /* @__PURE__ */ new Set();
643
+ for (const e of events) {
644
+ const ref = e.event.respondsTo?.eventId;
645
+ if (ref) referencedIds.add(ref);
646
+ }
647
+ const followedUp = sub.filter((e) => referencedIds.has(e.event.id)).length;
648
+ return {
649
+ score: clamp100(followedUp / sub.length * 100),
650
+ eventCount: sub.length,
651
+ confidence: confidenceFromCount(sub.length)
652
+ };
653
+ }
654
+ };
655
+ var ALIGNMENT_EXTRACTOR = {
656
+ id: "alignment",
657
+ description: "Coordination pressure \u2014 fraction of events that reference a prior event",
658
+ extract(events, domain) {
659
+ const sub = inDomain(events, domain);
660
+ if (sub.length === 0) return ZERO;
661
+ const referencing = sub.filter((e) => e.event.respondsTo !== void 0).length;
662
+ return {
663
+ score: clamp100(referencing / sub.length * 100),
664
+ eventCount: sub.length,
665
+ confidence: confidenceFromCount(sub.length)
666
+ };
667
+ }
668
+ };
669
+ var DECISION_MOMENTUM_EXTRACTOR = {
670
+ id: "decision_momentum",
671
+ description: "Rate of activity in this domain \u2014 events per day, capped at 10/day",
672
+ extract(events, domain) {
673
+ const sub = inDomain(events, domain);
674
+ if (sub.length === 0) return ZERO;
675
+ if (sub.length < 2) {
676
+ return {
677
+ score: 20,
678
+ // token non-zero score — single event = some motion
679
+ eventCount: sub.length,
680
+ confidence: confidenceFromCount(sub.length)
681
+ };
682
+ }
683
+ const ts = sub.map((e) => Date.parse(e.event.timestamp)).sort((a, b) => a - b);
684
+ const spanMs = ts[ts.length - 1] - ts[0];
685
+ const spanDays = Math.max(spanMs / (24 * 60 * 60 * 1e3), 1 / 24);
686
+ const perDay = sub.length / spanDays;
687
+ const normalized = Math.min(perDay, 10) / 10;
688
+ return {
689
+ score: clamp100(normalized * 100),
690
+ eventCount: sub.length,
691
+ confidence: confidenceFromCount(sub.length)
692
+ };
693
+ }
694
+ };
695
+ var DEFAULT_SIGNAL_EXTRACTORS = Object.freeze([
696
+ CLARITY_EXTRACTOR,
697
+ OWNERSHIP_EXTRACTOR,
698
+ FOLLOW_THROUGH_EXTRACTOR,
699
+ ALIGNMENT_EXTRACTOR,
700
+ DECISION_MOMENTUM_EXTRACTOR
701
+ ]);
702
+
703
+ // src/radiant/core/prompt.ts
704
+ function composeSystemPrompt(worldmodelContent, lens) {
705
+ const sections = [];
706
+ sections.push(
707
+ `## Worldmodel
708
+
709
+ You are operating inside a governed environment. The worldmodel below
710
+ defines the invariants, signals, decision priorities, and behavioral
711
+ expectations for this organization. Every response you produce must
712
+ be grounded in this worldmodel.
713
+
714
+ ` + worldmodelContent
715
+ );
716
+ const frame = lens.primary_frame;
717
+ const questionsBlock = frame.evaluation_questions.map((q, i) => `${i + 1}. ${q}`).join("\n");
718
+ const overlapsBlock = frame.overlaps.map(
719
+ (o) => `- ${o.domains[0]} + ${o.domains[1]} = **${o.emergent_state}**: ${o.description}`
720
+ ).join("\n");
721
+ sections.push(
722
+ `## How to Think (Analytical Frame: ${lens.name})
723
+
724
+ ${frame.scoring_rubric}
725
+
726
+ ### Evaluation questions to reason through
727
+
728
+ ${questionsBlock}
729
+
730
+ ### Overlap emergent states
731
+
732
+ ${overlapsBlock}
733
+
734
+ ### Center identity
735
+
736
+ When all dimensions integrate fully: **${frame.center_identity}**. Surface this sparingly \u2014 only when the integration is genuinely complete.`
737
+ );
738
+ const vocabPreferred = Object.entries(lens.vocabulary.preferred).map(([generic, native]) => `- "${generic}" \u2192 **${native}**`).join("\n");
739
+ const vocabArchitecture = lens.vocabulary.architecture.map((t) => `\`${t}\``).join(", ");
740
+ const vocabProperNouns = lens.vocabulary.proper_nouns.map((n) => `**${n}**`).join(", ");
741
+ const strategicBlock = lens.strategic_patterns.map((p) => `- ${p}`).join("\n");
742
+ sections.push(
743
+ `## How to Speak (Voice: ${lens.name})
744
+
745
+ Register: ${lens.voice.register}
746
+
747
+ Rules:
748
+ - Active voice: ${lens.voice.active_voice}
749
+ - Named specificity (people, places, numbers): ${lens.voice.specificity}
750
+ - Hype vocabulary: ${lens.voice.hype_vocabulary}
751
+ - Hedging / qualified phrasing: ${lens.voice.hedging}
752
+ - Playfulness: ${lens.voice.playfulness}
753
+ - Close with strategic frame: ${lens.voice.close_with_strategic_frame}
754
+ - Honesty about failure: ${lens.voice.honesty_about_failure}
755
+
756
+ ### Output translation discipline
757
+
758
+ ${lens.voice.output_translation}
759
+
760
+ ### Vocabulary
761
+
762
+ Proper nouns (use literally): ${vocabProperNouns}
763
+
764
+ Preferred term substitutions:
765
+ ${vocabPreferred}
766
+
767
+ Architecture vocabulary: ${vocabArchitecture}
768
+
769
+ ### Strategic decision patterns
770
+
771
+ When recommending action, these patterns reflect how this organization resolves tradeoffs:
772
+
773
+ ${strategicBlock}`
774
+ );
775
+ const forbiddenBlock = lens.forbidden_phrases.map((p) => `- "${p}"`).join("\n");
776
+ sections.push(
777
+ `## Guardrails
778
+
779
+ Do NOT use any of these phrases in your response. If you catch yourself
780
+ reaching for one, rephrase in direct, active, specific language instead.
781
+
782
+ ${forbiddenBlock}
783
+
784
+ If your response would violate a worldmodel invariant, state the conflict
785
+ explicitly and propose an alternative that honors the invariant.`
786
+ );
787
+ return sections.join("\n\n---\n\n");
788
+ }
789
+
790
+ // src/radiant/core/voice-check.ts
791
+ function checkForbiddenPhrases(lens, text) {
792
+ const lower = text.toLowerCase();
793
+ const violations = [];
794
+ for (const phrase of lens.forbidden_phrases) {
795
+ const phraseLower = phrase.toLowerCase();
796
+ let pos = 0;
797
+ while (true) {
798
+ const idx = lower.indexOf(phraseLower, pos);
799
+ if (idx === -1) break;
800
+ violations.push({ phrase, offset: idx });
801
+ pos = idx + phraseLower.length;
802
+ }
803
+ }
804
+ violations.sort((a, b) => a.offset - b.offset);
805
+ return violations;
806
+ }
807
+
808
+ // src/radiant/core/ai.ts
809
+ function createAnthropicAI(apiKey, model = "claude-sonnet-4-20250514", maxTokens = 4096) {
810
+ return {
811
+ async complete(systemPrompt, userQuery) {
812
+ const res = await fetch("https://api.anthropic.com/v1/messages", {
813
+ method: "POST",
814
+ headers: {
815
+ "x-api-key": apiKey,
816
+ "anthropic-version": "2023-06-01",
817
+ "content-type": "application/json"
818
+ },
819
+ body: JSON.stringify({
820
+ model,
821
+ max_tokens: maxTokens,
822
+ system: systemPrompt,
823
+ messages: [{ role: "user", content: userQuery }]
824
+ })
825
+ });
826
+ if (!res.ok) {
827
+ const body = await res.text();
828
+ throw new Error(
829
+ `Anthropic API error ${res.status}: ${body.slice(0, 500)}`
830
+ );
831
+ }
832
+ const data = await res.json();
833
+ const text = data.content?.filter((c) => c.type === "text").map((c) => c.text ?? "").join("");
834
+ if (!text) {
835
+ throw new Error("Anthropic returned no text content");
836
+ }
837
+ return text;
838
+ }
839
+ };
840
+ }
841
+ function createMockAI(fixedResponse) {
842
+ return {
843
+ async complete() {
844
+ return fixedResponse;
845
+ }
846
+ };
847
+ }
848
+
849
+ // src/radiant/core/scopes.ts
850
+ function parseRepoScope(scope) {
851
+ const cleaned = scope.replace(/^https?:\/\//, "").replace(/^github\.com\//, "").replace(/\.git$/, "").replace(/\/$/, "");
852
+ const parts = cleaned.split("/");
853
+ if (parts.length < 2 || !parts[0] || !parts[1]) {
854
+ throw new Error(
855
+ `Cannot parse repo scope: "${scope}". Expected "owner/repo" or a GitHub URL.`
856
+ );
857
+ }
858
+ return { owner: parts[0], repo: parts[1] };
859
+ }
860
+ function formatScope(scope) {
861
+ return `${scope.owner}/${scope.repo}`;
862
+ }
863
+
864
+ // src/radiant/adapters/github.ts
865
+ async function fetchGitHubActivity(scope, token, options = {}) {
866
+ const windowDays = options.windowDays ?? 14;
867
+ const perPage = options.perPage ?? 100;
868
+ const since = new Date(
869
+ Date.now() - windowDays * 24 * 60 * 60 * 1e3
870
+ ).toISOString();
871
+ const base = `https://api.github.com/repos/${formatScope(scope)}`;
872
+ const headers = {
873
+ Authorization: `token ${token}`,
874
+ Accept: "application/vnd.github.v3+json",
875
+ "User-Agent": "neuroverseos-radiant"
876
+ };
877
+ const events = [];
878
+ const [commits, prs, comments] = await Promise.all([
879
+ fetchJSON(
880
+ `${base}/commits?since=${since}&per_page=${perPage}`,
881
+ headers
882
+ ),
883
+ fetchJSON(
884
+ `${base}/pulls?state=all&sort=updated&direction=desc&per_page=${perPage}`,
885
+ headers
886
+ ),
887
+ fetchJSON(
888
+ `${base}/issues/comments?since=${since}&per_page=${perPage}&sort=updated&direction=desc`,
889
+ headers
890
+ )
891
+ ]);
892
+ for (const c of commits) {
893
+ events.push(mapCommit(c, scope));
894
+ }
895
+ const sinceDate = new Date(since);
896
+ for (const pr of prs) {
897
+ if (new Date(pr.updated_at) >= sinceDate) {
898
+ events.push(mapPR(pr, scope));
899
+ }
900
+ }
901
+ for (const comment of comments) {
902
+ events.push(mapComment(comment, scope));
903
+ }
904
+ events.sort(
905
+ (a, b) => Date.parse(a.timestamp) - Date.parse(b.timestamp)
906
+ );
907
+ return events;
908
+ }
909
+ function mapCommit(c, scope) {
910
+ const actor = mapUser(c.author, c.commit.author.name);
911
+ const coActors = extractCoAuthors(c.commit.message);
912
+ return {
913
+ id: `commit-${c.sha.slice(0, 8)}`,
914
+ timestamp: c.commit.author.date,
915
+ actor,
916
+ coActors: coActors.length > 0 ? coActors : void 0,
917
+ kind: "commit",
918
+ content: c.commit.message,
919
+ metadata: {
920
+ scope: formatScope(scope),
921
+ sha: c.sha
922
+ }
923
+ };
924
+ }
925
+ function mapPR(pr, scope) {
926
+ const event = {
927
+ id: `pr-${pr.number}`,
928
+ timestamp: pr.created_at,
929
+ actor: mapUser(pr.user),
930
+ kind: pr.merged_at ? "pr_merged" : pr.state === "open" ? "pr_opened" : "pr_closed",
931
+ content: `${pr.title}
932
+
933
+ ${pr.body ?? ""}`.trim(),
934
+ metadata: {
935
+ scope: formatScope(scope),
936
+ pr_number: pr.number,
937
+ state: pr.state,
938
+ merged_at: pr.merged_at
939
+ }
940
+ };
941
+ if (pr.merged_by && pr.merged_by.login !== pr.user.login) {
942
+ event.actor = mapUser(pr.merged_by);
943
+ event.kind = "pr_merged";
944
+ event.timestamp = pr.merged_at ?? pr.updated_at;
945
+ event.respondsTo = {
946
+ eventId: `pr-${pr.number}-opened`,
947
+ actor: mapUser(pr.user)
948
+ };
949
+ }
950
+ return event;
951
+ }
952
+ function mapComment(comment, scope) {
953
+ const issueMatch = comment.issue_url.match(/\/issues\/(\d+)$/);
954
+ const issueNumber = issueMatch ? issueMatch[1] : "unknown";
955
+ const event = {
956
+ id: `comment-${comment.id}`,
957
+ timestamp: comment.created_at,
958
+ actor: mapUser(comment.user),
959
+ kind: "comment",
960
+ content: comment.body,
961
+ respondsTo: {
962
+ eventId: `pr-${issueNumber}`,
963
+ actor: { id: "unknown", kind: "unknown" }
964
+ },
965
+ metadata: {
966
+ scope: formatScope(scope),
967
+ issue_number: issueNumber
968
+ }
969
+ };
970
+ return event;
971
+ }
972
+ var KNOWN_AI_LOGINS = /* @__PURE__ */ new Set([
973
+ "github-actions[bot]",
974
+ "dependabot[bot]",
975
+ "renovate[bot]",
976
+ "copilot"
977
+ ]);
978
+ var KNOWN_AI_CO_AUTHOR_NAMES = /* @__PURE__ */ new Set([
979
+ "claude",
980
+ "copilot",
981
+ "cursor",
982
+ "codeium",
983
+ "tabnine",
984
+ "codex"
985
+ ]);
986
+ function mapUser(ghUser, fallbackName) {
987
+ if (!ghUser) {
988
+ return {
989
+ id: fallbackName ?? "unknown",
990
+ kind: "unknown",
991
+ name: fallbackName
992
+ };
993
+ }
994
+ let kind = "human";
995
+ if (ghUser.type === "Bot" || ghUser.login.endsWith("[bot]")) {
996
+ kind = "bot";
997
+ }
998
+ if (KNOWN_AI_LOGINS.has(ghUser.login.toLowerCase())) {
999
+ kind = "bot";
1000
+ }
1001
+ return {
1002
+ id: ghUser.login,
1003
+ kind,
1004
+ name: ghUser.login
1005
+ };
1006
+ }
1007
+ function extractCoAuthors(message) {
1008
+ const coAuthors = [];
1009
+ const lines = message.split("\n");
1010
+ for (const line of lines) {
1011
+ const match = line.match(
1012
+ /^Co-authored-by:\s*(.+?)\s*<([^>]*)>/i
1013
+ );
1014
+ if (match) {
1015
+ const name = match[1].trim().toLowerCase();
1016
+ const isAI = KNOWN_AI_CO_AUTHOR_NAMES.has(name) || [...KNOWN_AI_CO_AUTHOR_NAMES].some((ai) => name.includes(ai));
1017
+ coAuthors.push({
1018
+ id: match[2] || name,
1019
+ kind: isAI ? "ai" : "human",
1020
+ name: match[1].trim()
1021
+ });
1022
+ }
1023
+ }
1024
+ return coAuthors;
1025
+ }
1026
+ async function fetchJSON(url, headers) {
1027
+ const res = await fetch(url, { headers });
1028
+ if (!res.ok) {
1029
+ if (res.status === 404) return [];
1030
+ if (res.status === 403) {
1031
+ const body = await res.text();
1032
+ if (body.includes("rate limit")) {
1033
+ throw new Error(
1034
+ `GitHub API rate limit exceeded. Wait or use a token with higher limits.`
1035
+ );
1036
+ }
1037
+ }
1038
+ throw new Error(
1039
+ `GitHub API error ${res.status} for ${url}: ${(await res.text()).slice(0, 300)}`
1040
+ );
1041
+ }
1042
+ return await res.json();
1043
+ }
1044
+ function createMockGitHubAdapter(fixedEvents) {
1045
+ return async () => fixedEvents;
1046
+ }
1047
+
1048
+ // src/radiant/adapters/exocortex.ts
1049
+ var import_fs = require("fs");
1050
+ var import_path = require("path");
1051
+ function readExocortex(dirPath) {
1052
+ const dir = (0, import_path.resolve)(dirPath);
1053
+ let filesLoaded = 0;
1054
+ function tryRead(...paths) {
1055
+ for (const p of paths) {
1056
+ const full = (0, import_path.join)(dir, p);
1057
+ if ((0, import_fs.existsSync)(full)) {
1058
+ try {
1059
+ const content = (0, import_fs.readFileSync)(full, "utf-8").trim();
1060
+ if (content) {
1061
+ filesLoaded++;
1062
+ return content;
1063
+ }
1064
+ } catch {
1065
+ }
1066
+ }
1067
+ }
1068
+ return null;
1069
+ }
1070
+ const ctx = {
1071
+ attention: tryRead("attention.md"),
1072
+ goals: tryRead("goals.md"),
1073
+ identity: tryRead("identity.md"),
1074
+ sprint: tryRead("sprint.md", "src/sprint.md"),
1075
+ organization: tryRead("org/organization.md", "org/src/organization.md"),
1076
+ methods: tryRead("org/methods.md", "org/src/methods.md"),
1077
+ source: dir,
1078
+ filesLoaded
1079
+ };
1080
+ return ctx;
1081
+ }
1082
+ function formatExocortexForPrompt(ctx) {
1083
+ if (ctx.filesLoaded === 0) return "";
1084
+ const sections = [];
1085
+ sections.push(
1086
+ "## Stated Intent (from exocortex)\n\nThe following is what the person/team SAYS they are doing, focused on, and working toward. Compare this against the ACTUAL activity from GitHub. Where stated intent and observed behavior diverge, that gap is the most valuable signal in this read. Name it directly."
1087
+ );
1088
+ if (ctx.attention) {
1089
+ sections.push(`### Current attention
1090
+
1091
+ ${ctx.attention}`);
1092
+ }
1093
+ if (ctx.goals) {
1094
+ sections.push(`### Goals
1095
+
1096
+ ${ctx.goals}`);
1097
+ }
1098
+ if (ctx.sprint) {
1099
+ sections.push(`### Sprint focus
1100
+
1101
+ ${ctx.sprint}`);
1102
+ }
1103
+ if (ctx.identity) {
1104
+ sections.push(`### Identity and values
1105
+
1106
+ ${ctx.identity}`);
1107
+ }
1108
+ if (ctx.organization) {
1109
+ sections.push(`### Organization
1110
+
1111
+ ${ctx.organization}`);
1112
+ }
1113
+ if (ctx.methods) {
1114
+ sections.push(`### Methods
1115
+
1116
+ ${ctx.methods}`);
1117
+ }
1118
+ return sections.join("\n\n");
1119
+ }
1120
+ function summarizeExocortex(ctx) {
1121
+ if (ctx.filesLoaded === 0) return "no exocortex files found";
1122
+ const loaded = [];
1123
+ if (ctx.attention) loaded.push("attention");
1124
+ if (ctx.goals) loaded.push("goals");
1125
+ if (ctx.sprint) loaded.push("sprint");
1126
+ if (ctx.identity) loaded.push("identity");
1127
+ if (ctx.organization) loaded.push("org");
1128
+ if (ctx.methods) loaded.push("methods");
1129
+ return `${loaded.join(", ")} (${ctx.filesLoaded} files)`;
1130
+ }
1131
+
1132
+ // src/radiant/core/patterns.ts
1133
+ async function interpretPatterns(input) {
1134
+ const prompt = buildInterpretationPrompt(input);
1135
+ const raw = await input.ai.complete(prompt, "Analyze the activity and produce the read.");
1136
+ const parsed = parseInterpretation(raw, input.canonicalPatterns ?? []);
1137
+ return {
1138
+ patterns: parsed.patterns,
1139
+ meaning: parsed.meaning,
1140
+ move: parsed.move,
1141
+ raw_ai_response: raw
1142
+ };
1143
+ }
1144
+ function buildInterpretationPrompt(input) {
1145
+ const signalSummary = formatSignalSummary(input.signals);
1146
+ const eventSample = formatEventSample(input.events, 30);
1147
+ const canonicalList = (input.canonicalPatterns ?? []).length > 0 ? `Patterns the organization has already named (use these names if you see them):
1148
+ ${input.canonicalPatterns.map((p) => `- ${p}`).join("\n")}` : "No patterns have been named yet. Everything you observe is new.";
1149
+ const frame = input.lens.primary_frame;
1150
+ const evalQuestions = frame.evaluation_questions.map((q, i) => `${i + 1}. ${q}`).join("\n");
1151
+ const forbiddenList = input.lens.forbidden_phrases.map((p) => `- "${p}"`).join("\n");
1152
+ const jargonTable = Object.entries(input.lens.vocabulary.jargon_translations).map(([internal, plain]) => ` "${internal}" \u2192 "${plain}"`).join("\n");
1153
+ return `You are a behavioral intelligence system reading team activity and producing a read for the reader who needs to act on it.
1154
+
1155
+ ## Context the reader has loaded
1156
+
1157
+ ${input.worldmodelContent}
1158
+
1159
+ ## What happened this window
1160
+
1161
+ ### Signal matrix (what Radiant measured)
1162
+
1163
+ ${signalSummary}
1164
+
1165
+ ### Recent events (sample)
1166
+
1167
+ ${eventSample}
1168
+
1169
+ ## How to reason
1170
+
1171
+ Reason through these questions INTERNALLY \u2014 do not list them in your output:
1172
+
1173
+ ${evalQuestions}
1174
+
1175
+ Scoring rubric: ${frame.scoring_rubric}
1176
+
1177
+ ${canonicalList}
1178
+
1179
+ ${input.statedIntent ? input.statedIntent + "\n" : ""}## Voice: speak like an Auki builder, not like a status report
1180
+
1181
+ The reader wants to know **what this means and what to do**, not "what happened." Frame every observation as consequence + implication, not just description.
1182
+
1183
+ Wrong voice (status report):
1184
+ "Rapid deployment of complex technical architecture through composable commits."
1185
+ "Signal extraction across life, cyber, and joint domains enables consistent behavioral analysis."
1186
+ "Decision momentum scores suggest architectural delivery without corresponding strategic direction setting."
1187
+
1188
+ Right voice (Auki builder):
1189
+ "Shipping pace is high. The architecture is getting ahead of strategic decisions \u2014 velocity without a declared target."
1190
+ "Every pattern is new. Nothing is being tracked by name yet. That's fine for now; it becomes a problem when patterns repeat and you still don't have vocabulary for them."
1191
+ "The work is converging across three modules. The story of HOW they compose isn't being told yet."
1192
+
1193
+ The difference: consequence in plain English, not observation in system vocabulary.
1194
+
1195
+ ## Translate internal jargon to plain English
1196
+
1197
+ Readers don't know Radiant's vocabulary. Before ANY description appears in your output, translate these:
1198
+
1199
+ ${jargonTable}
1200
+
1201
+ For example: don't say "update the worldmodel." Say "add a line to your strategy file."
1202
+
1203
+ ## Health is a valid read
1204
+
1205
+ 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:
1206
+
1207
+ "Nothing's broken. Keep shipping."
1208
+ "This is what healthy looks like \u2014 the invariants are holding."
1209
+ "Nothing here needs action."
1210
+
1211
+ Only recommend a move when the evidence actually calls for one.
1212
+
1213
+ ## Output schema \u2014 JSON object
1214
+
1215
+ \`\`\`json
1216
+ {
1217
+ "patterns": [
1218
+ {
1219
+ "name": "pattern_name_snake_case",
1220
+ "type": "canonical" | "candidate",
1221
+ "description": "Consequence-framed, plain-English, 1-2 sentences. The reader understands why this matters, not just what you observed.",
1222
+ "evidence": {
1223
+ "signals": ["signal_id.domain", ...],
1224
+ "events": ["event_id", ...],
1225
+ "cited_invariant": "invariant_name_or_null"
1226
+ },
1227
+ "confidence": 0.0 to 1.0
1228
+ }
1229
+ ],
1230
+ "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.",
1231
+ "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."
1232
+ }
1233
+ \`\`\`
1234
+
1235
+ ## Hard rules
1236
+
1237
+ - Every signal you cite MUST appear in the signal matrix above
1238
+ - Every event you cite MUST appear in the events sample above
1239
+ - Do not invent signals or events that aren't in the data
1240
+ - Candidate patterns must have type "candidate"
1241
+ - No hedging, no hype vocabulary
1242
+ - Apply jargon translation before output
1243
+ - Health-is-valid \u2014 don't invent problems
1244
+ - Return ONLY the JSON object, no other text
1245
+
1246
+ Do NOT use these phrases anywhere in your output:
1247
+ ${forbiddenList}`;
1248
+ }
1249
+ function formatSignalSummary(signals) {
1250
+ const lines = [];
1251
+ const domains = ["life", "cyber", "joint"];
1252
+ for (const domain of domains) {
1253
+ const domainSignals = signals.filter((s) => s.domain === domain);
1254
+ if (domainSignals.length === 0) continue;
1255
+ lines.push(`### ${domain}`);
1256
+ for (const s of domainSignals) {
1257
+ const gate = s.eventCount >= 3 && s.confidence >= 0.5 ? "\u2713" : "\u25CB";
1258
+ lines.push(
1259
+ ` ${gate} ${s.id}: score=${s.score.toFixed(1)}, events=${s.eventCount}, conf=${s.confidence.toFixed(2)}`
1260
+ );
1261
+ }
1262
+ }
1263
+ return lines.join("\n");
1264
+ }
1265
+ function formatEventSample(events, maxEvents) {
1266
+ const sample = events.slice(-maxEvents);
1267
+ return sample.map((e) => {
1268
+ const content = (e.event.content ?? "").slice(0, 200);
1269
+ const respondsTo = e.event.respondsTo ? ` (responds to ${e.event.respondsTo.eventId})` : "";
1270
+ return `- [${e.domain}] ${e.event.id} | ${e.event.actor.kind}:${e.event.actor.id} | ${e.event.kind ?? "event"}${respondsTo}
1271
+ "${content}"`;
1272
+ }).join("\n");
1273
+ }
1274
+ function parseInterpretation(raw, canonicalNames) {
1275
+ let meaning = "";
1276
+ let move = "";
1277
+ let patternsArray = [];
1278
+ const objMatch = raw.match(/\{[\s\S]*"patterns"[\s\S]*\}/);
1279
+ if (objMatch) {
1280
+ try {
1281
+ const obj = JSON.parse(objMatch[0]);
1282
+ if (Array.isArray(obj.patterns)) {
1283
+ patternsArray = obj.patterns;
1284
+ }
1285
+ if (typeof obj.meaning === "string") meaning = obj.meaning;
1286
+ if (typeof obj.move === "string") move = obj.move;
1287
+ } catch {
1288
+ }
1289
+ }
1290
+ if (patternsArray.length === 0) {
1291
+ const arrMatch = raw.match(/\[[\s\S]*\]/);
1292
+ if (arrMatch) {
1293
+ try {
1294
+ const arr = JSON.parse(arrMatch[0]);
1295
+ if (Array.isArray(arr)) patternsArray = arr;
1296
+ } catch {
1297
+ }
1298
+ }
1299
+ }
1300
+ const canonicalSet = new Set(canonicalNames.map((n) => n.toLowerCase()));
1301
+ const patterns = [];
1302
+ for (const item of patternsArray) {
1303
+ if (!isPatternLike(item)) continue;
1304
+ const nameStr = String(item.name ?? "unnamed");
1305
+ const ev = item.evidence;
1306
+ const isCanonical = item.type === "canonical" || canonicalSet.has(nameStr.toLowerCase());
1307
+ patterns.push({
1308
+ name: nameStr,
1309
+ type: isCanonical ? "canonical" : "candidate",
1310
+ declaredAs: isCanonical ? nameStr : void 0,
1311
+ description: String(item.description ?? ""),
1312
+ evidence: {
1313
+ signals: Array.isArray(ev?.signals) ? ev.signals.map(String) : [],
1314
+ events: Array.isArray(ev?.events) ? ev.events.map(String) : [],
1315
+ cited_invariant: ev?.cited_invariant ? String(ev.cited_invariant) : void 0
1316
+ },
1317
+ confidence: typeof item.confidence === "number" ? Math.max(0, Math.min(1, item.confidence)) : 0.5
1318
+ });
1319
+ }
1320
+ return { patterns, meaning, move };
1321
+ }
1322
+ function isPatternLike(x) {
1323
+ return typeof x === "object" && x !== null && "name" in x;
1324
+ }
1325
+
1326
+ // src/radiant/core/renderer.ts
1327
+ function render(input) {
1328
+ const text = renderText(input);
1329
+ const frontmatter = renderFrontmatter(input);
1330
+ return { text, frontmatter };
1331
+ }
1332
+ function renderText(input) {
1333
+ const sections = [];
1334
+ sections.push(
1335
+ `Scope: ${formatScope(input.scope)}
1336
+ Window: last ${input.windowDays} days \xB7 ${input.eventCount} events
1337
+ Lens: ${input.lens.name}`
1338
+ );
1339
+ if (input.patterns.length > 0) {
1340
+ const canonical = input.patterns.filter((p) => p.type === "canonical");
1341
+ const candidates = input.patterns.filter((p) => p.type === "candidate");
1342
+ let emergentBlock = "EMERGENT\n";
1343
+ if (canonical.length > 0) {
1344
+ for (const p of canonical) {
1345
+ emergentBlock += `
1346
+ ${p.name}
1347
+ `;
1348
+ emergentBlock += ` ${p.description}
1349
+ `;
1350
+ }
1351
+ }
1352
+ if (candidates.length > 0) {
1353
+ emergentBlock += "\n Emergent (candidates \u2014 not yet in worldmodel)\n";
1354
+ for (const p of candidates) {
1355
+ emergentBlock += `
1356
+ ${p.name} (candidate)
1357
+ `;
1358
+ emergentBlock += ` ${p.description}
1359
+ `;
1360
+ if (p.evidence.cited_invariant) {
1361
+ emergentBlock += ` Cited invariant: ${p.evidence.cited_invariant}
1362
+ `;
1363
+ }
1364
+ }
1365
+ }
1366
+ sections.push(emergentBlock.trimEnd());
1367
+ }
1368
+ if (input.meaning) {
1369
+ sections.push(`MEANING
1370
+
1371
+ ${input.meaning.split("\n").join("\n ")}`);
1372
+ }
1373
+ if (input.move) {
1374
+ sections.push(`MOVE
1375
+
1376
+ ${input.move.split("\n").join("\n ")}`);
1377
+ }
1378
+ const alignBlock = [
1379
+ "ALIGNMENT",
1380
+ "",
1381
+ ` Human work: ${formatScore(input.scores.A_L)}`,
1382
+ ` AI work: ${formatScore(input.scores.A_C)}`,
1383
+ ` Human\u2013AI collaboration: ${formatScore(input.scores.A_N)}`,
1384
+ ` Composite: ${formatScore(input.scores.R)}`
1385
+ ].join("\n");
1386
+ sections.push(alignBlock);
1387
+ if (input.governance && input.governance.totalEvents > 0) {
1388
+ const gov = input.governance;
1389
+ const govLines = ["GOVERNANCE", "", ` ${gov.summary}`];
1390
+ const showSide = (label, side) => {
1391
+ if (side.allow + side.modify + side.block === 0) return;
1392
+ govLines.push("");
1393
+ govLines.push(` ${label}:`);
1394
+ govLines.push(` ${side.allow} ALLOW \xB7 ${side.modify} MODIFY \xB7 ${side.block} BLOCK`);
1395
+ for (const d of side.details.slice(0, 3)) {
1396
+ const reason = d.reason ? ` \u2192 ${d.reason}` : "";
1397
+ govLines.push(` ${d.status}: ${d.eventId}${reason}`);
1398
+ }
1399
+ if (side.details.length > 3) {
1400
+ govLines.push(` ... and ${side.details.length - 3} more`);
1401
+ }
1402
+ };
1403
+ showSide("Human side", gov.human);
1404
+ showSide("AI side", gov.cyber);
1405
+ showSide("Human\u2013AI joint", gov.joint);
1406
+ sections.push(govLines.join("\n"));
1407
+ }
1408
+ sections.push(renderDepth(input.priorReadCount ?? 0, input.windowDays));
1409
+ return sections.join("\n\n");
1410
+ }
1411
+ function renderDepth(priorReads, windowDays) {
1412
+ if (priorReads === 0) {
1413
+ return [
1414
+ "DEPTH",
1415
+ "",
1416
+ ` This is your first read. Radiant sees ${windowDays} days of activity`,
1417
+ " but has no prior baseline to compare against.",
1418
+ "",
1419
+ " Available now:",
1420
+ " \u2713 Signal extraction across life / cyber / joint domains",
1421
+ " \u2713 Pattern identification (canonical + candidates)",
1422
+ " \u2713 Alignment scoring",
1423
+ "",
1424
+ " Available after 2+ reads:",
1425
+ " \xB7 Drift detection (is alignment improving or degrading?)",
1426
+ ' \xB7 Baselines (what does "normal" look like for this team?)',
1427
+ " \xB7 Pattern confidence (are these patterns persistent or noise?)",
1428
+ " \xB7 Evolution proposals (should the worldmodel adapt?)",
1429
+ "",
1430
+ " Run again next week. The read gets sharper every time."
1431
+ ].join("\n");
1432
+ }
1433
+ if (priorReads < 4) {
1434
+ return [
1435
+ "DEPTH",
1436
+ "",
1437
+ ` Read ${priorReads + 1} of this scope. Baseline forming.`,
1438
+ "",
1439
+ " Available now:",
1440
+ " \u2713 Signal extraction + pattern identification + alignment scoring",
1441
+ ` \u2713 Drift detection (comparing against ${priorReads} prior read${priorReads > 1 ? "s" : ""})`,
1442
+ " \xB7 Baselines stabilizing (need 4+ reads for reliable averages)",
1443
+ " \xB7 Pattern confidence accumulating",
1444
+ "",
1445
+ " The read sharpens with each run."
1446
+ ].join("\n");
1447
+ }
1448
+ return [
1449
+ "DEPTH",
1450
+ "",
1451
+ ` Read ${priorReads + 1} of this scope. Baseline established.`,
1452
+ "",
1453
+ " Available:",
1454
+ " \u2713 Signal extraction + pattern identification + alignment scoring",
1455
+ " \u2713 Drift detection against established baseline",
1456
+ " \u2713 Pattern confidence (persistent vs noise)",
1457
+ " \u2713 Evolution proposals (candidate patterns with enough history to evaluate)"
1458
+ ].join("\n");
1459
+ }
1460
+ function formatScore(s) {
1461
+ if (!isScored(s)) {
1462
+ if (s === "UNAVAILABLE") return "not available (no worldmodel loaded)";
1463
+ return "not enough signal to call yet";
1464
+ }
1465
+ const n = Math.round(s);
1466
+ let label;
1467
+ if (n >= 75) label = "STRONG";
1468
+ else if (n >= 60) label = "STABLE";
1469
+ else if (n >= 45) label = "needs attention";
1470
+ else if (n >= 30) label = "concerning";
1471
+ else label = "critical";
1472
+ return `${n} \xB7 ${label}`;
1473
+ }
1474
+ function renderFrontmatter(input) {
1475
+ const now = (/* @__PURE__ */ new Date()).toISOString();
1476
+ const signalsByDomain = groupSignalsByDomain(input.signals);
1477
+ const patternEntries = input.patterns.map((p) => {
1478
+ const entry = {
1479
+ name: p.name,
1480
+ type: p.type,
1481
+ conf: Number(p.confidence.toFixed(2)),
1482
+ evidence_signals: p.evidence.signals,
1483
+ evidence_events: p.evidence.events
1484
+ };
1485
+ if (p.evidence.cited_invariant) {
1486
+ entry.cited_invariant = p.evidence.cited_invariant;
1487
+ }
1488
+ return entry;
1489
+ });
1490
+ const frontmatter = {
1491
+ radiant_read: {
1492
+ scope: formatScope(input.scope),
1493
+ window: `${input.windowDays}d`,
1494
+ timestamp: now,
1495
+ lens: input.lens.name
1496
+ },
1497
+ events: {
1498
+ total: input.eventCount
1499
+ },
1500
+ signals: signalsByDomain,
1501
+ scores: {
1502
+ A_L: isScored(input.scores.A_L) ? Math.round(input.scores.A_L) : String(input.scores.A_L),
1503
+ A_C: isScored(input.scores.A_C) ? Math.round(input.scores.A_C) : String(input.scores.A_C),
1504
+ A_N: isScored(input.scores.A_N) ? Math.round(input.scores.A_N) : String(input.scores.A_N),
1505
+ R: isScored(input.scores.R) ? Math.round(input.scores.R) : String(input.scores.R)
1506
+ },
1507
+ patterns: patternEntries
1508
+ };
1509
+ return "---\n" + serializeYAML(frontmatter) + "---";
1510
+ }
1511
+ function groupSignalsByDomain(signals) {
1512
+ const result = {};
1513
+ for (const s of signals) {
1514
+ if (!result[s.domain]) result[s.domain] = {};
1515
+ result[s.domain][s.id] = {
1516
+ score: Number(s.score.toFixed(1)),
1517
+ n: s.eventCount,
1518
+ conf: Number(s.confidence.toFixed(2))
1519
+ };
1520
+ }
1521
+ return result;
1522
+ }
1523
+ function serializeYAML(obj, indent = 0) {
1524
+ const pad = " ".repeat(indent);
1525
+ if (obj === null || obj === void 0) return "null\n";
1526
+ if (typeof obj === "string") return `${JSON.stringify(obj)}
1527
+ `;
1528
+ if (typeof obj === "number" || typeof obj === "boolean") return `${obj}
1529
+ `;
1530
+ if (Array.isArray(obj)) {
1531
+ if (obj.length === 0) return "[]\n";
1532
+ if (obj.every((item) => typeof item === "string" || typeof item === "number")) {
1533
+ return `[${obj.map((item) => JSON.stringify(item)).join(", ")}]
1534
+ `;
1535
+ }
1536
+ let result = "\n";
1537
+ for (const item of obj) {
1538
+ if (typeof item === "object" && item !== null && !Array.isArray(item)) {
1539
+ const entries = Object.entries(item);
1540
+ result += `${pad}- ${entries[0][0]}: ${serializeYAML(entries[0][1], 0).trim()}
1541
+ `;
1542
+ for (let i = 1; i < entries.length; i++) {
1543
+ result += `${pad} ${entries[i][0]}: ${serializeYAML(entries[i][1], indent + 2).trim()}
1544
+ `;
1545
+ }
1546
+ } else {
1547
+ result += `${pad}- ${serializeYAML(item, indent + 1).trim()}
1548
+ `;
1549
+ }
1550
+ }
1551
+ return result;
1552
+ }
1553
+ if (typeof obj === "object") {
1554
+ const entries = Object.entries(obj);
1555
+ if (entries.length === 0) return "{}\n";
1556
+ let result = "\n";
1557
+ for (const [key, value] of entries) {
1558
+ if (typeof value === "object" && value !== null) {
1559
+ result += `${pad}${key}:${serializeYAML(value, indent + 1)}`;
1560
+ } else {
1561
+ result += `${pad}${key}: ${serializeYAML(value, indent).trim()}
1562
+ `;
1563
+ }
1564
+ }
1565
+ return result;
1566
+ }
1567
+ return `${obj}
1568
+ `;
1569
+ }
1570
+
1571
+ // src/engine/text-utils.ts
1572
+ function normalizeEventText(event) {
1573
+ return [
1574
+ event.intent,
1575
+ event.tool ?? "",
1576
+ event.scope ?? ""
1577
+ ].join(" ").toLowerCase();
1578
+ }
1579
+ function extractKeywords(text, minLength = 3) {
1580
+ return text.toLowerCase().split(/\s+/).filter((w) => w.length > minLength);
1581
+ }
1582
+ function matchesAllKeywords(eventText, ruleText) {
1583
+ const keywords = extractKeywords(ruleText);
1584
+ if (keywords.length === 0) return false;
1585
+ return keywords.every((kw) => eventText.includes(kw));
1586
+ }
1587
+ function matchesKeywordThreshold(eventText, ruleText, threshold = 0.5) {
1588
+ const keywords = extractKeywords(ruleText);
1589
+ if (keywords.length === 0) return false;
1590
+ const matched = keywords.filter((kw) => eventText.includes(kw));
1591
+ return matched.length >= Math.ceil(keywords.length * threshold);
1592
+ }
1593
+ function tokenSimilarity(a, b) {
1594
+ const tokensA = new Set(a.toLowerCase().split(/\s+/).filter((w) => w.length > 2));
1595
+ const tokensB = new Set(b.toLowerCase().split(/\s+/).filter((w) => w.length > 2));
1596
+ if (tokensA.size === 0 || tokensB.size === 0) return 0;
1597
+ let intersection = 0;
1598
+ for (const t of tokensA) {
1599
+ if (tokensB.has(t)) intersection++;
1600
+ }
1601
+ const union = (/* @__PURE__ */ new Set([...tokensA, ...tokensB])).size;
1602
+ return union > 0 ? intersection / union : 0;
1603
+ }
1604
+
1605
+ // src/engine/plan-engine.ts
1606
+ function keywordMatch(eventText, step) {
1607
+ const stepText = [
1608
+ step.label,
1609
+ step.description ?? "",
1610
+ ...step.tags ?? []
1611
+ ].join(" ");
1612
+ return matchesKeywordThreshold(eventText, stepText, 0.5);
1613
+ }
1614
+ function tokenSimilarity2(a, b) {
1615
+ return tokenSimilarity(a, b);
1616
+ }
1617
+ function findMatchingStep(eventText, event, steps) {
1618
+ const pendingOrActive = steps.filter((s) => s.status === "pending" || s.status === "active");
1619
+ if (pendingOrActive.length === 0) {
1620
+ return { matched: null, closest: null, closestScore: 0 };
1621
+ }
1622
+ for (const step of pendingOrActive) {
1623
+ if (keywordMatch(eventText, step)) {
1624
+ if (step.tools && event.tool && !step.tools.includes(event.tool)) {
1625
+ continue;
1626
+ }
1627
+ return { matched: step, closest: step, closestScore: 1 };
1628
+ }
1629
+ }
1630
+ const intentText = [event.intent, event.tool ?? "", event.scope ?? ""].join(" ");
1631
+ let bestStep = null;
1632
+ let bestScore = 0;
1633
+ for (const step of pendingOrActive) {
1634
+ const stepText = [step.label, step.description ?? "", ...step.tags ?? []].join(" ");
1635
+ const score = tokenSimilarity2(intentText, stepText);
1636
+ if (score > bestScore) {
1637
+ bestScore = score;
1638
+ bestStep = step;
1639
+ }
1640
+ }
1641
+ const SIMILARITY_THRESHOLD = 0.35;
1642
+ if (bestScore >= SIMILARITY_THRESHOLD && bestStep) {
1643
+ if (bestStep.tools && event.tool && !bestStep.tools.includes(event.tool)) {
1644
+ return { matched: null, closest: bestStep, closestScore: bestScore };
1645
+ }
1646
+ return { matched: bestStep, closest: bestStep, closestScore: bestScore };
1647
+ }
1648
+ return { matched: null, closest: bestStep, closestScore: bestScore };
1649
+ }
1650
+ function isSequenceValid(step, plan) {
1651
+ if (!plan.sequential) return true;
1652
+ if (!step.requires || step.requires.length === 0) return true;
1653
+ return step.requires.every((reqId) => {
1654
+ const reqStep = plan.steps.find((s) => s.id === reqId);
1655
+ return reqStep?.status === "completed";
1656
+ });
1657
+ }
1658
+ function checkConstraints(event, eventText, constraints) {
1659
+ const checks = [];
1660
+ for (const constraint of constraints) {
1661
+ if (constraint.type === "approval") {
1662
+ if (constraint.trigger && eventText.includes(constraint.trigger.substring(0, 10).toLowerCase())) {
1663
+ checks.push({ constraintId: constraint.id, passed: false, reason: constraint.description });
1664
+ return { violated: constraint, checks };
1665
+ }
1666
+ const keywords = constraint.description.toLowerCase().split(/\s+/).filter((w) => w.length > 3);
1667
+ const relevant = keywords.some((kw) => eventText.includes(kw));
1668
+ if (relevant) {
1669
+ checks.push({ constraintId: constraint.id, passed: false, reason: constraint.description });
1670
+ return { violated: constraint, checks };
1671
+ }
1672
+ checks.push({ constraintId: constraint.id, passed: true });
1673
+ continue;
1674
+ }
1675
+ if (constraint.type === "scope" && constraint.trigger) {
1676
+ const keywords = extractKeywords(constraint.trigger);
1677
+ const violated = keywords.length > 0 && keywords.every((kw) => eventText.includes(kw));
1678
+ checks.push({
1679
+ constraintId: constraint.id,
1680
+ passed: !violated,
1681
+ reason: violated ? constraint.description : void 0
1682
+ });
1683
+ if (violated) {
1684
+ return { violated: constraint, checks };
1685
+ }
1686
+ continue;
1687
+ }
1688
+ checks.push({ constraintId: constraint.id, passed: true });
1689
+ }
1690
+ return { violated: null, checks };
1691
+ }
1692
+ function getPlanProgress(plan) {
1693
+ const completed = plan.steps.filter((s) => s.status === "completed").length;
1694
+ const total = plan.steps.length;
1695
+ return {
1696
+ completed,
1697
+ total,
1698
+ percentage: total > 0 ? Math.round(completed / total * 100) : 0
1699
+ };
1700
+ }
1701
+ function evaluatePlan(event, plan) {
1702
+ const progress = getPlanProgress(plan);
1703
+ if (plan.expires_at) {
1704
+ const expiresAt = new Date(plan.expires_at).getTime();
1705
+ if (Date.now() > expiresAt) {
1706
+ return {
1707
+ allowed: true,
1708
+ status: "PLAN_COMPLETE",
1709
+ reason: "Plan has expired.",
1710
+ progress
1711
+ };
1712
+ }
1713
+ }
1714
+ if (progress.completed === progress.total) {
1715
+ return {
1716
+ allowed: true,
1717
+ status: "PLAN_COMPLETE",
1718
+ reason: "All plan steps are completed.",
1719
+ progress
1720
+ };
1721
+ }
1722
+ const eventText = normalizeEventText(event);
1723
+ const { matched, closest, closestScore } = findMatchingStep(eventText, event, plan.steps);
1724
+ if (!matched) {
1725
+ return {
1726
+ allowed: false,
1727
+ status: "OFF_PLAN",
1728
+ reason: "Action does not match any plan step.",
1729
+ closestStep: closest?.label,
1730
+ similarityScore: closestScore,
1731
+ progress
1732
+ };
1733
+ }
1734
+ if (!isSequenceValid(matched, plan)) {
1735
+ const pendingDeps = (matched.requires ?? []).filter((reqId) => plan.steps.find((s) => s.id === reqId)?.status !== "completed").join(", ");
1736
+ return {
1737
+ allowed: false,
1738
+ status: "OFF_PLAN",
1739
+ reason: `Step "${matched.label}" requires completion of: ${pendingDeps}`,
1740
+ matchedStep: matched.id,
1741
+ progress
1742
+ };
1743
+ }
1744
+ const { violated } = checkConstraints(event, eventText, plan.constraints);
1745
+ if (violated) {
1746
+ return {
1747
+ allowed: false,
1748
+ status: "CONSTRAINT_VIOLATED",
1749
+ reason: violated.description,
1750
+ matchedStep: matched.id,
1751
+ progress
1752
+ };
1753
+ }
1754
+ return {
1755
+ allowed: true,
1756
+ status: "ON_PLAN",
1757
+ reason: `Matches step: ${matched.label}`,
1758
+ matchedStep: matched.id,
1759
+ progress
1760
+ };
1761
+ }
1762
+ function buildPlanCheck(event, plan, verdict) {
1763
+ const eventText = normalizeEventText(event);
1764
+ const { matched, closest, closestScore } = findMatchingStep(eventText, event, plan.steps);
1765
+ const { checks: constraintChecks } = checkConstraints(event, eventText, plan.constraints);
1766
+ const progress = getPlanProgress(plan);
1767
+ return {
1768
+ planId: plan.plan_id,
1769
+ matched: !!matched,
1770
+ matchedStepId: matched?.id,
1771
+ matchedStepLabel: matched?.label,
1772
+ closestStepId: !matched ? closest?.id : void 0,
1773
+ closestStepLabel: !matched ? closest?.label : void 0,
1774
+ similarityScore: !matched ? closestScore : void 0,
1775
+ sequenceValid: matched ? isSequenceValid(matched, plan) : void 0,
1776
+ constraintsChecked: constraintChecks,
1777
+ progress: { completed: progress.completed, total: progress.total }
1778
+ };
1779
+ }
1780
+
1781
+ // src/engine/guard-engine.ts
1782
+ var PROMPT_INJECTION_PATTERNS = [
1783
+ // Instruction override
1784
+ { pattern: /ignore\s+(previous|all|prior|above)\s+(instructions?|rules?)/i, label: "ignore-instructions" },
1785
+ { pattern: /disregard\s+(your|the)\s+(rules|constraints)/i, label: "disregard-rules" },
1786
+ { pattern: /new\s+instructions?:/i, label: "new-instructions" },
1787
+ // Identity manipulation
1788
+ { pattern: /you\s+are\s+now/i, label: "identity-override" },
1789
+ { pattern: /new\s+persona/i, label: "new-persona" },
1790
+ { pattern: /act\s+as\s+if/i, label: "act-as-if" },
1791
+ { pattern: /pretend\s+(you|to\s+be|you\s+are\s+unrestricted)/i, label: "pretend-to-be" },
1792
+ // Context reset
1793
+ { pattern: /forget\s+(everything|all|your)/i, label: "forget-context" },
1794
+ { pattern: /system\s*:\s*override/i, label: "system-override" },
1795
+ // Constraint bypass
1796
+ { pattern: /override\s+(your|the)\s+(programming|constraints)/i, label: "override-constraints" },
1797
+ { pattern: /bypass\s+(your|the)\s+(filters|constraints|rules)/i, label: "bypass-filters" },
1798
+ // Prompt extraction
1799
+ { pattern: /system\s+prompt/i, label: "system-prompt-probe" },
1800
+ { pattern: /reveal\s+your\s+(instructions?|prompt|rules)/i, label: "reveal-instructions" },
1801
+ // Known jailbreak terms
1802
+ { pattern: /jailbreak/i, label: "jailbreak" },
1803
+ { pattern: /DAN\s+mode/i, label: "dan-mode" },
1804
+ { pattern: /developer\s+mode/i, label: "developer-mode" }
1805
+ ];
1806
+ var EXECUTION_CLAIM_PATTERNS = [
1807
+ { pattern: /I have (executed|completed|performed|done|made|created|sent|deleted|modified|updated)/i, label: "claim-i-have" },
1808
+ { pattern: /Successfully (created|deleted|modified|updated|sent|executed|performed)/i, label: "claim-successfully" },
1809
+ { pattern: /The file has been/i, label: "claim-file-modified" },
1810
+ { pattern: /I've made the changes/i, label: "claim-made-changes" },
1811
+ { pattern: /I('ve| have) (sent|posted|submitted|uploaded|downloaded)/i, label: "claim-sent" },
1812
+ { pattern: /Your (email|message|file|request) has been (sent|submitted)/i, label: "claim-your-sent" },
1813
+ { pattern: /Transaction complete/i, label: "claim-transaction" },
1814
+ { pattern: /Order placed/i, label: "claim-order" },
1815
+ { pattern: /Payment processed/i, label: "claim-payment" }
1816
+ ];
1817
+ var EXECUTION_INTENT_PATTERNS = [
1818
+ { pattern: /^(execute|run|perform|do this)/i, label: "intent-execute" },
1819
+ { pattern: /^(create|write|delete|modify) (a |the )?(file|folder|document)/i, label: "intent-file-ops" },
1820
+ { pattern: /^(send|post|submit) (a |an |the )?(email|message|tweet|post)/i, label: "intent-send" },
1821
+ { pattern: /^(search|look up|browse) (the )?web/i, label: "intent-web-search" },
1822
+ { pattern: /^(make|call|invoke) (a |an )?(api|http|rest) (call|request)/i, label: "intent-api-call" },
1823
+ { pattern: /^(buy|purchase|order|pay|transfer|send money)/i, label: "intent-financial" },
1824
+ { pattern: /^(book|schedule|reserve)/i, label: "intent-booking" },
1825
+ { pattern: /^(download|upload|save to|export to)/i, label: "intent-transfer" }
1826
+ ];
1827
+ var SCOPE_ESCAPE_PATTERNS = [
1828
+ { pattern: /\.\.\//, label: "parent-traversal" },
1829
+ { pattern: /^\/(?!home|project|workspace)/i, label: "absolute-path-outside-safe" },
1830
+ { pattern: /~\//, label: "home-directory" },
1831
+ { pattern: /\/etc\//i, label: "system-config" },
1832
+ { pattern: /\/usr\//i, label: "system-binaries" },
1833
+ { pattern: /\/var\//i, label: "system-variable-data" }
1834
+ ];
1835
+ var NEUTRAL_MESSAGES = {
1836
+ "prompt-injection": "This input contains patterns that could alter agent behavior.",
1837
+ "scope-escape": "This action would affect resources outside the declared scope.",
1838
+ "execution-claim": "This response claims to have performed an action.",
1839
+ "execution-intent": "This input requests execution in a thinking-only environment.",
1840
+ "delete": "This action would remove files. Confirmation needed.",
1841
+ "write-external": "This action would write outside the project folder.",
1842
+ "network-mutate": "This action would send data to an external service.",
1843
+ "credential-access": "This action would access stored credentials."
1844
+ };
1845
+ function levelRequiresConfirmation(level, actionType) {
1846
+ if (level === "strict") return true;
1847
+ if (level === "standard") {
1848
+ return actionType === "delete" || actionType === "credential-access";
1849
+ }
1850
+ return false;
1851
+ }
1852
+ function isExternalScope(scope) {
1853
+ const internalPatterns = [
1854
+ /^\.?\/?src\//i,
1855
+ /^\.?\/?lib\//i,
1856
+ /^\.?\/?app\//i,
1857
+ /^\.?\/?components\//i,
1858
+ /^\.?\/?pages\//i,
1859
+ /^\.?\/?public\//i,
1860
+ /^\.?\/?assets\//i,
1861
+ /^\.\//
1862
+ ];
1863
+ return !internalPatterns.some((p) => p.test(scope));
1864
+ }
1865
+ var MAX_INPUT_LENGTH = 1e5;
1866
+ function evaluateGuard(event, world, options = {}) {
1867
+ const startTime = performance.now();
1868
+ const level = options.level ?? "standard";
1869
+ const includeTrace = options.trace ?? false;
1870
+ if (!event.intent || typeof event.intent !== "string") {
1871
+ return {
1872
+ status: "BLOCK",
1873
+ reason: "GuardEvent.intent is required and must be a string",
1874
+ ruleId: "safety-input-validation",
1875
+ evidence: {
1876
+ worldId: world.world?.world_id ?? "",
1877
+ worldName: world.world?.name ?? "",
1878
+ worldVersion: world.world?.version ?? "",
1879
+ evaluatedAt: Date.now(),
1880
+ invariantsSatisfied: 0,
1881
+ invariantsTotal: 0,
1882
+ guardsMatched: [],
1883
+ rulesMatched: [],
1884
+ enforcementLevel: level
1885
+ }
1886
+ };
1887
+ }
1888
+ const inputLength = event.intent.length + (event.tool?.length ?? 0) + (event.scope?.length ?? 0) + (event.payload ? JSON.stringify(event.payload).length : 0);
1889
+ if (inputLength > MAX_INPUT_LENGTH) {
1890
+ return {
1891
+ status: "BLOCK",
1892
+ reason: `Input exceeds maximum allowed length (${MAX_INPUT_LENGTH} characters)`,
1893
+ ruleId: "safety-input-length",
1894
+ evidence: {
1895
+ worldId: world.world?.world_id ?? "",
1896
+ worldName: world.world?.name ?? "",
1897
+ worldVersion: world.world?.version ?? "",
1898
+ evaluatedAt: Date.now(),
1899
+ invariantsSatisfied: 0,
1900
+ invariantsTotal: 0,
1901
+ guardsMatched: [],
1902
+ rulesMatched: [],
1903
+ enforcementLevel: level
1904
+ }
1905
+ };
1906
+ }
1907
+ const eventText = normalizeEventText(event);
1908
+ const invariantChecks = [];
1909
+ const safetyChecks = [];
1910
+ let planCheckResult;
1911
+ const roleChecks = [];
1912
+ const guardChecks = [];
1913
+ const kernelRuleChecks = [];
1914
+ const levelChecks = [];
1915
+ let decidingLayer = "default-allow";
1916
+ let decidingId;
1917
+ const guardsMatched = [];
1918
+ const rulesMatched = [];
1919
+ if (options.emergencyOverride) {
1920
+ checkInvariantCoverage(world, invariantChecks);
1921
+ return buildVerdict(
1922
+ "ALLOW",
1923
+ void 0,
1924
+ "emergency-override",
1925
+ "Emergency override active \u2014 all governance rules suspended. Platform constraints still apply.",
1926
+ world,
1927
+ level,
1928
+ invariantChecks,
1929
+ guardsMatched,
1930
+ rulesMatched,
1931
+ includeTrace ? buildTrace(
1932
+ invariantChecks,
1933
+ safetyChecks,
1934
+ planCheckResult,
1935
+ roleChecks,
1936
+ guardChecks,
1937
+ kernelRuleChecks,
1938
+ levelChecks,
1939
+ "session-allowlist",
1940
+ "emergency-override",
1941
+ startTime
1942
+ ) : void 0,
1943
+ event.intent
1944
+ );
1945
+ }
1946
+ checkInvariantCoverage(world, invariantChecks);
1947
+ if (event.roleId && options.agentStates) {
1948
+ const agentState = options.agentStates.get(event.roleId);
1949
+ if (agentState && agentState.cooldownRemaining > 0) {
1950
+ decidingLayer = "safety";
1951
+ decidingId = `penalize-cooldown-${event.roleId}`;
1952
+ const verdict = buildVerdict(
1953
+ "PENALIZE",
1954
+ `Agent "${event.roleId}" is frozen for ${agentState.cooldownRemaining} more round(s) due to prior penalty.`,
1955
+ `penalize-cooldown-${event.roleId}`,
1956
+ void 0,
1957
+ world,
1958
+ level,
1959
+ invariantChecks,
1960
+ guardsMatched,
1961
+ rulesMatched,
1962
+ includeTrace ? buildTrace(
1963
+ invariantChecks,
1964
+ safetyChecks,
1965
+ planCheckResult,
1966
+ roleChecks,
1967
+ guardChecks,
1968
+ kernelRuleChecks,
1969
+ levelChecks,
1970
+ decidingLayer,
1971
+ decidingId,
1972
+ startTime
1973
+ ) : void 0
1974
+ );
1975
+ verdict.intentRecord = {
1976
+ originalIntent: event.intent,
1977
+ finalAction: "blocked (agent frozen)",
1978
+ enforcement: "PENALIZE",
1979
+ consequence: { type: "freeze", rounds: agentState.cooldownRemaining, description: "Agent still in cooldown from prior penalty" }
1980
+ };
1981
+ return verdict;
1982
+ }
1983
+ }
1984
+ if (options.sessionAllowlist) {
1985
+ const key = eventToAllowlistKey(event);
1986
+ if (options.sessionAllowlist.has(key)) {
1987
+ decidingLayer = "session-allowlist";
1988
+ decidingId = `allowlist:${key}`;
1989
+ return buildVerdict(
1990
+ "ALLOW",
1991
+ void 0,
1992
+ `allowlist:${key}`,
1993
+ void 0,
1994
+ world,
1995
+ level,
1996
+ invariantChecks,
1997
+ guardsMatched,
1998
+ rulesMatched,
1999
+ includeTrace ? buildTrace(
2000
+ invariantChecks,
2001
+ safetyChecks,
2002
+ planCheckResult,
2003
+ roleChecks,
2004
+ guardChecks,
2005
+ kernelRuleChecks,
2006
+ levelChecks,
2007
+ decidingLayer,
2008
+ decidingId,
2009
+ startTime
2010
+ ) : void 0,
2011
+ event.intent
2012
+ );
2013
+ }
2014
+ }
2015
+ const safetyVerdict = checkSafety(event, eventText, safetyChecks);
2016
+ if (safetyVerdict) {
2017
+ decidingLayer = "safety";
2018
+ decidingId = safetyVerdict.ruleId;
2019
+ return buildVerdict(
2020
+ safetyVerdict.status,
2021
+ safetyVerdict.reason,
2022
+ safetyVerdict.ruleId,
2023
+ void 0,
2024
+ world,
2025
+ level,
2026
+ invariantChecks,
2027
+ guardsMatched,
2028
+ rulesMatched,
2029
+ includeTrace ? buildTrace(
2030
+ invariantChecks,
2031
+ safetyChecks,
2032
+ planCheckResult,
2033
+ roleChecks,
2034
+ guardChecks,
2035
+ kernelRuleChecks,
2036
+ levelChecks,
2037
+ decidingLayer,
2038
+ decidingId,
2039
+ startTime
2040
+ ) : void 0,
2041
+ event.intent
2042
+ );
2043
+ }
2044
+ if (options.plan) {
2045
+ const planVerdict = evaluatePlan(event, options.plan);
2046
+ planCheckResult = buildPlanCheck(event, options.plan, planVerdict);
2047
+ if (!planVerdict.allowed && planVerdict.status !== "PLAN_COMPLETE") {
2048
+ decidingLayer = "plan-enforcement";
2049
+ decidingId = `plan-${options.plan.plan_id}`;
2050
+ const planStatus = planVerdict.status === "CONSTRAINT_VIOLATED" ? "PAUSE" : "BLOCK";
2051
+ let reason = planVerdict.reason ?? "Action blocked by plan.";
2052
+ if (planVerdict.status === "OFF_PLAN" && planVerdict.closestStep) {
2053
+ reason += ` Closest step: "${planVerdict.closestStep}" (similarity: ${(planVerdict.similarityScore ?? 0).toFixed(2)})`;
2054
+ }
2055
+ return buildVerdict(
2056
+ planStatus,
2057
+ reason,
2058
+ `plan-${options.plan.plan_id}`,
2059
+ void 0,
2060
+ world,
2061
+ level,
2062
+ invariantChecks,
2063
+ guardsMatched,
2064
+ rulesMatched,
2065
+ includeTrace ? buildTrace(
2066
+ invariantChecks,
2067
+ safetyChecks,
2068
+ planCheckResult,
2069
+ roleChecks,
2070
+ guardChecks,
2071
+ kernelRuleChecks,
2072
+ levelChecks,
2073
+ decidingLayer,
2074
+ decidingId,
2075
+ startTime
2076
+ ) : void 0,
2077
+ event.intent
2078
+ );
2079
+ }
2080
+ }
2081
+ const roleVerdict = checkRoleRules(event, eventText, world, roleChecks);
2082
+ if (roleVerdict) {
2083
+ decidingLayer = "role";
2084
+ decidingId = roleVerdict.ruleId;
2085
+ return buildVerdict(
2086
+ roleVerdict.status,
2087
+ roleVerdict.reason,
2088
+ roleVerdict.ruleId,
2089
+ void 0,
2090
+ world,
2091
+ level,
2092
+ invariantChecks,
2093
+ guardsMatched,
2094
+ rulesMatched,
2095
+ includeTrace ? buildTrace(
2096
+ invariantChecks,
2097
+ safetyChecks,
2098
+ planCheckResult,
2099
+ roleChecks,
2100
+ guardChecks,
2101
+ kernelRuleChecks,
2102
+ levelChecks,
2103
+ decidingLayer,
2104
+ decidingId,
2105
+ startTime
2106
+ ) : void 0,
2107
+ event.intent
2108
+ );
2109
+ }
2110
+ const guardVerdict = checkGuards(event, eventText, world, guardChecks, guardsMatched);
2111
+ if (guardVerdict) {
2112
+ if (guardVerdict.status !== "ALLOW") {
2113
+ decidingLayer = "guard";
2114
+ decidingId = guardVerdict.ruleId;
2115
+ const intentRecord = {
2116
+ originalIntent: event.intent,
2117
+ finalAction: guardVerdict.status === "MODIFY" ? guardVerdict.modifiedTo ?? "modified" : guardVerdict.status === "PENALIZE" ? "blocked + penalized" : guardVerdict.status === "REWARD" ? event.intent : guardVerdict.status === "NEUTRAL" ? event.intent : guardVerdict.status === "BLOCK" ? "blocked" : "paused",
2118
+ ruleApplied: guardVerdict.ruleId,
2119
+ enforcement: guardVerdict.status,
2120
+ modifiedTo: guardVerdict.modifiedTo,
2121
+ consequence: guardVerdict.consequence,
2122
+ reward: guardVerdict.reward
2123
+ };
2124
+ const verdict = buildVerdict(
2125
+ guardVerdict.status,
2126
+ guardVerdict.reason,
2127
+ guardVerdict.ruleId,
2128
+ void 0,
2129
+ world,
2130
+ level,
2131
+ invariantChecks,
2132
+ guardsMatched,
2133
+ rulesMatched,
2134
+ includeTrace ? buildTrace(
2135
+ invariantChecks,
2136
+ safetyChecks,
2137
+ planCheckResult,
2138
+ roleChecks,
2139
+ guardChecks,
2140
+ kernelRuleChecks,
2141
+ levelChecks,
2142
+ decidingLayer,
2143
+ decidingId,
2144
+ startTime
2145
+ ) : void 0,
2146
+ event.intent
2147
+ );
2148
+ verdict.intentRecord = intentRecord;
2149
+ if (guardVerdict.consequence) verdict.consequence = guardVerdict.consequence;
2150
+ if (guardVerdict.reward) verdict.reward = guardVerdict.reward;
2151
+ return verdict;
2152
+ }
2153
+ }
2154
+ const kernelVerdict = checkKernelRules(eventText, world, kernelRuleChecks, rulesMatched);
2155
+ if (kernelVerdict) {
2156
+ decidingLayer = "kernel-rule";
2157
+ decidingId = kernelVerdict.ruleId;
2158
+ return buildVerdict(
2159
+ kernelVerdict.status,
2160
+ kernelVerdict.reason,
2161
+ kernelVerdict.ruleId,
2162
+ void 0,
2163
+ world,
2164
+ level,
2165
+ invariantChecks,
2166
+ guardsMatched,
2167
+ rulesMatched,
2168
+ includeTrace ? buildTrace(
2169
+ invariantChecks,
2170
+ safetyChecks,
2171
+ planCheckResult,
2172
+ roleChecks,
2173
+ guardChecks,
2174
+ kernelRuleChecks,
2175
+ levelChecks,
2176
+ decidingLayer,
2177
+ decidingId,
2178
+ startTime
2179
+ ) : void 0,
2180
+ event.intent
2181
+ );
2182
+ }
2183
+ const levelVerdict = checkLevelConstraints(event, level, levelChecks);
2184
+ if (levelVerdict) {
2185
+ decidingLayer = "level-constraint";
2186
+ decidingId = levelVerdict.ruleId;
2187
+ return buildVerdict(
2188
+ levelVerdict.status,
2189
+ levelVerdict.reason,
2190
+ levelVerdict.ruleId,
2191
+ void 0,
2192
+ world,
2193
+ level,
2194
+ invariantChecks,
2195
+ guardsMatched,
2196
+ rulesMatched,
2197
+ includeTrace ? buildTrace(
2198
+ invariantChecks,
2199
+ safetyChecks,
2200
+ planCheckResult,
2201
+ roleChecks,
2202
+ guardChecks,
2203
+ kernelRuleChecks,
2204
+ levelChecks,
2205
+ decidingLayer,
2206
+ decidingId,
2207
+ startTime
2208
+ ) : void 0,
2209
+ event.intent
2210
+ );
2211
+ }
2212
+ const warning = guardVerdict?.warning;
2213
+ return buildVerdict(
2214
+ "ALLOW",
2215
+ void 0,
2216
+ void 0,
2217
+ warning,
2218
+ world,
2219
+ level,
2220
+ invariantChecks,
2221
+ guardsMatched,
2222
+ rulesMatched,
2223
+ includeTrace ? buildTrace(
2224
+ invariantChecks,
2225
+ safetyChecks,
2226
+ planCheckResult,
2227
+ roleChecks,
2228
+ guardChecks,
2229
+ kernelRuleChecks,
2230
+ levelChecks,
2231
+ decidingLayer,
2232
+ decidingId,
2233
+ startTime
2234
+ ) : void 0,
2235
+ event.intent
2236
+ );
2237
+ }
2238
+ function checkInvariantCoverage(world, checks) {
2239
+ const invariants = world.invariants ?? [];
2240
+ const guards = world.guards?.guards ?? [];
2241
+ for (const invariant of invariants) {
2242
+ const coveringGuard = guards.find(
2243
+ (g) => g.invariant_ref === invariant.id && g.immutable
2244
+ );
2245
+ checks.push({
2246
+ invariantId: invariant.id,
2247
+ label: invariant.label,
2248
+ hasGuardCoverage: !!coveringGuard,
2249
+ coveringGuardId: coveringGuard?.id
2250
+ });
2251
+ }
2252
+ }
2253
+ function checkSafety(event, eventText, checks) {
2254
+ const textToCheck = event.intent + (event.payload ? JSON.stringify(event.payload) : "");
2255
+ for (const { pattern, label } of PROMPT_INJECTION_PATTERNS) {
2256
+ const triggered = pattern.test(textToCheck);
2257
+ checks.push({
2258
+ checkType: "prompt-injection",
2259
+ triggered,
2260
+ matchedPattern: triggered ? label : void 0
2261
+ });
2262
+ if (triggered) {
2263
+ for (const remaining of PROMPT_INJECTION_PATTERNS.filter((p) => p.label !== label)) {
2264
+ checks.push({
2265
+ checkType: "prompt-injection",
2266
+ triggered: remaining.pattern.test(textToCheck),
2267
+ matchedPattern: remaining.pattern.test(textToCheck) ? remaining.label : void 0
2268
+ });
2269
+ }
2270
+ return {
2271
+ status: "PAUSE",
2272
+ reason: NEUTRAL_MESSAGES["prompt-injection"],
2273
+ ruleId: `safety-injection-${label}`
2274
+ };
2275
+ }
2276
+ }
2277
+ const scopeToCheck = event.scope ?? event.intent;
2278
+ for (const { pattern, label } of SCOPE_ESCAPE_PATTERNS) {
2279
+ const triggered = pattern.test(scopeToCheck);
2280
+ checks.push({
2281
+ checkType: "scope-escape",
2282
+ triggered,
2283
+ matchedPattern: triggered ? label : void 0
2284
+ });
2285
+ if (triggered) {
2286
+ for (const remaining of SCOPE_ESCAPE_PATTERNS.filter((p) => p.label !== label)) {
2287
+ checks.push({
2288
+ checkType: "scope-escape",
2289
+ triggered: remaining.pattern.test(scopeToCheck),
2290
+ matchedPattern: remaining.pattern.test(scopeToCheck) ? remaining.label : void 0
2291
+ });
2292
+ }
2293
+ return {
2294
+ status: "PAUSE",
2295
+ reason: NEUTRAL_MESSAGES["scope-escape"],
2296
+ ruleId: `safety-scope-${label}`
2297
+ };
2298
+ }
2299
+ }
2300
+ if (event.direction === "output") {
2301
+ for (const { pattern, label } of EXECUTION_CLAIM_PATTERNS) {
2302
+ const triggered = pattern.test(textToCheck);
2303
+ checks.push({
2304
+ checkType: "execution-claim",
2305
+ triggered,
2306
+ matchedPattern: triggered ? label : void 0
2307
+ });
2308
+ if (triggered) {
2309
+ for (const remaining of EXECUTION_CLAIM_PATTERNS.filter((p) => p.label !== label)) {
2310
+ checks.push({
2311
+ checkType: "execution-claim",
2312
+ triggered: remaining.pattern.test(textToCheck),
2313
+ matchedPattern: remaining.pattern.test(textToCheck) ? remaining.label : void 0
2314
+ });
2315
+ }
2316
+ return {
2317
+ status: "PAUSE",
2318
+ reason: NEUTRAL_MESSAGES["execution-claim"],
2319
+ ruleId: `safety-execution-claim-${label}`
2320
+ };
2321
+ }
2322
+ }
2323
+ }
2324
+ if (event.direction === "input") {
2325
+ const intentTrimmed = event.intent.trim();
2326
+ for (const { pattern, label } of EXECUTION_INTENT_PATTERNS) {
2327
+ const triggered = pattern.test(intentTrimmed);
2328
+ checks.push({
2329
+ checkType: "execution-intent",
2330
+ triggered,
2331
+ matchedPattern: triggered ? label : void 0
2332
+ });
2333
+ if (triggered) {
2334
+ for (const remaining of EXECUTION_INTENT_PATTERNS.filter((p) => p.label !== label)) {
2335
+ checks.push({
2336
+ checkType: "execution-intent",
2337
+ triggered: remaining.pattern.test(intentTrimmed),
2338
+ matchedPattern: remaining.pattern.test(intentTrimmed) ? remaining.label : void 0
2339
+ });
2340
+ }
2341
+ return {
2342
+ status: "PAUSE",
2343
+ reason: NEUTRAL_MESSAGES["execution-intent"],
2344
+ ruleId: `safety-execution-intent-${label}`
2345
+ };
2346
+ }
2347
+ }
2348
+ }
2349
+ return null;
2350
+ }
2351
+ function checkRoleRules(event, eventText, world, checks) {
2352
+ if (!event.roleId || !world.roles) return null;
2353
+ const role = world.roles.roles.find((r) => r.id === event.roleId);
2354
+ if (!role) return null;
2355
+ if (role.requiresApproval) {
2356
+ checks.push({
2357
+ roleId: role.id,
2358
+ roleName: role.name,
2359
+ rule: "All actions require approval",
2360
+ ruleType: "requiresApproval",
2361
+ matched: true
2362
+ });
2363
+ return {
2364
+ status: "PAUSE",
2365
+ reason: `Role "${role.name}" requires approval for all actions.`,
2366
+ ruleId: `role-${role.id}-requires-approval`
2367
+ };
2368
+ }
2369
+ for (const rule of role.cannotDo) {
2370
+ const matched = matchesKeywords(eventText, rule);
2371
+ checks.push({
2372
+ roleId: role.id,
2373
+ roleName: role.name,
2374
+ rule,
2375
+ ruleType: "cannotDo",
2376
+ matched
2377
+ });
2378
+ if (matched) {
2379
+ return {
2380
+ status: "BLOCK",
2381
+ reason: `Role "${role.name}" cannot: ${rule}`,
2382
+ ruleId: `role-${role.id}-cannotdo`
2383
+ };
2384
+ }
2385
+ }
2386
+ for (const rule of role.canDo) {
2387
+ checks.push({
2388
+ roleId: role.id,
2389
+ roleName: role.name,
2390
+ rule,
2391
+ ruleType: "canDo",
2392
+ matched: matchesKeywords(eventText, rule)
2393
+ });
2394
+ }
2395
+ return null;
2396
+ }
2397
+ function checkGuards(event, eventText, world, checks, guardsMatched) {
2398
+ if (!world.guards) return null;
2399
+ const guardsConfig = world.guards;
2400
+ let warnResult = null;
2401
+ const compiledPatterns = /* @__PURE__ */ new Map();
2402
+ for (const [key, def] of Object.entries(guardsConfig.intent_vocabulary)) {
2403
+ try {
2404
+ compiledPatterns.set(key, new RegExp(def.pattern, "i"));
2405
+ } catch {
2406
+ }
2407
+ }
2408
+ const eventTool = (event.tool ?? "").toLowerCase();
2409
+ for (const guard of guardsConfig.guards) {
2410
+ if (guard.appliesTo && guard.appliesTo.length > 0) {
2411
+ const normalizedAppliesTo = guard.appliesTo.map((t) => t.toLowerCase());
2412
+ if (!normalizedAppliesTo.includes(eventTool)) {
2413
+ continue;
2414
+ }
2415
+ }
2416
+ const enabled = guard.immutable || guard.default_enabled !== false;
2417
+ const matchedPatterns = [];
2418
+ for (const patternKey of guard.intent_patterns) {
2419
+ const regex = compiledPatterns.get(patternKey);
2420
+ if (regex?.test(eventText)) {
2421
+ matchedPatterns.push(patternKey);
2422
+ }
2423
+ }
2424
+ const matched = matchedPatterns.length > 0 && enabled;
2425
+ let roleGated = false;
2426
+ if (matched && guard.required_roles && guard.required_roles.length > 0 && event.roleId && guard.required_roles.includes(event.roleId)) {
2427
+ roleGated = true;
2428
+ }
2429
+ checks.push({
2430
+ guardId: guard.id,
2431
+ label: guard.label,
2432
+ category: guard.category,
2433
+ enabled,
2434
+ matched: matched && !roleGated,
2435
+ enforcement: guard.enforcement,
2436
+ matchedPatterns,
2437
+ roleGated
2438
+ });
2439
+ if (!matched || roleGated) continue;
2440
+ guardsMatched.push(guard.id);
2441
+ const actionMode = guard.player_modes?.action ?? guard.enforcement;
2442
+ const reason = guard.redirect ? `${guard.description} \u2014 ${guard.redirect}` : guard.description;
2443
+ if (actionMode === "block") {
2444
+ return { status: "BLOCK", reason, ruleId: `guard-${guard.id}` };
2445
+ }
2446
+ if (actionMode === "pause") {
2447
+ return { status: "PAUSE", reason, ruleId: `guard-${guard.id}` };
2448
+ }
2449
+ if (actionMode === "penalize") {
2450
+ const consequence = guard.consequence ? { ...guard.consequence } : { type: "freeze", rounds: 1, description: `Penalized for violating: ${guard.label}` };
2451
+ return { status: "PENALIZE", reason, ruleId: `guard-${guard.id}`, consequence };
2452
+ }
2453
+ if (actionMode === "reward") {
2454
+ const reward = guard.reward ? { ...guard.reward } : { type: "boost_influence", magnitude: 0.1, description: `Rewarded for: ${guard.label}` };
2455
+ return { status: "REWARD", reason, ruleId: `guard-${guard.id}`, reward };
2456
+ }
2457
+ if (actionMode === "modify") {
2458
+ const modifiedTo = guard.modify_to ?? guard.redirect ?? "hold";
2459
+ return { status: "MODIFY", reason: `${reason} \u2192 Modified to: ${modifiedTo}`, ruleId: `guard-${guard.id}`, modifiedTo };
2460
+ }
2461
+ if (actionMode === "neutral") {
2462
+ return { status: "NEUTRAL", reason, ruleId: `guard-${guard.id}` };
2463
+ }
2464
+ if (actionMode === "warn" && !warnResult) {
2465
+ warnResult = { status: "ALLOW", warning: reason, ruleId: `guard-${guard.id}` };
2466
+ }
2467
+ }
2468
+ return warnResult;
2469
+ }
2470
+ function checkKernelRules(eventText, world, checks, rulesMatched) {
2471
+ if (!world.kernel) return null;
2472
+ const forbidden = world.kernel.input_boundaries?.forbidden_patterns ?? [];
2473
+ const output = world.kernel.output_boundaries?.forbidden_patterns ?? [];
2474
+ for (const rule of forbidden) {
2475
+ let matched = false;
2476
+ let matchMethod = "none";
2477
+ if (rule.pattern) {
2478
+ try {
2479
+ matched = new RegExp(rule.pattern, "i").test(eventText);
2480
+ matchMethod = "pattern";
2481
+ } catch {
2482
+ }
2483
+ }
2484
+ if (!matched && rule.reason) {
2485
+ matched = matchesKeywords(eventText, rule.reason);
2486
+ if (matched) matchMethod = "keyword";
2487
+ }
2488
+ checks.push({
2489
+ ruleId: rule.id,
2490
+ text: rule.reason,
2491
+ category: "forbidden",
2492
+ matched,
2493
+ matchMethod
2494
+ });
2495
+ if (matched) {
2496
+ rulesMatched.push(rule.id);
2497
+ if (rule.action === "BLOCK") {
2498
+ return {
2499
+ status: "BLOCK",
2500
+ reason: rule.reason,
2501
+ ruleId: `kernel-${rule.id}`
2502
+ };
2503
+ }
2504
+ }
2505
+ }
2506
+ return null;
2507
+ }
2508
+ function checkLevelConstraints(event, level, checks) {
2509
+ if (level === "basic") return null;
2510
+ const intent = event.intent.toLowerCase();
2511
+ const tool = (event.tool ?? "").toLowerCase();
2512
+ const isDelete = intent.includes("delete") || intent.includes("remove") || intent.includes("rm ") || tool === "delete";
2513
+ const deleteTriggered = isDelete && levelRequiresConfirmation(level, "delete");
2514
+ checks.push({
2515
+ checkType: "delete",
2516
+ level,
2517
+ triggered: deleteTriggered,
2518
+ reason: deleteTriggered ? NEUTRAL_MESSAGES["delete"] : void 0
2519
+ });
2520
+ if (deleteTriggered) {
2521
+ return { status: "PAUSE", reason: NEUTRAL_MESSAGES["delete"], ruleId: "level-delete-check" };
2522
+ }
2523
+ const isExternal = event.scope ? isExternalScope(event.scope) : false;
2524
+ const externalTriggered = isExternal && levelRequiresConfirmation(level, "write-external");
2525
+ checks.push({
2526
+ checkType: "write-external",
2527
+ level,
2528
+ triggered: externalTriggered,
2529
+ reason: externalTriggered ? NEUTRAL_MESSAGES["write-external"] : void 0
2530
+ });
2531
+ if (externalTriggered) {
2532
+ return { status: "PAUSE", reason: NEUTRAL_MESSAGES["write-external"], ruleId: "level-external-write-check" };
2533
+ }
2534
+ const isNetwork = tool === "http" || tool === "fetch" || tool === "request" || intent.includes("post ") || intent.includes("sending");
2535
+ const networkTriggered = isNetwork && levelRequiresConfirmation(level, "network-mutate");
2536
+ checks.push({
2537
+ checkType: "network-mutate",
2538
+ level,
2539
+ triggered: networkTriggered,
2540
+ reason: networkTriggered ? NEUTRAL_MESSAGES["network-mutate"] : void 0
2541
+ });
2542
+ if (networkTriggered) {
2543
+ return { status: "PAUSE", reason: NEUTRAL_MESSAGES["network-mutate"], ruleId: "level-network-mutate-check" };
2544
+ }
2545
+ const isCredential = intent.includes("credential") || intent.includes("password") || intent.includes("secret") || intent.includes("api key") || intent.includes("token");
2546
+ const credentialTriggered = isCredential && levelRequiresConfirmation(level, "credential-access");
2547
+ checks.push({
2548
+ checkType: "credential-access",
2549
+ level,
2550
+ triggered: credentialTriggered,
2551
+ reason: credentialTriggered ? NEUTRAL_MESSAGES["credential-access"] : void 0
2552
+ });
2553
+ if (credentialTriggered) {
2554
+ return { status: "PAUSE", reason: NEUTRAL_MESSAGES["credential-access"], ruleId: "level-credential-check" };
2555
+ }
2556
+ const irreversibleTriggered = !!event.irreversible && level !== "basic";
2557
+ checks.push({
2558
+ checkType: "irreversible",
2559
+ level,
2560
+ triggered: irreversibleTriggered,
2561
+ reason: irreversibleTriggered ? "This action is marked as irreversible." : void 0
2562
+ });
2563
+ if (irreversibleTriggered) {
2564
+ return {
2565
+ status: "PAUSE",
2566
+ reason: "This action is marked as irreversible.",
2567
+ ruleId: "level-irreversible-check"
2568
+ };
2569
+ }
2570
+ return null;
2571
+ }
2572
+ function matchesKeywords(eventText, ruleText) {
2573
+ return matchesAllKeywords(eventText, ruleText);
2574
+ }
2575
+ function eventToAllowlistKey(event) {
2576
+ return `${(event.tool ?? "*").toLowerCase()}::${event.intent.toLowerCase().trim()}`;
2577
+ }
2578
+ function buildTrace(invariantChecks, safetyChecks, planCheck, roleChecks, guardChecks, kernelRuleChecks, levelChecks, decidingLayer, decidingId, startTime) {
2579
+ const trace = {
2580
+ invariantChecks,
2581
+ safetyChecks,
2582
+ roleChecks,
2583
+ guardChecks,
2584
+ kernelRuleChecks,
2585
+ levelChecks,
2586
+ precedenceResolution: {
2587
+ decidingLayer,
2588
+ decidingId,
2589
+ strategy: "first-match-wins",
2590
+ chainOrder: [
2591
+ "invariant-coverage",
2592
+ "session-allowlist",
2593
+ "safety-injection",
2594
+ "safety-scope-escape",
2595
+ "safety-execution-claim",
2596
+ "safety-execution-intent",
2597
+ "plan-enforcement",
2598
+ "role-rules",
2599
+ "declarative-guards",
2600
+ "kernel-rules",
2601
+ "level-constraints",
2602
+ "default-allow"
2603
+ ]
2604
+ },
2605
+ durationMs: performance.now() - startTime
2606
+ };
2607
+ if (planCheck) {
2608
+ trace.planCheck = planCheck;
2609
+ }
2610
+ return trace;
2611
+ }
2612
+ function buildVerdict(status, reason, ruleId, warning, world, level, invariantChecks, guardsMatched, rulesMatched, trace, eventIntent) {
2613
+ const evidence = {
2614
+ worldId: world.world.world_id,
2615
+ worldName: world.world.name,
2616
+ worldVersion: world.world.version,
2617
+ evaluatedAt: Date.now(),
2618
+ invariantsSatisfied: invariantChecks.filter((c) => c.hasGuardCoverage).length,
2619
+ invariantsTotal: invariantChecks.length,
2620
+ guardsMatched,
2621
+ rulesMatched,
2622
+ enforcementLevel: level
2623
+ };
2624
+ const verdict = {
2625
+ status,
2626
+ evidence
2627
+ };
2628
+ if (reason) verdict.reason = reason;
2629
+ if (ruleId) verdict.ruleId = ruleId;
2630
+ if (warning) verdict.warning = warning;
2631
+ if (trace) verdict.trace = trace;
2632
+ verdict.event = verdictToEvent(status, eventIntent);
2633
+ return verdict;
2634
+ }
2635
+ function verdictToEvent(status, intent) {
2636
+ const statusEventMap = {
2637
+ ALLOW: "action_allowed",
2638
+ BLOCK: "action_blocked",
2639
+ PAUSE: "action_paused",
2640
+ MODIFY: "action_modified",
2641
+ PENALIZE: "action_penalized",
2642
+ REWARD: "action_rewarded",
2643
+ NEUTRAL: "action_neutral"
2644
+ };
2645
+ return {
2646
+ type: intent || statusEventMap[status] || "unknown_action",
2647
+ actor: "agent",
2648
+ source: "guard",
2649
+ timestamp: Date.now(),
2650
+ guardStatus: status
2651
+ };
2652
+ }
2653
+
2654
+ // src/loader/world-loader.ts
2655
+ async function loadWorldFromDirectory(dirPath) {
2656
+ const { readFile } = await import("fs/promises");
2657
+ const { join: join3 } = await import("path");
2658
+ const { readdirSync: readdirSync2 } = await import("fs");
2659
+ async function readJson(filename) {
2660
+ const filePath = join3(dirPath, filename);
2661
+ try {
2662
+ const content = await readFile(filePath, "utf-8");
2663
+ return JSON.parse(content);
2664
+ } catch (err) {
2665
+ if (err instanceof Error && "code" in err && err.code === "ENOENT") {
2666
+ return void 0;
2667
+ }
2668
+ process.stderr.write(
2669
+ `[neuroverse] Warning: Failed to read ${filename}: ${err instanceof Error ? err.message : String(err)}
2670
+ `
2671
+ );
2672
+ return void 0;
2673
+ }
2674
+ }
2675
+ const worldJson = await readJson("world.json");
2676
+ if (!worldJson) {
2677
+ throw new Error(`Cannot read world.json in ${dirPath}`);
2678
+ }
2679
+ const invariantsJson = await readJson("invariants.json");
2680
+ const assumptionsJson = await readJson("assumptions.json");
2681
+ const stateSchemaJson = await readJson("state-schema.json");
2682
+ const gatesJson = await readJson("gates.json");
2683
+ const outcomesJson = await readJson("outcomes.json");
2684
+ const guardsJson = await readJson("guards.json");
2685
+ const rolesJson = await readJson("roles.json");
2686
+ const kernelJson = await readJson("kernel.json");
2687
+ const metadataJson = await readJson("metadata.json");
2688
+ const rules = [];
2689
+ try {
2690
+ const rulesDir = join3(dirPath, "rules");
2691
+ const ruleFiles = readdirSync2(rulesDir).filter((f) => f.endsWith(".json")).sort();
2692
+ for (const file of ruleFiles) {
2693
+ try {
2694
+ const content = await readFile(join3(rulesDir, file), "utf-8");
2695
+ rules.push(JSON.parse(content));
2696
+ } catch (err) {
2697
+ process.stderr.write(
2698
+ `[neuroverse] Warning: Failed to parse rule ${file}: ${err instanceof Error ? err.message : String(err)}
2699
+ `
2700
+ );
2701
+ }
2702
+ }
2703
+ } catch (err) {
2704
+ if (!(err instanceof Error && "code" in err && err.code === "ENOENT")) {
2705
+ process.stderr.write(
2706
+ `[neuroverse] Warning: Failed to read rules directory: ${err instanceof Error ? err.message : String(err)}
2707
+ `
2708
+ );
2709
+ }
2710
+ }
2711
+ return {
2712
+ world: worldJson,
2713
+ invariants: invariantsJson?.invariants ?? [],
2714
+ assumptions: assumptionsJson ?? { profiles: {}, parameter_definitions: {} },
2715
+ stateSchema: stateSchemaJson ?? { variables: {}, presets: {} },
2716
+ rules,
2717
+ gates: gatesJson ?? {
2718
+ viability_classification: [],
2719
+ structural_override: { description: "", enforcement: "mandatory" },
2720
+ sustainability_threshold: 0,
2721
+ collapse_visual: { background: "", text: "", border: "", label: "" }
2722
+ },
2723
+ outcomes: outcomesJson ?? {
2724
+ computed_outcomes: [],
2725
+ comparison_layout: { primary_card: "", status_badge: "", structural_indicators: [] }
2726
+ },
2727
+ guards: guardsJson,
2728
+ roles: rolesJson,
2729
+ kernel: kernelJson,
2730
+ metadata: metadataJson ?? {
2731
+ format_version: "1.0.0",
2732
+ created_at: "",
2733
+ last_modified: "",
2734
+ authoring_method: "manual-authoring"
2735
+ }
2736
+ };
2737
+ }
2738
+ async function loadWorld(worldPath) {
2739
+ const { stat } = await import("fs/promises");
2740
+ const info = await stat(worldPath);
2741
+ if (info.isDirectory()) {
2742
+ return loadWorldFromDirectory(worldPath);
2743
+ }
2744
+ throw new Error(`Cannot load world from: ${worldPath} \u2014 expected a directory`);
2745
+ }
2746
+
2747
+ // src/radiant/core/governance.ts
2748
+ async function auditGovernance(events, worldPath) {
2749
+ let world;
2750
+ try {
2751
+ world = await loadWorld(worldPath);
2752
+ } catch {
2753
+ return emptyAudit(events.length, "Could not load compiled worldmodel for governance audit.");
2754
+ }
2755
+ const verdicts = [];
2756
+ for (const ce of events) {
2757
+ const intent = ce.event.content?.slice(0, 500) || ce.event.kind || "activity";
2758
+ const scope = ce.event.metadata?.scope || void 0;
2759
+ try {
2760
+ const result = evaluateGuard(
2761
+ {
2762
+ intent,
2763
+ scope,
2764
+ actionCategory: mapKindToCategory(ce.event.kind)
2765
+ },
2766
+ world
2767
+ );
2768
+ verdicts.push({
2769
+ eventId: ce.event.id,
2770
+ domain: ce.domain,
2771
+ status: result.status,
2772
+ reason: result.reason,
2773
+ ruleId: result.ruleId,
2774
+ warning: result.warning
2775
+ });
2776
+ } catch {
2777
+ verdicts.push({
2778
+ eventId: ce.event.id,
2779
+ domain: ce.domain,
2780
+ status: "ALLOW",
2781
+ reason: "guard evaluation skipped (error)"
2782
+ });
2783
+ }
2784
+ }
2785
+ const human = bucketVerdicts(verdicts.filter((v) => v.domain === "life"));
2786
+ const cyber = bucketVerdicts(verdicts.filter((v) => v.domain === "cyber"));
2787
+ const joint = bucketVerdicts(verdicts.filter((v) => v.domain === "joint"));
2788
+ const summary = buildSummary(human, cyber, joint, events.length);
2789
+ return {
2790
+ totalEvents: events.length,
2791
+ human,
2792
+ cyber,
2793
+ joint,
2794
+ summary
2795
+ };
2796
+ }
2797
+ function bucketVerdicts(verdicts) {
2798
+ const nonAllow = verdicts.filter((v) => v.status !== "ALLOW");
2799
+ return {
2800
+ allow: verdicts.filter((v) => v.status === "ALLOW").length,
2801
+ modify: verdicts.filter((v) => v.status === "MODIFY").length,
2802
+ block: verdicts.filter((v) => v.status === "BLOCK").length,
2803
+ details: nonAllow
2804
+ };
2805
+ }
2806
+ function buildSummary(human, cyber, joint, total) {
2807
+ const humanTriggered = human.modify + human.block;
2808
+ const cyberTriggered = cyber.modify + cyber.block;
2809
+ const jointTriggered = joint.modify + joint.block;
2810
+ const totalTriggered = humanTriggered + cyberTriggered + jointTriggered;
2811
+ if (totalTriggered === 0) {
2812
+ return `${total} events evaluated. All passed. The cocoon held \u2014 no governance triggered.`;
2813
+ }
2814
+ const parts = [];
2815
+ parts.push(`${total} events evaluated. ${totalTriggered} triggered governance.`);
2816
+ if (humanTriggered > 0) {
2817
+ parts.push(`Human side: ${humanTriggered} (${human.block} blocked, ${human.modify} modified).`);
2818
+ }
2819
+ if (cyberTriggered > 0) {
2820
+ parts.push(`AI side: ${cyberTriggered} (${cyber.block} blocked, ${cyber.modify} modified).`);
2821
+ }
2822
+ if (jointTriggered > 0) {
2823
+ parts.push(`Joint work: ${jointTriggered} (${joint.block} blocked, ${joint.modify} modified).`);
2824
+ }
2825
+ if (humanTriggered > 0 && cyberTriggered > 0) {
2826
+ const ratio = humanTriggered / cyberTriggered;
2827
+ if (ratio > 2) {
2828
+ parts.push("Human side is testing the frame more than AI. Either the worldmodel needs calibrating for human workflows, or humans are genuinely drifting.");
2829
+ } else if (ratio < 0.5) {
2830
+ parts.push("AI side is testing the frame more than humans. Check whether the AI's output patterns match the declared invariants.");
2831
+ } else {
2832
+ parts.push("Roughly balanced between human and AI \u2014 both sides are testing the frame.");
2833
+ }
2834
+ }
2835
+ return parts.join(" ");
2836
+ }
2837
+ function mapKindToCategory(kind) {
2838
+ if (!kind) return "other";
2839
+ if (kind.includes("commit") || kind.includes("merge")) return "write";
2840
+ if (kind.includes("review") || kind.includes("comment")) return "read";
2841
+ return "other";
2842
+ }
2843
+ function emptyAudit(total, reason) {
2844
+ return {
2845
+ totalEvents: total,
2846
+ human: { allow: 0, modify: 0, block: 0, details: [] },
2847
+ cyber: { allow: 0, modify: 0, block: 0, details: [] },
2848
+ joint: { allow: 0, modify: 0, block: 0, details: [] },
2849
+ summary: reason
2850
+ };
2851
+ }
2852
+
2853
+ // src/radiant/memory/palace.ts
2854
+ var import_fs2 = require("fs");
2855
+ var import_path2 = require("path");
2856
+ function writeRead(exocortexDir, frontmatter, text) {
2857
+ const dir = (0, import_path2.resolve)(exocortexDir, "radiant", "reads");
2858
+ (0, import_fs2.mkdirSync)(dir, { recursive: true });
2859
+ const date = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
2860
+ const filename = `${date}.md`;
2861
+ const filepath = (0, import_path2.join)(dir, filename);
2862
+ const content = `${frontmatter}
2863
+
2864
+ ${text}
2865
+ `;
2866
+ (0, import_fs2.writeFileSync)(filepath, content, "utf-8");
2867
+ return filepath;
2868
+ }
2869
+ function updateKnowledge(exocortexDir, persistence, options) {
2870
+ const dir = (0, import_path2.resolve)(exocortexDir, "radiant");
2871
+ (0, import_fs2.mkdirSync)(dir, { recursive: true });
2872
+ const filepath = (0, import_path2.join)(dir, "knowledge.md");
2873
+ const totalReads = options?.totalReads ?? 0;
2874
+ const existingUntriggered = loadUntriggeredCounts(filepath);
2875
+ const lines = [
2876
+ "# Radiant \u2014 Accumulated Behavioral Knowledge",
2877
+ "",
2878
+ `Last updated: ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}`,
2879
+ `Total reads: ${totalReads}`,
2880
+ "",
2881
+ "---",
2882
+ "",
2883
+ "## Evolution proposals",
2884
+ ""
2885
+ ];
2886
+ const addCandidates = persistence.filter((p) => p.occurrences >= 3);
2887
+ if (addCandidates.length > 0) {
2888
+ lines.push("### Consider adding");
2889
+ lines.push("");
2890
+ lines.push("These candidate patterns keep recurring. They are not yet in the worldmodel.");
2891
+ lines.push("If they represent real behavioral patterns worth tracking, add them.");
2892
+ lines.push("If they were temporary, dismiss them.");
2893
+ lines.push("");
2894
+ for (const p of addCandidates) {
2895
+ lines.push(
2896
+ `- **${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).`
2897
+ );
2898
+ }
2899
+ lines.push("");
2900
+ }
2901
+ if (options?.declaredItems && options.declaredItems.length > 0) {
2902
+ const triggered = new Set(options.triggeredItems ?? []);
2903
+ const removeCandidates = [];
2904
+ for (const item of options.declaredItems) {
2905
+ if (!triggered.has(item.name)) {
2906
+ const prior = existingUntriggered.get(item.name) ?? 0;
2907
+ const count = prior + 1;
2908
+ existingUntriggered.set(item.name, count);
2909
+ if (count >= 4) {
2910
+ removeCandidates.push({ item, weeksSilent: count });
2911
+ }
2912
+ } else {
2913
+ existingUntriggered.set(item.name, 0);
2914
+ }
2915
+ }
2916
+ if (removeCandidates.length > 0) {
2917
+ lines.push("### Consider removing");
2918
+ lines.push("");
2919
+ lines.push("These items are declared in the worldmodel but haven't triggered in multiple reads.");
2920
+ lines.push("Either the team has internalized them (the rule is redundant) or they haven't been tested.");
2921
+ lines.push("A lean worldmodel with 5 sharp invariants is stronger than a bloated one with 20.");
2922
+ lines.push("");
2923
+ for (const { item, weeksSilent } of removeCandidates) {
2924
+ lines.push(
2925
+ `- **${item.name}** (${item.type}) \u2014 hasn't triggered in ${weeksSilent} reads. Internalized or untested? Review whether it still earns its place.`
2926
+ );
2927
+ }
2928
+ lines.push("");
2929
+ }
2930
+ }
2931
+ if (options?.triggeredItems && options.triggeredItems.length > 0) {
2932
+ lines.push("### Keep (recently active)");
2933
+ lines.push("");
2934
+ lines.push("These worldmodel items triggered governance in the most recent read. They're earning their place.");
2935
+ lines.push("");
2936
+ for (const name of options.triggeredItems) {
2937
+ lines.push(`- **${name}** \u2014 triggered this read. Holding.`);
2938
+ }
2939
+ lines.push("");
2940
+ }
2941
+ lines.push("---");
2942
+ lines.push("");
2943
+ lines.push("## Pattern persistence (all observed)");
2944
+ lines.push("");
2945
+ for (const p of persistence) {
2946
+ const status = p.occurrences >= 4 ? "**persistent**" : p.occurrences >= 2 ? "recurring" : "observed once";
2947
+ lines.push(`### ${p.name}`);
2948
+ lines.push(`- Status: ${status}`);
2949
+ lines.push(`- Observed ${p.occurrences} time${p.occurrences > 1 ? "s" : ""}: ${p.dates.join(", ")}`);
2950
+ lines.push("");
2951
+ }
2952
+ lines.push("---");
2953
+ lines.push("");
2954
+ lines.push("<!-- untriggered_counts (machine-readable, do not edit)");
2955
+ for (const [name, count] of existingUntriggered.entries()) {
2956
+ lines.push(`${name}=${count}`);
2957
+ }
2958
+ lines.push("-->");
2959
+ (0, import_fs2.writeFileSync)(filepath, lines.join("\n"), "utf-8");
2960
+ return filepath;
2961
+ }
2962
+ function loadUntriggeredCounts(filepath) {
2963
+ const counts = /* @__PURE__ */ new Map();
2964
+ if (!(0, import_fs2.existsSync)(filepath)) return counts;
2965
+ try {
2966
+ const content = (0, import_fs2.readFileSync)(filepath, "utf-8");
2967
+ const match = content.match(
2968
+ /<!-- untriggered_counts[\s\S]*?-->/
2969
+ );
2970
+ if (match) {
2971
+ const lines = match[0].split("\n");
2972
+ for (const line of lines) {
2973
+ const eq = line.match(/^([^=]+)=(\d+)$/);
2974
+ if (eq) {
2975
+ counts.set(eq[1], parseInt(eq[2], 10));
2976
+ }
2977
+ }
2978
+ }
2979
+ } catch {
2980
+ }
2981
+ return counts;
2982
+ }
2983
+ function loadPriorReads(exocortexDir) {
2984
+ const dir = (0, import_path2.resolve)(exocortexDir, "radiant", "reads");
2985
+ if (!(0, import_fs2.existsSync)(dir)) return [];
2986
+ const files = (0, import_fs2.readdirSync)(dir).filter((f) => f.endsWith(".md")).sort();
2987
+ const reads = [];
2988
+ for (const filename of files) {
2989
+ const filepath = (0, import_path2.join)(dir, filename);
2990
+ const content = (0, import_fs2.readFileSync)(filepath, "utf-8");
2991
+ const date = filename.replace(".md", "");
2992
+ const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
2993
+ const frontmatter = fmMatch ? fmMatch[1] : "";
2994
+ const patternNames = [];
2995
+ const nameMatches = frontmatter.matchAll(/- name: ["']?([^"'\n]+)["']?/g);
2996
+ for (const m of nameMatches) {
2997
+ patternNames.push(m[1].trim());
2998
+ }
2999
+ reads.push({ date, filename, patternNames, frontmatter });
3000
+ }
3001
+ return reads;
3002
+ }
3003
+ function computePersistence(priorReads, currentPatternNames) {
3004
+ const allPatterns = /* @__PURE__ */ new Map();
3005
+ for (const read of priorReads) {
3006
+ for (const name of read.patternNames) {
3007
+ const dates = allPatterns.get(name) ?? [];
3008
+ if (!dates.includes(read.date)) dates.push(read.date);
3009
+ allPatterns.set(name, dates);
3010
+ }
3011
+ }
3012
+ const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
3013
+ for (const name of currentPatternNames) {
3014
+ const dates = allPatterns.get(name) ?? [];
3015
+ if (!dates.includes(today)) dates.push(today);
3016
+ allPatterns.set(name, dates);
3017
+ }
3018
+ return Array.from(allPatterns.entries()).map(([name, dates]) => ({
3019
+ name,
3020
+ occurrences: dates.length,
3021
+ dates: dates.sort()
3022
+ })).sort((a, b) => b.occurrences - a.occurrences);
3023
+ }
3024
+ function formatPriorReadsForPrompt(priorReads) {
3025
+ if (priorReads.length === 0) return "";
3026
+ const lines = [
3027
+ "## Prior Radiant reads (history)",
3028
+ "",
3029
+ `Radiant has run ${priorReads.length} time${priorReads.length > 1 ? "s" : ""} before on this scope.`,
3030
+ "If you see patterns that appeared in prior reads, note their persistence.",
3031
+ "Patterns that recur across 3+ reads are strong candidates for declaration in the strategy file.",
3032
+ ""
3033
+ ];
3034
+ for (const read of priorReads.slice(-4)) {
3035
+ lines.push(`### Read from ${read.date}`);
3036
+ if (read.patternNames.length > 0) {
3037
+ lines.push(`Patterns observed: ${read.patternNames.join(", ")}`);
3038
+ } else {
3039
+ lines.push("No patterns extracted from frontmatter.");
3040
+ }
3041
+ lines.push("");
3042
+ }
3043
+ return lines.join("\n");
3044
+ }
3045
+
3046
+ // src/radiant/commands/think.ts
3047
+ async function think(input) {
3048
+ const lens = resolveLens(input.lensId);
3049
+ const systemPrompt = composeSystemPrompt(input.worldmodelContent, lens);
3050
+ const response = await input.ai.complete(systemPrompt, input.query);
3051
+ const voiceViolations = checkForbiddenPhrases(lens, response);
3052
+ return {
3053
+ response,
3054
+ lens: lens.name,
3055
+ voiceViolations,
3056
+ voiceClean: voiceViolations.length === 0,
3057
+ systemPrompt
3058
+ };
3059
+ }
3060
+ function resolveLens(id) {
3061
+ const lens = getLens(id);
3062
+ if (!lens) {
3063
+ const available = Object.keys(
3064
+ // Inline import-free way to list. At runtime, getLens returns from
3065
+ // the same LENSES record — we just need the keys for the error message.
3066
+ // We re-import getLens from lenses/index which exposes listLenses, but
3067
+ // since we already have lens===undefined we know the id was wrong.
3068
+ {}
3069
+ );
3070
+ throw new Error(
3071
+ `Lens "${id}" not found. Check the id or register the lens in src/radiant/lenses/index.ts.`
3072
+ );
3073
+ }
3074
+ return lens;
3075
+ }
3076
+
3077
+ // src/radiant/commands/emergent.ts
3078
+ async function emergent(input) {
3079
+ const lens = resolveLens2(input.lensId);
3080
+ const windowDays = input.windowDays ?? 14;
3081
+ let statedIntent;
3082
+ let exocortexContext;
3083
+ let priorReadContext = "";
3084
+ if (input.exocortexPath) {
3085
+ exocortexContext = readExocortex(input.exocortexPath);
3086
+ const formatted = formatExocortexForPrompt(exocortexContext);
3087
+ if (formatted) statedIntent = formatted;
3088
+ const priorReads = loadPriorReads(input.exocortexPath);
3089
+ if (priorReads.length > 0) {
3090
+ priorReadContext = formatPriorReadsForPrompt(priorReads);
3091
+ }
3092
+ }
3093
+ const events = await fetchGitHubActivity(input.scope, input.githubToken, {
3094
+ windowDays
3095
+ });
3096
+ const classified = classifyEvents(events);
3097
+ const signals = extractSignals(classified);
3098
+ const scores = computeScores(signals, input.worldmodelContent !== "");
3099
+ const { patterns, meaning, move } = await interpretPatterns({
3100
+ signals,
3101
+ events: classified,
3102
+ worldmodelContent: input.worldmodelContent,
3103
+ lens,
3104
+ ai: input.ai,
3105
+ canonicalPatterns: input.canonicalPatterns,
3106
+ statedIntent: statedIntent ? statedIntent + (priorReadContext ? "\n\n" + priorReadContext : "") : priorReadContext || void 0
3107
+ });
3108
+ const rewrittenPatterns = patterns.map((p) => lens.rewrite(p));
3109
+ const allDescriptions = rewrittenPatterns.map((p) => p.description).join("\n");
3110
+ const voiceViolations = checkForbiddenPhrases(lens, allDescriptions);
3111
+ let governance;
3112
+ if (input.worldPath) {
3113
+ try {
3114
+ governance = await auditGovernance(classified, input.worldPath);
3115
+ } catch {
3116
+ }
3117
+ }
3118
+ const rendered = render({
3119
+ scope: input.scope,
3120
+ windowDays,
3121
+ eventCount: events.length,
3122
+ signals,
3123
+ patterns: rewrittenPatterns,
3124
+ scores,
3125
+ lens,
3126
+ meaning: meaning || void 0,
3127
+ move: move || void 0,
3128
+ governance
3129
+ });
3130
+ if (input.exocortexPath) {
3131
+ try {
3132
+ const readPath = writeRead(input.exocortexPath, rendered.frontmatter, rendered.text);
3133
+ const priorReads = loadPriorReads(input.exocortexPath);
3134
+ const currentPatternNames = rewrittenPatterns.map((p) => p.name);
3135
+ const persistence = computePersistence(priorReads, currentPatternNames);
3136
+ const triggeredItems = governance ? [
3137
+ ...governance.human.details.map((d) => d.ruleId).filter(Boolean),
3138
+ ...governance.cyber.details.map((d) => d.ruleId).filter(Boolean),
3139
+ ...governance.joint.details.map((d) => d.ruleId).filter(Boolean)
3140
+ ] : [];
3141
+ updateKnowledge(input.exocortexPath, persistence, {
3142
+ triggeredItems,
3143
+ totalReads: priorReads.length + 1
3144
+ });
3145
+ } catch {
3146
+ }
3147
+ }
3148
+ return {
3149
+ text: rendered.text,
3150
+ frontmatter: rendered.frontmatter,
3151
+ voiceViolations,
3152
+ voiceClean: voiceViolations.length === 0,
3153
+ signals,
3154
+ scores,
3155
+ eventCount: events.length
3156
+ };
3157
+ }
3158
+ function computeScores(signals, worldmodelLoaded) {
3159
+ const gate = DEFAULT_EVIDENCE_GATE;
3160
+ const lifeSignals = signals.filter((s) => s.domain === "life");
3161
+ const A_L = scoreLife(
3162
+ { dimensions: lifeSignals.map(signalToDimension) },
3163
+ gate
3164
+ );
3165
+ const cyberSignals = signals.filter((s) => s.domain === "cyber");
3166
+ const A_C = scoreCyber(
3167
+ { dimensions: cyberSignals.map(signalToDimension) },
3168
+ gate
3169
+ );
3170
+ const jointSignals = signals.filter((s) => s.domain === "joint");
3171
+ const A_N = scoreNeuroVerse(
3172
+ jointSignals.map(signalToBridging),
3173
+ worldmodelLoaded,
3174
+ gate
3175
+ );
3176
+ const R = scoreComposite(A_L, A_C, A_N);
3177
+ return { A_L, A_C, A_N, R };
3178
+ }
3179
+ function signalToDimension(s) {
3180
+ return {
3181
+ id: s.id,
3182
+ score: s.score,
3183
+ eventCount: s.eventCount,
3184
+ confidence: s.confidence
3185
+ };
3186
+ }
3187
+ function signalToBridging(s) {
3188
+ return {
3189
+ component: "ALIGN",
3190
+ // Proxy: joint signals → ALIGN component
3191
+ score: s.score,
3192
+ eventCount: s.eventCount,
3193
+ confidence: s.confidence
3194
+ };
3195
+ }
3196
+ function resolveLens2(id) {
3197
+ const lens = getLens(id);
3198
+ if (!lens) {
3199
+ throw new Error(
3200
+ `Lens "${id}" not found. Check the id or register the lens.`
3201
+ );
3202
+ }
3203
+ return lens;
3204
+ }
3205
+
3206
+ // src/radiant/index.ts
3207
+ var RADIANT_PACKAGE_VERSION = "0.0.0";
3208
+ // Annotate the CommonJS export names for ESM import in node:
3209
+ 0 && (module.exports = {
3210
+ DEFAULT_EVIDENCE_GATE,
3211
+ DEFAULT_SIGNAL_EXTRACTORS,
3212
+ LENSES,
3213
+ RADIANT_PACKAGE_VERSION,
3214
+ auditGovernance,
3215
+ aukiBuilderLens,
3216
+ checkForbiddenPhrases,
3217
+ classifyActorDomain,
3218
+ classifyEvents,
3219
+ composeSystemPrompt,
3220
+ computePersistence,
3221
+ createAnthropicAI,
3222
+ createMockAI,
3223
+ createMockGitHubAdapter,
3224
+ emergent,
3225
+ extractSignals,
3226
+ fetchGitHubActivity,
3227
+ formatExocortexForPrompt,
3228
+ formatPriorReadsForPrompt,
3229
+ formatScope,
3230
+ getLens,
3231
+ interpretPatterns,
3232
+ isPresent,
3233
+ isScored,
3234
+ isSentinel,
3235
+ listLenses,
3236
+ loadPriorReads,
3237
+ parseRepoScope,
3238
+ presenceAverage,
3239
+ readExocortex,
3240
+ render,
3241
+ scoreComposite,
3242
+ scoreCyber,
3243
+ scoreLife,
3244
+ scoreNeuroVerse,
3245
+ summarizeExocortex,
3246
+ think,
3247
+ updateKnowledge,
3248
+ writeRead
3249
+ });