Repository navigation
refactor(plugin-security): move SecurityPlugin's controlled-by-parent master relation into security-plugin-cbp-relation.ts (#25223 cut 2) - #25310
Conversation
… read derivation into security-plugin-cbp-read.ts (wip) The bodies of five private methods (the ADR-0055 master relation, its two reports, the read leaf and the chain refusal) move unedited, re-indented one level, with CBP_LEAF_READ_VERBS and masterNotWritableRefusal, which only they read. The class keeps every method, its signature and docblock, and hands each body a host literal of exactly the members it reads. CBP_MAX_CHAIN_DEPTH stays where ADR-0055 anchors it and is exported for the module to import. The new module gets its own ADR-0055 anchor entry. Claude-Session: https://claude.ai/code/session_017BoLT8Gaa8t9a7AWVH8qZa Co-authored-by: Claude <noreply@anthropic.com>
…aster relation Ruling 6353073966 (letter A): cut 2 moves only resolveCbpRelation and its two reports, reportCbpMasterUnresolved and reportRejectedReferenceAlias, into security-plugin-cbp-relation.ts, with masterNotWritableRefusal and the two imports only it reads. computeControlledByParentFilter, controlledByParentChainRefusal, CBP_LEAF_READ_VERBS and CBP_MAX_CHAIN_DEPTH stay in security-plugin.ts byte for byte, because ADR-0055:26 #sharingModel and ADR-0055:58 #controlled_by_parent resolve only on tokens inside those two bodies. The module imports the class type-only, and security-plugin.ts gains no export. The adr-anchors entry follows the module's new name. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BoLT8Gaa8t9a7AWVH8qZa
📓 Docs Drift CheckThis PR changes 1 package(s): 15 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
⛔ 8 release-owned page(s) also name something this change touched. These are read-only:
What this run could not see
Coarse fallback — 16 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 b54819b8453ddb38421eb300f297f58448fdc73a && git checkout b54819b8453ddb38421eb300f297f58448fdc73a
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 09e07c259a633eb02fdb29bedfe911e808529f88 4c92fe8165dbea94721b01c5c269f3cca044da4a && git checkout -B drift-repro 09e07c259a633eb02fdb29bedfe911e808529f88 && git merge --no-ff 4c92fe8165dbea94721b01c5c269f3cca044da4a
node scripts/docs-audit/affected-docs.mjs --json 09e07c259a633eb02fdb29bedfe911e808529f88
|
席位核对 · ACCEPT · 2026-10-22T23:38Z
Generated by Claude Code |
Requested by Sales · project thread
Part of #25223
Clause-②: no
Metadata-protocol: none
Ruling-ref: 6353073966
Cut 2 of the
security-plugin.tssplit, as ruled in 6353073966 (letter A, narrowed). The bodies ofresolveCbpRelationand its two loud reports,reportCbpMasterUnresolvedandreportRejectedReferenceAlias, move unedited to the new modulepackages/plugins/plugin-security/src/security-plugin-cbp-relation.ts. Together they are the ADR-0055 §1 derivation of the one master acontrolled_by_parentobject takes its access from. The one module-level declaration only those bodies read,masterNotWritableRefusal, moves with them, and so do the two imports only it used.It is move-only, and the card stays open for the later cuts. The amended claim is 6353132374. It supersedes the five-body claim 6352049267, whose head made
check-adr-symbol-anchorsexit 1. Branch:claude/project-thread-3fzya4, the harness-pinned branch for this session. It names no issue, so the claim comment is the identity record. The branch carries the withdrawn five-body commit and then the narrowing commit, and the PR's diff against its merge base5801a4f2cis the narrowed cut alone.Two bodies stay in
security-plugin.tsbyte for byte, by the ruling's item 1: the read leafcomputeControlledByParentFilterand its chain refusalcontrolledByParentChainRefusal. So doCBP_LEAF_READ_VERBS,CBP_MAX_CHAIN_DEPTH,CbpRelationand every import they read. ADR-0055:26#sharingModeland ADR-0055:58#controlled_by_parentresolve only on tokens inside those two bodies. They move only after a separate Tier H docs PR repoints those anchors (ruling items 3 and 4).The published
.d.tsdoes not changeUnder the series bar (ruling 6348891160 item 1), measured on base
5801a4f2and on the narrowed head (the tree of the commit this PR adds):dist/index.d.tsanddist/index.d.mts, base and head, all four the same:803f5bfb7da0b00f8cd8d8f25172463d8dfb07d93fbdd8a9c6f4d4b7435e429a. The raw diff is 0 lines, so no union order moved either.b6b5c1b7fa6fa188f6e2f7e4cca3816a246b570f20d708643d116012aa86fa77.packages/plugins/plugin-security(it sorts the members of each string-literal union and changes nothing else):dist/index.d.ts, line 1870 (private resolveCbpRelation;):resolveCbpRelation;): raw1ff696eaab36c50ffffb459dc4a323a7b32fea15a9bd06d8cac43967ec92ac24, normalised41486774e365f562d279585cb6b64e282b783b7ae822bb19ef41d434a89d7a12.private resolveCbpRelationRenamed;): raw307edbdd465438d1ab2c5bcbf12d10854c3f8a4179ab90b49d065282ba6ec2ec, normalised5cb31db9affddd093d0068889eaef49ed684a9ab499ce213a3a77d9ebcd159ce.f607fd765d6b277e08b3b46ccb16d1e2d133ec55658ffe40155aef25e1bf54f0on all four.index.js68f4e3a8to6d2a398f,index.mjs1f24e6d5to953c5d9a), because code moved within them.No changeset:
skip-changeset, per ruling 6348891160 item 4.What moved
Base line numbers are each method's signature at
5801a4f2. The last column lists the members the body reads, which is exactly what its host carries.resolveCbpRelation:8884-:8985cbpRelCache,ql,reportCbpMasterUnresolved,reportRejectedReferenceAliasreportCbpMasterUnresolved:9007-:9042loggerreportRejectedReferenceAlias:9094-:9114loggermasterNotWritableRefusal(base:727-:737, with its docblock) moves too;resolveCbpRelationis its only reader. So do the two imports only it reads,controlledByParentMasterRefusal(with its two-line comment) andOWD_DELEGATING_ROW_WRITES.The shape (#23050 shape B, as cut 1 applied it)
.d.ts. Each body is now one host literal plusfn.call(host, …), marked[#25223 cut 2].CbpRelationHosttypes every member as the class member itself (SecurityPlugin['m']). Each moved function types itsthisas thePickof the host over exactly the members its body reads, and each stub annotates its literal with the samePick. There is no cast, and no member becomes public or protected.SecurityPlugintype-only, so there is no runtime import cycle, andsecurity-plugin.tsgains no export.CbpRelationis named in the module through the class's own signature (an alias over the non-null return type ofSecurityPlugin['resolveCbpRelation']), so the interface keeps its one declaration besidecbpRelCacheand the consumers that read it.this.m(...a)on the plugin at call time. A spy or test double set on the plugin is still the one the derivation reaches. No moved body calls a function-valued field, so no receiver changes.ql,loggerandcbpRelCachego as getters, because none is declaredreadonly.start()assignsqlandloggerafter construction, and the metadata watch clearscbpRelCachein place. The host declares every fieldreadonly, so a moved body cannot assign a member through it; the typecheck passes, so none does.async. Nothing re-exports the module, so the package entry does not move.Proof of move-only
asyncmatch. A negative control,candidates.length === 1changed to=== 2inresolveCbpRelation, fails the check.masterNotWritableRefusalis verbatim (11 lines) in the module and absent fromsecurity-plugin.ts.computeControlledByParentFilter,controlledByParentChainRefusal(docblock to closing brace),CBP_LEAF_READ_VERBSandCBP_MAX_CHAIN_DEPTH(docblock included) are byte-identical to base.git diff --color-moved=plain --color-moved-ws=allow-indentation-change 5801a4f2 HEADover the two source files): 158 of 159 deleted lines and 178 of 283 added lines are detected as moved.OWD_DELEGATING_ROW_WRITES,, taken out of a multi-name import. It is re-imported in the module besidemasterGovernsRowWrites.CbpRelationalias,CbpRelationHost, one pointer docblock per function and the rewritten signature heads. The rest are lines git does not pair with a moved block, such as blanks and closing braces.security-plugin.tsgoes from 10,952 to 10,823 lines.ADR anchors (ruling 6353073966 item 2)
node scripts/check-adr-symbol-anchors.mjs: exit 0 at base5801a4f2and exit 0 at head, both with2383 anchors across 142 records resolve — 467 symbol (440 declaration, 27 literal), 1888 file-level, 28 cross-repo, 6 exempt, 18 continuation. CI runs this gate (lint.yml), butdispatch-gates --commandsdoes not derive it for this change set, so it is run by hand here.pnpm check:adr-anchors: exit 0, 76 anchored files (75 at base, plus the new entry). The new entry isscripts/adr-anchors/packages__plugins__plugin-security__src__security-plugin-cbp-relation.ts.json, carrying ADR-0055 and the §1 invariant paragraph of thesecurity-plugin.tsentry, verbatim. That paragraph describes the master derivation, which now lives in the new module. Thesecurity-plugin.tsentry is unchanged, because the methods, their docblocks and both consumers of the derivation remain in that file.docs/adr/**is not touched.security-plugin.ts: 28 anchors, 20 symbols, 10 ADRs. It was measured withextractAnchorsandsymbolSegmentResolutionfromscripts/symbol-anchors.mjs, which is measurement, not a new gate. Base lines are at5801a4f2. Every anchor resolves at head insecurity-plugin.tswith its base class, and none moves to the new module.The table gives each anchor's class at base and head, the code lines it resolves on, and the member each line sits in. The member is shown after the line number. Every anchor stays in
security-plugin.ts.#CBP_MAX_CHAIN_DEPTH:630(top-level):635(top-level)#SecurityPlugin:1384(class):1377(class)#SecurityPlugin.getMetadataReadableFields:6126(method):6119(method)#SecurityPlugin.resolvePermissionSetsForContextUnmemoized:7037(method):7030(method)#assertControlledByParentWrite:9654(method):9525(method)#assertMasterRowEditable:10132(method):10003(method)#collectRLSPolicies:10389(method):10260(method)#computeControlledByParentFilter:9200(method):9071(method)#computeDelegatedReadFilter:6004(method):5997(method)#computeRlsFilter:5256(explainAccessForCaller),:7659(method):5249,:7652#controlled_by_parent:9035(reportCbpMasterUnresolved),:9209(computeControlledByParentFilter),:9275(controlledByParentChainRefusal):9080(computeControlledByParentFilter),:9146(controlledByParentChainRefusal)#getReadFilter:2296(start),:5882(method):2289,:5875#hasPlatformAdminPosture:7686(method):7679(method)#isPrincipalLessContext:484(top-level):489(top-level)#manage_metadata:233(PLATFORM_ADMIN_ONLY_CAPABILITIES):238#nav_permission_sets:1789(init):1782#refuseNoActiveOrganization:8499(local incomposeWriteTenantWall):8492#rlsFilter:4359(local instart):4352#sharingModel:9208(local incomputeControlledByParentFilter):9079#writeCheckPolicies:1279(top-level):1272(top-level)Only one resolving site moves:
#controlled_by_parentat base:9035. It is the quoted token insidereportCbpMasterUnresolved's message template, and it goes to the new module with that body, where it is still a literal. The anchor namessecurity-plugin.ts, and there it keeps its other two sites. That is ruling 6353073966 premise 6, read on this cut's base.Readers
No test, script, gate, baseline or docs anchor reads the moved lines by path, so nothing else is re-pointed.
check-scripts-symbol-anchors,check-spec-docblock-symbol-anchors,pnpm --filter @objectstack/spec check:liveness, andcheck-platform-checklist --changed-from origin/main. The last of these judged 6 anchors and lost 0.security-plugin.ts:Ncitation in the repo points into a moved range. The moved ranges are base:727-:738,:8884-:8985,:9007-:9042and:9094-:9114.:16-:726(the import block changed) and by -7 for base:739-:8883.:132,:303,:309,:1614,:1690,:1736,:3215,:3281,:3519and:4344all land in those shifted ranges. They are inCHANGELOG.md,packages/objectql/CHANGELOG.md,docs/launch-readiness.md,docs/design/predicate-compilation-convergence.md,packages/objectql/src/engine.tsandpackages/spec/liveness/object.json.:1614is a middleware docblock, not the system bypass, and:309isinterface WriteWallRefusal. So this cut does not make any of them wrong.check-platform-object-tenancy-census,check-position-name-fold-loaders,check-registry-log-declared,check-rest-log-spy-declared,check-system-context-census,check-tenant-audit-census,check:cross-package-test-inputs,check:driver-memory-censusandcheck:query-options-erasure. The last reports 62 unswept sites in 16 files at both base and head, andsecurity-plugin.tsis not a baseline key.check-undeclared-dep-imports: 3286 to 3287 files, 2824 specifiers at both.check:doc-authoring: 1410 to 1411 sources.check:org-identifier: 3628 to 3629 files.check:logger-receiver-detach: 3602 to 3604 files. The second extra file isapps/docs/.next/types/validator.ts, a gitignored local build output of the docs app. It is not in the tree CI checks out.check-issue-citationsjudges a change set, so it has nothing to read at base. At head it judged 12 citations across 2 files, and all resolve.Acceptance notes
docs/adr/**.#sharingModel, ADR-0055:58#controlled_by_parentand ADR-0123:4#refuseNoActiveOrganization. They need a docs-only Tier H card.domain:cli:dispatch-gates --commandsdoes not derivecheck-adr-symbol-anchorsfor this change set.Gates
All gates ran at the narrowed head, the tree of
4c92fe8165, on base5801a4f2. Since that base,origin/mainmoved to09e07c259a, but nothing underpackages/plugins/plugin-security/,docs/adr/orscripts/adr-anchors/changed.pnpm --filter @objectstack/plugin-security test(vitest run --maxWorkers=3, under the verify lock): Test Files 210 passed (210), Tests 4403 passed, 45 skipped (4448). Base5801a4f2gives the same counts. VERDICT command-exit 0 on both.pnpm --filter @objectstack/plugin-security typecheck: exit 0. It runstsc --noEmit, the scripts tsconfig, andcheck:test-typecheck, whose debt ledger holds 0 files / 0 errors.eslint --no-inline-configover the two touched source files: exit 0.pnpm --filter @objectstack/plugin-security build: exit 0. It produced the.d.tsand bundles measured above.node scripts/check-adr-symbol-anchors.mjsexit 0,pnpm check:query-options-erasureexit 0, plus the three symbol-anchor gates under Readers. None of these is derived for this change set; each was run by hand.dispatch-gates --commands: 62 commands, 449 changed lines, under the threshold. The--ranreconciliation shows 62 derived, 62 run, 0 NOT-MEASURED, 0 UNRUN. The zero is derived: all 62 recorded an exit code and none is 3.Per command (exit code):
node scripts/check-ci-filter-parity.mjsexit 0node scripts/check-closing-keyword-parity.mjsexit 0node scripts/check-closing-keyword-parity.mjs --self-testexit 0node scripts/check-comment-mask-adoption.mjsexit 0node scripts/check-comment-mask-adoption.mjs --self-testexit 0node scripts/check-comment-mask-corpus.mjsexit 0node scripts/check-dts-emitted.mjs --self-testexit 0node scripts/check-issue-citations.mjsexit 0node scripts/check-keyed-text-bounds.mjsexit 0node scripts/check-keyed-text-bounds.mjs --self-testexit 0node scripts/check-platform-object-tenancy-census.mjsexit 0node scripts/check-platform-object-tenancy-census.mjs --self-testexit 0node scripts/check-plugin-teardown-shape.mjsexit 0node scripts/check-plugin-teardown-shape.mjs --self-testexit 0node scripts/check-position-name-fold-loaders.mjsexit 0node scripts/check-position-name-fold-loaders.mjs --self-testexit 0node scripts/check-registry-log-declared.mjsexit 0node scripts/check-registry-log-declared.mjs --self-testexit 0node scripts/check-rest-log-spy-declared.mjsexit 0node scripts/check-rest-log-spy-declared.mjs --self-testexit 0node scripts/check-scripts-symbol-anchors.mjsexit 0node scripts/check-scripts-symbol-anchors.mjs --self-testexit 0node scripts/check-system-context-census.mjsexit 0node scripts/check-system-context-census.mjs --self-testexit 0node scripts/check-tenant-audit-census.mjsexit 0node scripts/check-tenant-audit-census.mjs --self-testexit 0node scripts/check-undeclared-dep-imports.mjsexit 0node scripts/check-undeclared-dep-imports.mjs --self-testexit 0node scripts/docs-audit/check-affected-docs.mjsexit 0node scripts/docs-audit/check-drift-comment.mjsexit 0pnpm --filter @objectstack/spec run check:duration-unit-keysexit 0pnpm check:adr-anchorsexit 0pnpm check:agent-test-spellingexit 0pnpm check:bash32-floorexit 0pnpm check:cli-command-idsexit 0pnpm check:closed-ceremony-textexit 0pnpm check:cross-package-test-inputsexit 0pnpm check:doc-authoringexit 0pnpm check:driver-memory-censusexit 0pnpm check:dts-closureexit 0pnpm check:dual-build-cjs-loadsexit 0pnpm check:entry-guardexit 0pnpm check:error-status-conformanceexit 0pnpm check:gitlink-declaredexit 0pnpm check:i18nexit 0pnpm check:i18n-stale-fillexit 0pnpm check:issue-citationsexit 0pnpm check:lean-entry-closureexit 0pnpm check:logger-receiver-detachexit 0pnpm check:nul-bytesexit 0pnpm check:org-identifierexit 0pnpm check:page-declaration-shapeexit 0pnpm check:parse-guardexit 0pnpm check:pnpm-filter-targetsexit 0pnpm check:pnpm-flag-spellingsexit 0pnpm check:published-filesexit 0pnpm check:refd-timer-probeexit 0pnpm check:slot-lookupexit 0pnpm check:sourcemap-no-sources-contentexit 0pnpm check:test-source-aliasexit 0pnpm check:tier-file-adoptionexit 0pnpm check:watch-hint-literalexit 0Generated by Claude Code
🤖 Generated with Claude Code
https://claude.ai/code/session_017BoLT8Gaa8t9a7AWVH8qZa