화면 모드
교안 실습 검증
교안에 넣은 실습은 학기 중 조용히 망가진다. 도구 버전을 올렸는데 명령이 그대로 남아 있고, 강사의 컴퓨터에서는 되는데 수강생 컴퓨터에서는 다른 셸에서 멈춘다. 에이전트에 버전 기준과 재현 스크립트를 맡겨 두면, 같은 검사를 매주 같은 조건으로 돌릴 수 있다.
기준일: 2026-09-30.
어떤 문제를 풀었나
수업이 한 번 진행되면 실습은 누적된다. 슬라이드 한 장이 바뀌면 명령 하나가 바뀌고, 패키지 하나가 올라가면 출력 형식이 바뀐다. 확인하지 않으면 수강생이 처음 만난 오류를 수업의 문제가 아니라 자신의 환경 문제로 받는다.
여기서는 두 가지를 한 흐름으로 묶는다.
- 교안에 넣은 실습이 최신 버전의 도구·런타임에서, Windows와 macOS 모두에서 문제없이 도는지 확인한다.
- 수강생이 제출한 실행 결과에서 같은 정보를 읽어 피드백에 쓴다. 이 부분은 보조이며, 검증 자동화를 끝냈다고 수업 전체가 자동으로 돌아가는 것은 아니다.
반복해서 필요한 작업은 세 가지다. 새 버전으로 명령을 다시 실행하고 두 운영체제에서 같은 결과인지 확인한다. 실패하면 어느 단계에서 났는지 기록하고 버전이 달라진 것을 교안 문구에 반영한다. 수강생이 돌린 같은 스크립트의 결과는 실패가 많은 지점을 찾는 데 쓴다.
환경 기준과 실행 절차는 사람이 정하고, 반복 실행과 결과 정리는 에이전트에 맡긴다. 처음에는 수업에서 실제로 쓰는 명령이 들어 있는 폴더 하나에서 통과시키는 것부터 시작한다.
무엇을 어떻게 연결하나
검증 대상은 교안의 실습 폴더이고, 그 바깥에는 환경 기준과 실행 환경, 결과 확인이 놓인다. 아래 Mermaid 그림은 한 번의 검증이 끝날 때까지의 흐름이다.
운영체제별 검증은 사람이 두 컴퓨터를 번갈아 켜는 대신 매트릭스 실행으로 대신한다. 로컬 실행은 기준을 잡는 용도로만 쓴다.
| 구성 요소 | 역할 | 먼저 확인할 내용 |
|---|---|---|
| 교안 실습 폴더 | 검증 대상 | 교안의 명령이 그대로 들어 있는가 |
| 버전 기준 파일 | 무엇을 설치할지 정한다 | 기준일과 함께 적었는가 |
| 잠금 파일 | 의존성 버전을 고정한다 | 커밋 대상에 포함했는가 |
| 재현 스크립트 | 실행 순서를 한 곳에 모은다 | 운영체제와 무관하게 도는가 |
| 매트릭스 실행 | 여러 운영체제에서 같은 명령을 돌린다 | 라벨과 기본 셸을 아는가 |
| 결과 리포트 | 사람이 읽는 근거 | 실패 단계와 로그 위치가 남는가 |
버전 기준은 저장소에 남기고, 교안에는 사람이 읽을 한 줄로 적는다. 두 곳이 어긋나면 무엇을 기준으로 확인했는지 애매해진다.
기준 고정
검증은 버전이 고정된 상태에서만 결과를 비교할 수 있다. 교안과 무관한 폴더에서 명령을 실행하지 말고, 수업에서 배포하는 실습 폴더를 그대로 검증 대상으로 삼는다.
Node.js와 패키지 매니저 버전은 파일로 남긴다. 이 저장소처럼 packageManager와 engines를 함께 쓰는 편이 읽기 쉽다.
json
{
"name": "abc-exercise",
"private": true,
"packageManager": "pnpm@10.34.6",
"engines": { "node": ">=24" },
"scripts": { "verify": "node scripts/verify.mjs" }
}engines는 Node.js 버전을, packageManager는 패키지 매니저 버전을 고정한다. 필요한 Node.js 버전 목록은 Node.js 다운로드 안내에서 확인할 수 있고, 필드 설명은 package.json 문서에 정리되어 있다.
버전 하나만 적으면 무엇을 기준으로 검사했는지 알 수 없다. 최소 지원 버전과 권장 버전을 나누어 적고, 어느 쪽을 돌렸는지 로그에 남긴다.
설치 단계에서 버전이 흔들리면 뒤의 결과도 비교할 수 없다. 잠금 파일을 커밋하고 설치 시 잠금을 그대로 쓴다.
sh
pnpm install --frozen-lockfile이 옵션의 동작과 관련 설정은 pnpm 설정 문서에서 확인할 수 있다. 기준을 올릴 때는 의존성을 먼저 올린 뒤 기준 파일과 교안 문구를 함께 고친다.
수업마다 명령이 조금씩 달라지면 무엇이 바뀌었는지 알기 어렵다. 설치부터 검사까지의 순서를 스크립트 한 개에 둔다. 셸 스크립트 대신 Node.js로 작성하면 두 운영체제에서 같은 파일을 실행할 수 있다. Windows의 기본 셸은 PowerShell이라 POSIX 명령을 그대로 옮기면 어긋나기 때문이다.
js
// scripts/verify.mjs
import { spawnSync } from 'node:child_process'
const steps = [
'node --version',
'pnpm --version',
'pnpm install --frozen-lockfile',
'pnpm lint',
'pnpm test',
'pnpm build',
]
for (const command of steps) {
console.log(`\n$ ${command}`)
const result = spawnSync(command, { stdio: 'inherit', shell: true })
if (result.status !== 0) process.exit(result.status ?? 1)
}실행은 pnpm verify 한 줄이다. 실패한 단계에서 즉시 종료하므로 마지막 오류 메시지만 읽어도 어느 단계에서 끝났는지 알 수 있다. 항목별로 따로 확인하고 싶을 때는 pnpm lint처럼 각 단계를 그대로 실행한다.
쓸 만한 요청 만들기
기준 확인용 첫 요청
새 폴더를 받은 에이전트에게 처음부터 고치게 하지 않는다. 무엇이 정해져 있고 무엇이 빠졌는지부터 확인한다.
text
exercises/ 폴더의 실습 스크립트를 읽고 검증 절차를 점검해 줘.
대상: exercises/
아직 파일을 수정하지 마.
다음 네 가지를 표로 정리해 줘.
- 실행에 필요한 Node.js와 패키지 매니저 버전
- 잠금 파일이 있는지, 커밋 대상에 포함됐는지
- 지금 스크립트가 실패할 수 있는 단계
- Windows와 macOS에서 결과가 달라질 수 있는 지점
파일에서 확인할 수 없는 내용은 추정하지 말고 확인 필요로 표시해 줘.표에서 비어 있는 칸이 곧 다음에 채울 항목이다.
실패 재현과 원인 좁히기
실행 결과는 그대로 두고 판단을 요구하지 않는다. 마지막 로그에서 거슬러 올라가며 멈춘 단계부터 확인한다.
text
pnpm verify를 실행하고, 마지막 오류 메시지부터 거슬러 올라가며
어느 단계에서 멈췄는지 확인해 줘.
보고할 내용:
- 멈춘 단계와 그 단계에서 실제로 실행된 명령어
- 로그에서 확인되는 원인 두 가지 후보
- 두 운영체제에서 결과가 달라질 가능성
수정은 하지 말고 보고만 해 줘.원인이 두 개로 좁혀지면 어느 쪽을 먼저 확인할지 정할 수 있다. 수정은 그다음 요청으로 따로 한다.
교안 문구만 수정
원인이 확인된 뒤 교안 문구만 고친다. 문서 전체를 다시 쓰게 하면 검증 범위가 커진다.
text
검증에서 확인된 버전 차이를 반영해 실습 안내 문장만 고쳐 줘.
대상: 실습 안내가 있는 문서와 slides 원고의 해당 부분
조건:
- 실행 명령은 바꾸지 마.
- 버전 표기와 실행 결과를 요구하는 문장만 수정해 줘.
- 최소 지원 버전과 권장 버전을 구분해 적어 줘.
- 기준일을 문서 맨 앞에 함께 적어 줘.
변경한 문장과 그 이유를 나란히 보여 줘.수강생 결과 비교 기준
제출 로그를 읽을 때는 원본을 바꾸지 않고 필요한 항목만 추출한다.
text
아래 제출 로그에서 버전, 실행 단계, 실패 지점을 표로 정리해 줘.
표 항목: 운영체제, Node.js 버전, 멈춘 단계, 오류 요약, 재현 명령
같은 항목이 없는 로그는 확인 불가로 표시해 줘.
오류 메시지에서 이름, 이메일, 토큰 값은 옮기지 마.
문제 유형별로 묶어 어떤 항목이 가장 많이 실패했는지 두 줄로 요약해 줘.실패가 몰린 항목은 설명을 보강할 위치가 된다. 표를 만든 뒤에는 사람이 판단한다.
재현에서 주간 확인까지
1. 로컬 실행 기준 잡기
먼저 강사의 컴퓨터에서 기준선을 정한다. node --version과 pnpm verify를 차례로 실행한다. 로컬에서 통과한 것을 운영체제 검사가 끝난 것으로 보지 않는다. 이 단계의 목적은 스크립트 자체에 있는 실수를 먼저 없애는 것이다.
2. 두 OS 매트릭스 실행
구성과 문법은 GitHub Actions 워크플로 문법과 매트릭스 사용 안내에서 확인할 수 있다. 러너 운영체제 표시는 GitHub 호스티드 러너 안내에 정리되어 있다.
yaml
name: verify
on:
push:
pull_request:
workflow_dispatch:
jobs:
verify:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
steps:
- uses: actions/checkout@v7
- uses: pnpm/action-setup@v6
- uses: actions/setup-node@v7
with:
node-version-file: .nvmrc
cache: pnpm
- run: pnpm install --frozen-lockfile
- run: pnpm verifyfail-fast: false는 한 운영체제에서 실패해도 나머지 결과를 끝까지 받게 한다. 한 운영체제에서만 나는 문제를 보려면 이 설정이 필요하다.
macOS와 Windows의 기본 파일 시스템은 대소문자를 구분하지 않는다. 두 운영체제만 확인하면 파일 이름 대소문자 문제가 그대로 통과할 수 있어 기본 예시에 Linux 러너도 함께 둔다.
3. 결과 근거 기록
실패한 실행에는 네 가지를 적는다.
| 기록 항목 | 예시 형태 |
|---|---|
| 운영체제와 버전 | windows-latest, macos-14 |
| 멈춘 단계 | pnpm test |
| 로그 위치 | 실행 로그 링크와 마지막 오류 줄 |
| 재현 명령 | 같은 브랜치에서 다시 돌리는 명령 |
로그 전체를 붙여 넣지 않는다. 마지막 오류와 재현 명령만 있으면 같은 검사를 다시 돌릴 수 있다. 긴 로그를 반복해서 읽게 만드는 비용은 토큰 절약 페이지에서 다룬다. 검증 방식과 완료 기준은 검증 페이지에서 다룬다.
4. 수강생 스크립트 실행
검증이 두 번 이상 안정적으로 돌면 수강생에게도 같은 명령을 맡긴다. 결과는 pnpm verify 출력 전문, 실행하지 못했을 때의 운영체제·버전·오류 메시지, 중간에 멈춘 단계와 마지막 화면 중 하나를 받는다. 버전과 실행 단계가 없으면 어디서 어긋났는지 비교할 수 없으므로 제출 안내에 node --version 출력과 마지막 오류를 함께 넣는다.
5. 반복 실패 자동 확인
같은 단계에서 같은 실패가 반복되면 실패 조건을 스크립트에 넣고, 훅이나 실행 단계에서 자동으로 확인하게 바꾼다. 기준과 명령은 저장소 문서에 남긴다. 다음 학기에 같은 검사를 다시 쓰려면 교안과 저장소 중 한쪽에만 적지 않는다. 이때 쓰는 기준과 연결은 하네스 스스로 개선하기 페이지에서 다룬다.
자주 막히는 지점과 주의점
로컬·수강생 환경 차이
버전, 셸, 경로 차이부터 확인한다. Windows의 기본 셸은 PowerShell이므로 export나 &&로 이어 붙인 명령, sed와 grep의 옵션 차이는 그대로 옮겨지지 않는다. 실행 명령은 운영체제에 맞춰 교안에서 한 번에 적는다.
줄바꿈 차이도 원인이 된다. 저장소에 .gitattributes를 두고 줄바꿈과 실행 권한을 고정하면 두 운영체제의 기본 설정 차이를 줄일 수 있다. 관련 설정은 git config 문서에서 확인할 수 있다. 패키지 매니저가 심볼릭 링크를 쓰는 경우에는 Windows 개발자 모드가 꺼져 있어 설치가 실패할 수 있으므로 설치 안내에 필요한 조건을 한 줄로 적는다. 설정 절차는 Microsoft 공식 안내에 있다.
통과 후 남는 문제
종료 코드만으로는 충분하지 않다. 로그가 비어 있거나, 스냅샷이 빈 파일이거나, "TODO"만 출력해도 명령은 성공이다. 검증 항목마다 기대 결과를 함께 적는다. 테스트는 통과 개수까지, 빌드는 산출물 파일 존재까지 확인한다. 기준은 룰에 짧게 두고, 긴 설명은 문서 페이지로 옮긴다.
매번 실행의 부담
검증을 매 커밋 시점에 돌릴 필요는 없다. 교안의 명령을 고친 직후, 버전 기준을 올린 직후, 학기 첫 수업 전 세 시점으로 좁히면 충분하다. 그 외에는 사람이 직접 돌린다. 확인하지 않은 결과가 쌓이면 판단이 오히려 늦어진다.
오래된 버전에 고정하면 수강생이 구버전을 설치해야 한다는 문제도 함께 생긴다. 최소 지원 버전과 권장 버전을 나누고, 최소 버전이 실제로 동작하는지도 따로 확인한다. 최신 버전에서만 되는 기능을 최소 버전 기준으로 안내하면 수강생이 처음부터 실패한다.
에이전트의 실패 요약
"테스트 실패"라는 한 줄만 남으면 원인을 찾기 위해 다시 실행해야 한다. 실패 단계, 마지막 오류 메시지, 재현 명령 세 가지는 그대로 남기도록 요청한다. 요약이 필요하면 그다음 단계에서 받는다. 완료 기준을 미리 정해 두면 사람이 결과를 확인하기 전에 완료로 보고하는 일을 줄일 수 있다.
수강생 로그의 개인정보
오류 메시지에는 파일 경로, 사용자 이름, 환경 변수의 값이 함께 찍힌다. 제출 로그를 옮길 때 이름, 이메일, 토큰 값은 제외하거나 가린다. 로그를 읽는 요청에 이 조건을 처음부터 넣는다. 보안 페이지의 격리 원칙을 그대로 적용하면 된다.