Implementation Tracker (Phase 1 MVP) β
As of: 2026-09-22 Β· Spec: PRODUCT_CONTEXT.md
Legend: π’ Done Β· π‘ Partial Β· π΄ Not Started Β· βͺ Dropped Β· π΅ Open/TBD
Summary Statistics β
| Metric | Count | Share |
|---|---|---|
| Total requirements tracked | 58 | 100% (C01βC18 + FR01βFR19 + AC01βAC21) |
| π’ Done | 2 | 3% |
| π‘ Partial | 28 | 48% |
| π΄ Not Started | 13 | 22% |
| βͺ Dropped | 9 | 16% |
| π΅ Open / TBD | 6 | 10% |
Product Boundary Requirements (C01βC18) β
| ID | Requirement | Status | Evidence / Notes | Source |
|---|---|---|---|---|
| C01 | Standalone SaaS; separate deployment, credentials, data boundaries | π‘ Partial | Sophia monorepo + own Mongo/S3/Stripe/Fargate path; shared cleverhire-bot and no production CleverHire adapter. Independence gate AC16 not qualified. | Β§3.1(1), Β§7.1, AC16 |
| C02 | Public self-service signup without routine Highbrow activation | π’ Done | POST /v1/auth/signup, Google signup, workspace creation (auth.routes.ts, auth.service.ts). ONBOARDING still says sales-led β stale. | Β§3.1(2), Β§7.1 C02, Β§23.1 |
| C03 | Stripe USD checkout; public product/pricing/help/policy pages | π‘ Partial | Stripe Checkout + webhook (credit.routes.ts, stripe-webhook.routes.ts). No public marketing/pricing/help/policy pages or sample report in apps/web. | Β§3.1(3), Β§12.3 |
| C04 | Prepaid minute credits; max-duration reserve; charge actual usage | π‘ Partial | Lots, ledger, reserve/settle/release (credit.service.ts, LedgerCreditsProvider). Trial grant optional (TRIAL_CREDITS_*) β conflicts with βno free live creditsβ when enabled. | Β§3.1(9), Β§7.1 C04, Β§8.1 |
| C05 | Exactly two roles: admin and member; creator starts admin | π’ Done | EUserRole.ADMIN / MEMBER in @sophia/shared; first signup user is admin. | Β§7.1 C05, Β§23.2 |
| C06 | Members: own interviews only; no private billing | π‘ Partial | Credit routes admin-only; billing UI gated. Interview list/detail not filtered by createdBy for members (interview.routes.ts comment vs interview.service.ts). | Β§7.1 C06, Β§4.2 |
| C07 | Admins: all interviews, team, billing, per-scheduler usage | π‘ Partial | Team, credits summary/history/lots, admin delete interview. No usage/spend CSV export API. | Β§7.1 C07, FR14 |
| C08 | One workspace/account; last-admin protection; immediate role effects | π‘ Partial | countActiveAdmins + team demotion guards (team.service.ts). Multi-workspace per account / immutable creator not fully verified. | Β§7.1 C08, Β§6.2 |
| C09 | Cognito; Google + email/password; no enterprise SSO | π‘ Partial | Firebase Auth + Google (auth.firebase.ts) β functional overlap, spec mismatch vs Cognito. | Β§7.1 C09, Β§23, T-002 |
| C10 | Shared templates + bulk scheduling | π΅ Open / βͺ | Templates βͺ dropped (10 Sep). Bulk CSV/XLSX fate unresolved β no bulk UI/API. | Β§7.1 C10, D13, D26, Q14 |
| C11 | Google/Microsoft calendar; slots; self-booking | βͺ Dropped | Day-window + ICS email replaces calendar integration. | Β§7.1 C11, D14 |
| C12 | English 1:1 AI interview; 5/10/15/20/30 min (default 20) | π‘ Partial | Duration on positions/interviews; candidate live via Daily + bot session. Full browser matrix / enforcement not qualified. | Β§7.1 C12, contracts |
| C13 | Sofia first; CleverHire consumes service later | π΅ Open | Strategy tension with AGENTS.md module rule (Β§23.3). No production adapter. | Β§7.1 C13, G5 |
| C14 | Broad ATS compatibility later phase | π΅ Open | Zod contracts only; no adapter tests shipped. | Β§7.1 C14, FR18 |
| C15 | First-time user/candidate usability as release gate | π΄ Not Started | No recorded 5-participant usability qual (AC19). | Β§7.1 C15, Β§17.3 |
| C16 | Delivery ownership, four-week plan, QA week | π΅ Open | Process/meta; milestones need re-baseline (Β§18.6). | Β§7.1 C16 |
| C17 | Competitive pricing; viable measured cost | π΄ Not Started | Prices in spec; no blended $0.15/min measurement in repo. | Β§7.1 C17, Β§17.4 |
| C18 | Phase 1 phone/person/eye + credibility; dual camera Phase 2 | π΄ Not Started | proctoring.credibility schema + PATCH from bot; no FR19-grade detectors in Sophia web. Dual camera correctly out of scope. | Β§7.1 C18, FR19, Β§23.11 |
Functional Requirements (FR01βFR19) β
| ID | Requirement | Status | Evidence / Notes | Source |
|---|---|---|---|---|
| FR01 | Signup/join: public signup, workspace, first admin; invitee joins intended workspace | π‘ Partial | Signup + Google + verify flows; team invite accept (AcceptInvitePage.tsx). Invite email dev-only (DevInvitationProvider). | Β§7.2 FR01, Β§6.1β6.2 |
| FR02 | Accounts: reset, verification resend, logout; no unsafe identity merge | π‘ Partial | Firebase client flows + API logout/revoke; linking rules not fully tested. | Β§7.2 FR02 |
| FR03 | Membership conflicts: no auto-transfer; no domain auto-join | π‘ Partial | Single org per user model; edge cases not qualified. | Β§7.2 FR03 |
| FR04 | Calendar consent separation | βͺ Dropped | Calendar integration removed. | Β§7.2 FR04 |
| FR05 | Shared recruiter templates | βͺ Dropped | Positions replace template library. | Β§7.2 FR05, D13 |
| FR06 | Bulk CSV/XLSX scheduling | π΅ Open | Not implemented; fate undecided (Q14). | Β§7.2 FR06, D26 |
| FR07 | Draft caps, resend limits, immutability after send | π΅ Open | Resend rate limit in API; draft/staging caps not enforced. | Β§7.2 FR07, Β§5.16 |
| FR08 | Calendar integration | βͺ Dropped | β | Β§7.4 |
| FR09 | Appointments / self-booking | βͺ Dropped | Day-window model instead. | Β§7.4 |
| FR10 | Candidate runtime: private pages, consent, screen share, recovery, FR19 detectors | π‘ Partial | Join, lobby, device checks incl. screen share (useDeviceChecks.ts), Daily live. No phone/person/true gaze; not full browser matrix. | Β§7.5 FR10 |
| FR11 | Calendar/appointments (continued) | βͺ Dropped | β | Β§7.4 |
| FR12 | Results: honest skills, transcript, recording, integrity, notes, PDF/export | π‘ Partial | Report generation with assessed + insufficient_evidence (report-generation.service.ts). No report UI, PDF, or evidence export routes. | Β§7.5 FR12, T-015 |
| FR13 | Credits/commercial packs; integer credit-seconds; charge rules | π‘ Partial | Packs via Stripe; ledger types; settle charges floor(seconds/60). Chargeback/deficit not built. | Β§7.6 FR13 |
| FR14 | Admin billing dashboard, alerts, member funding messages | π‘ Partial | Billing page + ledger; funding alerts / member-only messaging incomplete. | Β§7.6 FR14 |
| FR15 | Email + in-product notifications | π΄ Not Started | No notification consumer; T-017 open. | Β§7.7 FR15 |
| FR16 | Retention, export windows, purge, holds | π‘ Partial | retentionExpiresAt on interview; settlement sets default 60d. No purge sweeper, export pipeline, or holds. | Β§7.7 FR16, T-018 |
| FR17 | Ops: capacity limits, monitoring, operator console, support roster | π΄ Not Started | No operator routes; no 10/3 concurrency enforcement; no on-call artifacts in repo. | Β§7.7 FR17 |
| FR18 | Extraction: versioned contracts, adapter tests, reuse bot pipeline | π‘ Partial | Bot context/start/complete routes; shared Zod contracts. No adapter contract test suite; bot still CleverHire-coupled in prod. | Β§7.8 FR18 |
| FR19 | Phase 1 proctoring: phone/person/eye + credibility (amended) | π΄ Not Started | Proctoring blob + credibility fields on model; no qualifying detector pipeline in Sophia. | Β§7.9 FR19, D16βD17 |
Acceptance Criteria (AC01βAC21) β
| ID | Requirement (summary) | Status | Evidence / Notes | Source |
|---|---|---|---|---|
| AC01 | Public signup β workspace β first admin; resumable abandoned signup | π‘ Partial | Signup + org + admin role implemented; resumable signup not qualified. | Β§6.1, AC01/AC02 refs |
| AC02 | Invitee joins intended workspace/role; safe identity linking | π‘ Partial | Invite accept flow; email delivery stub; takeover edge cases not tested. | Β§6.2, Β§7.2 |
| AC03 | Two workspaces; tamper across APIs/files β zero leakage; member billing isolation | π΄ Not Started | Org-scoped repos + rules; no automated AC03 suite; member interview scope gap (C06). | Β§16.1, Β§17.3 |
| AC04 | One-workspace / invite conflict handling | π‘ Partial | Team service + invite expiry fields; full WAL22 scenarios not run. | Β§6.2 |
| AC05 | Positions, candidates, schedule prepared inputs (rΓ©sumΓ©, skills-fit) | π‘ Partial | CRUD + skills validation + resume upload; readability gate partial. | Β§6.4β6.6, FR07 survivors |
| AC06 | Bulk import scheduling (100 rows) | βͺ Dropped | Pending Q14 / QA re-baseline. | Β§3.3, Q13 |
| AC07 | Google Calendar integration | βͺ Dropped | β | Β§3.3, Q13 |
| AC08 | Candidate self-booking / slots | βͺ Dropped | Day-window replaces. | Β§3.3, Q13 |
| AC09 | Preflight failures β no live charge | π‘ Partial | Billing starts at live session; preflight not wired to meter end-to-end qual. | Β§6.7, WAL08 |
| AC10 | Live session, disconnect/recovery, terminal state + transcript preserved | π‘ Partial | Bot disconnect/rejoin routes; disconnected status on model; sweeper for abandoned not built. | Β§6.8β6.9, T-018 |
| AC11 | Wallet / ledger invariants (WAL01βWAL24 subset) | π‘ Partial | Atomic reserve/settle, Stripe idempotency; β₯1k sequence qual not run. | Β§15.1 |
| AC12 | Stripe purchase, webhook grant once, pending/failed grant nothing | π‘ Partial | stripe-webhook.routes.ts, duplicate handling; full WAL01β02 not qualified. | Β§6.3 |
| AC13 | Day-window scheduling + invitation (ICS) | π‘ Partial | expiryDays 7/14, window on interview; ICS + production email not sent. | Β§6.6, D14 |
| AC14 | Report quality: evidence, insufficient-evidence, no fabricated skills | π‘ Partial | LLM prompt enforces assessed; human β₯20-review gate not run. | Β§6.11, Β§17.3 |
| AC15 | Retention notices, export before purge, deletion/hold | π΄ Not Started | Retention timestamp only; no purge/export/hold jobs. | Β§6.14, FR16 |
| AC16 | Independence: CleverHire blocked; full paid journey on Sophia only | π‘ Partial | Data/API on Sophia; bot dependency + no formal AC16 test bundle. | Β§5.17, Β§10.10 |
| AC17 | Measured blended cost β€ $0.15/paid minute (release gate) | π΄ Not Started | No cost qualification artifact. | Β§3.3, Β§17.4 |
| AC18 | Platform failure injection: alerts β€60s, replay, backup/runbooks | π΄ Not Started | SQS DLQ infra; no fault-injection qual or runbooks in repo. | Β§15.3 |
| AC19 | Usability: 5 first-time users, β₯4/5 core tasks without coaching | π΄ Not Started | β | Β§17.3, Q31 |
| AC20 | Load: 10 concurrent (3/workspace), soak, 100-session day mix | π΄ Not Started | Bot default 3 cluster-wide; no qual harness. | Β§17.2 |
| AC21 | Proctoring qualification (PRO01β10, held-out set, false escalation) | π΄ Not Started | FR19 not implemented to gate level. | Β§15.2, Β§17.3, Q15 |
Decisions Register (D1βD28) β
| ID | Decision | Spec status | Implemented? | Conflicts / notes |
|---|---|---|---|---|
| D1 | Standalone public SaaS | FINAL | π‘ Partial | Own stack yes; shared bot + no AC16 sign-off. |
| D2 | Reuse shared Python bot | FINAL | π‘ Partial | Bot routes in API; production E2E incomplete. |
| D3 | Single shared DB + organizationId | FINAL | π’ Done | Models/repos follow data-access rules. |
| D4 | Ledger + cached org credits + reconciler | PROVISIONAL | π‘ Partial | Cache + ledger yes; reconciler job missing (T-018). |
| D5 | Reserve at schedule, settle at end, settledAt claim | FINAL | π’ Done | settlement.service.ts, credit reserve in schedule. |
| D6 | Charge actual seconds, not reserved max | FINAL | π‘ Partial | Settlement uses elapsed seconds; WAL matrix not qualified. |
| D7 | Frozen snapshot at schedule | FINAL | π’ Done | snapshot on interview; schedule copies resume text. |
| D8 | joinTokenHash on interview | PROVISIONAL | π’ Done | Hash stored; password + session token flow. |
| D9 | One candidates collection | FINAL | π’ Done | Candidate module + per-org email unique. |
| D10 | assessed + insufficient_evidence | FINAL | π’ Done | Report generation + Zod contracts. |
| D11 | deletedAt soft delete | PROVISIONAL | π’ Done | Used on core entities. |
| D12 | Integer credit-seconds | FINAL | π‘ Partial | Ledger integers; display rounding rules partial in UI. |
| D13 | Templates dropped | FINAL | βͺ N/A | Positions only. |
| D14 | Day-window + ICS; calendar dropped | FINAL | π‘ Partial | Window in code; ICS email not production. |
| D15 | Google + email Phase 1; no SSO | FINAL | π‘ Partial | Firebase not Cognito. |
| D16 | Hybrid eye + AI-likeness β credibility | FINAL | π΄ Not Started | Schema only. |
| D17 | Phone/person/eye remain Phase 1 | FINAL | π΄ Not Started | β |
| D18 | Dual camera Phase 2 | FINAL | βͺ N/A | Correctly out of scope. |
| D19 | positionId required | FINAL | π’ Done | Interview model requires position. |
| D20 | Separate interviewReports | FINAL | π’ Done | Report model + generation consumer. |
| D21 | Transcript in Mongo for now | PROVISIONAL | π’ Done | Inline on report document. |
| D22 | Free-text tags ~20 max | PROVISIONAL | π‘ Partial | Candidate tags; convention not enforced in schema. |
| D23 | Global-unique user email | PROVISIONAL | π’ Done | Unique index on user email. |
| D24 | disconnected + failureReason enum | PROVISIONAL | π’ Done | On interview model/status enum. |
| D25 | Skills + aiContext on position | PROVISIONAL | π’ Done | Position create + snapshot skills. |
| D26 | Bulk scheduling undecided | TBD | π΅ Open | No implementation. |
| D27 | Role naming admin/member | TBD | π’ Done | Code uses admin/member (Q21 effectively resolved in code). |
| D28 | Rejoin state embedded on interview | TBD | π’ Done | runtime subdocument on interview. |
Open Questions (Q1βQ32) β
| ID | Question | Status in code / product |
|---|---|---|
| Q1 | Global vs per-org user email | Resolved in code: global unique (D23). |
| Q2 | Store positions.description for bot | Resolved: snapshot + bot context use JD text. |
| Q3 | Transcript Mongo vs S3 | Resolved for now: Mongo on report (D21). |
| Q4 | interviewSessions collection | Resolved in code: embedded runtime (D28). |
| Q5 | credits.consumed rounding | Resolved by spec: floor seconds at settlement. |
| Q6 | Tags free-text vs managed | Open: free-text in code; degeneration accepted (D22). |
| Q7 | seniority field value | Open: kept; maps to experience level in practice. |
| Q8 | Rejoin embedded vs collection | Resolved: embedded (D28). |
| Q9 | Pin botType provider | Open: field exists, default openai. |
| Q10 | ICS shape + reminder timing for windows | Open: invitation subdoc; no production ICS. |
| Q11 | Eye-tracking on-device vs cloud | Open: D16 not implemented. |
| Q12 | Spec v0.5 lock date | Open: blocks formal QA sign-off. |
| Q13 | QA contract re-baseline | Open: AC06β08 still in PDF appendix. |
| Q14 | Bulk CSV fate | Open: not built. |
| Q15 | AC21/PRO gates after credibility redesign | Open: engineering must re-validate. |
| Q16 | Credibility threshold + compute location | Open: no production logic. |
| Q17 | Candidate reschedule/cancel on window model | Open: likely N/A; confirm with Kevin. |
| Q18 | No-show / late entry semantics | Open: expired window = no-show in working theory. |
| Q19 | Default window length options | Partial: org default 7; UI allows 7/14. |
| Q20 | Candidate password/challenge storage | Partial: join password on interview; security review open. |
| Q21 | admin/member vs owner/member | Resolved in code as admin/member; docs lag (Β§23.2). |
| Q22 | Self-serve vs sales-led | Resolved by product: self-serve; ONBOARDING stale. |
| Q23 | Ownership matrix | Open: follow PDF Appendix B; update ONBOARDING. |
| Q24 | Module inside CleverHire vs consumed service | Open: packages/ neutrality rule binds. |
| Q25 | 3 β 10 concurrent bots | Open / blocker: not implemented. |
| Q26 | Redis role | Open: not used in Sophia code paths. |
| Q27 | Which LLM paths run for reports | Open: OpenAI in report consumer; duplicate analysis not mapped. |
| Q28 | Contract versioning for ATS | Open: /v1 only. |
| Q29 | Admin 2FA / operator hardening | Open: not discussed in spec as required. |
| Q30 | QA $500 / infra $500 approval | Open: process/budget. |
| Q31 | Proctoring + usability participant recruitment | Open: AC19/AC21 blockers. |
| Q32 | Who runs fresh held-out qual after detector fix | Open: ownership unassigned. |