LazyCodex
LazyCodexv4.12.1

programming

TypeScript, Rust, Python, Go에 동일하게 적용되는 엄격한 규율 — 타입 우선, TDD.

programming 스킬은 LazyCodex(LZX)가 작성하는 모든 코드 한 줄에 적용하는 타입 규율입니다. Codex가 .py, .pyi, .rs, .ts, .tsx, .mts, .cts, .go 파일이나 프로젝트 매니페스트를 건드리는 순간 자동으로 활성화됩니다. 별도 명령은 없으며, LazyCodex가 Codex에 설치하는 OmO(oh-my-openagent) 플러그인 안에 포함되어 있습니다.

한 줄 요약

네 언어에 동일한 하나의 철학: 타입 우선, 스택 우선, async 정확성, 그리고 파일 크기에 대한 아키텍처적 정직함. 엄격한 타입, 최신 툴체인, parse-don't-validate, 완전한(exhaustive) 매칭, 타입이 있는 에러, escape hatch 금지, 250 순수 LOC 상한, TDD. 일회성 스크립트도 동일하게 적용합니다.

언어 게이트

한 줄을 쓰기 전에, 스킬은 먼저 언어를 식별하고 해당 레퍼런스 세트를 로드합니다. 언어별 규칙이 로드되기 전에는 아무것도 작성하지 않습니다.

파일 / 언어툴체인
.py, .pyi (Python)uv + basedpyright(typeCheckingMode = "all") + ruff(select = ["ALL"]) + pytest
.rs, Cargo.toml (Rust)cargo + clippy(pedantic + nursery) + rustfmt + cargo-nextest + nightly miri
.ts, .tsx, .mts, .cts (TypeScript)Bun + Biome + tsc --noEmit(strict + noUncheckedIndexedAccess)
.go, go.mod (Go)go modules + gofumpt + golangci-lint v2 + nilaway + go test -race

공유 철학

모든 레시피가 파생되는 여섯 가지 공리입니다.

  1. 타입 시스템이 곧 증명 시스템입니다. 버그를 타입 에러로 표현할 수 있다면, 반드시 타입 에러로 표현합니다.
  2. Parse, don't validate. 신뢰할 수 없는 입력은 경계에서 한 번만 타입 값으로 파싱하고(Pydantic v2 / serde / Zod), 내부에서는 다시 검증하지 않습니다.
  3. 하나의 이름 = 하나의 개념. UserIdstring이 아닙니다. 의미가 다른 모든 기본형에 NewType, newtype 튜플 struct, branded type을 사용합니다.
  4. 항상 완전한 variant 매칭. match + assert_never(Python), match(Rust), switch + assertNever(TypeScript), sealed interface + exhaustive 린터(Go). 태그된 variant에 if/elif/else는 금지입니다.
  5. 프레임워크 보장은 신뢰하고, 경계에서만 검증합니다. 방어적 null 체크나 예외가 날 수 없는 코드에 대한 try/except는 금지입니다.
  6. 테스트 주도. 필요성을 증명한 실패 테스트 없이는 프로덕션 코드를 출시하지 않습니다.

TDD 규율

모든 변경은 red → green → refactor 순서를 따릅니다.

Red

Given / When / Then으로 동작을 명시하는 실패 테스트를 작성합니다. 실행 후, 올바른 이유로 실패하는지 확인합니다 — 오타나 import 누락이 아니라 함수가 아직 없어서 실패해야 합니다.

Green

테스트를 통과시키는 최소한의 코드를 작성합니다. 두 번째 케이스는 다음 red입니다.

Refactor

테스트가 green인 상태에서 가차 없이 구조를 재정비합니다. 테스트가 안전망입니다.

테스트 피라미드는 세 단을 모두 갖춥니다. 빠른 unit 테스트(각 < 10ms) 다수, testcontainers로 실제 다운스트림을 검증하는 integration 테스트 일부, 실제 표면을 구동하는 E2E 시나리오 소수. E2E 커버리지가 0인 기능은 미완성입니다. mock은 최후의 수단으로, 실제 객체 → in-memory fake → testcontainers를 먼저 시도합니다.

250 순수 LOC 상한

순수 LOC(공백·주석 제외)가 250을 넘는 소스 파일은 스타일 취향이 아니라 결함입니다. 250 LOC에서는 리뷰어가 파일 전체를 작업 기억에 담고 횡단 버그를 잡을 수 있습니다.

  • 생성 시 250 LOC를 넘길 파일: 첫 커밋 전에 책임별로 분리합니다.
  • 편집 시 이미 250 LOC를 넘은 파일에 줄을 추가: 건드리는 단위를 먼저 별도 파일로 추출합니다.
  • 읽기 시 250 LOC를 넘긴 파일: smell을 명시하고 구체적인 분리안을 제안한 뒤, 그대로 진행할지 묻습니다.

금지된 회피: 주석을 예산에 포함하기, 토큰 수로 분리(service-2.ts), catch-all 덤프 파일(utils.py, helpers.ts), 230 LOC에서 "거의 다 됐으니" 넘어가기.

언어 공통 철칙

언어별 레퍼런스가 더 엄격하지 않은 한 적용됩니다.

  • 기본은 불변(frozen=True / let / readonly / 값 타입).
  • 모든 의미 단위에 branded 기본형.
  • escape hatch 금지: any/Any, unwrap/!, # type: ignore/@ts-ignore, 숫자 as 좁히기 금지.
  • bare 에러 문자열 금지 — 타입 예외, thiserror/anyhow, Error 서브클래스, sentinel + %w wrap.
  • RAII로 리소스 관리(with / Drop / using / defer).
  • 필수 async 런타임: anyio(bare asyncio 금지), tokio, AbortSignal 기반 플랫폼 네이티브, context.Context + errgroup.

작성 후 리뷰 루프

코드 작성·실질 편집을 마칠 때마다 완료 선언 전에 수행합니다.

  1. 변경된 모든 파일의 순수 LOC를 측정합니다.
  2. 해석: ≤ 200 양호, 200–250 경고 구간, > 250 결함(즉시 리팩터).
  3. 단일 책임, 경계 순수성, 완전 매칭, escape hatch, 방어 레이어, 일회성 헬퍼, 테스트 커버리지를 자가 점검합니다.

상한을 넘었거나 이슈가 둘 이상이면 스킬은 refactor 스킬(안전한 codemap 기반 다단계 리팩터) 또는 remove-ai-slops(테스트를 먼저 고정한 분류형 정리)를 로드합니다.

관련

목차