Repository navigation
fix(plugin-sharing): recipient_id declares object_name, the second sibling its picker reads - #19505
Conversation
…bling its picker reads `sys_sharing_rule.recipient_id` declared `dependsOn: ['recipient_type']` while its `recipient-picker` widget reads TWO siblings: `recipient_type` picks the mode, and the `field` recipient kind (#15072) reads `object_name` to offer that object's user-valued columns. The neighbouring `criteria_json` field already declares `dependsOn: ['object_name']` for its `filter-condition` widget, so the key is live and correctly used a few lines up — the omission was an omission, not a key nobody uses. Nothing breaks today only because the form renderer passes `dependentValues` as the whole watched record instead of a `dependsOn`-scoped slice. A renderer that ever scoped it — which is what this declaration asks for — would drop the object name and degrade the `field` recipient mode to a plain text input in silence. Also corrects the `recipient_id` docblock: the pinned console (`.objectui-sha` 87af769e) includes objectui#10049, so the picker DOES have a mapping for the `field` kind and no longer degrades to its text input for it. Claude-Session: https://claude.ai/code/session_01AhQASwqJr2Z7XfGWUdvnbF Co-authored-by: Claude <noreply@anthropic.com>
📓 Docs Drift CheckThis PR changes 1 package(s): 5 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
⛔ 2 release-owned page(s) also name something this change touched. These are read-only:
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): 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 151d17fa3d323b9d15cc3181747d7d24fea766a5 && git checkout 151d17fa3d323b9d15cc3181747d7d24fea766a5
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 2cac3636cab1cecef8f7a0453e4963dd1d01fb21 5e794538b29eef74c491f510ad67c9d5c9d52c2d && git checkout -B drift-repro 2cac3636cab1cecef8f7a0453e4963dd1d01fb21 && git merge --no-ff 5e794538b29eef74c491f510ad67c9d5c9d52c2d
node scripts/docs-audit/affected-docs.mjs --json 2cac3636cab1cecef8f7a0453e4963dd1d01fb21
|
Fixes #19258
Clause-②: no
sys_sharing_rule.recipient_iddeclareddependsOn: ['recipient_type']while itsrecipient-pickerwidget reads two siblings. It now declares both.The three readings, taken first-hand on today's head (
4045781fa, worktree base)recipient_id.dependsOnbefore this PR —packages/plugins/plugin-sharing/src/objects/sys-sharing-rule.object.ts:197['recipient_type']criteria_json.dependsOnat line 156, for itsfilter-conditionwidget['object_name']packages/fields/src/widgets/RecipientPickerField.tsx:150,152dependentValues.recipient_typeanddependentValues.object_nameReading 2 is the judgement: the key is live and used correctly a few lines up, for the very same
object_namedependency, by a widget in the same form. So this was an omission, not a key nobody uses.Reading 3 was taken in objectui at
befd40ccand re-taken at this repo's pinned.objectui-sha87af769e— the picker readsobject_nameat the pin too, so the dependency is live in the console this repo actually ships.Why nothing was broken today, and why that is the point
objectui
packages/components/src/renderers/form/form.tsx:3004passesdependentValues: ruleRecord— the whole watched form record, not adependsOn-scoped slice. That is what masked the under-declaration. A renderer that ever scoped it — which is exactly what this key asks for — would drop the object name and degrade thefieldrecipient mode to a plain text input in silence: no error, no empty state, just an admin typing a column name by hand again. The declaration is the only thing that survives that change, so it is what gets fixed.The second half of the fix: the docblock parenthesis, now verified unblocked
The
recipient_iddocblock said the picker "has no mapping for that kind and degrades to its text input". That was conditional on objectui#10049, so it was checked rather than assumed:23b99585, 2026-09-20,feat(fields): give RecipientPickerField a picker mode for the field sharing recipient (objectui#7613).git merge-base --is-ancestor 23b99585 87af769eexits 0 — this repo's pinned console includes it. (Exit 0 is self-proving on a shallow checkout; the control leg, an older known-ancestor commit, also exits 0.)So the parenthesis is false for the console this repo ships, and the docblock now says what the picker actually does: it offers the shared object's user-valued columns, using a "holds users" predicate that is a clause-for-clause copy of this plugin's own
fieldHoldsUsers.Tests
packages/plugins/plugin-sharing/src/field-recipient.test.tsgains three pins in the existing authoring-seams block (which already asserts declaration facts about this same field):recipient_id.dependsOncontainsrecipient_type;recipient_id.dependsOncontainsobject_name;criteria_json.dependsOnstill containsobject_name.Reverse verification — predicted direction: red, and sharply. The fix was committed first (
5e794538b), thendependsOnwas reverted on disk to['recipient_type']throughscripts/ablation-replace.mjs, which proved the mutation landed by anchor counts and blob hash (3b86f89cc43eto158df1894eb5) before running anything:Exactly one pin failed — the
object_nameone. Therecipient_typepin and thecriteria_jsoncontrol stayed green, so the new pin is sharp rather than tautological. Restore verified the way a restore has to be: blob back to3b86f89cc43e== HEAD, andgit diff HEADempty.Other readings, exit codes captured before any pipe:
pnpm --filter @objectstack/plugin-sharing exec vitest run src/field-recipient.test.tspnpm --filter @objectstack/plugin-sharing build && ... typecheckpnpm --filter '@objectstack/plugin-sharing^...' build(dependency closure)pnpm lint(repo-wide,eslint . --no-inline-config)scripts/pm/dispatch-gates.mjs --commandsderived families, all 62 runpnpm check:i18npnpm check:dual-build-cjs-loads,pnpm check:type-check-debtdist, which is CI's build). Not a red and not a green.dispatch-gates --ranwith those exit codes reconciles: 62 derived, 60 run, 2 NOT-MEASURED, 0 UNRUN.Changeset
patchon@objectstack/plugin-sharing. Measured rather than assumed: afterpnpm --filter @objectstack/plugin-sharing build, the changed declaration is present in the publishedfiles[]output —dist/index.jscarriesdependsOn: ["recipient_type", "object_name"], withrecipient-pickeras the positive control (1 hit). So the publish surface moves andskip-changesetdoes not apply.Acceptance notes
widgetis live in this repo on thesys_sharing_ruletrio plussys_permission_set'spermission-facet-link. Of the others:object_name'sobject-refwidget reads no siblings (ObjectRefField.tsxcontains nodependentValuesat all),criteria_json'sfilter-conditionwidget reads exactly theobject_nameit already declares, andpermission-facet-linkreads no siblings either. Sorecipient_idwas the only instance of this defect — nothing else to file.dependsOnon this object before this PR; the three added pins are the first, and they sit in the file that already owns this field's declaration assertions rather than in a new verification surface.packages/specis touched, no renderer behaviour is changed, and nodependentValuesplumbing is changed — this PR moves a declaration and the comment that describes it.Generated by Claude Code