QuranFlow · Redesign handoff
Guided Walkthrough · Decision Log
Built Jul 13, 2026 · Kamran away from keyboard; decisions taken autonomously per his instruction
and logged here. Orchestration: Opus 4.8 as orchestrator, advisor, reviewer and verifier;
Sonnet 5 as the content analyst and four screen implementers.
Location: handoff/walkthrough/.
Modeled on the Faith Essentials "40 Day Reset" hi-fi mockup pattern Kamran pointed to as the reference.
Status: delivered. All 20 screens built (four Sonnet implementers against a locked contract),
screenshot-verified one by one by the orchestrator, and the 20-chapter guided walkthrough runs end to
end (verified: boots at chapter 1, advances correctly, reaches chapter 20, no console errors).
Deliverable:
QuranFlow-Walkthrough.html — one 1.7 MB self-contained file that opens by
double-click over
file:// (confirmed). Dev source in
app/. Nothing committed
to git without Kamran's ask (standing rule).
Updated Aug 9, 2026 (v12). The build has grown well past that first cut: 64 chapters across
seven acts, five stamped entrances, and a response pass to the Lejla + Yasmine flow-map
reviews. See
Aug 9, 2026 · the review-response recut at the foot of this page.
Updated Aug 12, 2026 (v13). Session 3 and the first-ever coach-lane review: 82 chapters,
eight acts, twelve new student screens and nine new coach screens — then a post-review pass
on Aug 12: the Today header down to the bell alone, Resources doored from Learn, and the plum-wash
ground kept app-wide. See
Aug 11, 2026 · session 3 and the coach lane.
Updated Aug 18, 2026 (v14). A small, sharp round off one review: the submission state model
decided on Aug 11 and missed in v13 shipped first, messaging became the centrepiece, and both of
v13's proposal chips were answered — C13 cut, C12 accepted in another form. 80 chapters, no new
codes, three retired. See
Aug 18, 2026 · messaging, and the state model that was missed.
What this is, and why it is different from the existing mockup
The handoff already contains the Sakīna artboard mockup (handoff/mockup/): 40+
screens on one scrolling design canvas, the source of truth for design intent. It answers
"what should each screen look like." It does not answer "what is it like to use the app," and
it needs a local web server to view. This walkthrough is the complementary artifact: a single,
double-clickable file that you tap through like the real app, with a guided story rail for a
PM/developer discussion. Same design language; different job.
Product & scope decisions
| # | Decision | What & why |
| 1 | Deliverable = one interactive, double-clickable file with a guided tour | Mirrors the reference (FE "40 Day Reset"). A single self-contained HTML that opens by double-click (no server), with a dismissible walkthrough rail (‹ › through ~20 chapters) drawn as demo chrome, never as app UI. Solves the artboard mockup's two gaps for a stakeholder meeting: it is navigable, and it needs no toolchain to open. |
| 2 | 20-screen curated scope, organized by Weekly Rhythm | Five acts: Getting oriented (2) · The weekly rhythm (7) · Sessions & coaching (4) · Learn & progress (5) · The coach app (2). Flow-completeness over coverage: every tap lands somewhere and the core loop (watch → recite → submit → hear back) is whole, rather than 40 screens where half are dead ends. |
| 3 | Reuse the Sakīna design system, single theme | Plum palette, light mode only — honoring the standing accessibility ask to "reduce color variety, single theme" (FEEDBACK-SYNTHESIS.md). Tokens copied verbatim from DESIGN-SYSTEM.md; kit primitives ported from the mockup's sak-base.jsx. |
| 4 | Both apps represented | The student app is the spine; the coach app gets a two-screen glimpse (review queue + reviewing a recitation) so the discussion can cover both sides and the async-feedback loop end to end. |
| 5 | Real content, one coherent world | Student Sarah Ahmed (Level II, Toronto/EDT, Week 8 of 15); coach Ustadha Amina (Cairo/EEST); group coach Ust. Radwa; passage Al-Mulk 67:1–3; the coach's real feedback notes — all extracted from the mockup's own fixtures (see build-notes/02-fixtures.md). Invented strings are flagged [FIXTURE] there. |
| 6 | newTwo screens designed where no source existed | onboarding-notify (opt-in reminders — the mockup's onboarding never asks; the principle is "reminders you choose, never default-on") and week-detail (a single-week drilldown — Learn only had multi-week "Parts"). book-confirm added as an explicit "just booked" state (the source folded confirmation into the ongoing appointment detail). |
| 7 | Normalized the source's term-label inconsistency | The mockup says "Spring 2026" everywhere (term ends Jun 22) except the Year-2 booking screens, which say "Fall 2026 · Year 2." The walkthrough uses Spring 2026 throughout. The mockup's own inconsistency is flagged for that workstream, not reproduced here. |
Technical decisions
| # | Decision | What & why |
| T1 | Vite + React 19 + TypeScript + Tailwind v4 + Motion | The reference stack. React for stateful navigation + motion; Tailwind v4 @theme for the shell; Motion for the iOS push/pop/sheet transitions. |
| T2 | Single-file build via vite-plugin-singlefile | JS, CSS and fonts inline into one index.html (~1.7 MB). Opens by double-click, sends as one attachment, works offline. This is the whole reason it beats the artboard canvas for a meeting. |
| T3 | Reused the reference app-shell, adapted | The custom stack navigator, device shell (iPhone frame on desktop, full-bleed on phone), tour rail and in-memory store are ~90% app-agnostic; ported and re-skinned to Sakīna rather than rebuilt. Hash deep-links (#/screen?param=x) + a ?shell=0&safe=ios review harness make every screen state directly addressable for screenshots. |
| T4 | Self-hosted fonts, inlined | Newsreader (display), DM Mono (numbers), Amiri (Arabic) via @fontsource — no network at runtime. Amiri carries the Qur'anic glyphs; the Amiri Quran variant was not pinned, to keep the dependency set minimal and the build reproducible. |
| T5 | Build is vite build only; type-check is separate | So a stray type error during a multi-agent build never blocks the single-file output. bun run typecheck runs tsc when wanted. |
| T6 | Demo state in memory only | Reload = fresh story. Nothing persisted; no localStorage. A plain open starts the guided tour at chapter 0; a deep-link open starts in free exploration with no tour chrome. |
Process decisions
| # | Decision | What & why |
| P1 | Model roles | Opus 4.8 orchestrated and built the shared foundation + the reference screen directly (the highest-risk, most-shared code), then reviews and verifies. Sonnet 5 ran the spec/fixtures recon and the four screen implementers, each with hard file ownership (one set of screen files, no shared-file edits) to avoid conflicts. |
| P2 | Central screenshot verification | Implementers do not run the build or a browser (a shared-directory build race would waste work); the orchestrator builds once, screenshots every screen headlessly via the deep-link harness, and looks at each before calling it done. "Compiles" is not "done." |
| P3 | A locked contract before fan-out | The design tokens, kit API, screen list, routing ids, business rules and the reference screen were all fixed before any implementer started, captured in build-notes/03-implementer-brief.md. Implementers execute the contract; they don't invent it. |
| P4 | Uncommitted until asked | Nothing committed to git without Kamran's ask. Everything lives under handoff/walkthrough/. |
Open items
| Item | Note |
| O1 | for Kamran / SOKContent sign-off | All copy traces to the mockup's fixtures, but the one English translation gloss and any [FIXTURE] strings (per-week theme names, notification labels) want a content/SOK review before this file is shown outside the team. |
| O2 | contentSource inconsistency upstream | The Spring/Fall 2026 mismatch (decision 7) still lives in the artboard mockup itself; normalize it there in a later pass. |
| O3 | for KamranHosting (optional) | The build is one HTML file, so it needs no hosting for the meeting (open it locally). If a shareable link is wanted later, it drops onto any static host (e.g. a Cloudflare Pages project) unchanged. |
Aug 9, 2026 · the review-response recut (v12)
Response pass to the two flow-map reviews with Lejla (product owner) and Yasmine (coach and
curriculum manager), Aug 5 and Aug 6, adjudicated into one register of 119 items (U-001 to U-119).
Built by six parallel implementers under strict file ownership plus an integrator, the same model as
the original build. Deliverable bumped to QuranFlow-Walkthrough-v12.html; the five stamped
entrances were regenerated and v11 was left byte-identical.
Every wording choice below is directional: Yasmine's condition for this round is a screen-by-screen
copy pass with her before anything is final, and the walkthrough's opening placard now says so out loud.
| # | Decision | What & why |
| R1 | Screen codes became sticky, and five were retired | A chapter's code used to be its position in TOUR, so one insert silently renumbered every screen after it and broke the citation system the reviewers work in. Every chapter now declares an explicit code, and scripts/package.ts fails the build if one is missing, if two chapters share a code without sharing a screen, or if a retired code reappears. Retired, never reissued: S10 and S11 (welcome + level, "it's redundant" — absorbed by S08 and the new S53), S20 (the lesson landing page — "S20 makes no sense"; a week now opens the player), S27 and S28 (practice retakes — on the feedback screen a student can only listen). |
| R2 | newEight new codes, appended: S52–S59 | S52 profile completion (hard gate after sign-in, silently skipped when the checkout profile is complete) · S53 level curriculum overview (stands in for the two cut screens) · S54 Year-2 welcome (Year-2 electives will be sold outside the ecosystem, so nothing may assume Year 1) · S55 full-semester syllabus · S56 pre-recording intro (a regression: the shipped app has this and the redesign had lost it) · S57 the Appointments hub · S58 placement, returning-student variant · S59 the waiting screen for a skipped assessment. S58 and S59 are decided variants a reviewer previously could not find; they are chapters now so the ‹ › walk reaches them. |
| R3 | Today is a swipeable deck over a fixed page | "This part of the app is the most important for us to get right." The top of Today carries this week's lesson, this week's assignment and the feedback that came back, in one horizontal deck; live sessions sit under it, and announcements last and filtered ("have a criteria" — newest post only, and only while it is younger than 48 hours). Learning above sessions, per the shipped app. Lejla raised the discoverability risk herself, so the affordance announces itself: the next card peeks past the edge, and the dots underneath are a control, not decoration. Hoisted into the kit as SakDeck so both years' home screens are literally the same component. |
| R4 | Assignments are a destination, not a drilldown | "If I want to record a submission I have to log in, click learn, click the lesson, and then go to record — the feature is buried, three clicks away." The tab bar gained a third student destination: Assignments in Year 1 (rooted on the submissions-and-feedback archive), Appointments in Year 2 (rooted on the new S57). Which set renders is decided by the tab you are on, falling back to the entrance. "Submissions" was rejected as a name because "it doesn't incorporate the feedback you're getting." |
| R5 | Learn is fifteen numbered squares, and no invented groups | The 15-lesson list and the Foundations / Tajweed rules / Application groupings are gone — "we just have lessons 1 to 15." A five-by-three grid carries four wordless states, the hero points at the next week you still owe rather than the calendar week, and the detail the grid no longer shows moved to the new syllabus screen. The demo fixture deliberately leaves week 6 open while the term is in week 8, so the "next owed" hero and the still-open state have something to render. |
| R6 | The Year-2 chain was rebuilt as the Year-1 mirror | "This onboarding for year two, I'm not feeling it because it's giving me whiplash." Both arrivals — the Level-4 graduate and someone who bought a Year-2 course having never done Year 1 — now walk one chain: welcome, the course, the rhythm and what the live component is, then availability. The congratulations screen is the only node unique to graduates. Generalised rule, applied in every lane: "it doesn't make sense to ask the availability before they even know what they're being asked about." Availability is one screen told twice, four steps in for Year 2 and five of six for Year 1. |
| R7 | The first assessment produces placement only | A policy change taken live in the review: the coach listens and sets the level, and no feedback response is recorded, because coaches have no time for it and it is a chronic bottleneck. The personal touch it used to carry moves to a pre-recorded per-level welcome from the student's own teacher, on the coach screen where that card already drew the session's strongest praise. Knock-ons in the build: the send button reads "Send for evaluation", and nothing in the arrival chain promises a reply. |
| R8 | "Attempts" is gone; the two-a-week cap is not | The word, the counter and the whole "no attempts left" screen are out of the recording flow — "this isn't a place to put it because it's confusing." The allowance is real policy and is stated once, calmly, on the new pre-recording intro. The ten-minute revoke the reviewers liked is now literal: a quiet countdown inside the card, which disappears when it lapses. |
| R9 | Appointments: filters, five names, recurring weekly, and the real cancellation rule | Booking filters by teacher, day or time, each defaulting to any, because today students "click 500 things" to find a time. The coach picker became name chips that carry five teachers rather than two avatars that fill the width. Recurring weekly booking is built ("I love that"). The old copy — "even a minute before frees the slot" — was simply wrong and now reads "up to 24 hours before" on all three screens. The policy behind recurring booking (hoarding, release after two no-shows, 24h versus 48h) is explicitly undecided, and no screen promises anything about it. |
| R10 | Nothing narrates a state | No "you're behind" language anywhere, in either year: states are shown in colour and mark, or not shown at all. Being behind is the majority state, not an edge case, and the review deferred it deliberately to its own session with Kamran. Two partial answers did ship: Learn's hero shows the next week you owe, and its squares carry a still-open state without words. |
| R11 | The prototype stopped trapping its reviewer | Yasmine could not get back out of a version on her phone without closing and reopening the link. The device back button now walks the in-app stack and really leaves at a tab root; the rail's act sheet gained an "All entrances" row (and is reachable in the single-act coach build, which is where she got stuck); the 38px and 36px back buttons got 44×44 hit areas; and dead taps were removed. Both links are rendered only when the build is served over http(s) — in the double-click file they would be exactly the broken taps she complained about. |
| R12 | newEvery chapter carries a note, and the placard states its own framing | The rail's caption names the screen; a new one-sentence note under it says why the screen is there or what the review changed. The opening placard now answers the two things a reviewer cannot read off the screens: that the app is shown mid-semester and Week 8 of 15 is a sample week ("how is anybody going to understand why we suddenly jumped to week eight"), and that the wording is directional pending Yasmine's copy pass. The new-student entrance also re-roots its Today tab on the pre-semester state, so tapping Today there lands on a term that has not begun. |
Fixed while integrating (not review asks)
| # | Item | What |
| F1 | bugThe browser back button could leave the deliverable | The new history bookkeeping seeded its depth from the boot stack, which is one or two entries deep before anything has been pushed. The first time the app landed somewhere shallower — a tour step onto a tab root, a back tap on the opening screen — it handed back entries it never took and walked the browser out of the file. Reproduced by stepping the Year-2 tour; fixed by seeding the depth at zero. |
| F2 | bugThe rail's own placard clipped the phone | The device shell reserved a fixed 96px under the frame for a rail whose height varies. The tallest state overflowed and cut the top of the screen. The shell now measures its chrome instead of assuming it, which also lets the frame grow back when the rail is collapsed. |
| F3 | Cross-file fixture drift | Today still marked the coach's second anchored word as a single word after the feedback screen moved to a joined pair, still counted one video against the player's three, and still named a two-verse passage against the assignment's three. The coach's review screen cited a different passage from the submission it was reviewing. There is no fixtures file in this build, so these are kept in step by comment; all four were corrected. |
| F4 | Copy canon sweep | Arabic diacritics removed from every live UI string (they survive only in the three retired screen files); the rail's own act tagline still said "hear back", the retired term for Feedback; citation ranges normalised to one glyph. |
| F5 | bugThe prototype could bounce back to a stale screen | The capture harness caught the page jumping to an old #/today a second or two after a navigation, in a tab that had been driven hard. history.go() is asynchronous, and F1's fix issued one and moved on: anything written before the traversal landed was written at the position the browser was leaving, and Chrome responded by discarding the queued traversal, so the popstate it was waiting for never arrived and the counter holding that wait never came down. With that counter stuck, real back gestures were swallowed as well — the exact trap F1 set out to close — and the depth bookkeeping drifted far enough that a later step reached into entries left by an earlier load of the same file, which is the stale screen a reviewer saw. History writes are now serialized: one operation at a time, the newest destination applied when the traversal lands, and a 1.2 second backstop for the traversals a browser drops silently. Every entry this build writes is also stamped with a per-load id and its own depth, so a step back can never reach past what this page itself wrote. Before the fix, 40 hostile cycles in one tab left thirteen traversals outstanding and the next back gesture walked out of the deliverable into a stale copy of it; after it, 150 rapid tour steps leave the history exactly as they found it. |
Open after this pass
| Item | Note |
| O4 | blocking copyYasmine's screen-by-screen copy pass | Every string in v12 is a direction, not a decision. "Before, stuff would just happen without me knowing... the developers would make the decision on what goes on every page. And then that needs so many fixes." Nothing in this build should be read as settled wording. |
| O5 | for Lejla + Yasmine + KamranThe student who is behind | The majority state, with no answer on Today or Learn, and no "you're behind" language allowed. Parked for its own session; it is as much an automation problem (coach-signed outreach after two missed weeks) as a screen problem. |
| O6 | policyRecurring booking, and the passing criteria | Hoarding of later slots, releasing after two no-shows, 24h versus 48h cancellation — all raised, none decided. Separately, students are never told what actually passes a semester; the 12-submission figure was an example only, and staff can pass a student with very few. |
| O7 | scopeThe coach lane was never reached | The two sessions covered S01–S33, S37 and S42 only. C01–C09 carry exactly one decided change (the coach marks attendance, because Zoom is third-party) and are otherwise unreviewed. A third session was booked to resume at S33. |
| O8 | docsDownstream numbering | The flow map and handoff/docs/TRACEABILITY.md still describe the pre-review numbering. The map also carries two uncoded Year-2 cards, which this build reads as covered by S30 (the course) and S31 (the rhythm and the one-to-ones) rather than as two more screens. Closed Aug 10 2026: the map was recut to the new numbering (v11-review-recut), its two uncoded cards merged into S31, and after approval its sixteen marked frames were re-shot from the v12 build (v12-reshot-frames); TRACEABILITY.md gained the Aug 5–6 section with the retired/new code ledger. PRODUCT-SPEC and DATA-MODEL remain to be re-cut — tracked there as “spec sync pending”. |
Aug 11, 2026 · session 3 and the coach lane (v13)
Four sources, one round: session 3 (Aug 6, Lejla + Yasmine, resuming the student walk at
S33/S34), the first coach-lane review the app has ever had (Aug 6, C01–C09, ended early),
Lejla's coach-side audit against the April 2026 coach survey, and the Aug 11 Kamran + Lejla
meeting over the v12 change document (mobile half only). Adjudicated into one register of 284 items,
U-120 to U-403, continuing v12's numbering. The build grew to 82 chapters
across eight acts: twelve new student screens (S60–S71), nine new coach screens (C10–C18),
and three codes retired (S18, S36, S40). Deliverable bumped to
QuranFlow-Walkthrough-v13.html; the five stamped entrances were regenerated.
Wording is still directional — Yasmine's copy pass has not happened.
| # | Decision | What & why |
| R13 | Foundation, four implementers, a wiring pass, a finisher — and screen files only | The card-separation change (U-179) is app-wide, so it ran first as a foundation pass on kit.tsx and was screenshot-verified once rather than merged from four directions. Then four implementers in parallel, each owning only its screen files: lifecycle + Level 0, booking, Today/Learn/You, and the coach lane. The shared spine — tour.tsx, registry.tsx, TabBar.tsx — is written by the orchestrator alone. Implementers report their chapter rows in a wiring spec instead of writing them, so four agents can never race on the file that defines the story. |
| R14 | Code allocations were ruled centrally, including the two an implementer got to argue for | S69 rides submissions-archive with state: 'level0'. S70 (Learn before a level is set) got its own chapter as recommended, but placed in ARRIVING, not the weekly rhythm — the Level-0 story belongs with arrival, and a locked Learn inside the Week-8 act would break that act's narrative. S71 (a past 1:1) got a chapter in YEAR TWO right after S35, because the payoff of folding S36 into S35 is worth showing. C10–C18 per the coach spec; C19 stays reserved. |
| R15 | S60 carries no store patch | The rejected-recording chapter was offered one and it was dropped: the screen reads its own Week-6 fixture, and the Week-8 demo spine must not be disturbed by a chapter that only needs to show one earlier week. |
| R16 | The pre-semester countdown is store-driven, never a param | S18 is retired, so the countdown is a state of the ordinary Today. S01 patches currentWeek: 0; S17 and S19 patch currentWeek: 8, so the full tour resets when it reaches the weekly rhythm. Patches only run when a reviewer walks the rail, so the new-student entrance also sets that world at boot, for app mode where there is no rail. Its Today tab root stays written out as plain today with no params: a state=presemester param would quietly rebuild the very screen U-171 retired. |
| R17 | One month calendar, two codes, owned by the sessions tab | month-calendar is registered on tab: 'sessions' and renders as S64 (the live month) or S65 (the booked semester) by param. Tab ownership decides which tab bar draws, and a Year-1 reviewer jumping to the calendar must not suddenly see the Year-2 bar. codeForScreen now disambiguates by params for every multi-code key, so the code in the status bar stays right either way. |
| R18 | The coach tab bar is five tabs, and the cost is named | Home · Queue · Students · Appointments · Schedule — Appointments added because so many teachers do both jobs, Schedule reduced to live classes. The cost: You leaves the bar. coach-you (C09) becomes a pushed screen behind C10's header avatar. Six tabs is one too many on a 393px bar; the coach's own corner is the least-used destination and the one that survives being a tap deeper. C16 (hours) is reachable from both C10 and C09 so nothing hides behind that move. Superseded Aug 18, 2026 (v14): Appointments merged back into Schedule and the freed slot went to Messages — Home · Queue · Students · Schedule · Messages (R30). The cost named here still stands: You is still a pushed screen behind C10's header avatar. |
| R19 | reverses a prior verdictThe private-note tier is gone | The reconciliation board ruled that coach-review's "For Sarah / Private — just me" audience toggle was "a specific, named coach requirement; its absence is a functional gap, not a simplification" (handoff/reconciliation/index.html), and v12 restored it. v13 removes it. Lejla settled both halves in the coach session: coach notes are readable by any teacher assigned that student — they follow her through a mid-semester transfer — so calling anything private is misleading, and there is no private-to-me tier at all. Out with it: the audience state, the branch, the "Save private note" CTA. Send is now unconditional, which also simplifies the one cross-role write (sendReview()) by taking it out from behind a branch. Nothing in the coach lane is labelled "private"; every note surface states its audience instead. |
| R20 | new"Return this recording instead" — an addition beyond the spoken asks | S60 shows a student a recording that came back rejected. Nothing in the review said who returns it. A quiet return action on the coach's review screen gives the new state an author and closes the lifecycle, with the demo store untouched. Flagged as an addition in the change document rather than presented as a review ask. |
| R21 | The skipped-stage flag lives on C11, not the review screens | A student may skip any of the four stages of the first recitation. That flag is a placement fact, so it renders on the placement screen where a coach is deciding a level — not on C02/C03, which review a week's submission. |
| R22 | newTwo review-tool features: the code in the status bar, and chapters in the act sheet | The phone's status bar shows the screen code where the clock was, read off the screen actually on top rather than the tour's position — so it stays right when a reviewer dismisses the rail and taps through the app. A screen no chapter draws has no code, and the clock comes back. The act sheet now lists chapters as well as acts. A one-act entrance used to have nothing to jump between, which is how a reviewer got stuck inside the coach build; now every entrance has somewhere to go. |
| R23 | C12 and C13 are visible proposals, not decisions | The student reply channel and the live-class coach surface are both drawn, and both carry a "proposal — decision needed" status on the screen itself and in the rail note. Each is a program decision that materially changes the size of the build, so they are shown to be argued about. Nothing else in the build routes into them or depends on them. Answered Aug 18, 2026 (v14): both chips are gone. C13 was rejected and its code retired (R28); C12's channel was accepted in tagged-thread form, so its screen retired with the decision rather than against it (R29). No screen in the build carries a “proposal — decision needed” status any more. |
| R24 | reverses an Aug 11 build decisionThe Today toolbar carries the bell alone | Aug 11 built the three-circle quick-access row Yasmine suggested — announcements, resources, bell (U-184, suggestion-strength). Kamran questioned the redundancy against the WWDC field guide's toolbar model, and the ruling delegated on Aug 12 took the header to one control. The bell is the one inbox: announcements arrive there alongside notifications (U-172, decided), and the fresh-announcement preview at the foot of Today keeps the second door (U-164, decided). So U-138's "visible entry outside You" holds twice over without a third persistent circle. The field guide's toolbar is context plus local actions; a row of standing navigation circles is a tab bar in the wrong place. An interim two-circle state (folder + bell) was built and overruled the same day as a middle path. |
| R25 | Resources' home-level door is a row on Learn | The folder circle left Today with the megaphone. Resources are learning material and Learn is where a student looks for them, so the door is a first-class row under the grid rather than a Today circle — the original complaint was resources buried in a settings-shaped You, and a row on Learn is not that. It renders in both Learn states, Week 8 (S42) and Level 0 (S70, per U-363), and pushes S61. U-151 ("a dedicated place") is satisfied by S61 plus this door. S07's own resource kit (U-360) is untouched, as is S61 itself. |
| R26 | One ground, app-wide | "Why does it look like a shade of purple was added" — because one was, and it stays. #FAF7FA is the app's existing plum at 3%, introduced by the card-separation fix (U-179): white cards on a white page did not read as cards. It looks new-screen-only in the change document only because every before-shot is v12 white. A generation-split ground — washed on the new screens, white on the old — was considered and rejected as a reviewer affordance rather than a design; end users get one surface. This settles the interim state; it does not pre-empt the visual-identity round (U-327), which stays parked. |
Open after v13
| Item | Note |
| O9 | scopeThe coach "open" beat | Take-back now lasts until the teacher opens the submission, so there is a moment where the coach's tap locks the student's screen. Deliberately out of scope this round — the coach lane already grew by nine screens. It is one demo.set() on the queue row whenever the story wants to show it. |
| O10 | cleanupThree screen files to delete | recording-noattempts, week-at-a-glance (S40) and appointment-notes (S36) stay registered but unchaptered through v13, so nothing breaks mid-round. Delete all three once v13 ships and their codes are retired for good. |
| O11 | for the coach roundThe queue-pills guess | "Why is this not working?" — Lejla hit an unresponsive control in the coach entrance and moved on without saying which. The filter pills on C01 that did not actually re-sort are the best-guess culprit and are fixed; confirm against Yasmine's recording in the coach round rather than assuming it was the one. |
Aug 18, 2026 · messaging, and the state model that was missed (v14)
One source, one meeting: Kamran, Lejla and Sr. Yasmine on Aug 18, walking a slide deck
Sr. Yasmine had assembled from feedback forwarded by many teachers and students. Deck items are
third-hand, and nearly every one was adjudicated live by the three in the room. Reconciled into a
43-item register, U-404 to U-446, continuing v13's numbering. A small,
sharp round on a build people like — "the bazillion messages of this is so cool" from the
coaches, on the record: nothing structural, one centrepiece (messaging), a batch of
single-screen fixes, and one omission to own. 80 chapters, no new screen codes, three
retired (C12, C13, C17). Deliverable bumped to QuranFlow-Walkthrough-v14.html; the
five stamped entrances were regenerated. Wording is still directional — Sr. Yasmine's copy
pass has not happened.
| # | Decision | What & why |
| R27 | closes a v13 missThe one submission state model, this time actually applied | U-341 was decided on Aug 11 — one state model, student side and admin side alike — and it did not reach the v13 build. The build guide translated it additively ("the union gains rejected and revoked"), so nobody removed the two states it was meant to replace, and practiced and heard were still in the code on Aug 18 (submissions-archive.tsx:93, coach-student.tsx:101). Lejla found them in the meeting — "was that included? It wasn't included in this revision" — and U-435 is that same ask, shipped first this round. The model is unsubmitted → awaiting review → in review (locked) → reviewed, with rejected and revoked as exits, and one vocabulary in both seats: Awaiting review · In review · Feedback ready · Returned · Taken back to the student; Needs review · In review · Feedback sent · Returned · Taken back to the coach. The two retired words were never states of a submission — they were states of the student, which is why they never sat straight beside the others. The part that matters is not the deletion but the guard: the build now asserts on the built HTML that neither word can come back, alongside the standing bans on "TA", "Hear back", diacritics and the mono font. An instruction that can be read additively will be, eventually, by someone; an assertion cannot. |
| R28 | answers a v13 proposalC13 is cut: there is no live-class screen | "Screen isn't needed. Yeah." (U-418). Live sessions run in Zoom, and marking a roster that can hold 250 names is not work a coach will do on a phone between classes. The screen and its code retire through the ledger rule, the same way S18, S36 and S40 did — RETIRED_CODES plus the packager's validation, so the number can never be reissued. What survives is a backend fact, not a surface: count how many students tap Join per session, associated with that session and reportable in the admin portal (U-419) — the attendance and donor number the program currently reconstructs from Zoom statistics and self-reporting. That is parked to the admin track, not built here. |
| R29 | answers a v13 proposalC12 is superseded, not rejected — the reply channel was accepted in another form | v13 drew a student's reply as a short thread inside the submission. The meeting accepted the channel and rejected that shape: a student messages about a specific feedback from S26, and it lands in the coach's one inbox, tagged with its week ("Submission 8") — never siloed under the submission (U-426). So the proposal is answered yes, and the separate surface retires because its content now lives in C15, which is also the tab this round promoted. The siloed shape is exactly how the current app loses messages: when notifications broke, "we missed so many messages from students" (Sr. Yasmine). Recorded here as resolved-superseded rather than cut, because the difference matters to anyone reading the ledger later: C13 lost the argument, C12 won it and stopped needing a screen. The general "message your teacher" door stays tucked in You on purpose (U-425) — friction there is a feature, and the feedback-scoped channel is the sanctioned path. |
| R30 | Appointments stops being a destination: C17 folds into C07, and Messages takes the slot | v13's coach bar was Home · Queue · Students · Appointments · Schedule (R18). One review later the split reads as an accident of history: most coaches do both jobs, and a day holding a class and two one-to-ones should be one list, not two tabs. C07 becomes the whole schedule with a Live classes / Appointments filter standing in the space the cohort filters vacated (U-414, U-411), C17 retires, and the freed tab goes to Messages — C15 promoted, "the number one thing" in the coach feedback (U-415). New set: Home / Queue / Students / Schedule / Messages. Five stays the cap and the labels stay: "I don't think it should ever be more than five... even five is a lot," which also rejected icon-only tabs (U-417). The tab replaced a home row that read "2 unread", so the tab carries the unread count — a bar must not say less than the row it replaced. Terminology is settled with it: Live classes covers level classes, QRCs, office hours and occasional events; Appointments is the one-to-ones. |
| R31 | reverses decision 6Notifications default on, and onboarding says so | There is no per-event opt-in for live sessions: a student is notified about everything on the schedule (roughly 8–12 a week), switches categories off in settings if she wants to, and adds individual sessions to her own calendar (U-420). Opt-in was rejected because ticking a box per session reads as registering for it and invites decision fatigue (Lejla); a notification is "this is available for you", not a summons. The onboarding screen moved with the rule: S16 had shipped its toggles all off, which is the rejected position stated as a default — "the default when you're doing it is you kind of want everyone to turn it on" (Kamran). The screen and its caption now open with notifications on, calmly worded. This reverses decision 6's original framing for the scheduled-session category ("reminders you choose, never default-on"). It is not a reversal of consent: every category is still switchable in one place, nothing invents urgency to keep it on, and the student is told plainly what she is opted into. |
Open after v14
| Item | Note |
| O12 | for LejlaThe rescheduling exception | U-437: a student should be able to move a session to another time soon without being blocked because next week's is already booked. Read off the deck, never adjudicated — the conversation moved to the Mon–Sun booking window and did not come back. Lejla's call, bundled with the end-to-end booking walkthrough she and Sr. Yasmine owe (U-443): neither has properly exercised booking, and it was the biggest new build of the last round. |
| O13 | admin trackFour items that belong to the backend | Documented, deliberately not built here: a waiting alarm past about four days (U-407, admin dashboard, may already exist) · coach notes as their own tab in the admin portal, separate from admin notes (U-409) · coach pickers listing only active coaches, alphabetically (U-410) · the join-click count per session, reportable (U-419). Agenda seed for the Kamran + Lejla backend review. |
| O14 | docsThe student live-class screen has no code | live-class is registered and reachable from a session, but no chapter draws it, so it carries no S number — pre-existing in v13, noticed while retiring C13's coach-side namesake. Nothing is broken by it; a reviewer simply cannot cite that screen. Candidate for a code next round. |