<!-- task=02_antigravity_usage_status plan=2 tag=REVIEW_REVIEW_ANTIGRAVITY -->

# Antigravity Usage Readiness Scope 보정

## 배경

plan 1 구현은 `/usage` readiness에 parser-supported quota 문구를 추가하고 `/model` 수집을 best-effort로 바꿨다. 그러나 코드리뷰 결과, readiness 검사가 전체 `fullOutput`을 대상으로 수행되어 `/usage` 전송 이전 startup 화면의 `quota` 또는 `% used` 문구에도 매칭될 수 있음이 발견되었다.

이 후속 작업은 Antigravity checker의 `/usage` readiness 범위를 command 전송 이후 출력으로 한정한다. parser, edge formatter, config/docs, 실제 외부 `agy` 검증은 범위에 포함하지 않는다.

## 분석 결과

### 리뷰 지적

- `apps/node/internal/adapters/cli/status/antigravity.go`의 `waitForAny`는 매 반복마다 `cleanANSI(fullOutput)` 전체를 검사한다.
- plan 1에서 추가한 `resultRegex`는 `\bquota\b`와 `\d+(?:\.\d+)?%\s+used`를 인정한다.
- startup 화면에 quota 문구가 이미 있으면 `/usage` 명령 전송 직후 실제 `/usage` 응답을 읽기 전에 readiness가 성공하고, `/model`이 너무 일찍 입력될 수 있다.

## 구현 체크리스트

- [ ] [REVIEW_REVIEW_ANTIGRAVITY-1] `/usage` readiness를 `/usage` 전송 이후 출력으로 한정하고 startup quota 잡음에 조기 매칭되지 않도록 fake PTY 회귀 테스트를 추가한다.
- [ ] 중간 검증과 최종 검증 명령을 실행하고 결과를 기록한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

### [REVIEW_REVIEW_ANTIGRAVITY-1] `/usage` readiness command scope

### 문제

현재 `/usage` readiness는 전체 누적 출력에서 `quota` 또는 `% used`를 찾는다.

```go
resultRegex := regexp.MustCompile(`(?i)Usage limit:|Limit reached|No API calls have been made|\d+(?:\.\d+)?%\s+used|\bquota\b`)
if _, err := waitForAny([]waitPattern{{name: "usage", pattern: resultRegex}}, 20*time.Second); err != nil {
	return nil, fmt.Errorf("failed waiting for antigravity /usage output: %w", err)
}
```

`waitForAny`가 전체 `fullOutput`을 검사하기 때문에 startup/ready 이전에 출력된 quota 문구가 readiness를 만족시킬 수 있다.

### 해결 방법

`/usage` 전송 직전 현재 output 위치를 기록하고, `/usage` 대기에서는 해당 위치 이후의 출력만 검사한다. 구현 방식은 기존 구조에 맞게 선택한다.

가능한 구현 예:

```go
usageStart := len(fullOutput)
sendText("\x15/usage\r")
if _, err := waitForAnySince(usageStart, []waitPattern{{name: "usage", pattern: resultRegex}}, 20*time.Second); err != nil {
	return nil, fmt.Errorf("failed waiting for antigravity /usage output: %w", err)
}
```

또는 `waitForAny`에 optional offset을 넘기는 형태로 중복을 줄여도 된다. 핵심은 `/usage` 이전 출력으로 readiness가 성공하지 않는 것이다.

`resultRegex`도 필요 이상으로 넓지 않게 유지한다. `quota` 단독보다 `quota`와 used percent가 같은 post-command slice에 있거나, 명확한 terminal 상태(`Usage limit:`, `Limit reached`, `No API calls have been made`)를 확인하는 쪽을 우선한다.

### 수정 파일 및 체크리스트

- [ ] `apps/node/internal/adapters/cli/status/antigravity.go`에 command-scoped wait를 추가하거나 `/usage` 대기 전용 offset 처리를 넣는다.
- [ ] `apps/node/internal/adapters/cli/status/antigravity_test.go`에 startup 단계에서 `Auto (Antigravity) quota`와 `0% used`를 먼저 출력한 뒤, `/usage` 응답 전 일정 시간 `/model` 조기 입력이 없음을 확인하는 fake PTY 테스트를 추가한다.
- [ ] 같은 테스트에서 `/usage` 응답 이후 `/model`이 들어오고 최종 parsing이 성공하는지 확인한다.

### 중간 검증

```bash
go test -count=1 ./apps/node/internal/adapters/cli/status
```

## 최종 검증

```bash
go test -count=1 ./apps/node/internal/adapters/cli/status ./apps/edge/internal/opsconsole
```

```bash
rg --sort path -n "GeminiChecker|NewGeminiChecker|parseGemini|gemini[A-Z]|formatGemini|failed waiting for gemini|gemini startup" apps/node/internal/adapters/cli/status apps/edge/internal/opsconsole
```

기대: Go test는 fresh test 통과. `rg`는 match가 없어야 한다.

모든 코드 변경 완료 후 반드시 `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 채운다.
