<!-- task=m-agent-registration-capability-boundary/01_agent_port plan=0 tag=REFACTOR -->

# Plan - REFACTOR Agent Capability Port

## 이 파일을 읽는 구현 에이전트에게

`CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 채우는 것이 필수 마지막 단계다. 구현 후 검증을 실행하고 실제 출력, 설계 결정, 계획 대비 변경 사항을 기록한 뒤 active 파일을 그대로 두고 리뷰 준비를 보고한다. 사용자 결정, 사용자 소유 외부 환경, scope 충돌이 막으면 `사용자 리뷰 요청` 섹션에 근거를 기록하고 중단한다. 구현 중 사용자에게 직접 묻거나 `USER_REVIEW.md`, `complete.log`, archive 로그를 만들지 않는다.

## 배경

`OtoServerRegistrationClient`가 기본 command type 산출을 직접 소유해 agent 도메인이 command registry/catalog를 import한다. agent 등록 경로는 capability provider 계약만 알고, 실제 command catalog 조회는 command 도메인 adapter로 분리되어야 한다. 이 subtask는 downstream adapter가 꽂힐 agent-side port와 기본 주입 표면만 만든다.

## 사용자 리뷰 요청 흐름

구현 중 blocker는 active review stub의 `사용자 리뷰 요청` 섹션에 기록한다. 직접 사용자 prompt는 금지이며, code-review가 검증 후 `USER_REVIEW.md` 작성 여부를 결정한다.

## Roadmap Targets

- Milestone: `agent-roadmap/phase/message-based-build-agent/milestones/agent-registration-capability-boundary.md`
- Task ids:
  - `agent-port`: agent 등록에 필요한 capability provider 계약과 기본값 주입 지점을 정의한다.
- Completion mode: check-on-pass

## 분석 결과

### 읽은 파일

- `agent-roadmap/current.md`
- `agent-roadmap/phase/message-based-build-agent/PHASE.md`
- `agent-roadmap/phase/message-based-build-agent/milestones/agent-registration-capability-boundary.md`
- `agent-test/local/rules.md`
- `agent-test/local/agent-smoke.md`
- `agent-test/local/command-smoke.md`
- `agent-ops/rules/project/domain/agent/rules.md`
- `agent-ops/rules/project/domain/command/rules.md`
- `apps/runner/lib/oto/agent/registration_client.dart`
- `apps/runner/lib/oto/agent/agent_runner.dart`
- `apps/runner/lib/oto/agent/edge_registration_client.dart`
- `apps/runner/lib/oto/commands/command.dart`
- `apps/runner/lib/oto/commands/command_catalog.dart`
- `apps/runner/lib/oto/commands/command_registry.dart`
- `apps/runner/test/oto_agent_registration_test.dart`
- `apps/runner/test/oto_server_connection_smoke_test.dart`
- `apps/runner/test/oto_command_catalog_test.dart`

### 테스트 환경 규칙

`test_env=local`. `agent-test/local/rules.md`를 읽었고 agent/command smoke profile을 적용한다. agent 변경은 `cd apps/runner && dart analyze`와 agent registration test 및 server connection smoke가 기준이다. command adapter 후속 변경은 command catalog/runtime smoke 기준을 함께 쓴다.

### 테스트 커버리지 공백

- agent-side provider 계약은 신규 개념이라 현재 직접 테스트가 없다. `oto_agent_registration_test.dart`에 injectable fake provider test를 추가해야 한다.
- registration payload 의미는 기존 `builds OTO Server registration request from config`와 server smoke가 일부 커버한다.

### 심볼 참조

현재 subtask에서 기존 public symbol rename/removal은 없다. 신규 `RunnerCapabilityProvider`와 capability value class를 추가한다.

### 분할 판단

split 정책을 먼저 평가했다. API/foundation port, command-domain adapter, registration wiring/test가 서로 다른 dependency boundary라 multi-plan이 필요하다. shared task group은 `m-agent-registration-capability-boundary`이고 siblings는 `01_agent_port`(선행 없음), `02+01_command_adapter`(01 완료 필요), `03+01,02_registration_wiring`(01,02 완료 필요)이다.

### 범위 결정 근거

이 subtask는 agent package 안의 port와 `OtoServerRegistrationClient` 생성자 주입 표면까지만 다룬다. command catalog 조회 adapter와 import 제거는 후속 `02`, production wiring과 최종 smoke는 `03`에서 처리한다.

### 빌드 등급

`local-G05`: 신규 port API지만 scope가 agent 파일과 focused unit test로 작고 검증이 결정적이다.

## 구현 체크리스트

- [ ] agent 등록 capability provider port와 immutable capability model을 agent 도메인 파일에 추가한다.
- [ ] `OtoServerRegistrationClient`가 `commandTypes` 직접 list 대신 provider를 받을 수 있는 주입 지점을 준비하되 기존 `commandTypes:` call site는 깨지지 않게 유지한다.
- [ ] `oto_agent_registration_test.dart`에 fake provider 기반 request build test를 추가한다.
- [ ] 중간/최종 검증을 실행한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

### [REFACTOR-1] Agent Capability Provider Port

문제: [registration_client.dart](/config/workspace/oto/apps/runner/lib/oto/agent/registration_client.dart:9)가 command domain을 import하고, [registration_client.dart](/config/workspace/oto/apps/runner/lib/oto/agent/registration_client.dart:246)의 `_defaultCommandTypes()`가 command registry를 직접 실행한다.

해결 방법: `apps/runner/lib/oto/agent/runner_capability_provider.dart`를 추가해 agent 등록 client가 소비할 port를 정의한다.

```dart
abstract class RunnerCapabilityProvider {
  RunnerCapabilitySnapshot snapshot();
}

class RunnerCapabilitySnapshot {
  final String name;
  final String version;
  final List<String> commandTypes;
  const RunnerCapabilitySnapshot({
    required this.name,
    required this.version,
    required Iterable<String> commandTypes,
  }) : commandTypes = List.unmodifiable(commandTypes);
}
```

수정 파일 및 체크리스트:

- [ ] `apps/runner/lib/oto/agent/runner_capability_provider.dart` 추가
- [ ] `apps/runner/lib/oto/agent/registration_client.dart`가 provider type을 import
- [ ] `apps/runner/test/oto_agent_registration_test.dart` fake provider 추가

테스트 작성: 작성. provider snapshot이 request의 `capability`와 `commandCatalog.commandTypes`로 들어가는 단위 테스트를 추가한다.

중간 검증:

```bash
cd apps/runner && dart test test/oto_agent_registration_test.dart
```

## 수정 파일 요약

| 파일 | 항목 |
|------|------|
| `apps/runner/lib/oto/agent/runner_capability_provider.dart` | REFACTOR-1 |
| `apps/runner/lib/oto/agent/registration_client.dart` | REFACTOR-1 |
| `apps/runner/test/oto_agent_registration_test.dart` | REFACTOR-1 |

## 최종 검증

```bash
cd apps/runner && dart analyze
cd apps/runner && dart test test/oto_agent_registration_test.dart
```

모든 코드 변경 완료 후 반드시 `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 채운다. 이 파일 작성이 구현의 마지막 단계다.
