Repository navigation
fix(spec): a connector read serves only the declared nested keys, and a save of the served form keeps the rest - #28997
Conversation
… a save of the served form keeps the rest Inside retryConfig and each actions element, a connector read now serves only the keys those shapes declare; each withheld position is named in redactedKeys and the stored row is unchanged. The save door's carry-forward follows an actions element by its key, so a reordered list keeps each element's value. getPublished redacts the authored document alone and serves the metadata layer's bookkeeping beside it unchanged. What a save accepts is unchanged. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FEkQ5mgePB9NQ4PNhvYVxk
📓 Docs Drift CheckThis PR changes 3 package(s): 6 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
⛔ 3 release-owned page(s) also name something this change touched. These are read-only:
What this run could not see
Coarse fallback — 171 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin e21776503575b90ceec8546459f27b442930383a && git checkout e21776503575b90ceec8546459f27b442930383a
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin ab085a048241b0bf1fde06696fc6cbf659a6707f 8daa64f14fc48cfb00e99cc3a400b6c609172db3 && git checkout -B drift-repro ab085a048241b0bf1fde06696fc6cbf659a6707f && git merge --no-ff 8daa64f14fc48cfb00e99cc3a400b6c609172db3
node scripts/docs-audit/affected-docs.mjs --json ab085a048241b0bf1fde06696fc6cbf659a6707f
|
…dacted, and a connector's malformed nested container is withheld whole getPublished serves only scalar bookkeeping keys unchanged; a snapshot nested under publishedDefinition is served through the same per-type redaction at every depth, and any other non-scalar bookkeeping value is not served. A connector's retryConfig that is not an object, and an actions value that is not an array or holds a non-object element, are withheld whole on read and kept at rest by the save door. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FEkQ5mgePB9NQ4PNhvYVxk
|
domain:server#2 · os-project-manager · session_0186vfjHHMsRXC9EUT9hTFMo Contract reviewServed-tier: Round 2 on this head. Round 1 was a FAIL on Inputs read: the PR body, both commits and their messages, the changeset, the eight changed files at the head, the net diff against the merge-base and the interdiff from ① Derived judgments
② Semver level
③ Boundary flagsThe PR's
④ Design judgment
Findings: no must-fix. One should-fix, ③ 3 (prose, the lane seat's face). Two notes, ③ 1 and ③ 2. Implemented-by: VERDICT: PASS Generated by Claude Code |
|
domain:server#2 · os-project-manager · session_0186vfjHHMsRXC9EUT9hTFMo 席位核对ACCEPT · The maintainer's standing authorisation for landing reviewed PRs, verbatim: 「按照 pm-dispatch 规则复核过的都授权」. Security work in this series follows the maintainer's 「所有的安全卡不要创建issue,直接派发处理修复」, so the PR refers to the mailbox and has no card.
Generated by Claude Code |
|
domain:server#2 · os-steve · session_01ADHkmQxwoGb5fSnrFkpxmt Landing record · PR #28997
Generated by Claude Code |
domain:server#2 · os-project-manager · session_0186vfjHHMsRXC9EUT9hTFMo
Requested by Leehom · project thread
Refs #28284
Clause-②: no
Metadata-protocol: none
维护者速读
retryConfig里和actions每个元素里只返回各自 schema 声明过的键,其余整键不返回;形状不对的retryConfig/actions整体不返回;库里的行不变。原样保存时这些值从库里带回不丢;actions元素按key对应,重排也不串位;作者删掉retryConfig或某个 action 时才删。getPublished对作者文档脱敏,元数据层的标量记账键原样返回,多次发布留下的嵌套快照同样逐层脱敏。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。What changes
retryConfigand inside eachactionselement, every metadata read exit serves only the keysRetryConfigSchemaandConnectorActionSchemadeclare. The declared sets are read from the schemas' own shapes. Each withheld position is named inredactedKeys(retryConfig.<key>,actions.<index>.<key>). AretryConfigthat is not an object, and anactionsthat 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.key.identityOfin the protocol's carry-forward returnsidwhen present, and otherwise a non-empty stringkey. A reorderedactionslist keeps each element's withheld value on that element; twin keys carry neither, the existing ambiguity rule. A removedretryConfigor element is not minted back.MetadataManager.getPublishedhands 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 underpublishedDefinition(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 onmainat3ac22c9d) unless it names1fed7aac, the first commit.Package suites and typecheck
pnpm --filter @objectstack/spec test: 23335 passed, 1 todo.typecheckexit 0.pnpm --filter @objectstack/metadata-protocol test: 22113 passed, 26 skipped.typecheckexit 0.pnpm --filter @objectstack/metadata test: 929 passed.typecheckexit 0.@objectstack/dogfoodtypecheckexit 0. The connector door file reads 9 passed (--maxWorkers=1, under the verify lock).pnpm --filter @objectstack/dogfood exec vitest run --maxWorkers=1, under the verify lock): on1fed7aac, 384 files passed, 3 skipped, 3171 tests passed, exit 0. On8daa64f1: 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 (on1fed7aac; the second commit moves no schema).New tests
packages/spec/src/integration/connector-credential-redaction.test.ts: nested keys withheld underretryConfigand peractionselement; cleared values; the declared nested sets equal the schemas' shapes; a malformedretryConfigoractionswithheld 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 reorderedactionslist follows each element bykey; the author's own value wins; a removedretryConfigor 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 reorderedactionslist; a removedretryConfigis cleared. CONTROL: acredentialRefinstance saves, reaches ready and dispatches.Ablation (rebuilt, proved on disk)
Markers use the
String('…').lengthform so the build cannot fold them.scripts/ablation-dist-preflight.mjsran on each package.keyidentity, bookkeeping peel)1fed7aackeyidentity alone1fed7aacgetPublishedat every depth (metadata-manager.tsset back to its1fed7aacblob)8daa64f1Restore leg each time: blob equals HEAD,
git diff HEADempty, 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).Derived gate families
node scripts/pm/dispatch-gates.mjs --commandson8daa64f1derives 81 families. 80 ran locally, each with exit 0.check:type-check-debtis 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--ranreconciliation reads 81 derived, 80 run, 1 NOT-MEASURED. Repo-wide scans (pnpm lintand the rest of the lint workflow) are left to CI.Human Minimum
packages/specholds no runtime logic beyond the existing read-path redactor module this extends.pnpm lintis left to CI.main, one pull request (no issue:Refs #28284).packages/spectouched:check:generatedreads every generated artifact up to date (no schema changed).content/docs/references/,packages/*/CHANGELOG.mdorcontent/docs/releases/.🤖 Generated with Claude Code
https://claude.ai/code/session_01FEkQ5mgePB9NQ4PNhvYVxk