사용자 추가 딥다이브 · 2026-07-24 · gptaku-plugins · INSANE-SEARCH

fivetaku/insane-search 딥다이브
— 공개 페이지라면 뚫릴 때까지 접근 경로를 갈아타는 차단 저항 리더

insane-search의 한 줄 정의는 "포기는 배추 셀 때나 쓰는 말 — 공개된 페이지라면 결국 뚫어낸다"이다. 차단(403·WAF·봇 탐지)에 강한 공개 페이지 리더로, Claude Code용 플러그인이며 API 키도, 프록시 설정도 없다. 기본 WebFetch가 막히는 순간 자동으로 끼어들어, 공개 접근 경로를 단계적으로 상승(Phase 0→3)시키며 하나가 뚫릴 때까지 시도한다.

중요한 선은 이것이다 — 로그인과 페이월에서는 멈춘다. 뚫으려 하지 않고 authentication required라고 정직하게 보고하며, 사용자를 대신해 로그인하지 않고 자격 증명을 저장·전송하지 않는다. "인증 우회 도구가 아니라 공개 콘텐츠 전용 리더"라는 게 설계 자체에 박혀 있다.

(저장소 fivetaku/insane-search · 버전 0.12.1 · 라이선스 MIT · ⭐ 약 1.9k · 포크 247 · 언어 Python 88.6% · JS 8.2% · Shell 3.2% · gptaku-plugins 마켓플레이스의 일부 · 핵심 engine/(fetch_chain 1,332줄)·curl_cffi TLS 임퍼소네이션·yt-dlp·Playwright/patchright · shallow clone 소스 직접 분석)
목차
  1. 프로젝트 한 줄 요약
  2. 왜 주목받는가 — 기본 fetch가 못 하는 단 하나
  3. 기술 스택 — 뚫기 위한 도구 상자
  4. 아키텍처 심화 — Phase 0→3 에스컬레이션 파이프라인
  5. 디렉토리 구조 해부
  6. 학습 포인트 — 여기서 훔쳐올 설계
  7. 시스템 요구사항 · 경계(Boundaries)
  8. 직접 해볼 수 있는 실습 과제
  9. 관련 기술 심화 학습 로드맵
  10. 핵심 키워드 사전
  11. 참고 링크

1프로젝트 한 줄 요약

"접근할 수 없습니다"가 돌아오던 그 자리에서, 공개 경로를 끝까지 시도해 쓸 수 있는 텍스트를 돌려준다
한 문장으로

insane-search = 막힌 공개 페이지 앞에서 포기하지 않는 집요한 리더. 공식 API → 경량 프로브 → TLS 위장 → 진짜 브라우저까지 사다리를 올라, 하나가 뚫릴 때까지 시도한다.

평범한 fetch403을 맞으면 "못 읽는다"고 끝낸다. insane-search는 그 지점에서 "아직 안 해본 공개 경로"를 차례로 올린다 — 그리고 로그인·페이월이라는 진짜 벽을 만나면 가장하지 않고 멈춰 정직하게 보고한다.

외울 명령어는 없다. 평소처럼 Claude Code에게 "레딧에서 이 주제 반응 찾아줘", "이 유튜브 요약해줘"라고 부탁하면, fetch가 막히는 순간 플러그인이 알아서 끼어든다.

용어
WAF · 봇 탐지 · TLS 임퍼소네이션 · 공개 경로
WAF(Web Application Firewall)는 Cloudflare·Akamai·DataDome처럼 자동화 트래픽을 걸러내는 방어막이다. 봇 탐지는 "사람이 아닌 것 같다"를 판별해 403·CAPTCHA를 띄운다. TLS 임퍼소네이션은 실제 브라우저의 암호화 악수 지문(JA3/JA4)까지 똑같이 흉내 내 "진짜 사파리/크롬"처럼 보이게 하는 기법이다. 공개 경로는 로그인 없이 닿을 수 있는 API·피드·아카이브·렌더된 페이지를 뜻한다 — insane-search는 이 안에서만 움직인다.

2왜 주목받는가

별점 1.9k의 이유는 단 하나 — 기본 fetch가 못 하는 "뚫릴 때까지 계속 시도한다"

에이전트에게 웹을 읽히는 도구는 많다. insane-search가 눈에 띄는 건 차단 앞에서의 태도가 근본부터 다르기 때문이다 — 한 번 막히면 끝이 아니라, 공개 경로를 단계적으로 상승시키며 집요하게 재시도한다.

핵심 주장 ①

단정하지 않고 "단계를 올린다"

공개 API 리더 → 신디케이션 게이트웨이 → TLS 임퍼소네이션 → 진짜 헤드리스 브라우저까지, 직전 단계가 실패하거나 차단 신호를 감지했을 때만 다음 단계로 올라간다. 단순히 User-Agent만 바꾸는 게 아니라 완전한 브라우저 정체성(실제 TLS 지문·쿠키 워밍·리퍼러 체인)을 구성한다. 기본 Claude Code 단독이면 403·WAF·CAPTCHA에서 그냥 포기하던 자리를, 하나 뚫릴 때까지 밀어붙인다.

핵심 주장 ②

"사이트 이름을 코드에 넣지 않는다"는 일반화 규율

가장 인상적인 설계 원칙이다. engine/**·waf_profiles.yaml에는 특정 사이트 도메인·셀렉터·브랜드명을 하드코딩 금지한다(bias_check.py가 CI 게이트로 강제). 대신 프로파일은 WAF 제품별(akamai_bot_manager·cloudflare_turnstile·datadome…)로 짜여, "같은 WAF를 쓰는 어느 사이트에나 유효한가?"를 기준으로 삼는다. 그래서 새 사이트도 코드 수정 없이 커버된다.

핵심 주장 ③

숨은 API를 찾아 재활용한다 (scraper-forge)

HTML은 막혀도 사이트가 내부적으로 쓰는 JSON API는 방어가 얕은 경우가 많다. insane-search는 진짜 브라우저의 네트워크 트래픽을 관찰해 그 내부 엔드포인트를 그대로 재활용한다. INSANE_AUTO_FORGE=1이면 체인이 실패할 때 스스로 렌더→XHR 캡처→본문과 겹치는 데이터 API 선별→curl 재현→레시피 자동 저장까지 한다(광고·텔레메트리 endpoint는 제외).

눈여겨볼 것 — 드물게 성숙한 안전 설계
가져온 웹 텍스트를 "명령이 아니라 데이터"로 취급(R8)

엔진이 반환한 공개 웹 본문은 untrusted_public_web으로 다룬다. 본문 속 문장이 무언가를 지시하더라도 명령 실행·파일 접근·토큰 노출·상위 지시 무시는 금지된다. [BEGIN/END UNTRUSTED WEB CONTENT] 경계(생성된 boundary id 부착)와 to_untrusted_text()로 프롬프트 인젝션을 구조적으로 막는다. 웹을 읽는 에이전트 도구가 반드시 갖춰야 할 방어를 실제로 구현했다.

주의 — 이중 용도(dual-use)와 책임
"공개 콘텐츠 리더"이지 인증 우회 도구가 아니다

DISCLAIMER가 명확히 한다: 이건 범용 개발 도구라 본질적으로 이중 용도이며, 저자는 제3자의 실제 사용을 통제할 수 없다. 로그인·페이월에서 멈추도록 설계됐지만, 대상 사이트의 이용약관(ToS)·관련 법 준수는 전적으로 사용자 책임이다. 소유하지 않은 시스템에 접근하기 전 정당한 권한을 확보해야 한다. 학습·정리는 자유롭되, 실제 수집 활동은 각 플랫폼 규정과 법을 먼저 확인할 것.

3기술 스택 전체 지도

Python 엔진이 심장, JS 브라우저 템플릿이 최종 병기 — 전부 "셋업 제로"로 자동 설치
기술왜 이걸 썼나
엔진 코어Python 3 (engine/, 88.6%)fetch_chain.py(1,332줄) 단일 진입점. probe→validate→detect→plan→execute→report.
TLS 위장curl_cffi (≥0.15)Safari/Chrome/Firefox의 TLS(JA3/JA4) 지문을 복제. 0.15부터 최신 Chrome 지문·HTTP/3·SSRF-safe redirect.
미디어yt-dlpYouTube 등 1,858개 사이트의 메타데이터·자막을 --dump-json으로.
헤드리스 브라우저Playwright · patchright · nodriverpatchright는 Playwright 포크로 CDP Runtime.enable 누출을 막아 봇 탐지 회피. nodriver는 raw CDP.
콘텐츠 추출markdownify(기본 ON) · resiliparse · pdfplumberraw HTML→구조보존 마크다운(기본). 본문만 뽑기(opt-in), PDF는 pdfplumber. AGPL인 PyMuPDF는 금지.
파싱·설정BeautifulSoup4 · PyYAML · pypdfOGP/JSON-LD 메타 스캔, WAF 프로파일(yaml), PDF 폴백.
설치첫 실행 시 자동필요 패키지를 최초 호출 때 pip install. API 키도, 가입도 없다.
비유로 이해하기

insane-search는 잠긴 (공개) 문을 여는 열쇠 꾸러미 같다. 먼저 정문 열쇠(공식 API)를 넣어 보고, 안 되면 옆문(모바일·RSS 변형), 그다음 경비원처럼 보이는 변장(TLS 위장), 마지막엔 진짜 사람이 걸어 들어가는 것(헤드리스 브라우저)까지 차례로 시도한다. 단, 비밀번호가 걸린 문(로그인·페이월) 앞에서는 열쇠를 꺼내지 않고 "여긴 인증이 필요합니다"라고 물러선다.

4아키텍처 심화 분석

모든 요청이 Phase 0→3 사다리를 오른다 — 각 단계는 앞 단계가 막혔을 때만 발동
차단된 URL (403 / WAF / 봇 탐지) │ ▼ ┌ Phase 0 ─ 공식 공개 엔드포인트 (engine/phase0.py) ─────────┐ │ Reddit→.rss · X→oEmbed/syndication · YouTube→yt-dlp │ │ HN Firebase · arXiv Atom · Bluesky · Stack Overflow … │ └───────────────┬──────────────────────────────────────────┘ 없으면 ▼ ┌ Phase 0.5 recipe ─ recipes/<도메인>/recipe.yaml 있으면 API 직행 ┐ └───────────────┬──────────────────────────────────────────┘ ▼ ┌ Phase 1 probe ─ curl_cffi(safari) + self-referer ────────┐ │ → validate(4계층) → detect(WAF 랭킹) │ └───────────────┬──────────────────────────────────────────┘ challenge면 ▼ ┌ Phase 2 grid ─ TLS 임퍼소네이션 × URL 변형 × referer ─────┐ │ safari/chrome/firefox 계열 전수 (다양성 우선, 200에 안 멈춤)│ └───────────────┬──────────────────────────────────────────┘ 여전히 막히면 ▼ ┌ Phase 3 browser ─ capability-matched executor ───────────┐ │ protocol_stealth(nodriver→patchright) / real_chrome / │ │ Playwright MCP / mobile_chrome │ └───────────────┬──────────────────────────────────────────┘ ▼ 4계층 검증 통과? ──► strong_ok / weak_ok (성공 · 출처와 함께) │ └─ auth_required / 404 / paywall ──► 정직하게 정지 "인증 필요" (429 rate-limit은 terminal 아님 — 백오프 후 재시도)

핵심 설계 ① — 200은 성공이 아니다: 4계층 검증

대부분의 fetch는 HTTP 200이면 성공으로 친다. 여기선 200은 "검사 시작 조건"일 뿐이고, 네 가지를 모두(AND) 통과해야 성공이다.

# validate() — 4계층 AND (하나라도 실패하면 격자는 계속 탐색)
1) 챌린지 마커 없음   ("Just a moment...", "Access Denied", DataDome …)
2) 비정상 크기 아님   (본문 < 3KB 또는 WAF 지문 크기 아님)
3) 쿠키 센서 정상     (Akamai _abck=~-1~ 같은 차단 상태 아님)
4) success_selectors 매칭  (caller 제공 → strong_ok, 미제공 → weak_ok)

그래서 "200을 받았지만 실은 CAPTCHA 페이지"에 속지 않는다. 첫 200에서 탈출하지 않고, 진짜 콘텐츠 증거를 확인할 때까지 격자를 계속 돈다.

핵심 설계 ② — WAF 프로파일: 사이트가 아니라 "제품"을 안다

waf_profiles.yaml은 사이트가 아니라 WAF 제품별로 짜여 있다. 예를 들어 Akamai Bot Manager 프로파일은 이렇게 생겼다.

akamai_bot_manager:
  detectors:
    cookie: ["_abck", "bm_sz", "ak_bmsc"]   # 제품 아티팩트로 감지
    server_contains: ["AkamaiGHost"]
  capabilities_needed:
    - needs_real_tls_stack     # Playwright 번들 TLS는 탐지됨
    - needs_js_exec            # JS 센서 챌린지
    - needs_protocol_stealth   # Runtime.enable 지문화 → 심 계열 실패
  tls_impersonate_candidates:
    - [safari, safari15_5, safari17_0, safari260]   # 계열별 우선순위
    - [chrome99, chrome119, chrome131, chrome146]

감지는 다중 신호 게이팅(신호 2개 → confidence 0.9)으로 오탐을 줄이고, 프로파일은 "결정적 레시피"가 아니라 우선순위 추천(prior)일 뿐 — 실제 응답을 매 시도마다 평가한다. 그리고 executor.py가 이 capabilities_needed 태그를 읽어 알맞은 브라우저 실행기를 자동 선택한다(needs_protocol_stealth면 nodriver→patchright 등).

핵심 설계 ③ — 격자는 "다양성 우선"으로 짠다

fetch_chain.py의 v2 스케줄러는 격자를 만든 뒤 다양성을 위해 재정렬한다 — 두 URL 변형에 걸쳐 TLS 계열마다 대표 하나씩을 먼저 놓아, 작은 시도 예산으로도 모든 계열·변형을 건드리게 한다(사파리 계열만 태우다 끝나지 않게). tls_impersonate_avoid 항목은 삭제가 아니라 후순위로 미룰 뿐이라, 전수 모드에선 여전히 시도된다.

핵심 설계 ④ — engine의 "포기"는 허가가 아니다 (실패 게이트)

하네스 규칙 R6이 압권이다. engine은 실패 시 ok=false와 함께 아직 안 해본 경로(untried_routes)·grid_exhausted·must_invoke_playwright_mcp 플래그를 돌려준다. 이 셋이 모두 충족되기 전엔 "뚫을 수 없음" 결론이 금지된다. CLI는 미완이면 ⛔ NOT EXHAUSTED를 stderr로 찍어, 에이전트가 게을리 포기하지 못하게 기계적으로 고삐를 채운다. (단 auth_required·404 같은 terminal이면 정직하게 실패 인정 — 429는 terminal 아님.)

5디렉토리 구조 해부

skills/insane-search/engine/가 심장 — 그 위를 얇은 플러그인 껍질이 감싼다
insane-search/ ├── .claude-plugin/plugin.json ★ Claude Code 플러그인 매니페스트 (v0.12.1) ├── setup/setup.sh 첫 실행 셋업(별점 요청 포함) · 업데이트 체크 ├── README.{md,ko,ja,zh,es} 5개 언어 문서 · PLATFORMS.md · DISCLAIMER.md │ └── skills/insane-search/ ★ 스킬 본체 ├── SKILL.md 하네스 규칙 R1~R8 + Phase 0 API 인덱스 ├── engine/ ★★ Python 엔진 (단일 진입점: python3 -m engine) │ ├── fetch_chain.py 1,332줄 — probe→validate→detect→plan→execute │ ├── phase0.py 공식 공개 API 라우터(Reddit/X/YouTube…) │ ├── validators.py 4계층 검증 · Verdict 분류 · 챌린지 마커 │ ├── waf_detector.py WAF 랭킹 감지 알고리즘 │ ├── waf_profiles.yaml 제품별 프로파일(detectors·tls·capabilities) │ ├── executor.py capability→브라우저 실행기 매칭 │ ├── transport.py curl_cffi 전송 계층 │ ├── url_transforms.py 모바일/am/drop-www URL 변형 규칙 │ ├── content_safety.py R8 — untrusted 웹 본문 경계 래핑 │ ├── auto_forge.py 숨은 데이터 API 자동 발굴 │ ├── recipe_loader.py recipes/<도메인>/recipe.yaml 로딩 │ ├── bias_check.py No-Site-Name 린터(CI 게이트) │ ├── learning.py · observations_log.py 라우트 학습 · append-only 관측 │ ├── templates/*.js|py Playwright real/mobile · patchright · nodriver │ └── tests/ 22개 회귀 테스트(오프라인 모킹) ├── references/ 14개 md — tls-impersonate·twitter·naver·media… ├── recipes/<도메인>/recipe.yaml scraper-forge 산출물(격자 전 API 직행) ├── scripts/endpoint_miner.py 정적 API 마이닝 └── tests/coverage_battery.py 플랫폼 전수 경로 pass/fail + 썩은 예시 적발

구조가 말하는 것: 지식은 코드가 아니라 데이터/설정에 산다. 뚫는 방법(제품별 프로파일)은 waf_profiles.yaml에, 플랫폼 공식 경로는 phase0.py·references/에, 사이트 고유 힌트는 런타임 인자에만 둔다. bias_check.py가 "사이트명 하드코딩"을 CI에서 막아, 엔진이 특정 사이트에 유착되지 않게 강제한다.

6학습 포인트

스크래핑에 관심 없어도 훔쳐올, 안티프래질 설계·에이전트 하네스의 정석
배울 것 ①

에스컬레이션 사다리 — 실패를 "다음 단계 신호"로

하나의 방법에 올인하지 않고 비용이 낮은 것부터 높은 것으로(API→프로브→TLS위장→브라우저) 단계 상승하는 설계. 각 단계는 앞이 실패했을 때만 발동해 평균 비용은 낮게, 최악의 경우 성공률은 높게 가져간다. 재시도·폴백 시스템 전반에 통하는 사고틀이다.

배울 것 ②

HTTP/TLS 지문과 임퍼소네이션

봇 탐지가 User-Agent가 아니라 TLS 악수(JA3/JA4) 지문을 본다는 사실, 그리고 curl_cffi로 그걸 복제하는 법. 네트워크가 "누가 말하는가"를 어떻게 식별하는지 이해하면 보안·관측 양쪽에서 값지다.

배울 것 ③

"제품별 프로파일 vs 사이트별 하드코딩" — 일반화 규율

특정 사이트에 맞추면 당장은 쉽지만 곧 썩는다. 공통 축(WAF 제품)으로 추상화하고 사이트 고유 정보는 런타임으로 밀어내는 규율, 그리고 그걸 bias_check.pyCI에서 강제하는 방법. 규칙을 문서가 아니라 게이트로 지키는 사례.

배울 것 ④

검증 게이트 — "200 함정"을 피하는 법

성공을 상태코드가 아니라 콘텐츠 증거의 다층 AND로 정의하는 설계. 마커·크기·쿠키·셀렉터를 조합해 "받았지만 실은 차단 페이지"를 걸러낸다. 신뢰할 수 있는 자동화의 핵심은 "무엇이 성공인가"의 엄밀한 정의다.

배울 것 ⑤

웹을 읽는 에이전트의 프롬프트 인젝션 방어(R8)

외부 웹 텍스트를 untrusted_public_web으로 격리하고 명령이 아니라 데이터로 취급하는 경계 설계. LLM에 웹을 먹이는 모든 도구가 반드시 갖춰야 할 방어를 실제 코드(to_untrusted_text()·boundary id)로 본다.

배울 것 ⑥

에이전트-하네스 계약 — 엔진이 게으름을 막는다

R1~R8처럼 에이전트에게 강제되는 규칙을 두고, engine이 untried_routes·⛔ NOT EXHAUSTED로 "포기 금지"를 기계적으로 집행하는 설계. LLM의 즉흥 판단을 신뢰 가능한 절차로 묶는 하네스 패턴을 배운다.

실습 아이디어 (짧게)

플러그인 설치 후, 당신이 소유한 사이트나 공개 문서 URL로 python3 -m engine "<URL>" --trace를 돌려 result.trace를 읽어라. probe→detect→plan→execute가 어떤 순서로 무엇을 시도했는지, verdict가 어떻게 매겨졌는지 눈으로 따라가면 에스컬레이션의 실체가 잡힌다.

7시스템 요구사항 · 경계(Boundaries)

설치는 한 줄, 실행은 자동 — 그러나 "어디서 멈추는가"가 이 도구의 정체성
항목내용
플랫폼Claude Code 플러그인. /plugin marketplace add …/gptaku_plugins.git/plugin install insane-search@gptaku-plugins/reload-plugins.
런타임Python 3(엔진). Playwright 로컬 경로 사용 시 Node. 필요 패키지는 첫 실행 시 자동 설치(curl_cffi≥0.15·bs4·pyyaml·pypdf·markdownify).
키·프록시불필요. API 키도, 가입도, 프록시 설정도 없다.
진입점python3 -m engine "<URL>" 하나. Phase 0 자동 + 실패 시 격자→브라우저 에스컬레이션.
라이선스MIT (© 2026 fivetaku). DISCLAIMER는 이중 용도·무보증·사용자 책임을 명시.
경계 — 반드시 이해할 것
공개 콘텐츠 전용 · 인증은 넘지 않는다 · 사용자 책임

insane-search는 공개 페이지·공개 API·피드·아카이브·브라우저의 공개 응답으로 닿을 수 있는 것만 읽는다. 로그인·페이월에서 멈추고 authentication required라고 보고하며, 대신 로그인하지 않고 자격 증명을 저장·전송하지 않는다. 인증 우회·접근 통제 회피·무단 접근 도구가 아니다. 동시에 이건 이중 용도 도구라, 대상 사이트의 이용약관·관련 법 준수와 정당한 권한 확보는 전적으로 사용자 책임이다. 이 딥다이브는 아키텍처 학습용 정리이며, 실제 수집 전에는 각 플랫폼 규정을 확인하라.

8직접 해볼 수 있는 실습 과제

trace 읽기부터, WAF 프로파일 해부·검증 재현까지 (전부 공개/자기소유 대상으로)

과제 1. trace로 에스컬레이션 관찰 난이도 ★☆☆

공개 문서나 본인 소유 사이트 URL로 python3 -m engine "<URL>" --trace --json을 돌려, probe→detect→plan→execute 각 시도의 transform×impersonate×referer 조합과 verdict를 표로 정리하라. 목표: "단계 상승"이 실제로 어떻게 도는지 체감.

과제 2. 4계층 검증 재현 난이도 ★★☆

engine/validators.py를 읽고, "200이지만 챌린지 페이지"·"200이고 진짜 본문" 두 응답을 만들어 네 계층(마커·크기·쿠키·셀렉터)이 각각 어떻게 판정하는지 확인하라. 목표: 성공을 상태코드가 아니라 증거로 정의하는 법.

과제 3. WAF 프로파일 한 개 해부 난이도 ★★☆

waf_profiles.yamlcloudflare_turnstile 또는 datadome 프로파일을 골라 detectors·capabilities_needed·tls_candidates가 무엇을 의미하는지 주석으로 풀어 보라. 목표: "제품별 일반화"가 어떻게 사이트 무관 커버리지를 만드는지 이해.

과제 4. bias_check 통과/실패 만들기 난이도 ★★☆

engine/에 일부러 if "example.com" in url 같은 사이트 분기를 넣고 python3 engine/bias_check.py가 잡아내는지 확인한 뒤 되돌려라. 목표: 규칙을 CI 게이트로 강제하는 설계를 체험.

과제 5. R8 언트러스티드 경계 실습 난이도 ★★★

content_safety.pyto_untrusted_text()·boundary 래핑을 읽고, "본문에 가짜 지시가 든 페이지"를 모킹해 그 지시가 명령으로 실행되지 않고 데이터로만 다뤄지는지 확인하라. 목표: 웹-읽기 에이전트의 프롬프트 인젝션 방어를 손으로 검증.

9관련 기술 심화 학습 로드맵

이 엔진을 온전히 이해하려면 밟을 5주 코스
주차주제무엇을 · 왜
1주차HTTP·TLS 지문TLS 핸드셰이크, JA3/JA4 지문, HTTP/2·3 핑거프린트. 봇 탐지가 UA 너머 무엇을 보는지. curl_cffi로 과제 1 실습.
2주차안티봇·WAF 생태계Cloudflare·Akamai·DataDome·PerimeterX·Kasada의 감지 신호(쿠키·인터스티셜·센서). 제품별 프로파일로 과제 3.
3주차헤드리스 브라우저 · CDP 스텔스Playwright/CDP, Runtime.enable 누출, patchright·nodriver의 스텔스 원리, 네트워크 트래픽 캡처(숨은 API).
4주차콘텐츠 추출 · 검증OGP/JSON-LD 메타, 마크다운 변환, 본문 추출, "성공의 정의"(4계층). 과제 2로 검증 재현.
5주차에이전트 하네스 · 프롬프트 인젝션도구를 절차로 묶는 하네스(R1~R8), 실패 게이트, untrusted 웹 경계. 과제 4·5로 마무리. 법·ToS 준수 원칙 병행.

10핵심 키워드 사전

이 문서에 나온 개념들을 한 줄로
Phase 0→3 에스컬레이션
공식 API → 경량 프로브 → TLS 위장 격자 → 진짜 브라우저로 단계 상승. 앞 단계가 막혔을 때만 다음 단계 발동.
TLS 임퍼소네이션 (curl_cffi)
실제 브라우저의 TLS(JA3/JA4) 지문을 복제해 "진짜 사파리/크롬"처럼 보이게 하는 기법. UA 변조보다 깊다.
WAF 프로파일 · No-Site-Name
뚫는 지식을 사이트가 아니라 WAF 제품별로 저장. 사이트명 하드코딩은 bias_check.py가 CI에서 금지.
4계층 검증 (validate)
챌린지 마커·크기·쿠키 센서·success_selectors의 AND. HTTP 200은 성공이 아니라 검사 시작 조건.
verdict (strong_ok / weak_ok)
셀렉터로 콘텐츠가 증명되면 strong_ok, 미제공이면 weak_ok. SUSPECT_OK는 비terminal — 계속 탐색.
capability-matched executor
WAF 프로파일의 capabilities_needed 태그로 브라우저 실행기 자동 선택(protocol_stealth·real_chrome·MCP·mobile).
patchright · nodriver
Playwright 포크/raw CDP. 자동화 프로토콜(Runtime.enable) 지문화를 회피하는 스텔스 브라우저 경로.
scraper-forge · auto-forge
렌더 중 XHR을 캡처해 사이트 내부 JSON API를 발굴·재현하고 recipe.yaml로 저장. auto-forge는 이를 자동화(opt-in).
Phase 0.5 recipe
recipes/<도메인>/recipe.yaml이 있으면 격자 전에 그 공개 API로 직행. 막힌 HTML 페이지를 열린 JSON API로 매핑.
실패 게이트 (R6)
untried_routes·grid_exhausted·must_invoke_playwright_mcp가 다 충족돼야 "포기" 허용. CLI ⛔ NOT EXHAUSTED로 집행.
untrusted_public_web (R8)
가져온 웹 본문은 명령이 아니라 데이터. to_untrusted_text()·boundary id로 프롬프트 인젝션 차단.
429 ≠ terminal
rate-limit는 진짜 벽이 아님 — TLS 격자는 멈추되 백오프 후 브라우저/MCP 재접근은 살아있다. auth/404만 terminal.

11참고 링크

원문으로 더 파고들기 (경계 재확인)