@@ -93,6 +93,13 @@ import { HistoryPanel } from './ResourceHistoryPage.js';
9393import { useMetadataClient , useMetadataTypes , type RichMetadataTypeEntry } from './useMetadata.js' ;
9494// objectui#11773 — the package door's draft save sends the version it was built on.
9595import { readDraftForSave , useDraftSaveGuard } from './DraftConflictDialog.js' ;
96+ // objectstack#26858 — the served verdict the RLS clause editors read at their paths.
97+ import {
98+ DraftVerdictContext ,
99+ draftEnvelopeDiagnostics ,
100+ editedItemDiagnostics ,
101+ type ServerDiagnostics ,
102+ } from './draftVerdict.js' ;
96103// objectui#11787 — the package door autosaves through the pillars' own autosave.
97104import { useDraftAutoSave , type DraftSend } from '../studio-design/useDraftAutoSave.js' ;
98105// objectui#12456 — the Studio Access pillar's presentation draws the shared item header.
@@ -727,6 +734,11 @@ export function PermissionMatrixEditPage({ type, name, packageId, onDraftSaved,
727734 const [ fieldsByObject , setFieldsByObject ] = React . useState < Record < string , FieldSummary [ ] > > ( { } ) ;
728735 const [ expanded , setExpanded ] = React . useState < Set < string > > ( new Set ( ) ) ;
729736 const [ loading , setLoading ] = React . useState ( true ) ;
737+ // objectstack#26858 — the server's verdict on the set on screen: the pending
738+ // draft's while the package door holds one (what its publish will refuse),
739+ // else the layered read's. Taken off each read, never computed here.
740+ const [ servedVerdict , setServedVerdict ] = React . useState < ServerDiagnostics | undefined > ( undefined ) ;
741+ const verdictReadSeq = React . useRef ( 0 ) ;
730742 const [ saving , setSaving ] = React . useState ( false ) ;
731743 // objectui#11787 — when the package door's last draft save landed, for the
732744 // status line that replaces its Save button ("Saved 10:42").
@@ -849,6 +861,14 @@ export function PermissionMatrixEditPage({ type, name, packageId, onDraftSaved,
849861 ] ) ;
850862 if ( cancelled ) return ;
851863 const pendingDraft = pendingRead ?. answer ?? null ;
864+ verdictReadSeq . current += 1 ;
865+ setServedVerdict (
866+ editedItemDiagnostics ( {
867+ hasDraft : ! ! pendingDraft ,
868+ draftDiagnostics : draftEnvelopeDiagnostics ( pendingDraft ) ,
869+ layered : lay ,
870+ } ) ,
871+ ) ;
852872 // ARTIFACT tier input (objectui#4518) — the `code` layer, and its
853873 // `provenance` (objectui#4526), of the SAME envelope the display
854874 // baseline comes from, so the writability verdict and the body on
@@ -1326,6 +1346,13 @@ export function PermissionMatrixEditPage({ type, name, packageId, onDraftSaved,
13261346 // baseline hasn't moved. Show what we just staged.
13271347 resetDraftBaseline ( toDisplayDraft ( toSave ) ) ;
13281348 }
1349+ // objectstack#26858 — the draft this save stored carries its own publish
1350+ // verdict on its next read; the one held described the body before it.
1351+ // Read off the save's path, so a later read (or a load) wins.
1352+ const seq = ++ verdictReadSeq . current ;
1353+ void readDraftForSave ( client , type , payload . name , packageId ) . then ( ( read ) => {
1354+ if ( seq === verdictReadSeq . current ) setServedVerdict ( draftEnvelopeDiagnostics ( read . answer ) ) ;
1355+ } ) ;
13291356 // Let the surface count it.
13301357 onDraftSaved ?.( ) ;
13311358 } else {
@@ -1356,6 +1383,8 @@ export function PermissionMatrixEditPage({ type, name, packageId, onDraftSaved,
13561383 // fallback this line already spelled for the resolved-but-empty
13571384 // (404-shaped) envelope.
13581385 resetDraftBaseline ( toDisplayDraft ( ( lay ?. effective ?? toSave ) as PermissionSetDraft ) ) ;
1386+ verdictReadSeq . current += 1 ;
1387+ setServedVerdict ( editedItemDiagnostics ( { hasDraft : false , draftDiagnostics : undefined , layered : lay } ) ) ;
13591388 setPostSaveRereadFailed ( rereadFailed ) ;
13601389 // The write landed, so the server holds the set now whatever the
13611390 // confirming read said (objectui#7611: its holders can be listed). Only
@@ -2050,17 +2079,19 @@ export function PermissionMatrixEditPage({ type, name, packageId, onDraftSaved,
20502079 { capabilitiesEl }
20512080 </ div >
20522081 < div hidden = { facetTab === null } data-testid = "perm-tabpanel-facets" className = "min-h-0 flex-1 overflow-auto" >
2053- < PermissionAdvancedFacets
2054- draft = { draft }
2055- setDraft = { setDraft }
2056- writable = { writable }
2057- allSetNames = { allSetNames }
2058- loadObjectFields = { loadObjectFields }
2059- onCelErrorsChange = { setCelErrorCount }
2060- t = { t }
2061- only = { facetTab }
2062- packageBound = { ! ! packageId }
2063- />
2082+ < DraftVerdictContext . Provider value = { servedVerdict } >
2083+ < PermissionAdvancedFacets
2084+ draft = { draft }
2085+ setDraft = { setDraft }
2086+ writable = { writable }
2087+ allSetNames = { allSetNames }
2088+ loadObjectFields = { loadObjectFields }
2089+ onCelErrorsChange = { setCelErrorCount }
2090+ t = { t }
2091+ only = { facetTab }
2092+ packageBound = { ! ! packageId }
2093+ />
2094+ </ DraftVerdictContext . Provider >
20642095 </ div >
20652096 </ div >
20662097 ) }
@@ -2222,16 +2253,18 @@ export function PermissionMatrixEditPage({ type, name, packageId, onDraftSaved,
22222253 { /* Advanced facets (ADR-0056 P3) — RLS / tab visibility / delegated
22232254 admin scope, structured editors instead of raw JSON. Collapsed by
22242255 default so they don't crowd the object matrix. */ }
2225- < PermissionAdvancedFacets
2226- draft = { draft }
2227- setDraft = { setDraft }
2228- writable = { writable }
2229- allSetNames = { allSetNames }
2230- loadObjectFields = { loadObjectFields }
2231- onCelErrorsChange = { setCelErrorCount }
2232- t = { t }
2233- packageBound = { ! ! packageId }
2234- />
2256+ < DraftVerdictContext . Provider value = { servedVerdict } >
2257+ < PermissionAdvancedFacets
2258+ draft = { draft }
2259+ setDraft = { setDraft }
2260+ writable = { writable }
2261+ allSetNames = { allSetNames }
2262+ loadObjectFields = { loadObjectFields }
2263+ onCelErrorsChange = { setCelErrorCount }
2264+ t = { t }
2265+ packageBound = { ! ! packageId }
2266+ />
2267+ </ DraftVerdictContext . Provider >
22352268 </ div >
22362269 { /* ADR-0056 P4 — assigning users is a Setup act, so the DESIGN surface
22372270 (Studio, embedded) never shows it. objectui#7611 — the Setup catalog
0 commit comments