diff --git a/devlog/_plan/260913_devin_landing_and_caching/000_plan.md b/devlog/_plan/260913_devin_landing_and_caching/000_plan.md index e0af11ea20..7c91cc1959 100644 --- a/devlog/_plan/260913_devin_landing_and_caching/000_plan.md +++ b/devlog/_plan/260913_devin_landing_and_caching/000_plan.md @@ -152,3 +152,52 @@ Go에서 전체 요청 예산이라 정상적인 3분 턴도 자른다 — 따 | c-7 | effort 접미사 통합 merge | merge SHA + CI run id | | c-8 | AssignModel 라우터 지원 merge | merge SHA + CI run id | + +## 단위 종료 기록 (2026-09-13) + +6개 PR이 `dev`에 들어갔고, 1개 단계는 NOOP으로 닫혔다. + +| wp | 결과 | PR | merge SHA | exact-head CI | +|---|---|---|---|---| +| wp0 | 로드맵 | #4446 | `0a89b416a` | 27 success / 0 fail | +| wp1 | #4420 carry | #4445 | `eee8fd82f` | 31 success / 0 fail | +| wp2 | #4384 carry | #4448 | `720ea9730` | 22 success / 0 fail | +| wp3 | 헤더 데드라인 | #4450 | `dc33113a9` | 25 success / 0 fail | +| wp4 | 프롬프트 캐시 + identity | #4453 | `261bab915` | 25 success / 0 fail | +| wp5 | effort 접미사 통합 | #4459 | `cff737ce4` | 25 success / 0 fail | +| wp6 | **NOOP** (감사 FAIL) | — | — | — | + +원 PR #4420, #4384는 carry 링크와 함께 close했고, 두 저자는 squash 커밋의 +`Co-authored-by` 트레일러로 크레딧이 남는다. + +로컬 제품 스위트·typecheck·build·install은 이 세션에서 **NOT RUN**이다. 모든 머지 +증거는 exact-final-head hosted CI이며, cancelled/skipped는 성공으로 세지 않았다. + +### 감사가 계획을 바꾼 지점 + +서브에이전트 감사가 네 번 계획을 고쳤고, 그게 이 단위에서 가장 값어치 있는 부분이다. + +| 감사 지적 | 계획 원안 | 실제 착지 | +|---|---|---| +| abort 사유가 `AbortError`에 먹힌다 | `abort(new CloudChatError())` | 플래그 + catch에서 명시 throw | +| 전역 `clear()`가 타 계정 턴을 끊는다 | 문서화 후 유지 | export 제거, identity 스코프만 | +| epoch는 죽은 복잡도 | epoch 추가 | 추가하지 않음 | +| tier와 effort는 다른 개념 | 두 집합 병합 | 분리 유지, 이름으로 구분 | +| 라우터 uid 도달 증거 없음 | RPC 추가 | NOOP | + +### 미해결로 남긴 것 + +`c-8`(AssignModel 착지)은 **미충족으로 남긴다.** 기준이 거짓 전제 위에 쓰였고, +통과시키려고 기준을 약화하지 않는다. 위 "착지 조건" 둘 중 하나가 관측되면 연다. + +040에서 범위 밖으로 미룬 두 건도 남아 있다. + +- `invalid_argument` 분류. trailer → HTTP 400 매핑은 `chat.ts`에 이미 있다. 빠진 것은 + `devinErrorClassification`(`devin.ts:54`)에 400 분기가 없어 잘못된 요청이 구조화된 + 분류 없이 올라간다는 점이다. 040이 쓴 "자격증명 cooldown을 태운다"는 과장이었다 — + 현재 key-failover cooldown은 401/429에서만 돈다. 재감사 지적을 반영해 정정한다. +- rune-safe 도구 설명 절단. 현재 JS `slice`는 UTF-16 기준이라 한글·이모지 중간에서 + 잘리고 그 결과가 `invalid_argument`다. Plus는 1024B rune-safe로 자른다. + +둘 다 캐싱과는 별개 주제라 이 단위에서 분리했다. + diff --git a/devlog/_plan/260913_devin_landing_and_caching/060_wp6_assign_model_router.md b/devlog/_plan/260913_devin_landing_and_caching/060_wp6_assign_model_router.md index a2e6ab368f..37100bda59 100644 --- a/devlog/_plan/260913_devin_landing_and_caching/060_wp6_assign_model_router.md +++ b/devlog/_plan/260913_devin_landing_and_caching/060_wp6_assign_model_router.md @@ -98,3 +98,44 @@ if (isRouterModelUid(req.modelUid)) { wp4 다음. 둘 다 `chat.ts` 인코더를 건드리고, wp4의 필드 13이 먼저 들어가는 편이 필드 순서를 한 번만 정리한다. + +## 결론 — 구현하지 않는다 (A 단계 감사 FAIL, 2026-09-13) + +이 단계는 **NOOP으로 닫는다.** 독립 감사가 `VERDICT: fail`로 블로커 2건을 냈고, +둘 다 반박되지 않는다. + +**BLOCKER-1 — 라우터 uid가 우리에게 도달한다는 증거가 없다.** +Plus의 가드 패턴(`-router` 접미사, `model-router` 포함)은 우리 카탈로그에도, +`DEVIN_STATIC_MODELS`에도, 레인 A의 바이너리 조사에도 없다. 레인 A가 본 `adaptive`는 +`GetCliModelConfigs` 응답이고, 우리는 `GetCascadeModelConfigs`만 파싱한다. 다른 RPC의 +모델 목록을 근거로 우리 요청 경로에 RPC를 하나 더 붙일 수는 없다. + +**BLOCKER-2 — 훅을 걸 자리가 이미 선점되어 있다.** +사용자가 `adaptive`를 직접 타이핑해도 `resolveWireModelUid`가 먼저 `adaptive-medium`으로 +바꾸고, 그다음 카탈로그 preflight가 `not_listed`로 턴을 끝낸다. AssignModel 호출은 +그 두 단계 뒤에 올 자리라 영원히 실행되지 않는다. 훅을 앞으로 당기려면 wp5에서 막 +정리한 접미사 해석과 #14의 preflight 계약을 둘 다 되돌려야 하는데, 확인되지 않은 +수요를 위해 확인된 보호장치를 걷어내는 거래다. + +### 그래도 남겨 두는 것 + +봉투 자체는 검증됐으므로 기록은 유지한다. 나중에 라우터 uid가 실제로 관측되면 +이 문서의 필드 표를 그대로 쓰면 된다. 감사가 함께 확인한 사항: + +- 요청 1/2/3/5, 응답 1→{1 jwt, 2 uid} 구조는 Go 구현과 일치한다. +- 다만 우리 `buildMetadata`는 Go `devinBuildMetadata`와 필드·클라이언트 문자열이 + 달라서, 그대로 재사용하면 다른 봉투가 나간다. 재사용 전 대조가 필요하다. +- AssignModel이 느리면 wp3의 헤더 데드라인에는 안 걸리지만 사용자 체감 TTFB는 + 늘어난다. 구현한다면 이 호출에 **별도의 짧은 타임아웃**이 필요하다. +- 필드 26은 21 뒤, JWT가 있을 때만. assignment JWT는 api_key와 동급으로 로그·오류 + 본문에서 가려야 한다. + +### 착지 조건 + +다음 중 하나가 관측되면 이 단계를 다시 연다. + +1. `GetCascadeModelConfigs` 응답에 `-router` 또는 `model-router` uid가 실제로 나온다. +2. 사용자가 라우터 uid로 턴을 시도해 `not_listed`로 죽은 사례가 로그에 남는다. + +그 전까지 요청 경로에 RPC를 추가하는 것은 순비용이다. +