<!-- task=m-external-integration/04+01,02,03_adapter_boundary plan=1 tag=REVIEW_BOUNDARY -->

# Adapter Boundary Follow-up Plan - REVIEW_BOUNDARY

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

이 plan은 `code_review_local_G06_0.log`의 FAIL Required 항목만 닫는다. 새 provider 기능을 추가하지 말고, 선행 complete.log 증거와 provider boundary audit 증거를 실제 명령 출력으로 재수집한 뒤 `internal/notification`의 Mattermost adapter 직접 의존을 provider-neutral sink 경계 뒤로 이동한다.

모든 코드 변경 후 active `CODE_REVIEW-local-G07.md`의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다.

## Roadmap Targets

- Milestone: `agent-roadmap/phase/external-integration/milestones/external-integration.md`
- Task ids:
  - `adapter-boundary`: 외부 provider별 구현 경계 점검
- Completion mode: check-on-pass

## 실패 근거

- `code_review_local_G06_0.log`는 predecessor complete logs가 없다고 기록했지만, 실제로는 archive 아래에 `01_plane_adapter`, `02_jira_adapter`, `03_mattermost_adapter` complete logs가 존재한다.
- 같은 log의 provider leakage 검색 증거는 실제 stdout/stderr가 아니며, 원 명령의 `--glob '!adapters/**'`는 현재 경로 기준에서 adapter 파일을 제외하지 못한다.
- corrected search에서도 `services/core/internal/notification/service.go`가 `internal/adapters/mattermost` package와 `mattermost.TaskNotificationInput`을 직접 참조한다.

## 범위 결정 근거

- 이 follow-up은 `adapter-boundary` audit completion을 위한 Required 문제만 처리한다.
- Plane/Jira/Mattermost adapter 기능 자체는 선행 archive complete logs에서 PASS 완료된 것으로 보고 새 기능 구현은 하지 않는다.
- Roadmap 문서는 직접 수정하지 않는다. PASS 후 runtime이 completion metadata를 소비한다.

## 빌드 등급

- build lane/grade: `local-G07` - deterministic boundary fix와 증거 재수집.
- review lane/grade: `local-G07` - reviewer can rerun exact searches and Go baseline locally.

## 구현 체크리스트

- [ ] [REVIEW_BOUNDARY-1] 선행 complete.log와 audit 검색 증거를 실제 출력으로 재수집한다.
- [ ] [REVIEW_BOUNDARY-2] `internal/notification`의 Mattermost adapter 직접 의존을 provider-neutral sink 경계 뒤로 이동한다.
- [ ] [REVIEW_BOUNDARY-3] README/domain consistency와 최종 검증을 수행한다.
- [ ] `cd services/core && go test ./...`를 실행한다.
- [ ] `cd services/core && go vet ./...`를 실행한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

## [REVIEW_BOUNDARY-1] Evidence recovery

문제: predecessor complete.log evidence and boundary search output in `code_review_local_G06_0.log` are incorrect or non-verbatim.

해결 방법:

- Cite the exact predecessor complete log paths:
  - `agent-task/archive/2026/06/m-external-integration/01_plane_adapter/complete.log`
  - `agent-task/archive/2026/06/m-external-integration/02_jira_adapter/complete.log`
  - `agent-task/archive/2026/06/m-external-integration/03_mattermost_adapter/complete.log`
- Rerun the corrected non-adapter searches and paste actual stdout/stderr in `CODE_REVIEW-local-G07.md`.
- Every remaining hit must be classified as wiring, config/test data, provider-neutral contract, or a Required boundary fix.

수정 파일 및 체크리스트:

- [ ] No source change unless evidence exposes a boundary issue already covered by REVIEW_BOUNDARY-2.
- [ ] `CODE_REVIEW-local-G07.md` records exact command output.

테스트 작성:

- None.

중간 검증:

```bash
test -f agent-task/archive/2026/06/m-external-integration/01_plane_adapter/complete.log
test -f agent-task/archive/2026/06/m-external-integration/02_jira_adapter/complete.log
test -f agent-task/archive/2026/06/m-external-integration/03_mattermost_adapter/complete.log
rg --sort path -n "plane\\.|jira\\.|mattermost\\.|WorkItemRef|IssueRef|comment_html|/api/v4/posts|/rest/api/3" services/core/internal --glob '!**/adapters/**'
rg --sort path -n "internal/adapters/(plane|jira|mattermost)|mattermost\\.TaskNotificationInput|\\*mattermost\\.Client|plane\\.WorkItemRef|jira\\.IssueRef" services/core/internal/notification services/core/internal/workitem services/core/internal/workitempipeline services/core/internal/http services/core/internal/scheduler
```

기대:

- The three `test -f` commands exit 0.
- Broad search output contains only intentional config/test data or provider-neutral route/contract hits, and no unreviewed production adapter dependency outside wiring.
- Strict import/type search exits 1 with no output after REVIEW_BOUNDARY-2.

## [REVIEW_BOUNDARY-2] Mattermost notification boundary

문제: `internal/notification` directly imports `internal/adapters/mattermost` and constructs Mattermost adapter DTOs, so provider details are not isolated under `internal/adapters/<provider>`.

해결 방법:

- Keep `notification.Service` provider-neutral by depending only on `notification.TaskEventSink` and logger.
- Move Mattermost task-completed filtering and `mattermost.TaskNotificationInput` construction into the Mattermost adapter package, for example an adapter-owned `TaskEventSink`.
- Wire the Mattermost sink from `cmd/server/main.go`; wiring may import adapters, but `internal/notification` must not.
- Update notification tests to use fake `TaskEventSink` implementations instead of httptest Mattermost clients. Add adapter-level tests for the Mattermost sink if behavior moves there.

수정 파일 및 체크리스트:

- [ ] `services/core/internal/notification/service.go`: no `internal/adapters/mattermost` import, no `*mattermost.Client`, no `mattermost.TaskNotificationInput`.
- [ ] `services/core/internal/notification/service_test.go`: verifies fanout/error behavior with provider-neutral fake sinks.
- [ ] `services/core/internal/adapters/mattermost/**`: owns Mattermost-specific task notification formatting/sink behavior.
- [ ] `services/core/cmd/server/main.go`: wires the Mattermost sink as an adapter-owned sink.

테스트 작성:

- Update existing notification tests for provider-neutral sink behavior.
- Add or update Mattermost adapter tests for completed-only task event handling and error propagation.

중간 검증:

```bash
cd services/core && go test ./internal/notification ./internal/adapters/mattermost ./cmd/server
rg --sort path -n "internal/adapters/(plane|jira|mattermost)|mattermost\\.TaskNotificationInput|\\*mattermost\\.Client|plane\\.WorkItemRef|jira\\.IssueRef" services/core/internal/notification services/core/internal/workitem services/core/internal/workitempipeline services/core/internal/http services/core/internal/scheduler
```

기대:

- Targeted tests pass.
- Strict import/type search exits 1 with no output.

## [REVIEW_BOUNDARY-3] Docs and final verification

문제: boundary fix may require minor docs wording if README describes notification ownership incorrectly.

해결 방법:

- Check `services/core/README.md` and root `README.md` for statements that contradict the provider-neutral notification/service boundary.
- Update only if needed; do not broaden status claims.
- Confirm no roadmap file is directly modified.

수정 파일 및 체크리스트:

- [ ] `services/core/README.md`: current implementation range still matches code.
- [ ] `README.md`: current status still matches code if touched.
- [ ] `agent-roadmap/**`: no direct completion update.

테스트 작성:

- None for docs-only checks.

중간 검증:

```bash
git diff --name-only
```

기대: changes are limited to the follow-up scope and no roadmap file is modified.

## 수정 파일 요약

| 파일 | 항목 |
|------|------|
| `services/core/internal/notification/service.go` | REVIEW_BOUNDARY-2 |
| `services/core/internal/notification/service_test.go` | REVIEW_BOUNDARY-2 |
| `services/core/internal/adapters/mattermost/**` | REVIEW_BOUNDARY-2 |
| `services/core/cmd/server/main.go` | REVIEW_BOUNDARY-2 |
| `services/core/README.md` | REVIEW_BOUNDARY-3, if needed |
| `README.md` | REVIEW_BOUNDARY-3, if needed |
| `agent-task/m-external-integration/04+01,02,03_adapter_boundary/CODE_REVIEW-local-G07.md` | REVIEW_BOUNDARY-1..3 |

## 최종 검증

```bash
cd services/core && go test ./...
cd services/core && go vet ./...
rg --sort path -n "plane\\.|jira\\.|mattermost\\.|WorkItemRef|IssueRef|comment_html|/api/v4/posts|/rest/api/3" services/core/internal --glob '!**/adapters/**'
rg --sort path -n "internal/adapters/(plane|jira|mattermost)|mattermost\\.TaskNotificationInput|\\*mattermost\\.Client|plane\\.WorkItemRef|jira\\.IssueRef" services/core/internal/notification services/core/internal/workitem services/core/internal/workitempipeline services/core/internal/http services/core/internal/scheduler
```

기대:

- Go commands exit 0.
- Broad search output is pasted verbatim and every remaining hit is classified.
- Strict import/type search exits 1 with no output.

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