mainsequence 3.19.2__tar.gz → 3.19.5__tar.gz

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 (186) hide show
  1. {mainsequence-3.19.2 → mainsequence-3.19.5}/PKG-INFO +4 -2
  2. {mainsequence-3.19.2 → mainsequence-3.19.5}/README.md +3 -1
  3. {mainsequence-3.19.2 → mainsequence-3.19.5}/agent_scaffold/AGENTS.md +2 -2
  4. {mainsequence-3.19.2 → mainsequence-3.19.5}/agent_scaffold/skills/command_center/workspace_builder/SKILL.md +366 -45
  5. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/cli/api.py +64 -9
  6. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/cli/cli.py +91 -117
  7. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/cli/local_ops.py +6 -12
  8. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/client/command_center/workspace.py +1 -1
  9. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/client/models_helpers.py +1 -1
  10. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/client/models_tdag.py +50 -18
  11. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence.egg-info/PKG-INFO +4 -2
  12. {mainsequence-3.19.2 → mainsequence-3.19.5}/pyproject.toml +1 -1
  13. {mainsequence-3.19.2 → mainsequence-3.19.5}/tests/test_cli.py +135 -16
  14. {mainsequence-3.19.2 → mainsequence-3.19.5}/tests/test_project_batch_jobs_from_file.py +43 -0
  15. {mainsequence-3.19.2 → mainsequence-3.19.5}/LICENSE +0 -0
  16. {mainsequence-3.19.2 → mainsequence-3.19.5}/agent_scaffold/skills/a2a_communication/SKILL.md +0 -0
  17. {mainsequence-3.19.2 → mainsequence-3.19.5}/agent_scaffold/skills/application_surfaces/api_surfaces/SKILL.md +0 -0
  18. {mainsequence-3.19.2 → mainsequence-3.19.5}/agent_scaffold/skills/command_center/adapter_from_api/SKILL.md +0 -0
  19. {mainsequence-3.19.2 → mainsequence-3.19.5}/agent_scaffold/skills/command_center/api_mock_prototyping/SKILL.md +0 -0
  20. {mainsequence-3.19.2 → mainsequence-3.19.5}/agent_scaffold/skills/command_center/app_components/SKILL.md +0 -0
  21. {mainsequence-3.19.2 → mainsequence-3.19.5}/agent_scaffold/skills/command_center/connections/SKILL.md +0 -0
  22. {mainsequence-3.19.2 → mainsequence-3.19.5}/agent_scaffold/skills/command_center/workspace_analysis/SKILL.md +0 -0
  23. {mainsequence-3.19.2 → mainsequence-3.19.5}/agent_scaffold/skills/command_center/workspace_design/SKILL.md +0 -0
  24. {mainsequence-3.19.2 → mainsequence-3.19.5}/agent_scaffold/skills/dashboards/streamlit/SKILL.md +0 -0
  25. {mainsequence-3.19.2 → mainsequence-3.19.5}/agent_scaffold/skills/data_access/exploration/SKILL.md +0 -0
  26. {mainsequence-3.19.2 → mainsequence-3.19.5}/agent_scaffold/skills/data_publishing/data_nodes/SKILL.md +0 -0
  27. {mainsequence-3.19.2 → mainsequence-3.19.5}/agent_scaffold/skills/data_publishing/simple_tables/SKILL.md +0 -0
  28. {mainsequence-3.19.2 → mainsequence-3.19.5}/agent_scaffold/skills/maintenance/bug_auditor/SKILL.md +0 -0
  29. {mainsequence-3.19.2 → mainsequence-3.19.5}/agent_scaffold/skills/maintenance/local_journal/SKILL.md +0 -0
  30. {mainsequence-3.19.2 → mainsequence-3.19.5}/agent_scaffold/skills/markets_platform/assets_and_translation/SKILL.md +0 -0
  31. {mainsequence-3.19.2 → mainsequence-3.19.5}/agent_scaffold/skills/markets_platform/instruments_and_pricing/SKILL.md +0 -0
  32. {mainsequence-3.19.2 → mainsequence-3.19.5}/agent_scaffold/skills/markets_platform/virtualfundbuilder/SKILL.md +0 -0
  33. {mainsequence-3.19.2 → mainsequence-3.19.5}/agent_scaffold/skills/platform_operations/access_control_and_sharing/SKILL.md +0 -0
  34. {mainsequence-3.19.2 → mainsequence-3.19.5}/agent_scaffold/skills/platform_operations/orchestration_and_releases/SKILL.md +0 -0
  35. {mainsequence-3.19.2 → mainsequence-3.19.5}/agent_scaffold/skills/project_builder/SKILL.md +0 -0
  36. {mainsequence-3.19.2 → mainsequence-3.19.5}/agent_scaffold/skills/project_to_agent/SKILL.md +0 -0
  37. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/__init__.py +0 -0
  38. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/__main__.py +0 -0
  39. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/bootstrap.py +0 -0
  40. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/cli/__init__.py +0 -0
  41. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/cli/browser_auth.py +0 -0
  42. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/cli/config.py +0 -0
  43. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/cli/docker_utils.py +0 -0
  44. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/cli/doctor.py +0 -0
  45. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/cli/model_filters.py +0 -0
  46. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/cli/project_status.py +0 -0
  47. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/cli/pydantic_cli.py +0 -0
  48. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/cli/sdk_utils.py +0 -0
  49. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/cli/ssh_utils.py +0 -0
  50. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/cli/ui.py +0 -0
  51. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/client/__init__.py +0 -0
  52. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/client/agent_runtime_models.py +0 -0
  53. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/client/base.py +0 -0
  54. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/client/client.py +0 -0
  55. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/client/command_center/__init__.py +0 -0
  56. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/client/command_center/app_component.py +0 -0
  57. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/client/command_center/connections.py +0 -0
  58. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/client/command_center/data_models.py +0 -0
  59. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/client/command_center/workspace_snapshot.py +0 -0
  60. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/client/data_sources_interfaces/__init__.py +0 -0
  61. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/client/data_sources_interfaces/duckdb.py +0 -0
  62. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/client/data_sources_interfaces/timescale.py +0 -0
  63. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/client/exceptions.py +0 -0
  64. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/client/fastapi/__init__.py +0 -0
  65. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/client/fastapi/auth.py +0 -0
  66. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/client/models_simple_tables.py +0 -0
  67. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/client/models_user.py +0 -0
  68. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/client/models_vam.py +0 -0
  69. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/client/utils.py +0 -0
  70. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/compute_validation.py +0 -0
  71. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/dashboards/__init__.py +0 -0
  72. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/dashboards/streamlit/__init__.py +0 -0
  73. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/dashboards/streamlit/assets/config.toml +0 -0
  74. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/dashboards/streamlit/assets/favicon.png +0 -0
  75. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/dashboards/streamlit/assets/image_1_base64.txt +0 -0
  76. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/dashboards/streamlit/assets/image_2_base64.txt +0 -0
  77. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/dashboards/streamlit/assets/image_3_base64.txt +0 -0
  78. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/dashboards/streamlit/assets/image_4_base64.txt +0 -0
  79. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/dashboards/streamlit/assets/image_5_base64.txt +0 -0
  80. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/dashboards/streamlit/assets/logo.png +0 -0
  81. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/dashboards/streamlit/components/__init__.py +0 -0
  82. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/dashboards/streamlit/components/asset_select.py +0 -0
  83. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/dashboards/streamlit/components/date_settings.py +0 -0
  84. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/dashboards/streamlit/components/logged_user.py +0 -0
  85. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/dashboards/streamlit/core/__init__.py +0 -0
  86. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/dashboards/streamlit/core/theme.py +0 -0
  87. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/dashboards/streamlit/instruments/__init__.py +0 -0
  88. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/dashboards/streamlit/instruments/streamlit_form_factory.py +0 -0
  89. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/dashboards/streamlit/pages/__init__.py +0 -0
  90. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/dashboards/streamlit/scaffold.py +0 -0
  91. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/defaults.py +0 -0
  92. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/instrumentation/__init__.py +0 -0
  93. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/instrumentation/utils.py +0 -0
  94. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/instruments/__init__.py +0 -0
  95. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/instruments/data_interface/__init__.py +0 -0
  96. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/instruments/data_interface/data_interface.py +0 -0
  97. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/instruments/instruments/__init__.py +0 -0
  98. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/instruments/instruments/base_instrument.py +0 -0
  99. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/instruments/instruments/bond.py +0 -0
  100. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/instruments/instruments/callability.py +0 -0
  101. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/instruments/instruments/interest_rate_swap.py +0 -0
  102. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/instruments/instruments/json_codec.py +0 -0
  103. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/instruments/instruments/position.py +0 -0
  104. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/instruments/instruments/ql_fields.py +0 -0
  105. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/instruments/interest_rates/__init__.py +0 -0
  106. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/instruments/interest_rates/etl/__init__.py +0 -0
  107. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/instruments/interest_rates/etl/curve_codec.py +0 -0
  108. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/instruments/interest_rates/etl/nodes.py +0 -0
  109. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/instruments/interest_rates/etl/registry.py +0 -0
  110. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/instruments/pricing_models/__init__.py +0 -0
  111. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/instruments/pricing_models/bond_pricer.py +0 -0
  112. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/instruments/pricing_models/indices.py +0 -0
  113. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/instruments/pricing_models/indices_builders.py +0 -0
  114. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/instruments/pricing_models/swap_pricer.py +0 -0
  115. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/instruments/settings.py +0 -0
  116. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/instruments/utils.py +0 -0
  117. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/logconf.py +0 -0
  118. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/runtime_flags.py +0 -0
  119. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/tdag/__init__.py +0 -0
  120. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/tdag/__main__.py +0 -0
  121. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/tdag/base_persist_managers.py +0 -0
  122. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/tdag/config.py +0 -0
  123. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/tdag/configuration_models.py +0 -0
  124. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/tdag/data_nodes/__init__.py +0 -0
  125. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/tdag/data_nodes/build_operations.py +0 -0
  126. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/tdag/data_nodes/data_nodes.py +0 -0
  127. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/tdag/data_nodes/filters.py +0 -0
  128. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/tdag/data_nodes/models.py +0 -0
  129. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/tdag/data_nodes/namespacing.py +0 -0
  130. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/tdag/data_nodes/persist_managers.py +0 -0
  131. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/tdag/data_nodes/run_operations.py +0 -0
  132. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/tdag/data_nodes/utils.py +0 -0
  133. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/tdag/filters.py +0 -0
  134. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/tdag/future_registry.py +0 -0
  135. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/tdag/pydantic_metadata.py +0 -0
  136. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/tdag/simple_tables/__init__.py +0 -0
  137. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/tdag/simple_tables/filters.py +0 -0
  138. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/tdag/simple_tables/models.py +0 -0
  139. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/tdag/simple_tables/persist_managers.py +0 -0
  140. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/tdag/simple_tables/schema.py +0 -0
  141. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/tdag/simple_tables/table_nodes.py +0 -0
  142. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/tdag/utils.py +0 -0
  143. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/__init__.py +0 -0
  144. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/contrib/__init__.py +0 -0
  145. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/contrib/data_nodes/__init__.py +0 -0
  146. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/contrib/data_nodes/external_weights.py +0 -0
  147. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/contrib/data_nodes/intraday_trend.py +0 -0
  148. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/contrib/data_nodes/market_cap.py +0 -0
  149. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/contrib/data_nodes/mock_signal.py +0 -0
  150. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/contrib/data_nodes/portfolio_replicator.py +0 -0
  151. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/contrib/prices/__init__.py +0 -0
  152. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/contrib/prices/data_nodes.py +0 -0
  153. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/contrib/prices/utils.py +0 -0
  154. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/contrib/rebalance_strategies/__init__.py +0 -0
  155. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/contrib/rebalance_strategies/rebalance_strategies.py +0 -0
  156. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/enums.py +0 -0
  157. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/models.py +0 -0
  158. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/portfolio_nodes.py +0 -0
  159. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/resource_factory/__init__.py +0 -0
  160. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/resource_factory/rebalance_factory.py +0 -0
  161. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/resource_factory/signal_factory.py +0 -0
  162. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/utils.py +0 -0
  163. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence.egg-info/SOURCES.txt +0 -0
  164. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence.egg-info/dependency_links.txt +0 -0
  165. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence.egg-info/entry_points.txt +0 -0
  166. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence.egg-info/requires.txt +0 -0
  167. {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence.egg-info/top_level.txt +0 -0
  168. {mainsequence-3.19.2 → mainsequence-3.19.5}/setup.cfg +0 -0
  169. {mainsequence-3.19.2 → mainsequence-3.19.5}/tests/test_auth_precedence.py +0 -0
  170. {mainsequence-3.19.2 → mainsequence-3.19.5}/tests/test_build_operations_hashing.py +0 -0
  171. {mainsequence-3.19.2 → mainsequence-3.19.5}/tests/test_cli_browser_auth.py +0 -0
  172. {mainsequence-3.19.2 → mainsequence-3.19.5}/tests/test_client.py +0 -0
  173. {mainsequence-3.19.2 → mainsequence-3.19.5}/tests/test_command_center_app_component_models.py +0 -0
  174. {mainsequence-3.19.2 → mainsequence-3.19.5}/tests/test_command_center_data_models.py +0 -0
  175. {mainsequence-3.19.2 → mainsequence-3.19.5}/tests/test_command_center_models.py +0 -0
  176. {mainsequence-3.19.2 → mainsequence-3.19.5}/tests/test_dependency_extras.py +0 -0
  177. {mainsequence-3.19.2 → mainsequence-3.19.5}/tests/test_filter_normalization.py +0 -0
  178. {mainsequence-3.19.2 → mainsequence-3.19.5}/tests/test_instruments.py +0 -0
  179. {mainsequence-3.19.2 → mainsequence-3.19.5}/tests/test_logconf.py +0 -0
  180. {mainsequence-3.19.2 → mainsequence-3.19.5}/tests/test_logged_user_components.py +0 -0
  181. {mainsequence-3.19.2 → mainsequence-3.19.5}/tests/test_models_user_request_bound_auth.py +0 -0
  182. {mainsequence-3.19.2 → mainsequence-3.19.5}/tests/test_pod_project_resolution.py +0 -0
  183. {mainsequence-3.19.2 → mainsequence-3.19.5}/tests/test_run_configuration.py +0 -0
  184. {mainsequence-3.19.2 → mainsequence-3.19.5}/tests/test_simple_tables_configuration_hashing.py +0 -0
  185. {mainsequence-3.19.2 → mainsequence-3.19.5}/tests/test_simple_tables_persistence.py +0 -0
  186. {mainsequence-3.19.2 → mainsequence-3.19.5}/tests/test_workspace_snapshot.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mainsequence
3
- Version: 3.19.2
3
+ Version: 3.19.5
4
4
  Summary: Main Sequence SDK
5
5
  Author-email: Main Sequence GmbH <dev@main-sequence.io>
6
6
  License: MainSequence GmbH SDK License Agreement
@@ -89,7 +89,7 @@ Requires-Dist: playwright; extra == "workspace-snapshots"
89
89
  Dynamic: license-file
90
90
 
91
91
  <p align="center">
92
- <img src="https://main-sequence.app/static/media/logos/MS_logo_long_black.png" alt="Main Sequence Logo" width="500"/>
92
+ <img src="https://www.main-sequence.io/images/logos/MS_logo_long_black.png" alt="Main Sequence Logo" width="500"/>
93
93
  </p>
94
94
 
95
95
  # Main Sequence Python SDK
@@ -154,6 +154,7 @@ Recommended entry points:
154
154
  - [Working With Simple Tables](docs/tutorial/working_with_simple_tables.md)
155
155
  - [Create Your First API](docs/tutorial/create_your_first_api.md)
156
156
  - [Role-Based Access Control](docs/tutorial/role_based_access_control.md)
157
+ - [Turn Your Project Into an Agent](docs/tutorial/project_to_agent.md)
157
158
  - Knowledge:
158
159
  - [Data Nodes](docs/knowledge/data_nodes.md)
159
160
  - [Command Center](docs/knowledge/command_center/index.md)
@@ -209,6 +210,7 @@ From there, the normal learning path is:
209
210
  4. understand sharing and RBAC
210
211
  5. schedule jobs
211
212
  6. build dashboards or downstream consumers
213
+ 7. package the project as an agent-facing surface when the repository is ready
212
214
 
213
215
  ## Installation for development
214
216
 
@@ -1,5 +1,5 @@
1
1
  <p align="center">
2
- <img src="https://main-sequence.app/static/media/logos/MS_logo_long_black.png" alt="Main Sequence Logo" width="500"/>
2
+ <img src="https://www.main-sequence.io/images/logos/MS_logo_long_black.png" alt="Main Sequence Logo" width="500"/>
3
3
  </p>
4
4
 
5
5
  # Main Sequence Python SDK
@@ -64,6 +64,7 @@ Recommended entry points:
64
64
  - [Working With Simple Tables](docs/tutorial/working_with_simple_tables.md)
65
65
  - [Create Your First API](docs/tutorial/create_your_first_api.md)
66
66
  - [Role-Based Access Control](docs/tutorial/role_based_access_control.md)
67
+ - [Turn Your Project Into an Agent](docs/tutorial/project_to_agent.md)
67
68
  - Knowledge:
68
69
  - [Data Nodes](docs/knowledge/data_nodes.md)
69
70
  - [Command Center](docs/knowledge/command_center/index.md)
@@ -119,6 +120,7 @@ From there, the normal learning path is:
119
120
  4. understand sharing and RBAC
120
121
  5. schedule jobs
121
122
  6. build dashboards or downstream consumers
123
+ 7. package the project as an agent-facing surface when the repository is ready
122
124
 
123
125
  ## Installation for development
124
126
 
@@ -18,9 +18,9 @@ uses them to update only the Main Sequence section below.
18
18
  ## Main Sequence Instructions
19
19
 
20
20
  Before any non-trivial Main Sequence work, verify that this Main Sequence section matches the
21
- latest installed `agent_scaffold/AGENTS.md` template and that
21
+ latest installed `AGENTS.md` template and that
22
22
  `.agents/skills/mainsequence/project_builder/SKILL.md` matches the latest installed
23
- `agent_scaffold/skills/project_builder/SKILL.md`; if either local file does not match, update it
23
+ `.agents/skills/project_builder/SKILL.md`; if either local file does not match, update it
24
24
  before proceeding.
25
25
 
26
26
  Canonical Main Sequence documentation root:
@@ -69,25 +69,32 @@ This skill must not claim ownership of:
69
69
 
70
70
  0. If widget selection, layout narrative, or visualization strategy is not already decided, use:
71
71
  - `.agents/skills/mainsequence/command_center/workspace_design/SKILL.md`
72
- 1. Verify the widget catalog through the CLI:
72
+ 1. If the workspace may use connection-backed source widgets, inspect the available connections through the CLI first:
73
+ - `mainsequence cc connection list --json`
74
+ - identify the target connection instance `uid`
75
+ - `mainsequence cc connection detail <CONNECTION_UID> --json`
76
+ - `mainsequence cc connection_type list --json`
77
+ - identify the target connection `type_id`
78
+ - `mainsequence cc connection_type detail <TYPE_ID> --json`
79
+ 2. Verify the widget catalog through the CLI:
73
80
  - `mainsequence cc registered_widget_type list --json`
74
81
  - identify the target `widget_id`
75
82
  - `mainsequence cc registered_widget_type detail <WIDGET_ID> --json`
76
- 2. The SDK client models in `mainsequence/client/command_center/`:
83
+ 3. The SDK client models in `mainsequence/client/command_center/`:
77
84
  - `workspace.py`
78
85
  - `connections.py` when source widgets depend on backend-owned connections
79
86
  - `data_models.py`
80
87
  - `app_component.py` when the workspace contains AppComponent widgets or editable form payloads
81
- 3. `docs/knowledge/command_center/workspaces.md`
82
- 4. the local Main Sequence docs/models/examples in this repository that define the widget payloads being mounted
83
- 5. the current CLI docs if the task uses CLI workflow
88
+ 4. `docs/knowledge/command_center/workspaces.md`
89
+ 5. the local Main Sequence docs/models/examples in this repository that define the widget payloads being mounted
90
+ 6. the current CLI docs if the task uses CLI workflow
84
91
 
85
92
  If the workspace contains AppComponent widgets, also read:
86
93
 
87
- 6. `docs/knowledge/command_center/forms.md`
88
- 7. `docs/knowledge/command_center/widget_data_contracts.md`
89
- 8. `.agents/skills/mainsequence/platform_operations/orchestration_and_releases/SKILL.md` when mounted widgets depend on project APIs that must be usable from Command Center
90
- 9. `.agents/skills/mainsequence/command_center/api_mock_prototyping/SKILL.md` when the workspace should validate an AppComponent/API contract in `mock-json` mode before deployment
94
+ 7. `docs/knowledge/command_center/forms.md`
95
+ 8. `docs/knowledge/command_center/widget_data_contracts.md`
96
+ 9. `.agents/skills/mainsequence/platform_operations/orchestration_and_releases/SKILL.md` when mounted widgets depend on project APIs that must be usable from Command Center
97
+ 10. `.agents/skills/mainsequence/command_center/api_mock_prototyping/SKILL.md` when the workspace should validate an AppComponent/API contract in `mock-json` mode before deployment
91
98
 
92
99
  ## Command Center Mental Model
93
100
 
@@ -104,6 +111,92 @@ Think in terms of these objects:
104
111
  - saved widget or saved group:
105
112
  import-layer snapshot/template, not a live linked widget instance inside the workspace
106
113
 
114
+ ## Workspace JSON Model
115
+
116
+ Workspace JSON is the durable workspace definition. It is not a raw frontend state dump and it is
117
+ not a loaded runtime snapshot.
118
+
119
+ Portable export artifacts may use a wrapper:
120
+
121
+ ```json
122
+ {
123
+ "schema": "mainsequence.workspace",
124
+ "version": 1,
125
+ "exportedAt": "2026-05-07T00:00:00.000Z",
126
+ "workspace": {
127
+ "id": "workspace-example",
128
+ "title": "Example Workspace",
129
+ "description": "User-scoped workspace managed in Command Center.",
130
+ "type": "workspace",
131
+ "labels": [],
132
+ "category": "Custom",
133
+ "source": "user",
134
+ "layoutKind": "custom",
135
+ "grid": { "columns": 48, "rowHeight": 15, "gap": 8 },
136
+ "controls": {
137
+ "enabled": true,
138
+ "timeRange": {
139
+ "enabled": true,
140
+ "defaultRange": "24h",
141
+ "options": ["15m", "1h", "6h", "24h", "7d", "30d", "90d"]
142
+ },
143
+ "refresh": {
144
+ "enabled": true,
145
+ "defaultIntervalMs": 300000,
146
+ "intervals": [null, 30000, 60000, 300000, 600000, 3600000]
147
+ },
148
+ "actions": { "enabled": true, "share": false, "view": true }
149
+ },
150
+ "widgets": []
151
+ }
152
+ }
153
+ ```
154
+
155
+ Use the wrapper for portable artifacts. For direct workspace update commands, pass the writable
156
+ workspace payload shape expected by that command, not an arbitrary wrapper, unless the command
157
+ explicitly documents wrapper support.
158
+
159
+ Durable workspace JSON owns:
160
+
161
+ - workspace metadata, labels, category, source, layout kind, grid, and shared controls
162
+ - mounted widget instances and ordering
163
+ - widget `props`, `layout`, `position`, `bindings`, `managedBy`, `presentation`, and `row.children`
164
+ - connection/query configuration on source widgets when the source widget contract requires it
165
+
166
+ Durable workspace JSON does not own:
167
+
168
+ - current user-selected control values when the platform separates user state
169
+ - runtime/view state when the platform separates user state
170
+ - credentials, provider URLs, native socket details, or backend route fragments
171
+ - compiled or public runtime metadata generated by the platform
172
+
173
+ ## Widget Instance Shape
174
+
175
+ Each mounted widget instance should resolve to this shape:
176
+
177
+ ```json
178
+ {
179
+ "id": "unique-instance-id",
180
+ "widgetId": "registered-widget-type-id",
181
+ "title": "Optional title",
182
+ "props": {},
183
+ "bindings": {},
184
+ "layout": { "cols": 12, "rows": 8 },
185
+ "position": { "x": 0, "y": 0 }
186
+ }
187
+ ```
188
+
189
+ Important fields:
190
+
191
+ - `id`: unique mounted instance id inside the workspace
192
+ - `widgetId`: registered widget type id, not a saved-widget id and not a mounted instance id
193
+ - `props`: durable widget configuration
194
+ - `runtimeState`: optional current runtime/view state, not durable source configuration
195
+ - `bindings`: target-owned graph edges from this widget's input ports to upstream output ports
196
+ - `managedBy`: marks hidden managed source widgets
197
+ - `presentation`: placement, rail visibility, chrome, and exposed field behavior
198
+ - `row.children`: nested widgets inside a row/container widget
199
+
107
200
  ## Inputs This Skill Needs
108
201
 
109
202
  Before writing or mutating a workspace, collect or infer:
@@ -286,27 +379,133 @@ If the payload shape is not defined by those sources and cannot be verified, sto
286
379
 
287
380
  ### 3.1 Resolve connection-backed data before mounting consumers
288
381
 
289
- Before mounting table, chart, statistic, curve, or similar data consumers:
382
+ Connections are backend-owned data resources. Workspace consumers should not store connection
383
+ details directly unless their registered widget contract explicitly supports embedded managed source
384
+ props.
290
385
 
291
- 1. identify the source Connection Query widget
292
- 2. verify the selected connection instance exists and is usable
293
- 3. verify the connection type and `queryModelId`
294
- 4. verify the typed query payload
295
- 5. verify the published output contract
296
- 6. add a Tabular Transform widget if analytical reshaping is required
297
- 7. bind consumers to the source or transform `dataset` output
386
+ Prefer explicit source widgets:
298
387
 
299
- Do not store endpoint URLs, credentials, backend route fragments, provider ids, or mutable
300
- connection display labels as authoritative widget props.
388
+ - `connection-query` for request/response datasets
389
+ - `connection-stream-query` for streaming or incremental paths
390
+ - `tabular-transform` when analytical reshaping is needed before presentation
301
391
 
302
- Generic tabular consumers must receive `core.tabular_frame@v1`. If the upstream API or connection
303
- returns raw arrays, paginated JSON, nested provider payloads, or other ad hoc records, normalize
304
- through an Adapter from API connection first, then use an explicit transform when analytical
305
- reshaping is still required.
392
+ One source widget can feed several consumers. Reuse one source when the same query drives several
393
+ tables, charts, statistics, curves, or agent contexts.
306
394
 
307
- When a project API or AppComponent legitimately returns a full canonical frame, ground the contract
308
- against `mainsequence.client.command_center.data_models.TabularFrameResponse`. Source-specific
309
- runtime details belong in `source.context`, not top-level widget payload fields.
395
+ Before mounting table, chart, statistic, curve, or similar data consumers:
396
+
397
+ 1. identify the source widget
398
+ 2. verify the selected connection instance exists and is usable
399
+ 3. verify `connectionRef.id` is real and backend-owned
400
+ 4. verify `connectionRef.typeId` matches the connection type
401
+ 5. verify `queryModelId` matches `query.kind`
402
+ 6. verify the typed query payload matches the selected connection type and query model
403
+ 7. verify the published output contract
404
+ 8. add a Tabular Transform widget if analytical reshaping is required
405
+ 9. bind consumers to the source or transform output through target-owned `bindings`
406
+
407
+ Do not store credentials, provider URLs, native route fragments, backend route fragments, provider
408
+ ids, or mutable connection display labels as authoritative widget props.
409
+
410
+ Request/response source props:
411
+
412
+ ```json
413
+ {
414
+ "connectionRef": { "id": 123, "typeId": "mainsequence.simple-table" },
415
+ "queryModelId": "simple-table-sql",
416
+ "query": {
417
+ "kind": "simple-table-sql",
418
+ "sql": "select * from {{simple_table}} limit 500"
419
+ },
420
+ "timeRangeMode": "dashboard",
421
+ "variables": {},
422
+ "maxRows": 500
423
+ }
424
+ ```
425
+
426
+ Incremental request/response props:
427
+
428
+ ```json
429
+ {
430
+ "incrementalRefreshMode": "incremental",
431
+ "incrementalTimeField": "timestamp",
432
+ "incrementalMergeKeyFields": ["symbol", "timestamp"],
433
+ "incrementalOverlapMs": 60000,
434
+ "incrementalRetentionMs": 86400000,
435
+ "incrementalDedupePolicy": "latest"
436
+ }
437
+ ```
438
+
439
+ Stream source props:
440
+
441
+ ```json
442
+ {
443
+ "connectionRef": { "id": 123, "typeId": "binance.market-data" },
444
+ "queryModelId": "ticker-stream",
445
+ "query": {
446
+ "kind": "ticker-stream",
447
+ "symbols": ["BTCUSDT", "ETHUSDT"]
448
+ },
449
+ "timeRangeMode": "none",
450
+ "mergeKeyFields": ["symbol"],
451
+ "retentionMaxRows": 1000
452
+ }
453
+ ```
454
+
455
+ Connection source rules:
456
+
457
+ - use stream widgets only when the query model advertises stream support
458
+ - configure retention and merge keys explicitly when the consumer expects bounded live state
459
+ - incremental refresh requires a time-range-aware query model and stable time and identity columns
460
+ - `incrementalTimeField` must exist in the returned frame
461
+ - `incrementalMergeKeyFields` must identify stable rows
462
+ - generic tabular consumers must receive `core.tabular_frame@v1`
463
+ - if the upstream connection returns raw arrays, paginated JSON, nested provider payloads, or other
464
+ ad hoc records, normalize through an Adapter from API connection first, then use an explicit
465
+ transform when analytical reshaping is still required
466
+ - when a project API or AppComponent legitimately returns a full canonical frame, ground the
467
+ contract against `mainsequence.client.command_center.data_models.TabularFrameResponse`
468
+ - source-specific runtime details belong in `source.context`, not top-level widget payload fields
469
+
470
+ ### 3.2 Historical and incremental lanes
471
+
472
+ Modern tabular consumers use explicit role inputs:
473
+
474
+ - `seedData`: retained baseline or historical dataset
475
+ - `liveUpdates`: incremental publication lane
476
+
477
+ Source outputs:
478
+
479
+ - `connection-query.dataset`: retained `core.tabular_frame@v1` frame for historical consumers
480
+ - `connection-query.updates`: incremental output when incremental refresh is active
481
+ - `connection-stream-query.dataset`: retained compatibility frame
482
+ - `connection-stream-query.updates`: seed/update publication stream
483
+
484
+ Canonical binding shape:
485
+
486
+ ```json
487
+ "bindings": {
488
+ "seedData": {
489
+ "sourceWidgetId": "historical-source",
490
+ "sourceOutputId": "dataset"
491
+ },
492
+ "liveUpdates": {
493
+ "sourceWidgetId": "stream-source",
494
+ "sourceOutputId": "updates"
495
+ }
496
+ }
497
+ ```
498
+
499
+ Rules:
500
+
501
+ - historical/request-response data uses `dataset -> seedData`
502
+ - live or incremental data uses `updates -> liveUpdates`
503
+ - `sourceData` is legacy or compatibility input; use it only when the widget contract requires it
504
+ - do not send stream `dataset` to `liveUpdates`
505
+ - do not send request/response `dataset` to `liveUpdates`
506
+ - generic tabular consumers must receive `core.tabular_frame@v1`
507
+ - raw arrays, paginated JSON, or nested provider payloads must be normalized before reaching generic
508
+ consumers
310
509
 
311
510
  ### 4. Shared workspace state and current-user state are different
312
511
 
@@ -389,26 +588,51 @@ Prefer:
389
588
  Bindings are canonical instance-level graph edges. They live on the target widget instance in
390
589
  `bindings`, not in `props`, and not in widget-type metadata.
391
590
 
392
- One binding is always defined as:
591
+ One binding is always:
393
592
 
394
- - target widget instance + target input id
395
- - source widget instance + source output id
396
- - optional ordered transform steps
593
+ ```text
594
+ source widget output port -> target widget input port
595
+ ```
397
596
 
398
597
  Persisted shape:
399
598
 
400
599
  - `bindings[inputId] = WidgetPortBinding`
401
600
  - `bindings[inputId] = WidgetPortBinding[]` when the target input declares `cardinality: "many"`
402
601
 
403
- A `WidgetPortBinding` minimally contains:
602
+ Minimal `WidgetPortBinding`:
404
603
 
405
- - `sourceWidgetId`
406
- - `sourceOutputId`
407
- - optional `transformSteps`
604
+ ```json
605
+ {
606
+ "sourceWidgetId": "prices-source",
607
+ "sourceOutputId": "dataset"
608
+ }
609
+ ```
408
610
 
409
- Treat `transformSteps` as canonical. Legacy `transformId`, `transformPath`, and
611
+ Binding with transform steps:
612
+
613
+ ```json
614
+ {
615
+ "sourceWidgetId": "source-widget",
616
+ "sourceOutputId": "agent-context",
617
+ "transformSteps": [
618
+ { "id": "extract-path", "path": ["summary"], "contractId": "core.value.string@v1" }
619
+ ]
620
+ }
621
+ ```
622
+
623
+ Treat ordered `transformSteps` as canonical. Legacy `transformId`, `transformPath`, and
410
624
  `transformContractId` may still appear only as backward-compatible mirrors for older persisted
411
- workspaces.
625
+ workspaces. Do not author those legacy fields in new workspace JSON.
626
+
627
+ Supported lightweight transform steps:
628
+
629
+ - `select-array-item`
630
+ - `extract-path`
631
+
632
+ Binding transforms are only for selecting one array item or extracting a nested field before
633
+ compatibility is evaluated. Do not use binding transforms for analytical reshaping. Use a
634
+ `tabular-transform` widget for projection, aggregate, pivot, unpivot, filtering, joining, or other
635
+ visible data operations.
412
636
 
413
637
  Do not describe bindings loosely as “widget A uses widget B”. In this platform, bindings are always
414
638
  port-to-port:
@@ -424,17 +648,16 @@ Resolve bindings from the target widget outward:
424
648
  2. For each target input, record:
425
649
  - `inputId`
426
650
  - accepted contracts
651
+ - `acceptedOutputIds`
427
652
  - `required`
428
653
  - `cardinality`
429
654
  - `effects`
430
655
  3. Choose a source widget instance that actually publishes the required output id.
431
- 4. If the source output is structured JSON or an array, resolve binding transforms before contract
656
+ 4. Validate the source output id against `acceptedOutputIds` when the target input declares it.
657
+ 5. If the source output is structured JSON or an array, resolve binding transforms before contract
432
658
  validation.
433
- - supported transform steps:
434
- - `select-array-item`
435
- - `extract-path`
436
- 5. Validate the transformed contract against the target input `accepts`.
437
- 6. Treat the binding as usable only when the resolved status is `valid`.
659
+ 6. Validate the transformed contract against the target input `accepts`.
660
+ 7. Treat the binding as usable only when the resolved status is `valid`.
438
661
 
439
662
  A binding can exist in workspace JSON and still be unusable at runtime. The runtime may resolve a
440
663
  binding as:
@@ -461,6 +684,10 @@ Runtime and persistence rules:
461
684
  - binding changes clear that target widget's `runtimeState`
462
685
  - the widget settings `Bindings` tab and the workspace graph editor edit the same canonical binding model
463
686
  - for `cardinality: "many"` inputs, preserve order and store an array of bindings for that input id
687
+ - for `cardinality: "one"` inputs, store a single binding object, not an array
688
+ - do not bind a widget to itself
689
+ - graph/editor interactions may be dragged in either visual direction, but persisted JSON is always
690
+ normalized back to target-owned bindings
464
691
 
465
692
  Dynamic-IO rule:
466
693
 
@@ -471,6 +698,10 @@ Dynamic-IO rule:
471
698
  Concrete examples:
472
699
 
473
700
  - a Connection Query widget publishes `dataset`; a Tabular Transform widget can consume and republish `dataset`
701
+ - modern tabular consumers use explicit role inputs:
702
+ - historical/request-response data binds `dataset -> seedData`
703
+ - live or incremental data binds `updates -> liveUpdates`
704
+ - legacy `sourceData` should appear only when the widget contract still requires it
474
705
  - `main-sequence-ai-agent-terminal` accepts one input with `cardinality: "many"`, so several
475
706
  upstream widget contexts can feed one terminal
476
707
  - widgets that implement `buildAgentSnapshot(...)` may also publish a synthetic `agent-context`
@@ -483,16 +714,85 @@ Review rule:
483
714
  - target input id
484
715
  - source widget instance id
485
716
  - source output id
717
+ - accepted output id constraint, if any
486
718
  - transform steps, if any
487
719
  - final resolved contract
488
720
  - final resolved status
489
721
 
722
+ ## Managed Connection Sources
723
+
724
+ Some consumers support embedded connection authoring. Treat this as UI convenience, not a shortcut
725
+ around the source-widget model.
726
+
727
+ The persisted model still has:
728
+
729
+ - a visible owner widget, for example `graph`
730
+ - a hidden source widget, either `connection-query` or `connection-stream-query`
731
+ - `managedBy: { "ownerInstanceId": "<owner-id>", "role": "embedded-connection-source" }` on the hidden source widget
732
+ - a normal binding from the owner input to the hidden source output
733
+
734
+ Owner widget:
735
+
736
+ ```json
737
+ {
738
+ "id": "graph-1",
739
+ "widgetId": "graph",
740
+ "props": {
741
+ "graphSourceMode": "connection",
742
+ "embeddedConnectionQuery": {
743
+ "connectionRef": { "id": 123, "typeId": "mainsequence.simple-table" },
744
+ "queryModelId": "simple-table-sql",
745
+ "query": { "kind": "simple-table-sql", "sql": "select * from {{simple_table}}" }
746
+ }
747
+ },
748
+ "bindings": {
749
+ "seedData": {
750
+ "sourceWidgetId": "graph-1-source",
751
+ "sourceOutputId": "dataset"
752
+ }
753
+ }
754
+ }
755
+ ```
756
+
757
+ Hidden source widget:
758
+
759
+ ```json
760
+ {
761
+ "id": "graph-1-source",
762
+ "widgetId": "connection-query",
763
+ "title": "Graph Source",
764
+ "props": {
765
+ "connectionRef": { "id": 123, "typeId": "mainsequence.simple-table" },
766
+ "queryModelId": "simple-table-sql",
767
+ "query": { "kind": "simple-table-sql", "sql": "select * from {{simple_table}}" }
768
+ },
769
+ "managedBy": {
770
+ "ownerInstanceId": "graph-1",
771
+ "role": "embedded-connection-source"
772
+ },
773
+ "presentation": {
774
+ "placementMode": "sidebar",
775
+ "railVisibility": "hidden"
776
+ }
777
+ }
778
+ ```
779
+
780
+ Managed stream sources bind hidden source `updates` to owner `liveUpdates`.
781
+
782
+ Rules:
783
+
784
+ - keep owner props, hidden source props, `managedBy`, and bindings aligned
785
+ - do not leave orphan hidden source widgets
786
+ - do not point `managedBy.ownerInstanceId` at a missing owner
787
+ - prefer explicit visible source widgets when they make the workspace easier to inspect or reuse
788
+
490
789
 
491
790
  ## Review Rules
492
791
 
493
792
  When reviewing a workspace task, look for:
494
793
 
495
794
  - guessed widget payloads
795
+ - guessed input ids or output ids
496
796
  - widget work that skipped CLI registry verification
497
797
  - widget work that skipped SDK client model review when one exists
498
798
  - unknown or unverified `widgetId` values
@@ -500,12 +800,21 @@ When reviewing a workspace task, look for:
500
800
  - workspace mutation attempted without first exporting the current workspace JSON
501
801
  - widget payloads changed without saving versioned JSON drafts under `workspaces/widgets/`
502
802
  - workspace-wide rewrites for one-widget changes
503
- - shared state mixed incorrectly with current-user runtime state
803
+ - current-user runtime state mixed into durable workspace JSON accidentally
504
804
  - runtime ownership violations such as consumer widgets inventing canonical fetch paths
505
805
  - unresolved external resource ids
506
- - connection-backed consumers missing a source or transform `dataset` binding
806
+ - connection-backed consumers missing a source widget or required transform widget
507
807
  - generic tabular consumers bound to raw JSON instead of `core.tabular_frame@v1`
508
808
  - full canonical tabular payloads that drift from `TabularFrameResponse`
809
+ - bindings authored in `props` instead of `widget.bindings`
810
+ - bindings placed on the source widget instead of the target widget
811
+ - bindings that ignore `acceptedOutputIds`
812
+ - `dataset -> liveUpdates`
813
+ - stream `dataset` used for live data instead of stream `updates`
814
+ - stream or incremental outputs wired to the wrong role input
815
+ - binding transforms used for analytical reshaping instead of a transform widget
816
+ - hidden managed source widgets missing their owner widget
817
+ - stale `managedBy.ownerInstanceId` values
509
818
  - widget trees using structures not supported by the Main Sequence repository source models
510
819
 
511
820
  ## Validation Checklist
@@ -523,13 +832,25 @@ Do not claim success until you have checked:
523
832
  - versioned workspace/widget JSON files were preserved pending user acceptance
524
833
  - widget detail was reviewed for `widgetVersion`, configuration, runtime, IO, capabilities, agent hints, and examples
525
834
  - the relevant SDK client model was reviewed when one exists
526
- - connection-backed source widgets have verified connection instance, connection type, query model, typed query payload, and output contract
835
+ - every source widget has a valid connection ref, query model id, typed query payload, and output contract
836
+ - every `query.kind` matches `queryModelId`
527
837
  - generic tabular consumers receive `core.tabular_frame@v1`
838
+ - every binding references an existing source widget and output id
839
+ - every binding targets an existing input id
840
+ - every binding matches the target input contract
841
+ - every binding respects `acceptedOutputIds` when declared
842
+ - `cardinality: "many"` bindings preserve order as arrays
843
+ - `cardinality: "one"` bindings are single binding objects
844
+ - historical/request-response data uses `dataset -> seedData` when the widget exposes role inputs
845
+ - live or incremental data uses `updates -> liveUpdates` when the widget exposes role inputs
528
846
  - full canonical tabular frames match `TabularFrameResponse`
529
847
  - widget ids and widget instance ids are correct
530
848
  - any mounted widget that depends on a project API points to a FastAPI project resource that already exists
531
849
  - any mounted widget that depends on a project API points to a FastAPI `ResourceRelease` that already exists
532
850
  - local payload shape was reconciled against the verified widget id, widget-detail contract, and SDK model
851
+ - managed sources have valid `managedBy.ownerInstanceId` values
852
+ - owner widgets and hidden managed source widgets agree on connection/query props
853
+ - no credentials, native URLs, or backend route fragments are embedded in workspace JSON
533
854
  - the chosen mutation mode is correct:
534
855
  - full workspace update
535
856
  - widget-scoped mutation