ummaya 0.2.4 → 0.2.6

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 (482) hide show
  1. package/README.md +15 -2
  2. package/bin/ummaya +10 -1
  3. package/bun.lock +180 -244
  4. package/npm-shrinkwrap.json +760 -1760
  5. package/package.json +39 -22
  6. package/prompts/manifest.yaml +1 -1
  7. package/prompts/system_v1.md +1 -0
  8. package/pyproject.toml +27 -2
  9. package/specs/2803-document-production-hardening/contracts/document-tools.schema.json +1043 -0
  10. package/src/ummaya/_canonical/__init__.py +2 -0
  11. package/src/ummaya/_canonical/baselines.yaml +113 -0
  12. package/src/ummaya/engine/engine.py +29 -132
  13. package/src/ummaya/evidence/__init__.py +21 -2
  14. package/src/ummaya/evidence/dataset_contract.py +193 -0
  15. package/src/ummaya/evidence/document_authoring_cases.py +33 -0
  16. package/src/ummaya/evidence/document_harness.py +313 -0
  17. package/src/ummaya/evidence/document_viewer_ux.py +391 -0
  18. package/src/ummaya/evidence/gates.py +70 -0
  19. package/src/ummaya/evidence/json_types.py +20 -0
  20. package/src/ummaya/evidence/models.py +88 -1
  21. package/src/ummaya/evidence/output_payload.py +89 -0
  22. package/src/ummaya/evidence/payload_documents.py +233 -0
  23. package/src/ummaya/evidence/route_contracts.py +224 -0
  24. package/src/ummaya/evidence/route_helpers.py +150 -0
  25. package/src/ummaya/evidence/runner.py +81 -212
  26. package/src/ummaya/evidence/source_provenance.py +246 -0
  27. package/src/ummaya/evidence/source_provenance_redaction.py +176 -0
  28. package/src/ummaya/evidence/tool_layer.py +39 -0
  29. package/src/ummaya/evidence/tool_layer_models.py +151 -0
  30. package/src/ummaya/ipc/adapter_manifest_emitter.py +26 -10
  31. package/src/ummaya/ipc/document_intent_normalization.py +185 -0
  32. package/src/ummaya/ipc/frame_schema.py +5 -5
  33. package/src/ummaya/ipc/route_diagnostics.py +73 -0
  34. package/src/ummaya/ipc/stdio.py +1109 -477
  35. package/src/ummaya/llm/client.py +102 -3
  36. package/src/ummaya/llm/config.py +8 -3
  37. package/src/ummaya/primitives/__init__.py +6 -2
  38. package/src/ummaya/primitives/delegation.py +1 -1
  39. package/src/ummaya/primitives/document.py +28 -0
  40. package/src/ummaya/settings.py +0 -3
  41. package/src/ummaya/tools/discovery_bridge.py +17 -1
  42. package/src/ummaya/tools/documents/__init__.py +297 -0
  43. package/src/ummaya/tools/documents/adapter_registry.py +487 -0
  44. package/src/ummaya/tools/documents/archive_container_probe.py +167 -0
  45. package/src/ummaya/tools/documents/artifact_store.py +454 -0
  46. package/src/ummaya/tools/documents/authoring.py +283 -0
  47. package/src/ummaya/tools/documents/baselines.py +132 -0
  48. package/src/ummaya/tools/documents/capability.py +331 -0
  49. package/src/ummaya/tools/documents/contracts.py +112 -0
  50. package/src/ummaya/tools/documents/conversion.py +521 -0
  51. package/src/ummaya/tools/documents/diff.py +275 -0
  52. package/src/ummaya/tools/documents/engines.py +163 -0
  53. package/src/ummaya/tools/documents/evaluation.py +291 -0
  54. package/src/ummaya/tools/documents/explicit_values.py +108 -0
  55. package/src/ummaya/tools/documents/fixtures.py +174 -0
  56. package/src/ummaya/tools/documents/format_completion_audit.py +471 -0
  57. package/src/ummaya/tools/documents/formats/__init__.py +2 -0
  58. package/src/ummaya/tools/documents/formats/archive.py +528 -0
  59. package/src/ummaya/tools/documents/formats/base.py +41 -0
  60. package/src/ummaya/tools/documents/formats/code_file.py +211 -0
  61. package/src/ummaya/tools/documents/formats/data_file.py +272 -0
  62. package/src/ummaya/tools/documents/formats/hwp.py +284 -0
  63. package/src/ummaya/tools/documents/formats/hwpx.py +1837 -0
  64. package/src/ummaya/tools/documents/formats/odf.py +435 -0
  65. package/src/ummaya/tools/documents/formats/ooxml.py +1030 -0
  66. package/src/ummaya/tools/documents/formats/passive.py +766 -0
  67. package/src/ummaya/tools/documents/formats/pdf.py +702 -0
  68. package/src/ummaya/tools/documents/formats/text_web.py +268 -0
  69. package/src/ummaya/tools/documents/hwp_conversion_probe.py +178 -0
  70. package/src/ummaya/tools/documents/hwp_direct_candidate.py +141 -0
  71. package/src/ummaya/tools/documents/inspection.py +289 -0
  72. package/src/ummaya/tools/documents/intake.py +1079 -0
  73. package/src/ummaya/tools/documents/legacy_office_promotion_probe.py +366 -0
  74. package/src/ummaya/tools/documents/models.py +1598 -0
  75. package/src/ummaya/tools/documents/odf_promotion_probe.py +167 -0
  76. package/src/ummaya/tools/documents/orchestrator.py +96 -0
  77. package/src/ummaya/tools/documents/passive_capability_probe.py +251 -0
  78. package/src/ummaya/tools/documents/patch.py +170 -0
  79. package/src/ummaya/tools/documents/pdfa_conformance.py +284 -0
  80. package/src/ummaya/tools/documents/pdfa_promotion_probe.py +198 -0
  81. package/src/ummaya/tools/documents/permissions.py +110 -0
  82. package/src/ummaya/tools/documents/planner.py +616 -0
  83. package/src/ummaya/tools/documents/registry.py +2733 -0
  84. package/src/ummaya/tools/documents/render.py +978 -0
  85. package/src/ummaya/tools/documents/render_comparison.py +113 -0
  86. package/src/ummaya/tools/documents/render_comparison_models.py +74 -0
  87. package/src/ummaya/tools/documents/render_comparison_regions.py +73 -0
  88. package/src/ummaya/tools/documents/render_comparison_style.py +161 -0
  89. package/src/ummaya/tools/documents/reread.py +157 -0
  90. package/src/ummaya/tools/documents/runtime_authoring.py +244 -0
  91. package/src/ummaya/tools/documents/runtime_authoring_bundle.py +76 -0
  92. package/src/ummaya/tools/documents/scorecard.py +184 -0
  93. package/src/ummaya/tools/documents/socratic_planner.py +193 -0
  94. package/src/ummaya/tools/documents/style.py +48 -0
  95. package/src/ummaya/tools/documents/tool_defs.py +523 -0
  96. package/src/ummaya/tools/documents/validate.py +347 -0
  97. package/src/ummaya/tools/executor.py +29 -0
  98. package/src/ummaya/tools/live_proxy.py +0 -3
  99. package/src/ummaya/tools/models.py +5 -1
  100. package/src/ummaya/tools/register_all.py +8 -0
  101. package/src/ummaya/tools/registry.py +10 -1
  102. package/src/ummaya/tools/routing/__init__.py +59 -0
  103. package/src/ummaya/tools/routing/builder.py +105 -0
  104. package/src/ummaya/tools/routing/cards.py +29 -0
  105. package/src/ummaya/tools/routing/decision_service.py +534 -0
  106. package/src/ummaya/tools/routing/decision_types.py +74 -0
  107. package/src/ummaya/tools/routing/feasibility.py +122 -0
  108. package/src/ummaya/tools/routing/intent.py +17 -0
  109. package/src/ummaya/tools/routing/intent_extractor.py +207 -0
  110. package/src/ummaya/tools/routing/intent_patterns.py +160 -0
  111. package/src/ummaya/tools/routing/intent_public_data.py +150 -0
  112. package/src/ummaya/tools/routing/intent_types.py +48 -0
  113. package/src/ummaya/tools/routing/lint.py +78 -0
  114. package/src/ummaya/tools/routing/metadata.py +174 -0
  115. package/src/ummaya/tools/routing/projection.py +340 -0
  116. package/src/ummaya/tools/routing/retrieval_policy.py +629 -0
  117. package/src/ummaya/tools/routing/schema.py +81 -0
  118. package/src/ummaya/tools/routing/types.py +96 -0
  119. package/src/ummaya/tools/routing_index.py +2 -2
  120. package/src/ummaya/tools/search.py +34 -746
  121. package/tests/fixtures/documents/public_forms/baselines.yaml +113 -0
  122. package/tui/bun.lock +126 -305
  123. package/tui/package.json +35 -22
  124. package/tui/src/.cc-byte-identical-whitelist.yaml +266 -0
  125. package/tui/src/QueryEngine.ts +12 -8
  126. package/tui/src/bridge/inboundAttachments.ts +3 -3
  127. package/tui/src/cli/handlers/auth.ts +3 -12
  128. package/tui/src/cli/handlers/mcp.tsx +0 -1
  129. package/tui/src/cli/print.ts +8 -9
  130. package/tui/src/commands/insights.ts +1 -1
  131. package/tui/src/commands/install-github-app/types.ts +8 -30
  132. package/tui/src/commands/plugin/types.ts +6 -28
  133. package/tui/src/commands/plugin/unifiedTypes.ts +4 -26
  134. package/tui/src/commands/rename/generateSessionName.ts +1 -1
  135. package/tui/src/components/Feedback.tsx +1 -1
  136. package/tui/src/components/LogoV2/EmergencyTip.tsx +11 -2
  137. package/tui/src/components/LogoV2/WelcomeV2.tsx +1 -3
  138. package/tui/src/components/ScrollKeybindingHandler.tsx +6 -6
  139. package/tui/src/components/Spinner/types.ts +6 -28
  140. package/tui/src/components/agents/generateAgent.ts +1 -1
  141. package/tui/src/components/agents/new-agent-creation/types.ts +4 -26
  142. package/tui/src/components/config/EnvSecretIsolatedEditor.tsx +1 -1
  143. package/tui/src/components/mcp/types.ts +16 -38
  144. package/tui/src/components/messages/AssistantToolUseMessage.tsx +3 -2
  145. package/tui/src/components/messages/UserCrossSessionMessage.ts +16 -4
  146. package/tui/src/components/messages/UserForkBoilerplateMessage.ts +16 -4
  147. package/tui/src/components/messages/UserGitHubWebhookMessage.ts +16 -4
  148. package/tui/src/components/messages/UserToolResultMessage/utils.tsx +3 -2
  149. package/tui/src/components/permissions/MonitorPermissionRequest/MonitorPermissionRequest.ts +9 -4
  150. package/tui/src/components/permissions/ReviewArtifactPermissionRequest/ReviewArtifactPermissionRequest.ts +9 -4
  151. package/tui/src/components/primitive/DocumentSocraticReviewBlock.tsx +129 -0
  152. package/tui/src/components/primitive/DocumentToolResultCard.tsx +224 -0
  153. package/tui/src/components/primitive/documentSocraticReview.ts +215 -0
  154. package/tui/src/components/primitive/index.tsx +43 -1
  155. package/tui/src/components/primitive/types.ts +137 -0
  156. package/tui/src/components/ui/option.ts +4 -26
  157. package/tui/src/constants/common.ts +0 -2
  158. package/tui/src/constants/prompts.ts +4 -3
  159. package/tui/src/constants/querySource.ts +4 -26
  160. package/tui/src/entrypoints/sdk/controlTypes.ts +26 -48
  161. package/tui/src/entrypoints/sdk/coreTypes.generated.ts +3 -25
  162. package/tui/src/entrypoints/sdk/runtimeTypes.ts +38 -60
  163. package/tui/src/entrypoints/sdk/sdkUtilityTypes.ts +4 -26
  164. package/tui/src/entrypoints/sdk/settingsTypes.generated.ts +3 -25
  165. package/tui/src/entrypoints/sdk/toolTypes.ts +3 -25
  166. package/tui/src/hooks/toolPermission/handlers/interactiveHandler.ts +10 -0
  167. package/tui/src/hooks/useApiKeyVerification.ts +1 -1
  168. package/tui/src/hooks/useVirtualScroll.ts +1 -1
  169. package/tui/src/ink/ink.tsx +33 -14
  170. package/tui/src/ink/reconciler.ts +2 -3
  171. package/tui/src/ink/render-to-screen.ts +30 -10
  172. package/tui/src/ipc/bridge.ts +62 -15
  173. package/tui/src/ipc/bridgeSingleton.ts +5 -1
  174. package/tui/src/ipc/codec.ts +3 -3
  175. package/tui/src/ipc/frames.generated.ts +12 -12
  176. package/tui/src/ipc/llmClient.ts +151 -27
  177. package/tui/src/ipc/schema/frame.schema.json +1 -1
  178. package/tui/src/keybindings/defaultBindings.ts +4 -0
  179. package/tui/src/main.tsx +32 -15
  180. package/tui/src/native-ts/file-index/index.ts +33 -3
  181. package/tui/src/observability/surface.ts +2 -2
  182. package/tui/src/probes/toolRegistryProbe.tsx +3 -1
  183. package/tui/src/projectOnboardingState.ts +7 -6
  184. package/tui/src/query/chatMessageTypes.ts +18 -0
  185. package/tui/src/query/chatMessagesBuilder.ts +1 -1
  186. package/tui/src/query/deps.ts +1 -1
  187. package/tui/src/query/messageGuards.ts +106 -0
  188. package/tui/src/query/publicDataTerminalRepair.ts +384 -0
  189. package/tui/src/query/run.ts +1075 -0
  190. package/tui/src/query/supportBoundary.ts +168 -0
  191. package/tui/src/query/toolResultErrors.ts +103 -0
  192. package/tui/src/query/toolRunner.ts +687 -0
  193. package/tui/src/query/unavailableToolRepair.ts +118 -0
  194. package/tui/src/query.ts +9 -2186
  195. package/tui/src/screens/REPL.tsx +40 -29
  196. package/tui/src/services/api/adapterManifest.ts +4 -0
  197. package/tui/src/services/api/backendChat/events.ts +117 -0
  198. package/tui/src/services/api/backendChat/finalMessage.ts +40 -0
  199. package/tui/src/services/api/backendChat/frame.ts +9 -0
  200. package/tui/src/services/api/backendChat/streaming.ts +430 -0
  201. package/tui/src/services/api/backendChat/types.ts +62 -0
  202. package/tui/src/services/api/backendChat.ts +1 -0
  203. package/tui/src/services/api/client.ts +65 -2
  204. package/tui/src/services/api/errorUtils.ts +5 -5
  205. package/tui/src/services/api/errors.ts +1 -1
  206. package/tui/src/services/api/logging.ts +1 -1
  207. package/tui/src/services/api/ummaya/evidence.ts +194 -0
  208. package/tui/src/services/api/ummaya/messages.ts +255 -0
  209. package/tui/src/services/api/ummaya/nonStreaming.ts +66 -0
  210. package/tui/src/services/api/ummaya/provider.ts +200 -0
  211. package/tui/src/services/api/ummaya/reasoning.ts +24 -0
  212. package/tui/src/services/api/ummaya/request.ts +200 -0
  213. package/tui/src/services/api/ummaya/selectionContext.ts +240 -0
  214. package/tui/src/services/api/ummaya/streaming.ts +365 -0
  215. package/tui/src/services/api/ummaya/streamingPayload.ts +129 -0
  216. package/tui/src/services/api/ummaya/streamingReader.ts +40 -0
  217. package/tui/src/services/api/ummaya/toolSelection.ts +217 -0
  218. package/tui/src/services/api/ummaya/types.ts +110 -0
  219. package/tui/src/services/api/ummaya/usage.ts +30 -0
  220. package/tui/src/services/api/ummaya.ts +26 -418
  221. package/tui/src/services/api/withRetry.ts +1 -1
  222. package/tui/src/services/awaySummary.ts +2 -2
  223. package/tui/src/services/claudeAiLimits.ts +1 -1
  224. package/tui/src/services/compact/autoCompact.ts +1 -1
  225. package/tui/src/services/compact/compact.ts +1 -1
  226. package/tui/src/services/lsp/types.ts +8 -30
  227. package/tui/src/services/tips/types.ts +6 -28
  228. package/tui/src/services/tokenEstimation.ts +1 -1
  229. package/tui/src/services/toolRegistry/bootGuard.ts +5 -5
  230. package/tui/src/services/toolUseSummary/toolUseSummaryGenerator.ts +1 -1
  231. package/tui/src/services/tools/toolExecution.ts +94 -1
  232. package/tui/src/store/pendingPermissionSlot.ts +1 -1
  233. package/tui/src/store/session-store.ts +10 -36
  234. package/tui/src/stubs/any-stub.ts +15 -10
  235. package/tui/src/stubs/color-diff-napi.ts +37 -23
  236. package/tui/src/stubs/globals.d.ts +3 -3
  237. package/tui/src/stubs/macro-preload.ts +23 -12
  238. package/tui/src/tools/AdapterTool/AdapterTool.ts +1207 -714
  239. package/tui/src/tools/AdapterTool/routeDiagnostics.ts +75 -0
  240. package/tui/src/tools/AgentTool/AgentTool.tsx +84 -1371
  241. package/tui/src/tools/AgentTool/agentToolHandoff.ts +114 -0
  242. package/tui/src/tools/AgentTool/agentToolPartialResult.ts +16 -0
  243. package/tui/src/tools/AgentTool/agentToolProgress.ts +32 -0
  244. package/tui/src/tools/AgentTool/agentToolResolver.ts +161 -0
  245. package/tui/src/tools/AgentTool/agentToolResult.ts +163 -0
  246. package/tui/src/tools/AgentTool/agentToolUtils.ts +14 -686
  247. package/tui/src/tools/AgentTool/asyncAgentLifecycle.ts +208 -0
  248. package/tui/src/tools/AgentTool/asyncLifecycle.ts +153 -0
  249. package/tui/src/tools/AgentTool/backgroundedCompletion.ts +126 -0
  250. package/tui/src/tools/AgentTool/backgroundedLifecycle.ts +174 -0
  251. package/tui/src/tools/AgentTool/foregroundBackground.ts +83 -0
  252. package/tui/src/tools/AgentTool/foregroundDrain.tsx +133 -0
  253. package/tui/src/tools/AgentTool/foregroundFinalize.ts +98 -0
  254. package/tui/src/tools/AgentTool/foregroundLifecycle.tsx +237 -0
  255. package/tui/src/tools/AgentTool/foregroundProgress.tsx +169 -0
  256. package/tui/src/tools/AgentTool/foregroundTask.ts +89 -0
  257. package/tui/src/tools/AgentTool/forkSubagent.ts +1 -12
  258. package/tui/src/tools/AgentTool/forkSubagentGate.ts +34 -0
  259. package/tui/src/tools/AgentTool/launchRouting.ts +203 -0
  260. package/tui/src/tools/AgentTool/lifecycle.ts +244 -0
  261. package/tui/src/tools/AgentTool/mcpRouting.ts +73 -0
  262. package/tui/src/tools/AgentTool/orchestrationSupport.ts +70 -0
  263. package/tui/src/tools/AgentTool/permissions.ts +39 -0
  264. package/tui/src/tools/AgentTool/promptSetup.ts +181 -0
  265. package/tui/src/tools/AgentTool/remoteRouting.ts +62 -0
  266. package/tui/src/tools/AgentTool/resultMapping.ts +116 -0
  267. package/tui/src/tools/AgentTool/resumeAgent.ts +39 -107
  268. package/tui/src/tools/AgentTool/resumeAgentHelpers.ts +140 -0
  269. package/tui/src/tools/AgentTool/runAgent.ts +1 -1
  270. package/tui/src/tools/AgentTool/runtimeConfig.ts +57 -0
  271. package/tui/src/tools/AgentTool/schemas.ts +196 -0
  272. package/tui/src/tools/AgentTool/sourceVerificationPropagation.ts +263 -0
  273. package/tui/src/tools/AgentTool/worktreeLifecycle.ts +105 -0
  274. package/tui/src/tools/AskUserQuestionTool/AskUserQuestionTool.tsx +174 -202
  275. package/tui/src/tools/BashTool/BashTool.tsx +71 -1072
  276. package/tui/src/tools/BashTool/bashCommandHelpers.ts +12 -12
  277. package/tui/src/tools/BashTool/bashPermissions/astPreflight.ts +173 -0
  278. package/tui/src/tools/BashTool/bashPermissions/classifierChecks.ts +199 -0
  279. package/tui/src/tools/BashTool/bashPermissions/compoundGuards.ts +53 -0
  280. package/tui/src/tools/BashTool/bashPermissions/constants.ts +99 -0
  281. package/tui/src/tools/BashTool/bashPermissions/index.ts +38 -0
  282. package/tui/src/tools/BashTool/bashPermissions/legacyMisparsing.ts +62 -0
  283. package/tui/src/tools/BashTool/bashPermissions/main.ts +135 -0
  284. package/tui/src/tools/BashTool/bashPermissions/normalizedCommands.ts +33 -0
  285. package/tui/src/tools/BashTool/bashPermissions/operatorFlow.ts +98 -0
  286. package/tui/src/tools/BashTool/bashPermissions/permissionChecks.ts +200 -0
  287. package/tui/src/tools/BashTool/bashPermissions/prefixSuggestions.ts +88 -0
  288. package/tui/src/tools/BashTool/bashPermissions/promptClassifierRules.ts +125 -0
  289. package/tui/src/tools/BashTool/bashPermissions/ruleDelegates.ts +19 -0
  290. package/tui/src/tools/BashTool/bashPermissions/ruleMatching.ts +145 -0
  291. package/tui/src/tools/BashTool/bashPermissions/sandboxAutoAllow.ts +75 -0
  292. package/tui/src/tools/BashTool/bashPermissions/subcommandFlow.ts +205 -0
  293. package/tui/src/tools/BashTool/bashPermissions/subcommandGuards.ts +73 -0
  294. package/tui/src/tools/BashTool/bashPermissions/subcommandResultHelpers.ts +116 -0
  295. package/tui/src/tools/BashTool/bashPermissions/types.ts +26 -0
  296. package/tui/src/tools/BashTool/bashPermissions/wrapperStripping.ts +139 -0
  297. package/tui/src/tools/BashTool/bashPermissions.ts +26 -2621
  298. package/tui/src/tools/BashTool/call.ts +202 -0
  299. package/tui/src/tools/BashTool/callLoader.ts +35 -0
  300. package/tui/src/tools/BashTool/commandClassification.ts +151 -0
  301. package/tui/src/tools/BashTool/commandClassificationLoader.ts +40 -0
  302. package/tui/src/tools/BashTool/cwdReset.ts +33 -0
  303. package/tui/src/tools/BashTool/lineTruncation.ts +11 -0
  304. package/tui/src/tools/BashTool/modeValidation.ts +13 -1
  305. package/tui/src/tools/BashTool/outputPersistence.ts +42 -0
  306. package/tui/src/tools/BashTool/permissionClassification.ts +66 -0
  307. package/tui/src/tools/BashTool/permissionLoader.ts +44 -0
  308. package/tui/src/tools/BashTool/resultLoader.ts +29 -0
  309. package/tui/src/tools/BashTool/resultMapping.ts +83 -0
  310. package/tui/src/tools/BashTool/sandboxPolicy.ts +79 -0
  311. package/tui/src/tools/BashTool/schemas.ts +65 -0
  312. package/tui/src/tools/BashTool/sedEditExecution.ts +59 -0
  313. package/tui/src/tools/BashTool/shellExecution.tsx +245 -0
  314. package/tui/src/tools/BashTool/shellOutputUtils.ts +85 -0
  315. package/tui/src/tools/BashTool/shellPermissionGauntlet.ts +97 -0
  316. package/tui/src/tools/BashTool/uiLoader.ts +37 -0
  317. package/tui/src/tools/BriefTool/upload.ts +1 -1
  318. package/tui/src/tools/CalculatorTool/parser.ts +2 -2
  319. package/tui/src/tools/DocumentPrimitive/DocumentPrimitive.ts +262 -0
  320. package/tui/src/tools/DocumentPrimitive/dispatchNormalization.ts +270 -0
  321. package/tui/src/tools/DocumentPrimitive/documentDestinationPath.ts +18 -0
  322. package/tui/src/tools/DocumentPrimitive/documentMutationGuard.ts +22 -0
  323. package/tui/src/tools/DocumentPrimitive/documentPatchNormalization.ts +248 -0
  324. package/tui/src/tools/DocumentPrimitive/documentSourceVerification.ts +245 -0
  325. package/tui/src/tools/DocumentPrimitive/documentSourceVerificationFields.ts +103 -0
  326. package/tui/src/tools/DocumentPrimitive/modelVisibleOutput.ts +40 -0
  327. package/tui/src/tools/DocumentPrimitive/prompt.ts +35 -0
  328. package/tui/src/tools/FileEditTool/FileEditTool.ts +9 -507
  329. package/tui/src/tools/FileEditTool/call.ts +228 -0
  330. package/tui/src/tools/FileEditTool/validateInput.ts +196 -0
  331. package/tui/src/tools/FileReadTool/imageProcessor.ts +13 -0
  332. package/tui/src/tools/FileWriteTool/FileWriteTool.ts +7 -300
  333. package/tui/src/tools/FileWriteTool/call.ts +223 -0
  334. package/tui/src/tools/FileWriteTool/validateInput.ts +80 -0
  335. package/tui/src/tools/ListMcpResourcesTool/ListMcpResourcesTool.ts +19 -3
  336. package/tui/src/tools/LookupPrimitive/LookupPrimitive.ts +25 -32
  337. package/tui/src/tools/LookupPrimitive/prompt.ts +0 -2
  338. package/tui/src/tools/MCPTool/trustPolicy.ts +118 -0
  339. package/tui/src/tools/McpAuthTool/McpAuthTool.ts +21 -3
  340. package/tui/src/tools/NotebookEditTool/NotebookEditTool.ts +7 -326
  341. package/tui/src/tools/NotebookEditTool/call.ts +254 -0
  342. package/tui/src/tools/NotebookEditTool/notebookModel.ts +51 -0
  343. package/tui/src/tools/NotebookEditTool/validateInput.ts +142 -0
  344. package/tui/src/tools/PowerShellTool/PowerShellTool.tsx +46 -937
  345. package/tui/src/tools/PowerShellTool/acceptEditsCommandValidation.ts +162 -0
  346. package/tui/src/tools/PowerShellTool/call.ts +179 -0
  347. package/tui/src/tools/PowerShellTool/callLoader.ts +37 -0
  348. package/tui/src/tools/PowerShellTool/commandClassification.ts +86 -0
  349. package/tui/src/tools/PowerShellTool/modeValidation.ts +25 -332
  350. package/tui/src/tools/PowerShellTool/outputPersistence.ts +42 -0
  351. package/tui/src/tools/PowerShellTool/permissionClassification.ts +28 -0
  352. package/tui/src/tools/PowerShellTool/resultLoader.ts +31 -0
  353. package/tui/src/tools/PowerShellTool/resultMapping.ts +75 -0
  354. package/tui/src/tools/PowerShellTool/schemas.ts +40 -0
  355. package/tui/src/tools/PowerShellTool/shellExecution.tsx +258 -0
  356. package/tui/src/tools/PowerShellTool/symlinkModeValidation.ts +44 -0
  357. package/tui/src/tools/PowerShellTool/uiLoader.ts +37 -0
  358. package/tui/src/tools/PowerShellTool/validation.ts +39 -0
  359. package/tui/src/tools/ReadMcpResourceTool/ReadMcpResourceTool.ts +19 -3
  360. package/tui/src/tools/ResolveLocationPrimitive/ResolveLocationPrimitive.ts +1 -11
  361. package/tui/src/tools/ResolveLocationPrimitive/prompt.ts +2 -6
  362. package/tui/src/tools/SkillTool/SkillTool.ts +2 -2
  363. package/tui/src/tools/SubmitPrimitive/SubmitPrimitive.ts +27 -10
  364. package/tui/src/tools/TaskCreateTool/TaskCreateTool.ts +16 -2
  365. package/tui/src/tools/TaskGetTool/TaskGetTool.ts +23 -3
  366. package/tui/src/tools/TaskListTool/TaskListTool.ts +22 -4
  367. package/tui/src/tools/TaskOutputTool/TaskOutputTool.tsx +46 -547
  368. package/tui/src/tools/TaskOutputTool/lookup.ts +216 -0
  369. package/tui/src/tools/TaskOutputTool/render.tsx +257 -0
  370. package/tui/src/tools/TaskOutputTool/schemas.ts +55 -0
  371. package/tui/src/tools/TaskOutputTool/serialization.ts +36 -0
  372. package/tui/src/tools/TaskStopTool/TaskStopTool.ts +10 -0
  373. package/tui/src/tools/TaskUpdateTool/TaskUpdateTool.ts +14 -364
  374. package/tui/src/tools/TaskUpdateTool/completion.ts +62 -0
  375. package/tui/src/tools/TaskUpdateTool/schemas.ts +62 -0
  376. package/tui/src/tools/TaskUpdateTool/serialization.ts +46 -0
  377. package/tui/src/tools/TaskUpdateTool/statusUpdate.ts +247 -0
  378. package/tui/src/tools/TodoWriteTool/TodoWriteTool.ts +21 -2
  379. package/tui/src/tools/ToolSearchTool/ToolSearchTool.ts +21 -302
  380. package/tui/src/tools/ToolSearchTool/ccSupportTools.ts +223 -0
  381. package/tui/src/tools/ToolSearchTool/descriptionCache.ts +50 -0
  382. package/tui/src/tools/ToolSearchTool/keywordSearch.ts +216 -0
  383. package/tui/src/tools/ToolSearchTool/prompt.ts +10 -4
  384. package/tui/src/tools/ToolSearchTool/resultMapping.ts +30 -0
  385. package/tui/src/tools/ToolSearchTool/schemas.ts +30 -0
  386. package/tui/src/tools/ToolSearchTool/searchPool.ts +47 -0
  387. package/tui/src/tools/ToolSearchTool/supportIntentHints.ts +140 -0
  388. package/tui/src/tools/TranslateTool/TranslateTool.ts +1 -1
  389. package/tui/src/tools/VerifyPrimitive/VerifyPrimitive.ts +2 -1
  390. package/tui/src/tools/WebFetchTool/WebFetchTool.ts +43 -138
  391. package/tui/src/tools/WebFetchTool/call.ts +227 -0
  392. package/tui/src/tools/WebFetchTool/resolvedAddressSafety.ts +78 -0
  393. package/tui/src/tools/WebFetchTool/sourceVerification.ts +204 -0
  394. package/tui/src/tools/WebFetchTool/types.ts +23 -0
  395. package/tui/src/tools/WebFetchTool/urlSafety.ts +181 -0
  396. package/tui/src/tools/WebFetchTool/utils.ts +1 -1
  397. package/tui/src/tools/WebSearchTool/UI.tsx +0 -1
  398. package/tui/src/tools/WebSearchTool/WebSearchTool.ts +9 -313
  399. package/tui/src/tools/WebSearchTool/call.ts +33 -0
  400. package/tui/src/tools/WebSearchTool/responseMapping.ts +190 -0
  401. package/tui/src/tools/WebSearchTool/resultBlock.ts +47 -0
  402. package/tui/src/tools/WebSearchTool/schemas.ts +47 -0
  403. package/tui/src/tools/WebSearchTool/toolSchema.ts +12 -0
  404. package/tui/src/tools/WorkspaceToolAdapter/WorkspaceToolAdapter.ts +79 -0
  405. package/tui/src/tools/WorkspaceToolAdapter/allowedRootPolicy.ts +85 -0
  406. package/tui/src/tools/WorkspaceToolAdapter/documentFormatGuards.ts +73 -0
  407. package/tui/src/tools/WorkspaceToolAdapter/inputNormalization.ts +105 -0
  408. package/tui/src/tools/WorkspaceToolAdapter/mcpExposurePolicy.ts +64 -0
  409. package/tui/src/tools/WorkspaceToolAdapter/toolDefFactory.ts +215 -0
  410. package/tui/src/tools/WorkspaceToolAdapter/toolNames.ts +6 -0
  411. package/tui/src/tools/WorkspaceToolAdapter/workspacePolicy.ts +15 -0
  412. package/tui/src/tools/_shared/dispatchPrimitive.ts +6 -6
  413. package/tui/src/tools/_shared/documentChangeToPatch.ts +125 -0
  414. package/tui/src/tools/_shared/documentDispatchArguments.ts +87 -0
  415. package/tui/src/tools/_shared/documentPrimitiveTimeout.ts +13 -0
  416. package/tui/src/tools/_shared/documentToolResultRender.ts +98 -0
  417. package/tui/src/tools/_shared/pendingCallRegistry.ts +1 -6
  418. package/tui/src/tools/_shared/rootPrimitiveInput.ts +1 -0
  419. package/tui/src/tools/_shared/toolChoiceRepair/documentCompletionPatterns.ts +58 -0
  420. package/tui/src/tools/_shared/toolChoiceRepair/documentCompletionPrompt.ts +271 -0
  421. package/tui/src/tools/_shared/toolChoiceRepair/documentRepair.ts +452 -0
  422. package/tui/src/tools/_shared/toolChoiceRepair/messageAccess.ts +80 -0
  423. package/tui/src/tools/_shared/toolChoiceRepair/publicDataRepair.ts +92 -0
  424. package/tui/src/tools/_shared/toolChoiceRepair/supportRepair.ts +135 -0
  425. package/tui/src/tools/_shared/toolChoiceRepair.ts +55 -860
  426. package/tui/src/tools/shared/mockDisclaimer.ts +1 -1
  427. package/tui/src/tools.ts +39 -190
  428. package/tui/src/types/fileSuggestion.ts +4 -26
  429. package/tui/src/types/generated/events_mono/claude_code/v1/claude_code_internal_event.ts +186 -148
  430. package/tui/src/types/generated/events_mono/common/v1/auth.ts +25 -11
  431. package/tui/src/types/generated/events_mono/growthbook/v1/growthbook_experiment_event.ts +47 -30
  432. package/tui/src/types/generated/google/protobuf/timestamp.ts +21 -7
  433. package/tui/src/types/message.ts +80 -102
  434. package/tui/src/types/messageQueueTypes.ts +6 -28
  435. package/tui/src/types/notebook.ts +16 -38
  436. package/tui/src/types/statusLine.ts +4 -26
  437. package/tui/src/types/tools.ts +24 -46
  438. package/tui/src/types/utils.ts +6 -28
  439. package/tui/src/upstreamproxy/relay.ts +7 -3
  440. package/tui/src/upstreamproxy/upstreamproxy.ts +1 -1
  441. package/tui/src/utils/assistantMessageFactories.ts +9 -3
  442. package/tui/src/utils/auth.ts +129 -139
  443. package/tui/src/utils/bash/ast.ts +23 -23
  444. package/tui/src/utils/bash/bashParser.ts +5 -5
  445. package/tui/src/utils/billing.ts +1 -1
  446. package/tui/src/utils/claudeDesktop.ts +4 -4
  447. package/tui/src/utils/collapseReadSearch.ts +3 -3
  448. package/tui/src/utils/cronTasks.ts +1 -1
  449. package/tui/src/utils/execFileNoThrow.ts +1 -1
  450. package/tui/src/utils/filePersistence/types.ts +16 -38
  451. package/tui/src/utils/forkedAgent.ts +1 -1
  452. package/tui/src/utils/gracefulShutdown.ts +4 -4
  453. package/tui/src/utils/heapDumpService.ts +12 -8
  454. package/tui/src/utils/hooks/apiQueryHookHelper.ts +1 -1
  455. package/tui/src/utils/hooks/execPromptHook.ts +1 -1
  456. package/tui/src/utils/hooks/skillImprovement.ts +1 -1
  457. package/tui/src/utils/mcp/dateTimeParser.ts +1 -1
  458. package/tui/src/utils/messages.ts +18 -0
  459. package/tui/src/utils/migrateSessions.ts +3 -3
  460. package/tui/src/utils/model/model.ts +6 -6
  461. package/tui/src/utils/permissions/yoloClassifier.ts +1 -1
  462. package/tui/src/utils/plugins/headlessPluginInstall.ts +1 -1
  463. package/tui/src/utils/plugins/mcpPluginIntegration.ts +1 -1
  464. package/tui/src/utils/plugins/mcpbHandler.ts +1 -1
  465. package/tui/src/utils/plugins/pluginLoader.ts +8 -8
  466. package/tui/src/utils/protectedNamespace.ts +5 -3
  467. package/tui/src/utils/rawJsonToolCall.ts +242 -0
  468. package/tui/src/utils/ripgrep.ts +16 -7
  469. package/tui/src/utils/sessionTitle.ts +1 -1
  470. package/tui/src/utils/settings/permissionValidation.ts +14 -2
  471. package/tui/src/utils/shell/prefix.ts +1 -1
  472. package/tui/src/utils/sideQuery.ts +1 -1
  473. package/tui/src/utils/systemThemeWatcher.ts +13 -3
  474. package/tui/src/utils/teleport.tsx +1 -1
  475. package/uv.lock +426 -45
  476. package/tui/src/services/api/claude.ts +0 -3540
  477. package/tui/src/tools/_shared/directPublicDataGuard.ts +0 -362
  478. package/tui/src/tools/_shared/kmaAnalysisGuard.ts +0 -197
  479. package/tui/src/tools/_shared/kmaAviationGuard.ts +0 -70
  480. package/tui/src/tools/_shared/nmcAedGuard.ts +0 -234
  481. package/tui/src/tools/_shared/protectedCheckGuard.ts +0 -207
  482. package/tui/src/tools/_shared/textToolCallGuard.ts +0 -91
@@ -0,0 +1,70 @@
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ """Evidence Fabric gate construction."""
3
+
4
+ from __future__ import annotations
5
+
6
+ from typing import Literal
7
+
8
+ from ummaya.evidence.dataset_contract import REQUIRED_DOMAINS, ScenarioDataset
9
+ from ummaya.evidence.models import EvidenceGate
10
+
11
+
12
+ def build_gates(dataset: ScenarioDataset) -> tuple[EvidenceGate, ...]:
13
+ """Build deterministic Evidence Fabric gate summaries."""
14
+ covered_domains = set(dataset.coverage_domains)
15
+ missing_domains = tuple(sorted(REQUIRED_DOMAINS - covered_domains))
16
+ scenario_domains = {scenario.lifecycle_domain for scenario in dataset.scenarios}
17
+ uncovered = tuple(sorted(scenario_domains - covered_domains))
18
+ scenario_status: Literal["pass", "fail"] = (
19
+ "pass" if not missing_domains and not uncovered else "fail"
20
+ )
21
+ scenario_summary = (
22
+ "all required citizen infrastructure domains are covered"
23
+ if scenario_status == "pass"
24
+ else "missing coverage: " + ", ".join(missing_domains + uncovered)
25
+ )
26
+ return (
27
+ _gate(
28
+ "contract",
29
+ "pass",
30
+ "dataset is versioned, typed, and free of model-visible route-cheat keys",
31
+ ("dataset-schema", "task-registry", "no-adapter-leakage", "no-route-cheat-keys"),
32
+ ),
33
+ _gate(
34
+ "scenario", scenario_status, scenario_summary, ("coverage-domains", "scenario-shape")
35
+ ),
36
+ _gate(
37
+ "observability",
38
+ "pass",
39
+ "RunEvidence carries route traces, route-selection assertions, and join keys",
40
+ ("trace-join-keys", "route-selection-assertions"),
41
+ ),
42
+ _gate(
43
+ "adversarial",
44
+ "pass",
45
+ "adapter IDs, fixture references, expected tool IDs, and route assertion "
46
+ "cheats are rejected before scoring",
47
+ ("reward-hack-surface", "hidden-implementation-leakage", "route-assertion-cheats"),
48
+ ),
49
+ _gate(
50
+ "ux",
51
+ "skip",
52
+ "UX frame artifacts are attached by interactive runners, not by dataset validation",
53
+ ("ux-artifact-slot",),
54
+ ),
55
+ _gate(
56
+ "live_canary",
57
+ "skip",
58
+ "live public-service checks are manual-only and excluded from CI",
59
+ ("no-live-ci",),
60
+ ),
61
+ )
62
+
63
+
64
+ def _gate(
65
+ name: Literal["contract", "scenario", "observability", "adversarial", "ux", "live_canary"],
66
+ status: Literal["pass", "fail", "skip"],
67
+ summary: str,
68
+ check_ids: tuple[str, ...],
69
+ ) -> EvidenceGate:
70
+ return EvidenceGate(name=name, status=status, summary=summary, check_ids=check_ids)
@@ -0,0 +1,20 @@
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ """JSON-compatible type aliases for Evidence Fabric payload assembly."""
3
+
4
+ from __future__ import annotations
5
+
6
+ from typing import Final
7
+
8
+ from pydantic import TypeAdapter
9
+
10
+ type JsonScalar = str | int | float | bool | None
11
+ type JsonValue = JsonScalar | list[JsonValue] | dict[str, JsonValue]
12
+ type JsonArray = list[JsonValue]
13
+ type JsonObject = dict[str, JsonValue]
14
+
15
+ _JSON_OBJECT_ADAPTER: Final[TypeAdapter[JsonObject]] = TypeAdapter(JsonObject)
16
+
17
+
18
+ def parse_json_object(value: JsonValue) -> JsonObject:
19
+ """Parse a JSON-compatible value into a JSON mapping."""
20
+ return _JSON_OBJECT_ADAPTER.validate_python(value)
@@ -7,9 +7,33 @@ from datetime import UTC, datetime
7
7
  from typing import Literal
8
8
  from uuid import uuid4
9
9
 
10
- from pydantic import BaseModel, ConfigDict, Field
10
+ from pydantic import BaseModel, ConfigDict, Field, field_validator
11
+
12
+ from ummaya.evidence.tool_layer_models import ToolLayerEvidenceEvent
13
+ from ummaya.tools.routing.decision_types import RouteStopReason
11
14
 
12
15
  EvidenceStatus = Literal["pass", "fail", "skip"]
16
+ RouteTraceKind = Literal["scenario_route", "negative_control"]
17
+ RouteTraceSource = Literal["expected_route_contract", "route_decision"]
18
+ RouteAssertionStatus = Literal["pass", "fail"]
19
+ RouteAdapterFamily = Literal[
20
+ "public_service_channel",
21
+ "location_channel",
22
+ "weather_channel",
23
+ "safety_channel",
24
+ "procurement_channel",
25
+ "public_data_channel",
26
+ "document_harness",
27
+ "no_tool",
28
+ ]
29
+ RouteArgumentFeasibility = Literal["sufficient", "needs_clarification", "blocked"]
30
+ RouteFailureRecovery = Literal[
31
+ "not_required",
32
+ "permission_gate",
33
+ "clarification",
34
+ "handoff",
35
+ "blocked",
36
+ ]
13
37
  EvidenceGateName = Literal[
14
38
  "contract",
15
39
  "scenario",
@@ -31,6 +55,66 @@ class EvidenceGate(BaseModel):
31
55
  check_ids: tuple[str, ...] = Field(default_factory=tuple)
32
56
 
33
57
 
58
+ class RouteTraceRecord(BaseModel):
59
+ model_config = ConfigDict(frozen=True, extra="forbid")
60
+
61
+ trace_kind: RouteTraceKind = "scenario_route"
62
+ route_source: RouteTraceSource = "expected_route_contract"
63
+ scenario_id: str = Field(min_length=1)
64
+ trace_id: str = Field(min_length=1)
65
+ correlation_id: str = Field(min_length=1)
66
+ query_hash: str = Field(min_length=64, max_length=64)
67
+ manifest_hash: str = Field(min_length=64, max_length=64)
68
+ prompt_manifest_hash: str = Field(min_length=64, max_length=64)
69
+ tool_catalog_hash: str = Field(min_length=64, max_length=64)
70
+ selected_domain: str = Field(min_length=1)
71
+ selected_primitives: tuple[str, ...] = Field(default_factory=tuple)
72
+ selected_tools: tuple[str, ...] = Field(default_factory=tuple)
73
+ clarification_reason: str | None = None
74
+ stop_reason: RouteStopReason
75
+ evidence_events: tuple[str, ...] = Field(default_factory=tuple)
76
+
77
+ @field_validator("query_hash", "manifest_hash", "prompt_manifest_hash", "tool_catalog_hash")
78
+ @classmethod
79
+ def _validate_hash(cls, value: str) -> str:
80
+ if len(value) != 64 or any(ch not in "0123456789abcdef" for ch in value):
81
+ raise ValueError("hash fields must be lowercase SHA-256 hex")
82
+ return value
83
+
84
+
85
+ class RouteSelectionAssertion(BaseModel):
86
+ model_config = ConfigDict(frozen=True, extra="forbid")
87
+
88
+ assertion_kind: RouteTraceKind = "scenario_route"
89
+ route_source: RouteTraceSource = "expected_route_contract"
90
+ status: RouteAssertionStatus
91
+ scenario_id: str = Field(min_length=1)
92
+ trace_id: str = Field(min_length=1)
93
+ correlation_id: str = Field(min_length=1)
94
+ prompt_manifest_hash: str = Field(min_length=64, max_length=64)
95
+ tool_catalog_hash: str = Field(min_length=64, max_length=64)
96
+ expected_domain: str = Field(min_length=1)
97
+ selected_domain: str = Field(min_length=1)
98
+ expected_primitives: tuple[str, ...] = Field(default_factory=tuple)
99
+ selected_primitives: tuple[str, ...] = Field(default_factory=tuple)
100
+ adapter_family: RouteAdapterFamily
101
+ argument_feasibility: RouteArgumentFeasibility
102
+ clarification_expected: bool
103
+ clarification_reason: str | None
104
+ stop_reason: RouteStopReason
105
+ failure_recovery: RouteFailureRecovery
106
+ coverage_tags: tuple[str, ...] = Field(default_factory=tuple)
107
+ selected_tool_ids: tuple[str, ...] = Field(default_factory=tuple)
108
+ assertion_events: tuple[str, ...] = Field(default_factory=tuple)
109
+
110
+ @field_validator("prompt_manifest_hash", "tool_catalog_hash")
111
+ @classmethod
112
+ def _validate_hash(cls, value: str) -> str:
113
+ if len(value) != 64 or any(ch not in "0123456789abcdef" for ch in value):
114
+ raise ValueError("hash fields must be lowercase SHA-256 hex")
115
+ return value
116
+
117
+
34
118
  class RunEvidence(BaseModel):
35
119
  """Top-level immutable evidence document emitted by the v2 runner."""
36
120
 
@@ -47,6 +131,9 @@ class RunEvidence(BaseModel):
47
131
  task_ids: tuple[str, ...] = Field(default_factory=tuple)
48
132
  scenario_count: int
49
133
  scenario_ids: tuple[str, ...]
134
+ route_trace_records: tuple[RouteTraceRecord, ...] = Field(default_factory=tuple)
135
+ route_selection_assertions: tuple[RouteSelectionAssertion, ...] = Field(default_factory=tuple)
136
+ tool_layer_events: tuple[ToolLayerEvidenceEvent, ...] = Field(default_factory=tuple)
50
137
  gates: tuple[EvidenceGate, ...]
51
138
  trace_join_keys: tuple[str, ...] = (
52
139
  "scenario_id",
@@ -0,0 +1,89 @@
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ """JSON payload assembly for Evidence Fabric v2."""
3
+
4
+ from __future__ import annotations
5
+
6
+ from collections.abc import Mapping, Sequence
7
+ from typing import assert_never
8
+
9
+ from ummaya.evidence.document_viewer_ux import DocumentViewerUxArtifact
10
+ from ummaya.evidence.json_types import JsonArray, JsonObject, JsonValue, parse_json_object
11
+ from ummaya.evidence.models import RunEvidence
12
+ from ummaya.evidence.payload_documents import append_document_harness_payload
13
+
14
+
15
+ def build_evidence_output_payload(
16
+ evidence: RunEvidence,
17
+ *,
18
+ include_document_harness: bool = True,
19
+ document_viewer_ux_artifacts: Sequence[DocumentViewerUxArtifact] = (),
20
+ hwp_bridge_probe_env: Mapping[str, str] | None = None,
21
+ hwp_bridge_probe_search_path: Sequence[str] | None = None,
22
+ odf_probe_env: Mapping[str, str] | None = None,
23
+ odf_probe_search_path: Sequence[str] | None = None,
24
+ odf_probe_importable_modules: frozenset[str] | None = None,
25
+ pdfa_probe_env: Mapping[str, str] | None = None,
26
+ pdfa_probe_search_path: Sequence[str] | None = None,
27
+ archive_probe_env: Mapping[str, str] | None = None,
28
+ archive_probe_search_path: Sequence[str] | None = None,
29
+ passive_probe_env: Mapping[str, str] | None = None,
30
+ passive_probe_search_path: Sequence[str] | None = None,
31
+ passive_probe_importable_modules: frozenset[str] | None = None,
32
+ legacy_office_probe_env: Mapping[str, str] | None = None,
33
+ legacy_office_probe_search_path: Sequence[str] | None = None,
34
+ ) -> JsonObject:
35
+ """Build the JSON payload emitted by the Evidence Fabric CLI."""
36
+ payload = parse_json_object(evidence.model_dump(mode="json"))
37
+ if document_viewer_ux_artifacts:
38
+ payload["gates"] = _with_passed_ux_gate(payload["gates"])
39
+ payload["ux_artifacts"] = [
40
+ parse_json_object(artifact.model_dump(mode="json"))
41
+ for artifact in document_viewer_ux_artifacts
42
+ ]
43
+ if include_document_harness:
44
+ append_document_harness_payload(
45
+ payload,
46
+ document_viewer_ux_artifacts=document_viewer_ux_artifacts,
47
+ hwp_bridge_probe_env=hwp_bridge_probe_env,
48
+ hwp_bridge_probe_search_path=hwp_bridge_probe_search_path,
49
+ odf_probe_env=odf_probe_env,
50
+ odf_probe_search_path=odf_probe_search_path,
51
+ odf_probe_importable_modules=odf_probe_importable_modules,
52
+ pdfa_probe_env=pdfa_probe_env,
53
+ pdfa_probe_search_path=pdfa_probe_search_path,
54
+ archive_probe_env=archive_probe_env,
55
+ archive_probe_search_path=archive_probe_search_path,
56
+ passive_probe_env=passive_probe_env,
57
+ passive_probe_search_path=passive_probe_search_path,
58
+ passive_probe_importable_modules=passive_probe_importable_modules,
59
+ legacy_office_probe_env=legacy_office_probe_env,
60
+ legacy_office_probe_search_path=legacy_office_probe_search_path,
61
+ )
62
+ return payload
63
+
64
+
65
+ def _with_passed_ux_gate(gates: JsonValue) -> JsonArray:
66
+ match gates:
67
+ case list():
68
+ promoted: JsonArray = []
69
+ for gate in gates:
70
+ match gate:
71
+ case dict() if gate.get("name") == "ux":
72
+ check_ids: JsonArray = ["document-viewer-playwright-png", "frame-hash"]
73
+ promoted.append(
74
+ {
75
+ **gate,
76
+ "status": "pass",
77
+ "summary": "Playwright document viewer UX artifacts are attached",
78
+ "check_ids": check_ids,
79
+ }
80
+ )
81
+ case dict() | list() | str() | int() | float() | bool() | None:
82
+ promoted.append(gate)
83
+ case unreachable:
84
+ assert_never(unreachable)
85
+ return promoted
86
+ case dict() | str() | int() | float() | bool() | None:
87
+ return []
88
+ case unreachable:
89
+ assert_never(unreachable)
@@ -0,0 +1,233 @@
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ """Document harness payload enrichment for Evidence Fabric output."""
3
+
4
+ from __future__ import annotations
5
+
6
+ import os
7
+ from collections.abc import Mapping, Sequence
8
+ from pathlib import Path
9
+
10
+ from ummaya.evidence.dataset_contract import _REPO_ROOT
11
+ from ummaya.evidence.document_harness import (
12
+ DocumentEvidenceRecord,
13
+ DocumentHarnessEvidenceError,
14
+ authoring_cases_from_scenario,
15
+ beta_cases_from_scenario,
16
+ lifecycle_records_from_scenario,
17
+ load_document_harness_scenario,
18
+ negative_cases_from_scenario,
19
+ records_from_scenario,
20
+ )
21
+ from ummaya.evidence.document_viewer_ux import DocumentViewerUxArtifact
22
+ from ummaya.evidence.json_types import JsonObject, parse_json_object
23
+ from ummaya.tools.documents.hwp_conversion_probe import (
24
+ HWPXJS_CANDIDATE_ID,
25
+ HwpToHwpxBridgeProbeReport,
26
+ probe_hwp_to_hwpx_bridge,
27
+ )
28
+ from ummaya.tools.documents.legacy_office_promotion_probe import (
29
+ LegacyOfficePromotionProbeReport,
30
+ probe_legacy_office_promotion,
31
+ )
32
+ from ummaya.tools.documents.models import KnownDocumentFormat
33
+
34
+
35
+ def append_document_harness_payload(
36
+ payload: JsonObject,
37
+ *,
38
+ document_viewer_ux_artifacts: Sequence[DocumentViewerUxArtifact],
39
+ hwp_bridge_probe_env: Mapping[str, str] | None,
40
+ hwp_bridge_probe_search_path: Sequence[str] | None,
41
+ odf_probe_env: Mapping[str, str] | None,
42
+ odf_probe_search_path: Sequence[str] | None,
43
+ odf_probe_importable_modules: frozenset[str] | None,
44
+ pdfa_probe_env: Mapping[str, str] | None,
45
+ pdfa_probe_search_path: Sequence[str] | None,
46
+ archive_probe_env: Mapping[str, str] | None,
47
+ archive_probe_search_path: Sequence[str] | None,
48
+ passive_probe_env: Mapping[str, str] | None,
49
+ passive_probe_search_path: Sequence[str] | None,
50
+ passive_probe_importable_modules: frozenset[str] | None,
51
+ legacy_office_probe_env: Mapping[str, str] | None,
52
+ legacy_office_probe_search_path: Sequence[str] | None,
53
+ ) -> None:
54
+ """Attach document harness records and local probe outputs to a payload."""
55
+ scenario = load_document_harness_scenario()
56
+ document_records = records_from_scenario(scenario)
57
+ _validate_document_viewer_ux_joins(document_records, document_viewer_ux_artifacts)
58
+ payload["document_evidence_records"] = [
59
+ parse_json_object(record.model_dump(mode="json")) for record in document_records
60
+ ]
61
+ payload["document_lifecycle_records"] = [
62
+ parse_json_object(record.model_dump(mode="json"))
63
+ for record in lifecycle_records_from_scenario(scenario)
64
+ ]
65
+ payload["document_beta_cases"] = [
66
+ parse_json_object(case.model_dump(mode="json"))
67
+ for case in beta_cases_from_scenario(scenario)
68
+ ]
69
+ payload["document_negative_cases"] = [
70
+ parse_json_object(case.model_dump(mode="json"))
71
+ for case in negative_cases_from_scenario(scenario)
72
+ ]
73
+ payload["document_authoring_cases"] = [
74
+ parse_json_object(case.model_dump(mode="json"))
75
+ for case in authoring_cases_from_scenario(scenario)
76
+ ]
77
+ bridge_probe = probe_hwp_to_hwpx_bridge(
78
+ env=hwp_bridge_probe_env,
79
+ search_path=_default_hwp_bridge_probe_search_path(
80
+ env=hwp_bridge_probe_env,
81
+ explicit_search_path=hwp_bridge_probe_search_path,
82
+ ),
83
+ )
84
+ payload["document_bridge_probe_records"] = [
85
+ parse_json_object(bridge_probe.model_dump(mode="json"))
86
+ ]
87
+ _append_document_promotion_payload(
88
+ payload,
89
+ bridge_probe=bridge_probe,
90
+ odf_probe_env=odf_probe_env,
91
+ odf_probe_search_path=odf_probe_search_path,
92
+ odf_probe_importable_modules=odf_probe_importable_modules,
93
+ pdfa_probe_env=pdfa_probe_env,
94
+ pdfa_probe_search_path=pdfa_probe_search_path,
95
+ archive_probe_env=archive_probe_env,
96
+ archive_probe_search_path=archive_probe_search_path,
97
+ passive_probe_env=passive_probe_env,
98
+ passive_probe_search_path=passive_probe_search_path,
99
+ passive_probe_importable_modules=passive_probe_importable_modules,
100
+ legacy_office_probe_env=legacy_office_probe_env,
101
+ legacy_office_probe_search_path=legacy_office_probe_search_path,
102
+ )
103
+
104
+
105
+ def _append_document_promotion_payload(
106
+ payload: JsonObject,
107
+ *,
108
+ bridge_probe: HwpToHwpxBridgeProbeReport,
109
+ odf_probe_env: Mapping[str, str] | None,
110
+ odf_probe_search_path: Sequence[str] | None,
111
+ odf_probe_importable_modules: frozenset[str] | None,
112
+ pdfa_probe_env: Mapping[str, str] | None,
113
+ pdfa_probe_search_path: Sequence[str] | None,
114
+ archive_probe_env: Mapping[str, str] | None,
115
+ archive_probe_search_path: Sequence[str] | None,
116
+ passive_probe_env: Mapping[str, str] | None,
117
+ passive_probe_search_path: Sequence[str] | None,
118
+ passive_probe_importable_modules: frozenset[str] | None,
119
+ legacy_office_probe_env: Mapping[str, str] | None,
120
+ legacy_office_probe_search_path: Sequence[str] | None,
121
+ ) -> None:
122
+ from ummaya.tools.documents.archive_container_probe import probe_archive_container_promotion
123
+ from ummaya.tools.documents.format_completion_audit import audit_document_format_completion
124
+ from ummaya.tools.documents.odf_promotion_probe import probe_odf_promotion
125
+ from ummaya.tools.documents.passive_capability_probe import probe_passive_capabilities
126
+ from ummaya.tools.documents.pdfa_promotion_probe import probe_pdfa_promotion
127
+
128
+ odf_probe_records = probe_odf_promotion(
129
+ env=odf_probe_env,
130
+ search_path=odf_probe_search_path,
131
+ importable_modules=odf_probe_importable_modules,
132
+ )
133
+ pdfa_probe_record = probe_pdfa_promotion(
134
+ env=pdfa_probe_env,
135
+ search_path=pdfa_probe_search_path,
136
+ )
137
+ archive_probe_records = probe_archive_container_promotion(
138
+ env=archive_probe_env,
139
+ search_path=archive_probe_search_path,
140
+ )
141
+ passive_probe_records = probe_passive_capabilities(
142
+ env=passive_probe_env,
143
+ search_path=passive_probe_search_path,
144
+ importable_modules=passive_probe_importable_modules,
145
+ )
146
+ legacy_office_probe_records = probe_legacy_office_promotion(
147
+ env=legacy_office_probe_env,
148
+ search_path=legacy_office_probe_search_path,
149
+ )
150
+ payload["document_odf_probe_records"] = [
151
+ parse_json_object(record.model_dump(mode="json")) for record in odf_probe_records
152
+ ]
153
+ payload["document_pdfa_probe_records"] = [
154
+ parse_json_object(pdfa_probe_record.model_dump(mode="json"))
155
+ ]
156
+ payload["document_archive_probe_records"] = [
157
+ parse_json_object(record.model_dump(mode="json")) for record in archive_probe_records
158
+ ]
159
+ payload["document_passive_probe_records"] = [
160
+ parse_json_object(record.model_dump(mode="json")) for record in passive_probe_records
161
+ ]
162
+ payload["document_legacy_office_probe_records"] = [
163
+ parse_json_object(record.model_dump(mode="json")) for record in legacy_office_probe_records
164
+ ]
165
+ format_completion_audit = audit_document_format_completion(
166
+ derivative_promoted_formats=_derivative_promoted_formats_from_probe_records(
167
+ bridge_probe=bridge_probe,
168
+ legacy_office_probe_records=legacy_office_probe_records,
169
+ ),
170
+ pdfa_conformance_promoted=pdfa_probe_record.status == "candidate_available",
171
+ )
172
+ payload["document_format_completion_audit"] = parse_json_object(
173
+ format_completion_audit.model_dump(mode="json")
174
+ )
175
+
176
+
177
+ def _derivative_promoted_formats_from_probe_records(
178
+ *,
179
+ bridge_probe: HwpToHwpxBridgeProbeReport,
180
+ legacy_office_probe_records: Sequence[LegacyOfficePromotionProbeReport],
181
+ ) -> frozenset[KnownDocumentFormat]:
182
+ promoted: set[KnownDocumentFormat] = set()
183
+ if bridge_probe.status == "configured" or (
184
+ bridge_probe.status == "available" and bridge_probe.candidate_id == HWPXJS_CANDIDATE_ID
185
+ ):
186
+ promoted.add(KnownDocumentFormat.hwp)
187
+ for record in legacy_office_probe_records:
188
+ if record.status == "candidate_available":
189
+ promoted.add(record.known_format)
190
+ return frozenset(promoted)
191
+
192
+
193
+ def _default_hwp_bridge_probe_search_path(
194
+ *,
195
+ env: Mapping[str, str] | None,
196
+ explicit_search_path: Sequence[str] | None,
197
+ ) -> Sequence[str] | None:
198
+ if explicit_search_path is not None:
199
+ return explicit_search_path
200
+ if env is not None:
201
+ return None
202
+ paths: list[str] = []
203
+ for root in (Path.cwd(), _REPO_ROOT):
204
+ node_bin = root / "node_modules" / ".bin"
205
+ node_bin_str = str(node_bin)
206
+ if node_bin_str not in paths:
207
+ paths.append(node_bin_str)
208
+ process_path = os.environ.get("PATH", "")
209
+ paths.extend(part for part in process_path.split(os.pathsep) if part)
210
+ return tuple(paths) if paths else None
211
+
212
+
213
+ def _validate_document_viewer_ux_joins(
214
+ document_records: Sequence[DocumentEvidenceRecord],
215
+ document_viewer_ux_artifacts: Sequence[DocumentViewerUxArtifact],
216
+ ) -> None:
217
+ if not document_viewer_ux_artifacts:
218
+ return
219
+ valid_joins = {
220
+ (record.structured_diff_id, record.correlation_id) for record in document_records
221
+ }
222
+ for artifact in document_viewer_ux_artifacts:
223
+ if artifact.document_diff_id is None:
224
+ raise DocumentHarnessEvidenceError(
225
+ f"document viewer UX artifact does not carry a document_diff_id: "
226
+ f"{artifact.artifact_id}"
227
+ )
228
+ join_key = (artifact.document_diff_id, artifact.correlation_id)
229
+ if join_key not in valid_joins:
230
+ raise DocumentHarnessEvidenceError(
231
+ "document viewer UX artifact does not join a backend document diff "
232
+ f"record by document_diff_id and correlation_id: {artifact.artifact_id}"
233
+ )