matelab-python-sdk 0.1.0a6__tar.gz → 0.1.0a8__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 (64) hide show
  1. {matelab_python_sdk-0.1.0a6 → matelab_python_sdk-0.1.0a8}/AGENTS.md +4 -2
  2. {matelab_python_sdk-0.1.0a6 → matelab_python_sdk-0.1.0a8}/CHANGELOG.md +14 -0
  3. {matelab_python_sdk-0.1.0a6 → matelab_python_sdk-0.1.0a8}/PKG-INFO +37 -35
  4. {matelab_python_sdk-0.1.0a6 → matelab_python_sdk-0.1.0a8}/README.md +35 -34
  5. {matelab_python_sdk-0.1.0a6 → matelab_python_sdk-0.1.0a8}/docs/operation-coverage.yaml +0 -71
  6. {matelab_python_sdk-0.1.0a6 → matelab_python_sdk-0.1.0a8}/pyproject.toml +6 -3
  7. {matelab_python_sdk-0.1.0a6 → matelab_python_sdk-0.1.0a8}/scripts/check_installed_package.py +3 -0
  8. {matelab_python_sdk-0.1.0a6 → matelab_python_sdk-0.1.0a8}/scripts/check_release.py +1 -1
  9. {matelab_python_sdk-0.1.0a6 → matelab_python_sdk-0.1.0a8}/scripts/generate_models.py +84 -1
  10. {matelab_python_sdk-0.1.0a6 → matelab_python_sdk-0.1.0a8}/src/matelab/__init__.py +4 -0
  11. {matelab_python_sdk-0.1.0a6 → matelab_python_sdk-0.1.0a8}/src/matelab/_generated/models.py +751 -111
  12. {matelab_python_sdk-0.1.0a6 → matelab_python_sdk-0.1.0a8}/src/matelab/_transport.py +41 -32
  13. matelab_python_sdk-0.1.0a8/src/matelab/_wire_validation.py +89 -0
  14. {matelab_python_sdk-0.1.0a6 → matelab_python_sdk-0.1.0a8}/src/matelab/client.py +13 -5
  15. {matelab_python_sdk-0.1.0a6 → matelab_python_sdk-0.1.0a8}/src/matelab/domains/cloud_drive.py +64 -49
  16. {matelab_python_sdk-0.1.0a6 → matelab_python_sdk-0.1.0a8}/src/matelab/domains/literature.py +121 -103
  17. {matelab_python_sdk-0.1.0a6 → matelab_python_sdk-0.1.0a8}/src/matelab/domains/notebooks.py +59 -47
  18. {matelab_python_sdk-0.1.0a6 → matelab_python_sdk-0.1.0a8}/src/matelab/domains/records.py +380 -325
  19. {matelab_python_sdk-0.1.0a6 → matelab_python_sdk-0.1.0a8}/src/matelab/domains/templates.py +91 -58
  20. {matelab_python_sdk-0.1.0a6 → matelab_python_sdk-0.1.0a8}/src/matelab/domains/uploads.py +18 -16
  21. {matelab_python_sdk-0.1.0a6 → matelab_python_sdk-0.1.0a8}/src/matelab/domains/users.py +6 -5
  22. matelab_python_sdk-0.1.0a8/src/matelab/errors.py +64 -0
  23. {matelab_python_sdk-0.1.0a6 → matelab_python_sdk-0.1.0a8}/src/matelab/streaming.py +4 -4
  24. {matelab_python_sdk-0.1.0a6 → matelab_python_sdk-0.1.0a8}/tests/test_client.py +45 -8
  25. {matelab_python_sdk-0.1.0a6 → matelab_python_sdk-0.1.0a8}/tests/test_cloud_drive.py +4 -1
  26. matelab_python_sdk-0.1.0a8/tests/test_errors.py +65 -0
  27. {matelab_python_sdk-0.1.0a6 → matelab_python_sdk-0.1.0a8}/tests/test_generation.py +44 -1
  28. {matelab_python_sdk-0.1.0a6 → matelab_python_sdk-0.1.0a8}/tests/test_notebook_lifecycle.py +7 -2
  29. {matelab_python_sdk-0.1.0a6 → matelab_python_sdk-0.1.0a8}/tests/test_operation_coverage.py +6 -51
  30. {matelab_python_sdk-0.1.0a6 → matelab_python_sdk-0.1.0a8}/tests/test_record_mutations.py +2 -1
  31. {matelab_python_sdk-0.1.0a6 → matelab_python_sdk-0.1.0a8}/tests/test_records.py +2 -1
  32. {matelab_python_sdk-0.1.0a6 → matelab_python_sdk-0.1.0a8}/tests/test_release.py +6 -2
  33. {matelab_python_sdk-0.1.0a6 → matelab_python_sdk-0.1.0a8}/tests/test_streaming.py +27 -0
  34. {matelab_python_sdk-0.1.0a6 → matelab_python_sdk-0.1.0a8}/tests/test_transport.py +52 -5
  35. {matelab_python_sdk-0.1.0a6 → matelab_python_sdk-0.1.0a8}/tests/test_users.py +3 -2
  36. {matelab_python_sdk-0.1.0a6 → matelab_python_sdk-0.1.0a8}/tests/typing/consumer.py +8 -0
  37. {matelab_python_sdk-0.1.0a6 → matelab_python_sdk-0.1.0a8}/uv.lock +176 -1
  38. matelab_python_sdk-0.1.0a6/docs/roadmap.md +0 -934
  39. matelab_python_sdk-0.1.0a6/src/matelab/_wire_validation.py +0 -217
  40. matelab_python_sdk-0.1.0a6/src/matelab/errors.py +0 -30
  41. {matelab_python_sdk-0.1.0a6 → matelab_python_sdk-0.1.0a8}/.env.example +0 -0
  42. {matelab_python_sdk-0.1.0a6 → matelab_python_sdk-0.1.0a8}/.github/workflows/release.yml +0 -0
  43. {matelab_python_sdk-0.1.0a6 → matelab_python_sdk-0.1.0a8}/.gitignore +0 -0
  44. {matelab_python_sdk-0.1.0a6 → matelab_python_sdk-0.1.0a8}/LICENSE +0 -0
  45. {matelab_python_sdk-0.1.0a6 → matelab_python_sdk-0.1.0a8}/NOTICE +0 -0
  46. {matelab_python_sdk-0.1.0a6 → matelab_python_sdk-0.1.0a8}/contracts/matelab-integration-v1.lock.json +0 -0
  47. {matelab_python_sdk-0.1.0a6 → matelab_python_sdk-0.1.0a8}/contracts/matelab-integration-v1.openapi.yaml +0 -0
  48. {matelab_python_sdk-0.1.0a6 → matelab_python_sdk-0.1.0a8}/src/matelab/_generated/__init__.py +0 -0
  49. {matelab_python_sdk-0.1.0a6 → matelab_python_sdk-0.1.0a8}/src/matelab/domains/__init__.py +0 -0
  50. {matelab_python_sdk-0.1.0a6 → matelab_python_sdk-0.1.0a8}/src/matelab/domains/groups.py +0 -0
  51. {matelab_python_sdk-0.1.0a6 → matelab_python_sdk-0.1.0a8}/src/matelab/py.typed +0 -0
  52. {matelab_python_sdk-0.1.0a6 → matelab_python_sdk-0.1.0a8}/src/matelab/session.py +0 -0
  53. {matelab_python_sdk-0.1.0a6 → matelab_python_sdk-0.1.0a8}/tests/conftest.py +0 -0
  54. {matelab_python_sdk-0.1.0a6 → matelab_python_sdk-0.1.0a8}/tests/provider/test_provider_smoke.py +0 -0
  55. {matelab_python_sdk-0.1.0a6 → matelab_python_sdk-0.1.0a8}/tests/test_comments_and_downloads.py +0 -0
  56. {matelab_python_sdk-0.1.0a6 → matelab_python_sdk-0.1.0a8}/tests/test_consumer_smoke.py +0 -0
  57. {matelab_python_sdk-0.1.0a6 → matelab_python_sdk-0.1.0a8}/tests/test_extended_records.py +0 -0
  58. {matelab_python_sdk-0.1.0a6 → matelab_python_sdk-0.1.0a8}/tests/test_groups.py +0 -0
  59. {matelab_python_sdk-0.1.0a6 → matelab_python_sdk-0.1.0a8}/tests/test_notebooks.py +0 -0
  60. {matelab_python_sdk-0.1.0a6 → matelab_python_sdk-0.1.0a8}/tests/test_record_lifecycle.py +0 -0
  61. {matelab_python_sdk-0.1.0a6 → matelab_python_sdk-0.1.0a8}/tests/test_template_lifecycle.py +0 -0
  62. {matelab_python_sdk-0.1.0a6 → matelab_python_sdk-0.1.0a8}/tests/test_templates.py +0 -0
  63. {matelab_python_sdk-0.1.0a6 → matelab_python_sdk-0.1.0a8}/tests/test_uploads_and_literature.py +0 -0
  64. {matelab_python_sdk-0.1.0a6 → matelab_python_sdk-0.1.0a8}/tests/typing/pyproject.toml +0 -0
@@ -1,8 +1,8 @@
1
1
  # AGENTS.md
2
2
 
3
3
  本文档只保留维护 `matelab-python-sdk` 必须长期遵守的项目约束。当前能力和使用方式见
4
- `README.md`,实现路线与进度见 `docs/roadmap.md`,operation 状态以
5
- `docs/operation-coverage.yaml` 为机器权威。不要在本文记录阶段性完成状态、一次性验收数字或迁移历史。
4
+ `README.md`,版本历史见 `CHANGELOG.md`,operation 状态以 `docs/operation-coverage.yaml` 为机器权威。
5
+ 不要在本文记录阶段性完成状态、一次性验收数字或迁移历史。
6
6
 
7
7
  ## 权威与范围
8
8
 
@@ -62,6 +62,8 @@
62
62
  - mutation 默认不自动重试。multipart 或 stream 只有在确认可重放时才能重试;download stream 不自动重放,
63
63
  必须支持显式关闭。
64
64
  - HTTP/transport、Provider business/authentication、Wire Contract/schema 和 client usage 错误必须稳定区分。
65
+ - 每个公开 `MatelabError` 必须直接提供稳定的集成级 `category` 和保守的 `retryable`;Provider kind 和 HTTP
66
+ status 只用于诊断,下游不得重新解释 Provider 数字 code 才能决定恢复类别。
65
67
  - password、token、SSO code/key、临时附件凭证、原始文件内容和敏感 payload 不得进入日志、异常或提交内容。
66
68
 
67
69
  ## 测试与质量门槛
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.0a8 - 2026-08-04
4
+
5
+ - Adds a unified `MatelabErrorCategory` and conservative `retryable` flag to every public SDK error, centralizing
6
+ Provider error semantics so integrations no longer reinterpret `MatelabProviderErrorKind`.
7
+
8
+ ## 0.1.0a7 - 2026-08-04
9
+
10
+ - Replaces the hand-maintained wire-validation rule tables with deterministic generated JSON Schema 2020-12 rules.
11
+ - Simplifies transport, streaming, error mapping, and domain adapters while retaining the pinned `matelab-spec v0.3.0`
12
+ behavior and automatic Session refresh guarantees.
13
+ - Breaking: tightens several public domain inputs and results, and exposes stable `MatelabProviderErrorKind` values
14
+ instead of raw Provider error codes.
15
+ - Removes completed roadmap and work-package bookkeeping; refreshes release checks, documentation, and tests.
16
+
3
17
  ## 0.1.0a6 - 2026-08-01
4
18
 
5
19
  - Adopts the immutable `matelab-spec v0.3.0` Contract release and its form-encoding updates.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: matelab-python-sdk
3
- Version: 0.1.0a6
3
+ Version: 0.1.0a8
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
@@ -21,6 +21,7 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
21
21
  Classifier: Typing :: Typed
22
22
  Requires-Python: >=3.11
23
23
  Requires-Dist: httpx2<3,>=2.9.1
24
+ Requires-Dist: jsonschema<5,>=4.26
24
25
  Requires-Dist: pydantic<3,>=2.13.4
25
26
  Description-Content-Type: text/markdown
26
27
 
@@ -28,7 +29,7 @@ Description-Content-Type: text/markdown
28
29
 
29
30
  Reusable async Python client for the Matelab Integration Contract.
30
31
 
31
- The current alpha is `0.1.0a6`. `[project].version` in `pyproject.toml` is the sole SDK version source;
32
+ The current alpha is `0.1.0a8`. `[project].version` in `pyproject.toml` is the sole SDK version source;
32
33
  `uv.lock` only mirrors that source.
33
34
 
34
35
  The SDK is pinned to the immutable `matelab-spec v0.3.0` Contract Release. The sole release pin is
@@ -57,7 +58,7 @@ To test the same artifact a downstream Consumer will install, build and install
57
58
 
58
59
  ```bash
59
60
  uv build --no-build-isolation --out-dir dist/release
60
- python -m pip install dist/release/matelab_python_sdk-0.1.0a6-py3-none-any.whl
61
+ python -m pip install dist/release/matelab_python_sdk-0.1.0a8-py3-none-any.whl
61
62
  ```
62
63
 
63
64
  Do not infer Provider compatibility from the SDK version alone. A release is also bound to the Contract
@@ -84,18 +85,29 @@ explicitly when needed, for example `AsyncMatelab("https://custom.example/api")`
84
85
 
85
86
  ### Error handling
86
87
 
87
- Catch `MatelabError` for one application-level fallback, or a specific subclass when recovery differs:
88
-
89
- | Error | Meaning and normal response |
90
- |---|---|
91
- | `MatelabUsageError` | The call cannot be represented safely; correct its arguments. |
92
- | `MatelabAuthenticationError` | The Session is missing, expired, invalid, or rejected; refresh or authenticate again as appropriate. |
93
- | `MatelabProviderError` | The Provider rejected a valid request with a business error; inspect `code` and do not assume a mutation was applied. |
94
- | `MatelabTransportError` | The HTTP exchange failed; `status_code` is present for HTTP failures, and a mutation outcome may be unknown. |
95
- | `MatelabProtocolError` | The Provider response does not match the pinned Contract; treat it as Provider drift or an SDK defect. A mutation may already have been applied. |
96
-
97
- `code` and `status_code` are the stable scalar diagnostics. Provider response bodies and caller inputs are never
98
- attached to exceptions. Never automatically retry a mutation solely because it raised a transport or protocol error.
88
+ Catch `MatelabError` once at an integration seam. Every instance exposes a stable `category: MatelabErrorCategory` and
89
+ `retryable: bool`, so an integration can copy the message, category, and retry flag without inspecting subclasses or
90
+ Provider details:
91
+
92
+ | Error | Category | Retryable | Meaning and normal response |
93
+ |---|---|---:|---|
94
+ | `MatelabAuthenticationError` | `AUTHENTICATION` | No | The Session or credentials cannot authenticate; obtain valid authentication before making a new call. |
95
+ | `MatelabUsageError` | `VALIDATION` | No | The call cannot be represented safely; correct its arguments. |
96
+ | `MatelabProviderError` | `BUSINESS`, `VALIDATION`, or `UPSTREAM` | No | The Provider rejected the request; route by `category`, with `kind` available only for diagnosis. |
97
+ | `MatelabTransportError` | `UPSTREAM` | No | The HTTP exchange failed; `status_code` is present for HTTP failures, and a mutation outcome may be unknown. |
98
+ | `MatelabProtocolError` | `UPSTREAM` | No | The response violates the pinned Contract; treat it as Provider drift or an SDK defect. |
99
+
100
+ For `MatelabProviderError`, the SDK maps `REJECTED` to `BUSINESS`, `VALIDATION` to `VALIDATION`, and `SERVER` or
101
+ `UNKNOWN` to `UPSTREAM`. `MatelabProviderError.kind` remains a `MatelabProviderErrorKind` diagnostic, but integrations
102
+ do not need it for recovery routing. Authentication codes are hidden behind `MatelabAuthenticationError`; raw Provider
103
+ codes are not part of the public error interface.
104
+ Codes `0` and `10` remain operation-specific successes selected by the pinned Contract; an operation that receives a
105
+ success code it does not allow raises `MatelabProtocolError` rather than assigning an error kind.
106
+ `MatelabTransportError.status_code` remains available for HTTP failures. Provider response bodies and caller inputs are
107
+ never attached to exceptions. `retryable` means the identical SDK call is safe to replay without further
108
+ interpretation. It is conservatively `False` for every current SDK error because the Contract does not guarantee
109
+ mutation idempotency or outcome; an integration may add a narrower operation-specific retry policy only when it owns
110
+ that evidence.
99
111
 
100
112
  ### Session ownership
101
113
 
@@ -340,11 +352,7 @@ plain text and that a hash-based URI can fall back to an existing quote, so neit
340
352
  Existing `RecordRichTextUpdate` remains legal only with record-scoped `StagedRecordAttachment`. Attachment-bearing
341
353
  multi-record import is also forbidden; callers must split it into single-record finalizers.
342
354
 
343
- ## Implementation roadmap
344
-
345
- `docs/roadmap.md` is the complete SDK-only execution plan. It assigns all 71
346
- `matelab-spec v0.3.0` operations to ordered work packages, defines the machine-readable coverage that
347
- must be added, records Provider-risk gates, and specifies the final completion checks.
355
+ ## Operation coverage
348
356
 
349
357
  The SDK tracks all 71 Contract operations and exposes 70 through public domain interfaces; one identity-bootstrap
350
358
  operation is intentionally unexposed. It deliberately excludes MCP migration, adjacent-repository changes, external
@@ -352,7 +360,7 @@ publishing, and automatic mutation against a real Provider.
352
360
 
353
361
  Machine-readable status lives in
354
362
  `docs/operation-coverage.yaml`. An exact-coverage test keeps its 71
355
- operation IDs, methods, paths, work packages, and Provider issue references aligned with the pinned
363
+ operation IDs, methods, paths, states, public interfaces, and Provider issue references aligned with the pinned
356
364
  OpenAPI snapshot.
357
365
 
358
366
  | Domain | Implemented | Planned | Current public surface |
@@ -590,19 +598,11 @@ deletion is named `permanently_delete_files` and is non-recoverable. Cloud downl
590
598
  resolve bytes from the final file identity and reuse `DownloadStream`, thumbnail/preview choices and the PVD-002-safe
591
599
  range subset. Cloud mutations are not automatically retried.
592
600
 
593
- To run the implementation as a persistent Codex goal, start a task in this repository and use:
594
-
595
- > 完整阅读并严格遵循 `AGENTS.md`、`README.md` 和 `docs/roadmap.md`。创建并持续执行一个 goal:
596
- > 只修改当前仓库,按照 roadmap 从第一个未完成 work package 开始,完成 71-operation 精确覆盖和全部
597
- > SDK 领域 interface;每个 package 通过局部验证后自动继续,最终让 generation `--check`、Ruff、
598
- > Ruff format、Basedpyright、Pytest 和 package build 全部通过。不要修改相邻仓库,不执行生产 Provider
599
- > mutation,不 commit、push、tag 或发布。
600
-
601
601
  Owned/shared `NotebookRef`, public `PublicNotebookRef`, `RecordRef`, and `RecordVersionRef` keep
602
602
  Provider identifiers distinct. Historical reads first re-read the authorized current record and confirm
603
603
  that the requested version is still present in its `modify_log`; both reads write Provider audit entries.
604
604
 
605
- Errors are separated into Provider business errors, authentication errors, HTTP/transport errors,
605
+ Errors are separated into semantic Provider errors, authentication errors, HTTP/transport errors,
606
606
  Integration Contract response errors, and client-side usage errors. Provider response bodies and caller inputs do not
607
607
  enter exceptions.
608
608
 
@@ -621,11 +621,13 @@ uv build
621
621
 
622
622
  The generator first verifies the contract lock, OpenAPI release metadata, and snapshot digest. It then
623
623
  creates a temporary OpenAPI 3.1 generation projection, resolves references without network access, and
624
- generates private component, operation-response, and parameter models. The projection only flattens pure
625
- object inheritance that the generator cannot otherwise preserve correctly; the checked-in release
626
- snapshot remains unchanged. `--check` performs the same validation and deterministic generation without
627
- writing the checked-in models. The current lock resolves `datamodel-code-generator 0.71.0` and
628
- `hatchling 1.31.0`. Published metadata requires `httpx2>=2.9.1,<3` and
624
+ generates private component, operation-response, and parameter models. The projection flattens pure
625
+ object inheritance and preserves constraints the model generator cannot express as self-contained JSON Schema
626
+ 2020-12 metadata; the checked-in release snapshot remains unchanged. `--check` performs the same validation and deterministic generation without
627
+ writing the checked-in models. `WireModel` applies that metadata with the standard
628
+ `jsonschema` Draft 2020-12 validator; the SDK does not maintain a second hand-written schema interpreter. The current lock resolves
629
+ `datamodel-code-generator 0.71.0` and
630
+ `hatchling 1.31.0`. Published metadata requires `httpx2>=2.9.1,<3`, `jsonschema>=4.26,<5`, and
629
631
  `pydantic>=2.13.4,<3`; the build backend requires `hatchling>=1.27,<2`. These lower bounds are verified
630
632
  against the complete test suite on the supported Python boundary versions rather than inferred from
631
633
  `uv.lock`. The exact toolchain remains locked for development and release builds. Basedpyright and its
@@ -2,7 +2,7 @@
2
2
 
3
3
  Reusable async Python client for the Matelab Integration Contract.
4
4
 
5
- The current alpha is `0.1.0a6`. `[project].version` in `pyproject.toml` is the sole SDK version source;
5
+ The current alpha is `0.1.0a8`. `[project].version` in `pyproject.toml` is the sole SDK version source;
6
6
  `uv.lock` only mirrors that source.
7
7
 
8
8
  The SDK is pinned to the immutable `matelab-spec v0.3.0` Contract Release. The sole release pin is
@@ -31,7 +31,7 @@ To test the same artifact a downstream Consumer will install, build and install
31
31
 
32
32
  ```bash
33
33
  uv build --no-build-isolation --out-dir dist/release
34
- python -m pip install dist/release/matelab_python_sdk-0.1.0a6-py3-none-any.whl
34
+ python -m pip install dist/release/matelab_python_sdk-0.1.0a8-py3-none-any.whl
35
35
  ```
36
36
 
37
37
  Do not infer Provider compatibility from the SDK version alone. A release is also bound to the Contract
@@ -58,18 +58,29 @@ explicitly when needed, for example `AsyncMatelab("https://custom.example/api")`
58
58
 
59
59
  ### Error handling
60
60
 
61
- Catch `MatelabError` for one application-level fallback, or a specific subclass when recovery differs:
62
-
63
- | Error | Meaning and normal response |
64
- |---|---|
65
- | `MatelabUsageError` | The call cannot be represented safely; correct its arguments. |
66
- | `MatelabAuthenticationError` | The Session is missing, expired, invalid, or rejected; refresh or authenticate again as appropriate. |
67
- | `MatelabProviderError` | The Provider rejected a valid request with a business error; inspect `code` and do not assume a mutation was applied. |
68
- | `MatelabTransportError` | The HTTP exchange failed; `status_code` is present for HTTP failures, and a mutation outcome may be unknown. |
69
- | `MatelabProtocolError` | The Provider response does not match the pinned Contract; treat it as Provider drift or an SDK defect. A mutation may already have been applied. |
70
-
71
- `code` and `status_code` are the stable scalar diagnostics. Provider response bodies and caller inputs are never
72
- attached to exceptions. Never automatically retry a mutation solely because it raised a transport or protocol error.
61
+ Catch `MatelabError` once at an integration seam. Every instance exposes a stable `category: MatelabErrorCategory` and
62
+ `retryable: bool`, so an integration can copy the message, category, and retry flag without inspecting subclasses or
63
+ Provider details:
64
+
65
+ | Error | Category | Retryable | Meaning and normal response |
66
+ |---|---|---:|---|
67
+ | `MatelabAuthenticationError` | `AUTHENTICATION` | No | The Session or credentials cannot authenticate; obtain valid authentication before making a new call. |
68
+ | `MatelabUsageError` | `VALIDATION` | No | The call cannot be represented safely; correct its arguments. |
69
+ | `MatelabProviderError` | `BUSINESS`, `VALIDATION`, or `UPSTREAM` | No | The Provider rejected the request; route by `category`, with `kind` available only for diagnosis. |
70
+ | `MatelabTransportError` | `UPSTREAM` | No | The HTTP exchange failed; `status_code` is present for HTTP failures, and a mutation outcome may be unknown. |
71
+ | `MatelabProtocolError` | `UPSTREAM` | No | The response violates the pinned Contract; treat it as Provider drift or an SDK defect. |
72
+
73
+ For `MatelabProviderError`, the SDK maps `REJECTED` to `BUSINESS`, `VALIDATION` to `VALIDATION`, and `SERVER` or
74
+ `UNKNOWN` to `UPSTREAM`. `MatelabProviderError.kind` remains a `MatelabProviderErrorKind` diagnostic, but integrations
75
+ do not need it for recovery routing. Authentication codes are hidden behind `MatelabAuthenticationError`; raw Provider
76
+ codes are not part of the public error interface.
77
+ Codes `0` and `10` remain operation-specific successes selected by the pinned Contract; an operation that receives a
78
+ success code it does not allow raises `MatelabProtocolError` rather than assigning an error kind.
79
+ `MatelabTransportError.status_code` remains available for HTTP failures. Provider response bodies and caller inputs are
80
+ never attached to exceptions. `retryable` means the identical SDK call is safe to replay without further
81
+ interpretation. It is conservatively `False` for every current SDK error because the Contract does not guarantee
82
+ mutation idempotency or outcome; an integration may add a narrower operation-specific retry policy only when it owns
83
+ that evidence.
73
84
 
74
85
  ### Session ownership
75
86
 
@@ -314,11 +325,7 @@ plain text and that a hash-based URI can fall back to an existing quote, so neit
314
325
  Existing `RecordRichTextUpdate` remains legal only with record-scoped `StagedRecordAttachment`. Attachment-bearing
315
326
  multi-record import is also forbidden; callers must split it into single-record finalizers.
316
327
 
317
- ## Implementation roadmap
318
-
319
- `docs/roadmap.md` is the complete SDK-only execution plan. It assigns all 71
320
- `matelab-spec v0.3.0` operations to ordered work packages, defines the machine-readable coverage that
321
- must be added, records Provider-risk gates, and specifies the final completion checks.
328
+ ## Operation coverage
322
329
 
323
330
  The SDK tracks all 71 Contract operations and exposes 70 through public domain interfaces; one identity-bootstrap
324
331
  operation is intentionally unexposed. It deliberately excludes MCP migration, adjacent-repository changes, external
@@ -326,7 +333,7 @@ publishing, and automatic mutation against a real Provider.
326
333
 
327
334
  Machine-readable status lives in
328
335
  `docs/operation-coverage.yaml`. An exact-coverage test keeps its 71
329
- operation IDs, methods, paths, work packages, and Provider issue references aligned with the pinned
336
+ operation IDs, methods, paths, states, public interfaces, and Provider issue references aligned with the pinned
330
337
  OpenAPI snapshot.
331
338
 
332
339
  | Domain | Implemented | Planned | Current public surface |
@@ -564,19 +571,11 @@ deletion is named `permanently_delete_files` and is non-recoverable. Cloud downl
564
571
  resolve bytes from the final file identity and reuse `DownloadStream`, thumbnail/preview choices and the PVD-002-safe
565
572
  range subset. Cloud mutations are not automatically retried.
566
573
 
567
- To run the implementation as a persistent Codex goal, start a task in this repository and use:
568
-
569
- > 完整阅读并严格遵循 `AGENTS.md`、`README.md` 和 `docs/roadmap.md`。创建并持续执行一个 goal:
570
- > 只修改当前仓库,按照 roadmap 从第一个未完成 work package 开始,完成 71-operation 精确覆盖和全部
571
- > SDK 领域 interface;每个 package 通过局部验证后自动继续,最终让 generation `--check`、Ruff、
572
- > Ruff format、Basedpyright、Pytest 和 package build 全部通过。不要修改相邻仓库,不执行生产 Provider
573
- > mutation,不 commit、push、tag 或发布。
574
-
575
574
  Owned/shared `NotebookRef`, public `PublicNotebookRef`, `RecordRef`, and `RecordVersionRef` keep
576
575
  Provider identifiers distinct. Historical reads first re-read the authorized current record and confirm
577
576
  that the requested version is still present in its `modify_log`; both reads write Provider audit entries.
578
577
 
579
- Errors are separated into Provider business errors, authentication errors, HTTP/transport errors,
578
+ Errors are separated into semantic Provider errors, authentication errors, HTTP/transport errors,
580
579
  Integration Contract response errors, and client-side usage errors. Provider response bodies and caller inputs do not
581
580
  enter exceptions.
582
581
 
@@ -595,11 +594,13 @@ uv build
595
594
 
596
595
  The generator first verifies the contract lock, OpenAPI release metadata, and snapshot digest. It then
597
596
  creates a temporary OpenAPI 3.1 generation projection, resolves references without network access, and
598
- generates private component, operation-response, and parameter models. The projection only flattens pure
599
- object inheritance that the generator cannot otherwise preserve correctly; the checked-in release
600
- snapshot remains unchanged. `--check` performs the same validation and deterministic generation without
601
- writing the checked-in models. The current lock resolves `datamodel-code-generator 0.71.0` and
602
- `hatchling 1.31.0`. Published metadata requires `httpx2>=2.9.1,<3` and
597
+ generates private component, operation-response, and parameter models. The projection flattens pure
598
+ object inheritance and preserves constraints the model generator cannot express as self-contained JSON Schema
599
+ 2020-12 metadata; the checked-in release snapshot remains unchanged. `--check` performs the same validation and deterministic generation without
600
+ writing the checked-in models. `WireModel` applies that metadata with the standard
601
+ `jsonschema` Draft 2020-12 validator; the SDK does not maintain a second hand-written schema interpreter. The current lock resolves
602
+ `datamodel-code-generator 0.71.0` and
603
+ `hatchling 1.31.0`. Published metadata requires `httpx2>=2.9.1,<3`, `jsonschema>=4.26,<5`, and
603
604
  `pydantic>=2.13.4,<3`; the build backend requires `hatchling>=1.27,<2`. These lower bounds are verified
604
605
  against the complete test suite on the supported Python boundary versions rather than inferred from
605
606
  `uv.lock`. The exact toolchain remains locked for development and release builds. Basedpyright and its