@neuroverseos/governance 0.8.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +8 -0
- package/README.md +180 -10
- package/dist/{chunk-MC6O5GV5.js → chunk-3ZWU7C43.js} +1056 -135
- package/dist/{chunk-VGFDMPVB.js → chunk-TCGGED4G.js} +283 -1
- package/dist/cli/neuroverse.cjs +2000 -460
- package/dist/cli/radiant.cjs +1452 -237
- package/dist/cli/radiant.js +62 -24
- package/dist/cli/worldmodel.cjs +1157 -823
- package/dist/cli/worldmodel.js +116 -1
- package/dist/{lenses-K5FVSALR.js → lenses-XDWK6ZKI.js} +5 -3
- package/dist/radiant/index.cjs +953 -130
- package/dist/radiant/index.d.cts +271 -10
- package/dist/radiant/index.d.ts +271 -10
- package/dist/radiant/index.js +41 -397
- package/dist/{server-DFNY5N5A.js → server-JKUBUK5H.js} +2 -2
- package/dist/worldmodel-create-5SWHVNMQ.js +195 -0
- package/examples/radiant-weekly-workflow.yml +81 -0
- package/package.json +2 -1
package/dist/cli/worldmodel.cjs
CHANGED
|
@@ -3,6 +3,9 @@ var __defProp = Object.defineProperty;
|
|
|
3
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __esm = (fn, res) => function __init() {
|
|
7
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
8
|
+
};
|
|
6
9
|
var __export = (target, all) => {
|
|
7
10
|
for (var name in all)
|
|
8
11
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -17,885 +20,1101 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
17
20
|
};
|
|
18
21
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
22
|
|
|
20
|
-
// src/
|
|
21
|
-
var
|
|
22
|
-
__export(
|
|
23
|
-
|
|
23
|
+
// src/engine/worldmodel-compiler.ts
|
|
24
|
+
var worldmodel_compiler_exports = {};
|
|
25
|
+
__export(worldmodel_compiler_exports, {
|
|
26
|
+
compileWorldModel: () => compileWorldModel,
|
|
27
|
+
emitContextsConfig: () => emitContextsConfig,
|
|
28
|
+
emitLensSuggestions: () => emitLensSuggestions,
|
|
29
|
+
emitOverlapMap: () => emitOverlapMap,
|
|
30
|
+
emitSignalSchema: () => emitSignalSchema,
|
|
31
|
+
emitWorldMarkdown: () => emitWorldMarkdown
|
|
24
32
|
});
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
var import_fs = require("fs");
|
|
28
|
-
var import_path = require("path");
|
|
29
|
-
|
|
30
|
-
// src/engine/worldmodel-parser.ts
|
|
31
|
-
function splitSections(markdown) {
|
|
32
|
-
const lines = markdown.split("\n");
|
|
33
|
-
let frontmatter = "";
|
|
34
|
-
let bodyStart = 0;
|
|
35
|
-
if (lines[0]?.trim() === "---") {
|
|
36
|
-
const endIdx = lines.indexOf("---", 1);
|
|
37
|
-
if (endIdx > 0) {
|
|
38
|
-
frontmatter = lines.slice(1, endIdx).join("\n");
|
|
39
|
-
bodyStart = endIdx + 1;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
const sections = [];
|
|
43
|
-
let currentSection = null;
|
|
44
|
-
const contentLines = [];
|
|
45
|
-
for (let i = bodyStart; i < lines.length; i++) {
|
|
46
|
-
const line = lines[i];
|
|
47
|
-
if (line.startsWith("# ")) {
|
|
48
|
-
if (currentSection) {
|
|
49
|
-
currentSection.content = contentLines.join("\n").trim();
|
|
50
|
-
sections.push(currentSection);
|
|
51
|
-
contentLines.length = 0;
|
|
52
|
-
}
|
|
53
|
-
currentSection = {
|
|
54
|
-
name: line.replace(/^#\s+/, "").trim(),
|
|
55
|
-
content: "",
|
|
56
|
-
startLine: i + 1
|
|
57
|
-
// 1-based
|
|
58
|
-
};
|
|
59
|
-
} else if (currentSection) {
|
|
60
|
-
contentLines.push(line);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
if (currentSection) {
|
|
64
|
-
currentSection.content = contentLines.join("\n").trim();
|
|
65
|
-
sections.push(currentSection);
|
|
66
|
-
}
|
|
67
|
-
return { frontmatter, sections };
|
|
33
|
+
function toSnakeCase(text) {
|
|
34
|
+
return text.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_|_$/g, "");
|
|
68
35
|
}
|
|
69
|
-
function
|
|
70
|
-
|
|
71
|
-
const sections = [];
|
|
72
|
-
let currentSection = null;
|
|
73
|
-
const contentLines = [];
|
|
74
|
-
for (let i = 0; i < lines.length; i++) {
|
|
75
|
-
const line = lines[i];
|
|
76
|
-
if (line.startsWith("## ")) {
|
|
77
|
-
if (currentSection) {
|
|
78
|
-
currentSection.content = contentLines.join("\n").trim();
|
|
79
|
-
sections.push(currentSection);
|
|
80
|
-
contentLines.length = 0;
|
|
81
|
-
}
|
|
82
|
-
currentSection = {
|
|
83
|
-
name: line.replace(/^##\s+/, "").trim(),
|
|
84
|
-
content: "",
|
|
85
|
-
startLine: baseLine + i
|
|
86
|
-
};
|
|
87
|
-
} else if (currentSection) {
|
|
88
|
-
contentLines.push(line);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
if (currentSection) {
|
|
92
|
-
currentSection.content = contentLines.join("\n").trim();
|
|
93
|
-
sections.push(currentSection);
|
|
94
|
-
}
|
|
95
|
-
return sections;
|
|
36
|
+
function toKebabCase2(text) {
|
|
37
|
+
return text.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
|
|
96
38
|
}
|
|
97
|
-
function
|
|
98
|
-
|
|
99
|
-
const sections = [];
|
|
100
|
-
let currentSection = null;
|
|
101
|
-
const contentLines = [];
|
|
102
|
-
for (let i = 0; i < lines.length; i++) {
|
|
103
|
-
const line = lines[i];
|
|
104
|
-
if (line.startsWith("### ")) {
|
|
105
|
-
if (currentSection) {
|
|
106
|
-
currentSection.content = contentLines.join("\n").trim();
|
|
107
|
-
sections.push(currentSection);
|
|
108
|
-
contentLines.length = 0;
|
|
109
|
-
}
|
|
110
|
-
currentSection = {
|
|
111
|
-
name: line.replace(/^###\s+/, "").trim(),
|
|
112
|
-
content: "",
|
|
113
|
-
startLine: baseLine + i
|
|
114
|
-
};
|
|
115
|
-
} else if (currentSection) {
|
|
116
|
-
contentLines.push(line);
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
if (currentSection) {
|
|
120
|
-
currentSection.content = contentLines.join("\n").trim();
|
|
121
|
-
sections.push(currentSection);
|
|
122
|
-
}
|
|
123
|
-
return sections;
|
|
39
|
+
function titleCase(text) {
|
|
40
|
+
return text.split(/[\s_-]+/).map((w) => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase()).join(" ");
|
|
124
41
|
}
|
|
125
|
-
function
|
|
126
|
-
const
|
|
127
|
-
const
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
const line = lines[i];
|
|
132
|
-
if (line.startsWith("#### ")) {
|
|
133
|
-
if (currentSection) {
|
|
134
|
-
currentSection.content = contentLines.join("\n").trim();
|
|
135
|
-
sections.push(currentSection);
|
|
136
|
-
contentLines.length = 0;
|
|
137
|
-
}
|
|
138
|
-
currentSection = {
|
|
139
|
-
name: line.replace(/^####\s+/, "").trim(),
|
|
140
|
-
content: "",
|
|
141
|
-
startLine: baseLine + i
|
|
142
|
-
};
|
|
143
|
-
} else if (currentSection) {
|
|
144
|
-
contentLines.push(line);
|
|
42
|
+
function matchSignal(behaviorText, signals) {
|
|
43
|
+
const lowerText = behaviorText.toLowerCase();
|
|
44
|
+
for (const signal of signals) {
|
|
45
|
+
const signalWords = signal.toLowerCase().split("_");
|
|
46
|
+
if (signalWords.some((w) => w.length > 3 && lowerText.includes(w))) {
|
|
47
|
+
return signal;
|
|
145
48
|
}
|
|
146
49
|
}
|
|
147
|
-
|
|
148
|
-
currentSection.content = contentLines.join("\n").trim();
|
|
149
|
-
sections.push(currentSection);
|
|
150
|
-
}
|
|
151
|
-
return sections;
|
|
50
|
+
return "alignment_score";
|
|
152
51
|
}
|
|
153
|
-
function
|
|
154
|
-
const
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
52
|
+
function emitWorldMarkdown(model) {
|
|
53
|
+
const lines = [];
|
|
54
|
+
const worldId = model.frontmatter.model_id;
|
|
55
|
+
const worldName = model.frontmatter.name;
|
|
56
|
+
const version = model.frontmatter.version;
|
|
57
|
+
lines.push("---");
|
|
58
|
+
lines.push(`world_id: ${worldId}`);
|
|
59
|
+
lines.push(`name: ${worldName}`);
|
|
60
|
+
lines.push(`version: ${version}`);
|
|
61
|
+
lines.push("runtime_mode: COMPLIANCE");
|
|
62
|
+
lines.push("default_profile: aligned");
|
|
63
|
+
lines.push("alternative_profile: drifting");
|
|
64
|
+
lines.push("---");
|
|
65
|
+
lines.push("");
|
|
66
|
+
lines.push("# Thesis");
|
|
67
|
+
lines.push("");
|
|
68
|
+
lines.push(model.geometry.mission);
|
|
69
|
+
if (model.geometry.centerIdentity) {
|
|
70
|
+
lines.push(
|
|
71
|
+
`When all domains are aligned, the system operates as: ${model.geometry.centerIdentity}.`
|
|
72
|
+
);
|
|
170
73
|
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
const
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
if (inComment) {
|
|
183
|
-
if (trimmed.includes("-->")) {
|
|
184
|
-
inComment = false;
|
|
185
|
-
}
|
|
186
|
-
continue;
|
|
187
|
-
}
|
|
188
|
-
if (trimmed && !trimmed.startsWith("#")) {
|
|
189
|
-
textLines.push(trimmed);
|
|
74
|
+
lines.push("");
|
|
75
|
+
lines.push("# Invariants");
|
|
76
|
+
lines.push("");
|
|
77
|
+
let invariantIdx = 0;
|
|
78
|
+
for (const domain of model.geometry.domains) {
|
|
79
|
+
for (const value of domain.values) {
|
|
80
|
+
invariantIdx++;
|
|
81
|
+
const invId = `${toSnakeCase(domain.name)}_value_${String(invariantIdx).padStart(2, "0")}`;
|
|
82
|
+
lines.push(
|
|
83
|
+
`- \`${invId}\` \u2014 ${value} [${domain.name}] (structural, immutable)`
|
|
84
|
+
);
|
|
190
85
|
}
|
|
191
86
|
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
87
|
+
lines.push("");
|
|
88
|
+
lines.push("# State");
|
|
89
|
+
lines.push("");
|
|
90
|
+
lines.push("## alignment_score");
|
|
91
|
+
lines.push("- type: number");
|
|
92
|
+
lines.push("- min: 0");
|
|
93
|
+
lines.push("- max: 100");
|
|
94
|
+
lines.push("- step: 5");
|
|
95
|
+
lines.push("- default: 70");
|
|
96
|
+
lines.push("- label: Alignment Score");
|
|
97
|
+
lines.push(
|
|
98
|
+
"- description: Composite behavioral alignment metric derived from all signals"
|
|
99
|
+
);
|
|
100
|
+
lines.push("");
|
|
101
|
+
for (const signal of model.evolution.signals) {
|
|
102
|
+
const signalId = toSnakeCase(signal);
|
|
103
|
+
const signalLabel = titleCase(signal);
|
|
104
|
+
lines.push(`## ${signalId}`);
|
|
105
|
+
lines.push("- type: number");
|
|
106
|
+
lines.push("- min: 0");
|
|
107
|
+
lines.push("- max: 100");
|
|
108
|
+
lines.push("- step: 5");
|
|
109
|
+
lines.push("- default: 70");
|
|
110
|
+
lines.push(`- label: ${signalLabel}`);
|
|
111
|
+
lines.push(`- description: Behavioral signal measuring ${signal.replace(/_/g, " ")}`);
|
|
112
|
+
lines.push("");
|
|
207
113
|
}
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
}
|
|
240
|
-
const h2Sections = splitH2Sections(section.content, section.startLine);
|
|
241
|
-
const missionSection = h2Sections.find((s) => s.name.toLowerCase() === "mission");
|
|
242
|
-
if (missionSection) {
|
|
243
|
-
geometry.mission = extractTextContent(missionSection.content);
|
|
114
|
+
lines.push("# Assumptions");
|
|
115
|
+
lines.push("");
|
|
116
|
+
lines.push("## aligned");
|
|
117
|
+
lines.push("- name: Aligned");
|
|
118
|
+
lines.push("- description: All behavioral signals at healthy levels");
|
|
119
|
+
lines.push("- pressure_level: low");
|
|
120
|
+
lines.push("");
|
|
121
|
+
lines.push("## drifting");
|
|
122
|
+
lines.push("- name: Drifting");
|
|
123
|
+
lines.push("- description: Behavioral signals under pressure with drift risk");
|
|
124
|
+
lines.push("- pressure_level: high");
|
|
125
|
+
lines.push("");
|
|
126
|
+
lines.push("# Rules");
|
|
127
|
+
lines.push("");
|
|
128
|
+
let ruleIdx = 0;
|
|
129
|
+
for (const drift of model.evolution.driftBehaviors) {
|
|
130
|
+
ruleIdx++;
|
|
131
|
+
const ruleId = `rule-${String(ruleIdx).padStart(3, "0")}`;
|
|
132
|
+
const matchedSignal = matchSignal(drift, model.evolution.signals);
|
|
133
|
+
const signalId = toSnakeCase(matchedSignal);
|
|
134
|
+
lines.push(`## ${ruleId}: ${drift} (degradation)`);
|
|
135
|
+
lines.push(`Drift behavior detected: ${drift}`);
|
|
136
|
+
lines.push("");
|
|
137
|
+
lines.push(`When ${signalId} < 50 [state]`);
|
|
138
|
+
lines.push("Then alignment_score *= 0.80");
|
|
139
|
+
lines.push("");
|
|
140
|
+
lines.push(`> trigger: ${signalId} drops below threshold`);
|
|
141
|
+
lines.push(`> rule: Drift behavior weakens alignment`);
|
|
142
|
+
lines.push(`> shift: Behavioral alignment decreases`);
|
|
143
|
+
lines.push(`> effect: Alignment score reduced by 20%`);
|
|
144
|
+
lines.push("");
|
|
244
145
|
}
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
});
|
|
146
|
+
for (const aligned of model.evolution.alignedBehaviors) {
|
|
147
|
+
ruleIdx++;
|
|
148
|
+
const ruleId = `rule-${String(ruleIdx).padStart(3, "0")}`;
|
|
149
|
+
const matchedSignal = matchSignal(aligned, model.evolution.signals);
|
|
150
|
+
const signalId = toSnakeCase(matchedSignal);
|
|
151
|
+
lines.push(`## ${ruleId}: ${aligned} (advantage)`);
|
|
152
|
+
lines.push(`Aligned behavior reinforced: ${aligned}`);
|
|
153
|
+
lines.push("");
|
|
154
|
+
lines.push(`When ${signalId} >= 70 [state]`);
|
|
155
|
+
lines.push("Then alignment_score *= 1.10");
|
|
156
|
+
lines.push("");
|
|
157
|
+
lines.push(`> trigger: ${signalId} above healthy threshold`);
|
|
158
|
+
lines.push(`> rule: Aligned behavior strengthens system`);
|
|
159
|
+
lines.push(`> shift: Behavioral alignment increases`);
|
|
160
|
+
lines.push(`> effect: Alignment score boosted by 10%`);
|
|
161
|
+
lines.push("");
|
|
252
162
|
}
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
const
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
line: ds.startLine,
|
|
276
|
-
section: "Domains",
|
|
277
|
-
message: `Domain '${ds.name}' has no skills defined. Skills are the capabilities within this domain.`,
|
|
278
|
-
severity: "warning"
|
|
279
|
-
});
|
|
280
|
-
}
|
|
281
|
-
if (domain.values.length === 0) {
|
|
282
|
-
issues.push({
|
|
283
|
-
line: ds.startLine,
|
|
284
|
-
section: "Domains",
|
|
285
|
-
message: `Domain '${ds.name}' has no values defined. Behavior has no constraints without values.`,
|
|
286
|
-
severity: "warning"
|
|
287
|
-
});
|
|
288
|
-
}
|
|
289
|
-
geometry.domains.push(domain);
|
|
290
|
-
}
|
|
163
|
+
for (let i = 0; i < model.evolution.decisionPriorities.length; i++) {
|
|
164
|
+
ruleIdx++;
|
|
165
|
+
const priority = model.evolution.decisionPriorities[i];
|
|
166
|
+
const ruleId = `rule-${String(ruleIdx).padStart(3, "0")}`;
|
|
167
|
+
lines.push(
|
|
168
|
+
`## ${ruleId}: ${priority.preferred} over ${priority.over} (structural)`
|
|
169
|
+
);
|
|
170
|
+
lines.push(
|
|
171
|
+
`Priority: ${priority.preferred} takes precedence over ${priority.over} in tradeoff situations.`
|
|
172
|
+
);
|
|
173
|
+
lines.push("");
|
|
174
|
+
lines.push("When alignment_score < 40 [state]");
|
|
175
|
+
lines.push("Then alignment_score *= 0.70");
|
|
176
|
+
lines.push("Collapse: alignment_score < 10");
|
|
177
|
+
lines.push("");
|
|
178
|
+
lines.push(`> trigger: Alignment score critically low`);
|
|
179
|
+
lines.push(
|
|
180
|
+
`> rule: Priority violation \u2014 ${priority.preferred} must outweigh ${priority.over}`
|
|
181
|
+
);
|
|
182
|
+
lines.push(`> shift: System enters structural enforcement`);
|
|
183
|
+
lines.push(`> effect: Alignment sharply reduced; collapse if critical`);
|
|
184
|
+
lines.push("");
|
|
291
185
|
}
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
186
|
+
lines.push("# Gates");
|
|
187
|
+
lines.push("");
|
|
188
|
+
lines.push("- STRONG: alignment_score >= 85");
|
|
189
|
+
lines.push("- STABLE: alignment_score >= 65");
|
|
190
|
+
lines.push("- WATCHING: alignment_score >= 45");
|
|
191
|
+
lines.push("- FRAGILE: alignment_score > 30");
|
|
192
|
+
lines.push("- MISALIGNED: alignment_score <= 30");
|
|
193
|
+
lines.push("");
|
|
194
|
+
lines.push("# Outcomes");
|
|
195
|
+
lines.push("");
|
|
196
|
+
lines.push("## alignment_score");
|
|
197
|
+
lines.push("- type: number");
|
|
198
|
+
lines.push("- range: 0-100");
|
|
199
|
+
lines.push("- display: percentage");
|
|
200
|
+
lines.push("- label: Alignment Score");
|
|
201
|
+
lines.push("- primary: true");
|
|
202
|
+
lines.push("");
|
|
203
|
+
for (const signal of model.evolution.signals) {
|
|
204
|
+
const signalId = toSnakeCase(signal);
|
|
205
|
+
const signalLabel = titleCase(signal);
|
|
206
|
+
lines.push(`## ${signalId}`);
|
|
207
|
+
lines.push("- type: number");
|
|
208
|
+
lines.push("- range: 0-100");
|
|
209
|
+
lines.push("- display: percentage");
|
|
210
|
+
lines.push(`- label: ${signalLabel}`);
|
|
211
|
+
lines.push("");
|
|
299
212
|
}
|
|
300
|
-
const
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
const
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
issues.push({
|
|
323
|
-
line: overlapsSection.startLine + i,
|
|
324
|
-
section: "Overlap Effects",
|
|
325
|
-
message: `Overlap references unknown domain '${domainB}'. Must reference a declared domain.`,
|
|
326
|
-
severity: "warning"
|
|
327
|
-
});
|
|
328
|
-
}
|
|
329
|
-
geometry.overlapEffects.push({
|
|
330
|
-
domainA,
|
|
331
|
-
domainB,
|
|
332
|
-
effect,
|
|
333
|
-
line: overlapsSection.startLine + i
|
|
334
|
-
});
|
|
335
|
-
} else {
|
|
336
|
-
issues.push({
|
|
337
|
-
line: overlapsSection.startLine + i,
|
|
338
|
-
section: "Overlap Effects",
|
|
339
|
-
message: `Cannot parse overlap: '${bullet}'. Expected format: 'Domain A + Domain B = Emergent State'.`,
|
|
340
|
-
severity: "warning"
|
|
341
|
-
});
|
|
213
|
+
const lensSuggestions = buildLensSuggestions(model);
|
|
214
|
+
if (lensSuggestions.length > 0) {
|
|
215
|
+
lines.push("# Lenses");
|
|
216
|
+
lines.push("- policy: role_default");
|
|
217
|
+
lines.push("");
|
|
218
|
+
for (const lens of lensSuggestions) {
|
|
219
|
+
lines.push(`## ${lens.id}`);
|
|
220
|
+
lines.push(`- tagline: ${lens.tagline}`);
|
|
221
|
+
lines.push(
|
|
222
|
+
`- description: Lens derived from ${lens.derived_from.domainA} and ${lens.derived_from.domainB} interaction, producing ${lens.derived_from.effect}.`
|
|
223
|
+
);
|
|
224
|
+
lines.push(`- formality: ${lens.tone.formality}`);
|
|
225
|
+
lines.push(`- verbosity: ${lens.tone.verbosity}`);
|
|
226
|
+
lines.push(`- emotion: ${lens.tone.emotion}`);
|
|
227
|
+
lines.push(`- confidence: ${lens.tone.confidence}`);
|
|
228
|
+
lines.push("- tags: behavioral, worldmodel, overlap");
|
|
229
|
+
lines.push("- default_for_roles: all");
|
|
230
|
+
lines.push("- priority: 50");
|
|
231
|
+
lines.push("- stackable: true");
|
|
232
|
+
lines.push("");
|
|
233
|
+
for (const directive of lens.directives) {
|
|
234
|
+
lines.push(`> ${directive.scope}: ${directive.instruction}`);
|
|
342
235
|
}
|
|
236
|
+
lines.push("");
|
|
343
237
|
}
|
|
344
238
|
}
|
|
345
|
-
|
|
346
|
-
issues.push({
|
|
347
|
-
line: overlapsSection?.startLine ?? section.startLine,
|
|
348
|
-
section: "Overlap Effects",
|
|
349
|
-
message: 'No overlap effects defined. Define what emerges when two domains interact well (e.g., "Domain A + Domain B = Inspiration").',
|
|
350
|
-
severity: "warning"
|
|
351
|
-
});
|
|
352
|
-
}
|
|
353
|
-
const identitySection = h2Sections.find(
|
|
354
|
-
(s) => s.name.toLowerCase() === "center identity"
|
|
355
|
-
);
|
|
356
|
-
if (identitySection) {
|
|
357
|
-
geometry.centerIdentity = extractTextContent(identitySection.content);
|
|
358
|
-
}
|
|
359
|
-
if (!geometry.centerIdentity) {
|
|
360
|
-
issues.push({
|
|
361
|
-
line: identitySection?.startLine ?? section.startLine,
|
|
362
|
-
section: "Center Identity",
|
|
363
|
-
message: "No center identity defined. Define what the system becomes when all domains are aligned \u2014 the core identity.",
|
|
364
|
-
severity: "warning"
|
|
365
|
-
});
|
|
366
|
-
}
|
|
367
|
-
return geometry;
|
|
239
|
+
return lines.join("\n");
|
|
368
240
|
}
|
|
369
|
-
function
|
|
370
|
-
const
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
241
|
+
function emitSignalSchema(model) {
|
|
242
|
+
const signals = model.evolution.signals.map((signal) => ({
|
|
243
|
+
id: toSnakeCase(signal),
|
|
244
|
+
name: titleCase(signal),
|
|
245
|
+
type: "number",
|
|
246
|
+
default: 70
|
|
247
|
+
}));
|
|
248
|
+
return {
|
|
249
|
+
model_id: model.frontmatter.model_id,
|
|
250
|
+
signals
|
|
374
251
|
};
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
if (authoritySection) {
|
|
389
|
-
modifiers.authorityLayers = parseBulletList(authoritySection.content);
|
|
390
|
-
}
|
|
391
|
-
const spatialSection = h2Sections.find(
|
|
392
|
-
(s) => s.name.toLowerCase() === "spatial contexts"
|
|
393
|
-
);
|
|
394
|
-
if (spatialSection) {
|
|
395
|
-
modifiers.spatialContexts = parseBulletList(spatialSection.content);
|
|
396
|
-
}
|
|
397
|
-
const rulesSection = h2Sections.find(
|
|
398
|
-
(s) => s.name.toLowerCase() === "interpretation rules"
|
|
399
|
-
);
|
|
400
|
-
if (rulesSection) {
|
|
401
|
-
modifiers.interpretationRules = parseBulletList(rulesSection.content);
|
|
252
|
+
}
|
|
253
|
+
function emitOverlapMap(model) {
|
|
254
|
+
const pairings = model.geometry.overlapEffects.map((o) => ({
|
|
255
|
+
domainA: o.domainA,
|
|
256
|
+
domainB: o.domainB,
|
|
257
|
+
effect: o.effect
|
|
258
|
+
}));
|
|
259
|
+
const matrix = {};
|
|
260
|
+
for (const overlap of model.geometry.overlapEffects) {
|
|
261
|
+
const keyA = toKebabCase2(overlap.domainA);
|
|
262
|
+
const keyB = toKebabCase2(overlap.domainB);
|
|
263
|
+
if (!matrix[keyA]) matrix[keyA] = {};
|
|
264
|
+
matrix[keyA][keyB] = overlap.effect;
|
|
402
265
|
}
|
|
403
|
-
return
|
|
266
|
+
return {
|
|
267
|
+
model_id: model.frontmatter.model_id,
|
|
268
|
+
pairings,
|
|
269
|
+
matrix
|
|
270
|
+
};
|
|
404
271
|
}
|
|
405
|
-
function
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
evolutionConditions: []
|
|
272
|
+
function emitContextsConfig(model) {
|
|
273
|
+
return {
|
|
274
|
+
model_id: model.frontmatter.model_id,
|
|
275
|
+
authority_layers: model.modifiers.authorityLayers,
|
|
276
|
+
spatial_contexts: model.modifiers.spatialContexts,
|
|
277
|
+
interpretation_rules: model.modifiers.interpretationRules
|
|
412
278
|
};
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
}
|
|
422
|
-
const h2Sections = splitH2Sections(section.content, section.startLine);
|
|
423
|
-
const alignedSection = h2Sections.find(
|
|
424
|
-
(s) => s.name.toLowerCase() === "aligned behaviors"
|
|
425
|
-
);
|
|
426
|
-
if (alignedSection) {
|
|
427
|
-
evolution.alignedBehaviors = parseBulletList(alignedSection.content);
|
|
428
|
-
}
|
|
429
|
-
if (evolution.alignedBehaviors.length === 0) {
|
|
430
|
-
issues.push({
|
|
431
|
-
line: alignedSection?.startLine ?? section.startLine,
|
|
432
|
-
section: "Aligned Behaviors",
|
|
433
|
-
message: "No aligned behaviors defined. Define what success looks like in action.",
|
|
434
|
-
severity: "warning"
|
|
435
|
-
});
|
|
436
|
-
}
|
|
437
|
-
const driftSection = h2Sections.find(
|
|
438
|
-
(s) => s.name.toLowerCase() === "drift behaviors"
|
|
439
|
-
);
|
|
440
|
-
if (driftSection) {
|
|
441
|
-
evolution.driftBehaviors = parseBulletList(driftSection.content);
|
|
279
|
+
}
|
|
280
|
+
function deriveTone(domainA, domainB) {
|
|
281
|
+
const combined = `${domainA} ${domainB}`.toLowerCase();
|
|
282
|
+
let formality = "neutral";
|
|
283
|
+
if (/strateg|technic|analytic|research|engineer/.test(combined)) {
|
|
284
|
+
formality = "professional";
|
|
285
|
+
} else if (/narrat|story|communi|creative/.test(combined)) {
|
|
286
|
+
formality = "casual";
|
|
442
287
|
}
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
severity: "warning"
|
|
449
|
-
});
|
|
288
|
+
let verbosity = "balanced";
|
|
289
|
+
if (/foresight|scenario|plan|design/.test(combined)) {
|
|
290
|
+
verbosity = "detailed";
|
|
291
|
+
} else if (/prosper|negotiat|stakeholder/.test(combined)) {
|
|
292
|
+
verbosity = "concise";
|
|
450
293
|
}
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
if (
|
|
455
|
-
|
|
294
|
+
let emotion = "neutral";
|
|
295
|
+
if (/empath|emoti|care|safe|trust/.test(combined)) {
|
|
296
|
+
emotion = "warm";
|
|
297
|
+
} else if (/analytic|system|data/.test(combined)) {
|
|
298
|
+
emotion = "clinical";
|
|
456
299
|
}
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
severity: "error"
|
|
463
|
-
});
|
|
300
|
+
let confidence = "balanced";
|
|
301
|
+
if (/lead|command|decis|strateg/.test(combined)) {
|
|
302
|
+
confidence = "authoritative";
|
|
303
|
+
} else if (/explor|experiment|creat/.test(combined)) {
|
|
304
|
+
confidence = "exploratory";
|
|
464
305
|
}
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
line: prioritiesSection.startLine + i,
|
|
482
|
-
section: "Decision Priorities",
|
|
483
|
-
message: `Cannot parse priority: '${bullet}'. Expected format: 'preferred > over'.`,
|
|
484
|
-
severity: "warning"
|
|
485
|
-
});
|
|
486
|
-
}
|
|
306
|
+
return { formality, verbosity, emotion, confidence };
|
|
307
|
+
}
|
|
308
|
+
function buildLensSuggestions(model) {
|
|
309
|
+
const lenses = [];
|
|
310
|
+
const domainMap = new Map(model.geometry.domains.map((d) => [d.name.toLowerCase(), d]));
|
|
311
|
+
for (const overlap of model.geometry.overlapEffects) {
|
|
312
|
+
const lensId = toKebabCase2(overlap.effect);
|
|
313
|
+
const tone = deriveTone(overlap.domainA, overlap.domainB);
|
|
314
|
+
const domainAData = domainMap.get(overlap.domainA.toLowerCase());
|
|
315
|
+
const domainBData = domainMap.get(overlap.domainB.toLowerCase());
|
|
316
|
+
const directives = [];
|
|
317
|
+
if (domainAData && domainAData.skills.length > 0) {
|
|
318
|
+
directives.push({
|
|
319
|
+
scope: "response_framing",
|
|
320
|
+
instruction: `Approach through the lens of ${domainAData.skills.join(", ").toLowerCase()}.`
|
|
321
|
+
});
|
|
487
322
|
}
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
323
|
+
if (domainBData && domainBData.values.length > 0) {
|
|
324
|
+
directives.push({
|
|
325
|
+
scope: "behavior_shaping",
|
|
326
|
+
instruction: `Maintain ${domainBData.values.join(", ").toLowerCase()} in all responses.`
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
directives.push({
|
|
330
|
+
scope: "value_emphasis",
|
|
331
|
+
instruction: `Emphasize ${overlap.effect.toLowerCase()} as the emergent state of aligned behavior.`
|
|
495
332
|
});
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
message: "Signals defined but no drift behaviors. System cannot detect failure without drift definitions.",
|
|
508
|
-
severity: "warning"
|
|
333
|
+
lenses.push({
|
|
334
|
+
id: lensId,
|
|
335
|
+
name: titleCase(overlap.effect),
|
|
336
|
+
tagline: `${overlap.effect} through ${overlap.domainA} and ${overlap.domainB}.`,
|
|
337
|
+
derived_from: {
|
|
338
|
+
domainA: overlap.domainA,
|
|
339
|
+
domainB: overlap.domainB,
|
|
340
|
+
effect: overlap.effect
|
|
341
|
+
},
|
|
342
|
+
tone,
|
|
343
|
+
directives
|
|
509
344
|
});
|
|
510
345
|
}
|
|
511
|
-
return
|
|
346
|
+
return lenses;
|
|
512
347
|
}
|
|
513
|
-
function
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
348
|
+
function emitLensSuggestions(model) {
|
|
349
|
+
return buildLensSuggestions(model);
|
|
350
|
+
}
|
|
351
|
+
function compileWorldModel(model) {
|
|
352
|
+
return {
|
|
353
|
+
worldMarkdown: emitWorldMarkdown(model),
|
|
354
|
+
signalSchema: emitSignalSchema(model),
|
|
355
|
+
overlapMap: emitOverlapMap(model),
|
|
356
|
+
contextsConfig: emitContextsConfig(model),
|
|
357
|
+
lensSuggestions: emitLensSuggestions(model)
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
var init_worldmodel_compiler = __esm({
|
|
361
|
+
"src/engine/worldmodel-compiler.ts"() {
|
|
362
|
+
"use strict";
|
|
523
363
|
}
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
)
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
)
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
// src/cli/worldmodel-create.ts
|
|
367
|
+
var worldmodel_create_exports = {};
|
|
368
|
+
__export(worldmodel_create_exports, {
|
|
369
|
+
askQuestions: () => askQuestions,
|
|
370
|
+
saveWorldmodel: () => saveWorldmodel,
|
|
371
|
+
structureWorldmodel: () => structureWorldmodel
|
|
372
|
+
});
|
|
373
|
+
async function askQuestions() {
|
|
374
|
+
const rl = (0, import_readline.createInterface)({
|
|
375
|
+
input: process.stdin,
|
|
376
|
+
output: process.stderr
|
|
377
|
+
// questions to stderr so stdout stays clean
|
|
378
|
+
});
|
|
379
|
+
const answers = {};
|
|
380
|
+
process.stderr.write("\n");
|
|
381
|
+
process.stderr.write(" \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557\n");
|
|
382
|
+
process.stderr.write(" \u2551 NeuroVerseOS \u2014 Build your thinking constitution \u2551\n");
|
|
383
|
+
process.stderr.write(" \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D\n");
|
|
384
|
+
process.stderr.write("\n");
|
|
385
|
+
process.stderr.write(" Answer these questions in your own words.\n");
|
|
386
|
+
process.stderr.write(" There are no wrong answers \u2014 just say what you mean.\n");
|
|
387
|
+
process.stderr.write(" The AI will structure your answers into a worldmodel.\n\n");
|
|
388
|
+
for (const q of QUESTIONS) {
|
|
389
|
+
const answer = await new Promise((resolve3) => {
|
|
390
|
+
process.stderr.write(` \x1B[1m${q.question}\x1B[0m
|
|
391
|
+
`);
|
|
392
|
+
process.stderr.write(` \x1B[2m${q.placeholder}\x1B[0m
|
|
393
|
+
`);
|
|
394
|
+
rl.question(" > ", (ans) => {
|
|
395
|
+
process.stderr.write("\n");
|
|
396
|
+
resolve3(ans.trim());
|
|
397
|
+
});
|
|
544
398
|
});
|
|
399
|
+
answers[q.id] = answer;
|
|
545
400
|
}
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
}
|
|
558
|
-
return {
|
|
559
|
-
model: {
|
|
560
|
-
frontmatter,
|
|
561
|
-
geometry,
|
|
562
|
-
modifiers,
|
|
563
|
-
evolution
|
|
401
|
+
rl.close();
|
|
402
|
+
return answers;
|
|
403
|
+
}
|
|
404
|
+
async function structureWorldmodel(answers, apiKey) {
|
|
405
|
+
const prompt = buildStructuringPrompt(answers);
|
|
406
|
+
const res = await fetch("https://api.anthropic.com/v1/messages", {
|
|
407
|
+
method: "POST",
|
|
408
|
+
headers: {
|
|
409
|
+
"x-api-key": apiKey,
|
|
410
|
+
"anthropic-version": "2023-06-01",
|
|
411
|
+
"content-type": "application/json"
|
|
564
412
|
},
|
|
565
|
-
|
|
566
|
-
|
|
413
|
+
body: JSON.stringify({
|
|
414
|
+
model: "claude-sonnet-4-20250514",
|
|
415
|
+
max_tokens: 4096,
|
|
416
|
+
system: "You are a behavioral model architect. You take conversational answers about an organization's values, purpose, and priorities, and structure them into a precise .worldmodel.md file that follows the NeuroVerseOS three-layer format. Output ONLY the markdown file content, nothing else.",
|
|
417
|
+
messages: [{ role: "user", content: prompt }]
|
|
418
|
+
})
|
|
419
|
+
});
|
|
420
|
+
if (!res.ok) {
|
|
421
|
+
throw new Error(`AI structuring failed: ${res.status}`);
|
|
422
|
+
}
|
|
423
|
+
const data = await res.json();
|
|
424
|
+
const text = data.content?.filter((c) => c.type === "text").map((c) => c.text ?? "").join("");
|
|
425
|
+
if (!text) throw new Error("AI returned no content");
|
|
426
|
+
return text.replace(/^```markdown\n?/, "").replace(/\n?```$/, "").trim();
|
|
567
427
|
}
|
|
428
|
+
function buildStructuringPrompt(answers) {
|
|
429
|
+
return `Structure these conversational answers into a .worldmodel.md file.
|
|
568
430
|
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
431
|
+
The file MUST follow this exact three-layer format:
|
|
432
|
+
|
|
433
|
+
---
|
|
434
|
+
name: ${answers.name}
|
|
435
|
+
version: 1.0.0
|
|
436
|
+
---
|
|
437
|
+
|
|
438
|
+
# Core Model Geometry
|
|
439
|
+
|
|
440
|
+
## Mission
|
|
441
|
+
(from the mission answer)
|
|
442
|
+
|
|
443
|
+
## Domains
|
|
444
|
+
(2-4 domains from the domains answer, each with:)
|
|
445
|
+
### Domain Name
|
|
446
|
+
#### Skills (8-10 skills per domain, inferred from the answers)
|
|
447
|
+
#### Values (3-4 values per domain, drawn from the non-negotiables + mission)
|
|
448
|
+
|
|
449
|
+
## Overlap Effects
|
|
450
|
+
(from the overlaps answer, formatted as: Domain A + Domain B = Emergent State)
|
|
451
|
+
|
|
452
|
+
## Center Identity
|
|
453
|
+
(from the center answer)
|
|
454
|
+
|
|
455
|
+
# Contextual Modifiers
|
|
456
|
+
|
|
457
|
+
## Authority Layers
|
|
458
|
+
(infer 4-5 authority levels appropriate to this organization)
|
|
459
|
+
|
|
460
|
+
## Spatial Contexts
|
|
461
|
+
(infer 4-5 contexts where behavior happens)
|
|
462
|
+
|
|
463
|
+
## Interpretation Rules
|
|
464
|
+
(infer 3-5 rules about how context changes meaning)
|
|
465
|
+
|
|
466
|
+
# Evolution Layer
|
|
467
|
+
|
|
468
|
+
## Aligned Behaviors
|
|
469
|
+
(from the success answer, expanded to 5-8 items)
|
|
470
|
+
|
|
471
|
+
## Drift Behaviors
|
|
472
|
+
(from the drift answer, expanded to 5-8 items)
|
|
473
|
+
|
|
474
|
+
## Signals
|
|
475
|
+
(infer 5-7 observable signals from the answers, snake_case)
|
|
476
|
+
|
|
477
|
+
## Decision Priorities
|
|
478
|
+
(from the priorities answer, formatted as: preferred > secondary)
|
|
479
|
+
|
|
480
|
+
## Evolution Conditions
|
|
481
|
+
(infer 3-5 conditions for when the model should adapt)
|
|
482
|
+
|
|
483
|
+
HERE ARE THE ANSWERS:
|
|
484
|
+
|
|
485
|
+
Name: ${answers.name}
|
|
486
|
+
|
|
487
|
+
Mission: ${answers.mission}
|
|
488
|
+
|
|
489
|
+
Domains: ${answers.domains}
|
|
490
|
+
|
|
491
|
+
Overlaps: ${answers.overlaps}
|
|
492
|
+
|
|
493
|
+
Center identity: ${answers.center}
|
|
494
|
+
|
|
495
|
+
Non-negotiables: ${answers.nonnegotiables}
|
|
496
|
+
|
|
497
|
+
Success looks like: ${answers.success}
|
|
498
|
+
|
|
499
|
+
Drift looks like: ${answers.drift}
|
|
500
|
+
|
|
501
|
+
Priorities: ${answers.priorities}
|
|
502
|
+
|
|
503
|
+
Output ONLY the .worldmodel.md content. No explanation. No commentary. Just the file.`;
|
|
572
504
|
}
|
|
573
|
-
function
|
|
574
|
-
|
|
505
|
+
function saveWorldmodel(content, outputPath) {
|
|
506
|
+
const resolved = (0, import_path.resolve)(outputPath);
|
|
507
|
+
(0, import_fs.writeFileSync)(resolved, content, "utf-8");
|
|
508
|
+
return resolved;
|
|
575
509
|
}
|
|
576
|
-
|
|
577
|
-
|
|
510
|
+
var import_readline, import_fs, import_path, QUESTIONS;
|
|
511
|
+
var init_worldmodel_create = __esm({
|
|
512
|
+
"src/cli/worldmodel-create.ts"() {
|
|
513
|
+
"use strict";
|
|
514
|
+
import_readline = require("readline");
|
|
515
|
+
import_fs = require("fs");
|
|
516
|
+
import_path = require("path");
|
|
517
|
+
QUESTIONS = [
|
|
518
|
+
{
|
|
519
|
+
id: "name",
|
|
520
|
+
question: "What should we call this model? (Your name, your org, your project)",
|
|
521
|
+
placeholder: 'e.g., "Kirsten", "Auki", "My Startup"'
|
|
522
|
+
},
|
|
523
|
+
{
|
|
524
|
+
id: "mission",
|
|
525
|
+
question: "In one or two sentences \u2014 what does this system exist to do? Not a slogan. The real purpose.",
|
|
526
|
+
placeholder: 'e.g., "Protect human thinking while expanding cognitive capability through AI"'
|
|
527
|
+
},
|
|
528
|
+
{
|
|
529
|
+
id: "domains",
|
|
530
|
+
question: "What are the 2-3 big areas of focus? Not departments \u2014 the major kinds of work that matter most. Separate with commas.",
|
|
531
|
+
placeholder: 'e.g., "Safety and boundaries, Individual authority, AI as cognitive extension"'
|
|
532
|
+
},
|
|
533
|
+
{
|
|
534
|
+
id: "overlaps",
|
|
535
|
+
question: "When those areas work well TOGETHER, what does that feel like? Name a feeling for each pair.",
|
|
536
|
+
placeholder: 'e.g., "Safety + Authority = Trust, Authority + AI = Possibility"'
|
|
537
|
+
},
|
|
538
|
+
{
|
|
539
|
+
id: "center",
|
|
540
|
+
question: "When EVERYTHING is aligned \u2014 all areas working together \u2014 what does the system become? One name or phrase.",
|
|
541
|
+
placeholder: 'e.g., "The Sovereign Conduit", "Collective Vanguard Leader"'
|
|
542
|
+
},
|
|
543
|
+
{
|
|
544
|
+
id: "nonnegotiables",
|
|
545
|
+
question: "What's absolutely non-negotiable? What would you walk away over? List a few.",
|
|
546
|
+
placeholder: 'e.g., "Humans retain authority over thinking. AI extends, never replaces. People can always leave."'
|
|
547
|
+
},
|
|
548
|
+
{
|
|
549
|
+
id: "success",
|
|
550
|
+
question: `What does success look like in action? What would you point at and say "that's what I mean"?`,
|
|
551
|
+
placeholder: 'e.g., "Someone maintaining clear authorship of decisions even when AI contributed"'
|
|
552
|
+
},
|
|
553
|
+
{
|
|
554
|
+
id: "drift",
|
|
555
|
+
question: "What does drift look like? What would worry you if you saw it happening?",
|
|
556
|
+
placeholder: 'e.g., "Decision ownership quietly shifting to AI without explicit delegation"'
|
|
557
|
+
},
|
|
558
|
+
{
|
|
559
|
+
id: "priorities",
|
|
560
|
+
question: 'When tradeoffs appear, what wins? Give a few "X over Y" pairs.',
|
|
561
|
+
placeholder: 'e.g., "Safety over speed, sovereignty over convenience, diversity over uniformity"'
|
|
562
|
+
}
|
|
563
|
+
];
|
|
564
|
+
}
|
|
565
|
+
});
|
|
566
|
+
|
|
567
|
+
// src/cli/worldmodel.ts
|
|
568
|
+
var worldmodel_exports = {};
|
|
569
|
+
__export(worldmodel_exports, {
|
|
570
|
+
main: () => main
|
|
571
|
+
});
|
|
572
|
+
module.exports = __toCommonJS(worldmodel_exports);
|
|
573
|
+
var import_promises = require("fs/promises");
|
|
574
|
+
var import_fs2 = require("fs");
|
|
575
|
+
var import_path2 = require("path");
|
|
576
|
+
|
|
577
|
+
// src/engine/worldmodel-parser.ts
|
|
578
|
+
function splitSections(markdown) {
|
|
579
|
+
const lines = markdown.split("\n");
|
|
580
|
+
let frontmatter = "";
|
|
581
|
+
let bodyStart = 0;
|
|
582
|
+
if (lines[0]?.trim() === "---") {
|
|
583
|
+
const endIdx = lines.indexOf("---", 1);
|
|
584
|
+
if (endIdx > 0) {
|
|
585
|
+
frontmatter = lines.slice(1, endIdx).join("\n");
|
|
586
|
+
bodyStart = endIdx + 1;
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
const sections = [];
|
|
590
|
+
let currentSection = null;
|
|
591
|
+
const contentLines = [];
|
|
592
|
+
for (let i = bodyStart; i < lines.length; i++) {
|
|
593
|
+
const line = lines[i];
|
|
594
|
+
if (line.startsWith("# ")) {
|
|
595
|
+
if (currentSection) {
|
|
596
|
+
currentSection.content = contentLines.join("\n").trim();
|
|
597
|
+
sections.push(currentSection);
|
|
598
|
+
contentLines.length = 0;
|
|
599
|
+
}
|
|
600
|
+
currentSection = {
|
|
601
|
+
name: line.replace(/^#\s+/, "").trim(),
|
|
602
|
+
content: "",
|
|
603
|
+
startLine: i + 1
|
|
604
|
+
// 1-based
|
|
605
|
+
};
|
|
606
|
+
} else if (currentSection) {
|
|
607
|
+
contentLines.push(line);
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
if (currentSection) {
|
|
611
|
+
currentSection.content = contentLines.join("\n").trim();
|
|
612
|
+
sections.push(currentSection);
|
|
613
|
+
}
|
|
614
|
+
return { frontmatter, sections };
|
|
578
615
|
}
|
|
579
|
-
function
|
|
580
|
-
const
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
616
|
+
function splitH2Sections(content, baseLine) {
|
|
617
|
+
const lines = content.split("\n");
|
|
618
|
+
const sections = [];
|
|
619
|
+
let currentSection = null;
|
|
620
|
+
const contentLines = [];
|
|
621
|
+
for (let i = 0; i < lines.length; i++) {
|
|
622
|
+
const line = lines[i];
|
|
623
|
+
if (line.startsWith("## ")) {
|
|
624
|
+
if (currentSection) {
|
|
625
|
+
currentSection.content = contentLines.join("\n").trim();
|
|
626
|
+
sections.push(currentSection);
|
|
627
|
+
contentLines.length = 0;
|
|
628
|
+
}
|
|
629
|
+
currentSection = {
|
|
630
|
+
name: line.replace(/^##\s+/, "").trim(),
|
|
631
|
+
content: "",
|
|
632
|
+
startLine: baseLine + i
|
|
633
|
+
};
|
|
634
|
+
} else if (currentSection) {
|
|
635
|
+
contentLines.push(line);
|
|
585
636
|
}
|
|
586
637
|
}
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
const lines = [];
|
|
591
|
-
const worldId = model.frontmatter.model_id;
|
|
592
|
-
const worldName = model.frontmatter.name;
|
|
593
|
-
const version = model.frontmatter.version;
|
|
594
|
-
lines.push("---");
|
|
595
|
-
lines.push(`world_id: ${worldId}`);
|
|
596
|
-
lines.push(`name: ${worldName}`);
|
|
597
|
-
lines.push(`version: ${version}`);
|
|
598
|
-
lines.push("runtime_mode: COMPLIANCE");
|
|
599
|
-
lines.push("default_profile: aligned");
|
|
600
|
-
lines.push("alternative_profile: drifting");
|
|
601
|
-
lines.push("---");
|
|
602
|
-
lines.push("");
|
|
603
|
-
lines.push("# Thesis");
|
|
604
|
-
lines.push("");
|
|
605
|
-
lines.push(model.geometry.mission);
|
|
606
|
-
if (model.geometry.centerIdentity) {
|
|
607
|
-
lines.push(
|
|
608
|
-
`When all domains are aligned, the system operates as: ${model.geometry.centerIdentity}.`
|
|
609
|
-
);
|
|
638
|
+
if (currentSection) {
|
|
639
|
+
currentSection.content = contentLines.join("\n").trim();
|
|
640
|
+
sections.push(currentSection);
|
|
610
641
|
}
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
)
|
|
642
|
+
return sections;
|
|
643
|
+
}
|
|
644
|
+
function splitH3Sections(content, baseLine) {
|
|
645
|
+
const lines = content.split("\n");
|
|
646
|
+
const sections = [];
|
|
647
|
+
let currentSection = null;
|
|
648
|
+
const contentLines = [];
|
|
649
|
+
for (let i = 0; i < lines.length; i++) {
|
|
650
|
+
const line = lines[i];
|
|
651
|
+
if (line.startsWith("### ")) {
|
|
652
|
+
if (currentSection) {
|
|
653
|
+
currentSection.content = contentLines.join("\n").trim();
|
|
654
|
+
sections.push(currentSection);
|
|
655
|
+
contentLines.length = 0;
|
|
656
|
+
}
|
|
657
|
+
currentSection = {
|
|
658
|
+
name: line.replace(/^###\s+/, "").trim(),
|
|
659
|
+
content: "",
|
|
660
|
+
startLine: baseLine + i
|
|
661
|
+
};
|
|
662
|
+
} else if (currentSection) {
|
|
663
|
+
contentLines.push(line);
|
|
622
664
|
}
|
|
623
665
|
}
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
lines.push("## alignment_score");
|
|
628
|
-
lines.push("- type: number");
|
|
629
|
-
lines.push("- min: 0");
|
|
630
|
-
lines.push("- max: 100");
|
|
631
|
-
lines.push("- step: 5");
|
|
632
|
-
lines.push("- default: 70");
|
|
633
|
-
lines.push("- label: Alignment Score");
|
|
634
|
-
lines.push(
|
|
635
|
-
"- description: Composite behavioral alignment metric derived from all signals"
|
|
636
|
-
);
|
|
637
|
-
lines.push("");
|
|
638
|
-
for (const signal of model.evolution.signals) {
|
|
639
|
-
const signalId = toSnakeCase(signal);
|
|
640
|
-
const signalLabel = titleCase(signal);
|
|
641
|
-
lines.push(`## ${signalId}`);
|
|
642
|
-
lines.push("- type: number");
|
|
643
|
-
lines.push("- min: 0");
|
|
644
|
-
lines.push("- max: 100");
|
|
645
|
-
lines.push("- step: 5");
|
|
646
|
-
lines.push("- default: 70");
|
|
647
|
-
lines.push(`- label: ${signalLabel}`);
|
|
648
|
-
lines.push(`- description: Behavioral signal measuring ${signal.replace(/_/g, " ")}`);
|
|
649
|
-
lines.push("");
|
|
650
|
-
}
|
|
651
|
-
lines.push("# Assumptions");
|
|
652
|
-
lines.push("");
|
|
653
|
-
lines.push("## aligned");
|
|
654
|
-
lines.push("- name: Aligned");
|
|
655
|
-
lines.push("- description: All behavioral signals at healthy levels");
|
|
656
|
-
lines.push("- pressure_level: low");
|
|
657
|
-
lines.push("");
|
|
658
|
-
lines.push("## drifting");
|
|
659
|
-
lines.push("- name: Drifting");
|
|
660
|
-
lines.push("- description: Behavioral signals under pressure with drift risk");
|
|
661
|
-
lines.push("- pressure_level: high");
|
|
662
|
-
lines.push("");
|
|
663
|
-
lines.push("# Rules");
|
|
664
|
-
lines.push("");
|
|
665
|
-
let ruleIdx = 0;
|
|
666
|
-
for (const drift of model.evolution.driftBehaviors) {
|
|
667
|
-
ruleIdx++;
|
|
668
|
-
const ruleId = `rule-${String(ruleIdx).padStart(3, "0")}`;
|
|
669
|
-
const matchedSignal = matchSignal(drift, model.evolution.signals);
|
|
670
|
-
const signalId = toSnakeCase(matchedSignal);
|
|
671
|
-
lines.push(`## ${ruleId}: ${drift} (degradation)`);
|
|
672
|
-
lines.push(`Drift behavior detected: ${drift}`);
|
|
673
|
-
lines.push("");
|
|
674
|
-
lines.push(`When ${signalId} < 50 [state]`);
|
|
675
|
-
lines.push("Then alignment_score *= 0.80");
|
|
676
|
-
lines.push("");
|
|
677
|
-
lines.push(`> trigger: ${signalId} drops below threshold`);
|
|
678
|
-
lines.push(`> rule: Drift behavior weakens alignment`);
|
|
679
|
-
lines.push(`> shift: Behavioral alignment decreases`);
|
|
680
|
-
lines.push(`> effect: Alignment score reduced by 20%`);
|
|
681
|
-
lines.push("");
|
|
666
|
+
if (currentSection) {
|
|
667
|
+
currentSection.content = contentLines.join("\n").trim();
|
|
668
|
+
sections.push(currentSection);
|
|
682
669
|
}
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
670
|
+
return sections;
|
|
671
|
+
}
|
|
672
|
+
function splitH4Sections(content, baseLine) {
|
|
673
|
+
const lines = content.split("\n");
|
|
674
|
+
const sections = [];
|
|
675
|
+
let currentSection = null;
|
|
676
|
+
const contentLines = [];
|
|
677
|
+
for (let i = 0; i < lines.length; i++) {
|
|
678
|
+
const line = lines[i];
|
|
679
|
+
if (line.startsWith("#### ")) {
|
|
680
|
+
if (currentSection) {
|
|
681
|
+
currentSection.content = contentLines.join("\n").trim();
|
|
682
|
+
sections.push(currentSection);
|
|
683
|
+
contentLines.length = 0;
|
|
684
|
+
}
|
|
685
|
+
currentSection = {
|
|
686
|
+
name: line.replace(/^####\s+/, "").trim(),
|
|
687
|
+
content: "",
|
|
688
|
+
startLine: baseLine + i
|
|
689
|
+
};
|
|
690
|
+
} else if (currentSection) {
|
|
691
|
+
contentLines.push(line);
|
|
692
|
+
}
|
|
699
693
|
}
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
const ruleId = `rule-${String(ruleIdx).padStart(3, "0")}`;
|
|
704
|
-
lines.push(
|
|
705
|
-
`## ${ruleId}: ${priority.preferred} over ${priority.over} (structural)`
|
|
706
|
-
);
|
|
707
|
-
lines.push(
|
|
708
|
-
`Priority: ${priority.preferred} takes precedence over ${priority.over} in tradeoff situations.`
|
|
709
|
-
);
|
|
710
|
-
lines.push("");
|
|
711
|
-
lines.push("When alignment_score < 40 [state]");
|
|
712
|
-
lines.push("Then alignment_score *= 0.70");
|
|
713
|
-
lines.push("Collapse: alignment_score < 10");
|
|
714
|
-
lines.push("");
|
|
715
|
-
lines.push(`> trigger: Alignment score critically low`);
|
|
716
|
-
lines.push(
|
|
717
|
-
`> rule: Priority violation \u2014 ${priority.preferred} must outweigh ${priority.over}`
|
|
718
|
-
);
|
|
719
|
-
lines.push(`> shift: System enters structural enforcement`);
|
|
720
|
-
lines.push(`> effect: Alignment sharply reduced; collapse if critical`);
|
|
721
|
-
lines.push("");
|
|
694
|
+
if (currentSection) {
|
|
695
|
+
currentSection.content = contentLines.join("\n").trim();
|
|
696
|
+
sections.push(currentSection);
|
|
722
697
|
}
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
const signalLabel = titleCase(signal);
|
|
743
|
-
lines.push(`## ${signalId}`);
|
|
744
|
-
lines.push("- type: number");
|
|
745
|
-
lines.push("- range: 0-100");
|
|
746
|
-
lines.push("- display: percentage");
|
|
747
|
-
lines.push(`- label: ${signalLabel}`);
|
|
748
|
-
lines.push("");
|
|
698
|
+
return sections;
|
|
699
|
+
}
|
|
700
|
+
function parseBulletList(content) {
|
|
701
|
+
const items = [];
|
|
702
|
+
let inComment = false;
|
|
703
|
+
for (const line of content.split("\n")) {
|
|
704
|
+
const trimmed = line.trim();
|
|
705
|
+
if (trimmed.startsWith("<!--")) {
|
|
706
|
+
inComment = true;
|
|
707
|
+
}
|
|
708
|
+
if (inComment) {
|
|
709
|
+
if (trimmed.includes("-->")) {
|
|
710
|
+
inComment = false;
|
|
711
|
+
}
|
|
712
|
+
continue;
|
|
713
|
+
}
|
|
714
|
+
if (trimmed.startsWith("- ")) {
|
|
715
|
+
items.push(trimmed.slice(2).trim());
|
|
716
|
+
}
|
|
749
717
|
}
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
lines.push(`- confidence: ${lens.tone.confidence}`);
|
|
765
|
-
lines.push("- tags: behavioral, worldmodel, overlap");
|
|
766
|
-
lines.push("- default_for_roles: all");
|
|
767
|
-
lines.push("- priority: 50");
|
|
768
|
-
lines.push("- stackable: true");
|
|
769
|
-
lines.push("");
|
|
770
|
-
for (const directive of lens.directives) {
|
|
771
|
-
lines.push(`> ${directive.scope}: ${directive.instruction}`);
|
|
718
|
+
return items;
|
|
719
|
+
}
|
|
720
|
+
function extractTextContent(content) {
|
|
721
|
+
const lines = content.split("\n");
|
|
722
|
+
const textLines = [];
|
|
723
|
+
let inComment = false;
|
|
724
|
+
for (const line of lines) {
|
|
725
|
+
const trimmed = line.trim();
|
|
726
|
+
if (trimmed.startsWith("<!--")) {
|
|
727
|
+
inComment = true;
|
|
728
|
+
}
|
|
729
|
+
if (inComment) {
|
|
730
|
+
if (trimmed.includes("-->")) {
|
|
731
|
+
inComment = false;
|
|
772
732
|
}
|
|
773
|
-
|
|
733
|
+
continue;
|
|
734
|
+
}
|
|
735
|
+
if (trimmed && !trimmed.startsWith("#")) {
|
|
736
|
+
textLines.push(trimmed);
|
|
774
737
|
}
|
|
775
738
|
}
|
|
776
|
-
return
|
|
739
|
+
return textLines.join("\n").trim();
|
|
777
740
|
}
|
|
778
|
-
function
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
741
|
+
function toKebabCase(name) {
|
|
742
|
+
return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
|
|
743
|
+
}
|
|
744
|
+
function parseFrontmatter(yaml, issues) {
|
|
745
|
+
const result = {};
|
|
746
|
+
for (const line of yaml.split("\n")) {
|
|
747
|
+
const trimmed = line.trim();
|
|
748
|
+
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
749
|
+
const colonIdx = trimmed.indexOf(":");
|
|
750
|
+
if (colonIdx === -1) continue;
|
|
751
|
+
const key = trimmed.slice(0, colonIdx).trim();
|
|
752
|
+
const value = trimmed.slice(colonIdx + 1).trim();
|
|
753
|
+
result[key] = value;
|
|
754
|
+
}
|
|
755
|
+
const name = result.name || "";
|
|
756
|
+
if (!name) {
|
|
757
|
+
issues.push({
|
|
758
|
+
line: 1,
|
|
759
|
+
section: "frontmatter",
|
|
760
|
+
message: "Missing name in frontmatter. Provide a human-readable model name.",
|
|
761
|
+
severity: "error"
|
|
762
|
+
});
|
|
763
|
+
}
|
|
764
|
+
const model_id = result.model_id || toKebabCase(name);
|
|
785
765
|
return {
|
|
786
|
-
model_id
|
|
787
|
-
|
|
766
|
+
model_id,
|
|
767
|
+
name,
|
|
768
|
+
version: result.version || "1.0.0"
|
|
788
769
|
};
|
|
789
770
|
}
|
|
790
|
-
function
|
|
791
|
-
const
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
771
|
+
function parseGeometry(section, issues) {
|
|
772
|
+
const geometry = {
|
|
773
|
+
mission: "",
|
|
774
|
+
domains: [],
|
|
775
|
+
overlapEffects: [],
|
|
776
|
+
centerIdentity: ""
|
|
777
|
+
};
|
|
778
|
+
if (!section) {
|
|
779
|
+
issues.push({
|
|
780
|
+
line: 0,
|
|
781
|
+
section: "Core Model Geometry",
|
|
782
|
+
message: "Missing # Core Model Geometry section. Define the structural model: mission, domains with embedded skills and values, overlaps, and center identity.",
|
|
783
|
+
severity: "error"
|
|
784
|
+
});
|
|
785
|
+
return geometry;
|
|
802
786
|
}
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
787
|
+
const h2Sections = splitH2Sections(section.content, section.startLine);
|
|
788
|
+
const missionSection = h2Sections.find((s) => s.name.toLowerCase() === "mission");
|
|
789
|
+
if (missionSection) {
|
|
790
|
+
geometry.mission = extractTextContent(missionSection.content);
|
|
791
|
+
}
|
|
792
|
+
if (!geometry.mission) {
|
|
793
|
+
issues.push({
|
|
794
|
+
line: missionSection?.startLine ?? section.startLine,
|
|
795
|
+
section: "Mission",
|
|
796
|
+
message: "Missing ## Mission. Define what this system is trying to achieve \u2014 the core aim, not a slogan.",
|
|
797
|
+
severity: "error"
|
|
798
|
+
});
|
|
799
|
+
}
|
|
800
|
+
const domainsSection = h2Sections.find((s) => s.name.toLowerCase() === "domains");
|
|
801
|
+
if (domainsSection) {
|
|
802
|
+
const domainSections = splitH3Sections(domainsSection.content, domainsSection.startLine);
|
|
803
|
+
for (const ds of domainSections) {
|
|
804
|
+
const domain = {
|
|
805
|
+
id: toKebabCase(ds.name),
|
|
806
|
+
name: ds.name,
|
|
807
|
+
skills: [],
|
|
808
|
+
values: [],
|
|
809
|
+
line: ds.startLine
|
|
810
|
+
};
|
|
811
|
+
const h4Sections = splitH4Sections(ds.content, ds.startLine);
|
|
812
|
+
const skillsH4 = h4Sections.find((s) => s.name.toLowerCase() === "skills");
|
|
813
|
+
if (skillsH4) {
|
|
814
|
+
domain.skills = parseBulletList(skillsH4.content);
|
|
815
|
+
}
|
|
816
|
+
const valuesH4 = h4Sections.find((s) => s.name.toLowerCase() === "values");
|
|
817
|
+
if (valuesH4) {
|
|
818
|
+
domain.values = parseBulletList(valuesH4.content);
|
|
819
|
+
}
|
|
820
|
+
if (domain.skills.length === 0) {
|
|
821
|
+
issues.push({
|
|
822
|
+
line: ds.startLine,
|
|
823
|
+
section: "Domains",
|
|
824
|
+
message: `Domain '${ds.name}' has no skills defined. Skills are the capabilities within this domain.`,
|
|
825
|
+
severity: "warning"
|
|
826
|
+
});
|
|
827
|
+
}
|
|
828
|
+
if (domain.values.length === 0) {
|
|
829
|
+
issues.push({
|
|
830
|
+
line: ds.startLine,
|
|
831
|
+
section: "Domains",
|
|
832
|
+
message: `Domain '${ds.name}' has no values defined. Behavior has no constraints without values.`,
|
|
833
|
+
severity: "warning"
|
|
834
|
+
});
|
|
835
|
+
}
|
|
836
|
+
geometry.domains.push(domain);
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
if (geometry.domains.length < 2) {
|
|
840
|
+
issues.push({
|
|
841
|
+
line: domainsSection?.startLine ?? section.startLine,
|
|
842
|
+
section: "Domains",
|
|
843
|
+
message: "At least 2 domains required. Domains are the major operating modes of the system, each carrying skills and values.",
|
|
844
|
+
severity: "error"
|
|
845
|
+
});
|
|
846
|
+
}
|
|
847
|
+
const overlapsSection = h2Sections.find(
|
|
848
|
+
(s) => s.name.toLowerCase() === "overlap effects"
|
|
849
|
+
);
|
|
850
|
+
if (overlapsSection) {
|
|
851
|
+
const bullets = parseBulletList(overlapsSection.content);
|
|
852
|
+
const domainNames = new Set(geometry.domains.map((d) => d.name.toLowerCase()));
|
|
853
|
+
for (let i = 0; i < bullets.length; i++) {
|
|
854
|
+
const bullet = bullets[i];
|
|
855
|
+
const match = bullet.match(/^(.+?)\s*\+\s*(.+?)\s*=\s*(.+)$/);
|
|
856
|
+
if (match) {
|
|
857
|
+
const domainA = match[1].trim();
|
|
858
|
+
const domainB = match[2].trim();
|
|
859
|
+
const effect = match[3].trim();
|
|
860
|
+
if (!domainNames.has(domainA.toLowerCase())) {
|
|
861
|
+
issues.push({
|
|
862
|
+
line: overlapsSection.startLine + i,
|
|
863
|
+
section: "Overlap Effects",
|
|
864
|
+
message: `Overlap references unknown domain '${domainA}'. Must reference a declared domain.`,
|
|
865
|
+
severity: "warning"
|
|
866
|
+
});
|
|
867
|
+
}
|
|
868
|
+
if (!domainNames.has(domainB.toLowerCase())) {
|
|
869
|
+
issues.push({
|
|
870
|
+
line: overlapsSection.startLine + i,
|
|
871
|
+
section: "Overlap Effects",
|
|
872
|
+
message: `Overlap references unknown domain '${domainB}'. Must reference a declared domain.`,
|
|
873
|
+
severity: "warning"
|
|
874
|
+
});
|
|
875
|
+
}
|
|
876
|
+
geometry.overlapEffects.push({
|
|
877
|
+
domainA,
|
|
878
|
+
domainB,
|
|
879
|
+
effect,
|
|
880
|
+
line: overlapsSection.startLine + i
|
|
881
|
+
});
|
|
882
|
+
} else {
|
|
883
|
+
issues.push({
|
|
884
|
+
line: overlapsSection.startLine + i,
|
|
885
|
+
section: "Overlap Effects",
|
|
886
|
+
message: `Cannot parse overlap: '${bullet}'. Expected format: 'Domain A + Domain B = Emergent State'.`,
|
|
887
|
+
severity: "warning"
|
|
888
|
+
});
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
if (geometry.overlapEffects.length === 0) {
|
|
893
|
+
issues.push({
|
|
894
|
+
line: overlapsSection?.startLine ?? section.startLine,
|
|
895
|
+
section: "Overlap Effects",
|
|
896
|
+
message: 'No overlap effects defined. Define what emerges when two domains interact well (e.g., "Domain A + Domain B = Inspiration").',
|
|
897
|
+
severity: "warning"
|
|
898
|
+
});
|
|
899
|
+
}
|
|
900
|
+
const identitySection = h2Sections.find(
|
|
901
|
+
(s) => s.name.toLowerCase() === "center identity"
|
|
902
|
+
);
|
|
903
|
+
if (identitySection) {
|
|
904
|
+
geometry.centerIdentity = extractTextContent(identitySection.content);
|
|
905
|
+
}
|
|
906
|
+
if (!geometry.centerIdentity) {
|
|
907
|
+
issues.push({
|
|
908
|
+
line: identitySection?.startLine ?? section.startLine,
|
|
909
|
+
section: "Center Identity",
|
|
910
|
+
message: "No center identity defined. Define what the system becomes when all domains are aligned \u2014 the core identity.",
|
|
911
|
+
severity: "warning"
|
|
912
|
+
});
|
|
913
|
+
}
|
|
914
|
+
return geometry;
|
|
915
|
+
}
|
|
916
|
+
function parseModifiers(section, issues) {
|
|
917
|
+
const modifiers = {
|
|
918
|
+
authorityLayers: [],
|
|
919
|
+
spatialContexts: [],
|
|
920
|
+
interpretationRules: []
|
|
807
921
|
};
|
|
922
|
+
if (!section) {
|
|
923
|
+
issues.push({
|
|
924
|
+
line: 0,
|
|
925
|
+
section: "Contextual Modifiers",
|
|
926
|
+
message: "Missing # Contextual Modifiers section. Define how authority, role, and spatial context change how behavior is interpreted.",
|
|
927
|
+
severity: "warning"
|
|
928
|
+
});
|
|
929
|
+
return modifiers;
|
|
930
|
+
}
|
|
931
|
+
const h2Sections = splitH2Sections(section.content, section.startLine);
|
|
932
|
+
const authoritySection = h2Sections.find(
|
|
933
|
+
(s) => s.name.toLowerCase() === "authority layers"
|
|
934
|
+
);
|
|
935
|
+
if (authoritySection) {
|
|
936
|
+
modifiers.authorityLayers = parseBulletList(authoritySection.content);
|
|
937
|
+
}
|
|
938
|
+
const spatialSection = h2Sections.find(
|
|
939
|
+
(s) => s.name.toLowerCase() === "spatial contexts"
|
|
940
|
+
);
|
|
941
|
+
if (spatialSection) {
|
|
942
|
+
modifiers.spatialContexts = parseBulletList(spatialSection.content);
|
|
943
|
+
}
|
|
944
|
+
const rulesSection = h2Sections.find(
|
|
945
|
+
(s) => s.name.toLowerCase() === "interpretation rules"
|
|
946
|
+
);
|
|
947
|
+
if (rulesSection) {
|
|
948
|
+
modifiers.interpretationRules = parseBulletList(rulesSection.content);
|
|
949
|
+
}
|
|
950
|
+
return modifiers;
|
|
808
951
|
}
|
|
809
|
-
function
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
952
|
+
function parseEvolution(section, issues) {
|
|
953
|
+
const evolution = {
|
|
954
|
+
alignedBehaviors: [],
|
|
955
|
+
driftBehaviors: [],
|
|
956
|
+
signals: [],
|
|
957
|
+
decisionPriorities: [],
|
|
958
|
+
evolutionConditions: []
|
|
815
959
|
};
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
960
|
+
if (!section) {
|
|
961
|
+
issues.push({
|
|
962
|
+
line: 0,
|
|
963
|
+
section: "Evolution Layer",
|
|
964
|
+
message: "Missing # Evolution Layer section. Define observable behaviors, signals, decision priorities, and adaptation conditions.",
|
|
965
|
+
severity: "error"
|
|
966
|
+
});
|
|
967
|
+
return evolution;
|
|
824
968
|
}
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
969
|
+
const h2Sections = splitH2Sections(section.content, section.startLine);
|
|
970
|
+
const alignedSection = h2Sections.find(
|
|
971
|
+
(s) => s.name.toLowerCase() === "aligned behaviors"
|
|
972
|
+
);
|
|
973
|
+
if (alignedSection) {
|
|
974
|
+
evolution.alignedBehaviors = parseBulletList(alignedSection.content);
|
|
830
975
|
}
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
976
|
+
if (evolution.alignedBehaviors.length === 0) {
|
|
977
|
+
issues.push({
|
|
978
|
+
line: alignedSection?.startLine ?? section.startLine,
|
|
979
|
+
section: "Aligned Behaviors",
|
|
980
|
+
message: "No aligned behaviors defined. Define what success looks like in action.",
|
|
981
|
+
severity: "warning"
|
|
982
|
+
});
|
|
836
983
|
}
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
984
|
+
const driftSection = h2Sections.find(
|
|
985
|
+
(s) => s.name.toLowerCase() === "drift behaviors"
|
|
986
|
+
);
|
|
987
|
+
if (driftSection) {
|
|
988
|
+
evolution.driftBehaviors = parseBulletList(driftSection.content);
|
|
842
989
|
}
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
990
|
+
if (evolution.driftBehaviors.length === 0) {
|
|
991
|
+
issues.push({
|
|
992
|
+
line: driftSection?.startLine ?? section.startLine,
|
|
993
|
+
section: "Drift Behaviors",
|
|
994
|
+
message: "No drift behaviors defined. Define what misalignment looks like so the system can detect behavioral drift over time.",
|
|
995
|
+
severity: "warning"
|
|
996
|
+
});
|
|
997
|
+
}
|
|
998
|
+
const signalsSection = h2Sections.find(
|
|
999
|
+
(s) => s.name.toLowerCase() === "signals"
|
|
1000
|
+
);
|
|
1001
|
+
if (signalsSection) {
|
|
1002
|
+
evolution.signals = parseBulletList(signalsSection.content);
|
|
1003
|
+
}
|
|
1004
|
+
if (evolution.signals.length < 2) {
|
|
1005
|
+
issues.push({
|
|
1006
|
+
line: signalsSection?.startLine ?? section.startLine,
|
|
1007
|
+
section: "Signals",
|
|
1008
|
+
message: "At least 2 signals required. Signals are the observable metrics for detecting alignment or drift.",
|
|
1009
|
+
severity: "error"
|
|
1010
|
+
});
|
|
1011
|
+
}
|
|
1012
|
+
const prioritiesSection = h2Sections.find(
|
|
1013
|
+
(s) => s.name.toLowerCase() === "decision priorities"
|
|
1014
|
+
);
|
|
1015
|
+
if (prioritiesSection) {
|
|
1016
|
+
const bullets = parseBulletList(prioritiesSection.content);
|
|
1017
|
+
for (let i = 0; i < bullets.length; i++) {
|
|
1018
|
+
const bullet = bullets[i];
|
|
1019
|
+
const match = bullet.match(/^(.+?)\s*>\s*(.+)$/);
|
|
1020
|
+
if (match) {
|
|
1021
|
+
evolution.decisionPriorities.push({
|
|
1022
|
+
preferred: match[1].trim(),
|
|
1023
|
+
over: match[2].trim(),
|
|
1024
|
+
line: prioritiesSection.startLine + i
|
|
1025
|
+
});
|
|
1026
|
+
} else {
|
|
1027
|
+
issues.push({
|
|
1028
|
+
line: prioritiesSection.startLine + i,
|
|
1029
|
+
section: "Decision Priorities",
|
|
1030
|
+
message: `Cannot parse priority: '${bullet}'. Expected format: 'preferred > over'.`,
|
|
1031
|
+
severity: "warning"
|
|
1032
|
+
});
|
|
1033
|
+
}
|
|
865
1034
|
}
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
1035
|
+
}
|
|
1036
|
+
if (evolution.decisionPriorities.length === 0) {
|
|
1037
|
+
issues.push({
|
|
1038
|
+
line: prioritiesSection?.startLine ?? section.startLine,
|
|
1039
|
+
section: "Decision Priorities",
|
|
1040
|
+
message: "No decision priorities defined. Define what wins when tradeoffs appear.",
|
|
1041
|
+
severity: "warning"
|
|
869
1042
|
});
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
1043
|
+
}
|
|
1044
|
+
const evoSection = h2Sections.find(
|
|
1045
|
+
(s) => s.name.toLowerCase() === "evolution conditions"
|
|
1046
|
+
);
|
|
1047
|
+
if (evoSection) {
|
|
1048
|
+
evolution.evolutionConditions = parseBulletList(evoSection.content);
|
|
1049
|
+
}
|
|
1050
|
+
if (evolution.signals.length > 0 && evolution.driftBehaviors.length === 0) {
|
|
1051
|
+
issues.push({
|
|
1052
|
+
line: signalsSection?.startLine ?? section.startLine,
|
|
1053
|
+
section: "Evolution Layer",
|
|
1054
|
+
message: "Signals defined but no drift behaviors. System cannot detect failure without drift definitions.",
|
|
1055
|
+
severity: "warning"
|
|
881
1056
|
});
|
|
882
1057
|
}
|
|
883
|
-
return
|
|
884
|
-
}
|
|
885
|
-
function emitLensSuggestions(model) {
|
|
886
|
-
return buildLensSuggestions(model);
|
|
1058
|
+
return evolution;
|
|
887
1059
|
}
|
|
888
|
-
function
|
|
1060
|
+
function parseWorldModel(markdown) {
|
|
1061
|
+
const issues = [];
|
|
1062
|
+
if (!markdown || !markdown.trim()) {
|
|
1063
|
+
issues.push({
|
|
1064
|
+
line: 0,
|
|
1065
|
+
section: "file",
|
|
1066
|
+
message: "Empty input. Provide a .worldmodel.md file with three layers: Core Model Geometry, Contextual Modifiers, Evolution Layer.",
|
|
1067
|
+
severity: "error"
|
|
1068
|
+
});
|
|
1069
|
+
return { model: null, issues };
|
|
1070
|
+
}
|
|
1071
|
+
const { frontmatter: fmRaw, sections } = splitSections(markdown);
|
|
1072
|
+
const frontmatter = parseFrontmatter(fmRaw, issues);
|
|
1073
|
+
const geometrySection = sections.find(
|
|
1074
|
+
(s) => s.name.toLowerCase() === "core model geometry"
|
|
1075
|
+
);
|
|
1076
|
+
const modifiersSection = sections.find(
|
|
1077
|
+
(s) => s.name.toLowerCase() === "contextual modifiers"
|
|
1078
|
+
);
|
|
1079
|
+
const evolutionSection = sections.find(
|
|
1080
|
+
(s) => s.name.toLowerCase() === "evolution layer"
|
|
1081
|
+
);
|
|
1082
|
+
const geometry = parseGeometry(geometrySection, issues);
|
|
1083
|
+
const modifiers = parseModifiers(modifiersSection, issues);
|
|
1084
|
+
const evolution = parseEvolution(evolutionSection, issues);
|
|
1085
|
+
if (geometry.overlapEffects.length > 0 && !geometry.centerIdentity) {
|
|
1086
|
+
issues.push({
|
|
1087
|
+
line: 0,
|
|
1088
|
+
section: "Core Model Geometry",
|
|
1089
|
+
message: "Overlaps defined but no center identity. System lacks coherence without an aligned identity.",
|
|
1090
|
+
severity: "warning"
|
|
1091
|
+
});
|
|
1092
|
+
}
|
|
1093
|
+
const hasErrors = issues.some((i) => i.severity === "error");
|
|
1094
|
+
if (hasErrors) {
|
|
1095
|
+
return {
|
|
1096
|
+
model: {
|
|
1097
|
+
frontmatter,
|
|
1098
|
+
geometry,
|
|
1099
|
+
modifiers,
|
|
1100
|
+
evolution
|
|
1101
|
+
},
|
|
1102
|
+
issues
|
|
1103
|
+
};
|
|
1104
|
+
}
|
|
889
1105
|
return {
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
1106
|
+
model: {
|
|
1107
|
+
frontmatter,
|
|
1108
|
+
geometry,
|
|
1109
|
+
modifiers,
|
|
1110
|
+
evolution
|
|
1111
|
+
},
|
|
1112
|
+
issues
|
|
895
1113
|
};
|
|
896
1114
|
}
|
|
897
1115
|
|
|
898
1116
|
// src/cli/worldmodel.ts
|
|
1117
|
+
init_worldmodel_compiler();
|
|
899
1118
|
var BOLD = "\x1B[1m";
|
|
900
1119
|
var DIM = "\x1B[2m";
|
|
901
1120
|
var CYAN = "\x1B[36m";
|
|
@@ -968,8 +1187,8 @@ function formatIssue(issue) {
|
|
|
968
1187
|
return ` ${color}${icon}${RESET} [${issue.section}${lineRef}] ${issue.message}`;
|
|
969
1188
|
}
|
|
970
1189
|
async function readSourceFile(inputPath) {
|
|
971
|
-
const fullPath = (0,
|
|
972
|
-
if (!(0,
|
|
1190
|
+
const fullPath = (0, import_path2.resolve)(inputPath);
|
|
1191
|
+
if (!(0, import_fs2.existsSync)(fullPath)) {
|
|
973
1192
|
process.stderr.write(`File not found: ${fullPath}
|
|
974
1193
|
`);
|
|
975
1194
|
process.exit(3);
|
|
@@ -993,30 +1212,145 @@ async function cmdInit(argv) {
|
|
|
993
1212
|
const args = parseArgs(argv);
|
|
994
1213
|
if (args.help) {
|
|
995
1214
|
process.stdout.write(
|
|
996
|
-
'neuroverse worldmodel init \u2014
|
|
1215
|
+
'neuroverse worldmodel init \u2014 Create a new behavioral model\n\nWith ANTHROPIC_API_KEY set:\n Interactive \u2014 answers questions, AI structures your worldmodel.\n Your natural process: talk \u2192 structure \u2192 refine.\n\nWithout ANTHROPIC_API_KEY:\n Template \u2014 generates a scaffold you fill in manually.\n\nOptions:\n --name <name> Model name (default: "My Behavioral Model")\n --output <path> Output path (default: ./model.worldmodel.md)\n --template Force template mode even with API key set\n'
|
|
997
1216
|
);
|
|
998
1217
|
return;
|
|
999
1218
|
}
|
|
1000
1219
|
const modelName = args.name || "My Behavioral Model";
|
|
1001
|
-
const outputPath = (0,
|
|
1220
|
+
const outputPath = (0, import_path2.resolve)(
|
|
1002
1221
|
args.output || `./${toFileName(modelName)}.worldmodel.md`
|
|
1003
1222
|
);
|
|
1004
|
-
if ((0,
|
|
1223
|
+
if ((0, import_fs2.existsSync)(outputPath)) {
|
|
1005
1224
|
process.stderr.write(`File already exists: ${outputPath}
|
|
1006
1225
|
`);
|
|
1007
1226
|
process.stderr.write("Use --output to specify a different path.\n");
|
|
1008
1227
|
process.exit(1);
|
|
1009
1228
|
}
|
|
1229
|
+
const apiKey = process.env.ANTHROPIC_API_KEY;
|
|
1230
|
+
const forceTemplate = argv.includes("--template");
|
|
1231
|
+
if (apiKey && !forceTemplate && process.stdin.isTTY) {
|
|
1232
|
+
const { askQuestions: askQuestions2, structureWorldmodel: structureWorldmodel2, saveWorldmodel: saveWorldmodel2 } = await Promise.resolve().then(() => (init_worldmodel_create(), worldmodel_create_exports));
|
|
1233
|
+
process.stderr.write(`
|
|
1234
|
+
`);
|
|
1235
|
+
const answers = await askQuestions2();
|
|
1236
|
+
process.stderr.write(`${DIM}Structuring your worldmodel...${RESET}
|
|
1237
|
+
`);
|
|
1238
|
+
try {
|
|
1239
|
+
const content = await structureWorldmodel2(answers, apiKey);
|
|
1240
|
+
const dir2 = (0, import_path2.dirname)(outputPath);
|
|
1241
|
+
if (!(0, import_fs2.existsSync)(dir2)) {
|
|
1242
|
+
await (0, import_promises.mkdir)(dir2, { recursive: true });
|
|
1243
|
+
}
|
|
1244
|
+
saveWorldmodel2(content, outputPath);
|
|
1245
|
+
process.stderr.write(`
|
|
1246
|
+
${GREEN}Created${RESET} ${outputPath}
|
|
1247
|
+
`);
|
|
1248
|
+
process.stderr.write(
|
|
1249
|
+
`${DIM}Review the file, then run: neuroverse worldmodel validate ${(0, import_path2.basename)(outputPath)}${RESET}
|
|
1250
|
+
`
|
|
1251
|
+
);
|
|
1252
|
+
try {
|
|
1253
|
+
const validateResult = parseWorldModel(content);
|
|
1254
|
+
if (validateResult.model) {
|
|
1255
|
+
const m = validateResult.model;
|
|
1256
|
+
process.stderr.write(
|
|
1257
|
+
`${DIM} Domains: ${m.geometry.domains.length} Overlaps: ${m.geometry.overlapEffects.length} Signals: ${m.evolution.signals.length}${RESET}
|
|
1258
|
+
`
|
|
1259
|
+
);
|
|
1260
|
+
}
|
|
1261
|
+
const errors = validateResult.issues.filter((i) => i.severity === "error");
|
|
1262
|
+
if (errors.length > 0) {
|
|
1263
|
+
process.stderr.write(
|
|
1264
|
+
`
|
|
1265
|
+
${YELLOW}Validation found ${errors.length} issue${errors.length > 1 ? "s" : ""} \u2014 review and fix:${RESET}
|
|
1266
|
+
`
|
|
1267
|
+
);
|
|
1268
|
+
for (const issue of errors) {
|
|
1269
|
+
process.stderr.write(` ${formatIssue(issue)}
|
|
1270
|
+
`);
|
|
1271
|
+
}
|
|
1272
|
+
} else {
|
|
1273
|
+
process.stderr.write(`${GREEN}Validates cleanly!${RESET}
|
|
1274
|
+
`);
|
|
1275
|
+
try {
|
|
1276
|
+
if (!validateResult.model) throw new Error("no model");
|
|
1277
|
+
const { compileWorldModel: compileWorldModel2 } = await Promise.resolve().then(() => (init_worldmodel_compiler(), worldmodel_compiler_exports));
|
|
1278
|
+
const compiled = compileWorldModel2(validateResult.model);
|
|
1279
|
+
const outDir = (0, import_path2.dirname)(outputPath);
|
|
1280
|
+
const baseName = (0, import_path2.basename)(outputPath).replace(/\.worldmodel\.md$/, "");
|
|
1281
|
+
const worldPath = (0, import_path2.join)(outDir, `${baseName}.nv-world.md`);
|
|
1282
|
+
await (0, import_promises.writeFile)(worldPath, compiled.worldMarkdown, "utf-8");
|
|
1283
|
+
const signalsPath = (0, import_path2.join)(outDir, "signals.json");
|
|
1284
|
+
await (0, import_promises.writeFile)(signalsPath, JSON.stringify(compiled.signalSchema, null, 2), "utf-8");
|
|
1285
|
+
const overlapsPath = (0, import_path2.join)(outDir, "overlaps.json");
|
|
1286
|
+
await (0, import_promises.writeFile)(overlapsPath, JSON.stringify(compiled.overlapMap, null, 2), "utf-8");
|
|
1287
|
+
const contextsPath = (0, import_path2.join)(outDir, "contexts.json");
|
|
1288
|
+
await (0, import_promises.writeFile)(contextsPath, JSON.stringify(compiled.contextsConfig, null, 2), "utf-8");
|
|
1289
|
+
const lensesPath = (0, import_path2.join)(outDir, "lenses.json");
|
|
1290
|
+
await (0, import_promises.writeFile)(lensesPath, JSON.stringify(compiled.lensSuggestions, null, 2), "utf-8");
|
|
1291
|
+
process.stderr.write(`
|
|
1292
|
+
${GREEN}Compiled!${RESET} Token-optimized artifacts:
|
|
1293
|
+
`);
|
|
1294
|
+
process.stderr.write(`${DIM} ${worldPath}${RESET}
|
|
1295
|
+
`);
|
|
1296
|
+
process.stderr.write(`${DIM} ${signalsPath}${RESET}
|
|
1297
|
+
`);
|
|
1298
|
+
process.stderr.write(`${DIM} ${overlapsPath}${RESET}
|
|
1299
|
+
`);
|
|
1300
|
+
process.stderr.write(`${DIM} ${contextsPath}${RESET}
|
|
1301
|
+
`);
|
|
1302
|
+
process.stderr.write(`${DIM} ${lensesPath}${RESET}
|
|
1303
|
+
`);
|
|
1304
|
+
process.stderr.write(`
|
|
1305
|
+
${DIM}Source: ${outputPath} (readable, editable)${RESET}
|
|
1306
|
+
`);
|
|
1307
|
+
process.stderr.write(`${DIM}Compiled: ready for Radiant \u2014 token-optimized, no prose overhead.${RESET}
|
|
1308
|
+
`);
|
|
1309
|
+
} catch {
|
|
1310
|
+
process.stderr.write(
|
|
1311
|
+
`${DIM}Auto-compile skipped \u2014 run 'neuroverse worldmodel build ${(0, import_path2.basename)(outputPath)}' manually.${RESET}
|
|
1312
|
+
`
|
|
1313
|
+
);
|
|
1314
|
+
}
|
|
1315
|
+
}
|
|
1316
|
+
} catch {
|
|
1317
|
+
}
|
|
1318
|
+
} catch (err) {
|
|
1319
|
+
process.stderr.write(`${RED}Error:${RESET} ${err}
|
|
1320
|
+
`);
|
|
1321
|
+
process.stderr.write(
|
|
1322
|
+
`${DIM}Falling back to template mode.${RESET}
|
|
1323
|
+
|
|
1324
|
+
`
|
|
1325
|
+
);
|
|
1326
|
+
const template2 = generateScaffold(modelName);
|
|
1327
|
+
const dir2 = (0, import_path2.dirname)(outputPath);
|
|
1328
|
+
if (!(0, import_fs2.existsSync)(dir2)) {
|
|
1329
|
+
await (0, import_promises.mkdir)(dir2, { recursive: true });
|
|
1330
|
+
}
|
|
1331
|
+
await (0, import_promises.writeFile)(outputPath, template2, "utf-8");
|
|
1332
|
+
process.stderr.write(`${GREEN}Created${RESET} ${outputPath} (template)
|
|
1333
|
+
`);
|
|
1334
|
+
}
|
|
1335
|
+
return;
|
|
1336
|
+
}
|
|
1337
|
+
if (!apiKey && !forceTemplate) {
|
|
1338
|
+
process.stderr.write(
|
|
1339
|
+
`${DIM}Tip: Set ANTHROPIC_API_KEY for the guided experience \u2014 AI asks you questions and creates your worldmodel.${RESET}
|
|
1340
|
+
|
|
1341
|
+
`
|
|
1342
|
+
);
|
|
1343
|
+
}
|
|
1010
1344
|
const template = generateScaffold(modelName);
|
|
1011
|
-
const dir = (0,
|
|
1012
|
-
if (!(0,
|
|
1345
|
+
const dir = (0, import_path2.dirname)(outputPath);
|
|
1346
|
+
if (!(0, import_fs2.existsSync)(dir)) {
|
|
1013
1347
|
await (0, import_promises.mkdir)(dir, { recursive: true });
|
|
1014
1348
|
}
|
|
1015
1349
|
await (0, import_promises.writeFile)(outputPath, template, "utf-8");
|
|
1016
1350
|
process.stderr.write(`${GREEN}Created${RESET} ${outputPath}
|
|
1017
1351
|
`);
|
|
1018
1352
|
process.stderr.write(
|
|
1019
|
-
`${DIM}Edit the template, then run: neuroverse worldmodel validate ${(0,
|
|
1353
|
+
`${DIM}Edit the template, then run: neuroverse worldmodel validate ${(0, import_path2.basename)(outputPath)}${RESET}
|
|
1020
1354
|
`
|
|
1021
1355
|
);
|
|
1022
1356
|
}
|
|
@@ -1447,17 +1781,17 @@ async function cmdBuild(argv) {
|
|
|
1447
1781
|
process.stderr.write("\n");
|
|
1448
1782
|
}
|
|
1449
1783
|
const output = compileWorldModel(model);
|
|
1450
|
-
const outputDir = (0,
|
|
1784
|
+
const outputDir = (0, import_path2.resolve)(
|
|
1451
1785
|
args.output || `.neuroverse/worldmodels/${model.frontmatter.model_id}/`
|
|
1452
1786
|
);
|
|
1453
|
-
if (!(0,
|
|
1787
|
+
if (!(0, import_fs2.existsSync)(outputDir)) {
|
|
1454
1788
|
await (0, import_promises.mkdir)(outputDir, { recursive: true });
|
|
1455
1789
|
}
|
|
1456
|
-
const worldPath = (0,
|
|
1457
|
-
const signalsPath = (0,
|
|
1458
|
-
const overlapsPath = (0,
|
|
1459
|
-
const contextsPath = (0,
|
|
1460
|
-
const lensesPath = (0,
|
|
1790
|
+
const worldPath = (0, import_path2.join)(outputDir, `${model.frontmatter.model_id}.nv-world.md`);
|
|
1791
|
+
const signalsPath = (0, import_path2.join)(outputDir, "signals.json");
|
|
1792
|
+
const overlapsPath = (0, import_path2.join)(outputDir, "overlaps.json");
|
|
1793
|
+
const contextsPath = (0, import_path2.join)(outputDir, "contexts.json");
|
|
1794
|
+
const lensesPath = (0, import_path2.join)(outputDir, "lenses.json");
|
|
1461
1795
|
await Promise.all([
|
|
1462
1796
|
(0, import_promises.writeFile)(worldPath, output.worldMarkdown, "utf-8"),
|
|
1463
1797
|
(0, import_promises.writeFile)(signalsPath, JSON.stringify(output.signalSchema, null, 2) + "\n", "utf-8"),
|
|
@@ -1489,7 +1823,7 @@ async function cmdBuild(argv) {
|
|
|
1489
1823
|
`);
|
|
1490
1824
|
process.stderr.write(` ${BOLD}Output:${RESET} ${outputDir}/
|
|
1491
1825
|
`);
|
|
1492
|
-
process.stderr.write(` ${(0,
|
|
1826
|
+
process.stderr.write(` ${(0, import_path2.basename)(worldPath)}${DIM} \u2014 executable world${RESET}
|
|
1493
1827
|
`);
|
|
1494
1828
|
process.stderr.write(` signals.json${DIM} \u2014 signal schema${RESET}
|
|
1495
1829
|
`);
|
|
@@ -1525,9 +1859,9 @@ async function cmdEmitWorld(argv) {
|
|
|
1525
1859
|
const { model } = await loadAndParse(args.inputPath);
|
|
1526
1860
|
const markdown = emitWorldMarkdown(model);
|
|
1527
1861
|
if (args.output) {
|
|
1528
|
-
const dir = (0,
|
|
1529
|
-
if (!(0,
|
|
1530
|
-
await (0, import_promises.writeFile)((0,
|
|
1862
|
+
const dir = (0, import_path2.dirname)((0, import_path2.resolve)(args.output));
|
|
1863
|
+
if (!(0, import_fs2.existsSync)(dir)) await (0, import_promises.mkdir)(dir, { recursive: true });
|
|
1864
|
+
await (0, import_promises.writeFile)((0, import_path2.resolve)(args.output), markdown, "utf-8");
|
|
1531
1865
|
process.stderr.write(`${GREEN}Written${RESET} ${args.output}
|
|
1532
1866
|
`);
|
|
1533
1867
|
} else {
|