python3 전폐 2단계 재파일럿 — 4096 보강 후 통과 (2026-07-27)
개요
[[2026-07-27-python전폐-파일럿-4096절단발견]]에서 롤백된 디자인이식가드.sh crownyc 전환을,
입력()(stdin) 4096 절단을 원천 회피하는 방식으로 재작업해 재파일럿.
직전 롤백 사유였던
보안 회귀(5000자 패딩 뒤 sed -i 파괴패턴이 절단으로 통과)가 이번엔 정확히 차단됨을 실측 확인.처방 (보강 방식)
- 실측 확정:
읽기(경로)는 4096 절단 없이 ~64KB까지 온전(가드레일 §284, §233). 입력()(stdin)만
C
fgets(buf[4096])로 4095B 초과 1행을 조용히 자른다.
- 셸이 stdin payload를 고유 임시파일(
mktemp)에 저장 → 환경변수 JIN에 그 경로를 담아
crownyc run 훅JSON추출.toau에 전달 → 한선씨가
읽기(JIN)로 읽는다. command는 통상
64KB 이내라는 가정 위에서 동작(64KB↑는 이번 범위 밖, 별도 청크/버퍼파일읽기 우회 필요).
libs/훅JSON추출.한선 수정: JIN 환경변수가 있으면 읽기(JIN), 없으면 기존 입력()으로
하위호환 폴백(구 호출부·경량 A유형 다른 훅에 영향 없음). STRICT 0 컴파일.
~/.claude/scripts/디자인이식가드.sh 재전환: mktemp 임시파일 + trap 'rm -f "$TMPJIN"' EXIT
정리, 모든 crownyc 호출
2>/dev/null. python3 백업 =
~/.claude/scripts/.bak-4096보강/.
4096 보안테스트 (전/후 — 이번 재파일럿의 핵심 게이트)
레지스트리(
이식대상.psv)에서 원본dir을 동적으로 읽어 조립(훅 자기차단 회피 — 테스트 스크립트
자체의 명령줄엔 원본경로+파괴동사 리터럴이 등장하지 않음). 5060바이트 명령(4990자 패딩 +
sed -i 파괴패턴, 표적 =
/Users/ef/crowny-vision/디자인정본)으로 구성.
| 경로 | 추출된 command 길이 | 원본dir 문자열 보존 | 판정 |
|---|
| 구방식(stdin 파이핑, JIN 미사용) | 4046 / 5060 | 소실(절단) | 탐지 불가 — 직전 롤백 재현 |
| 신규(JIN + 읽기()) | 5060 / 5060 (전량) | 보존 | deny 정확 차단 |
회귀 5케이스 (전부 PASS)
- 원본 Write → deny
- 산출dir Write → 통과
- 무관 이벤트(tool_name=Read) → exit 0
- 파괴 Bash(sed -i 원본 표적) → deny
- cp 원본→산출(읽기전용 소스) → 통과
fail-closed 보강 (설계 중 발견한 함정 1건)
- crownyc는
.toau 파일이 없거나 로드 실패해도 자체 exit code는 0을 낸다("파일 열기 실패"는
stderr뿐) — RC만으론 추출 실패를 못 잡는다. 이중 신호로 판정하도록 수정: ①RC≠0(바이너리 자체
exec 실패, 예 127) ②TOOL_NAME/FILE_PATH/COMMAND가 빈 값(Claude Code 훅 payload 스키마상
Write/Edit/Bash 이벤트는 이 필드가 항상 존재 — 빈 값은 추출 파이프라인 실패로 간주).
.toau 경로를 무효화한 사본으로 재현 검증 → 정확히 deny(fail-closed) 확인.
- 훅JSON방출.toau 자체가 죽는 최악의 경우까지 대비해
_deny_raw()(printf 고정 JSON, 사용자
입력 미삽입이라 이스케이프 불필요) 안전망 추가.
성능
- 대표 Bash payload(무관 명령) 20회 평균: 구(python3) 47~74ms/run vs 신규(crownyc/JIN)
33~37ms/run —
게이트(+50ms 이내) 여유롭게 통과, 오히려 −11~−40ms 개선(측정 편차 있으나
항상 신규가 더 빠름).
자체테스트
디자인이식-자체테스트.sh →
ALL_PASS 8/8 (register/guard×2/diff×3/PreToolUse훅/PostToolUse게이트).
학습
crownycode-brain.sh learn "훅JSON추출" libs/훅JSON추출.한선 → exit1("이미 존재", 기존 학습
엔트리 유지 — 신규 아님이라 미갱신은 정상),
run "훅JSON추출" lookup HIT 확인.
관련 파일
/Users/ef/CrownyOS/crownyc/libs/훅JSON추출.한선 (JIN 보강, 폴백 유지)
/Users/ef/CrownyOS/crownyc/libs/훅JSON추출.toau, libs/훅JSON방출.toau (프리컴파일 배치)
/Users/ef/.claude/scripts/디자인이식가드.sh (재전환, fail-closed)
/Users/ef/.claude/scripts/.bak-4096보강/디자인이식가드.sh.bak.20260727-112047 (python3 백업)
/Users/ef/CrownyOS/crownyc/tools/python전폐-2단계-스펙.md (SSOT 스펙, §3.1/§7)
/Users/ef/.claude/templates/한선씨-가드레일.md §233(VM read 4096 공통한계)·§284(읽기() 64KB)
잔여 이슈
- command가 64KB(읽기() 절단 한계)를 넘는 극단 케이스는 이번 범위 밖 — 필요 시 청크 read/
버퍼파일읽기 우회 별도 작업.
- 나머지 12개 고위험 훅(마일스톤 2)은 이 패턴(JIN+읽기(), fail-closed 이중신호)을 그대로
적용해 순차 전환 가능 — 스펙 §4 마일스톤 표 참조.
- 30분 라이브 관찰(스펙 §3 절차 4)은 이 세션 범위 밖 — 다음 세션이 에러 로그 확인 후 마일스톤 1 착수 판단.
★파서 정직성 실측 (사용자 질문: 제대로 구현 vs 억지 1:1, 2026-07-27)
훅JSON추출.한선 = 얇은 래퍼, 실제 파싱=JSON본문파서.한선의
json본문_키찾기+
json본문_문자열값_이스케이프.
- 제대로인 부분(문법 인지): ①
"키": 뒤 : 확인(값 문자열 안 미끼 키 방어 실측 PASS) ②이스케이프 \" 정확복원(echo \"hi\" > x→온전) ③\uXXXX→한글 디코드. = 억지 문자열찾기 아님.
- 한계(구조 평면): 재귀 JSON 파서 아님 = 중첩 경로 못 따라감.
tool_input.file_path 지정 불가, file_path 첫 등장만 잡음. 실측: {"tool_response":{"file_path":"WRONG"},"tool_input":{"file_path":"RIGHT"}}→WRONG(오추출).
- 판정: 용도한정 파서(훅 평면 payload엔 충분·억지 아님, python json.load 범용 1:1은 아님).
- ★배치 전환 가드: PreToolUse(tool_input만)=안전(디자인이식가드 현재 무위험). PostToolUse 훅(tool_input+tool_response 양쪽 같은 키)에 쓰면 ③ 오추출 위험 → PostToolUse 전환 시 (a)키 경로 인지 파서로 보강 or (b)tool_input 블록만 슬라이스 후 추출. 억지로 첫등장 쓰지 말 것.