noteconnection 1.7.0 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (211) hide show
  1. package/LICENSE +674 -21
  2. package/README.md +242 -62
  3. package/dist/src/agent_workspace.contract.parity.test.js +475 -0
  4. package/dist/src/agent_workspace.frontend.test.js +9989 -0
  5. package/dist/src/agent_workspace.locale.contract.test.js +95 -0
  6. package/dist/src/agent_workspace.runtime.behavior.test.js +5072 -0
  7. package/dist/src/copy.assets.contract.test.js +130 -0
  8. package/dist/src/core/PathBridge.js +28 -3
  9. package/dist/src/export/WorkspaceExportBundle.js +1130 -0
  10. package/dist/src/export/WorkspaceExportBundle.test.js +1480 -0
  11. package/dist/src/export/index.js +18 -0
  12. package/dist/src/export/types.js +2 -0
  13. package/dist/src/fixrisk.issue.verifier.contract.test.js +3 -1
  14. package/dist/src/foundation.ann.runtime.contract.test.js +81 -0
  15. package/dist/src/foundation.release.evidence.contract.test.js +406 -0
  16. package/dist/src/foundation.sqlite.runtime.contract.test.js +82 -0
  17. package/dist/src/frontend/README.md +242 -62
  18. package/dist/src/frontend/agent_workspace.js +5353 -0
  19. package/dist/src/frontend/agent_workspace_runtime.js +4434 -0
  20. package/dist/src/frontend/analysis.js +31 -4
  21. package/dist/src/frontend/app.js +2178 -62
  22. package/dist/src/frontend/focus_mode_interactions.js +33 -0
  23. package/dist/src/frontend/godot_future_path_renderer.js +540 -0
  24. package/dist/src/frontend/godot_tree_interactions.js +178 -0
  25. package/dist/src/frontend/graph_state.mjs +105 -0
  26. package/dist/src/frontend/hosted_future_path_runtime.js +157 -0
  27. package/dist/src/frontend/i18n.mjs +186 -0
  28. package/dist/src/frontend/index.html +641 -266
  29. package/dist/src/frontend/layout_gpu.js +12 -4
  30. package/dist/src/frontend/locales/en.json +721 -5
  31. package/dist/src/frontend/locales/zh.json +721 -5
  32. package/dist/src/frontend/main.mjs +60 -0
  33. package/dist/src/frontend/markdown_runtime.js +827 -0
  34. package/dist/src/frontend/notemd.css +49 -0
  35. package/dist/src/frontend/notemd.html +7 -1
  36. package/dist/src/frontend/notemd.js +64 -0
  37. package/dist/src/frontend/path.html +107 -0
  38. package/dist/src/frontend/path_app.js +2108 -130
  39. package/dist/src/frontend/path_layout.mjs +143 -0
  40. package/dist/src/frontend/path_mermaid_utils.mjs +108 -0
  41. package/dist/src/frontend/path_modules_bridge.js +486 -0
  42. package/dist/src/frontend/path_state.mjs +118 -0
  43. package/dist/src/frontend/path_styles.css +146 -0
  44. package/dist/src/frontend/path_worker_bridge.mjs +85 -0
  45. package/dist/src/frontend/reader.js +393 -33
  46. package/dist/src/frontend/runtime_bridge.js +67 -54
  47. package/dist/src/frontend/runtime_bridge.mjs +279 -0
  48. package/dist/src/frontend/settings.js +130 -12
  49. package/dist/src/frontend/source_manager.js +190 -21
  50. package/dist/src/frontend/styles.css +2720 -72
  51. package/dist/src/frontend/workbench_state.mjs +101 -0
  52. package/dist/src/frontend/workspace_panes.js +10168 -0
  53. package/dist/src/frontend.locale.contract.test.js +62 -0
  54. package/dist/src/godot.sidecar.bootstrap.contract.test.js +244 -0
  55. package/dist/src/indexing/IndexLifecycle.js +195 -0
  56. package/dist/src/indexing/IndexLifecycle.test.js +49 -0
  57. package/dist/src/indexing/SegmentBuilder.js +64 -0
  58. package/dist/src/indexing/UnitBuilder.js +48 -0
  59. package/dist/src/indexing/types.js +2 -0
  60. package/dist/src/knowledge.api.contract.test.js +170 -0
  61. package/dist/src/learning/KnowledgeLearningPlatform.js +10386 -0
  62. package/dist/src/learning/KnowledgeLearningPlatform.persistence.test.js +327 -0
  63. package/dist/src/learning/KnowledgeLearningPlatform.program-f.test.js +99 -0
  64. package/dist/src/learning/KnowledgeLearningPlatform.test.js +2971 -0
  65. package/dist/src/learning/KnowledgeWorkspaceConversationRegression.js +2974 -0
  66. package/dist/src/learning/KnowledgeWorkspaceConversationRegression.test.js +3928 -0
  67. package/dist/src/learning/answerReleaseReview.js +4319 -0
  68. package/dist/src/learning/answerReleaseReview.test.js +2888 -0
  69. package/dist/src/learning/api.js +2 -0
  70. package/dist/src/learning/conversationComposer.js +1480 -0
  71. package/dist/src/learning/conversationComposer.test.js +1817 -0
  72. package/dist/src/learning/domains/ConversationManager.js +53 -0
  73. package/dist/src/learning/domains/KnowledgeIngestor.js +238 -0
  74. package/dist/src/learning/domains/KnowledgeQuerier.js +187 -0
  75. package/dist/src/learning/domains/MasteryEngine.js +387 -0
  76. package/dist/src/learning/domains/MemoryPolicyManager.js +408 -0
  77. package/dist/src/learning/domains/QualityEvaluator.js +307 -0
  78. package/dist/src/learning/domains/TutorRouter.js +313 -0
  79. package/dist/src/learning/domains/index.js +33 -0
  80. package/dist/src/learning/domains/types.js +7 -0
  81. package/dist/src/learning/errors.js +29 -0
  82. package/dist/src/learning/evidenceContextAssembler.js +1176 -0
  83. package/dist/src/learning/evidenceContextAssembler.test.js +6332 -0
  84. package/dist/src/learning/graphContextAssembler.js +870 -0
  85. package/dist/src/learning/graphContextAssembler.test.js +1033 -0
  86. package/dist/src/learning/index.js +28 -0
  87. package/dist/src/learning/queryBackend.js +1898 -0
  88. package/dist/src/learning/queryBackend.test.js +955 -0
  89. package/dist/src/learning/ragContextPack.js +257 -0
  90. package/dist/src/learning/ragContextPack.test.js +160 -0
  91. package/dist/src/learning/ragPublicText.js +38 -0
  92. package/dist/src/learning/ragSufficiencyJudge.js +161 -0
  93. package/dist/src/learning/ragSufficiencyJudge.test.js +177 -0
  94. package/dist/src/learning/ragSufficiencyProviderJudge.js +227 -0
  95. package/dist/src/learning/ragSufficiencyProviderJudge.test.js +156 -0
  96. package/dist/src/learning/requestNormalization.js +198 -0
  97. package/dist/src/learning/runtimeCapability.js +4677 -0
  98. package/dist/src/learning/runtimeCapability.test.js +3635 -0
  99. package/dist/src/learning/store.js +1240 -0
  100. package/dist/src/learning/store.test.js +1126 -0
  101. package/dist/src/learning/tutorAdapter.js +2 -0
  102. package/dist/src/learning/types.js +2 -0
  103. package/dist/src/learning/vectorAccelerationAdapter.js +942 -0
  104. package/dist/src/learning/vectorAccelerationAdapter.test.js +382 -0
  105. package/dist/src/lfs.asset.policy.contract.test.js +153 -0
  106. package/dist/src/license.policy.contract.test.js +66 -0
  107. package/dist/src/memory/MemoryGovernance.js +74 -0
  108. package/dist/src/memory/MemoryGovernance.test.js +46 -0
  109. package/dist/src/memory/types.js +2 -0
  110. package/dist/src/mermaid.frontend.guard.contract.test.js +77 -0
  111. package/dist/src/middleware/auth.js +17 -0
  112. package/dist/src/middleware/body-parser.js +45 -0
  113. package/dist/src/middleware/cors.js +44 -0
  114. package/dist/src/middleware/index.js +21 -0
  115. package/dist/src/middleware/request-trace.js +96 -0
  116. package/dist/src/notemd/AppConfigToml.js +6 -4
  117. package/dist/src/notemd/MermaidProcessor.js +400 -50
  118. package/dist/src/notemd/NotemdService.js +498 -13
  119. package/dist/src/notemd/PromptManager.js +15 -0
  120. package/dist/src/notemd/cli/commands.js +357 -0
  121. package/dist/src/notemd/cli/dispatcher.js +225 -0
  122. package/dist/src/notemd/cli/index.js +169 -0
  123. package/dist/src/notemd/cli/parser.js +68 -0
  124. package/dist/src/notemd/cli/types.js +2 -0
  125. package/dist/src/notemd/constants.js +43 -0
  126. package/dist/src/notemd/diagram/diagramGenerationService.js +78 -0
  127. package/dist/src/notemd/diagram/diagramSpec.js +79 -0
  128. package/dist/src/notemd/diagram/diagramSpecResponseParser.js +131 -0
  129. package/dist/src/notemd/diagram/intent.js +95 -0
  130. package/dist/src/notemd/diagram/planner.js +71 -0
  131. package/dist/src/notemd/diagram/prompts/diagramSpecPrompt.js +42 -0
  132. package/dist/src/notemd/diagram/types.js +18 -0
  133. package/dist/src/notemd/index.js +26 -0
  134. package/dist/src/notemd/operations/capabilityManifest.js +23 -0
  135. package/dist/src/notemd/operations/cliContracts.js +17 -0
  136. package/dist/src/notemd/operations/configProfileCommands.js +85 -0
  137. package/dist/src/notemd/operations/registry.contract.test.js +95 -0
  138. package/dist/src/notemd/operations/registry.js +991 -0
  139. package/dist/src/notemd/operations/types.js +2 -0
  140. package/dist/src/notemd/providerDiagnostics.js +220 -0
  141. package/dist/src/notemd/providerProfiles.js +42 -0
  142. package/dist/src/notemd/providerTemplates.js +231 -0
  143. package/dist/src/notemd/search/DuckDuckGoProvider.js +39 -0
  144. package/dist/src/notemd/search/SearchManager.js +13 -0
  145. package/dist/src/notemd/search/SearchProvider.js +2 -0
  146. package/dist/src/notemd/search/TavilyProvider.js +44 -0
  147. package/dist/src/notemd.agent.manifest.test.js +85 -0
  148. package/dist/src/notemd.api.contract.test.js +14 -1
  149. package/dist/src/notemd.app_config_toml.test.js +2 -1
  150. package/dist/src/notemd.batch.workflow.test.js +117 -0
  151. package/dist/src/notemd.cli.e2e.test.js +136 -0
  152. package/dist/src/notemd.core.test.js +51 -0
  153. package/dist/src/notemd.diagram.pipeline.test.js +233 -0
  154. package/dist/src/notemd.providerTemplates.test.js +34 -0
  155. package/dist/src/notemd.server.integration.test.js +143 -35
  156. package/dist/src/notemd.workflow.pipeline.test.js +162 -0
  157. package/dist/src/pathbridge.handshake.contract.test.js +16 -2
  158. package/dist/src/pathmode.background.contract.test.js +69 -0
  159. package/dist/src/pathmode.settings.api.contract.test.js +9 -0
  160. package/dist/src/pkg.sidecar.contract.test.js +9 -3
  161. package/dist/src/platform/ExportProfile.js +58 -0
  162. package/dist/src/platform/PlatformCapabilities.js +45 -0
  163. package/dist/src/platform/PlatformCapabilities.test.js +30 -0
  164. package/dist/src/platform/RenderMaterializer.js +33 -0
  165. package/dist/src/platform/RenderMaterializer.test.js +32 -0
  166. package/dist/src/query_backend.external_http.integration.test.js +410 -0
  167. package/dist/src/reader_renderer.js +404 -3
  168. package/dist/src/reader_renderer.test.js +87 -0
  169. package/dist/src/release.godot.mirror.contract.test.js +73 -0
  170. package/dist/src/resources/ResourceRegistry.js +223 -0
  171. package/dist/src/resources/ResourceRegistry.test.js +61 -0
  172. package/dist/src/resources/types.js +2 -0
  173. package/dist/src/routes/agentWorkspaceDiagnostics.js +173 -0
  174. package/dist/src/routes/data.js +267 -0
  175. package/dist/src/routes/diagnostics.js +51 -0
  176. package/dist/src/routes/index.js +23 -0
  177. package/dist/src/routes/knowledge.js +968 -0
  178. package/dist/src/routes/markdown.js +287 -0
  179. package/dist/src/routes/notemd.js +565 -0
  180. package/dist/src/routes/registry.contract.test.js +130 -0
  181. package/dist/src/routes/render.js +285 -0
  182. package/dist/src/routes/runtimeRunbookRouteOps.js +149 -0
  183. package/dist/src/routes/runtimeRunbookRouteOps.test.js +194 -0
  184. package/dist/src/routes/settings.js +6 -0
  185. package/dist/src/routes/staticFiles.js +94 -0
  186. package/dist/src/routes/types.js +2 -0
  187. package/dist/src/runtime.transport.adapter.contract.test.js +81 -0
  188. package/dist/src/server.js +11090 -1549
  189. package/dist/src/server.migration.test.js +193 -21
  190. package/dist/src/server.port.fallback.contract.test.js +63 -0
  191. package/dist/src/session/SessionStateStore.js +81 -0
  192. package/dist/src/session/SessionStateStore.test.js +58 -0
  193. package/dist/src/session/types.js +2 -0
  194. package/dist/src/settings.runtime.contract.test.js +50 -0
  195. package/dist/src/shared/types.contract.test.js +107 -0
  196. package/dist/src/shared/types.js +22 -0
  197. package/dist/src/sidecar.replacement.boundary.contract.test.js +128 -0
  198. package/dist/src/sidecar.supply.readiness.contract.test.js +144 -0
  199. package/dist/src/source_manager.loadflow.test.js +46 -0
  200. package/dist/src/startup.layout.snapshot.contract.test.js +57 -0
  201. package/dist/src/tauri.frontend.build.contract.test.js +60 -0
  202. package/dist/src/tauri.sidecar.cleanup.contract.test.js +21 -0
  203. package/dist/src/utils/RuntimePaths.js +4 -13
  204. package/dist/src/utils/platform.js +153 -0
  205. package/dist/src/workflows/WorkflowArtifactStore.js +96 -0
  206. package/dist/src/workflows/WorkflowArtifactStore.test.js +80 -0
  207. package/dist/src/workflows/types.js +2 -0
  208. package/dist/src/workspace/WorkspaceRegistry.js +122 -0
  209. package/dist/src/workspace/WorkspaceRegistry.test.js +29 -0
  210. package/dist/src/workspace/types.js +2 -0
  211. package/package.json +53 -10
@@ -0,0 +1,1130 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildWorkspaceExportBundle = buildWorkspaceExportBundle;
4
+ const crypto_1 = require("crypto");
5
+ const PlatformCapabilities_1 = require("../platform/PlatformCapabilities");
6
+ const RenderMaterializer_1 = require("../platform/RenderMaterializer");
7
+ function compareStrings(left, right) {
8
+ return String(left || '').localeCompare(String(right || ''));
9
+ }
10
+ function cloneJsonRecord(value) {
11
+ return { ...value };
12
+ }
13
+ function cloneRagContextPack(pack) {
14
+ if (!pack) {
15
+ return undefined;
16
+ }
17
+ return {
18
+ ...pack,
19
+ budget: { ...pack.budget },
20
+ fragments: pack.fragments.map((fragment) => ({
21
+ ...fragment,
22
+ headingPath: [...fragment.headingPath],
23
+ citationIds: [...fragment.citationIds],
24
+ relationEdgeIds: Array.isArray(fragment.relationEdgeIds)
25
+ ? [...fragment.relationEdgeIds]
26
+ : fragment.relationEdgeIds,
27
+ })),
28
+ sourceDecisions: pack.sourceDecisions.map((decision) => ({ ...decision })),
29
+ };
30
+ }
31
+ function cloneRagSufficiencyReview(review) {
32
+ if (!review) {
33
+ return undefined;
34
+ }
35
+ return {
36
+ ...review,
37
+ reasons: [...review.reasons],
38
+ };
39
+ }
40
+ function cloneRagEvidenceRecoveryTrace(recovery) {
41
+ if (!recovery) {
42
+ return undefined;
43
+ }
44
+ return {
45
+ ...recovery,
46
+ addedRoleCounts: { ...recovery.addedRoleCounts },
47
+ beforeReasons: Array.isArray(recovery.beforeReasons)
48
+ ? recovery.beforeReasons.slice()
49
+ : recovery.beforeReasons,
50
+ afterReasons: Array.isArray(recovery.afterReasons)
51
+ ? recovery.afterReasons.slice()
52
+ : recovery.afterReasons,
53
+ beforeSourceDecisionStatusCounts: recovery.beforeSourceDecisionStatusCounts
54
+ ? { ...recovery.beforeSourceDecisionStatusCounts }
55
+ : recovery.beforeSourceDecisionStatusCounts,
56
+ afterSourceDecisionStatusCounts: recovery.afterSourceDecisionStatusCounts
57
+ ? { ...recovery.afterSourceDecisionStatusCounts }
58
+ : recovery.afterSourceDecisionStatusCounts,
59
+ };
60
+ }
61
+ function cloneRagFailureClassifications(classifications) {
62
+ if (!Array.isArray(classifications)) {
63
+ return undefined;
64
+ }
65
+ return classifications.map((classification) => ({
66
+ ...classification,
67
+ evidence: Array.isArray(classification.evidence)
68
+ ? classification.evidence.slice()
69
+ : [],
70
+ }));
71
+ }
72
+ function cloneAnswerClaimCitations(claims) {
73
+ if (!Array.isArray(claims)) {
74
+ return undefined;
75
+ }
76
+ return claims.map((claim) => ({
77
+ ...claim,
78
+ citationIds: Array.isArray(claim.citationIds) ? claim.citationIds.slice() : [],
79
+ fragmentIds: Array.isArray(claim.fragmentIds) ? claim.fragmentIds.slice() : [],
80
+ sourcePaths: Array.isArray(claim.sourcePaths) ? claim.sourcePaths.slice() : [],
81
+ }));
82
+ }
83
+ function sortAndCloneBindings(bindings) {
84
+ return bindings
85
+ .slice()
86
+ .sort((left, right) => compareStrings(left.bindingId, right.bindingId))
87
+ .map((binding) => ({ ...binding }));
88
+ }
89
+ function sortAndCloneResources(resources) {
90
+ return resources
91
+ .slice()
92
+ .sort((left, right) => compareStrings(left.resourceId, right.resourceId))
93
+ .map((resource) => ({
94
+ ...resource,
95
+ metadata: cloneJsonRecord(resource.metadata || {}),
96
+ }));
97
+ }
98
+ function sortAndCloneProjections(projections) {
99
+ return projections
100
+ .slice()
101
+ .sort((left, right) => compareStrings(left.projectionId, right.projectionId))
102
+ .map((projection) => ({
103
+ ...projection,
104
+ metadata: cloneJsonRecord(projection.metadata || {}),
105
+ }));
106
+ }
107
+ function sortAndCloneUnits(units) {
108
+ return units
109
+ .slice()
110
+ .sort((left, right) => compareStrings(left.unitId, right.unitId))
111
+ .map((unit) => ({
112
+ ...unit,
113
+ segmentIds: [...unit.segmentIds],
114
+ }));
115
+ }
116
+ function sortAndCloneSegments(segments) {
117
+ return segments
118
+ .slice()
119
+ .sort((left, right) => compareStrings(left.segmentId, right.segmentId))
120
+ .map((segment) => ({ ...segment }));
121
+ }
122
+ function sortAndCloneAtoms(atoms) {
123
+ return atoms
124
+ .slice()
125
+ .sort((left, right) => compareStrings(left.id, right.id))
126
+ .map((atom) => ({
127
+ ...atom,
128
+ keywords: [...atom.keywords],
129
+ evidenceSpanIds: [...atom.evidenceSpanIds],
130
+ metadata: {
131
+ ...atom.metadata,
132
+ sectionPath: [...atom.metadata.sectionPath],
133
+ },
134
+ }));
135
+ }
136
+ function sortAndCloneEvidenceSpans(evidenceSpans) {
137
+ return evidenceSpans
138
+ .slice()
139
+ .sort((left, right) => compareStrings(left.id, right.id))
140
+ .map((span) => ({ ...span }));
141
+ }
142
+ function sortAndCloneRelationEdges(relationEdges) {
143
+ return relationEdges
144
+ .slice()
145
+ .sort((left, right) => compareStrings(left.id, right.id))
146
+ .map((edge) => ({
147
+ ...edge,
148
+ evidenceSpanIds: [...edge.evidenceSpanIds],
149
+ temporal: { ...edge.temporal },
150
+ }));
151
+ }
152
+ function sortAndCloneTemporalEdges(temporalEdges) {
153
+ return temporalEdges
154
+ .slice()
155
+ .sort((left, right) => compareStrings(left.id, right.id))
156
+ .map((edge) => ({ ...edge }));
157
+ }
158
+ function sortAndCloneSessionStates(sessionStates) {
159
+ return sessionStates
160
+ .slice()
161
+ .sort((left, right) => compareStrings(left.sessionStateId, right.sessionStateId))
162
+ .map((state) => ({
163
+ ...state,
164
+ activeResourceIds: [...state.activeResourceIds],
165
+ activeProjectionIds: [...state.activeProjectionIds],
166
+ retrievalSettings: { ...state.retrievalSettings },
167
+ memorySettings: { ...state.memorySettings },
168
+ panelState: cloneJsonRecord(state.panelState || {}),
169
+ }));
170
+ }
171
+ function sortAndCloneConversationSessions(records) {
172
+ return records
173
+ .slice()
174
+ .sort((left, right) => compareStrings(left.sessionId, right.sessionId))
175
+ .map((record) => ({
176
+ ...record,
177
+ turnIds: [...record.turnIds],
178
+ }));
179
+ }
180
+ function sortAndCloneConversationTurns(records) {
181
+ return records
182
+ .slice()
183
+ .sort((left, right) => compareStrings(left.turnId, right.turnId))
184
+ .map((record) => ({
185
+ ...record,
186
+ request: { ...record.request },
187
+ response: {
188
+ ...record.response,
189
+ knowledgePoints: record.response.knowledgePoints.map((point) => ({
190
+ ...point,
191
+ capabilities: [...point.capabilities],
192
+ citation: point.citation ? { ...point.citation } : null,
193
+ citations: Array.isArray(point.citations)
194
+ ? point.citations.map((citation) => ({ ...citation }))
195
+ : point.citations,
196
+ matchedSpans: Array.isArray(point.matchedSpans)
197
+ ? point.matchedSpans.map((span) => ({
198
+ ...span,
199
+ citation: span.citation ? { ...span.citation } : null,
200
+ }))
201
+ : point.matchedSpans,
202
+ relationPath: Array.isArray(point.relationPath)
203
+ ? point.relationPath.map((edge) => ({ ...edge }))
204
+ : point.relationPath,
205
+ relationPathAtomIds: Array.isArray(point.relationPathAtomIds)
206
+ ? [...point.relationPathAtomIds]
207
+ : point.relationPathAtomIds,
208
+ relationKinds: Array.isArray(point.relationKinds)
209
+ ? [...point.relationKinds]
210
+ : point.relationKinds,
211
+ temporalValidity: point.temporalValidity
212
+ ? {
213
+ ...point.temporalValidity,
214
+ reasons: Array.isArray(point.temporalValidity.reasons)
215
+ ? [...point.temporalValidity.reasons]
216
+ : [],
217
+ details: Array.isArray(point.temporalValidity.details)
218
+ ? point.temporalValidity.details.map((detail) => ({ ...detail }))
219
+ : [],
220
+ }
221
+ : point.temporalValidity,
222
+ })),
223
+ citations: record.response.citations.map((citation) => ({ ...citation })),
224
+ recalledMemories: record.response.recalledMemories.map((memory) => ({
225
+ ...memory,
226
+ tags: [...memory.tags],
227
+ references: [...memory.references],
228
+ })),
229
+ memoryActions: record.response.memoryActions.map((action) => ({ ...action })),
230
+ summary: { ...record.response.summary },
231
+ trace: {
232
+ ...record.response.trace,
233
+ retrieval: {
234
+ ...record.response.trace.retrieval,
235
+ retrievalModes: [...record.response.trace.retrieval.retrievalModes],
236
+ modeWeights: { ...record.response.trace.retrieval.modeWeights },
237
+ planner: record.response.trace.retrieval.planner
238
+ ? {
239
+ ...record.response.trace.retrieval.planner,
240
+ titleLikeQueries: [...(record.response.trace.retrieval.planner.titleLikeQueries || [])],
241
+ titleHitDocumentIds: [...(record.response.trace.retrieval.planner.titleHitDocumentIds || [])],
242
+ }
243
+ : undefined,
244
+ scope: record.response.trace.retrieval.scope ? {
245
+ ...record.response.trace.retrieval.scope,
246
+ documentIds: [...record.response.trace.retrieval.scope.documentIds],
247
+ atomIds: [...record.response.trace.retrieval.scope.atomIds],
248
+ sourcePathPrefixes: [...record.response.trace.retrieval.scope.sourcePathPrefixes],
249
+ languages: [...record.response.trace.retrieval.scope.languages],
250
+ } : undefined,
251
+ },
252
+ usedScope: {
253
+ ...record.response.trace.usedScope,
254
+ documentIds: [...record.response.trace.usedScope.documentIds],
255
+ atomIds: [...record.response.trace.usedScope.atomIds],
256
+ sourcePathPrefixes: [...record.response.trace.usedScope.sourcePathPrefixes],
257
+ languages: [...record.response.trace.usedScope.languages],
258
+ readiness: record.response.trace.usedScope.readiness
259
+ ? { ...record.response.trace.usedScope.readiness }
260
+ : undefined,
261
+ missDiagnostics: record.response.trace.usedScope.missDiagnostics
262
+ ? {
263
+ ...record.response.trace.usedScope.missDiagnostics,
264
+ titleLikeQueries: [...(record.response.trace.usedScope.missDiagnostics.titleLikeQueries || [])],
265
+ titleHitDocumentIds: [...(record.response.trace.usedScope.missDiagnostics.titleHitDocumentIds || [])],
266
+ }
267
+ : undefined,
268
+ },
269
+ workspaceReadiness: record.response.trace.workspaceReadiness
270
+ ? { ...record.response.trace.workspaceReadiness }
271
+ : undefined,
272
+ missDiagnostics: record.response.trace.missDiagnostics
273
+ ? {
274
+ ...record.response.trace.missDiagnostics,
275
+ titleLikeQueries: [...(record.response.trace.missDiagnostics.titleLikeQueries || [])],
276
+ titleHitDocumentIds: [...(record.response.trace.missDiagnostics.titleHitDocumentIds || [])],
277
+ }
278
+ : undefined,
279
+ planner: record.response.trace.planner
280
+ ? {
281
+ ...record.response.trace.planner,
282
+ titleLikeQueries: [...(record.response.trace.planner.titleLikeQueries || [])],
283
+ titleHitDocumentIds: [...(record.response.trace.planner.titleHitDocumentIds || [])],
284
+ }
285
+ : undefined,
286
+ graphContext: record.response.trace.graphContext
287
+ ? {
288
+ ...record.response.trace.graphContext,
289
+ supportingAtomIds: Array.isArray(record.response.trace.graphContext.supportingAtomIds)
290
+ ? [...record.response.trace.graphContext.supportingAtomIds]
291
+ : [],
292
+ supportingTitles: Array.isArray(record.response.trace.graphContext.supportingTitles)
293
+ ? [...record.response.trace.graphContext.supportingTitles]
294
+ : [],
295
+ relationKinds: Array.isArray(record.response.trace.graphContext.relationKinds)
296
+ ? [...record.response.trace.graphContext.relationKinds]
297
+ : [],
298
+ relationSummaries: Array.isArray(record.response.trace.graphContext.relationSummaries)
299
+ ? record.response.trace.graphContext.relationSummaries.map((summary) => ({
300
+ ...summary,
301
+ edgeIds: Array.isArray(summary.edgeIds) ? [...summary.edgeIds] : [],
302
+ sourceAtomIds: Array.isArray(summary.sourceAtomIds) ? [...summary.sourceAtomIds] : [],
303
+ targetAtomIds: Array.isArray(summary.targetAtomIds) ? [...summary.targetAtomIds] : [],
304
+ }))
305
+ : [],
306
+ knowledgePointRelations: Array.isArray(record.response.trace.graphContext.knowledgePointRelations)
307
+ ? record.response.trace.graphContext.knowledgePointRelations.map((relation) => ({
308
+ ...relation,
309
+ }))
310
+ : [],
311
+ connectionPaths: Array.isArray(record.response.trace.graphContext.connectionPaths)
312
+ ? record.response.trace.graphContext.connectionPaths.map((connectionPath) => ({
313
+ ...connectionPath,
314
+ pathAtomIds: Array.isArray(connectionPath.pathAtomIds) ? [...connectionPath.pathAtomIds] : [],
315
+ pathTitles: Array.isArray(connectionPath.pathTitles) ? [...connectionPath.pathTitles] : [],
316
+ pathEdges: Array.isArray(connectionPath.pathEdges)
317
+ ? connectionPath.pathEdges.map((edge) => ({ ...edge }))
318
+ : [],
319
+ }))
320
+ : [],
321
+ predecessorWindow: Array.isArray(record.response.trace.graphContext.predecessorWindow)
322
+ ? record.response.trace.graphContext.predecessorWindow.map((node) => ({
323
+ ...node,
324
+ }))
325
+ : [],
326
+ successorWindow: Array.isArray(record.response.trace.graphContext.successorWindow)
327
+ ? record.response.trace.graphContext.successorWindow.map((node) => ({
328
+ ...node,
329
+ }))
330
+ : [],
331
+ evidenceSourceRefs: Array.isArray(record.response.trace.graphContext.evidenceSourceRefs)
332
+ ? [...record.response.trace.graphContext.evidenceSourceRefs]
333
+ : [],
334
+ diagnostics: record.response.trace.graphContext.diagnostics
335
+ ? {
336
+ ...record.response.trace.graphContext.diagnostics,
337
+ missingConnectionPathSourceAtomIds: Array.isArray(record.response.trace.graphContext.diagnostics.missingConnectionPathSourceAtomIds)
338
+ ? [...record.response.trace.graphContext.diagnostics.missingConnectionPathSourceAtomIds]
339
+ : [],
340
+ missingPredecessorAtomIds: Array.isArray(record.response.trace.graphContext.diagnostics.missingPredecessorAtomIds)
341
+ ? [...record.response.trace.graphContext.diagnostics.missingPredecessorAtomIds]
342
+ : [],
343
+ missingSuccessorAtomIds: Array.isArray(record.response.trace.graphContext.diagnostics.missingSuccessorAtomIds)
344
+ ? [...record.response.trace.graphContext.diagnostics.missingSuccessorAtomIds]
345
+ : [],
346
+ }
347
+ : undefined,
348
+ temporalValidity: record.response.trace.graphContext.temporalValidity
349
+ ? {
350
+ ...record.response.trace.graphContext.temporalValidity,
351
+ warningReasons: Array.isArray(record.response.trace.graphContext.temporalValidity.warningReasons)
352
+ ? [...record.response.trace.graphContext.temporalValidity.warningReasons]
353
+ : [],
354
+ invalidKnowledgePointTitles: Array.isArray(record.response.trace.graphContext.temporalValidity.invalidKnowledgePointTitles)
355
+ ? [...record.response.trace.graphContext.temporalValidity.invalidKnowledgePointTitles]
356
+ : [],
357
+ edgeKinds: Array.isArray(record.response.trace.graphContext.temporalValidity.edgeKinds)
358
+ ? [...record.response.trace.graphContext.temporalValidity.edgeKinds]
359
+ : [],
360
+ details: Array.isArray(record.response.trace.graphContext.temporalValidity.details)
361
+ ? record.response.trace.graphContext.temporalValidity.details.map((detail) => ({ ...detail }))
362
+ : [],
363
+ }
364
+ : undefined,
365
+ }
366
+ : undefined,
367
+ ragContextPack: cloneRagContextPack(record.response.trace.ragContextPack),
368
+ ragSufficiencyReview: cloneRagSufficiencyReview(record.response.trace.ragSufficiencyReview),
369
+ ragRecovery: cloneRagEvidenceRecoveryTrace(record.response.trace.ragRecovery),
370
+ ragFailureClassifications: cloneRagFailureClassifications(record.response.trace.ragFailureClassifications),
371
+ answerClaimCitations: cloneAnswerClaimCitations(record.response.trace.answerClaimCitations),
372
+ },
373
+ },
374
+ }));
375
+ }
376
+ function sortAndCloneConversationInvocations(records) {
377
+ return records
378
+ .slice()
379
+ .sort((left, right) => compareStrings(left.invocationId, right.invocationId))
380
+ .map((record) => ({ ...record }));
381
+ }
382
+ function sortAndCloneWorkflowArtifacts(records) {
383
+ return records
384
+ .slice()
385
+ .sort((left, right) => compareStrings(left.artifactId, right.artifactId))
386
+ .map((record) => ({
387
+ ...record,
388
+ sourceResourceIds: [...record.sourceResourceIds],
389
+ sourceProjectionIds: [...record.sourceProjectionIds],
390
+ payload: cloneJsonRecord(record.payload || {}),
391
+ }));
392
+ }
393
+ function isRecord(value) {
394
+ return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
395
+ }
396
+ function normalizeCount(value) {
397
+ return Number.isFinite(Number(value)) ? Math.max(0, Math.floor(Number(value))) : 0;
398
+ }
399
+ function normalizeOptionalScore(value) {
400
+ return Number.isFinite(Number(value)) ? Number(Number(value).toFixed(2)) : null;
401
+ }
402
+ function normalizeBoolean(value) {
403
+ return value === true;
404
+ }
405
+ function normalizeString(value) {
406
+ return String(value || '').trim();
407
+ }
408
+ function normalizeStringArray(value) {
409
+ return Array.isArray(value)
410
+ ? value.map((entry) => normalizeString(entry)).filter(Boolean)
411
+ : [];
412
+ }
413
+ function buildAnswerReleaseReviewSummary(value) {
414
+ if (!isRecord(value)) {
415
+ return null;
416
+ }
417
+ const reviewedAt = normalizeString(value.reviewedAt);
418
+ const decision = normalizeString(value.decision).toLowerCase();
419
+ const revised = normalizeBoolean(value.revised);
420
+ const failedGateIds = normalizeStringArray(value.failedGateIds);
421
+ const leakedInternalFragmentCount = normalizeStringArray(value.leakedInternalFragments).length;
422
+ const reason = normalizeString(value.reason);
423
+ if (!reviewedAt
424
+ && !decision
425
+ && revised !== true
426
+ && failedGateIds.length <= 0
427
+ && leakedInternalFragmentCount <= 0
428
+ && !reason) {
429
+ return null;
430
+ }
431
+ return {
432
+ reviewedAt,
433
+ decision,
434
+ revised,
435
+ failedGateIds,
436
+ leakedInternalFragmentCount,
437
+ reason,
438
+ };
439
+ }
440
+ function buildKnowledgeRunReports(records) {
441
+ return records
442
+ .filter((record) => record.kind === 'knowledge_run')
443
+ .map((record) => {
444
+ const payload = record.payload && typeof record.payload === 'object'
445
+ ? record.payload
446
+ : {};
447
+ const knowledgeRun = payload.knowledgeRun && typeof payload.knowledgeRun === 'object'
448
+ ? payload.knowledgeRun
449
+ : {};
450
+ const runSummary = knowledgeRun.summary && typeof knowledgeRun.summary === 'object'
451
+ ? knowledgeRun.summary
452
+ : {};
453
+ const quality = knowledgeRun.quality && typeof knowledgeRun.quality === 'object'
454
+ ? knowledgeRun.quality
455
+ : {};
456
+ const scope = knowledgeRun.scope && typeof knowledgeRun.scope === 'object'
457
+ ? knowledgeRun.scope
458
+ : {};
459
+ const answerReleaseReview = buildAnswerReleaseReviewSummary(knowledgeRun.answerReleaseReview ?? payload.answerReleaseReview);
460
+ const graphContext = payload.graphContext && typeof payload.graphContext === 'object'
461
+ ? payload.graphContext
462
+ : {};
463
+ const diagnostics = graphContext.diagnostics && typeof graphContext.diagnostics === 'object'
464
+ ? graphContext.diagnostics
465
+ : {};
466
+ const temporalValidity = graphContext.temporalValidity && typeof graphContext.temporalValidity === 'object'
467
+ ? graphContext.temporalValidity
468
+ : {};
469
+ const connectionPathCount = Array.isArray(graphContext.connectionPaths)
470
+ ? graphContext.connectionPaths.filter((value) => Boolean(value && typeof value === 'object')).length
471
+ : 0;
472
+ const temporalWarningCount = Array.isArray(temporalValidity.warningReasons)
473
+ ? temporalValidity.warningReasons.map((value) => String(value || '').trim()).filter(Boolean).length
474
+ : 0;
475
+ const missingLookupCount = ((Array.isArray(diagnostics.missingConnectionPathSourceAtomIds)
476
+ ? diagnostics.missingConnectionPathSourceAtomIds.map((value) => String(value || '').trim()).filter(Boolean).length
477
+ : 0)
478
+ + (Array.isArray(diagnostics.missingPredecessorAtomIds)
479
+ ? diagnostics.missingPredecessorAtomIds.map((value) => String(value || '').trim()).filter(Boolean).length
480
+ : 0)
481
+ + (Array.isArray(diagnostics.missingSuccessorAtomIds)
482
+ ? diagnostics.missingSuccessorAtomIds.map((value) => String(value || '').trim()).filter(Boolean).length
483
+ : 0));
484
+ return {
485
+ artifactId: record.artifactId,
486
+ runId: String(knowledgeRun.runId || payload.runId || '').trim(),
487
+ generatedAt: String(knowledgeRun.generatedAt || record.updatedAt || record.createdAt || '').trim(),
488
+ artifactTitle: record.title,
489
+ artifactStatus: String(record.status || '').trim(),
490
+ workspaceId: record.workspaceId,
491
+ corpusId: record.corpusId,
492
+ qualityStatus: String(quality.status || knowledgeRun.status || '').trim(),
493
+ qualityScore: normalizeOptionalScore(quality.score),
494
+ claimCount: normalizeCount(runSummary.claimCount),
495
+ weakClaimCount: normalizeCount(runSummary.weakClaimCount),
496
+ reviewCardCount: normalizeCount(runSummary.reviewCardCount),
497
+ completedReviewCardCount: normalizeCount(runSummary.completedReviewCardCount),
498
+ remainingReviewCardCount: normalizeCount(runSummary.remainingReviewCardCount),
499
+ scopeSource: String(scope.scopeSource || scope.source || '').trim(),
500
+ graphSignal: {
501
+ graphOpsAvailable: diagnostics.graphOpsAvailable === true,
502
+ usedFallback: diagnostics.usedFallback === true,
503
+ selectedAnchorReason: String(diagnostics.selectedAnchorReason || '').trim(),
504
+ connectionPathCount,
505
+ temporalWarningCount,
506
+ supportNodeCount: normalizeCount(diagnostics.supportNodeCount),
507
+ supportNodeLimit: normalizeCount(diagnostics.supportNodeLimit),
508
+ pathDepthLimit: Number.isFinite(Number(diagnostics.pathDepthLimit))
509
+ ? Math.max(0, Math.floor(Number(diagnostics.pathDepthLimit)))
510
+ : null,
511
+ missingLookupCount,
512
+ },
513
+ ...(answerReleaseReview ? { answerReleaseReview } : {}),
514
+ };
515
+ });
516
+ }
517
+ function normalizeAnswerReleaseDecisionBucket(decisionLike) {
518
+ const normalized = normalizeString(decisionLike).toLowerCase();
519
+ if (normalized === 'release' || normalized === 'revise' || normalized === 'abstain') {
520
+ return normalized;
521
+ }
522
+ return 'other';
523
+ }
524
+ const ANSWER_RELEASE_AUDIT_TREND_WINDOW_SIZE = 4;
525
+ function buildEmptyAnswerReleaseDecisionCounts() {
526
+ return {
527
+ release: 0,
528
+ revise: 0,
529
+ abstain: 0,
530
+ other: 0,
531
+ };
532
+ }
533
+ function buildEmptyAnswerReleaseAuditWindow() {
534
+ return {
535
+ reviewedRunCount: 0,
536
+ decisionCounts: buildEmptyAnswerReleaseDecisionCounts(),
537
+ revisedRunCount: 0,
538
+ runsWithFailedGates: 0,
539
+ runsWithLeakedInternalFragments: 0,
540
+ latestReviewedAt: '',
541
+ earliestReviewedAt: '',
542
+ };
543
+ }
544
+ function buildAnswerReleaseAuditTimelineEntries(reports) {
545
+ return reports
546
+ .flatMap((report) => {
547
+ const review = report && typeof report.answerReleaseReview === 'object'
548
+ ? report.answerReleaseReview
549
+ : null;
550
+ if (!review) {
551
+ return [];
552
+ }
553
+ const reviewedAt = normalizeString(review.reviewedAt);
554
+ const uniqueFailedGateIds = Array.from(new Set((Array.isArray(review.failedGateIds) ? review.failedGateIds : [])
555
+ .map((gateId) => normalizeString(gateId))
556
+ .filter(Boolean)));
557
+ const leakedInternalFragmentCount = normalizeCount(review.leakedInternalFragmentCount);
558
+ return [{
559
+ artifactId: normalizeString(report.artifactId),
560
+ runId: normalizeString(report.runId),
561
+ generatedAt: normalizeString(report.generatedAt),
562
+ reviewedAt,
563
+ sortTimestamp: reviewedAt || normalizeString(report.generatedAt),
564
+ review,
565
+ uniqueFailedGateIds,
566
+ leakedInternalFragmentCount,
567
+ }];
568
+ })
569
+ .sort((left, right) => {
570
+ const timestampOrder = compareStrings(right.sortTimestamp, left.sortTimestamp);
571
+ if (timestampOrder !== 0) {
572
+ return timestampOrder;
573
+ }
574
+ const reviewedAtOrder = compareStrings(right.reviewedAt, left.reviewedAt);
575
+ if (reviewedAtOrder !== 0) {
576
+ return reviewedAtOrder;
577
+ }
578
+ const generatedAtOrder = compareStrings(right.generatedAt, left.generatedAt);
579
+ if (generatedAtOrder !== 0) {
580
+ return generatedAtOrder;
581
+ }
582
+ const runIdOrder = compareStrings(left.runId, right.runId);
583
+ if (runIdOrder !== 0) {
584
+ return runIdOrder;
585
+ }
586
+ return compareStrings(left.artifactId, right.artifactId);
587
+ });
588
+ }
589
+ function buildAnswerReleaseAuditWindow(entries) {
590
+ if (entries.length <= 0) {
591
+ return buildEmptyAnswerReleaseAuditWindow();
592
+ }
593
+ const decisionCounts = buildEmptyAnswerReleaseDecisionCounts();
594
+ let revisedRunCount = 0;
595
+ let runsWithFailedGates = 0;
596
+ let runsWithLeakedInternalFragments = 0;
597
+ entries.forEach((entry) => {
598
+ decisionCounts[normalizeAnswerReleaseDecisionBucket(entry.review.decision)] += 1;
599
+ if (entry.review.revised === true) {
600
+ revisedRunCount += 1;
601
+ }
602
+ if (entry.uniqueFailedGateIds.length > 0) {
603
+ runsWithFailedGates += 1;
604
+ }
605
+ if (entry.leakedInternalFragmentCount > 0) {
606
+ runsWithLeakedInternalFragments += 1;
607
+ }
608
+ });
609
+ return {
610
+ reviewedRunCount: entries.length,
611
+ decisionCounts,
612
+ revisedRunCount,
613
+ runsWithFailedGates,
614
+ runsWithLeakedInternalFragments,
615
+ latestReviewedAt: entries[0].reviewedAt,
616
+ earliestReviewedAt: entries[entries.length - 1].reviewedAt,
617
+ };
618
+ }
619
+ function buildAnswerReleaseAuditTrend(entries) {
620
+ const recentWindowEntries = entries.slice(0, ANSWER_RELEASE_AUDIT_TREND_WINDOW_SIZE);
621
+ const priorWindowEntries = entries.slice(ANSWER_RELEASE_AUDIT_TREND_WINDOW_SIZE, ANSWER_RELEASE_AUDIT_TREND_WINDOW_SIZE * 2);
622
+ return {
623
+ windowSize: ANSWER_RELEASE_AUDIT_TREND_WINDOW_SIZE,
624
+ recentWindow: buildAnswerReleaseAuditWindow(recentWindowEntries),
625
+ priorWindow: buildAnswerReleaseAuditWindow(priorWindowEntries),
626
+ };
627
+ }
628
+ function buildAnswerReleaseAuditMetricShifts(recentWindow, priorWindow) {
629
+ const metricDefinitions = [
630
+ {
631
+ metricId: 'reviewed_runs',
632
+ readValue: (windowSummary) => windowSummary.reviewedRunCount,
633
+ },
634
+ {
635
+ metricId: 'release_decisions',
636
+ readValue: (windowSummary) => windowSummary.decisionCounts.release,
637
+ },
638
+ {
639
+ metricId: 'revise_decisions',
640
+ readValue: (windowSummary) => windowSummary.decisionCounts.revise,
641
+ },
642
+ {
643
+ metricId: 'abstain_decisions',
644
+ readValue: (windowSummary) => windowSummary.decisionCounts.abstain,
645
+ },
646
+ {
647
+ metricId: 'other_decisions',
648
+ readValue: (windowSummary) => windowSummary.decisionCounts.other,
649
+ },
650
+ {
651
+ metricId: 'revised_runs',
652
+ readValue: (windowSummary) => windowSummary.revisedRunCount,
653
+ },
654
+ {
655
+ metricId: 'failed_gate_runs',
656
+ readValue: (windowSummary) => windowSummary.runsWithFailedGates,
657
+ },
658
+ {
659
+ metricId: 'leaked_runs',
660
+ readValue: (windowSummary) => windowSummary.runsWithLeakedInternalFragments,
661
+ },
662
+ ];
663
+ return metricDefinitions.map(({ metricId, readValue }) => {
664
+ const recentValue = normalizeCount(readValue(recentWindow));
665
+ const priorValue = normalizeCount(readValue(priorWindow));
666
+ return {
667
+ metricId,
668
+ recentValue,
669
+ priorValue,
670
+ delta: recentValue - priorValue,
671
+ };
672
+ });
673
+ }
674
+ function buildAnswerReleaseAuditWindowGateCounts(entries) {
675
+ const gateCounts = new Map();
676
+ entries.forEach((entry) => {
677
+ entry.uniqueFailedGateIds.forEach((gateId) => {
678
+ gateCounts.set(gateId, (gateCounts.get(gateId) || 0) + 1);
679
+ });
680
+ });
681
+ return gateCounts;
682
+ }
683
+ function buildAnswerReleaseAuditGateAging(entries) {
684
+ const gateAging = new Map();
685
+ entries.forEach((entry, index) => {
686
+ if (entry.uniqueFailedGateIds.length <= 0) {
687
+ return;
688
+ }
689
+ entry.uniqueFailedGateIds.forEach((gateId) => {
690
+ const existing = gateAging.get(gateId);
691
+ if (!existing) {
692
+ gateAging.set(gateId, {
693
+ gateId,
694
+ failureCount: 1,
695
+ latestReviewedAt: entry.reviewedAt,
696
+ oldestReviewedAt: entry.reviewedAt,
697
+ reviewedRunsSinceLastFailure: index,
698
+ occurrencesInRecentWindow: index < ANSWER_RELEASE_AUDIT_TREND_WINDOW_SIZE ? 1 : 0,
699
+ });
700
+ return;
701
+ }
702
+ existing.failureCount += 1;
703
+ existing.oldestReviewedAt = entry.reviewedAt || existing.oldestReviewedAt;
704
+ if (index < ANSWER_RELEASE_AUDIT_TREND_WINDOW_SIZE) {
705
+ existing.occurrencesInRecentWindow += 1;
706
+ }
707
+ });
708
+ });
709
+ return Array.from(gateAging.values()).sort((left, right) => {
710
+ if (left.reviewedRunsSinceLastFailure !== right.reviewedRunsSinceLastFailure) {
711
+ return left.reviewedRunsSinceLastFailure - right.reviewedRunsSinceLastFailure;
712
+ }
713
+ if (left.occurrencesInRecentWindow !== right.occurrencesInRecentWindow) {
714
+ return right.occurrencesInRecentWindow - left.occurrencesInRecentWindow;
715
+ }
716
+ if (left.failureCount !== right.failureCount) {
717
+ return right.failureCount - left.failureCount;
718
+ }
719
+ const latestReviewedAtOrder = compareStrings(right.latestReviewedAt, left.latestReviewedAt);
720
+ if (latestReviewedAtOrder !== 0) {
721
+ return latestReviewedAtOrder;
722
+ }
723
+ return compareStrings(left.gateId, right.gateId);
724
+ });
725
+ }
726
+ function buildAnswerReleaseAuditGateShifts(entries) {
727
+ const recentWindowEntries = entries.slice(0, ANSWER_RELEASE_AUDIT_TREND_WINDOW_SIZE);
728
+ const priorWindowEntries = entries.slice(ANSWER_RELEASE_AUDIT_TREND_WINDOW_SIZE, ANSWER_RELEASE_AUDIT_TREND_WINDOW_SIZE * 2);
729
+ const recentGateCounts = buildAnswerReleaseAuditWindowGateCounts(recentWindowEntries);
730
+ const priorGateCounts = buildAnswerReleaseAuditWindowGateCounts(priorWindowEntries);
731
+ const gateAgingById = new Map(buildAnswerReleaseAuditGateAging(entries).map((entry) => [entry.gateId, entry]));
732
+ const gateIds = Array.from(new Set([
733
+ ...recentGateCounts.keys(),
734
+ ...priorGateCounts.keys(),
735
+ ...gateAgingById.keys(),
736
+ ]));
737
+ return gateIds
738
+ .map((gateId) => {
739
+ const recentWindowCount = normalizeCount(recentGateCounts.get(gateId) || 0);
740
+ const priorWindowCount = normalizeCount(priorGateCounts.get(gateId) || 0);
741
+ const gateAging = gateAgingById.get(gateId);
742
+ return {
743
+ gateId,
744
+ recentWindowCount,
745
+ priorWindowCount,
746
+ delta: recentWindowCount - priorWindowCount,
747
+ failureCount: normalizeCount(gateAging?.failureCount || 0),
748
+ latestReviewedAt: normalizeString(gateAging?.latestReviewedAt || ''),
749
+ reviewedRunsSinceLastFailure: normalizeCount(gateAging?.reviewedRunsSinceLastFailure || 0),
750
+ };
751
+ })
752
+ .sort((left, right) => {
753
+ const leftHasRecentWindowFailure = left.recentWindowCount > 0 ? 0 : 1;
754
+ const rightHasRecentWindowFailure = right.recentWindowCount > 0 ? 0 : 1;
755
+ if (leftHasRecentWindowFailure !== rightHasRecentWindowFailure) {
756
+ return leftHasRecentWindowFailure - rightHasRecentWindowFailure;
757
+ }
758
+ const deltaMagnitudeOrder = Math.abs(right.delta) - Math.abs(left.delta);
759
+ if (deltaMagnitudeOrder !== 0) {
760
+ return deltaMagnitudeOrder;
761
+ }
762
+ if (left.reviewedRunsSinceLastFailure !== right.reviewedRunsSinceLastFailure) {
763
+ return left.reviewedRunsSinceLastFailure - right.reviewedRunsSinceLastFailure;
764
+ }
765
+ if (left.failureCount !== right.failureCount) {
766
+ return right.failureCount - left.failureCount;
767
+ }
768
+ if (left.recentWindowCount !== right.recentWindowCount) {
769
+ return right.recentWindowCount - left.recentWindowCount;
770
+ }
771
+ const latestReviewedAtOrder = compareStrings(right.latestReviewedAt, left.latestReviewedAt);
772
+ if (latestReviewedAtOrder !== 0) {
773
+ return latestReviewedAtOrder;
774
+ }
775
+ return compareStrings(left.gateId, right.gateId);
776
+ });
777
+ }
778
+ function buildAnswerReleaseAuditLatestPair(entries) {
779
+ if (entries.length < 2) {
780
+ return null;
781
+ }
782
+ const latestEntry = entries[0];
783
+ const previousEntry = entries[1];
784
+ const latestFailedGateIds = new Set(latestEntry.uniqueFailedGateIds);
785
+ const previousFailedGateIds = new Set(previousEntry.uniqueFailedGateIds);
786
+ return {
787
+ latestRunId: normalizeString(latestEntry.runId),
788
+ previousRunId: normalizeString(previousEntry.runId),
789
+ latestReviewedAt: normalizeString(latestEntry.reviewedAt),
790
+ previousReviewedAt: normalizeString(previousEntry.reviewedAt),
791
+ latestDecision: normalizeAnswerReleaseDecisionBucket(latestEntry.review.decision),
792
+ previousDecision: normalizeAnswerReleaseDecisionBucket(previousEntry.review.decision),
793
+ decisionChanged: normalizeAnswerReleaseDecisionBucket(latestEntry.review.decision)
794
+ !== normalizeAnswerReleaseDecisionBucket(previousEntry.review.decision),
795
+ latestRevised: latestEntry.review.revised === true,
796
+ previousRevised: previousEntry.review.revised === true,
797
+ revisedChanged: (latestEntry.review.revised === true) !== (previousEntry.review.revised === true),
798
+ latestLeakedInternalFragmentCount: normalizeCount(latestEntry.leakedInternalFragmentCount),
799
+ previousLeakedInternalFragmentCount: normalizeCount(previousEntry.leakedInternalFragmentCount),
800
+ leakedInternalFragmentDelta: normalizeCount(latestEntry.leakedInternalFragmentCount)
801
+ - normalizeCount(previousEntry.leakedInternalFragmentCount),
802
+ newlyFailedGateIds: latestEntry.uniqueFailedGateIds.filter((gateId) => !previousFailedGateIds.has(gateId)),
803
+ resolvedFailedGateIds: previousEntry.uniqueFailedGateIds.filter((gateId) => !latestFailedGateIds.has(gateId)),
804
+ persistentFailedGateIds: latestEntry.uniqueFailedGateIds.filter((gateId) => previousFailedGateIds.has(gateId)),
805
+ };
806
+ }
807
+ function buildAnswerReleaseAuditComparison(entries) {
808
+ const recentWindowEntries = entries.slice(0, ANSWER_RELEASE_AUDIT_TREND_WINDOW_SIZE);
809
+ const priorWindowEntries = entries.slice(ANSWER_RELEASE_AUDIT_TREND_WINDOW_SIZE, ANSWER_RELEASE_AUDIT_TREND_WINDOW_SIZE * 2);
810
+ const recentWindow = buildAnswerReleaseAuditWindow(recentWindowEntries);
811
+ const priorWindow = buildAnswerReleaseAuditWindow(priorWindowEntries);
812
+ return {
813
+ metricShifts: buildAnswerReleaseAuditMetricShifts(recentWindow, priorWindow),
814
+ gateShifts: buildAnswerReleaseAuditGateShifts(entries),
815
+ latestPair: buildAnswerReleaseAuditLatestPair(entries),
816
+ };
817
+ }
818
+ function buildKnowledgeRunAnswerReleaseAuditSummary(reports) {
819
+ const decisionCounts = buildEmptyAnswerReleaseDecisionCounts();
820
+ const failedGateCounts = new Map();
821
+ let reviewedRunCount = 0;
822
+ let revisedRunCount = 0;
823
+ let runsWithFailedGates = 0;
824
+ let runsWithLeakedInternalFragments = 0;
825
+ let leakedInternalFragmentTotalCount = 0;
826
+ let latestReviewedAt = '';
827
+ const timelineEntries = buildAnswerReleaseAuditTimelineEntries(reports);
828
+ reports.forEach((report) => {
829
+ const review = report && typeof report.answerReleaseReview === 'object'
830
+ ? report.answerReleaseReview
831
+ : null;
832
+ if (!review) {
833
+ return;
834
+ }
835
+ reviewedRunCount += 1;
836
+ decisionCounts[normalizeAnswerReleaseDecisionBucket(review.decision)] += 1;
837
+ if (review.revised === true) {
838
+ revisedRunCount += 1;
839
+ }
840
+ const uniqueFailedGateIds = Array.from(new Set((Array.isArray(review.failedGateIds) ? review.failedGateIds : [])
841
+ .map((gateId) => normalizeString(gateId))
842
+ .filter(Boolean)));
843
+ if (uniqueFailedGateIds.length > 0) {
844
+ runsWithFailedGates += 1;
845
+ uniqueFailedGateIds.forEach((gateId) => {
846
+ failedGateCounts.set(gateId, (failedGateCounts.get(gateId) || 0) + 1);
847
+ });
848
+ }
849
+ const leakedInternalFragmentCount = normalizeCount(review.leakedInternalFragmentCount);
850
+ if (leakedInternalFragmentCount > 0) {
851
+ runsWithLeakedInternalFragments += 1;
852
+ leakedInternalFragmentTotalCount += leakedInternalFragmentCount;
853
+ }
854
+ const reviewedAt = normalizeString(review.reviewedAt);
855
+ if (reviewedAt && (!latestReviewedAt || compareStrings(reviewedAt, latestReviewedAt) > 0)) {
856
+ latestReviewedAt = reviewedAt;
857
+ }
858
+ });
859
+ return {
860
+ totalRuns: reports.length,
861
+ reviewedRunCount,
862
+ unreviewedRunCount: Math.max(0, reports.length - reviewedRunCount),
863
+ decisionCounts,
864
+ revisedRunCount,
865
+ runsWithFailedGates,
866
+ runsWithLeakedInternalFragments,
867
+ leakedInternalFragmentTotalCount,
868
+ failedGateCounts: Array.from(failedGateCounts.entries())
869
+ .map(([gateId, count]) => ({
870
+ gateId,
871
+ count,
872
+ }))
873
+ .sort((left, right) => {
874
+ if (left.count !== right.count) {
875
+ return right.count - left.count;
876
+ }
877
+ return compareStrings(left.gateId, right.gateId);
878
+ }),
879
+ latestReviewedAt,
880
+ reviewTrend: buildAnswerReleaseAuditTrend(timelineEntries),
881
+ failedGateAging: buildAnswerReleaseAuditGateAging(timelineEntries),
882
+ comparison: buildAnswerReleaseAuditComparison(timelineEntries),
883
+ };
884
+ }
885
+ function buildGraphFocusReports(sessionStates) {
886
+ return sessionStates
887
+ .flatMap((state) => {
888
+ const panelState = isRecord(state.panelState) ? state.panelState : {};
889
+ const reports = Array.isArray(panelState.graphFocusReports)
890
+ ? panelState.graphFocusReports.filter((entry) => isRecord(entry))
891
+ : [];
892
+ return reports.map((entry) => {
893
+ const candidateSourcePaths = normalizeStringArray(entry.candidateSourcePaths);
894
+ const attemptedSourcePaths = normalizeStringArray(entry.attemptedSourcePaths);
895
+ return {
896
+ sessionStateId: state.sessionStateId,
897
+ sessionId: state.sessionId,
898
+ userId: state.userId,
899
+ workspaceId: state.workspaceId,
900
+ corpusId: state.corpusId,
901
+ mode: state.mode,
902
+ recordedAt: normalizeString(entry.recordedAt) || state.updatedAt,
903
+ title: normalizeString(entry.title),
904
+ requestedSourcePath: normalizeString(entry.requestedSourcePath),
905
+ resolvedSourcePath: normalizeString(entry.resolvedSourcePath),
906
+ signal: {
907
+ usedFallback: normalizeBoolean(entry.usedFallback),
908
+ fallbackSourcePathUsed: normalizeBoolean(entry.fallbackSourcePathUsed),
909
+ matchedSpanCount: normalizeCount(entry.matchedSpanCount),
910
+ highlightTermCount: normalizeCount(entry.highlightTermCount),
911
+ highlightedNodeCount: normalizeCount(entry.highlightedNodeCount),
912
+ candidateSourcePathCount: candidateSourcePaths.length,
913
+ attemptedSourcePathCount: attemptedSourcePaths.length,
914
+ markdownRuntimeAvailable: normalizeBoolean(entry.markdownRuntimeAvailable),
915
+ storageProviderAvailable: normalizeBoolean(entry.storageProviderAvailable),
916
+ readSucceeded: normalizeBoolean(entry.readSucceeded),
917
+ renderSucceeded: normalizeBoolean(entry.renderSucceeded),
918
+ failureReason: normalizeString(entry.failureReason),
919
+ },
920
+ };
921
+ });
922
+ })
923
+ .sort((left, right) => {
924
+ const recordedAtOrder = compareStrings(left.recordedAt, right.recordedAt);
925
+ if (recordedAtOrder !== 0) {
926
+ return recordedAtOrder;
927
+ }
928
+ const sessionOrder = compareStrings(left.sessionStateId, right.sessionStateId);
929
+ if (sessionOrder !== 0) {
930
+ return sessionOrder;
931
+ }
932
+ return compareStrings(left.requestedSourcePath, right.requestedSourcePath);
933
+ });
934
+ }
935
+ function sortAndCloneMemoryEntries(records) {
936
+ return records
937
+ .slice()
938
+ .sort((left, right) => {
939
+ const userOrder = compareStrings(left.userId, right.userId);
940
+ if (userOrder !== 0) {
941
+ return userOrder;
942
+ }
943
+ const layerOrder = compareStrings(left.layer, right.layer);
944
+ if (layerOrder !== 0) {
945
+ return layerOrder;
946
+ }
947
+ return compareStrings(left.entry.key, right.entry.key);
948
+ })
949
+ .map((record) => ({
950
+ userId: record.userId,
951
+ layer: record.layer,
952
+ entry: {
953
+ ...record.entry,
954
+ tags: [...record.entry.tags],
955
+ references: [...record.entry.references],
956
+ },
957
+ }));
958
+ }
959
+ function sortAndCloneMemoryAuditRecords(records) {
960
+ return records
961
+ .slice()
962
+ .sort((left, right) => compareStrings(left.auditId, right.auditId))
963
+ .map((record) => ({ ...record }));
964
+ }
965
+ function buildWorkspaceExportBundle(input) {
966
+ const capabilities = (0, PlatformCapabilities_1.resolvePlatformCapabilities)({
967
+ exportProfileId: input.request.exportProfileId || input.workspace.exportProfileId,
968
+ });
969
+ const render = (0, RenderMaterializer_1.resolveRenderMaterializationDecision)({
970
+ exportProfileId: capabilities.exportProfileId,
971
+ platformTarget: capabilities.platformTarget,
972
+ includeSvg: true,
973
+ });
974
+ const bindings = sortAndCloneBindings(input.bindings);
975
+ const resources = sortAndCloneResources(input.resources);
976
+ const projections = sortAndCloneProjections(input.projections);
977
+ const units = sortAndCloneUnits(input.units);
978
+ const segments = sortAndCloneSegments(input.segments);
979
+ const atoms = sortAndCloneAtoms(input.atoms);
980
+ const evidenceSpans = sortAndCloneEvidenceSpans(input.evidenceSpans);
981
+ const relationEdges = sortAndCloneRelationEdges(input.relationEdges);
982
+ const temporalEdges = sortAndCloneTemporalEdges(input.temporalEdges);
983
+ const sessionStates = sortAndCloneSessionStates(input.sessionStates);
984
+ const conversationSessions = sortAndCloneConversationSessions(input.conversationSessions);
985
+ const conversationTurns = sortAndCloneConversationTurns(input.conversationTurns);
986
+ const conversationInvocations = sortAndCloneConversationInvocations(input.conversationInvocations);
987
+ const workflowArtifacts = sortAndCloneWorkflowArtifacts(input.workflowArtifacts);
988
+ const knowledgeRunReports = buildKnowledgeRunReports(workflowArtifacts);
989
+ const knowledgeRunAnswerReleaseAuditSummary = buildKnowledgeRunAnswerReleaseAuditSummary(knowledgeRunReports);
990
+ const graphFocusReports = buildGraphFocusReports(sessionStates);
991
+ const memoryEntries = sortAndCloneMemoryEntries(input.memoryEntries);
992
+ const memoryAuditRecords = sortAndCloneMemoryAuditRecords(input.memoryAuditRecords);
993
+ const activeProjectionIds = projections
994
+ .filter((projection) => projection.status === 'active')
995
+ .map((projection) => projection.projectionId);
996
+ const indexedProjectionIds = new Set(units
997
+ .filter((unit) => unit.state === 'indexed' && unit.segmentIds.length > 0)
998
+ .map((unit) => unit.projectionId));
999
+ const missingIndexedProjectionIds = activeProjectionIds.filter((projectionId) => !indexedProjectionIds.has(projectionId));
1000
+ const reasons = [];
1001
+ if (missingIndexedProjectionIds.length > 0) {
1002
+ reasons.push(`Missing indexed segments for ${missingIndexedProjectionIds.length} active projection(s).`);
1003
+ }
1004
+ if (!render.responseArtifact || !capabilities.render.supportsPngArtifacts) {
1005
+ reasons.push('Resolved export profile does not provide a render artifact path.');
1006
+ }
1007
+ const deterministicPayload = {
1008
+ workspace: {
1009
+ ...input.workspace,
1010
+ languages: [...input.workspace.languages].sort(compareStrings),
1011
+ },
1012
+ capabilities,
1013
+ render,
1014
+ bindings,
1015
+ resources,
1016
+ projections,
1017
+ index: {
1018
+ summary: input.indexSummary,
1019
+ units,
1020
+ segments,
1021
+ },
1022
+ graph: {
1023
+ atoms,
1024
+ evidenceSpans,
1025
+ relationEdges,
1026
+ temporalEdges,
1027
+ },
1028
+ runtime: {
1029
+ sessionStates,
1030
+ conversationSessions,
1031
+ conversationTurns,
1032
+ conversationInvocations,
1033
+ workflowArtifacts,
1034
+ knowledgeRunReports,
1035
+ knowledgeRunAnswerReleaseAuditSummary,
1036
+ graphFocusReports,
1037
+ },
1038
+ memory: {
1039
+ entries: memoryEntries,
1040
+ auditRecords: memoryAuditRecords,
1041
+ },
1042
+ };
1043
+ const deterministicHash = (0, crypto_1.createHash)('sha256')
1044
+ .update(JSON.stringify(deterministicPayload))
1045
+ .digest('hex');
1046
+ const bundleId = `workspace_export_${deterministicHash.slice(0, 12)}`;
1047
+ return {
1048
+ manifest: {
1049
+ bundleId,
1050
+ workspaceId: input.workspace.workspaceId,
1051
+ corpusId: input.workspace.corpusId,
1052
+ exportProfileId: capabilities.exportProfileId,
1053
+ platformTarget: capabilities.platformTarget,
1054
+ packagingMode: capabilities.retrieval.supportsSidecar ? 'full' : 'slim',
1055
+ generatedAt: input.generatedAt,
1056
+ deterministicHash,
1057
+ counts: {
1058
+ bindings: bindings.length,
1059
+ resources: resources.length,
1060
+ projections: projections.length,
1061
+ units: units.length,
1062
+ segments: segments.length,
1063
+ atoms: atoms.length,
1064
+ evidenceSpans: evidenceSpans.length,
1065
+ relationEdges: relationEdges.length,
1066
+ temporalEdges: temporalEdges.length,
1067
+ sessionStates: sessionStates.length,
1068
+ conversationSessions: conversationSessions.length,
1069
+ conversationTurns: conversationTurns.length,
1070
+ conversationInvocations: conversationInvocations.length,
1071
+ workflowArtifacts: workflowArtifacts.length,
1072
+ memoryEntries: memoryEntries.length,
1073
+ memoryAuditRecords: memoryAuditRecords.length,
1074
+ },
1075
+ },
1076
+ workspace: {
1077
+ ...input.workspace,
1078
+ languages: [...input.workspace.languages].sort(compareStrings),
1079
+ },
1080
+ capabilities,
1081
+ readiness: {
1082
+ ready: reasons.length <= 0,
1083
+ reasons,
1084
+ activeProjectionCount: activeProjectionIds.length,
1085
+ indexedProjectionCount: indexedProjectionIds.size,
1086
+ missingIndexedProjectionIds,
1087
+ indexSummary: {
1088
+ ...input.indexSummary,
1089
+ states: { ...input.indexSummary.states },
1090
+ },
1091
+ render: {
1092
+ responseArtifact: render.responseArtifact,
1093
+ rendererPreference: render.rendererPreference,
1094
+ includeSvg: render.includeSvg,
1095
+ vectorSuppressed: render.vectorSuppressed,
1096
+ },
1097
+ },
1098
+ bindings,
1099
+ resources,
1100
+ projections,
1101
+ index: {
1102
+ summary: {
1103
+ ...input.indexSummary,
1104
+ states: { ...input.indexSummary.states },
1105
+ },
1106
+ units,
1107
+ segments,
1108
+ },
1109
+ graph: {
1110
+ atoms,
1111
+ evidenceSpans,
1112
+ relationEdges,
1113
+ temporalEdges,
1114
+ },
1115
+ runtime: {
1116
+ sessionStates,
1117
+ conversationSessions,
1118
+ conversationTurns,
1119
+ conversationInvocations,
1120
+ workflowArtifacts,
1121
+ knowledgeRunReports,
1122
+ knowledgeRunAnswerReleaseAuditSummary,
1123
+ graphFocusReports,
1124
+ },
1125
+ memory: {
1126
+ entries: memoryEntries,
1127
+ auditRecords: memoryAuditRecords,
1128
+ },
1129
+ };
1130
+ }