matelab-python-sdk 0.1.0a15__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 (78) hide show
  1. matelab_python_sdk-0.1.0a17/AGENTS.md +94 -0
  2. matelab_python_sdk-0.1.0a17/CHANGELOG.md +330 -0
  3. matelab_python_sdk-0.1.0a17/CONTEXT.md +91 -0
  4. matelab_python_sdk-0.1.0a17/PKG-INFO +906 -0
  5. matelab_python_sdk-0.1.0a17/README.md +878 -0
  6. {matelab_python_sdk-0.1.0a15 → matelab_python_sdk-0.1.0a17}/contracts/matelab-integration-v1.lock.json +3 -3
  7. {matelab_python_sdk-0.1.0a15 → matelab_python_sdk-0.1.0a17}/contracts/matelab-integration-v1.openapi.yaml +59 -8
  8. {matelab_python_sdk-0.1.0a15 → matelab_python_sdk-0.1.0a17}/docs/operation-coverage.yaml +16 -12
  9. {matelab_python_sdk-0.1.0a15 → matelab_python_sdk-0.1.0a17}/pyproject.toml +3 -1
  10. {matelab_python_sdk-0.1.0a15 → matelab_python_sdk-0.1.0a17}/scripts/generate_models.py +1 -2
  11. {matelab_python_sdk-0.1.0a15 → matelab_python_sdk-0.1.0a17}/src/matelab/__init__.py +33 -132
  12. {matelab_python_sdk-0.1.0a15 → matelab_python_sdk-0.1.0a17}/src/matelab/_generated/models.py +560 -637
  13. matelab_python_sdk-0.1.0a17/src/matelab/_hashes.py +8 -0
  14. {matelab_python_sdk-0.1.0a15 → matelab_python_sdk-0.1.0a17}/src/matelab/_transport.py +30 -22
  15. {matelab_python_sdk-0.1.0a15 → matelab_python_sdk-0.1.0a17}/src/matelab/_wire_validation.py +11 -8
  16. {matelab_python_sdk-0.1.0a15 → matelab_python_sdk-0.1.0a17}/src/matelab/client.py +7 -13
  17. matelab_python_sdk-0.1.0a17/src/matelab/domains/_attachment_content.py +45 -0
  18. {matelab_python_sdk-0.1.0a15 → matelab_python_sdk-0.1.0a17}/src/matelab/domains/cloud_drive.py +21 -76
  19. matelab_python_sdk-0.1.0a17/src/matelab/domains/groups.py +41 -0
  20. matelab_python_sdk-0.1.0a17/src/matelab/domains/literature.py +722 -0
  21. matelab_python_sdk-0.1.0a17/src/matelab/domains/notebooks.py +335 -0
  22. matelab_python_sdk-0.1.0a17/src/matelab/domains/records.py +2150 -0
  23. {matelab_python_sdk-0.1.0a15 → matelab_python_sdk-0.1.0a17}/src/matelab/domains/templates.py +113 -210
  24. {matelab_python_sdk-0.1.0a15 → matelab_python_sdk-0.1.0a17}/src/matelab/domains/uploads.py +36 -37
  25. {matelab_python_sdk-0.1.0a15 → matelab_python_sdk-0.1.0a17}/src/matelab/domains/users.py +3 -5
  26. {matelab_python_sdk-0.1.0a15 → matelab_python_sdk-0.1.0a17}/src/matelab/errors.py +6 -3
  27. {matelab_python_sdk-0.1.0a15 → matelab_python_sdk-0.1.0a17}/tests/test_async_attachment_upload.py +145 -104
  28. {matelab_python_sdk-0.1.0a15 → matelab_python_sdk-0.1.0a17}/tests/test_client.py +1 -1
  29. {matelab_python_sdk-0.1.0a15 → matelab_python_sdk-0.1.0a17}/tests/test_cloud_drive.py +13 -38
  30. {matelab_python_sdk-0.1.0a15 → matelab_python_sdk-0.1.0a17}/tests/test_comments_and_downloads.py +10 -15
  31. {matelab_python_sdk-0.1.0a15 → matelab_python_sdk-0.1.0a17}/tests/test_consumer_smoke.py +7 -3
  32. {matelab_python_sdk-0.1.0a15 → matelab_python_sdk-0.1.0a17}/tests/test_errors.py +12 -7
  33. {matelab_python_sdk-0.1.0a15 → matelab_python_sdk-0.1.0a17}/tests/test_extended_records.py +66 -81
  34. {matelab_python_sdk-0.1.0a15 → matelab_python_sdk-0.1.0a17}/tests/test_generation.py +17 -3
  35. matelab_python_sdk-0.1.0a17/tests/test_groups.py +61 -0
  36. {matelab_python_sdk-0.1.0a15 → matelab_python_sdk-0.1.0a17}/tests/test_notebook_lifecycle.py +74 -62
  37. {matelab_python_sdk-0.1.0a15 → matelab_python_sdk-0.1.0a17}/tests/test_notebooks.py +33 -5
  38. {matelab_python_sdk-0.1.0a15 → matelab_python_sdk-0.1.0a17}/tests/test_operation_coverage.py +6 -12
  39. {matelab_python_sdk-0.1.0a15 → matelab_python_sdk-0.1.0a17}/tests/test_record_lifecycle.py +75 -48
  40. {matelab_python_sdk-0.1.0a15 → matelab_python_sdk-0.1.0a17}/tests/test_record_mutations.py +286 -254
  41. {matelab_python_sdk-0.1.0a15 → matelab_python_sdk-0.1.0a17}/tests/test_records.py +32 -49
  42. {matelab_python_sdk-0.1.0a15 → matelab_python_sdk-0.1.0a17}/tests/test_streaming.py +28 -18
  43. {matelab_python_sdk-0.1.0a15 → matelab_python_sdk-0.1.0a17}/tests/test_template_lifecycle.py +39 -116
  44. {matelab_python_sdk-0.1.0a15 → matelab_python_sdk-0.1.0a17}/tests/test_templates.py +23 -28
  45. {matelab_python_sdk-0.1.0a15 → matelab_python_sdk-0.1.0a17}/tests/test_transport.py +92 -37
  46. {matelab_python_sdk-0.1.0a15 → matelab_python_sdk-0.1.0a17}/tests/test_uploads_and_literature.py +371 -118
  47. {matelab_python_sdk-0.1.0a15 → matelab_python_sdk-0.1.0a17}/tests/test_users.py +3 -9
  48. matelab_python_sdk-0.1.0a17/tests/typing/consumer.py +125 -0
  49. {matelab_python_sdk-0.1.0a15 → matelab_python_sdk-0.1.0a17}/uv.lock +1 -1
  50. matelab_python_sdk-0.1.0a15/AGENTS.md +0 -127
  51. matelab_python_sdk-0.1.0a15/CHANGELOG.md +0 -145
  52. matelab_python_sdk-0.1.0a15/PKG-INFO +0 -769
  53. matelab_python_sdk-0.1.0a15/README.md +0 -741
  54. matelab_python_sdk-0.1.0a15/src/matelab/domains/_attachment_content.py +0 -71
  55. matelab_python_sdk-0.1.0a15/src/matelab/domains/groups.py +0 -78
  56. matelab_python_sdk-0.1.0a15/src/matelab/domains/literature.py +0 -832
  57. matelab_python_sdk-0.1.0a15/src/matelab/domains/notebooks.py +0 -379
  58. matelab_python_sdk-0.1.0a15/src/matelab/domains/records.py +0 -2690
  59. matelab_python_sdk-0.1.0a15/src/matelab/domains/template_documents.py +0 -527
  60. matelab_python_sdk-0.1.0a15/tests/test_groups.py +0 -101
  61. matelab_python_sdk-0.1.0a15/tests/test_template_documents.py +0 -393
  62. matelab_python_sdk-0.1.0a15/tests/typing/consumer.py +0 -119
  63. {matelab_python_sdk-0.1.0a15 → matelab_python_sdk-0.1.0a17}/.env.example +0 -0
  64. {matelab_python_sdk-0.1.0a15 → matelab_python_sdk-0.1.0a17}/.github/workflows/release.yml +0 -0
  65. {matelab_python_sdk-0.1.0a15 → matelab_python_sdk-0.1.0a17}/.gitignore +0 -0
  66. {matelab_python_sdk-0.1.0a15 → matelab_python_sdk-0.1.0a17}/LICENSE +0 -0
  67. {matelab_python_sdk-0.1.0a15 → matelab_python_sdk-0.1.0a17}/NOTICE +0 -0
  68. {matelab_python_sdk-0.1.0a15 → matelab_python_sdk-0.1.0a17}/scripts/check_installed_package.py +0 -0
  69. {matelab_python_sdk-0.1.0a15 → matelab_python_sdk-0.1.0a17}/scripts/check_release.py +0 -0
  70. {matelab_python_sdk-0.1.0a15 → matelab_python_sdk-0.1.0a17}/src/matelab/_generated/__init__.py +0 -0
  71. {matelab_python_sdk-0.1.0a15 → matelab_python_sdk-0.1.0a17}/src/matelab/domains/__init__.py +0 -0
  72. {matelab_python_sdk-0.1.0a15 → matelab_python_sdk-0.1.0a17}/src/matelab/py.typed +0 -0
  73. {matelab_python_sdk-0.1.0a15 → matelab_python_sdk-0.1.0a17}/src/matelab/session.py +0 -0
  74. {matelab_python_sdk-0.1.0a15 → matelab_python_sdk-0.1.0a17}/src/matelab/streaming.py +0 -0
  75. {matelab_python_sdk-0.1.0a15 → matelab_python_sdk-0.1.0a17}/tests/conftest.py +0 -0
  76. {matelab_python_sdk-0.1.0a15 → matelab_python_sdk-0.1.0a17}/tests/provider/test_provider_smoke.py +0 -0
  77. {matelab_python_sdk-0.1.0a15 → matelab_python_sdk-0.1.0a17}/tests/test_release.py +0 -0
  78. {matelab_python_sdk-0.1.0a15 → matelab_python_sdk-0.1.0a17}/tests/typing/pyproject.toml +0 -0
@@ -0,0 +1,94 @@
1
+ # AGENTS.md
2
+
3
+ 本文档只保留维护 `matelab-python-sdk` 必须长期遵守的约束,不记录当前功能清单、迁移历史、阶段性状态或
4
+ 一次性验收数字。
5
+
6
+ ## 文档与权威边界
7
+
8
+ - `README.md`:当前 public interface、集成语义、示例及可执行的开发/发布流程;不承担版本迁移历史。
9
+ - `CONTEXT.md`:公共领域术语及易混概念的统一词汇;不记录实现或协议细节。
10
+ - `CHANGELOG.md`:按 SDK 版本记录变化和迁移影响;不作为当前接口说明。
11
+ - `docs/operation-coverage.yaml`:operation 状态、公开入口、稳定性和已知问题的机器权威;不写叙述性用法。
12
+ - `pyproject.toml`:SDK 版本、依赖范围、构建和工具配置的机器权威;`uv.lock` 只锁定本仓库环境。
13
+ - `contracts/matelab-integration-v1.lock.json` 及其 snapshot:Contract pin 和 wire schema 的唯一机器权威。
14
+ - `src/matelab/__init__.py::__all__`:公开导入边界;测试是行为证据,不替代上述文档。
15
+ - 本文件只规定维护原则和质量门槛。机器权威变化时,同一变更必须同步受影响的叙述文档,避免复制无归属的
16
+ 版本号、配置值或 operation 清单。
17
+
18
+ ## 工作范围与 public interface
19
+
20
+ - 本项目是 Matelab Integration Contract 的通用异步 Python Consumer,负责隐藏 HTTP 编码、认证刷新、业务
21
+ 错误、wire model 和 Provider 兼容细节。
22
+ - `/home/tnzhu/projects/matelab-spec` 负责 Wire Contract、兼容策略及 Provider 问题;`matelab-server` 是 Provider
23
+ 实现,`matelab-mcp` 只是 Consumer 证据,均不能反向定义 SDK interface。
24
+ - 修改前执行 `git status`,现有改动视为用户工作。默认只修改本仓库;未经明确授权,不修改相邻仓库、不迁移
25
+ MCP、不 commit/push/tag/publish,也不对真实 Provider 执行 mutation。
26
+ - `AsyncMatelab` 是稳定入口,能力按领域组织。public interface 只表达用户意图,不泄漏 controller、path、
27
+ opcode、wire 字段、generated model 或认证刷新细节。
28
+ - 公共类型必须区分 userid、database id、UID、relation id、staging id 等身份空间。Provider 未返回的 identity、
29
+ affected rows、排序、分页、原子性、CAS、幂等性或持久化结果不得推测;legacy 限制应诚实表达。
30
+ - MCP typed refs、capabilities、fingerprints、FastMCP/Redis context 和 Agent 展示模型不得进入 SDK。仅在存在真实
31
+ 第二种实现时增加 seam,不为测试预设抽象。
32
+ - 支持 Python 3.11+;源码不使用 `from __future__ import annotations`,前向引用优先通过定义顺序解决。
33
+
34
+ ## Contract、生成与 transport
35
+
36
+ - 每个 operation 必须核对 pinned OpenAPI 的 request、response、security、examples 和成功码,并查看相关
37
+ PVD/PCG。Contract 不足时可只读参考 Provider/Consumer;仍无法安全表达就报告缺口,不猜测或静默适配漂移。
38
+ - Contract Adoption 只能来自不可变 release tag,并在同一变更中更新唯一 lock 的 tag、commit、snapshot path
39
+ 和 SHA-256,重新生成并复核差异;不得跟踪移动分支或改写正式 snapshot。
40
+ - request/response 均由生成 wire model 校验,adapter 只负责 public Python 名称与 wire 字段映射。required
41
+ nullable 使用无默认值的 `T | None`;request 拒绝未知字段,response 兼容新增字段。
42
+ - 不手工编辑 `_generated`。generation projection 只能补偿生成器表达能力,并保留 inherited required 及
43
+ `if/then`、`oneOf`、`anyOf`、`not`;生成变化必须可追溯,`--check` 必须确定、非写入且能发现 stale output。
44
+ - `base_url` 是 Provider API 根;query、JSON、form、multipart、streaming、bearer 和成功码均按 operation 配置,
45
+ 不能用全局默认掩盖差异。
46
+ - `Token`、`Identity` 和 `Session` 是冻结、拒绝额外字段的 public model,组成规范化 Session JSON。每个
47
+ `AsyncMatelab` 最多持有一个最新 Session;SDK 不绑定裸 token,持久化、加密、撤销、身份归属和跨进程锁
48
+ 属于集成方。不同逻辑 Session 不共享 client,但可共享注入的 `httpx.AsyncClient`。
49
+ - token 在 repr 中隐藏,显式 Session JSON 保留凭证;凭证、SSO 参数、附件内容及敏感 payload 不得进入日志、
50
+ 异常或提交内容。
51
+ - access 到期前刷新;并发刷新使用单锁;安全请求遇到 `code=5` 最多刷新重试一次。mutation 默认不重试,
52
+ multipart/stream 仅在可重放时重试,download stream 必须可显式关闭。
53
+ - transport、Provider business/authentication、Contract/schema 和 usage 错误必须稳定区分;公开错误直接提供
54
+ 集成级 `category` 和保守的 `retryable`,下游不应重新解释 Provider 数字 code。
55
+
56
+ ## 测试与质量门槛
57
+
58
+ - 测试以 public interface 为主。新增或修改 operation 至少覆盖 method/path/encoding、认证、成功映射及适用的
59
+ 空结果、required nullable、additive response fields;通用 transport/auth/error 语义在集中测试中覆盖。
60
+ - 删除或收紧 public interface 时同步删除过时测试;无明确兼容承诺时不保留墓碑 alias 或测试。
61
+ - operation coverage 必须与 pinned OpenAPI exact match;implemented operation 必须同时具备 public interface、
62
+ wire adapter 和测试。生成测试必须覆盖 metadata/checksum、schema、required/nullable、extra policy、确定性和
63
+ stale detection。
64
+ - Provider smoke 默认 skip 且不自动读取 `.env`;本地 `.env.test` 必须保持 Git ignore。只能通过显式
65
+ `uv run --env-file .env.test` 对已确认的隔离目标 opt in;生产目标、mutation 或带写痕迹的读取必须获得本轮
66
+ 明确授权,并回读、尽力清理。
67
+ - Ruff/Basedpyright 的具体配置以 `pyproject.toml` 为准;不得通过排除测试、全局关规则或缩小检查范围消除诊断。
68
+ Basedpyright 目标为 0 errors / 0 warnings,必要 ignore 必须精确并说明原因。
69
+ - 先跑相关测试,交付前跑完整门槛;skip 必须说明原因,不能报告为通过:
70
+
71
+ ```bash
72
+ uv sync --frozen
73
+ uv run python scripts/generate_models.py --check
74
+ uv run ruff check .
75
+ uv run ruff format --check .
76
+ uv run basedpyright
77
+ uv run pytest
78
+ uv build --no-build-isolation
79
+ ```
80
+
81
+ 若沙箱造成缓存、Node wheel 或解释器发现失败,应在沙箱外复核同一命令,不得改配置或使用未锁定工具绕过。
82
+
83
+ ## 依赖、版本与发布
84
+
85
+ - runtime dependency 必须声明经支持 Python 版本验证的下限,并排除未经验证的下一个 major;构建后端范围和
86
+ wheel package 必须显式配置,不能依赖自动发现。
87
+ - `[project].version` 是唯一 SDK 版本源;SDK 使用 SemVer,Contract Line 不是 SDK 版本。公开接口删除、重命名、
88
+ 类型收紧或行为变化均按 breaking change 处理。
89
+ - 发行采用 Apache-2.0;`LICENSE`、`NOTICE`、PEP 639 metadata 和制品内容必须一致,wheel 包含 `py.typed` 且
90
+ 不公开 `_generated`。
91
+ - Gitee `origin` 是内部主仓库,私有 GitHub mirror 只承载 PyPI Trusted Publishing。release workflow 仅由与
92
+ 项目版本完全匹配的 `v*` tag 触发,第三方 Action 固定不可变 commit SHA。
93
+ - release 必须来自干净 revision、锁定环境和固定 `SOURCE_DATE_EPOCH`,记录 Contract 与制品 checksum;候选
94
+ 制品须审计内容/METADATA、验证安装后的公开导入和类型消费、覆盖 Python 版本边界并确认可复现构建。
@@ -0,0 +1,330 @@
1
+ # Changelog
2
+
3
+ This file records release-to-release changes and migration impact. It is not the authority for the current interface;
4
+ see [README.md](README.md) for current behavior and [AGENTS.md](AGENTS.md) for maintenance policy.
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
+
19
+ ## 0.1.0a16 - 2026-08-14
20
+
21
+ - Breaking: `UserSummary.display_name` is renamed to `name`; the SDK exposes the Provider's raw nullable real name
22
+ without implying presentation formatting. `NotebookShare.recipient_display_name` similarly becomes
23
+ `recipient_name`.
24
+ - Breaking: `templates.list()` now returns the `TemplateSummary` tuple directly and replaces `source` with the
25
+ `owned/shared/group/public` string-literal `scope`; `TemplateCollection`, `TemplateSource`, and
26
+ `TemplateLibraryRelationKind` are removed. Provider marketplace acquisitions and defaults share public scope, with
27
+ the optional user-library relation distinguishing an acquisition. The administrator-only `pending[]` queue is not
28
+ emitted as a visible template; owned rows expose their actual `pub` submission state as `market_review_pending`.
29
+ `TemplateLibraryEntryRef.kind` now identifies only the real user-library versus group-library relation identity
30
+ space, and one `remove_from_library()` operation replaces `unshare()`, `remove_market_acquisition()`, and
31
+ `remove_from_group()`. Template metadata `update()` requires all replaceable fields and returns `None`; generic
32
+ revision fields are renamed to `content_version`, `published_content_version`, and `market_review_reason`.
33
+ `TemplateMarketPage` retains its items, Provider-reported total and SDK-derived `has_more` without echoing request
34
+ pagination. Owned transfer provenance and pending-review publisher attribution are no longer mislabeled as
35
+ a uniform owner field; `owner` remains populated only where shared/group rows actually return the current owner.
36
+ Template summaries and marketplace entries consistently name stored usage content `usage_html`.
37
+ `update_usage()` replaces `update_intro()` and generates the Provider-only upload correlation value internally;
38
+ usage attachments remain unsupported while PVD-026 is open.
39
+ - Breaking: removes the frontend-derived `TemplateDocument`, semantic module/field/change models, and
40
+ `templates.read_document()`, `save_document()`, and `patch_content()`. Template content now has one public model,
41
+ `TemplateModule`, read with `templates.read()` and written as a full replacement with `templates.save_content()`.
42
+ Consumers that provide an editor should own its layout defaults and patch model; the Provider exposes neither an
43
+ atomic template patch nor compare-and-swap semantics.
44
+ - Centralizes outbound request serialization in the transport. Domain adapters now pass validated Pydantic wire models
45
+ directly; the transport emits wire aliases and explicitly supplied fields, reveals `SecretStr` values only in the
46
+ outbound payload, and separates multipart file fields without call-site `model_dump()` projections.
47
+ - Breaking: replaces notebook sharing's raw permission masks and seven boolean update arguments with
48
+ `NotebookPermissions`, shared with record-page capability results. `NotebookShareRef` now contains only
49
+ notebook/share-row identity; recipient metadata belongs to `NotebookShare`, while caller-relative
50
+ `belongs_to_caller` and redundant `caller_is_owner` are removed.
51
+ `NotebookShares` also drops its duplicate notebook field because each share ref already carries that context.
52
+ The Provider signing permission remains policy-only and does not introduce an SDK signing operation.
53
+ - Breaking: removes `NotebookListField`, notebook-list display fields and type tags from `NotebookSummary`, and UI
54
+ display/type-tag inputs from notebook creation and update. Provider `types`/`display`/`requests` remain wire-only
55
+ compatibility details; metadata updates pre-read the current owned notebook and preserve that configuration on a
56
+ best-effort basis because no atomic read-modify-write or compare-and-swap operation exists.
57
+ - Breaking: removes `PublicNotebookSummary`. Owned, shared, and public catalog entries now all use `NotebookSummary`;
58
+ public owner/group metadata that the Contract does not return is represented as `None` rather than an empty value
59
+ inferred by the SDK.
60
+ - Breaking: removes template render metadata, cloud-drive display-formatted dates, literature citation HTML/search
61
+ highlighting, and the Provider's literature form-definition models from the public interface. Removes
62
+ `literature.creation_schema()` without exposing its frontend template or deployment capability flag; Consumers call
63
+ `literature.extract_metadata()` directly and handle an unavailable optional backend as a Provider error. Metadata
64
+ extraction accepts either source and gives a supplied DOI precedence over a staged PDF.
65
+ - Breaking: `TemplateLibraryEntryRef` drops its duplicate template identity. `TemplateSummary` no longer projects
66
+ owner/group display names or the Provider's UI-oriented group `admin` flag.
67
+ - Breaking: removes `RecordSignature`, record lock/signature projections and `RecordVersionSummary`. `Record.versions`
68
+ now contains `RecordVersionRef` values directly; Provider version metadata and signature state remain wire-only.
69
+ - Breaking: removes `RecordPageContext` and `RecordPagePermissions`; `RecordPage` exposes the common
70
+ `NotebookPermissions` directly, without duplicate input notebook, request pagination, owner display name or template
71
+ UI context.
72
+ Provider finalization and additional-signature mutations remain deliberately outside the pinned Contract and SDK.
73
+ - Breaking: unifies personal and shared literature identities as `LiteratureLibraryRef` and `LiteratureItemRef`,
74
+ with `LiteratureLibraryRef.scope` derived from its identity rather than accepted as a second constructor value:
75
+ zero identifies the synthetic personal library and positive IDs identify shared libraries. Replaces raw literature
76
+ permission masks with `LiteratureLibraryPermissions`. `literature.libraries()` now returns usable summaries directly
77
+ and removes `LiteratureLibraries`, `PendingLiteratureShare`, and `PendingLiteratureShareComment`; dangling membership
78
+ rows and pending-share projections remain wire-only until a complete accept/reject Contract exists. Raw
79
+ source/backend extension maps remain wire-compatible but are no longer public; canonical-update loss detection stays
80
+ inside the update operation, covers top-level and nested source fields, and reports affected field paths only when
81
+ refusing a lossy update. Explicit loss opt-in skips the otherwise best-effort, non-atomic detail preflight. Comment
82
+ creation and update are now explicit `create_comment()` and `update_comment()` operations. `LiteratureCommentRef`
83
+ retains only the Provider comment-row ID. Creation pre-reads detail and rejects an existing caller-owned comment to
84
+ maintain the Integration Contract's one-caller-comment invariant despite the Provider's non-atomic PVD-035 gap;
85
+ update/delete avoid a duplicate read and rely on the mutation's ownership and permission checks. Invalid stored JSON
86
+ is represented by `LiteratureDetail.metadata=None` instead of a special metadata object with a wire-shaped validity
87
+ flag.
88
+ `LiteraturePage` shortens `library_name` to `name` and calls library classification labels `tags` rather than
89
+ overloading bibliographic `keywords`. `LiteratureLibrarySummary`, `LiteratureItemSummary`, and `LiteratureDetail`
90
+ use the same tag vocabulary; `literature.list(tags=...)` maps it to the legacy wire `keywords` filter.
91
+ Renames `LiteratureMetadata` to `LiteratureMetadataInput`, `LiteratureStoredMetadata` to
92
+ `StoredLiteratureMetadata`, `ExtractedLiteratureMetadata` to `PublicationMetadataCandidate`, and
93
+ `ExtractedLiteratureAuthor` to `PublicationAuthorCandidate`, distinguishing canonical write input, decoded stored
94
+ state, and unstored DOI/PDF evidence. The old public names are removed without aliases. `StoredLiteratureMetadata`
95
+ removes the duplicate legacy `authors` array and normalizes it into the canonical `author` text only when that
96
+ canonical field is absent; raw legacy fields remain available to internal update-loss detection.
97
+ `LiteratureItemSummary` and `LiteratureDetail` expose nullable `rating` instead of the Provider's zero-sentinel `star`,
98
+ represent a missing PDF as `None`, and require a non-null SHA-256 on each exposed `LiteraturePdf`; filename and size
99
+ remain optional. The falsely named list `publication_date` is removed, and optional list metadata uses `None` instead
100
+ of Provider empty-string sentinels.
101
+ - Breaking: record export and search now return tuples directly, and routing/forwarding flags are no longer public.
102
+ `ExportedRecord.modules` replaces the wire-shaped `data` field and distinguishes canonical stored modules from
103
+ template-shaped `RecordImportItem.data`. `records.search()` accepts its required field-to-path mapping as the primary
104
+ positional argument; `RecordSearchMatch.values` replaces `extracted` and the redundant `missing_extractions`, with
105
+ absent keys distinguishing missing Provider results from explicit JSON nulls.
106
+ Record lists/pages omit the Provider's full UI selection/filter payload, call their free-text filter `search`, and
107
+ use semantic permission names; record reads accept one `RecordLocator` or `RecordVersionRef` and expose the resolved
108
+ locator once as `Record.source`. Owner/editable UI flags, duplicated identity, template-rendering, PDF-capability,
109
+ data-server, and redundant selected-UID fields are removed. `Record.version` identifies historical content. Record
110
+ versions retain only their typed refs; Provider version/signature metadata stays wire-only.
111
+ `records.import_dataset()` returns the Provider-reported database-ID tuple directly and removes the one-field
112
+ `RecordImportResult`. The Provider-built notebook echo in paged record responses is not revalidated because server
113
+ code constructs it from the request. Record update does not expose the Provider's `password` field: the pinned read
114
+ Contract cannot represent encrypted record content, and the frontend's separate set/change/remove-password
115
+ lifecycle is not a safe generic SDK capability. `RecordImportItem.keywords`
116
+ replaces the Provider's singular semicolon-encoded `keyword` input. The Provider's misleading record `subtype`
117
+ terminology is now wire-only:
118
+ `RecordFolder`, `folder_id`, `folder_path`, and `folders` describe the notebook directory tree. Root-parent and
119
+ root-record zero sentinels become `None`, empty-folder SQL counts become zero, and `NotebookPermissions` uses
120
+ `can_manage_record_folders`. Record identities consistently use `record_id` for the Provider database row and
121
+ `record_uid` for its UID; the redundant `record_database_id` spelling is removed. Record copy now accepts an
122
+ optional caller-chosen `new_record_uid`, generates one locally when omitted, and returns a complete
123
+ `RecordLocator`; the partial one-field `RecordCopyResult` is removed. Deleted-record summaries and restore inputs
124
+ reuse `RecordRef`; the identical `DeletedRecordRef` type is removed without an alias.
125
+ - Breaking: replaces the eight mutation-family keyword arguments on `records.update()` with one required
126
+ `changes: Sequence[RecordChange]`. `RecordValueUpdate`, `RecordValueDeletion`, and `RecordModuleDeletion` complete
127
+ the typed intent union alongside the existing module, attachment, file-structure, and rich-text changes. The
128
+ category-only `RecordAttachmentChange` and `RecordFileStructureChange` aliases are removed; the SDK now keeps
129
+ Provider `modify`/`del`/`addModule`/`delModule`/`add` classification entirely inside the update implementation.
130
+ Removes `Record.content_sha256` and `records.update(expected_content_sha256=...)`: the value was only an SDK-side
131
+ read/prewrite comparison and could not provide Provider compare-and-swap semantics. Current-state reads now serve
132
+ only attachment/path safety rules; ordinary module creation and deletion use the Provider's canonical validation
133
+ without an additional SDK read. The update acknowledgement values are shortened to `"persisted"`, `"pending"`,
134
+ and `"unknown"`; the last value remains a conservative fallback for an unrecognized successful Provider message.
135
+ - Breaking: record relations now return a tuple directly and remove `RecordRelations`; the relation endpoint's legacy
136
+ comment duplicate and caller-relative `editable` value remain wire-only. `RecordCommentRef` now carries its typed
137
+ record source, update/delete accept that ref, and `RecordComment` no longer publishes duplicate source or
138
+ `owned_by_caller` UI state. Comment attachment refs no longer duplicate their parent comment; downloads accept the
139
+ parent ref explicitly. `RecordVersionRef` likewise carries a `RecordLocator` instead of three repeated primitive
140
+ identity fields. Historical reads now accept that version ref
141
+ directly instead of requiring the same locator a second time. Public record summaries drop the unused
142
+ caller-ownership flag, stale publication-lock state and owner email, and use the common `notebook_title` name.
143
+ `RecordRelationRef` now carries only its relation row and declared target IDs. The one-use `RelatedRecordIdentity`
144
+ wrapper and preview-oriented `RecordRelation` are removed; `relations()` returns refs directly, while
145
+ `delete_relation()` takes the source locator explicitly instead of duplicating it in every listed relation.
146
+ Deleted-record pages do not repeat request pagination or the input notebook and impose no SDK-only size range beyond
147
+ the Contract minimum. Relation writes no longer list relations solely to
148
+ inspect the caller-relative `editable` flag; Provider mutation authorization remains authoritative, while the reads
149
+ required for cross-server addition and target-ID-safe deletion remain. Record comment create/update use `body`;
150
+ update retains the PVD-004 ownership preflight, while deletion relies on the Provider's own ownership check and
151
+ avoids a duplicate list request. Comment bodies are not display-normalized before the Provider's documented trim.
152
+ - Breaking: unifies record attachment staging as `records.upload_attachment(notebook, ...) -> StagedAttachment`.
153
+ Uploading does not choose a target record; the handle retains its notebook selector, authenticated uploader, binding,
154
+ filename, and hash and is accepted by either one later import or update. `stage_attachment()`,
155
+ `StagedNotebookAttachment`, and `StagedRecordAttachment` are removed without aliases.
156
+ `upload_attachment()` no longer accepts caller-supplied staging metadata: the SDK generates the upload event,
157
+ calculates the SHA-256, omits the Provider's equivalent `name` and `last=1` defaults, and uses the validated response
158
+ as the completed staging result. Both attachment upload methods remove caller-supplied size, checksum, and multipart
159
+ content type because the Provider derives the metadata and both Contracts fix opaque binary attachment parts.
160
+ Comment uploads no longer expose `UploadBindingRef`; the SDK generates the Provider binding internally, while a
161
+ prior staged comment attachment may be passed as `batch=` when several uploads will be saved into one comment.
162
+ `RecordFilesAttachmentRootAppend`, `RecordTableFileAttachmentReplacement`, and
163
+ `RecordFilesAttachmentReplacement` are also removed: `RecordFilesAttachmentAppend` and
164
+ `RecordAttachmentReplacement` cover those intents, and files append now calls its optional location `folder_path`
165
+ instead of the wire-shaped `path`. Final operations centrally reject a different notebook or uploader, duplicate
166
+ references, and reuse after an attempted finalization. Provider temporary row IDs and caller-known response echoes
167
+ remain internal, while upload responses are still validated. `RecordImportItem.data` uses the recursive
168
+ `RecordImportValue` type instead of `object`, matching the JSON-or-staged-attachment values accepted at runtime.
169
+ - Breaking: group discovery replaces the raw data-server selector with `notebook_creation_available`.
170
+ `groups.list()` now returns the `GroupSummary` tuple directly and removes `GroupCollection` and `GroupMember`; the
171
+ Provider's unstable first-group member projection remains wire-only. Cloud-drive listings no longer expose synthetic
172
+ root metadata, constant caller ownership, inferred file locations or request echoes. `CloudDriveListing` retains
173
+ `total_count` and SDK-derived `has_more` directly and removes the one-use `CloudFilePage` wrapper. Completed staged files
174
+ keep their temporary Provider URL as an internal cross-operation binding detail rather than public metadata.
175
+ - Breaking: `StagedFile` now exposes its downstream `binding` directly instead of embedding the completed upload's
176
+ `StagedUploadSession`; `next_offset` remains exclusive to active sessions, while the upload-session identity remains
177
+ internal for cleanup. Non-final staging now returns the next `StagedUploadSession` directly and removes the shallow
178
+ `StagedFileFragment` wrapper. Byte fragments derive their size when omitted; file-like fragments still require it.
179
+ Provider-returned filename and size are still validated but no longer repeat caller-known values on the completed
180
+ result. `uploads.abort()` accepts either an active session or a completed staged file.
181
+ - Simplifies notebook operation boundaries around one internal allowed-scope validator. `NotebookRef.title` rejects
182
+ blank values but preserves surrounding whitespace because legacy private operations use the exact title as a
183
+ selector. Its `Literal` already defines the three possible scope values; operation seams state whether they accept
184
+ owned, shared, or public refs without a redundant constructor check.
185
+ - Makes the repository Ruff configuration authoritative for generated models. Generator emission uses its built-in
186
+ formatter before the explicit project-configured Ruff normalization, avoiding two competing Ruff configurations.
187
+
188
+ ## 0.1.0a15 - 2026-08-10
189
+
190
+ - Breaking: removes `PublicNotebookRef` and uses one `NotebookRef` with `scope="owned"`, `"shared"`, or `"public"`.
191
+ Public `notebook_id` values identify `eln_public` catalog rows rather than source ELNs; public record results retain
192
+ their separate source notebook identity.
193
+ - Centralizes notebook-scope validation: public record listing accepts only a public ref with a non-empty title,
194
+ private operations reject public refs, and owned-only notebook mutations reject shared/public refs. `NotebookRef.title`
195
+ is a non-empty `str` preserved without whitespace normalization; an unexpected null from the wider owned/shared wire
196
+ contract is reported as a protocol violation, matching Provider write validation and audited runtime data.
197
+
198
+ ## 0.1.0a14 - 2026-08-10
199
+
200
+ - Adds immutable semantic template modules, editable `TemplateDocument` values, ordered name-based patch intents,
201
+ stable content fingerprints, and `Templates.read_document()`, `save_document()`, and `patch_content()` while
202
+ retaining the low-level `TemplateModule`, `read()`, and `save_content()` interface.
203
+
204
+ ## 0.1.0a13 - 2026-08-08
205
+
206
+ - Breaking: `Identity.username` now removes surrounding whitespace and rejects values that become empty.
207
+ - Keeps `ByteRange` typed through the transport adapter and closes the underlying HTTPX2 response when download reads
208
+ or iteration finish or fail, while retaining explicit `DownloadStream.aclose()` for deferred framework consumers.
209
+ - Consolidates Provider session validation through the public `Session` models and simplifies private wire-rule and
210
+ token-refresh validation without changing the pinned Integration Contract.
211
+
212
+ ## 0.1.0a12 - 2026-08-07
213
+
214
+ - Breaking: removes `MatelabAttachmentValidationError`; local attachment size and checksum mismatches now use the
215
+ existing `MatelabUsageError` without a separate reason/value interface.
216
+ - Adopts immutable `matelab-spec v0.4.0` at commit `7993a7bccc213f626b9cc8124423e2b2c9e48dd7` and OpenAPI
217
+ SHA-256 `e725c9649700d5b4d1c7d75fb9422d64b04a68e0308ddec29ba274d774104c8e`. Fixed response models now
218
+ accept but ignore additive Provider fields; only the Contract's seven semantically open models preserve them.
219
+ - Breaking: removes the unused `StagedUploadSession.new()` constructor and the caller-echoed
220
+ `StagedFileFragment.fragment_size` field. `uploads.stage()` now owns fresh-session creation while retaining explicit
221
+ restored sessions, automatic single-`bytes` checksums, and required complete checksums for resumed final fragments.
222
+ - Breaking: removes untyped pass-through attributes from cloud-drive results, literature schema fields, and extracted
223
+ literature authors. Unknown response fields remain parse-compatible but are ignored unless the Contract defines an
224
+ open data shape. Template publication reasons now use only the Contract-declared Provider key.
225
+
226
+ ## 0.1.0a11 - 2026-08-05
227
+
228
+ - Adds `AsyncIterable[bytes]` support to the three complete record-attachment upload interfaces without adding new
229
+ methods. Async content is spooled, size/checksum validated, rewound, and cleaned up without blocking the event loop;
230
+ `sha256` may now be omitted and computed by the SDK.
231
+ - Adds structured `MatelabAttachmentValidationError` reasons and expected/actual values so integrations can distinguish
232
+ size and checksum failures without parsing exception text. Validation failures occur before Provider staging, while
233
+ source exceptions propagate unchanged.
234
+
235
+ ## 0.1.0a10 - 2026-08-05
236
+
237
+ - Keeps synchronous multipart file length probes and chunk reads off the event-loop thread while preserving streamed
238
+ uploads, correct content length, the bytes fast path, and existing non-replay retry restrictions.
239
+ - Replaces implicit-override suppressions with explicit `@override` declarations, simplifies inferred model attributes,
240
+ and declares the Python 3.11 `typing-extensions` runtime dependency directly.
241
+
242
+ ## 0.1.0a9 - 2026-08-04
243
+
244
+ - Breaking: removes `MatelabProviderErrorKind` and `MatelabProviderError.kind`; Provider wire codes now map directly
245
+ to the final `MatelabErrorCategory`, which integrations consume through `MatelabError.category`. This public API
246
+ removal requires a subsequent SemVer-appropriate release before distribution. Operation-specific code `0`/`10`
247
+ success handling and the bounded code `5` authentication refresh remain unchanged.
248
+ - Adds a conservative `retryable` flag to every public SDK error.
249
+
250
+ ## 0.1.0a8 - 2026-08-04
251
+
252
+ - Adds a unified `MatelabErrorCategory` and conservative `retryable` flag to every public SDK error, centralizing
253
+ Provider error semantics so integrations no longer reinterpret `MatelabProviderErrorKind`.
254
+
255
+ ## 0.1.0a7 - 2026-08-04
256
+
257
+ - Replaces the hand-maintained wire-validation rule tables with deterministic generated JSON Schema 2020-12 rules.
258
+ - Simplifies transport, streaming, error mapping, and domain adapters while retaining the pinned `matelab-spec v0.3.0`
259
+ behavior and automatic Session refresh guarantees.
260
+ - Breaking: tightens several public domain inputs and results, and exposes stable `MatelabProviderErrorKind` values
261
+ instead of raw Provider error codes.
262
+ - Removes completed roadmap and work-package bookkeeping; refreshes release checks, documentation, and tests.
263
+
264
+ ## 0.1.0a6 - 2026-08-01
265
+
266
+ - Adopts the immutable `matelab-spec v0.3.0` Contract release and its form-encoding updates.
267
+ - Tightens the public authentication/session contract around complete, serializable Pydantic `Session` models while
268
+ retaining automatic access-token refresh and Provider SSO exchange.
269
+ - Simplifies transport and domain interfaces, removes external-token binding and identity-attachment seams, and
270
+ restores strict runtime validation for byte-range inputs.
271
+
272
+ ## 0.1.0a5 - 2026-07-29
273
+
274
+ - Adopts immutable `matelab-spec v0.1.2` at commit `6dd674ac001ae61197495ace5eba489d585cb825` and OpenAPI
275
+ SHA-256 `7ccaf3116c8dcec7a6e49ff51fb1a5ecc83a140e013ec600516f5c2ffb3b5378`.
276
+ - Adds notebook-scoped staged finalizers for a null table file cell, an attachment-bearing appended table row,
277
+ files-module root append, and table/files occurrence replacement, with exact provenance, one-shot transport, and
278
+ canonical readback checks.
279
+ - Adds typed intents for an empty file table column and complete form file-field/table file-column deletion.
280
+ - Allows `records.update(..., module_deletions=...)` to delete a canonical module even when the current record read
281
+ observes attachments in it, verifies absence on persisted readback, and does not claim attachment-quote or byte
282
+ cleanup beyond the pinned Contract.
283
+ - Rejects cross-scope staged attachment handles before the record read, preserving the public static types while
284
+ avoiding the Provider's read-audit side effect for invalid runtime input.
285
+ - Keeps notebook-staged rich-text binding and attachment-bearing multi-record import explicitly unsupported because
286
+ v0.1.2 Provider Verification does not provide safe one-shot semantics for either.
287
+
288
+ ## 0.1.0a4 - 2026-07-28
289
+
290
+ - Further reduces the alpha public surface from 150 to 126 symbols by accepting direct keyword arguments and existing
291
+ domain values instead of request-shaped wrapper dataclasses.
292
+ - Centralizes safe request-model validation, strengthens generated Contract constraints, and preserves structured field
293
+ diagnostics without exposing credentials, tokens, or sensitive payload values.
294
+ - Tightens Session replacement, refresh races, multipart retry safety, streaming cleanup, and exact HTTP success
295
+ handling while retaining stable transport, authentication, Provider, protocol, usage, and verification errors.
296
+ - Collects all business capabilities under `matelab.domains`, keeps client/session/error/transport primitives at the
297
+ package root, and hardens generation and release-artifact audits.
298
+
299
+ ## 0.1.0a3 - 2026-07-28
300
+
301
+ - Replaces HTTPX with HTTPX2 2.9.1 and raises the Pydantic compatibility floor to 2.13.4. Injected clients must now
302
+ be `httpx2.AsyncClient` instances; HTTPX and HTTPX2 objects are not interchangeable. Default TLS verification now
303
+ uses the operating system trust store.
304
+ - Shrinks the alpha public surface from 184 to 150 symbols by returning existing domain values, tuples, booleans, or
305
+ `None` from simple mutations instead of defining endpoint-shaped result dataclasses. Contract invariants remain
306
+ documented operation semantics rather than repeated constant fields.
307
+ - Reorganizes the record and literature implementations into domain packages and keeps generated wire imports behind
308
+ one private namespace without changing the generated-model boundary.
309
+ - Aligns the opt-in SDK Provider smoke with the isolated test service's shared `MATELAB_PROVIDER_*` environment
310
+ variables and adds a safe `.env.example`.
311
+
312
+ ## 0.1.0a2 - 2026-07-27
313
+
314
+ - Adopts the immutable `matelab-spec v0.1.1` release.
315
+ - Adds notebook-scoped, uploader-bound record attachment staging before a target record exists.
316
+ - Finalizes staged attachments through a single-record import or one new form-file-field update without exposing
317
+ Provider-native attachment syntax or private transport details.
318
+ - Enforces exact notebook/user provenance and one finalization attempt per staged handle in one SDK client.
319
+
320
+ ## 0.1.0a1 - 2026-07-27
321
+
322
+ First public alpha candidate of the asynchronous Matelab Integration Contract SDK.
323
+
324
+ - Binds the immutable `matelab-spec v0.1.0` release.
325
+ - Exposes all 71 pinned Contract operations through public domain interfaces: 15 are stable and 56 remain
326
+ experimental.
327
+ - Provides instance-owned immutable Sessions, bounded token refresh, typed public models, streaming downloads,
328
+ and generated private wire validation.
329
+ - Ships as a typed package for Python 3.11 through 3.14.
330
+ - Uses the Apache License 2.0 with PEP 639 package metadata.
@@ -0,0 +1,91 @@
1
+ # Matelab SDK Domain Language
2
+
3
+ This glossary distinguishes public domain concepts whose names would otherwise be easy to conflate.
4
+
5
+ ## Templates
6
+
7
+ **Template ref**:
8
+ The Provider database identity of one template, independent of how it appears in a user's or group's library.
9
+ _Avoid_: Template library entry ref
10
+
11
+ **Template library entry ref**:
12
+ The relation-row identity for a template in either the authenticated user's library or a group library. User-library
13
+ and group-library relation IDs belong to different identity spaces and select different removal operations.
14
+ _Avoid_: Template ref, template ID
15
+
16
+ **Template scope**:
17
+ How the caller can access a template: owned, directly shared, through a group, or public. A public template's optional
18
+ user-library relation indicates whether the caller acquired it; marketplace review is separate state, not a scope.
19
+ _Avoid_: Template source ID, library relation kind
20
+
21
+ **Template module**:
22
+ One canonical Provider content module. Additive properties and the missing-versus-null `data` distinction are
23
+ preserved across read/save; frontend editor defaults and Agent editing intents are not part of this model.
24
+ _Avoid_: Template document, UI module
25
+
26
+ ## Literature
27
+
28
+ **Literature metadata input**:
29
+ A complete canonical set of bibliographic values proposed for creating or replacing a literature item.
30
+ _Avoid_: Stored metadata, metadata snapshot
31
+
32
+ **Stored literature metadata**:
33
+ The bibliographic values currently stored for a literature item, including readable values that may not be accepted in
34
+ a canonical replacement.
35
+ _Avoid_: Metadata input, update payload
36
+
37
+ **Publication metadata candidate**:
38
+ Unstored bibliographic evidence extracted from a DOI or publication file for review and possible reuse.
39
+ _Avoid_: Stored metadata, canonical metadata
40
+
41
+ **Publication author candidate**:
42
+ A structured author candidate supplied by publication metadata extraction.
43
+ _Avoid_: Literature author text
44
+
45
+ **Literature author text**:
46
+ A single textual representation of a literature item's authors, whether it has one author or many.
47
+ _Avoid_: Authors array, author list
48
+
49
+ **Literature keyword**:
50
+ A bibliographic subject term describing a literature item, independent of any library that contains the item.
51
+ _Avoid_: Tag, library keyword
52
+
53
+ **Literature tag**:
54
+ A classification label associated with a literature item within a particular library. A library's tag set is the
55
+ aggregate of its item tags.
56
+ _Avoid_: Keyword, item keyword, library keyword
57
+
58
+ ## Records
59
+
60
+ **Record ref**:
61
+ The Provider database row identity and UID of one active or deleted record, without notebook context.
62
+ _Avoid_: Record locator, public record ref, deleted record ref
63
+
64
+ **Record locator**:
65
+ A record ref paired with the owned or shared notebook in which it was observed. It is the complete source identity
66
+ used by record reads and record-scoped operations.
67
+ _Avoid_: Record ref, notebook ID
68
+
69
+ **Record version ref**:
70
+ A historical version ID bound to its record locator. It identifies observed historical content, not a separate active
71
+ record.
72
+ _Avoid_: Record ref, current version number
73
+
74
+ **Record relation ref**:
75
+ An observed relation-row ID and its declared target notebook/record IDs. The source locator is supplied separately to
76
+ relation deletion; nullable joined target previews and resolved identities remain wire-only.
77
+ _Avoid_: Relation summary, target record locator
78
+
79
+ **Record folder**:
80
+ A notebook-scoped hierarchical container used to organize records. Records at the notebook root have no folder.
81
+ _Avoid_: Subtype, record type, template
82
+
83
+ **Record import value**:
84
+ A template-shaped value composed of JSON-compatible scalars and containers, with a staged attachment
85
+ allowed wherever the template expects a file.
86
+ _Avoid_: Arbitrary object, stored record module, Provider attachment reference
87
+
88
+ **Staged attachment**:
89
+ An upload prepared in a selected notebook for one later record import or update; uploading does not choose the target
90
+ record.
91
+ _Avoid_: Import attachment, record-scoped upload, stored attachment, attachment ref