---
url: >-
  https://docs.nemo12.com/architecture/sdd-002-learner-intelligence/remediation-and-slices.md
description: >-
  Hệ vá chỗ hổng mastery bằng campaign có mở có đóng thế nào, và lát cắt IELTS,
  AI Teen nằm trong Learner Model ra sao.
---

# SDD-002 · Remediation Loop, lát cắt IELTS và AI Teen

Một phần của [SDD-002](./index.md).

## 22. Remediation Loop — nâng mastery khi hổng, có mở có đóng (REQ-INT-37, SRC-506)

Bối cảnh (SRC-506): chủ dự án đặt hai câu hỏi — "nâng mastery như thế nào khi learner hổng một vùng", và "cơ sở nào để tin việc nâng là phù hợp, có ích, không thiếu, không quá nhiều". Câu trả lời của thiết kế này: **cơ sở là một vòng lặp chẩn đoán–can thiệp–đo lại có stopping rule tường minh, không phải khối lượng content**. Các mảnh (Assessment §9, Recommendation §10, Learning §11, mastery update §7, confidence §8) đã có; mục này gói chúng thành một đơn vị vận hành có mở, có đóng, có bằng chứng.

### 22.1 Remediation Campaign — object hạng nhất

Mỗi lần hệ quyết định "nâng vùng X" là một **campaign** có vòng đời, không phải một chuỗi recommendation rời:

```text
RemediationCampaign: campaign_id · learner_id · trigger (readiness_gap | assessment | mentor | parent)
· surface_node (nơi TÍN HIỆU xuất hiện) · root_node (nơi GỐC RỄ nằm — có thể khác surface)
· baseline {mastery, confidence, đo lúc mở} · goal_ref (vì sao vùng này đáng nâng — §16)
· plan (bậc thang §22.3, sinh bởi Learning Engine) · stopping_rule (§22.4, chốt LÚC MỞ campaign)
· status (OPEN | ACTIVE | CLOSED_MASTERED | CLOSED_RECLASSIFIED | CLOSED_STALLED | CLOSED_ABANDONED)
· outcome {mastery, confidence, delta, đo lúc đóng} · versions (input_model_version, algorithm_version §15)
```

Luật kế thừa từ hệ: campaign là **computed + append-only lifecycle** (mở/đóng bằng event, không sửa tại chỗ), mọi transition ghi `engine_runs` (§19), mọi bước kèm `reason` truy về model (§15).

### 22.2 Mở campaign: chẩn đoán XUỐNG trước, dạy sau

Tín hiệu ở node A không có nghĩa gốc ở A (ba ca chuẩn môn toán, dùng làm test thiết kế: bậc hai ← phân tích nhân tử ← quy tắc dấu; xác suất ← số học phân số; đồ thị ← khái niệm hàm số/thay số — SRC-506):

1. **Đi xuống theo cạnh tiên quyết** (graph SDD-003): từ surface node, Assessment Engine (§9) probe các prerequisite theo InformationGain — mỗi node vài câu, dừng khi confidence đủ, đúng luật §9. `root_node` = node SÂU NHẤT có mastery dưới ngưỡng vai trò; các node trên nó vào plan theo thứ tự phụ thuộc.
2. **Phân loại trước khi dạy** — ba tình trạng, ba cách chữa khác nhau, cấm gộp:
   * `never-learned` (mastery thấp, chưa từng có evidence tốt) → dạy từ đầu (bậc thang đủ 4 bậc);
   * `forgotten` (historical_mastery cao, retention thấp — SDD-017) → **không mở campaign**, chuyển Retention/Review (§ SDD-017 §7); dạy lại từ đầu thứ learner từng vững là "quá nhiều";
   * `unreliable-evidence` (INSUFFICIENT_RELIABLE_EVIDENCE §18) → thu evidence sạch trước, chưa được kết luận hổng.
3. **Baseline chốt lúc mở**: mastery + confidence của root và các node trong plan. Không có baseline thì "có ích" không đo được.

### 22.3 Can thiệp: bậc thang của Learning Engine, đi từng node từ gốc lên

Trong mỗi node của plan, đi 4 bậc (output §11): **worked example → scaffold/practice có hint → practice độc lập → transfer** (bài trộn ngữ cảnh/khác dạng bề mặt). Difficulty Controller giữ bài ở vùng learner đúng ~70–80%. Hai luật:

* **Không nhảy node trên khi node dưới chưa đạt ngưỡng** của stopping rule — đúng nguyên tắc prerequisite fallback §11.
* **Bậc transfer là bắt buộc trước khi tính node "đã nâng"**: 10 câu đúng cùng dạng ngay sau khi học không phải bằng chứng (§8 đã chống bằng coverage/diversity factor; campaign biến nó thành điều kiện đóng).

### 22.4 Stopping rule — trả lời "đủ chưa, thừa chưa" bằng số

Chốt **lúc mở** campaign (không dời cột mốc giữa chừng), đối xứng với stopping của Assessment §9 và Depth §12:

* **Đóng `CLOSED_MASTERED`** khi root + mọi node trong plan đạt: `mastery ≥ ngưỡng theo vai trò` (prerequisite đang chặn chương sắp học ≈ 0.8; kỹ năng ngoại vi ≈ 0.6 — lấy từ `dependency_weight` và GoalRelevance, không một ngưỡng chung) **và** `confidence ≥ ngưỡng` **và** có ≥1 evidence transfer độc lập (không hint, khác dạng, cách phiên học ≥1 ngày — recency/independence weight §7 tự bảo đảm evidence này nặng ký).
* **Đóng `CLOSED_RECLASSIFIED`** khi sau một bậc can thiệp mà delta ≈ 0: nghi gốc còn sâu hơn hoặc sai loại (thực ra là retention/context) → quay lại §22.2, campaign cũ đóng với lý do, campaign mới trỏ `supersedes`. Cấm "bơm thêm bài" khi delta không nhích — đó chính là ca "nâng nhiều mà không có ích".
* **Đóng `CLOSED_STALLED`** khi chạm **budget**: mỗi campaign có trần thời gian/số bài lấy từ Workload/Constraint (SDD-007 §8) — điểm mà expected impact của bài tiếp theo ÷ cost rơi dưới các candidate khác của Recommendation §10. Stalled không phải thất bại im lặng: nổi lên cho mentor (REQ-MEN) kèm toàn bộ số liệu.
* **Chống thừa (overlearning)**: đạt stopping rule thì đóng, mọi luyện thêm cho node đó chuyển sang chế độ maintenance của Retention (SDD-017) — kế thừa overlearning protection §12.

### 22.5 Đo delta và bằng chứng "có ích"

`outcome.delta = mastery_đóng − baseline` tính riêng từng node, chỉ từ evidence độc lập sau can thiệp. Campaign đóng là một bản ghi tự đủ: vì sao mở (trigger + goal), chữa ở đâu (root ≠ surface), tốn bao nhiêu (bài/phút), được bao nhiêu (delta), vì sao dừng (rule nào khớp) — trả lời đúng bốn tiêu chí phù-hợp/có-ích/không-thiếu/không-thừa của SRC-506 bằng dữ liệu. Tổng hợp campaign theo môn/node là input cho content ops: node nào hay làm campaign stalled = chỗ content bậc thang đang mỏng.

### 22.6 Ràng buộc hiện thực (Phase sau, không trong SRC-506)

* Chẩn đoán xuống chỉ chạy được tới đâu **cạnh tiên quyết dày tới đó** — audit cạnh xuyên cấp lớp trong `docs/knowledge/` là việc riêng (Q-138).
* Evidence mức bước-làm-bài / loại lỗi (error taxonomy) làm chẩn đoán sắc hơn nhiều — việc riêng, không chặn v1 (v1 dùng probe per-node của Assessment; Q-139).
* Recommendation Engine xếp campaign ACTIVE vào hàng `repair` của REQ-INT-32 (SDD-021 §2.1) — repair vốn đã đứng sau review, trước exam_prep/new.

## 23. Lát cắt IELTS trong Learner Model (SRC-717, SRC-719, chỉ đạo 2026-09-14)

### 23.1 Vì sao là một LỚP bên trong, không phải một model ngang hàng

Learner Model đã trả lời "learner này làm được gì". Dựng thêm một model riêng cho IELTS là có hai
chỗ cùng nói về năng lực của một đứa trẻ, và hai chỗ như vậy sớm muộn lệch nhau mà **không cổng nào
bắt được** — cả hai đều "chạy đúng" theo định nghĩa của chính nó.

Nên `content.ielts` là một lát cắt nằm trong chính bản chụp Learner Model, sinh cùng một lúc, đọc
cùng bằng chứng. Bản chụp vì thế lên `learner-v3`: hình dạng content đổi, và người đọc lại lịch sử
phải phân biệt được bản chụp có lát cắt với bản chụp không có.

### 23.2 Ba nguồn vào, và chúng KHÔNG ngang giá nhau

| Nguồn | Là gì | Sống ở đâu |
| --- | --- | --- |
| **Declared** | Thứ learner **tin** về mình | `learner_ielts_declarations` (0218), `learner_ielts_baselines` (0217) |
| **Measured** | Thứ learner **làm được** | `assessment_responses` + `learner_evidence`, quy về strand |
| **Target** | Thứ learner **đang nhắm** | `learner_ielts_goals` + milestones |

Giá trị lớn nhất của lát cắt KHÔNG phải một con số tổng hợp, mà là **khoảng lệch giữa Declared và
Measured**. Một người tin mình yếu Listening trong khi bài làm cho thấy Listening đang là kỹ năng
tốt nhất đang phân bổ sai thời gian của chính mình — và không ai nói cho họ biết, vì họ là người
duy nhất đang nhìn cả hai nguồn, mà lại nhìn từ bên trong.

`calibrate()` chỉ kết luận khi chênh lệch vượt **0.15**. Dưới ngưỡng đó là nhiễu, và một câu như
"con đang đánh giá sai về mình" dựng trên nhiễu là loại sai tệ nhất: nó nghe sâu sắc nên được tin
ngay. Thiếu bằng chứng thì trả `unknown` **kèm câu nói rõ vì sao chưa nói được** — im lặng ở đây sẽ
bị đọc thành "không có gì bất thường".

### 23.3 Suy luận không cần đo: `flags`

Phần rẻ nhất và hay bị bỏ qua nhất. Đọc lời khai là đã thấy việc phải làm:

* bài viết chưa ai chữa, trong khi mục tiêu đòi tăng Writing;
* chưa có ai để luyện nói, trong khi mục tiêu đòi tăng Speaking;
* đã thi thật nhưng điểm hiện tại vẫn là tự đoán;
* học hơn một năm mà điểm còn thấp → nói về **cách luyện**, không nói về sự chăm chỉ.

### 23.4 Bài đo ngắn: đo được gì và KHÔNG đo được gì

Mười hai câu (ba câu mỗi kỹ năng, lấy từ ngân hàng `items` của subject `ielts`, chỉ câu đã
`published`) **không đo được band IELTS** và không bao giờ được quy ra band. Nó cho một thứ hẹp hơn
nhưng dùng được: **so sánh tương đối giữa bốn kỹ năng của cùng một người trong cùng một lượt làm**.

Hai khác biệt với luồng học, và cả hai đều có lý do:

1. **Chọn câu trải trên bốn kỹ năng** thay vì quanh một node — một bài chỉ hỏi Reading thì không
   nói được Reading mạnh hay yếu hơn Writing, mà đó đúng là câu hỏi duy nhất bài này tồn tại để trả lời.
2. **Nộp một lần**, không chấm từng câu. Mục đích là ĐO; hiện đáp án giữa chừng làm hỏng chính phép
   đo đó.

Thiếu hẳn câu của một kỹ năng thì API **từ chối dựng bài** (409) thay vì dựng bài què rồi để tầng
suy luận tưởng kỹ năng thứ tư không tồn tại.

### 23.5 Từ lát cắt tới Learning Plan

Planning Engine đọc lát cắt **từ bản chụp** (Learner Model chạy trước Planning trong WF-04), không
tính lại — hai chỗ cùng suy luận là hai chỗ sẽ lệch. Nó dịch kết luận thành ba thứ người đọc được:

* một **giai đoạn** đứng đầu kế hoạch (`IELTS: đẩy <kỹ năng> trước`), vì band-vào-ngày là ràng buộc
  cứng nhất learner đang có;
* các `flags` thành **ưu tiên**;
* khoảng lệch `underrates` thành một ưu tiên riêng: *xem lại chỗ đang dồn sức*.

Mỗi thứ mang `why` truy được về chính con số trong lát cắt (REQ-INT-14), không phải một câu chung chung.

### 23.6 Một ngoại lệ có chủ đích: endpoint đọc thì DỰNG LẠI

`GET /v1/learners/{id}/ielts-profile` **không** đọc bản chụp mà dựng lại bằng chính
`buildIeltsLayer` trên dữ liệu hiện tại. Bản đầu đọc bản chụp cho "nhất quán với kế hoạch", và test
bắt được hậu quả: learner vừa khai xong thì màn hình vẫn nói theo bản chụp cũ — đúng khoảnh khắc họ
vừa hành động, hệ lại bày bức tranh của trước đó. Không ai đọc điều này thành "engine chưa chạy
xong"; người ta đọc nó thành "khai xong chẳng thấy gì đổi".

Dựng lại không phải suy luận lần hai: vẫn đúng một hàm trên cùng đầu vào. Cái lệch còn lại là lệch
**thời điểm**, và `from_model_version` nói thẳng bản chụp mà kế hoạch đang dựa vào là bản nào.

## 24. Lát cắt AI Teen trong Learner Model (SRC-1257, chỉ đạo 2026-10-06)

Cùng khuôn §23: `content.ai_teen` là một lát cắt trong bản chụp Learner Model, không phải model
riêng; bản chụp lên `learner-v4`. Dựng ở `workers/api/src/modules/aiTeen/layer.ts` từ sổ bằng chứng
(`subject_id='ai_teen'`) và bảng hành trình `ai_teen_journeys`. Chi tiết đường ghi: SDD-043 §11.

| Trục | Nguồn | Ghi chú |
| --- | --- | --- |
| Declared | `self_report`, type `ai_teen_self_level`, node `ccs:{skill}` | level tự đánh giá ở Where am I? |
| Measured (tự chấm) | `ai_teen_task`, node `ccs:{skill}` | Performance Task tự chấm theo rubric; lấy level cao nhất đã đạt |
| Target | đích ở Goal + level task yêu cầu | `AI_TEEN_TASK_SKILLS` |
| Hiểu khái niệm / thực hành | `ai_teen_concept`, `ai_teen_practice`, node `ai-teen:{course}:u{n}` | chỉ đếm, KHÔNG quy ra level skill |

Ba nguồn mới đều `feeds_mastery: false`: node của chúng không phải node đồ thị kỹ năng (cùng lý do
`ielts_micro`, `sat_*`). Engine dựng lại ở mốc chuyển chặng (rời Where am I?, rời Assess, xong unit),
không sau mỗi câu (§21).
