POC Domain vs Rebuild client_sdk — Gap Analysis (2026-06-16)
Audit of what domain models and rules exist in the POC (../Chore_app)
that are not yet in the rebuild's client_sdk. Drives the SDK-hardening effort:
close every Tier-0 gap before building UI, so the data layer is finalized and we
don't keep re-opening it.
Summary
The rebuild SDK is a clean re-derivation of the POC's economy core and is
stronger than the POC on the invariants (POC stores mutable wallet balances
and credits wallet_bank directly; the rebuild's append-only ledger + zero-floor
- single-token-path are strictly better). ~80% of the Tier-0 economy/work domain is in place. The Tier-0 gaps are concentrated in: household money-config + earn split, chore recurrence/rollover, member roles/status + co-parent invites, terms-version gating, the household product feature-flags, and a set of cosmetic/archive fields. Buckets B (deferred) and C (intentionally dropped) check out — no accidental omissions.
Bucket A — Tier-0 gaps (actionable; the hardening work)
A.1 Missing models
| Model | POC location | Note |
|---|---|---|
EarningsSplit (give/save/spend %, fallback 10/40/50) | models/sdk/household.dart | Data behind §3 bucket routing; rebuild's EarnSplitPolicy is a hardcoded all-to-spend stub. |
TermsVersion / kCurrentTermsVersion | models/sdk/terms_version.dart + auth_service | §4/§7 Tier-0; absent (no model, method, or column). |
HouseholdFeatureFlags (4 toggles: stepBreakdown, activityGating, tithe, printableLists) | models/sdk/household_feature_flags.dart | §5 mandates a system distinct from entitlements; rebuild built only entitlements. |
HouseholdTrait (per-member affordances) | POC trait registry | §3/§4 "…age, traits"; absent. |
A.2 Missing fields (shared entities)
- Household:
currencyPerToken,split(EarningsSplit),emoji,giveDestinationName. - Chore:
emoji,weeklyDays,isActive(archive),placeIds/room assignees (Tier-0/1); deferred:estimateMin,assignedKidIds,maxPerDay/multiPerDay,tempBonus*,stepsPerKid. - Subtask:
minutes,placeId,assigneeId(deferred Tier-1);emojivs rebuildiconis just a rename. - HouseholdMember:
emoji,colorKey,traits,roles(MemberRole),status(MemberStatus), invite fields (inviteToken,invitedAt,inviteNote,expiresAt,email) — all Tier-0; deferred: birthday, homePlaceId, watchOnly. - Reward/Activity:
emoji,isActive(Tier-0); kind/description/appliesToKidIds (Tier-1). - Goal:
emoji,GoalScope.family(Tier-0 — rebuild requires memberId so a family goal can't exist); status/requested/imageUrl (Tier-1).
A.3 Missing enums / values
MemberRole {admin, helper, member}— Tier-0.MemberStatus {shadow, invited, active}— Tier-0.GoalScope {family, kid, parent}—familyis Tier-0.RewardKind {activity, item}— Tier-0/1.- Deferred:
ChoreFrequency.multiPerDay,GoalStatus,TempBonusUntil,TokenOwnerKind. - Note: rebuild
MemberKind {parent, coParent, child}is a deliberate redesign vs POC's kind+role split — keep it; layerMemberRoleon top.
A.4 Missing rules
| Rule | POC location | Note |
|---|---|---|
| Earnings-split routing (credit into give/save/spend per household split) | EarningsSplit + allocate flow | Rebuild EarnSplitPolicy = hardcoded {spend: amount}. The single most concrete rule stub. |
Daily/weekly chore rollover (re-present stale completions; once never clears; weekly uses weeklyDays) | chores_service.rolloverChoreCompletions | Rebuild has ChoreFrequency but no rollover engine — a daily chore never re-appears. |
| Terms-version re-acceptance gating on launch | auth_service + terms_version | Absent. |
| Signup captures username + country | spec §4 | Gap in BOTH POC and rebuild vs spec — add to rebuild. |
| Co-parent invite lifecycle (invite/resend/revoke, token gen, status transitions) | members_service.dart | Rebuild has add/remove member only. |
Invite/member expiry (expiresAt → no access) | HouseholdMemberPolicy | Absent. |
| Household product-flag gating | HouseholdFeatureFlags.isProductEnabled | No household-flag system. |
Rebuild rules already present and good (do not regress): zero-floor; single token path; parental-only approval; claimBounty age/already-claimed; auto-approver-must-be-parental; can't-remove-last-parent; activity gates (required-chore + min-balance); affordability surfaces-not-blocks; cancel-is-non-punitive.
Bucket B — Deferred-by-design (present in POC, expected-absent)
- Tier-1: chore assignedKidIds/estimateMin/maxPerDay, recurring-bounty completion; subtask minutes/place/assignee; RewardKind/description; Goal status/requested/image; submission partial-subtask ticking; member birthday/homePlace/watchOnly; TokenBatch goal ownership + transfer.
- Tier-2: temp-bonus tokens + expiry prune; fade engine (enum placeholder only); Kudos/family meter (unmodeled in both).
- Tier-3: ChoreRecommendation/Suggestion (AI recommender); per-kid steps (
stepsPerKid); subtask-icon catalog; AI sub-flags. - Tier-4: family-budget subsystem (planCents/spentCents/monthKey/rollover); parentWallet; grandparent/babysitter kinds; photo verification; HSA/FSA; gift-card redemption.
Bucket C — Intentionally dropped (confirmed absent per §8)
Legacy duplicate model set; Kid model; mutable embedded Wallet; brand-coupled flag sprawl (the 4 base flags themselves are a real gap, A.1); parent-scoped tenancy (parent_id); AppUser SDK model; legacyChildId; idiosyncratic brand naming. All correctly gone.
Hardening sequence (each its own tested commit)
- Household economy config + real earn-split — Household.currencyPerToken + EarningsSplit; replace EarnSplitPolicy stub with the household split.
- Chore recurrence + rollover — Chore.weeklyDays + isActive; port rolloverChoreCompletions.
- Member roles/status + co-parent invite lifecycle — MemberRole, MemberStatus, invite fields + invite/resend/revoke.
- Terms-version gating — TermsVersion + accept/re-prompt + column; plus signup username/country.
- Household product feature-flags — the 4 toggles, distinct from entitlements; wire activityGating to the existing ActivityGate path.
- Cosmetic/archive fields — emoji/isActive across Chore/Reward/Activity/Goal; member emoji/colorKey/traits + HouseholdTrait; GoalScope.family.