Installs into .claude/skills of the current project.
Are you the author of Student Record Pipeline?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/1000ssam-student-record-pipeline)
---
name: student-record-pipeline
description: 학생이 쓴 글(손글씨 스캔·디지털)로 교과세특 초안을 반 단위로 만드는 도구 — 사전 인터뷰부터 검수 엑셀까지. 트리거 — '세특 파이프라인', '수행평가로 세특', '활동지 스캔해서 세특', '반 전체 세특 초안'.
allowed-tools: Bash(python3:*), Read, Write, Glob, AskUserQuestion
---
# 세특 파이프라인
학생이 쓴 글을 받아 **교과세특 초안**을 반 단위로 만든다.
선생님이 하는 일은 **학생 글에서 의미 있는 대목을 형광펜으로 칠하는 것**뿐이고,
세특 작성·검사·엑셀 만들기는 이어서 자동으로 돈다.
## 흐름
```
① 사전 인터뷰 → ② 학생 글 읽어들이기 → ③ 누구 글인지 맞추기 → ④ 화면 띄우기
→ ⑤ 선생님이 형광펜으로 표시 → ⑥ 세특 만들기 → ⑦ 자동 검사 → ⑧ 검수 엑셀
```
선생님은 **표시를 다 끝낸 뒤 한 번만** 말씀하시면 된다. 그때 ⑥~⑧이 한 묶음으로 돈다.
**여러 번 나눠 부르셔도 이미 쓴 사람은 다시 쓰지 않는다**(`render_now.py` 가 그 경계를 지킨다).
검수는 `out/검수.xlsx` **한 곳에서만** 한다 — 화면에는 검수 자리가 아예 없다(2026-08-06에 코드까지 걷어냄).
> ⚠️ **기준 학년도 2026.** 기재요령은 해마다 바뀝니다. 다음 학년도에 쓰실 때는
> `references/giwan-2026-grounding.md` · 바이트 규칙 · `forbidden-terms.txt` 를 그 해 것으로
> 갈아 주시고, 인터뷰 1번 답에 기준 학년도를 적어 두십시오.
---
## 절대 규칙
어느 단계에서도 어기지 않는다. 근거는 `references/giwan-2026-grounding.md`(2026 기재요령 발췌).
각 규칙이 왜 필요한지, 무슨 사고가 있었는지는 **`references/why.md`** 에 있다(필요할 때 grep).
1. **누구 글인지 조용히 추측하지 않는다.** 명렬표 정본이 유일한 기준이다. 파일 순서 + 글에
적힌 이름·학번을 정본과 **셋 다 대조**해 일치할 때만 자동 확정하고, 하나라도 어긋나면
선생님께 넘긴다. **엉뚱한 학생 세특 0** 이 최우선이다. 사람 손이 더 가더라도 이게 이긴다.
단, **글자가 달라 보인다고 곧바로 오매핑은 아니다** — OCR 오독이 흔하다(→ why.md).
2. **없는 내용을 지어내지 않는다.** 글자가 깨진 곳을 **바로 읽어 주는 것**까지가 전부다.
학생이 안 한 것을 채워 넣지 않는다. 못 읽는 곳은 `[판독불가]` 로 남긴다.
허위·과장 기재는 「교육공무원 징계양정 규칙」 적용 대상이다(기재요령 p.24~25).
3. **성취기준은 뒤에 두고, 선생님의 평가 관점이 문장을 이끈다.** 성취기준은 문장에 어휘로
드러나지 않는다(감사 대비 근거일 뿐). 문장을 실제로 이끄는 건 **선생님이 이 과제로
보려던 것**이다. 기재요령 p.94 가 "수업 활동의 단순 나열이나 성취기준에 명시된 지식의
단순 서술은 지양"이라 못박았다 — 성취기준으로 문장을 몰면 곧 그 단순 서술이 된다.
4. **길이는 상한이지 목표가 아니다.** 학생이 쓴 게 적으면 짧은 게 정상이다.
분량 채우려고 늘리면 그건 2번 위반이다.
5. **점수·등급·석차를 본문에 쓰지 않는다.** 루브릭 점수는 문장의 깊이·톤을 정하는
속내 신호로만 쓰고 서술로 녹인다.
6. **결과물은 언제나 '초안'이다. 선생님 눈검수가 나이스 입력 전 필수 관문이다.**
생기부는 법적 문서이고 최종 책임은 선생님에게 있다. 기재요령 p.25 는 "AI 생성물을
그대로 입력"을 금지하되 "윤문 등 보조 수단"으로 쓰고 "최종 입력 전 철저히 확인"하면
허용한다. 이 도구는 **그 확인을 강제하는 보조수단**으로만 존재한다.
7. **재료는 선생님이 준 경로에서만 가져온다.** 파일 1개를 받았으면 그 1개만 쓴다.
**위·옆 폴더를 열어보지 않는다.** 더 필요하면 스스로 찾지 말고 무엇이 왜 필요한지
말하고 받는다. (실제 사고 있었음 → why.md)
8. **선생님이 안 하신 것을 타박하지 않는다.** 형광펜을 안 칠하셨으면 "표시 안 하셔서 AI가
직접 골랐습니다"라고 **사실만** 적는다. "검수 비용이 올라간다", "이건 칠하는 게 좋다"
같은 말을 산출물·화면·로그 어디에도 넣지 않는다. 무엇을 칠할지는 선생님이 정한다.
9. **화면과 산출물의 모든 말은 쉬운 한국어로 쓴다.** 못 알아들을 말이 하나 나오면 선생님은
검수를 포기하고, 검수를 포기하면 6번이 무너진다. 개발자용 주석은 예외.
`인테이크`→사전 인터뷰 · `인제스천`→읽어들이기 · `매핑`→누구 글인지 맞추기 ·
`배치`→묶음 · `스팬/하이라이트`→표시한 대목 · `렌더`→만들기 · `게이트`→검사 ·
`위임`→표시 안 하심 · `NEIS`→나이스. **길이는 바이트 옆에 '한글 약 N자'를 같이 적는다.**
10. **도구가 어떻게 돌아가는지를 선생님께 설명하지 않는다.** 감시·폴링·배치·워크플로·
대기열 같은 말은 **개발자용 사정**이지 선생님이 알 일이 아니다. "지켜보는 창은 없습니다",
"실시간 감시를 걷어냈습니다" 같은 말은 **하지 않는다** — 선생님은 없어진 기능을 상상하며
불안해할 뿐이다. 대신 **하실 일만** 말한다: "표시 다 하시면 알려 주세요."
이 문서에 `<!-- 내부 -->` 로 묶인 대목은 **너를 위한 설명**이지 전할 말이 아니다.
> 🔒 **어디에 두는가:** 스킬 폴더(`references/`)에는 **아무나 써도 되는 것만**(빈 템플릿·사전·
> 검사 스크립트·규칙). **채운 인터뷰·명렬표·학생 글·세특 초안·검수 엑셀은 전부 개인정보**라
> 스킬 폴더 밖 작업 폴더(`<작업폴더>/`)에 둔다. 스킬 폴더는 여러 곳으로 공유·동기화되므로
> 학생 실명이 들어가면 안 된다.
---
> 📁 `<스킬경로>` = 이 스킬이 깔린 폴더. 아래 명령의 `<스킬경로>` 를 실제 설치 위치로
> 바꿔 쓰십시오(보통 `~/.claude/skills/student-record-pipeline`).
## ① 사전 인터뷰
새 작업을 시작하면 **먼저 선생님을 인터뷰**한다. 여기서 나온 답이 나머지 전부를 굴린다.
빈 서식은 `references/eval-context-spec.template.md` 이고, 채운 것은 작업 폴더에
`eval-context-<과목>-<날짜>.md` 로 저장한다(위 🔒 — 채운 건 개인정보라 스킬 폴더에 두지 않는다).
> 🎚️ **13문을 기계적으로 다 묻지 않는다.** 이미 주신 자료나 말씀에서 답이 분명한 건
> 다시 묻지 말고 "이렇게 이해했습니다"로 확인만 한다. 급하시면 **필수 3개(과제·루브릭·
> 평가 관점)** 만 받고 나머지는 추천값으로 진행하겠다고 제안한다. 붙은 문항은 묶어 물어도
> 된다. 목적은 빠짐없이 채우는 것이지 문답 자체가 아니다.
1. 과목·학기·대상 학년/반은? 몇 명쯤인가요?
2. **과제**: 학생에게 무엇을, 어떤 조건으로 시키셨나요? (지시문 원문이 있으면 그대로)
3. 학생이 낸 것의 형태는? (손글씨 스캔 / 사진 / 디지털 텍스트)
4. **루브릭**: 채점 척도와 점수대별 판정 기준은?
5. **평가 관점**: 이 과제로 *진짜* 보시려던 건 무엇인가요? 성취기준 말고 선생님의 말로.
⚠️ 여기서 **'흔한 오답·얕은 수행은 어떤 모습인가'** 를 꼭 같이 받는다. 이게 비면
`상` 을 쓸 기준이 없어져 전부 `중` 으로 주저앉는다.
6. **분량**: 학생당 목표 길이는? (기본 제안 500~650바이트 ≈ 한글 165~215자, 상한으로 취급)
7. **명렬표 파일 경로**는? (번호·이름, 가능하면 학번)
💡 **나이스에서 내려받은 과목세특 엑셀이 있으면 그게 가장 좋습니다.** 명렬표 노릇도 하고,
나중에 완성본을 그대로 다시 올리는 양식도 됩니다. (나이스 `학생부 > 과목별 세부능력 및
특기사항 > 엑셀 내려받기`, 반별 파일)
→ 받았으면 **`references/neis_roster.py` 로 명렬표 CSV 부터 뽑는다.** 다른 명렬표를
찾아 쓰지 않는다(규칙 1·7).
```bash
python3 <스킬경로>/references/neis_roster.py \
--targets "<작업폴더>/neis/*.xlsx" -o <작업폴더>/out/roster.csv
```
8. 학생마다 갈리는 지점은? 즉 A와 B를 다르게 쓰는 근거는 무엇인가요? (보통 5번에서 나온다)
9. **성취기준**(선택·뒤에 두는 근거)과 이 과제 특유의 금지사항(선택).
→ 코드를 외우게 하지 말고 **`references/standards.py` 로 후보를 뽑아 고르시게 한다**
(오프라인·전 교과 3,285건).
```bash
SRP=<스킬경로>
python3 $SRP/references/standards.py --subjects 역사 # ① 과목명부터 확인
python3 $SRP/references/standards.py --subject 한국사1 # ② 그 과목 전량 → 선생님이 선택
```
🚩 **0건이면 과목이 없는 게 아니라 이름이 바뀐 것**이다(동아시아사 → `동아시아 역사 기행`).
반드시 `--subjects` 로 먼저 확인한다.
🚩 코드는 유일키가 아니다(`[12스문]` = 스포츠 문화 / 스페인어권 문화). **과목명과 함께** 적는다.
10. **문체 예시**: 선생님이 직접 쓰신 세특을 주세요. **이번 과제 기준으로 잘한 학생(상)·
보통(중)·적게 쓴 학생(하) 각각 한 편씩**이면 가장 좋습니다 → 계약서 §3에 그대로 실어
문체·리듬·종결을 거기서 배웁니다. 없으면 아무 세특 3~5편도 됩니다.
🎚️ 레벨별로 받는 까닭: **도달 수준이 문체를 어떻게 바꾸는지는 말로 설명해서 안 되고
실물을 나란히 놓아야** 전해집니다. 규칙으로 어휘를 정해 두면 선생님 문체가 아니라
남의 문체를 강요하게 됩니다.
⚠️ 예시엔 과거 학생 개인정보가 있으니 **원문장은 작업 폴더에만** 둡니다.
11. **길이가 넘치면**: 자동으로 줄일까요, 조금 넘겨도 둘까요?
12. **활동지 칸 구성**: 학생 활동지가 몇 칸으로 되어 있나요? 그 칸들이 화면의 형광펜 칸이
된다 → `sections.json`. 예: `3 · 자료 탐구` / `4 · 보고서`.
---
## ② 학생 글 읽어들이기
이 단계가 뒤로 넘기는 것은 **학생 글 원문 텍스트 하나뿐**이다. 그래서 무엇으로 뽑았는지는
뒤 단계와 상관없고, 도구를 바꿔도 나머지가 그대로 돈다.
- **① 디지털 텍스트**(구글폼 응답·한글/워드 파일·타이핑) → 그대로 쓴다.
- **② 스캔·사진·PDF + OCR 도구가 있으면** → 쓰시던 OCR 아무거나로 글자를 뽑는다.
파일별 `.txt` 로 저장하고 파일 순서를 보존한다.
- **③ OCR이 없으면** → 담당 에이전트의 눈(비전)으로 **보이는 그대로 받아쓴다.** 거친 손글씨는
이쪽이 전용 OCR보다 나을 때가 많다. 단 **복사기처럼** 시켜야 한다 — 그냥 두면 오타를 고치고
반쯤 쓴 말을 완성해서 **원자료를 조용히 지어낸다**(규칙 2 위반):
- 시키실 말: *"보이는 글자를 그대로 옮겨라. 맞춤법·띄어쓰기 **고치지 마라**. 못 읽는 글자는
`[판독불가]` 로 두고, 빈칸은 빈칸으로, 비문은 비문대로."*
- 결과도 똑같이 `.txt` 로 남긴다 — 그래야 뒤의 검사·검수가 똑같이 걸린다.
- 비전이 읽은 이름·학번은 **독립된 세 번째 근거가 아니다**(기대한 대로 읽어 버린다).
③에서 대조할 때 명렬표와 자리 순서를 더 무겁게 잡는다.
- 한 반 규모면 이 방법이 편하지만, 대량·여러 장이면 토큰·속도 때문에 전용 OCR이 낫다.
- 셋 다 **이후는 완전히 같은 길로 합류한다.**
글자가 깨진 곳은 이때 **문맥으로 바로 읽어 준다**(규칙 2 — 복원까지만, 보태지 않는다).
디지털 텍스트면 이 작업은 사실상 없다.
## ③ 누구 글인지 맞추기
**`references/map_pages.py` 를 쓴다. 새로 짜지 마라** — 순진하게 짜면 조용히 틀린다(→ why.md).
```bash
# 🚩 `references/…` 는 스킬 폴더 안에만 있다. setup.sh 는 marking-tool/ 만 작업폴더의 tool/ 로
# 복사하므로, 작업폴더에서 상대 경로로 부르면 "그런 파일 없음"으로 죽는다. 전 경로로 쓴다.
SRP=<스킬경로>
cp $SRP/references/mapping-config.example.json <작업폴더>/mapping-config.json # 활동지 형태를 채운다
python3 $SRP/references/map_pages.py --root <작업폴더>
```
- 활동지 칸 구성·인쇄된 양식 문구·헤더 라벨은 과제마다 다르므로 **설정 파일에 둔다.**
특히 `boilerplate`(인쇄 문구)를 비우면 **백지가 정상으로 보인다**(→ why.md '백지 게이트').
- 결과: `out/mapping_review.md`(선생님 확인용) + `out/mapping_reconciled.csv`(다음 단계 입력).
- ⚠️·❓·🚩·❌ 는 **선생님이 풀어 주신 뒤에** 다음으로 간다.
## ④~⑧ 화면부터 검수 엑셀까지
```bash
# 한 번만 — 도구 복사·채울 파일 만들기·학생 목록 조립
bash <스킬경로>/references/setup.sh <작업폴더>
cd <작업폴더>
# 1) 채우기: tool/render_contract.md(예시 칸 필수) · draft-rules.json · sections.json
# 2) 활동 맥락을 인터뷰 2번(과제 지시문)에서 **미리** 넣어 둔다 — 화면 입력만 믿지 마라
cat > out/marks/_context.json <<'JSON'
{"context": "<한 줄로 줄인 활동 맥락>",
"competency_examples": ["<이 과제에서 나올 법한 역량 한 줄>", "<다른 결의 역량 한 줄>"]}
JSON
# 3) 화면 (포트가 겹치면 PORT= 로 옮긴다 — 다른 과목이 7333·7334를 쓰고 있을 수 있다)
PORT=7335 node tool/server.mjs
```
🔑 **역량 예시는 네가 지어낸 일반론이면 안 된다.** 인터뷰 5번(이 과제로 진짜 보려던 것)과
8번(학생마다 갈리는 지점)의 답을 **선생님 말 그대로** 한 줄짜리 역량 문장으로 옮긴다.
과목 이름이나 교과 일반론("역사적 사고력")이 아니라, **이 과제에서만 나올 수 있는 문장**이라야
칸을 보자마자 "아 이런 걸 적는 거구나"가 된다. 못 뽑겠으면 **비워 둔다** — 엉뚱한 예시는
선생님 답을 그쪽으로 끌고 가므로 없느니만 못하다.
📏 **첫 번째 예시는 한글 20자 안팎으로 짧게.** 그게 칸 안에 그대로 뜨는데, 칸이 좁아
길면 문장 중간에서 잘린다(실측: 50자 → "…어떻게 다르" 에서 끊김). 둘째부터는 길어도 된다 —
고르는 목록에만 들어가고 잘리지 않는다.
그다음 선생님이 형광펜으로 칠하고 학생마다 **[마킹 끝]** 을 켠다.
다 하신 뒤 한 번 말씀하시면 그때 쓴다:
```bash
python3 tool/render_now.py # 상태표 + 새로/다시 쓸 사람만 배치 준비
# → 찍히는 Workflow 한 줄을 에이전트가 실행
python3 tool/gate.py ; python3 tool/make_review_xlsx.py
```
🔑 **여러 번 나눠 불러도 안전하다.** `render_now.py` 가 학생을 이렇게 가른다 —
`✅ 확정` · `⏸ 보류` · `✔ 이미 씀`(건드리지 않음) / `📝 처음 씀` · `🔁 다시 씀`(이번에 씀) /
`⬜ 마킹 안 끝남` · `⛔ 원문 없음`(대상 아님). **이미 쓴 사람을 다시 쓰지 않는다.**
`--opus` 는 물린 것을 다시 쓸 때, `--all` 은 확정·보류를 뺀 전원을 강제로 다시 쓸 때.
<!-- 내부 — 규칙 10. 아래는 네가 같은 걸 다시 만들지 않도록 남긴 기록이다.
선생님께 옮기지 마라. "예전엔 자동이었다" 는 말은 지금 도구가 모자라 보이게 만들 뿐이다. -->
> 🚫 **예전 방식(실시간 감시)은 걷어냈다.** `watch.sh` 가 [초안 요청]을 지켜보다 자동으로
> 이어받는 구조였는데, ① 반려로 대기열이 다시 차도 안쪽 루프에 갇혀 못 물어오고
> ② 화면 폴링이 '요청 켜진 학생이 있을 때만' 돌아서, 체크를 껐다 켜는 사이 떨어진 초안이
> **지워진 것처럼 보였다.** 둘 다 실측 사고다(2026-08-03).
**표시한 것만 쓴다.** 형광펜이 **하나라도** 있으면 그 대목만으로 쓰고 **학생 글 전체는
입력에 넣지 않는다.** 0개일 때만 학생 글을 읽고 AI가 직접 고른다. 섞으면 "표시한 것만
쓰기"가 조용히 새므로, 판정은 오직 **표시 개수 0인가 아닌가**로만 한다.
도달 수준(상/중/하)도 정하시면 그 범위 안에서 쓰고, 안 정하시면 재료 두께로 추정한다.
🚨 **작성 호출에 `model` 을 반드시 명시한다.** 안 적으면 세션 모델을 상속해 과금이 배로
튄다(실측 2.7배 → why.md). `batch_render_sonnet.js` 는 `sonnet` 을 명시해 두었다.
🚨 **렌더 입력(학생 글)을 에이전트가 읽지 마라.** 읽는 순간 컨텍스트에 통째로 얹힌다
(→ why.md '워크플로 args'). `build_run_batch.py` 가 `render_args.py --stdout` 으로 받아 배치
스크립트에 **직접 주입**하므로 **중간 파일이 아예 안 생긴다** — 열 파일이 없는 게 정상이다.
에이전트는 인원·바이트만 받는다. (`render_args.py` 를 손으로 따로 돌리면 그때는
`out/render_args.json` 이 만들어진다. 그 파일도 열지 마라.)
🔒 `out/_run_batch.js` 에는 학생 글이 박혀 있다. **커밋 금지.**
### 검사와 검수 엑셀
```bash
python3 tool/gate.py # 자동 검사 (통과=0 / 걸림=1)
python3 tool/make_review_xlsx.py # → out/검수.xlsx
```
`gate.py` 가 보는 것(전부 답이 딱 떨어지는 것만): 길이 · 못 쓰는 말 · 점수/등급 ·
가운뎃점과 특수기호 · `[판독불가]` 잔존 · 줄바꿈/그림문자/안 보이는 문자 · 띄어쓰기 ·
문장 끝맺음 · 학번 형식 · 같은 반·번호 겹침.
경고(안 고쳐도 됨): 짧음 · 퍼센트 · 조심할 말.
**`out/검수.xlsx` 가 이 파이프라인의 결과물이자 유일한 검수 자리다.**
`학번 | 이름 | 판정 | 왜 다시 쓰나요 | 세특 | 선생님이 표시한 대목 | 선생님이 정하신 것 | 확인할 것`
앞 네 칸은 틀고정 안에 있어 오른쪽을 읽는 동안에도 계속 보인다. **`판정` 칸은 고르는 칸**
(통과 / 재작성 / 보류)이고, 비워 두면 "아직 안 정하심"이라 아무것도 건드리지 않는다.
`보류` 는 **읽었지만 아직 못 정한 것** — 빈칸(안 읽음)과 구분하려고 둔다. 화면에서 보류를
누르는 자리를 없앴으므로 **이 칸이 보류를 정할 수 있는 유일한 곳**이다.
적으신 판정은 이렇게 되먹인다:
```bash
python3 tool/ingest_review_xlsx.py # 미리보기
python3 tool/ingest_review_xlsx.py --write # 반영 → 그다음 render_now.py --opus
```
같은 본문·같은 사유는 두 번 쌓이지 않는다(엑셀을 두 번 되먹여도 안전하다).
> 화면에는 검수 자리를 두지 않는다. 그 화면은 원문을 싣지 않는데 검수의 정의는
> "나온 문장이 그 재료에서 왔는가"라, 재료 없이 판정하게 된다. 사람 관문이 둘로 갈리면
> **정보가 적은 쪽이 앞에 서게 된다**(2026-08-03 결정).
세특 바로 옆에 **선생님이 칠하신 대목과 그때 쓰신 '왜'** 가 붙는다. 기계가 문자열을
맞춰보는 대신 선생님이 눈으로 보시게 한 것이다 — 기계는 뜻이 거꾸로 쓰인 것을 못 잡지만
사람은 바로 잡는다(→ why.md). '확인할 것' 칸에는 검사 결과, AI가 그렇게 쓴 이유,
못 쓴 것과 그 까닭, 책 인용이 있으면 사실 확인 요청이 들어간다.
## ⑨ 나이스에 넣기
나이스에서 내려받은 과목세특 엑셀이 있으면 세특 칸에 결정론적으로 써넣는다.
그 파일은 그대로 다시 올릴 수 있는 공식 양식이라 붙여넣기가 필요 없다.
```bash
python3 tool/gate.py --source <확정.csv> # ① 내용 검사
python3 <스킬경로>/references/neis_writeback.py \
--source <확정.csv> --targets "<…_과목세특_*.xlsx>" [--write] # ② 칸 대조 → 기입
```
- **(반, 번호) + 성명이 둘 다 맞을 때만** 쓴다. 이름이 다르면 절대 안 쓰고 표시만 한다.
- 세특 칸에 **다른 내용이 이미 있으면 전체 중단**한다. 선생님이 손보신 최신본을 덮어쓰면
안 된다. 검토 후 `--on-conflict skip|overwrite` 로 명시한다.
- 쓰기 전 전량 백업하고, 쓴 뒤 모든 칸을 다시 읽어 대조한다.
- 소스 CSV = `학번,이름,세특`. 학번 5자리를 `10401 → 4반 1번` 으로 읽는다.
- 🚩 **엉뚱한 파일을 줘도 중단이 아니라 "0건 기입"으로 조용히 끝난다.** `--write` 전에
"이중키 매칭 예정" 숫자가 인원과 같은지 눈으로 확인할 것.
- 🚩 이 양식의 세특 칸은 **과목 1개분**이다. 1·2로 나뉜 공통과목(예: 한국사)은 두 과목 **합산**
500자 캡이므로 양쪽 양식을 합쳐 관리한다.
- **여기까지도 최종본이 아니다** — 나이스에 올리기 전 선생님이 한 번 더 보신다(규칙 6).
---
## 나이스 글자 수
한글·한자·전각 = 3바이트, 영문·숫자·공백·반각부호 = 1바이트, **엔터 = 1바이트**
(기재요령 2026 고등판 p.214 각주). 선택과목 = 과목당 500자(1,500바이트).
**1·2로 나뉜 공통과목(예: 한국사)은 두 과목을 합쳐 500자**다 — 과목마다 500자가 아니다.
**추정하지 말고 `gate.py` 가 계산한 값을 쓴다.** 사람에게 보일 때는 '한글 약 N자'를 같이 적는다.
## 세특에 못 쓰는 것
전체·출처는 `references/giwan-2026-grounding.md` §5·§6.
**어떤 항목에도 불가(p.24~25):** 공인어학시험(TOEIC·TOEFL·TEPS·HSK·JLPT·한자검정 등) /
교내외 대회 참여·성적·수상(대회명 우회 불가) / 교외상·표창장 / 인증시험 / 모의고사·전국연합
학력평가 성적 및 관련 교내 수상 / 논문 투고·발표 / 도서출간 / 특허 등 지식재산권 / 해외활동
실적 / 부모의 사회·경제적 지위 암시 / 장학생·장학금 / 특정 대학·기관·상호·강사명 / 자격증 명칭
**세특에 특히(p.110):** K-MOOC·MOOC·KOCW / 방과후학교 활동 / 연구보고서(소논문)
🚨 **학생 본인이 인용한 자료의 출처는 금지 대상이 아니다.** "○○학회 논문을 읽고"는 정상이고
평가 관점의 핵심일 때가 많다. 금지되는 건 **학생 본인의** 투고·발표·출간 실적이다.
`draft-rules.json` 에 맨낱말(`논문`·`학회`·`출간`)을 넣으면 헛걸림이 쏟아진다.
🚨 **다른 학생 실명 금지.** 학생이 활동지에 반 친구 실명을 썼더라도 세특 본문엔 **역할명**
으로 바꾼다(예: "○○" → "백제 병사"). 대상 학생 본인 이름만 예외.
🚨 **학생이 지어낸 가상 인물명(갑돌·돌쇠 등)도 빼고 역할어로.** 이름만 지우고 문장 구조·의미는
유지한다("유민 갑돌과 민중 돌쇠" → "유민과 민중", 역할어가 없으면 "두 유민의 대화"처럼 최소 삽입).
실존 역사 인물·동음 일반명사는 그대로 두고, 실존/조어가 애매하면 지우지 말고 표시해 교사 확인으로 넘긴다.
탐지는 LLM이 하고(조어는 정규식 열거 불가), 결정론 검사는 잔존·과편집 검증에만 쓴다. (2026-07-14 한국사 배치 사후 패스에서 적발)
---
## 더 깊이 볼 때
기본 흐름은 위가 전부다. 아래는 **큰 배치에서 필요할 때만** 꺼낸다(기본은 쓰지 않는다).
| 도구 | 무엇 |
|---|---|
| `references/deep/ledger_verify.py` | 표시한 대목이 학생 글에 실재하는지 기계 대조(3계층) |
| `references/deep/verify_anchors.py` | 세특에 나온 고유명·수치가 학생 글에 정박했는지 |
| `references/deep/sentence_metrics.py` | 문장이 너무 길고 늘어지는지 표면 신호 |
| `references/deep/make_review_table.py` | 문장 옆에 근거를 붙인 별도 검토 표(검수 엑셀로 대체됨) |
| `references/verify.py` | 예전 종합 검사기 — `gate.py` 가 대체했다. 개별성(유사도) 검사가 필요할 때만 |
**도구를 고칠 때만 여는 명세**(평소엔 열지 않는다 — 위 흐름만으로 굴러간다):
| 문서 | 무엇 |
|---|---|
| `references/marking-mode.md` | 표시 기록의 데이터 형식, `level` 별 도달 진술 허가 범위, 요청→초안→판정 루프 |
| `references/neis-byte-rule.md` | 나이스 글자 수 규칙의 출처와 계산 근거 |
| `references/why.md` | 설계 근거와 사고 기록 |
| `PROVENANCE.md` | 전체 지도(근거 원천 → 단계 → 파일) |
🚨 **위 문서들을 통째로 읽지 마라.** 여는 순간 이 스킬을 다이어트한 의미가 없어진다.
**열기 전에 "이 파일에서 내가 쓸 게 몇 줄인가"를 먼저 물어라.** 답이 "몇 줄"이면 `grep -n -A12`.
같은 원칙이 다른 스킬·라이브러리 문서에도 적용된다(가격 한 줄 때문에 30K 스킬을 통째로 읽지 마라).
## 기억할 것
- 한 번에 한 과목을 처리한다. 여러 과목은 인터뷰 결과를 갈아끼워 반복한다.
- 기재요령은 학년도별로 개정된다. 인터뷰 1번 답에 기준 학년도를 적어 둔다(예: 2026학년도).
- `tool/` 을 고쳤으면 회귀 검사를 돌린다: `node tool/test_mark_ui.mjs && python3 tool/test_pending.py`.
화면 문구를 바꿀 때 깨지는 지점이 있다 → why.md '화면 문구를 바꿀 때'.