특정 경매 물건(사건번호) 권리분석 글(content/analysis)을 data/cases/<id>.json 사건 데이터로 쓴다 — 사건 데이터 검증·권리 계산(tools/analysis/compute.mjs) → 법령 근거 조사 노트 → 표는 shortcode로 자동, 본문은 해설 → 검사. 새 사건 데이터 파일 만들기, 사건 단계 확인, 매각 결과 입력 안내도 한다. "물건 분석 써줘", "사건 분석", "<사건번호> 분석", "다음 분석 글", "사건 등록", "매각 결과 입력" 요청 시 사용. 개념 설명 가이드 글은 write-guide 스킬.
Recursos
2Instal·la
npx skillscat add rich-batch/auction-note/analyze-case Instal·la des del registre de SkillsCat.
analyze-case
특정 경매 사건 하나의 권리관계를 설명하는 글을 쓴다. 입찰 권유가 아니라 공개 자료로 권리분석을 해 보는 기록이다. 저장소 구조와 공통 규칙은 루트 CLAUDE.md.
핵심 분업: 사실은 사람이 데이터로 넣고, 판정은 코드가 계산하고, AI는 해설만 쓴다.
| 단계 | 누가 | 무엇 |
|---|---|---|
| 1. 사건 등록 | 도구 + 사람 | 법원경매정보·온비드가 무료로 공개하는 자료(매각물건명세서 요약·현황조사서·공매재산명세서·온비드 등기 요약)를 도구로 옮기고, 사람이 공고·명세서와 대조해 data/cases/<id>.json 보완. 등기사항전부증명서는 유료라 열람하지 않는다(아래 "등기부를 보지 않는 분석") |
| 2. 계산 | 코드 | node tools/analysis/compute.mjs <id> → 말소기준권리·인수/소멸·대항력·인수 예상액을 computed에 기록 |
| 3. 글 | AI (이 스킬) | 계산 결과를 해설하는 글 초안. 확인 못 한 사실은 표시 없이 "입찰 전 확인할 것"에 독자용 문장으로 |
| 4. 발행 | 사람 | PR 체크박스 확인 → 머지(자동 공개) |
| 5. 결과 | 사람 | 매각기일 뒤 result 입력 → 글의 매각 결과 표가 다음 빌드에 자동 갱신 |
경로(글 하나 = 사건 ID 하나, 예: seoul-central-2026ta12345):
| 무엇 | 경로 |
|---|---|
| 사건 데이터 (사실 + 계산 결과 + 매각 결과) | data/cases/<id>.json — 필드 설명 tools/analysis/README.md |
| 글 | content/analysis/<id>/index.md |
| 조사 노트 (법령 근거) | pipeline/analysis/research/<id>.md |
| 검사 | node tools/check/analysis.mjs content/analysis/<id>/index.md |
모드
| 요청 | 할 일 |
|---|---|
| "상태", "분석할 거 있어?" | node tools/analysis/status.mjs 결과를 보여 주고 다음 할 일 안내 (이미 등록된 사건만) |
| "<날짜>에 뭐 있어?", "이번 주 후보 찾아줘"(온비드) | node tools/analysis/scan-onbid.mjs --date <날짜>(또는 --days N)로 아직 등록 안 된 온비드 물건 후보를 나열. 사건 등록은 아니다 — 관심 있는 물건관리번호를 사람이 고르면 그때 링크로 사건 등록으로 넘어간다 |
| "<날짜>에 뭐 있어?"(법원경매) | node tools/analysis/scan-court.mjs --court <법원코드> --date <날짜>로 그 법원의 매각공고 후보를 나열. --court 생략 시 data/courts-of-interest.json에 등록한 관심 법원을 순서대로(법원 전환마다 1분 지연) 조회. 법원코드 목록은 --courts |
| "<날짜>에 뭐 있어?"(공매+경매 같이) | node tools/analysis/scan-daily.mjs --date <날짜> — 위 온비드·법원경매 스캔을 같은 날짜로 그대로 실행. 두 스캔 모두 분석 가치 낮은 물건(최저가 300만원 미만·공유지분)은 기본 생략(tools/lib/candidate-filter.mjs) — 전부 보려면 --min-price=0 --include-share |
| "등록 <사건번호> <분류>" | node tools/analysis/new-case.mjs <id> <사건번호> <분류>(분류: apartment·villa·commercial·land·car)로 빈 파일을 만들고, 사람이 채울 필드를 tools/analysis/README.md 기준으로 안내. 값을 대신 지어내거나 웹에서 긁어 채우지 않는다 |
| 물건 링크 붙여넣기("이 링크로 사건 등록해줘" 등) | 아래 링크로 사건 등록 |
| " 분석", "다음 분석 글" | 아래 새 글 |
| " 고쳐 써줘" | render-prompt.mjs --case <id> --revise로 새 글과 같은 절차, 원래 date 유지 |
| "결과 " | 사람에게 매각결과(결과·매각가격·응찰자 수·확인일)를 받아 result에 넣는다. 글은 고치지 않아도 표가 자동 갱신된다 |
링크로 사건 등록
법원경매정보·온비드 같은 물건 페이지 링크를 받으면 로그인·캡차 없이 공개된 데이터는 자동으로 끝까지 조회하고, 그렇지 않은 것만 사람에게 넘긴다. 법원경매정보는 WAF 때문에 등기·점유 정보를 잘 우회해서 확인해야하지만, 온비드 압류재산(부동산)은 사이트가 스스로 "등기사항증명서 주요정보"·"임대차 정보"·"배분요구현황" 표를 로그인 없이 공개하므로 rights[]·tenants[]까지 자동으로 채운다(아래 온비드 절차 3번). 등기사항전부증명서·현황조사서·매각물건명세서 원본 자체는 여전히 자동으로 긁어올 수 없다 — 온비드가 옮겨 적은 요약을 대신 쓰는 것뿐이다.
법원경매정보(courtauction.go.kr): 사이트를 직접 스크래핑하면(간단한 curl·Playwright로 직접 접속) WAF가 차단한다. 이를 유념하고 새로운 방식을 강구한다. 추가로 court-auction-notice-search 패키지(https://github.com/NomaDamas/k-skill , npm에 공개됨)를 쓴다 — 사이트 내부 API를 호출하되 호출 간 지연·세션당 호출 제한·차단 감지 시 자동 재시도 금지 같은 안티봇 가드가 내장돼 있어 정보통신망법상 접근통제 우회 문제를 피한다.
- 법원코드·매각기일을 모르면
node tools/analysis/scan-court.mjs --court <법원코드> --date <YYYY-MM 또는 YYYY-MM-DD>로 후보를 먼저 본다(법원코드 목록:scan-court.mjs --courts). 등록하지는 않는다. 관심 법원이 정해져 있으면data/courts-of-interest.json의courts배열에 코드를 채워 두고--court없이 실행하면 그 법원들을 순서대로 조회한다 — 스크립트가 세션(쿠키·호출 간 지연)을 법원 사이에 공유하고 법원을 옮길 때마다 1분을 더 쉬므로 여러 법원을 한 명령으로 훑어도 되지만, 그래도 정말 관심 있는 법원만 목록에 넣는다(많을수록 세션 호출 한도·차단 위험이 커진다). 공매(온비드)도 같이 볼 때는node tools/analysis/scan-daily.mjs --date <날짜>로 한 번에. 두 스캔 모두 최저가가 너무 낮은 자투리·공유지분 매각은 기본으로 목록에서 생략한다(사람이 서류를 봐야 아는 특수성이 커서 이 저장소 계산 엔진이 잘 안 맞고, 매번 다 훑으면 토큰만 쓴다) —--min-price=0 --include-share로 필요하면 전부 본다. node tools/analysis/fetch-court.mjs <법원코드> <사건번호> --sale-date <매각기일>로 사건을 등록한다. 감정가·최저가·물건종류·소재지·배당요구종기·청구금액까지 자동으로 채운다.- 공개 자료로 나머지를 채운다 — 등기부 없이:
node tools/analysis/fetch-court-docs.mjs <id>— 현황조사서의 점유관계·전입일 →tenants[](보증금·확정일자·배당요구는 미상으로 남는다).node tools/analysis/fetch-court-result.mjs <id> --write— 물건상세의 매각물건명세서 요약 →spec_sheet(최선순위 설정·매각으로 소멸되지 않는 권리), 말소기준권리 한 줄 →rights[0](날짜·종류만), 전용면적, 기일 내역·유찰 횟수. 매각기일 뒤에 다시 돌리면 결과(result)도 채운다. 물건상세는 매각되면 닫히니 매각기일 전에 한 번 돌려 둔다.- 매각물건명세서 원문(PDF)의 임차인 보증금·확정일자·배당요구는 자동으로 못 가져온다 — 사람이 법원경매정보에서 명세서를 보고 넣거나, 못 넣으면 글이 "확인하지 못했다"로 쓴다.
- 여러 달을 잇달아 스캔하지 않는다 — 법원경매정보는 짧은 시간에 요청이 몰리면 IP를 약 1시간 차단한다.
BLOCKED/세션 호출 한도 초과 에러가 뜨면 스크립트가 그 자리에서 멈춘다(자동 재시도 금지) — 사람이 시간을 두고 다시 시도한다. 이미 등록된 사건은 자동으로 목록에서 빠지니 중단된 뒤 다시 돌려도 중복되지 않는다.
온비드(onbid.co.kr): WAF 차단이 없고 물건 조회 API가 공개돼 있어 자동 조회가 가능하다. 재산유형마다 법적 근거·계산 성격이 다르다.
| 재산유형 | 법적 근거 | 판정 기준 | 명령 |
|---|---|---|---|
| 압류재산 (기본값) | 국세징수법 제92조 | 등기 접수일 순서(말소기준권리) — court 경매와 같은 구조, 인수 금액 계산. rights[]·tenants[]도 온비드 공개 요약에서 자동으로 채움(아파트·빌라·상가·토지) |
node tools/analysis/fetch-onbid.mjs <물건관리번호> |
| 신탁공매 | 신탁법 제4조·제22조 | 신탁등기 접수일 — 등기 소멸/인수는 코드가 판정 안 하고 전부 review | node tools/analysis/fetch-onbid.mjs <물건관리번호> --type=trust |
| 국유재산 · 공유재산 | 국유재산법 제11조 · 공유재산법 제8조 | 사권(私權)이 소멸된 후에만 취득되는 게 원칙 — rights는 비어 있는 게 정상, 있으면 이례적이라 전부 review. 사용허가·대부 사용자 여부도 review | node tools/analysis/fetch-onbid.mjs <물건관리번호> (온비드 표시 그대로 인식) |
| 기타일반재산 | 위임기관마다 다름 | 하나로 일반화 못 함 — 등기·점유를 전부 review로 남기는 최소 계산 | node tools/analysis/fetch-onbid.mjs <물건관리번호> (온비드 표시 그대로 인식) |
- 물건관리번호를 받는다 (
2022-0200-007090처럼 온비드 화면에 보이는 번호 — 온비드는 상세 페이지에 고유 URL이 없어 "링크"가 아니라 이 번호로 찾는다). node tools/analysis/fetch-onbid.mjs <물건관리번호>를 실행한다 — 압류재산·국유재산·공유재산·기타일반재산은 온비드의 "재산유형" 표시를 그대로 받아들인다. 신탁공매만 예외: 온비드가 이 유형을 따로 표시하지 않아(보통 "기타일반재산"으로 보임) 위임기관 이름에 "신탁"이 있으면 스크립트가--type=trust로 다시 실행하라고 안내한다. 그 외(동산·유가증권 등) 유형은 법적 근거를 아직 확인 못 해 사건 파일을 만들지 않고 멈춘다.- 이 스크립트가 하는 일(공통):
- Playwright(Chromium,
npx playwright install chromium로 최초 1회 설치 필요)로 온비드 물건 검색 API를 호출해 공개 필드(사건번호·물건종류·소재지·면적·감정가·입찰기간·유찰횟수)를 가져온다. - 한 물건에 여러 회차(감액되는 최저가)가 동시에 예약돼 있으면 가장 가까운 회차를 자동으로 고른다.
- 소재지는 온비드 물건명(전체 주소, 지번·동·호수 포함)을 그대로 쓴다 — 법원경매정보·온비드가 법률상 공개하는 정보이고 기존 경매정보 서비스도 동일하게 전체 주소를 쓴다. 사람 이름·주민번호·전화번호는 계속 금지(FORBIDDEN_KEYS·정규식 검사).
data/cases/onbid-<물건관리번호 숫자만>.json을 만든다.source.type: "onbid",case.onbid_property_type은 위 표의 재산유형 중 하나.
- Playwright(Chromium,
- 압류재산·부동산(아파트·빌라·상가·토지)은
rights[]·tenants[]도 자동으로 채운다.fetch-onbid.mjs가 물건 상세 페이지의 "등기사항증명서 주요정보"·"임대차 정보"·"점유관계"·"배분요구 및 채권신고현황" 표(로그인 불필요, 온비드가 압류재산 입찰자를 위해 스스로 공개하는 요약 —tools/lib/onbid.mjs의fetchOnbidRightsAnalysis/buildOnbidRightsAndTenants)를 그대로 읽어 채운다. 이건 등기사항전부증명서 원본이 아니라 온비드가 옮겨 적은 요약이라:- 권리자명은 온비드가 이미 마스킹해서 주므로(
박**처럼)holder_type은 마스킹 패턴으로 개인/법인/기관을 추정한 값이고, 온비드 표의 "권리종류"가 이 저장소의 등기 종류와 안 맞으면(예: "위임기관") 최선으로 추정하고special[]에 검토 항목을 남긴다 — 사람도 AI도 이 추정을 최종값으로 믿지 말고, 애매한 항목은 special[]을 보고 등기사항전부증명서 원본과 대조한다. - 배분요구현황·점유관계는 입찰시작 7일 전부터 공개된다 — 그 전에 조회하면 rights[]는 채워져도 tenants[]의 배당요구 여부는 비어 있고
special[]에 "재조회 필요"로 남는다. 매각기일이 가까워지면 사건을 다시 조회(또는 온비드 화면과 대조)해서 채운다. - 감정평가서 같은 첨부파일은 온비드가 보안 뷰어로만 열리게 막아 놔서(다운로드 불가) 자동화 대상에서 뺐다 — 표로 공개된 값이 아닌 세부 사항(사진·평면도 등)이 필요하면 사람이 직접 연다.
- 신탁공매·국유재산·공유재산·기타일반재산·자동차는 자동 채움 대상이 아니다 — 계산 성격이 달라(신탁공매는 소멸/인수를 코드가 판정하지 않고, 국유재산 등은 rights가 비어 있는 게 원칙, 자동차는 별도 서류) 사람이 서류를 보고 채운다: 공매재산명세(국유재산·공유재산·기타일반재산은 공고문·사용허가·대부계약 현황), 자동차등록원부. 최저입찰가격이 온비드에서 "비공개"로 표시된 경우
sale.minimum도 사람이 채워야 한다. 신탁공매는 추가로case.trust_registered_on(신탁등기 접수일, 등기사항전부증명서에서 확인)도 사람이 채워야compute.mjs가 계산한다 — 없으면 INVALID로 막힌다. - 법원경매정보(court)는 자동화 할 수 있도록 강구해야한다. — WAF 때문에 이 과정이 까다롭다.(위 법원경매정보 절차 3번).
- 권리자명은 온비드가 이미 마스킹해서 주므로(
- 시세 조사(선택): 원하면 WebSearch/WebFetch로 네이버부동산·국토교통부 실거래가 공개시스템 등에서 인근 비교 사례 후보를 찾아 제시한다. 이건 그때그때 한 번 찾아보는 리서치이지 자동으로 캐싱·반복 수집하는 배치가 아니다. 사람이 확정한 값만
market.trades[]에 넣는다. - 이후는 기존 새 글 절차와 같다:
compute.mjs→ 글 작성.
새 글
- 계산 최신화.
node tools/analysis/compute.mjs <id>.INVALID면 멈추고 무엇을 고쳐야 하는지 사람에게 보고한다(데이터를 추측으로 고치지 않는다). - 지시문 받기.
node .claude/skills/analyze-case/render-prompt.mjs --case <id> node .claude/skills/analyze-case/render-prompt.mjs --next 1 === JOB블록대로 0단계(조사 노트) → 1단계(글) → 2단계(셀프 리뷰) → 검사. FAIL은 PASS까지 고친다.- 로컬 확인.
hugo -D -d <스크래치 폴더>빌드가 에러 없이 끝나는지(사건 데이터가 없거나computed가 없으면 shortcode가 빌드를 멈춘다). - 보고. 템플릿의 보고 항목 + 사람이 발행 전 해야 할 일(최신 매각물건명세서·공고와 대조 — PR 체크박스).
등기부를 보지 않는 분석
등기사항전부증명서는 인터넷등기소 유료 열람이라 이 블로그는 보지 않는다. 사건마다 비용을 들일 수 없고, 열람한 등기부를 공개 저장소에 옮길 수도 없기 때문이다. 대신 법원·온비드가 무료로 공개하는 요약만 쓴다.
| 출처 | 무엇을 알 수 있나 | 무엇을 모르나 |
|---|---|---|
| 법원경매정보 물건상세(매각물건명세서 요약) | 최선순위 설정(=말소기준권리 날짜·종류), 매각으로 소멸되지 않는 권리, 전용면적, 기일 내역 | 근저당 금액·접수번호, 후순위 등기 전체 |
| 법원경매정보 현황조사서 | 점유관계, 임차인 전입일 | 보증금·확정일자·배당요구 |
| 온비드 공매재산명세·등기 요약 | 권리 종류·설정일·금액(공매대행 의뢰 시점), 임대차·배분요구 현황 | 의뢰 이후 등기, 접수번호 |
- 계산: 말소기준권리와 임차인 전입일만 있으면 대항력·인수/소멸 판정은 된다. 금액이 없으면 인수 예상액은 "미상"으로 남고, 계산 도구가 review로 넘긴다 — 0으로 채우지 않는다(0이면 "인수 0원"이라는 틀린 결론이 나온다).
- 명세서가 기준: "매각으로 소멸되지 않는 권리"는 법원의 공식 판단이다. 계산과 어긋나면 엔진이 review로 알리고, 글은 명세서 쪽을 핵심 위험으로 다룬다.
- 글: 등기를 직접 본 것처럼 쓰지 않는다. 출처는 "매각물건명세서에 따르면"·"온비드 공개 요약에 따르면"으로 밝히고, 등기부로만 알 수 있는 것(금액·후순위 등기·말소 여부)은
## 입찰 전 확인할 것에 독자가 인터넷등기소에서 열람하도록 쓴다. 참고 자료에 등기사항전부증명서를 출처로 적지 않는다(render-prompt의{source_line}이 실제로 본 자료만 넣는다). - 데이터:
source.documents에는 실제로 본 자료만 적는다(등기사항전부증명서 금지).rights[].note에 어디서 옮겼는지 적는다.
여러 건을 한꺼번에 처리할 때 (토큰 절약)
"10건 등록해줘", "이 목록 다 분석해줘" 같은 배치 요청은 기계적인 단계와 판단이 필요한 단계를 나눠서 처리한다 — 단계마다 비용이 다르기 때문이다.
- 기계적인 단계(직접 실행, 에이전트 안 씀):
fetch-onbid.mjs·fetch-court.mjs·compute.mjs·fetch-market.mjs처럼 판단 없이 도구 하나 실행하고 결과만 확인하는 작업. 이걸 사건마다 서브에이전트(Agent 도구)로 돌리면 사건당 51~73만 토큰이 든다(포크마다 전체 컨텍스트를 다시 불러오기 때문) — 같은 작업을 bash 반복문으로 직접 돌리면 그 비용이 거의 안 든다. 여러 건의 등록·계산·시세조회는 하나의 셸 반복문으로 직접 실행한다. - 판단이 필요한 단계(에이전트로 병렬화): 실제 글쓰기(0~2단계)와 검사→수정 반복. 문체 규칙을 지키고 검사 실패를 보고 고치는 건 도구 실행이 아니라 판단이라 이 비용은 필요하다 — 그 대신 여러 건을 동시에 병렬로 돌려 시간을 아낀다.
즉 "등록·계산까지는 내가 직접 반복 실행 → 글쓰기·검사만 사건별로 병렬 에이전트"의 순서로 나눈다. 등록만 먼저 끝내고 사람이 rights[]·tenants[] 등을 채운 뒤에 글쓰기 단계로 넘어가는 경우가 많으니, 두 단계를 같은 배치로 묶어 한꺼번에 에이전트를 띄우지 않는다.
분류(case.category)별 차이
| 분류 | 계산 | 글에서 |
|---|---|---|
| apartment · villa · commercial | 아래 권리분석 엔진 그대로 (상가 임차인은 상가건물임대차보호법 규칙) | 표준 구조 |
| land | 같은 엔진, 임차인은 입력 금지(special에 기록). 법정지상권·지목/맹지·농지취득자격증명이 review에 자동으로 남는다 |
## 임차인과 점유는 "점유 현황"으로 쓰고 토지 확인 항목을 ## 입찰 전 확인할 것에 |
| car | 별도 엔진(computeCarCase). 자동차에 등록된 저당권·압류 등은 순서와 무관하게 항상 소멸(국세징수법 제92조제1항, 민사집행규칙 제108조가 준용하는 민사집행법 제91조제2항 — 자동차엔 지상권·전세권·대항력 있는 임차권 개념 자체가 없다). tenants는 항상 빈 배열(검증이 막음). 유일한 인수 위험인 유치권은 등록원부에 안 나타나 항상 review |
## 임차인과 점유는 "점유 현황"으로 쓰고 현재 보관 장소·유치권 여부를 다룬다. 입력은 등기사항전부증명서 대신 자동차등록원부(fetch-onbid.mjs가 압류재산 자동차를 감지하면 안내) |
분류 추가: data/categories.json에 한 줄 → 분류 페이지·탭·검증에 자동 반영. 계산 방식이 다르면 engine을 새로 정의하고 rights.mjs 검증을 갈라야 한다.
계산 도구가 하는 것 / 못 하는 것
한다 (tools/analysis/rights.mjs, 테스트 node --test tools/analysis/rights.test.mjs):
- 말소기준권리: (근)저당권·압류·가압류·담보가등기·경매개시결정 중 가장 빠른 접수(같은 날이면 접수번호), 건물 전부 전세권 + 배당요구
- 등기 권리 인수/소멸: 말소기준권리보다 앞서면 인수, 뒤면 소멸. 선순위 전세권은 배당요구 시 소멸
- 임차인 대항력: 점유(또는 임차권등기) + 전입·사업자등록일이 말소기준권리 접수일보다 하루 이상 앞설 때
- 인수 예상액: 대항력 있고 배당요구 안 함 → 보증금 전액 / 배당요구함 → 0 ~ 보증금(배당 순위 미계산)
- 입찰보증금(기본 10%, 재매각 20%), 감정가 대비 최저가 비율
- 매각물건명세서 기재(최선순위 설정, 인수 권리)와 대조해 어긋나면 review
못 한다 → review로 남김: 배당표(누가 얼마 배당받는지), 소액임차인 최우선변제, 유치권·법정지상권·분묘기지권, 후순위 가처분의 성격, 가등기의 성격(담보/보전), 대지권 미등기·토지별도등기 등 special에 적힌 사항.
규칙을 바꾸거나 추가할 때는 rights.mjs와 rights.test.mjs를 함께 고치고 테스트를 통과시킨다. 법령 근거를 주석에 남긴다.
자주 막히는 곳
| 증상 | 원인 / 해결 |
|---|---|
| 검사 "computed가 오래됨" | 데이터를 고친 뒤 compute를 안 돌림. 다시 돌리고 글이 새 결과와 맞는지 확인 |
| 검사 "사건 데이터에 없는 금액" | 본문에 계산해서 만든 숫자. 데이터 값(또는 두 값의 합·차)으로 바꾸거나 지운다. 필요한 값이면 사람이 데이터에 넣는다 |
| 빌드 에러 "data/cases/…json이 없음" | front matter case와 파일 이름이 다름 |
| 시세를 쓰고 싶음 | 사람이 market.trades에 실거래 사례와 source_url을 넣은 뒤에만 |
| 매각기일이 연기·변경됨 | 사람이 sale.sale_date를 고치고 compute 재실행(입력 해시가 바뀜) |