docs: capture today's Pres Mgmt config sync lessons for future agents
- BOOTSTRAP__AI_Agent_Quickstart.md: new category 9 under Common Mistakes pointing to today's incident (local/remote config sync pitfalls) - REFERENCE__Common_Agent_Mistakes.md: three new entries — 16) local "shadow field" silently bypasses an admin-synced master field 17) SWR await after a write does not mean dependent caches are fresh 18) conditional/stateful sync gates are effectively undebuggable - PROJECT__Stores_Svelte5_Migration.md: updated the canonical Migration Pattern example to stamp __version in the serializer (the old example silently didn't, which is exactly what caused the leads_loc/pres_mgmt_loc bugs fixed today); flagged badges_loc/launcher_loc/events_auth_loc as not yet fixed (dormant, not harmful) and idaa_loc as the next migration that should get this from day one - TODO__Agents.md: cross-referenced today's Pres Mgmt config sync overhaul in the LCI October restoration section for context, without touching the open items in that list Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -150,6 +150,63 @@ Review policy: balanced curation.
|
||||
|
||||
**Verify:** After deploy, validate that long-lived tabs pick up new SW behavior as intended.
|
||||
|
||||
### 16) Local "shadow field" silently bypasses the admin-synced master field
|
||||
**Impact:** an admin config toggle appears to do nothing — the UI updates fine when a local
|
||||
per-browser preference is clicked, but the actual admin setting has zero effect, at any
|
||||
permission level. Looks like a permissions bug; isn't one.
|
||||
|
||||
**What happened:** A list/table column's visibility prop was computed from only a local-only,
|
||||
never-synced preference field (e.g. `hide__session_li_location_field`), while a
|
||||
similarly-named, admin-synced field (`hide__session_location`) existed and was correctly
|
||||
synced — just never read at that particular render call site. Found twice in the same
|
||||
session (Pres Mgmt POC column, then Location column).
|
||||
|
||||
**Rule:** When a remote config field and a local-only preference field could plausibly both
|
||||
affect the same visible thing, combine them explicitly (`admin_field || local_field`) at
|
||||
*every* call site that renders that thing — don't assume one supersedes the other, and don't
|
||||
assume fixing it once means every other render site is also fixed.
|
||||
|
||||
**Verify:** `grep` every consumer of the field name (and near-miss siblings, e.g. `_li_`/`_field`
|
||||
suffixed variants) before trusting that a config toggle does what its label says.
|
||||
|
||||
### 17) SWR `await` after a write does not mean dependent caches are fresh
|
||||
**Impact:** a value you just saved appears stale or "one save behind" immediately after
|
||||
saving — looks like inverted/random behavior when toggling a boolean back and forth, since
|
||||
being one step behind on a 2-state toggle looks exactly like being inverted.
|
||||
|
||||
**What happened:** A save handler `await`ed `load_ae_obj_id__event()` (SWR) and assumed that
|
||||
meant Dexie now had the fresh record. In reality the fast path returns the stale cache
|
||||
immediately and refreshes Dexie via a non-awaited background fetch. A *different* page's own
|
||||
sync `$effect` read Dexie before that background fetch landed, re-syncing from the stale
|
||||
record and overwriting a value that had just been set correctly moments earlier.
|
||||
|
||||
**Rule:** After a write whose result other reactive code depends on, don't rely on an awaited
|
||||
SWR reload to mean downstream caches are updated — for any call with a populated cache, it
|
||||
almost never is. Update dependent local state directly from the data you already have (what
|
||||
you just saved), not by waiting on a refetch. See the "try_cache: false Bug" section of
|
||||
`GUIDE__SvelteKit2_Svelte5_DexieJS.md` for the related, equally counter-intuitive case where
|
||||
disabling caching *also* disables the very write you wanted.
|
||||
|
||||
### 18) Conditional ("locked") sync gates are effectively undebuggable
|
||||
**Impact:** a field's local value silently depends on the *history* of an unrelated flag's
|
||||
state across past syncs, not its current value — looks like inconsistent behavior tied to
|
||||
permission level, browser, or test sequence, none of which is the actual cause.
|
||||
|
||||
**What happened:** `sync_config__event_pres_mgmt()` only applied a subset of fields when a
|
||||
separate `lock_config` flag was `true` *at that exact sync call*. Toggling `lock_config` off
|
||||
even briefly during testing froze those fields at stale values in every browser that synced
|
||||
during that window, with nothing in the UI indicating staleness. Removed entirely — every
|
||||
event already had it set to `true` in production; the conditional gated nothing real.
|
||||
|
||||
**Rule:** Avoid making one config field's sync conditional on another field's *current*
|
||||
value unless that's a genuine, deliberate design choice — and if it is, surface the
|
||||
dependency in the UI (disable the inputs, show a warning), don't bury it in a silent
|
||||
function-level gate.
|
||||
|
||||
**Verify:** Before adding `if (some_flag) { ...many field syncs... }`, check whether removing
|
||||
the gate (sync unconditionally) loses any real behavior — query production data for whether
|
||||
the gate is ever actually in the "off" state before assuming it needs to exist.
|
||||
|
||||
---
|
||||
|
||||
## Archived Historical Items (Pruned)
|
||||
|
||||
Reference in New Issue
Block a user