mainsequence 6.0.37__tar.gz → 6.0.40__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. {mainsequence-6.0.37 → mainsequence-6.0.40}/PKG-INFO +1 -1
  2. {mainsequence-6.0.37 → mainsequence-6.0.40}/agent_scaffold/skills/data_access/exploration/SKILL.md +7 -0
  3. {mainsequence-6.0.37 → mainsequence-6.0.40}/agent_scaffold/skills/maintenance/project-maintenance/SKILL.md +31 -20
  4. {mainsequence-6.0.37 → mainsequence-6.0.40}/agent_scaffold/skills/sdk_project_execution/SKILL.md +21 -14
  5. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/bootstrap.py +1 -2
  6. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/cli/api.py +1 -18
  7. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/cli/cli.py +393 -390
  8. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/cli/local_ops.py +39 -0
  9. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/cli/migrations.py +6 -4
  10. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/cli/project_status.py +26 -84
  11. mainsequence-6.0.40/mainsequence/cli/ssh_utils.py +365 -0
  12. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/client/agent_runtime_models.py +20 -17
  13. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/client/base.py +29 -0
  14. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/client/metatables/core.py +73 -488
  15. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/client/models_foundry.py +81 -23
  16. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/client/models_helpers.py +25 -22
  17. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/client/utils.py +0 -20
  18. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/logconf.py +17 -39
  19. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/meta_tables/data_nodes/build_operations.py +12 -8
  20. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/meta_tables/data_nodes/data_nodes.py +8 -2
  21. mainsequence-6.0.40/mainsequence/project_context.py +485 -0
  22. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence.egg-info/PKG-INFO +1 -1
  23. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence.egg-info/SOURCES.txt +4 -1
  24. {mainsequence-6.0.37 → mainsequence-6.0.40}/pyproject.toml +1 -1
  25. {mainsequence-6.0.37 → mainsequence-6.0.40}/tests/test_auth_precedence.py +14 -82
  26. {mainsequence-6.0.37 → mainsequence-6.0.40}/tests/test_build_operations_hashing.py +0 -20
  27. {mainsequence-6.0.37 → mainsequence-6.0.40}/tests/test_cli.py +459 -86
  28. {mainsequence-6.0.37 → mainsequence-6.0.40}/tests/test_cli_migrations.py +38 -3
  29. {mainsequence-6.0.37 → mainsequence-6.0.40}/tests/test_filter_normalization.py +106 -14
  30. mainsequence-6.0.40/tests/test_local_ops.py +59 -0
  31. {mainsequence-6.0.37 → mainsequence-6.0.40}/tests/test_logconf.py +30 -10
  32. {mainsequence-6.0.37 → mainsequence-6.0.40}/tests/test_meta_tables_sqlalchemy_contracts.py +41 -17
  33. mainsequence-6.0.40/tests/test_pod_project_resolution.py +227 -0
  34. {mainsequence-6.0.37 → mainsequence-6.0.40}/tests/test_project_branch_contract.py +35 -14
  35. mainsequence-6.0.40/tests/test_project_runtime_context.py +499 -0
  36. {mainsequence-6.0.37 → mainsequence-6.0.40}/tests/test_run_configuration.py +5 -6
  37. mainsequence-6.0.40/tests/test_ssh_utils.py +187 -0
  38. mainsequence-6.0.37/mainsequence/cli/ssh_utils.py +0 -184
  39. mainsequence-6.0.37/mainsequence/runtime_context.py +0 -145
  40. mainsequence-6.0.37/tests/test_pod_project_resolution.py +0 -999
  41. {mainsequence-6.0.37 → mainsequence-6.0.40}/LICENSE +0 -0
  42. {mainsequence-6.0.37 → mainsequence-6.0.40}/README.md +0 -0
  43. {mainsequence-6.0.37 → mainsequence-6.0.40}/agent_scaffold/AGENTS.md +0 -0
  44. {mainsequence-6.0.37 → mainsequence-6.0.40}/agent_scaffold/skills/a2a_sdk_execution/SKILL.md +0 -0
  45. {mainsequence-6.0.37 → mainsequence-6.0.40}/agent_scaffold/skills/application_surfaces/api_surfaces/SKILL.md +0 -0
  46. {mainsequence-6.0.37 → mainsequence-6.0.40}/agent_scaffold/skills/data_publishing/data_nodes/SKILL.md +0 -0
  47. {mainsequence-6.0.37 → mainsequence-6.0.40}/agent_scaffold/skills/data_publishing/meta_table_migrations/SKILL.md +0 -0
  48. {mainsequence-6.0.37 → mainsequence-6.0.40}/agent_scaffold/skills/data_publishing/meta_tables/SKILL.md +0 -0
  49. {mainsequence-6.0.37 → mainsequence-6.0.40}/agent_scaffold/skills/maintenance/bug_auditor/SKILL.md +0 -0
  50. {mainsequence-6.0.37 → mainsequence-6.0.40}/agent_scaffold/skills/platform_operations/access_control_and_sharing/SKILL.md +0 -0
  51. {mainsequence-6.0.37 → mainsequence-6.0.40}/agent_scaffold/skills/platform_operations/orchestration_and_releases/SKILL.md +0 -0
  52. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/__init__.py +0 -0
  53. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/__main__.py +0 -0
  54. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/cli/__init__.py +0 -0
  55. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/cli/browser_auth.py +0 -0
  56. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/cli/config.py +0 -0
  57. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/cli/docker_utils.py +0 -0
  58. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/cli/doctor.py +0 -0
  59. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/cli/model_filters.py +0 -0
  60. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/cli/pydantic_cli.py +0 -0
  61. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/cli/sdk_utils.py +0 -0
  62. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/cli/ui.py +0 -0
  63. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/client/__init__.py +0 -0
  64. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/client/client.py +0 -0
  65. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/client/compute_validation.py +0 -0
  66. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/client/data_sources_interfaces/__init__.py +0 -0
  67. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/client/data_sources_interfaces/duckdb.py +0 -0
  68. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/client/data_sources_interfaces/local_paths.py +0 -0
  69. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/client/data_sources_interfaces/sqlite.py +0 -0
  70. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/client/dtype_codec.py +0 -0
  71. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/client/exceptions.py +0 -0
  72. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/client/metatables/__init__.py +0 -0
  73. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/client/models_user.py +0 -0
  74. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/defaults.py +0 -0
  75. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/instrumentation/__init__.py +0 -0
  76. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/instrumentation/utils.py +0 -0
  77. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/meta_tables/__init__.py +0 -0
  78. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/meta_tables/__main__.py +0 -0
  79. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/meta_tables/compiled_sql/__init__.py +0 -0
  80. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/meta_tables/compiled_sql/v1.py +0 -0
  81. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/meta_tables/data_nodes/__init__.py +0 -0
  82. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/meta_tables/data_nodes/models.py +0 -0
  83. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/meta_tables/data_nodes/namespacing.py +0 -0
  84. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/meta_tables/data_nodes/persist_managers.py +0 -0
  85. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/meta_tables/data_nodes/run_operations.py +0 -0
  86. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/meta_tables/data_nodes/utils.py +0 -0
  87. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/meta_tables/future_registry.py +0 -0
  88. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/meta_tables/hashing.py +0 -0
  89. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/meta_tables/migrations/__init__.py +0 -0
  90. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/meta_tables/migrations/alembic.py +0 -0
  91. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/meta_tables/migrations/env.py +0 -0
  92. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/meta_tables/migrations/provider.py +0 -0
  93. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/meta_tables/migrations/registry.py +0 -0
  94. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/meta_tables/migrations/scaffold.py +0 -0
  95. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/meta_tables/migrations/templates/__init__.py +0 -0
  96. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/meta_tables/migrations/templates/env.py.mako +0 -0
  97. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/meta_tables/migrations/templates/script.py.mako +0 -0
  98. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/meta_tables/pydantic_metadata.py +0 -0
  99. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/meta_tables/schema_names.py +0 -0
  100. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/meta_tables/sqlalchemy_contracts.py +0 -0
  101. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/project_skills.py +0 -0
  102. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/runtime_flags.py +0 -0
  103. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence/scaffold_skills.py +0 -0
  104. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence.egg-info/dependency_links.txt +0 -0
  105. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence.egg-info/entry_points.txt +0 -0
  106. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence.egg-info/requires.txt +0 -0
  107. {mainsequence-6.0.37 → mainsequence-6.0.40}/mainsequence.egg-info/top_level.txt +0 -0
  108. {mainsequence-6.0.37 → mainsequence-6.0.40}/setup.cfg +0 -0
  109. {mainsequence-6.0.37 → mainsequence-6.0.40}/tests/test_canonical_api_route_contract.py +0 -0
  110. {mainsequence-6.0.37 → mainsequence-6.0.40}/tests/test_cli_browser_auth.py +0 -0
  111. {mainsequence-6.0.37 → mainsequence-6.0.40}/tests/test_client.py +0 -0
  112. {mainsequence-6.0.37 → mainsequence-6.0.40}/tests/test_data_access_mixin_dimension_audit.py +0 -0
  113. {mainsequence-6.0.37 → mainsequence-6.0.40}/tests/test_data_node_storage_dimension_queries.py +0 -0
  114. {mainsequence-6.0.37 → mainsequence-6.0.40}/tests/test_data_node_update_flow.py +0 -0
  115. {mainsequence-6.0.37 → mainsequence-6.0.40}/tests/test_dependency_extras.py +0 -0
  116. {mainsequence-6.0.37 → mainsequence-6.0.40}/tests/test_duckdb_interface_dimensions.py +0 -0
  117. {mainsequence-6.0.37 → mainsequence-6.0.40}/tests/test_instrumentation.py +0 -0
  118. {mainsequence-6.0.37 → mainsequence-6.0.40}/tests/test_meta_table_migrations.py +0 -0
  119. {mainsequence-6.0.37 → mainsequence-6.0.40}/tests/test_meta_tables_client_models.py +0 -0
  120. {mainsequence-6.0.37 → mainsequence-6.0.40}/tests/test_models_user_request_bound_auth.py +0 -0
  121. {mainsequence-6.0.37 → mainsequence-6.0.40}/tests/test_notification_uid_contract.py +0 -0
  122. {mainsequence-6.0.37 → mainsequence-6.0.40}/tests/test_project_batch_jobs_from_file.py +0 -0
  123. {mainsequence-6.0.37 → mainsequence-6.0.40}/tests/test_project_skills.py +0 -0
  124. {mainsequence-6.0.37 → mainsequence-6.0.40}/tests/test_scaffold_skills.py +0 -0
  125. {mainsequence-6.0.37 → mainsequence-6.0.40}/tests/test_schema_names.py +0 -0
  126. {mainsequence-6.0.37 → mainsequence-6.0.40}/tests/test_secret_client_model.py +0 -0
  127. {mainsequence-6.0.37 → mainsequence-6.0.40}/tests/test_source_table_configuration.py +0 -0
  128. {mainsequence-6.0.37 → mainsequence-6.0.40}/tests/test_sqlite_interface_dimensions.py +0 -0
  129. {mainsequence-6.0.37 → mainsequence-6.0.40}/tests/test_update_runner_uid_runtime.py +0 -0
  130. {mainsequence-6.0.37 → mainsequence-6.0.40}/tests/test_update_statistics.py +0 -0
  131. {mainsequence-6.0.37 → mainsequence-6.0.40}/tests/test_update_uid_guards.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mainsequence
3
- Version: 6.0.37
3
+ Version: 6.0.40
4
4
  Summary: Main Sequence SDK
5
5
  Author-email: Main Sequence GmbH <dev@main-sequence.io>
6
6
  License-Expression: LicenseRef-MainSequence-Proprietary
@@ -154,6 +154,13 @@ field to filter by:
154
154
  - `mainsequence data-node list --filter KEY=VALUE`
155
155
  - `mainsequence data-node detail <DATA_NODE_STORAGE_UID>`
156
156
 
157
+ Collection listing is scoped to one Organization Environment. Inside a
158
+ registered project checkout, the CLI derives that scope from the process-frozen
159
+ Git-resolved ProjectBranch. Outside one, pass
160
+ `--organization-project-environment-uid <ENVIRONMENT_UID>` explicitly. Direct
161
+ SDK calls use the canonical
162
+ `organization_project_environment_uid=<ENVIRONMENT_UID>` filter.
163
+
157
164
  Column lookup is also a different path. Use it only for schema-name discovery,
158
165
  not as the default dataset discovery flow:
159
166
 
@@ -32,12 +32,11 @@ Route architecture changes to `project_design`, implementation routing to
32
32
  `maintenance/bug_auditor` when diagnosis extends beyond the maintenance
33
33
  workflow itself.
34
34
 
35
- The local identity contract has one persisted platform identifier:
36
- `MAIN_SEQUENCE_PROJECT_UID`, the logical Project UID. The checked-out Git
37
- branch selects the active ProjectBranch. Never ask the user for a
38
- ProjectBranch UID, persist `MAIN_SEQUENCE_PROJECT_BRANCH_UID`, or treat a
39
- ProjectBranch UID as local project configuration. The CLI may resolve that UID
40
- internally when a branch-owned platform API requires it.
35
+ The local identity contract is Git-native. The containing repository remote,
36
+ attached branch, and exact HEAD commit select the platform Project and
37
+ ProjectBranch. Never ask the user for a ProjectBranch UID, persist Project or
38
+ branch identity in `.env`, or use an environment variable as a branch selector.
39
+ The CLI resolves platform UIDs internally when a branch-owned API requires them.
41
40
 
42
41
  ## Inspect Before Changing State
43
42
 
@@ -53,8 +52,8 @@ internally when a branch-owned platform API requires it.
53
52
 
54
53
  The `project current` result must report the logical `project_uid`, current
55
54
  `git_branch`, `project_branch_uid`, and `project_branch_status=resolved`.
56
- Treat a detached checkout, missing logical Project UID, or unresolved/
57
- unregistered Git branch as a maintenance preflight failure before any
55
+ Treat a detached checkout, unresolved repository, or unresolved/unregistered
56
+ Git branch as a maintenance preflight failure before any
58
57
  mutating workflow.
59
58
 
60
59
  4. Separate existing user changes from changes created by the maintenance
@@ -125,11 +124,10 @@ authorizes a new PKCE grant and the backend returns credentials directly to
125
124
  the waiting CLI process.
126
125
 
127
126
  The command preserves unrelated project configuration and renders only the
128
- current supported authentication shape. Existing `MAINSEQUENCE_TOKEN` and
129
- `MAIN_SEQUENCE_PROJECT_ID` entries are not carried into the rewritten file;
130
- this is not a separate cleanup routine. It preserves the logical
131
- `MAIN_SEQUENCE_PROJECT_UID` and never writes a ProjectBranch UID; switching Git
132
- branches changes local branch context without rewriting `.env`.
127
+ current supported authentication shape. It removes legacy token aliases and
128
+ all retired Project, ProjectBranch, repository-branch, and Environment identity
129
+ entries. The Git checkout supplies source identity; switching branches changes
130
+ context on the next process run without rewriting `.env`.
133
131
 
134
132
  ## Update The Project SDK
135
133
 
@@ -192,6 +190,12 @@ a detached checkout and rejects a Git branch that is not registered under the
192
190
  logical Project. Do not bypass that validation or supply a ProjectBranch UID
193
191
  manually. Register or select the correct Git branch first.
194
192
 
193
+ After that branch preflight, `--dry-run` resolves the existing `uv` executable,
194
+ previews its patch version without mutation, requests the backend-owned tag for
195
+ that future version, rejects an invalid or existing local tag, prints the
196
+ complete plan, and returns without generating an SSH key, querying private
197
+ remote refs, changing dependencies or project files, or mutating Git state.
198
+
195
199
  After review:
196
200
 
197
201
  ```bash
@@ -200,13 +204,20 @@ mainsequence project sync --path . -m "<specific commit message>"
200
204
 
201
205
  The canonical command always:
202
206
 
203
- 1. applies a patch version bump;
204
- 2. runs `uv lock`;
205
- 3. runs `uv sync`;
206
- 4. exports locked production requirements;
207
- 5. stages and commits the changes;
208
- 6. creates an annotated `v<version>` tag; and
209
- 7. pushes the branch and tag with `--follow-tags`.
207
+ 1. selects `mainsequence-<repository-slug>-<first-16-sha256>` from the normalized
208
+ `host[:non-default-port]/repository/path`, never from the repository basename alone and never
209
+ from a legacy basename-only key;
210
+ 2. previews the `uv` patch version, requests the backend-owned ProjectBranch tag, and rejects an
211
+ invalid or existing local tag;
212
+ 3. registers a new or inaccessible key through the owning Project and verifies a dry-run push with
213
+ that forced identity;
214
+ 4. queries the exact tag ref on `origin` and stops if it exists or cannot be checked;
215
+ 5. applies the patch version bump and verifies it matches the preview;
216
+ 6. runs `uv lock` and `uv sync`;
217
+ 7. exports locked production requirements;
218
+ 8. stages and commits the changes;
219
+ 9. creates the returned annotated tag unchanged; and
220
+ 10. atomically pushes the explicit branch and tag refs with `--follow-tags`.
210
221
 
211
222
  Do not offer alternate bump modes, a no-push mode, or a hand-written sequence
212
223
  of equivalent commands. Do not call `sync-after-commit` or any backend repair
@@ -91,22 +91,26 @@ If the user goal or project context is unclear, stop before routing domain work.
91
91
 
92
92
  ## Resolve Local Project Context From Git
93
93
 
94
- Local project context is composed from two sources:
95
-
96
- - `.env` supplies `MAIN_SEQUENCE_PROJECT_UID`, the logical Project aggregate;
97
- - `git branch --show-current` supplies the active repository branch.
98
-
99
- Use `mainsequence project current --debug --json` to verify that pair resolves
94
+ The containing Git worktree is the only source of repository, attached branch,
95
+ and exact commit identity. The SDK normalizes the non-secret repository remote,
96
+ maps it to Project and ProjectBranch through the platform API, resolves once for
97
+ the process, and reuses the immutable result. Authentication selects credentials
98
+ and permissions; it does not select source identity. A `git switch` performed in
99
+ a long-running process takes effect only in the next CLI invocation, worker,
100
+ script, or other process run.
101
+
102
+ Use `mainsequence project current --debug --json` to verify that Git context resolves
100
103
  to `project_branch_status=resolved` and a nonempty `project_branch_uid`. The UID
101
104
  is an internal resolution result for branch-owned platform calls; it is not a
102
- local configuration input. Never require the user to look it up, never persist
103
- `MAIN_SEQUENCE_PROJECT_BRANCH_UID`, and never infer a branch from collection
104
- order. A detached checkout or an unregistered Git branch is unresolved project
105
- context and must block live branch-owned operations.
105
+ local or environment configuration input. Never require the user to look it up,
106
+ persist project identity in `.env`, accept a branch environment override, or
107
+ infer a branch from collection order. Local and deployed project images use the
108
+ same Git algorithm. A detached checkout or an unregistered Git branch is
109
+ unresolved context and must block only live branch-owned operations.
106
110
 
107
111
  Keep the platform boundaries explicit:
108
112
 
109
- - use the logical Project UID for aggregate identity and Project operations;
113
+ - use the Git-resolved logical Project UID for aggregate identity and Project operations;
110
114
  - let the SDK resolve the current Git branch to ProjectBranch only when Jobs,
111
115
  images, releases, resources, pods, or other branch-owned APIs require it;
112
116
  - treat GitRepository as repository metadata and clone-location ownership;
@@ -114,9 +118,12 @@ Keep the platform boundaries explicit:
114
118
 
115
119
  For ordinary local implementation, work naturally in the current Git branch.
116
120
  Do not make ProjectBranch selection a separate user workflow.
117
- An unregistered local branch may still use the logical Project default
118
- DataSource for generic MetaTable/session work. It remains invalid for Jobs,
119
- images, releases, resources, pods, and every other branch-owned platform API.
121
+ An unregistered local branch remains valid for ordinary local development, but
122
+ it has no ProjectBranch, Environment, or project-derived MetaTables DataSource.
123
+ Only branch-owned operations fail. Register the branch before using Jobs,
124
+ images, releases, resources, platform-managed MetaTables/DataNodes, migrations,
125
+ pods, or other branch-owned platform APIs. Never fall back to another branch or
126
+ to a Project-level default DataSource.
120
127
 
121
128
  ## Required Decisions
122
129
 
@@ -20,7 +20,7 @@ def _read_local_env_values(env_path: pathlib.Path) -> dict[str, str]:
20
20
  return {}
21
21
 
22
22
  values: dict[str, str] = {}
23
- for key in ("MAINSEQUENCE_ENDPOINT", "MAIN_SEQUENCE_PROJECT_UID"):
23
+ for key in ("MAINSEQUENCE_ENDPOINT",):
24
24
  match = re.search(rf"(?m)^{re.escape(key)}=(.+?)\s*$", content)
25
25
  if match:
26
26
  values[key] = match.group(1).strip()
@@ -35,7 +35,6 @@ def prime_runtime_env() -> None:
35
35
  local_values = _read_local_env_values(pathlib.Path.cwd() / ".env")
36
36
 
37
37
  _set_if_missing("MAINSEQUENCE_ENDPOINT", local_values.get("MAINSEQUENCE_ENDPOINT"))
38
- _set_if_missing("MAIN_SEQUENCE_PROJECT_UID", local_values.get("MAIN_SEQUENCE_PROJECT_UID"))
39
38
 
40
39
  try:
41
40
  from .cli import config as cli_config
@@ -606,7 +606,6 @@ def _run_sdk_model_operation(
606
606
  module_name: str,
607
607
  class_name: str,
608
608
  operation,
609
- project_uid_env: str | None = None,
610
609
  ):
611
610
  tokens = get_tokens()
612
611
  access = (tokens.get("access") or "").strip()
@@ -622,7 +621,6 @@ def _run_sdk_model_operation(
622
621
  "MAINSEQUENCE_ACCESS_TOKEN": os.environ.get("MAINSEQUENCE_ACCESS_TOKEN"),
623
622
  "MAINSEQUENCE_REFRESH_TOKEN": os.environ.get("MAINSEQUENCE_REFRESH_TOKEN"),
624
623
  "MAINSEQUENCE_ENDPOINT": os.environ.get("MAINSEQUENCE_ENDPOINT"),
625
- "MAIN_SEQUENCE_PROJECT_UID": os.environ.get("MAIN_SEQUENCE_PROJECT_UID"),
626
624
  }
627
625
 
628
626
  client_utils = None
@@ -639,11 +637,6 @@ def _run_sdk_model_operation(
639
637
  else:
640
638
  os.environ.pop("MAINSEQUENCE_REFRESH_TOKEN", None)
641
639
  os.environ["MAINSEQUENCE_ENDPOINT"] = endpoint
642
- if project_uid_env is not None:
643
- os.environ["MAIN_SEQUENCE_PROJECT_UID"] = str(project_uid_env)
644
- else:
645
- os.environ.pop("MAIN_SEQUENCE_PROJECT_UID", None)
646
-
647
640
  from mainsequence.client import utils as _client_utils
648
641
  from mainsequence.client.base import BaseObjectOrm
649
642
 
@@ -2028,7 +2021,6 @@ def get_project_data_node_updates(
2028
2021
  "MAINSEQUENCE_ACCESS_TOKEN": os.environ.get("MAINSEQUENCE_ACCESS_TOKEN"),
2029
2022
  "MAINSEQUENCE_REFRESH_TOKEN": os.environ.get("MAINSEQUENCE_REFRESH_TOKEN"),
2030
2023
  "MAINSEQUENCE_ENDPOINT": os.environ.get("MAINSEQUENCE_ENDPOINT"),
2031
- "MAIN_SEQUENCE_PROJECT_UID": os.environ.get("MAIN_SEQUENCE_PROJECT_UID"),
2032
2024
  }
2033
2025
 
2034
2026
  client_utils = None
@@ -2139,7 +2131,6 @@ def create_project_image(
2139
2131
  "MAINSEQUENCE_ACCESS_TOKEN": os.environ.get("MAINSEQUENCE_ACCESS_TOKEN"),
2140
2132
  "MAINSEQUENCE_REFRESH_TOKEN": os.environ.get("MAINSEQUENCE_REFRESH_TOKEN"),
2141
2133
  "MAINSEQUENCE_ENDPOINT": os.environ.get("MAINSEQUENCE_ENDPOINT"),
2142
- "MAIN_SEQUENCE_PROJECT_UID": os.environ.get("MAIN_SEQUENCE_PROJECT_UID"),
2143
2134
  }
2144
2135
 
2145
2136
  client_utils = None
@@ -2246,7 +2237,6 @@ def list_project_images(
2246
2237
  "MAINSEQUENCE_ACCESS_TOKEN": os.environ.get("MAINSEQUENCE_ACCESS_TOKEN"),
2247
2238
  "MAINSEQUENCE_REFRESH_TOKEN": os.environ.get("MAINSEQUENCE_REFRESH_TOKEN"),
2248
2239
  "MAINSEQUENCE_ENDPOINT": os.environ.get("MAINSEQUENCE_ENDPOINT"),
2249
- "MAIN_SEQUENCE_PROJECT_UID": os.environ.get("MAIN_SEQUENCE_PROJECT_UID"),
2250
2240
  }
2251
2241
 
2252
2242
  client_utils = None
@@ -2473,7 +2463,6 @@ def list_project_jobs(
2473
2463
  "MAINSEQUENCE_ACCESS_TOKEN": os.environ.get("MAINSEQUENCE_ACCESS_TOKEN"),
2474
2464
  "MAINSEQUENCE_REFRESH_TOKEN": os.environ.get("MAINSEQUENCE_REFRESH_TOKEN"),
2475
2465
  "MAINSEQUENCE_ENDPOINT": os.environ.get("MAINSEQUENCE_ENDPOINT"),
2476
- "MAIN_SEQUENCE_PROJECT_UID": os.environ.get("MAIN_SEQUENCE_PROJECT_UID"),
2477
2466
  }
2478
2467
 
2479
2468
  client_utils = None
@@ -2509,7 +2498,7 @@ def list_project_jobs(
2509
2498
  extra_filters = dict(filters or {})
2510
2499
  jobs = ClientJob.filter(
2511
2500
  timeout=timeout,
2512
- **{**extra_filters, "project__uid": resolved_branch_uid},
2501
+ **{**extra_filters, "project_branch_uid": resolved_branch_uid},
2513
2502
  )
2514
2503
 
2515
2504
  out: list[dict[str, Any]] = []
@@ -2585,7 +2574,6 @@ def list_project_resources(
2585
2574
  "MAINSEQUENCE_ACCESS_TOKEN": os.environ.get("MAINSEQUENCE_ACCESS_TOKEN"),
2586
2575
  "MAINSEQUENCE_REFRESH_TOKEN": os.environ.get("MAINSEQUENCE_REFRESH_TOKEN"),
2587
2576
  "MAINSEQUENCE_ENDPOINT": os.environ.get("MAINSEQUENCE_ENDPOINT"),
2588
- "MAIN_SEQUENCE_PROJECT_UID": os.environ.get("MAIN_SEQUENCE_PROJECT_UID"),
2589
2577
  }
2590
2578
 
2591
2579
  client_utils = None
@@ -4397,7 +4385,6 @@ def create_project_job(
4397
4385
  "MAINSEQUENCE_ACCESS_TOKEN": os.environ.get("MAINSEQUENCE_ACCESS_TOKEN"),
4398
4386
  "MAINSEQUENCE_REFRESH_TOKEN": os.environ.get("MAINSEQUENCE_REFRESH_TOKEN"),
4399
4387
  "MAINSEQUENCE_ENDPOINT": os.environ.get("MAINSEQUENCE_ENDPOINT"),
4400
- "MAIN_SEQUENCE_PROJECT_UID": os.environ.get("MAIN_SEQUENCE_PROJECT_UID"),
4401
4388
  }
4402
4389
 
4403
4390
  client_utils = None
@@ -5021,7 +5008,6 @@ def list_github_organizations() -> list[dict]:
5021
5008
  def create_project(
5022
5009
  *,
5023
5010
  project_name: str,
5024
- default_metatables_data_source_uid: str,
5025
5011
  project_type: str = "python",
5026
5012
  default_base_image_uid: str | None = None,
5027
5013
  github_org_uid: str | None = None,
@@ -5036,9 +5022,6 @@ def create_project(
5036
5022
  "project_type": project_type,
5037
5023
  }
5038
5024
 
5039
- if default_metatables_data_source_uid in (None, ""):
5040
- raise ValueError("default_metatables_data_source_uid is required")
5041
- payload["default_metatables_data_source_uid"] = str(default_metatables_data_source_uid)
5042
5025
  if default_base_image_uid not in (None, ""):
5043
5026
  payload["default_base_image_uid"] = str(default_base_image_uid)
5044
5027
  if github_org_uid not in (None, ""):