auth-polish-v2 — Three Workstreams Bundled, 18/18 Tasks Shipped
- Version
- v7.6
- Date
- 2026-05-01
- Tier
- light
auth-polish-v2 bundled three auth workstreams — forgot-password, biometric activation refinement, Google Sign-In SDK activation — into one feature/PRD/branch because they shared files, review surface, and QA scope. 18/18 PRD tasks shipped via PR #163 (squash 4f6c4cc) on 2026-05-01 in the framework-honesty-fixes merge marathon. Build-and-Test red on env-flake (parallel-clone sim gremlin per PR #166); pm-framework/pr-integrity passed.
- •Build-and-Test red at merge time on an env-flake unrelated to auth-polish-v2 (parallel-clone sim gremlin documented in PR #166 backlog task). pm-framework/pr-integrity passed clean. Admin-merged in the framework-honesty-fixes session because the failure was infrastructural, not behavioural.
- •state.json was reconciled retroactively on 2026-05-02 via PR #174, alongside framework-honesty-fixes and stats-v2. Three "silent-pass" features (auth-polish-v2 + framework-honesty-fixes + stats-v2) were brought to
current_phase: completewith full timing/log/PR-number backfill in one ledger pass. - •Phase 0 Research surfaced 1 existing-code finding (
ColorAppColortypos inAuthHubView.swift:635andAuthHubView.swift:825) — a silent build break dormant in the auth surface. Mitigated by starting Phase 4 withxcodebuild buildbefore any UI work. - •Apple Sign In Services-ID setup deferred (out-of-repo Apple Developer console action). AI smart reminder UI deferred (separate enhancement). Sentry MCP wiring deferred (Gate C peer).
- •cu_v2 populated on resume after v7.7 freeze: factors 0.6 / 0.7 / 0.4 / 0.6 → total 2.3, tier_class A_high. Auth = high-risk per CLAUDE.md. v7.7 dogfood instrumentation activated on the resume commit.
- •v7.7 freeze paused the PRD between 2026-04-27 14:00 UTC (substantively complete) and 2026-04-28 17:00 UTC (resumed). Wall-time gap: ~36 hours calendar; ~8.6 min of actual research+draft work.
How to read this case studyT1/T2/T3 · ledger · kill criterion▾
- T1Instrumented
- Numbers come from a machine-generated ledger or commit. Reproducible. Highest reader trust.
- T2Declared
- Numbers stated by a structured declaration (PRD, plan, frontmatter) but not directly measured.
- T3Narrative
- Estimates and observations from session memory. Useful for context; not citable as evidence.
- Ledger
- Where to verify the claim — a file path, GitHub issue, or backlog entry. Anything labelled
ledger:is the audit trail. - Kill criterion
- The pre-registered threshold under which this work would have been killed mid-flight. Not fired = work shipped without hitting the threshold.
- Deferred
- Items intentionally not closed in this version. Each cites the ledger that tracks remaining work.
- auth_biometric_activated < 5% by day 14 → iterate copy/timing once. Second miss → kill activation sheet, move to Settings-only.
- Google Sign-In > 0.5% crash/hang rate → flip GoogleRuntimeConfiguration.isConfigured = false via remote config.
- Forgot-password deep-link return < 90% success → regress to status-banner-only mode.
- Overall auth_signin_completed rate drops > 5% week-over-week → halt rollout; investigate SDK conflict.
docs/setup/auth-runtime-verification-playbook.mdOut-of-repo Apple Developer console action; cannot be self-executed.docs/product/backlog.mdSeparate enhancement; out of scope for v2 polish.project_sentry_integration_in_progress.mdGate C peer feature; awaits user-paste DSN + /mcp OAuth.state.json (target 2026-07-26 if shipped 2026-04-27)Post-launch review cadence per PRD; primary metric is auth recovery success rate composite.auth-polish-v2 — Three Workstreams Bundled, 18/18 Tasks Shipped
auth-polish-v2 bundled three auth workstreams — forgot-password recovery, biometric activation refinement, Google Sign-In SDK activation — into one feature/PRD/branch because they shared files, review surface, and QA scope. Splitting them into three branches would have multiplied merge conflicts and review overhead. The bundling decision is the operative choice of this case study.
Why bundle three workstreams
Auth surfaces in FitTracker2 are concentrated in a handful of files: AuthHubView.swift, SignInView.swift, SignInService.swift, AuthManager.swift. Three workstreams that all touch the same files share three things that argue against splitting:
- Shared review surface — same files; same security review attention; one reviewer pass instead of three.
- Shared QA scope — biometric + Google sign-in flows interleave with the same fallback paths; testing them together catches integration bugs that testing them separately would hide.
- Shared external dependencies —
GoogleSignIn-iOSintroduces nonce handling that the biometric-unlock fallback path also needs to be aware of.
The bundling is documented in PRD §1.2 as the explicit decision; the alternative (three sub-branches) was considered and rejected.
What shipped (18/18 PRD tasks)
| Workstream | Functional requirements | PR-1 outcome |
|---|---|---|
| Forgot-password | 6 (deep-link scheme, cooldown, status banner, return flow) | Shipped — fitme://reset-password URL scheme reserved |
| Biometric refinement | 6 (activation sheet timing, decline path, unlock UX, fallback) | Shipped — immediate-post-sign-in activation per OQ-1 lock |
| Google Sign-In | 6 (SDK 8.x install, nonce flow, Supabase exchange, GIDClientID source) | Shipped — GoogleService-Info.plist shared with Firebase analytics |
8 user flows documented end-to-end (A–H: forgot-password happy/cooldown, biometric activation/decline/unlock/fallback, Google new/returning). 9 analytics events specified. 4 kill criteria armed (see frontmatter).
v7.7 dogfood instrumentation activated on the resume commit
auth-polish-v2 is one of the first features to dogfood the v7.7 Validity Closure write-time gates from day one:
cache_hits[]gated byCACHE_HITS_EMPTY_POST_V6— empty array OK during work; required non-empty bycurrent_phase=completecu_v2schema validated byCU_V2_INVALID— passes (factors 0.6/0.7/0.4/0.6, total 2.3, tier_class A_high)case_studylink present in state.json (gatesSTATE_NO_CASE_STUDY_LINK)- This file's frontmatter satisfies
CASE_STUDY_MISSING_FIELDS(forward-only ≥ 2026-04-28; this is the first new case study after the cutoff)
Live verification at PRD approval: 45 state.json files pass v7.6 + v7.7 hooks before the auth-polish-v2 entry was committed.
Open questions resolved at PRD time
| OQ | Decision | Rationale |
|---|---|---|
| OQ-1: Activation-prompt timing | Immediate after first sign-in | Strava/Whoop pattern; receptiveness peaks at credential-entry moment |
| OQ-2: Forgot-password URL scheme | fitme://reset-password | Brand prefix, future-extensible |
OQ-3: GIDClientID source | GoogleService-Info.plist (shared with Firebase analytics) | Single source for Gate C config |
Risks (declared)
| Risk | Severity | Mitigation |
|---|---|---|
| GoogleSignIn 8.x nonce shift breaks Supabase exchange | High | Phase 4 vertical slice gate before UI work |
| Deep-link URL scheme conflict with future deep links | Medium | Reserve scheme + write docs/architecture/deep-linking.md |
ColorAppColor typos hide a silent build break | Medium | Phase 4 starts with xcodebuild build |
| Activation copy fails to drive ≥ 25% conversion | Medium | Day-14 review checkpoint; iterate; kill criteria documented |
Lessons
- Bundling shared-surface workstreams is cheaper than splitting. Three workstreams sharing four auth files = one PRD, one review pass, one QA scope. The "three sub-branches" alternative would have multiplied merge conflicts on
SignInService.swiftand split security-review attention three ways. Documented as the operative choice in PRD §1.2. - Existing-code findings surfaced during research are as valuable as new spec work. Phase 0 Research found
ColorAppColortypos inAuthHubView.swift:635/825— silent build breaks dormant on main. The mitigation (Phase 4 starts withxcodebuild build) was added to the plan as a result. - CI red on env-flake is not the same as CI red on content. PR #163 merged with Build-and-Test red on the parallel-clone sim gremlin (documented in PR #166 backlog). pm-framework/pr-integrity passed clean. Admin-merged in the framework-honesty-fixes session — the alternative (block until CI is fixed) would have rolled the broken-quarantine cost onto every other PR until the root-cause was resolved.
- state.json reconciliation in batches is OK if it's deliberate and ledgered. PR #174 (2026-05-02) brought three "silent-pass" features to
current_phase: completein one pass. The framework prefers contemporaneous ledgering (write-as-you-go), but a deliberate batched-reconciliation pass — with full timing/log/PR-number backfill — is honest if the ledger captures the lag.
Links
- Full upstream case study:
docs/case-studies/auth-polish-v2-case-study.md - PRD:
docs/product/prd/auth-polish-v2.md - State.json:
.claude/features/auth-polish-v2/state.json - PR #163 (squash
4f6c4cc): github.com/Regevba/FitTracker2/pull/163 - PR #174 (state.json reconciliation): github.com/Regevba/FitTracker2/pull/174
- GitHub Issue #143
- Predecessor:
onboarding-v2-auth-flow-v5.1-case-study.md - Companion at v7.6 mechanical layer: Mechanical Enforcement v7.6