관계적 일관성 엔진 (Relational consistency engine)
모든 핑거프린트 표면(fingerprint surface) — canvas, WebGL, audio, fonts, MediaDevices, WebGPU — 은 48개 규칙의 DAG(Directed Acyclic Graph)를 통해 단일 (profile, seed) 쌍으로부터 파생됩니다. 프랑켄슈타인식 핑거프린트는 없습니다. Mac UA(User Agent)가 Linux WebGL과 함께 나타나는 일은 결코 발생하지 않습니다.
mochi.js는 Bun 네이티브의 raw-CDP 브라우저 자동화 프레임워크입니다. 시드(seed)와 프로필(profile)을 전달하면, getParameter(0x9245) 탐지(probe)를 통과할 수 있는 관계적으로 일관된(relationally-coherent) 핑거프린트를 얻을 수 있습니다. JIT 친화적인 인젝션 페이로드(inject payload), Chromium 네이티브 fetch (정의상 실제 Chrome의 JA4), Bezier+Fitts 기반의 행동 합성(behavioral synth)을 제공합니다. 흔적을 전혀 남기지 않습니다.
Playwright와 Puppeteer가 핑거프린트를 남기는 곳에서, mochi.js는 측정 가능한 그 어떤 것도 남기지 않습니다. 각 기둥(pillar)은 한 종류의 탐지(detection) 클래스를 다룹니다.
모든 핑거프린트 표면 — canvas, WebGL, audio, fonts, MediaDevices, WebGPU — 은 48개 규칙의 DAG를 통해 단일 (profile, seed) 쌍으로부터 파생됩니다. 프랑켄슈타인식 핑거프린트는 없습니다. Mac UA가 Linux WebGL과 함께 나타나는 일은 결코 발생하지 않습니다.
session.fetch()는 CDP를 통해 Chromium 자체를 거쳐 라우팅됩니다 — 단순 GET 요청에는 Network.loadNetworkResource를, non-GET 요청에는 page.evaluate('fetch')를 사용합니다. JA4/JA3/H2는 정의상 실제 Chrome과 동일합니다. 보조를 맞추기 위한 병렬 HTTP 레이어가 없으며, 설치를 위한 FFI(Foreign Function Interface)도 필요하지 않습니다.
humanClick / humanType / humanScroll은 생체 역학 모델(biomechanical models)로부터 합성됩니다 — overshoot+correction이 포함된 Bezier 경로, Fitts-law 이동 시간, 로그 정규 분포(lognormal)의 digraph 지연 등을 사용합니다. 손, 떨림(tremor), wpm(분당 단어 수), scrollStyle 등 프로필 매개변수(Profile-parameterized)를 지원합니다.
실제 기기에서 캡처한 베이스라인(baselines)이 리포지토리에 포함되어 있습니다. 모든 PR은 라이브 세션의 Probe Manifest를 베이스라인과 비교(diff)하며, Zero-Diff는 CI 게이트(gate)로 작동합니다. 의도적인 차이(divergences)는 작성된 근거(rationale)와 함께 기록됩니다.
기존의 수동으로 짜 맞춘 파이프라인(Patchright + fingerprint-injector + Turnstile clicker + curl-impersonate)을 엔드 투 엔드(end-to-end)로 관리하는 단일 라이브러리로 대체합니다. Bun 전용입니다. Node, Python 사이드카(sidecars), 독점적인 요소(proprietary bits)는 없습니다.
import { mochi } from "@mochi.js/core";
// 세 줄로 스텔스 브라우저 부팅
const session = await mochi.launch({
...
import { mochi } from "@mochi.js/core";
// auto-click visible-checkbox Turnstile. Other variants → onEscalation.
const session = await mochi.launch({
...}
import { mochi } from "@mochi.js/core";
const session = await mochi.launch({ profile: "windows-chrome-stable", seed: "abc" });
const page = await session.newPage();
...