수정 2026-07-14
v1.36.18
UR-0052: handoff --compact 단일경로 + ID 5자리+ 대응 (P2-6 주석 마스킹은 조사 후 이연)
파서 없이 안전 구현 불가
핵심 변경
**P3-8 handoff --compact 단일 워크스페이스 무효**: --compact가 멀티(_handoffWorkspace)에만 있어 단일 handoff . --compact는 섹션 몇 개만 억제하고 본문 186줄 전량 출력 → 문서상 "~500자 요약"과 불일치. MCP handoff·REPL preview·agent-mode 등 내부 호출자 3곳이 단일 경로에 --compact를 써 preview 첫 3줄이 헤더/날짜/이름으로 무의미했음(재현: 186줄). → 단일 handoff()에 compact 단축 추가(subprocess 없이 파일 로더만으로 프로젝트/진척/메모리요약/다음액션/미답요청 3줄 압축, _lineSafe로 projectName 개행 주입 차단). 실측 186→3줄, --json은 여전히 full, preview 유의미화.
**P1-2 ID 리더 5자리+ 대응**: T-/M-/D-/R-/F- ID를 \d{4}(정확히 4자리)로 읽어, 10,000번째 ID(T-10000)부터 앞 4자리("1000")만 잡아 truncation/충돌(예: T-10000 뒤 task add가 T-1001 재발급)(재현확정). → letter-prefix ID의 \d{4}를 \d{4,}로 확장(bin 28·pure-utils 2·lib 9 = feature.js/audit.js/health.js/session-close.js 포함 — codex가 이 lib 누락을 지적). 판별자 (?!-)로 날짜 연도(\d{4}-)는 exactly-4 보존(불변 assert). \d{4,}는 4자리 ID도 매치해 무회귀. 실측: T-10000 뒤 add→**T-10001**, feature show F-10000 수용, 밀스톤 M-10000 카운트, 날짜 정상.
**P2-6 이연(조사 완료, 미채택)**: contract verify가 raw 소스를 훑어 주석처리된 // module.exports = { fn }을 실 구현으로 카운트하는 FN은 실재한다. 그러나 이를 고치려면 스캔 전 "주석만" 지워야 하고, JS에서 주석 경계를 정확히 찾으려면 정규식-리터럴/나눗셈/문자열/템플릿 보간(임의 코드)을 모두 렉싱해야 한다. 의존성 0(파서 금지) 제약 하에 손수 만든 마스커 3종(주석+문자열+정규식 마스킹 → 주석+문자열만 원문보존 → 줄머리 주석만)을 codex가 **7라운드 연속** 유효 JS에서 깨뜨렸다 — 특히 실코드를 지우는 **거짓 FAIL**(정당 계약을 CI에서 차단): if(x) /[/*]/의 /*를 유령 블록주석으로, ${/[}]/.test(x)?\n/* ${f.field} */\n:''}의 정규식 }를 보간 종료로 오계수해 중첩 템플릿의 실 필드를 삭제 등. CI 게이트에서 거짓 FAIL(정당 계약 차단) > 거짓 PASS(주석 export 카운트)이므로, **니치한 FN을 위해 현실적 거짓 FAIL 위험을 들이는 것은 순손해**로 판단하고 미채택. 근본 해법은 실 JS 파서(제약 위반)라 이연. contract verify는 기존 raw-소스 동작 유지(무회귀).