You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[Decision] What does turning publicSharing.enabled off mean for an ALREADY-MINTED share link? — the parent switch is mint-only while its own child predicate is now a standing policy #14033
Split out of #13856 by the domain:services PM seat (#6021) at dispatch. #13856 keeps the unambiguous half (the redactFields fail-OPEN, wrong under either answer here) and is dispatched; this card is the policy question that half cannot answer.
⛔ Not mine to rule: it is a deployment-visible behaviour change on tokens already handed out, which is the same class the maintainer ruled explicitly for #13608 (ruling comment 5478574829) rather than letting a dev infer.
The question
ShareLinkService.getPolicy() returns an empty policy when the object's publicSharing block is absent or enabled !== true. Nothing in resolveToken() reads policy.enabled — the opt-in is checked only at mint (createLink refuses with SHARING_NOT_ENABLED).
⇒ Turning the object-level opt-in OFF does not stop anonymous serving of tokens already handed out.
Two defensible answers, and #13856's filer named both:
A — de-opt-in is a standing policy (links die). Symmetric with what #13608 just landed for eligibility. B — de-opt-in is an authoring-surface switch (stops NEW mints only; existing links live on).
⭐ Why this is now sharper than when #13856 filed it
#13608 shipped on 2026-09-01 (PR #13857, fc9ba76a5). Its maintainer ruling made publicSharing.**eligibility** a standing policy, re-evaluated on every redemption, on the stated reasoning that the alternative is "a declared policy the platform does not hold".
eligibility is a child key inside the publicSharing block. So the platform now holds this shape:
declaration
when enforced
publicSharing.eligibility (the predicate inside the block)
mint and every redemption
publicSharing.enabled (the switch that governs the whole block)
mint only
⇒ Tightening a predicate inside the block kills existing links, while turning the entire block off does not. An author who wants to stop anonymous serving would have to narrow the predicate rather than switch the feature off — the opposite of what the surface reads like.
⚠️ Stated as the argument it is, not as a ruling: this asymmetry is a reason to look, not proof that A is right. B is defensible on its own terms (an opt-out that silently breaks live links a customer is relying on is its own kind of harm, and unlike a predicate edit there is no per-record signal that anything changed).
Independent corroboration that the switch is load-bearing
The #13857 contract review reached the same seam from the contract side, unprompted, and recorded it as a scoped observation:
enforcement is governed by the parent publicSharing.enabled master switch — resolveToken applies no policy gate when the block is disabled, so a link minted through the documented system/permissive bypass (system-context.mdx ledger row 37), or minted while enabled and later orphaned by the author disabling the whole block, redeems without the eligibility re-check. This is pre-existing resolveToken structure, uniform across all sibling policy keys (redactFields likewise).
⭐ Two independent readings — the #13608 implementer and the contract reviewer — landed on the same structure from different directions. That is what makes it worth a ruling rather than a note.
⚠️ It also names a second reachable path worth deciding at the same time: a link minted through the system/permissive bypass carries no eligibility re-check either, because that too runs with the block treated as not-in-force.
⛔ Not established how many live links sit on disabled blocks in any real deployment — that is a deployment query (sys_share_link joined against the objects' current publicSharing.enabled), not answerable from this repo. ⚠️ Do not size the remedy from an in-repo zero.
Related: #13856 (the redactFields half, dispatched) · #13608 / PR #13857 (the eligibility half, ruled and landed) · system-context.mdx ledger row 37 (the bypass path)
Split out of #13856 by the
domain:servicesPM seat (#6021) at dispatch. #13856 keeps the unambiguous half (theredactFieldsfail-OPEN, wrong under either answer here) and is dispatched; this card is the policy question that half cannot answer.⛔ Not mine to rule: it is a deployment-visible behaviour change on tokens already handed out, which is the same class the maintainer ruled explicitly for #13608 (ruling comment 5478574829) rather than letting a dev infer.
The question
ShareLinkService.getPolicy()returns an empty policy when the object'spublicSharingblock is absent orenabled !== true. Nothing inresolveToken()readspolicy.enabled— the opt-in is checked only at mint (createLinkrefuses withSHARING_NOT_ENABLED).⇒ Turning the object-level opt-in OFF does not stop anonymous serving of tokens already handed out.
Two defensible answers, and #13856's filer named both:
A — de-opt-in is a standing policy (links die). Symmetric with what #13608 just landed for
eligibility.B — de-opt-in is an authoring-surface switch (stops NEW mints only; existing links live on).
⭐ Why this is now sharper than when #13856 filed it
#13608 shipped on 2026-09-01 (PR #13857,
fc9ba76a5). Its maintainer ruling madepublicSharing.**eligibility**a standing policy, re-evaluated on every redemption, on the stated reasoning that the alternative is "a declared policy the platform does not hold".eligibilityis a child key inside thepublicSharingblock. So the platform now holds this shape:publicSharing.eligibility(the predicate inside the block)publicSharing.enabled(the switch that governs the whole block)⇒ Tightening a predicate inside the block kills existing links, while turning the entire block off does not. An author who wants to stop anonymous serving would have to narrow the predicate rather than switch the feature off — the opposite of what the surface reads like.
Independent corroboration that the switch is load-bearing
The #13857 contract review reached the same seam from the contract side, unprompted, and recorded it as a scoped observation:
⭐ Two independent readings — the #13608 implementer and the contract reviewer — landed on the same structure from different directions. That is what makes it worth a ruling rather than a note.
What a ruling needs to settle
enabled.publicSharing.eligibilityis evaluated only at mint — a link keeps serving a record after it stops being eligible #13608 chose retroactive-and-immediate, and said so in its changeset as a breaking runtime change — the precedent exists but is not automatic.redactFieldssits under the same switch. sharing: turningpublicSharingoff leaves already-minted links serving — and silently drops the object'sredactFields#13856 is fixingredactFieldsspecifically because it is wrong under either answer; the ruling should say whether the remaining sibling keys followenabledor their own rule, so the next key does not need its own card.Not established
publicSharingoff leaves already-minted links serving — and silently drops the object'sredactFields#13856's filer read this from source and said so; nothing was run. Whoever implements the ruling measures first.sys_share_linkjoined against the objects' currentpublicSharing.enabled), not answerable from this repo.Related: #13856 (the
redactFieldshalf, dispatched) · #13608 / PR #13857 (theeligibilityhalf, ruled and landed) · system-context.mdx ledger row 37 (the bypass path)Generated by Claude Code