# task-2726+2 보고서 — Round-2 bounded fix (origin/main 하드코딩 제거 → origin/${MAIN_BRANCH} 일관화)

- 작업 ID: task-2726+2 (round-2, **마지막 bounded round** — max_rounds=2 도달)
- 팀: dev3-team (다그다/팀장, 루/백엔드, 모리건/테스터)
- 작업 레벨: normal (Lv.2) · 게이트 Lv.2 (G1/G2/G3)
- 상태: **MERGE_READY_CANDIDATE** (PR #171 갱신, new head `80416faa`, merge 회장 승인 전 금지)
- 일시: 2026-06-03 17:12~17:30 KST
- 상위 누적 보고서: `memory/reports/task-2726.md` (round-0/1/2 통합 이력)

---

## S (Situation)
PR #171(head `041989e4`) OWNER `/gemini review` 에서 fresh **HIGH 1건** 유효(코드 직접대조):
`scripts/finish-task.sh` L545에서 `MAIN_BRANCH` 동적 감지하면서 L548은 `origin/main` 하드코딩 → 일관성 결함. master-default 또는 main 아닌 default branch 환경에서 merge-base 실패 → fallback/오판 가능.

## C (Complication)
하드코딩 `origin/main` 은 블록1(L548) 외에 블록2 MERGE-BASE staleness 검사(코드 2 + echo 문자열 2)에도 잔존. 블록2(`PROJECT_PATH` 가드)는 MAIN_BRANCH 미정의 스코프 → 단순 치환 불가, 동적 감지 추가 필요.

## Q (Question)
origin/main 하드코딩을 전부 제거하되 (1) 블록2에 MAIN_BRANCH 감지 추가, (2) fail-closed/STRICT default-off 유지, (3) master/main/default 차이를 회귀로 고정하려면?

## A (Answer)

### 수정/생성 파일 (expected_files 2파일)
- **수정** `scripts/finish-task.sh`
  - 블록1 L547~548: `merge-base origin/main HEAD` → `merge-base "origin/${MAIN_BRANCH}" HEAD` (L545 감지값 재사용)
  - 블록2 진입부: `MAIN_BRANCH=$(git -C "$PROJ_DIR" rev-parse --verify main >/dev/null 2>&1 && echo main || echo master)` 1줄 추가
  - 블록2: `rev-parse origin/main` → `rev-parse "origin/${MAIN_BRANCH}"`
  - 블록2: `merge-base HEAD origin/main` → `merge-base HEAD "origin/${MAIN_BRANCH}"`
  - 블록2 echo 2곳: `origin/main` 문자열 → `origin/${MAIN_BRANCH}`
  - 코드 경로 `origin/main` 하드코딩 **0건** (남은 2건은 변경 의도 기록 주석뿐, L547·L878)
- **수정** `tests/regression/test_finish_task_worktree_isolation_2726.py`
  - 회귀7 `TestMainBranchDetectionMasterDefault` 추가(6 테스트): master/main 감지, origin/master merge-base(origin/main 부재 시 PASS), origin/main merge-base(main-default), 소스 하드코딩 0 / `origin/${MAIN_BRANCH}` 사용 정적검증

## affected_files
- scripts/finish-task.sh
- tests/regression/test_finish_task_worktree_isolation_2726.py

## 테스트 결과 / 필수 검증 (회장 10) — 전부 PASS
1. 기존 24 회귀 유지 → **30 passed** (24 기존 + 6 신규, 무손상) ✓
2. master-default repo `origin/main` 부재 시 `origin/master` merge-base PASS (L1 실증) ✓
3. main-default 기존 동작 PASS ✓
4. `origin/main` 코드 하드코딩 grep **0** (주석 stripped 후 0) ✓
5. diff `git diff --name-only` = expected_files **2파일 내부** ✓
6. forbidden 0 (critical_gap.py·terminal_state_callback.py·deploy/systemd·.github 무손상) ✓
7. ANU key literal(`c119085...`) — 스크립트 0 / 테스트 0 ✓
8. `FINISH_TASK_WORKTREE_STRICT` default-off(L15 `:-0`) 유지 ✓
9. shared main/dev4 branch 개입 0 (task/task-2726-dev3 단일 브랜치) ✓
10. `.done` 위조 0 — finish-task.sh만이 완료 경로 ✓
- smoke: `python3 -m pytest tests/regression/test_finish_task_worktree_isolation_2726.py -q` → **30 passed** · `bash -n scripts/finish-task.sh` → rc=0 ✓

## L1 스모크테스트 결과 (필수)
- **서버 재시작**: 해당없음 (백엔드 bash CLI 함수)
- **API 응답 확인**: 해당없음
- **실동작 검증 (실제 실행)**: 임시 master-default bare origin + clone 구성(origin/main **ABSENT** 확인) → 스크립트와 동일 코드 경로 실행 → `MAIN_BRANCH=master` 감지 → `origin/master` SHA(`d68dbdef`) == merge-base(`d68dbdef`) **일치 → L1 SMOKE PASS**. 구 코드(`origin/main` 하드코딩)라면 이 repo에서 merge-base 빈값/오판 케이스였음.
- **스크린샷**: 해당없음 (CLI 백엔드)

## 버그 유무
- 신규 버그 없음. 새 HIGH/CRITICAL 발생 **0** (CHAIR_REQUIRED 트리거 없음).

## Git / 머지 판단
- **머지 필요**: Yes — 단 **회장 승인 전 merge 금지 (MERGE_READY_CANDIDATE)**
- **브랜치**: task/task-2726-dev3
- **워크트리 경로**: /home/jay/workspace/.worktrees/task-2726-dev3
- **PR**: #171 · **commit**: `80416faa` (non-force push, `041989e4..80416faa` fast-forward 갱신)
- **머지 의견**: bounded surgical fix, 30 회귀 PASS, diff 2파일, forbidden/ANU key 0, STRICT default-off 보존, fail-closed 유지. 새 head OWNER `/gemini review` → CI GREEN + fresh unresolved HIGH/CRITICAL 0 시 MERGE_READY_CANDIDATE.

## 모델 사용 기록
- 루(백엔드, finish-task.sh): **sonnet(general-purpose)** — bash 로직 수정
- 모리건(테스터, test 파일): **sonnet(general-purpose)** — 회귀 테스트(전략/분석 아님, haiku 미사용)
- 팀장(다그다, Opus): 설계/분배/검증/L1 smoke/통합 커밋·push만 수행(직접 코딩 위임)

## 비고 (doctrine 준수)
- ★ **마지막 bounded round(max_rounds=2 도달)**. 같은 blocker(origin 하드코딩/merge-base 계열) 재발 → LOOP_BOUNDARY. 새 HIGH/CRITICAL → CHAIR_REQUIRED.
- merge 미수행(회장 승인 전 금지) · 봇 `/gemini review` 미트리거(인간 OWNER 1회 doctrine) · amend/force push 금지(non-force fast-forward) 준수.
- shared main stash/reset/clean/delete 0 · dev4 미개입 · task-2725/2727 미혼입 · PR #169 미커밋.
- ANU normal callback cron 강제 등록(collector_role=ANU, 독립 ANU key) — finish-task.sh launcher 게이트 경유, self-key 금지, sendfile-only 금지.

---

## ANU Collector 회수·검증 (normal callback, collector_role=ANU)
- 회수 시각: 2026-06-03 17:46 KST · collector=anu-collector-508EB8F6 · anu_key=c119085…(self-key 미포함) · canonical_root=/home/jay/workspace
- result: `memory/events/task-2726+2.result.json` · envelope: `…/anu_callback/task-2726+2-normal-completion.json` (envelope_state=COLLECTED, delivery_outcome=FIRED, confirmation=CONFIRMED_BY_ANU_COLLECTOR)

### 독립 재검증 게이트 (head 80416faa)
1. head 80416faa: 로컬 worktree HEAD == PR #171 headRefOid **일치** ✓
2. 30 regression **30 passed** (1.45s, 기존24+신규6) ✓
3. diff vs origin/main = **2 expected_files** (finish-task.sh, test_…_2726.py) ✓
4. forbidden **0** · 5. ANU key literal(코드) **0** · 6. STRICT default-off(`:-0`) ✓
7. origin/main 코드 하드코딩 **0** (주석 stripped; 잔존 2건 변경의도 주석) · 8. `bash -n` rc=0 ✓
9. `.done` task-timer 정상(end_time+duration), qc_result=MERGE_READY_CANDIDATE, 위조 0 ✓
10. report sha256 `ef506498…` envelope 기록과 **일치** ✓
11. **CI GREEN 11/11** (cancel-kill-switch·ci/guard·gemini-review-gate·guard·hidden-path-audit·lock-in-check·merge-safety-check·phase3-merge-gate·qc-check·taskctl-state-guard×2) ✓
12. **fresh-active HIGH/CRITICAL = 0** — round-2 HIGH(origin/main@L548)은 fix 반영으로 `isOutdated=true` 해소, 잔존 active=MEDIUM×4(L57 home dir·L550 carry·L759 dead code·test L84 `$@`) ✓

### 유일 잔여 게이트 (human-gated)
- **새 head 80416faa 에 대한 Human OWNER `/gemini review` = PENDING**: 마지막 OWNER 트리거 07:50Z·마지막 gemini review 07:51Z 모두 80416faa push(08:17Z) **이전** → 새 head 대상 fresh review 미존재. bot `/gemini review` 무효 doctrine 으로 collector 트리거 **금지**.

### 판정
- **terminal_state = MERGE_READY_CANDIDATE** (CANDIDATE 확정) — static/CI 게이트 전부 GREEN, fresh-active HIGH/CRIT 0. 머지 확정 전 잔여 1건 = OWNER fresh `/gemini review`(인간 액션) → 이후 회장 merge 승인.
- **LOOP_BOUNDARY 미발동**: round-2 fix 로 동일 blocker(origin 하드코딩/merge-base) 해소, 재발 없음. (단 max_rounds=2 도달 — 재발 시 LOOP_BOUNDARY)
- **CHAIR_REQUIRED 미발동**: 새 HIGH/CRITICAL 0, expected_files 밖 변경 0.
- **merge 미수행** (HOLD_FOR_CHAIR, 회장 승인 전 금지) · merge_invocations=0 · auto_merge=0.
- 환경: finish-task GIT-GATE 의 shared-main EXTERNAL_DIRTY_BLOCKER 는 task 책임 아님(재실행 불필요), worktree 정상 완료 경로 = task-timer end + ANU callback (선례 동일).
