Pepguy commited on
Commit
e2b3a17
·
verified ·
1 Parent(s): c52657c

Update app.js

Browse files
Files changed (1) hide show
  1. app.js +174 -1960
app.js CHANGED
@@ -1,2002 +1,216 @@
1
- /**
2
- * axl_dataset_server.js
3
- * ══════════════════════════════════════════════════════════════════════════════
4
- * AXL Dataset Generation Server — Full Rewrite
5
- *
6
- * What changed:
7
- * 1. ALL synthetic generators now produce multi-scope AXL programs
8
- * matching the depth the AI produces (scope_depth 2-3, EMERGES,
9
- * CONTRADICT, CONSERVES, STEP/CANDIDATE where applicable)
10
- * 2. POST-PROCESSING NORMALIZER: every sample's c_values are mapped
11
- * to[0,1] relative to declared bounds before saving. No more
12
- * raw voltages, payoffs, or angles in c_values.
13
- * 3. VALIDATION: catches string c_values, missing VARS prefix,
14
- * mask length mismatch, non-finite b_raw — all logged and rejected.
15
- * 4. FOCUS TRACKER: guides AI generation away from overrepresented domains.
16
- * 5. DOWNLOAD endpoint returns dated filename.
17
- * 6. RPS throttle on AI calls, SAMPLES_PER_CALL configurable.
18
- * 7. AWS BEDROCK updated to ConverseCommand with NodeHttpHandler.
19
- * 8. [FIXED] Synthetic array strictly sliced to exact requested fraction.
20
- * 9.[FIXED] SAMPLES_PER_CALL lowered to 4 to prevent AWS token truncation.
21
- *
22
- * Endpoints:
23
- * GET /status
24
- * POST /generate?n=50&rps=3&synthetic_fraction=0.4
25
- * GET /dataset/download
26
- * POST /dataset/clear
27
- * GET /dataset/sample?n=5
28
- * GET /domains
29
- *
30
- * Usage:
31
- * node axl_dataset_server.js
32
- * PORT=8000 AWS_REGION=us-east-1 node axl_dataset_server.js
33
- * ══════════════════════════════════════════════════════════════════════════════
34
- */
35
-
36
- import express from "express";
37
- import cors from "cors";
38
- import { randomUUID } from "crypto";
39
- import fs from "fs";
40
- import path from "path";
41
- import {
42
- BedrockRuntimeClient,
43
- ConverseCommand
44
- } from "@aws-sdk/client-bedrock-runtime";
45
  import { NodeHttpHandler } from "@smithy/node-http-handler";
 
 
46
 
47
- // ── CONFIG ────────────────────────────────────────────────────────────────────
48
- const PORT = parseInt(process.env.PORT || "7860");
49
- const AWS_REGION = process.env.AWS_REGION || "us-east-1";
50
- const BEDROCK_MODEL_ID = "arn:aws:bedrock:us-east-1:106774395747:inference-profile/global.anthropic.claude-haiku-4-5-20251001-v1:0";
51
- //"arn:aws:bedrock:us-east-1:106774395747:inference-profile/global.anthropic.claude-sonnet-4-6";
52
-
53
- const DATASET_PATH = process.env.DATASET_PATH || "axl_dataset.json";
54
- const DEFAULT_RPS = parseFloat(process.env.DEFAULT_RPS || "3");
55
- const MAX_RPS = parseFloat(process.env.MAX_RPS || "8");
56
- const SAMPLES_PER_CALL = parseInt(process.env.SAMPLES_PER_CALL || "4"); // Reduced to prevent token cutoff
57
- const SCALE_K = 30.0;
58
- const LATENT_D_MAX = 8;
59
-
60
- // ── LOGGING ───────────────────────────────────────────────────────────────────
61
- const ts = () => new Date().toISOString().slice(11, 23);
62
- const log = (msg, level = "INFO") => {
63
- const icons = { INFO:" ", WARN:"⚠ ", ERROR:"✖ ", OK:"✔ ", HEAD:"━━" };
64
- console.log(`[${ts()}] ${icons[level]||" "} ${msg}`);
65
- };
66
-
67
- // ── MATH HELPERS ──────────────────────────────────────────────────────────────
68
- const randint = (lo, hi) => Math.floor(Math.random() * (hi - lo + 1)) + lo;
69
- const rnd = (lo, hi) => Math.random() * (hi - lo) + lo;
70
- const fmt = (v, d=6) => Number(v.toFixed(d));
71
- const safeNorm = (b) => {
72
- if (!isFinite(b)) return 0.0;
73
- return Math.sign(b) * Math.log1p(Math.abs(b)) / SCALE_K;
74
- };
75
- const randchoice = (arr) => arr[Math.floor(Math.random() * arr.length)];
76
-
77
- // ── NORMALIZER ────────────────────────────────────────────────────────────────
78
- function normalizeSample(s) {
79
- const parsed = parseVarsBounds(s.vars_text, s.n_vars);
80
-
81
- if (!Array.isArray(s.c_values) || s.c_values.length < s.n_vars) return null;
82
-
83
- const raw = s.c_values.slice(0, s.n_vars);
84
-
85
- const normalized = raw.map((v, i) => {
86
- if (typeof v !== "number" || !isFinite(v)) return null;
87
- const [lo, hi] = parsed[i] || [0, 1];
88
- if (hi <= lo) return Math.min(1, Math.max(0, v));
89
- return Math.min(1, Math.max(0, (v - lo) / (hi - lo)));
90
- });
91
-
92
- if (normalized.includes(null)) return null;
93
-
94
- const mask =[...Array(s.n_vars).fill(1), ...Array(Math.max(0, LATENT_D_MAX - s.n_vars)).fill(0)];
95
-
96
- return {
97
- ...s,
98
- c_values: normalized.map(v => fmt(v)),
99
- mask: mask,
100
- b_norm: fmt(safeNorm(s.b_raw), 8),
101
- vars_text: ensureVarsPrefix(s.vars_text),
102
- };
103
- }
104
-
105
- function parseVarsBounds(varsText, nVars) {
106
- const bounds = [];
107
- const re = /IN\s*[\[({]?\s*(-?[\d.e+\-]+)[\s,]+(-?[\d.e+\-]+)\s*[\])}]?/gi;
108
- let m;
109
- while ((m = re.exec(varsText)) !== null) {
110
- bounds.push([parseFloat(m[1]), parseFloat(m[2])]);
111
- }
112
- while (bounds.length < nVars) bounds.push([0, 1]);
113
- return bounds;
114
- }
115
-
116
- function ensureVarsPrefix(vt) {
117
- if (!vt) return "VARS c0 IN [0 1]";
118
- const t = vt.trim();
119
- return t.startsWith("VARS") ? t : "VARS " + t;
120
- }
121
-
122
- // ── VALIDATION ────────────────────────────────────────────────────────────────
123
- function validateSample(s) {
124
- const required =["domain","sense","n_vars","vars_text","expr_text",
125
- "sense_text","b_raw","c_values","mask"];
126
- for (const f of required) {
127
- if (s[f] === undefined || s[f] === null) {
128
- log(`Reject [${s.id||"?"}]: missing field ${f}`, "WARN");
129
- return false;
130
- }
131
- }
132
- if (!Array.isArray(s.c_values)) { log(`Reject: c_values not array`, "WARN"); return false; }
133
- if (s.c_values.length < s.n_vars) { log(`Reject: c_values len mismatch`, "WARN"); return false; }
134
- if (s.c_values.some(v => typeof v !== "number" || !isFinite(v))) {
135
- log(`Reject: non-numeric c_values in ${s.domain}`, "WARN"); return false;
136
- }
137
- if (!isFinite(s.b_raw)) { log(`Reject: non-finite b_raw`, "WARN"); return false; }
138
- if (!s.vars_text.trimStart().startsWith("VARS")) {
139
- log(`Auto-fix vars_text prefix for ${s.domain}`, "WARN");
140
- }
141
- if (!s.id) s.id = randomUUID();
142
- return true;
143
- }
144
-
145
- // ═════════════════════════════════════════════════════════════════════════════
146
- // DEEP SYNTHETIC GENERATORS
147
- // ═════════════════════════════════════════════════════════════════════════════
148
-
149
- // ── PHYSICS ───────────────────────────────────────────────────────────────────
150
- function synthPhysicsSamples(n) {
151
- const samples = [];
152
- const templates =[
153
- {
154
- name: "Kinetic Energy",
155
- fn: (c) => 0.5 * (c[0]) * (c[1])**2,
156
- bounds: [[0.1,100],[0.1,50]],
157
- units: "Joules",
158
- formula: "KE = 0.5 * m * v^2",
159
- conserves: "energy ACROSS elastic_collision",
160
- },
161
- {
162
- name: "Gravitational PE",
163
- fn: (c) => c[0] * 9.81 * c[1],
164
- bounds: [[0.1,100],[0.1,100]],
165
- units: "Joules",
166
- formula: "PE = m * g * h",
167
- conserves: "energy ACROSS conservative_field",
168
- },
169
- {
170
- name: "Ohm Power",
171
- fn: (c) => (c[0]**2) / Math.max(c[1], 0.001),
172
- bounds: [[0.1,240],[0.1,1000]],
173
- units: "Watts",
174
- formula: "P = V^2 / R",
175
- conserves: "charge ACROSS resistive_element",
176
- },
177
- {
178
- name: "Ideal Gas Temperature",
179
- fn: (c) => (c[0]*c[1]) / (c[2]*8.314),
180
- bounds: [[0.1,10],[0.001,0.1],[0.1,5]],
181
- units: "Kelvin",
182
- formula: "T = PV / nR",
183
- conserves: "particle_count ACROSS isothermal",
184
- },
185
- {
186
- name: "Snell Refraction",
187
- fn: (c) => (c[0]*2+1) * Math.sin(c[1]*1.5) / Math.max((c[2]*2+1), 0.001),
188
- bounds: [[0,1],[0,1],[0,1]],
189
- units: "dimensionless",
190
- formula: "n1*sin(t1)/n2",
191
- conserves: "wavevector_component ACROSS interface",
192
- },
193
- {
194
- name: "Centripetal Acceleration",
195
- fn: (c) => (c[0]**2) / Math.max(c[1], 0.001),
196
- bounds: [[0.1,50],[0.1,10]],
197
- units: "m/s²",
198
- formula: "a = v^2 / r",
199
- conserves: "angular_momentum ACROSS circular_motion",
200
- },
201
- ];
202
-
203
- for (let i = 0; i < n; i++) {
204
- const t = randchoice(templates);
205
- const cRaw = t.bounds.map(([lo,hi]) => rnd(lo, hi));
206
- try {
207
- const bRaw = t.fn(cRaw);
208
- if (!isFinite(bRaw)) continue;
209
- const nVars = t.bounds.length;
210
- const varsBounds = t.bounds.map(([lo,hi],j) => `c${j} IN [${lo} ${hi}]`).join(" ");
211
-
212
- const axl = [
213
- `SCOPE physics_primitives [level: 0]`,
214
- ` ASSUME measurement EXISTS`,
215
- ` ASSUME ${t.conserves}`,
216
- `END SCOPE`,
217
- ``,
218
- `SCOPE ${t.name.toLowerCase().replace(/ /g,"_")}[level: 1]`,
219
- ` ASSUME physics_primitives SCOPE HOLDS`,
220
- ``,
221
- ` ENTITY physical_system`,
222
- ...t.bounds.map(([lo,hi],j) =>
223
- ` FIELD c${j}: REAL BOUND [${lo}, ${hi}]`),
224
- ` FIELD result: REAL`,
225
- ` DERIVES result FROM {${cRaw.map((_,j)=>`c${j}`).join(", ")}} BY ${t.name.toLowerCase().replace(/ /g,"_")}_formula`,
226
- ` END ENTITY`,
227
- ``,
228
- ` TRANSFORM ${t.name.toLowerCase().replace(/ /g,"_")}_formula`,
229
- ` INPUT {${t.bounds.map((_,j)=>`c${j}: REAL BOUND [${t.bounds[j][0]}, ${t.bounds[j][1]}]`).join(", ")}}`,
230
- ` OUTPUT {result: REAL}`,
231
- ` PRODUCES result EQUALS ${t.formula}`,
232
- ` # Computed: ${t.fn(cRaw).toFixed(4)} ${t.units}`,
233
- ` END TRANSFORM`,
234
- ``,
235
- ` OBSERVE result EQUALS ${bRaw.toFixed(6)}`,
236
- ` UNKNOWN ${cRaw.map((_,j)=>`c${j}: REAL BOUND[${t.bounds[j][0]}, ${t.bounds[j][1]}]`).join("\n UNKNOWN ")}`,
237
- ``,
238
- ` COLLAPSE ${t.name.toLowerCase().replace(/ /g,"_")}`,
239
- ` GIVEN {result EQUALS ${bRaw.toFixed(4)}}`,
240
- ` FIND {${cRaw.map((_,j)=>`c${j}`).join(", ")}}`,
241
- ` CONFIDENCE 0.97`,
242
- ` END COLLAPSE`,
243
- `END SCOPE`,
244
- ].join("\n");
245
-
246
- samples.push({
247
- id: randomUUID(), domain: "physics", subdomain: t.name,
248
- sense: "EQUAL", n_vars: nVars,
249
- vars_text: `VARS ${varsBounds}`,
250
- expr_text: `EXPR ${t.formula}`,
251
- sense_text: "SENSE EQUAL",
252
- b_raw: fmt(bRaw), b_norm: fmt(safeNorm(bRaw), 8),
253
- c_values: cRaw.map(v => fmt(v)),
254
- mask: Array(nVars).fill(1),
255
- candidates:[], step_count: 0, axl_source: axl,
256
- metadata: {
257
- description: `${t.name} constraint inversion: ${t.formula} = ${bRaw.toFixed(4)}`,
258
- units: t.units, difficulty: "medium",
259
- scope_depth: 2, has_emergence: false, has_contradiction: false
260
- }
261
- });
262
- } catch(e) {}
263
- }
264
- return samples;
265
- }
266
-
267
- // ── FINANCE ───────────────────────────────────────────────────────────────────
268
- function synthFinanceSamples(n) {
269
- const samples =[];
270
- for (let i = 0; i < n; i++) {
271
- const kind = randchoice(["compound","loan","portfolio_variance","sharpe"]);
272
- try {
273
- let bRaw, cRaw, bounds, formula, desc, subdomain;
274
-
275
- if (kind === "compound") {
276
- const P = rnd(1000, 100000), r = rnd(0.01, 0.25), t = rnd(1, 30);
277
- bRaw = P * Math.exp(r * t);
278
- cRaw = [P, r, t];
279
- bounds = [[1000,100000],[0.01,0.25],[1,30]];
280
- formula = "P * exp(r * t)";
281
- subdomain = "compound_interest";
282
- desc = `Compound interest P=${P.toFixed(0)} r=${r.toFixed(3)} t=${t.toFixed(1)}y → ${bRaw.toFixed(2)}`;
283
- } else if (kind === "loan") {
284
- const P = rnd(50000,500000), r = rnd(0.002,0.02), np = randint(60,360);
285
- bRaw = P*r*(1+r)**np / ((1+r)**np - 1 + 1e-9);
286
- cRaw =[P, r, np];
287
- bounds = [[50000,500000],[0.002,0.02],[60,360]];
288
- formula = "P*r*(1+r)^n / ((1+r)^n - 1)";
289
- subdomain = "loan_payment";
290
- desc = `Monthly payment: ${bRaw.toFixed(2)}`;
291
- } else if (kind === "portfolio_variance") {
292
- const w =[rnd(0,1), rnd(0,1), rnd(0,1)];
293
- const s = w.reduce((a,b)=>a+b,0); w[0]/=s; w[1]/=s; w[2]/=s;
294
- const sig =[rnd(0.05,0.3), rnd(0.02,0.15), rnd(0.01,0.08)];
295
- const rho01 = rnd(-0.3,0.5), rho02 = rnd(-0.2,0.4), rho12 = rnd(-0.1,0.3);
296
- bRaw = w[0]**2*sig[0]**2 + w[1]**2*sig[1]**2 + w[2]**2*sig[2]**2
297
- + 2*w[0]*w[1]*rho01*sig[0]*sig[1]
298
- + 2*w[0]*w[2]*rho02*sig[0]*sig[2]
299
- + 2*w[1]*w[2]*rho12*sig[1]*sig[2];
300
- cRaw = [w[0], w[1], w[2]];
301
- bounds = [[0,1],[0,1],[0,1]];
302
- formula = "portfolio variance with covariance matrix";
303
- subdomain = "portfolio_variance";
304
- desc = `Minimum variance portfolio: variance=${bRaw.toFixed(5)}`;
305
- } else {
306
- const ret =[rnd(0.05,0.25), rnd(0.02,0.12), rnd(0.01,0.05)];
307
- const risk =[rnd(0.1,0.4), rnd(0.05,0.2), rnd(0.01,0.05)];
308
- const w =[rnd(0.2,0.6), rnd(0.1,0.4), rnd(0.05,0.3)];
309
- const s = w.reduce((a,b)=>a+b,0); w[0]/=s; w[1]/=s; w[2]/=s;
310
- const portRet = w.reduce((a,v,j)=>a+v*ret[j],0);
311
- const portRisk = Math.sqrt(w.reduce((a,v,j)=>a+v**2*risk[j]**2,0));
312
- bRaw = portRet / Math.max(portRisk, 0.001);
313
- cRaw = w;
314
- bounds = [[0,1],[0,1],[0,1]];
315
- formula = "Sharpe = return / risk";
316
- subdomain = "sharpe_ratio";
317
- desc = `Sharpe ratio: ${bRaw.toFixed(3)}`;
318
- }
319
-
320
- if (!isFinite(bRaw)) continue;
321
- const nVars = cRaw.length;
322
- const varsBounds = bounds.map(([lo,hi],j)=>`c${j} IN [${lo} ${hi}]`).join(" ");
323
-
324
- const axl = [
325
- `SCOPE financial_primitives[level: 0]`,
326
- ` ASSUME capital EXISTS`,
327
- ` ASSUME time EXISTS`,
328
- ` CONSERVES total_capital APPROXIMATELY ACROSS ${subdomain}`,
329
- `END SCOPE`,
330
- ``,
331
- `SCOPE ${subdomain} [level: 1]`,
332
- ` ASSUME financial_primitives SCOPE HOLDS`,
333
- ``,
334
- ` ENTITY financial_system`,
335
- ...bounds.map(([lo,hi],j) => ` FIELD c${j}: REAL BOUND[${lo}, ${hi}]`),
336
- ` FIELD output: REAL`,
337
- ` DERIVES output FROM {${cRaw.map((_,j)=>`c${j}`).join(", ")}} BY ${subdomain}_formula`,
338
- ` TENDS output ${ kind==="portfolio_variance"?"MIN":"MAX" }`,
339
- ` END ENTITY`,
340
- ``,
341
- ` TRANSFORM ${subdomain}_formula`,
342
- ` INPUT {${bounds.map(([lo,hi],j)=>`c${j}: REAL BOUND[${lo},${hi}]`).join(", ")}}`,
343
- ` OUTPUT {result: REAL}`,
344
- ` PRODUCES result EQUALS ${formula}`,
345
- ` END TRANSFORM`,
346
- ``,
347
- ` OBSERVE output EQUALS ${bRaw.toFixed(6)}`,
348
- ` UNKNOWN ${cRaw.map((_,j)=>`c${j}: REAL BOUND [${bounds[j][0]}, ${bounds[j][1]}]`).join("\n UNKNOWN ")}`,
349
- ``,
350
- ` COLLAPSE ${subdomain}`,
351
- ` GIVEN {output EQUALS ${bRaw.toFixed(4)}}`,
352
- ` FIND {${cRaw.map((_,j)=>`c${j}`).join(", ")}}`,
353
- ` CONFIDENCE 0.95`,
354
- ` END COLLAPSE`,
355
- `END SCOPE`,
356
- ].join("\n");
357
-
358
- samples.push({
359
- id: randomUUID(), domain: "finance", subdomain,
360
- sense: kind==="portfolio_variance" ? "MINIMIZE" : "EQUAL",
361
- n_vars: nVars,
362
- vars_text: `VARS ${varsBounds}`,
363
- expr_text: `EXPR FINANCE_${subdomain.toUpperCase()}`,
364
- sense_text: kind==="portfolio_variance" ? "SENSE MINIMIZE" : "SENSE EQUAL",
365
- b_raw: fmt(bRaw), b_norm: fmt(safeNorm(bRaw), 8),
366
- c_values: cRaw.map(v => fmt(v)),
367
- mask: Array(nVars).fill(1),
368
- candidates:[], step_count: 0, axl_source: axl,
369
- metadata: {
370
- description: desc, units: "currency",
371
- difficulty: "medium", scope_depth: 2,
372
- has_emergence: false, has_contradiction: false
373
- }
374
- });
375
- } catch(e) {}
376
- }
377
- return samples;
378
- }
379
-
380
- // ── CRYPTOGRAPHY ─────────────────────────────────────────────────────────────
381
- function synthXorSamples(n) {
382
- const samples =[];
383
- for (let i = 0; i < n; i++) {
384
- const key = randint(0,255), plain = randint(0,255);
385
- const cipher = key ^ plain;
386
- const keyBits = Array.from({length:8},(_,b)=>(key >>(7-b))&1);
387
- const plainBits = Array.from({length:8},(_,b)=>(plain >>(7-b))&1);
388
-
389
- const bitEntities = Array.from({length:8},(_,b)=>[
390
- ` ENTITY bit_${b}`,
391
- ` FIELD key_bit: DISCRETE VALUES {0, 1} EQUALS ${keyBits[b]}`,
392
- ` FIELD plain_bit: DISCRETE VALUES {0, 1} EQUALS ${plainBits[b]}`,
393
- ` FIELD out_bit: DISCRETE VALUES {0, 1}`,
394
- ` DERIVES out_bit FROM {key_bit, plain_bit} BY xor_gate`,
395
- ` END ENTITY`,
396
- ].join("\n")).join("\n");
397
-
398
- const axl =[
399
- `SCOPE xor_bit_level[level: 0]`,
400
- ` ASSUME bit EXISTS`,
401
- ` ASSUME bit DISCRETE VALUES {0, 1}`,
402
- ` TRANSFORM xor_gate`,
403
- ` INPUT {a: bit, b: bit}`,
404
- ` OUTPUT {out: bit}`,
405
- ` PRODUCES 0 WHEN a EQUALS b`,
406
- ` PRODUCES 1 WHEN a NOT_EQUALS b`,
407
- ` END TRANSFORM`,
408
- bitEntities,
409
- `END SCOPE`,
410
- ``,
411
- `SCOPE xor_byte_level[level: 1]`,
412
- ` ASSUME xor_bit_level SCOPE HOLDS`,
413
- ` ENTITY byte_assembler`,
414
- ` FIELD value: INTEGER BOUND[0, 255]`,
415
- ` DERIVES value FROM {bit_7..bit_0} BY binary_weighted_sum`,
416
- ` END ENTITY`,
417
- ` CONSERVES bit_count ACROSS binary_weighted_sum`,
418
- ` ENTITY key_byte`,
419
- ` FIELD raw: INTEGER BOUND[0, 255]`,
420
- ` FIELD normalised: REAL BOUND [0, 1]`,
421
- ` DERIVES normalised FROM raw BY divide_255`,
422
- ` END ENTITY`,
423
- ` ENTITY plain_byte`,
424
- ` FIELD raw: INTEGER BOUND[0, 255] EQUALS ${plain}`,
425
- ` END ENTITY`,
426
- ` ENTITY cipher_byte`,
427
- ` FIELD raw: INTEGER BOUND[0, 255]`,
428
- ` DERIVES raw FROM {key_byte.raw, plain_byte.raw} BY xor_byte_transform`,
429
- ` END ENTITY`,
430
- ` TRANSFORM xor_byte_transform`,
431
- ` INPUT {key: INTEGER BOUND [0,255], plain: INTEGER BOUND[0,255]}`,
432
- ` OUTPUT {cipher: INTEGER BOUND [0,255]}`,
433
- ` CONSERVES nothing`,
434
- ` CHANGES cipher`,
435
- ` PRODUCES cipher = key XOR plain`,
436
- ` END TRANSFORM`,
437
- ` OBSERVE cipher_byte.raw EQUALS ${cipher}`,
438
- ` UNKNOWN key_byte.normalised: REAL BOUND [0, 1]`,
439
- ` COLLAPSE xor_byte_level`,
440
- ` GIVEN cipher_byte.raw`,
441
- ` FIND key_byte.normalised`,
442
- ` CONFIDENCE 0.99`,
443
- ` END COLLAPSE`,
444
- `END SCOPE`,
445
- ].join("\n");
446
-
447
- samples.push({
448
- id: randomUUID(), domain: "cryptography", subdomain: "xor_byte",
449
- sense: "EQUAL", n_vars: 1,
450
- vars_text: "VARS c0 IN [0 255]",
451
- expr_text: `EXPR XOR plain=${plain} cipher=${cipher} key=UNKNOWN`,
452
- sense_text: "SENSE EQUAL",
453
- b_raw: fmt(cipher), b_norm: fmt(safeNorm(cipher), 8),
454
- c_values:[key],
455
- mask: [1], candidates:[], step_count: 0, axl_source: axl,
456
- metadata: {
457
- description: `XOR byte: plain=${plain} key=${key} → cipher=${cipher}`,
458
- units: "character_code", difficulty: "medium",
459
- scope_depth: 2, has_emergence: false, has_contradiction: true,
460
- key_bits: keyBits, plain_bits: plainBits,
461
- out_bits: keyBits.map((kb,b)=>kb^plainBits[b])
462
- }
463
- });
464
- }
465
- return samples;
466
- }
467
-
468
- function synthCaesarSamples(n) {
469
- const samples =[];
470
- for (let i = 0; i < n; i++) {
471
- const msgLen = randint(1,4);
472
- const shift = randint(0,25);
473
- const plains = Array.from({length:msgLen},()=>randint(0,25));
474
- const ciphers = plains.map(p=>(p+shift)%26);
475
- const bRaw = ciphers.reduce((a,b)=>a+b,0);
476
-
477
- const charEntities = plains.map((p,idx)=>[
478
- ` ENTITY char_${idx}`,
479
- ` FIELD plaintext: INTEGER DISCRETE VALUES {0..25} EQUALS ${p}`,
480
- ` FIELD ciphertext: INTEGER DISCRETE VALUES {0..25}`,
481
- ` DERIVES ciphertext FROM {plaintext, shift} BY caesar_transform`,
482
- ` END ENTITY`,
483
- ].join("\n")).join("\n");
484
-
485
- const axl = [
486
- `SCOPE alphabet_ring [level: 0]`,
487
- ` ASSUME integer EXISTS`,
488
- ` ASSUME modular_arithmetic HOLDS`,
489
- ` ENTITY alphabet`,
490
- ` FIELD size: INTEGER EQUALS 26`,
491
- ` BOUND any_char WITHIN [0, 25]`,
492
- ` END ENTITY`,
493
- ` TRANSFORM modular_add`,
494
- ` INPUT {a: INTEGER, b: INTEGER, mod: INTEGER}`,
495
- ` OUTPUT {result: INTEGER}`,
496
- ` PRODUCES result = (a + b) % mod`,
497
- ` CONSERVES mod`,
498
- ` END TRANSFORM`,
499
- `END SCOPE`,
500
- ``,
501
- `SCOPE caesar_char [level: 1]`,
502
- ` ASSUME alphabet_ring SCOPE HOLDS`,
503
- ` TRANSFORM caesar_transform`,
504
- ` INPUT {plaintext: INTEGER BOUND [0,25], shift: INTEGER BOUND [0,25]}`,
505
- ` OUTPUT {ciphertext: INTEGER BOUND [0,25]}`,
506
- ` PRODUCES ciphertext = modular_add(plaintext, shift, 26)`,
507
- ` CONSERVES alphabet_size`,
508
- ` CHANGES character_identity`,
509
- ` END TRANSFORM`,
510
- ` ENTITY shift_key`,
511
- ` FIELD raw: INTEGER BOUND [0, 25]`,
512
- ` FIELD normalised: REAL BOUND [0, 1]`,
513
- ` DERIVES normalised FROM raw BY divide_25`,
514
- ` END ENTITY`,
515
- charEntities,
516
- `END SCOPE`,
517
- ``,
518
- `SCOPE caesar_message [level: 2]`,
519
- ` ASSUME caesar_char SCOPE HOLDS`,
520
- ` ENTITY message`,
521
- ` FIELD plaintext: VECTOR OF INTEGER EQUALS[${plains.join(", ")}]`,
522
- ` FIELD ciphertext: VECTOR OF INTEGER`,
523
- ` FIELD length: INTEGER EQUALS ${msgLen}`,
524
- ` DERIVES ciphertext FROM {plaintext, shift_key.raw} BY caesar_transform APPLIED_TO_EACH`,
525
- ` END ENTITY`,
526
- ` OBSERVE message.ciphertext EQUALS[${ciphers.join(", ")}]`,
527
- ` OBSERVE SUM(message.ciphertext) EQUALS ${bRaw}`,
528
- ` UNKNOWN shift_key.normalised: REAL BOUND [0, 1]`,
529
- ` COLLAPSE caesar_message`,
530
- ` GIVEN {message.plaintext, SUM(message.ciphertext)}`,
531
- ` FIND shift_key.normalised`,
532
- ` CONFIDENCE 0.99`,
533
- ` END COLLAPSE`,
534
- `END SCOPE`,
535
- ].join("\n");
536
 
537
- samples.push({
538
- id: randomUUID(), domain: "cryptography", subdomain: "caesar",
539
- sense: "EQUAL", n_vars: 1,
540
- vars_text: "VARS c0 IN[0 25]",
541
- expr_text: `EXPR CAESAR plains=[${plains}] ciphers=[${ciphers}] shift=UNKNOWN`,
542
- sense_text: "SENSE EQUAL",
543
- b_raw: fmt(bRaw), b_norm: fmt(safeNorm(bRaw), 8),
544
- c_values: [shift],
545
- mask: [1], candidates:[], step_count: 0, axl_source: axl,
546
- metadata: {
547
- description: `Caesar: shift=${shift} plains=[${plains}] → [${ciphers}]`,
548
- units: "character_code_sum",
549
- difficulty: msgLen > 1 ? "medium" : "easy",
550
- scope_depth: 3, has_emergence: false, has_contradiction: true
551
- }
552
- });
553
- }
554
- return samples;
555
- }
556
 
557
- function synthVigenereSamples(n) {
558
- const samples =[];
559
- for (let i = 0; i < n; i++) {
560
- const keyLen = randint(2,5);
561
- const key = Array.from({length:keyLen},()=>randint(0,25));
562
- const plain = Array.from({length:keyLen},()=>randint(0,25));
563
- const cipher = plain.map((p,idx)=>(p+key[idx])%26);
564
- const bRaw = cipher.reduce((a,b)=>a+b,0);
565
 
566
- const posEntities = plain.map((p,idx)=>[
567
- ` ENTITY position_${idx}`,
568
- ` FIELD plaintext: INTEGER EQUALS ${p}`,
569
- ` FIELD key_char: INTEGER BOUND [0, 25]`,
570
- ` FIELD ciphertext: INTEGER BOUND[0, 25]`,
571
- ` DERIVES ciphertext FROM {plaintext, key_char} BY modular_add_26`,
572
- ` END ENTITY`,
573
- ].join("\n")).join("\n");
574
 
575
- const axl = [
576
- `SCOPE alphabet_ring [level: 0]`,
577
- ` ASSUME integer EXISTS`,
578
- ` TRANSFORM modular_add_26`,
579
- ` INPUT {a: INTEGER BOUND [0,25], b: INTEGER BOUND[0,25]}`,
580
- ` OUTPUT {result: INTEGER BOUND [0,25]}`,
581
- ` PRODUCES result = (a + b) % 26`,
582
- ` END TRANSFORM`,
583
- `END SCOPE`,
584
- ``,
585
- `SCOPE vigenere_position [level: 1]`,
586
- ` ASSUME alphabet_ring SCOPE HOLDS`,
587
- posEntities,
588
- ` EMERGES key_periodicity`,
589
- ` FROM COMPOSITION OF {position_0..position_${keyLen-1}}`,
590
- ` AT SCOPE vigenere_composition`,
591
- ` NOT PRESENT AT SCOPE alphabet_ring`,
592
- ` END EMERGES`,
593
- `END SCOPE`,
594
- ``,
595
- `SCOPE vigenere_composition [level: 2]`,
596
- ` ASSUME vigenere_position SCOPE HOLDS`,
597
- ` ENTITY key_vector`,
598
- ` FIELD chars: VECTOR OF INTEGER BOUND [0, 25]`,
599
- ` FIELD normalised: VECTOR OF REAL BOUND[0, 1]`,
600
- ` DERIVES normalised FROM chars BY divide_each_by_25`,
601
- ` END ENTITY`,
602
- ` ENTITY plaintext_vector`,
603
- ` FIELD chars: VECTOR OF INTEGER EQUALS [${plain.join(", ")}]`,
604
- ` END ENTITY`,
605
- ` ENTITY ciphertext_vector`,
606
- ` FIELD chars: VECTOR OF INTEGER`,
607
- ` DERIVES chars FROM {plaintext_vector.chars, key_vector.chars}`,
608
- ` BY modular_add_26 APPLIED_PAIRWISE`,
609
- ` END ENTITY`,
610
- ` OBSERVE ciphertext_vector.chars EQUALS[${cipher.join(", ")}]`,
611
- ` OBSERVE SUM(ciphertext_vector.chars) EQUALS ${bRaw}`,
612
- ` UNKNOWN key_vector.normalised: VECTOR OF REAL BOUND[0, 1]`,
613
- ` COLLAPSE vigenere_composition`,
614
- ` GIVEN {plaintext_vector.chars, ciphertext_vector.chars}`,
615
- ` FIND key_vector.normalised`,
616
- ` CONFIDENCE 0.99`,
617
- ` END COLLAPSE`,
618
- `END SCOPE`,
619
- ].join("\n");
620
 
621
- const varsText = `VARS ${Array.from({length:keyLen},(_,j)=>`c${j} IN [0 25]`).join(" ")}`;
622
- samples.push({
623
- id: randomUUID(), domain: "cryptography",
624
- subdomain: `vigenere_${keyLen}char`,
625
- sense: "EQUAL", n_vars: keyLen, vars_text: varsText,
626
- expr_text: `EXPR VIGENERE keyLen=${keyLen} plains=[${plain}] ciphers=[${cipher}] key=UNKNOWN`,
627
- sense_text: "SENSE EQUAL",
628
- b_raw: fmt(bRaw), b_norm: fmt(safeNorm(bRaw), 8),
629
- c_values: key,
630
- mask: Array(keyLen).fill(1),
631
- candidates:[], step_count: 0, axl_source: axl,
632
- metadata: {
633
- description: `Vigenère ${keyLen}-char key=[${key}]`,
634
- units: "character_code_sum",
635
- difficulty: keyLen <= 2 ? "medium" : keyLen <= 4 ? "hard" : "expert",
636
- scope_depth: 3, has_emergence: true, has_contradiction: true
637
- }
638
- });
639
  }
640
- return samples;
641
  }
642
 
643
- function synthAffineSamples(n) {
644
- const VALID_A =[1,3,5,7,9,11,15,17,19,21,23,25];
645
- const INV_A_MAP = {1:1,3:9,5:21,7:15,9:3,11:19,15:7,17:23,19:11,21:5,23:17,25:25};
646
- const samples =[];
647
- for (let i = 0; i < n; i++) {
648
- const aIdx = randint(0,11);
649
- const a = VALID_A[aIdx];
650
- const b = randint(0,25);
651
- const p = randint(0,25);
652
- const cipher = (a*p+b)%26;
653
- const aInv = INV_A_MAP[a];
654
- const verify = ((aInv*(cipher-b))%26+26)%26;
655
- if (verify !== p) continue;
656
 
657
- const axl =[
658
- `SCOPE modular_arithmetic [level: 0]`,
659
- ` ASSUME integer EXISTS`,
660
- ` TRANSFORM modular_multiply_add`,
661
- ` INPUT {a: INTEGER, p: INTEGER, b: INTEGER, mod: INTEGER}`,
662
- ` OUTPUT {result: INTEGER}`,
663
- ` PRODUCES result = (a * p + b) % mod`,
664
- ` END TRANSFORM`,
665
- ` TRANSFORM modular_inverse`,
666
- ` INPUT {a: INTEGER, mod: INTEGER}`,
667
- ` OUTPUT {a_inv: INTEGER}`,
668
- ` REQUIRES gcd(a, mod) EQUALS 1`,
669
- ` PRODUCES a_inv SUCH_THAT (a * a_inv) % mod EQUALS 1`,
670
- ` END TRANSFORM`,
671
- `END SCOPE`,
672
- ``,
673
- `SCOPE affine_cipher [level: 1]`,
674
- ` ASSUME modular_arithmetic SCOPE HOLDS`,
675
- ` ENTITY affine_key`,
676
- ` FIELD a: INTEGER DISCRETE VALUES {1,3,5,7,9,11,15,17,19,21,23,25}`,
677
- ` FIELD b: INTEGER BOUND[0, 25]`,
678
- ` FIELD a_idx: INTEGER BOUND[0, 11]`,
679
- ` FIELD a_norm: REAL BOUND[0, 1]`,
680
- ` FIELD b_norm: REAL BOUND [0, 1]`,
681
- ` DERIVES a FROM a_idx BY lookup_valid_a`,
682
- ` DERIVES a_norm FROM a_idx BY divide_11`,
683
- ` DERIVES b_norm FROM b BY divide_25`,
684
- ` BOUND a COPRIME_TO 26`,
685
- ` END ENTITY`,
686
- ` ENTITY affine_transform_result`,
687
- ` FIELD plaintext: INTEGER BOUND[0, 25] EQUALS ${p}`,
688
- ` FIELD ciphertext: INTEGER BOUND[0, 25]`,
689
- ` DERIVES ciphertext FROM {affine_key.a, plaintext, affine_key.b} BY modular_multiply_add`,
690
- ` END ENTITY`,
691
- ` ENTITY affine_inverse`,
692
- ` FIELD a_inv: INTEGER EQUALS ${aInv}`,
693
- ` FIELD recovery: INTEGER`,
694
- ` DERIVES recovery FROM {a_inv, ciphertext, b} BY modular_multiply_add`,
695
- ` END ENTITY`,
696
- ` CONTRADICT invertible WITH non_coprime_a`,
697
- ` AT SCOPE affine_cipher`,
698
- ` BOUNDARY_TYPE INFORMATION`,
699
- ` END CONTRADICT`,
700
- ` OBSERVE affine_transform_result.ciphertext EQUALS ${cipher}`,
701
- ` UNKNOWN affine_key.a_norm: REAL BOUND[0, 1]`,
702
- ` UNKNOWN affine_key.b_norm: REAL BOUND[0, 1]`,
703
- ` COLLAPSE affine_cipher`,
704
- ` GIVEN {affine_transform_result.plaintext, affine_transform_result.ciphertext}`,
705
- ` FIND {affine_key.a_norm, affine_key.b_norm}`,
706
- ` CONFIDENCE 0.99`,
707
- ` END COLLAPSE`,
708
- `END SCOPE`,
709
- ].join("\n");
710
 
711
- samples.push({
712
- id: randomUUID(), domain: "cryptography", subdomain: "affine",
713
- sense: "EQUAL", n_vars: 2,
714
- vars_text: "VARS c0 IN[0 11] c1 IN [0 25]",
715
- expr_text: `EXPR AFFINE a=${a}(idx=${aIdx}) b=${b} plain=${p} cipher=${cipher}`,
716
- sense_text: "SENSE EQUAL",
717
- b_raw: fmt(cipher), b_norm: fmt(safeNorm(cipher), 8),
718
- c_values: [aIdx, b],
719
- mask: [1,1], candidates:[], step_count: 0, axl_source: axl,
720
- metadata: {
721
- description: `Affine a=${a} b=${b} plain=${p} → cipher=${cipher}`,
722
- units: "character_code", difficulty: "hard",
723
- scope_depth: 2, has_emergence: false, has_contradiction: true,
724
- a_inverse: aInv, coprimality_proof: `gcd(${a},26)=1`
725
- }
726
  });
727
- }
728
- return samples;
729
- }
730
-
731
- // ── OPTIMIZATION (deep AXL) ───────────────────────────────────────────────────
732
- function synthOptimizationSamples(n) {
733
- const samples =[];
734
- for (let i = 0; i < n; i++) {
735
- const sense = randchoice(["MINIMIZE","MAXIMIZE"]);
736
- const nVars = randint(2,6);
737
- try {
738
- const coeffs = Array.from({length:nVars}, ()=>rnd(0.1,10.0));
739
- const cOpt = sense === "MINIMIZE" ? Array(nVars).fill(0.0) : Array(nVars).fill(1.0);
740
- const cVals = cOpt.map(v=>Math.min(1.0,Math.max(0.0,v+rnd(-0.05,0.05))));
741
- const bRaw = cVals.reduce((acc,v,j)=>acc+v*coeffs[j],0);
742
- const exprStr = coeffs.map((c,j)=>`${c.toFixed(3)}*c${j}`).join(" + ");
743
-
744
- const axl =[
745
- `SCOPE constraint_primitives [level: 0]`,
746
- ` ASSUME variable EXISTS`,
747
- ` ASSUME variable BOUND [0, 1]`,
748
- ` ASSUME objective EXISTS`,
749
- `END SCOPE`,
750
- ``,
751
- `SCOPE linear_program [level: 1]`,
752
- ` ASSUME constraint_primitives SCOPE HOLDS`,
753
- ``,
754
- ` ENTITY decision_variables`,
755
- ...Array.from({length:nVars},(_,j)=>
756
- ` FIELD c${j}: REAL BOUND[0, 1]`),
757
- ` END ENTITY`,
758
- ``,
759
- ` ENTITY objective_function`,
760
- ` FIELD value: REAL`,
761
- ` DERIVES value FROM {${Array.from({length:nVars},(_,j)=>`c${j}`).join(", ")}} BY linear_combination`,
762
- ` TENDS value ${sense === "MINIMIZE" ? "MIN" : "MAX"}`,
763
- ` END ENTITY`,
764
- ``,
765
- ` TRANSFORM linear_combination`,
766
- ` INPUT {${Array.from({length:nVars},(_,j)=>`c${j}: REAL BOUND [0,1]`).join(", ")}}`,
767
- ` OUTPUT {value: REAL}`,
768
- ` PRODUCES value EQUALS ${exprStr}`,
769
- ` END TRANSFORM`,
770
- ``,
771
- ` OBJECTIVE ${sense.toLowerCase()}_objective`,
772
- ` OPTIMIZE value ${sense}`,
773
- ` SUBJECT TO ${Array.from({length:nVars},(_,j)=>`c${j} WITHIN [0,1]`).join("\n SUBJECT TO ")}`,
774
- ` END OBJECTIVE`,
775
- ``,
776
- ` OBSERVE value EQUALS ${bRaw.toFixed(6)}`,
777
- ` UNKNOWN ${Array.from({length:nVars},(_,j)=>`c${j}: REAL BOUND [0, 1]`).join("\n UNKNOWN ")}`,
778
- ``,
779
- ` COLLAPSE linear_program`,
780
- ` GIVEN {value EQUALS ${bRaw.toFixed(4)}}`,
781
- ` FIND {${Array.from({length:nVars},(_,j)=>`c${j}`).join(", ")}}`,
782
- ` CONFIDENCE 0.95`,
783
- ` END COLLAPSE`,
784
- `END SCOPE`,
785
- ].join("\n");
786
-
787
- samples.push({
788
- id: randomUUID(), domain: "optimization",
789
- subdomain: `linear_${sense.toLowerCase()}_${nVars}var`,
790
- sense, n_vars: nVars,
791
- vars_text: `VARS ${Array.from({length:nVars},(_,j)=>`c${j} IN[0 1]`).join(" ")}`,
792
- expr_text: `EXPR ${exprStr}`,
793
- sense_text: `SENSE ${sense}`,
794
- b_raw: fmt(bRaw), b_norm: fmt(safeNorm(bRaw), 8),
795
- c_values: cVals.map(v=>fmt(v)),
796
- mask: Array(nVars).fill(1),
797
- candidates:[], step_count: 0, axl_source: axl,
798
- metadata: {
799
- description: `Linear ${sense.toLowerCase()} over ${nVars} variables`,
800
- units: "objective", difficulty: "easy",
801
- scope_depth: 2, has_emergence: false, has_contradiction: false
802
  }
803
- });
804
- } catch(e) {}
805
- }
806
- return samples;
807
- }
808
-
809
- // ── SYNTHETIC GENERATOR MAP ───────────────────────────────────────────────────
810
- const SYNTHETIC_GENERATORS = {
811
- physics: synthPhysicsSamples,
812
- finance: synthFinanceSamples,
813
- cryptography_xor: synthXorSamples,
814
- cryptography_caesar: synthCaesarSamples,
815
- cryptography_vigenere:synthVigenereSamples,
816
- cryptography_affine: synthAffineSamples,
817
- optimization: synthOptimizationSamples,
818
- };
819
-
820
- // ── FOCUS TRACKER ─────────────────────────────────────────────────────────────
821
- const tracker = {
822
- recent:[], counts: {}, total: 0,
823
- record(domain) {
824
- this.recent.push(domain);
825
- if (this.recent.length > 100) this.recent.shift();
826
- this.counts[domain] = (this.counts[domain]||0) + 1;
827
- this.total++;
828
- },
829
- stats() {
830
- return { total: this.total, counts: this.counts, recent: this.recent.slice(-20) };
831
- }
832
- };
833
 
834
- // ── DATASET STATE ─────────────────────────────────────────────────────────────
835
- let dataset =[];
836
- function loadDataset() {
837
- if (fs.existsSync(DATASET_PATH)) {
838
- dataset = JSON.parse(fs.readFileSync(DATASET_PATH,"utf8"));
839
- log(`Loaded ${dataset.length} existing samples`, "OK");
840
  }
841
  }
842
- function saveDataset() {
843
- fs.writeFileSync(DATASET_PATH, JSON.stringify(dataset, null, 2));
844
- log(`Saved ${dataset.length} samples → ${DATASET_PATH}`, "OK");
845
- }
846
 
847
- // ── BEDROCK CLIENT ────────────────────────────────────────────────────────────
848
 
849
- // Initialize Bedrock Client with NodeHttpHandler explicitly
850
- const bedrockClient = new BedrockRuntimeClient({
851
- region: AWS_REGION,
852
- requestHandler: new NodeHttpHandler({
853
- http2Handler: undefined,
854
- })
855
  });
856
 
857
- const AXL_SPEC = `
858
- # AXL Abstraction Exchange Language
859
- ### A Constraint-First, Bidirectionally Navigable Abstraction Language
860
- ---
861
-
862
- ## PHILOSOPHY
863
-
864
- AXL treats existence as a consequence of constraint satisfaction.
865
- Things exist not because they are declared, but because they are
866
- the only things consistent with the active assumptions and bounds.
867
- The language navigates upward (increasing abstraction, emergence)
868
- and downward (reducing abstraction, collapse to concrete).
869
-
870
- The system does not know biology, physics, or cryptography.
871
- It knows only: what is bounded, what is tended toward, what is
872
- observed, and what must follow. Domain knowledge lives in the
873
- encoder. AXL is what survives after domain is stripped away.
874
-
875
- ---
876
-
877
- ## PART I — FULL VOCABULARY
878
-
879
- ### 1. SCOPE DECLARATION
880
- Declares an abstraction level. Everything inside a scope inherits
881
- its level tag. Scopes are numbered — lower is more fundamental.
882
-
883
- SCOPE <name> [level: <int>]
884
- ...contents...
885
- END SCOPE
886
-
887
- Example levels (not hardcoded, user defined):
888
- - level 0 = most fundamental (quantum, bits)
889
- - level 1 = composed structures (atoms, bytes)
890
- - level 2 = functional systems (molecules, data blocks)
891
- - level 3 = emergent behavior (cells, algorithms)
892
- - level N = arbitrary abstraction ceiling
893
-
894
- ---
895
-
896
- ### 2. ENTITY
897
- A thing that exists within a scope. Has fields, states, and
898
- existence conditions. An entity does not exist unless its
899
- REQUIRES clause is satisfied.
900
-
901
- ENTITY <name>
902
- FIELD <name>: <type>[BOUND <range>] [CONSERVES] [DISCRETE]
903
- STATE <name>: REQUIRES <condition>
904
- TENDS <field> <direction>
905
- DERIVES FROM <entity_list>
906
- END ENTITY
907
-
908
- **FIELD** — a measurable or logical property of the entity
909
- **CONSERVES** — this field cannot change across any TRANSFORM
910
- **DISCRETE** — field only takes integer or enumerated values
911
- **TENDS** — soft directional pull on a field (not a hard target)
912
-
913
- ---
914
-
915
- ### 3. ASSUME
916
- Axiom declaration. Taken as true without derivation.
917
- The foundation everything else builds on.
918
- Multiple ASSUMEs compound — all must hold simultaneously.
919
-
920
- ASSUME <statement>
921
- ASSUME <entity> EXISTS
922
- ASSUME <field> EQUALS <value>
923
- ASSUME <relationship> HOLDS
924
-
925
- ---
926
-
927
- ### 4. BOUND
928
- Hard constraint on a field or relationship.
929
- Nothing outside a BOUND can exist in this scope.
930
-
931
- BOUND <field> WITHIN [<min>, <max>]
932
- BOUND <field> ABOVE <value>
933
- BOUND <field> BELOW <value>
934
- BOUND <field> EQUALS <value> # exact, no freedom
935
- BOUND <entity> COUNT WITHIN [<min>, <max>]
936
- BOUND <a> FORBIDS <b> # mutual exclusion
937
-
938
- ---
939
-
940
- ### 5. TEND
941
- Soft objective. The system pulls toward this but does not
942
- require it. Multiple TENDs create competing pressures that
943
- produce equilibrium — emergence happens here.
944
-
945
- TEND <field> MIN # pull toward minimum
946
- TEND <field> MAX # pull toward maximum
947
- TEND <field> TOWARD <value> # pull toward specific value
948
- TEND <system> STABLE # resist perturbation
949
- TEND <field> FOLLOW <other_field> # track another field
950
-
951
- ---
952
-
953
- ### 6. OBJECTIVE
954
- Hard optimization target. Unlike TEND, this must be satisfied
955
- for the scope to be considered resolved.
956
-
957
- OBJECTIVE <name>
958
- OPTIMIZE <field>[MIN | MAX | EQUAL <value>]
959
- SUBJECT TO <constraint_list>
960
- END OBJECTIVE
961
-
962
- ---
963
-
964
- ### 7. DERIVE
965
- Declares that something follows necessarily from other things.
966
- If the sources hold, the derived thing must hold.
967
- This is the upward propagation engine.
968
-
969
- DERIVE <entity | field | state>
970
- FROM <source_list>
971
- WHEN <condition>
972
- BY <transform_name>
973
- END DERIVE
974
-
975
- ---
976
-
977
- ### 8. TRANSFORM
978
- A process that maps one configuration to another.
979
- Transforms are the edges between scope levels.
980
- They must declare what they CONSERVE and what they CHANGE.
981
-
982
- TRANSFORM <name>
983
- INPUT <entity_or_field_list>
984
- OUTPUT <entity_or_field_list>
985
- CONSERVES <field_list>
986
- CHANGES <field_list>
987
- REQUIRES <precondition>
988
- PRODUCES <postcondition>
989
- END TRANSFORM
990
-
991
- ---
992
-
993
- ### 9. OBSERVE
994
- What has been measured. This is the B value in the UCE.
995
- The system will work backwards from this to find what
996
- configuration of unknowns is consistent with it.
997
-
998
- OBSERVE <field | entity | state> EQUALS <value>
999
- OBSERVE <field> WITHIN [<min>, <max>]
1000
- OBSERVE <pattern> IN <output>
1001
-
1002
- ---
1003
-
1004
- ### 10. UNKNOWN
1005
- What we are solving for. The C vector in the UCE.
1006
- The system navigates the abstraction domain to find
1007
- values of UNKNOWNs that satisfy all constraints
1008
- given the OBSERVATIONs.
1009
-
1010
- UNKNOWN <name>: <type> BOUND[<min>, <max>]
1011
- UNKNOWN <name>: DISCRETE WITHIN <set>
1012
-
1013
- ---
1014
-
1015
- ### 11. COLLAPSE
1016
- Instruction to reduce abstraction — find the most concrete
1017
- configuration satisfying all active constraints.
1018
- This is reverse abstraction in one word.
1019
-
1020
- COLLAPSE <scope | entity | system>
1021
- GIVEN <observation_list>
1022
- FIND <unknown_list>
1023
- CONFIDENCE <threshold>
1024
- END COLLAPSE
1025
-
1026
- ---
1027
-
1028
- ### 12. EXPAND
1029
- Opposite of COLLAPSE. Given a concrete configuration,
1030
- derive upward — what higher-level behaviors emerge?
1031
-
1032
- EXPAND <entity | configuration>
1033
- THROUGH <scope_list>
1034
- OBSERVE_EMERGENT <property_list>
1035
- END EXPAND
1036
-
1037
- ---
1038
-
1039
- ### 13. CONTRADICT
1040
- Flags that two things cannot both be true simultaneously.
1041
- Not an error — a scope boundary marker.
1042
- Where contradictions appear is where the interesting
1043
- physics, biology, and logic lives.
1044
-
1045
- CONTRADICT <statement_a> WITH <statement_b>
1046
- AT SCOPE <level>
1047
- BOUNDARY_TYPE[SCALE | SPEED | INFORMATION | ENERGY]
1048
-
1049
- ---
1050
-
1051
- ### 14. EMERGES
1052
- Declares a property that does not exist at lower scopes
1053
- but appears when lower entities compose.
1054
- Emergence is not reducible to its parts in AXL —
1055
- it must be explicitly declared.
1056
-
1057
- EMERGES <property>
1058
- FROM COMPOSITION OF <entity_list>
1059
- AT SCOPE <level>
1060
- NOT PRESENT AT SCOPE <lower_level>
1061
-
1062
- ---
1063
-
1064
- ### 15. COMPOSES
1065
- Declares that an entity is built from other entities.
1066
- Composition respects all lower-scope constraints.
1067
-
1068
- COMPOSES <higher_entity>
1069
- FROM <lower_entity_list>
1070
- BOUND count: <range>
1071
- CONSERVING <field_list>
1072
- END COMPOSES
1073
-
1074
- ---
1075
-
1076
- ### 16. STEP
1077
- Sequence counter for iterative or feedback processes.
1078
- Enables the system to learn groups across attempts.
1079
- Critical for the mining feedback loop.
1080
-
1081
- STEP <n>
1082
- STATE <snapshot>
1083
- CANDIDATE <configuration>
1084
- DELTA <change_from_previous>
1085
- END STEP
1086
-
1087
- ---
1088
-
1089
- ### 17. CANDIDATE
1090
- A proposed solution configuration.
1091
- Multiple candidates can coexist until COLLAPSE selects.
1092
-
1093
- CANDIDATE <n>
1094
- <field>: <value>
1095
- SCORE: <objective_value>
1096
- CONFIDENCE: <float 0-1>
1097
- END CANDIDATE
1098
-
1099
- ---
1100
-
1101
- ### 18. UNLESS
1102
- Conditional override. Higher scope can override lower scope
1103
- constraints under specific conditions.
1104
-
1105
- UNLESS <condition>
1106
- OVERRIDE <constraint>
1107
- WITH <replacement>
1108
- END UNLESS
1109
-
1110
- ---
1111
-
1112
- ### 19. CONSERVES
1113
- Declares an invariant across the entire system regardless
1114
- of what transforms occur. Conservation laws in physics,
1115
- invariants in computation, conservation of mass — all CONSERVES.
1116
-
1117
- CONSERVES <quantity> ACROSS <transform_list>
1118
- CONSERVES <quantity> WITHIN SCOPE <level>
1119
-
1120
- ---
1121
-
1122
- ### 20. SAMPLE
1123
- A specific observed instance used as training signal
1124
- for the diffusion engine. The raw material for learning.
1125
-
1126
- SAMPLE <id>
1127
- INPUT <configuration>
1128
- OUTPUT <observed_value>
1129
- STEP <n>
1130
- END SAMPLE
1131
-
1132
-
1133
- ---
1134
-
1135
- ## PART II — GRAMMAR RULES
1136
-
1137
- program := scope_block+
1138
- scope_block := SCOPE name [level] body END SCOPE
1139
- body := statement*
1140
- statement := assume | entity | bound | tend | objective
1141
- | derive | transform | observe | unknown
1142
- | collapse | expand | contradict | emerges
1143
- | composes | step | candidate | conserves
1144
- | sample | unless
1145
-
1146
- condition := field op value | entity EXISTS | state ACTIVE
1147
- | condition AND condition | condition OR condition
1148
- | NOT condition
1149
-
1150
- range := [min, max] | {discrete_set}
1151
- direction := MIN | MAX | STABLE | TOWARD value | FOLLOW field
1152
- type := REAL | INTEGER | BOOLEAN | SYMBOLIC | VECTOR
1153
- op := EQUALS | ABOVE | BELOW | WITHIN | FORBIDS
1154
-
1155
- ---
1156
-
1157
- ## PART III — DEMONSTRATIONS
1158
-
1159
- ---
1160
-
1161
- ### DEMONSTRATION 1: THE ATOM
1162
- #### Encoding atomic structure from quantum scope upward
1163
-
1164
- axl:
1165
- # ════════════════════════════════════════════════════
1166
- # ATOM SYSTEM
1167
- # Starting assumption: energy exists and is quantized
1168
- # ════════════════════════════════════════════════════
1169
-
1170
- SCOPE quantum[level: 0]
1171
-
1172
- ASSUME energy EXISTS
1173
- ASSUME energy DISCRETE # quantization axiom
1174
- ASSUME charge EXISTS
1175
- CONSERVES charge ACROSS ALL_TRANSFORMS
1176
- CONSERVES energy ACROSS ALL_TRANSFORMS UNLESS transform EQUALS radiation
1177
-
1178
- ENTITY quark
1179
- FIELD charge: REAL BOUND [-1, 1] DISCRETE VALUES {-2/3, -1/3, 1/3, 2/3}
1180
- FIELD color: SYMBOLIC DISCRETE VALUES {red, green, blue, antired, antigreen, antiblue}
1181
- FIELD mass: REAL BOUND [0.002, 4.5] # GeV
1182
- STATE free: REQUIRES energy ABOVE confinement_threshold
1183
- STATE confined: REQUIRES energy BELOW confinement_threshold
1184
- TENDS state TOWARD confined # quarks want to be bound
1185
- END ENTITY
1186
-
1187
- ENTITY gluon
1188
- FIELD charge: BOUND[0, 0] CONSERVES
1189
- FIELD color: SYMBOLIC # carries color charge
1190
- TENDS quark_binding MAX # gluons maximize binding
1191
- END ENTITY
1192
-
1193
- BOUND quark COLOR_NEUTRAL IN any_free_composite # color confinement
1194
-
1195
- END SCOPE
1196
-
1197
-
1198
- SCOPE hadron [level: 1]
1199
-
1200
- ASSUME quantum SCOPE HOLDS # inherit all quantum rules
1201
-
1202
- COMPOSES proton
1203
- FROM quark COUNT EQUALS 3
1204
- CONFIGURATION {up, up, down} # charge = 2/3+2/3-1/3 = +1
1205
- CONSERVING charge
1206
- BOUND total_charge EQUALS 1
1207
- BOUND color EQUALS neutral # must be colorless
1208
- END COMPOSES
1209
-
1210
- COMPOSES neutron
1211
- FROM quark COUNT EQUALS 3
1212
- CONFIGURATION {up, down, down} # charge = 2/3-1/3-1/3 = 0
1213
- CONSERVING charge
1214
- BOUND total_charge EQUALS 0
1215
- BOUND color EQUALS neutral
1216
- END COMPOSES
1217
-
1218
- EMERGES stability
1219
- FROM COMPOSITION OF {proton, neutron}
1220
- AT SCOPE hadron
1221
- NOT PRESENT AT SCOPE quantum
1222
- # individual quarks don't have nuclear stability — it emerges here
1223
-
1224
- END SCOPE
1225
-
1226
-
1227
- SCOPE nucleus[level: 2]
1228
-
1229
- ASSUME hadron SCOPE HOLDS
1230
-
1231
- COMPOSES nucleus
1232
- FROM {proton, neutron}
1233
- BOUND proton_count WITHIN [1, 118] # known elements
1234
- BOUND neutron_count WITHIN [0, 177]
1235
- TEND binding_energy MAX # nucleus maximizes binding
1236
- TEND neutron_to_proton_ratio TOWARD 1.0 # stability tendency
1237
- END COMPOSES
1238
-
1239
- ENTITY strong_force
1240
- FIELD range: BOUND[0, 3e-15] # femtometers — very short range
1241
- FIELD strength: REAL
1242
- TENDS nucleon_separation MIN # pulls nucleons together
1243
- END ENTITY
1244
-
1245
- ENTITY weak_force
1246
- TRANSFORMS neutron INTO proton
1247
- WHEN neutron_to_proton_ratio ABOVE stable_ratio
1248
- PRODUCES {proton, electron, antineutrino} # beta decay
1249
- CONSERVING charge
1250
- CONSERVING lepton_number
1251
- END ENTITY
1252
-
1253
- EMERGES atomic_number
1254
- FROM proton COUNT
1255
- AT SCOPE nucleus
1256
- # proton count alone determines element identity — pure emergence
1257
-
1258
- END SCOPE
1259
-
1260
-
1261
- SCOPE atom[level: 3]
1262
-
1263
- ASSUME nucleus SCOPE HOLDS
1264
-
1265
- ENTITY electron
1266
- FIELD charge: BOUND[-1, -1] CONSERVES
1267
- FIELD mass: BOUND[9.109e-31, 9.109e-31] CONSERVES
1268
- FIELD spin: DISCRETE VALUES {-0.5, 0.5}
1269
- FIELD orbital: DISCRETE VALUES {s, p, d, f}
1270
- FIELD energy_level: INTEGER BOUND [1, 7]
1271
- TENDS energy MIN # electrons seek lowest energy
1272
- BOUND same_orbital_same_spin FORBIDS # Pauli exclusion principle
1273
- END ENTITY
1274
-
1275
- COMPOSES atom
1276
- FROM {nucleus, electron}
1277
- BOUND electron_count EQUALS proton_count # neutral atom
1278
- TEND electron ORBITAL_FILL lowest_energy_first # Aufbau principle
1279
- END COMPOSES
1280
-
1281
- EMERGES chemical_behavior
1282
- FROM valence_electron_configuration
1283
- AT SCOPE atom
1284
- NOT PRESENT AT SCOPE nucleus
1285
- # chemistry is purely a scope 3 emergence — nucleus knows nothing of it
1286
-
1287
- EMERGES periodic_properties
1288
- FROM atomic_number MODULO orbital_filling_pattern
1289
- AT SCOPE atom
1290
-
1291
- END SCOPE
1292
-
1293
-
1294
- # ══ COLLAPSE EXAMPLE: Given observed spectral lines, find element ══
1295
-
1296
- OBSERVE spectral_emission EQUALS {656nm, 486nm, 434nm, 410nm}
1297
-
1298
- UNKNOWN element: SYMBOLIC WITHIN periodic_table
1299
- UNKNOWN atomic_number: INTEGER BOUND [1, 118]
1300
- UNKNOWN electron_configuration: VECTOR
1301
-
1302
- COLLAPSE atom
1303
- GIVEN {spectral_emission}
1304
- FIND {element, atomic_number, electron_configuration}
1305
- CONFIDENCE 0.95
1306
- END COLLAPSE
1307
-
1308
- # Answer the system should derive: Hydrogen (Z=1)
1309
-
1310
-
1311
- ---
1312
-
1313
- ### DEMONSTRATION 2: SHA-256 MINING
1314
- #### Encoding the constraint and the intelligent nonce search
1315
-
1316
- axl:
1317
- # ════════════════════════════════════════════════════
1318
- # SHA-256 BITCOIN MINING SYSTEM
1319
- # Objective: find nonce such that hash < target
1320
- # The system does not know what SHA-256 is.
1321
- # It knows: there is a transform, it has an output,
1322
- # the output must satisfy a bound.
1323
- # ════════════════════════════════════════════════════
1324
-
1325
- SCOPE bitfield[level: 0]
1326
-
1327
- ASSUME bit EXISTS
1328
- ASSUME bit DISCRETE VALUES {0, 1}
1329
- ENTITY bit_array
1330
- FIELD length: INTEGER
1331
- FIELD value: VECTOR of bit
1332
- BOUND value COUNT EQUALS length
1333
- END ENTITY
1334
-
1335
- END SCOPE
1336
-
1337
-
1338
- SCOPE sha256_internals[level: 1]
1339
-
1340
- ASSUME bitfield SCOPE HOLDS
1341
-
1342
- ENTITY message_schedule
1343
- FIELD W: VECTOR COUNT EQUALS 64 # 64 32-bit words
1344
- DERIVES FROM input_block
1345
- BY expansion_transform
1346
- END ENTITY
1347
-
1348
- TRANSFORM round_function
1349
- INPUT {working_vars: VECTOR COUNT 8, W_i: bit_array}
1350
- OUTPUT {working_vars_next: VECTOR COUNT 8}
1351
- CONSERVES bit_count
1352
- CHANGES working_vars
1353
- # 64 applications of this = full SHA-256
1354
- # Each application: sigma, choice, majority, mod add
1355
- # AXL does not encode the arithmetic — that's the domain encoder's job
1356
- # AXL encodes only: this is a deterministic transform with known structure
1357
- END TRANSFORM
1358
-
1359
- CONTRADICT input_a WITH input_b
1360
- AT SCOPE sha256_internals
1361
- BOUNDARY_TYPE INFORMATION
1362
- # Two different inputs CAN produce same output (collision)
1363
- # But finding one is computationally infeasible
1364
- # This contradiction is the security boundary
1365
-
1366
- TRANSFORM sha256
1367
- INPUT {message: bit_array BOUND length WITHIN [0, 2^64]}
1368
- OUTPUT {digest: bit_array BOUND length EQUALS 256}
1369
- CONSERVES nothing # one-way: no conservation
1370
- CHANGES everything # avalanche: all output bits affected
1371
- REQUIRES input EXISTS
1372
- PRODUCES digest PSEUDO_RANDOM_FROM input
1373
- # PSEUDO_RANDOM_FROM is the key declaration:
1374
- # output is deterministic but statistically independent of input structure
1375
- END TRANSFORM
1376
-
1377
- END SCOPE
1378
-
1379
-
1380
- SCOPE block_header[level: 2]
1381
-
1382
- ASSUME sha256_internals SCOPE HOLDS
1383
-
1384
- ENTITY block_header
1385
- FIELD version: INTEGER BOUND[1, 4]
1386
- FIELD prev_hash: bit_array BOUND length EQUALS 256 # GIVEN, fixed
1387
- FIELD merkle_root: bit_array BOUND length EQUALS 256 # GIVEN, fixed
1388
- FIELD timestamp: INTEGER # GIVEN, approximately fixed
1389
- FIELD bits: INTEGER # GIVEN, encodes target
1390
- FIELD nonce: INTEGER BOUND[0, 4294967295] # UNKNOWN — 32 bits of freedom
1391
- END ENTITY
1392
-
1393
- DERIVE target
1394
- FROM bits
1395
- BY difficulty_decode_transform
1396
- # target = a 256-bit number. Valid hash must be below it.
1397
- # More leading zeros in target = harder problem
1398
-
1399
- END SCOPE
1400
-
1401
-
1402
- SCOPE mining [level: 3]
1403
-
1404
- ASSUME block_header SCOPE HOLDS
1405
-
1406
- TRANSFORM double_sha256
1407
- INPUT {block_header}
1408
- OUTPUT {hash: bit_array BOUND length EQUALS 256}
1409
- BY {sha256 APPLIED_TWICE}
1410
- END TRANSFORM
1411
-
1412
- OBJECTIVE valid_block
1413
- OPTIMIZE hash MIN # minimize hash value numerically
1414
- SUBJECT TO hash BELOW target # hard bound — must be satisfied
1415
- SUBJECT TO nonce WITHIN[0, 4294967295]
1416
- END OBJECTIVE
1417
-
1418
- # ══ HERE IS THE INTELLIGENCE LAYER ══
1419
- # The nonce space has NO smooth gradient (SHA-256 destroys it)
1420
- # But the SEARCH SPACE has learnable structure:
1421
- # - which regions have been explored (coverage)
1422
- # - step count gives sequence context
1423
- # - candidate scoring gives relative ranking
1424
- # This is what the UCE learns — not the hash, but the search
1425
-
1426
- UNKNOWN nonce: INTEGER BOUND[0, 4294967295]
1427
-
1428
- STEP 0
1429
- STATE {nonce_space: unexplored}
1430
- CANDIDATE 0
1431
- nonce: SAMPLE uniform
1432
- SCORE: UNKNOWN
1433
- CONFIDENCE: 0.0
1434
- END CANDIDATE
1435
- END STEP
1436
-
1437
- STEP N
1438
- STATE {
1439
- explored_regions: VECTOR, # coverage map
1440
- best_hash_so_far: bit_array,
1441
- distance_to_target: INTEGER,
1442
- step_count: N
1443
- }
1444
- CANDIDATE 0..50 # 50 parallel candidates
1445
- nonce: DERIVES FROM {
1446
- explored_regions,
1447
- step_count,
1448
- best_hash_so_far
1449
- }
1450
- # The system learns: given search history,
1451
- # what nonce regions have NOT been tried
1452
- # and which historically neighboring regions
1453
- # produced closer hashes (within this block's structure)
1454
- SCORE: distance_to_target MIN
1455
- CONFIDENCE: LEARNS
1456
- END CANDIDATE
1457
- END STEP
1458
-
1459
- OBSERVE hash BELOW target # this is the termination condition
1460
-
1461
- COLLAPSE mining
1462
- GIVEN {block_header_fixed_fields, target, search_history}
1463
- FIND {nonce}
1464
- CONFIDENCE 0.99
1465
- END COLLAPSE
1466
-
1467
- # ══ WHAT THE SYSTEM LEARNS ══
1468
- # Not: how to reverse SHA-256
1469
- # But: how to cover the nonce space intelligently
1470
- # avoiding redundant regions, clustering search
1471
- # around previously productive neighborhoods
1472
- # The intelligence is in the search, not the hash
1473
-
1474
- END SCOPE
1475
-
1476
-
1477
- ---
1478
-
1479
- ### DEMONSTRATION 3: CELL DIVISION (MITOSIS)
1480
- #### Encoding life as constraint satisfaction
1481
-
1482
- axl:
1483
- # ════════════════════════════════════════════════════
1484
- # CELL DIVISION SYSTEM
1485
- # Life as constraints on information replication
1486
- # with error correction and state machines
1487
- # ════════════════════════════════════════════════════
1488
-
1489
- SCOPE molecular[level: 0]
1490
-
1491
- ASSUME molecule EXISTS
1492
- ASSUME information CAN BE ENCODED IN molecule
1493
- ASSUME chemical_bond EXISTS
1494
- CONSERVES atom_count ACROSS chemical_reactions
1495
- CONSERVES charge ACROSS chemical_reactions
1496
-
1497
- ENTITY nucleotide
1498
- FIELD base: SYMBOLIC DISCRETE VALUES {adenine, thymine, guanine, cytosine}
1499
- FIELD sugar: SYMBOLIC EQUALS deoxyribose
1500
- FIELD phosphate: BOOLEAN
1501
- BOUND adenine PAIRS_WITH thymine ONLY # base pairing rule
1502
- BOUND guanine PAIRS_WITH cytosine ONLY
1503
- END ENTITY
1504
-
1505
- ENTITY dna_strand
1506
- FIELD sequence: VECTOR of nucleotide
1507
- FIELD length: INTEGER BOUND [1, 3e9] # up to 3 billion base pairs
1508
- FIELD direction: SYMBOLIC DISCRETE VALUES {5_to_3, 3_to_5}
1509
- CONSERVES sequence UNLESS transform EQUALS mutation
1510
- TENDS base_pair_bonds STABLE # double helix stability
1511
- END ENTITY
1512
-
1513
- TRANSFORM base_pairing
1514
- INPUT {strand_a: dna_strand, strand_b: dna_strand}
1515
- OUTPUT {double_helix}
1516
- REQUIRES strand_a.direction FORBIDS strand_b.direction # antiparallel
1517
- REQUIRES each_base PAIRS_WITH complement
1518
- CONSERVES sequence_information
1519
- END TRANSFORM
1520
-
1521
- END SCOPE
1522
-
1523
-
1524
- SCOPE genome[level: 1]
1525
-
1526
- ASSUME molecular SCOPE HOLDS
1527
-
1528
- ENTITY chromosome
1529
- FIELD dna: dna_strand
1530
- FIELD histone_proteins: VECTOR
1531
- FIELD centromere_position: INTEGER
1532
- FIELD telomere_length: INTEGER BOUND [0, 15000] # erosion limit
1533
- TENDS compaction MAX WHEN cell_dividing EQUALS true
1534
- TENDS compaction MIN WHEN cell_active EQUALS true
1535
- END ENTITY
1536
-
1537
- ENTITY genome
1538
- FIELD chromosomes: VECTOR of chromosome
1539
- BOUND chromosome_count EQUALS 46 # human diploid — pairs of 23
1540
- CONSERVES chromosome_count UNLESS transform EQUALS meiosis
1541
- TENDS integrity MAX # genome resists damage
1542
- END ENTITY
1543
-
1544
- ENTITY dna_polymerase
1545
- FIELD error_rate: REAL BOUND[1e-9, 1e-9] # one error per billion bases
1546
- TENDS accuracy MAX
1547
- TRANSFORMS dna_strand INTO dna_strand_copy
1548
- CONSERVES sequence UNLESS error_rate TRIGGERS
1549
- END ENTITY
1550
-
1551
- EMERGES genetic_code
1552
- FROM nucleotide_triplet_sequence
1553
- AT SCOPE genome
1554
- NOT PRESENT AT SCOPE molecular
1555
- # individual nucleotides have no meaning — codons emerge at this level
1556
-
1557
- END SCOPE
1558
-
1559
-
1560
- SCOPE cell[level: 2]
1561
-
1562
- ASSUME genome SCOPE HOLDS
1563
-
1564
- ENTITY cell
1565
- FIELD genome: genome
1566
- FIELD membrane: BOOLEAN EQUALS true # boundary condition
1567
- FIELD atp_level: REAL BOUND[0, 1] # energy state
1568
- FIELD size: REAL BOUND[minimum_viable, maximum_before_division]
1569
- FIELD age: INTEGER # division counter
1570
- FIELD state: SYMBOLIC DISCRETE VALUES {
1571
- G1, # growth phase 1
1572
- S, # synthesis (DNA replication)
1573
- G2, # growth phase 2
1574
- M, # mitosis (division)
1575
- G0, # quiescent (resting)
1576
- apoptosis # programmed death
1577
- }
1578
- TENDS atp_level MAX # cells maximize energy
1579
- TENDS genome_integrity MAX # cells protect DNA
1580
- BOUND age BELOW hayflick_limit # telomere erosion limit
1581
- END ENTITY
1582
-
1583
- ENTITY checkpoint_protein
1584
- FIELD name: SYMBOLIC DISCRETE VALUES {p53, rb, cyclin_B, cdk1}
1585
- FIELD active: BOOLEAN
1586
- TENDS genome_damage OBSERVE # monitors DNA integrity
1587
- TRANSFORMS cell.state INTO apoptosis
1588
- WHEN genome_damage ABOVE repair_threshold
1589
- # p53 is the key constraint enforcer — if damage is too great, die
1590
- END ENTITY
1591
-
1592
- END SCOPE
1593
-
1594
-
1595
- SCOPE mitosis [level: 3]
1596
-
1597
- ASSUME cell SCOPE HOLDS
1598
-
1599
- # ══ TRIGGER CONDITIONS ══
1600
- # Cell division is itself a constraint satisfaction problem:
1601
- # divide WHEN AND ONLY WHEN all conditions hold
1602
 
1603
- OBJECTIVE division_trigger
1604
- OPTIMIZE cell.state EQUAL M
1605
- SUBJECT TO {
1606
- cell.size ABOVE division_threshold,
1607
- cell.atp_level ABOVE 0.7,
1608
- dna_replication EQUALS complete,
1609
- checkpoint_all EQUALS passed,
1610
- external_growth_signal EQUALS present,
1611
- cell.age BELOW hayflick_limit
1612
- }
1613
- # ALL conditions must hold — AND logic, not OR
1614
- # This is why cancer is a constraint violation:
1615
- # it occurs when checkpoint constraints are BROKEN
1616
- END OBJECTIVE
1617
 
1618
- TRANSFORM prophase
1619
- INPUT {cell: STATE G2}
1620
- OUTPUT {cell: chromosomes_condensed, spindle_forming}
1621
- REQUIRES division_trigger EQUALS satisfied
1622
- CONSERVES chromosome_count
1623
- CONSERVES genome_content
1624
- END TRANSFORM
 
1625
 
1626
- TRANSFORM metaphase
1627
- INPUT {cell: chromosomes_condensed}
1628
- OUTPUT {cell: chromosomes_aligned_at_plate}
1629
- REQUIRES spindle_attached_to EQUALS all_chromosomes
1630
- # Checkpoint: spindle assembly checkpoint
1631
- # If any chromosome unattached — PAUSE here
1632
- BOUND unattached_chromosomes EQUALS 0
1633
- UNLESS OVERRIDE apoptosis
1634
- END TRANSFORM
1635
 
1636
- TRANSFORM anaphase
1637
- INPUT {cell: chromosomes_aligned}
1638
- OUTPUT {sister_chromatids: separating}
1639
- CONSERVES chromosome_count_total
1640
- CHANGES chromosome_location
1641
- PRODUCES two_sets OF 46_chromosomes
1642
- END TRANSFORM
1643
 
1644
- TRANSFORM telophase_and_cytokinesis
1645
- INPUT {cell: chromatids_separated}
1646
- OUTPUT {daughter_cell_1, daughter_cell_2}
1647
- CONSERVES genome_content IN each_daughter
1648
- CONSERVES organelle_distribution APPROXIMATELY
1649
- PRODUCES {
1650
- daughter_cell_1: IDENTICAL_GENOME_TO parent,
1651
- daughter_cell_2: IDENTICAL_GENOME_TO parent
1652
  }
1653
- END TRANSFORM
1654
-
1655
- EMERGES tissue
1656
- FROM COMPOSITION OF {cell COUNT ABOVE 1}
1657
- AT SCOPE mitosis
1658
- NOT PRESENT AT SCOPE cell
1659
- # individual cells have no tissue identity — it emerges from composition
1660
-
1661
- EMERGES cancer
1662
- FROM checkpoint_protein.active EQUALS false
1663
- AND division_trigger SATISFIED_WITHOUT all_conditions
1664
- AT SCOPE mitosis
1665
- # Cancer is not a new thing — it is constraint violation
1666
- # The cell divides when it should not because the objective
1667
- # function has been corrupted
1668
- CONTRADICT cancer WITH normal_division
1669
- AT SCOPE mitosis
1670
- BOUNDARY_TYPE INFORMATION # corrupted information in genome
1671
-
1672
- # ══ COLLAPSE EXAMPLE: Cancer diagnosis ══
1673
-
1674
- OBSERVE {
1675
- cell.division_rate ABOVE normal_range,
1676
- checkpoint_protein.p53 EQUALS inactive,
1677
- cell.age ABOVE hayflick_limit
1678
- }
1679
-
1680
- UNKNOWN {
1681
- mutation_site: dna_strand LOCATION,
1682
- checkpoint_broken: SYMBOLIC,
1683
- division_trigger_violated: OBJECTIVE_CLAUSE
1684
- }
1685
-
1686
- COLLAPSE mitosis
1687
- GIVEN {abnormal_observations}
1688
- FIND {mutation_site, checkpoint_broken, division_trigger_violated}
1689
- CONFIDENCE 0.90
1690
- END COLLAPSE
1691
-
1692
- END SCOPE
1693
-
1694
-
1695
- # ════════════════════════════════════════════════════
1696
- # META: THE LANGUAGE DESCRIBING ITSELF
1697
- # AXL encoding its own structure
1698
- # ════════════════════════════════════════════════════
1699
-
1700
- SCOPE axl_meta [level: 0]
1701
-
1702
- ASSUME symbol EXISTS
1703
- ASSUME symbol CAN CARRY meaning
1704
- ASSUME meaning IS RELATIVE TO scope
1705
-
1706
- ENTITY keyword
1707
- FIELD token: SYMBOLIC
1708
- FIELD semantic: SYMBOLIC
1709
- FIELD abstraction_direction: DISCRETE VALUES {up, down, both, none}
1710
- FIELD arity: INTEGER # how many arguments it takes
1711
- END ENTITY
1712
-
1713
- ENTITY statement
1714
- FIELD keywords: VECTOR of keyword
1715
- FIELD scope_level: INTEGER
1716
- DERIVES meaning FROM {keywords, scope_level, context}
1717
- # Same token, different scope = different meaning
1718
- # BOUND in scope 0 (physics) ≠ BOUND in scope 3 (biology)
1719
- END ENTITY
1720
-
1721
- EMERGES program_meaning
1722
- FROM COMPOSITION OF {statement COUNT ABOVE 1}
1723
- AT SCOPE axl_meta
1724
- NOT PRESENT AT SCOPE symbol
1725
- # Individual symbols have no program meaning
1726
- # Meaning emerges from composition and scope
1727
-
1728
- TEND expressiveness MAX
1729
- TEND ambiguity MIN
1730
- CONTRADICT expressiveness WITH ambiguity
1731
- AT SCOPE axl_meta
1732
- BOUNDARY_TYPE INFORMATION
1733
- # All languages face this — AXL resolves it via scope tagging
1734
-
1735
- END SCOPE
1736
- `;
1737
-
1738
- function buildPrompt(n, recentDomains,
1739
- maxVars=8
1740
- // maxVars=20
1741
- ) {
1742
- const recentStr = recentDomains.slice(-10).join(", ") || "none yet";
1743
- return `${AXL_SPEC}
1744
-
1745
- ════════════════════════════════════════════════════════════
1746
- GENERATION TASK
1747
- ════════════════════════════════════════════════════════════
1748
 
1749
- Generate exactly ${n} UCE training samples as a JSON array.
1750
-
1751
- STRICT REQUIREMENTS:
1752
- 1. Output ONLY a valid JSON array. No markdown, no backticks, no preamble.
1753
- 2. Every sample MUST have all fields in the schema below.
1754
- 3. b_raw must be a computed finite float matching the AXL program's logic.
1755
- 4. c_values must be in RAW domain units matching the declared bounds in vars_text.
1756
- DO NOT pre-normalize to[0,1] — the pipeline does that. Example: if
1757
- vars_text says "VARS c0 IN [200 800]" then c_values should be like[650, 210].
1758
- 5. Every vars_text MUST start with the word VARS.
1759
- 6. Every sample must use a DIFFERENT domain or structural pattern.
1760
- 7. Vary: sense (EQUAL/MINIMIZE/MAXIMIZE/SELECT/TEND), n_vars (1-${maxVars}),
1761
- abstraction depth (scope_depth 2-10), domain.
1762
- 8. AXL programs must have 2-3 nested SCOPE blocks minimum.
1763
- 9. Include EMERGES for at least 40% of samples.
1764
- 10. Include STEP/CANDIDATE blocks for iterative search problems.
1765
- 11. Include CONTRADICT for problems with hard boundaries.
1766
- 12. Do NOT use domains recently overrepresented: ${recentStr}
1767
- 13. Be expressive, use all the information known on that problem and domain. minimum scope_depth: 3
1768
-
1769
- JSON SCHEMA (output array of these):
1770
- {
1771
- "id": "<uuid>",
1772
- "domain": "<domain>",
1773
- "subdomain": "<specific topic>",
1774
- "sense": "<EQUAL|MINIMIZE|MAXIMIZE|SELECT|TEND>",
1775
- "n_vars": <integer>,
1776
- "vars_text": "VARS c0 IN[lo hi] c1 IN [lo hi] ...",
1777
- "expr_text": "EXPR <description>",
1778
- "sense_text": "SENSE <EQUAL|MINIMIZE|MAXIMIZE|SELECT|TEND>",
1779
- "b_raw": <float>,
1780
- "b_norm": <sign(b)*log(1+|b|)/30>,
1781
- "c_values":[<raw domain values matching bounds>],
1782
- "mask": [1,1,...],
1783
- "candidates":[],
1784
- "step_count": <integer>,
1785
- "axl_source": "<full multi-scope AXL program as single string>",
1786
- "metadata": {
1787
- "description": "<one sentence>",
1788
- "units": "<units of b_raw>",
1789
- "difficulty": "<easy|medium|hard|expert>",
1790
- "scope_depth": <integer>,
1791
- "has_emergence": <boolean>,
1792
- "has_contradiction": <boolean>
1793
- }
1794
- }
1795
-
1796
- OUTPUT THE JSON ARRAY NOW:`;
1797
- }
1798
-
1799
- async function callBedrock(prompt) {
1800
- const model = "haiku";
1801
-
1802
- const command = new ConverseCommand({
1803
- modelId: BEDROCK_MODEL_ID,
1804
- messages: [{ role: "user", content:[{ text: prompt }] }],
1805
- inferenceConfig: {
1806
- maxTokens: 8000, //10000,
1807
- temperature: 1
1808
- }/*,
1809
- additionalModelRequestFields: (function() {
1810
- if (model.includes("haiku")) {
1811
- return {
1812
- reasoning_config: {
1813
- type: "enabled",
1814
- budget_tokens: 2048
1815
- }
1816
- };
1817
- } else if (model.includes("claude")) {
1818
- return {
1819
- // thinking: { type: "adaptive" },
1820
- output_config: { effort: "high" }
1821
- };
1822
- }
1823
- return undefined;
1824
- })() */
1825
- });
1826
-
1827
- const t0 = Date.now();
1828
- const res = await bedrockClient.send(command);
1829
- const text = res.output.message.content.find(b => b.text)?.text || "";
1830
- log(`Bedrock call ${((Date.now()-t0)/1000).toFixed(1)}s — ${text.length} chars`);
1831
-
1832
- const tokenUsage = res.usage ? (res.usage.inputTokens + res.usage.outputTokens) : 0;
1833
- console.log("Token Usage: " + tokenUsage);
1834
 
1835
- return text;
1836
- }
1837
-
1838
- function parseAIResponse(text) {
1839
- let t = text.trim();
1840
- for (const fence of ["```json","```JSON","```"]) {
1841
- if (t.startsWith(fence)) { t = t.slice(fence.length); break; }
1842
- }
1843
- if (t.endsWith("```")) t = t.slice(0,-3);
1844
- t = t.trim();
1845
- const start = t.indexOf("["), end = t.lastIndexOf("]");
1846
- if (start === -1 || end === -1) return[];
1847
- try {
1848
- return JSON.parse(t.slice(start, end+1));
1849
- } catch(e) {
1850
- log(`JSON parse error: ${e.message} — attempting salvage`, "WARN");
1851
- const saved =[];
1852
- let depth = 0, buf = "", inObj = false;
1853
- for (const ch of t.slice(start+1, end)) {
1854
- if (ch === "{") { depth++; inObj = true; }
1855
- if (inObj) buf += ch;
1856
- if (ch === "}") {
1857
- depth--;
1858
- if (depth === 0 && buf.trim()) {
1859
- try { saved.push(JSON.parse(buf)); } catch(_) {}
1860
- buf = ""; inObj = false;
1861
- }
1862
- }
1863
- }
1864
- log(`Salvaged ${saved.length} samples`);
1865
- return saved;
1866
- }
1867
- }
1868
-
1869
- // ── EXPRESS APP ───────────────────────────────────────────────────────────────
1870
- const app = express();
1871
- app.use(cors());
1872
- app.use(express.json());
1873
 
1874
- app.get("/status", (_, res) => res.json({
1875
- dataset_size: dataset.length,
1876
- dataset_path: DATASET_PATH,
1877
- bedrock_model: BEDROCK_MODEL_ID,
1878
- focus_tracker: tracker.stats(),
1879
- server_time: new Date().toISOString(),
1880
- }));
1881
 
1882
- app.get("/domains", (_, res) => res.json(tracker.stats()));
1883
 
1884
- app.post("/generate", async (req, res) => {
1885
- // Correcting the variable names to match the logic below
1886
- const n = parseInt(req.query.n ?? req.body.n ?? "50");
1887
- const rps = Math.min(parseFloat(req.query.rps ?? req.body.rps ?? DEFAULT_RPS.toString()), MAX_RPS);
1888
- const syntheticFraction = parseFloat(req.query.synthetic_fraction ?? req.body.synthetic_fraction ?? "0.4");
1889
- const maxVars = parseInt(req.query.max_vars ?? req.body.max_vars ?? "20");
1890
-
1891
- log(`Generation request: n=${n} rps=${rps} synthetic=${(syntheticFraction * 100).toFixed(0)}%`, "HEAD");
1892
-
1893
- let batchErrors = 0;
1894
- let newSamplesCount = 0;
1895
-
1896
- // ── 1. SYNTHETIC BATCH (Immediate Save) ──
1897
- const nSynthetic = Math.floor(n * syntheticFraction);
1898
- if (nSynthetic > 0) {
1899
- const gens = Object.values(SYNTHETIC_GENERATORS);
1900
- const perGen = Math.max(1, Math.ceil(nSynthetic / gens.length));
1901
- let tempSynth = [];
1902
- for (const genFn of gens) {
1903
- try { tempSynth.push(...genFn(perGen)); } catch(e) { log(`Gen error: ${e.message}`, "ERROR"); }
1904
- }
1905
- tempSynth = tempSynth.slice(0, nSynthetic);
1906
-
1907
- for (const raw of tempSynth) {
1908
- const norm = normalizeSample(raw);
1909
- if (norm && validateSample(norm)) {
1910
- dataset.push(norm);
1911
- tracker.record(norm.domain);
1912
- newSamplesCount++;
1913
- } else { batchErrors++; }
1914
  }
1915
- saveDataset();
1916
- log(`Synthetic batch committed to disk: ${newSamplesCount} samples`, "OK");
1917
- }
1918
-
1919
- // ── 2. AI BATCH (Incremental Save) ──
1920
- const nAI = n - nSynthetic;
1921
- const callsNeeded = Math.ceil(nAI / SAMPLES_PER_CALL);
1922
- const minInterval = 1000 / rps;
1923
-
1924
- // Respond immediately to prevent client-side timeouts
1925
- res.json({
1926
- message: "Generation started in background.",
1927
- total_requested: n,
1928
- synthetic_count: nSynthetic,
1929
- ai_tasks: callsNeeded
1930
- });
1931
 
1932
- // Run AI loop in background
1933
- (async () => {
1934
- for (let ci = 0; ci < callsNeeded; ci++) {
1935
- const t0 = Date.now();
1936
- try {
1937
- const prompt = buildPrompt(SAMPLES_PER_CALL, tracker.recent, maxVars);
1938
- const text = await callBedrock(prompt);
1939
- const parsed = parseAIResponse(text);
1940
-
1941
- let callValid = 0;
1942
- for (const raw of parsed) {
1943
- const norm = normalizeSample(raw);
1944
- if (norm && validateSample(norm)) {
1945
- norm.metadata = norm.metadata || {};
1946
- norm.metadata.source = "ai";
1947
- dataset.push(norm);
1948
- tracker.record(norm.domain);
1949
- callValid++;
1950
- newSamplesCount++;
1951
- } else { batchErrors++; }
1952
- }
1953
 
1954
- if (callValid > 0) {
1955
- saveDataset();
1956
- log(`Saved Call ${ci + 1}/${callsNeeded} (${callValid} samples). Total: ${dataset.length}`, "OK");
 
 
 
 
 
 
 
 
1957
  }
1958
- } catch (e) {
1959
- log(`Bedrock call ${ci + 1} failed: ${e.message}`, "ERROR");
1960
- batchErrors++;
1961
  }
1962
-
1963
- const elapsed = Date.now() - t0;
1964
- if (elapsed < minInterval) await new Promise(r => setTimeout(r, minInterval - elapsed));
1965
  }
1966
- log(`BACKGROUND PROCESS COMPLETE. New samples: ${newSamplesCount} | Errors: ${batchErrors}`, "HEAD");
1967
- })();
1968
- });
1969
 
1970
- app.get("/dataset/download", (req, res) => {
1971
- if (!fs.existsSync(DATASET_PATH)) {
1972
- return res.status(404).json({ error: "No dataset yet. Run /generate first." });
1973
- }
1974
- const dated = `axl_dataset_${new Date().toISOString().slice(0,19).replace(/[:T]/g,"-")}.json`;
1975
- res.download(DATASET_PATH, dated, (err) => {
1976
- if (err) log(`Download error: ${err.message}`, "ERROR");
1977
- else log(`Dataset downloaded as ${dated}`, "OK");
1978
- });
1979
- });
1980
-
1981
- app.post("/dataset/clear", (_, res) => {
1982
- const count = dataset.length;
1983
- dataset =[];
1984
- if (fs.existsSync(DATASET_PATH)) fs.unlinkSync(DATASET_PATH);
1985
- log(`Cleared ${count} samples`, "OK");
1986
- res.json({ cleared: count });
1987
- });
1988
 
1989
- app.get("/dataset/sample", (req, res) => {
1990
- const n = Math.min(parseInt(req.query.n||"5"), dataset.length);
1991
- const shuffled = [...dataset].sort(()=>Math.random()-0.5);
1992
- res.json({ samples: shuffled.slice(0,n) });
 
 
1993
  });
1994
 
1995
- // ── STARTUP ───────────────────────────────────────────────────────────────────
1996
- loadDataset();
1997
- app.listen(PORT, '0.0.0.0', () => {
1998
- log(`AXL Dataset Server listening on :${PORT}`, "OK");
1999
- log(`Model: ${BEDROCK_MODEL_ID}`);
2000
- log(`Dataset: ${DATASET_PATH}`);
2001
- log(`RPS: ${DEFAULT_RPS} default / ${MAX_RPS} max`);
2002
- });
 
1
+ import express from 'express';
2
+ import cors from 'cors';
3
+ import dotenv from 'dotenv';
4
+ import mongoose from 'mongoose';
5
+ import { BedrockRuntimeClient, ConverseStreamCommand } from "@aws-sdk/client-bedrock-runtime";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
  import { NodeHttpHandler } from "@smithy/node-http-handler";
7
+ import path from 'path';
8
+ import { fileURLToPath } from 'url';
9
 
10
+ dotenv.config();
11
+ const app = express();
12
+ const PORT = process.env.PORT || 7860;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
 
14
+ const __filename = fileURLToPath(import.meta.url);
15
+ const __dirname = path.dirname(__filename);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
 
17
+ app.use(cors());
18
+ app.use(express.json({ limit: '50mb' }));
19
+ app.use(express.static(path.join(__dirname, 'public'))); // Serve frontend
 
 
 
 
 
20
 
21
+ // --- SYSTEM PROMPT DEFINITIONS ---
22
+ const CLAUDE_SYSTEM_PROMPT = "You are a pro. Provide elite, high-level technical responses.";
 
 
 
 
 
 
23
 
24
+ // --- AI CLIENTS ---
25
+ const bedrockClient = new BedrockRuntimeClient({
26
+ region: "us-east-1",
27
+ requestHandler: new NodeHttpHandler({ http2Handler: undefined })
28
+ });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
 
30
+ function getBedrockModelId(modelName) {
31
+ switch(modelName) {
32
+ case "haiku": return "arn:aws:bedrock:us-east-1:106774395747:inference-profile/global.anthropic.claude-haiku-4-5-20251001-v1:0";
33
+ case "maverick": return "arn:aws:bedrock:us-east-1:106774395747:inference-profile/us.meta.llama4-maverick-17b-instruct-v1:0";
34
+ case "claude": default: return "arn:aws:bedrock:us-east-1:106774395747:inference-profile/global.anthropic.claude-sonnet-4-6";
 
 
 
 
 
 
 
 
 
 
 
 
 
35
  }
 
36
  }
37
 
38
+ // --- DB & MEMORY MANAGEMENT ---
39
+ const ChatSchema = new mongoose.Schema({
40
+ id: String,
41
+ title: String,
42
+ totalTokens: { type: Number, default: 0 },
43
+ messages: Array, // Array of { role, content, reasoning }
44
+ updatedAt: { type: Date, default: Date.now }
45
+ });
46
+ const Chat = mongoose.model('Chat', ChatSchema);
 
 
 
 
47
 
48
+ let memoryChats = {};
49
+ let dirtyChats = new Set(); // Track chats that need DB syncing
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
 
51
+ // Hydrate from DB on startup
52
+ async function initDB() {
53
+ try {
54
+ await mongoose.connect(process.env.MONGODB_URI);
55
+ console.log('✅ Connected to MongoDB');
56
+ const dbChats = await Chat.find();
57
+ dbChats.forEach(c => {
58
+ memoryChats[c.id] = { ...c.toObject(), isGenerating: false };
 
 
 
 
 
 
 
59
  });
60
+ console.log(`✅ Hydrated ${dbChats.length} chats from DB.`);
61
+
62
+ // Sync to DB every 15 seconds (occasional sync)
63
+ setInterval(async () => {
64
+ if (dirtyChats.size === 0) return;
65
+ const toSync = Array.from(dirtyChats);
66
+ dirtyChats.clear();
67
+ for (const id of toSync) {
68
+ if (memoryChats[id]) {
69
+ memoryChats[id].updatedAt = new Date();
70
+ await Chat.findOneAndUpdate({ id }, memoryChats[id], { upsert: true });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71
  }
72
+ }
73
+ console.log(`💾 Synced ${toSync.length} chats to MongoDB.`);
74
+ }, 15000);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
 
76
+ } catch (err) {
77
+ console.error('❌ MongoDB Connection Error:', err);
 
 
 
 
78
  }
79
  }
80
+ initDB();
 
 
 
81
 
82
+ // --- API ENDPOINTS FOR TOOL ---
83
 
84
+ // Get all chats (Sidebar)
85
+ app.get('/api/chats', (req, res) => {
86
+ const chatsList = Object.values(memoryChats).map(c => ({
87
+ id: c.id, title: c.title, totalTokens: c.totalTokens, updatedAt: c.updatedAt
88
+ })).sort((a, b) => new Date(b.updatedAt) - new Date(a.updatedAt));
89
+ res.json(chatsList);
90
  });
91
 
92
+ // Get specific chat details
93
+ app.get('/api/chats/:id', (req, res) => {
94
+ const chat = memoryChats[req.params.id];
95
+ if (!chat) return res.status(404).json({ error: "Chat not found" });
96
+ res.json(chat);
97
+ });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
98
 
99
+ // Create new chat
100
+ app.post('/api/chats', (req, res) => {
101
+ const newId = Date.now().toString();
102
+ memoryChats[newId] = {
103
+ id: newId,
104
+ title: "New Chat",
105
+ totalTokens: 0,
106
+ messages:[],
107
+ isGenerating: false,
108
+ updatedAt: new Date()
109
+ };
110
+ dirtyChats.add(newId);
111
+ res.json(memoryChats[newId]);
112
+ });
113
 
114
+ // Delete chat permanently
115
+ app.delete('/api/chats/:id', async (req, res) => {
116
+ const { id } = req.params;
117
+ delete memoryChats[id];
118
+ dirtyChats.delete(id);
119
+ await Chat.deleteOne({ id });
120
+ res.json({ success: true });
121
+ });
122
 
123
+ // Stream endpoint tied to Memory (AWS Bedrock Only)
124
+ app.post('/api/chats/:id/stream', async (req, res) => {
125
+ const { id } = req.params;
126
+ const { model, prompt, system_prompt, images } = req.body;
 
 
 
 
 
127
 
128
+ if (!memoryChats[id]) return res.status(404).send("Chat not found");
 
 
 
 
 
 
129
 
130
+ // Title generation on first message
131
+ if (memoryChats[id].messages.length === 0) {
132
+ memoryChats[id].title = prompt.substring(0, 30) + (prompt.length > 30 ? '...' : '');
 
 
 
 
 
133
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
134
 
135
+ // 1. SAVE TO MEMORY (Images excluded from storage to save DB space)
136
+ memoryChats[id].messages.push({ role: "user", content: prompt });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
137
 
138
+ const aiMessage = { role: "assistant", content: "", reasoning: "" };
139
+ memoryChats[id].messages.push(aiMessage);
140
+ memoryChats[id].isGenerating = true;
141
+ dirtyChats.add(id);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
142
 
143
+ // 2. SETUP STREAM HEADERS
144
+ res.setHeader('Content-Type', 'text/plain; charset=utf-8');
145
+ res.setHeader('Transfer-Encoding', 'chunked');
146
+ res.setHeader('X-Accel-Buffering', 'no');
147
+ res.flushHeaders();
 
 
148
 
149
+ let totalTokenCount = 0;
150
 
151
+ try {
152
+ const bedrockModelId = getBedrockModelId(model);
153
+ let contentBlock = [{ text: prompt }];
154
+
155
+ // Handle Base64 Image Injections
156
+ if (images && images.length > 0) {
157
+ const imageBlocks = images.map(imgStr => {
158
+ const base64Data = imgStr.replace(/^data:image\/\w+;base64,/, "");
159
+ return { image: { format: 'png', source: { bytes: Buffer.from(base64Data, 'base64') } } };
160
+ });
161
+ contentBlock = [...imageBlocks, ...contentBlock];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
162
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
163
 
164
+ // Map history for Bedrock (excluding the newly pushed user message which we manually constructed)
165
+ const historicalMessages = memoryChats[id].messages.slice(0, -2).map(m => ({
166
+ role: m.role, content:[{ text: m.content }]
167
+ }));
168
+
169
+ // Push the latest interaction payload
170
+ historicalMessages.push({ role: "user", content: contentBlock });
171
+
172
+ const command = new ConverseStreamCommand({
173
+ modelId: bedrockModelId,
174
+ system:[{ text: system_prompt || CLAUDE_SYSTEM_PROMPT }],
175
+ messages: historicalMessages,
176
+ inferenceConfig: { maxTokens: model.includes("haiku") ? 32000 : 4000, temperature: 1 },
177
+ additionalModelRequestFields: model.includes("claude") ? {
178
+ thinking: { type: "adaptive" }, output_config: { effort: "high" }
179
+ } : undefined
180
+ });
 
 
 
 
181
 
182
+ const response = await bedrockClient.send(command);
183
+
184
+ for await (const chunk of response.stream) {
185
+ if (chunk.contentBlockDelta) {
186
+ const delta = chunk.contentBlockDelta.delta;
187
+ if (delta.reasoningContent && delta.reasoningContent.text) {
188
+ aiMessage.reasoning += delta.reasoningContent.text;
189
+ res.write(`__THINK__${delta.reasoningContent.text}`);
190
+ } else if (delta.text) {
191
+ aiMessage.content += delta.text;
192
+ res.write(delta.text);
193
  }
 
 
 
194
  }
195
+ if (chunk.metadata && chunk.metadata.usage) {
196
+ totalTokenCount = (chunk.metadata.usage.inputTokens || 0) + (chunk.metadata.usage.outputTokens || 0);
197
+ }
198
  }
 
 
 
199
 
200
+ // Clean up & finalize memory
201
+ memoryChats[id].totalTokens += totalTokenCount;
202
+ memoryChats[id].isGenerating = false;
203
+ dirtyChats.add(id);
204
+
205
+ res.write(`__USAGE__${JSON.stringify({ totalTokenCount })}`);
206
+ res.end();
 
 
 
 
 
 
 
 
 
 
 
207
 
208
+ } catch (err) {
209
+ console.error(`❌ STREAM ERROR:`, err.message);
210
+ memoryChats[id].isGenerating = false;
211
+ res.write(`\n\n**ERROR**: ${err.message}`);
212
+ res.end();
213
+ }
214
  });
215
 
216
+ app.listen(PORT, '0.0.0.0', () => console.log(`🚀 AI Server live on http://localhost:${PORT}`));