This repository was archived by the owner on Sep 8, 2026. It is now read-only.
Repository navigation
feat(reducer): 응답 그룹의 첫 행 순번을 UsageSelection 에 노출한다 - #375
Merged
Merged
Conversation
UsageReducer 는 한 어시스턴트 응답의 트랜스크립트 행들을 message id 로 묶고 그중
마지막 행을 고른다. 최종 usage 수치가 거기 있기 때문이다. 그런데 행 단위로
스냅샷을 찍으면서 "이 턴 직전에 컨텍스트로 무엇이 들어왔는가" 를 묻는 소비자는 그
선택을 쓸 수 없다. 마지막 행에 도달했을 때 그 답은 이미 여러 행 앞에서 관측되고
지워진 뒤다. group_first_row_ordinal 이 그 앞 지점이다.
- UsageSelection 의 **마지막** 필드로 추가한다. frozen dataclass 에서 기본값 있는
필드를 tokens 앞에 두면 import 시점에 TypeError 가 난다.
- finalize() 에서 min(candidate.row_ordinal for candidate in candidates) 로 채운다.
:293 의 first_for_group 은 no_id_fallback 카운터용 bool 이라 쓸 수 없고,
observe() 가 호출자가 준 순번을 그대로 받으므로 append 순서도 믿을 수 없다.
- REDUCER_SCHEMA 는 건드리지 않는다. statusline.sh:514 는 스키마가 어긋나면
오류 없이 조용히 캐시 지표를 끈다.
이 필드를 읽는 소비자는 아직 없다. audit 이 Gate-B 동결 경로라 별도 세대로
가야 하므로, 그 전에 리듀서 쪽만 먼저 올려 두 변경이 한 PR 에 섞이지 않게 한다.
지금 상태에서 audit 출력은 바뀌지 않는다.
함께 고친 것:
- tests/test_tool_result_token_estimate.py 의 _corpus 가 message id 를 msg_{index}
로 찍는데, test_small_results_and_cache_rewrites_are_not_samples 가 같은 범위를
두 번 이어 붙여 usage 행 80개가 id 40개로 접히고 있었다. 그 단언은 오랫동안 이
충돌 덕분에 통과해 왔다. id_offset 을 넣어 두 코퍼스를 분리한다. 단언값 40 은
수정 전후 모두 유지된다(확인함).
- 리듀서와 그 미러를 PROVIDER_FREE_SUPPORT_PATHS 에 선언한다. 둘 다 production
surface 인벤토리에는 있는데 선언 목록에는 빠져 있었다.
변이 4종이 모두 새 테스트에 잡힌다: 앵커를 선택된 행으로, min 을 max 로,
REDUCER_SCHEMA 상향, 패키지 미러를 갱신하지 않음.
검증: tests.test_context_guard_audit_turn_anchor 8건 OK,
tests.test_context_guard_usage_reducer_v2 + test_tool_result_token_estimate 59건 OK,
ci_test_gate fast 76건 OK, 실제 3.11 compileall exit 0,
sync_plugin_copies --check 동기화 확인, prepublish_check --skip-tests OK,
release_preflight 경고 없음.
주의: 변이 테스트 중 __pycache__ 가 남아 복원 후에도 낡은 바이트코드가 로드되는
현상을 겪었다. 리듀서를 반복 수정하며 테스트할 때는 캐시를 지우고 재실행할 것.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01DE3AupXcyv64SEuQeTckSh
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Team Run ID: Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
GLM 리뷰가 blocker 하나를 정확히 짚었다. 기존 픽스처는 전부 타임스탬프 순서와 순번 순서가 같은 방향이었고 관찰 순서만 뒤집혀 있었다. 그래서 "앵커 = 그룹에서 가장 이른 타임스탬프를 가진 행의 순번" 이라는 **다른 정의**가 스위트 전체를 통과했다. 소비자가 아직 없고 스키마도 올리지 않는 상황에서 이 스위트가 정의를 고정하는 유일한 장치인데, 정의의 축을 구분하지 못하면 고정이 아니다. 직접 확인했다. 새 테스트를 뺀 상태에서 구현을 타임스탬프 기반 정의로 바꾸면 그대로 통과한다. GLM 의 지적이 맞았다. 추가한 것: - 순번과 타임스탬프를 반대 방향으로 놓은 테스트 두 개(양방향). 낮은 순번이 늦은 타임스탬프를 갖게 해서, 선택은 타임스탬프를 따르고 앵커는 최소 순번을 따른다는 두 축이 서로 다른 답을 내도록 만들었다. - no-id fallback 그룹의 앵커 테스트. 행 해시로 묶이는 경로가 무점검이었다. 변이 2종이 새로 잡힌다: 타임스탬프 기반 정의(GLM 이 제시한 대안), append 순서 기반 정의(candidates[0]). GLM 의 non-blocker 도 반영했다. - 필드 계약 주석에 범위를 좁혀 적었다. 이 값은 그룹의 *usage 후보 행* 중 최소 순번이지 응답의 첫 행이 아니고, no-id fallback 그룹에서는 "그 행이 처음 나온 위치" 일 뿐 이 턴의 직전 문맥이 아니다. - REDUCER_SCHEMA 에 "필드를 덧붙이기만 하는 변경에서는 올리지 않는다" 를 적어, 다음 사람이 구조 변경 없이 bump 하는 실수를 막는다. - 테스트의 미사용 datetime import 를 지웠다. 검증: tests.test_context_guard_audit_turn_anchor 11건 OK, tests.test_context_guard_usage_reducer_v2 + test_tool_result_token_estimate 59건 OK, ci_test_gate fast 76건 OK, 실제 3.11 compileall exit 0, sync_plugin_copies --check 동기화 확인, prepublish_check --skip-tests OK. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01DE3AupXcyv64SEuQeTckSh
- no-id fallback 테스트의 "처음 나타난 위치" 표현이 관측 순서로 읽힐 수 있었다. 이 스위트가 다른 곳에서 없앤 모호성이라 "최소 순번" 으로 바꾸고, 픽스처가 순번 6 을 2 보다 먼저 관측한다는 사실을 docstring 에 적었다. 구현 주석도 같이. - selections[0] 을 쓰는 두 테스트에 len(selections) == 1 단언을 넣었다. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01DE3AupXcyv64SEuQeTckSh
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
왜
UsageReducer는 한 어시스턴트 응답의 트랜스크립트 행들을 message id 로 묶고 그중 마지막 행을 고른다. 최종 usage 수치가 거기 있기 때문이다. 그런데 행 단위로 스냅샷을 찍으면서 "이 턴 직전에 컨텍스트로 무엇이 들어왔는가" 를 묻는 소비자는 그 선택을 쓸 수 없다. 마지막 행에 도달했을 때 그 답은 이미 여러 행 앞에서 관측되고 지워진 뒤다.group_first_row_ordinal이 그 앞 지점이다.설계에서 확인한 것
tokens앞에 두면 import 시점에TypeError가 난다.min(candidate.row_ordinal for candidate in candidates)로 채운다.:293의first_for_group은no_id_fallback카운터용 bool 이라 쓸 수 없고,observe()가 호출자가 준 순번을 그대로 받으므로 append 순서도 믿을 수 없다.REDUCER_SCHEMA는 건드리지 않는다.statusline.sh:514는 스키마가 어긋나면 오류 없이 조용히 캐시 지표를 끈다.소비자는 아직 없다
이 필드를 읽는 코드는 이번 PR 에 없다.
claude_transcript_cost_audit.py가 Gate-B 동결 경로라 별도 세대로 가야 하므로, 리듀서 쪽만 먼저 올려 두 변경이 한 PR 에 섞이지 않게 한다. 지금 상태에서 audit 출력은 바뀌지 않는다 (리듀서 + audit 스위트 59건이 그대로 통과).함께 고친 것
픽스처 message id 충돌.
tests/test_tool_result_token_estimate.py의_corpus가 id 를msg_{index}로 찍는데,test_small_results_and_cache_rewrites_are_not_samples가 같은 범위를 두 번 이어 붙여 usage 행 80개가 id 40개로 접히고 있었다. 그 단언은 오랫동안 이 충돌 덕분에 통과해 왔다.id_offset을 넣어 분리했고, 단언값 40 은 수정 전후 모두 유지된다.선언 누락. 리듀서와 그 미러가 production surface 인벤토리에는 있는데
PROVIDER_FREE_SUPPORT_PATHS에는 빠져 있었다.변이 테스트
min→maxREDUCER_SCHEMA상향검증
함정 하나
변이 테스트 중
__pycache__가 남아 파일을 복원한 뒤에도 낡은 바이트코드가 로드되는 현상을 겪었다. 리듀서를 반복 수정하며 테스트할 때는 캐시를 지우고 재실행할 것. 커밋 메시지에도 적어 두었다.동결 경로를 건드리지 않으므로 squash 로 병합해도 된다.
🤖 Generated with Claude Code
https://claude.ai/code/session_01DE3AupXcyv64SEuQeTckSh