WS9 fix wave: compose firm-visibility with deletion governance (WS8×WS9)

↗ view on GitHub · sloth-ninja · 2026-07-28 · cee6bc61

Composed-range re-review of the WS9 train surfaced five fixes, all in the
WS8×WS9 interaction class (firm visibility reads through rows deletion
governance tombstones; the two seams were never composed):

1. Parent-tombstone gap (important): tombstoning sets only deleted_at, so a
   tombstoned firm-visible matter/review still passed checkProjectAccess /
   ensureReviewAccess, and the content sub-routes (never re-checking the
   tombstone) let any firm member read - and via /generate, /chat WRITE - a
   soft-deleted item for the whole retention window. Folded the tombstone
   check into both helpers (choke point): tombstoned parent => not-ok for
   everyone incl. the owner. 42703-tolerant. Detail-route guards left as
   defence-in-depth. Restore/expedite/list paths verified unaffected.
2. setResourceVisibility now refuses a tombstoned item (.is deleted_at null
   in the predicate => not_found).
3. Audit resource_type unified to hyphenated "tabular-review" for both firm
   actions (flip route + admin revert param mapping); URL/API keep underscore.
4. PeopleModal add-member placeholder gains firm copy when firm surfaces show.
5. Firm-library rows: role=button + tabIndex + Enter/Space + aria-label.

Tests: +11 (backend 511/511). tsc/eslint clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Repository Sloth-ninja/JessicaOSS
Author sloth-ninja <ezanahaddis@gmail.com>
Authored
Parents c59adce3
Stats 14 files changed , +423 , -9
Part of WS9: firm library and firm-level visibility

Capture this commit into my fork

Download a Markdown prompt that tells Claude how to port this exact commit into your working tree. Run it via claude -p < capture-commit-cee6bc61.md from inside the repo you want the change in.

⬇ Download capture-commit-cee6bc61.md