Skip to content

fix: per-player permission sync — push + member-mapping UI + match warnings + DM-only clarity#67

Merged
keyxmakerx merged 1 commit into
mainfrom
claude/gallant-johnson-kd574n
Jun 21, 2026
Merged

fix: per-player permission sync — push + member-mapping UI + match warnings + DM-only clarity#67
keyxmakerx merged 1 commit into
mainfrom
claude/gallant-johnson-kd574n

Conversation

@keyxmakerx

Copy link
Copy Markdown
Owner

Cites: 2026-05-21-core-tenets §T-B1 (fail-closed visibility); reports/coordinator/2026-06-21-permission-sync-audit.md §1A/§2/§3/§5.
Security implication: all new paths fail CLOSED — unmapped users are dropped on both push and pull (never over-shares), and every mismatch is now surfaced instead of silently widening access.

What this changes

Closes the per-player permission-sync gaps. Pairs with Chronicle PR #488 (which makes permission changes broadcast) — both are needed for a Chronicle custom-permission change to fully reflect in Foundry.

  • Per-user push (Foundry→Chronicle): journal ownership now sends per-user grants (reverse-mapped via getChronicleUserId), not just a coarse role grant; visibility:'custom' only when real user grants exist; unmapped users skipped (never over-share).
  • Members mapping UI + match warnings (the operator's must-have): a new Members dashboard tab lists every Chronicle member with a Foundry-user dropdown + matched/UNMATCHED badge (persists via setUserMappings); on connect, a visible warning (ui.notifications + dashboard log) lists every member that couldn't be auto-matched — no more silent drops.
  • Silent-failure surfacing: dropped grants, fail-closed-to-NONE on a permissions-API error, per-user push failures, and members-fetch failures now warn in the dashboard/notifications.
  • DM-only clarity: the Status tab shows "N DM-only entities synced (hidden from players per the setting)" so correctly-hidden private content isn't mistaken for "didn't sync."
  • Consume public/tag_grants in _buildOwnership (only ever widens toward intent; fail-closed preserved).

Test plan

  • node --test full suite: 485 pass, 0 fail (+24 new tests)
  • CI confirms

🤖 Generated with Claude Code

https://claude.ai/code/session_01Y14Y6VXb7iB2xcNrYNDJa5


Generated by Claude Code

…-error surfacing

Closes the per-player permission gaps from the 2026-06-21 permission-sync
audit. Fail-CLOSED posture preserved: ambiguity always resolves toward LESS
player visibility.

1. Per-user grant PUSH (Foundry→Chronicle). journal-sync _buildPermissionGrants
   (new pure helper) reverse-maps each Foundry per-user ownership entry to a
   Chronicle {subject_type:'user', subject_id, permission} grant via
   getChronicleUserId (level >= OWNER -> edit, else view). _pushPermissions
   sends visibility:'custom' only when real user grants exist; unmapped Foundry
   users are skipped (never over-shared) and surfaced.

2. Manual mapping UI + match-error surfacing (operator must-have). New dashboard
   Members tab lists every Chronicle member with a Foundry-user dropdown +
   matched/UNMATCHED badge, persisting via setUserMappings. On connect,
   fetchAndCacheMembers now emits a visible ui.notifications.warn + dashboard
   warning listing every member that could NOT be auto-matched (previously
   silently skipped). memberKey() is the single source of truth for the
   member->mapping key.

3. Surface the other silent permission-sync failures (audit section 3): dropped
   unmapped grant in _buildOwnership, fail-closed-to-NONE permissions-API error,
   per-user push failures, and members-fetch failure now log a dashboard
   warning/error + notify where user-facing.

4. Clarify the perception gap (audit section 1A): noteDmOnlyHidden /
   getDmOnlyHiddenCount track private entities that synced but landed
   hidden-from-players; Status tab shows the count so it isn't mistaken for
   "didn't sync."

5. Consume tag_grants + public in _buildOwnership: a public grant maps to an
   OBSERVER/OWNER default (never lowers a higher grant); tag_grants are surfaced
   as a warning since Foundry can't expand them to users.

Tests: tools/test-permission-sync.mjs (push grant-building, memberKey, unmatched
warning, member-row view-model) + new cases in tools/test-build-ownership.mjs.
Full suite green (485 tests).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y14Y6VXb7iB2xcNrYNDJa5
@keyxmakerx keyxmakerx merged commit f7cd718 into main Jun 21, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants