mainsequence 4.3.19__tar.gz → 4.3.22__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.19/mainsequence.egg-info → mainsequence-4.3.22}/PKG-INFO +1 -1
- {mainsequence-4.3.19 → mainsequence-4.3.22}/agent_scaffold/skills/data_publishing/data_nodes/SKILL.md +82 -4
- {mainsequence-4.3.19 → mainsequence-4.3.22}/agent_scaffold/skills/data_publishing/meta_tables/SKILL.md +20 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/cli/cli.py +60 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/client/metatables/core.py +73 -4
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/client/models_foundry.py +10 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22/mainsequence.egg-info}/PKG-INFO +1 -1
- {mainsequence-4.3.19 → mainsequence-4.3.22}/pyproject.toml +1 -1
- {mainsequence-4.3.19 → mainsequence-4.3.22}/tests/test_cli.py +53 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/tests/test_meta_tables_client_models.py +138 -1
- {mainsequence-4.3.19 → mainsequence-4.3.22}/LICENSE +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/README.md +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/agent_scaffold/AGENTS.md +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/agent_scaffold/skills/a2a_communication/SKILL.md +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/agent_scaffold/skills/application_surfaces/api_surfaces/SKILL.md +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/agent_scaffold/skills/command_center/adapter_from_api/SKILL.md +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/agent_scaffold/skills/command_center/api_mock_prototyping/SKILL.md +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/agent_scaffold/skills/command_center/app_components/SKILL.md +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/agent_scaffold/skills/command_center/connections/SKILL.md +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/agent_scaffold/skills/command_center/workspace_analysis/SKILL.md +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/agent_scaffold/skills/command_center/workspace_builder/SKILL.md +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/agent_scaffold/skills/command_center/workspace_design/SKILL.md +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/agent_scaffold/skills/dashboards/streamlit/SKILL.md +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/agent_scaffold/skills/data_access/exploration/SKILL.md +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/agent_scaffold/skills/data_publishing/meta_table_migrations/SKILL.md +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/agent_scaffold/skills/maintenance/bug_auditor/SKILL.md +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/agent_scaffold/skills/ms-markets/SKILL.md +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/agent_scaffold/skills/platform_operations/access_control_and_sharing/SKILL.md +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/agent_scaffold/skills/platform_operations/orchestration_and_releases/SKILL.md +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/agent_scaffold/skills/project_builder/SKILL.md +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/agent_scaffold/skills/project_to_agent/SKILL.md +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/__init__.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/__main__.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/bootstrap.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/cli/__init__.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/cli/api.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/cli/browser_auth.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/cli/config.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/cli/docker_utils.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/cli/doctor.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/cli/local_ops.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/cli/migrations.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/cli/model_filters.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/cli/project_status.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/cli/pydantic_cli.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/cli/sdk_utils.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/cli/ssh_utils.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/cli/ui.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/client/__init__.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/client/agent_runtime_models.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/client/base.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/client/client.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/client/command_center/__init__.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/client/command_center/app_component.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/client/command_center/connections.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/client/command_center/data_models.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/client/command_center/workspace.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/client/command_center/workspace_snapshot.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/client/compute_validation.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/client/data_sources_interfaces/__init__.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/client/data_sources_interfaces/duckdb.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/client/data_sources_interfaces/local_paths.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/client/data_sources_interfaces/sqlite.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/client/dtype_codec.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/client/exceptions.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/client/fastapi/__init__.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/client/fastapi/auth.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/client/metatables/__init__.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/client/models_helpers.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/client/models_user.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/client/utils.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/defaults.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/instrumentation/__init__.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/instrumentation/utils.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/logconf.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/meta_tables/__init__.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/meta_tables/__main__.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/meta_tables/compiled_sql/__init__.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/meta_tables/compiled_sql/v1.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/meta_tables/data_nodes/__init__.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/meta_tables/data_nodes/build_operations.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/meta_tables/data_nodes/data_nodes.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/meta_tables/data_nodes/models.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/meta_tables/data_nodes/namespacing.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/meta_tables/data_nodes/persist_managers.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/meta_tables/data_nodes/run_operations.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/meta_tables/data_nodes/utils.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/meta_tables/future_registry.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/meta_tables/hashing.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/meta_tables/migrations/__init__.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/meta_tables/migrations/alembic.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/meta_tables/migrations/env.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/meta_tables/migrations/provider.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/meta_tables/migrations/registry.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/meta_tables/migrations/scaffold.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/meta_tables/migrations/templates/__init__.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/meta_tables/migrations/templates/env.py.mako +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/meta_tables/migrations/templates/script.py.mako +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/meta_tables/pydantic_metadata.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/meta_tables/schema_names.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/meta_tables/sqlalchemy_contracts.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/runtime_flags.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence.egg-info/SOURCES.txt +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence.egg-info/dependency_links.txt +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence.egg-info/entry_points.txt +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence.egg-info/requires.txt +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence.egg-info/top_level.txt +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/setup.cfg +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/tests/test_auth_precedence.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/tests/test_build_operations_hashing.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/tests/test_cli_browser_auth.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/tests/test_cli_migrations.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/tests/test_client.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/tests/test_command_center_app_component_models.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/tests/test_command_center_data_models.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/tests/test_command_center_models.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/tests/test_data_access_mixin_dimension_audit.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/tests/test_data_node_storage_dimension_queries.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/tests/test_data_node_update_flow.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/tests/test_dependency_extras.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/tests/test_duckdb_interface_dimensions.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/tests/test_filter_normalization.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/tests/test_instrumentation.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/tests/test_logconf.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/tests/test_meta_table_migrations.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/tests/test_meta_tables_sqlalchemy_contracts.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/tests/test_models_user_request_bound_auth.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/tests/test_pod_project_resolution.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/tests/test_project_batch_jobs_from_file.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/tests/test_run_configuration.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/tests/test_schema_names.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/tests/test_secret_client_model.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/tests/test_source_table_configuration.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/tests/test_sqlite_interface_dimensions.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/tests/test_update_runner_uid_runtime.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/tests/test_update_statistics.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/tests/test_update_uid_guards.py +0 -0
- {mainsequence-4.3.19 → mainsequence-4.3.22}/tests/test_workspace_snapshot.py +0 -0
|
@@ -335,7 +335,80 @@ Use `UpdateStatistics`.
|
|
|
335
335
|
Do not fetch or return full history every run unless there is a documented
|
|
336
336
|
reason.
|
|
337
337
|
|
|
338
|
-
### 6.
|
|
338
|
+
### 6. DataNode Tail Deletes Must Use `delete_after_date(...)`
|
|
339
|
+
|
|
340
|
+
When a DataNode workflow needs to remove persisted rows from its
|
|
341
|
+
`PlatformTimeIndexMetaTable` storage table, use
|
|
342
|
+
`TimeIndexMetaTable.delete_after_date(...)`. This is the only normal DataNode
|
|
343
|
+
storage deletion path.
|
|
344
|
+
|
|
345
|
+
Do not use raw SQL, compiled SQL operations, direct database clients,
|
|
346
|
+
`run_query(...)`, backend-private endpoints, table truncation, or ad hoc
|
|
347
|
+
delete helpers to clean DataNode storage rows.
|
|
348
|
+
|
|
349
|
+
The SDK call targets:
|
|
350
|
+
|
|
351
|
+
```text
|
|
352
|
+
POST /orm/api/ts_manager/dynamic_table/<dynamic_table_uid>/delete_after_date/
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
Use a global tail delete only when all streams in the table should be rolled
|
|
356
|
+
back from the same inclusive cutoff:
|
|
357
|
+
|
|
358
|
+
```python
|
|
359
|
+
storage = MyStorageTable.get_time_index_meta_table()
|
|
360
|
+
storage.delete_after_date("2026-04-01T00:00:00Z")
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
For multidimensional storage, prefer an explicit scope. Use
|
|
364
|
+
`dimension_filters` when deleting all rows for one or more dimension values:
|
|
365
|
+
|
|
366
|
+
```python
|
|
367
|
+
storage.delete_after_date(
|
|
368
|
+
"2026-04-01T00:00:00Z",
|
|
369
|
+
dimension_filters={
|
|
370
|
+
"asset_identifier": ["example-asset-btc", "example-asset-eth"],
|
|
371
|
+
},
|
|
372
|
+
)
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
Use `index_coordinates` when deleting exact coordinate streams:
|
|
376
|
+
|
|
377
|
+
```python
|
|
378
|
+
storage.delete_after_date(
|
|
379
|
+
"2026-04-01T00:00:00Z",
|
|
380
|
+
index_coordinates=[
|
|
381
|
+
{
|
|
382
|
+
"account_uid": "account-a",
|
|
383
|
+
"asset_identifier": "example-asset-btc",
|
|
384
|
+
}
|
|
385
|
+
],
|
|
386
|
+
)
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
Deleting all rows for scoped streams is allowed only with an explicit scope:
|
|
390
|
+
|
|
391
|
+
```python
|
|
392
|
+
storage.delete_after_date(
|
|
393
|
+
None,
|
|
394
|
+
dimension_filters={"asset_identifier": ["example-asset-btc"]},
|
|
395
|
+
)
|
|
396
|
+
|
|
397
|
+
storage.delete_after_date(
|
|
398
|
+
None,
|
|
399
|
+
index_coordinates=[
|
|
400
|
+
{
|
|
401
|
+
"account_uid": "account-a",
|
|
402
|
+
"asset_identifier": "example-asset-btc",
|
|
403
|
+
}
|
|
404
|
+
],
|
|
405
|
+
)
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
Never send `after_date=None` without `dimension_filters` or
|
|
409
|
+
`index_coordinates`. That is an unbounded table delete and must be rejected.
|
|
410
|
+
|
|
411
|
+
### 7. `time_index` Must Be Nanosecond UTC
|
|
339
412
|
|
|
340
413
|
Every non-empty DataFrame returned by `update()` must have its first index
|
|
341
414
|
level named `time_index` with dtype exactly `datetime64[ns, UTC]`.
|
|
@@ -386,7 +459,7 @@ physical schema evolution. Keep the `PlatformTimeIndexMetaTable` catalog model a
|
|
|
386
459
|
the SDK storage contract, apply Alembic-rendered SQL through the migration
|
|
387
460
|
workflow, then register or refresh the MetaTable catalog binding separately.
|
|
388
461
|
|
|
389
|
-
###
|
|
462
|
+
### 8. Dependencies Must Be Deterministic
|
|
390
463
|
|
|
391
464
|
Dependencies belong in constructor setup and `dependencies()`.
|
|
392
465
|
|
|
@@ -395,7 +468,7 @@ changing it changes the dependency graph and update identity.
|
|
|
395
468
|
|
|
396
469
|
Do not construct dependency graphs dynamically inside `update()`.
|
|
397
470
|
|
|
398
|
-
###
|
|
471
|
+
### 9. Foreign Keys Belong To SQLAlchemy And Alembic
|
|
399
472
|
|
|
400
473
|
For new code, model foreign keys on the `PlatformTimeIndexMetaTable` storage
|
|
401
474
|
class, or route the storage work to the MetaTable skill. When a DataNode storage
|
|
@@ -416,7 +489,7 @@ binding after upgrade.
|
|
|
416
489
|
|
|
417
490
|
Do not add DataNode configuration fields just to mutate storage metadata.
|
|
418
491
|
|
|
419
|
-
###
|
|
492
|
+
### 10. Metadata Belongs To Storage
|
|
420
493
|
|
|
421
494
|
Production-quality table identifiers, descriptions, labels, column docs, and
|
|
422
495
|
foreign-key metadata belong to the storage class/MetaTable registration path.
|
|
@@ -444,6 +517,8 @@ When reviewing an existing DataNode, look for:
|
|
|
444
517
|
- misuse of `hash_namespace`
|
|
445
518
|
- non-incremental `update()` behavior
|
|
446
519
|
- hidden dependency creation inside `update()`
|
|
520
|
+
- DataNode storage cleanup that bypasses `TimeIndexMetaTable.delete_after_date(...)`
|
|
521
|
+
- `delete_after_date(None)` without explicit `dimension_filters` or `index_coordinates`
|
|
447
522
|
- invalid identity-indexed output shape
|
|
448
523
|
- `time_index` dtype that is not exactly `datetime64[ns, UTC]`
|
|
449
524
|
- DataFrame columns that do not match the `PlatformTimeIndexMetaTable` class
|
|
@@ -464,6 +539,9 @@ Do not claim success until you have checked:
|
|
|
464
539
|
- no `test_node` usage remains
|
|
465
540
|
- `dependencies()` is deterministic
|
|
466
541
|
- `update()` is incremental
|
|
542
|
+
- DataNode storage deletion, rollback, and repair paths use
|
|
543
|
+
`TimeIndexMetaTable.delete_after_date(...)`
|
|
544
|
+
- unbounded deletes with `after_date=None` and no dimension/coordinate scope are absent
|
|
467
545
|
- the DataFrame shape matches the storage class
|
|
468
546
|
- non-empty outputs have first index level `time_index` with dtype `datetime64[ns, UTC]`
|
|
469
547
|
- the first validation run uses explicit `hash_namespace(...)` when it touches a shared backend
|
|
@@ -387,6 +387,24 @@ Only use physical table names returned by registered `MetaTable` objects when co
|
|
|
387
387
|
|
|
388
388
|
Do not hardcode platform-managed physical names manually.
|
|
389
389
|
|
|
390
|
+
### 7. DataNode storage deletes use the DataNode tail-delete API
|
|
391
|
+
|
|
392
|
+
For `PlatformTimeIndexMetaTable` storage owned by DataNodes, do not design raw
|
|
393
|
+
SQL delete operations or compiled SQL delete operations for rollback, repair, or
|
|
394
|
+
stream cleanup. Route that work to the DataNode skill and use
|
|
395
|
+
`TimeIndexMetaTable.delete_after_date(...)`.
|
|
396
|
+
|
|
397
|
+
The DataNode delete path is:
|
|
398
|
+
|
|
399
|
+
```text
|
|
400
|
+
POST /orm/api/ts_manager/dynamic_table/<dynamic_table_uid>/delete_after_date/
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
Use `after_date` for global tail rollback. Use `dimension_filters` or
|
|
404
|
+
`index_coordinates` for scoped deletes, including scoped full-stream deletes
|
|
405
|
+
where `after_date=None`. Never allow `after_date=None` without an explicit
|
|
406
|
+
dimension or coordinate scope.
|
|
407
|
+
|
|
390
408
|
## Review Rules
|
|
391
409
|
|
|
392
410
|
When reviewing an existing MetaTable workflow, look for:
|
|
@@ -406,6 +424,8 @@ When reviewing an existing MetaTable workflow, look for:
|
|
|
406
424
|
- migration work that asks users to define backend payloads, artifact rows, or SDK request objects
|
|
407
425
|
- compiled SQL operations without complete table scope
|
|
408
426
|
- raw SQL that hardcodes stale physical names
|
|
427
|
+
- raw SQL or compiled SQL deletes against DataNode-owned
|
|
428
|
+
`PlatformTimeIndexMetaTable` storage instead of `delete_after_date(...)`
|
|
409
429
|
- a table that should really be modeled as a DataNode instead
|
|
410
430
|
|
|
411
431
|
## Validation Checklist
|
|
@@ -11450,6 +11450,66 @@ def project_sync(
|
|
|
11450
11450
|
success(f"Synced: {repo_name}")
|
|
11451
11451
|
|
|
11452
11452
|
|
|
11453
|
+
@project.command("sync-after-commit")
|
|
11454
|
+
def project_sync_after_commit(
|
|
11455
|
+
project_uid: str | None = typer.Argument(
|
|
11456
|
+
None,
|
|
11457
|
+
help="Project UID. If omitted, read MAIN_SEQUENCE_PROJECT_UID from local .env.",
|
|
11458
|
+
),
|
|
11459
|
+
path: str | None = typer.Option(
|
|
11460
|
+
None,
|
|
11461
|
+
"--path",
|
|
11462
|
+
help="Project directory used to resolve MAIN_SEQUENCE_PROJECT_UID when PROJECT_UID is omitted.",
|
|
11463
|
+
),
|
|
11464
|
+
timeout: int | None = typer.Option(None, "--timeout", help="Request timeout in seconds."),
|
|
11465
|
+
):
|
|
11466
|
+
"""
|
|
11467
|
+
Trigger backend post-commit project sync.
|
|
11468
|
+
|
|
11469
|
+
This directly calls:
|
|
11470
|
+
|
|
11471
|
+
POST /orm/api/pods/projects/<project_uid>/sync_project_after_commit/
|
|
11472
|
+
|
|
11473
|
+
Examples
|
|
11474
|
+
--------
|
|
11475
|
+
```bash
|
|
11476
|
+
mainsequence project sync-after-commit project-uid-123
|
|
11477
|
+
mainsequence project sync-after-commit --path .
|
|
11478
|
+
```
|
|
11479
|
+
"""
|
|
11480
|
+
_require_login()
|
|
11481
|
+
|
|
11482
|
+
resolved_project_uid = project_uid
|
|
11483
|
+
if resolved_project_uid is None:
|
|
11484
|
+
project_dir = normalize_path(path) if path else pathlib.Path.cwd()
|
|
11485
|
+
if path and not project_dir.exists():
|
|
11486
|
+
error(f"Folder does not exist: {project_dir}")
|
|
11487
|
+
raise typer.Exit(1)
|
|
11488
|
+
resolved_project_uid = _read_project_ref_from_env_file(project_dir)
|
|
11489
|
+
|
|
11490
|
+
if resolved_project_uid is None:
|
|
11491
|
+
error(
|
|
11492
|
+
"Could not determine project uid. Pass PROJECT_UID or ensure "
|
|
11493
|
+
"MAIN_SEQUENCE_PROJECT_UID is present in local .env."
|
|
11494
|
+
)
|
|
11495
|
+
raise typer.Exit(1)
|
|
11496
|
+
|
|
11497
|
+
try:
|
|
11498
|
+
payload = sync_project_after_commit(resolved_project_uid, timeout=timeout)
|
|
11499
|
+
except ApiError as e:
|
|
11500
|
+
error(f"Backend post-commit sync failed: {e}")
|
|
11501
|
+
raise typer.Exit(1) from e
|
|
11502
|
+
|
|
11503
|
+
result = payload or {
|
|
11504
|
+
"project_uid": resolved_project_uid,
|
|
11505
|
+
"detail": "sync_project_after_commit triggered",
|
|
11506
|
+
}
|
|
11507
|
+
if _emit_json(result):
|
|
11508
|
+
return
|
|
11509
|
+
|
|
11510
|
+
success(f"Triggered backend sync for project {resolved_project_uid}.")
|
|
11511
|
+
|
|
11512
|
+
|
|
11453
11513
|
@project.command("sync_project", hidden=True)
|
|
11454
11514
|
def project_sync_project(
|
|
11455
11515
|
message: str = typer.Argument(..., help="Git commit message"),
|
|
@@ -500,9 +500,17 @@ class MetaTableOperationScope(BasePydanticModel):
|
|
|
500
500
|
return self
|
|
501
501
|
|
|
502
502
|
|
|
503
|
+
DEFAULT_META_TABLE_OPERATION_MAX_ROWS = 10_000
|
|
504
|
+
DEFAULT_META_TABLE_OPERATION_STATEMENT_TIMEOUT_MS = 60_000
|
|
505
|
+
|
|
506
|
+
|
|
503
507
|
class MetaTableOperationLimits(BasePydanticModel):
|
|
504
|
-
max_rows: int
|
|
505
|
-
|
|
508
|
+
max_rows: int = Field(default=DEFAULT_META_TABLE_OPERATION_MAX_ROWS, ge=1)
|
|
509
|
+
offset: int = Field(default=0, ge=0)
|
|
510
|
+
statement_timeout_ms: int = Field(
|
|
511
|
+
default=DEFAULT_META_TABLE_OPERATION_STATEMENT_TIMEOUT_MS,
|
|
512
|
+
ge=1,
|
|
513
|
+
)
|
|
506
514
|
|
|
507
515
|
|
|
508
516
|
class MetaTableCompiledSQLOperation(BasePydanticModel):
|
|
@@ -511,7 +519,12 @@ class MetaTableCompiledSQLOperation(BasePydanticModel):
|
|
|
511
519
|
dialect: MetaTableCompiledSQLDialect = "postgresql"
|
|
512
520
|
statement: MetaTableStatementPayload
|
|
513
521
|
scope: MetaTableOperationScope
|
|
514
|
-
limits: MetaTableOperationLimits
|
|
522
|
+
limits: MetaTableOperationLimits = Field(default_factory=MetaTableOperationLimits)
|
|
523
|
+
|
|
524
|
+
@field_validator("limits", mode="before")
|
|
525
|
+
@classmethod
|
|
526
|
+
def default_limits(cls, value):
|
|
527
|
+
return {} if value is None else value
|
|
515
528
|
|
|
516
529
|
|
|
517
530
|
class MetaTableRequestFields(BasePydanticModel):
|
|
@@ -1704,12 +1717,68 @@ class MetaTable(BasePydanticModel, LabelableObjectMixin, ShareableObjectMixin, B
|
|
|
1704
1717
|
if isinstance(operation, MetaTableCompiledSQLOperation)
|
|
1705
1718
|
else MetaTableCompiledSQLOperation(**operation)
|
|
1706
1719
|
)
|
|
1707
|
-
|
|
1720
|
+
response = cls._post_action(
|
|
1708
1721
|
"execute-operation",
|
|
1709
1722
|
payload,
|
|
1710
1723
|
timeout=timeout,
|
|
1711
1724
|
expected_statuses=(200,),
|
|
1712
1725
|
)
|
|
1726
|
+
if payload.operation != "select":
|
|
1727
|
+
return response
|
|
1728
|
+
|
|
1729
|
+
rows = response.get("rows")
|
|
1730
|
+
if not isinstance(rows, list):
|
|
1731
|
+
return response
|
|
1732
|
+
|
|
1733
|
+
requested_max_rows = payload.limits.max_rows
|
|
1734
|
+
if len(rows) >= requested_max_rows:
|
|
1735
|
+
return response
|
|
1736
|
+
|
|
1737
|
+
pagination = response.get("pagination") or {}
|
|
1738
|
+
has_more = bool(pagination.get("has_more"))
|
|
1739
|
+
next_offset = pagination.get("next_offset")
|
|
1740
|
+
if not has_more or next_offset in (None, ""):
|
|
1741
|
+
return response
|
|
1742
|
+
|
|
1743
|
+
accumulated_rows = list(rows)
|
|
1744
|
+
last_pagination = pagination
|
|
1745
|
+
while (
|
|
1746
|
+
has_more
|
|
1747
|
+
and next_offset not in (None, "")
|
|
1748
|
+
and len(accumulated_rows) < requested_max_rows
|
|
1749
|
+
):
|
|
1750
|
+
remaining_rows = requested_max_rows - len(accumulated_rows)
|
|
1751
|
+
next_payload = payload.model_copy(deep=True)
|
|
1752
|
+
next_payload.limits.offset = int(next_offset)
|
|
1753
|
+
next_payload.limits.max_rows = remaining_rows
|
|
1754
|
+
page_response = cls._post_action(
|
|
1755
|
+
"execute-operation",
|
|
1756
|
+
next_payload,
|
|
1757
|
+
timeout=timeout,
|
|
1758
|
+
expected_statuses=(200,),
|
|
1759
|
+
)
|
|
1760
|
+
page_rows = page_response.get("rows") or []
|
|
1761
|
+
if not isinstance(page_rows, list) or not page_rows:
|
|
1762
|
+
last_pagination = page_response.get("pagination") or {}
|
|
1763
|
+
break
|
|
1764
|
+
|
|
1765
|
+
accumulated_rows.extend(page_rows[:remaining_rows])
|
|
1766
|
+
last_pagination = page_response.get("pagination") or {}
|
|
1767
|
+
has_more = bool(last_pagination.get("has_more"))
|
|
1768
|
+
next_offset = last_pagination.get("next_offset")
|
|
1769
|
+
|
|
1770
|
+
response["rows"] = accumulated_rows
|
|
1771
|
+
response["row_count"] = len(accumulated_rows)
|
|
1772
|
+
response["max_rows"] = requested_max_rows
|
|
1773
|
+
response["truncated"] = bool(last_pagination.get("has_more"))
|
|
1774
|
+
response["pagination"] = {
|
|
1775
|
+
"limit": requested_max_rows,
|
|
1776
|
+
"offset": payload.limits.offset,
|
|
1777
|
+
"returned_count": len(accumulated_rows),
|
|
1778
|
+
"has_more": bool(last_pagination.get("has_more")),
|
|
1779
|
+
"next_offset": last_pagination.get("next_offset"),
|
|
1780
|
+
}
|
|
1781
|
+
return response
|
|
1713
1782
|
|
|
1714
1783
|
|
|
1715
1784
|
# Global executor (or you could define one on your class)
|
|
@@ -183,6 +183,16 @@ class Project(LabelableObjectMixin, ShareableObjectMixin, BasePydanticModel, Bas
|
|
|
183
183
|
examples=["git@github.com:mainsequence/data-pipeline.git"],
|
|
184
184
|
json_schema_extra={"label": "Git SSH URL"},
|
|
185
185
|
)
|
|
186
|
+
latest_git_version: str = Field(
|
|
187
|
+
"",
|
|
188
|
+
title="Latest Git Version",
|
|
189
|
+
description=(
|
|
190
|
+
"Normalized highest valid version extracted from repository tags for the "
|
|
191
|
+
"project's configured branch. Empty when the backend has not found a valid version."
|
|
192
|
+
),
|
|
193
|
+
examples=["1.2.3"],
|
|
194
|
+
json_schema_extra={"label": "Latest Git Version"},
|
|
195
|
+
)
|
|
186
196
|
created_by: str | int | dict[str, Any] | None = Field(
|
|
187
197
|
None,
|
|
188
198
|
title="Created By",
|
|
@@ -10294,6 +10294,59 @@ def test_project_sync_triggers_backend_sync_after_push(cli_mod, runner, monkeypa
|
|
|
10294
10294
|
assert "Triggered backend sync for project project-uid-123." in result.output
|
|
10295
10295
|
|
|
10296
10296
|
|
|
10297
|
+
def test_project_sync_after_commit_uses_project_uid(cli_mod, runner, monkeypatch):
|
|
10298
|
+
captured = {}
|
|
10299
|
+
|
|
10300
|
+
monkeypatch.setattr(cli_mod, "_require_login", lambda: {"username": "u"})
|
|
10301
|
+
monkeypatch.setattr(
|
|
10302
|
+
cli_mod,
|
|
10303
|
+
"sync_project_after_commit",
|
|
10304
|
+
lambda project_uid, timeout=None: captured.update(
|
|
10305
|
+
project_uid=project_uid,
|
|
10306
|
+
timeout=timeout,
|
|
10307
|
+
)
|
|
10308
|
+
or {"uid": project_uid},
|
|
10309
|
+
)
|
|
10310
|
+
|
|
10311
|
+
result = runner.invoke(
|
|
10312
|
+
cli_mod.app,
|
|
10313
|
+
["project", "sync-after-commit", "project-uid-123", "--timeout", "30"],
|
|
10314
|
+
)
|
|
10315
|
+
|
|
10316
|
+
assert result.exit_code == 0
|
|
10317
|
+
assert captured == {"project_uid": "project-uid-123", "timeout": 30}
|
|
10318
|
+
assert "Triggered backend sync for project project-uid-123." in result.output
|
|
10319
|
+
|
|
10320
|
+
|
|
10321
|
+
def test_project_sync_after_commit_reads_project_uid_from_env_file(
|
|
10322
|
+
cli_mod, runner, monkeypatch, tmp_path
|
|
10323
|
+
):
|
|
10324
|
+
target = tmp_path / "project"
|
|
10325
|
+
target.mkdir()
|
|
10326
|
+
(target / ".env").write_text("MAIN_SEQUENCE_PROJECT_UID=project-uid-123\n", encoding="utf-8")
|
|
10327
|
+
|
|
10328
|
+
monkeypatch.setattr(cli_mod, "_require_login", lambda: {"username": "u"})
|
|
10329
|
+
monkeypatch.setattr(
|
|
10330
|
+
cli_mod,
|
|
10331
|
+
"sync_project_after_commit",
|
|
10332
|
+
lambda project_uid, timeout=None: {
|
|
10333
|
+
"project_uid": project_uid,
|
|
10334
|
+
"status": "queued",
|
|
10335
|
+
},
|
|
10336
|
+
)
|
|
10337
|
+
|
|
10338
|
+
result = runner.invoke(
|
|
10339
|
+
cli_mod.app,
|
|
10340
|
+
["project", "sync-after-commit", "--path", str(target), "--json"],
|
|
10341
|
+
)
|
|
10342
|
+
|
|
10343
|
+
assert result.exit_code == 0
|
|
10344
|
+
assert json.loads(result.output) == {
|
|
10345
|
+
"project_uid": "project-uid-123",
|
|
10346
|
+
"status": "queued",
|
|
10347
|
+
}
|
|
10348
|
+
|
|
10349
|
+
|
|
10297
10350
|
def test_project_sync_project(cli_mod, runner, monkeypatch, tmp_path):
|
|
10298
10351
|
target = tmp_path / "project"
|
|
10299
10352
|
target.mkdir(parents=True, exist_ok=True)
|
|
@@ -410,6 +410,118 @@ def test_meta_table_execute_operation_serializes_scope_uid(monkeypatch):
|
|
|
410
410
|
assert captured["payload"]["json"]["statement"]["parameters"] == {
|
|
411
411
|
"symbol_1": "%BTC%",
|
|
412
412
|
}
|
|
413
|
+
assert captured["payload"]["json"]["limits"]["offset"] == 0
|
|
414
|
+
|
|
415
|
+
|
|
416
|
+
def test_meta_table_execute_operation_fetches_requested_rows_with_backend_pagination(
|
|
417
|
+
monkeypatch,
|
|
418
|
+
):
|
|
419
|
+
calls = []
|
|
420
|
+
|
|
421
|
+
def fake_make_request(**kwargs):
|
|
422
|
+
payload = kwargs["payload"]["json"]
|
|
423
|
+
calls.append(payload)
|
|
424
|
+
offset = payload["limits"]["offset"]
|
|
425
|
+
if offset == 0:
|
|
426
|
+
return _Response(
|
|
427
|
+
{
|
|
428
|
+
"ok": True,
|
|
429
|
+
"operation": "select",
|
|
430
|
+
"dialect": "postgresql",
|
|
431
|
+
"row_count": 2,
|
|
432
|
+
"rows": [{"value": 1}, {"value": 2}],
|
|
433
|
+
"truncated": True,
|
|
434
|
+
"max_rows": 2,
|
|
435
|
+
"pagination": {
|
|
436
|
+
"limit": 2,
|
|
437
|
+
"offset": 0,
|
|
438
|
+
"returned_count": 2,
|
|
439
|
+
"has_more": True,
|
|
440
|
+
"next_offset": 2,
|
|
441
|
+
},
|
|
442
|
+
}
|
|
443
|
+
)
|
|
444
|
+
if offset == 2:
|
|
445
|
+
return _Response(
|
|
446
|
+
{
|
|
447
|
+
"ok": True,
|
|
448
|
+
"operation": "select",
|
|
449
|
+
"dialect": "postgresql",
|
|
450
|
+
"row_count": 2,
|
|
451
|
+
"rows": [{"value": 3}, {"value": 4}],
|
|
452
|
+
"truncated": True,
|
|
453
|
+
"max_rows": 2,
|
|
454
|
+
"pagination": {
|
|
455
|
+
"limit": 2,
|
|
456
|
+
"offset": 2,
|
|
457
|
+
"returned_count": 2,
|
|
458
|
+
"has_more": True,
|
|
459
|
+
"next_offset": 4,
|
|
460
|
+
},
|
|
461
|
+
}
|
|
462
|
+
)
|
|
463
|
+
return _Response(
|
|
464
|
+
{
|
|
465
|
+
"ok": True,
|
|
466
|
+
"operation": "select",
|
|
467
|
+
"dialect": "postgresql",
|
|
468
|
+
"row_count": 1,
|
|
469
|
+
"rows": [{"value": 5}],
|
|
470
|
+
"truncated": False,
|
|
471
|
+
"max_rows": 1,
|
|
472
|
+
"pagination": {
|
|
473
|
+
"limit": 1,
|
|
474
|
+
"offset": 4,
|
|
475
|
+
"returned_count": 1,
|
|
476
|
+
"has_more": False,
|
|
477
|
+
"next_offset": None,
|
|
478
|
+
},
|
|
479
|
+
}
|
|
480
|
+
)
|
|
481
|
+
|
|
482
|
+
monkeypatch.setattr(meta_table_models, "make_request", fake_make_request)
|
|
483
|
+
monkeypatch.setattr(
|
|
484
|
+
meta_table_models.MetaTable,
|
|
485
|
+
"build_session",
|
|
486
|
+
classmethod(lambda cls: SimpleNamespace(headers={})),
|
|
487
|
+
)
|
|
488
|
+
|
|
489
|
+
result = meta_table_models.MetaTable.execute_operation(
|
|
490
|
+
{
|
|
491
|
+
"operation": "select",
|
|
492
|
+
"statement": {
|
|
493
|
+
"sql": "SELECT value FROM public.asset ORDER BY value",
|
|
494
|
+
"parameters": {},
|
|
495
|
+
},
|
|
496
|
+
"scope": {
|
|
497
|
+
"data_source_uid": "dddddddd-dddd-4ddd-8ddd-dddddddddddd",
|
|
498
|
+
"tables": [
|
|
499
|
+
{
|
|
500
|
+
"meta_table_uid": "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa",
|
|
501
|
+
"alias": "asset",
|
|
502
|
+
}
|
|
503
|
+
],
|
|
504
|
+
},
|
|
505
|
+
"limits": {
|
|
506
|
+
"max_rows": 5,
|
|
507
|
+
"statement_timeout_ms": 15000,
|
|
508
|
+
},
|
|
509
|
+
}
|
|
510
|
+
)
|
|
511
|
+
|
|
512
|
+
assert [row["value"] for row in result["rows"]] == [1, 2, 3, 4, 5]
|
|
513
|
+
assert result["row_count"] == 5
|
|
514
|
+
assert result["max_rows"] == 5
|
|
515
|
+
assert result["truncated"] is False
|
|
516
|
+
assert result["pagination"] == {
|
|
517
|
+
"limit": 5,
|
|
518
|
+
"offset": 0,
|
|
519
|
+
"returned_count": 5,
|
|
520
|
+
"has_more": False,
|
|
521
|
+
"next_offset": None,
|
|
522
|
+
}
|
|
523
|
+
assert [call["limits"]["offset"] for call in calls] == [0, 2, 4]
|
|
524
|
+
assert [call["limits"]["max_rows"] for call in calls] == [5, 3, 1]
|
|
413
525
|
|
|
414
526
|
|
|
415
527
|
def test_dynamic_table_data_source_issue_migration_connection_posts_scope(monkeypatch):
|
|
@@ -728,6 +840,31 @@ def test_compiled_sql_v1_protocol_is_validated_by_pydantic():
|
|
|
728
840
|
)
|
|
729
841
|
|
|
730
842
|
|
|
843
|
+
def test_compiled_sql_v1_operation_uses_backend_limit_defaults():
|
|
844
|
+
operation = build_operation(
|
|
845
|
+
operation="select",
|
|
846
|
+
sql="SELECT asset.symbol FROM public.asset AS asset",
|
|
847
|
+
scope={
|
|
848
|
+
"dataSourceUid": "dddddddd-dddd-4ddd-8ddd-dddddddddddd",
|
|
849
|
+
"tables": [
|
|
850
|
+
{
|
|
851
|
+
"metaTableUid": "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa",
|
|
852
|
+
"alias": "asset",
|
|
853
|
+
}
|
|
854
|
+
]
|
|
855
|
+
},
|
|
856
|
+
)
|
|
857
|
+
|
|
858
|
+
assert operation.limits.max_rows == 10_000
|
|
859
|
+
assert operation.limits.offset == 0
|
|
860
|
+
assert operation.limits.statement_timeout_ms == 60_000
|
|
861
|
+
assert meta_table_models._payload_json(operation)["limits"] == {
|
|
862
|
+
"max_rows": 10_000,
|
|
863
|
+
"offset": 0,
|
|
864
|
+
"statement_timeout_ms": 60_000,
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
|
|
731
868
|
def test_compiled_sql_v1_scope_resolves_session_data_source(monkeypatch):
|
|
732
869
|
monkeypatch.setattr(
|
|
733
870
|
meta_table_models,
|
|
@@ -774,7 +911,7 @@ def test_compiled_sql_v1_serializes_typed_temporal_parameters():
|
|
|
774
911
|
"metaTableUid": "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa",
|
|
775
912
|
"alias": "asset",
|
|
776
913
|
}
|
|
777
|
-
]
|
|
914
|
+
],
|
|
778
915
|
},
|
|
779
916
|
)
|
|
780
917
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mainsequence-4.3.19 → mainsequence-4.3.22}/agent_scaffold/skills/a2a_communication/SKILL.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mainsequence-4.3.19 → mainsequence-4.3.22}/agent_scaffold/skills/dashboards/streamlit/SKILL.md
RENAMED
|
File without changes
|
{mainsequence-4.3.19 → mainsequence-4.3.22}/agent_scaffold/skills/data_access/exploration/SKILL.md
RENAMED
|
File without changes
|
|
File without changes
|
{mainsequence-4.3.19 → mainsequence-4.3.22}/agent_scaffold/skills/maintenance/bug_auditor/SKILL.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/client/command_center/app_component.py
RENAMED
|
File without changes
|
{mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/client/command_center/connections.py
RENAMED
|
File without changes
|
{mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/client/command_center/data_models.py
RENAMED
|
File without changes
|
|
File without changes
|
{mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/client/command_center/workspace_snapshot.py
RENAMED
|
File without changes
|
|
File without changes
|
{mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/client/data_sources_interfaces/__init__.py
RENAMED
|
File without changes
|
{mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/client/data_sources_interfaces/duckdb.py
RENAMED
|
File without changes
|
|
File without changes
|
{mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/client/data_sources_interfaces/sqlite.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/meta_tables/compiled_sql/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/meta_tables/data_nodes/build_operations.py
RENAMED
|
File without changes
|
{mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/meta_tables/data_nodes/data_nodes.py
RENAMED
|
File without changes
|
|
File without changes
|
{mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/meta_tables/data_nodes/namespacing.py
RENAMED
|
File without changes
|
{mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/meta_tables/data_nodes/persist_managers.py
RENAMED
|
File without changes
|
{mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/meta_tables/data_nodes/run_operations.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mainsequence-4.3.19 → mainsequence-4.3.22}/mainsequence/meta_tables/sqlalchemy_contracts.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mainsequence-4.3.19 → mainsequence-4.3.22}/tests/test_command_center_app_component_models.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mainsequence-4.3.19 → mainsequence-4.3.22}/tests/test_data_node_storage_dimension_queries.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|