agentengine-sdk-python 0.8.2__py3-none-any.whl → 0.8.3__py3-none-any.whl

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 (250) hide show
  1. {agentengine_sdk_python-0.8.2.dist-info → agentengine_sdk_python-0.8.3.dist-info}/METADATA +18 -25
  2. {agentengine_sdk_python-0.8.2.dist-info → agentengine_sdk_python-0.8.3.dist-info}/RECORD +224 -169
  3. ksadk/_build_provenance.json +1 -0
  4. ksadk/agui/_agent_helpers.py +4 -0
  5. ksadk/api/client.py +3 -0
  6. ksadk/builders/managed_runtime_builder.py +3 -0
  7. ksadk/cli/__init__.py +6 -0
  8. ksadk/cli/cmd_plugin.py +657 -0
  9. ksadk/codex/runtime.py +50 -8
  10. ksadk/configs/env_registry.py +31 -3
  11. ksadk/configs/settings.py +9 -0
  12. ksadk/context_engine/contributors.py +73 -8
  13. ksadk/conversations/__init__.py +19 -0
  14. ksadk/conversations/context.py +104 -24
  15. ksadk/conversations/contracts.py +266 -0
  16. ksadk/conversations/message_projection.py +19 -1
  17. ksadk/conversations/projector.py +616 -0
  18. ksadk/conversations/reducer.py +98 -0
  19. ksadk/events/_v1_compat/projection.py +2 -0
  20. ksadk/events/adapters/codex.py +190 -0
  21. ksadk/harness/__init__.py +45 -35
  22. ksadk/harness/runtime.py +60 -1
  23. ksadk/kernel/contract_fingerprints.py +5 -4
  24. ksadk/kernel/contracts.py +8 -0
  25. ksadk/kernel/control.py +1 -0
  26. ksadk/kernel/ingress.py +21 -0
  27. ksadk/kernel/memory_store.py +1 -0
  28. ksadk/kernel/postgres_store.py +1 -0
  29. ksadk/kernel/sqlite_store.py +1 -0
  30. ksadk/kernel/worker.py +11 -0
  31. ksadk/memory/providers/local_sqlite.py +7 -0
  32. ksadk/plugins/__init__.py +167 -0
  33. ksadk/plugins/bridges/__init__.py +45 -0
  34. ksadk/plugins/bridges/codex.py +552 -0
  35. ksadk/plugins/bridges/dsh.py +1116 -0
  36. ksadk/plugins/builtins.py +747 -0
  37. ksadk/plugins/bundle.py +246 -0
  38. ksadk/plugins/bundle_security.py +167 -0
  39. ksadk/plugins/composition.py +529 -0
  40. ksadk/plugins/context_contributor.py +437 -0
  41. ksadk/plugins/contracts.py +451 -0
  42. ksadk/plugins/dsh_toolchain.py +935 -0
  43. ksadk/plugins/ecosystem_bridge.py +1105 -0
  44. ksadk/plugins/ecosystem_probe.py +191 -0
  45. ksadk/plugins/host.py +724 -0
  46. ksadk/plugins/providers/__init__.py +85 -0
  47. ksadk/plugins/providers/bundles/ksadk-codex/cordis.patch.yml +3 -0
  48. ksadk/plugins/providers/bundles/ksadk-codex/index.mjs +18 -0
  49. ksadk/plugins/providers/bundles/ksadk-codex/package.json +19 -0
  50. ksadk/plugins/providers/bundles/ksadk-harness/cordis.patch.yml +3 -0
  51. ksadk/plugins/providers/bundles/ksadk-harness/index.mjs +19 -0
  52. ksadk/plugins/providers/bundles/ksadk-harness/package.json +19 -0
  53. ksadk/plugins/providers/codex.py +722 -0
  54. ksadk/plugins/providers/codex_dsh.py +83 -0
  55. ksadk/plugins/providers/dsh.py +951 -0
  56. ksadk/plugins/providers/dsh_descriptor_host.py +226 -0
  57. ksadk/plugins/providers/harness.py +627 -0
  58. ksadk/plugins/providers/harness_dsh.py +91 -0
  59. ksadk/plugins/providers/legacy.py +215 -0
  60. ksadk/plugins/providers/legacy_catalog.py +100 -0
  61. ksadk/plugins/providers/shipped_dsh.py +370 -0
  62. ksadk/plugins/resolver.py +331 -0
  63. ksadk/plugins/subagent_providers/__init__.py +12 -0
  64. ksadk/plugins/subagent_providers/codex.py +443 -0
  65. ksadk/plugins/subagents.py +333 -0
  66. ksadk/runtime/_runner_adapter/stream_mapping.py +51 -42
  67. ksadk/runtime/adapter.py +1 -0
  68. ksadk/runtime/factory.py +76 -2
  69. ksadk/runtime/framework_adapters.py +18 -0
  70. ksadk/runtime/runner_adapter.py +5 -0
  71. ksadk/sandbox/__init__.py +2 -1
  72. ksadk/sandbox/factory.py +72 -0
  73. ksadk/scheduler/__init__.py +18 -0
  74. ksadk/scheduler/calendar.py +102 -0
  75. ksadk/scheduler/contracts.py +254 -0
  76. ksadk/scheduler/dispatcher.py +129 -0
  77. ksadk/scheduler/engine.py +416 -0
  78. ksadk/scheduler/sqlite_store.py +563 -0
  79. ksadk/server/static/assets/{ArtifactsPanel-DSU1sWD_.js → ArtifactsPanel-10GPXIJ6.js} +1 -1
  80. ksadk/server/static/assets/{CodeBlock-DOH6MVcn.js → CodeBlock-BXk1l-G1.js} +1 -1
  81. ksadk/server/static/assets/{MathMessageMarkdown-BL8my1R2.js → MathMessageMarkdown-D9uB55Oh.js} +1 -1
  82. ksadk/server/static/assets/{MermaidBlock-Dz4IP-Tx.js → MermaidBlock--OEYoXIJ.js} +6 -6
  83. ksadk/server/static/assets/{NativeTerminalPanel-DUrK0JpZ.js → NativeTerminalPanel-DrEe1syq.js} +1 -1
  84. ksadk/server/static/assets/{abnfDiagram-VCTEODGH-g20pFzNV.js → abnfDiagram-VCTEODGH-eeTFJLvo.js} +1 -1
  85. ksadk/server/static/assets/{arc-C4FzinUA.js → arc-S3ZNbIAd.js} +1 -1
  86. ksadk/server/static/assets/architecture-7GRP2DOG-Dk9nRQ6-.js +1 -0
  87. ksadk/server/static/assets/{architectureDiagram-5GKGNRK7-DpIqL5h4.js → architectureDiagram-5GKGNRK7-CRjgEJDX.js} +1 -1
  88. ksadk/server/static/assets/{blockDiagram-NRAW4CY4-BjkljTNz.js → blockDiagram-NRAW4CY4-C7bsBoNH.js} +1 -1
  89. ksadk/server/static/assets/{c4Diagram-UCG6FXSJ-Dk_ieq2X.js → c4Diagram-UCG6FXSJ-BX3c33Ob.js} +1 -1
  90. ksadk/server/static/assets/channel-s354Yo6o.js +1 -0
  91. ksadk/server/static/assets/chunk-2Q5K7J3B-CDpPpKR5.js +1 -0
  92. ksadk/server/static/assets/{chunk-5VM5RSS4-BVHAchFb.js → chunk-5VM5RSS4-bZ7ws-8m.js} +1 -1
  93. ksadk/server/static/assets/{chunk-F27PBJKO-C-ipQzuS.js → chunk-F27PBJKO-D2r0pvhY.js} +1 -1
  94. ksadk/server/static/assets/{chunk-G27WJ6UU-C2EyJbIK.js → chunk-G27WJ6UU-CZwF3oUP.js} +1 -1
  95. ksadk/server/static/assets/{chunk-JWPE2WC7-vYvVJb_M.js → chunk-JWPE2WC7-DigFYCML.js} +1 -1
  96. ksadk/server/static/assets/{chunk-LCL6LL3I-BcI6ysPT.js → chunk-LCL6LL3I-CnorGV5q.js} +1 -1
  97. ksadk/server/static/assets/{chunk-POPQ4Y6H-C030x_Z1.js → chunk-POPQ4Y6H-CexntQA-.js} +1 -1
  98. ksadk/server/static/assets/{chunk-RHFEMEQ7-yyGpsz4n.js → chunk-RHFEMEQ7-CHTC7UxA.js} +1 -1
  99. ksadk/server/static/assets/{chunk-SVP7TREG-BLTlmMU7.js → chunk-SVP7TREG-BC1EWt_-.js} +1 -1
  100. ksadk/server/static/assets/{chunk-XXDRQBXY-C_32ArgP.js → chunk-XXDRQBXY-BTG24xN0.js} +1 -1
  101. ksadk/server/static/assets/classDiagram-DTDB5LWJ-Dd0nucl9.js +1 -0
  102. ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-Dd0nucl9.js +1 -0
  103. ksadk/server/static/assets/{cose-bilkent-JH36ORCC-9YQYwdl0.js → cose-bilkent-JH36ORCC-CkonRdAS.js} +1 -1
  104. ksadk/server/static/assets/cynefin-OW5HDTMX-BBlT4uMf.js +1 -0
  105. ksadk/server/static/assets/{cynefinDiagram-5FMLGOSQ-ErLF5N13.js → cynefinDiagram-5FMLGOSQ-DEOCBe15.js} +1 -1
  106. ksadk/server/static/assets/{dagre-3AP2YEHR-DFiQF-6f.js → dagre-3AP2YEHR-DBThPuLa.js} +1 -1
  107. ksadk/server/static/assets/{dagre-BuhGnRI1.js → dagre-ClTPrTht.js} +1 -1
  108. ksadk/server/static/assets/{diagram-S7CK7UJ4-Bt1v8-GC.js → diagram-S7CK7UJ4-DsZHrnpJ.js} +1 -1
  109. ksadk/server/static/assets/{diagram-UQ7AKVKN-DSCxJdBK.js → diagram-UQ7AKVKN-BJR4nhVr.js} +1 -1
  110. ksadk/server/static/assets/{diagram-VSXAHHWV-DHfYwp_9.js → diagram-VSXAHHWV-xzcERX0a.js} +1 -1
  111. ksadk/server/static/assets/{diagram-VX7I27RA-DdzD-4Le.js → diagram-VX7I27RA-tn2xM1xu.js} +1 -1
  112. ksadk/server/static/assets/{diagram-Z3DM3KII-Du-nAJ9F.js → diagram-Z3DM3KII-BZPGBkw5.js} +1 -1
  113. ksadk/server/static/assets/{dist-ClxGviKw.js → dist-4zN1_tq5.js} +1 -1
  114. ksadk/server/static/assets/{dist-BE7bu-DL.js → dist-8VWI-2bZ.js} +1 -1
  115. ksadk/server/static/assets/{dist-BX8z72IC.js → dist-B-46q3Hk.js} +1 -1
  116. ksadk/server/static/assets/{dist-BjU6y-A2.js → dist-B0gdk4rl.js} +1 -1
  117. ksadk/server/static/assets/{dist-C_wsv-Qd.js → dist-B1oWRmrH.js} +1 -1
  118. ksadk/server/static/assets/{dist-ngtN0DJB.js → dist-BI1qQH4n.js} +1 -1
  119. ksadk/server/static/assets/{dist-dydu68Fl.js → dist-BJLUwH6W.js} +1 -1
  120. ksadk/server/static/assets/{dist-Dq9gLD7L.js → dist-Bbwqa8TG.js} +1 -1
  121. ksadk/server/static/assets/{dist-CttYUqzS.js → dist-Btyo4vX4.js} +1 -1
  122. ksadk/server/static/assets/{dist-CXYYBw3_.js → dist-C71CsujO.js} +1 -1
  123. ksadk/server/static/assets/{dist-dDdADKFA.js → dist-CXpH_Rdd.js} +1 -1
  124. ksadk/server/static/assets/{dist-CSh_DE14.js → dist-Cq4OL6nO.js} +1 -1
  125. ksadk/server/static/assets/{dist-8hqcx0sU.js → dist-D1V3f1B4.js} +1 -1
  126. ksadk/server/static/assets/{dist-BVDffZ0U.js → dist-DJmCPRVB.js} +1 -1
  127. ksadk/server/static/assets/{dist-DnfXs8Vn.js → dist-DQAB0qn_.js} +1 -1
  128. ksadk/server/static/assets/{dist-DNp6rLRA.js → dist-DUwKa_l6.js} +1 -1
  129. ksadk/server/static/assets/{dist-B7seoj3d.js → dist-DdRBIceA.js} +1 -1
  130. ksadk/server/static/assets/{dist-BytlxIDT.js → dist-DfGFrb0v.js} +1 -1
  131. ksadk/server/static/assets/{dist-Bf2M8m3N.js → dist-DjhwGUgZ.js} +1 -1
  132. ksadk/server/static/assets/{dist-W-TIVntx.js → dist-DyqV4fL4.js} +1 -1
  133. ksadk/server/static/assets/{dist-DUX-id_F.js → dist-M67Hwu0n.js} +1 -1
  134. ksadk/server/static/assets/{dist-DmldrHd_.js → dist-u8tVH5Ak.js} +1 -1
  135. ksadk/server/static/assets/{ebnfDiagram-PWID7BFC-Da9C9NO1.js → ebnfDiagram-PWID7BFC-DVfMsLge.js} +1 -1
  136. ksadk/server/static/assets/{erDiagram-SSCWMZ5O-EAGqqR79.js → erDiagram-SSCWMZ5O-CWEZSYaw.js} +1 -1
  137. ksadk/server/static/assets/eventmodeling-NTZA5JFV-Dr5okd8V.js +1 -0
  138. ksadk/server/static/assets/flowDiagram-A5DVABFB-VEO-cVcO.js +1 -0
  139. ksadk/server/static/assets/{ganttDiagram-EL5Y4UJY-DqJsKb59.js → ganttDiagram-EL5Y4UJY-TWIxoyYL.js} +1 -1
  140. ksadk/server/static/assets/gitGraph-4MIJSDKK-CKiKY9Cf.js +1 -0
  141. ksadk/server/static/assets/{gitGraphDiagram-WWUBYQGX-B6g4dtDi.js → gitGraphDiagram-WWUBYQGX-DDh2hd2S.js} +1 -1
  142. ksadk/server/static/assets/index-B2k_urY8.js +241 -0
  143. ksadk/server/static/assets/index-ILPt6IWF.css +2 -0
  144. ksadk/server/static/assets/info-A6RAGUB7-ubA4Nm_p.js +1 -0
  145. ksadk/server/static/assets/{infoDiagram-RXCK75RN-Djm_nbd5.js → infoDiagram-RXCK75RN-CgoyWiDR.js} +1 -1
  146. ksadk/server/static/assets/{ishikawaDiagram-5VMMS53U-DWya9SG2.js → ishikawaDiagram-5VMMS53U-CyRIu_om.js} +1 -1
  147. ksadk/server/static/assets/{journeyDiagram-EYS64GPL-DutxhSNI.js → journeyDiagram-EYS64GPL-DN5JXHzN.js} +1 -1
  148. ksadk/server/static/assets/{kanban-definition-3QL26DDD-DJdOF8Fm.js → kanban-definition-3QL26DDD-CNP3ui66.js} +1 -1
  149. ksadk/server/static/assets/{katex-vFWytM5c.js → katex-DWEzQy1d.js} +1 -1
  150. ksadk/server/static/assets/{linear-BHjG8b-J.js → linear-C-qHp7d2.js} +1 -1
  151. ksadk/server/static/assets/{mermaid-parser.core-KGSy4jWT.js → mermaid-parser.core-Cl-K943T.js} +2 -2
  152. ksadk/server/static/assets/{mindmap-definition-FBJOCRG2-9-HC88D4.js → mindmap-definition-FBJOCRG2-D5DB5mYm.js} +1 -1
  153. ksadk/server/static/assets/packet-AYTQ26CC-C7R3NUlK.js +1 -0
  154. ksadk/server/static/assets/{pegDiagram-XKGWAZYB-DrEZd4fD.js → pegDiagram-XKGWAZYB-BQVc9ia_.js} +1 -1
  155. ksadk/server/static/assets/pie-WAS4IAKB-BIT6qjr3.js +1 -0
  156. ksadk/server/static/assets/{pieDiagram-E7YTZNPT-DpjqOFFp.js → pieDiagram-E7YTZNPT-B6UCAvtY.js} +1 -1
  157. ksadk/server/static/assets/{quadrantDiagram-AXDQQJYC-BiNhgOXX.js → quadrantDiagram-AXDQQJYC-mIr2d3eb.js} +1 -1
  158. ksadk/server/static/assets/radar-RG4KPBEZ-l5noef9X.js +1 -0
  159. ksadk/server/static/assets/railroad-74A4TZTK-Baea6ZvM.js +1 -0
  160. ksadk/server/static/assets/railroad-abnf-HS5TGJTU-OKn8zZnU.js +1 -0
  161. ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-DdKAKC4l.js +1 -0
  162. ksadk/server/static/assets/railroad-peg-WCYAUIDC-Bds8udlG.js +1 -0
  163. ksadk/server/static/assets/{railroadDiagram-O6MQD6OU-_Y3Ojg6G.js → railroadDiagram-O6MQD6OU-Dt3FFDmK.js} +1 -1
  164. ksadk/server/static/assets/{requirementDiagram-EFPCY7ZU-DeCFdg9K.js → requirementDiagram-EFPCY7ZU-Cz_vQtgF.js} +1 -1
  165. ksadk/server/static/assets/{sankeyDiagram-P5KCCOFB-CPH75rhw.js → sankeyDiagram-P5KCCOFB-wlO1TsH5.js} +1 -1
  166. ksadk/server/static/assets/{sequenceDiagram-WJ2MYXX4-OEpQQdr4.js → sequenceDiagram-WJ2MYXX4-CHRbElYq.js} +1 -1
  167. ksadk/server/static/assets/{sizeCapture-X5ZJPWSS-heUErzhI.js → sizeCapture-X5ZJPWSS-DXX54iyO.js} +1 -1
  168. ksadk/server/static/assets/{stateDiagram-HBIQ2CUA-DvA3jSMB.js → stateDiagram-HBIQ2CUA-Dp_lw9II.js} +1 -1
  169. ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-5b-8o2iS.js +1 -0
  170. ksadk/server/static/assets/{swimlanes-XN3QIQJK-CR-dfN_t.js → swimlanes-XN3QIQJK-D8O5UlLG.js} +1 -1
  171. ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-uf6WPRA4.js +8 -0
  172. ksadk/server/static/assets/{timeline-definition-24CTP7MA-DAVJf1TX.js → timeline-definition-24CTP7MA-8mfKcxvG.js} +1 -1
  173. ksadk/server/static/assets/treeView-Q6P3EWNA-CK5CSrSO.js +1 -0
  174. ksadk/server/static/assets/treemap-WGGIJYW6-Ch2BKgAM.js +1 -0
  175. ksadk/server/static/assets/{vennDiagram-4TSXK5OY-DwM8eDkh.js → vennDiagram-4TSXK5OY-EnNl0DE7.js} +1 -1
  176. ksadk/server/static/assets/wardley-WFR3VGLG-YW3Q0ml_.js +1 -0
  177. ksadk/server/static/assets/{wardleyDiagram-VM6X3IG4-DZL-Zz2t.js → wardleyDiagram-VM6X3IG4-DBu5fbYr.js} +1 -1
  178. ksadk/server/static/assets/{xychartDiagram-S5SC5T6Z-Dy6Yh_hu.js → xychartDiagram-S5SC5T6Z-BSVXs4IY.js} +1 -1
  179. ksadk/server/static/index.html +2 -2
  180. ksadk/skills/service_client.py +48 -0
  181. ksadk/studio/agent_lifecycle.py +26 -20
  182. ksadk/studio/api.py +513 -71
  183. ksadk/studio/api_catalog_routes.py +5 -0
  184. ksadk/studio/api_contracts.py +34 -1
  185. ksadk/studio/api_plugin_routes.py +480 -0
  186. ksadk/studio/attachment_store.py +187 -0
  187. ksadk/studio/authoring.py +10 -4
  188. ksadk/studio/authoring_coordinator.py +12 -2
  189. ksadk/studio/builder.py +123 -43
  190. ksadk/studio/cloud.py +4 -0
  191. ksadk/studio/codex_agent_service.py +12 -1
  192. ksadk/studio/codex_builder.py +54 -15
  193. ksadk/studio/codex_manifest.py +21 -1
  194. ksadk/studio/codex_run.py +16 -4
  195. ksadk/studio/compatibility_report.py +445 -0
  196. ksadk/studio/compiler.py +6 -1
  197. ksadk/studio/contracts.py +123 -4
  198. ksadk/studio/dsh_provider_registration.py +768 -0
  199. ksadk/studio/event_store.py +54 -6
  200. ksadk/studio/framework_run.py +37 -4
  201. ksadk/studio/hosted_kernel.py +1 -1
  202. ksadk/studio/operations.py +12 -2
  203. ksadk/studio/plugin_composition.py +301 -0
  204. ksadk/studio/plugin_kernel_adapter.py +128 -0
  205. ksadk/studio/plugin_runtime.py +652 -0
  206. ksadk/studio/resource_catalog.py +6 -1
  207. ksadk/studio/run_service.py +713 -75
  208. ksadk/studio/runtime_source.py +9 -1
  209. ksadk/studio/scheduler_runtime.py +374 -0
  210. ksadk/studio/scheduler_service.py +211 -0
  211. ksadk/studio/service.py +672 -82
  212. ksadk/studio/shared_web.py +167 -28
  213. ksadk/studio/soul.py +52 -0
  214. ksadk/studio/static/assets/index-DXs1Eq4M.css +1 -0
  215. ksadk/studio/static/assets/index-DeDqwTsD.js +283 -0
  216. ksadk/studio/static/index.html +2 -2
  217. ksadk/studio/validator.py +1 -1
  218. ksadk/studio/workspace.py +1 -0
  219. ksadk/version.py +1 -1
  220. ksadk_runtime_common/workspace_files/path_utils.py +41 -0
  221. ksadk/server/static/assets/architecture-7GRP2DOG-DjKratdf.js +0 -1
  222. ksadk/server/static/assets/channel-4cQHKtx1.js +0 -1
  223. ksadk/server/static/assets/chunk-2Q5K7J3B-DmgWkESh.js +0 -1
  224. ksadk/server/static/assets/classDiagram-DTDB5LWJ-DLFd9Xi0.js +0 -1
  225. ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-DLFd9Xi0.js +0 -1
  226. ksadk/server/static/assets/cynefin-OW5HDTMX-DjEM48Qp.js +0 -1
  227. ksadk/server/static/assets/eventmodeling-NTZA5JFV-CMgMaJrC.js +0 -1
  228. ksadk/server/static/assets/flowDiagram-A5DVABFB-BBKL0x3P.js +0 -1
  229. ksadk/server/static/assets/gitGraph-4MIJSDKK-Dw63mrhw.js +0 -1
  230. ksadk/server/static/assets/index-8ipRcQ-M.js +0 -240
  231. ksadk/server/static/assets/index-ByFCqjlh.css +0 -2
  232. ksadk/server/static/assets/info-A6RAGUB7-B6iAblII.js +0 -1
  233. ksadk/server/static/assets/packet-AYTQ26CC-BOYAipuq.js +0 -1
  234. ksadk/server/static/assets/pie-WAS4IAKB-Ctq0Kbku.js +0 -1
  235. ksadk/server/static/assets/radar-RG4KPBEZ-DN0-ul_0.js +0 -1
  236. ksadk/server/static/assets/railroad-74A4TZTK-C6cC_to0.js +0 -1
  237. ksadk/server/static/assets/railroad-abnf-HS5TGJTU-BimjIuRc.js +0 -1
  238. ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-CvY65ABq.js +0 -1
  239. ksadk/server/static/assets/railroad-peg-WCYAUIDC-D72Iq_Tv.js +0 -1
  240. ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-BgQY03nz.js +0 -1
  241. ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-DLVw3q5Q.js +0 -8
  242. ksadk/server/static/assets/treeView-Q6P3EWNA-BMpO0wsB.js +0 -1
  243. ksadk/server/static/assets/treemap-WGGIJYW6-Et0aqzU3.js +0 -1
  244. ksadk/server/static/assets/wardley-WFR3VGLG-CbY0mhpl.js +0 -1
  245. ksadk/studio/static/assets/index-BLpcdrgW.css +0 -1
  246. ksadk/studio/static/assets/index-CYekR2Xv.js +0 -260
  247. {agentengine_sdk_python-0.8.2.dist-info → agentengine_sdk_python-0.8.3.dist-info}/WHEEL +0 -0
  248. {agentengine_sdk_python-0.8.2.dist-info → agentengine_sdk_python-0.8.3.dist-info}/entry_points.txt +0 -0
  249. {agentengine_sdk_python-0.8.2.dist-info → agentengine_sdk_python-0.8.3.dist-info}/licenses/LICENSE +0 -0
  250. {agentengine_sdk_python-0.8.2.dist-info → agentengine_sdk_python-0.8.3.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,1105 @@
1
+ """Frozen ``PluginEcosystemBridge/v1`` source contract.
2
+
3
+ An ecosystem bridge gives KsADK one lifecycle vocabulary while leaving Codex
4
+ and DeepSeek Harness in charge of their native
5
+ plugin ABI. The contract is deliberately declarative: it does not import
6
+ third-party plugin code, run install scripts, translate Agent loops, or grant
7
+ permissions. Inspection may report unknown versions and undeclared
8
+ permissions, but planning such an external transition fails closed.
9
+
10
+ The lifecycle is split into read-only discovery (``describe``/``probe``/
11
+ ``inspect``), an immutable transition (``plan``/``stage``/``commit``), and
12
+ truthful observed state (``reconcile``/``rollback``/``dispose``). External
13
+ plugins without an explicit permission declaration are rejected fail-closed.
14
+ Secrets may only cross the boundary as references.
15
+ """
16
+
17
+ from __future__ import annotations
18
+
19
+ import re
20
+ from typing import Annotated, Literal, Protocol, cast, runtime_checkable
21
+ from urllib.parse import parse_qsl, urlsplit
22
+
23
+ from pydantic import AwareDatetime, ConfigDict, Field, RootModel, field_validator, model_validator
24
+
25
+ from ksadk.plugins.contracts import PluginContractModel
26
+
27
+ PluginEcosystem = Literal["codex", "dsh"]
28
+ PluginIntegrationMode = Literal["bridged", "linked"]
29
+ PluginSupportMaturity = Literal[
30
+ "detected",
31
+ "linked-ready",
32
+ "bridged-ready",
33
+ "unsupported",
34
+ "experimental",
35
+ ]
36
+ PluginDesiredState = Literal["disabled", "enabled"]
37
+ PluginObservedState = Literal[
38
+ "resolved",
39
+ "admitted",
40
+ "staged",
41
+ "starting",
42
+ "ready",
43
+ "degraded",
44
+ "failed",
45
+ "draining",
46
+ "stopped",
47
+ "disposed",
48
+ "rejected",
49
+ ]
50
+ BridgeAction = Literal[
51
+ "describe",
52
+ "probe",
53
+ "inspect",
54
+ "plan",
55
+ "stage",
56
+ "commit",
57
+ "reconcile",
58
+ "rollback",
59
+ "dispose",
60
+ ]
61
+
62
+ _ID = re.compile(r"^[a-z0-9]+(?:[._-][a-z0-9]+)*$")
63
+ _SEMVER = re.compile(r"^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$")
64
+ _DIGEST = re.compile(r"^sha256:[0-9a-f]{64}$")
65
+ _REF = re.compile(r"^[a-z][a-z0-9+.-]*://\S+$")
66
+ _SECRET_REF = re.compile(r"^(?:secret|env|credential|vault)://\S+$")
67
+ _PROTOCOL = re.compile(r"^[a-z][a-z0-9._-]*/v[1-9][0-9]*$")
68
+ _SENSITIVE_QUERY_KEY = re.compile(r"(?:secret|password|token|api[_-]?key)", re.IGNORECASE)
69
+
70
+
71
+ def _validate_id(value: str, *, field: str) -> str:
72
+ if not _ID.fullmatch(value):
73
+ raise ValueError(f"{field} must be a lowercase qualified id")
74
+ return value
75
+
76
+
77
+ def _validate_semver(value: str, *, field: str) -> str:
78
+ if not _SEMVER.fullmatch(value):
79
+ raise ValueError(f"{field} must use an exact semantic version")
80
+ return value
81
+
82
+
83
+ def _validate_digest(value: str) -> str:
84
+ if not _DIGEST.fullmatch(value):
85
+ raise ValueError("digest must be a lowercase sha256: digest")
86
+ return value
87
+
88
+
89
+ def _validate_ref(value: str, *, field: str) -> str:
90
+ if not _REF.fullmatch(value):
91
+ raise ValueError(f"{field} must be an absolute typed reference")
92
+ parsed = urlsplit(value)
93
+ if parsed.username is not None or parsed.password is not None:
94
+ raise ValueError(f"{field} must not embed credentials")
95
+ if any(_SENSITIVE_QUERY_KEY.search(key) for key, _ in parse_qsl(parsed.query)):
96
+ raise ValueError(f"{field} must not embed secret query parameters")
97
+ return value
98
+
99
+
100
+ def _unique(value: tuple[str, ...], *, field: str) -> tuple[str, ...]:
101
+ if any(not item for item in value):
102
+ raise ValueError(f"{field} entries must not be empty")
103
+ if len(value) != len(set(value)):
104
+ raise ValueError(f"{field} entries must be unique")
105
+ return value
106
+
107
+
108
+ class BridgeHostRequirement(PluginContractModel):
109
+ host_id: str = Field(min_length=2, max_length=128)
110
+ version_constraint: str = Field(min_length=1, max_length=128)
111
+ protocol: str = Field(min_length=3, max_length=128)
112
+ protocol_constraint: str = Field(min_length=1, max_length=128)
113
+
114
+ @field_validator("host_id")
115
+ @classmethod
116
+ def validate_host_id(cls, value: str) -> str:
117
+ return _validate_id(value, field="hostId")
118
+
119
+ @field_validator("protocol")
120
+ @classmethod
121
+ def validate_protocol(cls, value: str) -> str:
122
+ if not _PROTOCOL.fullmatch(value):
123
+ raise ValueError("protocol must be a versioned protocol id")
124
+ return value
125
+
126
+
127
+ class BridgeHostObservation(PluginContractModel):
128
+ host_id: str = Field(min_length=2, max_length=128)
129
+ available: bool
130
+ version: str | None = None
131
+ protocol: str | None = Field(default=None, min_length=3, max_length=128)
132
+ protocol_version: str | None = None
133
+ digest: str | None = None
134
+
135
+ @field_validator("host_id")
136
+ @classmethod
137
+ def validate_host_id(cls, value: str) -> str:
138
+ return _validate_id(value, field="hostId")
139
+
140
+ @field_validator("version", "protocol_version")
141
+ @classmethod
142
+ def validate_optional_version(cls, value: str | None) -> str | None:
143
+ if value is not None:
144
+ return _validate_semver(value, field="host version")
145
+ return value
146
+
147
+ @field_validator("protocol")
148
+ @classmethod
149
+ def validate_optional_protocol(cls, value: str | None) -> str | None:
150
+ if value is not None and not _PROTOCOL.fullmatch(value):
151
+ raise ValueError("host protocol must be a versioned protocol id")
152
+ return value
153
+
154
+ @field_validator("digest")
155
+ @classmethod
156
+ def validate_optional_digest(cls, value: str | None) -> str | None:
157
+ if value is not None:
158
+ return _validate_digest(value)
159
+ return value
160
+
161
+ @model_validator(mode="after")
162
+ def validate_observation(self) -> "BridgeHostObservation":
163
+ trace = (self.version, self.protocol, self.protocol_version, self.digest)
164
+ if self.available and any(item is None for item in trace):
165
+ raise ValueError("available host observations require version, protocol, and digest")
166
+ if not self.available and any(item is not None for item in trace):
167
+ raise ValueError("unavailable host observations cannot claim host identity facts")
168
+ return self
169
+
170
+
171
+ class BridgeDescriptor(PluginContractModel):
172
+ descriptor_format: Literal["ksadk.plugin-ecosystem-bridge-descriptor/v1"] = (
173
+ "ksadk.plugin-ecosystem-bridge-descriptor/v1"
174
+ )
175
+ bridge_id: str = Field(min_length=3, max_length=128)
176
+ bridge_version: str
177
+ bridge_digest: str
178
+ ecosystem: PluginEcosystem
179
+ integration_mode: PluginIntegrationMode
180
+ maturity: PluginSupportMaturity
181
+ host_requirement: BridgeHostRequirement | None
182
+ supported_actions: tuple[BridgeAction, ...]
183
+
184
+ @field_validator("bridge_id")
185
+ @classmethod
186
+ def validate_bridge_id(cls, value: str) -> str:
187
+ return _validate_id(value, field="bridgeId")
188
+
189
+ @field_validator("bridge_version")
190
+ @classmethod
191
+ def validate_bridge_version(cls, value: str) -> str:
192
+ return _validate_semver(value, field="bridge version")
193
+
194
+ @field_validator("bridge_digest")
195
+ @classmethod
196
+ def validate_bridge_digest(cls, value: str) -> str:
197
+ return _validate_digest(value)
198
+
199
+ @field_validator("supported_actions")
200
+ @classmethod
201
+ def validate_actions(cls, value: tuple[BridgeAction, ...]) -> tuple[BridgeAction, ...]:
202
+ if not value or len(value) != len(set(value)):
203
+ raise ValueError("supportedActions must be non-empty and unique")
204
+ return value
205
+
206
+ @model_validator(mode="after")
207
+ def validate_mode(self) -> "BridgeDescriptor":
208
+ if self.host_requirement is None:
209
+ raise ValueError("bridged and linked bridges require an external host")
210
+ if self.maturity == "bridged-ready" and self.integration_mode != "bridged":
211
+ raise ValueError("bridged-ready maturity requires bridged integration")
212
+ if self.maturity == "linked-ready" and self.integration_mode != "linked":
213
+ raise ValueError("linked-ready maturity requires linked integration")
214
+ return self
215
+
216
+
217
+ class BridgeDescribeRequest(PluginContractModel):
218
+ request_format: Literal["ksadk.bridge-describe/v1"] = "ksadk.bridge-describe/v1"
219
+ ecosystem: PluginEcosystem
220
+
221
+
222
+ class BridgeDescribeResult(PluginContractModel):
223
+ result_format: Literal["ksadk.bridge-describe-result/v1"] = "ksadk.bridge-describe-result/v1"
224
+ descriptor: BridgeDescriptor
225
+
226
+
227
+ class PluginManifestCandidate(PluginContractModel):
228
+ ecosystem: PluginEcosystem
229
+ integration_mode: PluginIntegrationMode
230
+ maturity: PluginSupportMaturity
231
+ manifest_kind: Literal["codex-plugin", "dsh-bundle"]
232
+ manifest_ref: str = Field(min_length=4, max_length=4096)
233
+ manifest_digest: str
234
+
235
+ @field_validator("manifest_ref")
236
+ @classmethod
237
+ def validate_manifest_ref(cls, value: str) -> str:
238
+ return _validate_ref(value, field="manifestRef")
239
+
240
+ @field_validator("manifest_digest")
241
+ @classmethod
242
+ def validate_manifest_digest(cls, value: str) -> str:
243
+ return _validate_digest(value)
244
+
245
+ @model_validator(mode="after")
246
+ def validate_candidate_mode(self) -> "PluginManifestCandidate":
247
+ expected_kind = {"codex": "codex-plugin", "dsh": "dsh-bundle"}[
248
+ self.ecosystem
249
+ ]
250
+ if self.manifest_kind != expected_kind:
251
+ raise ValueError("manifestKind does not match the detected ecosystem")
252
+ return self
253
+
254
+
255
+ class BridgeProbeRequest(PluginContractModel):
256
+ request_format: Literal["ksadk.bridge-probe/v1"] = "ksadk.bridge-probe/v1"
257
+ source_ref: str = Field(min_length=4, max_length=4096)
258
+ source_digest: str
259
+ selected_manifest_ref: str | None = Field(default=None, min_length=4, max_length=4096)
260
+
261
+ @field_validator("source_ref", "selected_manifest_ref")
262
+ @classmethod
263
+ def validate_source_ref(cls, value: str | None) -> str | None:
264
+ if value is not None:
265
+ return _validate_ref(value, field="source reference")
266
+ return value
267
+
268
+ @field_validator("source_digest")
269
+ @classmethod
270
+ def validate_source_digest(cls, value: str) -> str:
271
+ return _validate_digest(value)
272
+
273
+
274
+ class BridgeRejection(PluginContractModel):
275
+ rejection_format: Literal["ksadk.bridge-rejection/v1"] = "ksadk.bridge-rejection/v1"
276
+ action: BridgeAction
277
+ code: Literal[
278
+ "ambiguous_manifest",
279
+ "permissions_undeclared",
280
+ "host_unavailable",
281
+ "host_incompatible",
282
+ "digest_mismatch",
283
+ "unsupported",
284
+ ]
285
+ retryable: bool
286
+ message: str = Field(min_length=1, max_length=1024)
287
+ host: BridgeHostObservation | None = None
288
+
289
+ @model_validator(mode="after")
290
+ def validate_host_rejection(self) -> "BridgeRejection":
291
+ if self.code in {"host_unavailable", "host_incompatible"} and self.host is None:
292
+ raise ValueError("host rejection requires a typed host observation")
293
+ if self.code == "host_unavailable" and self.host is not None and self.host.available:
294
+ raise ValueError("host_unavailable cannot claim that the host is available")
295
+ return self
296
+
297
+
298
+ class BridgeProbeResult(PluginContractModel):
299
+ result_format: Literal["ksadk.bridge-probe-result/v1"] = "ksadk.bridge-probe-result/v1"
300
+ candidates: tuple[PluginManifestCandidate, ...] = ()
301
+ selection_required: bool
302
+ selected_manifest_ref: str | None = Field(default=None, min_length=4, max_length=4096)
303
+ rejection: BridgeRejection | None = None
304
+
305
+ @field_validator("selected_manifest_ref")
306
+ @classmethod
307
+ def validate_selected_manifest_ref(cls, value: str | None) -> str | None:
308
+ if value is not None:
309
+ return _validate_ref(value, field="selectedManifestRef")
310
+ return value
311
+
312
+ @model_validator(mode="after")
313
+ def validate_candidates(self) -> "BridgeProbeResult":
314
+ refs = [item.manifest_ref for item in self.candidates]
315
+ if len(refs) != len(set(refs)):
316
+ raise ValueError("probe candidates must have unique manifestRef values")
317
+ if not refs:
318
+ if self.rejection is None or self.rejection.action != "probe":
319
+ raise ValueError("empty probe requires a typed probe rejection")
320
+ if self.selection_required or self.selected_manifest_ref is not None:
321
+ raise ValueError("rejected probe cannot claim a manifest selection")
322
+ return self
323
+ if self.rejection is not None:
324
+ raise ValueError("successful probe candidates cannot carry a rejection")
325
+ if self.selection_required and self.selected_manifest_ref is not None:
326
+ raise ValueError("selectionRequired cannot also claim a selected manifest")
327
+ if not self.selection_required:
328
+ if self.selected_manifest_ref is None:
329
+ raise ValueError("a completed probe requires selectedManifestRef")
330
+ if self.selected_manifest_ref not in refs:
331
+ raise ValueError("selectedManifestRef must identify a probe candidate")
332
+ return self
333
+
334
+
335
+ class BridgeProbeExchange(PluginContractModel):
336
+ fixture_kind: Literal["probe"] = "probe"
337
+ request: BridgeProbeRequest
338
+ result: BridgeProbeResult
339
+
340
+ @model_validator(mode="after")
341
+ def validate_explicit_selection(self) -> "BridgeProbeExchange":
342
+ candidate_refs = {item.manifest_ref for item in self.result.candidates}
343
+ if not candidate_refs:
344
+ return self
345
+ selected = self.request.selected_manifest_ref
346
+ if len(candidate_refs) > 1 and selected is None:
347
+ if not self.result.selection_required or self.result.selected_manifest_ref is not None:
348
+ raise ValueError("multiple manifests require explicit selection")
349
+ else:
350
+ if selected is None:
351
+ selected = next(iter(candidate_refs))
352
+ if selected not in candidate_refs:
353
+ raise ValueError("requested manifest selection was not detected")
354
+ if self.result.selection_required or self.result.selected_manifest_ref != selected:
355
+ raise ValueError("probe result must preserve the explicit manifest selection")
356
+ return self
357
+
358
+
359
+ class EcosystemPluginDescriptor(PluginContractModel):
360
+ descriptor_format: Literal["ksadk.ecosystem-plugin-descriptor/v1"] = (
361
+ "ksadk.ecosystem-plugin-descriptor/v1"
362
+ )
363
+ ecosystem: PluginEcosystem
364
+ plugin_id: str = Field(min_length=2, max_length=256)
365
+ plugin_version: str | None = None
366
+ integration_mode: PluginIntegrationMode
367
+ maturity: PluginSupportMaturity
368
+ source_ref: str = Field(min_length=4, max_length=4096)
369
+ artifact_digest: str
370
+ manifest_ref: str = Field(min_length=4, max_length=4096)
371
+ manifest_digest: str
372
+ host_requirement: BridgeHostRequirement | None
373
+ permissions_declared: bool
374
+ install_permissions: tuple[str, ...] = ()
375
+ runtime_permissions: tuple[str, ...] = ()
376
+ auth_scopes: tuple[str, ...] = ()
377
+ secret_refs: tuple[str, ...] = ()
378
+ components: tuple[str, ...] = ()
379
+
380
+ @field_validator("plugin_id")
381
+ @classmethod
382
+ def validate_plugin_id(cls, value: str) -> str:
383
+ return _validate_id(value, field="pluginId")
384
+
385
+ @field_validator("plugin_version")
386
+ @classmethod
387
+ def validate_plugin_version(cls, value: str | None) -> str | None:
388
+ if value is not None:
389
+ return _validate_semver(value, field="plugin version")
390
+ return value
391
+
392
+ @field_validator("source_ref", "manifest_ref")
393
+ @classmethod
394
+ def validate_descriptor_ref(cls, value: str) -> str:
395
+ return _validate_ref(value, field="descriptor reference")
396
+
397
+ @field_validator("artifact_digest", "manifest_digest")
398
+ @classmethod
399
+ def validate_descriptor_digest(cls, value: str) -> str:
400
+ return _validate_digest(value)
401
+
402
+ @field_validator("install_permissions", "runtime_permissions", "auth_scopes", "components")
403
+ @classmethod
404
+ def validate_unique_values(cls, value: tuple[str, ...]) -> tuple[str, ...]:
405
+ return _unique(value, field="descriptor list")
406
+
407
+ @field_validator("secret_refs")
408
+ @classmethod
409
+ def validate_secret_refs(cls, value: tuple[str, ...]) -> tuple[str, ...]:
410
+ _unique(value, field="secretRefs")
411
+ if any(not _SECRET_REF.fullmatch(item) for item in value):
412
+ raise ValueError("secretRefs may contain references only")
413
+ return value
414
+
415
+ @model_validator(mode="after")
416
+ def validate_external_shape(self) -> "EcosystemPluginDescriptor":
417
+ if self.integration_mode != "native" and self.host_requirement is None:
418
+ raise ValueError("bridged and linked plugins require an external host")
419
+ if self.integration_mode == "native" and self.host_requirement is not None:
420
+ raise ValueError("native plugins cannot require an external host")
421
+ return self
422
+
423
+
424
+ class BridgeInspectRequest(PluginContractModel):
425
+ request_format: Literal["ksadk.bridge-inspect/v1"] = "ksadk.bridge-inspect/v1"
426
+ bridge_id: str = Field(min_length=3, max_length=128)
427
+ source_ref: str = Field(min_length=4, max_length=4096)
428
+ source_digest: str
429
+ candidate: PluginManifestCandidate
430
+
431
+ @field_validator("bridge_id")
432
+ @classmethod
433
+ def validate_bridge_id(cls, value: str) -> str:
434
+ return _validate_id(value, field="bridgeId")
435
+
436
+ @field_validator("source_ref")
437
+ @classmethod
438
+ def validate_source_ref(cls, value: str) -> str:
439
+ return _validate_ref(value, field="sourceRef")
440
+
441
+ @field_validator("source_digest")
442
+ @classmethod
443
+ def validate_source_digest(cls, value: str) -> str:
444
+ return _validate_digest(value)
445
+
446
+
447
+ class BridgeInspectResult(PluginContractModel):
448
+ result_format: Literal["ksadk.bridge-inspect-result/v1"] = "ksadk.bridge-inspect-result/v1"
449
+ status: Literal["accepted", "rejected"]
450
+ descriptor: EcosystemPluginDescriptor | None = None
451
+ rejection: BridgeRejection | None = None
452
+
453
+ @model_validator(mode="after")
454
+ def validate_outcome(self) -> "BridgeInspectResult":
455
+ if self.status == "accepted" and (self.descriptor is None or self.rejection is not None):
456
+ raise ValueError("accepted inspection requires descriptor only")
457
+ if self.status == "rejected" and (self.rejection is None or self.descriptor is not None):
458
+ raise ValueError("rejected inspection requires rejection only")
459
+ return self
460
+
461
+
462
+ class BridgeInspectExchange(PluginContractModel):
463
+ fixture_kind: Literal["rejection"] = "rejection"
464
+ request: BridgeInspectRequest
465
+ result: BridgeInspectResult
466
+
467
+
468
+ class BridgePlanRequest(PluginContractModel):
469
+ request_format: Literal["ksadk.bridge-plan/v1"] = "ksadk.bridge-plan/v1"
470
+ descriptor: EcosystemPluginDescriptor
471
+ operation: Literal["install", "update", "enable", "disable", "uninstall"]
472
+ desired_state: PluginDesiredState
473
+ bound_references: tuple[str, ...] = ()
474
+ authorization_ref: str = Field(min_length=4, max_length=2048)
475
+ accept_undeclared_permissions: bool = False
476
+
477
+ @field_validator("bound_references")
478
+ @classmethod
479
+ def validate_bound_references(cls, value: tuple[str, ...]) -> tuple[str, ...]:
480
+ return _unique(value, field="boundReferences")
481
+
482
+ @field_validator("authorization_ref")
483
+ @classmethod
484
+ def validate_authorization_ref(cls, value: str) -> str:
485
+ return _validate_ref(value, field="authorizationRef")
486
+
487
+ @model_validator(mode="after")
488
+ def validate_admission(self) -> "BridgePlanRequest":
489
+ if self.descriptor.plugin_version is None:
490
+ raise ValueError("planning requires an exact inspected plugin version")
491
+ permissions_undeclared = (
492
+ self.descriptor.integration_mode != "native"
493
+ and not self.descriptor.permissions_declared
494
+ )
495
+ if permissions_undeclared and not self.accept_undeclared_permissions:
496
+ raise ValueError(
497
+ "external plugin permissions are undeclared; explicit risk acceptance is required"
498
+ )
499
+ if permissions_undeclared and (
500
+ not self.descriptor.install_permissions
501
+ or "process:host-user" not in self.descriptor.runtime_permissions
502
+ ):
503
+ raise ValueError(
504
+ "undeclared external permissions require conservative install permissions "
505
+ "and process:host-user runtime disclosure"
506
+ )
507
+ return self
508
+
509
+
510
+ class BridgeTransitionPlan(PluginContractModel):
511
+ plan_format: Literal["ksadk.bridge-transition-plan/v1"] = "ksadk.bridge-transition-plan/v1"
512
+ plan_id: str = Field(min_length=1, max_length=256)
513
+ bridge_id: str = Field(min_length=3, max_length=128)
514
+ bridge_version: str
515
+ bridge_digest: str
516
+ ecosystem: PluginEcosystem
517
+ plugin_id: str = Field(min_length=2, max_length=256)
518
+ plugin_version: str
519
+ integration_mode: PluginIntegrationMode
520
+ operation: Literal["install", "update", "enable", "disable", "uninstall"]
521
+ desired_state: PluginDesiredState
522
+ descriptor_digest: str
523
+ artifact_digest: str
524
+ manifest_digest: str
525
+ install_permissions: tuple[str, ...] = ()
526
+ runtime_permissions: tuple[str, ...] = ()
527
+ auth_scopes: tuple[str, ...] = ()
528
+ authorization_ref: str = Field(min_length=4, max_length=2048)
529
+ permissions_declared: bool
530
+ undeclared_permissions_accepted: bool = False
531
+ bound_references: tuple[str, ...] = ()
532
+ host_requirement: BridgeHostRequirement | None
533
+ rollback_point_ref: str | None = Field(default=None, min_length=4, max_length=2048)
534
+ rollback_point_digest: str | None = None
535
+ plan_digest: str
536
+ created_at: AwareDatetime
537
+
538
+ @field_validator("bridge_id", "plugin_id")
539
+ @classmethod
540
+ def validate_ids(cls, value: str) -> str:
541
+ return _validate_id(value, field="plan id")
542
+
543
+ @field_validator("bridge_version", "plugin_version")
544
+ @classmethod
545
+ def validate_versions(cls, value: str) -> str:
546
+ return _validate_semver(value, field="plan version")
547
+
548
+ @field_validator(
549
+ "bridge_digest",
550
+ "descriptor_digest",
551
+ "artifact_digest",
552
+ "manifest_digest",
553
+ "rollback_point_digest",
554
+ "plan_digest",
555
+ )
556
+ @classmethod
557
+ def validate_digests(cls, value: str | None) -> str | None:
558
+ if value is not None:
559
+ return _validate_digest(value)
560
+ return value
561
+
562
+ @field_validator("authorization_ref", "rollback_point_ref")
563
+ @classmethod
564
+ def validate_plan_refs(cls, value: str | None) -> str | None:
565
+ if value is not None:
566
+ return _validate_ref(value, field="plan reference")
567
+ return value
568
+
569
+ @field_validator(
570
+ "install_permissions", "runtime_permissions", "auth_scopes", "bound_references"
571
+ )
572
+ @classmethod
573
+ def validate_plan_lists(cls, value: tuple[str, ...]) -> tuple[str, ...]:
574
+ return _unique(value, field="plan list")
575
+
576
+ @model_validator(mode="after")
577
+ def validate_rollback_pair(self) -> "BridgeTransitionPlan":
578
+ if (self.rollback_point_ref is None) != (self.rollback_point_digest is None):
579
+ raise ValueError("rollback point reference and digest must appear together")
580
+ if self.integration_mode != "native" and self.host_requirement is None:
581
+ raise ValueError("external transition plans require a host")
582
+ if self.permissions_declared and self.undeclared_permissions_accepted:
583
+ raise ValueError(
584
+ "undeclaredPermissionsAccepted must be false when permissions are declared"
585
+ )
586
+ if (
587
+ self.integration_mode != "native"
588
+ and not self.permissions_declared
589
+ and not self.undeclared_permissions_accepted
590
+ ):
591
+ raise ValueError("external undeclared permissions require recorded risk acceptance")
592
+ return self
593
+
594
+
595
+ class BridgePlanResult(PluginContractModel):
596
+ result_format: Literal["ksadk.bridge-plan-result/v1"] = "ksadk.bridge-plan-result/v1"
597
+ plan: BridgeTransitionPlan
598
+
599
+
600
+ class BridgeStageRequest(PluginContractModel):
601
+ request_format: Literal["ksadk.bridge-stage/v1"] = "ksadk.bridge-stage/v1"
602
+ plan: BridgeTransitionPlan
603
+ expected_plan_digest: str
604
+
605
+ @field_validator("expected_plan_digest")
606
+ @classmethod
607
+ def validate_expected_plan_digest(cls, value: str) -> str:
608
+ return _validate_digest(value)
609
+
610
+ @model_validator(mode="after")
611
+ def validate_plan_digest(self) -> "BridgeStageRequest":
612
+ if self.expected_plan_digest != self.plan.plan_digest:
613
+ raise ValueError("expectedPlanDigest does not match the immutable plan")
614
+ return self
615
+
616
+
617
+ class BridgeStageResult(PluginContractModel):
618
+ result_format: Literal["ksadk.bridge-stage-result/v1"] = "ksadk.bridge-stage-result/v1"
619
+ stage_id: str = Field(min_length=1, max_length=256)
620
+ plan_id: str = Field(min_length=1, max_length=256)
621
+ plan_digest: str
622
+ bridge_version: str
623
+ bridge_digest: str
624
+ host: BridgeHostObservation
625
+ artifact_digest: str
626
+ manifest_digest: str
627
+ native_stage_ref: str = Field(min_length=4, max_length=2048)
628
+ native_stage_digest: str
629
+ staged_at: AwareDatetime
630
+
631
+ @field_validator(
632
+ "plan_digest", "bridge_digest", "artifact_digest", "manifest_digest", "native_stage_digest"
633
+ )
634
+ @classmethod
635
+ def validate_stage_digest(cls, value: str) -> str:
636
+ return _validate_digest(value)
637
+
638
+ @field_validator("bridge_version")
639
+ @classmethod
640
+ def validate_bridge_version(cls, value: str) -> str:
641
+ return _validate_semver(value, field="bridge version")
642
+
643
+ @field_validator("native_stage_ref")
644
+ @classmethod
645
+ def validate_native_stage_ref(cls, value: str) -> str:
646
+ return _validate_ref(value, field="nativeStageRef")
647
+
648
+ @model_validator(mode="after")
649
+ def validate_host_available(self) -> "BridgeStageResult":
650
+ if not self.host.available:
651
+ raise ValueError("successful stage result requires an available host")
652
+ return self
653
+
654
+
655
+ class BridgeCommitRequest(PluginContractModel):
656
+ request_format: Literal["ksadk.bridge-commit/v1"] = "ksadk.bridge-commit/v1"
657
+ stage_id: str = Field(min_length=1, max_length=256)
658
+ plan_id: str = Field(min_length=1, max_length=256)
659
+ plan_digest: str
660
+ native_stage_ref: str = Field(min_length=4, max_length=2048)
661
+ native_stage_digest: str
662
+ idempotency_key: str = Field(min_length=8, max_length=256)
663
+
664
+ @field_validator("plan_digest", "native_stage_digest")
665
+ @classmethod
666
+ def validate_commit_digest(cls, value: str) -> str:
667
+ return _validate_digest(value)
668
+
669
+ @field_validator("native_stage_ref")
670
+ @classmethod
671
+ def validate_native_stage_ref(cls, value: str) -> str:
672
+ return _validate_ref(value, field="nativeStageRef")
673
+
674
+
675
+ class EcosystemInstallReceipt(PluginContractModel):
676
+ receipt_format: Literal["ksadk.ecosystem-install-receipt/v1"] = (
677
+ "ksadk.ecosystem-install-receipt/v1"
678
+ )
679
+ receipt_id: str = Field(min_length=1, max_length=256)
680
+ plan_id: str = Field(min_length=1, max_length=256)
681
+ plan_digest: str
682
+ stage_id: str = Field(min_length=1, max_length=256)
683
+ ecosystem: PluginEcosystem
684
+ plugin_id: str = Field(min_length=2, max_length=256)
685
+ plugin_version: str
686
+ integration_mode: PluginIntegrationMode
687
+ desired_state: PluginDesiredState
688
+ bridge_id: str = Field(min_length=3, max_length=128)
689
+ bridge_version: str
690
+ bridge_digest: str
691
+ host: BridgeHostObservation
692
+ artifact_digest: str
693
+ manifest_digest: str
694
+ native_receipt_ref: str = Field(min_length=4, max_length=2048)
695
+ native_receipt_digest: str
696
+ bound_references: tuple[str, ...] = ()
697
+ committed_at: AwareDatetime
698
+
699
+ @field_validator("plugin_id", "bridge_id")
700
+ @classmethod
701
+ def validate_receipt_ids(cls, value: str) -> str:
702
+ return _validate_id(value, field="receipt id")
703
+
704
+ @field_validator("plugin_version", "bridge_version")
705
+ @classmethod
706
+ def validate_receipt_versions(cls, value: str) -> str:
707
+ return _validate_semver(value, field="receipt version")
708
+
709
+ @field_validator(
710
+ "plan_digest",
711
+ "bridge_digest",
712
+ "artifact_digest",
713
+ "manifest_digest",
714
+ "native_receipt_digest",
715
+ )
716
+ @classmethod
717
+ def validate_receipt_digests(cls, value: str) -> str:
718
+ return _validate_digest(value)
719
+
720
+ @field_validator("native_receipt_ref")
721
+ @classmethod
722
+ def validate_native_receipt_ref(cls, value: str) -> str:
723
+ return _validate_ref(value, field="nativeReceiptRef")
724
+
725
+ @field_validator("bound_references")
726
+ @classmethod
727
+ def validate_bound_references(cls, value: tuple[str, ...]) -> tuple[str, ...]:
728
+ return _unique(value, field="boundReferences")
729
+
730
+ @model_validator(mode="after")
731
+ def validate_host_available(self) -> "EcosystemInstallReceipt":
732
+ if self.integration_mode != "native" and not self.host.available:
733
+ raise ValueError("external install receipt requires an available native host")
734
+ return self
735
+
736
+
737
+ class BridgeCommitResult(PluginContractModel):
738
+ result_format: Literal["ksadk.bridge-commit-result/v1"] = "ksadk.bridge-commit-result/v1"
739
+ receipt: EcosystemInstallReceipt
740
+
741
+
742
+ class BridgeReconcileRequest(PluginContractModel):
743
+ request_format: Literal["ksadk.bridge-reconcile/v1"] = "ksadk.bridge-reconcile/v1"
744
+ receipt_id: str = Field(min_length=1, max_length=256)
745
+ native_receipt_ref: str = Field(min_length=4, max_length=2048)
746
+ native_receipt_digest: str
747
+
748
+ @field_validator("native_receipt_ref")
749
+ @classmethod
750
+ def validate_native_receipt_ref(cls, value: str) -> str:
751
+ return _validate_ref(value, field="nativeReceiptRef")
752
+
753
+ @field_validator("native_receipt_digest")
754
+ @classmethod
755
+ def validate_native_receipt_digest(cls, value: str) -> str:
756
+ return _validate_digest(value)
757
+
758
+
759
+ class EcosystemPluginInventory(PluginContractModel):
760
+ inventory_format: Literal["ksadk.ecosystem-inventory/v1"] = "ksadk.ecosystem-inventory/v1"
761
+ receipt_id: str = Field(min_length=1, max_length=256)
762
+ ecosystem: PluginEcosystem
763
+ plugin_id: str = Field(min_length=2, max_length=256)
764
+ plugin_version: str
765
+ integration_mode: PluginIntegrationMode
766
+ desired_state: PluginDesiredState
767
+ observed_state: PluginObservedState
768
+ maturity: PluginSupportMaturity
769
+ bridge_id: str = Field(min_length=3, max_length=128)
770
+ bridge_version: str
771
+ bridge_digest: str
772
+ host: BridgeHostObservation | None
773
+ artifact_digest: str
774
+ manifest_digest: str
775
+ native_receipt_ref: str = Field(min_length=4, max_length=2048)
776
+ native_receipt_digest: str
777
+ bound_references: tuple[str, ...] = ()
778
+ reason_code: str | None = Field(default=None, max_length=128)
779
+ reconciled_at: AwareDatetime
780
+
781
+ @field_validator("plugin_id", "bridge_id")
782
+ @classmethod
783
+ def validate_inventory_ids(cls, value: str) -> str:
784
+ return _validate_id(value, field="inventory id")
785
+
786
+ @field_validator("plugin_version", "bridge_version")
787
+ @classmethod
788
+ def validate_inventory_versions(cls, value: str) -> str:
789
+ return _validate_semver(value, field="inventory version")
790
+
791
+ @field_validator("bridge_digest", "artifact_digest", "manifest_digest", "native_receipt_digest")
792
+ @classmethod
793
+ def validate_inventory_digest(cls, value: str) -> str:
794
+ return _validate_digest(value)
795
+
796
+ @field_validator("native_receipt_ref")
797
+ @classmethod
798
+ def validate_native_receipt_ref(cls, value: str) -> str:
799
+ return _validate_ref(value, field="nativeReceiptRef")
800
+
801
+ @field_validator("bound_references")
802
+ @classmethod
803
+ def validate_bound_references(cls, value: tuple[str, ...]) -> tuple[str, ...]:
804
+ return _unique(value, field="boundReferences")
805
+
806
+ @model_validator(mode="after")
807
+ def validate_observed_truth(self) -> "EcosystemPluginInventory":
808
+ if self.integration_mode != "native" and self.host is None:
809
+ raise ValueError("external inventory requires a host observation")
810
+ if self.host is not None and not self.host.available and self.observed_state == "ready":
811
+ raise ValueError("unavailable host cannot be reconciled as ready")
812
+ if self.observed_state in {"degraded", "failed", "rejected"} and not self.reason_code:
813
+ raise ValueError("unhealthy inventory requires reasonCode")
814
+ return self
815
+
816
+
817
+ class BridgeReconcileResult(PluginContractModel):
818
+ result_format: Literal["ksadk.bridge-reconcile-result/v1"] = "ksadk.bridge-reconcile-result/v1"
819
+ inventory: EcosystemPluginInventory
820
+
821
+
822
+ class BridgeRollbackRequest(PluginContractModel):
823
+ request_format: Literal["ksadk.bridge-rollback/v1"] = "ksadk.bridge-rollback/v1"
824
+ receipt_id: str = Field(min_length=1, max_length=256)
825
+ rollback_point_ref: str = Field(min_length=4, max_length=2048)
826
+ rollback_point_digest: str
827
+ expected_native_receipt_digest: str
828
+
829
+ @field_validator("rollback_point_ref")
830
+ @classmethod
831
+ def validate_rollback_point_ref(cls, value: str) -> str:
832
+ return _validate_ref(value, field="rollbackPointRef")
833
+
834
+ @field_validator("rollback_point_digest", "expected_native_receipt_digest")
835
+ @classmethod
836
+ def validate_rollback_digest(cls, value: str) -> str:
837
+ return _validate_digest(value)
838
+
839
+
840
+ class BridgeRollbackResult(PluginContractModel):
841
+ result_format: Literal["ksadk.bridge-rollback-result/v1"] = "ksadk.bridge-rollback-result/v1"
842
+ receipt_id: str = Field(min_length=1, max_length=256)
843
+ state: Literal["rolled-back"]
844
+ native_receipt_ref: str = Field(min_length=4, max_length=2048)
845
+ native_receipt_digest: str
846
+ rolled_back_at: AwareDatetime
847
+
848
+ @field_validator("native_receipt_ref")
849
+ @classmethod
850
+ def validate_native_receipt_ref(cls, value: str) -> str:
851
+ return _validate_ref(value, field="nativeReceiptRef")
852
+
853
+ @field_validator("native_receipt_digest")
854
+ @classmethod
855
+ def validate_native_receipt_digest(cls, value: str) -> str:
856
+ return _validate_digest(value)
857
+
858
+
859
+ class BridgeDisposeRequest(PluginContractModel):
860
+ request_format: Literal["ksadk.bridge-dispose/v1"] = "ksadk.bridge-dispose/v1"
861
+ receipt_id: str = Field(min_length=1, max_length=256)
862
+ native_receipt_ref: str = Field(min_length=4, max_length=2048)
863
+ native_receipt_digest: str
864
+
865
+ @field_validator("native_receipt_ref")
866
+ @classmethod
867
+ def validate_native_receipt_ref(cls, value: str) -> str:
868
+ return _validate_ref(value, field="nativeReceiptRef")
869
+
870
+ @field_validator("native_receipt_digest")
871
+ @classmethod
872
+ def validate_native_receipt_digest(cls, value: str) -> str:
873
+ return _validate_digest(value)
874
+
875
+
876
+ class BridgeDisposeResult(PluginContractModel):
877
+ result_format: Literal["ksadk.bridge-dispose-result/v1"] = "ksadk.bridge-dispose-result/v1"
878
+ receipt_id: str = Field(min_length=1, max_length=256)
879
+ state: Literal["disposed"]
880
+ native_receipt_ref: str = Field(min_length=4, max_length=2048)
881
+ native_receipt_digest: str
882
+ disposed_at: AwareDatetime
883
+
884
+ @field_validator("native_receipt_ref")
885
+ @classmethod
886
+ def validate_native_receipt_ref(cls, value: str) -> str:
887
+ return _validate_ref(value, field="nativeReceiptRef")
888
+
889
+ @field_validator("native_receipt_digest")
890
+ @classmethod
891
+ def validate_native_receipt_digest(cls, value: str) -> str:
892
+ return _validate_digest(value)
893
+
894
+
895
+ class PluginEcosystemBridgeTranscript(PluginContractModel):
896
+ fixture_kind: Literal["lifecycle"] = "lifecycle"
897
+ contract_format: Literal["ksadk.plugin-ecosystem-bridge/v1"] = (
898
+ "ksadk.plugin-ecosystem-bridge/v1"
899
+ )
900
+ describe_request: BridgeDescribeRequest
901
+ describe_result: BridgeDescribeResult
902
+ probe: BridgeProbeExchange
903
+ inspect_request: BridgeInspectRequest
904
+ inspect_result: BridgeInspectResult
905
+ plan_request: BridgePlanRequest
906
+ plan_result: BridgePlanResult
907
+ stage_request: BridgeStageRequest
908
+ stage_result: BridgeStageResult
909
+ commit_request: BridgeCommitRequest
910
+ commit_result: BridgeCommitResult
911
+ reconcile_request: BridgeReconcileRequest
912
+ reconcile_result: BridgeReconcileResult
913
+ rollback_request: BridgeRollbackRequest
914
+ rollback_result: BridgeRollbackResult
915
+ dispose_request: BridgeDisposeRequest
916
+ dispose_result: BridgeDisposeResult
917
+
918
+ @model_validator(mode="after")
919
+ def validate_traceability(self) -> "PluginEcosystemBridgeTranscript":
920
+ bridge = self.describe_result.descriptor
921
+ descriptor = self.inspect_result.descriptor
922
+ if descriptor is None:
923
+ raise ValueError("lifecycle transcript requires an accepted inspection")
924
+ plan = self.plan_result.plan
925
+ receipt = self.commit_result.receipt
926
+ inventory = self.reconcile_result.inventory
927
+ if self.describe_request.ecosystem != bridge.ecosystem:
928
+ raise ValueError("describe result ecosystem does not match request")
929
+ if descriptor.ecosystem != bridge.ecosystem or plan.ecosystem != bridge.ecosystem:
930
+ raise ValueError("ecosystem identity must be preserved through planning")
931
+ if self.plan_request.descriptor != descriptor:
932
+ raise ValueError("plan request must preserve the inspected plugin descriptor")
933
+ if (plan.bridge_id, plan.bridge_version, plan.bridge_digest) != (
934
+ bridge.bridge_id,
935
+ bridge.bridge_version,
936
+ bridge.bridge_digest,
937
+ ):
938
+ raise ValueError("transition plan must pin the described bridge identity")
939
+ if descriptor.host_requirement != bridge.host_requirement:
940
+ raise ValueError("plugin descriptor must preserve the bridge host requirement")
941
+ if plan.host_requirement != bridge.host_requirement:
942
+ raise ValueError("transition plan must preserve the bridge host requirement")
943
+ if (
944
+ plan.permissions_declared != descriptor.permissions_declared
945
+ or plan.undeclared_permissions_accepted
946
+ != self.plan_request.accept_undeclared_permissions
947
+ ):
948
+ raise ValueError("transition plan must preserve permission disclosure and acceptance")
949
+ if (
950
+ plan.plugin_id,
951
+ plan.plugin_version,
952
+ plan.integration_mode,
953
+ plan.desired_state,
954
+ plan.bound_references,
955
+ ) != (
956
+ descriptor.plugin_id,
957
+ descriptor.plugin_version,
958
+ descriptor.integration_mode,
959
+ self.plan_request.desired_state,
960
+ self.plan_request.bound_references,
961
+ ):
962
+ raise ValueError("transition plan must preserve plugin identity and desired state")
963
+ expected_digests = (
964
+ descriptor.artifact_digest,
965
+ descriptor.manifest_digest,
966
+ )
967
+ observed_digest_pairs = (
968
+ (plan.artifact_digest, plan.manifest_digest),
969
+ (self.stage_result.artifact_digest, self.stage_result.manifest_digest),
970
+ (receipt.artifact_digest, receipt.manifest_digest),
971
+ (inventory.artifact_digest, inventory.manifest_digest),
972
+ )
973
+ if any(pair != expected_digests for pair in observed_digest_pairs):
974
+ raise ValueError("artifact and manifest digests must remain traceable")
975
+ if (
976
+ self.stage_result.plan_id != plan.plan_id
977
+ or self.stage_result.plan_digest != plan.plan_digest
978
+ ):
979
+ raise ValueError("stage result must trace to the immutable transition plan")
980
+ if self.commit_request.stage_id != self.stage_result.stage_id:
981
+ raise ValueError("commit request must trace to the staged transition")
982
+ if receipt.plan_id != plan.plan_id or receipt.stage_id != self.stage_result.stage_id:
983
+ raise ValueError("install receipt must trace to plan and stage")
984
+ if self.reconcile_request.receipt_id != receipt.receipt_id:
985
+ raise ValueError("reconcile request must trace to the install receipt")
986
+ if inventory.receipt_id != receipt.receipt_id:
987
+ raise ValueError("inventory must trace to the install receipt")
988
+ host_observations = (self.stage_result.host, receipt.host, inventory.host)
989
+ if inventory.host is None or any(
990
+ item != self.stage_result.host for item in host_observations
991
+ ):
992
+ raise ValueError("native host version, protocol, and digest must remain traceable")
993
+ if self.rollback_request.receipt_id != receipt.receipt_id:
994
+ raise ValueError("rollback request must trace to the install receipt")
995
+ if self.dispose_request.receipt_id != receipt.receipt_id:
996
+ raise ValueError("dispose request must trace to the install receipt")
997
+ native_digests = {
998
+ receipt.native_receipt_digest,
999
+ self.reconcile_request.native_receipt_digest,
1000
+ inventory.native_receipt_digest,
1001
+ self.rollback_request.expected_native_receipt_digest,
1002
+ }
1003
+ if len(native_digests) != 1:
1004
+ raise ValueError("native host receipt digest must remain traceable")
1005
+ if (
1006
+ self.dispose_request.native_receipt_ref != self.rollback_result.native_receipt_ref
1007
+ or self.dispose_request.native_receipt_digest
1008
+ != self.rollback_result.native_receipt_digest
1009
+ ):
1010
+ raise ValueError("dispose request must consume the rollback receipt")
1011
+ if (
1012
+ self.dispose_result.native_receipt_ref != self.dispose_request.native_receipt_ref
1013
+ or self.dispose_result.native_receipt_digest
1014
+ != self.dispose_request.native_receipt_digest
1015
+ ):
1016
+ raise ValueError("dispose result must preserve the disposed native receipt")
1017
+ return self
1018
+
1019
+
1020
+ BridgeFixturePayload = Annotated[
1021
+ PluginEcosystemBridgeTranscript | BridgeProbeExchange | BridgeInspectExchange,
1022
+ Field(discriminator="fixture_kind"),
1023
+ ]
1024
+
1025
+
1026
+ class PluginEcosystemBridgeFixture(RootModel[BridgeFixturePayload]):
1027
+ """Schema root shared by lifecycle, ambiguous-manifest and rejection goldens."""
1028
+
1029
+ model_config = ConfigDict(frozen=True)
1030
+
1031
+
1032
+ def ecosystem_bridge_json_schema() -> dict[str, object]:
1033
+ """Return the canonical JSON Schema for all v1 bridge conformance fixtures."""
1034
+
1035
+ schema = cast(dict[str, object], PluginEcosystemBridgeFixture.model_json_schema(by_alias=True))
1036
+ schema["$schema"] = "https://json-schema.org/draft/2020-12/schema"
1037
+ schema["$id"] = "https://ksadk.local/contracts/plugin/v1/plugin-ecosystem-bridge.schema.json"
1038
+ schema["title"] = "PluginEcosystemBridge/v1 conformance fixtures"
1039
+ return schema
1040
+
1041
+
1042
+ @runtime_checkable
1043
+ class PluginEcosystemBridge(Protocol):
1044
+ """Execution-neutral bridge SPI; implementations live outside this contract."""
1045
+
1046
+ async def describe(self, request: BridgeDescribeRequest) -> BridgeDescribeResult: ...
1047
+
1048
+ async def probe(self, request: BridgeProbeRequest) -> BridgeProbeResult: ...
1049
+
1050
+ async def inspect(self, request: BridgeInspectRequest) -> BridgeInspectResult: ...
1051
+
1052
+ async def plan(self, request: BridgePlanRequest) -> BridgePlanResult: ...
1053
+
1054
+ async def stage(self, request: BridgeStageRequest) -> BridgeStageResult: ...
1055
+
1056
+ async def commit(self, request: BridgeCommitRequest) -> BridgeCommitResult: ...
1057
+
1058
+ async def reconcile(self, request: BridgeReconcileRequest) -> BridgeReconcileResult: ...
1059
+
1060
+ async def rollback(self, request: BridgeRollbackRequest) -> BridgeRollbackResult: ...
1061
+
1062
+ async def dispose(self, request: BridgeDisposeRequest) -> BridgeDisposeResult: ...
1063
+
1064
+
1065
+ __all__ = [
1066
+ "BridgeAction",
1067
+ "BridgeCommitRequest",
1068
+ "BridgeCommitResult",
1069
+ "BridgeDescribeRequest",
1070
+ "BridgeDescribeResult",
1071
+ "BridgeDescriptor",
1072
+ "BridgeDisposeRequest",
1073
+ "BridgeDisposeResult",
1074
+ "BridgeHostObservation",
1075
+ "BridgeHostRequirement",
1076
+ "BridgeInspectExchange",
1077
+ "BridgeInspectRequest",
1078
+ "BridgeInspectResult",
1079
+ "BridgePlanRequest",
1080
+ "BridgePlanResult",
1081
+ "BridgeProbeExchange",
1082
+ "BridgeProbeRequest",
1083
+ "BridgeProbeResult",
1084
+ "BridgeReconcileRequest",
1085
+ "BridgeReconcileResult",
1086
+ "BridgeRejection",
1087
+ "BridgeRollbackRequest",
1088
+ "BridgeRollbackResult",
1089
+ "BridgeStageRequest",
1090
+ "BridgeStageResult",
1091
+ "BridgeTransitionPlan",
1092
+ "EcosystemInstallReceipt",
1093
+ "EcosystemPluginDescriptor",
1094
+ "EcosystemPluginInventory",
1095
+ "PluginDesiredState",
1096
+ "PluginEcosystem",
1097
+ "PluginEcosystemBridge",
1098
+ "PluginEcosystemBridgeFixture",
1099
+ "PluginEcosystemBridgeTranscript",
1100
+ "PluginIntegrationMode",
1101
+ "PluginManifestCandidate",
1102
+ "PluginObservedState",
1103
+ "PluginSupportMaturity",
1104
+ "ecosystem_bridge_json_schema",
1105
+ ]