diff --git a/browse/js/events.js b/browse/js/events.js
index 90bf600..ee52c78 100644
--- a/browse/js/events.js
+++ b/browse/js/events.js
@@ -792,6 +792,13 @@
function openPartyPicker(opts) {
return new Promise(function (resolve) {
var kindWord = opts.kind === 'folder' ? 'folder' : 'file';
+ // The "+ New party" affordance is gated on create authority over ssr/
+ // (pre-checked in createInAggregator). When denied, disable it and say
+ // who can — role-first text inline, the specific people in the tooltip.
+ var newPartyAllowed = opts.canNewParty !== false;
+ var newPartyNote = newPartyAllowed ? '(registers a new party)'
+ : (opts.newPartyHint && opts.newPartyHint.text) || 'You can’t register a new party here.';
+ var newPartyTitle = (!newPartyAllowed && opts.newPartyHint && opts.newPartyHint.title) || '';
var overlay = document.createElement('div');
overlay.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.4);display:flex;align-items:center;justify-content:center;z-index:9000;';
var box = document.createElement('div');
@@ -810,10 +817,10 @@
'Pick the party this ' + kindWord + ' belongs to — it lands under ' + escapeHtml(opts.slot) + '/<party>/.' +
'