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>
76 lines
2.4 KiB
YAML
76 lines
2.4 KiB
YAML
name: CI
|
|
|
|
on:
|
|
push:
|
|
branches: [main]
|
|
pull_request:
|
|
workflow_dispatch:
|
|
|
|
jobs:
|
|
check:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
# The bundle's own checks come first, before anything else can run.
|
|
# Both read only data/, lib/ and fixtures/ and exit non-zero on failure:
|
|
# validate.mjs — curriculum sequencing. Baseline: PASS, 0 blocking, 0 advisory.
|
|
# audit-gate.mjs — the word gate against 54 real tutor messages.
|
|
# Baseline: 7 of 41 and 2 of 13 flagged. Too many
|
|
# means it rejects real teaching; too few means
|
|
# violations reach the student.
|
|
- name: Curriculum validation and gate audit
|
|
run: sh run-checks.sh
|
|
|
|
- uses: actions/setup-node@v4
|
|
with:
|
|
node-version: 22
|
|
cache: npm
|
|
|
|
- run: npm ci
|
|
|
|
- name: Typecheck
|
|
run: npm run typecheck
|
|
|
|
# The sync round-trip needs a real Postgres and a running server, so a
|
|
# fake would not exercise the change_seq trigger, the last-write-wins
|
|
# upsert, or cursor paging — which is where sync actually goes wrong.
|
|
- name: Start Postgres
|
|
run: |
|
|
docker run -d --name hankan-pg \
|
|
-e POSTGRES_PASSWORD=test -e POSTGRES_DB=hankan \
|
|
-p 55432:5432 postgres:16-alpine
|
|
for i in $(seq 1 30); do
|
|
docker exec hankan-pg pg_isready -U postgres -d hankan && break
|
|
sleep 1
|
|
done
|
|
|
|
- name: Start the sync server
|
|
env:
|
|
DATABASE_URL: postgres://postgres:test@localhost:55432/hankan
|
|
HANKAN_TOKEN: test-token
|
|
HANKAN_TEST_MODE: "1"
|
|
# Keyless, so the tutor endpoint is exercised over real HTTP —
|
|
# SSE framing, CORS and auth — without an Anthropic key in CI.
|
|
HANKAN_TUTOR_BACKEND: echo
|
|
PORT: "8788"
|
|
run: |
|
|
node --experimental-strip-types server/src/main.ts &
|
|
for i in $(seq 1 30); do
|
|
curl -sf http://localhost:8788/health && break
|
|
sleep 1
|
|
done
|
|
|
|
- name: Tests
|
|
env:
|
|
HANKAN_TEST_SERVER: http://localhost:8788
|
|
run: npm test
|
|
|
|
# Every word in every unit's words[] must resolve in lemma or surface.
|
|
# Runs against the committed band files in app/public/dict/.
|
|
- name: Roadmap word coverage
|
|
run: npm run dict:assert
|
|
|
|
- name: Build
|
|
run: npm run build
|