OpenAI Codex · Code Mode

아키텍처 결정을 lint로 쓰세요

같은 AGENTS.md 안에서, 명령이 있는 규칙은 운영체제 세 대에서 빨갛게 켜져요. 경로만 있는 그 조항은, 이름을 바꾼 뒤에도 아무도 모릅니다.

강의 목표읽고 나면 세 가지를 말할 수 있어요. 호출점 규칙 하나가 어떻게 rustc 플러그인이 되어 Linux, macOS, Windows에서 동시에 막는지. 산문으로 쓴 경로는 왜 죽는지. 등록을 빠진 특성은 왜 망라 표로 잡을 수 있는지.
먼저 해보기 · 커밋 하나가 아키텍처 검사를 지나가요
같은 규범, 변경 카드 다섯 장: 어느 층이 막는지, 그 층이 무엇을 지키려는지 보세요
이번 변경
재생을 눌러 문이 어떻게 도는지 보세요. 오른쪽 한 층을 바로 눌러 통과인지 차단인지도 볼 수 있어요.
커밋과 문대기
create_openai_url(None)호출점에 맨손 None을 썼어요. 컴파일은 되고, 독자는 정의로 뛰어가야 무엇을 다스리는지 알아요.
이 단계의 판결
손안의 변경맨손 None
부딪힌 문아직 안 켜짐
이 조항이 지키는 것문을 먼저 한 바퀴
결말대기
시작을 기다려요.
논리 궤적 · 애니메이션 각 단계가 소스의 어느 구간에 대응하는지
  1. 호출점 인자가 익명 리터럴인가lib.rs L261
  2. 주석 이름이 매개변수 이름과 같은가lib.rs L222
  3. 피호출이 workspace crate인가lib.rs L177
  4. CI가 세 플랫폼에서 동시에 도는가rust-ci.yml L174
  5. Markdown 경로가 아직 존재하는가AGENTS.md L35
  6. Feature가 망라 표에 등록되었는가lib.rs L379
  7. 개발 중 특성은 기본이 꺼져 있어야 해요tests.rs L18
재생을 눌러, 이 변경이 문 여섯 층을 지나 어디에 멈추는지 보세요.
누가 막았나
무엇을 지키나
카드를 바꾸세요빨간불이 있으면, 이름 바꾸기나 빠뜨림이 그날 빨개져요. 없으면 글자는 남고, 대상은 이미 이사했어요.
수업용 스케치: 문 층은 수업용 묶음으로, “검사가 있는 것”과 “산문만 있는 것”을 대조해요. 궤적 오른쪽 행 번호는 openai/codex 저장소 commit 4f39251a01에 대응합니다.
아이디어 1 · 국소 검사할 수 있는 결정은, 기계가 돌릴 빨간불로 쓰세요
어떤 문제를 푸는가

신입이 일을 받아요. MCP 도구 호출을 고치라는 거예요. AGENTS.md를 열고 35행의 경로를 베껴요. 파일이 없어요. 진짜 파일은 connection_manager.rs이고, 같은 디렉터리에 있어요. 문서의 mcp_ 접두 이름은, 한번 이름을 바꾼 뒤 청소하지 않은 잔여예요.

출처:AGENTS.md 32–36행;codex-rs/codex-mcp/src/connection_manager.rs 1–15행

같은 파일에서, 위치 매개변수에 /*base_url*/이 빠지면 로컬 명령이 빨개져요. Cargo.toml을 고치고 Bazel 락을 안 새로고치면 CI가 빨개져요. 35행 그 경로에는 검사기가 없어요. Markdown은 파일이 있는지를 스스로 대조하지 않아요.

아이디어는 무엇인가

먼저 API를 바꿔, 호출점 스스로 읽히게 하세요. foo(false)의 독자는 정의로 뛰어가야 이 false가 무엇을 다스리는지 알아요. API를 못 바꿀 때만 /*param_name*/을 허용해요. lint는 퇴로예요.

출처:AGENTS.md 14–20행

구현은 독립 Dylint 크레이트에 살며, rustc 한 번으로 돌아요. 타입 해석이 끝난 뒤에야 피호출의 매개변수 이름을 얻어요. 입구는 함수 호출과 메서드 호출만 보고, 매크로가 펼친 것은 바로 건너뛰어요.

검사는 이 순서로 가요.

1. 이 저장소 crate만 봐요. stdtokio는 바로 통과예요.

2. 주석은 세 곳에서 찾아요. 인자 앞 틈, 앞 64바이트, 인자 텍스트 자신.

3. 이름이 틀리면 mismatch예요. 잘못된 주석은 “주석 없음” 조항으로 다시 떨어지지 않아요.

4. 안 썼을 때, 메서드 이름이 유일한 매개변수 이름과 같으면 면제예요. 예: .enabled(false).

5. 나머지는 익명 리터럴만 막아요. None, 불리언, 숫자는 써야 하고, 문자열과 문자는 통과예요.

출처:tools/argument-comment-lint/src/lib.rs 165–180행;tools/argument-comment-lint/src/lib.rs 261–274행

호출점 맨손 None workspace? 그럴 때만 계속 유효 주석? 이름이 맞아야 해요 deny, CI 세 대가 다시 Linux / macOS / Windows 입력은 호출 하나, 출력은 병합 전 빨간불. 지키는 것은 스스로 읽히는 호출점
수업용 구조도: 매개변수 이름을 해석할 수 있는 국소 호출이어야 rustc 플러그인을 키울 가치가 있어요.

저장소 입구는 기본 Allow인 그 조항을 deny로 올려요. CI는 Linux, macOS, Windows에서 각 한 번 돌고, 한 대가 실패해도 나머지 두 대는 끝까지 가요. 사람이 macOS에서 초록이어도, Windows 대상의 매크로 전개가 None을 하나 더 내면 세 번째 기계가 여전히 막아요.

출처:.github/workflows/rust-ci.yml 164–187행

왜 오래가는가

호출점은 국소적이고, 이름은 해석할 수 있고, 오탐은 면제로 거둘 수 있어요. 언어를 바꿔도 모양은 같아요. 먼저 이름을 고치고, 못 고치면 줄 안 이름을 요구해요. TypeScript는 ESLint, Python은 ruff, 둘 다 맞아요.

아이디어 2 · 산문은 썩어요. 셀 수 있다는 것과 세고 있다는 것은 달라요
어떤 문제를 푸는가

35행과 265행은 같은 부패예요. app-server 안내서는 아직 v2.rs를 쓰고, 지금은 디렉터리 v2/이며 아래가 서른 개 넘는 파일로 갈라졌어요. 파일이 800줄에 가까우면 쪼개야 해요. 쪼갠 뒤, 안내서의 단일 파일 경로는 아무도 안 바꿨어요.

출처:AGENTS.md 260–266행

모듈 줄 수 규칙은 자주 쓰는 파일 다섯을 지목해요. 넷은 이미 800을 넘었고, 하나는 900에 붙어 있어요. chat_composer.rs는 줄로 치면 12859줄이에요. 저장소에는 줄을 세는 명령이 없어요. 줄은 셀 수 있지만 CI는 세지 않아요. 한 변경이 기계적인지는 기계가 잘 못 하니, 800줄 상한은 리뷰에서 멈춰요.

출처:AGENTS.md 49–61행;AGENTS.md 125–131행

아이디어는 무엇인가

규칙을 두 세트로 읽으세요. 한 세트는 명령이나 컴파일러가 있어, 병합 전에 빨개져요. 한 세트는 사람과 리뷰만 읽고, 놓치면 통과예요. 경로 존재는 원래 가장 쉬운 검사예요. 백틱 경로를 뽑아 저장소 루트에 존재 여부를 보면 돼요. 저장소는 안 했어요. 예산은 호출점 가독성에 썼고, 경로 존재에는 안 썼어요.

규칙을 AGENTS.md에 씀 명령이나 컴파일러? 있으면 기계로 lint, 테스트, schema job 산문만 세 플랫폼 CI, 병합 차단 사람이나 리뷰가 잡을지도 경로는 바뀌고 글자는 남음
수업용 분기 그림: 검사가 있으면 그날 빨개지고, 산문만 있으면 조용히 끊겨요.
왜 오래가는가

문서는 스스로 재검사하지 않아요. 국소 검사할 수 있는데 Markdown에만 쓰면, 이름을 바꾸거나 파일을 쪼갠 날 글자는 남고 대상은 이사해요. 최소 형태는 경로를 대조하는 스무 줄 스크립트예요. rustc 플러그인은 필요 없어요.

lint로 쓴 규칙은, 파일 이름을 바꾼 날 빨개져요.
아이디어 3 · 생명주기를 열거형 더하기 망라 표로 쓰세요
어떤 문제를 푸는가

특성 스위치가 불리언과 설명 한 편에만 기대면, 등록 누락, 개발 중 기본 켜짐, 그냥 앉아 있는 Deprecated는 바로 빨개지지 않아요.

아이디어는 무엇인가

Feature 열거형 옆에 FEATURES 표가 있어요. FeatureSpec은 식별자, 설정 키, 단계, 기본 켜짐을 한 줄에 용접해요. 표에서 짝을 못 찾으면 unreachable!예요. 열거형에 변체가 하나 늘고 표에 한 줄이 빠지면, key()까지 가서 바로 붕괴해요.

출처:codex-rs/features/src/lib.rs 41–58행;codex-rs/features/src/lib.rs 819–826행;codex-rs/features/src/lib.rs 379–384행

옆의 테스트 두 개가 기본값을 잠가요. 개발 중 특성은 기본이 꺼져 있어야 해요. 기본이 켜진 특성의 단계는 Stable 또는 Removed여야 해요. 단계는 다섯이고, 여분의 Experimental은 메뉴 이름과 공고를 달고 있어요. Deprecated에는 만료일이 없고, Deprecated 항목 셋은 여전히 켤 수 있어요. 단계는 “더는 쓰지 마”는 말할 수 있어도, “다음 버전에 지워”는 말 못 해요.

출처:codex-rs/features/src/tests.rs 17–28행;codex-rs/features/src/tests.rs 82–94행

UnderDevelopment 기본은 꺼져야 Experimental 메뉴와 공고 Stable 그때만 기본 켜짐 Deprecated Removed 입력은 열거형 더하기 표 한 줄. 출력은 등록 누락이면 붕괴. Deprecated에서 Removed까지 타이머 없음
수업용 상태도: 망라 표는 등록과 기본값을 잠그지만, 자동 삭제는 잠그지 못해요.
왜 오래가는가

망라 표 더하기 테스트 두 개는, 언어를 바꿔도 성립해요. 등록이 빠지면 붕괴하고, 기본값은 잠겨요. 자동 삭제는 못 얻고, 이 불변식 둘만 얻어요.

가로 비교 · 같은 문제의 다른 답

DSH: 모든 패키지가 모습을 보여야 하고, 비어도 설명을 해야 해요

DeepSeek Harness는 “모든 패키지는 ./invariant를 가져야 한다”를 산문과 문으로 동시에 써요. 산문은 packages/AGENTS.md에 있어요. 문은 21줄 verify-package-invariants이고, 실패하면 process.exit(1)예요. 빈 설치기는 고정 접두 No runtime invariant:를 달아야 해요. 빔은 명시적 아키텍처 결론이에요. 나중에 가변 상태를 들이면, 진짜 검사로 바꿔야 해요.

노트는 왜 빔을 허용하는지 답하고, 검사기는 빔이 반드시 설명되어야 함을 보장해요. 둘 중 하나가 빠지면 Codex 35행 그 상태로 돌아가요. 글자는 남고, 대상은 이미 이사했어요. DSH에는 foo(false)를 보는 rustc 플러그인이 없어요. Codex에는 경로 존재를 보는 망라식 패키지 문이 없어요.

출처:packages/AGENTS.md 18행;scripts/verify-package-invariants.ts 1–21행

양쪽 모두 소스 대조 완료 · 2026-08-22

Grok: 국소화할 수 있는 결정은 clippy에 바로 넣어요

Grok Build 저장소 루트에는 AGENTS.md가 없어요. 그래도 아키텍처 결정 하나를 lint로 써요. clippy.tomlcanonicalize를 금하는 이유는, Windows에서 verbatim 접두가 나와 git을 깨고 모델 컨텍스트로 새기 때문이에요. 실행 경계도 같은 파일에 있어요. 이 금지는 각 crate의 cargo clippy presubmit가 돌리고, Bazel만 타는 crate는 사람이 봐야 해요.

Codex의 매개변수 주석과 같은 종류의 판단이에요. 호출점은 국소적이고, 오탐 면은 통제할 수 있어요. Grok은 Bazel 커버가 불완전하다고 인정해요. Codex는 로컬이 현재 OS만 돈다고 인정해요. 작은 팀은 경로 존재와 21줄 verify 스크립트를 먼저 베끼는 편이, Dylint를 베끼는 것보다 싸요.

출처:clippy.toml 9–28행

양쪽 모두 소스 대조 완료 · 2026-08-22
수업 실습
01

어떤 자동 검사를 먼저 만들까요

AGENTS.md 35행과 265행은 둘 다 죽은 경로예요. 자동 검사를 하나만 먼저 만들 수 있다면, codex-rs/ 접두 경로를 볼까요, 아니면 백틱 안에 /가 있는 모든 문자열을 볼까요?

첫 번째는 app-server-protocol/src/protocol/v2.rs 같은 상대 표기를 놓쳐요. 두 번째는 명령 이름, crate 이름, URL 조각을 다치게 해요. 필터 규칙을 쓰고, 이 죽은 경로 둘을 양성 예로 쓰세요.

Takeaway: 국소 검사할 수 있는 결정은 Markdown에만 쓰지 마세요. 조항은 사람에게 무엇을 볼지 말하고, 빨간불은 사람이 안 볼 때도 켜져 있어요. 경로 존재와 망라 표는 rustc 플러그인을 키우는 것보다 싸고, 더 먼저 해야 해요.