mainsequence 4.3.9__tar.gz → 4.3.18__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.
- {mainsequence-4.3.9/mainsequence.egg-info → mainsequence-4.3.18}/PKG-INFO +1 -1
- {mainsequence-4.3.9 → mainsequence-4.3.18}/agent_scaffold/skills/command_center/adapter_from_api/SKILL.md +54 -31
- {mainsequence-4.3.9 → mainsequence-4.3.18}/agent_scaffold/skills/command_center/app_components/SKILL.md +70 -35
- mainsequence-4.3.18/agent_scaffold/skills/data_publishing/meta_table_migrations/SKILL.md +102 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/agent_scaffold/skills/data_publishing/meta_tables/SKILL.md +26 -20
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/cli/migrations.py +125 -56
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/client/metatables/core.py +94 -251
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/meta_tables/data_nodes/data_nodes.py +25 -4
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/meta_tables/data_nodes/persist_managers.py +140 -29
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/meta_tables/data_nodes/run_operations.py +174 -41
- mainsequence-4.3.9/mainsequence/meta_tables/migrations.py → mainsequence-4.3.18/mainsequence/meta_tables/migrations/__init__.py +61 -42
- mainsequence-4.3.18/mainsequence/meta_tables/migrations/alembic.py +165 -0
- mainsequence-4.3.18/mainsequence/meta_tables/migrations/env.py +119 -0
- mainsequence-4.3.18/mainsequence/meta_tables/migrations/provider.py +25 -0
- mainsequence-4.3.18/mainsequence/meta_tables/migrations/registry.py +75 -0
- mainsequence-4.3.18/mainsequence/meta_tables/migrations/scaffold.py +221 -0
- mainsequence-4.3.18/mainsequence/meta_tables/migrations/templates/__init__.py +1 -0
- mainsequence-4.3.18/mainsequence/meta_tables/migrations/templates/env.py.mako +8 -0
- mainsequence-4.3.18/mainsequence/meta_tables/migrations/templates/script.py.mako +28 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18/mainsequence.egg-info}/PKG-INFO +1 -1
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence.egg-info/SOURCES.txt +10 -1
- {mainsequence-4.3.9 → mainsequence-4.3.18}/pyproject.toml +2 -2
- {mainsequence-4.3.9 → mainsequence-4.3.18}/tests/test_cli_migrations.py +58 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/tests/test_data_node_update_flow.py +30 -1
- {mainsequence-4.3.9 → mainsequence-4.3.18}/tests/test_meta_table_migrations.py +301 -15
- {mainsequence-4.3.9 → mainsequence-4.3.18}/tests/test_meta_tables_client_models.py +4 -57
- {mainsequence-4.3.9 → mainsequence-4.3.18}/tests/test_meta_tables_sqlalchemy_contracts.py +44 -2
- {mainsequence-4.3.9 → mainsequence-4.3.18}/tests/test_run_configuration.py +130 -11
- {mainsequence-4.3.9 → mainsequence-4.3.18}/tests/test_source_table_configuration.py +42 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/tests/test_update_runner_uid_runtime.py +205 -1
- {mainsequence-4.3.9 → mainsequence-4.3.18}/LICENSE +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/README.md +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/agent_scaffold/AGENTS.md +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/agent_scaffold/skills/a2a_communication/SKILL.md +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/agent_scaffold/skills/application_surfaces/api_surfaces/SKILL.md +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/agent_scaffold/skills/command_center/api_mock_prototyping/SKILL.md +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/agent_scaffold/skills/command_center/connections/SKILL.md +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/agent_scaffold/skills/command_center/workspace_analysis/SKILL.md +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/agent_scaffold/skills/command_center/workspace_builder/SKILL.md +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/agent_scaffold/skills/command_center/workspace_design/SKILL.md +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/agent_scaffold/skills/dashboards/streamlit/SKILL.md +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/agent_scaffold/skills/data_access/exploration/SKILL.md +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/agent_scaffold/skills/data_publishing/data_nodes/SKILL.md +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/agent_scaffold/skills/maintenance/bug_auditor/SKILL.md +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/agent_scaffold/skills/ms-markets/SKILL.md +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/agent_scaffold/skills/platform_operations/access_control_and_sharing/SKILL.md +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/agent_scaffold/skills/platform_operations/orchestration_and_releases/SKILL.md +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/agent_scaffold/skills/project_builder/SKILL.md +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/agent_scaffold/skills/project_to_agent/SKILL.md +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/__init__.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/__main__.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/bootstrap.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/cli/__init__.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/cli/api.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/cli/browser_auth.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/cli/cli.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/cli/config.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/cli/docker_utils.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/cli/doctor.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/cli/local_ops.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/cli/model_filters.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/cli/project_status.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/cli/pydantic_cli.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/cli/sdk_utils.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/cli/ssh_utils.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/cli/ui.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/client/__init__.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/client/agent_runtime_models.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/client/base.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/client/client.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/client/command_center/__init__.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/client/command_center/app_component.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/client/command_center/connections.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/client/command_center/data_models.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/client/command_center/workspace.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/client/command_center/workspace_snapshot.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/client/compute_validation.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/client/data_sources_interfaces/__init__.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/client/data_sources_interfaces/duckdb.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/client/data_sources_interfaces/local_paths.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/client/data_sources_interfaces/sqlite.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/client/dtype_codec.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/client/exceptions.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/client/fastapi/__init__.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/client/fastapi/auth.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/client/metatables/__init__.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/client/models_foundry.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/client/models_helpers.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/client/models_user.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/client/utils.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/defaults.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/instrumentation/__init__.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/instrumentation/utils.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/logconf.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/meta_tables/__init__.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/meta_tables/__main__.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/meta_tables/compiled_sql/__init__.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/meta_tables/compiled_sql/v1.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/meta_tables/data_nodes/__init__.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/meta_tables/data_nodes/build_operations.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/meta_tables/data_nodes/models.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/meta_tables/data_nodes/namespacing.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/meta_tables/data_nodes/utils.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/meta_tables/future_registry.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/meta_tables/hashing.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/meta_tables/pydantic_metadata.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/meta_tables/schema_names.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/meta_tables/sqlalchemy_contracts.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence/runtime_flags.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence.egg-info/dependency_links.txt +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence.egg-info/entry_points.txt +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence.egg-info/requires.txt +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/mainsequence.egg-info/top_level.txt +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/setup.cfg +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/tests/test_auth_precedence.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/tests/test_build_operations_hashing.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/tests/test_cli.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/tests/test_cli_browser_auth.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/tests/test_client.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/tests/test_command_center_app_component_models.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/tests/test_command_center_data_models.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/tests/test_command_center_models.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/tests/test_data_access_mixin_dimension_audit.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/tests/test_data_node_storage_dimension_queries.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/tests/test_dependency_extras.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/tests/test_duckdb_interface_dimensions.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/tests/test_filter_normalization.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/tests/test_instrumentation.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/tests/test_logconf.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/tests/test_models_user_request_bound_auth.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/tests/test_pod_project_resolution.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/tests/test_project_batch_jobs_from_file.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/tests/test_schema_names.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/tests/test_secret_client_model.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/tests/test_sqlite_interface_dimensions.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/tests/test_update_statistics.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/tests/test_update_uid_guards.py +0 -0
- {mainsequence-4.3.9 → mainsequence-4.3.18}/tests/test_workspace_snapshot.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: command-center-adapter-from-api
|
|
3
|
-
description: Use when building or changing an API so Command Center can consume it through an Adapter from API connection. This skill defines the provider-side API contract standards required for Command Center connection discovery, health checks, operation selection, config fields, secret injection metadata, canonical `TabularFrameResponse` outputs, and
|
|
3
|
+
description: Use when building or changing an API so Command Center can consume it through an Adapter from API connection. This skill defines the provider-side API contract standards required for Command Center connection discovery, health checks, operation selection, config fields, secret injection metadata, canonical `TabularFrameResponse` outputs, and optional response-mapping metadata for frontend/editor context or future explicit transforms. It does not define general API architecture and does not imply the API may only serve these endpoints.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Command Center Adapter From API
|
|
@@ -13,7 +13,7 @@ connection.
|
|
|
13
13
|
This skill defines the Command Center-facing contract that the API must expose. It does not own the
|
|
14
14
|
whole API architecture. An API may serve other clients and routes, but if it is consumed by Command
|
|
15
15
|
Center through this adapter, it must also expose the discovery, health, operation, config, secret,
|
|
16
|
-
and response-mapping metadata described here.
|
|
16
|
+
and any optional response-mapping metadata described here.
|
|
17
17
|
|
|
18
18
|
The runtime flow is:
|
|
19
19
|
|
|
@@ -26,8 +26,12 @@ API with Command Center contract endpoints
|
|
|
26
26
|
```
|
|
27
27
|
|
|
28
28
|
Generic table, chart, statistic, curve, transform, and agent-facing data consumers must consume
|
|
29
|
-
`core.tabular_frame@v1
|
|
30
|
-
|
|
29
|
+
an actual `core.tabular_frame@v1` payload at the consumption boundary. API responses that are
|
|
30
|
+
provider-native, paginated, nested, or domain specific are still provider-native even when the
|
|
31
|
+
contract includes `responseMappings`. A mapping may describe how a response could be interpreted by
|
|
32
|
+
frontend/editor tooling or a future explicit transform, but the current backend adapter must not
|
|
33
|
+
hot-path validate, extract JSONPath rows, coerce schemas, or reshape provider responses because a
|
|
34
|
+
mapping exists.
|
|
31
35
|
|
|
32
36
|
## Scope
|
|
33
37
|
|
|
@@ -39,7 +43,7 @@ This skill owns:
|
|
|
39
43
|
- operation metadata needed by Connection Query
|
|
40
44
|
- public config variable definitions
|
|
41
45
|
- secret variable definitions and backend injection metadata
|
|
42
|
-
- response
|
|
46
|
+
- optional response-mapping metadata for frontend/editor context and future explicit transforms
|
|
43
47
|
- API-side validation and maintenance rules for this contract
|
|
44
48
|
|
|
45
49
|
This skill does not own:
|
|
@@ -103,7 +107,7 @@ GET /openapi.json
|
|
|
103
107
|
```
|
|
104
108
|
|
|
105
109
|
This is supplementary metadata. The well-known Command Center contract decides what operations,
|
|
106
|
-
config fields, secrets, and response
|
|
110
|
+
config fields, secrets, and optional response-mapping metadata Command Center may use.
|
|
107
111
|
|
|
108
112
|
### 3. Dedicated Health Endpoint
|
|
109
113
|
|
|
@@ -123,8 +127,9 @@ parameters. Do not use a parameterized data endpoint as a fake health check.
|
|
|
123
127
|
Each queryable API operation must have a stable `operationId` in the well-known contract and a
|
|
124
128
|
matching route in the API.
|
|
125
129
|
|
|
126
|
-
Operation endpoints may return
|
|
127
|
-
|
|
130
|
+
Operation endpoints may return a full canonical `core.tabular_frame@v1` payload or provider-native
|
|
131
|
+
JSON. `responseMappings` may document an intended tabular interpretation, but they are not a
|
|
132
|
+
runtime guarantee that provider-native JSON becomes `core.tabular_frame@v1`.
|
|
128
133
|
|
|
129
134
|
## Well-Known Contract Shape
|
|
130
135
|
|
|
@@ -185,7 +190,7 @@ Every operation listed in `availableOperations` must define:
|
|
|
185
190
|
- `supportsMaxRows`
|
|
186
191
|
- `parameters`
|
|
187
192
|
- optional `requestBody`
|
|
188
|
-
- `responseMappings`
|
|
193
|
+
- optional `responseMappings`
|
|
189
194
|
- `cache`
|
|
190
195
|
|
|
191
196
|
Rules:
|
|
@@ -264,8 +269,8 @@ from mainsequence.client.command_center.data_models import TabularFrameResponse
|
|
|
264
269
|
Declare `response_model=TabularFrameResponse` instead of recreating the canonical frame shape
|
|
265
270
|
locally.
|
|
266
271
|
|
|
267
|
-
If an operation returns provider-native JSON, declare a `responseMappings` entry that
|
|
268
|
-
|
|
272
|
+
If an operation returns provider-native JSON, it may declare a `responseMappings` entry that
|
|
273
|
+
describes a tabular interpretation for frontend/editor metadata or future explicit transforms:
|
|
269
274
|
|
|
270
275
|
```json
|
|
271
276
|
{
|
|
@@ -289,13 +294,23 @@ operation as `core.tabular_frame@v1`:
|
|
|
289
294
|
|
|
290
295
|
Rules:
|
|
291
296
|
|
|
292
|
-
- `
|
|
293
|
-
-
|
|
294
|
-
-
|
|
295
|
-
-
|
|
297
|
+
- `responseMappings` are optional metadata in the current Adapter from API flow.
|
|
298
|
+
- A mapping does not make provider-native JSON a `core.tabular_frame@v1` runtime payload.
|
|
299
|
+
- The backend must not hot-path validate the upstream body against `responseMappings`.
|
|
300
|
+
- The backend must not extract JSONPath rows, coerce schemas, or reshape the response merely
|
|
301
|
+
because a mapping exists.
|
|
302
|
+
- If a mapping describes tabular interpretation, `contract` should be `core.tabular_frame@v1`.
|
|
303
|
+
- If `rowsPath` is present, it should point to the array of row objects inside the operation
|
|
304
|
+
response.
|
|
305
|
+
- If `fieldTypes` is present, it should cover the fields that frontend/editor tooling or future
|
|
306
|
+
transforms need for formatting and inference.
|
|
307
|
+
- Time-series metadata is useful when the mapped rows are meant for charts, curves, or time-aware
|
|
296
308
|
transforms.
|
|
297
309
|
- If the response shape changes, update the response mapping in the same change.
|
|
298
|
-
- Do not
|
|
310
|
+
- Do not claim provider-native JSON is safe for generic tabular consumers just because a
|
|
311
|
+
`responseMappings` entry exists.
|
|
312
|
+
- If generic tabular widgets need to consume the operation directly today, return
|
|
313
|
+
`TabularFrameResponse` from the API operation.
|
|
299
314
|
|
|
300
315
|
## Canonical SDK Model
|
|
301
316
|
|
|
@@ -313,8 +328,9 @@ Related SDK models:
|
|
|
313
328
|
- `TabularTimeSeriesMetaResponse`
|
|
314
329
|
|
|
315
330
|
Use these models when the API operation returns the full canonical frame. If the provider operation
|
|
316
|
-
returns provider-native JSON instead, keep the provider response model explicit
|
|
317
|
-
`responseMappings`
|
|
331
|
+
returns provider-native JSON instead, keep the provider response model explicit. Add
|
|
332
|
+
`responseMappings` only as metadata; do not treat it as runtime conversion into
|
|
333
|
+
`core.tabular_frame@v1`.
|
|
318
334
|
|
|
319
335
|
## Required Decisions
|
|
320
336
|
|
|
@@ -327,9 +343,10 @@ Before implementing or revising an API for Adapter from API consumption, decide:
|
|
|
327
343
|
5. Which operation IDs must remain stable?
|
|
328
344
|
6. Which public config fields does the connection need?
|
|
329
345
|
7. Which secrets does the connection need, and how does the backend inject them?
|
|
330
|
-
8. Which operations
|
|
331
|
-
|
|
332
|
-
|
|
346
|
+
8. Which operations directly return a full `core.tabular_frame@v1` payload for generic tabular
|
|
347
|
+
consumption?
|
|
348
|
+
9. For provider-native responses, is optional `responseMappings` metadata useful, and what explicit
|
|
349
|
+
transform or future feature would consume it?
|
|
333
350
|
10. If the operation returns a full canonical frame, does it use `TabularFrameResponse` as the
|
|
334
351
|
FastAPI `response_model`?
|
|
335
352
|
|
|
@@ -343,7 +360,8 @@ For a FastAPI provider:
|
|
|
343
360
|
- expose a zero-argument health route
|
|
344
361
|
- expose query operation routes with documented request parameters
|
|
345
362
|
- declare every Command Center-callable operation in `availableOperations`
|
|
346
|
-
- declare `
|
|
363
|
+
- declare `responseMappings` only as optional metadata when useful; do not rely on them for runtime
|
|
364
|
+
normalization
|
|
347
365
|
- use `TabularFrameResponse` when an operation returns the full canonical frame
|
|
348
366
|
- keep the API root, well-known contract, and OpenAPI document internally consistent
|
|
349
367
|
|
|
@@ -358,10 +376,11 @@ When reviewing an Adapter from API provider change, look for:
|
|
|
358
376
|
- operations missing from `availableOperations`
|
|
359
377
|
- operations exposed to Command Center without explicit allowlist metadata
|
|
360
378
|
- secret values represented as public config or query payload fields
|
|
361
|
-
-
|
|
362
|
-
- response mappings whose `rowsPath` no longer matches the API response
|
|
363
|
-
- missing `fieldTypes` for fields
|
|
364
|
-
- API endpoints returning provider-native JSON directly to generic tabular consumers
|
|
379
|
+
- provider-native responses being treated as `core.tabular_frame@v1` because a mapping exists
|
|
380
|
+
- response mappings whose `rowsPath` no longer matches the API response when the mapping is present
|
|
381
|
+
- missing `fieldTypes` for fields that declared mappings or future transforms need
|
|
382
|
+
- API endpoints returning provider-native JSON directly to generic tabular consumers without an
|
|
383
|
+
explicit transform path
|
|
365
384
|
- full canonical frame endpoints that do not use `TabularFrameResponse`
|
|
366
385
|
- docs or README examples that disagree with the actual contract endpoint
|
|
367
386
|
|
|
@@ -380,10 +399,12 @@ Do not claim the API is consumable by Adapter from API until:
|
|
|
380
399
|
- query-capable operations are explicitly marked as query-capable
|
|
381
400
|
- public config and secret fields are separated
|
|
382
401
|
- secret injection rules are backend-owned and explicit
|
|
383
|
-
- each generic tabular
|
|
402
|
+
- each operation that must feed generic tabular consumers directly returns `core.tabular_frame@v1`
|
|
384
403
|
- each full canonical frame operation uses `TabularFrameResponse`
|
|
385
|
-
-
|
|
386
|
-
|
|
404
|
+
- provider-native responses are not represented as direct generic tabular outputs solely through
|
|
405
|
+
`responseMappings`
|
|
406
|
+
- optional response mappings, when present, have accurate `rowsPath`, `fieldTypes`, and time-series
|
|
407
|
+
hints for their intended metadata or transform use
|
|
387
408
|
- the local README documents the Command Center contract endpoints
|
|
388
409
|
- any general FastAPI/API work has also followed `application_surfaces/api_surfaces`
|
|
389
410
|
|
|
@@ -396,8 +417,10 @@ Stop and surface the missing backend task when:
|
|
|
396
417
|
- operation IDs cannot be made stable
|
|
397
418
|
- auth requirements are unknown
|
|
398
419
|
- secret injection cannot be described without exposing secret values
|
|
399
|
-
-
|
|
400
|
-
|
|
420
|
+
- a provider-native response is being treated as generic tabular output only because
|
|
421
|
+
`responseMappings` exists
|
|
422
|
+
- the API response shape must feed generic tabular consumers directly but cannot return
|
|
423
|
+
`TabularFrameResponse`
|
|
401
424
|
- a full canonical frame endpoint cannot import or use `TabularFrameResponse`
|
|
402
425
|
- backend Adapter from API runtime support is required but not implemented
|
|
403
426
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: command-center-app-components
|
|
3
|
-
description: Use this skill when the task is about AppComponent widgets in a Main Sequence project. This skill owns AppComponent
|
|
3
|
+
description: Use this skill when the task is about AppComponent widgets in a Main Sequence project. This skill owns AppComponent generated request forms, response-side editable-form and notification UI contracts, dynamic request/response binding contracts, and the boundary between AppComponent responses and widget-facing output contracts, including requiring generic tabular consumers to receive core.tabular_frame@v1 instead of ad hoc AppComponent JSON. Before changing AppComponent payloads or contracts, verify the target widget in the Command Center registry through the CLI. Source order is strict: registry detail first, SDK client models second, local Main Sequence repository docs/models third only if the first two still leave something unresolved. Main Sequence is platform-first: if an AppComponent depends on a project API, that API must already exist as a FastAPI project resource and have a corresponding FastAPI ResourceRelease before the AppComponent is considered usable from Command Center. Resource and release creation belong to the orchestration-and-releases skill. It does not own workspace layout, generic FastAPI design, or Streamlit dashboards.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Command Center AppComponents
|
|
@@ -11,22 +11,23 @@ Use this skill when the task is about the backend contract behind a Command Cent
|
|
|
11
11
|
|
|
12
12
|
This skill is for:
|
|
13
13
|
|
|
14
|
-
- AppComponent
|
|
15
|
-
-
|
|
14
|
+
- AppComponent generated request form contracts
|
|
15
|
+
- response-side editable form and notification contracts
|
|
16
16
|
- field and section definitions
|
|
17
|
-
- deciding when default
|
|
17
|
+
- deciding when default request form generation is enough
|
|
18
18
|
- deciding when a widget-facing API response must use an exact SDK contract
|
|
19
19
|
- requiring API-backed AppComponents to depend on deployed FastAPI resources/releases, not local-only API code
|
|
20
20
|
|
|
21
21
|
## This Skill Can Do
|
|
22
22
|
|
|
23
|
-
- decide whether an AppComponent should rely on the default generated form
|
|
24
|
-
-
|
|
23
|
+
- decide whether an AppComponent should rely on the default generated request form
|
|
24
|
+
- return an `EditableFormDefinition` response when the API should render a stateful editable response form
|
|
25
|
+
- return a `NotificationDefinition` response when the API should render banner-style feedback
|
|
25
26
|
- define `FormSectionDefinition`
|
|
26
27
|
- define `FormFieldDefinition`
|
|
27
28
|
- choose the correct `FormFieldKind`
|
|
28
29
|
- define stable `token` values for fields
|
|
29
|
-
- review whether
|
|
30
|
+
- review whether the request form or response UI contract is over- or under-specified
|
|
30
31
|
- separate input contracts from output contracts
|
|
31
32
|
- decide when the API behind an AppComponent must return exact widget-facing response models
|
|
32
33
|
- verify the target widget type in the CLI registry before changing payload or contract logic
|
|
@@ -90,8 +91,10 @@ Before changing an AppComponent backend contract, collect or infer:
|
|
|
90
91
|
- registry detail payload from:
|
|
91
92
|
- `mainsequence cc registered_widget_type detail <WIDGET_ID> --json`
|
|
92
93
|
- what the widget is trying to collect from the user
|
|
93
|
-
- whether the default generated form is already sufficient
|
|
94
|
-
- the
|
|
94
|
+
- whether the default generated request form is already sufficient
|
|
95
|
+
- whether the request form needs supported operation-level UI metadata such as `select2` async search
|
|
96
|
+
- whether the response should render as a notification banner, an editable form session, or the generic response viewer
|
|
97
|
+
- the fields, sections, labels, and tokens a response-side editable form should expose
|
|
95
98
|
- whether the output is:
|
|
96
99
|
- a generic API contract
|
|
97
100
|
- an exact widget-facing contract
|
|
@@ -118,26 +121,27 @@ If registry detail is not sufficient, and only after checking the SDK client mod
|
|
|
118
121
|
- `mainsequence/client/command_center/app_component.py`
|
|
119
122
|
- `mainsequence/client/command_center/data_models.py`
|
|
120
123
|
|
|
121
|
-
If the
|
|
124
|
+
If the request contract, response UI contract, or widget-facing output contract is unclear, stop before building the AppComponent contract.
|
|
122
125
|
|
|
123
126
|
## Required Decisions
|
|
124
127
|
|
|
125
128
|
For every non-trivial AppComponent task, decide:
|
|
126
129
|
|
|
127
|
-
1. Is the default generated form sufficient?
|
|
128
|
-
2. If not,
|
|
129
|
-
3.
|
|
130
|
-
4. What field
|
|
131
|
-
5.
|
|
132
|
-
6.
|
|
130
|
+
1. Is the default generated request form sufficient?
|
|
131
|
+
2. If not, can the request-side need be handled by supported OpenAPI UI metadata such as `select2` async search?
|
|
132
|
+
3. Should the response render as generic JSON/form output, a `NotificationDefinition`, or an `EditableFormDefinition` session?
|
|
133
|
+
4. What are the stable field tokens for editable-form responses?
|
|
134
|
+
5. What field kinds should the frontend render?
|
|
135
|
+
6. Is the output generic, or does it need an exact widget-facing response contract?
|
|
136
|
+
7. If the AppComponent depends on a project API, does that API already exist as a FastAPI project resource with a FastAPI `ResourceRelease`?
|
|
133
137
|
|
|
134
138
|
## Build Rules
|
|
135
139
|
|
|
136
|
-
### 1. Default generated form first
|
|
140
|
+
### 1. Default generated request form first
|
|
137
141
|
|
|
138
|
-
Do not jump to a
|
|
142
|
+
Do not jump to a response-side editable form by default.
|
|
139
143
|
|
|
140
|
-
If the operation only exposes simple flat arguments with a straightforward shape, let Command Center resolve the form automatically.
|
|
144
|
+
If the operation only exposes simple flat arguments with a straightforward shape, let Command Center resolve the request form automatically from OpenAPI parameters and request body schema.
|
|
141
145
|
|
|
142
146
|
Typical cases where default generation is enough:
|
|
143
147
|
|
|
@@ -176,9 +180,14 @@ This skill does not create resources or releases. If the FastAPI project resourc
|
|
|
176
180
|
|
|
177
181
|
Only return to AppComponent contract work once the backing API deployment surface is real on the platform.
|
|
178
182
|
|
|
179
|
-
### 2. Use `EditableFormDefinition` only
|
|
183
|
+
### 2. Use `EditableFormDefinition` only for response-side editable form sessions
|
|
180
184
|
|
|
181
|
-
|
|
185
|
+
`EditableFormDefinition` is a response model. Command Center renders it after the operation returns successfully when the selected operation's primary success response advertises:
|
|
186
|
+
|
|
187
|
+
- `"x-ui-role": "editable-form"`
|
|
188
|
+
- `"x-ui-widget": "definition-v1"`
|
|
189
|
+
|
|
190
|
+
Use it when the response should become a stateful editable form session with:
|
|
182
191
|
|
|
183
192
|
- grouped sections
|
|
184
193
|
- domain-specific labels
|
|
@@ -186,7 +195,14 @@ Use a custom form when the widget needs:
|
|
|
186
195
|
- more control over editable vs read-only behavior
|
|
187
196
|
- stable custom tokens for bindings or draft state
|
|
188
197
|
|
|
189
|
-
Do not use
|
|
198
|
+
Do not use `EditableFormDefinition` to define the pre-submit request form. Request inputs are generated from OpenAPI path, query, header, and JSON body metadata. If the request side needs richer behavior, use supported operation-level UI metadata instead of returning a form definition.
|
|
199
|
+
|
|
200
|
+
The current supported request-side UI enhancement is:
|
|
201
|
+
|
|
202
|
+
- `"x-ui-widget": "select2"`
|
|
203
|
+
- `"x-ui-role": "async-select-search"`
|
|
204
|
+
|
|
205
|
+
This enhancement is resolved from the selected OpenAPI operation metadata and currently targets query-parameter search helpers on that operation.
|
|
190
206
|
|
|
191
207
|
### 3. Treat tokens as stable identities
|
|
192
208
|
|
|
@@ -212,7 +228,10 @@ Example:
|
|
|
212
228
|
|
|
213
229
|
Keep the boundary clear:
|
|
214
230
|
|
|
215
|
-
-
|
|
231
|
+
- OpenAPI parameters and request body schemas describe what the widget should collect before execution
|
|
232
|
+
- operation-level `select2` metadata can specialize supported request-side generated fields
|
|
233
|
+
- `EditableFormDefinition` and related form objects describe a response-side editable form session
|
|
234
|
+
- `NotificationDefinition` describes response-side banner feedback
|
|
216
235
|
- `mainsequence.client.command_center.data_models.TabularFrameResponse` is the SDK canonical model for `core.tabular_frame@v1`
|
|
217
236
|
- other SDK widget data models describe specialized widget-facing API responses when those exist
|
|
218
237
|
|
|
@@ -265,24 +284,37 @@ Do not use AppComponent as a shortcut source node for generic workspace data jus
|
|
|
265
284
|
operation itself is the intended form-driven action or workflow producing the canonical tabular
|
|
266
285
|
result.
|
|
267
286
|
|
|
268
|
-
### 6.2 `x-ui-role` is what makes
|
|
287
|
+
### 6.2 `x-ui-role` is what makes supported contracts render as richer UI
|
|
269
288
|
|
|
270
|
-
For AppComponent contracts, prefer SDK models whose OpenAPI schema carries the explicit UI role markers.
|
|
289
|
+
For AppComponent response contracts, prefer SDK models whose OpenAPI schema carries the explicit UI role markers.
|
|
271
290
|
|
|
272
291
|
The AppComponent should always try to implement:
|
|
273
292
|
|
|
274
|
-
- `"x-ui-role": "editable-form"` for
|
|
275
|
-
- `"x-ui-role": "notification"` for response-side
|
|
293
|
+
- `"x-ui-role": "editable-form"` with `"x-ui-widget": "definition-v1"` for response-side editable form sessions
|
|
294
|
+
- `"x-ui-role": "notification"` with `"x-ui-widget": "banner-v1"` for response-side banner feedback
|
|
295
|
+
|
|
296
|
+
For request-side generated form enhancements, the current supported operation-level contract is:
|
|
297
|
+
|
|
298
|
+
- `"x-ui-role": "async-select-search"` with `"x-ui-widget": "select2"`
|
|
276
299
|
|
|
277
300
|
These markers are not cosmetic. They are what tell Command Center to treat the payload as a richer UI contract instead of generic JSON.
|
|
278
301
|
|
|
279
302
|
That means:
|
|
280
303
|
|
|
281
|
-
- use
|
|
304
|
+
- use OpenAPI parameters and request bodies for pre-submit inputs
|
|
305
|
+
- use operation-level `select2` metadata when a request field should render as an async search input
|
|
306
|
+
- use `EditableFormDefinition` and related models when the AppComponent response should render as a stateful editable form
|
|
282
307
|
- use `NotificationDefinition` for response-side user feedback when the backend should return a banner-style notification
|
|
283
308
|
- do not handcraft loose dictionaries for these cases when the SDK model already exists
|
|
284
309
|
- keep input and response contracts separate instead of overloading one model to do both jobs
|
|
285
310
|
|
|
311
|
+
Current frontend resolution details matter:
|
|
312
|
+
|
|
313
|
+
- generated request forms come from OpenAPI path, query, header, and JSON body metadata
|
|
314
|
+
- request-side `select2` metadata is read from the selected OpenAPI operation
|
|
315
|
+
- response-side editable-form and notification metadata is read from the primary success response schema first, then from the operation metadata
|
|
316
|
+
- placing these response UI markers only on the OpenAPI media-type or response object is not sufficient in the current frontend
|
|
317
|
+
|
|
286
318
|
### 6.3 AppComponent bindings are dynamic, port-to-port, and response-shape aware
|
|
287
319
|
|
|
288
320
|
Treat AppComponent bindings as normal canonical widget bindings, not as a separate AppComponent-only
|
|
@@ -369,8 +401,8 @@ When reviewing an AppComponent task, look for:
|
|
|
369
401
|
|
|
370
402
|
- inferred or guessed `widget_id` values
|
|
371
403
|
- AppComponent work that skipped `registered_widget_type list/detail`
|
|
372
|
-
- a
|
|
373
|
-
- a flat autogenerated form that should have
|
|
404
|
+
- a response-side editable form being used where the request form should simply be generated from OpenAPI
|
|
405
|
+
- a flat autogenerated request form that should have used supported operation-level UI metadata
|
|
374
406
|
- unstable or poorly named field tokens
|
|
375
407
|
- wrong `FormFieldKind` choices
|
|
376
408
|
- generic API output being used where an exact widget-facing contract should have been returned
|
|
@@ -388,14 +420,16 @@ Do not claim success until you have checked:
|
|
|
388
420
|
- `mainsequence cc registered_widget_type list --json`
|
|
389
421
|
- `mainsequence cc registered_widget_type detail <WIDGET_ID> --json`
|
|
390
422
|
- registry detail was used as the first source of truth
|
|
391
|
-
- the choice between autogenerated form and
|
|
392
|
-
-
|
|
423
|
+
- the choice between autogenerated request form and supported request-side UI metadata is intentional
|
|
424
|
+
- response-side editable forms use `EditableFormDefinition`
|
|
425
|
+
- response-side notifications use `NotificationDefinition`
|
|
393
426
|
- sections and fields are explicit where needed
|
|
394
427
|
- field tokens are stable and meaningful
|
|
395
428
|
- field kinds reflect business meaning
|
|
396
429
|
- input and output contracts are not mixed together
|
|
397
|
-
-
|
|
398
|
-
- response-side AppComponent contracts use `"x-ui-role": "
|
|
430
|
+
- request-side AppComponent enhancements use operation-level `"x-ui-role": "async-select-search"` with `"x-ui-widget": "select2"` when async search is intended
|
|
431
|
+
- response-side AppComponent contracts use `"x-ui-role": "editable-form"` with `"x-ui-widget": "definition-v1"` when the API is returning a stateful editable form
|
|
432
|
+
- response-side AppComponent contracts use `"x-ui-role": "notification"` with `"x-ui-widget": "banner-v1"` when the API is returning user-facing banner feedback
|
|
399
433
|
- widget-facing outputs use exact SDK response models when applicable
|
|
400
434
|
- generic tabular consumers receive `core.tabular_frame@v1`
|
|
401
435
|
- AppComponent operations producing full canonical tabular frames use `TabularFrameResponse`
|
|
@@ -411,7 +445,8 @@ Do not claim success until you have checked:
|
|
|
411
445
|
- the task depends on guessed widget behavior without registry verification
|
|
412
446
|
- registry detail is insufficient and the required contract cannot be resolved from Main Sequence docs/models in this repository
|
|
413
447
|
- the task is really about workspace structure instead of AppComponent contracts
|
|
414
|
-
- the form contract is unclear but a
|
|
448
|
+
- the request form contract is unclear but a response-side editable form is being forced anyway
|
|
449
|
+
- the response UI contract is unclear but `EditableFormDefinition` or `NotificationDefinition` is being forced anyway
|
|
415
450
|
- the widget-facing output contract is unclear and no exact SDK model is available
|
|
416
451
|
- the task is really a generic API design problem rather than an AppComponent problem
|
|
417
452
|
- the AppComponent depends on a project API that does not yet exist as a FastAPI resource and FastAPI `ResourceRelease`
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: mainsequence-metatable-migrations
|
|
3
|
+
description: Use this skill when the task is about Main Sequence MetaTable schema evolution, Alembic provider setup, migration scaffold generation, revision creation, migration upgrade/current commands, provider-scoped MetaTable reservation/finalization, or debugging migration lifecycle failures. This skill owns the migration-first workflow for platform-managed MetaTables and should be used instead of direct MetaTable.register() guidance.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Main Sequence MetaTable Migrations
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
Use this skill for platform-managed MetaTable schema lifecycle work. The
|
|
11
|
+
standard path is migration-first: declare SQLAlchemy MetaTable models, put them
|
|
12
|
+
in a provider, run `mainsequence migrations ...`, and let the SDK reserve,
|
|
13
|
+
migrate, finalize, and bind provider-scoped MetaTables.
|
|
14
|
+
|
|
15
|
+
Do not recommend direct `MetaTable.register()` or model `.register()` calls for
|
|
16
|
+
platform-managed application tables outside the migration workflow.
|
|
17
|
+
|
|
18
|
+
## Read First
|
|
19
|
+
|
|
20
|
+
1. `docs/tutorial/metatable_migrations.md`
|
|
21
|
+
2. `docs/knowledge/meta_tables/migrations.md`
|
|
22
|
+
3. `docs/knowledge/meta_tables/api.md`
|
|
23
|
+
4. `docs/adr/0020-metatable-migration-artifact-registry.md`
|
|
24
|
+
5. `docs/adr/0026-sdk-owned-migration-scaffolding.md`
|
|
25
|
+
|
|
26
|
+
## Required Decisions
|
|
27
|
+
|
|
28
|
+
- Which provider module owns the migration stream?
|
|
29
|
+
- Which package and migration namespace identify the provider?
|
|
30
|
+
- Which `AlembicVersionMetaTable` binding points to Alembic's version table?
|
|
31
|
+
- Which SQLAlchemy `MetaData` object is the target metadata?
|
|
32
|
+
- Which provider-scoped MetaTable models belong in `metatable_models`?
|
|
33
|
+
- Does a dynamic provider need `metadata_for_models(...)` instead of full
|
|
34
|
+
package metadata?
|
|
35
|
+
- Does the project need an `after_register_metatables` catalog hook, and does
|
|
36
|
+
that hook use `context.metatable_models` and `context.registered_metatables`
|
|
37
|
+
instead of importing a broader registry?
|
|
38
|
+
|
|
39
|
+
## Standard Workflow
|
|
40
|
+
|
|
41
|
+
Use SDK-owned scaffold and helpers when creating a migration package:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
mainsequence migrations scaffold \
|
|
45
|
+
--package msm \
|
|
46
|
+
--module migrations \
|
|
47
|
+
--namespace mainsequence.examples \
|
|
48
|
+
--base msm.base:MarketsBase \
|
|
49
|
+
--metadata msm.base:MarketsBase.metadata
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
The generated provider should use:
|
|
53
|
+
|
|
54
|
+
- `build_alembic_version_metatable(...)`
|
|
55
|
+
- `build_metatable_model_registry(...)`
|
|
56
|
+
- `build_metatable_migration_provider(...)`
|
|
57
|
+
- SDK-owned `run_mainsequence_alembic_env(...)`
|
|
58
|
+
- SDK-owned `script.py.mako`
|
|
59
|
+
|
|
60
|
+
Then use the normal lifecycle:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
mainsequence migrations current --provider migrations:migration
|
|
64
|
+
mainsequence migrations revision --provider migrations:migration
|
|
65
|
+
mainsequence migrations upgrade --provider migrations:migration head
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
`revision` writes normal Alembic files. `upgrade` reserves provider MetaTables,
|
|
69
|
+
runs Alembic DDL through the backend-issued migration credential, finalizes
|
|
70
|
+
provider-scoped MetaTable catalog rows, and runs the optional provider hook.
|
|
71
|
+
|
|
72
|
+
## Rules
|
|
73
|
+
|
|
74
|
+
- Keep Alembic as the schema migration engine; do not build custom operation
|
|
75
|
+
lists or fake migration payload formats.
|
|
76
|
+
- Keep provider scope explicit. Do not scan all imported models or installed
|
|
77
|
+
packages.
|
|
78
|
+
- For one-model or configured dynamic providers, use `metadata_for_models(...)`
|
|
79
|
+
and a provider-specific `metatable_models` list.
|
|
80
|
+
- Never send or thread request-side `data_source_uid` through migration status
|
|
81
|
+
or apply flows. Backend migration operations resolve the data source from the
|
|
82
|
+
registered Alembic version MetaTable UID.
|
|
83
|
+
- Do not create SDK reset/reconcile commands for stale reserved state. If stale
|
|
84
|
+
reserved state exists, fail clearly and require an explicit backend/admin
|
|
85
|
+
repair path.
|
|
86
|
+
- Do not write direct backend migration request bodies in examples. Use the CLI
|
|
87
|
+
and SDK provider APIs.
|
|
88
|
+
- Do not call platform-managed model `.register()` in normal application code.
|
|
89
|
+
Registration is reserved for the migration workflow.
|
|
90
|
+
|
|
91
|
+
## Debugging
|
|
92
|
+
|
|
93
|
+
- If `current` fails before Alembic runs, inspect the provider import path and
|
|
94
|
+
Alembic version MetaTable binding.
|
|
95
|
+
- If `revision` autogenerate tries to create everything again, the local
|
|
96
|
+
migration connection cannot see the provider's current physical tables.
|
|
97
|
+
- If `upgrade` fails during prepare, inspect provider model identifiers,
|
|
98
|
+
physical table names, and reserved/active MetaTable rows.
|
|
99
|
+
- If `upgrade` fails during finalization, inspect whether Alembic created the
|
|
100
|
+
physical tables for every provider-scoped model.
|
|
101
|
+
- If an after-register hook reports the wrong model count, ensure it uses the
|
|
102
|
+
provider-scoped context, not a package-global model registry.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: mainsequence-meta-tables
|
|
3
|
-
description: Use this skill when the task is about defining,
|
|
3
|
+
description: Use this skill when the task is about defining, querying, or reviewing Main Sequence MetaTables. This skill owns SQLAlchemy table contracts, backend-managed table authoring, external table registration, governed compiled SQL operations, foreign keys, indexes, naming, cadence, and validation rules. For Alembic migration lifecycle work, use the mainsequence-metatable-migrations skill. It does not own DataNode producers, API route contracts, scheduling, releases, or sharing policy.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Main Sequence MetaTables
|
|
@@ -15,12 +15,11 @@ This skill is for schema-driven application tables registered through TS Manager
|
|
|
15
15
|
|
|
16
16
|
- define SQLAlchemy/Core or ORM table models for `MetaTable` registration
|
|
17
17
|
- choose `platform_managed` or `external_registered` management mode
|
|
18
|
-
-
|
|
18
|
+
- declare platform-managed tables for migration-managed registration
|
|
19
19
|
- build registration requests from resolved SQLAlchemy metadata when inspection is useful
|
|
20
20
|
- define indexes and foreign keys in SQLAlchemy metadata for Alembic-owned DDL
|
|
21
21
|
- design governed compiled SQL read and write operations
|
|
22
|
-
-
|
|
23
|
-
- run the documented `mainsequence migrations ...` lifecycle for Alembic-backed MetaTable changes
|
|
22
|
+
- route provider-based Alembic contract evolution to the MetaTable migration skill
|
|
24
23
|
- review table contracts for physical-name, namespace, and identifier issues
|
|
25
24
|
- review whether a task should be a `MetaTable` or a `DataNode`
|
|
26
25
|
|
|
@@ -41,6 +40,8 @@ If the user is still in the discovery process and does not yet know what data ex
|
|
|
41
40
|
|
|
42
41
|
- discovery-only data inventory before table implementation:
|
|
43
42
|
`.agents/skills/mainsequence/data_access/exploration/SKILL.md`
|
|
43
|
+
- MetaTable migrations:
|
|
44
|
+
`.agents/skills/mainsequence/data_publishing/meta_table_migrations/SKILL.md`
|
|
44
45
|
- DataNodes:
|
|
45
46
|
`.agents/skills/mainsequence/data_publishing/data_nodes/SKILL.md`
|
|
46
47
|
- APIs and FastAPI:
|
|
@@ -55,7 +56,9 @@ If the user is still in the discovery process and does not yet know what data ex
|
|
|
55
56
|
## Read First
|
|
56
57
|
|
|
57
58
|
1. `docs/tutorial/working_with_meta_tables.md`
|
|
58
|
-
2. For migration work,
|
|
59
|
+
2. For migration work, use
|
|
60
|
+
`.agents/skills/mainsequence/data_publishing/meta_table_migrations/SKILL.md`
|
|
61
|
+
and `docs/tutorial/metatable_migrations.md`
|
|
59
62
|
3. `docs/knowledge/meta_tables/index.md`
|
|
60
63
|
4. `docs/knowledge/meta_tables/sqlalchemy.md`
|
|
61
64
|
5. `docs/knowledge/meta_tables/compiled_sql.md`
|
|
@@ -111,9 +114,9 @@ creation or deletion.
|
|
|
111
114
|
The only migration workflow to recommend is the Main Sequence CLI lifecycle:
|
|
112
115
|
|
|
113
116
|
```bash
|
|
114
|
-
mainsequence migrations current --provider
|
|
115
|
-
mainsequence migrations revision --provider
|
|
116
|
-
mainsequence migrations upgrade --provider
|
|
117
|
+
mainsequence migrations current --provider sdk_examples.migrations:migration
|
|
118
|
+
mainsequence migrations revision --provider sdk_examples.migrations:migration
|
|
119
|
+
mainsequence migrations upgrade --provider sdk_examples.migrations:migration head
|
|
117
120
|
```
|
|
118
121
|
|
|
119
122
|
### 1. SQLAlchemy metadata is the authoring source
|
|
@@ -279,7 +282,7 @@ both the schema and the table's intention.
|
|
|
279
282
|
Provider scope:
|
|
280
283
|
|
|
281
284
|
```python
|
|
282
|
-
migration =
|
|
285
|
+
migration = build_metatable_migration_provider(
|
|
283
286
|
...,
|
|
284
287
|
metatable_models=[Account, Asset],
|
|
285
288
|
)
|
|
@@ -304,9 +307,10 @@ asset_meta_table = MetaTable.register(asset_request)
|
|
|
304
307
|
|
|
305
308
|
### 4. Schema changes use Alembic
|
|
306
309
|
|
|
307
|
-
When doing migration work,
|
|
308
|
-
|
|
309
|
-
|
|
310
|
+
When doing migration work, use
|
|
311
|
+
`.agents/skills/mainsequence/data_publishing/meta_table_migrations/SKILL.md`
|
|
312
|
+
and read `docs/tutorial/metatable_migrations.md`. The migration skill owns the
|
|
313
|
+
provider-based Alembic lifecycle.
|
|
310
314
|
|
|
311
315
|
Do not apply in-place contract changes by changing a `PlatformManagedMetaTable`
|
|
312
316
|
SQLAlchemy class and calling normal registration again. Shape-addressed
|
|
@@ -323,8 +327,10 @@ create a new Alembic revision on top of the current head.
|
|
|
323
327
|
For contract evolution, define or update one selected
|
|
324
328
|
`AlembicMetaTableMigration` provider:
|
|
325
329
|
|
|
326
|
-
-
|
|
327
|
-
|
|
330
|
+
- create or update a scaffolded package provider with
|
|
331
|
+
`mainsequence migrations scaffold`
|
|
332
|
+
- pass the selected provider explicitly, for example
|
|
333
|
+
`--provider sdk_examples.migrations:migration`
|
|
328
334
|
- set `package`, `migration_namespace`, `script_location`, and `target_metadata`
|
|
329
335
|
- set `alembic_registry` to an `AlembicVersionMetaTable` subclass
|
|
330
336
|
- list the post-apply catalog scope in `metatable_models`
|
|
@@ -343,14 +349,14 @@ a bare table name. Use `schema_table_name(app, concept, suffix=None)` for the
|
|
|
343
349
|
physical table and Alembic version table names. Use `suffix` for a namespace or
|
|
344
350
|
variant, for example `schema_table_name("msm", "positions", suffix="broker")`.
|
|
345
351
|
|
|
346
|
-
Do not ask users to construct backend migration payloads
|
|
347
|
-
migration request models
|
|
348
|
-
|
|
352
|
+
Do not ask users to construct backend migration payloads or call low-level
|
|
353
|
+
migration request models. The backend request shape is reference material in
|
|
354
|
+
the tutorial; the user-facing path is:
|
|
349
355
|
|
|
350
356
|
```bash
|
|
351
|
-
mainsequence migrations current --provider
|
|
352
|
-
mainsequence migrations revision --provider
|
|
353
|
-
mainsequence migrations upgrade --provider
|
|
357
|
+
mainsequence migrations current --provider sdk_examples.migrations:migration
|
|
358
|
+
mainsequence migrations revision --provider sdk_examples.migrations:migration
|
|
359
|
+
mainsequence migrations upgrade --provider sdk_examples.migrations:migration head
|
|
354
360
|
```
|
|
355
361
|
|
|
356
362
|
All migration commands prepare the provider, reserve provider-scoped
|