diff --git a/README.ko.md b/README.ko.md
index 5753aa4..0afed96 100644
--- a/README.ko.md
+++ b/README.ko.md
@@ -1,54 +1,64 @@
ΠΑΙΔΕΙΑ · Paideia for opencode
- 당신의 수업. 당신의 패턴. 당신의 오답. 당신의 치트시트.
- 당신의 자료를 영속적이고 편집 가능한 코스별 학습 그래프로 바꾸는 시험대비 하네스 — 모든 산출물이 일반 강의계획서가 아니라 당신에 의해 형성됩니다. opencode 에디션: 에디터 플러그인이 아니라 opencode를 구동하는 독립 하네스.
+ 당신의 과목, 당신의 패턴, 당신의 오답, 당신의 치트시트.
+ 당신의 자료에서 출발해 한 과목에 영속적으로 머무는 학습 그래프를 만드는 opencode 기반 명령줄 프로그램입니다 — 모든 산출물이 일반 실러버스가 아니라 당신의 손끝에서 빚어집니다.
-
-
-
-
- Exam Radar(OPTIMETA의 Alt 플러그인)로 강의를 포착하고 Paideia로 공부하세요. paideia alt로 로드맵을 바로 흘려보낼 수 있습니다.
-
-
-
-
-
-
+
+
+
+
+
+
+
+ 

+ 
+
원본 PAIDEIA의 소개 기사와 인터랙티브 데모입니다.
+
+
English README
·
- PAIDEIA — 원본 Claude Code 에디션
- ·
- PAIDEIA-codex — OpenAI Codex CLI 에디션
+ taewoopark.com — 저자 사이트
-> **Claude Code나 Codex 대신 opencode를 쓰시나요?** 같은 도구, 같은 디스크 구조, 같은 라이선스 — opencode를 구동하는 **하네스**로 재구축했습니다. 원본 PAIDEIA는 Claude Code *플러그인*(에디터가 로드하는 커맨드+스킬)이지만, 이 에디션은 opencode 위에 앉아 그것을 구동하는 독립 프로그램입니다(스테이지마다 `opencode run` 한 번). 이미 결제 중인 에이전트 런너를 고르세요 — 만들어지는 학습 그래프는 세 에디션 모두 동일하고 이식 가능합니다.
+PAIDEIA 패밀리 — 하나의 학습 엔진, 모든 에이전트 런타임
+
+| 플랫폼 | 저장소 | 설명 |
+|:--:|:--|:--|
+|
| **[PAIDEIA](https://github.com/OPTIMETA/PAIDEIA)** | 원본 — **Claude Code** 플러그인. |
+|
| **[PAIDEIA-codex](https://github.com/OPTIMETA/PAIDEIA-codex)** | **OpenAI Codex** 스킬 + 번들 MCP 서버. |
+|
| **[PAIDEIA-opencode](https://github.com/OPTIMETA/PAIDEIA-opencode)** | **opencode**를 구동하는 명령줄 프로그램. |
+|
| **[PAIDEIA-Hermes](https://github.com/OPTIMETA/PAIDEIA-Hermes)** | **Hermes Agent** 플러그인: CLI 명령 + 게이트웨이 라우팅. |
+|
| **[PAIDEIA-mcp](https://github.com/OPTIMETA/PAIDEIA-mcp)** | 독립형 로컬 **MCP** 서버 — Alt 로컬 모델에서 PAIDEIA 구동. |
+|
| **[PAIDEIA-Alt](https://github.com/OPTIMETA/PAIDEIA-Alt)** | **Exam Radar** — Alt 강의 캡처 플러그인 ([altalt.org](https://altalt.org)). |
-> **보안 안내.** PAIDEIA for opencode는 일반 npm/Node CLI(`paideia`)로 설치되며, `.zip` 다운로드·`.exe` 실행·별도 인스톨러를 절대 요구하지 않습니다. 이 README에서 명시적으로 링크되지 않은, PAIDEIA 이름을 쓰는 다른 저장소는 본 프로젝트와 무관합니다.
+
+ 일반적인 학습 도구는 평균적인 실러버스를 가르칩니다. Paideia는 당신의 실러버스를 가르칩니다 —
+ 당신의 교수님 강의노트, 당신의 숙제 경향, 당신의 필기, 당신의 오답에서 출발해서요. 모든 산출물은 당신이 직접 편집할 수 있는 마크다운 파일입니다.
+
- 일반 학습 도구는 평균 강의계획서를 가르칩니다. Paideia는 당신의 강의계획서를 가르칩니다 —
- 교수님의 노트, 당신의 과제 강조점, 당신의 손글씨, 당신의 오답으로부터. 모든 산출물은 편집 가능한 마크다운 파일입니다.
+
---
-## Paideia의 뜻
+## Paideia라는 이름에 대하여
고대 그리스에서 **Παιδεία**는 수동적인 학생에게 사실을 입력하는 일이 결코 아니었습니다. 그것은 원전과의 구조적 만남, 스승 아래의 안내된 연습, 피드백을 더 깊은 수정으로 접어 넣는 성찰적 대화를 통한 — 한 인간의 평생에 걸친 형성이었습니다.
@@ -60,92 +70,88 @@
└────────────────── 피드백 루프 ─────────────────────────┘
```
-모든 단계는 당신의 코스 폴더에 영원히 남는 마크다운 산출물을 만듭니다. 휘발되는 것도, API 뒤에 숨는 것도, 다음 펀딩 한파에 멈추는 것도 없습니다.
+학습 단계의 산출물은 코스 폴더의 마크다운 파일로 남습니다. 에이전트와 별개로 계속 읽고, 편집하고, 버전 관리할 수 있습니다. 새로운 산출물을 생성할 때는 해당 단계의 실행 환경·도구·모델이 필요합니다.
---
-## 플러그인이 아니라 하네스
+## 일반적인 학습 도구가 하지 못하는 것
-원본 PAIDEIA는 *플러그인*입니다 — 에디터(Claude Code)가 자기 에이전트 루프 안에서 로드·실행하는 커맨드·스킬이죠. 이 에디션은 **하네스**입니다. opencode *위에* 앉아 그것을 구동하는 독립 프로그램입니다.
+Paideia는 *당신*의 과목, *당신* 교수님의 과제, *당신*의 실수에서 출발합니다. 강의노트·교재 챕터·숙제·풀이·스캔 답안을 코스 폴더에 넣으면 그것이 학습의 기준이 됩니다.
-```
-┌──────────────────────────────────────────────────────────────┐
-│ paideia (하네스 — 시험대비 로직 전부를 소유) │
-│ │
-│ 커맨드 ─▶ 결정적 사전작업 ─▶ 스테이지 SPEC 합성 │
-│ 파싱 (PDF 렌더·OCR·파일 탐색· (시스템 + │
-│ git·워크스페이스 관리) 코스 컨텍스트 + │
-│ │ 커맨드 지시문) │
-│ ▼ ▼ │
-│ python / poppler opencode run --dir … │
-│ / ollama / tesseract -f │
-└──────────────────────────────────────────────┬───────────────┘
- ▼
- opencode (실행 엔진)
- 모델 · 도구(Read/Write/Bash/Task) · 인증
-```
+일반 커리큘럼이나 직접 만든 플래시카드도 함께 사용할 수 있습니다. Paideia가 더하는 것은 풀이에서 반복 패턴을 추출하고, 숙제 밀도로 연습 우선순위를 정하고, 오답 기록을 다음 드릴에 반영하는 흐름입니다. 아래 표는 이 흐름의 차이를 설명하며, 개별 학습 서비스의 기능이나 요금제를 단정하지 않습니다.
-- **하네스가 학습 로직을 소유합니다.** 모든 커맨드·프롬프트·규칙이 이 저장소에 있습니다. opencode에 PAIDEIA 플러그인/에이전트/스킬을 설치할 필요가 없습니다.
-- **opencode는 기반(substrate)입니다.** 모델·파일/셸/서브에이전트 도구·인증을 제공합니다. 각 스테이지는 한 번의 `opencode run`입니다.
-- **결정적 작업은 하네스에 남습니다** (PDF 래스터화, 로컬 OCR, 디렉토리 골격, 멱등성, git, PDF 아카이브, 단계 감지) — 토큰 비용도 추측도 없습니다.
-- **모델은 모델다운 일만 합니다** (비전 전사, 패턴 추출, 문제 생성, 전략 채점) — 완전히 합성된 명세로.
-
----
-
-## 일반 학습 도구가 못 하는 것
-
-대부분의 학습 도구는 *당신의* 코스·교수님·실수에 맞출 수 없습니다. 그들이 파는 상품이 일반 커리큘럼이기 때문입니다.
-
-- **Coursera, edX, Khan Academy** — 고정 커리큘럼; 당신의 교수가 무엇을 강조하는지 모릅니다.
-- **Quizlet, Anki** — 모든 카드를 직접 큐레이션; 당신의 솔루션에서 패턴을 유도하지 않습니다.
-- **ChatGPT Study Mode, Gemini, NotebookLM** — 코스별 영속 상태가 없습니다. 매 세션이 차갑게 시작하고, 지난주 실수가 이번 주 드릴을 형성하지 않습니다.
-
-이 중 어느 것도 눈앞의 구체적 자료를 중심으로 이해를 *형성*하지 않습니다. Paideia는 정반대입니다 — 모든 산출물이 *당신의* 폴더(강의 노트·교재 챕터·과제·솔루션·손글씨 시도)에서 유도되어, 편집 가능한 평문 마크다운으로 영구히 쌓입니다.
-
-| 축 | Paideia | 일반 edu-SaaS / LLM 채팅 |
+| 축 | Paideia | 일반 강좌 또는 구조화하지 않은 채팅 |
|-----|---------|------------------------------|
-| 풀이 패턴 (`P1..Pk`) | *당신 코스의* 솔루션에서 추출, 당신 파일 인용 | 일반 교재 목록 또는 없음 |
-| 드릴 우선순위 | *교수님의* 과제 강조로 가중 (HW 밀도 = 시험 등급) | 고정 커리큘럼 또는 직접 추측 |
-| 치트시트 | *당신의* `errors/log.md`에서 — 실제로 틀린 것 | 강의계획서 보일러플레이트 |
-| 세션 간 코스 상태 | 영속 마크다운+YAML, 작업하며 성장 | 대화 리셋; 이력은 유료 |
-| 동의 안 되는 산출물 편집 | `.md`를 아무 에디터로 열어 저장 | 읽기 전용 UI |
-| 산출물 위치 | 당신의 디스크, 텍스트로 | 원격 DB, 유료로만 내보내기 |
+| 풀이 패턴 (`P1..Pk`) | 내 과목의 풀이에서 추출하고 출처를 인용 | 과목 자료와 별도 지시가 필요 |
+| 드릴 우선순위 | 교수님의 숙제 비중으로 가중 | 별도로 정하고 관리해야 함 |
+| 치트시트 | 오답으로 주의점을 고르고 코스 인덱스에서 참조 내용을 가져옴 | 별도로 구성하고 갱신해야 함 |
+| 세션을 넘는 과목 상태 | 코스 폴더의 마크다운 + 메타데이터 | 서비스와 맥락 제공 방식에 따라 다름 |
+| 동의하지 않는 산출물 수정 | 에디터에서 `.md`를 열어 저장 | 도구의 편집·내보내기 지원에 따라 다름 |
+| 다음 학기로 준비 자료 옮기기 | 코스 폴더를 복사하고 바뀐 자료를 수정 | 관련 자료와 이력을 옮겨야 함 |
+| 이해의 변화 이력 | 파일을 커밋하면 `git log` / `git diff`로 확인 | 도구의 버전 관리 지원에 따라 다름 |
+| 산출물의 위치 | 내 디스크의 텍스트 파일 | 서비스에 따라 다름 |
-하네스는 무거운 작업에 opencode(유료 모델과 통신)를 쓰지만, 만들어지는 모든 것은 디스크에 평문 마크다운으로 남습니다. 런너를 바꾸거나 구독을 멈춰도 course-index·patterns·error log·weakmap·치트시트는 전부 당신 것입니다. 발판은 하네스, 학습 그래프는 당신 것입니다.
+모델 작업은 실행 환경이 담당하고, 학습 그래프는 언제든 열고 읽고 수정하고 비교할 수 있는 파일로 남습니다. 제공자를 바꾸거나 구독을 중단해도 이미 만들어진 파일은 사라지지 않습니다.
-기본적으로 OCR은 opencode 에이전트의 네이티브 비전을 거칩니다. 손글씨 PDF가 기기를 절대 떠나지 않길 원하면 `ollama pull qwen3-vl:8b`(일회성 ~6GB)로 이후 모든 OCR을 로컬 Qwen3-VL 추론으로 전환할 수 있습니다.
+기본 답안 OCR은 `vision`이며 실행 환경의 비전 경로로 페이지 이미지를 읽습니다. 로컬 답안 OCR을 쓰려면 Ollama와 `qwen3-vl:8b`를 설치한 뒤 `.course-meta`에 `OCR_ENGINE: ollama`로 지정하거나 grade에 `--ocr=ollama` 옵션을 붙이세요. 모델을 다운로드하는 것만으로 엔진이 바뀌지는 않습니다. `tesseract`도 로컬 선택지입니다. 로컬 OCR은 전사 단계를 기기 안에서 처리하며, 이후 분석·채점은 설정된 모델을 사용하므로 전사된 텍스트가 외부 모델에 전달될 수 있습니다.
---
-## 핵심 원칙: 과제 밀도 = 시험 출제 확률
+## 핵심 원리: 숙제 밀도가 곧 출제 확률입니다
-"똑똑하게 공부하라"는 조언 대부분은 사각지대를 사냥하라고 합니다. 그건 **거꾸로**입니다. 교수는 과제를 내줌으로써 시험 점수가 어디 있는지 *이미 알려줬습니다.* 과제가 많은 섹션이 🔥🔥 시험 핵심입니다. 과제가 0인 섹션은 "숨은 함정"이 아니라 ⚪ 저위험입니다. 교수의 누락은 그 주제가 시험에서 빠진다는 가장 강력한 신호입니다.
+숙제는 Paideia가 시험 준비 시간을 배분하는 일차 신호입니다. 과제가 많이 배정된 절은 더 연습하고, 숙제가 없는 절은 기본적으로 참조 자료로 둡니다. **이 티어는 학습 우선순위이며, 통계적으로 측정한 출제 확률이나 실제 시험 범위에 대한 보장은 아닙니다.**
-Paideia의 랭킹은 이를 명시하고, 모든 드릴 커맨드가 기본으로 이를 따릅니다:
+| 티어 | 해당 절의 숙제 수 | 처리 | 모의고사 배점 목표 |
+|------|-------------------|------|--------------------|
+| 🔥🔥 출제 핵심 | 3개 이상 | 가장 집중해서 연습 | ≥70% |
+| 🔥 출제 유력 | 2개 | 다음 순서로 연습 | ~25% |
+| 🟡 출제 가능 | 1개 | 가볍게 복습 | ≤5% |
+| ⚪ 저위험 | 0개 | 기본적으로 참조용 | 기본 0 |
-| 등급 | 섹션 과제 수 | 처리 | 모의고사 배점 비중 |
-|------|---------------------|-----------|---------------------------|
-| 🔥🔥 시험 핵심 | 3+ | 가장 강하게 드릴 | ≥70% |
-| 🔥 시험 유력 | 2 | 다음 드릴 | ~25% |
-| 🟡 시험 가능 | 1 | 가볍게 복습 | ≤5% |
-| ⚪ 저위험 | 0 | 참고용 | 0 |
-
-`paideia quiz all`, `paideia mock`, `paideia hwmap hot`은 모두 이 등급으로 출력을 가중합니다. ⚪ 섹션 드릴을 고집하면 하네스는 한 번 따르되 시험 확률이 낮다고 경고합니다 — 당신의 유한한 시간은 상상 속 함정보다 가치 있습니다.
+`paideia quiz all`, `paideia mock 90`, `paideia hwmap hot`은 이 순위를 사용합니다. 배점은 문제를 생성하는 에이전트에 주는 지침이므로, 정확한 비율이 필요하면 생성된 모의고사를 확인하세요. 사용자의 요청과 Exam Radar로 가져온 강의 강조 신호도 복습 범위를 결정하는 데 참고할 수 있습니다.
---
-## Formation Cycle, 단계별
+## 형성 사이클, 단계별 해설
+
+Mac에서 실제 실행한 CLI를 로컬 터미널 뷰어로 촬영했습니다. 코스 자료는 검증용으로 만든 작은 예제입니다. · 촬영 조건
+
+
+
+
+
paideia status — course · D-N · phase
+ |
+
+
+
paideia --help — command reference
+ |
+
+
+
+
+
paideia ingest — Markdown ingest
+ |
+
+
+
paideia doctor — dependency check
+ |
+
+
+
+**셸에서 `paideia <명령>`을 실행합니다.** 이 에디션은 독립적인 Node.js 프로그램입니다. 파일과 단계별 작업 명세를 준비한 다음, 모델 작업을 위해 `opencode run`을 시작합니다. `status`를 포함한 명령 17개를 제공하며 `init`은 `init-course`의 별칭입니다.
+
+초기 설정·진단·상태 확인·마크다운 복사는 로컬에서 수행합니다. 모델을 사용하는 단계는 각각 별도 CLI 호출입니다. 두 단계로 진행하는 blind/twin 연습에서는 `paideia blind --strategy "…"` 또는 `paideia twin --strategy "…"`로 접근법을 제출합니다. 답변을 기다리는 PAIDEIA 채팅 세션은 유지하지 않습니다. 생성된 수식은 Obsidian에서 읽을 수 있습니다.
| 단계 | 하는 일 | 커맨드 | 산출물 |
|-------|-------------|----------|----------|
| **Encounter** | 교수의 신호를 읽음 | `paideia ingest` | `converted/**/*.md` — 모든 강의·교재·과제·솔루션을 깔끔한 마크다운으로 |
| **Structure** | 코스의 문법을 추출 | `paideia analyze` | `course-index/{summary,patterns,coverage}.md` — 토픽 트리, 반복 풀이 패턴(P1..Pk), HW밀도 시험등급 |
-| **Practice** | 교수가 실제 내는 것에 가중한 능동 회상 | `paideia quiz` `twin` `blind` `chain` `mock` | `quizzes/` `twins/` `chain/` `mock/` — 종이에 푸는 문제 |
+| **Practice** | 숙제 비중에 가중한 능동 회상 | `paideia quiz` `twin` `blind` `chain` `mock` | `quizzes/` `twins/` `chain/` `mock/` — 종이에 푸는 문제 |
| **Reflection** | 손글씨 작업이 점수가 됨 | `paideia grade` | `answers/converted/.md` + `errors/log.md` — 에이전트 비전(기본)/Ollama/Tesseract OCR 후 전략 채점 |
| **Diagnosis** | 오답을 우선순위 약점 리포트로 압축 | `paideia weakmap` | `weakmap/weakmap_.md` — 추가 전용 이력 |
| **Distillation** | 한 페이지, 오답 기반, 인쇄용 | `paideia cheatsheet` `derive` `pattern` | `cheatsheet/final.md`, `derivations/.md` |
-보조: `paideia hwmap`은 HW밀도 시험확률을, `paideia status`는 사이클상 현재 위치를 보여주고, `paideia init-course`는 새 코스 폴더를 부트스트랩합니다.
+보조: `paideia hwmap`은 HW밀도 기반 학습 우선순위를, `paideia status`는 사이클상 현재 위치를 보여주고, `paideia init-course`는 새 코스 폴더를 부트스트랩합니다.
---
@@ -157,7 +163,7 @@ Paideia의 랭킹은 이를 명시하고, 모든 드릴 커맨드가 기본으
- **Node ≥ 18.17** (하네스 실행 — 순수 ESM, 런타임 의존성 0)
- **[opencode](https://opencode.ai)** (실행 엔진) — `npm i -g opencode-ai`, 그리고 한 번 `opencode auth login`
-- **Python 3.9+** + `pdf2image` + `pillow` (PDF 렌더·로컬 OCR); `cheatsheet --pdf`용 `reportlab` 추가
+- **Python 3.9+** + 렌더링용 `pdf2image`·`pillow`. PAIDEIA가 사용하는 Python 환경에서 `python3 -m pip install pdf2image pillow` 명령을 실행하세요. 로컬 Tesseract·폴백에는 `pytesseract`, PDF 내보내기 폴백에는 `reportlab`을 추가합니다. `PAIDEIA_PYTHON`으로 가상환경 인터프리터를 선택할 수 있습니다.
- Unix 계열 셸(`bash`/`zsh`). Windows는 [WSL2](https://learn.microsoft.com/windows/wsl/install).
- **macOS**: `brew install poppler tesseract tesseract-lang`
- **Linux (Debian/Ubuntu)**: `apt-get install poppler-utils tesseract-ocr tesseract-ocr-kor`
@@ -166,7 +172,7 @@ Paideia의 랭킹은 이를 명시하고, 모든 드릴 커맨드가 기본으
- `ollama` + `qwen3-vl:8b` 모델 (~6GB). `brew install ollama && ollama pull qwen3-vl:8b`.
-Ollama를 설치하지 않으면 기본 OCR 엔진은 opencode 에이전트의 비전입니다 — 추가 설치 없음.
+기본 답안 OCR은 `vision`이며 위 렌더링 의존성과 정상 작동하는 opencode 비전 모델이 필요합니다. `ollama`를 선택하려면 로컬 Ollama 서버가 실행 중이어야 합니다. 모델 다운로드만으로 엔진이 바뀌지는 않습니다.
### 하네스 설치
@@ -188,18 +194,19 @@ paideia init-course
```
대화형으로:
+
1. 이 코스의 인터페이스 언어를 물어봅니다 — `en`(기본) 또는 `ko`. 이후 모든 프롬프트·드릴 지시·생성 MD 서술이 이를 따릅니다. 구조 토큰(파일 경로, 커맨드 이름, 패턴 ID `P1, P2, …`, YAML 키, 등급 마커)은 언어와 무관하게 영어로 유지됩니다.
-2. 기본 OCR 엔진을 물어봅니다: `vision`(에이전트 비전, 설치 불필요), `ollama`(로컬 Qwen3-VL), `tesseract`.
+2. 기본 OCR 엔진을 물어봅니다: `vision`(에이전트 비전), `ollama`(로컬 Qwen3-VL), `tesseract`.
3. `COURSE_NAME`, `EXAM_DATE`, `EXAM_TYPE`, `USER_WEAK_ZONES`를 물어봅니다.
4. 디렉토리 골격을 생성합니다.
5. `.course-meta`(모든 커맨드와 `vision_ocr.py`가 읽는 `INTERFACE_LANG`+`OCR_ENGINE`), `AGENTS.md` 코스 컨텍스트, 그리고 `instructions` 키로 `AGENTS.md`를 폴더 내 모든 실행에 로드하는 `opencode.json`을 씁니다.
-6. `git init`으로 첫 타건부터 버전 관리합니다.
+6. 코스용 ignore 규칙을 추가합니다. 코스 폴더에 `.git`이 없으면 `git init`·파일 스테이징·초기 커밋을 시도하고, 기존 저장소에는 자동 커밋하지 않습니다. 이후 변경은 직접 커밋하세요.
단일 채점 호출에서 엔진 덮어쓰기: `paideia grade --ocr=vision 경로/answer.pdf`.
### 기존 코스 폴더 (마이그레이션)
-`.course-meta`에 `INTERFACE_LANG`이 없는 코스는 `en`으로 취급됩니다. 한국어 출력을 유지하려면 `INTERFACE_LANG: ko` 한 줄만 추가하면 됩니다.
+`INTERFACE_LANG`이 없으면 `en`으로 취급하며, 한국어 설명을 원하면 `INTERFACE_LANG: ko`를 추가합니다. 다른 에디션에서 이동할 때는 `AGENTS.md`·`opencode.json`·OCR 엔진도 확인하세요. Codex의 `codex-native`는 `vision`, `qwen3-vl`은 `ollama`에 대응합니다. `.course-meta`가 있으면 `init-course`는 `--force` 없이 재초기화하지 않습니다. 강제 실행 시 메타데이터를 다시 쓰고, 변경된 기존 `AGENTS.md`는 `.bak`으로 백업하며, 기존 `opencode.json`은 보존합니다. 개인 이력과 직접 편집한 산출물을 유지하세요.
---
@@ -217,7 +224,7 @@ my-course/
├── materials/ # 원본 파일을 여기 넣습니다 (PDF/MD)
│ ├── lectures/ textbook/ homework/ solutions/
│
-├── converted/ # 자동 생성 마크다운 — 편집 금지
+├── converted/ # 생성 마크다운 — 재변환 전에 편집 내용 보존
│ └── lectures/ textbook/ homework/ solutions/ # `paideia ingest` 출력 (비전 전사 LaTeX)
│
├── course-index/ # 지식 베이스 — `paideia analyze`가 생성
@@ -233,11 +240,11 @@ my-course/
└── .paideia/run/ # opencode에 넘긴 합성 스테이지 spec (실행마다 1개)
```
-**손으로 편집할 디렉토리는 둘뿐:** `materials/`(원본 PDF/MD)와 `answers/`(손글씨 스캔 PDF). 나머지는 커맨드가 생성하며 재생성 가능합니다. `git log `로 진행을 보거나, 폴더 전체를 Obsidian 볼트로 가리키세요.
+원본은 `materials/`, 답안 스캔은 `answers/`에 넣으세요. 마크다운 산출물은 모두 편집할 수 있지만 재생성으로 덮어쓸 수 있으니 보존할 수정은 커밋하세요. `errors/log.md`와 weakmap 이력은 원본 PDF만으로 복구할 수 없는 개인의 시도 기록이므로 보관해야 합니다. 에디션별 컨텍스트 파일과 OCR 엔진 이름은 다르니 FAQ의 코스 이동 안내를 확인하세요.
---
-## 읽기 팁: Obsidian
+## 읽기 팁: Obsidian을 쓰세요
Paideia는 모든 것을 LaTeX 수식(`$...$`, `$$...$$`)이 든 평문 마크다운으로 씁니다. 아무 에디터로도 읽히지만 **[Obsidian](https://obsidian.md)**이 자연스럽습니다:
@@ -248,15 +255,17 @@ Paideia는 모든 것을 LaTeX 수식(`$...$`, `$$...$$`)이 든 평문 마크
터미널은 마크다운 프리뷰가 있어도 수식에 약합니다 — 그것과 싸우지 마세요.
-## 그리고 강의 끝단: Alt
+---
+
+## 강의를 담는 쪽: Alt
Obsidian이 읽기 끝단의 동반자라면, **[Alt](https://www.altalt.io/ko/)**는 강의가 들어오는 다른 끝단의 동반자입니다. Alt는 강의를 녹음·전사하고, OPTIMETA의 **Exam Radar** 플러그인이 그 안에서 교수가 구두로 얼마나 강조했는지로 토픽을 랭크합니다. 그것을 `paideia alt`로 Paideia에 보내면 루프가 닫힙니다: **강의 참석 → 포착 → 시험 신호 추출 → 중요한 것만 공부.**
---
-## 전체 워크플로 — 예시
+## 전체 워크플로우 — 예시
-### 0단계 — 코스당 한 번 (15분)
+### Phase 0 — 코스당 한 번 (15분)
```bash
cp ~/textbooks/ch*.pdf ~/courses/my-course/materials/textbook/
@@ -268,7 +277,7 @@ paideia analyze "약점 힌트" # patterns + coverage + summary 생성
paideia hwmap hot # 🔥🔥 시험 핵심 존 표면화
```
-### 1단계 — 진단 (40분)
+### Phase 1 — 진단 (40분)
```bash
paideia quiz all 20 # 광범위 진단, 20문제
@@ -276,7 +285,7 @@ paideia quiz all 20 # 광범위 진단, 20문제
paideia grade # OCR + 전략 채점
```
-### 2단계 — 표적 드릴 (대부분의 준비 시간)
+### Phase 2 — 타겟 드릴링 (준비 시간의 대부분)
```bash
paideia weakmap # 우선순위 약점 리포트
@@ -287,21 +296,21 @@ paideia chain 3 # 다중 패턴 통합 문제
paideia quiz weakmap 5 # 최신 weakmap 표적 5문제
```
-### 3단계 — 통합 (~90분)
+### Phase 3 — 통합 (약 90분)
```bash
paideia mock 90 # HW밀도 가중 90분 모의고사
paideia grade # 모의고사 채점
```
-### 4단계 — 압축 (시험 전날 60분)
+### Phase 4 — 압축 (60분, 시험 전날 밤)
```bash
paideia cheatsheet --pdf # 오답 기반 1페이지
paideia weakmap # 약점 존 한 번 더 점검
```
-### 5단계 — 쿨다운 (시험 직전 10분)
+### Phase 5 — 쿨다운 (시험 10분 전)
```bash
paideia weakmap # 상위 3개만. 새로운 건 배우지 말 것.
@@ -309,7 +318,11 @@ paideia weakmap # 상위 3개만. 새로운 건 배우지 말
---
-## 커맨드 (16개 + status)
+## 명령어 (총 17개)
+
+`init`은 `init-course`의 별칭입니다.
+
+이 목록은 이 에디션의 실제 제공 기능입니다. 원본의 `reindex` 또는 `graph` 명령은 포함하지 않습니다.
| 커맨드 | 용도 |
|---------|---------|
@@ -335,65 +348,69 @@ paideia weakmap # 상위 3개만. 새로운 건 배우지 말
---
-## 내부 동작
+## 내부 구조
-### 스테이지 실행 방식
+### 단계별 실행 방식
-1. 하네스가 코스 루트(`.course-meta`)를 찾고 선행조건을 확인하고 결정적 사전작업을 합니다.
-2. **스테이지 spec**을 합성합니다 = 공유 시스템 프롬프트(`assets/prompts/_system.md`) + 실시간 **코스 컨텍스트** 블록(메타·`D-N`·단계·파일 목록·대상 파일) + 포팅된 커맨드 지시문(`assets/prompts/.md`). `{{COURSE_NAME}}`·`{{INTERFACE_LANG}}`·`{{TS}}` 등을 치환.
-3. spec을 `.paideia/run/-.md`에 쓰고 `opencode run --dir -f [-m ] --dangerously-skip-permissions`를 실행.
-4. opencode가 워크스페이스에 대해 spec을 실행하며 산출물을 씀.
-5. 하네스가 결정적 후처리를 함(스크래치 정리, 채점 PDF 아카이브, 요약 표 출력).
+프로그램이 코스 루트를 찾고 선행조건을 확인하며 파일과 `.paideia/run/`의 작업 명세를 준비합니다. 그다음 실행 지시문·`--dir`·`-f `을 붙여 `opencode run`을 호출합니다. 모델은 명세를 읽고 학습 산출물을 만들며, 프로그램은 임시 파일 정리와 성공한 채점 프로세스 뒤 답안 PDF 보관 처리를 수행합니다.
-`--dry-run`은 모델 호출 없이 정확한 명령과 합성된 spec을 보여줍니다.
+`--dry-run`은 모델 호출을 생략하지만 작업 명세 파일은 기록합니다. 모델 단계의 미리보기이며 설정·진단까지 모든 쓰기를 막는 전역 기능은 아닙니다. `blind`와 `twin`의 두 번째 단계는 별도 `--strategy "…"` 호출로 진행합니다.
### 설정
-- **모델** — `paideia --model `, 또는 `PAIDEIA_MODEL` 환경변수. 미설정 시 opencode 기본 모델.
-- **타임아웃** — 오래 걸리는 모든 자식 프로세스(각 `opencode run`, `vision_ocr.py` 로컬 OCR)에 안전 타임아웃이 있습니다(기본 **30분**); 아주 큰 코스나 느린 로컬 모델은 `PAIDEIA_TIMEOUT=<초>`로 늘리세요.
-- **권한** — 스테이지는 무인 실행을 위해 `--dangerously-skip-permissions`로 돕니다; opencode 승인 프롬프트를 유지하려면 `PAIDEIA_ASK_PERMISSIONS=1`.
-- **파이썬** — `PAIDEIA_PYTHON`으로 렌더·로컬 OCR에 쓰는 인터프리터를 덮어씁니다.
-- **색상** — `paideia status`는 TTY에서 코스 이름에 색을 입힙니다; 다른 프롬프트에 끼워 쓰려면 `NO_COLOR=1`(또는 `--plain`)로 이스케이프를 모두 끕니다.
-- **종료 코드** — `0` 성공, `1` 사용법·스테이지 오류. `paideia doctor`는 추가로 차단 이슈에 `2`, 경고에 `1`을 반환하므로 `paideia doctor && …` 로 완전히 깨끗한 설치만 통과시킬 수 있습니다.
-- **워크스페이스 설정** — `init-course`가 `opencode.json`(`instructions: ["AGENTS.md"]` 상시 컨텍스트 + `permission` allow)과 코스 `.gitignore`를 작성합니다.
+| 설정 | 효과 |
+|------|------|
+| `--model provider/model` / `PAIDEIA_MODEL` | 모델 선택. 생략하면 opencode 기본 모델 사용 |
+| `PAIDEIA_TIMEOUT` | 긴 자식 프로세스의 제한 시간(초). 기본 1800 |
+| `PAIDEIA_PYTHON` | PDF 렌더링·로컬 OCR 인터프리터 |
+| `PAIDEIA_ASK_PERMISSIONS=1` | 실행기의 자동 승인 플래그 생략. 코스 `opencode.json` 권한은 여전히 적용 |
+| `NO_COLOR=1` / `status --plain` | 색상 없는 상태 출력 |
+
+부트스트랩은 `AGENTS.md`와 이를 읽는 `opencode.json`을 쓰고 `edit`, `bash`, `webfetch`를 허용합니다. 해당 작업의 승인을 받으려면 명시적 권한 규칙도 확인하세요. `doctor`의 종료 코드는 정상 0, 경고 1, 차단 문제 2이며, 다른 명령은 대체로 성공 0·오류 1입니다. 모델 프로세스의 성공만으로 요청한 모든 산출물이 생성되었음을 보장하지는 않습니다.
+
+### 인제스트 파이프라인: 모든 PDF를 비전으로
-### 인제스트 파이프라인: 모든 PDF에 비전
+PDF는 페이지 이미지로 렌더링한 뒤 전사하고, 마크다운 원본은 출처 헤더를 붙여 복사합니다. ingest가 변환 자료를 쓰고, analyze가 이를 읽어 `summary.md`, `patterns.md`, `coverage.md`를 만듭니다.
-`paideia ingest`는 `materials/**`의 모든 PDF를 같은 비전 파이프라인으로 보냅니다. 텍스트 추출은 먼저 시도했으나 비신뢰로 판명됐습니다 — 평문처럼 *보이는* 페이지도 수식·도형·다단·여백 메모가 섞이는 순간 조용히 단어 샐러드가 됩니다.
+프로그램은 opencode 호출 전에 ingest PDF를 160 dpi, 긴 변 1800 px 이하로 렌더링합니다. 명세는 PDF당 에이전트 하나와 페이지 순서대로 읽기를 요청합니다. 최신 변환본은 건너뛰며 `--force`로 다시 변환합니다. 같은 분류 안에 이름이 같은 PDF와 `.md`가 있으면 `.md`가 우선합니다.
-하네스가 모든 페이지를 `dpi=160` PNG로 렌더하고, **어떤 에이전트가 읽기 전에** 긴 변 ≤1800px로 리사이즈합니다(many-image 요청은 2000px 초과 이미지를 거부; 16:9 슬라이드는 선제 리사이즈 없이는 이를 넘김). 그 뒤 opencode가 PDF당 서브에이전트 1개를 띄워 각자 자기 페이지를 *순차*로 읽고 LaTeX 마크다운으로 전사합니다 — `ℏ ∂ p2 ℏ 2 ∂ 2 p ̂` 대신 `$$\hat H = -\frac{\hbar^2}{2m}\partial_x^2 + V(x)$$`. 렌더가 결정적이라 하네스가 소유합니다(토큰 비용 없음, "읽기 전 리사이즈" 순서 보장).
+**PDF ingest는 항상 opencode의 에이전트 비전을 사용합니다.** `OCR_ENGINE`과 `grade --ocr=…`는 답안 OCR을 선택하며 ingest를 바꾸지 않습니다. 마크다운만 있는 ingest는 모델 호출 없이 끝날 수 있습니다.
-### 손글씨 OCR: 세 엔진, 당신이 선택
+### 필기 OCR: 세 가지 엔진 중에서 직접 고르실 수 있습니다
-종이에 풀고 PDF로 스캔해 `answers/`에 넣고 `paideia grade`를 돌립니다. 하네스가 코스별(`.course-meta`의 `OCR_ENGINE`)로 고르고 호출별(`paideia grade --ocr=<엔진>`)로 덮어쓸 수 있는 세 엔진 중 하나로 마크다운으로 변환합니다:
+종이에 풀고 `answers/`에 스캔을 넣은 다음 `paideia grade`를 실행합니다. 엔진은 코스별로 고르고 `--ocr=`으로 호출별 변경이 가능합니다.
-| 엔진 | 기본? | 동작 | 선택 시점 |
-|---|---|---|---|
-| `vision` | **예** | 하네스가 각 페이지를 래스터화 → opencode가 각 PNG를 읽어 한 번에 마크다운 합성. 추가 모델/설치 없음. | 기본 경로. 한국어+LaTeX에 강함. opencode에 비전 모델 필요. |
-| `ollama` | 선택 | `vision_ocr.py --engine=ollama` → 로컬 Qwen3-VL 8B, tesseract 자동 폴백. | 페이지 이미지가 기기를 절대 떠나지 않길 원할 때. `ollama pull qwen3-vl:8b`(~6GB) 1회 필요. |
-| `tesseract` | 선택 | `vision_ocr.py --engine=tesseract` → pytesseract(`eng`, ko면 `eng+kor`). | 가장 빠르고 가벼움; 타이핑 스캔에 적합; 손글씨엔 약함. |
+| 엔진 | 기본값? | 동작 방식 | 선택 시점 |
+|------|---------|-----------|-----------|
+| `vision` | 예 | 페이지를 렌더링한 뒤 에이전트의 비전 경로로 읽음 | 비전 모델·도구가 정상 설정되어 있을 때 |
+| `ollama` | 선택 | 로컬 Ollama `qwen3-vl:8b`, Tesseract 폴백 포함 | 답안 OCR의 페이지 이미지를 로컬에서 처리할 때 |
+| `tesseract` | 선택 | 로컬 `pytesseract` | 타이핑된 스캔. 필기·수식은 꼼꼼한 확인 필요 |
-각 엔진은 `answers/converted/.md`를 ``/`` 헤더와 함께 써서 `grade`가 저신뢰 OCR을 단서로 처리하게 합니다.
+기본 답안 OCR은 `vision`이며 실행 환경의 비전 경로로 페이지 이미지를 읽습니다. 로컬 답안 OCR을 쓰려면 Ollama와 `qwen3-vl:8b`를 설치한 뒤 `.course-meta`에 `OCR_ENGINE: ollama`로 지정하거나 grade에 `--ocr=ollama` 옵션을 붙이세요. 모델을 다운로드하는 것만으로 엔진이 바뀌지는 않습니다. `tesseract`도 로컬 선택지입니다. 로컬 OCR은 전사 단계를 기기 안에서 처리하며, 이후 분석·채점은 설정된 모델을 사용하므로 전사된 텍스트가 외부 모델에 전달될 수 있습니다.
-### 줄단위가 아닌 전략 기반 채점
+### 라인 단위가 아닌, 전략 기반 채점
-손글씨 수식 OCR 노이즈는 엄격한 대수 채점을 무용하게 합니다 — `∫`를 `∑`로 한 번만 오독해도 연쇄됩니다. 더 중요하게, **패턴 인식이 실제 시험 병목**이지 산수가 아닙니다. 채점기는 문제마다 세 가지를 봅니다:
+채점 지침은 (1) 선택한 패턴 `Pk`, (2) 변수·치환·기저·경로, (3) 최종 식의 형태를 봅니다. OCR이 불확실하면 전사와 채점 결과를 확인하세요. 오류는 `problem_id`, `pattern`, `error_type`, `summary`, `source`, `date` 필드로 `errors/log.md`에 추가합니다. 오류 유형은 `pattern-missed`, `wrong-variable`, `wrong-end-form`, `algebraic`, `sign`, `definition`입니다.
-1. **패턴** — `course-index/patterns.md`에서 올바른 Pk를 골랐는가?
-2. **변수** — 올바른 치환/기저/지표/등고선을 짚었는가?
-3. **최종형** — 최종 식의 형태(차원·점근·구조)가 맞는가?
+치트시트는 코스 인덱스와 오답 이력을 함께 사용합니다. 패턴·공식은 참조 내용을 제공하고, 오답은 주의점과 교정 항목을 결정합니다. `--pdf`는 `cheatsheet/final.md`를 pandoc 또는 ReportLab 폴백으로 PDF로 바꿉니다. PDF 생성이 누락되거나 실패해도 경고만 출력하고 종료 코드 0을 반환할 수 있으므로, `final.pdf`의 존재와 수식 렌더링을 확인하세요.
-오답은 타입 분류(`pattern-missed | wrong-variable | wrong-end-form | algebraic | sign | definition`)와 함께 YAML로 `errors/log.md`에 기록됩니다. 이 로그가 `paideia weakmap`의 씨앗이자 치트시트 *함정(traps)* 섹션의 핵심입니다 — `paideia cheatsheet`는 이를 `patterns.md`·`coverage.md`·`summary.md`와 함께 읽습니다.
+### *당신의* 풀이에서 추출된 패턴
-### 추가 전용 이력 & status
+`paideia analyze`는 과목의 풀이와 예제를 읽어 반복되는 접근법을 `P1`, `P2`, …로 붙이고 `converted/`의 출처를 인용합니다. 패턴 카드와 숙제 커버리지가 이후 드릴의 맥락이 됩니다. 모델이 만든 인덱스는 실제 과제와 대조해 확인할 수 있습니다.
-`weakmap/`는 절대 덮어쓰지 않습니다 — 매 실행이 `weakmap/weakmap_.md`를 만들어, `git log weakmap/`이 "내 이해를 시간순으로 `git diff`"가 됩니다.
+### Append-only 이력
-`paideia status`는 사이클상 위치(`paideia · · D-<일수> · · P ↑`)를 **디스크 활동**(달력 아님)에서 유도해 보여줍니다: `setup`(`patterns.md` 없음) → `diag`(채점 오답 없음) → `drill`(퀴즈 문제 + 채점된 `- problem_id:` 항목) → `mock`(mock 출처 항목 등장) → `cram`(`cheatsheet/final.*` 존재) → `cool`(`D-0`). ``는 최신 weakmap의 최상위 `pattern:` 태그(리포트 자체가 우선순위 순)이며, weakmap이 없으면 `errors/log.md`의 최빈 `pattern:` 태그입니다. `paideia status --banner`는 같은 내용을 2줄 세션 브리핑으로 출력합니다.
+명령은 `errors/log.md`에 시도를 추가하고 `weakmap/`에 날짜가 붙은 리포트를 저장합니다. 재변환하거나 에디션을 옮길 때 이 이력을 보존하세요. 문제지와 정답·풀이 파일은 별도로 생성되므로 먼저 문제를 풀고 해답을 여세요.
+
+### 상태와 세션 배너
+
+`paideia status`는 코스 · D-N · 단계 · 최다 실수를 보여 줍니다. `patterns.md`가 없으면 `setup`, 패턴은 있지만 퀴즈 문제와 인식되는 오답 항목이 함께 있지 않으면 `diag`, 둘 다 있으면 `drill`, 모의고사 출처 기록이 인식되면 `mock`, `cheatsheet/final.md`나 `.pdf`가 있으면 `cram`, 시험 당일이면 `cool`입니다. 최신 weakmap의 첫 패턴을 우선하고 없으면 오답 로그의 빈도로 판단합니다. 이는 파일 기반 추정이며 숙련도의 증명은 아닙니다.
+
+`paideia status --banner`는 두 줄 요약을 출력합니다. 직접 실행하는 명령이며 호스트의 세션 시작 훅을 설치하지 않습니다.
---
-## 무엇이 들어 있나
+## 배포물
```
PAIDEIA-opencode/
@@ -420,47 +437,51 @@ PAIDEIA-opencode/
---
-## 설계 신념
+## 설계 원칙
-1. **터미널은 수식에 약하다.** 하네스가 마크다운 파일을 만들고 당신이 읽는다(이상적으로 Obsidian에서).
-2. **풀이 타이핑은 느리고 오류가 잦다.** 종이에 풀고 스캔하면 하네스가 로컬로 OCR한다.
-3. **OCR 노이즈는 불가피하다.** 그래서 채점은 줄단위 대수가 아니라 전략 기반(패턴/변수/최종형)이다 — 실제 시험 채점관이 보는 것도 그것이다.
-4. **패턴은 *당신* 코스의 솔루션에서 추출되어야 한다** — 일반 목록이 아니라.
-5. **당신의 오답이 가장 가치 있는 학습 신호다** — 교재보다, 강의보다. 치트시트는 강의계획서가 아니라 `errors/log.md`에서 생성된다.
-6. **HW 밀도가 시험을 말해준다.** 시간은 유한하니, 점수가 있는 곳에 써라.
-7. **모든 것은 당신이 편집한다.** 패턴·weakmap·치트시트·오답 로그 — 전부 당신의 git 이력 속 평문 마크다운/YAML. 하네스는 발판, 학습 그래프는 당신 것.
+1. **수식은 마크다운으로 읽습니다.** Obsidian이나 마크다운을 보여 주는 데스크톱 화면에서 코스를 여세요.
+2. **풀이는 종이에 씁니다.** 답안을 스캔하고 환경에 맞는 OCR 경로를 고릅니다.
+3. **전략과 전사를 확인합니다.** 패턴·변수·최종 형태로 채점하며 OCR과 모델 판단은 교정할 수 있습니다.
+4. **내 과목에서 패턴을 뽑습니다.** 제공한 풀이와 예제를 출처로 인용합니다.
+5. **기록한 오답에서 배웁니다.** 연습과 치트시트의 주의점에 반영합니다.
+6. **숙제로 우선순위를 정합니다.** 밀도를 학습 신호로 삼고 공지된 시험 범위와 대조합니다.
+7. **학습 그래프를 직접 소유합니다.** 편집 가능한 마크다운, 보존한 오답 이력, 세션을 넘는 버전 관리입니다.
---
## FAQ
-**비수학 과목에도 되나요?**
-문제-패턴 추출 중심이라 정량 분야(수학·물리·EE·CS이론·ML이론·통계·공학)에서 빛납니다. 역사·문학도 인제스트·요약은 되지만, 드릴 커맨드는 문제에 풀이 패턴이 있다고 가정합니다.
+**수학 과목이 아닌 경우에도 쓸 수 있나요?**
+인제스트와 요약은 활용할 수 있지만 연습 과정은 반복되는 문제 풀이 패턴을 전제합니다. 수학·물리·공학 등 정량 과목을 중심으로 설계되었습니다.
+
+**다음 세션은 제 작업을 어떻게 기억하나요?**
+코스 컨텍스트·인덱스·오답 이력이 파일로 남고 다음 명령이 다시 읽습니다. 학습 기록을 대화 이력에만 의존하지 않습니다.
-**한·영 혼합 자료는?**
-됩니다. 인제스트·OCR이 `eng+kor`로 구성됩니다. 패턴·채점 응답이 원자료의 언어 혼합을 존중합니다. 인터페이스 언어는 `init-course`에서 코스별로 설정합니다.
+**패턴이나 치트시트를 직접 수정해도 되나요?**
+네. 마크다운 에디터에서 저장하고 재생성 전에 보존할 파일을 커밋하세요. 오답 로그와 weakmap 이력은 따로 유지해야 합니다.
-**LLM에 그냥 공부 도와달라는 것과 뭐가 다른가요?**
-코스별 영속성입니다. LLM 채팅은 2주 전 HW2에서 놓친 패턴도, 교수가 강조하는 섹션 랭킹도, "당신의 전형적 오답 타입"도 기억하지 못합니다. Paideia는 그 모두를 디스크의 마크다운에 씁니다. 오늘의 `paideia weakmap`은 코스 시작 이래 모든 `paideia grade`에서 정보를 받습니다 — `errors/log.md`가 추가 전용이기 때문입니다.
+**한국어·영어가 섞인 자료도 되나요?**
+`.course-meta`의 `INTERFACE_LANG: en` 또는 `ko`로 생성 설명의 언어를 고릅니다. 파일 경로·패턴 ID·YAML 키·티어 토큰은 유지됩니다. 로컬 OCR 스크립트는 이에 맞는 Tesseract 언어 설정을 사용하므로 필요한 언어팩을 설치하세요.
-**왜 opencode 플러그인이 아니라 하네스인가요?**
-플러그인은 한 에디터의 루프 안에 삽니다. 하네스는 학습 로직 자체를 소유하고 opencode를 교체 가능한 실행 엔진으로 구동합니다 — 그래서 같은 학습 그래프가 Claude Code·Codex·opencode 에디션에 걸쳐 이식됩니다. 모델에 보내는 정확한 지시(`.paideia/run/*.md`)를 읽을 수 있고, 어떤 스테이지든 `--dry-run`으로 재현할 수 있습니다.
+**Ollama가 꼭 필요한가요? 전체 과정이 오프라인인가요?**
+Ollama는 선택 사항이며 기본값은 실행 환경의 비전 경로입니다. 로컬 OCR은 이미지 전사를 기기에서 처리하지만 분석·채점은 설정된 모델을 사용합니다. 엔진별 준비 사항은 위 OCR 표를 참고하세요.
-**Ollama / Qwen3-VL가 필요한가요?**
-아니요. 기본 OCR 엔진은 opencode 에이전트의 네이티브 비전 — 추가 설치 없음. Ollama + `qwen3-vl:8b`는 페이지 이미지를 기기에 두고 싶은 사용자용 선택지이고, `tesseract`는 최소 설치/타이핑 스캔용 세 번째 옵션입니다.
+**PAIDEIA 에디션 사이에 코스를 옮길 수 있나요?**
+마크다운 학습 산출물은 폴더 구조를 공유합니다. 먼저 대상 에디션의 컨텍스트 파일(`CLAUDE.md` / `AGENTS.md` / `PAIDEIA.md`)과 엔진 이름(`claude` / `codex-native` / `vision`, `ollama` / `qwen3-vl`)을 확인하세요. 기존 메타데이터와 개인 이력을 보존해야 하며, 설정과 명령 목록까지 같지는 않습니다.
-**내 데이터는 안전한가요?**
-PDF·마크다운·오답·weakmap 모두 로컬 코스 폴더에 있습니다. 네트워크 트래픽은 OCR 엔진에 따라 다릅니다: `vision`은 페이지 이미지가 opencode가 설정한 모델 제공자를 거치고, `ollama`/`tesseract`는 아무것도 기기를 떠나지 않습니다.
+**모델이 생성한 채점은 확인이 필요한가요?**
+네. 원본 스캔·전사·참조 패턴·YAML 로그를 대조해 확인하고 고칠 수 있습니다. 상태 표시는 파일에 따른 진행 안내이며 이해도를 독립적으로 측정한 결과는 아닙니다.
---
-## Connect
+## 연락
-
+
+
---
diff --git a/README.md b/README.md
index 312e53c..27fe9f9 100644
--- a/README.md
+++ b/README.md
@@ -2,27 +2,19 @@
Your course. Your patterns. Your errors. Your cheatsheet.
- An exam-prep harness that turns your own materials into a permanent, editable, per-course study graph — every artifact shaped by you, not by a generic syllabus. The opencode edition: a standalone harness that drives opencode, not an editor plugin.
+ An opencode command-line harness that turns your own materials into a permanent, editable, per-course study graph — every artifact shaped by you, not by a generic syllabus.
-
-
-
-
- Capture lectures with Exam Radar — OPTIMETA's Alt plugin — and study them with Paideia. Pipe a roadmap straight in with paideia alt.
-
-
-
-
+
-
+
@@ -32,23 +24,38 @@
+
+ 

+ 
+
Original PAIDEIA coverage and interactive demo.
+
+
한국어 README
·
- PAIDEIA — original Claude Code edition
- ·
- PAIDEIA-codex — OpenAI Codex CLI edition
+ taewoopark.com — author site
-> **Using opencode instead of Claude Code or Codex?** Same tool, same on-disk layout, same license — re-built as a **harness** that drives opencode. The original PAIDEIA is a Claude Code *plugin* (commands + skills the editor loads); this edition is a self-contained program that sits above opencode and drives it, one `opencode run` per stage. Pick whichever agentic runner you already pay for; the study graph it builds is identical and portable across all three.
+The PAIDEIA family — one study engine, every agentic runtime
-> **Security notice.** PAIDEIA for opencode installs as a normal npm/Node CLI (`paideia`) and never asks you to download a `.zip`, run an `.exe`, or use any installer. Any other repository using the PAIDEIA name is not affiliated with this project unless it is explicitly linked from this README.
+| Platform | Repository | What it is |
+|:--:|:--|:--|
+|
| **[PAIDEIA](https://github.com/OPTIMETA/PAIDEIA)** | The original — a **Claude Code** plugin. |
+|
| **[PAIDEIA-codex](https://github.com/OPTIMETA/PAIDEIA-codex)** | **OpenAI Codex** skills + bundled MCP server. |
+|
| **[PAIDEIA-opencode](https://github.com/OPTIMETA/PAIDEIA-opencode)** | Command-line harness driving **opencode**. |
+|
| **[PAIDEIA-Hermes](https://github.com/OPTIMETA/PAIDEIA-Hermes)** | **Hermes Agent** plugin: CLI commands + gateway routing. |
+|
| **[PAIDEIA-mcp](https://github.com/OPTIMETA/PAIDEIA-mcp)** | Standalone local **MCP** server — drive PAIDEIA from Alt local models. |
+|
| **[PAIDEIA-Alt](https://github.com/OPTIMETA/PAIDEIA-Alt)** | **Exam Radar** — the Alt lecture-capture plugin ([altalt.org](https://altalt.org)). |
Generic study tools teach you the average syllabus. Paideia teaches you your syllabus —
from your professor's notes, your HW emphases, your handwriting, your errors. Every artifact is a markdown file you can edit.
+
+
+
+
---
## What Paideia means
@@ -63,95 +70,88 @@ This harness implements that cycle for the specific, bounded problem of **exam p
└────────────────── feedback loop ───────────────────────┘
```
-Every stage produces a markdown artifact that lives in your course folder forever. Nothing is ephemeral. Nothing is hidden behind an API. Nothing stops working when the next funding winter hits.
-
----
-
-## Harness, not a plugin
-
-The original PAIDEIA is a *plugin* — slash commands and skills an editor (Claude Code) loads and runs inside its own agent loop. This edition is a **harness**: a self-contained program that sits *above* opencode and drives it.
-
-```
-┌──────────────────────────────────────────────────────────────┐
-│ paideia (the harness — owns ALL the exam-prep logic) │
-│ │
-│ command ─▶ deterministic prep ─▶ compose a stage │
-│ parsing (render PDFs, run OCR, SPEC (system + │
-│ discover files, git, course context + │
-│ manage the workspace) instructions) │
-│ │ │ │
-│ ▼ ▼ │
-│ python / poppler opencode run --dir … │
-│ / ollama / tesseract -f │
-└──────────────────────────────────────────────┬───────────────┘
- ▼
- opencode (the execution engine)
- model · tools (Read/Write/Bash/Task) · auth
-```
-
-- **The harness owns the study logic.** Every command, prompt, and rule lives in this repo. opencode needs no PAIDEIA plugin, agent, or skill installed.
-- **opencode is the substrate.** It provides the model, the file/shell/subagent tools, and authentication. Each PAIDEIA stage is one `opencode run`.
-- **Deterministic work stays in the harness** (PDF rasterization, local OCR, the directory skeleton, idempotence, git, PDF archiving, phase detection) — no token cost, no guesswork.
-- **The model does the model-shaped work** (vision transcription, pattern extraction, problem generation, strategy grading) via a fully-composed specification.
+The study stages save Markdown artifacts in your course folder. You can keep reading, editing, and versioning those files independently of the agent. Generating new artifacts still requires the runtime, tools, and model used by the chosen stage.
---
## What generic study tools can't do
-Most study tools can't personalize to *your* course, *your* professor, or *your* mistakes — because the product they sell is a generic curriculum.
+Paideia starts with *your* course, *your* professor's assignments, and *your* mistakes. The input is the folder you bring: lecture notes, textbook chapters, homework, solutions, and scanned attempts.
-- **Coursera, edX, Khan Academy** — fixed curriculum; no idea what your professor actually emphasizes.
-- **Quizlet, Anki, Brainscape** — you manually curate every card; nothing derives patterns from your own solution manuals.
-- **Chegg, Course Hero** — generic solution manuals; not organized around your course's recurring idioms.
-- **ChatGPT Study Mode, Gemini "Deep Study", NotebookLM** — no persistent per-course state. Every new session starts cold, and last week's mistakes don't shape this week's drill unless you re-upload and re-explain.
+Generic curricula and manually curated flashcards can be useful companions. Paideia adds a specific workflow: extract recurring moves from your solutions, rank practice by homework coverage, and feed recorded errors into the next drill. The table describes that workflow, rather than the features or subscription terms of every learning service.
-None of them *form* understanding around the specific material in front of you. Paideia does the opposite: every artifact is derived from *your* folder — lecture notes, textbook chapter, HW, solutions, handwritten attempts — and accumulates permanently in plain markdown you can edit.
-
-| Axis | Paideia | Typical edu-SaaS / LLM chat |
+| Axis | Paideia | A generic course or an unstructured chat |
|-----|---------|------------------------------|
-| Solution patterns (`P1..Pk`) | Extracted from *your course's* own solutions, citing your own files | Generic textbook list, or none |
-| Drill priority | Weighted by *your professor's* HW emphasis (HW density = exam tier) | Fixed curriculum, or your own guesswork |
-| Cheatsheet | Built from *your* `errors/log.md` — whatever you actually got wrong | Boilerplate from the syllabus |
-| Per-course state across sessions | Permanent markdown + YAML, grows as you work | Conversation resets; paid tier for history |
-| Editing an artifact you disagree with | Open the `.md` in any editor, save | Read-only UI |
-| Version history of your own understanding | `git log` / `git diff` any artifact | Not surfaced |
-| Where the artifacts live | Your disk, as text | Remote DB, exportable only with paid tier |
+| Solution patterns (`P1..Pk`) | Extracted from your course's solutions, with source citations | Requires course-specific material and instructions |
+| Drill priority | Weighted by your professor's HW emphasis | Must be selected and maintained separately |
+| Cheatsheet | Errors shape the traps section; the course index supplies references | Must be assembled and revised separately |
+| Per-course state across sessions | Markdown + metadata files in the course folder | Depends on the service and how context is supplied |
+| Editing an artifact you disagree with | Open the `.md` in any editor and save | Depends on the tool's editing and export support |
+| Carrying prep into another semester | Copy the course folder and revise the changed material | Requires moving the relevant material and history |
+| Version history of your understanding | `git log` / `git diff`, when you commit the files | Depends on the tool's versioning support |
+| Where the artifacts live | Your disk, as text | Depends on the service |
-The harness uses opencode (which talks to a paid model) to do the heavy lifting, but everything it produces lives on your disk as plain markdown. If you switch model runners or pause your subscription, the course-index, patterns, error log, weakmaps, and cheatsheets are all still yours to open, read, edit, and diff. The scaffold is the harness; the study graph is yours.
+The runner does the model work; the study graph remains yours to open, read, edit, and diff. Changing providers or pausing a subscription does not remove the files already produced.
-By default, OCR goes through the opencode agent's native vision. If you'd rather the handwritten PDFs never leave the machine, `ollama pull qwen3-vl:8b` is a one-time ~6 GB download that flips every subsequent OCR pass to local Qwen3-VL inference.
+Default answer OCR is `vision`: page images are read through the runner's vision path. For local answer OCR, install Ollama and `qwen3-vl:8b`, then explicitly select `OCR_ENGINE: ollama` in `.course-meta` or pass `--ocr=ollama` to grade. Downloading the model alone does not change the engine. `tesseract` is the other local option. Local OCR keeps that transcription step local; subsequent analysis and grading still use the configured model and may send it the transcribed text.
---
## The load-bearing principle: HW density = exam probability
-Most "study smart" advice tells you to hunt your blind spots. That is **backwards**. The professor has *already told you* where the exam points live — by assigning homework. Sections with heavy HW coverage are 🔥🔥 Exam-primary. Sections with zero HW are ⚪ Low-risk, not "hidden traps". The professor's omission is the strongest possible signal that the topic is off the exam.
-
-Paideia's ranking is explicit about this, and every drill command honors it by default:
+Homework is Paideia's primary signal for allocating exam-prep time. Sections with more assigned problems get more practice; sections without homework remain reference material by default. **These are study-priority tiers, not measured probabilities or a guarantee of what the professor will test.**
-| Tier | HW count on section | Treatment | Share of mock-exam points |
-|------|---------------------|-----------|---------------------------|
+| Tier | HW count on section | Treatment | Target share of mock-exam points |
+|------|---------------------|-----------|---------------------------------|
| 🔥🔥 Exam-primary | 3+ | Drill hardest | ≥70% |
| 🔥 Exam-likely | 2 | Drill next | ~25% |
| 🟡 Exam-possible | 1 | Warm-pass review | ≤5% |
-| ⚪ Low-risk | 0 | Reference only | 0 |
+| ⚪ Low-risk | 0 | Reference only | 0 by default |
-`paideia quiz all`, `paideia mock`, `paideia hwmap hot` all weight output by this tiering. If you insist on drilling a ⚪ section, the harness complies once and warns you that exam probability is low — your limited time is worth more than an imagined gotcha.
+`paideia quiz all`, `paideia mock 90`, and `paideia hwmap hot` use this ranking. These allocations are instructions to the generating agent; inspect the resulting mock before relying on its exact distribution. Explicit requests and imported Exam Radar signals can inform what you choose to review.
---
## The formation cycle, stage by stage
+Actual macOS CLI sessions, viewed through a local terminal viewer. The course uses small synthetic demonstration materials. · Capture notes
+
+
+
+
+
paideia status — course · D-N · phase
+ |
+
+
+
paideia --help — command reference
+ |
+
+
+
+
+
paideia ingest — Markdown ingest
+ |
+
+
+
paideia doctor — dependency check
+ |
+
+
+
+Run **`paideia ` in your shell**. This edition is a standalone Node.js harness: it prepares files and a stage specification, then starts `opencode run` for the model work. It supplies 17 commands including `status`; `init` aliases `init-course`.
+
+Setup, diagnostics, status, and Markdown copy-through run locally. Model stages are separate CLI invocations. For a two-step blind/twin exercise, submit your approach with `paideia blind --strategy "…"` or `paideia twin --strategy "…"`; there is no persistent PAIDEIA chat awaiting the reply. Read generated math in Obsidian.
+
| Stage | What it does | Commands | Produces |
|-------|-------------|----------|----------|
| **Encounter** | Read the professor's signal | `paideia ingest` | `converted/**/*.md` — every lecture, textbook chapter, HW, solution, as clean markdown |
| **Structure** | Extract the grammar of the course | `paideia analyze` | `course-index/{summary,patterns,coverage}.md` — topic tree, recurring solution patterns (P1..Pk), HW-density exam-tier ranking |
-| **Practice** | Active recall weighted by what the professor actually tests | `paideia quiz`, `paideia twin`, `paideia blind`, `paideia chain`, `paideia mock` | `quizzes/`, `twins/`, `chain/`, `mock/` — problems you solve on paper |
+| **Practice** | Active recall weighted by assigned homework | `paideia quiz`, `paideia twin`, `paideia blind`, `paideia chain`, `paideia mock` | `quizzes/`, `twins/`, `chain/`, `mock/` — problems you solve on paper |
| **Reflection** | Your hand-written work becomes a grade | `paideia grade` | `answers/converted/.md` + `errors/log.md` — OCR via agent vision (default), Ollama/Qwen3-VL, or Tesseract; then strategy-based grading |
| **Diagnosis** | Errors compressed into a priority-ranked weakness report | `paideia weakmap` | `weakmap/weakmap_.md` — append-only history |
| **Distillation** | One page, error-driven, printable | `paideia cheatsheet`, `paideia derive`, `paideia pattern` | `cheatsheet/final.md`, `derivations/.md` — reference only what you actually need |
-Supporting: `paideia hwmap` surfaces HW-density exam-probability, `paideia status` shows where you are in the cycle, and `paideia init-course` bootstraps a fresh course folder.
+Supporting: `paideia hwmap` shows homework-based study priorities, `paideia status` shows where you are in the cycle, and `paideia init-course` bootstraps a fresh course folder.
---
@@ -163,7 +163,7 @@ Supporting: `paideia hwmap` surfaces HW-density exam-probability, `paideia statu
- **Node ≥ 18.17** (runs the harness — plain ESM, zero runtime dependencies)
- **[opencode](https://opencode.ai)** (the execution engine) — `npm i -g opencode-ai`, then `opencode auth login` once
-- **Python 3.9+** with `pdf2image` + `pillow` (PDF rendering & local OCR); add `reportlab` for `cheatsheet --pdf`
+- **Python 3.9+** with `pdf2image` + `pillow` for rendering. In the Python environment used by PAIDEIA, run `python3 -m pip install pdf2image pillow`; add `pytesseract` for local Tesseract/fallback and `reportlab` for the fallback PDF exporter. Use `PAIDEIA_PYTHON` to select a virtual environment’s interpreter.
- A Unix-style shell (`bash` / `zsh`). On Windows use [WSL2](https://learn.microsoft.com/windows/wsl/install).
- **macOS**: `brew install poppler tesseract tesseract-lang`
- **Linux (Debian/Ubuntu)**: `apt-get install poppler-utils tesseract-ocr tesseract-ocr-kor`
@@ -172,7 +172,7 @@ Supporting: `paideia hwmap` surfaces HW-density exam-probability, `paideia statu
- `ollama` + the `qwen3-vl:8b` model (~6 GB). `brew install ollama && ollama pull qwen3-vl:8b`.
-If you don't install Ollama, Paideia's default OCR engine is the opencode agent's own vision — nothing extra to install.
+The default answer OCR is `vision`; it requires the rendering dependencies above and a working vision-capable opencode model. Selecting `ollama` requires a running local Ollama server. Downloading the model alone does not switch the engine.
### Install the harness
@@ -194,18 +194,19 @@ paideia init-course
```
This interactively:
+
1. Asks which interface language you want for this course — `en` (default) or `ko`. All subsequent prompts, drill instructions, and generated MD narrative follow that choice. Structural tokens (file paths, command names, pattern IDs `P1, P2, …`, YAML keys, tier markers) stay in English regardless.
-2. Asks which OCR engine you want as default: `vision` (agent vision, no install), `ollama` (local Qwen3-VL), or `tesseract`.
+2. Asks which OCR engine you want as default: `vision` (agent vision), `ollama` (local Qwen3-VL), or `tesseract`.
3. Asks for `COURSE_NAME`, `EXAM_DATE`, `EXAM_TYPE`, `USER_WEAK_ZONES`.
4. Creates the directory skeleton (`materials/`, `converted/`, `course-index/`, `quizzes/`, `mock/`, `twins/`, `chain/`, `derivations/`, `cheatsheet/`, `weakmap/`, `answers/converted/`, `errors/`).
5. Writes `.course-meta` (carries `INTERFACE_LANG` + `OCR_ENGINE`, read by every command and by `vision_ocr.py`), an `AGENTS.md` course-context file, and an `opencode.json` whose `instructions` key loads `AGENTS.md` into every run in the folder.
-6. `git init` so your prep is versioned from the first keystroke.
+6. Adds course ignore rules. If there is no `.git` in the course folder, runs `git init`, stages files, and attempts an initial commit; existing repositories are not auto-committed. Commit later changes yourself.
Override the OCR engine for a single grade call anytime: `paideia grade --ocr=vision path/to/answer.pdf`.
### Existing course folders (migration note)
-A course created without an `INTERFACE_LANG` line in `.course-meta` is treated as `en`. To keep Korean output, add one line — `INTERFACE_LANG: ko` — and that's the whole migration.
+A course without `INTERFACE_LANG` is treated as `en`; add `INTERFACE_LANG: ko` for Korean narrative. When moving from another edition, also review `AGENTS.md`, `opencode.json`, and the OCR engine: Codex’s `codex-native` corresponds to `vision`, and `qwen3-vl` to `ollama`. `init-course` leaves an existing `.course-meta` course alone unless `--force` is set. Forced bootstrap rewrites metadata, backs up a changed `AGENTS.md` to `.bak`, and preserves an existing `opencode.json`. Keep personal history and edited artifacts.
---
@@ -226,7 +227,7 @@ my-course/
│ ├── homework/ # HW problem sets
│ └── solutions/ # HW solutions / worked examples
│
-├── converted/ # auto-generated markdown — do not edit
+├── converted/ # generated Markdown — back up edits before re-ingest
│ ├── lectures/ # output of `paideia ingest` (vision-transcribed LaTeX)
│ ├── textbook/ homework/ solutions/
│
@@ -247,7 +248,8 @@ my-course/
└── .paideia/run/ # the composed stage specs handed to opencode (one per run)
```
-**Only two directories are yours to edit by hand:** `materials/` (drop source PDFs/MDs) and `answers/` (drop hand-written scan PDFs). Everything else is produced by commands and is regenerable. `git log ` shows your progress over time, or point Obsidian at the whole folder as a vault.
+
+Drop source files in `materials/` and answer scans in `answers/`. All Markdown artifacts are editable; generation can overwrite derived files, so commit edits you want to preserve. Keep `errors/log.md` and the weakmap history: they record personal attempts that cannot be reconstructed from the source PDFs alone. Runtime context files and OCR engine names differ between editions; see the migration FAQ.
---
@@ -262,6 +264,8 @@ Paideia writes everything as plain markdown with LaTeX math (`$...$`, `$$...$$`)
The terminal — even with a markdown preview — is bad for math; don't fight that.
+---
+
## And the lecture end: Alt
Obsidian is the companion at the reading end. **[Alt](https://www.altalt.io/ko/)** is the companion at the other end — where the lectures come in. Alt records and transcribes your lectures, and OPTIMETA's **Exam Radar** plugin runs inside it to rank topics by how strongly the professor emphasized them out loud. Send that into Paideia with `paideia alt`, and the loop closes: **attend the lecture → capture it → extract the exam signal → study what matters.**
@@ -325,7 +329,9 @@ paideia weakmap # top 3 only. Do not learn new things.
---
-## Commands (16 + status)
+## Commands (17 total)
+
+This is the installed command inventory for this edition; `init` is an alias for `init-course`. It does not include the original's `reindex` or `graph` commands.
| Command | Purpose |
|---------|---------|
@@ -355,61 +361,61 @@ Global flags: `--model ` (pass a model to opencode), `--dry-run`
### How a stage runs
-1. The harness resolves the course root (`.course-meta`), checks prerequisites, and does any deterministic prep.
-2. It composes a **stage spec** = the shared system prompt (`assets/prompts/_system.md`) + a live **course context** block (meta, `D-N`, phase, file listings, target files) + the ported command instructions (`assets/prompts/.md`), interpolating `{{COURSE_NAME}}`, `{{INTERFACE_LANG}}`, `{{TS}}`, ….
-3. It writes the spec to `.paideia/run/-.md` and runs `opencode run --dir -f [-m ] --dangerously-skip-permissions`.
-4. opencode executes the spec against the workspace, writing the artifacts.
-5. The harness does any deterministic post-step (clean scratch pages, archive a graded PDF, print the summary table).
+The harness finds the course root, validates prerequisites, prepares files, and writes a specification under `.paideia/run/`. It invokes `opencode run` with a driver prompt, `--dir`, and `-f `. The model reads the specification and creates the study artifacts; the harness handles deterministic cleanup and answer-PDF archiving after a successful grade process.
-`--dry-run` shows the exact command and the composed spec without invoking the model.
+`--dry-run` skips the model call but still writes the stage specification. It is a preview for model stages, not a universal no-write switch for setup/diagnostics. `blind` and `twin` use separate `--strategy "…"` invocations for the second step.
### Configuration
-- **Model** — `paideia --model `, or set `PAIDEIA_MODEL`. Unset → opencode's configured default.
-- **Timeout** — every long-running child (each `opencode run`, and local OCR via `vision_ocr.py`) has a safety timeout (default **30 min**); raise it with `PAIDEIA_TIMEOUT=` for very large courses, or to allow a slow local model.
-- **Permissions** — stages pass `--dangerously-skip-permissions` so they run unattended; set `PAIDEIA_ASK_PERMISSIONS=1` to keep opencode's approval prompts.
-- **Python** — `PAIDEIA_PYTHON` overrides the interpreter used for rendering and local OCR.
-- **Colour** — `paideia status` tints the course name on a TTY; `NO_COLOR=1` (or `--plain`) suppresses every escape, for embedding the line in another prompt.
-- **Exit codes** — `0` success, `1` usage or stage error. `paideia doctor` additionally returns `2` for blocking issues and `1` for warnings, so `paideia doctor && …` gates on a fully clean install.
-- **Workspace config** — `init-course` writes an `opencode.json` with `instructions: ["AGENTS.md"]` (ambient course context) and `permission` set to allow, plus a course-scoped `.gitignore`.
+| Setting | Effect |
+|---------|--------|
+| `--model provider/model` / `PAIDEIA_MODEL` | Select the model; otherwise use opencode's default. |
+| `PAIDEIA_TIMEOUT` | Long-running child timeout in seconds; default 1800. |
+| `PAIDEIA_PYTHON` | Interpreter for PDF rendering and local OCR. |
+| `PAIDEIA_ASK_PERMISSIONS=1` | Omit the driver's automatic-approval flag. The course's `opencode.json` permissions still apply. |
+| `NO_COLOR=1` / `status --plain` | Plain status output. |
+
+Bootstrap writes `AGENTS.md` and an `opencode.json` that loads it and allows `edit`, `bash`, and `webfetch`. Review those explicit rules if you want prompts for those operations. `doctor` exits with 0 when clean, 1 for warnings, and 2 for blocking problems. Other commands generally use 0 for success and 1 for errors. A successful model process is not a guarantee that every requested artifact was produced.
### Ingest pipeline: vision for every PDF
-`paideia ingest` routes every PDF in `materials/**` through the same vision pipeline. Text extraction was tried first and proved unreliable: even pages that *look* like plain prose silently word-salad as soon as they mix equations, figures, multi-column layouts, or margin notes.
+PDFs are rendered into page images before transcription. Markdown sources are copied with a provenance header. Ingest writes the converted material; analyze then creates `summary.md`, `patterns.md`, and `coverage.md` from those sources.
+
+The harness renders ingest PDFs at 160 dpi and caps the long edge at 1800 px before calling opencode. The spec requests one agent per PDF, reading its pages in order. Up-to-date conversions are skipped; `--force` reconverts. A same-named `.md` source takes precedence over a PDF in the same category.
-The harness renders every page to PNG at `dpi=160` and resizes each to ≤1800 px on the long edge **before any agent starts reading** (many-image requests hard-reject images >2000 px; 16:9 slides blow past that unless you preempt the resize). Then opencode spawns one subagent per PDF, each reading its own pages *sequentially* and transcribing to LaTeX markdown — output like `$$\hat H = -\frac{\hbar^2}{2m}\partial_x^2 + V(x)$$` instead of `ℏ ∂ p2 ℏ 2 ∂ 2 p ̂`. Because the render is deterministic, the harness owns it (no token cost, and the resize-before-read ordering is guaranteed).
+**Ingest always uses opencode's agent vision for PDFs.** `OCR_ENGINE` and `grade --ocr=…` select answer OCR; they do not change ingest. A Markdown-only ingest can finish without a model call.
### Hand-writing OCR: three engines, you pick
-You solve on paper, scan to PDF, drop it into `answers/`, and run `paideia grade`. The harness converts the scan to markdown via one of three engines, chosen per course (`OCR_ENGINE` in `.course-meta`) and overridable per call (`paideia grade --ocr=`):
+Solve on paper, scan to `answers/`, then run `paideia grade`. Engine choice is per course and can be overridden with `--ocr=`.
| Engine | Default? | How it runs | When to pick it |
-|---|---|---|---|
-| `vision` | **Yes** | the harness rasterizes each page → opencode reads each PNG → synthesizes markdown in one pass. No extra model, nothing to install. | The out-of-the-box path. Strong on Korean + LaTeX. Needs a vision-capable model in opencode. |
-| `ollama` | opt-in | `vision_ocr.py --engine=ollama` → local Qwen3-VL 8B with automatic tesseract fallback. | You want the page images to never leave the machine. Requires `ollama pull qwen3-vl:8b` once (~6 GB). |
-| `tesseract` | opt-in | `vision_ocr.py --engine=tesseract` → pytesseract (`eng`, or `eng+kor` if `INTERFACE_LANG=ko`). | Fastest and lightest; acceptable for typed scans; poor on hand-writing. |
+|--------|----------|-------------|-----------------|
+| `vision` | Yes | Render pages, then read them through the agent's vision path. | A working vision-capable model/tool configuration. |
+| `ollama` | Optional | Local Ollama `qwen3-vl:8b`, with Tesseract fallback. | Keep the answer's OCR page images local. |
+| `tesseract` | Optional | Local `pytesseract`. | Typed scans; handwriting and math need careful review. |
-Each engine writes `answers/converted/.md` with a `` / `` header so `grade` can caveat low-confidence OCR.
+Default answer OCR is `vision`: page images are read through the runner's vision path. For local answer OCR, install Ollama and `qwen3-vl:8b`, then explicitly select `OCR_ENGINE: ollama` in `.course-meta` or pass `--ocr=ollama` to grade. Downloading the model alone does not change the engine. `tesseract` is the other local option. Local OCR keeps that transcription step local; subsequent analysis and grading still use the configured model and may send it the transcribed text.
### Strategy-based grading, not line-by-line
-OCR noise in hand-written math makes strict algebraic grading useless — a single misread `∫` vs `∑` cascades. More importantly, **pattern recognition is the actual exam bottleneck**, not arithmetic. The grader checks three things per problem:
+The grading instructions check (1) the selected pattern `Pk`, (2) the variables, substitution, basis, or contour, and (3) the final expression's form. Review the transcription and grade when OCR is uncertain. Errors are appended to `errors/log.md` using `problem_id`, `pattern`, `error_type`, `summary`, `source`, and `date`. Error types include `pattern-missed`, `wrong-variable`, `wrong-end-form`, `algebraic`, `sign`, and `definition`.
-1. **Pattern** — did the student pick the right Pk from `course-index/patterns.md`?
-2. **Variables** — did they identify the right substitution / basis / index / contour?
-3. **End-form** — does their final expression have the right shape (dimensions, asymptotics, structure)?
-
-Errors get logged as YAML to `errors/log.md` with a typed classification (`pattern-missed | wrong-variable | wrong-end-form | algebraic | sign | definition`). This log is the seed for `paideia weakmap` and the heart of the cheatsheet's *traps* section — `paideia cheatsheet` reads it alongside `patterns.md`, `coverage.md`, and `summary.md`.
+The cheatsheet uses the course index and error history together: patterns/formulas provide reference material, while your errors drive the traps and corrections. `--pdf` converts `cheatsheet/final.md` through pandoc or a ReportLab fallback. A missing or failed PDF export can print a warning while the command still exits 0; check that `final.pdf` exists and inspect its equations before printing.
### Patterns extracted from *your* solutions
-`paideia analyze` doesn't ship a generic "calculus moves" list. It reads your course's actual solution manual, extracts recurring solution patterns, and labels them P1, P2, … with worked instances that cite your own `converted/solutions/` files. For a complex analysis course, P3 might be "closed contour + Jordan's lemma + residue at essential singularity." Every discipline has its own moves; only the course itself reveals them.
+`paideia analyze` reads the course's solutions and worked examples, labels recurring moves `P1`, `P2`, …, and cites the source files under `converted/`. The resulting pattern cards and HW coverage are the context for later drills. The model-generated index should be checked against your assignments.
+
+### Append-only history
-### Append-only history & status
+Commands append attempts to `errors/log.md` and save dated reports under `weakmap/`. Keep that history when re-ingesting or migrating. Generated problem sets have separate answer/solution siblings; solve the problems before opening them.
-`weakmap/` never overwrites — every run produces `weakmap/weakmap_.md`, so `git log weakmap/` is "`git diff` your own understanding over time."
+### Status and the session banner
-`paideia status` reports where you are in the cycle — `paideia · · D- · · P ↑` — derived from **activity on disk**, not the calendar: `setup` (no `patterns.md`) → `diag` (no graded error yet) → `drill` (quiz problems + a graded `- problem_id:` entry) → `mock` (a mock-sourced entry appeared) → `cram` (`cheatsheet/final.*` exists) → `cool` (`D-0`). `` is the top-ranked `pattern:` tag in the latest weakmap — the report is already priority-ordered — falling back to the most frequent `pattern:` tag in `errors/log.md`. `paideia status --banner` prints the same as a two-line session brief.
+`paideia status` reports course · D-N · phase · top-miss. The detector uses `setup` when `patterns.md` is absent; `diag` when patterns exist without both a quiz problem and a recognized error entry; `drill` once both exist; `mock` after a recognized mock-sourced record; `cram` when `cheatsheet/final.md` or `.pdf` exists; and `cool` on exam day. The latest weakmap's first pattern is preferred, with error-log frequency as fallback. This is a filesystem heuristic, not evidence of mastery.
+
+`paideia status --banner` prints a two-line brief. This is an explicit command; the package does not install a host session-start hook.
---
@@ -445,35 +451,38 @@ PAIDEIA-opencode/
## Design convictions
-1. **The terminal is bad for math.** The harness produces markdown files; you read them (ideally in Obsidian).
-2. **Typing solutions is slow and error-prone.** You solve on paper, scan, and the harness OCRs locally.
-3. **OCR noise is inevitable.** So grading is strategy-based (pattern / variables / end-form), not line-by-line algebra — which is what the actual exam grader evaluates anyway.
-4. **Patterns must be extracted from *your* course's solutions** — not a generic list.
-5. **Your errors are the most valuable study signal** — more than the textbook, more than the lectures. The cheatsheet is generated from `errors/log.md`, not the syllabus.
-6. **HW density tells you the exam.** Your time is finite; spend it where the points are.
-7. **Everything is yours to edit.** Patterns, weakmaps, cheatsheets, the error log — all plain markdown/YAML in your own git history. The harness is a scaffold; the study graph is yours.
+1. **Read the math as Markdown.** Open the course in Obsidian or a Markdown-capable desktop view.
+2. **Solve on paper.** Scan the answer and choose the OCR path that fits your setup.
+3. **Review strategy and transcription.** Pattern, variables, and final form guide grading; OCR and model judgments can need correction.
+4. **Extract patterns from your course.** Cite the supplied solutions and worked examples.
+5. **Learn from recorded errors.** Let them shape practice and the cheatsheet's traps.
+6. **Use homework to prioritize.** Treat its density as a study signal and check it against the announced exam scope.
+7. **Keep the study graph yours.** Editable Markdown, preserved error history, and version control across sessions.
---
## FAQ
**Does this work for non-math courses?**
-It's built around problem-pattern extraction, so it shines in quantitative disciplines: math, physics, EE, CS-theory, ML-theory, statistics, engineering. For history or literature it would still ingest and summarize, but the drill commands assume problems have solution patterns.
+Ingest and summarization can help, but the practice workflow assumes recurring problem-solving patterns. It is designed for math, physics, engineering, and related quantitative courses.
-**Korean and English mixed materials?**
-Yes. Ingestion and OCR are configured for `eng+kor`. Patterns and grading responses honor the language mix of your source materials; set the interface language per course in `init-course`.
+**How does the next session remember my work?**
+The course context, index, and error history are files. Later commands read them again; your study record is not dependent on chat history alone.
-**How is this different from just asking an LLM to help me study?**
-Per-course persistence. An LLM chat has no memory of the pattern you missed on HW2, no ranking of which sections your professor emphasizes, no notion of "your typical error type." Paideia writes all of that to markdown on your disk. A `paideia weakmap` today is informed by every `paideia grade` since the course began, because `errors/log.md` is append-only.
+**Can I edit the patterns or cheatsheet?**
+Yes. Save changes in any Markdown editor and commit the files you want to preserve before regenerating them. Keep the error log and weakmap history.
+
+**Korean and English mixed materials?**
+Set `INTERFACE_LANG: en` or `ko` in `.course-meta` for the generated narrative. File paths, pattern IDs, YAML keys, and tier tokens stay unchanged. The local OCR helper uses the corresponding Tesseract language configuration; install the needed language packs.
-**Why a harness and not an opencode plugin?**
-A plugin lives inside one editor's loop. A harness owns the study logic itself and drives opencode as an interchangeable execution engine — which is why the same study graph is portable across the Claude Code, Codex, and opencode editions. You can read the exact instructions sent to the model (`.paideia/run/*.md`) and re-run any stage with `--dry-run`.
+**Do I need Ollama, and is the whole workflow offline?**
+Ollama is optional. The default uses the runtime’s vision path. Local OCR keeps image transcription on your machine, but analysis and grading still use your configured model. See the OCR engine table above for the required setup.
-**Do I need Ollama / Qwen3-VL?**
-No. The default OCR engine is the opencode agent's native vision — no extra install. Ollama + `qwen3-vl:8b` is opt-in for users who want page images to stay on their machine; `tesseract` is a third option for minimal-install setups.
+**Can I move a course between PAIDEIA editions?**
+The Markdown study artifacts share a layout. Review the destination's context file and engine names first: `CLAUDE.md` / `AGENTS.md` / `PAIDEIA.md`, and `claude` / `codex-native` / `vision` or `ollama` / `qwen3-vl`. Preserve your existing metadata and personal history; the versions do not have identical configuration or command sets.
-**Is my data private?**
-Your PDFs, markdown, errors, and weakmaps all live in your local course folder. Network traffic depends on the OCR engine: with `vision`, page images flow through opencode's configured model provider; with `ollama` / `tesseract`, nothing leaves the machine.
+**Does model-generated grading need review?**
+Yes. The source scan, transcription, referenced patterns, and YAML log let you inspect and correct an assessment. The status indicator is a file-based workflow cue, not an independent measurement of understanding.
---
@@ -483,7 +492,9 @@ Your PDFs, markdown, errors, and weakmaps all live in your local course folder.
+
+
---
diff --git a/docs/media/README.md b/docs/media/README.md
new file mode 100644
index 0000000..a7dcb64
--- /dev/null
+++ b/docs/media/README.md
@@ -0,0 +1,20 @@
+# README screenshots
+
+Captured on **2026-09-15**, on a Mac running macOS 26.6.2.
+
+- PAIDEIA-opencode: 0.2.0, source baseline `ca03229`.
+- opencode: 1.17.9; Node.js: 26.5.1; Python: 3.14.2.
+- Display: a real local shell in a loopback-only ttyd 1.7.7 browser terminal, at 1280 × 720. These are unedited captures, not interface mockups.
+- The `paideia` shell function invokes `node /bin/paideia.mjs` directly, so the screenshots use this checkout rather than an older globally linked copy.
+- Course: a synthetic complex-analysis demo, initialized by the actual `init-course` command with a 2026-12-15 exam date.
+
+| File | Actual command |
+|------|----------------|
+| `terminal-help.png` | `paideia --help` |
+| `terminal-status.png` | `paideia status --banner` |
+| `terminal-ingest.png` | `paideia ingest --force` |
+| `terminal-doctor.png` | `paideia doctor` |
+
+The three ingest inputs were Markdown: a short lecture on residues, five synthetic homework problems, and their solutions. This capture verifies Markdown passthrough, not PDF vision or model-generated analysis. The course remains in `setup` because no analyzed pattern index was produced. `doctor`'s “all clear” reports local checks, not a successful model request. Separate live analyze attempts encountered provider availability/authentication failures; these screenshots do not imply that those attempts succeeded.
+
+The README's hero reuses `terminal-help.png`. The original PAIDEIA's public interactive demo is labeled separately in the README.
diff --git a/docs/media/terminal-doctor.png b/docs/media/terminal-doctor.png
new file mode 100644
index 0000000..60d0b7c
Binary files /dev/null and b/docs/media/terminal-doctor.png differ
diff --git a/docs/media/terminal-help.png b/docs/media/terminal-help.png
new file mode 100644
index 0000000..993d336
Binary files /dev/null and b/docs/media/terminal-help.png differ
diff --git a/docs/media/terminal-ingest.png b/docs/media/terminal-ingest.png
new file mode 100644
index 0000000..b97395c
Binary files /dev/null and b/docs/media/terminal-ingest.png differ
diff --git a/docs/media/terminal-status.png b/docs/media/terminal-status.png
new file mode 100644
index 0000000..d3cdab6
Binary files /dev/null and b/docs/media/terminal-status.png differ