Skip to content

Parent Model ​

Model trả lời câu hỏi mà Learner Model cố tình không trả lời: "bố mẹ đang nghĩ gì về con, và điều đó lệch bao nhiêu so với thực tế?"

Thiết kế: SDD-002 §4/§13 · Code: workers/api/src/modules/parent/routes.ts · Test quyền: parent/authz.test.ts · Workflow: WF-12


1. Parent Model là declared model, không phải computed model ​

Đây là điều dễ hiểu sai nhất, nên nói ngay:

Learner ModelParent Model
LoạiComputed — engine sinhDeclared — người khai
Có trong MODEL_KINDS?✅ learner❌ không
Có version + hash?✅❌
Có engine chạy định kỳ?✅❌
Lưu ởlearner_model_versionsparent_beliefs + interactions

Không có parent trong MODEL_KINDS (shared/runlog.ts) và không có Parent Engine sinh model. Cái mà mã nguồn gọi là "Parent Engine" thực chất là hai đường ghi dữ liệu khai báo cộng với một hàm suy luận khuyến nghị chạy tại chỗ lúc đọc (§5) — không lưu, không version.

Đây là lựa chọn có chủ ý: niềm tin của phụ huynh không được phép trở thành một model chạy ngầm suy diễn về đứa trẻ. Nó là dữ liệu để đối chiếu, không phải để phán quyết.


2. Hai dòng dữ liệu ​

2.1 Parent Belief — niềm tin định kỳ theo môn ​

Bảng parent_beliefs (migration 0018, SRC-051).

CộtKiểuÝ nghĩa
learner_id + user_id + subject_idTEXTAi nghĩ về ai, ở môn nào. Có user_id nên bố và mẹ khai riêng, không đè nhau
worry_levelINT 1–51 rất yên tâm … 5 vô cùng lo lắng
perceived_stateTEXThong · lung_lay · on_dinh · chac — bố mẹ cảm thấy con đang ở đâu
predicted_scoreREALĐiểm bố mẹ hình dung con đạt khi thi thật
score_scaleREALThang điểm (mặc định 10; cho phép tới 1600 để dùng cho SAT)
will_passINT1 tin đủ điểm đỗ · 0 chưa tin · NULL chưa rõ
noteTEXTLời tự do
recorded_atTEXTMốc thời gian

Mỗi lần khai là một dòng mới — không update đè. Đây không phải chi tiết kỹ thuật mà là toàn bộ giá trị của bảng: chỉ khi giữ lịch sử thì mới trả lời được "tháng trước mẹ lo mức 5, giờ mức 2 — điều gì đã đổi?". Update đè sẽ xoá mất chính thứ đáng giá nhất.

Belief KHÔNG vào Evidence Registry

Migration 0018 ghi rõ ngay dòng đầu: không ghi vào learner_evidence. Niềm tin của phụ huynh không phải bằng chứng năng lực của đứa trẻ.

Mẹ tin con yếu Toán không làm mastery Toán giảm một chút nào. Nếu để nó ảnh hưởng, hệ thống sẽ biến lo lắng của người lớn thành "sự thật" về đứa trẻ — đúng cái vòng luẩn quẩn mà Nemo12 tồn tại để phá vỡ.

2.2 Parent Observation — quan sát tự do ​

Ghi vào bảng interactions (target_type='learner', author_role='guardian', visibility='learner_parent'), phân loại theo category: motivation · focus · time · emotion · behavior · other.

Khác với belief, observation có vào Evidence Registry:

sql
INSERT INTO learner_evidence (..., subject_id, node_id, source, type, observed_performance, reliability, ...)
VALUES (..., '', '', 'parent_observation', <category>, 0.5, 0.6, ...)

Ba con số cần đọc kỹ:

TrườngGiá trịVì sao
node_idrỗngKhông gắn với kỹ năng nào → updateMastery() chạy theo node nên không bao giờ chạm tới evidence này. Nó là tín hiệu ngữ cảnh, không phải phép đo năng lực
observed_performance0.5 cố địnhTrung tính. "Con hôm nay mất tập trung" không phải điểm số
reliability0.6Quan sát của người thân: đáng tin hơn đoán bừa (0.05), kém hơn bài làm thật (1.0)

Nói cách khác: quan sát được ghi nhận và giữ lại, nhưng không được phép dịch chuyển mastery. Bố mẹ được lắng nghe mà không vô tình chấm điểm con mình.

Cặp bảng này là hai thứ khác nhau về bản chất: belief là phán đoán, observation là quan sát. Trộn chúng vào một chỗ là cách nhanh nhất để mất khả năng phân biệt "mẹ lo" với "hôm qua con ốm".


3. Cơ chế CẬP NHẬT ​

3.1 Ai được ghi — chỉ phụ huynh, và learner bị chặn có chủ đích ​

Mọi route parent đi qua guardGuardian():

ts
const access = await resolveLearnerAccess(c, learnerId, { action });
if (access instanceof Response) return access;
if (access.via === "self") return errorResponse(c, "AUTHORIZATION_ERROR", "Chức năng dành cho phụ huynh");

Đây là guard chặt hơn learnerAccess() chuẩn: nó loại via === "self". Chính đứa trẻ không được ghi belief hay observation về mình — vì đây là dòng dữ liệu ghi lại góc nhìn của người lớn, và để nó lẫn tiếng nói của trẻ thì phép đối chiếu ở §4 mất hết ý nghĩa.

Nemo có tiếng nói riêng ở chỗ khác: cột của con trong Student Portrait và reaction. Không phải ở đây.

Mentor/staff/admin đọc được (qua resolveLearnerAccess, có ghi audit) nhưng cũng không ghi được — via của họ không phải self nên qua được guard, nhưng đó là chủ ý: mentor cần đọc để hiểu bối cảnh gia đình. Xem ma trận quyền.

3.2 Đường ghi ​

ViệcEndpointGhi vàoEvent
Ghi quan sátPOST /v1/learners/{id}/observationsinteractions + learner_evidence (một DB.batch)parent.observation.recorded
Ghi niềm tinPOST /v1/learners/{id}/beliefsparent_beliefs (INSERT mới)parent.belief.recorded

Observation dùng DB.batch cho cả hai statement: hoặc cả quan sát lẫn evidence cùng vào, hoặc không gì cả. INSERT OR IGNORE với event_id = parent-obs:{id} chống ghi trùng khi client retry.

Không có bước nào chạy engine. Ghi belief/observation không kích hoạt WF-04 — vì không có gì trong Learner Model thay đổi. So sánh với việc nộp bài (chạy WF-04 ngay): khác biệt này chính là ranh giới "dữ liệu người lớn khai" và "bằng chứng của trẻ".

3.3 Đường đọc ​

EndpointTrả về
GET /v1/learners/{id}/observations50 quan sát gần nhất, mới trước
GET /v1/learners/{id}/beliefs?subject_id={ history, latest } — latest là bản ghi mới nhất của từng môn, gộp sẵn từ history

latest được tính bằng cách duyệt history (đã ORDER BY recorded_at DESC) và giữ dòng đầu tiên gặp cho mỗi môn — không cần query thứ hai.


4. Cách DÙNG (1): đối chiếu niềm tin với thực tế ​

Đây là lý do Parent Model tồn tại.

Tại marlins #/child/{id}/beliefs, cạnh mỗi lần khai của phụ huynh là ước tính của hệ thống cho cùng môn đó, để bố mẹ tự so. Ghi chú trong code nói rõ tinh thần:

"Ước tính của hệ thống để bố mẹ tự so với cảm nhận của mình (không phán xét ai đúng)."

Bốn tình huống, và hành động đúng cho từng cái:

Bố mẹ tinHệ thống đoÝ nghĩaViệc cần làm
Lo (4–5)Đang ổnLo quá mứcCho bố mẹ thấy bằng chứng cụ thể — thường là gốc của việc đăng ký thêm lớp không cần thiết
Yên tâm (1–2)Có gap nghiêm trọngĐiểm mùChỉ đúng gap, không nói "con yếu"
LoCó gapĐồng thuậnCùng làm việc trên gap đó
Yên tâmĐang ổnĐồng thuậnKhông cần can thiệp gì

Hệ thống không tuyên bố ai đúng. Nó đặt hai con số cạnh nhau và để gia đình nói chuyện. Đó là toàn bộ thiết kế.


5. Cách DÙNG (2): Parent Recommendation — WF-12 ​

GET /v1/learners/{id}/parent-recommendation?subject_id=

Không phải model được lưu — là hàm suy luận chạy tại chỗ lúc đọc, dựa trên cockpit của learner. Không có version vì output luôn suy được lại từ trạng thái hiện tại.

Cây quyết định (thứ tự ưu tiên, dừng ở nhánh đầu tiên khớp) ​

1. assessed_nodes == 0      → "Con chưa làm bài chẩn đoán"
2. mode == exam_prep        → "Còn N ngày tới kỳ thi — luyện đề, giữ nhịp nghỉ"
3. có gap 'critical'        → "Tập trung vào <tên node> — gốc đang chặn nhiều phần sau"
4. có goal, chưa on_track   → "Đang tiến bộ nhưng chưa đạt — duy trì đều đặn"
5. còn lại                  → "Con đang đúng hướng — không cần tăng tải"

Thứ tự này là một khẳng định về giáo dục: deadline gần thắng gap sâu. Còn 5 ngày thi mà đi vá lỗ hổng nền tảng là hại con — lúc đó việc đúng là luyện đề và ngủ đủ.

Output ​

jsonc
{
  "subject_id": "math",
  "headline": "Tuần này, giúp con tập trung vào \"Hằng đẳng thức\" — đây là gốc đang chặn nhiều phần phía sau. **Chưa cần đăng ký thêm lớp.**",
  "support_actions": [
    "Dành 20 phút hỏi con về \"Hằng đẳng thức\", để con giải thích lại cho bạn nghe.",
    "Khen nỗ lực khi con chịu làm phần khó, thay vì chỉ khen điểm."
  ],
  "dont_do": "Tránh phản xạ 'thấy điểm thấp → cho học thêm'. Nguyên nhân thường là một gap nền tảng cụ thể, không phải yếu toàn bộ môn.",
  "readiness": 0.68, "on_track": true,
  "critical_gaps": ["Hằng đẳng thức", "Phân tích đa thức"],
  "mode": "deep_learning"
}

dont_do là trường bắt buộc, không phải trang trí ​

REQ-PAR-04 — chống intervention error. Mọi nhánh của cây quyết định đều có dont_do, kể cả nhánh "con đang ổn".

Sai lầm phổ biến nhất của phụ huynh Việt Nam không phải là làm quá ít, mà là phản xạ "thấy điểm thấp → cho học thêm". Một hệ thống chỉ biết nói "nên làm gì" sẽ khuếch đại đúng phản xạ đó. Vì vậy "tuần này chưa cần làm gì thêm" là một output hợp lệ và đầy đủ — không phải dấu hiệu hệ thống bí ý tưởng.

Ba nhánh nói thẳng "chưa cần đăng ký thêm lớp", và headline nhánh 3 in đậm câu đó ngay giữa lời khuyên tập trung.

Lời khuyên nói bằng tên bài, không bằng con số ​

titles map node_id → title_vi được nạp trước để headline nói "Hằng đẳng thức" chứ không phải "node math-8-alg-03" hay "mastery 0.32". Phụ huynh cần một câu có thể mang tới bàn ăn tối.


6. Ai thấy được gì ​

Dữ liệuLearnerPhụ huynhMentorAdmin
Belief của bố mẹ❌ không đọc được✅ ghi + đọc📝 đọc (có audit)📝
Observation❌✅ ghi + đọc📝 đọc📝
Parent recommendation❌✅📝📝

Learner không đọc được belief của bố mẹ. Có chủ đích: "mẹ lo mức 5 về Toán của con" là suy nghĩ riêng của người lớn, chưa được diễn đạt thành lời để nói với trẻ. Đưa thẳng con số lo lắng cho đứa trẻ là gây tổn thương mà không tạo ra hành động nào tốt hơn.

Thứ đứa trẻ được thấy và phản hồi là Student Portrait — nơi kỳ vọng đã được bố mẹ viết ra thành câu tử tế, có chỗ cho con viết lại bằng lời của mình.


7. Bất biến — vi phạm là bug ​

  1. parent_beliefs không bao giờ ghi vào learner_evidence.
  2. Parent observation vào evidence với node_id rỗng — không bao giờ chạm updateMastery().
  3. Mỗi lần khai belief là INSERT mới, không UPDATE.
  4. Chính learner không ghi được belief/observation (via === "self" bị chặn).
  5. Mọi nhánh parent recommendation phải có dont_do.
  6. Learner không đọc được belief của bố mẹ qua bất kỳ endpoint nào.
  7. Ghi belief/observation không kích hoạt WF-04.

8. Khoảng trống đã biết ​

ViệcTrạng thái
REQ-PAR-08 — adaptive questions cho phụ huynh dựa trên evidence gap⏳ cần Parent Model phase 2
REQ-PAR-11 — weekly plan có đánh dấu hoàn thành🔵 khung dùng chung WF-12, còn thiếu phần tick việc
REQ-PAR-12 — digest định kỳ qua email/notification⏳ chưa có kênh gửi; xem schedules
Tự động phát hiện lệch belief↔hệ thống và nêu thành tín hiệu⏳ hiện để bố mẹ tự so bằng mắt

Trace ​

  • REQ-PAR-01 (giải thích bằng evidence) · REQ-PAR-02/04 (recommendation + chống intervention error) · REQ-PAR-05 (Parent Model + niềm tin định kỳ) · REQ-PAR-10 (observation → evidence).
  • US-09, US-10, US-12, US-71 · WF-12.
  • Nguồn: SRC-006 (JTBD phụ huynh), SRC-051 (niềm tin định kỳ), SRC-105.
  • Thiết kế: SDD-002 §4/§13.
  • Kiểm chứng: QG-005; quyền: parent/authz.test.ts, QG-008.
  • Liên quan: Student Portrait · Models · Permissions.