Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions docs/ledger/rows/NAV-QUEST-VISIBILITY.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"id": "NAV-QUEST-VISIBILITY",
"title": "Restore My Quest access for every authenticated member by repairing its exact stale page setting",
"lane": "live",
"priority": "P1",
"size": "S",
"status": "open",
"source": {
"file": "scripts/ops/repair-root-quest-page-visibility.sql",
"ref": "Read-only Frequency Community root page_settings metadata and current admission source, 2026-11-04."
},
"detail": "Actual authenticated /crew redirected to /feed. Production metadata confirms exactly one root Space and its /crew page_settings row is published, visibility_role=crew, updated_at=2026-06-22 15:21:37.887+00. The community crew rung is retired and separate from paid Crew entitlement. Current Quest matrix and docs/ROLES.md grant every signed-in member full Quest access, while the shared layout still honors this stale operator visibility gate. PROPOSAL ONLY: exact operator transaction resolves one root, locks only /crew, refuses unless status/visibility/updated_at still match this reviewed snapshot, sets native visibility_role NULL (any authenticated member) and updated_at, verifies one row and unchanged remaining columns. No generic page gate, auth, RLS, role or unrelated route changes. The exact SQL passed eleven disposable PGlite 0.4.0 / PostgreSQL 17.5-compatible fixture cases, including unchanged unrelated rows and rollback/refusal cases; this is not hosted Supabase equivalence. Fresh compare-and-set preflight, exact main-committed SQL hash review/authorization and actual production postconditions are still required before any production execution. Never execute twice; an already-null or changed row refuses. Acceptance: authenticated member /crew reaches My Quest, guest remains signed out, other host-only/draft routes and other Space settings stay enforced.",
"verify": {
"kind": "manual",
"checked": "2026-11-04",
"evidence": "Read-only production gate/schema metadata confirms PK(space_id,route), nullable text visibility_role, published root /crew with crew restriction and exact updated_at. Unchanged committed operator SQL SHA-256 258956ee13d656f2b67959fc9a4c3c15690dc3e6a1740d0ced9d2127e1e43cec passes eleven isolated PGlite/PostgreSQL 17.5-compatible scenarios: valid one-row repair with other tenant/host/draft rows unchanged; missing/stale/wrong/already-cleared/ambiguous targets and unexpected target-column trigger changes refuse/roll back. Nine actual-source gate/nav controls keep other draft/host gates and Admin/preview framing intact. This is fixture/source proof, not hosted Supabase/browser/session evidence. Production operator SQL NOT EXECUTED and no setting changed. Keep open until fresh authorized repair/postconditions and member/guest production proof."
},
"wave": "W7"
}
62 changes: 62 additions & 0 deletions scripts/ops/repair-root-quest-page-visibility.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
-- PROPOSAL ONLY. Do not run before this exact file is reviewed, committed on main and authorized.
-- Restore the existing everyone-plays contract for authenticated members at root /crew only.
-- Native visibility_role=NULL means any signed-in member; it does not make /crew public.
-- Fresh metadata before execution must still match the observed compare-and-set token below.
-- A second execution, a changed row, missing/duplicate root or any unexpected side effect REFUSES.
begin;
set local lock_timeout = '3s';
set local statement_timeout = '15s';
do $repair$
declare
target_space uuid;
root_count integer;
target_count integer;
before_row jsonb;
after_row jsonb;
affected integer;
expected_updated_at constant timestamptz := '2026-06-22 15:21:37.887+00';
begin
select count(*) into root_count from public.spaces where type = 'root';
if root_count <> 1 then
raise exception 'QUEST-PAGE-VISIBILITY: expected one root Space, found %; refusing', root_count;
end if;
select id into strict target_space from public.spaces where type = 'root';

select count(*) into target_count from public.page_settings
where space_id = target_space and route = '/crew';
if target_count <> 1 then
raise exception 'QUEST-PAGE-VISIBILITY: expected one root /crew row, found %; refusing', target_count;
end if;

select to_jsonb(p) into strict before_row
from public.page_settings p
where p.space_id = target_space and p.route = '/crew'
for update;
if before_row is null
or before_row->>'status' is distinct from 'published'
or before_row->>'visibility_role' is distinct from 'crew'
or (before_row->>'updated_at')::timestamptz is distinct from expected_updated_at then
raise exception 'QUEST-PAGE-VISIBILITY: reviewed root /crew preconditions changed; refusing';
end if;

update public.page_settings
set visibility_role = null, updated_at = now()
where space_id = target_space and route = '/crew'
and status = 'published' and visibility_role = 'crew'
and updated_at = expected_updated_at;
get diagnostics affected = row_count;
if affected <> 1 then
raise exception 'QUEST-PAGE-VISIBILITY: changed % rows, expected one; rolling back', affected;
end if;

select to_jsonb(p) into after_row from public.page_settings p
where p.space_id = target_space and p.route = '/crew';
if after_row->>'status' is distinct from 'published'
or after_row->>'visibility_role' is not null
or (after_row - 'visibility_role' - 'updated_at') is distinct from
(before_row - 'visibility_role' - 'updated_at') then
raise exception 'QUEST-PAGE-VISIBILITY: unexpected postcondition; rolling back';
end if;
end
$repair$;
commit;
Loading