@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,1097 @@
1
+ import { materialAlongLine } from './material-accounting';
2
+ import { Chess, type Square } from "chess.js";
3
+ import { createPocIdentityTimeline } from "./poc-piece-refs";
4
+ import { moveMechanismFacts } from "./move-mechanism-facts";
5
+ import { withEvidenceLicenses, type EvidenceLicense } from "./evidence-licenses";
6
+ import { stableHash } from "./stable";
7
+ import type { ProofStrength, SemanticAttributes, SemanticEntity, SemanticParticipant, SemanticRelation, SemanticValue } from "./types";
8
+
9
+ export const REASONING_POC_VERSION = "conceptual-explanation-poc/57" as const;
10
+ export const REASONING_POC_MAX_OUTPUT_TOKENS = 2_000;
11
+ export const REASONING_POC_MAX_HYPOTHESIS_OUTPUT_TOKENS = 4_000;
12
+ export const REASONING_POC_MAX_CRITIC_OUTPUT_TOKENS = 7_000;
13
+ export const REASONING_POC_MAX_TERMINAL_REVIEW_OUTPUT_TOKENS = 4_000;
14
+ export const REASONING_POC_MAX_RESOLUTION_AUDIT_OUTPUT_TOKENS = 3_000;
15
+ /**
16
+ * The optional future-purpose planner may choose one already-supported,
17
+ * bounded probe. It never writes semantic hypotheses, so it gets a smaller
18
+ * transport budget than the hypothesis and critic stages.
19
+ */
20
+ export const REASONING_POC_MAX_PURPOSE_PROBE_OUTPUT_TOKENS = 1_500;
21
+ export const REASONING_POC_MAX_GRAPH_SELECTION_OUTPUT_TOKENS = 2_000;
22
+ export const REASONING_POC_MAX_DISCOURSE_OUTPUT_TOKENS = 2_500;
23
+ export const REASONING_POC_MAX_RENDER_OUTPUT_TOKENS = 4_000;
24
+ export const REASONING_POC_MAX_HYPOTHESIS_BATCHES = 2;
25
+ export const REASONING_POC_RESERVED_MANDATORY_STEPS = 11;
26
+ export const REASONING_POC_REVISION_EVIDENCE_ALLOWANCE = 1;
27
+ /** One opt-in slot for the bounded future-purpose planner; base profiles stay unchanged. */
28
+ export const REASONING_POC_PURPOSE_PROBE_ALLOWANCE = 1;
29
+ /** One opt-in slot for a complete replacement of structurally invalid critic output. */
30
+ export const REASONING_POC_CRITIC_CORRECTION_ALLOWANCE = 1;
31
+
32
+ export type ReasoningPositionContext = {
33
+ kind?: "position"; // Explicit root-position question; absent means the existing move contract.
34
+ nodeId: string;
35
+ parentNodeId?: string;
36
+ historyStartFen?: string;
37
+ fenBefore: string;
38
+ fenAfter: string;
39
+ historyUci: string[];
40
+ moveUci: string;
41
+ moveSan: string;
42
+ };
43
+
44
+ export type ReasoningAudience = "beginner" | "intermediate" | "advanced";
45
+
46
+ export type ReasoningGraphRequirements = {
47
+ minimumEntities: number;
48
+ minimumRelations: number;
49
+ };
50
+
51
+ export type QueryContract = {
52
+ schemaVersion: typeof REASONING_POC_VERSION;
53
+ requestId: string;
54
+ question: string;
55
+ requestedConclusion: "move-idea" | "position-question";
56
+ responseCoverageRequirement: "none" | "bounded-class";
57
+ continuationCoverageRequirement: "none" | "principal-variation";
58
+ minimumContinuationLines: number;
59
+ graphRequirements: ReasoningGraphRequirements;
60
+ audience: ReasoningAudience;
61
+ concise: boolean;
62
+ nodeId: string;
63
+ };
64
+
65
+ export type ReasoningRunControls = {
66
+ maxModelSteps: number;
67
+ maxToolCalls: number;
68
+ maxProbeCalls: number;
69
+ maxEvidenceRecords: number;
70
+ maxObservationRecords: number;
71
+ maxObservationsPresented: number;
72
+ maxHypotheses: number;
73
+ maxOutputChars: number;
74
+ maxProviderOutputChars: number;
75
+ maxWallTimeMs: number;
76
+ };
77
+
78
+ export const DEFAULT_REASONING_RUN_CONTROLS: Readonly<ReasoningRunControls> = Object.freeze({
79
+ maxModelSteps: 15,
80
+ maxToolCalls: 16,
81
+ maxProbeCalls: 5,
82
+ maxEvidenceRecords: 48,
83
+ maxObservationRecords: 48,
84
+ maxObservationsPresented: 16,
85
+ maxHypotheses: 16,
86
+ maxOutputChars: 2_400,
87
+ maxProviderOutputChars: 64_000,
88
+ maxWallTimeMs: 30_000,
89
+ });
90
+
91
+ export type ReasoningEvidenceKind = "context" | "fact" | "probe" | "graph" | "observation-review" | "reasoning-challenge" | "hypothesis-review" | "critic-resolution-audit";
92
+
93
+ export type ReasoningEvidenceRecord = {
94
+ schemaVersion: typeof REASONING_POC_VERSION;
95
+ id: string;
96
+ contextHash: string;
97
+ kind: ReasoningEvidenceKind;
98
+ source: string;
99
+ proofStrength: ProofStrength | null;
100
+ licenses?: EvidenceLicense[];
101
+ summary: string;
102
+ data: Record<string, SemanticValue>;
103
+ coverage: {
104
+ complete: boolean;
105
+ covered: string[];
106
+ unresolved: string[];
107
+ } | null;
108
+ replay: Record<string, SemanticValue> | null;
109
+ };
110
+
111
+ export type ReasoningToolName =
112
+ | "finish_evidence_collection"
113
+ | "review_observations"
114
+ | "challenge_reasoning"
115
+ | "record_hypotheses"
116
+ | "review_hypotheses"
117
+ | "finalize_reasoning_review"
118
+ | "audit_critic_resolutions"
119
+ | "analyze_game_position"
120
+ | "test_game_line"
121
+ | "inspect_position"
122
+ | "analyze_move"
123
+ | "explore_continuations"
124
+ | "compare_moves"
125
+ | "enumerate_defenses"
126
+ | "test_line"
127
+ | "trace_idea"
128
+ | "explain_plan";
129
+
130
+ export type ReasoningToolSupport = "supported" | "insufficient-evidence" | "unsupported";
131
+
132
+ export type ReasoningToolResult = {
133
+ schemaVersion: typeof REASONING_POC_VERSION;
134
+ callId: string;
135
+ tool: ReasoningToolName;
136
+ contextHash: string;
137
+ support: ReasoningToolSupport;
138
+ data: Record<string, SemanticValue>;
139
+ evidence: ReasoningEvidenceRecord[];
140
+ limitations: string[];
141
+ durationMs: number;
142
+ };
143
+
144
+ export type ReasoningToolDescriptor = {
145
+ name: ReasoningToolName;
146
+ description: string;
147
+ category: "fact" | "probe" | "graph";
148
+ inputSchema: Record<string, unknown>;
149
+ };
150
+
151
+ export interface ReasoningToolSet {
152
+ /** Native hosts reserve engine slots after legality checks, at dispatch. */
153
+ reservesSearchAtDispatch?: boolean;
154
+ descriptors(): ReasoningToolDescriptor[];
155
+ execute(
156
+ name: ReasoningToolName,
157
+ input: Record<string, unknown>,
158
+ signal?: AbortSignal,
159
+ execution?: ReasoningToolExecutionContext,
160
+ ): Promise<ReasoningToolResult>;
161
+ seedEvidence?(records: Iterable<ReasoningEvidenceRecord>): void;
162
+ }
163
+
164
+ export type ReasoningHypothesisProvenance = {
165
+ provider: string;
166
+ version: string;
167
+ origin: "model" | "learned-provider" | "reviewed-annotation" | "user";
168
+ };
169
+
170
+ export type ReasoningToolExecutionContext = {
171
+ hypothesisProvenance?: ReasoningHypothesisProvenance;
172
+ /** Reserve an answer-budgeted engine search after input/legality validation. */
173
+ reserveSearch?: () => boolean;
174
+ /** Reserve one answer-budgeted engine search before a PV endpoint continuation. */
175
+ reserveAdditionalSearch?: () => boolean;
176
+ /** Actual completed analyzer outcome; failed dispatches still consume attempts. */
177
+ recordSearchOutcome?: (outcome: 'succeeded' | 'failed') => void;
178
+ };
179
+
180
+ export type ReasoningProbeRecipe = {
181
+ tool: "inspect_position" | "analyze_move" | "enumerate_defenses" | "test_line";
182
+ input: Record<string, SemanticValue>;
183
+ purpose: string;
184
+ };
185
+
186
+ export type ReasoningObservation = {
187
+ schemaVersion: typeof REASONING_POC_VERSION;
188
+ id: string;
189
+ contextHash: string;
190
+ observationType: string;
191
+ participants: SemanticParticipant[];
192
+ attributes: Record<string, SemanticValue>;
193
+ exactness: "exact" | "heuristic";
194
+ provenance: {
195
+ provider: string;
196
+ version: string;
197
+ trust: "deterministic" | "learned" | "external";
198
+ methods: string[];
199
+ };
200
+ factEvidenceIds: string[];
201
+ probeRecipes: ReasoningProbeRecipe[];
202
+ };
203
+
204
+ export type ReasoningObservationSet = {
205
+ schemaVersion: typeof REASONING_POC_VERSION;
206
+ contextHash: string;
207
+ observations: ReasoningObservation[];
208
+ evidence: ReasoningEvidenceRecord[];
209
+ providers: Array<{ provider: string; version: string }>;
210
+ limitations: string[];
211
+ };
212
+
213
+ export type ReasoningRankedObservation = ReasoningObservation & {
214
+ salience: number;
215
+ salienceReasons: string[];
216
+ presentedToModel: boolean;
217
+ };
218
+
219
+ export type ReasoningRankedObservationSet = Omit<ReasoningObservationSet, "observations"> & {
220
+ observations: ReasoningRankedObservation[];
221
+ saliencePolicy: string;
222
+ };
223
+
224
+ /**
225
+ * The model-facing observation catalogue deliberately excludes the embedded
226
+ * evidence array. Evidence is transmitted once, through the separately
227
+ * licensed `evidence` field on HypothesisProviderInput. Keeping this shape
228
+ * explicit prevents an omitted observation or a duplicate evidence payload
229
+ * from leaking back into an isolated semantic stage.
230
+ */
231
+ export type ReasoningProviderObservationSet = Omit<ReasoningRankedObservationSet, "observations" | "evidence"> & {
232
+ observations: Array<Pick<ReasoningRankedObservation,
233
+ "id" | "observationType" | "participants" | "attributes" | "exactness" |
234
+ "provenance" | "factEvidenceIds" | "probeRecipes" | "salience" |
235
+ "salienceReasons" | "presentedToModel"
236
+ >>;
237
+ };
238
+
239
+ export interface ObservationProvider {
240
+ readonly id: string;
241
+ readonly version: string;
242
+ observe(context: ReasoningPositionContext, controls: ReasoningRunControls, signal?: AbortSignal): Promise<ReasoningObservationSet> | ReasoningObservationSet;
243
+ }
244
+
245
+ export interface SaliencePolicy {
246
+ readonly id: string;
247
+ rank(observations: ReasoningObservationSet, contract: QueryContract, graphContext?: Record<string, SemanticValue>): ReasoningRankedObservationSet;
248
+ }
249
+
250
+ export type ReasoningHypothesisRelationProposal = {
251
+ relationType: string;
252
+ from: string;
253
+ to: string;
254
+ attributes: SemanticAttributes;
255
+ evidenceIds: string[];
256
+ sourceObservationIds: string[];
257
+ };
258
+
259
+ export type HypothesisProviderInput = {
260
+ mode: "initial" | "revision";
261
+ correction?: {
262
+ attempt: 1;
263
+ rejectionStage: string;
264
+ rejectionCode: string;
265
+ rejectionDetails: string;
266
+ previousInvalidBatch: {
267
+ hypotheses: ReasoningHypothesisProposal[];
268
+ relations: ReasoningHypothesisRelationProposal[];
269
+ };
270
+ instruction: string;
271
+ };
272
+ revisionObligations: {
273
+ minimumNewHypotheses: 1;
274
+ reopenedGaps: Array<Pick<ReasoningChallengeDecision["observationAudits"][number],
275
+ "observationId" | "missingLink" | "omissionImpact" | "representedHypothesisIds"
276
+ >>;
277
+ novelHypothesisNeeded: boolean;
278
+ questionCoverageRationale: string;
279
+ hypothesisFindings: ReasoningCriticFinding[];
280
+ } | null;
281
+ contract: QueryContract;
282
+ context: ReasoningPositionContext;
283
+ observations: ReasoningProviderObservationSet;
284
+ evidence: Array<Pick<ReasoningEvidenceRecord, "id" | "kind" | "source" | "proofStrength" | "licenses" | "summary" | "data" | "coverage" | "replay">>;
285
+ existingHypotheses: Array<Pick<ReasoningHypothesisRecord,
286
+ "id" | "localId" | "entityType" | "concepts" | "owner" | "participants" | "attributes" |
287
+ "proofStrength" | "evidenceIds" | "sourceObservationIds" | "parentHypothesisIds" |
288
+ "anchorRequirements" | "origin" | "provenance" | "status"
289
+ >>;
290
+ existingRelations: Array<Pick<ReasoningHypothesisRelationRecord,
291
+ "id" | "relationType" | "fromHypothesisId" | "toHypothesisId" | "attributes" |
292
+ "evidenceIds" | "sourceObservationIds"
293
+ >>;
294
+ challenge: ReasoningChallengeDecision | null;
295
+ inspectionLenses: {
296
+ version: string;
297
+ authority: "non-evidentiary";
298
+ items: Array<{ id: string; families: string[]; text: string }>;
299
+ };
300
+ allowedVocabulary: {
301
+ entityTypes: string[];
302
+ concepts: string[];
303
+ relationTypes: string[];
304
+ participantRoles: string[];
305
+ };
306
+ allowedEvidenceIds: string[];
307
+ allowedReferences: Array<{ domain: string; id: string }>;
308
+ maxOutputTokens: number;
309
+ };
310
+
311
+ export type HypothesisProviderResult = {
312
+ batch: {
313
+ hypotheses: ReasoningHypothesisProposal[];
314
+ relations: ReasoningHypothesisRelationProposal[];
315
+ };
316
+ provenance: ReasoningHypothesisProvenance;
317
+ steps?: number;
318
+ usage?: { inputTokens: number | null; outputTokens: number | null };
319
+ diagnostics?: ReasoningRuntimeDiagnostic[];
320
+ };
321
+
322
+ export interface HypothesisProvider {
323
+ readonly id: string;
324
+ readonly version: string;
325
+ propose(input: HypothesisProviderInput, signal?: AbortSignal): Promise<HypothesisProviderResult>;
326
+ }
327
+
328
+ export type ReasoningAnchorRequirement = {
329
+ participant: SemanticParticipant;
330
+ disposition: "required";
331
+ };
332
+
333
+ export type ReasoningHypothesisProposal = {
334
+ localId: string;
335
+ entityType: string;
336
+ concepts: string[];
337
+ owner: "w" | "b" | null;
338
+ participants: SemanticParticipant[];
339
+ attributes: SemanticAttributes;
340
+ proofStrength: ProofStrength | null;
341
+ evidenceIds: string[];
342
+ sourceObservationIds: string[];
343
+ parentHypothesisIds: string[];
344
+ anchorRequirements: ReasoningAnchorRequirement[];
345
+ };
346
+
347
+ export type ReasoningHypothesisStatus = "proposed" | "needs-probe" | "accepted" | "rejected" | "superseded";
348
+
349
+ export type ReasoningHypothesisRecord = ReasoningHypothesisProposal & {
350
+ schemaVersion: typeof REASONING_POC_VERSION;
351
+ id: string;
352
+ contextHash: string;
353
+ origin: "model" | "learned-provider" | "reviewed-annotation" | "user";
354
+ provenance: { provider: string; version: string };
355
+ status: ReasoningHypothesisStatus;
356
+ review: { rationale: string; supersededBy: string[] } | null;
357
+ };
358
+
359
+ export type ReasoningHypothesisRelationRecord = {
360
+ schemaVersion: typeof REASONING_POC_VERSION;
361
+ id: string;
362
+ contextHash: string;
363
+ relationType: string;
364
+ fromHypothesisId: string;
365
+ toHypothesisId: string;
366
+ attributes: SemanticAttributes;
367
+ evidenceIds: string[];
368
+ sourceObservationIds: string[];
369
+ };
370
+
371
+ export type ReasoningHypothesisDecision = {
372
+ hypothesisId: string;
373
+ disposition: "accept" | "reject" | "needs-probe" | "supersede";
374
+ rationale: string;
375
+ supersededBy: string[];
376
+ };
377
+
378
+ export type ReasoningObservationDispositionState =
379
+ | "used"
380
+ | "irrelevant"
381
+ | "duplicate"
382
+ | "needs-probe"
383
+ | "unaddressed"
384
+ | "deferred-by-harness-budget"
385
+ | "not-presented-to-model";
386
+
387
+ export type ReasoningObservationDecision = {
388
+ observationId: string;
389
+ disposition: "used" | "irrelevant" | "duplicate" | "needs-probe";
390
+ rationale: string;
391
+ hypothesisIds: string[];
392
+ duplicateOfObservationId: string | null;
393
+ probeCallIds: string[];
394
+ };
395
+
396
+ export type ReasoningObservationCoverage = {
397
+ observationId: string;
398
+ state: ReasoningObservationDispositionState;
399
+ rationale: string | null;
400
+ hypothesisIds: string[];
401
+ duplicateOfObservationId: string | null;
402
+ probeCallIds: string[];
403
+ };
404
+
405
+ export type ReasoningChallengeObservationAudit = {
406
+ observationId: string;
407
+ action: "retain" | "reopen";
408
+ rationale: string;
409
+ missingLink: string | null;
410
+ omissionImpact: "preserves-conclusion" | "weakens-conclusion" | "uncertain";
411
+ representedHypothesisIds: string[];
412
+ };
413
+
414
+ export type ReasoningCriticFindingKind =
415
+ | "missing-link"
416
+ | "evidence-mismatch"
417
+ | "question-irrelevant"
418
+ | "overstated"
419
+ | "redundant";
420
+
421
+ export type ReasoningCriticFinding = {
422
+ id: string;
423
+ hypothesisId: string;
424
+ kind: ReasoningCriticFindingKind;
425
+ issue: string;
426
+ };
427
+
428
+ export type ReasoningCriticFindingResolutionDisposition =
429
+ | "rejected"
430
+ | "superseded"
431
+ | "retained-with-new-evidence"
432
+ | "retained-safe-to-omit"
433
+ | "resolved-by-associated-hypotheses"
434
+ | "resolved-existing-evidence";
435
+
436
+ export type ReasoningCriticFindingResolution = {
437
+ findingId: string;
438
+ hypothesisId: string;
439
+ disposition: ReasoningCriticFindingResolutionDisposition;
440
+ rationale: string;
441
+ evidenceIds: string[];
442
+ supersededBy: string[];
443
+ resolvedByHypothesisIds: string[];
444
+ };
445
+
446
+ export type ReasoningCriticResolutionAuditDecision = {
447
+ findingId: string;
448
+ hypothesisId: string;
449
+ outcome: "resolved" | "unresolved";
450
+ rationale: string;
451
+ };
452
+
453
+ export type ReasoningCriticResolutionAudit = {
454
+ decisions: ReasoningCriticResolutionAuditDecision[];
455
+ batchRationale: string;
456
+ };
457
+
458
+ /**
459
+ * Compact provenance that a completed critic audit found an already accepted
460
+ * hypothesis to represent a bounded causal or continuation meaning. It is an
461
+ * omission-audit signal only: it adds neither chess proof nor evidence
462
+ * authority, and is deliberately not a retained copy of the raw critic row.
463
+ */
464
+ export type ReasoningSemanticPreservationSignal = {
465
+ hypothesisId: string;
466
+ auditKind: "causal-evidence" | "continuation-activity";
467
+ evidenceId: string;
468
+ rootMove: string | null;
469
+ routeMoves: string[];
470
+ contact: {
471
+ attackedSquare: string;
472
+ targetMoverPieceId: string | null;
473
+ targetMoveUci: string | null;
474
+ continuationPieceId: string;
475
+ contactMoveUci: string;
476
+ } | null;
477
+ rationale: string;
478
+ };
479
+
480
+ export type ReasoningChallengeDecision = {
481
+ hypothesisIds: string[];
482
+ observationAudits: ReasoningChallengeObservationAudit[];
483
+ hypothesisFindings: ReasoningCriticFinding[];
484
+ semanticPreservationSignals: ReasoningSemanticPreservationSignal[];
485
+ novelHypothesisNeeded: boolean;
486
+ questionCoverageRationale: string;
487
+ };
488
+
489
+ export type ReasoningClaimKind = "fact" | "interpretation" | "consequence" | "defense" | "uncertainty";
490
+
491
+ export type ReasoningPieceKind = "bishop" | "king" | "knight" | "pawn" | "queen" | "rook";
492
+ export type ReasoningPieceReferenceForm = "definite" | "color-qualified" | "square-qualified" | "canonical" | "bare" | "bare-square-qualified";
493
+
494
+ export type ReasoningNarrativeSegment =
495
+ | { type: "text"; text: string }
496
+ | { type: "piece"; pieceId: string; form?: ReasoningPieceReferenceForm; capitalize?: boolean; label?: string }
497
+ | { type: "piece-kind"; pieceKind: ReasoningPieceKind; color: "w" | "b" | null; label?: string }
498
+ | { type: "square"; square: string; label?: string }
499
+ | { type: "move"; uci: string; pieceId: string; san?: string; label?: string }
500
+ | { type: "entity"; entityId: string; label?: string }
501
+ | { type: "relation"; relationId: string; fromEntityId: string; toEntityId: string; label?: string };
502
+
503
+ export type ResolvedReasoningNarrativeSegment =
504
+ | { type: "text"; text: string }
505
+ | { type: "piece"; pieceId: string; square: string | null; label: string }
506
+ | { type: "piece-kind"; pieceKind: ReasoningPieceKind; color: "w" | "b" | null; label: string }
507
+ | { type: "square"; square: string; label: string }
508
+ | { type: "move"; uci: string; pieceId: string; from: string; to: string; san: string; label: string }
509
+ | { type: "entity"; entityId: string; label: string }
510
+ | { type: "relation"; relationId: string; fromEntityId: string; toEntityId: string; relationType: string; label: string };
511
+
512
+ export type ReasoningGraphReference =
513
+ | { type: "entity"; entityId: string }
514
+ | { type: "relation"; relationId: string; fromEntityId: string; toEntityId: string };
515
+
516
+ export type ReasoningClaim = {
517
+ id: string;
518
+ kind: ReasoningClaimKind;
519
+ content: ReasoningNarrativeSegment[];
520
+ proofStrength: ProofStrength | null;
521
+ evidenceIds: string[];
522
+ graphRefs: ReasoningGraphReference[];
523
+ };
524
+
525
+ export type ValidatedReasoningClaim = Omit<ReasoningClaim, "content"> & {
526
+ content: ResolvedReasoningNarrativeSegment[];
527
+ text: string;
528
+ graphEvidenceId: string | null;
529
+ };
530
+
531
+ export type ReasoningMoveInput = { uci: string; pieceId: string };
532
+
533
+ type ReasoningDraftGraphCoverage = { graphRefs: ReasoningGraphReference[]; intentId?: string };
534
+
535
+ export type ReasoningDraftDemonstration =
536
+ | ({ id: string; type: "legal-variation"; start: "before" | "after"; moves: ReasoningMoveInput[]; label: string; evidenceIds: string[] } & ReasoningDraftGraphCoverage)
537
+ | ({ id: string; type: "conditional-route"; pieceId: string; waypoints: string[]; prerequisiteRefs: ReasoningNarrativeSegment[]; label: string; evidenceIds: string[] } & ReasoningDraftGraphCoverage)
538
+ | ({ id: string; type: "static-relationship"; from: ReasoningNarrativeSegment; to: ReasoningNarrativeSegment; relationType: string; label: string; evidenceIds: string[] } & ReasoningDraftGraphCoverage);
539
+
540
+ export type ResolvedReasoningMove = ReasoningMoveInput & { from: string; to: string; san: string; resultingFen: string };
541
+
542
+ export type ReasoningDemonstration =
543
+ ((Omit<Extract<ReasoningDraftDemonstration, { type: "legal-variation" }>, "moves"> & { moves: ResolvedReasoningMove[] })
544
+ | (Omit<Extract<ReasoningDraftDemonstration, { type: "conditional-route" }>, "prerequisiteRefs"> & { prerequisiteRefs: ResolvedReasoningNarrativeSegment[] })
545
+ | (Omit<Extract<ReasoningDraftDemonstration, { type: "static-relationship" }>, "from" | "to"> & { from: ResolvedReasoningNarrativeSegment; to: ResolvedReasoningNarrativeSegment }))
546
+ & { graphEvidenceId: string | null };
547
+
548
+ export type BoardAnnotation = { kind: "arrow" | "highlight"; from?: string; to: string; sourceRefType: "move" | "piece" | "square" | "route" };
549
+
550
+ export type ReasoningClaimScope = "conditional-plan" | "bounded-consequence" | "position-fact";
551
+
552
+ export type ReasoningDefenseCoverage = {
553
+ completeWithinClass: boolean;
554
+ completeForAllResponses: boolean;
555
+ coveredClasses: string[];
556
+ unresolvedClasses: string[];
557
+ evidenceIds: string[];
558
+ };
559
+
560
+ export type ReasoningValidationIssue = {
561
+ path: string;
562
+ code: string;
563
+ message: string;
564
+ permittedReferences: string[];
565
+ };
566
+
567
+ export type ReasoningDraft = {
568
+ claimScope: ReasoningClaimScope;
569
+ defenseCoverage: ReasoningDefenseCoverage;
570
+ claims: ReasoningClaim[];
571
+ demonstrations: ReasoningDraftDemonstration[];
572
+ limitations: string[];
573
+ };
574
+
575
+ export type ReasoningModelNarrativeSegment =
576
+ | Extract<ReasoningNarrativeSegment, { type: "text" }>
577
+ | Omit<Extract<ReasoningNarrativeSegment, { type: "piece" }>, "label">
578
+ | Omit<Extract<ReasoningNarrativeSegment, { type: "piece-kind" }>, "label">
579
+ | Omit<Extract<ReasoningNarrativeSegment, { type: "square" }>, "label">
580
+ | Omit<Extract<ReasoningNarrativeSegment, { type: "move" }>, "label">
581
+ | Omit<Extract<ReasoningNarrativeSegment, { type: "entity" }>, "label">
582
+ | Omit<Extract<ReasoningNarrativeSegment, { type: "relation" }>, "label">;
583
+
584
+ export type ReasoningModelDraftClaim = Omit<ReasoningClaim, "content" | "graphRefs"> & {
585
+ content: ReasoningModelNarrativeSegment[];
586
+ };
587
+
588
+ export type ReasoningModelDraftDemonstration =
589
+ | Omit<Extract<ReasoningDraftDemonstration, { type: "legal-variation" }>, "graphRefs">
590
+ | (Omit<Extract<ReasoningDraftDemonstration, { type: "conditional-route" }>, "graphRefs" | "prerequisiteRefs"> & {
591
+ prerequisiteRefs: ReasoningModelNarrativeSegment[];
592
+ })
593
+ | {
594
+ id: string;
595
+ type: "static-relationship";
596
+ relation: Extract<ReasoningModelNarrativeSegment, { type: "relation" }>;
597
+ label: string;
598
+ evidenceIds: string[];
599
+ };
600
+
601
+ export type ReasoningModelDraft = {
602
+ claimScope: ReasoningClaimScope;
603
+ defenseCoverage: ReasoningDefenseCoverage;
604
+ claims: ReasoningModelDraftClaim[];
605
+ demonstrations: ReasoningModelDraftDemonstration[];
606
+ limitations: string[];
607
+ };
608
+
609
+ export type ReasoningRenderNarrativeSegment =
610
+ | Exclude<ReasoningModelNarrativeSegment, { type: "relation" | "entity" }>
611
+ | { type: "entity"; entityId: string; label?: string };
612
+
613
+ export type ReasoningRenderDraftClaim = Omit<ReasoningModelDraftClaim, "content"> & {
614
+ content: ReasoningRenderNarrativeSegment[];
615
+ entityIds: string[];
616
+ };
617
+
618
+ export type ReasoningRenderDraftDemonstration =
619
+ // A legal variation is selected, not re-authored, by the presentation model.
620
+ // The frozen discourse intent identifies the bounded witness; the Harness
621
+ // replays that witness and attaches its exact moves, stable identities,
622
+ // evidence, and display label after structured output is parsed.
623
+ | { type: "legal-variation"; intentId: string }
624
+ | (Omit<Extract<ReasoningModelDraftDemonstration, { type: "conditional-route" }>, "prerequisiteRefs"> & {
625
+ intentId?: string;
626
+ prerequisiteRefs: ReasoningRenderNarrativeSegment[];
627
+ });
628
+
629
+ export type ReasoningRenderDraft = {
630
+ claims: ReasoningRenderDraftClaim[];
631
+ demonstrations: ReasoningRenderDraftDemonstration[];
632
+ };
633
+
634
+ export const REASONING_DISCOURSE_PLAN_VERSION = "reasoning-discourse-plan/2" as const;
635
+
636
+ export type ReasoningDiscourseRole = "main-idea" | "mechanism" | "practical-consequence" | "qualification";
637
+
638
+ export type ReasoningDiscourseParagraph = {
639
+ id: string;
640
+ role: ReasoningDiscourseRole;
641
+ claimKind: ReasoningClaimKind;
642
+ objective: string;
643
+ entityIds: string[];
644
+ relationIds: string[];
645
+ evidenceIds: string[];
646
+ };
647
+
648
+ export type ReasoningDiscourseRelationAction = {
649
+ relationId: string;
650
+ label: string;
651
+ };
652
+
653
+ export type ReasoningDiscourseDemonstrationIntent = {
654
+ id: string;
655
+ paragraphId: string;
656
+ type: "legal-variation" | "conditional-route";
657
+ evidenceIds: string[];
658
+ objective: string;
659
+ };
660
+
661
+ export type ReasoningDiscoursePlan = {
662
+ schemaVersion: typeof REASONING_POC_VERSION;
663
+ planVersion: typeof REASONING_DISCOURSE_PLAN_VERSION;
664
+ id: string;
665
+ checkpointId: string;
666
+ paragraphs: ReasoningDiscourseParagraph[];
667
+ relationActions: ReasoningDiscourseRelationAction[];
668
+ demonstrationIntents: ReasoningDiscourseDemonstrationIntent[];
669
+ };
670
+
671
+ export type ReasoningDiscoursePlanDraft = Pick<ReasoningDiscoursePlan, "paragraphs" | "relationActions" | "demonstrationIntents">;
672
+
673
+ export type ReasoningCheckpointEvidenceSummary = {
674
+ id: string;
675
+ kind: ReasoningEvidenceKind;
676
+ source: string;
677
+ proofStrength: ProofStrength | null;
678
+ licenses: EvidenceLicense[];
679
+ summary: string;
680
+ details: Record<string, SemanticValue>;
681
+ coverage: ReasoningEvidenceRecord["coverage"];
682
+ };
683
+
684
+ export type ReasoningReferenceScope = {
685
+ pieceIds: string[];
686
+ squares: string[];
687
+ moves: Array<ReasoningMoveInput & { san: string }>;
688
+ };
689
+
690
+ export type ReasoningCheckpointReferenceBindings = {
691
+ target: ReasoningReferenceScope;
692
+ evidence: Array<{ evidenceId: string } & ReasoningReferenceScope>;
693
+ entities: Array<{ entityId: string } & ReasoningReferenceScope>;
694
+ relations: Array<{ relationId: string } & ReasoningReferenceScope>;
695
+ };
696
+
697
+ export type ReasoningCheckpoint = {
698
+ schemaVersion: typeof REASONING_POC_VERSION;
699
+ checkpointVersion: "reasoning-checkpoint/5";
700
+ id: string;
701
+ requestId: string;
702
+ contextHash: string;
703
+ question: string;
704
+ audience: ReasoningAudience;
705
+ concise: boolean;
706
+ requestedConclusion: QueryContract["requestedConclusion"];
707
+ hypothesisLedgerRevision: string;
708
+ observationCoverage: ReasoningObservationCoverage[];
709
+ reviewedHypotheses: ReasoningHypothesisRecord[];
710
+ selectedGraph: {
711
+ evidenceId: string;
712
+ graphHash: string;
713
+ entities: SemanticEntity[];
714
+ relations: SemanticRelation[];
715
+ };
716
+ presentation: {
717
+ entities: Array<{ entityId: string; label: string }>;
718
+ relations: Array<{ relationId: string; fromEntityId: string; toEntityId: string; label: string }>;
719
+ };
720
+ approvedEvidence: ReasoningCheckpointEvidenceSummary[];
721
+ claimScope: ReasoningClaimScope;
722
+ defenseCoverage: ReasoningDefenseCoverage;
723
+ limitations: string[];
724
+ referenceBindings: ReasoningCheckpointReferenceBindings;
725
+ allowlists: {
726
+ evidenceIds: string[];
727
+ pieceIds: string[];
728
+ squares: string[];
729
+ moves: Array<ReasoningMoveInput & { san: string }>;
730
+ entityIds: string[];
731
+ relations: Array<{ relationId: string; fromEntityId: string; toEntityId: string }>;
732
+ };
733
+ obligations: {
734
+ requestedConclusion: QueryContract["requestedConclusion"];
735
+ responseCoverageRequirement: QueryContract["responseCoverageRequirement"];
736
+ continuationCoverageRequirement: QueryContract["continuationCoverageRequirement"];
737
+ minimumContinuationLines: number;
738
+ graphRequirements: ReasoningGraphRequirements;
739
+ entityIds: string[];
740
+ relations: Array<{ relationId: string; fromEntityId: string; toEntityId: string }>;
741
+ requireInterpretationClaim: boolean;
742
+ requireConditionalQualification: boolean;
743
+ };
744
+ };
745
+
746
+ export type ReasoningCompletionStage = "semantic-incomplete" | "reasoned-unrendered" | "render-invalid" | "complete";
747
+
748
+ export type ReasoningStructuralOutcome = "incomplete" | "complete";
749
+ export type ReasoningNarrativeOutcome = "not-attempted" | "unrendered" | "invalid" | "valid";
750
+ export type ReasoningInteractionCoverage = {
751
+ status: "not-assessed" | "partial" | "complete";
752
+ semanticReferenceCount: number;
753
+ interactiveReferenceCount: number;
754
+ genericReferenceCount: number;
755
+ coverageRatio: number | null;
756
+ gaps: Array<{ path: string; type: "piece-kind" | "off-board-piece" | "unbound-entity" | "unbound-relation" | "indistinguishable-entity-label"; label: string }>;
757
+ };
758
+
759
+ export type ReasoningRenderMetrics = {
760
+ inputBytes: number | null;
761
+ generatedJsonBytes: number;
762
+ inputTokens: number | null;
763
+ outputTokens: number | null;
764
+ finishReason: string | null;
765
+ validationResult: "not-attempted" | "unparseable" | "invalid" | "valid";
766
+ };
767
+
768
+ export type ReasoningToolTrace = {
769
+ callId: string;
770
+ tool: ReasoningToolName;
771
+ input: Record<string, unknown>;
772
+ support: ReasoningToolSupport;
773
+ evidenceIds: string[];
774
+ durationMs: number;
775
+ error?: string;
776
+ };
777
+
778
+ export type ReasoningHarnessPhase =
779
+ | "observations-presented"
780
+ | "hypothesis-submission-required"
781
+ | "hypotheses-recorded"
782
+ | "observations-reviewed"
783
+ | "future-purpose-planning"
784
+ | "reasoning-challenged"
785
+ | "hypotheses-revised"
786
+ | "hypotheses-reviewed"
787
+ | "critic-resolutions-audited"
788
+ | "graph-materialized"
789
+ | "checkpoint-frozen"
790
+ | "discourse-planning"
791
+ | "discourse-planning-repair"
792
+ | "discourse-planned"
793
+ | "draft-render"
794
+ | "draft-generated"
795
+ | "draft-repair";
796
+
797
+ export type ReasoningRuntimeDiagnostic = {
798
+ step: number;
799
+ provider: string;
800
+ model: string;
801
+ route: string;
802
+ sdkRuntime: string;
803
+ reasoningEffort: string;
804
+ outcome: "succeeded" | "failed" | "aborted";
805
+ httpStatus: number | null;
806
+ providerRequestId: string | null;
807
+ latencyMs: number | null;
808
+ retryCount: number | null;
809
+ finishReason: string | null;
810
+ contentPartCount: number;
811
+ textBytes: number;
812
+ toolCallCount: number;
813
+ toolCallBytes: number;
814
+ structuredOutputBytes: number;
815
+ reasoningPartCount: number;
816
+ reasoningBytes: number;
817
+ reasoningDetailsPresent: boolean;
818
+ inputTokens: number | null;
819
+ outputTokens: number | null;
820
+ outputTokenLimit: number;
821
+ requestContextBytes: number | null;
822
+ requestMessageCount: number | null;
823
+ contextCompacted: boolean;
824
+ lastHarnessPhase: ReasoningHarnessPhase;
825
+ errorCategory: string | null;
826
+ structuredOutputRecovery?: "locally-validated-json" | null;
827
+ /** Transport-only structured-output retry metadata for bounded stage recovery. */
828
+ recoveryAttempt?: number | null;
829
+ recoveryTrigger?: "output-truncated" | "output-missing" | null;
830
+ hypothesisRejectionStage?: "provider-structured-output" | "schema-validation" | "harness-validation" | null;
831
+ hypothesisRejectionCode?: "no-output" | "parse" | "schema" | "unknown-reference-or-evidence" | "unsupported-concept" | "anchor-incompatibility" | "supersession-lineage" | "critic-resolution-evidence" | "critic-resolution-incompatibility" | "used-observation-orphaned" | "empty-batch" | "evidence-license" | "proof-overstatement" | "malformed-structure" | "relation-or-budget" | "harness-validation" | null;
832
+ abortSource: "external" | "wall-time" | "provider" | null;
833
+ };
834
+
835
+ export class ModelRuntimeFailure extends Error {
836
+ readonly runtime: string;
837
+ readonly model: string;
838
+ readonly diagnostics: ReasoningRuntimeDiagnostic[];
839
+ readonly usage: { inputTokens: number | null; outputTokens: number | null };
840
+
841
+ constructor(input: {
842
+ runtime: string;
843
+ model: string;
844
+ diagnostics: ReasoningRuntimeDiagnostic[];
845
+ usage: { inputTokens: number | null; outputTokens: number | null };
846
+ }) {
847
+ super(`Model runtime failed: ${input.diagnostics.at(-1)?.errorCategory || "unknown"}`);
848
+ this.name = "ModelRuntimeFailure";
849
+ this.runtime = input.runtime;
850
+ this.model = input.model;
851
+ this.diagnostics = input.diagnostics.map((item) => ({ ...item }));
852
+ this.usage = { ...input.usage };
853
+ }
854
+ }
855
+
856
+ export type ModelRunRequest = {
857
+ schemaVersion: typeof REASONING_POC_VERSION;
858
+ contract: QueryContract;
859
+ context: ReasoningPositionContext;
860
+ contextHash: string;
861
+ observations: ReasoningRankedObservationSet;
862
+ controls: ReasoningRunControls;
863
+ };
864
+
865
+ export type ModelRunResult = {
866
+ runtime: string;
867
+ model: string;
868
+ draft?: ReasoningDraft;
869
+ trace: ReasoningToolTrace[];
870
+ steps: number;
871
+ usage: { inputTokens: number | null; outputTokens: number | null };
872
+ diagnostics?: ReasoningRuntimeDiagnostic[];
873
+ };
874
+
875
+ export interface ModelRuntime {
876
+ run(request: ModelRunRequest, tools: ReasoningToolSet, signal?: AbortSignal): Promise<ModelRunResult>;
877
+ replaySemanticStage?(request: ModelSemanticStageReplayRequest, signal?: AbortSignal): Promise<ModelSemanticStageReplayResult>;
878
+ planDiscourse?(request: ModelDiscoursePlanRequest, signal?: AbortSignal): Promise<ModelDiscoursePlanResult>;
879
+ renderCheckpoint?(request: ModelRenderRequest, signal?: AbortSignal): Promise<ModelRenderResult>;
880
+ repairDraft?(request: ModelDraftRepairRequest, signal?: AbortSignal): Promise<ModelDraftRepairResult>;
881
+ }
882
+
883
+ export type ReasoningSemanticReplayStage =
884
+ | "hypothesis-initial"
885
+ | "hypothesis-revision"
886
+ | "future-purpose-probe"
887
+ | "reasoning-critic"
888
+ | "critic-resolution-audit"
889
+ | "answer-obligation-and-graph-selection"
890
+ | "graph-selection";
891
+
892
+ export type ModelSemanticStageReplayRequest = {
893
+ schemaVersion: typeof REASONING_POC_VERSION;
894
+ stage: ReasoningSemanticReplayStage;
895
+ input: Record<string, unknown>;
896
+ };
897
+
898
+ export type ModelSemanticStageReplayResult = {
899
+ runtime: string;
900
+ model: string;
901
+ stage: ReasoningSemanticReplayStage;
902
+ output: Record<string, unknown>;
903
+ usage: { inputTokens: number | null; outputTokens: number | null };
904
+ diagnostics?: ReasoningRuntimeDiagnostic[];
905
+ };
906
+
907
+ export type ModelDiscoursePlanRequest = {
908
+ schemaVersion: typeof REASONING_POC_VERSION;
909
+ contract: QueryContract;
910
+ context: ReasoningPositionContext;
911
+ contextHash: string;
912
+ checkpoint: ReasoningCheckpoint;
913
+ };
914
+
915
+ export type ModelDiscoursePlanResult = {
916
+ runtime: string;
917
+ model: string;
918
+ plan: ReasoningDiscoursePlan;
919
+ usage: { inputTokens: number | null; outputTokens: number | null };
920
+ diagnostics?: ReasoningRuntimeDiagnostic[];
921
+ };
922
+
923
+ export type ModelRenderRequest = {
924
+ schemaVersion: typeof REASONING_POC_VERSION;
925
+ contract: QueryContract;
926
+ context: ReasoningPositionContext;
927
+ contextHash: string;
928
+ checkpoint: ReasoningCheckpoint;
929
+ discoursePlan?: ReasoningDiscoursePlan;
930
+ maxOutputChars: number;
931
+ previousValidationIssues?: ReasoningValidationIssue[];
932
+ };
933
+
934
+ export type ModelRenderResult = {
935
+ runtime: string;
936
+ model: string;
937
+ draft: ReasoningDraft;
938
+ usage: { inputTokens: number | null; outputTokens: number | null };
939
+ diagnostics?: ReasoningRuntimeDiagnostic[];
940
+ metrics: ReasoningRenderMetrics;
941
+ };
942
+
943
+ export type ModelDraftRepairRequest = {
944
+ schemaVersion: typeof REASONING_POC_VERSION;
945
+ contract: QueryContract;
946
+ context: ReasoningPositionContext;
947
+ contextHash: string;
948
+ originalDraft: ReasoningDraft;
949
+ issues: ReasoningValidationIssue[];
950
+ frozen: {
951
+ observationCoverage: ReasoningObservationCoverage[];
952
+ hypothesisLedgerRevision: string;
953
+ hypothesisIds: string[];
954
+ relationIds: string[];
955
+ graphEvidenceIds: string[];
956
+ evidenceIds: string[];
957
+ referenceAllowlists: {
958
+ pieceIds: string[];
959
+ squares: string[];
960
+ moves: Array<{ uci: string; pieceId: string; san: string }>;
961
+ };
962
+ referenceBindings: ReasoningCheckpointReferenceBindings;
963
+ claimScope: ReasoningClaimScope;
964
+ defenseCoverage: ReasoningDefenseCoverage;
965
+ };
966
+ maxOutputChars: number;
967
+ };
968
+
969
+ export type ModelDraftRepairResult = {
970
+ runtime: string;
971
+ model: string;
972
+ draft: ReasoningDraft;
973
+ usage: { inputTokens: number | null; outputTokens: number | null };
974
+ diagnostics?: ReasoningRuntimeDiagnostic[];
975
+ };
976
+
977
+ export type ValidatedReasoningAnswer = {
978
+ schemaVersion: typeof REASONING_POC_VERSION;
979
+ requestId: string;
980
+ contextHash: string;
981
+ status: "supported" | "partial" | "fact-only";
982
+ completionStage: ReasoningCompletionStage;
983
+ reasoningOutcome: ReasoningStructuralOutcome;
984
+ narrativeOutcome: ReasoningNarrativeOutcome;
985
+ interactionCoverage: ReasoningInteractionCoverage;
986
+ reasoningCheckpoint: ReasoningCheckpoint | null;
987
+ discoursePlan: ReasoningDiscoursePlan | null;
988
+ renderMetrics: ReasoningRenderMetrics;
989
+ claimScope: ReasoningClaimScope;
990
+ defenseCoverage: ReasoningDefenseCoverage;
991
+ answer: string;
992
+ claims: ValidatedReasoningClaim[];
993
+ rejectedClaims: Array<{ claim: ReasoningClaim; reasons: string[] }>;
994
+ rejectedDemonstrations: Array<{ demonstration: ReasoningDraftDemonstration; issues: ReasoningValidationIssue[] }>;
995
+ validationIssues: ReasoningValidationIssue[];
996
+ repair: { attempted: boolean; succeeded: boolean };
997
+ demonstrations: ReasoningDemonstration[];
998
+ annotations: BoardAnnotation[];
999
+ observationCoverage: ReasoningObservationCoverage[];
1000
+ hypotheses: ReasoningHypothesisRecord[];
1001
+ unverifiedCandidateHypothesisIds: string[];
1002
+ evidence: ReasoningEvidenceRecord[];
1003
+ limitations: string[];
1004
+ trace: ReasoningToolTrace[];
1005
+ runtime: string;
1006
+ model: string;
1007
+ usage: ModelRunResult["usage"];
1008
+ runtimeDiagnostics: ReasoningRuntimeDiagnostic[];
1009
+ };
1010
+
1011
+ const POSITION_CONTEXT_KEYS = new Set(["kind", "nodeId", "parentNodeId", "historyStartFen", "fenBefore", "fenAfter", "historyUci", "moveUci", "moveSan"]);
1012
+
1013
+ export function validateReasoningPositionContext(value: ReasoningPositionContext): ReasoningPositionContext {
1014
+ if (!value || typeof value !== "object") throw new Error("Reasoning position context must be an object");
1015
+ for (const key of Object.keys(value)) if (!POSITION_CONTEXT_KEYS.has(key)) throw new Error(`Unsupported reasoning position context field: ${key}`);
1016
+ if (!value.nodeId?.trim()) throw new Error("Reasoning position context requires nodeId");
1017
+ if (!Array.isArray(value.historyUci) || value.historyUci.some((move) => !/^[a-h][1-8][a-h][1-8][qrbn]?$/.test(move))) throw new Error("Reasoning position context historyUci must contain UCI moves");
1018
+ if (value.kind !== undefined && value.kind !== "position") throw new Error("Invalid context kind");
1019
+ if (!value.kind && !/^[a-h][1-8][a-h][1-8][qrbn]?$/.test(value.moveUci)) throw new Error("Reasoning position context moveUci is invalid");
1020
+ if (!value.kind && !value.moveSan?.trim()) throw new Error("Reasoning position context requires moveSan");
1021
+ const history = value.historyStartFen ? new Chess(value.historyStartFen) : new Chess();
1022
+ for (const [index, moveUci] of value.historyUci.entries()) {
1023
+ let replayed;
1024
+ try {
1025
+ replayed = history.move({ from: moveUci.slice(0, 2), to: moveUci.slice(2, 4), promotion: moveUci.slice(4) || undefined });
1026
+ } catch {
1027
+ replayed = null;
1028
+ }
1029
+ if (!replayed) throw new Error(`Reasoning position context historyUci is illegal at index ${index}`);
1030
+ }
1031
+ if (history.fen() !== new Chess(value.fenBefore).fen()) throw new Error("Reasoning position context historyUci does not replay to fenBefore");
1032
+ if (value.kind === "position") {
1033
+ if (value.moveUci !== "" || value.moveSan !== "" || value.parentNodeId || value.historyUci.length
1034
+ || value.fenBefore !== value.fenAfter || !value.historyStartFen || new Chess(value.historyStartFen).fen() !== value.fenBefore)
1035
+ throw new Error("Invalid starting-position context");
1036
+ return { ...value, historyUci: [] };
1037
+ }
1038
+ const before = new Chess(value.fenBefore);
1039
+ let applied;
1040
+ try {
1041
+ applied = before.move({ from: value.moveUci.slice(0, 2), to: value.moveUci.slice(2, 4), promotion: value.moveUci.slice(4) || undefined });
1042
+ } catch {
1043
+ applied = null;
1044
+ }
1045
+ if (!applied) throw new Error("Reasoning position context target move is illegal in fenBefore");
1046
+ if (applied.san !== value.moveSan) throw new Error("Reasoning position context moveSan does not match the target move");
1047
+ if (before.fen() !== value.fenAfter) throw new Error("Reasoning position context fenAfter does not match the target move");
1048
+ return { ...value, historyUci: [...value.historyUci] };
1049
+ }
1050
+
1051
+ export function reasoningContextHash(context: ReasoningPositionContext): string {
1052
+ const checked = validateReasoningPositionContext(context);
1053
+ return stableHash({ nodeId: checked.nodeId, parentNodeId: checked.parentNodeId || null, historyStartFen: checked.historyStartFen || null, fenBefore: checked.fenBefore, fenAfter: checked.fenAfter, historyUci: checked.historyUci, moveUci: checked.moveUci });
1054
+ }
1055
+
1056
+ export function createQueryContract(input: { requestId: string; question: string; audience?: ReasoningAudience; concise?: boolean; responseCoverageRequirement?: QueryContract["responseCoverageRequirement"]; continuationCoverageRequirement?: QueryContract["continuationCoverageRequirement"]; minimumContinuationLines?: number; graphRequirements?: Partial<ReasoningGraphRequirements>; context: ReasoningPositionContext }): QueryContract {
1057
+ if (!input.requestId?.trim()) throw new Error("Query contract requires requestId");
1058
+ if (!input.question?.trim()) throw new Error("Query contract requires a question");
1059
+ validateReasoningPositionContext(input.context);
1060
+ const responseCoverageRequirement = input.responseCoverageRequirement || "none";
1061
+ if (responseCoverageRequirement !== "none" && responseCoverageRequirement !== "bounded-class") throw new Error("Unsupported response coverage requirement");
1062
+ const continuationCoverageRequirement = input.continuationCoverageRequirement || "none";
1063
+ if (continuationCoverageRequirement !== "none" && continuationCoverageRequirement !== "principal-variation") throw new Error("Unsupported continuation coverage requirement");
1064
+ const minimumContinuationLines = input.minimumContinuationLines ?? (continuationCoverageRequirement === "principal-variation" ? 1 : 0);
1065
+ if (!Number.isInteger(minimumContinuationLines) || minimumContinuationLines < 0 || minimumContinuationLines > 3) throw new Error("minimumContinuationLines must be an integer from 0 through 3");
1066
+ if (continuationCoverageRequirement === "none" && minimumContinuationLines !== 0) throw new Error("minimumContinuationLines must be 0 when continuation coverage is not requested");
1067
+ if (continuationCoverageRequirement === "principal-variation" && minimumContinuationLines < 1) throw new Error("minimumContinuationLines must be at least 1 when principal-variation coverage is requested");
1068
+ const graphRequirements: ReasoningGraphRequirements = {
1069
+ minimumEntities: input.graphRequirements?.minimumEntities ?? 1,
1070
+ minimumRelations: input.graphRequirements?.minimumRelations ?? 0,
1071
+ };
1072
+ if (!Number.isInteger(graphRequirements.minimumEntities) || graphRequirements.minimumEntities < 1 || graphRequirements.minimumEntities > 12) throw new Error("minimumEntities must be an integer from 1 through 12");
1073
+ if (!Number.isInteger(graphRequirements.minimumRelations) || graphRequirements.minimumRelations < 0 || graphRequirements.minimumRelations > 20) throw new Error("minimumRelations must be an integer from 0 through 20");
1074
+ return { schemaVersion: REASONING_POC_VERSION, requestId: input.requestId, question: input.question.trim(), requestedConclusion: input.context.kind === "position" ? "position-question" : "move-idea", responseCoverageRequirement, continuationCoverageRequirement, minimumContinuationLines, graphRequirements, audience: input.audience || "intermediate", concise: input.concise ?? true, nodeId: input.context.nodeId };
1075
+ }
1076
+
1077
+ export function createContextEvidence(context: ReasoningPositionContext, contextHash = reasoningContextHash(context)): ReasoningEvidenceRecord {
1078
+ validateReasoningPositionContext(context);
1079
+ const identities = context.kind === "position" ? undefined : createPocIdentityTimeline(context);
1080
+ const selectedMoveMechanism = identities ? moveMechanismFacts(
1081
+ new Chess(context.fenBefore), new Chess(context.fenAfter),
1082
+ context.moveUci.slice(0, 2) as Square, context.moveUci.slice(2, 4) as Square,
1083
+ identities.before, identities.after,
1084
+ ) : undefined;
1085
+ return withEvidenceLicenses<ReasoningEvidenceRecord>({
1086
+ schemaVersion: REASONING_POC_VERSION,
1087
+ id: `evidence:context:${contextHash}`,
1088
+ contextHash,
1089
+ kind: "context",
1090
+ source: "validated-position-context",
1091
+ proofStrength: "observed",
1092
+ summary: context.kind === "position" ? "The supplied legal starting position is the question anchor; no target move has been played." : `${context.moveSan} (${context.moveUci}) is the target move in the supplied legal position.`,
1093
+ data: { ...(selectedMoveMechanism ? { selectedMoveMechanism } : {}), material: materialAlongLine(context.fenBefore, context.kind === "position" ? [] : [context.moveUci]), authority: "legal-exact", scope: "sequence-legality-and-identity", nodeId: context.nodeId, parentNodeId: context.parentNodeId || null, historyStartFen: context.historyStartFen || null, moveUci: context.moveUci, moveSan: context.moveSan, fenBefore: context.fenBefore, fenAfter: context.fenAfter },
1094
+ coverage: null,
1095
+ replay: context.kind === "position" ? { fen: context.fenBefore } : { fen: context.fenBefore, move: context.moveUci },
1096
+ });
1097
+ }