@konneal/engine 0.1.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.
Files changed (285) hide show
  1. package/LICENSE +29 -0
  2. package/README.md +13 -0
  3. package/dist/admin.d.ts +26 -0
  4. package/dist/ai.d.ts +6 -0
  5. package/dist/anchors.d.ts +6 -0
  6. package/dist/answercache.d.ts +22 -0
  7. package/dist/ask.d.ts +5 -0
  8. package/dist/auth.d.ts +12 -0
  9. package/dist/bubble.d.ts +14 -0
  10. package/dist/chunk-LLWPT2XV.js +49 -0
  11. package/dist/chunk-MB74PTRM.js +114 -0
  12. package/dist/chunk-WOGQM7DJ.js +197 -0
  13. package/dist/chunk-WWNCWKKC.js +42 -0
  14. package/dist/completion.d.ts +5 -0
  15. package/dist/config.d.ts +154 -0
  16. package/dist/config.js +37 -0
  17. package/dist/context.d.ts +115 -0
  18. package/dist/conversations.d.ts +5 -0
  19. package/dist/drafts.d.ts +129 -0
  20. package/dist/env.d.ts +57 -0
  21. package/dist/faithfulness.d.ts +5 -0
  22. package/dist/grader.d.ts +3 -0
  23. package/dist/graph.d.ts +13 -0
  24. package/dist/hybrid.d.ts +7 -0
  25. package/dist/index.d.ts +9 -0
  26. package/dist/index.js +5373 -0
  27. package/dist/internal_gateway.d.ts +14 -0
  28. package/dist/lexical.d.ts +7 -0
  29. package/dist/livedata.d.ts +77 -0
  30. package/dist/memories.d.ts +10 -0
  31. package/dist/modelplane.d.ts +61 -0
  32. package/dist/oidc.d.ts +73 -0
  33. package/dist/pipeline.d.ts +57 -0
  34. package/dist/profile.d.ts +2 -0
  35. package/dist/profile.gen.d.ts +70 -0
  36. package/dist/profile.js +8 -0
  37. package/dist/projects.d.ts +8 -0
  38. package/dist/prompts/conversational.md +8 -0
  39. package/dist/prompts/enrichment.md +3 -0
  40. package/dist/prompts/faithfulness.md +1 -0
  41. package/dist/prompts/grader.md +5 -0
  42. package/dist/prompts/listwise.md +3 -0
  43. package/dist/prompts/precision.md +1 -0
  44. package/dist/prompts/reflect.md +1 -0
  45. package/dist/prompts/relevancy.md +1 -0
  46. package/dist/prompts/research.md +10 -0
  47. package/dist/prompts/section-summary.md +5 -0
  48. package/dist/prompts/summarize.md +1 -0
  49. package/dist/prompts/system.md +18 -0
  50. package/dist/prompts/understanding.md +17 -0
  51. package/dist/quota.d.ts +13 -0
  52. package/dist/reflect.d.ts +5 -0
  53. package/dist/refs.d.ts +40 -0
  54. package/dist/refusal.d.ts +9 -0
  55. package/dist/refusal.js +9 -0
  56. package/dist/requestScope.d.ts +26 -0
  57. package/dist/requestScope.js +10 -0
  58. package/dist/research.d.ts +8 -0
  59. package/dist/search.d.ts +4 -0
  60. package/dist/selfquery.d.ts +7 -0
  61. package/dist/session.d.ts +1 -0
  62. package/dist/share.d.ts +2 -0
  63. package/dist/structural.d.ts +27 -0
  64. package/dist/tablecontext.d.ts +11 -0
  65. package/dist/understand.d.ts +11 -0
  66. package/dist/understandContract.d.ts +29 -0
  67. package/dist/verdict.d.ts +24 -0
  68. package/docs/API.md +451 -0
  69. package/docs/ARCHITECTURE.md +302 -0
  70. package/docs/AUDIT-2026-08-24.md +71 -0
  71. package/docs/CONTRIBUTOR-AUDIT-2026-08-25.md +147 -0
  72. package/docs/INGEST-ARCHITECTURE.md +158 -0
  73. package/docs/MCP.md +92 -0
  74. package/docs/METANORMA-AI-SERIALIZATION.md +247 -0
  75. package/docs/MKO-EXPORT-PIPELINE.md +147 -0
  76. package/docs/REDESIGN-NORMATIVE-RAG-ETSI.md +485 -0
  77. package/docs/RESEARCH-SOTA-2026.md +243 -0
  78. package/docs/ROADMAP-SOTA.md +130 -0
  79. package/docs/SOTA-STAGE-SPECS.md +509 -0
  80. package/docs/annealment/F1-verdict.md +27 -0
  81. package/docs/annealment/F10-notes.md +19 -0
  82. package/docs/annealment/F11-composition.md +17 -0
  83. package/docs/annealment/F12-passport.md +17 -0
  84. package/docs/annealment/F2-counterfactual.md +20 -0
  85. package/docs/annealment/F3-absence.md +21 -0
  86. package/docs/annealment/F4-instance.md +18 -0
  87. package/docs/annealment/F5-workflow.md +21 -0
  88. package/docs/annealment/F6-impact.md +21 -0
  89. package/docs/annealment/F7-editions.md +18 -0
  90. package/docs/annealment/F8-selfverify.md +19 -0
  91. package/docs/annealment/F9-projection-qa.md +17 -0
  92. package/docs/annealment/L0-locate.md +19 -0
  93. package/docs/annealment/L1-extract.md +18 -0
  94. package/docs/annealment/L2-nomenclature.md +22 -0
  95. package/docs/annealment/L3-geometry.md +23 -0
  96. package/docs/annealment/L4-composition.md +21 -0
  97. package/docs/annealment/L5-cross-standard.md +20 -0
  98. package/docs/annealment/L6-diachrony.md +21 -0
  99. package/docs/annealment/L7-perception.md +20 -0
  100. package/docs/annealment/L8-computation.md +22 -0
  101. package/docs/annealment/L9-instance-process.md +23 -0
  102. package/docs/annealment/README.md +10 -0
  103. package/docs/guidelines-metanorma-ai-programme.md +279 -0
  104. package/docs/identity-onboarding-rag.md +65 -0
  105. package/docs/identity-service.md +219 -0
  106. package/docs/knowledge-annealment.md +273 -0
  107. package/docs/konneal-extraction-plan.md +481 -0
  108. package/docs/metanorma-for-ai.md +270 -0
  109. package/docs/mirror-plan.md +36 -0
  110. package/docs/multi-sdo-architecture.md +191 -0
  111. package/docs/paper-annealment-comparison.md +259 -0
  112. package/docs/paper-assets/architecture.svg +94 -0
  113. package/docs/paper-assets/contract-v2.svg +94 -0
  114. package/docs/paper-assets/mko-ingest.svg +91 -0
  115. package/docs/paper-oiml-bulletin.md +402 -0
  116. package/docs/paper-oiml-bulletin.mdx +419 -0
  117. package/docs/product-branding-options.md +172 -0
  118. package/docs/projects-design.md +88 -0
  119. package/docs/sota-mechanisms.md +184 -0
  120. package/docs/spec-api.md +77 -0
  121. package/docs/spec-pipeline.md +126 -0
  122. package/docs/vector-adapter.md +88 -0
  123. package/package.json +70 -0
  124. package/profile/corpora.yaml +5 -0
  125. package/profile/datasets.yaml +14 -0
  126. package/profile/prompts.yaml +5 -0
  127. package/profile/publisher.yaml +17 -0
  128. package/profile/retrieval.yaml +1 -0
  129. package/profile/sources.yaml +5 -0
  130. package/profile/ui.yaml +7 -0
  131. package/scripts/gen_profile.mjs +33 -0
  132. package/workers/shared/ai.ts +21 -0
  133. package/workers/shared/auth.ts +16 -0
  134. package/workers/shared/chunk.ts +108 -0
  135. package/workers/shared/oidc.ts +312 -0
  136. package/workers/shared/router.ts +45 -0
  137. package/workers/shared/session.ts +104 -0
  138. package/workers/worker_internal/src/index.ts +157 -0
  139. package/workers/worker_internal/tsconfig.json +15 -0
  140. package/workers/worker_internal/wrangler.toml +32 -0
  141. package/workers/worker_mcp/src/index.ts +175 -0
  142. package/workers/worker_mcp/tsconfig.json +13 -0
  143. package/workers/worker_mcp/wrangler.toml +18 -0
  144. package/workers/worker_public/migrations/0002_conversations.sql +22 -0
  145. package/workers/worker_public/migrations/0003_shared_conversations.sql +9 -0
  146. package/workers/worker_public/migrations/0004_graph.sql +16 -0
  147. package/workers/worker_public/migrations/0005_documents.sql +19 -0
  148. package/workers/worker_public/migrations/0006_conversation_entities.sql +11 -0
  149. package/workers/worker_public/migrations/0007_chunks_fts.sql +43 -0
  150. package/workers/worker_public/migrations/0008_unit_payloads.sql +15 -0
  151. package/workers/worker_public/migrations/0009_chunks_unit.sql +8 -0
  152. package/workers/worker_public/migrations/0009_message_context.sql +7 -0
  153. package/workers/worker_public/migrations/0010_model_nodes.sql +33 -0
  154. package/workers/worker_public/migrations/0011_schema_union.sql +38 -0
  155. package/workers/worker_public/migrations/0012_memories.sql +15 -0
  156. package/workers/worker_public/migrations/0013_projects.sql +21 -0
  157. package/workers/worker_public/node_modules/@cloudflare/workers-types/2021-11-03/index.d.ts +16306 -0
  158. package/workers/worker_public/node_modules/@cloudflare/workers-types/2021-11-03/index.ts +16261 -0
  159. package/workers/worker_public/node_modules/@cloudflare/workers-types/2022-01-31/index.d.ts +16373 -0
  160. package/workers/worker_public/node_modules/@cloudflare/workers-types/2022-01-31/index.ts +16328 -0
  161. package/workers/worker_public/node_modules/@cloudflare/workers-types/2022-03-21/index.d.ts +16382 -0
  162. package/workers/worker_public/node_modules/@cloudflare/workers-types/2022-03-21/index.ts +16337 -0
  163. package/workers/worker_public/node_modules/@cloudflare/workers-types/2022-08-04/index.d.ts +16383 -0
  164. package/workers/worker_public/node_modules/@cloudflare/workers-types/2022-08-04/index.ts +16338 -0
  165. package/workers/worker_public/node_modules/@cloudflare/workers-types/2022-10-31/index.d.ts +16403 -0
  166. package/workers/worker_public/node_modules/@cloudflare/workers-types/2022-10-31/index.ts +16358 -0
  167. package/workers/worker_public/node_modules/@cloudflare/workers-types/2022-11-30/index.d.ts +16408 -0
  168. package/workers/worker_public/node_modules/@cloudflare/workers-types/2022-11-30/index.ts +16363 -0
  169. package/workers/worker_public/node_modules/@cloudflare/workers-types/2023-03-01/index.d.ts +16414 -0
  170. package/workers/worker_public/node_modules/@cloudflare/workers-types/2023-03-01/index.ts +16369 -0
  171. package/workers/worker_public/node_modules/@cloudflare/workers-types/2023-07-01/index.d.ts +16414 -0
  172. package/workers/worker_public/node_modules/@cloudflare/workers-types/2023-07-01/index.ts +16369 -0
  173. package/workers/worker_public/node_modules/@cloudflare/workers-types/README.md +135 -0
  174. package/workers/worker_public/node_modules/@cloudflare/workers-types/entrypoints.svg +53 -0
  175. package/workers/worker_public/node_modules/@cloudflare/workers-types/experimental/index.d.ts +17095 -0
  176. package/workers/worker_public/node_modules/@cloudflare/workers-types/experimental/index.ts +17050 -0
  177. package/workers/worker_public/node_modules/@cloudflare/workers-types/index.d.ts +16306 -0
  178. package/workers/worker_public/node_modules/@cloudflare/workers-types/index.ts +16261 -0
  179. package/workers/worker_public/node_modules/@cloudflare/workers-types/latest/index.d.ts +16447 -0
  180. package/workers/worker_public/node_modules/@cloudflare/workers-types/latest/index.ts +16402 -0
  181. package/workers/worker_public/node_modules/@cloudflare/workers-types/oldest/index.d.ts +16306 -0
  182. package/workers/worker_public/node_modules/@cloudflare/workers-types/oldest/index.ts +16261 -0
  183. package/workers/worker_public/node_modules/@cloudflare/workers-types/package.json +11 -0
  184. package/workers/worker_public/package.json +13 -0
  185. package/workers/worker_public/prompts/conversational.md +8 -0
  186. package/workers/worker_public/prompts/enrichment.md +3 -0
  187. package/workers/worker_public/prompts/faithfulness.md +1 -0
  188. package/workers/worker_public/prompts/grader.md +5 -0
  189. package/workers/worker_public/prompts/listwise.md +3 -0
  190. package/workers/worker_public/prompts/precision.md +1 -0
  191. package/workers/worker_public/prompts/reflect.md +1 -0
  192. package/workers/worker_public/prompts/relevancy.md +1 -0
  193. package/workers/worker_public/prompts/research.md +10 -0
  194. package/workers/worker_public/prompts/section-summary.md +5 -0
  195. package/workers/worker_public/prompts/summarize.md +1 -0
  196. package/workers/worker_public/prompts/system.md +18 -0
  197. package/workers/worker_public/prompts/understanding.md +17 -0
  198. package/workers/worker_public/public/app.js +166 -0
  199. package/workers/worker_public/public/index.html +48 -0
  200. package/workers/worker_public/public/style.css +147 -0
  201. package/workers/worker_public/schema.sql +248 -0
  202. package/workers/worker_public/src/admin.ts +358 -0
  203. package/workers/worker_public/src/ai.ts +71 -0
  204. package/workers/worker_public/src/anchors.ts +41 -0
  205. package/workers/worker_public/src/answercache.ts +72 -0
  206. package/workers/worker_public/src/ask.ts +1094 -0
  207. package/workers/worker_public/src/auth.ts +252 -0
  208. package/workers/worker_public/src/bubble.ts +111 -0
  209. package/workers/worker_public/src/completion.ts +75 -0
  210. package/workers/worker_public/src/config.ts +238 -0
  211. package/workers/worker_public/src/context.ts +238 -0
  212. package/workers/worker_public/src/conversations.ts +162 -0
  213. package/workers/worker_public/src/drafts.ts +497 -0
  214. package/workers/worker_public/src/env.ts +90 -0
  215. package/workers/worker_public/src/faithfulness.ts +63 -0
  216. package/workers/worker_public/src/grader.ts +89 -0
  217. package/workers/worker_public/src/graph.ts +63 -0
  218. package/workers/worker_public/src/hybrid.ts +77 -0
  219. package/workers/worker_public/src/index.ts +441 -0
  220. package/workers/worker_public/src/internal_gateway.ts +41 -0
  221. package/workers/worker_public/src/lexical.ts +86 -0
  222. package/workers/worker_public/src/lib/hit.ts +4 -0
  223. package/workers/worker_public/src/lib/http.ts +83 -0
  224. package/workers/worker_public/src/lib/router.ts +4 -0
  225. package/workers/worker_public/src/livedata.ts +334 -0
  226. package/workers/worker_public/src/memories.ts +81 -0
  227. package/workers/worker_public/src/modelplane.ts +213 -0
  228. package/workers/worker_public/src/oidc.ts +333 -0
  229. package/workers/worker_public/src/pipeline.ts +377 -0
  230. package/workers/worker_public/src/ports/blobs.ts +7 -0
  231. package/workers/worker_public/src/ports/cloudflare/adapters.ts +177 -0
  232. package/workers/worker_public/src/ports/kv.ts +8 -0
  233. package/workers/worker_public/src/ports/model.ts +28 -0
  234. package/workers/worker_public/src/ports/runtime.ts +13 -0
  235. package/workers/worker_public/src/ports/store.ts +20 -0
  236. package/workers/worker_public/src/ports/vector.ts +26 -0
  237. package/workers/worker_public/src/profile.gen.ts +101 -0
  238. package/workers/worker_public/src/profile.ts +16 -0
  239. package/workers/worker_public/src/projects.ts +108 -0
  240. package/workers/worker_public/src/prompts.d.ts +6 -0
  241. package/workers/worker_public/src/quota.ts +54 -0
  242. package/workers/worker_public/src/reflect.ts +67 -0
  243. package/workers/worker_public/src/refs.ts +107 -0
  244. package/workers/worker_public/src/refusal.ts +65 -0
  245. package/workers/worker_public/src/requestScope.ts +71 -0
  246. package/workers/worker_public/src/research.ts +126 -0
  247. package/workers/worker_public/src/search.ts +56 -0
  248. package/workers/worker_public/src/selfquery.ts +25 -0
  249. package/workers/worker_public/src/session.ts +4 -0
  250. package/workers/worker_public/src/share.ts +53 -0
  251. package/workers/worker_public/src/stages/conceptGraph.ts +68 -0
  252. package/workers/worker_public/src/stages/conceptSteer.ts +39 -0
  253. package/workers/worker_public/src/stages/corpusScope.ts +25 -0
  254. package/workers/worker_public/src/stages/dedup.ts +10 -0
  255. package/workers/worker_public/src/stages/dense.ts +73 -0
  256. package/workers/worker_public/src/stages/diversity.ts +33 -0
  257. package/workers/worker_public/src/stages/editionCover.ts +63 -0
  258. package/workers/worker_public/src/stages/editionSteer.ts +88 -0
  259. package/workers/worker_public/src/stages/familyBoost.ts +22 -0
  260. package/workers/worker_public/src/stages/federate.ts +22 -0
  261. package/workers/worker_public/src/stages/glossary.ts +65 -0
  262. package/workers/worker_public/src/stages/graphLane.ts +31 -0
  263. package/workers/worker_public/src/stages/hyde.ts +29 -0
  264. package/workers/worker_public/src/stages/index.ts +69 -0
  265. package/workers/worker_public/src/stages/lexicalUnion.ts +21 -0
  266. package/workers/worker_public/src/stages/multiQuery.ts +57 -0
  267. package/workers/worker_public/src/stages/overviewDemote.ts +14 -0
  268. package/workers/worker_public/src/stages/poolOpen.ts +10 -0
  269. package/workers/worker_public/src/stages/propagate.ts +15 -0
  270. package/workers/worker_public/src/stages/rerank.ts +47 -0
  271. package/workers/worker_public/src/stages/seal.ts +16 -0
  272. package/workers/worker_public/src/stages/sectionDescent.ts +61 -0
  273. package/workers/worker_public/src/stages/stdRefNudge.ts +35 -0
  274. package/workers/worker_public/src/stages/subQuery.ts +42 -0
  275. package/workers/worker_public/src/stages/termNudge.ts +24 -0
  276. package/workers/worker_public/src/stages/typedPin.ts +131 -0
  277. package/workers/worker_public/src/stages/types.ts +112 -0
  278. package/workers/worker_public/src/stages/windowFloor.ts +23 -0
  279. package/workers/worker_public/src/structural.ts +171 -0
  280. package/workers/worker_public/src/tablecontext.ts +41 -0
  281. package/workers/worker_public/src/understand.ts +72 -0
  282. package/workers/worker_public/src/understandContract.ts +67 -0
  283. package/workers/worker_public/src/verdict.ts +255 -0
  284. package/workers/worker_public/tsconfig.json +18 -0
  285. package/workers/worker_public/wrangler.toml +104 -0
@@ -0,0 +1,255 @@
1
+ // The verdict engine (TODO.era3/01): deterministic evaluation of the
2
+ // model plane's machine-checkable objects — OCL boolean checks over
3
+ // dotted parameter paths and structured threshold limits. The worker
4
+ // computes; the model narrates. No eval, no network, linear parse.
5
+ //
6
+ // Verdict vocabulary: "pass" when every check holds; the node's own
7
+ // on_violation word ("invalid"/"void") when any fails; "void" plus the
8
+ // missing parameter names when the question does not state enough —
9
+ // honest degradation, never a guess.
10
+
11
+ export interface MachineCheck {
12
+ expression: string;
13
+ symbolic: string;
14
+ values: Record<string, number>;
15
+ result: boolean | null; // null: could not evaluate (missing params)
16
+ }
17
+
18
+ export interface Verdict {
19
+ verdict: "pass" | "fail" | "void";
20
+ on_violation?: string;
21
+ violation_meaning?: string;
22
+ missing: string[];
23
+ checks: MachineCheck[];
24
+ }
25
+
26
+ // ── a tiny safe expression parser ─────────────────────────────────────
27
+ // grammar: or := and ("or" and)* ; and := not (("and")? not)* [juxtaposition]
28
+ // not := "not" not | cmp ; cmp := add ((">="|"<="|">"|"<"|"=="|"!=") add)?
29
+ // add := mul (("+"|"-") mul)* ; mul := unary (("*"|"/") unary)*
30
+ // unary := "-" unary | atom ; atom := number | ident | "(" or ")"
31
+ type Tok = { t: "num"; v: number } | { t: "id"; v: string } | { t: "op"; v: string };
32
+
33
+ function tokenize(src: string): Tok[] {
34
+ const toks: Tok[] = [];
35
+ let i = 0;
36
+ const s = src.replace(/\s+/g, " ");
37
+ while (i < s.length) {
38
+ const c = s[i];
39
+ if (c === " ") { i++; continue; }
40
+ if (/[0-9.]/.test(c)) {
41
+ const m = s.slice(i).match(/^[0-9]*\.?[0-9]+/)!;
42
+ toks.push({ t: "num", v: Number(m[0]) });
43
+ i += m[0].length;
44
+ continue;
45
+ }
46
+ if (/[A-Za-z_]/.test(c)) {
47
+ const m = s.slice(i).match(/^[A-Za-z_][A-Za-z0-9_]*(?:\.[A-Za-z_][A-Za-z0-9_]*)*/)!;
48
+ toks.push({ t: "id", v: m[0] });
49
+ i += m[0].length;
50
+ continue;
51
+ }
52
+ const two = s.slice(i, i + 2);
53
+ if ([">=", "<=", "==", "!="].includes(two)) { toks.push({ t: "op", v: two }); i += 2; continue; }
54
+ if ("+-*/()<>".includes(c)) { toks.push({ t: "op", v: c }); i++; continue; }
55
+ throw new Error(`bad char ${c!}`);
56
+ }
57
+ return toks;
58
+ }
59
+
60
+ function parseAndEval(src: string, params: Record<string, number>): boolean | number {
61
+ const toks = tokenize(src);
62
+ let p = 0;
63
+ const peek = () => toks[p];
64
+ const eat = (v?: string) => { const t = toks[p++]; if (v && (!t || t.t !== "op" || t.v !== v)) throw new Error(`expected ${v}`); return t; };
65
+ const isKw = (k: string) => { const t = peek(); return t && t.t === "id" && t.v.toLowerCase() === k; };
66
+
67
+ function or(): boolean | number {
68
+ let l = and();
69
+ while (isKw("or")) { p++; const r = and(); l = truthy(l) || truthy(r); }
70
+ return l;
71
+ }
72
+ function and(): boolean | number {
73
+ let l = not();
74
+ while (isKw("and")) { p++; const r = not(); l = truthy(l) && truthy(r); }
75
+ return l;
76
+ }
77
+ function not(): boolean | number {
78
+ if (isKw("not")) { p++; return !truthy(not()); }
79
+ return cmp();
80
+ }
81
+ function cmp(): boolean | number {
82
+ const l = add();
83
+ const t = peek();
84
+ if (t && t.t === "op" && [">=", "<=", ">", "<", "==", "!="].includes(t.v)) {
85
+ p++;
86
+ const r = add();
87
+ switch (t.v) {
88
+ case ">=": return num(l) >= num(r);
89
+ case "<=": return num(l) <= num(r);
90
+ case ">": return num(l) > num(r);
91
+ case "<": return num(l) < num(r);
92
+ case "==": return num(l) === num(r);
93
+ default: return num(l) !== num(r);
94
+ }
95
+ }
96
+ return l;
97
+ }
98
+ function add(): boolean | number {
99
+ let l = mul();
100
+ for (;;) {
101
+ const t = peek();
102
+ if (t && t.t === "op" && (t.v === "+" || t.v === "-")) { p++; const r = mul(); l = t.v === "+" ? num(l) + num(r) : num(l) - num(r); }
103
+ else return l;
104
+ }
105
+ }
106
+ function mul(): boolean | number {
107
+ let l = unary();
108
+ for (;;) {
109
+ const t = peek();
110
+ if (t && t.t === "op" && (t.v === "*" || t.v === "/")) { p++; const r = unary(); l = t.v === "*" ? num(l) * num(r) : num(l) / num(r); }
111
+ else return l;
112
+ }
113
+ }
114
+ function unary(): boolean | number {
115
+ const t = peek();
116
+ if (t && t.t === "op" && t.v === "-") { p++; return -num(unary()); }
117
+ return atom();
118
+ }
119
+ function atom(): boolean | number {
120
+ const t = eat();
121
+ if (!t) throw new Error("unexpected end");
122
+ if (t.t === "num") return t.v;
123
+ if (t.t === "id") {
124
+ if (params[t.v] !== undefined) return params[t.v];
125
+ throw new Error(`missing ${t.v}`);
126
+ }
127
+ if (t.v === "(") { const v = or(); eat(")"); return v; }
128
+ throw new Error(`unexpected ${t.v}`);
129
+ }
130
+ const truthy = (v: boolean | number) => (typeof v === "boolean" ? v : v !== 0);
131
+ const num = (v: boolean | number) => (typeof v === "boolean" ? (v ? 1 : 0) : v);
132
+
133
+ const out = or();
134
+ if (p !== toks.length) throw new Error("trailing tokens");
135
+ return out;
136
+ }
137
+
138
+ // ── the node's machine checks ─────────────────────────────────────────
139
+
140
+ function oclBody(s: string): string | null {
141
+ const m = String(s ?? "").match(/ocl\{([\s\S]*?)\}/);
142
+ return m ? m[1]!.trim() : null;
143
+ }
144
+
145
+ export function extractChecks(content: unknown): string[] {
146
+ if (!content || typeof content !== "object") return [];
147
+ const c = content as Record<string, any>;
148
+ const out: string[] = [];
149
+ const push = (e?: string) => { const b = e && oclBody(e); if (b) out.push(b); };
150
+ push(c.check);
151
+ push(c.limit?.expression);
152
+ push(c.acceptance_criteria?.limit && !c.acceptance_criteria.limit.expression?.includes("ocl{") ? null : c.acceptance_criteria?.limit?.expression);
153
+ // structured threshold limits compile to a comparison expression
154
+ const st = c.acceptance_criteria?.limit;
155
+ if (st?.expression && st.operator && st.threshold_expression) {
156
+ out.push(`${st.expression} ${st.operator} ${st.threshold_expression}`);
157
+ }
158
+ return [...new Set(out)];
159
+ }
160
+
161
+ export function symbolsIn(checks: string[]): string[] {
162
+ const ids = new Set<string>();
163
+ const KEYWORDS = new Set(["and", "or", "not"]);
164
+ for (const chk of checks) {
165
+ try {
166
+ for (const t of tokenize(chk)) if (t.t === "id" && !KEYWORDS.has(t.v.toLowerCase())) ids.add(t.v);
167
+ } catch {
168
+ // unparseable check: no symbols extractable
169
+ }
170
+ }
171
+ return [...ids];
172
+ }
173
+
174
+ /** Grounded parameter extraction: the node's OWN symbols only. Each
175
+ * symbol's leaf (d_max) or full spelling (D_max) followed by a number
176
+ * in the question text binds the value. A closed symbol set from the
177
+ * model plane — meaning never comes from string matching. */
178
+ function parseNumber(raw: string): number {
179
+ // strip spaces/commas; a lone dot before exactly 3 final digits is a
180
+ // thousands separator (metrology magnitudes; decimals like 0.9 keep
181
+ // their meaning)
182
+ let s = raw.replace(/[ ,]/g, "");
183
+ s = s.replace(/\.(\d{3})$/, "$1");
184
+ return Number(s.replace(/,(?=\d{3}\b)/g, ""));
185
+ }
186
+
187
+ export function extractParams(query: string, symbols: string[]): Record<string, number> {
188
+ const params: Record<string, number> = {};
189
+ for (const sym of symbols) {
190
+ const leaf = sym.split(".").pop() ?? sym;
191
+ const esc = leaf.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
192
+ // symbol, a short non-numeric gap (words like "were"/"of" allowed),
193
+ // then the number
194
+ const re = new RegExp(`\\b${esc}\\b\\D{0,14}?([0-9][0-9 ,.]*[0-9])`, "iu");
195
+ const m = query.match(re);
196
+ if (m) {
197
+ const v = parseNumber(m[1]!);
198
+ if (Number.isFinite(v)) params[sym] = v;
199
+ }
200
+ }
201
+ return params;
202
+ }
203
+
204
+ export function evaluate(content: unknown, query: string): Verdict | null {
205
+ const c = (content && typeof content === "object" ? content : {}) as Record<string, any>;
206
+ const checks = extractChecks(content);
207
+ if (!checks.length) return null;
208
+ const symbols = symbolsIn(checks);
209
+ const params = extractParams(query, symbols);
210
+ const missing = symbols.filter((s) => params[s] === undefined);
211
+ const machine: MachineCheck[] = checks.map((expression) => {
212
+ const values: Record<string, number> = {};
213
+ try {
214
+ for (const t of tokenize(expression)) if (t.t === "id" && params[t.v] !== undefined) values[t.v] = params[t.v];
215
+ } catch { /* values stay partial */ }
216
+ let result: boolean | null = null;
217
+ if (missing.length === 0) {
218
+ try { result = !!parseAndEval(expression, params); } catch { result = null; }
219
+ }
220
+ return { expression, symbolic: expression, values, result };
221
+ });
222
+ if (missing.length) {
223
+ return { verdict: "void", missing, checks: machine };
224
+ }
225
+ const failed = machine.some((m) => m.result === false);
226
+ const evaluable = machine.some((m) => m.result !== null);
227
+ if (!evaluable) return null;
228
+ return {
229
+ verdict: failed ? "fail" : "pass",
230
+ on_violation: failed ? String(c.on_violation ?? "invalid") : undefined,
231
+ violation_meaning: failed ? (typeof c.violation_meaning === "string" ? c.violation_meaning : undefined) : undefined,
232
+ missing: [],
233
+ checks: machine,
234
+ };
235
+ }
236
+
237
+ /** The deterministic note the answer model narrates — never recomputes. */
238
+ export function verdictNote(v: Verdict, node: { node_id: string; clause?: { urn?: string } | null }): string {
239
+ const lines = [
240
+ `Machine verdict (deterministic evaluation of node ${node.node_id}${node.clause?.urn ? `, ${node.clause.urn}` : ""}) — the service EXECUTED the node's machine check against the values stated in the question:`,
241
+ ];
242
+ for (const c of v.checks) {
243
+ const vals = Object.entries(c.values).map(([k, n]) => `${k}=${n}`).join(", ");
244
+ lines.push(`- ${c.expression}${vals ? ` [${vals}]` : ""} → ${c.result === null ? "not evaluated" : c.result ? "holds" : "VIOLATED"}`);
245
+ }
246
+ if (v.verdict === "void") {
247
+ lines.push(`VERDICT: VOID — the question does not state: ${v.missing.join(", ")}. Say exactly what is missing; never assume values.`);
248
+ } else if (v.verdict === "pass") {
249
+ lines.push(`VERDICT: PASS — every machine check holds at the stated values. Present this verdict, the arithmetic above, and cite the node's clause.`);
250
+ } else {
251
+ lines.push(`VERDICT: ${String(v.on_violation ?? "FAIL").toUpperCase()} — a machine check is violated. Present this verdict, the arithmetic, the violation meaning verbatim, and cite the node's clause.`);
252
+ }
253
+ lines.push("This verdict is computed data — quote it faithfully; do not recompute, soften, or contradict it.");
254
+ return lines.join("\n");
255
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "ES2022",
5
+ "moduleResolution": "bundler",
6
+ "lib": ["ES2022"],
7
+ "types": ["@cloudflare/workers-types"],
8
+ "strict": true,
9
+ "noEmit": true,
10
+ "allowImportingTsExtensions": true,
11
+ "noUnusedLocals": true,
12
+ "noUnusedParameters": true,
13
+ "skipLibCheck": true,
14
+ "isolatedModules": true,
15
+ "forceConsistentCasingInFileNames": true
16
+ },
17
+ "include": ["src/**/*.ts"]
18
+ }
@@ -0,0 +1,104 @@
1
+ name = "rag-public"
2
+ main = "src/index.ts"
3
+ compatibility_date = "2026-08-01"
4
+ workers_dev = true
5
+
6
+ # Prompts are DATA (workers/worker_public/prompts/*.md), imported into the
7
+ # bundle as text — edited as content, never as code.
8
+ [[rules]]
9
+ type = "Text"
10
+ globs = ["**/*.md"]
11
+
12
+ # Route: custom domain on the oimlsmart.org zone (OIML SMART account).
13
+ routes = [
14
+ { pattern = "ai.oimlsmart.org", custom_domain = true }
15
+ ]
16
+
17
+
18
+ [assets]
19
+ directory = "../../site/dist"
20
+ binding = "ASSETS"
21
+ run_worker_first = ["/", "/api/"]
22
+
23
+ [ai]
24
+ binding = "AI"
25
+
26
+ # Figure/image assets for answer contract v2 (TODO.remaining/03) — served
27
+ # at /assets/u/<unit>.<ext> with immutable caching; keys are unit-keyed.
28
+ [[r2_buckets]]
29
+ binding = "UNIT_ASSETS"
30
+ bucket_name = "rag-public-assets"
31
+
32
+ [[vectorize]]
33
+ binding = "VECTORIZE"
34
+ index_name = "idx_oiml_public_v2"
35
+
36
+ # Comparison lanes (TODO.model-rag): the annealment experiment indexes
37
+ [[vectorize]]
38
+ binding = "EXP_PRIMMEL"
39
+ index_name = "idx_exp_primmel"
40
+
41
+ [[vectorize]]
42
+ binding = "EXP_COMPOSED"
43
+ index_name = "idx_exp_composed"
44
+
45
+ [[vectorize]]
46
+ binding = "EXP_PLAIN"
47
+ index_name = "idx_exp_plain"
48
+
49
+ [[vectorize]]
50
+ binding = "EXP_ADC"
51
+ index_name = "idx_exp_adoc"
52
+
53
+ [[vectorize]]
54
+ binding = "EXP_MKO"
55
+ index_name = "idx_exp_mko"
56
+
57
+ [[vectorize]]
58
+ binding = "EXP_PFLAT"
59
+ index_name = "idx_exp_primmel_flat"
60
+
61
+ # The vocabulary lane (L2 nomenclature bridge): defined terms + definitions
62
+ [[vectorize]]
63
+ binding = "GLOSSARY"
64
+ index_name = "idx_glossary"
65
+
66
+ [[d1_databases]]
67
+ binding = "EXP_DB"
68
+ database_name = "rag-comparison"
69
+ database_id = "85a1fa04-ef61-4a2d-8e85-23bbc0a3284d"
70
+
71
+ [[kv_namespaces]]
72
+ binding = "CACHE"
73
+ id = "0f65d12cc77c41b5b91086de1c04f6da"
74
+
75
+ [[d1_databases]]
76
+ binding = "DB"
77
+ database_name = "rag-public"
78
+ database_id = "655cd63f-1826-4161-bfd1-90c584add4ce"
79
+
80
+ # Service binding: rag-public delegates federated retrieval to rag-internal
81
+ # for users with internal roles. rag-public itself holds NO binding to the
82
+ # internal Vectorize index — isolation is structural (CLAUDE.md).
83
+ [[services]]
84
+ binding = "INTERNAL_SERVICE"
85
+ service = "rag-internal"
86
+
87
+ [vars]
88
+ INDEX_VERSION = "public-v2.103-citelabels"
89
+ ANON_DAY_ASK = "20"
90
+ ANON_DAY_SEARCH = "50"
91
+ KEY_DAY_ASK_DEFAULT = "2000"
92
+ ANON_DAY_HARD_CAP = "5000"
93
+ MEMBER_DAY_ASK = "300"
94
+ OIDC_ISSUER = "https://id.oimlsmart.org"
95
+ OIDC_REDIRECT_URI = "https://ai.oimlsmart.org/auth/callback"
96
+ OIDC_CLIENT_ID = "oiml-rag"
97
+ # TODO.ai-platform/03 — the "my account" live-data delegation: the platform
98
+ # the assistant reads AS the user (the RFC 8693 exchange's scope target).
99
+ # Absent/blank → the account chip answers live-unavailable honestly.
100
+ SMART_PLATFORM_API = "https://demo.oimlsmart.org"
101
+ SMART_PLATFORM_CLIENT_ID = "oiml-smart"
102
+
103
+ [observability]
104
+ enabled = true