journeys walkthroughs overview - fahadahmed/jamaal-app GitHub Wiki

Journey walkthroughs

Status: complete — all eleven journeys walked; 89 gaps found (G-01 … G-89, G-58 and G-66 withdrawn), every one decided and applied. Each journey was walked one at a time. Each walkthrough walks a journey screen by screen to test the schema and our working assumptions before code, and doubles as the per-screen spec Claude Design redraws from. Screen IDs are from the Screens and flows register.

Method

For every screen in the journey:

  • Sees / does — what is on it and what the user can do.
  • Reads / writes — the schema fields and engine signals it touches.
  • Assumes — the working hypotheses the screen relies on, each checked against the schema and engine docs: ✓ holds, or ✗ G-nn a gap.
  • Copy to respect — lines that must be consistent with how the app works.

Then each walkthrough ends with the data that exists afterwards (an end-state check: if a screen's output can't be stored, that's a gap), what the next screen will show, and the gaps raised. Gaps go into the log below with a proposed resolution and a status, and a walkthrough isn't finished until each of its gaps is Decided or consciously deferred.

Journeys

# Journey Register flow Status
1 First launch and onboarding F01 Done — G-01 … G-10 decided and applied (G-08 closed by G-84)
2 Capture a task, and living in Today F03, F04, TD-01 Done — G-11 … G-20 decided and applied
3 A focus session F05 Done — G-21 … G-26 decided and applied
4 Anchors: an Anchor's day; creating Anchors F06, F07 Done — G-27 … G-36 decided and applied
5 Habits: create, log, pause F08 Done — G-37 … G-44 decided and applied
6 Night Planning F09 Done — gaps G-45 … G-53 decided and applied
7 Capacity and day settings F10 Done — gaps G-54 … G-57 decided and applied
8 Wellbeing F11 Done — gaps G-58 … G-67 decided and applied (mood removed)
9 Trial, paywall and read-only F12 Done — gaps G-68 … G-75 decided and applied
10 Notifications denied; problems and recovery F13, F15 Done — gaps G-76 … G-83 decided and applied
11 Categories F14 Done — gaps G-84 … G-89 decided and applied (closes G-08)

The order follows a new user's life (first launch first), so each journey can assume the data the earlier ones created. It can be reordered.

Gap log

Status: Proposed (a resolution is suggested, waiting for a decision) · Decided · Applied (written into the schema, engine or journey docs) · Open (needs information or a separate decision first).

ID From Gap Proposed resolution Status
G-01 J1 · OB-01/03 Onboarding re-runs on a second device. The "onboarding complete" flag is per-device, but the data syncs, so an iPad would show onboarding again on top of an already-set-up account. Add a synced UserSettings.onboardingCompletedAt. A first launch with iCloud waits briefly ("Checking iCloud…") for sync before deciding; a returning account gets a short "Welcome back" and skips onboarding. Applied — UserSettings.onboardingCompletedAt; "Welcome back" on a second device
G-02 J1 · OB-05 Reminders fire on every device. Times are per-device local preferences and every device schedules its own notifications, so an iPhone + iPad + Mac user gets three evening prompts. A second device also starts with the default 20:00, not what the user chose. Sync the times in UserSettings (planningMinute, morningMinute); keep a per-device "send reminders here" switch (local), defaulting on for iPhone and off for iPad and Mac. Applied — synced planningMinute / morningMinute; local "Send reminders on this device" switch (iPhone on, iPad/Mac off)
G-03 J1 · OB-06 The first task wouldn't appear on Today. Onboarding says "something you need to do this week", but a task with no date is backlog (collapsed) and a later date isn't due today — yet Today is meant to open with something in every section. The first task defaults to due today (Today or Tomorrow are the only choices), with the prompt "Something you need to do today." Applied — first task defaults to due today
G-04 J1 · OB-07 Habit presets aren't defined. presetKey is a string with no catalogue: onboarding needs each preset's kind, target, window, effort and schedule. Define the catalogue (table in the walkthrough), kept as bundled app data, not user data. Applied — preset catalogue in habit.md (Qur'an and dhikr values for the owner to correct)
G-05 J1 · OB-08 A rule created mid-day would mark today's earlier windows missed. Creating prayer times at 21:00 would generate Fajr → Asr for today, each already closed, and the next evaluation would finalise them as missed on the very first screen. Generation never creates an instance whose window ended before the rule's createdAt (and the same for slots added by a later edit). Engine rule, no new field. Applied — engine rule in module 3
G-06 J1 · OB-03 CloudKit development needs a paid developer account. CLAUDE.md says the free Personal Team is fine through development, but iCloud and push can't be provisioned on it, and the project's iCloud container list is empty. Simulator builds and CI are unaffected; real-device sync testing is not. Decide when to enrol (before any sync testing — Phase 3 at the latest), then create the container identifier. Correct the CLAUDE.md note. Applied — enrol before any real-device sync testing (Phase 3 at the latest); CLAUDE.md corrected
G-07 J1 · OB-04 Day settings can contradict each other. Nothing forbids a working-day end before its start, or a rollover after the start. Document the validation: rolloverMinute < dayStartMinute < dayEndMinute, with at least two hours between start and end. Applied — validation rule on UserSettings
G-08 J1 · OB-06 Category chips have no colours. The first-task screen introduces the three default categories, but TaskCategory.colorKey values aren't defined. Tied to the category-colour decision (register #9); placeholders until then. Applied — closed by G-84 (five label colours; hues to confirm against Design)
G-09 J1 · OB-08 Prayer times can't be built until a prayer-time library is chosen (and its method list checked against the method values offered). Choose the library (the design suggested adhan) at the start of the Anchor work. Applied — adhan-swift 1.5.0; MIT licence verified, builds on Xcode 27
G-10 J1 · OB-07 "Something else" can't host the full type picker in onboarding. In onboarding, "Something else" is a binary daily habit with just a title; the other kinds come from the Habits tab. Applied — "Something else" is a binary daily habit
G-11 J2 · TK-01 Effort can't express long tasks. The chip "2h+" stores what? A three-hour task can't be said, yet load and the "doesn't fit a gap" flag both rely on real durations. The four chips are shortcuts; Other… is a 15-minute stepper up to 8 hours. Applied — Other… stepper (15-minute steps, up to 8 h)
G-12 J2 · TK-01 Missing estimates silently switch the warnings off. Items without effort count as zero, so "Day is full" and the overflow flag never fire for them. Preselect 30m (changeable; No estimate stays available), so most tasks carry an effort. Applied — 30 min preselected; No estimate available
G-13 J2 · TD-01 "Today's load" isn't defined while the day is under way. Module 7 says "tasks planned for the day", not which ones, and a completed task must still count toward the day (the all-done screen reads "2h 15m spent"). Count live tasks due on or before today, plus tasks completed today, using actual focus time where a session exists and the estimate otherwise. Write it into module 7. Applied — module 7 defines today's load
G-14 J2 · TD-01 Un-completing a repeating task creates two live instances (the next one already exists). Remove the spawned next instance if it is untouched; otherwise refuse with "This one already repeated". Applied — task.md (untouched next instance removed, else refused)
G-15 J2 · TK-03 Which deferral reason is stored for an instant deferral? The 1st and 2nd have no chip, but reason has five values. A user deferral with no chip is reschedule; with a chip it is that chip's value; automatic is unspecified. Applied — reason semantics in task.md
G-16 J2 · TK-01/03 Quick dates have no rules. "Later this week" and "Next week" (and the week's first day) are undefined. Use the user's calendar's first weekday: Later this week = three days from now if still in the same week (otherwise not offered); Next week = the first day of next week. Applied — quick dates
G-17 J2 · TD-04 A separate Add chooser makes capture two taps. Drop the chooser screen: the Add sheet opens on Task, with a Task | Anchor switch at the top. Update the register. Applied — Add sheet with a Task
G-18 J2 · TD-01 No manual ordering in v1 rests on an untested hypothesis that the engine's order is good enough. Ship without drag-ordering; treat it as a working hypothesis to check in real use. If wrong, TaskItem.sortOrder is additive. Applied — no manual ordering in v1, recorded as a hypothesis to test
G-19 J2 · TK-02 A dropped task can't be found again after the 5-second undo: Design draws Delete, we have a soft Drop, and there is no History screen. Accept for v1 (history is kept in the data, just not surfaced); revisit with a History screen after launch. Applied — accepted for v1; revisit with a History screen after launch
G-20 J2 · TK-01/02 Design draws importance as "Matters 4 of 5", and "Edit / Delete". That contradicts three-level importance and soft Drop. Design redraws importance as low / medium / high and uses Drop. (A functional conflict, per the brief.) Applied — recorded as a Design fix in the brief
G-21 J3 · FS-01 Which Anchor events reach the chip is under-specified. The docs say "Maghrib in 12 min" (a window opening), but the costly moment is an open window about to close while a session runs. The chip shows the single most urgent line: an open, pending Anchor closing soon takes priority over a fixed Anchor's window opening within 30 minutes. Flexible Anchors never appear. Nothing blocks. Applied — module 8 and Today: closing-soon outranks opening-soon; flexible Anchors never appear
G-22 J3 · FS-05/07 There is no way to stop a session without finishing it. The state machine has abandon, but no screen reaches it, and being interrupted is the commonest ending. The finish sheet offers Done and Stop for now (time logged, task stays live); the switch-task sheet adds Stop for now to Done / Defer / Drop; a habit's settle sheet is Log it / Stop for now. Applied — Done / Stop for now on the finish and settle sheets
G-23 J3 · FS-06 Undoing a finish would count the undo window as work. Reopening sets endedAt to nil, so the five seconds before the tap become running time. Reopening adds the time since endedAt to pausedSeconds. Applied — undo adds the gap to pausedSeconds
G-24 J3 · timed habit Timed-habit minutes can drift and can't be recomputed. Rounding each session to whole minutes drifts, and a hand-added figure and timed figures both land in one integer. Recompute the day's HabitEntry.amount from that window's sessions (round(total seconds ÷ 60)), and store hand-added minutes as a finished session with a new WorkSession.outcome = manual. Two devices then converge by summing rows, not overwriting a counter. Applied — entry recomputed from sessions; WorkSession.outcome = manual
G-25 J3 · TD-01/TK-02 Resolving a task with a live session leaves the session running. Ticking, deferring or dropping a task that is being timed says nothing about its session. The session closes with the matching outcome (done → finished, defer → deferred, drop → dropped) and its time is logged. Applied — resolving a task closes its session with the matching outcome
G-26 J3 · FS-07 The user isn't told when a clash stops a timer. If two devices both started a session, the later is closed as abandoned silently. One quiet line on next open: "Two timers were running; the later one was stopped and its time logged." Applied — quiet notice on the next open after a clash
G-27 J4 · TD-01 Anchor titles don't compose. Anchor.title is "Fajr", the group is "Salah" (on the rule), and a two-slot rule needs both names; the display rule isn't written. Anchor.title stores the slot label (or the rule's title if none). A plain row shows rule.title plus the slot label when different; a grouped row is titled rule.title and lists members by slot label. Applied — Anchor.title is the slot label; display composition in anchor.md
G-28 J4 · AN-10 A forgotten tap can't be fixed. "Closed is final" leaves someone who prayed but didn't tap with a permanent miss (an open question in anchor.md). A missed Anchor offers "Mark as done after all" until the end of that logical day, with a neutral confirmation showing the time. Never reopens skipped or delegated; doesn't weaken the no-early-logging rule. Applied — "Mark as done after all" until the end of that logical day
G-29 J4 · AN-10 No record of when an Anchor was decided. Needed to show "attended 12:52", to date a plants-style rule's last done, and for late correction. Add Anchor.resolvedAt: Date?, set when the status leaves pending and updated by a late correction. A plants-style next window is scheduled from its logical date. Applied — Anchor.resolvedAt added
G-30 J4 · reminders Anchor reminders aren't defined. No per-Anchor setting, none for one-offs (no rule to inherit from), and generation stops at tomorrow so reminders would lapse after two days unopened. reminder: { atStart, beforeEndMinutes } in rule config, copied to Anchor.remindBeforeStartMinutes / remindBeforeEndMinutes (one-offs set them directly). Defaults: prayers at start, everything else off; closing reminders opt-in. Schedule over five days via the preview, within the 64 budget. Applied — reminder fields on Anchor, reminder in config, five-day planner horizon
G-31 J4 · AN-04 No region → prayer-method table, and no madhab default. A bundled suggestion table (e.g. North America → ISNA, Middle East → Umm al-Qura, South Asia → Karachi) and a standard-Asr default, both editable. The owner reviews the table. Applied — adhan-swift; region → method table bundled in JamaalCore, as drafted
G-32 J4 · AN-04/11 Device-mode location on several devices. Every device could overwrite the same rule's coordinate, so a travelling iPhone and a Mac at home would fight. A device writes the coordinate only when it has moved materially (about 25 km) since its own last check, never because it differs from the stored value. Applied — only a device that has itself moved writes the coordinate
G-33 J4 · AN-05 A plants-style rule has no "last done". afterLast has only a startDate meaning when the first window opens. For afterLast, startDate is the date it was last handled; the form asks "When did you last do this?" (default Today, or Due now = minDays ago); the first window opens minDays later. Applied — for afterLast, startDate is the date last handled; "Due now" option
G-34 J4 · AN-02 The rule detail can't show upcoming days. Only today and tomorrow are stored. Engine preview(rule, days): a dry-run generator (pure, no writes), also used for reminder scheduling. Applied — engine preview(rule, days)
G-35 J4 · TD-01 Do Anchors ever fold into "Also today"? (open question in today-list.md) Anchors are always shown, at every capacity level. Applied — Anchors always shown at every capacity level
G-36 J4 · AN-04 Jumu'ah. Friday's Dhuhr is replaced by the Friday prayer (open in anchor.md). An optional Friday label: Friday's Dhuhr Anchor is titled "Jumu'ah" (same window and time, only the name changes). The owner confirms it's enough. Applied — fridayLabel (Friday's Dhuhr is titled "Jumu'ah")
G-37 J5 · HB-03 No screen can make a habit with two times a day. The schema supports several windows, but the form has no way to add a second (e.g. medication morning and evening). A Times of day section: one all-day window by default, Add another time (up to four) with a label and optional start, end and reminder; each window has its own target, entries and grid. Applied — Times of day section, up to four windows (habit.md)
G-38 J5 · HB-04 "N times a week" habits are undefined on Today and in the grid. Which days show them, and can a day be missed while the week is open? Show it every day until the week's target is met, then as done; its days are never missed (filled or empty only); the read speaks in weeks; the week follows the calendar's first weekday. Applied — weekly-target habits (habit.md)
G-39 J5 · HB-02 Past days can't be corrected, or it's unstated. A forgotten log leaves a miss. The last 14 days of the grid are tappable to correct (toggle, stepper, minutes, slips / Held); older days are read-only. Applied — the last 14 days are correctable
G-40 J5 · HB-08 "Engaged that day" isn't computable. Avoid habits resolve only if the user engaged with the app, but opening the app leaves no record and the docs don't list which records count. Engaged = any of: a task completed that day; a habit entry with amount > 0 or an avoid entry with completedAt (Held today); an Anchor resolvedAt that day; a session with that day; a closed or skipped Night Planning session for that date. Opening the app alone doesn't count. Applied — the list of records that count as engagement
G-41 J5 · HB-01/07 Archived things can't be found again. Archiving hides a habit, Anchor rule, category or group with no way back. A collapsed Archived section at the end of each list, with Restore. Applied — Archived section with Restore on each list
G-42 J5 · HB-03/07 Changing a habit's kind would reinterpret its history (amount is a count, minutes or slips by kind). kind is fixed at creation; to change it, archive and create a new habit. Everything else stays editable. Applied — kind fixed at creation
G-43 J5 · TD-01 A reminder would fire for something already done. Repeating local notifications can't skip a day. The notification planner schedules habit reminders as near-term individual notifications, and cancels them when the habit is logged, paused, archived or edited. Applied — reminders planned near-term and cancelled on log
G-44 J5 · TD-01 The order of habits on Today is unspecified. Groups first (as pills), then ungrouped habits by window start (all-day last), then title. Applied — order of habits on Today
G-45 J6 · entry There is no way to start Night Planning from Today. The docs say Today has an "entry to Night Planning", but TD-01 lists none. A Plan tomorrow action in Today's toolbar (after Add); a quiet row after the planning time if tonight isn't planned or skipped; the action on the all-done state. Applied
G-46 J6 · entry Coming back to a night that's already closed or skipped is undefined. Opening for a forDate that has a session resumes it: a closed one at Build (to adjust), a skipped one clears skippedAt and starts at Review. Re-closing upserts DayPlan again. Applied
G-47 J6 · NP-03 Build tomorrow says "select, reorder and add Tasks and Habits". Habits are scheduled, not chosen, and there is no manual ordering. Tomorrow's habits are shown read-only; tasks aren't reorderable; the actions are pull in, push out, add a task, add a one-off Anchor. Correct the night-planning doc. Applied
G-48 J6 · NP-03/04 "Deferral" is defined too broadly. Pushing tomorrow's task to Thursday while planning, or the overload Move, would count as deferrals and push tasks toward "stale" — punishing planning. A deferral is a task moved later when its due day has already arrived. Moving a task that is due later is rescheduling: no count, no DeferralRecord, no easing. Applied — important
G-49 J6 · NP-03 Gaps have no edge rules. Tiny gaps, and a day that begins or ends with a commitment, aren't covered. Hide gaps under 20 minutes (they still count as free time); no "before" gap if the day begins with a commitment, no "after" gap if it ends with one; names use the composed Anchor titles; fit checks use the longest gap. Applied
G-50 J6 · NP-04 "Move it to Wednesday" isn't computable. Which task and which day is undefined. Suggest the lowest-ordered movable task (not doFirst) on the nearest of the next seven days whose load stays under 100%; if none, ask for a date. A rescheduling (G-48). Applied
G-51 J6 · NP-04 The chosen level is lost if the app closes mid-flow. NightPlanningSession has no capacity field. Write DayPlan(forDate).capacity the moment it's chosen; Close fills the snapshot. Applied
G-52 J6 · entry Tonight's prompt would still fire after the user has already planned. The planner cancels tonight's prompt once that night's session is closed or skipped, and never repeats it; the banner on Today stays until planned or skipped. Applied
G-53 J6 · TD-07 The morning card opens "a shortened Build tomorrow for today" — undefined. A session with forDate = today that starts at Build, then Load, then Close; Review and Carry are skipped (leftovers were settled at rollover). Applied
G-54 J7 · ST-02 Changing the rollover mid-day can flip "today" backwards. Moving it from 00:00 to 03:00 at 01:30 makes the logical date yesterday again, while things logged since midnight carry today's date. Allow the change only when the current time of day is after both the old and the new rollover; otherwise the control is disabled ("Available after 03:00"). It applies from the next boundary. Applied
G-55 J7 · ST-02 The normal-day suggestion (and wellbeing) read DayPlans that don't exist for unplanned days. A DayPlan is only written when a day is planned or the slider moved. The rollover step creates DayPlan(D) if missing for any ended day with activity, then finalises it; days with no activity get none. Applied
G-56 J7 · TD-01/ST-02 Derived Low and High budgets are untidy (⅔ and 4⁄3 of a 3h25m day reads "Low · 2h 17m"). Round Low and High to the nearest 5 minutes, for display and calculation. Applied
G-57 J7 · ST-02 Nothing relates the planning time to the end of the working day. A quiet note in Settings when planning time is before the working day ends; never blocked. Applied
G-58 J8 · WB-01 Mood is attached to the wrong day. Moot: mood removed (G-67). Withdrawn
G-59 J8 · TD-02/WB-03 "Seven days of history" is undefined. DayPlans exist only for active days; calendar days since install is a different count. An active day has a DayPlan. Gathering data lasts until 7 active days lie in the last 14 logical days. Applied
G-60 J8 · WB-01 completionRate has no denominator. Deferred tasks are re-dated, so "due that day" can't be recounted. At rollover: completed that day ÷ (completed + deferred or dropped that day). Days with neither aren't counted. Applied
G-61 J8 · WB-01 wasOverloaded is only a planning snapshot. A skipped night leaves zero load, and a plan isn't the day as lived. Rollover finalisation also sets planned minutes, loadScore and wasOverloaded from the day as lived (module 7, that day's level). Applied
G-62 J8 · WB-01/TD-02 The score has no recipe (X-04). Inputs are listed but not weights, window or trend. 14-day window over active days: tasks 35%, Anchors attended 25%, habits 20%, load 20%. Sparkline per day over trailing 14 days, shown from 7 active days. Trend words, not numbers. Strained when any pattern is active. Applied
G-63 J8 · WB-02 Patterns aren't computable as written, and avoidance duplicates the per-task deferral escalation. Define heavyRun (3 consecutive overloaded), habitNeglect (3 scheduled misses; excludes paused, weekly-target, avoid), completionCollapse (last 3 < half of prior 14 and < 40%), weekendOverplan (2 of last 3 weekends). Remove avoidance. Applied
G-64 J8 · WB-02 Only "Lighten Saturday" is drawn, and what it writes isn't said. One definite action per pattern: low day tomorrow; weekday default to low; normal day to the recent average (15 min); pause or shrink the habit. Always with Not now. Applied
G-65 J8 · WB-02 The nudge has no home and no memory of "Not now". An inline card (tab, and once a day on Today), never a notification in v1. One a day; a dismissed pattern isn't offered for 7 days. A preference turns cards off. Applied
G-66 J8 · WB-01 The mood note is stored but never shown. Moot: mood removed (G-67). Withdrawn
G-67 J8 · NP-01 Self-reporting doesn't belong in a behaviour-derived score. The Review step's optional mood line, and NightPlanningSession.mood / moodNote, would feed it. Remove mood entirely (owner decision): fields, Review line and score input. Wellbeing is completion of tasks and habits around the Anchors, nothing else. Applied
G-68 J9 · ST-05 There is no access state. "Trial / subscribed / read-only" is prose; grace periods, billing retry and offline aren't covered. A pure AccessState (trial / subscribed / readOnly); grace and retry count as subscribed; last-known entitlement cached locally for offline; an expiry only applies when StoreKit confirms it. Applied
G-69 J9 · ST-05 The trial's start and end aren't defined. Two possible start sources, and "14 days" against the rollover. Start = earlier of StoreKit's original-download date and firstLaunchAt; 14 logical days, day 1 the start day; ends at the next rollover; "days left" counts logical days. Applied
G-70 J9 · all "Locked vs allowed" is a category list, not a rule per action (Begin, past-day corrections, Not today, Defer/Drop, automatic rules). A per-action table: living the day is always allowed (incl. Begin, logging, Anchor outcomes, undo, export); shaping the plan needs a subscription (create, edit, Drop/Defer, Night Planning, capacity, archive/restore). Applied
G-71 J9 · SB-03 How a locked control behaves is undefined — hidden looks broken, greyed is a mystery. Stay visible; tapping opens one calm sheet with Subscribe / Not now. Pure planning toolbar items (Plan tomorrow) are hidden. Applied
G-72 J9 · SB-01 "Paywall on next open" is undefined, and so is what the engine does while read-only. Paywall once on the first open of each logical day, never mid-session. The engine keeps running (auto-deferral, DayPlan, generation, repeats); notifications stop except trial reminders. Anchor window reminders: owner to choose. Applied
G-73 J9 · SB-02 Trial reminders have no time, and cancelling isn't specified. 09:00 local on days 12, 14 and 15; cancelled on subscribing; off on devices with reminders off. Planner stops or starts other notifications on access state. Applied
G-74 J9 · SB-01 Mid-flow expiry or purchase isn't covered (Night Planning open, timer running). Check entitlement when an action starts; a running session can always finish; an open planning session ends as skipped at rollover; subscribing lifts locks at once. Applied
G-75 J9 · ST-08 "Delete my data" would sync back if only local. Two confirmations; delete locally and in iCloud; reset to first launch. Export and delete always available. Applied
G-76 J10 · OB-05/ST-03 "Denied" is three states (not asked, denied, turned off later), and the local switch can disagree with the permission. Read status on launch and foreground; Turn on reminders (not asked) / link to Settings (denied); the planner needs the switch and permission; ST-03 shows both. Applied
G-77 J10 · SY-01 Denial silences far more than the planning prompt (Anchor, habit, morning, trial reminders), and the banner has no limits; it is also conflated with the Plan tomorrow row. ST-03 card lists what isn't delivered; a quiet line where a reminder is configured; Today banner only if the switch is on and permission off, once a day, dismissible, with Don't remind me; distinct from the Plan tomorrow row; none on a deliberately quiet device. Applied
G-78 J10 · notifications Tapping a notification has no defined destination. Planning → Night Planning; Anchor/habit → Today at that row; trial → ST-05. No action buttons and default interruption level in v1. Applied
G-79 J10 · ST-06/SY-05 "Only when there is a problem" isn't defined. States: signed in, not signed in, restricted, storage full, sync trouble (3 failures over a day). Offline never counts. One quiet dismissible line on Today; always says the data is safe and what fixes it. Applied
G-80 J10 · ST-06 Signing out or changing iCloud account may reset the synced store — unverified. Listen for account changes; pause rollover and sync work; notice with Export first. Requires a real-device spike (Phase 3) before TestFlight. Applied
G-81 J10 · launch A store that fails to open would crash the app with no way back. A recovery screen: Try again, or Reset this device's data (two confirmations; iCloud copy re-downloads). Never silent. Applied
G-82 J10 · schema An older app reading an unknown raw value from a newer one has no fallback. Every raw read falls back to an inert unknown; rows kept and never rewritten; excluded from counts and the score; a quiet Update Jamaal where not displayable. Applied
G-83 J10 · register F15 contradicts Journey 3 (settle sheet vs the quiet line for a timer clash). Correct the register to the quiet line. Applied
G-84 J11 · OB-06/ST-04 Category colours are undefined (G-08), and the only accents (accent, terra) can't carry them (terra means warning). Five fixed label colours as ThreadsKit tokens: accent (teal, existing default), blue, ochre, plum, slate; defaults Personal=accent, Family=ochre, Work=blue. A label is a dot plus the name in ink. ThreadsKit 1.2.0; hues to confirm against Design. Unknown key → slate. Applied
G-85 J11 · ST-04 Names have no rules, and user-created duplicates across devices aren't merged. Trimmed, 1–24 characters, unique ignoring case (archived included). The engine dedups user-created categories by normalised name, keeping the earliest and moving the tasks. Applied
G-86 J11 · TK-06 Tasks under an archived category aren't specified (Today, picker, repeats, history). The task keeps and shows its label; archived is absent from picker and filter except as the current selection when editing; repeats copy it; found under All; history unchanged. Settles the app-flow open question. Applied
G-87 J11 · TD-03 "Narrows the whole list" is undefined (Anchors and habits have no category; meter; Start here; persistence; empty result). Filters Tasks only; Anchors and habits always shown; meter, load and Also today whole-day; Start here from visible tasks; local, clears at rollover and relaunch; "Nothing in Family today." with Show all. Applied
G-88 J11 · TK-01 New tasks' default category is unspecified. None, unless a filter is active, then inherit it. Applied
G-89 J11 · ST-04 Nothing limits the list or orders it. At most eight active; drag to reorder; picker and filter share the order; merged duplicates take the earliest's position. Applied

Open owner items

What the walkthroughs could not settle alone, in one place. None blocks starting JamaalCore.

Decisions and reviews

  • Anchor window reminders while read-only (G-72): the default stops them with everything else; the alternative keeps just those. Revisit before building notifications.
  • Region → calculation-method table and preset values (anchor.md, habit.md): the owner reviews them (Qur'an 15 min timed, dhikr 33 counted); the freeze checklist item Habit preset definitions is still unchecked.
  • Avoid-habit screen (HB-08): pick one of Design's two drawn treatments.
  • Category label hues (G-84): confirm against the Claude Design tokens before ThreadsKit 1.2.0 is cut.
  • Fonts: bundling and licences for Fraunces, Hanken Grotesk and JetBrains Mono, in ThreadsKit.
  • Family Sharing for the subscription, and whether an import from the JSON export is wanted later (v1 has export only).
  • Constants to tune in real use: the wellbeing weights and pattern thresholds, the load thresholds, and the other numbers in the rules engine's open questions.
  • Owner review of the schema before JamaalCore models are written.

Work outside the docs

  • Merge the stacked PRs in order: #61 → #63 → #65 → #67 → #69 → #71 → #73 → #75 → #77 → #79 → #81 → #82 → the one after it.
  • ThreadsKit 1.2.0: the five category label tokens, then bump the dependency.
  • macOS destination in Xcode, then verify the build and add macOS to CI.
  • Paid Apple Developer Program enrolment and the CloudKit container (Phase 3 at the latest), then the real-device iCloud spike (G-80).
  • Claude Design redraw from the register and the brief; mockups/ is still empty.
  • Start JamaalCore models, tests first (14 SwiftData models), then the engine modules in dependency order.