matelab-python-sdk 0.1.0a16__tar.gz → 0.1.0a17__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 (65) hide show
  1. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/CHANGELOG.md +13 -0
  2. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/PKG-INFO +30 -21
  3. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/README.md +29 -20
  4. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/contracts/matelab-integration-v1.lock.json +3 -3
  5. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/contracts/matelab-integration-v1.openapi.yaml +59 -8
  6. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/docs/operation-coverage.yaml +4 -4
  7. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/pyproject.toml +1 -1
  8. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/src/matelab/_generated/models.py +407 -42
  9. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/src/matelab/_transport.py +9 -4
  10. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/src/matelab/errors.py +6 -3
  11. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/tests/test_client.py +1 -1
  12. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/tests/test_cloud_drive.py +3 -1
  13. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/tests/test_errors.py +11 -1
  14. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/tests/test_generation.py +17 -3
  15. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/tests/test_streaming.py +8 -4
  16. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/tests/test_template_lifecycle.py +9 -2
  17. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/tests/test_transport.py +28 -13
  18. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/tests/typing/consumer.py +1 -1
  19. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/uv.lock +1 -1
  20. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/.env.example +0 -0
  21. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/.github/workflows/release.yml +0 -0
  22. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/.gitignore +0 -0
  23. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/AGENTS.md +0 -0
  24. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/CONTEXT.md +0 -0
  25. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/LICENSE +0 -0
  26. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/NOTICE +0 -0
  27. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/scripts/check_installed_package.py +0 -0
  28. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/scripts/check_release.py +0 -0
  29. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/scripts/generate_models.py +0 -0
  30. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/src/matelab/__init__.py +0 -0
  31. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/src/matelab/_generated/__init__.py +0 -0
  32. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/src/matelab/_hashes.py +0 -0
  33. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/src/matelab/_wire_validation.py +0 -0
  34. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/src/matelab/client.py +0 -0
  35. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/src/matelab/domains/__init__.py +0 -0
  36. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/src/matelab/domains/_attachment_content.py +0 -0
  37. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/src/matelab/domains/cloud_drive.py +0 -0
  38. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/src/matelab/domains/groups.py +0 -0
  39. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/src/matelab/domains/literature.py +0 -0
  40. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/src/matelab/domains/notebooks.py +0 -0
  41. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/src/matelab/domains/records.py +0 -0
  42. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/src/matelab/domains/templates.py +0 -0
  43. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/src/matelab/domains/uploads.py +0 -0
  44. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/src/matelab/domains/users.py +0 -0
  45. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/src/matelab/py.typed +0 -0
  46. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/src/matelab/session.py +0 -0
  47. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/src/matelab/streaming.py +0 -0
  48. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/tests/conftest.py +0 -0
  49. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/tests/provider/test_provider_smoke.py +0 -0
  50. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/tests/test_async_attachment_upload.py +0 -0
  51. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/tests/test_comments_and_downloads.py +0 -0
  52. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/tests/test_consumer_smoke.py +0 -0
  53. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/tests/test_extended_records.py +0 -0
  54. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/tests/test_groups.py +0 -0
  55. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/tests/test_notebook_lifecycle.py +0 -0
  56. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/tests/test_notebooks.py +0 -0
  57. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/tests/test_operation_coverage.py +0 -0
  58. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/tests/test_record_lifecycle.py +0 -0
  59. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/tests/test_record_mutations.py +0 -0
  60. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/tests/test_records.py +0 -0
  61. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/tests/test_release.py +0 -0
  62. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/tests/test_templates.py +0 -0
  63. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/tests/test_uploads_and_literature.py +0 -0
  64. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/tests/test_users.py +0 -0
  65. {matelab_python_sdk-0.1.0a16 → matelab_python_sdk-0.1.0a17}/tests/typing/pyproject.toml +0 -0
@@ -3,6 +3,19 @@
3
3
  This file records release-to-release changes and migration impact. It is not the authority for the current interface;
4
4
  see [README.md](README.md) for current behavior and [AGENTS.md](AGENTS.md) for maintenance policy.
5
5
 
6
+ ## 0.1.0a17 - 2026-08-20
7
+
8
+ - Adopts immutable `matelab-spec v0.4.1` at commit `6f8ab3d14797385d0075d0aba38bf3bf529e674d` and OpenAPI
9
+ SHA-256 `73d899c9e60b59f9521062ffcfaaae5f073eea36f24f3e535fcb53f12242581c`. The standard wire structure is
10
+ unchanged from v0.4.0. PVD-041 and PCG-015 confirm that optional code-4 `errs` remains opaque, potentially sensitive
11
+ and unsafe to expose as a stable typed SDK interface without stronger Provider evidence and a future Contract release.
12
+ - Breaking: `MatelabProviderError` construction now requires `provider_code`, `provider_message`, and `category`.
13
+ Transport and download errors preserve the Provider envelope's numeric `code` and expose an SDK-owned safe summary
14
+ instead of copying Provider-authored diagnostics into exceptions. The stable recovery interface remains `category`
15
+ plus conservative `retryable=False`; raw Provider codes are diagnostic rather than stable routing identifiers.
16
+ Exceptions exclude the response body, top-level `msg`, legacy `errmsg`, opaque `errs`, uncontracted debug fields, and
17
+ request payloads because Provider text may contain stack traces, credentials, or submitted values.
18
+
6
19
  ## 0.1.0a16 - 2026-08-14
7
20
 
8
21
  - Breaking: `UserSummary.display_name` is renamed to `name`; the SDK exposes the Provider's raw nullable real name
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: matelab-python-sdk
3
- Version: 0.1.0a16
3
+ Version: 0.1.0a17
4
4
  Summary: Reusable async Python client for the Matelab Integration Contract
5
5
  Author-email: 朱天念 <zhutiannian@gmail.com>
6
6
  License-Expression: Apache-2.0
@@ -35,10 +35,10 @@ This README describes the current SDK interface, integration semantics, examples
35
35
  [AGENTS.md](AGENTS.md) for durable maintenance rules, and `docs/operation-coverage.yaml` for the machine-readable
36
36
  operation inventory.
37
37
 
38
- The current alpha is `0.1.0a16`. `[project].version` in `pyproject.toml` is the sole SDK version source;
38
+ The current alpha is `0.1.0a17`. `[project].version` in `pyproject.toml` is the sole SDK version source;
39
39
  `uv.lock` only mirrors that source.
40
40
 
41
- The SDK is pinned to the immutable `matelab-spec v0.4.0` Contract Release. The sole release pin is
41
+ The SDK is pinned to the immutable `matelab-spec v0.4.1` Contract Release. The sole release pin is
42
42
  `contracts/matelab-integration-v1.lock.json`, which records
43
43
  the source tag, commit, OpenAPI path, local snapshot path, and SHA-256.
44
44
 
@@ -64,7 +64,7 @@ To test the same artifact a downstream Consumer will install, build and install
64
64
 
65
65
  ```bash
66
66
  uv build --no-build-isolation --out-dir dist/release
67
- python -m pip install dist/release/matelab_python_sdk-0.1.0a16-py3-none-any.whl
67
+ python -m pip install dist/release/matelab_python_sdk-0.1.0a17-py3-none-any.whl
68
68
  ```
69
69
 
70
70
  Do not infer Provider compatibility from the SDK version alone. A release is also bound to the Contract
@@ -93,29 +93,37 @@ explicitly when needed, for example `AsyncMatelab("https://custom.example/api")`
93
93
  ### Error handling
94
94
 
95
95
  Catch `MatelabError` once at an integration seam. Every instance exposes a stable `category: MatelabErrorCategory` and
96
- `retryable: bool`, so an integration can copy the message, category, and retry flag without inspecting subclasses or
97
- Provider details:
96
+ `retryable: bool`. `MatelabProviderError` additionally exposes `provider_code: int` and `provider_message: str`, so a
97
+ gateway can retain a stable diagnostic code and safe summary while routing recovery through the integration-level
98
+ category:
98
99
 
99
100
  | Error | Category | Retryable | Meaning and normal response |
100
101
  |---|---|---:|---|
101
102
  | `MatelabAuthenticationError` | `AUTHENTICATION` | No | The Session or credentials cannot authenticate; obtain valid authentication before making a new call. |
102
103
  | `MatelabUsageError` | `VALIDATION` | No | The call cannot be represented safely; correct its arguments. |
103
- | `MatelabProviderError` | `BUSINESS`, `VALIDATION`, or `UPSTREAM` | No | The Provider rejected the request; route directly by `category`. |
104
+ | `MatelabProviderError` | `BUSINESS`, `VALIDATION`, or `UPSTREAM` | No | The Provider rejected the request; record `provider_code` and route recovery by `category`; `provider_message` is an SDK-owned safe summary. |
104
105
  | `MatelabTransportError` | `UPSTREAM` | No | The HTTP exchange failed; `status_code` is present for HTTP failures, and a mutation outcome may be unknown. |
105
106
  | `MatelabProtocolError` | `UPSTREAM` | No | The response violates the pinned Contract; treat it as Provider drift or an SDK defect. |
106
107
 
107
108
  For `MatelabProviderError`, the SDK maps Provider wire code `2` to `BUSINESS`, `4` to `VALIDATION`, and `3` or an
108
- unknown code to `UPSTREAM`. Authentication codes are hidden behind `MatelabAuthenticationError`; raw Provider codes
109
- are not part of the public error interface. Code `5` triggers at most one refresh and replay only for authenticated
110
- operations that explicitly enable `retry_on_access_expired`; otherwise codes `1` and `5` raise
111
- `MatelabAuthenticationError` directly.
109
+ unknown code to `UPSTREAM`. `provider_code` is diagnostic metadata, not a stable routing identifier, and integrations
110
+ must not reinterpret it instead of `category`. `provider_message` and the exception string are SDK-owned safe summaries
111
+ selected from the code mapping; they do not reproduce Provider-authored text. Authentication codes remain hidden behind
112
+ `MatelabAuthenticationError`; code `5`
113
+ triggers at most one refresh and replay only for authenticated operations that explicitly enable
114
+ `retry_on_access_expired`, otherwise codes `1` and `5` raise `MatelabAuthenticationError` directly.
112
115
  Codes `0` and `10` remain operation-specific successes selected by the pinned Contract; an operation that receives a
113
116
  success code it does not allow raises `MatelabProtocolError` rather than assigning an error category.
114
- `MatelabTransportError.status_code` remains available for HTTP failures. Provider response bodies and caller inputs are
115
- never attached to exceptions. `retryable` means the identical SDK call is safe to replay without further
116
- interpretation. It is conservatively `False` for every current SDK error because the Contract does not guarantee
117
- mutation idempotency or outcome; an integration may add a narrower operation-specific retry policy only when it owns
118
- that evidence.
117
+ `MatelabTransportError.status_code` remains available for HTTP failures. Provider response bodies, top-level `msg`,
118
+ legacy `errmsg`, opaque `errs`, uncontracted debug fields, and request payloads are not attached to exceptions because
119
+ Provider-authored diagnostics may contain stack traces, credentials, or submitted values.
120
+ The pinned v0.4.1 Contract also declares optional code-4 `errs`, but PVD-041 and PCG-015 record incompatible observed
121
+ item/container shapes and insufficient evidence for requiredness, cardinality, or exclusion from other codes. The SDK
122
+ therefore keeps those diagnostics wire-only and does not expose `errs` as stable public metadata. A typed detail
123
+ interface remains blocked until a future Contract release can define one from stronger Provider evidence. `retryable`
124
+ means the identical SDK call is safe to replay without further interpretation. It is conservatively `False` for every
125
+ current SDK error because the Contract does not guarantee mutation idempotency or outcome; an integration may add a
126
+ narrower operation-specific retry policy only when it owns that evidence.
119
127
 
120
128
  ### Session ownership
121
129
 
@@ -798,8 +806,9 @@ does not expose a signing operation, signature projection or credentials for the
798
806
  results only report whether Provider policy allows signing.
799
807
 
800
808
  Errors are separated into semantic Provider errors, authentication errors, HTTP/transport errors,
801
- Integration Contract response errors, and client-side usage errors. Provider response bodies and caller inputs do not
802
- enter exceptions.
809
+ Integration Contract response errors, and client-side usage errors. Semantic Provider errors retain only the
810
+ Contract-defined top-level code plus an SDK-owned safe summary; Provider-authored messages, response bodies, legacy
811
+ aliases, and unrelated fields do not enter exceptions.
803
812
 
804
813
  ## Development
805
814
 
@@ -892,6 +901,6 @@ uv run python scripts/check_release.py dist/release/*.whl dist/release/*.tar.gz
892
901
  ```
893
902
 
894
903
  Rebuilding the same commit with the same locked environment and `SOURCE_DATE_EPOCH` must produce
895
- byte-identical wheel and source distribution hashes. The release is bound to `matelab-spec v0.4.0`,
896
- commit `7993a7bccc213f626b9cc8124423e2b2c9e48dd7`, and OpenAPI SHA-256
897
- `e725c9649700d5b4d1c7d75fb9422d64b04a68e0308ddec29ba274d774104c8e`.
904
+ byte-identical wheel and source distribution hashes. The release is bound to `matelab-spec v0.4.1`,
905
+ commit `6f8ab3d14797385d0075d0aba38bf3bf529e674d`, and OpenAPI SHA-256
906
+ `73d899c9e60b59f9521062ffcfaaae5f073eea36f24f3e535fcb53f12242581c`.
@@ -7,10 +7,10 @@ This README describes the current SDK interface, integration semantics, examples
7
7
  [AGENTS.md](AGENTS.md) for durable maintenance rules, and `docs/operation-coverage.yaml` for the machine-readable
8
8
  operation inventory.
9
9
 
10
- The current alpha is `0.1.0a16`. `[project].version` in `pyproject.toml` is the sole SDK version source;
10
+ The current alpha is `0.1.0a17`. `[project].version` in `pyproject.toml` is the sole SDK version source;
11
11
  `uv.lock` only mirrors that source.
12
12
 
13
- The SDK is pinned to the immutable `matelab-spec v0.4.0` Contract Release. The sole release pin is
13
+ The SDK is pinned to the immutable `matelab-spec v0.4.1` Contract Release. The sole release pin is
14
14
  `contracts/matelab-integration-v1.lock.json`, which records
15
15
  the source tag, commit, OpenAPI path, local snapshot path, and SHA-256.
16
16
 
@@ -36,7 +36,7 @@ To test the same artifact a downstream Consumer will install, build and install
36
36
 
37
37
  ```bash
38
38
  uv build --no-build-isolation --out-dir dist/release
39
- python -m pip install dist/release/matelab_python_sdk-0.1.0a16-py3-none-any.whl
39
+ python -m pip install dist/release/matelab_python_sdk-0.1.0a17-py3-none-any.whl
40
40
  ```
41
41
 
42
42
  Do not infer Provider compatibility from the SDK version alone. A release is also bound to the Contract
@@ -65,29 +65,37 @@ explicitly when needed, for example `AsyncMatelab("https://custom.example/api")`
65
65
  ### Error handling
66
66
 
67
67
  Catch `MatelabError` once at an integration seam. Every instance exposes a stable `category: MatelabErrorCategory` and
68
- `retryable: bool`, so an integration can copy the message, category, and retry flag without inspecting subclasses or
69
- Provider details:
68
+ `retryable: bool`. `MatelabProviderError` additionally exposes `provider_code: int` and `provider_message: str`, so a
69
+ gateway can retain a stable diagnostic code and safe summary while routing recovery through the integration-level
70
+ category:
70
71
 
71
72
  | Error | Category | Retryable | Meaning and normal response |
72
73
  |---|---|---:|---|
73
74
  | `MatelabAuthenticationError` | `AUTHENTICATION` | No | The Session or credentials cannot authenticate; obtain valid authentication before making a new call. |
74
75
  | `MatelabUsageError` | `VALIDATION` | No | The call cannot be represented safely; correct its arguments. |
75
- | `MatelabProviderError` | `BUSINESS`, `VALIDATION`, or `UPSTREAM` | No | The Provider rejected the request; route directly by `category`. |
76
+ | `MatelabProviderError` | `BUSINESS`, `VALIDATION`, or `UPSTREAM` | No | The Provider rejected the request; record `provider_code` and route recovery by `category`; `provider_message` is an SDK-owned safe summary. |
76
77
  | `MatelabTransportError` | `UPSTREAM` | No | The HTTP exchange failed; `status_code` is present for HTTP failures, and a mutation outcome may be unknown. |
77
78
  | `MatelabProtocolError` | `UPSTREAM` | No | The response violates the pinned Contract; treat it as Provider drift or an SDK defect. |
78
79
 
79
80
  For `MatelabProviderError`, the SDK maps Provider wire code `2` to `BUSINESS`, `4` to `VALIDATION`, and `3` or an
80
- unknown code to `UPSTREAM`. Authentication codes are hidden behind `MatelabAuthenticationError`; raw Provider codes
81
- are not part of the public error interface. Code `5` triggers at most one refresh and replay only for authenticated
82
- operations that explicitly enable `retry_on_access_expired`; otherwise codes `1` and `5` raise
83
- `MatelabAuthenticationError` directly.
81
+ unknown code to `UPSTREAM`. `provider_code` is diagnostic metadata, not a stable routing identifier, and integrations
82
+ must not reinterpret it instead of `category`. `provider_message` and the exception string are SDK-owned safe summaries
83
+ selected from the code mapping; they do not reproduce Provider-authored text. Authentication codes remain hidden behind
84
+ `MatelabAuthenticationError`; code `5`
85
+ triggers at most one refresh and replay only for authenticated operations that explicitly enable
86
+ `retry_on_access_expired`, otherwise codes `1` and `5` raise `MatelabAuthenticationError` directly.
84
87
  Codes `0` and `10` remain operation-specific successes selected by the pinned Contract; an operation that receives a
85
88
  success code it does not allow raises `MatelabProtocolError` rather than assigning an error category.
86
- `MatelabTransportError.status_code` remains available for HTTP failures. Provider response bodies and caller inputs are
87
- never attached to exceptions. `retryable` means the identical SDK call is safe to replay without further
88
- interpretation. It is conservatively `False` for every current SDK error because the Contract does not guarantee
89
- mutation idempotency or outcome; an integration may add a narrower operation-specific retry policy only when it owns
90
- that evidence.
89
+ `MatelabTransportError.status_code` remains available for HTTP failures. Provider response bodies, top-level `msg`,
90
+ legacy `errmsg`, opaque `errs`, uncontracted debug fields, and request payloads are not attached to exceptions because
91
+ Provider-authored diagnostics may contain stack traces, credentials, or submitted values.
92
+ The pinned v0.4.1 Contract also declares optional code-4 `errs`, but PVD-041 and PCG-015 record incompatible observed
93
+ item/container shapes and insufficient evidence for requiredness, cardinality, or exclusion from other codes. The SDK
94
+ therefore keeps those diagnostics wire-only and does not expose `errs` as stable public metadata. A typed detail
95
+ interface remains blocked until a future Contract release can define one from stronger Provider evidence. `retryable`
96
+ means the identical SDK call is safe to replay without further interpretation. It is conservatively `False` for every
97
+ current SDK error because the Contract does not guarantee mutation idempotency or outcome; an integration may add a
98
+ narrower operation-specific retry policy only when it owns that evidence.
91
99
 
92
100
  ### Session ownership
93
101
 
@@ -770,8 +778,9 @@ does not expose a signing operation, signature projection or credentials for the
770
778
  results only report whether Provider policy allows signing.
771
779
 
772
780
  Errors are separated into semantic Provider errors, authentication errors, HTTP/transport errors,
773
- Integration Contract response errors, and client-side usage errors. Provider response bodies and caller inputs do not
774
- enter exceptions.
781
+ Integration Contract response errors, and client-side usage errors. Semantic Provider errors retain only the
782
+ Contract-defined top-level code plus an SDK-owned safe summary; Provider-authored messages, response bodies, legacy
783
+ aliases, and unrelated fields do not enter exceptions.
775
784
 
776
785
  ## Development
777
786
 
@@ -864,6 +873,6 @@ uv run python scripts/check_release.py dist/release/*.whl dist/release/*.tar.gz
864
873
  ```
865
874
 
866
875
  Rebuilding the same commit with the same locked environment and `SOURCE_DATE_EPOCH` must produce
867
- byte-identical wheel and source distribution hashes. The release is bound to `matelab-spec v0.4.0`,
868
- commit `7993a7bccc213f626b9cc8124423e2b2c9e48dd7`, and OpenAPI SHA-256
869
- `e725c9649700d5b4d1c7d75fb9422d64b04a68e0308ddec29ba274d774104c8e`.
876
+ byte-identical wheel and source distribution hashes. The release is bound to `matelab-spec v0.4.1`,
877
+ commit `6f8ab3d14797385d0075d0aba38bf3bf529e674d`, and OpenAPI SHA-256
878
+ `73d899c9e60b59f9521062ffcfaaae5f073eea36f24f3e535fcb53f12242581c`.
@@ -2,12 +2,12 @@
2
2
  "schema_version": 1,
3
3
  "contract_line": "integration-v1",
4
4
  "release": {
5
- "tag": "v0.4.0",
6
- "commit": "7993a7bccc213f626b9cc8124423e2b2c9e48dd7"
5
+ "tag": "v0.4.1",
6
+ "commit": "6f8ab3d14797385d0075d0aba38bf3bf529e674d"
7
7
  },
8
8
  "openapi": {
9
9
  "source_path": "openapi/matelab-integration-v1.openapi.yaml",
10
10
  "snapshot": "matelab-integration-v1.openapi.yaml",
11
- "sha256": "e725c9649700d5b4d1c7d75fb9422d64b04a68e0308ddec29ba274d774104c8e"
11
+ "sha256": "73d899c9e60b59f9521062ffcfaaae5f073eea36f24f3e535fcb53f12242581c"
12
12
  }
13
13
  }
@@ -1,7 +1,7 @@
1
1
  openapi: 3.1.0
2
2
  info:
3
3
  title: Matelab Integration Contract
4
- version: 0.4.0
4
+ version: 0.4.1
5
5
  description: |
6
6
  Stable PHP wire contract for the `integration-v1` contract line.
7
7
  Business failures are returned as JSON envelopes over HTTP 200.
@@ -32,6 +32,7 @@ info:
32
32
  - lib/Base.php
33
33
  - lib/Route.php
34
34
  - lib/HttpServer.php
35
+ - lib/MultiException.php
35
36
  - config/Channel.php
36
37
  - sql/eln.sql
37
38
  - sql/matelab.sql
@@ -172,6 +173,25 @@ info:
172
173
  pathSegments: 2
173
174
  readback: column-absent-and-table-rows-preserved
174
175
  cellLikeThreeSegmentPath: deletes-whole-column-not-cell
176
+ x-provider-error-diagnostics:
177
+ status: evidence-gap
178
+ tracking: [PVD-041, PCG-015]
179
+ typedPublicInterface: unsafe
180
+ code4:
181
+ errsRequired: unverified
182
+ errsMinItems: unverified
183
+ errsOnOtherCodes: not-observed-but-not-contracted
184
+ releasedContainerShape: array
185
+ sourceConfirmedArrayItemShapes: [string, object, nested-object]
186
+ sourceConfirmedContractViolations: [object-container-from-file-validator-envelope-merge]
187
+ responsibilities:
188
+ codeAndErrcode: machine-readable-envelope-status
189
+ msgAndErrmsg: human-oriented-summary-not-a-stable-identifier
190
+ errs: opaque-provider-diagnostics
191
+ securityBoundary:
192
+ trust: untrusted-potentially-sensitive
193
+ observedContent: [localized-validation-text, request-derived-values, stored-field-names]
194
+ stackTraceExclusion: not-contractually-guaranteed
175
195
  servers:
176
196
  - url: https://matelab.example.invalid
177
197
  description: Placeholder; consumers supply their Provider base URL.
@@ -1487,7 +1507,7 @@ paths:
1487
1507
  Consumers must split attachment-bearing imports into single-record
1488
1508
  requests with a distinct staged name for each request, and must not
1489
1509
  retry a failed finalize with the same name.
1490
- x-known-provider-issues: [PVD-023, PVD-024, PVD-040]
1510
+ x-known-provider-issues: [PVD-023, PVD-024, PVD-040, PVD-041]
1491
1511
  security: [{bearerAuth: []}]
1492
1512
  requestBody:
1493
1513
  required: true
@@ -1627,6 +1647,11 @@ paths:
1627
1647
  caller-owned staging or authorized existing file quotes, and binds the
1628
1648
  resulting attachments while saving the record.
1629
1649
 
1650
+ This operation does not modify record title or other record metadata.
1651
+ `UpdateRecordRequest` rejects a top-level `title`; the Front uses the
1652
+ separate, currently unsupported `/eln_items/edit` route for that use
1653
+ case. A stable Integration metadata update remains PCG-016.
1654
+
1630
1655
  Verified staged-name update shapes are enumerated by
1631
1656
  `info.x-record-attachment-staging.safeFinalizerShapes.update` and their
1632
1657
  dedicated component schemas. They cover a new form file field, setting
@@ -1649,7 +1674,7 @@ paths:
1649
1674
  consumption are not atomic. Once a finalizer begins, any write error,
1650
1675
  collaboration-pending response, response loss or failed readback leaves
1651
1676
  staging indeterminate and must not be retried.
1652
- x-known-provider-issues: [PVD-014, PVD-015, PVD-016, PVD-017, PVD-040]
1677
+ x-known-provider-issues: [PVD-014, PVD-015, PVD-016, PVD-017, PVD-040, PVD-041]
1653
1678
  security: [{bearerAuth: []}]
1654
1679
  requestBody:
1655
1680
  required: true
@@ -3456,7 +3481,7 @@ paths:
3456
3481
  both branches must verify the stored result through
3457
3482
  `readLiteratureDetail`. Create-time file binding is affected by PVD-026.
3458
3483
  x-consumer-use-case: Create canonical personal literature with an optional staged PDF, or replace the canonical metadata of a writable item.
3459
- x-known-provider-issues: [PVD-011, PVD-026, PVD-027]
3484
+ x-known-provider-issues: [PVD-011, PVD-026, PVD-027, PVD-041]
3460
3485
  security: [{bearerAuth: []}]
3461
3486
  requestBody:
3462
3487
  required: true
@@ -4062,12 +4087,19 @@ components:
4062
4087
  type: integer
4063
4088
  msg:
4064
4089
  type: string
4090
+ description: |
4091
+ Human-oriented envelope summary. Consumers must use `code` for
4092
+ branching and must not parse this text as a stable identifier,
4093
+ field location, or retry signal.
4065
4094
  errcode:
4066
4095
  type: integer
4067
4096
  description: Legacy alias of `code`; always present in these operations.
4068
4097
  errmsg:
4069
4098
  type: string
4070
- description: Legacy alias of `msg`; always present in these operations.
4099
+ description: |
4100
+ Legacy alias of `msg`; always present in these operations. It has
4101
+ the same human-summary responsibility and is not a structured
4102
+ diagnostic field.
4071
4103
  BasicSuccessResponse:
4072
4104
  allOf:
4073
4105
  - $ref: "#/components/schemas/ResponseEnvelope"
@@ -4083,7 +4115,14 @@ components:
4083
4115
  code: {enum: [0, 10]}
4084
4116
  errcode: {enum: [0, 10]}
4085
4117
  ErrorDetail:
4086
- description: A stable per-field or per-location error value returned when code is 4.
4118
+ description: |
4119
+ Intentionally unconstrained Provider diagnostic array item. Source
4120
+ evidence includes strings, structured objects, sparse objects, and
4121
+ nested error groups. Integration-v1 therefore does not promise a stable
4122
+ item shape. The separate source-confirmed object-container branch
4123
+ violates ErrorResponse and is tracked by PVD-041 and PCG-015.
4124
+ x-contract-status: evidence-gap
4125
+ x-tracking: [PVD-041, PCG-015]
4087
4126
  ErrorResponse:
4088
4127
  allOf:
4089
4128
  - $ref: "#/components/schemas/ResponseEnvelope"
@@ -4106,11 +4145,23 @@ components:
4106
4145
  type: array
4107
4146
  items:
4108
4147
  $ref: "#/components/schemas/ErrorDetail"
4109
- description: Present for multi-error code 4; absent from ordinary errors.
4148
+ description: |
4149
+ Optional array of opaque, untrusted Provider diagnostics
4150
+ observed on code 4. Integration-v1 does not constrain its
4151
+ requiredness, cardinality, item shape, order, or absence on
4152
+ other codes. Values can contain localized validation text,
4153
+ request-derived values, or stored field names and must not be
4154
+ broadly logged or displayed without sanitization. No
4155
+ stack-trace exclusion is contractually guaranteed. The
4156
+ Provider's source-confirmed object-container branch violates
4157
+ this released array contract; see PVD-041 and PCG-015.
4158
+ x-known-provider-issues: [PVD-041]
4110
4159
  description: |
4111
4160
  Stable HTTP 200 error envelope. Codes observed in the common router are:
4112
4161
  1 authentication, 2 input/permission/business failure, 3 server failure,
4113
- 4 multiple errors (`errs` present), and 5 expired access token.
4162
+ 4 multiple errors (normally with `errs`), and 5 expired access token.
4163
+ `msg`/`errmsg` summarize the envelope for people; `errs`, when present,
4164
+ carries opaque diagnostics and is not a stable public detail interface.
4114
4165
  Sha256:
4115
4166
  type: string
4116
4167
  pattern: "^[0-9a-f]{64}$"
@@ -3,7 +3,7 @@
3
3
  schema_version: 1
4
4
  contract:
5
5
  line: integration-v1
6
- release: v0.4.0
6
+ release: v0.4.1
7
7
  operation_count: 71
8
8
 
9
9
  operations:
@@ -259,7 +259,7 @@ operations:
259
259
  state: implemented
260
260
  stability: experimental
261
261
  public_interface: AsyncMatelab.records.import_dataset
262
- known_issues: [PCG-008, PCG-014, PVD-023, PVD-024, PVD-040]
262
+ known_issues: [PCG-008, PCG-014, PVD-023, PVD-024, PVD-040, PVD-041]
263
263
 
264
264
  - operation_id: exportRecords
265
265
  method: POST
@@ -286,7 +286,7 @@ operations:
286
286
  state: implemented
287
287
  stability: experimental
288
288
  public_interface: AsyncMatelab.records.update
289
- known_issues: [PCG-001, PCG-002, PCG-014, PVD-014, PVD-015, PVD-016, PVD-017, PVD-040]
289
+ known_issues: [PCG-001, PCG-002, PCG-014, PVD-014, PVD-015, PVD-016, PVD-017, PVD-040, PVD-041]
290
290
 
291
291
  - operation_id: deleteRecordsByUid
292
292
  method: POST
@@ -540,7 +540,7 @@ operations:
540
540
  state: implemented
541
541
  stability: experimental
542
542
  public_interface: AsyncMatelab.literature.create / AsyncMatelab.literature.update
543
- known_issues: [PCG-010, PVD-011, PVD-026, PVD-027]
543
+ known_issues: [PCG-010, PVD-011, PVD-026, PVD-027, PVD-041]
544
544
 
545
545
  - operation_id: replaceLiteraturePdf
546
546
  method: POST
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "matelab-python-sdk"
7
- version = "0.1.0a16"
7
+ version = "0.1.0a17"
8
8
  description = "Reusable async Python client for the Matelab Integration Contract"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"