feat(security)!: reconcile SharingRule authoring with the enforced runtime — group→team, +business_unit, prune guest + owner-type (#1878) - #3557
Merged
Conversation
…ntime — group→team, +business_unit, prune guest + owner-type (#1878) The authoring ShareRecipientType enum drifted behind the ADR-0090 D3 rename and the enforced runtime: expandRecipient already expands `team` (sys_team / sys_team_member via TeamGraphService) and `business_unit`, but the enum still offered the pre-rename `group` (silently skipped at seed time with a warn) and omitted both live recipients. Owner-type rules validated but were skipped wholesale (live-membership-dependent). After this change every authorable recipient and rule type is enforced — nothing on the SharingRule surface validates and then silently does nothing (ADR-0078). - spec: rename group→team, add business_unit, drop guest; delete OwnerSharingRuleSchema + OwnerSharingRule (SharingRuleSchema = the criteria form; SharingRuleType = ['criteria']); JSDoc rewritten; explain.zod comment. - plugin-sharing bootstrap: map team→TeamGraphService expansion; retired shapes kept as defensive skips (stale pre-built packages), never match-all. - examples: migrate both never-enforced owner rules to enforced criteria rules (showcase share_open_tasks_with_manager: done==false → manager; crm share_active_leads_with_manager: status not converted/disqualified → sales_manager); crm smoke test asserts criteria-only. - dogfood: rbac-seeding test flips from "owner rule honestly skipped" to "criteria replacement seeds + enforces" (criteria_json {done:false}, recipient position/manager — proven on a real boot: ruleCount 4→5, showcase_task now hook-bound); authz-conformance sharing-rules row updated. - docs: permissions/sharing-rules.mdx recipient table (all enforced) + retired-shapes note; references regen; manifest key security/OwnerSharingRule dropped; api-surface −2 exports. Verified: spec 6882 + plugin-sharing 101 + crm 20 + showcase 58 + dogfood 17 tests green; spec/downstream-contract/examples tsc clean; check:docs / api-surface / skill-refs / skill-examples in sync. Ships minor per the launch-window breaking-as-minor policy; changeset carries the FROM→TO migration. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
Contributor
📓 Docs Drift CheckThis PR changes 3 package(s): 105 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
os-zhuang
added a commit
that referenced
this pull request
Jul 27, 2026
…ec/system (#1878) (#3593) The entire system/audit.zod.ts module — AuditConfigSchema, AuditStorageConfig, AuditRetentionPolicy, AuditEventFilter, SuspiciousActivityRule, DEFAULT_SUSPICIOUS_ACTIVITY_RULES, and the AuditEvent* shape schemas — had ZERO consumers repo-wide. The live audit path (plugin-audit) imports none of it: capture is unconditional via engine hooks (compliance ledger), the row shape is owned by plugin-audit's sys_audit_log object, retention rides the object lifecycle `audit` category with per-org settings overrides, and the authoring surface is object/field trackHistory. AuditConfigSchema.enabled even advertised turning the compliance ledger OFF — a semantic the platform deliberately rejects. Same ADR-0056 D8 family as the compliance.zod / masking.zod / RLSAuditConfig / PolicySchema removals. - Delete system/audit.zod.ts + audit.test.ts; drop the export from system/index.ts with a removal note (house pattern). - Drop the 11 manifest ratchet keys; regenerate JSON schemas, reference docs (references/system/audit.mdx removed by regen), and the API surface (21 exports, pure removal). - Fix the stale security-context.zod.ts module doc (audit joins the already removed compliance/masking bullets) and drop the PROTOCOL_MAP.md row (protocol-map gate caught the dangling link). - Annotate the 2026-07 security recheck doc: loose-end #1 done (verified scope = whole module, not just AuditRetentionPolicy); #2 done via #3557. - Changeset (minor per launch-window policy) carries the dead-knob → live- surface migration table. Verified: 6679 spec tests green, tsc clean, check:docs/api-surface/skill-refs/ react-blocks in sync, downstream-contract typecheck clean (gate not pinning any Audit export). Co-authored-by: Jack Zhuang <277994282+os-zhuang@users.noreply.github.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes the SharingRule loose end from the 2026-07 security-props recheck (#3503, umbrella #1878). Decision per owner directive: the system has team, not group; the rest judged against mainstream platforms, long-term surface honesty, and AI-authoring safety (ADR-0078).
Problem
The authoring
ShareRecipientTypeenum drifted behind both the ADR-0090 D3 rename and the enforced runtime.expandRecipientalready expandsteam(sys_team/sys_team_memberviaTeamGraphService) andbusiness_unit(BusinessUnitGraphService) — but the authoring enum still offered the pre-renamegroup(silently skipped at seed time with a warn) and omitted both live recipients.guesthad no runtime mapping at all, and owner-type rules (type: 'owner',ownedBy) validated and were then skipped wholesale. The spec's own JSDoc claimed team/business_unit support the enum didn't deliver.What changed
groupteam, wired to the liveTeamGraphServiceexpansionbusiness_unitguesttype: 'owner'(ownedBy)queuesys_queueyet)Net invariant: every authorable recipient and rule type now enforces — nothing on this surface validates and then silently does nothing.
OwnerSharingRuleSchema+ type export deleted;SharingRuleSchema= the criteria form (SharingRuleType = ['criteria'], union slot documented for future enforced types); JSDoc rewritten.teammapped; retired shapes kept as defensive skips (stale pre-built packages) — never seeded as match-all (ADR-0049).share_open_tasks_with_manager,share_active_leads_with_manager).showcase_tasknow hook-bound,criteria_jsoncompiles to exactly{done: false}. authz-conformancesharing-rulesrow updated.Verification
tsc --noEmitclean (the frozen third-party consumer uses none of the removed exports).check:docs/check:api-surface/check:skill-refs/check:skill-examplesin sync; skills contain no retired shapes.Breaking → ships as
minorper the launch-window breaking-as-minor policy; the changeset carries the FROM→TO migration (stale definitions fail parse with the valid options listed — loud at authoring time, exactly the ADR-0078 posture).Refs #1878, #2077, #1887.
🤖 Generated with Claude Code