@cavelang/cli 0.35.0 → 0.36.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 (327) hide show
  1. package/README.md +224 -12
  2. package/dist/internal/act/action.js +2 -1
  3. package/dist/internal/act/action.js.map +1 -1
  4. package/dist/internal/act/declare.d.ts.map +1 -1
  5. package/dist/internal/act/declare.js +82 -53
  6. package/dist/internal/act/declare.js.map +1 -1
  7. package/dist/internal/act/engine.d.ts +4 -3
  8. package/dist/internal/act/engine.d.ts.map +1 -1
  9. package/dist/internal/act/engine.js +121 -32
  10. package/dist/internal/act/engine.js.map +1 -1
  11. package/dist/internal/automate/cancellation.d.ts +3 -0
  12. package/dist/internal/automate/cancellation.d.ts.map +1 -0
  13. package/dist/internal/automate/cancellation.js +38 -0
  14. package/dist/internal/automate/cancellation.js.map +1 -0
  15. package/dist/internal/automate/declare.d.ts.map +1 -1
  16. package/dist/internal/automate/declare.js +49 -24
  17. package/dist/internal/automate/declare.js.map +1 -1
  18. package/dist/internal/automate/engine.d.ts +7 -3
  19. package/dist/internal/automate/engine.d.ts.map +1 -1
  20. package/dist/internal/automate/engine.js +196 -93
  21. package/dist/internal/automate/engine.js.map +1 -1
  22. package/dist/internal/automate/error-message.d.ts +3 -0
  23. package/dist/internal/automate/error-message.d.ts.map +1 -0
  24. package/dist/internal/automate/error-message.js +10 -0
  25. package/dist/internal/automate/error-message.js.map +1 -0
  26. package/dist/internal/automate/main.d.ts.map +1 -1
  27. package/dist/internal/automate/main.js +238 -35
  28. package/dist/internal/automate/main.js.map +1 -1
  29. package/dist/internal/automate/options.d.ts +4 -0
  30. package/dist/internal/automate/options.d.ts.map +1 -0
  31. package/dist/internal/automate/options.js +19 -0
  32. package/dist/internal/automate/options.js.map +1 -0
  33. package/dist/internal/connect/declared.d.ts +6 -27
  34. package/dist/internal/connect/declared.d.ts.map +1 -1
  35. package/dist/internal/connect/declared.js +165 -76
  36. package/dist/internal/connect/declared.js.map +1 -1
  37. package/dist/internal/connect/error-message.d.ts +3 -0
  38. package/dist/internal/connect/error-message.d.ts.map +1 -0
  39. package/dist/internal/connect/error-message.js +10 -0
  40. package/dist/internal/connect/error-message.js.map +1 -0
  41. package/dist/internal/connect/federation.d.ts +9 -0
  42. package/dist/internal/connect/federation.d.ts.map +1 -0
  43. package/dist/internal/connect/federation.js +19 -0
  44. package/dist/internal/connect/federation.js.map +1 -0
  45. package/dist/internal/connect/fetch-failure.d.ts +3 -0
  46. package/dist/internal/connect/fetch-failure.d.ts.map +1 -0
  47. package/dist/internal/connect/fetch-failure.js +36 -0
  48. package/dist/internal/connect/fetch-failure.js.map +1 -0
  49. package/dist/internal/connect/main.d.ts +1 -0
  50. package/dist/internal/connect/main.d.ts.map +1 -1
  51. package/dist/internal/connect/main.js +288 -114
  52. package/dist/internal/connect/main.js.map +1 -1
  53. package/dist/internal/connect/options.d.ts +3 -0
  54. package/dist/internal/connect/options.d.ts.map +1 -0
  55. package/dist/internal/connect/options.js +9 -0
  56. package/dist/internal/connect/options.js.map +1 -0
  57. package/dist/internal/connect/records.d.ts +3 -0
  58. package/dist/internal/connect/records.d.ts.map +1 -0
  59. package/dist/internal/connect/records.js +21 -0
  60. package/dist/internal/connect/records.js.map +1 -0
  61. package/dist/internal/connect/run.d.ts +1 -18
  62. package/dist/internal/connect/run.d.ts.map +1 -1
  63. package/dist/internal/connect/run.js +115 -55
  64. package/dist/internal/connect/run.js.map +1 -1
  65. package/dist/internal/connect/source.d.ts +3 -1
  66. package/dist/internal/connect/source.d.ts.map +1 -1
  67. package/dist/internal/connect/source.js +226 -47
  68. package/dist/internal/connect/source.js.map +1 -1
  69. package/dist/internal/connect/template.d.ts +2 -2
  70. package/dist/internal/connect/template.d.ts.map +1 -1
  71. package/dist/internal/connect/template.js +25 -9
  72. package/dist/internal/connect/template.js.map +1 -1
  73. package/dist/internal/connect/utf8.d.ts +3 -0
  74. package/dist/internal/connect/utf8.d.ts.map +1 -0
  75. package/dist/internal/connect/utf8.js +12 -0
  76. package/dist/internal/connect/utf8.js.map +1 -0
  77. package/dist/internal/eval/cleanup.d.ts +5 -0
  78. package/dist/internal/eval/cleanup.d.ts.map +1 -0
  79. package/dist/internal/eval/cleanup.js +50 -0
  80. package/dist/internal/eval/cleanup.js.map +1 -0
  81. package/dist/internal/eval/error-message.d.ts +3 -0
  82. package/dist/internal/eval/error-message.d.ts.map +1 -0
  83. package/dist/internal/eval/error-message.js +10 -0
  84. package/dist/internal/eval/error-message.js.map +1 -0
  85. package/dist/internal/eval/judge.d.ts.map +1 -1
  86. package/dist/internal/eval/judge.js +3 -31
  87. package/dist/internal/eval/judge.js.map +1 -1
  88. package/dist/internal/eval/loop.d.ts.map +1 -1
  89. package/dist/internal/eval/loop.js +18 -4
  90. package/dist/internal/eval/loop.js.map +1 -1
  91. package/dist/internal/eval/main.d.ts.map +1 -1
  92. package/dist/internal/eval/main.js +22 -10
  93. package/dist/internal/eval/main.js.map +1 -1
  94. package/dist/internal/eval/options.d.ts +6 -0
  95. package/dist/internal/eval/options.d.ts.map +1 -0
  96. package/dist/internal/eval/options.js +31 -0
  97. package/dist/internal/eval/options.js.map +1 -0
  98. package/dist/internal/eval/queries.d.ts.map +1 -1
  99. package/dist/internal/eval/queries.js +9 -6
  100. package/dist/internal/eval/queries.js.map +1 -1
  101. package/dist/internal/eval/run.d.ts.map +1 -1
  102. package/dist/internal/eval/run.js +112 -24
  103. package/dist/internal/eval/run.js.map +1 -1
  104. package/dist/internal/eval/score.d.ts.map +1 -1
  105. package/dist/internal/eval/score.js +9 -2
  106. package/dist/internal/eval/score.js.map +1 -1
  107. package/dist/internal/eval/suite.d.ts.map +1 -1
  108. package/dist/internal/eval/suite.js +14 -2
  109. package/dist/internal/eval/suite.js.map +1 -1
  110. package/dist/internal/ingest/cleanup.d.ts +5 -0
  111. package/dist/internal/ingest/cleanup.d.ts.map +1 -0
  112. package/dist/internal/ingest/cleanup.js +50 -0
  113. package/dist/internal/ingest/cleanup.js.map +1 -0
  114. package/dist/internal/ingest/content.d.ts +6 -0
  115. package/dist/internal/ingest/content.d.ts.map +1 -0
  116. package/dist/internal/ingest/content.js +25 -0
  117. package/dist/internal/ingest/content.js.map +1 -0
  118. package/dist/internal/ingest/context.d.ts.map +1 -1
  119. package/dist/internal/ingest/context.js +25 -7
  120. package/dist/internal/ingest/context.js.map +1 -1
  121. package/dist/internal/ingest/error-message.d.ts +3 -0
  122. package/dist/internal/ingest/error-message.d.ts.map +1 -0
  123. package/dist/internal/ingest/error-message.js +10 -0
  124. package/dist/internal/ingest/error-message.js.map +1 -0
  125. package/dist/internal/ingest/files.d.ts +4 -12
  126. package/dist/internal/ingest/files.d.ts.map +1 -1
  127. package/dist/internal/ingest/files.js +22 -10
  128. package/dist/internal/ingest/files.js.map +1 -1
  129. package/dist/internal/ingest/main.d.ts.map +1 -1
  130. package/dist/internal/ingest/main.js +46 -16
  131. package/dist/internal/ingest/main.js.map +1 -1
  132. package/dist/internal/ingest/options.d.ts +6 -0
  133. package/dist/internal/ingest/options.d.ts.map +1 -0
  134. package/dist/internal/ingest/options.js +27 -0
  135. package/dist/internal/ingest/options.js.map +1 -0
  136. package/dist/internal/ingest/prompt.d.ts.map +1 -1
  137. package/dist/internal/ingest/prompt.js +14 -10
  138. package/dist/internal/ingest/prompt.js.map +1 -1
  139. package/dist/internal/ingest/run.d.ts +9 -2
  140. package/dist/internal/ingest/run.d.ts.map +1 -1
  141. package/dist/internal/ingest/run.js +206 -62
  142. package/dist/internal/ingest/run.js.map +1 -1
  143. package/dist/internal/ingest/timeout.d.ts +3 -0
  144. package/dist/internal/ingest/timeout.d.ts.map +1 -0
  145. package/dist/internal/ingest/timeout.js +14 -0
  146. package/dist/internal/ingest/timeout.js.map +1 -0
  147. package/dist/internal/ingest/web.d.ts +2 -11
  148. package/dist/internal/ingest/web.d.ts.map +1 -1
  149. package/dist/internal/ingest/web.js +131 -25
  150. package/dist/internal/ingest/web.js.map +1 -1
  151. package/dist/internal/loop/budgets.d.ts +3 -0
  152. package/dist/internal/loop/budgets.d.ts.map +1 -0
  153. package/dist/internal/loop/budgets.js +10 -0
  154. package/dist/internal/loop/budgets.js.map +1 -0
  155. package/dist/internal/loop/index.d.ts +2 -0
  156. package/dist/internal/loop/index.d.ts.map +1 -1
  157. package/dist/internal/loop/index.js +2 -0
  158. package/dist/internal/loop/index.js.map +1 -1
  159. package/dist/internal/loop/json-answer.d.ts +7 -0
  160. package/dist/internal/loop/json-answer.d.ts.map +1 -0
  161. package/dist/internal/loop/json-answer.js +79 -0
  162. package/dist/internal/loop/json-answer.js.map +1 -0
  163. package/dist/internal/loop/json-spans.d.ts +3 -0
  164. package/dist/internal/loop/json-spans.d.ts.map +1 -0
  165. package/dist/internal/loop/json-spans.js +88 -0
  166. package/dist/internal/loop/json-spans.js.map +1 -0
  167. package/dist/internal/loop/llm.d.ts +3 -2
  168. package/dist/internal/loop/llm.d.ts.map +1 -1
  169. package/dist/internal/loop/llm.js +115 -32
  170. package/dist/internal/loop/llm.js.map +1 -1
  171. package/dist/internal/loop/process.d.ts +3 -1
  172. package/dist/internal/loop/process.d.ts.map +1 -1
  173. package/dist/internal/loop/process.js +159 -59
  174. package/dist/internal/loop/process.js.map +1 -1
  175. package/dist/internal/loop/read-snapshot.d.ts +4 -0
  176. package/dist/internal/loop/read-snapshot.d.ts.map +1 -0
  177. package/dist/internal/loop/read-snapshot.js +29 -0
  178. package/dist/internal/loop/read-snapshot.js.map +1 -0
  179. package/dist/internal/loop/reconstruct.d.ts +6 -5
  180. package/dist/internal/loop/reconstruct.d.ts.map +1 -1
  181. package/dist/internal/loop/reconstruct.js +19 -8
  182. package/dist/internal/loop/reconstruct.js.map +1 -1
  183. package/dist/internal/loop/score-settings.d.ts +5 -0
  184. package/dist/internal/loop/score-settings.d.ts.map +1 -0
  185. package/dist/internal/loop/score-settings.js +14 -0
  186. package/dist/internal/loop/score-settings.js.map +1 -0
  187. package/dist/internal/loop/sqlite.d.ts.map +1 -1
  188. package/dist/internal/loop/sqlite.js +15 -7
  189. package/dist/internal/loop/sqlite.js.map +1 -1
  190. package/dist/internal/loop/store.d.ts.map +1 -1
  191. package/dist/internal/loop/store.js +11 -7
  192. package/dist/internal/loop/store.js.map +1 -1
  193. package/dist/internal/loop/timeout.d.ts +3 -0
  194. package/dist/internal/loop/timeout.d.ts.map +1 -0
  195. package/dist/internal/loop/timeout.js +13 -0
  196. package/dist/internal/loop/timeout.js.map +1 -0
  197. package/dist/internal/mcp/error-message.d.ts +3 -0
  198. package/dist/internal/mcp/error-message.d.ts.map +1 -0
  199. package/dist/internal/mcp/error-message.js +10 -0
  200. package/dist/internal/mcp/error-message.js.map +1 -0
  201. package/dist/internal/mcp/main.d.ts.map +1 -1
  202. package/dist/internal/mcp/main.js +42 -27
  203. package/dist/internal/mcp/main.js.map +1 -1
  204. package/dist/internal/mcp/read-snapshot.d.ts +4 -0
  205. package/dist/internal/mcp/read-snapshot.d.ts.map +1 -0
  206. package/dist/internal/mcp/read-snapshot.js +22 -0
  207. package/dist/internal/mcp/read-snapshot.js.map +1 -0
  208. package/dist/internal/mcp/server.d.ts.map +1 -1
  209. package/dist/internal/mcp/server.js +181 -21
  210. package/dist/internal/mcp/server.js.map +1 -1
  211. package/dist/internal/mcp/source.d.ts +3 -0
  212. package/dist/internal/mcp/source.d.ts.map +1 -0
  213. package/dist/internal/mcp/source.js +13 -0
  214. package/dist/internal/mcp/source.js.map +1 -0
  215. package/dist/internal/mcp/tools.d.ts.map +1 -1
  216. package/dist/internal/mcp/tools.js +135 -72
  217. package/dist/internal/mcp/tools.js.map +1 -1
  218. package/dist/internal/rules/declarations.d.ts +6 -0
  219. package/dist/internal/rules/declarations.d.ts.map +1 -0
  220. package/dist/internal/rules/declarations.js +14 -0
  221. package/dist/internal/rules/declarations.js.map +1 -0
  222. package/dist/internal/rules/declare.d.ts.map +1 -1
  223. package/dist/internal/rules/declare.js +30 -16
  224. package/dist/internal/rules/declare.js.map +1 -1
  225. package/dist/internal/rules/engine.d.ts +8 -7
  226. package/dist/internal/rules/engine.d.ts.map +1 -1
  227. package/dist/internal/rules/engine.js +150 -44
  228. package/dist/internal/rules/engine.js.map +1 -1
  229. package/dist/internal/shape/alias-root.d.ts +3 -0
  230. package/dist/internal/shape/alias-root.d.ts.map +1 -0
  231. package/dist/internal/shape/alias-root.js +13 -0
  232. package/dist/internal/shape/alias-root.js.map +1 -0
  233. package/dist/internal/shape/check.d.ts +15 -3
  234. package/dist/internal/shape/check.d.ts.map +1 -1
  235. package/dist/internal/shape/check.js +230 -100
  236. package/dist/internal/shape/check.js.map +1 -1
  237. package/dist/internal/shape/client.d.ts.map +1 -1
  238. package/dist/internal/shape/client.js +42 -20
  239. package/dist/internal/shape/client.js.map +1 -1
  240. package/dist/internal/shape/constraints.d.ts +8 -0
  241. package/dist/internal/shape/constraints.d.ts.map +1 -0
  242. package/dist/internal/shape/constraints.js +17 -0
  243. package/dist/internal/shape/constraints.js.map +1 -0
  244. package/dist/internal/shape/edit-distance.d.ts +3 -0
  245. package/dist/internal/shape/edit-distance.d.ts.map +1 -0
  246. package/dist/internal/shape/edit-distance.js +33 -0
  247. package/dist/internal/shape/edit-distance.js.map +1 -0
  248. package/dist/internal/shape/gate.d.ts.map +1 -1
  249. package/dist/internal/shape/gate.js +0 -0
  250. package/dist/internal/shape/gate.js.map +1 -1
  251. package/dist/internal/shape/snapshot.d.ts +4 -0
  252. package/dist/internal/shape/snapshot.d.ts.map +1 -0
  253. package/dist/internal/shape/snapshot.js +20 -0
  254. package/dist/internal/shape/snapshot.js.map +1 -0
  255. package/dist/internal/shape/suggest.d.ts +8 -6
  256. package/dist/internal/shape/suggest.d.ts.map +1 -1
  257. package/dist/internal/shape/suggest.js +208 -92
  258. package/dist/internal/shape/suggest.js.map +1 -1
  259. package/dist/internal/sync/error-message.d.ts +3 -0
  260. package/dist/internal/sync/error-message.d.ts.map +1 -0
  261. package/dist/internal/sync/error-message.js +10 -0
  262. package/dist/internal/sync/error-message.js.map +1 -0
  263. package/dist/internal/sync/index.d.ts +3 -2
  264. package/dist/internal/sync/index.d.ts.map +1 -1
  265. package/dist/internal/sync/index.js +3 -2
  266. package/dist/internal/sync/index.js.map +1 -1
  267. package/dist/internal/sync/sync.d.ts +8 -5
  268. package/dist/internal/sync/sync.d.ts.map +1 -1
  269. package/dist/internal/sync/sync.js +322 -65
  270. package/dist/internal/sync/sync.js.map +1 -1
  271. package/dist/internal/view/api.d.ts +3 -1
  272. package/dist/internal/view/api.d.ts.map +1 -1
  273. package/dist/internal/view/api.js +154 -90
  274. package/dist/internal/view/api.js.map +1 -1
  275. package/dist/internal/view/error-message.d.ts +3 -0
  276. package/dist/internal/view/error-message.d.ts.map +1 -0
  277. package/dist/internal/view/error-message.js +10 -0
  278. package/dist/internal/view/error-message.js.map +1 -0
  279. package/dist/internal/view/main.d.ts.map +1 -1
  280. package/dist/internal/view/main.js +61 -8
  281. package/dist/internal/view/main.js.map +1 -1
  282. package/dist/internal/view/page.d.ts.map +1 -1
  283. package/dist/internal/view/page.js +119 -20
  284. package/dist/internal/view/page.js.map +1 -1
  285. package/dist/internal/view/report.d.ts.map +1 -1
  286. package/dist/internal/view/report.js +180 -145
  287. package/dist/internal/view/report.js.map +1 -1
  288. package/dist/internal/view/scope.d.ts +6 -2
  289. package/dist/internal/view/scope.d.ts.map +1 -1
  290. package/dist/internal/view/scope.js +107 -24
  291. package/dist/internal/view/scope.js.map +1 -1
  292. package/dist/internal/view/sensitivity.d.ts +4 -0
  293. package/dist/internal/view/sensitivity.d.ts.map +1 -0
  294. package/dist/internal/view/sensitivity.js +11 -0
  295. package/dist/internal/view/sensitivity.js.map +1 -0
  296. package/dist/internal/view/server.d.ts.map +1 -1
  297. package/dist/internal/view/server.js +57 -20
  298. package/dist/internal/view/server.js.map +1 -1
  299. package/dist/src/atomic-output.d.ts +3 -0
  300. package/dist/src/atomic-output.d.ts.map +1 -0
  301. package/dist/src/atomic-output.js +67 -0
  302. package/dist/src/atomic-output.js.map +1 -0
  303. package/dist/src/cli.d.ts +3 -2
  304. package/dist/src/cli.d.ts.map +1 -1
  305. package/dist/src/cli.js +188 -173
  306. package/dist/src/cli.js.map +1 -1
  307. package/dist/src/dispatch.d.ts.map +1 -1
  308. package/dist/src/dispatch.js +3 -2
  309. package/dist/src/dispatch.js.map +1 -1
  310. package/dist/src/doctor.d.ts.map +1 -1
  311. package/dist/src/doctor.js +178 -102
  312. package/dist/src/doctor.js.map +1 -1
  313. package/dist/src/error-message.d.ts +3 -0
  314. package/dist/src/error-message.d.ts.map +1 -0
  315. package/dist/src/error-message.js +20 -0
  316. package/dist/src/error-message.js.map +1 -0
  317. package/dist/src/hooks-config.d.ts +3 -0
  318. package/dist/src/hooks-config.d.ts.map +1 -0
  319. package/dist/src/hooks-config.js +23 -0
  320. package/dist/src/hooks-config.js.map +1 -0
  321. package/package.json +23 -20
  322. package/src/atomic-output.ts +47 -0
  323. package/src/cli.ts +170 -147
  324. package/src/dispatch.ts +3 -2
  325. package/src/doctor.ts +192 -111
  326. package/src/error-message.ts +13 -0
  327. package/src/hooks-config.ts +22 -0
@@ -11,8 +11,10 @@
11
11
  * prelude) appends nothing.
12
12
  */
13
13
  import { Claim, Key, Value } from '@cavelang/core';
14
+ import { canonicalizeText } from '@cavelang/canonical';
14
15
  import { Row } from '@cavelang/store';
15
16
  import * as Rule from "./rule.js";
17
+ import { currentDeclarations, declarationText } from "./declarations.js";
16
18
  import { provenanceContext, ruleAttribute, ruleSubject } from "./engine.js";
17
19
  /** Subject of the prelude digest bookkeeping claim. */
18
20
  const preludeSubject = 'derive/prelude';
@@ -33,6 +35,7 @@ export const declareRules = (store, text) => {
33
35
  const problems = [];
34
36
  const rules = [];
35
37
  const preludeLines = [];
38
+ const preludeSourceLines = [];
36
39
  const ruleLines = [];
37
40
  text.split(/\r?\n/).forEach((line, index) => {
38
41
  if (Rule.isRuleLine(line)) {
@@ -40,17 +43,27 @@ export const declareRules = (store, text) => {
40
43
  }
41
44
  else {
42
45
  preludeLines.push(line);
46
+ preludeSourceLines.push(index + 1);
43
47
  }
44
48
  });
45
49
  return store.transaction(() => {
50
+ store.registry();
46
51
  let prelude = 0;
47
52
  const preludeText = preludeLines.join('\n');
48
53
  if (preludeText.trim() !== '') {
54
+ // Validate even cached input: older versions cached failed preludes too.
55
+ const canonical = canonicalizeText(preludeText, store.registry());
56
+ if (canonical.problems.length > 0) {
57
+ for (const problem of canonical.problems)
58
+ problems.push({
59
+ ...problem, line: preludeSourceLines[problem.line - 1] ?? problem.line
60
+ });
61
+ return { declared: 0, unchanged: 0, prelude: 0, rules, problems };
62
+ }
49
63
  const digest = Rule.digestOf(preludeText);
50
64
  const known = store.currentBelief(declarationKey(preludeSubject, preludeDigestAttribute));
51
65
  if (known === undefined || known.conf <= 0 || known.value_text !== digest) {
52
- const result = store.ingest(preludeText, { source: 'cave-derive' });
53
- problems.push(...result.problems);
66
+ const result = store.insertResult(canonical, { source: 'cave-derive' });
54
67
  prelude = result.ids.length;
55
68
  store.ingest(`${preludeSubject} HAS ${preludeDigestAttribute}: ${digest} @${provenanceContext}`);
56
69
  }
@@ -60,7 +73,8 @@ export const declareRules = (store, text) => {
60
73
  for (const { line, at } of ruleLines) {
61
74
  const parsed = Rule.parse(line);
62
75
  if (!parsed.ok) {
63
- problems.push(...parsed.problems.map(message => ({ line: at, message })));
76
+ for (const message of parsed.problems)
77
+ problems.push({ line: at, message });
64
78
  continue;
65
79
  }
66
80
  const rule = parsed.rule;
@@ -85,10 +99,10 @@ export const declareRules = (store, text) => {
85
99
  });
86
100
  };
87
101
  /** Current positive rules of a store, in declaration order. */
88
- export const listRules = (store) => store.currentBeliefs()
89
- .filter(row => row.verb === 'HAS' && row.attribute === ruleAttribute && row.negated === 0 && row.conf > 0 && row.value_text !== null)
102
+ export const listRules = (store) => currentDeclarations(store, ruleAttribute)
103
+ .filter(row => row.value_text !== null)
90
104
  .map(row => {
91
- const text = Row.parseValue(row.value_text).raw;
105
+ const text = declarationText(row);
92
106
  const parsed = Rule.parse(text);
93
107
  const label = (parsed.ok ? parsed.rule.label : undefined) ?? row.comment ?? undefined;
94
108
  return {
@@ -105,17 +119,17 @@ export const listRules = (store) => store.currentBeliefs()
105
119
  * justification does not outlive its rule.
106
120
  */
107
121
  export const retractRule = (store, ref) => {
108
- const declarations = store.currentBeliefs().filter(row => row.verb === 'HAS' && row.attribute === ruleAttribute && row.negated === 0 && row.conf > 0);
109
- const matches = declarations.filter(row => row.subject === ref || row.subject === ruleSubject(ref) ||
110
- (ref.length >= 4 && row.subject.startsWith(ruleSubject(ref))));
111
- const subjects = [...new Set(matches.map(row => row.subject))];
112
- if (subjects.length === 0) {
113
- return { ok: false, error: `no current rule matches ${JSON.stringify(ref)}` };
114
- }
115
- if (subjects.length > 1) {
116
- return { ok: false, error: `${JSON.stringify(ref)} is ambiguous — matches ${subjects.join(', ')}` };
117
- }
118
122
  return store.transaction(() => {
123
+ const declarations = currentDeclarations(store, ruleAttribute);
124
+ const matches = declarations.filter(row => row.subject === ref || row.subject === ruleSubject(ref) ||
125
+ (ref.length >= 4 && row.subject.startsWith(ruleSubject(ref))));
126
+ const subjects = [...new Set(matches.map(row => row.subject))];
127
+ if (subjects.length === 0) {
128
+ return { ok: false, error: `no current rule matches ${JSON.stringify(ref)}` };
129
+ }
130
+ if (subjects.length > 1) {
131
+ return { ok: false, error: `${JSON.stringify(ref)} is ambiguous — matches ${subjects.join(', ')}` };
132
+ }
119
133
  let derived = 0;
120
134
  for (const declaration of matches) {
121
135
  store.insertResult({
@@ -1 +1 @@
1
- {"version":3,"file":"declare.js","sourceRoot":"","sources":["../../src/declare.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAA;AAClD,OAAO,EAAE,GAAG,EAAc,MAAM,iBAAiB,CAAA;AACjD,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AACjC,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAE3E,uDAAuD;AACvD,MAAM,cAAc,GAAG,gBAAgB,CAAA;AAEvC,MAAM,sBAAsB,GAAG,eAAe,CAAA;AAE9C,MAAM,mBAAmB,GAAG,CAAC,iBAAiB,CAAC,CAAA;AAE/C,MAAM,cAAc,GAAG,CAAC,OAAe,EAAE,SAAiB,EAAU,EAAE,CACpE,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC;IACd,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC;IAC9B,IAAI,EAAE,KAAK;IACX,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACrD,QAAQ,EAAE,mBAAmB;CAC9B,CAAC,CAAC,CAAA;AAaL;;;;GAIG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,KAAY,EAAE,IAAY,EAAe,EAAE;IACtE,MAAM,QAAQ,GAAwC,EAAE,CAAA;IACxD,MAAM,KAAK,GAAa,EAAE,CAAA;IAC1B,MAAM,YAAY,GAAa,EAAE,CAAA;IACjC,MAAM,SAAS,GAAmC,EAAE,CAAA;IACpD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;QAC1C,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1B,SAAS,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,GAAG,CAAC,EAAE,CAAC,CAAA;QACzC,CAAC;aAAM,CAAC;YACN,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACzB,CAAC;IACH,CAAC,CAAC,CAAA;IAEF,OAAO,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE;QAC5B,IAAI,OAAO,GAAG,CAAC,CAAA;QACf,MAAM,WAAW,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAC3C,IAAI,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YAC9B,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAA;YACzC,MAAM,KAAK,GAAG,KAAK,CAAC,aAAa,CAAC,cAAc,CAAC,cAAc,EAAE,sBAAsB,CAAC,CAAC,CAAA;YACzF,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC,UAAU,KAAK,MAAM,EAAE,CAAC;gBAC1E,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC,CAAA;gBACnE,QAAQ,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAA;gBACjC,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,CAAA;gBAC3B,KAAK,CAAC,MAAM,CAAC,GAAG,cAAc,QAAQ,sBAAsB,KAAK,MAAM,KAAK,iBAAiB,EAAE,CAAC,CAAA;YAClG,CAAC;QACH,CAAC;QAED,IAAI,QAAQ,GAAG,CAAC,CAAA;QAChB,IAAI,SAAS,GAAG,CAAC,CAAA;QACjB,KAAK,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,SAAS,EAAE,CAAC;YACrC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;YAC/B,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;gBACf,QAAQ,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,CAAA;gBACzE,SAAQ;YACV,CAAC;YACD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAA;YACxB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YAChB,MAAM,OAAO,GACX,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC;gBAC/C,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;oBAC7C,SAAS,CAAA;YACX,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;gBAC1B,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,EAAE,iEAAiE,EAAE,CAAC,CAAA;gBACvG,SAAQ;YACV,CAAC;YACD,MAAM,KAAK,GAAG,KAAK,CAAC,aAAa,CAAC,cAAc,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,aAAa,CAAC,CAAC,CAAA;YAC1F,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,IAAI,GAAG,CAAC,IAAI,KAAK,CAAC,UAAU,KAAK,OAAO,EAAE,CAAC;gBAC1E,SAAS,IAAI,CAAC,CAAA;gBACd,SAAQ;YACV,CAAC;YACD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,KAAK,EAAE,CAAA;YAChE,KAAK,CAAC,MAAM,CAAC,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,aAAa,KAAK,OAAO,KAAK,iBAAiB,GAAG,KAAK,EAAE,CAAC,CAAA;YAC1G,QAAQ,IAAI,CAAC,CAAA;QACf,CAAC;QACD,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAA;IAC1D,CAAC,CAAC,CAAA;AACJ,CAAC,CAAA;AAWD,+DAA+D;AAC/D,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,KAAY,EAAgB,EAAE,CACtD,KAAK,CAAC,cAAc,EAAE;KACnB,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,KAAK,IAAI,GAAG,CAAC,SAAS,KAAK,aAAa,IAAI,GAAG,CAAC,OAAO,KAAK,CAAC,IAAI,GAAG,CAAC,IAAI,GAAG,CAAC,IAAI,GAAG,CAAC,UAAU,KAAK,IAAI,CAAC;KACpI,GAAG,CAAC,GAAG,CAAC,EAAE;IACT,MAAM,IAAI,GAAG,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,UAAW,CAAC,CAAC,GAAG,CAAA;IAChD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IAC/B,MAAM,KAAK,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,GAAG,CAAC,OAAO,IAAI,SAAS,CAAA;IACrF,OAAO;QACL,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,IAAI;QACJ,GAAG,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE;QACvC,EAAE,EAAE,MAAM,CAAC,EAAE;QACb,QAAQ,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ;KAC3C,CAAA;AACH,CAAC,CAAC,CAAA;AAMN;;;;GAIG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,KAAY,EAAE,GAAW,EAAc,EAAE;IACnE,MAAM,YAAY,GAAG,KAAK,CAAC,cAAc,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CACvD,GAAG,CAAC,IAAI,KAAK,KAAK,IAAI,GAAG,CAAC,SAAS,KAAK,aAAa,IAAI,GAAG,CAAC,OAAO,KAAK,CAAC,IAAI,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,CAAA;IAC7F,MAAM,OAAO,GAAG,YAAY,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CACxC,GAAG,CAAC,OAAO,KAAK,GAAG,IAAI,GAAG,CAAC,OAAO,KAAK,WAAW,CAAC,GAAG,CAAC;QACvD,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;IAChE,MAAM,QAAQ,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;IAC9D,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,2BAA2B,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,EAAE,CAAA;IAC/E,CAAC;IACD,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,2BAA2B,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAA;IACrG,CAAC;IACD,OAAO,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE;QAC5B,IAAI,OAAO,GAAG,CAAC,CAAA;QACf,KAAK,MAAM,WAAW,IAAI,OAAO,EAAE,CAAC;YAClC,KAAK,CAAC,YAAY,CAAC;gBACjB,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,kCAAkC,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;gBAC9H,KAAK,EAAE,EAAE;gBACT,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE;gBAC1B,QAAQ,EAAE,EAAE;aACb,CAAC,CAAA;YACF,MAAM,IAAI,GAAG,KAAK,CAAC,YAAY,CAAC,KAAK,EAAE,WAAW,CAAC,OAAO,CAAC,CAAA;YAC3D,MAAM,MAAM,GAAG,IAAI,GAAG,EAAiB,CAAA;YACvC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;gBACvB,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;gBACtC,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,EAAE,GAAG,GAAG,CAAC,EAAE,EAAE,CAAC;oBAC3C,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,CAAA;gBAChC,CAAC;YACH,CAAC;YACD,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;gBAClC,IAAI,GAAG,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,SAAS,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY;oBACrE,CAAC,GAAG,CAAC,IAAI,KAAK,IAAI,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC;oBAClD,SAAQ;gBACV,CAAC;gBACD,KAAK,CAAC,YAAY,CAAC;oBACjB,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,2BAA2B,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;oBAC/G,KAAK,EAAE,EAAE;oBACT,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE;oBAC1B,QAAQ,EAAE,EAAE;iBACb,CAAC,CAAA;gBACF,OAAO,IAAI,CAAC,CAAA;YACd,CAAC;QACH,CAAC;QACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAA;IACxC,CAAC,CAAC,CAAA;AACJ,CAAC,CAAA"}
1
+ {"version":3,"file":"declare.js","sourceRoot":"","sources":["../../src/declare.ts"],"names":[],"mappings":"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"}
@@ -22,8 +22,8 @@
22
22
  * declaration row (§24.3);
23
23
  * - re-runs are idempotent — a conclusion equal to current belief appends
24
24
  * nothing — and incremental by per-rule tx watermark claims: a rule
25
- * re-fires only when rows recorded since its watermark could extend a
26
- * premise match, and a watermark predating the rule's current
25
+ * re-fires when newer rows could change a premise match or the active
26
+ * vocabulary/evaluation-policy fingerprint differs. A watermark predating the rule's current
27
27
  * declaration row is stale — a re-declared rule fires from scratch
28
28
  * (§24.4);
29
29
  * - support is recomputed on every firing: previously-derived claims the
@@ -67,16 +67,17 @@ export type RuleOutcome = {
67
67
  readonly label?: string;
68
68
  /** `false` when every pass skipped the rule — watermark said nothing new. */
69
69
  fired: boolean;
70
+ /** Attempted evaluations, including evaluations in rolled-back reconciliation. */
70
71
  evaluations: number;
71
- /** Solutions of the rule's final evaluation. */
72
+ /** Solutions of the rule's final attempted evaluation. */
72
73
  solutions: number;
73
- /** Conclusions asserted for the first time (or re-asserted after retraction). */
74
+ /** Retained first assertions (or re-assertions); excludes rolled-back reconciliation. */
74
75
  appended: number;
75
- /** Conclusions whose confidence or value changed — belief updates. */
76
+ /** Retained confidence/value updates; excludes rolled-back reconciliation. */
76
77
  updated: number;
77
- /** Idempotent skips — conclusion equals current belief (§24.4). */
78
+ /** Attempted idempotent skips, including during rolled-back reconciliation (§24.4). */
78
79
  unchanged: number;
79
- /** Previously-derived claims retracted — premises no longer hold (§24.5). */
80
+ /** Retained retractions for lost support; excludes rolled-back reconciliation (§24.5). */
80
81
  retracted: number;
81
82
  readonly problems: string[];
82
83
  };
@@ -1 +1 @@
1
- {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/engine.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/engine.ts"],"names":[],"mappings":"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"}
@@ -22,8 +22,8 @@
22
22
  * declaration row (§24.3);
23
23
  * - re-runs are idempotent — a conclusion equal to current belief appends
24
24
  * nothing — and incremental by per-rule tx watermark claims: a rule
25
- * re-fires only when rows recorded since its watermark could extend a
26
- * premise match, and a watermark predating the rule's current
25
+ * re-fires when newer rows could change a premise match or the active
26
+ * vocabulary/evaluation-policy fingerprint differs. A watermark predating the rule's current
27
27
  * declaration row is stale — a re-declared rule fires from scratch
28
28
  * (§24.4);
29
29
  * - support is recomputed on every firing: previously-derived claims the
@@ -33,16 +33,19 @@
33
33
  * retracts the whole dependent chain, mutually-supporting cycles
34
34
  * included (§24.5).
35
35
  */
36
- import { Claim, Confidence, Context, Key, Value, Verb } from '@cavelang/core';
36
+ import { createHash } from 'node:crypto';
37
+ import { Claim, Context, Key, Value, Verb } from '@cavelang/core';
37
38
  import * as Canonical from '@cavelang/canonical';
38
39
  import { noisyAndIndependent } from '@cavelang/fusion';
39
40
  import { Row } from '@cavelang/store';
40
41
  import { match } from '@cavelang/query';
41
42
  import * as Rule from "./rule.js";
43
+ import { currentDeclarations, declarationText } from "./declarations.js";
42
44
  /** Attribute of rule declaration claims: `rule/<digest> HAS rule: …`. */
43
45
  export const ruleAttribute = 'rule';
44
46
  /** Attribute of per-rule watermark claims (§24.4). */
45
47
  export const watermarkAttribute = 'derive-watermark';
48
+ const vocabularyAttribute = 'derive-vocabulary';
46
49
  /** Source context stamped on declarations and bookkeeping (like `src:cave-connect`). */
47
50
  export const provenanceContext = 'src:cave-derive';
48
51
  /** Declaration subject of a rule: its digest under the `rule/` scope. */
@@ -64,6 +67,21 @@ const bookkeepingKey = (subject, attribute) => Key.of(Claim.of({
64
67
  contexts: [provenanceContext]
65
68
  }));
66
69
  const maxTx = (store) => store.db.prepare('SELECT MAX(tx) AS t FROM cave_claim').get().t ?? undefined;
70
+ // Registry values are immutable. Cache per identity, but hash sorted semantic
71
+ // contents so reopening or replaying an equivalent registry retains the mark.
72
+ const vocabularyCache = new WeakMap();
73
+ const vocabularyOf = (store) => {
74
+ const registry = store.registry();
75
+ const cached = vocabularyCache.get(registry);
76
+ if (cached !== undefined)
77
+ return cached;
78
+ const pairs = [...registry.pairs].map(([name, pair]) => [name, pair.primary, pair.inverse]).sort();
79
+ const text = JSON.stringify([pairs, [...registry.declared].sort(),
80
+ [...registry.storage].sort(), [...registry.preferred].sort(), [...registry.renames].sort()]);
81
+ const fingerprint = `v1-${createHash('sha256').update(text).digest('hex')}`;
82
+ vocabularyCache.set(registry, fingerprint);
83
+ return fingerprint;
84
+ };
67
85
  /** Latest row per claim key among `rows` — the series current beliefs. */
68
86
  const latestPerKey = (rows) => {
69
87
  const latest = new Map();
@@ -93,9 +111,9 @@ const loadRules = (store) => {
93
111
  const problems = [];
94
112
  const notes = [];
95
113
  const byDigest = new Map();
96
- const declarations = store.currentBeliefs().filter(row => row.verb === 'HAS' && row.attribute === ruleAttribute && row.negated === 0 && row.conf > 0 && row.value_text !== null);
114
+ const declarations = currentDeclarations(store, ruleAttribute).filter(row => row.value_text !== null);
97
115
  for (const row of declarations) {
98
- const text = Row.parseValue(row.value_text).raw;
116
+ const text = declarationText(row);
99
117
  const parsed = Rule.parse(text);
100
118
  if (!parsed.ok) {
101
119
  problems.push({ subject: row.subject, problems: parsed.problems });
@@ -132,7 +150,7 @@ const loadRules = (store) => {
132
150
  /**
133
151
  * Could a row recorded after `mark` extend a match of one of the rule's
134
152
  * premises? A *shape* test — subject/verb/object/attribute/negated plus
135
- * context and tag membership; confidence and currency are ignored, so a
153
+ * context membership; mutable values, tags and confidence are ignored, so a
136
154
  * retraction row re-fires the rules its claim used to feed (§24.5).
137
155
  * Over-matching costs a harmless re-evaluation; under-matching would be a
138
156
  * correctness bug — under `aliases`, entity terms are dropped from the
@@ -140,6 +158,12 @@ const loadRules = (store) => {
140
158
  * fires too.
141
159
  */
142
160
  const shapeMatchesSince = (store, rule, mark, aliases) => {
161
+ // A new mapping can make old facts match a different premise direction.
162
+ // Their fact timestamps do not move, so ordinary shape probes miss it.
163
+ if (store.db.prepare(`SELECT 1 FROM cave_claim
164
+ WHERE tx > ? AND (verb IN ('REVERSE', 'RENAMED-TO') OR (verb = 'IS' AND object = 'verb'))
165
+ LIMIT 1`).get(mark) !== undefined)
166
+ return true;
143
167
  const registry = store.registry();
144
168
  for (const premise of rule.premises) {
145
169
  if (premise.kind !== 'pattern') {
@@ -178,33 +202,32 @@ const shapeMatchesSince = (store, rule, mark, aliases) => {
178
202
  params.push(subjectSlot.text);
179
203
  }
180
204
  if (objectSlot?.kind === 'term' && !aliases) {
181
- // A date/number object also matches metric rows (value in value_text).
182
- conditions.push('(c.object = ? OR c.value_text = ?)');
183
- params.push(objectSlot.text, objectSlot.text);
205
+ // Metric values share a claim key across changes. A replacement that
206
+ // stops matching must still wake the rule to retract its conclusions.
207
+ conditions.push('(c.object = ? OR c.object IS NULL)');
208
+ params.push(objectSlot.text);
184
209
  }
185
210
  if (premise.pattern.payload.kind === 'attribute') {
186
211
  conditions.push('c.attribute = ?');
187
212
  params.push(premise.pattern.payload.attribute);
188
- if (premise.pattern.payload.value.kind === 'term') {
189
- conditions.push('c.value_text = ?');
190
- params.push(premise.pattern.payload.value.text);
191
- }
213
+ // Attribute values are mutable within a series. Do not restrict the
214
+ // wake-up probe to either their spelling or their normalized value.
192
215
  }
193
216
  }
194
- for (const context of premise.pattern.contexts) {
195
- conditions.push('EXISTS (SELECT 1 FROM cave_context x WHERE x.claim_id = c.id AND x.context = ?)');
196
- params.push(context);
197
- }
198
- for (const tag of premise.pattern.tags) {
199
- if (tag.value === undefined) {
200
- conditions.push('EXISTS (SELECT 1 FROM cave_tag t WHERE t.claim_id = c.id AND t.key = ? AND t.value IS NULL)');
201
- params.push(tag.key);
202
- }
203
- else {
204
- conditions.push('EXISTS (SELECT 1 FROM cave_tag t WHERE t.claim_id = c.id AND t.key = ? AND t.value = ?)');
205
- params.push(tag.key, tag.value);
217
+ if (premise.pattern.contexts.length <= 16) {
218
+ for (const context of premise.pattern.contexts) {
219
+ conditions.push('EXISTS (SELECT 1 FROM cave_context x WHERE x.claim_id = c.id AND x.context = ?)');
220
+ params.push(context);
206
221
  }
207
222
  }
223
+ else {
224
+ conditions.push(`NOT EXISTS (SELECT 1 FROM json_each(?) required
225
+ WHERE NOT EXISTS (SELECT 1 FROM cave_context x
226
+ WHERE x.claim_id = c.id AND x.context = required.value))`);
227
+ params.push(JSON.stringify(premise.pattern.contexts));
228
+ }
229
+ // Tags are metadata, not identity: removing a required tag can invalidate
230
+ // prior conclusions just as adding it can enable a new match.
208
231
  const row = store.db.prepare(`SELECT 1 AS hit FROM cave_claim c WHERE ${conditions.join(' AND ')} LIMIT 1`)
209
232
  .get(...params);
210
233
  if (row !== undefined) {
@@ -228,11 +251,11 @@ const shapeMatchesSince = (store, rule, mark, aliases) => {
228
251
  * no row can match.
229
252
  */
230
253
  export const specialize = (pattern, bindings) => {
231
- const slot = (candidate) => candidate.kind === 'var' && bindings[candidate.name] !== undefined ?
254
+ const slot = (candidate) => candidate.kind === 'var' && Object.hasOwn(bindings, candidate.name) && bindings[candidate.name] !== undefined ?
232
255
  { kind: 'term', text: bindings[candidate.name] } :
233
256
  candidate;
234
257
  let verb = pattern.verb;
235
- if (verb.kind === 'var' && bindings[verb.name] !== undefined) {
258
+ if (verb.kind === 'var' && Object.hasOwn(bindings, verb.name) && bindings[verb.name] !== undefined) {
236
259
  const name = bindings[verb.name];
237
260
  if (!Verb.isVerbToken(name)) {
238
261
  return undefined;
@@ -318,7 +341,7 @@ const conclude = (rule, solution, registry) => {
318
341
  else if (payload.kind === 'metric' && payload.value.kind === 'atom' && payload.value.raw.startsWith('?')) {
319
342
  payload = Claim.metric(Row.parseValue(solution.bindings[payload.value.raw.slice(1)]));
320
343
  }
321
- const conf = Confidence.parse(Confidence.format(noisyAndIndependent(rule.conf, solution.rows.map(row => row.conf))));
344
+ const conf = noisyAndIndependent(rule.conf, solution.rows.map(row => row.conf));
322
345
  const draft = Claim.of({
323
346
  subject: term(template.subject, 'subject'),
324
347
  verb: template.verb,
@@ -352,9 +375,37 @@ const rollback = Symbol('cave-derive dry run');
352
375
  * transaction.
353
376
  */
354
377
  export const derive = (store, options = {}) => {
378
+ const suppliedMinConf = options.minConf;
379
+ const minConf = suppliedMinConf === undefined ? defaultMinConf : suppliedMinConf;
380
+ if (!Number.isFinite(minConf) || minConf < 0 || minConf > 1) {
381
+ throw new Error('minConf must be finite and in 0..1');
382
+ }
383
+ const suppliedMaxPasses = options.maxPasses;
384
+ const maxPasses = suppliedMaxPasses === undefined ? defaultMaxPasses : suppliedMaxPasses;
385
+ if (!Number.isSafeInteger(maxPasses) || maxPasses < 1) {
386
+ throw new Error('maxPasses must be a positive safe integer');
387
+ }
388
+ options = { minConf, maxPasses, full: options.full, dryRun: options.dryRun, aliases: options.aliases };
389
+ for (const key of ['full', 'dryRun', 'aliases']) {
390
+ if (options[key] !== undefined && typeof options[key] !== 'boolean') {
391
+ throw new Error(`${key} must be a boolean`);
392
+ }
393
+ }
394
+ return store.transaction(() => {
395
+ store.registry();
396
+ return deriveLocked(store, options);
397
+ });
398
+ };
399
+ /** Read declarations and watermarks only after reserving the write transaction. */
400
+ const deriveLocked = (store, options) => {
355
401
  const minConf = options.minConf ?? defaultMinConf;
356
402
  const maxPasses = options.maxPasses ?? defaultMaxPasses;
357
403
  const aliases = options.aliases === true;
404
+ // The persisted vocabulary companion also identifies the evaluation policy:
405
+ // unchanged rows can gain or lose support when these options change.
406
+ // v3 re-evaluates conclusions formerly rounded to two percentage decimals.
407
+ const evaluationFingerprint = () => 'v3-' + createHash('sha256')
408
+ .update(JSON.stringify([vocabularyOf(store), aliases, minConf])).digest('hex');
358
409
  const { loaded, problems, notes } = loadRules(store);
359
410
  let passes = 0;
360
411
  const supported = new Set();
@@ -364,6 +415,8 @@ export const derive = (store, options = {}) => {
364
415
  /** Per-rule scan mark: rows at or before it are fully accounted for. */
365
416
  const marks = new Map();
366
417
  const storedMarks = new Map();
418
+ const vocabularies = new Map();
419
+ const storedVocabularies = new Map();
367
420
  let complete = true;
368
421
  for (const { rule, row } of loaded) {
369
422
  const watermark = store.currentBelief(bookkeepingKey(ruleSubject(rule.digest), watermarkAttribute));
@@ -376,6 +429,11 @@ export const derive = (store, options = {}) => {
376
429
  const stored = watermark !== undefined && watermark.conf > 0 && watermark.tx > row.tx ?
377
430
  watermark.value_text ?? undefined :
378
431
  undefined;
432
+ const vocabulary = store.currentBelief(bookkeepingKey(ruleSubject(rule.digest), vocabularyAttribute));
433
+ const storedVocabulary = vocabulary !== undefined && vocabulary.conf > 0 && vocabulary.tx > row.tx
434
+ ? vocabulary.value_text ?? undefined : undefined;
435
+ storedVocabularies.set(rule.digest, storedVocabulary);
436
+ vocabularies.set(rule.digest, storedVocabulary);
379
437
  storedMarks.set(rule.digest, stored);
380
438
  marks.set(rule.digest, options.full === true ? undefined : stored);
381
439
  }
@@ -440,18 +498,17 @@ export const derive = (store, options = {}) => {
440
498
  }
441
499
  const current = store.currentBelief(conclusion.key);
442
500
  const columns = Row.toColumns(conclusion.claim);
443
- if (current !== undefined && current.conf > 0 &&
444
- Math.abs(current.conf - conclusion.conf) < 1e-9 && current.value_text === columns.valueText) {
501
+ if (current !== undefined && current.conf === conclusion.conf && current.value_text === columns.valueText) {
445
502
  outcome.unchanged += 1;
446
503
  continue;
447
504
  }
448
- const inserted = store.insertResult({ claims: [{ claim: conclusion.claim, line: 0 }], edges: [], registry: store.registry(), problems: [] }, { source: ruleSubject(rule.digest), lifecycle: true });
449
- // `conclude` returns the claim rather than its one-line registry
450
- // result. Replay all stored declarations after a generated vocabulary
451
- // claim so later rules and fixpoint passes see it immediately.
452
- if (isDeclarationClaim(conclusion.claim)) {
453
- store.reloadRegistry();
454
- }
505
+ const registry = store.registry();
506
+ // Extend the current registry, not the snapshot used to construct a
507
+ // batch of conclusions. Canonicalization preserves first-declaration-
508
+ // wins behavior for competing declarations from that batch.
509
+ const nextRegistry = isDeclarationClaim(conclusion.claim) ?
510
+ Canonical.canonicalizeText(Canonical.emitClaim(conclusion.claim), registry).registry : registry;
511
+ const inserted = store.insertResult({ claims: [{ claim: conclusion.claim, line: 0 }], edges: [], registry: nextRegistry, problems: [] }, { source: ruleSubject(rule.digest), lifecycle: true });
455
512
  const id = inserted.ids[0];
456
513
  const premiseIds = [...new Set(conclusion.rows.map(premiseRow => premiseRow.id))];
457
514
  store.appendEdges([
@@ -468,23 +525,30 @@ export const derive = (store, options = {}) => {
468
525
  }
469
526
  return progress;
470
527
  };
471
- const run = () => {
528
+ let reconciling = false;
529
+ const incompleteReconciliation = Symbol('cave-derive incomplete reconciliation');
530
+ const run = (resumeRetraction = false) => {
472
531
  const truncate = () => {
473
532
  complete = false;
474
533
  notes.push(`stopped at ${maxPasses} passes before reaching a fixpoint — no unsupported conclusions were retracted and no watermarks were advanced; re-run to continue, or raise maxPasses`);
475
534
  };
476
535
  for (;;) {
477
536
  // Pass loop: evaluate until no rule writes or extends support.
478
- let quiescent = false;
537
+ // The single recursive entry resumes at the first retraction under a
538
+ // savepoint; it must not repeat evaluation or charge an extra pass.
539
+ let quiescent = resumeRetraction;
540
+ resumeRetraction = false;
479
541
  while (!quiescent && passes < maxPasses) {
480
542
  passes += 1;
481
543
  let progress = false;
482
544
  for (const entry of loaded) {
483
545
  const mark = marks.get(entry.rule.digest);
484
- const now = maxTx(store);
485
- if (mark !== undefined && !shapeMatchesSince(store, entry.rule, mark, aliases)) {
546
+ const vocabulary = evaluationFingerprint();
547
+ if (mark !== undefined && vocabularies.get(entry.rule.digest) === vocabulary &&
548
+ !shapeMatchesSince(store, entry.rule, mark, aliases)) {
486
549
  continue;
487
550
  }
551
+ const now = maxTx(store);
488
552
  if (!fired.has(entry.rule.digest)) {
489
553
  fired.add(entry.rule.digest);
490
554
  entry.outcome.fired = true;
@@ -494,6 +558,19 @@ export const derive = (store, options = {}) => {
494
558
  progress = true;
495
559
  }
496
560
  marks.set(entry.rule.digest, now);
561
+ vocabularies.set(entry.rule.digest, vocabulary);
562
+ if (evaluationFingerprint() !== vocabulary) {
563
+ // A proof established under the old mapping is no longer valid.
564
+ // Re-suspend all current derivations on the next bounded pass,
565
+ // including conclusions written earlier in this invocation.
566
+ supported.clear();
567
+ suspended.clear();
568
+ fired.clear();
569
+ marks.clear();
570
+ vocabularies.clear();
571
+ progress = true;
572
+ break;
573
+ }
497
574
  }
498
575
  quiescent = !progress;
499
576
  }
@@ -504,6 +581,32 @@ export const derive = (store, options = {}) => {
504
581
  truncate();
505
582
  return;
506
583
  }
584
+ if (!reconciling) {
585
+ if (![...suspended.values()].some(({ row }) => !supported.has(row.claim_key)))
586
+ return;
587
+ // Keep additions from initial evaluation, but commit destructive support
588
+ // reconciliation only if all subsequent evaluation/retraction settles.
589
+ // The recursive call enters this savepoint once, regardless of depth
590
+ // of the dependency chain; subsequent passes use the ordinary loop.
591
+ const counts = loaded.map(({ outcome }) => ({
592
+ appended: outcome.appended, updated: outcome.updated, retracted: outcome.retracted
593
+ }));
594
+ reconciling = true;
595
+ try {
596
+ store.transaction(() => {
597
+ run(true);
598
+ if (!complete)
599
+ throw incompleteReconciliation;
600
+ });
601
+ }
602
+ catch (error) {
603
+ if (error !== incompleteReconciliation)
604
+ throw error;
605
+ for (let i = 0; i < loaded.length; i++)
606
+ Object.assign(loaded[i].outcome, counts[i]);
607
+ }
608
+ return;
609
+ }
507
610
  // Retraction phase (§24.5): suspended rows never re-supported lost
508
611
  // their premises. Retraction rows are ordinary appends — the loop
509
612
  // re-enters so dependent rules see them and cascade.
@@ -534,10 +637,13 @@ export const derive = (store, options = {}) => {
534
637
  continue;
535
638
  }
536
639
  const mark = marks.get(entry.rule.digest);
537
- if (mark === undefined || mark === storedMarks.get(entry.rule.digest)) {
538
- continue;
640
+ if (mark !== undefined && mark !== storedMarks.get(entry.rule.digest)) {
641
+ store.ingest(`${ruleSubject(entry.rule.digest)} HAS ${watermarkAttribute}: ${mark} @${provenanceContext}`);
642
+ }
643
+ const vocabulary = vocabularies.get(entry.rule.digest);
644
+ if (vocabulary !== undefined && vocabulary !== storedVocabularies.get(entry.rule.digest)) {
645
+ store.ingest(`${ruleSubject(entry.rule.digest)} HAS ${vocabularyAttribute}: ${vocabulary} @${provenanceContext}`);
539
646
  }
540
- store.ingest(`${ruleSubject(entry.rule.digest)} HAS ${watermarkAttribute}: ${mark} @${provenanceContext}`);
541
647
  }
542
648
  };
543
649
  if (options.dryRun === true) {