simulo-interfaces 0.10.0__tar.gz → 0.11.0__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 (54) hide show
  1. {simulo_interfaces-0.10.0/src/simulo_interfaces.egg-info → simulo_interfaces-0.11.0}/PKG-INFO +6 -5
  2. {simulo_interfaces-0.10.0 → simulo_interfaces-0.11.0}/pyproject.toml +11 -2
  3. {simulo_interfaces-0.10.0 → simulo_interfaces-0.11.0}/src/simulo/interfaces/authoring/__init__.py +5 -4
  4. {simulo_interfaces-0.10.0 → simulo_interfaces-0.11.0}/src/simulo/interfaces/authoring/asset.py +24 -17
  5. {simulo_interfaces-0.10.0 → simulo_interfaces-0.11.0}/src/simulo/interfaces/authoring/entity.py +3 -3
  6. {simulo_interfaces-0.10.0 → simulo_interfaces-0.11.0}/src/simulo/interfaces/authoring/robot.py +2 -2
  7. {simulo_interfaces-0.10.0 → simulo_interfaces-0.11.0}/src/simulo/interfaces/platform/__init__.py +9 -0
  8. {simulo_interfaces-0.10.0 → simulo_interfaces-0.11.0}/src/simulo/interfaces/platform/asset.py +2 -2
  9. {simulo_interfaces-0.10.0 → simulo_interfaces-0.11.0}/src/simulo/interfaces/platform/runs.py +49 -1
  10. {simulo_interfaces-0.10.0 → simulo_interfaces-0.11.0/src/simulo_interfaces.egg-info}/PKG-INFO +6 -5
  11. {simulo_interfaces-0.10.0 → simulo_interfaces-0.11.0}/src/simulo_interfaces.egg-info/requires.txt +5 -4
  12. {simulo_interfaces-0.10.0 → simulo_interfaces-0.11.0}/MANIFEST.in +0 -0
  13. {simulo_interfaces-0.10.0 → simulo_interfaces-0.11.0}/PYPI.md +0 -0
  14. {simulo_interfaces-0.10.0 → simulo_interfaces-0.11.0}/setup.cfg +0 -0
  15. {simulo_interfaces-0.10.0 → simulo_interfaces-0.11.0}/src/simulo/interfaces/__init__.py +0 -0
  16. {simulo_interfaces-0.10.0 → simulo_interfaces-0.11.0}/src/simulo/interfaces/authoring/actuator.py +0 -0
  17. {simulo_interfaces-0.10.0 → simulo_interfaces-0.11.0}/src/simulo/interfaces/authoring/light.py +0 -0
  18. {simulo_interfaces-0.10.0 → simulo_interfaces-0.11.0}/src/simulo/interfaces/authoring/materials.py +0 -0
  19. {simulo_interfaces-0.10.0 → simulo_interfaces-0.11.0}/src/simulo/interfaces/authoring/physics.py +0 -0
  20. {simulo_interfaces-0.10.0 → simulo_interfaces-0.11.0}/src/simulo/interfaces/authoring/pose.py +0 -0
  21. {simulo_interfaces-0.10.0 → simulo_interfaces-0.11.0}/src/simulo/interfaces/authoring/primitives.py +0 -0
  22. {simulo_interfaces-0.10.0 → simulo_interfaces-0.11.0}/src/simulo/interfaces/authoring/record.py +0 -0
  23. {simulo_interfaces-0.10.0 → simulo_interfaces-0.11.0}/src/simulo/interfaces/authoring/scene.py +0 -0
  24. {simulo_interfaces-0.10.0 → simulo_interfaces-0.11.0}/src/simulo/interfaces/authoring/sensor.py +0 -0
  25. {simulo_interfaces-0.10.0 → simulo_interfaces-0.11.0}/src/simulo/interfaces/authoring/terrain.py +0 -0
  26. {simulo_interfaces-0.10.0 → simulo_interfaces-0.11.0}/src/simulo/interfaces/authoring/visual.py +0 -0
  27. {simulo_interfaces-0.10.0 → simulo_interfaces-0.11.0}/src/simulo/interfaces/authoring/world.py +0 -0
  28. {simulo_interfaces-0.10.0 → simulo_interfaces-0.11.0}/src/simulo/interfaces/exceptions.py +0 -0
  29. {simulo_interfaces-0.10.0 → simulo_interfaces-0.11.0}/src/simulo/interfaces/ids.py +0 -0
  30. {simulo_interfaces-0.10.0 → simulo_interfaces-0.11.0}/src/simulo/interfaces/platform/app.py +0 -0
  31. {simulo_interfaces-0.10.0 → simulo_interfaces-0.11.0}/src/simulo/interfaces/platform/artifacts.py +0 -0
  32. {simulo_interfaces-0.10.0 → simulo_interfaces-0.11.0}/src/simulo/interfaces/platform/asset_catalog.py +0 -0
  33. {simulo_interfaces-0.10.0 → simulo_interfaces-0.11.0}/src/simulo/interfaces/platform/callbacks.py +0 -0
  34. {simulo_interfaces-0.10.0 → simulo_interfaces-0.11.0}/src/simulo/interfaces/platform/debug.py +0 -0
  35. {simulo_interfaces-0.10.0 → simulo_interfaces-0.11.0}/src/simulo/interfaces/platform/domain.py +0 -0
  36. {simulo_interfaces-0.10.0 → simulo_interfaces-0.11.0}/src/simulo/interfaces/platform/enums.py +0 -0
  37. {simulo_interfaces-0.10.0 → simulo_interfaces-0.11.0}/src/simulo/interfaces/platform/manifest.py +0 -0
  38. {simulo_interfaces-0.10.0 → simulo_interfaces-0.11.0}/src/simulo/interfaces/platform/runtime.py +0 -0
  39. {simulo_interfaces-0.10.0 → simulo_interfaces-0.11.0}/src/simulo/interfaces/platform/submit.py +0 -0
  40. {simulo_interfaces-0.10.0 → simulo_interfaces-0.11.0}/src/simulo/interfaces/platform/volume.py +0 -0
  41. {simulo_interfaces-0.10.0 → simulo_interfaces-0.11.0}/src/simulo/interfaces/py.typed +0 -0
  42. {simulo_interfaces-0.10.0 → simulo_interfaces-0.11.0}/src/simulo/interfaces/runtime/__init__.py +0 -0
  43. {simulo_interfaces-0.10.0 → simulo_interfaces-0.11.0}/src/simulo/interfaces/runtime/anomaly.py +0 -0
  44. {simulo_interfaces-0.10.0 → simulo_interfaces-0.11.0}/src/simulo/interfaces/runtime/components.py +0 -0
  45. {simulo_interfaces-0.10.0 → simulo_interfaces-0.11.0}/src/simulo/interfaces/runtime/env.py +0 -0
  46. {simulo_interfaces-0.10.0 → simulo_interfaces-0.11.0}/src/simulo/interfaces/runtime/player.py +0 -0
  47. {simulo_interfaces-0.10.0 → simulo_interfaces-0.11.0}/src/simulo/interfaces/runtime/policy.py +0 -0
  48. {simulo_interfaces-0.10.0 → simulo_interfaces-0.11.0}/src/simulo/interfaces/runtime/scenario.py +0 -0
  49. {simulo_interfaces-0.10.0 → simulo_interfaces-0.11.0}/src/simulo/interfaces/runtime/task.py +0 -0
  50. {simulo_interfaces-0.10.0 → simulo_interfaces-0.11.0}/src/simulo/interfaces/runtime/tensors.py +0 -0
  51. {simulo_interfaces-0.10.0 → simulo_interfaces-0.11.0}/src/simulo/interfaces/runtime/trainer.py +0 -0
  52. {simulo_interfaces-0.10.0 → simulo_interfaces-0.11.0}/src/simulo_interfaces.egg-info/SOURCES.txt +0 -0
  53. {simulo_interfaces-0.10.0 → simulo_interfaces-0.11.0}/src/simulo_interfaces.egg-info/dependency_links.txt +0 -0
  54. {simulo_interfaces-0.10.0 → simulo_interfaces-0.11.0}/src/simulo_interfaces.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: simulo-interfaces
3
- Version: 0.10.0
3
+ Version: 0.11.0
4
4
  Summary: Type contracts for the Simulo SDK. Installed automatically as a dependency of the simulo package.
5
5
  Author-email: Simulo Team <team@simulo.ai>
6
6
  License: BSD-3-Clause
@@ -16,13 +16,14 @@ Classifier: Typing :: Typed
16
16
  Requires-Python: >=3.11
17
17
  Description-Content-Type: text/markdown
18
18
  Provides-Extra: dev
19
- Requires-Dist: black>=24.0; extra == "dev"
20
- Requires-Dist: isort>=5.13; extra == "dev"
21
- Requires-Dist: ruff>=0.5; extra == "dev"
22
- Requires-Dist: mypy>=1.10; extra == "dev"
19
+ Requires-Dist: black==26.5.1; extra == "dev"
20
+ Requires-Dist: isort==8.0.1; extra == "dev"
21
+ Requires-Dist: ruff==0.15.21; extra == "dev"
22
+ Requires-Dist: mypy==2.3.0; extra == "dev"
23
23
  Requires-Dist: pytest>=8.2; extra == "dev"
24
24
  Requires-Dist: build>=1.2; extra == "dev"
25
25
  Requires-Dist: twine>=5.1; extra == "dev"
26
+ Requires-Dist: packaging>=23; extra == "dev"
26
27
  Provides-Extra: release
27
28
  Requires-Dist: commitizen>=3.27; extra == "release"
28
29
  Requires-Dist: build>=1.2; extra == "release"
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "simulo-interfaces"
7
- version = "0.10.0"
7
+ version = "0.11.0"
8
8
  description = "Type contracts for the Simulo SDK. Installed automatically as a dependency of the simulo package."
9
9
  readme = "PYPI.md"
10
10
  requires-python = ">=3.11"
@@ -26,7 +26,16 @@ classifiers = [
26
26
  dependencies = []
27
27
 
28
28
  [project.optional-dependencies]
29
- dev = ["black>=24.0", "isort>=5.13", "ruff>=0.5", "mypy>=1.10", "pytest>=8.2", "build>=1.2", "twine>=5.1"]
29
+ # black/isort/ruff/mypy pinned EXACT, not >=: see simulo-backend/pyproject.toml's
30
+ # `dev` extra for the full rationale (2026-08-01 ruff 0.15.21->0.16.1 CI incident).
31
+ # Keep in lockstep with `.github/workflows/simulo-interfaces-ci.yml`'s
32
+ # `ruff`/`black`/`isort`/`mypy` steps, which resolve their versions from THIS extra
33
+ # (`pip install -e ".[dev]"`).
34
+ dev = ["black==26.5.1", "isort==8.0.1", "ruff==0.15.21", "mypy==2.3.0", "pytest>=8.2", "build>=1.2",
35
+ "twine>=5.1", "packaging>=23"]
36
+ # `packaging` is a direct test dependency, not incidental: the consumer-pin guard parses
37
+ # PEP 508 requirements with it. It arrives transitively via pytest today, which is exactly
38
+ # why it is declared here — a transitive dep that disappears takes the guard with it.
30
39
  # `dev` carries build/twine but deliberately not commitizen; `release` below
31
40
  # adds commitizen for cutting version bumps without a second build/twine copy.
32
41
  release = ["commitizen>=3.27", "build>=1.2", "twine>=5.1"]
@@ -11,9 +11,10 @@ working because only this definition exists.
11
11
 
12
12
  Relocated so far — Wave C1: ``pose`` (``Pose``), ``materials`` (``Material``,
13
13
  ``SurfaceMaterial``), ``physics`` (``Physics``, ``Collision``, ``RigidPhysics``,
14
- ``DeformableMaterial``, ``DeformablePhysics``), ``asset`` (``Asset``,
14
+ ``DeformableMaterial``, ``DeformablePhysics``), ``asset`` (``AssetSource``,
15
15
  ``USDAsset``, ``URDFAsset`` — the model-source specs, distinct from the thin
16
- client's registry-handle ``simulo.Asset``), and ``light`` (``Light``,
16
+ client's registry-handle ``simulo.Asset``; renamed from ``Asset`` — owner
17
+ decision — to resolve that exact name collision), and ``light`` (``Light``,
17
18
  ``LightConfig``, ``DistantLight``, ``DomeLight``). Wave C2: ``terrain``
18
19
  (``Terrain``, ``TerrainConfig``, ``GroundPlane``, ``SubTerrainConfig``,
19
20
  ``RoughTerrain``), ``primitives`` (``PrimitiveShape``, ``Cone``,
@@ -85,7 +86,7 @@ docstring, is the source of truth for what lands here and when.
85
86
  """
86
87
 
87
88
  from simulo.interfaces.authoring.actuator import ActuatorProtocol
88
- from simulo.interfaces.authoring.asset import Asset, URDFAsset, USDAsset
89
+ from simulo.interfaces.authoring.asset import AssetSource, URDFAsset, USDAsset
89
90
  from simulo.interfaces.authoring.entity import AssetEntity, Entity
90
91
  from simulo.interfaces.authoring.light import DistantLight, DomeLight, Light, LightConfig
91
92
  from simulo.interfaces.authoring.materials import Material, SurfaceMaterial
@@ -139,7 +140,7 @@ __all__ = [
139
140
  "DeformablePhysics",
140
141
  "Physics",
141
142
  # asset (model-source specs)
142
- "Asset",
143
+ "AssetSource",
143
144
  "USDAsset",
144
145
  "URDFAsset",
145
146
  # light
@@ -1,10 +1,16 @@
1
1
  """Model-source asset specs — USD/URDF sources a scene loads.
2
2
 
3
- Owns the canonical ``Asset`` / ``USDAsset`` / ``URDFAsset`` model-source
3
+ Owns the canonical ``AssetSource`` / ``USDAsset`` / ``URDFAsset`` model-source
4
4
  dataclasses. Distinct from the thin client's user-facing ``simulo.Asset``
5
5
  registry handle (a catalog ref like ``robot/so-arm-100:v3``): these classes
6
6
  name a USD/URDF *file source* to load into a scene, and the backend consumes
7
7
  them when it builds the simulation.
8
+
9
+ Renamed from ``Asset`` (owner decision): the old name collided with the
10
+ thin client's registry-handle ``simulo.Asset`` — same name, different
11
+ constructor, different members, both user-facing. Nothing failed on the
12
+ collision (both expose ``.usd()``/``.urdf()``, the handle's just returns
13
+ ``Any``), which is exactly why it was worth a rename rather than a shim.
8
14
  """
9
15
 
10
16
  from dataclasses import dataclass
@@ -12,16 +18,16 @@ from typing import TYPE_CHECKING
12
18
 
13
19
 
14
20
  @dataclass
15
- class Asset:
16
- """Base asset class."""
21
+ class AssetSource:
22
+ """Base model-source asset class."""
17
23
 
18
24
  if TYPE_CHECKING:
19
- # ``Asset.usd`` / ``Asset.urdf`` are attached dynamically below (they
20
- # return the ``USDAsset`` / ``URDFAsset`` subclasses, which are defined
21
- # after this class). These declarations never execute; they exist so a
22
- # type checker sees the convenience aliases with their precise
23
- # signatures instead of rejecting ``Asset.usd(...)`` as an unknown
24
- # attribute.
25
+ # ``AssetSource.usd`` / ``AssetSource.urdf`` are attached dynamically
26
+ # below (they return the ``USDAsset`` / ``URDFAsset`` subclasses,
27
+ # which are defined after this class). These declarations never
28
+ # execute; they exist so a type checker sees the convenience aliases
29
+ # with their precise signatures instead of rejecting
30
+ # ``AssetSource.usd(...)`` as an unknown attribute.
25
31
  @classmethod
26
32
  def usd(cls, path: str) -> "USDAsset": ...
27
33
 
@@ -30,7 +36,7 @@ class Asset:
30
36
 
31
37
 
32
38
  @dataclass
33
- class USDAsset(Asset):
39
+ class USDAsset(AssetSource):
34
40
  """USD file asset.
35
41
 
36
42
  Attributes:
@@ -59,7 +65,7 @@ class USDAsset(Asset):
59
65
 
60
66
 
61
67
  @dataclass
62
- class URDFAsset(Asset):
68
+ class URDFAsset(AssetSource):
63
69
  """URDF file asset.
64
70
 
65
71
  Attributes:
@@ -81,12 +87,13 @@ class URDFAsset(Asset):
81
87
  return cls(path=path)
82
88
 
83
89
 
84
- # Alias for convenience — callers reach for `Asset.usd(...)` / `Asset.urdf(...)`.
85
- # Attached dynamically; the TYPE_CHECKING declarations on Asset above are what
86
- # let a type checker see them.
87
- Asset.usd = USDAsset.usd # type: ignore[method-assign]
88
- Asset.urdf = URDFAsset.urdf # type: ignore[method-assign]
90
+ # Alias for convenience — callers reach for `AssetSource.usd(...)` /
91
+ # `AssetSource.urdf(...)`.
92
+ # Attached dynamically; the TYPE_CHECKING declarations on AssetSource above
93
+ # are what let a type checker see them.
94
+ AssetSource.usd = USDAsset.usd # type: ignore[method-assign]
95
+ AssetSource.urdf = URDFAsset.urdf # type: ignore[method-assign]
89
96
 
90
97
  # Explicit public surface — keeps the TYPE_CHECKING import (needed for the
91
98
  # static-only `usd`/`urdf` declarations above) off the star-import namespace.
92
- __all__ = ["Asset", "USDAsset", "URDFAsset"]
99
+ __all__ = ["AssetSource", "USDAsset", "URDFAsset"]
@@ -3,7 +3,7 @@
3
3
  from dataclasses import dataclass, field
4
4
  from typing import Optional, Tuple
5
5
 
6
- from simulo.interfaces.authoring.asset import Asset
6
+ from simulo.interfaces.authoring.asset import AssetSource
7
7
  from simulo.interfaces.authoring.materials import Material
8
8
  from simulo.interfaces.authoring.physics import DeformablePhysics, RigidPhysics
9
9
  from simulo.interfaces.authoring.pose import Pose
@@ -147,7 +147,7 @@ class Entity:
147
147
  @staticmethod
148
148
  def from_asset(
149
149
  name: str,
150
- asset: Asset,
150
+ asset: AssetSource,
151
151
  pose: Optional[Pose] = None,
152
152
  ) -> "AssetEntity":
153
153
  """Create an entity from a USD or URDF asset.
@@ -177,4 +177,4 @@ class AssetEntity(Entity):
177
177
  existing dataclass field ordering. Callers always supply this.
178
178
  """
179
179
 
180
- asset: Optional[Asset] = None
180
+ asset: Optional[AssetSource] = None
@@ -61,7 +61,7 @@ entry in the backend conformance test's documented-omissions allowlist):
61
61
 
62
62
  from typing import Any, Dict, List, Optional, Protocol, Tuple, runtime_checkable
63
63
 
64
- from simulo.interfaces.authoring.asset import Asset
64
+ from simulo.interfaces.authoring.asset import AssetSource
65
65
  from simulo.interfaces.authoring.pose import Pose
66
66
  from simulo.interfaces.runtime.tensors import TensorLike
67
67
 
@@ -142,7 +142,7 @@ class RobotProtocol(Protocol):
142
142
  # -- Construction-time configuration (plain data members: genuinely
143
143
  # -- mutable attributes on the implementation, per mirror-fidelity rule).
144
144
 
145
- asset: Asset
145
+ asset: AssetSource
146
146
  """Model source (USD or URDF) defining the robot."""
147
147
 
148
148
  initial_pose: Pose
@@ -112,9 +112,13 @@ from simulo.interfaces.platform.manifest import (
112
112
  )
113
113
  from simulo.interfaces.platform.runs import (
114
114
  JOB_CANCEL_ROUTE_TEMPLATE,
115
+ JOB_LIST_SCOPES,
115
116
  JOB_LOGS_ROUTE_TEMPLATE,
116
117
  JOB_RESULT_ROUTE_TEMPLATE,
117
118
  JOB_ROUTE_TEMPLATE,
119
+ JOB_SCOPE_MINE,
120
+ JOB_SCOPE_ORG,
121
+ JOB_SCOPE_QUERY_PARAM,
118
122
  JOBS_API_DEFAULT_PORT,
119
123
  JOBS_ROUTE,
120
124
  LOG_CHUNK_MAX_BYTES,
@@ -216,6 +220,11 @@ __all__ = [
216
220
  "JOB_RESULT_ROUTE_TEMPLATE",
217
221
  "LOG_CHUNK_MAX_BYTES",
218
222
  "LOG_TAIL_MAX_BYTES",
223
+ # user scoping (issue #651)
224
+ "JOB_SCOPE_QUERY_PARAM",
225
+ "JOB_SCOPE_MINE",
226
+ "JOB_SCOPE_ORG",
227
+ "JOB_LIST_SCOPES",
219
228
  # submit / worker / recordings wire contract (PR-0)
220
229
  "PACKAGES_ROUTE",
221
230
  "PACKAGE_ARCHIVE_ROUTE_TEMPLATE",
@@ -7,8 +7,8 @@ from typing import Protocol, runtime_checkable
7
7
  class AssetProtocol(Protocol):
8
8
  """Read-only mounted cloud resource handle (Rule #6). FORWARD.
9
9
 
10
- Distinct from ``simulo.interfaces.authoring.asset.Asset`` (a USD/URDF
11
- model-source simulation asset).
10
+ Distinct from ``simulo.interfaces.authoring.asset.AssetSource`` (a
11
+ USD/URDF model-source simulation asset).
12
12
 
13
13
  This is the user-facing *handle* protocol; the asset-catalog **wire**
14
14
  contract (ref grammar, routes, caps, wire dataclasses) lives in
@@ -92,6 +92,31 @@ That scoping is additive at the transport layer: the :class:`JobRecord`
92
92
  fields and route shapes defined here do not change, only the server-side
93
93
  filtering they are evaluated under.
94
94
 
95
+ **User scoping (``?scope=``, additive):** within one organization,
96
+ ``GET /v1/jobs`` and every per-job route (``{job_id}``, ``{job_id}/logs``,
97
+ ``{job_id}/result``, and the sibling recordings/models/artifacts/view-session
98
+ routes documented in ``submit.py``) additionally accept an optional
99
+ ``?scope=mine|org`` query parameter, resolved server-side:
100
+
101
+ * ``mine`` (the default — the value an old client that never sends the
102
+ parameter gets) — only jobs this caller themselves submitted
103
+ (``submitted_by_user_id`` on the job row).
104
+ * ``org`` — every job in the caller's organization. An explicit opt-in,
105
+ never the default, and available to any active member (no additional role
106
+ beyond org membership — the platform's existing flat-permission model for
107
+ jobs, ``JOB_CREATE_ROLES``/``JOB_CANCEL_ROLES``).
108
+ * any other value → 422 (Job.md "List All Jobs Using CLI" AF-3, invalid
109
+ filter option).
110
+
111
+ ``POST /v1/jobs/{job_id}/cancel`` is a deliberate exception: it is NOT scope-
112
+ gated and keeps resolving org-wide regardless of ``?scope=`` — any active
113
+ member may cancel any job in their org, matching cancel's existing,
114
+ unchanged authorization model.
115
+
116
+ :class:`JobRecord` gains ``submitted_by_user_id`` (below) precisely so an
117
+ ``org``-scoped listing is attributable — a shared view of everyone's jobs
118
+ must say whose job each row is.
119
+
95
120
  Errors use the platform-standard shape (NFR contract)::
96
121
 
97
122
  {"error": {"code": "job_not_found", "message": "...", "request_id": "req_..."}}
@@ -125,9 +150,20 @@ JOB_RESULT_ROUTE_TEMPLATE = "/v1/jobs/{job_id}/result"
125
150
  #: executor); 202 ``{"cancel_requested": true}`` (running — the executor
126
151
  #: stops it within one heartbeat interval); 409 ``job_not_running``
127
152
  #: (already terminal); 404 ``job_not_found``. Full semantics in the module
128
- #: docstring above.
153
+ #: docstring above. NOT scope-gated (module docstring's "User scoping" note)
154
+ #: — cancel keeps resolving org-wide regardless of ``?scope=``.
129
155
  JOB_CANCEL_ROUTE_TEMPLATE = "/v1/jobs/{job_id}/cancel"
130
156
 
157
+ #: The ``?scope=`` query parameter name accepted by ``GET /v1/jobs`` and
158
+ #: every per-job read route (module docstring's "User scoping" section).
159
+ JOB_SCOPE_QUERY_PARAM = "scope"
160
+ #: Default / explicit-opt-in-only values for :data:`JOB_SCOPE_QUERY_PARAM`.
161
+ JOB_SCOPE_MINE = "mine"
162
+ JOB_SCOPE_ORG = "org"
163
+ #: The closed domain of ``?scope=`` — any other value is a 422 (Job.md "List
164
+ #: All Jobs Using CLI" AF-3).
165
+ JOB_LIST_SCOPES = (JOB_SCOPE_MINE, JOB_SCOPE_ORG)
166
+
131
167
  #: Upper bound on the log bytes a single ``/logs`` response carries. The server
132
168
  #: may return fewer bytes (never more); clients keep reading from ``next_offset``.
133
169
  #: This is a server-side response-size POLICY value, not a structural wire
@@ -247,6 +283,18 @@ class JobRecord:
247
283
  whenever :attr:`status_reason` is ``None``. Engine-neutral by contract (a user
248
284
  surface: never names the underlying simulation runtime)."""
249
285
 
286
+ submitted_by_user_id: Optional[str] = None
287
+ """Id of the user who submitted this run, or ``None`` when unknown (the
288
+ submitting user's account was later deleted — the id column is nullable
289
+ with ``ON DELETE SET NULL``, so a job's provenance can outlive the user).
290
+
291
+ Additive + tolerant like ``assets``/``seed``/``status_reason``: a control
292
+ plane that predates the field omits it and a consumer sees the ``None``
293
+ default. Populated on every record regardless of ``?scope=`` — it is what
294
+ makes an ``org``-scoped listing attributable (module docstring's "User
295
+ scoping" section): a shared view of everyone's jobs must say whose job
296
+ each row is, not just that it exists."""
297
+
250
298
  outputs: Optional[JobOutputsSummary] = None
251
299
  """Typed outputs summary of the run — a **rendering input,
252
300
  never a status**: ``completed ⚠ 1 anomaly`` is drawn from here while
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: simulo-interfaces
3
- Version: 0.10.0
3
+ Version: 0.11.0
4
4
  Summary: Type contracts for the Simulo SDK. Installed automatically as a dependency of the simulo package.
5
5
  Author-email: Simulo Team <team@simulo.ai>
6
6
  License: BSD-3-Clause
@@ -16,13 +16,14 @@ Classifier: Typing :: Typed
16
16
  Requires-Python: >=3.11
17
17
  Description-Content-Type: text/markdown
18
18
  Provides-Extra: dev
19
- Requires-Dist: black>=24.0; extra == "dev"
20
- Requires-Dist: isort>=5.13; extra == "dev"
21
- Requires-Dist: ruff>=0.5; extra == "dev"
22
- Requires-Dist: mypy>=1.10; extra == "dev"
19
+ Requires-Dist: black==26.5.1; extra == "dev"
20
+ Requires-Dist: isort==8.0.1; extra == "dev"
21
+ Requires-Dist: ruff==0.15.21; extra == "dev"
22
+ Requires-Dist: mypy==2.3.0; extra == "dev"
23
23
  Requires-Dist: pytest>=8.2; extra == "dev"
24
24
  Requires-Dist: build>=1.2; extra == "dev"
25
25
  Requires-Dist: twine>=5.1; extra == "dev"
26
+ Requires-Dist: packaging>=23; extra == "dev"
26
27
  Provides-Extra: release
27
28
  Requires-Dist: commitizen>=3.27; extra == "release"
28
29
  Requires-Dist: build>=1.2; extra == "release"
@@ -1,12 +1,13 @@
1
1
 
2
2
  [dev]
3
- black>=24.0
4
- isort>=5.13
5
- ruff>=0.5
6
- mypy>=1.10
3
+ black==26.5.1
4
+ isort==8.0.1
5
+ ruff==0.15.21
6
+ mypy==2.3.0
7
7
  pytest>=8.2
8
8
  build>=1.2
9
9
  twine>=5.1
10
+ packaging>=23
10
11
 
11
12
  [release]
12
13
  commitizen>=3.27