<!-- task=m-plane-origin-authoring-roundtrip-sync/10+09_plane_todo plan=2 tag=REVIEW_TEST_REGRESSION -->

# Plan - REVIEW_TEST_REGRESSION

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

`CODE_REVIEW-local-G04.md`의 구현 에이전트 소유 섹션을 채우는 것까지가 구현이다. 이번 루프는 직전 리뷰에서 발견된 `gitosync.Bridge` 회귀 테스트 공백만 닫는다. 코드를 고친 뒤 검증 명령을 실행하고 실제 출력까지 review stub에 기록한 뒤 active 파일을 그대로 두고 리뷰 준비 완료를 보고한다. finalization, log rename, `complete.log`, archive 이동은 code-review 전용이다. 구현 중 선택된 Milestone `구현 잠금 > 결정 필요` 항목이 실구현을 차단할 때만 review stub의 `사용자 리뷰 요청`에 기록하고, 직접 질문하거나 `request_user_input`을 호출하지 않는다. 환경/secret/service 준비, 일반 검증 공백은 사용자 리뷰 요청이 아니다.

## 배경

직전 `cloud-G07` 루프는 Plane API/UI, Core log, DB ledger evidence로 SDD S15를 만족했지만, 구현 중 추가된 `gitosync.Bridge` 계약 두 개가 테스트로 고정되지 않아 FAIL 판정을 받았다. 이번 루프는 live Plane 증거를 다시 만들지 않고, `bridge_test.go`에 focused regression coverage만 추가해 재리뷰가 동일 Milestone Task를 PASS로 닫을 수 있게 한다.

## 사용자 리뷰 요청 흐름

사용자 리뷰 요청은 선택된 Milestone `구현 잠금 > 결정 필요` 항목이 실구현을 차단할 때만 active review stub의 `사용자 리뷰 요청` 섹션에 기록한다. 직접 사용자에게 질문하거나 선택지를 제시하거나 입력 도구를 호출하지 않는다. 테스트 작성 범위 조정, 원격 runner 일시 실패, 검증 증거 공백은 사용자 리뷰 요청이 아니며 `검증 결과`나 다음 code-review follow-up으로 처리한다.

## Archive Evidence Snapshot

- Current archived plan: `agent-task/m-plane-origin-authoring-roundtrip-sync/10+09_plane_todo/plan_cloud_G07_1.log`
- Current archived review: `agent-task/m-plane-origin-authoring-roundtrip-sync/10+09_plane_todo/code_review_cloud_G07_1.log`
- Verdict: FAIL
- Required summary:
  - `services/core/internal/gitosync/bridge.go:171` now fills empty identity `Tenant`/`Project` from `BridgeConfig`, but `services/core/internal/gitosync/bridge_test.go:99` only covers identity docs that already include tenant/project.
  - `services/core/internal/gitosync/bridge.go:154` intentionally omits `RoadmapRevision` for missing-create jobs, but `services/core/internal/gitosync/bridge_test.go:317` does not assert `job.RoadmapRevision == ""`.
- Affected files: `services/core/internal/gitosync/bridge_test.go` only. Do not change runtime code unless a test exposes an unexpected compile or behavior issue in the existing implementation.
- Verification evidence from prior loop: remote `go test -count=1 ./internal/roadmapsync ./internal/roadmapsyncpipeline ./internal/adapters/plane ./internal/gitosync ./cmd/server ./internal/scheduler` passed; Plane `/work-items/{id}/`, comments, Core log, and DB ledger evidence satisfied SDD S15 for work item `6945a5e7-b2ef-4d48-a037-00fa2b6ab99b`.
- Roadmap carryover: keep `plane-todo` as the Roadmap target; this follow-up does not expand to `slot-finalize`, `remote-baseline`, `full-cycle`, or roadmap state updates.
- Allowed narrow reread paths: `agent-task/m-plane-origin-authoring-roundtrip-sync/10+09_plane_todo/plan_cloud_G07_1.log`, `agent-task/m-plane-origin-authoring-roundtrip-sync/10+09_plane_todo/code_review_cloud_G07_1.log`.

## Roadmap Targets

- Milestone: `agent-roadmap/phase/agent-ops-mcp-control-plane/milestones/plane-origin-authoring-roundtrip-sync.md`
- Task ids:
  - `plane-todo`: preserve original comment, project Milestone body/title, and move Plane work item to Todo
- 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:
  - `S15`: task=`plane-todo`; evidence=`original comment, body update, title update, Todo move recorded`
- Completion mode: spec-check-on-pass

## 분석 결과

### 읽은 파일

- `agent-ops/skills/common/code-review/SKILL.md`
- `agent-ops/skills/common/plan/SKILL.md`
- `agent-test/local/rules.md`
- `agent-test/local/core-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/gitosync/bridge.go`
- `services/core/internal/gitosync/bridge_test.go`

### SDD 기준

- SDD path: `agent-roadmap/sdd/agent-ops-mcp-control-plane/plane-origin-authoring-roundtrip-sync/SDD.md`
- Status: `[승인됨]`
- Target scenario: `S15`, Milestone Task id `plane-todo`
- Evidence Map: original comment, body update, `[milestone-id]` title update, Todo move, and `roadmap_sync_steps` evidence for the same target.
- 직전 루프에서 S15 runtime evidence는 충족됐다. 이번 루프는 그 PASS 근거를 유지하면서 bridge 회귀 테스트 공백만 닫는다.

### 테스트 환경 규칙

- test_env: `local`
- `agent-test/local/rules.md` present and read.
- matched profile: `agent-test/local/core-smoke.md`
- 적용 규칙: `services/core/**` 변경은 standard remote runner `$HOME/agent-work/nomadcode`에서 최소 `services/core` Go tests를 실행한다. focused 중간 검증은 `./internal/gitosync`, 최종 검증은 `./...`를 사용한다.
- `<확인 필요>` 값은 기준 출력 예시에만 있으며 이번 명령 선택에는 영향을 주지 않는다.

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

- identity-backed enqueue fallback: existing `TestBridgeEnqueuesExactJobArgs` covers identity with tenant/project already present, but does not cover empty tenant/project fallback from `BridgeConfig`.
- missing-create RoadmapRevision omission: existing `TestBridgeEnqueuesMissingCreateJobArgs` covers expected identity and empty ref, but does not assert `RoadmapRevision` remains empty.

### 심볼 참조

- none. No symbol rename or removal is planned.

### 분할 판단

- Split decision policy evaluated. This is a single test-file follow-up with one ownership boundary (`gitosync`), one verification profile, and no independent deployable subwork. Splitting would add coordination overhead without improving reviewability.

### 범위 결정 근거

- Include only `services/core/internal/gitosync/bridge_test.go`.
- Exclude `bridge.go` behavior changes unless the new tests reveal the current implementation does not satisfy the reviewed contract.
- Exclude live Plane/API/DB evidence collection because S15 runtime evidence was already judged sufficient in `code_review_cloud_G07_1.log`.

### 빌드 등급

- `local-G04`: bounded deterministic Go unit-test follow-up, no live provider semantics needed, moderate care required because the assertions protect persisted authoring roundtrip behavior.

## 구현 체크리스트

- [ ] identity tenant/project fallback regression test를 추가해 identity에 `Tenant`/`Project`가 없을 때 `BridgeConfig` 값이 `FetchWorkItem` ref와 enqueued job에 반영되는지 검증한다.
- [ ] missing-create job args regression assertion을 추가해 `RoadmapRevision`이 empty string으로 유지되는지 검증한다.
- [ ] 원격 runner에서 focused `gitosync` test와 core 최종 test를 실행하고 실제 stdout/stderr를 `CODE_REVIEW-local-G04.md`에 기록한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

### [REVIEW_TEST_REGRESSION-1] Cover Identity Tenant/Project Fallback

#### 문제

Before: `services/core/internal/gitosync/bridge.go:171` fills missing identity tenant/project from bridge config, but `services/core/internal/gitosync/bridge_test.go:99` uses `matchedScanOutput()` whose identity already contains both fields. A future removal of the fallback can pass the current tests.

After: a focused test proves identity-backed reconcile works when the milestone identity contains only provider/work item fields and the bridge must supply tenant/project from config.

#### 해결 방법

Add a test near `TestBridgeEnqueuesExactJobArgs`:

```go
func TestBridgeFillsIdentityTenantProjectFromConfig(t *testing.T) {
    identity := matchedIdentity()
    identity.Tenant = ""
    identity.Project = ""
    out := matchedScanOutput()
    out.Docs[0].Identity = identity
    out.Result.ScannedMilestones[0].Identity = identity
    ...
}
```

Assert:

- `reader.refs[0].Tenant == "acme"` and `reader.refs[0].Project == "proj-1"`.
- `enq.jobs[0].Ref.Tenant/Project` match config.
- `enq.jobs[0].Expected.Tenant/Project` match config.

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

- [ ] `services/core/internal/gitosync/bridge_test.go`: add the focused fallback test.
- [ ] Runtime code: do not edit unless the focused test exposes a real implementation bug.

#### 테스트 작성

- Write `TestBridgeFillsIdentityTenantProjectFromConfig`.
- Assertion goal: identity-backed docs with missing tenant/project still fetch and enqueue with config tenant/project.

#### 중간 검증

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

Expected: package passes.

### [REVIEW_TEST_REGRESSION-2] Pin Missing-Create RoadmapRevision Omission

#### 문제

Before: `services/core/internal/gitosync/bridge.go:154` intentionally omits `RoadmapRevision` for missing-create jobs, but `services/core/internal/gitosync/bridge_test.go:317` does not assert that field. Reintroducing `RoadmapRevision: scan.Revision.Revision` would recreate the authoring roundtrip revision conflict and still pass the current test.

After: the missing-create job args test fails if `RoadmapRevision` is populated.

#### 해결 방법

Extend `TestBridgeEnqueuesMissingCreateJobArgs` with:

```go
if job.RoadmapRevision != "" {
    t.Fatalf("RoadmapRevision: got %q, want empty for missing-create", job.RoadmapRevision)
}
```

Keep the existing provider/tenant/project and empty `Ref` assertions.

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

- [ ] `services/core/internal/gitosync/bridge_test.go`: add the `RoadmapRevision` empty assertion.
- [ ] Runtime code: do not edit unless the assertion exposes a real implementation bug.

#### 테스트 작성

- Extend `TestBridgeEnqueuesMissingCreateJobArgs`.
- Assertion goal: missing-create jobs preserve empty `RoadmapRevision`.

#### 중간 검증

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

Expected: package passes.

## 수정 파일 요약

| 파일 | 항목 |
|------|------|
| `services/core/internal/gitosync/bridge_test.go` | `REVIEW_TEST_REGRESSION-1`, `REVIEW_TEST_REGRESSION-2` |

## 최종 검증

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

Expected: package passes.

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

Expected: all `services/core` packages pass.

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