@knights-eye-chess/ai-analysis 0.0.0-stage → 0.1.0-dev.17

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 (258) hide show
  1. package/LICENSE +235 -0
  2. package/LICENSING.md +26 -0
  3. package/NOTICE +5 -0
  4. package/NPM-PUBLISHING.md +28 -0
  5. package/README.md +139 -2
  6. package/SOURCE-ORIGIN.json +16 -0
  7. package/THIRD_PARTY_NOTICES.md +18 -0
  8. package/build.mjs +22 -0
  9. package/dist/answer-pipeline.test.mjs +375 -0
  10. package/dist/chunk-PLKNJRPF.js +10662 -0
  11. package/dist/chunk-XQDZJOYD.js +2515 -0
  12. package/dist/index.js +146 -0
  13. package/dist/owner-tests/chess-reasoning-compact-search-preparation.test.mjs +963 -0
  14. package/dist/owner-tests/mechanism-encoding.test.mjs +529 -0
  15. package/dist/owner-tests/move-mechanism-facts.test.mjs +396 -0
  16. package/dist/owner-tests/pipeline-host-preparation.test.mjs +10556 -0
  17. package/dist/owner-tests/position-preparation.test.mjs +625 -0
  18. package/dist/owner-tests/preparation-consolidation.test.mjs +1052 -0
  19. package/dist/owner-tests/prose-reference-admission.test.mjs +1770 -0
  20. package/dist/owner-tests/score-comparison-notices.test.mjs +240 -0
  21. package/dist/owner-tests/simple-engine-presentation.test.mjs +233 -0
  22. package/dist/owner-tests/tool-input-loop-guard.test.mjs +78 -0
  23. package/dist/research.js +2274 -0
  24. package/dist/runtime-closure.json +103 -0
  25. package/dist/shared-runtime-closure.json +39 -0
  26. package/dist/shared.js +152 -0
  27. package/dist/types/ai-request-failure.d.ts +14 -0
  28. package/dist/types/ai-request-limits.d.ts +4 -0
  29. package/dist/types/ai-routing-diagnostics.d.ts +14 -0
  30. package/dist/types/chess-reasoning/ablation-adaptive-evidence-loop.d.ts +127 -0
  31. package/dist/types/chess-reasoning/ablation-adaptive-runtime.d.ts +178 -0
  32. package/dist/types/chess-reasoning/ablation-direct-synthesis.d.ts +1030 -0
  33. package/dist/types/chess-reasoning/ablation-evidence-bundle.d.ts +185 -0
  34. package/dist/types/chess-reasoning/ablation-evidence-capture.d.ts +37 -0
  35. package/dist/types/chess-reasoning/ablation-lean-direct-runtime.d.ts +193 -0
  36. package/dist/types/chess-reasoning/ablation-model-facing-evidence.d.ts +38 -0
  37. package/dist/types/chess-reasoning/ablation-transport-correction.d.ts +13 -0
  38. package/dist/types/chess-reasoning/ai-sdk-runtime-support.d.ts +93 -0
  39. package/dist/types/chess-reasoning/answer-host-contracts.d.ts +59 -0
  40. package/dist/types/chess-reasoning/answer-model-connector.d.ts +68 -0
  41. package/dist/types/chess-reasoning/answer-pipeline-exports.d.ts +98 -0
  42. package/dist/types/chess-reasoning/answer-pipeline.d.ts +41 -0
  43. package/dist/types/chess-reasoning/answer-reference-validation.d.ts +40 -0
  44. package/dist/types/chess-reasoning/answer-tool-host.d.ts +8 -0
  45. package/dist/types/chess-reasoning/branch-expansion-policy.d.ts +13 -0
  46. package/dist/types/chess-reasoning/branch-expansion.d.ts +39 -0
  47. package/dist/types/chess-reasoning/causal-claim-checks.d.ts +21 -0
  48. package/dist/types/chess-reasoning/chess-reference-dictionary.d.ts +13 -0
  49. package/dist/types/chess-reasoning/classification-question-target.d.ts +22 -0
  50. package/dist/types/chess-reasoning/classification-reassessment.d.ts +31 -0
  51. package/dist/types/chess-reasoning/compact-search-preparation.d.ts +7 -0
  52. package/dist/types/chess-reasoning/concept-registry.d.ts +99 -0
  53. package/dist/types/chess-reasoning/conversation-context.d.ts +12 -0
  54. package/dist/types/chess-reasoning/engine-search-failure.d.ts +7 -0
  55. package/dist/types/chess-reasoning/evidence-citation-normalization.d.ts +9 -0
  56. package/dist/types/chess-reasoning/evidence-licenses.d.ts +57 -0
  57. package/dist/types/chess-reasoning/evidence-selector-contract.d.ts +5 -0
  58. package/dist/types/chess-reasoning/existing-analysis-context.d.ts +104 -0
  59. package/dist/types/chess-reasoning/fact-observation-provider.d.ts +15 -0
  60. package/dist/types/chess-reasoning/fact-provider.d.ts +111 -0
  61. package/dist/types/chess-reasoning/fresh-engine-pv-witnesses.d.ts +67 -0
  62. package/dist/types/chess-reasoning/historical-prose.d.ts +23 -0
  63. package/dist/types/chess-reasoning/idea-graph.d.ts +34 -0
  64. package/dist/types/chess-reasoning/initial-search-plan.d.ts +37 -0
  65. package/dist/types/chess-reasoning/lossless-evidence-sharing.d.ts +18 -0
  66. package/dist/types/chess-reasoning/matched-comparison.d.ts +10 -0
  67. package/dist/types/chess-reasoning/material-accounting.d.ts +80 -0
  68. package/dist/types/chess-reasoning/material-format.d.ts +4 -0
  69. package/dist/types/chess-reasoning/mechanical-fact-provider.d.ts +33 -0
  70. package/dist/types/chess-reasoning/mechanical-ray-facts.d.ts +19 -0
  71. package/dist/types/chess-reasoning/mechanism-presentation.d.ts +9 -0
  72. package/dist/types/chess-reasoning/move-mechanism-facts.d.ts +45 -0
  73. package/dist/types/chess-reasoning/native-answer-connector.d.ts +4 -0
  74. package/dist/types/chess-reasoning/opening-source-contracts.d.ts +54 -0
  75. package/dist/types/chess-reasoning/opening-source-credits.d.ts +16 -0
  76. package/dist/types/chess-reasoning/opponent-threat-preparation.d.ts +7 -0
  77. package/dist/types/chess-reasoning/piece-identities.d.ts +11 -0
  78. package/dist/types/chess-reasoning/poc-contracts.d.ts +1026 -0
  79. package/dist/types/chess-reasoning/poc-hypotheses.d.ts +74 -0
  80. package/dist/types/chess-reasoning/poc-move-witnesses.d.ts +13 -0
  81. package/dist/types/chess-reasoning/poc-observations.d.ts +23 -0
  82. package/dist/types/chess-reasoning/poc-piece-refs.d.ts +12 -0
  83. package/dist/types/chess-reasoning/poc-plan-model.d.ts +45 -0
  84. package/dist/types/chess-reasoning/poc-semantic-text.d.ts +8 -0
  85. package/dist/types/chess-reasoning/poc-tools.d.ts +81 -0
  86. package/dist/types/chess-reasoning/portable-answer-runtime.d.ts +291 -0
  87. package/dist/types/chess-reasoning/position-analysis-contracts.d.ts +31 -0
  88. package/dist/types/chess-reasoning/position-analysis-scope.d.ts +3 -0
  89. package/dist/types/chess-reasoning/preparation-consolidation.d.ts +21 -0
  90. package/dist/types/chess-reasoning/production-observation-provider.d.ts +16 -0
  91. package/dist/types/chess-reasoning/question-routing.d.ts +326 -0
  92. package/dist/types/chess-reasoning/recorded-main-line.d.ts +37 -0
  93. package/dist/types/chess-reasoning/recorded-position-tools.d.ts +11 -0
  94. package/dist/types/chess-reasoning/recorded-reference-context.d.ts +13 -0
  95. package/dist/types/chess-reasoning/recorded-selected-classification.d.ts +36 -0
  96. package/dist/types/chess-reasoning/reference-limits.d.ts +2 -0
  97. package/dist/types/chess-reasoning/research-exports.d.ts +197 -0
  98. package/dist/types/chess-reasoning/saved-score-presentation.d.ts +14 -0
  99. package/dist/types/chess-reasoning/score-comparison-notices.d.ts +33 -0
  100. package/dist/types/chess-reasoning/server-simple-policy.d.ts +31 -0
  101. package/dist/types/chess-reasoning/simple-agent-config.d.ts +73 -0
  102. package/dist/types/chess-reasoning/simple-board-analysis.d.ts +85 -0
  103. package/dist/types/chess-reasoning/simple-compact-evidence.d.ts +7 -0
  104. package/dist/types/chess-reasoning/simple-completion.d.ts +23 -0
  105. package/dist/types/chess-reasoning/simple-engine-presentation.d.ts +3 -0
  106. package/dist/types/chess-reasoning/simple-evidence-preparation.d.ts +17 -0
  107. package/dist/types/chess-reasoning/simple-evidence-view.d.ts +17 -0
  108. package/dist/types/chess-reasoning/simple-explanation-coverage.d.ts +90 -0
  109. package/dist/types/chess-reasoning/simple-fact-delivery.d.ts +43 -0
  110. package/dist/types/chess-reasoning/simple-fallback-premise.d.ts +5 -0
  111. package/dist/types/chess-reasoning/simple-prose-references.d.ts +108 -0
  112. package/dist/types/chess-reasoning/simple-runtime-version.d.ts +1 -0
  113. package/dist/types/chess-reasoning/stable.d.ts +2 -0
  114. package/dist/types/chess-reasoning/tool-input-loop-guard.d.ts +5 -0
  115. package/dist/types/chess-reasoning/types.d.ts +180 -0
  116. package/dist/types/chess-reasoning/visible-support-lines.d.ts +12 -0
  117. package/dist/types/chess-reasoning/wikibooks-index.d.ts +30 -0
  118. package/dist/types/chess-reasoning/wikibooks-tool-context.d.ts +10 -0
  119. package/dist/types/player-perspective.d.ts +16 -0
  120. package/dist/types/shared-exports.d.ts +22 -0
  121. package/docs/API.md +82 -0
  122. package/docs/OWNERSHIP-ADOPTION.md +35 -0
  123. package/docs/OWNERSHIP-DRIFT.json +55 -0
  124. package/docs/RESEARCH-API.md +28 -0
  125. package/licenses/third-party/INVENTORY.json +202 -0
  126. package/licenses/third-party/ai-7.0.85/LICENSE +13 -0
  127. package/licenses/third-party/ai-sdk--gateway-4.0.69/LICENSE +13 -0
  128. package/licenses/third-party/ai-sdk--provider-4.0.9/LICENSE +13 -0
  129. package/licenses/third-party/ai-sdk--provider-utils-5.0.34/APACHE-2.0.txt +73 -0
  130. package/licenses/third-party/ai-sdk--provider-utils-5.0.34/src/to-json-schema/zod3-to-json-schema/LICENSE +16 -0
  131. package/licenses/third-party/chess.js-1.4.0/LICENSE +23 -0
  132. package/licenses/third-party/eventsource-parser-3.1.1/LICENSE +21 -0
  133. package/licenses/third-party/json-schema-0.4.0/LICENSE +195 -0
  134. package/licenses/third-party/standard-schema--spec-1.1.0/LICENSE +21 -0
  135. package/licenses/third-party/types--json-schema-7.0.15/LICENSE +21 -0
  136. package/licenses/third-party/types--node-22.19.19/LICENSE +21 -0
  137. package/licenses/third-party/undici-7.30.0/LICENSE +21 -0
  138. package/licenses/third-party/undici-7.30.0/lib/web/fetch/LICENSE +21 -0
  139. package/licenses/third-party/undici-types-6.21.0/LICENSE +21 -0
  140. package/licenses/third-party/vercel--oidc-3.2.0/LICENSE +202 -0
  141. package/licenses/third-party/workflow--serde-4.1.0/APACHE-2.0.txt +73 -0
  142. package/licenses/third-party/workflow--serde-4.1.0/LICENSE.md +3 -0
  143. package/licenses/third-party/zod-4.6.5/LICENSE +21 -0
  144. package/npm-release.json +5 -0
  145. package/package.json +72 -4
  146. package/scripts/check-release-tooling.mjs +22 -0
  147. package/scripts/pack.mjs +68 -0
  148. package/scripts/publish-reviewed.mjs +85 -0
  149. package/scripts/release-tooling.json +13 -0
  150. package/scripts/update-dependency.mjs +44 -0
  151. package/scripts/verify-release.mjs +52 -0
  152. package/src/ai-request-failure.ts +34 -0
  153. package/src/ai-request-limits.ts +4 -0
  154. package/src/ai-routing-diagnostics.ts +33 -0
  155. package/src/chess-reasoning/ablation-adaptive-evidence-loop.ts +515 -0
  156. package/src/chess-reasoning/ablation-adaptive-runtime.ts +924 -0
  157. package/src/chess-reasoning/ablation-direct-synthesis.ts +1128 -0
  158. package/src/chess-reasoning/ablation-evidence-bundle.ts +726 -0
  159. package/src/chess-reasoning/ablation-evidence-capture.ts +513 -0
  160. package/src/chess-reasoning/ablation-lean-direct-runtime.ts +670 -0
  161. package/src/chess-reasoning/ablation-model-facing-evidence.ts +212 -0
  162. package/src/chess-reasoning/ablation-transport-correction.ts +106 -0
  163. package/src/chess-reasoning/ai-sdk-runtime-support.ts +381 -0
  164. package/src/chess-reasoning/answer-host-contracts.ts +10 -0
  165. package/src/chess-reasoning/answer-model-connector.ts +83 -0
  166. package/src/chess-reasoning/answer-pipeline-exports.ts +98 -0
  167. package/src/chess-reasoning/answer-pipeline.ts +195 -0
  168. package/src/chess-reasoning/answer-reference-validation.ts +124 -0
  169. package/src/chess-reasoning/answer-tool-host.ts +10 -0
  170. package/src/chess-reasoning/branch-expansion-policy.ts +32 -0
  171. package/src/chess-reasoning/branch-expansion.ts +80 -0
  172. package/src/chess-reasoning/causal-claim-checks.ts +256 -0
  173. package/src/chess-reasoning/chess-reference-dictionary.ts +21 -0
  174. package/src/chess-reasoning/classification-question-target.ts +30 -0
  175. package/src/chess-reasoning/classification-reassessment.ts +34 -0
  176. package/src/chess-reasoning/compact-search-preparation.ts +125 -0
  177. package/src/chess-reasoning/concept-registry.ts +275 -0
  178. package/src/chess-reasoning/conversation-context.ts +29 -0
  179. package/src/chess-reasoning/engine-search-failure.ts +11 -0
  180. package/src/chess-reasoning/evidence-citation-normalization.ts +15 -0
  181. package/src/chess-reasoning/evidence-licenses.ts +166 -0
  182. package/src/chess-reasoning/evidence-selector-contract.ts +5 -0
  183. package/src/chess-reasoning/existing-analysis-context.ts +544 -0
  184. package/src/chess-reasoning/fact-observation-provider.ts +134 -0
  185. package/src/chess-reasoning/fact-provider.ts +250 -0
  186. package/src/chess-reasoning/fresh-engine-pv-witnesses.ts +128 -0
  187. package/src/chess-reasoning/historical-prose.ts +116 -0
  188. package/src/chess-reasoning/idea-graph.ts +224 -0
  189. package/src/chess-reasoning/initial-search-plan.ts +115 -0
  190. package/src/chess-reasoning/lossless-evidence-sharing.ts +135 -0
  191. package/src/chess-reasoning/matched-comparison.ts +40 -0
  192. package/src/chess-reasoning/material-accounting.ts +55 -0
  193. package/src/chess-reasoning/material-format.ts +47 -0
  194. package/src/chess-reasoning/mechanical-fact-provider.ts +1602 -0
  195. package/src/chess-reasoning/mechanical-ray-facts.ts +123 -0
  196. package/src/chess-reasoning/mechanism-presentation.ts +94 -0
  197. package/src/chess-reasoning/move-mechanism-facts.ts +185 -0
  198. package/src/chess-reasoning/native-answer-connector.ts +13 -0
  199. package/src/chess-reasoning/opening-source-contracts.ts +47 -0
  200. package/src/chess-reasoning/opening-source-credits.ts +53 -0
  201. package/src/chess-reasoning/opponent-threat-preparation.ts +98 -0
  202. package/src/chess-reasoning/piece-identities.ts +159 -0
  203. package/src/chess-reasoning/poc-contracts.ts +1097 -0
  204. package/src/chess-reasoning/poc-hypotheses.ts +759 -0
  205. package/src/chess-reasoning/poc-move-witnesses.ts +170 -0
  206. package/src/chess-reasoning/poc-observations.ts +611 -0
  207. package/src/chess-reasoning/poc-piece-refs.ts +62 -0
  208. package/src/chess-reasoning/poc-plan-model.ts +345 -0
  209. package/src/chess-reasoning/poc-semantic-text.ts +10 -0
  210. package/src/chess-reasoning/poc-tools.ts +978 -0
  211. package/src/chess-reasoning/portable-answer-runtime.ts +684 -0
  212. package/src/chess-reasoning/position-analysis-contracts.ts +88 -0
  213. package/src/chess-reasoning/position-analysis-scope.ts +20 -0
  214. package/src/chess-reasoning/preparation-consolidation.ts +91 -0
  215. package/src/chess-reasoning/production-observation-provider.ts +41 -0
  216. package/src/chess-reasoning/question-routing.ts +332 -0
  217. package/src/chess-reasoning/recorded-main-line.ts +55 -0
  218. package/src/chess-reasoning/recorded-position-tools.ts +78 -0
  219. package/src/chess-reasoning/recorded-reference-context.ts +44 -0
  220. package/src/chess-reasoning/recorded-selected-classification.ts +54 -0
  221. package/src/chess-reasoning/reference-limits.ts +2 -0
  222. package/src/chess-reasoning/research-exports.ts +197 -0
  223. package/src/chess-reasoning/saved-score-presentation.ts +6 -0
  224. package/src/chess-reasoning/score-comparison-notices.ts +115 -0
  225. package/src/chess-reasoning/server-simple-policy.ts +75 -0
  226. package/src/chess-reasoning/simple-agent-config.ts +58 -0
  227. package/src/chess-reasoning/simple-board-analysis.ts +57 -0
  228. package/src/chess-reasoning/simple-compact-evidence.ts +79 -0
  229. package/src/chess-reasoning/simple-completion.ts +37 -0
  230. package/src/chess-reasoning/simple-engine-presentation.ts +95 -0
  231. package/src/chess-reasoning/simple-evidence-preparation.ts +32 -0
  232. package/src/chess-reasoning/simple-evidence-view.ts +69 -0
  233. package/src/chess-reasoning/simple-explanation-coverage.ts +118 -0
  234. package/src/chess-reasoning/simple-fact-delivery.ts +52 -0
  235. package/src/chess-reasoning/simple-fallback-premise.ts +65 -0
  236. package/src/chess-reasoning/simple-prose-references.ts +528 -0
  237. package/src/chess-reasoning/simple-runtime-version.ts +2 -0
  238. package/src/chess-reasoning/stable.ts +18 -0
  239. package/src/chess-reasoning/tool-input-loop-guard.ts +38 -0
  240. package/src/chess-reasoning/types.ts +195 -0
  241. package/src/chess-reasoning/visible-support-lines.ts +44 -0
  242. package/src/chess-reasoning/wikibooks-index.ts +56 -0
  243. package/src/chess-reasoning/wikibooks-tool-context.ts +91 -0
  244. package/src/player-perspective.ts +41 -0
  245. package/src/shared-exports.ts +23 -0
  246. package/test/answer-pipeline.test.mjs +375 -0
  247. package/test/owner/chess-reasoning-compact-search-preparation.test.mjs +111 -0
  248. package/test/owner/mechanism-encoding.test.mjs +78 -0
  249. package/test/owner/move-mechanism-facts.test.mjs +105 -0
  250. package/test/owner/pipeline-host-preparation.test.mjs +115 -0
  251. package/test/owner/position-preparation.test.mjs +22 -0
  252. package/test/owner/preparation-consolidation.test.mjs +74 -0
  253. package/test/owner/prose-reference-admission.test.mjs +26 -0
  254. package/test/owner/score-comparison-notices.test.mjs +116 -0
  255. package/test/owner/simple-engine-presentation.test.mjs +50 -0
  256. package/test/owner/tool-input-loop-guard.test.mjs +25 -0
  257. package/test-types.mts +23 -0
  258. package/tsconfig.json +22 -0
@@ -0,0 +1,275 @@
1
+ import type {
2
+ ConceptKey,
3
+ RegistryKey,
4
+ SemanticCandidate,
5
+ SemanticEntity,
6
+ SemanticParticipant,
7
+ SemanticValue,
8
+ } from "./types";
9
+
10
+ export const ENTITY_TYPES = {
11
+ IDEA: "idea",
12
+ PLAN: "plan",
13
+ ROLE: "role-assignment",
14
+ CONDITION: "condition",
15
+ TRANSFORMATION: "transformation",
16
+ OUTCOME: "outcome",
17
+ } as const;
18
+
19
+ export const REFERENCE_DOMAINS = {
20
+ PIECE: "piece",
21
+ SQUARE: "square",
22
+ MOVE: "move",
23
+ POSITION: "position",
24
+ OUTCOME: "outcome",
25
+ ENTITY: "entity",
26
+ } as const;
27
+
28
+ export const PARTICIPANT_ROLES = {
29
+ ACTOR: "actor",
30
+ SUBJECT: "subject",
31
+ TARGET: "target",
32
+ GOAL: "goal",
33
+ RESOURCE: "resource",
34
+ DEFENDER: "defender",
35
+ DESTINATION: "destination",
36
+ } as const;
37
+
38
+ export const ATTRIBUTE_KEYS = {
39
+ ACCEPTING_MOVES: "acceptingMoves",
40
+ PROPOSAL_REASONS: "proposalReasons",
41
+ DESCRIPTION: "description",
42
+ CONFIDENCE_NOTE: "confidenceNote",
43
+ } as const;
44
+
45
+ export const RELATION_TYPES = {
46
+ SUPPORTS: "supports",
47
+ COMPETES: "competes",
48
+ DERIVES: "derives",
49
+ SPLITS: "splits",
50
+ CONVERGES: "converges",
51
+ ENABLES: "enables",
52
+ REQUIRES: "requires",
53
+ REFUTES: "refutes",
54
+ EXPLAINS: "explains",
55
+ TRANSFORMS: "transforms",
56
+ } as const;
57
+
58
+ /**
59
+ * These are registry values, not members of the entity schema. New concepts
60
+ * may be registered without changing `SemanticCandidate` or `SemanticEntity`.
61
+ */
62
+ export const CONCEPT_KEYS = {
63
+ OFFER: "material.offer",
64
+ MATERIAL_CLAIM: "material.claim",
65
+ FORK: "tactic.fork",
66
+ TRAPPED_TARGET: "tactic.trapped-target",
67
+ PROMOTION: "tactic.promotion",
68
+ MATING_ATTACK: "attack.mating",
69
+ PERPETUAL_CHECK: "attack.perpetual-check",
70
+ POSITIONAL_CLAIM: "position.claim",
71
+ KING_ATTACK_PLAN: "plan.king-attack",
72
+ PIECE_ROLE: "role.piece-function",
73
+ CHANGED_CONSTRAINT: "condition.changed-constraint",
74
+ POSITIONAL_TRANSFORMATION: "position.transformation",
75
+ } as const;
76
+
77
+ export type CaptureActor = "owner" | "opponent" | "either";
78
+
79
+ export type ConceptLifecycle = {
80
+ initialState: RegistryKey;
81
+ retainedState: RegistryKey;
82
+ terminalStates: RegistryKey[];
83
+ trackedParticipantRole?: RegistryKey;
84
+ expireWhenTrackedUnavailable?: boolean;
85
+ onTrackedCapture?: {
86
+ capturedBy: CaptureActor;
87
+ matchingState: RegistryKey;
88
+ matchingAnnotation: RegistryKey;
89
+ otherState: RegistryKey;
90
+ otherAnnotation: RegistryKey;
91
+ };
92
+ };
93
+
94
+ export type ConceptDefinition = {
95
+ key: ConceptKey;
96
+ label: string;
97
+ category: RegistryKey;
98
+ description: string;
99
+ defaultEntityType: RegistryKey;
100
+ acceptancePolicy?: RegistryKey;
101
+ lifecycle?: ConceptLifecycle;
102
+ };
103
+
104
+ export type ConceptRegistry = Readonly<Record<ConceptKey, Readonly<ConceptDefinition>>>;
105
+
106
+ const COMMON_TERMINAL_STATES = ["converted", "refuted", "abandoned", "expired"];
107
+
108
+ function claimLifecycle(capturedBy: CaptureActor): ConceptLifecycle {
109
+ return {
110
+ initialState: "created",
111
+ retainedState: "retained",
112
+ terminalStates: [...COMMON_TERMINAL_STATES],
113
+ trackedParticipantRole: PARTICIPANT_ROLES.TARGET,
114
+ expireWhenTrackedUnavailable: true,
115
+ onTrackedCapture: {
116
+ capturedBy,
117
+ matchingState: "converted",
118
+ matchingAnnotation: "converted",
119
+ otherState: "refuted",
120
+ otherAnnotation: "refuted",
121
+ },
122
+ };
123
+ }
124
+
125
+ export function createConceptRegistry(definitions: ConceptDefinition[]): ConceptRegistry {
126
+ const registry: Record<string, Readonly<ConceptDefinition>> = {};
127
+ for (const definition of definitions) {
128
+ if (!definition.key.trim()) throw new Error("Concept keys must not be empty");
129
+ if (registry[definition.key]) throw new Error(`Duplicate concept key: ${definition.key}`);
130
+ registry[definition.key] = Object.freeze({
131
+ ...definition,
132
+ lifecycle: definition.lifecycle
133
+ ? Object.freeze({
134
+ ...definition.lifecycle,
135
+ terminalStates: Object.freeze([...definition.lifecycle.terminalStates]) as unknown as RegistryKey[],
136
+ onTrackedCapture: definition.lifecycle.onTrackedCapture
137
+ ? Object.freeze({ ...definition.lifecycle.onTrackedCapture })
138
+ : undefined,
139
+ })
140
+ : undefined,
141
+ });
142
+ }
143
+ return Object.freeze(registry);
144
+ }
145
+
146
+ export function extendConceptRegistry(registry: ConceptRegistry, definitions: ConceptDefinition[]): ConceptRegistry {
147
+ return createConceptRegistry([...Object.values(registry), ...definitions]);
148
+ }
149
+
150
+ export function conceptDefinition(registry: ConceptRegistry, key: ConceptKey): Readonly<ConceptDefinition> | null {
151
+ return registry[key] || null;
152
+ }
153
+
154
+ export function conceptsOf(value: Pick<SemanticCandidate | SemanticEntity, "concepts">): ConceptKey[] {
155
+ return [...value.concepts];
156
+ }
157
+
158
+ export function hasConcept(value: Pick<SemanticCandidate | SemanticEntity, "concepts">, concept: ConceptKey): boolean {
159
+ return value.concepts.includes(concept);
160
+ }
161
+
162
+ export function primaryConcept(value: Pick<SemanticCandidate | SemanticEntity, "concepts">): ConceptKey | null {
163
+ return value.concepts[0] || null;
164
+ }
165
+
166
+ export function participantIds(
167
+ value: Pick<SemanticCandidate | SemanticEntity, "participants">,
168
+ role: RegistryKey,
169
+ domain?: RegistryKey,
170
+ ): string[] {
171
+ return value.participants
172
+ .filter((participant) => participant.role === role && (!domain || participant.ref.domain === domain))
173
+ .map((participant) => participant.ref.id);
174
+ }
175
+
176
+ export function participant(role: RegistryKey, domain: RegistryKey, id: string): SemanticParticipant {
177
+ return { role, ref: { domain, id } };
178
+ }
179
+
180
+ export function stringListAttribute(value: { attributes: Record<string, SemanticValue> }, key: string): string[] {
181
+ const attribute = value.attributes[key];
182
+ return Array.isArray(attribute) ? attribute.filter((item): item is string => typeof item === "string") : [];
183
+ }
184
+
185
+ export const DEFAULT_CONCEPT_REGISTRY = createConceptRegistry([
186
+ {
187
+ key: CONCEPT_KEYS.OFFER,
188
+ label: "Material offer",
189
+ category: "tactical",
190
+ description: "A material liability the opponent may choose to accept.",
191
+ defaultEntityType: ENTITY_TYPES.IDEA,
192
+ acceptancePolicy: "material-offer-liability/1",
193
+ lifecycle: claimLifecycle("opponent"),
194
+ },
195
+ {
196
+ key: CONCEPT_KEYS.MATERIAL_CLAIM,
197
+ label: "Material claim",
198
+ category: "tactical",
199
+ description: "An evidence-backed entitlement to win material.",
200
+ defaultEntityType: ENTITY_TYPES.IDEA,
201
+ lifecycle: claimLifecycle("owner"),
202
+ },
203
+ {
204
+ key: CONCEPT_KEYS.FORK,
205
+ label: "Fork",
206
+ category: "tactical",
207
+ description: "One resource attacks multiple targets.",
208
+ defaultEntityType: ENTITY_TYPES.IDEA,
209
+ lifecycle: claimLifecycle("owner"),
210
+ },
211
+ {
212
+ key: CONCEPT_KEYS.TRAPPED_TARGET,
213
+ label: "Trapped target",
214
+ category: "tactical",
215
+ description: "A target lacks an adequate escape or defensive resource.",
216
+ defaultEntityType: ENTITY_TYPES.IDEA,
217
+ lifecycle: claimLifecycle("owner"),
218
+ },
219
+ {
220
+ key: CONCEPT_KEYS.PROMOTION,
221
+ label: "Promotion",
222
+ category: "tactical",
223
+ description: "A promotion event or promotion claim.",
224
+ defaultEntityType: ENTITY_TYPES.IDEA,
225
+ },
226
+ {
227
+ key: CONCEPT_KEYS.MATING_ATTACK,
228
+ label: "Mating attack",
229
+ category: "tactical",
230
+ description: "A coordinated plan whose concrete target is mate.",
231
+ defaultEntityType: ENTITY_TYPES.PLAN,
232
+ },
233
+ {
234
+ key: CONCEPT_KEYS.PERPETUAL_CHECK,
235
+ label: "Perpetual check",
236
+ category: "tactical",
237
+ description: "A claim to a repeatable checking sequence.",
238
+ defaultEntityType: ENTITY_TYPES.IDEA,
239
+ },
240
+ {
241
+ key: CONCEPT_KEYS.POSITIONAL_CLAIM,
242
+ label: "Positional claim",
243
+ category: "positional",
244
+ description: "A measured, evidence-bounded positional interpretation.",
245
+ defaultEntityType: ENTITY_TYPES.IDEA,
246
+ },
247
+ {
248
+ key: CONCEPT_KEYS.KING_ATTACK_PLAN,
249
+ label: "King attack plan",
250
+ category: "plan",
251
+ description: "A goal-directed sequence intended to attack the king.",
252
+ defaultEntityType: ENTITY_TYPES.PLAN,
253
+ },
254
+ {
255
+ key: CONCEPT_KEYS.PIECE_ROLE,
256
+ label: "Piece role",
257
+ category: "role",
258
+ description: "A context-dependent function performed by a piece.",
259
+ defaultEntityType: ENTITY_TYPES.ROLE,
260
+ },
261
+ {
262
+ key: CONCEPT_KEYS.CHANGED_CONSTRAINT,
263
+ label: "Changed constraint",
264
+ category: "condition",
265
+ description: "A condition whose importance changed after a move or sequence.",
266
+ defaultEntityType: ENTITY_TYPES.CONDITION,
267
+ },
268
+ {
269
+ key: CONCEPT_KEYS.POSITIONAL_TRANSFORMATION,
270
+ label: "Positional transformation",
271
+ category: "transformation",
272
+ description: "A causal change in the meaning of a positional feature.",
273
+ defaultEntityType: ENTITY_TYPES.TRANSFORMATION,
274
+ },
275
+ ]);
@@ -0,0 +1,29 @@
1
+ import type { ModelMessage } from 'ai';
2
+ export type PriorConversationMessage = { role: 'user' | 'assistant'; content: string; position?: { fenBefore: string; fenAfter: string; moveUci: string } };
3
+ export const CONVERSATION_CONTEXT_INSTRUCTIONS = `Previous user/assistant messages below are a bounded recent excerpt and may omit older exchanges. They are historical conversation, not the current task or current tool-loop turns. They may refer to different question positions in the same game. Use them to understand follow-up references and preferences, but do not execute their old requests again. Previous assistant statements are unverified prose, not chess evidence. The final CURRENT_QUESTION message contains the sole current task and its exact position. Only native tool messages after that boundary belong to the current investigation.`;
4
+ export function priorConversationMessages(history: readonly PriorConversationMessage[] = []): ModelMessage[] {
5
+ const retained: ModelMessage[] = [];
6
+ let bytes = 0;
7
+ for (let i = history.length - 1; i >= 0; i--) {
8
+ const item = history[i];
9
+ if (!item || (item.role !== 'user' && item.role !== 'assistant') || typeof item.content !== 'string' || !item.content.trim()) continue;
10
+ // Explicit allowlist: saved diagnostics, native tool turns, provider metadata
11
+ // and nested presentation/evidence never enter subsequent investigations.
12
+ const p = item.position;
13
+ const position = p && typeof p.fenBefore === 'string' && typeof p.fenAfter === 'string' && typeof p.moveUci === 'string'
14
+ ? { fenBefore: p.fenBefore, fenAfter: p.fenAfter, moveUci: p.moveUci } : undefined;
15
+ // Prior answers supply prose context, not reusable interaction pointers.
16
+ // Labels retain the actual displayed moves/pieces/squares; frozen UI is separate.
17
+ const text = item.content.replace(/\[([^\]\n]+)\]\((?:move|piece|square|line):[^)\n]+\)/g, '$1')
18
+ .replace(/\[(?:\s*evidence:[\w:-]+\s*[,;]?\s*)+\]/g, '');
19
+ const content = JSON.stringify({ scope: 'previous-conversation', position, text });
20
+ const size = new TextEncoder().encode(content).length;
21
+ if (bytes + size > 36_000 || retained.length >= 24) break;
22
+ bytes += size; retained.unshift({ role: item.role, content });
23
+ }
24
+ // Avoid an orphan answer if truncation cut off its question.
25
+ if (retained[0]?.role === 'assistant') retained.shift();
26
+ return retained.length < history.length
27
+ ? [{ role: 'user', content: '[Conversation history truncated: only the most recent complete exchanges that fit are included.]' }, ...retained]
28
+ : retained;
29
+ }
@@ -0,0 +1,11 @@
1
+ /** Bounded observable cause only: no stack, response headers or provider payload. */
2
+ export function engineSearchFailure(error: unknown) {
3
+ const detail = error as { message?: unknown; code?: unknown; status?: unknown; cause?: unknown } | null;
4
+ const message = typeof detail?.message === 'string' ? detail.message.slice(0, 300)
5
+ : typeof error === 'string' ? error.slice(0, 300) : 'engine-search-unavailable';
6
+ const cause = detail?.cause as { message?: unknown; code?: unknown } | null;
7
+ return { error: message,
8
+ ...(typeof detail?.code === 'string' ? { code: detail.code.slice(0, 80) } : {}),
9
+ ...(typeof detail?.status === 'number' && Number.isInteger(detail.status) && detail.status >= 100 && detail.status <= 599 ? { status: detail.status } : {}),
10
+ ...(typeof cause?.message === 'string' ? { cause: cause.message.slice(0, 300) } : {}) };
11
+ }
@@ -0,0 +1,15 @@
1
+ import type { ReasoningEvidenceRecord } from './poc-contracts';
2
+
3
+ /** Repair syntax only when the exact supplied identifier makes it unambiguous. */
4
+ export function normalizedEvidenceCitations(answer: string, records: readonly Pick<ReasoningEvidenceRecord, 'id'>[]) {
5
+ const ids = new Set(records.map(record => record.id));
6
+ const repairs: Array<{originalId:string;canonicalId:string}> = [];
7
+ const normalized = answer.replace(/\b(?:evidence:){2,}[\w:-]+/g, originalId => {
8
+ if (ids.has(originalId)) return originalId;
9
+ const canonicalId = originalId.replace(/^(?:evidence:)+/, 'evidence:');
10
+ if (!ids.has(canonicalId)) return originalId;
11
+ repairs.push({originalId,canonicalId});
12
+ return canonicalId;
13
+ });
14
+ return {answer:normalized,repairs};
15
+ }
@@ -0,0 +1,166 @@
1
+ import type { ProofStrength, SemanticValue } from "./types";
2
+
3
+ export const EVIDENCE_LICENSE = Object.freeze({
4
+ CHESS_LEGALITY: "chess.legality",
5
+ CHESS_IDENTITY: "chess.identity",
6
+ CHESS_POSITION_FACT: "chess.position-fact",
7
+ ENGINE_BOUNDED_CONTINUATION: "engine.bounded-continuation",
8
+ ENGINE_BOUNDED_COMPARISON: "engine.bounded-comparison",
9
+ ENGINE_BOUNDED_SCORE: "engine.bounded-score",
10
+ ENGINE_BOUNDED_RESPONSE_COVERAGE: "engine.bounded-response-coverage",
11
+ COVERAGE_EXHAUSTIVE: "coverage.exhaustive",
12
+ ATTENTION_AFFORDANCE: "attention.affordance",
13
+ SEMANTIC_REVIEWED_STATE: "semantic.reviewed-state",
14
+ WORKFLOW_AUDIT: "workflow.audit",
15
+ } as const);
16
+
17
+ export type EvidenceLicense = typeof EVIDENCE_LICENSE[keyof typeof EVIDENCE_LICENSE];
18
+
19
+ const LICENSES = new Set<EvidenceLicense>(Object.values(EVIDENCE_LICENSE));
20
+
21
+ export type EvidenceLicenseInput = {
22
+ kind: string;
23
+ source: string;
24
+ authority: string | null;
25
+ proofStrength: ProofStrength | null;
26
+ data: Record<string, SemanticValue>;
27
+ coverage: { complete: boolean; covered: string[]; unresolved: string[] } | null;
28
+ replay: Record<string, SemanticValue> | null;
29
+ };
30
+
31
+ export type LicensableEvidenceRecord = {
32
+ kind: string;
33
+ source: string;
34
+ proofStrength: ProofStrength | null;
35
+ licenses?: EvidenceLicense[];
36
+ data: Record<string, SemanticValue>;
37
+ coverage: { complete: boolean; covered: string[]; unresolved: string[] } | null;
38
+ replay: Record<string, SemanticValue> | null;
39
+ };
40
+
41
+ export function evidenceLicenseInput(record: LicensableEvidenceRecord): EvidenceLicenseInput {
42
+ const data = record.data || {};
43
+ const authority = typeof data.authority === "string"
44
+ ? data.authority
45
+ : record.kind === "fact"
46
+ ? "deterministic-derived"
47
+ : record.kind === "probe"
48
+ ? "bounded-engine"
49
+ : null;
50
+ return {
51
+ kind: record.kind,
52
+ source: record.source,
53
+ authority,
54
+ proofStrength: record.proofStrength,
55
+ data,
56
+ coverage: record.coverage || null,
57
+ replay: record.replay || null,
58
+ };
59
+ }
60
+
61
+ function exactSequenceOnly(input: EvidenceLicenseInput): boolean {
62
+ return input.data.scope === "sequence-legality-and-identity";
63
+ }
64
+
65
+ function isWorkflowKind(kind: string): boolean {
66
+ return kind === "observation-review"
67
+ || kind === "reasoning-challenge"
68
+ || kind === "hypothesis-review"
69
+ || kind === "critic-resolution-audit";
70
+ }
71
+
72
+ /**
73
+ * Central maximum-license policy. A producer may claim any subset of these
74
+ * values, but no producer can broaden its source by adding a license.
75
+ */
76
+ export function maximumEvidenceLicenses(input: EvidenceLicenseInput): EvidenceLicense[] {
77
+ // Authority is the source ceiling. A heuristic producer cannot self-upgrade
78
+ // by attaching a narrower-looking scope.
79
+ if (input.authority === "heuristic-affordance") return [EVIDENCE_LICENSE.ATTENTION_AFFORDANCE];
80
+ if (isWorkflowKind(input.kind)) return [EVIDENCE_LICENSE.WORKFLOW_AUDIT];
81
+ if (input.kind === "graph") return [EVIDENCE_LICENSE.SEMANTIC_REVIEWED_STATE];
82
+ // A replay witness explicitly scoped to legality and stable identity stays
83
+ // in that narrow authority lane even when it was transported as a probe.
84
+ // Record kind is transport metadata; it must not broaden the scope's
85
+ // evidentiary meaning into a bounded-engine continuation or score.
86
+ if (exactSequenceOnly(input)) {
87
+ if (input.authority !== "legal-exact" && input.authority !== "bounded-engine") return [];
88
+ const scoped = new Set<EvidenceLicense>([
89
+ EVIDENCE_LICENSE.CHESS_LEGALITY,
90
+ EVIDENCE_LICENSE.CHESS_IDENTITY,
91
+ ]);
92
+ if (input.coverage?.complete && input.coverage.unresolved.length === 0) {
93
+ scoped.add(EVIDENCE_LICENSE.COVERAGE_EXHAUSTIVE);
94
+ }
95
+ return [...scoped].sort();
96
+ }
97
+
98
+ const result = new Set<EvidenceLicense>();
99
+ if (input.authority === "legal-exact" || input.authority === "deterministic-derived") {
100
+ result.add(EVIDENCE_LICENSE.CHESS_LEGALITY);
101
+ result.add(EVIDENCE_LICENSE.CHESS_IDENTITY);
102
+ result.add(EVIDENCE_LICENSE.CHESS_POSITION_FACT);
103
+ }
104
+
105
+ if (input.authority === "bounded-engine") {
106
+ result.add(EVIDENCE_LICENSE.ENGINE_BOUNDED_SCORE);
107
+ if (/compare[_-]moves|compare-moves/.test(input.source)) {
108
+ result.add(EVIDENCE_LICENSE.ENGINE_BOUNDED_COMPARISON);
109
+ } else {
110
+ result.add(EVIDENCE_LICENSE.ENGINE_BOUNDED_CONTINUATION);
111
+ }
112
+ if (/enumerate[_-]defenses|enumerate-defenses/.test(input.source)) {
113
+ result.add(EVIDENCE_LICENSE.ENGINE_BOUNDED_RESPONSE_COVERAGE);
114
+ }
115
+ if (input.replay) {
116
+ result.add(EVIDENCE_LICENSE.CHESS_LEGALITY);
117
+ result.add(EVIDENCE_LICENSE.CHESS_IDENTITY);
118
+ }
119
+ }
120
+
121
+ if (input.coverage?.complete && input.coverage.unresolved.length === 0) {
122
+ result.add(EVIDENCE_LICENSE.COVERAGE_EXHAUSTIVE);
123
+ }
124
+ return [...result].sort();
125
+ }
126
+
127
+ export function validateEvidenceLicenseClaims(input: EvidenceLicenseInput, claimed: readonly unknown[]): EvidenceLicense[] {
128
+ if (!Array.isArray(claimed)) throw new Error("Evidence licenses must be an array");
129
+ const normalized = [...new Set(claimed.map(String))];
130
+ const unknown = normalized.filter((license) => !LICENSES.has(license as EvidenceLicense));
131
+ if (unknown.length) throw new Error(`Unknown evidence license(s): ${unknown.join(", ")}`);
132
+ const maximum = new Set(maximumEvidenceLicenses(input));
133
+ const excessive = normalized.filter((license) => !maximum.has(license as EvidenceLicense));
134
+ if (excessive.length) throw new Error(`Evidence claims license(s) beyond its source ceiling: ${excessive.join(", ")}`);
135
+ return normalized.sort() as EvidenceLicense[];
136
+ }
137
+
138
+ export function effectiveEvidenceLicenses(input: EvidenceLicenseInput & { licenses?: readonly unknown[] }): EvidenceLicense[] {
139
+ // Legacy development fixtures without an explicit field are normalized at
140
+ // admission. Runtime and provider-owned records always serialize the result.
141
+ return input.licenses === undefined
142
+ ? maximumEvidenceLicenses(input)
143
+ : validateEvidenceLicenseClaims(input, input.licenses);
144
+ }
145
+
146
+ export function effectiveLicensesForRecord(record: LicensableEvidenceRecord): EvidenceLicense[] {
147
+ return effectiveEvidenceLicenses({ ...evidenceLicenseInput(record), licenses: record.licenses });
148
+ }
149
+
150
+ export function withEvidenceLicenses<T extends LicensableEvidenceRecord>(record: T): T & { licenses: EvidenceLicense[] } {
151
+ return { ...record, licenses: effectiveLicensesForRecord(record) };
152
+ }
153
+
154
+ export function licensesSemanticChessGrounding(licenses: readonly EvidenceLicense[]): boolean {
155
+ return licenses.some((license) => license === EVIDENCE_LICENSE.CHESS_POSITION_FACT
156
+ || license === EVIDENCE_LICENSE.ENGINE_BOUNDED_CONTINUATION
157
+ || license === EVIDENCE_LICENSE.ENGINE_BOUNDED_COMPARISON
158
+ || license === EVIDENCE_LICENSE.ENGINE_BOUNDED_RESPONSE_COVERAGE
159
+ || license === EVIDENCE_LICENSE.SEMANTIC_REVIEWED_STATE);
160
+ }
161
+
162
+ export function licensesBoundedRouteRelevance(licenses: readonly EvidenceLicense[]): boolean {
163
+ return licenses.includes(EVIDENCE_LICENSE.ENGINE_BOUNDED_CONTINUATION)
164
+ || licenses.includes(EVIDENCE_LICENSE.ENGINE_BOUNDED_COMPARISON)
165
+ || licenses.includes(EVIDENCE_LICENSE.ENGINE_BOUNDED_RESPONSE_COVERAGE);
166
+ }
@@ -0,0 +1,5 @@
1
+ export type LeanDirectEvidenceSelector = Readonly<{
2
+ id: string;
3
+ factKinds?: readonly string[];
4
+ observationTypes?: readonly string[];
5
+ }>;