Repository navigation
fix(app-shell): a server error at an RLS clause's path holds the permission-set autosave - #27612
Merged
Merged
Conversation
… a CEL clause's path The draft read's verdict reached the RLS clause's display (objectstack#26858) but never the count that holds the autosave, so a predicate the publish refuses kept saving. The clause now reports the served errors at its own path as blocking while it still shows the text that verdict judged. Claude-Session: https://claude.ai/code/session_01Utp6CaN9smHqkJcUWF4adR Co-authored-by: Claude <noreply@anthropic.com>
…s the CEL autosave) Claude-Session: https://claude.ai/code/session_01Utp6CaN9smHqkJcUWF4adR Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Utp6CaN9smHqkJcUWF4adR Co-authored-by: Claude <noreply@anthropic.com>
Contributor
Author
|
domain:ui#3 · os-bill · session_01Utp6CaJoinvGQSbHeDaWBe 席位核对ACCEPT · head
Generated by Claude Code |
This was referenced Oct 29, 2026
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.
Requested by Bill · project thread
维护者速读
CelPredicateField.tsx的report与heldKey效果;draftVerdict.ts的serverHoldAt;PermissionMatrixEditor.tsx里与servedVerdict同步设置的servedVerdictBody。pnpm --dir ui exec vitest run packages/app-shell/src/views/metadata-admin/PermissionMatrixEditor.serverVerdictHold-27482.test.tsx,预期 4 条全绿。Part of #27482
Clause-②: no
Metadata-protocol: none
This closes the RLS arm of the card. The Validations-tab arm is not done here and is listed under Acceptance notes, so the merge must not close the card.
What changes
draftVerdict.ts: a second context,DraftVerdictBodyContext, carries the body the served verdict judged.valueAtPathreads a dotted_diagnosticspath in that body, andserverHoldAt/useServerHoldAtanswer the served errors at a field's path only while the field shows the text that body holds there. No rule is restated: the server's errors are taken whole.CelPredicateField.tsx: a field with averdictPathreports those held server errors throughonLintChangeas blocking errors, beside its lint findings. It re-reports when the hold starts, changes or lapses, keyed on the messages rather than on the array identity. Display is unchanged.PermissionMatrixEditor.tsx:servedVerdictBodyis set besideservedVerdictat each of its three reads (the load, the package door's post-save draft read, the environment door's post-save layered read) and provided to the RLS facets. The existing count,celErrorCount, now includes those errors, so the package door's autosave holds and the environment door's Save is disabled.Why
The draft read's
_diagnosticsreached the RLS clause's display (#26858) but nevercelErrorCount, so a predicate the publish refuses (a USING over a formula field,rls-predicate-unenforceable) kept autosaving with the server's message on screen. Triage asked for exactly this: a server error at the field's own path counts incelErrorCount, with no second client copy of the publish rule.The verdict judges the stored draft and nothing else, and no door judges a text without storing it. Holding every edit while an error stands at the path would deadlock: the corrected clause could never be saved, so the next draft read could never clear it. So the hold applies while the clause still shows the judged text. Editing the clause away lets that one save go out, and its re-read brings the next verdict.
Tests
PermissionMatrixEditor.serverVerdictHold-27482.test.tsx(new, 4 cases, fake door decides the refusal): (a) a stored refused draft holds another edit, no PUT, message stays; (b) the card flow: the refused clause saves once, its re-read holds the next edit; (c) editing the clause away releases, the save goes out and its clean re-read clears the verdict; (d) typing back to the judged text before the autosave fires is held again, no PUT.draftVerdict.test.ts: four new cases forvalueAtPathandserverHoldAt(judged text holds, other text does not, no body / no path / no error at that exact path holds nothing, an absent value reads as empty text).Acceptance notes
ui/packages/app-shell/src/views/metadata-admin/draftVerdict.ts, the home of the served-verdict helpers.PermissionAdvancedFacets.tsxis untouched: the held errors ride the existingonLintChangereport.ObjectValidationsPanel's per-rule map, reported throughonBlockingIssuesChangeto the Data pillar's Save gate), but no server verdict reaches the Data pillar at all.DataPillarinStudioDesignSurface.tsxreads the object draft throughreadDraftForSave(client, 'object', …)and keeps onlyextractDraftBody, dropping_diagnostics; it provides noDraftVerdictContext, andConditionBuilderpasses noverdictPathto itsCelPredicateField. Wiring it is: keep the object draft read's_diagnosticsand body inDataPillar(load and post-save), provide both contexts, and giveConditionBuilderaverdictPathper rule. The hold then applies with no further change to the field. The server's path spelling for a validation rule's condition is not measured here. That region belongs to a sibling card in flight, so it is left to a follow-up.perm.cel.saveBlocked("Fix the CEL syntax errors before saving."), which also covers this server-verdict hold; the field itself shows the server's message. Rewording it is left alone (the studio namespace is in a sibling card's diff).whenconditions in the permission matrix pass noverdictPath, so they show and hold no server verdict, as before.Verification
Readings name the commit they ran on.
Tests
CelPredicateField,draftVerdictorConditionBuilder): 92 files, 811/811 passed.pnpm --filter @object-ui/app-shell type-check: exit 0.origin/mainmerged, install and the app-shell dependency closure rebuilt): the same 92 files, 811/811 passed;type-checkexit 0.Ablations (each committed first, mutated through scripts/ablation-replace.mjs, restored with blob == HEAD and an empty git diff HEAD)
CelPredicateField.tsx, the report ignores the held server errors (the anchorserver.length === 0made always true): cases (a), (b), (d) red, (c) green. Expected: (c) is the release path.draftVerdict.ts, the hold ignores the text (the judged-text comparison replaced by a constant true): the unit case "holds on the judged text, and not on any other" red and integration case (c) red, the deadlock this design avoids. Everything else green.Derived gates
node scripts/pm/dispatch-gates.mjs --commandson this diff: 34 families, all run, all exit 0 (--ranreconciliation: 34 derived, 34 run, 0 NOT-MEASURED).node scripts/check-sdui-manifest.mjsexit 0.pnpm check:new-line-citations(ui): 0 new citations. Every family CI runs is read from this PR's check runs.Human Minimum
packages/specholds no runtime logic. (No spec change.)pnpm lintpasses on the changed files (eslint, see the report).main, one pull request.packages/spectouched: not touched.content/docs/references/,packages/*/CHANGELOG.mdorcontent/docs/releases/.Generated by Claude Code