create-windy 0.5.2 → 0.6.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 (570) hide show
  1. package/dist/cli.js +288 -154
  2. package/package.json +2 -1
  3. package/template/.windy-template.json +2 -2
  4. package/template/apps/agent-server/README.md +25 -6
  5. package/template/apps/agent-server/src/southwind_agent_server/adk_adapter.py +15 -2
  6. package/template/apps/agent-server/src/southwind_agent_server/app.py +13 -34
  7. package/template/apps/agent-server/src/southwind_agent_server/config.py +49 -0
  8. package/template/apps/agent-server/src/southwind_agent_server/contracts.py +13 -0
  9. package/template/apps/agent-server/src/southwind_agent_server/engine_capacity.py +31 -0
  10. package/template/apps/agent-server/src/southwind_agent_server/fingerprint.py +5 -0
  11. package/template/apps/agent-server/src/southwind_agent_server/health_routes.py +50 -0
  12. package/template/apps/agent-server/src/southwind_agent_server/openai_engine.py +11 -2
  13. package/template/apps/agent-server/src/southwind_agent_server/openai_provider.py +3 -9
  14. package/template/apps/agent-server/src/southwind_agent_server/postgres_store.py +5 -0
  15. package/template/apps/agent-server/src/southwind_agent_server/readiness_pin.py +37 -0
  16. package/template/apps/agent-server/src/southwind_agent_server/run_admission.py +64 -0
  17. package/template/apps/agent-server/src/southwind_agent_server/run_capacity.py +59 -0
  18. package/template/apps/agent-server/src/southwind_agent_server/service.py +42 -43
  19. package/template/apps/agent-server/src/southwind_agent_server/service_errors.py +4 -0
  20. package/template/apps/agent-server/src/southwind_agent_server/service_execution.py +31 -0
  21. package/template/apps/agent-server/src/southwind_agent_server/service_tasks.py +34 -0
  22. package/template/apps/agent-server/src/southwind_agent_server/sqlite_catalog.py +11 -0
  23. package/template/apps/agent-server/src/southwind_agent_server/store.py +6 -0
  24. package/template/apps/agent-server/src/southwind_agent_server/vision_probe.py +87 -0
  25. package/template/apps/agent-server/src/southwind_agent_server/vision_requirement.py +28 -0
  26. package/template/apps/agent-server/src/southwind_agent_server/vlm_readiness.py +247 -0
  27. package/template/apps/agent-server/tests/test_api.py +16 -3
  28. package/template/apps/agent-server/tests/test_openai_provider.py +21 -4
  29. package/template/apps/agent-server/tests/test_postgres_store.py +3 -0
  30. package/template/apps/agent-server/tests/test_run_capacity.py +110 -0
  31. package/template/apps/agent-server/tests/test_runtime_factory_readiness.py +37 -0
  32. package/template/apps/agent-server/tests/test_sqlite_store.py +3 -0
  33. package/template/apps/agent-server/tests/test_vision_readiness_enforcement.py +72 -0
  34. package/template/apps/agent-server/tests/test_vlm_readiness.py +106 -0
  35. package/template/apps/document-server/src/southwind_document_server/adapter.py +117 -205
  36. package/template/apps/document-server/src/southwind_document_server/adapter_errors.py +13 -0
  37. package/template/apps/document-server/src/southwind_document_server/app.py +62 -14
  38. package/template/apps/document-server/src/southwind_document_server/artifacts.py +27 -0
  39. package/template/apps/document-server/src/southwind_document_server/config.py +96 -2
  40. package/template/apps/document-server/src/southwind_document_server/contracts.py +168 -13
  41. package/template/apps/document-server/src/southwind_document_server/fingerprint.py +128 -0
  42. package/template/apps/document-server/src/southwind_document_server/grants.py +81 -0
  43. package/template/apps/document-server/src/southwind_document_server/multipart_output.py +265 -0
  44. package/template/apps/document-server/src/southwind_document_server/output_validation.py +202 -0
  45. package/template/apps/document-server/src/southwind_document_server/progress.py +27 -0
  46. package/template/apps/document-server/src/southwind_document_server/readiness.py +280 -0
  47. package/template/apps/document-server/src/southwind_document_server/readiness_contracts.py +280 -0
  48. package/template/apps/document-server/src/southwind_document_server/readiness_http.py +87 -0
  49. package/template/apps/document-server/src/southwind_document_server/readiness_support.py +120 -0
  50. package/template/apps/document-server/src/southwind_document_server/request_validation.py +48 -0
  51. package/template/apps/document-server/src/southwind_document_server/service.py +297 -96
  52. package/template/apps/document-server/src/southwind_document_server/service_recovery.py +183 -0
  53. package/template/apps/document-server/src/southwind_document_server/sink.py +316 -0
  54. package/template/apps/document-server/src/southwind_document_server/store.py +301 -141
  55. package/template/apps/document-server/src/southwind_document_server/store_events.py +40 -0
  56. package/template/apps/document-server/src/southwind_document_server/store_models.py +62 -0
  57. package/template/apps/document-server/src/southwind_document_server/store_recovery.py +247 -0
  58. package/template/apps/document-server/src/southwind_document_server/store_schema.py +50 -0
  59. package/template/apps/document-server/tests/recovery_support.py +230 -0
  60. package/template/apps/document-server/tests/support.py +210 -0
  61. package/template/apps/document-server/tests/test_adapter.py +251 -0
  62. package/template/apps/document-server/tests/test_config.py +43 -0
  63. package/template/apps/document-server/tests/test_contracts.py +80 -0
  64. package/template/apps/document-server/tests/test_fingerprint.py +125 -0
  65. package/template/apps/document-server/tests/test_grants.py +46 -0
  66. package/template/apps/document-server/tests/test_handshake.py +154 -0
  67. package/template/apps/document-server/tests/test_integration.py +192 -0
  68. package/template/apps/document-server/tests/test_multipart_security.py +259 -0
  69. package/template/apps/document-server/tests/test_readiness.py +311 -0
  70. package/template/apps/document-server/tests/test_readiness_contracts.py +131 -0
  71. package/template/apps/document-server/tests/test_recovery.py +222 -0
  72. package/template/apps/document-server/tests/test_recovery_faults.py +101 -0
  73. package/template/apps/document-server/tests/test_recovery_races.py +283 -0
  74. package/template/apps/document-server/tests/test_service.py +16 -13
  75. package/template/apps/document-server/tests/test_service_artifacts.py +296 -0
  76. package/template/apps/document-server/tests/test_sink.py +253 -0
  77. package/template/apps/document-server/tests/test_store.py +199 -0
  78. package/template/apps/embedding-server/pyproject.toml +5 -0
  79. package/template/apps/embedding-server/src/southwind_embedding_server/adapter.py +38 -2
  80. package/template/apps/embedding-server/src/southwind_embedding_server/app.py +111 -3
  81. package/template/apps/embedding-server/src/southwind_embedding_server/config.py +27 -0
  82. package/template/apps/embedding-server/src/southwind_embedding_server/image_input.py +16 -5
  83. package/template/apps/embedding-server/src/southwind_embedding_server/run_cipher.py +31 -0
  84. package/template/apps/embedding-server/src/southwind_embedding_server/run_service.py +130 -0
  85. package/template/apps/embedding-server/src/southwind_embedding_server/run_store.py +250 -0
  86. package/template/apps/embedding-server/tests/test_adapter.py +25 -0
  87. package/template/apps/embedding-server/tests/test_run_http.py +185 -0
  88. package/template/apps/embedding-server/tests/test_run_service.py +200 -0
  89. package/template/apps/embedding-server/uv.lock +71 -0
  90. package/template/apps/server/Dockerfile +13 -0
  91. package/template/apps/server/package.json +1 -0
  92. package/template/apps/server/src/agent/drizzle-screenshot-intake-repository.integration.test.ts +283 -0
  93. package/template/apps/server/src/agent/drizzle-screenshot-intake-repository.ts +175 -0
  94. package/template/apps/server/src/agent/persistent-screenshot-intake-producer.ts +320 -0
  95. package/template/apps/server/src/agent/remote-runtime.ts +8 -1
  96. package/template/apps/server/src/agent/required-environment.ts +5 -0
  97. package/template/apps/server/src/agent/run-attach.ts +41 -0
  98. package/template/apps/server/src/agent/run-audit.ts +49 -0
  99. package/template/apps/server/src/agent/run-contracts.ts +6 -1
  100. package/template/apps/server/src/agent/run-facade.ts +66 -68
  101. package/template/apps/server/src/agent/run-route-input.ts +26 -1
  102. package/template/apps/server/src/agent/run-routes.ts +1 -0
  103. package/template/apps/server/src/agent/runtime-bootstrap-report.test.ts +1 -1
  104. package/template/apps/server/src/agent/runtime-bootstrap.ts +110 -60
  105. package/template/apps/server/src/agent/runtime-readiness-sources.test.ts +27 -0
  106. package/template/apps/server/src/agent/runtime-readiness-sources.ts +31 -0
  107. package/template/apps/server/src/agent/runtime-reporting-bootstrap.ts +40 -0
  108. package/template/apps/server/src/agent/screenshot-intake-authorization.ts +29 -0
  109. package/template/apps/server/src/agent/screenshot-intake-bootstrap.ts +61 -0
  110. package/template/apps/server/src/agent/screenshot-intake-durable.ts +53 -0
  111. package/template/apps/server/src/agent/screenshot-intake-errors.ts +9 -0
  112. package/template/apps/server/src/agent/screenshot-intake-producer.ts +41 -0
  113. package/template/apps/server/src/agent/screenshot-intake-record.ts +44 -0
  114. package/template/apps/server/src/agent/screenshot-intake-recovery.ts +106 -0
  115. package/template/apps/server/src/agent/screenshot-intake-repository.ts +64 -0
  116. package/template/apps/server/src/agent/screenshot-intake-reservation.ts +24 -0
  117. package/template/apps/server/src/agent/screenshot-intake-routes.ts +171 -0
  118. package/template/apps/server/src/agent/screenshot-intake-runtime-types.ts +6 -0
  119. package/template/apps/server/src/agent/screenshot-intake-sweep.ts +26 -0
  120. package/template/apps/server/src/agent/screenshot-intake-test-support.ts +87 -0
  121. package/template/apps/server/src/agent/screenshot-intake-v2-validation.ts +152 -0
  122. package/template/apps/server/src/agent/screenshot-intake-v2.test.ts +338 -0
  123. package/template/apps/server/src/agent/screenshot-intake-v2.ts +350 -0
  124. package/template/apps/server/src/agent/screenshot-png.ts +15 -0
  125. package/template/apps/server/src/agent/screenshot-run-binding.ts +34 -0
  126. package/template/apps/server/src/agent/unavailable-routes.ts +9 -0
  127. package/template/apps/server/src/agent/vision-facade.test.ts +98 -8
  128. package/template/apps/server/src/agent/vision-input.ts +5 -2
  129. package/template/apps/server/src/agent/vision-readiness-pin.ts +74 -0
  130. package/template/apps/server/src/agent/vision-readiness.ts +58 -0
  131. package/template/apps/server/src/ai-artifact/runtime-reference.test.ts +135 -0
  132. package/template/apps/server/src/ai-artifact/runtime.ts +134 -5
  133. package/template/apps/server/src/ai-output-artifact/cleanup.ts +214 -0
  134. package/template/apps/server/src/ai-output-artifact/contracts.ts +152 -0
  135. package/template/apps/server/src/ai-output-artifact/drizzle-cleanup.ts +37 -0
  136. package/template/apps/server/src/ai-output-artifact/drizzle-complete.ts +71 -0
  137. package/template/apps/server/src/ai-output-artifact/drizzle-grant-cleanup.ts +45 -0
  138. package/template/apps/server/src/ai-output-artifact/drizzle-grants.ts +109 -0
  139. package/template/apps/server/src/ai-output-artifact/drizzle-mapping.ts +77 -0
  140. package/template/apps/server/src/ai-output-artifact/drizzle-readiness.ts +46 -0
  141. package/template/apps/server/src/ai-output-artifact/drizzle-repository.ts +350 -0
  142. package/template/apps/server/src/ai-output-artifact/drizzle-seal.ts +64 -0
  143. package/template/apps/server/src/ai-output-artifact/grant.ts +30 -0
  144. package/template/apps/server/src/ai-output-artifact/host-registry.ts +53 -0
  145. package/template/apps/server/src/ai-output-artifact/memory-cleanup.ts +47 -0
  146. package/template/apps/server/src/ai-output-artifact/memory-grants.ts +98 -0
  147. package/template/apps/server/src/ai-output-artifact/memory-readiness.ts +26 -0
  148. package/template/apps/server/src/ai-output-artifact/memory-repository.ts +348 -0
  149. package/template/apps/server/src/ai-output-artifact/policy.test.ts +67 -0
  150. package/template/apps/server/src/ai-output-artifact/policy.ts +125 -0
  151. package/template/apps/server/src/ai-output-artifact/postgres-test-support.ts +147 -0
  152. package/template/apps/server/src/ai-output-artifact/postgres.integration.test.ts +349 -0
  153. package/template/apps/server/src/ai-output-artifact/reference-codec.ts +128 -0
  154. package/template/apps/server/src/ai-output-artifact/repository-grant-invariants.test-support.ts +165 -0
  155. package/template/apps/server/src/ai-output-artifact/repository-invariants.test-support.ts +239 -0
  156. package/template/apps/server/src/ai-output-artifact/repository-invariants.test.ts +18 -0
  157. package/template/apps/server/src/ai-output-artifact/repository.ts +107 -0
  158. package/template/apps/server/src/ai-output-artifact/route-input.ts +173 -0
  159. package/template/apps/server/src/ai-output-artifact/routes-delete.test.ts +287 -0
  160. package/template/apps/server/src/ai-output-artifact/routes-grant.test.ts +116 -0
  161. package/template/apps/server/src/ai-output-artifact/routes-nonblocking-body.test.ts +136 -0
  162. package/template/apps/server/src/ai-output-artifact/routes-security.test.ts +176 -0
  163. package/template/apps/server/src/ai-output-artifact/routes-storage-error.test.ts +105 -0
  164. package/template/apps/server/src/ai-output-artifact/routes.test-support.ts +84 -0
  165. package/template/apps/server/src/ai-output-artifact/routes.test.ts +198 -0
  166. package/template/apps/server/src/ai-output-artifact/routes.ts +280 -0
  167. package/template/apps/server/src/ai-output-artifact/service-completion.ts +60 -0
  168. package/template/apps/server/src/ai-output-artifact/service-grants.test.ts +169 -0
  169. package/template/apps/server/src/ai-output-artifact/service-grants.ts +217 -0
  170. package/template/apps/server/src/ai-output-artifact/service-input.ts +175 -0
  171. package/template/apps/server/src/ai-output-artifact/service-read.ts +89 -0
  172. package/template/apps/server/src/ai-output-artifact/service-recovery.test.ts +238 -0
  173. package/template/apps/server/src/ai-output-artifact/service-support.ts +240 -0
  174. package/template/apps/server/src/ai-output-artifact/service.test.ts +283 -0
  175. package/template/apps/server/src/ai-output-artifact/service.ts +334 -0
  176. package/template/apps/server/src/ai-output-artifact/storage-recovery.ts +33 -0
  177. package/template/apps/server/src/ai-output-artifact/storage-writer.ts +103 -0
  178. package/template/apps/server/src/ai-output-artifact/test-support.ts +161 -0
  179. package/template/apps/server/src/ai-runtime-readiness/health-response.ts +92 -0
  180. package/template/apps/server/src/ai-runtime-readiness/operation-port-trust.test.ts +66 -0
  181. package/template/apps/server/src/ai-runtime-readiness/operation-port.test-support.ts +143 -0
  182. package/template/apps/server/src/ai-runtime-readiness/operation-port.test.ts +193 -0
  183. package/template/apps/server/src/ai-runtime-readiness/operation-port.ts +172 -0
  184. package/template/apps/server/src/ai-runtime-readiness/trust-store.ts +61 -0
  185. package/template/apps/server/src/app/ai-screenshot-intake-binding.ts +22 -0
  186. package/template/apps/server/src/app/document-output-artifact-bindings.ts +5 -0
  187. package/template/apps/server/src/app/speech-output-artifact-bindings.ts +5 -0
  188. package/template/apps/server/src/application-services.ts +9 -3
  189. package/template/apps/server/src/audit/redaction.ts +1 -0
  190. package/template/apps/server/src/audit/reliable-writer.test.ts +8 -0
  191. package/template/apps/server/src/auth/password-change-license-restriction.test.ts +156 -0
  192. package/template/apps/server/src/document/cancel-response.ts +33 -0
  193. package/template/apps/server/src/document/contracts.ts +6 -0
  194. package/template/apps/server/src/document/errors.ts +11 -0
  195. package/template/apps/server/src/document/facade-cancel.test.ts +226 -0
  196. package/template/apps/server/src/document/facade-cancel.ts +110 -0
  197. package/template/apps/server/src/document/facade-grant-handoff.test.ts +113 -0
  198. package/template/apps/server/src/document/facade-idempotency.test.ts +195 -0
  199. package/template/apps/server/src/document/facade-invocation.ts +46 -0
  200. package/template/apps/server/src/document/facade-output-artifact.test.ts +310 -0
  201. package/template/apps/server/src/document/facade-read-response.ts +116 -0
  202. package/template/apps/server/src/document/facade-readiness.test.ts +95 -0
  203. package/template/apps/server/src/document/facade-support.ts +297 -0
  204. package/template/apps/server/src/document/facade.ts +164 -173
  205. package/template/apps/server/src/document/output-artifact-composition.test.ts +64 -0
  206. package/template/apps/server/src/document/output-artifact-composition.ts +78 -0
  207. package/template/apps/server/src/document/output-artifact-fingerprint.contract.test.ts +110 -0
  208. package/template/apps/server/src/document/output-artifact-fingerprint.ts +150 -0
  209. package/template/apps/server/src/document/output-artifact-host-registry.ts +44 -0
  210. package/template/apps/server/src/document/output-artifact-host.test.ts +332 -0
  211. package/template/apps/server/src/document/output-artifact-host.ts +331 -0
  212. package/template/apps/server/src/document/output-artifact-manifest.test-support.ts +71 -0
  213. package/template/apps/server/src/document/output-artifact-publish.test-support.ts +48 -0
  214. package/template/apps/server/src/document/output-artifact-readiness-probe.ts +347 -0
  215. package/template/apps/server/src/document/output-artifact-readiness-timeout.ts +30 -0
  216. package/template/apps/server/src/document/output-artifact-readiness.test.ts +264 -0
  217. package/template/apps/server/src/document/output-artifact-readiness.ts +87 -0
  218. package/template/apps/server/src/document/output-artifact-route-composition.test.ts +27 -0
  219. package/template/apps/server/src/document/output-artifact-route-composition.ts +14 -0
  220. package/template/apps/server/src/document/output-artifact-runtime.test-support.ts +8 -0
  221. package/template/apps/server/src/document/output-artifact-runtime.test.ts +124 -0
  222. package/template/apps/server/src/document/output-artifact-runtime.ts +275 -0
  223. package/template/apps/server/src/document/output-artifact.test-support.ts +350 -0
  224. package/template/apps/server/src/document/remote-response.ts +162 -0
  225. package/template/apps/server/src/document/remote-runtime.test.ts +100 -4
  226. package/template/apps/server/src/document/remote-runtime.ts +37 -85
  227. package/template/apps/server/src/document/routes-read-response.test.ts +267 -0
  228. package/template/apps/server/src/document/routes.test.ts +109 -0
  229. package/template/apps/server/src/document/routes.ts +23 -14
  230. package/template/apps/server/src/embedding/audit.ts +46 -0
  231. package/template/apps/server/src/embedding/contracts.ts +13 -0
  232. package/template/apps/server/src/embedding/drizzle-run-binding-repository.integration.test.ts +100 -0
  233. package/template/apps/server/src/embedding/drizzle-run-binding-repository.ts +102 -0
  234. package/template/apps/server/src/embedding/facade-types.ts +18 -0
  235. package/template/apps/server/src/embedding/facade.ts +242 -111
  236. package/template/apps/server/src/embedding/operation-authorization.ts +23 -0
  237. package/template/apps/server/src/embedding/remote-runtime.test.ts +18 -0
  238. package/template/apps/server/src/embedding/remote-runtime.ts +77 -0
  239. package/template/apps/server/src/embedding/routes.test.ts +118 -0
  240. package/template/apps/server/src/embedding/routes.ts +98 -0
  241. package/template/apps/server/src/embedding/run-artifact.ts +18 -0
  242. package/template/apps/server/src/embedding/run-authorization.test.ts +133 -0
  243. package/template/apps/server/src/embedding/run-authorization.ts +91 -0
  244. package/template/apps/server/src/embedding/run-binding-repository.ts +75 -0
  245. package/template/apps/server/src/embedding/run-fingerprint.test.ts +52 -0
  246. package/template/apps/server/src/embedding/run-fingerprint.ts +39 -0
  247. package/template/apps/server/src/embedding/terminal-observer.test.ts +26 -0
  248. package/template/apps/server/src/embedding/terminal-observer.ts +44 -0
  249. package/template/apps/server/src/index.ts +38 -31
  250. package/template/apps/server/src/module-host/ai-operation-port.ts +3 -3
  251. package/template/apps/server/src/module-host/durable-context.ts +194 -16
  252. package/template/apps/server/src/module-host/durable-handler-registration.ts +1 -0
  253. package/template/apps/server/src/module-host/durable-storage-filesystem-restart.test.ts +265 -0
  254. package/template/apps/server/src/module-host/durable-storage-write.test.ts +345 -0
  255. package/template/apps/server/src/module-host/http-runtime.ts +25 -0
  256. package/template/apps/server/src/module-host/initialize-contracts.ts +18 -1
  257. package/template/apps/server/src/module-host/initialize.test.ts +18 -0
  258. package/template/apps/server/src/module-host/initialize.ts +42 -2
  259. package/template/apps/server/src/module-host/module-secret-audit-version.test.ts +73 -0
  260. package/template/apps/server/src/module-host/module-secret-binding-resolution.ts +60 -0
  261. package/template/apps/server/src/module-host/module-secret-durable.test.ts +206 -0
  262. package/template/apps/server/src/module-host/module-secret-port.test-support.ts +125 -0
  263. package/template/apps/server/src/module-host/module-secret-port.test.ts +161 -0
  264. package/template/apps/server/src/module-host/module-secret-port.ts +249 -0
  265. package/template/apps/server/src/module-host/module-secret-result.test.ts +324 -0
  266. package/template/apps/server/src/module-host/module-secret-result.ts +274 -0
  267. package/template/apps/server/src/module-host/module-secret-tool-boundary.test.ts +143 -0
  268. package/template/apps/server/src/module-host/project-composition.ts +1 -0
  269. package/template/apps/server/src/module-host/report-staging-port.ts +55 -0
  270. package/template/apps/server/src/module-host/report-staging-registration.test.ts +104 -0
  271. package/template/apps/server/src/module-host/request-context.ts +58 -1
  272. package/template/apps/server/src/module-host/route-declaration.ts +11 -4
  273. package/template/apps/server/src/module-host/route-installer.test-fixture.ts +246 -0
  274. package/template/apps/server/src/module-host/route-installer.test.ts +47 -211
  275. package/template/apps/server/src/module-host/route-installer.ts +192 -21
  276. package/template/apps/server/src/module-host/route-registration.test.ts +44 -4
  277. package/template/apps/server/src/module-host/runtime-composition.ts +2 -0
  278. package/template/apps/server/src/module-host/scoped-host.ts +84 -0
  279. package/template/apps/server/src/module-host/screenshot-artifact-ref.ts +91 -0
  280. package/template/apps/server/src/module-host/screenshot-intake-composition.test.ts +292 -0
  281. package/template/apps/server/src/module-host/screenshot-intake-deadline.ts +38 -0
  282. package/template/apps/server/src/module-host/screenshot-intake-plan.ts +75 -0
  283. package/template/apps/server/src/module-host/screenshot-intake-port.ts +297 -0
  284. package/template/apps/server/src/module-host/screenshot-intake-security.test.ts +311 -0
  285. package/template/apps/server/src/module-host/screenshot-intake-store.ts +76 -0
  286. package/template/apps/server/src/module-host/screenshot-intake-test-support.ts +68 -0
  287. package/template/apps/server/src/module-host/secret-bindings.test.ts +167 -0
  288. package/template/apps/server/src/module-host/secret-bindings.ts +184 -0
  289. package/template/apps/server/src/module-host/storage-authorization-binding.test.ts +242 -0
  290. package/template/apps/server/src/module-host/storage-port.test.ts +8 -1
  291. package/template/apps/server/src/module-host/storage-port.ts +84 -8
  292. package/template/apps/server/src/module-host/storage-restart-fixture.test-support.ts +242 -0
  293. package/template/apps/server/src/module-host/storage-restart-postgres.integration.test.ts +280 -0
  294. package/template/apps/server/src/module-host/storage-scope-drift-http.test.ts +68 -0
  295. package/template/apps/server/src/module-host/storage-scope.ts +52 -1
  296. package/template/apps/server/src/module-host/storage-stream-route.test.ts +282 -0
  297. package/template/apps/server/src/module-host/storage-write-error.test.ts +174 -0
  298. package/template/apps/server/src/module-host/storage-write-error.ts +62 -0
  299. package/template/apps/server/src/module-host/storage-write-port.test.ts +323 -0
  300. package/template/apps/server/src/module-host/storage-write-port.ts +320 -0
  301. package/template/apps/server/src/module-host/storage-write-unavailable.ts +21 -0
  302. package/template/apps/server/src/module-host/storage-writer-retention.test.ts +109 -0
  303. package/template/apps/server/src/module-host/user-directory-composition.test.ts +1 -0
  304. package/template/apps/server/src/module-preflight-secret.test.ts +79 -0
  305. package/template/apps/server/src/module-preflight.ts +5 -0
  306. package/template/apps/server/src/platform-http-runtime.ts +16 -4
  307. package/template/apps/server/src/report-staging/archive-frame-stream.test.ts +209 -0
  308. package/template/apps/server/src/report-staging/archive-frame-stream.ts +341 -0
  309. package/template/apps/server/src/report-staging/archive-process.test.ts +302 -0
  310. package/template/apps/server/src/report-staging/archive-process.ts +257 -0
  311. package/template/apps/server/src/report-staging/archive-volumes.ts +30 -0
  312. package/template/apps/server/src/report-staging/cancellation.ts +13 -0
  313. package/template/apps/server/src/report-staging/contracts.ts +94 -0
  314. package/template/apps/server/src/report-staging/drizzle-lifecycle.ts +278 -0
  315. package/template/apps/server/src/report-staging/drizzle-mapping.ts +140 -0
  316. package/template/apps/server/src/report-staging/drizzle-repository.integration.test.ts +346 -0
  317. package/template/apps/server/src/report-staging/drizzle-repository.ts +255 -0
  318. package/template/apps/server/src/report-staging/drizzle-seal.integration.test.ts +267 -0
  319. package/template/apps/server/src/report-staging/drizzle-seal.ts +177 -0
  320. package/template/apps/server/src/report-staging/filesystem-cleanup.test.ts +68 -0
  321. package/template/apps/server/src/report-staging/filesystem-cleanup.ts +102 -0
  322. package/template/apps/server/src/report-staging/filesystem-errors.ts +15 -0
  323. package/template/apps/server/src/report-staging/filesystem-identifiers.ts +19 -0
  324. package/template/apps/server/src/report-staging/filesystem-io.test.ts +85 -0
  325. package/template/apps/server/src/report-staging/filesystem-io.ts +206 -0
  326. package/template/apps/server/src/report-staging/filesystem-scan.ts +85 -0
  327. package/template/apps/server/src/report-staging/filesystem-store.ts +346 -0
  328. package/template/apps/server/src/report-staging/heartbeat.test.ts +47 -0
  329. package/template/apps/server/src/report-staging/heartbeat.ts +53 -0
  330. package/template/apps/server/src/report-staging/manifest-stream.ts +46 -0
  331. package/template/apps/server/src/report-staging/memory-repository.ts +256 -0
  332. package/template/apps/server/src/report-staging/metadata-catalog.ts +89 -0
  333. package/template/apps/server/src/report-staging/metadata-spool-paths.ts +195 -0
  334. package/template/apps/server/src/report-staging/metadata-spool-schema.ts +54 -0
  335. package/template/apps/server/src/report-staging/metadata-spool.test.ts +214 -0
  336. package/template/apps/server/src/report-staging/metadata-spool.ts +305 -0
  337. package/template/apps/server/src/report-staging/native/archive-frame-helper.c +309 -0
  338. package/template/apps/server/src/report-staging/path-policy.test.ts +127 -0
  339. package/template/apps/server/src/report-staging/path-policy.ts +263 -0
  340. package/template/apps/server/src/report-staging/repository-fence.test.ts +114 -0
  341. package/template/apps/server/src/report-staging/repository.ts +75 -0
  342. package/template/apps/server/src/report-staging/runtime.ts +31 -0
  343. package/template/apps/server/src/report-staging/sealed-file.test.ts +34 -0
  344. package/template/apps/server/src/report-staging/sealed-file.ts +137 -0
  345. package/template/apps/server/src/report-staging/service-input-limits.test.ts +62 -0
  346. package/template/apps/server/src/report-staging/service-input.ts +204 -0
  347. package/template/apps/server/src/report-staging/service-lifecycle.test.ts +132 -0
  348. package/template/apps/server/src/report-staging/service-read-fence.test.ts +37 -0
  349. package/template/apps/server/src/report-staging/service-read.ts +172 -0
  350. package/template/apps/server/src/report-staging/service-support.ts +149 -0
  351. package/template/apps/server/src/report-staging/service.test-fixture.ts +226 -0
  352. package/template/apps/server/src/report-staging/service.test.ts +314 -0
  353. package/template/apps/server/src/report-staging/service.ts +255 -0
  354. package/template/apps/server/src/report-staging/supervised-process.ts +194 -0
  355. package/template/apps/server/src/speech/contracts.ts +8 -0
  356. package/template/apps/server/src/speech/errors.ts +10 -0
  357. package/template/apps/server/src/speech/facade-contract.ts +49 -0
  358. package/template/apps/server/src/speech/facade-output.test.ts +299 -0
  359. package/template/apps/server/src/speech/facade-output.ts +298 -0
  360. package/template/apps/server/src/speech/facade-validation.ts +127 -0
  361. package/template/apps/server/src/speech/facade.ts +185 -151
  362. package/template/apps/server/src/speech/fingerprint.test.ts +42 -0
  363. package/template/apps/server/src/speech/fingerprint.ts +28 -0
  364. package/template/apps/server/src/speech/output-artifact-binding.test.ts +11 -0
  365. package/template/apps/server/src/speech/output-artifact-binding.ts +30 -0
  366. package/template/apps/server/src/speech/output-artifact-error.ts +9 -0
  367. package/template/apps/server/src/speech/output-artifact-host.test-support.ts +73 -0
  368. package/template/apps/server/src/speech/output-artifact-host.test.ts +302 -0
  369. package/template/apps/server/src/speech/output-artifact-host.ts +279 -0
  370. package/template/apps/server/src/speech/output-artifact-policy.ts +114 -0
  371. package/template/apps/server/src/speech/output-artifact-replay.ts +91 -0
  372. package/template/apps/server/src/speech/remote-response.ts +158 -0
  373. package/template/apps/server/src/speech/remote-runtime.test.ts +90 -0
  374. package/template/apps/server/src/speech/remote-runtime.ts +36 -78
  375. package/template/apps/server/src/speech/routes.ts +60 -16
  376. package/template/apps/server/src/startup-finalization.ts +52 -0
  377. package/template/apps/server/src/startup-preflight.ts +2 -0
  378. package/template/apps/server/src/startup-shutdown.test.ts +69 -0
  379. package/template/apps/server/src/startup-shutdown.ts +61 -0
  380. package/template/apps/server/src/storage/drizzle-upload-purge.ts +61 -0
  381. package/template/apps/server/src/storage/drizzle-upload-references.ts +23 -0
  382. package/template/apps/server/src/storage/drizzle-upload-repository.integration.test.ts +103 -0
  383. package/template/apps/server/src/storage/drizzle-upload-repository.ts +109 -14
  384. package/template/apps/server/src/storage/host-runtime.ts +15 -0
  385. package/template/apps/server/src/storage/routes-stream-cancellation.test.ts +154 -0
  386. package/template/apps/server/src/storage/routes.test.ts +13 -2
  387. package/template/apps/server/src/storage/routes.ts +57 -18
  388. package/template/apps/server/src/storage/runtime.ts +17 -4
  389. package/template/apps/server/src/system/route-types.ts +5 -1
  390. package/template/apps/server/src/system/system-resource-monitoring.test.ts +47 -0
  391. package/template/apps/server/src/system/system-resource-monitoring.ts +60 -10
  392. package/template/apps/server/src/work-order/routes.test.ts +1 -0
  393. package/template/apps/speech-server/src/southwind_speech_server/adapter.py +58 -17
  394. package/template/apps/speech-server/src/southwind_speech_server/app.py +24 -17
  395. package/template/apps/speech-server/src/southwind_speech_server/bounded_json.py +60 -0
  396. package/template/apps/speech-server/src/southwind_speech_server/config.py +122 -2
  397. package/template/apps/speech-server/src/southwind_speech_server/contracts.py +58 -0
  398. package/template/apps/speech-server/src/southwind_speech_server/errors.py +8 -0
  399. package/template/apps/speech-server/src/southwind_speech_server/normalizer.py +14 -0
  400. package/template/apps/speech-server/src/southwind_speech_server/output_artifact.py +190 -0
  401. package/template/apps/speech-server/src/southwind_speech_server/output_validation.py +54 -0
  402. package/template/apps/speech-server/src/southwind_speech_server/pin_cli.py +83 -0
  403. package/template/apps/speech-server/src/southwind_speech_server/readiness.py +266 -0
  404. package/template/apps/speech-server/src/southwind_speech_server/readiness_contracts.py +268 -0
  405. package/template/apps/speech-server/src/southwind_speech_server/readiness_http.py +91 -0
  406. package/template/apps/speech-server/src/southwind_speech_server/readiness_local.py +161 -0
  407. package/template/apps/speech-server/src/southwind_speech_server/readiness_support.py +106 -0
  408. package/template/apps/speech-server/src/southwind_speech_server/service.py +118 -13
  409. package/template/apps/speech-server/src/southwind_speech_server/store.py +7 -0
  410. package/template/apps/speech-server/tests/test_bounded_json.py +55 -0
  411. package/template/apps/speech-server/tests/test_config.py +22 -0
  412. package/template/apps/speech-server/tests/test_output_artifact.py +60 -0
  413. package/template/apps/speech-server/tests/test_output_validation.py +44 -0
  414. package/template/apps/speech-server/tests/test_readiness.py +315 -0
  415. package/template/apps/speech-server/tests/test_readiness_http.py +48 -0
  416. package/template/apps/speech-server/tests/test_readiness_local.py +43 -0
  417. package/template/apps/speech-server/tests/test_service.py +211 -36
  418. package/template/apps/web/src/pages/system/components/OperationGpuMonitor.vue +2 -1
  419. package/template/apps/web/src/pages/system/components/OperationGpuMonitor.webtest.ts +29 -0
  420. package/template/apps/web/src/pages/system/components/OperationServiceMonitor.vue +2 -1
  421. package/template/apps/web/src/pages/system/components/OperationServiceMonitor.webtest.ts +4 -1
  422. package/template/docker-compose.yml +38 -1
  423. package/template/docs/architecture/ai-runtime-readiness.md +498 -0
  424. package/template/docs/architecture/ai-runtime.md +20 -4
  425. package/template/docs/architecture/durable-jobs.md +54 -5
  426. package/template/docs/architecture/module-host.md +72 -9
  427. package/template/docs/architecture/module-manifest-composition.md +5 -2
  428. package/template/docs/architecture/module-secret-resolution.md +250 -0
  429. package/template/docs/architecture/object-storage.md +144 -3
  430. package/template/docs/architecture/report-staging.md +158 -0
  431. package/template/docs/architecture/server-module-interface.md +29 -0
  432. package/template/docs/architecture/speech-variants.md +45 -0
  433. package/template/docs/platform/agent-tools.md +16 -0
  434. package/template/docs/platform/document-ai-runtime.md +199 -17
  435. package/template/docs/platform/module-configuration.md +5 -0
  436. package/template/docs/platform/speech-ai-runtime.md +34 -5
  437. package/template/docs/platform/vision-ai-runtime.md +24 -0
  438. package/template/package.json +4 -1
  439. package/template/packages/ai-client/package.json +1 -1
  440. package/template/packages/ai-client/src/agent/client/client.ts +3 -0
  441. package/template/packages/ai-client/src/agent/client/index.ts +1 -0
  442. package/template/packages/ai-client/src/agent/client/screenshot.test.ts +40 -0
  443. package/template/packages/ai-client/src/agent/client/screenshot.ts +146 -0
  444. package/template/packages/ai-client/src/agent/client/types.ts +2 -0
  445. package/template/packages/ai-client/src/agent/contracts/runs.ts +1 -0
  446. package/template/packages/ai-client/src/embedding/client.test.ts +52 -0
  447. package/template/packages/ai-client/src/embedding/client.ts +69 -0
  448. package/template/packages/ai-client/src/embedding/contracts.ts +47 -0
  449. package/template/packages/ai-client/src/embedding/index.ts +1 -0
  450. package/template/packages/ai-client/src/embedding/run.ts +130 -0
  451. package/template/packages/ai-client/src/speech/client.test.ts +26 -0
  452. package/template/packages/ai-client/src/speech/client.ts +25 -1
  453. package/template/packages/ai-client/src/speech/contracts.ts +19 -0
  454. package/template/packages/config/package.json +1 -1
  455. package/template/packages/database/drizzle/0048_illegal_magneto.sql +11 -0
  456. package/template/packages/database/drizzle/0049_right_lenny_balinger.sql +79 -0
  457. package/template/packages/database/drizzle/0050_greedy_sister_grimm.sql +92 -0
  458. package/template/packages/database/drizzle/0051_lame_shockwave.sql +19 -0
  459. package/template/packages/database/drizzle/0052_tiresome_komodo.sql +1 -0
  460. package/template/packages/database/drizzle/0053_calm_victor_mancha.sql +1 -0
  461. package/template/packages/database/drizzle/0054_tough_thanos.sql +29 -0
  462. package/template/packages/database/drizzle/meta/0048_snapshot.json +8852 -0
  463. package/template/packages/database/drizzle/meta/0049_snapshot.json +9410 -0
  464. package/template/packages/database/drizzle/meta/0050_snapshot.json +10115 -0
  465. package/template/packages/database/drizzle/meta/0051_snapshot.json +10257 -0
  466. package/template/packages/database/drizzle/meta/0052_snapshot.json +10263 -0
  467. package/template/packages/database/drizzle/meta/0053_snapshot.json +10270 -0
  468. package/template/packages/database/drizzle/meta/0054_snapshot.json +10468 -0
  469. package/template/packages/database/drizzle/meta/_journal.json +49 -0
  470. package/template/packages/database/package.json +1 -1
  471. package/template/packages/database/src/agent-runtime-schema.test.ts +15 -0
  472. package/template/packages/database/src/ai-output-artifacts.test.ts +57 -0
  473. package/template/packages/database/src/schema/agent-runtime.ts +43 -0
  474. package/template/packages/database/src/schema/ai-output-artifacts.ts +182 -0
  475. package/template/packages/database/src/schema/embedding-runtime.ts +62 -0
  476. package/template/packages/database/src/schema/file-storage.ts +18 -0
  477. package/template/packages/database/src/schema/index.ts +3 -0
  478. package/template/packages/database/src/schema/report-staging.ts +212 -0
  479. package/template/packages/database/src/schema.test.ts +19 -0
  480. package/template/packages/jobs/package.json +1 -1
  481. package/template/packages/modules/index.ts +1 -0
  482. package/template/packages/modules/package.json +1 -1
  483. package/template/packages/modules/src/ai-operation-composition.test.ts +37 -0
  484. package/template/packages/modules/src/ai-operation-composition.ts +2 -0
  485. package/template/packages/modules/src/ai-operation-readiness-contract.test.ts +38 -0
  486. package/template/packages/modules/src/ai-operation-readiness-contract.ts +34 -0
  487. package/template/packages/modules/src/capability-audit-validation.ts +20 -0
  488. package/template/packages/modules/src/capability-guard-validation.ts +41 -0
  489. package/template/packages/modules/src/composition.ts +11 -0
  490. package/template/packages/modules/src/manifest.ts +40 -0
  491. package/template/packages/modules/src/secret-composition.test.ts +308 -0
  492. package/template/packages/modules/src/secret-composition.ts +176 -0
  493. package/template/packages/modules/src/system-api-control-plane.ts +17 -1
  494. package/template/packages/modules/src/system-module-catalog.test.ts +52 -0
  495. package/template/packages/modules/src/system-module-catalog.ts +1 -1
  496. package/template/packages/server-sdk/contracts/ai-runtime-readiness/v1/document-python-parity.json +12 -0
  497. package/template/packages/server-sdk/contracts/ai-runtime-readiness/v1/document.json +70 -0
  498. package/template/packages/server-sdk/contracts/ai-runtime-readiness/v1/embedding.json +68 -0
  499. package/template/packages/server-sdk/contracts/ai-runtime-readiness/v1/speech.json +80 -0
  500. package/template/packages/server-sdk/contracts/ai-runtime-readiness/v1/vlm.json +70 -0
  501. package/template/packages/server-sdk/contracts/document-runtime/v1/fingerprint-fixture.json +101 -0
  502. package/template/packages/server-sdk/index.ts +109 -0
  503. package/template/packages/server-sdk/package.json +22 -3
  504. package/template/packages/server-sdk/src/ai-runtime-readiness-capture.ts +168 -0
  505. package/template/packages/server-sdk/src/ai-runtime-readiness-digest.ts +49 -0
  506. package/template/packages/server-sdk/src/ai-runtime-readiness-identity.ts +16 -0
  507. package/template/packages/server-sdk/src/ai-runtime-readiness-keys.ts +23 -0
  508. package/template/packages/server-sdk/src/ai-runtime-readiness-limits.ts +141 -0
  509. package/template/packages/server-sdk/src/ai-runtime-readiness-projection.ts +326 -0
  510. package/template/packages/server-sdk/src/ai-runtime-readiness-requirement.ts +31 -0
  511. package/template/packages/server-sdk/src/ai-runtime-readiness-time.ts +16 -0
  512. package/template/packages/server-sdk/src/ai-runtime-readiness-trust.ts +84 -0
  513. package/template/packages/server-sdk/src/ai-runtime-readiness-validation-values.ts +147 -0
  514. package/template/packages/server-sdk/src/ai-runtime-readiness-validation.ts +299 -0
  515. package/template/packages/server-sdk/src/ai-runtime-readiness-values.ts +42 -0
  516. package/template/packages/server-sdk/src/ai-runtime-readiness.adversarial-input.contract.test.ts +146 -0
  517. package/template/packages/server-sdk/src/ai-runtime-readiness.contract-support.ts +139 -0
  518. package/template/packages/server-sdk/src/ai-runtime-readiness.contract.test.ts +314 -0
  519. package/template/packages/server-sdk/src/ai-runtime-readiness.digest-safety.contract.test.ts +131 -0
  520. package/template/packages/server-sdk/src/ai-runtime-readiness.fail-closed.contract.test.ts +215 -0
  521. package/template/packages/server-sdk/src/ai-runtime-readiness.identity.contract.test.ts +138 -0
  522. package/template/packages/server-sdk/src/ai-runtime-readiness.input-safety.contract.test.ts +314 -0
  523. package/template/packages/server-sdk/src/ai-runtime-readiness.public-api.test.ts +18 -0
  524. package/template/packages/server-sdk/src/ai-runtime-readiness.python-parity.contract.test.ts +160 -0
  525. package/template/packages/server-sdk/src/ai-runtime-readiness.trust.contract.test.ts +135 -0
  526. package/template/packages/server-sdk/src/ai-runtime-readiness.ts +198 -0
  527. package/template/packages/server-sdk/src/ai-screenshot-intake-port.ts +58 -0
  528. package/template/packages/server-sdk/src/data-governance-registration.ts +1 -3
  529. package/template/packages/server-sdk/src/durable-handler.ts +12 -0
  530. package/template/packages/server-sdk/src/module-adapter.test.ts +10 -0
  531. package/template/packages/server-sdk/src/module-adapter.ts +3 -0
  532. package/template/packages/server-sdk/src/module-host.ts +8 -0
  533. package/template/packages/server-sdk/src/report-staging-context-compatibility.test.ts +25 -0
  534. package/template/packages/server-sdk/src/report-staging-port.ts +190 -0
  535. package/template/packages/server-sdk/src/request-context.ts +27 -1
  536. package/template/packages/server-sdk/src/route-definition.ts +6 -0
  537. package/template/packages/server-sdk/src/secret-binding.test.ts +66 -0
  538. package/template/packages/server-sdk/src/secret-binding.ts +54 -0
  539. package/template/packages/server-sdk/src/secret-context-compatibility.test.ts +77 -0
  540. package/template/packages/server-sdk/src/secret-port.ts +80 -0
  541. package/template/packages/server-sdk/src/storage-port.ts +129 -9
  542. package/template/packages/server-sdk/src/storage-v052-source-compatibility.test.ts +61 -0
  543. package/template/packages/shared/index.ts +2 -0
  544. package/template/packages/shared/package.json +4 -1
  545. package/template/packages/shared/src/ai-operation-readiness.test.ts +75 -0
  546. package/template/packages/shared/src/ai-operation-readiness.ts +170 -0
  547. package/template/packages/shared/src/license-catalog.ts +14 -9
  548. package/template/packages/shared/src/stable-key.ts +26 -0
  549. package/template/packages/shared/tsconfig.json +16 -0
  550. package/template/packages/storage/index.ts +2 -0
  551. package/template/packages/storage/package.json +1 -1
  552. package/template/packages/storage/src/in-memory-upload-repository.ts +105 -2
  553. package/template/packages/storage/src/local-file-blob-store.test.ts +58 -0
  554. package/template/packages/storage/src/local-file-blob-store.ts +5 -71
  555. package/template/packages/storage/src/local-file-blob-writer.ts +96 -0
  556. package/template/packages/storage/src/upload-abort-recovery.test.ts +234 -0
  557. package/template/packages/storage/src/upload-abort.ts +130 -0
  558. package/template/packages/storage/src/upload-cleanup-race.test.ts +207 -0
  559. package/template/packages/storage/src/upload-cleanup.ts +85 -0
  560. package/template/packages/storage/src/upload-completion.ts +52 -0
  561. package/template/packages/storage/src/upload-purge.test.ts +163 -0
  562. package/template/packages/storage/src/upload-purge.ts +261 -0
  563. package/template/packages/storage/src/upload-repository-v052-compatibility.test.ts +31 -0
  564. package/template/packages/storage/src/upload-repository.ts +61 -0
  565. package/template/packages/storage/src/upload-service-recovery.test.ts +296 -0
  566. package/template/packages/storage/src/upload-service.ts +138 -150
  567. package/template/packages/storage/src/upload-streams.ts +126 -30
  568. package/template/packages/storage/src/upload-types.ts +13 -0
  569. package/template/packages/storage/src/upload-validation.ts +127 -0
  570. package/template/scripts/provision-speech-readiness.ts +147 -0
@@ -0,0 +1,498 @@
1
+ # AI Runtime Readiness V1
2
+
3
+ 更新时间:2026-08-01。
4
+
5
+ 状态:公共 V1 合约与共享 fixture 的设计范围已经冻结;Document Runtime 已实现真实
6
+ Adapter probe、producer snapshot 和 Output Artifact Sink lifecycle probe,且既有
7
+ 无输出 Document facade 可加法消费 V1 offers。Host 以 Manifest 的 immutable expected
8
+ deployment pin 和真实 `/health/ready` snapshot 投影新版 Operation;未配置、超时、漂移
9
+ 或授权失败均 fail closed。Speech、Embedding 和 Agent/VLM 的真实 downstream probe
10
+ 仍由各自任务完成。本页定义 Host 应如何解释 readiness,不构成
11
+ 任何具体客户 Deployment 已经通过生产探测的声明。
12
+
13
+ ## 目标
14
+
15
+ AI Runtime Readiness V1 为 Southwind Server、Module Operation Host 和各独立
16
+ Runtime 提供同一套失败关闭契约。它回答的是:
17
+
18
+ > 当前这个 Operation 能否在一个已经过真实探测、身份和 release 均未漂移的
19
+ > Deployment 上,按完整声明的能力、模态和资源上限执行?
20
+
21
+ 它不把进程存活、环境变量存在、URL 非空或 Adapter 已实例化解释为可执行能力。
22
+ 某个可选 Runtime unavailable 只影响依赖它的 Operation,不阻止普通非 AI 功能和其它
23
+ Runtime 启动。
24
+
25
+ V1 公共类型、`parseAiRuntimeReadinessV1()`、offers digest、Deployment identity
26
+ parser 和 Operation 投影均从 `@southwind-ai/server-sdk` 根入口稳定导出,Schema
27
+ 常量为 `AI_RUNTIME_READINESS_SCHEMA_VERSION = 1`。Runtime 间共享的 wire fixture
28
+ 位于:
29
+
30
+ ```text
31
+ packages/server-sdk/contracts/ai-runtime-readiness/v1
32
+ ```
33
+
34
+ ## 核心术语
35
+
36
+ **Runtime snapshot**
37
+ : 一次有明确版本和有效期的 readiness 事实。单个 snapshot 只证明一个不可变
38
+ Deployment identity、一个 release digest 和一个 offers digest,不能同时代表多个
39
+ 可互换 Deployment。
40
+
41
+ **Deployment identity**
42
+ : 精确指向一个不可原地改写的部署实例或部署 release。V1 只接受
43
+ `windy-deployment-v1_<canonical lowercase UUIDv4>`;稳定的 Deployment Key、URL、
44
+ route alias、文件路径、Header 或 Secret 都不能替代不可变 identity。
45
+
46
+ **Release digest**
47
+ : 对 Runtime、Adapter、模型和服务 release 等执行实现形成的 canonical digest。模型
48
+ 或服务实现发生语义变化时,不能继续沿用旧证明。
49
+
50
+ **Offers digest**
51
+ : 对当前 Deployment 完整原子 offers 的 canonical SHA-256 摘要。它同时由 Registry
52
+ pin、snapshot Deployment 和 probe attestation 固定,并由 Host 对收到的 offers
53
+ 重算;能力、模态、输入限额或资源容量被改写时不能沿用旧证明。
54
+
55
+ **Probe attestation**
56
+ : Runtime 对真实 downstream 探测结果签发的短时事实,包含探测状态、观察时间和过期
57
+ 时间,以及探测到的 Deployment identity、release digest 和 offers digest。`ready`
58
+ 只接受成功、未过期、TTL 不超过 300 秒且与 snapshot Deployment 完全一致的
59
+ attestation。
60
+
61
+ **Offer**
62
+ : 同一 Deployment 下一个原子的 variant 能力包。每个 offer 独立声明 variant、
63
+ capabilities、输入/输出 modalities、普通 limits 与 resource limits。V1 的明确
64
+ resource limits 是 `maxConcurrentRuns` 与 `maxQueueDepth`;它们描述容量边界,不是
65
+ 当前调用的资源预留。
66
+
67
+ Agent/VLM 的这两个 resource limits 由 Provider 配置同时注入 readiness producer 与
68
+ 实际 Run admission。`maxConcurrentRuns` 是硬执行上限,`maxQueueDepth` 是已接受等待
69
+ 上限;满载时新请求在持久化前稳定失败,幂等重试仍可读取原 Run。启动恢复只按相同容量
70
+ 领取 durable Run,因此 readiness 不会声明一个执行层并未强制的资源边界。
71
+
72
+ **Operation projection**
73
+ : Host 将一个权威 Operation requirement 和 Deployment Registry pin 投影到一个
74
+ snapshot,得到结构化的 `ready` 或 `unavailable` 结果。
75
+
76
+ ## Snapshot 与 Offer 不变量
77
+
78
+ 一个 V1 snapshot 具有以下语义:
79
+
80
+ - `schemaVersion` 必须等于 `1`;未知版本、缺失版本和格式错误都失败关闭。
81
+ - 时间统一使用 canonical UTC RFC 3339
82
+ `YYYY-MM-DDTHH:mm:ss.sssZ`;其它时区、无时区或可被不同语言规范化的写法无效。
83
+ - 一个 snapshot 只能携带一个 immutable Deployment identity、release digest 和
84
+ offers digest。
85
+ - `configured` 只表示 Host 找到了显式配置,不表示 downstream 已经就绪。
86
+ - `ready` 必须同时包含:
87
+ - `configured=true`;
88
+ - 成功且未过期的真实 downstream probe attestation;
89
+ - 非空的 immutable Deployment identity;
90
+ - 合法的 release digest;
91
+ - 与实际 offers 一致且被 probe 和 Registry pin 固定的 offers digest;
92
+ - 至少一个结构完整的 offer;
93
+ - 每个 offer 的完整 capability、输入/输出 modality、limits 和 resource limits。
94
+ - 配置、URL、Token、capability 环境变量或本地进程存在,任一项单独或组合出现都不能
95
+ 产生 `ready`。
96
+ - probe 未执行、失败、超时、响应无效或已经过期时,snapshot 必须是
97
+ `unavailable`。
98
+ - probe 的 `checkedAt` 晚于 Host 判定时间时尚未生效,不能提前形成 `ready`。
99
+ - ready snapshot 的 `observedAt` 必须位于 `checkedAt` 与 Host 判定时间之间。
100
+ - probe 的 `validUntil - checkedAt` 不得超过 V1 固定的 300 秒;Producer 不能签发
101
+ 长期有效的 readiness。
102
+ - probe 有效期采用半开区间 `[checkedAt, validUntil)`:必须满足
103
+ `checkedAt < validUntil` 且 Host 判定时间 `now < validUntil`。`now` 恰好等于
104
+ `validUntil` 时已经过期,零 TTL attestation 是无效契约。
105
+ - 成功 probe attestation 中的 `deploymentIdentity`、`releaseDigest`、
106
+ `offersDigest` 必须与 snapshot `deployment` 完全一致;不一致时必须
107
+ unavailable。
108
+ - Host 必须用 `computeAiRuntimeOffersDigestV1()` 重算 offers,并同时核对 Registry
109
+ pin;只相信 Producer 提交的 digest 仍不构成证明。
110
+ - identity、digest、capability、modality、limit 或 resource limit 缺失时,不能用
111
+ 默认值补成 `ready`。
112
+ - snapshot 不包含 Endpoint、Secret、内部 Artifact URL、业务正文、Provider 原始错误
113
+ 或响应 body。
114
+
115
+ ### 不可信输入捕获
116
+
117
+ `parseAiRuntimeReadinessV1(raw, fallbackObservedAt)` 和
118
+ `projectAiOperationReadinessV1(requirement, snapshot, options)` 把 snapshot 视为
119
+ `unknown`。Host 在读取业务字段前只捕获一次有限的 JSON-like data snapshot:
120
+
121
+ - 只接受 primitive、标准 plain object 和稠密标准 Array;
122
+ - 只读取 own enumerable data descriptors,不执行 getter、setter 或隐式字符串转换;
123
+ - 拒绝 Proxy(含 revoked Proxy)、accessor、symbol、non-enumerable 字段、自定义或
124
+ `null` prototype、循环引用、共享对象引用和原型污染 key;
125
+ - 在递归深度、对象/数组节点、属性数、数组长度、key 和字符串长度上设硬预算,超限
126
+ 直接失败关闭。
127
+
128
+ 因此恶意 getter、Proxy trap 或原始异常中的 URL、Bearer Token 和 Provider body 不会
129
+ 被执行或进入 Module 输出。parser 对无效输入返回固定 `CONTRACT_INVALID` parse
130
+ result;projector 对任何 unknown snapshot 都返回固定结构化 unavailable,不能抛出
131
+ producer 的原始错误。V1 仍忽略安全预算内的未知普通字段;超出安全捕获边界的扩展不
132
+ 属于可兼容输入。
133
+
134
+ ### Deployment identity 格式
135
+
136
+ Deployment provisioning 必须用密码学安全随机 UUIDv4 生成一次
137
+ `windy-deployment-v1_<uuid>` 并随 Deployment 持久化;probe 只能回报它实际探测到的
138
+ 同一 identity,不能在每次探测时重建。固定 prefix 和 canonical lowercase UUIDv4
139
+ 同时提供 namespace 与 122 位随机 entropy,并排除 URI、Header、locator 和宽泛任意
140
+ 文本。
141
+
142
+ Runtime、Registry requirement 和 probe 必须复用根入口公开的
143
+ `parseAiRuntimeDeploymentIdentityV1()`。即使三处填入相同 URL、路径或
144
+ `Authorization: Bearer ...`,也必须在比较相等性前判定格式无效,绝不能形成
145
+ `ready`。
146
+
147
+ ### Offer 是原子能力包
148
+
149
+ Host 必须从单个 offer 验证一个 Operation 的全部 requirement,禁止跨 offer 拼接能力。
150
+ 例如下面两个 offer:
151
+
152
+ ```text
153
+ offer A: variant=fast, capabilities=[document.ocr], maxUnits=500
154
+ offer B: variant=accurate, capabilities=[document.layout], maxUnits=100
155
+ ```
156
+
157
+ 不能组合成同时支持 `document.ocr`、`document.layout` 且 `maxUnits=500` 的虚构
158
+ Operation。一个 offer 缺少任一所需 capability、modality 或 limit 时,应继续检查其它
159
+ 完整 offer;没有单个 offer 全部满足时返回 `unavailable`。
160
+
161
+ 同一 snapshot 下的 offers 可以表示同一不可变 Deployment/release 确实提供的多个
162
+ variant,但不能借此表示不同模型、不同 Adapter release 或不同 Deployment。需要证明
163
+ 另一个 Deployment 时必须产生另一个 snapshot。
164
+
165
+ ### Offers digest canonicalization
166
+
167
+ Runtime、Registry 和 Host 统一复用公共 `computeAiRuntimeOffersDigestV1()`:
168
+
169
+ - variant、capability 和 Deployment/Operation key 只接受最长 128 字符的 ASCII
170
+ stable-key:首字符为字母或数字,其余可使用字母、数字、`.`、`_`、`:`、`/`、`-`;
171
+ - offers 按 variant 的 code-unit 顺序排序,capabilities 和 modalities 作为集合按
172
+ 同一顺序排序;
173
+ - 字段顺序由公共函数固定,可选 limit 缺失时不写入;
174
+ - 数值只接受安全整数,使用 UTF-8 compact JSON 后计算 SHA-256。
175
+
176
+ 这些约束避免 JavaScript、Python 等 Runtime 各自的 Unicode 排序、JSON 空白和字段
177
+ 顺序产生不同摘要。Integration 不得复制一份近似 canonicalization。Producer 可直接
178
+ 把普通 offers 传给公共函数,不需要先复制或自行 canonicalize;公共函数会在任何
179
+ 复制、排序和 JSON 序列化前执行同一安全捕获、结构校验和 cardinality 检查。直接调用
180
+ 传入无效或超限输入时只抛固定的 `TypeError("AI Runtime offers contract invalid")`,
181
+ 不回显原始字段。
182
+
183
+ V1 同时固定以下公开 cardinality 边界,并在遍历、复制、排序或 digest 前失败关闭:
184
+
185
+ - 一个 snapshot 最多包含 16 个不同 variant 的 offers;
186
+ - 每个 offer 最多包含 32 个不同 capability stable keys;
187
+ - input/output modality 列表最多包含 V1 公开枚举的 6 个不同值;
188
+ - Operation requirement 最多包含 16 个不同 required capability stable keys。
189
+
190
+ Host 不截断、静默去重或拼接超限输入。上述常量由 `@southwind-ai/server-sdk` 导出,
191
+ Runtime、Registry 和 Host 应直接复用。
192
+
193
+ Document Python producer 与 TypeScript 公共 parser 还共同读取
194
+ `document-python-parity.json`,固定 16 offers、32 capabilities、6 modalities、
195
+ `Number.MAX_SAFE_INTEGER` 和第一个不安全整数。Python 在聚合响应 chunk 前检查剩余字节
196
+ 预算,并按公共字段顺序 canonicalize limits,避免语言间边界或 digest 漂移。
197
+
198
+ ## Ready 判定
199
+
200
+ V1 的 `ready` 是严格合取关系:
201
+
202
+ ```text
203
+ ready =
204
+ configured
205
+ AND downstream probe attested
206
+ AND attestation not expired
207
+ AND immutable deployment identity present
208
+ AND release digest present
209
+ AND probe/snapshot/registry pin the same offers digest
210
+ AND host recomputes the same offers digest
211
+ AND at least one complete offer present
212
+ ```
213
+
214
+ Host 还要在 Operation 投影时继续验证:
215
+
216
+ ```text
217
+ operation ready =
218
+ snapshot ready
219
+ AND registry pin matches identity, release digest and offers digest
220
+ AND one offer satisfies the whole authoritative requirement
221
+ ```
222
+
223
+ 任一事实缺失都产生 `unavailable`,不能从其它 Runtime、其它 offer、Manifest 默认值或
224
+ 旧 health payload 猜测。失败结果应携带稳定、结构化且不含敏感信息的 reason;典型原因
225
+ 类别包括:
226
+
227
+ - Runtime 未配置;
228
+ - downstream 未探测、不可达、拒绝、超时或返回无效响应;
229
+ - probe attestation 已过期;
230
+ - probe 尚未生效或签发 TTL 超过 300 秒;
231
+ - readiness contract 不受支持或无效;
232
+ - Deployment identity、release digest 或 offers digest 缺失、被篡改或与 Registry
233
+ pin 不符;
234
+ - Runtime kind 不匹配;
235
+ - variant、capability、输入/输出 modality 不支持;
236
+ - 普通 limit 或 resource limit 不能满足 Operation requirement;
237
+ - 没有一个原子 offer 能独立满足完整 requirement。
238
+
239
+ V1 固定的 structured reason code 为:
240
+
241
+ ```text
242
+ RUNTIME_NOT_CONFIGURED
243
+ DOWNSTREAM_NOT_PROBED
244
+ DOWNSTREAM_PROBE_FAILED
245
+ PROBE_STALE
246
+ PROBE_NOT_YET_VALID
247
+ PROBE_TTL_EXCEEDED
248
+ PROBE_ATTESTATION_MISMATCH
249
+ RESOURCE_UNAVAILABLE
250
+ CONTRACT_UNSUPPORTED
251
+ CONTRACT_INVALID
252
+ RUNTIME_KIND_MISMATCH
253
+ DEPLOYMENT_KEY_MISMATCH
254
+ DEPLOYMENT_IDENTITY_MISSING
255
+ DEPLOYMENT_IDENTITY_MISMATCH
256
+ RELEASE_DIGEST_MISSING
257
+ RELEASE_DIGEST_MISMATCH
258
+ OFFERS_DIGEST_MISSING
259
+ OFFERS_DIGEST_MISMATCH
260
+ CAPABILITY_MISSING
261
+ VARIANT_UNSUPPORTED
262
+ INPUT_MODALITY_UNSUPPORTED
263
+ OUTPUT_MODALITY_UNSUPPORTED
264
+ LIMIT_INSUFFICIENT
265
+ RESOURCE_LIMIT_INSUFFICIENT
266
+ ```
267
+
268
+ reason 同时声明 `retryable`,并可携带安全的 `subject`、`expected` 和 `actual`;不能携带
269
+ 底层异常、Endpoint、凭据或 Provider body。Downstream probe 自身使用更窄的 failure
270
+ code 区分认证、连接、无效响应、本地依赖、资源、超时和 unhealthy。
271
+
272
+ Runtime 提交的 unavailable reason 不是可信展示内容。Host 解析时对普通 reason 只保留
273
+ `code` 与 `retryable`;`DOWNSTREAM_PROBE_FAILED` 只额外接受固定 failure-code token
274
+ 作为 `subject`,且必须与 probe 的 `failureCode`、`retryable` 精确一致。Runtime 提交
275
+ 的 `expected`、`actual`、URL、Header、Token 或 Provider body 一律不能进入
276
+ operation-level 输出;投影器自身生成的比较详情也只能使用 Host 定义的安全字段。
277
+
278
+ V1 最多接受 16 个 unavailable reasons。普通 reason 的稳定 identity 是 `code`;
279
+ `DOWNSTREAM_PROBE_FAILED` 的 identity 是 `code + 已验证的 failureCode subject`。
280
+ `retryable` 和 Runtime 原始 detail 不参与 identity,因此同一原因提交冲突的 retryable
281
+ 也会整体失败关闭。`CAPABILITY_MISSING.subject` 固定为
282
+ `operation.requiredCapabilities`,不拼接 requirement 列表。
283
+
284
+ ## Host 的常见调用
285
+
286
+ 最常见的 Module/Host 调用只提交 Operation Key,不让调用方选择 Runtime、解析 health
287
+ JSON、提供 Registry pin 或自己组合 capability:
288
+
289
+ ```ts
290
+ const projected = await readinessPort.inspect({ operationKey });
291
+
292
+ if (projected.status !== "ready") {
293
+ throw new ModuleAiOperationError(
294
+ "AI_OPERATION_UNAVAILABLE",
295
+ "AI Operation 当前不可用",
296
+ );
297
+ }
298
+ ```
299
+
300
+ 公共 `ModuleAiOperationReadinessPortV1` 只暴露 `inspect({ operationKey })`。它返回
301
+ 版本化的 `ModuleAiOperationReadinessV1` discriminated union;`ready` 分支携带
302
+ `validUntil`、Deployment 和满足要求的原子 offers,`unavailable` 分支携带非空的
303
+ structured reasons。实际 Module Operation Port 接线后,Module 调用方只消费这一
304
+ operation-level projection;Runtime snapshot、Registry pin、版本解析和 offer 选择
305
+ 保留在 Host Implementation 内。状态页面可以展示结构化 unavailable reason,执行入口
306
+ 则统一映射为稳定的 `AI_OPERATION_UNAVAILABLE` 或 HTTP 503。
307
+
308
+ Host 健康探测只接受 HTTP `200` 或 `503` 的有界 JSON;`200` 必须投影为
309
+ `ready`,`503` 必须投影为 `unavailable`,状态与正文语义不一致时失败关闭。其它状态、
310
+ 重定向、非 JSON 或超过 64 KiB 的 body 统一折叠为
311
+ `DOWNSTREAM_PROBE_FAILED`。一次普通探测只有一个硬 deadline,从调用 producer 的
312
+ `health()` 起覆盖等待 Response 与流式读取 body;即使 producer 忽略
313
+ `AbortSignal`、body 永不完成或在 deadline 后才 reject,也不能悬挂 Host,且迟到的
314
+ settlement 会被安全消费。
315
+ 按模块注入的 Port 对“Operation 不存在”与“Operation 属于其它模块”返回
316
+ 完全相同的常量结果,只有本模块 Operation 才可投影实际 Runtime kind。
317
+
318
+ Operation requirement 必须来自 Host 已组合和校验的 Module Manifest 及平台配置,
319
+ Deployment identity、release digest、offers digest 期望值必须来自 Deployment
320
+ Registry pin。浏览器、业务 Module、模型输出和请求 body 都不能提交或扩大这些事实。
321
+
322
+ ### 避免检查与执行漂移
323
+
324
+ readiness 只是短时执行前证据。后续接线应在创建 Run 时固定 projected Deployment
325
+ identity、release digest 和 offers digest,并在真正调用 Runtime 前再次核对。
326
+ attestation 在两者之间过期、Deployment 漂移或 Runtime 拒绝时,执行仍须失败关闭。
327
+
328
+ ### Screenshot intake composition
329
+
330
+ VLM 的页面截图使用独立 `ModuleAiScreenshotIntakePortV1`。Module 只能创建短时计划、
331
+ 一次性 bind,或 discard/cancel;producer-only 的 Artifact attach 不属于 Module Port,
332
+ 业务模块不能提交截图 bytes、ArtifactRef、URL 或 Run ID。Server 只在 AI 开启且
333
+ project-owned factory 存在时注入 Port;默认 factory 为空时 Request Context 不包含该 Port。
334
+
335
+ Factory 返回的 plan 和 token 不是 Module capability。Host 先确认 Operation 属于当前
336
+ Module,并重新执行 License、Feature 和 Permission Guard;producer 签发的真实 plan
337
+ 本身必须在 60 秒内过期,Host 不把更长的 capability 截断伪装成短期 plan。Host 再用
338
+ 自有 token 绑定 Module、Operation、Actor、Scope 和同一或更短的 expiry,不向 Module
339
+ 暴露 producer token。
340
+
341
+ plan 保存在 Host 生命周期内按 Module 共享的有界 store,而不是 request-local Map;
342
+ 因此新 HTTP request 即使获得新的 producer facade,也能在 Actor/Scope 不变时完成一次
343
+ bind。store 不保存 requestId、GuardContext 或表单/页面敏感内容,过期记录会有界清理。
344
+ 默认 store 只属于单个 Server 进程,不在副本间复制;多副本部署必须把同一 plan 的
345
+ create 与终态请求粘性路由到同一进程,否则终态请求会稳定失败关闭。当前实现不声明
346
+ 跨进程 HA;若不能保证粘性路由,须先提供具备有界容量、原子 claim 和 TTL 清理语义的
347
+ 共享 Host store。进程异常退出后未显式 cancel 的 producer plan 仍受自身最多 60 秒
348
+ expiry 约束,不能因此获得更长 capability。
349
+ `bind/discard/cancel` 共享一次性原子消费,终态操作使用当前 request 重新执行 Guard;
350
+ 过期、取消、重用、Scope 漂移或 producer 异常均以稳定错误 fail closed。producer 的
351
+ create/bind/discard/cancel 与清理都有硬 deadline,批量清理使用受限并发而非串行等待
352
+ 全部历史 plan。
353
+
354
+ bind 结果只接受严格 plain-data `ArtifactRef` DTO;opaque token 最多 4096 字符。
355
+ Host 还必须用自己的 Artifact codec 验证签名 claims 中的当前 Module、Actor、expiry
356
+ 以及 MIME、字节数、SHA-256 等 metadata,不能只相信 producer 返回的字段。真实
357
+ producer 仍须完成截图大小、MIME、像素、上传清理与审计,再把 opaque Artifact 绑定到
358
+ canonical Run。
359
+
360
+ ### Screenshot intake V2(浏览器受控上传)
361
+
362
+ V2 不替换 V1 Module Port。它由 `POST /api/agent/screenshots` 创建短时 Host plan,浏览器
363
+ 仅可提交 `pageId`、不透明 `contextDigest`、声明的 MIME/bytes/pixels,随后以 `PUT` 上传
364
+ 原始 bytes;禁止提交 Actor、tenant、scope、Operation、Run ownership、Artifact URL 或物理
365
+ locator。项目自己的 page Registry producer 由 `pageId` 解析允许的视觉 Operation,Host 再从
366
+ 认证 RequestContext 重建 Actor/Scope,并执行 Permission、Feature、License Guard。
367
+
368
+ 当前 V2 只接受 PNG;Host 在上传时验证 PNG 签名、IHDR 宽高、声明像素和精确字节数,且同时
369
+ 应用 8 MiB、2,000 万像素、每个 plan 单图和有界总计划数限制。生产 producer 必须将实际
370
+ bytes 写入其受治理 Artifact 存储,并只交回 opaque `ArtifactRef`。`contextDigest` 是摘要,
371
+ Windy DTO 不保存 modal、DOM、form 或输入原文;长文本仍应进入原有 schema-governed input。
372
+
373
+ 创建时固定页面、Operation、context digest、purpose、TTL 和 Manifest deployment/release/offers
374
+ pin。Run admission 在 `remote.start` 前取得新的 VLM readiness pin;只有与计划完全一致时才
375
+ 可 reserve Artifact。Remote Runtime 与 Agent Server 创建端各再核对一次 pin;创建成功后 Host
376
+ 以真实 canonical Run ID 终结绑定。上传重放、取消、未使用 TTL、scope/Operation/pin 漂移、
377
+ factory 缺失或 producer 异常均会取消并失败关闭。
378
+
379
+ ## 四类 Runtime 的统一投影
380
+
381
+ ### Document
382
+
383
+ Document offer 可以表达 OCR、版面、表格、手写等 variant 与 capability,并完整声明
384
+ document/image 输入、输出 modality、页数、Artifact 数、输入输出字节、像素、运行时间
385
+ 及相应 resource limits。Document Adapter URL 存在不构成 probe。
386
+
387
+ ### Speech
388
+
389
+ Speech offer 按实际支持情况原子表达 `normalize`、`transcribe`、`translate` 等
390
+ variant,以及 audio/video 输入、时间戳 capability、媒体时长、分段数、字节和资源限制。
391
+ 不能把只支持 normalize 的 offer 与只支持 translate 的 offer 拼成一个复合能力。
392
+ FFmpeg/FFprobe 可用也只证明本地前处理条件,不能替代真实 Speech downstream probe。
393
+
394
+ ### Embedding
395
+
396
+ Embedding offer 分别表达实际支持的 text/image modality、批量、Artifact、像素、输入
397
+ 输出大小和资源限制。Deployment identity、release digest、维度和归一化等会影响索引
398
+ 可重现性的事实必须由可信 Runtime/Registry 固定,不能只信 Adapter 响应或配置 URL。
399
+
400
+ ### Agent/VLM
401
+
402
+ VLM 不新增 `vision` Runtime kind,也不新增业务可选的 `vision` Operation kind。
403
+ VLM 继续使用 `kind=agent`,由 offer 中的 `vision` capability、image modality、
404
+ Artifact/字节/像素上限以及对应 resource limits进行投影。普通文本 Agent offer 不能与
405
+ 另一个只提供图片能力的 offer 拼成虚构的 VLM offer。
406
+
407
+ ## 向后兼容
408
+
409
+ V1 保持新公共类型和导出为 additive change,不要求已有业务 Module 自行实现 Runtime
410
+ readiness。现有 `ModuleAiOperationPort` 若要暴露新能力,应采用新的组合 Interface 或
411
+ 向后兼容的可选入口,不能直接增加所有旧 Adapter 都必须实现的 required method。
412
+
413
+ 公共 readiness Port 不把旧 `/health/ready` payload 投影为 V1 ready:即使它包含
414
+ `status=ready`、capabilities、limits 或 deployment alias,也不能补写缺失的 probe、
415
+ identity 或 digest。唯一的过渡例外是已发布 0.5.2 的无 Output Artifact Document
416
+ facade:它继续接受原有 `status/capabilities` 检查,同时在 payload 明确声明
417
+ `schemaVersion=1` 时改用公共 parser/projector 消费完整 offer。这个 legacy 分支不产生
418
+ operation-level readiness、不能服务 Output Artifact binding,也不能被状态页解释为
419
+ V1 ready;未知 schema version 仍失败关闭。
420
+
421
+ 未来 V1 只允许不改变既有语义且位于安全捕获预算内的可选扩展。新增必要字段、扩大
422
+ 安全输入预算、改变 ready 判定、改变 offer 原子性或 reason 语义时必须审查兼容性,
423
+ 必要时提升 schema version。未知新版本在旧 Host 上继续失败关闭。
424
+
425
+ ## 与授权和资源调度的关系
426
+
427
+ Readiness 不替代以下权威检查:
428
+
429
+ - License;
430
+ - Feature Flag;
431
+ - RBAC Permission;
432
+ - Actor 与数据 Scope;
433
+ - Artifact 当前授权、MIME、哈希与业务对象绑定;
434
+ - Provider egress、DLP 和 Tool network policy;
435
+ - Run 幂等、取消、审计和输出校验。
436
+
437
+ 这些 Guard 仍由 Southwind Server 在每次执行的相应阶段重新检查。对未授权调用方,
438
+ Host 不应通过 readiness 暴露跨模块或跨租户的 Deployment 细节。
439
+
440
+ Readiness 也不是 GPU、CPU、显存、队列或并发槽位的资源预留。resource limits 描述该
441
+ offer 可接受的硬边界;Operation 的 `minConcurrentRuns` 与 `minQueueDepth` 只过滤不
442
+ 满足最低部署容量的 offer。投影成功不保证未来瞬时容量。创建 Run 时仍可能因限流、
443
+ 预算、队列饱和或现场资源变化返回稳定错误。
444
+
445
+ ## 共享 Fixture 与 Contract Tests
446
+
447
+ `packages/server-sdk/contracts/ai-runtime-readiness/v1` 是 V1 wire contract 的共享
448
+ fixture 事实源。Document、Speech、Embedding 和 Agent/VLM 使用同一套断言,至少覆盖:
449
+
450
+ - 真实、未过期 probe attestation 可以参与 ready 投影;
451
+ - 配置存在但未 probe 必须 unavailable;
452
+ - probe 失败、无效或过期必须 unavailable;
453
+ - identity、release/offers digest 缺失、篡改或 Registry pin 漂移必须 unavailable;
454
+ - 单个 offer 完整满足 requirement 时 ready;
455
+ - capability、variant、modality、limit 或 resource limit 不足时 unavailable;
456
+ - 两个不完整 offer 不能跨 offer 拼接;
457
+ - legacy payload 和未知 schema version 失败关闭;
458
+ - getter、Proxy、循环、原型污染和其它非 JSON snapshot 不执行、不抛且不泄漏原始
459
+ detail;
460
+ - direct offers digest 在 MAX 接受,在 MAX+1、巨大稀疏数组、accessor 和 Proxy 输入
461
+ 上于 canonicalization 前失败关闭;
462
+ - `now === validUntil` 已过期,`checkedAt === validUntil` 的零 TTL attestation
463
+ 无效;
464
+ - VLM 仍按 Agent Runtime 与 Agent Operation 投影。
465
+ - Document Python 与 TypeScript 从同一 parity fixture 验证 cardinality 和安全整数
466
+ 临界值。
467
+
468
+ Fixture 只证明 DTO、解析和投影规则一致,不证明真实模型、OCR、ASR 或 Embedding
469
+ downstream 已经部署或可达。
470
+
471
+ ## 后续 Integration 接线
472
+
473
+ 本任务不实现真实 probe Adapter,也不把现有 Runtime 宣称为 ready。后续
474
+ `WINDY-RUNTIME-READINESS-INTEGRATION-1` 至少需要完成:
475
+
476
+ 1. **Document Host 接线**:Document Runtime 已对实际 OCR/Document Adapter 执行
477
+ 有界、认证的 downstream probe,并签发 V1 attestation、producer identity、
478
+ release/offers digest 和完整 offers;Output Artifact Sink 私有 route 也会执行真实
479
+ upload/seal/authorized-read/cleanup,且缺少 Composition 注入的 Sink
480
+ `identity/releaseDigest/protocolVersion` 时固定 `503`。统一 Host 已把 raw snapshot 接入
481
+ Manifest Registry expected pin 与 operation projector,生产 bootstrap、生成器/env
482
+ 也已提供不可变 producer/Sink facts 接缝;具体项目仍须 provisioning 真实 facts、
483
+ 持久 Repository 与 project-owned Operation binding 后才能标记 ready。
484
+ 2. **Speech**:分别核对 FFmpeg/FFprobe 前处理条件与真实 Speech Adapter,报告实际
485
+ variant、媒体模态、输入和资源限制。
486
+ 3. **Embedding**:探测实际 Embedding downstream,并核对 Deployment、模型 release、
487
+ modalities、输入和资源限制;dimensions、normalized 等语义变化必须反映在新的
488
+ release digest 中。
489
+ 4. **Agent/VLM**:复用 Agent Runtime 的真实 Provider probe,补齐文本与 VLM 的原子
490
+ offers、Deployment identity、release digest、模态和资源限制。
491
+ 5. **Module Operation Port**:在 Host 中接入统一 parser/projector,替换各 facade
492
+ 分散的裸 health/capability 判断,对 Module 只暴露 operation-level 结果,并在 Run
493
+ 创建和执行时固定、复核 identity、release digest 和 offers digest。
494
+ 6. **聚合与恢复**:验证单 Runtime unavailable 不影响其它 Runtime,覆盖 probe
495
+ 过期、Deployment/release 漂移、恢复和旧生成项目的失败关闭行为。
496
+
497
+ 只有这些真实 Adapter 和 Host 接线通过对应合约、集成与业务样本验收后,才能把具体
498
+ Operation 标记为已就绪。
@@ -1,6 +1,6 @@
1
1
  # Southwind AI Runtime 架构
2
2
 
3
- 更新时间:2026-07-26。
3
+ 更新时间:2026-07-31。
4
4
 
5
5
  状态:架构已确认,文本 Agent、Document AI、批量 Speech/ASR 与受控 Vision Artifact
6
6
  切片已实现。当前包含 Module AI Operation
@@ -9,8 +9,9 @@ Provider、canonical HTTP/SSE、取消、cursor 重放和单副本有界 SQLite
9
9
  Provider 时仍安全拒绝。真实业务 Run 已在内部使用 ADK 2.5 Runner、Session、LlmAgent
10
10
  和 Event,并把事件转换为既有 canonical signal。ADK Workflow、LiteLLM 多 Provider
11
11
  路由和 PostgreSQL 多副本 Store 尚未实现。Document AI 已提供独立
12
- Server、授权 ArtifactRef、结构化页级结果和本地/内网 Adapter 契约,但未提供搜索型
13
- PDF 输出 Artifact;Speech 已提供批量转写、归一化、VAD/时间戳契约、稳定分段和结果
12
+ Server、授权 ArtifactRef、结构化页级结果、本地/内网 Adapter 契约,以及搜索型 PDF
13
+ 等派生文件的受治理 Output Artifact producer 协议;项目 composition 尚未接线,不能
14
+ 视为生产可用。Speech 已提供批量转写、归一化、VAD/时间戳契约、稳定分段和结果
14
15
  Artifact,但未提供实时 ASR、TTS 或 Dictation。不能据此宣称完整 AI Runtime 已交付。
15
16
  Vision 已提供 `agent.vision` 的多图片受控输入、像素限制、逐次发送审计和 JSON Schema
16
17
  终态校验;视频帧输入与实时视觉不在当前切片。
@@ -144,10 +145,18 @@ ADK 和 LiteLLM 不同时维护两套路由或 fallback。ADK 决定运行哪个
144
145
 
145
146
  - OCR、版面分析、表格识别和长文档解析 Adapter;
146
147
  - 文档处理 Run、页级进度和结果 Artifact;
148
+ - Output Artifact 的 generation ACK、manifest-first 流式校验和 Sink 补偿;
147
149
  - PaddleOCR、Unlimited OCR、本地/内网/云端 OCR 的能力归一化;
148
150
  - 页数、图像、像素、处理时长和 GPU 时间等用量事实。
149
151
 
150
152
  即使底层 Unlimited OCR 或其他 OCR 使用视觉语言模型,业务 Interface 仍是 Document Operation,不暴露 Chat Completion。
153
+ raw Output Grant 只存在于专用内部 Header 和 Runtime 进程内 CAS;不得进入 JSON、
154
+ 持久化、事件、日志、错误或 Provider 请求。重启恢复要求同一幂等语义和严格更高
155
+ generation,终态和事件必须单调。没有 Output Sink 的遗留非终态 Run 在启动事务中
156
+ 稳定失败;有 Sink 的 Run 从创建事务起就使用不会因重试或重启而顺延的固定恢复期限,
157
+ 只有 ACK 成功并调度任务后才清除恢复状态。只有 ACK 传输不确定时,当前进程才可用同
158
+ generation 和 exact token 重试;后台到期事务只写入一个失败事件,并以精确 generation
159
+ credential 删除 scope,缺少 credential 时如实保留 Host TTL cleanup pending 事实。
151
160
 
152
161
  ### Speech Server
153
162
 
@@ -570,7 +579,13 @@ document.extract.table
570
579
  document.extract.handwriting
571
580
  ```
572
581
 
573
- 长文档采用异步 Run。输入和结果通过 `ArtifactRef` 关联,页级进度可以使用状态查询或独立 SSE;文档内容本身不以 token delta 形式传输。
582
+ 长文档采用异步 Run。输入和结果通过 `ArtifactRef` 关联,页级进度可以使用状态查询或独立 SSE;文档内容本身不以 token delta 形式传输。Adapter 的无文件结果继续使用
583
+ `application/json` 且 `artifacts` 必须为空;派生文件使用 manifest-first
584
+ `multipart/related`,由 Runtime 校验 MIME、大小与 SHA-256 后通过 Host Sink 的
585
+ begin/part/complete/seal 生命周期密封。`maxOutputBytes` 同时约束 manifest JSON 与
586
+ Artifact 的业务内容总和,framing 余量不能转化为额外业务预算;截断、校验失败、超时
587
+ 和取消都会清理当前及先前临时文件。只有真正空正文的 `204` 才算 ACK。任何失败或取消
588
+ 都按精确 generation 执行授权删除补偿;没有当前 credential 时不伪装清理成功。
574
589
 
575
590
  路由考虑文档类型、页数、文件大小、语言、表格/版面需求、GPU、数据分类、成本和时限。敏感文档默认只允许 localhost 或 intranet Deployment,除非 Operation 明确允许出网。
576
591
 
@@ -791,6 +806,7 @@ fail closed。开发 ADK Web 已作为 localhost-only 的受控调试入口交
791
806
 
792
807
  ## 相关文档与资料
793
808
 
809
+ - [AI Runtime Readiness V1](./ai-runtime-readiness.md)
794
810
  - [平台基础设施](./foundation-infrastructure.md)
795
811
  - [Module Manifest 组合契约](./module-manifest-composition.md)
796
812
  - [模块初始化 Host](./module-host.md)
@@ -56,11 +56,60 @@ Actor、租户、部门、Scope Grant 和 Role ID,不含 Permission、凭据
56
56
 
57
57
  模块 Durable Handler 每次执行、自动重试和进程重启恢复时都重新从系统身份仓储解析当前
58
58
  Actor;用户停用、Scope 变化或缺少提交快照时以稳定错误 fail-closed。范围稳定后,Worker
59
- 才创建 `ModuleDurableHandlerContext`,其中只额外开放当前 Actor、request ID 和受限
60
- `storage.openResourceFile()`。每次文件读取仍重新执行当前 License、Feature、Permission、
61
- nominal Scope、资源与 fileId 绑定以及业务对象授权;成功与拒绝都走资源策略声明的审计
62
- 动作。Handler 不获得 Upload Repository、BlobStore、对象存储 Key、ArtifactRef 或主机
63
- 路径。
59
+ 才创建 `ModuleDurableHandlerContext`,其中开放当前 Actor、request ID、signal、
60
+ `storage.openResourceFile()` 和可选 `storageWriter: ModuleStorageWritePortV1`。每次文件读取仍重新执行当前
61
+ License、Feature、Permission、nominal Scope、资源与 fileId 绑定以及业务对象授权;
62
+ 成功与拒绝都走资源策略声明的审计动作。Writer 的五个方法为
63
+ `createUploadSession/getUploadSession/appendUploadPart/completeUpload/abortUpload`,
64
+ Owner 与可用 purpose 均来自本次 attempt 的 Host Context。Handler 不获得 Upload
65
+ Repository、BlobStore、对象存储 Key、ArtifactRef、tenant/Actor/Owner 输入或主机路径。
66
+
67
+ ### Durable 流式写入恢复
68
+
69
+ Upload session、已提交分片、服务端下一分片号和偏移属于 Storage Repository 的持久
70
+ 事实。需要跨 attempt 写入时,Handler 必须把 opaque session ID 保存到 payload 所引用的
71
+ 业务持久事实;也可以由提交 Route 先创建会话,再把 session ID 固化进 Job payload。不得
72
+ 把 session、Writer 或流 Reader 只保存在闭包、模块单例或 Worker 内存中。
73
+
74
+ 每个 attempt 的恢复顺序固定为:
75
+
76
+ 1. Worker 重新解析 `requestedBy`,比较提交时 Scope snapshot,并按当前 License、
77
+ Feature 与 Permission 重新授权;
78
+ 2. 业务从持久事实取得 opaque session ID,调用 `getUploadSession` 获取服务端
79
+ `nextPartNumber` 与 `receivedByteSize`;
80
+ 3. 按该位置继续 `appendUploadPart`,全部写入后调用 `completeUpload`;
81
+ 4. 完成结果写回业务持久事实;同一会话重复 `completeUpload` 返回首次发布的同一文件。
82
+
83
+ Host 在每个 Writer 调用上再次确认 session Owner 与当前模块注册 purpose。用户、Scope
84
+ 或 purpose 在 attempt 间漂移时立即 fail closed;Upload Repository 还保存创建时的
85
+ module 与 canonical Scope hash,当前 binding 必须完全匹配。不允许历史或无 binding 的
86
+ session ID 恢复旧授权,也不把底层存在性返回给业务。
87
+
88
+ attempt 的 `AbortSignal` 会中止当前流和本次尚未提交的临时 Blob,但已通过 CAS 提交的
89
+ 分片继续保留,下一 attempt 可以恢复。取消不等于业务放弃:只有显式
90
+ `abortUpload` 才删除该 session 的全部已提交分片;进程直接退出或来不及 abort 时,由
91
+ `system.storage.cleanup` 按 session TTL 清理,未引用 Blob 继续受 orphan grace period
92
+ 保护和回收。abort intent CAS 前已观察到取消或 lease 丢失的旧 attempt 不能改变会话;
93
+ 若 CAS 已先提交为 `aborting`,该会话不再恢复上传,后续 attempt 或 TTL 只负责重放清理。
94
+ 确认放弃通常应由后续重新授权的 attempt 执行;进程内 Signal 不是数据库 lease fence。
95
+ 业务 Handler 不注册自己的上传清理 timer。终止本身按
96
+ `uploading -> aborting -> aborted` 持久推进;只有 Blob 与 part 行清理完成才提交终态,
97
+ 失败或重启后的 attempt 可安全重放。
98
+
99
+ Writer 统一记录 `file.upload.create`、`file.upload.part.write`、
100
+ `file.upload.complete`、`file.upload.abort`。审计 target 只使用不透明 session/file
101
+ ID,metadata 只按动作从 purpose、分片位置、大小、SHA-256 和幂等重放白名单取值;
102
+ Module、Actor 与 request ID 来自本次 attempt,不能由 payload 覆盖,metadata 不包含
103
+ 文件内容或物理 locator。失败事件可额外记录稳定 `errorCode`,所有 Durable Writer
104
+ 事件还由 Host 加入 `jobId/attemptNumber`;这三项同样不能由 payload 覆盖。
105
+
106
+ Handler 需要外部系统凭据时只能通过
107
+ `requireModuleSecretPort(ModuleDurableHandlerContext)` 取得受治理 Port,并按 Manifest
108
+ 已声明的逻辑 handle/connection/purpose 请求。SDK 为旧 Context 测试桩保留 optional
109
+ 字段,但 Windy Host 每个 attempt 都注入新 Port;缺字段只返回稳定 unavailable,不存在
110
+ env/file fallback。每次 resolve 都重新执行当前 License、Feature、Permission、binding
111
+ 状态和 SecretResolver;Job payload、进度、Failure 和 Artifact 元数据不保存 Secret
112
+ 或 locator。
64
113
 
65
114
  任务产物读取统一经过 `DurableArtifactService`:先按 `jobId + kind` 回读持久化元数据,再校验 Owner 或显式 manage 能力、留存时间、Blob 大小和 SHA-256。调用方不能凭 `ArtifactRef` 猜测下载;API 层仍需执行对应 RBAC Guard 并记录下载审计。
66
115