Files
Hankan/fixtures/progress-snapshot.json
MechaCat02 e72b77d6c2 chore: take in the 16 Sep bundle — lib, curriculum v5, prompt, gate audit
The artifact was reworked after real incidents: a week of lost data, a
student taught out of order, and spelling diagnoses the model invented.
This takes the new export in verbatim; the port catches up in the
commits that follow.

Copied byte-identical from the bundle:
  lib/        lexicon.js and sync.js are new; gate.js gains enforcement,
              hangul.js letter-level marking, srs.js recall evidence,
              conjugation.js deconjugate(); blocks.js now takes the last
              block, closes gloss at "=", and parses recall, ::result and
              ::confirmed
  data/       curriculum.json v5 — six 다지기 phase reviews; the 371
              roadmap words are unchanged and no band moves
  prompt/     English-only rule, recall, LETTER-LEVEL CHECK, marking
  audit-gate.mjs, run-checks.sh, fixtures/  — the word gate measured
              against 54 real tutor messages

CI runs run-checks.sh in place of validate.mjs alone, and `npm run check`
gains the audit. Baselines: validate PASS 0/0; audit 7 of 41 and 2 of 13.

types/lib/ declares the new API, and test/lib/ pins it: letterCheck on
the prompt's own 짧다/빫다 case, deconjugation, the roadmap-first order
that keeps 마셔 out of Phase 1, sync's three gates, and recall evidence —
including the two ways lib's evidence is looser than PORT.md, pinned as
they are so the call site that tightens them is visibly needed.

TaskHost gains a plain recall renderer so the tree typechecks against the
wider Task union.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-16 19:49:52 +02:00

276 lines
3.6 KiB
JSON

{
"note": "A realistic mid-course progress state: Phase 1 finished, 1.10 다지기 in progress. The allowed-word set depends on this, so the audit is meaningless without it. deckWordsMet are the deck words the student has actually encountered (the app counts a card as allowed once its SRS state leaves 'new'); allowedWordsExpected is the set the shipped artifact computes from exactly this state — 149 words. If your port's allowed set differs from that, your gate is not the gate that was measured.",
"road": {
"ans": {},
"conf": {
"1.1": 87,
"1.10": 0,
"1.2": 89,
"1.3": 85,
"1.4": 88,
"1.5": 85,
"1.6": 86,
"1.7": 76,
"1.8": 85,
"1.9": 85
},
"cover": {},
"done": {
"1.1": 1,
"1.2": 1,
"1.3": 1,
"1.4": 1,
"1.5": 1,
"1.6": 1,
"1.7": 1,
"1.8": 1,
"1.9": 1
},
"migrated": 1,
"note": "",
"recent": [],
"unit": "1.10",
"v": 5
},
"deckWordsMet": [
"감사합니다",
"네",
"사람",
"친구",
"아버지",
"어머니",
"학생",
"아이",
"이",
"하나",
"여덟",
"학교",
"회사",
"밥",
"물",
"음식",
"가다",
"오다",
"먹다",
"마시다",
"읽다",
"앉다",
"모르다",
"없다",
"좋다",
"크다",
"작다",
"많다",
"바쁘다",
"싫다",
"슬프다",
"많이",
"같이",
"뭐",
"누구",
"어디",
"언제",
"왜",
"책",
"머리",
"귀",
"배",
"나",
"저",
"너",
"우리",
"이",
"그",
"저",
"여기",
"거기",
"저기",
"레벨",
"던전",
"탑",
"마법",
"소환",
"싸우다",
"진짜?",
"잠깐만",
"안 돼",
"가자",
"싫어",
"좋아",
"나무",
"소리",
"바다",
"다리",
"개",
"새",
"세",
"의사",
"위",
"돼지",
"꼬리",
"방",
"꽃",
"얼음",
"습니다",
"값",
"닭",
"넓다",
"짧다",
"설날",
"놓다",
"앉히다",
"먹어",
"읽어"
],
"allowedWordsExpected": [
"나",
"너",
"우리",
"이",
"그",
"저",
"여기",
"거기",
"저기",
"어디",
"누구",
"아이",
"어머니",
"아버지",
"나무",
"머리",
"소리",
"하나",
"바다",
"다리",
"개",
"새",
"배",
"네",
"세",
"의사",
"회사",
"뭐",
"왜",
"귀",
"위",
"돼지",
"가위",
"시계",
"매미",
"제비",
"코",
"차",
"커피",
"포도",
"치마",
"까치",
"아빠",
"오빠",
"토끼",
"꼬리",
"찌개",
"카페",
"피자",
"쿠키",
"바쁘다",
"밥",
"물",
"책",
"집",
"손",
"발",
"눈",
"입",
"옷",
"산",
"강",
"문",
"방",
"곰",
"밤",
"꽃",
"앞",
"낮",
"밖",
"말",
"한국어",
"음악",
"국어",
"단어",
"언어",
"발음",
"얼음",
"직업",
"금요일",
"일요일",
"목요일",
"작은",
"감사합니다",
"입니다",
"학년",
"국물",
"십만",
"작년",
"몇 명",
"습니다",
"한국말",
"꽃말",
"값",
"닭",
"여덟",
"앉다",
"읽다",
"없다",
"많다",
"삶",
"넓다",
"짧다",
"학교",
"좋다",
"같이",
"신라",
"설날",
"못해",
"축하",
"싫어",
"놓다",
"앉히다",
"친구",
"사람",
"시간",
"이름",
"나라",
"하늘",
"마음",
"얼굴",
"목소리",
"이야기",
"학생",
"음식",
"가다",
"오다",
"먹다",
"마시다",
"모르다",
"크다",
"작다",
"싫다",
"슬프다",
"많이",
"언제",
"레벨",
"던전",
"탑",
"마법",
"소환",
"싸우다",
"진짜?",
"잠깐만",
"안 돼",
"가자",
"좋아",
"먹어",
"읽어"
]
}