Uh oh!
There was an error while loading. Please reload this page.
fix(plugin-sharing): hold publicSharing.enabled at redemption, not only at mint (#14033) - #14580
Conversation
…ly at mint `ShareLinkService.resolveToken()` now reads the object's CURRENT `publicSharing` block on every redemption and refuses when `enabled` is not `true` — before the record probe, before the usage stamp, before any sibling key inside the block is evaluated. Re-enabling the block restores the same tokens (a standing policy, not a revocation). How a link was minted buys it nothing at redemption: rows minted under a system context or the `permissive` bypass on a switched-off object refuse the same way, and an object with no block at all is the same switch at its default. The refusal reuses the undifferentiated `null` a revoked / expired / unknown / ineligible token already gets — no new error code, no new response branch, no usage stamp (over HTTP the generic 404). The readable reason goes to the server-side log at `warn`, where the eligibility refusal already writes its own. Tests: the standing-policy pins (fake engine and real driver), the HTTP-seam shape, the log line, the bypass-minted path, and the reversal register for the #13856 pins that asserted serving on a disabled block. Changeset marked as a breaking runtime change in PR #13857's form. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AUF1NoViznQK32gqpK8wS8
…nk hunk shifted it `check:system-context-census --fix` — pure line rot: the `permissive` option's TSDoc grew five lines above the five `isSystem` read sites row 37 anchors in `share-link-service.ts`, so every anchor moved by exactly +5. No site arrived or vanished (109 read sites, 145 anchors, unchanged). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AUF1NoViznQK32gqpK8wS8
…blic-sharing-enabled-standing-policy
…gin/main `pnpm gen:system-context-census` on the merged tree (os-regen-merge.sh step 4): main's side of the page was taken at merge, then row 37's anchors re-derived from the merged `share-link-service.ts` (+5, the `permissive` TSDoc). No read site arrived or vanished. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AUF1NoViznQK32gqpK8wS8
📓 Docs Drift CheckThis PR changes 1 package(s): 1 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
⛔ 1 release-owned page(s) also name something this change touched. These are read-only:
What this run could not see
Coarse fallback — 8 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 114b3f22a35cc3c3d766b6dd3a6b69e3b9b98810 && git checkout 114b3f22a35cc3c3d766b6dd3a6b69e3b9b98810
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin a5b95ee6edd1e21e04cc43200f41fb730538b197 c55d849d768e09bb6d6a48973995b044bdc38861 && git checkout -B drift-repro a5b95ee6edd1e21e04cc43200f41fb730538b197 && git merge --no-ff c55d849d768e09bb6d6a48973995b044bdc38861
node scripts/docs-audit/affected-docs.mjs --json a5b95ee6edd1e21e04cc43200f41fb730538b197
|
… resolution is a standing policy The "What you get" cell of the system-context ledger's row 37 still said "link creation/resolution while the policy is off". Since the redemption gate on `publicSharing.enabled`, a link minted under the system / `permissive` bypass while the block is off does not resolve until the block is enabled. Prose only; the five anchors are untouched (seat-approved one-cell widening of the claim's file surface, 14033#issuecomment-5511082583). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AUF1NoViznQK32gqpK8wS8
…blic-sharing-enabled-standing-policy
…gin/main (round 0) os-regen-merge.sh step 4 on the merged tree: main's side of the page was taken at merge, the row-37 "What you get" cell re-applied (a hand edit no generator reproduces), then `pnpm gen:system-context-census`. Anchors unchanged; no read site arrived or vanished. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AUF1NoViznQK32gqpK8wS8
…, one permissive TSDoc clause, row 37 re-anchored Prose only; the gate, the tests and the changeset level are untouched. Changeset: the superseded #13856 reading is named; an object the engine cannot return a schema for is `enabled: false` by `getPolicy`'s definition and refuses at redemption (fail-closed, as `createLink`); the refusal logs one `warn` per refused hit, not latched. `permissive` TSDoc: during a late schema scan the option helps minting, not serving. The four added TSDoc lines moved the five row-37 anchors, re-anchored by the census gate's own `--fix`; the row-37 "What you get" cell is unchanged. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AUF1NoViznQK32gqpK8wS8
…blic-sharing-enabled-standing-policy
…gin/main (round 1) os-regen-merge.sh step 4 on the merged tree: main's side of the page taken at merge, the row-37 "What you get" cell re-applied (a hand edit no generator reproduces), then `pnpm gen:system-context-census`. No read site arrived or vanished. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AUF1NoViznQK32gqpK8wS8
os-sales
commented
Sep 2, 2026
Landing provenance — ready + auto-merge at head |
Item 2 of #14582 (follow-up to #14033 / PR #14580, split from #14033's docs surfaces that PR #14580 could not touch). The "Public Share Links" section documented the child predicate (eligibility, #13608) as a standing policy held at every redemption, but not the parent switch publicSharing.enabled — #14033 made that switch the same shape: held at every redemption, not only at mint. Adds the sibling paragraph plus its upgrade-note callout, placed after the eligibility paragraph so a reader who has already understood the child predicate recognises the parent's paragraph as the same shape one level up. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WLJQhde67SeTccsmnBVarV
Fixes#14033
Ruling of record (verbatim, untranslated)
Maintainer ruling of 2026-09-01, recorded by the director seat in 14033#issuecomment-5491054105 (maintainer's verbatim reply to the batch: 「其他同意」). The recorded four points, verbatim:
And its implementation notes, verbatim:
Premise verification on
origin/main(BASE53d368921) — all five holdTHE REPRO — minted while enabled, the SAME token stops resolving the moment the block is turned off) was run against the UNMODIFIED service before any edit:AssertionError: expected { link: { …(16) }, …(1) } to be null— the token kept serving with the block off. 15 such reds (every new/reversed pin), 61 existing pins green. Log: pre-fix run,Tests 15 failed | 61 passed (76). Premise valid.publicSharingoff leaves already-minted links serving — and silently drops the object'sredactFields#13856) pins. Two pins asserted a link on a DISABLED block still serves with redactions applied (THE REPRO — opting out keeps the declared redactions applying,boundary — the per-link redact_fields union is unchanged when the switch is off), and two reverse controls asserted a bypass-seeded link on a block-LESS object serves. All four are REVERSED in place and registered (docblock naming what each pinned, which ruling point moved it, the ruling verbatim in the block header); none deleted. The pins are agent-authored test content inshare-link-service.test.ts, not governed content. Theenabled: truecontrol and the mint-gate pin are untouched.publicSharing.eligibilityat redemption, not only at mint #13857 form. Its changeset (.changeset/share-link-eligibility-at-redemption.mdatfc9ba76a5) isminor+ the**BREAKING** runtime behaviour change on a published package … Shipped as minor under the repo's launch-window conventionbanner + an ADR-0087not-required (no-migration-prescription)marker. This changeset copies that form. HoldpublicSharing.eligibilityat redemption, not only at mint #13857 answers the refusal with the undifferentiatednull(over HTTP the generic404 INVALID_OR_EXPIRED), reason to the server-side log atwarn— the same family this refusal joins.resolveTokenalready gives for revoked / expired / unknown / ineligible:null. No error code is minted, nothing underpackages/spec/**is touched.check:dispatcher-error-vocabularyandcheck:error-code-casinggreen (below); acheck:error-code-provenancescript does not exist inpackage.json— reported as such, not as measured.content/docs/releases/**,rule-hooks.ts,sharing-plugin.ts,skills/**,packages/spec/**untouched; theredactFieldslogic from fix(plugin-sharing): declared publicSharing.redactFields survive the object opting out #14171 is untouched (getPolicyunchanged).PM mechanism hypotheses — verdicts
resolveToken, at the existing policy read (after the cheap revoked / expired / audience / password gates, BEFOREloadRecordForServing, BEFORE the usage stamp, BEFORE the redaction set):if (!policy.enabled) { log; return null; }. It reads the object's CURRENT block through the samegetPolicy/getSchemasource and nothing about how the row was minted. Measured: on a refused redemption the onlyfindthe engine sees is thesys_share_linktoken lookup;use_count/last_used_atare unchanged (fake engine and real SqlDriver alike).nullat the service seam,404 INVALID_OR_EXPIREDover HTTP, byte-for-byte equal to an unknown token (pinned at the route).SHARING_NOT_ENABLEDstays the authoring-side mint refusal (422, pinned unchanged) and appears at redemption only as thereasonfield of the server-side log line, never on the wire (pinned: the body contains noenabled,publicsharingorsharing_not_enabled).eligibilityis not evaluated and the redaction set is not computed (the gate returns first; pinned: a record the predicate WOULD refuse is refused by the switch with no record read and aSHARING_NOT_ENABLEDlog line, and switching back on the same token is refused by the predicate —RECORD_NOT_ELIGIBLE— then serves once it qualifies). With the block on, HoldpublicSharing.eligibilityat redemption, not only at mint #13857's 12 redemption pins and fix(plugin-sharing): declared publicSharing.redactFields survive the object opting out #14171'senabled: truecontrol are unchanged and green. No new code path for any sibling key.share-link-routes.tsuntouched:nullis already mapped (401 for a live password / signed-in row exactly as today, 410 for revoked / expired, else 404INVALID_OR_EXPIRED). The dispatcher twin (runtime/src/domains/share-links.ts) mapsnullthe same way.What changed
packages/plugins/plugin-sharing/src/share-link-service.tsresolveToken(): the standing-policy gate described under H1, with a docblock carrying the why, the placement argument, ruling point 3 (no mark of how a row was minted is read — an absent block is the same switch at its default and refuses too) and point 4.ShareLinkServiceOptions.permissiveTSDoc: states the bypass is MINT only and that a link minted under it while the block is off does not resolve until the block is enabled. This TSDoc grew five lines above the fiveisSystemread sites row 37 anchors — see the adjacent mechanical fix below.packages/plugins/plugin-sharing/src/share-link-service.test.ts— the reversal register for the #13856 block (four pins reversed in place, the ruling quoted verbatim once in the block header), the two harness helpers hoisted to module scope so both blocks share them, and the[#14033]block: the repro, the standing-policy restore, the shared-nullshape, and ruling point 3 on three mint paths (permissive, system context, never-declared block).packages/plugins/plugin-sharing/src/share-link-eligibility.test.ts— the[#14033]block on the real SqlDriver and the real public route: no record read / no usage stamp, the HTTP-seam equality with an unknown token, the log line, ruling point 4 both halves on one token, and thepermissive-minted link refused by the bypassing service and the ordinary one alike..changeset/share-link-enabled-at-redemption.md—@objectstack/plugin-sharing: minor, in PR #13857's form (see "Changeset level" below).content/docs/permissions/system-context.mdx— row 37 re-anchored bycheck:system-context-census --fix(adjacent mechanical fix, declared here; see below) AND its "What you get" cell hand-corrected (one cell, seat-approved in round 0): the bypass buys link creation only; resolution is not bypassed since #14033.Clause-② declaration (from the actual diff)
git diff -U0 origin/main...HEAD | grep exporton the branch: zero lines. No export is added, removed or re-shaped. The accept-set narrowing is behavioural, on the anonymous redemption door: tokens on an object whosepublicSharing.enabledis nottrue— accepted today, refused after, retroactively on deploy, for every mint path.needs:contract-reviewis hung on this PR and on #14033 per the claim. Hand-edited prose in this PR beyond the code and tests: exactly one cell — the "What you get" cell ofcontent/docs/permissions/system-context.mdxrow 37 (seat-approved widening of the claimed file surface, round 0); every other change to that page is the gate's own re-anchoring.Reading the contract review may want to judge: the gate treats an object with NO
publicSharingblock as switched off (it is the same switch at its default —enableddefaults tofalse;createLinkalready refuses both identically), so a bypass-minted link on a never-opted-in object refuses too. Ruling point 3 is read as requiring exactly this; exempting block-less objects would leave the row-37 path open on every object that never opted in.Log level
One new log site,
warn, through the sink's GUARANTEED member (ShareLinkServiceOptions.logger.warn), spelledthis.logger?.warn?.(…)exactly likestillEligible's refusal line. Why a log at all: by ruling the wire answer is deliberately undifferentiated, so the server-side log is the ONLY place the reason a link died exists — #13857's ruling put it there and the same argument holds for the parent switch. Why noterror: the caller was answered (null), so this is a response, not a durability degradation; noerror?growth on the published sink shape (#13398 class ruling respected).check:durability-log-levelandcheck:optional-error-sinkgreen.Adjacent mechanical fix — system-context row 37 re-anchor (+ the merge regeneration)
check:system-context-censuswent red on this branch with exactly the 10 problems thepermissiveTSDoc edit predicts: 5[site-without-a-row]reads at:445 :499 :503 :576 :606plus the 5[anchor-is-not-a-read-site]citations they rotted off (:440 :494 :498 :571 :601). Remedy: the gate's own--fix(5 anchors rewritten, all +5; 109 read sites / 145 anchors unchanged — no site arrived or vanished). The pre-PRmerge-treecheck then listed the same page as driver-deferred against a movedorigin/main, soscripts/pm/os-regen-merge.shwas run and the page regenerated as the driver instructs; see the commit list.Commits on the branch (squash-merged as one):
1925bfafcthe gate + pins + changeset ·a4f128f6bcensus re-anchor (--fix) ·1162f24dfmerge oforigin/main(7286dd58e) viaos-regen-merge.sh·a52cfa363census regeneration on the merged tree (pnpm gen:system-context-census). Final head:a52cfa363. The union of gates, both pin files (Tests 76 passed (76)) and the package typecheck were re-run on that head; the readings above are from those runs.Tests and ablation (ran on the head named in each line)
53d368921+ the new pins:Tests 15 failed | 61 passed (76)— all 15expected { link: … } to be null.a52cfa363:pnpm --filter @objectstack/plugin-sharing exec vitest run --maxWorkers=2 src/share-link-service.test.ts src/share-link-eligibility.test.ts→Test Files 2 passed (2)/Tests 76 passed (76).pnpm --filter @objectstack/plugin-sharing typecheck(tsc + tsconfig.scripts +check:test-typecheck) → exit 0;check:test-typecheck: OK — … 2 file(s) / 3 error(s) / 3 pinned signature(s) held(ledger unchanged; the edited test files carry no debt entry, so they are compiled and clean).a4f128f6b, before the main merge; the gate is byte-identical after it): the gate's condition replaced byfalsewith a marker, proven on disk by anchored counts (if (!policy.enabled) {1→0, marker 0→1,git diff --stat1 file 1+/1−). The subject is imported from source (./share-link-service.js, same package — not a dependency'sexports), so no dist is involved and no rebuild leg applies. Ablated run:Tests 15 failed | 61 passed (76)— exactly the 15 pins the gate protects went red; the 61 others (all HoldpublicSharing.eligibilityat redemption, not only at mint #13857 eligibility pins, the mint-gate pin, theenabled: truecontrol) stayed green. Restore:git checkout HEAD -- ABSOLUTE_PATH, proven by emptygit diff HEAD+ clean status + equal blob hashes (d00a6e53…both sides). Direction note vs the dispatch template: pin (b) (turn the block back ON restores the token) went RED under ablation, not green — it asserts the OFF refusal first, which the ablated tree cannot produce; the ON half is unreachable there. (d) and (e) stayed green as predicted.Gates (derived on the final head with
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands, run unlocked in four batches, exit captured before any pipe)Green (exit 0): 61 commands —
node scripts/check-adr-0087-registration.mjs·node scripts/check-changeset-no-major.mjs·node scripts/check-ci-filter-parity.mjs·node scripts/check-comment-mask-adoption.mjs·node scripts/check-cross-package-test-inputs.mjs·node scripts/check-doc-frontmatter.mjs·node scripts/check-doc-route-spelling.mjs·node scripts/check-docs-section-name.mjs·node scripts/check-empty-changeset.mjs·node scripts/check-keyed-text-bounds.mjs·node scripts/check-plugin-teardown-shape.mjs·node scripts/check-section-landing-index.mjs·node scripts/check-shard-attestation.mjs·node scripts/check-system-context-census.mjs·node scripts/check-tenant-audit-census.mjs·node scripts/check-undeclared-dep-imports.mjs·node scripts/docs-audit/check-affected-docs.mjs·node scripts/docs-audit/check-drift-comment.mjs·node scripts/pm/check-half-states.mjs·node scripts/pm/release-rehearsal-clone.mjs --self-test·pnpm --filter @objectstack/lint run check:doc-formula-expressions·pnpm --filter @objectstack/lint run check:doc-security-posture·pnpm --filter @objectstack/spec run check:docs·pnpm --filter @objectstack/spec run check:empty-state·pnpm --filter @objectstack/spec run check:liveness·pnpm --filter @objectstack/spec run check:strictness-ledger·pnpm --filter @objectstack/spec run check:variant-docs·pnpm --filter @objectstack/spec run check:yaml-examples·pnpm check:changeset-gate-self-tests·pnpm check:corpus-claim-drift·pnpm check:cross-package-test-inputs·pnpm check:doc-anchors·pnpm check:doc-authoring·pnpm check:docs-audit-scope·pnpm check:docs-redirects·pnpm check:docs-single-h1·pnpm check:engine-double-contract·pnpm check:i18n-stale-fill·pnpm check:logger-receiver-detach·pnpm check:merge-driver·pnpm check:objectql-double-limit·pnpm check:objectui-changeset·pnpm check:page-declaration-shape·pnpm check:pm-half-states·pnpm check:published-files·pnpm check:published-readme-links·pnpm check:query-options-erasure·pnpm check:react-page-adapter-contract·pnpm check:role-word·pnpm check:skill-identifier-liveness·pnpm check:slot-lookup·pnpm check:test-source-alias·pnpm check:type-check-coverage·pnpm check:type-source-resolution·pnpm check:vendor-version-stamps·pnpm check:where-matcher·pnpm check:dispatcher-error-vocabulary·pnpm check:error-code-casing·pnpm check:durability-log-level·pnpm check:optional-error-sink·pnpm check:nul-bytesNOT MEASURED — each exited on its own stated prerequisite, none is a red:
node scripts/check-test-completeness.mjs— exit 3: needs a saved test-run log; the gate's own text says the local reading is NOT MEASURED.pnpm check:dual-build-cjs-loads— exit 3PREREQUISITE NOT MET: reads built output of 54 packages that have nodist/here.pnpm check:i18n— exit 1PREREQUISITE NOT MET: the workspace CLI is not built. This diff touches no translation bundle or object metadata.pnpm --filter @objectstack/spec run check:skill-examples— exit 1:packages/client-react/distholds no.d.ts(not built). This diff touches no skill, doc example or client SDK.pnpm check:type-check-debt— exit 3PREREQUISITE NOT MET: 40 workspace dependencies of the ledgered packages are unbuilt; no ledger number was touched.check:error-code-provenance— no such script inpackage.json.Repo-wide
pnpm lintnot run locally (CI-owned); the diff is three TypeScript files in one package plus a changeset and a regenerated page.Changeset level
minor, notpatch, deliberately:scripts/check-changeset-no-major.mjsrecords the launch-window convention (a breaking change ships asminor; the BREAKING banner and the ADR-0087 disposition are the carriers), and the ruling says 「与 #13857 同型」 — #13857 isminorwith that banner. No export changed; the level carries the breaking banner, not a surface change. ADR-0087 disposition:not-required (no-migration-prescription)— nothing authorable is removed, renamed or re-shaped;check:adr-0087-registrationandcheck:changeset-no-majorgreen.Known stale prose deliberately NOT edited here (file surface per the claim) — flagged for the PM
content/docs/permissions/system-context.mdxrow 37, "What you get" column used to read "link creation/resolution while the policy is off". After this change the bypass buys creation only; resolution is refused. The page is in this PR only through the census gate's own regeneration (the claim's constraint), so the one-cell correction is proposed, not made: "Get: link creation while the policy is off — resolution is NOT bypassed since [Decision] What does turningpublicSharing.enabledoff mean for an ALREADY-MINTED share link? — the parent switch is mint-only while its own child predicate is now a standing policy #14033: a link minted this way does not resolve until the block is enabled".content/docs/protocol/objectql/security.mdx"Wheneligibilityis enforced" — theenabledswitch now deserves the sibling paragraph and upgrade note HoldpublicSharing.eligibilityat redemption, not only at mint #13857 wrote foreligibility.packages/spec/src/contracts/share-link-service.tsIShareLinkService.resolveTokenTSDoc lists thenullcauses and should name the switched-off block;packages/spec/src/data/object.zod.tspublicSharing.enabledTSDoc says "no share links can be issued" and should add "and none resolves". TSDoc only, no schema change — outside this card's surface (packages/spec/**is a stop condition for schema changes; these are prose).Generated by Claude Code
Patch round 0 (after the seat's collection comment 14033#issuecomment-5511082583)
content/docs/permissions/system-context.mdxrow 37 now reads "Get: link creation while the policy is off — resolution is not bypassed since [Decision] What does turningpublicSharing.enabledoff mean for an ALREADY-MINTED share link? — the parent switch is mint-only while its own child predicate is now a standing policy #14033 (publicSharing.enabledis a standing policy held at every redemption): a link minted this way does not resolve until the block is enabled". Anchors untouched;check:system-context-censusgreen on its own reading and the cell survivedpnpm gen:system-context-census(the generator re-anchors lines, it does not rewrite prose). Items 2–3 of "Known stale prose" stay with docs: state the standing-policy semantics ofpublicSharing.enabledon the three prose surfaces #14580 could not touch (follow-up to #14033) #14582.minor.origin/main(2a2653619) merged viascripts/pm/os-regen-merge.sh(the merge-tree listed the census page as driver-deferred); main's side of the page taken at merge, the cell re-applied, the page regenerated on the merged tree. New head:b2d9fd87b. The two pin files, the package typecheck,check:doc-authoringandcheck:system-context-censuswere re-run on that head — readings in the round-0 report comment on [Decision] What does turningpublicSharing.enabledoff mean for an ALREADY-MINTED share link? — the parent switch is mint-only while its own child predicate is now a standing policy #14033.Generated by Claude Code
Patch round 1 (after contract review round 1 PASS, 14033#issuecomment-5511376156 — the four prose-only notes taken)
.changeset/share-link-enabled-at-redemption.md, levelminorand the BREAKING banner untouched): (a) one sentence naming the superseded sharing: turningpublicSharingoff leaves already-minted links serving — and silently drops the object'sredactFields#13856 reading — the "an opted-out object's links keep resolving with the declared redactions" state does not hold once the block is off; (b) one clause in "What changed": an object the engine cannot return a schema for (nogetSchema, or not registered at the moment of redemption) isenabled: falsebygetPolicy's definition and is refused at redemption — fail-closed, the same definitioncreateLinkuses; (c) one operator-impact line: the refusal logs onewarnper refused hit and is not latched, so a retroactive deploy with many live links on switched-off objects bursts the log once..changeset/share-link-redactfields-survive-optout.md(sharing: turningpublicSharingoff leaves already-minted links serving — and silently drops the object'sredactFields#13856's own file) is not edited.share-link-service.ts, thepermissiveTSDoc only: one clause that during a late schema scan the option helps minting, not serving — redemption refuses until the schema resolves and the block is enabled. Four lines above the five row-37isSystemanchors, so the census page was re-anchored by the gate's own--fix; the row-37 "What you get" cell survived (grep count 1) and no row text changed.c55d849d7; readings in the round-1 report comment on [Decision] What does turningpublicSharing.enabledoff mean for an ALREADY-MINTED share link? — the parent switch is mint-only while its own child predicate is now a standing policy #14033. Not touched: the gate, the tests, the changeset level,security.mdx,sharing-service.mdx,packages/spec/**,releases/**.Generated by Claude Code
Generated by Claude Code