<!-- task=m-iop-agent-run-bridge/03_commit_push_policy plan=1 tag=REVIEW_API -->

# Plan - REVIEW_API

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

이 계획은 구현 후 `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 실제 내용과 검증 출력으로 채우는 것까지가 작업이다. 구현 에이전트는 검증을 실행하고 active 파일을 유지한 채 리뷰 준비 상태를 보고한다. 사용자만 결정할 수 있는 정책, 외부 secret, scope 충돌로 막히면 active review stub의 `사용자 리뷰 요청` 섹션에 정확한 결정, 근거, 실행 명령, 재개 조건을 남기고 멈춘다. 구현 중 채팅으로 사용자에게 직접 질문하거나 선택지를 제시하거나 `request_user_input`을 호출하지 않는다. 후속 에이전트가 재실행이나 산출물 수집으로 해소할 수 있는 검증 공백은 사용자 리뷰 요청이 아니다. 최종 archive, `complete.log`, roadmap 갱신은 code-review/runtime 책임이다.

## 배경

이 후속 계획은 `code_review_local_G06_0.log`의 Required 이슈를 닫는다. 기존 구현은 JSON decode 형태의 `[]any{"commit_push"}`만 처리해 계약의 `string array` 입력을 typed Go slice로 전달하는 경로에서 commit/push policy를 무시한다. 범위는 policy parser와 회귀 테스트 보강으로 제한한다.

## 사용자 리뷰 요청 흐름

구현 중 차단은 active `CODE_REVIEW-*-G??.md`의 `사용자 리뷰 요청` 섹션에 기록한다. 직접 사용자 프롬프트는 금지이며, code-review가 요청 타당성을 검증하고 실제 `USER_REVIEW.md` 작성을 소유한다.

## Roadmap Targets

- Milestone: `agent-roadmap/phase/agent-shell-iop-execution/milestones/iop-agent-run-bridge.md`
- Task ids:
  - `commit-push`: policy가 허용한 경우 commit/push operation으로 연결한다.
- Completion mode: check-on-pass

## 분석 결과

### 읽은 파일

- `agent-ops/rules/project/rules.md`
- `agent-ops/rules/private/rules.md`
- `agent-ops/rules/common/rules-roadmap.md`
- `agent-ops/rules/project/domain/core/rules.md`
- `agent-ops/rules/project/domain/contracts/rules.md`
- `agent-ops/rules/project/domain/workspace-ops/rules.md`
- `agent-ops/skills/common/router.md`
- `agent-ops/skills/common/code-review/SKILL.md`
- `agent-ops/skills/common/plan/SKILL.md`
- `agent-ops/skills/common/_templates/implementation-user-review-request-section.md`
- `agent-test/local/rules.md`
- `agent-test/local/core-smoke.md`
- `agent-test/local/contracts-smoke.md`
- `agent-test/local/workspace-ops-smoke.md`
- `agent-contract/index.md`
- `agent-task/m-iop-agent-run-bridge/03_commit_push_policy/plan_local_G06_0.log`
- `agent-task/m-iop-agent-run-bridge/03_commit_push_policy/code_review_local_G06_0.log`
- `services/core/internal/worker/runner.go`
- `services/core/internal/worker/runner_test.go`
- `services/core/internal/gitengine/command.go`
- `packages/contracts/notes/gito-control-plane.md`

### 테스트 환경 규칙

- `test_env=local`; `agent-test/local/rules.md` 있음, 읽음.
- 적용 profile: `agent-test/local/core-smoke.md`, `agent-test/local/contracts-smoke.md`.
- core 필수 명령: `cd services/core && go test ./...`.
- 이 후속 수정은 `packages/contracts/**`를 바꾸지 않지만, 현재 task diff에 계약 노트 변경이 포함되어 최종 smoke로 `rg --sort path -n "proto-socket|REST|gRPC|ChangeRequest|Operation|Event|agent_shell|agent-shell|iop" packages/contracts README.md docs`를 유지한다.
- 구조적 공백 없음. `<확인 필요>` 값 없음.

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

- `allowed_result_actions`의 JSON decode 형태 `[]any{"commit_push"}`는 기존 `TestRunnerRunOnceAgentRunCommitPushViaAllowedActions`가 검증한다.
- `allowed_result_actions`의 typed `[]string{"commit_push"}` 경로는 현재 미검증이며 동작도 누락되어 있다.

### 심볼 참조

- none. rename/remove 없음.

### 분할 판단

- split decision policy를 평가했다.
- 이 후속은 기존 split subtask `m-iop-agent-run-bridge/03_commit_push_policy` 안의 단일 Required 이슈만 다룬다.
- 새 subtask로 나누면 같은 helper와 같은 worker test fixture를 다시 조정해야 해 coordination만 늘어난다. 기존 sibling `04+03_revision_scan_event`는 이 subtask의 PASS `complete.log`를 기다리므로 건드리지 않는다.

### 범위 결정 근거

- `packages/contracts/notes/gito-control-plane.md`는 이미 `string array`로 올바르게 적혀 있어 수정하지 않는다.
- commit/push 실행 순서, dirty guard 정책, revision scan event 연결은 이번 Required 이슈 밖이다.
- provider credential, remote integration, 실제 push smoke는 secret/remote 준비가 필요하므로 범위 밖이다.

### 빌드 등급

- build=`local-G06`, review=`local-G06`. parser와 worker unit test 보강으로 닫히는 bounded follow-up이며, 기존 route가 적절하다.

## 구현 체크리스트

- [ ] `agentRunGitResultPolicyFrom`이 `allowed_result_actions`를 `[]string`과 JSON decode 형태 `[]any` 모두에서 trim 후 해석한다.
- [ ] worker unit test로 typed `[]string{"commit_push"}` 입력이 commit/push를 실행하는 회귀 경로를 검증한다.
- [ ] `cd services/core && go test ./internal/worker`를 실행한다.
- [ ] `cd services/core && go test ./...`를 실행한다.
- [ ] 계약 smoke `rg --sort path -n "proto-socket|REST|gRPC|ChangeRequest|Operation|Event|agent_shell|agent-shell|iop" packages/contracts README.md docs`를 실행한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

### [REVIEW_API-1] Support typed allowed_result_actions string slices

#### 문제

[services/core/internal/worker/runner.go](/config/workspace/gito/services/core/internal/worker/runner.go:384)는 `allowed_result_actions`를 `[]any`로만 해석한다. [packages/contracts/notes/gito-control-plane.md](/config/workspace/gito/packages/contracts/notes/gito-control-plane.md:90)는 이 key를 `string array`로 정의하므로, Go 코드가 `PolicyContext: map[string]any{"allowed_result_actions": []string{"commit_push"}}`처럼 typed slice를 넘기면 commit/push가 허용되지 않는다.

#### 해결 방법

`allowed_result_actions` 해석을 작은 helper로 분리하거나 switch로 확장해 `[]string`과 `[]any`를 모두 처리한다. 각 entry는 `strings.TrimSpace` 후 `"commit_push"`와 비교한다.

```go
// before: services/core/internal/worker/runner.go:384
if v, ok := ctx["allowed_result_actions"]; ok {
    if actions, ok := v.([]any); ok {
        for _, a := range actions {
            if s, ok := a.(string); ok && strings.TrimSpace(s) == "commit_push" {
                p.CommitPushAllowed = true
                break
            }
        }
    }
}
```

```go
// after
if v, ok := ctx["allowed_result_actions"]; ok && agentRunAllowsCommitPush(v) {
    p.CommitPushAllowed = true
}
```

`agentRunAllowsCommitPush`는 최소한 `[]string`과 `[]any`를 지원한다. unknown 타입은 false로 두고 error/log를 추가하지 않는다.

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

- [ ] `services/core/internal/worker/runner.go`: `allowed_result_actions` typed slice 지원 추가.
- [ ] `services/core/internal/worker/runner_test.go`: typed `[]string{"commit_push"}` 회귀 테스트 추가 또는 기존 allowed-actions 테스트 입력을 `[]string`으로 바꾸고 JSON decode 형태 보존이 필요하면 별도 테스트 유지.

#### 테스트 작성

작성한다. `TestRunnerRunOnceAgentRunCommitPushViaAllowedActions`가 `[]string{"commit_push"}`를 사용하도록 바꾸거나, 새 테스트에서 typed slice 입력이 `add -A`, `commit -m`, `push` call order를 만드는지 검증한다.

#### 중간 검증

```bash
cd services/core && go test ./internal/worker
```

기대: worker 패키지 테스트가 0 exit로 통과한다. Go test cache output은 허용한다.

## 수정 파일 요약

| 파일 | 항목 |
| --- | --- |
| `services/core/internal/worker/runner.go` | REVIEW_API-1 |
| `services/core/internal/worker/runner_test.go` | REVIEW_API-1 |

## 최종 검증

```bash
cd services/core && go test ./internal/worker
```

```bash
cd services/core && go test ./...
```

```bash
rg --sort path -n "proto-socket|REST|gRPC|ChangeRequest|Operation|Event|agent_shell|agent-shell|iop" packages/contracts README.md docs
```

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