mainsequence 9.0.6.dev38__tar.gz → 9.0.6.dev40__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 (102) hide show
  1. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/PKG-INFO +4 -5
  2. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/README.md +2 -2
  3. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/agent_scaffold/skills/platform_operations/orchestration_and_releases/SKILL.md +10 -2
  4. mainsequence-9.0.6.dev40/mainsequence/server/__init__.py +1 -0
  5. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/mainsequence/server/caller_assertions.py +3 -7
  6. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/mainsequence.egg-info/PKG-INFO +4 -5
  7. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/mainsequence.egg-info/requires.txt +1 -3
  8. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/pyproject.toml +2 -5
  9. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/tests/test_caller_assertions.py +3 -4
  10. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/tests/test_dependency_extras.py +32 -0
  11. mainsequence-9.0.6.dev38/mainsequence/server/__init__.py +0 -1
  12. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/LICENSE +0 -0
  13. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/agent_scaffold/AGENTS.md +0 -0
  14. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/agent_scaffold/skills/a2a_sdk_execution/SKILL.md +0 -0
  15. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/agent_scaffold/skills/application_surfaces/api_surfaces/SKILL.md +0 -0
  16. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/agent_scaffold/skills/mainsequence-inference/SKILL.md +0 -0
  17. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/agent_scaffold/skills/maintenance/bug_auditor/SKILL.md +0 -0
  18. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/agent_scaffold/skills/maintenance/code_repository_maintenance/SKILL.md +0 -0
  19. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/agent_scaffold/skills/maintenance/metatables_transition/SKILL.md +0 -0
  20. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/agent_scaffold/skills/platform_operations/access_control_and_sharing/SKILL.md +0 -0
  21. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/agent_scaffold/skills/sdk_code_repository_execution/SKILL.md +0 -0
  22. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/mainsequence/__init__.py +0 -0
  23. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/mainsequence/__main__.py +0 -0
  24. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/mainsequence/_request_identity.py +0 -0
  25. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/mainsequence/bootstrap.py +0 -0
  26. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/mainsequence/cli/__init__.py +0 -0
  27. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/mainsequence/cli/api.py +0 -0
  28. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/mainsequence/cli/browser_auth.py +0 -0
  29. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/mainsequence/cli/cli.py +0 -0
  30. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/mainsequence/cli/code_repository_status.py +0 -0
  31. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/mainsequence/cli/config.py +0 -0
  32. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/mainsequence/cli/docker_utils.py +0 -0
  33. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/mainsequence/cli/doctor.py +0 -0
  34. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/mainsequence/cli/local_ops.py +0 -0
  35. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/mainsequence/cli/model_filters.py +0 -0
  36. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/mainsequence/cli/pydantic_cli.py +0 -0
  37. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/mainsequence/cli/sdk_utils.py +0 -0
  38. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/mainsequence/cli/ssh_utils.py +0 -0
  39. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/mainsequence/cli/ui.py +0 -0
  40. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/mainsequence/client/__init__.py +0 -0
  41. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/mainsequence/client/agent_runtime_models.py +0 -0
  42. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/mainsequence/client/base.py +0 -0
  43. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/mainsequence/client/client.py +0 -0
  44. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/mainsequence/client/compute_validation.py +0 -0
  45. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/mainsequence/client/exceptions.py +0 -0
  46. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/mainsequence/client/github_issues.py +0 -0
  47. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/mainsequence/client/inference.py +0 -0
  48. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/mainsequence/client/models_foundry.py +0 -0
  49. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/mainsequence/client/models_helpers.py +0 -0
  50. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/mainsequence/client/models_user.py +0 -0
  51. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/mainsequence/client/observability.py +0 -0
  52. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/mainsequence/client/utils.py +0 -0
  53. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/mainsequence/client/value_sets.py +0 -0
  54. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/mainsequence/code_repository_context.py +0 -0
  55. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/mainsequence/code_repository_skills.py +0 -0
  56. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/mainsequence/defaults.py +0 -0
  57. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/mainsequence/instrumentation/__init__.py +0 -0
  58. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/mainsequence/instrumentation/utils.py +0 -0
  59. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/mainsequence/logconf.py +0 -0
  60. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/mainsequence/repository_identity_security.py +0 -0
  61. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/mainsequence/runtime_flags.py +0 -0
  62. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/mainsequence/scaffold_skills.py +0 -0
  63. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/mainsequence/server/fastapi.py +0 -0
  64. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/mainsequence.egg-info/SOURCES.txt +0 -0
  65. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/mainsequence.egg-info/dependency_links.txt +0 -0
  66. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/mainsequence.egg-info/entry_points.txt +0 -0
  67. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/mainsequence.egg-info/top_level.txt +0 -0
  68. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/setup.cfg +0 -0
  69. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/tests/test_auth_bootstrap.py +0 -0
  70. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/tests/test_auth_precedence.py +0 -0
  71. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/tests/test_canonical_api_route_contract.py +0 -0
  72. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/tests/test_cli.py +0 -0
  73. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/tests/test_cli_auth_contract.py +0 -0
  74. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/tests/test_cli_browser_auth.py +0 -0
  75. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/tests/test_cli_secure_storage.py +0 -0
  76. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/tests/test_client.py +0 -0
  77. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/tests/test_code_repository_branch_contract.py +0 -0
  78. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/tests/test_code_repository_documentation_contract.py +0 -0
  79. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/tests/test_code_repository_runtime_context.py +0 -0
  80. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/tests/test_code_repository_skills.py +0 -0
  81. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/tests/test_dev_release_version.py +0 -0
  82. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/tests/test_environment_resource_context.py +0 -0
  83. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/tests/test_environment_response_contracts.py +0 -0
  84. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/tests/test_fastapi_request_identity.py +0 -0
  85. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/tests/test_filter_normalization.py +0 -0
  86. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/tests/test_github_issues_client.py +0 -0
  87. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/tests/test_independent_context.py +0 -0
  88. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/tests/test_inference_client.py +0 -0
  89. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/tests/test_instrumentation.py +0 -0
  90. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/tests/test_job_client.py +0 -0
  91. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/tests/test_local_ops.py +0 -0
  92. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/tests/test_logconf.py +0 -0
  93. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/tests/test_models_user_request_bound_auth.py +0 -0
  94. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/tests/test_notification_uid_contract.py +0 -0
  95. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/tests/test_observability_client.py +0 -0
  96. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/tests/test_scaffold_skills.py +0 -0
  97. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/tests/test_secret_client_model.py +0 -0
  98. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/tests/test_source_ownership.py +0 -0
  99. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/tests/test_ssh_utils.py +0 -0
  100. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/tests/test_tolerant_response_reading.py +0 -0
  101. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/tests/test_tolerant_value_sets.py +0 -0
  102. {mainsequence-9.0.6.dev38 → mainsequence-9.0.6.dev40}/tests/test_user_application_facts.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mainsequence
3
- Version: 9.0.6.dev38
3
+ Version: 9.0.6.dev40
4
4
  Summary: Main Sequence SDK
5
5
  Author-email: Main Sequence GmbH <dev@main-sequence.io>
6
6
  License-Expression: MIT
@@ -25,13 +25,12 @@ Requires-Dist: protobuf>=6.33.5
25
25
  Requires-Dist: psutil
26
26
  Requires-Dist: pydantic<3,>=2.11
27
27
  Requires-Dist: pygments>=2.20.0
28
+ Requires-Dist: PyJWT[crypto]<3,>=2.10
28
29
  Requires-Dist: pyyaml
29
30
  Requires-Dist: requests>=2.33.0
30
31
  Requires-Dist: structlog
31
32
  Requires-Dist: typer
32
33
  Requires-Dist: urllib3>=2.7.0
33
- Provides-Extra: server
34
- Requires-Dist: PyJWT[crypto]<3,>=2.10; extra == "server"
35
34
  Dynamic: license-file
36
35
 
37
36
  <p align="center">
@@ -75,7 +74,7 @@ Main package areas:
75
74
  authentication, platform resources, and local CodeRepository operations
76
75
  - `mainsequence.instrumentation` and `mainsequence.logconf`: SDK tracing and
77
76
  logging integration
78
- - `mainsequence.server`: optional server-side caller assertion verification
77
+ - `mainsequence.server`: server-side caller assertion verification
79
78
  - `mainsequence.scaffold_skills`: reusable, version-pinned skill copying for
80
79
  this SDK and extension libraries
81
80
 
@@ -148,7 +147,7 @@ another repository, use the explicitly scoped `filter_admin` path. See
148
147
  [Resource releases](docs/knowledge/infrastructure/resource_releases.md) for
149
148
  supported filters and examples.
150
149
 
151
- Server integrations can install `mainsequence[server]` for the
150
+ The standard `mainsequence` installation includes PyJWT and cryptography for the
152
151
  framework-independent [caller assertion verifier](docs/knowledge/server/caller_assertions.md).
153
152
  Applications remain responsible for resource authorization and storage
154
153
  operations.
@@ -39,7 +39,7 @@ Main package areas:
39
39
  authentication, platform resources, and local CodeRepository operations
40
40
  - `mainsequence.instrumentation` and `mainsequence.logconf`: SDK tracing and
41
41
  logging integration
42
- - `mainsequence.server`: optional server-side caller assertion verification
42
+ - `mainsequence.server`: server-side caller assertion verification
43
43
  - `mainsequence.scaffold_skills`: reusable, version-pinned skill copying for
44
44
  this SDK and extension libraries
45
45
 
@@ -112,7 +112,7 @@ another repository, use the explicitly scoped `filter_admin` path. See
112
112
  [Resource releases](docs/knowledge/infrastructure/resource_releases.md) for
113
113
  supported filters and examples.
114
114
 
115
- Server integrations can install `mainsequence[server]` for the
115
+ The standard `mainsequence` installation includes PyJWT and cryptography for the
116
116
  framework-independent [caller assertion verifier](docs/knowledge/server/caller_assertions.md).
117
117
  Applications remain responsible for resource authorization and storage
118
118
  operations.
@@ -91,8 +91,16 @@ the SDK or CodeRepository code.
91
91
 
92
92
  Every file requires the backend-advertised `api_version`, a name, and resource
93
93
  declarations. Use the current template for accepted fields and resource kinds.
94
- There is no prune or strict-delete mode; removing a declaration does not delete
95
- an existing backend resource.
94
+ A declaration owns its target. On the next push of the branch head, these
95
+ delete the target:
96
+
97
+ - removing the declaration or its file;
98
+ - a `scope` that excludes the branch's Environment.
99
+
100
+ Renaming a file or key deletes the old target and creates a new one, with new
101
+ UIDs and URLs. An invalid file deletes nothing. The branch's Harness Agent
102
+ stays while any workflow file declares a `harness_agent`, so moving its
103
+ declaration keeps the same Agent.
96
104
 
97
105
  Do not hide important recurring schedules in ad hoc shell history or one-off manual commands.
98
106
 
@@ -0,0 +1 @@
1
+ """Server-side platform integrations. Import integrations explicitly."""
@@ -11,14 +11,10 @@ from collections.abc import Callable
11
11
  from dataclasses import dataclass
12
12
  from urllib.parse import urlsplit
13
13
 
14
+ import jwt
14
15
  import requests
15
-
16
- try:
17
- import jwt
18
- from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PublicKey
19
- from jwt import InvalidKeyError, InvalidTokenError
20
- except ImportError as exc:
21
- raise ImportError("Caller verification requires the mainsequence[server] extra.") from exc
16
+ from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PublicKey
17
+ from jwt import InvalidKeyError, InvalidTokenError
22
18
 
23
19
  ASSERTION_HEADER = "X-MainSequence-Caller-Assertion"
24
20
  ASSERTION_TYPE = "mainsequence-caller-assertion+jwt"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mainsequence
3
- Version: 9.0.6.dev38
3
+ Version: 9.0.6.dev40
4
4
  Summary: Main Sequence SDK
5
5
  Author-email: Main Sequence GmbH <dev@main-sequence.io>
6
6
  License-Expression: MIT
@@ -25,13 +25,12 @@ Requires-Dist: protobuf>=6.33.5
25
25
  Requires-Dist: psutil
26
26
  Requires-Dist: pydantic<3,>=2.11
27
27
  Requires-Dist: pygments>=2.20.0
28
+ Requires-Dist: PyJWT[crypto]<3,>=2.10
28
29
  Requires-Dist: pyyaml
29
30
  Requires-Dist: requests>=2.33.0
30
31
  Requires-Dist: structlog
31
32
  Requires-Dist: typer
32
33
  Requires-Dist: urllib3>=2.7.0
33
- Provides-Extra: server
34
- Requires-Dist: PyJWT[crypto]<3,>=2.10; extra == "server"
35
34
  Dynamic: license-file
36
35
 
37
36
  <p align="center">
@@ -75,7 +74,7 @@ Main package areas:
75
74
  authentication, platform resources, and local CodeRepository operations
76
75
  - `mainsequence.instrumentation` and `mainsequence.logconf`: SDK tracing and
77
76
  logging integration
78
- - `mainsequence.server`: optional server-side caller assertion verification
77
+ - `mainsequence.server`: server-side caller assertion verification
79
78
  - `mainsequence.scaffold_skills`: reusable, version-pinned skill copying for
80
79
  this SDK and extension libraries
81
80
 
@@ -148,7 +147,7 @@ another repository, use the explicitly scoped `filter_admin` path. See
148
147
  [Resource releases](docs/knowledge/infrastructure/resource_releases.md) for
149
148
  supported filters and examples.
150
149
 
151
- Server integrations can install `mainsequence[server]` for the
150
+ The standard `mainsequence` installation includes PyJWT and cryptography for the
152
151
  framework-independent [caller assertion verifier](docs/knowledge/server/caller_assertions.md).
153
152
  Applications remain responsible for resource authorization and storage
154
153
  operations.
@@ -10,11 +10,9 @@ protobuf>=6.33.5
10
10
  psutil
11
11
  pydantic<3,>=2.11
12
12
  pygments>=2.20.0
13
+ PyJWT[crypto]<3,>=2.10
13
14
  pyyaml
14
15
  requests>=2.33.0
15
16
  structlog
16
17
  typer
17
18
  urllib3>=2.7.0
18
-
19
- [server]
20
- PyJWT[crypto]<3,>=2.10
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "mainsequence"
7
- version = "9.0.6.dev38"
7
+ version = "9.0.6.dev40"
8
8
  description = "Main Sequence SDK"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.13"
@@ -34,6 +34,7 @@ dependencies = [
34
34
  "psutil",
35
35
  "pydantic>=2.11,<3",
36
36
  "pygments>=2.20.0",
37
+ "PyJWT[crypto]>=2.10,<3",
37
38
  "pyyaml",
38
39
  "requests>=2.33.0",
39
40
  "structlog",
@@ -41,9 +42,6 @@ dependencies = [
41
42
  "urllib3>=2.7.0",
42
43
  ]
43
44
 
44
- [project.optional-dependencies]
45
- server = ["PyJWT[crypto]>=2.10,<3"]
46
-
47
45
  [project.urls]
48
46
  Homepage = "https://github.com/mainsequence-sdk/mainsequence-sdk"
49
47
  Issues = "https://github.com/mainsequence-sdk/mainsequence-sdk/issues"
@@ -56,7 +54,6 @@ ms = "mainsequence.cli.cli:app"
56
54
  dev = [
57
55
  "fastapi>=0.110,<1",
58
56
  "httpx>=0.27,<1",
59
- "PyJWT[crypto]>=2.10,<3",
60
57
  "black>=26.3.1",
61
58
  "IPython",
62
59
  "mkdocs",
@@ -4,13 +4,12 @@ import json
4
4
  import time
5
5
  from uuid import uuid4
6
6
 
7
+ import jwt
7
8
  import pytest
8
9
  import requests
10
+ from cryptography.hazmat.primitives.asymmetric import ed25519
9
11
 
10
- jwt = pytest.importorskip("jwt")
11
- ed25519 = pytest.importorskip("cryptography.hazmat.primitives.asymmetric.ed25519")
12
-
13
- from mainsequence.server.caller_assertions import ( # noqa: E402
12
+ from mainsequence.server.caller_assertions import (
14
13
  ASSERTION_TYPE,
15
14
  CallerAssertionUnavailable,
16
15
  CallerAssertionVerifier,
@@ -6,6 +6,7 @@ import tomllib
6
6
  import types
7
7
 
8
8
  import pytest
9
+ from packaging.requirements import Requirement
9
10
 
10
11
 
11
12
  def _snapshot_mainsequence_modules() -> dict[str, types.ModuleType]:
@@ -57,3 +58,34 @@ def test_streamlit_is_absent_from_dependency_contracts() -> None:
57
58
  )
58
59
  assert '\nname = "streamlit"\n' not in (repo_root / "uv.lock").read_text(encoding="utf-8")
59
60
  assert "streamlit" not in (repo_root / "requirements.txt").read_text(encoding="utf-8").lower()
61
+
62
+
63
+ def test_caller_verification_dependencies_are_required() -> None:
64
+ repo_root = pathlib.Path(__file__).resolve().parents[1]
65
+ project = tomllib.loads((repo_root / "pyproject.toml").read_text(encoding="utf-8"))["project"]
66
+ dependencies = {
67
+ requirement.name.lower(): requirement
68
+ for requirement in map(Requirement, project["dependencies"])
69
+ }
70
+
71
+ assert "pyjwt" in dependencies
72
+ assert dependencies["pyjwt"].marker is None
73
+ assert "crypto" in dependencies["pyjwt"].extras
74
+ assert "server" not in project.get("optional-dependencies", {})
75
+
76
+ lock = tomllib.loads((repo_root / "uv.lock").read_text(encoding="utf-8"))
77
+ sdk = next(package for package in lock["package"] if package["name"] == "mainsequence")
78
+ jwt_dependency = next(item for item in sdk["dependencies"] if item["name"] == "pyjwt")
79
+ assert "crypto" in jwt_dependency["extra"]
80
+ assert "server" not in sdk.get("optional-dependencies", {})
81
+ assert "server" not in sdk["metadata"].get("provides-extras", [])
82
+
83
+ requirements = {
84
+ requirement.name.lower(): requirement
85
+ for line in (repo_root / "requirements.txt").read_text(encoding="utf-8").splitlines()
86
+ if line.strip() and not line.lstrip().startswith(("#", "-"))
87
+ for requirement in [Requirement(line)]
88
+ }
89
+ for name in ("pyjwt", "cryptography"):
90
+ assert name in requirements
91
+ assert requirements[name].marker is None
@@ -1 +0,0 @@
1
- """Optional server-side platform integrations. Import integrations explicitly."""