라이프스타일
버그 수정의 전체 과정
디버깅은 재현 가능한 증상에서 시작해 근거로 원인을 좁히고 수정 결과를 검증합니다. 입력, 단계, 기대와 실제 결과를 전달하세요.
읽는 데 약 14분 · 실습 25 분

이 글의 목차
Codex 학습 목차로 돌아가기Codex 학습 센터: 전체 튜토리얼 목차설치와 첫 작업부터 MD 지침과 고급 연동까지 60개 강의, 열 개 단원을 계획합니다. 수준, 환경, 목표, 명령으로 다음 글을 찾고 미게시 항목의 상태를 확인할 수 있습니다.전체 글 읽기
목표와 준비
이 단락의 학습 자료: 코드 이해기존 코드베이스 이해읽기 흐름으로 진입점, 데이터 흐름, 테스트를 찾아 파일 근거가 있는 프로젝트 지도를 만듭니다.전체 글 읽기
1단계: 결함 버전과 재현 절차 고정
broken 다섯 파일을 새 codex-bug-lab에 복사하고 원본을 남깁니다. Completed 조건이 반대이며 start의 미구현과 다릅니다. Get-Location/pwd로 위치를 확인하고 2통과1실패를 관찰합니다.
node --test core.test.mjs
로컬 미리 보기는 Windows에서 py -m http.server 4173 --bind 127.0.0.1, macOS/Linux에서 python3 -m http.server 4173 --bind 127.0.0.1을 실행합니다. URL을 열고 보존할 가상 데이터가 있으면 먼저 기록하세요. Reset practice data를 사용하고 All tasks에서 빈 목록을 확인한 뒤 Read, Build 순서로 추가하고 Read만 완료한 다음 Completed를 선택합니다. 기대값은 Read이고 결함 버전의 실제값은 Build입니다. 이 순서를 기록하세요. 데이터 초기화는 소스 파일을 복원하지 않습니다.
환경/시작/조작/기대/실제/증거를 적고 먼저 캐시 원인으로 단정하지 않습니다. 날짜/테스트는 관찰로 채웁니다. 화면이 다르면 실습/경로를 확인하고 글의 기대를 자신의 실측으로 삼지 않습니다.
# Bug: Completed shows unfinished tasks
Environment/date: fill from this run
Fixture: broken copied to codex-bug-lab
Steps: reset practice data; add Read and Build; complete Read; select Completed.
Expected: Read only.
Observed: Build only, if reproduced.
Baseline: node --test core.test.mjs; fill actual result.
Scope: keep UI, storage format, ordering and tests unchanged.
Root cause: not confirmed yet.
Unperformed checks: list explicitly.
2단계: 화면 없는 최소 재현
다음 repro.mjs를 루트에 추가합니다. 완료/미완료를 직접 전달해 저장/DOM/캐시/네트워크를 거치지 않습니다. 다른 터미널에서 node repro.mjs를 실행하면 b를 표시하고 a 불일치로 0이 아닌 종료가 결함 증거입니다.
import assert from "node:assert/strict";
import { visibleTasks } from "./core.mjs";
const tasks = [
{ id: "a", title: "Read", completed: true },
{ id: "b", title: "Build", completed: false },
];
const actual = visibleTasks(tasks, "completed").map((task) => task.id);
console.log("Completed IDs:", JSON.stringify(actual));
assert.deepEqual(actual, ["a"]);
console.log("Reproduction passed.");
node repro.mjs
브라우저 없이 틀리므로 이 결함 재현에 캐시/버튼은 필요 없습니다. 전체 UI 정상 증명은 아니지만 Completed부터 조사할 근거입니다. 미완료를 고르는 이유를 설명하게 하고 우연한 새로 고침 성공을 원인 발견으로 보지 않습니다.
동작 실패와 환경 실패 구분
node repro.mjs가 ERR_MODULE_NOT_FOUND를 표시하면 Completed 검증까지 도달하지 못한 상태입니다. 현재 폴더와 core.mjs 이름을 확인하세요. SyntaxError라면 코드를 빠짐없이 붙여 넣었는지 확인합니다. 프로그램이 로드되고 b를 출력한 뒤 a를 기대하는 검증에서 실패해야 이 결함이 재현된 것입니다. 첫 실행부터 통과해도 직접 고쳤다는 뜻은 아니며 expected를 복사했을 수 있습니다. 색이나 ‘실패’만 적지 말고 명령, 종료 코드, 실제 출력, 복사본 위치를 함께 남깁니다.
3단계: 최소 수정과 원인 설명 요청
데스크톱에서는 codex-bug-lab Codex 작업을 만들고 CLI에서는 해당 폴더를 확인한 뒤 codex를 실행합니다. 그다음 아래 제한 요청을 보내 기존 테스트와 repro.mjs를 고정합니다. 수정 뒤 오래된 결함 주석 한 줄은 제거해도 되지만 다른 함수 정리, UI 또는 프레임워크 변경은 하지 않습니다. 실패를 안 봤으면 먼저 확인하게 합니다.
Fix the reproduced Completed-filter bug in this codex-bug-lab.
First read core.mjs, core.test.mjs and repro.mjs. Run node repro.mjs and node --test core.test.mjs to confirm the current failure.
Explain the predicate error using the actual a/b IDs. Modify only the completed predicate in core.mjs and remove its obsolete deliberate-bug comment. Do not change tests, repro.mjs, active behavior, storage or UI.
Rerun both commands, inspect the final diff and report actual results. Browser checks must be marked NOT RUN unless actually performed. Do not publish or deploy.
Completed가 Active와 같은 !task.completed를 쓰는 것이 원인입니다. 다음 줄만 바꾸고 Active의 !는 둡니다. 표시 이름 교환은 repro가 실패해 겉모습 변경과 동작 수정을 구분합니다.
if (filter === "completed") return tasks.filter((task) => task.completed);
4단계: 같은 증거로 회귀 검증
수정 후 repro는 ["a"]와 성공 문구/종료0, 기존3테스트 통과입니다. 같은 화면 순서로 Completed Read, Active Build, All 둘 다를 확인합니다. 같은 입력으로 원래 결함 해소를 먼저 증명하고 빈 목록/완료 해제를 추가합니다.
| 증거 | 수정 전 | 수정 후 |
|---|---|---|
| 최소 재현 | b, assertion 실패 | a, 종료0 |
| 기존 테스트 | 2통과1실패 | 3통과0실패 |
| Completed 화면 | Build | Read |
| Active/All | 실제 결과 기록 | Build/둘 다 유지 |
| 미실행 | 명시 | 자동으로 통과 처리하지 않음 |
차이에서 addTask/decodeTasks/기댓값 불변을 확인합니다. 수정 주장뿐이면 명령/종료/실패 요약을 요청하고 실행 불가는 이유를 남깁니다. 명령 성공은 화면 확인 대신이 아니며 환경/URL과 함께 수행합니다.
완료 취소와 빈 목록 추가 확인
원래 재현이 통과한 뒤 아래 내용으로 regression.mjs를 만들고 node regression.mjs를 실행합니다. Completed의 a를 확인하고 a의 완료를 취소한 다음 Completed는 빈 목록, Active는 a/b인지 검증합니다. 원래 입력이 바뀌지 않았는지와 세 필터의 빈 목록도 확인합니다. 예상 결과는 Regression passed와 종료 코드 0입니다. 독립 검증 프로그램이므로 node --test core.test.mjs의 테스트 개수가 자동으로 늘지는 않습니다.
import assert from "node:assert/strict";
import { toggleTask, visibleTasks } from "./core.mjs";
const tasks = Object.freeze([
Object.freeze({ id: "a", title: "Read", completed: true }),
Object.freeze({ id: "b", title: "Build", completed: false }),
]);
const ids = (items, filter) => visibleTasks(items, filter).map((task) => task.id);
assert.deepEqual(ids(tasks, "completed"), ["a"]);
const changed = toggleTask(tasks, "a");
assert.deepEqual(ids(changed, "completed"), []);
assert.deepEqual(ids(changed, "active"), ["a", "b"]);
assert.deepEqual(ids(changed, "all"), ["a", "b"]);
assert.deepEqual(tasks.map((task) => task.completed), [true, false]);
for (const filter of ["all", "active", "completed"]) {
assert.deepEqual(ids(Object.freeze([]), filter), []);
}
console.log("Regression passed.");
node regression.mjs
원래 broken/core.mjs로 되돌리는 연습에서도 regression.mjs는 남깁니다. repro.mjs의 b와 일치하게 다시 0이 아닌 종료 코드로 실패해야 합니다. 테스트, 라벨, 저장 처리까지 바꿔 통과시켰다면 저장한 원본으로 돌아가 단일 수정부터 반복하고 인계 기록맥락과 작업 인계긴 작업에는 결정과 증거를 남깁니다. README는 사용법, 설계 문서는 이유, 인계는 진행 상황, AGENTS.md는 지속할 규칙으로 구분합니다.전체 글 읽기에 폐기한 가설을 남깁니다. 완전한 회귀 검증에는 실제 화면과 새로고침 확인도 필요하며 하지 않은 항목은 미실행으로 둡니다.
디버깅 습관, 복원과 전달
검증 가능한 가설을 하나씩 바꾸고 시도/결과를 남겨 무효 수정 반복을 막습니다. 다른 원인 증거면 범위를 다시 좁히고 한 줄 실습에 억지로 맞추지 않습니다. 실제 타이밍/인증/네트워크 차이도 있으며 개인 데이터를 제거해 재현을 전달합니다.
보고/최소 재현/원인/차이/회귀 표를 전달합니다. 반복은 자신의 미리 보기 종료 후 broken/core.mjs만 복원하고 repro와 기존2통과1실패를 봅니다. 자세한 예는 기능 검수할 일 필터 구현start에서 Active/Completed 필터를 구현하고 데이터 형식과 정상 및 경계 사례를 검증합니다.전체 글 읽기로 갑니다. 그림1재현,2원인수정,3회귀이며 참고 검증과 각자의 Codex 실행을 구분합니다.
Codex 학습 목차로 돌아가기Codex 학습 센터: 전체 튜토리얼 목차설치와 첫 작업부터 MD 지침과 고급 연동까지 60개 강의, 열 개 단원을 계획합니다. 수준, 환경, 목표, 명령으로 다음 글을 찾고 미게시 항목의 상태를 확인할 수 있습니다.전체 글 읽기
자세한 설명 보기
Reproduce to Fix to Regression
같은 주제의 글
라이프스타일
Codex 학습 센터: 전체 튜토리얼 목차
설치와 첫 작업부터 MD 지침과 고급 연동까지 60개 강의, 열 개 단원을 계획합니다. 수준, 환경, 목표, 명령으로 다음 글을 찾고 미게시 항목의 상태를 확인할 수 있습니다.
라이프스타일
Worktree와 작업 격리
Worktree는 하나의 Git 저장소에 다른 브랜치의 작업 폴더를 만듭니다. 파일이 분리되어도 DB, 포트와 외부 서비스는 공유될 수 있습니다.
라이프스타일
실습: 작은 웹사이트 만들기
brief.md에서 Small Steps 할 일 사이트를 계획하고 추가·완료·삭제·필터·로컬 저장을 구현합니다. HTML·CSS·데이터 함수·화면 이벤트·시험을 분리하고 Node와 브라우저로 검증한 뒤 재시작·복원 인계 기록을 남깁니다.
라이프스타일
사용량과 효율: 재작업 줄이기
조건, 모델 선택, 시간, 결과를 기록해 불필요한 재시도와 과도한 문맥을 줄입니다.
이 글을 인용한 글
최신 여행 소식·가이드

가이드도쿄
도쿄 어디에 묵을까? 신주쿠·우에노·도쿄역·시부야·아사쿠사·이케부쿠로·긴자 일곱 지역 비교: 공항 교통, 숙박세, 짐 배송까지
도쿄 어디에 묵을까? 신주쿠, 우에노, 도쿄역, 시부야, 아사쿠사, 이케부쿠로, 긴자 일곱 지역을 같은 기준으로 비교한다. 나리타·하네다 공항에서 오는 방법, 교통 노선, 주변의 볼거리, 동네 분위기, 적합한 여행자를 비교표와 야마노테선 안내도로 살펴보고, 2026년 9월에 확인한 도쿄도 숙박세(2027년 4월부터 3%)와 공항 택배로 짐을 보내는 규정도 정리했다.
- 예산
- 호텔

가이드도쿄
도쿄 교통패스 선택법: Suica/Welcome Suica, Tokyo Subway Ticket, JR Pass는 살 만할까?
도쿄를 처음 여행한다면 먼저 1인당 IC 카드 한 장으로 탈 때마다 결제한다(Welcome Suica는 보증금이 없고 28일간 유효). 하루에 지하철을 4번 이상 타면 2,000엔짜리 Tokyo Subway Ticket 72시간권을 추가하고, 간사이에 가지 않고 도쿄만 여행한다면 JR Pass는 반드시 손해다. TOURIST PASMO, iPhone의 Suica, 도쿄 Metro 하루권의 이용 가능·불가 범위를 결정도로 비교한다. 가격은 2026년 9월 확인.
- 교통
- 예산

가이드도쿄
도쿄 디즈니랜드·디즈니씨 가이드: 티켓 가격, 판타지 스프링스 Fantasy Springs, 디즈니 프리미어 액세스 DPA와 스탠바이 패스 이용법, 첫 방문에는 어느 파크가 좋을까
도쿄 디즈니 하루짜리 패스포트는 변동 가격제로, 2026년 9월에는 평일 대부분이 9,900엔, 주말이 10,900엔이다. 공식 홈페이지에서 매일 14:00에 두 달 뒤 같은 날짜의 티켓을 판매한다. 무료 프라이오리티 패스는 공식 서비스 목록에서 빠져 대기 시간을 줄이는 방법은 유료 디즈니 프리미어 액세스(한 사람당 한 번 1,000~3,500엔)뿐이다. 운영 시간, 25주년 행사, 스탠바이 패스, 엔트리 리퀘스트, 판타지 스프링스 이용법, 첫 방문 때 디즈니랜드와 디즈니씨 중 어디를 고를지도 담았다. 2026년 9월 공식 홈페이지에서 확인했다.
- 추천 일정
- 가족 여행