@neuroverseos/governance 0.5.1 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +55 -0
- package/dist/adapters/autoresearch.js +2 -2
- package/dist/adapters/deep-agents.js +2 -2
- package/dist/adapters/express.js +2 -2
- package/dist/adapters/github.js +2 -2
- package/dist/adapters/index.js +8 -8
- package/dist/adapters/langchain.js +2 -2
- package/dist/adapters/mentraos.js +2 -2
- package/dist/adapters/openai.js +2 -2
- package/dist/adapters/openclaw.js +2 -2
- package/dist/{add-JP7TC2K3.js → add-XSANI3FK.js} +1 -1
- package/dist/{build-THUEYMVT.js → build-UTVDGHB3.js} +4 -4
- package/dist/{chunk-TZBERHFM.js → chunk-7FL3U7Z5.js} +1 -1
- package/dist/{chunk-FGOSKQDE.js → chunk-A2UZTLRV.js} +1 -1
- package/dist/{chunk-R23T5SZG.js → chunk-B3IIPTY3.js} +1 -1
- package/dist/chunk-EQR7BGFN.js +337 -0
- package/dist/{chunk-LAKUB76X.js → chunk-FDPPZLSQ.js} +1 -1
- package/dist/{chunk-UZBW44KD.js → chunk-FKQCPRKI.js} +1 -1
- package/dist/{chunk-XPMZB46F.js → chunk-FS2UUJJO.js} +3 -3
- package/dist/{chunk-6UPEUMJ2.js → chunk-HDNDL6D5.js} +1 -1
- package/dist/{chunk-7UU7V3AD.js → chunk-IOVXB6QN.js} +1 -1
- package/dist/{chunk-EK77AJAH.js → chunk-OTZU76DH.js} +1 -1
- package/dist/{chunk-5RAQ5DZW.js → chunk-T6GMRZWC.js} +1 -1
- package/dist/{chunk-RF2L5SYG.js → chunk-TIXVEPS2.js} +1 -1
- package/dist/{chunk-TL4DLMMW.js → chunk-TJ5L2UTE.js} +1 -1
- package/dist/chunk-UGTNKTHS.js +542 -0
- package/dist/cli/neuroverse.cjs +1987 -303
- package/dist/cli/neuroverse.js +27 -19
- package/dist/cli/plan.js +1 -1
- package/dist/cli/run.js +2 -2
- package/dist/cli/worldmodel.cjs +1624 -0
- package/dist/cli/worldmodel.d.cts +24 -0
- package/dist/cli/worldmodel.d.ts +24 -0
- package/dist/cli/worldmodel.js +742 -0
- package/dist/{demo-N5K4VXJW.js → demo-6W3YXLAX.js} +2 -2
- package/dist/{derive-5LOMN7GO.js → derive-42IJW7JI.js} +3 -3
- package/dist/engine/worldmodel-compiler.cjs +366 -0
- package/dist/engine/worldmodel-compiler.d.cts +46 -0
- package/dist/engine/worldmodel-compiler.d.ts +46 -0
- package/dist/engine/worldmodel-compiler.js +17 -0
- package/dist/engine/worldmodel-parser.cjs +566 -0
- package/dist/engine/worldmodel-parser.d.cts +22 -0
- package/dist/engine/worldmodel-parser.d.ts +22 -0
- package/dist/engine/worldmodel-parser.js +7 -0
- package/dist/{equity-penalties-PYCJ3Q4U.js → equity-penalties-CCO3GVHS.js} +1 -1
- package/dist/{explain-42TVC3QD.js → explain-HDFN4ION.js} +1 -1
- package/dist/{guard-TPYDFG6V.js → guard-IHJEKHL2.js} +1 -1
- package/dist/{improve-HLZGJ54Z.js → improve-LRORRYEX.js} +1 -1
- package/dist/index.js +48 -48
- package/dist/{lens-NFGZHD76.js → lens-TLDZQXBI.js} +61 -2
- package/dist/{mcp-server-5XXNG6VC.js → mcp-server-CKYBHXWK.js} +2 -2
- package/dist/{playground-2EU5CFIH.js → playground-3TTBN7XD.js} +1 -1
- package/dist/{redteam-VK6OVHAE.js → redteam-W644UMWN.js} +1 -1
- package/dist/{session-NGA4DUPL.js → session-FMAROEIE.js} +2 -2
- package/dist/{simulate-4YNOBMES.js → simulate-VT437EEL.js} +1 -1
- package/dist/{test-HDBPMQTG.js → test-XDB2DH3L.js} +1 -1
- package/dist/{validate-6MFQZ2EG.js → validate-M52DX22Y.js} +1 -1
- package/dist/{world-H5WVURKU.js → world-O4HTQPDP.js} +1 -1
- package/dist/{world-loader-J47PCPDZ.js → world-loader-YTYFOP7D.js} +1 -1
- package/dist/worldmodel-contract-BPGhiuW5.d.cts +221 -0
- package/dist/worldmodel-contract-BPGhiuW5.d.ts +221 -0
- package/dist/worlds/auki-vanguard.worldmodel.md +116 -0
- package/dist/worlds/behavioral-demo.nv-world.md +130 -0
- package/dist/worlds/neuroverse-governance.worldmodel.md +115 -0
- package/package.json +2 -2
- package/dist/{bootstrap-IP5QMC3Q.js → bootstrap-2OW5ZLBL.js} +3 -3
- package/dist/{chunk-QZ666FCV.js → chunk-735Z3HA4.js} +3 -3
- /package/dist/{chunk-EQUAWNXW.js → chunk-I4RTIMLX.js} +0 -0
- /package/dist/{doctor-Q5APJOTS.js → doctor-XEMLO6UA.js} +0 -0
|
@@ -0,0 +1,542 @@
|
|
|
1
|
+
// src/engine/worldmodel-parser.ts
|
|
2
|
+
function splitSections(markdown) {
|
|
3
|
+
const lines = markdown.split("\n");
|
|
4
|
+
let frontmatter = "";
|
|
5
|
+
let bodyStart = 0;
|
|
6
|
+
if (lines[0]?.trim() === "---") {
|
|
7
|
+
const endIdx = lines.indexOf("---", 1);
|
|
8
|
+
if (endIdx > 0) {
|
|
9
|
+
frontmatter = lines.slice(1, endIdx).join("\n");
|
|
10
|
+
bodyStart = endIdx + 1;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
const sections = [];
|
|
14
|
+
let currentSection = null;
|
|
15
|
+
const contentLines = [];
|
|
16
|
+
for (let i = bodyStart; i < lines.length; i++) {
|
|
17
|
+
const line = lines[i];
|
|
18
|
+
if (line.startsWith("# ")) {
|
|
19
|
+
if (currentSection) {
|
|
20
|
+
currentSection.content = contentLines.join("\n").trim();
|
|
21
|
+
sections.push(currentSection);
|
|
22
|
+
contentLines.length = 0;
|
|
23
|
+
}
|
|
24
|
+
currentSection = {
|
|
25
|
+
name: line.replace(/^#\s+/, "").trim(),
|
|
26
|
+
content: "",
|
|
27
|
+
startLine: i + 1
|
|
28
|
+
// 1-based
|
|
29
|
+
};
|
|
30
|
+
} else if (currentSection) {
|
|
31
|
+
contentLines.push(line);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (currentSection) {
|
|
35
|
+
currentSection.content = contentLines.join("\n").trim();
|
|
36
|
+
sections.push(currentSection);
|
|
37
|
+
}
|
|
38
|
+
return { frontmatter, sections };
|
|
39
|
+
}
|
|
40
|
+
function splitH2Sections(content, baseLine) {
|
|
41
|
+
const lines = content.split("\n");
|
|
42
|
+
const sections = [];
|
|
43
|
+
let currentSection = null;
|
|
44
|
+
const contentLines = [];
|
|
45
|
+
for (let i = 0; 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: baseLine + i
|
|
57
|
+
};
|
|
58
|
+
} else if (currentSection) {
|
|
59
|
+
contentLines.push(line);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if (currentSection) {
|
|
63
|
+
currentSection.content = contentLines.join("\n").trim();
|
|
64
|
+
sections.push(currentSection);
|
|
65
|
+
}
|
|
66
|
+
return sections;
|
|
67
|
+
}
|
|
68
|
+
function splitH3Sections(content, baseLine) {
|
|
69
|
+
const lines = content.split("\n");
|
|
70
|
+
const sections = [];
|
|
71
|
+
let currentSection = null;
|
|
72
|
+
const contentLines = [];
|
|
73
|
+
for (let i = 0; i < lines.length; i++) {
|
|
74
|
+
const line = lines[i];
|
|
75
|
+
if (line.startsWith("### ")) {
|
|
76
|
+
if (currentSection) {
|
|
77
|
+
currentSection.content = contentLines.join("\n").trim();
|
|
78
|
+
sections.push(currentSection);
|
|
79
|
+
contentLines.length = 0;
|
|
80
|
+
}
|
|
81
|
+
currentSection = {
|
|
82
|
+
name: line.replace(/^###\s+/, "").trim(),
|
|
83
|
+
content: "",
|
|
84
|
+
startLine: baseLine + i
|
|
85
|
+
};
|
|
86
|
+
} else if (currentSection) {
|
|
87
|
+
contentLines.push(line);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
if (currentSection) {
|
|
91
|
+
currentSection.content = contentLines.join("\n").trim();
|
|
92
|
+
sections.push(currentSection);
|
|
93
|
+
}
|
|
94
|
+
return sections;
|
|
95
|
+
}
|
|
96
|
+
function splitH4Sections(content, baseLine) {
|
|
97
|
+
const lines = content.split("\n");
|
|
98
|
+
const sections = [];
|
|
99
|
+
let currentSection = null;
|
|
100
|
+
const contentLines = [];
|
|
101
|
+
for (let i = 0; i < lines.length; i++) {
|
|
102
|
+
const line = lines[i];
|
|
103
|
+
if (line.startsWith("#### ")) {
|
|
104
|
+
if (currentSection) {
|
|
105
|
+
currentSection.content = contentLines.join("\n").trim();
|
|
106
|
+
sections.push(currentSection);
|
|
107
|
+
contentLines.length = 0;
|
|
108
|
+
}
|
|
109
|
+
currentSection = {
|
|
110
|
+
name: line.replace(/^####\s+/, "").trim(),
|
|
111
|
+
content: "",
|
|
112
|
+
startLine: baseLine + i
|
|
113
|
+
};
|
|
114
|
+
} else if (currentSection) {
|
|
115
|
+
contentLines.push(line);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
if (currentSection) {
|
|
119
|
+
currentSection.content = contentLines.join("\n").trim();
|
|
120
|
+
sections.push(currentSection);
|
|
121
|
+
}
|
|
122
|
+
return sections;
|
|
123
|
+
}
|
|
124
|
+
function parseBulletList(content) {
|
|
125
|
+
const items = [];
|
|
126
|
+
let inComment = false;
|
|
127
|
+
for (const line of content.split("\n")) {
|
|
128
|
+
const trimmed = line.trim();
|
|
129
|
+
if (trimmed.startsWith("<!--")) {
|
|
130
|
+
inComment = true;
|
|
131
|
+
}
|
|
132
|
+
if (inComment) {
|
|
133
|
+
if (trimmed.includes("-->")) {
|
|
134
|
+
inComment = false;
|
|
135
|
+
}
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
if (trimmed.startsWith("- ")) {
|
|
139
|
+
items.push(trimmed.slice(2).trim());
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return items;
|
|
143
|
+
}
|
|
144
|
+
function extractTextContent(content) {
|
|
145
|
+
const lines = content.split("\n");
|
|
146
|
+
const textLines = [];
|
|
147
|
+
let inComment = false;
|
|
148
|
+
for (const line of lines) {
|
|
149
|
+
const trimmed = line.trim();
|
|
150
|
+
if (trimmed.startsWith("<!--")) {
|
|
151
|
+
inComment = true;
|
|
152
|
+
}
|
|
153
|
+
if (inComment) {
|
|
154
|
+
if (trimmed.includes("-->")) {
|
|
155
|
+
inComment = false;
|
|
156
|
+
}
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
if (trimmed && !trimmed.startsWith("#")) {
|
|
160
|
+
textLines.push(trimmed);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return textLines.join("\n").trim();
|
|
164
|
+
}
|
|
165
|
+
function toKebabCase(name) {
|
|
166
|
+
return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
|
|
167
|
+
}
|
|
168
|
+
function parseFrontmatter(yaml, issues) {
|
|
169
|
+
const result = {};
|
|
170
|
+
for (const line of yaml.split("\n")) {
|
|
171
|
+
const trimmed = line.trim();
|
|
172
|
+
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
173
|
+
const colonIdx = trimmed.indexOf(":");
|
|
174
|
+
if (colonIdx === -1) continue;
|
|
175
|
+
const key = trimmed.slice(0, colonIdx).trim();
|
|
176
|
+
const value = trimmed.slice(colonIdx + 1).trim();
|
|
177
|
+
result[key] = value;
|
|
178
|
+
}
|
|
179
|
+
const name = result.name || "";
|
|
180
|
+
if (!name) {
|
|
181
|
+
issues.push({
|
|
182
|
+
line: 1,
|
|
183
|
+
section: "frontmatter",
|
|
184
|
+
message: "Missing name in frontmatter. Provide a human-readable model name.",
|
|
185
|
+
severity: "error"
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
const model_id = result.model_id || toKebabCase(name);
|
|
189
|
+
return {
|
|
190
|
+
model_id,
|
|
191
|
+
name,
|
|
192
|
+
version: result.version || "1.0.0"
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
function parseGeometry(section, issues) {
|
|
196
|
+
const geometry = {
|
|
197
|
+
mission: "",
|
|
198
|
+
domains: [],
|
|
199
|
+
overlapEffects: [],
|
|
200
|
+
centerIdentity: ""
|
|
201
|
+
};
|
|
202
|
+
if (!section) {
|
|
203
|
+
issues.push({
|
|
204
|
+
line: 0,
|
|
205
|
+
section: "Core Model Geometry",
|
|
206
|
+
message: "Missing # Core Model Geometry section. Define the structural model: mission, domains with embedded skills and values, overlaps, and center identity.",
|
|
207
|
+
severity: "error"
|
|
208
|
+
});
|
|
209
|
+
return geometry;
|
|
210
|
+
}
|
|
211
|
+
const h2Sections = splitH2Sections(section.content, section.startLine);
|
|
212
|
+
const missionSection = h2Sections.find((s) => s.name.toLowerCase() === "mission");
|
|
213
|
+
if (missionSection) {
|
|
214
|
+
geometry.mission = extractTextContent(missionSection.content);
|
|
215
|
+
}
|
|
216
|
+
if (!geometry.mission) {
|
|
217
|
+
issues.push({
|
|
218
|
+
line: missionSection?.startLine ?? section.startLine,
|
|
219
|
+
section: "Mission",
|
|
220
|
+
message: "Missing ## Mission. Define what this system is trying to achieve \u2014 the core aim, not a slogan.",
|
|
221
|
+
severity: "error"
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
const domainsSection = h2Sections.find((s) => s.name.toLowerCase() === "domains");
|
|
225
|
+
if (domainsSection) {
|
|
226
|
+
const domainSections = splitH3Sections(domainsSection.content, domainsSection.startLine);
|
|
227
|
+
for (const ds of domainSections) {
|
|
228
|
+
const domain = {
|
|
229
|
+
id: toKebabCase(ds.name),
|
|
230
|
+
name: ds.name,
|
|
231
|
+
skills: [],
|
|
232
|
+
values: [],
|
|
233
|
+
line: ds.startLine
|
|
234
|
+
};
|
|
235
|
+
const h4Sections = splitH4Sections(ds.content, ds.startLine);
|
|
236
|
+
const skillsH4 = h4Sections.find((s) => s.name.toLowerCase() === "skills");
|
|
237
|
+
if (skillsH4) {
|
|
238
|
+
domain.skills = parseBulletList(skillsH4.content);
|
|
239
|
+
}
|
|
240
|
+
const valuesH4 = h4Sections.find((s) => s.name.toLowerCase() === "values");
|
|
241
|
+
if (valuesH4) {
|
|
242
|
+
domain.values = parseBulletList(valuesH4.content);
|
|
243
|
+
}
|
|
244
|
+
if (domain.skills.length === 0) {
|
|
245
|
+
issues.push({
|
|
246
|
+
line: ds.startLine,
|
|
247
|
+
section: "Domains",
|
|
248
|
+
message: `Domain '${ds.name}' has no skills defined. Skills are the capabilities within this domain.`,
|
|
249
|
+
severity: "warning"
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
if (domain.values.length === 0) {
|
|
253
|
+
issues.push({
|
|
254
|
+
line: ds.startLine,
|
|
255
|
+
section: "Domains",
|
|
256
|
+
message: `Domain '${ds.name}' has no values defined. Behavior has no constraints without values.`,
|
|
257
|
+
severity: "warning"
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
geometry.domains.push(domain);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
if (geometry.domains.length < 2) {
|
|
264
|
+
issues.push({
|
|
265
|
+
line: domainsSection?.startLine ?? section.startLine,
|
|
266
|
+
section: "Domains",
|
|
267
|
+
message: "At least 2 domains required. Domains are the major operating modes of the system, each carrying skills and values.",
|
|
268
|
+
severity: "error"
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
const overlapsSection = h2Sections.find(
|
|
272
|
+
(s) => s.name.toLowerCase() === "overlap effects"
|
|
273
|
+
);
|
|
274
|
+
if (overlapsSection) {
|
|
275
|
+
const bullets = parseBulletList(overlapsSection.content);
|
|
276
|
+
const domainNames = new Set(geometry.domains.map((d) => d.name.toLowerCase()));
|
|
277
|
+
for (let i = 0; i < bullets.length; i++) {
|
|
278
|
+
const bullet = bullets[i];
|
|
279
|
+
const match = bullet.match(/^(.+?)\s*\+\s*(.+?)\s*=\s*(.+)$/);
|
|
280
|
+
if (match) {
|
|
281
|
+
const domainA = match[1].trim();
|
|
282
|
+
const domainB = match[2].trim();
|
|
283
|
+
const effect = match[3].trim();
|
|
284
|
+
if (!domainNames.has(domainA.toLowerCase())) {
|
|
285
|
+
issues.push({
|
|
286
|
+
line: overlapsSection.startLine + i,
|
|
287
|
+
section: "Overlap Effects",
|
|
288
|
+
message: `Overlap references unknown domain '${domainA}'. Must reference a declared domain.`,
|
|
289
|
+
severity: "warning"
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
if (!domainNames.has(domainB.toLowerCase())) {
|
|
293
|
+
issues.push({
|
|
294
|
+
line: overlapsSection.startLine + i,
|
|
295
|
+
section: "Overlap Effects",
|
|
296
|
+
message: `Overlap references unknown domain '${domainB}'. Must reference a declared domain.`,
|
|
297
|
+
severity: "warning"
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
geometry.overlapEffects.push({
|
|
301
|
+
domainA,
|
|
302
|
+
domainB,
|
|
303
|
+
effect,
|
|
304
|
+
line: overlapsSection.startLine + i
|
|
305
|
+
});
|
|
306
|
+
} else {
|
|
307
|
+
issues.push({
|
|
308
|
+
line: overlapsSection.startLine + i,
|
|
309
|
+
section: "Overlap Effects",
|
|
310
|
+
message: `Cannot parse overlap: '${bullet}'. Expected format: 'Domain A + Domain B = Emergent State'.`,
|
|
311
|
+
severity: "warning"
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
if (geometry.overlapEffects.length === 0) {
|
|
317
|
+
issues.push({
|
|
318
|
+
line: overlapsSection?.startLine ?? section.startLine,
|
|
319
|
+
section: "Overlap Effects",
|
|
320
|
+
message: 'No overlap effects defined. Define what emerges when two domains interact well (e.g., "Domain A + Domain B = Inspiration").',
|
|
321
|
+
severity: "warning"
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
const identitySection = h2Sections.find(
|
|
325
|
+
(s) => s.name.toLowerCase() === "center identity"
|
|
326
|
+
);
|
|
327
|
+
if (identitySection) {
|
|
328
|
+
geometry.centerIdentity = extractTextContent(identitySection.content);
|
|
329
|
+
}
|
|
330
|
+
if (!geometry.centerIdentity) {
|
|
331
|
+
issues.push({
|
|
332
|
+
line: identitySection?.startLine ?? section.startLine,
|
|
333
|
+
section: "Center Identity",
|
|
334
|
+
message: "No center identity defined. Define what the system becomes when all domains are aligned \u2014 the core identity.",
|
|
335
|
+
severity: "warning"
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
return geometry;
|
|
339
|
+
}
|
|
340
|
+
function parseModifiers(section, issues) {
|
|
341
|
+
const modifiers = {
|
|
342
|
+
authorityLayers: [],
|
|
343
|
+
spatialContexts: [],
|
|
344
|
+
interpretationRules: []
|
|
345
|
+
};
|
|
346
|
+
if (!section) {
|
|
347
|
+
issues.push({
|
|
348
|
+
line: 0,
|
|
349
|
+
section: "Contextual Modifiers",
|
|
350
|
+
message: "Missing # Contextual Modifiers section. Define how authority, role, and spatial context change how behavior is interpreted.",
|
|
351
|
+
severity: "warning"
|
|
352
|
+
});
|
|
353
|
+
return modifiers;
|
|
354
|
+
}
|
|
355
|
+
const h2Sections = splitH2Sections(section.content, section.startLine);
|
|
356
|
+
const authoritySection = h2Sections.find(
|
|
357
|
+
(s) => s.name.toLowerCase() === "authority layers"
|
|
358
|
+
);
|
|
359
|
+
if (authoritySection) {
|
|
360
|
+
modifiers.authorityLayers = parseBulletList(authoritySection.content);
|
|
361
|
+
}
|
|
362
|
+
const spatialSection = h2Sections.find(
|
|
363
|
+
(s) => s.name.toLowerCase() === "spatial contexts"
|
|
364
|
+
);
|
|
365
|
+
if (spatialSection) {
|
|
366
|
+
modifiers.spatialContexts = parseBulletList(spatialSection.content);
|
|
367
|
+
}
|
|
368
|
+
const rulesSection = h2Sections.find(
|
|
369
|
+
(s) => s.name.toLowerCase() === "interpretation rules"
|
|
370
|
+
);
|
|
371
|
+
if (rulesSection) {
|
|
372
|
+
modifiers.interpretationRules = parseBulletList(rulesSection.content);
|
|
373
|
+
}
|
|
374
|
+
return modifiers;
|
|
375
|
+
}
|
|
376
|
+
function parseEvolution(section, issues) {
|
|
377
|
+
const evolution = {
|
|
378
|
+
alignedBehaviors: [],
|
|
379
|
+
driftBehaviors: [],
|
|
380
|
+
signals: [],
|
|
381
|
+
decisionPriorities: [],
|
|
382
|
+
evolutionConditions: []
|
|
383
|
+
};
|
|
384
|
+
if (!section) {
|
|
385
|
+
issues.push({
|
|
386
|
+
line: 0,
|
|
387
|
+
section: "Evolution Layer",
|
|
388
|
+
message: "Missing # Evolution Layer section. Define observable behaviors, signals, decision priorities, and adaptation conditions.",
|
|
389
|
+
severity: "error"
|
|
390
|
+
});
|
|
391
|
+
return evolution;
|
|
392
|
+
}
|
|
393
|
+
const h2Sections = splitH2Sections(section.content, section.startLine);
|
|
394
|
+
const alignedSection = h2Sections.find(
|
|
395
|
+
(s) => s.name.toLowerCase() === "aligned behaviors"
|
|
396
|
+
);
|
|
397
|
+
if (alignedSection) {
|
|
398
|
+
evolution.alignedBehaviors = parseBulletList(alignedSection.content);
|
|
399
|
+
}
|
|
400
|
+
if (evolution.alignedBehaviors.length === 0) {
|
|
401
|
+
issues.push({
|
|
402
|
+
line: alignedSection?.startLine ?? section.startLine,
|
|
403
|
+
section: "Aligned Behaviors",
|
|
404
|
+
message: "No aligned behaviors defined. Define what success looks like in action.",
|
|
405
|
+
severity: "warning"
|
|
406
|
+
});
|
|
407
|
+
}
|
|
408
|
+
const driftSection = h2Sections.find(
|
|
409
|
+
(s) => s.name.toLowerCase() === "drift behaviors"
|
|
410
|
+
);
|
|
411
|
+
if (driftSection) {
|
|
412
|
+
evolution.driftBehaviors = parseBulletList(driftSection.content);
|
|
413
|
+
}
|
|
414
|
+
if (evolution.driftBehaviors.length === 0) {
|
|
415
|
+
issues.push({
|
|
416
|
+
line: driftSection?.startLine ?? section.startLine,
|
|
417
|
+
section: "Drift Behaviors",
|
|
418
|
+
message: "No drift behaviors defined. Define what misalignment looks like so the system can detect behavioral drift over time.",
|
|
419
|
+
severity: "warning"
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
const signalsSection = h2Sections.find(
|
|
423
|
+
(s) => s.name.toLowerCase() === "signals"
|
|
424
|
+
);
|
|
425
|
+
if (signalsSection) {
|
|
426
|
+
evolution.signals = parseBulletList(signalsSection.content);
|
|
427
|
+
}
|
|
428
|
+
if (evolution.signals.length < 2) {
|
|
429
|
+
issues.push({
|
|
430
|
+
line: signalsSection?.startLine ?? section.startLine,
|
|
431
|
+
section: "Signals",
|
|
432
|
+
message: "At least 2 signals required. Signals are the observable metrics for detecting alignment or drift.",
|
|
433
|
+
severity: "error"
|
|
434
|
+
});
|
|
435
|
+
}
|
|
436
|
+
const prioritiesSection = h2Sections.find(
|
|
437
|
+
(s) => s.name.toLowerCase() === "decision priorities"
|
|
438
|
+
);
|
|
439
|
+
if (prioritiesSection) {
|
|
440
|
+
const bullets = parseBulletList(prioritiesSection.content);
|
|
441
|
+
for (let i = 0; i < bullets.length; i++) {
|
|
442
|
+
const bullet = bullets[i];
|
|
443
|
+
const match = bullet.match(/^(.+?)\s*>\s*(.+)$/);
|
|
444
|
+
if (match) {
|
|
445
|
+
evolution.decisionPriorities.push({
|
|
446
|
+
preferred: match[1].trim(),
|
|
447
|
+
over: match[2].trim(),
|
|
448
|
+
line: prioritiesSection.startLine + i
|
|
449
|
+
});
|
|
450
|
+
} else {
|
|
451
|
+
issues.push({
|
|
452
|
+
line: prioritiesSection.startLine + i,
|
|
453
|
+
section: "Decision Priorities",
|
|
454
|
+
message: `Cannot parse priority: '${bullet}'. Expected format: 'preferred > over'.`,
|
|
455
|
+
severity: "warning"
|
|
456
|
+
});
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
if (evolution.decisionPriorities.length === 0) {
|
|
461
|
+
issues.push({
|
|
462
|
+
line: prioritiesSection?.startLine ?? section.startLine,
|
|
463
|
+
section: "Decision Priorities",
|
|
464
|
+
message: "No decision priorities defined. Define what wins when tradeoffs appear.",
|
|
465
|
+
severity: "warning"
|
|
466
|
+
});
|
|
467
|
+
}
|
|
468
|
+
const evoSection = h2Sections.find(
|
|
469
|
+
(s) => s.name.toLowerCase() === "evolution conditions"
|
|
470
|
+
);
|
|
471
|
+
if (evoSection) {
|
|
472
|
+
evolution.evolutionConditions = parseBulletList(evoSection.content);
|
|
473
|
+
}
|
|
474
|
+
if (evolution.signals.length > 0 && evolution.driftBehaviors.length === 0) {
|
|
475
|
+
issues.push({
|
|
476
|
+
line: signalsSection?.startLine ?? section.startLine,
|
|
477
|
+
section: "Evolution Layer",
|
|
478
|
+
message: "Signals defined but no drift behaviors. System cannot detect failure without drift definitions.",
|
|
479
|
+
severity: "warning"
|
|
480
|
+
});
|
|
481
|
+
}
|
|
482
|
+
return evolution;
|
|
483
|
+
}
|
|
484
|
+
function parseWorldModel(markdown) {
|
|
485
|
+
const issues = [];
|
|
486
|
+
if (!markdown || !markdown.trim()) {
|
|
487
|
+
issues.push({
|
|
488
|
+
line: 0,
|
|
489
|
+
section: "file",
|
|
490
|
+
message: "Empty input. Provide a .worldmodel.md file with three layers: Core Model Geometry, Contextual Modifiers, Evolution Layer.",
|
|
491
|
+
severity: "error"
|
|
492
|
+
});
|
|
493
|
+
return { model: null, issues };
|
|
494
|
+
}
|
|
495
|
+
const { frontmatter: fmRaw, sections } = splitSections(markdown);
|
|
496
|
+
const frontmatter = parseFrontmatter(fmRaw, issues);
|
|
497
|
+
const geometrySection = sections.find(
|
|
498
|
+
(s) => s.name.toLowerCase() === "core model geometry"
|
|
499
|
+
);
|
|
500
|
+
const modifiersSection = sections.find(
|
|
501
|
+
(s) => s.name.toLowerCase() === "contextual modifiers"
|
|
502
|
+
);
|
|
503
|
+
const evolutionSection = sections.find(
|
|
504
|
+
(s) => s.name.toLowerCase() === "evolution layer"
|
|
505
|
+
);
|
|
506
|
+
const geometry = parseGeometry(geometrySection, issues);
|
|
507
|
+
const modifiers = parseModifiers(modifiersSection, issues);
|
|
508
|
+
const evolution = parseEvolution(evolutionSection, issues);
|
|
509
|
+
if (geometry.overlapEffects.length > 0 && !geometry.centerIdentity) {
|
|
510
|
+
issues.push({
|
|
511
|
+
line: 0,
|
|
512
|
+
section: "Core Model Geometry",
|
|
513
|
+
message: "Overlaps defined but no center identity. System lacks coherence without an aligned identity.",
|
|
514
|
+
severity: "warning"
|
|
515
|
+
});
|
|
516
|
+
}
|
|
517
|
+
const hasErrors = issues.some((i) => i.severity === "error");
|
|
518
|
+
if (hasErrors) {
|
|
519
|
+
return {
|
|
520
|
+
model: {
|
|
521
|
+
frontmatter,
|
|
522
|
+
geometry,
|
|
523
|
+
modifiers,
|
|
524
|
+
evolution
|
|
525
|
+
},
|
|
526
|
+
issues
|
|
527
|
+
};
|
|
528
|
+
}
|
|
529
|
+
return {
|
|
530
|
+
model: {
|
|
531
|
+
frontmatter,
|
|
532
|
+
geometry,
|
|
533
|
+
modifiers,
|
|
534
|
+
evolution
|
|
535
|
+
},
|
|
536
|
+
issues
|
|
537
|
+
};
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
export {
|
|
541
|
+
parseWorldModel
|
|
542
|
+
};
|