<!-- task=m-plane-origin-authoring-roundtrip-sync/11+10_slot_finalize plan=0 tag=TEST -->

# Plan - TEST

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

`CODE_REVIEW-cloud-G06.md`의 구현 에이전트 소유 섹션을 채우는 것까지가 구현이다. task metadata와 workspace slot terminal state를 실제 출력으로 기록하고 active 파일을 그대로 둔 채 리뷰 준비를 보고한다. SDD/Milestone lock 결정 외에는 직접 사용자에게 묻지 않는다.

## 배경

`slot-finalize`는 projected, failed, timeout, queue timeout, push failed, identity missing 결과가 task metadata와 workspace slot state에 일관되게 반영되는지 닫는 작업이다. 성공은 `available`, 수동 git 복구가 필요한 상태는 `dirty`, bridge/provider 오류는 `error`로 수렴해야 한다.

## 사용자 리뷰 요청 흐름

선택된 SDD 결정 또는 Milestone lock 결정만 review stub의 `사용자 리뷰 요청`에 기록한다. External service, secret, device, evidence gap은 일반 검증/후속 문제로 남긴다.

## Archive Evidence Snapshot

- Prior dependency: `agent-task/archive/2026/06/m-plane-origin-authoring-roundtrip-sync/07+05,06_slug_reconcile/complete.log`
- Immediate predecessor required by directory name: `10+09_plane_todo/complete.log`
- Carryover: Plane projection path is expected to be verified before slot finalization evidence is collected.

## Roadmap Targets

- Milestone: `agent-roadmap/phase/agent-ops-mcp-control-plane/milestones/plane-origin-authoring-roundtrip-sync.md`
- Task ids:
  - `slot-finalize`: projected/failed/timeout/queue timeout/push failed/identity missing map consistently to task metadata and workspace slot state
- Completion mode: check-on-pass

## Spec Targets

- SDD: `agent-roadmap/sdd/agent-ops-mcp-control-plane/plane-origin-authoring-roundtrip-sync/SDD.md`
- Acceptance scenarios:
  - `S16`: task=`slot-finalize`; evidence=`terminal task metadata and slot state evidence recorded`
- Completion mode: spec-check-on-pass

## 분석 결과

### 읽은 파일

- `agent-test/local/rules.md`
- `agent-test/local/core-smoke.md`
- `agent-test/live-cycle-smoke.md`
- `agent-roadmap/phase/agent-ops-mcp-control-plane/milestones/plane-origin-authoring-roundtrip-sync.md`
- `agent-roadmap/sdd/agent-ops-mcp-control-plane/plane-origin-authoring-roundtrip-sync/SDD.md`
- `services/core/internal/scheduler/jobs.go`
- `services/core/internal/scheduler/jobs_test.go`
- `services/core/internal/scheduler/roadmap_sync_jobs.go`
- `services/core/internal/scheduler/river.go`
- `services/core/internal/scheduler/river_test.go`
- `services/core/internal/scheduler/slot_finalizer.go`
- `services/core/internal/scheduler/stale.go`
- `services/core/internal/scheduler/stale_test.go`
- `services/core/internal/authoring/result.go`
- `services/core/internal/authoring/result_test.go`
- `services/core/migrations/00005_create_workspace_slots.sql`
- `services/core/queries/workspace_slots.sql`

### 테스트 환경 규칙

- test_env: `local`
- Env rules read: `agent-test/local/rules.md`
- Profiles read: `agent-test/local/core-smoke.md`, `agent-test/live-cycle-smoke.md`
- Current precheck passed: `cd services/core && go test -count=1 ./cmd/server ./internal/http ./internal/gitosync ./internal/roadmapsync ./internal/roadmapsyncpipeline ./internal/scheduler ./internal/adapters/plane ./internal/authoring`
- Final commands use remote runner focused tests plus live task/slot DB evidence.

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

- Unit tests cover projected/complete finalizer -> `available`, push failure -> `dirty`, bridge/identity failure -> `error`, and stale queue helper behavior.
- Remaining gap: same live cycle evidence showing task metadata `authoring_run_state=succeeded` and workspace slot state after Plane projection, plus failure categories if a live negative path is exercised.

### 심볼 참조

- none

### 분할 판단

- Split policy evaluated before choosing files.
- This task depends on `10+09_plane_todo`, because successful slot release evidence should follow verified Plane projection.
- It is separate because finalizer and workspace slot updates can fail after projection succeeds.

### 범위 결정 근거

- Scope includes scheduler finalizer, authoring result category mapping, stale helper, and live slot DB evidence.
- Excludes Plane body/status projection internals already owned by task 10.
- Excludes Plane `Todo -> In Progress` lifecycle and child-ticket execution.

### 빌드 등급

- `cloud-G06`: focused Go tests are bounded, but live task/slot state requires remote runner and DB evidence.

## 구현 체크리스트

- [ ] Predecessor `10+09_plane_todo` complete log이 있는지 확인하고, 없으면 구현을 시작하지 않고 review stub에 dependency blocker로 기록한다.
- [ ] Scheduler/authoring focused tests를 remote runner에서 실행하고 projected, dirty, error, stale queue coverage를 기록한다.
- [ ] Live task metadata에서 `authoring_run_state`, `authoring_run_updated_at`, `wait_type`, failure category 또는 success summary를 기록한다.
- [ ] DB/API에서 workspace slot state가 success `available`, git recovery `dirty`, bridge/provider/identity error `error` 기준과 일치함을 기록한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

### [TEST-1] Slot Terminal State Evidence

#### 문제

- Milestone line 79 requires projected/failed/timeout/queue timeout/push failed/identity missing to map consistently to task metadata and workspace slot state.
- `RoadmapCreationSyncWorker` finalizes projected/complete tasks and updates the slot to available at `services/core/internal/scheduler/roadmap_sync_jobs.go:91`.
- `applyTaskSlotTerminalState` skips missing slot metadata and writes slot state at `services/core/internal/scheduler/slot_finalizer.go`.
- `SlotStateForAuthoringOutcome` maps success/dirty/error categories at `services/core/internal/authoring/result.go:112`.
- Queue stale helper applies to queued authoring tasks at `services/core/internal/scheduler/stale.go:14`.

#### 해결 방법

- Use remote focused tests to prove unit-level mappings.
- Use the live task from task 10 to record success metadata and slot `available`.
- If live negative categories are naturally present, record them; otherwise rely on existing focused tests and state the live negative cases were not force-induced.
- Patch only scheduler/authoring mapping if a mismatch is found, with a regression test.

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

- [ ] `services/core/internal/scheduler/roadmap_sync_jobs.go`: optional defect fix if projected/complete finalization payload or available update is wrong.
- [ ] `services/core/internal/scheduler/jobs.go`: optional defect fix if failure categories map incorrectly.
- [ ] `services/core/internal/authoring/result.go`: optional defect fix if category-to-slot mapping is wrong.
- [ ] `services/core/internal/scheduler/stale.go`: optional defect fix if queue timeout/stale classification is wrong.
- [ ] `CODE_REVIEW-cloud-G06.md`: record remote tests, task metadata, and slot state evidence.

#### 테스트 작성

- Skip new tests if all existing focused tests pass and live success evidence matches.
- If a defect is found, add a focused regression test in `river_test.go`, `jobs_test.go`, `result_test.go`, or `stale_test.go`.

#### 중간 검증

```sh
ssh toki@toki-labs.com 'zsh -lc '\''cd "$HOME/agent-work/nomadcode/services/core" && go test -count=1 ./internal/scheduler ./internal/authoring'\'''
```

Expected: packages pass.

## 의존 관계 및 구현 순서

- Wait for predecessor `10+09_plane_todo` complete log.
- Run focused tests, then collect live task/slot state from the same cycle.

## 수정 파일 요약

| 파일 | 항목 |
|------|------|
| `services/core/internal/scheduler/roadmap_sync_jobs.go` | TEST-1 optional defect fix |
| `services/core/internal/scheduler/jobs.go` | TEST-1 optional defect fix |
| `services/core/internal/authoring/result.go` | TEST-1 optional defect fix |
| `services/core/internal/scheduler/stale.go` | TEST-1 optional defect fix |
| `CODE_REVIEW-cloud-G06.md` | TEST-1 evidence |

## 최종 검증

```sh
ssh toki@toki-labs.com 'zsh -lc '\''cd "$HOME/agent-work/nomadcode/services/core" && go test -count=1 ./internal/scheduler ./internal/authoring'\'''
```

Expected: all listed packages pass.

```sh
ssh toki@toki-labs.com 'zsh -lc '\''docker exec code-server-postgres psql -U nomadcode -d nomad-core-dev -c "select t.id, t.status, t.external_provider, t.external_id, t.metadata->>'\''authoring_run_state'\'' as run_state, t.metadata->>'\''wait_type'\'' as wait_type, t.metadata->>'\''authoring_failure_category'\'' as failure_category from tasks t where t.source = '\''plane'\'' order by t.updated_at desc limit 10;"'\'''
```

Expected: latest target task shows succeeded/completed metadata after projection or explicit failure category for a negative path.

```sh
ssh toki@toki-labs.com 'zsh -lc '\''docker exec code-server-postgres psql -U nomadcode -d nomad-core-dev -c "select id, slot_index, state, path, updated_at from workspace_slots order by updated_at desc limit 10;"'\'''
```

Expected: target slot state matches `available`, `dirty`, or `error` mapping described in the milestone, with no secrets printed.

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