Repository navigation
Commit ceef714
fix(spec): a connector read serves only the declared nested keys, and a save of the served form keeps the rest (#28997)
domain:server#2 · os-project-manager · session_0186vfjHHMsRXC9EUT9hTFMo
<!-- claude-projects-attribution: {"github_login":"os-project-manager"}
-->
_Requested by **Leehom** · [project
thread](https://claude.ai/code/project/chan_01TenzsRopZj4jMbvjX8uz1X?thread=cmsg_01TenzsRopZj4jMbvjX8uz1X1zG3Xn4JonaKvDLLr5gnjL)_
Refs #28284
Clause-②: no
Metadata-protocol: none
## 维护者速读
- **改了什么**:读取 connector 时,`retryConfig` 里和 `actions` 每个元素里只返回各自 schema
声明过的键,其余整键不返回;形状不对的 `retryConfig` / `actions`
整体不返回;库里的行不变。原样保存时这些值从库里带回不丢;`actions` 元素按 `key` 对应,重排也不串位;作者删掉
`retryConfig` 或某个 action 时才删。`getPublished`
对作者文档脱敏,元数据层的标量记账键原样返回,多次发布留下的嵌套快照同样逐层脱敏。
- **为什么改**:QA 第三轮发现的安全加固(细节按披露裁决不公开)
- **风险与回滚**:spec / metadata-protocol / metadata 三个
patch。保存接受什么不变。连带变化:carry-forward 中没有 `id` 的数组元素现在按 `key` 识别(目前只有
connector 的 action 有这种形状)。回滚即 revert 本 PR。
-
**先看**:`packages/spec/src/integration/connector-credential-redaction.ts`(模块说明第
8 项与 `undeclaredNestedKeysOf`) →
`packages/metadata-protocol/src/metadata-redaction.ts` 的 `identityOf` →
`packages/metadata/src/metadata-manager.ts` 的 `redactServedBody`。
- **两分钟验证**:`pnpm --filter @objectstack/spec exec vitest run
src/integration/connector-credential-redaction.test.ts`,预期 52 passed。
- **需要你做的**:无,席位做 contract review 后落地。
## What changes
- **Connector read, nested shapes.** Inside `retryConfig` and inside
each `actions` element, every metadata read exit serves only the keys
`RetryConfigSchema` and `ConnectorActionSchema` declare. The declared
sets are read from the schemas' own shapes. Each withheld position is
named in `redactedKeys` (`retryConfig.<key>`, `actions.<index>.<key>`).
A `retryConfig` that is not an object, and an `actions` that is not an
array or holds an element that is not an object, are withheld whole and
named by the container (a cleared form and an empty list are served as
written; an element is never removed on its own). The stored row is
never changed.
- **Carry-forward follows an action by its `key`.** `identityOf` in the
protocol's carry-forward returns `id` when present, and otherwise a
non-empty string `key`. A reordered `actions` list keeps each element's
withheld value on that element; twin keys carry neither, the existing
ambiguity rule. A removed `retryConfig` or element is not minted back.
- **`MetadataManager.getPublished`** hands the type's redactor the
authored document alone, and serves the metadata layer's own scalar
bookkeeping (`packageId`, `state`, the publish keys) beside the answer
unchanged. A publish snapshot nested under `publishedDefinition` (a
package published more than once) is served through the same redaction
at every depth; any other bookkeeping value that is not a scalar is not
served. A body with nothing to withhold at any depth is served as
before.
Nothing an author can write changes; no public export changes.
## Why
QA 第三轮发现的安全加固(细节按披露裁决不公开)
## Verification
Every reading below is on head `8daa64f1` (two commits on `main` at
`3ac22c9d`) unless it names `1fed7aac`, the first commit.
<details><summary>Package suites and typecheck</summary>
- `pnpm --filter @objectstack/spec test`: 23335 passed, 1 todo.
`typecheck` exit 0.
- `pnpm --filter @objectstack/metadata-protocol test`: 22113 passed, 26
skipped. `typecheck` exit 0.
- `pnpm --filter @objectstack/metadata test`: 929 passed. `typecheck`
exit 0.
- `@objectstack/dogfood` `typecheck` exit 0. The connector door file
reads 9 passed (`--maxWorkers=1`, under the verify lock).
- Whole dogfood battery (`pnpm --filter @objectstack/dogfood exec vitest
run --maxWorkers=1`, under the verify lock): on `1fed7aac`, 384 files
passed, 3 skipped, 3171 tests passed, exit 0. On `8daa64f1`: NOT
MEASURED. The run was still in progress when work stopped; CI's Dogfood
Regression Gate is green on this head.
- `pnpm --filter @objectstack/spec check:generated`: exit 0 (on
`1fed7aac`; the second commit moves no schema).
- CI on this head: Test Core (8 shards), Type Check (debt ledger
included), Lint, Check Changeset, Dogfood Regression Gate all green; no
red.
</details>
<details><summary>New tests</summary>
-
`packages/spec/src/integration/connector-credential-redaction.test.ts`:
nested keys withheld under `retryConfig` and per `actions` element;
cleared values; the declared nested sets equal the schemas' shapes; a
malformed `retryConfig` or `actions` withheld whole (four shapes) with
the cleared-form control; input never mutated. The file reads 52 passed.
-
`packages/metadata-protocol/src/metadata-redaction.connector-undeclared-keys.test.ts`
(7): the served form withholds the keys (control); a served-form save
keeps every value; a reordered `actions` list follows each element by
`key`; the author's own value wins; a removed `retryConfig` or element
is not minted back; twin keys carry neither; a malformed container
withheld whole is kept at rest by a save of the served form.
- `packages/metadata/src/published-body-bookkeeping-redaction.test.ts`
(5): a never-published row and a published snapshot keep their scalar
bookkeeping beside the redacted answer; a package published twice is
redacted at every depth; a non-scalar bookkeeping value that is not a
snapshot is not served; a clean body is served as stored.
-
`packages/qa/dogfood/test/connector-meta-door-undeclared-keys-withheld.dogfood.test.ts`
(9): the HTTP read doors (item, `/layers`, `/published`, both list
spellings) for a member and an administrator, plus the published read of
a package published twice; served-form saves keep the values at rest,
including a reordered `actions` list; a removed `retryConfig` is
cleared. CONTROL: a `credentialRef` instance saves, reaches ready and
dispatches.
</details>
<details><summary>Ablation (rebuilt, proved on disk)</summary>
Markers use the `String('…').length` form so the build cannot fold them.
`scripts/ablation-dist-preflight.mjs` ran on each package.
| Fix ablated | Head | Result while ablated |
|:---|:---|:---|
| all three (nested withholding, `key` identity, bookkeeping peel) |
`1fed7aac` | spec 3 failed / 48 · metadata-protocol 2 failed / 6 ·
metadata 3 failed / 3 · dogfood 2 failed / 8 |
| `key` identity alone | `1fed7aac` | metadata-protocol 2 failed / 6
(served-form save, reorder) · dogfood 1 failed / 8 (reorder) |
| `getPublished` at every depth (`metadata-manager.ts` set back to its
`1fed7aac` blob) | `8daa64f1` | metadata 2 failed / 5 (published twice;
non-scalar bookkeeping) · dogfood 1 failed / 9 (published twice) |
Restore leg each time: blob equals HEAD, `git diff HEAD` empty, rebuild
exit 0, and the same files green again (the first two legs also read the
marker absent from every built file: spec 588, metadata-protocol 24,
metadata 42).
</details>
<details><summary>Derived gate families</summary>
`node scripts/pm/dispatch-gates.mjs --commands` on `8daa64f1` derives 81
families. 80 ran locally, each with exit 0. `check:type-check-debt` is
NOT MEASURED locally: it queued behind the dogfood hold on the verify
lock and timed out (exit 99) before it got a turn. Its CI family, Type
Check · debt ledger, is green on this head. The `--ran` reconciliation
reads 81 derived, 80 run, 1 NOT-MEASURED. Repo-wide scans (`pnpm lint`
and the rest of the lint workflow) are left to CI.
</details>
## Human Minimum
- [x] 1. Schemas start as Zod; `packages/spec` holds no runtime logic
beyond the existing read-path redactor module this extends.
- [x] 2. Every name I added uses the casing for its kind.
- [x] 3. No formatter ran; `pnpm lint` is left to CI.
- [x] 4. One branch off an up-to-date `main`, one pull request (no
issue: `Refs #28284`).
- [x] 5. Changeset present; both declaration lines are filled in here
and in the changeset.
- [x] 6. `packages/spec` touched: `check:generated` reads every
generated artifact up to date (no schema changed).
- [x] 7. No hand edits to `content/docs/references/`,
`packages/*/CHANGELOG.md` or `content/docs/releases/`.
- [x] 8. Title and body sections other than the maintainer brief are in
English.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01FEkQ5mgePB9NQ4PNhvYVxk
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent fea2dbb commit ceef714
8 files changed
Lines changed: 695 additions & 19 deletions
File tree
- .changeset
- packages
- metadata-protocol/src
- metadata/src
- qa/dogfood/test
- spec/src/integration
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
151 | 151 | | |
152 | 152 | | |
153 | 153 | | |
154 | | - | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
155 | 159 | | |
156 | 160 | | |
157 | 161 | | |
158 | | - | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
159 | 165 | | |
160 | 166 | | |
161 | 167 | | |
| |||
190 | 196 | | |
191 | 197 | | |
192 | 198 | | |
193 | | - | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
194 | 202 | | |
195 | 203 | | |
196 | 204 | | |
| |||
201 | 209 | | |
202 | 210 | | |
203 | 211 | | |
204 | | - | |
205 | | - | |
| 212 | + | |
| 213 | + | |
206 | 214 | | |
207 | 215 | | |
208 | 216 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
87 | 87 | | |
88 | 88 | | |
89 | 89 | | |
90 | | - | |
| 90 | + | |
91 | 91 | | |
92 | 92 | | |
93 | 93 | | |
| |||
333 | 333 | | |
334 | 334 | | |
335 | 335 | | |
| 336 | + | |
| 337 | + | |
| 338 | + | |
| 339 | + | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
336 | 368 | | |
337 | 369 | | |
338 | 370 | | |
| |||
2285 | 2317 | | |
2286 | 2318 | | |
2287 | 2319 | | |
2288 | | - | |
| 2320 | + | |
| 2321 | + | |
| 2322 | + | |
| 2323 | + | |
| 2324 | + | |
| 2325 | + | |
| 2326 | + | |
| 2327 | + | |
| 2328 | + | |
| 2329 | + | |
| 2330 | + | |
| 2331 | + | |
| 2332 | + | |
| 2333 | + | |
| 2334 | + | |
| 2335 | + | |
| 2336 | + | |
| 2337 | + | |
2289 | 2338 | | |
2290 | 2339 | | |
2291 | 2340 | | |
2292 | 2341 | | |
2293 | 2342 | | |
2294 | | - | |
2295 | | - | |
| 2343 | + | |
2296 | 2344 | | |
2297 | 2345 | | |
2298 | 2346 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
0 commit comments