fitme·story
v7.6 · 4 min read
Summary card · 60-second read

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.

Honest disclosures
  • 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: complete with full timing/log/PR-number backfill in one ledger pass.
  • Phase 0 Research surfaced 1 existing-code finding (ColorAppColor typos in AuthHubView.swift:635 and AuthHubView.swift:825) — a silent build break dormant in the auth surface. Mitigated by starting Phase 4 with xcodebuild build before 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.
Pre auth-polish-v2
Three workstreams, three branches?
Forgot-password missing. Biometric activation copy unrefined. Google Sign-In SDK declared but not activated. Splitting across 3 branches = 3× merge conflicts + 3× review overhead on a shared file surface.
Post PR #163 (squash 4f6c4cc)
18/18 tasks · 1 bundled feature
Forgot-password deep-link (`fitme://reset-password`). Biometric activation sheet (immediate post-sign-in). GoogleSignIn-iOS 8.x activated via vertical-slice gate. 9 analytics events specified. 4 kill criteria armed.
Kill criterion · not fired
  • 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.
Deferred items
Apple Sign In Services-ID setupledger: docs/setup/auth-runtime-verification-playbook.mdOut-of-repo Apple Developer console action; cannot be self-executed.
AI smart reminder UI on auth surfacesledger: docs/product/backlog.mdSeparate enhancement; out of scope for v2 polish.
Sentry MCP wiringledger: project_sentry_integration_in_progress.mdGate C peer feature; awaits user-paste DSN + /mcp OAuth.
Day-90 metrics reviewledger: 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:

  1. Shared review surface — same files; same security review attention; one reviewer pass instead of three.
  2. 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.
  3. Shared external dependenciesGoogleSignIn-iOS introduces 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)

WorkstreamFunctional requirementsPR-1 outcome
Forgot-password6 (deep-link scheme, cooldown, status banner, return flow)Shipped — fitme://reset-password URL scheme reserved
Biometric refinement6 (activation sheet timing, decline path, unlock UX, fallback)Shipped — immediate-post-sign-in activation per OQ-1 lock
Google Sign-In6 (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 by CACHE_HITS_EMPTY_POST_V6 — empty array OK during work; required non-empty by current_phase=complete
  • cu_v2 schema validated by CU_V2_INVALID — passes (factors 0.6/0.7/0.4/0.6, total 2.3, tier_class A_high)
  • case_study link present in state.json (gates STATE_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

OQDecisionRationale
OQ-1: Activation-prompt timingImmediate after first sign-inStrava/Whoop pattern; receptiveness peaks at credential-entry moment
OQ-2: Forgot-password URL schemefitme://reset-passwordBrand prefix, future-extensible
OQ-3: GIDClientID sourceGoogleService-Info.plist (shared with Firebase analytics)Single source for Gate C config

Risks (declared)

RiskSeverityMitigation
GoogleSignIn 8.x nonce shift breaks Supabase exchangeHighPhase 4 vertical slice gate before UI work
Deep-link URL scheme conflict with future deep linksMediumReserve scheme + write docs/architecture/deep-linking.md
ColorAppColor typos hide a silent build breakMediumPhase 4 starts with xcodebuild build
Activation copy fails to drive ≥ 25% conversionMediumDay-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.swift and 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 ColorAppColor typos in AuthHubView.swift:635/825 — silent build breaks dormant on main. The mitigation (Phase 4 starts with xcodebuild 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: complete in 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