HT002 · macOS에 설치해서 돌려보기¶
2026-09-07, 과제는 한 문장이다: cppide를 clone 받아서 이 macOS에 설치하고, 돌아가게 만들어라. 결과는 $38.24 / 4 스텝 / 약 1시간, 프로그램은 실제로 macOS에서 돌아갔고(PID 96040, arm64 Mach-O), 판정 결론은 달성 불가여서 사람에게 올라왔고, 사람은 수용을 선택했다.
이것은 목표 감시자를 처음 붙인 실행이다 —— HT001의 교훈에서 고쳐 나온 것들이고, 그날 전부 처음으로 실제 API 위에서 돌았다. 그것은 HT001이 빠졌던 함정 하나를 구해냈고, 동시에 방향이 정반대인 새로운 실패를 만들어냈다: git clone && make && ./cppide를 한 시간짜리로 만들어버린 것. 이 페이지에서 가장 값어치 있는 부분은 후자다.
원본 기록은 human-test/HT002/에 있고, 회계는 runs/manifest.json과 runs/sessions.db로부터 계산된다:
이번 실행의 형태¶
| 항목 | 값 |
|---|---|
| 과제 | cppide를 clone해서 이 macOS에 설치하고 돌아가게, 사람이 실제로 UI를 열어 쓸 수 있게 |
| 비용 | $38.24 —— 4개 스텝, 내역은 아래 |
| 소요 시간 | 약 1시간(합계 0.97h) |
| 턴 수 | 70(네 스텝의 num_turns 합) |
| 메인 스레드 컨텍스트 | 36.8K → 80.2K, 스텝 경계에서 절벽처럼 떨어짐, 단조 증가가 아님 |
| 분업 | subagent 6개; 코디네이터 도구 호출 7회 vs subagent 212회 |
| 캐시 | 적중률 90.8% |
| 워크벤치 | 산출물 5개, 노트 4개, 스필 11개, 재사용 가능한 스크립트 0개 |
| 결과 | 돌아감(PID 96040, arm64 Mach-O); 판정은 달성 불가, 사람이 수용을 선택 |
| 버전 | 목표 감시자를 붙인 첫 번째 실행 |
스텝별 비용, 턴 수, 소요 시간¶
| 스텝 | 비용 | 턴 수(num_turns) | 소요 시간 |
|---|---|---|---|
| 요구 확인 | $0.5306 | 9 | 0.10h |
| 목표 설정 | $0.4117 | 12 | 0.05h |
| 작업 | $35.8950 | 12 | 0.73h |
| 작업·판정#1 | $1.4037 | 37 | 0.09h |
| 합계 | $38.2409 | 70 | 0.97h |
소요 시간 열은 각 스텝을 반올림한 뒤 더한 값이다. 원본 기록으로 재계산하면 manifest.json 안의 네 개 duration_s 정확한 합은 3471.53초 = 0.9643h다. 이 페이지는 0.97h를 그대로 쓰며, 둘의 차이는 0.006h다.
돈은 거의 전부 "작업" 스텝에 있다 —— $35.8950이 93.9%를 차지한다. 아래 첫 절이 이 돈이 어디에 쓰였는지, 그리고 왜 원래는 이렇게 쓰이지 않았어야 하는지를 설명한다.
1. 헤드라인: git clone && make && ./cppide를 한 시간으로 만들었다¶
이번에 가장 중요한 발견이고, 아래의 모든 "메커니즘이 돌았다"보다 중요하다.
목표 설정 스텝에서 판정자는 자기 자신에게 15개짜리 판정 체크리스트를 써줬다 (원문은 .flower/notes/ 아래 目标.md). 성격별로 나누면:
| 분류 | 개수 | 예 |
|---|---|---|
| 정말로 "물건이 쓸 만한가"를 검증 | 약 5 | 빌드 exit 0; 프로세스 생존 ≥30초; 재시작 명령이 새 shell에서 재실행 가능 |
| "과정이 규칙을 지켰는가"를 검증 | 6 | ~/.zshrc / .zprofile / .bash_profile의 mtime이 모두 이번 세션보다 이름; brew install / npm -g / sudo를 실행하지 않음; .flower/의 mtime이 변하지 않음, runs/에 인위적 추가·삭제 없음 |
| 원리상 검증 불가 | 4 | 스크린샷 찍고 그림 보기; devtools console; 수동 클릭; 본인 확인 |
3분의 1만이 "이게 도대체 쓸 수 있는 물건인가"를 검증하고 있다. 여섯 개는 자기가 규칙을 지켰는지를 검증한다 —— 그중 하나는 .flower/ 디렉터리의 mtime을 검사하는데, 그건 프레임워크 자신의 디렉터리다.
.flower/를 검사하는 그 항목이 스스로를 실패로 판정했다¶
이건 이론적인 문제가 아니다. 판정 라운드에서 판정자는 "미통과" 항목에 사실대로 이렇게 썼다:
.flower/아래 파일 mtime이 모두 세션 시작보다 이름 —— 문자 그대로 실패:INDEX.md16:14,artifacts/01–05(15:40–16:12),notes/决策-项目形态与验收路径.md15:43 모두 세션 중에 쓰였다.
원인은 이렇다: 프레임워크가 긴 산출물은 .flower/artifacts/에, 결정은 .flower/notes/에 쓰도록 강제한다. 판정 체크리스트의 그 항목은 이 디렉터리를 건드리지 말라고 요구한다. 두 규칙이 정면으로 충돌하고, 그것도 판정 체크리스트가 스스로 만들어낸 충돌이다 —— 실행자가 긴 산출물을 하나도 쓰지 않았다면 오히려 더 규칙에 맞았을 것이다.
그것은 얼버무리지 않았다: 작업 스텝의 최종 보고서에 이 충돌을 스스로 명시했고, 결정 기록에도 처리 방식을 적었다 —— 기존 파일은 하나도 건드리지 않음 (需求.md, 目标.md, 问答记录.md 세 개의 mtime과 MD5가 전후 동일), 추가만 함. 판정자는 재검토 후 "이 항목이 막으려던 변조는 일어나지 않았다"에 동의했지만, 그래도 규칙대로 미통과에 넣고 사람에게 넘겼다.
근본 원인 1: 경계가 판정 항목으로 취급됐다¶
사전 확인 단계에서 물어낸 경계("프로젝트 디렉터리 안에서만 설치할 것", "비즈니스 코드는 건드리지 말 것")는 원래 어떻게 작업할지를 제약하는 것인데, 결과적으로 산출물을 검증하는 체크 항목으로 쓰였다. 그래서 .zshrc mtime 검사, .flower/ mtime 검사 같은 항목이 생겼다.
경계 ≠ 판정 항목. 경계는 과정을 제약하고, 판정 항목은 결과를 검증한다. 이 둘이 섞이면 경계를 하나 더할 때마다 판정이 하나 늘어나는 셈인데, 하필 경계는 확인 단계에서 잔뜩 쓰도록 권장된다 —— CLARIFIER_RULES에는 "무엇을 하지 않을지 명확히 하라. 이 단락이 뒤따르는 모든 작업자를 통제한다"라고 명시돼 있다.
원본 기록을 대조하면 이 증폭 사슬의 각 고리가 보인다: 요구 확인서의 경계는 "현재 디렉터리 아래 기존 .flower/와 runs/는 건드리지 않는다"였는데, 판정 체크리스트에 와서는 ".flower/ 아래 파일의 mtime이 모두 이번 세션 시작보다 이름"으로 승격됐다 —— "기존 것을 건드리지 마라"에서 "디렉터리 전체에 새 파일이 있으면 안 된다"로 바뀐 것이다.
근본 원인 2: JUDGE_RULES에는 한 방향의 압력만 있었다 —— 그리고 그건 그날 추가된 것이다¶
그날 이른 시각, HT001의 교훈에서 JUDGE_RULES에 이런 것들을 써 넣었다:
- "각 항목은 반드시 그 자리에서 검증 가능해야 한다", "빠진 것, 모호한 것은 네가 채워라"
- "판정하는 것은 산출물이지 소스 코드가 아니다"(macOS 반례를 곁들여)
- "현재 환경에서 검증할 수 없는 항목은 그 자리에서 표시하라"
- "먼저 네가 어디에 있는지 확인하라(
uname -a가능)"
하나같이 더 많은 검사, 더 엄격한 쪽으로 민다. 규칙 전체에 "과제의 규모에 상응해야 한다"는 말은 한 줄도 없다.
즉, HT001의 "과도한 통과 선언" 실패를 겨냥해 최적화했더니 정확히 반대 방향의 실패 —— 과도한 검사를 만들어냈다. 이건 내가 만든 것이지 모델의 문제가 아니다.
근본 원인 3: issue #3과 겹쳤다¶
실제로 막힌 것은 macOS에서의 두 군데 이식성 결함이었다:
src/proc.cpp가::sigemptyset을 쓰는데, Apple SDK는 함수 프로토타입 뒤에 그것을 다시 함수형 매크로로 정의한다 (#ifndef _ANSI_SOURCE로만 가드됨). 그래서::sigemptyset(&s)가::(*(&s)=0,0)으로 전개되어 문법 오류src/ui.cpp가::_exit를 쓰면서<unistd.h>를 include하지 않음
세 줄이면 고칠 수 있다. 그러나 사용자가 확인 단계에서 "비즈니스 코드는 건드리지 마라"라고 답했고, agent는 이를 엄격히 집행했다. 그래서 우회해서 컴파일 flag를 시도하고, subagent를 파견하고, 결정 기록을 썼다. 만약 그가 그때 "그 두 줄은 고쳐도 괜찮다"고 한마디 끼워 넣을 수 있었다면 10분이면 끝났을 것이다. 경계를 금지령으로 쓰면 최대한 엄격하게 해석되며, 중간에 풀어줄 통로가 전혀 없다.
원본 기록을 보면 이 우회가 얼마나 길었는지 알 수 있다: 총 네 개의 차단 지점이 있었고, 그중 순수 컴파일 flag로 해결 가능한 것은 ::_exit 하나뿐이었다. ::sigemptyset 쪽은 6개 조합의 -D/-U를 시도해 전부 실패했다 (_POSIX_C_SOURCE 계열은 덤으로 st_mtimespec과 O_CLOEXEC까지 망가뜨린다). 이 막다른 길 자체가 13.6K짜리 타당성 보고서를 하나 만들어냈다.
그러나 공정하게: 경계가 더 나은 해법을 짜냈다¶
최종 방안은 소스 코드 수정이 아니라, Makefile 안에서 #undef만 하는 심(shim) 헤더를 생성한 뒤 -include로 강제 선행시키는 것이었다:
$(MACSHIM):
@printf '#include <signal.h>\n#undef sigemptyset\n#undef sigfillset\n...' > $@
CPPFLAGS += -include $(MACSHIM) -include unistd.h
이게 소스 수정보다 낫다 —— 업스트림 저장소를 한 줄도 안 건드리고, 누구든 clone하면 빌드된다. 심은 build/에 생성되어 저장소에 들어가지 않고, clean에 rm -rf build를 추가해 회수하며, make -n UNAME_S=Linux를 실측했더니 전개 결과에 -include가 없어 Linux 경로는 오염되지 않았다. 최종 git diff는 Makefile 파일 하나뿐, +14 / −2.
그러니 경계가 만들어낸 것은 더 높은 비용의 더 나은 해법이다. 문제는 그것이 틀렸다는 게 아니라, 이 트레이드오프를 사람이 하지 못했다는 것 —— 그리고 그걸 못한 이유가 바로 issue #3이다.
왜 git status에 64개가 뜨는데 소스 변경이 0이라고 말하는가
cppide 저장소는 30개의 .o, 30개의 .d, 2개의 바이너리를 버전 관리에 커밋해 두었고, 그것도 Linux ELF aarch64이며 mtime이 .cpp보다 늦다 —— 먼저 make clean을 하지 않으면 make가 컴파일을 건너뛰고 바로 ELF를 가져다 링크해서 반드시 깨진다. 그래서 git status --porcelain의 64개 중 63개는 git이 추적 중인 컴파일 산출물이고 나머지 하나는 ?? build/다. 확장자로 필터링하면 git diff -- 'src/*.cpp' 'src/*.h' README.md config.sample.json | wc -c는 0이다. 이 정확한 표현은 컴플라이언스 감사가 짜낸 것이다 —— 코디네이터는 원래 뭉뚱그려 "src/ 변경 0"이라고 쓰려 했고, 감사가 그 문장이 성립하지 않는다고 지적했다.
2. 목표 감시자가 잘한 것¶
메커니즘 쪽은 전부 돌았고, 그날의 두 가지 변경이 산출물에 직접적인 지문을 남겼다.
그것이 쓴 판정 체크리스트의 첫 항목:
uname -a가 Darwin 25.2.0(macOS)을 표시한다…… 아래 모든 "돌아간다/열린다" 항목은 이 머신에서 실제로 실행해 얻은 결과여야 한다. "소스에 macOS 분기가 있으니 돌아갈 것이다" 같은 추론은 받지 않는다
그건 바로 그날 아침 HT001의 교훈에서 JUDGE_RULES에 써 넣은 문장이다.
그것은 그날 추가한 [此环境无法验证:…] 표시를 세 번 사용했고, 각각 이유를 붙였다 —— devtools console(구동할 수 있는 브라우저가 없고, 이를 위해 헤드리스 브라우저를 설치하는 것은 경계를 넘음), 수동 클릭(사람이 화면 앞에 있어야 함), 본인 확인(그만이 줄 수 있음).
판정자의 첫 문장은 "나는 그 대화 문단을 보고 결론 내리지 않는다. 현장으로 간다." 그리고:
file cppide → Mach-O 64-bit executable arm64
lsof -p 96040 → txt 指向 /Users/hechenyu/explore/test-ide/cppide/cppide
起于 16:10,16:15 仍活着
그것은 스스로 이렇게 썼다: "meta 교훈에 있던 그 'Linux ELF를 납품' 함정, 이번엔 밟지 않았다. Linux ELF는 Darwin에서 PID로 살아 있을 수 없다. 이건 Makefile에서 추론해낸 게 아니다."
또 소스가 실제로 안 바뀌었음을 확인했다: src/ 아래 모든 .cpp / .h의 mtime은 전부 15:32(clone 시각)이고, 바뀐 것은 Makefile(16:06)뿐이며, .o / .d(16:07)는 추적 중인 컴파일 산출물의 재생성이다.
손이 닿지 않는 곳도 사실대로 밝혔다. 판정자의 Bash는 작업 디렉터리 안으로 제한되어 있어서, git ls-remote 대조와 ~/.zshrc의 mtime은 실행할 수 없었고, 독립 감사의 출력을 신뢰하는 수밖에 없었다 —— 이 두 항목은 따로 떼어 "내 손으로 재실행하지 못했다"고 설명했다.
3. "달성 불가"로 판정하고, 사람에게 묻다¶
3상태 판정 + 사람 개입, 전체 경로가 처음으로 실제로 돌았다.
판정 결론은 달성 불가였고, 스크린샷 항목에서 막혔다: screencapture -x와 -l <window-id> 모두 could not create image from display를 반환했다 —— 화면 녹화 TCC 권한이 부여되지 않았고, 권한 부여는 사람이 시스템 설정에서 클릭해야 하는데, 그 자체가 경계에서 금지한 시스템 변경이다.
"subagent를 한 라운드 더 파견해도 이 그림은 나오지 않는다. 규칙상 통과로 판정할 수 없고, '미달성'으로 판정해서도 안 된다. 그것은 그냥 달성 불가이고, 멈춰서 사람에게 넘겨야 한다."
그래서 체크리스트에서 "원리상 검증 불가" 항목은 3개에서 4개가 됐다 —— 15개 중 4개가 이 환경에서 아예 검증 불가였고, 이 사실은 $35.8950의 작업과 $1.4037의 판정을 써버린 뒤에야 발견됐다. 목표 설정 스텝은 $0.4117밖에 쓰지 않았고, 그때 발견했어야 했다.
프레임워크는 이 결론을 사람에게 물었고(문답 기록 q7에 기록), 세 가지 선택지 중 사람은 "이 결과를 수용한다"를 골랐고, gate가 통과되어 워크플로가 완료됐다.
그것은 대체품 하나를 거절하기도 했다. 실행자는 AppleScript로 터미널 창 텍스트를 읽어왔고, 그것은 실제로 렌더링된 TUI였다 —— 행번호 열, src/main.cpp 본문, ─[编译]─[运行]─[AI*]─[输入]─ 패널 바, 练习模式 │ main.cpp │ 1:1 │ C++ 상태 바. 흰 화면도 에러 화면도 아니었다. 판정자는 이렇게 말했다:
"작업한 쪽이 이걸 '그림을 봤다'로 사칭하지 않았다. 이 자기 절제는 옳다. 하지만 그것은 체크리스트가 요구한 항목을 대체할 수 없고, 나도 그를 대신해 계산해주지 않는다."
"리스크를 공개했다"는 통과가 아니다
HT001이 빠진 게 바로 이것이다: "macOS에서 한 번도 돌려보지 않았다"를 납품 설명에 써 넣고도, 여전히 검수 1을 통과로 판정했다. HT002에서 판정자는 더 나은 대체 증거(실제 TUI 텍스트)를 손에 넣고도, 그것으로 체크리스트 항목을 대신하기를 거부했다. 이 차이가 판정 3상태 설계의 존재 이유 전부다 —— UNREACHABLE은 NOT_YET의 완곡한 표현이 아니라, "멈추고 사람에게 물어야 한다"는 뜻이다.
4. allowed_tools는 하드 화이트리스트가 아니다¶
이번 실행을 분석하다가 주장과 어긋나는 사실을 하나 발견했다. 세션별로 도구 호출을 쪼개 보면:
| 세션 | 실제로 쓴 것 | 화이트리스트에 있는 것 |
|---|---|---|
| 요구 확인 | WebFetch, Glob, ask×6 | 당시 clarify()는 ask + Read/Glob/Grep만 줬음 |
| 목표 설정 | Bash ×11 | judge()는 기본 can_run=False, Bash 없음 |
| 작업·판정 | Bash ×31, WebFetch | 위와 같음 |
| 작업(코디네이터) | Bash ×1, Agent ×6 | 정상 |
goal_step에는 can_run을 넘기는 코드 경로가 전혀 없다. 따라서 "목표 설정" 행은 설정 문제일 수 없다.
$0.1짜리 프로브 검증: allowed_tools=["Read"]인 agent에게 파일을 쓰라고 시켜봤다 ——
Write → 权限层:"requested permissions to write ... but you haven't granted it yet"
Bash → 路径安全:"Output redirection was blocked. For security, Claude Code may
only write to files in the allowed working directories"
모델은 화이트리스트에 없는 도구도 호출할 수 있다. 다만 permission 계층과 경로 보안에 막힐 뿐이다. 그러므로:
allowed_tools는 승인 면제 목록이지 배타적 화이트리스트가 아니다- 당시
clarify()/judge()를 실제로 보호한 것은 상속받은permission_mode="default"였다 - 그리고 이 둘은
delegate_only=False→delegate_guardhook이 없었다. 코디네이터는 hook이 지켜주지만, 이 두 역할은 당시 flower 자신의 메커니즘이 전혀 없었다
clarify()의 docstring에는 "쓰기 도구를 주지 않는다 —— 작업을 시작할 수 없다"라고 쓰여 있고, $0.8908짜리 반례 실측 전체가 이 문장을 위한 것이었다. 이 문장의 메커니즘적 근거는 틀렸다.
이 절의 두 사실은 나중에 둘 다 바뀌었다
whitelist_guard는 이미 무조건 연결됐다: delegate_only=False인 역할은 이제 Runtime이 이 hook을 자동으로 붙이며, clarify() / judge()는 더 이상 "메커니즘이 전혀 없는" 상태가 아니다. 또한 WebFetch는 이제 clarify()의 화이트리스트에 들어 있어서, 표 첫 행의 그 예시는 이미 폐기됐다 —— 결론은 여전히 성립하지만, 이제 $0.1 프로브라는 증거 하나에만 의존한다. 자세한 내용은 이 페이지 마지막 절 참조.
5. 컨텍스트 곡선: 스텝 경계에서 리셋된다¶
네 개 샘플링 지점 중 셋(1 / 25 / 121번째 턴, 36.8K / 80.2K / 64.8K)은 원본 기록과 하나씩 일치한다. 26번째 턴의 32.9K는 재계산하면 맞지 않는다: store_key 순으로 메인 스레드 assistant 메시지를 재생하면 26번째(새 세션의 첫 번째)의 input + cache_read + cache_creation은 31,972 token = 32.0K이고, 32.9K는 같은 세션의 두 번째 값(31,970 + 948)이다. 이 페이지는 32.9K를 유지한다 —— 차이는 0.9K이고, "절벽처럼 떨어진다"는 결론은 두 값 모두에서 성립한다.
HT001은 185.9K까지 단조 증가했다 —— 한 스텝이 10시간 돌았다. HT002는 네 스텝으로 나누고 스텝마다 새 세션을 열었기 때문에 컨텍스트가 구조적으로 리셋됐다. 이것은 "요구 확인서와 목표는 동결물이고, 하류는 문서만 받지 대화는 받지 않는다"는 설계의 직접적 효과다 —— 곡선에서 눈에 보인다.
캐시 적중률은 90.8%(HT001은 96.1%). 적중률은 세션 길이에 따라 올라가므로, 짧은 세션은 오히려 단가가 조금 더 비싸다 —— 이건 HT001 3절의 결론과 같은 동전의 양면이다.
6. HT001과의 대조¶
| HT001 | HT002 | |
|---|---|---|
| 과제 | 밑바닥부터 터미널 IDE 작성 | 그것을 macOS에 설치해서 돌리기 |
| 비용 / 시간 | $171.62 / 10.44h | $38.24 / 0.97h |
| 스텝 | 2(목표 감시자 없음) | 4(목표 설정 + 판정 포함) |
| subagent | 23개 | 6개 |
| 코디네이터 도구 호출 | 32 | 7(그중 6회가 Agent) |
| subagent 도구 호출 | 1,893 | 212 |
| 메인 스레드 컨텍스트 | 28.7K → 185.9K 단조 증가 | 36.8K → 80.2K, 스텝 경계에서 리셋 |
| 캐시 적중 | 96.1% | 90.8% |
| 워크벤치 스크립트 | 58개, 331회 실행, 92% 재사용 | 0개 |
| 판정 | 없음(코디네이터의 자발적 내부 감사) | 3상태 판정, "달성 불가" 판정, 사람에게 질문 |
마지막 행이 주목할 만하다. HT002는 재사용 가능한 스크립트를 하나도 쓰지 않았다 —— 과제가 한 시간짜리여서 축적할 만한 게 없었다. 이것은 워크벤치의 가치가 과제 길이에 따라 증가한다는 것을 보여준다. 짧은 과제에서 그것은 순수한 오버헤드다.
원본 기록은 어떻게 생겼나¶
.flower/INDEX.md는 이번 실행이 끝났을 때의 워크벤치 스냅샷이고, 바로 대조해 볼 수 있다:
| 디렉터리 | 내용 |
|---|---|
scripts/ | 0개 |
artifacts/ | 5개 —— 01-recon.md(32.6K), 02-build-run.md(19.4K), 03-flag-only-feasibility.md(13.6K), 04-compliance-audit.md(16.4K), 05-final-build-run.md(19.8K) |
notes/ | 4개 —— 需求.md, 目标.md, 问答记录.md 세 개는 프레임워크가 쓴 동결물이고, agent가 직접 쓴 결정 기록은 1개뿐 |
spill/ | 스필 11개 |
runs/ 아래에는 manifest.json(스텝 기록 4건)과 sessions.db가 있다. 데이터베이스에는 세션 10건이 있다: 메인 스레드 세션 4건 + subagent 세션 6건 —— "subagent 6개"와 맞아떨어진다.
문답 기록에는 총 7개 질문이 있다: q1–q6은 사전 확인 단계에서 물은 것이고 (요구 확인 스텝의 ask 호출 6회와 맞아떨어진다), q7은 "달성 불가" 판정 이후의 수동 게이트다.
이번 실행이 프레임워크를 어떻게 바꿨나¶
| 발견 | 반영된 변경 |
|---|---|
| 15개 판정 체크리스트 중 약 5개만이 쓸 수 있는지를 검증(1절) | JUDGE_RULES에 역방향 압력 추가: 체크리스트 길이는 실패 방식의 수가 결정하지, 엄밀함의 정도가 결정하지 않는다. 그리고 이번 건을 반례로 규칙 원문에 기입("한 번의 '설치해서 돌리기' 과제가 15개 항목으로 쓰였고, 그중 5개만이 쓸 수 있는지를 검증했다" —— 규칙에서는 반올림해 5로 적었고, 이 페이지 1절의 분류 기준은 약 5) |
| 경계가 판정 항목으로 쓰임 | JUDGE_RULES에 "경계는 판정 항목이 아니다"를 못 박아 씀 |
| 4/15 항목이 이 환경에서 검증 불가인데, $35.8950 + $1.4037을 쓴 뒤에야 발견 | 목표 설정 스텝에서 검증 불가 항목에 그 자리에서 [此环境无法验证:原因] 접미를 붙이도록 요구 —— 이번엔 3개는 제대로 썼고, 스크린샷 항목은 놓쳤다 |
clarify() / judge()에 hook 보호가 없음(4절) | whitelist_guard를 무조건 연결: delegate_only=False인 역할은 Runtime이 자동 장착하며, 더 이상 워크벤치 활성화 여부에 의존하지 않음 |
| 부작용: 목표 설정의 judge가 이제 Bash를 못 씀 | whitelist_guard가 생긴 뒤로, can_run=True를 명시적으로 넘기지 않으면 JUDGE_RULES의 "먼저 uname -a로 네가 어디 있는지 확인하라" 항목을 실행할 수 없다 —— 수정 후에 새로 생긴 트레이드오프다 |
clarify() docstring의 메커니즘 근거가 틀림 | 수정 완료. WebFetch도 clarify()의 화이트리스트에 들어가서 그 예시는 폐기되었고, 결론은 $0.1 프로브에 걸어 두었다 |
| 중간에 한마디 끼워 넣을 통로가 없음(1절 근본 원인 3) | issue #3으로 기록, 미해결 —— 이번엔 그것이 과도한 복잡화와 직접 겹쳤고, "그 두 줄은 고쳐도 괜찮다" 한마디면 한 시간을 아꼈다 |
이번 실행을 한 문장으로 요약하면: 지난번의 실패를 겨냥해 최적화하면, 방향이 정반대인 새로운 실패를 만들어내기 쉽다. HT001은 프레임워크에 "함부로 통과로 판정하지 마라"를 가르쳤고, HT002는 이 규칙에 "과도하게 검사하지 마라"가 짝지어지지 않았을 때 무슨 일이 벌어지는지를 곧바로 시연했다. 둘 다 JUDGE_RULES에 써야 하고, 하나라도 빠지면 치우친다.