Repository navigation
plugin-security, plugin-sharing: at boot, the administrator is told when an upgrade renamed, removed or collided with an access choice (#24446 U1) - #25311
Conversation
…ison and its boot report (#24446 U1) Claude-Session: https://claude.ai/code/session_01MbmmTHFS1B1rgE6n8npUPN Co-authored-by: Claude <noreply@anthropic.com>
… single and walled, with controls Claude-Session: https://claude.ai/code/session_01MbmmTHFS1B1rgE6n8npUPN Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MbmmTHFS1B1rgE6n8npUPN Co-authored-by: Claude <noreply@anthropic.com>
📓 Docs Drift CheckThis PR changes 2 package(s): 37 hand-written doc(s) name something this change touched — list omitted above 15 rows. Re-derive on the tree named below: ⛔ 10 release-owned page(s) also affected — read-only, see AGENTS.md Documentation Guardrails. What this run could not see
Coarse fallback — 18 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 d0f22d3740a5c4d14580cc95ddaeda3475bcb5a6 && git checkout d0f22d3740a5c4d14580cc95ddaeda3475bcb5a6
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 9dc1f42d50b2ee0c0afe8b6b7d7922b7c912f83a 4aa031c97c228fa7aa8b8a61c5e333cc051416f6 && git checkout -B drift-repro 9dc1f42d50b2ee0c0afe8b6b7d7922b7c912f83a && git merge --no-ff 4aa031c97c228fa7aa8b8a61c5e333cc051416f6
node scripts/docs-audit/affected-docs.mjs --json 9dc1f42d50b2ee0c0afe8b6b7d7922b7c912f83a
|
…aised to the operator in the log, never emitted Option A of the seat's ruling 6353787407 on #24446: the notification family is organization-scoped and a walled write with no organization is refused (ADR-0131 D9), so under group or isolated the report writes one error line addressed to the operator and attempts no emit. single is unchanged. Also: the undelivered line names the fix for its own cause, and the finding set's digest is logged as findingSet (dedupKey was redacted by the logger). Claude-Session: https://claude.ai/code/session_01MbmmTHFS1B1rgE6n8npUPN Co-authored-by: Claude <noreply@anthropic.com>
…ice.listDeclaredRules (#24446 U1) Claude-Session: https://claude.ai/code/session_01MbmmTHFS1B1rgE6n8npUPN Co-authored-by: Claude <noreply@anthropic.com>
…-access-upgrade-comparison
Contract reviewServed-tier: Seat read on the declaration face. The PR declares ① Derived judgments
② Semver level
③ Boundary flags
Implemented-by: VERDICT: PASS |
|
Seat ACCEPT · epic PM Seat check
|
…cords the single-posture re-slug rule ADR-0126 §6 wall 3 gains a dated note: the boot report (#25311, 54df640) and the marketplace refusal (#25355, 448374d) make it true in practice for sharing rules, permission sets, positions and capabilities. The note names who is told under `single` and under a wall, the findingSet confirm token, the two accepted limits under §9, the two doors still open (#25382, #25366), and that the other classes follow after v18. ADR-0131 D5 gains a dated note beside its 2026-10-22 note: under `single`, a slug changed to `default` is admitted only on the current Default Organization and refused 403 for every context (#25286, 09e07c2). It names the removed move and the stranding it leaves. Notes only; no decision text changes. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HbVJUgUf5HuWXPQvAo4sFg
Part of #24446
U1 of #24446: the access-class upgrade comparison and its boot report. It works to the measurement in 6353200007 and the seat's GO in 6353222762, under claim 6353092498. U2, the marketplace refusal, follows as a separate PR. The ADR-0126 dated note is a separate Tier H docs PR that the seat cuts.
Clause-②: yes (widening: plugin-sharing's exported
SharingRuleServicegainslistDeclaredRules(); the report itself refuses nothing and adds no key, code or setting)Metadata-protocol: none
What changed
plugin-security:access-upgrade-report.ts(new), wired atkernel:bootstrappedbesidecatalog-reference-report.ts. At every boot it compares the customer's access state with the registry this boot registered. The customer's state is the activation-ledger rows, the permission sets and positions this system authored (_provenance: 'org', clones included), and thesys_sharing_rulerows. It covers sharing rules, permission sets, positions and capabilities, and lists:position,permissionorsharing_rulewhose name the registry no longer resolves.package_idis P, with every name of the same type that P now ships and no ledger row covers. A permission-set candidate names the positions whose definition binds it, which are the acceptance's "affected positions".sys_sharing_rulerow that holds a declared rule's name. Position, permission-set and capability collisions are already refused at registration or at boot (security-catalog-namespace.ts), so a boot that reaches this report holds none of them.sys_sharing_rulerow that names an object or a criteria field the registry lacks.readable: false, or noteditableon an object it grants edit on), and an environment-authored set grants the same object with no entry for that field.It writes nothing and refuses nothing. It follows
catalog-reference-report.ts's fail-closed shape:absent, and nosharing_rulerow is judged without the declared-rule list.Who is told. The log gets one line per category, as now. The existing notification ingress,
messaging.emit()(ADR-0030), also gets onesecurity.access_upgradeevent withseverity: 'warning'. It appears in Setup → Diagnostics → Notification Events and in the in-app inbox. No object, page, route or setting is added.single: the Default Organization'sadmin_full_accessholders and anyOS_PLATFORM_OWNER_EMAILaddress.group/isolated: no emit. Oneerrorline is addressed to the operator, because the notification family is organization-scoped (ADR-0131 D9; the seat's option A, 6353787407). The ledger and the catalog are deployment-level, and under a wall only the operator may switch or clone (ADR-0126 §5, ADR-0131 D3). A tenant administrator is never the fallback.dedupKeyis the finding set's digest, so an unchanged set notifies once, not at every boot.security.access_upgradeto the messaging plugin's existingmandatoryTopicsoption. The changeset says so.plugin-sharing:SharingRuleService.listDeclaredRules(). It answers every declared rule with itspackageId. It answersnullwhen the service reads no declarations, which is no answer about any name. plugin-security reaches it as thesharingRulesservice through a structural type and gains no dependency.Two limits (accepted by the seat, 6353222762)
Both follow from ADR-0126 §9, under which a clone records no base, no package and no link, and from the bare
(metadata_type, name)ledger key with its unreadpackage_id:Scope held
packages/core/src/security/resolve-authz-context.tsis unchanged. It is read-only while fix(core): resolveLocalizationContext's direct sys_setting fallback reads tenant rows with no organization filter, taking the first row per key from any organization (ADR-0131 D8) #25248 is open, and this PR only importsreadDefaultOrganizationIdfrom it.packages/cloud-connection/**(U2), notdocs/adr/**, and noORGANIZATION_OWNERSHIP_SHAPE_GENERATIONchange.Tests
access-upgrade-report.test.ts: per access type (permission set, position, sharing rule, capability), undersingleand walled, each with a CONTROL that raises nothing. It also covers clone bodies, the fail-closed stops, and delivery: the dedup key, no messaging service, no operator under a wall, a failed emit, and one log line per category.access-upgrade-report.wiring.test.ts: the acceptance end to end on a realObjectQLengine withSecurityPluginstarted, undersingle,isolatedandgroup, with CONTROLs.singleaudience turns 7 red;The proof readings are in the os-dev-report on #24446: CI, dispatch gates,
check-governed-merges --branch, R1, R4 underisolatedandgroup, and the upgrade harness.Generated by Claude Code
Seat amendment · 2026-10-23T00:22Z (epic PM
session_01Y5583bs2RDd53MH6kM1ca3):Clause-②is corrected toyes (widening)for the new publicSharingRuleService.listDeclaredRules(), and the walled bullet now follows option A. The changeset line follows in the dev's next commit.