matelab-python-sdk 0.1.0a17__tar.gz → 0.1.0a22__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.
- matelab_python_sdk-0.1.0a22/AGENTS.md +52 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/CHANGELOG.md +60 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/PKG-INFO +44 -25
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/README.md +43 -24
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/contracts/matelab-integration-v1.lock.json +3 -3
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/contracts/matelab-integration-v1.openapi.yaml +191 -131
- matelab_python_sdk-0.1.0a22/docs/agent-architecture.md +28 -0
- matelab_python_sdk-0.1.0a22/docs/agent-workflows.md +76 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/docs/operation-coverage.yaml +28 -28
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/pyproject.toml +1 -1
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/src/matelab/_generated/models.py +186 -81
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/src/matelab/domains/records.py +8 -18
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/tests/test_async_attachment_upload.py +2 -1
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/tests/test_generation.py +199 -4
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/tests/test_operation_coverage.py +1 -1
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/tests/test_record_mutations.py +20 -19
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/tests/test_records.py +103 -12
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/tests/test_transport.py +1 -1
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/tests/test_uploads_and_literature.py +2 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/uv.lock +1 -1
- matelab_python_sdk-0.1.0a17/AGENTS.md +0 -94
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/.env.example +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/.github/workflows/release.yml +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/.gitignore +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/CONTEXT.md +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/LICENSE +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/NOTICE +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/scripts/check_installed_package.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/scripts/check_release.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/scripts/generate_models.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/src/matelab/__init__.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/src/matelab/_generated/__init__.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/src/matelab/_hashes.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/src/matelab/_transport.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/src/matelab/_wire_validation.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/src/matelab/client.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/src/matelab/domains/__init__.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/src/matelab/domains/_attachment_content.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/src/matelab/domains/cloud_drive.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/src/matelab/domains/groups.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/src/matelab/domains/literature.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/src/matelab/domains/notebooks.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/src/matelab/domains/templates.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/src/matelab/domains/uploads.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/src/matelab/domains/users.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/src/matelab/errors.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/src/matelab/py.typed +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/src/matelab/session.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/src/matelab/streaming.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/tests/conftest.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/tests/provider/test_provider_smoke.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/tests/test_client.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/tests/test_cloud_drive.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/tests/test_comments_and_downloads.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/tests/test_consumer_smoke.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/tests/test_errors.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/tests/test_extended_records.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/tests/test_groups.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/tests/test_notebook_lifecycle.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/tests/test_notebooks.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/tests/test_record_lifecycle.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/tests/test_release.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/tests/test_streaming.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/tests/test_template_lifecycle.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/tests/test_templates.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/tests/test_users.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/tests/typing/consumer.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a22}/tests/typing/pyproject.toml +0 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
本文件只承载每次维护都必须在上下文中的步骤、权威和授权边界。分支规则通过下列指针按需加载。
|
|
4
|
+
|
|
5
|
+
## 维护顺序
|
|
6
|
+
|
|
7
|
+
1. **定界**:先读 `git status` 和适用权威;完成标准是任务范围、用户现有改动和所需外部权限均已识别。
|
|
8
|
+
2. **查证**:沿 public intent → wire operation → Provider evidence 核对;完成标准是每个受影响 operation 的
|
|
9
|
+
request、response、security、examples、成功码及 PVD/PCG 均有结论,Contract 缺口已明确报告。
|
|
10
|
+
3. **收敛**:只修改任务必需的层;完成标准是 public、adapter、generated、tests、coverage 和 docs 的影响均已
|
|
11
|
+
记账,未加入 Provider 推测、Consumer 私有概念或无真实第二实现的 seam。
|
|
12
|
+
4. **验证**:先跑聚焦测试,再跑适用的完整门槛;完成标准是必需命令全部退出为零,skip 单独说明。
|
|
13
|
+
5. **交付**:复核最终 diff、状态和验证证据;完成标准是结果、限制和未执行项都可由用户独立核对。
|
|
14
|
+
|
|
15
|
+
## 分支指针
|
|
16
|
+
|
|
17
|
+
- **SDK architecture**:修改 public 类型、命名、身份空间或模块边界时读
|
|
18
|
+
[`docs/agent-architecture.md#public-interface`](docs/agent-architecture.md#public-interface);修改 transport、认证、
|
|
19
|
+
Session、stream 或错误时读
|
|
20
|
+
[`docs/agent-architecture.md#transport-session-and-errors`](docs/agent-architecture.md#transport-session-and-errors)。
|
|
21
|
+
- **Contract adoption**:同步 spec tag、snapshot、lock 或生成模型时执行
|
|
22
|
+
[`docs/agent-workflows.md#contract-adoption`](docs/agent-workflows.md#contract-adoption)。
|
|
23
|
+
- **Delivery gate**:代码、Contract、依赖或构建元数据变化后执行
|
|
24
|
+
[`docs/agent-workflows.md#delivery-gate`](docs/agent-workflows.md#delivery-gate)。
|
|
25
|
+
- **Provider validation**:任何实时 Provider smoke、读取或 mutation 前执行
|
|
26
|
+
[`docs/agent-workflows.md#provider-validation`](docs/agent-workflows.md#provider-validation)。
|
|
27
|
+
- **Release**:版本、制品、commit、tag、push 或 publish 任务执行
|
|
28
|
+
[`docs/agent-workflows.md#release`](docs/agent-workflows.md#release)。
|
|
29
|
+
|
|
30
|
+
## 权威
|
|
31
|
+
|
|
32
|
+
| 权威 | 负责内容 |
|
|
33
|
+
| --- | --- |
|
|
34
|
+
| `README.md` | 当前 public interface、集成语义、示例及人类流程 |
|
|
35
|
+
| `CONTEXT.md` | public 类型和命名采用的领域词汇 |
|
|
36
|
+
| `CHANGELOG.md` | SDK 版本变化与迁移影响;不定义当前接口 |
|
|
37
|
+
| `docs/operation-coverage.yaml` | operation 状态、公开入口、稳定性和已知问题 |
|
|
38
|
+
| `pyproject.toml` | SDK 版本、依赖范围、构建与工具配置;`uv.lock` 只锁定本仓库环境 |
|
|
39
|
+
| Contract lock 与 snapshot | Contract pin 与 wire schema |
|
|
40
|
+
| `src/matelab/__init__.py::__all__` | 公开导入边界 |
|
|
41
|
+
|
|
42
|
+
机器权威变化时,同一变更同步受影响的当前态文档;历史只追加到 `CHANGELOG.md`。测试提供行为证据,不替代
|
|
43
|
+
接口、coverage 或 Contract 权威。
|
|
44
|
+
|
|
45
|
+
## 范围与授权
|
|
46
|
+
|
|
47
|
+
- 现有工作区改动属于用户;在其上做最小、可归因的修改。默认只写本仓库,邻接的 spec、Provider 和 Consumer
|
|
48
|
+
仓库只作只读证据来源。
|
|
49
|
+
- `/home/tnzhu/projects/matelab-spec` 定义 Wire Contract、兼容策略及 Provider 问题;`matelab-server` 是 Provider
|
|
50
|
+
实现,`matelab-mcp` 只提供 Consumer evidence,均不能反向定义 SDK interface。
|
|
51
|
+
- commit、push、tag、publish、生产访问和真实 Provider mutation 需要本轮明确授权;授权只覆盖用户指定的目标与
|
|
52
|
+
副作用。
|
|
@@ -3,6 +3,66 @@
|
|
|
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.0a22 - 2026-09-03
|
|
7
|
+
|
|
8
|
+
- Adopts immutable `matelab-spec v0.4.5` at commit `6afac7ff151680130e6e4bc6d95782589b97f4e7` and OpenAPI
|
|
9
|
+
SHA-256 `31a8d03b4366e2345dfccdbbaaaccf6754b2711428afa4295d778d121988460d`, aligned with Provider source evidence
|
|
10
|
+
`59eb05b233e5ddd023a60ccb5e5c5f2ae22a70f0` and its verified production-core equivalent.
|
|
11
|
+
- Tightens the private `readRecord` wire model so required `datetime_locked` is a non-negative integer; the Provider
|
|
12
|
+
normalizes an unavailable lock timestamp to `0`. The public `Record` interface remains unchanged.
|
|
13
|
+
- Retains the root-only `RecordFilesAttachmentAppend` boundary because `UpdateRecordRequest.add[]` still excludes the
|
|
14
|
+
folder `path` declared by the dedicated staged-name append schema; PVD-044 remains contract-contained.
|
|
15
|
+
|
|
16
|
+
## 0.1.0a21 - 2026-08-28
|
|
17
|
+
|
|
18
|
+
- Adopts immutable `matelab-spec v0.4.4` at commit `be070c5f931b2063327a3beaccc53a360204b64e` and OpenAPI
|
|
19
|
+
SHA-256 `2de38e46d3814b8b049af8afd18e85fb20be6ca29cc409390d25df663abc43f9`, aligned with Provider evidence
|
|
20
|
+
`7bd9704286057653632424fa82f413d99cd69ab6`.
|
|
21
|
+
- Accepts the required nullable `readRecord.datetime_locked` wire field for current unlocked records and follows the
|
|
22
|
+
unexposed `/actions/app` rename to `readApplicationBootstrap`; SDK Session identity remains sourced from token issuance.
|
|
23
|
+
- Keeps `RecordFilesAttachmentAppend` root-only. The release describes a safe optional folder path in its dedicated
|
|
24
|
+
staged-name append schema, but `UpdateRecordRequest.add[]` still references `AddValueOperation`, which forbids that
|
|
25
|
+
`path`;
|
|
26
|
+
exposing it would require bypassing whole-request Contract validation. PVD-044 also records that malformed path
|
|
27
|
+
containers can silently append at root.
|
|
28
|
+
|
|
29
|
+
## 0.1.0a20 - 2026-08-24
|
|
30
|
+
|
|
31
|
+
- Adopts immutable `matelab-spec v0.4.3` at commit `7965ac9803505ae35dc5ce36f52afc3c2c133c45` and OpenAPI
|
|
32
|
+
SHA-256 `6576812dd13f92ad58131f4edb8dc919d1b1fe0f19a695c2d25fbe6d13a8445b`, aligned with Provider evidence
|
|
33
|
+
`a3e6b961800f6b1ab666f0d3f6cd4c64c2a3ce27`.
|
|
34
|
+
- Breaking: tightens record readback to one canonical attachment object or `null` per table file cell, removing the
|
|
35
|
+
obsolete attachment-array compatibility path. Template decoding now accepts nullable JSON-code data and preserves
|
|
36
|
+
empty-string number/boolean cells alongside their scalar and null forms.
|
|
37
|
+
- Records PVD-046 while keeping `templates.save_content()` deliberately narrower than the Provider: the request remains
|
|
38
|
+
a canonical module list, and every table file cell remains one canonical attachment object or `null`, never an
|
|
39
|
+
arbitrary or multi-attachment array.
|
|
40
|
+
|
|
41
|
+
## 0.1.0a19 - 2026-08-23
|
|
42
|
+
|
|
43
|
+
- Re-adopts the force-rewritten `matelab-spec v0.4.2` at commit
|
|
44
|
+
`1a4b77721d782fccd2b1f26bcc16a7d876347686` and OpenAPI SHA-256
|
|
45
|
+
`1e737421aac636356487122ea89e20d54de07c8b9c0651cf6970a7123fe3b72b`. The published `0.1.0a18` entry below remains
|
|
46
|
+
historical evidence for the former `v0.4.2` target at `a51483f`; it is not rewritten.
|
|
47
|
+
- Aligns with current Provider evidence: comment attachment multipart uses `file`; temporary-file and comment identifiers
|
|
48
|
+
allow 100 characters; code-4 `errs` accepts opaque array or object containers; and DOI extraction validates
|
|
49
|
+
`^10\.[0-9]+/\S+$` before transport.
|
|
50
|
+
- Breaking: removes `RecordValueAddition.path` and `RecordFilesAttachmentAppend.folder_path` because the current
|
|
51
|
+
Provider's add-value shape no longer accepts `path`; files-module append now targets only the module root. Search
|
|
52
|
+
excludes encrypted records, and callers of arbitrary template-shaped imports must omit unset file-valued keys because
|
|
53
|
+
the Provider rejects their explicit `null`.
|
|
54
|
+
|
|
55
|
+
## 0.1.0a18 - 2026-08-23
|
|
56
|
+
|
|
57
|
+
- Adopts immutable `matelab-spec v0.4.2` at commit `a51483f910440fbbbc3693cc32566482064bb3ab` and OpenAPI
|
|
58
|
+
SHA-256 `4c92b96ba3dfe7122b30b4db2e2c8054c06018291c8c52c15482112b51a32920`. The wire schema, methods,
|
|
59
|
+
paths, encodings, operation count, and public interface are unchanged.
|
|
60
|
+
- Records that compatibility evidence remains the stable Provider revision
|
|
61
|
+
`59101f006e9fd6d6ce0b951dfd34695a7949b54f`; the latest reviewed revision
|
|
62
|
+
`a3e6b961800f6b1ab666f0d3f6cd4c64c2a3ce27` is incompatible. The SDK retains the stable multipart comment-upload
|
|
63
|
+
field, while integrations must account for that Provider's DOI rejection, encrypted-search omission, valid
|
|
64
|
+
files-folder-path rejection, and explicit-null table-file-import failure.
|
|
65
|
+
|
|
6
66
|
## 0.1.0a17 - 2026-08-20
|
|
7
67
|
|
|
8
68
|
- Adopts immutable `matelab-spec v0.4.1` at commit `6f8ab3d14797385d0075d0aba38bf3bf529e674d` and OpenAPI
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: matelab-python-sdk
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.0a22
|
|
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.
|
|
38
|
+
The current alpha is `0.1.0a22`. `[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.
|
|
41
|
+
The SDK is pinned to the immutable `matelab-spec v0.4.5` 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,12 +64,16 @@ 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.
|
|
67
|
+
python -m pip install dist/release/matelab_python_sdk-0.1.0a22-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
|
|
71
71
|
tag, commit, and checksum recorded below.
|
|
72
72
|
|
|
73
|
+
The Contract and public SDK interface track the current reviewed Provider at
|
|
74
|
+
`59eb05b233e5ddd023a60ccb5e5c5f2ae22a70f0`. Provider limitations that remain relevant to integrations are documented
|
|
75
|
+
alongside the affected interfaces below.
|
|
76
|
+
|
|
73
77
|
## Design
|
|
74
78
|
|
|
75
79
|
The public module is intentionally small:
|
|
@@ -117,8 +121,8 @@ success code it does not allow raises `MatelabProtocolError` rather than assigni
|
|
|
117
121
|
`MatelabTransportError.status_code` remains available for HTTP failures. Provider response bodies, top-level `msg`,
|
|
118
122
|
legacy `errmsg`, opaque `errs`, uncontracted debug fields, and request payloads are not attached to exceptions because
|
|
119
123
|
Provider-authored diagnostics may contain stack traces, credentials, or submitted values.
|
|
120
|
-
The pinned v0.4.
|
|
121
|
-
|
|
124
|
+
The pinned v0.4.5 Contract also declares optional code-4 `errs`, but PVD-041 and PCG-015 record opaque array/object
|
|
125
|
+
containers and insufficient evidence for requiredness, cardinality, or exclusion from other codes. The SDK
|
|
122
126
|
therefore keeps those diagnostics wire-only and does not expose `errs` as stable public metadata. A typed detail
|
|
123
127
|
interface remains blocked until a future Contract release can define one from stronger Provider evidence. `retryable`
|
|
124
128
|
means the identical SDK call is safe to replay without further interpretation. It is conservatively `False` for every
|
|
@@ -312,8 +316,10 @@ supports one file column. A locally rejected target does not spend the handle; o
|
|
|
312
316
|
result cannot be retried through the same client.
|
|
313
317
|
|
|
314
318
|
Files-module append and table/files replacement use the general record attachment intents and may be combined with
|
|
315
|
-
other non-conflicting record changes. `RecordFilesAttachmentAppend` targets the module root
|
|
316
|
-
|
|
319
|
+
other non-conflicting record changes. `RecordFilesAttachmentAppend` currently targets the module root. Although
|
|
320
|
+
v0.4.5 records Provider evidence for safe folder paths, its top-level `UpdateRecordRequest.add[]` schema still excludes
|
|
321
|
+
the `path` property declared by the dedicated staged-name append shape; the SDK therefore does not expose folder paths
|
|
322
|
+
until that wire-schema conflict is resolved (PVD-044):
|
|
317
323
|
|
|
318
324
|
```python
|
|
319
325
|
from matelab import RecordAttachmentReplacement, RecordFilesAttachmentAppend, RecordValueUpdate
|
|
@@ -344,7 +350,9 @@ await client.records.update(
|
|
|
344
350
|
|
|
345
351
|
For a files occurrence, `caption=None` preserves the observed string caption (an observed null caption normalizes to
|
|
346
352
|
the required empty string). Table replacement requires exactly one current attachment in the selected cell and does
|
|
347
|
-
not accept a caption.
|
|
353
|
+
not accept a caption. Record reads likewise accept only one canonical attachment object or `null` in a table file cell;
|
|
354
|
+
an attachment array violates the pinned response contract. Both replacement forms require the replacement hash to
|
|
355
|
+
differ from the current occurrence.
|
|
348
356
|
|
|
349
357
|
All record attachment intents reject handles from another notebook or authenticated uploader, duplicate use within one
|
|
350
358
|
finalization request, and raw Provider attachment references. Row/index-based operations use an immediate SDK read and
|
|
@@ -421,8 +429,8 @@ and `deletePersonalLiteratureItem`.
|
|
|
421
429
|
|
|
422
430
|
Every other implemented operation is explicitly `experimental`; the exact per-operation list and its
|
|
423
431
|
PVD/PCG references live in
|
|
424
|
-
`docs/operation-coverage.yaml`. `
|
|
425
|
-
|
|
432
|
+
`docs/operation-coverage.yaml`. `readApplicationBootstrap` is intentionally unexposed because it returns the Provider
|
|
433
|
+
application environment and menu model, while SDK identity is sourced from token issuance. `readLiteratureCreateTemplate`
|
|
426
434
|
is intentionally unexposed because it returns a frontend form definition and an optional deployment flag rather than
|
|
427
435
|
a resource needed by the SDK interface. There are no `planned` operations. Experimental support means the SDK
|
|
428
436
|
validates and exposes the pinned Contract while preserving limitations such as unstable ordering/pagination,
|
|
@@ -446,7 +454,7 @@ targets = await client.users.search("Example Researcher", global_scope=False)
|
|
|
446
454
|
`groups.list()` returns the `GroupSummary` tuple directly. Ordering remains Provider-unspecified and is documented
|
|
447
455
|
rather than repeated as a constant result field. The Provider's members for an unstable first group remain wire-only;
|
|
448
456
|
`users.search()` is the public recipient-discovery interface. These two discovery interfaces are experimental because
|
|
449
|
-
group order is unstable and user search is unpaged, unordered and not field-minimized (PVD-006, PVD-029
|
|
457
|
+
group order is unstable and user search is unpaged, unordered and not field-minimized (PVD-006, PVD-029).
|
|
450
458
|
`GroupSummary.notebook_creation_available` expresses whether the group can currently host notebook creation without
|
|
451
459
|
exposing the Provider's data-server routing value.
|
|
452
460
|
|
|
@@ -496,9 +504,12 @@ await client.templates.save_content(template, modules)
|
|
|
496
504
|
`TemplateModule.data_present` distinguishes a missing `data` property from an explicit null value, while
|
|
497
505
|
`attributes` prevents additive canonical properties from being dropped during a read/save cycle. The SDK does not
|
|
498
506
|
synthesize frontend editor UIDs, layout widths, rows, folders, option encoding, or a fixed set of display module
|
|
499
|
-
types.
|
|
500
|
-
|
|
501
|
-
|
|
507
|
+
types. A JSON-language code module with style metadata may return its JSON string or explicit `null`; number and boolean
|
|
508
|
+
table cells preserve the Provider's empty string as distinct from scalar and `null` values. The Provider accepts some
|
|
509
|
+
non-canonical module roots and arbitrary table file arrays, but the SDK does not expose that behavior: saved content
|
|
510
|
+
must remain a canonical module list, and a table file cell must be one canonical attachment object or `null` (PVD-046).
|
|
511
|
+
The Provider supports only whole-content replacement and has no atomic patch or compare-and-swap operation (PCG-007),
|
|
512
|
+
so a read-modify-save sequence can overwrite a concurrent change.
|
|
502
513
|
|
|
503
514
|
The market result retains the Provider's `total_count` and derives `has_more` without echoing the caller's page
|
|
504
515
|
arguments; it does not claim a stable order or continuation token. Template reads remain experimental
|
|
@@ -538,6 +549,8 @@ relations = await client.records.relations(source)
|
|
|
538
549
|
as `modules`; it is not the template-shaped `RecordImportItem.data` accepted by record import.
|
|
539
550
|
`records.search()` maps each requested field name to a stored record path. A match exposes only Provider-returned
|
|
540
551
|
entries in `values`, so key membership distinguishes an absent result from an explicit JSON `null`.
|
|
552
|
+
The current Provider excludes encrypted records from search (PVD-043); an empty search result therefore does
|
|
553
|
+
not prove that no matching encrypted record exists.
|
|
541
554
|
|
|
542
555
|
The Provider calls its notebook directory tree `subtype`; that name remains wire-only. The SDK exposes
|
|
543
556
|
`RecordFolder`, `RecordSummary.folder_id`, and the `folders` returned with record listings. A top-level folder has
|
|
@@ -587,7 +600,9 @@ UID. Import validates the complete batch with generated wire models but cannot m
|
|
|
587
600
|
individual inputs or promise atomicity (PCG-008); it therefore returns only the tuple of database IDs actually
|
|
588
601
|
reported by the Provider. `RecordImportItem.keywords` is a tuple; the adapter owns the Provider's
|
|
589
602
|
legacy semicolon encoding. Folder paths are ordered existing folder titles from the notebook root; they do not create
|
|
590
|
-
missing folders.
|
|
603
|
+
missing folders. The current Provider rejects explicit-null table-file imports (PVD-045). Because the SDK accepts
|
|
604
|
+
arbitrary template-shaped data and cannot identify file columns without the template definition, integrations must omit
|
|
605
|
+
an unset file-valued key instead of sending it as `None`. Delete means moving records into the recycle bin, not permanent
|
|
591
606
|
deletion. Delete and restore return `None`; record mutations are not automatically retried.
|
|
592
607
|
|
|
593
608
|
`records.copy()` accepts an optional `new_record_uid`; when omitted, the SDK generates one locally. The Provider
|
|
@@ -605,7 +620,9 @@ returns the acknowledgement classification
|
|
|
605
620
|
issue a post-write read. Database, active-browser, and unclassified acknowledgements remain distinct, and mutation
|
|
606
621
|
retries stay disabled. Encrypted record content is outside the SDK's public read/update interface: the list-level
|
|
607
622
|
`RecordSummary.encrypted` flag lets callers identify and skip it, while the Provider password field and frontend-only
|
|
608
|
-
password lifecycle remain unexposed.
|
|
623
|
+
password lifecycle remain unexposed. Files-module attachment append remains root-only because the pinned top-level
|
|
624
|
+
update request schema does not admit the dedicated staged-name append shape's folder `path`; malformed path containers
|
|
625
|
+
may also silently append at root according to PVD-044. A staged attachment is indeterminate once the write has started.
|
|
609
626
|
|
|
610
627
|
Relation addition reads both endpoints and checks their resolved data server before writing; this reduces PVD-019
|
|
611
628
|
risk but is not an atomic Provider authorization guarantee. It does not list relations merely to inspect the
|
|
@@ -617,8 +634,8 @@ ignores target notebook identity (PVD-020); its mutation likewise performs autho
|
|
|
617
634
|
`records.comments()`. Each returned `RecordRelationRef` carries only the relation row and declared target IDs.
|
|
618
635
|
Deletion accepts the source `RecordLocator` and one of those observed refs.
|
|
619
636
|
|
|
620
|
-
Comment upload follows the Provider's literal one-request `
|
|
621
|
-
|
|
637
|
+
Comment upload follows the current Provider's literal one-request `file` field (PVD-037). Comment mutations return `None`
|
|
638
|
+
after acknowledgement. Edit first verifies that the selected
|
|
622
639
|
comment is currently observed and caller-owned because the Provider otherwise reports a false success for a missing or
|
|
623
640
|
other-user ID (PVD-004). Delete sends the typed ref directly because the Provider mutation itself enforces record and
|
|
624
641
|
caller ownership. Neither operation performs a post-write read. Staged comment attachments have no Contract abort
|
|
@@ -697,7 +714,9 @@ The Provider's static literature form definition and extraction deployment flag
|
|
|
697
714
|
`extract_metadata()` directly and handle an unavailable or failing optional backend as a Provider error. Extraction
|
|
698
715
|
returns a `PublicationMetadataCandidate`: unstored, rich publication evidence rather than metadata already attached to
|
|
699
716
|
a literature item. Its structured authors are `PublicationAuthorCandidate` values. Extraction accepts a DOI, a
|
|
700
|
-
completed staged PDF, or both; a supplied DOI takes precedence over the staged PDF.
|
|
717
|
+
completed staged PDF, or both; a supplied DOI takes precedence over the staged PDF. A non-empty DOI must match
|
|
718
|
+
`^10\.[0-9]+/\S+$`; the generated request model rejects other values before sending them to the Provider (PVD-042).
|
|
719
|
+
Literature list
|
|
701
720
|
results likewise exclude Provider-generated citation HTML and author-highlight fragments; Consumers receive the
|
|
702
721
|
underlying citation fields instead of presentation markup. `LiteratureDetail.metadata` is `None` when invalid legacy
|
|
703
722
|
JSON produces the Provider's empty-array fallback; otherwise it contains decoded stored metadata without arbitrary
|
|
@@ -722,7 +741,7 @@ canonical update preflights the raw item response and refuses to drop top-level
|
|
|
722
741
|
`allow_source_metadata_loss=True` explicitly skips that preflight and sends the canonical replacement directly. The
|
|
723
742
|
default read/check/write protection is best effort rather than atomic because the Provider offers no revision or
|
|
724
743
|
compare-and-swap condition; this Provider-specific behavior remains internal to the update operation (PVD-027).
|
|
725
|
-
PDF replace/delete are separate acknowledged mutations and are not presented as atomic with metadata
|
|
744
|
+
PDF replace/delete are separate acknowledged mutations and are not presented as atomic with metadata.
|
|
726
745
|
Permanent personal deletion is named `permanently_delete`, returns `None`, and is non-recoverable. Sharing requires
|
|
727
746
|
list-observed item summaries, user-search summaries and a
|
|
728
747
|
valid caller identity, then returns `None` because the Provider supplies no per-recipient IDs (PVD-012, PVD-036).
|
|
@@ -759,7 +778,7 @@ time strings.
|
|
|
759
778
|
Folder create returns a `CloudFolderRef` built from the Provider ID. Other folder and file mutations return `None`
|
|
760
779
|
after acknowledgement and do not automatically list the drive. Staged finalize accepts a completed `StagedFile`;
|
|
761
780
|
the Provider binds by temporary row ID without checking its owner (PVD-031), and finalize atomicity/idempotency remain
|
|
762
|
-
absent
|
|
781
|
+
absent. Batch move and permanent delete do not claim Provider per-item results or atomicity. Permanent
|
|
763
782
|
deletion is named `permanently_delete_files` and is non-recoverable. Cloud downloads
|
|
764
783
|
resolve bytes from the final file identity and reuse `DownloadStream`, thumbnail/preview choices and the PVD-002-safe
|
|
765
784
|
range subset. Cloud mutations are not automatically retried.
|
|
@@ -901,6 +920,6 @@ uv run python scripts/check_release.py dist/release/*.whl dist/release/*.tar.gz
|
|
|
901
920
|
```
|
|
902
921
|
|
|
903
922
|
Rebuilding the same commit with the same locked environment and `SOURCE_DATE_EPOCH` must produce
|
|
904
|
-
byte-identical wheel and source distribution hashes. The release is bound to `matelab-spec v0.4.
|
|
905
|
-
|
|
906
|
-
`
|
|
923
|
+
byte-identical wheel and source distribution hashes. The release is bound to immutable `matelab-spec v0.4.5`, commit
|
|
924
|
+
`6afac7ff151680130e6e4bc6d95782589b97f4e7`, and OpenAPI SHA-256
|
|
925
|
+
`31a8d03b4366e2345dfccdbbaaaccf6754b2711428afa4295d778d121988460d`.
|
|
@@ -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.
|
|
10
|
+
The current alpha is `0.1.0a22`. `[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.
|
|
13
|
+
The SDK is pinned to the immutable `matelab-spec v0.4.5` 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,12 +36,16 @@ 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.
|
|
39
|
+
python -m pip install dist/release/matelab_python_sdk-0.1.0a22-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
|
|
43
43
|
tag, commit, and checksum recorded below.
|
|
44
44
|
|
|
45
|
+
The Contract and public SDK interface track the current reviewed Provider at
|
|
46
|
+
`59eb05b233e5ddd023a60ccb5e5c5f2ae22a70f0`. Provider limitations that remain relevant to integrations are documented
|
|
47
|
+
alongside the affected interfaces below.
|
|
48
|
+
|
|
45
49
|
## Design
|
|
46
50
|
|
|
47
51
|
The public module is intentionally small:
|
|
@@ -89,8 +93,8 @@ success code it does not allow raises `MatelabProtocolError` rather than assigni
|
|
|
89
93
|
`MatelabTransportError.status_code` remains available for HTTP failures. Provider response bodies, top-level `msg`,
|
|
90
94
|
legacy `errmsg`, opaque `errs`, uncontracted debug fields, and request payloads are not attached to exceptions because
|
|
91
95
|
Provider-authored diagnostics may contain stack traces, credentials, or submitted values.
|
|
92
|
-
The pinned v0.4.
|
|
93
|
-
|
|
96
|
+
The pinned v0.4.5 Contract also declares optional code-4 `errs`, but PVD-041 and PCG-015 record opaque array/object
|
|
97
|
+
containers and insufficient evidence for requiredness, cardinality, or exclusion from other codes. The SDK
|
|
94
98
|
therefore keeps those diagnostics wire-only and does not expose `errs` as stable public metadata. A typed detail
|
|
95
99
|
interface remains blocked until a future Contract release can define one from stronger Provider evidence. `retryable`
|
|
96
100
|
means the identical SDK call is safe to replay without further interpretation. It is conservatively `False` for every
|
|
@@ -284,8 +288,10 @@ supports one file column. A locally rejected target does not spend the handle; o
|
|
|
284
288
|
result cannot be retried through the same client.
|
|
285
289
|
|
|
286
290
|
Files-module append and table/files replacement use the general record attachment intents and may be combined with
|
|
287
|
-
other non-conflicting record changes. `RecordFilesAttachmentAppend` targets the module root
|
|
288
|
-
|
|
291
|
+
other non-conflicting record changes. `RecordFilesAttachmentAppend` currently targets the module root. Although
|
|
292
|
+
v0.4.5 records Provider evidence for safe folder paths, its top-level `UpdateRecordRequest.add[]` schema still excludes
|
|
293
|
+
the `path` property declared by the dedicated staged-name append shape; the SDK therefore does not expose folder paths
|
|
294
|
+
until that wire-schema conflict is resolved (PVD-044):
|
|
289
295
|
|
|
290
296
|
```python
|
|
291
297
|
from matelab import RecordAttachmentReplacement, RecordFilesAttachmentAppend, RecordValueUpdate
|
|
@@ -316,7 +322,9 @@ await client.records.update(
|
|
|
316
322
|
|
|
317
323
|
For a files occurrence, `caption=None` preserves the observed string caption (an observed null caption normalizes to
|
|
318
324
|
the required empty string). Table replacement requires exactly one current attachment in the selected cell and does
|
|
319
|
-
not accept a caption.
|
|
325
|
+
not accept a caption. Record reads likewise accept only one canonical attachment object or `null` in a table file cell;
|
|
326
|
+
an attachment array violates the pinned response contract. Both replacement forms require the replacement hash to
|
|
327
|
+
differ from the current occurrence.
|
|
320
328
|
|
|
321
329
|
All record attachment intents reject handles from another notebook or authenticated uploader, duplicate use within one
|
|
322
330
|
finalization request, and raw Provider attachment references. Row/index-based operations use an immediate SDK read and
|
|
@@ -393,8 +401,8 @@ and `deletePersonalLiteratureItem`.
|
|
|
393
401
|
|
|
394
402
|
Every other implemented operation is explicitly `experimental`; the exact per-operation list and its
|
|
395
403
|
PVD/PCG references live in
|
|
396
|
-
`docs/operation-coverage.yaml`. `
|
|
397
|
-
|
|
404
|
+
`docs/operation-coverage.yaml`. `readApplicationBootstrap` is intentionally unexposed because it returns the Provider
|
|
405
|
+
application environment and menu model, while SDK identity is sourced from token issuance. `readLiteratureCreateTemplate`
|
|
398
406
|
is intentionally unexposed because it returns a frontend form definition and an optional deployment flag rather than
|
|
399
407
|
a resource needed by the SDK interface. There are no `planned` operations. Experimental support means the SDK
|
|
400
408
|
validates and exposes the pinned Contract while preserving limitations such as unstable ordering/pagination,
|
|
@@ -418,7 +426,7 @@ targets = await client.users.search("Example Researcher", global_scope=False)
|
|
|
418
426
|
`groups.list()` returns the `GroupSummary` tuple directly. Ordering remains Provider-unspecified and is documented
|
|
419
427
|
rather than repeated as a constant result field. The Provider's members for an unstable first group remain wire-only;
|
|
420
428
|
`users.search()` is the public recipient-discovery interface. These two discovery interfaces are experimental because
|
|
421
|
-
group order is unstable and user search is unpaged, unordered and not field-minimized (PVD-006, PVD-029
|
|
429
|
+
group order is unstable and user search is unpaged, unordered and not field-minimized (PVD-006, PVD-029).
|
|
422
430
|
`GroupSummary.notebook_creation_available` expresses whether the group can currently host notebook creation without
|
|
423
431
|
exposing the Provider's data-server routing value.
|
|
424
432
|
|
|
@@ -468,9 +476,12 @@ await client.templates.save_content(template, modules)
|
|
|
468
476
|
`TemplateModule.data_present` distinguishes a missing `data` property from an explicit null value, while
|
|
469
477
|
`attributes` prevents additive canonical properties from being dropped during a read/save cycle. The SDK does not
|
|
470
478
|
synthesize frontend editor UIDs, layout widths, rows, folders, option encoding, or a fixed set of display module
|
|
471
|
-
types.
|
|
472
|
-
|
|
473
|
-
|
|
479
|
+
types. A JSON-language code module with style metadata may return its JSON string or explicit `null`; number and boolean
|
|
480
|
+
table cells preserve the Provider's empty string as distinct from scalar and `null` values. The Provider accepts some
|
|
481
|
+
non-canonical module roots and arbitrary table file arrays, but the SDK does not expose that behavior: saved content
|
|
482
|
+
must remain a canonical module list, and a table file cell must be one canonical attachment object or `null` (PVD-046).
|
|
483
|
+
The Provider supports only whole-content replacement and has no atomic patch or compare-and-swap operation (PCG-007),
|
|
484
|
+
so a read-modify-save sequence can overwrite a concurrent change.
|
|
474
485
|
|
|
475
486
|
The market result retains the Provider's `total_count` and derives `has_more` without echoing the caller's page
|
|
476
487
|
arguments; it does not claim a stable order or continuation token. Template reads remain experimental
|
|
@@ -510,6 +521,8 @@ relations = await client.records.relations(source)
|
|
|
510
521
|
as `modules`; it is not the template-shaped `RecordImportItem.data` accepted by record import.
|
|
511
522
|
`records.search()` maps each requested field name to a stored record path. A match exposes only Provider-returned
|
|
512
523
|
entries in `values`, so key membership distinguishes an absent result from an explicit JSON `null`.
|
|
524
|
+
The current Provider excludes encrypted records from search (PVD-043); an empty search result therefore does
|
|
525
|
+
not prove that no matching encrypted record exists.
|
|
513
526
|
|
|
514
527
|
The Provider calls its notebook directory tree `subtype`; that name remains wire-only. The SDK exposes
|
|
515
528
|
`RecordFolder`, `RecordSummary.folder_id`, and the `folders` returned with record listings. A top-level folder has
|
|
@@ -559,7 +572,9 @@ UID. Import validates the complete batch with generated wire models but cannot m
|
|
|
559
572
|
individual inputs or promise atomicity (PCG-008); it therefore returns only the tuple of database IDs actually
|
|
560
573
|
reported by the Provider. `RecordImportItem.keywords` is a tuple; the adapter owns the Provider's
|
|
561
574
|
legacy semicolon encoding. Folder paths are ordered existing folder titles from the notebook root; they do not create
|
|
562
|
-
missing folders.
|
|
575
|
+
missing folders. The current Provider rejects explicit-null table-file imports (PVD-045). Because the SDK accepts
|
|
576
|
+
arbitrary template-shaped data and cannot identify file columns without the template definition, integrations must omit
|
|
577
|
+
an unset file-valued key instead of sending it as `None`. Delete means moving records into the recycle bin, not permanent
|
|
563
578
|
deletion. Delete and restore return `None`; record mutations are not automatically retried.
|
|
564
579
|
|
|
565
580
|
`records.copy()` accepts an optional `new_record_uid`; when omitted, the SDK generates one locally. The Provider
|
|
@@ -577,7 +592,9 @@ returns the acknowledgement classification
|
|
|
577
592
|
issue a post-write read. Database, active-browser, and unclassified acknowledgements remain distinct, and mutation
|
|
578
593
|
retries stay disabled. Encrypted record content is outside the SDK's public read/update interface: the list-level
|
|
579
594
|
`RecordSummary.encrypted` flag lets callers identify and skip it, while the Provider password field and frontend-only
|
|
580
|
-
password lifecycle remain unexposed.
|
|
595
|
+
password lifecycle remain unexposed. Files-module attachment append remains root-only because the pinned top-level
|
|
596
|
+
update request schema does not admit the dedicated staged-name append shape's folder `path`; malformed path containers
|
|
597
|
+
may also silently append at root according to PVD-044. A staged attachment is indeterminate once the write has started.
|
|
581
598
|
|
|
582
599
|
Relation addition reads both endpoints and checks their resolved data server before writing; this reduces PVD-019
|
|
583
600
|
risk but is not an atomic Provider authorization guarantee. It does not list relations merely to inspect the
|
|
@@ -589,8 +606,8 @@ ignores target notebook identity (PVD-020); its mutation likewise performs autho
|
|
|
589
606
|
`records.comments()`. Each returned `RecordRelationRef` carries only the relation row and declared target IDs.
|
|
590
607
|
Deletion accepts the source `RecordLocator` and one of those observed refs.
|
|
591
608
|
|
|
592
|
-
Comment upload follows the Provider's literal one-request `
|
|
593
|
-
|
|
609
|
+
Comment upload follows the current Provider's literal one-request `file` field (PVD-037). Comment mutations return `None`
|
|
610
|
+
after acknowledgement. Edit first verifies that the selected
|
|
594
611
|
comment is currently observed and caller-owned because the Provider otherwise reports a false success for a missing or
|
|
595
612
|
other-user ID (PVD-004). Delete sends the typed ref directly because the Provider mutation itself enforces record and
|
|
596
613
|
caller ownership. Neither operation performs a post-write read. Staged comment attachments have no Contract abort
|
|
@@ -669,7 +686,9 @@ The Provider's static literature form definition and extraction deployment flag
|
|
|
669
686
|
`extract_metadata()` directly and handle an unavailable or failing optional backend as a Provider error. Extraction
|
|
670
687
|
returns a `PublicationMetadataCandidate`: unstored, rich publication evidence rather than metadata already attached to
|
|
671
688
|
a literature item. Its structured authors are `PublicationAuthorCandidate` values. Extraction accepts a DOI, a
|
|
672
|
-
completed staged PDF, or both; a supplied DOI takes precedence over the staged PDF.
|
|
689
|
+
completed staged PDF, or both; a supplied DOI takes precedence over the staged PDF. A non-empty DOI must match
|
|
690
|
+
`^10\.[0-9]+/\S+$`; the generated request model rejects other values before sending them to the Provider (PVD-042).
|
|
691
|
+
Literature list
|
|
673
692
|
results likewise exclude Provider-generated citation HTML and author-highlight fragments; Consumers receive the
|
|
674
693
|
underlying citation fields instead of presentation markup. `LiteratureDetail.metadata` is `None` when invalid legacy
|
|
675
694
|
JSON produces the Provider's empty-array fallback; otherwise it contains decoded stored metadata without arbitrary
|
|
@@ -694,7 +713,7 @@ canonical update preflights the raw item response and refuses to drop top-level
|
|
|
694
713
|
`allow_source_metadata_loss=True` explicitly skips that preflight and sends the canonical replacement directly. The
|
|
695
714
|
default read/check/write protection is best effort rather than atomic because the Provider offers no revision or
|
|
696
715
|
compare-and-swap condition; this Provider-specific behavior remains internal to the update operation (PVD-027).
|
|
697
|
-
PDF replace/delete are separate acknowledged mutations and are not presented as atomic with metadata
|
|
716
|
+
PDF replace/delete are separate acknowledged mutations and are not presented as atomic with metadata.
|
|
698
717
|
Permanent personal deletion is named `permanently_delete`, returns `None`, and is non-recoverable. Sharing requires
|
|
699
718
|
list-observed item summaries, user-search summaries and a
|
|
700
719
|
valid caller identity, then returns `None` because the Provider supplies no per-recipient IDs (PVD-012, PVD-036).
|
|
@@ -731,7 +750,7 @@ time strings.
|
|
|
731
750
|
Folder create returns a `CloudFolderRef` built from the Provider ID. Other folder and file mutations return `None`
|
|
732
751
|
after acknowledgement and do not automatically list the drive. Staged finalize accepts a completed `StagedFile`;
|
|
733
752
|
the Provider binds by temporary row ID without checking its owner (PVD-031), and finalize atomicity/idempotency remain
|
|
734
|
-
absent
|
|
753
|
+
absent. Batch move and permanent delete do not claim Provider per-item results or atomicity. Permanent
|
|
735
754
|
deletion is named `permanently_delete_files` and is non-recoverable. Cloud downloads
|
|
736
755
|
resolve bytes from the final file identity and reuse `DownloadStream`, thumbnail/preview choices and the PVD-002-safe
|
|
737
756
|
range subset. Cloud mutations are not automatically retried.
|
|
@@ -873,6 +892,6 @@ uv run python scripts/check_release.py dist/release/*.whl dist/release/*.tar.gz
|
|
|
873
892
|
```
|
|
874
893
|
|
|
875
894
|
Rebuilding the same commit with the same locked environment and `SOURCE_DATE_EPOCH` must produce
|
|
876
|
-
byte-identical wheel and source distribution hashes. The release is bound to `matelab-spec v0.4.
|
|
877
|
-
|
|
878
|
-
`
|
|
895
|
+
byte-identical wheel and source distribution hashes. The release is bound to immutable `matelab-spec v0.4.5`, commit
|
|
896
|
+
`6afac7ff151680130e6e4bc6d95782589b97f4e7`, and OpenAPI SHA-256
|
|
897
|
+
`31a8d03b4366e2345dfccdbbaaaccf6754b2711428afa4295d778d121988460d`.
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
"schema_version": 1,
|
|
3
3
|
"contract_line": "integration-v1",
|
|
4
4
|
"release": {
|
|
5
|
-
"tag": "v0.4.
|
|
6
|
-
"commit": "
|
|
5
|
+
"tag": "v0.4.5",
|
|
6
|
+
"commit": "6afac7ff151680130e6e4bc6d95782589b97f4e7"
|
|
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": "
|
|
11
|
+
"sha256": "31a8d03b4366e2345dfccdbbaaaccf6754b2711428afa4295d778d121988460d"
|
|
12
12
|
}
|
|
13
13
|
}
|