Source of truth · everything Insights, confirmed and prioritised · 16 August 2026
Insights Wiki
The hub. Open this at the start of every session — every open item ever discussed — confirmed against live code, and prioritised against being live to 1,000 users within the month. Approve, comment, deprioritise or ask for more context on any item, then hand the changes back and they become part of the record.
16 August 2026 (late) — Marie's in-use feedback: five bugs found and fixed from four screenshots
Screenshots were resetting the reader to slide one. Root cause was a default argument: resetIndex: Binding<UUID> = .constant(UUID()) minted a fresh id on every init, so any re-render fired the reset. A screenshot bounces the app through .inactive, which was enough — as do Control Centre, notification banners and the app switcher. No call site ever passed that binding.
Screenshotting inside go-deeper closed the chat. Different cause, same trigger: the card view presents both the chat and the "Screenshot taken" dialog, so raising the dialog tore down the chat.
The deck was refetching on every blip too — gated to real background returns.
The quest badge fired after ~2.9s of actual reading. Now scales with the reflection's length; Marie's 36-word quest goes 3.5s → 12.6s.
Go-deeper printed raw markdown asterisks. Fixed and verified against the exact text from the screenshot.
Quote slides sized to their length — the 36pt hero never shrank because minimumScaleFactor can't fire when the text is free to wrap.
And the content finding underneath it: of 910 quotes, only 5.5% are slogan-length. Median is 100 characters / 17 words. Marie is right that they read as sentences, and no font size fixes that.
16 August 2026 (night) — journeys filled, share preview made honest
69 cards added to the journeys. 14 of 15 paths are now complete 20-card journeys; before tonight there were 76 empty slots. Ordered by local fit — each gap took the card closest to the cards on either side of it — because there is no stored arc to order by. Additive only, fully reversible.
The women path was left alone at your call. The algorithm kept proposing men for it; you said no, so it was dropped from the fill entirely rather than partially applied. It still needs 7 picks from you.
Level and tone personalisation turns out not to exist.cards.metadata is empty on 695 of 697 cards, so _compute_user_level() returns 1 for every user and three ranking mechanisms silently never fire. Nothing is broken — it just was never populated. Decision on the board.
Share preview now shows the real card. The preview and the thing actually shared were two different designs. Also hardened the share-sheet presentation, which could pick a window that doesn't exist and silently do nothing.
Verified live, not just in the database — production /v1/paths now returns 20 cards for 14 journeys and 13 for the women path.
Measured the retry coverage — safe_execute protects about 19% of live database calls. Recorded, deliberately not mass-fixed; 167 call sites is your call, not an overnight one.
Corrected my own claim mid-way. I wrote that the empty metadata was breaking the level filter; reading the code, it is guarded by a null check and degrades cleanly to a no-op. Inert, not broken — a materially different thing, so the note was rewritten.
16 August 2026 (later) — indexes live, favourites batched, two regressions caught before shipping
Indexes applied to production — stories, key_insights, quests on card_id. Measured before and after on the same query: 124.6 ms → 2.3 ms, 54×. /v2/daily does 30 of these per load.
Favourites batched — and the cover-image regression caught before it shipped. Output proven byte-identical.
match_cards audited, not changed. It ships 600 kB of vectors per 100 rows against 8.9 kB of useful text. The audit claimed no caller reads it — that was wrong, and acting on it blind would have broken the recommender. All seven call sites checked: five never touch it, one has a working fallback. Safe to drop, but it is a live function signature so it waits for your go.
Backlog fully consolidated — everything ever discussed is now in this wiki, confirmed against live code, with four stale items closed.
16 August 2026 — Marie's decisions folded in; backend scale work committed
18 items approved, 2 deprioritised, 3 flagged for more context. All folded into the board.
Committed (branch fix/scale-cliffs-2026-08-15, not deployed) — four silent truncation cliffs closed, and the deck no longer rebuilds on every slide swipe.
Two regressions caught in my own work. Paginating one call dropped its safe_execute retry — fixed at the root so fetch_all now wraps every page, and the calls converted earlier gained protection they never had. Then tap_source (weight 0.30, higher than save_for_later) was missing from the recompute trigger set; caught by cross-checking against SIGNAL_WEIGHTS and against what the live build sends.
New finding — this_is_me, pass and read_50 carry no weight in SIGNAL_WEIGHTS, so the deck's signature gestures feed the recommender nothing. Added to the board.
Blocked on a design question — the nightly agent fix is not a one-liner after all. A 3-card prepared row is dropped by /v2/daily:679, which requires 10. Detail below.
15 August 2026 — six-agent audit, four fixes shipped, two wikis built
Correction to my own finding. "People behave like readers, not swipers" was wrong — this_is_me and pass only exist since 10 Aug (deck launch); I compared them against four months of old feed data. Scoped to the deck's real lifetime: 71 swipe actions vs 22 opens across 6 users. The swipe is being used.
Deployed — recommender signals were silently discarded for users with no profile row (103 of 239); popular cards ranked off a truncated 1,000-row slice. Verified live post-deploy: a fresh user's signal now writes a 1536-dim vector where before it wrote nothing.
Fixed, not shipped — favorite_item never fired from the live Save button; SwipeDeckView emitted zero events.