# Track C Status — Learning Runtime (Learner-First)

Pre-flight (2026-09-27): GATE 1 artifacts verified on origin/main — T-A-01…T-A-06 all
merged (last merge 4ad28ae `[merge][T-A-05]`). Note: `track_a.md` still reads "Gate 1
Not yet passed" — that text predates the orchestrator's T-A-05 merge commit; the six
Phase-0 branches are verifiably in `git branch -r --merged origin/main`. Proceeding.

| Task | Status | Branch | Notes / blockers |
|---|---|---|---|
| T-C-01 | ✅ merged 2026-09-27 | track-c/T-C-01-base-learning-model | BaseLearningModel ($connection='learning', extends A's BaseDomainModel → audited), `database/migrations/learning/` prefix 20260924_03 with schema marker; lint test: all `Models/Learning` on learning connection; cross-DB-FK test via SQLite `foreign_key_list` introspection (every FK target must live on `learning`). 82 passing, 0 failing (full suite incl. T-C-01). |
| T-C-02 | ✅ merged 2026-09-27 — **CONTRACT FOR D** | track-c/T-C-02-progress-service | `App\Services\Learning\ProgressService` frozen to README signatures (reflection-locked in test): `courseProgress(userId)`, `topicMastery(userId)`, `streak(userId)`, `attemptsSummary(userId)`, `timeSpent(userId, window)`, `weakTopics(userId)`. **D: bind/inject `ProgressService` (interface) now — Phase-0 stub `ProgressServiceStub` returns empty iterables; real impl replaces the binding in T-C-16 (Gate 3). No container binding added (AppServiceProvider is A-owned) — D binds the interface in its own provider.** 85 passing, 0 failing (full suite, incl. merged T-C-01). |
| T-C-03 | 🚀 pushed + REBASED onto latest main 2026-09-27 — READY FOR ORCHESTRATOR MERGE (fast-forward on origin/main 328d911; all files inside C ownership — root SubscriptionService.php removed, gate now consumes the README-frozen Billing FQCN via Mockery like B T-B-03; suite green at head) | track-c/T-C-03-access-gate | `AccessGate::evaluate(userId, ContentAccess, contentScope)` → `AccessDecision` (allow/preview/deny + reason). Order = entitlement(A's README-frozen `App\Services\Billing\SubscriptionService` — T-A-17 impl not on main yet, so tested via Mockery against the frozen FQCN, same pattern as B's merged T-B-03; **A: no action needed, your impl binds by FQCN**) ∩ enrollment (port, T-C-04) ∩ parental (port, T-C-13) ∩ DRM (B T-B-06 flag on `ContentAccess` value object — never a direct catalog query). Preview only: unentitled + sample access + all other factors green; previews never bypass enrollment/parental/DRM. 10 AC tests, each flips exactly ONE factor. 138 passing, 0 failing (full suite, post-rebase on latest main). |
| T-C-04…T-C-11, T-C-13…T-C-17 | ⏳ todo | — | See developer_C.md. T-C-04 blocked on T-C-03 merge (now rebased onto latest main). |
| T-C-12 | ✅ merged 2026-09-27 (skip-ahead) | track-c/T-C-12-learner-profile | `learner_profiles` (+ append-only `learner_profile_changes`, no cross-DB FKs; user_id plain indexed col). Learner profile + 3-step onboarding (basic info: grade/board/≥1 subject; prefs: learning style exactly-one visual/auditory/kinesthetic/mixed, study-time 30min–4h slider, avoid list) + goals (target_score 0–100, future exam_date). Avoid-subjects excluded from `recommendedSubjects()` only — required assessments still built from focus. Change history on every post-onboarding preference update (applies from point of change). Routes: `GET/PUT /api/learner/profile`, `POST /api/learner/onboarding/{basic,preferences,goals}` behind `auth:sanctum` (learner-owned; RBAC roles are admin-surface — no `student` role exists, file as A question). ACs: missing grade 422; target 105 422; avoid-vs-assessment; style uniqueness. 128 passing, 0 failing (full suite, post-rebase incl. T-B-01..03). |

## Gates

- Gate 1 (end Phase 0): **PASSING ARTIFACTS, PENDING ORCHESTRATOR MERGE** — D can compile
  against ProgressService (T-C-02 merged ✅), learning DB green + no cross-DB FKs
  (T-C-01 merged ✅), AccessGate with test-double ports (T-C-03 pushed, awaiting merge).
  Once T-C-03 is merged, mark Gate 1 passed here.

## Environment note

Local worktree `worktrees/track-C` was found with its checkout missing (only `.env` +
`vendor` present); restored via `git worktree add` onto the `track-C` branch (origin/main)
and `composer install` (79 packages). No repo files touched by the restore.
