docs: restructure bootstrap, add module references, and normalize docs

This commit is contained in:
Scott Idem
2026-06-12 16:48:35 -04:00
parent e05602b87b
commit a227c6aaa7
11 changed files with 511 additions and 237 deletions

View File

@@ -283,246 +283,23 @@ When building anything new, model it after Journals.
---
## 7. Mistakes Agents Have Made on This Project
## 7. Common Mistakes (Reference)
These are real incidents — know them before you start.
The full, curated mistake catalog now lives in
`documentation/REFERENCE__Common_Agent_Mistakes.md`.
1. **IDAA BB exposed publicly** — an agent removed an auth guard from the bulletin board
route. All IDAA content must be behind authentication. Always check route guards when
touching `/idaa/` routes.
Read this section first, then open the reference doc when your task touches one of these areas:
2. **`event_file_id` in PATCH body (400 error)** — including the object ID in `data_kv`
when calling `update_ae_obj__*`. The V3 API tries to `SET event_file_id = ...` which
fails because it's a view alias, not a DB column. See Section 2 above.
1. **Security/Auth**private route guards, account scoping, and pre-gate data load risks.
2. **V3 API payloads** — object ID in URL, `data_kv` field-only PATCH payloads.
3. **Dexie/IDB behavior**`.get()` primary key trap, stale cache/version mismatches, broad result clipping.
4. **Svelte 5 reactivity** — coarse-store `$effect` loops and `$`-sigil misuse on plain props.
5. **Sorting and search correctness**`tmp_sort_*` comparator direction and Dexie sorting caveats.
6. **Network reliability** — retry classification in `api_*_object.ts` and timeout behavior.
7. **JSON field safety**`*_json` null reads/writes and wrapper serialization behavior.
8. **Service worker rollout behavior** — stale-tab symptoms, activation expectations, and trade-offs.
3. **Bad `.d.ts` declaration silently hid 1368 errors** — a `declare module` in `app.d.ts`
(a script-context file) replaced the entire `@lucide/svelte` type exports instead of
merging. `svelte-check` showed 0 errors, masking real problems. If `svelte-check`
suddenly drops to 0 errors, verify it's not because a bad declaration wiped a module.
4. **Coarse store reactivity loop** — an `$effect` that read `$ae_loc.some_field` was
re-triggering repeatedly because unrelated writes to `$ae_loc` (e.g. SWR config reload)
fired the effect. In Svelte 5, any read of a Svelte 4 store inside `$effect` subscribes
to the whole store. Scope what you read carefully.
5. **`file_purpose == 'admin'` not hidden in Launcher** — the `hide_draft` prop hid
`outline` and `draft` files but not `admin` files. Gaps like this happen when a new
enum value is added to a field without auditing all the places that filter on it.
6. **Deleting files with `rm`** — always move to `~/tmp/agents_trash`. A deleted file may
contain context that's not recoverable from git if it was gitignored.
7. **Dexie `.get()` with a string object ID returns `undefined`** — Dexie `.get(value)`
looks up by the table's **primary key**, which is `id` (the first schema field). The V3
API never returns `id`, so it is always `undefined` in stored records. Passing a string
object ID (e.g. `person_id`) to `.get()` will silently return nothing. Always use
`.where('person_id').equals(person_id).first()` instead. This has caused liveQuery
blocks to always produce `undefined` even when the record exists in Dexie.
8. **Treating `$effect` blocks as auth bypass risks** — a `$effect` inside a child
component cannot bypass a parent `+layout.svelte` auth gate. Children only mount if
the parent calls `{@render children?.()}`. Adding redundant auth guards to `$effect`
blocks that can only run after the parent gate already passed is unnecessary — and
misleads future readers into thinking the parent gate is not sufficient on its own.
The **real** pre-gate risk is `+page.ts` / `+layout.ts`: universal load functions run
before any layout mounts and also fire during SvelteKit link prefetch. Keep those files
clean of data loads in private modules. See `GUIDE__SvelteKit2_Svelte5_DexieJS.md`
"SvelteKit Layout Hierarchy: Security and Execution Order" for the full explanation.
9. **Using query `key` as a proxy for bypass stripped `x-account-id`** — this caused
valid account-scoped requests to lose account context and 403. `key` can be a valid
endpoint/business param, but it is not equivalent to `x-no-account-id: bypass`. Keep
`x-no-account-id` usage narrow and temporary; do not expand it without a documented
allowlist case.
10. **Pre-stringifying `*_json` fields before passing to API wrappers** — the API wrappers
(`api_post__crud_obj.ts` for V3, `api.ts` for legacy CRUD) automatically serialize any
field ending in `_json` (e.g. `cfg_json`, `data_json`). Pass these as plain JS objects.
Pre-stringifying with `JSON.stringify()` before calling the wrapper will double-encode
the value in the legacy path (stringify sees a string and escapes it), and is at best
redundant on the V3 path. Both paths now pretty-print with 2-space indent.
See `GUIDE__AE_API_V3_for_Frontend.md` → section 3C for the full explanation.
11. **Broad Dexie result windows get silently clipped** — if a broad "All" view shows fewer
rows than a narrower filter, check for a page-level limit or an API revalidation step
replacing the local IDB result set. For empty text searches, the full local result set
should drive the display; server refreshes should update cache, not shrink visibility.
12. **Not bumping `IDB_CONTENT_VERSIONS` when changing `properties_to_save`** — this caused
the IDAA Recovery Meetings "no meetings found" bug for approximately one year (20252026).
**What happened:** A deploy changed `properties_to_save` in `ae_events__event.ts`, but no
one bumped `IDB_CONTENT_VERSIONS.events.event` in `store_versions.ts`. Existing users kept
the old stale event records in IndexedDB indefinitely. On the Recovery Meetings page, the
fast path (IDB search) returned those stale records, which all failed the `account_id`
filter and returned 0 results. The API call then either errored silently or was filtered
to 0 by the secondary client-side filter. Critically, the error state and the genuinely
empty state showed the **same** "No meetings found" message — users and staff had no
indication a failure had occurred. The manual Full Reset (via the `?` help panel) always
fixed it, but no one knew why it worked, making the root cause impossible to track down.
**The fix (2026-05-16):** `check_and_clear_idb_table()` in `store_versions.ts` is now
wired in `src/routes/idaa/(idaa)/+layout.svelte` for `db_events.event`. On a version
match it costs one localStorage read. On a mismatch it silently clears the table; the
SWR pattern then repopulates from the API on next load.
**The rule going forward:**
- When you change `properties_to_save` in any `ae_events__*.ts` file (or any other
object file) in a way that makes existing cached records stale — fields added, removed,
renamed, or where a computed field's behavior changes — **bump the matching entry in
`IDB_CONTENT_VERSIONS` in `src/lib/stores/store_versions.ts`**.
- If the table is not yet wired, wire it first (see the wiring instructions in the
`IDB_CONTENT_VERSIONS` comment block in `store_versions.ts`).
- Currently wired: `events.event`. All other tables are not yet wired.
**Also:** Never show the same UI message for both a failed API call and a genuinely empty
result. Always distinguish `qry__status === 'error'` from `qry__status === 'done'` with
0 results in your templates. Silent failures look like data problems and are extremely
difficult to diagnose.
13. **Breaking the API retry loop by returning errors instead of throwing them** — all four
`api_*_object.ts` files (`api_get_object.ts`, `api_post_object.ts`, `api_patch_object.ts`,
`api_delete_object.ts`) use a `.catch()` that returns the error as a value, followed by a
classification block. That block **must throw** for transient network failures (`TypeError`)
so they enter the retry loop. If you change it to `return false`, retries are silently
bypassed for the most common failure mode in hotel/conference WiFi — and nothing warns you.
**What happened (commit a10accfaa, Jan 2026):** A "silence background fetch noise" commit
changed `.catch()` to explicitly `return error`, then the classification block was changed
from a `throw` to `return false`. `TypeError` from `ERR_NETWORK_CHANGED` — the most common
failure on crowded WiFi — stopped retrying. The `retry_count = 5` parameter became dead
code for network errors. Went undetected for ~4 months.
**The retry classification these files must honor:**
- `TypeError` (ERR_NETWORK_CHANGED, WiFi blip) → **`throw`** → enters retry loop with backoff
- `AbortError` where `did_timeout_abort = true` (helper's own timer) → **`throw`** → retries
- `AbortError` where `did_timeout_abort = false` (navigation/unmount abort) → `return false`
- HTTP 400/401/403/422 → `return false` immediately (client errors are deterministic)
- HTTP 5xx → **`throw`** → retries with backoff
**How to verify after any change to the error block:** confirm that a `TypeError` still
produces up to 5 retry attempts with 2s→4s→6s→8s delays before returning false. A single
`return false` after the first network failure means the retry loop is broken.
**Also:** when reviewing these files, check that all four have:
- `ae_auth_error.set()` triggered on 401/403 (shows session-expired banner to the user)
- `timeout = 20000` default (was 60s in PATCH/DELETE until 2026-05-21 — 5-min worst case)
- `did_timeout_abort` flag per attempt (separates helper timeouts from caller aborts)
14. **Account-scoped `liveQuery` trigger firing before bootstrap completes** — components
that load account-specific data via `liveQuery` must not trigger the API fetch until the
bootstrap Sync Effect in `+layout.svelte` has set the real `account_id`.
**What happened:** `element_data_store.svelte` triggered its load when `entry` was falsy.
On a fresh load with no IDB cache, `$ae_api.account_id` was still `null` (bootstrap hadn't
run yet). The `localStorage` scavenge in `api_get_object.ts` then read the stale
`account_id = 1` from a previous dev/demo session and made the API call with the wrong
account. The response was cached in IDB, and the next page load showed the wrong account's
record.
A second failure mode: if IDB _did_ have a cached record from a previous session with a
different account, `liveQuery` returned it as a valid hit (`entry` truthy), so the trigger
never fired to fetch the correct record.
**The fix pattern** for any trigger `$effect` that depends on bootstrapped account context:
```typescript
$effect(() => {
// Use $slct.account_id (non-persisted), NOT $ae_loc.account_id (persisted, stale).
// $slct is initialized to null and set only by the bootstrap Sync Effect, so it
// reliably gates the fetch until bootstrap has completed.
const account_id = $slct.account_id;
const api_ready = !!$ae_api?.base_url;
const entry = $lq__ds_obj as SomeType | null | undefined;
if (!browser || !account_id || !api_ready) return;
// Also re-fetch when IDB holds a record from a different (non-null) account.
// null account_id = global/shared fallback — that is still a valid cache hit.
const entry_is_stale_account =
entry !== undefined &&
entry !== null &&
entry.account_id !== null &&
entry.account_id !== account_id;
if (!entry || entry_is_stale_account) {
trigger = 'load...';
}
});
```
**Why `$slct` not `$ae_loc`:**
`$ae_loc` is a `svelte-persisted-store` — it hydrates from `localStorage` before any
effects run, so its `account_id` may be a stale value from a previous session. `$slct`
is a plain writable store initialized to `null`; the bootstrap Sync Effect is the only
thing that sets it. Until that runs, `$slct.account_id` is `null`, providing a reliable
gate. See `GUIDE__SvelteKit2_Svelte5_DexieJS.md` → "Bootstrap Race" for the Dexie-side
context.
15. **`tmp_sort_*` comparators written descending instead of ascending** — `build_tmp_sort()` encodes `priority=true` as `'0'` and `priority=false` as `'1'`, designed for **ascending** sort so priority items appear first. Writing a JS `.sort()` comparator as `b.localeCompare(a)` (descending) inverts the encoding and sends priority items to the bottom.
Found in journals (2026-06), IDAA recovery meetings fast-path and API re-sort (2026-06), and as a Dexie anti-pattern in BB post comments.
```ts
// ❌ Wrong — descending puts priority=false ('1') before priority=true ('0')
list.sort((a, b) => (b.tmp_sort_1 ?? '').localeCompare(a.tmp_sort_1 ?? ''));
// ✅ Correct — ascending matches build_tmp_sort encoding
list.sort((a, b) => (a.tmp_sort_1 ?? '').localeCompare(b.tmp_sort_1 ?? ''));
```
**Companion Dexie trap:** `collection.reverse().sortBy('tmp_sort_*')` — Dexie ignores a collection-level `.reverse()` when `.sortBy()` is called. The sort is always ascending. To reverse the result, call `.reverse()` on the returned array after `await`. See `GUIDE__SvelteKit2_Svelte5_DexieJS.md` → `build_tmp_sort` section.
**Exception — legacy `ae_events__event.ts` encoding:** `ae_events__event.ts` (and `ae_events__event_session.ts`) do NOT use `build_tmp_sort`. They use `priority ? 1 : 0` (priority=true→`'1'`), which requires **descending** sort to put priority items first. `ae_events__event_presentation.ts` DOES use `build_tmp_sort` (it overrides the generic encoding in its `specific_processor`). Do not apply the ascending rule to raw event or session sorts until those modules are migrated to `build_tmp_sort`.
16. **`$` sigil on a plain prop value → `store_invalid_shape` at runtime** — when a parent passes
`prop={resolved_value}`, the child receives a plain JS value. Using `$prop` inside the child
tries to subscribe to it as a Svelte store and throws `store_invalid_shape: X is not a store
with a subscribe method`. This often happens in files migrated from Svelte 4 where `$lq__*`
usage was correct for the old store-subscription pattern. In Svelte 5, props are plain values:
```svelte
<!-- ❌ Wrong — treats prop as a Svelte store -->
{$lq__event_session_obj?.name}
<!-- ✅ Correct — prop is already the resolved value -->
{lq__event_session_obj?.name}
```
Also note: `PersistedState` stores (events module) use `.current` access, never the `$` sigil.
17. **`*_json` / `*_kv_json` DB columns start as `null`** — JSON blob columns (`cfg_json`,
`data_json`, `poc_kv_json`, etc.) are `null` in the database until first written. Two failure
modes:
- **Read crash:** `obj.poc_kv_json[poc_type]` throws `TypeError: can't access property "X",
poc_kv_json is null`. Fix: always use optional chaining: `obj.poc_kv_json?.[poc_type]`.
- **Write crash:** spreading `null` — `{ ...obj.poc_kv_json }` throws. Fix: initialize with
`{ ...(obj.poc_kv_json ?? {}) }` before writing any nested keys.
```ts
// ✅ Safe read
const bio_updated = obj.poc_kv_json?.[poc_type]?.biography_updated_on;
// ✅ Safe write
const kv = { ...(obj.poc_kv_json ?? {}) };
if (!kv[poc_type]) kv[poc_type] = {};
kv[poc_type]['biography'] = new_value;
await update_obj({ data_kv: { poc_kv_json: kv } });
```
18. **Service worker without `skipWaiting()` + `clients.claim()` silently serves stale code to long-lived tabs** — The default SvelteKit service worker template does NOT include these calls. Without them, a new SW installs in the background but waits in a **"waiting"** state until every tab running the old version is closed before it activates. Users who leave a page open all day (especially IDAA members in the Novi iframe on idaa.org) run old buggy JS indefinitely after a fix is deployed.
**Symptom that should trigger this check:** Bug reports from users that developers cannot reproduce. Developers constantly refresh and open/close tabs — the new SW activates immediately for them. End users with persistent tabs never get it.
**The fix** (already applied to `src/service-worker.js` as of 2026-06-03):
```js
self.addEventListener('install', (event) => {
event.waitUntil(addFilesToCache());
self.skipWaiting(); // activate immediately, don't wait for tabs to close
});
self.addEventListener('activate', (event) => {
event.waitUntil(deleteOldCaches());
self.clients.claim(); // take control of all open tabs right away
});
```
**Trade-off:** A tab mid-session gets new JS without a page reload. For a read-heavy app like IDAA (browsing meetings) this is harmless. For a form-heavy app the risk is higher — weigh accordingly.
The reference doc also includes a short archive list for older, less-relevant historical incidents.
---
@@ -560,13 +337,23 @@ Start here, then go deeper as needed:
| What you need | Read |
|---|---|
| Active tasks + known bugs | `documentation/TODO__Agents.md` ← always first |
| Documentation index | `documentation/README__Docs_Index.md` |
| Dev workflow + commit rules | `documentation/GUIDE__Development.md` |
| V3 API reference | `documentation/GUIDE__AE_API_V3_for_Frontend.md` |
| WebSockets / real-time updates | `documentation/GUIDE__AE_API_V3_for_Frontend_websockets.md` |
| Dexie / liveQuery patterns | `documentation/GUIDE__SvelteKit2_Svelte5_DexieJS.md` |
| Common mistakes reference | `documentation/REFERENCE__Common_Agent_Mistakes.md` |
| Svelte 5 patterns + pitfalls | `documentation/GEMINI__Svelte_and_Me.md` |
| Permissions + auth levels | `documentation/AE__Permissions_and_Security.md` |
| Electron / native launcher | `documentation/PROJECT__AE_Events_Launcher_Native_integration.md` |
| Store migration plan | `documentation/PROJECT__Stores_Svelte5_Migration.md` |
| Exhibitor Leads module | `documentation/MODULE__AE_Events_Exhibitor_Leads.md` |
| Journals module overview | `documentation/MODULE__AE_Journals.md` |
| Journals settings map | `documentation/MODULE__AE_Journals_Config_Map.md` |
| Exhibitor Leads module | `documentation/MODULE__AE_Events_Leads.md` |
| Presentation Management module | `documentation/PROJECT__AE_Events_PressMgmt_Config_Cleanup.md` |
| IDAA client architecture | `documentation/CLIENT__IDAA_and_customized_mods.md` |
| IDAA Archives module | `documentation/MODULE__AE_IDAA_Archives.md` |
| IDAA Bulletin Board module | `documentation/MODULE__AE_IDAA_Bulletin_Board.md` |
| IDAA Recovery Meetings module | `documentation/MODULE__AE_IDAA_Recovery_Meetings.md` |
| IDAA Video Conferences module | `documentation/MODULE__AE_IDAA_Video_Conferences.md` |
| Naming conventions | `documentation/AE__Naming_Conventions.md` |

View File

@@ -0,0 +1,38 @@
# Aether IDAA — Archives Module
**Status:** Active (private)
**Routes:** `src/routes/idaa/(idaa)/archives/`
**Underlying library:** `src/lib/ae_archives/`
IDAA Archives provides authenticated access to archival documents and media for the IDAA community.
---
## Core Responsibilities
- List, view, and edit archive records (permission-gated).
- Upload and manage archive content files.
- Render media/content viewers for archived assets.
---
## Security Requirements
- All IDAA archive content is private.
- Auth guard must remain enforced for all archive routes and child views.
- Do not add pre-gate data loading in universal `+page.ts`/`+layout.ts` paths.
---
## Route Map
- `/idaa/archives`
- `/idaa/archives/[archive_id]`
---
## Related Docs
- `documentation/CLIENT__IDAA_and_customized_mods.md`
- `documentation/AE__Permissions_and_Security.md`
- `documentation/REFERENCE__Common_Agent_Mistakes.md`

View File

@@ -0,0 +1,38 @@
# Aether IDAA — Bulletin Board Module
**Status:** Active (private)
**Routes:** `src/routes/idaa/(idaa)/bb/`
**Underlying library:** `src/lib/ae_posts/`
The IDAA Bulletin Board (BB) is a private community posting and comment system for authenticated IDAA users.
---
## Core Responsibilities
- Post list and post detail flows.
- Comment create/edit workflows.
- Priority/visibility and sort behavior aligned with IDAA privacy and moderation rules.
---
## Security Requirements
- All BB routes are private/authenticated.
- Do not weaken layout-level auth gating.
- Treat any public exposure of BB data as Sev-1.
---
## Route Map
- `/idaa/bb`
- `/idaa/bb/[post_id]`
---
## Related Docs
- `documentation/CLIENT__IDAA_and_customized_mods.md`
- `documentation/AE__Permissions_and_Security.md`
- `documentation/REFERENCE__Common_Agent_Mistakes.md`

View File

@@ -0,0 +1,40 @@
# Aether IDAA — Recovery Meetings Module
**Status:** Active (private)
**Routes:** `src/routes/idaa/(idaa)/recovery_meetings/`
**Underlying library:** `src/lib/ae_events/` (repurposed)
Recovery Meetings adapts Events module primitives for IDAA meeting discovery, filtering, viewing, and trusted editing.
---
## Core Responsibilities
- Meeting search/list/detail flows (IDB-first with API revalidation).
- Filter and sort controls for member workflows.
- Trusted/staff edit flows for meeting records.
- Modal and direct-page detail/edit entry paths.
---
## Security and Data Integrity
- Module is private/authenticated.
- Keep error state distinct from empty-result state.
- When persisted object shape changes, update `IDB_CONTENT_VERSIONS` wiring/version.
---
## Route Map
- `/idaa/recovery_meetings`
- `/idaa/recovery_meetings/[event_id]`
---
## Related Docs
- `documentation/CLIENT__IDAA_and_customized_mods.md`
- `documentation/PROJECT__IDAA_Stores_Svelte5_Migration_2026.md`
- `documentation/GUIDE__SvelteKit2_Svelte5_DexieJS.md`
- `documentation/REFERENCE__Common_Agent_Mistakes.md`

View File

@@ -0,0 +1,34 @@
# Aether IDAA — Video Conferences Module
**Status:** Active (private)
**Routes:** `src/routes/idaa/(idaa)/video_conferences/`
Video Conferences provides IDAAs Jitsi meeting access experience within the IDAA private module.
---
## Core Responsibilities
- Render conference links and meeting access UX.
- Support breakout links from Novi iframe context.
- Preserve required URL bootstrap parameters when generating breakout URLs.
---
## Breakout Link Requirement
When opening outside the iframe, ensure required keys (for example site key and Novi identity UUID) remain in the URL so users do not hit access denial flows.
---
## Security Requirements
- Module is private/authenticated.
- Avoid exposing conference route details publicly.
---
## Related Docs
- `documentation/CLIENT__IDAA_and_customized_mods.md`
- `documentation/AE__Permissions_and_Security.md`

View File

@@ -0,0 +1,51 @@
# Aether Journals — Module Overview
**Status:** Active module
**Library:** `src/lib/ae_journals/`
**Routes:** `src/routes/journals/`
This module manages private personal journals and journal entries with offline-first behavior and Svelte 5 runes patterns.
---
## Core Responsibilities
- Journal and journal-entry CRUD via V3 API wrappers.
- Dexie-backed local cache with liveQuery-driven UI updates.
- Private/passcode-aware access behavior.
- Entry editing flows including auto-save configuration.
---
## Key Data Objects
- `journal`
- `journal_entry`
Common fields and behavior follow Aether object conventions (`code`, `name`, `enable`, `hide`, `priority`, `sort`, `cfg_json`, `data_json`).
---
## Storage and Reactivity
- Local cache: Dexie tables in journals DB layer.
- UI reactivity: Svelte 5 runes (`$state`, `$derived`, `$effect`) plus liveQuery wrappers (`lq__*`, `lqw__*`).
- Persisted module settings: see config map.
Related config map:
- `documentation/MODULE__AE_Journals_Config_Map.md`
---
## Access and Privacy
Journals contain private personal data. Treat all journal and journal-entry routes as authenticated/private content.
---
## Related Docs
- `documentation/PROJECT__AE_UI_Journals_module_update_2026.md`
- `documentation/GUIDE__SvelteKit2_Svelte5_DexieJS.md`
- `documentation/GUIDE__AE_API_V3_for_Frontend.md`
- `documentation/BOOTSTRAP__AI_Agent_Quickstart.md`

View File

@@ -0,0 +1,55 @@
# Project: Documentation Refresh and Archive Plan (2026)
**Goal:** Keep onboarding docs fast and current while preserving historical context in archive.
## 1) Naming Standard
Use one of these prefixes consistently:
- `BOOTSTRAP__` for first-read onboarding.
- `GUIDE__` for cross-module technical guides.
- `MODULE__` for module-specific docs.
- `PROJECT__` for active, time-bounded workstreams.
- `PROPOSAL__` for design proposals not yet adopted.
- `REFERENCE__` for evergreen troubleshooting/reference catalogs.
## 2) Module Coverage Baseline (Active)
Minimum one module doc per active module family:
- Events Presentation Management -> `MODULE__AE_Events_Presentation_Management.md`
- Events Launcher -> `MODULE__AE_Events_Launcher.md`
- Events Launcher Native -> `MODULE__AE_Events_Launcher_Native.md`
- Events Badges -> `MODULE__AE_Events_Badges.md`
- Events Leads -> `MODULE__AE_Events_Leads.md`
- Journals -> `MODULE__AE_Journals.md`
- IDAA Archives -> `MODULE__AE_IDAA_Archives.md`
- IDAA Bulletin Board -> `MODULE__AE_IDAA_Bulletin_Board.md`
- IDAA Recovery Meetings -> `MODULE__AE_IDAA_Recovery_Meetings.md`
- IDAA Video Conferences -> `MODULE__AE_IDAA_Video_Conferences.md`
## 3) Archive Strategy
Archive docs that are superseded, duplicate, or no longer operationally used.
Do not delete historical context; move to `documentation/archive/` with clear names.
### Completed in this pass
- Moved `MODULE__AE_Events_Launcher_Config_Menu_new.md` -> `archive/PROPOSAL__AE_Events_Launcher_Config_Menu_Unified_Vision_v3_1.md`.
### Next archive candidates (review + approve)
- Older style-review snapshots once current style guide references are centralized.
- Closed project docs where TODO/archive already capture final status.
- Duplicate docs where one `MODULE__` file and one `PROJECT__` file now overlap heavily.
## 4) Review Cadence
Monthly lightweight review:
1. Verify `BOOTSTRAP__AI_Agent_Quickstart.md` links still resolve and reflect active work.
2. Verify each active module has one current `MODULE__` anchor doc.
3. Move stale proposals and completed projects into archive.
4. Update `REFERENCE__Common_Agent_Mistakes.md` keep/archive sections.
## 5) Immediate Follow-Up Tasks
1. Add a single docs index (`documentation/README__Docs_Index.md`) with routing by task type.
2. Normalize any remaining filenames with spaces or inconsistent separators.
3. Add `Last Updated` metadata lines to all `MODULE__` docs.
4. Run a link-check pass across documentation files.

View File

@@ -0,0 +1,60 @@
# Aether SvelteKit — Documentation Index
Use this file as the routing map for project documentation.
## 1) First Read
- `documentation/BOOTSTRAP__AI_Agent_Quickstart.md`
- `documentation/TODO__Agents.md`
## 2) Core Guides
- `documentation/GUIDE__Development.md`
- `documentation/GUIDE__AE_API_V3_for_Frontend.md`
- `documentation/GUIDE__AE_API_V3_for_Frontend_websockets.md`
- `documentation/GUIDE__SvelteKit2_Svelte5_DexieJS.md`
- `documentation/GUIDE__AE_UI_Style_Guidelines.md`
## 3) Safety and Reference
- `documentation/AE__Permissions_and_Security.md`
- `documentation/REFERENCE__Common_Agent_Mistakes.md`
- `documentation/AE__Naming_Conventions.md`
## 4) Module Docs (Active)
### Events
- `documentation/MODULE__AE_Events_Presentation_Management.md`
- `documentation/MODULE__AE_Events_Launcher.md`
- `documentation/MODULE__AE_Events_Launcher_Native.md`
- `documentation/MODULE__AE_Events_Launcher_Config_Menu.md`
- `documentation/MODULE__AE_Events_Badges.md`
- `documentation/MODULE__AE_Events_Badge_Templates.md`
- `documentation/MODULE__AE_Events_Leads.md`
### Journals
- `documentation/MODULE__AE_Journals.md`
- `documentation/MODULE__AE_Journals_Config_Map.md`
### IDAA
- `documentation/CLIENT__IDAA_and_customized_mods.md`
- `documentation/MODULE__AE_IDAA_Archives.md`
- `documentation/MODULE__AE_IDAA_Bulletin_Board.md`
- `documentation/MODULE__AE_IDAA_Recovery_Meetings.md`
- `documentation/MODULE__AE_IDAA_Video_Conferences.md`
## 5) Active Projects
- `documentation/PROJECT__Documentation_Refresh_and_Archive_Plan_2026.md`
- `documentation/PROJECT__Stores_Svelte5_Migration.md`
- `documentation/PROJECT__IDAA_Stores_Svelte5_Migration_2026.md`
- `documentation/PROJECT__Use_AE_API_V3_CRUD_upgrade.md`
- `documentation/PROJECT__AE_Events_PressMgmt_Config_Cleanup.md`
- `documentation/PROJECT__AE_Events_Badges_Review_Print.md`
- `documentation/PROJECT__AE_UI_Journals_module_update_2026.md`
## 6) Archive
- `documentation/archive/`
Archive contains completed historical project notes and superseded proposals.

View File

@@ -0,0 +1,171 @@
# Aether SvelteKit — Common Agent Mistakes (Reference)
This is the detailed mistake catalog referenced by `BOOTSTRAP__AI_Agent_Quickstart.md`.
Use it as a troubleshooting and prevention guide, not as first-pass onboarding.
Review policy: balanced curation.
- Keep: high-impact or recurring mistakes.
- Archive: one-off or lower-signal historical incidents.
---
## Active Mistakes (Curated)
### 1) IDAA content exposed publicly
**Impact:** Sev-1 privacy breach.
**What happened:** A route guard was removed on an IDAA BB route.
**Rule:** All `/idaa/` content is private. Never remove auth guards on IDAA routes.
**Verify:** Confirm route/layout auth checks still gate all IDAA pages before data load.
### 2) Object ID included in PATCH body (`data_kv`)
**Impact:** 400 errors (`Unknown column in SET`).
**What happened:** Object ID (for URL path) was also sent in `data_kv`.
**Rule:** Keep object ID in the URL only; `data_kv` contains changed fields only.
**Verify:** In `update_ae_obj__*` calls, confirm `data_kv` excludes `*_id` fields.
### 3) Coarse-store `$effect` reactivity loops
**Impact:** repeated fetches, duplicate side effects, noisy state churn.
**What happened:** `$effect` read fields from `svelte-persisted-store` stores (`$ae_loc`, `$idaa_loc`), subscribing to entire store.
**Rule:** Be minimal about coarse-store reads in `$effect`; move transient triggers to session state and keep duplicate guards in executor paths.
**Verify:** Check effect dependencies and ensure unrelated writes do not retrigger critical effects.
### 4) Dexie `.get()` used with string object ID
**Impact:** false misses (`undefined`) despite cached data.
**What happened:** `.get()` queried primary key `id`, but V3 records rely on object string IDs (e.g. `person_id`).
**Rule:** Use `.where('<obj_id>').equals(value).first()` for object lookups.
**Verify:** Search for `.get(` against object IDs and replace with indexed `where` query.
### 5) Misunderstanding `$effect` and auth gates
**Impact:** security confusion and wrong mitigations.
**What happened:** Child-component `$effect` blocks were treated as possible bypass vectors.
**Rule:** Child effects cannot bypass parent layout auth gates; pre-gate risk is in universal `+page.ts` / `+layout.ts` loads and prefetch.
**Verify:** Keep private-module data loads out of universal load files unless explicitly authenticated.
### 6) Using query `key` like `x-no-account-id: bypass`
**Impact:** dropped `x-account-id`, unexpected 403 on scoped requests.
**What happened:** `key` was treated as bypass intent and account context was stripped.
**Rule:** `key` is business data, not bypass intent. Only explicit `x-no-account-id: bypass` drops account context.
**Verify:** Check request headers for account-scoped calls and preserve `x-account-id` unless bypass is explicitly required.
### 7) Pre-stringifying `*_json` before API wrappers
**Impact:** double encoding risk and inconsistent payloads.
**What happened:** Callers stringified JSON fields manually before wrapper serialization.
**Rule:** Pass plain objects for `*_json` fields; wrappers handle serialization.
**Verify:** Remove `JSON.stringify(...)` around `cfg_json`, `data_json`, and related fields before wrapper calls.
### 8) Broad Dexie result windows silently clipped
**Impact:** “All” views show fewer rows than narrower filters.
**What happened:** page limits or API revalidation replaced local broad result sets.
**Rule:** For empty text search, local IDB result set should drive visible results; server refresh updates cache without shrinking display.
**Verify:** Compare empty-search “All” view vs narrower filter counts and inspect revalidation merge behavior.
### 9) Missing `IDB_CONTENT_VERSIONS` bump after `properties_to_save` changes
**Impact:** long-lived stale cache bugs (e.g. IDAA “no meetings found”).
**What happened:** shape persisted in IDB changed, but table content version was not bumped.
**Rule:** When persisted object shape/behavior changes, bump matching `IDB_CONTENT_VERSIONS` entry in `src/lib/stores/store_versions.ts`.
**Verify:** For relevant object changes, confirm both version increment and table-wiring path are in the same change set.
### 10) API retry loop broken by returning transient errors
**Impact:** no retries on common WiFi/network blips.
**What happened:** transient error paths returned `false` instead of throwing, bypassing retry loop.
**Rule:** Keep retry classification strict:
- transient `TypeError` and timeout aborts -> `throw`
- navigation abort -> `return false`
- deterministic 4xx -> `return false`
- 5xx -> `throw`
**Verify:** Simulate transient network failure and confirm retry/backoff attempts occur.
### 11) Account-scoped trigger fired before bootstrap account is ready
**Impact:** wrong-account API fetch and cached cross-account data.
**What happened:** trigger effects ran before account bootstrap settled, reading stale context.
**Rule:** Gate account-scoped load triggers on `$slct.account_id` readiness, not persisted `$ae_loc.account_id`.
**Verify:** Ensure trigger effects require browser + account_id + api readiness before fetch trigger assignment.
### 12) `tmp_sort_*` comparator direction inverted
**Impact:** priority ordering reversed.
**What happened:** descending comparator used with `build_tmp_sort` encoding (which expects ascending).
**Rule:** Use ascending compare for `build_tmp_sort` outputs, with documented exceptions for legacy encodings.
**Verify:** Confirm comparator direction per module encoding and avoid `collection.reverse().sortBy(...)` assumptions.
### 13) `$` sigil used on plain prop values
**Impact:** runtime `store_invalid_shape` errors.
**What happened:** child component treated normal prop values as Svelte stores.
**Rule:** In Svelte 5, props passed as values are plain values. Do not use `$prop` unless prop is an actual store.
**Verify:** In migrated components, replace `$lq__...` prop reads with plain `lq__...` prop access.
### 14) Null JSON blob fields not guarded
**Impact:** read/write crashes (`cannot access property of null`).
**What happened:** `*_json` / `*_kv_json` DB columns were null before first write.
**Rule:** Use optional chaining for reads and `?? {}` initialization before object spread writes.
**Verify:** Audit reads/writes for `cfg_json`, `data_json`, `poc_kv_json`, and similar nullable blob fields.
### 15) Service worker stale-tab behavior misunderstood
**Impact:** users run old code longer than expected, “cant reproduce” bug reports.
**What happened:** deployment assumptions ignored SW activation lifecycle.
**Rule:** Keep SW activation behavior explicit (`skipWaiting`, `clients.claim`) and evaluate trade-offs for session-heavy flows.
**Verify:** After deploy, validate that long-lived tabs pick up new SW behavior as intended.
---
## Archived Historical Items (Pruned)
These are retained as project memory but removed from the active mistake list because they are lower-signal or one-off.
1. **Bad `.d.ts` module declaration masking errors** (important incident, low recurrence recently).
2. **Launcher `file_purpose == 'admin'` filtering gap** (specific historical enum-audit miss).
3. **Deleting files with `rm`** (still a workflow rule, now maintained in bootstrap File Safety section rather than as a mistake entry).
---
## Related Docs
- `documentation/BOOTSTRAP__AI_Agent_Quickstart.md`
- `documentation/TODO__Agents.md`
- `documentation/GUIDE__SvelteKit2_Svelte5_DexieJS.md`
- `documentation/GUIDE__AE_API_V3_for_Frontend.md`
- `documentation/PROJECT__Stores_Svelte5_Migration.md`