Repository navigation
docs(plugin-sharing): state the grantsRefused narrowing, not a spec lag - #18260
Merged
claude[bot] merged 3 commits intoSep 15, 2026
Merged
Conversation
Both comments described a spec/plugin lag that no longer exists: `@objectstack/spec` now declares `grantsRefused?: number` on `SharingRuleEvaluationResult` itself, so "the six declared fields are unchanged" and "the contract lives in `@objectstack/spec` and is another lane's to move" read as if the spec were still behind. It is not. Rewritten to say what is actually true and load-bearing: the subtype REQUIRES the key the spec declares OPTIONAL, which is a legal covariant narrowing and the reason a caller holding the subtype never has to decide whether an unset key means "no grant was refused" or "this implementation does not report refusals". The `grantsRefused > 0` is NOT "the pass failed" paragraph is kept verbatim. Prose only. No type, signature or runtime behaviour changes. Claude-Session: https://claude.ai/code/session_01URLHobLUJB9K1ABV6ofdjj Co-authored-by: Claude <noreply@anthropic.com>
Contributor
📓 Docs Drift Check
What this run could not see
Coarse fallback — 9 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): |
…aring-comments-post-14969
…used prose The published `dist/index.d.ts` moves: the JSDoc on the exported `SharingRuleReconcilePassResult` ships there (705,069 to 705,528 bytes), so this diff is not a `skip-changeset` candidate. The declaration-only projection of that file is byte-identical before and after. Claude-Session: https://claude.ai/code/session_01URLHobLUJB9K1ABV6ofdjj Co-authored-by: Claude <noreply@anthropic.com>
claude
Bot
deleted the
claude/issue-15712-sharing-comments-post-14969
branch
September 15, 2026 05:48
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.
Fixes #15712
Clause-②: no
Prose-only. Since #14969 (delivered by PR #15714)
@objectstack/specdeclaresgrantsRefused?: numberonSharingRuleEvaluationResultitself, which falsified two comments in@objectstack/plugin-sharingthat described a spec/plugin lag. The code is not wrong and is not touched:SharingRuleReconcilePassResult extends SharingRuleEvaluationResult { grantsRefused: number }remains a legal covariant narrowing.Session: https://claude.ai/code/session_01URLHobLUJB9K1ABV6ofdjj
What changed
Line numbers re-derived on this branch's base
cb648cb1b(the card read them on22a006b26):cb648cb1bpackages/plugins/plugin-sharing/src/index.tspackages/plugins/plugin-sharing/src/sharing-rule-service.ts@objectstack/specand is another lane's to move, and every declared consumer keeps compiling against the six fields it always had. The seventh is additive…"Both now state the NARROWING rather than the lag: the spec declares the key OPTIONAL on purpose (an implementation that does not count refusals leaves it ABSENT, and absent is not
0), this implementation always counts them, so the subtype REQUIRES it — which is the reason a caller holding the subtype never has to decide whether an unset key means "no grant was refused" or "this implementation does not report refusals".The load-bearing paragraph is kept verbatim, as the card and the triage comment both demanded:
The card named two instances — the sweep that makes "no others" a measurement
Three greps over
packages/plugins/plugin-sharing/src(every file, tests included), each with the two known-stale blocks as its positive control:SharingRuleEvaluationResult|SharingRuleReconcilePassResult|grantsRefused, comment lines onlyindex.ts:26,sharing-rule-service.ts:145keeps compiling|rides along|additive|declared fields|declared consumerindex.ts:27-28,sharing-rule-service.ts:147-148@objectstack/specnamed in a commentsharing-rule-service.ts:146Plus a count/ownership sweep (
\b(six\|sixth\|seven\|seventh)\b,another lane\|lane's\|to move\|contract lives\|not ours). Everything the sweeps returned beyond the two blocks was read and is unaffected by #14969:sharing-rule-service.ts:151and:1723— the two survivinggrantsRefusedsentences; both describe the pass's behaviour, not the spec's shape. Kept.sharing-plugin.ts:1163— "six suites inplugin-security" is aboutbuildSharingMiddleware'smessageTranslatorcallers, a different six.exec-context-annotation.pin.ts,bu-tree-recompute.ts,objects/sys-sharing-rule.object.ts,field-recipient.test.ts,logger-shapes.ts— unrelated counts (a retired six-field exec-context shape, six hooks, six access levels, a seven-point executor contract, seven module-local logger interfaces).Repo-wide, outside the package:
packages/client/src/index.tstypesshares.rules.evaluateasSharingRuleEvaluationResultand carries no prose about its shape;docs/qa/platform-checklist/areas/access-security.jsonnames the body, not the field count. The only other text describing the lag is inpackages/plugins/plugin-sharing/CHANGELOG.md(entries 563-592), which is a historical release record and correct as of the release it describes — ⛔ not edited.Acceptance notes
backfillRuleGrants(sharing-plugin.ts) never readsgrantsRefused; it counts reconciled rules and returns anumber. That half was already inaccurate before spec: liftgrantsRefused?: number(optional) intoSharingRuleEvaluationResultso the SDK type stops lagging the wire by one key #14969. Since the whole sentence was being replaced anyway, the rewrite simply does not carry the claim forward, and names the consumers that are real: this package's own pins, andPOST /api/v1/sharing/rules/:idOrName/evaluate, which answerssvc.evaluateRule(…)unfiltered (rest-server.ts,res.json(result)).SharingRuleReconcilePassResultis still worth keeping as a named export is the same lane's judgment and is ⛔ not decided here. [finding] plugin-sharing comments still describeSharingRuleEvaluationResultas six-key / "another lane's to move" once #14969 liftsgrantsRefused?into the spec #15712 asks for prose only.Verification
All readings below are from branch tip
bd8f35bb8— this branch's merge oforigin/mainatfd1247142, plus the prose commit and the changeset commit.Gate denominator.
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackderived 59 families from the change set. (The first derivation, taken before the merge, printedSTALE TREEbecausescripts/pm/check-clause2-carriers.mjshad moved onmain; it was discarded and re-derived on the merged tree, which prints no staleness line.) All 59 were run with the exit code captured before any pipe, then reconciled back through--ranwith the codes attached:derived 59 / run 59 / NOT MEASURED 0 / UNRUN 0. Every family exited
0. No family exited3(PREREQUISITE NOT MET), so nothing here is a prerequisite miss being read as a pass. Slowest four:check:slot-lookup106s,check-comment-mask-corpus78s,check:dual-build-cjs-loads37s,check:i18n32s.Package lap (through
scripts/pm/os-verify-lock.sh, verdict lines quoted, never a bare exit code):pnpm turbo run build --filter='!@objectstack/docs' --concurrency=2VERDICT command-exit 0— 73 successful, 73 totalpnpm --filter @objectstack/plugin-sharing exec vitest run --maxWorkers=2VERDICT command-exit 0— 37 files, 910 tests passedpnpm --filter @objectstack/plugin-sharing typecheckVERDICT command-exit 0— includescheck:test-typecheck, which reports the test layer compiles and the debt ledger is unchanged (2 files / 3 errors / 3 pinned signatures)Import-side packages are not owed tests: the published surface does not change by a byte (measured below).
Repo-wide lint — run, not narrowed.
pnpm lint(eslint . --no-inline-config) exited0onbd8f35bb8. It fit inside the foreground cap, so no narrowing had to be declared.Published-artifact measurement — the changeset decision, not an assumption. The prose commit was built, the two sources were restored to their base blobs with
git checkout HEAD~1 --, rebuilt, and the resultingdist/index.d.tscaptured; then restored withgit checkout HEAD --and rebuilt. The restore leg is proved by a whole-treegit status --porcelain(empty) and by blob identity — diskgit hash-objectequalsgit rev-parse HEAD:pathfor both files, non-empty on both sides.dist/index.d.ts.d.tsis 705,069 bytes before and 705,528 after — published bytes move, soskip-changesetis not available and.changeset/15712-sharing-grants-refused-narrowing-prose.mddeclares apatchon@objectstack/plugin-sharing.dist/index.jsanddist/index.mjscontain neither the old nor the new prose: the compiler strips comments from the JavaScript outputs, so only the two.d.ts/.d.mtsfiles move.index.tshalf of this diff is a//comment inside an export list, and it does not reach the published payload at all (both markers read 0 in both builds). Thesharing-rule-service.tsJSDoc is the half that ships.Clause-② — re-derived from the delivered diff, by reachability from the published entry.
interface SharingRuleReconcilePassResultis declared atdist/index.d.ts:11920— the touched symbol IS reachable from the published entry, so the instrument can see itdeclare const ENGINE_ORGANIZATION_REFUSAL_CODEreads 0 in the same file — a module-local const in the same edited source is NOT reachable, so the instrument is not answering "yes" to everything⇒
Clause-②: no, andnode scripts/pm/check-clause2-carriers.mjs --pair 18260agrees independently: exit 0 — "the clause-② declaration is readable in the fixed spelling and both carriers agree, and its diff carries no widening tell".Control characters.
grep -naPover the edited files and the changeset for the C0 set plus DEL: no hits.pnpm check:nul-bytesis one of the 59 green families.Generated by Claude Code