begin은(는) 무엇을 하나요?
한 번에, 증거에 기반하여, 헤매지 않고 코드베이스의 방향을 잡습니다.
이 스킬이 방지하고자 하는 실패: 에이전트가 레포를 열고, 그럴듯한 단어를 grep하고, 우연히 일치하는 세 개의 파일을 읽고, 시스템의 4%만을 설명하는 자신감 넘치는 아키텍처 요약을 보고합니다. begin은 중요한 코드가 어디에 있는지 추측하는 대신 측정하고, 측정 결과가 가리키는 것만 읽습니다.
계약
- 아무것도 기억되지 않습니다. 모든 것은 도출됩니다. 중요성은 실제 임포트 그래프에 대한 PageRank에서, 복잡성은 계산된 의사결정 지점에서, 초점은 git과 PR 로그에서 비롯됩니다.
파일:라인이나 커밋을 가리킬 수 없으면 말하지 마십시오. - 모든 주장은 증거에 기반합니다. BEGIN.md의 각 진술은
path:line, 커밋, 또는 PR 번호를 인용합니다. 증거가 없는 문장은 추측이며, 이 스킬이 없애고자 하는 것이 바로 추측입니다. - 두 개의 계층, 하나는 살아있습니다.
.begin/은 재생성되고 자기 무시되는 기계 출력물입니다.BEGIN.md는 당신이 작성하고 커밋했으며 도출된 커밋으로 스탬프가 찍힌 산문입니다. 커밋 후 훅은 기계 계층을 다시 도출하고 코드가 어떤 산문 섹션을 앞질렀는지 보고합니다. 이 스킬은 추적된 파일을 절대 편집하지 않습니다 —.begin/은 자체.gitignore를 가지고 있어 레포의.gitignore는 건드리지 않습니다. - 프록시는 프록시로 명명됩니다.
complexityProxy는 의사결정 지점 개수이지 파싱 결과가 아닙니다. 중첩은 들여쓰기로 측정됩니다. 그렇게 말하십시오; 프록시를 사실로 둔갑시키지 마십시오. - 저하된 측정은 조용히 사용되지 않고 공지됩니다. 스캔은 얕은 클론, 죽은 변경 이력 창, 드롭된 파일, 전혀 파싱할 수 없는 언어, 또는 파싱할 수 있는 언어에 대한 해석 실패에 대해
[!WARNING]블록을 출력합니다. 테이블보다 먼저 그 블록을 읽고, 그 내용을 BEGIN.md에 반복하십시오. 깨진 그래프 위에 구축된 순위는 좋은 순위와 똑같이 보입니다 — 그것이 바로 위험의 전부입니다.
실행
S=~/.claude/skills/begin/scripts
bash $S/recon.sh # 누가/무엇을/언제: PRs, 당신의 커밋, 라이브 편집, 문서
node $S/scan.mjs # 구조: 임포트 그래프, 핫스팟, 표면->엔진
둘 다 .begin/에 쓰고 요약을 출력합니다. 레포 어디에서나 실행하세요 — 스캔은 레포 루트에 고정됩니다. recon.sh는 gh, 네트워크, 원격 저장소 없이도 정상적으로 저하되지만 node가 필요합니다 (수정이 필수입니다). 측정된 웜 캐시: 259개 파일 0.24초 · 3,384개 파일 1.9초 · 2,809개 파일 1.9초 · 1,819개 파일 2.5초 · 1,397개 파일 3.5초. 파일 수는 시간을 예측하지 못하며, 내용이 예측합니다.
알아두면 좋은 플래그:
--since "90 days ago"— 변경 이력 창 (두 스크립트 모두 기본값 90일).--top 40— 출력할 핫스팟 수 (기본값 25).--author "..."— 정규식. 거의 필요하지 않습니다: 기본값은 레포의user.name이며,recon.sh는 당신이 커밋이 없을 때 레포의 가장 활동적인 작성자로 대체하고 그렇게 말합니다. 방금 클론한 레포에서는 정상적인 경우입니다.--exclude 'examples/**,site/**'— 벤더 트리와 문서 사이트를 표면 개수에서 제외합니다. 패턴은 양쪽 끝에서 고정되며, 제거된 파일 수가 출력됩니다. 조용한 제외는 나중에 누락된 엣지로 나타나기 때문입니다.--root DIR— 다른 레포를 스캔합니다.
작업 순서 — 정확히 따르십시오
이 순서를 지키지 않으면 에이전트가 잘못된 파일을 읽게 됩니다.
1. 구조보다 먼저 정찰
recon.sh를 먼저 실행하십시오. "이 사람이 무엇을 하고 있었는가?"에 답합니다 — 커밋되지 않은 편집, 브랜치-vs-main 커밋, 본문을 포함한 최근 ~20개의 병합된 PR, 그리고 각각이 변경한 내용. 이것이 초점의 우선순위입니다. .begin/recon.md를 전체적으로 읽으십시오; 짧습니다.
커밋되지 않은 diff는 일반적으로 레포에서 가장 유익한 정보입니다 — 사용자가 현재 가지고 있는 질문입니다. Recon은 이에 대해 세 가지를 플래그합니다: 트리가 깨끗할 때 명시적으로 말합니다 (섹션을 생략하고 당신을 찾아 헤매게 하지 않음), diff가 잠금 파일과 빌드 출력물뿐일 때 첫 번째 읽기를 거기에 소비하지 말라고 알려줍니다, 그리고 당신의 체크아웃이 origin보다 뒤쳐져 있을 때 몇 개의 커밋만큼 뒤쳐졌는지 알려주고 당신의 트리에 없는 최근 PR의 파일 이름을 알려줍니다.
마지막 것은 주의사항이 아니라 전제조건입니다. Recon이 뒤쳐졌다고 보고하면 아래 3.2단계는 안전하지 않습니다: PR 파일 목록은 당신이 가지고 있지 않은 코드를 설명합니다. git pull을 먼저 하거나, PR 읽기 단계를 건너뛰고 BEGIN.md에서 그렇게 했다고 말하십시오.
2. 구조는 두 번째
scan.mjs를 실행하고 .begin/scan.md를 읽으십시오. [!WARNING] 블록부터 시작하십시오. 그러면 추측이 아닌 측정된 결과를 갖게 됩니다:
- 표면(Surfaces) — 인간이나 호출자가 실제로 시스템에 닿는 모든 곳, 종류별로 그룹화됨 (
web-page,ui-component,http-route,cli-command,mcp-tool,worker,public-api,migration, 그리고example,config,test는 표면이지만 제품은 아님). 이것이 지도의 UI 끝입니다. - 핫스팟(Hotspots) — 순위가 매겨져 있으며, 각 파일을 그 자리에 두게 한 용어를 명명하는
why열이 있습니다:depended-on,churn,complex또는recent.churn때문에 상위에 있는 파일은depended-on때문에 상위에 있는 파일과 다른 동물입니다; 열은 어떤 대화를 해야 하는지 알려줍니다. - 표면 → 엔진 경로 — 엔드포인트나 버튼에서 어려운 부분까지의 문자 그대로의 임포트 체인으로, BFS로 계산됩니다. 지연된
await import()엣지를 가로지르는 경로는 로드 시간이 아닌 호출 시간에 해석되므로 레이블이 지정됩니다. - 임포트 사이클 그룹 — 정적 값 엣지에 대한 강하게 연결된 집합으로, 하나의 실제 방향성 루프가 걸어나와 있습니다. 타입 전용 및 지연(
await import(...)) 엣지는 제외됩니다. 둘 다 실제 초기화 사이클을 형성하지 않기 때문입니다. - 도달 불가능한 파일 — 죽은 코드이거나, 발견법이 놓친 표면입니다. 어느 쪽인지 결정하고 말하십시오.
2.5. 레포가 이미 작성한 지도를 읽으십시오
핫스팟을 열기 전에 AGENTS.md, CLAUDE.md, ARCHITECTURE.md 또는 디렉토리별 README가 있는지 확인하십시오 — recon.md가 그것들을 나열합니다. 서브시스템 맵을 제공하는 레포는 스캔이 2초에 추론하고 산문이 한 시간에 재구성하는 것을 30줄로 제공합니다. 그것들을 먼저 읽은 다음, 스캔을 사용하여 확인하십시오: 문서는 오래되고, 그래프는 그렇지 않습니다.
3. 측정이 가리킨 것만 읽으십시오
다음 순서로 읽고, 멈추십시오:
- 커밋되지 않은 diff와 현재 브랜치의 커밋 (지금 하고 있는 작업).
- 가장 최근에 병합된 3-5개 PR로 변경된 파일 (방금 결정한 사항).
scan.md의 상위 8-15개 핫스팟.- 상위 3개 각각에 대해,
reachedVia표면을 안쪽으로 따라가서 사용자 액션에서 엔진까지의 전체 경로를 설명할 수 있도록 하십시오. README, 2.5의 에이전트 대상 문서, 그리고 헤드라인이 핫스팟과 일치하는 모든 문서.
첫 번째 패스에서는 이 세트 밖의 파일을 열지 마십시오. 무언가 누락된 것 같으면, 그것은 보고해야 할 발견 사항이지, 탐색할 면허가 아닙니다.
4. 쓰기 전에 확인하십시오
테이블은 결론이 아니라 일련의 단서입니다. 각 주장이 BEGIN.md에 들어가기 전에:
- 파일을 열고 인용하려는 라인이 당신이 생각하는 대로 말하는지 확인하십시오.
- 표면 → 엔진 경로의 경우, 임포트가 실제로 소스에 존재하는지 확인하십시오.
- 동작에 관한 것이라면, 그렇게 보이는 함수보다는 그것을 입증하는 테스트를 선호하십시오.
- 삼켜진 실패를 위해 핫 경로를
grep하십시오 —catch {},.catch(() => {}),as any,as never, 버려진 반환값. 버그는 오류가 버려지는 곳에 살며, 이것들이 첫날에 돌려줄 수 있는 가장 가치 있는 것입니다. - 주요 주장을 확인하려고 하지 말고, 반증하려고 최소한 한 번의 패스를 보내십시오. 좋은 BEGIN.md에서 가장 가치 있는 문장은 스캔과 모순되는 문장입니다.
스캔이 어떤 것에 대해 틀렸다면, BEGIN.md에 그렇게 말하고 수정하십시오. 그래프가 죽었다고 부르지만 실제로 HTTP나 큐를 통해 도달되는 파일은 기록할 수 있는 가장 유용한 것입니다. 왜냐하면 다른 누구도 다시 찾지 못할 것이기 때문입니다. .begin/surfaces.txt에 그러한 진입점을 선언하십시오 (한 줄에 하나의 경로, 선택적으로 path<TAB>kind) 그러면 다음 실행에서 그것들을 표면으로 취급할 것입니다.
5. BEGIN.md 작성
references/BEGIN-template.md를 사용하고, 먼저 references/EXAMPLE-BEGIN.md를 읽어 보정하십시오 — 실제 예시이며 모형이 아닙니다. 순서대로 구조:
- 이 시스템이 하는 일을 한 문단으로 — 코드의 용어가 아닌 사용자의 용어로.
- 기본 메커니즘 — 첫 번째 원칙. 핵심 변환은 무엇입니까? 나머지를 명확하게 만드는 하나의 아이디어는 무엇입니까? 그것 없이는 무엇이 깨집니까?
- 표면 → 엔진 —
scan.md의 경로에서 가져온 테이블, 각 행이 확인됨. 어떤 행도 프로세스나 네트워크 경계를 넘지 않으면 명시적으로 말하십시오: 분할 언어 레포에서 실제 이음새는 일반적으로 어떤 임포트 그래프도 볼 수 없는 HTTP나 큐 호출입니다. - 복잡한 부분, 순위별 — 발견 먼저, 측정 나중. 각 항목은 그 측정 라인에 아직 없는
file:line을 인용하는 함정이 필요합니다. 그것을 제공할 수 없는 항목은 실제로 읽지 않은 것입니다: 삭제하십시오. - 결정과 그 이유 — 각각을 PR 또는 커밋에 연결하고, PR 본문의 추론과 함께. 이것이 문서를 코드 투어가 아닌 지식 그래프로 만드는 것입니다.
- 중단한 곳 — 또는, 소유하지 않은 레포에서는 누가 이것을 소유하고 있으며 어디에서 성장하고 있는지: 활성 작성자, 가장 최근 열린 PR이 무엇을 추가하고 있는지, 어떤 것을 먼저 읽어야 하는지.
- 기계 계층이 여기서 볼 수 없었던 것 — 그리고 열린 질문, 가장 많은 하중을 지탱하는 단일 가정을 포함. 이것을 절대 생략하지 마십시오.
또한 실행 및 확인 방법 (recon.md가 package.json에서 추출한 스크립트)과 이 레포가 과부하하는 모든 단어에 대한 용어집을 기록하십시오. 둘 다 새로 온 사람이 가장 먼저 필요로 하고 모든 코드 투어가 잊어버리는 것입니다.
[[wiki-style]] 앵커로 상호 연결하십시오. 모든 섹션에 스탬프를 찍으십시오:
<!-- begin:section id="ingestion" sha="0055f01" files="src/adapter.ts,src/identity.ts" -->
sha = 섹션을 도출한 순간의 git rev-parse --short HEAD (나중에 BEGIN.md를 추가하는 커밋이 아님). files = 섹션의 주장이 의존하는 파일; src/engine/**와 같은 글로브가 작동합니다. files=가 없거나, 존재하지 않는 경로를 명명하는 files=가 있는 섹션은 결코 오래될 수 없으며 검증 불가능한 것으로 보고됩니다 — 이것이 이 스킬이 방지하고자 하는 실패이므로 경로를 올바르게 가져오십시오.
6. 살아있게 만드십시오
bash $S/install-hook.sh # post-commit; --pre-push for the other trigger
훅은 스캔을 다시 실행하고 얼마나 많은 섹션이 오래되었는지 명명하는 한 줄짜리 알림을 출력하며, 세부 사항은 .begin/stale.md에 있습니다. core.hooksPath (husky)와 git 워크트리를 존중하고, 기존 훅에 손상 없이 추가하며, 비쉘 훅에 추가하는 것을 거부하고, 추적된 파일을 절대 건드리지 않습니다. --uninstall로 제거하며, 자체 블록만 제거합니다.
/begin update
사용자가 이미 BEGIN.md가 있는 레포로 돌아올 때:
node $S/refresh.mjs && cat .begin/stale.md
오래된 섹션만 다시 쓰고, recon.sh를 다시 실행하여 섹션 6을 새로 고치고, 다시 쓰여진 각 섹션을 새로운 HEAD sha로 다시 스탬프하십시오. 현재 섹션은 바이트 단위로 동일하게 두십시오 — 모든 것을 다시 쓰는 업데이트는 독자가 무엇이 변경되었는지에 대한 감각과 git 기록의 유용성을 모두 파괴합니다.
BEGIN.md가 아직 없으면, /begin update는 그냥 /begin입니다: 하나를 작성하십시오.
보고
하나의 짧은 문단: 기본 메커니즘, 가장 중요한 하나 또는 두 개의 파일과 그 이유, 사용자가 중단한 곳, 그리고 확인할 수 없었던 단 한 가지. 세부 사항은 BEGIN.md에 있으며, 답변에 있지 않습니다.
확인하지 않은 것으로 닫으십시오. 전체 범위를 주장하는 begin 패스는 거짓말을 하고 있는 것입니다.
알려진 한계 — 이것들을 말하고, 덮지 마십시오
- 임포트 그래프는 정적입니다. 문자 그대로의
import('./x')는 해석되고 (지연으로 표시됨) 계산된import(expr), DI 컨테이너, 또는 문자열로 키가 지정된 레지스트리는 전혀 엣지를 생성하지 않으므로, 그러한 파일은 하중을 지탱하면서 도달 불가능해 보일 수 있습니다. 분할 언어 레포에서 프론트엔드↔백엔드 이음새는 HTTP 또는 WebSocket 호출이며 구조상 보이지 않습니다. 스캔은 인간이 판단할 수 있도록 정확히 도달 불가능한 파일을 플래그합니다. - 전체 JS/TS 및 Python 해석 — tsconfig
paths(트리의 모든 설정, 루트뿐만 아니라),extends, 프로젝트references, NodeNext./x.js→x.ts, 그리고 추론된 루트에 대한 Python 절대, 상대 및 서브모듈 임포트 (CPythonast실측 기준 약 98% 재현율 및 정밀도로 측정됨). Go, Rust, Ruby, Java, Kotlin, Swift, PHP, C# 및 C/C++는 전혀 엣지를 제공하지 않습니다. 그러한 레포에서 모든 파일은 중요도가 최저로 나타나고 "도달 불가능"으로 보입니다; 스캔은 경고하고, 빈 그래프를 발견으로 보고하지 않도록 그 경고를 반복해야 합니다. complexityProxy는 언어별 의사결정 지점을 계산하며, 주석과 단일 라인 문자열이 제거된 코드에서 계산합니다. 마크업 및 스키마 파일은 설계상 0점입니다; 벤더, 축소 및 생성된 파일은 감지되어 별도로 순위가 매겨집니다. 여러 줄 템플릿 리터럴은 여전히 계산되므로, 템플릿이 많은 파일은 약간 핫하게 읽힙니다.- 변경 이력은
--since에 의해 제한되며, 얕거나 새로운 클론은 변경 이력이 없습니다 — 스캔은 크게 말합니다. 2년 전에 한 번 다시 쓰여진 파일은 여전히 거의 0점이며 레포에서 가장 중요한 파일일 수 있습니다.
테스트
node $S/test-scan.mjs # graph, cycles, surfaces, reachability, Python
node $S/test-scan.mjs --mutate pyDotDot # ...and prove the assertions can go red
bash $S/test-living.sh # staleness, hooks, tree cleanliness
node $S/redact.mjs --self-test # secrets caught AND clean text unharmed
모든 어설션은 그 버그가 실제였고 한 번 출시되었기 때문에 존재합니다. 변형: alias, jsToTs, valueCycle, typeCycle, pyAbsolute, pyDotDot — 각각은 해당 어설션을 빨간색으로 바꿔야 하며, 그렇지 않으면 CI가 실패합니다.